wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   OS

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ssl.c Source File

ssl.c

00001 /* ssl.c
00002  *
00003  * Copyright (C) 2006-2017 wolfSSL Inc.
00004  *
00005  * This file is part of wolfSSL.
00006  *
00007  * wolfSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * wolfSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
00020  */
00021 
00022 
00023 #ifdef HAVE_CONFIG_H
00024     #include <config.h>
00025 #endif
00026 
00027 #include <wolfcrypt/settings.h>
00028 
00029 #ifndef WOLFCRYPT_ONLY
00030 
00031 #ifdef HAVE_ERRNO_H
00032     #include <errno.h>
00033 #endif
00034 
00035 #include <wolfssl/internal.h>
00036 #include <wolfssl/error-ssl.h>
00037 #include <wolfcrypt/coding.h>
00038 #ifdef NO_INLINE
00039     #include <wolfcrypt/misc.h>
00040 #else
00041     #define WOLFSSL_MISC_INCLUDED
00042     #include <wolfcrypt/src/misc.c>
00043 #endif
00044 
00045 
00046 #ifndef WOLFSSL_ALLOW_NO_SUITES
00047     #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA) \
00048                 && !defined(WOLFSSL_STATIC_DH) && !defined(WOLFSSL_STATIC_PSK) \
00049                 && !defined(HAVE_ED25519)
00050         #error "No cipher suites defined because DH disabled, ECC disabled, and no static suites defined. Please see top of README"
00051     #endif
00052 #endif
00053 
00054 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
00055         defined(HAVE_WEBSERVER) || defined(WOLFSSL_KEY_GEN)
00056     #include <wolfssl/openssl/evp.h>
00057     /* openssl headers end, wolfssl internal headers next */
00058 #endif
00059 
00060 #include <wolfcrypt/wc_encrypt.h>
00061 
00062 #ifdef OPENSSL_EXTRA
00063     /* openssl headers begin */
00064     #include <wolfssl/openssl/aes.h>
00065     #include <wolfssl/openssl/hmac.h>
00066     #include <wolfssl/openssl/crypto.h>
00067     #include <wolfssl/openssl/des.h>
00068     #include <wolfssl/openssl/bn.h>
00069     #include <wolfssl/openssl/buffer.h>
00070     #include <wolfssl/openssl/dh.h>
00071     #include <wolfssl/openssl/rsa.h>
00072     #include <wolfssl/openssl/pem.h >
00073     #include <wolfssl/openssl/ec.h>
00074     #include <wolfssl/openssl/ec25519.h>
00075     #include <wolfssl/openssl/ed25519.h>
00076     #include <wolfssl/openssl/ecdsa.h>
00077     #include <wolfssl/openssl/ecdh.h>
00078     #include <wolfssl/openssl/rc4.h>
00079     /* openssl headers end, wolfssl internal headers next */
00080     #include <wolfcrypt/hmac.h>
00081     #include <wolfcrypt/random.h>
00082     #include <wolfcrypt/des3.h>
00083     #include <wolfcrypt/md4.h>
00084     #include <wolfcrypt/md5.h>
00085     #include <wolfcrypt/arc4.h>
00086     #include <wolfcrypt/idea.h>
00087     #include <wolfcrypt/curve25519.h>
00088     #include <wolfcrypt/ed25519.h>
00089     #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL)
00090         #include <wolfssl/openssl/ocsp.h>
00091     #endif /* WITH_STUNNEL */
00092     #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
00093         #include <wolfcrypt/sha512.h>
00094     #endif
00095     #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \
00096         && !defined(WC_NO_RNG)
00097         #include <wolfcrypt/srp.h>
00098         #include <wolfcrypt/random.h>
00099     #endif
00100 #endif
00101 
00102 #ifdef NO_ASN
00103     #include <wolfcrypt/dh.h>
00104 #endif
00105 
00106 
00107 #ifdef WOLFSSL_SESSION_EXPORT
00108 #ifdef WOLFSSL_DTLS
00109 int wolfSSL_dtls_import(WOLFSSL* ssl, unsigned char* buf, unsigned int sz)
00110 {
00111     WOLFSSL_ENTER("wolfSSL_session_import");
00112 
00113     if (ssl == NULL || buf == NULL) {
00114         return BAD_FUNC_ARG;
00115     }
00116 
00117     /* sanity checks on buffer and protocol are done in internal function */
00118     return wolfSSL_dtls_import_internal(ssl, buf, sz);
00119 }
00120 
00121 
00122 /* Sets the function to call for serializing the session. This function is
00123  * called right after the handshake is completed. */
00124 int wolfSSL_CTX_dtls_set_export(WOLFSSL_CTX* ctx, wc_dtls_export func)
00125 {
00126 
00127     WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_export");
00128 
00129     /* purposefully allow func to be NULL */
00130     if (ctx == NULL) {
00131         return BAD_FUNC_ARG;
00132     }
00133 
00134     ctx->dtls_export = func;
00135 
00136     return WOLFSSL_SUCCESS;
00137 }
00138 
00139 
00140 /* Sets the function in WOLFSSL struct to call for serializing the session. This
00141  * function is called right after the handshake is completed. */
00142 int wolfSSL_dtls_set_export(WOLFSSL* ssl, wc_dtls_export func)
00143 {
00144 
00145     WOLFSSL_ENTER("wolfSSL_dtls_set_export");
00146 
00147     /* purposefully allow func to be NULL */
00148     if (ssl == NULL) {
00149         return BAD_FUNC_ARG;
00150     }
00151 
00152     ssl->dtls_export = func;
00153 
00154     return WOLFSSL_SUCCESS;
00155 }
00156 
00157 
00158 /* This function allows for directly serializing a session rather than using
00159  * callbacks. It has less overhead by removing a temporary buffer and gives
00160  * control over when the session gets serialized. When using callbacks the
00161  * session is always serialized immediatly after the handshake is finished.
00162  *
00163  * buf is the argument to contain the serialized session
00164  * sz  is the size of the buffer passed in
00165  * ssl is the WOLFSSL struct to serialize
00166  * returns the size of serialized session on success, 0 on no action, and
00167  *         negative value on error */
00168 int wolfSSL_dtls_export(WOLFSSL* ssl, unsigned char* buf, unsigned int* sz)
00169 {
00170     WOLFSSL_ENTER("wolfSSL_dtls_export");
00171 
00172     if (ssl == NULL || sz == NULL) {
00173         return BAD_FUNC_ARG;
00174     }
00175 
00176     if (buf == NULL) {
00177         *sz = MAX_EXPORT_BUFFER;
00178         return 0;
00179     }
00180 
00181     /* if not DTLS do nothing */
00182     if (!ssl->options.dtls) {
00183         WOLFSSL_MSG("Currently only DTLS export is supported");
00184         return 0;
00185     }
00186 
00187     /* copy over keys, options, and dtls state struct */
00188     return wolfSSL_dtls_export_internal(ssl, buf, *sz);
00189 }
00190 
00191 
00192 /* returns 0 on success */
00193 int wolfSSL_send_session(WOLFSSL* ssl)
00194 {
00195     int ret;
00196     byte* buf;
00197     word16 bufSz = MAX_EXPORT_BUFFER;
00198 
00199     WOLFSSL_ENTER("wolfSSL_send_session");
00200 
00201     if (ssl == NULL) {
00202         return BAD_FUNC_ARG;
00203     }
00204 
00205     buf = (byte*)XMALLOC(bufSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00206     if (buf == NULL) {
00207         return MEMORY_E;
00208     }
00209 
00210     /* if not DTLS do nothing */
00211     if (!ssl->options.dtls) {
00212         XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00213         WOLFSSL_MSG("Currently only DTLS export is supported");
00214         return 0;
00215     }
00216 
00217     /* copy over keys, options, and dtls state struct */
00218     ret = wolfSSL_dtls_export_internal(ssl, buf, bufSz);
00219     if (ret < 0) {
00220         XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00221         return ret;
00222     }
00223 
00224     /* if no error ret has size of buffer */
00225     ret = ssl->dtls_export(ssl, buf, ret, NULL);
00226     if (ret != WOLFSSL_SUCCESS) {
00227         XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00228         return ret;
00229     }
00230 
00231     XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00232     return 0;
00233 }
00234 #endif /* WOLFSSL_DTLS */
00235 #endif /* WOLFSSL_SESSION_EXPORT */
00236 
00237 
00238 /* prevent multiple mutex initializations */
00239 static volatile int initRefCount = 0;
00240 static wolfSSL_Mutex count_mutex;   /* init ref count mutex */
00241 
00242 /* Create a new WOLFSSL_CTX struct and return the pointer to created struct.
00243    WOLFSSL_METHOD pointer passed in is given to ctx to manage.
00244    This function frees the passed in WOLFSSL_METHOD struct on failure and on
00245    success is freed when ctx is freed.
00246  */
00247 WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap)
00248 {
00249     WOLFSSL_CTX* ctx = NULL;
00250 
00251     WOLFSSL_ENTER("WOLFSSL_CTX_new_ex");
00252 
00253     if (initRefCount == 0) {
00254         /* user no longer forced to call Init themselves */
00255         int ret = wolfSSL_Init();
00256         if (ret != WOLFSSL_SUCCESS) {
00257             WOLFSSL_MSG("wolfSSL_Init failed");
00258             WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
00259             if (method != NULL) {
00260                 XFREE(method, heap, DYNAMIC_TYPE_METHOD);
00261             }
00262             return NULL;
00263         }
00264     }
00265 
00266     if (method == NULL)
00267         return ctx;
00268 
00269     ctx = (WOLFSSL_CTX*) XMALLOC(sizeof(WOLFSSL_CTX), heap, DYNAMIC_TYPE_CTX);
00270     if (ctx) {
00271         if (InitSSL_Ctx(ctx, method, heap) < 0) {
00272             WOLFSSL_MSG("Init CTX failed");
00273             wolfSSL_CTX_free(ctx);
00274             ctx = NULL;
00275         }
00276 #if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
00277                            && !defined(NO_SHA256) && !defined(WC_NO_RNG)
00278         else {
00279             ctx->srp = (Srp*) XMALLOC(sizeof(Srp), heap, DYNAMIC_TYPE_SRP);
00280             if (ctx->srp == NULL){
00281                 WOLFSSL_MSG("Init CTX failed");
00282                 wolfSSL_CTX_free(ctx);
00283                 return NULL;
00284             }
00285             XMEMSET(ctx->srp, 0, sizeof(Srp));
00286         }
00287 #endif
00288     }
00289     else {
00290         WOLFSSL_MSG("Alloc CTX failed, method freed");
00291         XFREE(method, heap, DYNAMIC_TYPE_METHOD);
00292     }
00293 
00294 
00295     WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
00296     return ctx;
00297 }
00298 
00299 
00300 WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method)
00301 {
00302 #ifdef WOLFSSL_HEAP_TEST
00303     /* if testing the heap hint then set top level CTX to have test value */
00304     return wolfSSL_CTX_new_ex(method, (void*)WOLFSSL_HEAP_TEST);
00305 #else
00306     return wolfSSL_CTX_new_ex(method, NULL);
00307 #endif
00308 }
00309 
00310 
00311 void wolfSSL_CTX_free(WOLFSSL_CTX* ctx)
00312 {
00313     WOLFSSL_ENTER("SSL_CTX_free");
00314     if (ctx) {
00315 #if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
00316 && !defined(NO_SHA256) && !defined(WC_NO_RNG)
00317         if (ctx->srp != NULL){
00318             if (ctx->srp_password != NULL){
00319                 XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP);
00320             }
00321             wc_SrpTerm(ctx->srp);
00322             XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP);
00323         }
00324 #endif
00325         FreeSSL_Ctx(ctx);
00326     }
00327 
00328     WOLFSSL_LEAVE("SSL_CTX_free", 0);
00329 }
00330 
00331 
00332 #ifdef SINGLE_THREADED
00333 /* no locking in single threaded mode, allow a CTX level rng to be shared with
00334  * WOLFSSL objects, WOLFSSL_SUCCESS on ok */
00335 int wolfSSL_CTX_new_rng(WOLFSSL_CTX* ctx)
00336 {
00337     WC_RNG* rng;
00338     int     ret;
00339 
00340     if (ctx == NULL) {
00341         return BAD_FUNC_ARG;
00342     }
00343 
00344     rng = XMALLOC(sizeof(WC_RNG), ctx->heap, DYNAMIC_TYPE_RNG);
00345     if (rng == NULL) {
00346         return MEMORY_E;
00347     }
00348 
00349 #ifndef HAVE_FIPS
00350     ret = wc_InitRng_ex(rng, ctx->heap, ctx->devId);
00351 #else
00352     ret = wc_InitRng(rng);
00353 #endif
00354     if (ret != 0) {
00355         XFREE(rng, ctx->heap, DYNAMIC_TYPE_RNG);
00356         return ret;
00357     }
00358 
00359     ctx->rng = rng;
00360     return WOLFSSL_SUCCESS;
00361 }
00362 #endif
00363 
00364 
00365 WOLFSSL* wolfSSL_new(WOLFSSL_CTX* ctx)
00366 {
00367     WOLFSSL* ssl = NULL;
00368     int ret = 0;
00369 
00370     (void)ret;
00371     WOLFSSL_ENTER("SSL_new");
00372 
00373     if (ctx == NULL)
00374         return ssl;
00375 
00376     ssl = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ctx->heap, DYNAMIC_TYPE_SSL);
00377     if (ssl)
00378         if ( (ret = InitSSL(ssl, ctx, 0)) < 0) {
00379             FreeSSL(ssl, ctx->heap);
00380             ssl = 0;
00381         }
00382 
00383     WOLFSSL_LEAVE("SSL_new", ret);
00384     return ssl;
00385 }
00386 
00387 
00388 void wolfSSL_free(WOLFSSL* ssl)
00389 {
00390     WOLFSSL_ENTER("SSL_free");
00391     if (ssl)
00392         FreeSSL(ssl, ssl->ctx->heap);
00393     WOLFSSL_LEAVE("SSL_free", 0);
00394 }
00395 
00396 
00397 int wolfSSL_is_server(WOLFSSL* ssl)
00398 {
00399     if (ssl == NULL)
00400         return BAD_FUNC_ARG;
00401     return ssl->options.side == WOLFSSL_SERVER_END;
00402 }
00403 
00404 #ifdef HAVE_WRITE_DUP
00405 
00406 /*
00407  * Release resources around WriteDup object
00408  *
00409  * ssl WOLFSSL object
00410  *
00411  * no return, destruction so make best attempt
00412 */
00413 void FreeWriteDup(WOLFSSL* ssl)
00414 {
00415     int doFree = 0;
00416 
00417     WOLFSSL_ENTER("FreeWriteDup");
00418 
00419     if (ssl->dupWrite) {
00420         if (wc_LockMutex(&ssl->dupWrite->dupMutex) == 0) {
00421             ssl->dupWrite->dupCount--;
00422             if (ssl->dupWrite->dupCount == 0) {
00423                 doFree = 1;
00424             } else {
00425                 WOLFSSL_MSG("WriteDup count not zero, no full free");
00426             }
00427             wc_UnLockMutex(&ssl->dupWrite->dupMutex);
00428         }
00429     }
00430 
00431     if (doFree) {
00432         WOLFSSL_MSG("Doing WriteDup full free, count to zero");
00433         wc_FreeMutex(&ssl->dupWrite->dupMutex);
00434         XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
00435     }
00436 }
00437 
00438 
00439 /*
00440  * duplicate existing ssl members into dup needed for writing
00441  *
00442  * dup write only WOLFSSL
00443  * ssl exisiting WOLFSSL
00444  *
00445  * 0 on success
00446 */
00447 static int DupSSL(WOLFSSL* dup, WOLFSSL* ssl)
00448 {
00449     /* shared dupWrite setup */
00450     ssl->dupWrite = (WriteDup*)XMALLOC(sizeof(WriteDup), ssl->heap,
00451                                        DYNAMIC_TYPE_WRITEDUP);
00452     if (ssl->dupWrite == NULL) {
00453         return MEMORY_E;
00454     }
00455     XMEMSET(ssl->dupWrite, 0, sizeof(WriteDup));
00456 
00457     if (wc_InitMutex(&ssl->dupWrite->dupMutex) != 0) {
00458         XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
00459         ssl->dupWrite = NULL;
00460         return BAD_MUTEX_E;
00461     }
00462     ssl->dupWrite->dupCount = 2;    /* both sides have a count to start */
00463     dup->dupWrite = ssl->dupWrite; /* each side uses */
00464 
00465     /* copy write parts over to dup writer */
00466     XMEMCPY(&dup->specs,   &ssl->specs,   sizeof(CipherSpecs));
00467     XMEMCPY(&dup->options, &ssl->options, sizeof(Options));
00468     XMEMCPY(&dup->keys,    &ssl->keys,    sizeof(Keys));
00469     XMEMCPY(&dup->encrypt, &ssl->encrypt, sizeof(Ciphers));
00470     /* dup side now owns encrypt/write ciphers */
00471     XMEMSET(&ssl->encrypt, 0, sizeof(Ciphers));
00472 
00473     dup->IOCB_WriteCtx = ssl->IOCB_WriteCtx;
00474     dup->wfd    = ssl->wfd;
00475     dup->wflags = ssl->wflags;
00476     dup->hmac   = ssl->hmac;
00477 #ifdef HAVE_TRUNCATED_HMAC
00478     dup->truncated_hmac = ssl->truncated_hmac;
00479 #endif
00480 
00481     /* unique side dup setup */
00482     dup->dupSide = WRITE_DUP_SIDE;
00483     ssl->dupSide = READ_DUP_SIDE;
00484 
00485     return 0;
00486 }
00487 
00488 
00489 /*
00490  * duplicate a WOLFSSL object post handshake for writing only
00491  * turn exisitng object into read only.  Allows concurrent access from two
00492  * different threads.
00493  *
00494  * ssl exisiting WOLFSSL object
00495  *
00496  * return dup'd WOLFSSL object on success
00497 */
00498 WOLFSSL* wolfSSL_write_dup(WOLFSSL* ssl)
00499 {
00500     WOLFSSL* dup = NULL;
00501     int ret = 0;
00502 
00503     (void)ret;
00504     WOLFSSL_ENTER("wolfSSL_write_dup");
00505 
00506     if (ssl == NULL) {
00507         return ssl;
00508     }
00509 
00510     if (ssl->options.handShakeDone == 0) {
00511         WOLFSSL_MSG("wolfSSL_write_dup called before handshake complete");
00512         return NULL;
00513     }
00514 
00515     if (ssl->dupWrite) {
00516         WOLFSSL_MSG("wolfSSL_write_dup already called once");
00517         return NULL;
00518     }
00519 
00520     dup = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ssl->ctx->heap, DYNAMIC_TYPE_SSL);
00521     if (dup) {
00522         if ( (ret = InitSSL(dup, ssl->ctx, 1)) < 0) {
00523             FreeSSL(dup, ssl->ctx->heap);
00524             dup = NULL;
00525         } else if ( (ret = DupSSL(dup, ssl) < 0)) {
00526             FreeSSL(dup, ssl->ctx->heap);
00527             dup = NULL;
00528         }
00529     }
00530 
00531     WOLFSSL_LEAVE("wolfSSL_write_dup", ret);
00532 
00533     return dup;
00534 }
00535 
00536 
00537 /*
00538  * Notify write dup side of fatal error or close notify
00539  *
00540  * ssl WOLFSSL object
00541  * err Notify err
00542  *
00543  * 0 on success
00544 */
00545 int NotifyWriteSide(WOLFSSL* ssl, int err)
00546 {
00547     int ret;
00548 
00549     WOLFSSL_ENTER("NotifyWriteSide");
00550 
00551     ret = wc_LockMutex(&ssl->dupWrite->dupMutex);
00552     if (ret == 0) {
00553         ssl->dupWrite->dupErr = err;
00554         ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
00555     }
00556 
00557     return ret;
00558 }
00559 
00560 
00561 #endif /* HAVE_WRITE_DUP */
00562 
00563 
00564 #ifdef HAVE_POLY1305
00565 /* set if to use old poly 1 for yes 0 to use new poly */
00566 int wolfSSL_use_old_poly(WOLFSSL* ssl, int value)
00567 {
00568     (void)ssl;
00569     (void)value;
00570 
00571 #ifndef WOLFSSL_NO_TLS12
00572     WOLFSSL_ENTER("SSL_use_old_poly");
00573     WOLFSSL_MSG("Warning SSL connection auto detects old/new and this function"
00574             "is depriciated");
00575     ssl->options.oldPoly = (word16)value;
00576     WOLFSSL_LEAVE("SSL_use_old_poly", 0);
00577 #endif
00578     return 0;
00579 }
00580 #endif
00581 
00582 
00583 int wolfSSL_set_fd(WOLFSSL* ssl, int fd)
00584 {
00585     int ret;
00586 
00587     WOLFSSL_ENTER("SSL_set_fd");
00588 
00589     if (ssl == NULL) {
00590         return BAD_FUNC_ARG;
00591     }
00592 
00593     ret = wolfSSL_set_read_fd(ssl, fd);
00594     if (ret == WOLFSSL_SUCCESS) {
00595         ret = wolfSSL_set_write_fd(ssl, fd);
00596     }
00597 
00598     return ret;
00599 }
00600 
00601 
00602 int wolfSSL_set_read_fd(WOLFSSL* ssl, int fd)
00603 {
00604     WOLFSSL_ENTER("SSL_set_read_fd");
00605 
00606     if (ssl == NULL) {
00607         return BAD_FUNC_ARG;
00608     }
00609 
00610     ssl->rfd = fd;      /* not used directly to allow IO callbacks */
00611     ssl->IOCB_ReadCtx  = &ssl->rfd;
00612 
00613     #ifdef WOLFSSL_DTLS
00614         if (ssl->options.dtls) {
00615             ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
00616             ssl->buffers.dtlsCtx.rfd = fd;
00617         }
00618     #endif
00619 
00620     WOLFSSL_LEAVE("SSL_set_read_fd", WOLFSSL_SUCCESS);
00621     return WOLFSSL_SUCCESS;
00622 }
00623 
00624 
00625 int wolfSSL_set_write_fd(WOLFSSL* ssl, int fd)
00626 {
00627     WOLFSSL_ENTER("SSL_set_write_fd");
00628 
00629     if (ssl == NULL) {
00630         return BAD_FUNC_ARG;
00631     }
00632 
00633     ssl->wfd = fd;      /* not used directly to allow IO callbacks */
00634     ssl->IOCB_WriteCtx  = &ssl->wfd;
00635 
00636     #ifdef WOLFSSL_DTLS
00637         if (ssl->options.dtls) {
00638             ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
00639             ssl->buffers.dtlsCtx.wfd = fd;
00640         }
00641     #endif
00642 
00643     WOLFSSL_LEAVE("SSL_set_write_fd", WOLFSSL_SUCCESS);
00644     return WOLFSSL_SUCCESS;
00645 }
00646 
00647 
00648 /**
00649   * Get the name of cipher at priority level passed in.
00650   */
00651 char* wolfSSL_get_cipher_list(int priority)
00652 {
00653     const CipherSuiteInfo* ciphers = GetCipherNames();
00654 
00655     if (priority >= GetCipherNamesSize() || priority < 0) {
00656         return 0;
00657     }
00658 
00659     return (char*)ciphers[priority].name;
00660 }
00661 
00662 
00663 /**
00664   * Get the name of cipher at priority level passed in.
00665   */
00666 char* wolfSSL_get_cipher_list_ex(WOLFSSL* ssl, int priority)
00667 {
00668 
00669     if (ssl == NULL) {
00670         return NULL;
00671     }
00672     else {
00673         const char* cipher;
00674 
00675         if ((cipher = wolfSSL_get_cipher_name_internal(ssl)) != NULL) {
00676             if (priority == 0) {
00677                 return (char*)cipher;
00678             }
00679             else {
00680                 return NULL;
00681             }
00682         }
00683         else {
00684             return wolfSSL_get_cipher_list(priority);
00685         }
00686     }
00687 }
00688 
00689 
00690 int wolfSSL_get_ciphers(char* buf, int len)
00691 {
00692     const CipherSuiteInfo* ciphers = GetCipherNames();
00693     int  totalInc = 0;
00694     int  step     = 0;
00695     char delim    = ':';
00696     int  size     = GetCipherNamesSize();
00697     int  i;
00698 
00699     if (buf == NULL || len <= 0)
00700         return BAD_FUNC_ARG;
00701 
00702     /* Add each member to the buffer delimited by a : */
00703     for (i = 0; i < size; i++) {
00704         step = (int)(XSTRLEN(ciphers[i].name) + 1);  /* delimiter */
00705         totalInc += step;
00706 
00707         /* Check to make sure buf is large enough and will not overflow */
00708         if (totalInc < len) {
00709             size_t cipherLen = XSTRLEN(ciphers[i].name);
00710             XSTRNCPY(buf, ciphers[i].name, cipherLen);
00711             buf += cipherLen;
00712 
00713             if (i < size - 1)
00714                 *buf++ = delim;
00715             else
00716                 *buf++ = '\0';
00717         }
00718         else
00719             return BUFFER_E;
00720     }
00721     return WOLFSSL_SUCCESS;
00722 }
00723 
00724 const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf, int len)
00725 {
00726     const char* cipher;
00727 
00728     if (ssl == NULL)
00729         return NULL;
00730 
00731     cipher = wolfSSL_get_cipher_name_iana(ssl);
00732     len = min(len, (int)(XSTRLEN(cipher) + 1));
00733     XMEMCPY(buf, cipher, len);
00734     return buf;
00735 }
00736 
00737 int wolfSSL_get_fd(const WOLFSSL* ssl)
00738 {
00739     WOLFSSL_ENTER("SSL_get_fd");
00740     WOLFSSL_LEAVE("SSL_get_fd", ssl->rfd);
00741     return ssl->rfd;
00742 }
00743 
00744 
00745 int wolfSSL_dtls(WOLFSSL* ssl)
00746 {
00747     return ssl->options.dtls;
00748 }
00749 
00750 
00751 #ifndef WOLFSSL_LEANPSK
00752 int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
00753 {
00754 #ifdef WOLFSSL_DTLS
00755     void* sa = (void*)XMALLOC(peerSz, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
00756     if (sa != NULL) {
00757         if (ssl->buffers.dtlsCtx.peer.sa != NULL)
00758             XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
00759         XMEMCPY(sa, peer, peerSz);
00760         ssl->buffers.dtlsCtx.peer.sa = sa;
00761         ssl->buffers.dtlsCtx.peer.sz = peerSz;
00762         return WOLFSSL_SUCCESS;
00763     }
00764     return WOLFSSL_FAILURE;
00765 #else
00766     (void)ssl;
00767     (void)peer;
00768     (void)peerSz;
00769     return WOLFSSL_NOT_IMPLEMENTED;
00770 #endif
00771 }
00772 
00773 int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
00774 {
00775 #ifdef WOLFSSL_DTLS
00776     if (ssl == NULL) {
00777         return WOLFSSL_FAILURE;
00778     }
00779 
00780     if (peer != NULL && peerSz != NULL
00781             && *peerSz >= ssl->buffers.dtlsCtx.peer.sz
00782             && ssl->buffers.dtlsCtx.peer.sa != NULL) {
00783         *peerSz = ssl->buffers.dtlsCtx.peer.sz;
00784         XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
00785         return WOLFSSL_SUCCESS;
00786     }
00787     return WOLFSSL_FAILURE;
00788 #else
00789     (void)ssl;
00790     (void)peer;
00791     (void)peerSz;
00792     return WOLFSSL_NOT_IMPLEMENTED;
00793 #endif
00794 }
00795 
00796 
00797 #if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
00798 
00799 int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX* ctx)
00800 {
00801     WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_sctp()");
00802 
00803     if (ctx == NULL)
00804         return BAD_FUNC_ARG;
00805 
00806     ctx->dtlsSctp = 1;
00807     return WOLFSSL_SUCCESS;
00808 }
00809 
00810 
00811 int wolfSSL_dtls_set_sctp(WOLFSSL* ssl)
00812 {
00813     WOLFSSL_ENTER("wolfSSL_dtls_set_sctp()");
00814 
00815     if (ssl == NULL)
00816         return BAD_FUNC_ARG;
00817 
00818     ssl->options.dtlsSctp = 1;
00819     return WOLFSSL_SUCCESS;
00820 }
00821 
00822 
00823 int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word16 newMtu)
00824 {
00825     if (ctx == NULL || newMtu > MAX_RECORD_SIZE)
00826         return BAD_FUNC_ARG;
00827 
00828     ctx->dtlsMtuSz = newMtu;
00829     return WOLFSSL_SUCCESS;
00830 }
00831 
00832 
00833 int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu)
00834 {
00835     if (ssl == NULL)
00836         return BAD_FUNC_ARG;
00837 
00838     if (newMtu > MAX_RECORD_SIZE) {
00839         ssl->error = BAD_FUNC_ARG;
00840         return WOLFSSL_FAILURE;
00841     }
00842 
00843     ssl->dtlsMtuSz = newMtu;
00844     return WOLFSSL_SUCCESS;
00845 }
00846 
00847 
00848 #endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */
00849 
00850 
00851 #ifdef WOLFSSL_DTLS_DROP_STATS
00852 
00853 int wolfSSL_dtls_get_drop_stats(WOLFSSL* ssl,
00854                                 word32* macDropCount, word32* replayDropCount)
00855 {
00856     int ret;
00857 
00858     WOLFSSL_ENTER("wolfSSL_dtls_get_drop_stats()");
00859 
00860     if (ssl == NULL)
00861         ret = BAD_FUNC_ARG;
00862     else {
00863         ret = WOLFSSL_SUCCESS;
00864         if (macDropCount != NULL)
00865             *macDropCount = ssl->macDropCount;
00866         if (replayDropCount != NULL)
00867             *replayDropCount = ssl->replayDropCount;
00868     }
00869 
00870     WOLFSSL_LEAVE("wolfSSL_dtls_get_drop_stats()", ret);
00871     return ret;
00872 }
00873 
00874 #endif /* WOLFSSL_DTLS_DROP_STATS */
00875 
00876 
00877 #if defined(WOLFSSL_MULTICAST)
00878 
00879 int wolfSSL_CTX_mcast_set_member_id(WOLFSSL_CTX* ctx, word16 id)
00880 {
00881     int ret = 0;
00882 
00883     WOLFSSL_ENTER("wolfSSL_CTX_mcast_set_member_id()");
00884 
00885     if (ctx == NULL || id > 255)
00886         ret = BAD_FUNC_ARG;
00887 
00888     if (ret == 0) {
00889         ctx->haveEMS = 0;
00890         ctx->haveMcast = 1;
00891         ctx->mcastID = id;
00892 #ifndef WOLFSSL_USER_IO
00893         ctx->CBIORecv = EmbedReceiveFromMcast;
00894 #endif /* WOLFSSL_USER_IO */
00895     }
00896 
00897     if (ret == 0)
00898         ret = WOLFSSL_SUCCESS;
00899     WOLFSSL_LEAVE("wolfSSL_CTX_mcast_set_member_id()", ret);
00900     return ret;
00901 }
00902 
00903 int wolfSSL_mcast_get_max_peers(void)
00904 {
00905     return WOLFSSL_MULTICAST_PEERS;
00906 }
00907 
00908 #ifdef WOLFSSL_DTLS
00909 static WC_INLINE word32 UpdateHighwaterMark(word32 cur, word32 first,
00910                                          word32 second, word32 max)
00911 {
00912     word32 newCur = 0;
00913 
00914     if (cur < first)
00915         newCur = first;
00916     else if (cur < second)
00917         newCur = second;
00918     else if (cur < max)
00919         newCur = max;
00920 
00921     return newCur;
00922 }
00923 #endif /* WOLFSSL_DTLS */
00924 
00925 
00926 int wolfSSL_set_secret(WOLFSSL* ssl, word16 epoch,
00927                        const byte* preMasterSecret, word32 preMasterSz,
00928                        const byte* clientRandom, const byte* serverRandom,
00929                        const byte* suite)
00930 {
00931     int ret = 0;
00932 
00933     WOLFSSL_ENTER("wolfSSL_set_secret()");
00934 
00935     if (ssl == NULL || preMasterSecret == NULL ||
00936         preMasterSz == 0 || preMasterSz > ENCRYPT_LEN ||
00937         clientRandom == NULL || serverRandom == NULL || suite == NULL) {
00938 
00939         ret = BAD_FUNC_ARG;
00940     }
00941 
00942     if (ret == 0) {
00943         XMEMCPY(ssl->arrays->preMasterSecret, preMasterSecret, preMasterSz);
00944         ssl->arrays->preMasterSz = preMasterSz;
00945         XMEMCPY(ssl->arrays->clientRandom, clientRandom, RAN_LEN);
00946         XMEMCPY(ssl->arrays->serverRandom, serverRandom, RAN_LEN);
00947         ssl->options.cipherSuite0 = suite[0];
00948         ssl->options.cipherSuite = suite[1];
00949 
00950         ret = SetCipherSpecs(ssl);
00951     }
00952 
00953     if (ret == 0)
00954         ret = MakeTlsMasterSecret(ssl);
00955 
00956     if (ret == 0) {
00957         ssl->keys.encryptionOn = 1;
00958         ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE);
00959     }
00960 
00961     if (ret == 0) {
00962         if (ssl->options.dtls) {
00963         #ifdef WOLFSSL_DTLS
00964             WOLFSSL_DTLS_PEERSEQ* peerSeq;
00965             int i;
00966 
00967             ssl->keys.dtls_epoch = epoch;
00968             for (i = 0, peerSeq = ssl->keys.peerSeq;
00969                  i < WOLFSSL_DTLS_PEERSEQ_SZ;
00970                  i++, peerSeq++) {
00971 
00972                 peerSeq->nextEpoch = epoch;
00973                 peerSeq->prevSeq_lo = peerSeq->nextSeq_lo;
00974                 peerSeq->prevSeq_hi = peerSeq->nextSeq_hi;
00975                 peerSeq->nextSeq_lo = 0;
00976                 peerSeq->nextSeq_hi = 0;
00977                 XMEMCPY(peerSeq->prevWindow, peerSeq->window, DTLS_SEQ_SZ);
00978                 XMEMSET(peerSeq->window, 0, DTLS_SEQ_SZ);
00979                 peerSeq->highwaterMark = UpdateHighwaterMark(0,
00980                         ssl->ctx->mcastFirstSeq,
00981                         ssl->ctx->mcastSecondSeq,
00982                         ssl->ctx->mcastMaxSeq);
00983             }
00984         #else
00985             (void)epoch;
00986         #endif
00987         }
00988         FreeHandshakeResources(ssl);
00989         ret = WOLFSSL_SUCCESS;
00990     }
00991     else {
00992         if (ssl)
00993             ssl->error = ret;
00994         ret = WOLFSSL_FATAL_ERROR;
00995     }
00996     WOLFSSL_LEAVE("wolfSSL_set_secret()", ret);
00997     return ret;
00998 }
00999 
01000 
01001 #ifdef WOLFSSL_DTLS
01002 
01003 int wolfSSL_mcast_peer_add(WOLFSSL* ssl, word16 peerId, int remove)
01004 {
01005     WOLFSSL_DTLS_PEERSEQ* p = NULL;
01006     int ret = WOLFSSL_SUCCESS;
01007     int i;
01008 
01009     WOLFSSL_ENTER("wolfSSL_mcast_peer_add()");
01010     if (ssl == NULL || peerId > 255)
01011         return BAD_FUNC_ARG;
01012 
01013     if (!remove) {
01014         /* Make sure it isn't already present, while keeping the first
01015          * open spot. */
01016         for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
01017             if (ssl->keys.peerSeq[i].peerId == INVALID_PEER_ID)
01018                 p = &ssl->keys.peerSeq[i];
01019             if (ssl->keys.peerSeq[i].peerId == peerId) {
01020                 WOLFSSL_MSG("Peer ID already in multicast peer list.");
01021                 p = NULL;
01022             }
01023         }
01024 
01025         if (p != NULL) {
01026             XMEMSET(p, 0, sizeof(WOLFSSL_DTLS_PEERSEQ));
01027             p->peerId = peerId;
01028             p->highwaterMark = UpdateHighwaterMark(0,
01029                 ssl->ctx->mcastFirstSeq,
01030                 ssl->ctx->mcastSecondSeq,
01031                 ssl->ctx->mcastMaxSeq);
01032         }
01033         else {
01034             WOLFSSL_MSG("No room in peer list.");
01035             ret = -1;
01036         }
01037     }
01038     else {
01039         for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
01040             if (ssl->keys.peerSeq[i].peerId == peerId)
01041                 p = &ssl->keys.peerSeq[i];
01042         }
01043 
01044         if (p != NULL) {
01045             p->peerId = INVALID_PEER_ID;
01046         }
01047         else {
01048             WOLFSSL_MSG("Peer not found in list.");
01049         }
01050     }
01051 
01052     WOLFSSL_LEAVE("wolfSSL_mcast_peer_add()", ret);
01053     return ret;
01054 }
01055 
01056 
01057 /* If peerId is in the list of peers and its last sequence number is non-zero,
01058  * return 1, otherwise return 0. */
01059 int wolfSSL_mcast_peer_known(WOLFSSL* ssl, unsigned short peerId)
01060 {
01061     int known = 0;
01062     int i;
01063 
01064     WOLFSSL_ENTER("wolfSSL_mcast_peer_known()");
01065 
01066     if (ssl == NULL || peerId > 255) {
01067         return BAD_FUNC_ARG;
01068     }
01069 
01070     for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
01071         if (ssl->keys.peerSeq[i].peerId == peerId) {
01072             if (ssl->keys.peerSeq[i].nextSeq_hi ||
01073                 ssl->keys.peerSeq[i].nextSeq_lo) {
01074 
01075                 known = 1;
01076             }
01077             break;
01078         }
01079     }
01080 
01081     WOLFSSL_LEAVE("wolfSSL_mcast_peer_known()", known);
01082     return known;
01083 }
01084 
01085 
01086 int wolfSSL_CTX_mcast_set_highwater_cb(WOLFSSL_CTX* ctx, word32 maxSeq,
01087                                        word32 first, word32 second,
01088                                        CallbackMcastHighwater cb)
01089 {
01090     if (ctx == NULL || (second && first > second) ||
01091         first > maxSeq || second > maxSeq || cb == NULL) {
01092 
01093         return BAD_FUNC_ARG;
01094     }
01095 
01096     ctx->mcastHwCb = cb;
01097     ctx->mcastFirstSeq = first;
01098     ctx->mcastSecondSeq = second;
01099     ctx->mcastMaxSeq = maxSeq;
01100 
01101     return WOLFSSL_SUCCESS;
01102 }
01103 
01104 
01105 int wolfSSL_mcast_set_highwater_ctx(WOLFSSL* ssl, void* ctx)
01106 {
01107     if (ssl == NULL || ctx == NULL)
01108         return BAD_FUNC_ARG;
01109 
01110     ssl->mcastHwCbCtx = ctx;
01111 
01112     return WOLFSSL_SUCCESS;
01113 }
01114 
01115 #endif /* WOLFSSL_DTLS */
01116 
01117 #endif /* WOLFSSL_MULTICAST */
01118 
01119 
01120 #endif /* WOLFSSL_LEANPSK */
01121 
01122 
01123 /* return underlying connect or accept, WOLFSSL_SUCCESS on ok */
01124 int wolfSSL_negotiate(WOLFSSL* ssl)
01125 {
01126     int err = WOLFSSL_FATAL_ERROR;
01127 
01128     WOLFSSL_ENTER("wolfSSL_negotiate");
01129 #ifndef NO_WOLFSSL_SERVER
01130     if (ssl->options.side == WOLFSSL_SERVER_END) {
01131 #ifdef WOLFSSL_TLS13
01132         if (IsAtLeastTLSv1_3(ssl->version))
01133             err = wolfSSL_accept_TLSv13(ssl);
01134         else
01135 #endif
01136             err = wolfSSL_accept(ssl);
01137     }
01138 #endif
01139 
01140 #ifndef NO_WOLFSSL_CLIENT
01141     if (ssl->options.side == WOLFSSL_CLIENT_END) {
01142 #ifdef WOLFSSL_TLS13
01143         if (IsAtLeastTLSv1_3(ssl->version))
01144             err = wolfSSL_connect_TLSv13(ssl);
01145         else
01146 #endif
01147             err = wolfSSL_connect(ssl);
01148     }
01149 #endif
01150 
01151     (void)ssl;
01152 
01153     WOLFSSL_LEAVE("wolfSSL_negotiate", err);
01154 
01155     return err;
01156 }
01157 
01158 
01159 WC_RNG* wolfSSL_GetRNG(WOLFSSL* ssl)
01160 {
01161     if (ssl) {
01162         return ssl->rng;
01163     }
01164 
01165     return NULL;
01166 }
01167 
01168 
01169 #ifndef WOLFSSL_LEANPSK
01170 /* object size based on build */
01171 int wolfSSL_GetObjectSize(void)
01172 {
01173 #ifdef SHOW_SIZES
01174     printf("sizeof suites           = %lu\n", sizeof(Suites));
01175     printf("sizeof ciphers(2)       = %lu\n", sizeof(Ciphers));
01176 #ifndef NO_RC4
01177     printf("\tsizeof arc4         = %lu\n", sizeof(Arc4));
01178 #endif
01179     printf("\tsizeof aes          = %lu\n", sizeof(Aes));
01180 #ifndef NO_DES3
01181     printf("\tsizeof des3         = %lu\n", sizeof(Des3));
01182 #endif
01183 #ifndef NO_RABBIT
01184     printf("\tsizeof rabbit       = %lu\n", sizeof(Rabbit));
01185 #endif
01186 #ifdef HAVE_CHACHA
01187     printf("\tsizeof chacha       = %lu\n", sizeof(ChaCha));
01188 #endif
01189     printf("sizeof cipher specs     = %lu\n", sizeof(CipherSpecs));
01190     printf("sizeof keys             = %lu\n", sizeof(Keys));
01191     printf("sizeof Hashes(2)        = %lu\n", sizeof(Hashes));
01192 #ifndef NO_MD5
01193     printf("\tsizeof MD5          = %lu\n", sizeof(wc_Md5));
01194 #endif
01195 #ifndef NO_SHA
01196     printf("\tsizeof SHA          = %lu\n", sizeof(wc_Sha));
01197 #endif
01198 #ifdef WOLFSSL_SHA224
01199     printf("\tsizeof SHA224       = %lu\n", sizeof(wc_Sha224));
01200 #endif
01201 #ifndef NO_SHA256
01202     printf("\tsizeof SHA256       = %lu\n", sizeof(wc_Sha256));
01203 #endif
01204 #ifdef WOLFSSL_SHA384
01205     printf("\tsizeof SHA384       = %lu\n", sizeof(wc_Sha384));
01206 #endif
01207 #ifdef WOLFSSL_SHA384
01208     printf("\tsizeof SHA512       = %lu\n", sizeof(wc_Sha512));
01209 #endif
01210     printf("sizeof Buffers          = %lu\n", sizeof(Buffers));
01211     printf("sizeof Options          = %lu\n", sizeof(Options));
01212     printf("sizeof Arrays           = %lu\n", sizeof(Arrays));
01213 #ifndef NO_RSA
01214     printf("sizeof RsaKey           = %lu\n", sizeof(RsaKey));
01215 #endif
01216 #ifdef HAVE_ECC
01217     printf("sizeof ecc_key          = %lu\n", sizeof(ecc_key));
01218 #endif
01219     printf("sizeof WOLFSSL_CIPHER    = %lu\n", sizeof(WOLFSSL_CIPHER));
01220     printf("sizeof WOLFSSL_SESSION   = %lu\n", sizeof(WOLFSSL_SESSION));
01221     printf("sizeof WOLFSSL           = %lu\n", sizeof(WOLFSSL));
01222     printf("sizeof WOLFSSL_CTX       = %lu\n", sizeof(WOLFSSL_CTX));
01223 #endif
01224 
01225     return sizeof(WOLFSSL);
01226 }
01227 
01228 int wolfSSL_CTX_GetObjectSize(void)
01229 {
01230     return sizeof(WOLFSSL_CTX);
01231 }
01232 
01233 int wolfSSL_METHOD_GetObjectSize(void)
01234 {
01235     return sizeof(WOLFSSL_METHOD);
01236 }
01237 #endif
01238 
01239 
01240 #ifdef WOLFSSL_STATIC_MEMORY
01241 
01242 int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx, wolfSSL_method_func method,
01243                                    unsigned char* buf, unsigned int sz,
01244                                    int flag, int max)
01245 {
01246     WOLFSSL_HEAP*      heap;
01247     WOLFSSL_HEAP_HINT* hint;
01248     word32 idx = 0;
01249 
01250     if (ctx == NULL || buf == NULL) {
01251         return BAD_FUNC_ARG;
01252     }
01253 
01254     if (*ctx == NULL && method == NULL) {
01255         return BAD_FUNC_ARG;
01256     }
01257 
01258     if (*ctx == NULL || (*ctx)->heap == NULL) {
01259         if (sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT) > sz - idx) {
01260             return BUFFER_E; /* not enough memory for structures */
01261         }
01262         heap = (WOLFSSL_HEAP*)buf;
01263         idx += sizeof(WOLFSSL_HEAP);
01264         if (wolfSSL_init_memory_heap(heap) != 0) {
01265             return WOLFSSL_FAILURE;
01266         }
01267         hint = (WOLFSSL_HEAP_HINT*)(buf + idx);
01268         idx += sizeof(WOLFSSL_HEAP_HINT);
01269         XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT));
01270         hint->memory = heap;
01271 
01272         if (*ctx && (*ctx)->heap == NULL) {
01273             (*ctx)->heap = (void*)hint;
01274         }
01275     }
01276     else {
01277 #ifdef WOLFSSL_HEAP_TEST
01278         /* do not load in memory if test has been set */
01279         if ((*ctx)->heap == (void*)WOLFSSL_HEAP_TEST) {
01280             return WOLFSSL_SUCCESS;
01281         }
01282 #endif
01283         hint = (WOLFSSL_HEAP_HINT*)((*ctx)->heap);
01284         heap = hint->memory;
01285     }
01286 
01287     if (wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap) != 1) {
01288         WOLFSSL_MSG("Error partitioning memory");
01289         return WOLFSSL_FAILURE;
01290     }
01291 
01292     /* create ctx if needed */
01293     if (*ctx == NULL) {
01294         *ctx = wolfSSL_CTX_new_ex(method(hint), hint);
01295         if (*ctx == NULL) {
01296             WOLFSSL_MSG("Error creating ctx");
01297             return WOLFSSL_FAILURE;
01298         }
01299     }
01300 
01301     /* determine what max applies too */
01302     if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
01303         heap->maxIO = max;
01304     }
01305     else { /* general memory used in handshakes */
01306         heap->maxHa = max;
01307     }
01308 
01309     heap->flag |= flag;
01310 
01311     (void)max;
01312     (void)method;
01313 
01314     return WOLFSSL_SUCCESS;
01315 }
01316 
01317 
01318 int wolfSSL_is_static_memory(WOLFSSL* ssl, WOLFSSL_MEM_CONN_STATS* mem_stats)
01319 {
01320     if (ssl == NULL) {
01321         return BAD_FUNC_ARG;
01322     }
01323     WOLFSSL_ENTER("wolfSSL_is_static_memory");
01324 
01325     /* fill out statistics if wanted and WOLFMEM_TRACK_STATS flag */
01326     if (mem_stats != NULL && ssl->heap != NULL) {
01327         WOLFSSL_HEAP_HINT* hint = ((WOLFSSL_HEAP_HINT*)(ssl->heap));
01328         WOLFSSL_HEAP* heap      = hint->memory;
01329         if (heap->flag & WOLFMEM_TRACK_STATS && hint->stats != NULL) {
01330             XMEMCPY(mem_stats, hint->stats, sizeof(WOLFSSL_MEM_CONN_STATS));
01331         }
01332     }
01333 
01334     return (ssl->heap) ? 1 : 0;
01335 }
01336 
01337 
01338 int wolfSSL_CTX_is_static_memory(WOLFSSL_CTX* ctx, WOLFSSL_MEM_STATS* mem_stats)
01339 {
01340     if (ctx == NULL) {
01341         return BAD_FUNC_ARG;
01342     }
01343     WOLFSSL_ENTER("wolfSSL_CTX_is_static_memory");
01344 
01345     /* fill out statistics if wanted */
01346     if (mem_stats != NULL && ctx->heap != NULL) {
01347         WOLFSSL_HEAP* heap = ((WOLFSSL_HEAP_HINT*)(ctx->heap))->memory;
01348         if (wolfSSL_GetMemStats(heap, mem_stats) != 1) {
01349             return MEMORY_E;
01350         }
01351     }
01352 
01353     return (ctx->heap) ? 1 : 0;
01354 }
01355 
01356 #endif /* WOLFSSL_STATIC_MEMORY */
01357 
01358 
01359 /* return max record layer size plaintext input size */
01360 int wolfSSL_GetMaxOutputSize(WOLFSSL* ssl)
01361 {
01362     WOLFSSL_ENTER("wolfSSL_GetMaxOutputSize");
01363 
01364     if (ssl == NULL)
01365         return BAD_FUNC_ARG;
01366 
01367     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
01368         WOLFSSL_MSG("Handshake not complete yet");
01369         return BAD_FUNC_ARG;
01370     }
01371 
01372     return wolfSSL_GetMaxRecordSize(ssl, OUTPUT_RECORD_SIZE);
01373 }
01374 
01375 
01376 /* return record layer size of plaintext input size */
01377 int wolfSSL_GetOutputSize(WOLFSSL* ssl, int inSz)
01378 {
01379     int maxSize;
01380 
01381     WOLFSSL_ENTER("wolfSSL_GetOutputSize");
01382 
01383     if (inSz < 0)
01384         return BAD_FUNC_ARG;
01385 
01386     maxSize = wolfSSL_GetMaxOutputSize(ssl);
01387     if (maxSize < 0)
01388         return maxSize;   /* error */
01389     if (inSz > maxSize)
01390         return INPUT_SIZE_E;
01391 
01392     return BuildMessage(ssl, NULL, 0, NULL, inSz, application_data, 0, 1, 0);
01393 }
01394 
01395 
01396 #ifdef HAVE_ECC
01397 int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz)
01398 {
01399     if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
01400         WOLFSSL_MSG("Key size must be divisable by 8 or ctx was null");
01401         return BAD_FUNC_ARG;
01402     }
01403 
01404     ctx->minEccKeySz     = keySz / 8;
01405 #ifndef NO_CERTS
01406     ctx->cm->minEccKeySz = keySz / 8;
01407 #endif
01408     return WOLFSSL_SUCCESS;
01409 }
01410 
01411 
01412 int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz)
01413 {
01414     if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
01415         WOLFSSL_MSG("Key size must be divisable by 8 or ssl was null");
01416         return BAD_FUNC_ARG;
01417     }
01418 
01419     ssl->options.minEccKeySz = keySz / 8;
01420     return WOLFSSL_SUCCESS;
01421 }
01422 
01423 #endif /* !NO_RSA */
01424 
01425 #ifndef NO_RSA
01426 int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX* ctx, short keySz)
01427 {
01428     if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
01429         WOLFSSL_MSG("Key size must be divisable by 8 or ctx was null");
01430         return BAD_FUNC_ARG;
01431     }
01432 
01433     ctx->minRsaKeySz     = keySz / 8;
01434     ctx->cm->minRsaKeySz = keySz / 8;
01435     return WOLFSSL_SUCCESS;
01436 }
01437 
01438 
01439 int wolfSSL_SetMinRsaKey_Sz(WOLFSSL* ssl, short keySz)
01440 {
01441     if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
01442         WOLFSSL_MSG("Key size must be divisable by 8 or ssl was null");
01443         return BAD_FUNC_ARG;
01444     }
01445 
01446     ssl->options.minRsaKeySz = keySz / 8;
01447     return WOLFSSL_SUCCESS;
01448 }
01449 #endif /* !NO_RSA */
01450 
01451 #ifndef NO_DH
01452 /* server Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
01453 int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
01454                     const unsigned char* g, int gSz)
01455 {
01456     word16 havePSK = 0;
01457     word16 haveRSA = 1;
01458     int    keySz   = 0;
01459 
01460     WOLFSSL_ENTER("wolfSSL_SetTmpDH");
01461     if (ssl == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
01462 
01463     if (pSz < ssl->options.minDhKeySz)
01464         return DH_KEY_SIZE_E;
01465     if (pSz > ssl->options.maxDhKeySz)
01466         return DH_KEY_SIZE_E;
01467 
01468     if (ssl->options.side != WOLFSSL_SERVER_END)
01469         return SIDE_ERROR;
01470 
01471     if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
01472         XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
01473         ssl->buffers.serverDH_P.buffer = NULL;
01474     }
01475     if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
01476         XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
01477         ssl->buffers.serverDH_G.buffer = NULL;
01478     }
01479 
01480     ssl->buffers.weOwnDH = 1;  /* SSL owns now */
01481     ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->heap,
01482                                                     DYNAMIC_TYPE_PUBLIC_KEY);
01483     if (ssl->buffers.serverDH_P.buffer == NULL)
01484             return MEMORY_E;
01485 
01486     ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, ssl->heap,
01487                                                     DYNAMIC_TYPE_PUBLIC_KEY);
01488     if (ssl->buffers.serverDH_G.buffer == NULL) {
01489         XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
01490         ssl->buffers.serverDH_P.buffer = NULL;
01491         return MEMORY_E;
01492     }
01493 
01494     ssl->buffers.serverDH_P.length = pSz;
01495     ssl->buffers.serverDH_G.length = gSz;
01496 
01497     XMEMCPY(ssl->buffers.serverDH_P.buffer, p, pSz);
01498     XMEMCPY(ssl->buffers.serverDH_G.buffer, g, gSz);
01499 
01500     ssl->options.haveDH = 1;
01501     #ifndef NO_PSK
01502         havePSK = ssl->options.havePSK;
01503     #endif
01504     #ifdef NO_RSA
01505         haveRSA = 0;
01506     #endif
01507     #ifndef NO_CERTS
01508         keySz = ssl->buffers.keySz;
01509     #endif
01510     InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
01511                ssl->options.haveDH, ssl->options.haveNTRU,
01512                ssl->options.haveECDSAsig, ssl->options.haveECC,
01513                ssl->options.haveStaticECC, ssl->options.side);
01514 
01515     WOLFSSL_LEAVE("wolfSSL_SetTmpDH", 0);
01516     return WOLFSSL_SUCCESS;
01517 }
01518 
01519 /* server ctx Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
01520 int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
01521                          const unsigned char* g, int gSz)
01522 {
01523     WOLFSSL_ENTER("wolfSSL_CTX_SetTmpDH");
01524     if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
01525 
01526     if (pSz < ctx->minDhKeySz)
01527         return DH_KEY_SIZE_E;
01528     if (pSz > ctx->maxDhKeySz)
01529         return DH_KEY_SIZE_E;
01530 
01531     XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
01532     XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
01533 
01534     ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
01535     if (ctx->serverDH_P.buffer == NULL)
01536        return MEMORY_E;
01537 
01538     ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
01539     if (ctx->serverDH_G.buffer == NULL) {
01540         XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
01541         return MEMORY_E;
01542     }
01543 
01544     ctx->serverDH_P.length = pSz;
01545     ctx->serverDH_G.length = gSz;
01546 
01547     XMEMCPY(ctx->serverDH_P.buffer, p, pSz);
01548     XMEMCPY(ctx->serverDH_G.buffer, g, gSz);
01549 
01550     ctx->haveDH = 1;
01551 
01552     WOLFSSL_LEAVE("wolfSSL_CTX_SetTmpDH", 0);
01553     return WOLFSSL_SUCCESS;
01554 }
01555 
01556 
01557 int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz)
01558 {
01559     if (ctx == NULL || keySz > 16000 || keySz % 8 != 0)
01560         return BAD_FUNC_ARG;
01561 
01562     ctx->minDhKeySz = keySz / 8;
01563     return WOLFSSL_SUCCESS;
01564 }
01565 
01566 
01567 int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz)
01568 {
01569     if (ssl == NULL || keySz > 16000 || keySz % 8 != 0)
01570         return BAD_FUNC_ARG;
01571 
01572     ssl->options.minDhKeySz = keySz / 8;
01573     return WOLFSSL_SUCCESS;
01574 }
01575 
01576 
01577 int wolfSSL_CTX_SetMaxDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz)
01578 {
01579     if (ctx == NULL || keySz > 16000 || keySz % 8 != 0)
01580         return BAD_FUNC_ARG;
01581 
01582     ctx->maxDhKeySz = keySz / 8;
01583     return WOLFSSL_SUCCESS;
01584 }
01585 
01586 
01587 int wolfSSL_SetMaxDhKey_Sz(WOLFSSL* ssl, word16 keySz)
01588 {
01589     if (ssl == NULL || keySz > 16000 || keySz % 8 != 0)
01590         return BAD_FUNC_ARG;
01591 
01592     ssl->options.maxDhKeySz = keySz / 8;
01593     return WOLFSSL_SUCCESS;
01594 }
01595 
01596 
01597 int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl)
01598 {
01599     if (ssl == NULL)
01600         return BAD_FUNC_ARG;
01601 
01602     return (ssl->options.dhKeySz * 8);
01603 }
01604 
01605 #endif /* !NO_DH */
01606 
01607 
01608 int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
01609 {
01610     int ret;
01611 
01612     WOLFSSL_ENTER("SSL_write()");
01613 
01614     if (ssl == NULL || data == NULL || sz < 0)
01615         return BAD_FUNC_ARG;
01616 
01617 #ifdef WOLFSSL_EARLY_DATA
01618     if (ssl->earlyData != no_early_data && (ret = wolfSSL_negotiate(ssl)) < 0) {
01619         ssl->error = ret;
01620         return WOLFSSL_FATAL_ERROR;
01621     }
01622     ssl->earlyData = no_early_data;
01623 #endif
01624 
01625 #ifdef HAVE_WRITE_DUP
01626     { /* local variable scope */
01627         int dupErr = 0;   /* local copy */
01628 
01629         ret = 0;
01630 
01631         if (ssl->dupWrite && ssl->dupSide == READ_DUP_SIDE) {
01632             WOLFSSL_MSG("Read dup side cannot write");
01633             return WRITE_DUP_WRITE_E;
01634         }
01635         if (ssl->dupWrite) {
01636             if (wc_LockMutex(&ssl->dupWrite->dupMutex) != 0) {
01637                 return BAD_MUTEX_E;
01638             }
01639             dupErr = ssl->dupWrite->dupErr;
01640             ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
01641         }
01642 
01643         if (ret != 0) {
01644             ssl->error = ret;  /* high priority fatal error */
01645             return WOLFSSL_FATAL_ERROR;
01646         }
01647         if (dupErr != 0) {
01648             WOLFSSL_MSG("Write dup error from other side");
01649             ssl->error = dupErr;
01650             return WOLFSSL_FATAL_ERROR;
01651         }
01652     }
01653 #endif
01654 
01655 #ifdef HAVE_ERRNO_H
01656     errno = 0;
01657 #endif
01658 
01659     #ifdef OPENSSL_EXTRA
01660     if (ssl->CBIS != NULL) {
01661         ssl->CBIS(ssl, SSL_CB_WRITE, SSL_SUCCESS);
01662         ssl->cbmode = SSL_CB_WRITE;
01663     }
01664     #endif
01665     ret = SendData(ssl, data, sz);
01666 
01667     WOLFSSL_LEAVE("SSL_write()", ret);
01668 
01669     if (ret < 0)
01670         return WOLFSSL_FATAL_ERROR;
01671     else
01672         return ret;
01673 }
01674 
01675 static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
01676 {
01677     int ret;
01678 
01679     WOLFSSL_ENTER("wolfSSL_read_internal()");
01680 
01681     if (ssl == NULL || data == NULL || sz < 0)
01682         return BAD_FUNC_ARG;
01683 
01684 #ifdef HAVE_WRITE_DUP
01685     if (ssl->dupWrite && ssl->dupSide == WRITE_DUP_SIDE) {
01686         WOLFSSL_MSG("Write dup side cannot read");
01687         return WRITE_DUP_READ_E;
01688     }
01689 #endif
01690 
01691 #ifdef HAVE_ERRNO_H
01692         errno = 0;
01693 #endif
01694 
01695 #ifdef WOLFSSL_DTLS
01696     if (ssl->options.dtls) {
01697         ssl->dtls_expected_rx = max(sz + 100, MAX_MTU);
01698 #ifdef WOLFSSL_SCTP
01699         if (ssl->options.dtlsSctp)
01700             ssl->dtls_expected_rx = max(ssl->dtls_expected_rx, ssl->dtlsMtuSz);
01701 #endif
01702     }
01703 #endif
01704 
01705     sz = wolfSSL_GetMaxRecordSize(ssl, sz);
01706 
01707     ret = ReceiveData(ssl, (byte*)data, sz, peek);
01708 
01709 #ifdef HAVE_WRITE_DUP
01710     if (ssl->dupWrite) {
01711         if (ssl->error != 0 && ssl->error != WANT_READ
01712         #ifdef WOLFSSL_ASYNC_CRYPT
01713             && ssl->error != WC_PENDING_E
01714         #endif
01715         ) {
01716             int notifyErr;
01717 
01718             WOLFSSL_MSG("Notifying write side of fatal read error");
01719             notifyErr  = NotifyWriteSide(ssl, ssl->error);
01720             if (notifyErr < 0) {
01721                 ret = ssl->error = notifyErr;
01722             }
01723         }
01724     }
01725 #endif
01726 
01727     WOLFSSL_LEAVE("wolfSSL_read_internal()", ret);
01728 
01729     if (ret < 0)
01730         return WOLFSSL_FATAL_ERROR;
01731     else
01732         return ret;
01733 }
01734 
01735 
01736 int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz)
01737 {
01738     WOLFSSL_ENTER("wolfSSL_peek()");
01739 
01740     return wolfSSL_read_internal(ssl, data, sz, TRUE);
01741 }
01742 
01743 
01744 int wolfSSL_read(WOLFSSL* ssl, void* data, int sz)
01745 {
01746     WOLFSSL_ENTER("wolfSSL_read()");
01747 
01748     #ifdef OPENSSL_EXTRA
01749     if (ssl->CBIS != NULL) {
01750         ssl->CBIS(ssl, SSL_CB_READ, SSL_SUCCESS);
01751         ssl->cbmode = SSL_CB_READ;
01752     }
01753     #endif
01754     return wolfSSL_read_internal(ssl, data, sz, FALSE);
01755 }
01756 
01757 
01758 #ifdef WOLFSSL_MULTICAST
01759 
01760 int wolfSSL_mcast_read(WOLFSSL* ssl, word16* id, void* data, int sz)
01761 {
01762     int ret = 0;
01763 
01764     WOLFSSL_ENTER("wolfSSL_mcast_read()");
01765 
01766     if (ssl == NULL)
01767         return BAD_FUNC_ARG;
01768 
01769     ret = wolfSSL_read_internal(ssl, data, sz, FALSE);
01770     if (ssl->options.dtls && ssl->options.haveMcast && id != NULL)
01771         *id = ssl->keys.curPeerId;
01772     return ret;
01773 }
01774 
01775 #endif /* WOLFSSL_MULTICAST */
01776 
01777 
01778 /* helpers to set the device id, WOLFSSL_SUCCESS on ok */
01779 int wolfSSL_SetDevId(WOLFSSL* ssl, int devId)
01780 {
01781     if (ssl == NULL)
01782         return BAD_FUNC_ARG;
01783 
01784     ssl->devId = devId;
01785 
01786     return WOLFSSL_SUCCESS;
01787 }
01788 int wolfSSL_CTX_SetDevId(WOLFSSL_CTX* ctx, int devId)
01789 {
01790     if (ctx == NULL)
01791         return BAD_FUNC_ARG;
01792 
01793     ctx->devId = devId;
01794 
01795     return WOLFSSL_SUCCESS;
01796 }
01797 
01798 /* helpers to get device id and heap */
01799 int wolfSSL_CTX_GetDevId(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
01800 {
01801     int devId = INVALID_DEVID;
01802     if (ctx != NULL)
01803         devId = ctx->devId;
01804     else if (ssl != NULL)
01805         devId = ssl->devId;
01806     return devId;
01807 }
01808 void* wolfSSL_CTX_GetHeap(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
01809 {
01810     void* heap = NULL;
01811     if (ctx != NULL)
01812         heap = ctx->heap;
01813     else if (ssl != NULL)
01814         heap = ssl->heap;
01815     return heap;
01816 }
01817 
01818 
01819 #ifdef HAVE_SNI
01820 
01821 int wolfSSL_UseSNI(WOLFSSL* ssl, byte type, const void* data, word16 size)
01822 {
01823     if (ssl == NULL)
01824         return BAD_FUNC_ARG;
01825 
01826     return TLSX_UseSNI(&ssl->extensions, type, data, size, ssl->heap);
01827 }
01828 
01829 
01830 int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, const void* data,
01831                                                                     word16 size)
01832 {
01833     if (ctx == NULL)
01834         return BAD_FUNC_ARG;
01835 
01836     return TLSX_UseSNI(&ctx->extensions, type, data, size, ctx->heap);
01837 }
01838 
01839 #ifndef NO_WOLFSSL_SERVER
01840 
01841 void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options)
01842 {
01843     if (ssl && ssl->extensions)
01844         TLSX_SNI_SetOptions(ssl->extensions, type, options);
01845 }
01846 
01847 
01848 void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options)
01849 {
01850     if (ctx && ctx->extensions)
01851         TLSX_SNI_SetOptions(ctx->extensions, type, options);
01852 }
01853 
01854 
01855 byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type)
01856 {
01857     return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type);
01858 }
01859 
01860 
01861 word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data)
01862 {
01863     if (data)
01864         *data = NULL;
01865 
01866     if (ssl && ssl->extensions)
01867         return TLSX_SNI_GetRequest(ssl->extensions, type, data);
01868 
01869     return 0;
01870 }
01871 
01872 
01873 int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
01874                               byte type, byte* sni, word32* inOutSz)
01875 {
01876     if (clientHello && helloSz > 0 && sni && inOutSz && *inOutSz > 0)
01877         return TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
01878 
01879     return BAD_FUNC_ARG;
01880 }
01881 
01882 #endif /* NO_WOLFSSL_SERVER */
01883 
01884 #endif /* HAVE_SNI */
01885 
01886 
01887 #ifdef HAVE_MAX_FRAGMENT
01888 #ifndef NO_WOLFSSL_CLIENT
01889 
01890 int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl)
01891 {
01892     if (ssl == NULL)
01893         return BAD_FUNC_ARG;
01894 
01895     return TLSX_UseMaxFragment(&ssl->extensions, mfl, ssl->heap);
01896 }
01897 
01898 
01899 int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl)
01900 {
01901     if (ctx == NULL)
01902         return BAD_FUNC_ARG;
01903 
01904     return TLSX_UseMaxFragment(&ctx->extensions, mfl, ctx->heap);
01905 }
01906 
01907 #endif /* NO_WOLFSSL_CLIENT */
01908 #endif /* HAVE_MAX_FRAGMENT */
01909 
01910 #ifdef HAVE_TRUNCATED_HMAC
01911 #ifndef NO_WOLFSSL_CLIENT
01912 
01913 int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl)
01914 {
01915     if (ssl == NULL)
01916         return BAD_FUNC_ARG;
01917 
01918     return TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap);
01919 }
01920 
01921 
01922 int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
01923 {
01924     if (ctx == NULL)
01925         return BAD_FUNC_ARG;
01926 
01927     return TLSX_UseTruncatedHMAC(&ctx->extensions, ctx->heap);
01928 }
01929 
01930 #endif /* NO_WOLFSSL_CLIENT */
01931 #endif /* HAVE_TRUNCATED_HMAC */
01932 
01933 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
01934 
01935 int wolfSSL_UseOCSPStapling(WOLFSSL* ssl, byte status_type, byte options)
01936 {
01937     if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
01938         return BAD_FUNC_ARG;
01939 
01940     return TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
01941                                           options, NULL, ssl->heap, ssl->devId);
01942 }
01943 
01944 
01945 int wolfSSL_CTX_UseOCSPStapling(WOLFSSL_CTX* ctx, byte status_type,
01946                                                                    byte options)
01947 {
01948     if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
01949         return BAD_FUNC_ARG;
01950 
01951     return TLSX_UseCertificateStatusRequest(&ctx->extensions, status_type,
01952                                           options, NULL, ctx->heap, ctx->devId);
01953 }
01954 
01955 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
01956 
01957 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
01958 
01959 int wolfSSL_UseOCSPStaplingV2(WOLFSSL* ssl, byte status_type, byte options)
01960 {
01961     if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
01962         return BAD_FUNC_ARG;
01963 
01964     return TLSX_UseCertificateStatusRequestV2(&ssl->extensions, status_type,
01965                                                 options, ssl->heap, ssl->devId);
01966 }
01967 
01968 
01969 int wolfSSL_CTX_UseOCSPStaplingV2(WOLFSSL_CTX* ctx, byte status_type,
01970                                                                    byte options)
01971 {
01972     if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
01973         return BAD_FUNC_ARG;
01974 
01975     return TLSX_UseCertificateStatusRequestV2(&ctx->extensions, status_type,
01976                                                 options, ctx->heap, ctx->devId);
01977 }
01978 
01979 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
01980 
01981 /* Elliptic Curves */
01982 #ifdef HAVE_SUPPORTED_CURVES
01983 #ifndef NO_WOLFSSL_CLIENT
01984 
01985 int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
01986 {
01987     if (ssl == NULL)
01988         return BAD_FUNC_ARG;
01989 
01990     switch (name) {
01991         case WOLFSSL_ECC_SECP160K1:
01992         case WOLFSSL_ECC_SECP160R1:
01993         case WOLFSSL_ECC_SECP160R2:
01994         case WOLFSSL_ECC_SECP192K1:
01995         case WOLFSSL_ECC_SECP192R1:
01996         case WOLFSSL_ECC_SECP224K1:
01997         case WOLFSSL_ECC_SECP224R1:
01998         case WOLFSSL_ECC_SECP256K1:
01999         case WOLFSSL_ECC_SECP256R1:
02000         case WOLFSSL_ECC_SECP384R1:
02001         case WOLFSSL_ECC_SECP521R1:
02002         case WOLFSSL_ECC_BRAINPOOLP256R1:
02003         case WOLFSSL_ECC_BRAINPOOLP384R1:
02004         case WOLFSSL_ECC_BRAINPOOLP512R1:
02005         case WOLFSSL_ECC_X25519:
02006             break;
02007 
02008 #ifdef WOLFSSL_TLS13
02009         case WOLFSSL_FFDHE_2048:
02010         case WOLFSSL_FFDHE_3072:
02011         case WOLFSSL_FFDHE_4096:
02012         case WOLFSSL_FFDHE_6144:
02013         case WOLFSSL_FFDHE_8192:
02014             if (!IsAtLeastTLSv1_3(ssl->version))
02015                 return WOLFSSL_SUCCESS;
02016             break;
02017 #endif
02018 
02019         default:
02020             return BAD_FUNC_ARG;
02021     }
02022 
02023     ssl->options.userCurves = 1;
02024 
02025     return TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap);
02026 }
02027 
02028 
02029 int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
02030 {
02031     if (ctx == NULL)
02032         return BAD_FUNC_ARG;
02033 
02034     switch (name) {
02035         case WOLFSSL_ECC_SECP160K1:
02036         case WOLFSSL_ECC_SECP160R1:
02037         case WOLFSSL_ECC_SECP160R2:
02038         case WOLFSSL_ECC_SECP192K1:
02039         case WOLFSSL_ECC_SECP192R1:
02040         case WOLFSSL_ECC_SECP224K1:
02041         case WOLFSSL_ECC_SECP224R1:
02042         case WOLFSSL_ECC_SECP256K1:
02043         case WOLFSSL_ECC_SECP256R1:
02044         case WOLFSSL_ECC_SECP384R1:
02045         case WOLFSSL_ECC_SECP521R1:
02046         case WOLFSSL_ECC_BRAINPOOLP256R1:
02047         case WOLFSSL_ECC_BRAINPOOLP384R1:
02048         case WOLFSSL_ECC_BRAINPOOLP512R1:
02049         case WOLFSSL_ECC_X25519:
02050             break;
02051 
02052 #ifdef WOLFSSL_TLS13
02053         case WOLFSSL_FFDHE_2048:
02054         case WOLFSSL_FFDHE_3072:
02055         case WOLFSSL_FFDHE_4096:
02056         case WOLFSSL_FFDHE_6144:
02057         case WOLFSSL_FFDHE_8192:
02058             break;
02059 #endif
02060 
02061         default:
02062             return BAD_FUNC_ARG;
02063     }
02064 
02065     ctx->userCurves = 1;
02066 
02067     return TLSX_UseSupportedCurve(&ctx->extensions, name, ctx->heap);
02068 }
02069 
02070 #endif /* NO_WOLFSSL_CLIENT */
02071 #endif /* HAVE_SUPPORTED_CURVES */
02072 
02073 /* QSH quantum safe handshake */
02074 #ifdef HAVE_QSH
02075 /* returns 1 if QSH has been used 0 otherwise */
02076 int wolfSSL_isQSH(WOLFSSL* ssl)
02077 {
02078     /* if no ssl struct than QSH was not used */
02079     if (ssl == NULL)
02080         return 0;
02081 
02082     return ssl->isQSH;
02083 }
02084 
02085 
02086 int wolfSSL_UseSupportedQSH(WOLFSSL* ssl, word16 name)
02087 {
02088     if (ssl == NULL)
02089         return BAD_FUNC_ARG;
02090 
02091     switch (name) {
02092     #ifdef HAVE_NTRU
02093         case WOLFSSL_NTRU_EESS439:
02094         case WOLFSSL_NTRU_EESS593:
02095         case WOLFSSL_NTRU_EESS743:
02096             break;
02097     #endif
02098         default:
02099             return BAD_FUNC_ARG;
02100     }
02101 
02102     ssl->user_set_QSHSchemes = 1;
02103 
02104     return TLSX_UseQSHScheme(&ssl->extensions, name, NULL, 0, ssl->heap);
02105 }
02106 
02107 #ifndef NO_WOLFSSL_CLIENT
02108     /* user control over sending client public key in hello
02109        when flag = 1 will send keys if flag is 0 or function is not called
02110        then will not send keys in the hello extension
02111        return 0 on success
02112      */
02113     int wolfSSL_UseClientQSHKeys(WOLFSSL* ssl, unsigned char flag)
02114     {
02115         if (ssl == NULL)
02116             return BAD_FUNC_ARG;
02117 
02118         ssl->sendQSHKeys = flag;
02119 
02120         return 0;
02121     }
02122 #endif /* NO_WOLFSSL_CLIENT */
02123 #endif /* HAVE_QSH */
02124 
02125 /* Application-Layer Protocol Negotiation */
02126 #ifdef HAVE_ALPN
02127 
02128 int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
02129                     word32 protocol_name_listSz, byte options)
02130 {
02131     char    *list, *ptr, *token[10];
02132     word16  len;
02133     int     idx = 0;
02134     int     ret = WOLFSSL_FAILURE;
02135 
02136     WOLFSSL_ENTER("wolfSSL_UseALPN");
02137 
02138     if (ssl == NULL || protocol_name_list == NULL)
02139         return BAD_FUNC_ARG;
02140 
02141     if (protocol_name_listSz > (WOLFSSL_MAX_ALPN_NUMBER *
02142                                 WOLFSSL_MAX_ALPN_PROTO_NAME_LEN +
02143                                 WOLFSSL_MAX_ALPN_NUMBER)) {
02144         WOLFSSL_MSG("Invalid arguments, protocol name list too long");
02145         return BAD_FUNC_ARG;
02146     }
02147 
02148     if (!(options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) &&
02149         !(options & WOLFSSL_ALPN_FAILED_ON_MISMATCH)) {
02150             WOLFSSL_MSG("Invalid arguments, options not supported");
02151             return BAD_FUNC_ARG;
02152         }
02153 
02154 
02155     list = (char *)XMALLOC(protocol_name_listSz+1, ssl->heap,
02156                            DYNAMIC_TYPE_ALPN);
02157     if (list == NULL) {
02158         WOLFSSL_MSG("Memory failure");
02159         return MEMORY_ERROR;
02160     }
02161 
02162     XSTRNCPY(list, protocol_name_list, protocol_name_listSz);
02163     list[protocol_name_listSz] = '\0';
02164 
02165     /* read all protocol name from the list */
02166     token[idx] = XSTRTOK(list, ",", &ptr);
02167     while (token[idx] != NULL)
02168         token[++idx] = XSTRTOK(NULL, ",", &ptr);
02169 
02170     /* add protocol name list in the TLS extension in reverse order */
02171     while ((idx--) > 0) {
02172         len = (word16)XSTRLEN(token[idx]);
02173 
02174         ret = TLSX_UseALPN(&ssl->extensions, token[idx], len, options,
02175                                                                      ssl->heap);
02176         if (ret != WOLFSSL_SUCCESS) {
02177             WOLFSSL_MSG("TLSX_UseALPN failure");
02178             break;
02179         }
02180     }
02181 
02182     XFREE(list, ssl->heap, DYNAMIC_TYPE_ALPN);
02183 
02184     return ret;
02185 }
02186 
02187 int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name, word16 *size)
02188 {
02189     return TLSX_ALPN_GetRequest(ssl ? ssl->extensions : NULL,
02190                                (void **)protocol_name, size);
02191 }
02192 
02193 int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, word16 *listSz)
02194 {
02195     if (list == NULL || listSz == NULL)
02196         return BAD_FUNC_ARG;
02197 
02198     if (ssl->alpn_client_list == NULL)
02199         return BUFFER_ERROR;
02200 
02201     *listSz = (word16)XSTRLEN(ssl->alpn_client_list);
02202     if (*listSz == 0)
02203         return BUFFER_ERROR;
02204 
02205     *list = (char *)XMALLOC((*listSz)+1, ssl->heap, DYNAMIC_TYPE_TLSX);
02206     if (*list == NULL)
02207         return MEMORY_ERROR;
02208 
02209     XSTRNCPY(*list, ssl->alpn_client_list, (*listSz)+1);
02210     (*list)[*listSz] = 0;
02211 
02212     return WOLFSSL_SUCCESS;
02213 }
02214 
02215 
02216 /* used to free memory allocated by wolfSSL_ALPN_GetPeerProtocol */
02217 int wolfSSL_ALPN_FreePeerProtocol(WOLFSSL* ssl, char **list)
02218 {
02219     if (ssl == NULL) {
02220         return BAD_FUNC_ARG;
02221     }
02222 
02223     XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
02224     *list = NULL;
02225 
02226     return WOLFSSL_SUCCESS;
02227 }
02228 
02229 #endif /* HAVE_ALPN */
02230 
02231 /* Secure Renegotiation */
02232 #ifdef HAVE_SECURE_RENEGOTIATION
02233 
02234 /* user is forcing ability to use secure renegotiation, we discourage it */
02235 int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl)
02236 {
02237     int ret = BAD_FUNC_ARG;
02238 
02239     if (ssl)
02240         ret = TLSX_UseSecureRenegotiation(&ssl->extensions, ssl->heap);
02241 
02242     if (ret == WOLFSSL_SUCCESS) {
02243         TLSX* extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO);
02244 
02245         if (extension)
02246             ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
02247     }
02248 
02249     return ret;
02250 }
02251 
02252 
02253 /* do a secure renegotiation handshake, user forced, we discourage */
02254 int wolfSSL_Rehandshake(WOLFSSL* ssl)
02255 {
02256     int ret;
02257 
02258     if (ssl == NULL)
02259         return BAD_FUNC_ARG;
02260 
02261     if (ssl->secure_renegotiation == NULL) {
02262         WOLFSSL_MSG("Secure Renegotiation not forced on by user");
02263         return SECURE_RENEGOTIATION_E;
02264     }
02265 
02266     if (ssl->secure_renegotiation->enabled == 0) {
02267         WOLFSSL_MSG("Secure Renegotiation not enabled at extension level");
02268         return SECURE_RENEGOTIATION_E;
02269     }
02270 
02271     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
02272         WOLFSSL_MSG("Can't renegotiate until previous handshake complete");
02273         return SECURE_RENEGOTIATION_E;
02274     }
02275 
02276 #ifndef NO_FORCE_SCR_SAME_SUITE
02277     /* force same suite */
02278     if (ssl->suites) {
02279         ssl->suites->suiteSz = SUITE_LEN;
02280         ssl->suites->suites[0] = ssl->options.cipherSuite0;
02281         ssl->suites->suites[1] = ssl->options.cipherSuite;
02282     }
02283 #endif
02284 
02285     /* reset handshake states */
02286     ssl->options.serverState = NULL_STATE;
02287     ssl->options.clientState = NULL_STATE;
02288     ssl->options.connectState  = CONNECT_BEGIN;
02289     ssl->options.acceptState   = ACCEPT_BEGIN;
02290     ssl->options.handShakeState = NULL_STATE;
02291     ssl->options.processReply  = 0;  /* TODO, move states in internal.h */
02292 
02293     XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
02294 
02295     ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
02296 
02297     ret = InitHandshakeHashes(ssl);
02298     if (ret !=0)
02299         return ret;
02300 
02301     ret = wolfSSL_negotiate(ssl);
02302     return ret;
02303 }
02304 
02305 #endif /* HAVE_SECURE_RENEGOTIATION */
02306 
02307 /* Session Ticket */
02308 #if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SESSION_TICKET)
02309 /* WOLFSSL_SUCCESS on ok */
02310 int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
02311 {
02312     if (ctx == NULL)
02313         return BAD_FUNC_ARG;
02314 
02315     ctx->ticketEncCb = cb;
02316 
02317     return WOLFSSL_SUCCESS;
02318 }
02319 
02320 /* set hint interval, WOLFSSL_SUCCESS on ok */
02321 int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
02322 {
02323     if (ctx == NULL)
02324         return BAD_FUNC_ARG;
02325 
02326     ctx->ticketHint = hint;
02327 
02328     return WOLFSSL_SUCCESS;
02329 }
02330 
02331 /* set user context, WOLFSSL_SUCCESS on ok */
02332 int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void* userCtx)
02333 {
02334     if (ctx == NULL)
02335         return BAD_FUNC_ARG;
02336 
02337     ctx->ticketEncCtx = userCtx;
02338 
02339     return WOLFSSL_SUCCESS;
02340 }
02341 
02342 #endif /* !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET) */
02343 
02344 /* Session Ticket */
02345 #if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET)
02346 int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
02347 {
02348     if (ssl == NULL)
02349         return BAD_FUNC_ARG;
02350 
02351     return TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
02352 }
02353 
02354 int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx)
02355 {
02356     if (ctx == NULL)
02357         return BAD_FUNC_ARG;
02358 
02359     return TLSX_UseSessionTicket(&ctx->extensions, NULL, ctx->heap);
02360 }
02361 
02362 WOLFSSL_API int wolfSSL_get_SessionTicket(WOLFSSL* ssl,
02363                                           byte* buf, word32* bufSz)
02364 {
02365     if (ssl == NULL || buf == NULL || bufSz == NULL || *bufSz == 0)
02366         return BAD_FUNC_ARG;
02367 
02368     if (ssl->session.ticketLen <= *bufSz) {
02369         XMEMCPY(buf, ssl->session.ticket, ssl->session.ticketLen);
02370         *bufSz = ssl->session.ticketLen;
02371     }
02372     else
02373         *bufSz = 0;
02374 
02375     return WOLFSSL_SUCCESS;
02376 }
02377 
02378 WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const byte* buf,
02379                                           word32 bufSz)
02380 {
02381     if (ssl == NULL || (buf == NULL && bufSz > 0))
02382         return BAD_FUNC_ARG;
02383 
02384     if (bufSz > 0) {
02385         /* Ticket will fit into static ticket */
02386         if(bufSz <= SESSION_TICKET_LEN) {
02387             if (ssl->session.isDynamic) {
02388                 XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
02389                 ssl->session.isDynamic = 0;
02390                 ssl->session.ticket = ssl->session.staticTicket;
02391             }
02392         } else { /* Ticket requires dynamic ticket storage */
02393             if (ssl->session.ticketLen < bufSz) { /* is dyn buffer big enough */
02394                 if(ssl->session.isDynamic)
02395                     XFREE(ssl->session.ticket, ssl->heap,
02396                             DYNAMIC_TYPE_SESSION_TICK);
02397                 ssl->session.ticket = (byte*)XMALLOC(bufSz, ssl->heap,
02398                         DYNAMIC_TYPE_SESSION_TICK);
02399                 if(!ssl->session.ticket) {
02400                     ssl->session.ticket = ssl->session.staticTicket;
02401                     ssl->session.isDynamic = 0;
02402                     return MEMORY_ERROR;
02403                 }
02404                 ssl->session.isDynamic = 1;
02405             }
02406         }
02407         XMEMCPY(ssl->session.ticket, buf, bufSz);
02408     }
02409     ssl->session.ticketLen = (word16)bufSz;
02410 
02411     return WOLFSSL_SUCCESS;
02412 }
02413 
02414 
02415 WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
02416                                             CallbackSessionTicket cb, void* ctx)
02417 {
02418     if (ssl == NULL)
02419         return BAD_FUNC_ARG;
02420 
02421     ssl->session_ticket_cb = cb;
02422     ssl->session_ticket_ctx = ctx;
02423 
02424     return WOLFSSL_SUCCESS;
02425 }
02426 #endif
02427 
02428 
02429 #ifdef HAVE_EXTENDED_MASTER
02430 #ifndef NO_WOLFSSL_CLIENT
02431 
02432 int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx)
02433 {
02434     if (ctx == NULL)
02435         return BAD_FUNC_ARG;
02436 
02437     ctx->haveEMS = 0;
02438 
02439     return WOLFSSL_SUCCESS;
02440 }
02441 
02442 
02443 int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl)
02444 {
02445     if (ssl == NULL)
02446         return BAD_FUNC_ARG;
02447 
02448     ssl->options.haveEMS = 0;
02449 
02450     return WOLFSSL_SUCCESS;
02451 }
02452 
02453 #endif
02454 #endif
02455 
02456 
02457 #ifndef WOLFSSL_LEANPSK
02458 
02459 int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags)
02460 {
02461     int ret;
02462     int oldFlags;
02463 
02464     WOLFSSL_ENTER("wolfSSL_send()");
02465 
02466     if (ssl == NULL || data == NULL || sz < 0)
02467         return BAD_FUNC_ARG;
02468 
02469     oldFlags = ssl->wflags;
02470 
02471     ssl->wflags = flags;
02472     ret = wolfSSL_write(ssl, data, sz);
02473     ssl->wflags = oldFlags;
02474 
02475     WOLFSSL_LEAVE("wolfSSL_send()", ret);
02476 
02477     return ret;
02478 }
02479 
02480 
02481 int wolfSSL_recv(WOLFSSL* ssl, void* data, int sz, int flags)
02482 {
02483     int ret;
02484     int oldFlags;
02485 
02486     WOLFSSL_ENTER("wolfSSL_recv()");
02487 
02488     if (ssl == NULL || data == NULL || sz < 0)
02489         return BAD_FUNC_ARG;
02490 
02491     oldFlags = ssl->rflags;
02492 
02493     ssl->rflags = flags;
02494     ret = wolfSSL_read(ssl, data, sz);
02495     ssl->rflags = oldFlags;
02496 
02497     WOLFSSL_LEAVE("wolfSSL_recv()", ret);
02498 
02499     return ret;
02500 }
02501 #endif
02502 
02503 
02504 /* WOLFSSL_SUCCESS on ok */
02505 int wolfSSL_shutdown(WOLFSSL* ssl)
02506 {
02507     int  ret = WOLFSSL_FATAL_ERROR;
02508     byte tmp;
02509     WOLFSSL_ENTER("SSL_shutdown()");
02510 
02511     if (ssl == NULL)
02512         return WOLFSSL_FATAL_ERROR;
02513 
02514     if (ssl->options.quietShutdown) {
02515         WOLFSSL_MSG("quiet shutdown, no close notify sent");
02516         ret = WOLFSSL_SUCCESS;
02517     }
02518     else {
02519         /* try to send close notify, not an error if can't */
02520         if (!ssl->options.isClosed && !ssl->options.connReset &&
02521                                       !ssl->options.sentNotify) {
02522             ssl->error = SendAlert(ssl, alert_warning, close_notify);
02523             if (ssl->error < 0) {
02524                 WOLFSSL_ERROR(ssl->error);
02525                 return WOLFSSL_FATAL_ERROR;
02526             }
02527             ssl->options.sentNotify = 1;  /* don't send close_notify twice */
02528             if (ssl->options.closeNotify)
02529                 ret = WOLFSSL_SUCCESS;
02530             else {
02531                 ret = WOLFSSL_SHUTDOWN_NOT_DONE;
02532                 WOLFSSL_LEAVE("SSL_shutdown()", ret);
02533                 return ret;
02534             }
02535         }
02536 
02537         /* call wolfSSL_shutdown again for bidirectional shutdown */
02538         if (ssl->options.sentNotify && !ssl->options.closeNotify) {
02539             ret = wolfSSL_read(ssl, &tmp, 0);
02540             if (ret < 0) {
02541                 WOLFSSL_ERROR(ssl->error);
02542                 ret = WOLFSSL_FATAL_ERROR;
02543             } else if (ssl->options.closeNotify) {
02544                 ssl->error = WOLFSSL_ERROR_SYSCALL;   /* simulate OpenSSL behavior */
02545                 ret = WOLFSSL_SUCCESS;
02546             }
02547         }
02548     }
02549 
02550 #ifdef OPENSSL_EXTRA
02551     /* reset WOLFSSL structure state for possible re-use */
02552     if (ret == WOLFSSL_SUCCESS) {
02553         if (wolfSSL_clear(ssl) != WOLFSSL_SUCCESS) {
02554             WOLFSSL_MSG("could not clear WOLFSSL");
02555             ret = WOLFSSL_FATAL_ERROR;
02556         }
02557     }
02558 #endif
02559 
02560     WOLFSSL_LEAVE("SSL_shutdown()", ret);
02561 
02562     return ret;
02563 }
02564 
02565 
02566 /* get current error state value */
02567 int wolfSSL_state(WOLFSSL* ssl)
02568 {
02569     if (ssl == NULL) {
02570         return BAD_FUNC_ARG;
02571     }
02572 
02573     return ssl->error;
02574 }
02575 
02576 
02577 int wolfSSL_get_error(WOLFSSL* ssl, int ret)
02578 {
02579     WOLFSSL_ENTER("SSL_get_error");
02580 
02581     if (ret > 0)
02582         return WOLFSSL_ERROR_NONE;
02583     if (ssl == NULL)
02584         return BAD_FUNC_ARG;
02585 
02586     WOLFSSL_LEAVE("SSL_get_error", ssl->error);
02587 
02588     /* make sure converted types are handled in SetErrorString() too */
02589     if (ssl->error == WANT_READ)
02590         return WOLFSSL_ERROR_WANT_READ;         /* convert to OpenSSL type */
02591     else if (ssl->error == WANT_WRITE)
02592         return WOLFSSL_ERROR_WANT_WRITE;        /* convert to OpenSSL type */
02593     else if (ssl->error == ZERO_RETURN)
02594         return WOLFSSL_ERROR_ZERO_RETURN;       /* convert to OpenSSL type */
02595     return ssl->error;
02596 }
02597 
02598 
02599 /* retrive alert history, WOLFSSL_SUCCESS on ok */
02600 int wolfSSL_get_alert_history(WOLFSSL* ssl, WOLFSSL_ALERT_HISTORY *h)
02601 {
02602     if (ssl && h) {
02603         *h = ssl->alert_history;
02604     }
02605     return WOLFSSL_SUCCESS;
02606 }
02607 
02608 
02609 /* return TRUE if current error is want read */
02610 int wolfSSL_want_read(WOLFSSL* ssl)
02611 {
02612     WOLFSSL_ENTER("SSL_want_read");
02613     if (ssl->error == WANT_READ)
02614         return 1;
02615 
02616     return 0;
02617 }
02618 
02619 
02620 /* return TRUE if current error is want write */
02621 int wolfSSL_want_write(WOLFSSL* ssl)
02622 {
02623     WOLFSSL_ENTER("SSL_want_write");
02624     if (ssl->error == WANT_WRITE)
02625         return 1;
02626 
02627     return 0;
02628 }
02629 
02630 
02631 char* wolfSSL_ERR_error_string(unsigned long errNumber, char* data)
02632 {
02633     static const char* const msg = "Please supply a buffer for error string";
02634 
02635     WOLFSSL_ENTER("ERR_error_string");
02636     if (data) {
02637         SetErrorString((int)errNumber, data);
02638         return data;
02639     }
02640 
02641     return (char*)msg;
02642 }
02643 
02644 
02645 void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
02646 {
02647     WOLFSSL_ENTER("wolfSSL_ERR_error_string_n");
02648     if (len >= WOLFSSL_MAX_ERROR_SZ)
02649         wolfSSL_ERR_error_string(e, buf);
02650     else {
02651         char tmp[WOLFSSL_MAX_ERROR_SZ];
02652 
02653         WOLFSSL_MSG("Error buffer too short, truncating");
02654         if (len) {
02655             wolfSSL_ERR_error_string(e, tmp);
02656             XMEMCPY(buf, tmp, len-1);
02657             buf[len-1] = '\0';
02658         }
02659     }
02660 }
02661 
02662 
02663 /* don't free temporary arrays at end of handshake */
02664 void wolfSSL_KeepArrays(WOLFSSL* ssl)
02665 {
02666     if (ssl)
02667         ssl->options.saveArrays = 1;
02668 }
02669 
02670 
02671 /* user doesn't need temporary arrays anymore, Free */
02672 void wolfSSL_FreeArrays(WOLFSSL* ssl)
02673 {
02674     if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
02675         ssl->options.saveArrays = 0;
02676         FreeArrays(ssl, 1);
02677     }
02678 }
02679 
02680 /* Set option to indicate that the resources are not to be freed after
02681  * handshake.
02682  *
02683  * ssl  The SSL/TLS object.
02684  * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
02685  */
02686 int wolfSSL_KeepHandshakeResources(WOLFSSL* ssl)
02687 {
02688     if (ssl == NULL)
02689         return BAD_FUNC_ARG;
02690 
02691     ssl->options.keepResources = 1;
02692 
02693     return 0;
02694 }
02695 
02696 /* Free the handshake resources after handshake.
02697  *
02698  * ssl  The SSL/TLS object.
02699  * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
02700  */
02701 int wolfSSL_FreeHandshakeResources(WOLFSSL* ssl)
02702 {
02703     if (ssl == NULL)
02704         return BAD_FUNC_ARG;
02705 
02706     FreeHandshakeResources(ssl);
02707 
02708     return 0;
02709 }
02710 
02711 /* Use the client's order of preference when matching cipher suites.
02712  *
02713  * ssl  The SSL/TLS context object.
02714  * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
02715  */
02716 int wolfSSL_CTX_UseClientSuites(WOLFSSL_CTX* ctx)
02717 {
02718     if (ctx == NULL)
02719         return BAD_FUNC_ARG;
02720 
02721     ctx->useClientOrder = 1;
02722 
02723     return 0;
02724 }
02725 
02726 /* Use the client's order of preference when matching cipher suites.
02727  *
02728  * ssl  The SSL/TLS object.
02729  * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
02730  */
02731 int wolfSSL_UseClientSuites(WOLFSSL* ssl)
02732 {
02733     if (ssl == NULL)
02734         return BAD_FUNC_ARG;
02735 
02736     ssl->options.useClientOrder = 1;
02737 
02738     return 0;
02739 }
02740 
02741 const byte* wolfSSL_GetMacSecret(WOLFSSL* ssl, int verify)
02742 {
02743     if (ssl == NULL)
02744         return NULL;
02745 
02746     if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
02747          (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
02748         return ssl->keys.client_write_MAC_secret;
02749     else
02750         return ssl->keys.server_write_MAC_secret;
02751 }
02752 
02753 
02754 #ifdef ATOMIC_USER
02755 
02756 void  wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX* ctx, CallbackMacEncrypt cb)
02757 {
02758     if (ctx)
02759         ctx->MacEncryptCb = cb;
02760 }
02761 
02762 
02763 void  wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx)
02764 {
02765     if (ssl)
02766         ssl->MacEncryptCtx = ctx;
02767 }
02768 
02769 
02770 void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl)
02771 {
02772     if (ssl)
02773         return ssl->MacEncryptCtx;
02774 
02775     return NULL;
02776 }
02777 
02778 
02779 void  wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX* ctx, CallbackDecryptVerify cb)
02780 {
02781     if (ctx)
02782         ctx->DecryptVerifyCb = cb;
02783 }
02784 
02785 
02786 void  wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx)
02787 {
02788     if (ssl)
02789         ssl->DecryptVerifyCtx = ctx;
02790 }
02791 
02792 
02793 void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl)
02794 {
02795     if (ssl)
02796         return ssl->DecryptVerifyCtx;
02797 
02798     return NULL;
02799 }
02800 
02801 
02802 const byte* wolfSSL_GetClientWriteKey(WOLFSSL* ssl)
02803 {
02804     if (ssl)
02805         return ssl->keys.client_write_key;
02806 
02807     return NULL;
02808 }
02809 
02810 
02811 const byte* wolfSSL_GetClientWriteIV(WOLFSSL* ssl)
02812 {
02813     if (ssl)
02814         return ssl->keys.client_write_IV;
02815 
02816     return NULL;
02817 }
02818 
02819 
02820 const byte* wolfSSL_GetServerWriteKey(WOLFSSL* ssl)
02821 {
02822     if (ssl)
02823         return ssl->keys.server_write_key;
02824 
02825     return NULL;
02826 }
02827 
02828 
02829 const byte* wolfSSL_GetServerWriteIV(WOLFSSL* ssl)
02830 {
02831     if (ssl)
02832         return ssl->keys.server_write_IV;
02833 
02834     return NULL;
02835 }
02836 
02837 int wolfSSL_GetKeySize(WOLFSSL* ssl)
02838 {
02839     if (ssl)
02840         return ssl->specs.key_size;
02841 
02842     return BAD_FUNC_ARG;
02843 }
02844 
02845 
02846 int wolfSSL_GetIVSize(WOLFSSL* ssl)
02847 {
02848     if (ssl)
02849         return ssl->specs.iv_size;
02850 
02851     return BAD_FUNC_ARG;
02852 }
02853 
02854 
02855 int wolfSSL_GetBulkCipher(WOLFSSL* ssl)
02856 {
02857     if (ssl)
02858         return ssl->specs.bulk_cipher_algorithm;
02859 
02860     return BAD_FUNC_ARG;
02861 }
02862 
02863 
02864 int wolfSSL_GetCipherType(WOLFSSL* ssl)
02865 {
02866     if (ssl == NULL)
02867         return BAD_FUNC_ARG;
02868 
02869     if (ssl->specs.cipher_type == block)
02870         return WOLFSSL_BLOCK_TYPE;
02871     if (ssl->specs.cipher_type == stream)
02872         return WOLFSSL_STREAM_TYPE;
02873     if (ssl->specs.cipher_type == aead)
02874         return WOLFSSL_AEAD_TYPE;
02875 
02876     return -1;
02877 }
02878 
02879 
02880 int wolfSSL_GetCipherBlockSize(WOLFSSL* ssl)
02881 {
02882     if (ssl == NULL)
02883         return BAD_FUNC_ARG;
02884 
02885     return ssl->specs.block_size;
02886 }
02887 
02888 
02889 int wolfSSL_GetAeadMacSize(WOLFSSL* ssl)
02890 {
02891     if (ssl == NULL)
02892         return BAD_FUNC_ARG;
02893 
02894     return ssl->specs.aead_mac_size;
02895 }
02896 
02897 
02898 int wolfSSL_IsTLSv1_1(WOLFSSL* ssl)
02899 {
02900     if (ssl == NULL)
02901         return BAD_FUNC_ARG;
02902 
02903     if (ssl->options.tls1_1)
02904         return 1;
02905 
02906     return 0;
02907 }
02908 
02909 
02910 int wolfSSL_GetSide(WOLFSSL* ssl)
02911 {
02912     if (ssl)
02913         return ssl->options.side;
02914 
02915     return BAD_FUNC_ARG;
02916 }
02917 
02918 
02919 int wolfSSL_GetHmacSize(WOLFSSL* ssl)
02920 {
02921     /* AEAD ciphers don't have HMAC keys */
02922     if (ssl)
02923         return (ssl->specs.cipher_type != aead) ? ssl->specs.hash_size : 0;
02924 
02925     return BAD_FUNC_ARG;
02926 }
02927 
02928 #endif /* ATOMIC_USER */
02929 
02930 #ifndef NO_CERTS
02931 
02932 WOLFSSL_CERT_MANAGER* wolfSSL_CTX_GetCertManager(WOLFSSL_CTX* ctx)
02933 {
02934     WOLFSSL_CERT_MANAGER* cm = NULL;
02935     if (ctx)
02936         cm = ctx->cm;
02937     return cm;
02938 }
02939 
02940 WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap)
02941 {
02942     WOLFSSL_CERT_MANAGER* cm = NULL;
02943 
02944     WOLFSSL_ENTER("wolfSSL_CertManagerNew");
02945 
02946     cm = (WOLFSSL_CERT_MANAGER*) XMALLOC(sizeof(WOLFSSL_CERT_MANAGER), heap,
02947                                          DYNAMIC_TYPE_CERT_MANAGER);
02948     if (cm) {
02949         XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER));
02950 
02951         if (wc_InitMutex(&cm->caLock) != 0) {
02952             WOLFSSL_MSG("Bad mutex init");
02953             wolfSSL_CertManagerFree(cm);
02954             return NULL;
02955         }
02956 
02957         #ifdef WOLFSSL_TRUST_PEER_CERT
02958         if (wc_InitMutex(&cm->tpLock) != 0) {
02959             WOLFSSL_MSG("Bad mutex init");
02960             wolfSSL_CertManagerFree(cm);
02961             return NULL;
02962         }
02963         #endif
02964 
02965         /* set default minimum key size allowed */
02966         #ifndef NO_RSA
02967             cm->minRsaKeySz = MIN_RSAKEY_SZ;
02968         #endif
02969         #ifdef HAVE_ECC
02970             cm->minEccKeySz = MIN_ECCKEY_SZ;
02971         #endif
02972             cm->heap = heap;
02973     }
02974 
02975     return cm;
02976 }
02977 
02978 
02979 WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void)
02980 {
02981     return wolfSSL_CertManagerNew_ex(NULL);
02982 }
02983 
02984 
02985 void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
02986 {
02987     WOLFSSL_ENTER("wolfSSL_CertManagerFree");
02988 
02989     if (cm) {
02990         #ifdef HAVE_CRL
02991             if (cm->crl)
02992                 FreeCRL(cm->crl, 1);
02993         #endif
02994         #ifdef HAVE_OCSP
02995             if (cm->ocsp)
02996                 FreeOCSP(cm->ocsp, 1);
02997             XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
02998         #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
02999          || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
03000             if (cm->ocsp_stapling)
03001                 FreeOCSP(cm->ocsp_stapling, 1);
03002         #endif
03003         #endif
03004         FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
03005         wc_FreeMutex(&cm->caLock);
03006 
03007         #ifdef WOLFSSL_TRUST_PEER_CERT
03008         FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap);
03009         wc_FreeMutex(&cm->tpLock);
03010         #endif
03011 
03012         XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER);
03013     }
03014 
03015 }
03016 
03017 
03018 /* Unload the CA signer list */
03019 int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
03020 {
03021     WOLFSSL_ENTER("wolfSSL_CertManagerUnloadCAs");
03022 
03023     if (cm == NULL)
03024         return BAD_FUNC_ARG;
03025 
03026     if (wc_LockMutex(&cm->caLock) != 0)
03027         return BAD_MUTEX_E;
03028 
03029     FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
03030 
03031     wc_UnLockMutex(&cm->caLock);
03032 
03033 
03034     return WOLFSSL_SUCCESS;
03035 }
03036 
03037 
03038 #ifdef WOLFSSL_TRUST_PEER_CERT
03039 int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm)
03040 {
03041     WOLFSSL_ENTER("wolfSSL_CertManagerUnload_trust_peers");
03042 
03043     if (cm == NULL)
03044         return BAD_FUNC_ARG;
03045 
03046     if (wc_LockMutex(&cm->tpLock) != 0)
03047         return BAD_MUTEX_E;
03048 
03049     FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, NULL);
03050 
03051     wc_UnLockMutex(&cm->tpLock);
03052 
03053 
03054     return WOLFSSL_SUCCESS;
03055 }
03056 #endif /* WOLFSSL_TRUST_PEER_CERT */
03057 
03058 #endif /* NO_CERTS */
03059 
03060 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
03061     defined(HAVE_WEBSERVER)
03062 
03063 static const struct cipher{
03064         unsigned char type;
03065         const char *name;
03066 } cipher_tbl[] = {
03067 
03068 #ifndef NO_AES
03069     #ifdef WOLFSSL_AES_128
03070     {AES_128_CBC_TYPE, "AES-128-CBC"},
03071     #endif
03072     #ifdef WOLFSSL_AES_192
03073     {AES_192_CBC_TYPE, "AES-192-CBC"},
03074     #endif
03075     #ifdef WOLFSSL_AES_256
03076     {AES_256_CBC_TYPE, "AES-256-CBC"},
03077     #endif
03078 #if defined(OPENSSL_EXTRA)
03079     #ifdef WOLFSSL_AES_128
03080         {AES_128_CTR_TYPE, "AES-128-CTR"},
03081     #endif
03082     #ifdef WOLFSSL_AES_192
03083         {AES_192_CTR_TYPE, "AES-192-CTR"},
03084     #endif
03085     #ifdef WOLFSSL_AES_256
03086         {AES_256_CTR_TYPE, "AES-256-CTR"},
03087     #endif
03088 
03089     #ifdef WOLFSSL_AES_128
03090         {AES_128_ECB_TYPE, "AES-128-ECB"},
03091     #endif
03092     #ifdef WOLFSSL_AES_192
03093         {AES_192_ECB_TYPE, "AES-192-ECB"},
03094     #endif
03095     #ifdef WOLFSSL_AES_256
03096         {AES_256_ECB_TYPE, "AES-256-ECB"},
03097     #endif
03098 #endif
03099 
03100 #endif
03101 
03102 #ifndef NO_DES3
03103     {DES_CBC_TYPE, "DES-CBC"},
03104     {DES_ECB_TYPE, "DES-ECB"},
03105 
03106     {DES_EDE3_CBC_TYPE, "DES-EDE3-CBC"},
03107     {DES_EDE3_ECB_TYPE, "DES-EDE3-ECB"},
03108 #endif
03109 
03110 #ifndef NO_RC4
03111     {ARC4_TYPE, "ARC4"},
03112 #endif
03113 
03114 #ifdef HAVE_IDEA
03115     {IDEA_CBC_TYPE, "IDEA-CBC"},
03116 #endif
03117     { 0, NULL}
03118 };
03119 
03120 const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbyname(const char *name)
03121 {
03122 
03123     static const struct alias {
03124         const char *name;
03125         const char *alias;
03126     } alias_tbl[] =
03127     {
03128 #ifndef NO_DES3
03129         {"DES-CBC", "DES"},
03130         {"DES-CBC", "des"},
03131         {"DES-ECB", "DES-ECB"},
03132         {"DES-ECB", "des-ecb"},
03133         {"DES-EDE3-CBC", "DES3"},
03134         {"DES-EDE3-CBC", "des3"},
03135         {"DES-EDE3-ECB", "DES-EDE3"},
03136         {"DES-EDE3-ECB", "des-ede3"},
03137         {"DES-EDE3-ECB", "des-ede3-ecb"},
03138 #endif
03139 #ifdef HAVE_IDEA
03140         {"IDEA-CBC", "IDEA"},
03141         {"IDEA-CBC", "idea"},
03142 #endif
03143 #ifndef NO_AES
03144     #ifdef HAVE_AES_CBC
03145         #ifdef WOLFSSL_AES_128
03146         {"AES-128-CBC", "AES128-CBC"},
03147         {"AES-128-CBC", "aes128-cbc"},
03148         #endif
03149         #ifdef WOLFSSL_AES_192
03150         {"AES-192-CBC", "AES192-CBC"},
03151         {"AES-192-CBC", "aes192-cbc"},
03152         #endif
03153         #ifdef WOLFSSL_AES_256
03154         {"AES-256-CBC", "AES256-CBC"},
03155         {"AES-256-CBC", "aes256-cbc"},
03156         #endif
03157     #endif
03158     #ifdef WOLFSSL_AES_128
03159         {"AES-128-ECB", "AES128-ECB"},
03160         {"AES-128-ECB", "aes128-ecb"},
03161     #endif
03162     #ifdef WOLFSSL_AES_192
03163         {"AES-192-ECB", "AES192-ECB"},
03164         {"AES-192-ECB", "aes192-ecb"},
03165     #endif
03166     #ifdef WOLFSSL_AES_256
03167         {"AES-256-ECB", "AES256-ECB"},
03168         {"AES-256-EBC", "aes256-ecb"},
03169     #endif
03170 #endif
03171 #ifndef NO_RC4
03172         {"ARC4", "RC4"},
03173 #endif
03174         { NULL, NULL}
03175     };
03176 
03177     const struct cipher *ent;
03178     const struct alias  *al;
03179 
03180     WOLFSSL_ENTER("EVP_get_cipherbyname");
03181 
03182     for( al = alias_tbl; al->name != NULL; al++)
03183         if(XSTRNCMP(name, al->alias, XSTRLEN(al->alias)+1) == 0) {
03184             name = al->name;
03185             break;
03186         }
03187 
03188     for( ent = cipher_tbl; ent->name != NULL; ent++)
03189         if(XSTRNCMP(name, ent->name, XSTRLEN(ent->name)+1) == 0) {
03190             return (WOLFSSL_EVP_CIPHER *)ent->name;
03191         }
03192 
03193     return NULL;
03194 }
03195 
03196 /*
03197  * return an EVP_CIPHER structure when cipher NID is passed.
03198  *
03199  * id  cipher NID
03200  *
03201  * retrun WOLFSSL_EVP_CIPHER
03202 */
03203 const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id)
03204 {
03205     WOLFSSL_ENTER("EVP_get_cipherbynid");
03206 
03207     switch(id) {
03208 
03209 #if defined(OPENSSL_EXTRA)
03210 #ifndef NO_AES
03211     #ifdef HAVE_AES_CBC
03212         #ifdef WOLFSSL_AES_128
03213         case NID_aes_128_cbc:
03214             return wolfSSL_EVP_aes_128_cbc();
03215         #endif
03216         #ifdef WOLFSSL_AES_192
03217         case NID_aes_192_cbc:
03218             return wolfSSL_EVP_aes_192_cbc();
03219         #endif
03220         #ifdef WOLFSSL_AES_256
03221         case NID_aes_256_cbc:
03222             return wolfSSL_EVP_aes_256_cbc();
03223         #endif
03224     #endif
03225     #ifdef WOLFSSL_AES_COUNTER
03226         #ifdef WOLFSSL_AES_128
03227         case NID_aes_128_ctr:
03228             return wolfSSL_EVP_aes_128_ctr();
03229         #endif
03230         #ifdef WOLFSSL_AES_192
03231         case NID_aes_192_ctr:
03232             return wolfSSL_EVP_aes_192_ctr();
03233         #endif
03234         #ifdef WOLFSSL_AES_256
03235         case NID_aes_256_ctr:
03236             return wolfSSL_EVP_aes_256_ctr();
03237         #endif
03238     #endif /* WOLFSSL_AES_COUNTER */
03239     #ifdef HAVE_AES_ECB
03240         #ifdef WOLFSSL_AES_128
03241         case NID_aes_128_ecb:
03242             return wolfSSL_EVP_aes_128_ecb();
03243         #endif
03244         #ifdef WOLFSSL_AES_192
03245         case NID_aes_192_ecb:
03246             return wolfSSL_EVP_aes_192_ecb();
03247         #endif
03248         #ifdef WOLFSSL_AES_256
03249         case NID_aes_256_ecb:
03250             return wolfSSL_EVP_aes_256_ecb();
03251         #endif
03252     #endif /* HAVE_AES_ECB */
03253 #endif
03254 
03255 #ifndef NO_DES3
03256         case NID_des_cbc:
03257             return wolfSSL_EVP_des_cbc();
03258 #ifdef WOLFSSL_DES_ECB
03259         case NID_des_ecb:
03260             return wolfSSL_EVP_des_ecb();
03261 #endif
03262         case NID_des_ede3_cbc:
03263             return wolfSSL_EVP_des_ede3_cbc();
03264 #ifdef WOLFSSL_DES_ECB
03265         case NID_des_ede3_ecb:
03266             return wolfSSL_EVP_des_ede3_ecb();
03267 #endif
03268 #endif /*NO_DES3*/
03269 
03270 #ifdef HAVE_IDEA
03271         case NID_idea_cbc:
03272             return wolfSSL_EVP_idea_cbc();
03273 #endif
03274 #endif /*OPENSSL_EXTRA*/
03275 
03276         default:
03277             WOLFSSL_MSG("Bad cipher id value");
03278     }
03279 
03280     return NULL;
03281 }
03282 
03283 #ifndef NO_AES
03284     #ifdef HAVE_AES_CBC
03285     #ifdef WOLFSSL_AES_128
03286         static char *EVP_AES_128_CBC;
03287     #endif
03288     #ifdef WOLFSSL_AES_192
03289         static char *EVP_AES_192_CBC;
03290     #endif
03291     #ifdef WOLFSSL_AES_256
03292         static char *EVP_AES_256_CBC;
03293     #endif
03294     #endif /* HAVE_AES_CBC */
03295 #if defined(OPENSSL_EXTRA)
03296     #ifdef WOLFSSL_AES_128
03297     static char *EVP_AES_128_CTR;
03298     #endif
03299     #ifdef WOLFSSL_AES_192
03300     static char *EVP_AES_192_CTR;
03301     #endif
03302     #ifdef WOLFSSL_AES_256
03303     static char *EVP_AES_256_CTR;
03304     #endif
03305 
03306     #ifdef WOLFSSL_AES_128
03307     static char *EVP_AES_128_ECB;
03308     #endif
03309     #ifdef WOLFSSL_AES_192
03310     static char *EVP_AES_192_ECB;
03311     #endif
03312     #ifdef WOLFSSL_AES_256
03313     static char *EVP_AES_256_ECB;
03314     #endif
03315     static const int  EVP_AES_SIZE = 11;
03316 #endif
03317 #endif
03318 
03319 #ifndef NO_DES3
03320 static char *EVP_DES_CBC;
03321 static char *EVP_DES_ECB;
03322 
03323 static char *EVP_DES_EDE3_CBC;
03324 static char *EVP_DES_EDE3_ECB;
03325 
03326 #ifdef OPENSSL_EXTRA
03327 static const int  EVP_DES_SIZE = 7;
03328 static const int  EVP_DES_EDE3_SIZE = 12;
03329 #endif
03330 
03331 #endif
03332 
03333 #ifdef HAVE_IDEA
03334 static char *EVP_IDEA_CBC;
03335 #if defined(OPENSSL_EXTRA)
03336 static const int  EVP_IDEA_SIZE = 8;
03337 #endif
03338 #endif
03339 
03340 void wolfSSL_EVP_init(void)
03341 {
03342 #ifndef NO_AES
03343     #ifdef HAVE_AES_CBC
03344         #ifdef WOLFSSL_AES_128
03345         EVP_AES_128_CBC = (char *)EVP_get_cipherbyname("AES-128-CBC");
03346         #endif
03347         #ifdef WOLFSSL_AES_192
03348         EVP_AES_192_CBC = (char *)EVP_get_cipherbyname("AES-192-CBC");
03349         #endif
03350         #ifdef WOLFSSL_AES_256
03351         EVP_AES_256_CBC = (char *)EVP_get_cipherbyname("AES-256-CBC");
03352         #endif
03353     #endif /* HAVE_AES_CBC */
03354 
03355 #if defined(OPENSSL_EXTRA)
03356         #ifdef WOLFSSL_AES_128
03357         EVP_AES_128_CTR = (char *)EVP_get_cipherbyname("AES-128-CTR");
03358         #endif
03359         #ifdef WOLFSSL_AES_192
03360         EVP_AES_192_CTR = (char *)EVP_get_cipherbyname("AES-192-CTR");
03361         #endif
03362         #ifdef WOLFSSL_AES_256
03363         EVP_AES_256_CTR = (char *)EVP_get_cipherbyname("AES-256-CTR");
03364         #endif
03365 
03366         #ifdef WOLFSSL_AES_128
03367         EVP_AES_128_ECB = (char *)EVP_get_cipherbyname("AES-128-ECB");
03368         #endif
03369         #ifdef WOLFSSL_AES_192
03370         EVP_AES_192_ECB = (char *)EVP_get_cipherbyname("AES-192-ECB");
03371         #endif
03372         #ifdef WOLFSSL_AES_256
03373         EVP_AES_256_ECB = (char *)EVP_get_cipherbyname("AES-256-ECB");
03374         #endif
03375 #endif
03376 #endif
03377 
03378 #ifndef NO_DES3
03379     EVP_DES_CBC = (char *)EVP_get_cipherbyname("DES-CBC");
03380     EVP_DES_ECB = (char *)EVP_get_cipherbyname("DES-ECB");
03381 
03382     EVP_DES_EDE3_CBC = (char *)EVP_get_cipherbyname("DES-EDE3-CBC");
03383     EVP_DES_EDE3_ECB = (char *)EVP_get_cipherbyname("DES-EDE3-ECB");
03384 #endif
03385 
03386 #ifdef HAVE_IDEA
03387     EVP_IDEA_CBC = (char *)EVP_get_cipherbyname("IDEA-CBC");
03388 #endif
03389 }
03390 
03391 #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || HAVE_WEBSERVER */
03392 
03393 
03394 #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
03395 
03396 void wolfSSL_ERR_print_errors_fp(XFILE fp, int err)
03397 {
03398     char data[WOLFSSL_MAX_ERROR_SZ + 1];
03399 
03400     WOLFSSL_ENTER("wolfSSL_ERR_print_errors_fp");
03401     SetErrorString(err, data);
03402     fprintf(fp, "%s", data);
03403 }
03404 
03405 #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
03406 void wolfSSL_ERR_dump_errors_fp(XFILE fp)
03407 {
03408     wc_ERR_print_errors_fp(fp);
03409 }
03410 #endif
03411 #endif
03412 
03413 
03414 int wolfSSL_pending(WOLFSSL* ssl)
03415 {
03416     WOLFSSL_ENTER("SSL_pending");
03417     return ssl->buffers.clearOutputBuffer.length;
03418 }
03419 
03420 
03421 #ifndef WOLFSSL_LEANPSK
03422 /* turn on handshake group messages for context */
03423 int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx)
03424 {
03425     if (ctx == NULL)
03426        return BAD_FUNC_ARG;
03427 
03428     ctx->groupMessages = 1;
03429 
03430     return WOLFSSL_SUCCESS;
03431 }
03432 #endif
03433 
03434 
03435 #ifndef NO_WOLFSSL_CLIENT
03436 /* connect enough to get peer cert chain */
03437 int wolfSSL_connect_cert(WOLFSSL* ssl)
03438 {
03439     int  ret;
03440 
03441     if (ssl == NULL)
03442         return WOLFSSL_FAILURE;
03443 
03444     ssl->options.certOnly = 1;
03445     ret = wolfSSL_connect(ssl);
03446     ssl->options.certOnly   = 0;
03447 
03448     return ret;
03449 }
03450 #endif
03451 
03452 
03453 #ifndef WOLFSSL_LEANPSK
03454 /* turn on handshake group messages for ssl object */
03455 int wolfSSL_set_group_messages(WOLFSSL* ssl)
03456 {
03457     if (ssl == NULL)
03458        return BAD_FUNC_ARG;
03459 
03460     ssl->options.groupMessages = 1;
03461 
03462     return WOLFSSL_SUCCESS;
03463 }
03464 
03465 
03466 /* make minVersion the internal equivalent SSL version */
03467 static int SetMinVersionHelper(byte* minVersion, int version)
03468 {
03469 #ifdef NO_TLS
03470     (void)minVersion;
03471 #endif
03472 
03473     switch (version) {
03474 #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
03475         case WOLFSSL_SSLV3:
03476             *minVersion = SSLv3_MINOR;
03477             break;
03478 #endif
03479 
03480 #ifndef NO_TLS
03481     #ifndef NO_OLD_TLS
03482         case WOLFSSL_TLSV1:
03483             *minVersion = TLSv1_MINOR;
03484             break;
03485 
03486         case WOLFSSL_TLSV1_1:
03487             *minVersion = TLSv1_1_MINOR;
03488             break;
03489     #endif
03490     #ifndef WOLFSSL_NO_TLS12
03491         case WOLFSSL_TLSV1_2:
03492             *minVersion = TLSv1_2_MINOR;
03493             break;
03494     #endif
03495 #endif
03496     #ifdef WOLFSSL_TLS13
03497         case WOLFSSL_TLSV1_3:
03498             *minVersion = TLSv1_3_MINOR;
03499             break;
03500     #endif
03501 
03502         default:
03503             WOLFSSL_MSG("Bad function argument");
03504             return BAD_FUNC_ARG;
03505     }
03506 
03507     return WOLFSSL_SUCCESS;
03508 }
03509 
03510 
03511 /* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
03512 int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version)
03513 {
03514     WOLFSSL_ENTER("wolfSSL_CTX_SetMinVersion");
03515 
03516     if (ctx == NULL) {
03517         WOLFSSL_MSG("Bad function argument");
03518         return BAD_FUNC_ARG;
03519     }
03520 
03521     return SetMinVersionHelper(&ctx->minDowngrade, version);
03522 }
03523 
03524 
03525 /* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
03526 int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version)
03527 {
03528     WOLFSSL_ENTER("wolfSSL_SetMinVersion");
03529 
03530     if (ssl == NULL) {
03531         WOLFSSL_MSG("Bad function argument");
03532         return BAD_FUNC_ARG;
03533     }
03534 
03535     return SetMinVersionHelper(&ssl->options.minDowngrade, version);
03536 }
03537 
03538 
03539 /* Function to get version as WOLFSSL_ enum value for wolfSSL_SetVersion */
03540 int wolfSSL_GetVersion(WOLFSSL* ssl)
03541 {
03542     if (ssl == NULL)
03543         return BAD_FUNC_ARG;
03544 
03545     if (ssl->version.major == SSLv3_MAJOR) {
03546         switch (ssl->version.minor) {
03547             case SSLv3_MINOR :
03548                 return WOLFSSL_SSLV3;
03549             case TLSv1_MINOR :
03550                 return WOLFSSL_TLSV1;
03551             case TLSv1_1_MINOR :
03552                 return WOLFSSL_TLSV1_1;
03553             case TLSv1_2_MINOR :
03554                 return WOLFSSL_TLSV1_2;
03555             case TLSv1_3_MINOR :
03556                 return WOLFSSL_TLSV1_3;
03557             default:
03558                 break;
03559         }
03560     }
03561 
03562     return VERSION_ERROR;
03563 }
03564 
03565 int wolfSSL_SetVersion(WOLFSSL* ssl, int version)
03566 {
03567     word16 haveRSA = 1;
03568     word16 havePSK = 0;
03569     int    keySz   = 0;
03570 
03571     WOLFSSL_ENTER("wolfSSL_SetVersion");
03572 
03573     if (ssl == NULL) {
03574         WOLFSSL_MSG("Bad function argument");
03575         return BAD_FUNC_ARG;
03576     }
03577 
03578     switch (version) {
03579 #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
03580         case WOLFSSL_SSLV3:
03581             ssl->version = MakeSSLv3();
03582             break;
03583 #endif
03584 
03585 #ifndef NO_TLS
03586     #ifndef NO_OLD_TLS
03587         #ifdef WOLFSSL_ALLOW_TLSV10
03588         case WOLFSSL_TLSV1:
03589             ssl->version = MakeTLSv1();
03590             break;
03591         #endif
03592 
03593         case WOLFSSL_TLSV1_1:
03594             ssl->version = MakeTLSv1_1();
03595             break;
03596     #endif
03597     #ifndef WOLFSSL_NO_TLS12
03598         case WOLFSSL_TLSV1_2:
03599             ssl->version = MakeTLSv1_2();
03600             break;
03601     #endif
03602 #endif
03603 #ifdef WOLFSSL_TLS13
03604         case WOLFSSL_TLSV1_3:
03605             ssl->version = MakeTLSv1_3();
03606             break;
03607 
03608 #endif
03609 
03610         default:
03611             WOLFSSL_MSG("Bad function argument");
03612             return BAD_FUNC_ARG;
03613     }
03614 
03615     #ifdef NO_RSA
03616         haveRSA = 0;
03617     #endif
03618     #ifndef NO_PSK
03619         havePSK = ssl->options.havePSK;
03620     #endif
03621     #ifndef NO_CERTS
03622         keySz = ssl->buffers.keySz;
03623     #endif
03624 
03625     InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
03626                ssl->options.haveDH, ssl->options.haveNTRU,
03627                ssl->options.haveECDSAsig, ssl->options.haveECC,
03628                ssl->options.haveStaticECC, ssl->options.side);
03629 
03630     return WOLFSSL_SUCCESS;
03631 }
03632 #endif /* !leanpsk */
03633 
03634 
03635 #if !defined(NO_CERTS) || !defined(NO_SESSION_CACHE)
03636 
03637 /* Make a work from the front of random hash */
03638 static WC_INLINE word32 MakeWordFromHash(const byte* hashID)
03639 {
03640     return ((word32)hashID[0] << 24) | (hashID[1] << 16) |
03641         (hashID[2] <<  8) | hashID[3];
03642 }
03643 
03644 #endif /* !NO_CERTS || !NO_SESSION_CACHE */
03645 
03646 
03647 #ifndef NO_CERTS
03648 
03649 /* hash is the SHA digest of name, just use first 32 bits as hash */
03650 static WC_INLINE word32 HashSigner(const byte* hash)
03651 {
03652     return MakeWordFromHash(hash) % CA_TABLE_SIZE;
03653 }
03654 
03655 
03656 /* does CA already exist on signer list */
03657 int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash)
03658 {
03659     Signer* signers;
03660     int     ret = 0;
03661     word32  row;
03662 
03663     if (cm == NULL || hash == NULL) {
03664         return ret;
03665     }
03666 
03667     row = HashSigner(hash);
03668 
03669     if (wc_LockMutex(&cm->caLock) != 0) {
03670         return ret;
03671     }
03672     signers = cm->caTable[row];
03673     while (signers) {
03674         byte* subjectHash;
03675 
03676     #ifndef NO_SKID
03677         subjectHash = signers->subjectKeyIdHash;
03678     #else
03679         subjectHash = signers->subjectNameHash;
03680     #endif
03681 
03682         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
03683             ret = 1; /* success */
03684             break;
03685         }
03686         signers = signers->next;
03687     }
03688     wc_UnLockMutex(&cm->caLock);
03689 
03690     return ret;
03691 }
03692 
03693 
03694 #ifdef WOLFSSL_TRUST_PEER_CERT
03695 /* hash is the SHA digest of name, just use first 32 bits as hash */
03696 static WC_INLINE word32 TrustedPeerHashSigner(const byte* hash)
03697 {
03698     return MakeWordFromHash(hash) % TP_TABLE_SIZE;
03699 }
03700 
03701 /* does trusted peer already exist on signer list */
03702 int AlreadyTrustedPeer(WOLFSSL_CERT_MANAGER* cm, byte* hash)
03703 {
03704     TrustedPeerCert* tp;
03705     int     ret = 0;
03706     word32  row = TrustedPeerHashSigner(hash);
03707 
03708     if (wc_LockMutex(&cm->tpLock) != 0)
03709         return  ret;
03710     tp = cm->tpTable[row];
03711     while (tp) {
03712         byte* subjectHash;
03713         #ifndef NO_SKID
03714             subjectHash = tp->subjectKeyIdHash;
03715         #else
03716             subjectHash = tp->subjectNameHash;
03717         #endif
03718         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
03719             ret = 1;
03720             break;
03721         }
03722         tp = tp->next;
03723     }
03724     wc_UnLockMutex(&cm->tpLock);
03725 
03726     return ret;
03727 }
03728 
03729 
03730 /* return Trusted Peer if found, otherwise NULL
03731     type is what to match on
03732  */
03733 TrustedPeerCert* GetTrustedPeer(void* vp, byte* hash, int type)
03734 {
03735     WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
03736     TrustedPeerCert* ret = NULL;
03737     TrustedPeerCert* tp  = NULL;
03738     word32  row;
03739 
03740     if (cm == NULL || hash == NULL)
03741         return NULL;
03742 
03743     row = TrustedPeerHashSigner(hash);
03744 
03745     if (wc_LockMutex(&cm->tpLock) != 0)
03746         return ret;
03747 
03748     tp = cm->tpTable[row];
03749     while (tp) {
03750         byte* subjectHash;
03751         switch (type) {
03752             #ifndef NO_SKID
03753             case WC_MATCH_SKID:
03754                 subjectHash = tp->subjectKeyIdHash;
03755                 break;
03756             #endif
03757             case WC_MATCH_NAME:
03758                 subjectHash = tp->subjectNameHash;
03759                 break;
03760             default:
03761                 WOLFSSL_MSG("Unknown search type");
03762                 wc_UnLockMutex(&cm->tpLock);
03763                 return NULL;
03764         }
03765         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
03766             ret = tp;
03767             break;
03768         }
03769         tp = tp->next;
03770     }
03771     wc_UnLockMutex(&cm->tpLock);
03772 
03773     return ret;
03774 }
03775 
03776 
03777 int MatchTrustedPeer(TrustedPeerCert* tp, DecodedCert* cert)
03778 {
03779     if (tp == NULL || cert == NULL)
03780         return BAD_FUNC_ARG;
03781 
03782     /* subject key id or subject hash has been compared when searching
03783        tpTable for the cert from function GetTrustedPeer */
03784 
03785     /* compare signatures */
03786     if (tp->sigLen == cert->sigLength) {
03787         if (XMEMCMP(tp->sig, cert->signature, cert->sigLength)) {
03788             return WOLFSSL_FAILURE;
03789         }
03790     }
03791     else {
03792         return WOLFSSL_FAILURE;
03793     }
03794 
03795     return WOLFSSL_SUCCESS;
03796 }
03797 #endif /* WOLFSSL_TRUST_PEER_CERT */
03798 
03799 
03800 /* return CA if found, otherwise NULL */
03801 Signer* GetCA(void* vp, byte* hash)
03802 {
03803     WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
03804     Signer* ret = NULL;
03805     Signer* signers;
03806     word32  row = HashSigner(hash);
03807 
03808     if (cm == NULL)
03809         return NULL;
03810 
03811     if (wc_LockMutex(&cm->caLock) != 0)
03812         return ret;
03813 
03814     signers = cm->caTable[row];
03815     while (signers) {
03816         byte* subjectHash;
03817         #ifndef NO_SKID
03818             subjectHash = signers->subjectKeyIdHash;
03819         #else
03820             subjectHash = signers->subjectNameHash;
03821         #endif
03822         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
03823             ret = signers;
03824             break;
03825         }
03826         signers = signers->next;
03827     }
03828     wc_UnLockMutex(&cm->caLock);
03829 
03830     return ret;
03831 }
03832 
03833 
03834 #ifndef NO_SKID
03835 /* return CA if found, otherwise NULL. Walk through hash table. */
03836 Signer* GetCAByName(void* vp, byte* hash)
03837 {
03838     WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
03839     Signer* ret = NULL;
03840     Signer* signers;
03841     word32  row;
03842 
03843     if (cm == NULL)
03844         return NULL;
03845 
03846     if (wc_LockMutex(&cm->caLock) != 0)
03847         return ret;
03848 
03849     for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
03850         signers = cm->caTable[row];
03851         while (signers && ret == NULL) {
03852             if (XMEMCMP(hash, signers->subjectNameHash,
03853                         SIGNER_DIGEST_SIZE) == 0) {
03854                 ret = signers;
03855             }
03856             signers = signers->next;
03857         }
03858     }
03859     wc_UnLockMutex(&cm->caLock);
03860 
03861     return ret;
03862 }
03863 #endif
03864 
03865 
03866 #ifdef WOLFSSL_TRUST_PEER_CERT
03867 /* add a trusted peer cert to linked list */
03868 int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify)
03869 {
03870     int ret, row;
03871     TrustedPeerCert* peerCert;
03872     DecodedCert* cert = NULL;
03873     DerBuffer*   der = *pDer;
03874     byte* subjectHash = NULL;
03875 
03876     WOLFSSL_MSG("Adding a Trusted Peer Cert");
03877 
03878     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
03879                                  DYNAMIC_TYPE_DCERT);
03880     if (cert == NULL)
03881         return MEMORY_E;
03882 
03883     InitDecodedCert(cert, der->buffer, der->length, cm->heap);
03884     if ((ret = ParseCert(cert, TRUSTED_PEER_TYPE, verify, cm)) != 0) {
03885         XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
03886         return ret;
03887     }
03888     WOLFSSL_MSG("\tParsed new trusted peer cert");
03889 
03890     peerCert = (TrustedPeerCert*)XMALLOC(sizeof(TrustedPeerCert), cm->heap,
03891                                                              DYNAMIC_TYPE_CERT);
03892     if (peerCert == NULL) {
03893         FreeDecodedCert(cert);
03894         XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
03895         return MEMORY_E;
03896     }
03897     XMEMSET(peerCert, 0, sizeof(TrustedPeerCert));
03898 
03899 #ifndef NO_SKID
03900     if (cert->extAuthKeyIdSet) {
03901         subjectHash = cert->extSubjKeyId;
03902     }
03903     else {
03904         subjectHash = cert->subjectHash;
03905     }
03906 #else
03907     subjectHash = cert->subjectHash;
03908 #endif
03909 
03910     #ifndef IGNORE_NAME_CONSTRAINTS
03911         if (peerCert->permittedNames)
03912             FreeNameSubtrees(peerCert->permittedNames, cm->heap);
03913         if (peerCert->excludedNames)
03914             FreeNameSubtrees(peerCert->excludedNames, cm->heap);
03915     #endif
03916 
03917     if (AlreadyTrustedPeer(cm, subjectHash)) {
03918         WOLFSSL_MSG("\tAlready have this CA, not adding again");
03919         (void)ret;
03920     }
03921     else {
03922         /* add trusted peer signature */
03923         peerCert->sigLen = cert->sigLength;
03924         peerCert->sig = XMALLOC(cert->sigLength, cm->heap,
03925                                                         DYNAMIC_TYPE_SIGNATURE);
03926         if (peerCert->sig == NULL) {
03927             FreeDecodedCert(cert);
03928             XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
03929             FreeTrustedPeer(peerCert, cm->heap);
03930             return MEMORY_E;
03931         }
03932         XMEMCPY(peerCert->sig, cert->signature, cert->sigLength);
03933 
03934         /* add trusted peer name */
03935         peerCert->nameLen = cert->subjectCNLen;
03936         peerCert->name    = cert->subjectCN;
03937         #ifndef IGNORE_NAME_CONSTRAINTS
03938             peerCert->permittedNames = cert->permittedNames;
03939             peerCert->excludedNames  = cert->excludedNames;
03940         #endif
03941 
03942         /* add SKID when available and hash of name */
03943         #ifndef NO_SKID
03944             XMEMCPY(peerCert->subjectKeyIdHash, cert->extSubjKeyId,
03945                     SIGNER_DIGEST_SIZE);
03946         #endif
03947             XMEMCPY(peerCert->subjectNameHash, cert->subjectHash,
03948                     SIGNER_DIGEST_SIZE);
03949             peerCert->next    = NULL; /* If Key Usage not set, all uses valid. */
03950             cert->subjectCN = 0;
03951         #ifndef IGNORE_NAME_CONSTRAINTS
03952             cert->permittedNames = NULL;
03953             cert->excludedNames = NULL;
03954         #endif
03955 
03956         #ifndef NO_SKID
03957             if (cert->extAuthKeyIdSet) {
03958                 row = TrustedPeerHashSigner(peerCert->subjectKeyIdHash);
03959             }
03960             else {
03961                 row = TrustedPeerHashSigner(peerCert->subjectNameHash);
03962             }
03963         #else
03964             row = TrustedPeerHashSigner(peerCert->subjectNameHash);
03965         #endif
03966 
03967             if (wc_LockMutex(&cm->tpLock) == 0) {
03968                 peerCert->next = cm->tpTable[row];
03969                 cm->tpTable[row] = peerCert;   /* takes ownership */
03970                 wc_UnLockMutex(&cm->tpLock);
03971             }
03972             else {
03973                 WOLFSSL_MSG("\tTrusted Peer Cert Mutex Lock failed");
03974                 FreeDecodedCert(cert);
03975                 XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
03976                 FreeTrustedPeer(peerCert, cm->heap);
03977                 return BAD_MUTEX_E;
03978             }
03979         }
03980 
03981     WOLFSSL_MSG("\tFreeing parsed trusted peer cert");
03982     FreeDecodedCert(cert);
03983     XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
03984     WOLFSSL_MSG("\tFreeing der trusted peer cert");
03985     FreeDer(&der);
03986     WOLFSSL_MSG("\t\tOK Freeing der trusted peer cert");
03987     WOLFSSL_LEAVE("AddTrustedPeer", ret);
03988 
03989     return WOLFSSL_SUCCESS;
03990 }
03991 #endif /* WOLFSSL_TRUST_PEER_CERT */
03992 
03993 
03994 /* owns der, internal now uses too */
03995 /* type flag ids from user or from chain received during verify
03996    don't allow chain ones to be added w/o isCA extension */
03997 int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
03998 {
03999     int         ret;
04000     Signer*     signer = NULL;
04001     word32      row;
04002     byte*       subjectHash;
04003 #ifdef WOLFSSL_SMALL_STACK
04004     DecodedCert* cert = NULL;
04005 #else
04006     DecodedCert  cert[1];
04007 #endif
04008     DerBuffer*   der = *pDer;
04009 
04010     WOLFSSL_MSG("Adding a CA");
04011 
04012 #ifdef WOLFSSL_SMALL_STACK
04013     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
04014                                  DYNAMIC_TYPE_DCERT);
04015     if (cert == NULL)
04016         return MEMORY_E;
04017 #endif
04018 
04019     InitDecodedCert(cert, der->buffer, der->length, cm->heap);
04020     ret = ParseCert(cert, CA_TYPE, verify, cm);
04021     WOLFSSL_MSG("\tParsed new CA");
04022 
04023 #ifndef NO_SKID
04024     subjectHash = cert->extSubjKeyId;
04025 #else
04026     subjectHash = cert->subjectHash;
04027 #endif
04028 
04029     /* check CA key size */
04030     if (verify) {
04031         switch (cert->keyOID) {
04032             #ifndef NO_RSA
04033             case RSAk:
04034                 if (cm->minRsaKeySz < 0 ||
04035                                    cert->pubKeySize < (word16)cm->minRsaKeySz) {
04036                     ret = RSA_KEY_SIZE_E;
04037                     WOLFSSL_MSG("\tCA RSA key size error");
04038                 }
04039                 break;
04040             #endif /* !NO_RSA */
04041             #ifdef HAVE_ECC
04042             case ECDSAk:
04043                 if (cm->minEccKeySz < 0 ||
04044                                    cert->pubKeySize < (word16)cm->minEccKeySz) {
04045                     ret = ECC_KEY_SIZE_E;
04046                     WOLFSSL_MSG("\tCA ECC key size error");
04047                 }
04048                 break;
04049             #endif /* HAVE_ECC */
04050             #ifdef HAVE_ED25519
04051             case ED25519k:
04052                 if (cm->minEccKeySz < 0 ||
04053                                    ED25519_KEY_SIZE < (word16)cm->minEccKeySz) {
04054                     ret = ECC_KEY_SIZE_E;
04055                     WOLFSSL_MSG("\tCA ECC key size error");
04056                 }
04057                 break;
04058             #endif /* HAVE_ED25519 */
04059 
04060             default:
04061                 WOLFSSL_MSG("\tNo key size check done on CA");
04062                 break; /* no size check if key type is not in switch */
04063         }
04064     }
04065 
04066     if (ret == 0 && cert->isCA == 0 && type != WOLFSSL_USER_CA) {
04067         WOLFSSL_MSG("\tCan't add as CA if not actually one");
04068         ret = NOT_CA_ERROR;
04069     }
04070 #ifndef ALLOW_INVALID_CERTSIGN
04071     else if (ret == 0 && cert->isCA == 1 && type != WOLFSSL_USER_CA &&
04072              (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) == 0) {
04073         /* Intermediate CA certs are required to have the keyCertSign
04074         * extension set. User loaded root certs are not. */
04075         WOLFSSL_MSG("\tDoesn't have key usage certificate signing");
04076         ret = NOT_CA_ERROR;
04077     }
04078 #endif
04079     else if (ret == 0 && AlreadySigner(cm, subjectHash)) {
04080         WOLFSSL_MSG("\tAlready have this CA, not adding again");
04081         (void)ret;
04082     }
04083     else if (ret == 0) {
04084         /* take over signer parts */
04085         signer = MakeSigner(cm->heap);
04086         if (!signer)
04087             ret = MEMORY_ERROR;
04088     }
04089     if (ret == 0 && signer != NULL) {
04090     #ifdef WOLFSSL_SIGNER_DER_CERT
04091         ret = AllocDer(&signer->derCert, der->length, der->type, NULL);
04092     }
04093     if (ret == 0 && signer != NULL) {
04094         XMEMCPY(signer->derCert->buffer, der->buffer, der->length);
04095     #endif
04096         signer->keyOID         = cert->keyOID;
04097         if (cert->pubKeyStored) {
04098             signer->publicKey      = cert->publicKey;
04099             signer->pubKeySize     = cert->pubKeySize;
04100         }
04101         if (cert->subjectCNStored) {
04102             signer->nameLen        = cert->subjectCNLen;
04103             signer->name           = cert->subjectCN;
04104         }
04105         signer->pathLength     = cert->pathLength;
04106         signer->pathLengthSet  = cert->pathLengthSet;
04107     #ifndef IGNORE_NAME_CONSTRAINTS
04108         signer->permittedNames = cert->permittedNames;
04109         signer->excludedNames  = cert->excludedNames;
04110     #endif
04111     #ifndef NO_SKID
04112         XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
04113                 SIGNER_DIGEST_SIZE);
04114     #endif
04115         XMEMCPY(signer->subjectNameHash, cert->subjectHash,
04116                 SIGNER_DIGEST_SIZE);
04117         signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
04118                                                 : 0xFFFF;
04119         signer->next    = NULL; /* If Key Usage not set, all uses valid. */
04120         cert->publicKey = 0;    /* in case lock fails don't free here.   */
04121         cert->subjectCN = 0;
04122     #ifndef IGNORE_NAME_CONSTRAINTS
04123         cert->permittedNames = NULL;
04124         cert->excludedNames = NULL;
04125     #endif
04126 
04127     #ifndef NO_SKID
04128         row = HashSigner(signer->subjectKeyIdHash);
04129     #else
04130         row = HashSigner(signer->subjectNameHash);
04131     #endif
04132 
04133         if (wc_LockMutex(&cm->caLock) == 0) {
04134             signer->next = cm->caTable[row];
04135             cm->caTable[row] = signer;   /* takes ownership */
04136             wc_UnLockMutex(&cm->caLock);
04137             if (cm->caCacheCallback)
04138                 cm->caCacheCallback(der->buffer, (int)der->length, type);
04139         }
04140         else {
04141             WOLFSSL_MSG("\tCA Mutex Lock failed");
04142             ret = BAD_MUTEX_E;
04143             FreeSigner(signer, cm->heap);
04144         }
04145     }
04146 
04147     WOLFSSL_MSG("\tFreeing Parsed CA");
04148     FreeDecodedCert(cert);
04149 #ifdef WOLFSSL_SMALL_STACK
04150     XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
04151 #endif
04152     WOLFSSL_MSG("\tFreeing der CA");
04153     FreeDer(pDer);
04154     WOLFSSL_MSG("\t\tOK Freeing der CA");
04155 
04156     WOLFSSL_LEAVE("AddCA", ret);
04157 
04158     return ret == 0 ? WOLFSSL_SUCCESS : ret;
04159 }
04160 
04161 #endif /* !NO_CERTS */
04162 
04163 
04164 #ifndef NO_SESSION_CACHE
04165 
04166     /* basic config gives a cache with 33 sessions, adequate for clients and
04167        embedded servers
04168 
04169        MEDIUM_SESSION_CACHE allows 1055 sessions, adequate for servers that
04170        aren't under heavy load, basically allows 200 new sessions per minute
04171 
04172        BIG_SESSION_CACHE yields 20,027 sessions
04173 
04174        HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
04175        allows over 13,000 new sessions per minute or over 200 new sessions per
04176        second
04177 
04178        SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients
04179        or systems where the default of nearly 3kB is too much RAM, this define
04180        uses less than 500 bytes RAM
04181 
04182        default SESSION_CACHE stores 33 sessions (no XXX_SESSION_CACHE defined)
04183     */
04184     #ifdef HUGE_SESSION_CACHE
04185         #define SESSIONS_PER_ROW 11
04186         #define SESSION_ROWS 5981
04187     #elif defined(BIG_SESSION_CACHE)
04188         #define SESSIONS_PER_ROW 7
04189         #define SESSION_ROWS 2861
04190     #elif defined(MEDIUM_SESSION_CACHE)
04191         #define SESSIONS_PER_ROW 5
04192         #define SESSION_ROWS 211
04193     #elif defined(SMALL_SESSION_CACHE)
04194         #define SESSIONS_PER_ROW 2
04195         #define SESSION_ROWS 3
04196     #else
04197         #define SESSIONS_PER_ROW 3
04198         #define SESSION_ROWS 11
04199     #endif
04200 
04201     typedef struct SessionRow {
04202         int nextIdx;                           /* where to place next one   */
04203         int totalCount;                        /* sessions ever on this row */
04204         WOLFSSL_SESSION Sessions[SESSIONS_PER_ROW];
04205     } SessionRow;
04206 
04207     static SessionRow SessionCache[SESSION_ROWS];
04208 
04209     #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
04210         static word32 PeakSessions;
04211     #endif
04212 
04213     static wolfSSL_Mutex session_mutex;   /* SessionCache mutex */
04214 
04215     #ifndef NO_CLIENT_CACHE
04216 
04217         typedef struct ClientSession {
04218             word16 serverRow;            /* SessionCache Row id */
04219             word16 serverIdx;            /* SessionCache Idx (column) */
04220         } ClientSession;
04221 
04222         typedef struct ClientRow {
04223             int nextIdx;                /* where to place next one   */
04224             int totalCount;             /* sessions ever on this row */
04225             ClientSession Clients[SESSIONS_PER_ROW];
04226         } ClientRow;
04227 
04228         static ClientRow ClientCache[SESSION_ROWS];  /* Client Cache */
04229                                                      /* uses session mutex */
04230     #endif  /* NO_CLIENT_CACHE */
04231 
04232 #endif /* NO_SESSION_CACHE */
04233 
04234 int wolfSSL_Init(void)
04235 {
04236     WOLFSSL_ENTER("wolfSSL_Init");
04237 
04238     if (initRefCount == 0) {
04239         /* Initialize crypto for use with TLS connection */
04240         if (wolfCrypt_Init() != 0) {
04241             WOLFSSL_MSG("Bad wolfCrypt Init");
04242             return WC_INIT_E;
04243         }
04244 #ifndef NO_SESSION_CACHE
04245         if (wc_InitMutex(&session_mutex) != 0) {
04246             WOLFSSL_MSG("Bad Init Mutex session");
04247             return BAD_MUTEX_E;
04248         }
04249 #endif
04250         if (wc_InitMutex(&count_mutex) != 0) {
04251             WOLFSSL_MSG("Bad Init Mutex count");
04252             return BAD_MUTEX_E;
04253         }
04254     }
04255 
04256     if (wc_LockMutex(&count_mutex) != 0) {
04257         WOLFSSL_MSG("Bad Lock Mutex count");
04258         return BAD_MUTEX_E;
04259     }
04260 
04261     initRefCount++;
04262     wc_UnLockMutex(&count_mutex);
04263 
04264     return WOLFSSL_SUCCESS;
04265 }
04266 
04267 
04268 
04269 #ifndef NO_CERTS
04270 
04271 /* process user cert chain to pass during the handshake */
04272 static int ProcessUserChain(WOLFSSL_CTX* ctx, const unsigned char* buff,
04273                          long sz, int format, int type, WOLFSSL* ssl,
04274                          long* used, EncryptedInfo* info)
04275 {
04276     int ret = 0;
04277     void* heap = wolfSSL_CTX_GetHeap(ctx, ssl);
04278 #ifdef WOLFSSL_TLS13
04279     int cnt = 0;
04280 #endif
04281 
04282     /* we may have a user cert chain, try to consume */
04283     if (type == CERT_TYPE && info->consumed < sz) {
04284     #ifdef WOLFSSL_SMALL_STACK
04285         byte   staticBuffer[1];                 /* force heap usage */
04286     #else
04287         byte   staticBuffer[FILE_BUFFER_SIZE];  /* tmp chain buffer */
04288     #endif
04289         byte*  chainBuffer = staticBuffer;
04290         int    dynamicBuffer = 0;
04291         word32 bufferSz;
04292         long   consumed = info->consumed;
04293         word32 idx = 0;
04294         int    gotOne = 0;
04295 
04296         /* Calculate max possible size, including max headers */
04297         bufferSz = (word32)(sz - consumed) + (CERT_HEADER_SZ * MAX_CHAIN_DEPTH);
04298         if (bufferSz > sizeof(staticBuffer)) {
04299             WOLFSSL_MSG("Growing Tmp Chain Buffer");
04300             /* will shrink to actual size */
04301             chainBuffer = (byte*)XMALLOC(bufferSz, heap, DYNAMIC_TYPE_FILE);
04302             if (chainBuffer == NULL) {
04303                 return MEMORY_E;
04304             }
04305             dynamicBuffer = 1;
04306         }
04307 
04308         WOLFSSL_MSG("Processing Cert Chain");
04309         while (consumed < sz) {
04310             DerBuffer* part = NULL;
04311             word32 remain = (word32)(sz - consumed);
04312             info->consumed = 0;
04313 
04314             if (format == WOLFSSL_FILETYPE_PEM) {
04315             #ifdef WOLFSSL_PEM_TO_DER
04316                 ret = PemToDer(buff + consumed, remain, type, &part,
04317                                heap, info, NULL);
04318             #else
04319                 ret = NOT_COMPILED_IN;
04320             #endif
04321             }
04322             else {
04323                 int length = remain;
04324                 if (format == WOLFSSL_FILETYPE_ASN1) {
04325                     /* get length of der (read sequence) */
04326                     word32 inOutIdx = 0;
04327                     if (GetSequence(buff + consumed, &inOutIdx, &length, remain) < 0) {
04328                         ret = ASN_NO_PEM_HEADER;
04329                     }
04330                     length += inOutIdx; /* include leading sequence */
04331                 }
04332                 info->consumed = length;
04333                 if (ret == 0) {
04334                     ret = AllocDer(&part, length, type, heap);
04335                     if (ret == 0) {
04336                         XMEMCPY(part->buffer, buff + consumed, length);
04337                     }
04338                 }
04339             }
04340             if (ret == 0) {
04341                 gotOne = 1;
04342 #ifdef WOLFSSL_TLS13
04343                 cnt++;
04344 #endif
04345                 if ((idx + part->length + CERT_HEADER_SZ) > bufferSz) {
04346                     WOLFSSL_MSG("   Cert Chain bigger than buffer");
04347                     ret = BUFFER_E;
04348                 }
04349                 else {
04350                     c32to24(part->length, &chainBuffer[idx]);
04351                     idx += CERT_HEADER_SZ;
04352                     XMEMCPY(&chainBuffer[idx], part->buffer, part->length);
04353                     idx += part->length;
04354                     consumed  += info->consumed;
04355                     if (used)
04356                         *used += info->consumed;
04357                 }
04358             }
04359             FreeDer(&part);
04360 
04361             if (ret == ASN_NO_PEM_HEADER && gotOne) {
04362                 WOLFSSL_MSG("We got one good cert, so stuff at end ok");
04363                 break;
04364             }
04365 
04366             if (ret < 0) {
04367                 WOLFSSL_MSG("   Error in Cert in Chain");
04368                 if (dynamicBuffer)
04369                     XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
04370                 return ret;
04371             }
04372             WOLFSSL_MSG("   Consumed another Cert in Chain");
04373         }
04374         WOLFSSL_MSG("Finished Processing Cert Chain");
04375 
04376         /* only retain actual size used */
04377         ret = 0;
04378         if (idx > 0) {
04379             if (ssl) {
04380                 if (ssl->buffers.weOwnCertChain) {
04381                     FreeDer(&ssl->buffers.certChain);
04382                 }
04383                 ret = AllocDer(&ssl->buffers.certChain, idx, type, heap);
04384                 if (ret == 0) {
04385                     XMEMCPY(ssl->buffers.certChain->buffer, chainBuffer, idx);
04386                     ssl->buffers.weOwnCertChain = 1;
04387                 }
04388 #ifdef WOLFSSL_TLS13
04389                 ssl->buffers.certChainCnt = cnt;
04390 #endif
04391             } else if (ctx) {
04392                 FreeDer(&ctx->certChain);
04393                 ret = AllocDer(&ctx->certChain, idx, type, heap);
04394                 if (ret == 0) {
04395                     XMEMCPY(ctx->certChain->buffer, chainBuffer, idx);
04396                 }
04397 #ifdef WOLFSSL_TLS13
04398                 ctx->certChainCnt = cnt;
04399 #endif
04400             }
04401         }
04402 
04403         if (dynamicBuffer)
04404             XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
04405     }
04406 
04407     return ret;
04408 }
04409 /* process the buffer buff, length sz, into ctx of format and type
04410    used tracks bytes consumed, userChain specifies a user cert chain
04411    to pass during the handshake */
04412 int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
04413                          long sz, int format, int type, WOLFSSL* ssl,
04414                          long* used, int userChain)
04415 {
04416     DerBuffer*    der = NULL;        /* holds DER or RAW (for NTRU) */
04417     int           ret = 0;
04418     int           eccKey = 0;
04419     int           ed25519Key = 0;
04420     int           rsaKey = 0;
04421     int           resetSuites = 0;
04422     void*         heap = wolfSSL_CTX_GetHeap(ctx, ssl);
04423     int           devId = wolfSSL_CTX_GetDevId(ctx, ssl);
04424 #ifdef WOLFSSL_SMALL_STACK
04425     EncryptedInfo* info = NULL;
04426 #else
04427     EncryptedInfo  info[1];
04428 #endif
04429 
04430     (void)rsaKey;
04431     (void)devId;
04432 
04433     if (used)
04434         *used = sz;     /* used bytes default to sz, PEM chain may shorten*/
04435 
04436     /* check args */
04437     if (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM
04438                                     && format != WOLFSSL_FILETYPE_RAW)
04439         return WOLFSSL_BAD_FILETYPE;
04440 
04441     if (ctx == NULL && ssl == NULL)
04442         return BAD_FUNC_ARG;
04443 
04444 #ifdef WOLFSSL_SMALL_STACK
04445     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), heap,
04446                                    DYNAMIC_TYPE_ENCRYPTEDINFO);
04447     if (info == NULL)
04448         return MEMORY_E;
04449 #endif
04450 
04451     XMEMSET(info, 0, sizeof(EncryptedInfo));
04452 #ifdef WOLFSSL_ENCRYPTED_KEYS
04453     if (ctx) {
04454         info->passwd_cb       = ctx->passwd_cb;
04455         info->passwd_userdata = ctx->passwd_userdata;
04456     }
04457 #endif
04458 
04459     if (format == WOLFSSL_FILETYPE_PEM) {
04460     #ifdef WOLFSSL_PEM_TO_DER
04461         ret = PemToDer(buff, sz, type, &der, heap, info, &eccKey);
04462     #else
04463         ret = NOT_COMPILED_IN;
04464     #endif
04465     }
04466     else {
04467         /* ASN1 (DER) or RAW (NTRU) */
04468         int length = (int)sz;
04469         if (format == WOLFSSL_FILETYPE_ASN1) {
04470             /* get length of der (read sequence) */
04471             word32 inOutIdx = 0;
04472             if (GetSequence(buff, &inOutIdx, &length, (word32)sz) < 0) {
04473                 ret = ASN_PARSE_E;
04474             }
04475             length += inOutIdx; /* include leading sequence */
04476         }
04477 
04478         info->consumed = length;
04479 
04480         if (ret == 0) {
04481             ret = AllocDer(&der, (word32)length, type, heap);
04482             if (ret == 0) {
04483                 XMEMCPY(der->buffer, buff, length);
04484             }
04485         }
04486     }
04487 
04488     if (used) {
04489         *used = info->consumed;
04490     }
04491 
04492     /* process user chain */
04493     if (ret >= 0) {
04494         /* First certificate in chain is loaded into ssl->buffers.certificate.
04495          * Remainder are loaded into ssl->buffers.certChain.
04496          * Chain should have server cert first, then intermediates, then root.
04497          */
04498         if (userChain) {
04499             ret = ProcessUserChain(ctx, buff, sz, format, type, ssl, used, info);
04500         }
04501     }
04502 
04503 #ifdef WOLFSSL_ENCRYPTED_KEYS
04504     /* for WOLFSSL_FILETYPE_PEM, PemToDer manage the decryption if required */
04505     if (ret >= 0 && info->set && format != WOLFSSL_FILETYPE_PEM) {
04506         /* decrypt */
04507         int   passwordSz = NAME_SZ;
04508 #ifdef WOLFSSL_SMALL_STACK
04509         char* password = NULL;
04510 #else
04511         char  password[NAME_SZ];
04512 #endif
04513 
04514     #ifdef WOLFSSL_SMALL_STACK
04515         password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING);
04516         if (password == NULL)
04517             ret = MEMORY_E;
04518         else
04519     #endif
04520         if (info->passwd_cb == NULL) {
04521             WOLFSSL_MSG("No password callback set");
04522             ret = NO_PASSWORD;
04523         }
04524         else {
04525             ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,
04526                 info->passwd_userdata);
04527             if (ret >= 0) {
04528                 passwordSz = ret;
04529 
04530                 /* decrypt the key */
04531                 ret = wc_BufferKeyDecrypt(info, der->buffer, der->length,
04532                     (byte*)password, passwordSz, WC_MD5);
04533 
04534                 ForceZero(password, passwordSz);
04535             }
04536         }
04537 
04538     #ifdef WOLFSSL_SMALL_STACK
04539         XFREE(password, heap, DYNAMIC_TYPE_STRING);
04540     #endif
04541     }
04542 #endif /* WOLFSSL_ENCRYPTED_KEYS */
04543 
04544 #ifdef WOLFSSL_SMALL_STACK
04545     XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
04546 #endif
04547 
04548     /* check for error */
04549     if (ret < 0) {
04550         FreeDer(&der);
04551         return ret;
04552     }
04553 
04554     /* Handle DER owner */
04555     if (type == CA_TYPE) {
04556         if (ctx == NULL) {
04557             WOLFSSL_MSG("Need context for CA load");
04558             FreeDer(&der);
04559             return BAD_FUNC_ARG;
04560         }
04561         /* verify CA unless user set to no verify */
04562         return AddCA(ctx->cm, &der, WOLFSSL_USER_CA, !ctx->verifyNone);
04563     }
04564 #ifdef WOLFSSL_TRUST_PEER_CERT
04565     else if (type == TRUSTED_PEER_TYPE) {
04566         if (ctx == NULL) {
04567             WOLFSSL_MSG("Need context for trusted peer cert load");
04568             FreeDer(&der);
04569             return BAD_FUNC_ARG;
04570         }
04571         /* add trusted peer cert */
04572         return AddTrustedPeer(ctx->cm, &der, !ctx->verifyNone);
04573     }
04574 #endif /* WOLFSSL_TRUST_PEER_CERT */
04575     else if (type == CERT_TYPE) {
04576         if (ssl) {
04577              /* Make sure previous is free'd */
04578             if (ssl->buffers.weOwnCert) {
04579                 FreeDer(&ssl->buffers.certificate);
04580             #ifdef KEEP_OUR_CERT
04581                 FreeX509(ssl->ourCert);
04582                 if (ssl->ourCert) {
04583                     XFREE(ssl->ourCert, ssl->heap, DYNAMIC_TYPE_X509);
04584                     ssl->ourCert = NULL;
04585                 }
04586             #endif
04587             }
04588             ssl->buffers.certificate = der;
04589         #ifdef KEEP_OUR_CERT
04590             ssl->keepCert = 1; /* hold cert for ssl lifetime */
04591         #endif
04592             ssl->buffers.weOwnCert = 1;
04593         }
04594         else if (ctx) {
04595             FreeDer(&ctx->certificate); /* Make sure previous is free'd */
04596         #ifdef KEEP_OUR_CERT
04597             if (ctx->ourCert) {
04598                 if (ctx->ownOurCert) {
04599                     FreeX509(ctx->ourCert);
04600                     XFREE(ctx->ourCert, ctx->heap, DYNAMIC_TYPE_X509);
04601                 }
04602                 ctx->ourCert = NULL;
04603             }
04604         #endif
04605             ctx->certificate = der;
04606         }
04607     }
04608     else if (type == PRIVATEKEY_TYPE) {
04609         if (ssl) {
04610              /* Make sure previous is free'd */
04611             if (ssl->buffers.weOwnKey) {
04612                 FreeDer(&ssl->buffers.key);
04613             }
04614             ssl->buffers.key = der;
04615             ssl->buffers.weOwnKey = 1;
04616         }
04617         else if (ctx) {
04618             FreeDer(&ctx->privateKey);
04619             ctx->privateKey = der;
04620         }
04621     }
04622     else {
04623         FreeDer(&der);
04624         return WOLFSSL_BAD_CERTTYPE;
04625     }
04626 
04627     if (type == PRIVATEKEY_TYPE && format != WOLFSSL_FILETYPE_RAW) {
04628     #ifndef NO_RSA
04629         if (!eccKey && !ed25519Key) {
04630             /* make sure RSA key can be used */
04631             word32 idx = 0;
04632         #ifdef WOLFSSL_SMALL_STACK
04633             RsaKey* key = NULL;
04634         #else
04635             RsaKey  key[1];
04636         #endif
04637 
04638         #ifdef WOLFSSL_SMALL_STACK
04639             key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_RSA);
04640             if (key == NULL)
04641                 return MEMORY_E;
04642         #endif
04643 
04644             ret = wc_InitRsaKey_ex(key, heap, devId);
04645             if (ret == 0) {
04646                 if (wc_RsaPrivateKeyDecode(der->buffer, &idx, key, der->length)
04647                     != 0) {
04648                 #ifdef HAVE_ECC
04649                     /* could have DER ECC (or pkcs8 ecc), no easy way to tell */
04650                     eccKey = 1;  /* try it next */
04651                 #elif defined(HAVE_ED25519)
04652                     ed25519Key = 1; /* try it next */
04653                 #else
04654                     WOLFSSL_MSG("RSA decode failed and ECC not enabled to try");
04655                     ret = WOLFSSL_BAD_FILE;
04656                 #endif
04657                 }
04658                 else {
04659                     /* check that the size of the RSA key is enough */
04660                     int rsaSz = wc_RsaEncryptSize((RsaKey*)key);
04661                     int minRsaSz;
04662 
04663                     minRsaSz = ssl ? ssl->options.minRsaKeySz : ctx->minRsaKeySz;
04664                     if (rsaSz < minRsaSz) {
04665                         ret = RSA_KEY_SIZE_E;
04666                         WOLFSSL_MSG("Private Key size too small");
04667                     }
04668 
04669                     if (ssl) {
04670                         ssl->buffers.keyType = rsa_sa_algo;
04671                         ssl->buffers.keySz = rsaSz;
04672                     }
04673                     else if(ctx) {
04674                         ctx->privateKeyType = rsa_sa_algo;
04675                         ctx->privateKeySz = rsaSz;
04676                     }
04677 
04678                     rsaKey = 1;
04679                     (void)rsaKey;  /* for no ecc builds */
04680 
04681                     if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
04682                         ssl->options.haveStaticECC = 0;
04683                         resetSuites = 1;
04684                     }
04685                 }
04686 
04687                 wc_FreeRsaKey(key);
04688             }
04689 
04690         #ifdef WOLFSSL_SMALL_STACK
04691             XFREE(key, heap, DYNAMIC_TYPE_RSA);
04692         #endif
04693 
04694             if (ret != 0)
04695                 return ret;
04696         }
04697     #endif
04698     #ifdef HAVE_ECC
04699         if (!rsaKey && !ed25519Key) {
04700             /* make sure ECC key can be used */
04701             word32   idx = 0;
04702         #ifdef WOLFSSL_SMALL_STACK
04703             ecc_key* key = NULL;
04704         #else
04705             ecc_key  key[1];
04706         #endif
04707 
04708         #ifdef WOLFSSL_SMALL_STACK
04709             key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
04710             if (key == NULL)
04711                 return MEMORY_E;
04712         #endif
04713 
04714             if (wc_ecc_init_ex(key, heap, devId) == 0) {
04715                 if (wc_EccPrivateKeyDecode(der->buffer, &idx, key,
04716                                                             der->length) == 0) {
04717                     int keySz = wc_ecc_size(key);
04718                     int minKeySz;
04719 
04720                     /* check for minimum ECC key size and then free */
04721                     minKeySz = ssl ? ssl->options.minEccKeySz : ctx->minEccKeySz;
04722                     if (keySz < minKeySz) {
04723                         wc_ecc_free(key);
04724                         WOLFSSL_MSG("ECC private key too small");
04725                         return ECC_KEY_SIZE_E;
04726                     }
04727 
04728                     eccKey = 1;
04729                     if (ssl) {
04730                         ssl->options.haveStaticECC = 1;
04731                         ssl->buffers.keyType = ecc_dsa_sa_algo;
04732                         ssl->buffers.keySz = keySz;
04733                     }
04734                     else if (ctx) {
04735                         ctx->haveStaticECC = 1;
04736                         ctx->privateKeyType = ecc_dsa_sa_algo;
04737                         ctx->privateKeySz = keySz;
04738                     }
04739 
04740                     if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
04741                         resetSuites = 1;
04742                     }
04743                 }
04744                 else
04745                     eccKey = 0;
04746 
04747                 wc_ecc_free(key);
04748             }
04749 
04750         #ifdef WOLFSSL_SMALL_STACK
04751             XFREE(key, heap, DYNAMIC_TYPE_ECC);
04752         #endif
04753         }
04754     #endif /* HAVE_ECC */
04755     #ifdef HAVE_ED25519
04756         if (!rsaKey && !eccKey) {
04757             /* make sure Ed25519 key can be used */
04758             word32       idx = 0;
04759         #ifdef WOLFSSL_SMALL_STACK
04760             ed25519_key* key = NULL;
04761         #else
04762             ed25519_key  key[1];
04763         #endif
04764 
04765         #ifdef WOLFSSL_SMALL_STACK
04766             key = (ed25519_key*)XMALLOC(sizeof(ed25519_key), heap,
04767                                                           DYNAMIC_TYPE_ED25519);
04768             if (key == NULL)
04769                 return MEMORY_E;
04770         #endif
04771 
04772             ret = wc_ed25519_init(key);
04773             if (ret == 0) {
04774                 if (wc_Ed25519PrivateKeyDecode(der->buffer, &idx, key,
04775                                                             der->length) != 0) {
04776                     ret = WOLFSSL_BAD_FILE;
04777                 }
04778 
04779                 if (ret == 0) {
04780                     /* check for minimum key size and then free */
04781                     int minKeySz = ssl ? ssl->options.minEccKeySz :
04782                                                                ctx->minEccKeySz;
04783                     if (ED25519_KEY_SIZE < minKeySz) {
04784                         WOLFSSL_MSG("ED25519 private key too small");
04785                         ret = ECC_KEY_SIZE_E;
04786                     }
04787                 }
04788                 if (ret == 0) {
04789                     if (ssl) {
04790                         ssl->buffers.keyType = ed25519_sa_algo;
04791                         ssl->buffers.keySz = ED25519_KEY_SIZE;
04792                     }
04793                     else if (ctx) {
04794                         ctx->privateKeyType = ed25519_sa_algo;
04795                         ctx->privateKeySz = ED25519_KEY_SIZE;
04796                     }
04797 
04798                     ed25519Key = 1;
04799                     if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
04800                         resetSuites = 1;
04801                     }
04802                 }
04803 
04804                 wc_ed25519_free(key);
04805             }
04806 
04807         #ifdef WOLFSSL_SMALL_STACK
04808             XFREE(key, heap, DYNAMIC_TYPE_ED25519);
04809         #endif
04810             if (ret != 0)
04811                 return ret;
04812         }
04813     #else
04814         if (!rsaKey && !eccKey && !ed25519Key)
04815             return WOLFSSL_BAD_FILE;
04816     #endif
04817         (void)ed25519Key;
04818         (void)devId;
04819     }
04820     else if (type == CERT_TYPE) {
04821     #ifdef WOLFSSL_SMALL_STACK
04822         DecodedCert* cert = NULL;
04823     #else
04824         DecodedCert  cert[1];
04825     #endif
04826     #ifdef HAVE_PK_CALLBACKS
04827         int keyType = 0, keySz = 0;
04828     #endif
04829 
04830     #ifdef WOLFSSL_SMALL_STACK
04831         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap,
04832                                      DYNAMIC_TYPE_DCERT);
04833         if (cert == NULL)
04834             return MEMORY_E;
04835     #endif
04836 
04837         WOLFSSL_MSG("Checking cert signature type");
04838         InitDecodedCert(cert, der->buffer, der->length, heap);
04839 
04840         if (DecodeToKey(cert, 0) < 0) {
04841             WOLFSSL_MSG("Decode to key failed");
04842             FreeDecodedCert(cert);
04843         #ifdef WOLFSSL_SMALL_STACK
04844             XFREE(cert, heap, DYNAMIC_TYPE_DCERT);
04845         #endif
04846             return WOLFSSL_BAD_FILE;
04847         }
04848 
04849         if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
04850             resetSuites = 1;
04851         }
04852         if (ssl && ssl->ctx->haveECDSAsig) {
04853             WOLFSSL_MSG("SSL layer setting cert, CTX had ECDSA, turning off");
04854             ssl->options.haveECDSAsig = 0;   /* may turn back on next */
04855         }
04856 
04857         switch (cert->signatureOID) {
04858             case CTC_SHAwECDSA:
04859             case CTC_SHA256wECDSA:
04860             case CTC_SHA384wECDSA:
04861             case CTC_SHA512wECDSA:
04862                 WOLFSSL_MSG("ECDSA cert signature");
04863                 if (ssl)
04864                     ssl->options.haveECDSAsig = 1;
04865                 else if (ctx)
04866                     ctx->haveECDSAsig = 1;
04867                 break;
04868             case CTC_ED25519:
04869                 WOLFSSL_MSG("ED25519 cert signature");
04870                 if (ssl)
04871                     ssl->options.haveECDSAsig = 1;
04872                 else if (ctx)
04873                     ctx->haveECDSAsig = 1;
04874                 break;
04875             default:
04876                 WOLFSSL_MSG("Not ECDSA cert signature");
04877                 break;
04878         }
04879 
04880     #if defined(HAVE_ECC) || defined(HAVE_ED25519)
04881         if (ssl) {
04882             ssl->pkCurveOID = cert->pkCurveOID;
04883         #ifndef WC_STRICT_SIG
04884             if (cert->keyOID == ECDSAk) {
04885                 ssl->options.haveECC = 1;
04886             }
04887             #ifdef HAVE_ED25519
04888                 else if (cert->keyOID == ED25519k) {
04889                     ssl->options.haveECC = 1;
04890                 }
04891             #endif
04892         #else
04893             ssl->options.haveECC = ssl->options.haveECDSAsig;
04894         #endif
04895         }
04896         else if (ctx) {
04897             ctx->pkCurveOID = cert->pkCurveOID;
04898         #ifndef WC_STRICT_SIG
04899             if (cert->keyOID == ECDSAk) {
04900                 ctx->haveECC = 1;
04901             }
04902             #ifdef HAVE_ED25519
04903                 else if (cert->keyOID == ED25519k) {
04904                     ctx->haveECC = 1;
04905                 }
04906             #endif
04907         #else
04908             ctx->haveECC = ctx->haveECDSAsig;
04909         #endif
04910         }
04911     #endif
04912 
04913         /* check key size of cert unless specified not to */
04914         switch (cert->keyOID) {
04915         #ifndef NO_RSA
04916             case RSAk:
04917                 if (ssl && !ssl->options.verifyNone) {
04918                     if (ssl->options.minRsaKeySz < 0 ||
04919                           cert->pubKeySize < (word16)ssl->options.minRsaKeySz) {
04920                         ret = RSA_KEY_SIZE_E;
04921                         WOLFSSL_MSG("Certificate RSA key size too small");
04922                     }
04923                 }
04924                 else if (ctx && !ctx->verifyNone) {
04925                     if (ctx->minRsaKeySz < 0 ||
04926                                   cert->pubKeySize < (word16)ctx->minRsaKeySz) {
04927                         ret = RSA_KEY_SIZE_E;
04928                         WOLFSSL_MSG("Certificate RSA key size too small");
04929                     }
04930                 }
04931             #ifdef HAVE_PK_CALLBACKS
04932                 keyType = rsa_sa_algo;
04933                 /* pubKeySize is the encoded public key */
04934                 /* mask lsb 5-bits to round by 16 to get actual key size */
04935                 keySz = cert->pubKeySize & ~0x1FL;
04936             #endif
04937                 break;
04938         #endif /* !NO_RSA */
04939         #ifdef HAVE_ECC
04940             case ECDSAk:
04941                 if (ssl && !ssl->options.verifyNone) {
04942                     if (ssl->options.minEccKeySz < 0 ||
04943                           cert->pubKeySize < (word16)ssl->options.minEccKeySz) {
04944                         ret = ECC_KEY_SIZE_E;
04945                         WOLFSSL_MSG("Certificate ECC key size error");
04946                     }
04947                 }
04948                 else if (ctx && !ctx->verifyNone) {
04949                     if (ctx->minEccKeySz < 0 ||
04950                                   cert->pubKeySize < (word16)ctx->minEccKeySz) {
04951                         ret = ECC_KEY_SIZE_E;
04952                         WOLFSSL_MSG("Certificate ECC key size error");
04953                     }
04954                 }
04955             #ifdef HAVE_PK_CALLBACKS
04956                 keyType = ecc_dsa_sa_algo;
04957                 /* pubKeySize is encByte + x + y */
04958                 keySz = (cert->pubKeySize - 1) / 2;
04959             #endif
04960                 break;
04961         #endif /* HAVE_ECC */
04962         #ifdef HAVE_ED25519
04963             case ED25519k:
04964                 if (ssl && !ssl->options.verifyNone) {
04965                     if (ssl->options.minEccKeySz < 0 ||
04966                           ED25519_KEY_SIZE < (word16)ssl->options.minEccKeySz) {
04967                         ret = ECC_KEY_SIZE_E;
04968                         WOLFSSL_MSG("Certificate Ed key size error");
04969                     }
04970                 }
04971                 else if (ctx && !ctx->verifyNone) {
04972                     if (ctx->minEccKeySz < 0 ||
04973                                   ED25519_KEY_SIZE < (word16)ctx->minEccKeySz) {
04974                         ret = ECC_KEY_SIZE_E;
04975                         WOLFSSL_MSG("Certificate ECC key size error");
04976                     }
04977                 }
04978             #ifdef HAVE_PK_CALLBACKS
04979                 keyType = ed25519_sa_algo;
04980                 keySz = ED25519_KEY_SIZE;
04981             #endif
04982                 break;
04983         #endif /* HAVE_ED25519 */
04984 
04985             default:
04986                 WOLFSSL_MSG("No key size check done on certificate");
04987                 break; /* do no check if not a case for the key */
04988         }
04989 
04990     #ifdef HAVE_PK_CALLBACKS
04991         if (ssl && ssl->buffers.keyType == 0) {
04992             ssl->buffers.keyType = keyType;
04993             ssl->buffers.keySz = keySz;
04994         }
04995         else if (ctx && ctx->privateKeyType == 0) {
04996             ctx->privateKeyType = keyType;
04997             ctx->privateKeySz = keySz;
04998         }
04999     #endif
05000 
05001         FreeDecodedCert(cert);
05002     #ifdef WOLFSSL_SMALL_STACK
05003         XFREE(cert, heap, DYNAMIC_TYPE_DCERT);
05004     #endif
05005 
05006         if (ret != 0) {
05007             return ret;
05008         }
05009     }
05010 
05011     if (ssl && resetSuites) {
05012         word16 havePSK = 0;
05013         word16 haveRSA = 0;
05014         int    keySz   = 0;
05015 
05016         #ifndef NO_PSK
05017         if (ssl->options.havePSK) {
05018             havePSK = 1;
05019         }
05020         #endif
05021         #ifndef NO_RSA
05022             haveRSA = 1;
05023         #endif
05024         #ifndef NO_CERTS
05025             keySz = ssl->buffers.keySz;
05026         #endif
05027 
05028         /* let's reset suites */
05029         InitSuites(ssl->suites, ssl->version, keySz, haveRSA,
05030                    havePSK, ssl->options.haveDH, ssl->options.haveNTRU,
05031                    ssl->options.haveECDSAsig, ssl->options.haveECC,
05032                    ssl->options.haveStaticECC, ssl->options.side);
05033     }
05034 
05035     return WOLFSSL_SUCCESS;
05036 }
05037 
05038 
05039 /* CA PEM file for verification, may have multiple/chain certs to process */
05040 static int ProcessChainBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
05041                             long sz, int format, int type, WOLFSSL* ssl)
05042 {
05043     long used   = 0;
05044     int  ret    = 0;
05045     int  gotOne = 0;
05046 
05047     WOLFSSL_MSG("Processing CA PEM file");
05048     while (used < sz) {
05049         long consumed = 0;
05050 
05051         ret = ProcessBuffer(ctx, buff + used, sz - used, format, type, ssl,
05052                             &consumed, 0);
05053 
05054 #ifdef WOLFSSL_WPAS
05055 #ifdef HAVE_CRL
05056         if (ret < 0) {
05057             DerBuffer*    der = NULL;
05058             EncryptedInfo info;
05059 
05060             WOLFSSL_MSG("Trying a CRL");
05061             if (PemToDer(buff + used, sz - used, CRL_TYPE, &der, NULL, &info,
05062                                                                    NULL) == 0) {
05063                 WOLFSSL_MSG("   Proccessed a CRL");
05064                 wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, der->buffer,
05065                                                 der->length, WOLFSSL_FILETYPE_ASN1);
05066                 FreeDer(&der);
05067                 used += info.consumed;
05068                 continue;
05069             }
05070         }
05071 #endif
05072 #endif
05073         if (ret < 0)
05074         {
05075             if(consumed > 0) { /* Made progress in file */
05076                 WOLFSSL_ERROR(ret);
05077                 WOLFSSL_MSG("CA Parse failed, with progress in file.");
05078                 WOLFSSL_MSG("Search for other certs in file");
05079             } else {
05080                 WOLFSSL_MSG("CA Parse failed, no progress in file.");
05081                 WOLFSSL_MSG("Do not continue search for other certs in file");
05082                 break;
05083             }
05084         } else {
05085             WOLFSSL_MSG("   Processed a CA");
05086             gotOne = 1;
05087         }
05088         used += consumed;
05089     }
05090 
05091     if(gotOne)
05092     {
05093         WOLFSSL_MSG("Processed at least one valid CA. Other stuff OK");
05094         return WOLFSSL_SUCCESS;
05095     }
05096     return ret;
05097 }
05098 
05099 
05100 static WC_INLINE WOLFSSL_METHOD* cm_pick_method(void)
05101 {
05102     #ifndef NO_WOLFSSL_CLIENT
05103         #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
05104             return wolfSSLv3_client_method();
05105         #elif !defined(WOLFSSL_NO_TLS12)
05106             return wolfTLSv1_2_client_method();
05107         #elif defined(WOLFSSL_TLS13)
05108             return wolfTLSv1_3_client_method();
05109         #endif
05110     #elif !defined(NO_WOLFSSL_SERVER)
05111         #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
05112             return wolfSSLv3_server_method();
05113         #elif !defined(WOLFSSL_NO_TLS12)
05114             return wolfTLSv1_2_server_method();
05115         #elif defined(WOLFSSL_TLS13)
05116             return wolfTLSv1_3_server_method();
05117         #endif
05118     #else
05119         return NULL;
05120     #endif
05121 }
05122 
05123 
05124 /* like load verify locations, 1 for success, < 0 for error */
05125 int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm,
05126                                    const unsigned char* in, long sz, int format)
05127 {
05128     int ret = WOLFSSL_FATAL_ERROR;
05129     WOLFSSL_CTX* tmp;
05130 
05131     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCABuffer");
05132 
05133     if (cm == NULL) {
05134         WOLFSSL_MSG("No CertManager error");
05135         return ret;
05136     }
05137     tmp = wolfSSL_CTX_new(cm_pick_method());
05138 
05139     if (tmp == NULL) {
05140         WOLFSSL_MSG("CTX new failed");
05141         return ret;
05142     }
05143 
05144     /* for tmp use */
05145     wolfSSL_CertManagerFree(tmp->cm);
05146     tmp->cm = cm;
05147 
05148     ret = wolfSSL_CTX_load_verify_buffer(tmp, in, sz, format);
05149 
05150     /* don't loose our good one */
05151     tmp->cm = NULL;
05152     wolfSSL_CTX_free(tmp);
05153 
05154     return ret;
05155 }
05156 
05157 #ifdef HAVE_CRL
05158 
05159 int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER* cm,
05160                                    const unsigned char* buff, long sz, int type)
05161 {
05162     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLBuffer");
05163     if (cm == NULL)
05164         return BAD_FUNC_ARG;
05165 
05166     if (cm->crl == NULL) {
05167         if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
05168             WOLFSSL_MSG("Enable CRL failed");
05169             return WOLFSSL_FATAL_ERROR;
05170         }
05171     }
05172 
05173     return BufferLoadCRL(cm->crl, buff, sz, type, 0);
05174 }
05175 
05176 
05177 int wolfSSL_CTX_LoadCRLBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
05178                               long sz, int type)
05179 {
05180     WOLFSSL_ENTER("wolfSSL_CTX_LoadCRLBuffer");
05181 
05182     if (ctx == NULL)
05183         return BAD_FUNC_ARG;
05184 
05185     return wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, buff, sz, type);
05186 }
05187 
05188 
05189 int wolfSSL_LoadCRLBuffer(WOLFSSL* ssl, const unsigned char* buff,
05190                           long sz, int type)
05191 {
05192     WOLFSSL_ENTER("wolfSSL_LoadCRLBuffer");
05193 
05194     if (ssl == NULL || ssl->ctx == NULL)
05195         return BAD_FUNC_ARG;
05196 
05197     return wolfSSL_CertManagerLoadCRLBuffer(ssl->ctx->cm, buff, sz, type);
05198 }
05199 
05200 
05201 #endif /* HAVE_CRL */
05202 
05203 /* turn on CRL if off and compiled in, set options */
05204 int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, int options)
05205 {
05206     int ret = WOLFSSL_SUCCESS;
05207 
05208     (void)options;
05209 
05210     WOLFSSL_ENTER("wolfSSL_CertManagerEnableCRL");
05211     if (cm == NULL)
05212         return BAD_FUNC_ARG;
05213 
05214     #ifdef HAVE_CRL
05215         if (cm->crl == NULL) {
05216             cm->crl = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), cm->heap,
05217                                             DYNAMIC_TYPE_CRL);
05218             if (cm->crl == NULL)
05219                 return MEMORY_E;
05220 
05221             if (InitCRL(cm->crl, cm) != 0) {
05222                 WOLFSSL_MSG("Init CRL failed");
05223                 FreeCRL(cm->crl, 1);
05224                 cm->crl = NULL;
05225                 return WOLFSSL_FAILURE;
05226             }
05227 
05228         #ifdef HAVE_CRL_IO
05229             cm->crl->crlIOCb = EmbedCrlLookup;
05230         #endif
05231         }
05232 
05233         cm->crlEnabled = 1;
05234         if (options & WOLFSSL_CRL_CHECKALL)
05235             cm->crlCheckAll = 1;
05236     #else
05237         ret = NOT_COMPILED_IN;
05238     #endif
05239 
05240     return ret;
05241 }
05242 
05243 
05244 int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER* cm)
05245 {
05246     WOLFSSL_ENTER("wolfSSL_CertManagerDisableCRL");
05247     if (cm == NULL)
05248         return BAD_FUNC_ARG;
05249 
05250     cm->crlEnabled = 0;
05251 
05252     return WOLFSSL_SUCCESS;
05253 }
05254 /* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
05255 int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
05256                                     long sz, int format)
05257 {
05258     int ret = 0;
05259     DerBuffer* der = NULL;
05260 #ifdef WOLFSSL_SMALL_STACK
05261     DecodedCert* cert = NULL;
05262 #else
05263     DecodedCert  cert[1];
05264 #endif
05265 
05266     WOLFSSL_ENTER("wolfSSL_CertManagerVerifyBuffer");
05267 
05268 #ifdef WOLFSSL_SMALL_STACK
05269     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
05270                                  DYNAMIC_TYPE_DCERT);
05271     if (cert == NULL)
05272         return MEMORY_E;
05273 #endif
05274 
05275     if (format == WOLFSSL_FILETYPE_PEM) {
05276 #ifdef WOLFSSL_PEM_TO_DER
05277         ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, NULL, NULL);
05278         if (ret != 0) {
05279             FreeDer(&der);
05280         #ifdef WOLFSSL_SMALL_STACK
05281             XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
05282         #endif
05283             return ret;
05284         }
05285         InitDecodedCert(cert, der->buffer, der->length, cm->heap);
05286 #else
05287         ret = NOT_COMPILED_IN;
05288 #endif
05289     }
05290     else {
05291         InitDecodedCert(cert, (byte*)buff, (word32)sz, cm->heap);
05292     }
05293 
05294     if (ret == 0)
05295         ret = ParseCertRelative(cert, CERT_TYPE, 1, cm);
05296 
05297 #ifdef HAVE_CRL
05298     if (ret == 0 && cm->crlEnabled)
05299         ret = CheckCertCRL(cm->crl, cert);
05300 #endif
05301 
05302     FreeDecodedCert(cert);
05303     FreeDer(&der);
05304 #ifdef WOLFSSL_SMALL_STACK
05305     XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
05306 #endif
05307 
05308     return ret == 0 ? WOLFSSL_SUCCESS : ret;
05309 }
05310 
05311 
05312 /* turn on OCSP if off and compiled in, set options */
05313 int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, int options)
05314 {
05315     int ret = WOLFSSL_SUCCESS;
05316 
05317     (void)options;
05318 
05319     WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSP");
05320     if (cm == NULL)
05321         return BAD_FUNC_ARG;
05322 
05323     #ifdef HAVE_OCSP
05324         if (cm->ocsp == NULL) {
05325             cm->ocsp = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), cm->heap,
05326                                               DYNAMIC_TYPE_OCSP);
05327             if (cm->ocsp == NULL)
05328                 return MEMORY_E;
05329 
05330             if (InitOCSP(cm->ocsp, cm) != 0) {
05331                 WOLFSSL_MSG("Init OCSP failed");
05332                 FreeOCSP(cm->ocsp, 1);
05333                 cm->ocsp = NULL;
05334                 return WOLFSSL_FAILURE;
05335             }
05336         }
05337         cm->ocspEnabled = 1;
05338         if (options & WOLFSSL_OCSP_URL_OVERRIDE)
05339             cm->ocspUseOverrideURL = 1;
05340         if (options & WOLFSSL_OCSP_NO_NONCE)
05341             cm->ocspSendNonce = 0;
05342         else
05343             cm->ocspSendNonce = 1;
05344         if (options & WOLFSSL_OCSP_CHECKALL)
05345             cm->ocspCheckAll = 1;
05346         #ifndef WOLFSSL_USER_IO
05347             cm->ocspIOCb = EmbedOcspLookup;
05348             cm->ocspRespFreeCb = EmbedOcspRespFree;
05349             cm->ocspIOCtx = cm->heap;
05350         #endif /* WOLFSSL_USER_IO */
05351     #else
05352         ret = NOT_COMPILED_IN;
05353     #endif
05354 
05355     return ret;
05356 }
05357 
05358 
05359 int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm)
05360 {
05361     WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSP");
05362     if (cm == NULL)
05363         return BAD_FUNC_ARG;
05364 
05365     cm->ocspEnabled = 0;
05366 
05367     return WOLFSSL_SUCCESS;
05368 }
05369 
05370 /* turn on OCSP Stapling if off and compiled in, set options */
05371 int wolfSSL_CertManagerEnableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
05372 {
05373     int ret = WOLFSSL_SUCCESS;
05374 
05375     WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPStapling");
05376 
05377     if (cm == NULL)
05378         return BAD_FUNC_ARG;
05379 
05380 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
05381  || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
05382     if (cm->ocsp_stapling == NULL) {
05383         cm->ocsp_stapling = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP),
05384                                                cm->heap, DYNAMIC_TYPE_OCSP);
05385         if (cm->ocsp_stapling == NULL)
05386             return MEMORY_E;
05387 
05388         if (InitOCSP(cm->ocsp_stapling, cm) != 0) {
05389             WOLFSSL_MSG("Init OCSP failed");
05390             FreeOCSP(cm->ocsp_stapling, 1);
05391             cm->ocsp_stapling = NULL;
05392             return WOLFSSL_FAILURE;
05393         }
05394     }
05395     cm->ocspStaplingEnabled = 1;
05396 
05397     #ifndef WOLFSSL_USER_IO
05398         cm->ocspIOCb = EmbedOcspLookup;
05399         cm->ocspRespFreeCb = EmbedOcspRespFree;
05400         cm->ocspIOCtx = cm->heap;
05401     #endif /* WOLFSSL_USER_IO */
05402 #else
05403     ret = NOT_COMPILED_IN;
05404 #endif
05405 
05406     return ret;
05407 }
05408 
05409 int wolfSSL_CertManagerDisableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
05410 {
05411     int ret = WOLFSSL_SUCCESS;
05412 
05413     WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSPStapling");
05414 
05415     if (cm == NULL)
05416         return BAD_FUNC_ARG;
05417 
05418 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
05419  || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
05420     cm->ocspStaplingEnabled = 0;
05421 #else
05422     ret = NOT_COMPILED_IN;
05423 #endif
05424     return ret;
05425 }
05426 #if defined(SESSION_CERTS)
05427 WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL* ssl)
05428 {
05429     WOLFSSL_ENTER("wolfSSL_get_peer_cert_chain");
05430     if ((ssl == NULL) || (ssl->session.chain.count == 0))
05431         return NULL;
05432     else
05433         return (WOLF_STACK_OF(WOLFSSL_X509)* )&ssl->session.chain;
05434 }
05435 #endif
05436 #ifdef HAVE_OCSP
05437 
05438 /* check CRL if enabled, WOLFSSL_SUCCESS  */
05439 int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
05440 {
05441     int ret;
05442 #ifdef WOLFSSL_SMALL_STACK
05443     DecodedCert* cert = NULL;
05444 #else
05445     DecodedCert  cert[1];
05446 #endif
05447 
05448     WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSP");
05449 
05450     if (cm == NULL)
05451         return BAD_FUNC_ARG;
05452 
05453     if (cm->ocspEnabled == 0)
05454         return WOLFSSL_SUCCESS;
05455 
05456 #ifdef WOLFSSL_SMALL_STACK
05457     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
05458     if (cert == NULL)
05459         return MEMORY_E;
05460 #endif
05461 
05462     InitDecodedCert(cert, der, sz, NULL);
05463 
05464     if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm)) != 0) {
05465         WOLFSSL_MSG("ParseCert failed");
05466     }
05467     else if ((ret = CheckCertOCSP(cm->ocsp, cert, NULL)) != 0) {
05468         WOLFSSL_MSG("CheckCertOCSP failed");
05469     }
05470 
05471     FreeDecodedCert(cert);
05472 #ifdef WOLFSSL_SMALL_STACK
05473     XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
05474 #endif
05475 
05476     return ret == 0 ? WOLFSSL_SUCCESS : ret;
05477 }
05478 
05479 
05480 int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER* cm,
05481                                           const char* url)
05482 {
05483     WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSPOverrideURL");
05484     if (cm == NULL)
05485         return BAD_FUNC_ARG;
05486 
05487     XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
05488     if (url != NULL) {
05489         int urlSz = (int)XSTRLEN(url) + 1;
05490         cm->ocspOverrideURL = (char*)XMALLOC(urlSz, cm->heap, DYNAMIC_TYPE_URL);
05491         if (cm->ocspOverrideURL != NULL) {
05492             XMEMCPY(cm->ocspOverrideURL, url, urlSz);
05493         }
05494         else
05495             return MEMORY_E;
05496     }
05497     else
05498         cm->ocspOverrideURL = NULL;
05499 
05500     return WOLFSSL_SUCCESS;
05501 }
05502 
05503 
05504 int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER* cm,
05505                         CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
05506 {
05507     WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSP_Cb");
05508     if (cm == NULL)
05509         return BAD_FUNC_ARG;
05510 
05511     cm->ocspIOCb = ioCb;
05512     cm->ocspRespFreeCb = respFreeCb;
05513     cm->ocspIOCtx = ioCbCtx;
05514 
05515     return WOLFSSL_SUCCESS;
05516 }
05517 
05518 
05519 int wolfSSL_EnableOCSP(WOLFSSL* ssl, int options)
05520 {
05521     WOLFSSL_ENTER("wolfSSL_EnableOCSP");
05522     if (ssl)
05523         return wolfSSL_CertManagerEnableOCSP(ssl->ctx->cm, options);
05524     else
05525         return BAD_FUNC_ARG;
05526 }
05527 
05528 int wolfSSL_DisableOCSP(WOLFSSL* ssl)
05529 {
05530     WOLFSSL_ENTER("wolfSSL_DisableOCSP");
05531     if (ssl)
05532         return wolfSSL_CertManagerDisableOCSP(ssl->ctx->cm);
05533     else
05534         return BAD_FUNC_ARG;
05535 }
05536 
05537 
05538 int wolfSSL_EnableOCSPStapling(WOLFSSL* ssl)
05539 {
05540     WOLFSSL_ENTER("wolfSSL_EnableOCSPStapling");
05541     if (ssl)
05542         return wolfSSL_CertManagerEnableOCSPStapling(ssl->ctx->cm);
05543     else
05544         return BAD_FUNC_ARG;
05545 }
05546 
05547 int wolfSSL_DisableOCSPStapling(WOLFSSL* ssl)
05548 {
05549     WOLFSSL_ENTER("wolfSSL_DisableOCSPStapling");
05550     if (ssl)
05551         return wolfSSL_CertManagerDisableOCSPStapling(ssl->ctx->cm);
05552     else
05553         return BAD_FUNC_ARG;
05554 }
05555 
05556 int wolfSSL_SetOCSP_OverrideURL(WOLFSSL* ssl, const char* url)
05557 {
05558     WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
05559     if (ssl)
05560         return wolfSSL_CertManagerSetOCSPOverrideURL(ssl->ctx->cm, url);
05561     else
05562         return BAD_FUNC_ARG;
05563 }
05564 
05565 
05566 int wolfSSL_SetOCSP_Cb(WOLFSSL* ssl,
05567                         CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
05568 {
05569     WOLFSSL_ENTER("wolfSSL_SetOCSP_Cb");
05570     if (ssl) {
05571         ssl->ocspIOCtx = ioCbCtx; /* use SSL specific ioCbCtx */
05572         return wolfSSL_CertManagerSetOCSP_Cb(ssl->ctx->cm,
05573                                              ioCb, respFreeCb, NULL);
05574     }
05575     else
05576         return BAD_FUNC_ARG;
05577 }
05578 
05579 
05580 int wolfSSL_CTX_EnableOCSP(WOLFSSL_CTX* ctx, int options)
05581 {
05582     WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSP");
05583     if (ctx)
05584         return wolfSSL_CertManagerEnableOCSP(ctx->cm, options);
05585     else
05586         return BAD_FUNC_ARG;
05587 }
05588 
05589 
05590 int wolfSSL_CTX_DisableOCSP(WOLFSSL_CTX* ctx)
05591 {
05592     WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSP");
05593     if (ctx)
05594         return wolfSSL_CertManagerDisableOCSP(ctx->cm);
05595     else
05596         return BAD_FUNC_ARG;
05597 }
05598 
05599 
05600 int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX* ctx, const char* url)
05601 {
05602     WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
05603     if (ctx)
05604         return wolfSSL_CertManagerSetOCSPOverrideURL(ctx->cm, url);
05605     else
05606         return BAD_FUNC_ARG;
05607 }
05608 
05609 
05610 int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX* ctx, CbOCSPIO ioCb,
05611                            CbOCSPRespFree respFreeCb, void* ioCbCtx)
05612 {
05613     WOLFSSL_ENTER("wolfSSL_CTX_SetOCSP_Cb");
05614     if (ctx)
05615         return wolfSSL_CertManagerSetOCSP_Cb(ctx->cm, ioCb,
05616                                              respFreeCb, ioCbCtx);
05617     else
05618         return BAD_FUNC_ARG;
05619 }
05620 
05621 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
05622  || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
05623 int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX* ctx)
05624 {
05625     WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPStapling");
05626     if (ctx)
05627         return wolfSSL_CertManagerEnableOCSPStapling(ctx->cm);
05628     else
05629         return BAD_FUNC_ARG;
05630 }
05631 
05632 int wolfSSL_CTX_DisableOCSPStapling(WOLFSSL_CTX* ctx)
05633 {
05634     WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSPStapling");
05635     if (ctx)
05636         return wolfSSL_CertManagerDisableOCSPStapling(ctx->cm);
05637     else
05638         return BAD_FUNC_ARG;
05639 }
05640 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST || HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
05641 
05642 #endif /* HAVE_OCSP */
05643 
05644 
05645 #ifndef NO_FILESYSTEM
05646 
05647 /* process a file with name fname into ctx of format and type
05648    userChain specifies a user certificate chain to pass during handshake */
05649 int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type,
05650                 WOLFSSL* ssl, int userChain, WOLFSSL_CRL* crl)
05651 {
05652 #ifdef WOLFSSL_SMALL_STACK
05653     byte   staticBuffer[1]; /* force heap usage */
05654 #else
05655     byte   staticBuffer[FILE_BUFFER_SIZE];
05656 #endif
05657     byte*  myBuffer = staticBuffer;
05658     int    dynamic = 0;
05659     int    ret;
05660     long   sz = 0;
05661     XFILE  file;
05662     void*  heapHint = wolfSSL_CTX_GetHeap(ctx, ssl);
05663 
05664     (void)crl;
05665     (void)heapHint;
05666 
05667     if (fname == NULL) return WOLFSSL_BAD_FILE;
05668 
05669     file = XFOPEN(fname, "rb");
05670     if (file == XBADFILE) return WOLFSSL_BAD_FILE;
05671     XFSEEK(file, 0, XSEEK_END);
05672     sz = XFTELL(file);
05673     XREWIND(file);
05674 
05675     if (sz > (long)sizeof(staticBuffer)) {
05676         WOLFSSL_MSG("Getting dynamic buffer");
05677         myBuffer = (byte*)XMALLOC(sz, heapHint, DYNAMIC_TYPE_FILE);
05678         if (myBuffer == NULL) {
05679             XFCLOSE(file);
05680             return WOLFSSL_BAD_FILE;
05681         }
05682         dynamic = 1;
05683     }
05684     else if (sz <= 0) {
05685         XFCLOSE(file);
05686         return WOLFSSL_BAD_FILE;
05687     }
05688 
05689     if ( (ret = (int)XFREAD(myBuffer, 1, sz, file)) != sz)
05690         ret = WOLFSSL_BAD_FILE;
05691     else {
05692         if ((type == CA_TYPE || type == TRUSTED_PEER_TYPE)
05693                                                   && format == WOLFSSL_FILETYPE_PEM)
05694             ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl);
05695 #ifdef HAVE_CRL
05696         else if (type == CRL_TYPE)
05697             ret = BufferLoadCRL(crl, myBuffer, sz, format, 0);
05698 #endif
05699         else
05700             ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL,
05701                                 userChain);
05702     }
05703 
05704     XFCLOSE(file);
05705     if (dynamic)
05706         XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
05707 
05708     return ret;
05709 }
05710 
05711 
05712 /* loads file then loads each file in path, no c_rehash */
05713 int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
05714                                      const char* path)
05715 {
05716     int ret = WOLFSSL_SUCCESS;
05717 #ifndef NO_WOLFSSL_DIR
05718     int fileRet;
05719 #endif
05720 
05721     WOLFSSL_ENTER("wolfSSL_CTX_load_verify_locations");
05722 
05723     if (ctx == NULL || (file == NULL && path == NULL) )
05724         return WOLFSSL_FAILURE;
05725 
05726     if (file)
05727         ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, CA_TYPE, NULL, 0, NULL);
05728 
05729     if (ret == WOLFSSL_SUCCESS && path) {
05730 #ifndef NO_WOLFSSL_DIR
05731         char* name = NULL;
05732     #ifdef WOLFSSL_SMALL_STACK
05733         ReadDirCtx* readCtx = NULL;
05734         readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), ctx->heap,
05735                                                        DYNAMIC_TYPE_DIRCTX);
05736         if (readCtx == NULL)
05737             return MEMORY_E;
05738     #else
05739         ReadDirCtx readCtx[1];
05740     #endif
05741 
05742         /* try to load each regular file in path */
05743         fileRet = wc_ReadDirFirst(readCtx, path, &name);
05744         while (fileRet == 0 && name) {
05745             ret = ProcessFile(ctx, name, WOLFSSL_FILETYPE_PEM, CA_TYPE,
05746                                                           NULL, 0, NULL);
05747             if (ret != WOLFSSL_SUCCESS)
05748                 break;
05749             fileRet = wc_ReadDirNext(readCtx, path, &name);
05750         }
05751         wc_ReadDirClose(readCtx);
05752 
05753         /* pass directory read failure to response code */
05754         if (ret == WOLFSSL_SUCCESS && fileRet != -1) {
05755             ret = fileRet;
05756         }
05757 
05758     #ifdef WOLFSSL_SMALL_STACK
05759         XFREE(readCtx, ctx->heap, DYNAMIC_TYPE_DIRCTX);
05760     #endif
05761 #else
05762         ret = NOT_COMPILED_IN;
05763 #endif
05764     }
05765 
05766     return ret;
05767 }
05768 
05769 
05770 #ifdef WOLFSSL_TRUST_PEER_CERT
05771 /* Used to specify a peer cert to match when connecting
05772     ctx : the ctx structure to load in peer cert
05773     file: the string name of cert file
05774     type: type of format such as PEM/DER
05775  */
05776 int wolfSSL_CTX_trust_peer_cert(WOLFSSL_CTX* ctx, const char* file, int type)
05777 {
05778     WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_cert");
05779 
05780     if (ctx == NULL || file == NULL) {
05781         return WOLFSSL_FAILURE;
05782     }
05783 
05784     return ProcessFile(ctx, file, type, TRUSTED_PEER_TYPE, NULL, 0, NULL);
05785 }
05786 #endif /* WOLFSSL_TRUST_PEER_CERT */
05787 
05788 
05789 /* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
05790 int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* fname,
05791                              int format)
05792 {
05793     int    ret = WOLFSSL_FATAL_ERROR;
05794 #ifdef WOLFSSL_SMALL_STACK
05795     byte   staticBuffer[1]; /* force heap usage */
05796 #else
05797     byte   staticBuffer[FILE_BUFFER_SIZE];
05798 #endif
05799     byte*  myBuffer = staticBuffer;
05800     int    dynamic = 0;
05801     long   sz = 0;
05802     XFILE  file = XFOPEN(fname, "rb");
05803 
05804     WOLFSSL_ENTER("wolfSSL_CertManagerVerify");
05805 
05806     if (file == XBADFILE) return WOLFSSL_BAD_FILE;
05807     XFSEEK(file, 0, XSEEK_END);
05808     sz = XFTELL(file);
05809     XREWIND(file);
05810 
05811     if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
05812         WOLFSSL_MSG("CertManagerVerify file bad size");
05813         XFCLOSE(file);
05814         return WOLFSSL_BAD_FILE;
05815     }
05816 
05817     if (sz > (long)sizeof(staticBuffer)) {
05818         WOLFSSL_MSG("Getting dynamic buffer");
05819         myBuffer = (byte*) XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE);
05820         if (myBuffer == NULL) {
05821             XFCLOSE(file);
05822             return WOLFSSL_BAD_FILE;
05823         }
05824         dynamic = 1;
05825     }
05826 
05827     if ( (ret = (int)XFREAD(myBuffer, 1, sz, file)) != sz)
05828         ret = WOLFSSL_BAD_FILE;
05829     else
05830         ret = wolfSSL_CertManagerVerifyBuffer(cm, myBuffer, sz, format);
05831 
05832     XFCLOSE(file);
05833     if (dynamic)
05834         XFREE(myBuffer, cm->heap, DYNAMIC_TYPE_FILE);
05835 
05836     return ret;
05837 }
05838 
05839 
05840 /* like load verify locations, 1 for success, < 0 for error */
05841 int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* file,
05842                              const char* path)
05843 {
05844     int ret = WOLFSSL_FATAL_ERROR;
05845     WOLFSSL_CTX* tmp;
05846 
05847     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCA");
05848 
05849     if (cm == NULL) {
05850         WOLFSSL_MSG("No CertManager error");
05851         return ret;
05852     }
05853     tmp = wolfSSL_CTX_new(cm_pick_method());
05854 
05855     if (tmp == NULL) {
05856         WOLFSSL_MSG("CTX new failed");
05857         return ret;
05858     }
05859 
05860     /* for tmp use */
05861     wolfSSL_CertManagerFree(tmp->cm);
05862     tmp->cm = cm;
05863 
05864     ret = wolfSSL_CTX_load_verify_locations(tmp, file, path);
05865 
05866     /* don't loose our good one */
05867     tmp->cm = NULL;
05868     wolfSSL_CTX_free(tmp);
05869 
05870     return ret;
05871 }
05872 
05873 
05874 /* Check private against public in certificate for match
05875  *
05876  * ctx  WOLFSSL_CTX structure to check private key in
05877  *
05878  * Returns SSL_SUCCESS on good private key and SSL_FAILURE if miss matched. */
05879 int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx)
05880 {
05881 #ifdef WOLFSSL_SMALL_STACK
05882     DecodedCert* der = NULL;
05883 #else
05884     DecodedCert  der[1];
05885 #endif
05886     word32 size;
05887     byte*  buff;
05888     int    ret;
05889 
05890     WOLFSSL_ENTER("wolfSSL_CTX_check_private_key");
05891 
05892     if (ctx == NULL) {
05893         return WOLFSSL_FAILURE;
05894     }
05895 
05896 #ifndef NO_CERTS
05897 #ifdef WOLFSSL_SMALL_STACK
05898     der = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
05899     if (der == NULL)
05900         return MEMORY_E;
05901 #endif
05902 
05903     size = ctx->certificate->length;
05904     buff = ctx->certificate->buffer;
05905     InitDecodedCert(der, buff, size, ctx->heap);
05906     if (ParseCertRelative(der, CERT_TYPE, NO_VERIFY, NULL) != 0) {
05907         FreeDecodedCert(der);
05908     #ifdef WOLFSSL_SMALL_STACK
05909         XFREE(der, NULL, DYNAMIC_TYPE_DCERT);
05910     #endif
05911         return WOLFSSL_FAILURE;
05912     }
05913 
05914     size = ctx->privateKey->length;
05915     buff = ctx->privateKey->buffer;
05916     ret  = wc_CheckPrivateKey(buff, size, der);
05917     FreeDecodedCert(der);
05918 #ifdef WOLFSSL_SMALL_STACK
05919     XFREE(der, NULL, DYNAMIC_TYPE_DCERT);
05920 #endif
05921 
05922     if (ret == 1) {
05923         return WOLFSSL_SUCCESS;
05924     }
05925     else {
05926         return WOLFSSL_FAILURE;
05927     }
05928 #else
05929     WOLFSSL_MSG("NO_CERTS is defined, can not check private key");
05930     return WOLFSSL_FAILURE;
05931 #endif
05932 }
05933 
05934 #ifdef HAVE_CRL
05935 
05936 
05937 /* check CRL if enabled, WOLFSSL_SUCCESS  */
05938 int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
05939 {
05940     int ret = 0;
05941 #ifdef WOLFSSL_SMALL_STACK
05942     DecodedCert* cert = NULL;
05943 #else
05944     DecodedCert  cert[1];
05945 #endif
05946 
05947     WOLFSSL_ENTER("wolfSSL_CertManagerCheckCRL");
05948 
05949     if (cm == NULL)
05950         return BAD_FUNC_ARG;
05951 
05952     if (cm->crlEnabled == 0)
05953         return WOLFSSL_SUCCESS;
05954 
05955 #ifdef WOLFSSL_SMALL_STACK
05956     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
05957     if (cert == NULL)
05958         return MEMORY_E;
05959 #endif
05960 
05961     InitDecodedCert(cert, der, sz, NULL);
05962 
05963     if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_CRL, cm)) != 0) {
05964         WOLFSSL_MSG("ParseCert failed");
05965     }
05966     else if ((ret = CheckCertCRL(cm->crl, cert)) != 0) {
05967         WOLFSSL_MSG("CheckCertCRL failed");
05968     }
05969 
05970     FreeDecodedCert(cert);
05971 #ifdef WOLFSSL_SMALL_STACK
05972     XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
05973 #endif
05974 
05975     return ret == 0 ? WOLFSSL_SUCCESS : ret;
05976 }
05977 
05978 
05979 int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, CbMissingCRL cb)
05980 {
05981     WOLFSSL_ENTER("wolfSSL_CertManagerSetCRL_Cb");
05982     if (cm == NULL)
05983         return BAD_FUNC_ARG;
05984 
05985     cm->cbMissingCRL = cb;
05986 
05987     return WOLFSSL_SUCCESS;
05988 }
05989 
05990 #ifdef HAVE_CRL_IO
05991 int wolfSSL_CertManagerSetCRL_IOCb(WOLFSSL_CERT_MANAGER* cm, CbCrlIO cb)
05992 {
05993     if (cm == NULL)
05994         return BAD_FUNC_ARG;
05995 
05996     cm->crl->crlIOCb = cb;
05997 
05998     return WOLFSSL_SUCCESS;
05999 }
06000 #endif
06001 
06002 int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER* cm, const char* path,
06003                               int type, int monitor)
06004 {
06005     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRL");
06006     if (cm == NULL)
06007         return BAD_FUNC_ARG;
06008 
06009     if (cm->crl == NULL) {
06010         if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
06011             WOLFSSL_MSG("Enable CRL failed");
06012             return WOLFSSL_FATAL_ERROR;
06013         }
06014     }
06015 
06016     return LoadCRL(cm->crl, path, type, monitor);
06017 }
06018 
06019 
06020 int wolfSSL_EnableCRL(WOLFSSL* ssl, int options)
06021 {
06022     WOLFSSL_ENTER("wolfSSL_EnableCRL");
06023     if (ssl)
06024         return wolfSSL_CertManagerEnableCRL(ssl->ctx->cm, options);
06025     else
06026         return BAD_FUNC_ARG;
06027 }
06028 
06029 
06030 int wolfSSL_DisableCRL(WOLFSSL* ssl)
06031 {
06032     WOLFSSL_ENTER("wolfSSL_DisableCRL");
06033     if (ssl)
06034         return wolfSSL_CertManagerDisableCRL(ssl->ctx->cm);
06035     else
06036         return BAD_FUNC_ARG;
06037 }
06038 
06039 
06040 int wolfSSL_LoadCRL(WOLFSSL* ssl, const char* path, int type, int monitor)
06041 {
06042     WOLFSSL_ENTER("wolfSSL_LoadCRL");
06043     if (ssl)
06044         return wolfSSL_CertManagerLoadCRL(ssl->ctx->cm, path, type, monitor);
06045     else
06046         return BAD_FUNC_ARG;
06047 }
06048 
06049 
06050 int wolfSSL_SetCRL_Cb(WOLFSSL* ssl, CbMissingCRL cb)
06051 {
06052     WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
06053     if (ssl)
06054         return wolfSSL_CertManagerSetCRL_Cb(ssl->ctx->cm, cb);
06055     else
06056         return BAD_FUNC_ARG;
06057 }
06058 
06059 #ifdef HAVE_CRL_IO
06060 int wolfSSL_SetCRL_IOCb(WOLFSSL* ssl, CbCrlIO cb)
06061 {
06062     WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
06063     if (ssl)
06064         return wolfSSL_CertManagerSetCRL_IOCb(ssl->ctx->cm, cb);
06065     else
06066         return BAD_FUNC_ARG;
06067 }
06068 #endif
06069 
06070 int wolfSSL_CTX_EnableCRL(WOLFSSL_CTX* ctx, int options)
06071 {
06072     WOLFSSL_ENTER("wolfSSL_CTX_EnableCRL");
06073     if (ctx)
06074         return wolfSSL_CertManagerEnableCRL(ctx->cm, options);
06075     else
06076         return BAD_FUNC_ARG;
06077 }
06078 
06079 
06080 int wolfSSL_CTX_DisableCRL(WOLFSSL_CTX* ctx)
06081 {
06082     WOLFSSL_ENTER("wolfSSL_CTX_DisableCRL");
06083     if (ctx)
06084         return wolfSSL_CertManagerDisableCRL(ctx->cm);
06085     else
06086         return BAD_FUNC_ARG;
06087 }
06088 
06089 
06090 int wolfSSL_CTX_LoadCRL(WOLFSSL_CTX* ctx, const char* path,
06091                         int type, int monitor)
06092 {
06093     WOLFSSL_ENTER("wolfSSL_CTX_LoadCRL");
06094     if (ctx)
06095         return wolfSSL_CertManagerLoadCRL(ctx->cm, path, type, monitor);
06096     else
06097         return BAD_FUNC_ARG;
06098 }
06099 
06100 
06101 int wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX* ctx, CbMissingCRL cb)
06102 {
06103     WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_Cb");
06104     if (ctx)
06105         return wolfSSL_CertManagerSetCRL_Cb(ctx->cm, cb);
06106     else
06107         return BAD_FUNC_ARG;
06108 }
06109 
06110 #ifdef HAVE_CRL_IO
06111 int wolfSSL_CTX_SetCRL_IOCb(WOLFSSL_CTX* ctx, CbCrlIO cb)
06112 {
06113     WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_IOCb");
06114     if (ctx)
06115         return wolfSSL_CertManagerSetCRL_IOCb(ctx->cm, cb);
06116     else
06117         return BAD_FUNC_ARG;
06118 }
06119 #endif
06120 
06121 
06122 #endif /* HAVE_CRL */
06123 
06124 
06125 #ifdef WOLFSSL_DER_LOAD
06126 
06127 /* Add format parameter to allow DER load of CA files */
06128 int wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
06129                                           int format)
06130 {
06131     WOLFSSL_ENTER("wolfSSL_CTX_der_load_verify_locations");
06132     if (ctx == NULL || file == NULL)
06133         return WOLFSSL_FAILURE;
06134 
06135     if (ProcessFile(ctx, file, format, CA_TYPE, NULL, 0, NULL) == WOLFSSL_SUCCESS)
06136         return WOLFSSL_SUCCESS;
06137 
06138     return WOLFSSL_FAILURE;
06139 }
06140 
06141 #endif /* WOLFSSL_DER_LOAD */
06142 
06143 
06144 
06145 int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
06146                                      int format)
06147 {
06148     WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_file");
06149     if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL) == WOLFSSL_SUCCESS)
06150         return WOLFSSL_SUCCESS;
06151 
06152     return WOLFSSL_FAILURE;
06153 }
06154 
06155 
06156 int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX* ctx, const char* file,
06157                                     int format)
06158 {
06159     WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_file");
06160     if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL)
06161                     == WOLFSSL_SUCCESS)
06162         return WOLFSSL_SUCCESS;
06163 
06164     return WOLFSSL_FAILURE;
06165 }
06166 
06167 
06168 /* Sets the max chain depth when verifying a certificate chain. Default depth
06169  * is set to MAX_CHAIN_DEPTH.
06170  *
06171  * ctx   WOLFSSL_CTX structure to set depth in
06172  * depth max depth
06173  */
06174 void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx, int depth) {
06175     WOLFSSL_ENTER("wolfSSL_CTX_set_verify_depth");
06176 
06177     if (ctx == NULL || depth < 0 || depth > MAX_CHAIN_DEPTH) {
06178         WOLFSSL_MSG("Bad depth argument, too large or less than 0");
06179         return;
06180     }
06181 
06182     ctx->verifyDepth = (byte)depth;
06183 }
06184 
06185 
06186 /* get cert chaining depth using ssl struct */
06187 long wolfSSL_get_verify_depth(WOLFSSL* ssl)
06188 {
06189     if(ssl == NULL) {
06190         return BAD_FUNC_ARG;
06191     }
06192 #ifndef OPENSSL_EXTRA
06193     return MAX_CHAIN_DEPTH;
06194 #else
06195     return ssl->options.verifyDepth;
06196 #endif
06197 }
06198 
06199 
06200 /* get cert chaining depth using ctx struct */
06201 long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx)
06202 {
06203     if(ctx == NULL) {
06204         return BAD_FUNC_ARG;
06205     }
06206 #ifndef OPENSSL_EXTRA
06207     return MAX_CHAIN_DEPTH;
06208 #else
06209     return ctx->verifyDepth;
06210 #endif
06211 }
06212 
06213 
06214 int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX* ctx, const char* file)
06215 {
06216    /* process up to MAX_CHAIN_DEPTH plus subject cert */
06217    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file");
06218    if (ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM,CERT_TYPE,NULL,1, NULL)
06219                    == WOLFSSL_SUCCESS)
06220        return WOLFSSL_SUCCESS;
06221 
06222    return WOLFSSL_FAILURE;
06223 }
06224 
06225 
06226 int wolfSSL_CTX_use_certificate_chain_file_format(WOLFSSL_CTX* ctx,
06227                                                   const char* file, int format)
06228 {
06229    /* process up to MAX_CHAIN_DEPTH plus subject cert */
06230    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file_format");
06231    if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 1, NULL)
06232                    == WOLFSSL_SUCCESS)
06233        return WOLFSSL_SUCCESS;
06234 
06235    return WOLFSSL_FAILURE;
06236 }
06237 
06238 
06239 #ifndef NO_DH
06240 
06241 /* server Diffie-Hellman parameters */
06242 static int wolfSSL_SetTmpDH_file_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
06243                                         const char* fname, int format)
06244 {
06245 #ifdef WOLFSSL_SMALL_STACK
06246     byte   staticBuffer[1]; /* force heap usage */
06247 #else
06248     byte   staticBuffer[FILE_BUFFER_SIZE];
06249 #endif
06250     byte*  myBuffer = staticBuffer;
06251     int    dynamic = 0;
06252     int    ret;
06253     long   sz = 0;
06254     XFILE  file;
06255 
06256     if (ctx == NULL || fname == NULL)
06257         return BAD_FUNC_ARG;
06258 
06259     file = XFOPEN(fname, "rb");
06260     if (file == XBADFILE) return WOLFSSL_BAD_FILE;
06261     XFSEEK(file, 0, XSEEK_END);
06262     sz = XFTELL(file);
06263     XREWIND(file);
06264 
06265     if (sz > (long)sizeof(staticBuffer)) {
06266         WOLFSSL_MSG("Getting dynamic buffer");
06267         myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
06268         if (myBuffer == NULL) {
06269             XFCLOSE(file);
06270             return WOLFSSL_BAD_FILE;
06271         }
06272         dynamic = 1;
06273     }
06274     else if (sz <= 0) {
06275         XFCLOSE(file);
06276         return WOLFSSL_BAD_FILE;
06277     }
06278 
06279     if ( (ret = (int)XFREAD(myBuffer, 1, sz, file)) != sz)
06280         ret = WOLFSSL_BAD_FILE;
06281     else {
06282         if (ssl)
06283             ret = wolfSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format);
06284         else
06285             ret = wolfSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format);
06286     }
06287 
06288     XFCLOSE(file);
06289     if (dynamic)
06290         XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
06291 
06292     return ret;
06293 }
06294 
06295 /* server Diffie-Hellman parameters */
06296 int wolfSSL_SetTmpDH_file(WOLFSSL* ssl, const char* fname, int format)
06297 {
06298     if (ssl == NULL)
06299         return BAD_FUNC_ARG;
06300 
06301     return wolfSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format);
06302 }
06303 
06304 
06305 /* server Diffie-Hellman parameters */
06306 int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format)
06307 {
06308     return wolfSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format);
06309 }
06310 
06311 #endif /* NO_DH */
06312 
06313 #endif /* NO_FILESYSTEM */
06314 
06315 
06316 #if defined(OPENSSL_EXTRA) || !defined(NO_PWDBASED) && \
06317     (defined(OPENSSL_EXTRA_X509_SMALL) || defined(HAVE_WEBSERVER))
06318 
06319 static int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp,
06320     int* pHash, int* pHashSz)
06321 {
06322     enum wc_HashType hash = WC_HASH_TYPE_NONE;
06323     int hashSz;
06324 
06325     if (XSTRLEN(evp) < 3) {
06326         /* do not try comparing strings if size is too small */
06327         return WOLFSSL_FAILURE;
06328     }
06329 
06330     if (XSTRNCMP("SHA", evp, 3) == 0) {
06331         if (XSTRLEN(evp) > 3) {
06332         #ifndef NO_SHA256
06333             if (XSTRNCMP("SHA256", evp, 6) == 0) {
06334                 hash = WC_HASH_TYPE_SHA256;
06335             }
06336             else
06337         #endif
06338         #ifdef WOLFSSL_SHA384
06339             if (XSTRNCMP("SHA384", evp, 6) == 0) {
06340                 hash = WC_HASH_TYPE_SHA384;
06341             }
06342             else
06343         #endif
06344         #ifdef WOLFSSL_SHA512
06345             if (XSTRNCMP("SHA512", evp, 6) == 0) {
06346                 hash = WC_HASH_TYPE_SHA512;
06347             }
06348             else
06349         #endif
06350             {
06351                 WOLFSSL_MSG("Unknown SHA hash");
06352             }
06353         }
06354         else {
06355             hash = WC_HASH_TYPE_SHA;
06356         }
06357     }
06358 #ifdef WOLFSSL_MD2
06359     else if (XSTRNCMP("MD2", evp, 3) == 0) {
06360         hash = WC_HASH_TYPE_MD2;
06361     }
06362 #endif
06363 #ifndef NO_MD4
06364     else if (XSTRNCMP("MD4", evp, 3) == 0) {
06365         hash = WC_HASH_TYPE_MD4;
06366     }
06367 #endif
06368 #ifndef NO_MD5
06369     else if (XSTRNCMP("MD5", evp, 3) == 0) {
06370         hash = WC_HASH_TYPE_MD5;
06371     }
06372 #endif
06373 
06374     if (pHash)
06375         *pHash = hash;
06376 
06377     hashSz = wc_HashGetDigestSize(hash);
06378     if (pHashSz)
06379         *pHashSz = hashSz;
06380 
06381     if (hashSz < 0) {
06382         return WOLFSSL_FAILURE;
06383     }
06384 
06385     return WOLFSSL_SUCCESS;
06386 }
06387 
06388 #endif
06389 
06390 
06391 #ifdef OPENSSL_EXTRA
06392 /* put SSL type in extra for now, not very common */
06393 
06394 /* Converts a DER format key read from "bio" to a PKCS8 structure.
06395  *
06396  * bio  input bio to read DER from
06397  * pkey If not NULL then this pointer will be overwritten with a new PKCS8
06398  *      structure.
06399  *
06400  * returns a WOLFSSL_PKCS8_PRIV_KEY_INFO pointer on success and NULL in fail
06401  *         case.
06402  */
06403 WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY_bio(WOLFSSL_BIO* bio,
06404         WOLFSSL_PKCS8_PRIV_KEY_INFO** pkey)
06405 {
06406     WOLFSSL_PKCS8_PRIV_KEY_INFO* pkcs8 = NULL;
06407 #ifdef WOLFSSL_PEM_TO_DER
06408     unsigned char* mem;
06409     int memSz;
06410     int keySz;
06411 
06412     WOLFSSL_MSG("wolfSSL_d2i_PKCS8_PKEY_bio()");
06413 
06414     if (bio == NULL) {
06415         return NULL;
06416     }
06417 
06418     if ((memSz = wolfSSL_BIO_get_mem_data(bio, &mem)) < 0) {
06419         return NULL;
06420     }
06421 
06422     if ((keySz = wc_KeyPemToDer(mem, memSz, mem, memSz, NULL)) < 0) {
06423         WOLFSSL_MSG("Not PEM format");
06424         keySz = memSz;
06425         if ((keySz = ToTraditional((byte*)mem, (word32)keySz)) < 0) {
06426             return NULL;
06427         }
06428     }
06429 
06430     pkcs8 = wolfSSL_PKEY_new();
06431     if (pkcs8 == NULL) {
06432         return NULL;
06433     }
06434 
06435     pkcs8->pkey.ptr = (char*)XMALLOC(keySz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
06436     if (pkcs8->pkey.ptr == NULL) {
06437         wolfSSL_EVP_PKEY_free(pkcs8);
06438         return NULL;
06439     }
06440     XMEMCPY(pkcs8->pkey.ptr, mem, keySz);
06441     pkcs8->pkey_sz = keySz;
06442 
06443     if (pkey != NULL) {
06444         *pkey = pkcs8;
06445     }
06446 #else
06447     (void)bio;
06448     (void)pkey;
06449 #endif /* WOLFSSL_PEM_TO_DER */
06450 
06451     return pkcs8;
06452 }
06453 
06454 
06455 /* expecting DER format public key
06456  *
06457  * bio  input bio to read DER from
06458  * out  If not NULL then this pointer will be overwritten with a new
06459  * WOLFSSL_EVP_PKEY pointer
06460  *
06461  * returns a WOLFSSL_EVP_PKEY pointer on success and NULL in fail case.
06462  */
06463 WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY_bio(WOLFSSL_BIO* bio,
06464                                          WOLFSSL_EVP_PKEY** out)
06465 {
06466     unsigned char* mem;
06467     long memSz;
06468     WOLFSSL_EVP_PKEY* pkey = NULL;
06469 
06470     WOLFSSL_ENTER("wolfSSL_d2i_PUBKEY_bio()");
06471 
06472     if (bio == NULL) {
06473         return NULL;
06474     }
06475     (void)out;
06476 
06477     memSz = wolfSSL_BIO_pending(bio);
06478     if (memSz <= 0) {
06479         return NULL;
06480     }
06481 
06482     mem = (unsigned char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
06483     if (mem == NULL) {
06484         return NULL;
06485     }
06486 
06487     if (wolfSSL_BIO_read(bio, mem, (int)memSz) == memSz) {
06488         pkey = wolfSSL_d2i_PUBKEY(NULL, &mem, memSz);
06489         if (out != NULL && pkey != NULL) {
06490             *out = pkey;
06491         }
06492     }
06493 
06494     XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
06495     return pkey;
06496 }
06497 
06498 
06499 
06500 /* Converts a DER encoded public key to a WOLFSSL_EVP_PKEY structure.
06501  *
06502  * out  pointer to new WOLFSSL_EVP_PKEY structure. Can be NULL
06503  * in   DER buffer to convert
06504  * inSz size of in buffer
06505  *
06506  * returns a pointer to a new WOLFSSL_EVP_PKEY structure on success and NULL
06507  *         on fail
06508  */
06509 WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** out, unsigned char** in,
06510         long inSz)
06511 {
06512     WOLFSSL_EVP_PKEY* pkey = NULL;
06513     const unsigned char* mem;
06514     long memSz = inSz;
06515 
06516     WOLFSSL_ENTER("wolfSSL_d2i_PUBKEY");
06517 
06518     if (in == NULL || inSz < 0) {
06519         WOLFSSL_MSG("Bad argument");
06520         return NULL;
06521     }
06522     mem = *in;
06523 
06524     #if !defined(NO_RSA)
06525     {
06526         RsaKey rsa;
06527         word32 keyIdx = 0;
06528 
06529         /* test if RSA key */
06530         if (wc_InitRsaKey(&rsa, NULL) == 0 &&
06531             wc_RsaPublicKeyDecode(mem, &keyIdx, &rsa, (word32)memSz) == 0) {
06532             wc_FreeRsaKey(&rsa);
06533             pkey = wolfSSL_PKEY_new();
06534             if (pkey != NULL) {
06535                 pkey->pkey_sz = keyIdx;
06536                 pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
06537                         DYNAMIC_TYPE_PUBLIC_KEY);
06538                 if (pkey->pkey.ptr == NULL) {
06539                     wolfSSL_EVP_PKEY_free(pkey);
06540                     return NULL;
06541                 }
06542                 XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
06543                 pkey->type = EVP_PKEY_RSA;
06544                 if (out != NULL) {
06545                     *out = pkey;
06546                 }
06547 
06548                 pkey->ownRsa = 1;
06549                 pkey->rsa = wolfSSL_RSA_new();
06550                 if (pkey->rsa == NULL) {
06551                     wolfSSL_EVP_PKEY_free(pkey);
06552                     return NULL;
06553                 }
06554 
06555                 if (wolfSSL_RSA_LoadDer_ex(pkey->rsa,
06556                             (const unsigned char*)pkey->pkey.ptr,
06557                             pkey->pkey_sz, WOLFSSL_RSA_LOAD_PUBLIC) != 1) {
06558                     wolfSSL_EVP_PKEY_free(pkey);
06559                     return NULL;
06560                 }
06561 
06562                 return pkey;
06563             }
06564         }
06565         wc_FreeRsaKey(&rsa);
06566     }
06567     #endif /* NO_RSA */
06568 
06569     #ifdef HAVE_ECC
06570     {
06571         word32  keyIdx = 0;
06572         ecc_key ecc;
06573 
06574         if (wc_ecc_init(&ecc) == 0 &&
06575             wc_EccPublicKeyDecode(mem, &keyIdx, &ecc, (word32)memSz) == 0) {
06576             wc_ecc_free(&ecc);
06577             pkey = wolfSSL_PKEY_new();
06578             if (pkey != NULL) {
06579                 pkey->pkey_sz = keyIdx;
06580                 pkey->pkey.ptr = (char*)XMALLOC(keyIdx, NULL,
06581                         DYNAMIC_TYPE_PUBLIC_KEY);
06582                 if (pkey->pkey.ptr == NULL) {
06583                     wolfSSL_EVP_PKEY_free(pkey);
06584                     return NULL;
06585                 }
06586                 XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
06587                 pkey->type = EVP_PKEY_EC;
06588                 if (out != NULL) {
06589                     *out = pkey;
06590                 }
06591                 return pkey;
06592             }
06593         }
06594         wc_ecc_free(&ecc);
06595     }
06596     #endif /* HAVE_ECC */
06597 
06598     return pkey;
06599 
06600 }
06601 
06602 
06603 /* Reads in a DER format key. If PKCS8 headers are found they are stripped off.
06604  *
06605  * type  type of key
06606  * out   newly created WOLFSSL_EVP_PKEY structure
06607  * in    pointer to input key DER
06608  * inSz  size of in buffer
06609  *
06610  * On success a non null pointer is returned and the pointer in is advanced the
06611  * same number of bytes read.
06612  */
06613 WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out,
06614         const unsigned char **in, long inSz)
06615 {
06616     WOLFSSL_EVP_PKEY* local;
06617     word32 idx = 0;
06618     int    ret;
06619 
06620     WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey");
06621 
06622     if (in == NULL || inSz < 0) {
06623         WOLFSSL_MSG("Bad argument");
06624         return NULL;
06625     }
06626 
06627     /* Check if input buffer has PKCS8 header. In the case that it does not
06628      * have a PKCS8 header then do not error out. */
06629     if ((ret = ToTraditionalInline((const byte*)(*in), &idx, (word32)inSz))
06630             > 0) {
06631         WOLFSSL_MSG("Found and removed PKCS8 header");
06632     }
06633     else {
06634         if (ret != ASN_PARSE_E) {
06635             WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 header");
06636             return NULL;
06637         }
06638     }
06639 
06640     if (out != NULL && *out != NULL) {
06641         wolfSSL_EVP_PKEY_free(*out);
06642     }
06643     local = wolfSSL_PKEY_new();
06644     if (local == NULL) {
06645         return NULL;
06646     }
06647 
06648     /* sanity check on idx before use */
06649     if ((int)idx > inSz) {
06650         WOLFSSL_MSG("Issue with index pointer");
06651         wolfSSL_EVP_PKEY_free(local);
06652         local = NULL;
06653         return NULL;
06654     }
06655 
06656     local->type     = type;
06657     local->pkey_sz  = (int)inSz - idx;
06658     local->pkey.ptr = (char*)XMALLOC(inSz - idx, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
06659     if (local->pkey.ptr == NULL) {
06660         wolfSSL_EVP_PKEY_free(local);
06661         local = NULL;
06662         return NULL;
06663     }
06664     else {
06665         XMEMCPY(local->pkey.ptr, *in + idx, inSz - idx);
06666     }
06667 
06668     switch (type) {
06669 #ifndef NO_RSA
06670         case EVP_PKEY_RSA:
06671             local->ownRsa = 1;
06672             local->rsa = wolfSSL_RSA_new();
06673             if (local->rsa == NULL) {
06674                 wolfSSL_EVP_PKEY_free(local);
06675                 return NULL;
06676             }
06677             if (wolfSSL_RSA_LoadDer_ex(local->rsa,
06678                       (const unsigned char*)local->pkey.ptr, local->pkey_sz,
06679                       WOLFSSL_RSA_LOAD_PRIVATE) != SSL_SUCCESS) {
06680                 wolfSSL_EVP_PKEY_free(local);
06681                 return NULL;
06682             }
06683             break;
06684 #endif /* NO_RSA */
06685 #ifdef HAVE_ECC
06686         case EVP_PKEY_EC:
06687             local->ownEcc = 1;
06688             local->ecc = wolfSSL_EC_KEY_new();
06689             if (local->ecc == NULL) {
06690                 wolfSSL_EVP_PKEY_free(local);
06691                 return NULL;
06692             }
06693             if (wolfSSL_EC_KEY_LoadDer(local->ecc,
06694                       (const unsigned char*)local->pkey.ptr, local->pkey_sz)
06695                       != SSL_SUCCESS) {
06696                 wolfSSL_EVP_PKEY_free(local);
06697                 return NULL;
06698             }
06699             break;
06700 #endif /* HAVE_ECC */
06701 
06702         default:
06703             WOLFSSL_MSG("Unsupported key type");
06704             wolfSSL_EVP_PKEY_free(local);
06705             return NULL;
06706     }
06707 
06708     /* advance pointer with success */
06709     if (local != NULL) {
06710         if ((idx + local->pkey_sz) <= (word32)inSz) {
06711             *in = *in + idx + local->pkey_sz;
06712         }
06713 
06714         if (out != NULL) {
06715             *out = local;
06716         }
06717     }
06718 
06719     return local;
06720 }
06721 
06722 #ifndef NO_WOLFSSL_STUB
06723 long wolfSSL_ctrl(WOLFSSL* ssl, int cmd, long opt, void* pt)
06724 {
06725     WOLFSSL_STUB("SSL_ctrl");
06726     (void)ssl;
06727     (void)cmd;
06728     (void)opt;
06729     (void)pt;
06730     return WOLFSSL_FAILURE;
06731 }
06732 #endif
06733 
06734 #ifndef NO_WOLFSSL_STUB
06735 long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt)
06736 {
06737     WOLFSSL_STUB("SSL_CTX_ctrl");
06738     (void)ctx;
06739     (void)cmd;
06740     (void)opt;
06741     (void)pt;
06742     return WOLFSSL_FAILURE;
06743 }
06744 #endif
06745 
06746 #ifndef NO_CERTS
06747 
06748 int wolfSSL_check_private_key(const WOLFSSL* ssl)
06749 {
06750     DecodedCert der;
06751     word32 size;
06752     byte*  buff;
06753     int    ret;
06754 
06755     if (ssl == NULL) {
06756         return WOLFSSL_FAILURE;
06757     }
06758 
06759     size = ssl->buffers.certificate->length;
06760     buff = ssl->buffers.certificate->buffer;
06761     InitDecodedCert(&der, buff, size, ssl->heap);
06762 #ifdef HAVE_PK_CALLBACKS
06763     ret = InitSigPkCb((WOLFSSL*)ssl, &der.sigCtx);
06764     if (ret != 0) {
06765         FreeDecodedCert(&der);
06766         return ret;
06767     }
06768 #endif
06769 
06770     if (ParseCertRelative(&der, CERT_TYPE, NO_VERIFY, NULL) != 0) {
06771         FreeDecodedCert(&der);
06772         return WOLFSSL_FAILURE;
06773     }
06774 
06775     size = ssl->buffers.key->length;
06776     buff = ssl->buffers.key->buffer;
06777     ret  = wc_CheckPrivateKey(buff, size, &der);
06778     FreeDecodedCert(&der);
06779     return ret;
06780 }
06781 
06782 
06783 /* Looks for the extension matching the passed in nid
06784  *
06785  * c   : if not null then is set to status value -2 if multiple occurances
06786  *       of the extension are found, -1 if not found, 0 if found and not
06787  *       critical, and 1 if found and critical.
06788  * nid : Extension OID to be found.
06789  * idx : if NULL return first extension found match, otherwise start search at
06790  *       idx location and set idx to the location of extension returned.
06791  * returns NULL or a pointer to an WOLFSSL_STACK holding extension structure
06792  *
06793  * NOTE code for decoding extensions is in asn.c DecodeCertExtensions --
06794  * use already decoded extension in this function to avoid decoding twice.
06795  * Currently we do not make use of idx since getting pre decoded extensions.
06796  */
06797 void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509,
06798                                                      int nid, int* c, int* idx)
06799 {
06800     WOLFSSL_STACK* sk = NULL;
06801     WOLFSSL_ASN1_OBJECT* obj = NULL;
06802 
06803     WOLFSSL_ENTER("wolfSSL_X509_get_ext_d2i");
06804 
06805     if (x509 == NULL) {
06806         return NULL;
06807     }
06808 
06809     if (c != NULL) {
06810         *c = -1; /* default to not found */
06811     }
06812 
06813     sk = (WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)*)XMALLOC(
06814                 sizeof(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)), NULL, DYNAMIC_TYPE_ASN1);
06815     if (sk == NULL) {
06816         return NULL;
06817     }
06818     XMEMSET(sk, 0, sizeof(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)));
06819 
06820     switch (nid) {
06821         case BASIC_CA_OID:
06822             if (x509->basicConstSet) {
06823                 obj = wolfSSL_ASN1_OBJECT_new();
06824                 if (obj == NULL) {
06825                     WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
06826                     wolfSSL_sk_ASN1_OBJECT_free(sk);
06827                     return NULL;
06828                 }
06829                 if (c != NULL) {
06830                     *c = x509->basicConstCrit;
06831                 }
06832                 obj->type = BASIC_CA_OID;
06833                 obj->grp  = oidCertExtType;
06834             }
06835             else {
06836                 WOLFSSL_MSG("No Basic Constraint set");
06837             }
06838             break;
06839 
06840         case ALT_NAMES_OID:
06841             {
06842                 DNS_entry* dns = NULL;
06843 
06844                 if (x509->subjAltNameSet && x509->altNames != NULL) {
06845                     /* alt names are DNS_entry structs */
06846                     if (c != NULL) {
06847                         if (x509->altNames->next != NULL) {
06848                             *c = -2; /* more then one found */
06849                         }
06850                         else {
06851                             *c = x509->subjAltNameCrit;
06852                         }
06853                     }
06854 
06855                     dns = x509->altNames;
06856                     while (dns != NULL) {
06857                         obj = wolfSSL_ASN1_OBJECT_new();
06858                         if (obj == NULL) {
06859                             WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
06860                             wolfSSL_sk_ASN1_OBJECT_free(sk);
06861                             return NULL;
06862                         }
06863                         obj->type = dns->type;
06864                         obj->grp  = oidCertExtType;
06865                         obj->obj  = (byte*)dns->name;
06866 
06867                         /* set app derefrenced pointers */
06868                         obj->d.ia5_internal.data   = dns->name;
06869                         obj->d.ia5_internal.length = (int)XSTRLEN(dns->name);
06870                         dns = dns->next;
06871                         /* last dns in list add at end of function */
06872                         if (dns != NULL) {
06873                             if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) !=
06874                                                                   WOLFSSL_SUCCESS) {
06875                             WOLFSSL_MSG("Error pushing ASN1 object onto stack");
06876                             wolfSSL_ASN1_OBJECT_free(obj);
06877                             wolfSSL_sk_ASN1_OBJECT_free(sk);
06878                             sk = NULL;
06879                             }
06880                         }
06881                     }
06882                 }
06883                 else {
06884                     WOLFSSL_MSG("No Alt Names set");
06885                 }
06886             }
06887             break;
06888 
06889         case CRL_DIST_OID:
06890             if (x509->CRLdistSet && x509->CRLInfo != NULL) {
06891                 if (c != NULL) {
06892                     *c = x509->CRLdistCrit;
06893                 }
06894                 obj = wolfSSL_ASN1_OBJECT_new();
06895                 if (obj == NULL) {
06896                     WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
06897                     wolfSSL_sk_ASN1_OBJECT_free(sk);
06898                     return NULL;
06899                 }
06900                 obj->type  = CRL_DIST_OID;
06901                 obj->grp   = oidCertExtType;
06902                 obj->obj   = x509->CRLInfo;
06903                 obj->objSz = x509->CRLInfoSz;
06904             }
06905             else {
06906                 WOLFSSL_MSG("No CRL dist set");
06907             }
06908             break;
06909 
06910         case AUTH_INFO_OID:
06911             if (x509->authInfoSet && x509->authInfo != NULL) {
06912                 if (c != NULL) {
06913                     *c = x509->authInfoCrit;
06914                 }
06915                 obj = wolfSSL_ASN1_OBJECT_new();
06916                 if (obj == NULL) {
06917                     WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
06918                     wolfSSL_sk_ASN1_OBJECT_free(sk);
06919                     return NULL;
06920                 }
06921                 obj->type  = AUTH_INFO_OID;
06922                 obj->grp   = oidCertExtType;
06923                 obj->obj   = x509->authInfo;
06924                 obj->objSz = x509->authInfoSz;
06925             }
06926             else {
06927                 WOLFSSL_MSG("No Auth Info set");
06928             }
06929             break;
06930 
06931         case AUTH_KEY_OID:
06932             if (x509->authKeyIdSet) {
06933                 if (c != NULL) {
06934                     *c = x509->authKeyIdCrit;
06935                 }
06936                 obj = wolfSSL_ASN1_OBJECT_new();
06937                 if (obj == NULL) {
06938                     WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
06939                     wolfSSL_sk_ASN1_OBJECT_free(sk);
06940                     return NULL;
06941                 }
06942                 obj->type  = AUTH_KEY_OID;
06943                 obj->grp   = oidCertExtType;
06944                 obj->obj   = x509->authKeyId;
06945                 obj->objSz = x509->authKeyIdSz;
06946             }
06947             else {
06948                 WOLFSSL_MSG("No Auth Key set");
06949             }
06950             break;
06951 
06952         case SUBJ_KEY_OID:
06953             if (x509->subjKeyIdSet) {
06954                 if (c != NULL) {
06955                     *c = x509->subjKeyIdCrit;
06956                 }
06957                 obj = wolfSSL_ASN1_OBJECT_new();
06958                 if (obj == NULL) {
06959                     WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
06960                     wolfSSL_sk_ASN1_OBJECT_free(sk);
06961                     return NULL;
06962                 }
06963                 obj->type  = SUBJ_KEY_OID;
06964                 obj->grp   = oidCertExtType;
06965                 obj->obj   = x509->subjKeyId;
06966                 obj->objSz = x509->subjKeyIdSz;
06967             }
06968             else {
06969                 WOLFSSL_MSG("No Subject Key set");
06970             }
06971             break;
06972 
06973         case CERT_POLICY_OID:
06974             #ifdef WOLFSSL_CERT_EXT
06975             {
06976                 int i;
06977 
06978                 if (x509->certPoliciesNb > 0) {
06979                     if (c != NULL) {
06980                         if (x509->certPoliciesNb > 1) {
06981                             *c = -2;
06982                         }
06983                         else {
06984                             *c = 0;
06985                         }
06986                     }
06987 
06988                     for (i = 0; i < x509->certPoliciesNb - 1; i++) {
06989                         obj = wolfSSL_ASN1_OBJECT_new();
06990                         if (obj == NULL) {
06991                             WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
06992                             wolfSSL_sk_ASN1_OBJECT_free(sk);
06993                             return NULL;
06994                         }
06995                         obj->type  = CERT_POLICY_OID;
06996                         obj->grp   = oidCertExtType;
06997                         obj->obj   = (byte*)(x509->certPolicies[i]);
06998                         obj->objSz = MAX_CERTPOL_SZ;
06999                         if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj)
07000                                                                != WOLFSSL_SUCCESS) {
07001                             WOLFSSL_MSG("Error pushing ASN1 object onto stack");
07002                             wolfSSL_ASN1_OBJECT_free(obj);
07003                             wolfSSL_sk_ASN1_OBJECT_free(sk);
07004                             sk = NULL;
07005                         }
07006                     }
07007                     obj = wolfSSL_ASN1_OBJECT_new();
07008                     if (obj == NULL) {
07009                         WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
07010                         wolfSSL_sk_ASN1_OBJECT_free(sk);
07011                         return NULL;
07012                     }
07013                     obj->type  = CERT_POLICY_OID;
07014                     obj->grp   = oidCertExtType;
07015                     obj->obj   = (byte*)(x509->certPolicies[i]);
07016                     obj->objSz = MAX_CERTPOL_SZ;
07017                 }
07018                 else {
07019                     WOLFSSL_MSG("No Cert Policy set");
07020                 }
07021             }
07022             #else
07023                 #ifdef WOLFSSL_SEP
07024                 if (x509->certPolicySet) {
07025                     if (c != NULL) {
07026                         *c = x509->certPolicyCrit;
07027                     }
07028                     obj = wolfSSL_ASN1_OBJECT_new();
07029                     if (obj == NULL) {
07030                         WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
07031                         wolfSSL_sk_ASN1_OBJECT_free(sk);
07032                         return NULL;
07033                     }
07034                     obj->type  = CERT_POLICY_OID;
07035                     obj->grp   = oidCertExtType;
07036                 }
07037                 else {
07038                     WOLFSSL_MSG("No Cert Policy set");
07039                 }
07040                 #else
07041                 WOLFSSL_MSG("wolfSSL not built with WOLFSSL_SEP or WOLFSSL_CERT_EXT");
07042                 #endif /* WOLFSSL_SEP */
07043             #endif /* WOLFSSL_CERT_EXT */
07044             break;
07045 
07046         case KEY_USAGE_OID:
07047             if (x509->keyUsageSet) {
07048                 if (c != NULL) {
07049                     *c = x509->keyUsageCrit;
07050                 }
07051                 obj = wolfSSL_ASN1_OBJECT_new();
07052                 if (obj == NULL) {
07053                     WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
07054                     wolfSSL_sk_ASN1_OBJECT_free(sk);
07055                     return NULL;
07056                 }
07057                 obj->type  = KEY_USAGE_OID;
07058                 obj->grp   = oidCertExtType;
07059                 obj->obj   = (byte*)&(x509->keyUsage);
07060                 obj->objSz = sizeof(word16);
07061             }
07062             else {
07063                 WOLFSSL_MSG("No Key Usage set");
07064             }
07065             break;
07066 
07067         case INHIBIT_ANY_OID:
07068             WOLFSSL_MSG("INHIBIT ANY extension not supported");
07069             break;
07070 
07071         case EXT_KEY_USAGE_OID:
07072             if (x509->extKeyUsageSrc != NULL) {
07073                 if (c != NULL) {
07074                     if (x509->extKeyUsageCount > 1) {
07075                         *c = -2;
07076                     }
07077                     else {
07078                         *c = x509->extKeyUsageCrit;
07079                     }
07080                 }
07081                 obj = wolfSSL_ASN1_OBJECT_new();
07082                 if (obj == NULL) {
07083                     WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
07084                     wolfSSL_sk_ASN1_OBJECT_free(sk);
07085                     return NULL;
07086                 }
07087                 obj->type  = EXT_KEY_USAGE_OID;
07088                 obj->grp   = oidCertExtType;
07089                 obj->obj   = x509->extKeyUsageSrc;
07090                 obj->objSz = x509->extKeyUsageSz;
07091             }
07092             else {
07093                 WOLFSSL_MSG("No Extended Key Usage set");
07094             }
07095             break;
07096 
07097         case NAME_CONS_OID:
07098             WOLFSSL_MSG("Name Constraint OID extension not supported");
07099             break;
07100 
07101         case PRIV_KEY_USAGE_PERIOD_OID:
07102             WOLFSSL_MSG("Private Key Usage Period extension not supported");
07103             break;
07104 
07105         case SUBJECT_INFO_ACCESS:
07106             WOLFSSL_MSG("Subject Info Access extension not supported");
07107             break;
07108 
07109         case POLICY_MAP_OID:
07110             WOLFSSL_MSG("Policy Map extension not supported");
07111             break;
07112 
07113         case POLICY_CONST_OID:
07114             WOLFSSL_MSG("Policy Constraint extension not supported");
07115             break;
07116 
07117         case ISSUE_ALT_NAMES_OID:
07118             WOLFSSL_MSG("Issue Alt Names extension not supported");
07119             break;
07120 
07121         case TLS_FEATURE_OID:
07122             WOLFSSL_MSG("TLS Feature extension not supported");
07123             break;
07124 
07125         default:
07126             WOLFSSL_MSG("Unsupported/Unknown extension OID");
07127     }
07128 
07129     if (obj != NULL) {
07130         if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) != WOLFSSL_SUCCESS) {
07131             WOLFSSL_MSG("Error pushing ASN1 object onto stack");
07132             wolfSSL_ASN1_OBJECT_free(obj);
07133             wolfSSL_sk_ASN1_OBJECT_free(sk);
07134             sk = NULL;
07135         }
07136     }
07137     else { /* no ASN1 object found for extension, free stack */
07138         wolfSSL_sk_ASN1_OBJECT_free(sk);
07139         sk = NULL;
07140     }
07141 
07142     (void)idx;
07143 
07144     return sk;
07145 }
07146 
07147 
07148 /* this function makes the assumption that out buffer is big enough for digest*/
07149 static int wolfSSL_EVP_Digest(unsigned char* in, int inSz, unsigned char* out,
07150                               unsigned int* outSz, const WOLFSSL_EVP_MD* evp,
07151                               WOLFSSL_ENGINE* eng)
07152 {
07153     int err;
07154     int hashType = WC_HASH_TYPE_NONE;
07155     int hashSz;
07156 
07157     (void)eng;
07158 
07159     err = wolfSSL_EVP_get_hashinfo(evp, &hashType, &hashSz);
07160     if (err != WOLFSSL_SUCCESS)
07161         return err;
07162 
07163     *outSz = hashSz;
07164 
07165     if (wc_Hash((enum wc_HashType)hashType, in, inSz, out, *outSz) != 0) {
07166         return WOLFSSL_FAILURE;
07167     }
07168 
07169     return WOLFSSL_SUCCESS;
07170 }
07171 
07172 
07173 int wolfSSL_X509_digest(const WOLFSSL_X509* x509, const WOLFSSL_EVP_MD* digest,
07174         unsigned char* buf, unsigned int* len)
07175 {
07176     WOLFSSL_ENTER("wolfSSL_X509_digest");
07177 
07178     if (x509 == NULL || digest == NULL) {
07179         return WOLFSSL_FAILURE;
07180     }
07181 
07182     return wolfSSL_EVP_Digest(x509->derCert->buffer, x509->derCert->length, buf,
07183                               len, digest, NULL);
07184 }
07185 
07186 
07187 int wolfSSL_use_PrivateKey(WOLFSSL* ssl, WOLFSSL_EVP_PKEY* pkey)
07188 {
07189     WOLFSSL_ENTER("wolfSSL_use_PrivateKey");
07190     if (ssl == NULL || pkey == NULL ) {
07191         return WOLFSSL_FAILURE;
07192     }
07193 
07194     return wolfSSL_use_PrivateKey_buffer(ssl, (unsigned char*)pkey->pkey.ptr,
07195                                          pkey->pkey_sz, WOLFSSL_FILETYPE_ASN1);
07196 }
07197 
07198 
07199 int wolfSSL_use_PrivateKey_ASN1(int pri, WOLFSSL* ssl, unsigned char* der,
07200                                 long derSz)
07201 {
07202     WOLFSSL_ENTER("wolfSSL_use_PrivateKey_ASN1");
07203     if (ssl == NULL || der == NULL ) {
07204         return WOLFSSL_FAILURE;
07205     }
07206 
07207     (void)pri; /* type of private key */
07208     return wolfSSL_use_PrivateKey_buffer(ssl, der, derSz, WOLFSSL_FILETYPE_ASN1);
07209 }
07210 
07211 
07212 #ifndef NO_RSA
07213 int wolfSSL_use_RSAPrivateKey_ASN1(WOLFSSL* ssl, unsigned char* der, long derSz)
07214 {
07215     WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_ASN1");
07216     if (ssl == NULL || der == NULL ) {
07217         return WOLFSSL_FAILURE;
07218     }
07219 
07220     return wolfSSL_use_PrivateKey_buffer(ssl, der, derSz, WOLFSSL_FILETYPE_ASN1);
07221 }
07222 #endif
07223 
07224 int wolfSSL_use_certificate_ASN1(WOLFSSL* ssl, unsigned char* der, int derSz)
07225 {
07226     long idx;
07227 
07228     WOLFSSL_ENTER("wolfSSL_use_certificate_ASN1");
07229     if (der != NULL && ssl != NULL) {
07230         if (ProcessBuffer(NULL, der, derSz, WOLFSSL_FILETYPE_ASN1, CERT_TYPE, ssl,
07231                                                         &idx, 0) == WOLFSSL_SUCCESS)
07232             return WOLFSSL_SUCCESS;
07233     }
07234 
07235     (void)idx;
07236     return WOLFSSL_FAILURE;
07237 }
07238 
07239 
07240 int wolfSSL_use_certificate(WOLFSSL* ssl, WOLFSSL_X509* x509)
07241 {
07242     long idx;
07243 
07244     WOLFSSL_ENTER("wolfSSL_use_certificate");
07245     if (x509 != NULL && ssl != NULL && x509->derCert != NULL) {
07246         if (ProcessBuffer(NULL, x509->derCert->buffer, x509->derCert->length,
07247                      WOLFSSL_FILETYPE_ASN1, CERT_TYPE, ssl, &idx, 0) == WOLFSSL_SUCCESS)
07248             return WOLFSSL_SUCCESS;
07249     }
07250 
07251     (void)idx;
07252     return WOLFSSL_FAILURE;
07253 }
07254 #endif /* NO_CERTS */
07255 
07256 #ifndef NO_FILESYSTEM
07257 
07258 int wolfSSL_use_certificate_file(WOLFSSL* ssl, const char* file, int format)
07259 {
07260     WOLFSSL_ENTER("wolfSSL_use_certificate_file");
07261     if (ProcessFile(ssl->ctx, file, format, CERT_TYPE,
07262                     ssl, 0, NULL) == WOLFSSL_SUCCESS)
07263         return WOLFSSL_SUCCESS;
07264 
07265     return WOLFSSL_FAILURE;
07266 }
07267 
07268 
07269 int wolfSSL_use_PrivateKey_file(WOLFSSL* ssl, const char* file, int format)
07270 {
07271     WOLFSSL_ENTER("wolfSSL_use_PrivateKey_file");
07272     if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE,
07273                     ssl, 0, NULL) == WOLFSSL_SUCCESS)
07274         return WOLFSSL_SUCCESS;
07275 
07276     return WOLFSSL_FAILURE;
07277 }
07278 
07279 
07280 int wolfSSL_use_certificate_chain_file(WOLFSSL* ssl, const char* file)
07281 {
07282    /* process up to MAX_CHAIN_DEPTH plus subject cert */
07283    WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file");
07284    if (ProcessFile(ssl->ctx, file, WOLFSSL_FILETYPE_PEM, CERT_TYPE,
07285                    ssl, 1, NULL) == WOLFSSL_SUCCESS)
07286        return WOLFSSL_SUCCESS;
07287 
07288    return WOLFSSL_FAILURE;
07289 }
07290 
07291 int wolfSSL_use_certificate_chain_file_format(WOLFSSL* ssl, const char* file,
07292                                               int format)
07293 {
07294    /* process up to MAX_CHAIN_DEPTH plus subject cert */
07295    WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file_format");
07296    if (ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 1,
07297                    NULL) == WOLFSSL_SUCCESS)
07298        return WOLFSSL_SUCCESS;
07299 
07300    return WOLFSSL_FAILURE;
07301 }
07302 
07303 
07304 #ifdef HAVE_ECC
07305 
07306 /* Set Temp CTX EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
07307 int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX* ctx, word16 sz)
07308 {
07309     if (ctx == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
07310         return BAD_FUNC_ARG;
07311 
07312     ctx->eccTempKeySz = sz;
07313 
07314     return WOLFSSL_SUCCESS;
07315 }
07316 
07317 
07318 /* Set Temp SSL EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
07319 int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL* ssl, word16 sz)
07320 {
07321     if (ssl == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
07322         return BAD_FUNC_ARG;
07323 
07324     ssl->eccTempKeySz = sz;
07325 
07326     return WOLFSSL_SUCCESS;
07327 }
07328 
07329 #endif /* HAVE_ECC */
07330 
07331 
07332 
07333 
07334 int wolfSSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX* ctx,const char* file,
07335                                    int format)
07336 {
07337     WOLFSSL_ENTER("SSL_CTX_use_RSAPrivateKey_file");
07338 
07339     return wolfSSL_CTX_use_PrivateKey_file(ctx, file, format);
07340 }
07341 
07342 
07343 int wolfSSL_use_RSAPrivateKey_file(WOLFSSL* ssl, const char* file, int format)
07344 {
07345     WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_file");
07346 
07347     return wolfSSL_use_PrivateKey_file(ssl, file, format);
07348 }
07349 
07350 #endif /* NO_FILESYSTEM */
07351 
07352 /* Copies the master secret over to out buffer. If outSz is 0 returns the size
07353  * of master secret.
07354  *
07355  * ses : a session from completed TLS/SSL handshake
07356  * out : buffer to hold copy of master secret
07357  * outSz : size of out buffer
07358  * returns : number of bytes copied into out buffer on success
07359  *           less then or equal to 0 is considered a failure case
07360  */
07361 int wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION* ses,
07362         unsigned char* out, int outSz)
07363 {
07364     int size;
07365 
07366     if (outSz == 0) {
07367         return SECRET_LEN;
07368     }
07369 
07370     if (ses == NULL || out == NULL || outSz < 0) {
07371         return 0;
07372     }
07373 
07374     if (outSz > SECRET_LEN) {
07375         size = SECRET_LEN;
07376     }
07377     else {
07378         size = outSz;
07379     }
07380 
07381     XMEMCPY(out, ses->masterSecret, size);
07382     return size;
07383 }
07384 
07385 
07386 int wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION* ses)
07387 {
07388     (void)ses;
07389     return SECRET_LEN;
07390 }
07391 
07392 #endif /* OPENSSL_EXTRA */
07393 
07394 #ifndef NO_FILESYSTEM
07395 #ifdef HAVE_NTRU
07396 
07397 int wolfSSL_CTX_use_NTRUPrivateKey_file(WOLFSSL_CTX* ctx, const char* file)
07398 {
07399     WOLFSSL_ENTER("wolfSSL_CTX_use_NTRUPrivateKey_file");
07400     if (ctx == NULL)
07401         return WOLFSSL_FAILURE;
07402 
07403     if (ProcessFile(ctx, file, WOLFSSL_FILETYPE_RAW, PRIVATEKEY_TYPE, NULL, 0, NULL)
07404                          == WOLFSSL_SUCCESS) {
07405         ctx->haveNTRU = 1;
07406         return WOLFSSL_SUCCESS;
07407     }
07408 
07409     return WOLFSSL_FAILURE;
07410 }
07411 
07412 #endif /* HAVE_NTRU */
07413 
07414 
07415 #endif /* NO_FILESYSTEM */
07416 
07417 
07418 void wolfSSL_CTX_set_verify(WOLFSSL_CTX* ctx, int mode, VerifyCallback vc)
07419 {
07420     WOLFSSL_ENTER("wolfSSL_CTX_set_verify");
07421     if (mode & WOLFSSL_VERIFY_PEER) {
07422         ctx->verifyPeer = 1;
07423         ctx->verifyNone = 0;  /* in case previously set */
07424     }
07425 
07426     if (mode == WOLFSSL_VERIFY_NONE) {
07427         ctx->verifyNone = 1;
07428         ctx->verifyPeer = 0;  /* in case previously set */
07429     }
07430 
07431     if (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT)
07432         ctx->failNoCert = 1;
07433 
07434     if (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK) {
07435         ctx->failNoCert    = 0; /* fail on all is set to fail on PSK */
07436         ctx->failNoCertxPSK = 1;
07437     }
07438 
07439     ctx->verifyCallback = vc;
07440 }
07441 
07442 
07443 void wolfSSL_set_verify(WOLFSSL* ssl, int mode, VerifyCallback vc)
07444 {
07445     WOLFSSL_ENTER("wolfSSL_set_verify");
07446     if (mode & WOLFSSL_VERIFY_PEER) {
07447         ssl->options.verifyPeer = 1;
07448         ssl->options.verifyNone = 0;  /* in case previously set */
07449     }
07450 
07451     if (mode == WOLFSSL_VERIFY_NONE) {
07452         ssl->options.verifyNone = 1;
07453         ssl->options.verifyPeer = 0;  /* in case previously set */
07454     }
07455 
07456     if (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT)
07457         ssl->options.failNoCert = 1;
07458 
07459     if (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK) {
07460         ssl->options.failNoCert    = 0; /* fail on all is set to fail on PSK */
07461         ssl->options.failNoCertxPSK = 1;
07462     }
07463 
07464     ssl->verifyCallback = vc;
07465 }
07466 
07467 
07468 /* store user ctx for verify callback */
07469 void wolfSSL_SetCertCbCtx(WOLFSSL* ssl, void* ctx)
07470 {
07471     WOLFSSL_ENTER("wolfSSL_SetCertCbCtx");
07472     if (ssl)
07473         ssl->verifyCbCtx = ctx;
07474 }
07475 
07476 
07477 /* store context CA Cache addition callback */
07478 void wolfSSL_CTX_SetCACb(WOLFSSL_CTX* ctx, CallbackCACache cb)
07479 {
07480     if (ctx && ctx->cm)
07481         ctx->cm->caCacheCallback = cb;
07482 }
07483 
07484 
07485 #if defined(PERSIST_CERT_CACHE)
07486 
07487 #if !defined(NO_FILESYSTEM)
07488 
07489 /* Persist cert cache to file */
07490 int wolfSSL_CTX_save_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
07491 {
07492     WOLFSSL_ENTER("wolfSSL_CTX_save_cert_cache");
07493 
07494     if (ctx == NULL || fname == NULL)
07495         return BAD_FUNC_ARG;
07496 
07497     return CM_SaveCertCache(ctx->cm, fname);
07498 }
07499 
07500 
07501 /* Persist cert cache from file */
07502 int wolfSSL_CTX_restore_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
07503 {
07504     WOLFSSL_ENTER("wolfSSL_CTX_restore_cert_cache");
07505 
07506     if (ctx == NULL || fname == NULL)
07507         return BAD_FUNC_ARG;
07508 
07509     return CM_RestoreCertCache(ctx->cm, fname);
07510 }
07511 
07512 #endif /* NO_FILESYSTEM */
07513 
07514 /* Persist cert cache to memory */
07515 int wolfSSL_CTX_memsave_cert_cache(WOLFSSL_CTX* ctx, void* mem,
07516                                    int sz, int* used)
07517 {
07518     WOLFSSL_ENTER("wolfSSL_CTX_memsave_cert_cache");
07519 
07520     if (ctx == NULL || mem == NULL || used == NULL || sz <= 0)
07521         return BAD_FUNC_ARG;
07522 
07523     return CM_MemSaveCertCache(ctx->cm, mem, sz, used);
07524 }
07525 
07526 
07527 /* Restore cert cache from memory */
07528 int wolfSSL_CTX_memrestore_cert_cache(WOLFSSL_CTX* ctx, const void* mem, int sz)
07529 {
07530     WOLFSSL_ENTER("wolfSSL_CTX_memrestore_cert_cache");
07531 
07532     if (ctx == NULL || mem == NULL || sz <= 0)
07533         return BAD_FUNC_ARG;
07534 
07535     return CM_MemRestoreCertCache(ctx->cm, mem, sz);
07536 }
07537 
07538 
07539 /* get how big the the cert cache save buffer needs to be */
07540 int wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX* ctx)
07541 {
07542     WOLFSSL_ENTER("wolfSSL_CTX_get_cert_cache_memsize");
07543 
07544     if (ctx == NULL)
07545         return BAD_FUNC_ARG;
07546 
07547     return CM_GetCertCacheMemSize(ctx->cm);
07548 }
07549 
07550 #endif /* PERSIST_CERT_CACHE */
07551 #endif /* !NO_CERTS */
07552 
07553 
07554 #ifndef NO_SESSION_CACHE
07555 
07556 WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl)
07557 {
07558     WOLFSSL_ENTER("SSL_get_session");
07559     if (ssl)
07560         return GetSession(ssl, 0, 0);
07561 
07562     return NULL;
07563 }
07564 
07565 
07566 int wolfSSL_set_session(WOLFSSL* ssl, WOLFSSL_SESSION* session)
07567 {
07568     WOLFSSL_ENTER("SSL_set_session");
07569     if (session)
07570         return SetSession(ssl, session);
07571 
07572     return WOLFSSL_FAILURE;
07573 }
07574 
07575 
07576 #ifndef NO_CLIENT_CACHE
07577 
07578 /* Associate client session with serverID, find existing or store for saving
07579    if newSession flag on, don't reuse existing session
07580    WOLFSSL_SUCCESS on ok */
07581 int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
07582 {
07583     WOLFSSL_SESSION* session = NULL;
07584 
07585     WOLFSSL_ENTER("wolfSSL_SetServerID");
07586 
07587     if (ssl == NULL || id == NULL || len <= 0)
07588         return BAD_FUNC_ARG;
07589 
07590     if (newSession == 0) {
07591         session = GetSessionClient(ssl, id, len);
07592         if (session) {
07593             if (SetSession(ssl, session) != WOLFSSL_SUCCESS) {
07594     #ifdef HAVE_EXT_CACHE
07595                 wolfSSL_SESSION_free(session);
07596     #endif
07597                 WOLFSSL_MSG("SetSession failed");
07598                 session = NULL;
07599             }
07600         }
07601     }
07602 
07603     if (session == NULL) {
07604         WOLFSSL_MSG("Valid ServerID not cached already");
07605 
07606         ssl->session.idLen = (word16)min(SERVER_ID_LEN, (word32)len);
07607         XMEMCPY(ssl->session.serverID, id, ssl->session.idLen);
07608     }
07609     #ifdef HAVE_EXT_CACHE
07610     else
07611         wolfSSL_SESSION_free(session);
07612     #endif
07613 
07614     return WOLFSSL_SUCCESS;
07615 }
07616 
07617 #endif /* NO_CLIENT_CACHE */
07618 
07619 #if defined(PERSIST_SESSION_CACHE)
07620 
07621 /* for persistence, if changes to layout need to increment and modify
07622    save_session_cache() and restore_session_cache and memory versions too */
07623 #define WOLFSSL_CACHE_VERSION 2
07624 
07625 /* Session Cache Header information */
07626 typedef struct {
07627     int version;     /* cache layout version id */
07628     int rows;        /* session rows */
07629     int columns;     /* session columns */
07630     int sessionSz;   /* sizeof WOLFSSL_SESSION */
07631 } cache_header_t;
07632 
07633 /* current persistence layout is:
07634 
07635    1) cache_header_t
07636    2) SessionCache
07637    3) ClientCache
07638 
07639    update WOLFSSL_CACHE_VERSION if change layout for the following
07640    PERSISTENT_SESSION_CACHE functions
07641 */
07642 
07643 
07644 /* get how big the the session cache save buffer needs to be */
07645 int wolfSSL_get_session_cache_memsize(void)
07646 {
07647     int sz  = (int)(sizeof(SessionCache) + sizeof(cache_header_t));
07648 
07649     #ifndef NO_CLIENT_CACHE
07650         sz += (int)(sizeof(ClientCache));
07651     #endif
07652 
07653     return sz;
07654 }
07655 
07656 
07657 /* Persist session cache to memory */
07658 int wolfSSL_memsave_session_cache(void* mem, int sz)
07659 {
07660     int i;
07661     cache_header_t cache_header;
07662     SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
07663 #ifndef NO_CLIENT_CACHE
07664     ClientRow*     clRow;
07665 #endif
07666 
07667     WOLFSSL_ENTER("wolfSSL_memsave_session_cache");
07668 
07669     if (sz < wolfSSL_get_session_cache_memsize()) {
07670         WOLFSSL_MSG("Memory buffer too small");
07671         return BUFFER_E;
07672     }
07673 
07674     cache_header.version   = WOLFSSL_CACHE_VERSION;
07675     cache_header.rows      = SESSION_ROWS;
07676     cache_header.columns   = SESSIONS_PER_ROW;
07677     cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
07678     XMEMCPY(mem, &cache_header, sizeof(cache_header));
07679 
07680     if (wc_LockMutex(&session_mutex) != 0) {
07681         WOLFSSL_MSG("Session cache mutex lock failed");
07682         return BAD_MUTEX_E;
07683     }
07684 
07685     for (i = 0; i < cache_header.rows; ++i)
07686         XMEMCPY(row++, SessionCache + i, sizeof(SessionRow));
07687 
07688 #ifndef NO_CLIENT_CACHE
07689     clRow = (ClientRow*)row;
07690     for (i = 0; i < cache_header.rows; ++i)
07691         XMEMCPY(clRow++, ClientCache + i, sizeof(ClientRow));
07692 #endif
07693 
07694     wc_UnLockMutex(&session_mutex);
07695 
07696     WOLFSSL_LEAVE("wolfSSL_memsave_session_cache", WOLFSSL_SUCCESS);
07697 
07698     return WOLFSSL_SUCCESS;
07699 }
07700 
07701 
07702 /* Restore the persistent session cache from memory */
07703 int wolfSSL_memrestore_session_cache(const void* mem, int sz)
07704 {
07705     int    i;
07706     cache_header_t cache_header;
07707     SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
07708 #ifndef NO_CLIENT_CACHE
07709     ClientRow*     clRow;
07710 #endif
07711 
07712     WOLFSSL_ENTER("wolfSSL_memrestore_session_cache");
07713 
07714     if (sz < wolfSSL_get_session_cache_memsize()) {
07715         WOLFSSL_MSG("Memory buffer too small");
07716         return BUFFER_E;
07717     }
07718 
07719     XMEMCPY(&cache_header, mem, sizeof(cache_header));
07720     if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
07721         cache_header.rows      != SESSION_ROWS ||
07722         cache_header.columns   != SESSIONS_PER_ROW ||
07723         cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
07724 
07725         WOLFSSL_MSG("Session cache header match failed");
07726         return CACHE_MATCH_ERROR;
07727     }
07728 
07729     if (wc_LockMutex(&session_mutex) != 0) {
07730         WOLFSSL_MSG("Session cache mutex lock failed");
07731         return BAD_MUTEX_E;
07732     }
07733 
07734     for (i = 0; i < cache_header.rows; ++i)
07735         XMEMCPY(SessionCache + i, row++, sizeof(SessionRow));
07736 
07737 #ifndef NO_CLIENT_CACHE
07738     clRow = (ClientRow*)row;
07739     for (i = 0; i < cache_header.rows; ++i)
07740         XMEMCPY(ClientCache + i, clRow++, sizeof(ClientRow));
07741 #endif
07742 
07743     wc_UnLockMutex(&session_mutex);
07744 
07745     WOLFSSL_LEAVE("wolfSSL_memrestore_session_cache", WOLFSSL_SUCCESS);
07746 
07747     return WOLFSSL_SUCCESS;
07748 }
07749 
07750 #if !defined(NO_FILESYSTEM)
07751 
07752 /* Persist session cache to file */
07753 /* doesn't use memsave because of additional memory use */
07754 int wolfSSL_save_session_cache(const char *fname)
07755 {
07756     XFILE  file;
07757     int    ret;
07758     int    rc = WOLFSSL_SUCCESS;
07759     int    i;
07760     cache_header_t cache_header;
07761 
07762     WOLFSSL_ENTER("wolfSSL_save_session_cache");
07763 
07764     file = XFOPEN(fname, "w+b");
07765     if (file == XBADFILE) {
07766         WOLFSSL_MSG("Couldn't open session cache save file");
07767         return WOLFSSL_BAD_FILE;
07768     }
07769     cache_header.version   = WOLFSSL_CACHE_VERSION;
07770     cache_header.rows      = SESSION_ROWS;
07771     cache_header.columns   = SESSIONS_PER_ROW;
07772     cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
07773 
07774     /* cache header */
07775     ret = (int)XFWRITE(&cache_header, sizeof cache_header, 1, file);
07776     if (ret != 1) {
07777         WOLFSSL_MSG("Session cache header file write failed");
07778         XFCLOSE(file);
07779         return FWRITE_ERROR;
07780     }
07781 
07782     if (wc_LockMutex(&session_mutex) != 0) {
07783         WOLFSSL_MSG("Session cache mutex lock failed");
07784         XFCLOSE(file);
07785         return BAD_MUTEX_E;
07786     }
07787 
07788     /* session cache */
07789     for (i = 0; i < cache_header.rows; ++i) {
07790         ret = (int)XFWRITE(SessionCache + i, sizeof(SessionRow), 1, file);
07791         if (ret != 1) {
07792             WOLFSSL_MSG("Session cache member file write failed");
07793             rc = FWRITE_ERROR;
07794             break;
07795         }
07796     }
07797 
07798 #ifndef NO_CLIENT_CACHE
07799     /* client cache */
07800     for (i = 0; i < cache_header.rows; ++i) {
07801         ret = (int)XFWRITE(ClientCache + i, sizeof(ClientRow), 1, file);
07802         if (ret != 1) {
07803             WOLFSSL_MSG("Client cache member file write failed");
07804             rc = FWRITE_ERROR;
07805             break;
07806         }
07807     }
07808 #endif /* NO_CLIENT_CACHE */
07809 
07810     wc_UnLockMutex(&session_mutex);
07811 
07812     XFCLOSE(file);
07813     WOLFSSL_LEAVE("wolfSSL_save_session_cache", rc);
07814 
07815     return rc;
07816 }
07817 
07818 
07819 /* Restore the persistent session cache from file */
07820 /* doesn't use memstore because of additional memory use */
07821 int wolfSSL_restore_session_cache(const char *fname)
07822 {
07823     XFILE  file;
07824     int    rc = WOLFSSL_SUCCESS;
07825     int    ret;
07826     int    i;
07827     cache_header_t cache_header;
07828 
07829     WOLFSSL_ENTER("wolfSSL_restore_session_cache");
07830 
07831     file = XFOPEN(fname, "rb");
07832     if (file == XBADFILE) {
07833         WOLFSSL_MSG("Couldn't open session cache save file");
07834         return WOLFSSL_BAD_FILE;
07835     }
07836     /* cache header */
07837     ret = (int)XFREAD(&cache_header, sizeof cache_header, 1, file);
07838     if (ret != 1) {
07839         WOLFSSL_MSG("Session cache header file read failed");
07840         XFCLOSE(file);
07841         return FREAD_ERROR;
07842     }
07843     if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
07844         cache_header.rows      != SESSION_ROWS ||
07845         cache_header.columns   != SESSIONS_PER_ROW ||
07846         cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
07847 
07848         WOLFSSL_MSG("Session cache header match failed");
07849         XFCLOSE(file);
07850         return CACHE_MATCH_ERROR;
07851     }
07852 
07853     if (wc_LockMutex(&session_mutex) != 0) {
07854         WOLFSSL_MSG("Session cache mutex lock failed");
07855         XFCLOSE(file);
07856         return BAD_MUTEX_E;
07857     }
07858 
07859     /* session cache */
07860     for (i = 0; i < cache_header.rows; ++i) {
07861         ret = (int)XFREAD(SessionCache + i, sizeof(SessionRow), 1, file);
07862         if (ret != 1) {
07863             WOLFSSL_MSG("Session cache member file read failed");
07864             XMEMSET(SessionCache, 0, sizeof SessionCache);
07865             rc = FREAD_ERROR;
07866             break;
07867         }
07868     }
07869 
07870 #ifndef NO_CLIENT_CACHE
07871     /* client cache */
07872     for (i = 0; i < cache_header.rows; ++i) {
07873         ret = (int)XFREAD(ClientCache + i, sizeof(ClientRow), 1, file);
07874         if (ret != 1) {
07875             WOLFSSL_MSG("Client cache member file read failed");
07876             XMEMSET(ClientCache, 0, sizeof ClientCache);
07877             rc = FREAD_ERROR;
07878             break;
07879         }
07880     }
07881 
07882 #endif /* NO_CLIENT_CACHE */
07883 
07884     wc_UnLockMutex(&session_mutex);
07885 
07886     XFCLOSE(file);
07887     WOLFSSL_LEAVE("wolfSSL_restore_session_cache", rc);
07888 
07889     return rc;
07890 }
07891 
07892 #endif /* !NO_FILESYSTEM */
07893 #endif /* PERSIST_SESSION_CACHE */
07894 #endif /* NO_SESSION_CACHE */
07895 
07896 
07897 void wolfSSL_load_error_strings(void)   /* compatibility only */
07898 {}
07899 
07900 
07901 int wolfSSL_library_init(void)
07902 {
07903     WOLFSSL_ENTER("SSL_library_init");
07904     if (wolfSSL_Init() == WOLFSSL_SUCCESS)
07905         return WOLFSSL_SUCCESS;
07906     else
07907         return WOLFSSL_FATAL_ERROR;
07908 }
07909 
07910 
07911 #ifdef HAVE_SECRET_CALLBACK
07912 
07913 int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx)
07914 {
07915     WOLFSSL_ENTER("wolfSSL_set_session_secret_cb");
07916     if (ssl == NULL)
07917         return WOLFSSL_FATAL_ERROR;
07918 
07919     ssl->sessionSecretCb = cb;
07920     ssl->sessionSecretCtx = ctx;
07921     /* If using a pre-set key, assume session resumption. */
07922     ssl->session.sessionIDSz = 0;
07923     ssl->options.resuming = 1;
07924 
07925     return WOLFSSL_SUCCESS;
07926 }
07927 
07928 #endif
07929 
07930 
07931 #ifndef NO_SESSION_CACHE
07932 
07933 /* on by default if built in but allow user to turn off */
07934 long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX* ctx, long mode)
07935 {
07936     WOLFSSL_ENTER("SSL_CTX_set_session_cache_mode");
07937     if (mode == WOLFSSL_SESS_CACHE_OFF)
07938         ctx->sessionCacheOff = 1;
07939 
07940     if ((mode & WOLFSSL_SESS_CACHE_NO_AUTO_CLEAR) != 0)
07941         ctx->sessionCacheFlushOff = 1;
07942 
07943 #ifdef HAVE_EXT_CACHE
07944     if ((mode & WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE) != 0)
07945         ctx->internalCacheOff = 1;
07946 #endif
07947 
07948     return WOLFSSL_SUCCESS;
07949 }
07950 
07951 #endif /* NO_SESSION_CACHE */
07952 
07953 
07954 #if !defined(NO_CERTS)
07955 #if defined(PERSIST_CERT_CACHE)
07956 
07957 
07958 #define WOLFSSL_CACHE_CERT_VERSION 1
07959 
07960 typedef struct {
07961     int version;                 /* cache cert layout version id */
07962     int rows;                    /* hash table rows, CA_TABLE_SIZE */
07963     int columns[CA_TABLE_SIZE];  /* columns per row on list */
07964     int signerSz;                /* sizeof Signer object */
07965 } CertCacheHeader;
07966 
07967 /* current cert persistence layout is:
07968 
07969    1) CertCacheHeader
07970    2) caTable
07971 
07972    update WOLFSSL_CERT_CACHE_VERSION if change layout for the following
07973    PERSIST_CERT_CACHE functions
07974 */
07975 
07976 
07977 /* Return memory needed to persist this signer, have lock */
07978 static WC_INLINE int GetSignerMemory(Signer* signer)
07979 {
07980     int sz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID)
07981            + sizeof(signer->nameLen)    + sizeof(signer->subjectNameHash);
07982 
07983 #if !defined(NO_SKID)
07984         sz += (int)sizeof(signer->subjectKeyIdHash);
07985 #endif
07986 
07987     /* add dynamic bytes needed */
07988     sz += signer->pubKeySize;
07989     sz += signer->nameLen;
07990 
07991     return sz;
07992 }
07993 
07994 
07995 /* Return memory needed to persist this row, have lock */
07996 static WC_INLINE int GetCertCacheRowMemory(Signer* row)
07997 {
07998     int sz = 0;
07999 
08000     while (row) {
08001         sz += GetSignerMemory(row);
08002         row = row->next;
08003     }
08004 
08005     return sz;
08006 }
08007 
08008 
08009 /* get the size of persist cert cache, have lock */
08010 static WC_INLINE int GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
08011 {
08012     int sz;
08013     int i;
08014 
08015     sz = sizeof(CertCacheHeader);
08016 
08017     for (i = 0; i < CA_TABLE_SIZE; i++)
08018         sz += GetCertCacheRowMemory(cm->caTable[i]);
08019 
08020     return sz;
08021 }
08022 
08023 
08024 /* Store cert cache header columns with number of items per list, have lock */
08025 static WC_INLINE void SetCertHeaderColumns(WOLFSSL_CERT_MANAGER* cm, int* columns)
08026 {
08027     int     i;
08028     Signer* row;
08029 
08030     for (i = 0; i < CA_TABLE_SIZE; i++) {
08031         int count = 0;
08032         row = cm->caTable[i];
08033 
08034         while (row) {
08035             ++count;
08036             row = row->next;
08037         }
08038         columns[i] = count;
08039     }
08040 }
08041 
08042 
08043 /* Restore whole cert row from memory, have lock, return bytes consumed,
08044    < 0 on error, have lock */
08045 static WC_INLINE int RestoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current,
08046                                  int row, int listSz, const byte* end)
08047 {
08048     int idx = 0;
08049 
08050     if (listSz < 0) {
08051         WOLFSSL_MSG("Row header corrupted, negative value");
08052         return PARSE_ERROR;
08053     }
08054 
08055     while (listSz) {
08056         Signer* signer;
08057         byte*   start = current + idx;  /* for end checks on this signer */
08058         int     minSz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) +
08059                       sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
08060         #ifndef NO_SKID
08061                 minSz += (int)sizeof(signer->subjectKeyIdHash);
08062         #endif
08063 
08064         if (start + minSz > end) {
08065             WOLFSSL_MSG("Would overread restore buffer");
08066             return BUFFER_E;
08067         }
08068         signer = MakeSigner(cm->heap);
08069         if (signer == NULL)
08070             return MEMORY_E;
08071 
08072         /* pubKeySize */
08073         XMEMCPY(&signer->pubKeySize, current + idx, sizeof(signer->pubKeySize));
08074         idx += (int)sizeof(signer->pubKeySize);
08075 
08076         /* keyOID */
08077         XMEMCPY(&signer->keyOID, current + idx, sizeof(signer->keyOID));
08078         idx += (int)sizeof(signer->keyOID);
08079 
08080         /* pulicKey */
08081         if (start + minSz + signer->pubKeySize > end) {
08082             WOLFSSL_MSG("Would overread restore buffer");
08083             FreeSigner(signer, cm->heap);
08084             return BUFFER_E;
08085         }
08086         signer->publicKey = (byte*)XMALLOC(signer->pubKeySize, cm->heap,
08087                                            DYNAMIC_TYPE_KEY);
08088         if (signer->publicKey == NULL) {
08089             FreeSigner(signer, cm->heap);
08090             return MEMORY_E;
08091         }
08092 
08093         XMEMCPY(signer->publicKey, current + idx, signer->pubKeySize);
08094         idx += signer->pubKeySize;
08095 
08096         /* nameLen */
08097         XMEMCPY(&signer->nameLen, current + idx, sizeof(signer->nameLen));
08098         idx += (int)sizeof(signer->nameLen);
08099 
08100         /* name */
08101         if (start + minSz + signer->pubKeySize + signer->nameLen > end) {
08102             WOLFSSL_MSG("Would overread restore buffer");
08103             FreeSigner(signer, cm->heap);
08104             return BUFFER_E;
08105         }
08106         signer->name = (char*)XMALLOC(signer->nameLen, cm->heap,
08107                                       DYNAMIC_TYPE_SUBJECT_CN);
08108         if (signer->name == NULL) {
08109             FreeSigner(signer, cm->heap);
08110             return MEMORY_E;
08111         }
08112 
08113         XMEMCPY(signer->name, current + idx, signer->nameLen);
08114         idx += signer->nameLen;
08115 
08116         /* subjectNameHash */
08117         XMEMCPY(signer->subjectNameHash, current + idx, SIGNER_DIGEST_SIZE);
08118         idx += SIGNER_DIGEST_SIZE;
08119 
08120         #ifndef NO_SKID
08121             /* subjectKeyIdHash */
08122             XMEMCPY(signer->subjectKeyIdHash, current + idx,SIGNER_DIGEST_SIZE);
08123             idx += SIGNER_DIGEST_SIZE;
08124         #endif
08125 
08126         signer->next = cm->caTable[row];
08127         cm->caTable[row] = signer;
08128 
08129         --listSz;
08130     }
08131 
08132     return idx;
08133 }
08134 
08135 
08136 /* Store whole cert row into memory, have lock, return bytes added */
08137 static WC_INLINE int StoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current, int row)
08138 {
08139     int     added  = 0;
08140     Signer* list   = cm->caTable[row];
08141 
08142     while (list) {
08143         XMEMCPY(current + added, &list->pubKeySize, sizeof(list->pubKeySize));
08144         added += (int)sizeof(list->pubKeySize);
08145 
08146         XMEMCPY(current + added, &list->keyOID,     sizeof(list->keyOID));
08147         added += (int)sizeof(list->keyOID);
08148 
08149         XMEMCPY(current + added, list->publicKey, list->pubKeySize);
08150         added += list->pubKeySize;
08151 
08152         XMEMCPY(current + added, &list->nameLen, sizeof(list->nameLen));
08153         added += (int)sizeof(list->nameLen);
08154 
08155         XMEMCPY(current + added, list->name, list->nameLen);
08156         added += list->nameLen;
08157 
08158         XMEMCPY(current + added, list->subjectNameHash, SIGNER_DIGEST_SIZE);
08159         added += SIGNER_DIGEST_SIZE;
08160 
08161         #ifndef NO_SKID
08162             XMEMCPY(current + added, list->subjectKeyIdHash,SIGNER_DIGEST_SIZE);
08163             added += SIGNER_DIGEST_SIZE;
08164         #endif
08165 
08166         list = list->next;
08167     }
08168 
08169     return added;
08170 }
08171 
08172 
08173 /* Persist cert cache to memory, have lock */
08174 static WC_INLINE int DoMemSaveCertCache(WOLFSSL_CERT_MANAGER* cm,
08175                                      void* mem, int sz)
08176 {
08177     int realSz;
08178     int ret = WOLFSSL_SUCCESS;
08179     int i;
08180 
08181     WOLFSSL_ENTER("DoMemSaveCertCache");
08182 
08183     realSz = GetCertCacheMemSize(cm);
08184     if (realSz > sz) {
08185         WOLFSSL_MSG("Mem output buffer too small");
08186         ret = BUFFER_E;
08187     }
08188     else {
08189         byte*           current;
08190         CertCacheHeader hdr;
08191 
08192         hdr.version  = WOLFSSL_CACHE_CERT_VERSION;
08193         hdr.rows     = CA_TABLE_SIZE;
08194         SetCertHeaderColumns(cm, hdr.columns);
08195         hdr.signerSz = (int)sizeof(Signer);
08196 
08197         XMEMCPY(mem, &hdr, sizeof(CertCacheHeader));
08198         current = (byte*)mem + sizeof(CertCacheHeader);
08199 
08200         for (i = 0; i < CA_TABLE_SIZE; ++i)
08201             current += StoreCertRow(cm, current, i);
08202     }
08203 
08204     return ret;
08205 }
08206 
08207 
08208 #if !defined(NO_FILESYSTEM)
08209 
08210 /* Persist cert cache to file */
08211 int CM_SaveCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
08212 {
08213     XFILE file;
08214     int   rc = WOLFSSL_SUCCESS;
08215     int   memSz;
08216     byte* mem;
08217 
08218     WOLFSSL_ENTER("CM_SaveCertCache");
08219 
08220     file = XFOPEN(fname, "w+b");
08221     if (file == XBADFILE) {
08222        WOLFSSL_MSG("Couldn't open cert cache save file");
08223        return WOLFSSL_BAD_FILE;
08224     }
08225 
08226     if (wc_LockMutex(&cm->caLock) != 0) {
08227         WOLFSSL_MSG("wc_LockMutex on caLock failed");
08228         XFCLOSE(file);
08229         return BAD_MUTEX_E;
08230     }
08231 
08232     memSz = GetCertCacheMemSize(cm);
08233     mem   = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
08234     if (mem == NULL) {
08235         WOLFSSL_MSG("Alloc for tmp buffer failed");
08236         rc = MEMORY_E;
08237     } else {
08238         rc = DoMemSaveCertCache(cm, mem, memSz);
08239         if (rc == WOLFSSL_SUCCESS) {
08240             int ret = (int)XFWRITE(mem, memSz, 1, file);
08241             if (ret != 1) {
08242                 WOLFSSL_MSG("Cert cache file write failed");
08243                 rc = FWRITE_ERROR;
08244             }
08245         }
08246         XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
08247     }
08248 
08249     wc_UnLockMutex(&cm->caLock);
08250     XFCLOSE(file);
08251 
08252     return rc;
08253 }
08254 
08255 
08256 /* Restore cert cache from file */
08257 int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
08258 {
08259     XFILE file;
08260     int   rc = WOLFSSL_SUCCESS;
08261     int   ret;
08262     int   memSz;
08263     byte* mem;
08264 
08265     WOLFSSL_ENTER("CM_RestoreCertCache");
08266 
08267     file = XFOPEN(fname, "rb");
08268     if (file == XBADFILE) {
08269        WOLFSSL_MSG("Couldn't open cert cache save file");
08270        return WOLFSSL_BAD_FILE;
08271     }
08272 
08273     XFSEEK(file, 0, XSEEK_END);
08274     memSz = (int)XFTELL(file);
08275     XREWIND(file);
08276 
08277     if (memSz <= 0) {
08278         WOLFSSL_MSG("Bad file size");
08279         XFCLOSE(file);
08280         return WOLFSSL_BAD_FILE;
08281     }
08282 
08283     mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
08284     if (mem == NULL) {
08285         WOLFSSL_MSG("Alloc for tmp buffer failed");
08286         XFCLOSE(file);
08287         return MEMORY_E;
08288     }
08289 
08290     ret = (int)XFREAD(mem, memSz, 1, file);
08291     if (ret != 1) {
08292         WOLFSSL_MSG("Cert file read error");
08293         rc = FREAD_ERROR;
08294     } else {
08295         rc = CM_MemRestoreCertCache(cm, mem, memSz);
08296         if (rc != WOLFSSL_SUCCESS) {
08297             WOLFSSL_MSG("Mem restore cert cache failed");
08298         }
08299     }
08300 
08301     XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
08302     XFCLOSE(file);
08303 
08304     return rc;
08305 }
08306 
08307 #endif /* NO_FILESYSTEM */
08308 
08309 
08310 /* Persist cert cache to memory */
08311 int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, void* mem, int sz, int* used)
08312 {
08313     int ret = WOLFSSL_SUCCESS;
08314 
08315     WOLFSSL_ENTER("CM_MemSaveCertCache");
08316 
08317     if (wc_LockMutex(&cm->caLock) != 0) {
08318         WOLFSSL_MSG("wc_LockMutex on caLock failed");
08319         return BAD_MUTEX_E;
08320     }
08321 
08322     ret = DoMemSaveCertCache(cm, mem, sz);
08323     if (ret == WOLFSSL_SUCCESS)
08324         *used  = GetCertCacheMemSize(cm);
08325 
08326     wc_UnLockMutex(&cm->caLock);
08327 
08328     return ret;
08329 }
08330 
08331 
08332 /* Restore cert cache from memory */
08333 int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const void* mem, int sz)
08334 {
08335     int ret = WOLFSSL_SUCCESS;
08336     int i;
08337     CertCacheHeader* hdr = (CertCacheHeader*)mem;
08338     byte*            current = (byte*)mem + sizeof(CertCacheHeader);
08339     byte*            end     = (byte*)mem + sz;  /* don't go over */
08340 
08341     WOLFSSL_ENTER("CM_MemRestoreCertCache");
08342 
08343     if (current > end) {
08344         WOLFSSL_MSG("Cert Cache Memory buffer too small");
08345         return BUFFER_E;
08346     }
08347 
08348     if (hdr->version  != WOLFSSL_CACHE_CERT_VERSION ||
08349         hdr->rows     != CA_TABLE_SIZE ||
08350         hdr->signerSz != (int)sizeof(Signer)) {
08351 
08352         WOLFSSL_MSG("Cert Cache Memory header mismatch");
08353         return CACHE_MATCH_ERROR;
08354     }
08355 
08356     if (wc_LockMutex(&cm->caLock) != 0) {
08357         WOLFSSL_MSG("wc_LockMutex on caLock failed");
08358         return BAD_MUTEX_E;
08359     }
08360 
08361     FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
08362 
08363     for (i = 0; i < CA_TABLE_SIZE; ++i) {
08364         int added = RestoreCertRow(cm, current, i, hdr->columns[i], end);
08365         if (added < 0) {
08366             WOLFSSL_MSG("RestoreCertRow error");
08367             ret = added;
08368             break;
08369         }
08370         current += added;
08371     }
08372 
08373     wc_UnLockMutex(&cm->caLock);
08374 
08375     return ret;
08376 }
08377 
08378 
08379 /* get how big the the cert cache save buffer needs to be */
08380 int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
08381 {
08382     int sz;
08383 
08384     WOLFSSL_ENTER("CM_GetCertCacheMemSize");
08385 
08386     if (wc_LockMutex(&cm->caLock) != 0) {
08387         WOLFSSL_MSG("wc_LockMutex on caLock failed");
08388         return BAD_MUTEX_E;
08389     }
08390 
08391     sz = GetCertCacheMemSize(cm);
08392 
08393     wc_UnLockMutex(&cm->caLock);
08394 
08395     return sz;
08396 }
08397 
08398 #endif /* PERSIST_CERT_CACHE */
08399 #endif /* NO_CERTS */
08400 
08401 
08402 int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX* ctx, const char* list)
08403 {
08404     WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list");
08405 
08406     /* alloc/init on demand only */
08407     if (ctx->suites == NULL) {
08408         ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap,
08409                                        DYNAMIC_TYPE_SUITES);
08410         if (ctx->suites == NULL) {
08411             WOLFSSL_MSG("Memory alloc for Suites failed");
08412             return WOLFSSL_FAILURE;
08413         }
08414         XMEMSET(ctx->suites, 0, sizeof(Suites));
08415     }
08416 
08417     return (SetCipherList(ctx, ctx->suites, list)) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
08418 }
08419 
08420 
08421 int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list)
08422 {
08423     WOLFSSL_ENTER("wolfSSL_set_cipher_list");
08424     return (SetCipherList(ssl->ctx, ssl->suites, list)) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
08425 }
08426 
08427 
08428 int wolfSSL_dtls_get_using_nonblock(WOLFSSL* ssl)
08429 {
08430     int useNb = 0;
08431 
08432     WOLFSSL_ENTER("wolfSSL_dtls_get_using_nonblock");
08433     if (ssl->options.dtls) {
08434 #ifdef WOLFSSL_DTLS
08435         useNb = ssl->options.dtlsUseNonblock;
08436 #endif
08437     }
08438     else {
08439         WOLFSSL_MSG("wolfSSL_dtls_get_using_nonblock() is "
08440                     "DEPRECATED for non-DTLS use.");
08441     }
08442     return useNb;
08443 }
08444 
08445 
08446 #ifndef WOLFSSL_LEANPSK
08447 
08448 void wolfSSL_dtls_set_using_nonblock(WOLFSSL* ssl, int nonblock)
08449 {
08450     (void)nonblock;
08451 
08452     WOLFSSL_ENTER("wolfSSL_dtls_set_using_nonblock");
08453     if (ssl->options.dtls) {
08454 #ifdef WOLFSSL_DTLS
08455         ssl->options.dtlsUseNonblock = (nonblock != 0);
08456 #endif
08457     }
08458     else {
08459         WOLFSSL_MSG("wolfSSL_dtls_set_using_nonblock() is "
08460                     "DEPRECATED for non-DTLS use.");
08461     }
08462 }
08463 
08464 
08465 #ifdef WOLFSSL_DTLS
08466 
08467 int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl)
08468 {
08469     return ssl->dtls_timeout;
08470 }
08471 
08472 
08473 /* user may need to alter init dtls recv timeout, WOLFSSL_SUCCESS on ok */
08474 int wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int timeout)
08475 {
08476     if (ssl == NULL || timeout < 0)
08477         return BAD_FUNC_ARG;
08478 
08479     if (timeout > ssl->dtls_timeout_max) {
08480         WOLFSSL_MSG("Can't set dtls timeout init greater than dtls timeout max");
08481         return BAD_FUNC_ARG;
08482     }
08483 
08484     ssl->dtls_timeout_init = timeout;
08485     ssl->dtls_timeout = timeout;
08486 
08487     return WOLFSSL_SUCCESS;
08488 }
08489 
08490 
08491 /* user may need to alter max dtls recv timeout, WOLFSSL_SUCCESS on ok */
08492 int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int timeout)
08493 {
08494     if (ssl == NULL || timeout < 0)
08495         return BAD_FUNC_ARG;
08496 
08497     if (timeout < ssl->dtls_timeout_init) {
08498         WOLFSSL_MSG("Can't set dtls timeout max less than dtls timeout init");
08499         return BAD_FUNC_ARG;
08500     }
08501 
08502     ssl->dtls_timeout_max = timeout;
08503 
08504     return WOLFSSL_SUCCESS;
08505 }
08506 
08507 
08508 int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
08509 {
08510     int result = WOLFSSL_SUCCESS;
08511 
08512     if (!ssl->options.handShakeDone &&
08513         (DtlsMsgPoolTimeout(ssl) < 0 || DtlsMsgPoolSend(ssl, 0) < 0)) {
08514 
08515         result = WOLFSSL_FATAL_ERROR;
08516     }
08517     return result;
08518 }
08519 
08520 #endif /* DTLS */
08521 #endif /* LEANPSK */
08522 
08523 
08524 #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
08525 
08526 /* Not an SSL function, return 0 for success, error code otherwise */
08527 /* Prereq: ssl's RNG needs to be initialized. */
08528 int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
08529                                  const byte* secret, word32 secretSz)
08530 {
08531     int ret = 0;
08532 
08533     WOLFSSL_ENTER("wolfSSL_DTLS_SetCookieSecret");
08534 
08535     if (ssl == NULL) {
08536         WOLFSSL_MSG("need a SSL object");
08537         return BAD_FUNC_ARG;
08538     }
08539 
08540     if (secret != NULL && secretSz == 0) {
08541         WOLFSSL_MSG("can't have a new secret without a size");
08542         return BAD_FUNC_ARG;
08543     }
08544 
08545     /* If secretSz is 0, use the default size. */
08546     if (secretSz == 0)
08547         secretSz = COOKIE_SECRET_SZ;
08548 
08549     if (secretSz != ssl->buffers.dtlsCookieSecret.length) {
08550         byte* newSecret;
08551 
08552         if (ssl->buffers.dtlsCookieSecret.buffer != NULL) {
08553             ForceZero(ssl->buffers.dtlsCookieSecret.buffer,
08554                       ssl->buffers.dtlsCookieSecret.length);
08555             XFREE(ssl->buffers.dtlsCookieSecret.buffer,
08556                   ssl->heap, DYNAMIC_TYPE_NONE);
08557         }
08558 
08559         newSecret = (byte*)XMALLOC(secretSz, ssl->heap,DYNAMIC_TYPE_COOKIE_PWD);
08560         if (newSecret == NULL) {
08561             ssl->buffers.dtlsCookieSecret.buffer = NULL;
08562             ssl->buffers.dtlsCookieSecret.length = 0;
08563             WOLFSSL_MSG("couldn't allocate new cookie secret");
08564             return MEMORY_ERROR;
08565         }
08566         ssl->buffers.dtlsCookieSecret.buffer = newSecret;
08567         ssl->buffers.dtlsCookieSecret.length = secretSz;
08568     }
08569 
08570     /* If the supplied secret is NULL, randomly generate a new secret. */
08571     if (secret == NULL) {
08572         ret = wc_RNG_GenerateBlock(ssl->rng,
08573                              ssl->buffers.dtlsCookieSecret.buffer, secretSz);
08574     }
08575     else
08576         XMEMCPY(ssl->buffers.dtlsCookieSecret.buffer, secret, secretSz);
08577 
08578     WOLFSSL_LEAVE("wolfSSL_DTLS_SetCookieSecret", 0);
08579     return ret;
08580 }
08581 
08582 #endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
08583 
08584 #ifdef OPENSSL_EXTRA
08585     WOLFSSL_METHOD* wolfSSLv23_method(void) {
08586         WOLFSSL_METHOD* m = NULL;
08587         WOLFSSL_ENTER("wolfSSLv23_method");
08588 #if !defined(NO_WOLFSSL_CLIENT)
08589         m = wolfSSLv23_client_method();
08590 #elif !defined(NO_WOLFSSL_SERVER)
08591         m = wolfSSLv23_server_method();
08592 #endif
08593         if (m != NULL) {
08594             m->side = WOLFSSL_NEITHER_END;
08595         }
08596 
08597         return m;
08598     }
08599 #endif /* OPENSSL_EXTRA */
08600 
08601 /* client only parts */
08602 #ifndef NO_WOLFSSL_CLIENT
08603 
08604     #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
08605     WOLFSSL_METHOD* wolfSSLv3_client_method(void)
08606     {
08607         WOLFSSL_ENTER("SSLv3_client_method");
08608         return wolfSSLv3_client_method_ex(NULL);
08609     }
08610     #endif
08611 
08612     #ifdef WOLFSSL_DTLS
08613 
08614         #ifndef NO_OLD_TLS
08615         WOLFSSL_METHOD* wolfDTLSv1_client_method(void)
08616         {
08617             WOLFSSL_ENTER("DTLSv1_client_method");
08618             return wolfDTLSv1_client_method_ex(NULL);
08619         }
08620         #endif  /* NO_OLD_TLS */
08621 
08622         WOLFSSL_METHOD* wolfDTLSv1_2_client_method(void)
08623         {
08624             WOLFSSL_ENTER("DTLSv1_2_client_method");
08625             return wolfDTLSv1_2_client_method_ex(NULL);
08626         }
08627     #endif
08628 
08629     #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
08630     WOLFSSL_METHOD* wolfSSLv3_client_method_ex(void* heap)
08631     {
08632         WOLFSSL_METHOD* method =
08633                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
08634                                                      heap, DYNAMIC_TYPE_METHOD);
08635         WOLFSSL_ENTER("SSLv3_client_method_ex");
08636         if (method)
08637             InitSSL_Method(method, MakeSSLv3());
08638         return method;
08639     }
08640     #endif
08641 
08642     #ifdef WOLFSSL_DTLS
08643 
08644         #ifndef NO_OLD_TLS
08645         WOLFSSL_METHOD* wolfDTLSv1_client_method_ex(void* heap)
08646         {
08647             WOLFSSL_METHOD* method =
08648                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
08649                                                      heap, DYNAMIC_TYPE_METHOD);
08650             WOLFSSL_ENTER("DTLSv1_client_method_ex");
08651             if (method)
08652                 InitSSL_Method(method, MakeDTLSv1());
08653             return method;
08654         }
08655         #endif  /* NO_OLD_TLS */
08656 
08657         WOLFSSL_METHOD* wolfDTLSv1_2_client_method_ex(void* heap)
08658         {
08659             WOLFSSL_METHOD* method =
08660                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
08661                                                      heap, DYNAMIC_TYPE_METHOD);
08662             WOLFSSL_ENTER("DTLSv1_2_client_method_ex");
08663             if (method)
08664                 InitSSL_Method(method, MakeDTLSv1_2());
08665             (void)heap;
08666             return method;
08667         }
08668     #endif
08669 
08670     /* If SCTP is not enabled returns the state of the dtls option.
08671      * If SCTP is enabled returns dtls && !sctp. */
08672     static WC_INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl)
08673     {
08674         int result = ssl->options.dtls;
08675 
08676         if (result) {
08677         #ifdef WOLFSSL_SCTP
08678             result = !ssl->options.dtlsSctp;
08679         #endif
08680         }
08681 
08682         return result;
08683     }
08684 
08685 
08686     /* please see note at top of README if you get an error from connect */
08687     int wolfSSL_connect(WOLFSSL* ssl)
08688     {
08689     #ifndef WOLFSSL_NO_TLS12
08690         int neededState;
08691     #endif
08692 
08693         WOLFSSL_ENTER("SSL_connect()");
08694 
08695         #ifdef HAVE_ERRNO_H
08696             errno = 0;
08697         #endif
08698 
08699         if (ssl == NULL)
08700             return BAD_FUNC_ARG;
08701 
08702         #ifdef OPENSSL_EXTRA
08703             if (ssl->CBIS != NULL) {
08704                 ssl->CBIS(ssl, SSL_ST_CONNECT, SSL_SUCCESS);
08705                 ssl->cbmode = SSL_CB_WRITE;
08706             }
08707         #endif
08708         if (ssl->options.side != WOLFSSL_CLIENT_END) {
08709             WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
08710             return WOLFSSL_FATAL_ERROR;
08711         }
08712 
08713     #ifdef WOLFSSL_NO_TLS12
08714         return wolfSSL_connect_TLSv13(ssl);
08715     #else
08716         #ifdef WOLFSSL_TLS13
08717             if (ssl->options.tls1_3)
08718                 return wolfSSL_connect_TLSv13(ssl);
08719         #endif
08720 
08721         #ifdef WOLFSSL_DTLS
08722             if (ssl->version.major == DTLS_MAJOR) {
08723                 ssl->options.dtls   = 1;
08724                 ssl->options.tls    = 1;
08725                 ssl->options.tls1_1 = 1;
08726             }
08727         #endif
08728 
08729         if (ssl->buffers.outputBuffer.length > 0) {
08730             if ( (ssl->error = SendBuffered(ssl)) == 0) {
08731                 /* fragOffset is non-zero when sending fragments. On the last
08732                  * fragment, fragOffset is zero again, and the state can be
08733                  * advanced. */
08734                 if (ssl->fragOffset == 0) {
08735                     ssl->options.connectState++;
08736                     WOLFSSL_MSG("connect state: "
08737                                 "Advanced from last buffered fragment send");
08738                 }
08739                 else {
08740                     WOLFSSL_MSG("connect state: "
08741                                 "Not advanced, more fragments to send");
08742                 }
08743             }
08744             else {
08745                 WOLFSSL_ERROR(ssl->error);
08746                 return WOLFSSL_FATAL_ERROR;
08747             }
08748         }
08749 
08750 #ifdef WOLFSSL_TLS13
08751         if (ssl->options.tls1_3)
08752             return wolfSSL_connect_TLSv13(ssl);
08753 #endif
08754 
08755         switch (ssl->options.connectState) {
08756 
08757         case CONNECT_BEGIN :
08758             /* always send client hello first */
08759             if ( (ssl->error = SendClientHello(ssl)) != 0) {
08760                 WOLFSSL_ERROR(ssl->error);
08761                 return WOLFSSL_FATAL_ERROR;
08762             }
08763             ssl->options.connectState = CLIENT_HELLO_SENT;
08764             WOLFSSL_MSG("connect state: CLIENT_HELLO_SENT");
08765             FALL_THROUGH;
08766 
08767         case CLIENT_HELLO_SENT :
08768             neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
08769                                           SERVER_HELLODONE_COMPLETE;
08770             #ifdef WOLFSSL_DTLS
08771                 /* In DTLS, when resuming, we can go straight to FINISHED,
08772                  * or do a cookie exchange and then skip to FINISHED, assume
08773                  * we need the cookie exchange first. */
08774                 if (IsDtlsNotSctpMode(ssl))
08775                     neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
08776             #endif
08777             /* get response */
08778             while (ssl->options.serverState < neededState) {
08779                 #ifdef WOLFSSL_TLS13
08780                     if (ssl->options.tls1_3)
08781                         return wolfSSL_connect_TLSv13(ssl);
08782                 #endif
08783                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
08784                     WOLFSSL_ERROR(ssl->error);
08785                     return WOLFSSL_FATAL_ERROR;
08786                 }
08787                 /* if resumption failed, reset needed state */
08788                 else if (neededState == SERVER_FINISHED_COMPLETE)
08789                     if (!ssl->options.resuming) {
08790                         if (!IsDtlsNotSctpMode(ssl))
08791                             neededState = SERVER_HELLODONE_COMPLETE;
08792                         else
08793                             neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
08794                     }
08795             }
08796 
08797             ssl->options.connectState = HELLO_AGAIN;
08798             WOLFSSL_MSG("connect state: HELLO_AGAIN");
08799             FALL_THROUGH;
08800 
08801         case HELLO_AGAIN :
08802             if (ssl->options.certOnly)
08803                 return WOLFSSL_SUCCESS;
08804 
08805         #ifdef WOLFSSL_TLS13
08806             if (ssl->options.tls1_3)
08807                 return wolfSSL_connect_TLSv13(ssl);
08808         #endif
08809 
08810             #ifdef WOLFSSL_DTLS
08811                 if (IsDtlsNotSctpMode(ssl)) {
08812                     /* re-init hashes, exclude first hello and verify request */
08813                     if ((ssl->error = InitHandshakeHashes(ssl)) != 0) {
08814                         WOLFSSL_ERROR(ssl->error);
08815                         return WOLFSSL_FATAL_ERROR;
08816                     }
08817                     if ( (ssl->error = SendClientHello(ssl)) != 0) {
08818                         WOLFSSL_ERROR(ssl->error);
08819                         return WOLFSSL_FATAL_ERROR;
08820                     }
08821                 }
08822             #endif
08823 
08824             ssl->options.connectState = HELLO_AGAIN_REPLY;
08825             WOLFSSL_MSG("connect state: HELLO_AGAIN_REPLY");
08826             FALL_THROUGH;
08827 
08828         case HELLO_AGAIN_REPLY :
08829             #ifdef WOLFSSL_DTLS
08830                 if (IsDtlsNotSctpMode(ssl)) {
08831                     neededState = ssl->options.resuming ?
08832                            SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
08833 
08834                     /* get response */
08835                     while (ssl->options.serverState < neededState) {
08836                         if ( (ssl->error = ProcessReply(ssl)) < 0) {
08837                             WOLFSSL_ERROR(ssl->error);
08838                             return WOLFSSL_FATAL_ERROR;
08839                         }
08840                         /* if resumption failed, reset needed state */
08841                         if (neededState == SERVER_FINISHED_COMPLETE) {
08842                             if (!ssl->options.resuming)
08843                                 neededState = SERVER_HELLODONE_COMPLETE;
08844                         }
08845                     }
08846                 }
08847             #endif
08848 
08849             ssl->options.connectState = FIRST_REPLY_DONE;
08850             WOLFSSL_MSG("connect state: FIRST_REPLY_DONE");
08851             FALL_THROUGH;
08852 
08853         case FIRST_REPLY_DONE :
08854             #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH)
08855                 #ifdef WOLFSSL_TLS13
08856                     if (ssl->options.tls1_3)
08857                         return wolfSSL_connect_TLSv13(ssl);
08858                 #endif
08859                 if (ssl->options.sendVerify) {
08860                     if ( (ssl->error = SendCertificate(ssl)) != 0) {
08861                         WOLFSSL_ERROR(ssl->error);
08862                         return WOLFSSL_FATAL_ERROR;
08863                     }
08864                     WOLFSSL_MSG("sent: certificate");
08865                 }
08866 
08867             #endif
08868             ssl->options.connectState = FIRST_REPLY_FIRST;
08869             WOLFSSL_MSG("connect state: FIRST_REPLY_FIRST");
08870             FALL_THROUGH;
08871 
08872         case FIRST_REPLY_FIRST :
08873         #ifdef WOLFSSL_TLS13
08874             if (ssl->options.tls1_3)
08875                 return wolfSSL_connect_TLSv13(ssl);
08876         #endif
08877             if (!ssl->options.resuming) {
08878                 if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
08879                     WOLFSSL_ERROR(ssl->error);
08880                     return WOLFSSL_FATAL_ERROR;
08881                 }
08882                 WOLFSSL_MSG("sent: client key exchange");
08883             }
08884 
08885             ssl->options.connectState = FIRST_REPLY_SECOND;
08886             WOLFSSL_MSG("connect state: FIRST_REPLY_SECOND");
08887             FALL_THROUGH;
08888 
08889         case FIRST_REPLY_SECOND :
08890             #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH)
08891                 if (ssl->options.sendVerify) {
08892                     if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
08893                         WOLFSSL_ERROR(ssl->error);
08894                         return WOLFSSL_FATAL_ERROR;
08895                     }
08896                     WOLFSSL_MSG("sent: certificate verify");
08897                 }
08898             #endif /* !NO_CERTS && !WOLFSSL_NO_CLIENT_AUTH */
08899             ssl->options.connectState = FIRST_REPLY_THIRD;
08900             WOLFSSL_MSG("connect state: FIRST_REPLY_THIRD");
08901             FALL_THROUGH;
08902 
08903         case FIRST_REPLY_THIRD :
08904             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
08905                 WOLFSSL_ERROR(ssl->error);
08906                 return WOLFSSL_FATAL_ERROR;
08907             }
08908             WOLFSSL_MSG("sent: change cipher spec");
08909             ssl->options.connectState = FIRST_REPLY_FOURTH;
08910             WOLFSSL_MSG("connect state: FIRST_REPLY_FOURTH");
08911             FALL_THROUGH;
08912 
08913         case FIRST_REPLY_FOURTH :
08914             if ( (ssl->error = SendFinished(ssl)) != 0) {
08915                 WOLFSSL_ERROR(ssl->error);
08916                 return WOLFSSL_FATAL_ERROR;
08917             }
08918             WOLFSSL_MSG("sent: finished");
08919             ssl->options.connectState = FINISHED_DONE;
08920             WOLFSSL_MSG("connect state: FINISHED_DONE");
08921             FALL_THROUGH;
08922 
08923         case FINISHED_DONE :
08924             /* get response */
08925             while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
08926                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
08927                     WOLFSSL_ERROR(ssl->error);
08928                     return WOLFSSL_FATAL_ERROR;
08929                 }
08930 
08931             ssl->options.connectState = SECOND_REPLY_DONE;
08932             WOLFSSL_MSG("connect state: SECOND_REPLY_DONE");
08933             FALL_THROUGH;
08934 
08935         case SECOND_REPLY_DONE:
08936 #ifndef NO_HANDSHAKE_DONE_CB
08937             if (ssl->hsDoneCb) {
08938                 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
08939                 if (cbret < 0) {
08940                     ssl->error = cbret;
08941                     WOLFSSL_MSG("HandShake Done Cb don't continue error");
08942                     return WOLFSSL_FATAL_ERROR;
08943                 }
08944             }
08945 #endif /* NO_HANDSHAKE_DONE_CB */
08946 
08947             if (!ssl->options.dtls) {
08948                 if (!ssl->options.keepResources) {
08949                     FreeHandshakeResources(ssl);
08950                 }
08951             }
08952 #ifdef WOLFSSL_DTLS
08953             else {
08954                 ssl->options.dtlsHsRetain = 1;
08955             }
08956 #endif /* WOLFSSL_DTLS */
08957 
08958             WOLFSSL_LEAVE("SSL_connect()", WOLFSSL_SUCCESS);
08959             return WOLFSSL_SUCCESS;
08960 
08961         default:
08962             WOLFSSL_MSG("Unknown connect state ERROR");
08963             return WOLFSSL_FATAL_ERROR; /* unknown connect state */
08964         }
08965     #endif /* !WOLFSSL_NO_TLS12 */
08966     }
08967 
08968 #endif /* NO_WOLFSSL_CLIENT */
08969 
08970 
08971 /* server only parts */
08972 #ifndef NO_WOLFSSL_SERVER
08973 
08974     #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
08975     WOLFSSL_METHOD* wolfSSLv3_server_method(void)
08976     {
08977         WOLFSSL_ENTER("SSLv3_server_method");
08978         return wolfSSLv3_server_method_ex(NULL);
08979     }
08980     #endif
08981 
08982 
08983     #ifdef WOLFSSL_DTLS
08984 
08985         #ifndef NO_OLD_TLS
08986         WOLFSSL_METHOD* wolfDTLSv1_server_method(void)
08987         {
08988             WOLFSSL_ENTER("DTLSv1_server_method");
08989             return wolfDTLSv1_server_method_ex(NULL);
08990         }
08991         #endif /* NO_OLD_TLS */
08992 
08993         WOLFSSL_METHOD* wolfDTLSv1_2_server_method(void)
08994         {
08995             WOLFSSL_ENTER("DTLSv1_2_server_method");
08996             return wolfDTLSv1_2_server_method_ex(NULL);
08997         }
08998     #endif
08999 
09000     #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
09001     WOLFSSL_METHOD* wolfSSLv3_server_method_ex(void* heap)
09002     {
09003         WOLFSSL_METHOD* method =
09004                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
09005                                                      heap, DYNAMIC_TYPE_METHOD);
09006         WOLFSSL_ENTER("SSLv3_server_method_ex");
09007         if (method) {
09008             InitSSL_Method(method, MakeSSLv3());
09009             method->side = WOLFSSL_SERVER_END;
09010         }
09011         return method;
09012     }
09013     #endif
09014 
09015 
09016     #ifdef WOLFSSL_DTLS
09017 
09018         #ifndef NO_OLD_TLS
09019         WOLFSSL_METHOD* wolfDTLSv1_server_method_ex(void* heap)
09020         {
09021             WOLFSSL_METHOD* method =
09022                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
09023                                                      heap, DYNAMIC_TYPE_METHOD);
09024             WOLFSSL_ENTER("DTLSv1_server_method_ex");
09025             if (method) {
09026                 InitSSL_Method(method, MakeDTLSv1());
09027                 method->side = WOLFSSL_SERVER_END;
09028             }
09029             return method;
09030         }
09031         #endif /* NO_OLD_TLS */
09032 
09033         WOLFSSL_METHOD* wolfDTLSv1_2_server_method_ex(void* heap)
09034         {
09035             WOLFSSL_METHOD* method =
09036                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
09037                                                      heap, DYNAMIC_TYPE_METHOD);
09038             WOLFSSL_ENTER("DTLSv1_2_server_method_ex");
09039             if (method) {
09040                 InitSSL_Method(method, MakeDTLSv1_2());
09041                 method->side = WOLFSSL_SERVER_END;
09042             }
09043             (void)heap;
09044             return method;
09045         }
09046     #endif
09047 
09048 
09049     int wolfSSL_accept(WOLFSSL* ssl)
09050     {
09051 #ifndef WOLFSSL_NO_TLS12
09052         word16 havePSK = 0;
09053         word16 haveAnon = 0;
09054         word16 haveMcast = 0;
09055 #endif
09056 
09057 #ifdef WOLFSSL_NO_TLS12
09058         return wolfSSL_accept_TLSv13(ssl);
09059 #else
09060     #ifdef WOLFSSL_TLS13
09061         if (ssl->options.tls1_3)
09062             return wolfSSL_accept_TLSv13(ssl);
09063     #endif
09064         WOLFSSL_ENTER("SSL_accept()");
09065 
09066         #ifdef HAVE_ERRNO_H
09067             errno = 0;
09068         #endif
09069 
09070         #ifndef NO_PSK
09071             havePSK = ssl->options.havePSK;
09072         #endif
09073         (void)havePSK;
09074 
09075         #ifdef HAVE_ANON
09076             haveAnon = ssl->options.haveAnon;
09077         #endif
09078         (void)haveAnon;
09079 
09080         #ifdef WOLFSSL_MULTICAST
09081             haveMcast = ssl->options.haveMcast;
09082         #endif
09083         (void)haveMcast;
09084 
09085         if (ssl->options.side != WOLFSSL_SERVER_END) {
09086             WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
09087             return WOLFSSL_FATAL_ERROR;
09088         }
09089 
09090     #ifndef NO_CERTS
09091         /* in case used set_accept_state after init */
09092         /* allow no private key if using PK callbacks and CB is set */
09093         if (!havePSK && !haveAnon && !haveMcast) {
09094             if (!ssl->buffers.certificate ||
09095                 !ssl->buffers.certificate->buffer) {
09096 
09097                 WOLFSSL_MSG("accept error: server cert required");
09098                 WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY);
09099                 return WOLFSSL_FATAL_ERROR;
09100             }
09101 
09102         #ifdef HAVE_PK_CALLBACKS
09103             if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) {
09104                 WOLFSSL_MSG("Using PK for server private key");
09105             }
09106             else
09107         #endif
09108             if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
09109                 WOLFSSL_MSG("accept error: server key required");
09110                 WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY);
09111                 return WOLFSSL_FATAL_ERROR;
09112             }
09113         }
09114     #endif
09115 
09116     #ifdef WOLFSSL_DTLS
09117         if (ssl->version.major == DTLS_MAJOR) {
09118             ssl->options.dtls   = 1;
09119             ssl->options.tls    = 1;
09120             ssl->options.tls1_1 = 1;
09121         }
09122     #endif
09123 
09124         if (ssl->buffers.outputBuffer.length > 0) {
09125             if ( (ssl->error = SendBuffered(ssl)) == 0) {
09126                 /* fragOffset is non-zero when sending fragments. On the last
09127                  * fragment, fragOffset is zero again, and the state can be
09128                  * advanced. */
09129                 if (ssl->fragOffset == 0) {
09130                     ssl->options.acceptState++;
09131                     WOLFSSL_MSG("accept state: "
09132                                 "Advanced from last buffered fragment send");
09133                 }
09134                 else {
09135                     WOLFSSL_MSG("accept state: "
09136                                 "Not advanced, more fragments to send");
09137                 }
09138             }
09139             else {
09140                 WOLFSSL_ERROR(ssl->error);
09141                 return WOLFSSL_FATAL_ERROR;
09142             }
09143         }
09144 
09145         switch (ssl->options.acceptState) {
09146 
09147         case ACCEPT_BEGIN :
09148             /* get response */
09149             while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
09150                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
09151                     WOLFSSL_ERROR(ssl->error);
09152                     return WOLFSSL_FATAL_ERROR;
09153                 }
09154 #ifdef WOLFSSL_TLS13
09155             ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
09156             WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
09157             FALL_THROUGH;
09158 
09159         case ACCEPT_CLIENT_HELLO_DONE :
09160             if (ssl->options.tls1_3) {
09161                 return wolfSSL_accept_TLSv13(ssl);
09162             }
09163 #endif
09164             ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
09165             WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
09166             FALL_THROUGH;
09167 
09168         case ACCEPT_FIRST_REPLY_DONE :
09169             if ( (ssl->error = SendServerHello(ssl)) != 0) {
09170                 WOLFSSL_ERROR(ssl->error);
09171                 return WOLFSSL_FATAL_ERROR;
09172             }
09173             ssl->options.acceptState = SERVER_HELLO_SENT;
09174             WOLFSSL_MSG("accept state SERVER_HELLO_SENT");
09175             FALL_THROUGH;
09176 
09177         case SERVER_HELLO_SENT :
09178         #ifdef WOLFSSL_TLS13
09179             if (ssl->options.tls1_3) {
09180                 return wolfSSL_accept_TLSv13(ssl);
09181             }
09182         #endif
09183             #ifndef NO_CERTS
09184                 if (!ssl->options.resuming)
09185                     if ( (ssl->error = SendCertificate(ssl)) != 0) {
09186                         WOLFSSL_ERROR(ssl->error);
09187                         return WOLFSSL_FATAL_ERROR;
09188                     }
09189             #endif
09190             ssl->options.acceptState = CERT_SENT;
09191             WOLFSSL_MSG("accept state CERT_SENT");
09192             FALL_THROUGH;
09193 
09194         case CERT_SENT :
09195             #ifndef NO_CERTS
09196             if (!ssl->options.resuming)
09197                 if ( (ssl->error = SendCertificateStatus(ssl)) != 0) {
09198                     WOLFSSL_ERROR(ssl->error);
09199                     return WOLFSSL_FATAL_ERROR;
09200                 }
09201             #endif
09202             ssl->options.acceptState = CERT_STATUS_SENT;
09203             WOLFSSL_MSG("accept state CERT_STATUS_SENT");
09204             FALL_THROUGH;
09205 
09206         case CERT_STATUS_SENT :
09207         #ifdef WOLFSSL_TLS13
09208             if (ssl->options.tls1_3) {
09209                 return wolfSSL_accept_TLSv13(ssl);
09210             }
09211         #endif
09212             if (!ssl->options.resuming)
09213                 if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
09214                     WOLFSSL_ERROR(ssl->error);
09215                     return WOLFSSL_FATAL_ERROR;
09216                 }
09217             ssl->options.acceptState = KEY_EXCHANGE_SENT;
09218             WOLFSSL_MSG("accept state KEY_EXCHANGE_SENT");
09219             FALL_THROUGH;
09220 
09221         case KEY_EXCHANGE_SENT :
09222             #ifndef NO_CERTS
09223                 if (!ssl->options.resuming) {
09224                     if (ssl->options.verifyPeer) {
09225                         if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
09226                             WOLFSSL_ERROR(ssl->error);
09227                             return WOLFSSL_FATAL_ERROR;
09228                         }
09229                     }
09230                 }
09231             #endif
09232             ssl->options.acceptState = CERT_REQ_SENT;
09233             WOLFSSL_MSG("accept state CERT_REQ_SENT");
09234             FALL_THROUGH;
09235 
09236         case CERT_REQ_SENT :
09237             if (!ssl->options.resuming)
09238                 if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
09239                     WOLFSSL_ERROR(ssl->error);
09240                     return WOLFSSL_FATAL_ERROR;
09241                 }
09242             ssl->options.acceptState = SERVER_HELLO_DONE;
09243             WOLFSSL_MSG("accept state SERVER_HELLO_DONE");
09244             FALL_THROUGH;
09245 
09246         case SERVER_HELLO_DONE :
09247             if (!ssl->options.resuming) {
09248                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
09249                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
09250                         WOLFSSL_ERROR(ssl->error);
09251                         return WOLFSSL_FATAL_ERROR;
09252                     }
09253             }
09254             ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
09255             WOLFSSL_MSG("accept state  ACCEPT_SECOND_REPLY_DONE");
09256             FALL_THROUGH;
09257 
09258         case ACCEPT_SECOND_REPLY_DONE :
09259 #ifdef HAVE_SESSION_TICKET
09260             if (ssl->options.createTicket) {
09261                 if ( (ssl->error = SendTicket(ssl)) != 0) {
09262                     WOLFSSL_ERROR(ssl->error);
09263                     return WOLFSSL_FATAL_ERROR;
09264                 }
09265             }
09266 #endif /* HAVE_SESSION_TICKET */
09267             ssl->options.acceptState = TICKET_SENT;
09268             WOLFSSL_MSG("accept state  TICKET_SENT");
09269             FALL_THROUGH;
09270 
09271         case TICKET_SENT:
09272             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
09273                 WOLFSSL_ERROR(ssl->error);
09274                 return WOLFSSL_FATAL_ERROR;
09275             }
09276             ssl->options.acceptState = CHANGE_CIPHER_SENT;
09277             WOLFSSL_MSG("accept state  CHANGE_CIPHER_SENT");
09278             FALL_THROUGH;
09279 
09280         case CHANGE_CIPHER_SENT :
09281             if ( (ssl->error = SendFinished(ssl)) != 0) {
09282                 WOLFSSL_ERROR(ssl->error);
09283                 return WOLFSSL_FATAL_ERROR;
09284             }
09285 
09286             ssl->options.acceptState = ACCEPT_FINISHED_DONE;
09287             WOLFSSL_MSG("accept state ACCEPT_FINISHED_DONE");
09288             FALL_THROUGH;
09289 
09290         case ACCEPT_FINISHED_DONE :
09291             if (ssl->options.resuming)
09292                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
09293                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
09294                         WOLFSSL_ERROR(ssl->error);
09295                         return WOLFSSL_FATAL_ERROR;
09296                     }
09297 
09298             ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
09299             WOLFSSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
09300             FALL_THROUGH;
09301 
09302         case ACCEPT_THIRD_REPLY_DONE :
09303 #ifndef NO_HANDSHAKE_DONE_CB
09304             if (ssl->hsDoneCb) {
09305                 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
09306                 if (cbret < 0) {
09307                     ssl->error = cbret;
09308                     WOLFSSL_MSG("HandShake Done Cb don't continue error");
09309                     return WOLFSSL_FATAL_ERROR;
09310                 }
09311             }
09312 #endif /* NO_HANDSHAKE_DONE_CB */
09313 
09314             if (!ssl->options.dtls) {
09315                 if (!ssl->options.keepResources) {
09316                     FreeHandshakeResources(ssl);
09317                 }
09318             }
09319 #ifdef WOLFSSL_DTLS
09320             else {
09321                 ssl->options.dtlsHsRetain = 1;
09322             }
09323 #endif /* WOLFSSL_DTLS */
09324 
09325 #ifdef WOLFSSL_SESSION_EXPORT
09326             if (ssl->dtls_export) {
09327                 if ((ssl->error = wolfSSL_send_session(ssl)) != 0) {
09328                     WOLFSSL_MSG("Export DTLS session error");
09329                     WOLFSSL_ERROR(ssl->error);
09330                     return WOLFSSL_FATAL_ERROR;
09331                 }
09332             }
09333 #endif
09334 
09335             WOLFSSL_LEAVE("SSL_accept()", WOLFSSL_SUCCESS);
09336             return WOLFSSL_SUCCESS;
09337 
09338         default :
09339             WOLFSSL_MSG("Unknown accept state ERROR");
09340             return WOLFSSL_FATAL_ERROR;
09341         }
09342 #endif /* !WOLFSSL_NO_TLS12 */
09343     }
09344 
09345 #endif /* NO_WOLFSSL_SERVER */
09346 
09347 
09348 #ifndef NO_HANDSHAKE_DONE_CB
09349 
09350 int wolfSSL_SetHsDoneCb(WOLFSSL* ssl, HandShakeDoneCb cb, void* user_ctx)
09351 {
09352     WOLFSSL_ENTER("wolfSSL_SetHsDoneCb");
09353 
09354     if (ssl == NULL)
09355         return BAD_FUNC_ARG;
09356 
09357     ssl->hsDoneCb  = cb;
09358     ssl->hsDoneCtx = user_ctx;
09359 
09360 
09361     return WOLFSSL_SUCCESS;
09362 }
09363 
09364 #endif /* NO_HANDSHAKE_DONE_CB */
09365 
09366 int wolfSSL_Cleanup(void)
09367 {
09368     int ret = WOLFSSL_SUCCESS;
09369     int release = 0;
09370 
09371     WOLFSSL_ENTER("wolfSSL_Cleanup");
09372 
09373     if (initRefCount == 0)
09374         return ret;  /* possibly no init yet, but not failure either way */
09375 
09376     if (wc_LockMutex(&count_mutex) != 0) {
09377         WOLFSSL_MSG("Bad Lock Mutex count");
09378         return BAD_MUTEX_E;
09379     }
09380 
09381     release = initRefCount-- == 1;
09382     if (initRefCount < 0)
09383         initRefCount = 0;
09384 
09385     wc_UnLockMutex(&count_mutex);
09386 
09387     if (!release)
09388         return ret;
09389 
09390 #ifndef NO_SESSION_CACHE
09391     if (wc_FreeMutex(&session_mutex) != 0)
09392         ret = BAD_MUTEX_E;
09393 #endif
09394     if (wc_FreeMutex(&count_mutex) != 0)
09395         ret = BAD_MUTEX_E;
09396 
09397     if (wolfCrypt_Cleanup() != 0) {
09398         WOLFSSL_MSG("Error with wolfCrypt_Cleanup call");
09399         ret = WC_CLEANUP_E;
09400     }
09401 
09402     return ret;
09403 }
09404 
09405 
09406 #ifndef NO_SESSION_CACHE
09407 
09408 
09409 /* some session IDs aren't random after all, let's make them random */
09410 static WC_INLINE word32 HashSession(const byte* sessionID, word32 len, int* error)
09411 {
09412     byte digest[WC_MAX_DIGEST_SIZE];
09413 
09414 #ifndef NO_MD5
09415     *error =  wc_Md5Hash(sessionID, len, digest);
09416 #elif !defined(NO_SHA)
09417     *error =  wc_ShaHash(sessionID, len, digest);
09418 #elif !defined(NO_SHA256)
09419     *error =  wc_Sha256Hash(sessionID, len, digest);
09420 #else
09421     #error "We need a digest to hash the session IDs"
09422 #endif
09423 
09424     return *error == 0 ? MakeWordFromHash(digest) : 0; /* 0 on failure */
09425 }
09426 
09427 
09428 void wolfSSL_flush_sessions(WOLFSSL_CTX* ctx, long tm)
09429 {
09430     /* static table now, no flushing needed */
09431     (void)ctx;
09432     (void)tm;
09433 }
09434 
09435 
09436 /* set ssl session timeout in seconds */
09437 int wolfSSL_set_timeout(WOLFSSL* ssl, unsigned int to)
09438 {
09439     if (ssl == NULL)
09440         return BAD_FUNC_ARG;
09441 
09442     if (to == 0)
09443         to = WOLFSSL_SESSION_TIMEOUT;
09444     ssl->timeout = to;
09445 
09446     return WOLFSSL_SUCCESS;
09447 }
09448 
09449 
09450 /* set ctx session timeout in seconds */
09451 int wolfSSL_CTX_set_timeout(WOLFSSL_CTX* ctx, unsigned int to)
09452 {
09453     if (ctx == NULL)
09454         return BAD_FUNC_ARG;
09455 
09456     if (to == 0)
09457         to = WOLFSSL_SESSION_TIMEOUT;
09458     ctx->timeout = to;
09459 
09460     return WOLFSSL_SUCCESS;
09461 }
09462 
09463 
09464 #ifndef NO_CLIENT_CACHE
09465 
09466 /* Get Session from Client cache based on id/len, return NULL on failure */
09467 WOLFSSL_SESSION* GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
09468 {
09469     WOLFSSL_SESSION* ret = NULL;
09470     word32          row;
09471     int             idx;
09472     int             count;
09473     int             error = 0;
09474 
09475     WOLFSSL_ENTER("GetSessionClient");
09476 
09477     if (ssl->ctx->sessionCacheOff)
09478         return NULL;
09479 
09480     if (ssl->options.side == WOLFSSL_SERVER_END)
09481         return NULL;
09482 
09483     len = min(SERVER_ID_LEN, (word32)len);
09484 
09485 #ifdef HAVE_EXT_CACHE
09486     if (ssl->ctx->get_sess_cb != NULL) {
09487         int copy = 0;
09488         ret = ssl->ctx->get_sess_cb(ssl, (byte*)id, len, &copy);
09489         if (ret != NULL)
09490             return ret;
09491     }
09492 
09493     if (ssl->ctx->internalCacheOff)
09494         return NULL;
09495 #endif
09496 
09497     row = HashSession(id, len, &error) % SESSION_ROWS;
09498     if (error != 0) {
09499         WOLFSSL_MSG("Hash session failed");
09500         return NULL;
09501     }
09502 
09503     if (wc_LockMutex(&session_mutex) != 0) {
09504         WOLFSSL_MSG("Lock session mutex failed");
09505         return NULL;
09506     }
09507 
09508     /* start from most recently used */
09509     count = min((word32)ClientCache[row].totalCount, SESSIONS_PER_ROW);
09510     idx = ClientCache[row].nextIdx - 1;
09511     if (idx < 0)
09512         idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
09513 
09514     for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
09515         WOLFSSL_SESSION* current;
09516         ClientSession   clSess;
09517 
09518         if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
09519             WOLFSSL_MSG("Bad idx");
09520             break;
09521         }
09522 
09523         clSess = ClientCache[row].Clients[idx];
09524 
09525         current = &SessionCache[clSess.serverRow].Sessions[clSess.serverIdx];
09526         if (XMEMCMP(current->serverID, id, len) == 0) {
09527             WOLFSSL_MSG("Found a serverid match for client");
09528             if (LowResTimer() < (current->bornOn + current->timeout)) {
09529                 WOLFSSL_MSG("Session valid");
09530                 ret = current;
09531                 break;
09532             } else {
09533                 WOLFSSL_MSG("Session timed out");  /* could have more for id */
09534             }
09535         } else {
09536             WOLFSSL_MSG("ServerID not a match from client table");
09537         }
09538     }
09539 
09540     wc_UnLockMutex(&session_mutex);
09541 
09542     return ret;
09543 }
09544 
09545 #endif /* NO_CLIENT_CACHE */
09546 
09547 /* Restore the master secret and session information for certificates.
09548  *
09549  * ssl                  The SSL/TLS object.
09550  * session              The cached session to restore.
09551  * masterSecret         The master secret from the cached session.
09552  * restoreSessionCerts  Restoring session certificates is required.
09553  */
09554 static WC_INLINE void RestoreSession(WOLFSSL* ssl, WOLFSSL_SESSION* session,
09555         byte* masterSecret, byte restoreSessionCerts)
09556 {
09557     (void)ssl;
09558     (void)restoreSessionCerts;
09559 
09560     if (masterSecret)
09561         XMEMCPY(masterSecret, session->masterSecret, SECRET_LEN);
09562 #ifdef SESSION_CERTS
09563     /* If set, we should copy the session certs into the ssl object
09564      * from the session we are returning so we can resume */
09565     if (restoreSessionCerts) {
09566         ssl->session.chain        = session->chain;
09567         ssl->session.version      = session->version;
09568         ssl->session.cipherSuite0 = session->cipherSuite0;
09569         ssl->session.cipherSuite  = session->cipherSuite;
09570     }
09571 #endif /* SESSION_CERTS */
09572 }
09573 
09574 WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
09575         byte restoreSessionCerts)
09576 {
09577     WOLFSSL_SESSION* ret = 0;
09578     const byte*  id = NULL;
09579     word32       row;
09580     int          idx;
09581     int          count;
09582     int          error = 0;
09583 
09584     (void)       restoreSessionCerts;
09585 
09586     if (ssl->options.sessionCacheOff)
09587         return NULL;
09588 
09589     if (ssl->options.haveSessionId == 0)
09590         return NULL;
09591 
09592 #ifdef HAVE_SESSION_TICKET
09593     if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
09594         return NULL;
09595 #endif
09596 
09597     if (ssl->arrays)
09598         id = ssl->arrays->sessionID;
09599     else
09600         id = ssl->session.sessionID;
09601 
09602 #ifdef HAVE_EXT_CACHE
09603     if (ssl->ctx->get_sess_cb != NULL) {
09604         int copy = 0;
09605         /* Attempt to retrieve the session from the external cache. */
09606         ret = ssl->ctx->get_sess_cb(ssl, (byte*)id, ID_LEN, &copy);
09607         if (ret != NULL) {
09608             RestoreSession(ssl, ret, masterSecret, restoreSessionCerts);
09609             return ret;
09610         }
09611     }
09612 
09613     if (ssl->ctx->internalCacheOff)
09614         return NULL;
09615 #endif
09616 
09617     row = HashSession(id, ID_LEN, &error) % SESSION_ROWS;
09618     if (error != 0) {
09619         WOLFSSL_MSG("Hash session failed");
09620         return NULL;
09621     }
09622 
09623     if (wc_LockMutex(&session_mutex) != 0)
09624         return 0;
09625 
09626     /* start from most recently used */
09627     count = min((word32)SessionCache[row].totalCount, SESSIONS_PER_ROW);
09628     idx = SessionCache[row].nextIdx - 1;
09629     if (idx < 0)
09630         idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
09631 
09632     for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
09633         WOLFSSL_SESSION* current;
09634 
09635         if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
09636             WOLFSSL_MSG("Bad idx");
09637             break;
09638         }
09639 
09640         current = &SessionCache[row].Sessions[idx];
09641         if (XMEMCMP(current->sessionID, id, ID_LEN) == 0) {
09642             WOLFSSL_MSG("Found a session match");
09643             if (LowResTimer() < (current->bornOn + current->timeout)) {
09644                 WOLFSSL_MSG("Session valid");
09645                 ret = current;
09646                 RestoreSession(ssl, ret, masterSecret, restoreSessionCerts);
09647             } else {
09648                 WOLFSSL_MSG("Session timed out");
09649             }
09650             break;  /* no more sessionIDs whether valid or not that match */
09651         } else {
09652             WOLFSSL_MSG("SessionID not a match at this idx");
09653         }
09654     }
09655 
09656     wc_UnLockMutex(&session_mutex);
09657 
09658     return ret;
09659 }
09660 
09661 
09662 static int GetDeepCopySession(WOLFSSL* ssl, WOLFSSL_SESSION* copyFrom)
09663 {
09664     WOLFSSL_SESSION* copyInto = &ssl->session;
09665     void* tmpBuff             = NULL;
09666     int ticketLen             = 0;
09667     int doDynamicCopy         = 0;
09668     int ret                   = WOLFSSL_SUCCESS;
09669 
09670     (void)ticketLen;
09671     (void)doDynamicCopy;
09672     (void)tmpBuff;
09673 
09674     if (!ssl || !copyFrom)
09675         return BAD_FUNC_ARG;
09676 
09677 #ifdef HAVE_SESSION_TICKET
09678     /* Free old dynamic ticket if we had one to avoid leak */
09679     if (copyInto->isDynamic) {
09680         XFREE(copyInto->ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09681         copyInto->ticket = copyInto->staticTicket;
09682         copyInto->isDynamic = 0;
09683     }
09684 #endif
09685 
09686     if (wc_LockMutex(&session_mutex) != 0)
09687         return BAD_MUTEX_E;
09688 
09689 #ifdef HAVE_SESSION_TICKET
09690     /* Size of ticket to alloc if needed; Use later for alloc outside lock */
09691     doDynamicCopy = copyFrom->isDynamic;
09692     ticketLen = copyFrom->ticketLen;
09693 #endif
09694 
09695     *copyInto = *copyFrom;
09696 
09697     /* Default ticket to non dynamic. This will avoid crash if we fail below */
09698 #ifdef HAVE_SESSION_TICKET
09699     copyInto->ticket = copyInto->staticTicket;
09700     copyInto->isDynamic = 0;
09701 #endif
09702 
09703     if (wc_UnLockMutex(&session_mutex) != 0) {
09704         return BAD_MUTEX_E;
09705     }
09706 
09707 #ifdef HAVE_SESSION_TICKET
09708 #ifdef WOLFSSL_TLS13
09709     if (wc_LockMutex(&session_mutex) != 0) {
09710         XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09711         return BAD_MUTEX_E;
09712     }
09713 
09714     copyInto->cipherSuite0   = copyFrom->cipherSuite0;
09715     copyInto->cipherSuite    = copyFrom->cipherSuite;
09716     copyInto->namedGroup     = copyFrom->namedGroup;
09717     copyInto->ticketSeen     = copyFrom->ticketSeen;
09718     copyInto->ticketAdd      = copyFrom->ticketAdd;
09719 #ifndef WOLFSSL_TLS13_DRAFT_18
09720     XMEMCPY(&copyInto->ticketNonce, &copyFrom->ticketNonce,
09721                                                            sizeof(TicketNonce));
09722 #endif
09723 #ifdef WOLFSSL_EARLY_DATA
09724     copyInto->maxEarlyDataSz = copyFrom->maxEarlyDataSz;
09725 #endif
09726     XMEMCPY(copyInto->masterSecret, copyFrom->masterSecret, SECRET_LEN);
09727 
09728     if (wc_UnLockMutex(&session_mutex) != 0) {
09729         if (ret == WOLFSSL_SUCCESS)
09730             ret = BAD_MUTEX_E;
09731     }
09732 #endif
09733     /* If doing dynamic copy, need to alloc outside lock, then inside a lock
09734      * confirm the size still matches and memcpy */
09735     if (doDynamicCopy) {
09736         tmpBuff = (byte*)XMALLOC(ticketLen, ssl->heap,
09737                                                      DYNAMIC_TYPE_SESSION_TICK);
09738         if (!tmpBuff)
09739             return MEMORY_ERROR;
09740 
09741         if (wc_LockMutex(&session_mutex) != 0) {
09742             XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09743             return BAD_MUTEX_E;
09744         }
09745 
09746         if (ticketLen != copyFrom->ticketLen) {
09747             /* Another thread modified the ssl-> session ticket during alloc.
09748              * Treat as error, since ticket different than when copy requested */
09749             ret = VAR_STATE_CHANGE_E;
09750         }
09751 
09752         if (ret == WOLFSSL_SUCCESS) {
09753             copyInto->ticket = (byte*)tmpBuff;
09754             copyInto->isDynamic = 1;
09755             XMEMCPY(copyInto->ticket, copyFrom->ticket, ticketLen);
09756         }
09757     } else {
09758         /* Need to ensure ticket pointer gets updated to own buffer
09759          * and is not pointing to buff of session copied from */
09760         copyInto->ticket = copyInto->staticTicket;
09761     }
09762 
09763     if (doDynamicCopy) {
09764         if (wc_UnLockMutex(&session_mutex) != 0) {
09765             if (ret == WOLFSSL_SUCCESS)
09766                 ret = BAD_MUTEX_E;
09767         }
09768     }
09769 
09770     if (ret != WOLFSSL_SUCCESS) {
09771         /* cleanup */
09772         if (tmpBuff)
09773             XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09774         copyInto->ticket = copyInto->staticTicket;
09775         copyInto->isDynamic = 0;
09776     }
09777 #endif /* HAVE_SESSION_TICKET */
09778     return ret;
09779 }
09780 
09781 
09782 int SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
09783 {
09784     if (ssl->options.sessionCacheOff)
09785         return WOLFSSL_FAILURE;
09786 
09787 #ifdef OPENSSL_EXTRA
09788     /* check for application context id */
09789     if (ssl->sessionCtxSz > 0) {
09790         if (XMEMCMP(ssl->sessionCtx, session->sessionCtx, ssl->sessionCtxSz)) {
09791             /* context id did not match! */
09792             WOLFSSL_MSG("Session context did not match");
09793             return SSL_FAILURE;
09794         }
09795     }
09796 #endif /* OPENSSL_EXTRA */
09797 
09798     if (LowResTimer() < (session->bornOn + session->timeout)) {
09799         int ret = GetDeepCopySession(ssl, session);
09800         if (ret == WOLFSSL_SUCCESS) {
09801             ssl->options.resuming = 1;
09802 
09803 #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
09804                                defined(HAVE_SESSION_TICKET))
09805             ssl->version              = session->version;
09806             ssl->options.cipherSuite0 = session->cipherSuite0;
09807             ssl->options.cipherSuite  = session->cipherSuite;
09808 #endif
09809         }
09810 
09811         return ret;
09812     }
09813     return WOLFSSL_FAILURE;  /* session timed out */
09814 }
09815 
09816 
09817 #ifdef WOLFSSL_SESSION_STATS
09818 static int get_locked_session_stats(word32* active, word32* total,
09819                                     word32* peak);
09820 #endif
09821 
09822 int AddSession(WOLFSSL* ssl)
09823 {
09824     word32 row = 0;
09825     word32 idx = 0;
09826     int    error = 0;
09827 #ifdef HAVE_SESSION_TICKET
09828     byte*  tmpBuff = NULL;
09829     int    ticLen  = 0;
09830 #endif
09831     WOLFSSL_SESSION* session;
09832 
09833     if (ssl->options.sessionCacheOff)
09834         return 0;
09835 
09836     if (ssl->options.haveSessionId == 0)
09837         return 0;
09838 
09839 #ifdef HAVE_SESSION_TICKET
09840     if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
09841         return 0;
09842 #endif
09843 
09844 #ifdef HAVE_SESSION_TICKET
09845     ticLen = ssl->session.ticketLen;
09846     /* Alloc Memory here so if Malloc fails can exit outside of lock */
09847     if(ticLen > SESSION_TICKET_LEN) {
09848         tmpBuff = (byte*)XMALLOC(ticLen, ssl->heap,
09849                 DYNAMIC_TYPE_SESSION_TICK);
09850         if(!tmpBuff)
09851             return MEMORY_E;
09852     }
09853 #endif
09854 
09855 #ifdef HAVE_EXT_CACHE
09856     if (ssl->options.internalCacheOff) {
09857         /* Create a new session object to be stored. */
09858         session = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), NULL,
09859                                             DYNAMIC_TYPE_OPENSSL);
09860         if (session == NULL) {
09861 #ifdef HAVE_SESSION_TICKET
09862             XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09863 #endif
09864             return MEMORY_E;
09865         }
09866         XMEMSET(session, 0, sizeof(WOLFSSL_SESSION));
09867         session->isAlloced = 1;
09868     }
09869     else
09870 #endif
09871     {
09872         /* Use the session object in the cache for external cache if required.
09873          */
09874         row = HashSession(ssl->arrays->sessionID, ID_LEN, &error) %
09875                 SESSION_ROWS;
09876         if (error != 0) {
09877             WOLFSSL_MSG("Hash session failed");
09878 #ifdef HAVE_SESSION_TICKET
09879             XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09880 #endif
09881             return error;
09882         }
09883 
09884         if (wc_LockMutex(&session_mutex) != 0) {
09885 #ifdef HAVE_SESSION_TICKET
09886             XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09887 #endif
09888             return BAD_MUTEX_E;
09889         }
09890 
09891         idx = SessionCache[row].nextIdx++;
09892 #ifdef SESSION_INDEX
09893         ssl->sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx;
09894 #endif
09895         session = &SessionCache[row].Sessions[idx];
09896     }
09897 
09898     if (!ssl->options.tls1_3)
09899         XMEMCPY(session->masterSecret, ssl->arrays->masterSecret, SECRET_LEN);
09900     else
09901         XMEMCPY(session->masterSecret, ssl->session.masterSecret, SECRET_LEN);
09902     session->haveEMS = ssl->options.haveEMS;
09903     XMEMCPY(session->sessionID, ssl->arrays->sessionID, ID_LEN);
09904     session->sessionIDSz = ssl->arrays->sessionIDSz;
09905 
09906 #ifdef OPENSSL_EXTRA
09907     /* If using compatibilty layer then check for and copy over session context
09908      * id. */
09909     if (ssl->sessionCtxSz > 0 && ssl->sessionCtxSz < ID_LEN) {
09910         XMEMCPY(session->sessionCtx, ssl->sessionCtx, ssl->sessionCtxSz);
09911     }
09912 #endif
09913 
09914     session->timeout = ssl->timeout;
09915     session->bornOn  = LowResTimer();
09916 
09917 #ifdef HAVE_SESSION_TICKET
09918     /* Check if another thread modified ticket since alloc */
09919     if (ticLen != ssl->session.ticketLen) {
09920         error = VAR_STATE_CHANGE_E;
09921     }
09922 
09923     if (error == 0) {
09924         /* Cleanup cache row's old Dynamic buff if exists */
09925         if(session->isDynamic) {
09926             XFREE(session->ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09927             session->ticket = NULL;
09928         }
09929 
09930         /* If too large to store in static buffer, use dyn buffer */
09931         if (ticLen > SESSION_TICKET_LEN) {
09932             session->ticket = tmpBuff;
09933             session->isDynamic = 1;
09934         } else {
09935             session->ticket = session->staticTicket;
09936             session->isDynamic = 0;
09937         }
09938     }
09939 
09940     if (error == 0) {
09941         session->ticketLen = (word16)ticLen;
09942         XMEMCPY(session->ticket, ssl->session.ticket, ticLen);
09943     } else { /* cleanup, reset state */
09944         session->ticket    = session->staticTicket;
09945         session->isDynamic = 0;
09946         session->ticketLen = 0;
09947         if (tmpBuff) {
09948             XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09949             tmpBuff = NULL;
09950         }
09951     }
09952 #endif
09953 
09954 #ifdef SESSION_CERTS
09955     if (error == 0) {
09956         session->chain.count = ssl->session.chain.count;
09957         XMEMCPY(session->chain.certs, ssl->session.chain.certs,
09958                 sizeof(x509_buffer) * MAX_CHAIN_DEPTH);
09959     }
09960 #endif /* SESSION_CERTS */
09961 #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
09962                                defined(HAVE_SESSION_TICKET))
09963     if (error == 0) {
09964         session->version      = ssl->version;
09965         session->cipherSuite0 = ssl->options.cipherSuite0;
09966         session->cipherSuite  = ssl->options.cipherSuite;
09967     }
09968 #endif /* SESSION_CERTS || (WOLFSSL_TLS13 & HAVE_SESSION_TICKET) */
09969 #if defined(WOLFSSL_TLS13)
09970     if (error == 0) {
09971         session->namedGroup     = ssl->session.namedGroup;
09972     }
09973 #endif
09974 #if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
09975     if (error == 0) {
09976         session->ticketSeen     = ssl->session.ticketSeen;
09977         session->ticketAdd      = ssl->session.ticketAdd;
09978 #ifndef WOLFSSL_TLS13_DRAFT_18
09979         XMEMCPY(&session->ticketNonce, &ssl->session.ticketNonce,
09980                                                            sizeof(TicketNonce));
09981 #endif
09982     #ifdef WOLFSSL_EARLY_DATA
09983         session->maxEarlyDataSz = ssl->session.maxEarlyDataSz;
09984     #endif
09985     }
09986 #endif /* WOLFSSL_TLS13 && HAVE_SESSION_TICKET */
09987 #ifdef HAVE_EXT_CACHE
09988     if (!ssl->options.internalCacheOff)
09989 #endif
09990     {
09991         if (error == 0) {
09992             SessionCache[row].totalCount++;
09993             if (SessionCache[row].nextIdx == SESSIONS_PER_ROW)
09994                 SessionCache[row].nextIdx = 0;
09995         }
09996     }
09997 #ifndef NO_CLIENT_CACHE
09998     if (error == 0) {
09999         if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->session.idLen) {
10000             word32 clientRow, clientIdx;
10001 
10002             WOLFSSL_MSG("Adding client cache entry");
10003 
10004             session->idLen = ssl->session.idLen;
10005             XMEMCPY(session->serverID, ssl->session.serverID,
10006                     ssl->session.idLen);
10007 
10008 #ifdef HAVE_EXT_CACHE
10009             if (!ssl->options.internalCacheOff)
10010 #endif
10011             {
10012                 clientRow = HashSession(ssl->session.serverID,
10013                         ssl->session.idLen, &error) % SESSION_ROWS;
10014                 if (error != 0) {
10015                     WOLFSSL_MSG("Hash session failed");
10016                 } else {
10017                     clientIdx = ClientCache[clientRow].nextIdx++;
10018 
10019                     ClientCache[clientRow].Clients[clientIdx].serverRow =
10020                                                                    (word16)row;
10021                     ClientCache[clientRow].Clients[clientIdx].serverIdx =
10022                                                                    (word16)idx;
10023 
10024                     ClientCache[clientRow].totalCount++;
10025                     if (ClientCache[clientRow].nextIdx == SESSIONS_PER_ROW)
10026                         ClientCache[clientRow].nextIdx = 0;
10027                 }
10028             }
10029         }
10030         else
10031             session->idLen = 0;
10032     }
10033 #endif /* NO_CLIENT_CACHE */
10034 
10035 #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
10036 #ifdef HAVE_EXT_CACHE
10037     if (!ssl->options.internalCacheOff)
10038 #endif
10039     {
10040         if (error == 0) {
10041             word32 active = 0;
10042 
10043             error = get_locked_session_stats(&active, NULL, NULL);
10044             if (error == WOLFSSL_SUCCESS) {
10045                 error = 0;  /* back to this function ok */
10046 
10047                 if (active > PeakSessions)
10048                     PeakSessions = active;
10049             }
10050         }
10051     }
10052 #endif /* defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS) */
10053 
10054 #ifdef HAVE_EXT_CACHE
10055     if (!ssl->options.internalCacheOff)
10056 #endif
10057     {
10058         if (wc_UnLockMutex(&session_mutex) != 0)
10059             return BAD_MUTEX_E;
10060     }
10061 
10062 #ifdef HAVE_EXT_CACHE
10063     if (error == 0 && ssl->ctx->new_sess_cb != NULL)
10064         ssl->ctx->new_sess_cb(ssl, session);
10065     if (ssl->options.internalCacheOff)
10066         wolfSSL_SESSION_free(session);
10067 #endif
10068 
10069     return error;
10070 }
10071 
10072 
10073 #ifdef SESSION_INDEX
10074 
10075 int wolfSSL_GetSessionIndex(WOLFSSL* ssl)
10076 {
10077     WOLFSSL_ENTER("wolfSSL_GetSessionIndex");
10078     WOLFSSL_LEAVE("wolfSSL_GetSessionIndex", ssl->sessionIndex);
10079     return ssl->sessionIndex;
10080 }
10081 
10082 
10083 int wolfSSL_GetSessionAtIndex(int idx, WOLFSSL_SESSION* session)
10084 {
10085     int row, col, result = WOLFSSL_FAILURE;
10086 
10087     WOLFSSL_ENTER("wolfSSL_GetSessionAtIndex");
10088 
10089     row = idx >> SESSIDX_ROW_SHIFT;
10090     col = idx & SESSIDX_IDX_MASK;
10091 
10092     if (wc_LockMutex(&session_mutex) != 0) {
10093         return BAD_MUTEX_E;
10094     }
10095 
10096     if (row < SESSION_ROWS &&
10097         col < (int)min(SessionCache[row].totalCount, SESSIONS_PER_ROW)) {
10098         XMEMCPY(session,
10099                  &SessionCache[row].Sessions[col], sizeof(WOLFSSL_SESSION));
10100         result = WOLFSSL_SUCCESS;
10101     }
10102 
10103     if (wc_UnLockMutex(&session_mutex) != 0)
10104         result = BAD_MUTEX_E;
10105 
10106     WOLFSSL_LEAVE("wolfSSL_GetSessionAtIndex", result);
10107     return result;
10108 }
10109 
10110 #endif /* SESSION_INDEX */
10111 
10112 #if defined(SESSION_INDEX) && defined(SESSION_CERTS)
10113 
10114 WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session)
10115 {
10116     WOLFSSL_X509_CHAIN* chain = NULL;
10117 
10118     WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
10119     if (session)
10120         chain = &session->chain;
10121 
10122     WOLFSSL_LEAVE("wolfSSL_SESSION_get_peer_chain", chain ? 1 : 0);
10123     return chain;
10124 }
10125 
10126 #endif /* SESSION_INDEX && SESSION_CERTS */
10127 
10128 
10129 #ifdef WOLFSSL_SESSION_STATS
10130 
10131 /* requires session_mutex lock held, WOLFSSL_SUCCESS on ok */
10132 static int get_locked_session_stats(word32* active, word32* total, word32* peak)
10133 {
10134     int result = WOLFSSL_SUCCESS;
10135     int i;
10136     int count;
10137     int idx;
10138     word32 now   = 0;
10139     word32 seen  = 0;
10140     word32 ticks = LowResTimer();
10141 
10142     (void)peak;
10143 
10144     WOLFSSL_ENTER("get_locked_session_stats");
10145 
10146     for (i = 0; i < SESSION_ROWS; i++) {
10147         seen += SessionCache[i].totalCount;
10148 
10149         if (active == NULL)
10150             continue;  /* no need to calculate what we can't set */
10151 
10152         count = min((word32)SessionCache[i].totalCount, SESSIONS_PER_ROW);
10153         idx   = SessionCache[i].nextIdx - 1;
10154         if (idx < 0)
10155             idx = SESSIONS_PER_ROW - 1; /* if back to front previous was end */
10156 
10157         for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
10158             if (idx >= SESSIONS_PER_ROW || idx < 0) {  /* sanity check */
10159                 WOLFSSL_MSG("Bad idx");
10160                 break;
10161             }
10162 
10163             /* if not expried then good */
10164             if (ticks < (SessionCache[i].Sessions[idx].bornOn +
10165                          SessionCache[i].Sessions[idx].timeout) ) {
10166                 now++;
10167             }
10168         }
10169     }
10170 
10171     if (active)
10172         *active = now;
10173 
10174     if (total)
10175         *total = seen;
10176 
10177 #ifdef WOLFSSL_PEAK_SESSIONS
10178     if (peak)
10179         *peak = PeakSessions;
10180 #endif
10181 
10182     WOLFSSL_LEAVE("get_locked_session_stats", result);
10183 
10184     return result;
10185 }
10186 
10187 
10188 /* return WOLFSSL_SUCCESS on ok */
10189 int wolfSSL_get_session_stats(word32* active, word32* total, word32* peak,
10190                               word32* maxSessions)
10191 {
10192     int result = WOLFSSL_SUCCESS;
10193 
10194     WOLFSSL_ENTER("wolfSSL_get_session_stats");
10195 
10196     if (maxSessions) {
10197         *maxSessions = SESSIONS_PER_ROW * SESSION_ROWS;
10198 
10199         if (active == NULL && total == NULL && peak == NULL)
10200             return result;  /* we're done */
10201     }
10202 
10203     /* user must provide at least one query value */
10204     if (active == NULL && total == NULL && peak == NULL)
10205         return BAD_FUNC_ARG;
10206 
10207     if (wc_LockMutex(&session_mutex) != 0) {
10208         return BAD_MUTEX_E;
10209     }
10210 
10211     result = get_locked_session_stats(active, total, peak);
10212 
10213     if (wc_UnLockMutex(&session_mutex) != 0)
10214         result = BAD_MUTEX_E;
10215 
10216     WOLFSSL_LEAVE("wolfSSL_get_session_stats", result);
10217 
10218     return result;
10219 }
10220 
10221 #endif /* WOLFSSL_SESSION_STATS */
10222 
10223 
10224     #ifdef PRINT_SESSION_STATS
10225 
10226     /* WOLFSSL_SUCCESS on ok */
10227     int wolfSSL_PrintSessionStats(void)
10228     {
10229         word32 totalSessionsSeen = 0;
10230         word32 totalSessionsNow = 0;
10231         word32 peak = 0;
10232         word32 maxSessions = 0;
10233         int    i;
10234         int    ret;
10235         double E;               /* expected freq */
10236         double chiSquare = 0;
10237 
10238         ret = wolfSSL_get_session_stats(&totalSessionsNow, &totalSessionsSeen,
10239                                         &peak, &maxSessions);
10240         if (ret != WOLFSSL_SUCCESS)
10241             return ret;
10242         printf("Total Sessions Seen = %d\n", totalSessionsSeen);
10243         printf("Total Sessions Now  = %d\n", totalSessionsNow);
10244 #ifdef WOLFSSL_PEAK_SESSIONS
10245         printf("Peak  Sessions      = %d\n", peak);
10246 #endif
10247         printf("Max   Sessions      = %d\n", maxSessions);
10248 
10249         E = (double)totalSessionsSeen / SESSION_ROWS;
10250 
10251         for (i = 0; i < SESSION_ROWS; i++) {
10252             double diff = SessionCache[i].totalCount - E;
10253             diff *= diff;                /* square    */
10254             diff /= E;                   /* normalize */
10255 
10256             chiSquare += diff;
10257         }
10258         printf("  chi-square = %5.1f, d.f. = %d\n", chiSquare,
10259                                                      SESSION_ROWS - 1);
10260         #if (SESSION_ROWS == 11)
10261             printf(" .05 p value =  18.3, chi-square should be less\n");
10262         #elif (SESSION_ROWS == 211)
10263             printf(".05 p value  = 244.8, chi-square should be less\n");
10264         #elif (SESSION_ROWS == 5981)
10265             printf(".05 p value  = 6161.0, chi-square should be less\n");
10266         #elif (SESSION_ROWS == 3)
10267             printf(".05 p value  =   6.0, chi-square should be less\n");
10268         #elif (SESSION_ROWS == 2861)
10269             printf(".05 p value  = 2985.5, chi-square should be less\n");
10270         #endif
10271         printf("\n");
10272 
10273         return ret;
10274     }
10275 
10276     #endif /* SESSION_STATS */
10277 
10278 #else  /* NO_SESSION_CACHE */
10279 
10280 /* No session cache version */
10281 WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
10282         byte restoreSessionCerts)
10283 {
10284     (void)ssl;
10285     (void)masterSecret;
10286     (void)restoreSessionCerts;
10287 
10288     return NULL;
10289 }
10290 
10291 #endif /* NO_SESSION_CACHE */
10292 
10293 
10294 /* call before SSL_connect, if verifying will add name check to
10295    date check and signature check */
10296 int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
10297 {
10298     WOLFSSL_ENTER("wolfSSL_check_domain_name");
10299 
10300     if (ssl == NULL || dn == NULL) {
10301         WOLFSSL_MSG("Bad function argument: NULL");
10302         return WOLFSSL_FAILURE;
10303     }
10304 
10305     if (ssl->buffers.domainName.buffer)
10306         XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
10307 
10308     ssl->buffers.domainName.length = (word32)XSTRLEN(dn);
10309     ssl->buffers.domainName.buffer = (byte*)XMALLOC(
10310             ssl->buffers.domainName.length + 1, ssl->heap, DYNAMIC_TYPE_DOMAIN);
10311 
10312     if (ssl->buffers.domainName.buffer) {
10313         char* domainName = (char*)ssl->buffers.domainName.buffer;
10314         XSTRNCPY(domainName, dn, ssl->buffers.domainName.length);
10315         domainName[ssl->buffers.domainName.length] = '\0';
10316         return WOLFSSL_SUCCESS;
10317     }
10318     else {
10319         ssl->error = MEMORY_ERROR;
10320         return WOLFSSL_FAILURE;
10321     }
10322 }
10323 
10324 
10325 /* turn on wolfSSL zlib compression
10326    returns WOLFSSL_SUCCESS for success, else error (not built in)
10327 */
10328 int wolfSSL_set_compression(WOLFSSL* ssl)
10329 {
10330     WOLFSSL_ENTER("wolfSSL_set_compression");
10331     (void)ssl;
10332 #ifdef HAVE_LIBZ
10333     ssl->options.usingCompression = 1;
10334     return WOLFSSL_SUCCESS;
10335 #else
10336     return NOT_COMPILED_IN;
10337 #endif
10338 }
10339 
10340 
10341 #ifndef USE_WINDOWS_API
10342     #ifndef NO_WRITEV
10343 
10344         /* simulate writev semantics, doesn't actually do block at a time though
10345            because of SSL_write behavior and because front adds may be small */
10346         int wolfSSL_writev(WOLFSSL* ssl, const struct iovec* iov, int iovcnt)
10347         {
10348         #ifdef WOLFSSL_SMALL_STACK
10349             byte   staticBuffer[1]; /* force heap usage */
10350         #else
10351             byte   staticBuffer[FILE_BUFFER_SIZE];
10352         #endif
10353             byte* myBuffer  = staticBuffer;
10354             int   dynamic   = 0;
10355             int   sending   = 0;
10356             int   idx       = 0;
10357             int   i;
10358             int   ret;
10359 
10360             WOLFSSL_ENTER("wolfSSL_writev");
10361 
10362             for (i = 0; i < iovcnt; i++)
10363                 sending += (int)iov[i].iov_len;
10364 
10365             if (sending > (int)sizeof(staticBuffer)) {
10366                 myBuffer = (byte*)XMALLOC(sending, ssl->heap,
10367                                                            DYNAMIC_TYPE_WRITEV);
10368                 if (!myBuffer)
10369                     return MEMORY_ERROR;
10370 
10371                 dynamic = 1;
10372             }
10373 
10374             for (i = 0; i < iovcnt; i++) {
10375                 XMEMCPY(&myBuffer[idx], iov[i].iov_base, iov[i].iov_len);
10376                 idx += (int)iov[i].iov_len;
10377             }
10378 
10379             ret = wolfSSL_write(ssl, myBuffer, sending);
10380 
10381             if (dynamic)
10382                 XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
10383 
10384             return ret;
10385         }
10386     #endif
10387 #endif
10388 
10389 
10390 #ifdef WOLFSSL_CALLBACKS
10391 
10392     typedef struct itimerval Itimerval;
10393 
10394     /* don't keep calling simple functions while setting up timer and signals
10395        if no inlining these are the next best */
10396 
10397     #define AddTimes(a, b, c)                       \
10398         do {                                        \
10399             c.tv_sec  = a.tv_sec  + b.tv_sec;       \
10400             c.tv_usec = a.tv_usec + b.tv_usec;      \
10401             if (c.tv_usec >=  1000000) {            \
10402                 c.tv_sec++;                         \
10403                 c.tv_usec -= 1000000;               \
10404             }                                       \
10405         } while (0)
10406 
10407 
10408     #define SubtractTimes(a, b, c)                  \
10409         do {                                        \
10410             c.tv_sec  = a.tv_sec  - b.tv_sec;       \
10411             c.tv_usec = a.tv_usec - b.tv_usec;      \
10412             if (c.tv_usec < 0) {                    \
10413                 c.tv_sec--;                         \
10414                 c.tv_usec += 1000000;               \
10415             }                                       \
10416         } while (0)
10417 
10418     #define CmpTimes(a, b, cmp)                     \
10419         ((a.tv_sec  ==  b.tv_sec) ?                 \
10420             (a.tv_usec cmp b.tv_usec) :             \
10421             (a.tv_sec  cmp b.tv_sec))               \
10422 
10423 
10424     /* do nothing handler */
10425     static void myHandler(int signo)
10426     {
10427         (void)signo;
10428         return;
10429     }
10430 
10431 
10432     static int wolfSSL_ex_wrapper(WOLFSSL* ssl, HandShakeCallBack hsCb,
10433                                  TimeoutCallBack toCb, Timeval timeout)
10434     {
10435         int       ret        = WOLFSSL_FATAL_ERROR;
10436         int       oldTimerOn = 0;   /* was timer already on */
10437         Timeval   startTime;
10438         Timeval   endTime;
10439         Timeval   totalTime;
10440         Itimerval myTimeout;
10441         Itimerval oldTimeout; /* if old timer adjust from total time to reset */
10442         struct sigaction act, oact;
10443 
10444         #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
10445 
10446         if (hsCb) {
10447             ssl->hsInfoOn = 1;
10448             InitHandShakeInfo(&ssl->handShakeInfo, ssl);
10449         }
10450         if (toCb) {
10451             ssl->toInfoOn = 1;
10452             InitTimeoutInfo(&ssl->timeoutInfo);
10453 
10454             if (gettimeofday(&startTime, 0) < 0)
10455                 ERR_OUT(GETTIME_ERROR);
10456 
10457             /* use setitimer to simulate getitimer, init 0 myTimeout */
10458             myTimeout.it_interval.tv_sec  = 0;
10459             myTimeout.it_interval.tv_usec = 0;
10460             myTimeout.it_value.tv_sec     = 0;
10461             myTimeout.it_value.tv_usec    = 0;
10462             if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
10463                 ERR_OUT(SETITIMER_ERROR);
10464 
10465             if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
10466                 oldTimerOn = 1;
10467 
10468                 /* is old timer going to expire before ours */
10469                 if (CmpTimes(oldTimeout.it_value, timeout, <)) {
10470                     timeout.tv_sec  = oldTimeout.it_value.tv_sec;
10471                     timeout.tv_usec = oldTimeout.it_value.tv_usec;
10472                 }
10473             }
10474             myTimeout.it_value.tv_sec  = timeout.tv_sec;
10475             myTimeout.it_value.tv_usec = timeout.tv_usec;
10476 
10477             /* set up signal handler, don't restart socket send/recv */
10478             act.sa_handler = myHandler;
10479             sigemptyset(&act.sa_mask);
10480             act.sa_flags = 0;
10481 #ifdef SA_INTERRUPT
10482             act.sa_flags |= SA_INTERRUPT;
10483 #endif
10484             if (sigaction(SIGALRM, &act, &oact) < 0)
10485                 ERR_OUT(SIGACT_ERROR);
10486 
10487             if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
10488                 ERR_OUT(SETITIMER_ERROR);
10489         }
10490 
10491         /* do main work */
10492 #ifndef NO_WOLFSSL_CLIENT
10493         if (ssl->options.side == WOLFSSL_CLIENT_END)
10494             ret = wolfSSL_connect(ssl);
10495 #endif
10496 #ifndef NO_WOLFSSL_SERVER
10497         if (ssl->options.side == WOLFSSL_SERVER_END)
10498             ret = wolfSSL_accept(ssl);
10499 #endif
10500 
10501         /* do callbacks */
10502         if (toCb) {
10503             if (oldTimerOn) {
10504                 gettimeofday(&endTime, 0);
10505                 SubtractTimes(endTime, startTime, totalTime);
10506                 /* adjust old timer for elapsed time */
10507                 if (CmpTimes(totalTime, oldTimeout.it_value, <))
10508                     SubtractTimes(oldTimeout.it_value, totalTime,
10509                                   oldTimeout.it_value);
10510                 else {
10511                     /* reset value to interval, may be off */
10512                     oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
10513                     oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
10514                 }
10515                 /* keep iter the same whether there or not */
10516             }
10517             /* restore old handler */
10518             if (sigaction(SIGALRM, &oact, 0) < 0)
10519                 ret = SIGACT_ERROR;    /* more pressing error, stomp */
10520             else
10521                 /* use old settings which may turn off (expired or not there) */
10522                 if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
10523                     ret = SETITIMER_ERROR;
10524 
10525             /* if we had a timeout call callback */
10526             if (ssl->timeoutInfo.timeoutName[0]) {
10527                 ssl->timeoutInfo.timeoutValue.tv_sec  = timeout.tv_sec;
10528                 ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
10529                 (toCb)(&ssl->timeoutInfo);
10530             }
10531             /* clean up */
10532             FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
10533             ssl->toInfoOn = 0;
10534         }
10535         if (hsCb) {
10536             FinishHandShakeInfo(&ssl->handShakeInfo);
10537             (hsCb)(&ssl->handShakeInfo);
10538             ssl->hsInfoOn = 0;
10539         }
10540         return ret;
10541     }
10542 
10543 
10544 #ifndef NO_WOLFSSL_CLIENT
10545 
10546     int wolfSSL_connect_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
10547                           TimeoutCallBack toCb, Timeval timeout)
10548     {
10549         WOLFSSL_ENTER("wolfSSL_connect_ex");
10550         return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
10551     }
10552 
10553 #endif
10554 
10555 
10556 #ifndef NO_WOLFSSL_SERVER
10557 
10558     int wolfSSL_accept_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
10559                          TimeoutCallBack toCb,Timeval timeout)
10560     {
10561         WOLFSSL_ENTER("wolfSSL_accept_ex");
10562         return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
10563     }
10564 
10565 #endif
10566 
10567 #endif /* WOLFSSL_CALLBACKS */
10568 
10569 
10570 #ifndef NO_PSK
10571 
10572     void wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX* ctx,
10573                                          wc_psk_client_callback cb)
10574     {
10575         WOLFSSL_ENTER("SSL_CTX_set_psk_client_callback");
10576         ctx->havePSK = 1;
10577         ctx->client_psk_cb = cb;
10578     }
10579 
10580 
10581     void wolfSSL_set_psk_client_callback(WOLFSSL* ssl,wc_psk_client_callback cb)
10582     {
10583         byte haveRSA = 1;
10584         int  keySz   = 0;
10585 
10586         WOLFSSL_ENTER("SSL_set_psk_client_callback");
10587         ssl->options.havePSK = 1;
10588         ssl->options.client_psk_cb = cb;
10589 
10590         #ifdef NO_RSA
10591             haveRSA = 0;
10592         #endif
10593         #ifndef NO_CERTS
10594             keySz = ssl->buffers.keySz;
10595         #endif
10596         InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
10597                    ssl->options.haveDH, ssl->options.haveNTRU,
10598                    ssl->options.haveECDSAsig, ssl->options.haveECC,
10599                    ssl->options.haveStaticECC, ssl->options.side);
10600     }
10601 
10602 
10603     void wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX* ctx,
10604                                          wc_psk_server_callback cb)
10605     {
10606         WOLFSSL_ENTER("SSL_CTX_set_psk_server_callback");
10607         ctx->havePSK = 1;
10608         ctx->server_psk_cb = cb;
10609     }
10610 
10611 
10612     void wolfSSL_set_psk_server_callback(WOLFSSL* ssl,wc_psk_server_callback cb)
10613     {
10614         byte haveRSA = 1;
10615         int  keySz   = 0;
10616 
10617         WOLFSSL_ENTER("SSL_set_psk_server_callback");
10618         ssl->options.havePSK = 1;
10619         ssl->options.server_psk_cb = cb;
10620 
10621         #ifdef NO_RSA
10622             haveRSA = 0;
10623         #endif
10624         #ifndef NO_CERTS
10625             keySz = ssl->buffers.keySz;
10626         #endif
10627         InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
10628                    ssl->options.haveDH, ssl->options.haveNTRU,
10629                    ssl->options.haveECDSAsig, ssl->options.haveECC,
10630                    ssl->options.haveStaticECC, ssl->options.side);
10631     }
10632 
10633 
10634     const char* wolfSSL_get_psk_identity_hint(const WOLFSSL* ssl)
10635     {
10636         WOLFSSL_ENTER("SSL_get_psk_identity_hint");
10637 
10638         if (ssl == NULL || ssl->arrays == NULL)
10639             return NULL;
10640 
10641         return ssl->arrays->server_hint;
10642     }
10643 
10644 
10645     const char* wolfSSL_get_psk_identity(const WOLFSSL* ssl)
10646     {
10647         WOLFSSL_ENTER("SSL_get_psk_identity");
10648 
10649         if (ssl == NULL || ssl->arrays == NULL)
10650             return NULL;
10651 
10652         return ssl->arrays->client_identity;
10653     }
10654 
10655 
10656     int wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX* ctx, const char* hint)
10657     {
10658         WOLFSSL_ENTER("SSL_CTX_use_psk_identity_hint");
10659         if (hint == 0)
10660             ctx->server_hint[0] = '\0';
10661         else {
10662             XSTRNCPY(ctx->server_hint, hint, sizeof(ctx->server_hint));
10663             ctx->server_hint[MAX_PSK_ID_LEN] = '\0'; /* null term */
10664         }
10665         return WOLFSSL_SUCCESS;
10666     }
10667 
10668 
10669     int wolfSSL_use_psk_identity_hint(WOLFSSL* ssl, const char* hint)
10670     {
10671         WOLFSSL_ENTER("SSL_use_psk_identity_hint");
10672 
10673         if (ssl == NULL || ssl->arrays == NULL)
10674             return WOLFSSL_FAILURE;
10675 
10676         if (hint == 0)
10677             ssl->arrays->server_hint[0] = 0;
10678         else {
10679             XSTRNCPY(ssl->arrays->server_hint, hint,
10680                                             sizeof(ssl->arrays->server_hint));
10681             ssl->arrays->server_hint[MAX_PSK_ID_LEN] = '\0'; /* null term */
10682         }
10683         return WOLFSSL_SUCCESS;
10684     }
10685 
10686 #endif /* NO_PSK */
10687 
10688 
10689 #ifdef HAVE_ANON
10690 
10691     int wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX* ctx)
10692     {
10693         WOLFSSL_ENTER("wolfSSL_CTX_allow_anon_cipher");
10694 
10695         if (ctx == NULL)
10696             return WOLFSSL_FAILURE;
10697 
10698         ctx->haveAnon = 1;
10699 
10700         return WOLFSSL_SUCCESS;
10701     }
10702 
10703 #endif /* HAVE_ANON */
10704 
10705 
10706 #ifndef NO_CERTS
10707 /* used to be defined on NO_FILESYSTEM only, but are generally useful */
10708 
10709     /* wolfSSL extension allows DER files to be loaded from buffers as well */
10710     int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX* ctx,
10711                                        const unsigned char* in,
10712                                        long sz, int format)
10713     {
10714         WOLFSSL_ENTER("wolfSSL_CTX_load_verify_buffer");
10715         if (format == WOLFSSL_FILETYPE_PEM)
10716             return ProcessChainBuffer(ctx, in, sz, format, CA_TYPE, NULL);
10717         else
10718             return ProcessBuffer(ctx, in, sz, format, CA_TYPE, NULL,NULL,0);
10719     }
10720 
10721 
10722 #ifdef WOLFSSL_TRUST_PEER_CERT
10723     int wolfSSL_CTX_trust_peer_buffer(WOLFSSL_CTX* ctx,
10724                                        const unsigned char* in,
10725                                        long sz, int format)
10726     {
10727         WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_buffer");
10728 
10729         /* sanity check on arguments */
10730         if (sz < 0 || in == NULL || ctx == NULL) {
10731             return BAD_FUNC_ARG;
10732         }
10733 
10734         if (format == WOLFSSL_FILETYPE_PEM)
10735             return ProcessChainBuffer(ctx, in, sz, format,
10736                                                        TRUSTED_PEER_TYPE, NULL);
10737         else
10738             return ProcessBuffer(ctx, in, sz, format, TRUSTED_PEER_TYPE,
10739                                                                    NULL,NULL,0);
10740     }
10741 #endif /* WOLFSSL_TRUST_PEER_CERT */
10742 
10743 
10744     int wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX* ctx,
10745                                  const unsigned char* in, long sz, int format)
10746     {
10747         WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_buffer");
10748         return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 0);
10749     }
10750 
10751 
10752     int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX* ctx,
10753                                  const unsigned char* in, long sz, int format)
10754     {
10755         WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_buffer");
10756         return ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL,NULL,0);
10757     }
10758 
10759 
10760     int wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX* ctx,
10761                                  const unsigned char* in, long sz, int format)
10762     {
10763         WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_buffer_format");
10764         return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 1);
10765     }
10766 
10767     int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
10768                                  const unsigned char* in, long sz)
10769     {
10770         return wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, in, sz,
10771                                                             WOLFSSL_FILETYPE_PEM);
10772     }
10773 
10774 
10775 #ifndef NO_DH
10776 
10777     /* server wrapper for ctx or ssl Diffie-Hellman parameters */
10778     static int wolfSSL_SetTmpDH_buffer_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
10779                                                const unsigned char* buf,
10780                                                long sz, int format)
10781     {
10782         DerBuffer* der = NULL;
10783         int    ret      = 0;
10784         word32 pSz = MAX_DH_SIZE;
10785         word32 gSz = MAX_DH_SIZE;
10786     #ifdef WOLFSSL_SMALL_STACK
10787         byte*  p = NULL;
10788         byte*  g = NULL;
10789     #else
10790         byte   p[MAX_DH_SIZE];
10791         byte   g[MAX_DH_SIZE];
10792     #endif
10793 
10794         if (ctx == NULL || buf == NULL)
10795             return BAD_FUNC_ARG;
10796 
10797         ret = AllocDer(&der, 0, DH_PARAM_TYPE, ctx->heap);
10798         if (ret != 0) {
10799             return ret;
10800         }
10801         der->buffer = (byte*)buf;
10802         der->length = (word32)sz;
10803 
10804     #ifdef WOLFSSL_SMALL_STACK
10805         p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
10806         g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
10807 
10808         if (p == NULL || g == NULL) {
10809             XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
10810             XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
10811             return MEMORY_E;
10812         }
10813     #endif
10814 
10815         if (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM)
10816             ret = WOLFSSL_BAD_FILETYPE;
10817         else {
10818             if (format == WOLFSSL_FILETYPE_PEM) {
10819 #ifdef WOLFSSL_PEM_TO_DER
10820                 FreeDer(&der);
10821                 ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap,
10822                                NULL, NULL);
10823     #ifdef WOLFSSL_WPAS
10824         #ifndef NO_DSA
10825                 if (ret < 0) {
10826                     ret = PemToDer(buf, sz, DSA_PARAM_TYPE, &der, ctx->heap,
10827                                NULL, NULL);
10828                 }
10829         #endif
10830     #endif /* WOLFSSL_WPAS */
10831 #else
10832                 ret = NOT_COMPILED_IN;
10833 #endif /* WOLFSSL_PEM_TO_DER */
10834             }
10835 
10836             if (ret == 0) {
10837                 if (wc_DhParamsLoad(der->buffer, der->length, p, &pSz, g, &gSz) < 0)
10838                     ret = WOLFSSL_BAD_FILETYPE;
10839                 else if (ssl)
10840                     ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
10841                 else
10842                     ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
10843             }
10844         }
10845 
10846         FreeDer(&der);
10847 
10848     #ifdef WOLFSSL_SMALL_STACK
10849         XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
10850         XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
10851     #endif
10852 
10853         return ret;
10854     }
10855 
10856 
10857     /* server Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
10858     int wolfSSL_SetTmpDH_buffer(WOLFSSL* ssl, const unsigned char* buf, long sz,
10859                                int format)
10860     {
10861         if (ssl == NULL)
10862             return BAD_FUNC_ARG;
10863 
10864         return wolfSSL_SetTmpDH_buffer_wrapper(ssl->ctx, ssl, buf, sz, format);
10865     }
10866 
10867 
10868     /* server ctx Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
10869     int wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX* ctx, const unsigned char* buf,
10870                                    long sz, int format)
10871     {
10872         return wolfSSL_SetTmpDH_buffer_wrapper(ctx, NULL, buf, sz, format);
10873     }
10874 
10875 #endif /* NO_DH */
10876 
10877 
10878     int wolfSSL_use_certificate_buffer(WOLFSSL* ssl,
10879                                  const unsigned char* in, long sz, int format)
10880     {
10881         WOLFSSL_ENTER("wolfSSL_use_certificate_buffer");
10882         return ProcessBuffer(ssl->ctx, in, sz, format,CERT_TYPE,ssl,NULL,0);
10883     }
10884 
10885 
10886     int wolfSSL_use_PrivateKey_buffer(WOLFSSL* ssl,
10887                                  const unsigned char* in, long sz, int format)
10888     {
10889         WOLFSSL_ENTER("wolfSSL_use_PrivateKey_buffer");
10890         return ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE,
10891                              ssl, NULL, 0);
10892     }
10893 
10894     int wolfSSL_use_certificate_chain_buffer_format(WOLFSSL* ssl,
10895                                  const unsigned char* in, long sz, int format)
10896     {
10897         WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer_format");
10898         return ProcessBuffer(ssl->ctx, in, sz, format, CERT_TYPE,
10899                              ssl, NULL, 1);
10900     }
10901 
10902     int wolfSSL_use_certificate_chain_buffer(WOLFSSL* ssl,
10903                                  const unsigned char* in, long sz)
10904     {
10905         return wolfSSL_use_certificate_chain_buffer_format(ssl, in, sz,
10906                                                             WOLFSSL_FILETYPE_PEM);
10907     }
10908 
10909 
10910     /* unload any certs or keys that SSL owns, leave CTX as is
10911        WOLFSSL_SUCCESS on ok */
10912     int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl)
10913     {
10914         if (ssl == NULL) {
10915             WOLFSSL_MSG("Null function arg");
10916             return BAD_FUNC_ARG;
10917         }
10918 
10919         if (ssl->buffers.weOwnCert && !ssl->keepCert) {
10920             WOLFSSL_MSG("Unloading cert");
10921             FreeDer(&ssl->buffers.certificate);
10922             #ifdef KEEP_OUR_CERT
10923                 FreeX509(ssl->ourCert);
10924                 if (ssl->ourCert) {
10925                     XFREE(ssl->ourCert, ssl->heap, DYNAMIC_TYPE_X509);
10926                     ssl->ourCert = NULL;
10927                 }
10928             #endif
10929             ssl->buffers.weOwnCert = 0;
10930         }
10931 
10932         if (ssl->buffers.weOwnCertChain) {
10933             WOLFSSL_MSG("Unloading cert chain");
10934             FreeDer(&ssl->buffers.certChain);
10935             ssl->buffers.weOwnCertChain = 0;
10936         }
10937 
10938         if (ssl->buffers.weOwnKey) {
10939             WOLFSSL_MSG("Unloading key");
10940             FreeDer(&ssl->buffers.key);
10941             ssl->buffers.weOwnKey = 0;
10942         }
10943 
10944         return WOLFSSL_SUCCESS;
10945     }
10946 
10947 
10948     int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx)
10949     {
10950         WOLFSSL_ENTER("wolfSSL_CTX_UnloadCAs");
10951 
10952         if (ctx == NULL)
10953             return BAD_FUNC_ARG;
10954 
10955         return wolfSSL_CertManagerUnloadCAs(ctx->cm);
10956     }
10957 
10958 
10959 #ifdef WOLFSSL_TRUST_PEER_CERT
10960     int wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX* ctx)
10961     {
10962         WOLFSSL_ENTER("wolfSSL_CTX_Unload_trust_peers");
10963 
10964         if (ctx == NULL)
10965             return BAD_FUNC_ARG;
10966 
10967         return wolfSSL_CertManagerUnload_trust_peers(ctx->cm);
10968     }
10969 #endif /* WOLFSSL_TRUST_PEER_CERT */
10970 /* old NO_FILESYSTEM end */
10971 #endif /* !NO_CERTS */
10972 
10973 
10974 #ifdef OPENSSL_EXTRA
10975 
10976     int wolfSSL_add_all_algorithms(void)
10977     {
10978         WOLFSSL_ENTER("wolfSSL_add_all_algorithms");
10979         if (wolfSSL_Init() == WOLFSSL_SUCCESS)
10980             return WOLFSSL_SUCCESS;
10981         else
10982             return WOLFSSL_FATAL_ERROR;
10983     }
10984 
10985     int wolfSSL_OPENSSL_add_all_algorithms_noconf(void)
10986     {
10987         WOLFSSL_ENTER("wolfSSL_OPENSSL_add_all_algorithms_noconf");
10988 
10989         if  (wolfSSL_add_all_algorithms() == WOLFSSL_FATAL_ERROR)
10990             return WOLFSSL_FATAL_ERROR;
10991 
10992         return  WOLFSSL_SUCCESS;
10993     }
10994 
10995    /* returns previous set cache size which stays constant */
10996     long wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX* ctx, long sz)
10997     {
10998         /* cache size fixed at compile time in wolfSSL */
10999         (void)ctx;
11000         (void)sz;
11001         WOLFSSL_MSG("session cache is set at compile time");
11002         #ifndef NO_SESSION_CACHE
11003             return SESSIONS_PER_ROW * SESSION_ROWS;
11004         #else
11005             return 0;
11006         #endif
11007     }
11008 
11009 #endif
11010 
11011 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
11012     void wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX* ctx, int mode)
11013     {
11014         WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
11015         if (mode)
11016             ctx->quietShutdown = 1;
11017     }
11018 
11019 
11020     void wolfSSL_set_quiet_shutdown(WOLFSSL* ssl, int mode)
11021     {
11022         WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
11023         if (mode)
11024             ssl->options.quietShutdown = 1;
11025     }
11026 #endif
11027 
11028 #ifdef OPENSSL_EXTRA
11029     void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr)
11030     {
11031         WOLFSSL_ENTER("wolfSSL_set_bio");
11032 
11033         if (ssl == NULL) {
11034             WOLFSSL_MSG("Bad argument, ssl was NULL");
11035             return;
11036         }
11037 
11038         /* if WOLFSSL_BIO is socket type then set WOLFSSL socket to use */
11039         if (rd != NULL && rd->type == WOLFSSL_BIO_SOCKET) {
11040             wolfSSL_set_rfd(ssl, rd->fd);
11041         }
11042         if (wr != NULL && wr->type == WOLFSSL_BIO_SOCKET) {
11043             wolfSSL_set_wfd(ssl, wr->fd);
11044         }
11045 
11046         /* free any existing WOLFSSL_BIOs in use */
11047         if (ssl->biord != NULL) {
11048             if (ssl->biord != ssl->biowr) {
11049                 if (ssl->biowr != NULL) {
11050                     wolfSSL_BIO_free(ssl->biowr);
11051                     ssl->biowr = NULL;
11052                 }
11053             }
11054             wolfSSL_BIO_free(ssl->biord);
11055             ssl->biord = NULL;
11056         }
11057 
11058 
11059         ssl->biord = rd;
11060         ssl->biowr = wr;
11061 
11062         /* set SSL to use BIO callbacks instead */
11063         if (((ssl->cbioFlag & WOLFSSL_CBIO_RECV) == 0) &&
11064             (rd != NULL && rd->type != WOLFSSL_BIO_SOCKET)) {
11065             ssl->CBIORecv = BioReceive;
11066         }
11067         if (((ssl->cbioFlag & WOLFSSL_CBIO_SEND) == 0) &&
11068             (wr != NULL && wr->type != WOLFSSL_BIO_SOCKET)) {
11069             ssl->CBIOSend = BioSend;
11070         }
11071     }
11072 #endif
11073 
11074 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
11075     void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX* ctx,
11076                                        WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
11077     {
11078         WOLFSSL_ENTER("wolfSSL_SSL_CTX_set_client_CA_list");
11079 
11080         if (ctx != NULL)
11081             ctx->ca_names = names;
11082     }
11083 
11084     WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_SSL_CTX_get_client_CA_list(
11085             const WOLFSSL_CTX *s)
11086     {
11087         WOLFSSL_ENTER("wolfSSL_SSL_CTX_get_client_CA_list");
11088 
11089         if (s == NULL)
11090             return NULL;
11091 
11092         return s->ca_names;
11093     }
11094 #endif
11095 
11096 #ifdef OPENSSL_EXTRA
11097     #if !defined(NO_RSA) && !defined(NO_CERTS)
11098     WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char* fname)
11099     {
11100         WOLFSSL_STACK *list = NULL;
11101         WOLFSSL_STACK *node;
11102         WOLFSSL_BIO* bio;
11103         WOLFSSL_X509 *cert = NULL;
11104         WOLFSSL_X509_NAME *subjectName = NULL;
11105 
11106         WOLFSSL_ENTER("wolfSSL_load_client_CA_file");
11107 
11108         bio = wolfSSL_BIO_new_file(fname, "r");
11109         if (bio == NULL)
11110             return NULL;
11111 
11112         /* Read each certificate in the chain out of the file. */
11113         while (wolfSSL_PEM_read_bio_X509(bio, &cert, NULL, NULL) != NULL) {
11114             subjectName = wolfSSL_X509_get_subject_name(cert);
11115             if (subjectName == NULL)
11116                 break;
11117 
11118             node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
11119                                            DYNAMIC_TYPE_OPENSSL);
11120             if (node == NULL)
11121                 break;
11122 
11123             /* Need a persistent copy of the subject name. */
11124             node->data.name = (WOLFSSL_X509_NAME*)XMALLOC(
11125                     sizeof(WOLFSSL_X509_NAME), NULL, DYNAMIC_TYPE_OPENSSL);
11126             if (node->data.name == NULL) {
11127                 XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
11128                 break;
11129             }
11130             XMEMCPY(node->data.name, subjectName, sizeof(WOLFSSL_X509_NAME));
11131             /* Clear pointers so freeing certificate doesn't free memory. */
11132             XMEMSET(subjectName, 0, sizeof(WOLFSSL_X509_NAME));
11133 
11134             /* Put node on the front of the list. */
11135             node->num  = (list == NULL) ? 1 : list->num + 1;
11136             node->next = list;
11137             list = node;
11138 
11139             wolfSSL_X509_free(cert);
11140             cert = NULL;
11141         }
11142 
11143         wolfSSL_X509_free(cert);
11144         wolfSSL_BIO_free(bio);
11145         return list;
11146     }
11147 
11148     int wolfSSL_CTX_add_client_CA(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
11149     {
11150         WOLFSSL_STACK *node = NULL;
11151         WOLFSSL_X509_NAME *subjectName = NULL;
11152 
11153         WOLFSSL_ENTER("wolfSSL_CTX_add_client_CA");
11154 
11155         if (ctx == NULL || x509 == NULL){
11156             WOLFSSL_MSG("Bad argument");
11157             return SSL_FAILURE;
11158         }
11159 
11160         subjectName = wolfSSL_X509_get_subject_name(x509);
11161         if (subjectName == NULL){
11162             WOLFSSL_MSG("invalid x509 data");
11163             return SSL_FAILURE;
11164         }
11165 
11166         /* Alloc stack struct */
11167         node = (WOLF_STACK_OF(WOLFSSL_X509_NAME)*)XMALLOC(
11168                                            sizeof(WOLF_STACK_OF(WOLFSSL_X509_NAME)),
11169                                            NULL, DYNAMIC_TYPE_OPENSSL);
11170         if (node == NULL){
11171             WOLFSSL_MSG("memory allocation error");
11172             return SSL_FAILURE;
11173         }
11174         XMEMSET(node, 0, sizeof(WOLF_STACK_OF(WOLFSSL_X509_NAME)));
11175 
11176         /* Alloc and copy WOLFSSL_X509_NAME */
11177         node->data.name = (WOLFSSL_X509_NAME*)XMALLOC(
11178                                               sizeof(WOLFSSL_X509_NAME),
11179                                               NULL, DYNAMIC_TYPE_OPENSSL);
11180         if (node->data.name == NULL) {
11181             XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
11182             WOLFSSL_MSG("memory allocation error");
11183             return SSL_FAILURE;
11184         }
11185         XMEMCPY(node->data.name, subjectName, sizeof(WOLFSSL_X509_NAME));
11186         XMEMSET(subjectName, 0, sizeof(WOLFSSL_X509_NAME));
11187 
11188         /* push new node onto head of stack */
11189         node->num = (ctx->ca_names == NULL) ? 1 : ctx->ca_names->num + 1;
11190         node->next = ctx->ca_names;
11191         ctx->ca_names = node;
11192         return SSL_SUCCESS;
11193     }
11194     #endif
11195 
11196     #ifndef NO_WOLFSSL_STUB
11197     int wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX* ctx)
11198     {
11199         /* TODO:, not needed in goahead */
11200         (void)ctx;
11201         WOLFSSL_STUB("SSL_CTX_set_default_verify_paths");
11202         return SSL_NOT_IMPLEMENTED;
11203     }
11204     #endif
11205 
11206     #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \
11207         && !defined(WC_NO_RNG)
11208     static const byte srp_N[] = {
11209         0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6, 0x9C, 0x33, 0xF8,
11210         0x0A, 0xFA, 0x8F, 0xC5, 0xE8, 0x60, 0x72, 0x61, 0x87, 0x75, 0xFF,
11211         0x3C, 0x0B, 0x9E, 0xA2, 0x31, 0x4C, 0x9C, 0x25, 0x65, 0x76, 0xD6,
11212         0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3, 0x38, 0x3B, 0x48, 0x13,
11213         0xD6, 0x92, 0xC6, 0xE0, 0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B,
11214         0xE4, 0x8E, 0x49, 0x5C, 0x1D, 0x60, 0x89, 0xDA, 0xD1, 0x5D, 0xC7,
11215         0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6, 0xCE, 0x8E, 0xF4, 0xAD, 0x69,
11216         0xB1, 0x5D, 0x49, 0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85,
11217         0xC5, 0x29, 0xF5, 0x66, 0x66, 0x0E, 0x57, 0xEC, 0x68, 0xED, 0xBC,
11218         0x3C, 0x05, 0x72, 0x6C, 0xC0, 0x2F, 0xD4, 0xCB, 0xF4, 0x97, 0x6E,
11219         0xAA, 0x9A, 0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B, 0x9F,
11220         0xC6, 0x1D, 0x2F, 0xC0, 0xEB, 0x06, 0xE3
11221     };
11222     static const byte srp_g[] = {
11223         0x02
11224     };
11225 
11226     int wolfSSL_CTX_set_srp_username(WOLFSSL_CTX* ctx, char* username)
11227     {
11228         int r = 0;
11229         SrpSide srp_side = SRP_CLIENT_SIDE;
11230         WC_RNG rng;
11231         byte salt[SRP_SALT_SIZE];
11232 
11233         WOLFSSL_ENTER("wolfSSL_CTX_set_srp_username");
11234         if (ctx == NULL || ctx->srp == NULL || username==NULL)
11235             return SSL_FAILURE;
11236 
11237         if (ctx->method->side == WOLFSSL_SERVER_END){
11238             srp_side = SRP_SERVER_SIDE;
11239         } else if (ctx->method->side == WOLFSSL_CLIENT_END){
11240             srp_side = SRP_CLIENT_SIDE;
11241         } else {
11242             WOLFSSL_MSG("Init CTX failed");
11243             return SSL_FAILURE;
11244         }
11245 
11246         if (wc_SrpInit(ctx->srp, SRP_TYPE_SHA256, srp_side) < 0){
11247             WOLFSSL_MSG("Init CTX failed");
11248             XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP);
11249             wolfSSL_CTX_free(ctx);
11250             return SSL_FAILURE;
11251         }
11252         r = wc_SrpSetUsername(ctx->srp, (const byte*)username,
11253                               (word32)XSTRLEN(username));
11254         if (r < 0) {
11255             WOLFSSL_MSG("fail to set srp username.");
11256             return SSL_FAILURE;
11257         }
11258 
11259         /* if wolfSSL_CTX_set_srp_password has already been called, */
11260         /* execute wc_SrpSetPassword here */
11261         if (ctx->srp_password != NULL){
11262             if (wc_InitRng(&rng) < 0){
11263                 WOLFSSL_MSG("wc_InitRng failed");
11264                 return SSL_FAILURE;
11265             }
11266             XMEMSET(salt, 0, sizeof(salt)/sizeof(salt[0]));
11267             if (wc_RNG_GenerateBlock(&rng, salt,
11268                                      sizeof(salt)/sizeof(salt[0])) <  0){
11269                 WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
11270                 wc_FreeRng(&rng);
11271                 return SSL_FAILURE;
11272             }
11273             if (wc_SrpSetParams(ctx->srp, srp_N, sizeof(srp_N)/sizeof(srp_N[0]),
11274                                 srp_g, sizeof(srp_g)/sizeof(srp_g[0]),
11275                                 salt, sizeof(salt)/sizeof(salt[0])) < 0){
11276                 WOLFSSL_MSG("wc_SrpSetParam failed");
11277                 wc_FreeRng(&rng);
11278                 return SSL_FAILURE;
11279             }
11280             r = wc_SrpSetPassword(ctx->srp,
11281                      (const byte*)ctx->srp_password,
11282                      (word32)XSTRLEN((char *)ctx->srp_password));
11283             if (r < 0) {
11284                 WOLFSSL_MSG("fail to set srp password.");
11285                 return SSL_FAILURE;
11286             }
11287             wc_FreeRng(&rng);
11288             XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP);
11289             ctx->srp_password = NULL;
11290         }
11291 
11292         return SSL_SUCCESS;
11293     }
11294 
11295     int wolfSSL_CTX_set_srp_password(WOLFSSL_CTX* ctx, char* password)
11296     {
11297         int r;
11298         WC_RNG rng;
11299         byte salt[SRP_SALT_SIZE];
11300 
11301         WOLFSSL_ENTER("wolfSSL_CTX_set_srp_password");
11302         if (ctx == NULL || ctx->srp == NULL || password == NULL)
11303             return SSL_FAILURE;
11304 
11305         if (ctx->srp->user != NULL){
11306             if (wc_InitRng(&rng) < 0){
11307                 WOLFSSL_MSG("wc_InitRng failed");
11308                 return SSL_FAILURE;
11309             }
11310             XMEMSET(salt, 0, sizeof(salt)/sizeof(salt[0]));
11311             if (wc_RNG_GenerateBlock(&rng, salt,
11312                                      sizeof(salt)/sizeof(salt[0])) <  0){
11313                 WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
11314                 wc_FreeRng(&rng);
11315                 return SSL_FAILURE;
11316             }
11317             if (wc_SrpSetParams(ctx->srp, srp_N, sizeof(srp_N)/sizeof(srp_N[0]),
11318                                 srp_g, sizeof(srp_g)/sizeof(srp_g[0]),
11319                                 salt, sizeof(salt)/sizeof(salt[0])) < 0){
11320                 WOLFSSL_MSG("wc_SrpSetParam failed");
11321                 wc_FreeRng(&rng);
11322                 return SSL_FAILURE;
11323             }
11324             r = wc_SrpSetPassword(ctx->srp, (const byte*)password,
11325                                   (word32)XSTRLEN(password));
11326             if (r < 0) {
11327                 WOLFSSL_MSG("wc_SrpSetPassword failed.");
11328                 wc_FreeRng(&rng);
11329                 return SSL_FAILURE;
11330             }
11331             if (ctx->srp_password != NULL){
11332                 XFREE(ctx->srp_password,NULL,
11333                       DYNAMIC_TYPE_SRP);
11334                 ctx->srp_password = NULL;
11335             }
11336             wc_FreeRng(&rng);
11337         } else {
11338             /* save password for wolfSSL_set_srp_username */
11339             if (ctx->srp_password != NULL)
11340                 XFREE(ctx->srp_password,ctx->heap, DYNAMIC_TYPE_SRP);
11341 
11342             ctx->srp_password = (byte*)XMALLOC(XSTRLEN(password) + 1, ctx->heap,
11343                                                DYNAMIC_TYPE_SRP);
11344             if (ctx->srp_password == NULL){
11345                 WOLFSSL_MSG("memory allocation error");
11346                 return SSL_FAILURE;
11347             }
11348             XMEMCPY(ctx->srp_password, password, XSTRLEN(password) + 1);
11349         }
11350         return SSL_SUCCESS;
11351     }
11352     #endif /* WOLFCRYPT_HAVE_SRP && !NO_SHA256 && !WC_NO_RNG */
11353 
11354     /* keyblock size in bytes or -1 */
11355     int wolfSSL_get_keyblock_size(WOLFSSL* ssl)
11356     {
11357         if (ssl == NULL)
11358             return WOLFSSL_FATAL_ERROR;
11359 
11360         return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
11361                     ssl->specs.hash_size);
11362     }
11363 
11364 
11365     /* store keys returns WOLFSSL_SUCCESS or -1 on error */
11366     int wolfSSL_get_keys(WOLFSSL* ssl, unsigned char** ms, unsigned int* msLen,
11367                                      unsigned char** sr, unsigned int* srLen,
11368                                      unsigned char** cr, unsigned int* crLen)
11369     {
11370         if (ssl == NULL || ssl->arrays == NULL)
11371             return WOLFSSL_FATAL_ERROR;
11372 
11373         *ms = ssl->arrays->masterSecret;
11374         *sr = ssl->arrays->serverRandom;
11375         *cr = ssl->arrays->clientRandom;
11376 
11377         *msLen = SECRET_LEN;
11378         *srLen = RAN_LEN;
11379         *crLen = RAN_LEN;
11380 
11381         return WOLFSSL_SUCCESS;
11382     }
11383 
11384 #endif /* OPENSSL_EXTRA */
11385 
11386 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
11387     void wolfSSL_set_accept_state(WOLFSSL* ssl)
11388     {
11389         word16 haveRSA = 1;
11390         word16 havePSK = 0;
11391 
11392         WOLFSSL_ENTER("SSL_set_accept_state");
11393         if (ssl->options.side == WOLFSSL_CLIENT_END) {
11394     #ifdef HAVE_ECC
11395             ecc_key key;
11396             word32 idx = 0;
11397 
11398             if (ssl->options.haveStaticECC && ssl->buffers.key != NULL) {
11399                 wc_ecc_init(&key);
11400                 if (wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &idx, &key,
11401                                                ssl->buffers.key->length) != 0) {
11402                     ssl->options.haveECDSAsig = 0;
11403                     ssl->options.haveECC = 0;
11404                     ssl->options.haveStaticECC = 0;
11405                 }
11406                 wc_ecc_free(&key);
11407             }
11408     #endif
11409 
11410     #ifndef NO_DH
11411             if (!ssl->options.haveDH && ssl->ctx->haveDH) {
11412                 ssl->buffers.serverDH_P = ssl->ctx->serverDH_P;
11413                 ssl->buffers.serverDH_G = ssl->ctx->serverDH_G;
11414                 ssl->options.haveDH = 1;
11415             }
11416     #endif
11417         }
11418         ssl->options.side = WOLFSSL_SERVER_END;
11419         /* reset suites in case user switched */
11420 
11421         #ifdef NO_RSA
11422             haveRSA = 0;
11423         #endif
11424         #ifndef NO_PSK
11425             havePSK = ssl->options.havePSK;
11426         #endif
11427         InitSuites(ssl->suites, ssl->version, ssl->buffers.keySz, haveRSA,
11428                    havePSK, ssl->options.haveDH, ssl->options.haveNTRU,
11429                    ssl->options.haveECDSAsig, ssl->options.haveECC,
11430                    ssl->options.haveStaticECC, ssl->options.side);
11431     }
11432 
11433 #endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA */
11434 
11435     /* return true if connection established */
11436     int wolfSSL_is_init_finished(WOLFSSL* ssl)
11437     {
11438         if (ssl == NULL)
11439             return 0;
11440 
11441         if (ssl->options.handShakeState == HANDSHAKE_DONE)
11442             return 1;
11443 
11444         return 0;
11445     }
11446 
11447 #ifdef OPENSSL_EXTRA
11448 
11449     void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX* ctx,
11450                                       WOLFSSL_RSA*(*f)(WOLFSSL*, int, int))
11451     {
11452         /* wolfSSL verifies all these internally */
11453         (void)ctx;
11454         (void)f;
11455     }
11456 
11457 
11458     void wolfSSL_set_shutdown(WOLFSSL* ssl, int opt)
11459     {
11460         WOLFSSL_ENTER("wolfSSL_set_shutdown");
11461         if(ssl==NULL) {
11462             WOLFSSL_MSG("Shutdown not set. ssl is null");
11463             return;
11464         }
11465 
11466         ssl->options.sentNotify =  (opt&WOLFSSL_SENT_SHUTDOWN) > 0;
11467         ssl->options.closeNotify = (opt&WOLFSSL_RECEIVED_SHUTDOWN) > 0;
11468     }
11469 
11470 
11471     long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx)
11472     {
11473         WOLFSSL_ENTER("wolfSSL_CTX_get_options");
11474         WOLFSSL_MSG("wolfSSL options are set through API calls and macros");
11475         if(ctx == NULL)
11476             return BAD_FUNC_ARG;
11477         return ctx->mask;
11478     }
11479 
11480     static long wolf_set_options(long old_op, long op);
11481     long wolfSSL_CTX_set_options(WOLFSSL_CTX* ctx, long opt)
11482     {
11483         WOLFSSL_ENTER("SSL_CTX_set_options");
11484 
11485         if (ctx == NULL)
11486             return BAD_FUNC_ARG;
11487 
11488         ctx->mask = wolf_set_options(ctx->mask, opt);
11489 
11490         return ctx->mask;
11491     }
11492 
11493     long wolfSSL_CTX_clear_options(WOLFSSL_CTX* ctx, long opt)
11494     {
11495         WOLFSSL_ENTER("SSL_CTX_clear_options");
11496         if(ctx == NULL)
11497             return BAD_FUNC_ARG;
11498         ctx->mask &= ~opt;
11499         return ctx->mask;
11500     }
11501 
11502     int wolfSSL_set_rfd(WOLFSSL* ssl, int rfd)
11503     {
11504         WOLFSSL_ENTER("SSL_set_rfd");
11505         ssl->rfd = rfd;      /* not used directly to allow IO callbacks */
11506 
11507         ssl->IOCB_ReadCtx  = &ssl->rfd;
11508 
11509         return WOLFSSL_SUCCESS;
11510     }
11511 
11512 
11513     int wolfSSL_set_wfd(WOLFSSL* ssl, int wfd)
11514     {
11515         WOLFSSL_ENTER("SSL_set_wfd");
11516         ssl->wfd = wfd;      /* not used directly to allow IO callbacks */
11517 
11518         ssl->IOCB_WriteCtx  = &ssl->wfd;
11519 
11520         return WOLFSSL_SUCCESS;
11521     }
11522 
11523 
11524 
11525 
11526 #ifndef NO_CERTS
11527     WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(WOLFSSL_CTX* ctx)
11528     {
11529         if (ctx == NULL) {
11530             return NULL;
11531         }
11532 
11533         return &ctx->x509_store;
11534     }
11535 
11536 
11537     void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, WOLFSSL_X509_STORE* str)
11538     {
11539         if (ctx == NULL || str == NULL) {
11540             return;
11541         }
11542 
11543         /* free cert manager if have one */
11544         if (ctx->cm != NULL) {
11545             wolfSSL_CertManagerFree(ctx->cm);
11546         }
11547         ctx->cm               = str->cm;
11548         ctx->x509_store.cache = str->cache;
11549         ctx->x509_store_pt    = str; /* take ownership of store and free it
11550                                         with CTX free */
11551     }
11552 
11553 
11554     WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get_current_cert(
11555                                                     WOLFSSL_X509_STORE_CTX* ctx)
11556     {
11557         WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_current_cert");
11558         if (ctx)
11559             return ctx->current_cert;
11560         return NULL;
11561     }
11562 
11563 
11564     int wolfSSL_X509_STORE_CTX_get_error(WOLFSSL_X509_STORE_CTX* ctx)
11565     {
11566         WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error");
11567         if (ctx != NULL)
11568             return ctx->error;
11569         return 0;
11570     }
11571 
11572 
11573     int wolfSSL_X509_STORE_CTX_get_error_depth(WOLFSSL_X509_STORE_CTX* ctx)
11574     {
11575         WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error_depth");
11576         if(ctx)
11577             return ctx->error_depth;
11578         return WOLFSSL_FATAL_ERROR;
11579     }
11580 
11581     void wolfSSL_X509_STORE_CTX_set_verify_cb(WOLFSSL_X509_STORE_CTX *ctx,
11582                                   WOLFSSL_X509_STORE_CTX_verify_cb verify_cb)
11583     {
11584         WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_verify_cb");
11585         if(ctx == NULL)
11586             return;
11587         ctx->verify_cb = verify_cb;
11588     }
11589 #endif /* !NO_CERTS */
11590 
11591     WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_buffer(void)
11592     {
11593         static WOLFSSL_BIO_METHOD meth;
11594 
11595         WOLFSSL_ENTER("BIO_f_buffer");
11596         meth.type = WOLFSSL_BIO_BUFFER;
11597 
11598         return &meth;
11599     }
11600 
11601     #ifndef NO_WOLFSSL_STUB
11602     long wolfSSL_BIO_set_write_buffer_size(WOLFSSL_BIO* bio, long size)
11603     {
11604         /* wolfSSL has internal buffer, compatibility only */
11605         WOLFSSL_ENTER("BIO_set_write_buffer_size");
11606         WOLFSSL_STUB("BIO_set_write_buffer_size");
11607         (void)bio;
11608         return size;
11609     }
11610     #endif
11611 
11612     WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_bio(void)
11613     {
11614         static WOLFSSL_BIO_METHOD bio_meth;
11615 
11616         WOLFSSL_ENTER("wolfSSL_BIO_f_bio");
11617         bio_meth.type = WOLFSSL_BIO_BIO;
11618 
11619         return &bio_meth;
11620     }
11621 
11622 
11623 #ifndef NO_FILESYSTEM
11624     WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_file(void)
11625     {
11626         static WOLFSSL_BIO_METHOD file_meth;
11627 
11628         WOLFSSL_ENTER("wolfSSL_BIO_f_file");
11629         file_meth.type = WOLFSSL_BIO_FILE;
11630 
11631         return &file_meth;
11632     }
11633 #endif
11634 
11635 
11636     WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_ssl(void)
11637     {
11638         static WOLFSSL_BIO_METHOD meth;
11639 
11640         WOLFSSL_ENTER("BIO_f_ssl");
11641         meth.type = WOLFSSL_BIO_SSL;
11642 
11643         return &meth;
11644     }
11645 
11646 
11647     WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void)
11648     {
11649         static WOLFSSL_BIO_METHOD meth;
11650 
11651         WOLFSSL_ENTER("BIO_s_socket");
11652         meth.type = WOLFSSL_BIO_SOCKET;
11653 
11654         return &meth;
11655     }
11656 
11657 
11658     WOLFSSL_BIO* wolfSSL_BIO_new_socket(int sfd, int closeF)
11659     {
11660         WOLFSSL_BIO* bio = wolfSSL_BIO_new(wolfSSL_BIO_s_socket());
11661 
11662         WOLFSSL_ENTER("BIO_new_socket");
11663         if (bio) {
11664             bio->type  = WOLFSSL_BIO_SOCKET;
11665             bio->close = (byte)closeF;
11666             bio->fd    = sfd;
11667         }
11668         return bio;
11669     }
11670 
11671 
11672     int wolfSSL_BIO_eof(WOLFSSL_BIO* b)
11673     {
11674         WOLFSSL_ENTER("BIO_eof");
11675         if (b->eof)
11676             return 1;
11677 
11678         return 0;
11679     }
11680 
11681 
11682     long wolfSSL_BIO_set_ssl(WOLFSSL_BIO* b, WOLFSSL* ssl, int closeF)
11683     {
11684         WOLFSSL_ENTER("wolfSSL_BIO_set_ssl");
11685 
11686         if (b != NULL) {
11687             b->ssl   = ssl;
11688             b->close = (byte)closeF;
11689     /* add to ssl for bio free if SSL_free called before/instead of free_all? */
11690         }
11691 
11692         return 0;
11693     }
11694 
11695 
11696     long wolfSSL_BIO_set_fd(WOLFSSL_BIO* b, int fd, int closeF)
11697     {
11698         WOLFSSL_ENTER("wolfSSL_BIO_set_fd");
11699 
11700         if (b != NULL) {
11701             b->fd    = fd;
11702             b->close = (byte)closeF;
11703         }
11704 
11705         return WOLFSSL_SUCCESS;
11706     }
11707 
11708 
11709     WOLFSSL_BIO* wolfSSL_BIO_new(WOLFSSL_BIO_METHOD* method)
11710     {
11711         WOLFSSL_BIO* bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0,
11712                                                 DYNAMIC_TYPE_OPENSSL);
11713         WOLFSSL_ENTER("wolfSSL_BIO_new");
11714         if (bio) {
11715             XMEMSET(bio, 0, sizeof(WOLFSSL_BIO));
11716             bio->type   = method->type;
11717             bio->close  = BIO_CLOSE; /* default to close things */
11718             if (method->type != WOLFSSL_BIO_FILE &&
11719                     method->type != WOLFSSL_BIO_SOCKET) {
11720                 bio->mem_buf =(WOLFSSL_BUF_MEM*)XMALLOC(sizeof(WOLFSSL_BUF_MEM),
11721                                                        0, DYNAMIC_TYPE_OPENSSL);
11722                 if (bio->mem_buf == NULL) {
11723                     WOLFSSL_MSG("Memory error");
11724                     wolfSSL_BIO_free(bio);
11725                     return NULL;
11726                 }
11727                 bio->mem_buf->data = (char*)bio->mem;
11728             }
11729         }
11730         return bio;
11731     }
11732 
11733 
11734     int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, void* p)
11735     {
11736         WOLFSSL_ENTER("wolfSSL_BIO_get_mem_data");
11737 
11738         if (bio == NULL || p == NULL)
11739             return WOLFSSL_FATAL_ERROR;
11740 
11741         *(byte **)p = bio->mem;
11742 
11743         return bio->memLen;
11744     }
11745 
11746 
11747     WOLFSSL_BIO* wolfSSL_BIO_new_mem_buf(void* buf, int len)
11748     {
11749         WOLFSSL_BIO* bio = NULL;
11750 
11751         if (buf == NULL || len < 0) {
11752             return bio;
11753         }
11754 
11755         bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
11756         if (bio == NULL) {
11757             return bio;
11758         }
11759 
11760         bio->memLen = bio->wrSz = len;
11761         bio->mem    = (byte*)XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL);
11762         if (bio->mem == NULL) {
11763             wolfSSL_BIO_free(bio);
11764             return NULL;
11765         }
11766         if (bio->mem_buf != NULL) {
11767             bio->mem_buf->data = (char*)bio->mem;
11768             bio->mem_buf->length = bio->memLen;
11769         }
11770 
11771         XMEMCPY(bio->mem, buf, len);
11772 
11773         return bio;
11774     }
11775 
11776     /*
11777      * Note : If the flag BIO_NOCLOSE is set then freeing memory buffers is up
11778      *        to the application.
11779      */
11780     int wolfSSL_BIO_free(WOLFSSL_BIO* bio)
11781     {
11782         /* unchain?, doesn't matter in goahead since from free all */
11783         WOLFSSL_ENTER("wolfSSL_BIO_free");
11784         if (bio) {
11785             /* remove from pair by setting the paired bios pair to NULL */
11786             if (bio->pair != NULL) {
11787                 bio->pair->pair = NULL;
11788             }
11789 
11790             if (bio->close) {
11791                 if (bio->ssl)
11792                     wolfSSL_free(bio->ssl);
11793                 if (bio->fd)
11794                     CloseSocket(bio->fd);
11795             }
11796 
11797         #ifndef NO_FILESYSTEM
11798             if (bio->type == WOLFSSL_BIO_FILE && bio->close == BIO_CLOSE) {
11799                 if (bio->file) {
11800                     XFCLOSE(bio->file);
11801                 }
11802             }
11803         #endif
11804 
11805             if (bio->close != BIO_NOCLOSE) {
11806                 if (bio->mem != NULL) {
11807                     if (bio->mem_buf != NULL) {
11808                         if (bio->mem_buf->data != (char*)bio->mem) {
11809                             XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
11810                             bio->mem = NULL;
11811                         }
11812                     }
11813                     else {
11814                         XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
11815                         bio->mem = NULL;
11816                     }
11817                 }
11818                 if (bio->mem_buf != NULL) {
11819                     wolfSSL_BUF_MEM_free(bio->mem_buf);
11820                     bio->mem_buf = NULL;
11821                 }
11822             }
11823 
11824             XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
11825         }
11826         return 0;
11827     }
11828 
11829 
11830     int wolfSSL_BIO_free_all(WOLFSSL_BIO* bio)
11831     {
11832         WOLFSSL_ENTER("BIO_free_all");
11833         while (bio) {
11834             WOLFSSL_BIO* next = bio->next;
11835             wolfSSL_BIO_free(bio);
11836             bio = next;
11837         }
11838         return 0;
11839     }
11840 
11841 
11842     WOLFSSL_BIO* wolfSSL_BIO_push(WOLFSSL_BIO* top, WOLFSSL_BIO* append)
11843     {
11844         WOLFSSL_ENTER("BIO_push");
11845         top->next    = append;
11846         append->prev = top;
11847 
11848         return top;
11849     }
11850 
11851 
11852     int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
11853     {
11854         /* for wolfSSL no flushing needed */
11855         WOLFSSL_ENTER("BIO_flush");
11856         (void)bio;
11857         return 1;
11858     }
11859 #endif /* OPENSSL_EXTRA */
11860 
11861 #ifdef WOLFSSL_ENCRYPTED_KEYS
11862 
11863     void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX* ctx,
11864                                                    void* userdata)
11865     {
11866         WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb_userdata");
11867         ctx->passwd_userdata = userdata;
11868     }
11869 
11870 
11871     void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX* ctx,pem_password_cb* cb)
11872     {
11873         WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb");
11874         if (ctx != NULL) {
11875             ctx->passwd_cb = cb;
11876         }
11877     }
11878 
11879     pem_password_cb* wolfSSL_CTX_get_default_passwd_cb(WOLFSSL_CTX *ctx)
11880     {
11881         if (ctx == NULL || ctx->passwd_cb == NULL) {
11882             return NULL;
11883         }
11884 
11885         return ctx->passwd_cb;
11886     }
11887 
11888 
11889     void* wolfSSL_CTX_get_default_passwd_cb_userdata(WOLFSSL_CTX *ctx)
11890     {
11891         if (ctx == NULL) {
11892             return NULL;
11893         }
11894 
11895         return ctx->passwd_userdata;
11896     }
11897 
11898 #if !defined(NO_PWDBASED) && (defined(OPENSSL_EXTRA) || \
11899         defined(OPENSSL_EXTRA_X509_SMALL) || defined(HAVE_WEBSERVER))
11900 
11901     int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER* type,
11902                        const WOLFSSL_EVP_MD* md, const byte* salt,
11903                        const byte* data, int sz, int count, byte* key, byte* iv)
11904     {
11905         int ret;
11906         int hashType = WC_HASH_TYPE_NONE;
11907     #ifdef WOLFSSL_SMALL_STACK
11908         EncryptedInfo* info = NULL;
11909     #else
11910         EncryptedInfo  info[1];
11911     #endif
11912 
11913     #ifdef WOLFSSL_SMALL_STACK
11914         info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
11915                                        DYNAMIC_TYPE_ENCRYPTEDINFO);
11916         if (info == NULL) {
11917             WOLFSSL_MSG("malloc failed");
11918             return WOLFSSL_FAILURE;
11919         }
11920     #endif
11921 
11922         XMEMSET(info, 0, sizeof(EncryptedInfo));
11923         info->ivSz = EVP_SALT_SIZE;
11924 
11925         ret = wolfSSL_EVP_get_hashinfo(md, &hashType, NULL);
11926         if (ret == 0)
11927             ret = wc_EncryptedInfoGet(info, type);
11928         if (ret == 0)
11929             ret = wc_PBKDF1_ex(key, info->keySz, iv, info->ivSz, data, sz, salt,
11930                                EVP_SALT_SIZE, count, hashType, NULL);
11931 
11932     #ifdef WOLFSSL_SMALL_STACK
11933         XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
11934     #endif
11935 
11936         if (ret <= 0)
11937             return 0; /* failure - for compatibility */
11938 
11939         return ret;
11940     }
11941 
11942 #endif /* !NO_PWDBASED && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || HAVE_WEBSERVER) */
11943 #endif /* WOLFSSL_ENCRYPTED_KEYS */
11944 
11945 
11946 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
11947     int wolfSSL_num_locks(void)
11948     {
11949         return 0;
11950     }
11951 
11952     void wolfSSL_set_locking_callback(void (*f)(int, int, const char*, int))
11953     {
11954         WOLFSSL_ENTER("wolfSSL_set_locking_callback");
11955 
11956         if (wc_SetMutexCb(f) != 0) {
11957             WOLFSSL_MSG("Error when setting mutex call back");
11958         }
11959     }
11960 
11961 
11962     typedef unsigned long (idCb)(void);
11963     static idCb* inner_idCb = NULL;
11964 
11965     unsigned long wolfSSL_thread_id(void)
11966     {
11967         if (inner_idCb != NULL) {
11968             return inner_idCb();
11969         }
11970         else {
11971             return 0;
11972         }
11973     }
11974 
11975 
11976     void wolfSSL_set_id_callback(unsigned long (*f)(void))
11977     {
11978         inner_idCb = f;
11979     }
11980 
11981     unsigned long wolfSSL_ERR_get_error(void)
11982     {
11983         WOLFSSL_ENTER("wolfSSL_ERR_get_error");
11984 
11985 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
11986         {
11987             unsigned long ret = wolfSSL_ERR_peek_error_line_data(NULL, NULL,
11988                                                                  NULL, NULL);
11989             wc_RemoveErrorNode(-1);
11990             return ret;
11991         }
11992 #elif (defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE))
11993         {
11994             int ret = wc_PullErrorNode(NULL, NULL, NULL);
11995 
11996             if (ret < 0) {
11997                 if (ret == BAD_STATE_E) return 0; /* no errors in queue */
11998                 WOLFSSL_MSG("Error with pulling error node!");
11999                 WOLFSSL_LEAVE("wolfSSL_ERR_get_error", ret);
12000                 ret = 0 - ret; /* return absolute value of error */
12001 
12002                 /* panic and try to clear out nodes */
12003                 wc_ClearErrorNodes();
12004             }
12005 
12006             return (unsigned long)ret;
12007         }
12008 #else
12009         return (unsigned long)(0 - NOT_COMPILED_IN);
12010 #endif
12011     }
12012 
12013 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
12014 
12015 
12016 #ifdef OPENSSL_EXTRA
12017 
12018 #if !defined(NO_WOLFSSL_SERVER)
12019 size_t wolfSSL_get_server_random(const WOLFSSL *ssl, unsigned char *out,
12020                                                                    size_t outSz)
12021 {
12022     size_t size;
12023 
12024     /* return max size of buffer */
12025     if (outSz == 0) {
12026         return RAN_LEN;
12027     }
12028 
12029     if (ssl == NULL || out == NULL) {
12030         return 0;
12031     }
12032 
12033     if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) {
12034         WOLFSSL_MSG("Arrays struct not saved after handshake");
12035         return 0;
12036     }
12037 
12038     if (outSz > RAN_LEN) {
12039         size = RAN_LEN;
12040     }
12041     else {
12042         size = outSz;
12043     }
12044 
12045     XMEMCPY(out, ssl->arrays->serverRandom, size);
12046     return size;
12047 }
12048 #endif /* !defined(NO_WOLFSSL_SERVER) */
12049 
12050 
12051 #if !defined(NO_WOLFSSL_CLIENT)
12052 /* Return the amount of random bytes copied over or error case.
12053  * ssl : ssl struct after handshake
12054  * out : buffer to hold random bytes
12055  * outSz : either 0 (return max buffer sz) or size of out buffer
12056  *
12057  * NOTE: wolfSSL_KeepArrays(ssl) must be called to retain handshake information.
12058  */
12059 size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
12060                                                                    size_t outSz)
12061 {
12062     size_t size;
12063 
12064     /* return max size of buffer */
12065     if (outSz == 0) {
12066         return RAN_LEN;
12067     }
12068 
12069     if (ssl == NULL || out == NULL) {
12070         return 0;
12071     }
12072 
12073     if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) {
12074         WOLFSSL_MSG("Arrays struct not saved after handshake");
12075         return 0;
12076     }
12077 
12078     if (outSz > RAN_LEN) {
12079         size = RAN_LEN;
12080     }
12081     else {
12082         size = outSz;
12083     }
12084 
12085     XMEMCPY(out, ssl->arrays->clientRandom, size);
12086     return size;
12087 }
12088 #endif /* !NO_WOLFSSL_CLIENT */
12089 
12090 
12091     unsigned long wolfSSLeay(void)
12092     {
12093         return SSLEAY_VERSION_NUMBER;
12094     }
12095 
12096 
12097     const char* wolfSSLeay_version(int type)
12098     {
12099         static const char* version = "SSLeay wolfSSL compatibility";
12100         (void)type;
12101         return version;
12102     }
12103 
12104 
12105 #ifndef NO_MD5
12106     int wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5)
12107     {
12108         int ret;
12109         typedef char md5_test[sizeof(MD5_CTX) >= sizeof(wc_Md5) ? 1 : -1];
12110         (void)sizeof(md5_test);
12111 
12112         WOLFSSL_ENTER("MD5_Init");
12113         ret = wc_InitMd5((wc_Md5*)md5);
12114 
12115         /* return 1 on success, 0 otherwise */
12116         if (ret == 0)
12117             return 1;
12118 
12119         return 0;
12120     }
12121 
12122 
12123     int wolfSSL_MD5_Update(WOLFSSL_MD5_CTX* md5, const void* input,
12124                            unsigned long sz)
12125     {
12126         int ret;
12127 
12128         WOLFSSL_ENTER("wolfSSL_MD5_Update");
12129         ret = wc_Md5Update((wc_Md5*)md5, (const byte*)input, (word32)sz);
12130 
12131         /* return 1 on success, 0 otherwise */
12132         if (ret == 0)
12133             return 1;
12134 
12135         return 0;
12136     }
12137 
12138 
12139     int wolfSSL_MD5_Final(byte* input, WOLFSSL_MD5_CTX* md5)
12140     {
12141         int ret;
12142 
12143         WOLFSSL_ENTER("MD5_Final");
12144         ret = wc_Md5Final((wc_Md5*)md5, input);
12145 
12146         /* return 1 on success, 0 otherwise */
12147         if (ret == 0)
12148             return 1;
12149 
12150         return 0;
12151     }
12152 #endif /* !NO_MD5 */
12153 
12154 
12155 #ifndef NO_SHA
12156     int wolfSSL_SHA_Init(WOLFSSL_SHA_CTX* sha)
12157     {
12158         int ret;
12159 
12160         typedef char sha_test[sizeof(SHA_CTX) >= sizeof(wc_Sha) ? 1 : -1];
12161         (void)sizeof(sha_test);
12162 
12163         WOLFSSL_ENTER("SHA_Init");
12164         ret = wc_InitSha((wc_Sha*)sha);
12165 
12166         /* return 1 on success, 0 otherwise */
12167         if (ret == 0)
12168             return 1;
12169 
12170         return 0;
12171     }
12172 
12173 
12174     int wolfSSL_SHA_Update(WOLFSSL_SHA_CTX* sha, const void* input,
12175                            unsigned long sz)
12176     {
12177         int ret;
12178 
12179         WOLFSSL_ENTER("SHA_Update");
12180         ret = wc_ShaUpdate((wc_Sha*)sha, (const byte*)input, (word32)sz);
12181 
12182         /* return 1 on success, 0 otherwise */
12183         if (ret == 0)
12184             return 1;
12185 
12186         return 0;
12187     }
12188 
12189 
12190     int wolfSSL_SHA_Final(byte* input, WOLFSSL_SHA_CTX* sha)
12191     {
12192         int ret;
12193 
12194         WOLFSSL_ENTER("SHA_Final");
12195         ret = wc_ShaFinal((wc_Sha*)sha, input);
12196 
12197         /* return 1 on success, 0 otherwise */
12198         if (ret == 0)
12199             return 1;
12200 
12201         return 0;
12202     }
12203 
12204 
12205     int wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX* sha)
12206     {
12207         WOLFSSL_ENTER("SHA1_Init");
12208         return SHA_Init(sha);
12209     }
12210 
12211 
12212     int wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX* sha, const void* input,
12213                             unsigned long sz)
12214     {
12215         WOLFSSL_ENTER("SHA1_Update");
12216         return SHA_Update(sha, input, sz);
12217     }
12218 
12219 
12220     int wolfSSL_SHA1_Final(byte* input, WOLFSSL_SHA_CTX* sha)
12221     {
12222         WOLFSSL_ENTER("SHA1_Final");
12223         return SHA_Final(input, sha);
12224     }
12225 #endif /* !NO_SHA */
12226 
12227 #ifdef WOLFSSL_SHA224
12228 
12229     int wolfSSL_SHA224_Init(WOLFSSL_SHA224_CTX* sha)
12230     {
12231         int ret;
12232 
12233         typedef char sha_test[sizeof(SHA224_CTX) >= sizeof(wc_Sha224) ? 1 : -1];
12234         (void)sizeof(sha_test);
12235 
12236         WOLFSSL_ENTER("SHA224_Init");
12237         ret = wc_InitSha224((wc_Sha224*)sha);
12238 
12239         /* return 1 on success, 0 otherwise */
12240         if (ret == 0)
12241             return 1;
12242 
12243         return 0;
12244     }
12245 
12246 
12247     int wolfSSL_SHA224_Update(WOLFSSL_SHA224_CTX* sha, const void* input,
12248                            unsigned long sz)
12249     {
12250         int ret;
12251 
12252         WOLFSSL_ENTER("SHA224_Update");
12253         ret = wc_Sha224Update((wc_Sha224*)sha, (const byte*)input, (word32)sz);
12254 
12255         /* return 1 on success, 0 otherwise */
12256         if (ret == 0)
12257             return 1;
12258 
12259         return 0;
12260     }
12261 
12262 
12263     int wolfSSL_SHA224_Final(byte* input, WOLFSSL_SHA224_CTX* sha)
12264     {
12265         int ret;
12266 
12267         WOLFSSL_ENTER("SHA224_Final");
12268         ret = wc_Sha224Final((wc_Sha224*)sha, input);
12269 
12270         /* return 1 on success, 0 otherwise */
12271         if (ret == 0)
12272             return 1;
12273 
12274         return 0;
12275     }
12276 
12277 #endif /* WOLFSSL_SHA224 */
12278 
12279 
12280     int wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX* sha256)
12281     {
12282         int ret;
12283 
12284         typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(wc_Sha256) ? 1 : -1];
12285         (void)sizeof(sha_test);
12286 
12287         WOLFSSL_ENTER("SHA256_Init");
12288         ret = wc_InitSha256((wc_Sha256*)sha256);
12289 
12290         /* return 1 on success, 0 otherwise */
12291         if (ret == 0)
12292             return 1;
12293 
12294         return 0;
12295     }
12296 
12297 
12298     int wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX* sha, const void* input,
12299                               unsigned long sz)
12300     {
12301         int ret;
12302 
12303         WOLFSSL_ENTER("SHA256_Update");
12304         ret = wc_Sha256Update((wc_Sha256*)sha, (const byte*)input, (word32)sz);
12305 
12306         /* return 1 on success, 0 otherwise */
12307         if (ret == 0)
12308             return 1;
12309 
12310         return 0;
12311     }
12312 
12313 
12314     int wolfSSL_SHA256_Final(byte* input, WOLFSSL_SHA256_CTX* sha)
12315     {
12316         int ret;
12317 
12318         WOLFSSL_ENTER("SHA256_Final");
12319         ret = wc_Sha256Final((wc_Sha256*)sha, input);
12320 
12321         /* return 1 on success, 0 otherwise */
12322         if (ret == 0)
12323             return 1;
12324 
12325         return 0;
12326     }
12327 
12328 
12329 #ifdef WOLFSSL_SHA384
12330 
12331     int wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX* sha)
12332     {
12333         int ret;
12334 
12335         typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(wc_Sha384) ? 1 : -1];
12336         (void)sizeof(sha_test);
12337 
12338         WOLFSSL_ENTER("SHA384_Init");
12339         ret = wc_InitSha384((wc_Sha384*)sha);
12340 
12341         /* return 1 on success, 0 otherwise */
12342         if (ret == 0)
12343             return 1;
12344 
12345         return 0;
12346     }
12347 
12348 
12349     int wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX* sha, const void* input,
12350                            unsigned long sz)
12351     {
12352         int ret;
12353 
12354         WOLFSSL_ENTER("SHA384_Update");
12355         ret = wc_Sha384Update((wc_Sha384*)sha, (const byte*)input, (word32)sz);
12356 
12357         /* return 1 on success, 0 otherwise */
12358         if (ret == 0)
12359             return 1;
12360 
12361         return 0;
12362     }
12363 
12364 
12365     int wolfSSL_SHA384_Final(byte* input, WOLFSSL_SHA384_CTX* sha)
12366     {
12367         int ret;
12368 
12369         WOLFSSL_ENTER("SHA384_Final");
12370         ret = wc_Sha384Final((wc_Sha384*)sha, input);
12371 
12372         /* return 1 on success, 0 otherwise */
12373         if (ret == 0)
12374             return 1;
12375 
12376         return 0;
12377     }
12378 
12379 #endif /* WOLFSSL_SHA384 */
12380 
12381 
12382 #ifdef WOLFSSL_SHA512
12383 
12384     int wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha)
12385     {
12386         int ret;
12387 
12388         typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(wc_Sha512) ? 1 : -1];
12389         (void)sizeof(sha_test);
12390 
12391         WOLFSSL_ENTER("SHA512_Init");
12392         ret = wc_InitSha512((wc_Sha512*)sha);
12393 
12394         /* return 1 on success, 0 otherwise */
12395         if (ret == 0)
12396             return 1;
12397 
12398         return 0;
12399     }
12400 
12401 
12402     int wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX* sha, const void* input,
12403                            unsigned long sz)
12404     {
12405         int ret;
12406 
12407         WOLFSSL_ENTER("SHA512_Update");
12408         ret = wc_Sha512Update((wc_Sha512*)sha, (const byte*)input, (word32)sz);
12409 
12410         /* return 1 on success, 0 otherwise */
12411         if (ret == 0)
12412             return 1;
12413 
12414         return 0;
12415     }
12416 
12417 
12418     int wolfSSL_SHA512_Final(byte* input, WOLFSSL_SHA512_CTX* sha)
12419     {
12420         int ret;
12421 
12422         WOLFSSL_ENTER("SHA512_Final");
12423         ret = wc_Sha512Final((wc_Sha512*)sha, input);
12424 
12425         /* return 1 on success, 0 otherwise */
12426         if (ret == 0)
12427             return 1;
12428 
12429         return 0;
12430     }
12431 
12432 #endif /* WOLFSSL_SHA512 */
12433 
12434     static const struct s_ent {
12435         const unsigned char macType;
12436         const char *name;
12437     } md_tbl[] = {
12438     #ifndef NO_MD4
12439          {MD4, "MD4"},
12440     #endif /* NO_MD4 */
12441 
12442     #ifndef NO_MD5
12443         {WC_MD5, "MD5"},
12444     #endif /* NO_MD5 */
12445 
12446     #ifndef NO_SHA
12447         {WC_SHA, "SHA"},
12448     #endif /* NO_SHA */
12449 
12450     #ifdef WOLFSSL_SHA224
12451         {WC_SHA224, "SHA224"},
12452     #endif /* WOLFSSL_SHA224 */
12453     #ifndef NO_SHA256
12454         {WC_SHA256, "SHA256"},
12455     #endif
12456 
12457     #ifdef WOLFSSL_SHA384
12458         {WC_SHA384, "SHA384"},
12459     #endif /* WOLFSSL_SHA384 */
12460     #ifdef WOLFSSL_SHA512
12461         {WC_SHA512, "SHA512"},
12462     #endif /* WOLFSSL_SHA512 */
12463         {0, NULL}
12464     };
12465 
12466 const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name)
12467 {
12468     static const struct alias {
12469         const char *name;
12470         const char *alias;
12471     } alias_tbl[] =
12472     {
12473         {"MD4", "ssl3-md4"},
12474         {"MD5", "ssl3-md5"},
12475         {"SHA", "ssl3-sha1"},
12476         {"SHA", "SHA1"},
12477         { NULL, NULL}
12478     };
12479 
12480     const struct alias  *al;
12481     const struct s_ent *ent;
12482 
12483     for (al = alias_tbl; al->name != NULL; al++)
12484         if(XSTRNCMP(name, al->alias, XSTRLEN(al->alias)+1) == 0) {
12485             name = al->name;
12486             break;
12487         }
12488 
12489     for (ent = md_tbl; ent->name != NULL; ent++)
12490         if(XSTRNCMP(name, ent->name, XSTRLEN(ent->name)+1) == 0) {
12491             return (EVP_MD *)ent->name;
12492         }
12493     return NULL;
12494 }
12495 
12496 static WOLFSSL_EVP_MD *wolfSSL_EVP_get_md(const unsigned char type)
12497 {
12498     const struct s_ent *ent ;
12499     WOLFSSL_ENTER("EVP_get_md");
12500     for( ent = md_tbl; ent->name != NULL; ent++){
12501         if(type == ent->macType) {
12502             return (WOLFSSL_EVP_MD *)ent->name;
12503         }
12504     }
12505     return (WOLFSSL_EVP_MD *)"";
12506 }
12507 
12508 int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
12509 {
12510     const struct s_ent *ent ;
12511     WOLFSSL_ENTER("EVP_MD_type");
12512     for( ent = md_tbl; ent->name != NULL; ent++){
12513         if(XSTRNCMP((const char *)md, ent->name, XSTRLEN(ent->name)+1) == 0) {
12514             return ent->macType;
12515         }
12516     }
12517     return 0;
12518 }
12519 
12520 
12521 #ifndef NO_MD4
12522 
12523     /* return a pointer to MD4 EVP type */
12524     const WOLFSSL_EVP_MD* wolfSSL_EVP_md4(void)
12525     {
12526         WOLFSSL_ENTER("wolfSSL_EVP_md4");
12527         return EVP_get_digestbyname("MD4");
12528     }
12529 
12530 #endif /* !NO_MD4 */
12531 
12532 
12533 #ifndef NO_MD5
12534 
12535     const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void)
12536     {
12537         WOLFSSL_ENTER("EVP_md5");
12538         return EVP_get_digestbyname("MD5");
12539     }
12540 
12541 #endif /* !NO_MD5 */
12542 
12543 
12544 #ifndef NO_SHA
12545     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void)
12546     {
12547         WOLFSSL_ENTER("EVP_sha1");
12548         return EVP_get_digestbyname("SHA");
12549     }
12550 #endif /* NO_SHA */
12551 
12552 #ifdef WOLFSSL_SHA224
12553 
12554     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha224(void)
12555     {
12556         WOLFSSL_ENTER("EVP_sha224");
12557         return EVP_get_digestbyname("SHA224");
12558     }
12559 
12560 #endif /* WOLFSSL_SHA224 */
12561 
12562 
12563     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void)
12564     {
12565         WOLFSSL_ENTER("EVP_sha256");
12566         return EVP_get_digestbyname("SHA256");
12567     }
12568 
12569 #ifdef WOLFSSL_SHA384
12570 
12571     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void)
12572     {
12573         WOLFSSL_ENTER("EVP_sha384");
12574         return EVP_get_digestbyname("SHA384");
12575     }
12576 
12577 #endif /* WOLFSSL_SHA384 */
12578 
12579 #ifdef WOLFSSL_SHA512
12580 
12581     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void)
12582     {
12583         WOLFSSL_ENTER("EVP_sha512");
12584         return EVP_get_digestbyname("SHA512");
12585     }
12586 
12587 #endif /* WOLFSSL_SHA512 */
12588 
12589 
12590     WOLFSSL_EVP_MD_CTX *wolfSSL_EVP_MD_CTX_new(void)
12591     {
12592         WOLFSSL_EVP_MD_CTX* ctx;
12593         WOLFSSL_ENTER("EVP_MD_CTX_new");
12594         ctx = (WOLFSSL_EVP_MD_CTX*)XMALLOC(sizeof *ctx, NULL,
12595                                                        DYNAMIC_TYPE_OPENSSL);
12596         if (ctx){
12597             wolfSSL_EVP_MD_CTX_init(ctx);
12598         }
12599         return ctx;
12600     }
12601 
12602     WOLFSSL_API void wolfSSL_EVP_MD_CTX_free(WOLFSSL_EVP_MD_CTX *ctx)
12603     {
12604         if (ctx) {
12605             WOLFSSL_ENTER("EVP_MD_CTX_free");
12606                 wolfSSL_EVP_MD_CTX_cleanup(ctx);
12607                 XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
12608             }
12609     }
12610 
12611 
12612     /* returns the type of message digest used by the ctx */
12613     int wolfSSL_EVP_MD_CTX_type(const WOLFSSL_EVP_MD_CTX *ctx) {
12614         WOLFSSL_ENTER("EVP_MD_CTX_type");
12615         return ctx->macType;
12616     }
12617 
12618 
12619     /* returns WOLFSSL_SUCCESS on success */
12620     int wolfSSL_EVP_MD_CTX_copy(WOLFSSL_EVP_MD_CTX *out, const WOLFSSL_EVP_MD_CTX *in)
12621     {
12622         return wolfSSL_EVP_MD_CTX_copy_ex(out, in);
12623     }
12624 
12625 
12626     /* copies structure in to the structure out
12627      *
12628      * returns WOLFSSL_SUCCESS on success */
12629     int wolfSSL_EVP_MD_CTX_copy_ex(WOLFSSL_EVP_MD_CTX *out, const WOLFSSL_EVP_MD_CTX *in)
12630     {
12631         if ((out == NULL) || (in == NULL)) return WOLFSSL_FAILURE;
12632         WOLFSSL_ENTER("EVP_CIPHER_MD_CTX_copy_ex");
12633         XMEMCPY(out, in, sizeof(WOLFSSL_EVP_MD_CTX));
12634         return WOLFSSL_SUCCESS;
12635     }
12636 
12637     void wolfSSL_EVP_MD_CTX_init(WOLFSSL_EVP_MD_CTX* ctx)
12638     {
12639         WOLFSSL_ENTER("EVP_CIPHER_MD_CTX_init");
12640         XMEMSET(ctx, 0, sizeof(WOLFSSL_EVP_MD_CTX));
12641     }
12642 
12643     const WOLFSSL_EVP_MD *wolfSSL_EVP_MD_CTX_md(const WOLFSSL_EVP_MD_CTX *ctx)
12644     {
12645         if (ctx == NULL)
12646             return NULL;
12647         WOLFSSL_ENTER("EVP_MD_CTX_md");
12648         return (const WOLFSSL_EVP_MD *)wolfSSL_EVP_get_md(ctx->macType);
12649     }
12650 
12651     #ifndef NO_AES
12652 
12653     #ifdef HAVE_AES_CBC
12654     #ifdef WOLFSSL_AES_128
12655     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void)
12656     {
12657         WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cbc");
12658         if (EVP_AES_128_CBC == NULL)
12659             wolfSSL_EVP_init();
12660         return EVP_AES_128_CBC;
12661     }
12662     #endif /* WOLFSSL_AES_128 */
12663 
12664 
12665     #ifdef WOLFSSL_AES_192
12666     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void)
12667     {
12668         WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cbc");
12669         if (EVP_AES_192_CBC == NULL)
12670             wolfSSL_EVP_init();
12671         return EVP_AES_192_CBC;
12672     }
12673     #endif /* WOLFSSL_AES_192 */
12674 
12675 
12676     #ifdef WOLFSSL_AES_256
12677     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void)
12678     {
12679         WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cbc");
12680         if (EVP_AES_256_CBC == NULL)
12681             wolfSSL_EVP_init();
12682         return EVP_AES_256_CBC;
12683     }
12684     #endif /* WOLFSSL_AES_256 */
12685     #endif /* HAVE_AES_CBC */
12686 
12687 
12688     #ifdef WOLFSSL_AES_128
12689     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void)
12690     {
12691         WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ctr");
12692         if (EVP_AES_128_CTR == NULL)
12693             wolfSSL_EVP_init();
12694         return EVP_AES_128_CTR;
12695     }
12696     #endif /* WOLFSSL_AES_2128 */
12697 
12698 
12699     #ifdef WOLFSSL_AES_192
12700     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void)
12701     {
12702         WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ctr");
12703         if (EVP_AES_192_CTR == NULL)
12704             wolfSSL_EVP_init();
12705         return EVP_AES_192_CTR;
12706     }
12707     #endif /* WOLFSSL_AES_192 */
12708 
12709 
12710     #ifdef WOLFSSL_AES_256
12711     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void)
12712     {
12713         WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ctr");
12714         if (EVP_AES_256_CTR == NULL)
12715             wolfSSL_EVP_init();
12716         return EVP_AES_256_CTR;
12717     }
12718     #endif /* WOLFSSL_AES_256 */
12719 
12720     #ifdef WOLFSSL_AES_128
12721     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ecb(void)
12722     {
12723         WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ecb");
12724         if (EVP_AES_128_ECB == NULL)
12725             wolfSSL_EVP_init();
12726         return EVP_AES_128_ECB;
12727     }
12728     #endif /* WOLFSSL_AES_128 */
12729 
12730 
12731     #ifdef WOLFSSL_AES_192
12732     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ecb(void)
12733     {
12734         WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ecb");
12735         if (EVP_AES_192_ECB == NULL)
12736             wolfSSL_EVP_init();
12737         return EVP_AES_192_ECB;
12738     }
12739     #endif /* WOLFSSL_AES_192*/
12740 
12741 
12742     #ifdef WOLFSSL_AES_256
12743     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ecb(void)
12744     {
12745         WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ecb");
12746         if (EVP_AES_256_ECB == NULL)
12747             wolfSSL_EVP_init();
12748         return EVP_AES_256_ECB;
12749     }
12750     #endif /* WOLFSSL_AES_256 */
12751     #endif /* NO_AES */
12752 
12753 #ifndef NO_DES3
12754     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void)
12755     {
12756         WOLFSSL_ENTER("wolfSSL_EVP_des_cbc");
12757         if (EVP_DES_CBC == NULL)
12758             wolfSSL_EVP_init();
12759         return EVP_DES_CBC;
12760     }
12761 #ifdef WOLFSSL_DES_ECB
12762     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ecb(void)
12763     {
12764         WOLFSSL_ENTER("wolfSSL_EVP_des_ecb");
12765         if (EVP_DES_ECB == NULL)
12766             wolfSSL_EVP_init();
12767         return EVP_DES_ECB;
12768     }
12769 #endif
12770     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void)
12771     {
12772         WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_cbc");
12773         if (EVP_DES_EDE3_CBC == NULL)
12774             wolfSSL_EVP_init();
12775         return EVP_DES_EDE3_CBC;
12776     }
12777 #ifdef WOLFSSL_DES_ECB
12778     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_ecb(void)
12779     {
12780         WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_ecb");
12781         if (EVP_DES_EDE3_ECB == NULL)
12782             wolfSSL_EVP_init();
12783         return EVP_DES_EDE3_ECB;
12784     }
12785 #endif
12786 #endif /* NO_DES3 */
12787 
12788 #ifndef NO_RC4
12789     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc4(void)
12790     {
12791         static const char* type = "ARC4";
12792         WOLFSSL_ENTER("wolfSSL_EVP_rc4");
12793         return type;
12794     }
12795 #endif
12796 
12797 #ifdef HAVE_IDEA
12798     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_idea_cbc(void)
12799     {
12800         WOLFSSL_ENTER("wolfSSL_EVP_idea_cbc");
12801         if (EVP_IDEA_CBC == NULL)
12802             wolfSSL_EVP_init();
12803         return EVP_IDEA_CBC;
12804     }
12805 #endif
12806     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void)
12807     {
12808         static const char* type = "NULL";
12809         WOLFSSL_ENTER("wolfSSL_EVP_enc_null");
12810         return type;
12811     }
12812 
12813 
12814     int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx)
12815     {
12816         WOLFSSL_ENTER("EVP_MD_CTX_cleanup");
12817         ForceZero(ctx, sizeof(*ctx));
12818         ctx->macType = 0xFF;
12819         return 1;
12820     }
12821 
12822 
12823 
12824     void wolfSSL_EVP_CIPHER_CTX_init(WOLFSSL_EVP_CIPHER_CTX* ctx)
12825     {
12826         WOLFSSL_ENTER("EVP_CIPHER_CTX_init");
12827         if (ctx) {
12828             ctx->cipherType = 0xff;   /* no init */
12829             ctx->keyLen     = 0;
12830             ctx->enc        = 1;      /* start in encrypt mode */
12831         }
12832     }
12833 
12834 
12835     /* WOLFSSL_SUCCESS on ok */
12836     int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx)
12837     {
12838         WOLFSSL_ENTER("EVP_CIPHER_CTX_cleanup");
12839         if (ctx) {
12840             ctx->cipherType = 0xff;  /* no more init */
12841             ctx->keyLen     = 0;
12842         }
12843 
12844         return WOLFSSL_SUCCESS;
12845     }
12846 
12847 
12848     /* return WOLFSSL_SUCCESS on ok, 0 on failure to match API compatibility */
12849     int  wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
12850                                const WOLFSSL_EVP_CIPHER* type, const byte* key,
12851                                const byte* iv, int enc)
12852     {
12853         int ret = 0;
12854         (void)key;
12855         (void)iv;
12856         (void)enc;
12857 
12858         WOLFSSL_ENTER("wolfSSL_EVP_CipherInit");
12859         if (ctx == NULL) {
12860             WOLFSSL_MSG("no ctx");
12861             return 0;   /* failure */
12862         }
12863 
12864         if (type == NULL && ctx->cipherType == WOLFSSL_EVP_CIPH_TYPE_INIT) {
12865             WOLFSSL_MSG("no type set");
12866             return 0;   /* failure */
12867         }
12868         if (ctx->cipherType == WOLFSSL_EVP_CIPH_TYPE_INIT){
12869             ctx->bufUsed = 0;
12870             ctx->lastUsed = 0;
12871             ctx->flags   = 0;
12872         }
12873 #ifndef NO_AES
12874     #ifdef HAVE_AES_CBC
12875         #ifdef WOLFSSL_AES_128
12876         if (ctx->cipherType == AES_128_CBC_TYPE ||
12877             (type && XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)) {
12878             WOLFSSL_MSG("EVP_AES_128_CBC");
12879             ctx->cipherType = AES_128_CBC_TYPE;
12880             ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
12881             ctx->flags     |= WOLFSSL_EVP_CIPH_CBC_MODE;
12882             ctx->keyLen     = 16;
12883             ctx->block_size = AES_BLOCK_SIZE;
12884             if (enc == 0 || enc == 1)
12885                 ctx->enc = enc ? 1 : 0;
12886             if (key) {
12887                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
12888                                 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
12889                 if (ret != 0)
12890                     return ret;
12891             }
12892             if (iv && key == NULL) {
12893                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
12894                 if (ret != 0)
12895                     return ret;
12896             }
12897         }
12898         #endif /* WOLFSSL_AES_128 */
12899         #ifdef WOLFSSL_AES_192
12900         if (ctx->cipherType == AES_192_CBC_TYPE ||
12901                  (type && XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)) {
12902             WOLFSSL_MSG("EVP_AES_192_CBC");
12903             ctx->cipherType = AES_192_CBC_TYPE;
12904             ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
12905             ctx->flags     |= WOLFSSL_EVP_CIPH_CBC_MODE;
12906             ctx->keyLen     = 24;
12907             ctx->block_size = AES_BLOCK_SIZE;
12908             if (enc == 0 || enc == 1)
12909                 ctx->enc = enc ? 1 : 0;
12910             if (key) {
12911                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
12912                                 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
12913                 if (ret != 0)
12914                     return ret;
12915             }
12916             if (iv && key == NULL) {
12917                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
12918                 if (ret != 0)
12919                     return ret;
12920             }
12921         }
12922         #endif /* WOLFSSL_AES_192 */
12923         #ifdef WOLFSSL_AES_256
12924         if (ctx->cipherType == AES_256_CBC_TYPE ||
12925                  (type && XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)) {
12926             WOLFSSL_MSG("EVP_AES_256_CBC");
12927             ctx->cipherType = AES_256_CBC_TYPE;
12928             ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
12929             ctx->flags     |= WOLFSSL_EVP_CIPH_CBC_MODE;
12930             ctx->keyLen     = 32;
12931             ctx->block_size = AES_BLOCK_SIZE;
12932             if (enc == 0 || enc == 1)
12933                 ctx->enc = enc ? 1 : 0;
12934             if (key) {
12935                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
12936                                 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
12937                 if (ret != 0){
12938                     WOLFSSL_MSG("wc_AesSetKey() failed");
12939                     return ret;
12940                 }
12941             }
12942             if (iv && key == NULL) {
12943                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
12944                 if (ret != 0){
12945                     WOLFSSL_MSG("wc_AesSetIV() failed");
12946                     return ret;
12947                 }
12948             }
12949         }
12950         #endif /* WOLFSSL_AES_256 */
12951     #endif /* HAVE_AES_CBC */
12952 #ifdef WOLFSSL_AES_COUNTER
12953         #ifdef WOLFSSL_AES_128
12954         if (ctx->cipherType == AES_128_CTR_TYPE ||
12955                  (type && XSTRNCMP(type, EVP_AES_128_CTR, EVP_AES_SIZE) == 0)) {
12956             WOLFSSL_MSG("EVP_AES_128_CTR");
12957             ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
12958             ctx->cipherType = AES_128_CTR_TYPE;
12959             ctx->flags     |= WOLFSSL_EVP_CIPH_CTR_MODE;
12960             ctx->keyLen     = 16;
12961             ctx->block_size = AES_BLOCK_SIZE;
12962             if (enc == 0 || enc == 1)
12963                 ctx->enc = enc ? 1 : 0;
12964             if (key) {
12965               ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
12966                     AES_ENCRYPTION);
12967                 if (ret != 0)
12968                     return ret;
12969             }
12970             if (iv && key == NULL) {
12971                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
12972                 if (ret != 0)
12973                     return ret;
12974             }
12975         }
12976         #endif /* WOLFSSL_AES_128 */
12977         #ifdef WOLFSSL_AES_192
12978         if (ctx->cipherType == AES_192_CTR_TYPE ||
12979                  (type && XSTRNCMP(type, EVP_AES_192_CTR, EVP_AES_SIZE) == 0)) {
12980             WOLFSSL_MSG("EVP_AES_192_CTR");
12981             ctx->cipherType = AES_192_CTR_TYPE;
12982             ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
12983             ctx->flags     |= WOLFSSL_EVP_CIPH_CTR_MODE;
12984             ctx->keyLen     = 24;
12985             ctx->block_size = AES_BLOCK_SIZE;
12986             if (enc == 0 || enc == 1)
12987                 ctx->enc = enc ? 1 : 0;
12988             if (key) {
12989                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
12990                       AES_ENCRYPTION);
12991                 if (ret != 0)
12992                     return ret;
12993             }
12994             if (iv && key == NULL) {
12995                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
12996                 if (ret != 0)
12997                     return ret;
12998             }
12999         }
13000         #endif /* WOLFSSL_AES_192 */
13001         #ifdef WOLFSSL_AES_256
13002         if (ctx->cipherType == AES_256_CTR_TYPE ||
13003                  (type && XSTRNCMP(type, EVP_AES_256_CTR, EVP_AES_SIZE) == 0)) {
13004             WOLFSSL_MSG("EVP_AES_256_CTR");
13005             ctx->cipherType = AES_256_CTR_TYPE;
13006             ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
13007             ctx->flags     |= WOLFSSL_EVP_CIPH_CTR_MODE;
13008             ctx->keyLen     = 32;
13009             ctx->block_size = AES_BLOCK_SIZE;
13010             if (enc == 0 || enc == 1)
13011                 ctx->enc = enc ? 1 : 0;
13012             if (key) {
13013                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
13014                       AES_ENCRYPTION);
13015                 if (ret != 0)
13016                     return ret;
13017             }
13018             if (iv && key == NULL) {
13019                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
13020                 if (ret != 0)
13021                     return ret;
13022             }
13023         }
13024         #endif /* WOLFSSL_AES_256 */
13025 #endif /* WOLFSSL_AES_COUNTER */
13026         #ifdef WOLFSSL_AES_128
13027         if (ctx->cipherType == AES_128_ECB_TYPE ||
13028             (type && XSTRNCMP(type, EVP_AES_128_ECB, EVP_AES_SIZE) == 0)) {
13029             WOLFSSL_MSG("EVP_AES_128_ECB");
13030             ctx->cipherType = AES_128_ECB_TYPE;
13031             ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
13032             ctx->flags     |= WOLFSSL_EVP_CIPH_ECB_MODE;
13033             ctx->keyLen     = 16;
13034             ctx->block_size = AES_BLOCK_SIZE;
13035             if (enc == 0 || enc == 1)
13036                 ctx->enc = enc ? 1 : 0;
13037             if (key) {
13038                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, NULL,
13039                       ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
13040             }
13041             if (ret != 0)
13042                 return ret;
13043         }
13044         #endif /* WOLFSSL_AES_128 */
13045         #ifdef WOLFSSL_AES_192
13046         if (ctx->cipherType == AES_192_ECB_TYPE ||
13047                  (type && XSTRNCMP(type, EVP_AES_192_ECB, EVP_AES_SIZE) == 0)) {
13048             WOLFSSL_MSG("EVP_AES_192_ECB");
13049             ctx->cipherType = AES_192_ECB_TYPE;
13050             ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
13051             ctx->flags     |= WOLFSSL_EVP_CIPH_ECB_MODE;
13052             ctx->keyLen     = 24;
13053             ctx->block_size = AES_BLOCK_SIZE;
13054             if (enc == 0 || enc == 1)
13055                 ctx->enc = enc ? 1 : 0;
13056             if (key) {
13057                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, NULL,
13058                       ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
13059             }
13060             if (ret != 0)
13061                 return ret;
13062         }
13063         #endif /* WOLFSSL_AES_192 */
13064         #ifdef WOLFSSL_AES_256
13065         if (ctx->cipherType == AES_256_ECB_TYPE ||
13066                  (type && XSTRNCMP(type, EVP_AES_256_ECB, EVP_AES_SIZE) == 0)) {
13067             WOLFSSL_MSG("EVP_AES_256_ECB");
13068             ctx->cipherType = AES_256_ECB_TYPE;
13069             ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
13070             ctx->flags     |= WOLFSSL_EVP_CIPH_ECB_MODE;
13071             ctx->keyLen     = 32;
13072             ctx->block_size = AES_BLOCK_SIZE;
13073             if (enc == 0 || enc == 1)
13074                 ctx->enc = enc ? 1 : 0;
13075             if (key) {
13076               ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, NULL,
13077                     ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
13078             }
13079             if (ret != 0)
13080                 return ret;
13081         }
13082         #endif /* WOLFSSL_AES_256 */
13083 #endif /* NO_AES */
13084 
13085 #ifndef NO_DES3
13086         if (ctx->cipherType == DES_CBC_TYPE ||
13087                  (type && XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0)) {
13088             WOLFSSL_MSG("EVP_DES_CBC");
13089             ctx->cipherType = DES_CBC_TYPE;
13090             ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
13091             ctx->flags     |= WOLFSSL_EVP_CIPH_CBC_MODE;
13092             ctx->keyLen     = 8;
13093             ctx->block_size = DES_BLOCK_SIZE;
13094             if (enc == 0 || enc == 1)
13095                 ctx->enc = enc ? 1 : 0;
13096             if (key) {
13097                 ret = wc_Des_SetKey(&ctx->cipher.des, key, iv,
13098                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
13099                 if (ret != 0)
13100                     return ret;
13101             }
13102 
13103             if (iv && key == NULL)
13104                 wc_Des_SetIV(&ctx->cipher.des, iv);
13105         }
13106 #ifdef WOLFSSL_DES_ECB
13107         else if (ctx->cipherType == DES_ECB_TYPE ||
13108                  (type && XSTRNCMP(type, EVP_DES_ECB, EVP_DES_SIZE) == 0)) {
13109             WOLFSSL_MSG("EVP_DES_ECB");
13110             ctx->cipherType = DES_ECB_TYPE;
13111             ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
13112             ctx->flags     |= WOLFSSL_EVP_CIPH_ECB_MODE;
13113             ctx->keyLen     = 8;
13114             ctx->block_size = DES_BLOCK_SIZE;
13115             if (enc == 0 || enc == 1)
13116                 ctx->enc = enc ? 1 : 0;
13117             if (key) {
13118                 WOLFSSL_MSG("Des_SetKey");
13119                 ret = wc_Des_SetKey(&ctx->cipher.des, key, NULL,
13120                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
13121                 if (ret != 0)
13122                     return ret;
13123             }
13124         }
13125 #endif
13126         else if (ctx->cipherType == DES_EDE3_CBC_TYPE ||
13127                  (type &&
13128                   XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)) {
13129             WOLFSSL_MSG("EVP_DES_EDE3_CBC");
13130             ctx->cipherType = DES_EDE3_CBC_TYPE;
13131             ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
13132             ctx->flags     |= WOLFSSL_EVP_CIPH_CBC_MODE;
13133             ctx->keyLen     = 24;
13134             ctx->block_size = DES_BLOCK_SIZE;
13135             if (enc == 0 || enc == 1)
13136                 ctx->enc = enc ? 1 : 0;
13137             if (key) {
13138                 ret = wc_Des3_SetKey(&ctx->cipher.des3, key, iv,
13139                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
13140                 if (ret != 0)
13141                     return ret;
13142             }
13143 
13144             if (iv && key == NULL) {
13145                 ret = wc_Des3_SetIV(&ctx->cipher.des3, iv);
13146                 if (ret != 0)
13147                     return ret;
13148             }
13149         }
13150         else if (ctx->cipherType == DES_EDE3_ECB_TYPE ||
13151                  (type &&
13152                   XSTRNCMP(type, EVP_DES_EDE3_ECB, EVP_DES_EDE3_SIZE) == 0)) {
13153             WOLFSSL_MSG("EVP_DES_EDE3_ECB");
13154             ctx->cipherType = DES_EDE3_ECB_TYPE;
13155             ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
13156             ctx->flags     |= WOLFSSL_EVP_CIPH_ECB_MODE;
13157             ctx->keyLen     = 24;
13158             ctx->block_size = DES_BLOCK_SIZE;
13159             if (enc == 0 || enc == 1)
13160                 ctx->enc = enc ? 1 : 0;
13161             if (key) {
13162                 ret = wc_Des3_SetKey(&ctx->cipher.des3, key, NULL,
13163                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
13164                 if (ret != 0)
13165                     return ret;
13166             }
13167         }
13168 #endif /* NO_DES3 */
13169 #ifndef NO_RC4
13170         if (ctx->cipherType == ARC4_TYPE || (type &&
13171                                      XSTRNCMP(type, "ARC4", 4) == 0)) {
13172             WOLFSSL_MSG("ARC4");
13173             ctx->cipherType = ARC4_TYPE;
13174             ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
13175             ctx->flags     |= WOLFSSL_EVP_CIPH_STREAM_CIPHER;
13176             ctx->block_size = 1;
13177             if (ctx->keyLen == 0)  /* user may have already set */
13178                 ctx->keyLen = 16;  /* default to 128 */
13179             if (key)
13180                 wc_Arc4SetKey(&ctx->cipher.arc4, key, ctx->keyLen);
13181         }
13182 #endif /* NO_RC4 */
13183 #ifdef HAVE_IDEA
13184         if (ctx->cipherType == IDEA_CBC_TYPE ||
13185                  (type && XSTRNCMP(type, EVP_IDEA_CBC, EVP_IDEA_SIZE) == 0)) {
13186             WOLFSSL_MSG("EVP_IDEA_CBC");
13187             ctx->cipherType = IDEA_CBC_TYPE;
13188             ctx->flags     &= ~WOLFSSL_EVP_CIPH_MODE;
13189             ctx->flags     |= WOLFSSL_EVP_CIPH_CBC_MODE;
13190             ctx->keyLen     = IDEA_KEY_SIZE;
13191             ctx->block_size = 8;
13192             if (enc == 0 || enc == 1)
13193                 ctx->enc = enc ? 1 : 0;
13194             if (key) {
13195                 ret = wc_IdeaSetKey(&ctx->cipher.idea, key, (word16)ctx->keyLen,
13196                                     iv, ctx->enc ? IDEA_ENCRYPTION :
13197                                                    IDEA_DECRYPTION);
13198                 if (ret != 0)
13199                     return ret;
13200             }
13201 
13202             if (iv && key == NULL)
13203                 wc_IdeaSetIV(&ctx->cipher.idea, iv);
13204         }
13205 #endif /* HAVE_IDEA */
13206         if (ctx->cipherType == NULL_CIPHER_TYPE || (type &&
13207                                      XSTRNCMP(type, "NULL", 4) == 0)) {
13208             WOLFSSL_MSG("NULL cipher");
13209             ctx->cipherType = NULL_CIPHER_TYPE;
13210             ctx->keyLen = 0;
13211             ctx->block_size = 16;
13212         }
13213         (void)ret; /* remove warning. If execution reaches this point, ret=0 */
13214         return WOLFSSL_SUCCESS;
13215     }
13216 
13217 
13218     /* WOLFSSL_SUCCESS on ok */
13219     int wolfSSL_EVP_CIPHER_CTX_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx)
13220     {
13221         WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_key_length");
13222         if (ctx)
13223             return ctx->keyLen;
13224 
13225         return 0;   /* failure */
13226     }
13227 
13228 
13229     /* WOLFSSL_SUCCESS on ok */
13230     int wolfSSL_EVP_CIPHER_CTX_set_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx,
13231                                              int keylen)
13232     {
13233         WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_set_key_length");
13234         if (ctx)
13235             ctx->keyLen = keylen;
13236         else
13237             return 0;  /* failure */
13238 
13239         return WOLFSSL_SUCCESS;
13240     }
13241 
13242 
13243     /* WOLFSSL_SUCCESS on ok */
13244     int wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* dst, byte* src,
13245                           word32 len)
13246     {
13247         int ret = 0;
13248         WOLFSSL_ENTER("wolfSSL_EVP_Cipher");
13249 
13250         if (ctx == NULL || dst == NULL || src == NULL) {
13251             WOLFSSL_MSG("Bad function argument");
13252             return 0;  /* failure */
13253         }
13254 
13255         if (ctx->cipherType == 0xff) {
13256             WOLFSSL_MSG("no init");
13257             return 0;  /* failure */
13258         }
13259 
13260         switch (ctx->cipherType) {
13261 
13262 #ifndef NO_AES
13263 #ifdef HAVE_AES_CBC
13264             case AES_128_CBC_TYPE :
13265             case AES_192_CBC_TYPE :
13266             case AES_256_CBC_TYPE :
13267                 WOLFSSL_MSG("AES CBC");
13268                 if (ctx->enc)
13269                     ret = wc_AesCbcEncrypt(&ctx->cipher.aes, dst, src, len);
13270                 else
13271                     ret = wc_AesCbcDecrypt(&ctx->cipher.aes, dst, src, len);
13272                 break;
13273 #endif /* HAVE_AES_CBC */
13274 #ifdef HAVE_AES_ECB
13275             case AES_128_ECB_TYPE :
13276             case AES_192_ECB_TYPE :
13277             case AES_256_ECB_TYPE :
13278                 WOLFSSL_MSG("AES ECB");
13279                 if (ctx->enc)
13280                     ret = wc_AesEcbEncrypt(&ctx->cipher.aes, dst, src, len);
13281                 else
13282                     ret = wc_AesEcbDecrypt(&ctx->cipher.aes, dst, src, len);
13283                 break;
13284 #endif
13285 #ifdef WOLFSSL_AES_COUNTER
13286             case AES_128_CTR_TYPE :
13287             case AES_192_CTR_TYPE :
13288             case AES_256_CTR_TYPE :
13289                     WOLFSSL_MSG("AES CTR");
13290                     ret = wc_AesCtrEncrypt(&ctx->cipher.aes, dst, src, len);
13291                 break;
13292 #endif /* WOLFSSL_AES_COUNTER */
13293 #endif /* NO_AES */
13294 
13295 #ifndef NO_DES3
13296             case DES_CBC_TYPE :
13297                 if (ctx->enc)
13298                     wc_Des_CbcEncrypt(&ctx->cipher.des, dst, src, len);
13299                 else
13300                     wc_Des_CbcDecrypt(&ctx->cipher.des, dst, src, len);
13301                 break;
13302             case DES_EDE3_CBC_TYPE :
13303                 if (ctx->enc)
13304                     ret = wc_Des3_CbcEncrypt(&ctx->cipher.des3, dst, src, len);
13305                 else
13306                     ret = wc_Des3_CbcDecrypt(&ctx->cipher.des3, dst, src, len);
13307                 break;
13308 #ifdef WOLFSSL_DES_ECB
13309             case DES_ECB_TYPE :
13310                 ret = wc_Des_EcbEncrypt(&ctx->cipher.des, dst, src, len);
13311                 break;
13312             case DES_EDE3_ECB_TYPE :
13313                 ret = wc_Des3_EcbEncrypt(&ctx->cipher.des3, dst, src, len);
13314                 break;
13315 #endif
13316 #endif /* !NO_DES3 */
13317 
13318 #ifndef NO_RC4
13319             case ARC4_TYPE :
13320                 wc_Arc4Process(&ctx->cipher.arc4, dst, src, len);
13321                 break;
13322 #endif
13323 
13324 #ifdef HAVE_IDEA
13325             case IDEA_CBC_TYPE :
13326                 if (ctx->enc)
13327                     wc_IdeaCbcEncrypt(&ctx->cipher.idea, dst, src, len);
13328                 else
13329                     wc_IdeaCbcDecrypt(&ctx->cipher.idea, dst, src, len);
13330                 break;
13331 #endif
13332             case NULL_CIPHER_TYPE :
13333                 XMEMCPY(dst, src, len);
13334                 break;
13335 
13336             default: {
13337                 WOLFSSL_MSG("bad type");
13338                 return 0;  /* failure */
13339             }
13340         }
13341 
13342         if (ret != 0) {
13343             WOLFSSL_MSG("wolfSSL_EVP_Cipher failure");
13344             return 0;  /* failure */
13345         }
13346 
13347         WOLFSSL_MSG("wolfSSL_EVP_Cipher success");
13348         return WOLFSSL_SUCCESS;  /* success */
13349     }
13350 
13351 #define WOLFSSL_EVP_INCLUDED
13352 #include "wolfcrypt/src/evp.c"
13353 
13354 
13355     /* store for external read of iv, WOLFSSL_SUCCESS on success */
13356     int  wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
13357     {
13358         WOLFSSL_ENTER("wolfSSL_StoreExternalIV");
13359 
13360         if (ctx == NULL) {
13361             WOLFSSL_MSG("Bad function argument");
13362             return WOLFSSL_FATAL_ERROR;
13363         }
13364 
13365         switch (ctx->cipherType) {
13366 
13367 #ifndef NO_AES
13368             case AES_128_CBC_TYPE :
13369             case AES_192_CBC_TYPE :
13370             case AES_256_CBC_TYPE :
13371                 WOLFSSL_MSG("AES CBC");
13372                 XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
13373                 break;
13374 
13375 #ifdef WOLFSSL_AES_COUNTER
13376             case AES_128_CTR_TYPE :
13377             case AES_192_CTR_TYPE :
13378             case AES_256_CTR_TYPE :
13379                 WOLFSSL_MSG("AES CTR");
13380                 XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
13381                 break;
13382 #endif /* WOLFSSL_AES_COUNTER */
13383 
13384 #endif /* NO_AES */
13385 
13386 #ifndef NO_DES3
13387             case DES_CBC_TYPE :
13388                 WOLFSSL_MSG("DES CBC");
13389                 XMEMCPY(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
13390                 break;
13391 
13392             case DES_EDE3_CBC_TYPE :
13393                 WOLFSSL_MSG("DES EDE3 CBC");
13394                 XMEMCPY(ctx->iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
13395                 break;
13396 #endif
13397 
13398 #ifdef HAVE_IDEA
13399             case IDEA_CBC_TYPE :
13400                 WOLFSSL_MSG("IDEA CBC");
13401                 XMEMCPY(ctx->iv, &ctx->cipher.idea.reg, IDEA_BLOCK_SIZE);
13402                 break;
13403 #endif
13404             case ARC4_TYPE :
13405                 WOLFSSL_MSG("ARC4");
13406                 break;
13407 
13408             case NULL_CIPHER_TYPE :
13409                 WOLFSSL_MSG("NULL");
13410                 break;
13411 
13412             default: {
13413                 WOLFSSL_MSG("bad type");
13414                 return WOLFSSL_FATAL_ERROR;
13415             }
13416         }
13417         return WOLFSSL_SUCCESS;
13418     }
13419 
13420 
13421     /* set internal IV from external, WOLFSSL_SUCCESS on success */
13422     int  wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
13423     {
13424 
13425         WOLFSSL_ENTER("wolfSSL_SetInternalIV");
13426 
13427         if (ctx == NULL) {
13428             WOLFSSL_MSG("Bad function argument");
13429             return WOLFSSL_FATAL_ERROR;
13430         }
13431 
13432         switch (ctx->cipherType) {
13433 
13434 #ifndef NO_AES
13435             case AES_128_CBC_TYPE :
13436             case AES_192_CBC_TYPE :
13437             case AES_256_CBC_TYPE :
13438                 WOLFSSL_MSG("AES CBC");
13439                 XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
13440                 break;
13441 
13442 #ifdef WOLFSSL_AES_COUNTER
13443             case AES_128_CTR_TYPE :
13444             case AES_192_CTR_TYPE :
13445             case AES_256_CTR_TYPE :
13446                 WOLFSSL_MSG("AES CTR");
13447                 XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
13448                 break;
13449 #endif
13450 
13451 #endif /* NO_AES */
13452 
13453 #ifndef NO_DES3
13454             case DES_CBC_TYPE :
13455                 WOLFSSL_MSG("DES CBC");
13456                 XMEMCPY(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
13457                 break;
13458 
13459             case DES_EDE3_CBC_TYPE :
13460                 WOLFSSL_MSG("DES EDE3 CBC");
13461                 XMEMCPY(&ctx->cipher.des3.reg, ctx->iv, DES_BLOCK_SIZE);
13462                 break;
13463 #endif
13464 
13465 #ifdef HAVE_IDEA
13466             case IDEA_CBC_TYPE :
13467                 WOLFSSL_MSG("IDEA CBC");
13468                 XMEMCPY(&ctx->cipher.idea.reg, ctx->iv, IDEA_BLOCK_SIZE);
13469                 break;
13470 #endif
13471             case ARC4_TYPE :
13472                 WOLFSSL_MSG("ARC4");
13473                 break;
13474 
13475             case NULL_CIPHER_TYPE :
13476                 WOLFSSL_MSG("NULL");
13477                 break;
13478 
13479             default: {
13480                 WOLFSSL_MSG("bad type");
13481                 return WOLFSSL_FATAL_ERROR;
13482             }
13483         }
13484         return WOLFSSL_SUCCESS;
13485     }
13486 
13487 
13488     /* WOLFSSL_SUCCESS on ok */
13489     int wolfSSL_EVP_DigestInit(WOLFSSL_EVP_MD_CTX* ctx,
13490                                const WOLFSSL_EVP_MD* type)
13491     {
13492         int ret = WOLFSSL_SUCCESS;
13493 
13494         WOLFSSL_ENTER("EVP_DigestInit");
13495 
13496         if (ctx == NULL || type == NULL) {
13497             return BAD_FUNC_ARG;
13498         }
13499 
13500 
13501     #ifdef WOLFSSL_ASYNC_CRYPT
13502         /* compile-time validation of ASYNC_CTX_SIZE */
13503         typedef char async_test[WC_ASYNC_DEV_SIZE >= sizeof(WC_ASYNC_DEV) ?
13504                                                                         1 : -1];
13505         (void)sizeof(async_test);
13506     #endif
13507 
13508         if (XSTRNCMP(type, "SHA256", 6) == 0) {
13509              ctx->macType = WC_SHA256;
13510              ret = wolfSSL_SHA256_Init(&(ctx->hash.digest.sha256));
13511         }
13512     #ifdef WOLFSSL_SHA224
13513         else if (XSTRNCMP(type, "SHA224", 6) == 0) {
13514              ctx->macType = WC_SHA224;
13515              ret = wolfSSL_SHA224_Init(&(ctx->hash.digest.sha224));
13516         }
13517     #endif
13518     #ifdef WOLFSSL_SHA384
13519         else if (XSTRNCMP(type, "SHA384", 6) == 0) {
13520              ctx->macType = WC_SHA384;
13521              ret = wolfSSL_SHA384_Init(&(ctx->hash.digest.sha384));
13522         }
13523     #endif
13524     #ifdef WOLFSSL_SHA512
13525         else if (XSTRNCMP(type, "SHA512", 6) == 0) {
13526              ctx->macType = WC_SHA512;
13527              ret = wolfSSL_SHA512_Init(&(ctx->hash.digest.sha512));
13528         }
13529     #endif
13530     #ifndef NO_MD4
13531         else if (XSTRNCMP(type, "MD4", 3) == 0) {
13532             ctx->macType = MD4;
13533             wolfSSL_MD4_Init(&(ctx->hash.digest.md4));
13534         }
13535     #endif
13536     #ifndef NO_MD5
13537         else if (XSTRNCMP(type, "MD5", 3) == 0) {
13538             ctx->macType = WC_MD5;
13539             ret = wolfSSL_MD5_Init(&(ctx->hash.digest.md5));
13540         }
13541     #endif
13542     #ifndef NO_SHA
13543         /* has to be last since would pick or 224, 256, 384, or 512 too */
13544         else if (XSTRNCMP(type, "SHA", 3) == 0) {
13545              ctx->macType = WC_SHA;
13546              ret = wolfSSL_SHA_Init(&(ctx->hash.digest.sha));
13547         }
13548     #endif /* NO_SHA */
13549         else
13550              return BAD_FUNC_ARG;
13551 
13552         return ret;
13553     }
13554 
13555 
13556     /* WOLFSSL_SUCCESS on ok, WOLFSSL_FAILURE on failure */
13557     int wolfSSL_EVP_DigestUpdate(WOLFSSL_EVP_MD_CTX* ctx, const void* data,
13558                                 size_t sz)
13559     {
13560         WOLFSSL_ENTER("EVP_DigestUpdate");
13561 
13562         switch (ctx->macType) {
13563 #ifndef NO_MD4
13564             case MD4:
13565                 wolfSSL_MD4_Update((MD4_CTX*)&ctx->hash, data,
13566                                   (unsigned long)sz);
13567                 break;
13568 #endif
13569 #ifndef NO_MD5
13570             case WC_MD5:
13571                 wolfSSL_MD5_Update((MD5_CTX*)&ctx->hash, data,
13572                                   (unsigned long)sz);
13573                 break;
13574 #endif
13575 #ifndef NO_SHA
13576             case WC_SHA:
13577                 wolfSSL_SHA_Update((SHA_CTX*)&ctx->hash, data,
13578                                   (unsigned long)sz);
13579                 break;
13580 #endif
13581 #ifdef WOLFSSL_SHA224
13582             case WC_SHA224:
13583                 wolfSSL_SHA224_Update((SHA224_CTX*)&ctx->hash, data,
13584                                      (unsigned long)sz);
13585                 break;
13586 #endif
13587 #ifndef NO_SHA256
13588             case WC_SHA256:
13589                 wolfSSL_SHA256_Update((SHA256_CTX*)&ctx->hash, data,
13590                                      (unsigned long)sz);
13591                 break;
13592 #endif /* !NO_SHA256 */
13593 #ifdef WOLFSSL_SHA384
13594             case WC_SHA384:
13595                 wolfSSL_SHA384_Update((SHA384_CTX*)&ctx->hash, data,
13596                                      (unsigned long)sz);
13597                 break;
13598 #endif
13599 #ifdef WOLFSSL_SHA512
13600             case WC_SHA512:
13601                 wolfSSL_SHA512_Update((SHA512_CTX*)&ctx->hash, data,
13602                                      (unsigned long)sz);
13603                 break;
13604 #endif /* WOLFSSL_SHA512 */
13605             default:
13606                 return WOLFSSL_FAILURE;
13607         }
13608 
13609         return WOLFSSL_SUCCESS;
13610     }
13611 
13612 
13613     /* WOLFSSL_SUCCESS on ok */
13614     int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md,
13615                                unsigned int* s)
13616     {
13617         WOLFSSL_ENTER("EVP_DigestFinal");
13618         switch (ctx->macType) {
13619 #ifndef NO_MD4
13620             case MD4:
13621                 wolfSSL_MD4_Final(md, (MD4_CTX*)&ctx->hash);
13622                 if (s) *s = MD4_DIGEST_SIZE;
13623                 break;
13624 #endif
13625 #ifndef NO_MD5
13626             case WC_MD5:
13627                 wolfSSL_MD5_Final(md, (MD5_CTX*)&ctx->hash);
13628                 if (s) *s = WC_MD5_DIGEST_SIZE;
13629                 break;
13630 #endif
13631 #ifndef NO_SHA
13632             case WC_SHA:
13633                 wolfSSL_SHA_Final(md, (SHA_CTX*)&ctx->hash);
13634                 if (s) *s = WC_SHA_DIGEST_SIZE;
13635                 break;
13636 #endif
13637 #ifdef WOLFSSL_SHA224
13638             case WC_SHA224:
13639                 wolfSSL_SHA224_Final(md, (SHA224_CTX*)&ctx->hash);
13640                 if (s) *s = WC_SHA224_DIGEST_SIZE;
13641                 break;
13642 #endif
13643 #ifndef NO_SHA256
13644             case WC_SHA256:
13645                 wolfSSL_SHA256_Final(md, (SHA256_CTX*)&ctx->hash);
13646                 if (s) *s = WC_SHA256_DIGEST_SIZE;
13647                 break;
13648 #endif /* !NO_SHA256 */
13649 #ifdef WOLFSSL_SHA384
13650             case WC_SHA384:
13651                 wolfSSL_SHA384_Final(md, (SHA384_CTX*)&ctx->hash);
13652                 if (s) *s = WC_SHA384_DIGEST_SIZE;
13653                 break;
13654 #endif
13655 #ifdef WOLFSSL_SHA512
13656             case WC_SHA512:
13657                 wolfSSL_SHA512_Final(md, (SHA512_CTX*)&ctx->hash);
13658                 if (s) *s = WC_SHA512_DIGEST_SIZE;
13659                 break;
13660 #endif /* WOLFSSL_SHA512 */
13661             default:
13662                 return WOLFSSL_FAILURE;
13663         }
13664 
13665         return WOLFSSL_SUCCESS;
13666     }
13667 
13668 
13669     /* WOLFSSL_SUCCESS on ok */
13670     int wolfSSL_EVP_DigestFinal_ex(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md,
13671                                    unsigned int* s)
13672     {
13673         WOLFSSL_ENTER("EVP_DigestFinal_ex");
13674         return EVP_DigestFinal(ctx, md, s);
13675     }
13676 
13677 
13678     unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, const void* key,
13679                                 int key_len, const unsigned char* d, int n,
13680                                 unsigned char* md, unsigned int* md_len)
13681     {
13682         int type;
13683         int mdlen;
13684         unsigned char* ret = NULL;
13685 #ifdef WOLFSSL_SMALL_STACK
13686         Hmac* hmac = NULL;
13687 #else
13688         Hmac  hmac[1];
13689 #endif
13690         void* heap = NULL;
13691 
13692         WOLFSSL_ENTER("wolfSSL_HMAC");
13693         if (!md) {
13694             WOLFSSL_MSG("Static buffer not supported, pass in md buffer");
13695             return NULL;  /* no static buffer support */
13696         }
13697 
13698 #ifndef NO_MD5
13699         if (XSTRNCMP(evp_md, "MD5", 3) == 0) {
13700             type = WC_MD5;
13701             mdlen = WC_MD5_DIGEST_SIZE;
13702         } else
13703 #endif
13704 #ifdef WOLFSSL_SHA224
13705         if (XSTRNCMP(evp_md, "SHA224", 6) == 0) {
13706             type = WC_SHA224;
13707             mdlen = WC_SHA224_DIGEST_SIZE;
13708         } else
13709 #endif
13710 #ifndef NO_SHA256
13711         if (XSTRNCMP(evp_md, "SHA256", 6) == 0) {
13712             type = WC_SHA256;
13713             mdlen = WC_SHA256_DIGEST_SIZE;
13714         } else
13715 #endif
13716 #ifdef WOLFSSL_SHA384
13717         if (XSTRNCMP(evp_md, "SHA384", 6) == 0) {
13718             type = WC_SHA384;
13719             mdlen = WC_SHA384_DIGEST_SIZE;
13720         } else
13721 #endif
13722 #ifdef WOLFSSL_SHA512
13723         if (XSTRNCMP(evp_md, "SHA512", 6) == 0) {
13724             type = WC_SHA512;
13725             mdlen = WC_SHA512_DIGEST_SIZE;
13726         } else
13727 #endif
13728 #ifndef NO_SHA
13729         if (XSTRNCMP(evp_md, "SHA", 3) == 0) {
13730             type = WC_SHA;
13731             mdlen = WC_SHA_DIGEST_SIZE;
13732         } else
13733 #endif
13734         {
13735             return NULL;
13736         }
13737 
13738     #ifdef WOLFSSL_SMALL_STACK
13739         hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_HMAC);
13740         if (hmac == NULL)
13741             return NULL;
13742     #endif
13743 
13744         if (wc_HmacInit(hmac, heap, INVALID_DEVID) == 0) {
13745             if (wc_HmacSetKey(hmac, type, (const byte*)key, key_len) == 0) {
13746                 if (wc_HmacUpdate(hmac, d, n) == 0) {
13747                     if (wc_HmacFinal(hmac, md) == 0) {
13748                         if (md_len)
13749                             *md_len = mdlen;
13750                         ret = md;
13751                     }
13752                 }
13753             }
13754             wc_HmacFree(hmac);
13755         }
13756 
13757     #ifdef WOLFSSL_SMALL_STACK
13758         XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);
13759     #endif
13760 
13761         (void)evp_md;
13762         return ret;
13763     }
13764 
13765     void wolfSSL_ERR_clear_error(void)
13766     {
13767         WOLFSSL_ENTER("wolfSSL_ERR_clear_error");
13768 
13769 #if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX)
13770         wc_ClearErrorNodes();
13771 #endif
13772     }
13773 
13774 
13775     /* frees all nodes in the current threads error queue
13776      *
13777      * id  thread id. ERR_remove_state is depriciated and id is ignored. The
13778      *     current threads queue will be free'd.
13779      */
13780     void wolfSSL_ERR_remove_state(unsigned long id)
13781     {
13782         WOLFSSL_ENTER("wolfSSL_ERR_remove_state");
13783         (void)id;
13784         if (wc_ERR_remove_state() != 0) {
13785             WOLFSSL_MSG("Error with removing the state");
13786         }
13787     }
13788 
13789 
13790     int wolfSSL_RAND_status(void)
13791     {
13792         return WOLFSSL_SUCCESS;  /* wolfCrypt provides enough seed internally */
13793     }
13794 
13795 
13796     #ifndef NO_WOLFSSL_STUB
13797     void wolfSSL_RAND_add(const void* add, int len, double entropy)
13798     {
13799         (void)add;
13800         (void)len;
13801         (void)entropy;
13802         WOLFSSL_STUB("RAND_add");
13803         /* wolfSSL seeds/adds internally, use explicit RNG if you want
13804            to take control */
13805     }
13806     #endif
13807 
13808 #ifndef NO_DES3
13809     /* 0 on ok */
13810     int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key,
13811                               WOLFSSL_DES_key_schedule* schedule)
13812     {
13813         WOLFSSL_ENTER("wolfSSL_DES_key_sched");
13814 
13815         if (key == NULL || schedule == NULL) {
13816             WOLFSSL_MSG("Null argument passed in");
13817         }
13818         else {
13819             XMEMCPY(schedule, key, sizeof(WOLFSSL_const_DES_cblock));
13820         }
13821 
13822         return 0;
13823     }
13824 
13825 
13826     /* intended to behave similar to Kerberos mit_des_cbc_cksum
13827      * return the last 4 bytes of cipher text */
13828     WOLFSSL_DES_LONG wolfSSL_DES_cbc_cksum(const unsigned char* in,
13829             WOLFSSL_DES_cblock* out, long length, WOLFSSL_DES_key_schedule* sc,
13830             WOLFSSL_const_DES_cblock* iv)
13831     {
13832         WOLFSSL_DES_LONG ret;
13833         unsigned char* tmp;
13834         unsigned char* data   = (unsigned char*)in;
13835         long           dataSz = length;
13836         byte dynamicFlag = 0; /* when padding the buffer created needs free'd */
13837 
13838         WOLFSSL_ENTER("wolfSSL_DES_cbc_cksum");
13839 
13840         if (in == NULL || out == NULL || sc == NULL || iv == NULL) {
13841             WOLFSSL_MSG("Bad argument passed in");
13842             return 0;
13843         }
13844 
13845         /* if input length is not a multiple of DES_BLOCK_SIZE pad with 0s */
13846         if (dataSz % DES_BLOCK_SIZE) {
13847             dataSz += DES_BLOCK_SIZE - (dataSz % DES_BLOCK_SIZE);
13848             data = (unsigned char*)XMALLOC(dataSz, NULL,
13849                                            DYNAMIC_TYPE_TMP_BUFFER);
13850             if (data == NULL) {
13851                 WOLFSSL_MSG("Issue creating temporary buffer");
13852                 return 0;
13853             }
13854             dynamicFlag = 1; /* set to free buffer at end */
13855             XMEMCPY(data, in, length);
13856             XMEMSET(data + length, 0, dataSz - length); /* padding */
13857         }
13858 
13859         tmp = (unsigned char*)XMALLOC(dataSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13860         if (tmp == NULL) {
13861             WOLFSSL_MSG("Issue creating temporary buffer");
13862             if (dynamicFlag == 1) {
13863                 XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13864             }
13865             return 0;
13866         }
13867 
13868         wolfSSL_DES_cbc_encrypt(data, tmp, dataSz, sc,
13869                 (WOLFSSL_DES_cblock*)iv, 1);
13870         XMEMCPY((unsigned char*)out, tmp + (dataSz - DES_BLOCK_SIZE),
13871                 DES_BLOCK_SIZE);
13872 
13873         ret = (((*((unsigned char*)out + 4) & 0xFF) << 24)|
13874                ((*((unsigned char*)out + 5) & 0xFF) << 16)|
13875                ((*((unsigned char*)out + 6) & 0xFF) << 8) |
13876                (*((unsigned char*)out + 7) & 0xFF));
13877 
13878         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13879         if (dynamicFlag == 1) {
13880             XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13881         }
13882 
13883         return ret;
13884     }
13885 
13886 
13887     void wolfSSL_DES_cbc_encrypt(const unsigned char* input,
13888                                  unsigned char* output, long length,
13889                                  WOLFSSL_DES_key_schedule* schedule,
13890                                  WOLFSSL_DES_cblock* ivec, int enc)
13891     {
13892         Des myDes;
13893         byte lastblock[DES_BLOCK_SIZE];
13894         int  lb_sz;
13895         long  blk;
13896 
13897         WOLFSSL_ENTER("DES_cbc_encrypt");
13898 
13899         /* OpenSSL compat, no ret */
13900         wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
13901         lb_sz = length%DES_BLOCK_SIZE;
13902         blk   = length/DES_BLOCK_SIZE;
13903 
13904         if (enc){
13905             wc_Des_CbcEncrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE);
13906             if(lb_sz){
13907                 XMEMSET(lastblock, 0, DES_BLOCK_SIZE);
13908                 XMEMCPY(lastblock, input+length-lb_sz, lb_sz);
13909                 wc_Des_CbcEncrypt(&myDes, output+blk*DES_BLOCK_SIZE,
13910                     lastblock, (word32)DES_BLOCK_SIZE);
13911             }
13912         }
13913         else {
13914             wc_Des_CbcDecrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE);
13915             if(lb_sz){
13916                 wc_Des_CbcDecrypt(&myDes, lastblock, input+length-lb_sz, (word32)DES_BLOCK_SIZE);
13917                 XMEMCPY(output+length-lb_sz, lastblock, lb_sz);
13918             }
13919         }
13920     }
13921 
13922 
13923     /* WOLFSSL_DES_key_schedule is a unsigned char array of size 8 */
13924     void wolfSSL_DES_ede3_cbc_encrypt(const unsigned char* input,
13925                                       unsigned char* output, long sz,
13926                                       WOLFSSL_DES_key_schedule* ks1,
13927                                       WOLFSSL_DES_key_schedule* ks2,
13928                                       WOLFSSL_DES_key_schedule* ks3,
13929                                       WOLFSSL_DES_cblock* ivec, int enc)
13930     {
13931         Des3 des;
13932         byte key[24];/* EDE uses 24 size key */
13933         byte lastblock[DES_BLOCK_SIZE];
13934         int  lb_sz;
13935         long  blk;
13936 
13937         WOLFSSL_ENTER("wolfSSL_DES_ede3_cbc_encrypt");
13938 
13939         XMEMSET(key, 0, sizeof(key));
13940         XMEMCPY(key, *ks1, DES_BLOCK_SIZE);
13941         XMEMCPY(&key[DES_BLOCK_SIZE], *ks2, DES_BLOCK_SIZE);
13942         XMEMCPY(&key[DES_BLOCK_SIZE * 2], *ks3, DES_BLOCK_SIZE);
13943         lb_sz = sz%DES_BLOCK_SIZE;
13944         blk   = sz/DES_BLOCK_SIZE;
13945         if (enc) {
13946             wc_Des3_SetKey(&des, key, (const byte*)ivec, DES_ENCRYPTION);
13947             wc_Des3_CbcEncrypt(&des, output, input, (word32)blk*DES_BLOCK_SIZE);
13948             if(lb_sz){
13949                 XMEMSET(lastblock, 0, DES_BLOCK_SIZE);
13950                 XMEMCPY(lastblock, input+sz-lb_sz, lb_sz);
13951                 wc_Des3_CbcEncrypt(&des, output+blk*DES_BLOCK_SIZE,
13952                     lastblock, (word32)DES_BLOCK_SIZE);
13953             }
13954         }
13955         else {
13956             wc_Des3_SetKey(&des, key, (const byte*)ivec, DES_DECRYPTION);
13957             wc_Des3_CbcDecrypt(&des, output, input, (word32)blk*DES_BLOCK_SIZE);
13958             if(lb_sz){
13959                 wc_Des3_CbcDecrypt(&des, lastblock, input+sz-lb_sz, (word32)DES_BLOCK_SIZE);
13960                 XMEMCPY(output+sz-lb_sz, lastblock, lb_sz);
13961             }
13962         }
13963     }
13964 
13965 
13966     /* correctly sets ivec for next call */
13967     void wolfSSL_DES_ncbc_encrypt(const unsigned char* input,
13968                      unsigned char* output, long length,
13969                      WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec,
13970                      int enc)
13971     {
13972         Des myDes;
13973         byte lastblock[DES_BLOCK_SIZE];
13974         int  lb_sz;
13975         long  blk;
13976 
13977         WOLFSSL_ENTER("DES_ncbc_encrypt");
13978 
13979         /* OpenSSL compat, no ret */
13980         wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
13981         lb_sz = length%DES_BLOCK_SIZE;
13982         blk   = length/DES_BLOCK_SIZE;
13983         if (enc){
13984             wc_Des_CbcEncrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE);
13985             if(lb_sz){
13986                 XMEMSET(lastblock, 0, DES_BLOCK_SIZE);
13987                 XMEMCPY(lastblock, input+length-lb_sz, lb_sz);
13988                 wc_Des_CbcEncrypt(&myDes, output+blk*DES_BLOCK_SIZE,
13989                     lastblock, (word32)DES_BLOCK_SIZE);
13990             }
13991         } else {
13992             wc_Des_CbcDecrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE);
13993             if(lb_sz){
13994                 wc_Des_CbcDecrypt(&myDes, lastblock, input+length-lb_sz, (word32)DES_BLOCK_SIZE);
13995                 XMEMCPY(output+length-lb_sz, lastblock, lb_sz);
13996             }
13997         }
13998 
13999         XMEMCPY(ivec, output + length - sizeof(DES_cblock), sizeof(DES_cblock));
14000     }
14001 
14002 #endif /* NO_DES3 */
14003 
14004 
14005     void wolfSSL_ERR_free_strings(void)
14006     {
14007         /* handled internally */
14008     }
14009 
14010 
14011     void wolfSSL_EVP_cleanup(void)
14012     {
14013         /* nothing to do here */
14014     }
14015 
14016 
14017     void wolfSSL_cleanup_all_ex_data(void)
14018     {
14019         /* nothing to do here */
14020     }
14021 
14022     int wolfSSL_clear(WOLFSSL* ssl)
14023     {
14024         if (ssl == NULL) {
14025             return WOLFSSL_FAILURE;
14026         }
14027 
14028         ssl->options.isClosed = 0;
14029         ssl->options.connReset = 0;
14030         ssl->options.sentNotify = 0;
14031 
14032         ssl->options.serverState = NULL_STATE;
14033         ssl->options.clientState = NULL_STATE;
14034         ssl->options.connectState = CONNECT_BEGIN;
14035         ssl->options.acceptState  = ACCEPT_BEGIN;
14036         ssl->options.handShakeState  = NULL_STATE;
14037         ssl->options.handShakeDone = 0;
14038         /* ssl->options.processReply = doProcessInit; */
14039 
14040         ssl->keys.encryptionOn = 0;
14041         XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
14042 
14043         if (ssl->hsHashes != NULL) {
14044 #ifndef NO_OLD_TLS
14045 #ifndef NO_MD5
14046             wc_InitMd5(&ssl->hsHashes->hashMd5);
14047 #endif
14048 #ifndef NO_SHA
14049             if (wc_InitSha(&ssl->hsHashes->hashSha) != 0)
14050                 return WOLFSSL_FAILURE;
14051 #endif
14052 #endif
14053 #ifndef NO_SHA256
14054             if (wc_InitSha256(&ssl->hsHashes->hashSha256) != 0)
14055                 return WOLFSSL_FAILURE;
14056 #endif
14057 #ifdef WOLFSSL_SHA384
14058             if (wc_InitSha384(&ssl->hsHashes->hashSha384) != 0)
14059                 return WOLFSSL_FAILURE;
14060 #endif
14061 #ifdef WOLFSSL_SHA512
14062             if (wc_InitSha512(&ssl->hsHashes->hashSha512) != 0)
14063                 return WOLFSSL_FAILURE;
14064 #endif
14065         }
14066 #ifdef SESSION_CERTS
14067         ssl->session.chain.count = 0;
14068 #endif
14069 #ifdef KEEP_PEER_CERT
14070         FreeX509(&ssl->peerCert);
14071         InitX509(&ssl->peerCert, 0, ssl->heap);
14072 #endif
14073 
14074         return WOLFSSL_SUCCESS;
14075     }
14076 
14077     long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t)
14078     {
14079         word32 tmptime;
14080         if (!ses || t < 0)
14081             return BAD_FUNC_ARG;
14082 
14083         tmptime = t & 0xFFFFFFFF;
14084 
14085         ses->timeout = tmptime;
14086 
14087         return WOLFSSL_SUCCESS;
14088     }
14089 
14090 
14091     long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode)
14092     {
14093         /* WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
14094 
14095         WOLFSSL_ENTER("SSL_CTX_set_mode");
14096         if (mode == SSL_MODE_ENABLE_PARTIAL_WRITE)
14097             ctx->partialWrite = 1;
14098 
14099         return mode;
14100     }
14101 
14102     #ifndef NO_WOLFSSL_STUB
14103     long wolfSSL_SSL_get_mode(WOLFSSL* ssl)
14104     {
14105         /* TODO: */
14106         (void)ssl;
14107         WOLFSSL_STUB("SSL_get_mode");
14108         return 0;
14109     }
14110     #endif
14111 
14112     #ifndef NO_WOLFSSL_STUB
14113     long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx)
14114     {
14115         /* TODO: */
14116         (void)ctx;
14117         WOLFSSL_STUB("SSL_CTX_get_mode");
14118         return 0;
14119     }
14120     #endif
14121 
14122     #ifndef NO_WOLFSSL_STUB
14123     void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m)
14124     {
14125         /* TODO: maybe? */
14126         (void)ctx;
14127         (void)m;
14128         WOLFSSL_STUB("SSL_CTX_set_default_read_ahead");
14129     }
14130     #endif
14131 
14132 
14133     /* Storing app session context id, this value is inherited by WOLFSSL
14134      * objects created from WOLFSSL_CTX. Any session that is imported with a
14135      * different session context id will be rejected.
14136      *
14137      * ctx         structure to set context in
14138      * sid_ctx     value of context to set
14139      * sid_ctx_len length of sid_ctx buffer
14140      *
14141      * Returns SSL_SUCCESS in success case and SSL_FAILURE when failing
14142      */
14143     int wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX* ctx,
14144                                            const unsigned char* sid_ctx,
14145                                            unsigned int sid_ctx_len)
14146     {
14147         WOLFSSL_ENTER("SSL_CTX_set_session_id_context");
14148 
14149         /* No application specific context needed for wolfSSL */
14150         if (sid_ctx_len > ID_LEN || ctx == NULL || sid_ctx == NULL) {
14151             return SSL_FAILURE;
14152         }
14153         XMEMCPY(ctx->sessionCtx, sid_ctx, sid_ctx_len);
14154         ctx->sessionCtxSz = (byte)sid_ctx_len;
14155 
14156         return SSL_SUCCESS;
14157     }
14158 
14159 
14160 
14161     /* Storing app session context id. Any session that is imported with a
14162      * different session context id will be rejected.
14163      *
14164      * ssl  structure to set context in
14165      * id   value of context to set
14166      * len  length of sid_ctx buffer
14167      *
14168      * Returns SSL_SUCCESS in success case and SSL_FAILURE when failing
14169      */
14170     int wolfSSL_set_session_id_context(WOLFSSL* ssl, const unsigned char* id,
14171                                    unsigned int len)
14172     {
14173         WOLFSSL_STUB("wolfSSL_set_session_id_context");
14174 
14175         if (len > ID_LEN || ssl == NULL || id == NULL) {
14176             return SSL_FAILURE;
14177         }
14178         XMEMCPY(ssl->sessionCtx, id, len);
14179         ssl->sessionCtxSz = (byte)len;
14180 
14181         return SSL_SUCCESS;
14182     }
14183 
14184 
14185     long wolfSSL_CTX_sess_get_cache_size(WOLFSSL_CTX* ctx)
14186     {
14187         (void)ctx;
14188         #ifndef NO_SESSION_CACHE
14189             return SESSIONS_PER_ROW * SESSION_ROWS;
14190         #else
14191             return 0;
14192         #endif
14193     }
14194 
14195 
14196     /* returns the unsigned error value and increments the pointer into the
14197      * error queue.
14198      *
14199      * file  pointer to file name
14200      * line  gets set to line number of error when not NULL
14201      */
14202     unsigned long wolfSSL_ERR_get_error_line(const char** file, int* line)
14203     {
14204     #ifdef DEBUG_WOLFSSL
14205         int ret = wc_PullErrorNode(file, NULL, line);
14206         if (ret < 0) {
14207             if (ret == BAD_STATE_E) return 0; /* no errors in queue */
14208             WOLFSSL_MSG("Issue getting error node");
14209             WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line", ret);
14210             ret = 0 - ret; /* return absolute value of error */
14211 
14212             /* panic and try to clear out nodes */
14213             wc_ClearErrorNodes();
14214         }
14215         return (unsigned long)ret;
14216     #else
14217         (void)file;
14218         (void)line;
14219 
14220         return 0;
14221     #endif
14222     }
14223 
14224 
14225 #ifdef DEBUG_WOLFSSL
14226     static const char WOLFSSL_SYS_ACCEPT_T[]  = "accept";
14227     static const char WOLFSSL_SYS_BIND_T[]    = "bind";
14228     static const char WOLFSSL_SYS_CONNECT_T[] = "connect";
14229     static const char WOLFSSL_SYS_FOPEN_T[]   = "fopen";
14230     static const char WOLFSSL_SYS_FREAD_T[]   = "fread";
14231     static const char WOLFSSL_SYS_GETADDRINFO_T[] = "getaddrinfo";
14232     static const char WOLFSSL_SYS_GETSOCKOPT_T[]  = "getsockopt";
14233     static const char WOLFSSL_SYS_GETSOCKNAME_T[] = "getsockname";
14234     static const char WOLFSSL_SYS_GETHOSTBYNAME_T[] = "gethostbyname";
14235     static const char WOLFSSL_SYS_GETNAMEINFO_T[]   = "getnameinfo";
14236     static const char WOLFSSL_SYS_GETSERVBYNAME_T[] = "getservbyname";
14237     static const char WOLFSSL_SYS_IOCTLSOCKET_T[]   = "ioctlsocket";
14238     static const char WOLFSSL_SYS_LISTEN_T[]        = "listen";
14239     static const char WOLFSSL_SYS_OPENDIR_T[]       = "opendir";
14240     static const char WOLFSSL_SYS_SETSOCKOPT_T[]    = "setsockopt";
14241     static const char WOLFSSL_SYS_SOCKET_T[]        = "socket";
14242 
14243     /* switch with int mapped to function name for compatibility */
14244     static const char* wolfSSL_ERR_sys_func(int fun)
14245     {
14246         switch (fun) {
14247             case WOLFSSL_SYS_ACCEPT:      return WOLFSSL_SYS_ACCEPT_T;
14248             case WOLFSSL_SYS_BIND:        return WOLFSSL_SYS_BIND_T;
14249             case WOLFSSL_SYS_CONNECT:     return WOLFSSL_SYS_CONNECT_T;
14250             case WOLFSSL_SYS_FOPEN:       return WOLFSSL_SYS_FOPEN_T;
14251             case WOLFSSL_SYS_FREAD:       return WOLFSSL_SYS_FREAD_T;
14252             case WOLFSSL_SYS_GETADDRINFO: return WOLFSSL_SYS_GETADDRINFO_T;
14253             case WOLFSSL_SYS_GETSOCKOPT:  return WOLFSSL_SYS_GETSOCKOPT_T;
14254             case WOLFSSL_SYS_GETSOCKNAME: return WOLFSSL_SYS_GETSOCKNAME_T;
14255             case WOLFSSL_SYS_GETHOSTBYNAME: return WOLFSSL_SYS_GETHOSTBYNAME_T;
14256             case WOLFSSL_SYS_GETNAMEINFO: return WOLFSSL_SYS_GETNAMEINFO_T;
14257             case WOLFSSL_SYS_GETSERVBYNAME: return WOLFSSL_SYS_GETSERVBYNAME_T;
14258             case WOLFSSL_SYS_IOCTLSOCKET: return WOLFSSL_SYS_IOCTLSOCKET_T;
14259             case WOLFSSL_SYS_LISTEN:      return WOLFSSL_SYS_LISTEN_T;
14260             case WOLFSSL_SYS_OPENDIR:     return WOLFSSL_SYS_OPENDIR_T;
14261             case WOLFSSL_SYS_SETSOCKOPT:  return WOLFSSL_SYS_SETSOCKOPT_T;
14262             case WOLFSSL_SYS_SOCKET:      return WOLFSSL_SYS_SOCKET_T;
14263             default:
14264                 return "NULL";
14265         }
14266     }
14267 #endif /* DEBUG_WOLFSSL */
14268 
14269 
14270     /* @TODO when having an error queue this needs to push to the queue */
14271     void wolfSSL_ERR_put_error(int lib, int fun, int err, const char* file,
14272             int line)
14273     {
14274         WOLFSSL_ENTER("wolfSSL_ERR_put_error");
14275 
14276         #ifndef DEBUG_WOLFSSL
14277         (void)fun;
14278         (void)err;
14279         (void)file;
14280         (void)line;
14281         WOLFSSL_MSG("Not compiled in debug mode");
14282         #else
14283         WOLFSSL_ERROR_LINE(err, wolfSSL_ERR_sys_func(fun), (unsigned int)line,
14284             file, NULL);
14285         #endif
14286         (void)lib;
14287     }
14288 
14289 
14290     /* Similar to wolfSSL_ERR_get_error_line but takes in a flags argument for
14291      * more flexability.
14292      *
14293      * file  output pointer to file where error happened
14294      * line  output to line number of error
14295      * data  output data. Is a string if ERR_TXT_STRING flag is used
14296      * flags bit flag to adjust data output
14297      *
14298      * Returns the error value or 0 if no errors are in the queue
14299      */
14300     unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line,
14301                                                   const char** data, int *flags)
14302     {
14303         int ret;
14304 
14305         WOLFSSL_STUB("wolfSSL_ERR_get_error_line_data");
14306 
14307         if (flags != NULL) {
14308             if ((*flags & ERR_TXT_STRING) == ERR_TXT_STRING) {
14309                 ret = wc_PullErrorNode(file, data, line);
14310                 if (ret < 0) {
14311                     if (ret == BAD_STATE_E) return 0; /* no errors in queue */
14312                     WOLFSSL_MSG("Error with pulling error node!");
14313                     WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line_data", ret);
14314                     ret = 0 - ret; /* return absolute value of error */
14315 
14316                     /* panic and try to clear out nodes */
14317                     wc_ClearErrorNodes();
14318                 }
14319 
14320                 return (unsigned long)ret;
14321             }
14322         }
14323 
14324         ret = wc_PullErrorNode(file, NULL, line);
14325         if (ret < 0) {
14326             if (ret == BAD_STATE_E) return 0; /* no errors in queue */
14327             WOLFSSL_MSG("Error with pulling error node!");
14328             WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line_data", ret);
14329             ret = 0 - ret; /* return absolute value of error */
14330 
14331             /* panic and try to clear out nodes */
14332             wc_ClearErrorNodes();
14333         }
14334 
14335         return (unsigned long)ret;
14336     }
14337 
14338 #endif /* OPENSSL_EXTRA */
14339 
14340 
14341 #ifdef KEEP_PEER_CERT
14342     #ifdef SESSION_CERTS
14343     /* Decode the X509 DER encoded certificate into a WOLFSSL_X509 object.
14344      *
14345      * x509  WOLFSSL_X509 object to decode into.
14346      * in    X509 DER data.
14347      * len   Length of the X509 DER data.
14348      * returns the new certificate on success, otherwise NULL.
14349      */
14350     static int DecodeToX509(WOLFSSL_X509* x509, const byte* in, int len)
14351     {
14352         int          ret;
14353     #ifdef WOLFSSL_SMALL_STACK
14354         DecodedCert* cert = NULL;
14355     #else
14356         DecodedCert  cert[1];
14357     #endif
14358 
14359     #ifdef WOLFSSL_SMALL_STACK
14360         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
14361                                      DYNAMIC_TYPE_DCERT);
14362         if (cert == NULL)
14363             return MEMORY_E;
14364     #endif
14365 
14366         /* Create a DecodedCert object and copy fields into WOLFSSL_X509 object.
14367          */
14368         InitDecodedCert(cert, (byte*)in, len, NULL);
14369         if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) == 0) {
14370             InitX509(x509, 0, NULL);
14371             ret = CopyDecodedToX509(x509, cert);
14372             FreeDecodedCert(cert);
14373         }
14374     #ifdef WOLFSSL_SMALL_STACK
14375         XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
14376     #endif
14377 
14378         return ret;
14379     }
14380     #endif /* SESSION_CERTS */
14381 
14382 
14383     WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl)
14384     {
14385         WOLFSSL_ENTER("SSL_get_peer_certificate");
14386         if (ssl->peerCert.issuer.sz)
14387             return &ssl->peerCert;
14388 #ifdef SESSION_CERTS
14389         else if (ssl->session.chain.count > 0) {
14390             if (DecodeToX509(&ssl->peerCert, ssl->session.chain.certs[0].buffer,
14391                     ssl->session.chain.certs[0].length) == 0) {
14392                 return &ssl->peerCert;
14393             }
14394         }
14395 #endif
14396         return 0;
14397     }
14398 
14399 #endif /* KEEP_PEER_CERT */
14400 
14401 
14402 #ifndef NO_CERTS
14403 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
14404     defined(OPENSSL_EXTRA)  || defined(OPENSSL_EXTRA_X509_SMALL)
14405 
14406 /* user externally called free X509, if dynamic go ahead with free, otherwise
14407  * don't */
14408 static void ExternalFreeX509(WOLFSSL_X509* x509)
14409 {
14410     WOLFSSL_ENTER("ExternalFreeX509");
14411     if (x509) {
14412         if (x509->dynamicMemory) {
14413             FreeX509(x509);
14414             XFREE(x509, x509->heap, DYNAMIC_TYPE_X509);
14415         } else {
14416             WOLFSSL_MSG("free called on non dynamic object, not freeing");
14417         }
14418     }
14419 }
14420 
14421 /* Frees an external WOLFSSL_X509 structure */
14422 void wolfSSL_X509_free(WOLFSSL_X509* x509)
14423 {
14424     WOLFSSL_ENTER("wolfSSL_FreeX509");
14425     ExternalFreeX509(x509);
14426 }
14427 
14428 
14429 /* copy name into in buffer, at most sz bytes, if buffer is null will
14430    malloc buffer, call responsible for freeing                     */
14431 char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
14432 {
14433     int copySz;
14434 
14435     if (name == NULL) {
14436         WOLFSSL_MSG("WOLFSSL_X509_NAME pointer was NULL");
14437         return NULL;
14438     }
14439 
14440     copySz = min(sz, name->sz);
14441 
14442     WOLFSSL_ENTER("wolfSSL_X509_NAME_oneline");
14443     if (!name->sz) return in;
14444 
14445     if (!in) {
14446     #ifdef WOLFSSL_STATIC_MEMORY
14447         WOLFSSL_MSG("Using static memory -- please pass in a buffer");
14448         return NULL;
14449     #else
14450         in = (char*)XMALLOC(name->sz, NULL, DYNAMIC_TYPE_OPENSSL);
14451         if (!in ) return in;
14452         copySz = name->sz;
14453     #endif
14454     }
14455 
14456     if (copySz <= 0)
14457         return in;
14458 
14459     XMEMCPY(in, name->name, copySz - 1);
14460     in[copySz - 1] = 0;
14461 
14462     return in;
14463 }
14464 
14465 
14466 /* Wraps wolfSSL_X509_d2i
14467  *
14468  * returns a WOLFSSL_X509 structure pointer on success and NULL on fail
14469  */
14470 WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, const unsigned char** in,
14471         int len)
14472 {
14473     return wolfSSL_X509_d2i(x509, *in, len);
14474 }
14475 
14476 
14477 WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
14478 {
14479     WOLFSSL_X509 *newX509 = NULL;
14480 
14481     WOLFSSL_ENTER("wolfSSL_X509_d2i");
14482 
14483     if (in != NULL && len != 0) {
14484     #ifdef WOLFSSL_SMALL_STACK
14485         DecodedCert* cert = NULL;
14486     #else
14487         DecodedCert  cert[1];
14488     #endif
14489 
14490     #ifdef WOLFSSL_SMALL_STACK
14491         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
14492                                      DYNAMIC_TYPE_DCERT);
14493         if (cert == NULL)
14494             return NULL;
14495     #endif
14496 
14497         InitDecodedCert(cert, (byte*)in, len, NULL);
14498         if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
14499             newX509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
14500                                              DYNAMIC_TYPE_X509);
14501             if (newX509 != NULL) {
14502                 InitX509(newX509, 1, NULL);
14503                 if (CopyDecodedToX509(newX509, cert) != 0) {
14504                     XFREE(newX509, NULL, DYNAMIC_TYPE_X509);
14505                     newX509 = NULL;
14506                 }
14507             }
14508         }
14509         FreeDecodedCert(cert);
14510     #ifdef WOLFSSL_SMALL_STACK
14511         XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
14512     #endif
14513     }
14514 
14515     if (x509 != NULL)
14516         *x509 = newX509;
14517 
14518     return newX509;
14519 }
14520 #endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSL_EXTRA ||
14521           OPENSSL_EXTRA_X509_SMALL */
14522 
14523 #if defined(OPENSSL_ALL) || defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
14524     /* return the next, if any, altname from the peer cert */
14525     char* wolfSSL_X509_get_next_altname(WOLFSSL_X509* cert)
14526     {
14527         char* ret = NULL;
14528         WOLFSSL_ENTER("wolfSSL_X509_get_next_altname");
14529 
14530         /* don't have any to work with */
14531         if (cert == NULL || cert->altNames == NULL)
14532             return NULL;
14533 
14534         /* already went through them */
14535         if (cert->altNamesNext == NULL)
14536             return NULL;
14537 
14538         ret = cert->altNamesNext->name;
14539         cert->altNamesNext = cert->altNamesNext->next;
14540 
14541         return ret;
14542     }
14543 
14544 
14545     int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509)
14546     {
14547         int isCA = 0;
14548 
14549         WOLFSSL_ENTER("wolfSSL_X509_get_isCA");
14550 
14551         if (x509 != NULL)
14552             isCA = x509->isCa;
14553 
14554         WOLFSSL_LEAVE("wolfSSL_X509_get_isCA", isCA);
14555 
14556         return isCA;
14557     }
14558 
14559     int wolfSSL_X509_get_signature(WOLFSSL_X509* x509,
14560                                                  unsigned char* buf, int* bufSz)
14561     {
14562         WOLFSSL_ENTER("wolfSSL_X509_get_signature");
14563         if (x509 == NULL || bufSz == NULL || *bufSz < (int)x509->sig.length)
14564             return WOLFSSL_FATAL_ERROR;
14565 
14566         if (buf != NULL)
14567             XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
14568         *bufSz = x509->sig.length;
14569 
14570         return WOLFSSL_SUCCESS;
14571     }
14572 
14573 
14574     /* write X509 serial number in unsigned binary to buffer
14575        buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
14576        return WOLFSSL_SUCCESS on success */
14577     int wolfSSL_X509_get_serial_number(WOLFSSL_X509* x509,
14578                                        byte* in, int* inOutSz)
14579     {
14580         WOLFSSL_ENTER("wolfSSL_X509_get_serial_number");
14581         if (x509 == NULL || in == NULL ||
14582                                    inOutSz == NULL || *inOutSz < x509->serialSz)
14583             return BAD_FUNC_ARG;
14584 
14585         XMEMCPY(in, x509->serial, x509->serialSz);
14586         *inOutSz = x509->serialSz;
14587 
14588         return WOLFSSL_SUCCESS;
14589     }
14590 
14591 
14592     const byte* wolfSSL_X509_get_der(WOLFSSL_X509* x509, int* outSz)
14593     {
14594         WOLFSSL_ENTER("wolfSSL_X509_get_der");
14595 
14596         if (x509 == NULL || x509->derCert == NULL || outSz == NULL)
14597             return NULL;
14598 
14599         *outSz = (int)x509->derCert->length;
14600         return x509->derCert->buffer;
14601     }
14602 
14603 
14604     int wolfSSL_X509_version(WOLFSSL_X509* x509)
14605     {
14606         WOLFSSL_ENTER("wolfSSL_X509_version");
14607 
14608         if (x509 == NULL)
14609             return 0;
14610 
14611         return x509->version;
14612     }
14613 
14614 
14615     const byte* wolfSSL_X509_notBefore(WOLFSSL_X509* x509)
14616     {
14617         WOLFSSL_ENTER("wolfSSL_X509_notBefore");
14618 
14619         if (x509 == NULL)
14620             return NULL;
14621 
14622         return x509->notBefore;
14623     }
14624 
14625 
14626     const byte* wolfSSL_X509_notAfter(WOLFSSL_X509* x509)
14627     {
14628         WOLFSSL_ENTER("wolfSSL_X509_notAfter");
14629 
14630         if (x509 == NULL)
14631             return NULL;
14632 
14633         return x509->notAfter;
14634     }
14635 
14636 
14637 #ifdef WOLFSSL_SEP
14638 
14639 /* copy oid into in buffer, at most *inOutSz bytes, if buffer is null will
14640    malloc buffer, call responsible for freeing. Actual size returned in
14641    *inOutSz. Requires inOutSz be non-null */
14642 byte* wolfSSL_X509_get_device_type(WOLFSSL_X509* x509, byte* in, int *inOutSz)
14643 {
14644     int copySz;
14645 
14646     WOLFSSL_ENTER("wolfSSL_X509_get_dev_type");
14647     if (inOutSz == NULL) return NULL;
14648     if (!x509->deviceTypeSz) return in;
14649 
14650     copySz = min(*inOutSz, x509->deviceTypeSz);
14651 
14652     if (!in) {
14653     #ifdef WOLFSSL_STATIC_MEMORY
14654         WOLFSSL_MSG("Using static memory -- please pass in a buffer");
14655         return NULL;
14656     #else
14657         in = (byte*)XMALLOC(x509->deviceTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
14658         if (!in) return in;
14659         copySz = x509->deviceTypeSz;
14660     #endif
14661     }
14662 
14663     XMEMCPY(in, x509->deviceType, copySz);
14664     *inOutSz = copySz;
14665 
14666     return in;
14667 }
14668 
14669 
14670 byte* wolfSSL_X509_get_hw_type(WOLFSSL_X509* x509, byte* in, int* inOutSz)
14671 {
14672     int copySz;
14673 
14674     WOLFSSL_ENTER("wolfSSL_X509_get_hw_type");
14675     if (inOutSz == NULL) return NULL;
14676     if (!x509->hwTypeSz) return in;
14677 
14678     copySz = min(*inOutSz, x509->hwTypeSz);
14679 
14680     if (!in) {
14681     #ifdef WOLFSSL_STATIC_MEMORY
14682         WOLFSSL_MSG("Using static memory -- please pass in a buffer");
14683         return NULL;
14684     #else
14685         in = (byte*)XMALLOC(x509->hwTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
14686         if (!in) return in;
14687         copySz = x509->hwTypeSz;
14688     #endif
14689     }
14690 
14691     XMEMCPY(in, x509->hwType, copySz);
14692     *inOutSz = copySz;
14693 
14694     return in;
14695 }
14696 
14697 
14698 byte* wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509* x509,byte* in,
14699                                         int* inOutSz)
14700 {
14701     int copySz;
14702 
14703     WOLFSSL_ENTER("wolfSSL_X509_get_hw_serial_number");
14704     if (inOutSz == NULL) return NULL;
14705     if (!x509->hwTypeSz) return in;
14706 
14707     copySz = min(*inOutSz, x509->hwSerialNumSz);
14708 
14709     if (!in) {
14710     #ifdef WOLFSSL_STATIC_MEMORY
14711         WOLFSSL_MSG("Using static memory -- please pass in a buffer");
14712         return NULL;
14713     #else
14714         in = (byte*)XMALLOC(x509->hwSerialNumSz, 0, DYNAMIC_TYPE_OPENSSL);
14715         if (!in) return in;
14716         copySz = x509->hwSerialNumSz;
14717     #endif
14718     }
14719 
14720     XMEMCPY(in, x509->hwSerialNum, copySz);
14721     *inOutSz = copySz;
14722 
14723     return in;
14724 }
14725 
14726 #endif /* WOLFSSL_SEP */
14727 
14728 /* require OPENSSL_EXTRA since wolfSSL_X509_free is wrapped by OPENSSL_EXTRA */
14729 #if !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
14730 /* return 1 on success 0 on fail */
14731 int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509* x509)
14732 {
14733     WOLFSSL_STACK* node;
14734 
14735     if (sk == NULL || x509 == NULL) {
14736         return WOLFSSL_FAILURE;
14737     }
14738 
14739     /* no previous values in stack */
14740     if (sk->data.x509 == NULL) {
14741         sk->data.x509 = x509;
14742         sk->num += 1;
14743         return WOLFSSL_SUCCESS;
14744     }
14745 
14746     /* stack already has value(s) create a new node and add more */
14747     node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
14748                                                              DYNAMIC_TYPE_X509);
14749     if (node == NULL) {
14750         WOLFSSL_MSG("Memory error");
14751         return WOLFSSL_FAILURE;
14752     }
14753     XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
14754 
14755     /* push new x509 onto head of stack */
14756     node->data.x509 = sk->data.x509;
14757     node->next      = sk->next;
14758     sk->next        = node;
14759     sk->data.x509   = x509;
14760     sk->num        += 1;
14761 
14762     return WOLFSSL_SUCCESS;
14763 }
14764 
14765 
14766 WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk) {
14767     WOLFSSL_STACK* node;
14768     WOLFSSL_X509*  x509;
14769 
14770     if (sk == NULL) {
14771         return NULL;
14772     }
14773 
14774     node = sk->next;
14775     x509 = sk->data.x509;
14776 
14777     if (node != NULL) { /* update sk and remove node from stack */
14778         sk->data.x509 = node->data.x509;
14779         sk->next = node->next;
14780         XFREE(node, NULL, DYNAMIC_TYPE_X509);
14781     }
14782     else { /* last x509 in stack */
14783         sk->data.x509 = NULL;
14784     }
14785 
14786     if (sk->num > 0) {
14787         sk->num -= 1;
14788     }
14789 
14790     return x509;
14791 }
14792 
14793 
14794 /* Getter function for WOLFSSL_X509_NAME pointer
14795  *
14796  * sk is the stack to retrieve pointer from
14797  * i  is the index value in stack
14798  *
14799  * returns a pointer to a WOLFSSL_X509_NAME structure on success and NULL on
14800  *         fail
14801  */
14802 void* wolfSSL_sk_X509_NAME_value(const STACK_OF(WOLFSSL_X509_NAME)* sk, int i)
14803 {
14804     WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_value");
14805 
14806     for (; sk != NULL && i > 0; i--)
14807         sk = sk->next;
14808 
14809     if (i != 0 || sk == NULL)
14810         return NULL;
14811     return sk->data.name;
14812 }
14813 
14814 
14815 /* Getter function for WOLFSSL_X509 pointer
14816  *
14817  * sk is the stack to retrieve pointer from
14818  * i  is the index value in stack
14819  *
14820  * returns a pointer to a WOLFSSL_X509 structure on success and NULL on
14821  *         fail
14822  */
14823 void* wolfSSL_sk_X509_value(STACK_OF(WOLFSSL_X509)* sk, int i)
14824 {
14825     WOLFSSL_ENTER("wolfSSL_sk_X509_value");
14826 
14827     for (; sk != NULL && i > 0; i--)
14828         sk = sk->next;
14829 
14830     if (i != 0 || sk == NULL)
14831         return NULL;
14832     return sk->data.x509;
14833 }
14834 
14835 
14836 /* Free's all nodes in X509 stack. This is different then wolfSSL_sk_X509_free
14837  * in that it allows for choosing the function to use when freeing an X509s.
14838  *
14839  * sk  stack to free nodes in
14840  * f   X509 free function
14841  */
14842 void wolfSSL_sk_X509_pop_free(STACK_OF(WOLFSSL_X509)* sk, void f (WOLFSSL_X509*)){
14843     WOLFSSL_STACK* node;
14844 
14845     WOLFSSL_ENTER("wolfSSL_sk_X509_pop_free");
14846 
14847     if (sk == NULL) {
14848         return;
14849     }
14850 
14851     /* parse through stack freeing each node */
14852     node = sk->next;
14853     while (sk->num > 1) {
14854         WOLFSSL_STACK* tmp = node;
14855         node = node->next;
14856 
14857         f(tmp->data.x509);
14858         XFREE(tmp, NULL, DYNAMIC_TYPE_X509);
14859         sk->num -= 1;
14860     }
14861 
14862     /* free head of stack */
14863     if (sk->num == 1) {
14864         f(sk->data.x509);
14865     }
14866     XFREE(sk, NULL, DYNAMIC_TYPE_X509);
14867 }
14868 
14869 
14870 /* free structure for x509 stack */
14871 void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk) {
14872     WOLFSSL_STACK* node;
14873 
14874     if (sk == NULL) {
14875         return;
14876     }
14877 
14878     /* parse through stack freeing each node */
14879     node = sk->next;
14880     while (sk->num > 1) {
14881         WOLFSSL_STACK* tmp = node;
14882         node = node->next;
14883 
14884         wolfSSL_X509_free(tmp->data.x509);
14885         XFREE(tmp, NULL, DYNAMIC_TYPE_X509);
14886         sk->num -= 1;
14887     }
14888 
14889     /* free head of stack */
14890     if (sk->num == 1) {
14891     wolfSSL_X509_free(sk->data.x509);
14892     }
14893     XFREE(sk, NULL, DYNAMIC_TYPE_X509);
14894 }
14895 
14896 #endif /* NO_CERTS && OPENSSL_EXTRA */
14897 
14898 #ifdef OPENSSL_EXTRA
14899 
14900 /* Returns the general name at index i from the stack
14901  *
14902  * sk stack to get general name from
14903  * i  index to get
14904  *
14905  * return a pointer to the internal node of the stack
14906  */
14907 WOLFSSL_ASN1_OBJECT* wolfSSL_sk_GENERAL_NAME_value(WOLFSSL_STACK* sk, int i)
14908 {
14909     WOLFSSL_STACK* cur;
14910     int j;
14911 
14912     WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_value");
14913 
14914     if (i < 0 || sk == NULL) {
14915         return NULL;
14916     }
14917 
14918     cur = sk;
14919     for (j = 0; j < i && cur != NULL; j++) {
14920         cur = cur->next;
14921     }
14922 
14923     if (cur == NULL) {
14924         return NULL;
14925     }
14926 
14927     return cur->data.obj;
14928 }
14929 
14930 
14931 /* Gets the number of nodes in the stack
14932  *
14933  * sk  stack to get the number of nodes from
14934  *
14935  * returns the number of nodes, -1 if no nodes
14936  */
14937 int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk)
14938 {
14939     WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_num");
14940 
14941     if (sk == NULL) {
14942         return -1;
14943     }
14944 
14945     return (int)sk->num;
14946 }
14947 
14948 /* Frees all nodes in a GENERAL NAME stack
14949  *
14950  * sk stack of nodes to free
14951  * f  free function to use, not called with wolfSSL
14952  */
14953 void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk,
14954         void f (WOLFSSL_ASN1_OBJECT*))
14955 {
14956     WOLFSSL_STACK* node;
14957 
14958     WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_pop_free");
14959 
14960     (void)f;
14961     if (sk == NULL) {
14962         return;
14963     }
14964 
14965     /* parse through stack freeing each node */
14966     node = sk->next;
14967     while (sk->num > 1) {
14968         WOLFSSL_STACK* tmp = node;
14969         node = node->next;
14970 
14971         wolfSSL_ASN1_OBJECT_free(tmp->data.obj);
14972         XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1);
14973         sk->num -= 1;
14974     }
14975 
14976     /* free head of stack */
14977     if (sk->num == 1) {
14978         wolfSSL_ASN1_OBJECT_free(sk->data.obj);
14979     }
14980     XFREE(sk, NULL, DYNAMIC_TYPE_ASN1);
14981 
14982 
14983 }
14984 #endif /* OPENSSL_EXTRA */
14985 
14986 #ifndef NO_FILESYSTEM
14987 
14988 #ifndef NO_STDIO_FILESYSTEM
14989 
14990 WOLFSSL_X509* wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file)
14991 {
14992     WOLFSSL_X509* newX509 = NULL;
14993 
14994     WOLFSSL_ENTER("wolfSSL_X509_d2i_fp");
14995 
14996     if (file != XBADFILE) {
14997         byte* fileBuffer = NULL;
14998         long sz = 0;
14999 
15000         XFSEEK(file, 0, XSEEK_END);
15001         sz = XFTELL(file);
15002         XREWIND(file);
15003 
15004         if (sz < 0) {
15005             WOLFSSL_MSG("Bad tell on FILE");
15006             return NULL;
15007         }
15008 
15009         fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
15010         if (fileBuffer != NULL) {
15011             int ret = (int)XFREAD(fileBuffer, 1, sz, file);
15012             if (ret == sz) {
15013                 newX509 = wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
15014             }
15015             XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
15016         }
15017     }
15018 
15019     if (x509 != NULL)
15020         *x509 = newX509;
15021 
15022     return newX509;
15023 }
15024 
15025 #endif /* NO_STDIO_FILESYSTEM */
15026 
15027 WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format)
15028 {
15029 #ifdef WOLFSSL_SMALL_STACK
15030     byte  staticBuffer[1]; /* force heap usage */
15031 #else
15032     byte  staticBuffer[FILE_BUFFER_SIZE];
15033 #endif
15034     byte* fileBuffer = staticBuffer;
15035     int   dynamic = 0;
15036     int   ret;
15037     long  sz = 0;
15038     XFILE file;
15039 
15040     WOLFSSL_X509* x509 = NULL;
15041 
15042     /* Check the inputs */
15043     if ((fname == NULL) ||
15044         (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM))
15045         return NULL;
15046 
15047     file = XFOPEN(fname, "rb");
15048     if (file == XBADFILE)
15049         return NULL;
15050 
15051     XFSEEK(file, 0, XSEEK_END);
15052     sz = XFTELL(file);
15053     XREWIND(file);
15054 
15055     if (sz > (long)sizeof(staticBuffer)) {
15056         fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
15057         if (fileBuffer == NULL) {
15058             XFCLOSE(file);
15059             return NULL;
15060         }
15061         dynamic = 1;
15062     }
15063     else if (sz < 0) {
15064         XFCLOSE(file);
15065         return NULL;
15066     }
15067 
15068     ret = (int)XFREAD(fileBuffer, 1, sz, file);
15069     if (ret != sz) {
15070         XFCLOSE(file);
15071         if (dynamic)
15072             XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
15073         return NULL;
15074     }
15075 
15076     XFCLOSE(file);
15077 
15078     x509 = wolfSSL_X509_load_certificate_buffer(fileBuffer, (int)sz, format);
15079 
15080     if (dynamic)
15081         XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
15082 
15083     return x509;
15084 }
15085 
15086 #endif /* NO_FILESYSTEM */
15087 
15088 
15089 WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer(
15090     const unsigned char* buf, int sz, int format)
15091 {
15092     int ret;
15093     WOLFSSL_X509* x509 = NULL;
15094     DerBuffer* der = NULL;
15095 
15096     WOLFSSL_ENTER("wolfSSL_X509_load_certificate_ex");
15097 
15098     if (format == WOLFSSL_FILETYPE_PEM) {
15099     #ifdef WOLFSSL_PEM_TO_DER
15100         if (PemToDer(buf, sz, CERT_TYPE, &der, NULL, NULL, NULL) != 0) {
15101             FreeDer(&der);
15102         }
15103     #else
15104         ret = NOT_COMPILED_IN;
15105     #endif
15106     }
15107     else {
15108         ret = AllocDer(&der, (word32)sz, CERT_TYPE, NULL);
15109         if (ret == 0) {
15110             XMEMCPY(der->buffer, buf, sz);
15111         }
15112     }
15113 
15114     /* At this point we want `der` to have the certificate in DER format */
15115     /* ready to be decoded. */
15116     if (der != NULL && der->buffer != NULL) {
15117     #ifdef WOLFSSL_SMALL_STACK
15118         DecodedCert* cert = NULL;
15119     #else
15120         DecodedCert  cert[1];
15121     #endif
15122 
15123     #ifdef WOLFSSL_SMALL_STACK
15124         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
15125                                      DYNAMIC_TYPE_DCERT);
15126         if (cert != NULL)
15127     #endif
15128         {
15129             InitDecodedCert(cert, der->buffer, der->length, NULL);
15130             if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
15131                 x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
15132                                                              DYNAMIC_TYPE_X509);
15133                 if (x509 != NULL) {
15134                     InitX509(x509, 1, NULL);
15135                     if (CopyDecodedToX509(x509, cert) != 0) {
15136                         XFREE(x509, NULL, DYNAMIC_TYPE_X509);
15137                         x509 = NULL;
15138                     }
15139                 }
15140             }
15141 
15142             FreeDecodedCert(cert);
15143         #ifdef WOLFSSL_SMALL_STACK
15144             XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
15145         #endif
15146         }
15147 
15148         FreeDer(&der);
15149     }
15150 
15151     return x509;
15152 }
15153 
15154 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
15155 
15156 /* OPENSSL_EXTRA is needed for wolfSSL_X509_d21 function
15157    KEEP_OUR_CERT is to insure ability for returning ssl certificate */
15158 #if defined(OPENSSL_EXTRA) && defined(KEEP_OUR_CERT)
15159 WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl)
15160 {
15161     if (ssl == NULL) {
15162         return NULL;
15163     }
15164 
15165     if (ssl->buffers.weOwnCert) {
15166         if (ssl->ourCert == NULL) {
15167             if (ssl->buffers.certificate == NULL) {
15168                 WOLFSSL_MSG("Certificate buffer not set!");
15169                 return NULL;
15170             }
15171             ssl->ourCert = wolfSSL_X509_d2i(NULL,
15172                                               ssl->buffers.certificate->buffer,
15173                                               ssl->buffers.certificate->length);
15174         }
15175         return ssl->ourCert;
15176     }
15177     else { /* if cert not owned get parent ctx cert or return null */
15178         if (ssl->ctx) {
15179             if (ssl->ctx->ourCert == NULL) {
15180                 if (ssl->ctx->certificate == NULL) {
15181                     WOLFSSL_MSG("Ctx Certificate buffer not set!");
15182                     return NULL;
15183                 }
15184                 ssl->ctx->ourCert = wolfSSL_X509_d2i(NULL,
15185                                                ssl->ctx->certificate->buffer,
15186                                                ssl->ctx->certificate->length);
15187                 ssl->ctx->ownOurCert = 1;
15188             }
15189             return ssl->ctx->ourCert;
15190         }
15191     }
15192 
15193     return NULL;
15194 }
15195 #endif /* OPENSSL_EXTRA && KEEP_OUR_CERT */
15196 #endif /* NO_CERTS */
15197 
15198 
15199 #ifdef OPENSSL_EXTRA
15200 /* return 1 on success 0 on fail */
15201 int wolfSSL_sk_ASN1_OBJECT_push(WOLF_STACK_OF(WOLFSSL_ASN1_OBJEXT)* sk,
15202                                                       WOLFSSL_ASN1_OBJECT* obj)
15203 {
15204     WOLFSSL_STACK* node;
15205 
15206     if (sk == NULL || obj == NULL) {
15207         return WOLFSSL_FAILURE;
15208     }
15209 
15210     /* no previous values in stack */
15211     if (sk->data.obj == NULL) {
15212         sk->data.obj = obj;
15213         sk->num += 1;
15214         return WOLFSSL_SUCCESS;
15215     }
15216 
15217     /* stack already has value(s) create a new node and add more */
15218     node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
15219                                                              DYNAMIC_TYPE_ASN1);
15220     if (node == NULL) {
15221         WOLFSSL_MSG("Memory error");
15222         return WOLFSSL_FAILURE;
15223     }
15224     XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
15225 
15226     /* push new obj onto head of stack */
15227     node->data.obj = sk->data.obj;
15228     node->next      = sk->next;
15229     sk->next        = node;
15230     sk->data.obj   = obj;
15231     sk->num        += 1;
15232 
15233     return WOLFSSL_SUCCESS;
15234 }
15235 
15236 
15237 WOLFSSL_ASN1_OBJECT* wolfSSL_sk_ASN1_OBJCET_pop(
15238                                             WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk)
15239 {
15240     WOLFSSL_STACK* node;
15241     WOLFSSL_ASN1_OBJECT*  obj;
15242 
15243     if (sk == NULL) {
15244         return NULL;
15245     }
15246 
15247     node = sk->next;
15248     obj = sk->data.obj;
15249 
15250     if (node != NULL) { /* update sk and remove node from stack */
15251         sk->data.obj = node->data.obj;
15252         sk->next = node->next;
15253         XFREE(node, NULL, DYNAMIC_TYPE_ASN1);
15254     }
15255     else { /* last obj in stack */
15256         sk->data.obj = NULL;
15257     }
15258 
15259     if (sk->num > 0) {
15260         sk->num -= 1;
15261     }
15262 
15263     return obj;
15264 }
15265 
15266 
15267 #ifndef NO_ASN
15268 WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void)
15269 {
15270     WOLFSSL_ASN1_OBJECT* obj;
15271 
15272     obj = (WOLFSSL_ASN1_OBJECT*)XMALLOC(sizeof(WOLFSSL_ASN1_OBJECT), NULL,
15273                                         DYNAMIC_TYPE_ASN1);
15274     if (obj == NULL) {
15275         return NULL;
15276     }
15277 
15278     XMEMSET(obj, 0, sizeof(WOLFSSL_ASN1_OBJECT));
15279     obj->d.ia5 = &(obj->d.ia5_internal);
15280     return obj;
15281 }
15282 
15283 
15284 void wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT* obj)
15285 {
15286     if (obj == NULL) {
15287         return;
15288     }
15289 
15290     if (obj->dynamic == 1) {
15291         if (obj->obj != NULL) {
15292             WOLFSSL_MSG("Freeing ASN1 OBJECT data");
15293             XFREE(obj->obj, obj->heap, DYNAMIC_TYPE_ASN1);
15294         }
15295     }
15296 
15297     XFREE(obj, NULL, DYNAMIC_TYPE_ASN1);
15298 }
15299 
15300 
15301 /* free structure for x509 stack */
15302 void wolfSSL_sk_ASN1_OBJECT_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk)
15303 {
15304     WOLFSSL_STACK* node;
15305 
15306     if (sk == NULL) {
15307         return;
15308     }
15309 
15310     /* parse through stack freeing each node */
15311     node = sk->next;
15312     while (sk->num > 1) {
15313         WOLFSSL_STACK* tmp = node;
15314         node = node->next;
15315 
15316         wolfSSL_ASN1_OBJECT_free(tmp->data.obj);
15317         XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1);
15318         sk->num -= 1;
15319     }
15320 
15321     /* free head of stack */
15322     if (sk->num == 1) {
15323         wolfSSL_ASN1_OBJECT_free(sk->data.obj);
15324     }
15325     XFREE(sk, NULL, DYNAMIC_TYPE_ASN1);
15326 }
15327 
15328 int wolfSSL_ASN1_STRING_to_UTF8(unsigned char **out, WOLFSSL_ASN1_STRING *in)
15329 {
15330     /*
15331        ASN1_STRING_to_UTF8() converts the string in to UTF8 format,
15332        the converted data is allocated in a buffer in *out.
15333        The length of out is returned or a negative error code.
15334        The buffer *out should be free using OPENSSL_free().
15335        */
15336     (void)out;
15337     (void)in;
15338     WOLFSSL_STUB("ASN1_STRING_to_UTF8");
15339     return -1;
15340 }
15341 #endif /* NO_ASN */
15342 
15343 void wolfSSL_set_connect_state(WOLFSSL* ssl)
15344 {
15345     word16 haveRSA = 1;
15346     word16 havePSK = 0;
15347 
15348     if (ssl == NULL) {
15349         WOLFSSL_MSG("WOLFSSL struct pointer passed in was null");
15350         return;
15351     }
15352 
15353     #ifndef NO_DH
15354     /* client creates its own DH parameters on handshake */
15355     if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
15356         XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap,
15357             DYNAMIC_TYPE_PUBLIC_KEY);
15358     }
15359     ssl->buffers.serverDH_P.buffer = NULL;
15360     if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
15361         XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap,
15362             DYNAMIC_TYPE_PUBLIC_KEY);
15363     }
15364     ssl->buffers.serverDH_G.buffer = NULL;
15365     #endif
15366 
15367     if (ssl->options.side == WOLFSSL_SERVER_END) {
15368         #ifdef NO_RSA
15369             haveRSA = 0;
15370         #endif
15371         #ifndef NO_PSK
15372             havePSK = ssl->options.havePSK;
15373         #endif
15374         InitSuites(ssl->suites, ssl->version, ssl->buffers.keySz, haveRSA,
15375                    havePSK, ssl->options.haveDH, ssl->options.haveNTRU,
15376                    ssl->options.haveECDSAsig, ssl->options.haveECC,
15377                    ssl->options.haveStaticECC, WOLFSSL_CLIENT_END);
15378     }
15379     ssl->options.side = WOLFSSL_CLIENT_END;
15380 }
15381 #endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA */
15382 
15383 
15384 int wolfSSL_get_shutdown(const WOLFSSL* ssl)
15385 {
15386     WOLFSSL_ENTER("wolfSSL_get_shutdown");
15387     /* in OpenSSL, WOLFSSL_SENT_SHUTDOWN = 1, when closeNotifySent   *
15388      * WOLFSSL_RECEIVED_SHUTDOWN = 2, from close notify or fatal err */
15389     return ((ssl->options.closeNotify||ssl->options.connReset) << 1)
15390             | (ssl->options.sentNotify);
15391 }
15392 
15393 
15394 int wolfSSL_session_reused(WOLFSSL* ssl)
15395 {
15396     return ssl->options.resuming;
15397 }
15398 
15399 #if defined(OPENSSL_EXTRA) || defined(HAVE_EXT_CACHE)
15400 void wolfSSL_SESSION_free(WOLFSSL_SESSION* session)
15401 {
15402     if (session == NULL)
15403         return;
15404 
15405 #ifdef HAVE_EXT_CACHE
15406     if (session->isAlloced) {
15407     #ifdef HAVE_SESSION_TICKET
15408         if (session->isDynamic)
15409             XFREE(session->ticket, NULL, DYNAMIC_TYPE_SESSION_TICK);
15410     #endif
15411         XFREE(session, NULL, DYNAMIC_TYPE_OPENSSL);
15412     }
15413 #else
15414     /* No need to free since cache is static */
15415     (void)session;
15416 #endif
15417 }
15418 #endif
15419 
15420 const char* wolfSSL_get_version(WOLFSSL* ssl)
15421 {
15422     WOLFSSL_ENTER("SSL_get_version");
15423     if (ssl->version.major == SSLv3_MAJOR) {
15424         switch (ssl->version.minor) {
15425         #ifndef NO_OLD_TLS
15426             #ifdef WOLFSSL_ALLOW_SSLV3
15427             case SSLv3_MINOR :
15428                 return "SSLv3";
15429             #endif
15430             #ifdef WOLFSSL_ALLOW_TLSV10
15431             case TLSv1_MINOR :
15432                 return "TLSv1";
15433             #endif
15434             case TLSv1_1_MINOR :
15435                 return "TLSv1.1";
15436         #endif
15437             case TLSv1_2_MINOR :
15438                 return "TLSv1.2";
15439         #ifdef WOLFSSL_TLS13
15440             case TLSv1_3_MINOR :
15441             /* TODO: [TLS13] Remove draft versions. */
15442             #ifndef WOLFSSL_TLS13_FINAL
15443                 #ifdef WOLFSSL_TLS13_DRAFT_18
15444                     return "TLSv1.3 (Draft 18)";
15445                 #elif defined(WOLFSSL_TLS13_DRAFT_22)
15446                     return "TLSv1.3 (Draft 22)";
15447                 #elif defined(WOLFSSL_TLS13_DRAFT_23)
15448                     return "TLSv1.3 (Draft 23)";
15449                 #elif defined(WOLFSSL_TLS13_DRAFT_26)
15450                     return "TLSv1.3 (Draft 26)";
15451                 #else
15452                     return "TLSv1.3 (Draft 28)";
15453                 #endif
15454             #else
15455                 return "TLSv1.3";
15456             #endif
15457         #endif
15458             default:
15459                 return "unknown";
15460         }
15461     }
15462 #ifdef WOLFSSL_DTLS
15463     else if (ssl->version.major == DTLS_MAJOR) {
15464         switch (ssl->version.minor) {
15465             case DTLS_MINOR :
15466                 return "DTLS";
15467             case DTLSv1_2_MINOR :
15468                 return "DTLSv1.2";
15469             default:
15470                 return "unknown";
15471         }
15472     }
15473 #endif /* WOLFSSL_DTLS */
15474     return "unknown";
15475 }
15476 
15477 
15478 /* current library version */
15479 const char* wolfSSL_lib_version(void)
15480 {
15481     return LIBWOLFSSL_VERSION_STRING;
15482 }
15483 
15484 
15485 /* current library version in hex */
15486 word32 wolfSSL_lib_version_hex(void)
15487 {
15488     return LIBWOLFSSL_VERSION_HEX;
15489 }
15490 
15491 
15492 int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl)
15493 {
15494     WOLFSSL_ENTER("SSL_get_current_cipher_suite");
15495     if (ssl)
15496         return (ssl->options.cipherSuite0 << 8) | ssl->options.cipherSuite;
15497     return 0;
15498 }
15499 
15500 WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL* ssl)
15501 {
15502     WOLFSSL_ENTER("SSL_get_current_cipher");
15503     if (ssl)
15504         return &ssl->cipher;
15505     else
15506         return NULL;
15507 }
15508 
15509 
15510 const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher)
15511 {
15512     WOLFSSL_ENTER("SSL_CIPHER_get_name");
15513 
15514     if (cipher == NULL || cipher->ssl == NULL) {
15515         return NULL;
15516     }
15517 
15518     return wolfSSL_get_cipher_name_iana(cipher->ssl);
15519 }
15520 
15521 const char* wolfSSL_SESSION_CIPHER_get_name(WOLFSSL_SESSION* session)
15522 {
15523     if (session == NULL) {
15524         return NULL;
15525     }
15526 
15527 #ifdef SESSION_CERTS
15528     return GetCipherNameIana(session->cipherSuite0, session->cipherSuite);
15529 #else
15530     return NULL;
15531 #endif
15532 }
15533 
15534 const char* wolfSSL_get_cipher(WOLFSSL* ssl)
15535 {
15536     WOLFSSL_ENTER("wolfSSL_get_cipher");
15537     return wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl));
15538 }
15539 
15540 /* gets cipher name in the format DHE-RSA-... rather then TLS_DHE... */
15541 const char* wolfSSL_get_cipher_name(WOLFSSL* ssl)
15542 {
15543     /* get access to cipher_name_idx in internal.c */
15544     return wolfSSL_get_cipher_name_internal(ssl);
15545 }
15546 
15547 const char* wolfSSL_get_cipher_name_from_suite(const byte cipherSuite0,
15548     const byte cipherSuite)
15549 {
15550     return GetCipherNameInternal(cipherSuite0, cipherSuite);
15551 }
15552 
15553 
15554 #ifdef HAVE_ECC
15555 /* Return the name of the curve used for key exchange as a printable string.
15556  *
15557  * ssl  The SSL/TLS object.
15558  * returns NULL if ECDH was not used, otherwise the name as a string.
15559  */
15560 const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
15561 {
15562     if (ssl == NULL)
15563         return NULL;
15564     if (!IsAtLeastTLSv1_3(ssl->version) && ssl->specs.kea != ecdhe_psk_kea &&
15565             ssl->specs.kea != ecc_diffie_hellman_kea)
15566         return NULL;
15567     if (ssl->ecdhCurveOID == 0)
15568         return NULL;
15569     if (ssl->ecdhCurveOID == ECC_X25519_OID)
15570         return "X25519";
15571     return wc_ecc_get_name(wc_ecc_get_oid(ssl->ecdhCurveOID, NULL, NULL));
15572 }
15573 #endif
15574 
15575 
15576 #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(KEEP_PEER_CERT) || \
15577     defined(SESSION_CERTS)
15578 /* Smaller subset of X509 compatibility functions. Avoid increasing the size of
15579  * this subset and its memory usage */
15580 
15581 #if !defined(NO_CERTS)
15582 /* returns a pointer to a new WOLFSSL_X509 structure on success and NULL on
15583  * fail
15584  */
15585 WOLFSSL_X509* wolfSSL_X509_new()
15586 {
15587     WOLFSSL_X509* x509;
15588 
15589     x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
15590             DYNAMIC_TYPE_X509);
15591     if (x509 != NULL) {
15592         InitX509(x509, 1, NULL);
15593     }
15594 
15595     return x509;
15596 }
15597 
15598 WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
15599 {
15600     WOLFSSL_ENTER("wolfSSL_X509_get_subject_name");
15601     if (cert && cert->subject.sz != 0)
15602         return &cert->subject;
15603     return NULL;
15604 }
15605 
15606 
15607 
15608 WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509* cert)
15609 {
15610     WOLFSSL_ENTER("X509_get_issuer_name");
15611     if (cert && cert->issuer.sz != 0)
15612         return &cert->issuer;
15613     return NULL;
15614 }
15615 
15616 
15617 int wolfSSL_X509_get_signature_type(WOLFSSL_X509* x509)
15618 {
15619     int type = 0;
15620 
15621     WOLFSSL_ENTER("wolfSSL_X509_get_signature_type");
15622 
15623     if (x509 != NULL)
15624         type = x509->sigOID;
15625 
15626     return type;
15627 }
15628 
15629 #if defined(OPENSSL_EXTRA_X509_SMALL)
15630 #ifdef HAVE_ECC
15631     static int SetECKeyExternal(WOLFSSL_EC_KEY* eckey);
15632 #endif
15633 
15634 /* Used to get a string from the WOLFSSL_X509_NAME structure that
15635  * corresponds with the NID value passed in.
15636  *
15637  * name structure to get string from
15638  * nid  NID value to search for
15639  * buf  [out] buffer to hold results. If NULL then the buffer size minus the
15640  *      null char is returned.
15641  * len  size of "buf" passed in
15642  *
15643  * returns the length of string found, not including the NULL terminator.
15644  *         It's possible the function could return a negative value in the
15645  *         case that len is less than or equal to 0. A negative value is
15646  *         considered an error case.
15647  */
15648 int wolfSSL_X509_NAME_get_text_by_NID(WOLFSSL_X509_NAME* name,
15649                                       int nid, char* buf, int len)
15650 {
15651     char *text = NULL;
15652     int textSz = 0;
15653 
15654     WOLFSSL_ENTER("wolfSSL_X509_NAME_get_text_by_NID");
15655 
15656     switch (nid) {
15657         case ASN_COMMON_NAME:
15658             text = name->fullName.fullName + name->fullName.cnIdx;
15659             textSz = name->fullName.cnLen;
15660             break;
15661         case ASN_SUR_NAME:
15662             text = name->fullName.fullName + name->fullName.snIdx;
15663             textSz = name->fullName.snLen;
15664             break;
15665         case ASN_SERIAL_NUMBER:
15666             text = name->fullName.fullName + name->fullName.serialIdx;
15667             textSz = name->fullName.serialLen;
15668             break;
15669         case ASN_COUNTRY_NAME:
15670             text = name->fullName.fullName + name->fullName.cIdx;
15671             textSz = name->fullName.cLen;
15672             break;
15673         case ASN_LOCALITY_NAME:
15674             text = name->fullName.fullName + name->fullName.lIdx;
15675             textSz = name->fullName.lLen;
15676             break;
15677         case ASN_STATE_NAME:
15678             text = name->fullName.fullName + name->fullName.stIdx;
15679             textSz = name->fullName.stLen;
15680             break;
15681         case ASN_ORG_NAME:
15682             text = name->fullName.fullName + name->fullName.oIdx;
15683             textSz = name->fullName.oLen;
15684             break;
15685         case ASN_ORGUNIT_NAME:
15686             text = name->fullName.fullName + name->fullName.ouIdx;
15687             textSz = name->fullName.ouLen;
15688             break;
15689         case ASN_DOMAIN_COMPONENT:
15690             text = name->fullName.fullName + name->fullName.dcIdx[0];
15691             textSz = name->fullName.dcLen[0];
15692             break;
15693         default:
15694             WOLFSSL_MSG("Entry type not found");
15695             return SSL_FATAL_ERROR;
15696     }
15697 
15698     /* if buf is NULL return size of buffer needed (minus null char) */
15699     if (buf == NULL) {
15700         return textSz;
15701     }
15702 
15703     if (buf != NULL && text != NULL) {
15704         textSz = min(textSz + 1, len); /* + 1 to account for null char */
15705         if (textSz > 0) {
15706             XMEMCPY(buf, text, textSz - 1);
15707             buf[textSz - 1] = '\0';
15708         }
15709     }
15710 
15711     WOLFSSL_LEAVE("wolfSSL_X509_NAME_get_text_by_NID", textSz);
15712     return (textSz - 1); /* do not include null character in size */
15713 }
15714 
15715 
15716 /* Creates a new WOLFSSL_EVP_PKEY structure that has the public key from x509
15717  *
15718  * returns a pointer to the created WOLFSSL_EVP_PKEY on success and NULL on fail
15719  */
15720 WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
15721 {
15722     WOLFSSL_EVP_PKEY* key = NULL;
15723     WOLFSSL_ENTER("X509_get_pubkey");
15724     if (x509 != NULL) {
15725         key = (WOLFSSL_EVP_PKEY*)XMALLOC(
15726                     sizeof(WOLFSSL_EVP_PKEY), x509->heap,
15727                                                        DYNAMIC_TYPE_PUBLIC_KEY);
15728         if (key != NULL) {
15729             XMEMSET(key, 0, sizeof(WOLFSSL_EVP_PKEY));
15730             if (x509->pubKeyOID == RSAk) {
15731                 key->type = EVP_PKEY_RSA;
15732             }
15733             else {
15734                 key->type = EVP_PKEY_EC;
15735             }
15736             key->save_type = 0;
15737             key->pkey.ptr = (char*)XMALLOC(
15738                         x509->pubKey.length, x509->heap,
15739                                                        DYNAMIC_TYPE_PUBLIC_KEY);
15740             if (key->pkey.ptr == NULL) {
15741                 XFREE(key, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
15742                 return NULL;
15743             }
15744             XMEMCPY(key->pkey.ptr, x509->pubKey.buffer, x509->pubKey.length);
15745             key->pkey_sz = x509->pubKey.length;
15746 
15747             #ifdef HAVE_ECC
15748                 key->pkey_curve = (int)x509->pkCurveOID;
15749             #endif /* HAVE_ECC */
15750 
15751             /* decode RSA key */
15752             #ifndef NO_RSA
15753             if (key->type == EVP_PKEY_RSA) {
15754                 key->ownRsa = 1;
15755                 key->rsa = wolfSSL_RSA_new();
15756                 if (key->rsa == NULL) {
15757                     XFREE(key, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
15758                     return NULL;
15759                 }
15760 
15761                 if (wolfSSL_RSA_LoadDer_ex(key->rsa,
15762                             (const unsigned char*)key->pkey.ptr, key->pkey_sz,
15763                             WOLFSSL_RSA_LOAD_PUBLIC) != SSL_SUCCESS) {
15764                     wolfSSL_RSA_free(key->rsa);
15765                     XFREE(key, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
15766                     return NULL;
15767                 }
15768             }
15769             #endif /* NO_RSA */
15770 
15771             /* decode ECC key */
15772             #ifdef HAVE_ECC
15773             if (key->type == EVP_PKEY_EC) {
15774                 word32 idx = 0;
15775 
15776                 key->ownEcc = 1;
15777                 key->ecc = wolfSSL_EC_KEY_new();
15778                 if (key->ecc == NULL || key->ecc->internal == NULL) {
15779                     XFREE(key, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
15780                     return NULL;
15781                 }
15782 
15783                 /* not using wolfSSL_EC_KEY_LoadDer because public key in x509
15784                  * is in the format of x963 (no sequence at start of buffer) */
15785                 if (wc_EccPublicKeyDecode((const unsigned char*)key->pkey.ptr,
15786                         &idx, (ecc_key*)key->ecc->internal, key->pkey_sz) < 0) {
15787                     WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
15788                     XFREE(key, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
15789                     wolfSSL_EC_KEY_free(key->ecc);
15790                     return NULL;
15791                 }
15792 
15793                 if (SetECKeyExternal(key->ecc) != SSL_SUCCESS) {
15794                     WOLFSSL_MSG("SetECKeyExternal failed");
15795                     XFREE(key, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
15796                     wolfSSL_EC_KEY_free(key->ecc);
15797                     return NULL;
15798                 }
15799 
15800                 key->ecc->inSet = 1;
15801             }
15802             #endif /* HAVE_ECC */
15803         }
15804     }
15805     return key;
15806 }
15807 #endif /* OPENSSL_EXTRA_X509_SMALL */
15808 #endif /* !NO_CERTS */
15809 
15810 /* End of smaller subset of X509 compatibility functions. Avoid increasing the
15811  * size of this subset and its memory usage */
15812 #endif /* OPENSSL_EXTRA_X509_SMALL */
15813 
15814 #if defined(OPENSSL_EXTRA)
15815 #if !defined(NO_CERTS)
15816     int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509* x509, int nid)
15817     {
15818         int isSet = 0;
15819 
15820         WOLFSSL_ENTER("wolfSSL_X509_ext_isSet_by_NID");
15821 
15822         if (x509 != NULL) {
15823             switch (nid) {
15824                 case BASIC_CA_OID: isSet = x509->basicConstSet; break;
15825                 case ALT_NAMES_OID: isSet = x509->subjAltNameSet; break;
15826                 case AUTH_KEY_OID: isSet = x509->authKeyIdSet; break;
15827                 case SUBJ_KEY_OID: isSet = x509->subjKeyIdSet; break;
15828                 case KEY_USAGE_OID: isSet = x509->keyUsageSet; break;
15829                 #ifdef WOLFSSL_SEP
15830                     case CERT_POLICY_OID: isSet = x509->certPolicySet; break;
15831                 #endif /* WOLFSSL_SEP */
15832             }
15833         }
15834 
15835         WOLFSSL_LEAVE("wolfSSL_X509_ext_isSet_by_NID", isSet);
15836 
15837         return isSet;
15838     }
15839 
15840 
15841     int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509* x509, int nid)
15842     {
15843         int crit = 0;
15844 
15845         WOLFSSL_ENTER("wolfSSL_X509_ext_get_critical_by_NID");
15846 
15847         if (x509 != NULL) {
15848             switch (nid) {
15849                 case BASIC_CA_OID: crit = x509->basicConstCrit; break;
15850                 case ALT_NAMES_OID: crit = x509->subjAltNameCrit; break;
15851                 case AUTH_KEY_OID: crit = x509->authKeyIdCrit; break;
15852                 case SUBJ_KEY_OID: crit = x509->subjKeyIdCrit; break;
15853                 case KEY_USAGE_OID: crit = x509->keyUsageCrit; break;
15854                 #ifdef WOLFSSL_SEP
15855                     case CERT_POLICY_OID: crit = x509->certPolicyCrit; break;
15856                 #endif /* WOLFSSL_SEP */
15857             }
15858         }
15859 
15860         WOLFSSL_LEAVE("wolfSSL_X509_ext_get_critical_by_NID", crit);
15861 
15862         return crit;
15863     }
15864 
15865 
15866     int wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509* x509)
15867     {
15868         int isSet = 0;
15869 
15870         WOLFSSL_ENTER("wolfSSL_X509_get_isSet_pathLength");
15871 
15872         if (x509 != NULL)
15873             isSet = x509->basicConstPlSet;
15874 
15875         WOLFSSL_LEAVE("wolfSSL_X509_get_isSet_pathLength", isSet);
15876 
15877         return isSet;
15878     }
15879 
15880 
15881     word32 wolfSSL_X509_get_pathLength(WOLFSSL_X509* x509)
15882     {
15883         word32 pathLength = 0;
15884 
15885         WOLFSSL_ENTER("wolfSSL_X509_get_pathLength");
15886 
15887         if (x509 != NULL)
15888             pathLength = x509->pathLength;
15889 
15890         WOLFSSL_LEAVE("wolfSSL_X509_get_pathLength", pathLength);
15891 
15892         return pathLength;
15893     }
15894 
15895 
15896     unsigned int wolfSSL_X509_get_keyUsage(WOLFSSL_X509* x509)
15897     {
15898         word16 usage = 0;
15899 
15900         WOLFSSL_ENTER("wolfSSL_X509_get_keyUsage");
15901 
15902         if (x509 != NULL)
15903             usage = x509->keyUsage;
15904 
15905         WOLFSSL_LEAVE("wolfSSL_X509_get_keyUsage", usage);
15906 
15907         return usage;
15908     }
15909 
15910 
15911     byte* wolfSSL_X509_get_authorityKeyID(WOLFSSL_X509* x509,
15912                                           byte* dst, int* dstLen)
15913     {
15914         byte *id = NULL;
15915         int copySz = 0;
15916 
15917         WOLFSSL_ENTER("wolfSSL_X509_get_authorityKeyID");
15918 
15919         if (x509 != NULL) {
15920             if (x509->authKeyIdSet) {
15921                 copySz = min(dstLen != NULL ? *dstLen : 0,
15922                              (int)x509->authKeyIdSz);
15923                 id = x509->authKeyId;
15924             }
15925 
15926             if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
15927                 XMEMCPY(dst, id, copySz);
15928                 id = dst;
15929                 *dstLen = copySz;
15930             }
15931         }
15932 
15933         WOLFSSL_LEAVE("wolfSSL_X509_get_authorityKeyID", copySz);
15934 
15935         return id;
15936     }
15937 
15938 
15939     byte* wolfSSL_X509_get_subjectKeyID(WOLFSSL_X509* x509,
15940                                         byte* dst, int* dstLen)
15941     {
15942         byte *id = NULL;
15943         int copySz = 0;
15944 
15945         WOLFSSL_ENTER("wolfSSL_X509_get_subjectKeyID");
15946 
15947         if (x509 != NULL) {
15948             if (x509->subjKeyIdSet) {
15949                 copySz = min(dstLen != NULL ? *dstLen : 0,
15950                                                         (int)x509->subjKeyIdSz);
15951                 id = x509->subjKeyId;
15952             }
15953 
15954             if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
15955                 XMEMCPY(dst, id, copySz);
15956                 id = dst;
15957                 *dstLen = copySz;
15958             }
15959         }
15960 
15961         WOLFSSL_LEAVE("wolfSSL_X509_get_subjectKeyID", copySz);
15962 
15963         return id;
15964     }
15965 
15966 
15967     int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME* name)
15968     {
15969         int count = 0;
15970 
15971         WOLFSSL_ENTER("wolfSSL_X509_NAME_entry_count");
15972 
15973         if (name != NULL)
15974             count = name->fullName.entryCount;
15975 
15976         WOLFSSL_LEAVE("wolfSSL_X509_NAME_entry_count", count);
15977         return count;
15978     }
15979 
15980 
15981 
15982     int wolfSSL_X509_NAME_get_index_by_NID(WOLFSSL_X509_NAME* name,
15983                                           int nid, int pos)
15984     {
15985         int ret    = -1;
15986 
15987         WOLFSSL_ENTER("wolfSSL_X509_NAME_get_index_by_NID");
15988 
15989         if (name == NULL) {
15990             return BAD_FUNC_ARG;
15991         }
15992 
15993         /* these index values are already stored in DecodedName
15994            use those when available */
15995         if (name->fullName.fullName && name->fullName.fullNameLen > 0) {
15996             name->fullName.dcMode = 0;
15997             switch (nid) {
15998                 case ASN_COMMON_NAME:
15999                     if (pos != name->fullName.cnIdx)
16000                         ret = name->fullName.cnIdx;
16001                     break;
16002                 case ASN_DOMAIN_COMPONENT:
16003                     name->fullName.dcMode = 1;
16004                     if (pos < name->fullName.dcNum - 1){
16005                         ret = pos + 1;
16006                     } else {
16007                         ret = -1;
16008                     }
16009                     break;
16010                 default:
16011                     WOLFSSL_MSG("NID not yet implemented");
16012                     break;
16013             }
16014         }
16015 
16016         WOLFSSL_LEAVE("wolfSSL_X509_NAME_get_index_by_NID", ret);
16017 
16018         (void)pos;
16019         (void)nid;
16020 
16021         return ret;
16022     }
16023 
16024 
16025     WOLFSSL_ASN1_STRING*  wolfSSL_X509_NAME_ENTRY_get_data(
16026                                                     WOLFSSL_X509_NAME_ENTRY* in)
16027     {
16028         WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_data");
16029         return in->value;
16030     }
16031 
16032 
16033     /* Creates a new WOLFSSL_ASN1_STRING structure.
16034      *
16035      * returns a pointer to the new structure created on success or NULL if fail
16036      */
16037     WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_new()
16038     {
16039         WOLFSSL_ASN1_STRING* asn1;
16040 
16041         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_new");
16042 
16043         asn1 = (WOLFSSL_ASN1_STRING*)XMALLOC(sizeof(WOLFSSL_ASN1_STRING), NULL,
16044                 DYNAMIC_TYPE_OPENSSL);
16045         if (asn1 != NULL) {
16046             XMEMSET(asn1, 0, sizeof(WOLFSSL_ASN1_STRING));
16047         }
16048 
16049         return asn1; /* no check for null because error case is returning null*/
16050     }
16051 
16052 
16053     /* used to free a WOLFSSL_ASN1_STRING structure */
16054     void wolfSSL_ASN1_STRING_free(WOLFSSL_ASN1_STRING* asn1)
16055     {
16056         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_free");
16057 
16058         if (asn1 != NULL) {
16059             if (asn1->length > 0 && asn1->data != NULL) {
16060                 XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
16061             }
16062             XFREE(asn1, NULL, DYNAMIC_TYPE_OPENSSL);
16063         }
16064     }
16065 
16066 
16067     /* Creates a new WOLFSSL_ASN1_STRING structure given the input type.
16068      *
16069      * type is the type of set when WOLFSSL_ASN1_STRING is created
16070      *
16071      * returns a pointer to the new structure created on success or NULL if fail
16072      */
16073     WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_type_new(int type)
16074     {
16075         WOLFSSL_ASN1_STRING* asn1;
16076 
16077         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_type_new");
16078 
16079         asn1 = wolfSSL_ASN1_STRING_new();
16080         if (asn1 == NULL) {
16081             return NULL;
16082         }
16083         asn1->type = type;
16084 
16085         return asn1;
16086     }
16087 
16088 
16089     /* if dataSz is negative then use XSTRLEN to find length of data
16090      * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */
16091     int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1, const void* data,
16092             int dataSz)
16093     {
16094         int sz;
16095 
16096         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_set");
16097 
16098         if (data == NULL || asn1 == NULL) {
16099             return WOLFSSL_FAILURE;
16100         }
16101 
16102         if (dataSz < 0) {
16103             sz = (int)XSTRLEN((const char*)data) + 1; /* +1 for null */
16104         }
16105         else {
16106             sz = dataSz;
16107         }
16108 
16109         if (sz < 0) {
16110             return WOLFSSL_FAILURE;
16111         }
16112 
16113         /* free any existing data before copying */
16114         if (asn1->data != NULL) {
16115             XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
16116         }
16117 
16118         /* create new data buffer and copy over */
16119         asn1->data = (char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_OPENSSL);
16120         if (asn1->data == NULL) {
16121             return WOLFSSL_FAILURE;
16122         }
16123         XMEMCPY(asn1->data, data, sz);
16124         asn1->length = sz;
16125 
16126         return WOLFSSL_SUCCESS;
16127     }
16128 
16129 
16130     unsigned char* wolfSSL_ASN1_STRING_data(WOLFSSL_ASN1_STRING* asn)
16131     {
16132         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_data");
16133 
16134         if (asn) {
16135             return (unsigned char*)asn->data;
16136         }
16137         else {
16138             return NULL;
16139         }
16140     }
16141 
16142 
16143     int wolfSSL_ASN1_STRING_length(WOLFSSL_ASN1_STRING* asn)
16144     {
16145         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_length");
16146 
16147         if (asn) {
16148             return asn->length;
16149         }
16150         else {
16151             return 0;
16152         }
16153     }
16154 
16155 
16156 #ifdef XSNPRINTF /* a snprintf function needs to be available */
16157     /* Writes the human readable form of x509 to bio.
16158      *
16159      * bio  WOLFSSL_BIO to write to.
16160      * x509 Certificate to write.
16161      *
16162      * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
16163      */
16164     int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
16165     {
16166         WOLFSSL_ENTER("wolfSSL_X509_print");
16167 
16168         if (bio == NULL || x509 == NULL) {
16169             return WOLFSSL_FAILURE;
16170         }
16171 
16172         if (wolfSSL_BIO_write(bio, "Certificate:\n", sizeof("Certificate:\n"))
16173             <= 0) {
16174                 return WOLFSSL_FAILURE;
16175         }
16176 
16177         if (wolfSSL_BIO_write(bio, "    Data:\n", sizeof("    Data:\n"))
16178             <= 0) {
16179                 return WOLFSSL_FAILURE;
16180         }
16181 
16182         /* print version of cert */
16183         {
16184             int version;
16185             char tmp[17];
16186 
16187             if ((version = wolfSSL_X509_version(x509)) <= 0) {
16188                 WOLFSSL_MSG("Error getting X509 version");
16189                 return WOLFSSL_FAILURE;
16190             }
16191             if (wolfSSL_BIO_write(bio, "        Version: ",
16192                                 sizeof("        Version: ")) <= 0) {
16193                 return WOLFSSL_FAILURE;
16194             }
16195             XSNPRINTF(tmp, sizeof(tmp), "%d\n", version);
16196             if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
16197                 return WOLFSSL_FAILURE;
16198             }
16199         }
16200 
16201         /* print serial number out */
16202         {
16203             unsigned char serial[32];
16204             int  sz = sizeof(serial);
16205 
16206             XMEMSET(serial, 0, sz);
16207             if (wolfSSL_X509_get_serial_number(x509, serial, &sz)
16208                     != WOLFSSL_SUCCESS) {
16209                 WOLFSSL_MSG("Error getting x509 serial number");
16210                 return WOLFSSL_FAILURE;
16211             }
16212             if (wolfSSL_BIO_write(bio, "        Serial Number: ",
16213                                 sizeof("        Serial Number: ")) <= 0) {
16214                 return WOLFSSL_FAILURE;
16215             }
16216 
16217             /* if serial can fit into byte than print on the same line */
16218             if (sz <= (int)sizeof(byte)) {
16219                 char tmp[17];
16220                 XSNPRINTF(tmp, sizeof(tmp), "%d (0x%x)\n", serial[0],serial[0]);
16221                 if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
16222                     return WOLFSSL_FAILURE;
16223                 }
16224             }
16225             else {
16226                 int i;
16227                 char tmp[100];
16228                 int  tmpSz = 100;
16229                 char val[5];
16230                 int  valSz = 5;
16231 
16232                 /* serial is larger than int size so print off hex values */
16233                 if (wolfSSL_BIO_write(bio, "\n            ",
16234                                 sizeof("\n            ")) <= 0) {
16235                     return WOLFSSL_FAILURE;
16236                 }
16237                 tmp[0] = '\0';
16238                 for (i = 0; i < sz - 1 && (3 * i) < tmpSz - valSz; i++) {
16239                     XSNPRINTF(val, sizeof(val) - 1, "%02x:", serial[i]);
16240                     val[3] = '\0'; /* make sure is null terminated */
16241                     XSTRNCAT(tmp, val, valSz);
16242                 }
16243                 XSNPRINTF(val, sizeof(val) - 1, "%02x\n", serial[i]);
16244                 val[3] = '\0'; /* make sure is null terminated */
16245                 XSTRNCAT(tmp, val, valSz);
16246                 if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
16247                     return WOLFSSL_FAILURE;
16248                 }
16249             }
16250         }
16251 
16252         /* print signature algo */
16253         {
16254             int   oid;
16255             char* sig;
16256 
16257             if ((oid = wolfSSL_X509_get_signature_type(x509)) <= 0) {
16258                 WOLFSSL_MSG("Error getting x509 signature type");
16259                 return WOLFSSL_FAILURE;
16260             }
16261             if (wolfSSL_BIO_write(bio, "    Signature Algorithm: ",
16262                                 sizeof("    Signature Algorithm: ")) <= 0) {
16263                 return WOLFSSL_FAILURE;
16264             }
16265             sig = GetSigName(oid);
16266             if (wolfSSL_BIO_write(bio, sig, (int)XSTRLEN(sig)) <= 0) {
16267                 return WOLFSSL_FAILURE;
16268             }
16269             if (wolfSSL_BIO_write(bio, "\n", sizeof("\n")) <= 0) {
16270                 return WOLFSSL_FAILURE;
16271             }
16272         }
16273 
16274         /* print issuer */
16275         {
16276             char* issuer;
16277         #ifdef WOLFSSL_SMALL_STACK
16278             char* buff  = NULL;
16279             int   issSz = 0;
16280         #else
16281             char buff[256];
16282             int  issSz = 256;
16283         #endif
16284 
16285             issuer  = wolfSSL_X509_NAME_oneline(
16286                              wolfSSL_X509_get_issuer_name(x509), buff, issSz);
16287 
16288             if (wolfSSL_BIO_write(bio, "        Issuer: ",
16289                                 sizeof("        Issuer: ")) <= 0) {
16290                 #ifdef WOLFSSL_SMALL_STACK
16291                 XFREE(issuer, NULL, DYNAMIC_TYPE_OPENSSL);
16292                 #endif
16293                 return WOLFSSL_FAILURE;
16294             }
16295             if (issuer != NULL) {
16296                 if (wolfSSL_BIO_write(bio, issuer, (int)XSTRLEN(issuer)) <= 0) {
16297                     #ifdef WOLFSSL_SMALL_STACK
16298                     XFREE(issuer, NULL, DYNAMIC_TYPE_OPENSSL);
16299                     #endif
16300                     return WOLFSSL_FAILURE;
16301                 }
16302             }
16303             #ifdef WOLFSSL_SMALL_STACK
16304             XFREE(issuer, NULL, DYNAMIC_TYPE_OPENSSL);
16305             #endif
16306             if (wolfSSL_BIO_write(bio, "\n", sizeof("\n")) <= 0) {
16307                 return WOLFSSL_FAILURE;
16308             }
16309         }
16310 
16311         /* print validity */
16312         {
16313             char tmp[80];
16314 
16315             if (wolfSSL_BIO_write(bio, "        Validity\n",
16316                                 sizeof("        Validity\n")) <= 0) {
16317                 return WOLFSSL_FAILURE;
16318             }
16319             if (wolfSSL_BIO_write(bio, "            Not Before: ",
16320                                 sizeof("            Not Before: ")) <= 0) {
16321                 return WOLFSSL_FAILURE;
16322             }
16323             if (GetTimeString(x509->notBefore + 2, ASN_UTC_TIME,
16324                 tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
16325                 if (GetTimeString(x509->notBefore + 2, ASN_GENERALIZED_TIME,
16326                 tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
16327                     WOLFSSL_MSG("Error getting not before date");
16328                     return WOLFSSL_FAILURE;
16329                 }
16330             }
16331             tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
16332             if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
16333                 return WOLFSSL_FAILURE;
16334             }
16335             if (wolfSSL_BIO_write(bio, "\n            Not After : ",
16336                                 sizeof("\n            Not After : ")) <= 0) {
16337                 return WOLFSSL_FAILURE;
16338             }
16339             if (GetTimeString(x509->notAfter + 2,ASN_UTC_TIME,
16340                 tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
16341                 if (GetTimeString(x509->notAfter + 2,ASN_GENERALIZED_TIME,
16342                     tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
16343                     WOLFSSL_MSG("Error getting not before date");
16344                     return WOLFSSL_FAILURE;
16345                 }
16346             }
16347             tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
16348             if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
16349                 return WOLFSSL_FAILURE;
16350             }
16351         }
16352 
16353         /* print subject */
16354         {
16355             char* subject;
16356         #ifdef WOLFSSL_SMALL_STACK
16357             char* buff  = NULL;
16358             int   subSz = 0;
16359         #else
16360             char buff[256];
16361             int  subSz = 256;
16362         #endif
16363 
16364             subject  = wolfSSL_X509_NAME_oneline(
16365                              wolfSSL_X509_get_subject_name(x509), buff, subSz);
16366 
16367             if (wolfSSL_BIO_write(bio, "\n        Subject: ",
16368                                 sizeof("\n        Subject: ")) <= 0) {
16369                 #ifdef WOLFSSL_SMALL_STACK
16370                 XFREE(subject, NULL, DYNAMIC_TYPE_OPENSSL);
16371                 #endif
16372                 return WOLFSSL_FAILURE;
16373             }
16374             if (subject != NULL) {
16375                 if (wolfSSL_BIO_write(bio, subject, (int)XSTRLEN(subject)) <= 0) {
16376                     #ifdef WOLFSSL_SMALL_STACK
16377                     XFREE(subject, NULL, DYNAMIC_TYPE_OPENSSL);
16378                     #endif
16379                     return WOLFSSL_FAILURE;
16380                 }
16381             }
16382             #ifdef WOLFSSL_SMALL_STACK
16383             XFREE(subject, NULL, DYNAMIC_TYPE_OPENSSL);
16384             #endif
16385         }
16386 
16387         /* get and print public key */
16388         if (wolfSSL_BIO_write(bio, "\n        Subject Public Key Info:\n",
16389                           sizeof("\n        Subject Public Key Info:\n")) <= 0) {
16390             return WOLFSSL_FAILURE;
16391         }
16392         {
16393             char tmp[100];
16394 
16395             switch (x509->pubKeyOID) {
16396                 #ifndef NO_RSA
16397                 case RSAk:
16398                     if (wolfSSL_BIO_write(bio,
16399                                 "            Public Key Algorithm: RSA\n",
16400                       sizeof("            Public Key Algorithm: RSA\n")) <= 0) {
16401                         return WOLFSSL_FAILURE;
16402                     }
16403                 #ifdef HAVE_USER_RSA
16404                     if (wolfSSL_BIO_write(bio,
16405                         "                Build without user RSA to print key\n",
16406                 sizeof("                Build without user RSA to print key\n"))
16407                         <= 0) {
16408                         return WOLFSSL_FAILURE;
16409                     }
16410                 #else
16411                     {
16412                         RsaKey rsa;
16413                         word32 idx = 0;
16414                         int  sz;
16415                         byte lbit = 0;
16416                         int  rawLen;
16417                         unsigned char* rawKey;
16418 
16419                         if (wc_InitRsaKey(&rsa, NULL) != 0) {
16420                             WOLFSSL_MSG("wc_InitRsaKey failure");
16421                             return WOLFSSL_FAILURE;
16422                         }
16423                         if (wc_RsaPublicKeyDecode(x509->pubKey.buffer,
16424                                 &idx, &rsa, x509->pubKey.length) != 0) {
16425                             WOLFSSL_MSG("Error decoding RSA key");
16426                             return WOLFSSL_FAILURE;
16427                         }
16428                         if ((sz = wc_RsaEncryptSize(&rsa)) < 0) {
16429                             WOLFSSL_MSG("Error getting RSA key size");
16430                             return WOLFSSL_FAILURE;
16431                         }
16432                         XSNPRINTF(tmp, sizeof(tmp) - 1, "%s%s: (%d bit)\n%s\n",
16433                                 "                 ", "Public-Key", 8 * sz,
16434                                 "                 Modulus:");
16435                         tmp[sizeof(tmp) - 1] = '\0';
16436                         if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
16437                             return WOLFSSL_FAILURE;
16438                         }
16439 
16440                         /* print out modulus */
16441                         XSNPRINTF(tmp, sizeof(tmp) - 1,"                     ");
16442                         tmp[sizeof(tmp) - 1] = '\0';
16443                         if (mp_leading_bit(&rsa.n)) {
16444                             lbit = 1;
16445                             XSTRNCAT(tmp, "00", sizeof("00"));
16446                         }
16447 
16448                         rawLen = mp_unsigned_bin_size(&rsa.n);
16449                         rawKey = (unsigned char*)XMALLOC(rawLen, NULL,
16450                                 DYNAMIC_TYPE_TMP_BUFFER);
16451                         if (rawKey == NULL) {
16452                             WOLFSSL_MSG("Memory error");
16453                             return WOLFSSL_FAILURE;
16454                         }
16455                         mp_to_unsigned_bin(&rsa.n, rawKey);
16456                         for (idx = 0; idx < (word32)rawLen; idx++) {
16457                             char val[5];
16458                             int valSz = 5;
16459 
16460                             if ((idx == 0) && !lbit) {
16461                                 XSNPRINTF(val, valSz - 1, "%02x", rawKey[idx]);
16462                             }
16463                             else if ((idx != 0) && (((idx + lbit) % 15) == 0)) {
16464                                 tmp[sizeof(tmp) - 1] = '\0';
16465                                 if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp))
16466                                         <= 0) {
16467                                     XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16468                                     return WOLFSSL_FAILURE;
16469                                 }
16470                                 XSNPRINTF(tmp, sizeof(tmp) - 1,
16471                                         ":\n                     ");
16472                                 XSNPRINTF(val, valSz - 1, "%02x", rawKey[idx]);
16473                             }
16474                             else {
16475                                 XSNPRINTF(val, valSz - 1, ":%02x", rawKey[idx]);
16476                             }
16477                             XSTRNCAT(tmp, val, valSz);
16478                         }
16479                         XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16480 
16481                         /* print out remaning modulus values */
16482                         if ((idx > 0) && (((idx - 1 + lbit) % 15) != 0)) {
16483                                 tmp[sizeof(tmp) - 1] = '\0';
16484                                 if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp))
16485                                         <= 0) {
16486                                     return WOLFSSL_FAILURE;
16487                                 }
16488                         }
16489 
16490                         /* print out exponent values */
16491                         rawLen = mp_unsigned_bin_size(&rsa.e);
16492                         if (rawLen < 0) {
16493                             WOLFSSL_MSG("Error getting exponent size");
16494                             return WOLFSSL_FAILURE;
16495                         }
16496 
16497                         if ((word32)rawLen < sizeof(word32)) {
16498                             rawLen = sizeof(word32);
16499                         }
16500                         rawKey = (unsigned char*)XMALLOC(rawLen, NULL,
16501                                 DYNAMIC_TYPE_TMP_BUFFER);
16502                         if (rawKey == NULL) {
16503                             WOLFSSL_MSG("Memory error");
16504                             return WOLFSSL_FAILURE;
16505                         }
16506                         XMEMSET(rawKey, 0, rawLen);
16507                         mp_to_unsigned_bin(&rsa.e, rawKey);
16508                         if ((word32)rawLen <= sizeof(word32)) {
16509                             idx = *(word32*)rawKey;
16510                         }
16511                         XSNPRINTF(tmp, sizeof(tmp) - 1,
16512                         "\n                 Exponent: %d\n", idx);
16513                         if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
16514                             XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16515                             return WOLFSSL_FAILURE;
16516                         }
16517                         XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16518                     }
16519                 #endif /* HAVE_USER_RSA */
16520                     break;
16521                 #endif /* NO_RSA */
16522 
16523                 #ifdef HAVE_ECC
16524                 case ECDSAk:
16525                     {
16526                         word32 i;
16527                         ecc_key ecc;
16528 
16529                         if (wolfSSL_BIO_write(bio,
16530                                 "            Public Key Algorithm: EC\n",
16531                       sizeof("            Public Key Algorithm: EC\n")) <= 0) {
16532                         return WOLFSSL_FAILURE;
16533                         }
16534                         if (wc_ecc_init_ex(&ecc, x509->heap, INVALID_DEVID)
16535                                 != 0) {
16536                             return WOLFSSL_FAILURE;
16537                         }
16538 
16539                         i = 0;
16540                         if (wc_EccPublicKeyDecode(x509->pubKey.buffer, &i,
16541                                               &ecc, x509->pubKey.length) != 0) {
16542                             wc_ecc_free(&ecc);
16543                             return WOLFSSL_FAILURE;
16544                         }
16545                         XSNPRINTF(tmp, sizeof(tmp) - 1, "%s%s: (%d bit)\n%s\n",
16546                                 "                 ", "Public-Key",
16547                                 8 * wc_ecc_size(&ecc),
16548                                 "                 pub:");
16549                         tmp[sizeof(tmp) - 1] = '\0';
16550                         if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
16551                             wc_ecc_free(&ecc);
16552                             return WOLFSSL_FAILURE;
16553                         }
16554                         XSNPRINTF(tmp, sizeof(tmp) - 1,"                     ");
16555                         {
16556                             word32 derSz;
16557                             byte*  der;
16558 
16559                             derSz = wc_ecc_size(&ecc) * WOLFSSL_BIT_SIZE;
16560                             der = (byte*)XMALLOC(derSz, x509->heap,
16561                                     DYNAMIC_TYPE_TMP_BUFFER);
16562                             if (der == NULL) {
16563                                 wc_ecc_free(&ecc);
16564                                 return WOLFSSL_FAILURE;
16565                             }
16566 
16567                             if (wc_ecc_export_x963(&ecc, der, &derSz) != 0) {
16568                                 wc_ecc_free(&ecc);
16569                                 XFREE(der, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
16570                                 return WOLFSSL_FAILURE;
16571                             }
16572                             for (i = 0; i < derSz; i++) {
16573                                 char val[5];
16574                                 int valSz = 5;
16575 
16576                                 if (i == 0) {
16577                                     XSNPRINTF(val, valSz - 1, "%02x", der[i]);
16578                                 }
16579                                 else if ((i % 15) == 0) {
16580                                     tmp[sizeof(tmp) - 1] = '\0';
16581                                     if (wolfSSL_BIO_write(bio, tmp,
16582                                                 (int)XSTRLEN(tmp)) <= 0) {
16583                                         wc_ecc_free(&ecc);
16584                                         XFREE(der, x509->heap,
16585                                                 DYNAMIC_TYPE_TMP_BUFFER);
16586                                         return WOLFSSL_FAILURE;
16587                                     }
16588                                     XSNPRINTF(tmp, sizeof(tmp) - 1,
16589                                         ":\n                     ");
16590                                     XSNPRINTF(val, valSz - 1, "%02x", der[i]);
16591                                 }
16592                                 else {
16593                                     XSNPRINTF(val, valSz - 1, ":%02x", der[i]);
16594                                 }
16595                                 XSTRNCAT(tmp, val, valSz);
16596                             }
16597 
16598                             /* print out remaning modulus values */
16599                             if ((i > 0) && (((i - 1) % 15) != 0)) {
16600                                 tmp[sizeof(tmp) - 1] = '\0';
16601                                 if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp))
16602                                         <= 0) {
16603                                     wc_ecc_free(&ecc);
16604                                     XFREE(der, x509->heap,
16605                                                 DYNAMIC_TYPE_TMP_BUFFER);
16606                                     return WOLFSSL_FAILURE;
16607                                 }
16608                             }
16609 
16610                             XFREE(der, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
16611                         }
16612                         XSNPRINTF(tmp, sizeof(tmp) - 1, "\n%s%s: %s\n",
16613                                 "                ", "ASN1 OID",
16614                                 ecc.dp->name);
16615                         if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
16616                             wc_ecc_free(&ecc);
16617                             return WOLFSSL_FAILURE;
16618                         }
16619                         wc_ecc_free(&ecc);
16620                     }
16621                     break;
16622                 #endif /* HAVE_ECC */
16623                 default:
16624                     WOLFSSL_MSG("Unknown key type");
16625                     return WOLFSSL_FAILURE;
16626             }
16627         }
16628 
16629         /* print out extensions */
16630         if (wolfSSL_BIO_write(bio, "        X509v3 extensions:\n",
16631                             sizeof("        X509v3 extensions:\n")) <= 0) {
16632             return WOLFSSL_FAILURE;
16633         }
16634 
16635         /* print subject key id */
16636         if (x509->subjKeyIdSet && x509->subjKeyId != NULL &&
16637                 x509->subjKeyIdSz > 0) {
16638             char tmp[100];
16639             word32 i;
16640             char val[5];
16641             int valSz = 5;
16642 
16643 
16644             if (wolfSSL_BIO_write(bio,
16645                         "            X509v3 Subject Key Identifier:\n",
16646                  sizeof("            X509v3 Subject Key Identifier:\n"))
16647                  <= 0) {
16648                 return WOLFSSL_FAILURE;
16649             }
16650 
16651             XSNPRINTF(tmp, sizeof(tmp) - 1, "                 ");
16652             for (i = 0; i < sizeof(tmp) && i < (x509->subjKeyIdSz - 1); i++) {
16653                 XSNPRINTF(val, valSz - 1, "%02X:", x509->subjKeyId[i]);
16654                 XSTRNCAT(tmp, val, valSz);
16655             }
16656             XSNPRINTF(val, valSz - 1, "%02X\n", x509->subjKeyId[i]);
16657             XSTRNCAT(tmp, val, valSz);
16658             if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
16659                 return WOLFSSL_FAILURE;
16660             }
16661         }
16662 
16663         /* printf out authority key id */
16664         if (x509->authKeyIdSet && x509->authKeyId != NULL &&
16665                 x509->authKeyIdSz > 0) {
16666             char tmp[100];
16667             word32 i;
16668             char val[5];
16669             int valSz = 5;
16670 
16671             if (wolfSSL_BIO_write(bio,
16672                         "            X509v3 Authority Key Identifier:\n",
16673                  sizeof("            X509v3 Authority Key Identifier:\n"))
16674                  <= 0) {
16675                 return WOLFSSL_FAILURE;
16676             }
16677 
16678             XSNPRINTF(tmp, sizeof(tmp) - 1, "                 keyid");
16679             for (i = 0; i < x509->authKeyIdSz; i++) {
16680                 /* check if buffer is almost full */
16681                 if (XSTRLEN(tmp) >= sizeof(tmp) - valSz) {
16682                     if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
16683                         return WOLFSSL_FAILURE;
16684                     }
16685                     tmp[0] = '\0';
16686                 }
16687                 XSNPRINTF(val, valSz - 1, ":%02X", x509->authKeyId[i]);
16688                 XSTRNCAT(tmp, val, valSz);
16689             }
16690             if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
16691                 return WOLFSSL_FAILURE;
16692             }
16693 
16694             /* print issuer */
16695             {
16696                 char* issuer;
16697             #ifdef WOLFSSL_SMALL_STACK
16698                 char* buff  = NULL;
16699                 int   issSz = 0;
16700             #else
16701                 char buff[256];
16702                 int  issSz = 256;
16703             #endif
16704 
16705                 issuer  = wolfSSL_X509_NAME_oneline(
16706                                wolfSSL_X509_get_issuer_name(x509), buff, issSz);
16707 
16708                 if (wolfSSL_BIO_write(bio, "\n                 DirName:",
16709                                   sizeof("\n                 DirName:")) <= 0) {
16710                     #ifdef WOLFSSL_SMALL_STACK
16711                     XFREE(issuer, NULL, DYNAMIC_TYPE_OPENSSL);
16712                     #endif
16713                     return WOLFSSL_FAILURE;
16714                 }
16715                 if (issuer != NULL) {
16716                     if (wolfSSL_BIO_write(bio, issuer, (int)XSTRLEN(issuer)) <= 0) {
16717                         #ifdef WOLFSSL_SMALL_STACK
16718                         XFREE(issuer, NULL, DYNAMIC_TYPE_OPENSSL);
16719                         #endif
16720                         return WOLFSSL_FAILURE;
16721                     }
16722                 }
16723                 #ifdef WOLFSSL_SMALL_STACK
16724                 XFREE(issuer, NULL, DYNAMIC_TYPE_OPENSSL);
16725                 #endif
16726                 if (wolfSSL_BIO_write(bio, "\n", sizeof("\n")) <= 0) {
16727                     return WOLFSSL_FAILURE;
16728                 }
16729             }
16730         }
16731 
16732         /* print basic constraint */
16733         if (x509->basicConstSet) {
16734             char tmp[100];
16735 
16736             if (wolfSSL_BIO_write(bio,
16737                         "\n            X509v3 Basic Constraints:\n",
16738                  sizeof("\n            X509v3 Basic Constraints:\n"))
16739                  <= 0) {
16740                 return WOLFSSL_FAILURE;
16741             }
16742             XSNPRINTF(tmp, sizeof(tmp),
16743                     "                    CA:%s\n",
16744                     (x509->isCa)? "TRUE": "FALSE");
16745             if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
16746                 return WOLFSSL_FAILURE;
16747             }
16748         }
16749 
16750         /* print out signature */
16751         {
16752             unsigned char* sig;
16753             int sigSz;
16754             int i;
16755             char tmp[100];
16756             int sigOid = wolfSSL_X509_get_signature_type(x509);
16757 
16758             if (wolfSSL_BIO_write(bio,
16759                                 "    Signature Algorithm: ",
16760                       sizeof("    Signature Algorithm: ")) <= 0) {
16761                 return WOLFSSL_FAILURE;
16762             }
16763             XSNPRINTF(tmp, sizeof(tmp) - 1,"%s\n", GetSigName(sigOid));
16764             tmp[sizeof(tmp) - 1] = '\0';
16765             if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
16766                 return WOLFSSL_FAILURE;
16767             }
16768 
16769             sigSz = (int)x509->sig.length;
16770             sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16771             if (sig == NULL || sigSz <= 0) {
16772                 return WOLFSSL_FAILURE;
16773             }
16774             if (wolfSSL_X509_get_signature(x509, sig, &sigSz) <= 0) {
16775                 XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16776                 return WOLFSSL_FAILURE;
16777             }
16778             XSNPRINTF(tmp, sizeof(tmp) - 1,"         ");
16779             tmp[sizeof(tmp) - 1] = '\0';
16780             for (i = 0; i < sigSz; i++) {
16781                 char val[5];
16782                 int valSz = 5;
16783 
16784                 if (i == 0) {
16785                     XSNPRINTF(val, valSz - 1, "%02x", sig[i]);
16786                 }
16787                 else if (((i % 18) == 0)) {
16788                     tmp[sizeof(tmp) - 1] = '\0';
16789                     if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp))
16790                             <= 0) {
16791                         XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16792                         return WOLFSSL_FAILURE;
16793                     }
16794                     XSNPRINTF(tmp, sizeof(tmp) - 1,
16795                             ":\n         ");
16796                     XSNPRINTF(val, valSz - 1, "%02x", sig[i]);
16797                 }
16798                 else {
16799                     XSNPRINTF(val, valSz - 1, ":%02x", sig[i]);
16800                 }
16801                 XSTRNCAT(tmp, val, valSz);
16802             }
16803             XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16804 
16805             /* print out remaning sig values */
16806             if ((i > 0) && (((i - 1) % 18) != 0)) {
16807                     tmp[sizeof(tmp) - 1] = '\0';
16808                     if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp))
16809                             <= 0) {
16810                         return WOLFSSL_FAILURE;
16811                     }
16812             }
16813         }
16814 
16815         /* done with print out */
16816         if (wolfSSL_BIO_write(bio, "\n", sizeof("\n")) <= 0) {
16817             return WOLFSSL_FAILURE;
16818         }
16819 
16820         return WOLFSSL_SUCCESS;
16821     }
16822 #endif /* XSNPRINTF */
16823 
16824 #endif /* NO_CERTS */
16825 
16826 char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in,
16827                                  int len)
16828 {
16829     char *ret = in;
16830     const char *keaStr, *authStr, *encStr, *macStr;
16831     size_t strLen;
16832 
16833     if (cipher == NULL || in == NULL)
16834         return NULL;
16835 
16836     switch (cipher->ssl->specs.kea) {
16837         case no_kea:
16838             keaStr = "None";
16839             break;
16840 #ifndef NO_RSA
16841         case rsa_kea:
16842             keaStr = "RSA";
16843             break;
16844 #endif
16845 #ifndef NO_DH
16846         case diffie_hellman_kea:
16847             keaStr = "DHE";
16848             break;
16849 #endif
16850         case fortezza_kea:
16851             keaStr = "FZ";
16852             break;
16853 #ifndef NO_PSK
16854         case psk_kea:
16855             keaStr = "PSK";
16856             break;
16857     #ifndef NO_DH
16858         case dhe_psk_kea:
16859             keaStr = "DHEPSK";
16860             break;
16861     #endif
16862     #ifdef HAVE_ECC
16863         case ecdhe_psk_kea:
16864             keaStr = "ECDHEPSK";
16865             break;
16866     #endif
16867 #endif
16868 #ifdef HAVE_NTRU
16869         case ntru_kea:
16870             keaStr = "NTRU";
16871             break;
16872 #endif
16873 #ifdef HAVE_ECC
16874         case ecc_diffie_hellman_kea:
16875             keaStr = "ECDHE";
16876             break;
16877         case ecc_static_diffie_hellman_kea:
16878             keaStr = "ECDH";
16879             break;
16880 #endif
16881         default:
16882             keaStr = "unknown";
16883             break;
16884     }
16885 
16886     switch (cipher->ssl->specs.sig_algo) {
16887         case anonymous_sa_algo:
16888             authStr = "None";
16889             break;
16890 #ifndef NO_RSA
16891         case rsa_sa_algo:
16892             authStr = "RSA";
16893             break;
16894 #endif
16895 #ifndef NO_DSA
16896         case dsa_sa_algo:
16897             authStr = "DSA";
16898             break;
16899 #endif
16900 #ifdef HAVE_ECC
16901         case ecc_dsa_sa_algo:
16902             authStr = "ECDSA";
16903             break;
16904 #endif
16905         default:
16906             authStr = "unknown";
16907             break;
16908     }
16909 
16910     switch (cipher->ssl->specs.bulk_cipher_algorithm) {
16911         case wolfssl_cipher_null:
16912             encStr = "None";
16913             break;
16914 #ifndef NO_RC4
16915         case wolfssl_rc4:
16916             encStr = "RC4(128)";
16917             break;
16918 #endif
16919 #ifndef NO_DES3
16920         case wolfssl_triple_des:
16921             encStr = "3DES(168)";
16922             break;
16923 #endif
16924 #ifdef HAVE_IDEA
16925         case wolfssl_idea:
16926             encStr = "IDEA(128)";
16927             break;
16928 #endif
16929 #ifndef NO_AES
16930         case wolfssl_aes:
16931             if (cipher->ssl->specs.key_size == 128)
16932                 encStr = "AES(128)";
16933             else if (cipher->ssl->specs.key_size == 256)
16934                 encStr = "AES(256)";
16935             else
16936                 encStr = "AES(?)";
16937             break;
16938     #ifdef HAVE_AESGCM
16939         case wolfssl_aes_gcm:
16940             if (cipher->ssl->specs.key_size == 128)
16941                 encStr = "AESGCM(128)";
16942             else if (cipher->ssl->specs.key_size == 256)
16943                 encStr = "AESGCM(256)";
16944             else
16945                 encStr = "AESGCM(?)";
16946             break;
16947     #endif
16948     #ifdef HAVE_AESCCM
16949         case wolfssl_aes_ccm:
16950             if (cipher->ssl->specs.key_size == 128)
16951                 encStr = "AESCCM(128)";
16952             else if (cipher->ssl->specs.key_size == 256)
16953                 encStr = "AESCCM(256)";
16954             else
16955                 encStr = "AESCCM(?)";
16956             break;
16957     #endif
16958 #endif
16959 #ifdef HAVE_CHACHA
16960         case wolfssl_chacha:
16961             encStr = "CHACHA20/POLY1305(256)";
16962             break;
16963 #endif
16964 #ifdef HAVE_CAMELLIA
16965         case wolfssl_camellia:
16966             if (cipher->ssl->specs.key_size == 128)
16967                 encStr = "Camellia(128)";
16968             else if (cipher->ssl->specs.key_size == 256)
16969                 encStr = "Camellia(256)";
16970             else
16971                 encStr = "Camellia(?)";
16972             break;
16973 #endif
16974 #if defined(HAVE_HC128) && !defined(NO_HC128)
16975         case wolfssl_hc128:
16976             encStr = "HC128(128)";
16977             break;
16978 #endif
16979 #if defined(HAVE_RABBIT) && !defined(NO_RABBIT)
16980         case wolfssl_rabbit:
16981             encStr = "RABBIT(128)";
16982             break;
16983 #endif
16984         default:
16985             encStr = "unknown";
16986             break;
16987     }
16988 
16989     switch (cipher->ssl->specs.mac_algorithm) {
16990         case no_mac:
16991             macStr = "None";
16992             break;
16993 #ifndef NO_MD5
16994         case md5_mac:
16995             macStr = "MD5";
16996             break;
16997 #endif
16998 #ifndef NO_SHA
16999         case sha_mac:
17000             macStr = "SHA1";
17001             break;
17002 #endif
17003 #ifdef HAVE_SHA224
17004         case sha224_mac:
17005             macStr = "SHA224";
17006             break;
17007 #endif
17008 #ifndef NO_SHA256
17009         case sha256_mac:
17010             macStr = "SHA256";
17011             break;
17012 #endif
17013 #ifdef HAVE_SHA384
17014         case sha384_mac:
17015             macStr = "SHA384";
17016             break;
17017 #endif
17018 #ifdef HAVE_SHA512
17019         case sha512_mac:
17020             macStr = "SHA512";
17021             break;
17022 #endif
17023 #ifdef HAVE_BLAKE2
17024         case blake2b_mac:
17025             macStr = "BLAKE2b";
17026             break;
17027 #endif
17028         default:
17029             macStr = "unknown";
17030             break;
17031     }
17032 
17033     /* Build up the string by copying onto the end. */
17034     XSTRNCPY(in, wolfSSL_CIPHER_get_name(cipher), len);
17035     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
17036 
17037     XSTRNCPY(in, " ", len);
17038     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
17039     XSTRNCPY(in, wolfSSL_get_version(cipher->ssl), len);
17040     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
17041 
17042     XSTRNCPY(in, " Kx=", len);
17043     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
17044     XSTRNCPY(in, keaStr, len);
17045     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
17046 
17047     XSTRNCPY(in, " Au=", len);
17048     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
17049     XSTRNCPY(in, authStr, len);
17050     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
17051 
17052     XSTRNCPY(in, " Enc=", len);
17053     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
17054     XSTRNCPY(in, encStr, len);
17055     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
17056 
17057     XSTRNCPY(in, " Mac=", len);
17058     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
17059     XSTRNCPY(in, macStr, len);
17060     in[len-1] = '\0';
17061 
17062     return ret;
17063 }
17064 
17065 
17066 #ifndef NO_SESSION_CACHE
17067 
17068 WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl)
17069 {
17070     if (ssl == NULL) {
17071         return NULL;
17072     }
17073 
17074     /* sessions are stored statically, no need for reference count */
17075     return wolfSSL_get_session(ssl);
17076 }
17077 
17078 #endif /* NO_SESSION_CACHE */
17079 
17080 
17081 
17082 /* was do nothing */
17083 /*
17084 void OPENSSL_free(void* buf)
17085 {
17086     (void)buf;
17087 }
17088 */
17089 
17090 #ifndef NO_WOLFSSL_STUB
17091 int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, char** path,
17092                    int* ssl)
17093 {
17094     (void)url;
17095     (void)host;
17096     (void)port;
17097     (void)path;
17098     (void)ssl;
17099     WOLFSSL_STUB("OCSP_parse_url");
17100     return 0;
17101 }
17102 #endif
17103 
17104 WOLFSSL_METHOD* wolfSSLv2_client_method(void)
17105 {
17106     return 0;
17107 }
17108 
17109 
17110 WOLFSSL_METHOD* wolfSSLv2_server_method(void)
17111 {
17112     return 0;
17113 }
17114 
17115 
17116 #ifndef NO_MD4
17117 
17118 void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX* md4)
17119 {
17120     /* make sure we have a big enough buffer */
17121     typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1];
17122     (void) sizeof(ok);
17123 
17124     WOLFSSL_ENTER("MD4_Init");
17125     wc_InitMd4((Md4*)md4);
17126 }
17127 
17128 
17129 void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX* md4, const void* data,
17130                        unsigned long len)
17131 {
17132     WOLFSSL_ENTER("MD4_Update");
17133     wc_Md4Update((Md4*)md4, (const byte*)data, (word32)len);
17134 }
17135 
17136 
17137 void wolfSSL_MD4_Final(unsigned char* digest, WOLFSSL_MD4_CTX* md4)
17138 {
17139     WOLFSSL_ENTER("MD4_Final");
17140     wc_Md4Final((Md4*)md4, digest);
17141 }
17142 
17143 #endif /* NO_MD4 */
17144 
17145 
17146 /* Removes a WOLFSSL_BIO struct from the WOLFSSL_BIO linked list.
17147  *
17148  * bio is the WOLFSSL_BIO struct in the list and removed.
17149  *
17150  * The return WOLFSSL_BIO struct is the next WOLFSSL_BIO in the list or NULL if
17151  * there is none.
17152  */
17153 WOLFSSL_BIO* wolfSSL_BIO_pop(WOLFSSL_BIO* bio)
17154 {
17155     if (bio == NULL) {
17156         WOLFSSL_MSG("Bad argument passed in");
17157         return NULL;
17158     }
17159 
17160     if (bio->prev != NULL) {
17161         bio->prev->next = bio->next;
17162     }
17163 
17164     if (bio->next != NULL) {
17165         bio->next->prev = bio->prev;
17166     }
17167 
17168     return bio->next;
17169 }
17170 
17171 
17172 int wolfSSL_BIO_pending(WOLFSSL_BIO* bio)
17173 {
17174     return (int)wolfSSL_BIO_ctrl_pending(bio);
17175 }
17176 
17177 
17178 
17179 WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_mem(void)
17180 {
17181     static WOLFSSL_BIO_METHOD meth;
17182 
17183     WOLFSSL_ENTER("BIO_s_mem");
17184     meth.type = WOLFSSL_BIO_MEMORY;
17185 
17186     return &meth;
17187 }
17188 
17189 
17190 WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_base64(void)
17191 {
17192     static WOLFSSL_BIO_METHOD meth;
17193 
17194     WOLFSSL_ENTER("wolfSSL_BIO_f_base64");
17195     meth.type = WOLFSSL_BIO_BASE64;
17196 
17197     return &meth;
17198 }
17199 
17200 
17201 /* Set the flag for the bio.
17202  *
17203  * bio   the structre to set the flag in
17204  * flags the flag to use
17205  */
17206 void wolfSSL_BIO_set_flags(WOLFSSL_BIO* bio, int flags)
17207 {
17208     WOLFSSL_ENTER("wolfSSL_BIO_set_flags");
17209 
17210     if (bio != NULL) {
17211         bio->flags |= flags;
17212     }
17213 }
17214 
17215 
17216 #ifndef NO_WOLFSSL_STUB
17217 void wolfSSL_RAND_screen(void)
17218 {
17219     WOLFSSL_STUB("RAND_screen");
17220 }
17221 #endif
17222 
17223 
17224 
17225 int wolfSSL_RAND_load_file(const char* fname, long len)
17226 {
17227     (void)fname;
17228     /* wolfCrypt provides enough entropy internally or will report error */
17229     if (len == -1)
17230         return 1024;
17231     else
17232         return (int)len;
17233 }
17234 
17235 
17236 #ifndef NO_WOLFSSL_STUB
17237 WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void)
17238 {
17239     WOLFSSL_STUB("COMP_zlib");
17240     return 0;
17241 }
17242 #endif
17243 
17244 #ifndef NO_WOLFSSL_STUB
17245 WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void)
17246 {
17247     WOLFSSL_STUB("COMP_rle");
17248     return 0;
17249 }
17250 #endif
17251 
17252 #ifndef NO_WOLFSSL_STUB
17253 int wolfSSL_COMP_add_compression_method(int method, void* data)
17254 {
17255     (void)method;
17256     (void)data;
17257     WOLFSSL_STUB("COMP_add_compression_method");
17258     return 0;
17259 }
17260 #endif
17261 
17262 #ifndef NO_WOLFSSL_STUB
17263 void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f)(
17264                                                           const char*, int))
17265 {
17266     WOLFSSL_STUB("CRYPTO_set_dynlock_create_callback");
17267     (void)f;
17268 }
17269 #endif
17270 
17271 #ifndef NO_WOLFSSL_STUB
17272 void wolfSSL_set_dynlock_lock_callback(
17273              void (*f)(int, WOLFSSL_dynlock_value*, const char*, int))
17274 {
17275     WOLFSSL_STUB("CRYPTO_set_set_dynlock_lock_callback");
17276     (void)f;
17277 }
17278 #endif
17279 
17280 #ifndef NO_WOLFSSL_STUB
17281 void wolfSSL_set_dynlock_destroy_callback(
17282                   void (*f)(WOLFSSL_dynlock_value*, const char*, int))
17283 {
17284     WOLFSSL_STUB("CRYPTO_set_set_dynlock_destroy_callback");
17285     (void)f;
17286 }
17287 #endif
17288 
17289 
17290 const char* wolfSSL_X509_verify_cert_error_string(long err)
17291 {
17292     return wolfSSL_ERR_reason_error_string(err);
17293 }
17294 
17295 
17296 #ifndef NO_WOLFSSL_STUB
17297 int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup, const char* dir,
17298                                long len)
17299 {
17300     (void)lookup;
17301     (void)dir;
17302     (void)len;
17303     WOLFSSL_STUB("X509_LOOKUP_add_dir");
17304     return 0;
17305 }
17306 #endif
17307 
17308 int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
17309                                  const char* file, long type)
17310 {
17311 #if !defined(NO_FILESYSTEM) && \
17312     (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM))
17313     int           ret = WOLFSSL_FAILURE;
17314     XFILE         fp;
17315     long          sz;
17316     byte*         pem = NULL;
17317     byte*         curr = NULL;
17318     byte*         prev = NULL;
17319     WOLFSSL_X509* x509;
17320     const char* header = NULL;
17321     const char* footer = NULL;
17322 
17323     if (type != X509_FILETYPE_PEM)
17324         return BAD_FUNC_ARG;
17325 
17326     fp = XFOPEN(file, "r");
17327     if (fp == NULL)
17328         return BAD_FUNC_ARG;
17329 
17330     XFSEEK(fp, 0, XSEEK_END);
17331     sz = XFTELL(fp);
17332     XREWIND(fp);
17333 
17334     if (sz <= 0)
17335         goto end;
17336 
17337     pem = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_PEM);
17338     if (pem == NULL) {
17339         ret = MEMORY_ERROR;
17340         goto end;
17341     }
17342 
17343     /* Read in file which may be CRLs or certificates. */
17344     if (XFREAD(pem, (size_t)sz, 1, fp) != 1)
17345         goto end;
17346 
17347     prev = curr = pem;
17348     do {
17349         /* get PEM header and footer based on type */
17350         if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
17351                 XSTRNSTR((char*)curr, header, (unsigned int)sz) != NULL) {
17352 #ifdef HAVE_CRL
17353             WOLFSSL_CERT_MANAGER* cm = lookup->store->cm;
17354 
17355             if (cm->crl == NULL) {
17356                 if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
17357                     WOLFSSL_MSG("Enable CRL failed");
17358                     goto end;
17359                 }
17360             }
17361 
17362             ret = BufferLoadCRL(cm->crl, curr, sz, WOLFSSL_FILETYPE_PEM, 1);
17363             if (ret != WOLFSSL_SUCCESS)
17364                 goto end;
17365 #endif
17366             curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz);
17367         }
17368         else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 &&
17369                 XSTRNSTR((char*)curr, header, (unsigned int)sz) != NULL) {
17370             x509 = wolfSSL_X509_load_certificate_buffer(curr, (int)sz,
17371                                                         WOLFSSL_FILETYPE_PEM);
17372             if (x509 == NULL)
17373                  goto end;
17374             ret = wolfSSL_X509_STORE_add_cert(lookup->store, x509);
17375             wolfSSL_X509_free(x509);
17376             if (ret != WOLFSSL_SUCCESS)
17377                 goto end;
17378             curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz);
17379         }
17380         else
17381             goto end;
17382 
17383         if (curr == NULL)
17384             goto end;
17385 
17386         curr++;
17387         sz -= (long)(curr - prev);
17388         prev = curr;
17389     }
17390     while (ret == WOLFSSL_SUCCESS);
17391 
17392 end:
17393     if (pem != NULL)
17394         XFREE(pem, 0, DYNAMIC_TYPE_PEM);
17395     XFCLOSE(fp);
17396     return ret;
17397 #else
17398     (void)lookup;
17399     (void)file;
17400     (void)type;
17401     return WOLFSSL_FAILURE;
17402 #endif
17403 }
17404 
17405 WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void)
17406 {
17407     /* Method implementation in functions. */
17408     static WOLFSSL_X509_LOOKUP_METHOD meth = { 1 };
17409     return &meth;
17410 }
17411 
17412 WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void)
17413 {
17414     /* Method implementation in functions. */
17415     static WOLFSSL_X509_LOOKUP_METHOD meth = { 0 };
17416     return &meth;
17417 }
17418 
17419 
17420 WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
17421                                                WOLFSSL_X509_LOOKUP_METHOD* m)
17422 {
17423     /* Method is a dummy value and is not needed. */
17424     (void)m;
17425     /* Make sure the lookup has a back reference to the store. */
17426     store->lookup.store = store;
17427     return &store->lookup;
17428 }
17429 
17430 
17431 #ifndef NO_CERTS
17432 /* Converts the X509 to DER format and outputs it into bio.
17433  *
17434  * bio  is the structure to hold output DER
17435  * x509 certificate to create DER from
17436  *
17437  * returns WOLFSSL_SUCCESS on success
17438  */
17439 int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
17440 {
17441     WOLFSSL_ENTER("wolfSSL_i2d_X509_bio");
17442 
17443     if (bio == NULL || x509 == NULL) {
17444         return WOLFSSL_FAILURE;
17445     }
17446 
17447     if (x509->derCert != NULL) {
17448         word32 len = x509->derCert->length;
17449         byte*  der = x509->derCert->buffer;
17450 
17451         if (wolfSSL_BIO_write(bio, der, len) == (int)len) {
17452             return SSL_SUCCESS;
17453         }
17454     }
17455 
17456     return WOLFSSL_FAILURE;
17457 }
17458 
17459 
17460 /* Converts an internal structure to a DER buffer
17461  *
17462  * x509 structure to get DER buffer from
17463  * out  buffer to hold result. If NULL then *out is NULL then a new buffer is
17464  *      created.
17465  *
17466  * returns the size of the DER result on success
17467  */
17468 int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out)
17469 {
17470     const unsigned char* der;
17471     int derSz = 0;
17472 
17473     if (x509 == NULL || out == NULL) {
17474         return BAD_FUNC_ARG;
17475     }
17476 
17477     der = wolfSSL_X509_get_der(x509, &derSz);
17478     if (der == NULL) {
17479         return MEMORY_E;
17480     }
17481 
17482     if (*out == NULL) {
17483         *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
17484         if (*out == NULL) {
17485             return MEMORY_E;
17486         }
17487     }
17488 
17489     XMEMCPY(*out, der, derSz);
17490 
17491     return derSz;
17492 }
17493 
17494 
17495 /* Converts the DER from bio and creates a WOLFSSL_X509 structure from it.
17496  *
17497  * bio  is the structure holding DER
17498  * x509 certificate to create from DER. Can be NULL
17499  *
17500  * returns pointer to WOLFSSL_X509 structure on success and NULL on fail
17501  */
17502 WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
17503 {
17504     WOLFSSL_X509* localX509 = NULL;
17505     unsigned char* mem  = NULL;
17506     int    ret;
17507     word32 size;
17508 
17509     WOLFSSL_ENTER("wolfSSL_d2i_X509_bio");
17510 
17511     if (bio == NULL) {
17512         WOLFSSL_MSG("Bad Function Argument bio is NULL");
17513         return NULL;
17514     }
17515 
17516     ret = wolfSSL_BIO_get_mem_data(bio, &mem);
17517     if (mem == NULL || ret <= 0) {
17518         WOLFSSL_MSG("Failed to get data from bio struct");
17519         return NULL;
17520     }
17521     size = ret;
17522 
17523     localX509 = wolfSSL_X509_d2i(NULL, mem, size);
17524     if (localX509 == NULL) {
17525         return NULL;
17526     }
17527 
17528     if (x509 != NULL) {
17529         *x509 = localX509;
17530     }
17531 
17532     return localX509;
17533 }
17534 
17535 
17536 #if !defined(NO_ASN) && !defined(NO_PWDBASED)
17537 WC_PKCS12* wolfSSL_d2i_PKCS12_bio(WOLFSSL_BIO* bio, WC_PKCS12** pkcs12)
17538 {
17539     WC_PKCS12* localPkcs12    = NULL;
17540     unsigned char* mem  = NULL;
17541     int ret;
17542     word32 size;
17543 
17544     WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_bio");
17545 
17546     if (bio == NULL) {
17547         WOLFSSL_MSG("Bad Function Argument bio is NULL");
17548         return NULL;
17549     }
17550 
17551     localPkcs12 = wc_PKCS12_new();
17552     if (localPkcs12 == NULL) {
17553         WOLFSSL_MSG("Memory error");
17554         return NULL;
17555     }
17556 
17557     if (pkcs12 != NULL) {
17558         *pkcs12 = localPkcs12;
17559     }
17560 
17561     ret = wolfSSL_BIO_get_mem_data(bio, &mem);
17562     if (mem == NULL || ret <= 0) {
17563         WOLFSSL_MSG("Failed to get data from bio struct");
17564         wc_PKCS12_free(localPkcs12);
17565         if (pkcs12 != NULL) {
17566             *pkcs12 = NULL;
17567         }
17568         return NULL;
17569     }
17570     size = ret;
17571 
17572     ret = wc_d2i_PKCS12(mem, size, localPkcs12);
17573     if (ret < 0) {
17574         WOLFSSL_MSG("Failed to get PKCS12 sequence");
17575         wc_PKCS12_free(localPkcs12);
17576         if (pkcs12 != NULL) {
17577             *pkcs12 = NULL;
17578         }
17579         return NULL;
17580     }
17581 
17582     return localPkcs12;
17583 }
17584 
17585 
17586 /* helper function to get DER buffer from WOLFSSL_EVP_PKEY */
17587 static int wolfSSL_i2d_PrivateKey(WOLFSSL_EVP_PKEY* key, unsigned char** der)
17588 {
17589     *der = (unsigned char*)key->pkey.ptr;
17590 
17591     return key->pkey_sz;
17592 }
17593 
17594 
17595 
17596 /* Creates a new WC_PKCS12 structure
17597  *
17598  * pass  password to use
17599  * name  friendlyName to use
17600  * pkey  private key to go into PKCS12 bundle
17601  * cert  certificate to go into PKCS12 bundle
17602  * ca    extra certificates that can be added to bundle. Can be NULL
17603  * keyNID  type of encryption to use on the key (-1 means no encryption)
17604  * certNID type of ecnryption to use on the certificate
17605  * itt     number of iterations with encryption
17606  * macItt  number of iterations with mac creation
17607  * keyType flag for signature and/or encryption key
17608  *
17609  * returns a pointer to a new WC_PKCS12 structure on success and NULL on fail
17610  */
17611 WC_PKCS12* wolfSSL_PKCS12_create(char* pass, char* name,
17612         WOLFSSL_EVP_PKEY* pkey, WOLFSSL_X509* cert,
17613         WOLF_STACK_OF(WOLFSSL_X509)* ca,
17614         int keyNID, int certNID, int itt, int macItt, int keyType)
17615 {
17616     WC_PKCS12*      pkcs12;
17617     WC_DerCertList* list = NULL;
17618     word32 passSz;
17619     byte* keyDer;
17620     word32 keyDerSz;
17621     byte* certDer;
17622     int certDerSz;
17623 
17624     int ret;
17625 
17626     WOLFSSL_ENTER("wolfSSL_PKCS12_create()");
17627 
17628     if (pass == NULL || pkey == NULL || cert == NULL) {
17629         WOLFSSL_LEAVE("wolfSSL_PKCS12_create()", BAD_FUNC_ARG);
17630         return NULL;
17631     }
17632     passSz = (word32)XSTRLEN(pass);
17633 
17634     if ((ret = wolfSSL_i2d_PrivateKey(pkey, &keyDer)) < 0) {
17635         WOLFSSL_LEAVE("wolfSSL_PKCS12_create", ret);
17636         return NULL;
17637     }
17638     keyDerSz = ret;
17639 
17640     certDer = (byte*)wolfSSL_X509_get_der(cert, &certDerSz);
17641     if (certDer == NULL) {
17642         return NULL;
17643     }
17644 
17645     if (ca != NULL) {
17646         WC_DerCertList* cur;
17647         unsigned long numCerts = ca->num;
17648         byte* curDer;
17649         int   curDerSz = 0;
17650         WOLFSSL_STACK* sk = ca;
17651 
17652         while (numCerts > 0 && sk != NULL) {
17653             cur = (WC_DerCertList*)XMALLOC(sizeof(WC_DerCertList), NULL,
17654                     DYNAMIC_TYPE_PKCS);
17655             if (cur == NULL) {
17656                 wc_FreeCertList(list, NULL);
17657                 return NULL;
17658             }
17659 
17660             curDer = (byte*)wolfSSL_X509_get_der(sk->data.x509, &curDerSz);
17661             if (curDer == NULL || curDerSz < 0) {
17662                 XFREE(cur, NULL, DYNAMIC_TYPE_PKCS);
17663                 wc_FreeCertList(list, NULL);
17664                 return NULL;
17665             }
17666 
17667             cur->buffer = (byte*)XMALLOC(curDerSz, NULL, DYNAMIC_TYPE_PKCS);
17668             if (cur->buffer == NULL) {
17669                 XFREE(cur, NULL, DYNAMIC_TYPE_PKCS);
17670                 wc_FreeCertList(list, NULL);
17671                 return NULL;
17672             }
17673             XMEMCPY(cur->buffer, curDer, curDerSz);
17674             cur->bufferSz = curDerSz;
17675             cur->next = list;
17676             list = cur;
17677 
17678             sk = sk->next;
17679             numCerts--;
17680         }
17681     }
17682 
17683     pkcs12 = wc_PKCS12_create(pass, passSz, name, keyDer, keyDerSz,
17684             certDer, certDerSz, list, keyNID, certNID, itt, macItt,
17685             keyType, NULL);
17686 
17687     if (ca != NULL) {
17688         wc_FreeCertList(list, NULL);
17689     }
17690 
17691     return pkcs12;
17692 }
17693 
17694 
17695 /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure */
17696 int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
17697       WOLFSSL_EVP_PKEY** pkey, WOLFSSL_X509** cert, WOLF_STACK_OF(WOLFSSL_X509)** ca)
17698 {
17699     DecodedCert DeCert;
17700     void* heap = NULL;
17701     int ret;
17702     byte* certData = NULL;
17703     word32 certDataSz;
17704     byte* pk = NULL;
17705     word32 pkSz;
17706     WC_DerCertList* certList = NULL;
17707 
17708     WOLFSSL_ENTER("wolfSSL_PKCS12_parse");
17709 
17710     if (pkcs12 == NULL || psw == NULL || pkey == NULL || cert == NULL) {
17711         WOLFSSL_MSG("Bad argument value");
17712         return WOLFSSL_FAILURE;
17713     }
17714 
17715     heap  = wc_PKCS12_GetHeap(pkcs12);
17716     *pkey = NULL;
17717     *cert = NULL;
17718 
17719     if (ca == NULL) {
17720         ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
17721             NULL);
17722     }
17723     else {
17724         *ca = NULL;
17725         ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
17726             &certList);
17727     }
17728     if (ret < 0) {
17729         WOLFSSL_LEAVE("wolfSSL_PKCS12_parse", ret);
17730         return WOLFSSL_FAILURE;
17731     }
17732 
17733     /* Decode cert and place in X509 stack struct */
17734     if (certList != NULL) {
17735         WC_DerCertList* current = certList;
17736 
17737         *ca = (WOLF_STACK_OF(WOLFSSL_X509)*)XMALLOC(sizeof(WOLF_STACK_OF(WOLFSSL_X509)),
17738                                                heap, DYNAMIC_TYPE_X509);
17739         if (*ca == NULL) {
17740             if (pk != NULL) {
17741                 XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
17742             }
17743             if (certData != NULL) {
17744                 XFREE(*cert, heap, DYNAMIC_TYPE_PKCS); *cert = NULL;
17745             }
17746             /* Free up WC_DerCertList and move on */
17747             while (current != NULL) {
17748                 WC_DerCertList* next = current->next;
17749 
17750                 XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
17751                 XFREE(current, heap, DYNAMIC_TYPE_PKCS);
17752                 current = next;
17753             }
17754             return WOLFSSL_FAILURE;
17755         }
17756         XMEMSET(*ca, 0, sizeof(WOLF_STACK_OF(WOLFSSL_X509)));
17757 
17758         /* add list of DER certs as X509's to stack */
17759         while (current != NULL) {
17760             WC_DerCertList*  toFree = current;
17761             WOLFSSL_X509* x509;
17762 
17763             x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
17764                                                              DYNAMIC_TYPE_X509);
17765             InitX509(x509, 1, heap);
17766             InitDecodedCert(&DeCert, current->buffer, current->bufferSz, heap);
17767             if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
17768                 WOLFSSL_MSG("Issue with parsing certificate");
17769                 FreeDecodedCert(&DeCert);
17770                 wolfSSL_X509_free(x509);
17771             }
17772             else {
17773                 if ((ret = CopyDecodedToX509(x509, &DeCert)) != 0) {
17774                     WOLFSSL_MSG("Failed to copy decoded cert");
17775                     FreeDecodedCert(&DeCert);
17776                     wolfSSL_X509_free(x509);
17777                     wolfSSL_sk_X509_free(*ca); *ca = NULL;
17778                     if (pk != NULL) {
17779                         XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
17780                     }
17781                     if (certData != NULL) {
17782                         XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
17783                     }
17784                     /* Free up WC_DerCertList */
17785                     while (current != NULL) {
17786                         WC_DerCertList* next = current->next;
17787 
17788                         XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
17789                         XFREE(current, heap, DYNAMIC_TYPE_PKCS);
17790                         current = next;
17791                     }
17792                     return WOLFSSL_FAILURE;
17793                 }
17794                 FreeDecodedCert(&DeCert);
17795 
17796                 if (wolfSSL_sk_X509_push(*ca, x509) != 1) {
17797                     WOLFSSL_MSG("Failed to push x509 onto stack");
17798                     wolfSSL_X509_free(x509);
17799                     wolfSSL_sk_X509_free(*ca); *ca = NULL;
17800                     if (pk != NULL) {
17801                         XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
17802                     }
17803                     if (certData != NULL) {
17804                         XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
17805                     }
17806 
17807                     /* Free up WC_DerCertList */
17808                     while (current != NULL) {
17809                         WC_DerCertList* next = current->next;
17810 
17811                         XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
17812                         XFREE(current, heap, DYNAMIC_TYPE_PKCS);
17813                         current = next;
17814                     }
17815                     return WOLFSSL_FAILURE;
17816                 }
17817             }
17818             current = current->next;
17819             XFREE(toFree->buffer, heap, DYNAMIC_TYPE_PKCS);
17820             XFREE(toFree, heap, DYNAMIC_TYPE_PKCS);
17821         }
17822     }
17823 
17824 
17825     /* Decode cert and place in X509 struct */
17826     if (certData != NULL) {
17827         *cert = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
17828                                                              DYNAMIC_TYPE_X509);
17829         if (*cert == NULL) {
17830             if (pk != NULL) {
17831                 XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
17832             }
17833             if (ca != NULL) {
17834                 wolfSSL_sk_X509_free(*ca); *ca = NULL;
17835             }
17836             XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
17837             return WOLFSSL_FAILURE;
17838         }
17839         InitX509(*cert, 1, heap);
17840         InitDecodedCert(&DeCert, certData, certDataSz, heap);
17841         if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
17842             WOLFSSL_MSG("Issue with parsing certificate");
17843         }
17844         if ((ret = CopyDecodedToX509(*cert, &DeCert)) != 0) {
17845             WOLFSSL_MSG("Failed to copy decoded cert");
17846             FreeDecodedCert(&DeCert);
17847             if (pk != NULL) {
17848                 XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
17849             }
17850             if (ca != NULL) {
17851                 wolfSSL_sk_X509_free(*ca); *ca = NULL;
17852             }
17853             wolfSSL_X509_free(*cert); *cert = NULL;
17854             return WOLFSSL_FAILURE;
17855         }
17856         FreeDecodedCert(&DeCert);
17857         XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
17858     }
17859 
17860 
17861     /* get key type */
17862     ret = BAD_STATE_E;
17863     if (pk != NULL) { /* decode key if present */
17864         *pkey = wolfSSL_PKEY_new_ex(heap);
17865         if (*pkey == NULL) {
17866             wolfSSL_X509_free(*cert); *cert = NULL;
17867             if (ca != NULL) {
17868                 wolfSSL_sk_X509_free(*ca); *ca = NULL;
17869             }
17870             XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
17871             return WOLFSSL_FAILURE;
17872         }
17873         #ifndef NO_RSA
17874         {
17875             word32 keyIdx = 0;
17876             RsaKey key;
17877 
17878             if (wc_InitRsaKey(&key, heap) != 0) {
17879                 ret = BAD_STATE_E;
17880             }
17881             else {
17882                 if ((ret = wc_RsaPrivateKeyDecode(pk, &keyIdx, &key, pkSz))
17883                                                                          == 0) {
17884                     (*pkey)->type = EVP_PKEY_RSA;
17885                     (*pkey)->rsa  = wolfSSL_RSA_new();
17886                     (*pkey)->ownRsa = 1; /* we own RSA */
17887                     if ((*pkey)->rsa == NULL) {
17888                         WOLFSSL_MSG("issue creating EVP RSA key");
17889                         wolfSSL_X509_free(*cert); *cert = NULL;
17890                         if (ca != NULL) {
17891                             wolfSSL_sk_X509_free(*ca); *ca = NULL;
17892                         }
17893                         wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
17894                         XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
17895                         return WOLFSSL_FAILURE;
17896                     }
17897                     if ((ret = wolfSSL_RSA_LoadDer_ex((*pkey)->rsa, pk, pkSz,
17898                                     WOLFSSL_RSA_LOAD_PRIVATE)) != SSL_SUCCESS) {
17899                         WOLFSSL_MSG("issue loading RSA key");
17900                         wolfSSL_X509_free(*cert); *cert = NULL;
17901                         if (ca != NULL) {
17902                             wolfSSL_sk_X509_free(*ca); *ca = NULL;
17903                         }
17904                         wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
17905                         XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
17906                         return WOLFSSL_FAILURE;
17907                     }
17908 
17909                     WOLFSSL_MSG("Found PKCS12 RSA key");
17910                     ret = 0; /* set in success state for upcoming ECC check */
17911                 }
17912                 wc_FreeRsaKey(&key);
17913             }
17914         }
17915         #endif /* NO_RSA */
17916 
17917         #ifdef HAVE_ECC
17918         {
17919             word32  keyIdx = 0;
17920             ecc_key key;
17921 
17922             if (ret != 0) { /* if is in fail state check if ECC key */
17923                 if (wc_ecc_init(&key) != 0) {
17924                     wolfSSL_X509_free(*cert); *cert = NULL;
17925                     if (ca != NULL) {
17926                         wolfSSL_sk_X509_free(*ca); *ca = NULL;
17927                     }
17928                     wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
17929                     XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
17930                     return WOLFSSL_FAILURE;
17931                 }
17932 
17933                 if ((ret = wc_EccPrivateKeyDecode(pk, &keyIdx, &key, pkSz))
17934                                                                          != 0) {
17935                     wolfSSL_X509_free(*cert); *cert = NULL;
17936                     if (ca != NULL) {
17937                         wolfSSL_sk_X509_free(*ca); *ca = NULL;
17938                     }
17939                     wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
17940                     XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
17941                     WOLFSSL_MSG("Bad PKCS12 key format");
17942                     return WOLFSSL_FAILURE;
17943                 }
17944                 (*pkey)->type = EVP_PKEY_EC;
17945                 (*pkey)->pkey_curve = key.dp->oidSum;
17946                 wc_ecc_free(&key);
17947                 WOLFSSL_MSG("Found PKCS12 ECC key");
17948             }
17949         }
17950         #else
17951         if (ret != 0) { /* if is in fail state and no ECC then fail */
17952             wolfSSL_X509_free(*cert); *cert = NULL;
17953             if (ca != NULL) {
17954                 wolfSSL_sk_X509_free(*ca); *ca = NULL;
17955             }
17956             wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
17957             XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
17958             WOLFSSL_MSG("Bad PKCS12 key format");
17959             return WOLFSSL_FAILURE;
17960         }
17961         #endif /* HAVE_ECC */
17962 
17963         (*pkey)->save_type = 0;
17964         (*pkey)->pkey_sz   = pkSz;
17965         (*pkey)->pkey.ptr  = (char*)pk;
17966     }
17967 
17968     (void)ret;
17969     (void)ca;
17970 
17971     return WOLFSSL_SUCCESS;
17972 }
17973 #endif /* !defined(NO_ASN) && !defined(NO_PWDBASED) */
17974 
17975 
17976 /* no-op function. Was initially used for adding encryption algorithms available
17977  * for PKCS12 */
17978 void wolfSSL_PKCS12_PBE_add(void)
17979 {
17980     WOLFSSL_ENTER("wolfSSL_PKCS12_PBE_add");
17981 }
17982 
17983 
17984 
17985 WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx)
17986 {
17987     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_chain");
17988 
17989     if (ctx == NULL) {
17990         return NULL;
17991     }
17992 
17993 #ifdef SESSION_CERTS
17994     /* if chain is null but sesChain is available then populate stack */
17995     if (ctx->chain == NULL && ctx->sesChain != NULL) {
17996         int i;
17997         WOLFSSL_X509_CHAIN* c = ctx->sesChain;
17998         WOLFSSL_STACK*     sk = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK),
17999                                     NULL, DYNAMIC_TYPE_X509);
18000 
18001         if (sk == NULL) {
18002             return NULL;
18003         }
18004 
18005         XMEMSET(sk, 0, sizeof(WOLFSSL_STACK));
18006         ctx->chain = sk;
18007 
18008         for (i = 0; i < c->count && i < MAX_CHAIN_DEPTH; i++) {
18009             WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, i);
18010 
18011             if (x509 == NULL) {
18012                 WOLFSSL_MSG("Unable to get x509 from chain");
18013                 wolfSSL_sk_X509_free(sk);
18014                 return NULL;
18015             }
18016 
18017             if (wolfSSL_sk_X509_push(sk, x509) != SSL_SUCCESS) {
18018                 WOLFSSL_MSG("Unable to load x509 into stack");
18019                 wolfSSL_sk_X509_free(sk);
18020                 wolfSSL_X509_free(x509);
18021                 return NULL;
18022             }
18023         }
18024 
18025 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)
18026         /* add CA used to verify top of chain to the list */
18027         if (c->count > 0) {
18028             WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, c->count - 1);
18029             if (x509 != NULL) {
18030                 WOLFSSL_X509* issuer = NULL;
18031                 if (wolfSSL_X509_STORE_CTX_get1_issuer(&issuer, ctx, x509)
18032                         == WOLFSSL_SUCCESS) {
18033                     /* check that the certificate being looked up is not self
18034                      * signed and that a issuer was found */
18035                     if (issuer != NULL && wolfSSL_X509_NAME_cmp(&x509->issuer,
18036                                 &x509->subject) != 0) {
18037                         if (wolfSSL_sk_X509_push(sk, issuer) != SSL_SUCCESS) {
18038                             WOLFSSL_MSG("Unable to load CA x509 into stack");
18039                             wolfSSL_sk_X509_free(sk);
18040                             wolfSSL_X509_free(issuer);
18041                             return NULL;
18042                         }
18043                     }
18044                     else {
18045                         WOLFSSL_MSG("Certificate is self signed");
18046                     }
18047                 }
18048                 else {
18049                     WOLFSSL_MSG("Could not find CA for certificate");
18050                 }
18051             }
18052         }
18053 #endif
18054 
18055     }
18056 #endif /* SESSION_CERTS */
18057 
18058     return ctx->chain;
18059 }
18060 
18061 
18062 int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509)
18063 {
18064     int result = WOLFSSL_FATAL_ERROR;
18065 
18066     WOLFSSL_ENTER("wolfSSL_X509_STORE_add_cert");
18067     if (store != NULL && store->cm != NULL && x509 != NULL
18068                                                 && x509->derCert != NULL) {
18069         DerBuffer* derCert = NULL;
18070 
18071         result = AllocDer(&derCert, x509->derCert->length,
18072             x509->derCert->type, NULL);
18073         if (result == 0) {
18074             /* AddCA() frees the buffer. */
18075             XMEMCPY(derCert->buffer,
18076                             x509->derCert->buffer, x509->derCert->length);
18077             result = AddCA(store->cm, &derCert, WOLFSSL_USER_CA, 1);
18078         }
18079     }
18080 
18081     WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_cert", result);
18082 
18083     if (result != WOLFSSL_SUCCESS) {
18084         result = WOLFSSL_FATAL_ERROR;
18085     }
18086 
18087     return result;
18088 }
18089 
18090 WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void)
18091 {
18092     WOLFSSL_X509_STORE* store = NULL;
18093 
18094     if((store = (WOLFSSL_X509_STORE*)XMALLOC(sizeof(WOLFSSL_X509_STORE), NULL,
18095                             DYNAMIC_TYPE_X509_STORE)) == NULL)
18096         goto err_exit;
18097 
18098     if((store->cm = wolfSSL_CertManagerNew()) == NULL)
18099         goto err_exit;
18100 
18101     store->isDynamic = 1;
18102 
18103 #ifdef HAVE_CRL
18104     store->crl = NULL;
18105     if((store->crl = (WOLFSSL_X509_CRL *)XMALLOC(sizeof(WOLFSSL_X509_CRL),
18106                                 NULL, DYNAMIC_TYPE_TMP_BUFFER)) == NULL)
18107         goto err_exit;
18108     if(InitCRL(store->crl, NULL) < 0)
18109         goto err_exit;
18110 #endif
18111 
18112     return store;
18113 
18114 err_exit:
18115     if(store == NULL)
18116         return NULL;
18117     if(store->cm != NULL)
18118         wolfSSL_CertManagerFree(store->cm);
18119 #ifdef HAVE_CRL
18120     if(store->crl != NULL)
18121         wolfSSL_X509_CRL_free(store->crl);
18122 #endif
18123     wolfSSL_X509_STORE_free(store);
18124 
18125     return NULL;
18126 }
18127 
18128 
18129 void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store)
18130 {
18131     if (store != NULL && store->isDynamic) {
18132         if (store->cm != NULL)
18133             wolfSSL_CertManagerFree(store->cm);
18134 #ifdef HAVE_CRL
18135         if (store->crl != NULL)
18136             wolfSSL_X509_CRL_free(store->crl);
18137 #endif
18138         XFREE(store, NULL, DYNAMIC_TYPE_X509_STORE);
18139     }
18140 }
18141 
18142 
18143 int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, unsigned long flag)
18144 {
18145     int ret = WOLFSSL_SUCCESS;
18146 
18147     WOLFSSL_ENTER("wolfSSL_X509_STORE_set_flags");
18148 
18149     if ((flag & WOLFSSL_CRL_CHECKALL) || (flag & WOLFSSL_CRL_CHECK)) {
18150         ret = wolfSSL_CertManagerEnableCRL(store->cm, (int)flag);
18151     }
18152 
18153     (void)store;
18154     (void)flag;
18155 
18156     return ret;
18157 }
18158 
18159 
18160 int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE* store)
18161 {
18162     (void)store;
18163     return WOLFSSL_SUCCESS;
18164 }
18165 
18166 #ifndef NO_WOLFSSL_STUB
18167 int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX* ctx, int idx,
18168                             WOLFSSL_X509_NAME* name, WOLFSSL_X509_OBJECT* obj)
18169 {
18170     (void)ctx;
18171     (void)idx;
18172     (void)name;
18173     (void)obj;
18174     WOLFSSL_STUB("X509_STORE_get_by_subject");
18175     return 0;
18176 }
18177 #endif
18178 
18179 WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new(void)
18180 {
18181     WOLFSSL_X509_STORE_CTX* ctx = (WOLFSSL_X509_STORE_CTX*)XMALLOC(
18182                                     sizeof(WOLFSSL_X509_STORE_CTX), NULL,
18183                                     DYNAMIC_TYPE_X509_CTX);
18184     if (ctx != NULL) {
18185         ctx->param = NULL;
18186         wolfSSL_X509_STORE_CTX_init(ctx, NULL, NULL, NULL);
18187     }
18188 
18189     return ctx;
18190 }
18191 
18192 
18193 int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
18194      WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509, WOLF_STACK_OF(WOLFSSL_X509)* sk)
18195 {
18196     (void)sk;
18197     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_init");
18198     if (ctx != NULL) {
18199         ctx->store = store;
18200         ctx->current_cert = x509;
18201         ctx->chain  = sk;
18202         ctx->domain = NULL;
18203 #ifdef HAVE_EX_DATA
18204         ctx->ex_data = NULL;
18205 #endif
18206         ctx->userCtx = NULL;
18207         ctx->error = 0;
18208         ctx->error_depth = 0;
18209         ctx->discardSessionCerts = 0;
18210 #ifdef OPENSSL_EXTRA
18211         if (ctx->param == NULL) {
18212             ctx->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
18213                            sizeof(WOLFSSL_X509_VERIFY_PARAM),
18214                            NULL,DYNAMIC_TYPE_OPENSSL);
18215             if (ctx->param == NULL){
18216                 WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init failed");
18217                 return SSL_FATAL_ERROR;
18218             }
18219         }
18220 #endif
18221         return SSL_SUCCESS;
18222     }
18223     return WOLFSSL_FATAL_ERROR;
18224 }
18225 
18226 
18227 void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx)
18228 {
18229     if (ctx != NULL) {
18230         if (ctx->store != NULL)
18231             wolfSSL_X509_STORE_free(ctx->store);
18232         if (ctx->current_cert != NULL)
18233             wolfSSL_FreeX509(ctx->current_cert);
18234         if (ctx->chain != NULL)
18235             wolfSSL_sk_X509_free(ctx->chain);
18236 #ifdef OPENSSL_EXTRA
18237         if (ctx->param != NULL){
18238             XFREE(ctx->param,NULL,DYNAMIC_TYPE_OPENSSL);
18239         }
18240 #endif
18241         XFREE(ctx, NULL, DYNAMIC_TYPE_X509_CTX);
18242     }
18243 }
18244 
18245 
18246 void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX* ctx)
18247 {
18248     (void)ctx;
18249     /* Do nothing */
18250 }
18251 
18252 
18253 int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
18254 {
18255     if (ctx != NULL && ctx->store != NULL && ctx->store->cm != NULL
18256          && ctx->current_cert != NULL && ctx->current_cert->derCert != NULL) {
18257         return wolfSSL_CertManagerVerifyBuffer(ctx->store->cm,
18258                     ctx->current_cert->derCert->buffer,
18259                     ctx->current_cert->derCert->length,
18260                     WOLFSSL_FILETYPE_ASN1);
18261     }
18262     return WOLFSSL_FATAL_ERROR;
18263 }
18264 #endif /* NO_CERTS */
18265 
18266 #if !defined(NO_FILESYSTEM)
18267 static void *wolfSSL_d2i_X509_fp_ex(XFILE file, void **x509, int type)
18268 {
18269     void *newx509 = NULL;
18270     DerBuffer*   der = NULL;
18271     byte *fileBuffer = NULL;
18272 
18273     if (file != XBADFILE)
18274     {
18275         long sz = 0;
18276 
18277         XFSEEK(file, 0, XSEEK_END);
18278         sz = XFTELL(file);
18279         XREWIND(file);
18280 
18281         if (sz < 0)
18282         {
18283             WOLFSSL_MSG("Bad tell on FILE");
18284             return NULL;
18285         }
18286 
18287         fileBuffer = (byte *)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
18288         if (fileBuffer != NULL)
18289         {
18290             if((long)XFREAD(fileBuffer, 1, sz, file) != sz)
18291             {
18292                 WOLFSSL_MSG("File read failed");
18293                 goto err_exit;
18294             }
18295             if(type == CERT_TYPE)
18296                 newx509 = (void *)wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
18297             #ifdef HAVE_CRL
18298             else if(type == CRL_TYPE)
18299                 newx509 = (void *)wolfSSL_d2i_X509_CRL(NULL, fileBuffer, (int)sz);
18300             #endif
18301             #if !defined(NO_ASN) && !defined(NO_PWDBASED)
18302             else if(type == PKCS12_TYPE){
18303                 if((newx509 = wc_PKCS12_new()) == NULL)
18304                     goto err_exit;
18305                 if(wc_d2i_PKCS12(fileBuffer, (int)sz, (WC_PKCS12*)newx509) < 0)
18306                     goto err_exit;
18307             }
18308             #endif
18309             else goto err_exit;
18310             if(newx509 == NULL)
18311             {
18312                 WOLFSSL_MSG("X509 failed");
18313                 goto err_exit;
18314             }
18315         }
18316     }
18317     if (x509 != NULL)
18318         *x509 = newx509;
18319 
18320     goto _exit;
18321 
18322 err_exit:
18323     if(newx509 != NULL){
18324         if(type == CERT_TYPE)
18325             wolfSSL_X509_free((WOLFSSL_X509*)newx509);
18326         #ifdef HAVE_CRL
18327         else {
18328            if(type == CRL_TYPE)
18329                 wolfSSL_X509_CRL_free((WOLFSSL_X509_CRL*)newx509);
18330         }
18331         #endif
18332     }
18333 _exit:
18334     if(der != NULL)
18335         FreeDer(&der);
18336     if(fileBuffer != NULL)
18337         XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
18338     return newx509;
18339 }
18340 
18341 WOLFSSL_X509_PKCS12 *wolfSSL_d2i_PKCS12_fp(XFILE fp, WOLFSSL_X509_PKCS12 **pkcs12)
18342 {
18343     WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_fp");
18344     return (WOLFSSL_X509_PKCS12 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)pkcs12, PKCS12_TYPE);
18345 }
18346 
18347 WOLFSSL_X509 *wolfSSL_d2i_X509_fp(XFILE fp, WOLFSSL_X509 **x509)
18348 {
18349     WOLFSSL_ENTER("wolfSSL_d2i_X509_fp");
18350     return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)x509, CERT_TYPE);
18351 }
18352 #endif /* !NO_FILESYSTEM */
18353 
18354 
18355 #ifdef HAVE_CRL
18356 #ifndef NO_FILESYSTEM
18357 WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_fp(XFILE fp, WOLFSSL_X509_CRL **crl)
18358 {
18359     WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL_fp");
18360     return (WOLFSSL_X509_CRL *)wolfSSL_d2i_X509_fp_ex(fp, (void **)crl, CRL_TYPE);
18361 }
18362 #endif /* !NO_FILESYSTEM */
18363 
18364 
18365 WOLFSSL_X509_CRL* wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL** crl, const unsigned char* in, int len)
18366 {
18367     WOLFSSL_X509_CRL *newcrl = NULL;
18368     int ret ;
18369 
18370     WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL");
18371 
18372     if(in == NULL){
18373         WOLFSSL_MSG("Bad argument value");
18374         return NULL;
18375     }
18376 
18377     newcrl = (WOLFSSL_X509_CRL*)XMALLOC(sizeof(WOLFSSL_X509_CRL), NULL, DYNAMIC_TYPE_TMP_BUFFER);
18378     if (newcrl == NULL){
18379         WOLFSSL_MSG("New CRL allocation failed");
18380         return NULL;
18381     }
18382     if (InitCRL(newcrl, NULL) < 0) {
18383         WOLFSSL_MSG("Init tmp CRL failed");
18384         goto err_exit;
18385     }
18386     ret = BufferLoadCRL(newcrl, in, len, WOLFSSL_FILETYPE_ASN1, 1);
18387     if (ret != WOLFSSL_SUCCESS){
18388         WOLFSSL_MSG("Buffer Load CRL failed");
18389         goto err_exit;
18390     }
18391     if(crl){
18392         *crl = newcrl;
18393     }
18394     goto _exit;
18395 
18396 err_exit:
18397     if(newcrl != NULL)
18398         wolfSSL_X509_CRL_free(newcrl);
18399     newcrl = NULL;
18400 _exit:
18401     return newcrl;
18402 }
18403 
18404 void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl)
18405 {
18406     WOLFSSL_ENTER("wolfSSL_X509_CRL_free");
18407 
18408     FreeCRL(crl, 1);
18409     return;
18410 }
18411 #endif /* HAVE_CRL */
18412 
18413 #ifndef NO_WOLFSSL_STUB
18414 WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl)
18415 {
18416     (void)crl;
18417     WOLFSSL_STUB("X509_CRL_get_lastUpdate");
18418     return 0;
18419 }
18420 #endif
18421 #ifndef NO_WOLFSSL_STUB
18422 WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
18423 {
18424     (void)crl;
18425     WOLFSSL_STUB("X509_CRL_get_nextUpdate");
18426     return 0;
18427 }
18428 #endif
18429 
18430 
18431 #ifndef NO_WOLFSSL_STUB
18432 int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
18433 {
18434     (void)crl;
18435     (void)key;
18436     WOLFSSL_STUB("X509_CRL_verify");
18437     return 0;
18438 }
18439 #endif
18440 #endif /* OPENSSL_EXTRA */
18441 
18442 #if defined(OPENSSL_EXTRA_X509_SMALL)
18443 /* Subset of OPENSSL_EXTRA for PKEY operations PKEY free is needed by the
18444  * subset of X509 API */
18445 
18446 WOLFSSL_EVP_PKEY* wolfSSL_PKEY_new(){
18447     return wolfSSL_PKEY_new_ex(NULL);
18448 }
18449 
18450 
18451 WOLFSSL_EVP_PKEY* wolfSSL_PKEY_new_ex(void* heap)
18452 {
18453     WOLFSSL_EVP_PKEY* pkey;
18454     int ret;
18455     WOLFSSL_ENTER("wolfSSL_PKEY_new");
18456     pkey = (WOLFSSL_EVP_PKEY*)XMALLOC(sizeof(WOLFSSL_EVP_PKEY), heap,
18457             DYNAMIC_TYPE_PUBLIC_KEY);
18458     if (pkey != NULL) {
18459         XMEMSET(pkey, 0, sizeof(WOLFSSL_EVP_PKEY));
18460         pkey->heap = heap;
18461         pkey->type = WOLFSSL_EVP_PKEY_DEFAULT;
18462 #ifndef HAVE_FIPS
18463         ret = wc_InitRng_ex(&(pkey->rng), heap, INVALID_DEVID);
18464 #else
18465         ret = wc_InitRng(&(pkey->rng));
18466 #endif
18467         if (ret != 0){
18468             wolfSSL_EVP_PKEY_free(pkey);
18469             WOLFSSL_MSG("memory falure");
18470             return NULL;
18471         }
18472     }
18473     else {
18474         WOLFSSL_MSG("memory failure");
18475     }
18476 
18477     return pkey;
18478 }
18479 
18480 
18481 void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key)
18482 {
18483     WOLFSSL_ENTER("wolfSSL_PKEY_free");
18484     if (key != NULL) {
18485         wc_FreeRng(&(key->rng));
18486         if (key->pkey.ptr != NULL)
18487         {
18488             XFREE(key->pkey.ptr, key->heap, DYNAMIC_TYPE_PUBLIC_KEY);
18489         }
18490         switch(key->type)
18491         {
18492             #ifndef NO_RSA
18493             case EVP_PKEY_RSA:
18494                 if (key->rsa != NULL && key->ownRsa == 1) {
18495                     wolfSSL_RSA_free(key->rsa);
18496                 }
18497                 break;
18498             #endif /* NO_RSA */
18499 
18500             #ifdef HAVE_ECC
18501             case EVP_PKEY_EC:
18502                 if (key->ecc != NULL && key->ownEcc == 1) {
18503                     wolfSSL_EC_KEY_free(key->ecc);
18504                 }
18505                 break;
18506             #endif /* HAVE_ECC */
18507 
18508             default:
18509             break;
18510         }
18511         XFREE(key, key->heap, DYNAMIC_TYPE_PUBLIC_KEY);
18512     }
18513 }
18514 #endif /* OPENSSL_EXTRA_X509_SMALL */
18515 
18516 
18517 #ifdef OPENSSL_EXTRA
18518 
18519 void wolfSSL_X509_STORE_CTX_set_time(WOLFSSL_X509_STORE_CTX* ctx,
18520                                     unsigned long flags,
18521                                     time_t t)
18522 {
18523     (void)flags;
18524 
18525     if (ctx == NULL || ctx->param == NULL)
18526         return;
18527 
18528     ctx->param->check_time = t;
18529     ctx->param->flags |= WOLFSSL_USE_CHECK_TIME;
18530 }
18531 
18532 #ifndef NO_WOLFSSL_STUB
18533 void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj)
18534 {
18535     (void)obj;
18536     WOLFSSL_STUB("X509_OBJECT_free_contents");
18537 }
18538 #endif
18539 
18540 #ifndef NO_WOLFSSL_STUB
18541 int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME* asnTime)
18542 {
18543     (void)asnTime;
18544     WOLFSSL_STUB("X509_cmp_current_time");
18545     return 0;
18546 }
18547 #endif
18548 
18549 #ifndef NO_WOLFSSL_STUB
18550 int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED* revoked)
18551 {
18552     (void)revoked;
18553     WOLFSSL_STUB("sk_X509_REVOKED_num");
18554     return 0;
18555 }
18556 #endif
18557 
18558 #ifndef NO_WOLFSSL_STUB
18559 WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL* crl)
18560 {
18561     (void)crl;
18562     WOLFSSL_STUB("X509_CRL_get_REVOKED");
18563     return 0;
18564 }
18565 #endif
18566 
18567 #ifndef NO_WOLFSSL_STUB
18568 WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(
18569                                     WOLFSSL_X509_REVOKED* revoked, int value)
18570 {
18571     (void)revoked;
18572     (void)value;
18573     WOLFSSL_STUB("sk_X509_REVOKED_value");
18574     return 0;
18575 }
18576 #endif
18577 
18578 /* Used to create a new WOLFSSL_ASN1_INTEGER structure.
18579  * returns a pointer to new structure on success and NULL on failure
18580  */
18581 WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_new(void)
18582 {
18583     WOLFSSL_ASN1_INTEGER* a;
18584 
18585     a = (WOLFSSL_ASN1_INTEGER*)XMALLOC(sizeof(WOLFSSL_ASN1_INTEGER), NULL,
18586                                        DYNAMIC_TYPE_OPENSSL);
18587     if (a == NULL) {
18588         return NULL;
18589     }
18590 
18591     XMEMSET(a, 0, sizeof(WOLFSSL_ASN1_INTEGER));
18592     a->data    = a->intData;
18593     a->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
18594     return a;
18595 }
18596 
18597 
18598 /* free's internal elements of WOLFSSL_ASN1_INTEGER and free's "in" itself */
18599 void wolfSSL_ASN1_INTEGER_free(WOLFSSL_ASN1_INTEGER* in)
18600 {
18601     if (in != NULL) {
18602         if (in->isDynamic) {
18603             XFREE(in->data, NULL, DYNAMIC_TYPE_OPENSSL);
18604         }
18605         XFREE(in, NULL, DYNAMIC_TYPE_OPENSSL);
18606     }
18607 }
18608 
18609 
18610 WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
18611 {
18612     WOLFSSL_ASN1_INTEGER* a;
18613     int i = 0;
18614 
18615     WOLFSSL_ENTER("wolfSSL_X509_get_serialNumber");
18616 
18617     a = wolfSSL_ASN1_INTEGER_new();
18618     if (a == NULL)
18619         return NULL;
18620 
18621     /* Make sure there is space for the data, ASN.1 type and length. */
18622     if (x509->serialSz > (WOLFSSL_ASN1_INTEGER_MAX - 2)) {
18623         /* dynamicly create data buffer, +2 for type and length */
18624         a->data = (unsigned char*)XMALLOC(x509->serialSz + 2, NULL,
18625                 DYNAMIC_TYPE_OPENSSL);
18626         if (a->data == NULL) {
18627             wolfSSL_ASN1_INTEGER_free(a);
18628             return NULL;
18629         }
18630         a->dataMax   = x509->serialSz + 2;
18631         a->isDynamic = 1;
18632     }
18633 
18634     a->data[i++] = ASN_INTEGER;
18635     i += SetLength(x509->serialSz, a->data + i);
18636     XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
18637 
18638     return a;
18639 }
18640 
18641 #endif /* OPENSSL_EXTRA */
18642 
18643 #if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || \
18644     defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
18645 int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime)
18646 {
18647     char buf[MAX_TIME_STRING_SZ];
18648     int  ret = WOLFSSL_SUCCESS;
18649 
18650     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_print");
18651 
18652     if (bio == NULL || asnTime == NULL) {
18653         WOLFSSL_MSG("NULL function argument");
18654         return WOLFSSL_FAILURE;
18655     }
18656 
18657     if (wolfSSL_ASN1_TIME_to_string((WOLFSSL_ASN1_TIME*)asnTime, buf,
18658                 sizeof(buf)) == NULL) {
18659         XMEMSET(buf, 0, MAX_TIME_STRING_SZ);
18660         XMEMCPY(buf, "Bad time value", 14);
18661         ret = WOLFSSL_FAILURE;
18662     }
18663 
18664     if (wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf)) <= 0) {
18665         WOLFSSL_MSG("Unable to write to bio");
18666         return WOLFSSL_FAILURE;
18667     }
18668 
18669     return ret;
18670 }
18671 
18672 
18673 char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* t, char* buf, int len)
18674 {
18675     int format;
18676     int dateLen;
18677     byte* date = (byte*)t;
18678 
18679     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_string");
18680 
18681     if (t == NULL || buf == NULL || len < 5) {
18682         WOLFSSL_MSG("Bad argument");
18683         return NULL;
18684     }
18685 
18686     format  = *date; date++;
18687     dateLen = *date; date++;
18688     if (dateLen > len) {
18689         WOLFSSL_MSG("Length of date is longer then buffer");
18690         return NULL;
18691     }
18692 
18693     if (!GetTimeString(date, format, buf, len)) {
18694         return NULL;
18695     }
18696 
18697     return buf;
18698 }
18699 #endif /* WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
18700     OPENSSL_EXTRA*/
18701 
18702 
18703 #ifdef OPENSSL_EXTRA
18704 
18705 #if !defined(NO_ASN_TIME) && !defined(USER_TIME) && \
18706     !defined(TIME_OVERRIDES) && !defined(NO_FILESYSTEM)
18707 
18708 WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_adj(WOLFSSL_ASN1_TIME *s, time_t t,
18709                                     int offset_day, long offset_sec)
18710 {
18711     const time_t sec_per_day = 24*60*60;
18712     struct tm* ts = NULL;
18713     struct tm* tmpTime = NULL;
18714     time_t t_adj = 0;
18715     time_t offset_day_sec = 0;
18716 
18717 #if defined(NEED_TMP_TIME)
18718     struct tm tmpTimeStorage;
18719     tmpTime = &tmpTimeStorage;
18720 #else
18721     (void)tmpTime;
18722 #endif
18723 
18724     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_adj");
18725 
18726     if (s == NULL){
18727         s = (WOLFSSL_ASN1_TIME*)XMALLOC(sizeof(WOLFSSL_ASN1_TIME), NULL,
18728                                         DYNAMIC_TYPE_OPENSSL);
18729         if (s == NULL){
18730             return NULL;
18731         }
18732     }
18733 
18734     /* compute GMT time with offset */
18735     offset_day_sec = offset_day * sec_per_day;
18736     t_adj          = t + offset_day_sec + offset_sec;
18737     ts             = (struct tm *)XGMTIME(&t_adj, tmpTime);
18738     if (ts == NULL){
18739         WOLFSSL_MSG("failed to get time data.");
18740         XFREE(s, NULL, DYNAMIC_TYPE_OPENSSL);
18741         return NULL;
18742     }
18743 
18744     /* create ASN1 time notation */
18745     /* UTC Time */
18746     if (ts->tm_year >= 50 && ts->tm_year < 150){
18747         char utc_str[ASN_UTC_TIME_SIZE];
18748         int utc_year = 0,utc_mon,utc_day,utc_hour,utc_min,utc_sec;
18749         byte *data_ptr = NULL;
18750 
18751         if (ts->tm_year >= 50 && ts->tm_year < 100){
18752             utc_year = ts->tm_year;
18753         } else if (ts->tm_year >= 100 && ts->tm_year < 150){
18754             utc_year = ts->tm_year - 100;
18755         }
18756         utc_mon  = ts->tm_mon + 1;
18757         utc_day  = ts->tm_mday;
18758         utc_hour = ts->tm_hour;
18759         utc_min  = ts->tm_min;
18760         utc_sec  = ts->tm_sec;
18761         XSNPRINTF((char *)utc_str, ASN_UTC_TIME_SIZE,
18762                   "%02d%02d%02d%02d%02d%02dZ",
18763                   utc_year, utc_mon, utc_day, utc_hour, utc_min, utc_sec);
18764         data_ptr  = s->data;
18765         *data_ptr = (byte) ASN_UTC_TIME; data_ptr++;
18766         *data_ptr = (byte) ASN_UTC_TIME_SIZE; data_ptr++;
18767         XMEMCPY(data_ptr,(byte *)utc_str, ASN_UTC_TIME_SIZE);
18768     /* GeneralizedTime */
18769     } else {
18770         char gt_str[ASN_GENERALIZED_TIME_SIZE];
18771         int gt_year,gt_mon,gt_day,gt_hour,gt_min,gt_sec;
18772         byte *data_ptr = NULL;
18773 
18774         gt_year = ts->tm_year + 1900;
18775         gt_mon  = ts->tm_mon + 1;
18776         gt_day  = ts->tm_mday;
18777         gt_hour = ts->tm_hour;
18778         gt_min  = ts->tm_min;
18779         gt_sec  = ts->tm_sec;
18780         XSNPRINTF((char *)gt_str, ASN_GENERALIZED_TIME_SIZE,
18781                   "%4d%02d%02d%02d%02d%02dZ",
18782                   gt_year, gt_mon, gt_day, gt_hour, gt_min,gt_sec);
18783         data_ptr  = s->data;
18784         *data_ptr = (byte) ASN_GENERALIZED_TIME; data_ptr++;
18785         *data_ptr = (byte) ASN_GENERALIZED_TIME_SIZE; data_ptr++;
18786         XMEMCPY(data_ptr,(byte *)gt_str, ASN_GENERALIZED_TIME_SIZE);
18787     }
18788 
18789     return s;
18790 }
18791 #endif /* !NO_ASN_TIME && !USER_TIME && !TIME_OVERRIDES && !NO_FILESYSTEM */
18792 
18793 #ifndef NO_WOLFSSL_STUB
18794 int wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER* a,
18795                             const WOLFSSL_ASN1_INTEGER* b)
18796 {
18797     (void)a;
18798     (void)b;
18799     WOLFSSL_STUB("ASN1_INTEGER_cmp");
18800     return 0;
18801 }
18802 #endif
18803 
18804 #ifndef NO_WOLFSSL_STUB
18805 long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER* i)
18806 {
18807     (void)i;
18808     WOLFSSL_STUB("ASN1_INTEGER_get");
18809     return 0;
18810 }
18811 #endif
18812 
18813 
18814 void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx)
18815 {
18816     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_ex_data");
18817 #if defined(HAVE_EX_DATA) || defined(FORTRESS)
18818     if (ctx != NULL && idx == 0)
18819         return ctx->ex_data;
18820 #else
18821     (void)ctx;
18822     (void)idx;
18823 #endif
18824     return 0;
18825 }
18826 
18827 
18828 /* Gets an index to store SSL structure at.
18829  *
18830  * Returns positive index on success and negative values on failure
18831  */
18832 int wolfSSL_get_ex_data_X509_STORE_CTX_idx(void)
18833 {
18834     WOLFSSL_ENTER("wolfSSL_get_ex_data_X509_STORE_CTX_idx");
18835 
18836     /* store SSL at index 0 */
18837     return 0;
18838 }
18839 
18840 
18841 /* Set an error stat in the X509 STORE CTX
18842  *
18843  */
18844 void wolfSSL_X509_STORE_CTX_set_error(WOLFSSL_X509_STORE_CTX* ctx, int er)
18845 {
18846     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_error");
18847 
18848     if (ctx != NULL) {
18849         ctx->error = er;
18850     }
18851 }
18852 
18853 
18854 /* Sets a function callback that will send information about the state of all
18855  * WOLFSSL objects that have been created by the WOLFSSL_CTX structure passed
18856  * in.
18857  *
18858  * ctx WOLFSSL_CTX structre to set callback function in
18859  * f   callback function to use
18860  */
18861 void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX* ctx,
18862        void (*f)(const WOLFSSL* ssl, int type, int val))
18863 {
18864     WOLFSSL_ENTER("wolfSSL_CTX_set_info_callback");
18865     if (ctx == NULL) {
18866         WOLFSSL_MSG("Bad function argument");
18867     }
18868     else {
18869         ctx->CBIS = f;
18870     }
18871 }
18872 
18873 
18874 unsigned long wolfSSL_ERR_peek_error(void)
18875 {
18876     WOLFSSL_ENTER("wolfSSL_ERR_peek_error");
18877 
18878     return wolfSSL_ERR_peek_error_line_data(NULL, NULL, NULL, NULL);
18879 }
18880 
18881 
18882 /* This function is to find global error values that are the same through out
18883  * all library version. With wolfSSL having only one set of error codes the
18884  * return value is pretty straight forward. The only thing needed is all wolfSSL
18885  * error values are typically negative.
18886  *
18887  * Returns the error reason
18888  */
18889 int wolfSSL_ERR_GET_REASON(unsigned long err)
18890 {
18891     int ret = (int)err;
18892 
18893     WOLFSSL_ENTER("wolfSSL_ERR_GET_REASON");
18894 
18895 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
18896     /* Nginx looks for this error to know to stop parsing certificates. */
18897     if (err == ((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE))
18898         return PEM_R_NO_START_LINE;
18899 #endif
18900 
18901     /* check if error value is in range of wolfSSL errors */
18902     ret = 0 - ret; /* setting as negative value */
18903     /* wolfCrypt range is less than MAX (-100)
18904        wolfSSL range is MIN (-300) and lower */
18905     if (ret < MAX_CODE_E) {
18906         return ret;
18907     }
18908     else {
18909         WOLFSSL_MSG("Not in range of typical error values");
18910         ret = (int)err;
18911     }
18912 
18913     return ret;
18914 }
18915 
18916 
18917 /* returns a string that describes the alert
18918  *
18919  * alertID the alert value to look up
18920  */
18921 const char* wolfSSL_alert_type_string_long(int alertID)
18922 {
18923     WOLFSSL_ENTER("wolfSSL_aalert_type_string_long");
18924 
18925     switch (alertID) {
18926         case close_notify:
18927             {
18928                 static const char close_notify_str[] =
18929                     "close_notify";
18930                 return close_notify_str;
18931             }
18932 
18933         case unexpected_message:
18934             {
18935                 static const char unexpected_message_str[] =
18936                     "unexpected_message";
18937                 return unexpected_message_str;
18938             }
18939 
18940         case bad_record_mac:
18941             {
18942                 static const char bad_record_mac_str[] =
18943                     "bad_record_mac";
18944                 return bad_record_mac_str;
18945             }
18946 
18947         case record_overflow:
18948             {
18949                 static const char record_overflow_str[] =
18950                     "record_overflow";
18951                 return record_overflow_str;
18952             }
18953 
18954         case decompression_failure:
18955             {
18956                 static const char decompression_failure_str[] =
18957                     "decompression_failure";
18958                 return decompression_failure_str;
18959             }
18960 
18961         case handshake_failure:
18962             {
18963                 static const char handshake_failure_str[] =
18964                     "handshake_failure";
18965                 return handshake_failure_str;
18966             }
18967 
18968         case no_certificate:
18969             {
18970                 static const char no_certificate_str[] =
18971                     "no_certificate";
18972                 return no_certificate_str;
18973             }
18974 
18975         case bad_certificate:
18976             {
18977                 static const char bad_certificate_str[] =
18978                     "bad_certificate";
18979                 return bad_certificate_str;
18980             }
18981 
18982         case unsupported_certificate:
18983             {
18984                 static const char unsupported_certificate_str[] =
18985                     "unsupported_certificate";
18986                 return unsupported_certificate_str;
18987             }
18988 
18989         case certificate_revoked:
18990             {
18991                 static const char certificate_revoked_str[] =
18992                     "certificate_revoked";
18993                 return certificate_revoked_str;
18994             }
18995 
18996         case certificate_expired:
18997             {
18998                 static const char certificate_expired_str[] =
18999                     "certificate_expired";
19000                 return certificate_expired_str;
19001             }
19002 
19003         case certificate_unknown:
19004             {
19005                 static const char certificate_unknown_str[] =
19006                     "certificate_unknown";
19007                 return certificate_unknown_str;
19008             }
19009 
19010         case illegal_parameter:
19011             {
19012                 static const char illegal_parameter_str[] =
19013                     "illegal_parameter";
19014                 return illegal_parameter_str;
19015             }
19016 
19017         case decode_error:
19018             {
19019                 static const char decode_error_str[] =
19020                     "decode_error";
19021                 return decode_error_str;
19022             }
19023 
19024         case decrypt_error:
19025             {
19026                 static const char decrypt_error_str[] =
19027                     "decrypt_error";
19028                 return decrypt_error_str;
19029             }
19030 
19031     #ifdef WOLFSSL_MYSQL_COMPATIBLE
19032     /* catch name conflict for enum protocol with MYSQL build */
19033         case wc_protocol_version:
19034             {
19035                 static const char wc_protocol_version_str[] =
19036                     "wc_protocol_version";
19037                 return wc_protocol_version_str;
19038             }
19039 
19040     #else
19041         case protocol_version:
19042             {
19043                 static const char protocol_version_str[] =
19044                     "protocol_version";
19045                 return protocol_version_str;
19046             }
19047 
19048     #endif
19049         case no_renegotiation:
19050             {
19051                 static const char no_renegotiation_str[] =
19052                     "no_renegotiation";
19053                 return no_renegotiation_str;
19054             }
19055 
19056         case unrecognized_name:
19057             {
19058                 static const char unrecognized_name_str[] =
19059                     "unrecognized_name";
19060                 return unrecognized_name_str;
19061             }
19062 
19063         case bad_certificate_status_response:
19064             {
19065                 static const char bad_certificate_status_response_str[] =
19066                     "bad_certificate_status_response";
19067                 return bad_certificate_status_response_str;
19068             }
19069 
19070         case no_application_protocol:
19071             {
19072                 static const char no_application_protocol_str[] =
19073                     "no_application_protocol";
19074                 return no_application_protocol_str;
19075             }
19076 
19077         default:
19078             WOLFSSL_MSG("Unknown Alert");
19079             return NULL;
19080     }
19081 }
19082 
19083 
19084 const char* wolfSSL_alert_desc_string_long(int alertID)
19085 {
19086     WOLFSSL_ENTER("wolfSSL_alert_desc_string_long");
19087     return wolfSSL_alert_type_string_long(alertID);
19088 }
19089 
19090 
19091 /* Gets the current state of the WOLFSSL structure
19092  *
19093  * ssl WOLFSSL structure to get state of
19094  *
19095  * Returns a human readable string of the WOLFSSL structure state
19096  */
19097 const char* wolfSSL_state_string_long(const WOLFSSL* ssl)
19098 {
19099 
19100     static const char* OUTPUT_STR[14][6][3] = {
19101         {
19102             {"SSLv3 Initialization","SSLv3 Initialization","SSLv3 Initialization"},
19103             {"TLSv1 Initialization","TLSv2 Initialization","TLSv2 Initialization"},
19104             {"TLSv1_1 Initialization","TLSv1_1 Initialization","TLSv1_1 Initialization"},
19105             {"TLSv1_2 Initialization","TLSv1_2 Initialization","TLSv1_2 Initialization"},
19106             {"DTLSv1 Initialization","DTLSv1 Initialization","DTLSv1 Initialization"},
19107             {"DTLSv1_2 Initialization","DTLSv1_2 Initialization","DTLSv1_2 Initialization"},
19108         },
19109         {
19110             {"SSLv3 read Server Hello Verify Request",
19111              "SSLv3 write Server Hello Verify Request",
19112              "SSLv3 Server Hello Verify Request"},
19113             {"TLSv1 read Server Hello Verify Request",
19114              "TLSv1 write Server Hello Verify Request",
19115              "TLSv1 Server Hello Verify Request"},
19116             {"TLSv1_1 read Server Hello Verify Request",
19117             "TLSv1_1 write Server Hello Verify Request",
19118              "TLSv1_1 Server Hello Verify Request"},
19119             {"TLSv1_2 read Server Hello Verify Request",
19120             "TLSv1_2 write Server Hello Verify Request",
19121              "TLSv1_2 Server Hello Verify Request"},
19122             {"DTLSv1 read Server Hello Verify Request",
19123              "DTLSv1 write Server Hello Verify Request",
19124              "DTLSv1 Server Hello Verify Request"},
19125             {"DTLSv1_2 read Server Hello Verify Request",
19126              "DTLSv1_2 write Server Hello Verify Request",
19127              "DTLSv1_2 Server Hello Verify Request"},
19128         },
19129         {
19130             {"SSLv3 read Server Hello",
19131              "SSLv3 write Server Hello",
19132              "SSLv3 Server Hello"},
19133             {"TLSv1 read Server Hello",
19134              "TLSv1 write Server Hello",
19135              "TLSv1 Server Hello"},
19136             {"TLSv1_1 read Server Hello",
19137             "TLSv1_1 write Server Hello",
19138              "TLSv1_1 Server Hello"},
19139             {"TLSv1_2 read Server Hello",
19140             "TLSv1_2 write Server Hello",
19141              "TLSv1_2 Server Hello"},
19142             {"DTLSv1 read Server Hello",
19143             "DTLSv1 write Server Hello",
19144              "DTLSv1 Server Hello"},
19145             {"DTLSv1_2 read Server Hello"
19146              "DTLSv1_2 write Server Hello",
19147              "DTLSv1_2 Server Hello",
19148             },
19149         },
19150         {
19151             {"SSLv3 read Server Session Ticket",
19152              "SSLv3 write Server Session Ticket",
19153              "SSLv3 Server Session Ticket"},
19154             {"TLSv1 read Server Session Ticket",
19155              "TLSv1 write Server Session Ticket",
19156              "TLSv1 Server Session Ticket"},
19157             {"TLSv1_1 read Server Session Ticket",
19158              "TLSv1_1 write Server Session Ticket",
19159              "TLSv1_1 Server Session Ticket"},
19160             {"TLSv1_2 read Server Session Ticket",
19161              "TLSv1_2 write Server Session Ticket",
19162              "TLSv1_2 Server Session Ticket"},
19163             {"DTLSv1 read Server Session Ticket",
19164              "DTLSv1 write Server Session Ticket",
19165              "DTLSv1 Server Session Ticket"},
19166             {"DTLSv1_2 read Server Session Ticket",
19167              "DTLSv1_2 write Server Session Ticket",
19168              "DTLSv1_2 Server Session Ticket"},
19169         },
19170         {
19171             {"SSLv3 read Server Cert",
19172              "SSLv3 write Server Cert",
19173              "SSLv3 Server Cert"},
19174             {"TLSv1 read Server Cert",
19175              "TLSv1 write Server Cert",
19176              "TLSv1 Server Cert"},
19177             {"TLSv1_1 read Server Cert",
19178              "TLSv1_1 write Server Cert",
19179              "TLSv1_1 Server Cert"},
19180             {"TLSv1_2 read Server Cert",
19181              "TLSv1_2 write Server Cert",
19182              "TLSv1_2 Server Cert"},
19183             {"DTLSv1 read Server Cert",
19184              "DTLSv1 write Server Cert",
19185              "DTLSv1 Server Cert"},
19186             {"DTLSv1_2 read Server Cert",
19187              "DTLSv1_2 write Server Cert",
19188              "DTLSv1_2 Server Cert"},
19189         },
19190         {
19191             {"SSLv3 read Server Key Exchange",
19192              "SSLv3 write Server Key Exchange",
19193              "SSLv3 Server Key Exchange"},
19194             {"TLSv1 read Server Key Exchange",
19195              "TLSv1 write Server Key Exchange",
19196              "TLSv1 Server Key Exchange"},
19197             {"TLSv1_1 read Server Key Exchange",
19198              "TLSv1_1 write Server Key Exchange",
19199              "TLSv1_1 Server Key Exchange"},
19200             {"TLSv1_2 read Server Key Exchange",
19201              "TLSv1_2 write Server Key Exchange",
19202              "TLSv1_2 Server Key Exchange"},
19203             {"DTLSv1 read Server Key Exchange",
19204              "DTLSv1 write Server Key Exchange",
19205              "DTLSv1 Server Key Exchange"},
19206             {"DTLSv1_2 read Server Key Exchange",
19207              "DTLSv1_2 write Server Key Exchange",
19208              "DTLSv1_2 Server Key Exchange"},
19209         },
19210         {
19211             {"SSLv3 read Server Hello Done",
19212              "SSLv3 write Server Hello Done",
19213              "SSLv3 Server Hello Done"},
19214             {"TLSv1 read Server Hello Done",
19215              "TLSv1 write Server Hello Done",
19216              "TLSv1 Server Hello Done"},
19217             {"TLSv1_1 read Server Hello Done",
19218              "TLSv1_1 write Server Hello Done",
19219              "TLSv1_1 Server Hello Done"},
19220             {"TLSv1_2 read Server Hello Done",
19221              "TLSv1_2 write Server Hello Done",
19222              "TLSv1_2 Server Hello Done"},
19223             {"DTLSv1 read Server Hello Done",
19224              "DTLSv1 write Server Hello Done",
19225              "DTLSv1 Server Hello Done"},
19226             {"DTLSv1_2 read Server Hello Done",
19227              "DTLSv1_2 write Server Hello Done",
19228              "DTLSv1_2 Server Hello Done"},
19229         },
19230         {
19231             {"SSLv3 read Server Change CipherSpec",
19232              "SSLv3 write Server Change CipherSpec",
19233              "SSLv3 Server Change CipherSpec"},
19234             {"TLSv1 read Server Change CipherSpec",
19235              "TLSv1 write Server Change CipherSpec",
19236              "TLSv1 Server Change CipherSpec"},
19237             {"TLSv1_1 read Server Change CipherSpec",
19238              "TLSv1_1 write Server Change CipherSpec",
19239              "TLSv1_1 Server Change CipherSpec"},
19240             {"TLSv1_2 read Server Change CipherSpec",
19241              "TLSv1_2 write Server Change CipherSpec",
19242              "TLSv1_2 Server Change CipherSpec"},
19243             {"DTLSv1 read Server Change CipherSpec",
19244              "DTLSv1 write Server Change CipherSpec",
19245              "DTLSv1 Server Change CipherSpec"},
19246             {"DTLSv1_2 read Server Change CipherSpec",
19247              "DTLSv1_2 write Server Change CipherSpec",
19248              "DTLSv1_2 Server Change CipherSpec"},
19249         },
19250         {
19251             {"SSLv3 read Server Finished",
19252              "SSLv3 write Server Finished",
19253              "SSLv3 Server Finished"},
19254             {"TLSv1 read Server Finished",
19255              "TLSv1 write Server Finished",
19256              "TLSv1 Server Finished"},
19257             {"TLSv1_1 read Server Finished",
19258              "TLSv1_1 write Server Finished",
19259              "TLSv1_1 Server Finished"},
19260             {"TLSv1_2 read Server Finished",
19261              "TLSv1_2 write Server Finished",
19262              "TLSv1_2 Server Finished"},
19263             {"DTLSv1 read Server Finished",
19264              "DTLSv1 write Server Finished",
19265              "DTLSv1 Server Finished"},
19266             {"DTLSv1_2 read Server Finished",
19267              "DTLSv1_2 write Server Finished",
19268              "DTLSv1_2 Server Finished"},
19269         },
19270         {
19271             {"SSLv3 read Client Hello",
19272              "SSLv3 write Client Hello",
19273              "SSLv3 Client Hello"},
19274             {"TLSv1 read Client Hello",
19275              "TLSv1 write Client Hello",
19276              "TLSv1 Client Hello"},
19277             {"TLSv1_1 read Client Hello",
19278              "TLSv1_1 write Client Hello",
19279              "TLSv1_1 Client Hello"},
19280             {"TLSv1_2 read Client Hello",
19281              "TLSv1_2 write Client Hello",
19282              "TLSv1_2 Client Hello"},
19283             {"DTLSv1 read Client Hello",
19284              "DTLSv1 write Client Hello",
19285              "DTLSv1 Client Hello"},
19286             {"DTLSv1_2 read Client Hello",
19287              "DTLSv1_2 write Client Hello",
19288              "DTLSv1_2 Client Hello"},
19289         },
19290         {
19291             {"SSLv3 read Client Key Exchange",
19292              "SSLv3 write Client Key Exchange",
19293              "SSLv3 Client Key Exchange"},
19294             {"TLSv1 read Client Key Exchange",
19295              "TLSv1 write Client Key Exchange",
19296              "TLSv1 Client Key Exchange"},
19297             {"TLSv1_1 read Client Key Exchange",
19298              "TLSv1_1 write Client Key Exchange",
19299              "TLSv1_1 Client Key Exchange"},
19300             {"TLSv1_2 read Client Key Exchange",
19301              "TLSv1_2 write Client Key Exchange",
19302              "TLSv1_2 Client Key Exchange"},
19303             {"DTLSv1 read Client Key Exchange",
19304              "DTLSv1 write Client Key Exchange",
19305              "DTLSv1 Client Key Exchange"},
19306             {"DTLSv1_2 read Client Key Exchange",
19307              "DTLSv1_2 write Client Key Exchange",
19308              "DTLSv1_2 Client Key Exchange"},
19309         },
19310         {
19311             {"SSLv3 read Client Change CipherSpec",
19312              "SSLv3 write Client Change CipherSpec",
19313              "SSLv3 Client Change CipherSpec"},
19314             {"TLSv1 read Client Change CipherSpec",
19315              "TLSv1 write Client Change CipherSpec",
19316              "TLSv1 Client Change CipherSpec"},
19317             {"TLSv1_1 read Client Change CipherSpec",
19318              "TLSv1_1 write Client Change CipherSpec",
19319              "TLSv1_1 Client Change CipherSpec"},
19320             {"TLSv1_2 read Client Change CipherSpec",
19321              "TLSv1_2 write Client Change CipherSpec",
19322              "TLSv1_2 Client Change CipherSpec"},
19323             {"DTLSv1 read Client Change CipherSpec",
19324              "DTLSv1 write Client Change CipherSpec",
19325              "DTLSv1 Client Change CipherSpec"},
19326             {"DTLSv1_2 read Client Change CipherSpec",
19327              "DTLSv1_2 write Client Change CipherSpec",
19328              "DTLSv1_2 Client Change CipherSpec"},
19329         },
19330         {
19331             {"SSLv3 read Client Finished",
19332              "SSLv3 write Client Finished",
19333              "SSLv3 Client Finished"},
19334             {"TLSv1 read Client Finished",
19335              "TLSv1 write Client Finished",
19336              "TLSv1 Client Finished"},
19337             {"TLSv1_1 read Client Finished",
19338              "TLSv1_1 write Client Finished",
19339              "TLSv1_1 Client Finished"},
19340             {"TLSv1_2 read Client Finished",
19341              "TLSv1_2 write Client Finished",
19342              "TLSv1_2 Client Finished"},
19343             {"DTLSv1 read Client Finished",
19344              "DTLSv1 write Client Finished",
19345              "DTLSv1 Client Finished"},
19346             {"DTLSv1_2 read Client Finished",
19347              "DTLSv1_2 write Client Finished",
19348              "DTLSv1_2 Client Finished"},
19349         },
19350         {
19351             {"SSLv3 Handshake Done",
19352              "SSLv3 Handshake Done",
19353              "SSLv3 Handshake Done"},
19354             {"TLSv1 Handshake Done",
19355              "TLSv1 Handshake Done",
19356              "TLSv1 Handshake Done"},
19357             {"TLSv1_1 Handshake Done",
19358              "TLSv1_1 Handshake Done",
19359              "TLSv1_1 Handshake Done"},
19360             {"TLSv1_2 Handshake Done",
19361              "TLSv1_2 Handshake Done",
19362              "TLSv1_2 Handshake Done"},
19363             {"DTLSv1 Handshake Done",
19364              "DTLSv1 Handshake Done",
19365              "DTLSv1 Handshake Done"},
19366             {"DTLSv1_2 Handshake Done"
19367              "DTLSv1_2 Handshake Done"
19368              "DTLSv1_2 Handshake Done"}
19369         }
19370     };
19371     enum ProtocolVer {
19372         SSL_V3 = 0,
19373         TLS_V1,
19374         TLS_V1_1,
19375         TLS_V1_2,
19376         DTLS_V1,
19377         DTLS_V1_2,
19378         UNKNOWN = 100
19379     };
19380 
19381     enum IOMode {
19382         SS_READ = 0,
19383         SS_WRITE,
19384         SS_NEITHER
19385     };
19386 
19387     enum SslState {
19388         ss_null_state = 0,
19389         ss_server_helloverify,
19390         ss_server_hello,
19391         ss_sessionticket,
19392         ss_server_cert,
19393         ss_server_keyexchange,
19394         ss_server_hellodone,
19395         ss_server_changecipherspec,
19396         ss_server_finished,
19397         ss_client_hello,
19398         ss_client_keyexchange,
19399         ss_client_changecipherspec,
19400         ss_client_finished,
19401         ss_handshake_done
19402     };
19403 
19404     int protocol = 0;
19405     int cbmode = 0;
19406     int state = 0;
19407 
19408     WOLFSSL_ENTER("wolfSSL_state_string_long");
19409     if (ssl == NULL) {
19410         WOLFSSL_MSG("Null argument passed in");
19411         return NULL;
19412     }
19413 
19414     /* Get state of callback */
19415     if (ssl->cbmode == SSL_CB_MODE_WRITE){
19416         cbmode =  SS_WRITE;
19417     } else if (ssl->cbmode == SSL_CB_MODE_READ){
19418         cbmode =  SS_READ;
19419     } else {
19420         cbmode =  SS_NEITHER;
19421     }
19422 
19423     /* Get protocol version */
19424     switch (ssl->version.major){
19425         case SSLv3_MAJOR:
19426             switch (ssl->version.minor){
19427                 case TLSv1_MINOR:
19428                     protocol = TLS_V1;
19429                     break;
19430                 case TLSv1_1_MINOR:
19431                     protocol = TLS_V1_1;
19432                     break;
19433                 case TLSv1_2_MINOR:
19434                     protocol = TLS_V1_2;
19435                     break;
19436                 case SSLv3_MINOR:
19437                     protocol = SSL_V3;
19438                     break;
19439                 default:
19440                     protocol = UNKNOWN;
19441             }
19442             break;
19443         case DTLS_MAJOR:
19444             switch (ssl->version.minor){
19445         case DTLS_MINOR:
19446             protocol = DTLS_V1;
19447             break;
19448         case DTLSv1_2_MINOR:
19449             protocol = DTLS_V1_2;
19450             break;
19451         default:
19452             protocol = UNKNOWN;
19453     }
19454     break;
19455     default:
19456         protocol = UNKNOWN;
19457     }
19458 
19459     /* accept process */
19460     if (ssl->cbmode == SSL_CB_MODE_READ){
19461         state = ssl->cbtype;
19462         switch (state) {
19463             case hello_verify_request:
19464                 state = ss_server_helloverify;
19465                 break;
19466             case session_ticket:
19467                 state = ss_sessionticket;
19468                 break;
19469             case server_hello:
19470                 state = ss_server_hello;
19471                 break;
19472             case server_hello_done:
19473                 state = ss_server_hellodone;
19474                 break;
19475             case certificate:
19476                 state = ss_server_cert;
19477                 break;
19478             case server_key_exchange:
19479                 state = ss_server_keyexchange;
19480                 break;
19481             case client_hello:
19482                 state = ss_client_hello;
19483                 break;
19484             case client_key_exchange:
19485                 state = ss_client_keyexchange;
19486                 break;
19487             case finished:
19488                 if (ssl->options.side == WOLFSSL_SERVER_END)
19489                     state = ss_client_finished;
19490                 else if (ssl->options.side == WOLFSSL_CLIENT_END)
19491                     state = ss_server_finished;
19492                 break;
19493             default:
19494                 WOLFSSL_MSG("Unknown State");
19495                 state = ss_null_state;
19496         }
19497     } else {
19498         /* Send process */
19499         if (ssl->options.side == WOLFSSL_SERVER_END)
19500             state = ssl->options.serverState;
19501         else
19502             state = ssl->options.clientState;
19503 
19504         switch(state){
19505             case SERVER_HELLOVERIFYREQUEST_COMPLETE:
19506                 state = ss_server_helloverify;
19507                 break;
19508             case SERVER_HELLO_COMPLETE:
19509                 state = ss_server_hello;
19510                 break;
19511             case SERVER_CERT_COMPLETE:
19512                 state = ss_server_cert;
19513                 break;
19514             case SERVER_KEYEXCHANGE_COMPLETE:
19515                 state = ss_server_keyexchange;
19516                 break;
19517             case SERVER_HELLODONE_COMPLETE:
19518                 state = ss_server_hellodone;
19519                 break;
19520             case SERVER_CHANGECIPHERSPEC_COMPLETE:
19521                 state = ss_server_changecipherspec;
19522                 break;
19523             case SERVER_FINISHED_COMPLETE:
19524                 state = ss_server_finished;
19525                 break;
19526             case CLIENT_HELLO_COMPLETE:
19527                 state = ss_client_hello;
19528                 break;
19529             case CLIENT_KEYEXCHANGE_COMPLETE:
19530                 state = ss_client_keyexchange;
19531                 break;
19532             case CLIENT_CHANGECIPHERSPEC_COMPLETE:
19533                 state = ss_client_changecipherspec;
19534                 break;
19535             case CLIENT_FINISHED_COMPLETE:
19536                 state = ss_client_finished;
19537                 break;
19538             case HANDSHAKE_DONE:
19539                 state = ss_handshake_done;
19540                 break;
19541             default:
19542                 WOLFSSL_MSG("Unknown State");
19543                 state = ss_null_state;
19544         }
19545     }
19546 
19547     if (protocol == UNKNOWN)
19548         return NULL;
19549     else
19550         return OUTPUT_STR[state][protocol][cbmode];
19551 }
19552 
19553 #ifndef NO_WOLFSSL_STUB
19554 int wolfSSL_PEM_def_callback(char* name, int num, int w, void* key)
19555 {
19556     (void)name;
19557     (void)num;
19558     (void)w;
19559     (void)key;
19560     WOLFSSL_STUB("PEM_def_callback");
19561     return 0;
19562 }
19563 #endif
19564 
19565 static long wolf_set_options(long old_op, long op)
19566 {
19567     /* if SSL_OP_ALL then turn all bug workarounds on */
19568     if ((op & SSL_OP_ALL) == SSL_OP_ALL) {
19569         WOLFSSL_MSG("\tSSL_OP_ALL");
19570 
19571         op |= SSL_OP_MICROSOFT_SESS_ID_BUG;
19572         op |= SSL_OP_NETSCAPE_CHALLENGE_BUG;
19573         op |= SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
19574         op |= SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG;
19575         op |= SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER;
19576         op |= SSL_OP_MSIE_SSLV2_RSA_PADDING;
19577         op |= SSL_OP_SSLEAY_080_CLIENT_DH_BUG;
19578         op |= SSL_OP_TLS_D5_BUG;
19579         op |= SSL_OP_TLS_BLOCK_PADDING_BUG;
19580         op |= SSL_OP_TLS_ROLLBACK_BUG;
19581         op |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
19582     }
19583 
19584     /* by default cookie exchange is on with DTLS */
19585     if ((op & SSL_OP_COOKIE_EXCHANGE) == SSL_OP_COOKIE_EXCHANGE) {
19586         WOLFSSL_MSG("\tSSL_OP_COOKIE_EXCHANGE : on by default");
19587     }
19588 
19589     if ((op & WOLFSSL_OP_NO_SSLv2) == WOLFSSL_OP_NO_SSLv2) {
19590         WOLFSSL_MSG("\tWOLFSSL_OP_NO_SSLv2 : wolfSSL does not support SSLv2");
19591     }
19592 
19593     if ((op & SSL_OP_NO_TLSv1_3) == SSL_OP_NO_TLSv1_3) {
19594         WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_3");
19595     }
19596 
19597     if ((op & SSL_OP_NO_TLSv1_2) == SSL_OP_NO_TLSv1_2) {
19598         WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_2");
19599     }
19600 
19601     if ((op & SSL_OP_NO_TLSv1_1) == SSL_OP_NO_TLSv1_1) {
19602         WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_1");
19603     }
19604 
19605     if ((op & SSL_OP_NO_TLSv1) == SSL_OP_NO_TLSv1) {
19606         WOLFSSL_MSG("\tSSL_OP_NO_TLSv1");
19607     }
19608 
19609     if ((op & SSL_OP_NO_SSLv3) == SSL_OP_NO_SSLv3) {
19610         WOLFSSL_MSG("\tSSL_OP_NO_SSLv3");
19611     }
19612 
19613     if ((op & SSL_OP_NO_COMPRESSION) == SSL_OP_NO_COMPRESSION) {
19614     #ifdef HAVE_LIBZ
19615         WOLFSSL_MSG("SSL_OP_NO_COMPRESSION");
19616     #else
19617         WOLFSSL_MSG("SSL_OP_NO_COMPRESSION: compression not compiled in");
19618     #endif
19619     }
19620 
19621     return old_op | op;
19622 }
19623 
19624 long wolfSSL_set_options(WOLFSSL* ssl, long op)
19625 {
19626     word16 haveRSA = 1;
19627     word16 havePSK = 0;
19628     int    keySz   = 0;
19629 
19630     WOLFSSL_ENTER("wolfSSL_set_options");
19631 
19632     if (ssl == NULL) {
19633         return 0;
19634     }
19635 
19636     ssl->options.mask = wolf_set_options(ssl->options.mask, op);
19637 
19638     if ((ssl->options.mask & SSL_OP_NO_TLSv1_3) == SSL_OP_NO_TLSv1_3) {
19639         if (ssl->version.minor == TLSv1_3_MINOR)
19640             ssl->version.minor = TLSv1_2_MINOR;
19641     }
19642 
19643     if ((ssl->options.mask & SSL_OP_NO_TLSv1_2) == SSL_OP_NO_TLSv1_2) {
19644         if (ssl->version.minor == TLSv1_2_MINOR)
19645             ssl->version.minor = TLSv1_1_MINOR;
19646     }
19647 
19648     if ((ssl->options.mask & SSL_OP_NO_TLSv1_1) == SSL_OP_NO_TLSv1_1) {
19649         if (ssl->version.minor == TLSv1_1_MINOR)
19650             ssl->version.minor = TLSv1_MINOR;
19651     }
19652 
19653     if ((ssl->options.mask & SSL_OP_NO_TLSv1) == SSL_OP_NO_TLSv1) {
19654         if (ssl->version.minor == TLSv1_MINOR)
19655             ssl->version.minor = SSLv3_MINOR;
19656     }
19657 
19658     if ((ssl->options.mask & SSL_OP_NO_COMPRESSION) == SSL_OP_NO_COMPRESSION) {
19659     #ifdef HAVE_LIBZ
19660         ssl->options.usingCompression = 0;
19661     #endif
19662     }
19663 
19664     /* in the case of a version change the cipher suites should be reset */
19665 #ifndef NO_PSK
19666     havePSK = ssl->options.havePSK;
19667 #endif
19668 #ifdef NO_RSA
19669     haveRSA = 0;
19670 #endif
19671 #ifndef NO_CERTS
19672     keySz = ssl->buffers.keySz;
19673 #endif
19674 
19675     InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
19676                        ssl->options.haveDH, ssl->options.haveNTRU,
19677                        ssl->options.haveECDSAsig, ssl->options.haveECC,
19678                        ssl->options.haveStaticECC, ssl->options.side);
19679 
19680     return ssl->options.mask;
19681 }
19682 
19683 
19684 long wolfSSL_get_options(const WOLFSSL* ssl)
19685 {
19686     WOLFSSL_ENTER("wolfSSL_get_options");
19687     if(ssl == NULL)
19688         return WOLFSSL_FAILURE;
19689     return ssl->options.mask;
19690 }
19691 
19692 long wolfSSL_clear_options(WOLFSSL* ssl, long opt)
19693 {
19694     WOLFSSL_ENTER("SSL_clear_options");
19695     if(ssl == NULL)
19696         return WOLFSSL_FAILURE;
19697     ssl->options.mask &= ~opt;
19698     return ssl->options.mask;
19699 }
19700 
19701 /*** TBD ***/
19702 #ifndef NO_WOLFSSL_STUB
19703 WOLFSSL_API long wolfSSL_clear_num_renegotiations(WOLFSSL *s)
19704 {
19705     (void)s;
19706     WOLFSSL_STUB("SSL_clear_num_renegotiations");
19707     return 0;
19708 }
19709 #endif
19710 
19711 /*** TBD ***/
19712 #ifndef NO_WOLFSSL_STUB
19713 WOLFSSL_API long wolfSSL_total_renegotiations(WOLFSSL *s)
19714 {
19715     (void)s;
19716     WOLFSSL_STUB("SSL_total_renegotiations");
19717     return 0;
19718 }
19719 #endif
19720 
19721 #ifndef NO_DH
19722 long wolfSSL_set_tmp_dh(WOLFSSL *ssl, WOLFSSL_DH *dh)
19723 {
19724     int pSz, gSz;
19725     byte *p, *g;
19726     int ret = 0;
19727 
19728     WOLFSSL_ENTER("wolfSSL_set_tmp_dh");
19729 
19730     if (!ssl || !dh)
19731         return BAD_FUNC_ARG;
19732 
19733     /* Get needed size for p and g */
19734     pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
19735     gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
19736 
19737     if (pSz <= 0 || gSz <= 0)
19738         return WOLFSSL_FATAL_ERROR;
19739 
19740     p = (byte*)XMALLOC(pSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
19741     if (!p)
19742         return MEMORY_E;
19743 
19744     g = (byte*)XMALLOC(gSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
19745     if (!g) {
19746         XFREE(p, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
19747         return MEMORY_E;
19748     }
19749 
19750     pSz = wolfSSL_BN_bn2bin(dh->p, p);
19751     gSz = wolfSSL_BN_bn2bin(dh->g, g);
19752 
19753     if (pSz >= 0 && gSz >= 0) /* Conversion successful */
19754         ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
19755 
19756     XFREE(p, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
19757     XFREE(g, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
19758 
19759     return pSz > 0 && gSz > 0 ? ret : WOLFSSL_FATAL_ERROR;
19760 }
19761 #endif /* !NO_DH */
19762 
19763 
19764 #ifdef HAVE_PK_CALLBACKS
19765 long wolfSSL_set_tlsext_debug_arg(WOLFSSL* ssl, void *arg)
19766 {
19767     if (ssl == NULL) {
19768         return WOLFSSL_FAILURE;
19769     }
19770 
19771     ssl->loggingCtx = arg;
19772     return WOLFSSL_SUCCESS;
19773 }
19774 #endif /* HAVE_PK_CALLBACKS */
19775 
19776 #if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)
19777 const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *sess, unsigned int *sid_ctx_length)
19778 {
19779     const byte *c = wolfSSL_SESSION_get_id((SSL_SESSION *)sess, sid_ctx_length);
19780     return c;
19781 }
19782 #endif
19783 
19784 /*** TBD ***/
19785 #ifndef NO_WOLFSSL_STUB
19786 WOLFSSL_API int wolfSSL_sk_SSL_COMP_zero(WOLFSSL_STACK* st)
19787 {
19788     (void)st;
19789     WOLFSSL_STUB("wolfSSL_sk_SSL_COMP_zero");
19790     /* wolfSSL_set_options(ssl, SSL_OP_NO_COMPRESSION); */
19791     return WOLFSSL_FAILURE;
19792 }
19793 #endif
19794 
19795 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
19796 long wolfSSL_set_tlsext_status_type(WOLFSSL *s, int type)
19797 {
19798     WOLFSSL_ENTER("wolfSSL_set_tlsext_status_type");
19799 
19800     if (s == NULL){
19801         return BAD_FUNC_ARG;
19802     }
19803 
19804     if (type == TLSEXT_STATUSTYPE_ocsp){
19805         int r = 0;
19806         r = TLSX_UseCertificateStatusRequest(&s->extensions, type, 0, s,
19807                                                              s->heap, s->devId);
19808         return (long)r;
19809     } else {
19810         WOLFSSL_MSG(
19811        "SSL_set_tlsext_status_type only supports TLSEXT_STATUSTYPE_ocsp type.");
19812         return SSL_FAILURE;
19813     }
19814 
19815 }
19816 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
19817 
19818 #ifndef NO_WOLFSSL_STUB
19819 WOLFSSL_API long wolfSSL_get_tlsext_status_exts(WOLFSSL *s, void *arg)
19820 {
19821     (void)s;
19822     (void)arg;
19823     WOLFSSL_STUB("wolfSSL_get_tlsext_status_exts");
19824     return WOLFSSL_FAILURE;
19825 }
19826 #endif
19827 
19828 /*** TBD ***/
19829 #ifndef NO_WOLFSSL_STUB
19830 WOLFSSL_API long wolfSSL_set_tlsext_status_exts(WOLFSSL *s, void *arg)
19831 {
19832     (void)s;
19833     (void)arg;
19834     WOLFSSL_STUB("wolfSSL_set_tlsext_status_exts");
19835     return WOLFSSL_FAILURE;
19836 }
19837 #endif
19838 
19839 /*** TBD ***/
19840 #ifndef NO_WOLFSSL_STUB
19841 WOLFSSL_API long wolfSSL_get_tlsext_status_ids(WOLFSSL *s, void *arg)
19842 {
19843     (void)s;
19844     (void)arg;
19845     WOLFSSL_STUB("wolfSSL_get_tlsext_status_ids");
19846     return WOLFSSL_FAILURE;
19847 }
19848 #endif
19849 
19850 /*** TBD ***/
19851 #ifndef NO_WOLFSSL_STUB
19852 WOLFSSL_API long wolfSSL_set_tlsext_status_ids(WOLFSSL *s, void *arg)
19853 {
19854     (void)s;
19855     (void)arg;
19856     WOLFSSL_STUB("wolfSSL_set_tlsext_status_ids");
19857     return WOLFSSL_FAILURE;
19858 }
19859 #endif
19860 
19861 /*** TBD ***/
19862 #ifndef NO_WOLFSSL_STUB
19863 WOLFSSL_API int SSL_SESSION_set1_id(WOLFSSL_SESSION *s, const unsigned char *sid, unsigned int sid_len)
19864 {
19865     (void)s;
19866     (void)sid;
19867     (void)sid_len;
19868     WOLFSSL_STUB("SSL_SESSION_set1_id");
19869     return WOLFSSL_FAILURE;
19870 }
19871 #endif
19872 
19873 #ifndef NO_WOLFSSL_STUB
19874 /*** TBD ***/
19875 WOLFSSL_API int SSL_SESSION_set1_id_context(WOLFSSL_SESSION *s, const unsigned char *sid_ctx, unsigned int sid_ctx_len)
19876 {
19877     (void)s;
19878     (void)sid_ctx;
19879     (void)sid_ctx_len;
19880     WOLFSSL_STUB("SSL_SESSION_set1_id_context");
19881     return WOLFSSL_FAILURE;
19882 }
19883 #endif
19884 
19885 #ifndef NO_WOLFSSL_STUB
19886 /*** TBD ***/
19887 WOLFSSL_API void *X509_get0_tbs_sigalg(const WOLFSSL_X509 *x)
19888 {
19889     (void)x;
19890     WOLFSSL_STUB("X509_get0_tbs_sigalg");
19891     return NULL;
19892 }
19893 #endif
19894 
19895 #ifndef NO_WOLFSSL_STUB
19896 /*** TBD ***/
19897 WOLFSSL_API void X509_ALGOR_get0(WOLFSSL_ASN1_OBJECT **paobj, int *pptype, const void **ppval, const void *algor)
19898 {
19899     (void)paobj;
19900     (void)pptype;
19901     (void)ppval;
19902     (void)algor;
19903     WOLFSSL_STUB("X509_ALGOR_get0");
19904 }
19905 #endif
19906 
19907 #ifndef NO_WOLFSSL_STUB
19908 /*** TBD ***/
19909 WOLFSSL_API void *X509_get_X509_PUBKEY(void * x)
19910 {
19911     (void)x;
19912     WOLFSSL_STUB("X509_get_X509_PUBKEY");
19913     return NULL;
19914 }
19915 #endif
19916 
19917 #ifndef NO_WOLFSSL_STUB
19918 /*** TBD ***/
19919 WOLFSSL_API int X509_PUBKEY_get0_param(WOLFSSL_ASN1_OBJECT **ppkalg, const unsigned char **pk, int *ppklen, void **pa, WOLFSSL_EVP_PKEY *pub)
19920 {
19921     (void)ppkalg;
19922     (void)pk;
19923     (void)ppklen;
19924     (void)pa;
19925     (void)pub;
19926     WOLFSSL_STUB("X509_PUBKEY_get0_param");
19927     return WOLFSSL_FAILURE;
19928 }
19929 #endif
19930 
19931 #ifndef NO_WOLFSSL_STUB
19932 /*** TBD ***/
19933 WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_get_privatekey(const WOLFSSL *ssl)
19934 {
19935     (void)ssl;
19936     WOLFSSL_STUB("SSL_get_privatekey");
19937     return NULL;
19938 }
19939 #endif
19940 
19941 #ifndef NO_WOLFSSL_STUB
19942 /*** TBD ***/
19943 WOLFSSL_API int i2t_ASN1_OBJECT(char *buf, int buf_len, WOLFSSL_ASN1_OBJECT *a)
19944 {
19945     (void)buf;
19946     (void)buf_len;
19947     (void)a;
19948     WOLFSSL_STUB("i2t_ASN1_OBJECT");
19949     return -1;
19950 }
19951 #endif
19952 
19953 #if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)
19954 #ifndef NO_WOLFSSL_STUB
19955 /*** TBD ***/
19956 WOLFSSL_API size_t SSL_get_finished(const WOLFSSL *s, void *buf, size_t count)
19957 {
19958     (void)s;
19959     (void)buf;
19960     (void)count;
19961     WOLFSSL_STUB("SSL_get_finished");
19962     return WOLFSSL_FAILURE;
19963 }
19964 #endif
19965 
19966 #ifndef NO_WOLFSSL_STUB
19967 /*** TBD ***/
19968 WOLFSSL_API size_t SSL_get_peer_finished(const WOLFSSL *s, void *buf, size_t count)
19969 {
19970     (void)s;
19971     (void)buf;
19972     (void)count;
19973     WOLFSSL_STUB("SSL_get_peer_finished");
19974     return WOLFSSL_FAILURE;
19975 }
19976 #endif
19977 #endif /* WOLFSSL_HAPROXY */
19978 
19979 #ifndef NO_WOLFSSL_STUB
19980 /*** TBD ***/
19981 WOLFSSL_API void SSL_CTX_set_tmp_dh_callback(WOLFSSL_CTX *ctx, WOLFSSL_DH *(*dh) (WOLFSSL *ssl, int is_export, int keylength))
19982 {
19983     (void)ctx;
19984     (void)dh;
19985     WOLFSSL_STUB("SSL_CTX_set_tmp_dh_callback");
19986 }
19987 #endif
19988 
19989 #ifndef NO_WOLFSSL_STUB
19990 /*** TBD ***/
19991 WOLFSSL_API WOLF_STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
19992 {
19993     WOLFSSL_STUB("SSL_COMP_get_compression_methods");
19994     return NULL;
19995 }
19996 #endif
19997 
19998 #ifndef NO_WOLFSSL_STUB
19999 /*** TBD ***/
20000 WOLFSSL_API int wolfSSL_sk_SSL_CIPHER_num(const void * p)
20001 {
20002     (void)p;
20003     WOLFSSL_STUB("wolfSSL_sk_SSL_CIPHER_num");
20004     return -1;
20005 }
20006 #endif
20007 
20008 #if !defined(NO_FILESYSTEM)
20009 #ifndef NO_WOLFSSL_STUB
20010 /*** TBD ***/
20011 WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_X509(FILE *fp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u)
20012 {
20013     (void)fp;
20014     (void)x;
20015     (void)cb;
20016     (void)u;
20017     WOLFSSL_STUB("PEM_read_X509");
20018     return NULL;
20019 }
20020 #endif
20021 
20022 #ifndef NO_WOLFSSL_STUB
20023 /*** TBD ***/
20024 WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PrivateKey(FILE *fp, WOLFSSL_EVP_PKEY **x, pem_password_cb *cb, void *u)
20025 {
20026     (void)fp;
20027     (void)x;
20028     (void)cb;
20029     (void)u;
20030     WOLFSSL_STUB("PEM_read_PrivateKey");
20031     return NULL;
20032 }
20033 #endif
20034 #endif
20035 
20036 #ifndef NO_WOLFSSL_STUB
20037 /*** TBD ***/
20038 WOLFSSL_API int X509_STORE_load_locations(WOLFSSL_X509_STORE *ctx, const char *file, const char *dir)
20039 {
20040     (void)ctx;
20041     (void)file;
20042     (void)dir;
20043     WOLFSSL_STUB("X509_STORE_load_locations");
20044     return WOLFSSL_FAILURE;
20045 }
20046 #endif
20047 
20048 #ifndef NO_WOLFSSL_STUB
20049 /*** TBD ***/
20050 WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_value(void *ciphers, int idx)
20051 {
20052     (void)ciphers;
20053     (void)idx;
20054     WOLFSSL_STUB("wolfSSL_sk_SSL_CIPHER_value");
20055     return NULL;
20056 }
20057 #endif
20058 
20059 WOLFSSL_API void ERR_load_SSL_strings(void)
20060 {
20061 
20062 }
20063 
20064 #ifdef HAVE_OCSP
20065 WOLFSSL_API long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char **resp)
20066 {
20067     if (s == NULL || resp == NULL)
20068         return 0;
20069 
20070     *resp = s->ocspResp;
20071     return s->ocspRespSz;
20072 }
20073 
20074 WOLFSSL_API long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char *resp, int len)
20075 {
20076     if (s == NULL)
20077         return WOLFSSL_FAILURE;
20078 
20079     s->ocspResp   = resp;
20080     s->ocspRespSz = len;
20081 
20082     return WOLFSSL_SUCCESS;
20083 }
20084 #endif /* HAVE_OCSP */
20085 
20086 long wolfSSL_get_verify_result(const WOLFSSL *ssl)
20087 {
20088     if (ssl == NULL) {
20089         return WOLFSSL_FAILURE;
20090     }
20091 
20092     return ssl->peerVerifyRet;
20093 }
20094 
20095 
20096 #ifndef NO_WOLFSSL_STUB
20097 /* shows the number of accepts attempted by CTX in it's lifetime */
20098 long wolfSSL_CTX_sess_accept(WOLFSSL_CTX* ctx)
20099 {
20100     WOLFSSL_STUB("wolfSSL_CTX_sess_accept");
20101     (void)ctx;
20102     return 0;
20103 }
20104 #endif
20105 
20106 #ifndef NO_WOLFSSL_STUB
20107 /* shows the number of connects attempted CTX in it's lifetime */
20108 long wolfSSL_CTX_sess_connect(WOLFSSL_CTX* ctx)
20109 {
20110     WOLFSSL_STUB("wolfSSL_CTX_sess_connect");
20111     (void)ctx;
20112     return 0;
20113 }
20114 #endif
20115 
20116 
20117 #ifndef NO_WOLFSSL_STUB
20118 /* shows the number of accepts completed by CTX in it's lifetime */
20119 long wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX* ctx)
20120 {
20121     WOLFSSL_STUB("wolfSSL_CTX_sess_accept_good");
20122     (void)ctx;
20123     return 0;
20124 }
20125 #endif
20126 
20127 
20128 #ifndef NO_WOLFSSL_STUB
20129 /* shows the number of connects completed by CTX in it's lifetime */
20130 long wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX* ctx)
20131 {
20132     WOLFSSL_STUB("wolfSSL_CTX_sess_connect_good");
20133     (void)ctx;
20134     return 0;
20135 }
20136 #endif
20137 
20138 
20139 #ifndef NO_WOLFSSL_STUB
20140 /* shows the number of renegotiation accepts attempted by CTX */
20141 long wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX* ctx)
20142 {
20143     WOLFSSL_STUB("wolfSSL_CTX_sess_accept_renegotiate");
20144     (void)ctx;
20145     return 0;
20146 }
20147 #endif
20148 
20149 
20150 #ifndef NO_WOLFSSL_STUB
20151 /* shows the number of renegotiation accepts attempted by CTX */
20152 long wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX* ctx)
20153 {
20154     WOLFSSL_STUB("wolfSSL_CTX_sess_connect_renegotiate");
20155     (void)ctx;
20156     return 0;
20157 }
20158 #endif
20159 
20160 
20161 #ifndef NO_WOLFSSL_STUB
20162 long wolfSSL_CTX_sess_hits(WOLFSSL_CTX* ctx)
20163 {
20164     WOLFSSL_STUB("wolfSSL_CTX_sess_hits");
20165     (void)ctx;
20166     return 0;
20167 }
20168 #endif
20169 
20170 
20171 #ifndef NO_WOLFSSL_STUB
20172 long wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX* ctx)
20173 {
20174     WOLFSSL_STUB("wolfSSL_CTX_sess_cb_hits");
20175     (void)ctx;
20176     return 0;
20177 }
20178 #endif
20179 
20180 
20181 #ifndef NO_WOLFSSL_STUB
20182 long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX* ctx)
20183 {
20184     WOLFSSL_STUB("wolfSSL_CTX_sess_cache_full");
20185     (void)ctx;
20186     return 0;
20187 }
20188 #endif
20189 
20190 
20191 #ifndef NO_WOLFSSL_STUB
20192 long wolfSSL_CTX_sess_misses(WOLFSSL_CTX* ctx)
20193 {
20194     WOLFSSL_STUB("wolfSSL_CTX_sess_misses");
20195     (void)ctx;
20196     return 0;
20197 }
20198 #endif
20199 
20200 
20201 #ifndef NO_WOLFSSL_STUB
20202 long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX* ctx)
20203 {
20204     WOLFSSL_STUB("wolfSSL_CTX_sess_timeouts");
20205     (void)ctx;
20206     return 0;
20207 }
20208 #endif
20209 
20210 
20211 /* Return the total number of sessions */
20212 long wolfSSL_CTX_sess_number(WOLFSSL_CTX* ctx)
20213 {
20214     word32 total = 0;
20215 
20216     WOLFSSL_ENTER("wolfSSL_CTX_sess_number");
20217     (void)ctx;
20218 
20219 #ifdef WOLFSSL_SESSION_STATS
20220     if (wolfSSL_get_session_stats(NULL, &total, NULL, NULL) != SSL_SUCCESS) {
20221         WOLFSSL_MSG("Error getting session stats");
20222     }
20223 #else
20224     WOLFSSL_MSG("Please use macro WOLFSSL_SESSION_STATS for session stats");
20225 #endif
20226 
20227     return (long)total;
20228 }
20229 
20230 
20231 #ifndef NO_CERTS
20232 long wolfSSL_CTX_add_extra_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
20233 {
20234     byte* chain = NULL;
20235     long  chainSz = 0;
20236     int   derSz;
20237     const byte* der;
20238     int   ret;
20239     int   idx = 0;
20240     DerBuffer *derBuffer = NULL;
20241 
20242     WOLFSSL_ENTER("wolfSSL_CTX_add_extra_chain_cert");
20243 
20244     if (ctx == NULL || x509 == NULL) {
20245         WOLFSSL_MSG("Bad Argument");
20246         return WOLFSSL_FAILURE;
20247     }
20248 
20249     der = wolfSSL_X509_get_der(x509, &derSz);
20250     if (der == NULL || derSz <= 0) {
20251         WOLFSSL_MSG("Error getting X509 DER");
20252         return WOLFSSL_FAILURE;
20253     }
20254 
20255     if (ctx->certificate == NULL) {
20256         /* Process buffer makes first certificate the leaf. */
20257         ret = ProcessBuffer(ctx, der, derSz, WOLFSSL_FILETYPE_ASN1, CERT_TYPE,
20258                             NULL, NULL, 1);
20259         if (ret != WOLFSSL_SUCCESS) {
20260             WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret);
20261             return WOLFSSL_FAILURE;
20262         }
20263     }
20264     else {
20265         /* TODO: Do this elsewhere. */
20266         ret = AllocDer(&derBuffer, derSz, CERT_TYPE, ctx->heap);
20267         if (ret != 0) {
20268             WOLFSSL_MSG("Memory Error");
20269             return WOLFSSL_FAILURE;
20270         }
20271         XMEMCPY(derBuffer->buffer, der, derSz);
20272         ret = AddCA(ctx->cm, &derBuffer, WOLFSSL_USER_CA, !ctx->verifyNone);
20273         if (ret != WOLFSSL_SUCCESS) {
20274             WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret);
20275             return WOLFSSL_FAILURE;
20276         }
20277 
20278         /* adding cert to existing chain */
20279         if (ctx->certChain != NULL && ctx->certChain->length > 0) {
20280             chainSz += ctx->certChain->length;
20281         }
20282         chainSz += OPAQUE24_LEN + derSz;
20283 
20284         chain = (byte*)XMALLOC(chainSz, ctx->heap, DYNAMIC_TYPE_DER);
20285         if (chain == NULL) {
20286             WOLFSSL_MSG("Memory Error");
20287             return WOLFSSL_FAILURE;
20288         }
20289 
20290         if (ctx->certChain != NULL && ctx->certChain->length > 0) {
20291             XMEMCPY(chain, ctx->certChain->buffer, ctx->certChain->length);
20292             idx = ctx->certChain->length;
20293         }
20294         c32to24(derSz, chain + idx);
20295         idx += OPAQUE24_LEN,
20296         XMEMCPY(chain + idx, der, derSz);
20297         idx += derSz;
20298 #ifdef WOLFSSL_TLS13
20299         ctx->certChainCnt++;
20300 #endif
20301 
20302         FreeDer(&ctx->certChain);
20303         ret = AllocDer(&ctx->certChain, idx, CERT_TYPE, ctx->heap);
20304         if (ret == 0) {
20305             XMEMCPY(ctx->certChain->buffer, chain, idx);
20306         }
20307     }
20308 
20309     /* on success WOLFSSL_X509 memory is responsibility of ctx */
20310     wolfSSL_X509_free(x509);
20311     if (chain != NULL)
20312         XFREE(chain, ctx->heap, DYNAMIC_TYPE_DER);
20313 
20314     return WOLFSSL_SUCCESS;
20315 }
20316 
20317 
20318 long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX* ctx, void* arg)
20319 {
20320     if (ctx == NULL || ctx->cm == NULL) {
20321         return WOLFSSL_FAILURE;
20322     }
20323 
20324     ctx->cm->ocspIOCtx = arg;
20325     return WOLFSSL_SUCCESS;
20326 }
20327 
20328 #endif /* NO_CERTS */
20329 
20330 
20331 /* Get the session cache mode for CTX
20332  *
20333  * ctx  WOLFSSL_CTX struct to get cache mode from
20334  *
20335  * Returns a bit mask that has the session cache mode */
20336 WOLFSSL_API long wolfSSL_CTX_get_session_cache_mode(WOLFSSL_CTX* ctx)
20337 {
20338     long m = 0;
20339 
20340     WOLFSSL_ENTER("SSL_CTX_set_session_cache_mode");
20341 
20342     if (ctx == NULL) {
20343         return m;
20344     }
20345 
20346     if (ctx->sessionCacheOff != 1) {
20347         m |= SSL_SESS_CACHE_SERVER;
20348     }
20349 
20350     if (ctx->sessionCacheFlushOff == 1) {
20351         m |= SSL_SESS_CACHE_NO_AUTO_CLEAR;
20352     }
20353 
20354 #ifdef HAVE_EXT_CACHE
20355     if (ctx->internalCacheOff == 1) {
20356         m |= SSL_SESS_CACHE_NO_INTERNAL_STORE;
20357     }
20358 #endif
20359 
20360     return m;
20361 }
20362 
20363 
20364 int wolfSSL_CTX_get_read_ahead(WOLFSSL_CTX* ctx)
20365 {
20366     if (ctx == NULL) {
20367         return WOLFSSL_FAILURE;
20368     }
20369 
20370     return ctx->readAhead;
20371 }
20372 
20373 
20374 int wolfSSL_CTX_set_read_ahead(WOLFSSL_CTX* ctx, int v)
20375 {
20376     if (ctx == NULL) {
20377         return WOLFSSL_FAILURE;
20378     }
20379 
20380     ctx->readAhead = (byte)v;
20381 
20382     return WOLFSSL_SUCCESS;
20383 }
20384 
20385 
20386 long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg(WOLFSSL_CTX* ctx,
20387         void* arg)
20388 {
20389     if (ctx == NULL) {
20390         return WOLFSSL_FAILURE;
20391     }
20392 
20393     ctx->userPRFArg = arg;
20394     return WOLFSSL_SUCCESS;
20395 }
20396 
20397 
20398 #ifndef NO_DES3
20399 /* 0 on success */
20400 int wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* myDes,
20401                                                WOLFSSL_DES_key_schedule* key)
20402 {
20403 #ifdef WOLFSSL_CHECK_DESKEY
20404     return wolfSSL_DES_set_key_checked(myDes, key);
20405 #else
20406     wolfSSL_DES_set_key_unchecked(myDes, key);
20407     return 0;
20408 #endif
20409 }
20410 
20411 
20412 
20413 /* return true in fail case (1) */
20414 static int DES_check(word32 mask, word32 mask2, unsigned char* key)
20415 {
20416     word32 value[2];
20417 
20418     /* sanity check on length made in wolfSSL_DES_set_key_checked */
20419     value[0] = mask;
20420     value[1] = mask2;
20421     return (XMEMCMP(value, key, sizeof(value)) == 0)? 1: 0;
20422 }
20423 
20424 
20425 /* check that the key is odd parity and is not a weak key
20426  * returns -1 if parity is wrong, -2 if weak/null key and 0 on success */
20427 int wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes,
20428                                                WOLFSSL_DES_key_schedule* key)
20429 {
20430     if (myDes == NULL || key == NULL) {
20431         WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_set_key_checked");
20432         return -2;
20433     }
20434     else {
20435         word32 i;
20436         word32 sz = sizeof(WOLFSSL_DES_key_schedule);
20437 
20438         /* sanity check before call to DES_check */
20439         if (sz != (sizeof(word32) * 2)) {
20440             WOLFSSL_MSG("Unexpected WOLFSSL_DES_key_schedule size");
20441             return -2;
20442         }
20443 
20444         /* check odd parity */
20445         for (i = 0; i < sz; i++) {
20446             unsigned char c = *((unsigned char*)myDes + i);
20447             if (((c & 0x01) ^
20448                 ((c >> 1) & 0x01) ^
20449                 ((c >> 2) & 0x01) ^
20450                 ((c >> 3) & 0x01) ^
20451                 ((c >> 4) & 0x01) ^
20452                 ((c >> 5) & 0x01) ^
20453                 ((c >> 6) & 0x01) ^
20454                 ((c >> 7) & 0x01)) != 1) {
20455                 WOLFSSL_MSG("Odd parity test fail");
20456                 return -1;
20457             }
20458         }
20459 
20460         if (wolfSSL_DES_is_weak_key(myDes) == 1) {
20461             WOLFSSL_MSG("Weak key found");
20462             return -2;
20463         }
20464 
20465         /* passed tests, now copy over key */
20466         XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock));
20467 
20468         return 0;
20469     }
20470 }
20471 
20472 
20473 /* check is not weak. Weak key list from Nist "Recommendation for the Triple
20474  * Data Encryption Algorithm (TDEA) Block Cipher"
20475  *
20476  * returns 1 if is weak 0 if not
20477  */
20478 int wolfSSL_DES_is_weak_key(WOLFSSL_const_DES_cblock* key)
20479 {
20480     word32 mask, mask2;
20481 
20482     WOLFSSL_ENTER("wolfSSL_DES_is_weak_key");
20483 
20484     if (key == NULL) {
20485         WOLFSSL_MSG("NULL key passed in");
20486         return 1;
20487     }
20488 
20489     mask = 0x01010101; mask2 = 0x01010101;
20490     if (DES_check(mask, mask2, *key)) {
20491         WOLFSSL_MSG("Weak key found");
20492         return 1;
20493     }
20494 
20495     mask = 0xFEFEFEFE; mask2 = 0xFEFEFEFE;
20496     if (DES_check(mask, mask2, *key)) {
20497         WOLFSSL_MSG("Weak key found");
20498         return 1;
20499     }
20500 
20501     mask = 0xE0E0E0E0; mask2 = 0xF1F1F1F1;
20502     if (DES_check(mask, mask2, *key)) {
20503         WOLFSSL_MSG("Weak key found");
20504         return 1;
20505     }
20506 
20507     mask = 0x1F1F1F1F; mask2 = 0x0E0E0E0E;
20508     if (DES_check(mask, mask2, *key)) {
20509         WOLFSSL_MSG("Weak key found");
20510         return 1;
20511     }
20512 
20513     /* semi-weak *key check (list from same Nist paper) */
20514     mask  = 0x011F011F; mask2 = 0x010E010E;
20515     if (DES_check(mask, mask2, *key) ||
20516        DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
20517         WOLFSSL_MSG("Weak key found");
20518         return 1;
20519     }
20520 
20521     mask  = 0x01E001E0; mask2 = 0x01F101F1;
20522     if (DES_check(mask, mask2, *key) ||
20523        DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
20524         WOLFSSL_MSG("Weak key found");
20525         return 1;
20526     }
20527 
20528     mask  = 0x01FE01FE; mask2 = 0x01FE01FE;
20529     if (DES_check(mask, mask2, *key) ||
20530        DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
20531         WOLFSSL_MSG("Weak key found");
20532         return 1;
20533     }
20534 
20535     mask  = 0x1FE01FE0; mask2 = 0x0EF10EF1;
20536     if (DES_check(mask, mask2, *key) ||
20537        DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
20538         WOLFSSL_MSG("Weak key found");
20539         return 1;
20540     }
20541 
20542     mask  = 0x1FFE1FFE; mask2 = 0x0EFE0EFE;
20543     if (DES_check(mask, mask2, *key) ||
20544        DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
20545         WOLFSSL_MSG("Weak key found");
20546         return 1;
20547     }
20548 
20549     return 0;
20550 }
20551 
20552 
20553 void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock* myDes,
20554                                                WOLFSSL_DES_key_schedule* key)
20555 {
20556     if (myDes != NULL && key != NULL) {
20557         XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock));
20558     }
20559 }
20560 
20561 
20562 /* Sets the parity of the DES key for use */
20563 void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* myDes)
20564 {
20565     word32 i;
20566     word32 sz = sizeof(WOLFSSL_DES_cblock);
20567 
20568     WOLFSSL_ENTER("wolfSSL_DES_set_odd_parity");
20569 
20570     for (i = 0; i < sz; i++) {
20571         unsigned char c = *((unsigned char*)myDes + i);
20572         if ((
20573             ((c >> 1) & 0x01) ^
20574             ((c >> 2) & 0x01) ^
20575             ((c >> 3) & 0x01) ^
20576             ((c >> 4) & 0x01) ^
20577             ((c >> 5) & 0x01) ^
20578             ((c >> 6) & 0x01) ^
20579             ((c >> 7) & 0x01)) != 1) {
20580             WOLFSSL_MSG("Setting odd parity bit");
20581             *((unsigned char*)myDes + i) = *((unsigned char*)myDes + i) | 0x01;
20582         }
20583     }
20584 }
20585 
20586 
20587 #ifdef WOLFSSL_DES_ECB
20588 /* Encrpyt or decrypt input message desa with key and get output in desb.
20589  * if enc is DES_ENCRYPT,input message is encrypted or
20590  * if enc is DES_DECRYPT,input message is decrypted.
20591  * */
20592 void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* desa,
20593              WOLFSSL_DES_cblock* desb, WOLFSSL_DES_key_schedule* key, int enc)
20594 {
20595     Des myDes;
20596 
20597     WOLFSSL_ENTER("wolfSSL_DES_ecb_encrypt");
20598 
20599     if (desa == NULL || key == NULL || desb == NULL ||
20600         (enc != DES_ENCRYPT && enc != DES_DECRYPT)) {
20601         WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_ecb_encrypt");
20602     } else {
20603         if (wc_Des_SetKey(&myDes, (const byte*) key,
20604                            (const byte*) NULL, !enc) != 0) {
20605             WOLFSSL_MSG("wc_Des_SetKey return error.");
20606             return;
20607         }
20608         if (enc){
20609             if (wc_Des_EcbEncrypt(&myDes, (byte*) desb, (const byte*) desa,
20610                         sizeof(WOLFSSL_DES_cblock)) != 0){
20611                 WOLFSSL_MSG("wc_Des_EcbEncrpyt return error.");
20612             }
20613         } else {
20614             if (wc_Des_EcbDecrypt(&myDes, (byte*) desb, (const byte*) desa,
20615                         sizeof(WOLFSSL_DES_cblock)) != 0){
20616                 WOLFSSL_MSG("wc_Des_EcbDecrpyt return error.");
20617             }
20618         }
20619     }
20620 }
20621 #endif
20622 
20623 #endif /* NO_DES3 */
20624 
20625 #ifndef NO_RC4
20626 /* Set the key state for Arc4 structure.
20627  *
20628  * key  Arc4 structure to use
20629  * len  length of data buffer
20630  * data initial state to set Arc4 structure
20631  */
20632 void wolfSSL_RC4_set_key(WOLFSSL_RC4_KEY* key, int len,
20633         const unsigned char* data)
20634 {
20635     typedef char rc4_test[sizeof(WOLFSSL_RC4_KEY) >= sizeof(Arc4) ? 1 : -1];
20636     (void)sizeof(rc4_test);
20637 
20638     WOLFSSL_ENTER("wolfSSL_RC4_set_key");
20639 
20640     if (key == NULL || len < 0) {
20641         WOLFSSL_MSG("bad argument passed in");
20642         return;
20643     }
20644 
20645     XMEMSET(key, 0, sizeof(WOLFSSL_RC4_KEY));
20646     wc_Arc4SetKey((Arc4*)key, data, (word32)len);
20647 }
20648 
20649 
20650 /* Encrypt/decrypt with Arc4 structure.
20651  *
20652  * len length of buffer to encrypt/decrypt (in/out)
20653  * in  buffer to encrypt/decrypt
20654  * out results of encryption/decryption
20655  */
20656 void wolfSSL_RC4(WOLFSSL_RC4_KEY* key, size_t len,
20657         const unsigned char* in, unsigned char* out)
20658 {
20659     WOLFSSL_ENTER("wolfSSL_RC4");
20660 
20661     if (key == NULL || in == NULL || out == NULL) {
20662         WOLFSSL_MSG("Bad argument passed in");
20663         return;
20664     }
20665 
20666     wc_Arc4Process((Arc4*)key, out, in, (word32)len);
20667 }
20668 #endif /* NO_RC4 */
20669 
20670 #ifndef NO_AES
20671 
20672 #ifdef WOLFSSL_AES_DIRECT
20673 /* AES encrypt direct, it is expected to be blocks of AES_BLOCK_SIZE for input.
20674  *
20675  * input  Data to encrypt
20676  * output Encrypted data after done
20677  * key    AES key to use for encryption
20678  */
20679 void wolfSSL_AES_encrypt(const unsigned char* input, unsigned char* output,
20680         AES_KEY *key)
20681 {
20682     WOLFSSL_ENTER("wolfSSL_AES_encrypt");
20683 
20684     if (input == NULL || output == NULL || key == NULL) {
20685         WOLFSSL_MSG("Null argument passed in");
20686         return;
20687     }
20688 
20689     wc_AesEncryptDirect((Aes*)key, output, input);
20690 }
20691 
20692 
20693 /* AES decrypt direct, it is expected to be blocks of AES_BLOCK_SIZE for input.
20694  *
20695  * input  Data to decrypt
20696  * output Decrypted data after done
20697  * key    AES key to use for encryption
20698  */
20699 void wolfSSL_AES_decrypt(const unsigned char* input, unsigned char* output,
20700         AES_KEY *key)
20701 {
20702     WOLFSSL_ENTER("wolfSSL_AES_decrypt");
20703 
20704     if (input == NULL || output == NULL || key == NULL) {
20705         WOLFSSL_MSG("Null argument passed in");
20706         return;
20707     }
20708 
20709     wc_AesDecryptDirect((Aes*)key, output, input);
20710 }
20711 #endif /* WOLFSSL_AES_DIRECT */
20712 
20713 /* Setup of an AES key to use for encryption.
20714  *
20715  * key  key in bytes to use for encryption
20716  * bits size of key in bits
20717  * aes  AES structure to initialize
20718  */
20719 int wolfSSL_AES_set_encrypt_key(const unsigned char *key, const int bits,
20720         AES_KEY *aes)
20721 {
20722     typedef char aes_test[sizeof(AES_KEY) >= sizeof(Aes) ? 1 : -1];
20723     (void)sizeof(aes_test);
20724 
20725     WOLFSSL_ENTER("wolfSSL_AES_set_encrypt_key");
20726 
20727     if (key == NULL || aes == NULL) {
20728         WOLFSSL_MSG("Null argument passed in");
20729         return -1;
20730     }
20731 
20732     XMEMSET(aes, 0, sizeof(AES_KEY));
20733     if (wc_AesSetKey((Aes*)aes, key, ((bits)/8), NULL, AES_ENCRYPTION) != 0) {
20734         WOLFSSL_MSG("Error in setting AES key");
20735         return -1;
20736     }
20737     return 0;
20738 }
20739 
20740 
20741 /* Setup of an AES key to use for decryption.
20742  *
20743  * key  key in bytes to use for decryption
20744  * bits size of key in bits
20745  * aes  AES structure to initialize
20746  */
20747 int wolfSSL_AES_set_decrypt_key(const unsigned char *key, const int bits,
20748         AES_KEY *aes)
20749 {
20750     typedef char aes_test[sizeof(AES_KEY) >= sizeof(Aes) ? 1 : -1];
20751     (void)sizeof(aes_test);
20752 
20753     WOLFSSL_ENTER("wolfSSL_AES_set_decrypt_key");
20754 
20755     if (key == NULL || aes == NULL) {
20756         WOLFSSL_MSG("Null argument passed in");
20757         return -1;
20758     }
20759 
20760     XMEMSET(aes, 0, sizeof(AES_KEY));
20761     if (wc_AesSetKey((Aes*)aes, key, ((bits)/8), NULL, AES_DECRYPTION) != 0) {
20762         WOLFSSL_MSG("Error in setting AES key");
20763         return -1;
20764     }
20765     return 0;
20766 }
20767 
20768 
20769 #ifdef HAVE_AES_ECB
20770 /* Encrypt/decrypt a 16 byte block of data using the key passed in.
20771  *
20772  * in  buffer to encrypt/decyrpt
20773  * out buffer to hold result of encryption/decryption
20774  * key AES structure to use with encryption/decryption
20775  * enc AES_ENCRPT for encryption and AES_DECRYPT for decryption
20776  */
20777 void wolfSSL_AES_ecb_encrypt(const unsigned char *in, unsigned char* out,
20778                              AES_KEY *key, const int enc)
20779 {
20780     Aes* aes;
20781 
20782     WOLFSSL_ENTER("wolfSSL_AES_ecb_encrypt");
20783 
20784     if (key == NULL || in == NULL || out == NULL) {
20785         WOLFSSL_MSG("Error, Null argument passed in");
20786         return;
20787     }
20788 
20789     aes = (Aes*)key;
20790     if (enc == AES_ENCRYPT) {
20791         if (wc_AesEcbEncrypt(aes, out, in, AES_BLOCK_SIZE) != 0) {
20792             WOLFSSL_MSG("Error with AES CBC encrypt");
20793         }
20794     }
20795     else {
20796     #ifdef HAVE_AES_DECRYPT
20797         if (wc_AesEcbDecrypt(aes, out, in, AES_BLOCK_SIZE) != 0) {
20798             WOLFSSL_MSG("Error with AES CBC decrypt");
20799         }
20800     #else
20801         WOLFSSL_MSG("AES decryption not compiled in");
20802     #endif
20803     }
20804 }
20805 #endif /* HAVE_AES_ECB */
20806 
20807 
20808 /* Encrypt data using key and iv passed in. iv gets updated to most recent iv
20809  * state after encryptiond/decryption.
20810  *
20811  * in  buffer to encrypt/decyrpt
20812  * out buffer to hold result of encryption/decryption
20813  * len length of input buffer
20814  * key AES structure to use with encryption/decryption
20815  * iv  iv to use with operation
20816  * enc AES_ENCRPT for encryption and AES_DECRYPT for decryption
20817  */
20818 void wolfSSL_AES_cbc_encrypt(const unsigned char *in, unsigned char* out,
20819         size_t len, AES_KEY *key, unsigned char* iv, const int enc)
20820 {
20821     Aes* aes;
20822 
20823     WOLFSSL_ENTER("wolfSSL_AES_cbc_encrypt");
20824 
20825     if (key == NULL || in == NULL || out == NULL || iv == NULL) {
20826         WOLFSSL_MSG("Error, Null argument passed in");
20827         return;
20828     }
20829 
20830     aes = (Aes*)key;
20831     if (wc_AesSetIV(aes, (const byte*)iv) != 0) {
20832         WOLFSSL_MSG("Error with setting iv");
20833         return;
20834     }
20835 
20836     if (enc == AES_ENCRYPT) {
20837         if (wc_AesCbcEncrypt(aes, out, in, (word32)len) != 0) {
20838             WOLFSSL_MSG("Error with AES CBC encrypt");
20839         }
20840     }
20841     else {
20842         if (wc_AesCbcDecrypt(aes, out, in, (word32)len) != 0) {
20843             WOLFSSL_MSG("Error with AES CBC decrypt");
20844         }
20845     }
20846 
20847     /* to be compatible copy iv to iv buffer after completing operation */
20848     XMEMCPY(iv, (byte*)(aes->reg), AES_BLOCK_SIZE);
20849 }
20850 
20851 
20852 /* Encrypt data using CFB mode with key and iv passed in. iv gets updated to
20853  * most recent iv state after encryptiond/decryption.
20854  *
20855  * in  buffer to encrypt/decyrpt
20856  * out buffer to hold result of encryption/decryption
20857  * len length of input buffer
20858  * key AES structure to use with encryption/decryption
20859  * iv  iv to use with operation
20860  * num contains the amount of block used
20861  * enc AES_ENCRPT for encryption and AES_DECRYPT for decryption
20862  */
20863 void wolfSSL_AES_cfb128_encrypt(const unsigned char *in, unsigned char* out,
20864         size_t len, AES_KEY *key, unsigned char* iv, int* num,
20865         const int enc)
20866 {
20867 #ifndef WOLFSSL_AES_CFB
20868     WOLFSSL_MSG("CFB mode not enabled please use macro WOLFSSL_AES_CFB");
20869     (void)in;
20870     (void)out;
20871     (void)len;
20872     (void)key;
20873     (void)iv;
20874     (void)num;
20875     (void)enc;
20876 
20877     return;
20878 #else
20879     Aes* aes;
20880 
20881     WOLFSSL_ENTER("wolfSSL_AES_cbc_encrypt");
20882     if (key == NULL || in == NULL || out == NULL || iv == NULL) {
20883         WOLFSSL_MSG("Error, Null argument passed in");
20884         return;
20885     }
20886 
20887     aes = (Aes*)key;
20888     if (wc_AesSetIV(aes, (const byte*)iv) != 0) {
20889         WOLFSSL_MSG("Error with setting iv");
20890         return;
20891     }
20892 
20893     if (enc == AES_ENCRYPT) {
20894         if (wc_AesCfbEncrypt(aes, out, in, (word32)len) != 0) {
20895             WOLFSSL_MSG("Error with AES CBC encrypt");
20896         }
20897     }
20898     else {
20899         if (wc_AesCfbDecrypt(aes, out, in, (word32)len) != 0) {
20900             WOLFSSL_MSG("Error with AES CBC decrypt");
20901         }
20902     }
20903 
20904     /* to be compatible copy iv to iv buffer after completing operation */
20905     XMEMCPY(iv, (byte*)(aes->reg), AES_BLOCK_SIZE);
20906 
20907     /* store number of left over bytes to num */
20908     *num = (aes->left)? AES_BLOCK_SIZE - aes->left : 0;
20909 #endif /* WOLFSSL_AES_CFB */
20910 }
20911 #endif /* NO_AES */
20912 
20913 #ifndef NO_WOLFSSL_STUB
20914 int wolfSSL_BIO_printf(WOLFSSL_BIO* bio, const char* format, ...)
20915 {
20916     (void)bio;
20917     (void)format;
20918     WOLFSSL_STUB("BIO_printf");
20919     return 0;
20920 }
20921 #endif
20922 
20923 #ifndef NO_WOLFSSL_STUB
20924 int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a)
20925 {
20926     (void)bio;
20927     (void)a;
20928     WOLFSSL_STUB("ASN1_UTCTIME_print");
20929     return 0;
20930 }
20931 #endif
20932 
20933 /* Return the month as a string.
20934  *
20935  * n  The number of the month as a two characters (1 based).
20936  * returns the month as a string.
20937  */
20938 static WC_INLINE const char* MonthStr(const char* n)
20939 {
20940     static const char monthStr[12][4] = {
20941             "Jan", "Feb", "Mar", "Apr", "May", "Jun",
20942             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
20943     return monthStr[(n[0] - '0') * 10 + (n[1] - '0') - 1];
20944 }
20945 
20946 int wolfSSL_ASN1_GENERALIZEDTIME_print(WOLFSSL_BIO* bio,
20947     const WOLFSSL_ASN1_GENERALIZEDTIME* asnTime)
20948 {
20949     const char* p = (const char *)(asnTime->data + 2);
20950     WOLFSSL_ENTER("wolfSSL_ASN1_GENERALIZEDTIME_print");
20951 
20952     if (bio == NULL || asnTime == NULL)
20953         return BAD_FUNC_ARG;
20954 
20955     /* GetTimeString not always available. */
20956     wolfSSL_BIO_write(bio, MonthStr(p + 4), 3);
20957     wolfSSL_BIO_write(bio, " ", 1);
20958     /* Day */
20959     wolfSSL_BIO_write(bio, p + 6, 2);
20960     wolfSSL_BIO_write(bio, " ", 1);
20961     /* Hour */
20962     wolfSSL_BIO_write(bio, p + 8, 2);
20963     wolfSSL_BIO_write(bio, ":", 1);
20964     /* Min */
20965     wolfSSL_BIO_write(bio, p + 10, 2);
20966     wolfSSL_BIO_write(bio, ":", 1);
20967     /* Secs */
20968     wolfSSL_BIO_write(bio, p + 12, 2);
20969     wolfSSL_BIO_write(bio, " ", 1);
20970     wolfSSL_BIO_write(bio, p, 4);
20971 
20972     return 0;
20973 }
20974 
20975 void wolfSSL_ASN1_GENERALIZEDTIME_free(WOLFSSL_ASN1_TIME* asn1Time)
20976 {
20977     WOLFSSL_ENTER("wolfSSL_ASN1_GENERALIZEDTIME_free");
20978     if (asn1Time == NULL)
20979         return;
20980     XMEMSET(asn1Time->data, 0, sizeof(asn1Time->data));
20981 }
20982 
20983 int  wolfSSL_sk_num(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk)
20984 {
20985     if (sk == NULL)
20986         return 0;
20987     return (int)sk->num;
20988 }
20989 
20990 void* wolfSSL_sk_value(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, int i)
20991 {
20992     for (; sk != NULL && i > 0; i--)
20993         sk = sk->next;
20994     if (sk == NULL)
20995         return NULL;
20996     return (void*)sk->data.obj;
20997 }
20998 
20999 #endif /* OPENSSL_EXTRA */
21000 
21001 #if defined(OPENSSL_EXTRA) || defined(HAVE_EXT_CACHE)
21002 /* stunnel 4.28 needs */
21003 void wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX* ctx,
21004                     WOLFSSL_SESSION*(*f)(WOLFSSL*, unsigned char*, int, int*))
21005 {
21006 #ifdef HAVE_EXT_CACHE
21007     ctx->get_sess_cb = f;
21008 #else
21009     (void)ctx;
21010     (void)f;
21011 #endif
21012 }
21013 
21014 void wolfSSL_CTX_sess_set_new_cb(WOLFSSL_CTX* ctx,
21015                              int (*f)(WOLFSSL*, WOLFSSL_SESSION*))
21016 {
21017 #ifdef HAVE_EXT_CACHE
21018     ctx->new_sess_cb = f;
21019 #else
21020     (void)ctx;
21021     (void)f;
21022 #endif
21023 }
21024 
21025 void wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX* ctx, void (*f)(WOLFSSL_CTX*,
21026                                                         WOLFSSL_SESSION*))
21027 {
21028 #ifdef HAVE_EXT_CACHE
21029     ctx->rem_sess_cb = f;
21030 #else
21031     (void)ctx;
21032     (void)f;
21033 #endif
21034 }
21035 #endif /* OPENSSL_EXTRA || HAVE_EXT_CACHE */
21036 
21037 #ifdef OPENSSL_EXTRA
21038 
21039 /*
21040  *
21041  * Note: It is expected that the importing and exporting function have been
21042  *       built with the same settings. For example if session tickets was
21043  *       enabled with the wolfSSL library exporting a session then it is
21044  *       expected to be turned on with the wolfSSL library importing the session.
21045  */
21046 int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
21047 {
21048     int size = 0;
21049 #ifdef HAVE_EXT_CACHE
21050     int idx = 0;
21051 #ifdef SESSION_CERTS
21052     int i;
21053 #endif
21054     unsigned char *data;
21055 
21056     if (sess == NULL) {
21057         return BAD_FUNC_ARG;
21058     }
21059 
21060     /* bornOn | timeout | sessionID len | sessionID | masterSecret | haveEMS */
21061     size += OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN + sess->sessionIDSz +
21062             SECRET_LEN + OPAQUE8_LEN;
21063 #ifdef SESSION_CERTS
21064     /* Peer chain */
21065     size += OPAQUE8_LEN;
21066     for (i = 0; i < sess->chain.count; i++)
21067         size += OPAQUE16_LEN + sess->chain.certs[i].length;
21068     /* Protocol version + cipher suite */
21069     size += OPAQUE16_LEN + OPAQUE16_LEN;
21070 #endif
21071 #ifndef NO_CLIENT_CACHE
21072     /* ServerID len | ServerID */
21073     size += OPAQUE16_LEN + sess->idLen;
21074 #endif
21075 #ifdef HAVE_SESSION_TICKET
21076     /* ticket len | ticket */
21077     size += OPAQUE16_LEN + sess->ticketLen;
21078 #endif
21079 #ifdef OPENSSL_EXTRA
21080     /* session context ID len | session context ID */
21081     size += OPAQUE8_LEN + sess->sessionCtxSz;
21082 #endif
21083 
21084     if (p != NULL) {
21085         if (*p == NULL)
21086             *p = (unsigned char*)XMALLOC(size, NULL, DYNAMIC_TYPE_OPENSSL);
21087         if (*p == NULL)
21088             return 0;
21089         data = *p;
21090 
21091         c32toa(sess->bornOn, data + idx); idx += OPAQUE32_LEN;
21092         c32toa(sess->timeout, data + idx); idx += OPAQUE32_LEN;
21093         data[idx++] = sess->sessionIDSz;
21094         XMEMCPY(data + idx, sess->sessionID, sess->sessionIDSz);
21095         idx += sess->sessionIDSz;
21096         XMEMCPY(data + idx, sess->masterSecret, SECRET_LEN); idx += SECRET_LEN;
21097         data[idx++] = (byte)sess->haveEMS;
21098 #ifdef SESSION_CERTS
21099         data[idx++] = (byte)sess->chain.count;
21100         for (i = 0; i < sess->chain.count; i++) {
21101             c16toa((word16)sess->chain.certs[i].length, data + idx);
21102             idx += OPAQUE16_LEN;
21103             XMEMCPY(data + idx, sess->chain.certs[i].buffer,
21104                     sess->chain.certs[i].length);
21105             idx += sess->chain.certs[i].length;
21106         }
21107         data[idx++] = sess->version.major;
21108         data[idx++] = sess->version.minor;
21109         data[idx++] = sess->cipherSuite0;
21110         data[idx++] = sess->cipherSuite;
21111 #endif
21112 #ifndef NO_CLIENT_CACHE
21113         c16toa(sess->idLen, data + idx); idx += OPAQUE16_LEN;
21114         XMEMCPY(data + idx, sess->serverID, sess->idLen);
21115         idx += sess->idLen;
21116 #endif
21117 #ifdef HAVE_SESSION_TICKET
21118         c16toa(sess->ticketLen, data + idx); idx += OPAQUE16_LEN;
21119         XMEMCPY(data + idx, sess->ticket, sess->ticketLen);
21120         idx += sess->ticketLen;
21121 #endif
21122 #ifdef OPENSSL_EXTRA
21123         data[idx++] = sess->sessionCtxSz;
21124         XMEMCPY(data + idx, sess->sessionCtx, sess->sessionCtxSz);
21125         idx += sess->sessionCtxSz;
21126 #endif
21127     }
21128 #endif
21129 
21130     (void)sess;
21131     (void)p;
21132 #ifdef HAVE_EXT_CACHE
21133     (void)idx;
21134 #endif
21135 
21136     return size;
21137 }
21138 
21139 
21140 /* TODO: no function to free new session.
21141  *
21142  * Note: It is expected that the importing and exporting function have been
21143  *       built with the same settings. For example if session tickets was
21144  *       enabled with the wolfSSL library exporting a session then it is
21145  *       expected to be turned on with the wolfSSL library importing the session.
21146  */
21147 WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
21148                                 const unsigned char** p, long i)
21149 {
21150     WOLFSSL_SESSION* s = NULL;
21151     int ret = 0;
21152 #if defined(HAVE_EXT_CACHE)
21153     int idx;
21154     byte* data;
21155 #ifdef SESSION_CERTS
21156     int j;
21157     word16 length;
21158 #endif
21159 #endif
21160 
21161     (void)p;
21162     (void)i;
21163     (void)ret;
21164 
21165     if (sess != NULL)
21166         s = *sess;
21167 
21168 #ifdef HAVE_EXT_CACHE
21169     if (p == NULL || *p == NULL)
21170         return NULL;
21171 
21172     if (s == NULL) {
21173         s = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), NULL,
21174                                       DYNAMIC_TYPE_OPENSSL);
21175         if (s == NULL)
21176             return NULL;
21177         XMEMSET(s, 0, sizeof(WOLFSSL_SESSION));
21178         s->isAlloced = 1;
21179 #ifdef HAVE_SESSION_TICKET
21180         s->isDynamic = 0;
21181 #endif
21182     }
21183 
21184     idx = 0;
21185     data = (byte*)*p;
21186 
21187     /* bornOn | timeout | sessionID len */
21188     if (i < OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN) {
21189         ret = BUFFER_ERROR;
21190         goto end;
21191     }
21192     ato32(data + idx, &s->bornOn); idx += OPAQUE32_LEN;
21193     ato32(data + idx, &s->timeout); idx += OPAQUE32_LEN;
21194     s->sessionIDSz = data[idx++];
21195 
21196     /* sessionID | secret | haveEMS */
21197     if (i - idx < s->sessionIDSz + SECRET_LEN + OPAQUE8_LEN) {
21198         ret = BUFFER_ERROR;
21199         goto end;
21200     }
21201     XMEMCPY(s->sessionID, data + idx, s->sessionIDSz);
21202     idx  += s->sessionIDSz;
21203     XMEMCPY(s->masterSecret, data + idx, SECRET_LEN); idx += SECRET_LEN;
21204     s->haveEMS = data[idx++];
21205 
21206 #ifdef SESSION_CERTS
21207     /* Certificate chain */
21208     if (i - idx == 0) {
21209         ret = BUFFER_ERROR;
21210         goto end;
21211     }
21212     s->chain.count = data[idx++];
21213     for (j = 0; j < s->chain.count; j++) {
21214         if (i - idx < OPAQUE16_LEN) {
21215             ret = BUFFER_ERROR;
21216             goto end;
21217         }
21218         ato16(data + idx, &length); idx += OPAQUE16_LEN;
21219         s->chain.certs[j].length = length;
21220         if (i - idx < length) {
21221             ret = BUFFER_ERROR;
21222             goto end;
21223         }
21224         XMEMCPY(s->chain.certs[j].buffer, data + idx, length);
21225         idx += length;
21226     }
21227 
21228     /* Protocol Version | Cipher suite */
21229     if (i - idx < OPAQUE16_LEN + OPAQUE16_LEN) {
21230         ret = BUFFER_ERROR;
21231         goto end;
21232     }
21233     s->version.major = data[idx++];
21234     s->version.minor = data[idx++];
21235     s->cipherSuite0 = data[idx++];
21236     s->cipherSuite = data[idx++];
21237 #endif
21238 #ifndef NO_CLIENT_CACHE
21239     /* ServerID len */
21240     if (i - idx < OPAQUE16_LEN) {
21241         ret = BUFFER_ERROR;
21242         goto end;
21243     }
21244     ato16(data + idx, &s->idLen); idx += OPAQUE16_LEN;
21245 
21246     /* ServerID */
21247     if (i - idx < s->idLen) {
21248         ret = BUFFER_ERROR;
21249         goto end;
21250     }
21251     XMEMCPY(s->serverID, data + idx, s->idLen); idx += s->idLen;
21252 #endif
21253 #ifdef HAVE_SESSION_TICKET
21254     /* ticket len */
21255     if (i - idx < OPAQUE16_LEN) {
21256         ret = BUFFER_ERROR;
21257         goto end;
21258     }
21259     ato16(data + idx, &s->ticketLen); idx += OPAQUE16_LEN;
21260 
21261     /* Dispose of ol dynamic ticket and ensure space for new ticket. */
21262     if (s->isDynamic)
21263         XFREE(s->ticket, NULL, DYNAMIC_TYPE_SESSION_TICK);
21264     if (s->ticketLen <= SESSION_TICKET_LEN)
21265         s->ticket = s->staticTicket;
21266     else {
21267         s->ticket = (byte*)XMALLOC(s->ticketLen, NULL,
21268                                    DYNAMIC_TYPE_SESSION_TICK);
21269         if (s->ticket == NULL) {
21270             ret = MEMORY_ERROR;
21271             goto end;
21272         }
21273         s->isDynamic = 1;
21274     }
21275 
21276     /* ticket */
21277     if (i - idx < s->ticketLen) {
21278         ret = BUFFER_ERROR;
21279         goto end;
21280     }
21281     XMEMCPY(s->ticket, data + idx, s->ticketLen); idx += s->ticketLen;
21282 #endif
21283 #ifdef OPENSSL_EXTRA
21284     /* byte for length of session context ID */
21285     if (i - idx < OPAQUE8_LEN) {
21286         ret = BUFFER_ERROR;
21287         goto end;
21288     }
21289     s->sessionCtxSz = data[idx++];
21290 
21291     /* app session context ID */
21292     if (i - idx < s->sessionCtxSz) {
21293         ret = BUFFER_ERROR;
21294         goto end;
21295     }
21296     XMEMCPY(s->sessionCtx, data + idx, s->sessionCtxSz); idx += s->sessionCtxSz;
21297 #endif
21298     (void)idx;
21299 
21300     if (sess != NULL)
21301         *sess = s;
21302 
21303     *p += idx;
21304 
21305 end:
21306     if (ret != 0 && (sess == NULL || *sess != s))
21307         wolfSSL_SESSION_free(s);
21308 #endif
21309     return s;
21310 }
21311 
21312 
21313 long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION* sess)
21314 {
21315     WOLFSSL_ENTER("wolfSSL_SESSION_get_timeout");
21316     return sess->timeout;
21317 }
21318 
21319 
21320 long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION* sess)
21321 {
21322     WOLFSSL_ENTER("wolfSSL_SESSION_get_time");
21323     return sess->bornOn;
21324 }
21325 
21326 
21327 #endif /* OPENSSL_EXTRA */
21328 
21329 
21330 #ifdef KEEP_PEER_CERT
21331 char*  wolfSSL_X509_get_subjectCN(WOLFSSL_X509* x509)
21332 {
21333     if (x509 == NULL)
21334         return NULL;
21335 
21336     return x509->subjectCN;
21337 }
21338 #endif /* KEEP_PEER_CERT */
21339 
21340 #ifdef OPENSSL_EXTRA
21341 
21342 #if defined(FORTRESS) && !defined(NO_FILESYSTEM)
21343 int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname)
21344 {
21345     int ret = WOLFSSL_FATAL_ERROR;
21346 
21347     WOLFSSL_ENTER("wolfSSL_cmp_peer_cert_to_file");
21348     if (ssl != NULL && fname != NULL)
21349     {
21350     #ifdef WOLFSSL_SMALL_STACK
21351         byte           staticBuffer[1]; /* force heap usage */
21352     #else
21353         byte           staticBuffer[FILE_BUFFER_SIZE];
21354     #endif
21355         byte*          myBuffer  = staticBuffer;
21356         int            dynamic   = 0;
21357         XFILE          file      = XBADFILE;
21358         size_t         sz        = 0;
21359         WOLFSSL_CTX*   ctx       = ssl->ctx;
21360         WOLFSSL_X509*  peer_cert = &ssl->peerCert;
21361         DerBuffer*     fileDer = NULL;
21362 
21363         file = XFOPEN(fname, "rb");
21364         if (file == XBADFILE)
21365             return WOLFSSL_BAD_FILE;
21366 
21367         XFSEEK(file, 0, XSEEK_END);
21368         sz = XFTELL(file);
21369         XREWIND(file);
21370 
21371         if (sz > (long)sizeof(staticBuffer)) {
21372             WOLFSSL_MSG("Getting dynamic buffer");
21373             myBuffer = (byte*)XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
21374             dynamic = 1;
21375         }
21376 
21377 
21378         if ((myBuffer != NULL) &&
21379             (sz > 0) &&
21380             (XFREAD(myBuffer, 1, sz, file) == sz) &&
21381             (PemToDer(myBuffer, (long)sz, CERT_TYPE,
21382                       &fileDer, ctx->heap, NULL, NULL) == 0) &&
21383             (fileDer->length != 0) &&
21384             (fileDer->length == peer_cert->derCert->length) &&
21385             (XMEMCMP(peer_cert->derCert->buffer, fileDer->buffer,
21386                                                 fileDer->length) == 0))
21387         {
21388             ret = 0;
21389         }
21390 
21391         FreeDer(&fileDer);
21392 
21393         if (dynamic)
21394             XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
21395 
21396         XFCLOSE(file);
21397     }
21398 
21399     return ret;
21400 }
21401 #endif
21402 #endif /* OPENSSL_EXTRA */
21403 
21404 #if defined(OPENSSL_EXTRA) || \
21405     (defined(OPENSSL_EXTRA_X509_SMALL) && !defined(NO_RSA))
21406 static WC_RNG globalRNG;
21407 static int initGlobalRNG = 0;
21408 #endif
21409 
21410 #ifdef OPENSSL_EXTRA
21411 
21412 /* Not thread safe! Can be called multiple times.
21413  * Checks if the global RNG has been created. If not then one is created.
21414  *
21415  * Returns SSL_SUCCESS when no error is encountered.
21416  */
21417 static int wolfSSL_RAND_Init(void)
21418 {
21419     if (initGlobalRNG == 0) {
21420         if (wc_InitRng(&globalRNG) < 0) {
21421             WOLFSSL_MSG("wolfSSL Init Global RNG failed");
21422             return 0;
21423         }
21424         initGlobalRNG = 1;
21425     }
21426 
21427     return SSL_SUCCESS;
21428 }
21429 
21430 
21431 /* SSL_SUCCESS on ok */
21432 int wolfSSL_RAND_seed(const void* seed, int len)
21433 {
21434 
21435     WOLFSSL_MSG("wolfSSL_RAND_seed");
21436 
21437     (void)seed;
21438     (void)len;
21439 
21440     return wolfSSL_RAND_Init();
21441 }
21442 
21443 
21444 /* Returns the path for reading seed data from.
21445  * Uses the env variable $RANDFILE first if set, if not then used $HOME/.rnd
21446  *
21447  * Note uses stdlib by default unless XGETENV macro is overwritten
21448  *
21449  * fname buffer to hold path
21450  * len   length of fname buffer
21451  *
21452  * Returns a pointer to fname on success and NULL on failure
21453  */
21454 const char* wolfSSL_RAND_file_name(char* fname, unsigned long len)
21455 {
21456 #ifndef NO_FILESYSTEM
21457     char* rt;
21458     char ap[] = "/.rnd";
21459 
21460     WOLFSSL_ENTER("wolfSSL_RAND_file_name");
21461 
21462     if (fname == NULL) {
21463         return NULL;
21464     }
21465 
21466     XMEMSET(fname, 0, len);
21467     /* if access to stdlib.h */
21468     if ((rt = XGETENV("RANDFILE")) != NULL) {
21469         if (len > XSTRLEN(rt)) {
21470             XMEMCPY(fname, rt, XSTRLEN(rt));
21471         }
21472         else {
21473             WOLFSSL_MSG("RANDFILE too large for buffer");
21474             rt = NULL;
21475         }
21476     }
21477 
21478     /* $RANDFILE was not set or is too large, check $HOME */
21479     if (rt == NULL) {
21480         WOLFSSL_MSG("Environment variable RANDFILE not set");
21481         if ((rt = XGETENV("HOME")) == NULL) {
21482             WOLFSSL_MSG("Environment variable HOME not set");
21483             return NULL;
21484         }
21485 
21486         if (len > XSTRLEN(rt) +  XSTRLEN(ap)) {
21487             fname[0] = '\0';
21488             XSTRNCAT(fname, rt, len);
21489             XSTRNCAT(fname, ap, len - XSTRLEN(rt));
21490             return fname;
21491         }
21492         else {
21493             WOLFSSL_MSG("HOME too large for buffer");
21494             return NULL;
21495         }
21496     }
21497 
21498     return fname;
21499 #else
21500     /* no filesystem defined */
21501     WOLFSSL_ENTER("wolfSSL_RAND_file_name");
21502     WOLFSSL_MSG("No filesystem feature enabled, not compiled in");
21503     (void)fname;
21504     (void)len;
21505     return NULL;
21506 #endif
21507 }
21508 
21509 
21510 /* Writes 1024 bytes from the RNG to the given file name.
21511  *
21512  * fname name of file to write to
21513  *
21514  * Returns the number of bytes writen
21515  */
21516 int wolfSSL_RAND_write_file(const char* fname)
21517 {
21518     int bytes = 0;
21519 
21520     WOLFSSL_ENTER("RAND_write_file");
21521 
21522     if (fname == NULL) {
21523         return SSL_FAILURE;
21524     }
21525 
21526 #ifndef NO_FILESYSTEM
21527     {
21528     #ifndef WOLFSSL_SMALL_STACK
21529         unsigned char buf[1024];
21530     #else
21531         unsigned char* buf = (unsigned char *)XMALLOC(1024, NULL,
21532                                                        DYNAMIC_TYPE_TMP_BUFFER);
21533         if (buf == NULL) {
21534             WOLFSSL_MSG("malloc failed");
21535             return SSL_FAILURE;
21536         }
21537     #endif
21538         bytes = 1024; /* default size of buf */
21539 
21540         if (initGlobalRNG == 0 && wolfSSL_RAND_Init() != SSL_SUCCESS) {
21541             WOLFSSL_MSG("No RNG to use");
21542         #ifdef WOLFSSL_SMALL_STACK
21543             XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21544         #endif
21545             return 0;
21546         }
21547 
21548         if (wc_RNG_GenerateBlock(&globalRNG, buf, bytes) != 0) {
21549             WOLFSSL_MSG("Error generating random buffer");
21550             bytes = 0;
21551         }
21552         else {
21553             XFILE f;
21554 
21555             f = XFOPEN(fname, "wb");
21556             if (f == NULL) {
21557                 WOLFSSL_MSG("Error opening the file");
21558                 bytes = 0;
21559             }
21560             else {
21561                 XFWRITE(buf, 1, bytes, f);
21562                 XFCLOSE(f);
21563             }
21564         }
21565         ForceZero(buf, bytes);
21566     #ifdef WOLFSSL_SMALL_STACK
21567         XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21568     #endif
21569     }
21570 #endif
21571 
21572     return bytes;
21573 }
21574 
21575 #ifndef FREERTOS_TCP
21576 
21577 /* These constant values are protocol values made by egd */
21578 #if defined(USE_WOLFSSL_IO) && !defined(USE_WINDOWS_API)
21579     #define WOLFSSL_EGD_NBLOCK 0x01
21580     #include <sys/un.h>
21581 #endif
21582 
21583 /* at compile time check for HASH DRBG and throw warning if not found */
21584 #ifndef HAVE_HASHDRBG
21585     #warning HAVE_HASHDRBG is needed for wolfSSL_RAND_egd to seed
21586 #endif
21587 
21588 /* This collects entropy from the path nm and seeds the global PRNG with it.
21589  * Makes a call to wolfSSL_RAND_Init which is not thread safe.
21590  *
21591  * nm is the file path to the egd server
21592  *
21593  * Returns the number of bytes read.
21594  */
21595 int wolfSSL_RAND_egd(const char* nm)
21596 {
21597 #if defined(USE_WOLFSSL_IO) && !defined(USE_WINDOWS_API) && !defined(HAVE_FIPS)
21598     struct sockaddr_un rem;
21599     int fd;
21600     int ret = WOLFSSL_SUCCESS;
21601     word32 bytes = 0;
21602     word32 idx   = 0;
21603 #ifndef WOLFSSL_SMALL_STACK
21604     unsigned char buf[256];
21605 #else
21606     unsigned char* buf;
21607     buf = (unsigned char*)XMALLOC(256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21608     if (buf == NULL) {
21609         WOLFSSL_MSG("Not enough memory");
21610         return WOLFSSL_FATAL_ERROR;
21611     }
21612 #endif
21613 
21614     if (nm == NULL) {
21615     #ifdef WOLFSSL_SMALL_STACK
21616         XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21617     #endif
21618         return WOLFSSL_FATAL_ERROR;
21619     }
21620 
21621     fd = socket(AF_UNIX, SOCK_STREAM, 0);
21622     if (fd < 0) {
21623         WOLFSSL_MSG("Error creating socket");
21624     #ifdef WOLFSSL_SMALL_STACK
21625         XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21626     #endif
21627         return WOLFSSL_FATAL_ERROR;
21628     }
21629     if (ret == WOLFSSL_SUCCESS) {
21630         rem.sun_family = AF_UNIX;
21631         XSTRNCPY(rem.sun_path, nm, sizeof(rem.sun_path));
21632         rem.sun_path[sizeof(rem.sun_path)-1] = '\0';
21633     }
21634 
21635     /* connect to egd server */
21636     if (ret == WOLFSSL_SUCCESS) {
21637         if (connect(fd, (struct sockaddr*)&rem, sizeof(struct sockaddr_un))
21638                 == -1) {
21639             WOLFSSL_MSG("error connecting to egd server");
21640             ret = WOLFSSL_FATAL_ERROR;
21641         }
21642     }
21643 
21644     while (ret == WOLFSSL_SUCCESS && bytes < 255 && idx + 2 < 256) {
21645         if (ret == WOLFSSL_SUCCESS) {
21646             buf[idx]     = WOLFSSL_EGD_NBLOCK;
21647             buf[idx + 1] = 255 - bytes; /* request 255 bytes from server */
21648             ret = (int)write(fd, buf + idx, 2);
21649             if (ret <= 0 || ret != 2) {
21650                 if (errno == EAGAIN) {
21651                     ret = WOLFSSL_SUCCESS;
21652                     continue;
21653                 }
21654                 WOLFSSL_MSG("error requesting entropy from egd server");
21655                 ret = WOLFSSL_FATAL_ERROR;
21656                 break;
21657             }
21658         }
21659 
21660         /* attempting to read */
21661         buf[idx] = 0;
21662         ret = (int)read(fd, buf + idx, 256 - bytes);
21663         if (ret == 0) {
21664             WOLFSSL_MSG("error reading entropy from egd server");
21665             ret = WOLFSSL_FATAL_ERROR;
21666             break;
21667         }
21668         if (ret > 0 && buf[idx] > 0) {
21669             bytes += buf[idx]; /* egd stores amount sent in first byte */
21670             if (bytes + idx > 255 || buf[idx] > ret) {
21671                 WOLFSSL_MSG("Buffer error");
21672                 ret = WOLFSSL_FATAL_ERROR;
21673                 break;
21674             }
21675             XMEMMOVE(buf + idx, buf + idx + 1, buf[idx]);
21676             idx = bytes;
21677             ret = WOLFSSL_SUCCESS;
21678             if (bytes >= 255) {
21679                 break;
21680             }
21681         }
21682         else {
21683             if (errno == EAGAIN || errno == EINTR) {
21684                 WOLFSSL_MSG("EGD would read");
21685                 ret = WOLFSSL_SUCCESS; /* try again */
21686             }
21687             else if (buf[idx] == 0) {
21688                 /* if egd returned 0 then there is no more entropy to be had.
21689                    Do not try more reads. */
21690                 ret = WOLFSSL_SUCCESS;
21691                 break;
21692             }
21693             else {
21694                 WOLFSSL_MSG("Error with read");
21695                 ret = WOLFSSL_FATAL_ERROR;
21696             }
21697         }
21698     }
21699 
21700     if (bytes > 0 && ret == WOLFSSL_SUCCESS) {
21701         wolfSSL_RAND_Init(); /* call to check global RNG is created */
21702         if (wc_RNG_DRBG_Reseed(&globalRNG, (const byte*) buf, bytes)
21703                 != 0) {
21704             WOLFSSL_MSG("Error with reseeding DRBG structure");
21705             ret = WOLFSSL_FATAL_ERROR;
21706         }
21707         #ifdef SHOW_SECRETS
21708         { /* print out entropy found */
21709             word32 i;
21710             printf("EGD Entropy = ");
21711             for (i = 0; i < bytes; i++) {
21712                 printf("%02X", buf[i]);
21713             }
21714             printf("\n");
21715         }
21716         #endif
21717     }
21718 
21719     ForceZero(buf, bytes);
21720     #ifdef WOLFSSL_SMALL_STACK
21721     XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21722     #endif
21723     close(fd);
21724 
21725     if (ret == WOLFSSL_SUCCESS) {
21726         return bytes;
21727     }
21728     else {
21729         return ret;
21730     }
21731 #else /* defined(USE_WOLFSSL_IO) && !defined(USE_WINDOWS_API) && !HAVE_FIPS */
21732     WOLFSSL_MSG("Type of socket needed is not available");
21733     WOLFSSL_MSG("\tor using FIPS mode where RNG API is not available");
21734     (void)nm;
21735 
21736     return WOLFSSL_FATAL_ERROR;
21737 #endif /* defined(USE_WOLFSSL_IO) && !defined(USE_WINDOWS_API) */
21738 }
21739 
21740 #endif /* !FREERTOS_TCP */
21741 
21742 void wolfSSL_RAND_Cleanup(void)
21743 {
21744     WOLFSSL_ENTER("wolfSSL_RAND_Cleanup()");
21745 
21746     if (initGlobalRNG != 0) {
21747         wc_FreeRng(&globalRNG);
21748         initGlobalRNG = 0;
21749     }
21750 }
21751 
21752 
21753 int wolfSSL_RAND_pseudo_bytes(unsigned char* buf, int num)
21754 {
21755     return wolfSSL_RAND_bytes(buf, num);
21756 }
21757 
21758 
21759 /* SSL_SUCCESS on ok */
21760 int wolfSSL_RAND_bytes(unsigned char* buf, int num)
21761 {
21762     int     ret = 0;
21763     int     initTmpRng = 0;
21764     WC_RNG* rng = NULL;
21765 #ifdef WOLFSSL_SMALL_STACK
21766     WC_RNG* tmpRNG = NULL;
21767 #else
21768     WC_RNG  tmpRNG[1];
21769 #endif
21770 
21771     WOLFSSL_ENTER("wolfSSL_RAND_bytes");
21772 
21773 #ifdef WOLFSSL_SMALL_STACK
21774     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
21775     if (tmpRNG == NULL)
21776         return ret;
21777 #endif
21778 
21779     if (wc_InitRng(tmpRNG) == 0) {
21780         rng = tmpRNG;
21781         initTmpRng = 1;
21782     }
21783     else if (initGlobalRNG)
21784         rng = &globalRNG;
21785 
21786     if (rng) {
21787         if (wc_RNG_GenerateBlock(rng, buf, num) != 0)
21788             WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
21789         else
21790             ret = WOLFSSL_SUCCESS;
21791     }
21792 
21793     if (initTmpRng)
21794         wc_FreeRng(tmpRNG);
21795 
21796 #ifdef WOLFSSL_SMALL_STACK
21797     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
21798 #endif
21799 
21800     return ret;
21801 }
21802 
21803 
21804 int wolfSSL_RAND_poll()
21805 {
21806     byte  entropy[16];
21807     int  ret = 0;
21808     word32 entropy_sz = 16;
21809 
21810     WOLFSSL_ENTER("wolfSSL_RAND_poll");
21811     if (initGlobalRNG == 0){
21812         WOLFSSL_MSG("Global RNG no Init");
21813         return  WOLFSSL_FAILURE;
21814     }
21815     ret = wc_GenerateSeed(&globalRNG.seed, entropy, entropy_sz);
21816     if (ret != 0){
21817         WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
21818         ret = WOLFSSL_FAILURE;
21819     }else
21820         ret = WOLFSSL_SUCCESS;
21821 
21822     return ret;
21823 }
21824 
21825 WOLFSSL_BN_CTX* wolfSSL_BN_CTX_new(void)
21826 {
21827     static int ctx;  /* wolfcrypt doesn't now need ctx */
21828 
21829     WOLFSSL_MSG("wolfSSL_BN_CTX_new");
21830     return (WOLFSSL_BN_CTX*)&ctx;
21831 
21832 }
21833 
21834 void wolfSSL_BN_CTX_init(WOLFSSL_BN_CTX* ctx)
21835 {
21836     (void)ctx;
21837     WOLFSSL_MSG("wolfSSL_BN_CTX_init");
21838 }
21839 
21840 
21841 void wolfSSL_BN_CTX_free(WOLFSSL_BN_CTX* ctx)
21842 {
21843     (void)ctx;
21844     WOLFSSL_MSG("wolfSSL_BN_CTX_free");
21845     /* do free since static ctx that does nothing */
21846 }
21847 #endif /* OPENSSL_EXTRA */
21848 
21849 
21850 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
21851 static void InitwolfSSL_BigNum(WOLFSSL_BIGNUM* bn)
21852 {
21853     if (bn) {
21854         XMEMSET(bn, 0, sizeof(WOLFSSL_BIGNUM));
21855         bn->neg      = 0;
21856         bn->internal = NULL;
21857     }
21858 }
21859 
21860 WOLFSSL_BIGNUM* wolfSSL_BN_new(void)
21861 {
21862     WOLFSSL_BIGNUM* external;
21863     mp_int*        mpi;
21864 
21865     WOLFSSL_MSG("wolfSSL_BN_new");
21866 
21867     mpi = (mp_int*) XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
21868     if (mpi == NULL) {
21869         WOLFSSL_MSG("wolfSSL_BN_new malloc mpi failure");
21870         return NULL;
21871     }
21872 
21873     external = (WOLFSSL_BIGNUM*) XMALLOC(sizeof(WOLFSSL_BIGNUM), NULL,
21874                                         DYNAMIC_TYPE_BIGINT);
21875     if (external == NULL) {
21876         WOLFSSL_MSG("wolfSSL_BN_new malloc WOLFSSL_BIGNUM failure");
21877         XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
21878         return NULL;
21879     }
21880 
21881     InitwolfSSL_BigNum(external);
21882     external->internal = mpi;
21883     if (mp_init(mpi) != MP_OKAY) {
21884         wolfSSL_BN_free(external);
21885         return NULL;
21886     }
21887 
21888     return external;
21889 }
21890 
21891 
21892 void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn)
21893 {
21894     WOLFSSL_MSG("wolfSSL_BN_free");
21895     if (bn) {
21896         if (bn->internal) {
21897             mp_forcezero((mp_int*)bn->internal);
21898             XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT);
21899             bn->internal = NULL;
21900         }
21901         XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT);
21902         bn = NULL;
21903     }
21904 }
21905 #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
21906 
21907 #ifdef OPENSSL_EXTRA
21908 
21909 void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM* bn)
21910 {
21911     WOLFSSL_MSG("wolfSSL_BN_clear_free");
21912 
21913     wolfSSL_BN_free(bn);
21914 }
21915 
21916 
21917 /* WOLFSSL_SUCCESS on ok */
21918 int wolfSSL_BN_sub(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
21919                   const WOLFSSL_BIGNUM* b)
21920 {
21921     WOLFSSL_MSG("wolfSSL_BN_sub");
21922 
21923     if (r == NULL || a == NULL || b == NULL)
21924         return 0;
21925 
21926     if (mp_sub((mp_int*)a->internal,(mp_int*)b->internal,
21927                (mp_int*)r->internal) == MP_OKAY)
21928         return WOLFSSL_SUCCESS;
21929 
21930     WOLFSSL_MSG("wolfSSL_BN_sub mp_sub failed");
21931     return 0;
21932 }
21933 
21934 /* WOLFSSL_SUCCESS on ok */
21935 int wolfSSL_BN_mod(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
21936                   const WOLFSSL_BIGNUM* b, const WOLFSSL_BN_CTX* c)
21937 {
21938     (void)c;
21939     WOLFSSL_MSG("wolfSSL_BN_mod");
21940 
21941     if (r == NULL || a == NULL || b == NULL)
21942         return 0;
21943 
21944     if (mp_mod((mp_int*)a->internal,(mp_int*)b->internal,
21945                (mp_int*)r->internal) == MP_OKAY)
21946         return WOLFSSL_SUCCESS;
21947 
21948     WOLFSSL_MSG("wolfSSL_BN_mod mp_mod failed");
21949     return 0;
21950 }
21951 
21952 
21953 /* r = (a^p) % m */
21954 int wolfSSL_BN_mod_exp(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
21955       const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
21956 {
21957     int ret;
21958 
21959     WOLFSSL_ENTER("wolfSSL_BN_mod_exp");
21960 
21961     (void) ctx;
21962     if (r == NULL || a == NULL || p == NULL || m == NULL) {
21963         WOLFSSL_MSG("Bad Argument");
21964         return WOLFSSL_FAILURE;
21965     }
21966 
21967     if ((ret = mp_exptmod((mp_int*)a->internal,(mp_int*)p->internal,
21968                (mp_int*)m->internal, (mp_int*)r->internal)) == MP_OKAY) {
21969         return WOLFSSL_SUCCESS;
21970     }
21971 
21972     WOLFSSL_LEAVE("wolfSSL_BN_mod_exp", ret);
21973     (void)ret;
21974 
21975     return WOLFSSL_FAILURE;
21976 }
21977 
21978 /* r = (a * p) % m */
21979 int wolfSSL_BN_mod_mul(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
21980         const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
21981 {
21982     int ret;
21983 
21984     WOLFSSL_ENTER("wolfSSL_BN_mod_mul");
21985 
21986     (void) ctx;
21987     if (r == NULL || a == NULL || p == NULL || m == NULL) {
21988         WOLFSSL_MSG("Bad Argument");
21989         return SSL_FAILURE;
21990     }
21991 
21992     if ((ret = mp_mulmod((mp_int*)a->internal,(mp_int*)p->internal,
21993                (mp_int*)m->internal, (mp_int*)r->internal)) == MP_OKAY) {
21994         return SSL_SUCCESS;
21995     }
21996 
21997     WOLFSSL_LEAVE("wolfSSL_BN_mod_mul", ret);
21998     (void)ret;
21999 
22000     return SSL_FAILURE;
22001 }
22002 
22003 const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void)
22004 {
22005     static WOLFSSL_BIGNUM* bn_one = NULL;
22006 
22007     WOLFSSL_MSG("wolfSSL_BN_value_one");
22008 
22009     if (bn_one == NULL) {
22010         bn_one = wolfSSL_BN_new();
22011         if (bn_one) {
22012             if (mp_set_int((mp_int*)bn_one->internal, 1) != MP_OKAY) {
22013                 /* handle error by freeing BN and returning NULL */
22014                 wolfSSL_BN_free(bn_one);
22015                 bn_one = NULL;
22016             }
22017         }
22018     }
22019 
22020     return bn_one;
22021 }
22022 
22023 /* return compliant with OpenSSL
22024  *   size of BIGNUM in bytes, 0 if error */
22025 int wolfSSL_BN_num_bytes(const WOLFSSL_BIGNUM* bn)
22026 {
22027     WOLFSSL_ENTER("wolfSSL_BN_num_bytes");
22028 
22029     if (bn == NULL || bn->internal == NULL)
22030         return WOLFSSL_FAILURE;
22031 
22032     return mp_unsigned_bin_size((mp_int*)bn->internal);
22033 }
22034 
22035 /* return compliant with OpenSSL
22036  *   size of BIGNUM in bits, 0 if error */
22037 int wolfSSL_BN_num_bits(const WOLFSSL_BIGNUM* bn)
22038 {
22039     WOLFSSL_ENTER("wolfSSL_BN_num_bits");
22040 
22041     if (bn == NULL || bn->internal == NULL)
22042         return WOLFSSL_FAILURE;
22043 
22044     return mp_count_bits((mp_int*)bn->internal);
22045 }
22046 
22047 /* return compliant with OpenSSL
22048  *   1 if BIGNUM is zero, 0 else */
22049 int wolfSSL_BN_is_zero(const WOLFSSL_BIGNUM* bn)
22050 {
22051     WOLFSSL_MSG("wolfSSL_BN_is_zero");
22052 
22053     if (bn == NULL || bn->internal == NULL)
22054         return WOLFSSL_FAILURE;
22055 
22056     if (mp_iszero((mp_int*)bn->internal) == MP_YES)
22057         return WOLFSSL_SUCCESS;
22058 
22059     return WOLFSSL_FAILURE;
22060 }
22061 
22062 /* return compliant with OpenSSL
22063  *   1 if BIGNUM is one, 0 else */
22064 int wolfSSL_BN_is_one(const WOLFSSL_BIGNUM* bn)
22065 {
22066     WOLFSSL_MSG("wolfSSL_BN_is_one");
22067 
22068     if (bn == NULL || bn->internal == NULL)
22069         return WOLFSSL_FAILURE;
22070 
22071     if (mp_cmp_d((mp_int*)bn->internal, 1) == MP_EQ)
22072         return WOLFSSL_SUCCESS;
22073 
22074     return WOLFSSL_FAILURE;
22075 }
22076 
22077 /* return compliant with OpenSSL
22078  *   1 if BIGNUM is odd, 0 else */
22079 int wolfSSL_BN_is_odd(const WOLFSSL_BIGNUM* bn)
22080 {
22081     WOLFSSL_MSG("wolfSSL_BN_is_odd");
22082 
22083     if (bn == NULL || bn->internal == NULL)
22084         return WOLFSSL_FAILURE;
22085 
22086     if (mp_isodd((mp_int*)bn->internal) == MP_YES)
22087         return WOLFSSL_SUCCESS;
22088 
22089     return WOLFSSL_FAILURE;
22090 }
22091 
22092 /* return compliant with OpenSSL
22093  *   -1 if a < b, 0 if a == b and 1 if a > b
22094  */
22095 int wolfSSL_BN_cmp(const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b)
22096 {
22097     int ret;
22098 
22099     WOLFSSL_MSG("wolfSSL_BN_cmp");
22100 
22101     if (a == NULL || a->internal == NULL || b == NULL || b->internal == NULL)
22102         return WOLFSSL_FATAL_ERROR;
22103 
22104     ret = mp_cmp((mp_int*)a->internal, (mp_int*)b->internal);
22105 
22106     return (ret == MP_EQ ? 0 : (ret == MP_GT ? 1 : -1));
22107 }
22108 
22109 /* return compliant with OpenSSL
22110  *   length of BIGNUM in bytes, -1 if error */
22111 int wolfSSL_BN_bn2bin(const WOLFSSL_BIGNUM* bn, unsigned char* r)
22112 {
22113     WOLFSSL_MSG("wolfSSL_BN_bn2bin");
22114 
22115     if (bn == NULL || bn->internal == NULL) {
22116         WOLFSSL_MSG("NULL bn error");
22117         return WOLFSSL_FATAL_ERROR;
22118     }
22119 
22120     if (r == NULL)
22121         return mp_unsigned_bin_size((mp_int*)bn->internal);
22122 
22123     if (mp_to_unsigned_bin((mp_int*)bn->internal, r) != MP_OKAY) {
22124         WOLFSSL_MSG("mp_to_unsigned_bin error");
22125         return WOLFSSL_FATAL_ERROR;
22126     }
22127 
22128     return mp_unsigned_bin_size((mp_int*)bn->internal);
22129 }
22130 
22131 
22132 WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char* str, int len,
22133                             WOLFSSL_BIGNUM* ret)
22134 {
22135     int weOwn = 0;
22136 
22137     WOLFSSL_MSG("wolfSSL_BN_bin2bn");
22138 
22139     /* if ret is null create a BN */
22140     if (ret == NULL) {
22141         ret = wolfSSL_BN_new();
22142         weOwn = 1;
22143         if (ret == NULL)
22144             return NULL;
22145     }
22146 
22147     /* check ret and ret->internal then read in value */
22148     if (ret && ret->internal) {
22149         if (mp_read_unsigned_bin((mp_int*)ret->internal, str, len) != 0) {
22150             WOLFSSL_MSG("mp_read_unsigned_bin failure");
22151             if (weOwn)
22152                 wolfSSL_BN_free(ret);
22153             return NULL;
22154         }
22155     }
22156 
22157     return ret;
22158 }
22159 
22160 /* return compliant with OpenSSL
22161  *   1 if success, 0 if error */
22162 #ifndef NO_WOLFSSL_STUB
22163 int wolfSSL_mask_bits(WOLFSSL_BIGNUM* bn, int n)
22164 {
22165     (void)bn;
22166     (void)n;
22167     WOLFSSL_ENTER("wolfSSL_BN_mask_bits");
22168     WOLFSSL_STUB("BN_mask_bits");
22169     return SSL_FAILURE;
22170 }
22171 #endif
22172 
22173 
22174 /* WOLFSSL_SUCCESS on ok */
22175 int wolfSSL_BN_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
22176 {
22177     int           ret    = 0;
22178     int           len    = bits / 8;
22179     int           initTmpRng = 0;
22180     WC_RNG*       rng    = NULL;
22181 #ifdef WOLFSSL_SMALL_STACK
22182     WC_RNG*       tmpRNG = NULL;
22183     byte*         buff   = NULL;
22184 #else
22185     WC_RNG        tmpRNG[1];
22186     byte          buff[1024];
22187 #endif
22188 
22189     (void)top;
22190     (void)bottom;
22191     WOLFSSL_MSG("wolfSSL_BN_rand");
22192 
22193     if (bits % 8)
22194         len++;
22195 
22196 #ifdef WOLFSSL_SMALL_STACK
22197     buff   = (byte*)XMALLOC(1024,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
22198     tmpRNG = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
22199     if (buff == NULL || tmpRNG == NULL) {
22200         XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
22201         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
22202         return ret;
22203     }
22204 #endif
22205 
22206     if (bn == NULL || bn->internal == NULL)
22207         WOLFSSL_MSG("Bad function arguments");
22208     else if (wc_InitRng(tmpRNG) == 0) {
22209         rng = tmpRNG;
22210         initTmpRng = 1;
22211     }
22212     else if (initGlobalRNG)
22213         rng = &globalRNG;
22214 
22215     if (rng) {
22216         if (wc_RNG_GenerateBlock(rng, buff, len) != 0)
22217             WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
22218         else {
22219             buff[0]     |= 0x80 | 0x40;
22220             buff[len-1] |= 0x01;
22221 
22222             if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY)
22223                 WOLFSSL_MSG("mp read bin failed");
22224             else
22225                 ret = WOLFSSL_SUCCESS;
22226         }
22227     }
22228 
22229     if (initTmpRng)
22230         wc_FreeRng(tmpRNG);
22231 
22232 #ifdef WOLFSSL_SMALL_STACK
22233     XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
22234     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
22235 #endif
22236 
22237     return ret;
22238 }
22239 
22240 
22241 /* WOLFSSL_SUCCESS on ok
22242  * code is same as wolfSSL_BN_rand except for how top and bottom is handled.
22243  * top -1 then leave most sig bit alone
22244  * top 0 then most sig is set to 1
22245  * top is 1 then first two most sig bits are 1
22246  *
22247  * bottom is hot then odd number */
22248 int wolfSSL_BN_pseudo_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
22249 {
22250     int           ret    = 0;
22251     int           len    = bits / 8;
22252     int           initTmpRng = 0;
22253     WC_RNG*       rng    = NULL;
22254 #ifdef WOLFSSL_SMALL_STACK
22255     WC_RNG*       tmpRNG = NULL;
22256     byte*         buff   = NULL;
22257 #else
22258     WC_RNG        tmpRNG[1];
22259     byte          buff[1024];
22260 #endif
22261 
22262     WOLFSSL_MSG("wolfSSL_BN_rand");
22263 
22264     if (bits % 8)
22265         len++;
22266 
22267 #ifdef WOLFSSL_SMALL_STACK
22268     buff   = (byte*)XMALLOC(1024,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
22269     tmpRNG = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
22270     if (buff == NULL || tmpRNG == NULL) {
22271         XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
22272         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22273         return ret;
22274     }
22275 #endif
22276 
22277     if (bn == NULL || bn->internal == NULL)
22278         WOLFSSL_MSG("Bad function arguments");
22279     else if (wc_InitRng(tmpRNG) == 0) {
22280         rng = tmpRNG;
22281         initTmpRng = 1;
22282     }
22283     else if (initGlobalRNG)
22284         rng = &globalRNG;
22285 
22286     if (rng) {
22287         if (wc_RNG_GenerateBlock(rng, buff, len) != 0)
22288             WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
22289         else {
22290             switch (top) {
22291                 case -1:
22292                     break;
22293 
22294                 case 0:
22295                     buff[0] |= 0x80;
22296                     break;
22297 
22298                 case 1:
22299                     buff[0] |= 0x80 | 0x40;
22300                     break;
22301             }
22302 
22303             if (bottom == 1) {
22304                 buff[len-1] |= 0x01;
22305             }
22306 
22307             if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY)
22308                 WOLFSSL_MSG("mp read bin failed");
22309             else
22310                 ret = WOLFSSL_SUCCESS;
22311         }
22312     }
22313 
22314     if (initTmpRng)
22315         wc_FreeRng(tmpRNG);
22316 
22317 #ifdef WOLFSSL_SMALL_STACK
22318     XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
22319     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22320 #endif
22321 
22322     return ret;
22323 }
22324 
22325 /* return code compliant with OpenSSL :
22326  *   1 if bit set, 0 else
22327  */
22328 int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM* bn, int n)
22329 {
22330     if (bn == NULL || bn->internal == NULL) {
22331         WOLFSSL_MSG("bn NULL error");
22332         return WOLFSSL_FAILURE;
22333     }
22334 
22335     if (n > DIGIT_BIT) {
22336         WOLFSSL_MSG("input bit count too large");
22337         return WOLFSSL_FAILURE;
22338     }
22339 
22340     return mp_is_bit_set((mp_int*)bn->internal, (mp_digit)n);
22341 }
22342 
22343 /* return code compliant with OpenSSL :
22344  *   1 if success, 0 else
22345  */
22346 int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n)
22347 {
22348     if (bn == NULL || bn->internal == NULL) {
22349         WOLFSSL_MSG("bn NULL error");
22350         return WOLFSSL_FAILURE;
22351     }
22352 
22353     if (mp_set_bit((mp_int*)bn->internal, n) != MP_OKAY) {
22354         WOLFSSL_MSG("mp_set_int error");
22355         return WOLFSSL_FAILURE;
22356     }
22357 
22358     return WOLFSSL_SUCCESS;
22359 }
22360 
22361 
22362 /* WOLFSSL_SUCCESS on ok */
22363 /* Note on use: this function expects str to be an even length. It is
22364  * converting pairs of bytes into 8-bit values. As an example, the RSA
22365  * public exponent is commonly 0x010001. To get it to convert, you need
22366  * to pass in the string "010001", it will fail if you use "10001". This
22367  * is an affect of how Base16_Decode() works.
22368  */
22369 int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str)
22370 {
22371     int     ret     = 0;
22372     word32  decSz   = 1024;
22373 #ifdef WOLFSSL_SMALL_STACK
22374     byte*   decoded = NULL;
22375 #else
22376     byte    decoded[1024];
22377 #endif
22378     int     weOwn = 0;
22379 
22380     WOLFSSL_MSG("wolfSSL_BN_hex2bn");
22381 
22382 #ifdef WOLFSSL_SMALL_STACK
22383     decoded = (byte*)XMALLOC(decSz, NULL, DYNAMIC_TYPE_DER);
22384     if (decoded == NULL)
22385         return ret;
22386 #endif
22387 
22388     if (str == NULL || str[0] == '\0')
22389         WOLFSSL_MSG("Bad function argument");
22390     else if (Base16_Decode((byte*)str, (int)XSTRLEN(str), decoded, &decSz) < 0)
22391         WOLFSSL_MSG("Bad Base16_Decode error");
22392     else if (bn == NULL)
22393         ret = decSz;
22394     else {
22395         if (*bn == NULL) {
22396             *bn = wolfSSL_BN_new();
22397             if (*bn != NULL) {
22398                 weOwn = 1;
22399             }
22400         }
22401 
22402         if (*bn == NULL)
22403             WOLFSSL_MSG("BN new failed");
22404         else if (wolfSSL_BN_bin2bn(decoded, decSz, *bn) == NULL) {
22405             WOLFSSL_MSG("Bad bin2bn error");
22406             if (weOwn == 1) {
22407                 wolfSSL_BN_free(*bn); /* Free new BN */
22408             }
22409         }
22410         else
22411             ret = WOLFSSL_SUCCESS;
22412     }
22413 
22414 #ifdef WOLFSSL_SMALL_STACK
22415     XFREE(decoded, NULL, DYNAMIC_TYPE_DER);
22416 #endif
22417 
22418     return ret;
22419 }
22420 
22421 
22422 WOLFSSL_BIGNUM* wolfSSL_BN_dup(const WOLFSSL_BIGNUM* bn)
22423 {
22424     WOLFSSL_BIGNUM* ret;
22425 
22426     WOLFSSL_MSG("wolfSSL_BN_dup");
22427 
22428     if (bn == NULL || bn->internal == NULL) {
22429         WOLFSSL_MSG("bn NULL error");
22430         return NULL;
22431     }
22432 
22433     ret = wolfSSL_BN_new();
22434     if (ret == NULL) {
22435         WOLFSSL_MSG("bn new error");
22436         return NULL;
22437     }
22438 
22439     if (mp_copy((mp_int*)bn->internal, (mp_int*)ret->internal) != MP_OKAY) {
22440         WOLFSSL_MSG("mp_copy error");
22441         wolfSSL_BN_free(ret);
22442         return NULL;
22443     }
22444 
22445     ret->neg = bn->neg;
22446 
22447     return ret;
22448 }
22449 
22450 
22451 WOLFSSL_BIGNUM* wolfSSL_BN_copy(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* bn)
22452 {
22453     WOLFSSL_MSG("wolfSSL_BN_copy");
22454 
22455     if (r == NULL || bn == NULL) {
22456         WOLFSSL_MSG("r or bn NULL error");
22457         return NULL;
22458     }
22459 
22460     if (mp_copy((mp_int*)bn->internal, (mp_int*)r->internal) != MP_OKAY) {
22461         WOLFSSL_MSG("mp_copy error");
22462         return NULL;
22463     }
22464 
22465     r->neg = bn->neg;
22466 
22467     return r;
22468 }
22469 
22470 /* return code compliant with OpenSSL :
22471  *   1 if success, 0 else
22472  */
22473 int wolfSSL_BN_set_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
22474 {
22475     WOLFSSL_MSG("wolfSSL_BN_set_word");
22476 
22477     if (bn == NULL) {
22478         WOLFSSL_MSG("bn NULL error");
22479         return WOLFSSL_FAILURE;
22480     }
22481 
22482     if (mp_set_int((mp_int*)bn->internal, w) != MP_OKAY) {
22483         WOLFSSL_MSG("mp_init_set_int error");
22484         return WOLFSSL_FAILURE;
22485     }
22486 
22487     return WOLFSSL_SUCCESS;
22488 }
22489 
22490 
22491 /* Returns the big number as an unsigned long if possible.
22492  *
22493  * bn  big number structure to get value from
22494  *
22495  * Returns value or 0xFFFFFFFFL if bigger than unsigned long.
22496  */
22497 unsigned long wolfSSL_BN_get_word(const WOLFSSL_BIGNUM* bn)
22498 {
22499     mp_int* mp;
22500 
22501     WOLFSSL_MSG("wolfSSL_BN_get_word");
22502 
22503     if (bn == NULL) {
22504         WOLFSSL_MSG("Invalid argument");
22505         return 0;
22506     }
22507 
22508     if (wolfSSL_BN_num_bytes(bn) > (int)sizeof(unsigned long)) {
22509         WOLFSSL_MSG("bignum is larger than unsigned long");
22510         return 0xFFFFFFFFL;
22511     }
22512     mp = (mp_int*)bn->internal;
22513 
22514     return (unsigned long)(mp->dp[0]);
22515 }
22516 
22517 /* return code compliant with OpenSSL :
22518  *   number length in decimal if success, 0 if error
22519  */
22520 #ifndef NO_WOLFSSL_STUB
22521 int wolfSSL_BN_dec2bn(WOLFSSL_BIGNUM** bn, const char* str)
22522 {
22523     (void)bn;
22524     (void)str;
22525 
22526     WOLFSSL_MSG("wolfSSL_BN_dec2bn");
22527     WOLFSSL_STUB("BN_dec2bn");
22528     return SSL_FAILURE;
22529 }
22530 #endif
22531 
22532 #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
22533 char *wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM *bn)
22534 {
22535     int len = 0;
22536     char *buf;
22537 
22538     WOLFSSL_MSG("wolfSSL_BN_bn2dec");
22539 
22540     if (bn == NULL || bn->internal == NULL) {
22541         WOLFSSL_MSG("bn NULL error");
22542         return NULL;
22543     }
22544 
22545     if (mp_radix_size((mp_int*)bn->internal, MP_RADIX_DEC, &len) != MP_OKAY) {
22546         WOLFSSL_MSG("mp_radix_size failure");
22547         return NULL;
22548     }
22549 
22550     buf = (char*) XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
22551     if (buf == NULL) {
22552         WOLFSSL_MSG("BN_bn2dec malloc buffer failure");
22553         return NULL;
22554     }
22555 
22556     if (mp_todecimal((mp_int*)bn->internal, buf) != MP_OKAY) {
22557         XFREE(buf, NULL, DYNAMIC_TYPE_ECC);
22558         return NULL;
22559     }
22560 
22561     return buf;
22562 }
22563 #else
22564 char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM* bn)
22565 {
22566     (void)bn;
22567 
22568     WOLFSSL_MSG("wolfSSL_BN_bn2dec");
22569 
22570     return NULL;
22571 }
22572 #endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
22573 
22574 /* return code compliant with OpenSSL :
22575  *   1 if success, 0 else
22576  */
22577 int wolfSSL_BN_lshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
22578 {
22579     WOLFSSL_MSG("wolfSSL_BN_lshift");
22580 
22581     if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
22582         WOLFSSL_MSG("bn NULL error");
22583         return WOLFSSL_FAILURE;
22584     }
22585 
22586     if (mp_mul_2d((mp_int*)bn->internal, n, (mp_int*)r->internal) != MP_OKAY) {
22587         WOLFSSL_MSG("mp_mul_2d error");
22588         return WOLFSSL_FAILURE;
22589     }
22590 
22591     return WOLFSSL_SUCCESS;
22592 }
22593 
22594 /* return code compliant with OpenSSL :
22595  *   1 if success, 0 else
22596  */
22597 int wolfSSL_BN_rshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
22598 {
22599     WOLFSSL_MSG("wolfSSL_BN_rshift");
22600 
22601     if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
22602         WOLFSSL_MSG("bn NULL error");
22603         return WOLFSSL_FAILURE;
22604     }
22605 
22606     if (mp_div_2d((mp_int*)bn->internal, n,
22607                   (mp_int*)r->internal, NULL) != MP_OKAY) {
22608         WOLFSSL_MSG("mp_mul_2d error");
22609         return WOLFSSL_FAILURE;
22610     }
22611 
22612     return WOLFSSL_SUCCESS;
22613 }
22614 
22615 /* return code compliant with OpenSSL :
22616  *   1 if success, 0 else
22617  */
22618 int wolfSSL_BN_add_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w)
22619 {
22620     WOLFSSL_MSG("wolfSSL_BN_add_word");
22621 
22622     if (bn == NULL || bn->internal == NULL) {
22623         WOLFSSL_MSG("bn NULL error");
22624         return WOLFSSL_FAILURE;
22625     }
22626 
22627     if (mp_add_d((mp_int*)bn->internal, w, (mp_int*)bn->internal) != MP_OKAY) {
22628         WOLFSSL_MSG("mp_add_d error");
22629         return WOLFSSL_FAILURE;
22630     }
22631 
22632     return WOLFSSL_SUCCESS;
22633 }
22634 
22635 /* return code compliant with OpenSSL :
22636  *   1 if success, 0 else
22637  */
22638 int wolfSSL_BN_add(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a, WOLFSSL_BIGNUM *b)
22639 {
22640     WOLFSSL_MSG("wolfSSL_BN_add");
22641 
22642     if (r == NULL || r->internal == NULL || a == NULL || a->internal == NULL ||
22643         b == NULL || b->internal == NULL) {
22644         WOLFSSL_MSG("bn NULL error");
22645         return WOLFSSL_FAILURE;
22646     }
22647 
22648     if (mp_add((mp_int*)a->internal, (mp_int*)b->internal,
22649                (mp_int*)r->internal) != MP_OKAY) {
22650         WOLFSSL_MSG("mp_add_d error");
22651         return WOLFSSL_FAILURE;
22652     }
22653 
22654     return WOLFSSL_SUCCESS;
22655 }
22656 
22657 #ifdef WOLFSSL_KEY_GEN
22658 
22659 /* return code compliant with OpenSSL :
22660  *   1 if prime, 0 if not, -1 if error
22661  */
22662 int wolfSSL_BN_is_prime_ex(const WOLFSSL_BIGNUM *bn, int nbchecks,
22663                            WOLFSSL_BN_CTX *ctx, WOLFSSL_BN_GENCB *cb)
22664 {
22665     int res;
22666 
22667     (void)ctx;
22668     (void)cb;
22669 
22670     WOLFSSL_MSG("wolfSSL_BN_is_prime_ex");
22671 
22672     if (bn == NULL || bn->internal == NULL) {
22673         WOLFSSL_MSG("bn NULL error");
22674         return WOLFSSL_FATAL_ERROR;
22675     }
22676 
22677     if (mp_prime_is_prime((mp_int*)bn->internal, nbchecks, &res) != MP_OKAY) {
22678         WOLFSSL_MSG("mp_prime_is_prime error");
22679         return WOLFSSL_FATAL_ERROR;
22680     }
22681 
22682     if (res != MP_YES) {
22683         WOLFSSL_MSG("mp_prime_is_prime not prime");
22684         return WOLFSSL_FAILURE;
22685     }
22686 
22687     return WOLFSSL_SUCCESS;
22688 }
22689 
22690 /* return code compliant with OpenSSL :
22691  *   (bn mod w) if success, -1 if error
22692  */
22693 WOLFSSL_BN_ULONG wolfSSL_BN_mod_word(const WOLFSSL_BIGNUM *bn,
22694                                      WOLFSSL_BN_ULONG w)
22695 {
22696     WOLFSSL_BN_ULONG ret = 0;
22697 
22698     WOLFSSL_MSG("wolfSSL_BN_mod_word");
22699 
22700     if (bn == NULL || bn->internal == NULL) {
22701         WOLFSSL_MSG("bn NULL error");
22702         return (WOLFSSL_BN_ULONG)WOLFSSL_FATAL_ERROR;
22703     }
22704 
22705     if (mp_mod_d((mp_int*)bn->internal, w, &ret) != MP_OKAY) {
22706         WOLFSSL_MSG("mp_add_d error");
22707         return (WOLFSSL_BN_ULONG)WOLFSSL_FATAL_ERROR;
22708     }
22709 
22710     return ret;
22711 }
22712 #endif /* #ifdef WOLFSSL_KEY_GEN */
22713 
22714 char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM *bn)
22715 {
22716 #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(DEBUG_WOLFSSL)
22717     int len = 0;
22718     char *buf;
22719 
22720     WOLFSSL_ENTER("wolfSSL_BN_bn2hex");
22721 
22722     if (bn == NULL || bn->internal == NULL) {
22723         WOLFSSL_MSG("bn NULL error");
22724         return NULL;
22725     }
22726 
22727     if (mp_radix_size((mp_int*)bn->internal, MP_RADIX_HEX, &len) != MP_OKAY) {
22728         WOLFSSL_MSG("mp_radix_size failure");
22729         return NULL;
22730     }
22731 
22732     buf = (char*) XMALLOC(len, NULL, DYNAMIC_TYPE_ECC);
22733     if (buf == NULL) {
22734         WOLFSSL_MSG("BN_bn2hex malloc buffer failure");
22735         return NULL;
22736     }
22737 
22738     if (mp_tohex((mp_int*)bn->internal, buf) != MP_OKAY) {
22739         XFREE(buf, NULL, DYNAMIC_TYPE_ECC);
22740         return NULL;
22741     }
22742 
22743     return buf;
22744 #else
22745     (void)bn;
22746     WOLFSSL_MSG("wolfSSL_BN_bn2hex not compiled in");
22747     return (char*)"";
22748 #endif
22749 }
22750 
22751 #ifndef NO_FILESYSTEM
22752 /* return code compliant with OpenSSL :
22753  *   1 if success, 0 if error
22754  */
22755 int wolfSSL_BN_print_fp(XFILE fp, const WOLFSSL_BIGNUM *bn)
22756 {
22757 #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(DEBUG_WOLFSSL)
22758     char *buf;
22759 
22760     WOLFSSL_ENTER("wolfSSL_BN_print_fp");
22761 
22762     if (fp == NULL || bn == NULL || bn->internal == NULL) {
22763         WOLFSSL_MSG("bn NULL error");
22764         return WOLFSSL_FAILURE;
22765     }
22766 
22767     buf = wolfSSL_BN_bn2hex(bn);
22768     if (buf == NULL) {
22769         WOLFSSL_MSG("wolfSSL_BN_bn2hex failure");
22770         return WOLFSSL_FAILURE;
22771     }
22772 
22773     fprintf(fp, "%s", buf);
22774     XFREE(buf, NULL, DYNAMIC_TYPE_ECC);
22775 
22776     return WOLFSSL_SUCCESS;
22777 #else
22778     (void)fp;
22779     (void)bn;
22780 
22781     WOLFSSL_MSG("wolfSSL_BN_print_fp not compiled in");
22782 
22783     return WOLFSSL_SUCCESS;
22784 #endif
22785 }
22786 #endif /* !NO_FILESYSTEM */
22787 
22788 
22789 WOLFSSL_BIGNUM *wolfSSL_BN_CTX_get(WOLFSSL_BN_CTX *ctx)
22790 {
22791     /* ctx is not used, return new Bignum */
22792     (void)ctx;
22793 
22794     WOLFSSL_ENTER("wolfSSL_BN_CTX_get");
22795 
22796     return wolfSSL_BN_new();
22797 }
22798 
22799 #ifndef NO_WOLFSSL_STUB
22800 void wolfSSL_BN_CTX_start(WOLFSSL_BN_CTX *ctx)
22801 {
22802     (void)ctx;
22803 
22804     WOLFSSL_ENTER("wolfSSL_BN_CTX_start");
22805     WOLFSSL_STUB("BN_CTX_start");
22806     WOLFSSL_MSG("wolfSSL_BN_CTX_start TBD");
22807 }
22808 #endif
22809 
22810 
22811 WOLFSSL_BIGNUM *wolfSSL_BN_mod_inverse(WOLFSSL_BIGNUM *r,
22812                                        WOLFSSL_BIGNUM *a,
22813                                        const WOLFSSL_BIGNUM *n,
22814                                        WOLFSSL_BN_CTX *ctx)
22815 {
22816     int dynamic = 0;
22817 
22818     /* ctx is not used */
22819     (void)ctx;
22820 
22821     WOLFSSL_ENTER("wolfSSL_BN_mod_inverse");
22822 
22823     /* check parameter */
22824     if (r == NULL) {
22825         r = wolfSSL_BN_new();
22826         if (r == NULL){
22827             WOLFSSL_MSG("WolfSSL_BN_new() failed");
22828             return NULL;
22829         }
22830         dynamic = 1;
22831     }
22832 
22833     if (a == NULL) {
22834         WOLFSSL_MSG("a NULL error");
22835         if (dynamic == 1) {
22836             wolfSSL_BN_free(r);
22837         }
22838         return NULL;
22839     }
22840 
22841     if (n == NULL) {
22842         WOLFSSL_MSG("n NULL error");
22843         if (dynamic == 1) {
22844             wolfSSL_BN_free(r);
22845         }
22846         return NULL;
22847     }
22848 
22849     /* Compute inverse of a modulo n and return r */
22850     if (mp_invmod((mp_int *)a->internal,(mp_int *)n->internal,
22851                   (mp_int*)r->internal) == MP_VAL){
22852         WOLFSSL_MSG("mp_invmod() error");
22853         if (dynamic == 1) {
22854             wolfSSL_BN_free(r);
22855         }
22856         return NULL;
22857     }
22858 
22859     return  r;
22860 }
22861 
22862 #ifndef NO_DH
22863 
22864 static void InitwolfSSL_DH(WOLFSSL_DH* dh)
22865 {
22866     if (dh) {
22867         dh->p        = NULL;
22868         dh->g        = NULL;
22869         dh->q        = NULL;
22870         dh->pub_key  = NULL;
22871         dh->priv_key = NULL;
22872         dh->internal = NULL;
22873         dh->inSet    = 0;
22874         dh->exSet    = 0;
22875     }
22876 }
22877 
22878 
22879 WOLFSSL_DH* wolfSSL_DH_new(void)
22880 {
22881     WOLFSSL_DH* external;
22882     DhKey*     key;
22883 
22884     WOLFSSL_MSG("wolfSSL_DH_new");
22885 
22886     key = (DhKey*) XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
22887     if (key == NULL) {
22888         WOLFSSL_MSG("wolfSSL_DH_new malloc DhKey failure");
22889         return NULL;
22890     }
22891 
22892     external = (WOLFSSL_DH*) XMALLOC(sizeof(WOLFSSL_DH), NULL,
22893                                     DYNAMIC_TYPE_DH);
22894     if (external == NULL) {
22895         WOLFSSL_MSG("wolfSSL_DH_new malloc WOLFSSL_DH failure");
22896         XFREE(key, NULL, DYNAMIC_TYPE_DH);
22897         return NULL;
22898     }
22899 
22900     InitwolfSSL_DH(external);
22901     if (wc_InitDhKey(key) != 0) {
22902         WOLFSSL_MSG("wolfSSL_DH_new InitDhKey failure");
22903         XFREE(key, NULL, DYNAMIC_TYPE_DH);
22904         XFREE(external, NULL, DYNAMIC_TYPE_DH);
22905         return NULL;
22906     }
22907     external->internal = key;
22908 
22909     return external;
22910 }
22911 
22912 
22913 void wolfSSL_DH_free(WOLFSSL_DH* dh)
22914 {
22915     WOLFSSL_MSG("wolfSSL_DH_free");
22916 
22917     if (dh) {
22918         if (dh->internal) {
22919             wc_FreeDhKey((DhKey*)dh->internal);
22920             XFREE(dh->internal, NULL, DYNAMIC_TYPE_DH);
22921             dh->internal = NULL;
22922         }
22923         wolfSSL_BN_free(dh->priv_key);
22924         wolfSSL_BN_free(dh->pub_key);
22925         wolfSSL_BN_free(dh->g);
22926         wolfSSL_BN_free(dh->p);
22927         wolfSSL_BN_free(dh->q);
22928         InitwolfSSL_DH(dh);  /* set back to NULLs for safety */
22929 
22930         XFREE(dh, NULL, DYNAMIC_TYPE_DH);
22931     }
22932 }
22933 
22934 
22935 static int SetDhInternal(WOLFSSL_DH* dh)
22936 {
22937     int            ret = WOLFSSL_FATAL_ERROR;
22938     int            pSz = 1024;
22939     int            gSz = 1024;
22940 #ifdef WOLFSSL_SMALL_STACK
22941     unsigned char* p   = NULL;
22942     unsigned char* g   = NULL;
22943 #else
22944     unsigned char  p[1024];
22945     unsigned char  g[1024];
22946 #endif
22947 
22948     WOLFSSL_ENTER("SetDhInternal");
22949 
22950     if (dh == NULL || dh->p == NULL || dh->g == NULL)
22951         WOLFSSL_MSG("Bad function arguments");
22952     else if (wolfSSL_BN_bn2bin(dh->p, NULL) > pSz)
22953         WOLFSSL_MSG("Bad p internal size");
22954     else if (wolfSSL_BN_bn2bin(dh->g, NULL) > gSz)
22955         WOLFSSL_MSG("Bad g internal size");
22956     else {
22957     #ifdef WOLFSSL_SMALL_STACK
22958         p = (unsigned char*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
22959         g = (unsigned char*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
22960 
22961         if (p == NULL || g == NULL) {
22962             XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
22963             XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
22964             return ret;
22965         }
22966     #endif
22967 
22968         pSz = wolfSSL_BN_bn2bin(dh->p, p);
22969         gSz = wolfSSL_BN_bn2bin(dh->g, g);
22970 
22971         if (pSz <= 0 || gSz <= 0)
22972             WOLFSSL_MSG("Bad BN2bin set");
22973         else if (wc_DhSetKey((DhKey*)dh->internal, p, pSz, g, gSz) < 0)
22974             WOLFSSL_MSG("Bad DH SetKey");
22975         else {
22976             dh->inSet = 1;
22977             ret = WOLFSSL_SUCCESS;
22978         }
22979 
22980     #ifdef WOLFSSL_SMALL_STACK
22981         XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
22982         XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
22983     #endif
22984     }
22985 
22986 
22987     return ret;
22988 }
22989 
22990 /* return code compliant with OpenSSL :
22991  *   DH prime size in bytes if success, 0 if error
22992  */
22993 int wolfSSL_DH_size(WOLFSSL_DH* dh)
22994 {
22995     WOLFSSL_MSG("wolfSSL_DH_size");
22996 
22997     if (dh == NULL)
22998         return WOLFSSL_FATAL_ERROR;
22999 
23000     return wolfSSL_BN_num_bytes(dh->p);
23001 }
23002 
23003 
23004 /* This sets a big number with the 1536-bit prime from RFC 3526.
23005  *
23006  * bn  if not NULL then the big number structure is used. If NULL then a new
23007  *     big number structure is created.
23008  *
23009  * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
23010  */
23011 WOLFSSL_BIGNUM* wolfSSL_DH_1536_prime(WOLFSSL_BIGNUM* bn)
23012 {
23013     const char prm[] = {
23014         "FFFFFFFFFFFFFFFFC90FDAA22168C234"
23015         "C4C6628B80DC1CD129024E088A67CC74"
23016         "020BBEA63B139B22514A08798E3404DD"
23017         "EF9519B3CD3A431B302B0A6DF25F1437"
23018         "4FE1356D6D51C245E485B576625E7EC6"
23019         "F44C42E9A637ED6B0BFF5CB6F406B7ED"
23020         "EE386BFB5A899FA5AE9F24117C4B1FE6"
23021         "49286651ECE45B3DC2007CB8A163BF05"
23022         "98DA48361C55D39A69163FA8FD24CF5F"
23023         "83655D23DCA3AD961C62F356208552BB"
23024         "9ED529077096966D670C354E4ABC9804"
23025         "F1746C08CA237327FFFFFFFFFFFFFFFF"
23026     };
23027 
23028     WOLFSSL_ENTER("wolfSSL_DH_1536_prime");
23029 
23030     if (wolfSSL_BN_hex2bn(&bn, prm) != SSL_SUCCESS) {
23031         WOLFSSL_MSG("Error converting DH 1536 prime to big number");
23032         return NULL;
23033     }
23034 
23035     return bn;
23036 }
23037 
23038 
23039 /* return code compliant with OpenSSL :
23040  *   1 if success, 0 if error
23041  */
23042 int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
23043 {
23044     int            ret    = WOLFSSL_FAILURE;
23045     word32         pubSz  = 768;
23046     word32         privSz = 768;
23047     int            initTmpRng = 0;
23048     WC_RNG*        rng    = NULL;
23049 #ifdef WOLFSSL_SMALL_STACK
23050     unsigned char* pub    = NULL;
23051     unsigned char* priv   = NULL;
23052     WC_RNG*        tmpRNG = NULL;
23053 #else
23054     unsigned char  pub [768];
23055     unsigned char  priv[768];
23056     WC_RNG         tmpRNG[1];
23057 #endif
23058 
23059     WOLFSSL_MSG("wolfSSL_DH_generate_key");
23060 
23061 #ifdef WOLFSSL_SMALL_STACK
23062     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
23063     pub    = (unsigned char*)XMALLOC(pubSz,   NULL, DYNAMIC_TYPE_PUBLIC_KEY);
23064     priv   = (unsigned char*)XMALLOC(privSz,  NULL, DYNAMIC_TYPE_PRIVATE_KEY);
23065 
23066     if (tmpRNG == NULL || pub == NULL || priv == NULL) {
23067         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
23068         XFREE(pub,    NULL, DYNAMIC_TYPE_PUBLIC_KEY);
23069         XFREE(priv,   NULL, DYNAMIC_TYPE_PRIVATE_KEY);
23070         return ret;
23071     }
23072 #endif
23073 
23074     if (dh == NULL || dh->p == NULL || dh->g == NULL)
23075         WOLFSSL_MSG("Bad function arguments");
23076     else if (dh->inSet == 0 && SetDhInternal(dh) != WOLFSSL_SUCCESS)
23077             WOLFSSL_MSG("Bad DH set internal");
23078     else if (wc_InitRng(tmpRNG) == 0) {
23079         rng = tmpRNG;
23080         initTmpRng = 1;
23081     }
23082     else {
23083         WOLFSSL_MSG("Bad RNG Init, trying global");
23084         if (initGlobalRNG == 0)
23085             WOLFSSL_MSG("Global RNG no Init");
23086         else
23087             rng = &globalRNG;
23088     }
23089 
23090     if (rng) {
23091        if (wc_DhGenerateKeyPair((DhKey*)dh->internal, rng, priv, &privSz,
23092                                                                pub, &pubSz) < 0)
23093             WOLFSSL_MSG("Bad wc_DhGenerateKeyPair");
23094        else {
23095             if (dh->pub_key)
23096                 wolfSSL_BN_free(dh->pub_key);
23097 
23098             dh->pub_key = wolfSSL_BN_new();
23099             if (dh->pub_key == NULL) {
23100                 WOLFSSL_MSG("Bad DH new pub");
23101             }
23102             if (dh->priv_key)
23103                 wolfSSL_BN_free(dh->priv_key);
23104 
23105             dh->priv_key = wolfSSL_BN_new();
23106 
23107             if (dh->priv_key == NULL) {
23108                 WOLFSSL_MSG("Bad DH new priv");
23109             }
23110 
23111             if (dh->pub_key && dh->priv_key) {
23112                if (wolfSSL_BN_bin2bn(pub, pubSz, dh->pub_key) == NULL)
23113                    WOLFSSL_MSG("Bad DH bn2bin error pub");
23114                else if (wolfSSL_BN_bin2bn(priv, privSz, dh->priv_key) == NULL)
23115                    WOLFSSL_MSG("Bad DH bn2bin error priv");
23116                else
23117                    ret = WOLFSSL_SUCCESS;
23118             }
23119         }
23120     }
23121 
23122     if (initTmpRng)
23123         wc_FreeRng(tmpRNG);
23124 
23125 #ifdef WOLFSSL_SMALL_STACK
23126     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
23127     XFREE(pub,    NULL, DYNAMIC_TYPE_PUBLIC_KEY);
23128     XFREE(priv,   NULL, DYNAMIC_TYPE_PRIVATE_KEY);
23129 #endif
23130 
23131     return ret;
23132 }
23133 
23134 
23135 /* return code compliant with OpenSSL :
23136  *   size of shared secret if success, -1 if error
23137  */
23138 int wolfSSL_DH_compute_key(unsigned char* key, WOLFSSL_BIGNUM* otherPub,
23139                           WOLFSSL_DH* dh)
23140 {
23141     int            ret    = WOLFSSL_FATAL_ERROR;
23142     word32         keySz  = 0;
23143     word32         pubSz  = 1024;
23144     word32         privSz = 1024;
23145 #ifdef WOLFSSL_SMALL_STACK
23146     unsigned char* pub    = NULL;
23147     unsigned char* priv   = NULL;
23148 #else
23149     unsigned char  pub [1024];
23150     unsigned char  priv[1024];
23151 #endif
23152 
23153     WOLFSSL_MSG("wolfSSL_DH_compute_key");
23154 
23155 #ifdef WOLFSSL_SMALL_STACK
23156     pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
23157     if (pub == NULL)
23158         return ret;
23159 
23160     priv = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
23161     if (priv == NULL) {
23162         XFREE(pub, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
23163         return ret;
23164     }
23165 #endif
23166 
23167     if (dh == NULL || dh->priv_key == NULL || otherPub == NULL)
23168         WOLFSSL_MSG("Bad function arguments");
23169     else if ((keySz = (word32)DH_size(dh)) == 0)
23170         WOLFSSL_MSG("Bad DH_size");
23171     else if (wolfSSL_BN_bn2bin(dh->priv_key, NULL) > (int)privSz)
23172         WOLFSSL_MSG("Bad priv internal size");
23173     else if (wolfSSL_BN_bn2bin(otherPub, NULL) > (int)pubSz)
23174         WOLFSSL_MSG("Bad otherPub size");
23175     else {
23176         privSz = wolfSSL_BN_bn2bin(dh->priv_key, priv);
23177         pubSz  = wolfSSL_BN_bn2bin(otherPub, pub);
23178         if (dh->inSet == 0 && SetDhInternal(dh) != SSL_SUCCESS){
23179                 WOLFSSL_MSG("Bad DH set internal");
23180         }
23181         if (privSz <= 0 || pubSz <= 0)
23182             WOLFSSL_MSG("Bad BN2bin set");
23183         else if (wc_DhAgree((DhKey*)dh->internal, key, &keySz,
23184                             priv, privSz, pub, pubSz) < 0)
23185             WOLFSSL_MSG("wc_DhAgree failed");
23186         else
23187             ret = (int)keySz;
23188     }
23189 
23190 #ifdef WOLFSSL_SMALL_STACK
23191     XFREE(pub,  NULL, DYNAMIC_TYPE_PUBLIC_KEY);
23192     XFREE(priv, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
23193 #endif
23194 
23195     return ret;
23196 }
23197 #endif /* NO_DH */
23198 
23199 
23200 #ifndef NO_DSA
23201 static void InitwolfSSL_DSA(WOLFSSL_DSA* dsa)
23202 {
23203     if (dsa) {
23204         dsa->p        = NULL;
23205         dsa->q        = NULL;
23206         dsa->g        = NULL;
23207         dsa->pub_key  = NULL;
23208         dsa->priv_key = NULL;
23209         dsa->internal = NULL;
23210         dsa->inSet    = 0;
23211         dsa->exSet    = 0;
23212     }
23213 }
23214 
23215 
23216 WOLFSSL_DSA* wolfSSL_DSA_new(void)
23217 {
23218     WOLFSSL_DSA* external;
23219     DsaKey*     key;
23220 
23221     WOLFSSL_MSG("wolfSSL_DSA_new");
23222 
23223     key = (DsaKey*) XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
23224     if (key == NULL) {
23225         WOLFSSL_MSG("wolfSSL_DSA_new malloc DsaKey failure");
23226         return NULL;
23227     }
23228 
23229     external = (WOLFSSL_DSA*) XMALLOC(sizeof(WOLFSSL_DSA), NULL,
23230                                     DYNAMIC_TYPE_DSA);
23231     if (external == NULL) {
23232         WOLFSSL_MSG("wolfSSL_DSA_new malloc WOLFSSL_DSA failure");
23233         XFREE(key, NULL, DYNAMIC_TYPE_DSA);
23234         return NULL;
23235     }
23236 
23237     InitwolfSSL_DSA(external);
23238     if (wc_InitDsaKey(key) != 0) {
23239         WOLFSSL_MSG("wolfSSL_DSA_new InitDsaKey failure");
23240         XFREE(key, NULL, DYNAMIC_TYPE_DSA);
23241         wolfSSL_DSA_free(external);
23242         return NULL;
23243     }
23244     external->internal = key;
23245 
23246     return external;
23247 }
23248 
23249 
23250 void wolfSSL_DSA_free(WOLFSSL_DSA* dsa)
23251 {
23252     WOLFSSL_MSG("wolfSSL_DSA_free");
23253 
23254     if (dsa) {
23255         if (dsa->internal) {
23256             FreeDsaKey((DsaKey*)dsa->internal);
23257             XFREE(dsa->internal, NULL, DYNAMIC_TYPE_DSA);
23258             dsa->internal = NULL;
23259         }
23260         wolfSSL_BN_free(dsa->priv_key);
23261         wolfSSL_BN_free(dsa->pub_key);
23262         wolfSSL_BN_free(dsa->g);
23263         wolfSSL_BN_free(dsa->q);
23264         wolfSSL_BN_free(dsa->p);
23265         InitwolfSSL_DSA(dsa);  /* set back to NULLs for safety */
23266 
23267         XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
23268         dsa = NULL;
23269     }
23270 }
23271 
23272 #endif /* NO_DSA */
23273 
23274 #endif /* OPENSSL_EXTRA */
23275 #if !defined(NO_RSA) && defined(OPENSSL_EXTRA_X509_SMALL)
23276 static void InitwolfSSL_Rsa(WOLFSSL_RSA* rsa)
23277 {
23278     if (rsa) {
23279         XMEMSET(rsa, 0, sizeof(WOLFSSL_RSA));
23280     }
23281 }
23282 
23283 void wolfSSL_RSA_free(WOLFSSL_RSA* rsa)
23284 {
23285     WOLFSSL_ENTER("wolfSSL_RSA_free");
23286 
23287     if (rsa) {
23288         if (rsa->internal) {
23289 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \
23290     !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING)
23291             WC_RNG* rng;
23292 
23293             /* check if RNG is owned before freeing it */
23294             if (rsa->ownRng) {
23295                 rng = ((RsaKey*)rsa->internal)->rng;
23296                 if (rng != NULL && rng != &globalRNG) {
23297                     wc_FreeRng(rng);
23298                     XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
23299                 }
23300             }
23301 #endif /* WC_RSA_BLINDING */
23302             wc_FreeRsaKey((RsaKey*)rsa->internal);
23303             XFREE(rsa->internal, NULL, DYNAMIC_TYPE_RSA);
23304             rsa->internal = NULL;
23305         }
23306         wolfSSL_BN_free(rsa->iqmp);
23307         wolfSSL_BN_free(rsa->dmq1);
23308         wolfSSL_BN_free(rsa->dmp1);
23309         wolfSSL_BN_free(rsa->q);
23310         wolfSSL_BN_free(rsa->p);
23311         wolfSSL_BN_free(rsa->d);
23312         wolfSSL_BN_free(rsa->e);
23313         wolfSSL_BN_free(rsa->n);
23314 
23315     #ifdef WC_RSA_BLINDING
23316         if (wc_FreeRng(rsa->rng) != 0) {
23317             WOLFSSL_MSG("Issue freeing rng");
23318         }
23319         XFREE(rsa->rng, NULL, DYNAMIC_TYPE_RNG);
23320     #endif
23321 
23322         InitwolfSSL_Rsa(rsa);  /* set back to NULLs for safety */
23323 
23324         XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
23325         rsa = NULL;
23326     }
23327 }
23328 
23329 WOLFSSL_RSA* wolfSSL_RSA_new(void)
23330 {
23331     WOLFSSL_RSA* external;
23332     RsaKey*     key;
23333 
23334     WOLFSSL_ENTER("wolfSSL_RSA_new");
23335 
23336     key = (RsaKey*) XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
23337     if (key == NULL) {
23338         WOLFSSL_MSG("wolfSSL_RSA_new malloc RsaKey failure");
23339         return NULL;
23340     }
23341 
23342     external = (WOLFSSL_RSA*) XMALLOC(sizeof(WOLFSSL_RSA), NULL,
23343                                      DYNAMIC_TYPE_RSA);
23344     if (external == NULL) {
23345         WOLFSSL_MSG("wolfSSL_RSA_new malloc WOLFSSL_RSA failure");
23346         XFREE(key, NULL, DYNAMIC_TYPE_RSA);
23347         return NULL;
23348     }
23349 
23350     InitwolfSSL_Rsa(external);
23351     if (wc_InitRsaKey(key, NULL) != 0) {
23352         WOLFSSL_MSG("InitRsaKey WOLFSSL_RSA failure");
23353         XFREE(external, NULL, DYNAMIC_TYPE_RSA);
23354         XFREE(key, NULL, DYNAMIC_TYPE_RSA);
23355         return NULL;
23356     }
23357 
23358 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \
23359     !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING)
23360     {
23361         WC_RNG* rng = NULL;
23362 
23363         rng = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
23364         if (rng != NULL && wc_InitRng(rng) != 0) {
23365             WOLFSSL_MSG("InitRng failure, attempting to use global RNG");
23366             XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
23367             rng = NULL;
23368         }
23369 
23370         external->ownRng = 1;
23371         if (rng == NULL && initGlobalRNG) {
23372             external->ownRng = 0;
23373             rng = &globalRNG;
23374         }
23375 
23376         if (rng == NULL) {
23377             WOLFSSL_MSG("wolfSSL_RSA_new no WC_RNG for blinding");
23378             XFREE(external, NULL, DYNAMIC_TYPE_RSA);
23379             XFREE(key, NULL, DYNAMIC_TYPE_RSA);
23380             return NULL;
23381         }
23382 
23383         wc_RsaSetRNG(key, rng);
23384     }
23385 #endif /* WC_RSA_BLINDING */
23386 
23387     external->internal = key;
23388     external->inSet = 0;
23389     return external;
23390 }
23391 #endif /* !NO_RSA && OPENSSL_EXTRA_X509_SMALL */
23392 
23393 /* these defines are to make sure the functions SetIndividualExternal is not
23394  * declared and then not used. */
23395 #if !defined(NO_ASN) || !defined(NO_DSA) || defined(HAVE_ECC) || \
23396     (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA))
23397 
23398 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
23399 /* when calling SetIndividualExternal, mpi should be cleared by caller if no
23400  * longer used. ie mp_clear(mpi). This is to free data when fastmath is
23401  * disabled since a copy of mpi is made by this function and placed into bn.
23402  */
23403 static int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi)
23404 {
23405     byte dynamic = 0;
23406 
23407     WOLFSSL_MSG("Entering SetIndividualExternal");
23408 
23409     if (mpi == NULL || bn == NULL) {
23410         WOLFSSL_MSG("mpi NULL error");
23411         return WOLFSSL_FATAL_ERROR;
23412     }
23413 
23414     if (*bn == NULL) {
23415         *bn = wolfSSL_BN_new();
23416         if (*bn == NULL) {
23417             WOLFSSL_MSG("SetIndividualExternal alloc failed");
23418             return WOLFSSL_FATAL_ERROR;
23419         }
23420         dynamic = 1;
23421     }
23422 
23423     if (mp_copy(mpi, (mp_int*)((*bn)->internal)) != MP_OKAY) {
23424         WOLFSSL_MSG("mp_copy error");
23425         if (dynamic == 1) {
23426             wolfSSL_BN_free(*bn);
23427         }
23428         return WOLFSSL_FATAL_ERROR;
23429     }
23430 
23431     return WOLFSSL_SUCCESS;
23432 }
23433 #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
23434 
23435 #ifdef OPENSSL_EXTRA /* only without X509_SMALL */
23436 static int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi)
23437 {
23438     WOLFSSL_MSG("Entering SetIndividualInternal");
23439 
23440     if (bn == NULL || bn->internal == NULL) {
23441         WOLFSSL_MSG("bn NULL error");
23442         return WOLFSSL_FATAL_ERROR;
23443     }
23444 
23445     if (mpi == NULL || (mp_init(mpi) != MP_OKAY)) {
23446         WOLFSSL_MSG("mpi NULL error");
23447         return WOLFSSL_FATAL_ERROR;
23448     }
23449 
23450     if (mp_copy((mp_int*)bn->internal, mpi) != MP_OKAY) {
23451         WOLFSSL_MSG("mp_copy error");
23452         return WOLFSSL_FATAL_ERROR;
23453     }
23454 
23455     return WOLFSSL_SUCCESS;
23456 }
23457 
23458 #ifndef NO_ASN
23459 WOLFSSL_BIGNUM *wolfSSL_ASN1_INTEGER_to_BN(const WOLFSSL_ASN1_INTEGER *ai,
23460                                        WOLFSSL_BIGNUM *bn)
23461 {
23462     mp_int mpi;
23463     word32 idx = 0;
23464     int ret;
23465 
23466     WOLFSSL_ENTER("wolfSSL_ASN1_INTEGER_to_BN");
23467 
23468     if (ai == NULL) {
23469         return NULL;
23470     }
23471 
23472     if ((ret = GetInt(&mpi, ai->data, &idx, ai->dataMax)) != 0) {
23473         /* expecting ASN1 format for INTEGER */
23474         WOLFSSL_LEAVE("wolfSSL_ASN1_INTEGER_to_BN", ret);
23475         return NULL;
23476     }
23477 
23478     /* mp_clear needs called because mpi is copied and causes memory leak with
23479      * --disable-fastmath */
23480     ret = SetIndividualExternal(&bn, &mpi);
23481     mp_clear(&mpi);
23482 
23483     if (ret != WOLFSSL_SUCCESS) {
23484         return NULL;
23485     }
23486     return bn;
23487 }
23488 #endif /* !NO_ASN */
23489 
23490 #if !defined(NO_DSA) && !defined(NO_DH)
23491 WOLFSSL_DH *wolfSSL_DSA_dup_DH(const WOLFSSL_DSA *dsa)
23492 {
23493     WOLFSSL_DH* dh;
23494     DhKey*      key;
23495 
23496     WOLFSSL_ENTER("wolfSSL_DSA_dup_DH");
23497 
23498     if (dsa == NULL) {
23499         return NULL;
23500     }
23501 
23502     dh = wolfSSL_DH_new();
23503     if (dh == NULL) {
23504         return NULL;
23505     }
23506     key = (DhKey*)dh->internal;
23507 
23508     if (dsa->p != NULL &&
23509         SetIndividualInternal(((WOLFSSL_DSA*)dsa)->p, &key->p) != WOLFSSL_SUCCESS) {
23510         WOLFSSL_MSG("rsa p key error");
23511         wolfSSL_DH_free(dh);
23512         return NULL;
23513     }
23514     if (dsa->g != NULL &&
23515         SetIndividualInternal(((WOLFSSL_DSA*)dsa)->g, &key->g) != WOLFSSL_SUCCESS) {
23516         WOLFSSL_MSG("rsa g key error");
23517         wolfSSL_DH_free(dh);
23518         return NULL;
23519     }
23520 
23521     if (SetIndividualExternal(&dh->p, &key->p) != WOLFSSL_SUCCESS) {
23522         WOLFSSL_MSG("dsa p key error");
23523         wolfSSL_DH_free(dh);
23524         return NULL;
23525     }
23526     if (SetIndividualExternal(&dh->g, &key->g) != WOLFSSL_SUCCESS) {
23527         WOLFSSL_MSG("dsa g key error");
23528         wolfSSL_DH_free(dh);
23529         return NULL;
23530     }
23531 
23532     return dh;
23533 }
23534 #endif /* !defined(NO_DSA) && !defined(NO_DH) */
23535 
23536 #endif /* OPENSSL_EXTRA */
23537 #endif /* !NO_RSA && !NO_DSA */
23538 
23539 #ifdef OPENSSL_EXTRA
23540 
23541 #ifndef NO_DSA
23542 /* wolfSSL -> OpenSSL */
23543 static int SetDsaExternal(WOLFSSL_DSA* dsa)
23544 {
23545     DsaKey* key;
23546     WOLFSSL_MSG("Entering SetDsaExternal");
23547 
23548     if (dsa == NULL || dsa->internal == NULL) {
23549         WOLFSSL_MSG("dsa key NULL error");
23550         return WOLFSSL_FATAL_ERROR;
23551     }
23552 
23553     key = (DsaKey*)dsa->internal;
23554 
23555     if (SetIndividualExternal(&dsa->p, &key->p) != WOLFSSL_SUCCESS) {
23556         WOLFSSL_MSG("dsa p key error");
23557         return WOLFSSL_FATAL_ERROR;
23558     }
23559 
23560     if (SetIndividualExternal(&dsa->q, &key->q) != WOLFSSL_SUCCESS) {
23561         WOLFSSL_MSG("dsa q key error");
23562         return WOLFSSL_FATAL_ERROR;
23563     }
23564 
23565     if (SetIndividualExternal(&dsa->g, &key->g) != WOLFSSL_SUCCESS) {
23566         WOLFSSL_MSG("dsa g key error");
23567         return WOLFSSL_FATAL_ERROR;
23568     }
23569 
23570     if (SetIndividualExternal(&dsa->pub_key, &key->y) != WOLFSSL_SUCCESS) {
23571         WOLFSSL_MSG("dsa y key error");
23572         return WOLFSSL_FATAL_ERROR;
23573     }
23574 
23575     if (SetIndividualExternal(&dsa->priv_key, &key->x) != WOLFSSL_SUCCESS) {
23576         WOLFSSL_MSG("dsa x key error");
23577         return WOLFSSL_FATAL_ERROR;
23578     }
23579 
23580     dsa->exSet = 1;
23581 
23582     return WOLFSSL_SUCCESS;
23583 }
23584 
23585 /* Openssl -> WolfSSL */
23586 static int SetDsaInternal(WOLFSSL_DSA* dsa)
23587 {
23588     DsaKey* key;
23589     WOLFSSL_MSG("Entering SetDsaInternal");
23590 
23591     if (dsa == NULL || dsa->internal == NULL) {
23592         WOLFSSL_MSG("dsa key NULL error");
23593         return WOLFSSL_FATAL_ERROR;
23594     }
23595 
23596     key = (DsaKey*)dsa->internal;
23597 
23598     if (dsa->p != NULL &&
23599         SetIndividualInternal(dsa->p, &key->p) != WOLFSSL_SUCCESS) {
23600         WOLFSSL_MSG("rsa p key error");
23601         return WOLFSSL_FATAL_ERROR;
23602     }
23603 
23604     if (dsa->q != NULL &&
23605         SetIndividualInternal(dsa->q, &key->q) != WOLFSSL_SUCCESS) {
23606         WOLFSSL_MSG("rsa q key error");
23607         return WOLFSSL_FATAL_ERROR;
23608     }
23609 
23610     if (dsa->g != NULL &&
23611         SetIndividualInternal(dsa->g, &key->g) != WOLFSSL_SUCCESS) {
23612         WOLFSSL_MSG("rsa g key error");
23613         return WOLFSSL_FATAL_ERROR;
23614     }
23615 
23616     if (dsa->pub_key != NULL) {
23617         if (SetIndividualInternal(dsa->pub_key, &key->y) != WOLFSSL_SUCCESS) {
23618             WOLFSSL_MSG("rsa pub_key error");
23619             return WOLFSSL_FATAL_ERROR;
23620         }
23621 
23622         /* public key */
23623         key->type = DSA_PUBLIC;
23624     }
23625 
23626     if (dsa->priv_key != NULL) {
23627         if (SetIndividualInternal(dsa->priv_key, &key->x) != WOLFSSL_SUCCESS) {
23628             WOLFSSL_MSG("rsa priv_key error");
23629             return WOLFSSL_FATAL_ERROR;
23630         }
23631 
23632         /* private key */
23633         key->type = DSA_PRIVATE;
23634     }
23635 
23636     dsa->inSet = 1;
23637 
23638     return WOLFSSL_SUCCESS;
23639 }
23640 #endif /* NO_DSA */
23641 #endif /* OPENSSL_EXTRA */
23642 
23643 #if !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) && \
23644     !defined(NO_RSA) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
23645 /* WolfSSL -> OpenSSL */
23646 static int SetRsaExternal(WOLFSSL_RSA* rsa)
23647 {
23648     RsaKey* key;
23649     WOLFSSL_MSG("Entering SetRsaExternal");
23650 
23651     if (rsa == NULL || rsa->internal == NULL) {
23652         WOLFSSL_MSG("rsa key NULL error");
23653         return WOLFSSL_FATAL_ERROR;
23654     }
23655 
23656     key = (RsaKey*)rsa->internal;
23657 
23658     if (SetIndividualExternal(&rsa->n, &key->n) != WOLFSSL_SUCCESS) {
23659         WOLFSSL_MSG("rsa n key error");
23660         return WOLFSSL_FATAL_ERROR;
23661     }
23662 
23663     if (SetIndividualExternal(&rsa->e, &key->e) != WOLFSSL_SUCCESS) {
23664         WOLFSSL_MSG("rsa e key error");
23665         return WOLFSSL_FATAL_ERROR;
23666     }
23667 
23668     if (key->type == RSA_PRIVATE) {
23669         if (SetIndividualExternal(&rsa->d, &key->d) != WOLFSSL_SUCCESS) {
23670             WOLFSSL_MSG("rsa d key error");
23671             return WOLFSSL_FATAL_ERROR;
23672         }
23673 
23674         if (SetIndividualExternal(&rsa->p, &key->p) != WOLFSSL_SUCCESS) {
23675             WOLFSSL_MSG("rsa p key error");
23676             return WOLFSSL_FATAL_ERROR;
23677         }
23678 
23679         if (SetIndividualExternal(&rsa->q, &key->q) != WOLFSSL_SUCCESS) {
23680             WOLFSSL_MSG("rsa q key error");
23681             return WOLFSSL_FATAL_ERROR;
23682         }
23683 
23684     #ifndef RSA_LOW_MEM
23685         if (SetIndividualExternal(&rsa->dmp1, &key->dP) != WOLFSSL_SUCCESS) {
23686             WOLFSSL_MSG("rsa dP key error");
23687             return WOLFSSL_FATAL_ERROR;
23688         }
23689 
23690         if (SetIndividualExternal(&rsa->dmq1, &key->dQ) != WOLFSSL_SUCCESS) {
23691             WOLFSSL_MSG("rsa dQ key error");
23692             return WOLFSSL_FATAL_ERROR;
23693         }
23694 
23695         if (SetIndividualExternal(&rsa->iqmp, &key->u) != WOLFSSL_SUCCESS) {
23696             WOLFSSL_MSG("rsa u key error");
23697             return WOLFSSL_FATAL_ERROR;
23698         }
23699     #endif /* !RSA_LOW_MEM */
23700     }
23701     rsa->exSet = 1;
23702 
23703     return WOLFSSL_SUCCESS;
23704 }
23705 #endif
23706 
23707 #ifdef OPENSSL_EXTRA
23708 #if !defined(NO_RSA)
23709 #if !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
23710 /* Openssl -> WolfSSL */
23711 static int SetRsaInternal(WOLFSSL_RSA* rsa)
23712 {
23713     RsaKey* key;
23714     WOLFSSL_MSG("Entering SetRsaInternal");
23715 
23716     if (rsa == NULL || rsa->internal == NULL) {
23717         WOLFSSL_MSG("rsa key NULL error");
23718         return WOLFSSL_FATAL_ERROR;
23719     }
23720 
23721     key = (RsaKey*)rsa->internal;
23722 
23723     if (SetIndividualInternal(rsa->n, &key->n) != WOLFSSL_SUCCESS) {
23724         WOLFSSL_MSG("rsa n key error");
23725         return WOLFSSL_FATAL_ERROR;
23726     }
23727 
23728     if (SetIndividualInternal(rsa->e, &key->e) != WOLFSSL_SUCCESS) {
23729         WOLFSSL_MSG("rsa e key error");
23730         return WOLFSSL_FATAL_ERROR;
23731     }
23732 
23733     /* public key */
23734     key->type = RSA_PUBLIC;
23735 
23736     if (rsa->d != NULL) {
23737         if (SetIndividualInternal(rsa->d, &key->d) != WOLFSSL_SUCCESS) {
23738             WOLFSSL_MSG("rsa d key error");
23739             return WOLFSSL_FATAL_ERROR;
23740         }
23741 
23742         /* private key */
23743         key->type = RSA_PRIVATE;
23744     }
23745 
23746     if (rsa->p != NULL &&
23747         SetIndividualInternal(rsa->p, &key->p) != WOLFSSL_SUCCESS) {
23748         WOLFSSL_MSG("rsa p key error");
23749         return WOLFSSL_FATAL_ERROR;
23750     }
23751 
23752     if (rsa->q != NULL &&
23753         SetIndividualInternal(rsa->q, &key->q) != WOLFSSL_SUCCESS) {
23754         WOLFSSL_MSG("rsa q key error");
23755         return WOLFSSL_FATAL_ERROR;
23756     }
23757 
23758 #ifndef RSA_LOW_MEM
23759     if (rsa->dmp1 != NULL &&
23760         SetIndividualInternal(rsa->dmp1, &key->dP) != WOLFSSL_SUCCESS) {
23761         WOLFSSL_MSG("rsa dP key error");
23762         return WOLFSSL_FATAL_ERROR;
23763     }
23764 
23765     if (rsa->dmq1 != NULL &&
23766         SetIndividualInternal(rsa->dmq1, &key->dQ) != WOLFSSL_SUCCESS) {
23767         WOLFSSL_MSG("rsa dQ key error");
23768         return WOLFSSL_FATAL_ERROR;
23769     }
23770 
23771     if (rsa->iqmp != NULL &&
23772         SetIndividualInternal(rsa->iqmp, &key->u) != WOLFSSL_SUCCESS) {
23773         WOLFSSL_MSG("rsa u key error");
23774         return WOLFSSL_FATAL_ERROR;
23775     }
23776 #endif /* !RSA_LOW_MEM */
23777 
23778     rsa->inSet = 1;
23779 
23780     return WOLFSSL_SUCCESS;
23781 }
23782 
23783 
23784 /* SSL_SUCCESS on ok */
23785 #ifndef NO_WOLFSSL_STUB
23786 int wolfSSL_RSA_blinding_on(WOLFSSL_RSA* rsa, WOLFSSL_BN_CTX* bn)
23787 {
23788     (void)rsa;
23789     (void)bn;
23790     WOLFSSL_STUB("RSA_blinding_on");
23791     WOLFSSL_MSG("wolfSSL_RSA_blinding_on");
23792 
23793     return WOLFSSL_SUCCESS;  /* on by default */
23794 }
23795 #endif
23796 
23797 /* return compliant with OpenSSL
23798  *   size of encrypted data if success , -1 if error
23799  */
23800 int wolfSSL_RSA_public_encrypt(int len, const unsigned char* fr,
23801                             unsigned char* to, WOLFSSL_RSA* rsa, int padding)
23802 {
23803     int initTmpRng = 0;
23804     WC_RNG *rng = NULL;
23805     int outLen;
23806     int ret = 0;
23807 #ifdef WOLFSSL_SMALL_STACK
23808     WC_RNG* tmpRNG = NULL;
23809 #else
23810     WC_RNG  tmpRNG[1];
23811 #endif
23812 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
23813     int  mgf = WC_MGF1NONE;
23814     enum wc_HashType hash = WC_HASH_TYPE_NONE;
23815 #endif
23816 
23817     WOLFSSL_MSG("wolfSSL_RSA_public_encrypt");
23818 
23819     /* Check and remap the padding to internal values, if needed. */
23820 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
23821     if (padding == RSA_PKCS1_PADDING)
23822         padding = WC_RSA_PKCSV15_PAD;
23823     else if (padding == RSA_PKCS1_OAEP_PADDING) {
23824         padding = WC_RSA_OAEP_PAD;
23825         hash = WC_HASH_TYPE_SHA;
23826         mgf = WC_MGF1SHA1;
23827     }
23828 #else
23829     if (padding == RSA_PKCS1_PADDING)
23830       ;
23831 #endif
23832     else {
23833         WOLFSSL_MSG("wolfSSL_RSA_public_encrypt unsupported padding");
23834         return 0;
23835     }
23836 
23837     if (rsa->inSet == 0)
23838     {
23839         if (SetRsaInternal(rsa) != SSL_SUCCESS) {
23840             WOLFSSL_MSG("SetRsaInternal failed");
23841             return 0;
23842         }
23843     }
23844 
23845     outLen = wolfSSL_RSA_size(rsa);
23846 
23847 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \
23848     !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING)
23849     rng = ((RsaKey*)rsa->internal)->rng;
23850 #endif
23851     if (rng == NULL) {
23852 #ifdef WOLFSSL_SMALL_STACK
23853         tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
23854         if (tmpRNG == NULL)
23855             return 0;
23856 #endif
23857 
23858         if (wc_InitRng(tmpRNG) == 0) {
23859             rng = tmpRNG;
23860             initTmpRng = 1;
23861         }
23862         else {
23863             WOLFSSL_MSG("Bad RNG Init, trying global");
23864             if (initGlobalRNG == 0)
23865                 WOLFSSL_MSG("Global RNG no Init");
23866             else
23867                 rng = &globalRNG;
23868         }
23869     }
23870 
23871     if (outLen == 0) {
23872         WOLFSSL_MSG("Bad RSA size");
23873     }
23874 
23875     if (rng) {
23876 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
23877         ret = wc_RsaPublicEncrypt_ex(fr, len, to, outLen,
23878                              (RsaKey*)rsa->internal, rng, padding,
23879                              hash, mgf, NULL, 0);
23880 #else
23881         ret = wc_RsaPublicEncrypt(fr, len, to, outLen,
23882                              (RsaKey*)rsa->internal, rng);
23883 #endif
23884         if (ret <= 0) {
23885             WOLFSSL_MSG("Bad Rsa Encrypt");
23886         }
23887         if (len <= 0) {
23888             WOLFSSL_MSG("Bad Rsa Encrypt");
23889         }
23890     }
23891 
23892     if (initTmpRng)
23893         wc_FreeRng(tmpRNG);
23894 
23895 #ifdef WOLFSSL_SMALL_STACK
23896     XFREE(tmpRNG,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
23897 #endif
23898 
23899     if (ret >= 0)
23900         WOLFSSL_MSG("wolfSSL_RSA_public_encrypt success");
23901     else {
23902         WOLFSSL_MSG("wolfSSL_RSA_public_encrypt failed");
23903         ret = WOLFSSL_FATAL_ERROR; /* return -1 on error case */
23904     }
23905     return ret;
23906 }
23907 
23908 /* return compliant with OpenSSL
23909  *   size of plain recovered data if success , -1 if error
23910  */
23911 int wolfSSL_RSA_private_decrypt(int len, const unsigned char* fr,
23912                             unsigned char* to, WOLFSSL_RSA* rsa, int padding)
23913 {
23914     int outLen;
23915     int ret = 0;
23916   #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
23917     int mgf = WC_MGF1NONE;
23918     enum wc_HashType hash = WC_HASH_TYPE_NONE;
23919   #endif
23920 
23921     WOLFSSL_MSG("wolfSSL_RSA_private_decrypt");
23922 
23923 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
23924     if (padding == RSA_PKCS1_PADDING)
23925         padding = WC_RSA_PKCSV15_PAD;
23926     else if (padding == RSA_PKCS1_OAEP_PADDING) {
23927         padding = WC_RSA_OAEP_PAD;
23928         hash = WC_HASH_TYPE_SHA;
23929         mgf = WC_MGF1SHA1;
23930     }
23931 #else
23932     if (padding == RSA_PKCS1_PADDING)
23933         ;
23934 #endif
23935     else {
23936         WOLFSSL_MSG("wolfSSL_RSA_private_decrypt unsupported padding");
23937         return 0;
23938     }
23939 
23940     if (rsa->inSet == 0)
23941     {
23942         if (SetRsaInternal(rsa) != SSL_SUCCESS) {
23943             WOLFSSL_MSG("SetRsaInternal failed");
23944             return 0;
23945         }
23946     }
23947 
23948     outLen = wolfSSL_RSA_size(rsa);
23949     if (outLen == 0) {
23950         WOLFSSL_MSG("Bad RSA size");
23951     }
23952 
23953     /* size of 'to' buffer must be size of RSA key */
23954 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
23955     ret = wc_RsaPrivateDecrypt_ex(fr, len, to, outLen,
23956                             (RsaKey*)rsa->internal, padding,
23957                             hash, mgf, NULL, 0);
23958 #else
23959     ret = wc_RsaPrivateDecrypt(fr, len, to, outLen,
23960                             (RsaKey*)rsa->internal);
23961 #endif
23962 
23963     if (len <= 0) {
23964         WOLFSSL_MSG("Bad Rsa Decrypt");
23965     }
23966 
23967     if (ret > 0)
23968         WOLFSSL_MSG("wolfSSL_RSA_private_decrypt success");
23969     else {
23970         WOLFSSL_MSG("wolfSSL_RSA_private_decrypt failed");
23971         ret = WOLFSSL_FATAL_ERROR;
23972     }
23973     return ret;
23974 }
23975 
23976 
23977 /* RSA private encrypt calls wc_RsaSSL_Sign. Similar function set up as RSA
23978  * public decrypt.
23979  *
23980  * len  Length of input buffer
23981  * in   Input buffer to sign
23982  * out  Output buffer (expected to be greater than or equal to RSA key size)
23983  * rsa     Key to use for encryption
23984  * padding Type of RSA padding to use.
23985  */
23986 int wolfSSL_RSA_private_encrypt(int len, unsigned char* in,
23987                             unsigned char* out, WOLFSSL_RSA* rsa, int padding)
23988 {
23989     int sz = 0;
23990     WC_RNG* rng = NULL;
23991     RsaKey* key;
23992 
23993     WOLFSSL_MSG("wolfSSL_RSA_private_encrypt");
23994 
23995     if (len < 0 || rsa == NULL || rsa->internal == NULL || in == NULL) {
23996         WOLFSSL_MSG("Bad function arguments");
23997         return 0;
23998     }
23999 
24000     if (padding != RSA_PKCS1_PADDING) {
24001         WOLFSSL_MSG("wolfSSL_RSA_private_encrypt unsupported padding");
24002         return 0;
24003     }
24004 
24005     if (rsa->inSet == 0)
24006     {
24007         WOLFSSL_MSG("Setting internal RSA structure");
24008 
24009         if (SetRsaInternal(rsa) != SSL_SUCCESS) {
24010             WOLFSSL_MSG("SetRsaInternal failed");
24011             return 0;
24012         }
24013     }
24014 
24015     key = (RsaKey*)rsa->internal;
24016     #if defined(WC_RSA_BLINDING) && !defined(HAVE_USER_RSA)
24017     rng = key->rng;
24018     #else
24019 #ifndef HAVE_FIPS
24020     if (wc_InitRng_ex(rng, key->heap, INVALID_DEVID) != 0) {
24021 #else
24022     if (wc_InitRng(rng) != 0) {
24023 #endif
24024         WOLFSSL_MSG("Error with random number");
24025         return SSL_FATAL_ERROR;
24026     }
24027     #endif
24028 
24029     /* size of output buffer must be size of RSA key */
24030     sz = wc_RsaSSL_Sign(in, (word32)len, out, wolfSSL_RSA_size(rsa), key, rng);
24031     #if !defined(WC_RSA_BLINDING) || defined(HAVE_USER_RSA)
24032     if (wc_FreeRng(rng) != 0) {
24033         WOLFSSL_MSG("Error freeing random number generator");
24034         return SSL_FATAL_ERROR;
24035     }
24036     #endif
24037     if (sz <= 0) {
24038         WOLFSSL_LEAVE("wolfSSL_RSA_private_encrypt", sz);
24039         return 0;
24040     }
24041 
24042     return sz;
24043 }
24044 #endif /* HAVE_USER_RSA */
24045 
24046 /* return compliant with OpenSSL
24047  *   RSA modulus size in bytes, -1 if error
24048  */
24049 int wolfSSL_RSA_size(const WOLFSSL_RSA* rsa)
24050 {
24051     WOLFSSL_ENTER("wolfSSL_RSA_size");
24052 
24053     if (rsa == NULL)
24054         return WOLFSSL_FATAL_ERROR;
24055     if (rsa->inSet == 0)
24056     {
24057         if (SetRsaInternal((WOLFSSL_RSA*)rsa) != SSL_SUCCESS) {
24058             WOLFSSL_MSG("SetRsaInternal failed");
24059             return 0;
24060         }
24061     }
24062     return wc_RsaEncryptSize((RsaKey*)rsa->internal);
24063 }
24064 
24065 
24066 /* Generates a RSA key of length len
24067  *
24068  * len  length of RSA key i.e. 2048
24069  * e    e to use when generating RSA key
24070  * f    callback function for generation details
24071  * data user callback argument
24072  *
24073  * Note: Because of wc_MakeRsaKey an RSA key size generated can be slightly
24074  *       rounded down. For example generating a key of size 2999 with e =
24075  *       65537 will make a key of size 374 instead of 375.
24076  * Returns a new RSA key on success and NULL on failure
24077  */
24078 WOLFSSL_RSA* wolfSSL_RSA_generate_key(int len, unsigned long e,
24079                                       void(*f)(int, int, void*), void* data)
24080 {
24081     WOLFSSL_RSA*    rsa = NULL;
24082     WOLFSSL_BIGNUM* bn  = NULL;
24083 
24084     WOLFSSL_ENTER("wolfSSL_RSA_generate_key");
24085 
24086     (void)f;
24087     (void)data;
24088 
24089     if (len < 0) {
24090         WOLFSSL_MSG("Bad argument: length was less than 0");
24091         return NULL;
24092     }
24093 
24094     bn = wolfSSL_BN_new();
24095     if (bn == NULL) {
24096         WOLFSSL_MSG("Error creating big number");
24097         return NULL;
24098     }
24099 
24100     if (wolfSSL_BN_set_word(bn, (WOLFSSL_BN_ULONG)e) != SSL_SUCCESS) {
24101         WOLFSSL_MSG("Error using e value");
24102         wolfSSL_BN_free(bn);
24103         return NULL;
24104     }
24105 
24106     rsa = wolfSSL_RSA_new();
24107     if (rsa == NULL) {
24108         WOLFSSL_MSG("memory error");
24109     }
24110     else {
24111         if (wolfSSL_RSA_generate_key_ex(rsa, len, bn, NULL) != SSL_SUCCESS){
24112             wolfSSL_RSA_free(rsa);
24113             rsa = NULL;
24114         }
24115     }
24116     wolfSSL_BN_free(bn);
24117 
24118     return rsa;
24119 }
24120 
24121 
24122 /* return compliant with OpenSSL
24123  *   1 if success, 0 if error
24124  */
24125 int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* bn,
24126                                 void* cb)
24127 {
24128     int ret = WOLFSSL_FAILURE;
24129 
24130     (void)cb;
24131     (void)bn;
24132     (void)bits;
24133 
24134     WOLFSSL_ENTER("wolfSSL_RSA_generate_key_ex");
24135 
24136     if (rsa == NULL || rsa->internal == NULL) {
24137         /* bit size checked during make key call */
24138         WOLFSSL_MSG("bad arguments");
24139         return WOLFSSL_FAILURE;
24140     }
24141 
24142 #ifdef WOLFSSL_KEY_GEN
24143     {
24144     #ifdef WOLFSSL_SMALL_STACK
24145         WC_RNG* rng = NULL;
24146     #else
24147         WC_RNG  rng[1];
24148     #endif
24149 
24150     #ifdef WOLFSSL_SMALL_STACK
24151         rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
24152         if (rng == NULL)
24153             return WOLFSSL_FAILURE;
24154     #endif
24155 
24156         if (wc_InitRng(rng) < 0)
24157             WOLFSSL_MSG("RNG init failed");
24158         else if (wc_MakeRsaKey((RsaKey*)rsa->internal, bits,
24159                     wolfSSL_BN_get_word(bn), rng) != MP_OKAY)
24160             WOLFSSL_MSG("wc_MakeRsaKey failed");
24161         else if (SetRsaExternal(rsa) != WOLFSSL_SUCCESS)
24162             WOLFSSL_MSG("SetRsaExternal failed");
24163         else {
24164             rsa->inSet = 1;
24165             ret = WOLFSSL_SUCCESS;
24166         }
24167 
24168         wc_FreeRng(rng);
24169     #ifdef WOLFSSL_SMALL_STACK
24170         XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
24171     #endif
24172     }
24173 #else
24174     WOLFSSL_MSG("No Key Gen built in");
24175 #endif
24176     return ret;
24177 }
24178 #endif /* NO_RSA */
24179 
24180 #ifndef NO_DSA
24181 /* return code compliant with OpenSSL :
24182  *   1 if success, 0 if error
24183  */
24184 int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa)
24185 {
24186     int ret = WOLFSSL_FAILURE;
24187 
24188     WOLFSSL_ENTER("wolfSSL_DSA_generate_key");
24189 
24190     if (dsa == NULL || dsa->internal == NULL) {
24191         WOLFSSL_MSG("Bad arguments");
24192         return WOLFSSL_FAILURE;
24193     }
24194 
24195     if (dsa->inSet == 0) {
24196         WOLFSSL_MSG("No DSA internal set, do it");
24197 
24198         if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) {
24199             WOLFSSL_MSG("SetDsaInternal failed");
24200             return ret;
24201         }
24202     }
24203 
24204 #ifdef WOLFSSL_KEY_GEN
24205     {
24206         int initTmpRng = 0;
24207         WC_RNG *rng = NULL;
24208 #ifdef WOLFSSL_SMALL_STACK
24209         WC_RNG *tmpRNG = NULL;
24210 #else
24211         WC_RNG tmpRNG[1];
24212 #endif
24213 
24214 #ifdef WOLFSSL_SMALL_STACK
24215         tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
24216         if (tmpRNG == NULL)
24217             return WOLFSSL_FATAL_ERROR;
24218 #endif
24219         if (wc_InitRng(tmpRNG) == 0) {
24220             rng = tmpRNG;
24221             initTmpRng = 1;
24222         }
24223         else {
24224             WOLFSSL_MSG("Bad RNG Init, trying global");
24225             if (initGlobalRNG == 0)
24226                 WOLFSSL_MSG("Global RNG no Init");
24227             else
24228                 rng = &globalRNG;
24229         }
24230 
24231         if (rng) {
24232             if (wc_MakeDsaKey(rng, (DsaKey*)dsa->internal) != MP_OKAY)
24233                 WOLFSSL_MSG("wc_MakeDsaKey failed");
24234             else if (SetDsaExternal(dsa) != WOLFSSL_SUCCESS)
24235                 WOLFSSL_MSG("SetDsaExternal failed");
24236             else
24237                 ret = WOLFSSL_SUCCESS;
24238         }
24239 
24240         if (initTmpRng)
24241             wc_FreeRng(tmpRNG);
24242 
24243 #ifdef WOLFSSL_SMALL_STACK
24244         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
24245 #endif
24246     }
24247 #else /* WOLFSSL_KEY_GEN */
24248     WOLFSSL_MSG("No Key Gen built in");
24249 #endif
24250     return ret;
24251 }
24252 
24253 
24254 /* Returns a pointer to a new WOLFSSL_DSA structure on success and NULL on fail
24255  */
24256 WOLFSSL_DSA* wolfSSL_DSA_generate_parameters(int bits, unsigned char* seed,
24257         int seedLen, int* counterRet, unsigned long* hRet,
24258         WOLFSSL_BN_CB cb, void* CBArg)
24259 {
24260     WOLFSSL_DSA* dsa;
24261 
24262     WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters()");
24263 
24264     (void)cb;
24265     (void)CBArg;
24266     dsa = wolfSSL_DSA_new();
24267     if (dsa == NULL) {
24268         return NULL;
24269     }
24270 
24271     if (wolfSSL_DSA_generate_parameters_ex(dsa, bits, seed, seedLen,
24272                                   counterRet, hRet, NULL) != SSL_SUCCESS) {
24273         wolfSSL_DSA_free(dsa);
24274         return NULL;
24275     }
24276 
24277     return dsa;
24278 }
24279 
24280 
24281 /* return code compliant with OpenSSL :
24282  *   1 if success, 0 if error
24283  */
24284 int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits,
24285                                        unsigned char* seed, int seedLen,
24286                                        int* counterRet,
24287                                        unsigned long* hRet, void* cb)
24288 {
24289     int ret = WOLFSSL_FAILURE;
24290 
24291     (void)bits;
24292     (void)seed;
24293     (void)seedLen;
24294     (void)counterRet;
24295     (void)hRet;
24296     (void)cb;
24297 
24298     WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters_ex");
24299 
24300     if (dsa == NULL || dsa->internal == NULL) {
24301         WOLFSSL_MSG("Bad arguments");
24302         return WOLFSSL_FAILURE;
24303     }
24304 
24305 #ifdef WOLFSSL_KEY_GEN
24306     {
24307         int initTmpRng = 0;
24308         WC_RNG *rng = NULL;
24309 #ifdef WOLFSSL_SMALL_STACK
24310         WC_RNG *tmpRNG = NULL;
24311 #else
24312         WC_RNG tmpRNG[1];
24313 #endif
24314 
24315 #ifdef WOLFSSL_SMALL_STACK
24316         tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
24317         if (tmpRNG == NULL)
24318             return WOLFSSL_FATAL_ERROR;
24319 #endif
24320         if (wc_InitRng(tmpRNG) == 0) {
24321             rng = tmpRNG;
24322             initTmpRng = 1;
24323         }
24324         else {
24325             WOLFSSL_MSG("Bad RNG Init, trying global");
24326             if (initGlobalRNG == 0)
24327                 WOLFSSL_MSG("Global RNG no Init");
24328             else
24329                 rng = &globalRNG;
24330         }
24331 
24332         if (rng) {
24333             if (wc_MakeDsaParameters(rng, bits,
24334                                      (DsaKey*)dsa->internal) != MP_OKAY)
24335                 WOLFSSL_MSG("wc_MakeDsaParameters failed");
24336             else if (SetDsaExternal(dsa) != WOLFSSL_SUCCESS)
24337                 WOLFSSL_MSG("SetDsaExternal failed");
24338             else
24339                 ret = WOLFSSL_SUCCESS;
24340         }
24341 
24342         if (initTmpRng)
24343             wc_FreeRng(tmpRNG);
24344 
24345 #ifdef WOLFSSL_SMALL_STACK
24346         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
24347 #endif
24348     }
24349 #else /* WOLFSSL_KEY_GEN */
24350     WOLFSSL_MSG("No Key Gen built in");
24351 #endif
24352 
24353     return ret;
24354 }
24355 
24356 /* return WOLFSSL_SUCCESS on success, < 0 otherwise */
24357 int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
24358                        WOLFSSL_DSA* dsa)
24359 {
24360     int     ret = WOLFSSL_FATAL_ERROR;
24361     int     initTmpRng = 0;
24362     WC_RNG* rng = NULL;
24363 #ifdef WOLFSSL_SMALL_STACK
24364     WC_RNG* tmpRNG = NULL;
24365 #else
24366     WC_RNG  tmpRNG[1];
24367 #endif
24368 
24369     WOLFSSL_ENTER("wolfSSL_DSA_do_sign");
24370 
24371     if (d == NULL || sigRet == NULL || dsa == NULL) {
24372         WOLFSSL_MSG("Bad function arguments");
24373         return ret;
24374     }
24375 
24376     if (dsa->inSet == 0)
24377     {
24378         WOLFSSL_MSG("No DSA internal set, do it");
24379 
24380         if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) {
24381             WOLFSSL_MSG("SetDsaInternal failed");
24382             return ret;
24383         }
24384     }
24385 
24386 #ifdef WOLFSSL_SMALL_STACK
24387     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
24388     if (tmpRNG == NULL)
24389         return WOLFSSL_FATAL_ERROR;
24390 #endif
24391 
24392     if (wc_InitRng(tmpRNG) == 0) {
24393         rng = tmpRNG;
24394         initTmpRng = 1;
24395     }
24396     else {
24397         WOLFSSL_MSG("Bad RNG Init, trying global");
24398         if (initGlobalRNG == 0)
24399             WOLFSSL_MSG("Global RNG no Init");
24400         else
24401             rng = &globalRNG;
24402     }
24403 
24404     if (rng) {
24405         if (DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0)
24406             WOLFSSL_MSG("DsaSign failed");
24407         else
24408             ret = WOLFSSL_SUCCESS;
24409     }
24410 
24411     if (initTmpRng)
24412         wc_FreeRng(tmpRNG);
24413 #ifdef WOLFSSL_SMALL_STACK
24414     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
24415 #endif
24416 
24417     return ret;
24418 }
24419 
24420 
24421 int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig,
24422                         WOLFSSL_DSA* dsa, int *dsacheck)
24423 {
24424     int    ret = WOLFSSL_FATAL_ERROR;
24425 
24426     WOLFSSL_ENTER("wolfSSL_DSA_do_verify");
24427 
24428     if (d == NULL || sig == NULL || dsa == NULL) {
24429         WOLFSSL_MSG("Bad function arguments");
24430         return WOLFSSL_FATAL_ERROR;
24431     }
24432     if (dsa->inSet == 0)
24433     {
24434         WOLFSSL_MSG("No DSA internal set, do it");
24435 
24436         if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) {
24437             WOLFSSL_MSG("SetDsaInternal failed");
24438             return WOLFSSL_FATAL_ERROR;
24439         }
24440     }
24441 
24442     ret = DsaVerify(d, sig, (DsaKey*)dsa->internal, dsacheck);
24443     if (ret != 0 || *dsacheck != 1) {
24444         WOLFSSL_MSG("DsaVerify failed");
24445         return ret;
24446     }
24447 
24448     return WOLFSSL_SUCCESS;
24449 }
24450 #endif /* NO_DSA */
24451 
24452 
24453 #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
24454 
24455 #ifdef DEBUG_SIGN
24456 static void show(const char *title, const unsigned char *out, unsigned int outlen)
24457 {
24458     const unsigned char *pt;
24459     printf("%s[%d] = \n", title, (int)outlen);
24460     outlen = outlen>100?100:outlen;
24461     for (pt = out; pt < out + outlen;
24462             printf("%c", ((*pt)&0x6f)>='A'?((*pt)&0x6f):'.'), pt++);
24463     printf("\n");
24464 }
24465 #else
24466 #define show(a,b,c)
24467 #endif
24468 
24469 /* return SSL_SUCCES on ok, 0 otherwise */
24470 int wolfSSL_RSA_sign(int type, const unsigned char* m,
24471                            unsigned int mLen, unsigned char* sigRet,
24472                            unsigned int* sigLen, WOLFSSL_RSA* rsa)
24473 {
24474     return wolfSSL_RSA_sign_ex(type, m, mLen, sigRet, sigLen, rsa, 1);
24475 }
24476 
24477 int wolfSSL_RSA_sign_ex(int type, const unsigned char* m,
24478                            unsigned int mLen, unsigned char* sigRet,
24479                            unsigned int* sigLen, WOLFSSL_RSA* rsa, int flag)
24480 {
24481     word32  outLen;
24482     word32  signSz;
24483     int     initTmpRng = 0;
24484     WC_RNG* rng        = NULL;
24485     int     ret        = 0;
24486 #ifdef WOLFSSL_SMALL_STACK
24487     WC_RNG* tmpRNG     = NULL;
24488     byte*   encodedSig = NULL;
24489 #else
24490     WC_RNG  tmpRNG[1];
24491     byte    encodedSig[MAX_ENCODED_SIG_SZ];
24492 #endif
24493 
24494     WOLFSSL_ENTER("wolfSSL_RSA_sign");
24495 
24496     if (m == NULL || sigRet == NULL || sigLen == NULL || rsa == NULL) {
24497         WOLFSSL_MSG("Bad function arguments");
24498         return 0;
24499     }
24500     show("Message to Sign", m, mLen);
24501 
24502     switch (type) {
24503     #ifdef WOLFSSL_MD2
24504         case NID_md2:       type = MD2h;    break;
24505     #endif
24506     #ifndef NO_MD5
24507         case NID_md5:       type = MD5h;    break;
24508     #endif
24509     #ifndef NO_SHA
24510         case NID_sha1:      type = SHAh;    break;
24511     #endif
24512     #ifndef NO_SHA256
24513         case NID_sha256:    type = SHA256h; break;
24514     #endif
24515     #ifdef WOLFSSL_SHA384
24516         case NID_sha384:    type = SHA384h; break;
24517     #endif
24518     #ifdef WOLFSSL_SHA512
24519         case NID_sha512:    type = SHA512h; break;
24520     #endif
24521         default:
24522             WOLFSSL_MSG("This NID (md type) not configured or not implemented");
24523             return 0;
24524     }
24525 
24526     if (rsa->inSet == 0)
24527     {
24528         WOLFSSL_MSG("No RSA internal set, do it");
24529 
24530         if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) {
24531             WOLFSSL_MSG("SetRsaInternal failed");
24532             return 0;
24533         }
24534     }
24535 
24536     outLen = (word32)wolfSSL_BN_num_bytes(rsa->n);
24537 
24538 #ifdef WOLFSSL_SMALL_STACK
24539     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
24540     if (tmpRNG == NULL)
24541         return 0;
24542 
24543     encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
24544                                                    DYNAMIC_TYPE_SIGNATURE);
24545     if (encodedSig == NULL) {
24546         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
24547         return 0;
24548     }
24549 #endif
24550 
24551     if (outLen == 0)
24552         WOLFSSL_MSG("Bad RSA size");
24553     else if (wc_InitRng(tmpRNG) == 0) {
24554         rng = tmpRNG;
24555         initTmpRng = 1;
24556     }
24557     else {
24558         WOLFSSL_MSG("Bad RNG Init, trying global");
24559 
24560         if (initGlobalRNG == 0)
24561             WOLFSSL_MSG("Global RNG no Init");
24562         else
24563             rng = &globalRNG;
24564     }
24565 
24566     if (rng) {
24567 
24568         signSz = wc_EncodeSignature(encodedSig, m, mLen, type);
24569         if (signSz == 0) {
24570             WOLFSSL_MSG("Bad Encode Signature");
24571         }
24572         else {
24573             show("Encoded Message", encodedSig, signSz);
24574             if (flag != 0) {
24575                 ret = wc_RsaSSL_Sign(encodedSig, signSz, sigRet, outLen,
24576                                 (RsaKey*)rsa->internal, rng);
24577                 if (ret <= 0) {
24578                     WOLFSSL_MSG("Bad Rsa Sign");
24579                     ret = 0;
24580                 }
24581                 else {
24582                     *sigLen = (unsigned int)ret;
24583                     ret = SSL_SUCCESS;
24584                     show("Signature", sigRet, *sigLen);
24585                 }
24586             } else {
24587                 ret = SSL_SUCCESS;
24588                 XMEMCPY(sigRet, encodedSig, signSz);
24589                 *sigLen = signSz;
24590             }
24591         }
24592 
24593     }
24594 
24595     if (initTmpRng)
24596         wc_FreeRng(tmpRNG);
24597 
24598 #ifdef WOLFSSL_SMALL_STACK
24599     XFREE(tmpRNG,     NULL, DYNAMIC_TYPE_RNG);
24600     XFREE(encodedSig, NULL, DYNAMIC_TYPE_SIGNATURE);
24601 #endif
24602 
24603     if (ret == WOLFSSL_SUCCESS)
24604         WOLFSSL_MSG("wolfSSL_RSA_sign success");
24605     else {
24606         WOLFSSL_MSG("wolfSSL_RSA_sign failed");
24607     }
24608     return ret;
24609 }
24610 
24611 
24612 /* returns WOLFSSL_SUCCESS on successful verify and WOLFSSL_FAILURE on fail */
24613 int wolfSSL_RSA_verify(int type, const unsigned char* m,
24614                                unsigned int mLen, const unsigned char* sig,
24615                                unsigned int sigLen, WOLFSSL_RSA* rsa)
24616 {
24617     int     ret;
24618     unsigned char *sigRet ;
24619     unsigned char *sigDec ;
24620     unsigned int   len;
24621 
24622     WOLFSSL_ENTER("wolfSSL_RSA_verify");
24623     if ((m == NULL) || (sig == NULL)) {
24624         WOLFSSL_MSG("Bad function arguments");
24625         return WOLFSSL_FAILURE;
24626     }
24627 
24628     sigRet = (unsigned char *)XMALLOC(sigLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
24629     if (sigRet == NULL) {
24630         WOLFSSL_MSG("Memory failure");
24631         return WOLFSSL_FAILURE;
24632     }
24633     sigDec = (unsigned char *)XMALLOC(sigLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
24634     if (sigDec == NULL) {
24635         WOLFSSL_MSG("Memory failure");
24636         XFREE(sigRet, NULL, DYNAMIC_TYPE_TMP_BUFFER);
24637         return WOLFSSL_FAILURE;
24638     }
24639     /* get non-encrypted signature to be compared with decrypted sugnature*/
24640     ret = wolfSSL_RSA_sign_ex(type, m, mLen, sigRet, &len, rsa, 0);
24641     if (ret <= 0) {
24642         WOLFSSL_MSG("Message Digest Error");
24643         XFREE(sigRet, NULL, DYNAMIC_TYPE_TMP_BUFFER);
24644         XFREE(sigDec, NULL, DYNAMIC_TYPE_TMP_BUFFER);
24645         return WOLFSSL_FAILURE;
24646     }
24647     show("Encoded Message", sigRet, len);
24648     /* decrypt signature */
24649     ret = wc_RsaSSL_Verify(sig, sigLen, (unsigned char *)sigDec, sigLen,
24650         (RsaKey*)rsa->internal);
24651     if (ret <= 0) {
24652         WOLFSSL_MSG("RSA Decrypt error");
24653         XFREE(sigRet, NULL, DYNAMIC_TYPE_TMP_BUFFER);
24654         XFREE(sigDec, NULL, DYNAMIC_TYPE_TMP_BUFFER);
24655         return WOLFSSL_FAILURE;
24656     }
24657     show("Decrypted Signature", sigDec, ret);
24658 
24659     if ((int)len == ret && XMEMCMP(sigRet, sigDec, ret) == 0) {
24660         WOLFSSL_MSG("wolfSSL_RSA_verify success");
24661         XFREE(sigRet, NULL, DYNAMIC_TYPE_TMP_BUFFER);
24662         XFREE(sigDec, NULL, DYNAMIC_TYPE_TMP_BUFFER);
24663         return WOLFSSL_SUCCESS;
24664     }
24665     else {
24666         WOLFSSL_MSG("wolfSSL_RSA_verify failed");
24667         XFREE(sigRet, NULL, DYNAMIC_TYPE_TMP_BUFFER);
24668         XFREE(sigDec, NULL, DYNAMIC_TYPE_TMP_BUFFER);
24669         return WOLFSSL_FAILURE;
24670     }
24671 }
24672 
24673 int wolfSSL_RSA_public_decrypt(int flen, const unsigned char* from,
24674                           unsigned char* to, WOLFSSL_RSA* rsa, int padding)
24675 {
24676     int tlen = 0;
24677 
24678     WOLFSSL_ENTER("wolfSSL_RSA_public_decrypt");
24679 
24680     if (rsa == NULL || rsa->internal == NULL || from == NULL) {
24681         WOLFSSL_MSG("Bad function arguments");
24682         return 0;
24683     }
24684 
24685     if (padding != RSA_PKCS1_PADDING) {
24686         WOLFSSL_MSG("wolfSSL_RSA_public_decrypt unsupported padding");
24687         return 0;
24688     }
24689 
24690     if (rsa->inSet == 0)
24691     {
24692         WOLFSSL_MSG("No RSA internal set, do it");
24693 
24694         if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) {
24695             WOLFSSL_MSG("SetRsaInternal failed");
24696             return 0;
24697         }
24698     }
24699 
24700     /* size of 'to' buffer must be size of RSA key */
24701     tlen = wc_RsaSSL_Verify(from, flen, to, wolfSSL_RSA_size(rsa),
24702                             (RsaKey*)rsa->internal);
24703     if (tlen <= 0)
24704         WOLFSSL_MSG("wolfSSL_RSA_public_decrypt failed");
24705     else {
24706         WOLFSSL_MSG("wolfSSL_RSA_public_decrypt success");
24707     }
24708     return tlen;
24709 }
24710 
24711 
24712 /* generate p-1 and q-1, WOLFSSL_SUCCESS on ok */
24713 int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
24714 {
24715     int    err;
24716     mp_int tmp;
24717 
24718     WOLFSSL_MSG("wolfSSL_RsaGenAdd");
24719 
24720     if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->d == NULL ||
24721                        rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
24722         WOLFSSL_MSG("rsa no init error");
24723         return WOLFSSL_FATAL_ERROR;
24724     }
24725 
24726     if (mp_init(&tmp) != MP_OKAY) {
24727         WOLFSSL_MSG("mp_init error");
24728         return WOLFSSL_FATAL_ERROR;
24729     }
24730 
24731     err = mp_sub_d((mp_int*)rsa->p->internal, 1, &tmp);
24732     if (err != MP_OKAY) {
24733         WOLFSSL_MSG("mp_sub_d error");
24734     }
24735     else
24736         err = mp_mod((mp_int*)rsa->d->internal, &tmp,
24737                      (mp_int*)rsa->dmp1->internal);
24738 
24739     if (err != MP_OKAY) {
24740         WOLFSSL_MSG("mp_mod error");
24741     }
24742     else
24743         err = mp_sub_d((mp_int*)rsa->q->internal, 1, &tmp);
24744     if (err != MP_OKAY) {
24745         WOLFSSL_MSG("mp_sub_d error");
24746     }
24747     else
24748         err = mp_mod((mp_int*)rsa->d->internal, &tmp,
24749                      (mp_int*)rsa->dmq1->internal);
24750 
24751     mp_clear(&tmp);
24752 
24753     if (err == MP_OKAY)
24754         return WOLFSSL_SUCCESS;
24755     else
24756         return WOLFSSL_FATAL_ERROR;
24757 }
24758 #endif /* NO_RSA */
24759 
24760 int wolfSSL_HMAC_CTX_Init(WOLFSSL_HMAC_CTX* ctx)
24761 {
24762     WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init");
24763 
24764     if (ctx != NULL) {
24765         /* wc_HmacSetKey sets up ctx->hmac */
24766         XMEMSET(ctx, 0, sizeof(WOLFSSL_HMAC_CTX));
24767     }
24768 
24769     return WOLFSSL_SUCCESS;
24770 }
24771 
24772 
24773 int wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX* ctx, const void* key,
24774                              int keylen, const EVP_MD* type, WOLFSSL_ENGINE* e)
24775 {
24776     WOLFSSL_ENTER("wolfSSL_HMAC_Init_ex");
24777 
24778     /* WOLFSSL_ENGINE not used, call wolfSSL_HMAC_Init */
24779     (void)e;
24780     return wolfSSL_HMAC_Init(ctx, key, keylen, type);
24781 }
24782 
24783 
24784 /* Deep copy of information from src to des structure
24785  *
24786  * des destination to copy information to
24787  * src structure to get infromation from
24788  *
24789  * Returns SSL_SUCCESS on success and SSL_FAILURE on error
24790  */
24791 int wolfSSL_HMAC_CTX_copy(WOLFSSL_HMAC_CTX* des, WOLFSSL_HMAC_CTX* src)
24792 {
24793     void* heap = NULL;
24794 
24795     WOLFSSL_ENTER("wolfSSL_HMAC_CTX_copy");
24796 
24797     if (des == NULL || src == NULL) {
24798         return SSL_FAILURE;
24799     }
24800 
24801 #ifndef HAVE_FIPS
24802     heap = src->hmac.heap;
24803 #endif
24804 
24805     if (wc_HmacInit(&des->hmac, heap, 0) != 0) {
24806         WOLFSSL_MSG("Error initializing HMAC");
24807         return SSL_FAILURE;
24808     }
24809 
24810     des->type = src->type;
24811 
24812     /* requires that hash structures have no dynamic parts to them */
24813     switch (src->hmac.macType) {
24814     #ifndef NO_MD5
24815         case WC_MD5:
24816             XMEMCPY(&des->hmac.hash.md5, &src->hmac.hash.md5, sizeof(wc_Md5));
24817             break;
24818     #endif /* !NO_MD5 */
24819 
24820     #ifndef NO_SHA
24821         case WC_SHA:
24822             XMEMCPY(&des->hmac.hash.sha, &src->hmac.hash.sha, sizeof(wc_Sha));
24823             break;
24824     #endif /* !NO_SHA */
24825 
24826     #ifdef WOLFSSL_SHA224
24827         case WC_SHA224:
24828             XMEMCPY(&des->hmac.hash.sha224, &src->hmac.hash.sha224,
24829                     sizeof(wc_Sha224));
24830             break;
24831     #endif /* WOLFSSL_SHA224 */
24832 
24833     #ifndef NO_SHA256
24834         case WC_SHA256:
24835             XMEMCPY(&des->hmac.hash.sha256, &src->hmac.hash.sha256,
24836                     sizeof(wc_Sha256));
24837             break;
24838     #endif /* !NO_SHA256 */
24839 
24840     #ifdef WOLFSSL_SHA384
24841         case WC_SHA384:
24842             XMEMCPY(&des->hmac.hash.sha384, &src->hmac.hash.sha384,
24843                     sizeof(wc_Sha384));
24844             break;
24845     #endif /* WOLFSSL_SHA384 */
24846     #ifdef WOLFSSL_SHA512
24847         case WC_SHA512:
24848             XMEMCPY(&des->hmac.hash.sha512, &src->hmac.hash.sha512,
24849                     sizeof(wc_Sha512));
24850             break;
24851     #endif /* WOLFSSL_SHA512 */
24852 
24853         default:
24854             WOLFSSL_MSG("Unknown or unsupported hash type");
24855             return WOLFSSL_FAILURE;
24856     }
24857 
24858     XMEMCPY((byte*)des->hmac.ipad, (byte*)src->hmac.ipad, WC_HMAC_BLOCK_SIZE);
24859     XMEMCPY((byte*)des->hmac.opad, (byte*)src->hmac.opad, WC_HMAC_BLOCK_SIZE);
24860     XMEMCPY((byte*)des->hmac.innerHash, (byte*)src->hmac.innerHash,
24861                                                             WC_MAX_DIGEST_SIZE);
24862 #ifndef HAVE_FIPS
24863     des->hmac.heap    = heap;
24864 #endif
24865     des->hmac.macType = src->hmac.macType;
24866     des->hmac.innerHashKeyed = src->hmac.innerHashKeyed;
24867     XMEMCPY((byte *)&des->save_ipad, (byte *)&src->hmac.ipad,
24868                                         WC_HMAC_BLOCK_SIZE);
24869     XMEMCPY((byte *)&des->save_opad, (byte *)&src->hmac.opad,
24870                                         WC_HMAC_BLOCK_SIZE);
24871 
24872 #ifdef WOLFSSL_ASYNC_CRYPT
24873     XMEMCPY(&des->hmac.asyncDev, &src->hmac.asyncDev, sizeof(WC_ASYNC_DEV));
24874     des->hmac.keyLen = src->hmac.keyLen;
24875     #ifdef HAVE_CAVIUM
24876         des->hmac.data = (byte*)XMALLOC(src->hmac.dataLen, des->hmac.heap,
24877                 DYNAMIC_TYPE_HMAC);
24878         if (des->hmac.data == NULL) {
24879             return BUFFER_E;
24880         }
24881         XMEMCPY(des->hmac.data, src->hmac.data, src->hmac.dataLen);
24882         des->hmac.dataLen = src->hmac.dataLen;
24883     #endif /* HAVE_CAVIUM */
24884 #endif /* WOLFSSL_ASYNC_CRYPT */
24885         return WOLFSSL_SUCCESS;
24886 }
24887 
24888 #if defined(HAVE_FIPS) && \
24889     (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
24890 
24891 static int _HMAC_Init(Hmac* hmac, int type, void* heap)
24892 {
24893     int ret = 0;
24894 
24895     switch (type) {
24896     #ifndef NO_MD5
24897         case WC_MD5:
24898             ret = wc_InitMd5(&hmac->hash.md5);
24899             break;
24900     #endif /* !NO_MD5 */
24901 
24902     #ifndef NO_SHA
24903         case WC_SHA:
24904             ret = wc_InitSha(&hmac->hash.sha);
24905             break;
24906     #endif /* !NO_SHA */
24907 
24908     #ifdef WOLFSSL_SHA224
24909         case WC_SHA224:
24910             ret = wc_InitSha224(&hmac->hash.sha224);
24911             break;
24912     #endif /* WOLFSSL_SHA224 */
24913 
24914     #ifndef NO_SHA256
24915         case WC_SHA256:
24916             ret = wc_InitSha256(&hmac->hash.sha256);
24917             break;
24918     #endif /* !NO_SHA256 */
24919 
24920     #ifdef WOLFSSL_SHA384
24921         case WC_SHA384:
24922             ret = wc_InitSha384(&hmac->hash.sha384);
24923             break;
24924     #endif /* WOLFSSL_SHA384 */
24925     #ifdef WOLFSSL_SHA512
24926         case WC_SHA512:
24927             ret = wc_InitSha512(&hmac->hash.sha512);
24928             break;
24929     #endif /* WOLFSSL_SHA512 */
24930 
24931     #ifdef HAVE_BLAKE2
24932         case BLAKE2B_ID:
24933             ret = wc_InitBlake2b(&hmac->hash.blake2b, BLAKE2B_256);
24934             break;
24935     #endif /* HAVE_BLAKE2 */
24936 
24937     #ifdef WOLFSSL_SHA3
24938         case WC_SHA3_224:
24939             ret = wc_InitSha3_224(&hmac->hash.sha3, heap, INVALID_DEVID);
24940             break;
24941         case WC_SHA3_256:
24942             ret = wc_InitSha3_256(&hmac->hash.sha3, heap, INVALID_DEVID);
24943             break;
24944         case WC_SHA3_384:
24945             ret = wc_InitSha3_384(&hmac->hash.sha3, heap, INVALID_DEVID);
24946             break;
24947         case WC_SHA3_512:
24948             ret = wc_InitSha3_512(&hmac->hash.sha3, heap, INVALID_DEVID);
24949             break;
24950     #endif
24951 
24952         default:
24953             ret = BAD_FUNC_ARG;
24954             break;
24955     }
24956 
24957     (void)heap;
24958 
24959     return ret;
24960 }
24961 
24962 #else
24963     #define _HMAC_Init _InitHmac
24964 #endif
24965 
24966 
24967 int wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen,
24968                   const EVP_MD* type)
24969 {
24970     int hmac_error = 0;
24971     void* heap = NULL;
24972 
24973     WOLFSSL_MSG("wolfSSL_HMAC_Init");
24974 
24975     if (ctx == NULL) {
24976         WOLFSSL_MSG("no ctx on init");
24977         return WOLFSSL_FAILURE;
24978     }
24979 
24980 #ifndef HAVE_FIPS
24981     heap = ctx->hmac.heap;
24982 #endif
24983 
24984     if (type) {
24985         WOLFSSL_MSG("init has type");
24986 
24987 #ifndef NO_MD5
24988         if (XSTRNCMP(type, "MD5", 3) == 0) {
24989             WOLFSSL_MSG("md5 hmac");
24990             ctx->type = WC_MD5;
24991         }
24992         else
24993 #endif
24994 #ifdef WOLFSSL_SHA224
24995         if (XSTRNCMP(type, "SHA224", 6) == 0) {
24996             WOLFSSL_MSG("sha224 hmac");
24997             ctx->type = WC_SHA224;
24998         }
24999         else
25000 #endif
25001 #ifndef NO_SHA256
25002         if (XSTRNCMP(type, "SHA256", 6) == 0) {
25003             WOLFSSL_MSG("sha256 hmac");
25004             ctx->type = WC_SHA256;
25005         }
25006         else
25007 #endif
25008 #ifdef WOLFSSL_SHA384
25009         if (XSTRNCMP(type, "SHA384", 6) == 0) {
25010             WOLFSSL_MSG("sha384 hmac");
25011             ctx->type = WC_SHA384;
25012         }
25013         else
25014 #endif
25015 #ifdef WOLFSSL_SHA512
25016         if (XSTRNCMP(type, "SHA512", 6) == 0) {
25017             WOLFSSL_MSG("sha512 hmac");
25018             ctx->type = WC_SHA512;
25019         }
25020         else
25021 #endif
25022 
25023 #ifndef NO_SHA
25024         /* has to be last since would pick or 256, 384, or 512 too */
25025         if (XSTRNCMP(type, "SHA", 3) == 0) {
25026             WOLFSSL_MSG("sha hmac");
25027             ctx->type = WC_SHA;
25028         }
25029         else
25030 #endif
25031         {
25032             WOLFSSL_MSG("bad init type");
25033             return WOLFSSL_FAILURE;
25034         }
25035     }
25036 
25037     if (key && keylen) {
25038         WOLFSSL_MSG("keying hmac");
25039 
25040         if (wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID) == 0) {
25041             hmac_error = wc_HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key,
25042                                        (word32)keylen);
25043             if (hmac_error < 0){
25044                 wc_HmacFree(&ctx->hmac);
25045                 return WOLFSSL_FAILURE;
25046             }
25047             XMEMCPY((byte *)&ctx->save_ipad, (byte *)&ctx->hmac.ipad,
25048                                         WC_HMAC_BLOCK_SIZE);
25049             XMEMCPY((byte *)&ctx->save_opad, (byte *)&ctx->hmac.opad,
25050                                         WC_HMAC_BLOCK_SIZE);
25051         }
25052         /* OpenSSL compat, no error */
25053     } else if(ctx->type >= 0) { /* MD5 == 0 */
25054         WOLFSSL_MSG("recover hmac");
25055         if (wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID) == 0) {
25056             ctx->hmac.macType = (byte)ctx->type;
25057             ctx->hmac.innerHashKeyed = 0;
25058             XMEMCPY((byte *)&ctx->hmac.ipad, (byte *)&ctx->save_ipad,
25059                                        WC_HMAC_BLOCK_SIZE);
25060             XMEMCPY((byte *)&ctx->hmac.opad, (byte *)&ctx->save_opad,
25061                                        WC_HMAC_BLOCK_SIZE);
25062             if ((hmac_error = _HMAC_Init(&ctx->hmac, ctx->hmac.macType, heap))
25063                     !=0) {
25064                return hmac_error;
25065             }
25066         }
25067     }
25068 
25069     (void)hmac_error;
25070 
25071     return WOLFSSL_SUCCESS;
25072 }
25073 
25074 
25075 int wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, const unsigned char* data,
25076                     int len)
25077 {
25078     int hmac_error = 0;
25079 
25080     WOLFSSL_MSG("wolfSSL_HMAC_Update");
25081 
25082     if (ctx == NULL) {
25083         WOLFSSL_MSG("no ctx");
25084         return WOLFSSL_FAILURE;
25085     }
25086 
25087     if (data) {
25088         WOLFSSL_MSG("updating hmac");
25089         hmac_error = wc_HmacUpdate(&ctx->hmac, data, (word32)len);
25090         if (hmac_error < 0){
25091             WOLFSSL_MSG("hmac update error");
25092             return WOLFSSL_FAILURE;
25093         }
25094     }
25095 
25096     return WOLFSSL_SUCCESS;
25097 }
25098 
25099 
25100 int wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash,
25101                    unsigned int* len)
25102 {
25103     int hmac_error;
25104 
25105     WOLFSSL_MSG("wolfSSL_HMAC_Final");
25106 
25107     /* "len" parameter is optional. */
25108     if (ctx == NULL || hash == NULL) {
25109         WOLFSSL_MSG("invalid parameter");
25110         return WOLFSSL_FAILURE;
25111     }
25112 
25113     WOLFSSL_MSG("final hmac");
25114     hmac_error = wc_HmacFinal(&ctx->hmac, hash);
25115     if (hmac_error < 0){
25116         WOLFSSL_MSG("final hmac error");
25117         return WOLFSSL_FAILURE;
25118     }
25119 
25120     if (len) {
25121         WOLFSSL_MSG("setting output len");
25122         switch (ctx->type) {
25123             #ifndef NO_MD5
25124             case WC_MD5:
25125                 *len = WC_MD5_DIGEST_SIZE;
25126                 break;
25127             #endif
25128 
25129             #ifndef NO_SHA
25130             case WC_SHA:
25131                 *len = WC_SHA_DIGEST_SIZE;
25132                 break;
25133             #endif
25134 
25135             #ifdef WOLFSSL_SHA224
25136             case WC_SHA224:
25137                 *len = WC_SHA224_DIGEST_SIZE;
25138                 break;
25139             #endif
25140 
25141             #ifndef NO_SHA256
25142             case WC_SHA256:
25143                 *len = WC_SHA256_DIGEST_SIZE;
25144                 break;
25145             #endif
25146 
25147             #ifdef WOLFSSL_SHA384
25148             case WC_SHA384:
25149                 *len = WC_SHA384_DIGEST_SIZE;
25150                 break;
25151             #endif
25152 
25153             #ifdef WOLFSSL_SHA512
25154             case WC_SHA512:
25155                 *len = WC_SHA512_DIGEST_SIZE;
25156                 break;
25157             #endif
25158 
25159             default:
25160                 WOLFSSL_MSG("bad hmac type");
25161                 return WOLFSSL_FAILURE;
25162         }
25163     }
25164 
25165     return WOLFSSL_SUCCESS;
25166 }
25167 
25168 
25169 int wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx)
25170 {
25171     WOLFSSL_MSG("wolfSSL_HMAC_cleanup");
25172 
25173     if (ctx)
25174         wc_HmacFree(&ctx->hmac);
25175 
25176     return SSL_SUCCESS;
25177 }
25178 
25179 
25180 const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id)
25181 {
25182     WOLFSSL_MSG("wolfSSL_get_digestbynid");
25183 
25184     switch(id) {
25185 #ifndef NO_MD5
25186         case NID_md5:
25187             return wolfSSL_EVP_md5();
25188 #endif
25189 #ifndef NO_SHA
25190         case NID_sha1:
25191             return wolfSSL_EVP_sha1();
25192 #endif
25193         default:
25194             WOLFSSL_MSG("Bad digest id value");
25195     }
25196 
25197     return NULL;
25198 }
25199 
25200 
25201 #ifndef NO_RSA
25202 WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY* key)
25203 {
25204     WOLFSSL_RSA* local;
25205 
25206     WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_RSA");
25207 
25208     if (key == NULL) {
25209         return NULL;
25210     }
25211 
25212     local = wolfSSL_RSA_new();
25213     if (local == NULL) {
25214         WOLFSSL_MSG("Error creating a new WOLFSSL_RSA structure");
25215         return NULL;
25216     }
25217 
25218     if (key->type == EVP_PKEY_RSA) {
25219         if (wolfSSL_RSA_LoadDer(local, (const unsigned char*)key->pkey.ptr,
25220                     key->pkey_sz) != SSL_SUCCESS) {
25221             /* now try public key */
25222             if (wolfSSL_RSA_LoadDer_ex(local,
25223                         (const unsigned char*)key->pkey.ptr, key->pkey_sz,
25224                         WOLFSSL_RSA_LOAD_PUBLIC) != SSL_SUCCESS) {
25225                 wolfSSL_RSA_free(local);
25226                 local = NULL;
25227             }
25228         }
25229     }
25230     else {
25231         WOLFSSL_MSG("WOLFSSL_EVP_PKEY does not hold an RSA key");
25232         wolfSSL_RSA_free(local);
25233         local = NULL;
25234     }
25235     return local;
25236 }
25237 
25238 
25239 /* with set1 functions the pkey struct does not own the RSA structure
25240  *
25241  * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
25242  */
25243 int wolfSSL_EVP_PKEY_set1_RSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_RSA *key)
25244 {
25245     if((pkey == NULL) || (key ==NULL))return WOLFSSL_FAILURE;
25246     WOLFSSL_ENTER("wolfSSL_EVP_PKEY_set1_RSA");
25247     if (pkey->rsa != NULL && pkey->ownRsa == 1) {
25248         wolfSSL_RSA_free(pkey->rsa);
25249     }
25250     pkey->rsa    = key;
25251     pkey->ownRsa = 0; /* pkey does not own RSA */
25252     pkey->type = EVP_PKEY_RSA;
25253 #ifdef WC_RSA_BLINDING
25254     if (key->ownRng == 0) {
25255         if (wc_RsaSetRNG((RsaKey*)(pkey->rsa->internal), &(pkey->rng)) != 0) {
25256             WOLFSSL_MSG("Error setting RSA rng");
25257             return SSL_FAILURE;
25258         }
25259     }
25260 #endif
25261     return WOLFSSL_SUCCESS;
25262 }
25263 #endif /* NO_RSA */
25264 
25265 #ifndef NO_WOLFSSL_STUB
25266 WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY* key)
25267 {
25268     (void)key;
25269     WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_DSA not implemented");
25270     WOLFSSL_STUB("EVP_PKEY_get1_DSA");
25271     return NULL;
25272 }
25273 #endif
25274 
25275 #ifndef NO_WOLFSSL_STUB
25276 WOLFSSL_EC_KEY* wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* key)
25277 {
25278     (void)key;
25279     WOLFSSL_STUB("EVP_PKEY_get1_EC_KEY");
25280     WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_EC_KEY not implemented");
25281 
25282     return NULL;
25283 }
25284 #endif
25285 
25286 void* wolfSSL_EVP_X_STATE(const WOLFSSL_EVP_CIPHER_CTX* ctx)
25287 {
25288     WOLFSSL_MSG("wolfSSL_EVP_X_STATE");
25289 
25290     if (ctx) {
25291         switch (ctx->cipherType) {
25292             case ARC4_TYPE:
25293                 WOLFSSL_MSG("returning arc4 state");
25294                 return (void*)&ctx->cipher.arc4.x;
25295 
25296             default:
25297                 WOLFSSL_MSG("bad x state type");
25298                 return 0;
25299         }
25300     }
25301 
25302     return NULL;
25303 }
25304 
25305 
25306 int wolfSSL_EVP_X_STATE_LEN(const WOLFSSL_EVP_CIPHER_CTX* ctx)
25307 {
25308     WOLFSSL_MSG("wolfSSL_EVP_X_STATE_LEN");
25309 
25310     if (ctx) {
25311         switch (ctx->cipherType) {
25312             case ARC4_TYPE:
25313                 WOLFSSL_MSG("returning arc4 state size");
25314                 return sizeof(Arc4);
25315 
25316             default:
25317                 WOLFSSL_MSG("bad x state type");
25318                 return 0;
25319         }
25320     }
25321 
25322     return 0;
25323 }
25324 
25325 
25326 #ifndef NO_DES3
25327 
25328 void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
25329                             unsigned char* iv, int len)
25330 {
25331     (void)len;
25332 
25333     WOLFSSL_MSG("wolfSSL_3des_iv");
25334 
25335     if (ctx == NULL || iv == NULL) {
25336         WOLFSSL_MSG("Bad function argument");
25337         return;
25338     }
25339 
25340     if (doset)
25341         wc_Des3_SetIV(&ctx->cipher.des3, iv);  /* OpenSSL compat, no ret */
25342     else
25343         XMEMCPY(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
25344 }
25345 
25346 #endif /* NO_DES3 */
25347 
25348 
25349 #ifndef NO_AES
25350 
25351 void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
25352                       unsigned char* iv, int len)
25353 {
25354     (void)len;
25355 
25356     WOLFSSL_MSG("wolfSSL_aes_ctr_iv");
25357 
25358     if (ctx == NULL || iv == NULL) {
25359         WOLFSSL_MSG("Bad function argument");
25360         return;
25361     }
25362 
25363     if (doset)
25364        (void)wc_AesSetIV(&ctx->cipher.aes, iv);  /* OpenSSL compat, no ret */
25365     else
25366         XMEMCPY(iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
25367 }
25368 
25369 #endif /* NO_AES */
25370 
25371 #ifndef NO_WOLFSSL_STUB
25372 const WOLFSSL_EVP_MD* wolfSSL_EVP_ripemd160(void)
25373 {
25374     WOLFSSL_MSG("wolfSSL_ripemd160");
25375     WOLFSSL_STUB("EVP_ripemd160");
25376     return NULL;
25377 }
25378 #endif
25379 
25380 int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* type)
25381 {
25382     WOLFSSL_MSG("wolfSSL_EVP_MD_size");
25383 
25384     if (type == NULL) {
25385         WOLFSSL_MSG("No md type arg");
25386         return BAD_FUNC_ARG;
25387     }
25388 
25389     if (XSTRNCMP(type, "SHA256", 6) == 0) {
25390         return WC_SHA256_DIGEST_SIZE;
25391     }
25392 #ifndef NO_MD5
25393     else if (XSTRNCMP(type, "MD5", 3) == 0) {
25394         return WC_MD5_DIGEST_SIZE;
25395     }
25396 #endif
25397 #ifdef WOLFSSL_SHA224
25398     else if (XSTRNCMP(type, "SHA224", 6) == 0) {
25399         return WC_SHA224_DIGEST_SIZE;
25400     }
25401 #endif
25402 #ifdef WOLFSSL_SHA384
25403     else if (XSTRNCMP(type, "SHA384", 6) == 0) {
25404         return WC_SHA384_DIGEST_SIZE;
25405     }
25406 #endif
25407 #ifdef WOLFSSL_SHA512
25408     else if (XSTRNCMP(type, "SHA512", 6) == 0) {
25409         return WC_SHA512_DIGEST_SIZE;
25410     }
25411 #endif
25412 #ifndef NO_SHA
25413     /* has to be last since would pick or 256, 384, or 512 too */
25414     else if (XSTRNCMP(type, "SHA", 3) == 0) {
25415         return WC_SHA_DIGEST_SIZE;
25416     }
25417 #endif
25418 
25419     return BAD_FUNC_ARG;
25420 }
25421 
25422 
25423 int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx)
25424 {
25425     WOLFSSL_MSG("wolfSSL_EVP_CIPHER_CTX_iv_length");
25426 
25427     switch (ctx->cipherType) {
25428 
25429 #ifdef HAVE_AES_CBC
25430         case AES_128_CBC_TYPE :
25431         case AES_192_CBC_TYPE :
25432         case AES_256_CBC_TYPE :
25433             WOLFSSL_MSG("AES CBC");
25434             return AES_BLOCK_SIZE;
25435 #endif
25436 #ifdef WOLFSSL_AES_COUNTER
25437         case AES_128_CTR_TYPE :
25438         case AES_192_CTR_TYPE :
25439         case AES_256_CTR_TYPE :
25440             WOLFSSL_MSG("AES CTR");
25441             return AES_BLOCK_SIZE;
25442 #endif
25443 #ifndef NO_DES3
25444         case DES_CBC_TYPE :
25445             WOLFSSL_MSG("DES CBC");
25446             return DES_BLOCK_SIZE;
25447 
25448         case DES_EDE3_CBC_TYPE :
25449             WOLFSSL_MSG("DES EDE3 CBC");
25450             return DES_BLOCK_SIZE;
25451 #endif
25452 #ifdef HAVE_IDEA
25453         case IDEA_CBC_TYPE :
25454             WOLFSSL_MSG("IDEA CBC");
25455             return IDEA_BLOCK_SIZE;
25456 #endif
25457 #ifndef NO_RC4
25458         case ARC4_TYPE :
25459             WOLFSSL_MSG("ARC4");
25460             return 0;
25461 #endif
25462 
25463         case NULL_CIPHER_TYPE :
25464             WOLFSSL_MSG("NULL");
25465             return 0;
25466 
25467         default: {
25468             WOLFSSL_MSG("bad type");
25469         }
25470     }
25471     return 0;
25472 }
25473 
25474 int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER* cipher)
25475 {
25476     const char *name = (const char *)cipher;
25477     WOLFSSL_MSG("wolfSSL_EVP_CIPHER_iv_length");
25478 
25479 #ifndef NO_AES
25480     #ifdef WOLFSSL_AES_128
25481     if (XSTRNCMP(name, EVP_AES_128_CBC, XSTRLEN(EVP_AES_128_CBC)) == 0)
25482         return AES_BLOCK_SIZE;
25483     #endif
25484     #ifdef WOLFSSL_AES_192
25485     if (XSTRNCMP(name, EVP_AES_192_CBC, XSTRLEN(EVP_AES_192_CBC)) == 0)
25486         return AES_BLOCK_SIZE;
25487     #endif
25488     #ifdef WOLFSSL_AES_256
25489     if (XSTRNCMP(name, EVP_AES_256_CBC, XSTRLEN(EVP_AES_256_CBC)) == 0)
25490         return AES_BLOCK_SIZE;
25491     #endif
25492 #ifdef WOLFSSL_AES_COUNTER
25493     #ifdef WOLFSSL_AES_128
25494     if (XSTRNCMP(name, EVP_AES_128_CTR, XSTRLEN(EVP_AES_128_CTR)) == 0)
25495         return AES_BLOCK_SIZE;
25496     #endif
25497     #ifdef WOLFSSL_AES_192
25498     if (XSTRNCMP(name, EVP_AES_192_CTR, XSTRLEN(EVP_AES_192_CTR)) == 0)
25499         return AES_BLOCK_SIZE;
25500     #endif
25501     #ifdef WOLFSSL_AES_256
25502     if (XSTRNCMP(name, EVP_AES_256_CTR, XSTRLEN(EVP_AES_256_CTR)) == 0)
25503         return AES_BLOCK_SIZE;
25504     #endif
25505 #endif
25506 #endif
25507 
25508 #ifndef NO_DES3
25509     if ((XSTRNCMP(name, EVP_DES_CBC, XSTRLEN(EVP_DES_CBC)) == 0) ||
25510            (XSTRNCMP(name, EVP_DES_EDE3_CBC, XSTRLEN(EVP_DES_EDE3_CBC)) == 0)) {
25511         return DES_BLOCK_SIZE;
25512     }
25513 #endif
25514 
25515 #ifdef HAVE_IDEA
25516     if (XSTRNCMP(name, EVP_IDEA_CBC, XSTRLEN(EVP_IDEA_CBC)) == 0)
25517         return IDEA_BLOCK_SIZE;
25518 #endif
25519 
25520     (void)name;
25521 
25522     return 0;
25523 }
25524 
25525 /* Free the dynamically allocated data.
25526  *
25527  * p  Pointer to dynamically allocated memory.
25528  */
25529 void wolfSSL_OPENSSL_free(void* p)
25530 {
25531     WOLFSSL_MSG("wolfSSL_OPENSSL_free");
25532 
25533     XFREE(p, NULL, DYNAMIC_TYPE_OPENSSL);
25534 }
25535 
25536 void *wolfSSL_OPENSSL_malloc(size_t a)
25537 {
25538   return XMALLOC(a, NULL, DYNAMIC_TYPE_OPENSSL);
25539 }
25540 
25541 #if defined(WOLFSSL_KEY_GEN) && defined(WOLFSSL_PEM_TO_DER)
25542 
25543 static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher,
25544                          unsigned char* passwd, int passwdSz, byte **cipherInfo)
25545 {
25546     int ret, paddingSz;
25547     word32 idx, cipherInfoSz;
25548 #ifdef WOLFSSL_SMALL_STACK
25549     EncryptedInfo* info = NULL;
25550 #else
25551     EncryptedInfo  info[1];
25552 #endif
25553 
25554     WOLFSSL_ENTER("EncryptDerKey");
25555 
25556     if (der == NULL || derSz == NULL || cipher == NULL ||
25557         passwd == NULL || cipherInfo == NULL)
25558         return BAD_FUNC_ARG;
25559 
25560 #ifdef WOLFSSL_SMALL_STACK
25561     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
25562                                    DYNAMIC_TYPE_ENCRYPTEDINFO);
25563     if (info == NULL) {
25564         WOLFSSL_MSG("malloc failed");
25565         return WOLFSSL_FAILURE;
25566     }
25567 #endif
25568 
25569     XMEMSET(info, 0, sizeof(EncryptedInfo));
25570 
25571     /* set the cipher name on info */
25572     XSTRNCPY(info->name, cipher, NAME_SZ-1);
25573     info->name[NAME_SZ-1] = '\0'; /* null term */
25574 
25575     ret = wc_EncryptedInfoGet(info, info->name);
25576     if (ret != 0) {
25577         WOLFSSL_MSG("unsupported cipher");
25578     #ifdef WOLFSSL_SMALL_STACK
25579         XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
25580     #endif
25581         return WOLFSSL_FAILURE;
25582     }
25583 
25584     /* Generate a random salt */
25585     if (wolfSSL_RAND_bytes(info->iv, info->ivSz) != WOLFSSL_SUCCESS) {
25586         WOLFSSL_MSG("generate iv failed");
25587 #ifdef WOLFSSL_SMALL_STACK
25588         XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
25589 #endif
25590         return WOLFSSL_FAILURE;
25591     }
25592 
25593     /* add the padding before encryption */
25594     paddingSz = ((*derSz)/info->ivSz + 1) * info->ivSz - (*derSz);
25595     if (paddingSz == 0)
25596         paddingSz = info->ivSz;
25597     XMEMSET(der+(*derSz), (byte)paddingSz, paddingSz);
25598     (*derSz) += paddingSz;
25599 
25600     /* encrypt buffer */
25601     if (wc_BufferKeyEncrypt(info, der, *derSz, passwd, passwdSz, WC_MD5) != 0) {
25602         WOLFSSL_MSG("encrypt key failed");
25603 #ifdef WOLFSSL_SMALL_STACK
25604         XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
25605 #endif
25606         return WOLFSSL_FAILURE;
25607     }
25608 
25609     /* create cipher info : 'cipher_name,Salt(hex)' */
25610     cipherInfoSz = (word32)(2*info->ivSz + XSTRLEN(info->name) + 2);
25611     *cipherInfo = (byte*)XMALLOC(cipherInfoSz, NULL,
25612                                 DYNAMIC_TYPE_STRING);
25613     if (*cipherInfo == NULL) {
25614         WOLFSSL_MSG("malloc failed");
25615 #ifdef WOLFSSL_SMALL_STACK
25616         XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
25617 #endif
25618         return WOLFSSL_FAILURE;
25619     }
25620     XSTRNCPY((char*)*cipherInfo, info->name, cipherInfoSz);
25621     XSTRNCAT((char*)*cipherInfo, ",", 1);
25622 
25623     idx = (word32)XSTRLEN((char*)*cipherInfo);
25624     cipherInfoSz -= idx;
25625     ret = Base16_Encode(info->iv, info->ivSz, *cipherInfo+idx, &cipherInfoSz);
25626 
25627 #ifdef WOLFSSL_SMALL_STACK
25628     XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
25629 #endif
25630     if (ret != 0) {
25631         WOLFSSL_MSG("Base16_Encode failed");
25632         XFREE(*cipherInfo, NULL, DYNAMIC_TYPE_STRING);
25633         return WOLFSSL_FAILURE;
25634     }
25635 
25636     return WOLFSSL_SUCCESS;
25637 }
25638 #endif /* WOLFSSL_KEY_GEN || WOLFSSL_PEM_TO_DER */
25639 
25640 #if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN)
25641 /* Takes a WOLFSSL_RSA key and writes it out to a WOLFSSL_BIO
25642  *
25643  * bio    the WOLFSSL_BIO to write to
25644  * key    the WOLFSSL_RSA key to write out
25645  * cipher cipher used
25646  * passwd password string if used
25647  * len    length of password string
25648  * cb     password callback to use
25649  * arg    null terminated string for passphrase
25650  */
25651 int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* key,
25652                                         const WOLFSSL_EVP_CIPHER* cipher,
25653                                         unsigned char* passwd, int len,
25654                                         pem_password_cb* cb, void* arg)
25655 {
25656     int ret;
25657     WOLFSSL_EVP_PKEY* pkey;
25658 
25659     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_RSAPrivateKey");
25660 
25661 
25662     pkey = wolfSSL_PKEY_new_ex(bio->heap);
25663     if (pkey == NULL) {
25664         WOLFSSL_MSG("wolfSSL_PKEY_new_ex failed");
25665         return SSL_FAILURE;
25666     }
25667 
25668     pkey->type   = EVP_PKEY_RSA;
25669     pkey->rsa    = key;
25670     pkey->ownRsa = 0;
25671 #ifdef WOLFSSL_KEY_GEN
25672     /* similar to how wolfSSL_PEM_write_mem_RSAPrivateKey finds DER of key */
25673     {
25674         int derMax;
25675         int derSz;
25676         byte* derBuf;
25677 
25678         /* 5 > size of n, d, p, q, d%(p-1), d(q-1), 1/q%p, e + ASN.1 additional
25679          *  informations
25680          */
25681         derMax = 5 * wolfSSL_RSA_size(key) + AES_BLOCK_SIZE;
25682 
25683         derBuf = (byte*)XMALLOC(derMax, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
25684         if (derBuf == NULL) {
25685             WOLFSSL_MSG("malloc failed");
25686             wolfSSL_EVP_PKEY_free(pkey);
25687             return SSL_FAILURE;
25688         }
25689 
25690         /* Key to DER */
25691         derSz = wc_RsaKeyToDer((RsaKey*)key->internal, derBuf, derMax);
25692         if (derSz < 0) {
25693             WOLFSSL_MSG("wc_RsaKeyToDer failed");
25694             XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
25695             wolfSSL_EVP_PKEY_free(pkey);
25696             return SSL_FAILURE;
25697         }
25698 
25699         pkey->pkey.ptr = (char*)XMALLOC(derSz, bio->heap,
25700                 DYNAMIC_TYPE_TMP_BUFFER);
25701         if (pkey->pkey.ptr == NULL) {
25702             WOLFSSL_MSG("key malloc failed");
25703             XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
25704             wolfSSL_EVP_PKEY_free(pkey);
25705             return SSL_FAILURE;
25706         }
25707         pkey->pkey_sz = derSz;
25708         XMEMCPY(pkey->pkey.ptr, derBuf, derSz);
25709         XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
25710     }
25711 #endif
25712 
25713     ret = wolfSSL_PEM_write_bio_PrivateKey(bio, pkey, cipher, passwd, len,
25714                                         cb, arg);
25715 
25716     wolfSSL_EVP_PKEY_free(pkey);
25717 
25718     return ret;
25719 }
25720 
25721 
25722 int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
25723                                         const WOLFSSL_EVP_CIPHER* cipher,
25724                                         unsigned char* passwd, int len,
25725                                         pem_password_cb* cb, void* arg)
25726 {
25727     byte* keyDer;
25728     int pemSz;
25729     int type;
25730     int ret;
25731     byte* tmp;
25732 
25733     (void)cipher;
25734     (void)passwd;
25735     (void)len;
25736     (void)cb;
25737     (void)arg;
25738 
25739     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PrivateKey");
25740 
25741     if (bio == NULL || key == NULL) {
25742         return WOLFSSL_FAILURE;
25743     }
25744 
25745     keyDer = (byte*)key->pkey.ptr;
25746 
25747     switch (key->type) {
25748         case EVP_PKEY_RSA:
25749             type = PRIVATEKEY_TYPE;
25750             break;
25751 
25752 #ifndef NO_DSA
25753         case EVP_PKEY_DSA:
25754             type = DSA_PRIVATEKEY_TYPE;
25755             break;
25756 #endif
25757 
25758         case EVP_PKEY_EC:
25759             type = ECC_PRIVATEKEY_TYPE;
25760             break;
25761 
25762         default:
25763             WOLFSSL_MSG("Unknown Key type!");
25764             type = PRIVATEKEY_TYPE;
25765     }
25766 
25767     pemSz = wc_DerToPem(keyDer, key->pkey_sz, NULL, 0, type);
25768     if (pemSz < 0) {
25769         WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", pemSz);
25770         return WOLFSSL_FAILURE;
25771     }
25772     tmp = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
25773     if (tmp == NULL) {
25774         return MEMORY_E;
25775     }
25776 
25777     ret = wc_DerToPemEx(keyDer, key->pkey_sz, tmp, pemSz,
25778                                 NULL, type);
25779     if (ret < 0) {
25780         WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", ret);
25781         XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
25782         return SSL_FAILURE;
25783     }
25784 
25785     ret = wolfSSL_BIO_write(bio, tmp, pemSz);
25786     XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
25787     if (ret != pemSz) {
25788         WOLFSSL_MSG("Unable to write full PEM to BIO");
25789         return SSL_FAILURE;
25790     }
25791 
25792     return SSL_SUCCESS;
25793 }
25794 #endif /* defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) */
25795 
25796 #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) && \
25797     (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM))
25798 
25799 /* return code compliant with OpenSSL :
25800  *   1 if success, 0 if error
25801  */
25802 int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher,
25803                                         unsigned char* passwd, int passwdSz,
25804                                         unsigned char **pem, int *plen)
25805 {
25806     byte *derBuf, *tmp, *cipherInfo = NULL;
25807     int  der_max_len = 0, derSz = 0;
25808     const int type = PRIVATEKEY_TYPE;
25809     const char* header = NULL;
25810     const char* footer = NULL;
25811 
25812     WOLFSSL_ENTER("wolfSSL_PEM_write_mem_RSAPrivateKey");
25813 
25814     if (pem == NULL || plen == NULL || rsa == NULL || rsa->internal == NULL) {
25815         WOLFSSL_MSG("Bad function arguments");
25816         return WOLFSSL_FAILURE;
25817     }
25818 
25819     if (wc_PemGetHeaderFooter(type, &header, &footer) != 0)
25820         return WOLFSSL_FAILURE;
25821 
25822     if (rsa->inSet == 0) {
25823         WOLFSSL_MSG("No RSA internal set, do it");
25824 
25825         if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) {
25826             WOLFSSL_MSG("SetRsaInternal failed");
25827             return WOLFSSL_FAILURE;
25828         }
25829     }
25830 
25831     /* 5 > size of n, d, p, q, d%(p-1), d(q-1), 1/q%p, e + ASN.1 additional
25832      *  informations
25833      */
25834     der_max_len = 5 * wolfSSL_RSA_size(rsa) + AES_BLOCK_SIZE;
25835 
25836     derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_DER);
25837     if (derBuf == NULL) {
25838         WOLFSSL_MSG("malloc failed");
25839         return WOLFSSL_FAILURE;
25840     }
25841 
25842     /* Key to DER */
25843     derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, derBuf, der_max_len);
25844     if (derSz < 0) {
25845         WOLFSSL_MSG("wc_RsaKeyToDer failed");
25846         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
25847         return WOLFSSL_FAILURE;
25848     }
25849 
25850     /* encrypt DER buffer if required */
25851     if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
25852         int ret;
25853 
25854         ret = EncryptDerKey(derBuf, &derSz, cipher,
25855                             passwd, passwdSz, &cipherInfo);
25856         if (ret != WOLFSSL_SUCCESS) {
25857             WOLFSSL_MSG("EncryptDerKey failed");
25858             XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
25859             return ret;
25860         }
25861 
25862         /* tmp buffer with a max size */
25863         *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
25864             (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE;
25865     }
25866     else {
25867         /* tmp buffer with a max size */
25868         *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
25869             (int)XSTRLEN(footer) + 1;
25870     }
25871 
25872     tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_PEM);
25873     if (tmp == NULL) {
25874         WOLFSSL_MSG("malloc failed");
25875         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
25876         if (cipherInfo != NULL)
25877             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
25878         return WOLFSSL_FAILURE;
25879     }
25880 
25881     /* DER to PEM */
25882     *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, type);
25883     if (*plen <= 0) {
25884         WOLFSSL_MSG("wc_DerToPemEx failed");
25885         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
25886         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
25887         if (cipherInfo != NULL)
25888             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
25889         return WOLFSSL_FAILURE;
25890     }
25891     XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
25892     if (cipherInfo != NULL)
25893         XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
25894 
25895     *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY);
25896     if (*pem == NULL) {
25897         WOLFSSL_MSG("malloc failed");
25898         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
25899         return WOLFSSL_FAILURE;
25900     }
25901     XMEMSET(*pem, 0, (*plen)+1);
25902 
25903     if (XMEMCPY(*pem, tmp, *plen) == NULL) {
25904         WOLFSSL_MSG("XMEMCPY failed");
25905         XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
25906         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
25907         return WOLFSSL_FAILURE;
25908     }
25909     XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
25910 
25911     return WOLFSSL_SUCCESS;
25912 }
25913 
25914 
25915 #ifndef NO_FILESYSTEM
25916 /* return code compliant with OpenSSL :
25917  *   1 if success, 0 if error
25918  */
25919 int wolfSSL_PEM_write_RSAPrivateKey(FILE *fp, WOLFSSL_RSA *rsa,
25920                                     const EVP_CIPHER *enc,
25921                                     unsigned char *kstr, int klen,
25922                                     pem_password_cb *cb, void *u)
25923 {
25924     byte *pem;
25925     int  plen, ret;
25926 
25927     (void)cb;
25928     (void)u;
25929 
25930     WOLFSSL_MSG("wolfSSL_PEM_write_RSAPrivateKey");
25931 
25932     if (fp == NULL || rsa == NULL || rsa->internal == NULL) {
25933         WOLFSSL_MSG("Bad function arguments");
25934         return WOLFSSL_FAILURE;
25935     }
25936 
25937     ret = wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, enc, kstr, klen, &pem, &plen);
25938     if (ret != WOLFSSL_SUCCESS) {
25939         WOLFSSL_MSG("wolfSSL_PEM_write_mem_RSAPrivateKey failed");
25940         return WOLFSSL_FAILURE;
25941     }
25942 
25943     ret = (int)XFWRITE(pem, plen, 1, fp);
25944     if (ret != 1) {
25945         WOLFSSL_MSG("RSA private key file write failed");
25946         return WOLFSSL_FAILURE;
25947     }
25948 
25949     XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
25950     return WOLFSSL_SUCCESS;
25951 }
25952 #endif /* NO_FILESYSTEM */
25953 #endif /* WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA && WOLFSSL_PEM_TO_DER */
25954 
25955 
25956 #ifdef HAVE_ECC
25957 
25958 /* EC_POINT Openssl -> WolfSSL */
25959 static int SetECPointInternal(WOLFSSL_EC_POINT *p)
25960 {
25961     ecc_point* point;
25962     WOLFSSL_ENTER("SetECPointInternal");
25963 
25964     if (p == NULL || p->internal == NULL) {
25965         WOLFSSL_MSG("ECPoint NULL error");
25966         return WOLFSSL_FATAL_ERROR;
25967     }
25968 
25969     point = (ecc_point*)p->internal;
25970 
25971     if (p->X != NULL && SetIndividualInternal(p->X, point->x) != WOLFSSL_SUCCESS) {
25972         WOLFSSL_MSG("ecc point X error");
25973         return WOLFSSL_FATAL_ERROR;
25974     }
25975 
25976     if (p->Y != NULL && SetIndividualInternal(p->Y, point->y) != WOLFSSL_SUCCESS) {
25977         WOLFSSL_MSG("ecc point Y error");
25978         return WOLFSSL_FATAL_ERROR;
25979     }
25980 
25981     if (p->Z != NULL && SetIndividualInternal(p->Z, point->z) != WOLFSSL_SUCCESS) {
25982         WOLFSSL_MSG("ecc point Z error");
25983         return WOLFSSL_FATAL_ERROR;
25984     }
25985 
25986     p->inSet = 1;
25987 
25988     return WOLFSSL_SUCCESS;
25989 }
25990 #endif /* HAVE_ECC */
25991 #endif /* OPENSSL_EXTRA */
25992 
25993 #if defined(HAVE_ECC) && defined(OPENSSL_EXTRA_X509_SMALL)
25994 
25995 /* EC_POINT WolfSSL -> OpenSSL */
25996 static int SetECPointExternal(WOLFSSL_EC_POINT *p)
25997 {
25998     ecc_point* point;
25999 
26000     WOLFSSL_ENTER("SetECPointExternal");
26001 
26002     if (p == NULL || p->internal == NULL) {
26003         WOLFSSL_MSG("ECPoint NULL error");
26004         return WOLFSSL_FATAL_ERROR;
26005     }
26006 
26007     point = (ecc_point*)p->internal;
26008 
26009     if (SetIndividualExternal(&p->X, point->x) != WOLFSSL_SUCCESS) {
26010         WOLFSSL_MSG("ecc point X error");
26011         return WOLFSSL_FATAL_ERROR;
26012     }
26013 
26014     if (SetIndividualExternal(&p->Y, point->y) != WOLFSSL_SUCCESS) {
26015         WOLFSSL_MSG("ecc point Y error");
26016         return WOLFSSL_FATAL_ERROR;
26017     }
26018 
26019     if (SetIndividualExternal(&p->Z, point->z) != WOLFSSL_SUCCESS) {
26020         WOLFSSL_MSG("ecc point Z error");
26021         return WOLFSSL_FATAL_ERROR;
26022     }
26023 
26024     p->exSet = 1;
26025 
26026     return WOLFSSL_SUCCESS;
26027 }
26028 
26029 
26030 /* EC_KEY wolfSSL -> OpenSSL */
26031 static int SetECKeyExternal(WOLFSSL_EC_KEY* eckey)
26032 {
26033     ecc_key* key;
26034 
26035     WOLFSSL_ENTER("SetECKeyExternal");
26036 
26037     if (eckey == NULL || eckey->internal == NULL) {
26038         WOLFSSL_MSG("ec key NULL error");
26039         return WOLFSSL_FATAL_ERROR;
26040     }
26041 
26042     key = (ecc_key*)eckey->internal;
26043 
26044     /* set group (OID, nid and idx) */
26045     eckey->group->curve_oid = ecc_sets[key->idx].oidSum;
26046     eckey->group->curve_nid = ecc_sets[key->idx].id;
26047     eckey->group->curve_idx = key->idx;
26048 
26049     if (eckey->pub_key->internal != NULL) {
26050         /* set the internal public key */
26051         if (wc_ecc_copy_point(&key->pubkey,
26052                              (ecc_point*)eckey->pub_key->internal) != MP_OKAY) {
26053             WOLFSSL_MSG("SetECKeyExternal ecc_copy_point failed");
26054             return WOLFSSL_FATAL_ERROR;
26055         }
26056 
26057         /* set the external pubkey (point) */
26058         if (SetECPointExternal(eckey->pub_key) != WOLFSSL_SUCCESS) {
26059             WOLFSSL_MSG("SetECKeyExternal SetECPointExternal failed");
26060             return WOLFSSL_FATAL_ERROR;
26061         }
26062     }
26063 
26064     /* set the external privkey */
26065     if (key->type == ECC_PRIVATEKEY) {
26066         if (SetIndividualExternal(&eckey->priv_key, &key->k) != WOLFSSL_SUCCESS) {
26067             WOLFSSL_MSG("ec priv key error");
26068             return WOLFSSL_FATAL_ERROR;
26069         }
26070     }
26071 
26072     eckey->exSet = 1;
26073 
26074     return WOLFSSL_SUCCESS;
26075 }
26076 #endif /* HAVE_ECC && OPENSSL_EXTRA_X509_SMALL */
26077 
26078 #ifdef OPENSSL_EXTRA
26079 #ifdef HAVE_ECC
26080 /* EC_KEY Openssl -> WolfSSL */
26081 static int SetECKeyInternal(WOLFSSL_EC_KEY* eckey)
26082 {
26083     ecc_key* key;
26084 
26085     WOLFSSL_ENTER("SetECKeyInternal");
26086 
26087     if (eckey == NULL || eckey->internal == NULL) {
26088         WOLFSSL_MSG("ec key NULL error");
26089         return WOLFSSL_FATAL_ERROR;
26090     }
26091 
26092     key = (ecc_key*)eckey->internal;
26093 
26094     /* validate group */
26095     if ((eckey->group->curve_idx < 0) ||
26096         (wc_ecc_is_valid_idx(eckey->group->curve_idx) == 0)) {
26097         WOLFSSL_MSG("invalid curve idx");
26098         return WOLFSSL_FATAL_ERROR;
26099     }
26100 
26101     /* set group (idx of curve and corresponding domain parameters) */
26102     key->idx = eckey->group->curve_idx;
26103     key->dp = &ecc_sets[key->idx];
26104 
26105     /* set pubkey (point) */
26106     if (eckey->pub_key != NULL) {
26107         if (SetECPointInternal(eckey->pub_key) != WOLFSSL_SUCCESS) {
26108             WOLFSSL_MSG("ec key pub error");
26109             return WOLFSSL_FATAL_ERROR;
26110         }
26111 
26112         /* public key */
26113         key->type = ECC_PUBLICKEY;
26114     }
26115 
26116     /* set privkey */
26117     if (eckey->priv_key != NULL) {
26118         if (SetIndividualInternal(eckey->priv_key, &key->k) != WOLFSSL_SUCCESS) {
26119             WOLFSSL_MSG("ec key priv error");
26120             return WOLFSSL_FATAL_ERROR;
26121         }
26122 
26123         /* private key */
26124         key->type = ECC_PRIVATEKEY;
26125     }
26126 
26127     eckey->inSet = 1;
26128 
26129     return WOLFSSL_SUCCESS;
26130 }
26131 
26132 WOLFSSL_EC_POINT *wolfSSL_EC_KEY_get0_public_key(const WOLFSSL_EC_KEY *key)
26133 {
26134     WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_public_key");
26135 
26136     if (key == NULL) {
26137         WOLFSSL_MSG("wolfSSL_EC_KEY_get0_group Bad arguments");
26138         return NULL;
26139     }
26140 
26141     return key->pub_key;
26142 }
26143 
26144 const WOLFSSL_EC_GROUP *wolfSSL_EC_KEY_get0_group(const WOLFSSL_EC_KEY *key)
26145 {
26146     WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_group");
26147 
26148     if (key == NULL) {
26149         WOLFSSL_MSG("wolfSSL_EC_KEY_get0_group Bad arguments");
26150         return NULL;
26151     }
26152 
26153     return key->group;
26154 }
26155 
26156 
26157 /* return code compliant with OpenSSL :
26158  *   1 if success, 0 if error
26159  */
26160 int wolfSSL_EC_KEY_set_private_key(WOLFSSL_EC_KEY *key,
26161                                    const WOLFSSL_BIGNUM *priv_key)
26162 {
26163     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_private_key");
26164 
26165     if (key == NULL || priv_key == NULL) {
26166         WOLFSSL_MSG("Bad arguments");
26167         return WOLFSSL_FAILURE;
26168     }
26169 
26170     /* free key if previously set */
26171     if (key->priv_key != NULL)
26172         wolfSSL_BN_free(key->priv_key);
26173 
26174     key->priv_key = wolfSSL_BN_dup(priv_key);
26175     if (key->priv_key == NULL) {
26176         WOLFSSL_MSG("key ecc priv key NULL");
26177         return WOLFSSL_FAILURE;
26178     }
26179 
26180     if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) {
26181         WOLFSSL_MSG("SetECKeyInternal failed");
26182         wolfSSL_BN_free(key->priv_key);
26183         return WOLFSSL_FAILURE;
26184     }
26185 
26186     return WOLFSSL_SUCCESS;
26187 }
26188 
26189 
26190 WOLFSSL_BIGNUM *wolfSSL_EC_KEY_get0_private_key(const WOLFSSL_EC_KEY *key)
26191 {
26192     WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_private_key");
26193 
26194     if (key == NULL) {
26195         WOLFSSL_MSG("wolfSSL_EC_KEY_get0_private_key Bad arguments");
26196         return NULL;
26197     }
26198 
26199     return key->priv_key;
26200 }
26201 
26202 WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid)
26203 {
26204     WOLFSSL_EC_KEY *key;
26205     int x;
26206 
26207     WOLFSSL_ENTER("wolfSSL_EC_KEY_new_by_curve_name");
26208 
26209     key = wolfSSL_EC_KEY_new();
26210     if (key == NULL) {
26211         WOLFSSL_MSG("wolfSSL_EC_KEY_new failure");
26212         return NULL;
26213     }
26214 
26215     /* set the nid of the curve */
26216     key->group->curve_nid = nid;
26217 
26218     /* search and set the corresponding internal curve idx */
26219     for (x = 0; ecc_sets[x].size != 0; x++)
26220         if (ecc_sets[x].id == key->group->curve_nid) {
26221             key->group->curve_idx = x;
26222             key->group->curve_oid = ecc_sets[x].oidSum;
26223             break;
26224         }
26225 
26226     return key;
26227 }
26228 
26229 #endif /* HAVE_ECC */
26230 #endif /* OPENSSL_EXTRA */
26231 
26232 #if defined(HAVE_ECC) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
26233 static void InitwolfSSL_ECKey(WOLFSSL_EC_KEY* key)
26234 {
26235     if (key) {
26236         key->group    = NULL;
26237         key->pub_key  = NULL;
26238         key->priv_key = NULL;
26239         key->internal = NULL;
26240         key->inSet    = 0;
26241         key->exSet    = 0;
26242     }
26243 }
26244 
26245 WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void)
26246 {
26247     WOLFSSL_EC_KEY *external;
26248     ecc_key* key;
26249 
26250     WOLFSSL_ENTER("wolfSSL_EC_KEY_new");
26251 
26252     external = (WOLFSSL_EC_KEY*)XMALLOC(sizeof(WOLFSSL_EC_KEY), NULL,
26253                                         DYNAMIC_TYPE_ECC);
26254     if (external == NULL) {
26255         WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_KEY failure");
26256         return NULL;
26257     }
26258     XMEMSET(external, 0, sizeof(WOLFSSL_EC_KEY));
26259 
26260     InitwolfSSL_ECKey(external);
26261 
26262     external->internal = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL,
26263                                            DYNAMIC_TYPE_ECC);
26264     if (external->internal == NULL) {
26265         WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc ecc key failure");
26266         wolfSSL_EC_KEY_free(external);
26267         return NULL;
26268     }
26269     XMEMSET(external->internal, 0, sizeof(ecc_key));
26270 
26271     wc_ecc_init((ecc_key*)external->internal);
26272 
26273     /* public key */
26274     external->pub_key = (WOLFSSL_EC_POINT*)XMALLOC(sizeof(WOLFSSL_EC_POINT),
26275                                                    NULL, DYNAMIC_TYPE_ECC);
26276     if (external->pub_key == NULL) {
26277         WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_POINT failure");
26278         wolfSSL_EC_KEY_free(external);
26279         return NULL;
26280     }
26281     XMEMSET(external->pub_key, 0, sizeof(WOLFSSL_EC_POINT));
26282 
26283     key = (ecc_key*)external->internal;
26284     external->pub_key->internal = wc_ecc_new_point();
26285     if (wc_ecc_copy_point((ecc_point*)&key->pubkey,
26286                 (ecc_point*)external->pub_key->internal) != MP_OKAY) {
26287         WOLFSSL_MSG("wc_ecc_copy_point failure");
26288         wolfSSL_EC_KEY_free(external);
26289         return NULL;
26290     }
26291 
26292     /* curve group */
26293     external->group = (WOLFSSL_EC_GROUP*)XMALLOC(sizeof(WOLFSSL_EC_GROUP), NULL,
26294                                                  DYNAMIC_TYPE_ECC);
26295     if (external->group == NULL) {
26296         WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_GROUP failure");
26297         wolfSSL_EC_KEY_free(external);
26298         return NULL;
26299     }
26300     XMEMSET(external->group, 0, sizeof(WOLFSSL_EC_GROUP));
26301 
26302     /* private key */
26303     external->priv_key = wolfSSL_BN_new();
26304     if (external->priv_key == NULL) {
26305         WOLFSSL_MSG("wolfSSL_BN_new failure");
26306         wolfSSL_EC_KEY_free(external);
26307         return NULL;
26308     }
26309 
26310     return external;
26311 }
26312 
26313 void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key)
26314 {
26315     WOLFSSL_ENTER("wolfSSL_EC_KEY_free");
26316 
26317     if (key != NULL) {
26318         if (key->internal != NULL) {
26319             wc_ecc_free((ecc_key*)key->internal);
26320             XFREE(key->internal, NULL, DYNAMIC_TYPE_ECC);
26321         }
26322         wolfSSL_BN_free(key->priv_key);
26323         wolfSSL_EC_POINT_free(key->pub_key);
26324         wolfSSL_EC_GROUP_free(key->group);
26325         InitwolfSSL_ECKey(key); /* set back to NULLs for safety */
26326 
26327         XFREE(key, NULL, DYNAMIC_TYPE_ECC);
26328         key = NULL;
26329     }
26330 }
26331 #endif /* HAVE_ECC && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */
26332 
26333 #ifdef OPENSSL_EXTRA
26334 #ifdef HAVE_ECC
26335 
26336 #ifndef NO_WOLFSSL_STUB
26337 int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group)
26338 {
26339     (void)key;
26340     (void)group;
26341 
26342     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_group");
26343     WOLFSSL_STUB("EC_KEY_set_group");
26344 
26345     return -1;
26346 }
26347 #endif
26348 
26349 int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key)
26350 {
26351     int     initTmpRng = 0;
26352     WC_RNG* rng = NULL;
26353 #ifdef WOLFSSL_SMALL_STACK
26354     WC_RNG* tmpRNG = NULL;
26355 #else
26356     WC_RNG  tmpRNG[1];
26357 #endif
26358 
26359     WOLFSSL_ENTER("wolfSSL_EC_KEY_generate_key");
26360 
26361     if (key == NULL || key->internal == NULL ||
26362         key->group == NULL || key->group->curve_idx < 0) {
26363         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key Bad arguments");
26364         return 0;
26365     }
26366 
26367 #ifdef WOLFSSL_SMALL_STACK
26368     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
26369     if (tmpRNG == NULL)
26370         return 0;
26371 #endif
26372 
26373     if (wc_InitRng(tmpRNG) == 0) {
26374         rng = tmpRNG;
26375         initTmpRng = 1;
26376     }
26377     else {
26378         WOLFSSL_MSG("Bad RNG Init, trying global");
26379         if (initGlobalRNG == 0)
26380             WOLFSSL_MSG("Global RNG no Init");
26381         else
26382             rng = &globalRNG;
26383     }
26384 
26385     if (rng == NULL) {
26386         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to set RNG");
26387 #ifdef WOLFSSL_SMALL_STACK
26388         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
26389 #endif
26390         return 0;
26391     }
26392 
26393     if (wc_ecc_make_key_ex(rng, 0, (ecc_key*)key->internal,
26394                                         key->group->curve_nid) != MP_OKAY) {
26395         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key wc_ecc_make_key failed");
26396 #ifdef WOLFSSL_SMALL_STACK
26397         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
26398 #endif
26399         return 0;
26400     }
26401 
26402     if (initTmpRng)
26403         wc_FreeRng(tmpRNG);
26404 #ifdef WOLFSSL_SMALL_STACK
26405     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
26406 #endif
26407 
26408     if (SetECKeyExternal(key) != WOLFSSL_SUCCESS) {
26409         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key SetECKeyExternal failed");
26410         return 0;
26411     }
26412 
26413     return 1;
26414 }
26415 
26416 #ifndef NO_WOLFSSL_STUB
26417 void wolfSSL_EC_KEY_set_asn1_flag(WOLFSSL_EC_KEY *key, int asn1_flag)
26418 {
26419     (void)key;
26420     (void)asn1_flag;
26421 
26422     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_asn1_flag");
26423     WOLFSSL_STUB("EC_KEY_set_asn1_flag");
26424 }
26425 #endif
26426 
26427 /* return code compliant with OpenSSL :
26428  *   1 if success, 0 if error
26429  */
26430 int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key,
26431                                   const WOLFSSL_EC_POINT *pub)
26432 {
26433     ecc_point *pub_p, *key_p;
26434 
26435     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_public_key");
26436 
26437     if (key == NULL || key->internal == NULL ||
26438         pub == NULL || pub->internal == NULL) {
26439         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order Bad arguments");
26440         return WOLFSSL_FAILURE;
26441     }
26442 
26443     if (key->inSet == 0) {
26444         if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) {
26445             WOLFSSL_MSG("SetECKeyInternal failed");
26446             return WOLFSSL_FAILURE;
26447         }
26448     }
26449 
26450     if (pub->inSet == 0) {
26451         if (SetECPointInternal((WOLFSSL_EC_POINT *)pub) != WOLFSSL_SUCCESS) {
26452             WOLFSSL_MSG("SetECPointInternal failed");
26453             return WOLFSSL_FAILURE;
26454         }
26455     }
26456 
26457     pub_p = (ecc_point*)pub->internal;
26458     key_p = (ecc_point*)key->pub_key->internal;
26459 
26460     /* create new point if required */
26461     if (key_p == NULL)
26462         key_p = wc_ecc_new_point();
26463 
26464     if (key_p == NULL) {
26465         WOLFSSL_MSG("key ecc point NULL");
26466         return WOLFSSL_FAILURE;
26467     }
26468 
26469     if (wc_ecc_copy_point(pub_p, key_p) != MP_OKAY) {
26470         WOLFSSL_MSG("ecc_copy_point failure");
26471         return WOLFSSL_FAILURE;
26472     }
26473 
26474     if (SetECKeyExternal(key) != WOLFSSL_SUCCESS) {
26475         WOLFSSL_MSG("SetECKeyInternal failed");
26476         return WOLFSSL_FAILURE;
26477     }
26478 
26479     wolfSSL_EC_POINT_dump("pub", pub);
26480     wolfSSL_EC_POINT_dump("key->pub_key", key->pub_key);
26481 
26482     return WOLFSSL_SUCCESS;
26483 }
26484 /* End EC_KEY */
26485 
26486 void wolfSSL_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *p)
26487 {
26488 #if defined(DEBUG_WOLFSSL)
26489     char *num;
26490 
26491     WOLFSSL_ENTER("wolfSSL_EC_POINT_dump");
26492 
26493     if (p == NULL) {
26494         printf("%s = NULL", msg);
26495         return;
26496     }
26497 
26498     printf("%s:\n\tinSet=%d, exSet=%d\n", msg, p->inSet, p->exSet);
26499     num = wolfSSL_BN_bn2hex(p->X);
26500     printf("\tX = %s\n", num);
26501     XFREE(num, NULL, DYNAMIC_TYPE_ECC);
26502     num = wolfSSL_BN_bn2hex(p->Y);
26503     printf("\tY = %s\n", num);
26504     XFREE(num, NULL, DYNAMIC_TYPE_ECC);
26505     num = wolfSSL_BN_bn2hex(p->Z);
26506     printf("\tZ = %s\n", num);
26507     XFREE(num, NULL, DYNAMIC_TYPE_ECC);
26508 #else
26509     (void)msg;
26510     (void)p;
26511 #endif
26512 }
26513 
26514 /* Start EC_GROUP */
26515 
26516 /* return code compliant with OpenSSL :
26517  *   0 if equal, 1 if not and -1 in case of error
26518  */
26519 int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b,
26520                          WOLFSSL_BN_CTX *ctx)
26521 {
26522     (void)ctx;
26523 
26524     WOLFSSL_ENTER("wolfSSL_EC_GROUP_cmp");
26525 
26526     if (a == NULL || b == NULL) {
26527         WOLFSSL_MSG("wolfSSL_EC_GROUP_cmp Bad arguments");
26528         return WOLFSSL_FATAL_ERROR;
26529     }
26530 
26531     /* ok */
26532     if ((a->curve_idx == b->curve_idx) && (a->curve_nid == b->curve_nid))
26533         return 0;
26534 
26535     /* ko */
26536     return 1;
26537 }
26538 
26539 #endif /* HAVE_ECC */
26540 #endif /* OPENSSL_EXTRA */
26541 
26542 #if defined(HAVE_ECC) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
26543 void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group)
26544 {
26545     WOLFSSL_ENTER("wolfSSL_EC_GROUP_free");
26546 
26547     XFREE(group, NULL, DYNAMIC_TYPE_ECC);
26548     group = NULL;
26549 }
26550 #endif
26551 
26552 #ifdef OPENSSL_EXTRA
26553 #ifdef HAVE_ECC
26554 #ifndef NO_WOLFSSL_STUB
26555 void wolfSSL_EC_GROUP_set_asn1_flag(WOLFSSL_EC_GROUP *group, int flag)
26556 {
26557     (void)group;
26558     (void)flag;
26559 
26560     WOLFSSL_ENTER("wolfSSL_EC_GROUP_set_asn1_flag");
26561     WOLFSSL_STUB("EC_GROUP_set_asn1_flag");
26562 }
26563 #endif
26564 
26565 WOLFSSL_EC_GROUP *wolfSSL_EC_GROUP_new_by_curve_name(int nid)
26566 {
26567     WOLFSSL_EC_GROUP *g;
26568     int x;
26569 
26570     WOLFSSL_ENTER("wolfSSL_EC_GROUP_new_by_curve_name");
26571 
26572     /* curve group */
26573     g = (WOLFSSL_EC_GROUP*) XMALLOC(sizeof(WOLFSSL_EC_GROUP), NULL,
26574                                     DYNAMIC_TYPE_ECC);
26575     if (g == NULL) {
26576         WOLFSSL_MSG("wolfSSL_EC_GROUP_new_by_curve_name malloc failure");
26577         return NULL;
26578     }
26579     XMEMSET(g, 0, sizeof(WOLFSSL_EC_GROUP));
26580 
26581     /* set the nid of the curve */
26582     g->curve_nid = nid;
26583 
26584     /* search and set the corresponding internal curve idx */
26585     for (x = 0; ecc_sets[x].size != 0; x++)
26586         if (ecc_sets[x].id == g->curve_nid) {
26587             g->curve_idx = x;
26588             g->curve_oid = ecc_sets[x].oidSum;
26589             break;
26590         }
26591 
26592     return g;
26593 }
26594 
26595 /* return code compliant with OpenSSL :
26596  *   the curve nid if success, 0 if error
26597  */
26598 int wolfSSL_EC_GROUP_get_curve_name(const WOLFSSL_EC_GROUP *group)
26599 {
26600     WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_curve_name");
26601 
26602     if (group == NULL) {
26603         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_curve_name Bad arguments");
26604         return WOLFSSL_FAILURE;
26605     }
26606 
26607     return group->curve_nid;
26608 }
26609 
26610 /* return code compliant with OpenSSL :
26611  *   the degree of the curve if success, 0 if error
26612  */
26613 int wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP *group)
26614 {
26615     WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_degree");
26616 
26617     if (group == NULL || group->curve_idx < 0) {
26618         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_degree Bad arguments");
26619         return WOLFSSL_FAILURE;
26620     }
26621 
26622     switch(group->curve_nid) {
26623         case NID_secp112r1:
26624         case NID_secp112r2:
26625             return 112;
26626         case NID_secp128r1:
26627         case NID_secp128r2:
26628             return 128;
26629         case NID_secp160k1:
26630         case NID_secp160r1:
26631         case NID_secp160r2:
26632         case NID_brainpoolP160r1:
26633             return 160;
26634         case NID_secp192k1:
26635         case NID_brainpoolP192r1:
26636         case NID_X9_62_prime192v1:
26637             return 192;
26638         case NID_secp224k1:
26639         case NID_secp224r1:
26640         case NID_brainpoolP224r1:
26641             return 224;
26642         case NID_secp256k1:
26643         case NID_brainpoolP256r1:
26644         case NID_X9_62_prime256v1:
26645             return 256;
26646         case NID_brainpoolP320r1:
26647             return 320;
26648         case NID_secp384r1:
26649         case NID_brainpoolP384r1:
26650             return 384;
26651         case NID_secp521r1:
26652         case NID_brainpoolP512r1:
26653             return 521;
26654         default:
26655             return WOLFSSL_FAILURE;
26656     }
26657 }
26658 
26659 /* return code compliant with OpenSSL :
26660  *   1 if success, 0 if error
26661  */
26662 int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group,
26663                                WOLFSSL_BIGNUM *order, WOLFSSL_BN_CTX *ctx)
26664 {
26665     (void)ctx;
26666 
26667     if (group == NULL || order == NULL || order->internal == NULL) {
26668         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order NULL error");
26669         return WOLFSSL_FAILURE;
26670     }
26671 
26672     if (mp_init((mp_int*)order->internal) != MP_OKAY) {
26673         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_init failure");
26674         return WOLFSSL_FAILURE;
26675     }
26676 
26677     if (mp_read_radix((mp_int*)order->internal,
26678                   ecc_sets[group->curve_idx].order, MP_RADIX_HEX) != MP_OKAY) {
26679         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_read order failure");
26680         mp_clear((mp_int*)order->internal);
26681         return WOLFSSL_FAILURE;
26682     }
26683 
26684     return WOLFSSL_SUCCESS;
26685 }
26686 /* End EC_GROUP */
26687 
26688 /* Start EC_POINT */
26689 
26690 /* return code compliant with OpenSSL :
26691  *   1 if success, 0 if error
26692  */
26693 int wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP *group,
26694                         const WOLFSSL_EC_POINT *p,
26695                         unsigned char *out, unsigned int *len)
26696 {
26697     int err;
26698 
26699     WOLFSSL_ENTER("wolfSSL_ECPoint_i2d");
26700 
26701     if (group == NULL || p == NULL || len == NULL) {
26702         WOLFSSL_MSG("wolfSSL_ECPoint_i2d NULL error");
26703         return WOLFSSL_FAILURE;
26704     }
26705 
26706     if (p->inSet == 0) {
26707         WOLFSSL_MSG("No ECPoint internal set, do it");
26708 
26709         if (SetECPointInternal((WOLFSSL_EC_POINT *)p) != WOLFSSL_SUCCESS) {
26710             WOLFSSL_MSG("SetECPointInternal SetECPointInternal failed");
26711             return WOLFSSL_FAILURE;
26712         }
26713     }
26714 
26715     if (out != NULL) {
26716         wolfSSL_EC_POINT_dump("i2d p", p);
26717     }
26718 
26719     err = wc_ecc_export_point_der(group->curve_idx, (ecc_point*)p->internal,
26720                                   out, len);
26721     if (err != MP_OKAY && !(out == NULL && err == LENGTH_ONLY_E)) {
26722         WOLFSSL_MSG("wolfSSL_ECPoint_i2d wc_ecc_export_point_der failed");
26723         return WOLFSSL_FAILURE;
26724     }
26725 
26726     return WOLFSSL_SUCCESS;
26727 }
26728 
26729 /* return code compliant with OpenSSL :
26730  *   1 if success, 0 if error
26731  */
26732 int wolfSSL_ECPoint_d2i(unsigned char *in, unsigned int len,
26733                         const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *p)
26734 {
26735     WOLFSSL_ENTER("wolfSSL_ECPoint_d2i");
26736 
26737     if (group == NULL || p == NULL || p->internal == NULL || in == NULL) {
26738         WOLFSSL_MSG("wolfSSL_ECPoint_d2i NULL error");
26739         return WOLFSSL_FAILURE;
26740     }
26741 
26742     if (wc_ecc_import_point_der(in, len, group->curve_idx,
26743                                 (ecc_point*)p->internal) != MP_OKAY) {
26744         WOLFSSL_MSG("wc_ecc_import_point_der failed");
26745         return WOLFSSL_FAILURE;
26746     }
26747 
26748     if (p->exSet == 0) {
26749         WOLFSSL_MSG("No ECPoint external set, do it");
26750 
26751         if (SetECPointExternal(p) != WOLFSSL_SUCCESS) {
26752             WOLFSSL_MSG("SetECPointExternal failed");
26753             return WOLFSSL_FAILURE;
26754         }
26755     }
26756 
26757     wolfSSL_EC_POINT_dump("d2i p", p);
26758 
26759     return WOLFSSL_SUCCESS;
26760 }
26761 
26762 WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group)
26763 {
26764     WOLFSSL_EC_POINT *p;
26765 
26766     WOLFSSL_ENTER("wolfSSL_EC_POINT_new");
26767 
26768     if (group == NULL) {
26769         WOLFSSL_MSG("wolfSSL_EC_POINT_new NULL error");
26770         return NULL;
26771     }
26772 
26773     p = (WOLFSSL_EC_POINT *)XMALLOC(sizeof(WOLFSSL_EC_POINT), NULL,
26774                                     DYNAMIC_TYPE_ECC);
26775     if (p == NULL) {
26776         WOLFSSL_MSG("wolfSSL_EC_POINT_new malloc ecc point failure");
26777         return NULL;
26778     }
26779     XMEMSET(p, 0, sizeof(WOLFSSL_EC_POINT));
26780 
26781     p->internal = wc_ecc_new_point();
26782     if (p->internal == NULL) {
26783         WOLFSSL_MSG("ecc_new_point failure");
26784         XFREE(p, NULL, DYNAMIC_TYPE_ECC);
26785         return NULL;
26786     }
26787 
26788     return p;
26789 }
26790 
26791 /* return code compliant with OpenSSL :
26792  *   1 if success, 0 if error
26793  */
26794 int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group,
26795                                                 const WOLFSSL_EC_POINT *point,
26796                                                 WOLFSSL_BIGNUM *x,
26797                                                 WOLFSSL_BIGNUM *y,
26798                                                 WOLFSSL_BN_CTX *ctx)
26799 {
26800     (void)ctx;
26801 
26802     WOLFSSL_ENTER("wolfSSL_EC_POINT_get_affine_coordinates_GFp");
26803 
26804     if (group == NULL || point == NULL || point->internal == NULL ||
26805         x == NULL || y == NULL) {
26806         WOLFSSL_MSG("wolfSSL_EC_POINT_get_affine_coordinates_GFp NULL error");
26807         return WOLFSSL_FAILURE;
26808     }
26809 
26810     if (point->inSet == 0) {
26811         WOLFSSL_MSG("No ECPoint internal set, do it");
26812 
26813         if (SetECPointInternal((WOLFSSL_EC_POINT *)point) != WOLFSSL_SUCCESS) {
26814             WOLFSSL_MSG("SetECPointInternal failed");
26815             return WOLFSSL_FAILURE;
26816         }
26817     }
26818 
26819     BN_copy(x, point->X);
26820     BN_copy(y, point->Y);
26821 
26822     return WOLFSSL_SUCCESS;
26823 }
26824 
26825 #ifndef WOLFSSL_ATECC508A
26826 /* return code compliant with OpenSSL :
26827  *   1 if success, 0 if error
26828  */
26829 int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r,
26830                          const WOLFSSL_BIGNUM *n, const WOLFSSL_EC_POINT *q,
26831                          const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
26832 {
26833     mp_int a, prime;
26834     int ret;
26835 
26836     (void)ctx;
26837     (void)n;
26838 
26839     WOLFSSL_ENTER("wolfSSL_EC_POINT_mul");
26840 
26841     if (group == NULL || r == NULL || r->internal == NULL ||
26842         q == NULL || q->internal == NULL || m == NULL) {
26843         WOLFSSL_MSG("wolfSSL_EC_POINT_mul NULL error");
26844         return WOLFSSL_FAILURE;
26845     }
26846 
26847     if (q->inSet == 0) {
26848         WOLFSSL_MSG("No ECPoint internal set, do it");
26849 
26850         if (SetECPointInternal((WOLFSSL_EC_POINT *)q) != WOLFSSL_SUCCESS) {
26851             WOLFSSL_MSG("SetECPointInternal q failed");
26852             return WOLFSSL_FAILURE;
26853         }
26854     }
26855 
26856     /* read the curve prime and a */
26857     if (mp_init_multi(&prime, &a, NULL, NULL, NULL, NULL) != MP_OKAY) {
26858         return WOLFSSL_FAILURE;
26859     }
26860 
26861     ret = mp_read_radix(&prime, ecc_sets[group->curve_idx].prime, MP_RADIX_HEX);
26862     if (ret == MP_OKAY) {
26863         ret = mp_read_radix(&a, ecc_sets[group->curve_idx].Af, MP_RADIX_HEX);
26864     }
26865 
26866     /* r = q * m % prime */
26867     if (ret == MP_OKAY) {
26868         ret = wc_ecc_mulmod((mp_int*)m->internal, (ecc_point*)q->internal,
26869                       (ecc_point*)r->internal, &a, &prime, 1);
26870     }
26871 
26872     mp_clear(&a);
26873     mp_clear(&prime);
26874 
26875     if (ret == MP_OKAY) {
26876         r->inSet = 1; /* mark internal set */
26877 
26878         /* set the external value for the computed point */
26879         ret = SetECPointExternal(r);
26880         if (ret != WOLFSSL_SUCCESS) {
26881             WOLFSSL_MSG("SetECPointInternal r failed");
26882         }
26883     }
26884     else {
26885         ret = WOLFSSL_FAILURE;
26886     }
26887 
26888     return ret;
26889 }
26890 #endif
26891 
26892 void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *p)
26893 {
26894     WOLFSSL_ENTER("wolfSSL_EC_POINT_clear_free");
26895 
26896     wolfSSL_EC_POINT_free(p);
26897 }
26898 
26899 /* return code compliant with OpenSSL :
26900  *   0 if equal, 1 if not and -1 in case of error
26901  */
26902 int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group,
26903                          const WOLFSSL_EC_POINT *a, const WOLFSSL_EC_POINT *b,
26904                          WOLFSSL_BN_CTX *ctx)
26905 {
26906     int ret;
26907 
26908     (void)ctx;
26909 
26910     WOLFSSL_ENTER("wolfSSL_EC_POINT_cmp");
26911 
26912     if (group == NULL || a == NULL || a->internal == NULL || b == NULL ||
26913         b->internal == NULL) {
26914         WOLFSSL_MSG("wolfSSL_EC_POINT_cmp Bad arguments");
26915         return WOLFSSL_FATAL_ERROR;
26916     }
26917 
26918     ret = wc_ecc_cmp_point((ecc_point*)a->internal, (ecc_point*)b->internal);
26919     if (ret == MP_EQ)
26920         return 0;
26921     else if (ret == MP_LT || ret == MP_GT)
26922         return 1;
26923 
26924     return WOLFSSL_FATAL_ERROR;
26925 }
26926 #endif /* HAVE_ECC */
26927 #endif /* OPENSSL_EXTRA */
26928 
26929 #if defined(HAVE_ECC) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
26930 void wolfSSL_EC_POINT_free(WOLFSSL_EC_POINT *p)
26931 {
26932     WOLFSSL_ENTER("wolfSSL_EC_POINT_free");
26933 
26934     if (p != NULL) {
26935         if (p->internal != NULL) {
26936             wc_ecc_del_point((ecc_point*)p->internal);
26937             p->internal = NULL;
26938         }
26939 
26940         wolfSSL_BN_free(p->X);
26941         wolfSSL_BN_free(p->Y);
26942         wolfSSL_BN_free(p->Z);
26943         p->X = NULL;
26944         p->Y = NULL;
26945         p->Z = NULL;
26946         p->inSet = p->exSet = 0;
26947 
26948         XFREE(p, NULL, DYNAMIC_TYPE_ECC);
26949         p = NULL;
26950     }
26951 }
26952 #endif
26953 
26954 #ifdef OPENSSL_EXTRA
26955 #ifdef HAVE_ECC
26956 /* return code compliant with OpenSSL :
26957  *   1 if point at infinity, 0 else
26958  */
26959 int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group,
26960                                     const WOLFSSL_EC_POINT *point)
26961 {
26962     int ret;
26963 
26964     WOLFSSL_ENTER("wolfSSL_EC_POINT_is_at_infinity");
26965 
26966     if (group == NULL || point == NULL || point->internal == NULL) {
26967         WOLFSSL_MSG("wolfSSL_EC_POINT_is_at_infinity NULL error");
26968         return WOLFSSL_FAILURE;
26969     }
26970     if (point->inSet == 0) {
26971         WOLFSSL_MSG("No ECPoint internal set, do it");
26972 
26973         if (SetECPointInternal((WOLFSSL_EC_POINT *)point) != WOLFSSL_SUCCESS) {
26974             WOLFSSL_MSG("SetECPointInternal failed");
26975             return WOLFSSL_FAILURE;
26976         }
26977     }
26978 
26979     ret = wc_ecc_point_is_at_infinity((ecc_point*)point->internal);
26980     if (ret <= 0) {
26981         WOLFSSL_MSG("ecc_point_is_at_infinity failure");
26982         return WOLFSSL_FAILURE;
26983     }
26984 
26985     return WOLFSSL_SUCCESS;
26986 }
26987 
26988 /* End EC_POINT */
26989 
26990 /* Start ECDSA_SIG */
26991 void wolfSSL_ECDSA_SIG_free(WOLFSSL_ECDSA_SIG *sig)
26992 {
26993     WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_free");
26994 
26995     if (sig) {
26996         wolfSSL_BN_free(sig->r);
26997         wolfSSL_BN_free(sig->s);
26998 
26999         XFREE(sig, NULL, DYNAMIC_TYPE_ECC);
27000     }
27001 }
27002 
27003 WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_SIG_new(void)
27004 {
27005     WOLFSSL_ECDSA_SIG *sig;
27006 
27007     WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_new");
27008 
27009     sig = (WOLFSSL_ECDSA_SIG*) XMALLOC(sizeof(WOLFSSL_ECDSA_SIG), NULL,
27010                                        DYNAMIC_TYPE_ECC);
27011     if (sig == NULL) {
27012         WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA signature failure");
27013         return NULL;
27014     }
27015 
27016     sig->s = NULL;
27017     sig->r = wolfSSL_BN_new();
27018     if (sig->r == NULL) {
27019         WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA r failure");
27020         wolfSSL_ECDSA_SIG_free(sig);
27021         return NULL;
27022     }
27023 
27024     sig->s = wolfSSL_BN_new();
27025     if (sig->s == NULL) {
27026         WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA s failure");
27027         wolfSSL_ECDSA_SIG_free(sig);
27028         return NULL;
27029     }
27030 
27031     return sig;
27032 }
27033 
27034 /* return signature structure on success, NULL otherwise */
27035 WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *d, int dlen,
27036                                          WOLFSSL_EC_KEY *key)
27037 {
27038     WOLFSSL_ECDSA_SIG *sig = NULL;
27039     int     initTmpRng = 0;
27040     WC_RNG* rng = NULL;
27041 #ifdef WOLFSSL_SMALL_STACK
27042     WC_RNG* tmpRNG = NULL;
27043 #else
27044     WC_RNG  tmpRNG[1];
27045 #endif
27046 
27047     WOLFSSL_ENTER("wolfSSL_ECDSA_do_sign");
27048 
27049     if (d == NULL || key == NULL || key->internal == NULL) {
27050         WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Bad arguments");
27051         return NULL;
27052     }
27053 
27054     /* set internal key if not done */
27055     if (key->inSet == 0)
27056     {
27057         WOLFSSL_MSG("wolfSSL_ECDSA_do_sign No EC key internal set, do it");
27058 
27059         if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) {
27060             WOLFSSL_MSG("wolfSSL_ECDSA_do_sign SetECKeyInternal failed");
27061             return NULL;
27062         }
27063     }
27064 
27065 #ifdef WOLFSSL_SMALL_STACK
27066     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
27067     if (tmpRNG == NULL)
27068         return NULL;
27069 #endif
27070 
27071     if (wc_InitRng(tmpRNG) == 0) {
27072         rng = tmpRNG;
27073         initTmpRng = 1;
27074     }
27075     else {
27076         WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Bad RNG Init, trying global");
27077         if (initGlobalRNG == 0)
27078             WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Global RNG no Init");
27079         else
27080             rng = &globalRNG;
27081     }
27082 
27083     if (rng) {
27084         mp_int sig_r, sig_s;
27085 
27086         if (mp_init_multi(&sig_r, &sig_s, NULL, NULL, NULL, NULL) == MP_OKAY) {
27087             if (wc_ecc_sign_hash_ex(d, dlen, rng, (ecc_key*)key->internal,
27088                                     &sig_r, &sig_s) != MP_OKAY) {
27089                 WOLFSSL_MSG("wc_ecc_sign_hash_ex failed");
27090             }
27091             else {
27092                 /* put signature blob in ECDSA structure */
27093                 sig = wolfSSL_ECDSA_SIG_new();
27094                 if (sig == NULL)
27095                     WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new failed");
27096                 else if (SetIndividualExternal(&(sig->r), &sig_r)!=WOLFSSL_SUCCESS){
27097                     WOLFSSL_MSG("ecdsa r key error");
27098                     wolfSSL_ECDSA_SIG_free(sig);
27099                     sig = NULL;
27100                 }
27101                 else if (SetIndividualExternal(&(sig->s), &sig_s)!=WOLFSSL_SUCCESS){
27102                     WOLFSSL_MSG("ecdsa s key error");
27103                     wolfSSL_ECDSA_SIG_free(sig);
27104                     sig = NULL;
27105                 }
27106 
27107             }
27108             mp_free(&sig_r);
27109             mp_free(&sig_s);
27110         }
27111     }
27112 
27113     if (initTmpRng)
27114         wc_FreeRng(tmpRNG);
27115 #ifdef WOLFSSL_SMALL_STACK
27116     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
27117 #endif
27118 
27119     return sig;
27120 }
27121 
27122 /* return code compliant with OpenSSL :
27123  *   1 for a valid signature, 0 for an invalid signature and -1 on error
27124  */
27125 int wolfSSL_ECDSA_do_verify(const unsigned char *d, int dlen,
27126                             const WOLFSSL_ECDSA_SIG *sig, WOLFSSL_EC_KEY *key)
27127 {
27128     int check_sign = 0;
27129 
27130     WOLFSSL_ENTER("wolfSSL_ECDSA_do_verify");
27131 
27132     if (d == NULL || sig == NULL || key == NULL || key->internal == NULL) {
27133         WOLFSSL_MSG("wolfSSL_ECDSA_do_verify Bad arguments");
27134         return WOLFSSL_FATAL_ERROR;
27135     }
27136 
27137     /* set internal key if not done */
27138     if (key->inSet == 0)
27139     {
27140         WOLFSSL_MSG("No EC key internal set, do it");
27141 
27142         if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) {
27143             WOLFSSL_MSG("SetECKeyInternal failed");
27144             return WOLFSSL_FATAL_ERROR;
27145         }
27146     }
27147 
27148     if (wc_ecc_verify_hash_ex((mp_int*)sig->r->internal,
27149                               (mp_int*)sig->s->internal, d, dlen, &check_sign,
27150                               (ecc_key *)key->internal) != MP_OKAY) {
27151         WOLFSSL_MSG("wc_ecc_verify_hash failed");
27152         return WOLFSSL_FATAL_ERROR;
27153     }
27154     else if (check_sign == 0) {
27155         WOLFSSL_MSG("wc_ecc_verify_hash incorrect signature detected");
27156         return WOLFSSL_FAILURE;
27157     }
27158 
27159     return WOLFSSL_SUCCESS;
27160 }
27161 /* End ECDSA_SIG */
27162 
27163 /* Start ECDH */
27164 /* return code compliant with OpenSSL :
27165  *   length of computed key if success, -1 if error
27166  */
27167 int wolfSSL_ECDH_compute_key(void *out, size_t outlen,
27168                              const WOLFSSL_EC_POINT *pub_key,
27169                              WOLFSSL_EC_KEY *ecdh,
27170                              void *(*KDF) (const void *in, size_t inlen,
27171                                            void *out, size_t *outlen))
27172 {
27173     word32 len;
27174     (void)KDF;
27175 
27176     (void)KDF;
27177 
27178     WOLFSSL_ENTER("wolfSSL_ECDH_compute_key");
27179 
27180     if (out == NULL || pub_key == NULL || pub_key->internal == NULL ||
27181         ecdh == NULL || ecdh->internal == NULL) {
27182         WOLFSSL_MSG("Bad function arguments");
27183         return WOLFSSL_FATAL_ERROR;
27184     }
27185 
27186     /* set internal key if not done */
27187     if (ecdh->inSet == 0)
27188     {
27189         WOLFSSL_MSG("No EC key internal set, do it");
27190 
27191         if (SetECKeyInternal(ecdh) != WOLFSSL_SUCCESS) {
27192             WOLFSSL_MSG("SetECKeyInternal failed");
27193             return WOLFSSL_FATAL_ERROR;
27194         }
27195     }
27196 
27197     len = (word32)outlen;
27198 
27199     if (wc_ecc_shared_secret_ssh((ecc_key*)ecdh->internal,
27200                                  (ecc_point*)pub_key->internal,
27201                                  (byte *)out, &len) != MP_OKAY) {
27202         WOLFSSL_MSG("wc_ecc_shared_secret failed");
27203         return WOLFSSL_FATAL_ERROR;
27204     }
27205 
27206     return len;
27207 }
27208 /* End ECDH */
27209 
27210 #if !defined(NO_FILESYSTEM)
27211 /* return code compliant with OpenSSL :
27212  *   1 if success, 0 if error
27213  */
27214 #ifndef NO_WOLFSSL_STUB
27215 int wolfSSL_PEM_write_EC_PUBKEY(FILE *fp, WOLFSSL_EC_KEY *x)
27216 {
27217     (void)fp;
27218     (void)x;
27219     WOLFSSL_STUB("PEM_write_EC_PUBKEY");
27220     WOLFSSL_MSG("wolfSSL_PEM_write_EC_PUBKEY not implemented");
27221 
27222     return WOLFSSL_FAILURE;
27223 }
27224 #endif
27225 
27226 #endif /* NO_FILESYSTEM */
27227 
27228 #if defined(WOLFSSL_KEY_GEN)
27229 
27230 /* return code compliant with OpenSSL :
27231  *   1 if success, 0 if error
27232  */
27233 #ifndef NO_WOLFSSL_STUB
27234 int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ecc,
27235                                        const EVP_CIPHER* cipher,
27236                                        unsigned char* passwd, int len,
27237                                        pem_password_cb* cb, void* arg)
27238 {
27239     (void)bio;
27240     (void)ecc;
27241     (void)cipher;
27242     (void)passwd;
27243     (void)len;
27244     (void)cb;
27245     (void)arg;
27246     WOLFSSL_STUB("PEM_write_bio_ECPrivateKey");
27247     WOLFSSL_MSG("wolfSSL_PEM_write_bio_ECPrivateKey not implemented");
27248 
27249     return WOLFSSL_FAILURE;
27250 }
27251 #endif
27252 
27253 /* return code compliant with OpenSSL :
27254  *   1 if success, 0 if error
27255  */
27256 int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc,
27257                                        const EVP_CIPHER* cipher,
27258                                        unsigned char* passwd, int passwdSz,
27259                                        unsigned char **pem, int *plen)
27260 {
27261 #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
27262     byte *derBuf, *tmp, *cipherInfo = NULL;
27263     int  der_max_len = 0, derSz = 0;
27264     const int type = ECC_PRIVATEKEY_TYPE;
27265     const char* header = NULL;
27266     const char* footer = NULL;
27267 
27268     WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey");
27269 
27270     if (pem == NULL || plen == NULL || ecc == NULL || ecc->internal == NULL) {
27271         WOLFSSL_MSG("Bad function arguments");
27272         return WOLFSSL_FAILURE;
27273     }
27274 
27275     if (wc_PemGetHeaderFooter(type, &header, &footer) != 0)
27276         return WOLFSSL_FAILURE;
27277 
27278     if (ecc->inSet == 0) {
27279         WOLFSSL_MSG("No ECC internal set, do it");
27280 
27281         if (SetECKeyInternal(ecc) != WOLFSSL_SUCCESS) {
27282             WOLFSSL_MSG("SetDsaInternal failed");
27283             return WOLFSSL_FAILURE;
27284         }
27285     }
27286 
27287     /* 4 > size of pub, priv + ASN.1 additional informations
27288      */
27289     der_max_len = 4 * wc_ecc_size((ecc_key*)ecc->internal) + AES_BLOCK_SIZE;
27290 
27291     derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_DER);
27292     if (derBuf == NULL) {
27293         WOLFSSL_MSG("malloc failed");
27294         return WOLFSSL_FAILURE;
27295     }
27296 
27297     /* Key to DER */
27298     derSz = wc_EccKeyToDer((ecc_key*)ecc->internal, derBuf, der_max_len);
27299     if (derSz < 0) {
27300         WOLFSSL_MSG("wc_DsaKeyToDer failed");
27301         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
27302         return WOLFSSL_FAILURE;
27303     }
27304 
27305     /* encrypt DER buffer if required */
27306     if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
27307         int ret;
27308 
27309         ret = EncryptDerKey(derBuf, &derSz, cipher,
27310                             passwd, passwdSz, &cipherInfo);
27311         if (ret != WOLFSSL_SUCCESS) {
27312             WOLFSSL_MSG("EncryptDerKey failed");
27313             XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
27314             return ret;
27315         }
27316 
27317         /* tmp buffer with a max size */
27318         *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
27319             (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE;
27320     }
27321     else { /* tmp buffer with a max size */
27322         *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
27323             (int)XSTRLEN(footer) + 1;
27324     }
27325 
27326     tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_PEM);
27327     if (tmp == NULL) {
27328         WOLFSSL_MSG("malloc failed");
27329         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
27330         if (cipherInfo != NULL)
27331             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
27332         return WOLFSSL_FAILURE;
27333     }
27334 
27335     /* DER to PEM */
27336     *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, type);
27337     if (*plen <= 0) {
27338         WOLFSSL_MSG("wc_DerToPemEx failed");
27339         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
27340         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
27341         if (cipherInfo != NULL)
27342             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
27343         return WOLFSSL_FAILURE;
27344     }
27345     XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
27346     if (cipherInfo != NULL)
27347         XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
27348 
27349     *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY);
27350     if (*pem == NULL) {
27351         WOLFSSL_MSG("malloc failed");
27352         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
27353         return WOLFSSL_FAILURE;
27354     }
27355     XMEMSET(*pem, 0, (*plen)+1);
27356 
27357     if (XMEMCPY(*pem, tmp, *plen) == NULL) {
27358         WOLFSSL_MSG("XMEMCPY failed");
27359         XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
27360         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
27361         return WOLFSSL_FAILURE;
27362     }
27363     XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
27364 
27365     return WOLFSSL_SUCCESS;
27366 #else
27367     (void)ecc;
27368     (void)cipher;
27369     (void)passwd;
27370     (void)passwdSz;
27371     (void)pem;
27372     (void)plen;
27373     return WOLFSSL_FAILURE;
27374 #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
27375 }
27376 
27377 #ifndef NO_FILESYSTEM
27378 /* return code compliant with OpenSSL :
27379  *   1 if success, 0 if error
27380  */
27381 int wolfSSL_PEM_write_ECPrivateKey(FILE *fp, WOLFSSL_EC_KEY *ecc,
27382                                    const EVP_CIPHER *enc,
27383                                    unsigned char *kstr, int klen,
27384                                    pem_password_cb *cb, void *u)
27385 {
27386     byte *pem;
27387     int  plen, ret;
27388 
27389     (void)cb;
27390     (void)u;
27391 
27392     WOLFSSL_MSG("wolfSSL_PEM_write_ECPrivateKey");
27393 
27394     if (fp == NULL || ecc == NULL || ecc->internal == NULL) {
27395         WOLFSSL_MSG("Bad function arguments");
27396         return WOLFSSL_FAILURE;
27397     }
27398 
27399     ret = wolfSSL_PEM_write_mem_ECPrivateKey(ecc, enc, kstr, klen, &pem, &plen);
27400     if (ret != WOLFSSL_SUCCESS) {
27401         WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey failed");
27402         return WOLFSSL_FAILURE;
27403     }
27404 
27405     ret = (int)XFWRITE(pem, plen, 1, fp);
27406     if (ret != 1) {
27407         WOLFSSL_MSG("ECC private key file write failed");
27408         return WOLFSSL_FAILURE;
27409     }
27410 
27411     XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
27412     return WOLFSSL_SUCCESS;
27413 }
27414 
27415 #endif /* NO_FILESYSTEM */
27416 #endif /* defined(WOLFSSL_KEY_GEN) */
27417 
27418 #endif /* HAVE_ECC */
27419 
27420 
27421 #ifndef NO_DSA
27422 
27423 #if defined(WOLFSSL_KEY_GEN)
27424 
27425 /* return code compliant with OpenSSL :
27426  *   1 if success, 0 if error
27427  */
27428 int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa,
27429                                        const EVP_CIPHER* cipher,
27430                                        unsigned char* passwd, int len,
27431                                        pem_password_cb* cb, void* arg)
27432 {
27433     (void)bio;
27434     (void)dsa;
27435     (void)cipher;
27436     (void)passwd;
27437     (void)len;
27438     (void)cb;
27439     (void)arg;
27440 
27441     WOLFSSL_MSG("wolfSSL_PEM_write_bio_DSAPrivateKey not implemented");
27442 
27443     return WOLFSSL_FAILURE;
27444 }
27445 
27446 /* return code compliant with OpenSSL :
27447  *   1 if success, 0 if error
27448  */
27449 int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa,
27450                                         const EVP_CIPHER* cipher,
27451                                         unsigned char* passwd, int passwdSz,
27452                                         unsigned char **pem, int *plen)
27453 {
27454 #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
27455     byte *derBuf, *tmp, *cipherInfo = NULL;
27456     int  der_max_len = 0, derSz = 0;
27457     const int type = DSA_PRIVATEKEY_TYPE;
27458     const char* header = NULL;
27459     const char* footer = NULL;
27460 
27461     WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey");
27462 
27463     if (pem == NULL || plen == NULL || dsa == NULL || dsa->internal == NULL) {
27464         WOLFSSL_MSG("Bad function arguments");
27465         return WOLFSSL_FAILURE;
27466     }
27467 
27468     if (wc_PemGetHeaderFooter(type, &header, &footer) != 0)
27469         return WOLFSSL_FAILURE;
27470 
27471     if (dsa->inSet == 0) {
27472         WOLFSSL_MSG("No DSA internal set, do it");
27473 
27474         if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) {
27475             WOLFSSL_MSG("SetDsaInternal failed");
27476             return WOLFSSL_FAILURE;
27477         }
27478     }
27479 
27480     /* 4 > size of pub, priv, p, q, g + ASN.1 additional informations
27481      */
27482     der_max_len = 4 * wolfSSL_BN_num_bytes(dsa->g) + AES_BLOCK_SIZE;
27483 
27484     derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_DER);
27485     if (derBuf == NULL) {
27486         WOLFSSL_MSG("malloc failed");
27487         return WOLFSSL_FAILURE;
27488     }
27489 
27490     /* Key to DER */
27491     derSz = wc_DsaKeyToDer((DsaKey*)dsa->internal, derBuf, der_max_len);
27492     if (derSz < 0) {
27493         WOLFSSL_MSG("wc_DsaKeyToDer failed");
27494         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
27495         return WOLFSSL_FAILURE;
27496     }
27497 
27498     /* encrypt DER buffer if required */
27499     if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
27500         int ret;
27501 
27502         ret = EncryptDerKey(derBuf, &derSz, cipher,
27503                             passwd, passwdSz, &cipherInfo);
27504         if (ret != WOLFSSL_SUCCESS) {
27505             WOLFSSL_MSG("EncryptDerKey failed");
27506             XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
27507             return ret;
27508         }
27509 
27510         /* tmp buffer with a max size */
27511         *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
27512             (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE;
27513     }
27514     else { /* tmp buffer with a max size */
27515         *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
27516             (int)XSTRLEN(footer) + 1;
27517     }
27518 
27519     tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_PEM);
27520     if (tmp == NULL) {
27521         WOLFSSL_MSG("malloc failed");
27522         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
27523         if (cipherInfo != NULL)
27524             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
27525         return WOLFSSL_FAILURE;
27526     }
27527 
27528     /* DER to PEM */
27529     *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, type);
27530     if (*plen <= 0) {
27531         WOLFSSL_MSG("wc_DerToPemEx failed");
27532         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
27533         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
27534         if (cipherInfo != NULL)
27535             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
27536         return WOLFSSL_FAILURE;
27537     }
27538     XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
27539     if (cipherInfo != NULL)
27540         XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
27541 
27542     *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY);
27543     if (*pem == NULL) {
27544         WOLFSSL_MSG("malloc failed");
27545         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
27546         return WOLFSSL_FAILURE;
27547     }
27548     XMEMSET(*pem, 0, (*plen)+1);
27549 
27550     if (XMEMCPY(*pem, tmp, *plen) == NULL) {
27551         WOLFSSL_MSG("XMEMCPY failed");
27552         XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
27553         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
27554         return WOLFSSL_FAILURE;
27555     }
27556     XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
27557 
27558     return WOLFSSL_SUCCESS;
27559 #else
27560     (void)dsa;
27561     (void)cipher;
27562     (void)passwd;
27563     (void)passwdSz;
27564     (void)pem;
27565     (void)plen;
27566     return WOLFSSL_FAILURE;
27567 #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
27568 }
27569 
27570 #ifndef NO_FILESYSTEM
27571 /* return code compliant with OpenSSL :
27572  *   1 if success, 0 if error
27573  */
27574 int wolfSSL_PEM_write_DSAPrivateKey(FILE *fp, WOLFSSL_DSA *dsa,
27575                                     const EVP_CIPHER *enc,
27576                                     unsigned char *kstr, int klen,
27577                                     pem_password_cb *cb, void *u)
27578 {
27579     byte *pem;
27580     int  plen, ret;
27581 
27582     (void)cb;
27583     (void)u;
27584 
27585     WOLFSSL_MSG("wolfSSL_PEM_write_DSAPrivateKey");
27586 
27587     if (fp == NULL || dsa == NULL || dsa->internal == NULL) {
27588         WOLFSSL_MSG("Bad function arguments");
27589         return WOLFSSL_FAILURE;
27590     }
27591 
27592     ret = wolfSSL_PEM_write_mem_DSAPrivateKey(dsa, enc, kstr, klen, &pem, &plen);
27593     if (ret != WOLFSSL_SUCCESS) {
27594         WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey failed");
27595         return WOLFSSL_FAILURE;
27596     }
27597 
27598     ret = (int)XFWRITE(pem, plen, 1, fp);
27599     if (ret != 1) {
27600         WOLFSSL_MSG("DSA private key file write failed");
27601         return WOLFSSL_FAILURE;
27602     }
27603 
27604     XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
27605     return WOLFSSL_SUCCESS;
27606 }
27607 
27608 #endif /* NO_FILESYSTEM */
27609 #endif /* defined(WOLFSSL_KEY_GEN) */
27610 
27611 #ifndef NO_FILESYSTEM
27612 /* return code compliant with OpenSSL :
27613  *   1 if success, 0 if error
27614  */
27615 #ifndef NO_WOLFSSL_STUB
27616 int wolfSSL_PEM_write_DSA_PUBKEY(FILE *fp, WOLFSSL_DSA *x)
27617 {
27618     (void)fp;
27619     (void)x;
27620     WOLFSSL_STUB("PEM_write_DSA_PUBKEY");
27621     WOLFSSL_MSG("wolfSSL_PEM_write_DSA_PUBKEY not implemented");
27622 
27623     return WOLFSSL_FAILURE;
27624 }
27625 #endif
27626 #endif /* NO_FILESYSTEM */
27627 
27628 #endif /* #ifndef NO_DSA */
27629 
27630 
27631 WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
27632                     WOLFSSL_EVP_PKEY** key, pem_password_cb* cb, void* pass)
27633 {
27634     WOLFSSL_EVP_PKEY* pkey = NULL;
27635 #ifdef WOLFSSL_SMALL_STACK
27636     EncryptedInfo* info;
27637 #else
27638     EncryptedInfo info[1];
27639 #endif /* WOLFSSL_SMALL_STACK */
27640     pem_password_cb* localCb = cb;
27641     DerBuffer* der = NULL;
27642 
27643     char* mem = NULL;
27644     int memSz;
27645     int ret;
27646     int eccFlag = 0;
27647 
27648     WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PrivateKey");
27649 
27650     if (bio == NULL) {
27651         return pkey;
27652     }
27653 
27654     if ((ret = wolfSSL_BIO_pending(bio)) > 0) {
27655         memSz = ret;
27656         mem = (char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
27657         if (mem == NULL) {
27658             WOLFSSL_MSG("Memory error");
27659             return NULL;
27660         }
27661 
27662         if ((ret = wolfSSL_BIO_read(bio, mem, memSz)) <= 0) {
27663             WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PrivateKey", ret);
27664             XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
27665             return NULL;
27666         }
27667     }
27668     else if (bio->type == WOLFSSL_BIO_FILE) {
27669         int sz  = 100; /* read from file by 100 byte chuncks */
27670         int idx = 0;
27671         char* tmp = (char*)XMALLOC(sz, bio->heap, DYNAMIC_TYPE_OPENSSL);
27672 
27673         memSz = 0;
27674         if (tmp == NULL) {
27675             WOLFSSL_MSG("Memory error");
27676             return NULL;
27677         }
27678 
27679         while ((sz = wolfSSL_BIO_read(bio, tmp, sz)) > 0) {
27680             if (memSz + sz < 0) {
27681                 /* sanity check */
27682                 break;
27683             }
27684             mem = (char*)XREALLOC(mem, memSz + sz, bio->heap,
27685                     DYNAMIC_TYPE_OPENSSL);
27686             if (mem == NULL) {
27687                 WOLFSSL_MSG("Memory error");
27688                 XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
27689                 return NULL;
27690             }
27691             XMEMCPY(mem + idx, tmp, sz);
27692             memSz += sz;
27693             idx   += sz;
27694             sz = 100; /* read another 100 byte chunck from file */
27695         }
27696         XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
27697         if (memSz <= 0) {
27698             WOLFSSL_MSG("No data to read from bio");
27699             if (mem != NULL) {
27700                 XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
27701             }
27702             return NULL;
27703         }
27704     }
27705     else {
27706         WOLFSSL_MSG("No data to read from bio");
27707         return NULL;
27708     }
27709 
27710 #ifdef WOLFSSL_SMALL_STACK
27711     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
27712                                    DYNAMIC_TYPE_TMP_BUFFER);
27713     if (info == NULL) {
27714         WOLFSSL_MSG("Error getting memory for EncryptedInfo structure");
27715         XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
27716         return NULL;
27717     }
27718 #endif
27719 
27720     XMEMSET(info, 0, sizeof(EncryptedInfo));
27721     info->passwd_cb       = localCb;
27722     info->passwd_userdata = pass;
27723     ret = PemToDer((const unsigned char*)mem, memSz, PRIVATEKEY_TYPE, &der,
27724         NULL, info, &eccFlag);
27725 
27726     if (ret < 0) {
27727         WOLFSSL_MSG("Bad Pem To Der");
27728     }
27729     else {
27730         int type;
27731         const unsigned char* ptr = der->buffer;
27732 
27733         /* write left over data back to bio */
27734         if ((memSz - (int)info->consumed) > 0 &&
27735                 bio->type != WOLFSSL_BIO_FILE) {
27736             if (wolfSSL_BIO_write(bio, mem + (int)info->consumed,
27737                                    memSz - (int)info->consumed) <= 0) {
27738                 WOLFSSL_MSG("Unable to advance bio read pointer");
27739             }
27740         }
27741 
27742         if (eccFlag) {
27743             type = EVP_PKEY_EC;
27744         }
27745         else {
27746             type = EVP_PKEY_RSA;
27747         }
27748 
27749         /* handle case where reuse is attempted */
27750         if (key != NULL && *key != NULL) {
27751             pkey = *key;
27752         }
27753 
27754         wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length);
27755         if (pkey == NULL) {
27756             WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
27757         }
27758     }
27759 
27760 #ifdef WOLFSSL_SMALL_STACK
27761     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27762 #endif
27763 
27764     XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
27765     FreeDer(&der);
27766 
27767     if (key != NULL) {
27768         *key = pkey;
27769     }
27770 
27771     return pkey;
27772 }
27773 
27774 
27775 #ifndef NO_RSA
27776 /* Uses the same format of input as wolfSSL_PEM_read_bio_PrivateKey but expects
27777  * the results to be an RSA key.
27778  *
27779  * bio  structure to read RSA private key from
27780  * rsa  if not null is then set to the result
27781  * cb   password callback for reading PEM
27782  * pass password string
27783  *
27784  * returns a pointer to a new WOLFSSL_RSA structure on success and NULL on fail
27785  */
27786 WOLFSSL_RSA* wolfSSL_PEM_read_bio_RSAPrivateKey(WOLFSSL_BIO* bio,
27787         WOLFSSL_RSA** rsa, pem_password_cb* cb, void* pass)
27788 {
27789     WOLFSSL_EVP_PKEY* pkey;
27790     WOLFSSL_RSA* local;
27791 
27792     pkey = wolfSSL_PEM_read_bio_PrivateKey(bio, NULL, cb, pass);
27793     if (pkey == NULL) {
27794         return NULL;
27795     }
27796 
27797     /* Since the WOLFSSL_RSA structure is being taken from WOLFSSL_EVP_PEKY the
27798      * flag indicating that the WOLFSSL_RSA structure is owned should be FALSE
27799      * to avoid having it free'd */
27800     pkey->ownRsa = 0;
27801     local = pkey->rsa;
27802     if (rsa != NULL) {
27803         *rsa = local;
27804     }
27805 
27806     wolfSSL_EVP_PKEY_free(pkey);
27807     return local;
27808 }
27809 #endif /* !NO_RSA */
27810 
27811 
27812 /* return of pkey->type which will be EVP_PKEY_RSA for example.
27813  *
27814  * type  type of EVP_PKEY
27815  *
27816  * returns type or if type is not found then NID_undef
27817  */
27818 int wolfSSL_EVP_PKEY_type(int type)
27819 {
27820     WOLFSSL_MSG("wolfSSL_EVP_PKEY_type");
27821 
27822     switch (type) {
27823     #ifdef OPENSSL_EXTRA
27824         case EVP_PKEY_RSA:
27825             return EVP_PKEY_RSA;
27826         case EVP_PKEY_DSA:
27827             return EVP_PKEY_DSA;
27828         case EVP_PKEY_EC:
27829             return EVP_PKEY_EC;
27830     #endif
27831         default:
27832             return NID_undef;
27833     }
27834 }
27835 
27836 
27837 int wolfSSL_EVP_PKEY_base_id(const EVP_PKEY *pkey)
27838 {
27839     return EVP_PKEY_type(pkey->type);
27840 }
27841 
27842 
27843 #if !defined(NO_FILESYSTEM)
27844 WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x,
27845                                           pem_password_cb *cb, void *u)
27846 {
27847     (void)fp;
27848     (void)x;
27849     (void)cb;
27850     (void)u;
27851 
27852     WOLFSSL_MSG("wolfSSL_PEM_read_PUBKEY not implemented");
27853 
27854     return NULL;
27855 }
27856 #endif /* NO_FILESYSTEM */
27857 
27858 #ifndef NO_RSA
27859 
27860 #if !defined(NO_FILESYSTEM)
27861 #ifndef NO_WOLFSSL_STUB
27862 WOLFSSL_RSA *wolfSSL_PEM_read_RSAPublicKey(FILE *fp, WOLFSSL_RSA **x,
27863                                            pem_password_cb *cb, void *u)
27864 {
27865     (void)fp;
27866     (void)x;
27867     (void)cb;
27868     (void)u;
27869     WOLFSSL_STUB("PEM_read_RSAPublicKey");
27870     WOLFSSL_MSG("wolfSSL_PEM_read_RSAPublicKey not implemented");
27871 
27872     return NULL;
27873 }
27874 #endif
27875 /* return code compliant with OpenSSL :
27876  *   1 if success, 0 if error
27877  */
27878 #ifndef NO_WOLFSSL_STUB
27879 int wolfSSL_PEM_write_RSAPublicKey(FILE *fp, WOLFSSL_RSA *x)
27880 {
27881     (void)fp;
27882     (void)x;
27883     WOLFSSL_STUB("PEM_write_RSAPublicKey");
27884     WOLFSSL_MSG("wolfSSL_PEM_write_RSAPublicKey not implemented");
27885 
27886     return WOLFSSL_FAILURE;
27887 }
27888 #endif
27889 
27890 /* return code compliant with OpenSSL :
27891  *   1 if success, 0 if error
27892  */
27893 #ifndef NO_WOLFSSL_STUB
27894 int wolfSSL_PEM_write_RSA_PUBKEY(FILE *fp, WOLFSSL_RSA *x)
27895 {
27896     (void)fp;
27897     (void)x;
27898     WOLFSSL_STUB("PEM_write_RSA_PUBKEY");
27899     WOLFSSL_MSG("wolfSSL_PEM_write_RSA_PUBKEY not implemented");
27900 
27901     return WOLFSSL_FAILURE;
27902 }
27903 #endif
27904 
27905 #endif /* NO_FILESYSTEM */
27906 
27907 WOLFSSL_RSA *wolfSSL_d2i_RSAPublicKey(WOLFSSL_RSA **r, const unsigned char **pp, long len)
27908 {
27909     WOLFSSL_RSA *rsa = NULL;
27910 
27911     WOLFSSL_ENTER("d2i_RSAPublicKey");
27912 
27913     if(pp == NULL){
27914         WOLFSSL_MSG("Bad argument");
27915         return NULL;
27916     }
27917     if((rsa = wolfSSL_RSA_new()) == NULL){
27918         WOLFSSL_MSG("RSA_new failed");
27919         return NULL;
27920     }
27921 
27922     if(wolfSSL_RSA_LoadDer_ex(rsa, *pp, (int)len, WOLFSSL_RSA_LOAD_PUBLIC)
27923                                                      != WOLFSSL_SUCCESS){
27924         WOLFSSL_MSG("RSA_LoadDer failed");
27925         wolfSSL_RSA_free(rsa);
27926         rsa = NULL;
27927         return NULL;
27928     }
27929     if(r != NULL)
27930         *r = rsa;
27931     return rsa;
27932 }
27933 
27934 /* Converts an rsa private key from der format to an rsa structure.
27935 Returns pointer to the rsa structure on succcess and NULL if error. */
27936 WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA **r, 
27937                                        const unsigned char **derBuf, long derSz)
27938 {
27939     WOLFSSL_RSA *rsa = NULL;
27940 
27941     WOLFSSL_ENTER("wolfSSL_d2i_RSAPrivateKey");
27942 
27943     /* check for bad functions arguments */
27944     if (derBuf == NULL) {
27945         WOLFSSL_MSG("Bad argument");
27946         return NULL;
27947     }
27948     if ((rsa = wolfSSL_RSA_new()) == NULL) {
27949         WOLFSSL_MSG("RSA_new failed");
27950         return NULL;
27951     }
27952 
27953     if (wolfSSL_RSA_LoadDer_ex(rsa, *derBuf, (int)derSz, 
27954                                  WOLFSSL_RSA_LOAD_PRIVATE) != WOLFSSL_SUCCESS) {
27955         WOLFSSL_MSG("RSA_LoadDer failed");
27956         wolfSSL_RSA_free(rsa);
27957         rsa = NULL;
27958         return NULL;
27959     }
27960     if(r != NULL)
27961         *r = rsa;
27962 
27963     return rsa;
27964 }
27965 
27966 #if !defined(HAVE_FAST_RSA)
27967 #if defined(WOLFSSL_KEY_GEN)
27968 
27969 /* Converts an internal rsa structure to der format.
27970 Returns size of der on success and WOLFSSL_FAILURE if error */
27971 int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp)
27972 {
27973     byte* der = NULL;
27974     int derMax;
27975     int ret;
27976     int i;
27977 
27978     WOLFSSL_ENTER("wolfSSL_i2d_RSAPrivateKey");
27979 
27980     /* check for bad functions arguments */
27981     if ((rsa == NULL) || (pp == NULL)) {
27982         WOLFSSL_MSG("Bad Function Arguments");
27983         return BAD_FUNC_ARG;
27984     }
27985 
27986     if (rsa->inSet == 0) {
27987         if ((ret = SetRsaInternal(rsa)) != WOLFSSL_SUCCESS) {
27988             WOLFSSL_MSG("SetRsaInternal() Failed");
27989             return ret;
27990         }
27991     }
27992 
27993     /* 5 > size of n, d, p, q, d%(p-1), d(q-1), 1/q%p, e + ASN.1 additional
27994      *  informations
27995      */
27996     derMax = 5 * wolfSSL_RSA_size(rsa) + AES_BLOCK_SIZE;
27997 
27998     der = (byte*)XMALLOC(derMax, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27999     if (der == NULL) {
28000         WOLFSSL_MSG("Malloc failed");
28001         return WOLFSSL_FAILURE;
28002     }
28003 
28004     /* RSA key to DER */
28005     if ((ret = wc_RsaKeyToDer((RsaKey *)rsa->internal, der, derMax)) < 0) {
28006         WOLFSSL_MSG("wc_RsaKeyToDer() failed");
28007         XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28008         der = NULL;
28009         return ret;
28010     }
28011 
28012     /* ret is the size of the der buffer */
28013     for (i = 0; i < ret; i++) {
28014         *(*pp + i) = *(der + i);
28015     }
28016     *pp += ret;
28017 
28018     XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28019     return ret; /* returns size of der if successful */
28020 }
28021 #endif /* WOLFSSL_KEY_GEN */
28022 
28023 
28024 int wolfSSL_i2d_RSAPublicKey(WOLFSSL_RSA *rsa, const unsigned char **pp)
28025 {
28026     byte *der;
28027     int derLen;
28028     int ret;
28029 
28030     WOLFSSL_ENTER("i2d_RSAPublicKey");
28031     if ((rsa == NULL) || (pp == NULL))
28032         return WOLFSSL_FATAL_ERROR;
28033     if ((ret = SetRsaInternal(rsa)) != WOLFSSL_SUCCESS) {
28034         WOLFSSL_MSG("SetRsaInternal Failed");
28035         return ret;
28036     }
28037     if ((derLen = RsaPublicKeyDerSize((RsaKey *)rsa->internal, 1)) < 0)
28038         return WOLFSSL_FATAL_ERROR;
28039     der = (byte*)XMALLOC(derLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28040     if (der == NULL) {
28041         return WOLFSSL_FATAL_ERROR;
28042     }
28043     if ((ret = wc_RsaKeyToPublicDer((RsaKey *)rsa->internal, der, derLen)) < 0){
28044         WOLFSSL_MSG("RsaKeyToPublicDer failed");
28045         XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28046         return ret;
28047     }
28048 
28049     *pp = der;
28050     return ret;
28051 }
28052 #endif /* #if !defined(HAVE_FAST_RSA) */
28053 
28054 #endif /* !NO_RSA */
28055 #endif /* OPENSSL_EXTRA */
28056 
28057 #if !defined(NO_RSA) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
28058 /* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */
28059 int wolfSSL_RSA_LoadDer(WOLFSSL_RSA* rsa, const unsigned char* derBuf, int derSz)
28060 {
28061   return wolfSSL_RSA_LoadDer_ex(rsa, derBuf, derSz, WOLFSSL_RSA_LOAD_PRIVATE);
28062 }
28063 
28064 
28065 int wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA* rsa, const unsigned char* derBuf,
28066                                                      int derSz, int opt)
28067 {
28068 
28069     word32 idx = 0;
28070     int    ret;
28071 
28072     WOLFSSL_ENTER("wolfSSL_RSA_LoadDer");
28073 
28074     if (rsa == NULL || rsa->internal == NULL || derBuf == NULL || derSz <= 0) {
28075         WOLFSSL_MSG("Bad function arguments");
28076         return WOLFSSL_FATAL_ERROR;
28077     }
28078 
28079     if (opt == WOLFSSL_RSA_LOAD_PRIVATE) {
28080         ret = wc_RsaPrivateKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal, derSz);
28081     }
28082     else {
28083         ret = wc_RsaPublicKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal, derSz);
28084     }
28085 
28086     if (ret < 0) {
28087         if (opt == WOLFSSL_RSA_LOAD_PRIVATE) {
28088              WOLFSSL_MSG("RsaPrivateKeyDecode failed");
28089         }
28090         else {
28091              WOLFSSL_MSG("RsaPublicKeyDecode failed");
28092         }
28093         return SSL_FATAL_ERROR;
28094     }
28095 
28096     if (SetRsaExternal(rsa) != WOLFSSL_SUCCESS) {
28097         WOLFSSL_MSG("SetRsaExternal failed");
28098         return WOLFSSL_FATAL_ERROR;
28099     }
28100 
28101     rsa->inSet = 1;
28102 
28103     return WOLFSSL_SUCCESS;
28104 }
28105 #endif /* NO_RSA */
28106 
28107 #ifdef OPENSSL_EXTRA
28108 #ifndef NO_DSA
28109 /* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */
28110 int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* derBuf, int derSz)
28111 {
28112     word32 idx = 0;
28113     int    ret;
28114 
28115     WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
28116 
28117     if (dsa == NULL || dsa->internal == NULL || derBuf == NULL || derSz <= 0) {
28118         WOLFSSL_MSG("Bad function arguments");
28119         return WOLFSSL_FATAL_ERROR;
28120     }
28121 
28122     ret = DsaPrivateKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal, derSz);
28123     if (ret < 0) {
28124         WOLFSSL_MSG("DsaPrivateKeyDecode failed");
28125         return WOLFSSL_FATAL_ERROR;
28126     }
28127 
28128     if (SetDsaExternal(dsa) != WOLFSSL_SUCCESS) {
28129         WOLFSSL_MSG("SetDsaExternal failed");
28130         return WOLFSSL_FATAL_ERROR;
28131     }
28132 
28133     dsa->inSet = 1;
28134 
28135     return WOLFSSL_SUCCESS;
28136 }
28137 #endif /* NO_DSA */
28138 
28139 #ifdef HAVE_ECC
28140 /* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */
28141 int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key,
28142                            const unsigned char* derBuf,  int derSz)
28143 {
28144     word32 idx = 0;
28145     int    ret;
28146 
28147     WOLFSSL_ENTER("wolfSSL_EC_KEY_LoadDer");
28148 
28149     if (key == NULL || key->internal == NULL || derBuf == NULL || derSz <= 0) {
28150         WOLFSSL_MSG("Bad function arguments");
28151         return WOLFSSL_FATAL_ERROR;
28152     }
28153 
28154     ret = wc_EccPrivateKeyDecode(derBuf, &idx, (ecc_key*)key->internal, derSz);
28155     if (ret < 0) {
28156         WOLFSSL_MSG("wc_EccPrivateKeyDecode failed");
28157         return WOLFSSL_FATAL_ERROR;
28158     }
28159 
28160     if (SetECKeyExternal(key) != WOLFSSL_SUCCESS) {
28161         WOLFSSL_MSG("SetECKeyExternal failed");
28162         return WOLFSSL_FATAL_ERROR;
28163     }
28164 
28165     key->inSet = 1;
28166 
28167     return WOLFSSL_SUCCESS;
28168 }
28169 #endif /* HAVE_ECC */
28170 
28171 
28172 #endif /* OPENSSL_EXTRA */
28173 
28174 
28175 #ifdef WOLFSSL_ALT_CERT_CHAINS
28176 int wolfSSL_is_peer_alt_cert_chain(const WOLFSSL* ssl)
28177 {
28178     int isUsing = 0;
28179     if (ssl)
28180         isUsing = ssl->options.usingAltCertChain;
28181     return isUsing;
28182 }
28183 #endif /* WOLFSSL_ALT_CERT_CHAINS */
28184 
28185 
28186 #ifdef SESSION_CERTS
28187 
28188 #ifdef WOLFSSL_ALT_CERT_CHAINS
28189 /* Get peer's alternate certificate chain */
28190 WOLFSSL_X509_CHAIN* wolfSSL_get_peer_alt_chain(WOLFSSL* ssl)
28191 {
28192     WOLFSSL_ENTER("wolfSSL_get_peer_alt_chain");
28193     if (ssl)
28194         return &ssl->session.altChain;
28195 
28196     return 0;
28197 }
28198 #endif /* WOLFSSL_ALT_CERT_CHAINS */
28199 
28200 
28201 /* Get peer's certificate chain */
28202 WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl)
28203 {
28204     WOLFSSL_ENTER("wolfSSL_get_peer_chain");
28205     if (ssl)
28206         return &ssl->session.chain;
28207 
28208     return 0;
28209 }
28210 
28211 
28212 /* Get peer's certificate chain total count */
28213 int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain)
28214 {
28215     WOLFSSL_ENTER("wolfSSL_get_chain_count");
28216     if (chain)
28217         return chain->count;
28218 
28219     return 0;
28220 }
28221 
28222 
28223 /* Get peer's ASN.1 DER certificate at index (idx) length in bytes */
28224 int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx)
28225 {
28226     WOLFSSL_ENTER("wolfSSL_get_chain_length");
28227     if (chain)
28228         return chain->certs[idx].length;
28229 
28230     return 0;
28231 }
28232 
28233 
28234 /* Get peer's ASN.1 DER certificate at index (idx) */
28235 byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx)
28236 {
28237     WOLFSSL_ENTER("wolfSSL_get_chain_cert");
28238     if (chain)
28239         return chain->certs[idx].buffer;
28240 
28241     return 0;
28242 }
28243 
28244 
28245 /* Get peer's wolfSSL X509 certificate at index (idx) */
28246 WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx)
28247 {
28248     int          ret;
28249     WOLFSSL_X509* x509 = NULL;
28250 #ifdef WOLFSSL_SMALL_STACK
28251     DecodedCert* cert = NULL;
28252 #else
28253     DecodedCert  cert[1];
28254 #endif
28255 
28256     WOLFSSL_ENTER("wolfSSL_get_chain_X509");
28257     if (chain != NULL) {
28258     #ifdef WOLFSSL_SMALL_STACK
28259         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
28260                                                        DYNAMIC_TYPE_DCERT);
28261         if (cert != NULL)
28262     #endif
28263         {
28264             InitDecodedCert(cert, chain->certs[idx].buffer,
28265                                   chain->certs[idx].length, NULL);
28266 
28267             if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) != 0) {
28268                 WOLFSSL_MSG("Failed to parse cert");
28269             }
28270             else {
28271                 x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
28272                                                              DYNAMIC_TYPE_X509);
28273                 if (x509 == NULL) {
28274                     WOLFSSL_MSG("Failed alloc X509");
28275                 }
28276                 else {
28277                     InitX509(x509, 1, NULL);
28278 
28279                     if ((ret = CopyDecodedToX509(x509, cert)) != 0) {
28280                         WOLFSSL_MSG("Failed to copy decoded");
28281                         XFREE(x509, NULL, DYNAMIC_TYPE_X509);
28282                         x509 = NULL;
28283                     }
28284                 }
28285             }
28286 
28287             FreeDecodedCert(cert);
28288         #ifdef WOLFSSL_SMALL_STACK
28289             XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
28290         #endif
28291         }
28292     }
28293     (void)ret;
28294 
28295     return x509;
28296 }
28297 
28298 
28299 /* Get peer's PEM certificate at index (idx), output to buffer if inLen big
28300    enough else return error (-1). If buffer is NULL only calculate
28301    outLen. Output length is in *outLen WOLFSSL_SUCCESS on ok */
28302 int  wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
28303                                unsigned char* buf, int inLen, int* outLen)
28304 {
28305 #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
28306     const char* header = NULL;
28307     const char* footer = NULL;
28308     int headerLen;
28309     int footerLen;
28310     int i;
28311     int err;
28312     word32 szNeeded = 0;
28313 
28314     WOLFSSL_ENTER("wolfSSL_get_chain_cert_pem");
28315     if (!chain || !outLen || idx < 0 || idx >= wolfSSL_get_chain_count(chain))
28316         return BAD_FUNC_ARG;
28317 
28318     err = wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer);
28319     if (err != 0)
28320         return err;
28321 
28322     headerLen = (int)XSTRLEN(header);
28323     footerLen = (int)XSTRLEN(footer);
28324 
28325     /* Null output buffer return size needed in outLen */
28326     if(!buf) {
28327         if(Base64_Encode(chain->certs[idx].buffer, chain->certs[idx].length,
28328                     NULL, &szNeeded) != LENGTH_ONLY_E)
28329             return WOLFSSL_FAILURE;
28330         *outLen = szNeeded + headerLen + footerLen;
28331         return LENGTH_ONLY_E;
28332     }
28333 
28334     /* don't even try if inLen too short */
28335     if (inLen < headerLen + footerLen + chain->certs[idx].length)
28336         return BAD_FUNC_ARG;
28337 
28338     /* header */
28339     if (XMEMCPY(buf, header, headerLen) == NULL)
28340         return WOLFSSL_FATAL_ERROR;
28341 
28342     i = headerLen;
28343 
28344     /* body */
28345     *outLen = inLen;  /* input to Base64_Encode */
28346     if ( (err = Base64_Encode(chain->certs[idx].buffer,
28347                        chain->certs[idx].length, buf + i, (word32*)outLen)) < 0)
28348         return err;
28349     i += *outLen;
28350 
28351     /* footer */
28352     if ( (i + footerLen) > inLen)
28353         return BAD_FUNC_ARG;
28354     if (XMEMCPY(buf + i, footer, footerLen) == NULL)
28355         return WOLFSSL_FATAL_ERROR;
28356     *outLen += headerLen + footerLen;
28357 
28358     return WOLFSSL_SUCCESS;
28359 #else
28360     (void)chain;
28361     (void)idx;
28362     (void)buf;
28363     (void)inLen;
28364     (void)outLen;
28365     return WOLFSSL_FAILURE;
28366 #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
28367 }
28368 
28369 
28370 /* get session ID */
28371 const byte* wolfSSL_get_sessionID(const WOLFSSL_SESSION* session)
28372 {
28373     WOLFSSL_ENTER("wolfSSL_get_sessionID");
28374     if (session)
28375         return session->sessionID;
28376 
28377     return NULL;
28378 }
28379 
28380 
28381 #endif /* SESSION_CERTS */
28382 
28383 #ifdef HAVE_FUZZER
28384 void wolfSSL_SetFuzzerCb(WOLFSSL* ssl, CallbackFuzzer cbf, void* fCtx)
28385 {
28386     if (ssl) {
28387         ssl->fuzzerCb  = cbf;
28388         ssl->fuzzerCtx = fCtx;
28389     }
28390 }
28391 #endif
28392 
28393 #ifndef NO_CERTS
28394 #ifdef  HAVE_PK_CALLBACKS
28395 
28396 #ifdef HAVE_ECC
28397 void  wolfSSL_CTX_SetEccKeyGenCb(WOLFSSL_CTX* ctx, CallbackEccKeyGen cb)
28398 {
28399     if (ctx)
28400         ctx->EccKeyGenCb = cb;
28401 }
28402 void  wolfSSL_SetEccKeyGenCtx(WOLFSSL* ssl, void *ctx)
28403 {
28404     if (ssl)
28405         ssl->EccKeyGenCtx = ctx;
28406 }
28407 void* wolfSSL_GetEccKeyGenCtx(WOLFSSL* ssl)
28408 {
28409     if (ssl)
28410         return ssl->EccKeyGenCtx;
28411 
28412     return NULL;
28413 }
28414 
28415 void  wolfSSL_CTX_SetEccSignCb(WOLFSSL_CTX* ctx, CallbackEccSign cb)
28416 {
28417     if (ctx)
28418         ctx->EccSignCb = cb;
28419 }
28420 void  wolfSSL_SetEccSignCtx(WOLFSSL* ssl, void *ctx)
28421 {
28422     if (ssl)
28423         ssl->EccSignCtx = ctx;
28424 }
28425 void* wolfSSL_GetEccSignCtx(WOLFSSL* ssl)
28426 {
28427     if (ssl)
28428         return ssl->EccSignCtx;
28429 
28430     return NULL;
28431 }
28432 
28433 void  wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX* ctx, CallbackEccVerify cb)
28434 {
28435     if (ctx)
28436         ctx->EccVerifyCb = cb;
28437 }
28438 void  wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx)
28439 {
28440     if (ssl)
28441         ssl->EccVerifyCtx = ctx;
28442 }
28443 void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl)
28444 {
28445     if (ssl)
28446         return ssl->EccVerifyCtx;
28447 
28448     return NULL;
28449 }
28450 
28451 void wolfSSL_CTX_SetEccSharedSecretCb(WOLFSSL_CTX* ctx, CallbackEccSharedSecret cb)
28452 {
28453     if (ctx)
28454         ctx->EccSharedSecretCb = cb;
28455 }
28456 void  wolfSSL_SetEccSharedSecretCtx(WOLFSSL* ssl, void *ctx)
28457 {
28458     if (ssl)
28459         ssl->EccSharedSecretCtx = ctx;
28460 }
28461 void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl)
28462 {
28463     if (ssl)
28464         return ssl->EccSharedSecretCtx;
28465 
28466     return NULL;
28467 }
28468 #endif /* HAVE_ECC */
28469 
28470 #ifdef HAVE_ED25519
28471 void  wolfSSL_CTX_SetEd25519SignCb(WOLFSSL_CTX* ctx, CallbackEd25519Sign cb)
28472 {
28473     if (ctx)
28474         ctx->Ed25519SignCb = cb;
28475 }
28476 void  wolfSSL_SetEd25519SignCtx(WOLFSSL* ssl, void *ctx)
28477 {
28478     if (ssl)
28479         ssl->Ed25519SignCtx = ctx;
28480 }
28481 void* wolfSSL_GetEd25519SignCtx(WOLFSSL* ssl)
28482 {
28483     if (ssl)
28484         return ssl->Ed25519SignCtx;
28485 
28486     return NULL;
28487 }
28488 
28489 void  wolfSSL_CTX_SetEd25519VerifyCb(WOLFSSL_CTX* ctx, CallbackEd25519Verify cb)
28490 {
28491     if (ctx)
28492         ctx->Ed25519VerifyCb = cb;
28493 }
28494 void  wolfSSL_SetEd25519VerifyCtx(WOLFSSL* ssl, void *ctx)
28495 {
28496     if (ssl)
28497         ssl->Ed25519VerifyCtx = ctx;
28498 }
28499 void* wolfSSL_GetEd25519VerifyCtx(WOLFSSL* ssl)
28500 {
28501     if (ssl)
28502         return ssl->Ed25519VerifyCtx;
28503 
28504     return NULL;
28505 }
28506 #endif /* HAVE_ED25519 */
28507 
28508 #ifdef HAVE_CURVE25519
28509 void wolfSSL_CTX_SetX25519KeyGenCb(WOLFSSL_CTX* ctx,
28510         CallbackX25519KeyGen cb)
28511 {
28512     if (ctx)
28513         ctx->X25519KeyGenCb = cb;
28514 }
28515 void  wolfSSL_SetX25519KeyGenCtx(WOLFSSL* ssl, void *ctx)
28516 {
28517     if (ssl)
28518         ssl->X25519KeyGenCtx = ctx;
28519 }
28520 void* wolfSSL_GetX25519KeyGenCtx(WOLFSSL* ssl)
28521 {
28522     if (ssl)
28523         return ssl->X25519KeyGenCtx;
28524 
28525     return NULL;
28526 }
28527 
28528 void wolfSSL_CTX_SetX25519SharedSecretCb(WOLFSSL_CTX* ctx,
28529         CallbackX25519SharedSecret cb)
28530 {
28531     if (ctx)
28532         ctx->X25519SharedSecretCb = cb;
28533 }
28534 void  wolfSSL_SetX25519SharedSecretCtx(WOLFSSL* ssl, void *ctx)
28535 {
28536     if (ssl)
28537         ssl->X25519SharedSecretCtx = ctx;
28538 }
28539 void* wolfSSL_GetX25519SharedSecretCtx(WOLFSSL* ssl)
28540 {
28541     if (ssl)
28542         return ssl->X25519SharedSecretCtx;
28543 
28544     return NULL;
28545 }
28546 #endif /* HAVE_CURVE25519 */
28547 
28548 #ifndef NO_RSA
28549 void  wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX* ctx, CallbackRsaSign cb)
28550 {
28551     if (ctx)
28552         ctx->RsaSignCb = cb;
28553 }
28554 void  wolfSSL_CTX_SetRsaSignCheckCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
28555 {
28556     if (ctx)
28557         ctx->RsaSignCheckCb = cb;
28558 }
28559 void  wolfSSL_SetRsaSignCtx(WOLFSSL* ssl, void *ctx)
28560 {
28561     if (ssl)
28562         ssl->RsaSignCtx = ctx;
28563 }
28564 void* wolfSSL_GetRsaSignCtx(WOLFSSL* ssl)
28565 {
28566     if (ssl)
28567         return ssl->RsaSignCtx;
28568 
28569     return NULL;
28570 }
28571 
28572 
28573 void  wolfSSL_CTX_SetRsaVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
28574 {
28575     if (ctx)
28576         ctx->RsaVerifyCb = cb;
28577 }
28578 void  wolfSSL_SetRsaVerifyCtx(WOLFSSL* ssl, void *ctx)
28579 {
28580     if (ssl)
28581         ssl->RsaVerifyCtx = ctx;
28582 }
28583 void* wolfSSL_GetRsaVerifyCtx(WOLFSSL* ssl)
28584 {
28585     if (ssl)
28586         return ssl->RsaVerifyCtx;
28587 
28588     return NULL;
28589 }
28590 
28591 #ifdef WC_RSA_PSS
28592 void  wolfSSL_CTX_SetRsaPssSignCb(WOLFSSL_CTX* ctx, CallbackRsaPssSign cb)
28593 {
28594     if (ctx)
28595         ctx->RsaPssSignCb = cb;
28596 }
28597 void  wolfSSL_CTX_SetRsaPssSignCheckCb(WOLFSSL_CTX* ctx, CallbackRsaPssVerify cb)
28598 {
28599     if (ctx)
28600         ctx->RsaPssSignCheckCb = cb;
28601 }
28602 void  wolfSSL_SetRsaPssSignCtx(WOLFSSL* ssl, void *ctx)
28603 {
28604     if (ssl)
28605         ssl->RsaPssSignCtx = ctx;
28606 }
28607 void* wolfSSL_GetRsaPssSignCtx(WOLFSSL* ssl)
28608 {
28609     if (ssl)
28610         return ssl->RsaPssSignCtx;
28611 
28612     return NULL;
28613 }
28614 
28615 void  wolfSSL_CTX_SetRsaPssVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaPssVerify cb)
28616 {
28617     if (ctx)
28618         ctx->RsaPssVerifyCb = cb;
28619 }
28620 void  wolfSSL_SetRsaPssVerifyCtx(WOLFSSL* ssl, void *ctx)
28621 {
28622     if (ssl)
28623         ssl->RsaPssVerifyCtx = ctx;
28624 }
28625 void* wolfSSL_GetRsaPssVerifyCtx(WOLFSSL* ssl)
28626 {
28627     if (ssl)
28628         return ssl->RsaPssVerifyCtx;
28629 
28630     return NULL;
28631 }
28632 #endif /* WC_RSA_PSS */
28633 
28634 void  wolfSSL_CTX_SetRsaEncCb(WOLFSSL_CTX* ctx, CallbackRsaEnc cb)
28635 {
28636     if (ctx)
28637         ctx->RsaEncCb = cb;
28638 }
28639 void  wolfSSL_SetRsaEncCtx(WOLFSSL* ssl, void *ctx)
28640 {
28641     if (ssl)
28642         ssl->RsaEncCtx = ctx;
28643 }
28644 void* wolfSSL_GetRsaEncCtx(WOLFSSL* ssl)
28645 {
28646     if (ssl)
28647         return ssl->RsaEncCtx;
28648 
28649     return NULL;
28650 }
28651 
28652 void  wolfSSL_CTX_SetRsaDecCb(WOLFSSL_CTX* ctx, CallbackRsaDec cb)
28653 {
28654     if (ctx)
28655         ctx->RsaDecCb = cb;
28656 }
28657 void  wolfSSL_SetRsaDecCtx(WOLFSSL* ssl, void *ctx)
28658 {
28659     if (ssl)
28660         ssl->RsaDecCtx = ctx;
28661 }
28662 void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
28663 {
28664     if (ssl)
28665         return ssl->RsaDecCtx;
28666 
28667     return NULL;
28668 }
28669 #endif /* NO_RSA */
28670 
28671 #endif /* HAVE_PK_CALLBACKS */
28672 #endif /* NO_CERTS */
28673 
28674 #if defined(HAVE_PK_CALLBACKS) && !defined(NO_DH)
28675 void wolfSSL_CTX_SetDhAgreeCb(WOLFSSL_CTX* ctx, CallbackDhAgree cb)
28676 {
28677     if (ctx)
28678         ctx->DhAgreeCb = cb;
28679 }
28680 void wolfSSL_SetDhAgreeCtx(WOLFSSL* ssl, void *ctx)
28681 {
28682     if (ssl)
28683         ssl->DhAgreeCtx = ctx;
28684 }
28685 void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
28686 {
28687     if (ssl)
28688         return ssl->DhAgreeCtx;
28689 
28690     return NULL;
28691 }
28692 #endif /* HAVE_PK_CALLBACKS && !NO_DH */
28693 
28694 
28695 #ifdef WOLFSSL_HAVE_WOLFSCEP
28696     /* Used by autoconf to see if wolfSCEP is available */
28697     void wolfSSL_wolfSCEP(void) {}
28698 #endif
28699 
28700 
28701 #ifdef WOLFSSL_HAVE_CERT_SERVICE
28702     /* Used by autoconf to see if cert service is available */
28703     void wolfSSL_cert_service(void) {}
28704 #endif
28705 
28706 
28707 #ifdef OPENSSL_EXTRA /*Lighttp compatibility*/
28708 
28709     #ifndef NO_CERTS
28710     void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name){
28711         WOLFSSL_ENTER("wolfSSL_X509_NAME_free");
28712         FreeX509Name(name, NULL);
28713         XFREE(name, NULL, DYNAMIC_TYPE_X509);
28714     }
28715 
28716 
28717     /* Malloc's a new WOLFSSL_X509_NAME structure
28718      *
28719      * returns NULL on failure, otherwise returns a new structure.
28720      */
28721     WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new()
28722     {
28723         WOLFSSL_X509_NAME* name;
28724 
28725         WOLFSSL_ENTER("wolfSSL_X509_NAME_new");
28726 
28727         name = (WOLFSSL_X509_NAME*)XMALLOC(sizeof(WOLFSSL_X509_NAME), NULL,
28728                 DYNAMIC_TYPE_X509);
28729         if (name != NULL) {
28730             InitX509Name(name, 1);
28731         }
28732         return name;
28733     }
28734 
28735 
28736 #if defined(WOLFSSL_CERT_GEN) && !defined(NO_RSA)
28737 /* needed SetName function from asn.c is wrapped by NO_RSA */
28738     /* helper function for CopyX509NameToCertName()
28739      *
28740      * returns WOLFSSL_SUCCESS on success
28741      */
28742     static int CopyX509NameEntry(char* out, int mx, char* in, int inLen)
28743     {
28744         if (inLen > mx) {
28745             WOLFSSL_MSG("Name too long");
28746             XMEMCPY(out, in, mx);
28747         }
28748         else {
28749             XMEMCPY(out, in, inLen);
28750             out[inLen] = '\0';
28751         }
28752 
28753         /* make sure is null terminated */
28754         out[mx-1] = '\0';
28755 
28756         return WOLFSSL_SUCCESS;
28757     }
28758 
28759 
28760     /* Helper function to copy cert name from a WOLFSSL_X509_NAME structure to
28761      * a CertName structure.
28762      *
28763      * returns WOLFSSL_SUCCESS on success and a negative error value on failure
28764      */
28765     static int CopyX509NameToCertName(WOLFSSL_X509_NAME* n, CertName* cName)
28766     {
28767         DecodedName* dn = NULL;
28768 
28769         if (n == NULL || cName == NULL) {
28770             return BAD_FUNC_ARG;
28771         }
28772 
28773         dn = &(n->fullName);
28774 
28775         /* initialize cert name */
28776         cName->country[0] = '\0';
28777         cName->countryEnc = CTC_PRINTABLE;
28778         cName->state[0] = '\0';
28779         cName->stateEnc = CTC_UTF8;
28780         cName->locality[0] = '\0';
28781         cName->localityEnc = CTC_UTF8;
28782         cName->sur[0] = '\0';
28783         cName->surEnc = CTC_UTF8;
28784         cName->org[0] = '\0';
28785         cName->orgEnc = CTC_UTF8;
28786         cName->unit[0] = '\0';
28787         cName->unitEnc = CTC_UTF8;
28788         cName->commonName[0] = '\0';
28789         cName->commonNameEnc = CTC_UTF8;
28790         cName->email[0] = '\0';
28791 
28792 
28793         /* ASN_COUNTRY_NAME */
28794         WOLFSSL_MSG("Copy Country Name");
28795         if (CopyX509NameEntry(cName->country, CTC_NAME_SIZE, dn->fullName + dn->cIdx,
28796                     dn->cLen) != SSL_SUCCESS) {
28797             return BUFFER_E;
28798         }
28799 
28800         /* ASN_ORGUNIT_NAME */
28801         WOLFSSL_MSG("Copy Org Unit Name");
28802         if (CopyX509NameEntry(cName->unit, CTC_NAME_SIZE, dn->fullName + dn->ouIdx,
28803                     dn->ouLen) != SSL_SUCCESS) {
28804             return BUFFER_E;
28805         }
28806 
28807         /* ASN_ORG_NAME */
28808         WOLFSSL_MSG("Copy Org Name");
28809         if (CopyX509NameEntry(cName->org, CTC_NAME_SIZE, dn->fullName + dn->oIdx,
28810                     dn->oLen) != SSL_SUCCESS) {
28811             return BUFFER_E;
28812         }
28813 
28814         /* ASN_STATE_NAME */
28815         WOLFSSL_MSG("Copy State Name");
28816         if (CopyX509NameEntry(cName->state, CTC_NAME_SIZE, dn->fullName + dn->stIdx,
28817                     dn->stLen) != SSL_SUCCESS) {
28818             return BUFFER_E;
28819         }
28820 
28821         /* ASN_LOCALITY_NAME */
28822         WOLFSSL_MSG("Copy Locality Name");
28823         if (CopyX509NameEntry(cName->locality, CTC_NAME_SIZE,
28824                     dn->fullName + dn->lIdx, dn->lLen)
28825                     != SSL_SUCCESS) {
28826             return BUFFER_E;
28827         }
28828 
28829         /* ASN_SUR_NAME */
28830         WOLFSSL_MSG("Copy Sur Name");
28831         if (CopyX509NameEntry(cName->sur, CTC_NAME_SIZE, dn->fullName + dn->snIdx,
28832                     dn->snLen) != SSL_SUCCESS) {
28833             return BUFFER_E;
28834         }
28835 
28836         /* ASN_COMMON_NAME */
28837         WOLFSSL_MSG("Copy Common Name");
28838         if (CopyX509NameEntry(cName->commonName, CTC_NAME_SIZE,
28839                     dn->fullName + dn->cnIdx, dn->cnLen)
28840                     != SSL_SUCCESS) {
28841             return BUFFER_E;
28842         }
28843 
28844         WOLFSSL_MSG("Copy Email");
28845         if (CopyX509NameEntry(cName->email, CTC_NAME_SIZE,
28846                     dn->fullName + dn->emailIdx, dn->emailLen)
28847                     != SSL_SUCCESS) {
28848             return BUFFER_E;
28849         }
28850 
28851         return WOLFSSL_SUCCESS;
28852     }
28853 
28854 
28855     /* Converts the x509 name structure into DER format.
28856      *
28857      * out  pointer to either a pre setup buffer or a pointer to null for
28858      *      creating a dynamic buffer. In the case that a pre-existing buffer is
28859      *      used out will be incremented the size of the DER buffer on success.
28860      *
28861      * returns the size of the buffer on success, or negative value with failure
28862      */
28863     int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* name, unsigned char** out)
28864     {
28865         CertName cName;
28866         unsigned char buf[256]; /* ASN_MAX_NAME */
28867         int sz;
28868 
28869         if (out == NULL || name == NULL) {
28870             return BAD_FUNC_ARG;
28871         }
28872 
28873         if (CopyX509NameToCertName(name, &cName) != SSL_SUCCESS) {
28874             WOLFSSL_MSG("Error converting x509 name to internal CertName");
28875             return SSL_FATAL_ERROR;
28876         }
28877 
28878         sz = SetName(buf, sizeof(buf), &cName);
28879         if (sz < 0) {
28880             return sz;
28881         }
28882 
28883         /* using buffer passed in */
28884         if (*out != NULL) {
28885             XMEMCPY(*out, buf, sz);
28886             *out += sz;
28887         }
28888         else {
28889             *out = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_OPENSSL);
28890             if (*out == NULL) {
28891                 return MEMORY_E;
28892             }
28893             XMEMCPY(*out, buf, sz);
28894         }
28895 
28896         return sz;
28897     }
28898 #endif /* WOLFSSL_CERT_GEN */
28899 
28900 
28901     /* Compares the two X509 names. If the size of x is larger then y then a
28902      * positive value is returned if x is smaller a negative value is returned.
28903      * In the case that the sizes are equal a the value of memcmp between the
28904      * two names is returned.
28905      *
28906      * x First name for comparision
28907      * y Second name to compare with x
28908      */
28909     int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME* x,
28910             const WOLFSSL_X509_NAME* y)
28911     {
28912         WOLFSSL_STUB("wolfSSL_X509_NAME_cmp");
28913 
28914         if (x == NULL || y == NULL) {
28915             WOLFSSL_MSG("Bad argument passed in");
28916             return -2;
28917         }
28918 
28919         if ((x->sz - y->sz) != 0) {
28920             return x->sz - y->sz;
28921         }
28922         else {
28923             return XMEMCMP(x->name, y->name, x->sz); /* y sz is the same */
28924         }
28925     }
28926 
28927 
28928     WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
28929                                                  pem_password_cb *cb, void *u)
28930     {
28931         WOLFSSL_X509* x509 = NULL;
28932 #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
28933         unsigned char* pem = NULL;
28934         int pemSz;
28935         long  i = 0, l;
28936         const char* footer = NULL;
28937 
28938         WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509");
28939 
28940         if (bp == NULL) {
28941             WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", BAD_FUNC_ARG);
28942             return NULL;
28943         }
28944 
28945         if (bp->type == WOLFSSL_BIO_MEMORY) {
28946             l = (long)wolfSSL_BIO_ctrl_pending(bp);
28947             if (l <= 0) {
28948                 WOLFSSL_MSG("No pending data in WOLFSSL_BIO");
28949                 return NULL;
28950             }
28951         }
28952         else if (bp->type == WOLFSSL_BIO_FILE) {
28953 #ifndef NO_FILESYSTEM
28954             /* Read in next certificate from file but no more. */
28955             i = XFTELL(bp->file);
28956             if (i < 0)
28957                 return NULL;
28958             if (XFSEEK(bp->file, 0, SEEK_END) != 0)
28959                 return NULL;
28960             l = XFTELL(bp->file);
28961             if (l < 0)
28962                 return NULL;
28963             if (XFSEEK(bp->file, i, SEEK_SET) != 0)
28964                 return NULL;
28965 
28966             /* check calculated length */
28967             if (l - i < 0)
28968                 return NULL;
28969 
28970             l -= i;
28971 #else
28972             WOLFSSL_MSG("Unable to read file with NO_FILESYSTEM defined");
28973             return NULL;
28974 #endif /* !NO_FILESYSTEM */
28975         }
28976         else
28977             return NULL;
28978 
28979         pem = (unsigned char*)XMALLOC(l, 0, DYNAMIC_TYPE_PEM);
28980         if (pem == NULL)
28981             return NULL;
28982 
28983         i = 0;
28984         if (wc_PemGetHeaderFooter(CERT_TYPE, NULL, &footer) != 0) {
28985             XFREE(pem, 0, DYNAMIC_TYPE_PEM);
28986             return NULL;
28987         }
28988 
28989         /* TODO: Inefficient
28990          * reading in one byte at a time until see "END CERTIFICATE"
28991          */
28992         while ((l = wolfSSL_BIO_read(bp, (char *)&pem[i], 1)) == 1) {
28993             i++;
28994             if (i > 26 && XMEMCMP((char *)&pem[i-26], footer, 25) == 0) {
28995                 if (pem[i-1] == '\r') {
28996                     /* found \r , Windows line ending is \r\n so try to read one
28997                      * more byte for \n, ignoring return value */
28998                     (void)wolfSSL_BIO_read(bp, (char *)&pem[i++], 1);
28999                 }
29000                 break;
29001             }
29002         }
29003     #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
29004         if (l == 0)
29005             WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
29006     #endif
29007         pemSz = (int)i;
29008         x509 = wolfSSL_X509_load_certificate_buffer(pem, pemSz,
29009                                                               WOLFSSL_FILETYPE_PEM);
29010 
29011         if (x != NULL) {
29012             *x = x509;
29013         }
29014 
29015         XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
29016 
29017 #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
29018         (void)bp;
29019         (void)x;
29020         (void)cb;
29021         (void)u;
29022 
29023         return x509;
29024     }
29025 
29026 #if defined(HAVE_CRL) && !defined(NO_FILESYSTEM)
29027     WOLFSSL_API WOLFSSL_X509_CRL* wolfSSL_PEM_read_X509_CRL(XFILE fp, WOLFSSL_X509_CRL **crl,
29028                                                     pem_password_cb *cb, void *u)
29029     {
29030 #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
29031         unsigned char* pem = NULL;
29032         DerBuffer* der = NULL;
29033         int pemSz;
29034         int derSz;
29035         long  i = 0, l;
29036         WOLFSSL_X509_CRL* newcrl;
29037 
29038         WOLFSSL_ENTER("wolfSSL_PEM_read_X509_CRL");
29039 
29040         if (fp == NULL) {
29041             WOLFSSL_LEAVE("wolfSSL_PEM_read_X509_CRL", BAD_FUNC_ARG);
29042             return NULL;
29043         }
29044         /* Read in CRL from file */
29045         i = XFTELL(fp);
29046         if (i < 0) {
29047             WOLFSSL_LEAVE("wolfSSL_PEM_read_X509_CRL", BAD_FUNC_ARG);
29048             return NULL;
29049         }
29050 
29051         if (XFSEEK(fp, 0, SEEK_END) != 0)
29052             return NULL;
29053         l = XFTELL(fp);
29054         if (l < 0)
29055             return NULL;
29056         if (XFSEEK(fp, i, SEEK_SET) != 0)
29057             return NULL;
29058         pemSz = (int)(l - i);
29059         /* check calculated length */
29060         if (pemSz  < 0)
29061             return NULL;
29062         if((pem = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM)) == NULL)
29063             return NULL;
29064 
29065         if((int)XFREAD((char *)pem, 1, pemSz, fp) != pemSz)
29066             goto err_exit;
29067         if((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0)
29068             goto err_exit;
29069         XFREE(pem, 0, DYNAMIC_TYPE_PEM);
29070 
29071         derSz = der->length;
29072         if((newcrl = wolfSSL_d2i_X509_CRL(crl, (const unsigned char *)der->buffer, derSz)) == NULL)
29073             goto err_exit;
29074         FreeDer(&der);
29075 
29076         return newcrl;
29077 
29078     err_exit:
29079         if(pem != NULL)
29080             XFREE(pem, 0, DYNAMIC_TYPE_PEM);
29081         if(der != NULL)
29082             FreeDer(&der);
29083         return NULL;
29084 
29085         (void)cb;
29086         (void)u;
29087     #endif
29088 
29089     }
29090 #endif
29091 
29092     /*
29093      * bp : bio to read X509 from
29094      * x  : x509 to write to
29095      * cb : password call back for reading PEM
29096      * u  : password
29097      * _AUX is for working with a trusted X509 certificate
29098      */
29099     WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX(WOLFSSL_BIO *bp,
29100                                WOLFSSL_X509 **x, pem_password_cb *cb, void *u) {
29101         WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509");
29102 
29103         /* AUX info is; trusted/rejected uses, friendly name, private key id,
29104          * and potentially a stack of "other" info. wolfSSL does not store
29105          * friendly name or private key id yet in WOLFSSL_X509 for human
29106          * readibility and does not support extra trusted/rejected uses for
29107          * root CA. */
29108         return wolfSSL_PEM_read_bio_X509(bp, x, cb, u);
29109     }
29110 
29111     void wolfSSL_X509_NAME_ENTRY_free(WOLFSSL_X509_NAME_ENTRY* ne)
29112     {
29113         if (ne != NULL) {
29114             if (ne->value != NULL && ne->value != &(ne->data)) {
29115                 wolfSSL_ASN1_STRING_free(ne->value);
29116             }
29117             XFREE(ne, NULL, DYNAMIC_TYPE_NAME_ENTRY);
29118         }
29119     }
29120 
29121 
29122     WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_new(void)
29123     {
29124         WOLFSSL_X509_NAME_ENTRY* ne = NULL;
29125 
29126         ne = (WOLFSSL_X509_NAME_ENTRY*)XMALLOC(sizeof(WOLFSSL_X509_NAME_ENTRY),
29127                 NULL, DYNAMIC_TYPE_NAME_ENTRY);
29128         if (ne != NULL) {
29129             XMEMSET(ne, 0, sizeof(WOLFSSL_X509_NAME_ENTRY));
29130             ne->value = &(ne->data);
29131         }
29132 
29133         return ne;
29134     }
29135 
29136 
29137     WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_NID(
29138             WOLFSSL_X509_NAME_ENTRY** out, int nid, int type,
29139             unsigned char* data, int dataSz)
29140     {
29141         WOLFSSL_X509_NAME_ENTRY* ne = NULL;
29142 
29143         WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_NID()");
29144 
29145         ne = wolfSSL_X509_NAME_ENTRY_new();
29146         if (ne == NULL) {
29147             return NULL;
29148         }
29149 
29150         ne->nid = nid;
29151         ne->value = wolfSSL_ASN1_STRING_type_new(type);
29152         wolfSSL_ASN1_STRING_set(ne->value, (const void*)data, dataSz);
29153         ne->set = 1;
29154 
29155         if (out != NULL) {
29156             *out = ne;
29157         }
29158 
29159         return ne;
29160     }
29161 
29162 
29163     /* Copies entry into name. With it being copied freeing entry becomes the
29164      * callers responsibility.
29165      * returns 1 for success and 0 for error */
29166     int wolfSSL_X509_NAME_add_entry(WOLFSSL_X509_NAME* name,
29167             WOLFSSL_X509_NAME_ENTRY* entry, int idx, int set)
29168     {
29169         int i;
29170 
29171         WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry()");
29172 
29173         for (i = 0; i < MAX_NAME_ENTRIES; i++) {
29174             if (name->extra[i].set != 1) { /* not set so overwrited */
29175                 WOLFSSL_X509_NAME_ENTRY* current = &(name->extra[i]);
29176                 WOLFSSL_ASN1_STRING*     str;
29177 
29178                 WOLFSSL_MSG("Found place for name entry");
29179 
29180                 XMEMCPY(current, entry, sizeof(WOLFSSL_X509_NAME_ENTRY));
29181                 str = entry->value;
29182                 XMEMCPY(&(current->data), str, sizeof(WOLFSSL_ASN1_STRING));
29183                 current->value = &(current->data);
29184                 current->data.data = (char*)XMALLOC(str->length,
29185                        name->x509->heap, DYNAMIC_TYPE_OPENSSL);
29186 
29187                 if (current->data.data == NULL) {
29188                     return SSL_FAILURE;
29189                 }
29190                 XMEMCPY(current->data.data, str->data, str->length);
29191 
29192                 /* make sure is null terminated */
29193                 current->data.data[str->length - 1] = '\0';
29194 
29195                 current->set = 1; /* make sure now listed as set */
29196                 break;
29197             }
29198         }
29199 
29200         if (i == MAX_NAME_ENTRIES) {
29201             WOLFSSL_MSG("No spot found for name entry");
29202             return SSL_FAILURE;
29203         }
29204 
29205         (void)idx;
29206         (void)set;
29207         return SSL_SUCCESS;
29208     }
29209     #endif /* ifndef NO_CERTS */
29210 
29211 
29212     /* NID variables are dependent on compatibility header files currently
29213      *
29214      * returns a pointer to a new WOLFSSL_ASN1_OBJECT struct on success and NULL
29215      *         on fail
29216      */
29217     WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_nid2obj(int id)
29218     {
29219         word32 oidSz = 0;
29220         const byte* oid;
29221         word32 type = 0;
29222         WOLFSSL_ASN1_OBJECT* obj;
29223         byte objBuf[MAX_OID_SZ + MAX_LENGTH_SZ + 1]; /* +1 for object tag */
29224         word32 objSz = 0;
29225         const char* sName;
29226 
29227         WOLFSSL_ENTER("wolfSSL_OBJ_nid2obj()");
29228 
29229         /* get OID type */
29230         switch (id) {
29231             /* oidHashType */
29232         #ifdef WOLFSSL_MD2
29233             case NID_md2:
29234                 id = MD2h;
29235                 type = oidHashType;
29236                 sName = "md2";
29237                 break;
29238         #endif
29239         #ifndef NO_MD5
29240             case NID_md5:
29241                 id = MD5h;
29242                 type = oidHashType;
29243                 sName = "md5";
29244                 break;
29245         #endif
29246         #ifndef NO_SHA
29247             case NID_sha1:
29248                 id = SHAh;
29249                 type = oidHashType;
29250                 sName = "sha";
29251                 break;
29252         #endif
29253             case NID_sha224:
29254                 id = SHA224h;
29255                 type = oidHashType;
29256                 sName = "sha224";
29257                 break;
29258         #ifndef NO_SHA256
29259             case NID_sha256:
29260                 id = SHA256h;
29261                 type = oidHashType;
29262                 sName = "sha256";
29263                 break;
29264         #endif
29265         #ifdef WOLFSSL_SHA384
29266             case NID_sha384:
29267                 id = SHA384h;
29268                 type = oidHashType;
29269                 sName = "sha384";
29270                 break;
29271         #endif
29272         #ifdef WOLFSSL_SHA512
29273             case NID_sha512:
29274                 id = SHA512h;
29275                 type = oidHashType;
29276                 sName = "sha512";
29277                 break;
29278         #endif
29279 
29280             /*  oidSigType */
29281         #ifndef NO_DSA
29282             case CTC_SHAwDSA:
29283                 sName = "shaWithDSA";
29284                 type = oidSigType;
29285                 break;
29286 
29287         #endif /* NO_DSA */
29288         #ifndef NO_RSA
29289             case CTC_MD2wRSA:
29290                 sName = "md2WithRSA";
29291                 type = oidSigType;
29292                 break;
29293 
29294         #ifndef NO_MD5
29295             case CTC_MD5wRSA:
29296                 sName = "md5WithRSA";
29297                 type = oidSigType;
29298                 break;
29299         #endif
29300 
29301             case CTC_SHAwRSA:
29302                 sName = "shaWithRSA";
29303                 type = oidSigType;
29304                 break;
29305 
29306         #ifdef WOLFSSL_SHA224
29307             case CTC_SHA224wRSA:
29308                 sName = "sha224WithRSA";
29309                 type = oidSigType;
29310                 break;
29311         #endif
29312 
29313         #ifndef NO_SHA256
29314             case CTC_SHA256wRSA:
29315                 sName = "sha256WithRSA";
29316                 type = oidSigType;
29317                 break;
29318         #endif
29319 
29320         #ifdef WOLFSSL_SHA384
29321             case CTC_SHA384wRSA:
29322                 sName = "sha384WithRSA";
29323                 type = oidSigType;
29324                 break;
29325         #endif
29326 
29327         #ifdef WOLFSSL_SHA512
29328             case CTC_SHA512wRSA:
29329                 sName = "sha512WithRSA";
29330                 type = oidSigType;
29331                 break;
29332         #endif
29333         #endif /* NO_RSA */
29334         #ifdef HAVE_ECC
29335             case CTC_SHAwECDSA:
29336                 sName = "shaWithECDSA";
29337                 type = oidSigType;
29338                 break;
29339 
29340             case CTC_SHA224wECDSA:
29341                 sName = "sha224WithECDSA";
29342                 type = oidSigType;
29343                 break;
29344 
29345             case CTC_SHA256wECDSA:
29346                 sName = "sha256WithECDSA";
29347                 type = oidSigType;
29348                 break;
29349 
29350             case CTC_SHA384wECDSA:
29351                 sName = "sha384WithECDSA";
29352                 type = oidSigType;
29353                 break;
29354 
29355             case CTC_SHA512wECDSA:
29356                 sName = "sha512WithECDSA";
29357                 type = oidSigType;
29358                 break;
29359         #endif /* HAVE_ECC */
29360 
29361             /* oidKeyType */
29362         #ifndef NO_DSA
29363             case DSAk:
29364                 sName = "DSA key";
29365                 type = oidKeyType;
29366                 break;
29367         #endif /* NO_DSA */
29368         #ifndef NO_RSA
29369             case RSAk:
29370                 sName = "RSA key";
29371                 type = oidKeyType;
29372                 break;
29373         #endif /* NO_RSA */
29374         #ifdef HAVE_NTRU
29375             case NTRUk:
29376                 sName = "NTRU key";
29377                 type = oidKeyType;
29378                 break;
29379         #endif /* HAVE_NTRU */
29380         #ifdef HAVE_ECC
29381             case ECDSAk:
29382                 sName = "ECDSA key";
29383                 type = oidKeyType;
29384                 break;
29385         #endif /* HAVE_ECC */
29386 
29387             /* oidBlkType */
29388         #ifdef WOLFSSL_AES_128
29389             case AES128CBCb:
29390                 sName = "AES-128-CBC";
29391                 type = oidBlkType;
29392                 break;
29393         #endif
29394         #ifdef WOLFSSL_AES_192
29395             case AES192CBCb:
29396                 sName = "AES-192-CBC";
29397                 type = oidBlkType;
29398                 break;
29399         #endif
29400 
29401         #ifdef WOLFSSL_AES_256
29402             case AES256CBCb:
29403                 sName = "AES-256-CBC";
29404                 type = oidBlkType;
29405                 break;
29406         #endif
29407 
29408         #ifndef NO_DES3
29409             case NID_des:
29410                 id = DESb;
29411                 sName = "DES-CBC";
29412                 type = oidBlkType;
29413                 break;
29414 
29415             case NID_des3:
29416                 id = DES3b;
29417                 sName = "DES3-CBC";
29418                 type = oidBlkType;
29419                 break;
29420         #endif /* !NO_DES3 */
29421 
29422         #ifdef HAVE_OCSP
29423             case NID_id_pkix_OCSP_basic:
29424                 id = OCSP_BASIC_OID;
29425                 sName = "OCSP_basic";
29426                 type = oidOcspType;
29427                 break;
29428 
29429             case OCSP_NONCE_OID:
29430                 sName = "OCSP_nonce";
29431                 type = oidOcspType;
29432                 break;
29433         #endif /* HAVE_OCSP */
29434 
29435             /* oidCertExtType */
29436             case BASIC_CA_OID:
29437                 sName = "X509 basic ca";
29438                 type = oidCertExtType;
29439                 break;
29440 
29441             case ALT_NAMES_OID:
29442                 sName = "X509 alt names";
29443                 type = oidCertExtType;
29444                 break;
29445 
29446             case CRL_DIST_OID:
29447                 sName = "X509 crl";
29448                 type = oidCertExtType;
29449                 break;
29450 
29451             case AUTH_INFO_OID:
29452                 sName = "X509 auth info";
29453                 type = oidCertExtType;
29454                 break;
29455 
29456             case AUTH_KEY_OID:
29457                 sName = "X509 auth key";
29458                 type = oidCertExtType;
29459                 break;
29460 
29461             case SUBJ_KEY_OID:
29462                 sName = "X509 subject key";
29463                 type = oidCertExtType;
29464                 break;
29465 
29466             case KEY_USAGE_OID:
29467                 sName = "X509 key usage";
29468                 type = oidCertExtType;
29469                 break;
29470 
29471             case INHIBIT_ANY_OID:
29472                 id = INHIBIT_ANY_OID;
29473                 sName = "X509 inhibit any";
29474                 type = oidCertExtType;
29475                 break;
29476 
29477             case NID_ext_key_usage:
29478                 id = KEY_USAGE_OID;
29479                 sName = "X509 ext key usage";
29480                 type = oidCertExtType;
29481                 break;
29482 
29483             case NID_name_constraints:
29484                 id = NAME_CONS_OID;
29485                 sName = "X509 name constraints";
29486                 type = oidCertExtType;
29487                 break;
29488 
29489             case NID_certificate_policies:
29490                 id = CERT_POLICY_OID;
29491                 sName = "X509 certificate policies";
29492                 type = oidCertExtType;
29493                 break;
29494 
29495             /* oidCertAuthInfoType */
29496             case AIA_OCSP_OID:
29497                 sName = "Cert Auth OCSP";
29498                 type = oidCertAuthInfoType;
29499                 break;
29500 
29501             case AIA_CA_ISSUER_OID:
29502                 sName = "Cert Auth CA Issuer";
29503                 type = oidCertAuthInfoType;
29504                 break;
29505 
29506             /* oidCertPolicyType */
29507             case NID_any_policy:
29508                 id = CP_ANY_OID;
29509                 sName = "Cert any policy";
29510                 type = oidCertPolicyType;
29511                 break;
29512 
29513                 /* oidCertAltNameType */
29514             case NID_hw_name_oid:
29515                 id = HW_NAME_OID;
29516                 sName = "Hardware name";
29517                 type = oidCertAltNameType;
29518                 break;
29519 
29520             /* oidCertKeyUseType */
29521             case NID_anyExtendedKeyUsage:
29522                 id = EKU_ANY_OID;
29523                 sName = "Cert any extended key";
29524                 type = oidCertKeyUseType;
29525                 break;
29526 
29527             case EKU_SERVER_AUTH_OID:
29528                 sName = "Cert server auth key";
29529                 type = oidCertKeyUseType;
29530                 break;
29531 
29532             case EKU_CLIENT_AUTH_OID:
29533                 sName = "Cert client auth key";
29534                 type = oidCertKeyUseType;
29535                 break;
29536 
29537             case EKU_OCSP_SIGN_OID:
29538                 sName = "Cert OCSP sign key";
29539                 type = oidCertKeyUseType;
29540                 break;
29541 
29542             /* oidKdfType */
29543             case PBKDF2_OID:
29544                 sName = "PBKDFv2";
29545                 type = oidKdfType;
29546                 break;
29547 
29548                 /* oidPBEType */
29549             case PBE_SHA1_RC4_128:
29550                 sName = "PBE shaWithRC4-128";
29551                 type = oidPBEType;
29552                 break;
29553 
29554             case PBE_SHA1_DES:
29555                 sName = "PBE shaWithDES";
29556                 type = oidPBEType;
29557                 break;
29558 
29559             case PBE_SHA1_DES3:
29560                 sName = "PBE shaWithDES3";
29561                 type = oidPBEType;
29562                 break;
29563 
29564                 /* oidKeyWrapType */
29565         #ifdef WOLFSSL_AES_128
29566             case AES128_WRAP:
29567                 sName = "AES-128 wrap";
29568                 type = oidKeyWrapType;
29569                 break;
29570         #endif
29571 
29572         #ifdef WOLFSSL_AES_192
29573             case AES192_WRAP:
29574                 sName = "AES-192 wrap";
29575                 type = oidKeyWrapType;
29576                 break;
29577         #endif
29578 
29579         #ifdef WOLFSSL_AES_256
29580             case AES256_WRAP:
29581                 sName = "AES-256 wrap";
29582                 type = oidKeyWrapType;
29583                 break;
29584         #endif
29585 
29586                 /* oidCmsKeyAgreeType */
29587         #ifndef NO_SHA
29588             case dhSinglePass_stdDH_sha1kdf_scheme:
29589                 sName = "DH-SHA kdf";
29590                 type = oidCmsKeyAgreeType;
29591                 break;
29592         #endif
29593         #ifdef WOLFSSL_SHA224
29594             case dhSinglePass_stdDH_sha224kdf_scheme:
29595                 sName = "DH-SHA224 kdf";
29596                 type = oidCmsKeyAgreeType;
29597                 break;
29598         #endif
29599         #ifndef NO_SHA256
29600             case dhSinglePass_stdDH_sha256kdf_scheme:
29601                 sName = "DH-SHA256 kdf";
29602                 type = oidCmsKeyAgreeType;
29603                 break;
29604 
29605         #endif
29606         #ifdef WOLFSSL_SHA384
29607             case dhSinglePass_stdDH_sha384kdf_scheme:
29608                 sName = "DH-SHA384 kdf";
29609                 type = oidCmsKeyAgreeType;
29610                 break;
29611         #endif
29612         #ifdef WOLFSSL_SHA512
29613             case dhSinglePass_stdDH_sha512kdf_scheme:
29614                 sName = "DH-SHA512 kdf";
29615                 type = oidCmsKeyAgreeType;
29616                 break;
29617         #endif
29618             default:
29619                 WOLFSSL_MSG("NID not in table");
29620                 return NULL;
29621         }
29622 
29623     #ifdef HAVE_ECC
29624          if (type == 0 && wc_ecc_get_oid(id, &oid, &oidSz) > 0) {
29625              type = oidCurveType;
29626          }
29627     #endif /* HAVE_ECC */
29628 
29629         if (XSTRLEN(sName) > WOLFSSL_MAX_SNAME - 1) {
29630             WOLFSSL_MSG("Attempted short name is too large");
29631             return NULL;
29632         }
29633 
29634         oid = OidFromId(id, type, &oidSz);
29635 
29636         /* set object ID to buffer */
29637         obj = wolfSSL_ASN1_OBJECT_new();
29638         if (obj == NULL) {
29639             WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
29640             return NULL;
29641         }
29642         obj->type    = id;
29643         obj->grp     = type;
29644         obj->dynamic = 1;
29645         XMEMCPY(obj->sName, (char*)sName, XSTRLEN((char*)sName));
29646 
29647         objBuf[0] = ASN_OBJECT_ID; objSz++;
29648         objSz += SetLength(oidSz, objBuf + 1);
29649         XMEMCPY(objBuf + objSz, oid, oidSz);
29650         objSz     += oidSz;
29651         obj->objSz = objSz;
29652 
29653         obj->obj = (byte*)XMALLOC(obj->objSz, NULL, DYNAMIC_TYPE_ASN1);
29654         if (obj->obj == NULL) {
29655             wolfSSL_ASN1_OBJECT_free(obj);
29656             return NULL;
29657         }
29658         XMEMCPY(obj->obj, objBuf, obj->objSz);
29659 
29660         (void)type;
29661 
29662         return obj;
29663     }
29664 
29665 
29666     /* if no_name is one than use numerical form otherwise can be short name.
29667      *
29668      * returns the buffer size on success
29669      */
29670     int wolfSSL_OBJ_obj2txt(char *buf, int bufLen, WOLFSSL_ASN1_OBJECT *a, int no_name)
29671     {
29672         int bufSz;
29673 
29674         WOLFSSL_ENTER("wolfSSL_OBJ_obj2txt()");
29675 
29676         if (buf == NULL || bufLen <= 1 || a == NULL) {
29677             WOLFSSL_MSG("Bad input argument");
29678             return WOLFSSL_FAILURE;
29679         }
29680 
29681         if (no_name == 1) {
29682             int    length;
29683             word32 idx = 0;
29684 
29685             if (a->obj[idx++] != ASN_OBJECT_ID) {
29686                 WOLFSSL_MSG("Bad ASN1 Object");
29687                 return WOLFSSL_FAILURE;
29688             }
29689 
29690             if (GetLength((const byte*)a->obj, &idx, &length,
29691                            a->objSz) < 0 || length < 0) {
29692                 return ASN_PARSE_E;
29693             }
29694 
29695             if (bufLen < MAX_OID_STRING_SZ) {
29696                 bufSz = bufLen - 1;
29697             }
29698             else {
29699                 bufSz = MAX_OID_STRING_SZ;
29700             }
29701 
29702             if ((bufSz = DecodePolicyOID(buf, (word32)bufSz, a->obj + idx,
29703                         (word32)length)) <= 0) {
29704                 WOLFSSL_MSG("Error decoding OID");
29705                 return WOLFSSL_FAILURE;
29706             }
29707 
29708         }
29709         else { /* return short name */
29710             if (XSTRLEN(a->sName) + 1 < (word32)bufLen - 1) {
29711                 bufSz = (int)XSTRLEN(a->sName);
29712             }
29713             else {
29714                 bufSz = bufLen - 1;
29715             }
29716             XMEMCPY(buf, a->sName, bufSz);
29717         }
29718 
29719         buf[bufSz] = '\0';
29720         return bufSz;
29721     }
29722 
29723 #if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
29724     defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
29725     defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
29726     defined(WOLFSSL_HAPROXY)
29727 
29728 #ifndef NO_SHA
29729     /* One shot SHA1 hash of message.
29730      *
29731      * d  message to hash
29732      * n  size of d buffer
29733      * md buffer to hold digest. Should be SHA_DIGEST_SIZE.
29734      *
29735      * Note: if md is null then a static buffer of SHA_DIGEST_SIZE is used.
29736      *       When the static buffer is used this function is not thread safe.
29737      *
29738      * Returns a pointer to the message digest on success and NULL on failure.
29739      */
29740     unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n,
29741             unsigned char *md)
29742     {
29743         static byte dig[WC_SHA_DIGEST_SIZE];
29744         wc_Sha sha;
29745 
29746         WOLFSSL_ENTER("wolfSSL_SHA1");
29747 
29748         if (wc_InitSha_ex(&sha, NULL, 0) != 0) {
29749             WOLFSSL_MSG("SHA1 Init failed");
29750             return NULL;
29751         }
29752 
29753         if (wc_ShaUpdate(&sha, (const byte*)d, (word32)n) != 0) {
29754             WOLFSSL_MSG("SHA1 Update failed");
29755             return NULL;
29756         }
29757 
29758         if (wc_ShaFinal(&sha, dig) != 0) {
29759             WOLFSSL_MSG("SHA1 Final failed");
29760             return NULL;
29761         }
29762 
29763         wc_ShaFree(&sha);
29764 
29765         if (md != NULL) {
29766             XMEMCPY(md, dig, WC_SHA_DIGEST_SIZE);
29767             return md;
29768         }
29769         else {
29770             return (unsigned char*)dig;
29771         }
29772     }
29773 #endif /* ! NO_SHA */
29774 
29775 #ifndef NO_SHA256
29776     /* One shot SHA256 hash of message.
29777      *
29778      * d  message to hash
29779      * n  size of d buffer
29780      * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE.
29781      *
29782      * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
29783      *       When the static buffer is used this function is not thread safe.
29784      *
29785      * Returns a pointer to the message digest on success and NULL on failure.
29786      */
29787     unsigned char *wolfSSL_SHA256(const unsigned char *d, size_t n,
29788             unsigned char *md)
29789     {
29790         static byte dig[WC_SHA256_DIGEST_SIZE];
29791         wc_Sha256 sha;
29792 
29793         WOLFSSL_ENTER("wolfSSL_SHA256");
29794 
29795         if (wc_InitSha256_ex(&sha, NULL, 0) != 0) {
29796             WOLFSSL_MSG("SHA256 Init failed");
29797             return NULL;
29798         }
29799 
29800         if (wc_Sha256Update(&sha, (const byte*)d, (word32)n) != 0) {
29801             WOLFSSL_MSG("SHA256 Update failed");
29802             return NULL;
29803         }
29804 
29805         if (wc_Sha256Final(&sha, dig) != 0) {
29806             WOLFSSL_MSG("SHA256 Final failed");
29807             return NULL;
29808         }
29809 
29810         wc_Sha256Free(&sha);
29811 
29812         if (md != NULL) {
29813             XMEMCPY(md, dig, WC_SHA256_DIGEST_SIZE);
29814             return md;
29815         }
29816         else {
29817             return (unsigned char*)dig;
29818         }
29819     }
29820 #endif /* ! NO_SHA256 */
29821 
29822 #ifdef WOLFSSL_SHA384
29823      /* One shot SHA384 hash of message.
29824       *
29825       * d  message to hash
29826       * n  size of d buffer
29827       * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE.
29828       *
29829       * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
29830       *       When the static buffer is used this function is not thread safe.
29831       *
29832       * Returns a pointer to the message digest on success and NULL on failure.
29833       */
29834      unsigned char *wolfSSL_SHA384(const unsigned char *d, size_t n,
29835              unsigned char *md)
29836      {
29837          static byte dig[WC_SHA384_DIGEST_SIZE];
29838          wc_Sha384 sha;
29839 
29840          WOLFSSL_ENTER("wolfSSL_SHA384");
29841 
29842          if (wc_InitSha384_ex(&sha, NULL, 0) != 0) {
29843              WOLFSSL_MSG("SHA384 Init failed");
29844              return NULL;
29845          }
29846 
29847          if (wc_Sha384Update(&sha, (const byte*)d, (word32)n) != 0) {
29848              WOLFSSL_MSG("SHA384 Update failed");
29849              return NULL;
29850          }
29851 
29852          if (wc_Sha384Final(&sha, dig) != 0) {
29853              WOLFSSL_MSG("SHA384 Final failed");
29854              return NULL;
29855          }
29856 
29857          wc_Sha384Free(&sha);
29858 
29859          if (md != NULL) {
29860              XMEMCPY(md, dig, WC_SHA384_DIGEST_SIZE);
29861              return md;
29862          }
29863          else {
29864              return (unsigned char*)dig;
29865          }
29866      }
29867 #endif /* WOLFSSL_SHA384  */
29868 
29869 
29870 #if defined(WOLFSSL_SHA512)
29871      /* One shot SHA512 hash of message.
29872       *
29873       * d  message to hash
29874       * n  size of d buffer
29875       * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE.
29876       *
29877       * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
29878       *       When the static buffer is used this function is not thread safe.
29879       *
29880       * Returns a pointer to the message digest on success and NULL on failure.
29881       */
29882      unsigned char *wolfSSL_SHA512(const unsigned char *d, size_t n,
29883              unsigned char *md)
29884      {
29885          static byte dig[WC_SHA512_DIGEST_SIZE];
29886          wc_Sha512 sha;
29887 
29888          WOLFSSL_ENTER("wolfSSL_SHA512");
29889 
29890          if (wc_InitSha512_ex(&sha, NULL, 0) != 0) {
29891              WOLFSSL_MSG("SHA512 Init failed");
29892              return NULL;
29893          }
29894 
29895          if (wc_Sha512Update(&sha, (const byte*)d, (word32)n) != 0) {
29896              WOLFSSL_MSG("SHA512 Update failed");
29897              return NULL;
29898          }
29899 
29900          if (wc_Sha512Final(&sha, dig) != 0) {
29901              WOLFSSL_MSG("SHA512 Final failed");
29902              return NULL;
29903          }
29904 
29905          wc_Sha512Free(&sha);
29906 
29907          if (md != NULL) {
29908              XMEMCPY(md, dig, WC_SHA512_DIGEST_SIZE);
29909              return md;
29910          }
29911          else {
29912              return (unsigned char*)dig;
29913          }
29914      }
29915 #endif /* defined(WOLFSSL_SHA512)  */
29916 
29917     char wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x)
29918     {
29919         int ret;
29920 
29921         WOLFSSL_ENTER("wolfSSL_CTX_use_certificate");
29922 
29923         FreeDer(&ctx->certificate); /* Make sure previous is free'd */
29924         ret = AllocDer(&ctx->certificate, x->derCert->length, CERT_TYPE,
29925                        ctx->heap);
29926         if (ret != 0)
29927             return 0;
29928 
29929         XMEMCPY(ctx->certificate->buffer, x->derCert->buffer,
29930                 x->derCert->length);
29931 #ifdef KEEP_OUR_CERT
29932         if (ctx->ourCert != NULL && ctx->ownOurCert) {
29933             FreeX509(ctx->ourCert);
29934             XFREE(ctx->ourCert, ctx->heap, DYNAMIC_TYPE_X509);
29935         }
29936         ctx->ourCert = x;
29937         ctx->ownOurCert = 0;
29938 #endif
29939 
29940         /* Update the available options with public keys. */
29941         switch (x->pubKeyOID) {
29942             case RSAk:
29943                 ctx->haveRSA = 1;
29944                 break;
29945         #ifdef HAVE_ED25519
29946             case ED25519k:
29947         #endif
29948             case ECDSAk:
29949                 ctx->haveECC = 1;
29950             #if defined(HAVE_ECC) || defined(HAVE_ED25519)
29951                 ctx->pkCurveOID = x->pkCurveOID;
29952             #endif
29953                 break;
29954         }
29955 
29956         return WOLFSSL_SUCCESS;
29957     }
29958 
29959     #ifndef NO_WOLFSSL_STUB
29960     int wolfSSL_BIO_read_filename(WOLFSSL_BIO *b, const char *name) {
29961     #ifndef NO_FILESYSTEM
29962         XFILE fp;
29963 
29964         WOLFSSL_ENTER("wolfSSL_BIO_new_file");
29965 
29966         if ((wolfSSL_BIO_get_fp(b, &fp) == WOLFSSL_SUCCESS) && (fp != NULL))
29967         {
29968             XFCLOSE(fp);
29969         }
29970 
29971         fp = XFOPEN(name, "r");
29972         if (fp == NULL)
29973             return WOLFSSL_BAD_FILE;
29974 
29975         if (wolfSSL_BIO_set_fp(b, fp, BIO_CLOSE) != WOLFSSL_SUCCESS) {
29976             XFCLOSE(fp);
29977             return WOLFSSL_BAD_FILE;
29978         }
29979 
29980         /* file is closed when bio is free'd */
29981         return WOLFSSL_SUCCESS;
29982     #else
29983         (void)name;
29984         (void)b;
29985         return WOLFSSL_NOT_IMPLEMENTED;
29986     #endif
29987     }
29988     #endif
29989 
29990 #ifdef HAVE_ECC
29991     const char * wolfSSL_OBJ_nid2sn(int n) {
29992         int i;
29993         WOLFSSL_ENTER("wolfSSL_OBJ_nid2sn");
29994 
29995         /* find based on NID and return name */
29996         for (i = 0; i < ecc_sets[i].size; i++) {
29997             if (n == ecc_sets[i].id) {
29998                 return ecc_sets[i].name;
29999             }
30000         }
30001         return NULL;
30002     }
30003 
30004     int wolfSSL_OBJ_sn2nid(const char *sn) {
30005         int i;
30006         WOLFSSL_ENTER("wolfSSL_OBJ_osn2nid");
30007 
30008         /* Nginx uses this OpenSSL string. */
30009         if (XSTRNCMP(sn, "prime256v1", 10) == 0)
30010             sn = "SECP256R1";
30011         if (XSTRNCMP(sn, "secp384r1", 10) == 0)
30012             sn = "SECP384R1";
30013         /* find based on name and return NID */
30014         for (i = 0; i < ecc_sets[i].size; i++) {
30015             if (XSTRNCMP(sn, ecc_sets[i].name, ECC_MAXNAME) == 0) {
30016                 return ecc_sets[i].id;
30017             }
30018         }
30019         return -1;
30020     }
30021 #endif /* HAVE_ECC */
30022 
30023     /* Gets the NID value that corresponds with the ASN1 object.
30024      *
30025      * o ASN1 object to get NID of
30026      *
30027      * Return NID on success and a negative value on failure
30028      */
30029     int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o) {
30030         word32 oid = 0;
30031         word32 idx = 0;
30032         int id;
30033 
30034         WOLFSSL_ENTER("wolfSSL_OBJ_obj2nid");
30035 
30036         if (o == NULL) {
30037             return -1;
30038         }
30039 
30040         if ((id = GetObjectId(o->obj, &idx, &oid, o->grp, o->objSz)) < 0) {
30041             WOLFSSL_MSG("Issue getting OID of object");
30042             return -1;
30043         }
30044 
30045         /* get OID type */
30046         switch (o->grp) {
30047             /* oidHashType */
30048             case oidHashType:
30049                 switch (oid) {
30050                 #ifdef WOLFSSL_MD2
30051                     case MD2h:
30052                         return NID_md2;
30053                 #endif
30054                 #ifndef NO_MD5
30055                     case MD5h:
30056                         return NID_md5;
30057                 #endif
30058                 #ifndef NO_SHA
30059                     case SHAh:
30060                         return NID_sha1;
30061                 #endif
30062                     case SHA224h:
30063                         return NID_sha224;
30064                 #ifndef NO_SHA256
30065                     case SHA256h:
30066                         return NID_sha256;
30067                 #endif
30068                 #ifdef WOLFSSL_SHA384
30069                     case SHA384h:
30070                         return NID_sha384;
30071                 #endif
30072                 #ifdef WOLFSSL_SHA512
30073                     case SHA512h:
30074                         return NID_sha512;
30075                 #endif
30076                 }
30077                 break;
30078 
30079             /*  oidSigType */
30080             case oidSigType:
30081                 switch (oid) {
30082                 #ifndef NO_DSA
30083                     case CTC_SHAwDSA:
30084                         return CTC_SHAwDSA;
30085                 #endif /* NO_DSA */
30086                 #ifndef NO_RSA
30087                     case CTC_MD2wRSA:
30088                         return CTC_MD2wRSA;
30089                     case CTC_MD5wRSA:
30090                         return CTC_MD5wRSA;
30091                     case CTC_SHAwRSA:
30092                         return CTC_SHAwRSA;
30093                     case CTC_SHA224wRSA:
30094                         return CTC_SHA224wRSA;
30095                     case CTC_SHA256wRSA:
30096                         return CTC_SHA256wRSA;
30097                     case CTC_SHA384wRSA:
30098                         return CTC_SHA384wRSA;
30099                     case CTC_SHA512wRSA:
30100                         return CTC_SHA512wRSA;
30101                 #endif /* NO_RSA */
30102                 #ifdef HAVE_ECC
30103                     case CTC_SHAwECDSA:
30104                         return CTC_SHAwECDSA;
30105                     case CTC_SHA224wECDSA:
30106                         return CTC_SHA224wECDSA;
30107                     case CTC_SHA256wECDSA:
30108                         return CTC_SHA256wECDSA;
30109                     case CTC_SHA384wECDSA:
30110                         return CTC_SHA384wECDSA;
30111                     case CTC_SHA512wECDSA:
30112                         return CTC_SHA512wECDSA;
30113                 #endif /* HAVE_ECC */
30114                 }
30115                 break;
30116 
30117             /* oidKeyType */
30118             case oidKeyType:
30119                 switch (oid) {
30120                 #ifndef NO_DSA
30121                     case DSAk:
30122                         return DSAk;
30123                 #endif /* NO_DSA */
30124                 #ifndef NO_RSA
30125                     case RSAk:
30126                         return RSAk;
30127                 #endif /* NO_RSA */
30128                 #ifdef HAVE_NTRU
30129                     case NTRUk:
30130                         return NTRUk;
30131                 #endif /* HAVE_NTRU */
30132                 #ifdef HAVE_ECC
30133                     case ECDSAk:
30134                         return ECDSAk;
30135                 #endif /* HAVE_ECC */
30136                 }
30137                 break;
30138 
30139             /* oidBlkType */
30140             case oidBlkType:
30141                 switch (oid) {
30142                 #ifdef WOLFSSL_AES_128
30143                     case AES128CBCb:
30144                         return AES128CBCb;
30145                 #endif
30146                 #ifdef WOLFSSL_AES_192
30147                     case AES192CBCb:
30148                         return AES192CBCb;
30149                 #endif
30150                 #ifdef WOLFSSL_AES_256
30151                     case AES256CBCb:
30152                         return AES256CBCb;
30153                 #endif
30154                 #ifndef NO_DES3
30155                     case DESb:
30156                         return NID_des;
30157                     case DES3b:
30158                         return NID_des3;
30159                 #endif
30160                 }
30161                 break;
30162 
30163         #ifdef HAVE_OCSP
30164             case oidOcspType:
30165                 switch (oid) {
30166                     case OCSP_BASIC_OID:
30167                         return NID_id_pkix_OCSP_basic;
30168                     case OCSP_NONCE_OID:
30169                         return OCSP_NONCE_OID;
30170                 }
30171                 break;
30172         #endif /* HAVE_OCSP */
30173 
30174             /* oidCertExtType */
30175             case oidCertExtType:
30176                 switch (oid) {
30177                     case BASIC_CA_OID:
30178                         return BASIC_CA_OID;
30179                     case ALT_NAMES_OID:
30180                         return ALT_NAMES_OID;
30181                     case CRL_DIST_OID:
30182                         return CRL_DIST_OID;
30183                     case AUTH_INFO_OID:
30184                         return AUTH_INFO_OID;
30185                     case AUTH_KEY_OID:
30186                         return AUTH_KEY_OID;
30187                     case SUBJ_KEY_OID:
30188                         return SUBJ_KEY_OID;
30189                     case INHIBIT_ANY_OID:
30190                         return INHIBIT_ANY_OID;
30191                     case KEY_USAGE_OID:
30192                         return NID_ext_key_usage;
30193                     case NAME_CONS_OID:
30194                         return NID_name_constraints;
30195                     case CERT_POLICY_OID:
30196                         return NID_certificate_policies;
30197                 }
30198                 break;
30199 
30200             /* oidCertAuthInfoType */
30201             case oidCertAuthInfoType:
30202                 switch (oid) {
30203                     case AIA_OCSP_OID:
30204                         return AIA_OCSP_OID;
30205                     case AIA_CA_ISSUER_OID:
30206                         return AIA_CA_ISSUER_OID;
30207                 }
30208                 break;
30209 
30210             /* oidCertPolicyType */
30211             case oidCertPolicyType:
30212                 switch (oid) {
30213                     case CP_ANY_OID:
30214                         return NID_any_policy;
30215                 }
30216                 break;
30217 
30218             /* oidCertAltNameType */
30219             case oidCertAltNameType:
30220                 switch (oid) {
30221                     case HW_NAME_OID:
30222                         return NID_hw_name_oid;
30223                 }
30224                 break;
30225 
30226             /* oidCertKeyUseType */
30227             case oidCertKeyUseType:
30228                 switch (oid) {
30229                     case EKU_ANY_OID:
30230                         return NID_anyExtendedKeyUsage;
30231                     case EKU_SERVER_AUTH_OID:
30232                         return EKU_SERVER_AUTH_OID;
30233                     case EKU_CLIENT_AUTH_OID:
30234                         return EKU_CLIENT_AUTH_OID;
30235                     case EKU_OCSP_SIGN_OID:
30236                         return EKU_OCSP_SIGN_OID;
30237                 }
30238                 break;
30239 
30240             /* oidKdfType */
30241             case oidKdfType:
30242                 switch (oid) {
30243                     case PBKDF2_OID:
30244                         return PBKDF2_OID;
30245                 }
30246                 break;
30247 
30248             /* oidPBEType */
30249             case oidPBEType:
30250                 switch (oid) {
30251                     case PBE_SHA1_RC4_128:
30252                         return PBE_SHA1_RC4_128;
30253                     case PBE_SHA1_DES:
30254                         return PBE_SHA1_DES;
30255                     case PBE_SHA1_DES3:
30256                         return PBE_SHA1_DES3;
30257                 }
30258                 break;
30259 
30260             /* oidKeyWrapType */
30261             case oidKeyWrapType:
30262                 switch (oid) {
30263                 #ifdef WOLFSSL_AES_128
30264                     case AES128_WRAP:
30265                         return AES128_WRAP;
30266                 #endif
30267                 #ifdef WOLFSSL_AES_192
30268                     case AES192_WRAP:
30269                         return AES192_WRAP;
30270                 #endif
30271                 #ifdef WOLFSSL_AES_256
30272                     case AES256_WRAP:
30273                         return AES256_WRAP;
30274                 #endif
30275                 }
30276                 break;
30277 
30278             /* oidCmsKeyAgreeType */
30279             case oidCmsKeyAgreeType:
30280                 switch (oid) {
30281                     #ifndef NO_SHA
30282                     case dhSinglePass_stdDH_sha1kdf_scheme:
30283                         return dhSinglePass_stdDH_sha1kdf_scheme;
30284                     #endif
30285                     #ifdef WOLFSSL_SHA224
30286                     case dhSinglePass_stdDH_sha224kdf_scheme:
30287                         return dhSinglePass_stdDH_sha224kdf_scheme;
30288                     #endif
30289                     #ifndef NO_SHA256
30290                     case dhSinglePass_stdDH_sha256kdf_scheme:
30291                         return dhSinglePass_stdDH_sha256kdf_scheme;
30292                     #endif
30293                     #ifdef WOLFSSL_SHA384
30294                     case dhSinglePass_stdDH_sha384kdf_scheme:
30295                         return dhSinglePass_stdDH_sha384kdf_scheme;
30296                     #endif
30297                     #ifdef WOLFSSL_SHA512
30298                     case dhSinglePass_stdDH_sha512kdf_scheme:
30299                         return dhSinglePass_stdDH_sha512kdf_scheme;
30300                     #endif
30301                 }
30302                 break;
30303 
30304             default:
30305                 WOLFSSL_MSG("NID not in table");
30306                 return -1;
30307         }
30308 
30309         return -1;
30310     }
30311 
30312 
30313 #ifndef NO_WOLFSSL_STUB
30314     char * wolfSSL_OBJ_nid2ln(int n)
30315     {
30316         (void)n;
30317         WOLFSSL_ENTER("wolfSSL_OBJ_nid2ln");
30318         WOLFSSL_STUB("OBJ_nid2ln");
30319 
30320         return NULL;
30321     }
30322 #endif
30323 
30324 #ifndef NO_WOLFSSL_STUB
30325     int wolfSSL_OBJ_txt2nid(const char* s)
30326     {
30327         (void)s;
30328         WOLFSSL_STUB("OBJ_txt2nid");
30329 
30330         return 0;
30331     }
30332 #endif
30333 
30334     /* compatibility function. It's intended use is to remove OID's from an
30335      * internal table that have been added with OBJ_create. wolfSSL manages it's
30336      * own interenal OID values and does not currently support OBJ_create. */
30337     void wolfSSL_OBJ_cleanup(void)
30338     {
30339         WOLFSSL_ENTER("wolfSSL_OBJ_cleanup()");
30340     }
30341 
30342 
30343     #ifndef NO_WOLFSSL_STUB
30344     void wolfSSL_set_verify_depth(WOLFSSL *ssl, int depth) {
30345         WOLFSSL_ENTER("wolfSSL_set_verify_depth");
30346 #ifndef OPENSSL_EXTRA
30347         (void)ssl;
30348         (void)depth;
30349         WOLFSSL_STUB("wolfSSL_set_verify_depth");
30350 #else
30351         ssl->options.verifyDepth = (byte)depth;
30352 #endif
30353     }
30354     #endif
30355 
30356 
30357     #ifndef NO_WOLFSSL_STUB
30358     WOLFSSL_ASN1_OBJECT * wolfSSL_X509_NAME_ENTRY_get_object(WOLFSSL_X509_NAME_ENTRY *ne) {
30359         (void)ne;
30360         WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_object");
30361         WOLFSSL_STUB("X509_NAME_ENTRY_get_object");
30362 
30363         return NULL;
30364     }
30365     #endif
30366 
30367     WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(
30368                                              WOLFSSL_X509_NAME *name, int loc) {
30369 
30370         int maxLoc = name->fullName.fullNameLen;
30371 
30372         WOLFSSL_ENTER("wolfSSL_X509_NAME_get_entry");
30373 
30374         if (loc < 0 || loc > maxLoc) {
30375             WOLFSSL_MSG("Bad argument");
30376             return NULL;
30377         }
30378 
30379         /* DC component */
30380         if (name->fullName.dcMode){
30381             if (name->fullName.fullName != NULL){
30382                 if (loc == name->fullName.dcNum){
30383                     name->cnEntry.data.data   = &name->fullName.fullName[name->fullName.cIdx];
30384                     name->cnEntry.data.length = name->fullName.cLen;
30385                     name->cnEntry.nid         = ASN_COUNTRY_NAME;
30386                 } else {
30387                     name->cnEntry.data.data   = &name->fullName.fullName[name->fullName.dcIdx[loc]];
30388                     name->cnEntry.data.length = name->fullName.dcLen[loc];
30389                     name->cnEntry.nid         = ASN_DOMAIN_COMPONENT;
30390                 }
30391             }
30392             name->cnEntry.data.type = CTC_UTF8;
30393             name->cnEntry.set       = 1;
30394             return &(name->cnEntry);
30395 
30396          /* common name index case */
30397         } else if (loc == name->fullName.cnIdx) {
30398             /* get CN shortcut from x509 since it has null terminator */
30399             name->cnEntry.data.data   = name->x509->subjectCN;
30400             name->cnEntry.data.length = name->fullName.cnLen;
30401             name->cnEntry.data.type   = CTC_UTF8;
30402             name->cnEntry.nid         = ASN_COMMON_NAME;
30403             name->cnEntry.set         = 1;
30404             return &(name->cnEntry);
30405         }
30406 
30407         /* additionall cases to check for go here */
30408 
30409         WOLFSSL_MSG("Entry not found or implemented");
30410         (void)name;
30411         (void)loc;
30412 
30413         return NULL;
30414     }
30415 
30416     #ifndef NO_WOLFSSL_STUB
30417     void wolfSSL_sk_X509_NAME_pop_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, void f (WOLFSSL_X509_NAME*)){
30418         (void) sk;
30419         (void) f;
30420         WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_pop_free");
30421         WOLFSSL_STUB("sk_X509_NAME_pop_free");
30422     }
30423     #endif
30424     #ifndef NO_WOLFSSL_STUB
30425     int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key){
30426         (void) x509;
30427         (void) key;
30428         WOLFSSL_ENTER("wolfSSL_X509_check_private_key");
30429         WOLFSSL_STUB("X509_check_private_key");
30430 
30431         return WOLFSSL_SUCCESS;
30432     }
30433 
30434     WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list( WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk ){
30435         (void) sk;
30436         WOLFSSL_ENTER("wolfSSL_dup_CA_list");
30437         WOLFSSL_STUB("SSL_dup_CA_list");
30438 
30439         return NULL;
30440     }
30441     #endif
30442 
30443 #endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE || HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
30444 #endif /* OPENSSL_EXTRA */
30445 
30446 #ifdef OPENSSL_EXTRA
30447 
30448 /* wolfSSL uses negative values for error states. This function returns an
30449  * unsigned type so the value returned is the absolute value of the error.
30450  */
30451 unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line)
30452 {
30453     WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
30454 
30455     (void)line;
30456     (void)file;
30457 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(DEBUG_WOLFSSL) || defined(WOLFSSL_HAPROXY)
30458     {
30459         int ret;
30460 
30461         if ((ret = wc_PeekErrorNode(-1, file, NULL, line)) < 0) {
30462             WOLFSSL_MSG("Issue peeking at error node in queue");
30463             return 0;
30464         }
30465     #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
30466         if (ret == -ASN_NO_PEM_HEADER)
30467             return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
30468     #endif
30469         return (unsigned long)ret;
30470     }
30471 #else
30472     return (unsigned long)(0 - NOT_COMPILED_IN);
30473 #endif
30474 }
30475 
30476 
30477 #ifndef NO_CERTS
30478 int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey)
30479 {
30480     WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey");
30481 
30482     if (ctx == NULL || pkey == NULL) {
30483         return WOLFSSL_FAILURE;
30484     }
30485 
30486     if (pkey->pkey.ptr != NULL) {
30487         /* ptr for WOLFSSL_EVP_PKEY struct is expected to be DER format */
30488         return wolfSSL_CTX_use_PrivateKey_buffer(ctx,
30489                                        (const unsigned char*)pkey->pkey.ptr,
30490                                        pkey->pkey_sz, SSL_FILETYPE_ASN1);
30491     }
30492 
30493     WOLFSSL_MSG("wolfSSL private key not set");
30494     return BAD_FUNC_ARG;
30495 }
30496 #endif /* !NO_CERTS */
30497 
30498 
30499 void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx)
30500 {
30501     WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
30502     #ifdef HAVE_EX_DATA
30503     if(ctx != NULL && idx < MAX_EX_DATA && idx >= 0) {
30504         return ctx->ex_data[idx];
30505     }
30506     #else
30507     (void)ctx;
30508     (void)idx;
30509     #endif
30510     return NULL;
30511 }
30512 
30513 int wolfSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b,
30514                                 void* c)
30515 {
30516     static int ctx_idx = 0;
30517 
30518     WOLFSSL_ENTER("wolfSSL_CTX_get_ex_new_index");
30519     (void)idx;
30520     (void)arg;
30521     (void)a;
30522     (void)b;
30523     (void)c;
30524 
30525     return ctx_idx++;
30526 }
30527 
30528 
30529 /* Return the index that can be used for the WOLFSSL structure to store
30530  * application data.
30531  *
30532  */
30533 int wolfSSL_get_ex_new_index(long argValue, void* arg,
30534         WOLFSSL_CRYPTO_EX_new* cb1, WOLFSSL_CRYPTO_EX_dup* cb2,
30535         WOLFSSL_CRYPTO_EX_free* cb3)
30536 {
30537     static int ssl_idx = 0;
30538 
30539     WOLFSSL_ENTER("wolfSSL_get_ex_new_index");
30540 
30541     (void)argValue;
30542     (void)arg;
30543     (void)cb1;
30544     (void)cb2;
30545     (void)cb3;
30546 
30547     return ssl_idx++;
30548 }
30549 
30550 
30551 int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data)
30552 {
30553     WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data");
30554     #ifdef HAVE_EX_DATA
30555     if (ctx != NULL && idx < MAX_EX_DATA)
30556     {
30557         ctx->ex_data[idx] = data;
30558         return WOLFSSL_SUCCESS;
30559     }
30560     #else
30561     (void)ctx;
30562     (void)idx;
30563     (void)data;
30564     #endif
30565     return WOLFSSL_FAILURE;
30566 }
30567 
30568 
30569 /* Returns char* to app data stored in ex[0].
30570  *
30571  * ssl WOLFSSL structure to get app data from
30572  */
30573 void* wolfSSL_get_app_data(const WOLFSSL *ssl)
30574 {
30575     /* checkout exdata stuff... */
30576     WOLFSSL_ENTER("wolfSSL_get_app_data");
30577 
30578     return wolfSSL_get_ex_data(ssl, 0);
30579 }
30580 
30581 
30582 /* Set ex array 0 to have app data
30583  *
30584  * ssl WOLFSSL struct to set app data in
30585  * arg data to be stored
30586  *
30587  * Returns SSL_SUCCESS on sucess and SSL_FAILURE on failure
30588  */
30589 int wolfSSL_set_app_data(WOLFSSL *ssl, void* arg) {
30590     WOLFSSL_ENTER("wolfSSL_set_app_data");
30591 
30592     return wolfSSL_set_ex_data(ssl, 0, arg);
30593 }
30594 
30595 
30596 int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data)
30597 {
30598     WOLFSSL_ENTER("wolfSSL_set_ex_data");
30599 #if defined(HAVE_EX_DATA) || defined(FORTRESS)
30600     if (ssl != NULL && idx < MAX_EX_DATA)
30601     {
30602         ssl->ex_data[idx] = data;
30603         return WOLFSSL_SUCCESS;
30604     }
30605 #else
30606     WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
30607     (void)ssl;
30608     (void)idx;
30609     (void)data;
30610 #endif
30611     return WOLFSSL_FAILURE;
30612 }
30613 
30614 
30615 
30616 void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx)
30617 {
30618     WOLFSSL_ENTER("wolfSSL_get_ex_data");
30619 #if defined(HAVE_EX_DATA) || defined(FORTRESS)
30620     if (ssl != NULL && idx < MAX_EX_DATA && idx >= 0)
30621         return ssl->ex_data[idx];
30622 #else
30623     WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
30624     (void)ssl;
30625     (void)idx;
30626 #endif
30627     return 0;
30628 }
30629 
30630 #ifndef NO_DSA
30631 WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO *bp, WOLFSSL_DSA **x,
30632         pem_password_cb *cb, void *u)
30633 {
30634     WOLFSSL_DSA* dsa;
30635     DsaKey* key;
30636     int    length;
30637     unsigned char*  buf;
30638     word32 bufSz;
30639     int ret;
30640     word32 idx = 0;
30641     DerBuffer* pDer;
30642 
30643     WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSAparams");
30644 
30645     ret = wolfSSL_BIO_get_mem_data(bp, &buf);
30646     if (ret <= 0) {
30647         WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret);
30648         return NULL;
30649     }
30650 
30651     bufSz = (word32)ret;
30652 
30653     if (cb != NULL || u != NULL) {
30654         /*
30655          * cb is for a call back when encountering encrypted PEM files
30656          * if cb == NULL and u != NULL then u = null terminated password string
30657          */
30658         WOLFSSL_MSG("Not yet supporting call back or password for encrypted PEM");
30659     }
30660 
30661     if ((ret = PemToDer(buf, (long)bufSz, DSA_PARAM_TYPE, &pDer, NULL, NULL,
30662                     NULL)) < 0 ) {
30663         WOLFSSL_MSG("Issue converting from PEM to DER");
30664         return NULL;
30665     }
30666 
30667     if ((ret = GetSequence(pDer->buffer, &idx, &length, pDer->length)) < 0) {
30668         WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret);
30669         FreeDer(&pDer);
30670         return NULL;
30671     }
30672 
30673     dsa = wolfSSL_DSA_new();
30674     if (dsa == NULL) {
30675         FreeDer(&pDer);
30676         WOLFSSL_MSG("Error creating DSA struct");
30677         return NULL;
30678     }
30679 
30680     key = (DsaKey*)dsa->internal;
30681     if (key == NULL) {
30682         FreeDer(&pDer);
30683         wolfSSL_DSA_free(dsa);
30684         WOLFSSL_MSG("Error finding DSA key struct");
30685         return NULL;
30686     }
30687 
30688     if (GetInt(&key->p,  pDer->buffer, &idx, pDer->length) < 0 ||
30689         GetInt(&key->q,  pDer->buffer, &idx, pDer->length) < 0 ||
30690         GetInt(&key->g,  pDer->buffer, &idx, pDer->length) < 0 ) {
30691         WOLFSSL_MSG("dsa key error");
30692         FreeDer(&pDer);
30693         wolfSSL_DSA_free(dsa);
30694         return NULL;
30695     }
30696 
30697     if (SetIndividualExternal(&dsa->p, &key->p) != WOLFSSL_SUCCESS) {
30698         WOLFSSL_MSG("dsa p key error");
30699         FreeDer(&pDer);
30700         wolfSSL_DSA_free(dsa);
30701         return NULL;
30702     }
30703 
30704     if (SetIndividualExternal(&dsa->q, &key->q) != WOLFSSL_SUCCESS) {
30705         WOLFSSL_MSG("dsa q key error");
30706         FreeDer(&pDer);
30707         wolfSSL_DSA_free(dsa);
30708         return NULL;
30709     }
30710 
30711     if (SetIndividualExternal(&dsa->g, &key->g) != WOLFSSL_SUCCESS) {
30712         WOLFSSL_MSG("dsa g key error");
30713         FreeDer(&pDer);
30714         wolfSSL_DSA_free(dsa);
30715         return NULL;
30716     }
30717 
30718     if (x != NULL) {
30719         *x = dsa;
30720     }
30721 
30722     FreeDer(&pDer);
30723     return dsa;
30724 }
30725 #endif /* NO_DSA */
30726 
30727 #define WOLFSSL_BIO_INCLUDED
30728 #include "src/bio.c"
30729 
30730 /* Begin functions for openssl/buffer.h */
30731 WOLFSSL_BUF_MEM* wolfSSL_BUF_MEM_new(void)
30732 {
30733     WOLFSSL_BUF_MEM* buf;
30734     buf = (WOLFSSL_BUF_MEM*)XMALLOC(sizeof(WOLFSSL_BUF_MEM), NULL,
30735                                                         DYNAMIC_TYPE_OPENSSL);
30736     if (buf) {
30737         XMEMSET(buf, 0, sizeof(WOLFSSL_BUF_MEM));
30738     }
30739     return buf;
30740 }
30741 
30742 
30743 /* returns length of buffer on success */
30744 int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len)
30745 {
30746     int len_int = (int)len;
30747     int mx;
30748 
30749     /* verify provided arguments */
30750     if (buf == NULL || len_int < 0) {
30751         return 0; /* BAD_FUNC_ARG; */
30752     }
30753 
30754     /* check to see if fits in existing length */
30755     if (buf->length > len) {
30756         buf->length = len;
30757         return len_int;
30758     }
30759 
30760     /* check to see if fits in max buffer */
30761     if (buf->max >= len) {
30762         if (buf->data != NULL) {
30763             XMEMSET(&buf->data[buf->length], 0, len - buf->length);
30764         }
30765         buf->length = len;
30766         return len_int;
30767     }
30768 
30769     /* expand size, to handle growth */
30770     mx = (len_int + 3) / 3 * 4;
30771 
30772     /* use realloc */
30773     buf->data = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30774     if (buf->data == NULL) {
30775         return 0; /* ERR_R_MALLOC_FAILURE; */
30776     }
30777 
30778     buf->max = mx;
30779     XMEMSET(&buf->data[buf->length], 0, len - buf->length);
30780     buf->length = len;
30781 
30782     return len_int;
30783 }
30784 
30785 void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf)
30786 {
30787     if (buf) {
30788         if (buf->data) {
30789             XFREE(buf->data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30790             buf->data = NULL;
30791         }
30792         buf->max = 0;
30793         buf->length = 0;
30794         XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
30795     }
30796 }
30797 /* End Functions for openssl/buffer.h */
30798 
30799 #endif /* OPENSSL_EXTRA */
30800 
30801 
30802 #if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
30803     || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
30804 
30805 WOLFSSL_BIO *wolfSSL_BIO_new_file(const char *filename, const char *mode)
30806 {
30807 #ifndef NO_FILESYSTEM
30808     WOLFSSL_BIO* bio;
30809     XFILE fp;
30810 
30811     WOLFSSL_ENTER("wolfSSL_BIO_new_file");
30812 
30813     fp = XFOPEN(filename, mode);
30814     if (fp == NULL)
30815         return NULL;
30816 
30817     bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
30818     if (bio == NULL) {
30819         XFCLOSE(fp);
30820         return bio;
30821     }
30822 
30823     if (wolfSSL_BIO_set_fp(bio, fp, BIO_CLOSE) != WOLFSSL_SUCCESS) {
30824         XFCLOSE(fp);
30825         wolfSSL_BIO_free(bio);
30826         bio = NULL;
30827     }
30828 
30829     /* file is closed when BIO is free'd */
30830     return bio;
30831 #else
30832     (void)filename;
30833     (void)mode;
30834     return NULL;
30835 #endif /* NO_FILESYSTEM */
30836 }
30837 
30838 
30839 #ifndef NO_DH
30840 WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bio, WOLFSSL_DH **x,
30841         pem_password_cb *cb, void *u)
30842 {
30843 #ifndef NO_FILESYSTEM
30844     WOLFSSL_DH* localDh = NULL;
30845     unsigned char* mem  = NULL;
30846     word32 size;
30847     long   sz;
30848     int    ret;
30849     DerBuffer *der = NULL;
30850     byte*  p = NULL;
30851     byte*  g = NULL;
30852     word32 pSz = MAX_DH_SIZE;
30853     word32 gSz = MAX_DH_SIZE;
30854     int    memAlloced = 0;
30855 
30856     WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DHparams");
30857     (void)cb;
30858     (void)u;
30859 
30860     if (bio == NULL) {
30861         WOLFSSL_MSG("Bad Function Argument bio is NULL");
30862         return NULL;
30863     }
30864 
30865     if (bio->type == WOLFSSL_BIO_MEMORY) {
30866         /* Use the buffer directly. */
30867         ret = wolfSSL_BIO_get_mem_data(bio, &mem);
30868         if (mem == NULL || ret <= 0) {
30869             WOLFSSL_MSG("Failed to get data from bio struct");
30870             goto end;
30871         }
30872         size = ret;
30873     }
30874     else if (bio->type == WOLFSSL_BIO_FILE) {
30875         /* Read whole file into a new buffer. */
30876         XFSEEK(bio->file, 0, SEEK_END);
30877         sz = XFTELL(bio->file);
30878         XFSEEK(bio->file, 0, SEEK_SET);
30879         if (sz <= 0L)
30880             goto end;
30881         mem = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_PEM);
30882         if (mem == NULL)
30883             goto end;
30884         memAlloced = 1;
30885 
30886         if (wolfSSL_BIO_read(bio, (char *)mem, (int)sz) <= 0)
30887             goto end;
30888         size = (word32)sz;
30889     }
30890     else {
30891         WOLFSSL_MSG("BIO type not supported for reading DH parameters");
30892         goto end;
30893     }
30894 
30895     ret = PemToDer(mem, size, DH_PARAM_TYPE, &der, NULL, NULL, NULL);
30896     if (ret != 0)
30897         goto end;
30898 
30899     /* Use the object passed in, otherwise allocate a new object */
30900     if (x != NULL)
30901         localDh = *x;
30902     if (localDh == NULL) {
30903         localDh = (WOLFSSL_DH*)XMALLOC(sizeof(WOLFSSL_DH), NULL,
30904                                        DYNAMIC_TYPE_OPENSSL);
30905         if (localDh == NULL)
30906             goto end;
30907         XMEMSET(localDh, 0, sizeof(WOLFSSL_DH));
30908     }
30909 
30910     /* Load data in manually */
30911     p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
30912     g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
30913     if (p == NULL || g == NULL)
30914         goto end;
30915 
30916     /* Extract the p and g as data from the DER encoded DH parameters. */
30917     ret = wc_DhParamsLoad(der->buffer, der->length, p, &pSz, g, &gSz);
30918     if (ret != 0) {
30919         if (x != NULL && localDh != *x)
30920             XFREE(localDh, NULL, DYNAMIC_TYPE_OPENSSL);
30921         localDh = NULL;
30922         goto end;
30923     }
30924 
30925     if (x != NULL)
30926         *x = localDh;
30927 
30928     /* Put p and g in as big numbers. */
30929     if (localDh->p != NULL) {
30930         wolfSSL_BN_free(localDh->p);
30931         localDh->p = NULL;
30932     }
30933     if (localDh->g != NULL) {
30934         wolfSSL_BN_free(localDh->g);
30935         localDh->g = NULL;
30936     }
30937     localDh->p = wolfSSL_BN_bin2bn(p, pSz, NULL);
30938     localDh->g = wolfSSL_BN_bin2bn(g, gSz, NULL);
30939     if (localDh->p == NULL || localDh->g == NULL) {
30940         if (x != NULL && localDh != *x)
30941             wolfSSL_DH_free(localDh);
30942         localDh = NULL;
30943     }
30944 
30945 end:
30946     if (memAlloced) XFREE(mem, NULL, DYNAMIC_TYPE_PEM);
30947     if (der != NULL) FreeDer(&der);
30948     XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
30949     XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
30950     return localDh;
30951 #else
30952     (void)bio;
30953     (void)x;
30954     (void)cb;
30955     (void)u;
30956     return NULL;
30957 #endif
30958 }
30959 #endif
30960 
30961 #ifdef WOLFSSL_CERT_GEN
30962 
30963 #ifdef WOLFSSL_CERT_REQ
30964 /* writes the x509 from x to the WOLFSSL_BIO bp
30965  *
30966  * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
30967  */
30968 int wolfSSL_PEM_write_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
30969 {
30970     byte* pem;
30971     int   pemSz = 0;
30972     const unsigned char* der;
30973     int derSz;
30974     int ret;
30975 
30976     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_REQ()");
30977 
30978     if (x == NULL || bp == NULL) {
30979         return WOLFSSL_FAILURE;
30980     }
30981 
30982     der = wolfSSL_X509_get_der(x, &derSz);
30983     if (der == NULL) {
30984         return WOLFSSL_FAILURE;
30985     }
30986 
30987     /* get PEM size */
30988     pemSz = wc_DerToPemEx(der, derSz, NULL, 0, NULL, CERTREQ_TYPE);
30989     if (pemSz < 0) {
30990         return WOLFSSL_FAILURE;
30991     }
30992 
30993     /* create PEM buffer and convert from DER */
30994     pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30995     if (pem == NULL) {
30996         return WOLFSSL_FAILURE;
30997     }
30998     if (wc_DerToPemEx(der, derSz, pem, pemSz, NULL, CERTREQ_TYPE) < 0) {
30999         XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
31000         return WOLFSSL_FAILURE;
31001     }
31002 
31003     /* write the PEM to BIO */
31004     ret = wolfSSL_BIO_write(bp, pem, pemSz);
31005     XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
31006 
31007     if (ret <= 0) return WOLFSSL_FAILURE;
31008     return WOLFSSL_SUCCESS;
31009 }
31010 #endif /* WOLFSSL_CERT_REQ */
31011 
31012 
31013 /* writes the x509 from x to the WOLFSSL_BIO bp
31014  *
31015  * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
31016  */
31017 int wolfSSL_PEM_write_bio_X509_AUX(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
31018 {
31019     byte* pem;
31020     int   pemSz = 0;
31021     const unsigned char* der;
31022     int derSz;
31023     int ret;
31024 
31025     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_AUX()");
31026 
31027     if (bp == NULL || x == NULL) {
31028         WOLFSSL_MSG("NULL argument passed in");
31029         return WOLFSSL_FAILURE;
31030     }
31031 
31032     der = wolfSSL_X509_get_der(x, &derSz);
31033     if (der == NULL) {
31034         return WOLFSSL_FAILURE;
31035     }
31036 
31037     /* get PEM size */
31038     pemSz = wc_DerToPemEx(der, derSz, NULL, 0, NULL, CERT_TYPE);
31039     if (pemSz < 0) {
31040         return WOLFSSL_FAILURE;
31041     }
31042 
31043     /* create PEM buffer and convert from DER */
31044     pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
31045     if (pem == NULL) {
31046         return WOLFSSL_FAILURE;
31047     }
31048     if (wc_DerToPemEx(der, derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
31049         XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
31050         return WOLFSSL_FAILURE;
31051     }
31052 
31053     /* write the PEM to BIO */
31054     ret = wolfSSL_BIO_write(bp, pem, pemSz);
31055     XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
31056 
31057     if (ret <= 0) return WOLFSSL_FAILURE;
31058     return WOLFSSL_SUCCESS;
31059 }
31060 #endif /* WOLFSSL_CERT_GEN */
31061 
31062 int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert)
31063 {
31064     byte* pem;
31065     int   pemSz = 0;
31066     const unsigned char* der;
31067     int derSz;
31068     int ret;
31069 
31070     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_AUX()");
31071 
31072     if (bio == NULL || cert == NULL) {
31073         WOLFSSL_MSG("NULL argument passed in");
31074         return WOLFSSL_FAILURE;
31075     }
31076 
31077     der = wolfSSL_X509_get_der(cert, &derSz);
31078     if (der == NULL) {
31079         return WOLFSSL_FAILURE;
31080     }
31081 
31082     /* get PEM size */
31083     pemSz = wc_DerToPemEx(der, derSz, NULL, 0, NULL, CERT_TYPE);
31084     if (pemSz < 0) {
31085         return WOLFSSL_FAILURE;
31086     }
31087 
31088     /* create PEM buffer and convert from DER */
31089     pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
31090     if (pem == NULL) {
31091         return WOLFSSL_FAILURE;
31092     }
31093     if (wc_DerToPemEx(der, derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
31094         XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
31095         return WOLFSSL_FAILURE;
31096     }
31097 
31098     /* write the PEM to BIO */
31099     ret = wolfSSL_BIO_write(bio, pem, pemSz);
31100     XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
31101 
31102     if (ret <= 0) return WOLFSSL_FAILURE;
31103     return WOLFSSL_SUCCESS;
31104 }
31105 
31106 
31107 #if defined(OPENSSL_EXTRA) && !defined(NO_DH)
31108 /* Intialize ctx->dh with dh's params. Return WOLFSSL_SUCCESS on ok */
31109 long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL_DH* dh)
31110 {
31111     int pSz, gSz;
31112     byte *p, *g;
31113     int ret=0;
31114 
31115     WOLFSSL_ENTER("wolfSSL_CTX_set_tmp_dh");
31116 
31117     if(!ctx || !dh)
31118         return BAD_FUNC_ARG;
31119 
31120     /* Get needed size for p and g */
31121     pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
31122     gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
31123 
31124     if(pSz <= 0 || gSz <= 0)
31125         return WOLFSSL_FATAL_ERROR;
31126 
31127     p = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
31128     if(!p)
31129         return MEMORY_E;
31130 
31131     g = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
31132     if(!g) {
31133         XFREE(p, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
31134         return MEMORY_E;
31135     }
31136 
31137     pSz = wolfSSL_BN_bn2bin(dh->p, p);
31138     gSz = wolfSSL_BN_bn2bin(dh->g, g);
31139 
31140     if(pSz >= 0 && gSz >= 0) /* Conversion successful */
31141         ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
31142 
31143     XFREE(p, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
31144     XFREE(g, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
31145 
31146     return pSz > 0 && gSz > 0 ? ret : WOLFSSL_FATAL_ERROR;
31147 }
31148 #endif /* OPENSSL_EXTRA && !NO_DH */
31149 
31150 
31151 /* returns the enum value associated with handshake state
31152  *
31153  * ssl the WOLFSSL structure to get state of
31154  */
31155 int wolfSSL_get_state(const WOLFSSL* ssl)
31156 {
31157     WOLFSSL_ENTER("wolfSSL_get_state");
31158 
31159     if (ssl == NULL) {
31160         WOLFSSL_MSG("Null argument passed in");
31161         return SSL_FAILURE;
31162     }
31163 
31164     return ssl->options.handShakeState;
31165 }
31166 #endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE */
31167 
31168 #if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO)
31169 
31170 /* Returns the verifyCallback from the ssl structure if successful.
31171 Returns NULL otherwise. */
31172 VerifyCallback wolfSSL_get_verify_callback(WOLFSSL* ssl)
31173 {
31174     WOLFSSL_ENTER("wolfSSL_get_verify_callback()");
31175     if (ssl) {
31176         return ssl->verifyCallback;
31177     }
31178     return NULL;
31179 }
31180 
31181 /* Creates a new bio pair.
31182 Returns WOLFSSL_SUCCESS if no error, WOLFSSL_FAILURE otherwise.*/
31183 int wolfSSL_BIO_new_bio_pair(WOLFSSL_BIO **bio1_p, size_t writebuf1,
31184                                          WOLFSSL_BIO **bio2_p, size_t writebuf2)
31185 {
31186     WOLFSSL_BIO *bio1 = NULL, *bio2 = NULL;
31187     int ret = 1;
31188 
31189     WOLFSSL_ENTER("wolfSSL_BIO_new_bio_pair()");
31190 
31191     if (bio1_p == NULL || bio2_p == NULL) {
31192         WOLFSSL_MSG("Bad Function Argument");
31193         return BAD_FUNC_ARG;
31194     }
31195 
31196     /* set up the new bio structures and write buf sizes */
31197     if ((bio1 = wolfSSL_BIO_new(wolfSSL_BIO_s_bio())) == NULL) {
31198         WOLFSSL_MSG("Bio allocation failed");
31199         ret = WOLFSSL_FAILURE;
31200     }
31201     if (ret) {
31202         if ((bio2 = wolfSSL_BIO_new(wolfSSL_BIO_s_bio())) == NULL) {
31203             WOLFSSL_MSG("Bio allocation failed");
31204             ret = WOLFSSL_FAILURE;
31205         }
31206     }
31207     if (ret && writebuf1) {
31208         if (!(ret = wolfSSL_BIO_set_write_buf_size(bio1, writebuf1))) {
31209             WOLFSSL_MSG("wolfSSL_BIO_set_write_buf() failure");
31210         }
31211     }
31212     if (ret && writebuf2) {
31213         if (!(ret = wolfSSL_BIO_set_write_buf_size(bio2, writebuf2))) {
31214             WOLFSSL_MSG("wolfSSL_BIO_set_write_buf() failure");
31215         }
31216     }
31217 
31218     if (ret) {
31219         if ((ret = wolfSSL_BIO_make_bio_pair(bio1, bio2))) {
31220             *bio1_p = bio1;
31221             *bio2_p = bio2;
31222         }
31223     }
31224     if (!ret) {
31225         wolfSSL_BIO_free(bio1);
31226         bio1 = NULL;
31227         wolfSSL_BIO_free(bio2);
31228         bio2 = NULL;
31229     }
31230     return ret;
31231 }
31232 
31233 
31234 #if !defined(NO_RSA)
31235 /* Converts an rsa key from a bio buffer into an internal rsa structure.
31236 Returns a pointer to the new WOLFSSL_RSA structure. */
31237 WOLFSSL_RSA* wolfSSL_d2i_RSAPrivateKey_bio(WOLFSSL_BIO *bio, WOLFSSL_RSA **out)
31238 {
31239     const unsigned char* bioMem = NULL;
31240     int bioMemSz = 0;
31241     WOLFSSL_RSA* key = NULL;
31242     unsigned char maxKeyBuf[4096];
31243     unsigned char* bufPtr = NULL;
31244     unsigned char* extraBioMem = NULL;
31245     int extraBioMemSz = 0;
31246     int derLength = 0;
31247     int j = 0, i = 0;
31248 
31249     WOLFSSL_ENTER("wolfSSL_d2i_RSAPrivateKey_bio()");
31250 
31251     if (bio == NULL) {
31252         WOLFSSL_MSG("Bad Function Argument");
31253         return NULL;
31254     }
31255     (void)out;
31256 
31257     bioMemSz = wolfSSL_BIO_pending(bio);
31258     if (bioMemSz <= 0) {
31259         WOLFSSL_MSG("wolfSSL_BIO_pending() failure");
31260         return NULL;
31261     }
31262 
31263     bioMem = (unsigned char*)XMALLOC(bioMemSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31264     if (bioMem == NULL) {
31265         WOLFSSL_MSG("Malloc failure");
31266         return NULL;
31267     }
31268 
31269     bufPtr = maxKeyBuf;
31270     if (wolfSSL_BIO_read(bio, (unsigned char*)bioMem, (int)bioMemSz) == bioMemSz) {
31271         if ((key = wolfSSL_d2i_RSAPrivateKey(NULL, &bioMem, bioMemSz)) == NULL) {
31272             XFREE((unsigned char*)bioMem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31273             return NULL;
31274         }
31275 
31276         /* This function is used to get the total length of the rsa key. */
31277         derLength = wolfSSL_i2d_RSAPrivateKey(key, &bufPtr);
31278 
31279         /* Write extra data back into bio object if necessary. */
31280         extraBioMemSz = (bioMemSz - derLength);
31281         if (extraBioMemSz > 0) {
31282             extraBioMem = (unsigned char *)XMALLOC(extraBioMemSz, NULL,
31283                                                        DYNAMIC_TYPE_TMP_BUFFER);
31284             if (extraBioMem == NULL) {
31285                 WOLFSSL_MSG("Malloc failure");;
31286                 XFREE((unsigned char*)extraBioMem, bio->heap, 
31287                                                        DYNAMIC_TYPE_TMP_BUFFER);
31288                 XFREE((unsigned char*)bioMem, bio->heap, 
31289                                                        DYNAMIC_TYPE_TMP_BUFFER);
31290                 return NULL;
31291             }
31292 
31293             for (i = derLength; i < bioMemSz; i++) {
31294                 *(extraBioMem + j) = *(bioMem + i);
31295                 j++;
31296             }
31297 
31298             wolfSSL_BIO_write(bio, extraBioMem, extraBioMemSz);
31299             if (wolfSSL_BIO_pending(bio) <= 0) {
31300                 WOLFSSL_MSG("Failed to write memory to bio");
31301                 XFREE((unsigned char*)extraBioMem, bio->heap, 
31302                                                        DYNAMIC_TYPE_TMP_BUFFER);
31303                 XFREE((unsigned char*)bioMem, bio->heap, 
31304                                                        DYNAMIC_TYPE_TMP_BUFFER);
31305                 return NULL;
31306             }
31307             XFREE((unsigned char*)extraBioMem, bio->heap, 
31308                                                        DYNAMIC_TYPE_TMP_BUFFER);
31309         }
31310 
31311         if (out != NULL && key != NULL) {
31312             *out = key;
31313         }
31314     }
31315     XFREE((unsigned char*)bioMem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31316     return key;
31317 }
31318 #endif
31319 
31320 
31321 /* Adds the ASN1 certificate to the user ctx.
31322 Returns WOLFSSL_SUCCESS if no error, returns WOLFSSL_FAILURE otherwise.*/
31323 int wolfSSL_CTX_use_certificate_ASN1(WOLFSSL_CTX *ctx, int derSz, 
31324                                                        const unsigned char *der)
31325 {
31326     WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_ASN1()");
31327     if (der != NULL && ctx != NULL) {
31328         if (wolfSSL_CTX_use_certificate_buffer(ctx, der, derSz, 
31329                                       WOLFSSL_FILETYPE_ASN1) == WOLFSSL_SUCCESS) {
31330             return WOLFSSL_SUCCESS;
31331         }
31332 
31333     }
31334     return WOLFSSL_FAILURE;
31335 }
31336 
31337 
31338 #if !defined(NO_RSA) && !defined(HAVE_FAST_RSA)
31339 /* Adds the rsa private key to the user ctx.
31340 Returns WOLFSSL_SUCCESS if no error, returns WOLFSSL_FAILURE otherwise.*/
31341 int wolfSSL_CTX_use_RSAPrivateKey(WOLFSSL_CTX* ctx, WOLFSSL_RSA* rsa)
31342 {
31343     int ret;
31344     int derSize;
31345     unsigned char maxDerBuf[4096];
31346     unsigned char* key = NULL;
31347 
31348     WOLFSSL_ENTER("wolfSSL_CTX_use_RSAPrivateKey()");
31349 
31350     if (ctx == NULL || rsa == NULL) {
31351         WOLFSSL_MSG("one or more inputs were NULL");
31352         return BAD_FUNC_ARG;
31353     }
31354     key = maxDerBuf;
31355     /* convert RSA struct to der encoded buffer and get the size */
31356     if ((derSize = wolfSSL_i2d_RSAPrivateKey(rsa, &key)) <= 0) {
31357         WOLFSSL_MSG("wolfSSL_i2d_RSAPrivateKey() failure");
31358         return WOLFSSL_FAILURE;
31359     }
31360     ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, (const unsigned char*)maxDerBuf, 
31361                                                     derSize, SSL_FILETYPE_ASN1);
31362     if (ret != WOLFSSL_SUCCESS) {
31363         WOLFSSL_MSG("wolfSSL_CTX_USE_PrivateKey_buffer() failure");
31364         return WOLFSSL_FAILURE;
31365     }
31366     return ret;
31367 }
31368 #endif /* NO_RSA && !HAVE_FAST_RSA */
31369 
31370 
31371 /* Converts EVP_PKEY data from a bio buffer to a WOLFSSL_EVP_PKEY structure.
31372 Returns pointer to private EVP_PKEY struct upon success, NULL if there
31373 is a failure.*/
31374 WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_bio(WOLFSSL_BIO* bio,
31375                                                          WOLFSSL_EVP_PKEY** out)
31376 {
31377     unsigned char* mem = NULL;
31378     int memSz = 0;
31379     WOLFSSL_EVP_PKEY* key = NULL;
31380     int i = 0, j = 0;
31381     unsigned char* extraBioMem = NULL;
31382     int extraBioMemSz = 0;
31383     int derLength = 0;
31384 
31385     WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey_bio()");
31386 
31387     if (bio == NULL) {
31388         return NULL;
31389     }
31390     (void)out;
31391 
31392     memSz = wolfSSL_BIO_pending(bio);
31393     if (memSz <= 0) {
31394         WOLFSSL_MSG("wolfSSL_BIO_pending() failure");
31395         return NULL;
31396     }
31397 
31398     mem = (unsigned char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31399     if (mem == NULL) {
31400         WOLFSSL_MSG("Malloc failure");
31401         return NULL;
31402     }
31403 
31404     if (wolfSSL_BIO_read(bio, (unsigned char*)mem, memSz) == memSz) {
31405         /* Determines key type and returns the new private EVP_PKEY object */
31406         if ((key = wolfSSL_d2i_PrivateKey_EVP(NULL, &mem, (long)memSz)) == NULL) {
31407             WOLFSSL_MSG("wolfSSL_d2i_PrivateKey_EVP() failure");
31408             XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31409             return NULL;
31410         }
31411 
31412         /* Write extra data back into bio object if necessary. */
31413         derLength = key->pkey_sz;
31414         extraBioMemSz = (memSz - derLength);
31415         if (extraBioMemSz > 0) {
31416             extraBioMem = (unsigned char *)XMALLOC(extraBioMemSz, NULL,
31417                                                        DYNAMIC_TYPE_TMP_BUFFER);
31418             if (extraBioMem == NULL) {
31419                 WOLFSSL_MSG("Malloc failure");
31420                 XFREE((unsigned char*)extraBioMem, bio->heap,
31421                                                        DYNAMIC_TYPE_TMP_BUFFER);
31422                 XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31423                 return NULL;
31424             }
31425 
31426             for (i = derLength; i < memSz; i++) {
31427                 *(extraBioMem + j) = *(mem + i);
31428                 j++;
31429             }
31430 
31431             wolfSSL_BIO_write(bio, extraBioMem, extraBioMemSz);
31432             if (wolfSSL_BIO_pending(bio) <= 0) {
31433                 WOLFSSL_MSG("Failed to write memory to bio");
31434                 XFREE((unsigned char*)extraBioMem, bio->heap,
31435                                                        DYNAMIC_TYPE_TMP_BUFFER);
31436                 XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31437                 return NULL;
31438             }
31439             XFREE((unsigned char*)extraBioMem, bio->heap,
31440                                                        DYNAMIC_TYPE_TMP_BUFFER);
31441         }
31442 
31443         if (out != NULL && key != NULL) {
31444             *out = key;
31445         }
31446     }
31447     XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31448     return key;
31449 }
31450 
31451 
31452 /* Converts a DER encoded private key to a WOLFSSL_EVP_PKEY structure.
31453  * returns a pointer to a new WOLFSSL_EVP_PKEY structure on success and NULL
31454  * on fail */
31455 WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY** out,
31456                                                   unsigned char** in, long inSz)
31457 {
31458     WOLFSSL_EVP_PKEY* pkey = NULL;
31459     const unsigned char* mem;
31460     long memSz = inSz;
31461 
31462     WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey_EVP()");
31463 
31464     if (in == NULL || inSz < 0) {
31465         WOLFSSL_MSG("Bad argument");
31466         return NULL;
31467     }
31468     mem = *in;
31469 
31470     #if !defined(NO_RSA)
31471     {
31472         RsaKey rsa;
31473         word32 keyIdx = 0;
31474 
31475         /* test if RSA key */
31476         if (wc_InitRsaKey(&rsa, NULL) == 0 &&
31477             wc_RsaPrivateKeyDecode(mem, &keyIdx, &rsa, (word32)memSz) == 0) {
31478             wc_FreeRsaKey(&rsa);
31479             pkey = wolfSSL_PKEY_new();
31480             if (pkey != NULL) {
31481                 pkey->pkey_sz = keyIdx;
31482                 pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
31483                         DYNAMIC_TYPE_PRIVATE_KEY);
31484                 if (pkey->pkey.ptr == NULL) {
31485                     wolfSSL_EVP_PKEY_free(pkey);
31486                     return NULL;
31487                 }
31488                 XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
31489                 pkey->type = EVP_PKEY_RSA;
31490                 if (out != NULL) {
31491                     *out = pkey;
31492                 }
31493 
31494                 pkey->ownRsa = 1;
31495                 pkey->rsa = wolfSSL_RSA_new();
31496                 if (pkey->rsa == NULL) {
31497                     wolfSSL_EVP_PKEY_free(pkey);
31498                     return NULL;
31499                 }
31500 
31501                 if (wolfSSL_RSA_LoadDer_ex(pkey->rsa,
31502                             (const unsigned char*)pkey->pkey.ptr,
31503                             pkey->pkey_sz, WOLFSSL_RSA_LOAD_PRIVATE) != 1) {
31504                     wolfSSL_EVP_PKEY_free(pkey);
31505                     return NULL;
31506                 }
31507 
31508                 return pkey;
31509             }
31510         }
31511         wc_FreeRsaKey(&rsa);
31512     }
31513     #endif /* NO_RSA */
31514 
31515     #ifdef HAVE_ECC
31516     {
31517         word32  keyIdx = 0;
31518         ecc_key ecc;
31519 
31520         /* test if ecc key */
31521         if (wc_ecc_init(&ecc) == 0 &&
31522             wc_EccPrivateKeyDecode(mem, &keyIdx, &ecc, (word32)memSz) == 0) {
31523             wc_ecc_free(&ecc);
31524             pkey = wolfSSL_PKEY_new();
31525             if (pkey != NULL) {
31526                 pkey->pkey_sz = keyIdx;
31527                 pkey->pkey.ptr = (char*)XMALLOC(keyIdx, NULL,
31528                         DYNAMIC_TYPE_PRIVATE_KEY);
31529                 if (pkey->pkey.ptr == NULL) {
31530                     wolfSSL_EVP_PKEY_free(pkey);
31531                     return NULL;
31532                 }
31533                 XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
31534                 pkey->type = EVP_PKEY_EC;
31535                 if (out != NULL) {
31536                     *out = pkey;
31537                 }
31538                 return pkey;
31539             }
31540         }
31541         wc_ecc_free(&ecc);
31542     }
31543     #endif /* HAVE_ECC */
31544     return pkey;
31545 }
31546 #endif /* OPENSSL_ALL || WOLFSSL_ASIO */
31547 
31548 
31549 /* stunnel compatibility functions*/
31550 #if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) \
31551                           || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)))
31552 void wolfSSL_ERR_remove_thread_state(void* pid)
31553 {
31554     (void) pid;
31555     return;
31556 }
31557 
31558 #ifndef NO_FILESYSTEM
31559 /***TBD ***/
31560 void wolfSSL_print_all_errors_fp(XFILE *fp)
31561 {
31562     (void)fp;
31563 }
31564 #endif
31565 
31566 int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION* session, int idx, void* data)
31567 {
31568     WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data");
31569 #ifdef HAVE_EX_DATA
31570     if(session != NULL && idx < MAX_EX_DATA) {
31571         session->ex_data[idx] = data;
31572         return WOLFSSL_SUCCESS;
31573     }
31574 #else
31575     (void)session;
31576     (void)idx;
31577     (void)data;
31578 #endif
31579     return WOLFSSL_FAILURE;
31580 }
31581 
31582 
31583 int wolfSSL_SESSION_get_ex_new_index(long idx, void* data, void* cb1,
31584        void* cb2, CRYPTO_free_func* cb3)
31585 {
31586     WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_new_index");
31587     (void)idx;
31588     (void)cb1;
31589     (void)cb2;
31590     (void)cb3;
31591     if (XSTRNCMP((const char*)data, "redirect index", 14) == 0) {
31592         return 0;
31593     }
31594     else if (XSTRNCMP((const char*)data, "addr index", 10) == 0) {
31595         return 1;
31596     }
31597     return WOLFSSL_FAILURE;
31598 }
31599 
31600 
31601 void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION* session, int idx)
31602 {
31603     WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_data");
31604 #ifdef HAVE_EX_DATA
31605     if (session != NULL && idx < MAX_EX_DATA && idx >= 0)
31606         return session->ex_data[idx];
31607 #else
31608     (void)session;
31609     (void)idx;
31610 #endif
31611     return NULL;
31612 }
31613 
31614 #ifndef NO_WOLFSSL_STUB
31615 int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
31616                                 void *(*r) (void *, size_t, const char *,
31617                                             int), void (*f) (void *))
31618 {
31619     (void) m;
31620     (void) r;
31621     (void) f;
31622     WOLFSSL_ENTER("wolfSSL_CRYPTO_set_mem_ex_functions");
31623     WOLFSSL_STUB("CRYPTO_set_mem_ex_functions");
31624 
31625     return WOLFSSL_FAILURE;
31626 }
31627 #endif
31628 
31629 
31630 void wolfSSL_CRYPTO_cleanup_all_ex_data(void){
31631     WOLFSSL_ENTER("CRYPTO_cleanup_all_ex_data");
31632 }
31633 
31634 
31635 #ifndef NO_WOLFSSL_STUB
31636 WOLFSSL_DH *wolfSSL_DH_generate_parameters(int prime_len, int generator,
31637                            void (*callback) (int, int, void *), void *cb_arg)
31638 {
31639     (void)prime_len;
31640     (void)generator;
31641     (void)callback;
31642     (void)cb_arg;
31643     WOLFSSL_ENTER("wolfSSL_DH_generate_parameters");
31644     WOLFSSL_STUB("DH_generate_parameters");
31645 
31646     return NULL;
31647 }
31648 #endif
31649 
31650 #ifndef NO_WOLFSSL_STUB
31651 int wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH* dh, int prime_len, int generator,
31652                            void (*callback) (int, int, void *))
31653 {
31654     (void)prime_len;
31655     (void)generator;
31656     (void)callback;
31657     (void)dh;
31658     WOLFSSL_ENTER("wolfSSL_DH_generate_parameters_ex");
31659     WOLFSSL_STUB("DH_generate_parameters_ex");
31660 
31661     return -1;
31662 }
31663 #endif
31664 
31665 void wolfSSL_ERR_load_crypto_strings(void)
31666 {
31667     WOLFSSL_ENTER("wolfSSL_ERR_load_crypto_strings");
31668     /* Do nothing */
31669     return;
31670 }
31671 
31672 #ifndef NO_WOLFSSL_STUB
31673 unsigned long wolfSSL_ERR_peek_last_error(void)
31674 {
31675     WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
31676 
31677 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
31678     {
31679         int ret;
31680 
31681         if ((ret = wc_PeekErrorNode(-1, NULL, NULL, NULL)) < 0) {
31682             WOLFSSL_MSG("Issue peeking at error node in queue");
31683             return 0;
31684         }
31685         if (ret == -ASN_NO_PEM_HEADER)
31686             return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
31687         return (unsigned long)ret;
31688     }
31689 #else
31690     return (unsigned long)(0 - NOT_COMPILED_IN);
31691 #endif
31692 }
31693 #endif
31694 
31695 #ifndef NO_WOLFSSL_STUB
31696 int wolfSSL_FIPS_mode(void)
31697 {
31698     WOLFSSL_ENTER("wolfSSL_FIPS_mode");
31699     WOLFSSL_STUB("FIPS_mode");
31700 
31701     return WOLFSSL_FAILURE;
31702 }
31703 #endif
31704 
31705 #ifndef NO_WOLFSSL_STUB
31706 int wolfSSL_FIPS_mode_set(int r)
31707 {
31708     (void)r;
31709     WOLFSSL_ENTER("wolfSSL_FIPS_mode_set");
31710     WOLFSSL_STUB("FIPS_mode_set");
31711 
31712     return WOLFSSL_FAILURE;
31713 }
31714 #endif
31715 
31716 #ifndef NO_WOLFSSL_STUB
31717 int wolfSSL_RAND_set_rand_method(const void *meth)
31718 {
31719     (void) meth;
31720     WOLFSSL_ENTER("wolfSSL_RAND_set_rand_method");
31721     WOLFSSL_STUB("RAND_set_rand_method");
31722 
31723     /* if implemented RAND_bytes and RAND_pseudo_bytes need updated
31724      * those two functions will call the respective functions from meth */
31725     return SSL_FAILURE;
31726 }
31727 #endif
31728 
31729 int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits)
31730 {
31731     int ret = WOLFSSL_FAILURE;
31732     WOLFSSL_ENTER("wolfSSL_CIPHER_get_bits");
31733     if(c != NULL && c->ssl != NULL) {
31734         ret = 8 * c->ssl->specs.key_size;
31735         if(alg_bits != NULL) {
31736             *alg_bits = ret;
31737         }
31738     }
31739     return ret;
31740 }
31741 
31742 int wolfSSL_sk_X509_NAME_num(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *s)
31743 {
31744     WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_num");
31745 
31746     if (s == NULL)
31747         return -1;
31748     return (int)s->num;
31749 }
31750 
31751 
31752 int wolfSSL_sk_X509_num(const WOLF_STACK_OF(WOLFSSL_X509) *s)
31753 {
31754     WOLFSSL_ENTER("wolfSSL_sk_X509_num");
31755 
31756     if (s == NULL)
31757         return -1;
31758     return (int)s->num;
31759 }
31760 
31761 int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
31762                 int indent, unsigned long flags)
31763 {
31764     int i;
31765     (void)flags;
31766     WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex");
31767 
31768     for (i = 0; i < indent; i++) {
31769         if (wolfSSL_BIO_write(bio, " ", 1) != 1)
31770             return WOLFSSL_FAILURE;
31771     }
31772 
31773     if (flags == XN_FLAG_RFC2253) {
31774         if (wolfSSL_BIO_write(bio, name->name + 1, name->sz - 2)
31775                                                                 != name->sz - 2)
31776             return WOLFSSL_FAILURE;
31777     }
31778     else if (wolfSSL_BIO_write(bio, name->name, name->sz) != name->sz)
31779         return WOLFSSL_FAILURE;
31780 
31781     return WOLFSSL_SUCCESS;
31782 }
31783 
31784 #ifndef NO_WOLFSSL_STUB
31785 WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr(const WOLFSSL_X509* x)
31786 {
31787     (void)x;
31788     WOLFSSL_ENTER("wolfSSL_X509_get0_pubkey_bitstr");
31789     WOLFSSL_STUB("X509_get0_pubkey_bitstr");
31790 
31791     return NULL;
31792 }
31793 #endif
31794 
31795 #ifndef NO_WOLFSSL_STUB
31796 int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
31797 {
31798     (void)ctx;
31799     (void)session;
31800     WOLFSSL_ENTER("wolfSSL_CTX_add_session");
31801     WOLFSSL_STUB("SSL_CTX_add_session");
31802 
31803     return WOLFSSL_SUCCESS;
31804 }
31805 #endif
31806 
31807 
31808 int wolfSSL_version(WOLFSSL* ssl)
31809 {
31810     WOLFSSL_ENTER("wolfSSL_version");
31811     if (ssl->version.major == SSLv3_MAJOR) {
31812         switch (ssl->version.minor) {
31813             case SSLv3_MINOR :
31814                 return SSL3_VERSION;
31815             case TLSv1_MINOR :
31816             case TLSv1_1_MINOR :
31817             case TLSv1_2_MINOR :
31818             case TLSv1_3_MINOR :
31819                 return TLS1_VERSION;
31820             default:
31821                 return WOLFSSL_FAILURE;
31822         }
31823     }
31824     else if (ssl->version.major == DTLS_MAJOR) {
31825         switch (ssl->version.minor) {
31826             case DTLS_MINOR :
31827             case DTLSv1_2_MINOR :
31828                 return DTLS1_VERSION;
31829             default:
31830                 return WOLFSSL_FAILURE;
31831         }
31832     }
31833     return WOLFSSL_FAILURE;
31834 }
31835 
31836 
31837 WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl)
31838 {
31839     WOLFSSL_ENTER("wolfSSL_get_SSL_CTX");
31840     return ssl->ctx;
31841 }
31842 
31843 int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME* name)
31844 {
31845     WOLFSSL_ENTER("wolfSSL_X509_NAME_get_sz");
31846     if(!name)
31847         return -1;
31848     return name->sz;
31849 }
31850 
31851 #ifdef HAVE_SNI
31852 int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name)
31853 {
31854     int ret;
31855     WOLFSSL_ENTER("wolfSSL_set_tlsext_host_name");
31856     ret = wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME,
31857             host_name, (word16)XSTRLEN(host_name));
31858     WOLFSSL_LEAVE("wolfSSL_set_tlsext_host_name", ret);
31859     return ret;
31860 }
31861 
31862 
31863 #ifndef NO_WOLFSSL_SERVER
31864 const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type)
31865 {
31866     void * serverName = NULL;
31867     if (ssl == NULL)
31868         return NULL;
31869     TLSX_SNI_GetRequest(ssl->extensions, type, &serverName);
31870     return (const char *)serverName;
31871 }
31872 #endif /* NO_WOLFSSL_SERVER */
31873 #endif /* HAVE_SNI */
31874 
31875 WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
31876 {
31877     if (ssl && ctx && SetSSL_CTX(ssl, ctx, 0) == WOLFSSL_SUCCESS)
31878         return ssl->ctx;
31879     return NULL;
31880 }
31881 
31882 
31883 VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX* ctx)
31884 {
31885     WOLFSSL_ENTER("wolfSSL_CTX_get_verify_callback");
31886     if(ctx)
31887         return ctx->verifyCallback;
31888     return NULL;
31889 }
31890 
31891 
31892 void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
31893 {
31894     WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
31895     if (ctx)
31896         ctx->sniRecvCb = cb;
31897 }
31898 
31899 int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
31900                                                CallbackSniRecv cb)
31901 {
31902     WOLFSSL_ENTER("wolfSSL_CTX_set_tlsext_servername_callback");
31903     if (ctx) {
31904         ctx->sniRecvCb = cb;
31905         return 1;
31906     }
31907     return 0;
31908 }
31909 
31910 void wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
31911 {
31912     WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
31913     if (ctx)
31914         ctx->sniRecvCbArg = arg;
31915 }
31916 
31917 void wolfSSL_ERR_load_BIO_strings(void) {
31918     WOLFSSL_ENTER("ERR_load_BIO_strings");
31919     /* do nothing */
31920 }
31921 
31922 #ifndef NO_WOLFSSL_STUB
31923 void wolfSSL_THREADID_set_callback(void(*threadid_func)(void*))
31924 {
31925     WOLFSSL_ENTER("wolfSSL_THREADID_set_callback");
31926     WOLFSSL_STUB("CRYPTO_THREADID_set_callback");
31927     (void)threadid_func;
31928     return;
31929 }
31930 #endif
31931 
31932 #ifndef NO_WOLFSSL_STUB
31933 void wolfSSL_THREADID_set_numeric(void* id, unsigned long val)
31934 {
31935     WOLFSSL_ENTER("wolfSSL_THREADID_set_numeric");
31936     WOLFSSL_STUB("CRYPTO_THREADID_set_numeric");
31937     (void)id;
31938     (void)val;
31939     return;
31940 }
31941 #endif
31942 
31943 
31944 #ifndef NO_WOLFSSL_STUB
31945 WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs(WOLFSSL_X509_STORE_CTX* ctx,
31946                                                 WOLFSSL_X509_NAME* name)
31947 {
31948     WOLFSSL_ENTER("wolfSSL_X509_STORE_get1_certs");
31949     WOLFSSL_STUB("X509_STORE_get1_certs");
31950     (void)ctx;
31951     (void)name;
31952     return NULL;
31953 }
31954 #endif
31955 
31956 #endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_LIGHTY)) */
31957 
31958 
31959 #if defined(OPENSSL_ALL) || \
31960     (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \
31961      defined(WOLFSSL_NGINX)) || defined(WOLFSSL_HAPROXY))
31962 
31963 const byte* wolfSSL_SESSION_get_id(WOLFSSL_SESSION* sess, unsigned int* idLen)
31964 {
31965     WOLFSSL_ENTER("wolfSSL_SESSION_get_id");
31966     if(!sess || !idLen) {
31967         WOLFSSL_MSG("Bad func args. Please provide idLen");
31968         return NULL;
31969     }
31970     *idLen = sess->sessionIDSz;
31971     return sess->sessionID;
31972 }
31973 #endif
31974 
31975 #if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && defined(HAVE_STUNNEL)) \
31976     || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
31977 
31978 int wolfSSL_CTX_get_verify_mode(WOLFSSL_CTX* ctx)
31979 {
31980     int mode = 0;
31981     WOLFSSL_ENTER("wolfSSL_CTX_get_verify_mode");
31982 
31983     if(!ctx)
31984         return WOLFSSL_FATAL_ERROR;
31985 
31986     if (ctx->verifyPeer)
31987         mode |= WOLFSSL_VERIFY_PEER;
31988     else if (ctx->verifyNone)
31989         mode |= WOLFSSL_VERIFY_NONE;
31990 
31991     if (ctx->failNoCert)
31992         mode |= WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
31993 
31994     if (ctx->failNoCertxPSK)
31995         mode |= WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
31996 
31997     WOLFSSL_LEAVE("wolfSSL_CTX_get_verify_mode", mode);
31998     return mode;
31999 }
32000 #endif
32001 
32002 #if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE25519)
32003 /* return 1 if success, 0 if error
32004  * output keys are little endian format
32005  */
32006 int wolfSSL_EC25519_generate_key(unsigned char *priv, unsigned int *privSz,
32007                                  unsigned char *pub, unsigned int *pubSz)
32008 {
32009 #ifndef WOLFSSL_KEY_GEN
32010     WOLFSSL_MSG("No Key Gen built in");
32011     (void) priv;
32012     (void) privSz;
32013     (void) pub;
32014     (void) pubSz;
32015     return WOLFSSL_FAILURE;
32016 #else /* WOLFSSL_KEY_GEN */
32017     int ret = WOLFSSL_FAILURE;
32018     int initTmpRng = 0;
32019     WC_RNG *rng = NULL;
32020 #ifdef WOLFSSL_SMALL_STACK
32021     WC_RNG *tmpRNG = NULL;
32022 #else
32023     WC_RNG tmpRNG[1];
32024 #endif
32025 
32026     WOLFSSL_ENTER("wolfSSL_EC25519_generate_key");
32027 
32028     if (priv == NULL || privSz == NULL || *privSz < CURVE25519_KEYSIZE ||
32029         pub == NULL || pubSz == NULL || *pubSz < CURVE25519_KEYSIZE) {
32030         WOLFSSL_MSG("Bad arguments");
32031         return WOLFSSL_FAILURE;
32032     }
32033 
32034 #ifdef WOLFSSL_SMALL_STACK
32035     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
32036     if (tmpRNG == NULL)
32037         return WOLFSSL_FAILURE;
32038 #endif
32039     if (wc_InitRng(tmpRNG) == 0) {
32040         rng = tmpRNG;
32041         initTmpRng = 1;
32042     }
32043     else {
32044         WOLFSSL_MSG("Bad RNG Init, trying global");
32045         if (initGlobalRNG == 0)
32046             WOLFSSL_MSG("Global RNG no Init");
32047         else
32048             rng = &globalRNG;
32049     }
32050 
32051     if (rng) {
32052         curve25519_key key;
32053 
32054         if (wc_curve25519_init(&key) != MP_OKAY)
32055             WOLFSSL_MSG("wc_curve25519_init failed");
32056         else if (wc_curve25519_make_key(rng, CURVE25519_KEYSIZE, &key)!=MP_OKAY)
32057             WOLFSSL_MSG("wc_curve25519_make_key failed");
32058         /* export key pair */
32059         else if (wc_curve25519_export_key_raw_ex(&key, priv, privSz, pub,
32060                                                  pubSz, EC25519_LITTLE_ENDIAN)
32061                  != MP_OKAY)
32062             WOLFSSL_MSG("wc_curve25519_export_key_raw_ex failed");
32063         else
32064             ret = WOLFSSL_SUCCESS;
32065 
32066         wc_curve25519_free(&key);
32067     }
32068 
32069     if (initTmpRng)
32070         wc_FreeRng(tmpRNG);
32071 
32072 #ifdef WOLFSSL_SMALL_STACK
32073     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
32074 #endif
32075 
32076     return ret;
32077 #endif /* WOLFSSL_KEY_GEN */
32078 }
32079 
32080 /* return 1 if success, 0 if error
32081  * input and output keys are little endian format
32082  */
32083 int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz,
32084                                const unsigned char *priv, unsigned int privSz,
32085                                const unsigned char *pub, unsigned int pubSz)
32086 {
32087 #ifndef WOLFSSL_KEY_GEN
32088     WOLFSSL_MSG("No Key Gen built in");
32089     (void) shared;
32090     (void) sharedSz;
32091     (void) priv;
32092     (void) privSz;
32093     (void) pub;
32094     (void) pubSz;
32095     return WOLFSSL_FAILURE;
32096 #else /* WOLFSSL_KEY_GEN */
32097     int ret = WOLFSSL_FAILURE;
32098     curve25519_key privkey, pubkey;
32099 
32100     WOLFSSL_ENTER("wolfSSL_EC25519_shared_key");
32101 
32102     if (shared == NULL || sharedSz == NULL || *sharedSz < CURVE25519_KEYSIZE ||
32103         priv == NULL || privSz < CURVE25519_KEYSIZE ||
32104         pub == NULL || pubSz < CURVE25519_KEYSIZE) {
32105         WOLFSSL_MSG("Bad arguments");
32106         return WOLFSSL_FAILURE;
32107     }
32108 
32109     /* import private key */
32110     if (wc_curve25519_init(&privkey) != MP_OKAY) {
32111         WOLFSSL_MSG("wc_curve25519_init privkey failed");
32112         return ret;
32113     }
32114     if (wc_curve25519_import_private_ex(priv, privSz, &privkey,
32115                                         EC25519_LITTLE_ENDIAN) != MP_OKAY) {
32116         WOLFSSL_MSG("wc_curve25519_import_private_ex failed");
32117         wc_curve25519_free(&privkey);
32118         return ret;
32119     }
32120 
32121     /* import public key */
32122     if (wc_curve25519_init(&pubkey) != MP_OKAY) {
32123         WOLFSSL_MSG("wc_curve25519_init pubkey failed");
32124         wc_curve25519_free(&privkey);
32125         return ret;
32126     }
32127     if (wc_curve25519_import_public_ex(pub, pubSz, &pubkey,
32128                                        EC25519_LITTLE_ENDIAN) != MP_OKAY) {
32129         WOLFSSL_MSG("wc_curve25519_import_public_ex failed");
32130         wc_curve25519_free(&privkey);
32131         wc_curve25519_free(&pubkey);
32132         return ret;
32133     }
32134 
32135     if (wc_curve25519_shared_secret_ex(&privkey, &pubkey,
32136                                        shared, sharedSz,
32137                                        EC25519_LITTLE_ENDIAN) != MP_OKAY)
32138         WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
32139     else
32140         ret = WOLFSSL_SUCCESS;
32141 
32142     wc_curve25519_free(&privkey);
32143     wc_curve25519_free(&pubkey);
32144 
32145     return ret;
32146 #endif /* WOLFSSL_KEY_GEN */
32147 }
32148 #endif /* OPENSSL_EXTRA && HAVE_CURVE25519 */
32149 
32150 #if defined(OPENSSL_EXTRA) && defined(HAVE_ED25519)
32151 /* return 1 if success, 0 if error
32152  * output keys are little endian format
32153  */
32154 int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz,
32155                                  unsigned char *pub, unsigned int *pubSz)
32156 {
32157 #ifndef WOLFSSL_KEY_GEN
32158     WOLFSSL_MSG("No Key Gen built in");
32159     (void) priv;
32160     (void) privSz;
32161     (void) pub;
32162     (void) pubSz;
32163     return WOLFSSL_FAILURE;
32164 #else /* WOLFSSL_KEY_GEN */
32165     int ret = WOLFSSL_FAILURE;
32166     int initTmpRng = 0;
32167     WC_RNG *rng = NULL;
32168 #ifdef WOLFSSL_SMALL_STACK
32169     WC_RNG *tmpRNG = NULL;
32170 #else
32171     WC_RNG tmpRNG[1];
32172 #endif
32173 
32174     WOLFSSL_ENTER("wolfSSL_ED25519_generate_key");
32175 
32176     if (priv == NULL || privSz == NULL || *privSz < ED25519_PRV_KEY_SIZE ||
32177         pub == NULL || pubSz == NULL || *pubSz < ED25519_PUB_KEY_SIZE) {
32178         WOLFSSL_MSG("Bad arguments");
32179         return WOLFSSL_FAILURE;
32180     }
32181 
32182 #ifdef WOLFSSL_SMALL_STACK
32183     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
32184     if (tmpRNG == NULL)
32185         return WOLFSSL_FATAL_ERROR;
32186 #endif
32187     if (wc_InitRng(tmpRNG) == 0) {
32188         rng = tmpRNG;
32189         initTmpRng = 1;
32190     }
32191     else {
32192         WOLFSSL_MSG("Bad RNG Init, trying global");
32193         if (initGlobalRNG == 0)
32194             WOLFSSL_MSG("Global RNG no Init");
32195         else
32196             rng = &globalRNG;
32197     }
32198 
32199     if (rng) {
32200         ed25519_key key;
32201 
32202         if (wc_ed25519_init(&key) != MP_OKAY)
32203             WOLFSSL_MSG("wc_ed25519_init failed");
32204         else if (wc_ed25519_make_key(rng, ED25519_KEY_SIZE, &key)!=MP_OKAY)
32205             WOLFSSL_MSG("wc_ed25519_make_key failed");
32206         /* export private key */
32207         else if (wc_ed25519_export_key(&key, priv, privSz, pub, pubSz)!=MP_OKAY)
32208             WOLFSSL_MSG("wc_ed25519_export_key failed");
32209         else
32210             ret = WOLFSSL_SUCCESS;
32211 
32212         wc_ed25519_free(&key);
32213     }
32214 
32215     if (initTmpRng)
32216         wc_FreeRng(tmpRNG);
32217 
32218 #ifdef WOLFSSL_SMALL_STACK
32219     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
32220 #endif
32221 
32222     return ret;
32223 #endif /* WOLFSSL_KEY_GEN */
32224 }
32225 
32226 /* return 1 if success, 0 if error
32227  * input and output keys are little endian format
32228  * priv is a buffer containing private and public part of key
32229  */
32230 int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
32231                          const unsigned char *priv, unsigned int privSz,
32232                          unsigned char *sig, unsigned int *sigSz)
32233 {
32234 #ifndef WOLFSSL_KEY_GEN
32235     WOLFSSL_MSG("No Key Gen built in");
32236     (void) msg;
32237     (void) msgSz;
32238     (void) priv;
32239     (void) privSz;
32240     (void) sig;
32241     (void) sigSz;
32242     return WOLFSSL_FAILURE;
32243 #else /* WOLFSSL_KEY_GEN */
32244     ed25519_key key;
32245     int ret = WOLFSSL_FAILURE;
32246 
32247     WOLFSSL_ENTER("wolfSSL_ED25519_sign");
32248 
32249     if (priv == NULL || privSz != ED25519_PRV_KEY_SIZE ||
32250         msg == NULL || sig == NULL || *sigSz < ED25519_SIG_SIZE) {
32251         WOLFSSL_MSG("Bad arguments");
32252         return WOLFSSL_FAILURE;
32253     }
32254 
32255     /* import key */
32256     if (wc_ed25519_init(&key) != MP_OKAY) {
32257         WOLFSSL_MSG("wc_curve25519_init failed");
32258         return ret;
32259     }
32260     if (wc_ed25519_import_private_key(priv, privSz/2,
32261                                       priv+(privSz/2), ED25519_PUB_KEY_SIZE,
32262                                       &key) != MP_OKAY){
32263         WOLFSSL_MSG("wc_ed25519_import_private failed");
32264         wc_ed25519_free(&key);
32265         return ret;
32266     }
32267 
32268     if (wc_ed25519_sign_msg(msg, msgSz, sig, sigSz, &key) != MP_OKAY)
32269         WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
32270     else
32271         ret = WOLFSSL_SUCCESS;
32272 
32273     wc_ed25519_free(&key);
32274 
32275     return ret;
32276 #endif /* WOLFSSL_KEY_GEN */
32277 }
32278 
32279 /* return 1 if success, 0 if error
32280  * input and output keys are little endian format
32281  * pub is a buffer containing public part of key
32282  */
32283 int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
32284                            const unsigned char *pub, unsigned int pubSz,
32285                            const unsigned char *sig, unsigned int sigSz)
32286 {
32287 #ifndef WOLFSSL_KEY_GEN
32288     WOLFSSL_MSG("No Key Gen built in");
32289     (void) msg;
32290     (void) msgSz;
32291     (void) pub;
32292     (void) pubSz;
32293     (void) sig;
32294     (void) sigSz;
32295     return WOLFSSL_FAILURE;
32296 #else /* WOLFSSL_KEY_GEN */
32297     ed25519_key key;
32298     int ret = WOLFSSL_FAILURE, check = 0;
32299 
32300     WOLFSSL_ENTER("wolfSSL_ED25519_verify");
32301 
32302     if (pub == NULL || pubSz != ED25519_PUB_KEY_SIZE ||
32303         msg == NULL || sig == NULL || sigSz != ED25519_SIG_SIZE) {
32304         WOLFSSL_MSG("Bad arguments");
32305         return WOLFSSL_FAILURE;
32306     }
32307 
32308     /* import key */
32309     if (wc_ed25519_init(&key) != MP_OKAY) {
32310         WOLFSSL_MSG("wc_curve25519_init failed");
32311         return ret;
32312     }
32313     if (wc_ed25519_import_public(pub, pubSz, &key) != MP_OKAY){
32314         WOLFSSL_MSG("wc_ed25519_import_public failed");
32315         wc_ed25519_free(&key);
32316         return ret;
32317     }
32318 
32319     if ((ret = wc_ed25519_verify_msg((byte*)sig, sigSz, msg, msgSz,
32320                                      &check, &key)) != MP_OKAY) {
32321         WOLFSSL_MSG("wc_ed25519_verify_msg failed");
32322     }
32323     else if (!check)
32324         WOLFSSL_MSG("wc_ed25519_verify_msg failed (signature invalid)");
32325     else
32326         ret = WOLFSSL_SUCCESS;
32327 
32328     wc_ed25519_free(&key);
32329 
32330     return ret;
32331 #endif /* WOLFSSL_KEY_GEN */
32332 }
32333 
32334 #endif /* OPENSSL_EXTRA && HAVE_ED25519 */
32335 
32336 #ifdef WOLFSSL_JNI
32337 
32338 int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr)
32339 {
32340     WOLFSSL_ENTER("wolfSSL_set_jobject");
32341     if (ssl != NULL)
32342     {
32343         ssl->jObjectRef = objPtr;
32344         return WOLFSSL_SUCCESS;
32345     }
32346     return WOLFSSL_FAILURE;
32347 }
32348 
32349 void* wolfSSL_get_jobject(WOLFSSL* ssl)
32350 {
32351     WOLFSSL_ENTER("wolfSSL_get_jobject");
32352     if (ssl != NULL)
32353         return ssl->jObjectRef;
32354     return NULL;
32355 }
32356 
32357 #endif /* WOLFSSL_JNI */
32358 
32359 
32360 #ifdef WOLFSSL_ASYNC_CRYPT
32361 int wolfSSL_CTX_AsyncPoll(WOLFSSL_CTX* ctx, WOLF_EVENT** events, int maxEvents,
32362     WOLF_EVENT_FLAG flags, int* eventCount)
32363 {
32364     if (ctx == NULL) {
32365         return BAD_FUNC_ARG;
32366     }
32367 
32368     return wolfAsync_EventQueuePoll(&ctx->event_queue, NULL,
32369                                         events, maxEvents, flags, eventCount);
32370 }
32371 
32372 int wolfSSL_AsyncPoll(WOLFSSL* ssl, WOLF_EVENT_FLAG flags)
32373 {
32374     int ret, eventCount = 0;
32375     WOLF_EVENT* events[1];
32376 
32377     if (ssl == NULL) {
32378         return BAD_FUNC_ARG;
32379     }
32380 
32381     ret = wolfAsync_EventQueuePoll(&ssl->ctx->event_queue, ssl,
32382         events, sizeof(events)/sizeof(events), flags, &eventCount);
32383     if (ret == 0) {
32384         ret = eventCount;
32385     }
32386 
32387     return ret;
32388 }
32389 
32390 #endif /* WOLFSSL_ASYNC_CRYPT */
32391 
32392 #ifdef OPENSSL_EXTRA
32393 unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line,
32394                                                const char **data, int *flags)
32395 {
32396     WOLFSSL_ENTER("wolfSSL_ERR_peek_error_line_data");
32397 
32398     (void)line;
32399     (void)file;
32400 
32401     /* No data or flags stored - error display only in Nginx. */
32402     if (data != NULL) {
32403         *data = "";
32404     }
32405     if (flags != NULL) {
32406         *flags = 0;
32407     }
32408 
32409 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
32410     defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_MYSQL_COMPATIBLE)
32411     {
32412         int ret = 0;
32413 
32414         while (1) {
32415             if ((ret = wc_PeekErrorNode(-1, file, NULL, line)) < 0) {
32416                 WOLFSSL_MSG("Issue peeking at error node in queue");
32417                 return 0;
32418             }
32419             ret = -ret;
32420 
32421             if (ret == ASN_NO_PEM_HEADER)
32422                 return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
32423             if (ret != WANT_READ && ret != WANT_WRITE &&
32424                     ret != ZERO_RETURN && ret != WOLFSSL_ERROR_ZERO_RETURN &&
32425                     ret != SOCKET_PEER_CLOSED_E && ret != SOCKET_ERROR_E)
32426                 break;
32427 
32428             wc_RemoveErrorNode(-1);
32429         }
32430 
32431         return (unsigned long)ret;
32432     }
32433 #else
32434     return (unsigned long)(0 - NOT_COMPILED_IN);
32435 #endif
32436 }
32437 #endif
32438 
32439 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
32440 
32441 #ifndef NO_WOLFSSL_STUB
32442 WOLF_STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl)
32443 {
32444     (void)ssl;
32445     WOLFSSL_STUB("wolfSSL_get_ciphers_compat");
32446     return NULL;
32447 }
32448 #endif
32449 
32450 #ifndef NO_WOLFSSL_STUB
32451 void wolfSSL_OPENSSL_config(char *config_name)
32452 {
32453     (void)config_name;
32454     WOLFSSL_STUB("OPENSSL_config");
32455 }
32456 #endif
32457 #endif
32458 
32459 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
32460     || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
32461 int wolfSSL_X509_get_ex_new_index(int idx, void *arg, void *a, void *b, void *c)
32462 {
32463     static int x509_idx = 0;
32464 
32465     WOLFSSL_ENTER("wolfSSL_X509_get_ex_new_index");
32466     (void)idx;
32467     (void)arg;
32468     (void)a;
32469     (void)b;
32470     (void)c;
32471 
32472     return x509_idx++;
32473 }
32474 
32475 void *wolfSSL_X509_get_ex_data(X509 *x509, int idx)
32476 {
32477     WOLFSSL_ENTER("wolfSSL_X509_get_ex_data");
32478     #ifdef HAVE_EX_DATA
32479     if (x509 != NULL && idx < MAX_EX_DATA && idx >= 0) {
32480         return x509->ex_data[idx];
32481     }
32482     #else
32483     (void)x509;
32484     (void)idx;
32485     #endif
32486     return NULL;
32487 }
32488 int wolfSSL_X509_set_ex_data(X509 *x509, int idx, void *data)
32489 {
32490     WOLFSSL_ENTER("wolfSSL_X509_set_ex_data");
32491     #ifdef HAVE_EX_DATA
32492     if (x509 != NULL && idx < MAX_EX_DATA)
32493     {
32494         x509->ex_data[idx] = data;
32495         return WOLFSSL_SUCCESS;
32496     }
32497     #else
32498     (void)x509;
32499     (void)idx;
32500     (void)data;
32501     #endif
32502     return WOLFSSL_FAILURE;
32503 }
32504 int wolfSSL_X509_NAME_digest(const WOLFSSL_X509_NAME *name,
32505         const WOLFSSL_EVP_MD *type, unsigned char *md, unsigned int *len)
32506 {
32507     WOLFSSL_ENTER("wolfSSL_X509_NAME_digest");
32508 
32509     if (name == NULL || type == NULL)
32510         return WOLFSSL_FAILURE;
32511 
32512 #ifndef NO_FILESYSTEM
32513     return wolfSSL_EVP_Digest((unsigned char*)name->fullName.fullName,
32514                               name->fullName.fullNameLen, md, len, type, NULL);
32515 #else
32516     (void)md;
32517     (void)len;
32518     return NOT_COMPILED_IN;
32519 #endif
32520 }
32521 
32522 long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx)
32523 {
32524     WOLFSSL_ENTER("wolfSSL_SSL_CTX_get_timeout");
32525 
32526     if (ctx == NULL)
32527         return 0;
32528 
32529     return ctx->timeout;
32530 }
32531 
32532 #ifdef HAVE_ECC
32533 int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx, WOLFSSL_EC_KEY *ecdh)
32534 {
32535     WOLFSSL_ENTER("wolfSSL_SSL_CTX_set_tmp_ecdh");
32536 
32537     if (ctx == NULL || ecdh == NULL)
32538         return BAD_FUNC_ARG;
32539 
32540     ctx->ecdhCurveOID = ecdh->group->curve_oid;
32541 
32542     return WOLFSSL_SUCCESS;
32543 }
32544 #endif
32545 
32546 /* Assumes that the session passed in is from the cache. */
32547 int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *s)
32548 {
32549     WOLFSSL_ENTER("wolfSSL_SSL_CTX_remove_session");
32550 
32551     if (ctx == NULL || s == NULL)
32552         return BAD_FUNC_ARG;
32553 
32554 #ifdef HAVE_EXT_CACHE
32555     if (!ctx->internalCacheOff)
32556 #endif
32557     {
32558         /* Don't remove session just timeout session. */
32559         s->timeout = 0;
32560     }
32561 
32562 #ifdef HAVE_EXT_CACHE
32563     if (ctx->rem_sess_cb != NULL)
32564         ctx->rem_sess_cb(ctx, s);
32565 #endif
32566 
32567     return 0;
32568 }
32569 
32570 BIO *wolfSSL_SSL_get_rbio(const WOLFSSL *s)
32571 {
32572     WOLFSSL_ENTER("wolfSSL_SSL_get_rbio");
32573     (void)s;
32574     /* Nginx sets the buffer size if the read BIO is different to write BIO.
32575      * The setting buffer size doesn't do anything so return NULL for both.
32576      */
32577     return NULL;
32578 }
32579 BIO *wolfSSL_SSL_get_wbio(const WOLFSSL *s)
32580 {
32581     WOLFSSL_ENTER("wolfSSL_SSL_get_wbio");
32582     (void)s;
32583     /* Nginx sets the buffer size if the read BIO is different to write BIO.
32584      * The setting buffer size doesn't do anything so return NULL for both.
32585      */
32586     return NULL;
32587 }
32588 
32589 int wolfSSL_SSL_do_handshake(WOLFSSL *s)
32590 {
32591     WOLFSSL_ENTER("wolfSSL_SSL_do_handshake");
32592 
32593     if (s == NULL)
32594         return WOLFSSL_FAILURE;
32595 
32596     if (s->options.side == WOLFSSL_CLIENT_END) {
32597     #ifndef NO_WOLFSSL_CLIENT
32598         return wolfSSL_connect(s);
32599     #else
32600         WOLFSSL_MSG("Client not compiled in");
32601         return WOLFSSL_FAILURE;
32602     #endif
32603     }
32604 
32605 #ifndef NO_WOLFSSL_SERVER
32606     return wolfSSL_accept(s);
32607 #else
32608     WOLFSSL_MSG("Server not compiled in");
32609     return WOLFSSL_FAILURE;
32610 #endif
32611 }
32612 
32613 int wolfSSL_SSL_in_init(WOLFSSL *s)
32614 {
32615     WOLFSSL_ENTER("wolfSSL_SSL_in_init");
32616 
32617     if (s == NULL)
32618         return WOLFSSL_FAILURE;
32619 
32620     if (s->options.side == WOLFSSL_CLIENT_END)
32621         return s->options.connectState < SECOND_REPLY_DONE;
32622     return s->options.acceptState < ACCEPT_THIRD_REPLY_DONE;
32623 }
32624 
32625 #ifndef NO_SESSION_CACHE
32626 
32627 WOLFSSL_SESSION *wolfSSL_SSL_get0_session(const WOLFSSL *ssl)
32628 {
32629     WOLFSSL_SESSION *session;
32630 
32631     WOLFSSL_ENTER("wolfSSL_SSL_get0_session");
32632 
32633     if (ssl == NULL) {
32634         return NULL;
32635     }
32636 
32637     session = wolfSSL_get_session((WOLFSSL*)ssl);
32638 
32639 #ifdef HAVE_EXT_CACHE
32640     ((WOLFSSL*)ssl)->extSession = session;
32641 #endif
32642 
32643     return session;
32644 }
32645 
32646 #endif /* NO_SESSION_CACHE */
32647 
32648 int wolfSSL_X509_check_host(X509 *x, const char *chk, size_t chklen,
32649                     unsigned int flags, char **peername)
32650 {
32651     int         ret;
32652     DecodedCert dCert;
32653 
32654     WOLFSSL_ENTER("wolfSSL_X509_check_host");
32655 
32656     /* flags and peername not needed for Nginx. */
32657     (void)flags;
32658     (void)peername;
32659 
32660     if (flags == WOLFSSL_NO_WILDCARDS) {
32661         WOLFSSL_MSG("X509_CHECK_FLAG_NO_WILDCARDS not yet implemented");
32662         return WOLFSSL_FAILURE;
32663     }
32664 
32665     InitDecodedCert(&dCert, x->derCert->buffer, x->derCert->length, NULL);
32666     ret = ParseCertRelative(&dCert, CERT_TYPE, 0, NULL);
32667     if (ret != 0)
32668         return WOLFSSL_FAILURE;
32669 
32670     ret = CheckHostName(&dCert, (char *)chk, chklen);
32671     FreeDecodedCert(&dCert);
32672     if (ret != 0)
32673         return WOLFSSL_FAILURE;
32674     return WOLFSSL_SUCCESS;
32675 }
32676 
32677 int wolfSSL_i2a_ASN1_INTEGER(BIO *bp, const WOLFSSL_ASN1_INTEGER *a)
32678 {
32679     static char num[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
32680                             '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
32681     int    i;
32682     word32 j;
32683     word32 len = 0;
32684 
32685     WOLFSSL_ENTER("wolfSSL_i2a_ASN1_INTEGER");
32686 
32687     if (bp == NULL || a == NULL)
32688         return WOLFSSL_FAILURE;
32689 
32690     /* Skip ASN.1 INTEGER (type) byte. */
32691     i = 1;
32692     /* When indefinte length, can't determine length with data available. */
32693     if (a->data[i] == 0x80)
32694         return 0;
32695     /* One length byte if less than 0x80. */
32696     if (a->data[i] < 0x80)
32697         len = a->data[i++];
32698     /* Multiple length byte if greater than 0x80. */
32699     else if (a->data[i] > 0x80) {
32700         switch (a->data[i++] - 0x80) {
32701             case 4:
32702                 len |= a->data[i++] << 24;
32703                 FALL_THROUGH;
32704             case 3:
32705                 len |= a->data[i++] << 16;
32706                 FALL_THROUGH;
32707             case 2:
32708                 len |= a->data[i++] <<  8;
32709                 FALL_THROUGH;
32710             case 1:
32711                 len |= a->data[i++];
32712                 break;
32713             default:
32714                 /* Not supporting greater than 4 bytes of length. */
32715                 return 0;
32716         }
32717     }
32718 
32719     /* Zero length integer is the value zero. */
32720     if (len == 0) {
32721         wolfSSL_BIO_write(bp, "00", 2);
32722         return 2;
32723     }
32724 
32725     /* Don't do negative - just write out every byte. */
32726     for (j = 0; j < len; i++,j++) {
32727         wolfSSL_BIO_write(bp, &num[a->data[i] >> 4], 1);
32728         wolfSSL_BIO_write(bp, &num[a->data[i] & 0xf], 1);
32729     }
32730 
32731     /* Two nibbles written for each byte. */
32732     return len * 2;
32733 }
32734 
32735 
32736 #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
32737 /* Expected return values from implementations of OpenSSL ticket key callback.
32738  */
32739 #define TICKET_KEY_CB_RET_FAILURE    -1
32740 #define TICKET_KEY_CB_RET_NOT_FOUND   0
32741 #define TICKET_KEY_CB_RET_OK          1
32742 #define TICKET_KEY_CB_RET_RENEW       2
32743 
32744 /* The ticket key callback as used in OpenSSL is stored here. */
32745 static int (*ticketKeyCb)(WOLFSSL *ssl, unsigned char *name, unsigned char *iv,
32746     WOLFSSL_EVP_CIPHER_CTX *ectx, WOLFSSL_HMAC_CTX *hctx, int enc) = NULL;
32747 
32748 /* Implementation of session ticket encryption/decryption using OpenSSL
32749  * callback to initialize the cipher and HMAC.
32750  *
32751  * ssl           The SSL/TLS object.
32752  * keyName       The key name - used to identify the key to be used.
32753  * iv            The IV to use.
32754  * mac           The MAC of the encrypted data.
32755  * enc           Encrypt ticket.
32756  * encTicket     The ticket data.
32757  * encTicketLen  The length of the ticket data.
32758  * encLen        The encrypted/decrypted ticket length - output length.
32759  * ctx           Ignored. Application specific data.
32760  * returns WOLFSSL_TICKET_RET_OK to indicate success,
32761  *         WOLFSSL_TICKET_RET_CREATE if a new ticket is required and
32762  *         WOLFSSL_TICKET_RET_FATAL on error.
32763  */
32764 static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
32765                                   unsigned char keyName[WOLFSSL_TICKET_NAME_SZ],
32766                                   unsigned char iv[WOLFSSL_TICKET_IV_SZ],
32767                                   unsigned char mac[WOLFSSL_TICKET_MAC_SZ],
32768                                   int enc, unsigned char* encTicket,
32769                                   int encTicketLen, int* encLen, void* ctx)
32770 {
32771     byte                    digest[WC_MAX_DIGEST_SIZE];
32772     WOLFSSL_EVP_CIPHER_CTX  evpCtx;
32773     WOLFSSL_HMAC_CTX        hmacCtx;
32774     unsigned int            mdSz = 0;
32775     int                     len = 0;
32776     int                     ret = WOLFSSL_TICKET_RET_FATAL;
32777     int                     res;
32778 
32779     (void)ctx;
32780 
32781     if (ticketKeyCb == NULL)
32782         return WOLFSSL_TICKET_RET_FATAL;
32783 
32784     wolfSSL_EVP_CIPHER_CTX_init(&evpCtx);
32785     /* Initialize the cipher and HMAC. */
32786     res = ticketKeyCb(ssl, keyName, iv, &evpCtx, &hmacCtx, enc);
32787     if (res != TICKET_KEY_CB_RET_OK && res != TICKET_KEY_CB_RET_RENEW)
32788         return WOLFSSL_TICKET_RET_FATAL;
32789 
32790     if (enc)
32791     {
32792         /* Encrypt in place. */
32793         if (!wolfSSL_EVP_CipherUpdate(&evpCtx, encTicket, &len,
32794                                       encTicket, encTicketLen))
32795             goto end;
32796         encTicketLen = len;
32797         if (!wolfSSL_EVP_EncryptFinal(&evpCtx, &encTicket[encTicketLen], &len))
32798             goto end;
32799         /* Total length of encrypted data. */
32800         encTicketLen += len;
32801         *encLen = encTicketLen;
32802 
32803         /* HMAC the encrypted data into the parameter 'mac'. */
32804         if (!wolfSSL_HMAC_Update(&hmacCtx, encTicket, encTicketLen))
32805             goto end;
32806 #ifdef WOLFSSL_SHA512
32807         /* Check for SHA512, which would overrun the mac buffer */
32808         if (hmacCtx.hmac.macType == WC_SHA512)
32809             goto end;
32810 #endif
32811         if (!wolfSSL_HMAC_Final(&hmacCtx, mac, &mdSz))
32812             goto end;
32813     }
32814     else
32815     {
32816         /* HMAC the encrypted data and compare it to the passed in data. */
32817         if (!wolfSSL_HMAC_Update(&hmacCtx, encTicket, encTicketLen))
32818             goto end;
32819         if (!wolfSSL_HMAC_Final(&hmacCtx, digest, &mdSz))
32820             goto end;
32821         if (XMEMCMP(mac, digest, mdSz) != 0)
32822             goto end;
32823 
32824         /* Decrypt the ticket data in place. */
32825         if (!wolfSSL_EVP_CipherUpdate(&evpCtx, encTicket, &len,
32826                                       encTicket, encTicketLen))
32827             goto end;
32828         encTicketLen = len;
32829         if (!wolfSSL_EVP_DecryptFinal(&evpCtx, &encTicket[encTicketLen], &len))
32830             goto end;
32831         /* Total length of decrypted data. */
32832         *encLen = encTicketLen + len;
32833     }
32834 
32835     ret = (res == TICKET_KEY_CB_RET_RENEW) ? WOLFSSL_TICKET_RET_CREATE :
32836                                              WOLFSSL_TICKET_RET_OK;
32837 end:
32838     return ret;
32839 }
32840 
32841 /* Set the callback to use when encrypting/decrypting tickets.
32842  *
32843  * ctx  The SSL/TLS context object.
32844  * cb   The OpenSSL session ticket callback.
32845  * returns WOLFSSL_SUCCESS to indicate success.
32846  */
32847 int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *ctx, int (*cb)(
32848     WOLFSSL *ssl, unsigned char *name, unsigned char *iv,
32849     WOLFSSL_EVP_CIPHER_CTX *ectx, WOLFSSL_HMAC_CTX *hctx, int enc))
32850 {
32851     /* Store callback in a global. */
32852     ticketKeyCb = cb;
32853     /* Set the ticket encryption callback to be a wrapper around OpenSSL
32854      * callback.
32855      */
32856     ctx->ticketEncCb = wolfSSL_TicketKeyCb;
32857 
32858     return WOLFSSL_SUCCESS;
32859 }
32860 #endif /* HAVE_SESSION_TICKET */
32861 
32862 #endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
32863     OPENSSL_EXTRA || HAVE_LIGHTY */
32864 
32865 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
32866 #ifdef HAVE_OCSP
32867 /* Not an OpenSSL API. */
32868 int wolfSSL_get_ocsp_response(WOLFSSL* ssl, byte** response)
32869 {
32870     *response = ssl->ocspResp;
32871     return ssl->ocspRespSz;
32872 }
32873 
32874 /* Not an OpenSSL API. */
32875 char* wolfSSL_get_ocsp_url(WOLFSSL* ssl)
32876 {
32877     return ssl->url;
32878 }
32879 
32880 /* Not an OpenSSL API. */
32881 int wolfSSL_set_ocsp_url(WOLFSSL* ssl, char* url)
32882 {
32883     if (ssl == NULL)
32884         return WOLFSSL_FAILURE;
32885 
32886     ssl->url = url;
32887     return WOLFSSL_SUCCESS;
32888 }
32889 #endif /* OCSP */
32890 #endif /* OPENSSL_ALL / WOLFSSL_NGINX  / WOLFSSL_HAPROXY */
32891 
32892 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
32893     defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
32894 int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, WOLF_STACK_OF(X509)** chain)
32895 {
32896     word32         idx;
32897     word32         length;
32898     WOLFSSL_STACK* node;
32899     WOLFSSL_STACK* last = NULL;
32900 
32901     if (ctx == NULL || chain == NULL) {
32902         chain = NULL;
32903         return WOLFSSL_FAILURE;
32904     }
32905     if (ctx->x509Chain != NULL) {
32906         *chain = ctx->x509Chain;
32907         return WOLFSSL_SUCCESS;
32908     }
32909 
32910     /* If there are no chains then success! */
32911     *chain = NULL;
32912     if (ctx->certChain == NULL || ctx->certChain->length == 0) {
32913         return WOLFSSL_SUCCESS;
32914     }
32915 
32916     /* Create a new stack of WOLFSSL_X509 object from chain buffer. */
32917     for (idx = 0; idx < ctx->certChain->length; ) {
32918         node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
32919                                        DYNAMIC_TYPE_OPENSSL);
32920         if (node == NULL)
32921             return WOLFSSL_FAILURE;
32922         node->next = NULL;
32923 
32924         /* 3 byte length | X509 DER data */
32925         ato24(ctx->certChain->buffer + idx, &length);
32926         idx += 3;
32927 
32928         /* Create a new X509 from DER encoded data. */
32929         node->data.x509 = wolfSSL_X509_d2i(NULL, ctx->certChain->buffer + idx,
32930             length);
32931         if (node->data.x509 == NULL) {
32932             XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
32933             /* Return as much of the chain as we created. */
32934             ctx->x509Chain = *chain;
32935             return WOLFSSL_FAILURE;
32936         }
32937         idx += length;
32938 
32939         /* Add object to the end of the stack. */
32940         if (last == NULL) {
32941             node->num = 1;
32942             *chain = node;
32943         }
32944         else {
32945             (*chain)->num++;
32946             last->next = node;
32947         }
32948 
32949         last = node;
32950     }
32951 
32952     ctx->x509Chain = *chain;
32953 
32954     return WOLFSSL_SUCCESS;
32955 }
32956 
32957 int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx,
32958     int(*cb)(WOLFSSL*, void*))
32959 {
32960     if (ctx == NULL || ctx->cm == NULL)
32961         return WOLFSSL_FAILURE;
32962 
32963 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
32964  || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
32965     /* Ensure stapling is on for callback to be used. */
32966     wolfSSL_CTX_EnableOCSPStapling(ctx);
32967 
32968     if (ctx->cm->ocsp_stapling == NULL)
32969         return WOLFSSL_FAILURE;
32970 
32971     ctx->cm->ocsp_stapling->statusCb = cb;
32972 #else
32973     (void)cb;
32974 #endif
32975 
32976     return WOLFSSL_SUCCESS;
32977 }
32978 
32979 int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer,
32980     WOLFSSL_X509_STORE_CTX *ctx, WOLFSSL_X509 *x)
32981 {
32982     WOLFSSL_STACK* node;
32983     Signer* ca = NULL;
32984 #ifdef WOLFSSL_SMALL_STACK
32985     DecodedCert* cert = NULL;
32986 #else
32987     DecodedCert  cert[1];
32988 #endif
32989 
32990     if (issuer == NULL || ctx == NULL || x == NULL)
32991         return WOLFSSL_FATAL_ERROR;
32992 
32993     if (ctx->chain != NULL) {
32994         for (node = ctx->chain; node != NULL; node = node->next) {
32995             if (wolfSSL_X509_check_issued(node->data.x509, x) == X509_V_OK) {
32996                 *issuer = x;
32997                 return WOLFSSL_SUCCESS;
32998             }
32999         }
33000     }
33001 
33002 
33003 #ifdef WOLFSSL_SMALL_STACK
33004     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
33005     if (cert == NULL)
33006         return WOLFSSL_FAILURE;
33007 #endif
33008 
33009     /* Use existing CA retrieval APIs that use DecodedCert. */
33010     InitDecodedCert(cert, x->derCert->buffer, x->derCert->length, NULL);
33011     if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
33012     #ifndef NO_SKID
33013         if (cert->extAuthKeyIdSet)
33014             ca = GetCA(ctx->store->cm, cert->extAuthKeyId);
33015         if (ca == NULL)
33016             ca = GetCAByName(ctx->store->cm, cert->issuerHash);
33017     #else /* NO_SKID */
33018         ca = GetCA(ctx->store->cm, cert->issuerHash);
33019     #endif /* NO SKID */
33020     }
33021     FreeDecodedCert(cert);
33022 #ifdef WOLFSSL_SMALL_STACK
33023     XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
33024 #endif
33025 
33026     if (ca == NULL)
33027         return WOLFSSL_FAILURE;
33028 
33029     *issuer = (WOLFSSL_X509 *)XMALLOC(sizeof(WOLFSSL_X509), 0,
33030         DYNAMIC_TYPE_OPENSSL);
33031     if (*issuer == NULL)
33032         return WOLFSSL_FAILURE;
33033 
33034     /* Create an empty certificate as CA doesn't have a certificate. */
33035     XMEMSET(*issuer, 0, sizeof(WOLFSSL_X509));
33036     (*issuer)->dynamicMemory = 1;
33037 #ifdef WOLFSSL_SIGNER_DER_CERT
33038     if (AllocDer(&(*issuer)->derCert, ca->derCert->length, ca->derCert->type,
33039                                                                    NULL) == 0) {
33040         XMEMCPY((*issuer)->derCert->buffer, ca->derCert->buffer,
33041                                                            ca->derCert->length);
33042     }
33043     else {
33044         XFREE(*issuer, 0, DYNAMIC_TYPE_OPENSSL);
33045         return WOLFSSL_FAILURE;
33046     }
33047 #endif
33048 
33049     /* Result is ignored when passed to wolfSSL_OCSP_cert_to_id(). */
33050 
33051     return WOLFSSL_SUCCESS;
33052 }
33053 
33054 void wolfSSL_X509_email_free(WOLF_STACK_OF(WOLFSSL_STRING) *sk)
33055 {
33056     WOLFSSL_STACK *curr;
33057 
33058     while (sk != NULL) {
33059         curr = sk;
33060         sk = sk->next;
33061 
33062         XFREE(curr, NULL, DYNAMIC_TYPE_OPENSSL);
33063     }
33064 }
33065 
33066 WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 *x)
33067 {
33068     WOLFSSL_STACK* list = NULL;
33069     char*          url;
33070 
33071     if (x->authInfoSz == 0)
33072         return NULL;
33073 
33074     list = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK) + x->authInfoSz + 1,
33075                                    NULL, DYNAMIC_TYPE_OPENSSL);
33076     if (list == NULL)
33077         return NULL;
33078 
33079     url = (char*)list;
33080     url += sizeof(WOLFSSL_STACK);
33081     XMEMCPY(url, x->authInfo, x->authInfoSz);
33082     url[x->authInfoSz] = '\0';
33083 
33084     list->data.string = url;
33085     list->next = NULL;
33086 
33087     return list;
33088 }
33089 
33090 int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject)
33091 {
33092     WOLFSSL_X509_NAME *issuerName = wolfSSL_X509_get_issuer_name(subject);
33093     WOLFSSL_X509_NAME *subjectName = wolfSSL_X509_get_subject_name(issuer);
33094 
33095     if (issuerName == NULL || subjectName == NULL)
33096         return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
33097 
33098     /* Literal matching of encoded names and key ids. */
33099     if (issuerName->sz != subjectName->sz ||
33100            XMEMCMP(issuerName->name, subjectName->name, subjectName->sz) != 0) {
33101         return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
33102     }
33103 
33104     if (subject->authKeyId != NULL && issuer->subjKeyId != NULL) {
33105         if (subject->authKeyIdSz != issuer->subjKeyIdSz ||
33106                 XMEMCMP(subject->authKeyId, issuer->subjKeyId,
33107                         issuer->subjKeyIdSz) != 0) {
33108             return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
33109         }
33110     }
33111 
33112     return X509_V_OK;
33113 }
33114 
33115 WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x)
33116 {
33117     return wolfSSL_X509_d2i(NULL, x->derCert->buffer, x->derCert->length);
33118 }
33119 
33120 char* wolfSSL_sk_WOLFSSL_STRING_value(WOLF_STACK_OF(WOLFSSL_STRING)* strings,
33121     int idx)
33122 {
33123     for (; idx > 0 && strings != NULL; idx--)
33124         strings = strings->next;
33125     if (strings == NULL)
33126         return NULL;
33127     return strings->data.string;
33128 }
33129 #endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
33130 
33131 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
33132 #ifdef HAVE_ALPN
33133 void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl, const unsigned char **data,
33134                                 unsigned int *len)
33135 {
33136     word16 nameLen;
33137 
33138     if (ssl != NULL && data != NULL && len != NULL) {
33139         TLSX_ALPN_GetRequest(ssl->extensions, (void **)data, &nameLen);
33140         *len = nameLen;
33141     }
33142 }
33143 
33144 int wolfSSL_select_next_proto(unsigned char **out, unsigned char *outLen,
33145                               const unsigned char *in, unsigned int inLen,
33146                               const unsigned char *clientNames,
33147                               unsigned int clientLen)
33148 {
33149     unsigned int i, j;
33150     byte lenIn, lenClient;
33151 
33152     if (out == NULL || outLen == NULL || in == NULL || clientNames == NULL)
33153         return OPENSSL_NPN_UNSUPPORTED;
33154 
33155     for (i = 0; i < inLen; i += lenIn) {
33156         lenIn = in[i++];
33157         for (j = 0; j < clientLen; j += lenClient) {
33158             lenClient = clientNames[j++];
33159 
33160             if (lenIn != lenClient)
33161                 continue;
33162 
33163             if (XMEMCMP(in + i, clientNames + j, lenIn) == 0) {
33164                 *out = (unsigned char *)(in + i);
33165                 *outLen = lenIn;
33166                 return OPENSSL_NPN_NEGOTIATED;
33167             }
33168         }
33169     }
33170 
33171     *out = (unsigned char *)clientNames + 1;
33172     *outLen = clientNames[0];
33173     return OPENSSL_NPN_NO_OVERLAP;
33174 }
33175 
33176 void wolfSSL_CTX_set_alpn_select_cb(WOLFSSL_CTX *ctx,
33177                                     int (*cb) (WOLFSSL *ssl,
33178                                                const unsigned char **out,
33179                                                unsigned char *outlen,
33180                                                const unsigned char *in,
33181                                                unsigned int inlen,
33182                                                void *arg), void *arg)
33183 {
33184     if (ctx != NULL) {
33185         ctx->alpnSelect = cb;
33186         ctx->alpnSelectArg = arg;
33187     }
33188 }
33189 
33190 void wolfSSL_CTX_set_next_protos_advertised_cb(WOLFSSL_CTX *s,
33191                                            int (*cb) (WOLFSSL *ssl,
33192                                                       const unsigned char
33193                                                       **out,
33194                                                       unsigned int *outlen,
33195                                                       void *arg), void *arg)
33196 {
33197     (void)s;
33198     (void)cb;
33199     (void)arg;
33200     WOLFSSL_STUB("wolfSSL_CTX_set_next_protos_advertised_cb");
33201 }
33202 
33203 void wolfSSL_CTX_set_next_proto_select_cb(WOLFSSL_CTX *s,
33204                                       int (*cb) (WOLFSSL *ssl,
33205                                                  unsigned char **out,
33206                                                  unsigned char *outlen,
33207                                                  const unsigned char *in,
33208                                                  unsigned int inlen,
33209                                                  void *arg), void *arg)
33210 {
33211     (void)s;
33212     (void)cb;
33213     (void)arg;
33214     WOLFSSL_STUB("wolfSSL_CTX_set_next_proto_select_cb");
33215 }
33216 
33217 void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s, const unsigned char **data,
33218                                     unsigned *len)
33219 {
33220     (void)s;
33221     (void)data;
33222     (void)len;
33223     WOLFSSL_STUB("wolfSSL_get0_next_proto_negotiated");
33224 }
33225 #endif /* HAVE_ALPN */
33226 
33227 #endif /* WOLFSSL_NGINX  / WOLFSSL_HAPROXY */
33228 
33229 #if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
33230 WOLFSSL_API int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, char* names)
33231 {
33232     int idx, start = 0, len;
33233     int curve;
33234     char name[MAX_CURVE_NAME_SZ];
33235 
33236     /* Disable all curves so that only the ones the user wants are enabled. */
33237     ctx->disabledCurves = (word32)-1;
33238     for (idx = 1; names[idx-1] != '\0'; idx++) {
33239         if (names[idx] != ':' && names[idx] != '\0')
33240             continue;
33241 
33242         len = idx - 1 - start;
33243         if (len > MAX_CURVE_NAME_SZ - 1)
33244             return WOLFSSL_FAILURE;
33245 
33246         XMEMCPY(name, names + start, len);
33247         name[len] = 0;
33248 
33249         if ((XSTRNCMP(name, "prime256v1", len) == 0) ||
33250                                       (XSTRNCMP(name, "secp256r1", len) == 0) ||
33251                                       (XSTRNCMP(name, "P-256", len) == 0)) {
33252             curve = WOLFSSL_ECC_SECP256R1;
33253         }
33254         else if ((XSTRNCMP(name, "secp384r1", len) == 0) ||
33255                                           (XSTRNCMP(name, "P-384", len) == 0)) {
33256             curve = WOLFSSL_ECC_SECP384R1;
33257         }
33258         else if ((XSTRNCMP(name, "secp521r1", len) == 0) ||
33259                                           (XSTRNCMP(name, "P-521", len) == 0)) {
33260             curve = WOLFSSL_ECC_SECP521R1;
33261         }
33262         else if (XSTRNCMP(name, "X25519", len) == 0)
33263             curve = WOLFSSL_ECC_X25519;
33264         else if ((curve = wc_ecc_get_curve_id_from_name(name)) < 0)
33265             return WOLFSSL_FAILURE;
33266 
33267         /* Switch the bit to off and therefore is enabled. */
33268         ctx->disabledCurves &= ~(1 << curve);
33269         start = idx + 1;
33270     }
33271 
33272     return WOLFSSL_SUCCESS;
33273 }
33274 #endif
33275 
33276 #ifdef OPENSSL_EXTRA
33277 #ifndef NO_WOLFSSL_STUB
33278 int wolfSSL_CTX_set_msg_callback(WOLFSSL_CTX *ctx, SSL_Msg_Cb cb)
33279 {
33280     WOLFSSL_STUB("SSL_CTX_set_msg_callback");
33281     (void)ctx;
33282     (void)cb;
33283     return WOLFSSL_FAILURE;
33284 }
33285 #endif
33286 
33287 
33288 /* Sets a callback for when sending and receiving protocol messages.
33289  *
33290  * ssl WOLFSSL structure to set callback in
33291  * cb  callback to use
33292  *
33293  * return SSL_SUCCESS on success and SSL_FAILURE with error case
33294  */
33295 int wolfSSL_set_msg_callback(WOLFSSL *ssl, SSL_Msg_Cb cb)
33296 {
33297     WOLFSSL_ENTER("wolfSSL_set_msg_callback");
33298 
33299     if (ssl == NULL) {
33300         return SSL_FAILURE;
33301     }
33302 
33303     if (cb != NULL) {
33304         ssl->toInfoOn = 1;
33305     }
33306 
33307     ssl->protoMsgCb = cb;
33308     return SSL_SUCCESS;
33309 }
33310 #ifndef NO_WOLFSSL_STUB
33311 int wolfSSL_CTX_set_msg_callback_arg(WOLFSSL_CTX *ctx, void* arg)
33312 {
33313     WOLFSSL_STUB("SSL_CTX_set_msg_callback_arg");
33314     (void)ctx;
33315     (void)arg;
33316     return WOLFSSL_FAILURE;
33317 }
33318 #endif
33319 
33320 int wolfSSL_set_msg_callback_arg(WOLFSSL *ssl, void* arg)
33321 {
33322     WOLFSSL_ENTER("wolfSSL_set_msg_callback_arg");
33323     ssl->protoMsgCtx = arg;
33324     return WOLFSSL_SUCCESS;
33325 }
33326 
33327 void *wolfSSL_OPENSSL_memdup(const void *data, size_t siz, const char* file, int line)
33328 {
33329     void *ret;
33330     (void)file;
33331     (void)line;
33332 
33333     if (data == NULL || siz >= INT_MAX)
33334         return NULL;
33335 
33336     ret = OPENSSL_malloc(siz);
33337     if (ret == NULL) {
33338         return NULL;
33339     }
33340     return XMEMCPY(ret, data, siz);
33341 }
33342 
33343 int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, const unsigned char *p,
33344                             unsigned int p_len)
33345 {
33346     WOLFSSL_ENTER("wolfSSL_CTX_set_alpn_protos");
33347     if(ctx == NULL)
33348         return BAD_FUNC_ARG;
33349     if((void *)ctx->alpn_cli_protos != NULL)
33350         wolfSSL_OPENSSL_free((void *)ctx->alpn_cli_protos);
33351     ctx->alpn_cli_protos =
33352         (const unsigned char *)wolfSSL_OPENSSL_memdup(p, p_len, NULL, 0);
33353     if (ctx->alpn_cli_protos == NULL) {
33354         return SSL_FAILURE;
33355     }
33356     ctx->alpn_cli_protos_len = p_len;
33357 
33358     return SSL_SUCCESS;
33359 }
33360 
33361 #endif
33362 
33363 #endif /* WOLFCRYPT_ONLY */
33364 
33365 #if defined(OPENSSL_EXTRA)
33366 int wolfSSL_X509_check_ca(WOLFSSL_X509 *x509)
33367 {
33368     WOLFSSL_ENTER("X509_check_ca");
33369 
33370     if (x509 == NULL)
33371         return WOLFSSL_FAILURE;
33372     if (x509->isCa)
33373         return 1;
33374     if (x509->extKeyUsageCrit)
33375         return 4;
33376 
33377     return 0;
33378 }
33379 
33380 
33381 const char *wolfSSL_ASN1_tag2str(int tag)
33382 {
33383     static const char *const tag_label[31] = {
33384         "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", "NULL",
33385         "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", "ENUMERATED",
33386         "<ASN1 11>", "UTF8STRING", "<ASN1 13>", "<ASN1 14>", "<ASN1 15>",
33387         "SEQUENCE", "SET", "NUMERICSTRING", "PRINTABLESTRING", "T61STRING",
33388         "VIDEOTEXTSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME",
33389         "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", "UNIVERSALSTRING",
33390         "<ASN1 29>", "BMPSTRING"
33391     };
33392 
33393     if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
33394         tag &= ~0x100;
33395     if (tag < 0 || tag > 30)
33396         return "(unknown)";
33397     return tag_label[tag];
33398 }
33399 
33400 static int check_esc_char(char c, char *esc)
33401 {
33402     char *ptr = NULL;
33403 
33404     ptr = esc;
33405     while(*ptr != 0){
33406         if (c == *ptr)
33407             return 1;
33408         ptr++;
33409     }
33410     return 0;
33411 }
33412 
33413 int wolfSSL_ASN1_STRING_print_ex(WOLFSSL_BIO *out, WOLFSSL_ASN1_STRING *str,
33414                                  unsigned long flags)
33415 {
33416     size_t str_len = 0, type_len = 0;
33417     unsigned char *typebuf = NULL;
33418     const char *hash="#";
33419 
33420     WOLFSSL_ENTER("wolfSSL_ASN1_STRING_PRINT_ex");
33421     if (out == NULL || str == NULL)
33422         return WOLFSSL_FAILURE;
33423 
33424     /* add ASN1 type tag */
33425     if (flags & ASN1_STRFLGS_SHOW_TYPE){
33426         const char *tag = wolfSSL_ASN1_tag2str(str->type);
33427         /* colon len + tag len + null*/
33428         type_len = XSTRLEN(tag) + 2;
33429         typebuf = (unsigned char *)XMALLOC(type_len , NULL, DYNAMIC_TYPE_TMP_BUFFER);
33430         if (typebuf == NULL){
33431             WOLFSSL_MSG("memory alloc failed.");
33432             return WOLFSSL_FAILURE;
33433         }
33434         XMEMSET(typebuf, 0, type_len);
33435         XSNPRINTF((char*)typebuf, (size_t)type_len , "%s:", tag);
33436         type_len--;
33437     }
33438 
33439     /* dump hex */
33440     if (flags & ASN1_STRFLGS_DUMP_ALL){
33441         static const char hex_char[] = { '0', '1', '2', '3', '4', '5', '6',
33442                                          '7','8', '9', 'A', 'B', 'C', 'D',
33443                                          'E', 'F' };
33444         char hex_tmp[4];
33445         char *str_ptr, *str_end;
33446 
33447         if (type_len > 0){
33448             if (wolfSSL_BIO_write(out, typebuf, (int)type_len) != (int)type_len){
33449                 XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
33450                 return WOLFSSL_FAILURE;
33451             }
33452             str_len += type_len;
33453         }
33454         if (wolfSSL_BIO_write(out, hash, 1) != 1){
33455             goto err_exit;
33456         }
33457         str_len++;
33458         if (flags & ASN1_STRFLGS_DUMP_DER){
33459             hex_tmp[0] = hex_char[str->type >> 4];
33460             hex_tmp[1] = hex_char[str->type & 0xf];
33461             hex_tmp[2] = hex_char[str->length >> 4];
33462             hex_tmp[3] = hex_char[str->length & 0xf];
33463             if (wolfSSL_BIO_write(out, hex_tmp, 4) != 4){
33464                 goto err_exit;
33465             }
33466             str_len += 4;
33467             XMEMSET(hex_tmp, 0, 4);
33468         }
33469 
33470         str_ptr = str->data;
33471         str_end = str->data + str->length;
33472         while (str_ptr < str_end){
33473             hex_tmp[0] = hex_char[*str_ptr >> 4];
33474             hex_tmp[1] = hex_char[*str_ptr & 0xf];
33475             if (wolfSSL_BIO_write(out, hex_tmp, 2) != 2){
33476                 goto err_exit;
33477             }
33478             str_ptr++;
33479             str_len += 2;
33480         }
33481         if (type_len > 0)
33482             XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
33483 
33484         return (int)str_len;
33485     }
33486 
33487     if (type_len > 0){
33488         if (wolfSSL_BIO_write(out, typebuf, (int)type_len) != (int)type_len){
33489             XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
33490             return WOLFSSL_FAILURE;
33491         }
33492         str_len += type_len;
33493     }
33494 
33495     if (flags & ASN1_STRFLGS_ESC_2253){
33496         char esc_ch[] = "+;<>\\";
33497         char* esc_ptr = NULL;
33498 
33499         esc_ptr = str->data;
33500         while (*esc_ptr != 0){
33501             if (check_esc_char(*esc_ptr, esc_ch)){
33502                 if (wolfSSL_BIO_write(out,"\\", 1) != 1)
33503                     goto err_exit;
33504                 str_len++;
33505             }
33506             if (wolfSSL_BIO_write(out, esc_ptr, 1) != 1)
33507                 goto err_exit;
33508             str_len++;
33509             esc_ptr++;
33510         }
33511         if (type_len > 0)
33512             XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
33513         return (int)str_len;
33514     }
33515 
33516     if (wolfSSL_BIO_write(out, str->data, str->length) != str->length){
33517         goto err_exit;
33518     }
33519     str_len += str->length;
33520     if (type_len > 0)
33521         XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
33522 
33523     return (int)str_len;
33524 
33525 err_exit:
33526     if (type_len > 0)
33527         XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
33528     return WOLFSSL_FAILURE;
33529 }
33530 
33531 #ifndef NO_ASN_TIME
33532 WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_to_generalizedtime(WOLFSSL_ASN1_TIME *t,
33533                                                         WOLFSSL_ASN1_TIME **out)
33534 {
33535     unsigned char time_type;
33536     WOLFSSL_ASN1_TIME *ret = NULL;
33537     unsigned char *data_ptr = NULL;
33538 
33539     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_generalizedtime");
33540     if (t == NULL)
33541         return NULL;
33542 
33543     time_type = t->data[0];
33544     if (time_type != ASN_UTC_TIME && time_type != ASN_GENERALIZED_TIME){
33545         WOLFSSL_MSG("Invalid ASN_TIME type.");
33546         return NULL;
33547     }
33548     if (out == NULL || *out == NULL){
33549         ret = (WOLFSSL_ASN1_TIME*)XMALLOC(sizeof(WOLFSSL_ASN1_TIME), NULL,
33550                                         DYNAMIC_TYPE_TMP_BUFFER);
33551         if (ret == NULL){
33552             WOLFSSL_MSG("memory alloc failed.");
33553             return NULL;
33554         }
33555         XMEMSET(ret, 0, sizeof(WOLFSSL_ASN1_TIME));
33556     } else
33557         ret = *out;
33558 
33559     if (time_type == ASN_GENERALIZED_TIME){
33560         XMEMCPY(ret->data, t->data, ASN_GENERALIZED_TIME_SIZE);
33561         return ret;
33562     } else if (time_type == ASN_UTC_TIME){
33563         ret->data[0] = ASN_GENERALIZED_TIME;
33564         ret->data[1] = ASN_GENERALIZED_TIME_SIZE;
33565         data_ptr  = ret->data + 2;
33566         if (t->data[2] >= '5')
33567             XSNPRINTF((char*)data_ptr, ASN_UTC_TIME_SIZE + 2, "19%s", t->data + 2);
33568         else
33569             XSNPRINTF((char*)data_ptr, ASN_UTC_TIME_SIZE + 2, "20%s", t->data + 2);
33570 
33571         return ret;
33572     }
33573 
33574     WOLFSSL_MSG("Invalid ASN_TIME value");
33575     return NULL;
33576 }
33577 #endif /* !NO_ASN_TIME */
33578 
33579 
33580 #ifndef NO_ASN
33581 int wolfSSL_i2c_ASN1_INTEGER(WOLFSSL_ASN1_INTEGER *a, unsigned char **pp)
33582 {
33583     unsigned char *pptr = NULL;
33584     char pad = 0 ;
33585     unsigned char pad_val = 0;
33586     int ret_size = 0;
33587     unsigned char data1 = 0;
33588     unsigned char neg = 0;
33589     int i = 0;
33590 
33591     WOLFSSL_ENTER("wolfSSL_i2c_ASN1_INTEGER");
33592     if (a == NULL)
33593         return WOLFSSL_FAILURE;
33594 
33595     ret_size = a->intData[1];
33596     if (ret_size == 0)
33597         ret_size = 1;
33598     else{
33599         ret_size = (int)a->intData[1];
33600         neg = a->negative;
33601         data1 = a->intData[2];
33602         if (ret_size == 1 && data1 == 0)
33603             neg = 0;
33604         /* 0x80 or greater positive number in first byte */
33605         if (!neg && (data1 > 127)){
33606             pad = 1;
33607             pad_val = 0;
33608         } else if (neg){
33609             /* negative number */
33610             if (data1 > 128){
33611                 pad = 1;
33612                 pad_val = 0xff;
33613             } else if (data1 == 128){
33614                 for (i = 3; i < a->intData[1] + 2; i++){
33615                     if (a->intData[i]){
33616                         pad = 1;
33617                         pad_val = 0xff;
33618                         break;
33619                     }
33620                 }
33621             }
33622         }
33623         ret_size += (int)pad;
33624     }
33625     if (pp == NULL)
33626         return ret_size;
33627 
33628     pptr = *pp;
33629     if (pad)
33630         *(pptr++) = pad_val;
33631     if (a->intData[1] == 0)
33632         *(pptr++) = 0;
33633     else if (!neg){
33634         /* positive number */
33635         for (i=0; i < a->intData[1]; i++){
33636             *pptr = a->intData[i+2];
33637             pptr++;
33638         }
33639     } else {
33640         /* negative number */
33641         int str_len = 0;
33642 
33643         /* 0 padding from end of buffer */
33644         str_len = (int)a->intData[1];
33645         pptr += a->intData[1] - 1;
33646         while (!a->intData[str_len + 2] && str_len > 1){
33647             *(pptr--) = 0;
33648             str_len--;
33649         }
33650         /* 2's complement next octet */
33651         *(pptr--) = ((a->intData[str_len + 1]) ^ 0xff) + 1;
33652         str_len--;
33653         /* Complement any octets left */
33654         while (str_len > 0){
33655             *(pptr--) = a->intData[str_len + 1] ^ 0xff;
33656             str_len--;
33657         }
33658     }
33659     *pp += ret_size;
33660     return ret_size;
33661 }
33662 #endif /* !NO_ASN */
33663 
33664 #endif  /* OPENSSLEXTRA */
33665