wolf SSL / wolfSSL-TLS13-Beta

Fork of wolfSSL by wolf SSL

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-2016 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 <wolfssl/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 <wolfssl/wolfcrypt/coding.h>
00038 #ifdef NO_INLINE
00039     #include <wolfssl/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         #error "No cipher suites defined because DH disabled, ECC disabled, and no static suites defined. Please see top of README"
00050     #endif
00051 #endif
00052 
00053 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
00054                               defined(WOLFSSL_KEY_GEN)
00055     #include <wolfssl/openssl/evp.h>
00056     /* openssl headers end, wolfssl internal headers next */
00057     #include <wolfssl/wolfcrypt/wc_encrypt.h>
00058 #endif
00059 
00060 #ifdef OPENSSL_EXTRA
00061     /* openssl headers begin */
00062     #include <wolfssl/openssl/hmac.h>
00063     #include <wolfssl/openssl/crypto.h>
00064     #include <wolfssl/openssl/des.h>
00065     #include <wolfssl/openssl/bn.h>
00066     #include <wolfssl/openssl/dh.h>
00067     #include <wolfssl/openssl/rsa.h>
00068     #include <wolfssl/openssl/pem.h>
00069     #include <wolfssl/openssl/ec.h>
00070     #include <wolfssl/openssl/ec25519.h>
00071     #include <wolfssl/openssl/ed25519.h>
00072     #include <wolfssl/openssl/ecdsa.h>
00073     #include <wolfssl/openssl/ecdh.h>
00074     /* openssl headers end, wolfssl internal headers next */
00075     #include <wolfssl/wolfcrypt/hmac.h>
00076     #include <wolfssl/wolfcrypt/random.h>
00077     #include <wolfssl/wolfcrypt/des3.h>
00078     #include <wolfssl/wolfcrypt/md4.h>
00079     #include <wolfssl/wolfcrypt/md5.h>
00080     #include <wolfssl/wolfcrypt/arc4.h>
00081     #include <wolfssl/wolfcrypt/idea.h>
00082     #include <wolfssl/wolfcrypt/curve25519.h>
00083     #include <wolfssl/wolfcrypt/ed25519.h>
00084     #ifdef HAVE_STUNNEL
00085         #include <wolfssl/openssl/ocsp.h>
00086     #endif /* WITH_STUNNEL */
00087     #ifdef WOLFSSL_SHA512
00088         #include <wolfssl/wolfcrypt/sha512.h>
00089     #endif
00090 #endif
00091 
00092 #ifdef NO_ASN
00093     #include <wolfssl/wolfcrypt/dh.h>
00094 #endif
00095 
00096 
00097 #ifndef WOLFSSL_LEANPSK
00098 char* mystrnstr(const char* s1, const char* s2, unsigned int n)
00099 {
00100     unsigned int s2_len = (unsigned int)XSTRLEN(s2);
00101 
00102     if (s2_len == 0)
00103         return (char*)s1;
00104 
00105     while (n >= s2_len && s1[0]) {
00106         if (s1[0] == s2[0])
00107             if (XMEMCMP(s1, s2, s2_len) == 0)
00108                 return (char*)s1;
00109         s1++;
00110         n--;
00111     }
00112 
00113     return NULL;
00114 }
00115 #endif
00116 
00117 #ifdef WOLFSSL_SESSION_EXPORT
00118 #ifdef WOLFSSL_DTLS
00119 int wolfSSL_dtls_import(WOLFSSL* ssl, unsigned char* buf, unsigned int sz)
00120 {
00121     WOLFSSL_ENTER("wolfSSL_session_import");
00122 
00123     if (ssl == NULL || buf == NULL) {
00124         return BAD_FUNC_ARG;
00125     }
00126 
00127     /* sanity checks on buffer and protocol are done in internal function */
00128     return wolfSSL_dtls_import_internal(ssl, buf, sz);
00129 }
00130 
00131 
00132 /* Sets the function to call for serializing the session. This function is
00133  * called right after the handshake is completed. */
00134 int wolfSSL_CTX_dtls_set_export(WOLFSSL_CTX* ctx, wc_dtls_export func)
00135 {
00136 
00137     WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_export");
00138 
00139     /* purposefully allow func to be NULL */
00140     if (ctx == NULL) {
00141         return BAD_FUNC_ARG;
00142     }
00143 
00144     ctx->dtls_export = func;
00145 
00146     return SSL_SUCCESS;
00147 }
00148 
00149 
00150 /* Sets the function in WOLFSSL struct to call for serializing the session. This
00151  * function is called right after the handshake is completed. */
00152 int wolfSSL_dtls_set_export(WOLFSSL* ssl, wc_dtls_export func)
00153 {
00154 
00155     WOLFSSL_ENTER("wolfSSL_dtls_set_export");
00156 
00157     /* purposefully allow func to be NULL */
00158     if (ssl == NULL) {
00159         return BAD_FUNC_ARG;
00160     }
00161 
00162     ssl->dtls_export = func;
00163 
00164     return SSL_SUCCESS;
00165 }
00166 
00167 
00168 /* This function allows for directly serializing a session rather than using
00169  * callbacks. It has less overhead by removing a temporary buffer and gives
00170  * control over when the session gets serialized. When using callbacks the
00171  * session is always serialized immediatly after the handshake is finished.
00172  *
00173  * buf is the argument to contain the serialized session
00174  * sz  is the size of the buffer passed in
00175  * ssl is the WOLFSSL struct to serialize
00176  * returns the size of serialized session on success, 0 on no action, and
00177  *         negative value on error */
00178 int wolfSSL_dtls_export(WOLFSSL* ssl, unsigned char* buf, unsigned int* sz)
00179 {
00180     WOLFSSL_ENTER("wolfSSL_dtls_export");
00181 
00182     if (ssl == NULL || sz == NULL) {
00183         return BAD_FUNC_ARG;
00184     }
00185 
00186     if (buf == NULL) {
00187         *sz = MAX_EXPORT_BUFFER;
00188         return 0;
00189     }
00190 
00191     /* if not DTLS do nothing */
00192     if (!ssl->options.dtls) {
00193         WOLFSSL_MSG("Currently only DTLS export is supported");
00194         return 0;
00195     }
00196 
00197     /* copy over keys, options, and dtls state struct */
00198     return wolfSSL_dtls_export_internal(ssl, buf, *sz);
00199 }
00200 
00201 
00202 /* returns 0 on success */
00203 int wolfSSL_send_session(WOLFSSL* ssl)
00204 {
00205     int ret;
00206     byte* buf;
00207     word16 bufSz = MAX_EXPORT_BUFFER;
00208 
00209     WOLFSSL_ENTER("wolfSSL_send_session");
00210 
00211     if (ssl == NULL) {
00212         return BAD_FUNC_ARG;
00213     }
00214 
00215     buf = (byte*)XMALLOC(bufSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00216     if (buf == NULL) {
00217         return MEMORY_E;
00218     }
00219 
00220     /* if not DTLS do nothing */
00221     if (!ssl->options.dtls) {
00222         XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00223         WOLFSSL_MSG("Currently only DTLS export is supported");
00224         return 0;
00225     }
00226 
00227     /* copy over keys, options, and dtls state struct */
00228     ret = wolfSSL_dtls_export_internal(ssl, buf, bufSz);
00229     if (ret < 0) {
00230         XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00231         return ret;
00232     }
00233 
00234     /* if no error ret has size of buffer */
00235     ret = ssl->dtls_export(ssl, buf, ret, NULL);
00236     if (ret != SSL_SUCCESS) {
00237         XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00238         return ret;
00239     }
00240 
00241     XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00242     return 0;
00243 }
00244 #endif /* WOLFSSL_DTLS */
00245 #endif /* WOLFSSL_SESSION_EXPORT */
00246 
00247 
00248 /* prevent multiple mutex initializations */
00249 static volatile int initRefCount = 0;
00250 static wolfSSL_Mutex count_mutex;   /* init ref count mutex */
00251 
00252 
00253 /* Create a new WOLFSSL_CTX struct and return the pointer to created struct.
00254    WOLFSSL_METHOD pointer passed in is given to ctx to manage.
00255    This function frees the passed in WOLFSSL_METHOD struct on failure and on
00256    success is freed when ctx is freed.
00257  */
00258 WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap)
00259 {
00260     WOLFSSL_CTX* ctx = NULL;
00261 
00262     WOLFSSL_ENTER("WOLFSSL_CTX_new_ex");
00263 
00264     if (initRefCount == 0) {
00265         /* user no longer forced to call Init themselves */
00266         int ret = wolfSSL_Init();
00267         if (ret != SSL_SUCCESS) {
00268             WOLFSSL_MSG("wolfSSL_Init failed");
00269             WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
00270             if (method != NULL) {
00271                 XFREE(method, heap, DYNAMIC_TYPE_METHOD);
00272             }
00273             return NULL;
00274         }
00275     }
00276 
00277     if (method == NULL)
00278         return ctx;
00279 
00280     ctx = (WOLFSSL_CTX*) XMALLOC(sizeof(WOLFSSL_CTX), heap, DYNAMIC_TYPE_CTX);
00281     if (ctx) {
00282         if (InitSSL_Ctx(ctx, method, heap) < 0) {
00283             WOLFSSL_MSG("Init CTX failed");
00284             wolfSSL_CTX_free(ctx);
00285             ctx = NULL;
00286         }
00287     }
00288     else {
00289         WOLFSSL_MSG("Alloc CTX failed, method freed");
00290         XFREE(method, heap, DYNAMIC_TYPE_METHOD);
00291     }
00292 
00293     WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
00294     return ctx;
00295 }
00296 
00297 
00298 WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method)
00299 {
00300 #ifdef WOLFSSL_HEAP_TEST
00301     /* if testing the heap hint then set top level CTX to have test value */
00302     return wolfSSL_CTX_new_ex(method, (void*)WOLFSSL_HEAP_TEST);
00303 #else
00304     return wolfSSL_CTX_new_ex(method, NULL);
00305 #endif
00306 }
00307 
00308 
00309 void wolfSSL_CTX_free(WOLFSSL_CTX* ctx)
00310 {
00311     WOLFSSL_ENTER("SSL_CTX_free");
00312     if (ctx)
00313         FreeSSL_Ctx(ctx);
00314     WOLFSSL_LEAVE("SSL_CTX_free", 0);
00315 }
00316 
00317 
00318 #ifdef SINGLE_THREADED
00319 /* no locking in single threaded mode, allow a CTX level rng to be shared with
00320  * WOLFSSL objects, SSL_SUCCESS on ok */
00321 int wolfSSL_CTX_new_rng(WOLFSSL_CTX* ctx)
00322 {
00323     WC_RNG* rng;
00324     int     ret;
00325 
00326     if (ctx == NULL) {
00327         return BAD_FUNC_ARG;
00328     }
00329 
00330     rng = XMALLOC(sizeof(WC_RNG), ctx->heap, DYNAMIC_TYPE_RNG);
00331     if (rng == NULL) {
00332         return MEMORY_E;
00333     }
00334 
00335 #ifndef HAVE_FIPS
00336     ret = wc_InitRng_ex(rng, ctx->heap, ctx->devId);
00337 #else
00338     ret = wc_InitRng(rng);
00339 #endif
00340     if (ret != 0) {
00341         XFREE(rng, ctx->heap, DYNAMIC_TYPE_RNG);
00342         return ret;
00343     }
00344 
00345     ctx->rng = rng;
00346     return SSL_SUCCESS;
00347 }
00348 #endif
00349 
00350 
00351 WOLFSSL* wolfSSL_new(WOLFSSL_CTX* ctx)
00352 {
00353     WOLFSSL* ssl = NULL;
00354     int ret = 0;
00355 
00356     (void)ret;
00357     WOLFSSL_ENTER("SSL_new");
00358 
00359     if (ctx == NULL)
00360         return ssl;
00361 
00362     ssl = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ctx->heap, DYNAMIC_TYPE_SSL);
00363     if (ssl)
00364         if ( (ret = InitSSL(ssl, ctx, 0)) < 0) {
00365             FreeSSL(ssl, ctx->heap);
00366             ssl = 0;
00367         }
00368 
00369     WOLFSSL_LEAVE("SSL_new", ret);
00370     return ssl;
00371 }
00372 
00373 
00374 void wolfSSL_free(WOLFSSL* ssl)
00375 {
00376     WOLFSSL_ENTER("SSL_free");
00377     if (ssl)
00378         FreeSSL(ssl, ssl->ctx->heap);
00379     WOLFSSL_LEAVE("SSL_free", 0);
00380 }
00381 
00382 
00383 #ifdef HAVE_WRITE_DUP
00384 
00385 /*
00386  * Release resources around WriteDup object
00387  *
00388  * ssl WOLFSSL object
00389  *
00390  * no return, destruction so make best attempt
00391 */
00392 void FreeWriteDup(WOLFSSL* ssl)
00393 {
00394     int doFree = 0;
00395 
00396     WOLFSSL_ENTER("FreeWriteDup");
00397 
00398     if (ssl->dupWrite) {
00399         if (wc_LockMutex(&ssl->dupWrite->dupMutex) == 0) {
00400             ssl->dupWrite->dupCount--;
00401             if (ssl->dupWrite->dupCount == 0) {
00402                 doFree = 1;
00403             } else {
00404                 WOLFSSL_MSG("WriteDup count not zero, no full free");
00405             }
00406             wc_UnLockMutex(&ssl->dupWrite->dupMutex);
00407         }
00408     }
00409 
00410     if (doFree) {
00411         WOLFSSL_MSG("Doing WriteDup full free, count to zero");
00412         wc_FreeMutex(&ssl->dupWrite->dupMutex);
00413         XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
00414     }
00415 }
00416 
00417 
00418 /*
00419  * duplicate existing ssl members into dup needed for writing
00420  *
00421  * dup write only WOLFSSL
00422  * ssl exisiting WOLFSSL
00423  *
00424  * 0 on success
00425 */
00426 static int DupSSL(WOLFSSL* dup, WOLFSSL* ssl)
00427 {
00428     /* shared dupWrite setup */
00429     ssl->dupWrite = (WriteDup*)XMALLOC(sizeof(WriteDup), ssl->heap,
00430                                        DYNAMIC_TYPE_WRITEDUP);
00431     if (ssl->dupWrite == NULL) {
00432         return MEMORY_E;
00433     }
00434     XMEMSET(ssl->dupWrite, 0, sizeof(WriteDup));
00435 
00436     if (wc_InitMutex(&ssl->dupWrite->dupMutex) != 0) {
00437         XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
00438         ssl->dupWrite = NULL;
00439         return BAD_MUTEX_E;
00440     }
00441     ssl->dupWrite->dupCount = 2;    /* both sides have a count to start */
00442     dup->dupWrite = ssl->dupWrite ; /* each side uses */
00443 
00444     /* copy write parts over to dup writer */
00445     XMEMCPY(&dup->specs,   &ssl->specs,   sizeof(CipherSpecs));
00446     XMEMCPY(&dup->options, &ssl->options, sizeof(Options));
00447     XMEMCPY(&dup->keys,    &ssl->keys,    sizeof(Keys));
00448     XMEMCPY(&dup->encrypt, &ssl->encrypt, sizeof(Ciphers));
00449     /* dup side now owns encrypt/write ciphers */
00450     XMEMSET(&ssl->encrypt, 0, sizeof(Ciphers));
00451 
00452     dup->IOCB_WriteCtx = ssl->IOCB_WriteCtx;
00453     dup->wfd    = ssl->wfd;
00454     dup->wflags = ssl->wflags;
00455     dup->hmac   = ssl->hmac;
00456 #ifdef HAVE_TRUNCATED_HMAC
00457     dup->truncated_hmac = ssl->truncated_hmac;
00458 #endif
00459 
00460     /* unique side dup setup */
00461     dup->dupSide = WRITE_DUP_SIDE;
00462     ssl->dupSide = READ_DUP_SIDE;
00463 
00464     return 0;
00465 }
00466 
00467 
00468 /*
00469  * duplicate a WOLFSSL object post handshake for writing only
00470  * turn exisitng object into read only.  Allows concurrent access from two
00471  * different threads.
00472  *
00473  * ssl exisiting WOLFSSL object
00474  *
00475  * return dup'd WOLFSSL object on success
00476 */
00477 WOLFSSL* wolfSSL_write_dup(WOLFSSL* ssl)
00478 {
00479     WOLFSSL* dup = NULL;
00480     int ret = 0;
00481 
00482     (void)ret;
00483     WOLFSSL_ENTER("wolfSSL_write_dup");
00484 
00485     if (ssl == NULL) {
00486         return ssl;
00487     }
00488 
00489     if (ssl->options.handShakeDone == 0) {
00490         WOLFSSL_MSG("wolfSSL_write_dup called before handshake complete");
00491         return NULL;
00492     }
00493 
00494     if (ssl->dupWrite) {
00495         WOLFSSL_MSG("wolfSSL_write_dup already called once");
00496         return NULL;
00497     }
00498 
00499     dup = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ssl->ctx->heap, DYNAMIC_TYPE_SSL);
00500     if (dup) {
00501         if ( (ret = InitSSL(dup, ssl->ctx, 1)) < 0) {
00502             FreeSSL(dup, ssl->ctx->heap);
00503             dup = NULL;
00504         } else if ( (ret = DupSSL(dup, ssl) < 0)) {
00505             FreeSSL(dup, ssl->ctx->heap);
00506             dup = NULL;
00507         }
00508     }
00509 
00510     WOLFSSL_LEAVE("wolfSSL_write_dup", ret);
00511 
00512     return dup;
00513 }
00514 
00515 
00516 /*
00517  * Notify write dup side of fatal error or close notify
00518  *
00519  * ssl WOLFSSL object
00520  * err Notify err
00521  *
00522  * 0 on success
00523 */
00524 int NotifyWriteSide(WOLFSSL* ssl, int err)
00525 {
00526     int ret;
00527 
00528     WOLFSSL_ENTER("NotifyWriteSide");
00529 
00530     ret = wc_LockMutex(&ssl->dupWrite->dupMutex);
00531     if (ret == 0) {
00532         ssl->dupWrite->dupErr = err;
00533         ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
00534     }
00535 
00536     return ret;
00537 }
00538 
00539 
00540 #endif /* HAVE_WRITE_DUP */
00541 
00542 
00543 #ifdef HAVE_POLY1305
00544 /* set if to use old poly 1 for yes 0 to use new poly */
00545 int wolfSSL_use_old_poly(WOLFSSL* ssl, int value)
00546 {
00547     WOLFSSL_ENTER("SSL_use_old_poly");
00548     WOLFSSL_MSG("Warning SSL connection auto detects old/new and this function"
00549             "is depriciated");
00550     ssl->options.oldPoly = (word16)value;
00551     WOLFSSL_LEAVE("SSL_use_old_poly", 0);
00552     return 0;
00553 }
00554 #endif
00555 
00556 
00557 int wolfSSL_set_fd(WOLFSSL* ssl, int fd)
00558 {
00559     int ret;
00560 
00561     WOLFSSL_ENTER("SSL_set_fd");
00562 
00563     if (ssl == NULL) {
00564         return BAD_FUNC_ARG;
00565     }
00566 
00567     ret = wolfSSL_set_read_fd(ssl, fd);
00568     if (ret == SSL_SUCCESS) {
00569         ret = wolfSSL_set_write_fd(ssl, fd);
00570     }
00571 
00572     return ret;
00573 }
00574 
00575 
00576 int wolfSSL_set_read_fd(WOLFSSL* ssl, int fd)
00577 {
00578     WOLFSSL_ENTER("SSL_set_read_fd");
00579 
00580     if (ssl == NULL) {
00581         return BAD_FUNC_ARG;
00582     }
00583 
00584     ssl->rfd = fd;      /* not used directly to allow IO callbacks */
00585     ssl->IOCB_ReadCtx  = &ssl->rfd;
00586 
00587     #ifdef WOLFSSL_DTLS
00588         if (ssl->options.dtls) {
00589             ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
00590             ssl->buffers.dtlsCtx.rfd = fd;
00591         }
00592     #endif
00593 
00594     WOLFSSL_LEAVE("SSL_set_read_fd", SSL_SUCCESS);
00595     return SSL_SUCCESS;
00596 }
00597 
00598 
00599 int wolfSSL_set_write_fd(WOLFSSL* ssl, int fd)
00600 {
00601     WOLFSSL_ENTER("SSL_set_write_fd");
00602 
00603     if (ssl == NULL) {
00604         return BAD_FUNC_ARG;
00605     }
00606 
00607     ssl->wfd = fd;      /* not used directly to allow IO callbacks */
00608     ssl->IOCB_WriteCtx  = &ssl->wfd;
00609 
00610     #ifdef WOLFSSL_DTLS
00611         if (ssl->options.dtls) {
00612             ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
00613             ssl->buffers.dtlsCtx.wfd = fd;
00614         }
00615     #endif
00616 
00617     WOLFSSL_LEAVE("SSL_set_write_fd", SSL_SUCCESS);
00618     return SSL_SUCCESS;
00619 }
00620 
00621 
00622 /**
00623   * Get the name of cipher at priority level passed in.
00624   */
00625 char* wolfSSL_get_cipher_list(int priority)
00626 {
00627     const char* const* ciphers = GetCipherNames();
00628 
00629     if (priority >= GetCipherNamesSize() || priority < 0) {
00630         return 0;
00631     }
00632 
00633     return (char*)ciphers[priority];
00634 }
00635 
00636 
00637 int wolfSSL_get_ciphers(char* buf, int len)
00638 {
00639     const char* const* ciphers = GetCipherNames();
00640     int  totalInc = 0;
00641     int  step     = 0;
00642     char delim    = ':';
00643     int  size     = GetCipherNamesSize();
00644     int  i;
00645 
00646     if (buf == NULL || len <= 0)
00647         return BAD_FUNC_ARG;
00648 
00649     /* Add each member to the buffer delimited by a : */
00650     for (i = 0; i < size; i++) {
00651         step = (int)(XSTRLEN(ciphers[i]) + 1);  /* delimiter */
00652         totalInc += step;
00653 
00654         /* Check to make sure buf is large enough and will not overflow */
00655         if (totalInc < len) {
00656             XSTRNCPY(buf, ciphers[i], XSTRLEN(ciphers[i]));
00657             buf += XSTRLEN(ciphers[i]);
00658 
00659             if (i < size - 1)
00660                 *buf++ = delim;
00661             else
00662                 *buf++ = '\0';
00663         }
00664         else
00665             return BUFFER_E;
00666     }
00667     return SSL_SUCCESS;
00668 }
00669 
00670 const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf, int len)
00671 {
00672     const char* cipher;
00673 
00674     if (ssl == NULL)
00675         return NULL;
00676 
00677     cipher = wolfSSL_get_cipher_name_from_suite(ssl->options.cipherSuite,
00678                                                 ssl->options.cipherSuite0);
00679     len = min(len, (int)(XSTRLEN(cipher) + 1));
00680     XMEMCPY(buf, cipher, len);
00681     return buf;
00682 }
00683 
00684 int wolfSSL_get_fd(const WOLFSSL* ssl)
00685 {
00686     WOLFSSL_ENTER("SSL_get_fd");
00687     WOLFSSL_LEAVE("SSL_get_fd", ssl->rfd);
00688     return ssl->rfd;
00689 }
00690 
00691 
00692 int wolfSSL_get_using_nonblock(WOLFSSL* ssl)
00693 {
00694     WOLFSSL_ENTER("wolfSSL_get_using_nonblock");
00695     WOLFSSL_LEAVE("wolfSSL_get_using_nonblock", ssl->options.usingNonblock);
00696     return ssl->options.usingNonblock;
00697 }
00698 
00699 
00700 int wolfSSL_dtls(WOLFSSL* ssl)
00701 {
00702     return ssl->options.dtls;
00703 }
00704 
00705 
00706 #ifndef WOLFSSL_LEANPSK
00707 void wolfSSL_set_using_nonblock(WOLFSSL* ssl, int nonblock)
00708 {
00709     WOLFSSL_ENTER("wolfSSL_set_using_nonblock");
00710     ssl->options.usingNonblock = (nonblock != 0);
00711 }
00712 
00713 
00714 int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
00715 {
00716 #ifdef WOLFSSL_DTLS
00717     void* sa = (void*)XMALLOC(peerSz, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
00718     if (sa != NULL) {
00719         if (ssl->buffers.dtlsCtx.peer.sa != NULL)
00720             XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
00721         XMEMCPY(sa, peer, peerSz);
00722         ssl->buffers.dtlsCtx.peer.sa = sa;
00723         ssl->buffers.dtlsCtx.peer.sz = peerSz;
00724         return SSL_SUCCESS;
00725     }
00726     return SSL_FAILURE;
00727 #else
00728     (void)ssl;
00729     (void)peer;
00730     (void)peerSz;
00731     return SSL_NOT_IMPLEMENTED;
00732 #endif
00733 }
00734 
00735 int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
00736 {
00737 #ifdef WOLFSSL_DTLS
00738     if (ssl == NULL) {
00739         return SSL_FAILURE;
00740     }
00741 
00742     if (peer != NULL && peerSz != NULL
00743             && *peerSz >= ssl->buffers.dtlsCtx.peer.sz
00744             && ssl->buffers.dtlsCtx.peer.sa != NULL) {
00745         *peerSz = ssl->buffers.dtlsCtx.peer.sz;
00746         XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
00747         return SSL_SUCCESS;
00748     }
00749     return SSL_FAILURE;
00750 #else
00751     (void)ssl;
00752     (void)peer;
00753     (void)peerSz;
00754     return SSL_NOT_IMPLEMENTED;
00755 #endif
00756 }
00757 
00758 
00759 #if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
00760 
00761 int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX* ctx)
00762 {
00763     WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_sctp()");
00764 
00765     if (ctx == NULL)
00766         return BAD_FUNC_ARG;
00767 
00768     ctx->dtlsSctp = 1;
00769     return SSL_SUCCESS;
00770 }
00771 
00772 
00773 int wolfSSL_dtls_set_sctp(WOLFSSL* ssl)
00774 {
00775     WOLFSSL_ENTER("wolfSSL_dtls_set_sctp()");
00776 
00777     if (ssl == NULL)
00778         return BAD_FUNC_ARG;
00779 
00780     ssl->options.dtlsSctp = 1;
00781     return SSL_SUCCESS;
00782 }
00783 
00784 
00785 int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word16 newMtu)
00786 {
00787     if (ctx == NULL || newMtu > MAX_RECORD_SIZE)
00788         return BAD_FUNC_ARG;
00789 
00790     ctx->dtlsMtuSz = newMtu;
00791     return SSL_SUCCESS;
00792 }
00793 
00794 
00795 int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu)
00796 {
00797     if (ssl == NULL)
00798         return BAD_FUNC_ARG;
00799 
00800     if (newMtu > MAX_RECORD_SIZE) {
00801         ssl->error = BAD_FUNC_ARG;
00802         return SSL_FAILURE;
00803     }
00804 
00805     ssl->dtlsMtuSz = newMtu;
00806     return SSL_SUCCESS;
00807 }
00808 
00809 
00810 #endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */
00811 
00812 #endif /* WOLFSSL_LEANPSK */
00813 
00814 
00815 /* return underlying connect or accept, SSL_SUCCESS on ok */
00816 int wolfSSL_negotiate(WOLFSSL* ssl)
00817 {
00818     int err = SSL_FATAL_ERROR;
00819 
00820     WOLFSSL_ENTER("wolfSSL_negotiate");
00821 #ifndef NO_WOLFSSL_SERVER
00822     if (ssl->options.side == WOLFSSL_SERVER_END)
00823         err = wolfSSL_accept(ssl);
00824 #endif
00825 
00826 #ifndef NO_WOLFSSL_CLIENT
00827     if (ssl->options.side == WOLFSSL_CLIENT_END)
00828         err = wolfSSL_connect(ssl);
00829 #endif
00830 
00831     WOLFSSL_LEAVE("wolfSSL_negotiate", err);
00832 
00833     return err;
00834 }
00835 
00836 
00837 WC_RNG* wolfSSL_GetRNG(WOLFSSL* ssl)
00838 {
00839     if (ssl) {
00840         return ssl->rng;
00841     }
00842 
00843     return NULL;
00844 }
00845 
00846 
00847 #ifndef WOLFSSL_LEANPSK
00848 /* object size based on build */
00849 int wolfSSL_GetObjectSize(void)
00850 {
00851 #ifdef SHOW_SIZES
00852     printf("sizeof suites           = %lu\n", sizeof(Suites));
00853     printf("sizeof ciphers(2)       = %lu\n", sizeof(Ciphers));
00854 #ifndef NO_RC4
00855     printf("\tsizeof arc4         = %lu\n", sizeof(Arc4));
00856 #endif
00857     printf("\tsizeof aes          = %lu\n", sizeof(Aes));
00858 #ifndef NO_DES3
00859     printf("\tsizeof des3         = %lu\n", sizeof(Des3));
00860 #endif
00861 #ifndef NO_RABBIT
00862     printf("\tsizeof rabbit       = %lu\n", sizeof(Rabbit));
00863 #endif
00864 #ifdef HAVE_CHACHA
00865     printf("\tsizeof chacha       = %lu\n", sizeof(ChaCha));
00866 #endif
00867     printf("sizeof cipher specs     = %lu\n", sizeof(CipherSpecs));
00868     printf("sizeof keys             = %lu\n", sizeof(Keys));
00869     printf("sizeof Hashes(2)        = %lu\n", sizeof(Hashes));
00870 #ifndef NO_MD5
00871     printf("\tsizeof MD5          = %lu\n", sizeof(Md5));
00872 #endif
00873 #ifndef NO_SHA
00874     printf("\tsizeof SHA          = %lu\n", sizeof(Sha));
00875 #endif
00876 #ifdef WOLFSSL_SHA224
00877     printf("    sizeof SHA224       = %lu\n", sizeof(Sha224));
00878 #endif
00879 #ifndef NO_SHA256
00880     printf("\tsizeof SHA256       = %lu\n", sizeof(Sha256));
00881 #endif
00882 #ifdef WOLFSSL_SHA384
00883     printf("\tsizeof SHA384       = %lu\n", sizeof(Sha384));
00884 #endif
00885 #ifdef WOLFSSL_SHA384
00886     printf("\tsizeof SHA512       = %lu\n", sizeof(Sha512));
00887 #endif
00888     printf("sizeof Buffers          = %lu\n", sizeof(Buffers));
00889     printf("sizeof Options          = %lu\n", sizeof(Options));
00890     printf("sizeof Arrays           = %lu\n", sizeof(Arrays));
00891 #ifndef NO_RSA
00892     printf("sizeof RsaKey           = %lu\n", sizeof(RsaKey));
00893 #endif
00894 #ifdef HAVE_ECC
00895     printf("sizeof ecc_key          = %lu\n", sizeof(ecc_key));
00896 #endif
00897     printf("sizeof WOLFSSL_CIPHER    = %lu\n", sizeof(WOLFSSL_CIPHER));
00898     printf("sizeof WOLFSSL_SESSION   = %lu\n", sizeof(WOLFSSL_SESSION));
00899     printf("sizeof WOLFSSL           = %lu\n", sizeof(WOLFSSL));
00900     printf("sizeof WOLFSSL_CTX       = %lu\n", sizeof(WOLFSSL_CTX));
00901 #endif
00902 
00903     return sizeof(WOLFSSL);
00904 }
00905 #endif
00906 
00907 
00908 #ifdef WOLFSSL_STATIC_MEMORY
00909 
00910 int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx, wolfSSL_method_func method,
00911                                    unsigned char* buf, unsigned int sz,
00912                                    int flag, int max)
00913 {
00914     WOLFSSL_HEAP*      heap;
00915     WOLFSSL_HEAP_HINT* hint;
00916     word32 idx = 0;
00917 
00918     if (ctx == NULL || buf == NULL) {
00919         return BAD_FUNC_ARG;
00920     }
00921 
00922     if (*ctx == NULL && method == NULL) {
00923         return BAD_FUNC_ARG;
00924     }
00925 
00926     if (*ctx == NULL || (*ctx)->heap == NULL) {
00927         if (sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT) > sz - idx) {
00928             return BUFFER_E; /* not enough memory for structures */
00929         }
00930         heap = (WOLFSSL_HEAP*)buf;
00931         idx += sizeof(WOLFSSL_HEAP);
00932         if (wolfSSL_init_memory_heap(heap) != 0) {
00933             return SSL_FAILURE;
00934         }
00935         hint = (WOLFSSL_HEAP_HINT*)(buf + idx);
00936         idx += sizeof(WOLFSSL_HEAP_HINT);
00937         XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT));
00938         hint->memory = heap;
00939 
00940         if (*ctx && (*ctx)->heap == NULL) {
00941             (*ctx)->heap = (void*)hint;
00942         }
00943     }
00944     else {
00945 #ifdef WOLFSSL_HEAP_TEST
00946         /* do not load in memory if test has been set */
00947         if ((*ctx)->heap == (void*)WOLFSSL_HEAP_TEST) {
00948             return SSL_SUCCESS;
00949         }
00950 #endif
00951         hint = (WOLFSSL_HEAP_HINT*)((*ctx)->heap);
00952         heap = hint->memory;
00953     }
00954 
00955     if (wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap) != 1) {
00956         WOLFSSL_MSG("Error partitioning memory");
00957         return SSL_FAILURE;
00958     }
00959 
00960     /* create ctx if needed */
00961     if (*ctx == NULL) {
00962         *ctx = wolfSSL_CTX_new_ex(method(hint), hint);
00963         if (*ctx == NULL) {
00964             WOLFSSL_MSG("Error creating ctx");
00965             return SSL_FAILURE;
00966         }
00967     }
00968 
00969     /* determine what max applies too */
00970     if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
00971         heap->maxIO = max;
00972     }
00973     else { /* general memory used in handshakes */
00974         heap->maxHa = max;
00975     }
00976 
00977     heap->flag |= flag;
00978 
00979     (void)max;
00980     (void)method;
00981 
00982     return SSL_SUCCESS;
00983 }
00984 
00985 
00986 int wolfSSL_is_static_memory(WOLFSSL* ssl, WOLFSSL_MEM_CONN_STATS* mem_stats)
00987 {
00988     if (ssl == NULL) {
00989         return BAD_FUNC_ARG;
00990     }
00991     WOLFSSL_ENTER("wolfSSL_is_static_memory");
00992 
00993     /* fill out statistics if wanted and WOLFMEM_TRACK_STATS flag */
00994     if (mem_stats != NULL && ssl->heap != NULL) {
00995         WOLFSSL_HEAP_HINT* hint = ((WOLFSSL_HEAP_HINT*)(ssl->heap));
00996         WOLFSSL_HEAP* heap      = hint->memory;
00997         if (heap->flag & WOLFMEM_TRACK_STATS && hint->stats != NULL) {
00998             XMEMCPY(mem_stats, hint->stats, sizeof(WOLFSSL_MEM_CONN_STATS));
00999         }
01000     }
01001 
01002     return (ssl->heap) ? 1 : 0;
01003 }
01004 
01005 
01006 int wolfSSL_CTX_is_static_memory(WOLFSSL_CTX* ctx, WOLFSSL_MEM_STATS* mem_stats)
01007 {
01008     if (ctx == NULL) {
01009         return BAD_FUNC_ARG;
01010     }
01011     WOLFSSL_ENTER("wolfSSL_CTX_is_static_memory");
01012 
01013     /* fill out statistics if wanted */
01014     if (mem_stats != NULL && ctx->heap != NULL) {
01015         WOLFSSL_HEAP* heap = ((WOLFSSL_HEAP_HINT*)(ctx->heap))->memory;
01016         if (wolfSSL_GetMemStats(heap, mem_stats) != 1) {
01017             return MEMORY_E;
01018         }
01019     }
01020 
01021     return (ctx->heap) ? 1 : 0;
01022 }
01023 
01024 #endif /* WOLFSSL_STATIC_MEMORY */
01025 
01026 
01027 /* return max record layer size plaintext input size */
01028 int wolfSSL_GetMaxOutputSize(WOLFSSL* ssl)
01029 {
01030     int maxSize = OUTPUT_RECORD_SIZE;
01031 
01032     WOLFSSL_ENTER("wolfSSL_GetMaxOutputSize");
01033 
01034     if (ssl == NULL)
01035         return BAD_FUNC_ARG;
01036 
01037     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
01038         WOLFSSL_MSG("Handshake not complete yet");
01039         return BAD_FUNC_ARG;
01040     }
01041 
01042 #ifdef HAVE_MAX_FRAGMENT
01043     maxSize = min(maxSize, ssl->max_fragment);
01044 #endif
01045 
01046 #ifdef WOLFSSL_DTLS
01047     if (ssl->options.dtls) {
01048         maxSize = min(maxSize, MAX_UDP_SIZE);
01049     }
01050 #endif
01051 
01052     return maxSize;
01053 }
01054 
01055 
01056 /* return record layer size of plaintext input size */
01057 int wolfSSL_GetOutputSize(WOLFSSL* ssl, int inSz)
01058 {
01059     int maxSize;
01060 
01061     WOLFSSL_ENTER("wolfSSL_GetOutputSize");
01062 
01063     if (inSz < 0)
01064         return BAD_FUNC_ARG;
01065 
01066     maxSize = wolfSSL_GetMaxOutputSize(ssl);
01067     if (maxSize < 0)
01068         return maxSize;   /* error */
01069     if (inSz > maxSize)
01070         return INPUT_SIZE_E;
01071 
01072     return BuildMessage(ssl, NULL, 0, NULL, inSz, application_data, 0, 1, 0);
01073 }
01074 
01075 
01076 #ifdef HAVE_ECC
01077 int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz)
01078 {
01079     if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
01080         WOLFSSL_MSG("Key size must be divisable by 8 or ctx was null");
01081         return BAD_FUNC_ARG;
01082     }
01083 
01084     ctx->minEccKeySz     = keySz / 8;
01085     ctx->cm->minEccKeySz = keySz / 8;
01086     return SSL_SUCCESS;
01087 }
01088 
01089 
01090 int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz)
01091 {
01092     if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
01093         WOLFSSL_MSG("Key size must be divisable by 8 or ssl was null");
01094         return BAD_FUNC_ARG;
01095     }
01096 
01097     ssl->options.minEccKeySz = keySz / 8;
01098     return SSL_SUCCESS;
01099 }
01100 
01101 #endif /* !NO_RSA */
01102 
01103 #ifndef NO_RSA
01104 int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX* ctx, short keySz)
01105 {
01106     if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
01107         WOLFSSL_MSG("Key size must be divisable by 8 or ctx was null");
01108         return BAD_FUNC_ARG;
01109     }
01110 
01111     ctx->minRsaKeySz     = keySz / 8;
01112     ctx->cm->minRsaKeySz = keySz / 8;
01113     return SSL_SUCCESS;
01114 }
01115 
01116 
01117 int wolfSSL_SetMinRsaKey_Sz(WOLFSSL* ssl, short keySz)
01118 {
01119     if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
01120         WOLFSSL_MSG("Key size must be divisable by 8 or ssl was null");
01121         return BAD_FUNC_ARG;
01122     }
01123 
01124     ssl->options.minRsaKeySz = keySz / 8;
01125     return SSL_SUCCESS;
01126 }
01127 #endif /* !NO_RSA */
01128 
01129 #ifndef NO_DH
01130 /* server Diffie-Hellman parameters, SSL_SUCCESS on ok */
01131 int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
01132                     const unsigned char* g, int gSz)
01133 {
01134     word16 havePSK = 0;
01135     word16 haveRSA = 1;
01136 
01137     WOLFSSL_ENTER("wolfSSL_SetTmpDH");
01138     if (ssl == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
01139 
01140     if (pSz < ssl->options.minDhKeySz)
01141         return DH_KEY_SIZE_E;
01142 
01143     if (ssl->options.side != WOLFSSL_SERVER_END)
01144         return SIDE_ERROR;
01145 
01146     if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
01147         XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
01148         ssl->buffers.serverDH_P.buffer = NULL;
01149     }
01150     if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
01151         XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
01152         ssl->buffers.serverDH_G.buffer = NULL;
01153     }
01154 
01155     ssl->buffers.weOwnDH = 1;  /* SSL owns now */
01156     ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->heap,
01157                                                     DYNAMIC_TYPE_DH_BUFFER);
01158     if (ssl->buffers.serverDH_P.buffer == NULL)
01159         return MEMORY_E;
01160 
01161     ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, ssl->heap,
01162                                                     DYNAMIC_TYPE_DH_BUFFER);
01163     if (ssl->buffers.serverDH_G.buffer == NULL) {
01164         XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
01165         ssl->buffers.serverDH_P.buffer = NULL;
01166         return MEMORY_E;
01167     }
01168 
01169     ssl->buffers.serverDH_P.length = pSz;
01170     ssl->buffers.serverDH_G.length = gSz;
01171 
01172     XMEMCPY(ssl->buffers.serverDH_P.buffer, p, pSz);
01173     XMEMCPY(ssl->buffers.serverDH_G.buffer, g, gSz);
01174 
01175     ssl->options.haveDH = 1;
01176     #ifndef NO_PSK
01177         havePSK = ssl->options.havePSK;
01178     #endif
01179     #ifdef NO_RSA
01180         haveRSA = 0;
01181     #endif
01182     InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH,
01183                ssl->options.haveNTRU, ssl->options.haveECDSAsig,
01184                ssl->options.haveECC, ssl->options.haveStaticECC,
01185                ssl->options.side);
01186 
01187     WOLFSSL_LEAVE("wolfSSL_SetTmpDH", 0);
01188     return SSL_SUCCESS;
01189 }
01190 
01191 /* server ctx Diffie-Hellman parameters, SSL_SUCCESS on ok */
01192 int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
01193                          const unsigned char* g, int gSz)
01194 {
01195     WOLFSSL_ENTER("wolfSSL_CTX_SetTmpDH");
01196     if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
01197 
01198     if (pSz < ctx->minDhKeySz)
01199         return DH_KEY_SIZE_E;
01200 
01201     XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH_BUFFER);
01202     XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH_BUFFER);
01203 
01204     ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_DH_BUFFER);
01205     if (ctx->serverDH_P.buffer == NULL)
01206        return MEMORY_E;
01207 
01208     ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_DH_BUFFER);
01209     if (ctx->serverDH_G.buffer == NULL) {
01210         XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH_BUFFER);
01211         return MEMORY_E;
01212     }
01213 
01214     ctx->serverDH_P.length = pSz;
01215     ctx->serverDH_G.length = gSz;
01216 
01217     XMEMCPY(ctx->serverDH_P.buffer, p, pSz);
01218     XMEMCPY(ctx->serverDH_G.buffer, g, gSz);
01219 
01220     ctx->haveDH = 1;
01221 
01222     WOLFSSL_LEAVE("wolfSSL_CTX_SetTmpDH", 0);
01223     return SSL_SUCCESS;
01224 }
01225 
01226 
01227 int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz)
01228 {
01229     if (ctx == NULL || keySz > 16000 || keySz % 8 != 0)
01230         return BAD_FUNC_ARG;
01231 
01232     ctx->minDhKeySz = keySz / 8;
01233     return SSL_SUCCESS;
01234 }
01235 
01236 
01237 int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz)
01238 {
01239     if (ssl == NULL || keySz > 16000 || keySz % 8 != 0)
01240         return BAD_FUNC_ARG;
01241 
01242     ssl->options.minDhKeySz = keySz / 8;
01243     return SSL_SUCCESS;
01244 }
01245 
01246 
01247 int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl)
01248 {
01249     if (ssl == NULL)
01250         return BAD_FUNC_ARG;
01251 
01252     return (ssl->options.dhKeySz * 8);
01253 }
01254 
01255 #endif /* !NO_DH */
01256 
01257 
01258 int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
01259 {
01260     int ret;
01261 
01262     WOLFSSL_ENTER("SSL_write()");
01263 
01264     if (ssl == NULL || data == NULL || sz < 0)
01265         return BAD_FUNC_ARG;
01266 
01267 #ifdef HAVE_WRITE_DUP
01268     { /* local variable scope */
01269         int dupErr = 0;   /* local copy */
01270 
01271         ret = 0;
01272 
01273         if (ssl->dupWrite && ssl->dupSide == READ_DUP_SIDE) {
01274             WOLFSSL_MSG("Read dup side cannot write");
01275             return WRITE_DUP_WRITE_E;
01276         }
01277         if (ssl->dupWrite) {
01278             if (wc_LockMutex(&ssl->dupWrite->dupMutex) != 0) {
01279                 return BAD_MUTEX_E;
01280             }
01281             dupErr = ssl->dupWrite->dupErr;
01282             ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
01283         }
01284 
01285         if (ret != 0) {
01286             ssl->error = ret;  /* high priority fatal error */
01287             return SSL_FATAL_ERROR;
01288         }
01289         if (dupErr != 0) {
01290             WOLFSSL_MSG("Write dup error from other side");
01291             ssl->error = dupErr;
01292             return SSL_FATAL_ERROR;
01293         }
01294     }
01295 #endif
01296 
01297 #ifdef HAVE_ERRNO_H
01298     errno = 0;
01299 #endif
01300 
01301     ret = SendData(ssl, data, sz);
01302 
01303     WOLFSSL_LEAVE("SSL_write()", ret);
01304 
01305     if (ret < 0)
01306         return SSL_FATAL_ERROR;
01307     else
01308         return ret;
01309 }
01310 
01311 
01312 static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
01313 {
01314     int ret;
01315 
01316     WOLFSSL_ENTER("wolfSSL_read_internal()");
01317 
01318     if (ssl == NULL || data == NULL || sz < 0)
01319         return BAD_FUNC_ARG;
01320 
01321 #ifdef HAVE_WRITE_DUP
01322     if (ssl->dupWrite && ssl->dupSide == WRITE_DUP_SIDE) {
01323         WOLFSSL_MSG("Write dup side cannot read");
01324         return WRITE_DUP_READ_E;
01325     }
01326 #endif
01327 
01328 #ifdef HAVE_ERRNO_H
01329         errno = 0;
01330 #endif
01331 
01332 #ifdef WOLFSSL_DTLS
01333     if (ssl->options.dtls) {
01334         ssl->dtls_expected_rx = max(sz + 100, MAX_MTU);
01335 #ifdef WOLFSSL_SCTP
01336         if (ssl->options.dtlsSctp)
01337             ssl->dtls_expected_rx = max(ssl->dtls_expected_rx, ssl->dtlsMtuSz);
01338 #endif
01339     }
01340 #endif
01341 
01342     sz = min(sz, OUTPUT_RECORD_SIZE);
01343 #ifdef HAVE_MAX_FRAGMENT
01344     sz = min(sz, ssl->max_fragment);
01345 #endif
01346     ret = ReceiveData(ssl, (byte*)data, sz, peek);
01347 
01348 #ifdef HAVE_WRITE_DUP
01349     if (ssl->dupWrite) {
01350         if (ssl->error != 0 && ssl->error != WANT_READ &&
01351                                ssl->error != WC_PENDING_E) {
01352             int notifyErr;
01353 
01354             WOLFSSL_MSG("Notifying write side of fatal read error");
01355             notifyErr  = NotifyWriteSide(ssl, ssl->error);
01356             if (notifyErr < 0) {
01357                 ret = ssl->error = notifyErr;
01358             }
01359         }
01360     }
01361 #endif
01362 
01363     WOLFSSL_LEAVE("wolfSSL_read_internal()", ret);
01364 
01365     if (ret < 0)
01366         return SSL_FATAL_ERROR;
01367     else
01368         return ret;
01369 }
01370 
01371 
01372 int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz)
01373 {
01374     WOLFSSL_ENTER("wolfSSL_peek()");
01375 
01376     return wolfSSL_read_internal(ssl, data, sz, TRUE);
01377 }
01378 
01379 
01380 int wolfSSL_read(WOLFSSL* ssl, void* data, int sz)
01381 {
01382     WOLFSSL_ENTER("wolfSSL_read()");
01383 
01384     return wolfSSL_read_internal(ssl, data, sz, FALSE);
01385 }
01386 
01387 
01388 #ifdef WOLFSSL_ASYNC_CRYPT
01389 
01390 /* let's use async hardware, SSL_SUCCESS on ok */
01391 int wolfSSL_UseAsync(WOLFSSL* ssl, int devId)
01392 {
01393     if (ssl == NULL)
01394         return BAD_FUNC_ARG;
01395 
01396     ssl->devId = devId;
01397 
01398     return SSL_SUCCESS;
01399 }
01400 
01401 
01402 /* let's use async hardware, SSL_SUCCESS on ok */
01403 int wolfSSL_CTX_UseAsync(WOLFSSL_CTX* ctx, int devId)
01404 {
01405     if (ctx == NULL)
01406         return BAD_FUNC_ARG;
01407 
01408     ctx->devId = devId;
01409 
01410     return SSL_SUCCESS;
01411 }
01412 
01413 #endif /* WOLFSSL_ASYNC_CRYPT */
01414 
01415 #ifdef HAVE_SNI
01416 
01417 int wolfSSL_UseSNI(WOLFSSL* ssl, byte type, const void* data, word16 size)
01418 {
01419     if (ssl == NULL)
01420         return BAD_FUNC_ARG;
01421 
01422     return TLSX_UseSNI(&ssl->extensions, type, data, size, ssl->heap);
01423 }
01424 
01425 
01426 int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, const void* data,
01427                                                                     word16 size)
01428 {
01429     if (ctx == NULL)
01430         return BAD_FUNC_ARG;
01431 
01432     return TLSX_UseSNI(&ctx->extensions, type, data, size, ctx->heap);
01433 }
01434 
01435 #ifndef NO_WOLFSSL_SERVER
01436 
01437 void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options)
01438 {
01439     if (ssl && ssl->extensions)
01440         TLSX_SNI_SetOptions(ssl->extensions, type, options);
01441 }
01442 
01443 
01444 void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options)
01445 {
01446     if (ctx && ctx->extensions)
01447         TLSX_SNI_SetOptions(ctx->extensions, type, options);
01448 }
01449 
01450 
01451 byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type)
01452 {
01453     return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type);
01454 }
01455 
01456 
01457 word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data)
01458 {
01459     if (data)
01460         *data = NULL;
01461 
01462     if (ssl && ssl->extensions)
01463         return TLSX_SNI_GetRequest(ssl->extensions, type, data);
01464 
01465     return 0;
01466 }
01467 
01468 
01469 int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
01470                               byte type, byte* sni, word32* inOutSz)
01471 {
01472     if (clientHello && helloSz > 0 && sni && inOutSz && *inOutSz > 0)
01473         return TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
01474 
01475     return BAD_FUNC_ARG;
01476 }
01477 
01478 #endif /* NO_WOLFSSL_SERVER */
01479 
01480 #endif /* HAVE_SNI */
01481 
01482 
01483 #ifdef HAVE_MAX_FRAGMENT
01484 #ifndef NO_WOLFSSL_CLIENT
01485 
01486 int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl)
01487 {
01488     if (ssl == NULL)
01489         return BAD_FUNC_ARG;
01490 
01491     return TLSX_UseMaxFragment(&ssl->extensions, mfl, ssl->heap);
01492 }
01493 
01494 
01495 int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl)
01496 {
01497     if (ctx == NULL)
01498         return BAD_FUNC_ARG;
01499 
01500     return TLSX_UseMaxFragment(&ctx->extensions, mfl, ctx->heap);
01501 }
01502 
01503 #endif /* NO_WOLFSSL_CLIENT */
01504 #endif /* HAVE_MAX_FRAGMENT */
01505 
01506 #ifdef HAVE_TRUNCATED_HMAC
01507 #ifndef NO_WOLFSSL_CLIENT
01508 
01509 int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl)
01510 {
01511     if (ssl == NULL)
01512         return BAD_FUNC_ARG;
01513 
01514     return TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap);
01515 }
01516 
01517 
01518 int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
01519 {
01520     if (ctx == NULL)
01521         return BAD_FUNC_ARG;
01522 
01523     return TLSX_UseTruncatedHMAC(&ctx->extensions, ctx->heap);
01524 }
01525 
01526 #endif /* NO_WOLFSSL_CLIENT */
01527 #endif /* HAVE_TRUNCATED_HMAC */
01528 
01529 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
01530 
01531 int wolfSSL_UseOCSPStapling(WOLFSSL* ssl, byte status_type, byte options)
01532 {
01533     if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
01534         return BAD_FUNC_ARG;
01535 
01536     return TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
01537                                                 options, ssl->heap, ssl->devId);
01538 }
01539 
01540 
01541 int wolfSSL_CTX_UseOCSPStapling(WOLFSSL_CTX* ctx, byte status_type,
01542                                                                    byte options)
01543 {
01544     if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
01545         return BAD_FUNC_ARG;
01546 
01547     return TLSX_UseCertificateStatusRequest(&ctx->extensions, status_type,
01548                                                 options, ctx->heap, ctx->devId);
01549 }
01550 
01551 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
01552 
01553 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
01554 
01555 int wolfSSL_UseOCSPStaplingV2(WOLFSSL* ssl, byte status_type, byte options)
01556 {
01557     if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
01558         return BAD_FUNC_ARG;
01559 
01560     return TLSX_UseCertificateStatusRequestV2(&ssl->extensions, status_type,
01561                                                 options, ssl->heap, ssl->devId);
01562 }
01563 
01564 
01565 int wolfSSL_CTX_UseOCSPStaplingV2(WOLFSSL_CTX* ctx,
01566                                                  byte status_type, byte options)
01567 {
01568     if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
01569         return BAD_FUNC_ARG;
01570 
01571     return TLSX_UseCertificateStatusRequestV2(&ctx->extensions, status_type,
01572                                                 options, ctx->heap, ctx->devId);
01573 }
01574 
01575 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
01576 
01577 /* Elliptic Curves */
01578 #ifdef HAVE_SUPPORTED_CURVES
01579 #ifndef NO_WOLFSSL_CLIENT
01580 
01581 int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
01582 {
01583     if (ssl == NULL)
01584         return BAD_FUNC_ARG;
01585 
01586     switch (name) {
01587         case WOLFSSL_ECC_SECP160K1:
01588         case WOLFSSL_ECC_SECP160R1:
01589         case WOLFSSL_ECC_SECP160R2:
01590         case WOLFSSL_ECC_SECP192K1:
01591         case WOLFSSL_ECC_SECP192R1:
01592         case WOLFSSL_ECC_SECP224K1:
01593         case WOLFSSL_ECC_SECP224R1:
01594         case WOLFSSL_ECC_SECP256K1:
01595         case WOLFSSL_ECC_SECP256R1:
01596         case WOLFSSL_ECC_SECP384R1:
01597         case WOLFSSL_ECC_SECP521R1:
01598         case WOLFSSL_ECC_BRAINPOOLP256R1:
01599         case WOLFSSL_ECC_BRAINPOOLP384R1:
01600         case WOLFSSL_ECC_BRAINPOOLP512R1:
01601             break;
01602 
01603 #ifdef WOLFSSL_TLS13
01604         case WOLFSSL_FFDHE_2048:
01605         case WOLFSSL_FFDHE_3072:
01606         case WOLFSSL_FFDHE_4096:
01607         case WOLFSSL_FFDHE_6144:
01608         case WOLFSSL_FFDHE_8192:
01609             if (!IsAtLeastTLSv1_3(ssl->version))
01610                 return SSL_SUCCESS;
01611             break;
01612 #endif
01613 
01614         default:
01615             return BAD_FUNC_ARG;
01616     }
01617 
01618     ssl->options.userCurves = 1;
01619 
01620     return TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap);
01621 }
01622 
01623 
01624 int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
01625 {
01626     if (ctx == NULL)
01627         return BAD_FUNC_ARG;
01628 
01629     switch (name) {
01630         case WOLFSSL_ECC_SECP160K1:
01631         case WOLFSSL_ECC_SECP160R1:
01632         case WOLFSSL_ECC_SECP160R2:
01633         case WOLFSSL_ECC_SECP192K1:
01634         case WOLFSSL_ECC_SECP192R1:
01635         case WOLFSSL_ECC_SECP224K1:
01636         case WOLFSSL_ECC_SECP224R1:
01637         case WOLFSSL_ECC_SECP256K1:
01638         case WOLFSSL_ECC_SECP256R1:
01639         case WOLFSSL_ECC_SECP384R1:
01640         case WOLFSSL_ECC_SECP521R1:
01641         case WOLFSSL_ECC_BRAINPOOLP256R1:
01642         case WOLFSSL_ECC_BRAINPOOLP384R1:
01643         case WOLFSSL_ECC_BRAINPOOLP512R1:
01644             break;
01645 
01646 #ifdef WOLFSSL_TLS13
01647         case WOLFSSL_FFDHE_2048:
01648         case WOLFSSL_FFDHE_3072:
01649         case WOLFSSL_FFDHE_4096:
01650         case WOLFSSL_FFDHE_6144:
01651         case WOLFSSL_FFDHE_8192:
01652             break;
01653 #endif
01654 
01655         default:
01656             return BAD_FUNC_ARG;
01657     }
01658 
01659     ctx->userCurves = 1;
01660 
01661     return TLSX_UseSupportedCurve(&ctx->extensions, name, ctx->heap);
01662 }
01663 
01664 #endif /* NO_WOLFSSL_CLIENT */
01665 #endif /* HAVE_SUPPORTED_CURVES */
01666 
01667 /* QSH quantum safe handshake */
01668 #ifdef HAVE_QSH
01669 /* returns 1 if QSH has been used 0 otherwise */
01670 int wolfSSL_isQSH(WOLFSSL* ssl)
01671 {
01672     /* if no ssl struct than QSH was not used */
01673     if (ssl == NULL)
01674         return 0;
01675 
01676     return ssl->isQSH;
01677 }
01678 
01679 
01680 int wolfSSL_UseSupportedQSH(WOLFSSL* ssl, word16 name)
01681 {
01682     if (ssl == NULL)
01683         return BAD_FUNC_ARG;
01684 
01685     switch (name) {
01686     #ifdef HAVE_NTRU
01687         case WOLFSSL_NTRU_EESS439:
01688         case WOLFSSL_NTRU_EESS593:
01689         case WOLFSSL_NTRU_EESS743:
01690             break;
01691     #endif
01692         default:
01693             return BAD_FUNC_ARG;
01694     }
01695 
01696     ssl->user_set_QSHSchemes = 1;
01697 
01698     return TLSX_UseQSHScheme(&ssl->extensions, name, NULL, 0, ssl->heap);
01699 }
01700 
01701 #ifndef NO_WOLFSSL_CLIENT
01702     /* user control over sending client public key in hello
01703        when flag = 1 will send keys if flag is 0 or function is not called
01704        then will not send keys in the hello extension
01705        return 0 on success
01706      */
01707     int wolfSSL_UseClientQSHKeys(WOLFSSL* ssl, unsigned char flag)
01708     {
01709         if (ssl == NULL)
01710             return BAD_FUNC_ARG;
01711 
01712         ssl->sendQSHKeys = flag;
01713 
01714         return 0;
01715     }
01716 #endif /* NO_WOLFSSL_CLIENT */
01717 #endif /* HAVE_QSH */
01718 
01719 /* Application-Layer Protocol Negotiation */
01720 #ifdef HAVE_ALPN
01721 
01722 int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
01723                     word32 protocol_name_listSz, byte options)
01724 {
01725     char    *list, *ptr, *token[10];
01726     word16  len;
01727     int     idx = 0;
01728     int     ret = SSL_FAILURE;
01729 
01730     WOLFSSL_ENTER("wolfSSL_UseALPN");
01731 
01732     if (ssl == NULL || protocol_name_list == NULL)
01733         return BAD_FUNC_ARG;
01734 
01735     if (protocol_name_listSz > (WOLFSSL_MAX_ALPN_NUMBER *
01736                                 WOLFSSL_MAX_ALPN_PROTO_NAME_LEN +
01737                                 WOLFSSL_MAX_ALPN_NUMBER)) {
01738         WOLFSSL_MSG("Invalid arguments, protocol name list too long");
01739         return BAD_FUNC_ARG;
01740     }
01741 
01742     if (!(options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) &&
01743         !(options & WOLFSSL_ALPN_FAILED_ON_MISMATCH)) {
01744             WOLFSSL_MSG("Invalid arguments, options not supported");
01745             return BAD_FUNC_ARG;
01746         }
01747 
01748 
01749     list = (char *)XMALLOC(protocol_name_listSz+1, ssl->heap,
01750                            DYNAMIC_TYPE_TMP_BUFFER);
01751     if (list == NULL) {
01752         WOLFSSL_MSG("Memory failure");
01753         return MEMORY_ERROR;
01754     }
01755 
01756     XMEMSET(list, 0, protocol_name_listSz+1);
01757     XSTRNCPY(list, protocol_name_list, protocol_name_listSz);
01758 
01759     /* read all protocol name from the list */
01760     token[idx] = XSTRTOK(list, ",", &ptr);
01761     while (token[idx] != NULL)
01762         token[++idx] = XSTRTOK(NULL, ",", &ptr);
01763 
01764     /* add protocol name list in the TLS extension in reverse order */
01765     while ((idx--) > 0) {
01766         len = (word16)XSTRLEN(token[idx]);
01767 
01768         ret = TLSX_UseALPN(&ssl->extensions, token[idx], len, options,
01769                                                                      ssl->heap);
01770         if (ret != SSL_SUCCESS) {
01771             WOLFSSL_MSG("TLSX_UseALPN failure");
01772             break;
01773         }
01774     }
01775 
01776     XFREE(list, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
01777 
01778     return ret;
01779 }
01780 
01781 int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name, word16 *size)
01782 {
01783     return TLSX_ALPN_GetRequest(ssl ? ssl->extensions : NULL,
01784                                (void **)protocol_name, size);
01785 }
01786 
01787 int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, word16 *listSz)
01788 {
01789     if (list == NULL || listSz == NULL)
01790         return BAD_FUNC_ARG;
01791 
01792     if (ssl->alpn_client_list == NULL)
01793         return BUFFER_ERROR;
01794 
01795     *listSz = (word16)XSTRLEN(ssl->alpn_client_list);
01796     if (*listSz == 0)
01797         return BUFFER_ERROR;
01798 
01799     *list = (char *)XMALLOC((*listSz)+1, ssl->heap, DYNAMIC_TYPE_TLSX);
01800     if (*list == NULL)
01801         return MEMORY_ERROR;
01802 
01803     XSTRNCPY(*list, ssl->alpn_client_list, (*listSz)+1);
01804     (*list)[*listSz] = 0;
01805 
01806     return SSL_SUCCESS;
01807 }
01808 
01809 
01810 /* used to free memory allocated by wolfSSL_ALPN_GetPeerProtocol */
01811 int wolfSSL_ALPN_FreePeerProtocol(WOLFSSL* ssl, char **list)
01812 {
01813     if (ssl == NULL) {
01814         return BAD_FUNC_ARG;
01815     }
01816 
01817     XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
01818     *list = NULL;
01819 
01820     return SSL_SUCCESS;
01821 }
01822 
01823 #endif /* HAVE_ALPN */
01824 
01825 /* Secure Renegotiation */
01826 #ifdef HAVE_SECURE_RENEGOTIATION
01827 
01828 /* user is forcing ability to use secure renegotiation, we discourage it */
01829 int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl)
01830 {
01831     int ret = BAD_FUNC_ARG;
01832 
01833     if (ssl)
01834         ret = TLSX_UseSecureRenegotiation(&ssl->extensions, ssl->heap);
01835 
01836     if (ret == SSL_SUCCESS) {
01837         TLSX* extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO);
01838 
01839         if (extension)
01840             ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
01841     }
01842 
01843     return ret;
01844 }
01845 
01846 
01847 /* do a secure renegotiation handshake, user forced, we discourage */
01848 int wolfSSL_Rehandshake(WOLFSSL* ssl)
01849 {
01850     int ret;
01851 
01852     if (ssl == NULL)
01853         return BAD_FUNC_ARG;
01854 
01855     if (ssl->secure_renegotiation == NULL) {
01856         WOLFSSL_MSG("Secure Renegotiation not forced on by user");
01857         return SECURE_RENEGOTIATION_E;
01858     }
01859 
01860     if (ssl->secure_renegotiation->enabled == 0) {
01861         WOLFSSL_MSG("Secure Renegotiation not enabled at extension level");
01862         return SECURE_RENEGOTIATION_E;
01863     }
01864 
01865     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
01866         WOLFSSL_MSG("Can't renegotiate until previous handshake complete");
01867         return SECURE_RENEGOTIATION_E;
01868     }
01869 
01870 #ifndef NO_FORCE_SCR_SAME_SUITE
01871     /* force same suite */
01872     if (ssl->suites) {
01873         ssl->suites->suiteSz = SUITE_LEN;
01874         ssl->suites->suites[0] = ssl->options.cipherSuite0;
01875         ssl->suites->suites[1] = ssl->options.cipherSuite;
01876     }
01877 #endif
01878 
01879     /* reset handshake states */
01880     ssl->options.serverState = NULL_STATE;
01881     ssl->options.clientState = NULL_STATE;
01882     ssl->options.connectState  = CONNECT_BEGIN;
01883     ssl->options.acceptState   = ACCEPT_BEGIN;
01884     ssl->options.handShakeState = NULL_STATE;
01885     ssl->options.processReply  = 0;  /* TODO, move states in internal.h */
01886 
01887     XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
01888 
01889     ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
01890 
01891     ret = InitHandshakeHashes(ssl);
01892     if (ret !=0)
01893         return ret;
01894 
01895     ret = wolfSSL_negotiate(ssl);
01896     return ret;
01897 }
01898 
01899 #endif /* HAVE_SECURE_RENEGOTIATION */
01900 
01901 /* Session Ticket */
01902 #if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SESSION_TICKET)
01903 /* SSL_SUCCESS on ok */
01904 int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
01905 {
01906     if (ctx == NULL)
01907         return BAD_FUNC_ARG;
01908 
01909     ctx->ticketEncCb = cb;
01910 
01911     return SSL_SUCCESS;
01912 }
01913 
01914 /* set hint interval, SSL_SUCCESS on ok */
01915 int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
01916 {
01917     if (ctx == NULL)
01918         return BAD_FUNC_ARG;
01919 
01920     ctx->ticketHint = hint;
01921 
01922     return SSL_SUCCESS;
01923 }
01924 
01925 /* set user context, SSL_SUCCESS on ok */
01926 int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void* userCtx)
01927 {
01928     if (ctx == NULL)
01929         return BAD_FUNC_ARG;
01930 
01931     ctx->ticketEncCtx = userCtx;
01932 
01933     return SSL_SUCCESS;
01934 }
01935 
01936 #endif /* !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET) */
01937 
01938 /* Session Ticket */
01939 #if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET)
01940 int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
01941 {
01942     if (ssl == NULL)
01943         return BAD_FUNC_ARG;
01944 
01945     return TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
01946 }
01947 
01948 int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx)
01949 {
01950     if (ctx == NULL)
01951         return BAD_FUNC_ARG;
01952 
01953     return TLSX_UseSessionTicket(&ctx->extensions, NULL, ctx->heap);
01954 }
01955 
01956 WOLFSSL_API int wolfSSL_get_SessionTicket(WOLFSSL* ssl,
01957                                           byte* buf, word32* bufSz)
01958 {
01959     if (ssl == NULL || buf == NULL || bufSz == NULL || *bufSz == 0)
01960         return BAD_FUNC_ARG;
01961 
01962     if (ssl->session.ticketLen <= *bufSz) {
01963         XMEMCPY(buf, ssl->session.ticket, ssl->session.ticketLen);
01964         *bufSz = ssl->session.ticketLen;
01965     }
01966     else
01967         *bufSz = 0;
01968 
01969     return SSL_SUCCESS;
01970 }
01971 
01972 WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const byte* buf,
01973                                           word32 bufSz)
01974 {
01975     if (ssl == NULL || (buf == NULL && bufSz > 0))
01976         return BAD_FUNC_ARG;
01977 
01978     if (bufSz > 0) {
01979         /* Ticket will fit into static ticket */
01980         if(bufSz <= SESSION_TICKET_LEN) {
01981             if (ssl->session.isDynamic) {
01982                 XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
01983                 ssl->session.isDynamic = 0;
01984                 ssl->session.ticket = ssl->session.staticTicket;
01985             }
01986         } else { /* Ticket requires dynamic ticket storage */
01987             if (ssl->session.ticketLen < bufSz) { /* is dyn buffer big enough */
01988                 if(ssl->session.isDynamic)
01989                     XFREE(ssl->session.ticket, ssl->heap,
01990                             DYNAMIC_TYPE_SESSION_TICK);
01991                 ssl->session.ticket = (byte*)XMALLOC(bufSz, ssl->heap,
01992                         DYNAMIC_TYPE_SESSION_TICK);
01993                 if(!ssl->session.ticket) {
01994                     ssl->session.ticket = ssl->session.staticTicket;
01995                     ssl->session.isDynamic = 0;
01996                     return MEMORY_ERROR;
01997                 }
01998                 ssl->session.isDynamic = 1;
01999             }
02000         }
02001         XMEMCPY(ssl->session.ticket, buf, bufSz);
02002     }
02003     ssl->session.ticketLen = (word16)bufSz;
02004 
02005     return SSL_SUCCESS;
02006 }
02007 
02008 
02009 WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
02010                                             CallbackSessionTicket cb, void* ctx)
02011 {
02012     if (ssl == NULL)
02013         return BAD_FUNC_ARG;
02014 
02015     ssl->session_ticket_cb = cb;
02016     ssl->session_ticket_ctx = ctx;
02017 
02018     return SSL_SUCCESS;
02019 }
02020 #endif
02021 
02022 
02023 #ifdef HAVE_EXTENDED_MASTER
02024 #ifndef NO_WOLFSSL_CLIENT
02025 
02026 int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx)
02027 {
02028     if (ctx == NULL)
02029         return BAD_FUNC_ARG;
02030 
02031     ctx->haveEMS = 0;
02032 
02033     return SSL_SUCCESS;
02034 }
02035 
02036 
02037 int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl)
02038 {
02039     if (ssl == NULL)
02040         return BAD_FUNC_ARG;
02041 
02042     ssl->options.haveEMS = 0;
02043 
02044     return SSL_SUCCESS;
02045 }
02046 
02047 #endif
02048 #endif
02049 
02050 
02051 #ifndef WOLFSSL_LEANPSK
02052 
02053 int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags)
02054 {
02055     int ret;
02056     int oldFlags;
02057 
02058     WOLFSSL_ENTER("wolfSSL_send()");
02059 
02060     if (ssl == NULL || data == NULL || sz < 0)
02061         return BAD_FUNC_ARG;
02062 
02063     oldFlags = ssl->wflags;
02064 
02065     ssl->wflags = flags;
02066     ret = wolfSSL_write(ssl, data, sz);
02067     ssl->wflags = oldFlags;
02068 
02069     WOLFSSL_LEAVE("wolfSSL_send()", ret);
02070 
02071     return ret;
02072 }
02073 
02074 
02075 int wolfSSL_recv(WOLFSSL* ssl, void* data, int sz, int flags)
02076 {
02077     int ret;
02078     int oldFlags;
02079 
02080     WOLFSSL_ENTER("wolfSSL_recv()");
02081 
02082     if (ssl == NULL || data == NULL || sz < 0)
02083         return BAD_FUNC_ARG;
02084 
02085     oldFlags = ssl->rflags;
02086 
02087     ssl->rflags = flags;
02088     ret = wolfSSL_read(ssl, data, sz);
02089     ssl->rflags = oldFlags;
02090 
02091     WOLFSSL_LEAVE("wolfSSL_recv()", ret);
02092 
02093     return ret;
02094 }
02095 #endif
02096 
02097 
02098 /* SSL_SUCCESS on ok */
02099 int wolfSSL_shutdown(WOLFSSL* ssl)
02100 {
02101     int  ret = SSL_FATAL_ERROR;
02102     byte tmp;
02103     WOLFSSL_ENTER("SSL_shutdown()");
02104 
02105     if (ssl == NULL)
02106         return SSL_FATAL_ERROR;
02107 
02108     if (ssl->options.quietShutdown) {
02109         WOLFSSL_MSG("quiet shutdown, no close notify sent");
02110         return SSL_SUCCESS;
02111     }
02112 
02113     /* try to send close notify, not an error if can't */
02114     if (!ssl->options.isClosed && !ssl->options.connReset &&
02115                                   !ssl->options.sentNotify) {
02116         ssl->error = SendAlert(ssl, alert_warning, close_notify);
02117         if (ssl->error < 0) {
02118             WOLFSSL_ERROR(ssl->error);
02119             return SSL_FATAL_ERROR;
02120         }
02121         ssl->options.sentNotify = 1;  /* don't send close_notify twice */
02122         if (ssl->options.closeNotify)
02123             ret = SSL_SUCCESS;
02124         else
02125             ret = SSL_SHUTDOWN_NOT_DONE;
02126 
02127         WOLFSSL_LEAVE("SSL_shutdown()", ret);
02128         return ret;
02129     }
02130 
02131     /* call wolfSSL_shutdown again for bidirectional shutdown */
02132     if (ssl->options.sentNotify && !ssl->options.closeNotify) {
02133         ret = wolfSSL_read(ssl, &tmp, 0);
02134         if (ret < 0) {
02135             WOLFSSL_ERROR(ssl->error);
02136             ret = SSL_FATAL_ERROR;
02137         } else if (ssl->options.closeNotify) {
02138             ssl->error = SSL_ERROR_SYSCALL;   /* simulate OpenSSL behavior */
02139             ret = SSL_SUCCESS;
02140         }
02141     }
02142 
02143     WOLFSSL_LEAVE("SSL_shutdown()", ret);
02144 
02145     return ret;
02146 }
02147 
02148 
02149 /* get current error state value */
02150 int wolfSSL_state(WOLFSSL* ssl)
02151 {
02152     if (ssl == NULL) {
02153         return BAD_FUNC_ARG;
02154     }
02155 
02156     return ssl->error;
02157 }
02158 
02159 
02160 int wolfSSL_get_error(WOLFSSL* ssl, int ret)
02161 {
02162     WOLFSSL_ENTER("SSL_get_error");
02163 
02164     if (ret > 0)
02165         return SSL_ERROR_NONE;
02166     if (ssl == NULL)
02167         return BAD_FUNC_ARG;
02168 
02169     WOLFSSL_LEAVE("SSL_get_error", ssl->error);
02170 
02171     /* make sure converted types are handled in SetErrorString() too */
02172     if (ssl->error == WANT_READ)
02173         return SSL_ERROR_WANT_READ;         /* convert to OpenSSL type */
02174     else if (ssl->error == WANT_WRITE)
02175         return SSL_ERROR_WANT_WRITE;        /* convert to OpenSSL type */
02176     else if (ssl->error == ZERO_RETURN)
02177         return SSL_ERROR_ZERO_RETURN;       /* convert to OpenSSL type */
02178     return ssl->error;
02179 }
02180 
02181 
02182 /* retrive alert history, SSL_SUCCESS on ok */
02183 int wolfSSL_get_alert_history(WOLFSSL* ssl, WOLFSSL_ALERT_HISTORY *h)
02184 {
02185     if (ssl && h) {
02186         *h = ssl->alert_history;
02187     }
02188     return SSL_SUCCESS;
02189 }
02190 
02191 
02192 /* return TRUE if current error is want read */
02193 int wolfSSL_want_read(WOLFSSL* ssl)
02194 {
02195     WOLFSSL_ENTER("SSL_want_read");
02196     if (ssl->error == WANT_READ)
02197         return 1;
02198 
02199     return 0;
02200 }
02201 
02202 
02203 /* return TRUE if current error is want write */
02204 int wolfSSL_want_write(WOLFSSL* ssl)
02205 {
02206     WOLFSSL_ENTER("SSL_want_write");
02207     if (ssl->error == WANT_WRITE)
02208         return 1;
02209 
02210     return 0;
02211 }
02212 
02213 
02214 char* wolfSSL_ERR_error_string(unsigned long errNumber, char* data)
02215 {
02216     static const char* msg = "Please supply a buffer for error string";
02217 
02218     WOLFSSL_ENTER("ERR_error_string");
02219     if (data) {
02220         SetErrorString((int)errNumber, data);
02221         return data;
02222     }
02223 
02224     return (char*)msg;
02225 }
02226 
02227 
02228 void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
02229 {
02230     WOLFSSL_ENTER("wolfSSL_ERR_error_string_n");
02231     if (len >= WOLFSSL_MAX_ERROR_SZ)
02232         wolfSSL_ERR_error_string(e, buf);
02233     else {
02234         char tmp[WOLFSSL_MAX_ERROR_SZ];
02235 
02236         WOLFSSL_MSG("Error buffer too short, truncating");
02237         if (len) {
02238             wolfSSL_ERR_error_string(e, tmp);
02239             XMEMCPY(buf, tmp, len-1);
02240             buf[len-1] = '\0';
02241         }
02242     }
02243 }
02244 
02245 
02246 /* don't free temporary arrays at end of handshake */
02247 void wolfSSL_KeepArrays(WOLFSSL* ssl)
02248 {
02249     if (ssl)
02250         ssl->options.saveArrays = 1;
02251 }
02252 
02253 
02254 /* user doesn't need temporary arrays anymore, Free */
02255 void wolfSSL_FreeArrays(WOLFSSL* ssl)
02256 {
02257     if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
02258         ssl->options.saveArrays = 0;
02259         FreeArrays(ssl, 1);
02260     }
02261 }
02262 
02263 /* Set option to indicate that the resources are not to be freed after
02264  * handshake.
02265  *
02266  * ssl  The SSL/TLS object.
02267  * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
02268  */
02269 int wolfSSL_KeepHandshakeResources(WOLFSSL* ssl)
02270 {
02271     if (ssl == NULL)
02272         return BAD_FUNC_ARG;
02273 
02274     ssl->options.keepResources = 1;
02275 
02276     return 0;
02277 }
02278 
02279 /* Free the handshake resources after handshake.
02280  *
02281  * ssl  The SSL/TLS object.
02282  * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
02283  */
02284 int wolfSSL_FreeHandshakeResources(WOLFSSL* ssl)
02285 {
02286     if (ssl == NULL)
02287         return BAD_FUNC_ARG;
02288 
02289     FreeHandshakeResources(ssl);
02290 
02291     return 0;
02292 }
02293 
02294 /* Use the client's order of preference when matching cipher suites.
02295  *
02296  * ssl  The SSL/TLS context object.
02297  * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
02298  */
02299 int wolfSSL_CTX_UseClientSuites(WOLFSSL_CTX* ctx)
02300 {
02301     if (ctx == NULL)
02302         return BAD_FUNC_ARG;
02303 
02304     ctx->useClientOrder = 1;
02305 
02306     return 0;
02307 }
02308 
02309 /* Use the client's order of preference when matching cipher suites.
02310  *
02311  * ssl  The SSL/TLS object.
02312  * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
02313  */
02314 int wolfSSL_UseClientSuites(WOLFSSL* ssl)
02315 {
02316     if (ssl == NULL)
02317         return BAD_FUNC_ARG;
02318 
02319     ssl->options.useClientOrder = 1;
02320 
02321     return 0;
02322 }
02323 
02324 const byte* wolfSSL_GetMacSecret(WOLFSSL* ssl, int verify)
02325 {
02326     if (ssl == NULL)
02327         return NULL;
02328 
02329     if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
02330          (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
02331         return ssl->keys.client_write_MAC_secret;
02332     else
02333         return ssl->keys.server_write_MAC_secret;
02334 }
02335 
02336 
02337 #ifdef ATOMIC_USER
02338 
02339 void  wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX* ctx, CallbackMacEncrypt cb)
02340 {
02341     if (ctx)
02342         ctx->MacEncryptCb = cb;
02343 }
02344 
02345 
02346 void  wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx)
02347 {
02348     if (ssl)
02349         ssl->MacEncryptCtx = ctx;
02350 }
02351 
02352 
02353 void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl)
02354 {
02355     if (ssl)
02356         return ssl->MacEncryptCtx;
02357 
02358     return NULL;
02359 }
02360 
02361 
02362 void  wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX* ctx, CallbackDecryptVerify cb)
02363 {
02364     if (ctx)
02365         ctx->DecryptVerifyCb = cb;
02366 }
02367 
02368 
02369 void  wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx)
02370 {
02371     if (ssl)
02372         ssl->DecryptVerifyCtx = ctx;
02373 }
02374 
02375 
02376 void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl)
02377 {
02378     if (ssl)
02379         return ssl->DecryptVerifyCtx;
02380 
02381     return NULL;
02382 }
02383 
02384 
02385 const byte* wolfSSL_GetClientWriteKey(WOLFSSL* ssl)
02386 {
02387     if (ssl)
02388         return ssl->keys.client_write_key;
02389 
02390     return NULL;
02391 }
02392 
02393 
02394 const byte* wolfSSL_GetClientWriteIV(WOLFSSL* ssl)
02395 {
02396     if (ssl)
02397         return ssl->keys.client_write_IV;
02398 
02399     return NULL;
02400 }
02401 
02402 
02403 const byte* wolfSSL_GetServerWriteKey(WOLFSSL* ssl)
02404 {
02405     if (ssl)
02406         return ssl->keys.server_write_key;
02407 
02408     return NULL;
02409 }
02410 
02411 
02412 const byte* wolfSSL_GetServerWriteIV(WOLFSSL* ssl)
02413 {
02414     if (ssl)
02415         return ssl->keys.server_write_IV;
02416 
02417     return NULL;
02418 }
02419 
02420 int wolfSSL_GetKeySize(WOLFSSL* ssl)
02421 {
02422     if (ssl)
02423         return ssl->specs.key_size;
02424 
02425     return BAD_FUNC_ARG;
02426 }
02427 
02428 
02429 int wolfSSL_GetIVSize(WOLFSSL* ssl)
02430 {
02431     if (ssl)
02432         return ssl->specs.iv_size;
02433 
02434     return BAD_FUNC_ARG;
02435 }
02436 
02437 
02438 int wolfSSL_GetBulkCipher(WOLFSSL* ssl)
02439 {
02440     if (ssl)
02441         return ssl->specs.bulk_cipher_algorithm;
02442 
02443     return BAD_FUNC_ARG;
02444 }
02445 
02446 
02447 int wolfSSL_GetCipherType(WOLFSSL* ssl)
02448 {
02449     if (ssl == NULL)
02450         return BAD_FUNC_ARG;
02451 
02452     if (ssl->specs.cipher_type == block)
02453         return WOLFSSL_BLOCK_TYPE;
02454     if (ssl->specs.cipher_type == stream)
02455         return WOLFSSL_STREAM_TYPE;
02456     if (ssl->specs.cipher_type == aead)
02457         return WOLFSSL_AEAD_TYPE;
02458 
02459     return -1;
02460 }
02461 
02462 
02463 int wolfSSL_GetCipherBlockSize(WOLFSSL* ssl)
02464 {
02465     if (ssl == NULL)
02466         return BAD_FUNC_ARG;
02467 
02468     return ssl->specs.block_size;
02469 }
02470 
02471 
02472 int wolfSSL_GetAeadMacSize(WOLFSSL* ssl)
02473 {
02474     if (ssl == NULL)
02475         return BAD_FUNC_ARG;
02476 
02477     return ssl->specs.aead_mac_size;
02478 }
02479 
02480 
02481 int wolfSSL_IsTLSv1_1(WOLFSSL* ssl)
02482 {
02483     if (ssl == NULL)
02484         return BAD_FUNC_ARG;
02485 
02486     if (ssl->options.tls1_1)
02487         return 1;
02488 
02489     return 0;
02490 }
02491 
02492 
02493 int wolfSSL_GetSide(WOLFSSL* ssl)
02494 {
02495     if (ssl)
02496         return ssl->options.side;
02497 
02498     return BAD_FUNC_ARG;
02499 }
02500 
02501 
02502 int wolfSSL_GetHmacSize(WOLFSSL* ssl)
02503 {
02504     /* AEAD ciphers don't have HMAC keys */
02505     if (ssl)
02506         return (ssl->specs.cipher_type != aead) ? ssl->specs.hash_size : 0;
02507 
02508     return BAD_FUNC_ARG;
02509 }
02510 
02511 #endif /* ATOMIC_USER */
02512 
02513 #ifndef NO_CERTS
02514 int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
02515 {
02516     int ret = BAD_FUNC_ARG;
02517     if (pDer) {
02518         int dynType = 0;
02519         DerBuffer* der;
02520 
02521         /* Determine dynamic type */
02522         switch (type) {
02523             case CA_TYPE:   dynType = DYNAMIC_TYPE_CA;   break;
02524             case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;
02525             case CRL_TYPE:  dynType = DYNAMIC_TYPE_CRL;  break;
02526             case DSA_TYPE:  dynType = DYNAMIC_TYPE_DSA;  break;
02527             case ECC_TYPE:  dynType = DYNAMIC_TYPE_ECC;  break;
02528             case RSA_TYPE:  dynType = DYNAMIC_TYPE_RSA;  break;
02529             default:        dynType = DYNAMIC_TYPE_KEY;  break;
02530         }
02531 
02532         /* Setup new buffer */
02533         *pDer = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + length, heap, dynType);
02534         if (*pDer == NULL) {
02535             return MEMORY_ERROR;
02536         }
02537         XMEMSET(*pDer, 0, sizeof(DerBuffer) + length);
02538 
02539         der = *pDer;
02540         der->type = type;
02541         der->dynType = dynType; /* Cache this for FreeDer */
02542         der->heap = heap;
02543         der->buffer = (byte*)der + sizeof(DerBuffer);
02544         der->length = length;
02545         ret = 0; /* Success */
02546     }
02547     return ret;
02548 }
02549 
02550 void FreeDer(DerBuffer** pDer)
02551 {
02552     if (pDer && *pDer)
02553     {
02554         DerBuffer* der = (DerBuffer*)*pDer;
02555 
02556         /* ForceZero private keys */
02557         if (der->type == PRIVATEKEY_TYPE) {
02558             ForceZero(der->buffer, der->length);
02559         }
02560         der->buffer = NULL;
02561         der->length = 0;
02562         XFREE(der, der->heap, der->dynType);
02563 
02564         *pDer = NULL;
02565     }
02566 }
02567 
02568 
02569 WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap)
02570 {
02571     WOLFSSL_CERT_MANAGER* cm = NULL;
02572 
02573     WOLFSSL_ENTER("wolfSSL_CertManagerNew");
02574 
02575     cm = (WOLFSSL_CERT_MANAGER*) XMALLOC(sizeof(WOLFSSL_CERT_MANAGER), heap,
02576                                          DYNAMIC_TYPE_CERT_MANAGER);
02577     if (cm) {
02578         XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER));
02579 
02580         if (wc_InitMutex(&cm->caLock) != 0) {
02581             WOLFSSL_MSG("Bad mutex init");
02582             wolfSSL_CertManagerFree(cm);
02583             return NULL;
02584         }
02585 
02586         #ifdef WOLFSSL_TRUST_PEER_CERT
02587         if (wc_InitMutex(&cm->tpLock) != 0) {
02588             WOLFSSL_MSG("Bad mutex init");
02589             wolfSSL_CertManagerFree(cm);
02590             return NULL;
02591         }
02592         #endif
02593 
02594         /* set default minimum key size allowed */
02595         #ifndef NO_RSA
02596             cm->minRsaKeySz = MIN_RSAKEY_SZ;
02597         #endif
02598         #ifdef HAVE_ECC
02599             cm->minEccKeySz = MIN_ECCKEY_SZ;
02600         #endif
02601             cm->heap = heap;
02602     }
02603 
02604     return cm;
02605 }
02606 
02607 
02608 WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void)
02609 {
02610     return wolfSSL_CertManagerNew_ex(NULL);
02611 }
02612 
02613 
02614 void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
02615 {
02616     WOLFSSL_ENTER("wolfSSL_CertManagerFree");
02617 
02618     if (cm) {
02619         #ifdef HAVE_CRL
02620             if (cm->crl)
02621                 FreeCRL(cm->crl, 1);
02622         #endif
02623         #ifdef HAVE_OCSP
02624             if (cm->ocsp)
02625                 FreeOCSP(cm->ocsp, 1);
02626             XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
02627         #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
02628          || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) \
02629          || defined(WOLFSSL_HAPROXY)
02630             if (cm->ocsp_stapling)
02631                 FreeOCSP(cm->ocsp_stapling, 1);
02632         #endif
02633         #endif
02634         FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
02635         wc_FreeMutex(&cm->caLock);
02636 
02637         #ifdef WOLFSSL_TRUST_PEER_CERT
02638         FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap);
02639         wc_FreeMutex(&cm->tpLock);
02640         #endif
02641 
02642         XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER);
02643     }
02644 
02645 }
02646 
02647 
02648 /* Unload the CA signer list */
02649 int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
02650 {
02651     WOLFSSL_ENTER("wolfSSL_CertManagerUnloadCAs");
02652 
02653     if (cm == NULL)
02654         return BAD_FUNC_ARG;
02655 
02656     if (wc_LockMutex(&cm->caLock) != 0)
02657         return BAD_MUTEX_E;
02658 
02659     FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
02660 
02661     wc_UnLockMutex(&cm->caLock);
02662 
02663 
02664     return SSL_SUCCESS;
02665 }
02666 
02667 
02668 #ifdef WOLFSSL_TRUST_PEER_CERT
02669 int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm)
02670 {
02671     WOLFSSL_ENTER("wolfSSL_CertManagerUnload_trust_peers");
02672 
02673     if (cm == NULL)
02674         return BAD_FUNC_ARG;
02675 
02676     if (wc_LockMutex(&cm->tpLock) != 0)
02677         return BAD_MUTEX_E;
02678 
02679     FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, NULL);
02680 
02681     wc_UnLockMutex(&cm->tpLock);
02682 
02683 
02684     return SSL_SUCCESS;
02685 }
02686 #endif /* WOLFSSL_TRUST_PEER_CERT */
02687 
02688 
02689 /* Return bytes written to buff or < 0 for error */
02690 int wolfSSL_CertPemToDer(const unsigned char* pem, int pemSz,
02691                         unsigned char* buff, int buffSz, int type)
02692 {
02693     int            eccKey = 0;
02694     int            ret;
02695     DerBuffer*     der = NULL;
02696 #ifdef WOLFSSL_SMALL_STACK
02697     EncryptedInfo* info = NULL;
02698 #else
02699     EncryptedInfo  info[1];
02700 #endif
02701 
02702     WOLFSSL_ENTER("wolfSSL_CertPemToDer");
02703 
02704     if (pem == NULL || buff == NULL || buffSz <= 0) {
02705         WOLFSSL_MSG("Bad pem der args");
02706         return BAD_FUNC_ARG;
02707     }
02708 
02709     if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) {
02710         WOLFSSL_MSG("Bad cert type");
02711         return BAD_FUNC_ARG;
02712     }
02713 
02714 #ifdef WOLFSSL_SMALL_STACK
02715     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
02716                                    DYNAMIC_TYPE_TMP_BUFFER);
02717     if (info == NULL)
02718         return MEMORY_E;
02719 #endif
02720 
02721     info->set      = 0;
02722     info->ctx      = NULL;
02723     info->consumed = 0;
02724 
02725     ret = PemToDer(pem, pemSz, type, &der, NULL, info, &eccKey);
02726 
02727 #ifdef WOLFSSL_SMALL_STACK
02728     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02729 #endif
02730 
02731     if (ret < 0) {
02732         WOLFSSL_MSG("Bad Pem To Der");
02733     }
02734     else {
02735         if (der->length <= (word32)buffSz) {
02736             XMEMCPY(buff, der->buffer, der->length);
02737             ret = der->length;
02738         }
02739         else {
02740             WOLFSSL_MSG("Bad der length");
02741             ret = BAD_FUNC_ARG;
02742         }
02743     }
02744 
02745     FreeDer(&der);
02746     return ret;
02747 }
02748 
02749 #endif /* NO_CERTS */
02750 
02751 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
02752 
02753 static struct cipher{
02754         unsigned char type;
02755         const char *name;
02756 } cipher_tbl[] = {
02757 
02758 #ifndef NO_AES
02759     {AES_128_CBC_TYPE, "AES-128-CBC"},
02760     {AES_192_CBC_TYPE, "AES-192-CBC"},
02761     {AES_256_CBC_TYPE, "AES-256-CBC"},
02762 #if defined(OPENSSL_EXTRA)
02763         {AES_128_CTR_TYPE, "AES-128-CTR"},
02764         {AES_192_CTR_TYPE, "AES-192-CTR"},
02765         {AES_256_CTR_TYPE, "AES-256-CTR"},
02766 
02767         {AES_128_ECB_TYPE, "AES-128-ECB"},
02768         {AES_192_ECB_TYPE, "AES-192-ECB"},
02769         {AES_256_ECB_TYPE, "AES-256-ECB"},
02770 #endif
02771 
02772 #endif
02773 
02774 #ifndef NO_DES3
02775     {DES_CBC_TYPE, "DES-CBC"},
02776     {DES_ECB_TYPE, "DES-ECB"},
02777 
02778     {DES_EDE3_CBC_TYPE, "DES-EDE3-CBC"},
02779     {DES_EDE3_ECB_TYPE, "DES-EDE3-ECB"},
02780 #endif
02781 
02782 #ifdef HAVE_IDEA
02783     {IDEA_CBC_TYPE, "IDEA-CBC"},
02784 #endif
02785     { 0, NULL}
02786 } ;
02787 
02788 const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbyname(const char *name)
02789 {
02790 
02791     static const struct alias {
02792         const char *name;
02793         const char *alias;
02794     } alias_tbl[] =
02795     {
02796         {"DES-CBC", "DES"},
02797         {"DES-CBC", "des"},
02798         {"DES-EDE3-CBC", "DES3"},
02799         {"DES-EDE3-CBC", "des3"},
02800         {"DES-EDE3-ECB", "des-ede3-ecb"},
02801         {"IDEA-CBC", "IDEA"},
02802         {"IDEA-CBC", "idea"},
02803         {"AES-128-CBC", "AES128"},
02804         {"AES-128-CBC", "aes128"},
02805         {"AES-192-CBC", "AES192"},
02806         {"AES-192-CBC", "aes192"},
02807         {"AES-256-CBC", "AES256"},
02808         {"AES-256-CBC", "aes256"},
02809         { NULL, NULL}
02810     };
02811 
02812     const struct cipher *ent ;
02813     const struct alias  *al ;
02814 
02815     WOLFSSL_ENTER("EVP_get_cipherbyname");
02816 
02817     for( al = alias_tbl; al->name != NULL; al++)
02818         if(XSTRNCMP(name, al->alias, XSTRLEN(al->alias)+1) == 0) {
02819             name = al->name;
02820             break;
02821         }
02822 
02823     for( ent = cipher_tbl; ent->name != NULL; ent++)
02824         if(XSTRNCMP(name, ent->name, XSTRLEN(ent->name)+1) == 0) {
02825             return (WOLFSSL_EVP_CIPHER *)ent->name;
02826         }
02827 
02828     return NULL;
02829 }
02830 
02831 
02832 #ifndef NO_AES
02833 static char *EVP_AES_128_CBC;
02834 static char *EVP_AES_192_CBC;
02835 static char *EVP_AES_256_CBC;
02836 #if defined(OPENSSL_EXTRA)
02837     static char *EVP_AES_128_CTR;
02838     static char *EVP_AES_192_CTR;
02839     static char *EVP_AES_256_CTR;
02840 
02841     static char *EVP_AES_128_ECB;
02842     static char *EVP_AES_192_ECB;
02843     static char *EVP_AES_256_ECB;
02844 #endif
02845 static const int  EVP_AES_SIZE = 11;
02846 #endif
02847 
02848 #ifndef NO_DES3
02849 static char *EVP_DES_CBC;
02850 static char *EVP_DES_ECB;
02851 static const int  EVP_DES_SIZE = 7;
02852 
02853 static char *EVP_DES_EDE3_CBC;
02854 static char *EVP_DES_EDE3_ECB;
02855 static const int  EVP_DES_EDE3_SIZE = 12;
02856 #endif
02857 
02858 #ifdef HAVE_IDEA
02859 static char *EVP_IDEA_CBC;
02860 static const int  EVP_IDEA_SIZE = 8;
02861 #endif
02862 
02863 void wolfSSL_EVP_init(void)
02864 {
02865 #ifndef NO_AES
02866     EVP_AES_128_CBC = (char *)EVP_get_cipherbyname("AES-128-CBC");
02867     EVP_AES_192_CBC = (char *)EVP_get_cipherbyname("AES-192-CBC");
02868     EVP_AES_256_CBC = (char *)EVP_get_cipherbyname("AES-256-CBC");
02869 
02870 #if defined(OPENSSL_EXTRA)
02871         EVP_AES_128_CTR = (char *)EVP_get_cipherbyname("AES-128-CTR");
02872         EVP_AES_192_CTR = (char *)EVP_get_cipherbyname("AES-192-CTR");
02873         EVP_AES_256_CTR = (char *)EVP_get_cipherbyname("AES-256-CTR");
02874 
02875         EVP_AES_128_ECB = (char *)EVP_get_cipherbyname("AES-128-ECB");
02876         EVP_AES_192_ECB = (char *)EVP_get_cipherbyname("AES-192-ECB");
02877         EVP_AES_256_ECB = (char *)EVP_get_cipherbyname("AES-256-ECB");
02878 #endif
02879 #endif
02880 
02881 #ifndef NO_DES3
02882     EVP_DES_CBC = (char *)EVP_get_cipherbyname("DES-CBC");
02883     EVP_DES_ECB = (char *)EVP_get_cipherbyname("DES-ECB");
02884 
02885     EVP_DES_EDE3_CBC = (char *)EVP_get_cipherbyname("DES-EDE3-CBC");
02886     EVP_DES_EDE3_ECB = (char *)EVP_get_cipherbyname("DES-EDE3-ECB");
02887 #endif
02888 
02889 #ifdef HAVE_IDEA
02890     EVP_IDEA_CBC = (char *)EVP_get_cipherbyname("IDEA-CBC");
02891 #endif
02892 }
02893 
02894 /* our KeyPemToDer password callback, password in userData */
02895 static INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
02896 {
02897     (void)rw;
02898 
02899     if (userdata == NULL)
02900         return 0;
02901 
02902     XSTRNCPY(passwd, (char*)userdata, sz);
02903     return min((word32)sz, (word32)XSTRLEN((char*)userdata));
02904 }
02905 
02906 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
02907 
02908 #ifndef NO_CERTS
02909 
02910 /* Return bytes written to buff or < 0 for error */
02911 int wolfSSL_KeyPemToDer(const unsigned char* pem, int pemSz,
02912                         unsigned char* buff, int buffSz, const char* pass)
02913 {
02914     int            eccKey = 0;
02915     int            ret;
02916     DerBuffer*     der = NULL;
02917 #ifdef WOLFSSL_SMALL_STACK
02918     EncryptedInfo* info = NULL;
02919 #else
02920     EncryptedInfo  info[1];
02921 #endif
02922 
02923     WOLFSSL_ENTER("wolfSSL_KeyPemToDer");
02924 
02925     if (pem == NULL || buff == NULL || buffSz <= 0) {
02926         WOLFSSL_MSG("Bad pem der args");
02927         return BAD_FUNC_ARG;
02928     }
02929 
02930 #ifdef WOLFSSL_SMALL_STACK
02931     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
02932                                    DYNAMIC_TYPE_TMP_BUFFER);
02933     if (info == NULL)
02934         return MEMORY_E;
02935 #endif
02936 
02937     info->set      = 0;
02938     info->ctx      = NULL;
02939     info->consumed = 0;
02940 
02941 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
02942     if (pass) {
02943         info->ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
02944         if (info->ctx == NULL) {
02945         #ifdef WOLFSSL_SMALL_STACK
02946             XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02947         #endif
02948             return MEMORY_E;
02949         }
02950 
02951         wolfSSL_CTX_set_default_passwd_cb(info->ctx, OurPasswordCb);
02952         wolfSSL_CTX_set_default_passwd_cb_userdata(info->ctx, (void*)pass);
02953     }
02954 #else
02955     (void)pass;
02956 #endif
02957 
02958     ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, &eccKey);
02959 
02960     if (info->ctx)
02961         wolfSSL_CTX_free(info->ctx);
02962 
02963 #ifdef WOLFSSL_SMALL_STACK
02964     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02965 #endif
02966 
02967     if (ret < 0) {
02968         WOLFSSL_MSG("Bad Pem To Der");
02969     }
02970     else {
02971         if (der->length <= (word32)buffSz) {
02972             XMEMCPY(buff, der->buffer, der->length);
02973             ret = der->length;
02974         }
02975         else {
02976             WOLFSSL_MSG("Bad der length");
02977             ret = BAD_FUNC_ARG;
02978         }
02979     }
02980 
02981     FreeDer(&der);
02982     return ret;
02983 }
02984 
02985 #endif /* !NO_CERTS */
02986 
02987 
02988 
02989 #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
02990 
02991 void wolfSSL_ERR_print_errors_fp(FILE* fp, int err)
02992 {
02993     char data[WOLFSSL_MAX_ERROR_SZ + 1];
02994 
02995     WOLFSSL_ENTER("wolfSSL_ERR_print_errors_fp");
02996     SetErrorString(err, data);
02997     fprintf(fp, "%s", data);
02998 }
02999 
03000 #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
03001 void wolfSSL_ERR_dump_errors_fp(FILE* fp)
03002 {
03003     wc_ERR_print_errors_fp(fp);
03004 }
03005 #endif
03006 #endif
03007 
03008 
03009 int wolfSSL_pending(WOLFSSL* ssl)
03010 {
03011     WOLFSSL_ENTER("SSL_pending");
03012     return ssl->buffers.clearOutputBuffer.length;
03013 }
03014 
03015 
03016 #ifndef WOLFSSL_LEANPSK
03017 /* turn on handshake group messages for context */
03018 int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx)
03019 {
03020     if (ctx == NULL)
03021        return BAD_FUNC_ARG;
03022 
03023     ctx->groupMessages = 1;
03024 
03025     return SSL_SUCCESS;
03026 }
03027 #endif
03028 
03029 
03030 #ifndef NO_WOLFSSL_CLIENT
03031 /* connect enough to get peer cert chain */
03032 int wolfSSL_connect_cert(WOLFSSL* ssl)
03033 {
03034     int  ret;
03035 
03036     if (ssl == NULL)
03037         return SSL_FAILURE;
03038 
03039     ssl->options.certOnly = 1;
03040     ret = wolfSSL_connect(ssl);
03041     ssl->options.certOnly   = 0;
03042 
03043     return ret;
03044 }
03045 #endif
03046 
03047 
03048 #ifndef WOLFSSL_LEANPSK
03049 /* turn on handshake group messages for ssl object */
03050 int wolfSSL_set_group_messages(WOLFSSL* ssl)
03051 {
03052     if (ssl == NULL)
03053        return BAD_FUNC_ARG;
03054 
03055     ssl->options.groupMessages = 1;
03056 
03057     return SSL_SUCCESS;
03058 }
03059 
03060 
03061 /* make minVersion the internal equivalent SSL version */
03062 static int SetMinVersionHelper(byte* minVersion, int version)
03063 {
03064 #ifdef NO_TLS
03065     (void)minVersion;
03066 #endif
03067 
03068     switch (version) {
03069 #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
03070         case WOLFSSL_SSLV3:
03071             *minVersion = SSLv3_MINOR;
03072             break;
03073 #endif
03074 
03075 #ifndef NO_TLS
03076     #ifndef NO_OLD_TLS
03077         case WOLFSSL_TLSV1:
03078             *minVersion = TLSv1_MINOR;
03079             break;
03080 
03081         case WOLFSSL_TLSV1_1:
03082             *minVersion = TLSv1_1_MINOR;
03083             break;
03084     #endif
03085         case WOLFSSL_TLSV1_2:
03086             *minVersion = TLSv1_2_MINOR;
03087             break;
03088 #endif
03089 
03090         default:
03091             WOLFSSL_MSG("Bad function argument");
03092             return BAD_FUNC_ARG;
03093     }
03094 
03095     return SSL_SUCCESS;
03096 }
03097 
03098 
03099 /* Set minimum downgrade version allowed, SSL_SUCCESS on ok */
03100 int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version)
03101 {
03102     WOLFSSL_ENTER("wolfSSL_CTX_SetMinVersion");
03103 
03104     if (ctx == NULL) {
03105         WOLFSSL_MSG("Bad function argument");
03106         return BAD_FUNC_ARG;
03107     }
03108 
03109     return SetMinVersionHelper(&ctx->minDowngrade, version);
03110 }
03111 
03112 
03113 /* Set minimum downgrade version allowed, SSL_SUCCESS on ok */
03114 int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version)
03115 {
03116     WOLFSSL_ENTER("wolfSSL_SetMinVersion");
03117 
03118     if (ssl == NULL) {
03119         WOLFSSL_MSG("Bad function argument");
03120         return BAD_FUNC_ARG;
03121     }
03122 
03123     return SetMinVersionHelper(&ssl->options.minDowngrade, version);
03124 }
03125 
03126 
03127 int wolfSSL_SetVersion(WOLFSSL* ssl, int version)
03128 {
03129     word16 haveRSA = 1;
03130     word16 havePSK = 0;
03131 
03132     WOLFSSL_ENTER("wolfSSL_SetVersion");
03133 
03134     if (ssl == NULL) {
03135         WOLFSSL_MSG("Bad function argument");
03136         return BAD_FUNC_ARG;
03137     }
03138 
03139     switch (version) {
03140 #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
03141         case WOLFSSL_SSLV3:
03142             ssl->version = MakeSSLv3();
03143             break;
03144 #endif
03145 
03146 #ifndef NO_TLS
03147     #ifndef NO_OLD_TLS
03148         case WOLFSSL_TLSV1:
03149             ssl->version = MakeTLSv1();
03150             break;
03151 
03152         case WOLFSSL_TLSV1_1:
03153             ssl->version = MakeTLSv1_1();
03154             break;
03155     #endif
03156         case WOLFSSL_TLSV1_2:
03157             ssl->version = MakeTLSv1_2();
03158             break;
03159 #endif
03160 
03161         default:
03162             WOLFSSL_MSG("Bad function argument");
03163             return BAD_FUNC_ARG;
03164     }
03165 
03166     #ifdef NO_RSA
03167         haveRSA = 0;
03168     #endif
03169     #ifndef NO_PSK
03170         havePSK = ssl->options.havePSK;
03171     #endif
03172 
03173     InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH,
03174                 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
03175                 ssl->options.haveECC, ssl->options.haveStaticECC,
03176                 ssl->options.side);
03177 
03178     return SSL_SUCCESS;
03179 }
03180 #endif /* !leanpsk */
03181 
03182 
03183 #if !defined(NO_CERTS) || !defined(NO_SESSION_CACHE)
03184 
03185 /* Make a work from the front of random hash */
03186 static INLINE word32 MakeWordFromHash(const byte* hashID)
03187 {
03188     return (hashID[0] << 24) | (hashID[1] << 16) | (hashID[2] <<  8) |
03189             hashID[3];
03190 }
03191 
03192 #endif /* !NO_CERTS || !NO_SESSION_CACHE */
03193 
03194 
03195 #ifndef NO_CERTS
03196 
03197 /* hash is the SHA digest of name, just use first 32 bits as hash */
03198 static INLINE word32 HashSigner(const byte* hash)
03199 {
03200     return MakeWordFromHash(hash) % CA_TABLE_SIZE;
03201 }
03202 
03203 
03204 /* does CA already exist on signer list */
03205 int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash)
03206 {
03207     Signer* signers;
03208     int     ret = 0;
03209     word32  row;
03210 
03211     if (cm == NULL || hash == NULL) {
03212         return ret;
03213     }
03214 
03215     row = HashSigner(hash);
03216 
03217     if (wc_LockMutex(&cm->caLock) != 0) {
03218         return ret;
03219     }
03220     signers = cm->caTable[row];
03221     while (signers) {
03222         byte* subjectHash;
03223 
03224     #ifndef NO_SKID
03225         subjectHash = signers->subjectKeyIdHash;
03226     #else
03227         subjectHash = signers->subjectNameHash;
03228     #endif
03229 
03230         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
03231             ret = 1; /* success */
03232             break;
03233         }
03234         signers = signers->next;
03235     }
03236     wc_UnLockMutex(&cm->caLock);
03237 
03238     return ret;
03239 }
03240 
03241 
03242 #ifdef WOLFSSL_TRUST_PEER_CERT
03243 /* hash is the SHA digest of name, just use first 32 bits as hash */
03244 static INLINE word32 TrustedPeerHashSigner(const byte* hash)
03245 {
03246     return MakeWordFromHash(hash) % TP_TABLE_SIZE;
03247 }
03248 
03249 /* does trusted peer already exist on signer list */
03250 int AlreadyTrustedPeer(WOLFSSL_CERT_MANAGER* cm, byte* hash)
03251 {
03252     TrustedPeerCert* tp;
03253     int     ret = 0;
03254     word32  row = TrustedPeerHashSigner(hash);
03255 
03256     if (wc_LockMutex(&cm->tpLock) != 0)
03257         return  ret;
03258     tp = cm->tpTable[row];
03259     while (tp) {
03260         byte* subjectHash;
03261         #ifndef NO_SKID
03262             subjectHash = tp->subjectKeyIdHash;
03263         #else
03264             subjectHash = tp->subjectNameHash;
03265         #endif
03266         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
03267             ret = 1;
03268             break;
03269         }
03270         tp = tp->next;
03271     }
03272     wc_UnLockMutex(&cm->tpLock);
03273 
03274     return ret;
03275 }
03276 
03277 
03278 /* return Trusted Peer if found, otherwise NULL
03279     type is what to match on
03280  */
03281 TrustedPeerCert* GetTrustedPeer(void* vp, byte* hash, int type)
03282 {
03283     WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
03284     TrustedPeerCert* ret = NULL;
03285     TrustedPeerCert* tp  = NULL;
03286     word32  row;
03287 
03288     if (cm == NULL || hash == NULL)
03289         return NULL;
03290 
03291     row = TrustedPeerHashSigner(hash);
03292 
03293     if (wc_LockMutex(&cm->tpLock) != 0)
03294         return ret;
03295 
03296     tp = cm->tpTable[row];
03297     while (tp) {
03298         byte* subjectHash;
03299         switch (type) {
03300             #ifndef NO_SKID
03301             case WC_MATCH_SKID:
03302                 subjectHash = tp->subjectKeyIdHash;
03303                 break;
03304             #endif
03305             case WC_MATCH_NAME:
03306                 subjectHash = tp->subjectNameHash;
03307                 break;
03308             default:
03309                 WOLFSSL_MSG("Unknown search type");
03310                 wc_UnLockMutex(&cm->tpLock);
03311                 return NULL;
03312         }
03313         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
03314             ret = tp;
03315             break;
03316         }
03317         tp = tp->next;
03318     }
03319     wc_UnLockMutex(&cm->tpLock);
03320 
03321     return ret;
03322 }
03323 
03324 
03325 int MatchTrustedPeer(TrustedPeerCert* tp, DecodedCert* cert)
03326 {
03327     if (tp == NULL || cert == NULL)
03328         return BAD_FUNC_ARG;
03329 
03330     /* subject key id or subject hash has been compared when searching
03331        tpTable for the cert from function GetTrustedPeer */
03332 
03333     /* compare signatures */
03334     if (tp->sigLen == cert->sigLength) {
03335         if (XMEMCMP(tp->sig, cert->signature, cert->sigLength)) {
03336             return SSL_FAILURE;
03337         }
03338     }
03339     else {
03340         return SSL_FAILURE;
03341     }
03342 
03343     return SSL_SUCCESS;
03344 }
03345 #endif /* WOLFSSL_TRUST_PEER_CERT */
03346 
03347 
03348 /* return CA if found, otherwise NULL */
03349 Signer* GetCA(void* vp, byte* hash)
03350 {
03351     WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
03352     Signer* ret = NULL;
03353     Signer* signers;
03354     word32  row = HashSigner(hash);
03355 
03356     if (cm == NULL)
03357         return NULL;
03358 
03359     if (wc_LockMutex(&cm->caLock) != 0)
03360         return ret;
03361 
03362     signers = cm->caTable[row];
03363     while (signers) {
03364         byte* subjectHash;
03365         #ifndef NO_SKID
03366             subjectHash = signers->subjectKeyIdHash;
03367         #else
03368             subjectHash = signers->subjectNameHash;
03369         #endif
03370         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
03371             ret = signers;
03372             break;
03373         }
03374         signers = signers->next;
03375     }
03376     wc_UnLockMutex(&cm->caLock);
03377 
03378     return ret;
03379 }
03380 
03381 
03382 #ifndef NO_SKID
03383 /* return CA if found, otherwise NULL. Walk through hash table. */
03384 Signer* GetCAByName(void* vp, byte* hash)
03385 {
03386     WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
03387     Signer* ret = NULL;
03388     Signer* signers;
03389     word32  row;
03390 
03391     if (cm == NULL)
03392         return NULL;
03393 
03394     if (wc_LockMutex(&cm->caLock) != 0)
03395         return ret;
03396 
03397     for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
03398         signers = cm->caTable[row];
03399         while (signers && ret == NULL) {
03400             if (XMEMCMP(hash, signers->subjectNameHash,
03401                         SIGNER_DIGEST_SIZE) == 0) {
03402                 ret = signers;
03403             }
03404             signers = signers->next;
03405         }
03406     }
03407     wc_UnLockMutex(&cm->caLock);
03408 
03409     return ret;
03410 }
03411 #endif
03412 
03413 
03414 #ifdef WOLFSSL_TRUST_PEER_CERT
03415 /* add a trusted peer cert to linked list */
03416 int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify)
03417 {
03418     int ret, row;
03419     TrustedPeerCert* peerCert;
03420     DecodedCert* cert = NULL;
03421     DerBuffer*   der = *pDer;
03422     byte* subjectHash = NULL;
03423 
03424     WOLFSSL_MSG("Adding a Trusted Peer Cert");
03425 
03426     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
03427                                  DYNAMIC_TYPE_TMP_BUFFER);
03428     if (cert == NULL)
03429         return MEMORY_E;
03430 
03431     InitDecodedCert(cert, der->buffer, der->length, cm->heap);
03432     if ((ret = ParseCert(cert, TRUSTED_PEER_TYPE, verify, cm)) != 0) {
03433         XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03434         return ret;
03435     }
03436     WOLFSSL_MSG("\tParsed new trusted peer cert");
03437 
03438     peerCert = (TrustedPeerCert*)XMALLOC(sizeof(TrustedPeerCert), cm->heap,
03439                                                              DYNAMIC_TYPE_CERT);
03440     if (peerCert == NULL) {
03441         FreeDecodedCert(cert);
03442         XFREE(cert, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
03443         return MEMORY_E;
03444     }
03445     XMEMSET(peerCert, 0, sizeof(TrustedPeerCert));
03446 
03447 #ifndef NO_SKID
03448     if (cert->extAuthKeyIdSet) {
03449         subjectHash = cert->extSubjKeyId;
03450     }
03451     else {
03452         subjectHash = cert->subjectHash;
03453     }
03454 #else
03455     subjectHash = cert->subjectHash;
03456 #endif
03457 
03458     #ifndef IGNORE_NAME_CONSTRAINTS
03459         if (peerCert->permittedNames)
03460             FreeNameSubtrees(peerCert->permittedNames, cm->heap);
03461         if (peerCert->excludedNames)
03462             FreeNameSubtrees(peerCert->excludedNames, cm->heap);
03463     #endif
03464 
03465     if (AlreadyTrustedPeer(cm, subjectHash)) {
03466         WOLFSSL_MSG("\tAlready have this CA, not adding again");
03467         (void)ret;
03468     }
03469     else {
03470         /* add trusted peer signature */
03471         peerCert->sigLen = cert->sigLength;
03472         peerCert->sig = XMALLOC(cert->sigLength, cm->heap,
03473                                                         DYNAMIC_TYPE_SIGNATURE);
03474         if (peerCert->sig == NULL) {
03475             FreeDecodedCert(cert);
03476             XFREE(cert, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
03477             FreeTrustedPeer(peerCert, cm->heap);
03478             return MEMORY_E;
03479         }
03480         XMEMCPY(peerCert->sig, cert->signature, cert->sigLength);
03481 
03482         /* add trusted peer name */
03483         peerCert->nameLen = cert->subjectCNLen;
03484         peerCert->name    = cert->subjectCN;
03485         #ifndef IGNORE_NAME_CONSTRAINTS
03486             peerCert->permittedNames = cert->permittedNames;
03487             peerCert->excludedNames  = cert->excludedNames;
03488         #endif
03489 
03490         /* add SKID when available and hash of name */
03491         #ifndef NO_SKID
03492             XMEMCPY(peerCert->subjectKeyIdHash, cert->extSubjKeyId,
03493                     SIGNER_DIGEST_SIZE);
03494         #endif
03495             XMEMCPY(peerCert->subjectNameHash, cert->subjectHash,
03496                     SIGNER_DIGEST_SIZE);
03497             peerCert->next    = NULL; /* If Key Usage not set, all uses valid. */
03498             cert->subjectCN = 0;
03499         #ifndef IGNORE_NAME_CONSTRAINTS
03500             cert->permittedNames = NULL;
03501             cert->excludedNames = NULL;
03502         #endif
03503 
03504         #ifndef NO_SKID
03505             if (cert->extAuthKeyIdSet) {
03506                 row = TrustedPeerHashSigner(peerCert->subjectKeyIdHash);
03507             }
03508             else {
03509                 row = TrustedPeerHashSigner(peerCert->subjectNameHash);
03510             }
03511         #else
03512             row = TrustedPeerHashSigner(peerCert->subjectNameHash);
03513         #endif
03514 
03515             if (wc_LockMutex(&cm->tpLock) == 0) {
03516                 peerCert->next = cm->tpTable[row];
03517                 cm->tpTable[row] = peerCert;   /* takes ownership */
03518                 wc_UnLockMutex(&cm->tpLock);
03519             }
03520             else {
03521                 WOLFSSL_MSG("\tTrusted Peer Cert Mutex Lock failed");
03522                 FreeDecodedCert(cert);
03523                 XFREE(cert, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
03524                 FreeTrustedPeer(peerCert, cm->heap);
03525                 return BAD_MUTEX_E;
03526             }
03527         }
03528 
03529     WOLFSSL_MSG("\tFreeing parsed trusted peer cert");
03530     FreeDecodedCert(cert);
03531     XFREE(cert, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
03532     WOLFSSL_MSG("\tFreeing der trusted peer cert");
03533     FreeDer(&der);
03534     WOLFSSL_MSG("\t\tOK Freeing der trusted peer cert");
03535     WOLFSSL_LEAVE("AddTrustedPeer", ret);
03536 
03537     return SSL_SUCCESS;
03538 }
03539 #endif /* WOLFSSL_TRUST_PEER_CERT */
03540 
03541 
03542 /* owns der, internal now uses too */
03543 /* type flag ids from user or from chain received during verify
03544    don't allow chain ones to be added w/o isCA extension */
03545 int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
03546 {
03547     int         ret;
03548     Signer*     signer = 0;
03549     word32      row;
03550     byte*       subjectHash;
03551 #ifdef WOLFSSL_SMALL_STACK
03552     DecodedCert* cert = NULL;
03553 #else
03554     DecodedCert  cert[1];
03555 #endif
03556     DerBuffer*   der = *pDer;
03557 
03558     WOLFSSL_MSG("Adding a CA");
03559 
03560 #ifdef WOLFSSL_SMALL_STACK
03561     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
03562                                  DYNAMIC_TYPE_TMP_BUFFER);
03563     if (cert == NULL)
03564         return MEMORY_E;
03565 #endif
03566 
03567     InitDecodedCert(cert, der->buffer, der->length, cm->heap);
03568     ret = ParseCert(cert, CA_TYPE, verify, cm);
03569     WOLFSSL_MSG("\tParsed new CA");
03570 
03571 #ifndef NO_SKID
03572     subjectHash = cert->extSubjKeyId;
03573 #else
03574     subjectHash = cert->subjectHash;
03575 #endif
03576 
03577     /* check CA key size */
03578     if (verify) {
03579         switch (cert->keyOID) {
03580             #ifndef NO_RSA
03581             case RSAk:
03582                 if (cm->minRsaKeySz < 0 ||
03583                                    cert->pubKeySize < (word16)cm->minRsaKeySz) {
03584                     ret = RSA_KEY_SIZE_E;
03585                     WOLFSSL_MSG("\tCA RSA key size error");
03586                 }
03587                 break;
03588             #endif /* !NO_RSA */
03589             #ifdef HAVE_ECC
03590             case ECDSAk:
03591                 if (cm->minEccKeySz < 0 ||
03592                                    cert->pubKeySize < (word16)cm->minEccKeySz) {
03593                     ret = ECC_KEY_SIZE_E;
03594                     WOLFSSL_MSG("\tCA ECC key size error");
03595                 }
03596                 break;
03597             #endif /* HAVE_ECC */
03598 
03599             default:
03600                 WOLFSSL_MSG("\tNo key size check done on CA");
03601                 break; /* no size check if key type is not in switch */
03602         }
03603     }
03604 
03605     if (ret == 0 && cert->isCA == 0 && type != WOLFSSL_USER_CA) {
03606         WOLFSSL_MSG("\tCan't add as CA if not actually one");
03607         ret = NOT_CA_ERROR;
03608     }
03609 #ifndef ALLOW_INVALID_CERTSIGN
03610     else if (ret == 0 && cert->isCA == 1 && type != WOLFSSL_USER_CA &&
03611              (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) == 0) {
03612         /* Intermediate CA certs are required to have the keyCertSign
03613         * extension set. User loaded root certs are not. */
03614         WOLFSSL_MSG("\tDoesn't have key usage certificate signing");
03615         ret = NOT_CA_ERROR;
03616     }
03617 #endif
03618     else if (ret == 0 && AlreadySigner(cm, subjectHash)) {
03619         WOLFSSL_MSG("\tAlready have this CA, not adding again");
03620         (void)ret;
03621     }
03622     else if (ret == 0) {
03623         /* take over signer parts */
03624         signer = MakeSigner(cm->heap);
03625         if (!signer)
03626             ret = MEMORY_ERROR;
03627         else {
03628             signer->keyOID         = cert->keyOID;
03629             if (cert->pubKeyStored) {
03630                 signer->publicKey      = cert->publicKey;
03631                 signer->pubKeySize     = cert->pubKeySize;
03632             }
03633             if (cert->subjectCNStored) {
03634                 signer->nameLen        = cert->subjectCNLen;
03635                 signer->name           = cert->subjectCN;
03636             }
03637             signer->pathLength     = cert->pathLength;
03638             signer->pathLengthSet  = cert->pathLengthSet;
03639         #ifndef IGNORE_NAME_CONSTRAINTS
03640             signer->permittedNames = cert->permittedNames;
03641             signer->excludedNames  = cert->excludedNames;
03642         #endif
03643         #ifndef NO_SKID
03644             XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
03645                     SIGNER_DIGEST_SIZE);
03646         #endif
03647             XMEMCPY(signer->subjectNameHash, cert->subjectHash,
03648                     SIGNER_DIGEST_SIZE);
03649             signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
03650                                                     : 0xFFFF;
03651             signer->next    = NULL; /* If Key Usage not set, all uses valid. */
03652             cert->publicKey = 0;    /* in case lock fails don't free here.   */
03653             cert->subjectCN = 0;
03654         #ifndef IGNORE_NAME_CONSTRAINTS
03655             cert->permittedNames = NULL;
03656             cert->excludedNames = NULL;
03657         #endif
03658 
03659         #ifndef NO_SKID
03660             row = HashSigner(signer->subjectKeyIdHash);
03661         #else
03662             row = HashSigner(signer->subjectNameHash);
03663         #endif
03664 
03665             if (wc_LockMutex(&cm->caLock) == 0) {
03666                 signer->next = cm->caTable[row];
03667                 cm->caTable[row] = signer;   /* takes ownership */
03668                 wc_UnLockMutex(&cm->caLock);
03669                 if (cm->caCacheCallback)
03670                     cm->caCacheCallback(der->buffer, (int)der->length, type);
03671             }
03672             else {
03673                 WOLFSSL_MSG("\tCA Mutex Lock failed");
03674                 ret = BAD_MUTEX_E;
03675                 FreeSigner(signer, cm->heap);
03676             }
03677         }
03678     }
03679 
03680     WOLFSSL_MSG("\tFreeing Parsed CA");
03681     FreeDecodedCert(cert);
03682 #ifdef WOLFSSL_SMALL_STACK
03683     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03684 #endif
03685     WOLFSSL_MSG("\tFreeing der CA");
03686     FreeDer(pDer);
03687     WOLFSSL_MSG("\t\tOK Freeing der CA");
03688 
03689     WOLFSSL_LEAVE("AddCA", ret);
03690 
03691     return ret == 0 ? SSL_SUCCESS : ret;
03692 }
03693 
03694 #endif /* !NO_CERTS */
03695 
03696 
03697 #ifndef NO_SESSION_CACHE
03698 
03699     /* basic config gives a cache with 33 sessions, adequate for clients and
03700        embedded servers
03701 
03702        MEDIUM_SESSION_CACHE allows 1055 sessions, adequate for servers that
03703        aren't under heavy load, basically allows 200 new sessions per minute
03704 
03705        BIG_SESSION_CACHE yields 20,027 sessions
03706 
03707        HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
03708        allows over 13,000 new sessions per minute or over 200 new sessions per
03709        second
03710 
03711        SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients
03712        or systems where the default of nearly 3kB is too much RAM, this define
03713        uses less than 500 bytes RAM
03714 
03715        default SESSION_CACHE stores 33 sessions (no XXX_SESSION_CACHE defined)
03716     */
03717     #ifdef HUGE_SESSION_CACHE
03718         #define SESSIONS_PER_ROW 11
03719         #define SESSION_ROWS 5981
03720     #elif defined(BIG_SESSION_CACHE)
03721         #define SESSIONS_PER_ROW 7
03722         #define SESSION_ROWS 2861
03723     #elif defined(MEDIUM_SESSION_CACHE)
03724         #define SESSIONS_PER_ROW 5
03725         #define SESSION_ROWS 211
03726     #elif defined(SMALL_SESSION_CACHE)
03727         #define SESSIONS_PER_ROW 2
03728         #define SESSION_ROWS 3
03729     #else
03730         #define SESSIONS_PER_ROW 3
03731         #define SESSION_ROWS 11
03732     #endif
03733 
03734     typedef struct SessionRow {
03735         int nextIdx;                           /* where to place next one   */
03736         int totalCount;                        /* sessions ever on this row */
03737         WOLFSSL_SESSION Sessions[SESSIONS_PER_ROW];
03738     } SessionRow;
03739 
03740     static SessionRow SessionCache[SESSION_ROWS];
03741 
03742     #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
03743         static word32 PeakSessions;
03744     #endif
03745 
03746     static wolfSSL_Mutex session_mutex;   /* SessionCache mutex */
03747 
03748     #ifndef NO_CLIENT_CACHE
03749 
03750         typedef struct ClientSession {
03751             word16 serverRow;            /* SessionCache Row id */
03752             word16 serverIdx;            /* SessionCache Idx (column) */
03753         } ClientSession;
03754 
03755         typedef struct ClientRow {
03756             int nextIdx;                /* where to place next one   */
03757             int totalCount;             /* sessions ever on this row */
03758             ClientSession Clients[SESSIONS_PER_ROW];
03759         } ClientRow;
03760 
03761         static ClientRow ClientCache[SESSION_ROWS];  /* Client Cache */
03762                                                      /* uses session mutex */
03763     #endif  /* NO_CLIENT_CACHE */
03764 
03765 #endif /* NO_SESSION_CACHE */
03766 
03767 int wolfSSL_Init(void)
03768 {
03769     WOLFSSL_ENTER("wolfSSL_Init");
03770 
03771     if (initRefCount == 0) {
03772         /* Initialize crypto for use with TLS connection */
03773         if (wolfCrypt_Init() != 0) {
03774             WOLFSSL_MSG("Bad wolfCrypt Init");
03775             return WC_INIT_E;
03776         }
03777 #ifndef NO_SESSION_CACHE
03778         if (wc_InitMutex(&session_mutex) != 0) {
03779             WOLFSSL_MSG("Bad Init Mutex session");
03780             return BAD_MUTEX_E;
03781         }
03782 #endif
03783         if (wc_InitMutex(&count_mutex) != 0) {
03784             WOLFSSL_MSG("Bad Init Mutex count");
03785             return BAD_MUTEX_E;
03786         }
03787     }
03788 
03789     if (wc_LockMutex(&count_mutex) != 0) {
03790         WOLFSSL_MSG("Bad Lock Mutex count");
03791         return BAD_MUTEX_E;
03792     }
03793 
03794     initRefCount++;
03795     wc_UnLockMutex(&count_mutex);
03796 
03797     return SSL_SUCCESS;
03798 }
03799 
03800 
03801 #if (defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)) && !defined(NO_CERTS)
03802 
03803 /* SSL_SUCCESS if ok, <= 0 else */
03804 static int wolfssl_decrypt_buffer_key(DerBuffer* der, byte* password,
03805                                       int passwordSz, EncryptedInfo* info)
03806 {
03807     int ret = SSL_BAD_FILE;
03808 
03809 #ifdef WOLFSSL_SMALL_STACK
03810     byte* key      = NULL;
03811 #else
03812     byte  key[AES_256_KEY_SIZE];
03813 #endif
03814 
03815     (void)passwordSz;
03816     (void)key;
03817 
03818     WOLFSSL_ENTER("wolfssl_decrypt_buffer_key");
03819 
03820     if (der == NULL || password == NULL || info == NULL) {
03821         WOLFSSL_MSG("bad arguments");
03822         return SSL_FATAL_ERROR;
03823     }
03824 
03825     /* use file's salt for key derivation, hex decode first */
03826     if (Base16_Decode(info->iv, info->ivSz, info->iv, &info->ivSz) != 0) {
03827         WOLFSSL_MSG("base16 decode failed");
03828         return SSL_FATAL_ERROR;
03829     }
03830 
03831 #ifndef NO_MD5
03832 
03833 #ifdef WOLFSSL_SMALL_STACK
03834     key = (byte*)XMALLOC(AES_256_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03835     if (key == NULL) {
03836         WOLFSSL_MSG("memory failure");
03837         return SSL_FATAL_ERROR;
03838     }
03839 #endif /* WOLFSSL_SMALL_STACK */
03840 
03841     if ((ret = wolfSSL_EVP_BytesToKey(info->name, "MD5", info->iv,
03842                               password, passwordSz, 1, key, NULL)) <= 0) {
03843         WOLFSSL_MSG("bytes to key failure");
03844 #ifdef WOLFSSL_SMALL_STACK
03845         XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03846 #endif
03847         return SSL_FATAL_ERROR;
03848     }
03849 
03850 #endif /* NO_MD5 */
03851 
03852 #ifndef NO_DES3
03853     if (XSTRNCMP(info->name, EVP_DES_CBC, EVP_DES_SIZE) == 0)
03854         ret = wc_Des_CbcDecryptWithKey(der->buffer, der->buffer, der->length,
03855                                        key, info->iv);
03856     else if (XSTRNCMP(info->name, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)
03857         ret = wc_Des3_CbcDecryptWithKey(der->buffer, der->buffer, der->length,
03858                                         key, info->iv);
03859 #endif /* NO_DES3 */
03860 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(HAVE_AES_DECRYPT)
03861     if (XSTRNCMP(info->name, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)
03862         ret = wc_AesCbcDecryptWithKey(der->buffer, der->buffer, der->length,
03863                                       key, AES_128_KEY_SIZE, info->iv);
03864     else if (XSTRNCMP(info->name, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)
03865         ret = wc_AesCbcDecryptWithKey(der->buffer, der->buffer, der->length,
03866                                       key, AES_192_KEY_SIZE, info->iv);
03867     else if (XSTRNCMP(info->name, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)
03868         ret = wc_AesCbcDecryptWithKey(der->buffer, der->buffer, der->length,
03869                                       key, AES_256_KEY_SIZE, info->iv);
03870 #endif /* !NO_AES && HAVE_AES_CBC && HAVE_AES_DECRYPT */
03871 
03872 #ifdef WOLFSSL_SMALL_STACK
03873     XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03874 #endif
03875 
03876     if (ret == MP_OKAY)
03877         return SSL_SUCCESS;
03878     else if (ret == SSL_BAD_FILE)
03879         return SSL_BAD_FILE;
03880 
03881     return SSL_FATAL_ERROR;
03882 }
03883 #endif /* defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) */
03884 
03885 
03886 #if defined(WOLFSSL_KEY_GEN) && defined(OPENSSL_EXTRA)
03887 static int wolfssl_encrypt_buffer_key(byte* der, word32 derSz, byte* password,
03888                                       int passwordSz, EncryptedInfo* info)
03889 {
03890     int ret = SSL_BAD_FILE;
03891 
03892 #ifdef WOLFSSL_SMALL_STACK
03893     byte* key      = NULL;
03894 #else
03895     byte  key[AES_256_KEY_SIZE];
03896 #endif
03897 
03898     (void)derSz;
03899     (void)passwordSz;
03900     (void)key;
03901 
03902     WOLFSSL_ENTER("wolfssl_encrypt_buffer_key");
03903 
03904     if (der == NULL || password == NULL || info == NULL || info->ivSz == 0) {
03905         WOLFSSL_MSG("bad arguments");
03906         return SSL_FATAL_ERROR;
03907     }
03908 
03909 #ifndef NO_MD5
03910 
03911 #ifdef WOLFSSL_SMALL_STACK
03912     key = (byte*)XMALLOC(AES_256_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03913     if (key == NULL) {
03914         WOLFSSL_MSG("memory failure");
03915         return SSL_FATAL_ERROR;
03916     }
03917 #endif /* WOLFSSL_SMALL_STACK */
03918 
03919     if ((ret = wolfSSL_EVP_BytesToKey(info->name, "MD5", info->iv,
03920                               password, passwordSz, 1, key, NULL)) <= 0) {
03921         WOLFSSL_MSG("bytes to key failure");
03922 #ifdef WOLFSSL_SMALL_STACK
03923         XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03924 #endif
03925         return SSL_FATAL_ERROR;
03926     }
03927 
03928 #endif /* NO_MD5 */
03929 
03930     if (ret > 0) {
03931         ret = SSL_BAD_FILE; /* Reset error return */
03932 #ifndef NO_DES3
03933         if (XSTRNCMP(info->name, EVP_DES_CBC, EVP_DES_SIZE) == 0)
03934             ret = wc_Des_CbcEncryptWithKey(der, der, derSz, key, info->iv);
03935         else if (XSTRNCMP(info->name, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)
03936             ret = wc_Des3_CbcEncryptWithKey(der, der, derSz, key, info->iv);
03937 #endif /* NO_DES3 */
03938 #ifndef NO_AES
03939         if (XSTRNCMP(info->name, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)
03940             ret = wc_AesCbcEncryptWithKey(der, der, derSz,
03941                                           key, AES_128_KEY_SIZE, info->iv);
03942         else if (XSTRNCMP(info->name, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)
03943             ret = wc_AesCbcEncryptWithKey(der, der, derSz,
03944                                           key, AES_192_KEY_SIZE, info->iv);
03945         else if (XSTRNCMP(info->name, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)
03946             ret = wc_AesCbcEncryptWithKey(der, der, derSz,
03947                                           key, AES_256_KEY_SIZE, info->iv);
03948 #endif /* NO_AES */
03949     }
03950 
03951 #ifdef WOLFSSL_SMALL_STACK
03952     XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03953 #endif
03954 
03955     if (ret == MP_OKAY)
03956         return SSL_SUCCESS;
03957     else if (ret == SSL_BAD_FILE)
03958         return SSL_BAD_FILE;
03959 
03960     return SSL_FATAL_ERROR;
03961 }
03962 #endif /* defined(WOLFSSL_KEY_GEN) */
03963 
03964 
03965 #ifndef NO_CERTS
03966 
03967 /* Remove PEM header/footer, convert to ASN1, store any encrypted data
03968    info->consumed tracks of PEM bytes consumed in case multiple parts */
03969 int PemToDer(const unsigned char* buff, long longSz, int type,
03970               DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
03971 {
03972     const char* header      = NULL;
03973     const char* footer      = NULL;
03974     char*       headerEnd;
03975     char*       footerEnd;
03976     char*       consumedEnd;
03977     char*       bufferEnd   = (char*)(buff + longSz);
03978     long        neededSz;
03979     int         ret         = 0;
03980     int         sz          = (int)longSz;
03981     int         encrypted_key = 0;
03982     DerBuffer*  der;
03983 
03984     WOLFSSL_ENTER("PemToDer");
03985 
03986     switch (type) {
03987         case CA_TYPE:       /* same as below */
03988         case TRUSTED_PEER_TYPE:
03989         case CERT_TYPE:      header=BEGIN_CERT;     footer=END_CERT;     break;
03990         case CRL_TYPE:       header=BEGIN_X509_CRL; footer=END_X509_CRL; break;
03991         case DH_PARAM_TYPE:  header=BEGIN_DH_PARAM; footer=END_DH_PARAM; break;
03992         case DSA_PARAM_TYPE: header=BEGIN_DSA_PARAM; footer=END_DSA_PARAM; break;
03993         case CERTREQ_TYPE:   header=BEGIN_CERT_REQ; footer=END_CERT_REQ; break;
03994         case DSA_TYPE:       header=BEGIN_DSA_PRIV; footer=END_DSA_PRIV; break;
03995         case ECC_TYPE:       header=BEGIN_EC_PRIV;  footer=END_EC_PRIV;  break;
03996         case RSA_TYPE:       header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV; break;
03997         case PUBLICKEY_TYPE: header=BEGIN_PUB_KEY;  footer=END_PUB_KEY;  break;
03998         default:             header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV; break;
03999     }
04000 
04001     /* find header */
04002     for (;;) {
04003         headerEnd = XSTRNSTR((char*)buff, header, sz);
04004 
04005         if (headerEnd || type != PRIVATEKEY_TYPE) {
04006             break;
04007         } else if (header == BEGIN_RSA_PRIV) {
04008                    header =  BEGIN_PRIV_KEY;       footer = END_PRIV_KEY;
04009         } else if (header == BEGIN_PRIV_KEY) {
04010                    header =  BEGIN_ENC_PRIV_KEY;   footer = END_ENC_PRIV_KEY;
04011         } else if (header == BEGIN_ENC_PRIV_KEY) {
04012                    header =  BEGIN_EC_PRIV;        footer = END_EC_PRIV;
04013         } else if (header == BEGIN_EC_PRIV) {
04014                    header =  BEGIN_DSA_PRIV;       footer = END_DSA_PRIV;
04015         } else
04016             break;
04017     }
04018 
04019     if (!headerEnd) {
04020         WOLFSSL_MSG("Couldn't find PEM header");
04021         return SSL_NO_PEM_HEADER;
04022     }
04023 
04024     headerEnd += XSTRLEN(header);
04025 
04026     if ((headerEnd + 1) >= bufferEnd)
04027         return SSL_BAD_FILE;
04028 
04029     /* eat end of line */
04030     if (headerEnd[0] == '\n')
04031         headerEnd++;
04032     else if (headerEnd[1] == '\n')
04033         headerEnd += 2;
04034     else {
04035         if (info)
04036             info->consumed = (long)(headerEnd+2 - (char*)buff);
04037         return SSL_BAD_FILE;
04038     }
04039 
04040     if (type == PRIVATEKEY_TYPE) {
04041         if (eccKey)
04042             *eccKey = header == BEGIN_EC_PRIV;
04043     }
04044 
04045 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
04046     {
04047         /* remove encrypted header if there */
04048         char encHeader[] = "Proc-Type";
04049         char* line = XSTRNSTR(headerEnd, encHeader, PEM_LINE_LEN);
04050         if (line) {
04051             char* newline;
04052             char* finish;
04053             char* start  = XSTRNSTR(line, "DES", PEM_LINE_LEN);
04054 
04055             if (!start)
04056                 start = XSTRNSTR(line, "AES", PEM_LINE_LEN);
04057 
04058             if (!start) return SSL_BAD_FILE;
04059             if (!info)  return SSL_BAD_FILE;
04060 
04061             finish = XSTRNSTR(start, ",", PEM_LINE_LEN);
04062 
04063             if (start && finish && (start < finish)) {
04064                 newline = XSTRNSTR(finish, "\r", PEM_LINE_LEN);
04065 
04066                 if (XMEMCPY(info->name, start, finish - start) == NULL)
04067                     return SSL_FATAL_ERROR;
04068                 info->name[finish - start] = 0;
04069                 if (XMEMCPY(info->iv, finish + 1, sizeof(info->iv)) == NULL)
04070                     return SSL_FATAL_ERROR;
04071 
04072                 if (!newline) newline = XSTRNSTR(finish, "\n", PEM_LINE_LEN);
04073                 if (newline && (newline > finish)) {
04074                     info->ivSz = (word32)(newline - (finish + 1));
04075                     info->set = 1;
04076                 }
04077                 else
04078                     return SSL_BAD_FILE;
04079             }
04080             else
04081                 return SSL_BAD_FILE;
04082 
04083             /* eat blank line */
04084             while (*newline == '\r' || *newline == '\n')
04085                 newline++;
04086             headerEnd = newline;
04087 
04088             encrypted_key = 1;
04089         }
04090     }
04091 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
04092 
04093     /* find footer */
04094     footerEnd = XSTRNSTR((char*)buff, footer, sz);
04095     if (!footerEnd) {
04096         if (info)
04097             info->consumed = longSz; /* No more certs if no footer */
04098         return SSL_BAD_FILE;
04099     }
04100 
04101     consumedEnd = footerEnd + XSTRLEN(footer);
04102 
04103     if (consumedEnd < bufferEnd) {  /* handle no end of line on last line */
04104         /* eat end of line */
04105         if (consumedEnd[0] == '\n')
04106             consumedEnd++;
04107         else if ((consumedEnd + 1 < bufferEnd) && consumedEnd[1] == '\n')
04108             consumedEnd += 2;
04109         else {
04110             if (info)
04111                 info->consumed = (long)(consumedEnd+2 - (char*)buff);
04112             return SSL_BAD_FILE;
04113         }
04114     }
04115 
04116     if (info)
04117         info->consumed = (long)(consumedEnd - (char*)buff);
04118 
04119     /* set up der buffer */
04120     neededSz = (long)(footerEnd - headerEnd);
04121     if (neededSz > sz || neededSz <= 0)
04122         return SSL_BAD_FILE;
04123 
04124     ret = AllocDer(pDer, (word32)neededSz, type, heap);
04125     if (ret < 0) {
04126         return ret;
04127     }
04128     der = *pDer;
04129 
04130     if (Base64_Decode((byte*)headerEnd, (word32)neededSz,
04131                       der->buffer, &der->length) < 0)
04132         return SSL_BAD_FILE;
04133 
04134     if (header == BEGIN_PRIV_KEY && !encrypted_key) {
04135         /* pkcs8 key, convert and adjust length */
04136         if ((ret = ToTraditional(der->buffer, der->length)) < 0)
04137             return ret;
04138 
04139         der->length = ret;
04140         return 0;
04141     }
04142 
04143 #if (defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)) && !defined(NO_PWDBASED)
04144     if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
04145         int   passwordSz;
04146     #ifdef WOLFSSL_SMALL_STACK
04147         char* password = NULL;
04148     #else
04149         char  password[80];
04150     #endif
04151 
04152         if (!info || !info->ctx || !info->ctx->passwd_cb)
04153             return SSL_BAD_FILE;  /* no callback error */
04154 
04155     #ifdef WOLFSSL_SMALL_STACK
04156         password = (char*)XMALLOC(80, heap, DYNAMIC_TYPE_TMP_BUFFER);
04157         if (password == NULL)
04158             return MEMORY_E;
04159     #endif
04160         passwordSz = info->ctx->passwd_cb(password, sizeof(password), 0,
04161                                           info->ctx->userdata);
04162         /* convert and adjust length */
04163         if (header == BEGIN_ENC_PRIV_KEY) {
04164             ret = ToTraditionalEnc(der->buffer, der->length,
04165                                    password, passwordSz);
04166     #ifdef WOLFSSL_SMALL_STACK
04167             XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04168     #endif
04169             if (ret < 0) {
04170                 return ret;
04171             }
04172 
04173             der->length = ret;
04174         }
04175         /* decrypt the key */
04176         else {
04177             ret = wolfssl_decrypt_buffer_key(der, (byte*)password,
04178                                              passwordSz, info);
04179     #ifdef WOLFSSL_SMALL_STACK
04180             XFREE(password, heap, DYNAMIC_TYPE_TMP_BUFFER);
04181     #endif
04182             if (ret != SSL_SUCCESS) {
04183                 return ret;
04184             }
04185         }
04186     }
04187 #endif  /* OPENSSL_EXTRA || HAVE_WEBSERVER || NO_PWDBASED */
04188 
04189     return 0;
04190 }
04191 
04192 
04193 
04194 /* process user cert chain to pass during the handshake */
04195 static int ProcessUserChain(WOLFSSL_CTX* ctx, const unsigned char* buff,
04196                          long sz, int format, int type, WOLFSSL* ssl,
04197                          long* used, EncryptedInfo* info)
04198 {
04199     int ret = 0;
04200     void* heap = ctx ? ctx->heap : ((ssl) ? ssl->heap : NULL);
04201 #ifdef WOLFSSL_TLS13
04202     int cnt = 0;
04203 #endif
04204 
04205     /* we may have a user cert chain, try to consume */
04206     if (type == CERT_TYPE && info->consumed < sz) {
04207     #ifdef WOLFSSL_SMALL_STACK
04208         byte   staticBuffer[1];                 /* force heap usage */
04209     #else
04210         byte   staticBuffer[FILE_BUFFER_SIZE];  /* tmp chain buffer */
04211     #endif
04212         byte*  chainBuffer = staticBuffer;
04213         int    dynamicBuffer = 0;
04214         word32 bufferSz = sizeof(staticBuffer);
04215         long   consumed = info->consumed;
04216         word32 idx = 0;
04217         int    gotOne = 0;
04218 
04219         if ( (sz - consumed) > (int)bufferSz) {
04220             WOLFSSL_MSG("Growing Tmp Chain Buffer");
04221             bufferSz = (word32)(sz - consumed);
04222                        /* will shrink to actual size */
04223             chainBuffer = (byte*)XMALLOC(bufferSz, heap, DYNAMIC_TYPE_FILE);
04224             if (chainBuffer == NULL) {
04225                 return MEMORY_E;
04226             }
04227             dynamicBuffer = 1;
04228         }
04229 
04230         WOLFSSL_MSG("Processing Cert Chain");
04231         while (consumed < sz) {
04232             int eccKey = 0;
04233             DerBuffer* part = NULL;
04234             word32 remain = (word32)(sz - consumed);
04235             info->consumed = 0;
04236 
04237             if (format == SSL_FILETYPE_PEM) {
04238                 ret = PemToDer(buff + consumed, remain, type, &part,
04239                                heap, info, &eccKey);
04240             }
04241             else {
04242                 int length = remain;
04243                 if (format == SSL_FILETYPE_ASN1) {
04244                     /* get length of der (read sequence) */
04245                     word32 inOutIdx = 0;
04246                     if (GetSequence(buff + consumed, &inOutIdx, &length, remain) < 0) {
04247                         ret = SSL_NO_PEM_HEADER;
04248                     }
04249                     length += inOutIdx; /* include leading squence */
04250                 }
04251                 info->consumed = length;
04252                 if (ret == 0) {
04253                     ret = AllocDer(&part, length, type, heap);
04254                     if (ret == 0) {
04255                         XMEMCPY(part->buffer, buff + consumed, length);
04256                     }
04257                 }
04258             }
04259             if (ret == 0) {
04260                 gotOne = 1;
04261 #ifdef WOLFSSL_TLS13
04262                 cnt++;
04263 #endif
04264                 if ((idx + part->length) > bufferSz) {
04265                     WOLFSSL_MSG("   Cert Chain bigger than buffer");
04266                     ret = BUFFER_E;
04267                 }
04268                 else {
04269                     c32to24(part->length, &chainBuffer[idx]);
04270                     idx += CERT_HEADER_SZ;
04271                     XMEMCPY(&chainBuffer[idx], part->buffer, part->length);
04272                     idx += part->length;
04273                     consumed  += info->consumed;
04274                     if (used)
04275                         *used += info->consumed;
04276                 }
04277             }
04278             FreeDer(&part);
04279 
04280             if (ret == SSL_NO_PEM_HEADER && gotOne) {
04281                 WOLFSSL_MSG("We got one good cert, so stuff at end ok");
04282                 break;
04283             }
04284 
04285             if (ret < 0) {
04286                 WOLFSSL_MSG("   Error in Cert in Chain");
04287                 if (dynamicBuffer)
04288                     XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
04289                 return ret;
04290             }
04291             WOLFSSL_MSG("   Consumed another Cert in Chain");
04292         }
04293         WOLFSSL_MSG("Finished Processing Cert Chain");
04294 
04295         /* only retain actual size used */
04296         ret = 0;
04297         if (idx > 0) {
04298             if (ssl) {
04299                 if (ssl->buffers.weOwnCertChain) {
04300                     FreeDer(&ssl->buffers.certChain);
04301                 }
04302                 ret = AllocDer(&ssl->buffers.certChain, idx, type, heap);
04303                 if (ret == 0) {
04304                     XMEMCPY(ssl->buffers.certChain->buffer, chainBuffer, idx);
04305                     ssl->buffers.weOwnCertChain = 1;
04306                 }
04307 #ifdef WOLFSSL_TLS13
04308                 ssl->buffers.certChainCnt = cnt;
04309 #endif
04310             } else if (ctx) {
04311                 FreeDer(&ctx->certChain);
04312                 ret = AllocDer(&ctx->certChain, idx, type, heap);
04313                 if (ret == 0) {
04314                     XMEMCPY(ctx->certChain->buffer, chainBuffer, idx);
04315                 }
04316 #ifdef WOLFSSL_TLS13
04317                 ctx->certChainCnt = cnt;
04318 #endif
04319             }
04320         }
04321 
04322         if (dynamicBuffer)
04323             XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
04324     }
04325 
04326     return ret;
04327 }
04328 /* process the buffer buff, length sz, into ctx of format and type
04329    used tracks bytes consumed, userChain specifies a user cert chain
04330    to pass during the handshake */
04331 int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
04332                          long sz, int format, int type, WOLFSSL* ssl,
04333                          long* used, int userChain)
04334 {
04335     DerBuffer*    der = NULL;        /* holds DER or RAW (for NTRU) */
04336     int           ret = 0;
04337     int           eccKey = 0;
04338     int           rsaKey = 0;
04339     int           resetSuites = 0;
04340     void*         heap = ctx ? ctx->heap : ((ssl) ? ssl->heap : NULL);
04341     int           devId = ctx ? ctx->devId : ((ssl) ? ssl->devId : INVALID_DEVID);
04342 #ifdef WOLFSSL_SMALL_STACK
04343     EncryptedInfo* info = NULL;
04344 #else
04345     EncryptedInfo  info[1];
04346 #endif
04347 
04348     (void)rsaKey;
04349 
04350     if (used)
04351         *used = sz;     /* used bytes default to sz, PEM chain may shorten*/
04352 
04353     /* check args */
04354     if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM
04355                                     && format != SSL_FILETYPE_RAW)
04356         return SSL_BAD_FILETYPE;
04357 
04358     if (ctx == NULL && ssl == NULL)
04359         return BAD_FUNC_ARG;
04360 
04361 #ifdef WOLFSSL_SMALL_STACK
04362     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), heap,
04363                                    DYNAMIC_TYPE_TMP_BUFFER);
04364     if (info == NULL)
04365         return MEMORY_E;
04366 #endif
04367 
04368     XMEMSET(info, 0, sizeof(EncryptedInfo));
04369     info->set      = 0;
04370     info->ctx      = ctx;
04371     info->consumed = 0;
04372 
04373     if (format == SSL_FILETYPE_PEM) {
04374         ret = PemToDer(buff, sz, type, &der, heap, info, &eccKey);
04375     }
04376     else {  /* ASN1 (DER) or RAW (NTRU) */
04377         int length = (int)sz;
04378         if (format == SSL_FILETYPE_ASN1) {
04379             /* get length of der (read sequence) */
04380             word32 inOutIdx = 0;
04381             if (GetSequence(buff, &inOutIdx, &length, (word32)sz) < 0) {
04382                 ret = ASN_PARSE_E;
04383             }
04384             length += inOutIdx; /* include leading squence */
04385         }
04386         info->consumed = length;
04387         if (ret == 0) {
04388             ret = AllocDer(&der, (word32)length, type, heap);
04389             if (ret == 0) {
04390                 XMEMCPY(der->buffer, buff, length);
04391             }
04392         }
04393     }
04394 
04395     if (used) {
04396         *used = info->consumed;
04397     }
04398 
04399     /* process user chain */
04400     if (ret >= 0) {
04401         if (userChain) {
04402             ret = ProcessUserChain(ctx, buff, sz, format, type, ssl, used, info);
04403         }
04404     }
04405 
04406     /* check for error */
04407     if (ret < 0) {
04408     #ifdef WOLFSSL_SMALL_STACK
04409         XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
04410     #endif
04411         FreeDer(&der);
04412         return ret;
04413     }
04414 
04415 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
04416     /* for SSL_FILETYPE_PEM, PemToDer manage the decryption if required */
04417     if (info->set && (format != SSL_FILETYPE_PEM)) {
04418         /* decrypt */
04419         int   passwordSz;
04420 #ifdef WOLFSSL_SMALL_STACK
04421         char* password = NULL;
04422 #else
04423         char  password[80];
04424 #endif
04425 
04426     #ifdef WOLFSSL_SMALL_STACK
04427         password = (char*)XMALLOC(80, heap, DYNAMIC_TYPE_TMP_BUFFER);
04428         if (password == NULL)
04429             ret = MEMORY_E;
04430         else
04431     #endif
04432         if (!ctx || !ctx->passwd_cb) {
04433             ret = NO_PASSWORD;
04434         }
04435         else {
04436             passwordSz = ctx->passwd_cb(password, sizeof(password),
04437                                         0, ctx->userdata);
04438 
04439             /* decrypt the key */
04440             ret = wolfssl_decrypt_buffer_key(der, (byte*)password,
04441                                              passwordSz, info);
04442         }
04443 
04444     #ifdef WOLFSSL_SMALL_STACK
04445         XFREE(password, heap, DYNAMIC_TYPE_TMP_BUFFER);
04446     #endif
04447 
04448         if (ret != SSL_SUCCESS) {
04449         #ifdef WOLFSSL_SMALL_STACK
04450             XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
04451         #endif
04452             FreeDer(&der);
04453             return ret;
04454         }
04455     }
04456 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
04457 
04458 #ifdef WOLFSSL_SMALL_STACK
04459     XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
04460 #endif
04461 
04462     /* Handle DER owner */
04463     if (type == CA_TYPE) {
04464         if (ctx == NULL) {
04465             WOLFSSL_MSG("Need context for CA load");
04466             FreeDer(&der);
04467             return BAD_FUNC_ARG;
04468         }
04469         /* verify CA unless user set to no verify */
04470         return AddCA(ctx->cm, &der, WOLFSSL_USER_CA, !ctx->verifyNone);
04471     }
04472 #ifdef WOLFSSL_TRUST_PEER_CERT
04473     else if (type == TRUSTED_PEER_TYPE) {
04474         if (ctx == NULL) {
04475             WOLFSSL_MSG("Need context for trusted peer cert load");
04476             FreeDer(&der);
04477             return BAD_FUNC_ARG;
04478         }
04479         /* add trusted peer cert */
04480         return AddTrustedPeer(ctx->cm, &der, !ctx->verifyNone);
04481     }
04482 #endif /* WOLFSSL_TRUST_PEER_CERT */
04483     else if (type == CERT_TYPE) {
04484         if (ssl) {
04485              /* Make sure previous is free'd */
04486             if (ssl->buffers.weOwnCert) {
04487                 FreeDer(&ssl->buffers.certificate);
04488                 #ifdef KEEP_OUR_CERT
04489                     FreeX509(ssl->ourCert);
04490                     if (ssl->ourCert) {
04491                         XFREE(ssl->ourCert, ssl->heap, DYNAMIC_TYPE_X509);
04492                         ssl->ourCert = NULL;
04493                     }
04494                 #endif
04495             }
04496             ssl->buffers.certificate = der;
04497             #ifdef KEEP_OUR_CERT
04498                 ssl->keepCert = 1; /* hold cert for ssl lifetime */
04499             #endif
04500             ssl->buffers.weOwnCert = 1;
04501         }
04502         else if (ctx) {
04503             FreeDer(&ctx->certificate); /* Make sure previous is free'd */
04504         #ifdef KEEP_OUR_CERT
04505             if (ctx->ourCert) {
04506                 if (ctx->ownOurCert) {
04507                     FreeX509(ctx->ourCert);
04508                     XFREE(ctx->ourCert, ctx->heap, DYNAMIC_TYPE_X509);
04509                 }
04510                 ctx->ourCert = NULL;
04511             }
04512         #endif
04513             ctx->certificate = der;
04514         }
04515     }
04516     else if (type == PRIVATEKEY_TYPE) {
04517         if (ssl) {
04518              /* Make sure previous is free'd */
04519             if (ssl->buffers.weOwnKey) {
04520                 FreeDer(&ssl->buffers.key);
04521             }
04522             ssl->buffers.key = der;
04523             ssl->buffers.weOwnKey = 1;
04524         }
04525         else if (ctx) {
04526             FreeDer(&ctx->privateKey);
04527             ctx->privateKey = der;
04528         }
04529     }
04530     else {
04531         FreeDer(&der);
04532         return SSL_BAD_CERTTYPE;
04533     }
04534 
04535     if (type == PRIVATEKEY_TYPE && format != SSL_FILETYPE_RAW) {
04536     #ifndef NO_RSA
04537         if (!eccKey) {
04538             /* make sure RSA key can be used */
04539             word32 idx = 0;
04540         #ifdef WOLFSSL_SMALL_STACK
04541             RsaKey* key = NULL;
04542         #else
04543             RsaKey  key[1];
04544         #endif
04545 
04546         #ifdef WOLFSSL_SMALL_STACK
04547             key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap,
04548                                    DYNAMIC_TYPE_TMP_BUFFER);
04549             if (key == NULL)
04550                 return MEMORY_E;
04551         #endif
04552 
04553             ret = wc_InitRsaKey_ex(key, heap, devId);
04554             if (ret == 0) {
04555                 if (wc_RsaPrivateKeyDecode(der->buffer, &idx, key, der->length)
04556                     != 0) {
04557                 #ifdef HAVE_ECC
04558                     /* could have DER ECC (or pkcs8 ecc), no easy way to tell */
04559                     eccKey = 1;  /* so try it out */
04560                 #else
04561                     WOLFSSL_MSG("RSA decode failed and ECC not enabled to try");
04562                     ret = SSL_BAD_FILE;
04563                 #endif
04564                 } else {
04565                     /* check that the size of the RSA key is enough */
04566                     int RsaSz = wc_RsaEncryptSize((RsaKey*)key);
04567 
04568                     if (ssl) {
04569                         if (RsaSz < ssl->options.minRsaKeySz) {
04570                             ret = RSA_KEY_SIZE_E;
04571                             WOLFSSL_MSG("Private Key size too small");
04572                         }
04573                     }
04574                     else if(ctx) {
04575                         if (RsaSz < ctx->minRsaKeySz) {
04576                             ret = RSA_KEY_SIZE_E;
04577                             WOLFSSL_MSG("Private Key size too small");
04578                         }
04579                     }
04580                     rsaKey = 1;
04581                     (void)rsaKey;  /* for no ecc builds */
04582 
04583                     if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
04584                         ssl->options.haveStaticECC = 0;
04585                         resetSuites = 1;
04586                     }
04587                 }
04588 
04589                 wc_FreeRsaKey(key);
04590             }
04591 
04592         #ifdef WOLFSSL_SMALL_STACK
04593             XFREE(key, heap, DYNAMIC_TYPE_TMP_BUFFER);
04594         #endif
04595 
04596             if (ret != 0)
04597                 return ret;
04598         }
04599     #endif
04600     #ifdef HAVE_ECC
04601         if (!rsaKey) {
04602             /* make sure ECC key can be used */
04603             word32  idx = 0;
04604             ecc_key key;
04605 
04606             ret = wc_ecc_init_ex(&key, heap, devId);
04607             if (ret != 0) {
04608                 return ret;
04609             }
04610 
04611             if (wc_EccPrivateKeyDecode(der->buffer, &idx, &key,
04612                                                         der->length) != 0) {
04613                 wc_ecc_free(&key);
04614                 return SSL_BAD_FILE;
04615             }
04616 
04617             /* check for minimum ECC key size and then free */
04618             if (ssl) {
04619                 if (wc_ecc_size(&key) < ssl->options.minEccKeySz) {
04620                     wc_ecc_free(&key);
04621                     WOLFSSL_MSG("ECC private key too small");
04622                     return ECC_KEY_SIZE_E;
04623                 }
04624             }
04625             else if (ctx) {
04626                 if (wc_ecc_size(&key) < ctx->minEccKeySz) {
04627                     wc_ecc_free(&key);
04628                     WOLFSSL_MSG("ECC private key too small");
04629                     return ECC_KEY_SIZE_E;
04630                 }
04631             }
04632 
04633             wc_ecc_free(&key);
04634             eccKey = 1;
04635             if (ssl) {
04636                 ssl->options.haveStaticECC = 1;
04637             }
04638             else if (ctx) {
04639                 ctx->haveStaticECC = 1;
04640             }
04641 
04642             if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
04643                 resetSuites = 1;
04644             }
04645         }
04646     #endif /* HAVE_ECC */
04647     }
04648     else if (type == CERT_TYPE) {
04649     #ifdef WOLFSSL_SMALL_STACK
04650         DecodedCert* cert = NULL;
04651     #else
04652         DecodedCert  cert[1];
04653     #endif
04654 
04655     #ifdef WOLFSSL_SMALL_STACK
04656         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap,
04657                                      DYNAMIC_TYPE_TMP_BUFFER);
04658         if (cert == NULL)
04659             return MEMORY_E;
04660     #endif
04661 
04662         WOLFSSL_MSG("Checking cert signature type");
04663         InitDecodedCert(cert, der->buffer, der->length, heap);
04664 
04665         if (DecodeToKey(cert, 0) < 0) {
04666             WOLFSSL_MSG("Decode to key failed");
04667             FreeDecodedCert(cert);
04668         #ifdef WOLFSSL_SMALL_STACK
04669             XFREE(cert, heap, DYNAMIC_TYPE_TMP_BUFFER);
04670         #endif
04671             return SSL_BAD_FILE;
04672         }
04673 
04674         if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
04675             resetSuites = 1;
04676         }
04677         if (ssl && ssl->ctx->haveECDSAsig) {
04678             WOLFSSL_MSG("SSL layer setting cert, CTX had ECDSA, turning off");
04679             ssl->options.haveECDSAsig = 0;   /* may turn back on next */
04680         }
04681 
04682         switch (cert->signatureOID) {
04683             case CTC_SHAwECDSA:
04684             case CTC_SHA256wECDSA:
04685             case CTC_SHA384wECDSA:
04686             case CTC_SHA512wECDSA:
04687                 WOLFSSL_MSG("ECDSA cert signature");
04688                 if (ssl)
04689                     ssl->options.haveECDSAsig = 1;
04690                 else if (ctx)
04691                     ctx->haveECDSAsig = 1;
04692                 break;
04693             default:
04694                 WOLFSSL_MSG("Not ECDSA cert signature");
04695                 break;
04696         }
04697 
04698     #ifdef HAVE_ECC
04699         if (ssl) {
04700             ssl->pkCurveOID = cert->pkCurveOID;
04701         #ifndef WC_STRICT_SIG
04702             if (cert->keyOID == ECDSAk) {
04703                 ssl->options.haveECC = 1;
04704             }
04705         #else
04706             ssl->options.haveECC = ssl->options.haveECDSAsig;
04707         #endif
04708         }
04709         else if (ctx) {
04710             ctx->pkCurveOID = cert->pkCurveOID;
04711         #ifndef WC_STRICT_SIG
04712             if (cert->keyOID == ECDSAk) {
04713                 ctx->haveECC = 1;
04714             }
04715         #else
04716             ctx->haveECC = ctx->haveECDSAsig;
04717         #endif
04718         }
04719     #endif
04720 
04721         /* check key size of cert unless specified not to */
04722         switch (cert->keyOID) {
04723         #ifndef NO_RSA
04724             case RSAk:
04725                 if (ssl && !ssl->options.verifyNone) {
04726                     if (ssl->options.minRsaKeySz < 0 ||
04727                           cert->pubKeySize < (word16)ssl->options.minRsaKeySz) {
04728                         ret = RSA_KEY_SIZE_E;
04729                         WOLFSSL_MSG("Certificate RSA key size too small");
04730                     }
04731                 }
04732                 else if (ctx && !ctx->verifyNone) {
04733                     if (ctx->minRsaKeySz < 0 ||
04734                                   cert->pubKeySize < (word16)ctx->minRsaKeySz) {
04735                         ret = RSA_KEY_SIZE_E;
04736                         WOLFSSL_MSG("Certificate RSA key size too small");
04737                     }
04738                 }
04739                 break;
04740             #endif /* !NO_RSA */
04741         #ifdef HAVE_ECC
04742             case ECDSAk:
04743                 if (ssl && !ssl->options.verifyNone) {
04744                     if (ssl->options.minEccKeySz < 0 ||
04745                           cert->pubKeySize < (word16)ssl->options.minEccKeySz) {
04746                         ret = ECC_KEY_SIZE_E;
04747                         WOLFSSL_MSG("Certificate ECC key size error");
04748                     }
04749                 }
04750                 else if (ctx && !ctx->verifyNone) {
04751                     if (ctx->minEccKeySz < 0 ||
04752                                   cert->pubKeySize < (word16)ctx->minEccKeySz) {
04753                         ret = ECC_KEY_SIZE_E;
04754                         WOLFSSL_MSG("Certificate ECC key size error");
04755                     }
04756                 }
04757                 break;
04758             #endif /* HAVE_ECC */
04759 
04760             default:
04761                 WOLFSSL_MSG("No key size check done on certificate");
04762                 break; /* do no check if not a case for the key */
04763         }
04764 
04765         FreeDecodedCert(cert);
04766     #ifdef WOLFSSL_SMALL_STACK
04767         XFREE(cert, heap, DYNAMIC_TYPE_TMP_BUFFER);
04768     #endif
04769 
04770         if (ret != 0) {
04771             return ret;
04772         }
04773     }
04774 
04775     if (ssl && resetSuites) {
04776         word16 havePSK = 0;
04777         word16 haveRSA = 0;
04778 
04779         #ifndef NO_PSK
04780         if (ssl->options.havePSK) {
04781             havePSK = 1;
04782         }
04783         #endif
04784         #ifndef NO_RSA
04785             haveRSA = 1;
04786         #endif
04787 
04788         /* let's reset suites */
04789         InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
04790                    ssl->options.haveDH, ssl->options.haveNTRU,
04791                    ssl->options.haveECDSAsig, ssl->options.haveECC,
04792                    ssl->options.haveStaticECC, ssl->options.side);
04793     }
04794 
04795     return SSL_SUCCESS;
04796 }
04797 
04798 
04799 /* CA PEM file for verification, may have multiple/chain certs to process */
04800 static int ProcessChainBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
04801                             long sz, int format, int type, WOLFSSL* ssl)
04802 {
04803     long used   = 0;
04804     int  ret    = 0;
04805     int  gotOne = 0;
04806 
04807     WOLFSSL_MSG("Processing CA PEM file");
04808     while (used < sz) {
04809         long consumed = 0;
04810 
04811         ret = ProcessBuffer(ctx, buff + used, sz - used, format, type, ssl,
04812                             &consumed, 0);
04813 
04814 #ifdef WOLFSSL_WPAS
04815 #ifdef HAVE_CRL
04816         if (ret < 0) {
04817             DerBuffer*    der = NULL;
04818             EncryptedInfo info;
04819 
04820             WOLFSSL_MSG("Trying a CRL");
04821             if (PemToDer(buff + used, sz - used, CRL_TYPE, &der, NULL, &info,
04822                          NULL) == 0) {
04823                 WOLFSSL_MSG("   Proccessed a CRL");
04824                 wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, der->buffer,
04825                                                  der->length,SSL_FILETYPE_ASN1);
04826                 FreeDer(&der);
04827                 used += info.consumed;
04828                 continue;
04829             }
04830         }
04831 #endif
04832 #endif
04833         if (ret < 0)
04834         {
04835             if(consumed > 0) { /* Made progress in file */
04836                 WOLFSSL_ERROR(ret);
04837                 WOLFSSL_MSG("CA Parse failed, with progress in file.");
04838                 WOLFSSL_MSG("Search for other certs in file");
04839             } else {
04840                 WOLFSSL_MSG("CA Parse failed, no progress in file.");
04841                 WOLFSSL_MSG("Do not continue search for other certs in file");
04842                 break;
04843             }
04844         } else {
04845             WOLFSSL_MSG("   Processed a CA");
04846             gotOne = 1;
04847         }
04848         used += consumed;
04849     }
04850 
04851     if(gotOne)
04852     {
04853         WOLFSSL_MSG("Processed at least one valid CA. Other stuff OK");
04854         return SSL_SUCCESS;
04855     }
04856     return ret;
04857 }
04858 
04859 
04860 static INLINE WOLFSSL_METHOD* cm_pick_method(void)
04861 {
04862     #ifndef NO_WOLFSSL_CLIENT
04863         #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
04864             return wolfSSLv3_client_method();
04865         #else
04866             return wolfTLSv1_2_client_method();
04867         #endif
04868     #elif !defined(NO_WOLFSSL_SERVER)
04869         #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
04870             return wolfSSLv3_server_method();
04871         #else
04872             return wolfTLSv1_2_server_method();
04873         #endif
04874     #else
04875         return NULL;
04876     #endif
04877 }
04878 
04879 
04880 /* like load verify locations, 1 for success, < 0 for error */
04881 int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm,
04882                                    const unsigned char* in, long sz, int format)
04883 {
04884     int ret = SSL_FATAL_ERROR;
04885     WOLFSSL_CTX* tmp;
04886 
04887     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCABuffer");
04888 
04889     if (cm == NULL) {
04890         WOLFSSL_MSG("No CertManager error");
04891         return ret;
04892     }
04893     tmp = wolfSSL_CTX_new(cm_pick_method());
04894 
04895     if (tmp == NULL) {
04896         WOLFSSL_MSG("CTX new failed");
04897         return ret;
04898     }
04899 
04900     /* for tmp use */
04901     wolfSSL_CertManagerFree(tmp->cm);
04902     tmp->cm = cm;
04903 
04904     ret = wolfSSL_CTX_load_verify_buffer(tmp, in, sz, format);
04905 
04906     /* don't loose our good one */
04907     tmp->cm = NULL;
04908     wolfSSL_CTX_free(tmp);
04909 
04910     return ret;
04911 }
04912 
04913 #ifdef HAVE_CRL
04914 
04915 int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER* cm,
04916                                    const unsigned char* buff, long sz, int type)
04917 {
04918     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLBuffer");
04919     if (cm == NULL)
04920         return BAD_FUNC_ARG;
04921 
04922     if (cm->crl == NULL) {
04923         if (wolfSSL_CertManagerEnableCRL(cm, 0) != SSL_SUCCESS) {
04924             WOLFSSL_MSG("Enable CRL failed");
04925             return SSL_FATAL_ERROR;
04926         }
04927     }
04928 
04929     return BufferLoadCRL(cm->crl, buff, sz, type);
04930 }
04931 
04932 
04933 int wolfSSL_CTX_LoadCRLBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
04934                               long sz, int type)
04935 {
04936     WOLFSSL_ENTER("wolfSSL_CTX_LoadCRLBuffer");
04937 
04938     if (ctx == NULL)
04939         return BAD_FUNC_ARG;
04940 
04941     return wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, buff, sz, type);
04942 }
04943 
04944 
04945 int wolfSSL_LoadCRLBuffer(WOLFSSL* ssl, const unsigned char* buff,
04946                           long sz, int type)
04947 {
04948     WOLFSSL_ENTER("wolfSSL_LoadCRLBuffer");
04949 
04950     if (ssl == NULL || ssl->ctx == NULL)
04951         return BAD_FUNC_ARG;
04952 
04953     return wolfSSL_CertManagerLoadCRLBuffer(ssl->ctx->cm, buff, sz, type);
04954 }
04955 
04956 
04957 #endif /* HAVE_CRL */
04958 
04959 /* turn on CRL if off and compiled in, set options */
04960 int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, int options)
04961 {
04962     int ret = SSL_SUCCESS;
04963 
04964     (void)options;
04965 
04966     WOLFSSL_ENTER("wolfSSL_CertManagerEnableCRL");
04967     if (cm == NULL)
04968         return BAD_FUNC_ARG;
04969 
04970     #ifdef HAVE_CRL
04971         if (cm->crl == NULL) {
04972             cm->crl = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), cm->heap,
04973                                            DYNAMIC_TYPE_CRL);
04974             if (cm->crl == NULL)
04975                 return MEMORY_E;
04976 
04977             if (InitCRL(cm->crl, cm) != 0) {
04978                 WOLFSSL_MSG("Init CRL failed");
04979                 FreeCRL(cm->crl, 1);
04980                 cm->crl = NULL;
04981                 return SSL_FAILURE;
04982             }
04983 
04984         #ifdef HAVE_CRL_IO
04985             cm->crl->crlIOCb = EmbedCrlLookup;
04986         #endif
04987         }
04988 
04989         cm->crlEnabled = 1;
04990         if (options & WOLFSSL_CRL_CHECKALL)
04991             cm->crlCheckAll = 1;
04992     #else
04993         ret = NOT_COMPILED_IN;
04994     #endif
04995 
04996     return ret;
04997 }
04998 
04999 
05000 int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER* cm)
05001 {
05002     WOLFSSL_ENTER("wolfSSL_CertManagerDisableCRL");
05003     if (cm == NULL)
05004         return BAD_FUNC_ARG;
05005 
05006     cm->crlEnabled = 0;
05007 
05008     return SSL_SUCCESS;
05009 }
05010 /* Verify the certificate, SSL_SUCCESS for ok, < 0 for error */
05011 int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
05012                                     long sz, int format)
05013 {
05014     int ret = 0;
05015     DerBuffer* der = NULL;
05016 #ifdef WOLFSSL_SMALL_STACK
05017     DecodedCert* cert = NULL;
05018 #else
05019     DecodedCert  cert[1];
05020 #endif
05021 
05022     WOLFSSL_ENTER("wolfSSL_CertManagerVerifyBuffer");
05023 
05024 #ifdef WOLFSSL_SMALL_STACK
05025     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
05026                                  DYNAMIC_TYPE_TMP_BUFFER);
05027     if (cert == NULL)
05028         return MEMORY_E;
05029 #endif
05030 
05031     if (format == SSL_FILETYPE_PEM) {
05032         int eccKey = 0; /* not used */
05033     #ifdef WOLFSSL_SMALL_STACK
05034         EncryptedInfo* info = NULL;
05035     #else
05036         EncryptedInfo  info[1];
05037     #endif
05038 
05039     #ifdef WOLFSSL_SMALL_STACK
05040         info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), cm->heap,
05041                                        DYNAMIC_TYPE_TMP_BUFFER);
05042         if (info == NULL) {
05043             XFREE(cert, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
05044             return MEMORY_E;
05045         }
05046     #endif
05047 
05048         info->set      = 0;
05049         info->ctx      = NULL;
05050         info->consumed = 0;
05051 
05052         ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, info, &eccKey);
05053         if (ret != 0) {
05054             FreeDer(&der);
05055             #ifdef WOLFSSL_SMALL_STACK
05056                 XFREE(info, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
05057             #endif
05058             return ret;
05059         }
05060         InitDecodedCert(cert, der->buffer, der->length, cm->heap);
05061 
05062     #ifdef WOLFSSL_SMALL_STACK
05063         XFREE(info, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
05064     #endif
05065     }
05066     else
05067         InitDecodedCert(cert, (byte*)buff, (word32)sz, cm->heap);
05068 
05069     if (ret == 0)
05070         ret = ParseCertRelative(cert, CERT_TYPE, 1, cm);
05071 
05072 #ifdef HAVE_CRL
05073     if (ret == 0 && cm->crlEnabled)
05074         ret = CheckCertCRL(cm->crl, cert);
05075 #endif
05076 
05077     FreeDecodedCert(cert);
05078     FreeDer(&der);
05079 #ifdef WOLFSSL_SMALL_STACK
05080     XFREE(cert, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
05081 #endif
05082 
05083     return ret == 0 ? SSL_SUCCESS : ret;
05084 }
05085 
05086 
05087 /* turn on OCSP if off and compiled in, set options */
05088 int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, int options)
05089 {
05090     int ret = SSL_SUCCESS;
05091 
05092     (void)options;
05093 
05094     WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSP");
05095     if (cm == NULL)
05096         return BAD_FUNC_ARG;
05097 
05098     #ifdef HAVE_OCSP
05099         if (cm->ocsp == NULL) {
05100             cm->ocsp = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), cm->heap,
05101                                               DYNAMIC_TYPE_OCSP);
05102             if (cm->ocsp == NULL)
05103                 return MEMORY_E;
05104 
05105             if (InitOCSP(cm->ocsp, cm) != 0) {
05106                 WOLFSSL_MSG("Init OCSP failed");
05107                 FreeOCSP(cm->ocsp, 1);
05108                 cm->ocsp = NULL;
05109                 return SSL_FAILURE;
05110             }
05111         }
05112         cm->ocspEnabled = 1;
05113         if (options & WOLFSSL_OCSP_URL_OVERRIDE)
05114             cm->ocspUseOverrideURL = 1;
05115         if (options & WOLFSSL_OCSP_NO_NONCE)
05116             cm->ocspSendNonce = 0;
05117         else
05118             cm->ocspSendNonce = 1;
05119         if (options & WOLFSSL_OCSP_CHECKALL)
05120             cm->ocspCheckAll = 1;
05121         #ifndef WOLFSSL_USER_IO
05122             cm->ocspIOCb = EmbedOcspLookup;
05123             cm->ocspRespFreeCb = EmbedOcspRespFree;
05124             cm->ocspIOCtx = cm->heap;
05125         #endif /* WOLFSSL_USER_IO */
05126     #else
05127         ret = NOT_COMPILED_IN;
05128     #endif
05129 
05130     return ret;
05131 }
05132 
05133 
05134 int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm)
05135 {
05136     WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSP");
05137     if (cm == NULL)
05138         return BAD_FUNC_ARG;
05139 
05140     cm->ocspEnabled = 0;
05141 
05142     return SSL_SUCCESS;
05143 }
05144 
05145 /* turn on OCSP Stapling if off and compiled in, set options */
05146 int wolfSSL_CertManagerEnableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
05147 {
05148     int ret = SSL_SUCCESS;
05149 
05150     WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPStapling");
05151     if (cm == NULL)
05152         return BAD_FUNC_ARG;
05153 
05154     #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
05155      || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
05156         if (cm->ocsp_stapling == NULL) {
05157             cm->ocsp_stapling = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP),
05158                                                    cm->heap, DYNAMIC_TYPE_OCSP);
05159             if (cm->ocsp_stapling == NULL)
05160                 return MEMORY_E;
05161 
05162             if (InitOCSP(cm->ocsp_stapling, cm) != 0) {
05163                 WOLFSSL_MSG("Init OCSP failed");
05164                 FreeOCSP(cm->ocsp_stapling, 1);
05165                 cm->ocsp_stapling = NULL;
05166                 return SSL_FAILURE;
05167             }
05168         }
05169         cm->ocspStaplingEnabled = 1;
05170 
05171         #ifndef WOLFSSL_USER_IO
05172             cm->ocspIOCb = EmbedOcspLookup;
05173             cm->ocspRespFreeCb = EmbedOcspRespFree;
05174             cm->ocspIOCtx = cm->heap;
05175         #endif /* WOLFSSL_USER_IO */
05176     #else
05177         ret = NOT_COMPILED_IN;
05178     #endif
05179 
05180     return ret;
05181 }
05182 
05183 
05184 #ifdef HAVE_OCSP
05185 
05186 
05187 /* check CRL if enabled, SSL_SUCCESS  */
05188 int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
05189 {
05190     int ret;
05191 #ifdef WOLFSSL_SMALL_STACK
05192     DecodedCert* cert = NULL;
05193 #else
05194     DecodedCert  cert[1];
05195 #endif
05196 
05197     WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSP");
05198 
05199     if (cm == NULL)
05200         return BAD_FUNC_ARG;
05201 
05202     if (cm->ocspEnabled == 0)
05203         return SSL_SUCCESS;
05204 
05205 #ifdef WOLFSSL_SMALL_STACK
05206     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
05207                                  DYNAMIC_TYPE_TMP_BUFFER);
05208     if (cert == NULL)
05209         return MEMORY_E;
05210 #endif
05211 
05212     InitDecodedCert(cert, der, sz, NULL);
05213 
05214     if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm)) != 0) {
05215         WOLFSSL_MSG("ParseCert failed");
05216     }
05217     else if ((ret = CheckCertOCSP(cm->ocsp, cert, NULL)) != 0) {
05218         WOLFSSL_MSG("CheckCertOCSP failed");
05219     }
05220 
05221     FreeDecodedCert(cert);
05222 #ifdef WOLFSSL_SMALL_STACK
05223     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
05224 #endif
05225 
05226     return ret == 0 ? SSL_SUCCESS : ret;
05227 }
05228 
05229 
05230 int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER* cm,
05231                                           const char* url)
05232 {
05233     WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSPOverrideURL");
05234     if (cm == NULL)
05235         return BAD_FUNC_ARG;
05236 
05237     XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
05238     if (url != NULL) {
05239         int urlSz = (int)XSTRLEN(url) + 1;
05240         cm->ocspOverrideURL = (char*)XMALLOC(urlSz, cm->heap, DYNAMIC_TYPE_URL);
05241         if (cm->ocspOverrideURL != NULL) {
05242             XMEMCPY(cm->ocspOverrideURL, url, urlSz);
05243         }
05244         else
05245             return MEMORY_E;
05246     }
05247     else
05248         cm->ocspOverrideURL = NULL;
05249 
05250     return SSL_SUCCESS;
05251 }
05252 
05253 
05254 int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER* cm,
05255                         CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
05256 {
05257     WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSP_Cb");
05258     if (cm == NULL)
05259         return BAD_FUNC_ARG;
05260 
05261     cm->ocspIOCb = ioCb;
05262     cm->ocspRespFreeCb = respFreeCb;
05263     cm->ocspIOCtx = ioCbCtx;
05264 
05265     return SSL_SUCCESS;
05266 }
05267 
05268 
05269 int wolfSSL_EnableOCSP(WOLFSSL* ssl, int options)
05270 {
05271     WOLFSSL_ENTER("wolfSSL_EnableOCSP");
05272     if (ssl)
05273         return wolfSSL_CertManagerEnableOCSP(ssl->ctx->cm, options);
05274     else
05275         return BAD_FUNC_ARG;
05276 }
05277 
05278 
05279 int wolfSSL_DisableOCSP(WOLFSSL* ssl)
05280 {
05281     WOLFSSL_ENTER("wolfSSL_DisableOCSP");
05282     if (ssl)
05283         return wolfSSL_CertManagerDisableOCSP(ssl->ctx->cm);
05284     else
05285         return BAD_FUNC_ARG;
05286 }
05287 
05288 
05289 int wolfSSL_SetOCSP_OverrideURL(WOLFSSL* ssl, const char* url)
05290 {
05291     WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
05292     if (ssl)
05293         return wolfSSL_CertManagerSetOCSPOverrideURL(ssl->ctx->cm, url);
05294     else
05295         return BAD_FUNC_ARG;
05296 }
05297 
05298 
05299 int wolfSSL_SetOCSP_Cb(WOLFSSL* ssl,
05300                         CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
05301 {
05302     WOLFSSL_ENTER("wolfSSL_SetOCSP_Cb");
05303     if (ssl)
05304         return wolfSSL_CertManagerSetOCSP_Cb(ssl->ctx->cm,
05305                                              ioCb, respFreeCb, ioCbCtx);
05306     else
05307         return BAD_FUNC_ARG;
05308 }
05309 
05310 
05311 int wolfSSL_CTX_EnableOCSP(WOLFSSL_CTX* ctx, int options)
05312 {
05313     WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSP");
05314     if (ctx)
05315         return wolfSSL_CertManagerEnableOCSP(ctx->cm, options);
05316     else
05317         return BAD_FUNC_ARG;
05318 }
05319 
05320 
05321 int wolfSSL_CTX_DisableOCSP(WOLFSSL_CTX* ctx)
05322 {
05323     WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSP");
05324     if (ctx)
05325         return wolfSSL_CertManagerDisableOCSP(ctx->cm);
05326     else
05327         return BAD_FUNC_ARG;
05328 }
05329 
05330 
05331 int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX* ctx, const char* url)
05332 {
05333     WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
05334     if (ctx)
05335         return wolfSSL_CertManagerSetOCSPOverrideURL(ctx->cm, url);
05336     else
05337         return BAD_FUNC_ARG;
05338 }
05339 
05340 
05341 int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX* ctx, CbOCSPIO ioCb,
05342                            CbOCSPRespFree respFreeCb, void* ioCbCtx)
05343 {
05344     WOLFSSL_ENTER("wolfSSL_CTX_SetOCSP_Cb");
05345     if (ctx)
05346         return wolfSSL_CertManagerSetOCSP_Cb(ctx->cm, ioCb,
05347                                              respFreeCb, ioCbCtx);
05348     else
05349         return BAD_FUNC_ARG;
05350 }
05351 
05352 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
05353  || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
05354 int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX* ctx)
05355 {
05356     WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPStapling");
05357     if (ctx)
05358         return wolfSSL_CertManagerEnableOCSPStapling(ctx->cm);
05359     else
05360         return BAD_FUNC_ARG;
05361 }
05362 #endif
05363 
05364 #endif /* HAVE_OCSP */
05365 
05366 
05367 #ifndef NO_FILESYSTEM
05368 
05369 /* process a file with name fname into ctx of format and type
05370    userChain specifies a user certificate chain to pass during handshake */
05371 int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type,
05372                 WOLFSSL* ssl, int userChain, WOLFSSL_CRL* crl)
05373 {
05374 #ifdef WOLFSSL_SMALL_STACK
05375     byte   staticBuffer[1]; /* force heap usage */
05376 #else
05377     byte   staticBuffer[FILE_BUFFER_SIZE];
05378 #endif
05379     byte*  myBuffer = staticBuffer;
05380     int    dynamic = 0;
05381     int    ret;
05382     long   sz = 0;
05383     XFILE  file;
05384     void*  heapHint = ctx ? ctx->heap : ((ssl) ? ssl->heap : NULL);
05385 
05386     (void)crl;
05387     (void)heapHint;
05388 
05389     if (fname == NULL) return SSL_BAD_FILE;
05390 
05391     file = XFOPEN(fname, "rb");
05392     if (file == XBADFILE) return SSL_BAD_FILE;
05393     XFSEEK(file, 0, XSEEK_END);
05394     sz = XFTELL(file);
05395     XREWIND(file);
05396 
05397     if (sz > (long)sizeof(staticBuffer)) {
05398         WOLFSSL_MSG("Getting dynamic buffer");
05399         myBuffer = (byte*)XMALLOC(sz, heapHint, DYNAMIC_TYPE_FILE);
05400         if (myBuffer == NULL) {
05401             XFCLOSE(file);
05402             return SSL_BAD_FILE;
05403         }
05404         dynamic = 1;
05405     }
05406     else if (sz <= 0) {
05407         XFCLOSE(file);
05408         return SSL_BAD_FILE;
05409     }
05410 
05411     if ( (ret = (int)XFREAD(myBuffer, 1, sz, file)) != sz)
05412         ret = SSL_BAD_FILE;
05413     else {
05414         if ((type == CA_TYPE || type == TRUSTED_PEER_TYPE)
05415                                                   && format == SSL_FILETYPE_PEM)
05416             ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl);
05417 #ifdef HAVE_CRL
05418         else if (type == CRL_TYPE)
05419             ret = BufferLoadCRL(crl, myBuffer, sz, format);
05420 #endif
05421         else
05422             ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL,
05423                                 userChain);
05424     }
05425 
05426     XFCLOSE(file);
05427     if (dynamic)
05428         XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
05429 
05430     return ret;
05431 }
05432 
05433 
05434 /* loads file then loads each file in path, no c_rehash */
05435 int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
05436                                      const char* path)
05437 {
05438     int ret = SSL_SUCCESS;
05439 
05440     WOLFSSL_ENTER("wolfSSL_CTX_load_verify_locations");
05441 
05442     if (ctx == NULL || (file == NULL && path == NULL) )
05443         return SSL_FAILURE;
05444 
05445     if (file)
05446         ret = ProcessFile(ctx, file, SSL_FILETYPE_PEM, CA_TYPE, NULL, 0, NULL);
05447 
05448     if (ret == SSL_SUCCESS && path) {
05449 #ifndef NO_WOLFSSL_DIR
05450         char* name = NULL;
05451     #ifdef WOLFSSL_SMALL_STACK
05452         ReadDirCtx* readCtx = NULL;
05453         readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), ctx->heap,
05454                                                        DYNAMIC_TYPE_TMP_BUFFER);
05455         if (name == NULL)
05456             return MEMORY_E;
05457     #else
05458         ReadDirCtx readCtx[1];
05459     #endif
05460 
05461         /* try to load each regular file in path */
05462         ret = wc_ReadDirFirst(readCtx, path, &name);
05463         while (ret == 0 && name) {
05464             ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE,
05465                                                           NULL, 0, NULL);
05466             if (ret != SSL_SUCCESS)
05467                 break;
05468             ret = wc_ReadDirNext(readCtx, path, &name);
05469         }
05470         wc_ReadDirClose(readCtx);
05471 
05472     #ifdef WOLFSSL_SMALL_STACK
05473         XFREE(readCtx, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
05474     #endif
05475 #else
05476         ret = NOT_COMPILED_IN;
05477 #endif
05478     }
05479 
05480     return ret;
05481 }
05482 
05483 
05484 #ifdef WOLFSSL_TRUST_PEER_CERT
05485 /* Used to specify a peer cert to match when connecting
05486     ctx : the ctx structure to load in peer cert
05487     file: the string name of cert file
05488     type: type of format such as PEM/DER
05489  */
05490 int wolfSSL_CTX_trust_peer_cert(WOLFSSL_CTX* ctx, const char* file, int type)
05491 {
05492     WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_cert");
05493 
05494     if (ctx == NULL || file == NULL) {
05495         return SSL_FAILURE;
05496     }
05497 
05498     return ProcessFile(ctx, file, type, TRUSTED_PEER_TYPE, NULL, 0, NULL);
05499 }
05500 #endif /* WOLFSSL_TRUST_PEER_CERT */
05501 
05502 
05503 /* Verify the certificate, SSL_SUCCESS for ok, < 0 for error */
05504 int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* fname,
05505                              int format)
05506 {
05507     int    ret = SSL_FATAL_ERROR;
05508 #ifdef WOLFSSL_SMALL_STACK
05509     byte   staticBuffer[1]; /* force heap usage */
05510 #else
05511     byte   staticBuffer[FILE_BUFFER_SIZE];
05512 #endif
05513     byte*  myBuffer = staticBuffer;
05514     int    dynamic = 0;
05515     long   sz = 0;
05516     XFILE  file = XFOPEN(fname, "rb");
05517 
05518     WOLFSSL_ENTER("wolfSSL_CertManagerVerify");
05519 
05520     if (file == XBADFILE) return SSL_BAD_FILE;
05521     XFSEEK(file, 0, XSEEK_END);
05522     sz = XFTELL(file);
05523     XREWIND(file);
05524 
05525     if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
05526         WOLFSSL_MSG("CertManagerVerify file bad size");
05527         XFCLOSE(file);
05528         return SSL_BAD_FILE;
05529     }
05530 
05531     if (sz > (long)sizeof(staticBuffer)) {
05532         WOLFSSL_MSG("Getting dynamic buffer");
05533         myBuffer = (byte*) XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE);
05534         if (myBuffer == NULL) {
05535             XFCLOSE(file);
05536             return SSL_BAD_FILE;
05537         }
05538         dynamic = 1;
05539     }
05540 
05541     if ( (ret = (int)XFREAD(myBuffer, 1, sz, file)) != sz)
05542         ret = SSL_BAD_FILE;
05543     else
05544         ret = wolfSSL_CertManagerVerifyBuffer(cm, myBuffer, sz, format);
05545 
05546     XFCLOSE(file);
05547     if (dynamic)
05548         XFREE(myBuffer, cm->heap, DYNAMIC_TYPE_FILE);
05549 
05550     return ret;
05551 }
05552 
05553 
05554 /* like load verify locations, 1 for success, < 0 for error */
05555 int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* file,
05556                              const char* path)
05557 {
05558     int ret = SSL_FATAL_ERROR;
05559     WOLFSSL_CTX* tmp;
05560 
05561     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCA");
05562 
05563     if (cm == NULL) {
05564         WOLFSSL_MSG("No CertManager error");
05565         return ret;
05566     }
05567     tmp = wolfSSL_CTX_new(cm_pick_method());
05568 
05569     if (tmp == NULL) {
05570         WOLFSSL_MSG("CTX new failed");
05571         return ret;
05572     }
05573 
05574     /* for tmp use */
05575     wolfSSL_CertManagerFree(tmp->cm);
05576     tmp->cm = cm;
05577 
05578     ret = wolfSSL_CTX_load_verify_locations(tmp, file, path);
05579 
05580     /* don't loose our good one */
05581     tmp->cm = NULL;
05582     wolfSSL_CTX_free(tmp);
05583 
05584     return ret;
05585 }
05586 
05587 
05588 
05589 
05590 int wolfSSL_CTX_check_private_key(WOLFSSL_CTX* ctx)
05591 {
05592     /* TODO: check private against public for RSA match */
05593     (void)ctx;
05594     WOLFSSL_ENTER("SSL_CTX_check_private_key");
05595     return SSL_SUCCESS;
05596 }
05597 
05598 
05599 #ifdef HAVE_CRL
05600 
05601 
05602 /* check CRL if enabled, SSL_SUCCESS  */
05603 int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
05604 {
05605     int ret = 0;
05606 #ifdef WOLFSSL_SMALL_STACK
05607     DecodedCert* cert = NULL;
05608 #else
05609     DecodedCert  cert[1];
05610 #endif
05611 
05612     WOLFSSL_ENTER("wolfSSL_CertManagerCheckCRL");
05613 
05614     if (cm == NULL)
05615         return BAD_FUNC_ARG;
05616 
05617     if (cm->crlEnabled == 0)
05618         return SSL_SUCCESS;
05619 
05620 #ifdef WOLFSSL_SMALL_STACK
05621     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
05622                                  DYNAMIC_TYPE_TMP_BUFFER);
05623     if (cert == NULL)
05624         return MEMORY_E;
05625 #endif
05626 
05627     InitDecodedCert(cert, der, sz, NULL);
05628 
05629     if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_CRL, cm)) != 0) {
05630         WOLFSSL_MSG("ParseCert failed");
05631     }
05632     else if ((ret = CheckCertCRL(cm->crl, cert)) != 0) {
05633         WOLFSSL_MSG("CheckCertCRL failed");
05634     }
05635 
05636     FreeDecodedCert(cert);
05637 #ifdef WOLFSSL_SMALL_STACK
05638     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
05639 #endif
05640 
05641     return ret == 0 ? SSL_SUCCESS : ret;
05642 }
05643 
05644 
05645 int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, CbMissingCRL cb)
05646 {
05647     WOLFSSL_ENTER("wolfSSL_CertManagerSetCRL_Cb");
05648     if (cm == NULL)
05649         return BAD_FUNC_ARG;
05650 
05651     cm->cbMissingCRL = cb;
05652 
05653     return SSL_SUCCESS;
05654 }
05655 
05656 #ifdef HAVE_CRL_IO
05657 int wolfSSL_CertManagerSetCRL_IOCb(WOLFSSL_CERT_MANAGER* cm, CbCrlIO cb)
05658 {
05659     if (cm == NULL)
05660         return BAD_FUNC_ARG;
05661 
05662     cm->crl->crlIOCb = cb;
05663 
05664     return SSL_SUCCESS;
05665 }
05666 #endif
05667 
05668 int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER* cm, const char* path,
05669                               int type, int monitor)
05670 {
05671     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRL");
05672     if (cm == NULL)
05673         return BAD_FUNC_ARG;
05674 
05675     if (cm->crl == NULL) {
05676         if (wolfSSL_CertManagerEnableCRL(cm, 0) != SSL_SUCCESS) {
05677             WOLFSSL_MSG("Enable CRL failed");
05678             return SSL_FATAL_ERROR;
05679         }
05680     }
05681 
05682     return LoadCRL(cm->crl, path, type, monitor);
05683 }
05684 
05685 
05686 int wolfSSL_EnableCRL(WOLFSSL* ssl, int options)
05687 {
05688     WOLFSSL_ENTER("wolfSSL_EnableCRL");
05689     if (ssl)
05690         return wolfSSL_CertManagerEnableCRL(ssl->ctx->cm, options);
05691     else
05692         return BAD_FUNC_ARG;
05693 }
05694 
05695 
05696 int wolfSSL_DisableCRL(WOLFSSL* ssl)
05697 {
05698     WOLFSSL_ENTER("wolfSSL_DisableCRL");
05699     if (ssl)
05700         return wolfSSL_CertManagerDisableCRL(ssl->ctx->cm);
05701     else
05702         return BAD_FUNC_ARG;
05703 }
05704 
05705 
05706 int wolfSSL_LoadCRL(WOLFSSL* ssl, const char* path, int type, int monitor)
05707 {
05708     WOLFSSL_ENTER("wolfSSL_LoadCRL");
05709     if (ssl)
05710         return wolfSSL_CertManagerLoadCRL(ssl->ctx->cm, path, type, monitor);
05711     else
05712         return BAD_FUNC_ARG;
05713 }
05714 
05715 
05716 int wolfSSL_SetCRL_Cb(WOLFSSL* ssl, CbMissingCRL cb)
05717 {
05718     WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
05719     if (ssl)
05720         return wolfSSL_CertManagerSetCRL_Cb(ssl->ctx->cm, cb);
05721     else
05722         return BAD_FUNC_ARG;
05723 }
05724 
05725 #ifdef HAVE_CRL_IO
05726 int wolfSSL_SetCRL_IOCb(WOLFSSL* ssl, CbCrlIO cb)
05727 {
05728     WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
05729     if (ssl)
05730         return wolfSSL_CertManagerSetCRL_IOCb(ssl->ctx->cm, cb);
05731     else
05732         return BAD_FUNC_ARG;
05733 }
05734 #endif
05735 
05736 int wolfSSL_CTX_EnableCRL(WOLFSSL_CTX* ctx, int options)
05737 {
05738     WOLFSSL_ENTER("wolfSSL_CTX_EnableCRL");
05739     if (ctx)
05740         return wolfSSL_CertManagerEnableCRL(ctx->cm, options);
05741     else
05742         return BAD_FUNC_ARG;
05743 }
05744 
05745 
05746 int wolfSSL_CTX_DisableCRL(WOLFSSL_CTX* ctx)
05747 {
05748     WOLFSSL_ENTER("wolfSSL_CTX_DisableCRL");
05749     if (ctx)
05750         return wolfSSL_CertManagerDisableCRL(ctx->cm);
05751     else
05752         return BAD_FUNC_ARG;
05753 }
05754 
05755 
05756 int wolfSSL_CTX_LoadCRL(WOLFSSL_CTX* ctx, const char* path,
05757                         int type, int monitor)
05758 {
05759     WOLFSSL_ENTER("wolfSSL_CTX_LoadCRL");
05760     if (ctx)
05761         return wolfSSL_CertManagerLoadCRL(ctx->cm, path, type, monitor);
05762     else
05763         return BAD_FUNC_ARG;
05764 }
05765 
05766 
05767 int wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX* ctx, CbMissingCRL cb)
05768 {
05769     WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_Cb");
05770     if (ctx)
05771         return wolfSSL_CertManagerSetCRL_Cb(ctx->cm, cb);
05772     else
05773         return BAD_FUNC_ARG;
05774 }
05775 
05776 #ifdef HAVE_CRL_IO
05777 int wolfSSL_CTX_SetCRL_IOCb(WOLFSSL_CTX* ctx, CbCrlIO cb)
05778 {
05779     WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_IOCb");
05780     if (ctx)
05781         return wolfSSL_CertManagerSetCRL_IOCb(ctx->cm, cb);
05782     else
05783         return BAD_FUNC_ARG;
05784 }
05785 #endif
05786 
05787 
05788 #endif /* HAVE_CRL */
05789 
05790 
05791 #ifdef WOLFSSL_DER_LOAD
05792 
05793 /* Add format parameter to allow DER load of CA files */
05794 int wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
05795                                           int format)
05796 {
05797     WOLFSSL_ENTER("wolfSSL_CTX_der_load_verify_locations");
05798     if (ctx == NULL || file == NULL)
05799         return SSL_FAILURE;
05800 
05801     if (ProcessFile(ctx, file, format, CA_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
05802         return SSL_SUCCESS;
05803 
05804     return SSL_FAILURE;
05805 }
05806 
05807 #endif /* WOLFSSL_DER_LOAD */
05808 
05809 
05810 #ifdef WOLFSSL_CERT_GEN
05811 
05812 /* load pem cert from file into der buffer, return der size or error */
05813 int wolfSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
05814 {
05815 #ifdef WOLFSSL_SMALL_STACK
05816     EncryptedInfo* info = NULL;
05817     byte   staticBuffer[1]; /* force XMALLOC */
05818 #else
05819     EncryptedInfo info[1];
05820     byte   staticBuffer[FILE_BUFFER_SIZE];
05821 #endif
05822     byte*  fileBuf = staticBuffer;
05823     int    dynamic = 0;
05824     int    ret     = 0;
05825     int    ecc     = 0;
05826     long   sz      = 0;
05827     XFILE  file    = XFOPEN(fileName, "rb");
05828     DerBuffer* converted = NULL;
05829 
05830     WOLFSSL_ENTER("wolfSSL_PemCertToDer");
05831 
05832     if (file == XBADFILE) {
05833         ret = SSL_BAD_FILE;
05834     }
05835     else {
05836         XFSEEK(file, 0, XSEEK_END);
05837         sz = XFTELL(file);
05838         XREWIND(file);
05839 
05840         if (sz <= 0) {
05841             ret = SSL_BAD_FILE;
05842         }
05843         else if (sz > (long)sizeof(staticBuffer)) {
05844         #ifdef WOLFSSL_STATIC_MEMORY
05845             WOLFSSL_MSG("File was larger then static buffer");
05846             return MEMORY_E;
05847         #endif
05848             fileBuf = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
05849             if (fileBuf == NULL)
05850                 ret = MEMORY_E;
05851             else
05852                 dynamic = 1;
05853         }
05854 
05855         if (ret == 0) {
05856             if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz) {
05857                 ret = SSL_BAD_FILE;
05858             }
05859             else {
05860             #ifdef WOLFSSL_SMALL_STACK
05861                 info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
05862                                                DYNAMIC_TYPE_TMP_BUFFER);
05863                 if (info == NULL)
05864                     ret = MEMORY_E;
05865                 else
05866             #endif
05867                 {
05868                     ret = PemToDer(fileBuf, sz, CA_TYPE, &converted,
05869                                    0, info, &ecc);
05870                 #ifdef WOLFSSL_SMALL_STACK
05871                     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
05872                 #endif
05873                 }
05874             }
05875 
05876             if (ret == 0) {
05877                 if (converted->length < (word32)derSz) {
05878                     XMEMCPY(derBuf, converted->buffer, converted->length);
05879                     ret = converted->length;
05880                 }
05881                 else
05882                     ret = BUFFER_E;
05883             }
05884 
05885             FreeDer(&converted);
05886         }
05887 
05888         XFCLOSE(file);
05889         if (dynamic)
05890             XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE);
05891     }
05892 
05893     return ret;
05894 }
05895 
05896 #endif /* WOLFSSL_CERT_GEN */
05897 
05898 #ifdef WOLFSSL_CERT_EXT
05899 #ifndef NO_FILESYSTEM
05900 /* load pem public key from file into der buffer, return der size or error */
05901 int wolfSSL_PemPubKeyToDer(const char* fileName,
05902                            unsigned char* derBuf, int derSz)
05903 {
05904 #ifdef WOLFSSL_SMALL_STACK
05905     byte   staticBuffer[1]; /* force XMALLOC */
05906 #else
05907     byte   staticBuffer[FILE_BUFFER_SIZE];
05908 #endif
05909     byte*  fileBuf = staticBuffer;
05910     int    dynamic = 0;
05911     int    ret     = 0;
05912     long   sz      = 0;
05913     XFILE  file    = XFOPEN(fileName, "rb");
05914     DerBuffer* converted = NULL;
05915 
05916     WOLFSSL_ENTER("wolfSSL_PemPubKeyToDer");
05917 
05918     if (file == XBADFILE) {
05919         ret = SSL_BAD_FILE;
05920     }
05921     else {
05922         XFSEEK(file, 0, XSEEK_END);
05923         sz = XFTELL(file);
05924         XREWIND(file);
05925 
05926         if (sz <= 0) {
05927             ret = SSL_BAD_FILE;
05928         }
05929         else if (sz > (long)sizeof(staticBuffer)) {
05930         #ifdef WOLFSSL_STATIC_MEMORY
05931             WOLFSSL_MSG("File was larger then static buffer");
05932             return MEMORY_E;
05933         #endif
05934             fileBuf = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
05935             if (fileBuf == NULL)
05936                 ret = MEMORY_E;
05937             else
05938                 dynamic = 1;
05939         }
05940         if (ret == 0) {
05941             if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz)
05942                 ret = SSL_BAD_FILE;
05943             else
05944                 ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, &converted,
05945                                0, NULL, NULL);
05946 
05947             if (ret == 0) {
05948                 if (converted->length < (word32)derSz) {
05949                     XMEMCPY(derBuf, converted->buffer, converted->length);
05950                     ret = converted->length;
05951                 }
05952                 else
05953                     ret = BUFFER_E;
05954             }
05955 
05956             FreeDer(&converted);
05957         }
05958 
05959         XFCLOSE(file);
05960         if (dynamic)
05961             XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE);
05962     }
05963 
05964     return ret;
05965 }
05966 #endif /* NO_FILESYSTEM */
05967 
05968 /* Return bytes written to buff or < 0 for error */
05969 int wolfSSL_PubKeyPemToDer(const unsigned char* pem, int pemSz,
05970                            unsigned char* buff, int buffSz)
05971 {
05972     int ret;
05973     DerBuffer* der = NULL;
05974 
05975     WOLFSSL_ENTER("wolfSSL_PubKeyPemToDer");
05976 
05977     if (pem == NULL || buff == NULL || buffSz <= 0) {
05978         WOLFSSL_MSG("Bad pem der args");
05979         return BAD_FUNC_ARG;
05980     }
05981 
05982     ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, NULL);
05983     if (ret < 0) {
05984         WOLFSSL_MSG("Bad Pem To Der");
05985     }
05986     else {
05987         if (der->length <= (word32)buffSz) {
05988             XMEMCPY(buff, der->buffer, der->length);
05989             ret = der->length;
05990         }
05991         else {
05992             WOLFSSL_MSG("Bad der length");
05993             ret = BAD_FUNC_ARG;
05994         }
05995     }
05996 
05997     FreeDer(&der);
05998     return ret;
05999 }
06000 
06001 #endif /* WOLFSSL_CERT_EXT */
06002 
06003 int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
06004                                      int format)
06005 {
06006     WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_file");
06007     if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
06008         return SSL_SUCCESS;
06009 
06010     return SSL_FAILURE;
06011 }
06012 
06013 
06014 int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX* ctx, const char* file,
06015                                     int format)
06016 {
06017     WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_file");
06018     if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL)
06019                     == SSL_SUCCESS)
06020         return SSL_SUCCESS;
06021 
06022     return SSL_FAILURE;
06023 }
06024 
06025 
06026 /* get cert chaining depth using ssl struct */
06027 long wolfSSL_get_verify_depth(WOLFSSL* ssl)
06028 {
06029     if(ssl == NULL) {
06030         return BAD_FUNC_ARG;
06031     }
06032     return MAX_CHAIN_DEPTH;
06033 }
06034 
06035 
06036 /* get cert chaining depth using ctx struct */
06037 long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx)
06038 {
06039     if(ctx == NULL) {
06040         return BAD_FUNC_ARG;
06041     }
06042     return MAX_CHAIN_DEPTH;
06043 }
06044 
06045 
06046 int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX* ctx, const char* file)
06047 {
06048    /* process up to MAX_CHAIN_DEPTH plus subject cert */
06049    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file");
06050    if (ProcessFile(ctx, file, SSL_FILETYPE_PEM,CERT_TYPE,NULL,1, NULL)
06051                    == SSL_SUCCESS)
06052        return SSL_SUCCESS;
06053 
06054    return SSL_FAILURE;
06055 }
06056 
06057 
06058 #ifndef NO_DH
06059 
06060 /* server Diffie-Hellman parameters */
06061 static int wolfSSL_SetTmpDH_file_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
06062                                         const char* fname, int format)
06063 {
06064 #ifdef WOLFSSL_SMALL_STACK
06065     byte   staticBuffer[1]; /* force heap usage */
06066 #else
06067     byte   staticBuffer[FILE_BUFFER_SIZE];
06068 #endif
06069     byte*  myBuffer = staticBuffer;
06070     int    dynamic = 0;
06071     int    ret;
06072     long   sz = 0;
06073     XFILE  file;
06074 
06075     if (ctx == NULL || fname == NULL)
06076         return BAD_FUNC_ARG;
06077 
06078     file = XFOPEN(fname, "rb");
06079     if (file == XBADFILE) return SSL_BAD_FILE;
06080     XFSEEK(file, 0, XSEEK_END);
06081     sz = XFTELL(file);
06082     XREWIND(file);
06083 
06084     if (sz > (long)sizeof(staticBuffer)) {
06085         WOLFSSL_MSG("Getting dynamic buffer");
06086         myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
06087         if (myBuffer == NULL) {
06088             XFCLOSE(file);
06089             return SSL_BAD_FILE;
06090         }
06091         dynamic = 1;
06092     }
06093     else if (sz <= 0) {
06094         XFCLOSE(file);
06095         return SSL_BAD_FILE;
06096     }
06097 
06098     if ( (ret = (int)XFREAD(myBuffer, 1, sz, file)) != sz)
06099         ret = SSL_BAD_FILE;
06100     else {
06101         if (ssl)
06102             ret = wolfSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format);
06103         else
06104             ret = wolfSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format);
06105     }
06106 
06107     XFCLOSE(file);
06108     if (dynamic)
06109         XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
06110 
06111     return ret;
06112 }
06113 
06114 /* server Diffie-Hellman parameters */
06115 int wolfSSL_SetTmpDH_file(WOLFSSL* ssl, const char* fname, int format)
06116 {
06117     if (ssl == NULL)
06118         return BAD_FUNC_ARG;
06119 
06120     return wolfSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format);
06121 }
06122 
06123 
06124 /* server Diffie-Hellman parameters */
06125 int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format)
06126 {
06127     return wolfSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format);
06128 }
06129 
06130 #endif /* NO_DH */
06131 
06132 
06133 #ifdef OPENSSL_EXTRA
06134 /* put SSL type in extra for now, not very common */
06135 
06136 WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out,
06137         const unsigned char **in, long inSz)
06138 {
06139     WOLFSSL_EVP_PKEY* local;
06140 
06141     WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey");
06142 
06143     if (in == NULL || inSz < 0) {
06144         WOLFSSL_MSG("Bad argument");
06145         return NULL;
06146     }
06147 
06148     local = wolfSSL_PKEY_new();
06149     if (local == NULL) {
06150         return NULL;
06151     }
06152 
06153     local->type     = type;
06154     local->pkey_sz  = (int)inSz;
06155     local->pkey.ptr = (char*)XMALLOC(inSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
06156     if (local->pkey.ptr == NULL) {
06157         wolfSSL_EVP_PKEY_free(local);
06158         local = NULL;
06159     }
06160     else {
06161         XMEMCPY(local->pkey.ptr, *in, inSz);
06162     }
06163 
06164     if (out != NULL) {
06165         *out = local;
06166     }
06167 
06168     return local;
06169 }
06170 
06171 
06172 long wolfSSL_ctrl(WOLFSSL* ssl, int cmd, long opt, void* pt)
06173 {
06174     WOLFSSL_STUB("wolfSSL_ctrl");
06175     (void)ssl;
06176     (void)cmd;
06177     (void)opt;
06178     (void)pt;
06179     return SSL_FAILURE;
06180 }
06181 
06182 
06183 long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt)
06184 {
06185     WOLFSSL_STUB("wolfSSL_CTX_ctrl");
06186     (void)ctx;
06187     (void)cmd;
06188     (void)opt;
06189     (void)pt;
06190     return SSL_FAILURE;
06191 }
06192 
06193 #ifndef NO_CERTS
06194 int wolfSSL_check_private_key(const WOLFSSL* ssl)
06195 {
06196     DecodedCert der;
06197     word32 size;
06198     byte*  buff;
06199     int    ret;
06200 
06201     if (ssl == NULL) {
06202         return SSL_FAILURE;
06203     }
06204 
06205     size = ssl->buffers.certificate->length;
06206     buff = ssl->buffers.certificate->buffer;
06207     InitDecodedCert(&der, buff, size, ssl->heap);
06208     if (ParseCertRelative(&der, CERT_TYPE, NO_VERIFY, NULL) != 0) {
06209         FreeDecodedCert(&der);
06210         return SSL_FAILURE;
06211     }
06212 
06213     size = ssl->buffers.key->length;
06214     buff = ssl->buffers.key->buffer;
06215     ret  = wc_CheckPrivateKey(buff, size, &der);
06216     FreeDecodedCert(&der);
06217     return ret;
06218 }
06219 
06220 
06221 /* Looks for the extension matching the passed in nid
06222  *
06223  * c   : if not null then is set to status value -2 if multiple occurances
06224  *       of the extension are found, -1 if not found, 0 if found and not
06225  *       critical, and 1 if found and critical.
06226  * nid : Extension OID to be found.
06227  * idx : if NULL return first extension found match, otherwise start search at
06228  *       idx location and set idx to the location of extension returned.
06229  * returns NULL or a pointer to an WOLFSSL_STACK holding extension structure
06230  *
06231  * NOTE code for decoding extensions is in asn.c DecodeCertExtensions --
06232  * use already decoded extension in this function to avoid decoding twice.
06233  * Currently we do not make use of idx since getting pre decoded extensions.
06234  */
06235 void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509,
06236                                                      int nid, int* c, int* idx)
06237 {
06238     WOLFSSL_STACK* sk = NULL;
06239     WOLFSSL_ASN1_OBJECT* obj = NULL;
06240 
06241     WOLFSSL_ENTER("wolfSSL_X509_get_ext_d2i");
06242 
06243     if (x509 == NULL) {
06244         return NULL;
06245     }
06246 
06247     if (c != NULL) {
06248         *c = -1; /* default to not found */
06249     }
06250 
06251     sk = (STACK_OF(WOLFSSL_ASN1_OBJECT)*)XMALLOC(
06252                 sizeof(STACK_OF(WOLFSSL_ASN1_OBJECT)), NULL, DYNAMIC_TYPE_ASN1);
06253     if (sk == NULL) {
06254         return NULL;
06255     }
06256     XMEMSET(sk, 0, sizeof(STACK_OF(WOLFSSL_ASN1_OBJECT)));
06257 
06258     switch (nid) {
06259         case BASIC_CA_OID:
06260             if (x509->basicConstSet) {
06261                 obj = wolfSSL_ASN1_OBJECT_new();
06262                 if (c != NULL) {
06263                     *c = x509->basicConstCrit;
06264                 }
06265                 obj->type = BASIC_CA_OID;
06266             }
06267             else {
06268                 WOLFSSL_MSG("No Basic Constraint set");
06269             }
06270             break;
06271 
06272         case ALT_NAMES_OID:
06273             {
06274                 DNS_entry* dns;
06275 
06276                 if (x509->subjAltNameSet && x509->altNames != NULL) {
06277                     /* alt names are DNS_entry structs */
06278                     if (c != NULL) {
06279                         if (x509->altNames->next != NULL) {
06280                             *c = -2; /* more then one found */
06281                         }
06282                         else {
06283                             *c = x509->subjAltNameCrit;
06284                         }
06285                     }
06286 
06287                     dns = x509->altNames;
06288                     while (dns != NULL) {
06289                         obj = wolfSSL_ASN1_OBJECT_new();
06290                         obj->type = ALT_NAMES_OID;
06291                         obj->obj  = (byte*)dns->name;
06292                         dns = dns->next;
06293                         /* last dns in list add at end of function */
06294                         if (dns != NULL) {
06295                             if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) !=
06296                                                                   SSL_SUCCESS) {
06297                             WOLFSSL_MSG("Error pushing ASN1 object onto stack");
06298                             wolfSSL_ASN1_OBJECT_free(obj);
06299                             wolfSSL_sk_ASN1_OBJECT_free(sk);
06300                             sk = NULL;
06301                             }
06302                         }
06303                     }
06304                 }
06305                 else {
06306                     WOLFSSL_MSG("No Alt Names set");
06307                 }
06308             }
06309             break;
06310 
06311         case CRL_DIST_OID:
06312             if (x509->CRLdistSet && x509->CRLInfo != NULL) {
06313                 if (c != NULL) {
06314                     *c = x509->CRLdistCrit;
06315                 }
06316                 obj = wolfSSL_ASN1_OBJECT_new();
06317                 obj->type  = CRL_DIST_OID;
06318                 obj->obj   = x509->CRLInfo;
06319                 obj->objSz = x509->CRLInfoSz;
06320             }
06321             else {
06322                 WOLFSSL_MSG("No CRL dist set");
06323             }
06324             break;
06325 
06326         case AUTH_INFO_OID:
06327             if (x509->authInfoSet && x509->authInfo != NULL) {
06328                 if (c != NULL) {
06329                     *c = x509->authInfoCrit;
06330                 }
06331                 obj = wolfSSL_ASN1_OBJECT_new();
06332                 obj->type  = AUTH_INFO_OID;
06333                 obj->obj   = x509->authInfo;
06334                 obj->objSz = x509->authInfoSz;
06335             }
06336             else {
06337                 WOLFSSL_MSG("No Auth Info set");
06338             }
06339             break;
06340 
06341         case AUTH_KEY_OID:
06342             if (x509->authKeyIdSet) {
06343                 if (c != NULL) {
06344                     *c = x509->authKeyIdCrit;
06345                 }
06346                 obj = wolfSSL_ASN1_OBJECT_new();
06347                 obj->type  = AUTH_KEY_OID;
06348                 obj->obj   = x509->authKeyId;
06349                 obj->objSz = x509->authKeyIdSz;
06350             }
06351             else {
06352                 WOLFSSL_MSG("No Auth Key set");
06353             }
06354             break;
06355 
06356         case SUBJ_KEY_OID:
06357             if (x509->subjKeyIdSet) {
06358                 if (c != NULL) {
06359                     *c = x509->subjKeyIdCrit;
06360                 }
06361                 obj = wolfSSL_ASN1_OBJECT_new();
06362                 obj->type  = SUBJ_KEY_OID;
06363                 obj->obj   = x509->subjKeyId;
06364                 obj->objSz = x509->subjKeyIdSz;
06365             }
06366             else {
06367                 WOLFSSL_MSG("No Subject Key set");
06368             }
06369             break;
06370 
06371         case CERT_POLICY_OID:
06372             #ifdef WOLFSSL_CERT_EXT
06373             {
06374                 int i;
06375 
06376                 if (x509->certPoliciesNb > 0) {
06377                     if (c != NULL) {
06378                         if (x509->certPoliciesNb > 1) {
06379                             *c = -2;
06380                         }
06381                         else {
06382                             *c = 0;
06383                         }
06384                     }
06385 
06386                     for (i = 0; i < x509->certPoliciesNb - 1; i++) {
06387                         obj = wolfSSL_ASN1_OBJECT_new();
06388                         obj->type  = CERT_POLICY_OID;
06389                         obj->obj   = (byte*)(x509->certPolicies[i]);
06390                         obj->objSz = MAX_CERTPOL_SZ;
06391                         if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj)
06392                                                                != SSL_SUCCESS) {
06393                             WOLFSSL_MSG("Error pushing ASN1 object onto stack");
06394                             wolfSSL_ASN1_OBJECT_free(obj);
06395                             wolfSSL_sk_ASN1_OBJECT_free(sk);
06396                             sk = NULL;
06397                         }
06398                     }
06399                     obj = wolfSSL_ASN1_OBJECT_new();
06400                     obj->type  = CERT_POLICY_OID;
06401                     obj->obj   = (byte*)(x509->certPolicies[i]);
06402                     obj->objSz = MAX_CERTPOL_SZ;
06403                 }
06404                 else {
06405                     WOLFSSL_MSG("No Cert Policy set");
06406                 }
06407             }
06408             #else
06409                 #ifdef WOLFSSL_SEP
06410                 if (x509->certPolicySet) {
06411                     if (c != NULL) {
06412                         *c = x509->certPolicyCrit;
06413                     }
06414                     obj = wolfSSL_ASN1_OBJECT_new();
06415                     obj->type  = CERT_POLICY_OID;
06416                 }
06417                 else {
06418                     WOLFSSL_MSG("No Cert Policy set");
06419                 }
06420                 #else
06421                 WOLFSSL_MSG("wolfSSL not built with WOLFSSL_SEP or WOLFSSL_CERT_EXT");
06422                 #endif /* WOLFSSL_SEP */
06423             #endif /* WOLFSSL_CERT_EXT */
06424             break;
06425 
06426         case KEY_USAGE_OID:
06427             if (x509->keyUsageSet) {
06428                 if (c != NULL) {
06429                     *c = x509->keyUsageCrit;
06430                 }
06431                 obj = wolfSSL_ASN1_OBJECT_new();
06432                 obj->type  = KEY_USAGE_OID;
06433                 obj->obj   = (byte*)&(x509->keyUsage);
06434                 obj->objSz = sizeof(word16);
06435             }
06436             else {
06437                 WOLFSSL_MSG("No Key Usage set");
06438             }
06439             break;
06440 
06441         case INHIBIT_ANY_OID:
06442             WOLFSSL_MSG("INHIBIT ANY extension not supported");
06443             break;
06444 
06445         case EXT_KEY_USAGE_OID:
06446             if (x509->extKeyUsageSrc != NULL) {
06447                 if (c != NULL) {
06448                     if (x509->extKeyUsageCount > 1) {
06449                         *c = -2;
06450                     }
06451                     else {
06452                         *c = x509->extKeyUsageCrit;
06453                     }
06454                 }
06455                 obj = wolfSSL_ASN1_OBJECT_new();
06456                 obj->type  = EXT_KEY_USAGE_OID;
06457                 obj->obj   = x509->extKeyUsageSrc;
06458                 obj->objSz = x509->extKeyUsageSz;
06459             }
06460             else {
06461                 WOLFSSL_MSG("No Extended Key Usage set");
06462             }
06463             break;
06464 
06465         case NAME_CONS_OID:
06466             WOLFSSL_MSG("Name Constraint OID extension not supported");
06467             break;
06468 
06469         case PRIV_KEY_USAGE_PERIOD_OID:
06470             WOLFSSL_MSG("Private Key Usage Period extension not supported");
06471             break;
06472 
06473         case SUBJECT_INFO_ACCESS:
06474             WOLFSSL_MSG("Subject Info Access extension not supported");
06475             break;
06476 
06477         case POLICY_MAP_OID:
06478             WOLFSSL_MSG("Policy Map extension not supported");
06479             break;
06480 
06481         case POLICY_CONST_OID:
06482             WOLFSSL_MSG("Policy Constraint extension not supported");
06483             break;
06484 
06485         case ISSUE_ALT_NAMES_OID:
06486             WOLFSSL_MSG("Issue Alt Names extension not supported");
06487             break;
06488 
06489         case TLS_FEATURE_OID:
06490             WOLFSSL_MSG("TLS Feature extension not supported");
06491             break;
06492 
06493         default:
06494             WOLFSSL_MSG("Unsupported/Unknown extension OID");
06495     }
06496 
06497     if (obj != NULL) {
06498         if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) != SSL_SUCCESS) {
06499             WOLFSSL_MSG("Error pushing ASN1 object onto stack");
06500             wolfSSL_ASN1_OBJECT_free(obj);
06501             wolfSSL_sk_ASN1_OBJECT_free(sk);
06502             sk = NULL;
06503         }
06504     }
06505     else { /* no ASN1 object found for extension, free stack */
06506         wolfSSL_sk_ASN1_OBJECT_free(sk);
06507         sk = NULL;
06508     }
06509 
06510     (void)idx;
06511 
06512     return sk;
06513 }
06514 
06515 
06516 /* this function makes the assumption that out buffer is big enough for digest*/
06517 static int wolfSSL_EVP_Digest(unsigned char* in, int inSz, unsigned char* out,
06518                               unsigned int* outSz, const WOLFSSL_EVP_MD* evp,
06519                               WOLFSSL_ENGINE* eng)
06520 {
06521     enum wc_HashType hash = WC_HASH_TYPE_NONE;
06522     int  hashSz;
06523 
06524     if (XSTRLEN(evp) < 3) {
06525         /* do not try comparing strings if size is too small */
06526         return SSL_FAILURE;
06527     }
06528 
06529     if (XSTRNCMP("SHA", evp, 3) == 0) {
06530         if (XSTRLEN(evp) > 3) {
06531             if (XSTRNCMP("SHA256", evp, 6) == 0) {
06532                 hash = WC_HASH_TYPE_SHA256;
06533             }
06534             else if (XSTRNCMP("SHA384", evp, 6) == 0) {
06535                 hash = WC_HASH_TYPE_SHA384;
06536             }
06537             else if (XSTRNCMP("SHA512", evp, 6) == 0) {
06538                 hash = WC_HASH_TYPE_SHA512;
06539             }
06540             else {
06541                 WOLFSSL_MSG("Unknown SHA hash");
06542             }
06543         }
06544         else {
06545             hash = WC_HASH_TYPE_SHA;
06546         }
06547     }
06548     else if (XSTRNCMP("MD2", evp, 3) == 0) {
06549         hash = WC_HASH_TYPE_MD2;
06550     }
06551     else if (XSTRNCMP("MD4", evp, 3) == 0) {
06552         hash = WC_HASH_TYPE_MD4;
06553     }
06554     else if (XSTRNCMP("MD5", evp, 3) == 0) {
06555         hash = WC_HASH_TYPE_MD5;
06556     }
06557 
06558     hashSz = wc_HashGetDigestSize(hash);
06559     if (hashSz < 0) {
06560         WOLFSSL_LEAVE("wolfSSL_EVP_Digest", hashSz);
06561         return SSL_FAILURE;
06562     }
06563     *outSz = hashSz;
06564 
06565     (void)eng;
06566     if (wc_Hash(hash, in, inSz, out, *outSz) == 0) {
06567         return SSL_SUCCESS;
06568     }
06569     else {
06570         return SSL_FAILURE;
06571     }
06572 }
06573 
06574 
06575 int wolfSSL_X509_digest(const WOLFSSL_X509* x509, const WOLFSSL_EVP_MD* digest,
06576         unsigned char* buf, unsigned int* len)
06577 {
06578     WOLFSSL_ENTER("wolfSSL_X509_digest");
06579 
06580     if (x509 == NULL || digest == NULL) {
06581         return SSL_FAILURE;
06582     }
06583 
06584     return wolfSSL_EVP_Digest(x509->derCert->buffer, x509->derCert->length, buf,
06585                               len, digest, NULL);
06586 }
06587 
06588 
06589 int wolfSSL_use_PrivateKey(WOLFSSL* ssl, WOLFSSL_EVP_PKEY* pkey)
06590 {
06591     WOLFSSL_ENTER("wolfSSL_use_PrivateKey");
06592     if (ssl == NULL || pkey == NULL ) {
06593         return SSL_FAILURE;
06594     }
06595 
06596     return wolfSSL_use_PrivateKey_buffer(ssl, (unsigned char*)pkey->pkey.ptr,
06597                                          pkey->pkey_sz, SSL_FILETYPE_ASN1);
06598 }
06599 
06600 
06601 int wolfSSL_use_PrivateKey_ASN1(int pri, WOLFSSL* ssl, unsigned char* der,
06602                                 long derSz)
06603 {
06604     WOLFSSL_ENTER("wolfSSL_use_PrivateKey_ASN1");
06605     if (ssl == NULL || der == NULL ) {
06606         return SSL_FAILURE;
06607     }
06608 
06609     (void)pri; /* type of private key */
06610     return wolfSSL_use_PrivateKey_buffer(ssl, der, derSz, SSL_FILETYPE_ASN1);
06611 }
06612 
06613 
06614 #ifndef NO_RSA
06615 int wolfSSL_use_RSAPrivateKey_ASN1(WOLFSSL* ssl, unsigned char* der, long derSz)
06616 {
06617     WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_ASN1");
06618     if (ssl == NULL || der == NULL ) {
06619         return SSL_FAILURE;
06620     }
06621 
06622     return wolfSSL_use_PrivateKey_buffer(ssl, der, derSz, SSL_FILETYPE_ASN1);
06623 }
06624 #endif
06625 
06626 int wolfSSL_use_certificate_ASN1(WOLFSSL* ssl, unsigned char* der, int derSz)
06627 {
06628     long idx;
06629 
06630     WOLFSSL_ENTER("wolfSSL_use_certificate_ASN1");
06631     if (der != NULL && ssl != NULL) {
06632         if (ProcessBuffer(NULL, der, derSz, SSL_FILETYPE_ASN1, CERT_TYPE, ssl,
06633                                                         &idx, 0) == SSL_SUCCESS)
06634             return SSL_SUCCESS;
06635     }
06636 
06637     (void)idx;
06638     return SSL_FAILURE;
06639 }
06640 
06641 
06642 int wolfSSL_use_certificate(WOLFSSL* ssl, WOLFSSL_X509* x509)
06643 {
06644     long idx;
06645 
06646     WOLFSSL_ENTER("wolfSSL_use_certificate");
06647     if (x509 != NULL && ssl != NULL && x509->derCert != NULL) {
06648         if (ProcessBuffer(NULL, x509->derCert->buffer, x509->derCert->length,
06649                      SSL_FILETYPE_ASN1, CERT_TYPE, ssl, &idx, 0) == SSL_SUCCESS)
06650             return SSL_SUCCESS;
06651     }
06652 
06653     (void)idx;
06654     return SSL_FAILURE;
06655 }
06656 #endif /* NO_CERTS */
06657 
06658 
06659 int wolfSSL_use_certificate_file(WOLFSSL* ssl, const char* file, int format)
06660 {
06661     WOLFSSL_ENTER("wolfSSL_use_certificate_file");
06662     if (ProcessFile(ssl->ctx, file, format, CERT_TYPE,
06663                     ssl, 0, NULL) == SSL_SUCCESS)
06664         return SSL_SUCCESS;
06665 
06666     return SSL_FAILURE;
06667 }
06668 
06669 
06670 int wolfSSL_use_PrivateKey_file(WOLFSSL* ssl, const char* file, int format)
06671 {
06672     WOLFSSL_ENTER("wolfSSL_use_PrivateKey_file");
06673     if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE,
06674                     ssl, 0, NULL) == SSL_SUCCESS)
06675         return SSL_SUCCESS;
06676 
06677     return SSL_FAILURE;
06678 }
06679 
06680 
06681 int wolfSSL_use_certificate_chain_file(WOLFSSL* ssl, const char* file)
06682 {
06683    /* process up to MAX_CHAIN_DEPTH plus subject cert */
06684    WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file");
06685    if (ProcessFile(ssl->ctx, file, SSL_FILETYPE_PEM, CERT_TYPE,
06686                    ssl, 1, NULL) == SSL_SUCCESS)
06687        return SSL_SUCCESS;
06688 
06689    return SSL_FAILURE;
06690 }
06691 
06692 
06693 #ifdef HAVE_ECC
06694 
06695 /* Set Temp CTX EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
06696 int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX* ctx, word16 sz)
06697 {
06698     if (ctx == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
06699         return BAD_FUNC_ARG;
06700 
06701     ctx->eccTempKeySz = sz;
06702 
06703     return SSL_SUCCESS;
06704 }
06705 
06706 
06707 /* Set Temp SSL EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
06708 int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL* ssl, word16 sz)
06709 {
06710     if (ssl == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
06711         return BAD_FUNC_ARG;
06712 
06713     ssl->eccTempKeySz = sz;
06714 
06715     return SSL_SUCCESS;
06716 }
06717 
06718 #endif /* HAVE_ECC */
06719 
06720 
06721 
06722 
06723 int wolfSSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX* ctx,const char* file,
06724                                    int format)
06725 {
06726     WOLFSSL_ENTER("SSL_CTX_use_RSAPrivateKey_file");
06727 
06728     return wolfSSL_CTX_use_PrivateKey_file(ctx, file, format);
06729 }
06730 
06731 
06732 int wolfSSL_use_RSAPrivateKey_file(WOLFSSL* ssl, const char* file, int format)
06733 {
06734     WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_file");
06735 
06736     return wolfSSL_use_PrivateKey_file(ssl, file, format);
06737 }
06738 
06739 
06740 /* Copies the master secret over to out buffer. If outSz is 0 returns the size
06741  * of master secret.
06742  *
06743  * ses : a session from completed TLS/SSL handshake
06744  * out : buffer to hold copy of master secret
06745  * outSz : size of out buffer
06746  * returns : number of bytes copied into out buffer on success
06747  *           less then or equal to 0 is considered a failure case
06748  */
06749 int wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION* ses,
06750         unsigned char* out, int outSz)
06751 {
06752     int size;
06753 
06754     if (outSz == 0) {
06755         return SECRET_LEN;
06756     }
06757 
06758     if (ses == NULL || out == NULL || outSz < 0) {
06759         return 0;
06760     }
06761 
06762     if (outSz > SECRET_LEN) {
06763         size = SECRET_LEN;
06764     }
06765     else {
06766         size = outSz;
06767     }
06768 
06769     XMEMCPY(out, ses->masterSecret, size);
06770     return size;
06771 }
06772 
06773 
06774 int wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION* ses)
06775 {
06776     (void)ses;
06777     return SECRET_LEN;
06778 }
06779 
06780 #endif /* OPENSSL_EXTRA */
06781 
06782 #ifdef HAVE_NTRU
06783 
06784 int wolfSSL_CTX_use_NTRUPrivateKey_file(WOLFSSL_CTX* ctx, const char* file)
06785 {
06786     WOLFSSL_ENTER("wolfSSL_CTX_use_NTRUPrivateKey_file");
06787     if (ctx == NULL)
06788         return SSL_FAILURE;
06789 
06790     if (ProcessFile(ctx, file, SSL_FILETYPE_RAW, PRIVATEKEY_TYPE, NULL, 0, NULL)
06791                          == SSL_SUCCESS) {
06792         ctx->haveNTRU = 1;
06793         return SSL_SUCCESS;
06794     }
06795 
06796     return SSL_FAILURE;
06797 }
06798 
06799 #endif /* HAVE_NTRU */
06800 
06801 
06802 #endif /* NO_FILESYSTEM */
06803 
06804 
06805 void wolfSSL_CTX_set_verify(WOLFSSL_CTX* ctx, int mode, VerifyCallback vc)
06806 {
06807     WOLFSSL_ENTER("wolfSSL_CTX_set_verify");
06808     if (mode & SSL_VERIFY_PEER) {
06809         ctx->verifyPeer = 1;
06810         ctx->verifyNone = 0;  /* in case previously set */
06811     }
06812 
06813     if (mode == SSL_VERIFY_NONE) {
06814         ctx->verifyNone = 1;
06815         ctx->verifyPeer = 0;  /* in case previously set */
06816     }
06817 
06818     if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
06819         ctx->failNoCert = 1;
06820 
06821     if (mode & SSL_VERIFY_FAIL_EXCEPT_PSK) {
06822         ctx->failNoCert    = 0; /* fail on all is set to fail on PSK */
06823         ctx->failNoCertxPSK = 1;
06824     }
06825 
06826     ctx->verifyCallback = vc;
06827 }
06828 
06829 
06830 void wolfSSL_set_verify(WOLFSSL* ssl, int mode, VerifyCallback vc)
06831 {
06832     WOLFSSL_ENTER("wolfSSL_set_verify");
06833     if (mode & SSL_VERIFY_PEER) {
06834         ssl->options.verifyPeer = 1;
06835         ssl->options.verifyNone = 0;  /* in case previously set */
06836     }
06837 
06838     if (mode == SSL_VERIFY_NONE) {
06839         ssl->options.verifyNone = 1;
06840         ssl->options.verifyPeer = 0;  /* in case previously set */
06841     }
06842 
06843     if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
06844         ssl->options.failNoCert = 1;
06845 
06846     if (mode & SSL_VERIFY_FAIL_EXCEPT_PSK) {
06847         ssl->options.failNoCert    = 0; /* fail on all is set to fail on PSK */
06848         ssl->options.failNoCertxPSK = 1;
06849     }
06850 
06851     ssl->verifyCallback = vc;
06852 }
06853 
06854 
06855 /* store user ctx for verify callback */
06856 void wolfSSL_SetCertCbCtx(WOLFSSL* ssl, void* ctx)
06857 {
06858     WOLFSSL_ENTER("wolfSSL_SetCertCbCtx");
06859     if (ssl)
06860         ssl->verifyCbCtx = ctx;
06861 }
06862 
06863 
06864 /* store context CA Cache addition callback */
06865 void wolfSSL_CTX_SetCACb(WOLFSSL_CTX* ctx, CallbackCACache cb)
06866 {
06867     if (ctx && ctx->cm)
06868         ctx->cm->caCacheCallback = cb;
06869 }
06870 
06871 
06872 #if defined(PERSIST_CERT_CACHE)
06873 
06874 #if !defined(NO_FILESYSTEM)
06875 
06876 /* Persist cert cache to file */
06877 int wolfSSL_CTX_save_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
06878 {
06879     WOLFSSL_ENTER("wolfSSL_CTX_save_cert_cache");
06880 
06881     if (ctx == NULL || fname == NULL)
06882         return BAD_FUNC_ARG;
06883 
06884     return CM_SaveCertCache(ctx->cm, fname);
06885 }
06886 
06887 
06888 /* Persist cert cache from file */
06889 int wolfSSL_CTX_restore_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
06890 {
06891     WOLFSSL_ENTER("wolfSSL_CTX_restore_cert_cache");
06892 
06893     if (ctx == NULL || fname == NULL)
06894         return BAD_FUNC_ARG;
06895 
06896     return CM_RestoreCertCache(ctx->cm, fname);
06897 }
06898 
06899 #endif /* NO_FILESYSTEM */
06900 
06901 /* Persist cert cache to memory */
06902 int wolfSSL_CTX_memsave_cert_cache(WOLFSSL_CTX* ctx, void* mem,
06903                                    int sz, int* used)
06904 {
06905     WOLFSSL_ENTER("wolfSSL_CTX_memsave_cert_cache");
06906 
06907     if (ctx == NULL || mem == NULL || used == NULL || sz <= 0)
06908         return BAD_FUNC_ARG;
06909 
06910     return CM_MemSaveCertCache(ctx->cm, mem, sz, used);
06911 }
06912 
06913 
06914 /* Restore cert cache from memory */
06915 int wolfSSL_CTX_memrestore_cert_cache(WOLFSSL_CTX* ctx, const void* mem, int sz)
06916 {
06917     WOLFSSL_ENTER("wolfSSL_CTX_memrestore_cert_cache");
06918 
06919     if (ctx == NULL || mem == NULL || sz <= 0)
06920         return BAD_FUNC_ARG;
06921 
06922     return CM_MemRestoreCertCache(ctx->cm, mem, sz);
06923 }
06924 
06925 
06926 /* get how big the the cert cache save buffer needs to be */
06927 int wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX* ctx)
06928 {
06929     WOLFSSL_ENTER("wolfSSL_CTX_get_cert_cache_memsize");
06930 
06931     if (ctx == NULL)
06932         return BAD_FUNC_ARG;
06933 
06934     return CM_GetCertCacheMemSize(ctx->cm);
06935 }
06936 
06937 #endif /* PERSISTE_CERT_CACHE */
06938 #endif /* !NO_CERTS */
06939 
06940 
06941 #ifndef NO_SESSION_CACHE
06942 
06943 WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl)
06944 {
06945     WOLFSSL_ENTER("SSL_get_session");
06946     if (ssl)
06947         return GetSession(ssl, 0, 0);
06948 
06949     return NULL;
06950 }
06951 
06952 
06953 int wolfSSL_set_session(WOLFSSL* ssl, WOLFSSL_SESSION* session)
06954 {
06955     WOLFSSL_ENTER("SSL_set_session");
06956     if (session)
06957         return SetSession(ssl, session);
06958 
06959     return SSL_FAILURE;
06960 }
06961 
06962 
06963 #ifndef NO_CLIENT_CACHE
06964 
06965 /* Associate client session with serverID, find existing or store for saving
06966    if newSession flag on, don't reuse existing session
06967    SSL_SUCCESS on ok */
06968 int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
06969 {
06970     WOLFSSL_SESSION* session = NULL;
06971 
06972     WOLFSSL_ENTER("wolfSSL_SetServerID");
06973 
06974     if (ssl == NULL || id == NULL || len <= 0)
06975         return BAD_FUNC_ARG;
06976 
06977     if (newSession == 0) {
06978         session = GetSessionClient(ssl, id, len);
06979         if (session) {
06980             if (SetSession(ssl, session) != SSL_SUCCESS) {
06981     #ifdef HAVE_EXT_CACHE
06982                 wolfSSL_SESSION_free(session);
06983     #endif
06984                 WOLFSSL_MSG("SetSession failed");
06985                 session = NULL;
06986             }
06987         }
06988     }
06989 
06990     if (session == NULL) {
06991         WOLFSSL_MSG("Valid ServerID not cached already");
06992 
06993         ssl->session.idLen = (word16)min(SERVER_ID_LEN, (word32)len);
06994         XMEMCPY(ssl->session.serverID, id, ssl->session.idLen);
06995     }
06996     #ifdef HAVE_EXT_CACHE
06997     else
06998         wolfSSL_SESSION_free(session);
06999     #endif
07000 
07001     return SSL_SUCCESS;
07002 }
07003 
07004 #endif /* NO_CLIENT_CACHE */
07005 
07006 #if defined(PERSIST_SESSION_CACHE)
07007 
07008 /* for persistence, if changes to layout need to increment and modify
07009    save_session_cache() and restore_session_cache and memory versions too */
07010 #define WOLFSSL_CACHE_VERSION 2
07011 
07012 /* Session Cache Header information */
07013 typedef struct {
07014     int version;     /* cache layout version id */
07015     int rows;        /* session rows */
07016     int columns;     /* session columns */
07017     int sessionSz;   /* sizeof WOLFSSL_SESSION */
07018 } cache_header_t;
07019 
07020 /* current persistence layout is:
07021 
07022    1) cache_header_t
07023    2) SessionCache
07024    3) ClientCache
07025 
07026    update WOLFSSL_CACHE_VERSION if change layout for the following
07027    PERSISTENT_SESSION_CACHE functions
07028 */
07029 
07030 
07031 /* get how big the the session cache save buffer needs to be */
07032 int wolfSSL_get_session_cache_memsize(void)
07033 {
07034     int sz  = (int)(sizeof(SessionCache) + sizeof(cache_header_t));
07035 
07036     #ifndef NO_CLIENT_CACHE
07037         sz += (int)(sizeof(ClientCache));
07038     #endif
07039 
07040     return sz;
07041 }
07042 
07043 
07044 /* Persist session cache to memory */
07045 int wolfSSL_memsave_session_cache(void* mem, int sz)
07046 {
07047     int i;
07048     cache_header_t cache_header;
07049     SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
07050 #ifndef NO_CLIENT_CACHE
07051     ClientRow*     clRow;
07052 #endif
07053 
07054     WOLFSSL_ENTER("wolfSSL_memsave_session_cache");
07055 
07056     if (sz < wolfSSL_get_session_cache_memsize()) {
07057         WOLFSSL_MSG("Memory buffer too small");
07058         return BUFFER_E;
07059     }
07060 
07061     cache_header.version   = WOLFSSL_CACHE_VERSION;
07062     cache_header.rows      = SESSION_ROWS;
07063     cache_header.columns   = SESSIONS_PER_ROW;
07064     cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
07065     XMEMCPY(mem, &cache_header, sizeof(cache_header));
07066 
07067     if (wc_LockMutex(&session_mutex) != 0) {
07068         WOLFSSL_MSG("Session cache mutex lock failed");
07069         return BAD_MUTEX_E;
07070     }
07071 
07072     for (i = 0; i < cache_header.rows; ++i)
07073         XMEMCPY(row++, SessionCache + i, sizeof(SessionRow));
07074 
07075 #ifndef NO_CLIENT_CACHE
07076     clRow = (ClientRow*)row;
07077     for (i = 0; i < cache_header.rows; ++i)
07078         XMEMCPY(clRow++, ClientCache + i, sizeof(ClientRow));
07079 #endif
07080 
07081     wc_UnLockMutex(&session_mutex);
07082 
07083     WOLFSSL_LEAVE("wolfSSL_memsave_session_cache", SSL_SUCCESS);
07084 
07085     return SSL_SUCCESS;
07086 }
07087 
07088 
07089 /* Restore the persistent session cache from memory */
07090 int wolfSSL_memrestore_session_cache(const void* mem, int sz)
07091 {
07092     int    i;
07093     cache_header_t cache_header;
07094     SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
07095 #ifndef NO_CLIENT_CACHE
07096     ClientRow*     clRow;
07097 #endif
07098 
07099     WOLFSSL_ENTER("wolfSSL_memrestore_session_cache");
07100 
07101     if (sz < wolfSSL_get_session_cache_memsize()) {
07102         WOLFSSL_MSG("Memory buffer too small");
07103         return BUFFER_E;
07104     }
07105 
07106     XMEMCPY(&cache_header, mem, sizeof(cache_header));
07107     if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
07108         cache_header.rows      != SESSION_ROWS ||
07109         cache_header.columns   != SESSIONS_PER_ROW ||
07110         cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
07111 
07112         WOLFSSL_MSG("Session cache header match failed");
07113         return CACHE_MATCH_ERROR;
07114     }
07115 
07116     if (wc_LockMutex(&session_mutex) != 0) {
07117         WOLFSSL_MSG("Session cache mutex lock failed");
07118         return BAD_MUTEX_E;
07119     }
07120 
07121     for (i = 0; i < cache_header.rows; ++i)
07122         XMEMCPY(SessionCache + i, row++, sizeof(SessionRow));
07123 
07124 #ifndef NO_CLIENT_CACHE
07125     clRow = (ClientRow*)row;
07126     for (i = 0; i < cache_header.rows; ++i)
07127         XMEMCPY(ClientCache + i, clRow++, sizeof(ClientRow));
07128 #endif
07129 
07130     wc_UnLockMutex(&session_mutex);
07131 
07132     WOLFSSL_LEAVE("wolfSSL_memrestore_session_cache", SSL_SUCCESS);
07133 
07134     return SSL_SUCCESS;
07135 }
07136 
07137 #if !defined(NO_FILESYSTEM)
07138 
07139 /* Persist session cache to file */
07140 /* doesn't use memsave because of additional memory use */
07141 int wolfSSL_save_session_cache(const char *fname)
07142 {
07143     XFILE  file;
07144     int    ret;
07145     int    rc = SSL_SUCCESS;
07146     int    i;
07147     cache_header_t cache_header;
07148 
07149     WOLFSSL_ENTER("wolfSSL_save_session_cache");
07150 
07151     file = XFOPEN(fname, "w+b");
07152     if (file == XBADFILE) {
07153         WOLFSSL_MSG("Couldn't open session cache save file");
07154         return SSL_BAD_FILE;
07155     }
07156     cache_header.version   = WOLFSSL_CACHE_VERSION;
07157     cache_header.rows      = SESSION_ROWS;
07158     cache_header.columns   = SESSIONS_PER_ROW;
07159     cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
07160 
07161     /* cache header */
07162     ret = (int)XFWRITE(&cache_header, sizeof cache_header, 1, file);
07163     if (ret != 1) {
07164         WOLFSSL_MSG("Session cache header file write failed");
07165         XFCLOSE(file);
07166         return FWRITE_ERROR;
07167     }
07168 
07169     if (wc_LockMutex(&session_mutex) != 0) {
07170         WOLFSSL_MSG("Session cache mutex lock failed");
07171         XFCLOSE(file);
07172         return BAD_MUTEX_E;
07173     }
07174 
07175     /* session cache */
07176     for (i = 0; i < cache_header.rows; ++i) {
07177         ret = (int)XFWRITE(SessionCache + i, sizeof(SessionRow), 1, file);
07178         if (ret != 1) {
07179             WOLFSSL_MSG("Session cache member file write failed");
07180             rc = FWRITE_ERROR;
07181             break;
07182         }
07183     }
07184 
07185 #ifndef NO_CLIENT_CACHE
07186     /* client cache */
07187     for (i = 0; i < cache_header.rows; ++i) {
07188         ret = (int)XFWRITE(ClientCache + i, sizeof(ClientRow), 1, file);
07189         if (ret != 1) {
07190             WOLFSSL_MSG("Client cache member file write failed");
07191             rc = FWRITE_ERROR;
07192             break;
07193         }
07194     }
07195 #endif /* NO_CLIENT_CACHE */
07196 
07197     wc_UnLockMutex(&session_mutex);
07198 
07199     XFCLOSE(file);
07200     WOLFSSL_LEAVE("wolfSSL_save_session_cache", rc);
07201 
07202     return rc;
07203 }
07204 
07205 
07206 /* Restore the persistent session cache from file */
07207 /* doesn't use memstore because of additional memory use */
07208 int wolfSSL_restore_session_cache(const char *fname)
07209 {
07210     XFILE  file;
07211     int    rc = SSL_SUCCESS;
07212     int    ret;
07213     int    i;
07214     cache_header_t cache_header;
07215 
07216     WOLFSSL_ENTER("wolfSSL_restore_session_cache");
07217 
07218     file = XFOPEN(fname, "rb");
07219     if (file == XBADFILE) {
07220         WOLFSSL_MSG("Couldn't open session cache save file");
07221         return SSL_BAD_FILE;
07222     }
07223     /* cache header */
07224     ret = (int)XFREAD(&cache_header, sizeof cache_header, 1, file);
07225     if (ret != 1) {
07226         WOLFSSL_MSG("Session cache header file read failed");
07227         XFCLOSE(file);
07228         return FREAD_ERROR;
07229     }
07230     if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
07231         cache_header.rows      != SESSION_ROWS ||
07232         cache_header.columns   != SESSIONS_PER_ROW ||
07233         cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
07234 
07235         WOLFSSL_MSG("Session cache header match failed");
07236         XFCLOSE(file);
07237         return CACHE_MATCH_ERROR;
07238     }
07239 
07240     if (wc_LockMutex(&session_mutex) != 0) {
07241         WOLFSSL_MSG("Session cache mutex lock failed");
07242         XFCLOSE(file);
07243         return BAD_MUTEX_E;
07244     }
07245 
07246     /* session cache */
07247     for (i = 0; i < cache_header.rows; ++i) {
07248         ret = (int)XFREAD(SessionCache + i, sizeof(SessionRow), 1, file);
07249         if (ret != 1) {
07250             WOLFSSL_MSG("Session cache member file read failed");
07251             XMEMSET(SessionCache, 0, sizeof SessionCache);
07252             rc = FREAD_ERROR;
07253             break;
07254         }
07255     }
07256 
07257 #ifndef NO_CLIENT_CACHE
07258     /* client cache */
07259     for (i = 0; i < cache_header.rows; ++i) {
07260         ret = (int)XFREAD(ClientCache + i, sizeof(ClientRow), 1, file);
07261         if (ret != 1) {
07262             WOLFSSL_MSG("Client cache member file read failed");
07263             XMEMSET(ClientCache, 0, sizeof ClientCache);
07264             rc = FREAD_ERROR;
07265             break;
07266         }
07267     }
07268 
07269 #endif /* NO_CLIENT_CACHE */
07270 
07271     wc_UnLockMutex(&session_mutex);
07272 
07273     XFCLOSE(file);
07274     WOLFSSL_LEAVE("wolfSSL_restore_session_cache", rc);
07275 
07276     return rc;
07277 }
07278 
07279 #endif /* !NO_FILESYSTEM */
07280 #endif /* PERSIST_SESSION_CACHE */
07281 #endif /* NO_SESSION_CACHE */
07282 
07283 
07284 void wolfSSL_load_error_strings(void)   /* compatibility only */
07285 {}
07286 
07287 
07288 int wolfSSL_library_init(void)
07289 {
07290     WOLFSSL_ENTER("SSL_library_init");
07291     if (wolfSSL_Init() == SSL_SUCCESS)
07292         return SSL_SUCCESS;
07293     else
07294         return SSL_FATAL_ERROR;
07295 }
07296 
07297 
07298 #ifdef HAVE_SECRET_CALLBACK
07299 
07300 int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx)
07301 {
07302     WOLFSSL_ENTER("wolfSSL_set_session_secret_cb");
07303     if (ssl == NULL)
07304         return SSL_FATAL_ERROR;
07305 
07306     ssl->sessionSecretCb = cb;
07307     ssl->sessionSecretCtx = ctx;
07308     /* If using a pre-set key, assume session resumption. */
07309     ssl->session.sessionIDSz = 0;
07310     ssl->options.resuming = 1;
07311 
07312     return SSL_SUCCESS;
07313 }
07314 
07315 #endif
07316 
07317 
07318 #ifndef NO_SESSION_CACHE
07319 
07320 /* on by default if built in but allow user to turn off */
07321 long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX* ctx, long mode)
07322 {
07323     WOLFSSL_ENTER("SSL_CTX_set_session_cache_mode");
07324     if (mode == SSL_SESS_CACHE_OFF)
07325         ctx->sessionCacheOff = 1;
07326 
07327     if ((mode & SSL_SESS_CACHE_NO_AUTO_CLEAR) != 0)
07328         ctx->sessionCacheFlushOff = 1;
07329 
07330 #ifdef HAVE_EXT_CACHE
07331     if ((mode & SSL_SESS_CACHE_NO_INTERNAL_STORE) != 0)
07332         ctx->internalCacheOff = 1;
07333 #endif
07334 
07335     return SSL_SUCCESS;
07336 }
07337 
07338 #endif /* NO_SESSION_CACHE */
07339 
07340 
07341 #if !defined(NO_CERTS)
07342 #if defined(PERSIST_CERT_CACHE)
07343 
07344 
07345 #define WOLFSSL_CACHE_CERT_VERSION 1
07346 
07347 typedef struct {
07348     int version;                 /* cache cert layout version id */
07349     int rows;                    /* hash table rows, CA_TABLE_SIZE */
07350     int columns[CA_TABLE_SIZE];  /* columns per row on list */
07351     int signerSz;                /* sizeof Signer object */
07352 } CertCacheHeader;
07353 
07354 /* current cert persistence layout is:
07355 
07356    1) CertCacheHeader
07357    2) caTable
07358 
07359    update WOLFSSL_CERT_CACHE_VERSION if change layout for the following
07360    PERSIST_CERT_CACHE functions
07361 */
07362 
07363 
07364 /* Return memory needed to persist this signer, have lock */
07365 static INLINE int GetSignerMemory(Signer* signer)
07366 {
07367     int sz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID)
07368            + sizeof(signer->nameLen)    + sizeof(signer->subjectNameHash);
07369 
07370 #if !defined(NO_SKID)
07371         sz += (int)sizeof(signer->subjectKeyIdHash);
07372 #endif
07373 
07374     /* add dynamic bytes needed */
07375     sz += signer->pubKeySize;
07376     sz += signer->nameLen;
07377 
07378     return sz;
07379 }
07380 
07381 
07382 /* Return memory needed to persist this row, have lock */
07383 static INLINE int GetCertCacheRowMemory(Signer* row)
07384 {
07385     int sz = 0;
07386 
07387     while (row) {
07388         sz += GetSignerMemory(row);
07389         row = row->next;
07390     }
07391 
07392     return sz;
07393 }
07394 
07395 
07396 /* get the size of persist cert cache, have lock */
07397 static INLINE int GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
07398 {
07399     int sz;
07400     int i;
07401 
07402     sz = sizeof(CertCacheHeader);
07403 
07404     for (i = 0; i < CA_TABLE_SIZE; i++)
07405         sz += GetCertCacheRowMemory(cm->caTable[i]);
07406 
07407     return sz;
07408 }
07409 
07410 
07411 /* Store cert cache header columns with number of items per list, have lock */
07412 static INLINE void SetCertHeaderColumns(WOLFSSL_CERT_MANAGER* cm, int* columns)
07413 {
07414     int     i;
07415     Signer* row;
07416 
07417     for (i = 0; i < CA_TABLE_SIZE; i++) {
07418         int count = 0;
07419         row = cm->caTable[i];
07420 
07421         while (row) {
07422             ++count;
07423             row = row->next;
07424         }
07425         columns[i] = count;
07426     }
07427 }
07428 
07429 
07430 /* Restore whole cert row from memory, have lock, return bytes consumed,
07431    < 0 on error, have lock */
07432 static INLINE int RestoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current,
07433                                  int row, int listSz, const byte* end)
07434 {
07435     int idx = 0;
07436 
07437     if (listSz < 0) {
07438         WOLFSSL_MSG("Row header corrupted, negative value");
07439         return PARSE_ERROR;
07440     }
07441 
07442     while (listSz) {
07443         Signer* signer;
07444         byte*   start = current + idx;  /* for end checks on this signer */
07445         int     minSz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) +
07446                       sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
07447         #ifndef NO_SKID
07448                 minSz += (int)sizeof(signer->subjectKeyIdHash);
07449         #endif
07450 
07451         if (start + minSz > end) {
07452             WOLFSSL_MSG("Would overread restore buffer");
07453             return BUFFER_E;
07454         }
07455         signer = MakeSigner(cm->heap);
07456         if (signer == NULL)
07457             return MEMORY_E;
07458 
07459         /* pubKeySize */
07460         XMEMCPY(&signer->pubKeySize, current + idx, sizeof(signer->pubKeySize));
07461         idx += (int)sizeof(signer->pubKeySize);
07462 
07463         /* keyOID */
07464         XMEMCPY(&signer->keyOID, current + idx, sizeof(signer->keyOID));
07465         idx += (int)sizeof(signer->keyOID);
07466 
07467         /* pulicKey */
07468         if (start + minSz + signer->pubKeySize > end) {
07469             WOLFSSL_MSG("Would overread restore buffer");
07470             FreeSigner(signer, cm->heap);
07471             return BUFFER_E;
07472         }
07473         signer->publicKey = (byte*)XMALLOC(signer->pubKeySize, cm->heap,
07474                                            DYNAMIC_TYPE_KEY);
07475         if (signer->publicKey == NULL) {
07476             FreeSigner(signer, cm->heap);
07477             return MEMORY_E;
07478         }
07479 
07480         XMEMCPY(signer->publicKey, current + idx, signer->pubKeySize);
07481         idx += signer->pubKeySize;
07482 
07483         /* nameLen */
07484         XMEMCPY(&signer->nameLen, current + idx, sizeof(signer->nameLen));
07485         idx += (int)sizeof(signer->nameLen);
07486 
07487         /* name */
07488         if (start + minSz + signer->pubKeySize + signer->nameLen > end) {
07489             WOLFSSL_MSG("Would overread restore buffer");
07490             FreeSigner(signer, cm->heap);
07491             return BUFFER_E;
07492         }
07493         signer->name = (char*)XMALLOC(signer->nameLen, cm->heap,
07494                                       DYNAMIC_TYPE_SUBJECT_CN);
07495         if (signer->name == NULL) {
07496             FreeSigner(signer, cm->heap);
07497             return MEMORY_E;
07498         }
07499 
07500         XMEMCPY(signer->name, current + idx, signer->nameLen);
07501         idx += signer->nameLen;
07502 
07503         /* subjectNameHash */
07504         XMEMCPY(signer->subjectNameHash, current + idx, SIGNER_DIGEST_SIZE);
07505         idx += SIGNER_DIGEST_SIZE;
07506 
07507         #ifndef NO_SKID
07508             /* subjectKeyIdHash */
07509             XMEMCPY(signer->subjectKeyIdHash, current + idx,SIGNER_DIGEST_SIZE);
07510             idx += SIGNER_DIGEST_SIZE;
07511         #endif
07512 
07513         signer->next = cm->caTable[row];
07514         cm->caTable[row] = signer;
07515 
07516         --listSz;
07517     }
07518 
07519     return idx;
07520 }
07521 
07522 
07523 /* Store whole cert row into memory, have lock, return bytes added */
07524 static INLINE int StoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current, int row)
07525 {
07526     int     added  = 0;
07527     Signer* list   = cm->caTable[row];
07528 
07529     while (list) {
07530         XMEMCPY(current + added, &list->pubKeySize, sizeof(list->pubKeySize));
07531         added += (int)sizeof(list->pubKeySize);
07532 
07533         XMEMCPY(current + added, &list->keyOID,     sizeof(list->keyOID));
07534         added += (int)sizeof(list->keyOID);
07535 
07536         XMEMCPY(current + added, list->publicKey, list->pubKeySize);
07537         added += list->pubKeySize;
07538 
07539         XMEMCPY(current + added, &list->nameLen, sizeof(list->nameLen));
07540         added += (int)sizeof(list->nameLen);
07541 
07542         XMEMCPY(current + added, list->name, list->nameLen);
07543         added += list->nameLen;
07544 
07545         XMEMCPY(current + added, list->subjectNameHash, SIGNER_DIGEST_SIZE);
07546         added += SIGNER_DIGEST_SIZE;
07547 
07548         #ifndef NO_SKID
07549             XMEMCPY(current + added, list->subjectKeyIdHash,SIGNER_DIGEST_SIZE);
07550             added += SIGNER_DIGEST_SIZE;
07551         #endif
07552 
07553         list = list->next;
07554     }
07555 
07556     return added;
07557 }
07558 
07559 
07560 /* Persist cert cache to memory, have lock */
07561 static INLINE int DoMemSaveCertCache(WOLFSSL_CERT_MANAGER* cm,
07562                                      void* mem, int sz)
07563 {
07564     int realSz;
07565     int ret = SSL_SUCCESS;
07566     int i;
07567 
07568     WOLFSSL_ENTER("DoMemSaveCertCache");
07569 
07570     realSz = GetCertCacheMemSize(cm);
07571     if (realSz > sz) {
07572         WOLFSSL_MSG("Mem output buffer too small");
07573         ret = BUFFER_E;
07574     }
07575     else {
07576         byte*           current;
07577         CertCacheHeader hdr;
07578 
07579         hdr.version  = WOLFSSL_CACHE_CERT_VERSION;
07580         hdr.rows     = CA_TABLE_SIZE;
07581         SetCertHeaderColumns(cm, hdr.columns);
07582         hdr.signerSz = (int)sizeof(Signer);
07583 
07584         XMEMCPY(mem, &hdr, sizeof(CertCacheHeader));
07585         current = (byte*)mem + sizeof(CertCacheHeader);
07586 
07587         for (i = 0; i < CA_TABLE_SIZE; ++i)
07588             current += StoreCertRow(cm, current, i);
07589     }
07590 
07591     return ret;
07592 }
07593 
07594 
07595 #if !defined(NO_FILESYSTEM)
07596 
07597 /* Persist cert cache to file */
07598 int CM_SaveCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
07599 {
07600     XFILE file;
07601     int   rc = SSL_SUCCESS;
07602     int   memSz;
07603     byte* mem;
07604 
07605     WOLFSSL_ENTER("CM_SaveCertCache");
07606 
07607     file = XFOPEN(fname, "w+b");
07608     if (file == XBADFILE) {
07609        WOLFSSL_MSG("Couldn't open cert cache save file");
07610        return SSL_BAD_FILE;
07611     }
07612 
07613     if (wc_LockMutex(&cm->caLock) != 0) {
07614         WOLFSSL_MSG("wc_LockMutex on caLock failed");
07615         XFCLOSE(file);
07616         return BAD_MUTEX_E;
07617     }
07618 
07619     memSz = GetCertCacheMemSize(cm);
07620     mem   = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
07621     if (mem == NULL) {
07622         WOLFSSL_MSG("Alloc for tmp buffer failed");
07623         rc = MEMORY_E;
07624     } else {
07625         rc = DoMemSaveCertCache(cm, mem, memSz);
07626         if (rc == SSL_SUCCESS) {
07627             int ret = (int)XFWRITE(mem, memSz, 1, file);
07628             if (ret != 1) {
07629                 WOLFSSL_MSG("Cert cache file write failed");
07630                 rc = FWRITE_ERROR;
07631             }
07632         }
07633         XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
07634     }
07635 
07636     wc_UnLockMutex(&cm->caLock);
07637     XFCLOSE(file);
07638 
07639     return rc;
07640 }
07641 
07642 
07643 /* Restore cert cache from file */
07644 int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
07645 {
07646     XFILE file;
07647     int   rc = SSL_SUCCESS;
07648     int   ret;
07649     int   memSz;
07650     byte* mem;
07651 
07652     WOLFSSL_ENTER("CM_RestoreCertCache");
07653 
07654     file = XFOPEN(fname, "rb");
07655     if (file == XBADFILE) {
07656        WOLFSSL_MSG("Couldn't open cert cache save file");
07657        return SSL_BAD_FILE;
07658     }
07659 
07660     XFSEEK(file, 0, XSEEK_END);
07661     memSz = (int)XFTELL(file);
07662     XREWIND(file);
07663 
07664     if (memSz <= 0) {
07665         WOLFSSL_MSG("Bad file size");
07666         XFCLOSE(file);
07667         return SSL_BAD_FILE;
07668     }
07669 
07670     mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
07671     if (mem == NULL) {
07672         WOLFSSL_MSG("Alloc for tmp buffer failed");
07673         XFCLOSE(file);
07674         return MEMORY_E;
07675     }
07676 
07677     ret = (int)XFREAD(mem, memSz, 1, file);
07678     if (ret != 1) {
07679         WOLFSSL_MSG("Cert file read error");
07680         rc = FREAD_ERROR;
07681     } else {
07682         rc = CM_MemRestoreCertCache(cm, mem, memSz);
07683         if (rc != SSL_SUCCESS) {
07684             WOLFSSL_MSG("Mem restore cert cache failed");
07685         }
07686     }
07687 
07688     XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
07689     XFCLOSE(file);
07690 
07691     return rc;
07692 }
07693 
07694 #endif /* NO_FILESYSTEM */
07695 
07696 
07697 /* Persist cert cache to memory */
07698 int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, void* mem, int sz, int* used)
07699 {
07700     int ret = SSL_SUCCESS;
07701 
07702     WOLFSSL_ENTER("CM_MemSaveCertCache");
07703 
07704     if (wc_LockMutex(&cm->caLock) != 0) {
07705         WOLFSSL_MSG("wc_LockMutex on caLock failed");
07706         return BAD_MUTEX_E;
07707     }
07708 
07709     ret = DoMemSaveCertCache(cm, mem, sz);
07710     if (ret == SSL_SUCCESS)
07711         *used  = GetCertCacheMemSize(cm);
07712 
07713     wc_UnLockMutex(&cm->caLock);
07714 
07715     return ret;
07716 }
07717 
07718 
07719 /* Restore cert cache from memory */
07720 int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const void* mem, int sz)
07721 {
07722     int ret = SSL_SUCCESS;
07723     int i;
07724     CertCacheHeader* hdr = (CertCacheHeader*)mem;
07725     byte*            current = (byte*)mem + sizeof(CertCacheHeader);
07726     byte*            end     = (byte*)mem + sz;  /* don't go over */
07727 
07728     WOLFSSL_ENTER("CM_MemRestoreCertCache");
07729 
07730     if (current > end) {
07731         WOLFSSL_MSG("Cert Cache Memory buffer too small");
07732         return BUFFER_E;
07733     }
07734 
07735     if (hdr->version  != WOLFSSL_CACHE_CERT_VERSION ||
07736         hdr->rows     != CA_TABLE_SIZE ||
07737         hdr->signerSz != (int)sizeof(Signer)) {
07738 
07739         WOLFSSL_MSG("Cert Cache Memory header mismatch");
07740         return CACHE_MATCH_ERROR;
07741     }
07742 
07743     if (wc_LockMutex(&cm->caLock) != 0) {
07744         WOLFSSL_MSG("wc_LockMutex on caLock failed");
07745         return BAD_MUTEX_E;
07746     }
07747 
07748     FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
07749 
07750     for (i = 0; i < CA_TABLE_SIZE; ++i) {
07751         int added = RestoreCertRow(cm, current, i, hdr->columns[i], end);
07752         if (added < 0) {
07753             WOLFSSL_MSG("RestoreCertRow error");
07754             ret = added;
07755             break;
07756         }
07757         current += added;
07758     }
07759 
07760     wc_UnLockMutex(&cm->caLock);
07761 
07762     return ret;
07763 }
07764 
07765 
07766 /* get how big the the cert cache save buffer needs to be */
07767 int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
07768 {
07769     int sz;
07770 
07771     WOLFSSL_ENTER("CM_GetCertCacheMemSize");
07772 
07773     if (wc_LockMutex(&cm->caLock) != 0) {
07774         WOLFSSL_MSG("wc_LockMutex on caLock failed");
07775         return BAD_MUTEX_E;
07776     }
07777 
07778     sz = GetCertCacheMemSize(cm);
07779 
07780     wc_UnLockMutex(&cm->caLock);
07781 
07782     return sz;
07783 }
07784 
07785 #endif /* PERSIST_CERT_CACHE */
07786 #endif /* NO_CERTS */
07787 
07788 
07789 int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX* ctx, const char* list)
07790 {
07791     WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list");
07792 
07793     /* alloc/init on demand only */
07794     if (ctx->suites == NULL) {
07795         ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap,
07796                                        DYNAMIC_TYPE_SUITES);
07797         if (ctx->suites == NULL) {
07798             WOLFSSL_MSG("Memory alloc for Suites failed");
07799             return SSL_FAILURE;
07800         }
07801         XMEMSET(ctx->suites, 0, sizeof(Suites));
07802     }
07803 
07804     return (SetCipherList(ctx, ctx->suites, list)) ? SSL_SUCCESS : SSL_FAILURE;
07805 }
07806 
07807 
07808 int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list)
07809 {
07810     WOLFSSL_ENTER("wolfSSL_set_cipher_list");
07811     return (SetCipherList(ssl->ctx, ssl->suites, list)) ? SSL_SUCCESS : SSL_FAILURE;
07812 }
07813 
07814 
07815 #ifndef WOLFSSL_LEANPSK
07816 #ifdef WOLFSSL_DTLS
07817 
07818 int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl)
07819 {
07820     (void)ssl;
07821 
07822     return ssl->dtls_timeout;
07823 }
07824 
07825 
07826 /* user may need to alter init dtls recv timeout, SSL_SUCCESS on ok */
07827 int wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int timeout)
07828 {
07829     if (ssl == NULL || timeout < 0)
07830         return BAD_FUNC_ARG;
07831 
07832     if (timeout > ssl->dtls_timeout_max) {
07833         WOLFSSL_MSG("Can't set dtls timeout init greater than dtls timeout max");
07834         return BAD_FUNC_ARG;
07835     }
07836 
07837     ssl->dtls_timeout_init = timeout;
07838     ssl->dtls_timeout = timeout;
07839 
07840     return SSL_SUCCESS;
07841 }
07842 
07843 
07844 /* user may need to alter max dtls recv timeout, SSL_SUCCESS on ok */
07845 int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int timeout)
07846 {
07847     if (ssl == NULL || timeout < 0)
07848         return BAD_FUNC_ARG;
07849 
07850     if (timeout < ssl->dtls_timeout_init) {
07851         WOLFSSL_MSG("Can't set dtls timeout max less than dtls timeout init");
07852         return BAD_FUNC_ARG;
07853     }
07854 
07855     ssl->dtls_timeout_max = timeout;
07856 
07857     return SSL_SUCCESS;
07858 }
07859 
07860 
07861 int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
07862 {
07863     int result = SSL_SUCCESS;
07864 
07865     if (!ssl->options.handShakeDone &&
07866         (DtlsMsgPoolTimeout(ssl) < 0 || DtlsMsgPoolSend(ssl, 0) < 0)) {
07867 
07868         result = SSL_FATAL_ERROR;
07869     }
07870     return result;
07871 }
07872 
07873 #endif /* DTLS */
07874 #endif /* LEANPSK */
07875 
07876 
07877 #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
07878 
07879 /* Not an SSL function, return 0 for success, error code otherwise */
07880 /* Prereq: ssl's RNG needs to be initialized. */
07881 int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
07882                                  const byte* secret, word32 secretSz)
07883 {
07884     int ret = 0;
07885 
07886     WOLFSSL_ENTER("wolfSSL_DTLS_SetCookieSecret");
07887 
07888     if (ssl == NULL) {
07889         WOLFSSL_MSG("need a SSL object");
07890         return BAD_FUNC_ARG;
07891     }
07892 
07893     if (secret != NULL && secretSz == 0) {
07894         WOLFSSL_MSG("can't have a new secret without a size");
07895         return BAD_FUNC_ARG;
07896     }
07897 
07898     /* If secretSz is 0, use the default size. */
07899     if (secretSz == 0)
07900         secretSz = COOKIE_SECRET_SZ;
07901 
07902     if (secretSz != ssl->buffers.dtlsCookieSecret.length) {
07903         byte* newSecret;
07904 
07905         if (ssl->buffers.dtlsCookieSecret.buffer != NULL) {
07906             ForceZero(ssl->buffers.dtlsCookieSecret.buffer,
07907                       ssl->buffers.dtlsCookieSecret.length);
07908             XFREE(ssl->buffers.dtlsCookieSecret.buffer,
07909                   ssl->heap, DYNAMIC_TYPE_NONE);
07910         }
07911 
07912         newSecret = (byte*)XMALLOC(secretSz, ssl->heap,DYNAMIC_TYPE_COOKIE_PWD);
07913         if (newSecret == NULL) {
07914             ssl->buffers.dtlsCookieSecret.buffer = NULL;
07915             ssl->buffers.dtlsCookieSecret.length = 0;
07916             WOLFSSL_MSG("couldn't allocate new cookie secret");
07917             return MEMORY_ERROR;
07918         }
07919         ssl->buffers.dtlsCookieSecret.buffer = newSecret;
07920         ssl->buffers.dtlsCookieSecret.length = secretSz;
07921     }
07922 
07923     /* If the supplied secret is NULL, randomly generate a new secret. */
07924     if (secret == NULL) {
07925         ret = wc_RNG_GenerateBlock(ssl->rng,
07926                              ssl->buffers.dtlsCookieSecret.buffer, secretSz);
07927     }
07928     else
07929         XMEMCPY(ssl->buffers.dtlsCookieSecret.buffer, secret, secretSz);
07930 
07931     WOLFSSL_LEAVE("wolfSSL_DTLS_SetCookieSecret", 0);
07932     return ret;
07933 }
07934 
07935 #endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
07936 
07937 #ifdef OPENSSL_EXTRA
07938     WOLFSSL_METHOD* wolfSSLv23_method(void) {
07939         WOLFSSL_METHOD* m;
07940         WOLFSSL_ENTER("wolfSSLv23_method");
07941 #ifndef NO_WOLFSSL_CLIENT
07942         m = wolfSSLv23_client_method();
07943 #else
07944         m = wolfSSLv23_server_method();
07945 #endif
07946         if (m != NULL) {
07947             m->side = WOLFSSL_NEITHER_END;
07948         }
07949 
07950         return m;
07951     }
07952 #endif /* OPENSSL_EXTRA */
07953 
07954 /* client only parts */
07955 #ifndef NO_WOLFSSL_CLIENT
07956 
07957     #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
07958     WOLFSSL_METHOD* wolfSSLv3_client_method(void)
07959     {
07960         WOLFSSL_ENTER("SSLv3_client_method");
07961         return wolfSSLv3_client_method_ex(NULL);
07962     }
07963     #endif
07964 
07965     #ifdef WOLFSSL_DTLS
07966 
07967         #ifndef NO_OLD_TLS
07968         WOLFSSL_METHOD* wolfDTLSv1_client_method(void)
07969         {
07970             WOLFSSL_ENTER("DTLSv1_client_method");
07971             return wolfDTLSv1_client_method_ex(NULL);
07972         }
07973         #endif  /* NO_OLD_TLS */
07974 
07975         WOLFSSL_METHOD* wolfDTLSv1_2_client_method(void)
07976         {
07977             WOLFSSL_ENTER("DTLSv1_2_client_method");
07978             return wolfDTLSv1_2_client_method_ex(NULL);
07979         }
07980     #endif
07981 
07982     #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
07983     WOLFSSL_METHOD* wolfSSLv3_client_method_ex(void* heap)
07984     {
07985         WOLFSSL_METHOD* method =
07986                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
07987                                                      heap, DYNAMIC_TYPE_METHOD);
07988         WOLFSSL_ENTER("SSLv3_client_method_ex");
07989         if (method)
07990             InitSSL_Method(method, MakeSSLv3());
07991         return method;
07992     }
07993     #endif
07994 
07995     #ifdef WOLFSSL_DTLS
07996 
07997         #ifndef NO_OLD_TLS
07998         WOLFSSL_METHOD* wolfDTLSv1_client_method_ex(void* heap)
07999         {
08000             WOLFSSL_METHOD* method =
08001                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
08002                                                      heap, DYNAMIC_TYPE_METHOD);
08003             WOLFSSL_ENTER("DTLSv1_client_method_ex");
08004             if (method)
08005                 InitSSL_Method(method, MakeDTLSv1());
08006             return method;
08007         }
08008         #endif  /* NO_OLD_TLS */
08009 
08010         WOLFSSL_METHOD* wolfDTLSv1_2_client_method_ex(void* heap)
08011         {
08012             WOLFSSL_METHOD* method =
08013                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
08014                                                      heap, DYNAMIC_TYPE_METHOD);
08015             WOLFSSL_ENTER("DTLSv1_2_client_method_ex");
08016             if (method)
08017                 InitSSL_Method(method, MakeDTLSv1_2());
08018             (void)heap;
08019             return method;
08020         }
08021     #endif
08022 
08023     /* If SCTP is not enabled returns the state of the dtls option.
08024      * If SCTP is enabled returns dtls && !sctp. */
08025     static INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl)
08026     {
08027         int result = ssl->options.dtls;
08028 
08029         if (result) {
08030         #ifdef WOLFSSL_SCTP
08031             result = !ssl->options.dtlsSctp;
08032         #endif
08033         }
08034 
08035         return result;
08036     }
08037 
08038 
08039     /* please see note at top of README if you get an error from connect */
08040     int wolfSSL_connect(WOLFSSL* ssl)
08041     {
08042         int neededState;
08043 
08044         WOLFSSL_ENTER("SSL_connect()");
08045 
08046         #ifdef HAVE_ERRNO_H
08047             errno = 0;
08048         #endif
08049 
08050         if (ssl == NULL)
08051             return BAD_FUNC_ARG;
08052 
08053         if (ssl->options.side != WOLFSSL_CLIENT_END) {
08054             WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
08055             return SSL_FATAL_ERROR;
08056         }
08057 
08058         #ifdef WOLFSSL_DTLS
08059             if (ssl->version.major == DTLS_MAJOR) {
08060                 ssl->options.dtls   = 1;
08061                 ssl->options.tls    = 1;
08062                 ssl->options.tls1_1 = 1;
08063             }
08064         #endif
08065 
08066         if (ssl->buffers.outputBuffer.length > 0) {
08067             if ( (ssl->error = SendBuffered(ssl)) == 0) {
08068                 /* fragOffset is non-zero when sending fragments. On the last
08069                  * fragment, fragOffset is zero again, and the state can be
08070                  * advanced. */
08071                 if (ssl->fragOffset == 0) {
08072                     ssl->options.connectState++;
08073                     WOLFSSL_MSG("connect state: "
08074                                 "Advanced from last buffered fragment send");
08075                 }
08076                 else {
08077                     WOLFSSL_MSG("connect state: "
08078                                 "Not advanced, more fragments to send");
08079                 }
08080             }
08081             else {
08082                 WOLFSSL_ERROR(ssl->error);
08083                 return SSL_FATAL_ERROR;
08084             }
08085         }
08086 
08087         switch (ssl->options.connectState) {
08088 
08089         case CONNECT_BEGIN :
08090             /* always send client hello first */
08091             if ( (ssl->error = SendClientHello(ssl)) != 0) {
08092                 WOLFSSL_ERROR(ssl->error);
08093                 return SSL_FATAL_ERROR;
08094             }
08095             ssl->options.connectState = CLIENT_HELLO_SENT;
08096             WOLFSSL_MSG("connect state: CLIENT_HELLO_SENT");
08097 
08098         case CLIENT_HELLO_SENT :
08099             neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
08100                                           SERVER_HELLODONE_COMPLETE;
08101             #ifdef WOLFSSL_DTLS
08102                 /* In DTLS, when resuming, we can go straight to FINISHED,
08103                  * or do a cookie exchange and then skip to FINISHED, assume
08104                  * we need the cookie exchange first. */
08105                 if (IsDtlsNotSctpMode(ssl))
08106                     neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
08107             #endif
08108             /* get response */
08109             while (ssl->options.serverState < neededState) {
08110                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
08111                     WOLFSSL_ERROR(ssl->error);
08112                     return SSL_FATAL_ERROR;
08113                 }
08114                 /* if resumption failed, reset needed state */
08115                 else if (neededState == SERVER_FINISHED_COMPLETE)
08116                     if (!ssl->options.resuming) {
08117                         if (!IsDtlsNotSctpMode(ssl))
08118                             neededState = SERVER_HELLODONE_COMPLETE;
08119                         else
08120                             neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
08121                     }
08122             }
08123 
08124             ssl->options.connectState = HELLO_AGAIN;
08125             WOLFSSL_MSG("connect state: HELLO_AGAIN");
08126 
08127         case HELLO_AGAIN :
08128             if (ssl->options.certOnly)
08129                 return SSL_SUCCESS;
08130 
08131 #ifdef WOLFSSL_TLS13
08132             if (ssl->options.tls1_3)
08133                 return wolfSSL_connect_TLSv13(ssl);
08134 #endif
08135 
08136             #ifdef WOLFSSL_DTLS
08137                 if (IsDtlsNotSctpMode(ssl)) {
08138                     /* re-init hashes, exclude first hello and verify request */
08139                     if ((ssl->error = InitHandshakeHashes(ssl)) != 0) {
08140                         WOLFSSL_ERROR(ssl->error);
08141                         return SSL_FATAL_ERROR;
08142                     }
08143                     if ( (ssl->error = SendClientHello(ssl)) != 0) {
08144                         WOLFSSL_ERROR(ssl->error);
08145                         return SSL_FATAL_ERROR;
08146                     }
08147                 }
08148             #endif
08149 
08150             ssl->options.connectState = HELLO_AGAIN_REPLY;
08151             WOLFSSL_MSG("connect state: HELLO_AGAIN_REPLY");
08152 
08153         case HELLO_AGAIN_REPLY :
08154             #ifdef WOLFSSL_DTLS
08155                 if (IsDtlsNotSctpMode(ssl)) {
08156                     neededState = ssl->options.resuming ?
08157                            SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
08158 
08159                     /* get response */
08160                     while (ssl->options.serverState < neededState) {
08161                         if ( (ssl->error = ProcessReply(ssl)) < 0) {
08162                                 WOLFSSL_ERROR(ssl->error);
08163                                 return SSL_FATAL_ERROR;
08164                         }
08165                         /* if resumption failed, reset needed state */
08166                         else if (neededState == SERVER_FINISHED_COMPLETE)
08167                             if (!ssl->options.resuming)
08168                                 neededState = SERVER_HELLODONE_COMPLETE;
08169                     }
08170                 }
08171             #endif
08172 
08173             ssl->options.connectState = FIRST_REPLY_DONE;
08174             WOLFSSL_MSG("connect state: FIRST_REPLY_DONE");
08175 
08176         case FIRST_REPLY_DONE :
08177             #ifndef NO_CERTS
08178                 if (ssl->options.sendVerify) {
08179                     if ( (ssl->error = SendCertificate(ssl)) != 0) {
08180                         WOLFSSL_ERROR(ssl->error);
08181                         return SSL_FATAL_ERROR;
08182                     }
08183                     WOLFSSL_MSG("sent: certificate");
08184                 }
08185 
08186             #endif
08187             ssl->options.connectState = FIRST_REPLY_FIRST;
08188             WOLFSSL_MSG("connect state: FIRST_REPLY_FIRST");
08189 
08190         case FIRST_REPLY_FIRST :
08191             if (!ssl->options.resuming) {
08192                 if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
08193                     WOLFSSL_ERROR(ssl->error);
08194                     return SSL_FATAL_ERROR;
08195                 }
08196                 WOLFSSL_MSG("sent: client key exchange");
08197             }
08198 
08199             ssl->options.connectState = FIRST_REPLY_SECOND;
08200             WOLFSSL_MSG("connect state: FIRST_REPLY_SECOND");
08201 
08202         case FIRST_REPLY_SECOND :
08203             #ifndef NO_CERTS
08204                 if (ssl->options.sendVerify) {
08205                     if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
08206                         WOLFSSL_ERROR(ssl->error);
08207                         return SSL_FATAL_ERROR;
08208                     }
08209                     WOLFSSL_MSG("sent: certificate verify");
08210                 }
08211             #endif
08212             ssl->options.connectState = FIRST_REPLY_THIRD;
08213             WOLFSSL_MSG("connect state: FIRST_REPLY_THIRD");
08214 
08215         case FIRST_REPLY_THIRD :
08216             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
08217                 WOLFSSL_ERROR(ssl->error);
08218                 return SSL_FATAL_ERROR;
08219             }
08220             WOLFSSL_MSG("sent: change cipher spec");
08221             ssl->options.connectState = FIRST_REPLY_FOURTH;
08222             WOLFSSL_MSG("connect state: FIRST_REPLY_FOURTH");
08223 
08224         case FIRST_REPLY_FOURTH :
08225             if ( (ssl->error = SendFinished(ssl)) != 0) {
08226                 WOLFSSL_ERROR(ssl->error);
08227                 return SSL_FATAL_ERROR;
08228             }
08229             WOLFSSL_MSG("sent: finished");
08230             ssl->options.connectState = FINISHED_DONE;
08231             WOLFSSL_MSG("connect state: FINISHED_DONE");
08232 
08233         case FINISHED_DONE :
08234             /* get response */
08235             while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
08236                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
08237                     WOLFSSL_ERROR(ssl->error);
08238                     return SSL_FATAL_ERROR;
08239                 }
08240 
08241             ssl->options.connectState = SECOND_REPLY_DONE;
08242             WOLFSSL_MSG("connect state: SECOND_REPLY_DONE");
08243 
08244         case SECOND_REPLY_DONE:
08245 #ifndef NO_HANDSHAKE_DONE_CB
08246             if (ssl->hsDoneCb) {
08247                 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
08248                 if (cbret < 0) {
08249                     ssl->error = cbret;
08250                     WOLFSSL_MSG("HandShake Done Cb don't continue error");
08251                     return SSL_FATAL_ERROR;
08252                 }
08253             }
08254 #endif /* NO_HANDSHAKE_DONE_CB */
08255 
08256             if (!ssl->options.dtls) {
08257                 if (!ssl->options.keepResources) {
08258                     FreeHandshakeResources(ssl);
08259                 }
08260             }
08261 #ifdef WOLFSSL_DTLS
08262             else {
08263                 ssl->options.dtlsHsRetain = 1;
08264             }
08265 #endif /* WOLFSSL_DTLS */
08266 
08267             WOLFSSL_LEAVE("SSL_connect()", SSL_SUCCESS);
08268             return SSL_SUCCESS;
08269 
08270         default:
08271             WOLFSSL_MSG("Unknown connect state ERROR");
08272             return SSL_FATAL_ERROR; /* unknown connect state */
08273         }
08274     }
08275 
08276 #endif /* NO_WOLFSSL_CLIENT */
08277 
08278 
08279 /* server only parts */
08280 #ifndef NO_WOLFSSL_SERVER
08281 
08282     #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
08283     WOLFSSL_METHOD* wolfSSLv3_server_method(void)
08284     {
08285         WOLFSSL_ENTER("SSLv3_server_method");
08286         return wolfSSLv3_server_method_ex(NULL);
08287     }
08288     #endif
08289 
08290 
08291     #ifdef WOLFSSL_DTLS
08292 
08293         #ifndef NO_OLD_TLS
08294         WOLFSSL_METHOD* wolfDTLSv1_server_method(void)
08295         {
08296             WOLFSSL_ENTER("DTLSv1_server_method");
08297             return wolfDTLSv1_server_method_ex(NULL);
08298         }
08299         #endif /* NO_OLD_TLS */
08300 
08301         WOLFSSL_METHOD* wolfDTLSv1_2_server_method(void)
08302         {
08303             WOLFSSL_ENTER("DTLSv1_2_server_method");
08304             return wolfDTLSv1_2_server_method_ex(NULL);
08305         }
08306     #endif
08307 
08308     #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
08309     WOLFSSL_METHOD* wolfSSLv3_server_method_ex(void* heap)
08310     {
08311         WOLFSSL_METHOD* method =
08312                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
08313                                                      heap, DYNAMIC_TYPE_METHOD);
08314         WOLFSSL_ENTER("SSLv3_server_method_ex");
08315         if (method) {
08316             InitSSL_Method(method, MakeSSLv3());
08317             method->side = WOLFSSL_SERVER_END;
08318         }
08319         return method;
08320     }
08321     #endif
08322 
08323 
08324     #ifdef WOLFSSL_DTLS
08325 
08326         #ifndef NO_OLD_TLS
08327         WOLFSSL_METHOD* wolfDTLSv1_server_method_ex(void* heap)
08328         {
08329             WOLFSSL_METHOD* method =
08330                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
08331                                                      heap, DYNAMIC_TYPE_METHOD);
08332             WOLFSSL_ENTER("DTLSv1_server_method_ex");
08333             if (method) {
08334                 InitSSL_Method(method, MakeDTLSv1());
08335                 method->side = WOLFSSL_SERVER_END;
08336             }
08337             return method;
08338         }
08339         #endif /* NO_OLD_TLS */
08340 
08341         WOLFSSL_METHOD* wolfDTLSv1_2_server_method_ex(void* heap)
08342         {
08343             WOLFSSL_METHOD* method =
08344                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
08345                                                      heap, DYNAMIC_TYPE_METHOD);
08346             WOLFSSL_ENTER("DTLSv1_2_server_method_ex");
08347             if (method) {
08348                 InitSSL_Method(method, MakeDTLSv1_2());
08349                 method->side = WOLFSSL_SERVER_END;
08350             }
08351             (void)heap;
08352             return method;
08353         }
08354     #endif
08355 
08356 
08357     int wolfSSL_accept(WOLFSSL* ssl)
08358     {
08359         word16 havePSK = 0;
08360         word16 haveAnon = 0;
08361 
08362 #ifdef WOLFSSL_TLS13
08363         if (ssl->options.tls1_3)
08364             return wolfSSL_accept_TLSv13(ssl);
08365 #endif
08366 
08367         WOLFSSL_ENTER("SSL_accept()");
08368 
08369         #ifdef HAVE_ERRNO_H
08370             errno = 0;
08371         #endif
08372 
08373         #ifndef NO_PSK
08374             havePSK = ssl->options.havePSK;
08375         #endif
08376         (void)havePSK;
08377 
08378         #ifdef HAVE_ANON
08379             haveAnon = ssl->options.haveAnon;
08380         #endif
08381         (void)haveAnon;
08382 
08383         if (ssl->options.side != WOLFSSL_SERVER_END) {
08384             WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
08385             return SSL_FATAL_ERROR;
08386         }
08387 
08388         #ifndef NO_CERTS
08389             /* in case used set_accept_state after init */
08390             if (!havePSK && !haveAnon &&
08391                 (!ssl->buffers.certificate ||
08392                  !ssl->buffers.certificate->buffer ||
08393                  !ssl->buffers.key ||
08394                  !ssl->buffers.key->buffer)) {
08395                 WOLFSSL_MSG("accept error: don't have server cert and key");
08396                 ssl->error = NO_PRIVATE_KEY;
08397                 WOLFSSL_ERROR(ssl->error);
08398                 return SSL_FATAL_ERROR;
08399             }
08400         #endif
08401 
08402         #ifdef WOLFSSL_DTLS
08403             if (ssl->version.major == DTLS_MAJOR) {
08404                 ssl->options.dtls   = 1;
08405                 ssl->options.tls    = 1;
08406                 ssl->options.tls1_1 = 1;
08407             }
08408         #endif
08409 
08410         if (ssl->buffers.outputBuffer.length > 0) {
08411             if ( (ssl->error = SendBuffered(ssl)) == 0) {
08412                 /* fragOffset is non-zero when sending fragments. On the last
08413                  * fragment, fragOffset is zero again, and the state can be
08414                  * advanced. */
08415                 if (ssl->fragOffset == 0) {
08416                     ssl->options.acceptState++;
08417                     WOLFSSL_MSG("accept state: "
08418                                 "Advanced from last buffered fragment send");
08419                 }
08420                 else {
08421                     WOLFSSL_MSG("accept state: "
08422                                 "Not advanced, more fragments to send");
08423                 }
08424             }
08425             else {
08426                 WOLFSSL_ERROR(ssl->error);
08427                 return SSL_FATAL_ERROR;
08428             }
08429         }
08430 
08431         switch (ssl->options.acceptState) {
08432 
08433         case ACCEPT_BEGIN :
08434             /* get response */
08435             while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
08436                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
08437                     WOLFSSL_ERROR(ssl->error);
08438                     return SSL_FATAL_ERROR;
08439                 }
08440 #ifdef WOLFSSL_TLS13
08441             ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
08442             WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
08443 
08444         case ACCEPT_CLIENT_HELLO_DONE :
08445             if (ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST) {
08446                 if ((ssl->error = SendTls13HelloRetryRequest(ssl)) != 0) {
08447                     WOLFSSL_ERROR(ssl->error);
08448                     return SSL_FATAL_ERROR;
08449                 }
08450             }
08451             ssl->options.acceptState = ACCEPT_HELLO_RETRY_REQUEST_DONE;
08452             WOLFSSL_MSG("accept state ACCEPT_HELLO_RETRY_REQUEST_DONE");
08453 
08454         case ACCEPT_HELLO_RETRY_REQUEST_DONE :
08455             if (ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST) {
08456                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
08457                     WOLFSSL_ERROR(ssl->error);
08458                     return SSL_FATAL_ERROR;
08459                 }
08460             }
08461 #endif
08462             ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
08463             WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
08464 
08465         case ACCEPT_FIRST_REPLY_DONE :
08466 #ifdef WOLFSSL_TLS13
08467             if (ssl->options.tls1_3) {
08468                 return wolfSSL_accept_TLSv13(ssl);
08469             }
08470 #endif
08471             if ( (ssl->error = SendServerHello(ssl)) != 0) {
08472                 WOLFSSL_ERROR(ssl->error);
08473                 return SSL_FATAL_ERROR;
08474             }
08475             ssl->options.acceptState = SERVER_HELLO_SENT;
08476             WOLFSSL_MSG("accept state SERVER_HELLO_SENT");
08477 
08478         case SERVER_HELLO_SENT :
08479             #ifndef NO_CERTS
08480                 if (!ssl->options.resuming)
08481                     if ( (ssl->error = SendCertificate(ssl)) != 0) {
08482                         WOLFSSL_ERROR(ssl->error);
08483                         return SSL_FATAL_ERROR;
08484                     }
08485             #endif
08486             ssl->options.acceptState = CERT_SENT;
08487             WOLFSSL_MSG("accept state CERT_SENT");
08488 
08489         case CERT_SENT :
08490             #ifndef NO_CERTS
08491             if (!ssl->options.resuming)
08492                 if ( (ssl->error = SendCertificateStatus(ssl)) != 0) {
08493                     WOLFSSL_ERROR(ssl->error);
08494                     return SSL_FATAL_ERROR;
08495                 }
08496             #endif
08497             ssl->options.acceptState = CERT_STATUS_SENT;
08498             WOLFSSL_MSG("accept state CERT_STATUS_SENT");
08499 
08500         case CERT_STATUS_SENT :
08501             if (!ssl->options.resuming)
08502                 if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
08503                     WOLFSSL_ERROR(ssl->error);
08504                     return SSL_FATAL_ERROR;
08505                 }
08506             ssl->options.acceptState = KEY_EXCHANGE_SENT;
08507             WOLFSSL_MSG("accept state KEY_EXCHANGE_SENT");
08508 
08509         case KEY_EXCHANGE_SENT :
08510             #ifndef NO_CERTS
08511                 if (!ssl->options.resuming)
08512                     if (ssl->options.verifyPeer)
08513                         if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
08514                             WOLFSSL_ERROR(ssl->error);
08515                             return SSL_FATAL_ERROR;
08516                         }
08517             #endif
08518             ssl->options.acceptState = CERT_REQ_SENT;
08519             WOLFSSL_MSG("accept state CERT_REQ_SENT");
08520 
08521         case CERT_REQ_SENT :
08522             if (!ssl->options.resuming)
08523                 if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
08524                     WOLFSSL_ERROR(ssl->error);
08525                     return SSL_FATAL_ERROR;
08526                 }
08527             ssl->options.acceptState = SERVER_HELLO_DONE;
08528             WOLFSSL_MSG("accept state SERVER_HELLO_DONE");
08529 
08530         case SERVER_HELLO_DONE :
08531             if (!ssl->options.resuming) {
08532                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
08533                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
08534                         WOLFSSL_ERROR(ssl->error);
08535                         return SSL_FATAL_ERROR;
08536                     }
08537             }
08538             ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
08539             WOLFSSL_MSG("accept state  ACCEPT_SECOND_REPLY_DONE");
08540 
08541         case ACCEPT_SECOND_REPLY_DONE :
08542 #ifdef HAVE_SESSION_TICKET
08543             if (ssl->options.createTicket) {
08544                 if ( (ssl->error = SendTicket(ssl)) != 0) {
08545                     WOLFSSL_ERROR(ssl->error);
08546                     return SSL_FATAL_ERROR;
08547                 }
08548             }
08549 #endif /* HAVE_SESSION_TICKET */
08550             ssl->options.acceptState = TICKET_SENT;
08551             WOLFSSL_MSG("accept state  TICKET_SENT");
08552 
08553         case TICKET_SENT:
08554             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
08555                 WOLFSSL_ERROR(ssl->error);
08556                 return SSL_FATAL_ERROR;
08557             }
08558             ssl->options.acceptState = CHANGE_CIPHER_SENT;
08559             WOLFSSL_MSG("accept state  CHANGE_CIPHER_SENT");
08560 
08561         case CHANGE_CIPHER_SENT :
08562             if ( (ssl->error = SendFinished(ssl)) != 0) {
08563                 WOLFSSL_ERROR(ssl->error);
08564                 return SSL_FATAL_ERROR;
08565             }
08566 
08567             ssl->options.acceptState = ACCEPT_FINISHED_DONE;
08568             WOLFSSL_MSG("accept state ACCEPT_FINISHED_DONE");
08569 
08570         case ACCEPT_FINISHED_DONE :
08571             if (ssl->options.resuming)
08572                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
08573                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
08574                         WOLFSSL_ERROR(ssl->error);
08575                         return SSL_FATAL_ERROR;
08576                     }
08577 
08578             ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
08579             WOLFSSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
08580 
08581         case ACCEPT_THIRD_REPLY_DONE :
08582 #ifndef NO_HANDSHAKE_DONE_CB
08583             if (ssl->hsDoneCb) {
08584                 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
08585                 if (cbret < 0) {
08586                     ssl->error = cbret;
08587                     WOLFSSL_MSG("HandShake Done Cb don't continue error");
08588                     return SSL_FATAL_ERROR;
08589                 }
08590             }
08591 #endif /* NO_HANDSHAKE_DONE_CB */
08592 
08593             if (!ssl->options.dtls) {
08594                 if (!ssl->options.keepResources) {
08595                     FreeHandshakeResources(ssl);
08596                 }
08597             }
08598 #ifdef WOLFSSL_DTLS
08599             else {
08600                 ssl->options.dtlsHsRetain = 1;
08601             }
08602 #endif /* WOLFSSL_DTLS */
08603 
08604 #ifdef WOLFSSL_SESSION_EXPORT
08605             if (ssl->dtls_export) {
08606                 if ((ssl->error = wolfSSL_send_session(ssl)) != 0) {
08607                     WOLFSSL_MSG("Export DTLS session error");
08608                     WOLFSSL_ERROR(ssl->error);
08609                     return SSL_FATAL_ERROR;
08610                 }
08611             }
08612 #endif
08613 
08614             WOLFSSL_LEAVE("SSL_accept()", SSL_SUCCESS);
08615             return SSL_SUCCESS;
08616 
08617         default :
08618             WOLFSSL_MSG("Unknown accept state ERROR");
08619             return SSL_FATAL_ERROR;
08620         }
08621     }
08622 
08623 #endif /* NO_WOLFSSL_SERVER */
08624 
08625 
08626 #ifndef NO_HANDSHAKE_DONE_CB
08627 
08628 int wolfSSL_SetHsDoneCb(WOLFSSL* ssl, HandShakeDoneCb cb, void* user_ctx)
08629 {
08630     WOLFSSL_ENTER("wolfSSL_SetHsDoneCb");
08631 
08632     if (ssl == NULL)
08633         return BAD_FUNC_ARG;
08634 
08635     ssl->hsDoneCb  = cb;
08636     ssl->hsDoneCtx = user_ctx;
08637 
08638 
08639     return SSL_SUCCESS;
08640 }
08641 
08642 #endif /* NO_HANDSHAKE_DONE_CB */
08643 
08644 int wolfSSL_Cleanup(void)
08645 {
08646     int ret = SSL_SUCCESS;
08647     int release = 0;
08648 
08649     WOLFSSL_ENTER("wolfSSL_Cleanup");
08650 
08651     if (initRefCount == 0)
08652         return ret;  /* possibly no init yet, but not failure either way */
08653 
08654     if (wc_LockMutex(&count_mutex) != 0) {
08655         WOLFSSL_MSG("Bad Lock Mutex count");
08656         return BAD_MUTEX_E;
08657     }
08658 
08659     release = initRefCount-- == 1;
08660     if (initRefCount < 0)
08661         initRefCount = 0;
08662 
08663     wc_UnLockMutex(&count_mutex);
08664 
08665     if (!release)
08666         return ret;
08667 
08668 #ifndef NO_SESSION_CACHE
08669     if (wc_FreeMutex(&session_mutex) != 0)
08670         ret = BAD_MUTEX_E;
08671 #endif
08672     if (wc_FreeMutex(&count_mutex) != 0)
08673         ret = BAD_MUTEX_E;
08674 
08675     if (wolfCrypt_Cleanup() != 0) {
08676         WOLFSSL_MSG("Error with wolfCrypt_Cleanup call");
08677         ret = WC_CLEANUP_E;
08678     }
08679 
08680     return ret;
08681 }
08682 
08683 
08684 #ifndef NO_SESSION_CACHE
08685 
08686 
08687 /* some session IDs aren't random after all, let's make them random */
08688 static INLINE word32 HashSession(const byte* sessionID, word32 len, int* error)
08689 {
08690     byte digest[MAX_DIGEST_SIZE];
08691 
08692 #ifndef NO_MD5
08693     *error =  wc_Md5Hash(sessionID, len, digest);
08694 #elif !defined(NO_SHA)
08695     *error =  wc_ShaHash(sessionID, len, digest);
08696 #elif !defined(NO_SHA256)
08697     *error =  wc_Sha256Hash(sessionID, len, digest);
08698 #else
08699     #error "We need a digest to hash the session IDs"
08700 #endif
08701 
08702     return *error == 0 ? MakeWordFromHash(digest) : 0; /* 0 on failure */
08703 }
08704 
08705 
08706 void wolfSSL_flush_sessions(WOLFSSL_CTX* ctx, long tm)
08707 {
08708     /* static table now, no flushing needed */
08709     (void)ctx;
08710     (void)tm;
08711 }
08712 
08713 
08714 /* set ssl session timeout in seconds */
08715 int wolfSSL_set_timeout(WOLFSSL* ssl, unsigned int to)
08716 {
08717     if (ssl == NULL)
08718         return BAD_FUNC_ARG;
08719 
08720     if (to == 0)
08721         to = WOLFSSL_SESSION_TIMEOUT;
08722     ssl->timeout = to;
08723 
08724     return SSL_SUCCESS;
08725 }
08726 
08727 
08728 /* set ctx session timeout in seconds */
08729 int wolfSSL_CTX_set_timeout(WOLFSSL_CTX* ctx, unsigned int to)
08730 {
08731     if (ctx == NULL)
08732         return BAD_FUNC_ARG;
08733 
08734     if (to == 0)
08735         to = WOLFSSL_SESSION_TIMEOUT;
08736     ctx->timeout = to;
08737 
08738     return SSL_SUCCESS;
08739 }
08740 
08741 
08742 #ifndef NO_CLIENT_CACHE
08743 
08744 /* Get Session from Client cache based on id/len, return NULL on failure */
08745 WOLFSSL_SESSION* GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
08746 {
08747     WOLFSSL_SESSION* ret = NULL;
08748     word32          row;
08749     int             idx;
08750     int             count;
08751     int             error = 0;
08752 
08753     WOLFSSL_ENTER("GetSessionClient");
08754 
08755     if (ssl->ctx->sessionCacheOff)
08756         return NULL;
08757 
08758     if (ssl->options.side == WOLFSSL_SERVER_END)
08759         return NULL;
08760 
08761     len = min(SERVER_ID_LEN, (word32)len);
08762 
08763 #ifdef HAVE_EXT_CACHE
08764     if (ssl->ctx->get_sess_cb != NULL) {
08765         int copy = 0;
08766         ret = ssl->ctx->get_sess_cb(ssl, (byte*)id, len, &copy);
08767         if (ret != NULL)
08768             return ret;
08769     }
08770 
08771     if (ssl->ctx->internalCacheOff)
08772         return NULL;
08773 #endif
08774 
08775     row = HashSession(id, len, &error) % SESSION_ROWS;
08776     if (error != 0) {
08777         WOLFSSL_MSG("Hash session failed");
08778         return NULL;
08779     }
08780 
08781     if (wc_LockMutex(&session_mutex) != 0) {
08782         WOLFSSL_MSG("Lock session mutex failed");
08783         return NULL;
08784     }
08785 
08786     /* start from most recently used */
08787     count = min((word32)ClientCache[row].totalCount, SESSIONS_PER_ROW);
08788     idx = ClientCache[row].nextIdx - 1;
08789     if (idx < 0)
08790         idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
08791 
08792     for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
08793         WOLFSSL_SESSION* current;
08794         ClientSession   clSess;
08795 
08796         if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
08797             WOLFSSL_MSG("Bad idx");
08798             break;
08799         }
08800 
08801         clSess = ClientCache[row].Clients[idx];
08802 
08803         current = &SessionCache[clSess.serverRow].Sessions[clSess.serverIdx];
08804         if (XMEMCMP(current->serverID, id, len) == 0) {
08805             WOLFSSL_MSG("Found a serverid match for client");
08806             if (LowResTimer() < (current->bornOn + current->timeout)) {
08807                 WOLFSSL_MSG("Session valid");
08808                 ret = current;
08809                 break;
08810             } else {
08811                 WOLFSSL_MSG("Session timed out");  /* could have more for id */
08812             }
08813         } else {
08814             WOLFSSL_MSG("ServerID not a match from client table");
08815         }
08816     }
08817 
08818     wc_UnLockMutex(&session_mutex);
08819 
08820     return ret;
08821 }
08822 
08823 #endif /* NO_CLIENT_CACHE */
08824 
08825 /* Restore the master secret and session information for certificates.
08826  *
08827  * ssl                  The SSL/TLS object.
08828  * session              The cached session to restore.
08829  * masterSecret         The master secret from the cached session.
08830  * restoreSessionCerts  Restoring session certificates is required.
08831  */
08832 static INLINE void RestoreSession(WOLFSSL* ssl, WOLFSSL_SESSION* session,
08833         byte* masterSecret, byte restoreSessionCerts)
08834 {
08835     (void)ssl;
08836     (void)restoreSessionCerts;
08837 
08838     if (masterSecret)
08839         XMEMCPY(masterSecret, session->masterSecret, SECRET_LEN);
08840 #ifdef SESSION_CERTS
08841     /* If set, we should copy the session certs into the ssl object
08842      * from the session we are returning so we can resume */
08843     if (restoreSessionCerts) {
08844         ssl->session.chain        = session->chain;
08845         ssl->session.version      = session->version;
08846         ssl->session.cipherSuite0 = session->cipherSuite0;
08847         ssl->session.cipherSuite  = session->cipherSuite;
08848     }
08849 #endif /* SESSION_CERTS */
08850 }
08851 
08852 WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
08853         byte restoreSessionCerts)
08854 {
08855     WOLFSSL_SESSION* ret = 0;
08856     const byte*  id = NULL;
08857     word32       row;
08858     int          idx;
08859     int          count;
08860     int          error = 0;
08861 
08862     (void)       restoreSessionCerts;
08863 
08864     if (ssl->options.sessionCacheOff)
08865         return NULL;
08866 
08867     if (ssl->options.haveSessionId == 0)
08868         return NULL;
08869 
08870 #ifdef HAVE_SESSION_TICKET
08871     if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
08872         return NULL;
08873 #endif
08874 
08875     if (ssl->arrays)
08876         id = ssl->arrays->sessionID;
08877     else
08878         id = ssl->session.sessionID;
08879 
08880 #ifdef HAVE_EXT_CACHE
08881     if (ssl->ctx->get_sess_cb != NULL) {
08882         int copy = 0;
08883         /* Attempt to retrieve the session from the external cache. */
08884         ret = ssl->ctx->get_sess_cb(ssl, (byte*)id, ID_LEN, &copy);
08885         if (ret != NULL) {
08886             RestoreSession(ssl, ret, masterSecret, restoreSessionCerts);
08887             return ret;
08888         }
08889     }
08890 
08891     if (ssl->ctx->internalCacheOff)
08892         return NULL;
08893 #endif
08894 
08895     row = HashSession(id, ID_LEN, &error) % SESSION_ROWS;
08896     if (error != 0) {
08897         WOLFSSL_MSG("Hash session failed");
08898         return NULL;
08899     }
08900 
08901     if (wc_LockMutex(&session_mutex) != 0)
08902         return 0;
08903 
08904     /* start from most recently used */
08905     count = min((word32)SessionCache[row].totalCount, SESSIONS_PER_ROW);
08906     idx = SessionCache[row].nextIdx - 1;
08907     if (idx < 0)
08908         idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
08909 
08910     for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
08911         WOLFSSL_SESSION* current;
08912 
08913         if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
08914             WOLFSSL_MSG("Bad idx");
08915             break;
08916         }
08917 
08918         current = &SessionCache[row].Sessions[idx];
08919         if (XMEMCMP(current->sessionID, id, ID_LEN) == 0) {
08920             WOLFSSL_MSG("Found a session match");
08921             if (LowResTimer() < (current->bornOn + current->timeout)) {
08922                 WOLFSSL_MSG("Session valid");
08923                 ret = current;
08924                 RestoreSession(ssl, ret, masterSecret, restoreSessionCerts);
08925             } else {
08926                 WOLFSSL_MSG("Session timed out");
08927             }
08928             break;  /* no more sessionIDs whether valid or not that match */
08929         } else {
08930             WOLFSSL_MSG("SessionID not a match at this idx");
08931         }
08932     }
08933 
08934     wc_UnLockMutex(&session_mutex);
08935 
08936     return ret;
08937 }
08938 
08939 
08940 static int GetDeepCopySession(WOLFSSL* ssl, WOLFSSL_SESSION* copyFrom)
08941 {
08942     WOLFSSL_SESSION* copyInto = &ssl->session;
08943     void* tmpBuff             = NULL;
08944     int ticketLen             = 0;
08945     int doDynamicCopy         = 0;
08946     int ret                   = SSL_SUCCESS;
08947 
08948     (void)ticketLen;
08949     (void)doDynamicCopy;
08950     (void)tmpBuff;
08951 
08952     if (!ssl || !copyFrom)
08953         return BAD_FUNC_ARG;
08954 
08955 #ifdef HAVE_SESSION_TICKET
08956     /* Free old dynamic ticket if we had one to avoid leak */
08957     if (copyInto->isDynamic) {
08958         XFREE(copyInto->ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
08959         copyInto->ticket = copyInto->staticTicket;
08960         copyInto->isDynamic = 0;
08961     }
08962 #endif
08963 
08964     if (wc_LockMutex(&session_mutex) != 0)
08965         return BAD_MUTEX_E;
08966 
08967 #ifdef HAVE_SESSION_TICKET
08968     /* Size of ticket to alloc if needed; Use later for alloc outside lock */
08969     doDynamicCopy = copyFrom->isDynamic;
08970     ticketLen = copyFrom->ticketLen;
08971 #endif
08972 
08973     *copyInto = *copyFrom;
08974 
08975     /* Default ticket to non dynamic. This will avoid crash if we fail below */
08976 #ifdef HAVE_SESSION_TICKET
08977     copyInto->ticket = copyInto->staticTicket;
08978     copyInto->isDynamic = 0;
08979 #endif
08980 
08981     if (wc_UnLockMutex(&session_mutex) != 0) {
08982         return BAD_MUTEX_E;
08983     }
08984 
08985 #ifdef HAVE_SESSION_TICKET
08986 #ifdef WOLFSSL_TLS13
08987     if (wc_LockMutex(&session_mutex) != 0) {
08988         XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
08989         return BAD_MUTEX_E;
08990     }
08991 
08992     copyInto->cipherSuite0 = copyFrom->cipherSuite0;
08993     copyInto->cipherSuite = copyFrom->cipherSuite;
08994     copyInto->namedGroup = copyFrom->namedGroup;
08995     copyInto->ticketSeen = copyFrom->ticketSeen;
08996     copyInto->ticketAdd = copyFrom->ticketAdd;
08997     XMEMCPY(copyInto->masterSecret, copyFrom->masterSecret, SECRET_LEN);
08998 
08999     if (wc_UnLockMutex(&session_mutex) != 0) {
09000         if (ret == SSL_SUCCESS)
09001             ret = BAD_MUTEX_E;
09002     }
09003 #endif
09004     /* If doing dynamic copy, need to alloc outside lock, then inside a lock
09005      * confirm the size still matches and memcpy */
09006     if (doDynamicCopy) {
09007         tmpBuff = (byte*)XMALLOC(ticketLen, ssl->heap,
09008                                                      DYNAMIC_TYPE_SESSION_TICK);
09009         if (!tmpBuff)
09010             return MEMORY_ERROR;
09011 
09012         if (wc_LockMutex(&session_mutex) != 0) {
09013             XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09014             return BAD_MUTEX_E;
09015         }
09016 
09017         if (ticketLen != copyFrom->ticketLen) {
09018             /* Another thread modified the ssl-> session ticket during alloc.
09019              * Treat as error, since ticket different than when copy requested */
09020             ret = VAR_STATE_CHANGE_E;
09021         }
09022 
09023         if (ret == SSL_SUCCESS) {
09024             copyInto->ticket = (byte*)tmpBuff;
09025             copyInto->isDynamic = 1;
09026             XMEMCPY(copyInto->ticket, copyFrom->ticket, ticketLen);
09027         }
09028     } else {
09029         /* Need to ensure ticket pointer gets updated to own buffer
09030          * and is not pointing to buff of session copied from */
09031         copyInto->ticket = copyInto->staticTicket;
09032     }
09033 
09034     if (doDynamicCopy) {
09035         if (wc_UnLockMutex(&session_mutex) != 0) {
09036             if (ret == SSL_SUCCESS)
09037                 ret = BAD_MUTEX_E;
09038         }
09039     }
09040 
09041     if (ret != SSL_SUCCESS) {
09042         /* cleanup */
09043         if (tmpBuff)
09044             XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09045         copyInto->ticket = copyInto->staticTicket;
09046         copyInto->isDynamic = 0;
09047     }
09048 #endif /* HAVE_SESSION_TICKET */
09049     return ret;
09050 }
09051 
09052 
09053 int SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
09054 {
09055     if (ssl->options.sessionCacheOff)
09056         return SSL_FAILURE;
09057 
09058     if (LowResTimer() < (session->bornOn + session->timeout)) {
09059         int ret = GetDeepCopySession(ssl, session);
09060         if (ret == SSL_SUCCESS) {
09061             ssl->options.resuming = 1;
09062 
09063 #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
09064                                defined(HAVE_SESSION_TICKET) && !defined(NO_PSK))
09065             ssl->version              = session->version;
09066             ssl->options.cipherSuite0 = session->cipherSuite0;
09067             ssl->options.cipherSuite  = session->cipherSuite;
09068 #endif
09069         }
09070 
09071         return ret;
09072     }
09073     return SSL_FAILURE;  /* session timed out */
09074 }
09075 
09076 
09077 #ifdef WOLFSSL_SESSION_STATS
09078 static int get_locked_session_stats(word32* active, word32* total,
09079                                     word32* peak);
09080 #endif
09081 
09082 int AddSession(WOLFSSL* ssl)
09083 {
09084     word32 row = 0;
09085     word32 idx = 0;
09086     int    error = 0;
09087 #ifdef HAVE_SESSION_TICKET
09088     byte*  tmpBuff = NULL;
09089     int    ticLen  = 0;
09090 #endif
09091     WOLFSSL_SESSION* session;
09092 
09093     if (ssl->options.sessionCacheOff)
09094         return 0;
09095 
09096     if (ssl->options.haveSessionId == 0)
09097         return 0;
09098 
09099 #ifdef HAVE_SESSION_TICKET
09100     if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
09101         return 0;
09102 #endif
09103 
09104 #ifdef HAVE_SESSION_TICKET
09105     ticLen = ssl->session.ticketLen;
09106     /* Alloc Memory here so if Malloc fails can exit outside of lock */
09107     if(ticLen > SESSION_TICKET_LEN) {
09108         tmpBuff = (byte*)XMALLOC(ticLen, ssl->heap,
09109                 DYNAMIC_TYPE_SESSION_TICK);
09110         if(!tmpBuff)
09111             return MEMORY_E;
09112     }
09113 #endif
09114 
09115 #ifdef HAVE_EXT_CACHE
09116     if (ssl->options.internalCacheOff) {
09117         /* Create a new session object to be stored. */
09118         session = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), NULL,
09119                                             DYNAMIC_TYPE_OPENSSL);
09120         if (session == NULL) {
09121 #ifdef HAVE_SESSION_TICKET
09122             XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09123 #endif
09124             return MEMORY_E;
09125         }
09126         XMEMSET(session, 0, sizeof(WOLFSSL_SESSION));
09127         session->isAlloced = 1;
09128     }
09129     else
09130 #endif
09131     {
09132         /* Use the session object in the cache for external cache if required.
09133          */
09134         row = HashSession(ssl->arrays->sessionID, ID_LEN, &error) %
09135                 SESSION_ROWS;
09136         if (error != 0) {
09137             WOLFSSL_MSG("Hash session failed");
09138 #ifdef HAVE_SESSION_TICKET
09139             XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09140 #endif
09141             return error;
09142         }
09143 
09144         if (wc_LockMutex(&session_mutex) != 0) {
09145 #ifdef HAVE_SESSION_TICKET
09146             XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09147 #endif
09148             return BAD_MUTEX_E;
09149         }
09150 
09151         idx = SessionCache[row].nextIdx++;
09152 #ifdef SESSION_INDEX
09153         ssl->sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx;
09154 #endif
09155         session = &SessionCache[row].Sessions[idx];
09156     }
09157 
09158     if (!ssl->options.tls1_3)
09159         XMEMCPY(session->masterSecret, ssl->arrays->masterSecret, SECRET_LEN);
09160     else
09161         XMEMCPY(session->masterSecret, ssl->session.masterSecret, SECRET_LEN);
09162     session->haveEMS = ssl->options.haveEMS;
09163     XMEMCPY(session->sessionID, ssl->arrays->sessionID, ID_LEN);
09164     session->sessionIDSz = ssl->arrays->sessionIDSz;
09165 
09166     session->timeout = ssl->timeout;
09167     session->bornOn  = LowResTimer();
09168 
09169 #ifdef HAVE_SESSION_TICKET
09170     /* Check if another thread modified ticket since alloc */
09171     if (ticLen != ssl->session.ticketLen) {
09172         error = VAR_STATE_CHANGE_E;
09173     }
09174 
09175     if (error == 0) {
09176         /* Cleanup cache row's old Dynamic buff if exists */
09177         if(session->isDynamic) {
09178             XFREE(session->ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09179             session->ticket = NULL;
09180         }
09181 
09182         /* If too large to store in static buffer, use dyn buffer */
09183         if (ticLen > SESSION_TICKET_LEN) {
09184             session->ticket = tmpBuff;
09185             session->isDynamic = 1;
09186         } else {
09187             session->ticket = session->staticTicket;
09188             session->isDynamic = 0;
09189         }
09190     }
09191 
09192     if (error == 0) {
09193         session->ticketLen = ticLen;
09194         XMEMCPY(session->ticket, ssl->session.ticket, ticLen);
09195     } else { /* cleanup, reset state */
09196         session->ticket    = session->staticTicket;
09197         session->isDynamic = 0;
09198         session->ticketLen = 0;
09199         if (tmpBuff) {
09200             XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
09201             tmpBuff = NULL;
09202         }
09203     }
09204 #endif
09205 
09206 #ifdef SESSION_CERTS
09207     if (error == 0) {
09208         session->chain.count = ssl->session.chain.count;
09209         XMEMCPY(session->chain.certs, ssl->session.chain.certs,
09210                 sizeof(x509_buffer) * MAX_CHAIN_DEPTH);
09211     }
09212 #endif /* SESSION_CERTS */
09213 #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
09214                                defined(HAVE_SESSION_TICKET) && !defined(NO_PSK))
09215     if (error == 0) {
09216         session->version      = ssl->version;
09217         session->cipherSuite0 = ssl->options.cipherSuite0;
09218         session->cipherSuite  = ssl->options.cipherSuite;
09219     }
09220 #endif /* SESSION_CERTS || (WOLFSSL_TLS13 & !NO_PSK) */
09221 #if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
09222     if (error == 0) {
09223         session->namedGroup = ssl->session.namedGroup;
09224         session->ticketSeen = ssl->session.ticketSeen;
09225         session->ticketAdd = ssl->session.ticketAdd;
09226     }
09227 #endif /* WOLFSSL_TLS13 && HAVE_SESSION_TICKET */
09228 #ifdef HAVE_EXT_CACHE
09229     if (!ssl->options.internalCacheOff)
09230 #endif
09231     {
09232         if (error == 0) {
09233             SessionCache[row].totalCount++;
09234             if (SessionCache[row].nextIdx == SESSIONS_PER_ROW)
09235                 SessionCache[row].nextIdx = 0;
09236         }
09237     }
09238 #ifndef NO_CLIENT_CACHE
09239     if (error == 0) {
09240         if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->session.idLen) {
09241             word32 clientRow, clientIdx;
09242 
09243             WOLFSSL_MSG("Adding client cache entry");
09244 
09245             session->idLen = ssl->session.idLen;
09246             XMEMCPY(session->serverID, ssl->session.serverID,
09247                     ssl->session.idLen);
09248 
09249 #ifdef HAVE_EXT_CACHE
09250             if (!ssl->options.internalCacheOff)
09251 #endif
09252             {
09253                 clientRow = HashSession(ssl->session.serverID,
09254                         ssl->session.idLen, &error) % SESSION_ROWS;
09255                 if (error != 0) {
09256                     WOLFSSL_MSG("Hash session failed");
09257                 } else {
09258                     clientIdx = ClientCache[clientRow].nextIdx++;
09259 
09260                     ClientCache[clientRow].Clients[clientIdx].serverRow =
09261                                                                    (word16)row;
09262                     ClientCache[clientRow].Clients[clientIdx].serverIdx =
09263                                                                    (word16)idx;
09264 
09265                     ClientCache[clientRow].totalCount++;
09266                     if (ClientCache[clientRow].nextIdx == SESSIONS_PER_ROW)
09267                         ClientCache[clientRow].nextIdx = 0;
09268                 }
09269             }
09270         }
09271         else
09272             session->idLen = 0;
09273     }
09274 #endif /* NO_CLIENT_CACHE */
09275 
09276 #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
09277 #ifdef HAVE_EXT_CACHE
09278     if (!ssl->options.internalCacheOff)
09279 #endif
09280     {
09281         if (error == 0) {
09282             word32 active = 0;
09283 
09284             error = get_locked_session_stats(&active, NULL, NULL);
09285             if (error == SSL_SUCCESS) {
09286                 error = 0;  /* back to this function ok */
09287 
09288                 if (active > PeakSessions)
09289                     PeakSessions = active;
09290             }
09291         }
09292     }
09293 #endif /* defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS) */
09294 
09295 #ifdef HAVE_EXT_CACHE
09296     if (!ssl->options.internalCacheOff)
09297 #endif
09298     {
09299         if (wc_UnLockMutex(&session_mutex) != 0)
09300             return BAD_MUTEX_E;
09301     }
09302 
09303 #ifdef HAVE_EXT_CACHE
09304     if (error == 0 && ssl->ctx->new_sess_cb != NULL)
09305         ssl->ctx->new_sess_cb(ssl, session);
09306     if (ssl->options.internalCacheOff)
09307         wolfSSL_SESSION_free(session);
09308 #endif
09309 
09310     return error;
09311 }
09312 
09313 
09314 #ifdef SESSION_INDEX
09315 
09316 int wolfSSL_GetSessionIndex(WOLFSSL* ssl)
09317 {
09318     WOLFSSL_ENTER("wolfSSL_GetSessionIndex");
09319     WOLFSSL_LEAVE("wolfSSL_GetSessionIndex", ssl->sessionIndex);
09320     return ssl->sessionIndex;
09321 }
09322 
09323 
09324 int wolfSSL_GetSessionAtIndex(int idx, WOLFSSL_SESSION* session)
09325 {
09326     int row, col, result = SSL_FAILURE;
09327 
09328     WOLFSSL_ENTER("wolfSSL_GetSessionAtIndex");
09329 
09330     row = idx >> SESSIDX_ROW_SHIFT;
09331     col = idx & SESSIDX_IDX_MASK;
09332 
09333     if (wc_LockMutex(&session_mutex) != 0) {
09334         return BAD_MUTEX_E;
09335     }
09336 
09337     if (row < SESSION_ROWS &&
09338         col < (int)min(SessionCache[row].totalCount, SESSIONS_PER_ROW)) {
09339         XMEMCPY(session,
09340                  &SessionCache[row].Sessions[col], sizeof(WOLFSSL_SESSION));
09341         result = SSL_SUCCESS;
09342     }
09343 
09344     if (wc_UnLockMutex(&session_mutex) != 0)
09345         result = BAD_MUTEX_E;
09346 
09347     WOLFSSL_LEAVE("wolfSSL_GetSessionAtIndex", result);
09348     return result;
09349 }
09350 
09351 #endif /* SESSION_INDEX */
09352 
09353 #if defined(SESSION_INDEX) && defined(SESSION_CERTS)
09354 
09355 WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session)
09356 {
09357     WOLFSSL_X509_CHAIN* chain = NULL;
09358 
09359     WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
09360     if (session)
09361         chain = &session->chain;
09362 
09363     WOLFSSL_LEAVE("wolfSSL_SESSION_get_peer_chain", chain ? 1 : 0);
09364     return chain;
09365 }
09366 
09367 #endif /* SESSION_INDEX && SESSION_CERTS */
09368 
09369 
09370 #ifdef WOLFSSL_SESSION_STATS
09371 
09372 /* requires session_mutex lock held, SSL_SUCCESS on ok */
09373 static int get_locked_session_stats(word32* active, word32* total, word32* peak)
09374 {
09375     int result = SSL_SUCCESS;
09376     int i;
09377     int count;
09378     int idx;
09379     word32 now   = 0;
09380     word32 seen  = 0;
09381     word32 ticks = LowResTimer();
09382 
09383     (void)peak;
09384 
09385     WOLFSSL_ENTER("get_locked_session_stats");
09386 
09387     for (i = 0; i < SESSION_ROWS; i++) {
09388         seen += SessionCache[i].totalCount;
09389 
09390         if (active == NULL)
09391             continue;  /* no need to calculate what we can't set */
09392 
09393         count = min((word32)SessionCache[i].totalCount, SESSIONS_PER_ROW);
09394         idx   = SessionCache[i].nextIdx - 1;
09395         if (idx < 0)
09396             idx = SESSIONS_PER_ROW - 1; /* if back to front previous was end */
09397 
09398         for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
09399             if (idx >= SESSIONS_PER_ROW || idx < 0) {  /* sanity check */
09400                 WOLFSSL_MSG("Bad idx");
09401                 break;
09402             }
09403 
09404             /* if not expried then good */
09405             if (ticks < (SessionCache[i].Sessions[idx].bornOn +
09406                          SessionCache[i].Sessions[idx].timeout) ) {
09407                 now++;
09408             }
09409         }
09410     }
09411 
09412     if (active)
09413         *active = now;
09414 
09415     if (total)
09416         *total = seen;
09417 
09418 #ifdef WOLFSSL_PEAK_SESSIONS
09419     if (peak)
09420         *peak = PeakSessions;
09421 #endif
09422 
09423     WOLFSSL_LEAVE("get_locked_session_stats", result);
09424 
09425     return result;
09426 }
09427 
09428 
09429 /* return SSL_SUCCESS on ok */
09430 int wolfSSL_get_session_stats(word32* active, word32* total, word32* peak,
09431                               word32* maxSessions)
09432 {
09433     int result = SSL_SUCCESS;
09434 
09435     WOLFSSL_ENTER("wolfSSL_get_session_stats");
09436 
09437     if (maxSessions) {
09438         *maxSessions = SESSIONS_PER_ROW * SESSION_ROWS;
09439 
09440         if (active == NULL && total == NULL && peak == NULL)
09441             return result;  /* we're done */
09442     }
09443 
09444     /* user must provide at least one query value */
09445     if (active == NULL && total == NULL && peak == NULL)
09446         return BAD_FUNC_ARG;
09447 
09448     if (wc_LockMutex(&session_mutex) != 0) {
09449         return BAD_MUTEX_E;
09450     }
09451 
09452     result = get_locked_session_stats(active, total, peak);
09453 
09454     if (wc_UnLockMutex(&session_mutex) != 0)
09455         result = BAD_MUTEX_E;
09456 
09457     WOLFSSL_LEAVE("wolfSSL_get_session_stats", result);
09458 
09459     return result;
09460 }
09461 
09462 #endif /* WOLFSSL_SESSION_STATS */
09463 
09464 
09465     #ifdef PRINT_SESSION_STATS
09466 
09467     /* SSL_SUCCESS on ok */
09468     int wolfSSL_PrintSessionStats(void)
09469     {
09470         word32 totalSessionsSeen = 0;
09471         word32 totalSessionsNow = 0;
09472         word32 peak = 0;
09473         word32 maxSessions = 0;
09474         int    i;
09475         int    ret;
09476         double E;               /* expected freq */
09477         double chiSquare = 0;
09478 
09479         ret = wolfSSL_get_session_stats(&totalSessionsNow, &totalSessionsSeen,
09480                                         &peak, &maxSessions);
09481         if (ret != SSL_SUCCESS)
09482             return ret;
09483         printf("Total Sessions Seen = %d\n", totalSessionsSeen);
09484         printf("Total Sessions Now  = %d\n", totalSessionsNow);
09485 #ifdef WOLFSSL_PEAK_SESSIONS
09486         printf("Peak  Sessions      = %d\n", peak);
09487 #endif
09488         printf("Max   Sessions      = %d\n", maxSessions);
09489 
09490         E = (double)totalSessionsSeen / SESSION_ROWS;
09491 
09492         for (i = 0; i < SESSION_ROWS; i++) {
09493             double diff = SessionCache[i].totalCount - E;
09494             diff *= diff;                /* square    */
09495             diff /= E;                   /* normalize */
09496 
09497             chiSquare += diff;
09498         }
09499         printf("  chi-square = %5.1f, d.f. = %d\n", chiSquare,
09500                                                      SESSION_ROWS - 1);
09501         #if (SESSION_ROWS == 11)
09502             printf(" .05 p value =  18.3, chi-square should be less\n");
09503         #elif (SESSION_ROWS == 211)
09504             printf(".05 p value  = 244.8, chi-square should be less\n");
09505         #elif (SESSION_ROWS == 5981)
09506             printf(".05 p value  = 6161.0, chi-square should be less\n");
09507         #elif (SESSION_ROWS == 3)
09508             printf(".05 p value  =   6.0, chi-square should be less\n");
09509         #elif (SESSION_ROWS == 2861)
09510             printf(".05 p value  = 2985.5, chi-square should be less\n");
09511         #endif
09512         printf("\n");
09513 
09514         return ret;
09515     }
09516 
09517     #endif /* SESSION_STATS */
09518 
09519 #else  /* NO_SESSION_CACHE */
09520 
09521 /* No session cache version */
09522 WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
09523         byte restoreSessionCerts)
09524 {
09525     (void)ssl;
09526     (void)masterSecret;
09527     (void)restoreSessionCerts;
09528 
09529     return NULL;
09530 }
09531 
09532 #endif /* NO_SESSION_CACHE */
09533 
09534 
09535 /* call before SSL_connect, if verifying will add name check to
09536    date check and signature check */
09537 int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
09538 {
09539     WOLFSSL_ENTER("wolfSSL_check_domain_name");
09540     if (ssl->buffers.domainName.buffer)
09541         XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
09542 
09543     ssl->buffers.domainName.length = (word32)XSTRLEN(dn) + 1;
09544     ssl->buffers.domainName.buffer = (byte*) XMALLOC(
09545                 ssl->buffers.domainName.length, ssl->heap, DYNAMIC_TYPE_DOMAIN);
09546 
09547     if (ssl->buffers.domainName.buffer) {
09548         XSTRNCPY((char*)ssl->buffers.domainName.buffer, dn,
09549                 ssl->buffers.domainName.length);
09550         return SSL_SUCCESS;
09551     }
09552     else {
09553         ssl->error = MEMORY_ERROR;
09554         return SSL_FAILURE;
09555     }
09556 }
09557 
09558 
09559 /* turn on wolfSSL zlib compression
09560    returns SSL_SUCCESS for success, else error (not built in)
09561 */
09562 int wolfSSL_set_compression(WOLFSSL* ssl)
09563 {
09564     WOLFSSL_ENTER("wolfSSL_set_compression");
09565     (void)ssl;
09566 #ifdef HAVE_LIBZ
09567     ssl->options.usingCompression = 1;
09568     return SSL_SUCCESS;
09569 #else
09570     return NOT_COMPILED_IN;
09571 #endif
09572 }
09573 
09574 
09575 #ifndef USE_WINDOWS_API
09576     #ifndef NO_WRITEV
09577 
09578         /* simulate writev semantics, doesn't actually do block at a time though
09579            because of SSL_write behavior and because front adds may be small */
09580         int wolfSSL_writev(WOLFSSL* ssl, const struct iovec* iov, int iovcnt)
09581         {
09582         #ifdef WOLFSSL_SMALL_STACK
09583             byte   staticBuffer[1]; /* force heap usage */
09584         #else
09585             byte   staticBuffer[FILE_BUFFER_SIZE];
09586         #endif
09587             byte* myBuffer  = staticBuffer;
09588             int   dynamic   = 0;
09589             int   sending   = 0;
09590             int   idx       = 0;
09591             int   i;
09592             int   ret;
09593 
09594             WOLFSSL_ENTER("wolfSSL_writev");
09595 
09596             for (i = 0; i < iovcnt; i++)
09597                 sending += (int)iov[i].iov_len;
09598 
09599             if (sending > (int)sizeof(staticBuffer)) {
09600                 myBuffer = (byte*)XMALLOC(sending, ssl->heap,
09601                                                            DYNAMIC_TYPE_WRITEV);
09602                 if (!myBuffer)
09603                     return MEMORY_ERROR;
09604 
09605                 dynamic = 1;
09606             }
09607 
09608             for (i = 0; i < iovcnt; i++) {
09609                 XMEMCPY(&myBuffer[idx], iov[i].iov_base, iov[i].iov_len);
09610                 idx += (int)iov[i].iov_len;
09611             }
09612 
09613             ret = wolfSSL_write(ssl, myBuffer, sending);
09614 
09615             if (dynamic)
09616                 XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
09617 
09618             return ret;
09619         }
09620     #endif
09621 #endif
09622 
09623 
09624 #ifdef WOLFSSL_CALLBACKS
09625 
09626     typedef struct itimerval Itimerval;
09627 
09628     /* don't keep calling simple functions while setting up timer and signals
09629        if no inlining these are the next best */
09630 
09631     #define AddTimes(a, b, c)                       \
09632         do {                                        \
09633             c.tv_sec  = a.tv_sec  + b.tv_sec;       \
09634             c.tv_usec = a.tv_usec + b.tv_usec;      \
09635             if (c.tv_usec >=  1000000) {            \
09636                 c.tv_sec++;                         \
09637                 c.tv_usec -= 1000000;               \
09638             }                                       \
09639         } while (0)
09640 
09641 
09642     #define SubtractTimes(a, b, c)                  \
09643         do {                                        \
09644             c.tv_sec  = a.tv_sec  - b.tv_sec;       \
09645             c.tv_usec = a.tv_usec - b.tv_usec;      \
09646             if (c.tv_usec < 0) {                    \
09647                 c.tv_sec--;                         \
09648                 c.tv_usec += 1000000;               \
09649             }                                       \
09650         } while (0)
09651 
09652     #define CmpTimes(a, b, cmp)                     \
09653         ((a.tv_sec  ==  b.tv_sec) ?                 \
09654             (a.tv_usec cmp b.tv_usec) :             \
09655             (a.tv_sec  cmp b.tv_sec))               \
09656 
09657 
09658     /* do nothing handler */
09659     static void myHandler(int signo)
09660     {
09661         (void)signo;
09662         return;
09663     }
09664 
09665 
09666     static int wolfSSL_ex_wrapper(WOLFSSL* ssl, HandShakeCallBack hsCb,
09667                                  TimeoutCallBack toCb, Timeval timeout)
09668     {
09669         int       ret        = SSL_FATAL_ERROR;
09670         int       oldTimerOn = 0;   /* was timer already on */
09671         Timeval   startTime;
09672         Timeval   endTime;
09673         Timeval   totalTime;
09674         Itimerval myTimeout;
09675         Itimerval oldTimeout; /* if old timer adjust from total time to reset */
09676         struct sigaction act, oact;
09677 
09678         #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
09679 
09680         if (hsCb) {
09681             ssl->hsInfoOn = 1;
09682             InitHandShakeInfo(&ssl->handShakeInfo, ssl);
09683         }
09684         if (toCb) {
09685             ssl->toInfoOn = 1;
09686             InitTimeoutInfo(&ssl->timeoutInfo);
09687 
09688             if (gettimeofday(&startTime, 0) < 0)
09689                 ERR_OUT(GETTIME_ERROR);
09690 
09691             /* use setitimer to simulate getitimer, init 0 myTimeout */
09692             myTimeout.it_interval.tv_sec  = 0;
09693             myTimeout.it_interval.tv_usec = 0;
09694             myTimeout.it_value.tv_sec     = 0;
09695             myTimeout.it_value.tv_usec    = 0;
09696             if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
09697                 ERR_OUT(SETITIMER_ERROR);
09698 
09699             if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
09700                 oldTimerOn = 1;
09701 
09702                 /* is old timer going to expire before ours */
09703                 if (CmpTimes(oldTimeout.it_value, timeout, <)) {
09704                     timeout.tv_sec  = oldTimeout.it_value.tv_sec;
09705                     timeout.tv_usec = oldTimeout.it_value.tv_usec;
09706                 }
09707             }
09708             myTimeout.it_value.tv_sec  = timeout.tv_sec;
09709             myTimeout.it_value.tv_usec = timeout.tv_usec;
09710 
09711             /* set up signal handler, don't restart socket send/recv */
09712             act.sa_handler = myHandler;
09713             sigemptyset(&act.sa_mask);
09714             act.sa_flags = 0;
09715 #ifdef SA_INTERRUPT
09716             act.sa_flags |= SA_INTERRUPT;
09717 #endif
09718             if (sigaction(SIGALRM, &act, &oact) < 0)
09719                 ERR_OUT(SIGACT_ERROR);
09720 
09721             if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
09722                 ERR_OUT(SETITIMER_ERROR);
09723         }
09724 
09725         /* do main work */
09726 #ifndef NO_WOLFSSL_CLIENT
09727         if (ssl->options.side == WOLFSSL_CLIENT_END)
09728             ret = wolfSSL_connect(ssl);
09729 #endif
09730 #ifndef NO_WOLFSSL_SERVER
09731         if (ssl->options.side == WOLFSSL_SERVER_END)
09732             ret = wolfSSL_accept(ssl);
09733 #endif
09734 
09735         /* do callbacks */
09736         if (toCb) {
09737             if (oldTimerOn) {
09738                 gettimeofday(&endTime, 0);
09739                 SubtractTimes(endTime, startTime, totalTime);
09740                 /* adjust old timer for elapsed time */
09741                 if (CmpTimes(totalTime, oldTimeout.it_value, <))
09742                     SubtractTimes(oldTimeout.it_value, totalTime,
09743                                   oldTimeout.it_value);
09744                 else {
09745                     /* reset value to interval, may be off */
09746                     oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
09747                     oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
09748                 }
09749                 /* keep iter the same whether there or not */
09750             }
09751             /* restore old handler */
09752             if (sigaction(SIGALRM, &oact, 0) < 0)
09753                 ret = SIGACT_ERROR;    /* more pressing error, stomp */
09754             else
09755                 /* use old settings which may turn off (expired or not there) */
09756                 if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
09757                     ret = SETITIMER_ERROR;
09758 
09759             /* if we had a timeout call callback */
09760             if (ssl->timeoutInfo.timeoutName[0]) {
09761                 ssl->timeoutInfo.timeoutValue.tv_sec  = timeout.tv_sec;
09762                 ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
09763                 (toCb)(&ssl->timeoutInfo);
09764             }
09765             /* clean up */
09766             FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
09767             ssl->toInfoOn = 0;
09768         }
09769         if (hsCb) {
09770             FinishHandShakeInfo(&ssl->handShakeInfo);
09771             (hsCb)(&ssl->handShakeInfo);
09772             ssl->hsInfoOn = 0;
09773         }
09774         return ret;
09775     }
09776 
09777 
09778 #ifndef NO_WOLFSSL_CLIENT
09779 
09780     int wolfSSL_connect_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
09781                           TimeoutCallBack toCb, Timeval timeout)
09782     {
09783         WOLFSSL_ENTER("wolfSSL_connect_ex");
09784         return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
09785     }
09786 
09787 #endif
09788 
09789 
09790 #ifndef NO_WOLFSSL_SERVER
09791 
09792     int wolfSSL_accept_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
09793                          TimeoutCallBack toCb,Timeval timeout)
09794     {
09795         WOLFSSL_ENTER("wolfSSL_accept_ex");
09796         return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
09797     }
09798 
09799 #endif
09800 
09801 #endif /* WOLFSSL_CALLBACKS */
09802 
09803 
09804 #ifndef NO_PSK
09805 
09806     void wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX* ctx,
09807                                          wc_psk_client_callback cb)
09808     {
09809         WOLFSSL_ENTER("SSL_CTX_set_psk_client_callback");
09810         ctx->havePSK = 1;
09811         ctx->client_psk_cb = cb;
09812     }
09813 
09814 
09815     void wolfSSL_set_psk_client_callback(WOLFSSL* ssl,wc_psk_client_callback cb)
09816     {
09817         byte haveRSA = 1;
09818 
09819         WOLFSSL_ENTER("SSL_set_psk_client_callback");
09820         ssl->options.havePSK = 1;
09821         ssl->options.client_psk_cb = cb;
09822 
09823         #ifdef NO_RSA
09824             haveRSA = 0;
09825         #endif
09826         InitSuites(ssl->suites, ssl->version, haveRSA, TRUE,
09827                    ssl->options.haveDH, ssl->options.haveNTRU,
09828                    ssl->options.haveECDSAsig, ssl->options.haveECC,
09829                    ssl->options.haveStaticECC, ssl->options.side);
09830     }
09831 
09832 
09833     void wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX* ctx,
09834                                          wc_psk_server_callback cb)
09835     {
09836         WOLFSSL_ENTER("SSL_CTX_set_psk_server_callback");
09837         ctx->havePSK = 1;
09838         ctx->server_psk_cb = cb;
09839     }
09840 
09841 
09842     void wolfSSL_set_psk_server_callback(WOLFSSL* ssl,wc_psk_server_callback cb)
09843     {
09844         byte haveRSA = 1;
09845 
09846         WOLFSSL_ENTER("SSL_set_psk_server_callback");
09847         ssl->options.havePSK = 1;
09848         ssl->options.server_psk_cb = cb;
09849 
09850         #ifdef NO_RSA
09851             haveRSA = 0;
09852         #endif
09853         InitSuites(ssl->suites, ssl->version, haveRSA, TRUE,
09854                    ssl->options.haveDH, ssl->options.haveNTRU,
09855                    ssl->options.haveECDSAsig, ssl->options.haveECC,
09856                    ssl->options.haveStaticECC, ssl->options.side);
09857     }
09858 
09859 
09860     const char* wolfSSL_get_psk_identity_hint(const WOLFSSL* ssl)
09861     {
09862         WOLFSSL_ENTER("SSL_get_psk_identity_hint");
09863 
09864         if (ssl == NULL || ssl->arrays == NULL)
09865             return NULL;
09866 
09867         return ssl->arrays->server_hint;
09868     }
09869 
09870 
09871     const char* wolfSSL_get_psk_identity(const WOLFSSL* ssl)
09872     {
09873         WOLFSSL_ENTER("SSL_get_psk_identity");
09874 
09875         if (ssl == NULL || ssl->arrays == NULL)
09876             return NULL;
09877 
09878         return ssl->arrays->client_identity;
09879     }
09880 
09881 
09882     int wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX* ctx, const char* hint)
09883     {
09884         WOLFSSL_ENTER("SSL_CTX_use_psk_identity_hint");
09885         if (hint == 0)
09886             ctx->server_hint[0] = 0;
09887         else {
09888             XSTRNCPY(ctx->server_hint, hint, sizeof(ctx->server_hint));
09889             ctx->server_hint[MAX_PSK_ID_LEN] = '\0'; /* null term */
09890         }
09891         return SSL_SUCCESS;
09892     }
09893 
09894 
09895     int wolfSSL_use_psk_identity_hint(WOLFSSL* ssl, const char* hint)
09896     {
09897         WOLFSSL_ENTER("SSL_use_psk_identity_hint");
09898 
09899         if (ssl == NULL || ssl->arrays == NULL)
09900             return SSL_FAILURE;
09901 
09902         if (hint == 0)
09903             ssl->arrays->server_hint[0] = 0;
09904         else {
09905             XSTRNCPY(ssl->arrays->server_hint, hint,
09906                                             sizeof(ssl->arrays->server_hint));
09907             ssl->arrays->server_hint[MAX_PSK_ID_LEN] = '\0'; /* null term */
09908         }
09909         return SSL_SUCCESS;
09910     }
09911 
09912 #endif /* NO_PSK */
09913 
09914 
09915 #ifdef HAVE_ANON
09916 
09917     int wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX* ctx)
09918     {
09919         WOLFSSL_ENTER("wolfSSL_CTX_allow_anon_cipher");
09920 
09921         if (ctx == NULL)
09922             return SSL_FAILURE;
09923 
09924         ctx->haveAnon = 1;
09925 
09926         return SSL_SUCCESS;
09927     }
09928 
09929 #endif /* HAVE_ANON */
09930 
09931 
09932 #ifndef NO_CERTS
09933 /* used to be defined on NO_FILESYSTEM only, but are generally useful */
09934 
09935     /* wolfSSL extension allows DER files to be loaded from buffers as well */
09936     int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX* ctx,
09937                                        const unsigned char* in,
09938                                        long sz, int format)
09939     {
09940         WOLFSSL_ENTER("wolfSSL_CTX_load_verify_buffer");
09941         if (format == SSL_FILETYPE_PEM)
09942             return ProcessChainBuffer(ctx, in, sz, format, CA_TYPE, NULL);
09943         else
09944             return ProcessBuffer(ctx, in, sz, format, CA_TYPE, NULL,NULL,0);
09945     }
09946 
09947 
09948 #ifdef WOLFSSL_TRUST_PEER_CERT
09949     int wolfSSL_CTX_trust_peer_buffer(WOLFSSL_CTX* ctx,
09950                                        const unsigned char* in,
09951                                        long sz, int format)
09952     {
09953         WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_buffer");
09954 
09955         /* sanity check on arguments */
09956         if (sz < 0 || in == NULL || ctx == NULL) {
09957             return BAD_FUNC_ARG;
09958         }
09959 
09960         if (format == SSL_FILETYPE_PEM)
09961             return ProcessChainBuffer(ctx, in, sz, format,
09962                                                        TRUSTED_PEER_TYPE, NULL);
09963         else
09964             return ProcessBuffer(ctx, in, sz, format, TRUSTED_PEER_TYPE,
09965                                                                    NULL,NULL,0);
09966     }
09967 #endif /* WOLFSSL_TRUST_PEER_CERT */
09968 
09969 
09970     int wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX* ctx,
09971                                  const unsigned char* in, long sz, int format)
09972     {
09973         WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_buffer");
09974         return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 0);
09975     }
09976 
09977 
09978     int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX* ctx,
09979                                  const unsigned char* in, long sz, int format)
09980     {
09981         WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_buffer");
09982         return ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL,NULL,0);
09983     }
09984 
09985 
09986     int wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX* ctx,
09987                                  const unsigned char* in, long sz, int format)
09988     {
09989         WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_buffer_format");
09990         return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 1);
09991     }
09992 
09993     int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
09994                                  const unsigned char* in, long sz)
09995     {
09996         return wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, in, sz,
09997                                                             SSL_FILETYPE_PEM);
09998     }
09999 
10000 
10001 #ifndef NO_DH
10002 
10003     /* server wrapper for ctx or ssl Diffie-Hellman parameters */
10004     static int wolfSSL_SetTmpDH_buffer_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
10005                                                const unsigned char* buf,
10006                                                long sz, int format)
10007     {
10008         DerBuffer* der = NULL;
10009         int    ret      = 0;
10010         word32 pSz = MAX_DH_SIZE;
10011         word32 gSz = MAX_DH_SIZE;
10012     #ifdef WOLFSSL_SMALL_STACK
10013         byte*  p = NULL;
10014         byte*  g = NULL;
10015     #else
10016         byte   p[MAX_DH_SIZE];
10017         byte   g[MAX_DH_SIZE];
10018     #endif
10019 
10020         if (ctx == NULL || buf == NULL)
10021             return BAD_FUNC_ARG;
10022 
10023         ret = AllocDer(&der, 0, DH_PARAM_TYPE, ctx->heap);
10024         if (ret != 0) {
10025             return ret;
10026         }
10027         der->buffer = (byte*)buf;
10028         der->length = (word32)sz;
10029 
10030     #ifdef WOLFSSL_SMALL_STACK
10031         p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10032         g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10033 
10034         if (p == NULL || g == NULL) {
10035             XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10036             XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10037             return MEMORY_E;
10038         }
10039     #endif
10040 
10041         if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM)
10042             ret = SSL_BAD_FILETYPE;
10043         else {
10044             if (format == SSL_FILETYPE_PEM) {
10045                 FreeDer(&der);
10046                 ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap,
10047                                NULL, NULL);
10048 #ifdef WOLFSSL_WPAS
10049     #ifndef NO_DSA
10050                 if (ret < 0) {
10051                     ret = PemToDer(buf, sz, DSA_PARAM_TYPE, &der, ctx->heap,
10052                                NULL, NULL);
10053                 }
10054     #endif
10055 #endif
10056             }
10057 
10058             if (ret == 0) {
10059                 if (wc_DhParamsLoad(der->buffer, der->length, p, &pSz, g, &gSz) < 0)
10060                     ret = SSL_BAD_FILETYPE;
10061                 else if (ssl)
10062                     ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
10063                 else
10064                     ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
10065             }
10066         }
10067 
10068         FreeDer(&der);
10069 
10070     #ifdef WOLFSSL_SMALL_STACK
10071         XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10072         XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10073     #endif
10074 
10075         return ret;
10076     }
10077 
10078 
10079     /* server Diffie-Hellman parameters, SSL_SUCCESS on ok */
10080     int wolfSSL_SetTmpDH_buffer(WOLFSSL* ssl, const unsigned char* buf, long sz,
10081                                int format)
10082     {
10083         if (ssl == NULL)
10084             return BAD_FUNC_ARG;
10085 
10086         return wolfSSL_SetTmpDH_buffer_wrapper(ssl->ctx, ssl, buf, sz, format);
10087     }
10088 
10089 
10090     /* server ctx Diffie-Hellman parameters, SSL_SUCCESS on ok */
10091     int wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX* ctx, const unsigned char* buf,
10092                                    long sz, int format)
10093     {
10094         return wolfSSL_SetTmpDH_buffer_wrapper(ctx, NULL, buf, sz, format);
10095     }
10096 
10097 #endif /* NO_DH */
10098 
10099 
10100     int wolfSSL_use_certificate_buffer(WOLFSSL* ssl,
10101                                  const unsigned char* in, long sz, int format)
10102     {
10103         WOLFSSL_ENTER("wolfSSL_use_certificate_buffer");
10104         return ProcessBuffer(ssl->ctx, in, sz, format,CERT_TYPE,ssl,NULL,0);
10105     }
10106 
10107 
10108     int wolfSSL_use_PrivateKey_buffer(WOLFSSL* ssl,
10109                                  const unsigned char* in, long sz, int format)
10110     {
10111         WOLFSSL_ENTER("wolfSSL_use_PrivateKey_buffer");
10112         return ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE,
10113                              ssl, NULL, 0);
10114     }
10115 
10116     int wolfSSL_use_certificate_chain_buffer_format(WOLFSSL* ssl,
10117                                  const unsigned char* in, long sz, int format)
10118     {
10119         WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer_format");
10120         return ProcessBuffer(ssl->ctx, in, sz, format, CERT_TYPE,
10121                              ssl, NULL, 1);
10122     }
10123 
10124     int wolfSSL_use_certificate_chain_buffer(WOLFSSL* ssl,
10125                                  const unsigned char* in, long sz)
10126     {
10127         return wolfSSL_use_certificate_chain_buffer_format(ssl, in, sz,
10128                                                             SSL_FILETYPE_PEM);
10129     }
10130 
10131 
10132     /* unload any certs or keys that SSL owns, leave CTX as is
10133        SSL_SUCCESS on ok */
10134     int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl)
10135     {
10136         if (ssl == NULL) {
10137             WOLFSSL_MSG("Null function arg");
10138             return BAD_FUNC_ARG;
10139         }
10140 
10141         if (ssl->buffers.weOwnCert && !ssl->keepCert) {
10142             WOLFSSL_MSG("Unloading cert");
10143             FreeDer(&ssl->buffers.certificate);
10144             #ifdef KEEP_OUR_CERT
10145                 FreeX509(ssl->ourCert);
10146                 if (ssl->ourCert) {
10147                     XFREE(ssl->ourCert, ssl->heap, DYNAMIC_TYPE_X509);
10148                     ssl->ourCert = NULL;
10149                 }
10150             #endif
10151             ssl->buffers.weOwnCert = 0;
10152         }
10153 
10154         if (ssl->buffers.weOwnCertChain) {
10155             WOLFSSL_MSG("Unloading cert chain");
10156             FreeDer(&ssl->buffers.certChain);
10157             ssl->buffers.weOwnCertChain = 0;
10158         }
10159 
10160         if (ssl->buffers.weOwnKey) {
10161             WOLFSSL_MSG("Unloading key");
10162             FreeDer(&ssl->buffers.key);
10163             ssl->buffers.weOwnKey = 0;
10164         }
10165 
10166         return SSL_SUCCESS;
10167     }
10168 
10169 
10170     int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx)
10171     {
10172         WOLFSSL_ENTER("wolfSSL_CTX_UnloadCAs");
10173 
10174         if (ctx == NULL)
10175             return BAD_FUNC_ARG;
10176 
10177         return wolfSSL_CertManagerUnloadCAs(ctx->cm);
10178     }
10179 
10180 
10181 #ifdef WOLFSSL_TRUST_PEER_CERT
10182     int wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX* ctx)
10183     {
10184         WOLFSSL_ENTER("wolfSSL_CTX_Unload_trust_peers");
10185 
10186         if (ctx == NULL)
10187             return BAD_FUNC_ARG;
10188 
10189         return wolfSSL_CertManagerUnload_trust_peers(ctx->cm);
10190     }
10191 #endif /* WOLFSSL_TRUST_PEER_CERT */
10192 /* old NO_FILESYSTEM end */
10193 #endif /* !NO_CERTS */
10194 
10195 
10196 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
10197 
10198 
10199     int wolfSSL_add_all_algorithms(void)
10200     {
10201         WOLFSSL_ENTER("wolfSSL_add_all_algorithms");
10202         if (wolfSSL_Init() == SSL_SUCCESS)
10203             return SSL_SUCCESS;
10204         else
10205             return SSL_FATAL_ERROR;
10206     }
10207 
10208 
10209    /* returns previous set cache size which stays constant */
10210     long wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX* ctx, long sz)
10211     {
10212         /* cache size fixed at compile time in wolfSSL */
10213         (void)ctx;
10214         (void)sz;
10215         WOLFSSL_MSG("session cache is set at compile time");
10216         #ifndef NO_SESSION_CACHE
10217             return SESSIONS_PER_ROW * SESSION_ROWS;
10218         #else
10219             return 0;
10220         #endif
10221     }
10222 
10223 
10224     void wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX* ctx, int mode)
10225     {
10226         WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
10227         if (mode)
10228             ctx->quietShutdown = 1;
10229     }
10230 
10231 
10232     void wolfSSL_set_quiet_shutdown(WOLFSSL* ssl, int mode)
10233     {
10234         WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
10235         if (mode)
10236             ssl->options.quietShutdown = 1;
10237     }
10238 
10239 
10240     void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr)
10241     {
10242         WOLFSSL_ENTER("SSL_set_bio");
10243         wolfSSL_set_rfd(ssl, rd->fd);
10244         wolfSSL_set_wfd(ssl, wr->fd);
10245 
10246         ssl->biord = rd;
10247         ssl->biowr = wr;
10248     }
10249 
10250 
10251     void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX* ctx,
10252                                        STACK_OF(WOLFSSL_X509_NAME)* names)
10253     {
10254         WOLFSSL_ENTER("wolfSSL_SSL_CTX_set_client_CA_list");
10255 
10256         if (ctx != NULL)
10257             ctx->ca_names = names;
10258     }
10259 
10260     STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_SSL_CTX_get_client_CA_list(
10261             const WOLFSSL_CTX *s)
10262     {
10263         WOLFSSL_ENTER("wolfSSL_SSL_CTX_get_client_CA_list");
10264 
10265         if (s == NULL)
10266             return NULL;
10267 
10268         return s->ca_names;
10269     }
10270 
10271     STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char* fname)
10272     {
10273         WOLFSSL_STACK *list = NULL;
10274         WOLFSSL_STACK *node;
10275         WOLFSSL_BIO* bio;
10276         WOLFSSL_X509 *cert = NULL;
10277         WOLFSSL_X509_NAME *subjectName = NULL;
10278 
10279         WOLFSSL_ENTER("wolfSSL_load_client_CA_file");
10280 
10281         bio = wolfSSL_BIO_new_file(fname, "r");
10282         if (bio == NULL)
10283             return NULL;
10284 
10285         /* Read each certificate in the chain out of the file. */
10286         while (wolfSSL_PEM_read_bio_X509(bio, &cert, NULL, NULL) != NULL) {
10287             subjectName = wolfSSL_X509_get_subject_name(cert);
10288             if (subjectName == NULL)
10289                 break;
10290 
10291             node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
10292                                            DYNAMIC_TYPE_OPENSSL);
10293             if (node == NULL)
10294                 break;
10295 
10296             /* Need a persistent copy of the subject name. */
10297             node->data.name = (WOLFSSL_X509_NAME*)XMALLOC(
10298                     sizeof(WOLFSSL_X509_NAME), NULL, DYNAMIC_TYPE_OPENSSL);
10299             if (node->data.name == NULL) {
10300                 XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
10301                 break;
10302             }
10303             XMEMCPY(node->data.name, subjectName, sizeof(WOLFSSL_X509_NAME));
10304             /* Clear pointers so freeing certificate doesn't free memory. */
10305             XMEMSET(subjectName, 0, sizeof(WOLFSSL_X509_NAME));
10306 
10307             /* Put node on the front of the list. */
10308             node->num  = (list == NULL) ? 1 : list->num + 1;
10309             node->next = list;
10310             list = node;
10311 
10312             wolfSSL_X509_free(cert);
10313             cert = NULL;
10314         }
10315 
10316         wolfSSL_X509_free(cert);
10317         wolfSSL_BIO_free(bio);
10318         return list;
10319     }
10320 
10321 
10322     int wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX* ctx)
10323     {
10324         /* TODO:, not needed in goahead */
10325         (void)ctx;
10326         return SSL_NOT_IMPLEMENTED;
10327     }
10328 
10329 
10330     /* keyblock size in bytes or -1 */
10331     int wolfSSL_get_keyblock_size(WOLFSSL* ssl)
10332     {
10333         if (ssl == NULL)
10334             return SSL_FATAL_ERROR;
10335 
10336         return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
10337                     ssl->specs.hash_size);
10338     }
10339 
10340 
10341     /* store keys returns SSL_SUCCESS or -1 on error */
10342     int wolfSSL_get_keys(WOLFSSL* ssl, unsigned char** ms, unsigned int* msLen,
10343                                      unsigned char** sr, unsigned int* srLen,
10344                                      unsigned char** cr, unsigned int* crLen)
10345     {
10346         if (ssl == NULL || ssl->arrays == NULL)
10347             return SSL_FATAL_ERROR;
10348 
10349         *ms = ssl->arrays->masterSecret;
10350         *sr = ssl->arrays->serverRandom;
10351         *cr = ssl->arrays->clientRandom;
10352 
10353         *msLen = SECRET_LEN;
10354         *srLen = RAN_LEN;
10355         *crLen = RAN_LEN;
10356 
10357         return SSL_SUCCESS;
10358     }
10359 
10360 
10361     void wolfSSL_set_accept_state(WOLFSSL* ssl)
10362     {
10363         word16 haveRSA = 1;
10364         word16 havePSK = 0;
10365 
10366         WOLFSSL_ENTER("SSL_set_accept_state");
10367         if (ssl->options.side == WOLFSSL_CLIENT_END) {
10368     #ifdef HAVE_ECC
10369             ecc_key key;
10370             word32 idx = 0;
10371 
10372             if (ssl->options.haveStaticECC && ssl->buffers.key != NULL) {
10373                 wc_ecc_init(&key);
10374                 if (wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &idx, &key,
10375                                                ssl->buffers.key->length) != 0) {
10376                     ssl->options.haveECDSAsig = 0;
10377                     ssl->options.haveECC = 0;
10378                     ssl->options.haveStaticECC = 0;
10379                 }
10380                 wc_ecc_free(&key);
10381             }
10382     #endif
10383 
10384     #ifndef NO_DH
10385             if (!ssl->options.haveDH && ssl->ctx->haveDH) {
10386                 ssl->buffers.serverDH_P = ssl->ctx->serverDH_P;
10387                 ssl->buffers.serverDH_G = ssl->ctx->serverDH_G;
10388                 ssl->options.haveDH = 1;
10389             }
10390     #endif
10391         }
10392         ssl->options.side = WOLFSSL_SERVER_END;
10393         /* reset suites in case user switched */
10394 
10395         #ifdef NO_RSA
10396             haveRSA = 0;
10397         #endif
10398         #ifndef NO_PSK
10399             havePSK = ssl->options.havePSK;
10400         #endif
10401         InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
10402                    ssl->options.haveDH, ssl->options.haveNTRU,
10403                    ssl->options.haveECDSAsig, ssl->options.haveECC,
10404                    ssl->options.haveStaticECC, ssl->options.side);
10405     }
10406 #endif
10407 
10408     /* return true if connection established */
10409     int wolfSSL_is_init_finished(WOLFSSL* ssl)
10410     {
10411         if (ssl == NULL)
10412             return 0;
10413 
10414         if (ssl->options.handShakeState == HANDSHAKE_DONE)
10415             return 1;
10416 
10417         return 0;
10418     }
10419 
10420 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
10421     void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX* ctx,
10422                                       WOLFSSL_RSA*(*f)(WOLFSSL*, int, int))
10423     {
10424         /* wolfSSL verifies all these internally */
10425         (void)ctx;
10426         (void)f;
10427     }
10428 
10429 
10430     void wolfSSL_set_shutdown(WOLFSSL* ssl, int opt)
10431     {
10432         WOLFSSL_ENTER("wolfSSL_set_shutdown");
10433         if(ssl==NULL) {
10434             WOLFSSL_MSG("Shutdown not set. ssl is null");
10435             return;
10436         }
10437 
10438         ssl->options.sentNotify =  (opt&SSL_SENT_SHUTDOWN) > 0;
10439         ssl->options.closeNotify = (opt&SSL_RECEIVED_SHUTDOWN) > 0;
10440     }
10441 
10442 
10443     long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx)
10444     {
10445         (void)ctx;
10446         WOLFSSL_ENTER("wolfSSL_CTX_get_options");
10447         WOLFSSL_MSG("wolfSSL options are set through API calls and macros");
10448 
10449         return 0;
10450     }
10451 
10452 
10453     long wolfSSL_CTX_set_options(WOLFSSL_CTX* ctx, long opt)
10454     {
10455         WOLFSSL_ENTER("SSL_CTX_set_options");
10456         ctx->mask |= opt;
10457         return opt;
10458     }
10459 
10460 
10461     int wolfSSL_set_rfd(WOLFSSL* ssl, int rfd)
10462     {
10463         WOLFSSL_ENTER("SSL_set_rfd");
10464         ssl->rfd = rfd;      /* not used directly to allow IO callbacks */
10465 
10466         ssl->IOCB_ReadCtx  = &ssl->rfd;
10467 
10468         return SSL_SUCCESS;
10469     }
10470 
10471 
10472     int wolfSSL_set_wfd(WOLFSSL* ssl, int wfd)
10473     {
10474         WOLFSSL_ENTER("SSL_set_wfd");
10475         ssl->wfd = wfd;      /* not used directly to allow IO callbacks */
10476 
10477         ssl->IOCB_WriteCtx  = &ssl->wfd;
10478 
10479         return SSL_SUCCESS;
10480     }
10481 
10482 
10483     WOLFSSL_RSA* wolfSSL_RSA_generate_key(int len, unsigned long bits,
10484                                           void(*f)(int, int, void*), void* data)
10485     {
10486         /* no tmp key needed, actual generation not supported */
10487         WOLFSSL_ENTER("RSA_generate_key");
10488         (void)len;
10489         (void)bits;
10490         (void)f;
10491         (void)data;
10492         return NULL;
10493     }
10494 
10495 
10496     WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(WOLFSSL_CTX* ctx)
10497     {
10498         if (ctx == NULL) {
10499             return NULL;
10500         }
10501 
10502         return &(ctx->x509_store);
10503     }
10504 
10505 
10506 #ifndef NO_CERTS
10507     void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, WOLFSSL_X509_STORE* str)
10508     {
10509         if (ctx == NULL || str == NULL) {
10510             return;
10511         }
10512 
10513         /* free cert manager if have one */
10514         if (ctx->cm != NULL) {
10515             wolfSSL_CertManagerFree(ctx->cm);
10516         }
10517         ctx->cm               = str->cm;
10518         ctx->x509_store.cache = str->cache;
10519     }
10520 
10521 
10522     WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get_current_cert(
10523                                                     WOLFSSL_X509_STORE_CTX* ctx)
10524     {
10525         WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_current_cert");
10526         if (ctx)
10527             return ctx->current_cert;
10528         return NULL;
10529     }
10530 
10531 
10532     int wolfSSL_X509_STORE_CTX_get_error(WOLFSSL_X509_STORE_CTX* ctx)
10533     {
10534         WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error");
10535         if (ctx != NULL)
10536             return ctx->error;
10537         return 0;
10538     }
10539 
10540 
10541     int wolfSSL_X509_STORE_CTX_get_error_depth(WOLFSSL_X509_STORE_CTX* ctx)
10542     {
10543         WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error_depth");
10544         if(ctx)
10545             return ctx->error_depth;
10546         return SSL_FATAL_ERROR;
10547     }
10548 #endif
10549 
10550 
10551     WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_buffer(void)
10552     {
10553         static WOLFSSL_BIO_METHOD meth;
10554 
10555         WOLFSSL_ENTER("BIO_f_buffer");
10556         meth.type = BIO_BUFFER;
10557 
10558         return &meth;
10559     }
10560 
10561 
10562     long wolfSSL_BIO_set_write_buffer_size(WOLFSSL_BIO* bio, long size)
10563     {
10564         /* wolfSSL has internal buffer, compatibility only */
10565         WOLFSSL_ENTER("BIO_set_write_buffer_size");
10566         (void)bio;
10567         return size;
10568     }
10569 
10570 
10571     WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_bio(void)
10572     {
10573         static WOLFSSL_BIO_METHOD bio_meth;
10574 
10575         WOLFSSL_ENTER("wolfSSL_BIO_f_bio");
10576         bio_meth.type = BIO_BIO;
10577 
10578         return &bio_meth;
10579     }
10580 
10581 
10582 #ifndef NO_FILESYSTEM
10583     WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_file(void)
10584     {
10585         static WOLFSSL_BIO_METHOD file_meth;
10586 
10587         WOLFSSL_ENTER("wolfSSL_BIO_f_file");
10588         file_meth.type = BIO_FILE;
10589 
10590         return &file_meth;
10591     }
10592 #endif
10593 
10594 
10595     WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_ssl(void)
10596     {
10597         static WOLFSSL_BIO_METHOD meth;
10598 
10599         WOLFSSL_ENTER("BIO_f_ssl");
10600         meth.type = BIO_SSL;
10601 
10602         return &meth;
10603     }
10604 
10605 
10606     WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void)
10607     {
10608         static WOLFSSL_BIO_METHOD meth;
10609 
10610         WOLFSSL_ENTER("BIO_s_socket");
10611         meth.type = BIO_SOCKET;
10612 
10613         return &meth;
10614     }
10615 
10616 
10617     WOLFSSL_BIO* wolfSSL_BIO_new_socket(int sfd, int closeF)
10618     {
10619         WOLFSSL_BIO* bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0,
10620                                                 DYNAMIC_TYPE_OPENSSL);
10621 
10622         WOLFSSL_ENTER("BIO_new_socket");
10623         if (bio) {
10624             XMEMSET(bio, 0, sizeof(WOLFSSL_BIO));
10625             bio->type  = BIO_SOCKET;
10626             bio->close = (byte)closeF;
10627             bio->fd    = sfd;
10628             bio->mem   = NULL;
10629         }
10630         return bio;
10631     }
10632 
10633 
10634     int wolfSSL_BIO_eof(WOLFSSL_BIO* b)
10635     {
10636         WOLFSSL_ENTER("BIO_eof");
10637         if (b->eof)
10638             return 1;
10639 
10640         return 0;
10641     }
10642 
10643 
10644     long wolfSSL_BIO_set_ssl(WOLFSSL_BIO* b, WOLFSSL* ssl, int closeF)
10645     {
10646         WOLFSSL_ENTER("wolfSSL_BIO_set_ssl");
10647 
10648         if (b != NULL) {
10649             b->ssl   = ssl;
10650             b->close = (byte)closeF;
10651     /* add to ssl for bio free if SSL_free called before/instead of free_all? */
10652         }
10653 
10654         return 0;
10655     }
10656 
10657 
10658     long wolfSSL_BIO_set_fd(WOLFSSL_BIO* b, int fd, int closeF)
10659     {
10660         WOLFSSL_ENTER("wolfSSL_BIO_set_fd");
10661 
10662         if (b != NULL) {
10663             b->fd    = fd;
10664             b->close = (byte)closeF;
10665         }
10666 
10667         return SSL_SUCCESS;
10668     }
10669 
10670 
10671     WOLFSSL_BIO* wolfSSL_BIO_new(WOLFSSL_BIO_METHOD* method)
10672     {
10673         WOLFSSL_BIO* bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0,
10674                                                 DYNAMIC_TYPE_OPENSSL);
10675         WOLFSSL_ENTER("BIO_new");
10676         if (bio) {
10677             XMEMSET(bio, 0, sizeof(WOLFSSL_BIO));
10678             bio->type   = method->type;
10679             bio->ssl    = NULL;
10680             bio->mem    = NULL;
10681             bio->prev   = NULL;
10682             bio->next   = NULL;
10683         }
10684         return bio;
10685     }
10686 
10687 
10688     int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, void* p)
10689     {
10690         WOLFSSL_ENTER("wolfSSL_BIO_get_mem_data");
10691 
10692         if (bio == NULL || p == NULL)
10693             return SSL_FATAL_ERROR;
10694 
10695         *(byte **)p = bio->mem;
10696 
10697         return bio->memLen;
10698     }
10699 
10700 
10701     WOLFSSL_BIO* wolfSSL_BIO_new_mem_buf(void* buf, int len)
10702     {
10703         WOLFSSL_BIO* bio = NULL;
10704         if (buf == NULL)
10705             return bio;
10706 
10707         bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
10708         if (bio == NULL)
10709             return bio;
10710 
10711         bio->memLen = len;
10712         bio->mem    = (byte*)XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL);
10713         if (bio->mem == NULL) {
10714             XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
10715             return NULL;
10716         }
10717 
10718         XMEMCPY(bio->mem, buf, len);
10719 
10720         return bio;
10721     }
10722 
10723 
10724 #ifdef USE_WINDOWS_API
10725     #define CloseSocket(s) closesocket(s)
10726 #elif defined(WOLFSSL_MDK_ARM)  || defined(WOLFSSL_KEIL_TCP_NET)
10727     #define CloseSocket(s) closesocket(s)
10728     extern int closesocket(int) ;
10729 #else
10730     #define CloseSocket(s) close(s)
10731 #endif
10732 
10733     int wolfSSL_BIO_free(WOLFSSL_BIO* bio)
10734     {
10735         /* unchain?, doesn't matter in goahead since from free all */
10736         WOLFSSL_ENTER("wolfSSL_BIO_free");
10737         if (bio) {
10738             /* remove from pair by setting the paired bios pair to NULL */
10739             if (bio->pair != NULL) {
10740                 bio->pair->pair = NULL;
10741             }
10742 
10743             if (bio->close) {
10744                 if (bio->ssl)
10745                     wolfSSL_free(bio->ssl);
10746                 if (bio->fd)
10747                     CloseSocket(bio->fd);
10748             }
10749 
10750         #ifndef NO_FILESYSTEM
10751             if (bio->type == BIO_FILE && bio->close == BIO_CLOSE) {
10752                 if (bio->file) {
10753                     XFCLOSE(bio->file);
10754                 }
10755             }
10756         #endif
10757 
10758             if (bio->mem)
10759                 XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
10760             XFREE(bio, bio->heap, DYNAMIC_TYPE_OPENSSL);
10761         }
10762         return 0;
10763     }
10764 
10765 
10766     int wolfSSL_BIO_free_all(WOLFSSL_BIO* bio)
10767     {
10768         WOLFSSL_ENTER("BIO_free_all");
10769         while (bio) {
10770             WOLFSSL_BIO* next = bio->next;
10771             wolfSSL_BIO_free(bio);
10772             bio = next;
10773         }
10774         return 0;
10775     }
10776 
10777 
10778     static int wolfSSL_BIO_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
10779     {
10780         int   sz;
10781         char* pt;
10782 
10783         sz = wolfSSL_BIO_nread(bio, &pt, len);
10784 
10785         if (sz > 0) {
10786             XMEMCPY(buf, pt, sz);
10787         }
10788 
10789         return sz;
10790     }
10791 
10792 
10793     int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
10794     {
10795         int  ret;
10796         WOLFSSL* ssl = 0;
10797         WOLFSSL_BIO* front = bio;
10798 
10799         WOLFSSL_ENTER("wolfSSL_BIO_read");
10800 
10801         if (bio && bio->type == BIO_BIO) {
10802             return wolfSSL_BIO_BIO_read(bio, buf, len);
10803         }
10804 
10805     #ifndef NO_FILESYSTEM
10806         if (bio && bio->type == BIO_FILE) {
10807             return (int)XFREAD(buf, 1, len, bio->file);
10808         }
10809     #endif
10810         if (bio && bio->type == BIO_MEMORY) {
10811             len = min(len, bio->memLen);
10812             XMEMCPY(buf, bio->mem, len);
10813             return len;
10814         }
10815 
10816         /* already got eof, again is error */
10817         if (bio && front->eof)
10818             return SSL_FATAL_ERROR;
10819 
10820         while(bio && ((ssl = bio->ssl) == 0) )
10821             bio = bio->next;
10822 
10823         if (ssl == 0) return BAD_FUNC_ARG;
10824 
10825         ret = wolfSSL_read(ssl, buf, len);
10826         if (ret == 0)
10827             front->eof = 1;
10828         else if (ret < 0) {
10829             int err = wolfSSL_get_error(ssl, 0);
10830             if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
10831                 front->eof = 1;
10832         }
10833         return ret;
10834     }
10835 
10836 
10837     static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data,
10838             int len)
10839     {
10840         /* internal function where arguments have already been sanity checked */
10841         int   sz;
10842         char* buf;
10843 
10844         sz = wolfSSL_BIO_nwrite(bio, &buf, len);
10845 
10846         /* test space for write */
10847         if (sz <= 0) {
10848             WOLFSSL_MSG("No room left to write");
10849             return sz;
10850         }
10851 
10852         XMEMCPY(buf, data, sz);
10853 
10854         return sz;
10855     }
10856 
10857 
10858     int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
10859     {
10860         int  ret;
10861         WOLFSSL* ssl = 0;
10862         WOLFSSL_BIO* front = bio;
10863         byte* p;
10864 
10865         WOLFSSL_ENTER("wolfSSL_BIO_write");
10866 
10867         if (bio && bio->type == BIO_BIO) {
10868             return wolfSSL_BIO_BIO_write(bio, data, len);
10869         }
10870 
10871     #ifndef NO_FILESYSTEM
10872         if (bio && bio->type == BIO_FILE) {
10873             return (int)XFWRITE(data, 1, len, bio->file);
10874         }
10875     #endif
10876 
10877         if (bio && bio->type == BIO_MEMORY) {
10878             /* Make buffer big enough to hold new data. */
10879             if (bio->mem == NULL) {
10880                 bio->mem = (byte*)XMALLOC(len, bio->heap, DYNAMIC_TYPE_OPENSSL);
10881                 if (bio->mem == NULL)
10882                     return -1;
10883                 p = bio->mem;
10884             }
10885             else {
10886                 p = (byte*)XMALLOC(len + bio->memLen, bio->heap,
10887                                    DYNAMIC_TYPE_OPENSSL);
10888                 if (p == NULL)
10889                     return -1;
10890                 XMEMCPY(p, bio->mem, bio->memLen);
10891                 XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
10892                 bio->mem = p;
10893                 p += bio->memLen;
10894             }
10895 
10896             /* Put data on the end of the buffer. */
10897             XMEMCPY(p, data, len);
10898             bio->memLen += len;
10899 
10900             return len;
10901         }
10902 
10903         /* already got eof, again is error */
10904         if (bio && front->eof)
10905             return SSL_FATAL_ERROR;
10906 
10907         while(bio && ((ssl = bio->ssl) == 0) )
10908             bio = bio->next;
10909 
10910         if (ssl == 0) return BAD_FUNC_ARG;
10911 
10912         ret = wolfSSL_write(ssl, data, len);
10913         if (ret == 0)
10914             front->eof = 1;
10915         else if (ret < 0) {
10916             int err = wolfSSL_get_error(ssl, 0);
10917             if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
10918                 front->eof = 1;
10919         }
10920 
10921         return ret;
10922     }
10923 
10924 
10925     WOLFSSL_BIO* wolfSSL_BIO_push(WOLFSSL_BIO* top, WOLFSSL_BIO* append)
10926     {
10927         WOLFSSL_ENTER("BIO_push");
10928         top->next    = append;
10929         append->prev = top;
10930 
10931         return top;
10932     }
10933 
10934 
10935     int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
10936     {
10937         /* for wolfSSL no flushing needed */
10938         WOLFSSL_ENTER("BIO_flush");
10939         (void)bio;
10940         return 1;
10941     }
10942 
10943 
10944 #endif /* OPENSSL_EXTRA || GOAHEAD_WS */
10945 
10946 
10947 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
10948 
10949     void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX* ctx,
10950                                                    void* userdata)
10951     {
10952         WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb_userdata");
10953         ctx->userdata = userdata;
10954     }
10955 
10956 
10957     void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX* ctx,pem_password_cb* cb)
10958     {
10959         WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb");
10960         if (ctx != NULL) {
10961             ctx->passwd_cb = cb;
10962         }
10963     }
10964 
10965     int wolfSSL_num_locks(void)
10966     {
10967         return 0;
10968     }
10969 
10970     void wolfSSL_set_locking_callback(void (*f)(int, int, const char*, int))
10971     {
10972         (void)f;
10973     }
10974 
10975     void wolfSSL_set_id_callback(unsigned long (*f)(void))
10976     {
10977         (void)f;
10978     }
10979 
10980     unsigned long wolfSSL_ERR_get_error(void)
10981     {
10982         WOLFSSL_ENTER("wolfSSL_ERR_get_error");
10983 
10984 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
10985         {
10986             unsigned long ret = wolfSSL_ERR_peek_error_line_data(NULL, NULL,
10987                                                                  NULL, NULL);
10988             wc_RemoveErrorNode(-1);
10989             return ret;
10990         }
10991 #else
10992         return (unsigned long)(0 - NOT_COMPILED_IN);
10993 #endif
10994     }
10995 
10996 #ifndef NO_MD5
10997 
10998     int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER* type,
10999                        const WOLFSSL_EVP_MD* md, const byte* salt,
11000                        const byte* data, int sz, int count, byte* key, byte* iv)
11001     {
11002         int  keyLen = 0;
11003         int  ivLen  = 0;
11004         int  j;
11005         int  keyLeft;
11006         int  ivLeft;
11007         int  keyOutput = 0;
11008         byte digest[MD5_DIGEST_SIZE];
11009     #ifdef WOLFSSL_SMALL_STACK
11010         Md5* md5 = NULL;
11011     #else
11012         Md5  md5[1];
11013     #endif
11014 
11015     #ifdef WOLFSSL_SMALL_STACK
11016         md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
11017         if (md5 == NULL)
11018             return 0;
11019     #endif
11020 
11021         (void)type;
11022 
11023         WOLFSSL_ENTER("wolfSSL_EVP_BytesToKey");
11024 
11025         if (wc_InitMd5(md5) != 0) {
11026         #ifdef WOLFSSL_SMALL_STACK
11027             XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11028         #endif
11029             return 0;
11030         }
11031 
11032         /* only support MD5 for now */
11033         if (XSTRNCMP(md, "MD5", 3) != 0) {
11034         #ifdef WOLFSSL_SMALL_STACK
11035             XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11036         #endif
11037             return 0;
11038         }
11039 
11040         /* only support CBC DES and AES for now */
11041         #ifndef NO_DES3
11042         if (XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0) {
11043             keyLen = DES_KEY_SIZE;
11044             ivLen  = DES_IV_SIZE;
11045         }
11046         else if (XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0) {
11047             keyLen = DES3_KEY_SIZE;
11048             ivLen  = DES_IV_SIZE;
11049         }
11050         else
11051         #endif /* NO_DES3 */
11052         #ifndef NO_AES
11053         if (XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0) {
11054             keyLen = AES_128_KEY_SIZE;
11055             ivLen  = AES_IV_SIZE;
11056         }
11057         else if (XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0) {
11058             keyLen = AES_192_KEY_SIZE;
11059             ivLen  = AES_IV_SIZE;
11060         }
11061         else if (XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0) {
11062             keyLen = AES_256_KEY_SIZE;
11063             ivLen  = AES_IV_SIZE;
11064         }
11065         else
11066         #endif /* NO_AES */
11067         {
11068         #ifdef WOLFSSL_SMALL_STACK
11069             XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11070         #endif
11071             return 0;
11072         }
11073 
11074         keyLeft   = keyLen;
11075         ivLeft    = ivLen;
11076 
11077         while (keyOutput < (keyLen + ivLen)) {
11078             int digestLeft = MD5_DIGEST_SIZE;
11079             /* D_(i - 1) */
11080             if (keyOutput)                      /* first time D_0 is empty */
11081                 wc_Md5Update(md5, digest, MD5_DIGEST_SIZE);
11082             /* data */
11083             wc_Md5Update(md5, data, sz);
11084             /* salt */
11085             if (salt)
11086                 wc_Md5Update(md5, salt, EVP_SALT_SIZE);
11087             wc_Md5Final(md5, digest);
11088             /* count */
11089             for (j = 1; j < count; j++) {
11090                 wc_Md5Update(md5, digest, MD5_DIGEST_SIZE);
11091                 wc_Md5Final(md5, digest);
11092             }
11093 
11094             if (keyLeft) {
11095                 int store = min(keyLeft, MD5_DIGEST_SIZE);
11096                 XMEMCPY(&key[keyLen - keyLeft], digest, store);
11097 
11098                 keyOutput  += store;
11099                 keyLeft    -= store;
11100                 digestLeft -= store;
11101             }
11102 
11103             if (ivLeft && digestLeft) {
11104                 int store = min(ivLeft, digestLeft);
11105                 if (iv != NULL)
11106                     XMEMCPY(&iv[ivLen - ivLeft],
11107                             &digest[MD5_DIGEST_SIZE - digestLeft], store);
11108                 keyOutput += store;
11109                 ivLeft    -= store;
11110             }
11111         }
11112 
11113     #ifdef WOLFSSL_SMALL_STACK
11114         XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11115     #endif
11116 
11117         return keyOutput == (keyLen + ivLen) ? keyOutput : 0;
11118     }
11119 
11120 #endif /* NO_MD5 */
11121 
11122 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
11123 
11124 
11125 #ifdef OPENSSL_EXTRA
11126 
11127 #if !defined(NO_WOLFSSL_SERVER)
11128 size_t wolfSSL_get_server_random(const WOLFSSL *ssl, unsigned char *out,
11129                                                                    size_t outSz)
11130 {
11131     size_t size;
11132 
11133     /* return max size of buffer */
11134     if (outSz == 0) {
11135         return RAN_LEN;
11136     }
11137 
11138     if (ssl == NULL || out == NULL) {
11139         return 0;
11140     }
11141 
11142     if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) {
11143         WOLFSSL_MSG("Arrays struct not saved after handshake");
11144         return 0;
11145     }
11146 
11147     if (outSz > RAN_LEN) {
11148         size = RAN_LEN;
11149     }
11150     else {
11151         size = outSz;
11152     }
11153 
11154     XMEMCPY(out, ssl->arrays->serverRandom, size);
11155     return size;
11156 }
11157 #endif /* !defined(NO_WOLFSSL_SERVER) */
11158 
11159 
11160 #if !defined(NO_WOLFSSL_CLIENT)
11161 /* Return the amount of random bytes copied over or error case.
11162  * ssl : ssl struct after handshake
11163  * out : buffer to hold random bytes
11164  * outSz : either 0 (return max buffer sz) or size of out buffer
11165  *
11166  * NOTE: wolfSSL_KeepArrays(ssl) must be called to retain handshake information.
11167  */
11168 size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
11169                                                                    size_t outSz)
11170 {
11171     size_t size;
11172 
11173     /* return max size of buffer */
11174     if (outSz == 0) {
11175         return RAN_LEN;
11176     }
11177 
11178     if (ssl == NULL || out == NULL) {
11179         return 0;
11180     }
11181 
11182     if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) {
11183         WOLFSSL_MSG("Arrays struct not saved after handshake");
11184         return 0;
11185     }
11186 
11187     if (outSz > RAN_LEN) {
11188         size = RAN_LEN;
11189     }
11190     else {
11191         size = outSz;
11192     }
11193 
11194     XMEMCPY(out, ssl->arrays->clientRandom, size);
11195     return size;
11196 }
11197 #endif /* !defined(NO_WOLFSSL_CLIENT) */
11198 
11199 
11200     unsigned long wolfSSLeay(void)
11201     {
11202         return SSLEAY_VERSION_NUMBER;
11203     }
11204 
11205 
11206     const char* wolfSSLeay_version(int type)
11207     {
11208         static const char* version = "SSLeay wolfSSL compatibility";
11209         (void)type;
11210         return version;
11211     }
11212 
11213 
11214 #ifndef NO_MD5
11215     void wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5)
11216     {
11217         int ret;
11218         typedef char md5_test[sizeof(MD5_CTX) >= sizeof(Md5) ? 1 : -1];
11219         (void)sizeof(md5_test);
11220 
11221         WOLFSSL_ENTER("MD5_Init");
11222         ret = wc_InitMd5((Md5*)md5);
11223         (void)ret;
11224     }
11225 
11226 
11227     void wolfSSL_MD5_Update(WOLFSSL_MD5_CTX* md5, const void* input,
11228                            unsigned long sz)
11229     {
11230         WOLFSSL_ENTER("wolfSSL_MD5_Update");
11231         wc_Md5Update((Md5*)md5, (const byte*)input, (word32)sz);
11232     }
11233 
11234 
11235     void wolfSSL_MD5_Final(byte* input, WOLFSSL_MD5_CTX* md5)
11236     {
11237         WOLFSSL_ENTER("MD5_Final");
11238         wc_Md5Final((Md5*)md5, input);
11239     }
11240 #endif /* NO_MD5 */
11241 
11242 
11243 #ifndef NO_SHA
11244     void wolfSSL_SHA_Init(WOLFSSL_SHA_CTX* sha)
11245     {
11246         typedef char sha_test[sizeof(SHA_CTX) >= sizeof(Sha) ? 1 : -1];
11247         (void)sizeof(sha_test);
11248 
11249         WOLFSSL_ENTER("SHA_Init");
11250         wc_InitSha((Sha*)sha);  /* OpenSSL compat, no ret */
11251     }
11252 
11253 
11254     void wolfSSL_SHA_Update(WOLFSSL_SHA_CTX* sha, const void* input,
11255                            unsigned long sz)
11256     {
11257         WOLFSSL_ENTER("SHA_Update");
11258         wc_ShaUpdate((Sha*)sha, (const byte*)input, (word32)sz);
11259     }
11260 
11261 
11262     void wolfSSL_SHA_Final(byte* input, WOLFSSL_SHA_CTX* sha)
11263     {
11264         WOLFSSL_ENTER("SHA_Final");
11265         wc_ShaFinal((Sha*)sha, input);
11266     }
11267 
11268 
11269     void wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX* sha)
11270     {
11271         WOLFSSL_ENTER("SHA1_Init");
11272         SHA_Init(sha);
11273     }
11274 
11275 
11276     void wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX* sha, const void* input,
11277                             unsigned long sz)
11278     {
11279         WOLFSSL_ENTER("SHA1_Update");
11280         SHA_Update(sha, input, sz);
11281     }
11282 
11283 
11284     void wolfSSL_SHA1_Final(byte* input, WOLFSSL_SHA_CTX* sha)
11285     {
11286         WOLFSSL_ENTER("SHA1_Final");
11287         SHA_Final(input, sha);
11288     }
11289 #endif /* NO_SHA */
11290 
11291     #ifdef WOLFSSL_SHA224
11292 
11293     void wolfSSL_SHA224_Init(WOLFSSL_SHA224_CTX* sha)
11294     {
11295         typedef char sha_test[sizeof(SHA224_CTX) >= sizeof(Sha224) ? 1 : -1];
11296         (void)sizeof(sha_test);
11297 
11298         WOLFSSL_ENTER("SHA224_Init");
11299         wc_InitSha224((Sha224*)sha);   /* OpenSSL compat, no error */
11300     }
11301 
11302 
11303     void wolfSSL_SHA224_Update(WOLFSSL_SHA224_CTX* sha, const void* input,
11304                            unsigned long sz)
11305     {
11306         WOLFSSL_ENTER("SHA224_Update");
11307         wc_Sha224Update((Sha224*)sha, (const byte*)input, (word32)sz);
11308         /* OpenSSL compat, no error */
11309     }
11310 
11311 
11312     void wolfSSL_SHA224_Final(byte* input, WOLFSSL_SHA224_CTX* sha)
11313     {
11314         WOLFSSL_ENTER("SHA224_Final");
11315         wc_Sha224Final((Sha224*)sha, input);
11316         /* OpenSSL compat, no error */
11317     }
11318 
11319     #endif /* WOLFSSL_SHA224 */
11320 
11321 
11322     void wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX* sha256)
11323     {
11324         typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(Sha256) ? 1 : -1];
11325         (void)sizeof(sha_test);
11326 
11327         WOLFSSL_ENTER("SHA256_Init");
11328         wc_InitSha256((Sha256*)sha256);  /* OpenSSL compat, no error */
11329     }
11330 
11331 
11332     void wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX* sha, const void* input,
11333                               unsigned long sz)
11334     {
11335         WOLFSSL_ENTER("SHA256_Update");
11336         wc_Sha256Update((Sha256*)sha, (const byte*)input, (word32)sz);
11337         /* OpenSSL compat, no error */
11338     }
11339 
11340 
11341     void wolfSSL_SHA256_Final(byte* input, WOLFSSL_SHA256_CTX* sha)
11342     {
11343         WOLFSSL_ENTER("SHA256_Final");
11344         wc_Sha256Final((Sha256*)sha, input);
11345         /* OpenSSL compat, no error */
11346     }
11347 
11348 
11349     #ifdef WOLFSSL_SHA384
11350 
11351     void wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX* sha)
11352     {
11353         typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(Sha384) ? 1 : -1];
11354         (void)sizeof(sha_test);
11355 
11356         WOLFSSL_ENTER("SHA384_Init");
11357         wc_InitSha384((Sha384*)sha);   /* OpenSSL compat, no error */
11358     }
11359 
11360 
11361     void wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX* sha, const void* input,
11362                            unsigned long sz)
11363     {
11364         WOLFSSL_ENTER("SHA384_Update");
11365         wc_Sha384Update((Sha384*)sha, (const byte*)input, (word32)sz);
11366         /* OpenSSL compat, no error */
11367     }
11368 
11369 
11370     void wolfSSL_SHA384_Final(byte* input, WOLFSSL_SHA384_CTX* sha)
11371     {
11372         WOLFSSL_ENTER("SHA384_Final");
11373         wc_Sha384Final((Sha384*)sha, input);
11374         /* OpenSSL compat, no error */
11375     }
11376 
11377     #endif /* WOLFSSL_SHA384 */
11378 
11379 
11380    #ifdef WOLFSSL_SHA512
11381 
11382     void wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha)
11383     {
11384         typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(Sha512) ? 1 : -1];
11385         (void)sizeof(sha_test);
11386 
11387         WOLFSSL_ENTER("SHA512_Init");
11388         wc_InitSha512((Sha512*)sha);  /* OpenSSL compat, no error */
11389     }
11390 
11391 
11392     void wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX* sha, const void* input,
11393                            unsigned long sz)
11394     {
11395         WOLFSSL_ENTER("SHA512_Update");
11396         wc_Sha512Update((Sha512*)sha, (const byte*)input, (word32)sz);
11397         /* OpenSSL compat, no error */
11398     }
11399 
11400 
11401     void wolfSSL_SHA512_Final(byte* input, WOLFSSL_SHA512_CTX* sha)
11402     {
11403         WOLFSSL_ENTER("SHA512_Final");
11404         wc_Sha512Final((Sha512*)sha, input);
11405         /* OpenSSL compat, no error */
11406     }
11407 
11408     #endif /* WOLFSSL_SHA512 */
11409 
11410     static struct s_ent{
11411         const unsigned char macType;
11412         const char *name;
11413     } md_tbl[] = {
11414     #ifndef NO_MD5
11415        {MD5, "MD5"},
11416     #endif /* NO_MD5 */
11417 
11418     #ifndef NO_SHA
11419        {SHA, "SHA"},
11420     #endif /* NO_SHA */
11421 
11422     #ifdef WOLFSSL_SHA224
11423        {SHA224, "SHA224"},
11424     #endif /* WOLFSSL_SHA224 */
11425 
11426        {SHA256, "SHA256"},
11427 
11428     #ifdef WOLFSSL_SHA384
11429        {SHA384, "SHA384"},
11430     #endif /* WOLFSSL_SHA384 */
11431 
11432     #ifdef WOLFSSL_SHA512
11433         {SHA512, "SHA512"},
11434     #endif /* WOLFSSL_SHA512 */
11435 
11436         {0, NULL}
11437     } ;
11438 
11439 const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name)
11440 {
11441     static const struct alias {
11442         const char *name;
11443         const char *alias;
11444     } alias_tbl[] =
11445     {
11446         {"MD5", "ssl3-md5"},
11447         {"SHA1", "ssl3-sha1"},
11448         { NULL, NULL}
11449     };
11450 
11451     const struct alias  *al ;
11452     const struct s_ent *ent ;
11453 
11454     for( al = alias_tbl; al->name != NULL; al++)
11455         if(XSTRNCMP(name, al->alias, XSTRLEN(al->alias)+1) == 0) {
11456             name = al->name;
11457             break;
11458         }
11459 
11460     for( ent = md_tbl; ent->name != NULL; ent++)
11461         if(XSTRNCMP(name, ent->name, XSTRLEN(ent->name)+1) == 0) {
11462             return (EVP_MD *)ent->name;
11463         }
11464     return NULL;
11465 }
11466 
11467 static WOLFSSL_EVP_MD *wolfSSL_EVP_get_md(const unsigned char type)
11468 {
11469     const struct s_ent *ent ;
11470     for( ent = md_tbl; ent->macType != 0; ent++)
11471         if(type == ent->macType) {
11472             return (WOLFSSL_EVP_MD *)ent->name;
11473         }
11474     return 0;
11475 }
11476 
11477 int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
11478 {
11479     const struct s_ent *ent ;
11480     for( ent = md_tbl; ent->name != NULL; ent++)
11481         if(XSTRNCMP((const char *)md, ent->name, XSTRLEN(ent->name)+1) == 0) {
11482             return ent->macType;
11483         }
11484     return 0;
11485 }
11486 
11487 
11488     #ifndef NO_MD5
11489 
11490     const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void)
11491     {
11492         const char* type = EVP_get_digestbyname("MD5");
11493         WOLFSSL_ENTER("EVP_md5");
11494         return type;
11495     }
11496 
11497     #endif /* NO_MD5 */
11498 
11499 
11500 #ifndef NO_SHA
11501     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void)
11502     {
11503         const char* type = EVP_get_digestbyname("SHA");
11504         WOLFSSL_ENTER("EVP_sha1");
11505         return type;
11506     }
11507 #endif /* NO_SHA */
11508 
11509     #ifdef WOLFSSL_SHA224
11510 
11511     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha224(void)
11512     {
11513         const char* type = EVP_get_digestbyname("SHA224");
11514         WOLFSSL_ENTER("EVP_sha224");
11515         return type;
11516     }
11517 
11518     #endif /* WOLFSSL_SHA224 */
11519 
11520 
11521     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void)
11522     {
11523         const char* type = EVP_get_digestbyname("SHA256");
11524         WOLFSSL_ENTER("EVP_sha256");
11525         return type;
11526     }
11527 
11528     #ifdef WOLFSSL_SHA384
11529 
11530     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void)
11531     {
11532         const char* type = EVP_get_digestbyname("SHA384");
11533         WOLFSSL_ENTER("EVP_sha384");
11534         return type;
11535     }
11536 
11537     #endif /* WOLFSSL_SHA384 */
11538 
11539     #ifdef WOLFSSL_SHA512
11540 
11541     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void)
11542     {
11543         const char* type = EVP_get_digestbyname("SHA512");
11544         WOLFSSL_ENTER("EVP_sha512");
11545         return type;
11546     }
11547 
11548     #endif /* WOLFSSL_SHA512 */
11549 
11550     WOLFSSL_EVP_MD_CTX *wolfSSL_EVP_MD_CTX_new(void)
11551     {
11552         WOLFSSL_EVP_MD_CTX* ctx;
11553         WOLFSSL_ENTER("EVP_MD_CTX_new");
11554         ctx = (WOLFSSL_EVP_MD_CTX*)XMALLOC(sizeof *ctx, NULL,
11555                                                        DYNAMIC_TYPE_TMP_BUFFER);
11556         if (ctx){
11557             wolfSSL_EVP_MD_CTX_init(ctx);
11558         }
11559         return ctx;
11560     }
11561 
11562     WOLFSSL_API void wolfSSL_EVP_MD_CTX_free(WOLFSSL_EVP_MD_CTX *ctx)
11563     {
11564         if (ctx) {
11565             WOLFSSL_ENTER("EVP_MD_CTX_free");
11566                 wolfSSL_EVP_MD_CTX_cleanup(ctx);
11567                 XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11568             }
11569     }
11570 
11571     void wolfSSL_EVP_MD_CTX_init(WOLFSSL_EVP_MD_CTX* ctx)
11572     {
11573         WOLFSSL_ENTER("EVP_CIPHER_MD_CTX_init");
11574         XMEMSET(ctx, 0, sizeof(WOLFSSL_EVP_MD_CTX));
11575     }
11576 
11577     const WOLFSSL_EVP_MD *wolfSSL_EVP_MD_CTX_md(const WOLFSSL_EVP_MD_CTX *ctx)
11578     {
11579         if (!ctx)
11580             return NULL;
11581         return (const WOLFSSL_EVP_MD *)wolfSSL_EVP_get_md(ctx->macType);
11582     }
11583 
11584     #ifndef NO_AES
11585 
11586     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void)
11587     {
11588         WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cbc");
11589         return EVP_AES_128_CBC;
11590     }
11591 
11592 
11593     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void)
11594     {
11595         WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cbc");
11596         return EVP_AES_192_CBC;
11597     }
11598 
11599 
11600     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void)
11601     {
11602         WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cbc");
11603         return EVP_AES_256_CBC;
11604     }
11605 
11606 
11607     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void)
11608     {
11609         WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ctr");
11610         return EVP_AES_128_CTR;
11611     }
11612 
11613 
11614     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void)
11615     {
11616         WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ctr");
11617         return EVP_AES_192_CTR;
11618     }
11619 
11620 
11621     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void)
11622     {
11623         WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ctr");
11624         return EVP_AES_256_CTR;
11625     }
11626 
11627     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ecb(void)
11628     {
11629         WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ecb");
11630         return EVP_AES_128_ECB;
11631     }
11632 
11633 
11634     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ecb(void)
11635     {
11636         WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ecb");
11637         return EVP_AES_192_ECB;
11638     }
11639 
11640 
11641     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ecb(void)
11642     {
11643         WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ecb");
11644         return EVP_AES_256_ECB;
11645     }
11646     #endif /* NO_AES */
11647 
11648 #ifndef NO_DES3
11649     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void)
11650     {
11651         WOLFSSL_ENTER("wolfSSL_EVP_des_cbc");
11652         return EVP_DES_CBC;
11653     }
11654 #ifdef WOLFSSL_DES_ECB
11655     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ecb(void)
11656     {
11657         WOLFSSL_ENTER("wolfSSL_EVP_des_ecb");
11658         return EVP_DES_ECB;
11659     }
11660 #endif
11661     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void)
11662     {
11663         WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_cbc");
11664         return EVP_DES_EDE3_CBC;
11665     }
11666 #ifdef WOLFSSL_DES_ECB
11667     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_ecb(void)
11668     {
11669         WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_ecb");
11670         return EVP_DES_EDE3_ECB;
11671     }
11672 #endif
11673 #endif /* NO_DES3 */
11674 
11675     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc4(void)
11676     {
11677         static const char* type = "ARC4";
11678         WOLFSSL_ENTER("wolfSSL_EVP_rc4");
11679         return type;
11680     }
11681 
11682 #ifdef HAVE_IDEA
11683     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_idea_cbc(void)
11684     {
11685         WOLFSSL_ENTER("wolfSSL_EVP_idea_cbc");
11686         return EVP_IDEA_CBC;
11687     }
11688 #endif
11689     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void)
11690     {
11691         static const char* type = "NULL";
11692         WOLFSSL_ENTER("wolfSSL_EVP_enc_null");
11693         return type;
11694     }
11695 
11696 
11697     int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx)
11698     {
11699         WOLFSSL_ENTER("EVP_MD_CTX_cleanup");
11700         (void)ctx;
11701         return 0;
11702     }
11703 
11704 
11705 
11706     void wolfSSL_EVP_CIPHER_CTX_init(WOLFSSL_EVP_CIPHER_CTX* ctx)
11707     {
11708         WOLFSSL_ENTER("EVP_CIPHER_CTX_init");
11709         if (ctx) {
11710             ctx->cipherType = 0xff;   /* no init */
11711             ctx->keyLen     = 0;
11712             ctx->enc        = 1;      /* start in encrypt mode */
11713         }
11714     }
11715 
11716 
11717     /* SSL_SUCCESS on ok */
11718     int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx)
11719     {
11720         WOLFSSL_ENTER("EVP_CIPHER_CTX_cleanup");
11721         if (ctx) {
11722             ctx->cipherType = 0xff;  /* no more init */
11723             ctx->keyLen     = 0;
11724         }
11725 
11726         return SSL_SUCCESS;
11727     }
11728 
11729 
11730     /* return SSL_SUCCESS on ok, 0 on failure to match API compatibility */
11731     int  wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
11732                                const WOLFSSL_EVP_CIPHER* type, byte* key,
11733                                byte* iv, int enc)
11734     {
11735         int ret = -1;  /* failure local, during function 0 means success
11736                           because internal functions work that way */
11737         (void)key;
11738         (void)iv;
11739         (void)enc;
11740 
11741         WOLFSSL_ENTER("wolfSSL_EVP_CipherInit");
11742         if (ctx == NULL) {
11743             WOLFSSL_MSG("no ctx");
11744             return 0;   /* failure */
11745         }
11746 
11747         if (type == NULL && ctx->cipherType == 0xff) {
11748             WOLFSSL_MSG("no type set");
11749             return 0;   /* failure */
11750         }
11751         ctx->bufUsed = 0;
11752         ctx->lastUsed = 0;
11753         ctx->flags   = 0;
11754 
11755 #ifndef NO_AES
11756         /* printf("cipherType=%d\n", ctx->cipherType); */
11757         if (ctx->cipherType == AES_128_CBC_TYPE ||
11758             (type && XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)) {
11759             WOLFSSL_MSG("EVP_AES_128_CBC");
11760             ctx->cipherType = AES_128_CBC_TYPE;
11761             ctx->flags      = WOLFSSL_EVP_CIPH_CBC_MODE;
11762             ctx->keyLen     = 16;
11763             ctx->block_size = AES_BLOCK_SIZE;
11764             if (enc == 0 || enc == 1)
11765                 ctx->enc = enc ? 1 : 0;
11766             if (key) {
11767                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
11768                                 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
11769                 if (ret != 0)
11770                     return ret;
11771             }
11772             if (iv && key == NULL) {
11773                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
11774                 if (ret != 0)
11775                     return ret;
11776             }
11777         }
11778         else if (ctx->cipherType == AES_192_CBC_TYPE ||
11779                  (type && XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)) {
11780             WOLFSSL_MSG("EVP_AES_192_CBC");
11781             ctx->cipherType = AES_192_CBC_TYPE;
11782             ctx->flags      = WOLFSSL_EVP_CIPH_CBC_MODE;
11783             ctx->keyLen     = 24;
11784             ctx->block_size = AES_BLOCK_SIZE;
11785             if (enc == 0 || enc == 1)
11786                 ctx->enc = enc ? 1 : 0;
11787             if (key) {
11788                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
11789                                 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
11790                 if (ret != 0)
11791                     return ret;
11792             }
11793             if (iv && key == NULL) {
11794                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
11795                 if (ret != 0)
11796                     return ret;
11797             }
11798         }
11799         else if (ctx->cipherType == AES_256_CBC_TYPE ||
11800                  (type && XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)) {
11801             WOLFSSL_MSG("EVP_AES_256_CBC");
11802             ctx->cipherType = AES_256_CBC_TYPE;
11803             ctx->flags      = WOLFSSL_EVP_CIPH_CBC_MODE;
11804             ctx->keyLen     = 32;
11805             ctx->block_size = AES_BLOCK_SIZE;
11806             if (enc == 0 || enc == 1)
11807                 ctx->enc = enc ? 1 : 0;
11808             if (key) {
11809                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
11810                                 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
11811                 if (ret != 0)
11812                     return ret;
11813             }
11814             if (iv && key == NULL) {
11815                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
11816                 if (ret != 0)
11817                     return ret;
11818             }
11819         }
11820 #ifdef WOLFSSL_AES_COUNTER
11821         else if (ctx->cipherType == AES_128_CTR_TYPE ||
11822                  (type && XSTRNCMP(type, EVP_AES_128_CTR, EVP_AES_SIZE) == 0)) {
11823             WOLFSSL_MSG("EVP_AES_128_CTR");
11824             ctx->cipherType = AES_128_CTR_TYPE;
11825             ctx->flags      = WOLFSSL_EVP_CIPH_CTR_MODE;
11826             ctx->keyLen     = 16;
11827             ctx->block_size = AES_BLOCK_SIZE;
11828             if (enc == 0 || enc == 1)
11829                 ctx->enc = enc ? 1 : 0;
11830             if (key) {
11831               ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
11832                     AES_ENCRYPTION);
11833                 if (ret != 0)
11834                     return ret;
11835             }
11836             if (iv && key == NULL) {
11837                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
11838                 if (ret != 0)
11839                     return ret;
11840             }
11841         }
11842         else if (ctx->cipherType == AES_192_CTR_TYPE ||
11843                  (type && XSTRNCMP(type, EVP_AES_192_CTR, EVP_AES_SIZE) == 0)) {
11844             WOLFSSL_MSG("EVP_AES_192_CTR");
11845             ctx->cipherType = AES_192_CTR_TYPE;
11846             ctx->flags      = WOLFSSL_EVP_CIPH_CTR_MODE;
11847             ctx->keyLen     = 24;
11848             ctx->block_size = AES_BLOCK_SIZE;
11849             if (enc == 0 || enc == 1)
11850                 ctx->enc = enc ? 1 : 0;
11851             if (key) {
11852                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
11853                       AES_ENCRYPTION);
11854                 if (ret != 0)
11855                     return ret;
11856             }
11857             if (iv && key == NULL) {
11858                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
11859                 if (ret != 0)
11860                     return ret;
11861             }
11862         }
11863         else if (ctx->cipherType == AES_256_CTR_TYPE ||
11864                  (type && XSTRNCMP(type, EVP_AES_256_CTR, EVP_AES_SIZE) == 0)) {
11865             WOLFSSL_MSG("EVP_AES_256_CTR");
11866             ctx->cipherType = AES_256_CTR_TYPE;
11867             ctx->flags      = WOLFSSL_EVP_CIPH_CTR_MODE;
11868             ctx->keyLen     = 32;
11869             ctx->block_size = AES_BLOCK_SIZE;
11870             if (enc == 0 || enc == 1)
11871                 ctx->enc = enc ? 1 : 0;
11872             if (key) {
11873                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
11874                       AES_ENCRYPTION);
11875                 if (ret != 0)
11876                     return ret;
11877             }
11878             if (iv && key == NULL) {
11879                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
11880                 if (ret != 0)
11881                     return ret;
11882             }
11883         }
11884 #endif /* WOLFSSL_AES_CTR */
11885         else if (ctx->cipherType == AES_128_ECB_TYPE ||
11886             (type && XSTRNCMP(type, EVP_AES_128_ECB, EVP_AES_SIZE) == 0)) {
11887             WOLFSSL_MSG("EVP_AES_128_ECB");
11888             ctx->cipherType = AES_128_ECB_TYPE;
11889             ctx->flags      = WOLFSSL_EVP_CIPH_ECB_MODE;
11890             ctx->keyLen     = 16;
11891             ctx->block_size = AES_BLOCK_SIZE;
11892             if (enc == 0 || enc == 1)
11893                 ctx->enc = enc ? 1 : 0;
11894             if (key) {
11895                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, NULL,
11896                       ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
11897             }
11898             if (ret != 0)
11899                 return ret;
11900         }
11901         else if (ctx->cipherType == AES_192_ECB_TYPE ||
11902                  (type && XSTRNCMP(type, EVP_AES_192_ECB, EVP_AES_SIZE) == 0)) {
11903             WOLFSSL_MSG("EVP_AES_192_ECB");
11904             ctx->cipherType = AES_192_ECB_TYPE;
11905             ctx->flags      = WOLFSSL_EVP_CIPH_ECB_MODE;
11906             ctx->keyLen     = 24;
11907             ctx->block_size = AES_BLOCK_SIZE;
11908             if (enc == 0 || enc == 1)
11909                 ctx->enc = enc ? 1 : 0;
11910             if (key) {
11911                 if(ctx->enc)
11912                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, NULL,
11913                       ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
11914             }
11915             if (ret != 0)
11916                 return ret;
11917         }
11918         else if (ctx->cipherType == AES_256_ECB_TYPE ||
11919                  (type && XSTRNCMP(type, EVP_AES_256_ECB, EVP_AES_SIZE) == 0)) {
11920             WOLFSSL_MSG("EVP_AES_256_ECB");
11921             ctx->cipherType = AES_256_ECB_TYPE;
11922             ctx->flags      = WOLFSSL_EVP_CIPH_ECB_MODE;
11923             ctx->keyLen     = 32;
11924             ctx->block_size = AES_BLOCK_SIZE;
11925             if (enc == 0 || enc == 1)
11926                 ctx->enc = enc ? 1 : 0;
11927             if (key) {
11928               ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, NULL,
11929                     ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
11930             }
11931             if (ret != 0)
11932                 return ret;
11933         }
11934 #endif /* NO_AES */
11935 
11936 #ifndef NO_DES3
11937         if (ctx->cipherType == DES_CBC_TYPE ||
11938                  (type && XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0)) {
11939             WOLFSSL_MSG("EVP_DES_CBC");
11940             ctx->cipherType = DES_CBC_TYPE;
11941             ctx->flags      = WOLFSSL_EVP_CIPH_CBC_MODE;
11942             ctx->keyLen     = 8;
11943             ctx->block_size = DES_BLOCK_SIZE;
11944             if (enc == 0 || enc == 1)
11945                 ctx->enc = enc ? 1 : 0;
11946             if (key) {
11947                 ret = wc_Des_SetKey(&ctx->cipher.des, key, iv,
11948                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
11949                 if (ret != 0)
11950                     return ret;
11951             }
11952 
11953             if (iv && key == NULL)
11954                 wc_Des_SetIV(&ctx->cipher.des, iv);
11955         }
11956 #ifdef WOLFSSL_DES_ECB
11957         else if (ctx->cipherType == DES_ECB_TYPE ||
11958                  (type && XSTRNCMP(type, EVP_DES_ECB, EVP_DES_SIZE) == 0)) {
11959             WOLFSSL_MSG("EVP_DES_ECB");
11960             ctx->cipherType = DES_ECB_TYPE;
11961             ctx->flags      = WOLFSSL_EVP_CIPH_ECB_MODE;
11962             ctx->keyLen     = 8;
11963             ctx->block_size = DES_BLOCK_SIZE;
11964             if (enc == 0 || enc == 1)
11965                 ctx->enc = enc ? 1 : 0;
11966             if (key) {
11967                 ret = wc_Des_SetKey(&ctx->cipher.des, key, NULL,
11968                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
11969                 if (ret != 0)
11970                     return ret;
11971             }
11972         }
11973 #endif
11974         else if (ctx->cipherType == DES_EDE3_CBC_TYPE ||
11975                  (type &&
11976                   XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)) {
11977             WOLFSSL_MSG("EVP_DES_EDE3_CBC");
11978             ctx->cipherType = DES_EDE3_CBC_TYPE;
11979             ctx->flags      = WOLFSSL_EVP_CIPH_CBC_MODE;
11980             ctx->keyLen     = 24;
11981             ctx->block_size = DES_BLOCK_SIZE;
11982             if (enc == 0 || enc == 1)
11983                 ctx->enc = enc ? 1 : 0;
11984             if (key) {
11985                 ret = wc_Des3_SetKey(&ctx->cipher.des3, key, iv,
11986                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
11987                 if (ret != 0)
11988                     return ret;
11989             }
11990 
11991             if (iv && key == NULL) {
11992                 ret = wc_Des3_SetIV(&ctx->cipher.des3, iv);
11993                 if (ret != 0)
11994                     return ret;
11995             }
11996         }
11997         else if (ctx->cipherType == DES_EDE3_ECB_TYPE ||
11998                  (type &&
11999                   XSTRNCMP(type, EVP_DES_EDE3_ECB, EVP_DES_EDE3_SIZE) == 0)) {
12000             WOLFSSL_MSG("EVP_DES_EDE3_ECB");
12001             ctx->cipherType = DES_EDE3_ECB_TYPE;
12002             ctx->flags      = WOLFSSL_EVP_CIPH_ECB_MODE;
12003             ctx->keyLen     = 24;
12004             ctx->block_size = DES_BLOCK_SIZE;
12005             if (enc == 0 || enc == 1)
12006                 ctx->enc = enc ? 1 : 0;
12007             if (key) {
12008                 ret = wc_Des3_SetKey(&ctx->cipher.des3, key, NULL,
12009                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
12010                 if (ret != 0)
12011                     return ret;
12012             }
12013         }
12014 #endif /* NO_DES3 */
12015 #ifndef NO_RC4
12016         if (ctx->cipherType == ARC4_TYPE || (type &&
12017                                      XSTRNCMP(type, "ARC4", 4) == 0)) {
12018             WOLFSSL_MSG("ARC4");
12019             ctx->cipherType = ARC4_TYPE;
12020             ctx->flags      = WOLFSSL_EVP_CIPH_STREAM_CIPHER;
12021             if (ctx->keyLen == 0)  /* user may have already set */
12022                 ctx->keyLen = 16;  /* default to 128 */
12023             if (key)
12024                 wc_Arc4SetKey(&ctx->cipher.arc4, key, ctx->keyLen);
12025             ret = 0;  /* success */
12026         }
12027 #endif /* NO_RC4 */
12028 #ifdef HAVE_IDEA
12029         if (ctx->cipherType == IDEA_CBC_TYPE ||
12030                  (type && XSTRNCMP(type, EVP_IDEA_CBC, EVP_IDEA_SIZE) == 0)) {
12031             WOLFSSL_MSG("EVP_IDEA_CBC");
12032             ctx->cipherType = IDEA_CBC_TYPE;
12033             ctx->flags      = WOLFSSL_EVP_CIPH_CBC_MODE;
12034             ctx->keyLen     = IDEA_KEY_SIZE;
12035             if (enc == 0 || enc == 1)
12036                 ctx->enc = enc ? 1 : 0;
12037             if (key) {
12038                 ret = wc_IdeaSetKey(&ctx->cipher.idea, key, (word16)ctx->keyLen,
12039                                     iv, ctx->enc ? IDEA_ENCRYPTION :
12040                                                    IDEA_DECRYPTION);
12041                 if (ret != 0)
12042                     return ret;
12043             }
12044 
12045             if (iv && key == NULL)
12046                 wc_IdeaSetIV(&ctx->cipher.idea, iv);
12047         }
12048 #endif /* HAVE_IDEA */
12049         if (ctx->cipherType == NULL_CIPHER_TYPE || (type &&
12050                                      XSTRNCMP(type, "NULL", 4) == 0)) {
12051             WOLFSSL_MSG("NULL cipher");
12052             ctx->cipherType = NULL_CIPHER_TYPE;
12053             ctx->keyLen = 0;
12054             ret = 0;  /* success */
12055         }
12056 
12057         if (ret == 0)
12058             return SSL_SUCCESS;
12059         else
12060             return 0;  /* overall failure */
12061     }
12062 
12063 
12064     /* SSL_SUCCESS on ok */
12065     int wolfSSL_EVP_CIPHER_CTX_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx)
12066     {
12067         WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_key_length");
12068         if (ctx)
12069             return ctx->keyLen;
12070 
12071         return 0;   /* failure */
12072     }
12073 
12074 
12075     /* SSL_SUCCESS on ok */
12076     int wolfSSL_EVP_CIPHER_CTX_set_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx,
12077                                              int keylen)
12078     {
12079         WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_set_key_length");
12080         if (ctx)
12081             ctx->keyLen = keylen;
12082         else
12083             return 0;  /* failure */
12084 
12085         return SSL_SUCCESS;
12086     }
12087 
12088 
12089     /* SSL_SUCCESS on ok */
12090     int wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* dst, byte* src,
12091                           word32 len)
12092     {
12093         int ret = 0;
12094         WOLFSSL_ENTER("wolfSSL_EVP_Cipher");
12095 
12096         if (ctx == NULL || dst == NULL || src == NULL) {
12097             WOLFSSL_MSG("Bad function argument");
12098             return 0;  /* failure */
12099         }
12100 
12101         if (ctx->cipherType == 0xff) {
12102             WOLFSSL_MSG("no init");
12103             return 0;  /* failure */
12104         }
12105 
12106         switch (ctx->cipherType) {
12107 
12108 #ifndef NO_AES
12109 #ifdef HAVE_AES_CBC
12110             case AES_128_CBC_TYPE :
12111             case AES_192_CBC_TYPE :
12112             case AES_256_CBC_TYPE :
12113                 WOLFSSL_MSG("AES CBC");
12114                 if (ctx->enc)
12115                     ret = wc_AesCbcEncrypt(&ctx->cipher.aes, dst, src, len);
12116                 else
12117                     ret = wc_AesCbcDecrypt(&ctx->cipher.aes, dst, src, len);
12118                 break;
12119 #endif /* HAVE_AES_CBC */
12120 #ifdef HAVE_AES_ECB
12121             case AES_128_ECB_TYPE :
12122             case AES_192_ECB_TYPE :
12123             case AES_256_ECB_TYPE :
12124                 WOLFSSL_MSG("AES ECB");
12125                 if (ctx->enc)
12126                     ret = wc_AesEcbEncrypt(&ctx->cipher.aes, dst, src, len);
12127                 else
12128                     ret = wc_AesEcbDecrypt(&ctx->cipher.aes, dst, src, len);
12129                 break;
12130 #endif
12131 #ifdef WOLFSSL_AES_COUNTER
12132             case AES_128_CTR_TYPE :
12133             case AES_192_CTR_TYPE :
12134             case AES_256_CTR_TYPE :
12135                     WOLFSSL_MSG("AES CTR");
12136                     wc_AesCtrEncrypt(&ctx->cipher.aes, dst, src, len);
12137                 break;
12138 #endif /* WOLFSSL_AES_COUNTER */
12139 #endif /* NO_AES */
12140 
12141 #ifndef NO_DES3
12142             case DES_CBC_TYPE :
12143                 if (ctx->enc)
12144                     wc_Des_CbcEncrypt(&ctx->cipher.des, dst, src, len);
12145                 else
12146                     wc_Des_CbcDecrypt(&ctx->cipher.des, dst, src, len);
12147                 break;
12148             case DES_EDE3_CBC_TYPE :
12149                 if (ctx->enc)
12150                     ret = wc_Des3_CbcEncrypt(&ctx->cipher.des3, dst, src, len);
12151                 else
12152                     ret = wc_Des3_CbcDecrypt(&ctx->cipher.des3, dst, src, len);
12153                 break;
12154 #ifdef WOLFSSL_DES_ECB
12155             case DES_ECB_TYPE :
12156                 ret = wc_Des_EcbEncrypt(&ctx->cipher.des, dst, src, len);
12157                 break;
12158             case DES_EDE3_ECB_TYPE :
12159                 ret = wc_Des3_EcbEncrypt(&ctx->cipher.des3, dst, src, len);
12160                 break;
12161 #endif
12162 #endif /* !NO_DES3 */
12163 
12164 #ifndef NO_RC4
12165             case ARC4_TYPE :
12166                 wc_Arc4Process(&ctx->cipher.arc4, dst, src, len);
12167                 break;
12168 #endif
12169 
12170 #ifdef HAVE_IDEA
12171             case IDEA_CBC_TYPE :
12172                 if (ctx->enc)
12173                     wc_IdeaCbcEncrypt(&ctx->cipher.idea, dst, src, len);
12174                 else
12175                     wc_IdeaCbcDecrypt(&ctx->cipher.idea, dst, src, len);
12176                 break;
12177 #endif
12178             case NULL_CIPHER_TYPE :
12179                 XMEMCPY(dst, src, len);
12180                 break;
12181 
12182             default: {
12183                 WOLFSSL_MSG("bad type");
12184                 return 0;  /* failure */
12185             }
12186         }
12187 
12188         if (ret != 0) {
12189             WOLFSSL_MSG("wolfSSL_EVP_Cipher failure");
12190             return 0;  /* failure */
12191         }
12192 
12193         WOLFSSL_MSG("wolfSSL_EVP_Cipher success");
12194         return SSL_SUCCESS;  /* success */
12195     }
12196 
12197 #include "wolfcrypt/src/evp.c"
12198 
12199 
12200     /* store for external read of iv, SSL_SUCCESS on success */
12201     int  wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
12202     {
12203         WOLFSSL_ENTER("wolfSSL_StoreExternalIV");
12204 
12205         if (ctx == NULL) {
12206             WOLFSSL_MSG("Bad function argument");
12207             return SSL_FATAL_ERROR;
12208         }
12209 
12210         switch (ctx->cipherType) {
12211 
12212 #ifndef NO_AES
12213             case AES_128_CBC_TYPE :
12214             case AES_192_CBC_TYPE :
12215             case AES_256_CBC_TYPE :
12216                 WOLFSSL_MSG("AES CBC");
12217                 XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
12218                 break;
12219 
12220 #ifdef WOLFSSL_AES_COUNTER
12221             case AES_128_CTR_TYPE :
12222             case AES_192_CTR_TYPE :
12223             case AES_256_CTR_TYPE :
12224                 WOLFSSL_MSG("AES CTR");
12225                 XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
12226                 break;
12227 #endif /* WOLFSSL_AES_COUNTER */
12228 
12229 #endif /* NO_AES */
12230 
12231 #ifndef NO_DES3
12232             case DES_CBC_TYPE :
12233                 WOLFSSL_MSG("DES CBC");
12234                 XMEMCPY(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
12235                 break;
12236 
12237             case DES_EDE3_CBC_TYPE :
12238                 WOLFSSL_MSG("DES EDE3 CBC");
12239                 XMEMCPY(ctx->iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
12240                 break;
12241 #endif
12242 
12243 #ifdef HAVE_IDEA
12244             case IDEA_CBC_TYPE :
12245                 WOLFSSL_MSG("IDEA CBC");
12246                 XMEMCPY(ctx->iv, &ctx->cipher.idea.reg, IDEA_BLOCK_SIZE);
12247                 break;
12248 #endif
12249             case ARC4_TYPE :
12250                 WOLFSSL_MSG("ARC4");
12251                 break;
12252 
12253             case NULL_CIPHER_TYPE :
12254                 WOLFSSL_MSG("NULL");
12255                 break;
12256 
12257             default: {
12258                 WOLFSSL_MSG("bad type");
12259                 return SSL_FATAL_ERROR;
12260             }
12261         }
12262         return SSL_SUCCESS;
12263     }
12264 
12265 
12266     /* set internal IV from external, SSL_SUCCESS on success */
12267     int  wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
12268     {
12269 
12270         WOLFSSL_ENTER("wolfSSL_SetInternalIV");
12271 
12272         if (ctx == NULL) {
12273             WOLFSSL_MSG("Bad function argument");
12274             return SSL_FATAL_ERROR;
12275         }
12276 
12277         switch (ctx->cipherType) {
12278 
12279 #ifndef NO_AES
12280             case AES_128_CBC_TYPE :
12281             case AES_192_CBC_TYPE :
12282             case AES_256_CBC_TYPE :
12283                 WOLFSSL_MSG("AES CBC");
12284                 XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
12285                 break;
12286 
12287 #ifdef WOLFSSL_AES_COUNTER
12288             case AES_128_CTR_TYPE :
12289             case AES_192_CTR_TYPE :
12290             case AES_256_CTR_TYPE :
12291                 WOLFSSL_MSG("AES CTR");
12292                 XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
12293                 break;
12294 #endif
12295 
12296 #endif /* NO_AES */
12297 
12298 #ifndef NO_DES3
12299             case DES_CBC_TYPE :
12300                 WOLFSSL_MSG("DES CBC");
12301                 XMEMCPY(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
12302                 break;
12303 
12304             case DES_EDE3_CBC_TYPE :
12305                 WOLFSSL_MSG("DES EDE3 CBC");
12306                 XMEMCPY(&ctx->cipher.des3.reg, ctx->iv, DES_BLOCK_SIZE);
12307                 break;
12308 #endif
12309 
12310 #ifdef HAVE_IDEA
12311             case IDEA_CBC_TYPE :
12312                 WOLFSSL_MSG("IDEA CBC");
12313                 XMEMCPY(&ctx->cipher.idea.reg, ctx->iv, IDEA_BLOCK_SIZE);
12314                 break;
12315 #endif
12316             case ARC4_TYPE :
12317                 WOLFSSL_MSG("ARC4");
12318                 break;
12319 
12320             case NULL_CIPHER_TYPE :
12321                 WOLFSSL_MSG("NULL");
12322                 break;
12323 
12324             default: {
12325                 WOLFSSL_MSG("bad type");
12326                 return SSL_FATAL_ERROR;
12327             }
12328         }
12329         return SSL_SUCCESS;
12330     }
12331 
12332 
12333     /* SSL_SUCCESS on ok */
12334     int wolfSSL_EVP_DigestInit(WOLFSSL_EVP_MD_CTX* ctx,
12335                                const WOLFSSL_EVP_MD* type)
12336     {
12337         WOLFSSL_ENTER("EVP_DigestInit");
12338 
12339         if (ctx == NULL || type == NULL) {
12340             return BAD_FUNC_ARG;
12341         }
12342 
12343 
12344     #ifdef WOLFSSL_ASYNC_CRYPT
12345         /* compile-time validation of ASYNC_CTX_SIZE */
12346         typedef char async_test[WC_ASYNC_DEV_SIZE >= sizeof(WC_ASYNC_DEV) ?
12347                                                                         1 : -1];
12348         (void)sizeof(async_test);
12349     #endif
12350 
12351         if (XSTRNCMP(type, "SHA256", 6) == 0) {
12352              ctx->macType = SHA256;
12353              wolfSSL_SHA256_Init(&(ctx->hash.sha256));
12354         }
12355     #ifdef WOLFSSL_SHA224
12356         else if (XSTRNCMP(type, "SHA224", 6) == 0) {
12357              ctx->macType = SHA224;
12358              wolfSSL_SHA224_Init(&(ctx->hash.sha224));
12359         }
12360     #endif
12361     #ifdef WOLFSSL_SHA384
12362         else if (XSTRNCMP(type, "SHA384", 6) == 0) {
12363              ctx->macType = SHA384;
12364              wolfSSL_SHA384_Init(&(ctx->hash.sha384));
12365         }
12366     #endif
12367     #ifdef WOLFSSL_SHA512
12368         else if (XSTRNCMP(type, "SHA512", 6) == 0) {
12369              ctx->macType = SHA512;
12370              wolfSSL_SHA512_Init(&(ctx->hash.sha512));
12371         }
12372     #endif
12373     #ifndef NO_MD5
12374         else if (XSTRNCMP(type, "MD5", 3) == 0) {
12375             ctx->macType = MD5;
12376             wolfSSL_MD5_Init(&(ctx->hash.md5));
12377         }
12378     #endif
12379     #ifndef NO_SHA
12380         /* has to be last since would pick or 224, 256, 384, or 512 too */
12381         else if (XSTRNCMP(type, "SHA", 3) == 0) {
12382              ctx->macType = SHA;
12383              wolfSSL_SHA_Init(&(ctx->hash.sha));
12384         }
12385     #endif /* NO_SHA */
12386         else
12387              return BAD_FUNC_ARG;
12388 
12389         return SSL_SUCCESS;
12390     }
12391 
12392 
12393     /* SSL_SUCCESS on ok */
12394     int wolfSSL_EVP_DigestUpdate(WOLFSSL_EVP_MD_CTX* ctx, const void* data,
12395                                 unsigned long sz)
12396     {
12397         WOLFSSL_ENTER("EVP_DigestUpdate");
12398 
12399         switch (ctx->macType) {
12400 #ifndef NO_MD5
12401             case MD5:
12402                 wolfSSL_MD5_Update((MD5_CTX*)&ctx->hash, data,
12403                                   (unsigned long)sz);
12404                 break;
12405 #endif
12406 #ifndef NO_SHA
12407             case SHA:
12408                 wolfSSL_SHA_Update((SHA_CTX*)&ctx->hash, data,
12409                                   (unsigned long)sz);
12410                 break;
12411 #endif
12412 #ifdef WOLFSSL_SHA224
12413             case SHA224:
12414                 wolfSSL_SHA224_Update((SHA224_CTX*)&ctx->hash, data,
12415                                      (unsigned long)sz);
12416                 break;
12417 #endif
12418 #ifndef NO_SHA256
12419             case SHA256:
12420                 wolfSSL_SHA256_Update((SHA256_CTX*)&ctx->hash, data,
12421                                      (unsigned long)sz);
12422                 break;
12423 #endif
12424 #ifdef WOLFSSL_SHA384
12425             case SHA384:
12426                 wolfSSL_SHA384_Update((SHA384_CTX*)&ctx->hash, data,
12427                                      (unsigned long)sz);
12428                 break;
12429 #endif
12430 #ifdef WOLFSSL_SHA512
12431             case SHA512:
12432                 wolfSSL_SHA512_Update((SHA512_CTX*)&ctx->hash, data,
12433                                      (unsigned long)sz);
12434                 break;
12435 #endif
12436             default:
12437                 return BAD_FUNC_ARG;
12438         }
12439 
12440         return SSL_SUCCESS;
12441     }
12442 
12443 
12444     /* SSL_SUCCESS on ok */
12445     int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md,
12446                                unsigned int* s)
12447     {
12448         WOLFSSL_ENTER("EVP_DigestFinal");
12449         switch (ctx->macType) {
12450 #ifndef NO_MD5
12451             case MD5:
12452                 wolfSSL_MD5_Final(md, (MD5_CTX*)&ctx->hash);
12453                 if (s) *s = MD5_DIGEST_SIZE;
12454                 break;
12455 #endif
12456 #ifndef NO_SHA
12457             case SHA:
12458                 wolfSSL_SHA_Final(md, (SHA_CTX*)&ctx->hash);
12459                 if (s) *s = SHA_DIGEST_SIZE;
12460                 break;
12461 #endif
12462 #ifdef WOLFSSL_SHA224
12463             case SHA224:
12464                 wolfSSL_SHA224_Final(md, (SHA224_CTX*)&ctx->hash);
12465                 if (s) *s = SHA224_DIGEST_SIZE;
12466                 break;
12467 #endif
12468 #ifndef NO_SHA256
12469             case SHA256:
12470                 wolfSSL_SHA256_Final(md, (SHA256_CTX*)&ctx->hash);
12471                 if (s) *s = SHA256_DIGEST_SIZE;
12472                 break;
12473 #endif
12474 #ifdef WOLFSSL_SHA384
12475             case SHA384:
12476                 wolfSSL_SHA384_Final(md, (SHA384_CTX*)&ctx->hash);
12477                 if (s) *s = SHA384_DIGEST_SIZE;
12478                 break;
12479 #endif
12480 #ifdef WOLFSSL_SHA512
12481             case SHA512:
12482                 wolfSSL_SHA512_Final(md, (SHA512_CTX*)&ctx->hash);
12483                 if (s) *s = SHA512_DIGEST_SIZE;
12484                 break;
12485 #endif
12486             default:
12487                 return BAD_FUNC_ARG;
12488         }
12489 
12490         return SSL_SUCCESS;
12491     }
12492 
12493 
12494     /* SSL_SUCCESS on ok */
12495     int wolfSSL_EVP_DigestFinal_ex(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md,
12496                                    unsigned int* s)
12497     {
12498         WOLFSSL_ENTER("EVP_DigestFinal_ex");
12499         return EVP_DigestFinal(ctx, md, s);
12500     }
12501 
12502 
12503     unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, const void* key,
12504                                 int key_len, const unsigned char* d, int n,
12505                                 unsigned char* md, unsigned int* md_len)
12506     {
12507         int type;
12508         unsigned char* ret = NULL;
12509 #ifdef WOLFSSL_SMALL_STACK
12510         Hmac* hmac = NULL;
12511 #else
12512         Hmac  hmac[1];
12513 #endif
12514         void* heap = NULL;
12515 
12516         WOLFSSL_ENTER("HMAC");
12517         if (!md)
12518             return NULL;  /* no static buffer support */
12519 
12520         if (XSTRNCMP(evp_md, "MD5", 3) == 0)
12521             type = MD5;
12522         else if (XSTRNCMP(evp_md, "SHA", 3) == 0)
12523             type = SHA;
12524         else
12525             return NULL;
12526 
12527     #ifdef WOLFSSL_SMALL_STACK
12528         hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_TMP_BUFFER);
12529         if (hmac == NULL)
12530             return NULL;
12531     #endif
12532 
12533         if (wc_HmacInit(hmac, heap, INVALID_DEVID) == 0) {
12534             if (wc_HmacSetKey(hmac, type, (const byte*)key, key_len) == 0) {
12535                 if (wc_HmacUpdate(hmac, d, n) == 0) {
12536                     if (wc_HmacFinal(hmac, md) == 0) {
12537                         if (md_len)
12538                             *md_len = (type == MD5) ? (int)MD5_DIGEST_SIZE
12539                                                     : (int)SHA_DIGEST_SIZE;
12540                         ret = md;
12541                     }
12542                 }
12543             }
12544             wc_HmacFree(hmac);
12545         }
12546 
12547     #ifdef WOLFSSL_SMALL_STACK
12548         XFREE(hmac, heap, DYNAMIC_TYPE_TMP_BUFFER);
12549     #endif
12550 
12551         return ret;
12552     }
12553 
12554     void wolfSSL_ERR_clear_error(void)
12555     {
12556         WOLFSSL_ENTER("wolfSSL_ERR_clear_error");
12557 
12558 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
12559         wc_ClearErrorNodes();
12560 #endif
12561     }
12562 
12563 
12564     int wolfSSL_RAND_status(void)
12565     {
12566         return SSL_SUCCESS;  /* wolfCrypt provides enough seed internally */
12567     }
12568 
12569 
12570 
12571     void wolfSSL_RAND_add(const void* add, int len, double entropy)
12572     {
12573         (void)add;
12574         (void)len;
12575         (void)entropy;
12576 
12577         /* wolfSSL seeds/adds internally, use explicit RNG if you want
12578            to take control */
12579     }
12580 
12581 
12582 #ifndef NO_DES3
12583     /* SSL_SUCCESS on ok */
12584     int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key,
12585                               WOLFSSL_DES_key_schedule* schedule)
12586     {
12587         WOLFSSL_ENTER("DES_key_sched");
12588         XMEMCPY(schedule, key, sizeof(const_DES_cblock));
12589         return SSL_SUCCESS;
12590     }
12591 
12592 
12593     void wolfSSL_DES_cbc_encrypt(const unsigned char* input,
12594                                  unsigned char* output, long length,
12595                                  WOLFSSL_DES_key_schedule* schedule,
12596                                  WOLFSSL_DES_cblock* ivec, int enc)
12597     {
12598         Des myDes;
12599 
12600         WOLFSSL_ENTER("DES_cbc_encrypt");
12601 
12602         /* OpenSSL compat, no ret */
12603         wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
12604 
12605         if (enc)
12606             wc_Des_CbcEncrypt(&myDes, output, input, (word32)length);
12607         else
12608             wc_Des_CbcDecrypt(&myDes, output, input, (word32)length);
12609     }
12610 
12611 
12612     /* WOLFSSL_DES_key_schedule is a unsigned char array of size 8 */
12613     void wolfSSL_DES_ede3_cbc_encrypt(const unsigned char* input,
12614                                       unsigned char* output, long sz,
12615                                       WOLFSSL_DES_key_schedule* ks1,
12616                                       WOLFSSL_DES_key_schedule* ks2,
12617                                       WOLFSSL_DES_key_schedule* ks3,
12618                                       WOLFSSL_DES_cblock* ivec, int enc)
12619     {
12620         Des3 des;
12621         byte key[24];/* EDE uses 24 size key */
12622 
12623         WOLFSSL_ENTER("wolfSSL_DES_ede3_cbc_encrypt");
12624 
12625         XMEMSET(key, 0, sizeof(key));
12626         XMEMCPY(key, *ks1, DES_BLOCK_SIZE);
12627         XMEMCPY(&key[DES_BLOCK_SIZE], *ks2, DES_BLOCK_SIZE);
12628         XMEMCPY(&key[DES_BLOCK_SIZE * 2], *ks3, DES_BLOCK_SIZE);
12629 
12630         if (enc) {
12631             wc_Des3_SetKey(&des, key, (const byte*)ivec, DES_ENCRYPTION);
12632             wc_Des3_CbcEncrypt(&des, output, input, (word32)sz);
12633         }
12634         else {
12635             wc_Des3_SetKey(&des, key, (const byte*)ivec, DES_DECRYPTION);
12636             wc_Des3_CbcDecrypt(&des, output, input, (word32)sz);
12637         }
12638     }
12639 
12640 
12641     /* correctly sets ivec for next call */
12642     void wolfSSL_DES_ncbc_encrypt(const unsigned char* input,
12643                      unsigned char* output, long length,
12644                      WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec,
12645                      int enc)
12646     {
12647         Des myDes;
12648 
12649         WOLFSSL_ENTER("DES_ncbc_encrypt");
12650 
12651         /* OpenSSL compat, no ret */
12652         wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
12653 
12654         if (enc)
12655             wc_Des_CbcEncrypt(&myDes, output, input, (word32)length);
12656         else
12657             wc_Des_CbcDecrypt(&myDes, output, input, (word32)length);
12658 
12659         XMEMCPY(ivec, output + length - sizeof(DES_cblock), sizeof(DES_cblock));
12660     }
12661 
12662 #endif /* NO_DES3 */
12663 
12664 
12665     void wolfSSL_ERR_free_strings(void)
12666     {
12667         /* handled internally */
12668     }
12669 
12670 
12671     void wolfSSL_ERR_remove_state(unsigned long state)
12672     {
12673         /* TODO: GetErrors().Remove(); */
12674         (void)state;
12675     }
12676 
12677 
12678     void wolfSSL_EVP_cleanup(void)
12679     {
12680         /* nothing to do here */
12681     }
12682 
12683 
12684     void wolfSSL_cleanup_all_ex_data(void)
12685     {
12686         /* nothing to do here */
12687     }
12688 
12689 
12690     int wolfSSL_clear(WOLFSSL* ssl)
12691     {
12692         ssl->options.isClosed = 0;
12693         ssl->options.connReset = 0;
12694         ssl->options.sentNotify = 0;
12695 
12696         ssl->options.serverState = NULL_STATE;
12697         ssl->options.clientState = NULL_STATE;
12698         ssl->options.connectState = CONNECT_BEGIN;
12699         ssl->options.acceptState  = ACCEPT_BEGIN;
12700         ssl->options.handShakeState  = NULL_STATE;
12701         ssl->options.handShakeDone = 0;
12702         /* ssl->options.processReply = doProcessInit; */
12703 
12704         ssl->keys.encryptionOn = 0;
12705         XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
12706 
12707 #ifndef NO_OLD_TLS
12708 #ifndef NO_MD5
12709         wc_InitMd5(&ssl->hsHashes->hashMd5);
12710 #endif
12711 #ifndef NO_SHA
12712         if (wc_InitSha(&ssl->hsHashes->hashSha) != 0)
12713             return SSL_FAILURE;
12714 #endif
12715 #endif
12716 #ifndef NO_SHA256
12717         if (wc_InitSha256(&ssl->hsHashes->hashSha256) != 0)
12718             return SSL_FAILURE;
12719 #endif
12720 #ifdef WOLFSSL_SHA384
12721         if (wc_InitSha384(&ssl->hsHashes->hashSha384) != 0)
12722             return SSL_FAILURE;
12723 #endif
12724 #ifdef WOLFSSL_SHA512
12725         if (wc_InitSha512(&ssl->hsHashes->hashSha512) != 0)
12726             return SSL_FAILURE;
12727 #endif
12728 
12729 #ifdef KEEP_PEER_CERT
12730         FreeX509(&ssl->peerCert);
12731         InitX509(&ssl->peerCert, 0, ssl->heap);
12732 #endif
12733 
12734         return SSL_SUCCESS;
12735     }
12736 
12737 
12738     long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t)
12739     {
12740         word32 tmptime;
12741         if (!ses || t < 0)
12742             return BAD_FUNC_ARG;
12743 
12744         tmptime = t & 0xFFFFFFFF;
12745 
12746         ses->timeout = tmptime;
12747 
12748         return SSL_SUCCESS;
12749     }
12750 
12751 
12752     long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode)
12753     {
12754         /* SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
12755 
12756         WOLFSSL_ENTER("SSL_CTX_set_mode");
12757         if (mode == SSL_MODE_ENABLE_PARTIAL_WRITE)
12758             ctx->partialWrite = 1;
12759 
12760         return mode;
12761     }
12762 
12763 
12764     long wolfSSL_SSL_get_mode(WOLFSSL* ssl)
12765     {
12766         /* TODO: */
12767         (void)ssl;
12768         return 0;
12769     }
12770 
12771 
12772     long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx)
12773     {
12774         /* TODO: */
12775         (void)ctx;
12776         return 0;
12777     }
12778 
12779 
12780     void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m)
12781     {
12782         /* TODO: maybe? */
12783         (void)ctx;
12784         (void)m;
12785     }
12786 
12787 
12788     int wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX* ctx,
12789                                            const unsigned char* sid_ctx,
12790                                            unsigned int sid_ctx_len)
12791     {
12792         /* No application specific context needed for wolfSSL */
12793         (void)ctx;
12794         (void)sid_ctx;
12795         (void)sid_ctx_len;
12796         return SSL_SUCCESS;
12797     }
12798 
12799 
12800     long wolfSSL_CTX_sess_get_cache_size(WOLFSSL_CTX* ctx)
12801     {
12802         (void)ctx;
12803         #ifndef NO_SESSION_CACHE
12804             return SESSIONS_PER_ROW * SESSION_ROWS;
12805         #else
12806             return 0;
12807         #endif
12808     }
12809 
12810     unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line,
12811                                                   const char** data, int *flags)
12812     {
12813         /* Not implemented */
12814         (void)file;
12815         (void)line;
12816         (void)data;
12817         (void)flags;
12818         return 0;
12819     }
12820 
12821     WOLFSSL_API pem_password_cb* wolfSSL_CTX_get_default_passwd_cb(
12822                                                                WOLFSSL_CTX *ctx)
12823     {
12824         if (ctx == NULL || ctx->passwd_cb == NULL) {
12825             return NULL;
12826         }
12827 
12828         return ctx->passwd_cb;
12829     }
12830 
12831 
12832     WOLFSSL_API void *wolfSSL_CTX_get_default_passwd_cb_userdata(
12833                                                                WOLFSSL_CTX *ctx)
12834     {
12835         if (ctx == NULL) {
12836             return NULL;
12837         }
12838 
12839         return ctx->userdata;
12840     }
12841 
12842 #endif /* OPENSSL_EXTRA */
12843 
12844 
12845 #if defined(KEEP_PEER_CERT)
12846     #ifdef SESSION_CERTS
12847     /* Decode the X509 DER encoded certificate into a WOLFSSL_X509 object.
12848      *
12849      * x509  WOLFSSL_X509 object to decode into.
12850      * in    X509 DER data.
12851      * len   Length of the X509 DER data.
12852      * returns the new certificate on success, otherwise NULL.
12853      */
12854     static int DecodeToX509(WOLFSSL_X509* x509, const byte* in, int len)
12855     {
12856         int          ret;
12857     #ifdef WOLFSSL_SMALL_STACK
12858         DecodedCert* cert = NULL;
12859     #else
12860         DecodedCert  cert[1];
12861     #endif
12862 
12863     #ifdef WOLFSSL_SMALL_STACK
12864         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
12865                                      DYNAMIC_TYPE_TMP_BUFFER);
12866         if (cert == NULL)
12867             return MEMORY_E;
12868     #endif
12869 
12870         /* Create a DecodedCert object and copy fields into WOLFSSL_X509 object.
12871          */
12872         InitDecodedCert(cert, (byte*)in, len, NULL);
12873         if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) == 0) {
12874             InitX509(x509, 0, NULL);
12875             ret = CopyDecodedToX509(x509, cert);
12876             FreeDecodedCert(cert);
12877         }
12878     #ifdef WOLFSSL_SMALL_STACK
12879         XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12880     #endif
12881 
12882         return ret;
12883     }
12884     #endif
12885 
12886 
12887     WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl)
12888     {
12889         WOLFSSL_ENTER("SSL_get_peer_certificate");
12890         if (ssl->peerCert.issuer.sz)
12891             return &ssl->peerCert;
12892 #ifdef SESSION_CERTS
12893         else if (ssl->session.chain.count > 0) {
12894             if (DecodeToX509(&ssl->peerCert, ssl->session.chain.certs[0].buffer,
12895                     ssl->session.chain.certs[0].length) == 0) {
12896                 return &ssl->peerCert;
12897             }
12898         }
12899 #endif
12900         return 0;
12901     }
12902 
12903 #endif /* KEEP_PEER_CERT */
12904 
12905 
12906 #ifndef NO_CERTS
12907 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || defined(OPENSSL_EXTRA)
12908 
12909 /* user externally called free X509, if dynamic go ahead with free, otherwise
12910  * don't */
12911 static void ExternalFreeX509(WOLFSSL_X509* x509)
12912 {
12913     WOLFSSL_ENTER("ExternalFreeX509");
12914     if (x509) {
12915         if (x509->dynamicMemory) {
12916             FreeX509(x509);
12917             XFREE(x509, x509->heap, DYNAMIC_TYPE_X509);
12918         } else {
12919             WOLFSSL_MSG("free called on non dynamic object, not freeing");
12920         }
12921     }
12922 }
12923 
12924 #endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSSL_EXTRA */
12925 
12926 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
12927 
12928     void wolfSSL_FreeX509(WOLFSSL_X509* x509)
12929     {
12930         WOLFSSL_ENTER("wolfSSL_FreeX509");
12931         ExternalFreeX509(x509);
12932     }
12933 
12934     /* return the next, if any, altname from the peer cert */
12935     char* wolfSSL_X509_get_next_altname(WOLFSSL_X509* cert)
12936     {
12937         char* ret = NULL;
12938         WOLFSSL_ENTER("wolfSSL_X509_get_next_altname");
12939 
12940         /* don't have any to work with */
12941         if (cert == NULL || cert->altNames == NULL)
12942             return NULL;
12943 
12944         /* already went through them */
12945         if (cert->altNamesNext == NULL)
12946             return NULL;
12947 
12948         ret = cert->altNamesNext->name;
12949         cert->altNamesNext = cert->altNamesNext->next;
12950 
12951         return ret;
12952     }
12953 
12954 
12955     WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509* cert)
12956     {
12957         WOLFSSL_ENTER("X509_get_issuer_name");
12958         if (cert && cert->issuer.sz != 0)
12959             return &cert->issuer;
12960         return NULL;
12961     }
12962 
12963 
12964     WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
12965     {
12966         WOLFSSL_ENTER("wolfSSL_X509_get_subject_name");
12967         if (cert && cert->subject.sz != 0)
12968             return &cert->subject;
12969         return NULL;
12970     }
12971 
12972 
12973     int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509)
12974     {
12975         int isCA = 0;
12976 
12977         WOLFSSL_ENTER("wolfSSL_X509_get_isCA");
12978 
12979         if (x509 != NULL)
12980             isCA = x509->isCa;
12981 
12982         WOLFSSL_LEAVE("wolfSSL_X509_get_isCA", isCA);
12983 
12984         return isCA;
12985     }
12986 
12987 
12988 #ifdef OPENSSL_EXTRA
12989     int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509* x509, int nid)
12990     {
12991         int isSet = 0;
12992 
12993         WOLFSSL_ENTER("wolfSSL_X509_ext_isSet_by_NID");
12994 
12995         if (x509 != NULL) {
12996             switch (nid) {
12997                 case BASIC_CA_OID: isSet = x509->basicConstSet; break;
12998                 case ALT_NAMES_OID: isSet = x509->subjAltNameSet; break;
12999                 case AUTH_KEY_OID: isSet = x509->authKeyIdSet; break;
13000                 case SUBJ_KEY_OID: isSet = x509->subjKeyIdSet; break;
13001                 case KEY_USAGE_OID: isSet = x509->keyUsageSet; break;
13002                 #ifdef WOLFSSL_SEP
13003                     case CERT_POLICY_OID: isSet = x509->certPolicySet; break;
13004                 #endif /* WOLFSSL_SEP */
13005             }
13006         }
13007 
13008         WOLFSSL_LEAVE("wolfSSL_X509_ext_isSet_by_NID", isSet);
13009 
13010         return isSet;
13011     }
13012 
13013 
13014     int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509* x509, int nid)
13015     {
13016         int crit = 0;
13017 
13018         WOLFSSL_ENTER("wolfSSL_X509_ext_get_critical_by_NID");
13019 
13020         if (x509 != NULL) {
13021             switch (nid) {
13022                 case BASIC_CA_OID: crit = x509->basicConstCrit; break;
13023                 case ALT_NAMES_OID: crit = x509->subjAltNameCrit; break;
13024                 case AUTH_KEY_OID: crit = x509->authKeyIdCrit; break;
13025                 case SUBJ_KEY_OID: crit = x509->subjKeyIdCrit; break;
13026                 case KEY_USAGE_OID: crit = x509->keyUsageCrit; break;
13027                 #ifdef WOLFSSL_SEP
13028                     case CERT_POLICY_OID: crit = x509->certPolicyCrit; break;
13029                 #endif /* WOLFSSL_SEP */
13030             }
13031         }
13032 
13033         WOLFSSL_LEAVE("wolfSSL_X509_ext_get_critical_by_NID", crit);
13034 
13035         return crit;
13036     }
13037 
13038 
13039     int wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509* x509)
13040     {
13041         int isSet = 0;
13042 
13043         WOLFSSL_ENTER("wolfSSL_X509_get_isSet_pathLength");
13044 
13045         if (x509 != NULL)
13046             isSet = x509->basicConstPlSet;
13047 
13048         WOLFSSL_LEAVE("wolfSSL_X509_get_isSet_pathLength", isSet);
13049 
13050         return isSet;
13051     }
13052 
13053 
13054     word32 wolfSSL_X509_get_pathLength(WOLFSSL_X509* x509)
13055     {
13056         word32 pathLength = 0;
13057 
13058         WOLFSSL_ENTER("wolfSSL_X509_get_pathLength");
13059 
13060         if (x509 != NULL)
13061             pathLength = x509->pathLength;
13062 
13063         WOLFSSL_LEAVE("wolfSSL_X509_get_pathLength", pathLength);
13064 
13065         return pathLength;
13066     }
13067 
13068 
13069     unsigned int wolfSSL_X509_get_keyUsage(WOLFSSL_X509* x509)
13070     {
13071         word16 usage = 0;
13072 
13073         WOLFSSL_ENTER("wolfSSL_X509_get_keyUsage");
13074 
13075         if (x509 != NULL)
13076             usage = x509->keyUsage;
13077 
13078         WOLFSSL_LEAVE("wolfSSL_X509_get_keyUsage", usage);
13079 
13080         return usage;
13081     }
13082 
13083 
13084     byte* wolfSSL_X509_get_authorityKeyID(WOLFSSL_X509* x509,
13085                                           byte* dst, int* dstLen)
13086     {
13087         byte *id = NULL;
13088         int copySz = 0;
13089 
13090         WOLFSSL_ENTER("wolfSSL_X509_get_authorityKeyID");
13091 
13092         if (x509 != NULL) {
13093             if (x509->authKeyIdSet) {
13094                 copySz = min(dstLen != NULL ? *dstLen : 0,
13095                              (int)x509->authKeyIdSz);
13096                 id = x509->authKeyId;
13097             }
13098 
13099             if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
13100                 XMEMCPY(dst, id, copySz);
13101                 id = dst;
13102                 *dstLen = copySz;
13103             }
13104         }
13105 
13106         WOLFSSL_LEAVE("wolfSSL_X509_get_authorityKeyID", copySz);
13107 
13108         return id;
13109     }
13110 
13111 
13112     byte* wolfSSL_X509_get_subjectKeyID(WOLFSSL_X509* x509,
13113                                         byte* dst, int* dstLen)
13114     {
13115         byte *id = NULL;
13116         int copySz = 0;
13117 
13118         WOLFSSL_ENTER("wolfSSL_X509_get_subjectKeyID");
13119 
13120         if (x509 != NULL) {
13121             if (x509->subjKeyIdSet) {
13122                 copySz = min(dstLen != NULL ? *dstLen : 0,
13123                                                         (int)x509->subjKeyIdSz);
13124                 id = x509->subjKeyId;
13125             }
13126 
13127             if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
13128                 XMEMCPY(dst, id, copySz);
13129                 id = dst;
13130                 *dstLen = copySz;
13131             }
13132         }
13133 
13134         WOLFSSL_LEAVE("wolfSSL_X509_get_subjectKeyID", copySz);
13135 
13136         return id;
13137     }
13138 
13139 
13140     int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME* name)
13141     {
13142         int count = 0;
13143 
13144         WOLFSSL_ENTER("wolfSSL_X509_NAME_entry_count");
13145 
13146         if (name != NULL)
13147             count = name->fullName.entryCount;
13148 
13149         WOLFSSL_LEAVE("wolfSSL_X509_NAME_entry_count", count);
13150         return count;
13151     }
13152 
13153 
13154     int wolfSSL_X509_NAME_get_text_by_NID(WOLFSSL_X509_NAME* name,
13155                                           int nid, char* buf, int len)
13156     {
13157         char *text = NULL;
13158         int textSz = 0;
13159 
13160         WOLFSSL_ENTER("wolfSSL_X509_NAME_get_text_by_NID");
13161 
13162         switch (nid) {
13163             case ASN_COMMON_NAME:
13164                 text = name->fullName.fullName + name->fullName.cnIdx;
13165                 textSz = name->fullName.cnLen;
13166                 break;
13167             case ASN_SUR_NAME:
13168                 text = name->fullName.fullName + name->fullName.snIdx;
13169                 textSz = name->fullName.snLen;
13170                 break;
13171             case ASN_SERIAL_NUMBER:
13172                 text = name->fullName.fullName + name->fullName.serialIdx;
13173                 textSz = name->fullName.serialLen;
13174                 break;
13175             case ASN_COUNTRY_NAME:
13176                 text = name->fullName.fullName + name->fullName.cIdx;
13177                 textSz = name->fullName.cLen;
13178                 break;
13179             case ASN_LOCALITY_NAME:
13180                 text = name->fullName.fullName + name->fullName.lIdx;
13181                 textSz = name->fullName.lLen;
13182                 break;
13183             case ASN_STATE_NAME:
13184                 text = name->fullName.fullName + name->fullName.stIdx;
13185                 textSz = name->fullName.stLen;
13186                 break;
13187             case ASN_ORG_NAME:
13188                 text = name->fullName.fullName + name->fullName.oIdx;
13189                 textSz = name->fullName.oLen;
13190                 break;
13191             case ASN_ORGUNIT_NAME:
13192                 text = name->fullName.fullName + name->fullName.ouIdx;
13193                 textSz = name->fullName.ouLen;
13194                 break;
13195             default:
13196                 break;
13197         }
13198 
13199         if (buf != NULL && text != NULL) {
13200             textSz = min(textSz, len);
13201             if (textSz > 0) {
13202                 XMEMCPY(buf, text, textSz - 1);
13203                 buf[textSz - 1] = '\0';
13204             }
13205         }
13206 
13207         WOLFSSL_LEAVE("wolfSSL_X509_NAME_get_text_by_NID", textSz);
13208         return textSz;
13209     }
13210 
13211     int wolfSSL_X509_NAME_get_index_by_NID(WOLFSSL_X509_NAME* name,
13212                                           int nid, int pos)
13213     {
13214         int ret    = -1;
13215 
13216         WOLFSSL_ENTER("wolfSSL_X509_NAME_get_index_by_NID");
13217 
13218         if (name == NULL) {
13219             return BAD_FUNC_ARG;
13220         }
13221 
13222         /* these index values are already stored in DecodedName
13223            use those when available */
13224         if (name->fullName.fullName && name->fullName.fullNameLen > 0) {
13225             switch (nid) {
13226                 case ASN_COMMON_NAME:
13227                     if (pos != name->fullName.cnIdx)
13228                         ret = name->fullName.cnIdx;
13229                     break;
13230                 default:
13231                     WOLFSSL_MSG("NID not yet implemented");
13232                     break;
13233             }
13234         }
13235 
13236         WOLFSSL_LEAVE("wolfSSL_X509_NAME_get_index_by_NID", ret);
13237 
13238         (void)pos;
13239         (void)nid;
13240 
13241         return ret;
13242     }
13243 
13244 
13245     WOLFSSL_ASN1_STRING*  wolfSSL_X509_NAME_ENTRY_get_data(
13246                                                     WOLFSSL_X509_NAME_ENTRY* in)
13247     {
13248         WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_data");
13249         return in->value;
13250     }
13251 
13252 
13253     char* wolfSSL_ASN1_STRING_data(WOLFSSL_ASN1_STRING* asn)
13254     {
13255         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_data");
13256 
13257         if (asn) {
13258             return asn->data;
13259         }
13260         else {
13261             return NULL;
13262         }
13263     }
13264 
13265 
13266     int wolfSSL_ASN1_STRING_length(WOLFSSL_ASN1_STRING* asn)
13267     {
13268         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_length");
13269 
13270         if (asn) {
13271             return asn->length;
13272         }
13273         else {
13274             return 0;
13275         }
13276     }
13277 #endif
13278 
13279 
13280     /* copy name into in buffer, at most sz bytes, if buffer is null will
13281        malloc buffer, call responsible for freeing                     */
13282     char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
13283     {
13284         int copySz = min(sz, name->sz);
13285 
13286         WOLFSSL_ENTER("wolfSSL_X509_NAME_oneline");
13287         if (!name->sz) return in;
13288 
13289         if (!in) {
13290         #ifdef WOLFSSL_STATIC_MEMORY
13291             WOLFSSL_MSG("Using static memory -- please pass in a buffer");
13292             return NULL;
13293         #else
13294             in = (char*)XMALLOC(name->sz, NULL, DYNAMIC_TYPE_OPENSSL);
13295             if (!in ) return in;
13296             copySz = name->sz;
13297         #endif
13298         }
13299 
13300         if (copySz == 0)
13301             return in;
13302 
13303         XMEMCPY(in, name->name, copySz - 1);
13304         in[copySz - 1] = 0;
13305 
13306         return in;
13307     }
13308 
13309 
13310     int wolfSSL_X509_get_signature_type(WOLFSSL_X509* x509)
13311     {
13312         int type = 0;
13313 
13314         WOLFSSL_ENTER("wolfSSL_X509_get_signature_type");
13315 
13316         if (x509 != NULL)
13317             type = x509->sigOID;
13318 
13319         return type;
13320     }
13321 
13322 
13323     int wolfSSL_X509_get_signature(WOLFSSL_X509* x509,
13324                                                  unsigned char* buf, int* bufSz)
13325     {
13326         WOLFSSL_ENTER("wolfSSL_X509_get_signature");
13327         if (x509 == NULL || bufSz == NULL || *bufSz < (int)x509->sig.length)
13328             return SSL_FATAL_ERROR;
13329 
13330         if (buf != NULL)
13331             XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
13332         *bufSz = x509->sig.length;
13333 
13334         return SSL_SUCCESS;
13335     }
13336 
13337 
13338     /* write X509 serial number in unsigned binary to buffer
13339        buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
13340        return SSL_SUCCESS on success */
13341     int wolfSSL_X509_get_serial_number(WOLFSSL_X509* x509,
13342                                        byte* in, int* inOutSz)
13343     {
13344         WOLFSSL_ENTER("wolfSSL_X509_get_serial_number");
13345         if (x509 == NULL || in == NULL ||
13346                                    inOutSz == NULL || *inOutSz < x509->serialSz)
13347             return BAD_FUNC_ARG;
13348 
13349         XMEMCPY(in, x509->serial, x509->serialSz);
13350         *inOutSz = x509->serialSz;
13351 
13352         return SSL_SUCCESS;
13353     }
13354 
13355 
13356     const byte* wolfSSL_X509_get_der(WOLFSSL_X509* x509, int* outSz)
13357     {
13358         WOLFSSL_ENTER("wolfSSL_X509_get_der");
13359 
13360         if (x509 == NULL || outSz == NULL)
13361             return NULL;
13362 
13363         *outSz = (int)x509->derCert->length;
13364         return x509->derCert->buffer;
13365     }
13366 
13367 
13368     int wolfSSL_X509_version(WOLFSSL_X509* x509)
13369     {
13370         WOLFSSL_ENTER("wolfSSL_X509_version");
13371 
13372         if (x509 == NULL)
13373             return 0;
13374 
13375         return x509->version;
13376     }
13377 
13378 
13379     const byte* wolfSSL_X509_notBefore(WOLFSSL_X509* x509)
13380     {
13381         WOLFSSL_ENTER("wolfSSL_X509_notBefore");
13382 
13383         if (x509 == NULL)
13384             return NULL;
13385 
13386         return x509->notBefore;
13387     }
13388 
13389 
13390     const byte* wolfSSL_X509_notAfter(WOLFSSL_X509* x509)
13391     {
13392         WOLFSSL_ENTER("wolfSSL_X509_notAfter");
13393 
13394         if (x509 == NULL)
13395             return NULL;
13396 
13397         return x509->notAfter;
13398     }
13399 
13400 
13401 #ifdef WOLFSSL_SEP
13402 
13403 /* copy oid into in buffer, at most *inOutSz bytes, if buffer is null will
13404    malloc buffer, call responsible for freeing. Actual size returned in
13405    *inOutSz. Requires inOutSz be non-null */
13406 byte* wolfSSL_X509_get_device_type(WOLFSSL_X509* x509, byte* in, int *inOutSz)
13407 {
13408     int copySz;
13409 
13410     WOLFSSL_ENTER("wolfSSL_X509_get_dev_type");
13411     if (inOutSz == NULL) return NULL;
13412     if (!x509->deviceTypeSz) return in;
13413 
13414     copySz = min(*inOutSz, x509->deviceTypeSz);
13415 
13416     if (!in) {
13417     #ifdef WOLFSSL_STATIC_MEMORY
13418         WOLFSSL_MSG("Using static memory -- please pass in a buffer");
13419         return NULL;
13420     #else
13421         in = (byte*)XMALLOC(x509->deviceTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
13422         if (!in) return in;
13423         copySz = x509->deviceTypeSz;
13424     #endif
13425     }
13426 
13427     XMEMCPY(in, x509->deviceType, copySz);
13428     *inOutSz = copySz;
13429 
13430     return in;
13431 }
13432 
13433 
13434 byte* wolfSSL_X509_get_hw_type(WOLFSSL_X509* x509, byte* in, int* inOutSz)
13435 {
13436     int copySz;
13437 
13438     WOLFSSL_ENTER("wolfSSL_X509_get_hw_type");
13439     if (inOutSz == NULL) return NULL;
13440     if (!x509->hwTypeSz) return in;
13441 
13442     copySz = min(*inOutSz, x509->hwTypeSz);
13443 
13444     if (!in) {
13445     #ifdef WOLFSSL_STATIC_MEMORY
13446         WOLFSSL_MSG("Using static memory -- please pass in a buffer");
13447         return NULL;
13448     #else
13449         in = (byte*)XMALLOC(x509->hwTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
13450         if (!in) return in;
13451         copySz = x509->hwTypeSz;
13452     #endif
13453     }
13454 
13455     XMEMCPY(in, x509->hwType, copySz);
13456     *inOutSz = copySz;
13457 
13458     return in;
13459 }
13460 
13461 
13462 byte* wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509* x509,byte* in,
13463                                         int* inOutSz)
13464 {
13465     int copySz;
13466 
13467     WOLFSSL_ENTER("wolfSSL_X509_get_hw_serial_number");
13468     if (inOutSz == NULL) return NULL;
13469     if (!x509->hwTypeSz) return in;
13470 
13471     copySz = min(*inOutSz, x509->hwSerialNumSz);
13472 
13473     if (!in) {
13474     #ifdef WOLFSSL_STATIC_MEMORY
13475         WOLFSSL_MSG("Using static memory -- please pass in a buffer");
13476         return NULL;
13477     #else
13478         in = (byte*)XMALLOC(x509->hwSerialNumSz, 0, DYNAMIC_TYPE_OPENSSL);
13479         if (!in) return in;
13480         copySz = x509->hwSerialNumSz;
13481     #endif
13482     }
13483 
13484     XMEMCPY(in, x509->hwSerialNum, copySz);
13485     *inOutSz = copySz;
13486 
13487     return in;
13488 }
13489 
13490 #endif /* WOLFSSL_SEP */
13491 
13492 /* require OPENSSL_EXTRA since wolfSSL_X509_free is wrapped by OPENSSL_EXTRA */
13493 #if !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
13494 /* return 1 on success 0 on fail */
13495 int wolfSSL_sk_X509_push(STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509* x509)
13496 {
13497     WOLFSSL_STACK* node;
13498 
13499     if (sk == NULL || x509 == NULL) {
13500         return SSL_FAILURE;
13501     }
13502 
13503     /* no previous values in stack */
13504     if (sk->data.x509 == NULL) {
13505         sk->data.x509 = x509;
13506         sk->num += 1;
13507         return SSL_SUCCESS;
13508     }
13509 
13510     /* stack already has value(s) create a new node and add more */
13511     node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
13512                                                              DYNAMIC_TYPE_X509);
13513     if (node == NULL) {
13514         WOLFSSL_MSG("Memory error");
13515         return SSL_FAILURE;
13516     }
13517     XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
13518 
13519     /* push new x509 onto head of stack */
13520     node->data.x509 = sk->data.x509;
13521     node->next      = sk->next;
13522     sk->next        = node;
13523     sk->data.x509   = x509;
13524     sk->num        += 1;
13525 
13526     return SSL_SUCCESS;
13527 }
13528 
13529 
13530 WOLFSSL_X509* wolfSSL_sk_X509_pop(STACK_OF(WOLFSSL_X509_NAME)* sk) {
13531     WOLFSSL_STACK* node;
13532     WOLFSSL_X509*  x509;
13533 
13534     if (sk == NULL) {
13535         return NULL;
13536     }
13537 
13538     node = sk->next;
13539     x509 = sk->data.x509;
13540 
13541     if (node != NULL) { /* update sk and remove node from stack */
13542         sk->data.x509 = node->data.x509;
13543         sk->next = node->next;
13544         XFREE(node, NULL, DYNAMIC_TYPE_X509);
13545     }
13546     else { /* last x509 in stack */
13547         sk->data.x509 = NULL;
13548     }
13549 
13550     if (sk->num > 0) {
13551         sk->num -= 1;
13552     }
13553 
13554     return x509;
13555 }
13556 
13557 
13558 /* free structure for x509 stack */
13559 void wolfSSL_sk_X509_free(STACK_OF(WOLFSSL_X509_NAME)* sk) {
13560     WOLFSSL_STACK* node;
13561 
13562     if (sk == NULL) {
13563         return;
13564     }
13565 
13566     /* parse through stack freeing each node */
13567     node = sk->next;
13568     while (sk->num > 1) {
13569         WOLFSSL_STACK* tmp = node;
13570         node = node->next;
13571 
13572         wolfSSL_X509_free(tmp->data.x509);
13573         XFREE(tmp, NULL, DYNAMIC_TYPE_X509);
13574         sk->num -= 1;
13575     }
13576 
13577     /* free head of stack */
13578     if (sk->num == 1) {
13579     wolfSSL_X509_free(sk->data.x509);
13580     }
13581     XFREE(sk, NULL, DYNAMIC_TYPE_X509);
13582 }
13583 #endif /* NO_CERTS && OPENSSL_EXTRA */
13584 
13585 WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
13586 {
13587     WOLFSSL_X509 *newX509 = NULL;
13588 
13589     WOLFSSL_ENTER("wolfSSL_X509_d2i");
13590 
13591     if (in != NULL && len != 0) {
13592     #ifdef WOLFSSL_SMALL_STACK
13593         DecodedCert* cert = NULL;
13594     #else
13595         DecodedCert  cert[1];
13596     #endif
13597 
13598     #ifdef WOLFSSL_SMALL_STACK
13599         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
13600                                      DYNAMIC_TYPE_TMP_BUFFER);
13601         if (cert == NULL)
13602             return NULL;
13603     #endif
13604 
13605         InitDecodedCert(cert, (byte*)in, len, NULL);
13606         if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
13607             newX509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
13608                                              DYNAMIC_TYPE_X509);
13609             if (newX509 != NULL) {
13610                 InitX509(newX509, 1, NULL);
13611                 if (CopyDecodedToX509(newX509, cert) != 0) {
13612                     XFREE(newX509, NULL, DYNAMIC_TYPE_X509);
13613                     newX509 = NULL;
13614                 }
13615             }
13616         }
13617         FreeDecodedCert(cert);
13618     #ifdef WOLFSSL_SMALL_STACK
13619         XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13620     #endif
13621     }
13622 
13623     if (x509 != NULL)
13624         *x509 = newX509;
13625 
13626     return newX509;
13627 }
13628 
13629 
13630 #ifndef NO_FILESYSTEM
13631 
13632 #ifndef NO_STDIO_FILESYSTEM
13633 
13634 WOLFSSL_X509* wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file)
13635 {
13636     WOLFSSL_X509* newX509 = NULL;
13637 
13638     WOLFSSL_ENTER("wolfSSL_X509_d2i_fp");
13639 
13640     if (file != XBADFILE) {
13641         byte* fileBuffer = NULL;
13642         long sz = 0;
13643 
13644         XFSEEK(file, 0, XSEEK_END);
13645         sz = XFTELL(file);
13646         XREWIND(file);
13647 
13648         if (sz < 0) {
13649             WOLFSSL_MSG("Bad tell on FILE");
13650             return NULL;
13651         }
13652 
13653         fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
13654         if (fileBuffer != NULL) {
13655             int ret = (int)XFREAD(fileBuffer, 1, sz, file);
13656             if (ret == sz) {
13657                 newX509 = wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
13658             }
13659             XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
13660         }
13661     }
13662 
13663     if (x509 != NULL)
13664         *x509 = newX509;
13665 
13666     return newX509;
13667 }
13668 
13669 #endif /* NO_STDIO_FILESYSTEM */
13670 
13671 WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format)
13672 {
13673 #ifdef WOLFSSL_SMALL_STACK
13674     byte  staticBuffer[1]; /* force heap usage */
13675 #else
13676     byte  staticBuffer[FILE_BUFFER_SIZE];
13677 #endif
13678     byte* fileBuffer = staticBuffer;
13679     int   dynamic = 0;
13680     int   ret;
13681     long  sz = 0;
13682     XFILE file;
13683 
13684     WOLFSSL_X509* x509 = NULL;
13685 
13686     /* Check the inputs */
13687     if ((fname == NULL) ||
13688         (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM))
13689         return NULL;
13690 
13691     file = XFOPEN(fname, "rb");
13692     if (file == XBADFILE)
13693         return NULL;
13694 
13695     XFSEEK(file, 0, XSEEK_END);
13696     sz = XFTELL(file);
13697     XREWIND(file);
13698 
13699     if (sz > (long)sizeof(staticBuffer)) {
13700         fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
13701         if (fileBuffer == NULL) {
13702             XFCLOSE(file);
13703             return NULL;
13704         }
13705         dynamic = 1;
13706     }
13707     else if (sz < 0) {
13708         XFCLOSE(file);
13709         return NULL;
13710     }
13711 
13712     ret = (int)XFREAD(fileBuffer, 1, sz, file);
13713     if (ret != sz) {
13714         XFCLOSE(file);
13715         if (dynamic)
13716             XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
13717         return NULL;
13718     }
13719 
13720     XFCLOSE(file);
13721 
13722     x509 = wolfSSL_X509_load_certificate_buffer(fileBuffer, (int)sz, format);
13723 
13724     if (dynamic)
13725         XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
13726 
13727     return x509;
13728 }
13729 
13730 #endif /* NO_FILESYSTEM */
13731 
13732 
13733 WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer(
13734     const unsigned char* buf, int sz, int format)
13735 {
13736     int ret;
13737     WOLFSSL_X509* x509 = NULL;
13738     DerBuffer* der = NULL;
13739 
13740     WOLFSSL_ENTER("wolfSSL_X509_load_certificate_ex");
13741 
13742     if (format == SSL_FILETYPE_PEM) {
13743         int ecc = 0;
13744     #ifdef WOLFSSL_SMALL_STACK
13745         EncryptedInfo* info = NULL;
13746     #else
13747         EncryptedInfo  info[1];
13748     #endif
13749 
13750     #ifdef WOLFSSL_SMALL_STACK
13751         info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
13752                                                       DYNAMIC_TYPE_TMP_BUFFER);
13753         if (info == NULL) {
13754             return NULL;
13755         }
13756     #endif
13757 
13758         info->set = 0;
13759         info->ctx = NULL;
13760         info->consumed = 0;
13761 
13762         if (PemToDer(buf, sz, CERT_TYPE, &der, NULL, info, &ecc) != 0) {
13763             FreeDer(&der);
13764         }
13765 
13766     #ifdef WOLFSSL_SMALL_STACK
13767         XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13768     #endif
13769     }
13770     else {
13771         ret = AllocDer(&der, (word32)sz, CERT_TYPE, NULL);
13772         if (ret == 0) {
13773             XMEMCPY(der->buffer, buf, sz);
13774         }
13775     }
13776 
13777     /* At this point we want `der` to have the certificate in DER format */
13778     /* ready to be decoded. */
13779     if (der != NULL && der->buffer != NULL) {
13780     #ifdef WOLFSSL_SMALL_STACK
13781         DecodedCert* cert = NULL;
13782     #else
13783         DecodedCert  cert[1];
13784     #endif
13785 
13786     #ifdef WOLFSSL_SMALL_STACK
13787         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
13788                                                        DYNAMIC_TYPE_TMP_BUFFER);
13789         if (cert != NULL)
13790     #endif
13791         {
13792             InitDecodedCert(cert, der->buffer, der->length, NULL);
13793             if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
13794                 x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
13795                                                              DYNAMIC_TYPE_X509);
13796                 if (x509 != NULL) {
13797                     InitX509(x509, 1, NULL);
13798                     if (CopyDecodedToX509(x509, cert) != 0) {
13799                         XFREE(x509, NULL, DYNAMIC_TYPE_X509);
13800                         x509 = NULL;
13801                     }
13802                 }
13803             }
13804 
13805             FreeDecodedCert(cert);
13806         #ifdef WOLFSSL_SMALL_STACK
13807             XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13808         #endif
13809         }
13810 
13811         FreeDer(&der);
13812     }
13813 
13814     return x509;
13815 }
13816 
13817 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
13818 
13819 /* OPENSSL_EXTRA is needed for wolfSSL_X509_d21 function
13820    KEEP_OUR_CERT is to insure ability for returning ssl certificate */
13821 #if defined(OPENSSL_EXTRA) && defined(KEEP_OUR_CERT)
13822 WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl)
13823 {
13824     if (ssl == NULL) {
13825         return NULL;
13826     }
13827 
13828     if (ssl->buffers.weOwnCert) {
13829         if (ssl->ourCert == NULL) {
13830             if (ssl->buffers.certificate == NULL) {
13831                 WOLFSSL_MSG("Certificate buffer not set!");
13832                 return NULL;
13833             }
13834             ssl->ourCert = wolfSSL_X509_d2i(NULL,
13835                                               ssl->buffers.certificate->buffer,
13836                                               ssl->buffers.certificate->length);
13837         }
13838         return ssl->ourCert;
13839     }
13840     else { /* if cert not owned get parent ctx cert or return null */
13841         if (ssl->ctx) {
13842             if (ssl->ctx->ourCert == NULL) {
13843                 if (ssl->ctx->certificate == NULL) {
13844                     WOLFSSL_MSG("Ctx Certificate buffer not set!");
13845                     return NULL;
13846                 }
13847                 ssl->ctx->ourCert = wolfSSL_X509_d2i(NULL,
13848                                                ssl->ctx->certificate->buffer,
13849                                                ssl->ctx->certificate->length);
13850                 ssl->ctx->ownOurCert = 1;
13851             }
13852             return ssl->ctx->ourCert;
13853         }
13854     }
13855 
13856     return NULL;
13857 }
13858 #endif /* OPENSSL_EXTRA && KEEP_OUR_CERT */
13859 #endif /* NO_CERTS */
13860 
13861 
13862 #ifdef OPENSSL_EXTRA
13863 /* return 1 on success 0 on fail */
13864 int wolfSSL_sk_ASN1_OBJECT_push(STACK_OF(WOLFSSL_ASN1_OBJEXT)* sk,
13865                                                       WOLFSSL_ASN1_OBJECT* obj)
13866 {
13867     WOLFSSL_STACK* node;
13868 
13869     if (sk == NULL || obj == NULL) {
13870         return SSL_FAILURE;
13871     }
13872 
13873     /* no previous values in stack */
13874     if (sk->data.obj == NULL) {
13875         sk->data.obj = obj;
13876         sk->num += 1;
13877         return SSL_SUCCESS;
13878     }
13879 
13880     /* stack already has value(s) create a new node and add more */
13881     node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
13882                                                              DYNAMIC_TYPE_ASN1);
13883     if (node == NULL) {
13884         WOLFSSL_MSG("Memory error");
13885         return SSL_FAILURE;
13886     }
13887     XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
13888 
13889     /* push new obj onto head of stack */
13890     node->data.obj = sk->data.obj;
13891     node->next      = sk->next;
13892     sk->next        = node;
13893     sk->data.obj   = obj;
13894     sk->num        += 1;
13895 
13896     return SSL_SUCCESS;
13897 }
13898 
13899 
13900 WOLFSSL_ASN1_OBJECT* wolfSSL_sk_ASN1_OBJCET_pop(
13901                                             STACK_OF(WOLFSSL_ASN1_OBJECT)* sk)
13902 {
13903     WOLFSSL_STACK* node;
13904     WOLFSSL_ASN1_OBJECT*  obj;
13905 
13906     if (sk == NULL) {
13907         return NULL;
13908     }
13909 
13910     node = sk->next;
13911     obj = sk->data.obj;
13912 
13913     if (node != NULL) { /* update sk and remove node from stack */
13914         sk->data.obj = node->data.obj;
13915         sk->next = node->next;
13916         XFREE(node, NULL, DYNAMIC_TYPE_ASN1);
13917     }
13918     else { /* last obj in stack */
13919         sk->data.obj = NULL;
13920     }
13921 
13922     if (sk->num > 0) {
13923         sk->num -= 1;
13924     }
13925 
13926     return obj;
13927 }
13928 
13929 
13930 #ifndef NO_ASN
13931 WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void)
13932 {
13933     WOLFSSL_ASN1_OBJECT* obj;
13934 
13935     obj = (WOLFSSL_ASN1_OBJECT*)XMALLOC(sizeof(WOLFSSL_ASN1_OBJECT), NULL,
13936                                         DYNAMIC_TYPE_ASN1);
13937     if (obj == NULL) {
13938         return NULL;
13939     }
13940 
13941     XMEMSET(obj, 0, sizeof(WOLFSSL_ASN1_OBJECT));
13942     return obj;
13943 }
13944 
13945 
13946 void wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT* obj)
13947 {
13948     if (obj == NULL) {
13949         return;
13950     }
13951 
13952     if (obj->dynamic == 1) {
13953         if (obj->obj != NULL) {
13954             WOLFSSL_MSG("Freeing ASN1 OBJECT data");
13955             XFREE(obj->obj, obj->heap, DYNAMIC_TYPE_ASN1);
13956         }
13957     }
13958 
13959     XFREE(obj, NULL, DYNAMIC_TYPE_ASN1);
13960 }
13961 
13962 
13963 /* free structure for x509 stack */
13964 void wolfSSL_sk_ASN1_OBJECT_free(STACK_OF(WOLFSSL_ASN1_OBJECT)* sk)
13965 {
13966     WOLFSSL_STACK* node;
13967 
13968     if (sk == NULL) {
13969         return;
13970     }
13971 
13972     /* parse through stack freeing each node */
13973     node = sk->next;
13974     while (sk->num > 1) {
13975         WOLFSSL_STACK* tmp = node;
13976         node = node->next;
13977 
13978         wolfSSL_ASN1_OBJECT_free(tmp->data.obj);
13979         XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1);
13980         sk->num -= 1;
13981     }
13982 
13983     /* free head of stack */
13984     if (sk->num == 1) {
13985         wolfSSL_ASN1_OBJECT_free(sk->data.obj);
13986     }
13987     XFREE(sk, NULL, DYNAMIC_TYPE_ASN1);
13988 }
13989 
13990 int wolfSSL_ASN1_STRING_to_UTF8(unsigned char **out, WOLFSSL_ASN1_STRING *in)
13991 {
13992     /*
13993        ASN1_STRING_to_UTF8() converts the string in to UTF8 format,
13994        the converted data is allocated in a buffer in *out.
13995        The length of out is returned or a negative error code.
13996        The buffer *out should be free using OPENSSL_free().
13997        */
13998     (void)out;
13999     (void)in;
14000     WOLFSSL_STUB("ASN1_STRING_to_UTF8");
14001     return -1;
14002 }
14003 #endif /* NO_ASN */
14004 
14005 
14006 int wolfSSL_set_session_id_context(WOLFSSL* ssl, const unsigned char* id,
14007                                unsigned int len)
14008 {
14009     (void)ssl;
14010     (void)id;
14011     (void)len;
14012     return 0;
14013 }
14014 
14015 
14016 void wolfSSL_set_connect_state(WOLFSSL* ssl)
14017 {
14018     word16 haveRSA = 1;
14019     word16 havePSK = 0;
14020 
14021     if (ssl->options.side == WOLFSSL_SERVER_END) {
14022         ssl->options.side = WOLFSSL_CLIENT_END;
14023 
14024         #ifdef NO_RSA
14025             haveRSA = 0;
14026         #endif
14027         #ifndef NO_PSK
14028             havePSK = ssl->options.havePSK;
14029         #endif
14030         InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
14031                    ssl->options.haveDH, ssl->options.haveNTRU,
14032                    ssl->options.haveECDSAsig, ssl->options.haveECC,
14033                    ssl->options.haveStaticECC, ssl->options.side);
14034     }
14035 }
14036 #endif
14037 
14038 int wolfSSL_get_shutdown(const WOLFSSL* ssl)
14039 {
14040     WOLFSSL_ENTER("wolfSSL_get_shutdown");
14041     /* in OpenSSL, SSL_SENT_SHUTDOWN = 1, when closeNotifySent   *
14042      * SSL_RECEIVED_SHUTDOWN = 2, from close notify or fatal err */
14043     return ((ssl->options.closeNotify||ssl->options.connReset) << 1)
14044             | (ssl->options.sentNotify);
14045 }
14046 
14047 
14048 int wolfSSL_session_reused(WOLFSSL* ssl)
14049 {
14050     return ssl->options.resuming;
14051 }
14052 
14053 #ifdef OPENSSL_EXTRA
14054 void wolfSSL_SESSION_free(WOLFSSL_SESSION* session)
14055 {
14056     if (session == NULL)
14057         return;
14058 
14059 #ifdef HAVE_EXT_CACHE
14060     if (session->isAlloced) {
14061     #ifdef HAVE_SESSION_TICKET
14062         if (session->isDynamic)
14063             XFREE(session->ticket, NULL, DYNAMIC_TYPE_SESSION_TICK);
14064     #endif
14065         XFREE(session, NULL, DYNAMIC_TYPE_OPENSSL);
14066     }
14067 #else
14068     /* No need to free since cache is static */
14069     (void)session;
14070 #endif
14071 }
14072 #endif
14073 
14074 const char* wolfSSL_get_version(WOLFSSL* ssl)
14075 {
14076     WOLFSSL_ENTER("SSL_get_version");
14077     if (ssl->version.major == SSLv3_MAJOR) {
14078         switch (ssl->version.minor) {
14079             case SSLv3_MINOR :
14080                 return "SSLv3";
14081             case TLSv1_MINOR :
14082                 return "TLSv1";
14083             case TLSv1_1_MINOR :
14084                 return "TLSv1.1";
14085             case TLSv1_2_MINOR :
14086                 return "TLSv1.2";
14087             case TLSv1_3_MINOR :
14088                 return "TLSv1.3";
14089             default:
14090                 return "unknown";
14091         }
14092     }
14093     else if (ssl->version.major == DTLS_MAJOR) {
14094         switch (ssl->version.minor) {
14095             case DTLS_MINOR :
14096                 return "DTLS";
14097             case DTLSv1_2_MINOR :
14098                 return "DTLSv1.2";
14099             default:
14100                 return "unknown";
14101         }
14102     }
14103     return "unknown";
14104 }
14105 
14106 
14107 /* current library version */
14108 const char* wolfSSL_lib_version(void)
14109 {
14110     return LIBWOLFSSL_VERSION_STRING;
14111 }
14112 
14113 
14114 /* current library version in hex */
14115 word32 wolfSSL_lib_version_hex(void)
14116 {
14117     return LIBWOLFSSL_VERSION_HEX;
14118 }
14119 
14120 
14121 int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl)
14122 {
14123     WOLFSSL_ENTER("SSL_get_current_cipher_suite");
14124     if (ssl)
14125         return (ssl->options.cipherSuite0 << 8) | ssl->options.cipherSuite;
14126     return 0;
14127 }
14128 
14129 WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL* ssl)
14130 {
14131     WOLFSSL_ENTER("SSL_get_current_cipher");
14132     if (ssl)
14133         return &ssl->cipher;
14134     else
14135         return NULL;
14136 }
14137 
14138 
14139 const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher)
14140 {
14141     WOLFSSL_ENTER("SSL_CIPHER_get_name");
14142 
14143     if (cipher == NULL || cipher->ssl == NULL) {
14144         return NULL;
14145     }
14146 
14147     return wolfSSL_get_cipher_name_from_suite(cipher->ssl->options.cipherSuite,
14148         cipher->ssl->options.cipherSuite0);
14149 }
14150 
14151 const char* wolfSSL_SESSION_CIPHER_get_name(WOLFSSL_SESSION* session)
14152 {
14153     if (session == NULL) {
14154         return NULL;
14155     }
14156 
14157 #ifdef SESSION_CERTS
14158     return wolfSSL_get_cipher_name_from_suite(session->cipherSuite,
14159         session->cipherSuite0);
14160 #else
14161     return NULL;
14162 #endif
14163 }
14164 
14165 const char* wolfSSL_get_cipher(WOLFSSL* ssl)
14166 {
14167     WOLFSSL_ENTER("wolfSSL_get_cipher");
14168     return wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl));
14169 }
14170 
14171 /* gets cipher name in the format DHE-RSA-... rather then TLS_DHE... */
14172 const char* wolfSSL_get_cipher_name(WOLFSSL* ssl)
14173 {
14174     /* get access to cipher_name_idx in internal.c */
14175     return wolfSSL_get_cipher_name_internal(ssl);
14176 }
14177 
14178 #ifdef HAVE_ECC
14179 /* Return the name of the curve used for key exchange as a printable string.
14180  *
14181  * ssl  The SSL/TLS object.
14182  * returns NULL if ECDH was not used, otherwise the name as a string.
14183  */
14184 const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
14185 {
14186     if (ssl == NULL)
14187         return NULL;
14188     if (ssl->specs.kea != ecdhe_psk_kea &&
14189             ssl->specs.kea != ecc_diffie_hellman_kea)
14190         return NULL;
14191     if (ssl->ecdhCurveOID == 0)
14192         return NULL;
14193     return wc_ecc_get_name(wc_ecc_get_oid(ssl->ecdhCurveOID, NULL, NULL));
14194 }
14195 #endif
14196 
14197 #ifdef OPENSSL_EXTRA
14198 
14199 char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in,
14200                                  int len)
14201 {
14202     char *ret = in;
14203     const char *keaStr, *authStr, *encStr, *macStr;
14204     size_t strLen;
14205 
14206     if (cipher == NULL || in == NULL)
14207         return NULL;
14208 
14209     switch (cipher->ssl->specs.kea) {
14210         case no_kea:
14211             keaStr = "None";
14212             break;
14213 #ifndef NO_RSA
14214         case rsa_kea:
14215             keaStr = "RSA";
14216             break;
14217 #endif
14218 #ifndef NO_DH
14219         case diffie_hellman_kea:
14220             keaStr = "DHE";
14221             break;
14222 #endif
14223         case fortezza_kea:
14224             keaStr = "FZ";
14225             break;
14226 #ifndef NO_PSK
14227         case psk_kea:
14228             keaStr = "PSK";
14229             break;
14230     #ifndef NO_DH
14231         case dhe_psk_kea:
14232             keaStr = "DHEPSK";
14233             break;
14234     #endif
14235     #ifdef HAVE_ECC
14236         case ecdhe_psk_kea:
14237             keaStr = "ECDHEPSK";
14238             break;
14239     #endif
14240 #endif
14241 #ifdef HAVE_NTRU
14242         case ntru_kea:
14243             keaStr = "NTRU";
14244             break;
14245 #endif
14246 #ifdef HAVE_ECC
14247         case ecc_diffie_hellman_kea:
14248             keaStr = "ECDHE";
14249             break;
14250         case ecc_static_diffie_hellman_kea:
14251             keaStr = "ECDH";
14252             break;
14253 #endif
14254         default:
14255             keaStr = "unknown";
14256             break;
14257     }
14258 
14259     switch (cipher->ssl->specs.sig_algo) {
14260         case anonymous_sa_algo:
14261             authStr = "None";
14262             break;
14263 #ifndef NO_RSA
14264         case rsa_sa_algo:
14265             authStr = "RSA";
14266             break;
14267 #endif
14268 #ifndef NO_DSA
14269         case dsa_sa_algo:
14270             authStr = "DSA";
14271             break;
14272 #endif
14273 #ifdef HAVE_ECC
14274         case ecc_dsa_sa_algo:
14275             authStr = "ECDSA";
14276             break;
14277 #endif
14278         default:
14279             authStr = "unknown";
14280             break;
14281     }
14282 
14283     switch (cipher->ssl->specs.bulk_cipher_algorithm) {
14284         case wolfssl_cipher_null:
14285             encStr = "None";
14286             break;
14287 #ifndef NO_RC4
14288         case wolfssl_rc4:
14289             encStr = "RC4(128)";
14290             break;
14291 #endif
14292 #ifndef NO_DES3
14293         case wolfssl_triple_des:
14294             encStr = "3DES(168)";
14295             break;
14296 #endif
14297 #ifdef HAVE_IDEA
14298         case wolfssl_idea:
14299             encStr = "IDEA(128)";
14300             break;
14301 #endif
14302 #ifndef NO_AES
14303         case wolfssl_aes:
14304             if (cipher->ssl->specs.key_size == 128)
14305                 encStr = "AES(128)";
14306             else if (cipher->ssl->specs.key_size == 256)
14307                 encStr = "AES(256)";
14308             else
14309                 encStr = "AES(?)";
14310             break;
14311     #ifdef HAVE_AESGCM
14312         case wolfssl_aes_gcm:
14313             if (cipher->ssl->specs.key_size == 128)
14314                 encStr = "AESGCM(128)";
14315             else if (cipher->ssl->specs.key_size == 256)
14316                 encStr = "AESGCM(256)";
14317             else
14318                 encStr = "AESGCM(?)";
14319             break;
14320     #endif
14321     #ifdef HAVE_AESCCM
14322         case wolfssl_aes_ccm:
14323             if (cipher->ssl->specs.key_size == 128)
14324                 encStr = "AESCCM(128)";
14325             else if (cipher->ssl->specs.key_size == 256)
14326                 encStr = "AESCCM(256)";
14327             else
14328                 encStr = "AESCCM(?)";
14329             break;
14330     #endif
14331 #endif
14332 #ifdef HAVE_CHACHA
14333         case wolfssl_chacha:
14334             encStr = "CHACHA20/POLY1305(256)";
14335             break;
14336 #endif
14337 #ifdef HAVE_CAMELLIA
14338         case wolfssl_camellia:
14339             if (cipher->ssl->specs.key_size == 128)
14340                 encStr = "Camellia(128)";
14341             else if (cipher->ssl->specs.key_size == 256)
14342                 encStr = "Camellia(256)";
14343             else
14344                 encStr = "Camellia(?)";
14345             break;
14346 #endif
14347 #if defined(HAVE_HC128) && !defined(NO_HC128)
14348         case wolfssl_hc128:
14349             encStr = "HC128(128)";
14350             break;
14351 #endif
14352 #if defined(HAVE_RABBIT) && !defined(NO_RABBIT)
14353         case wolfssl_rabbit:
14354             encStr = "RABBIT(128)";
14355             break;
14356 #endif
14357         default:
14358             encStr = "unknown";
14359             break;
14360     }
14361 
14362     switch (cipher->ssl->specs.mac_algorithm) {
14363         case no_mac:
14364             macStr = "None";
14365             break;
14366 #ifndef NO_MD5
14367         case md5_mac:
14368             macStr = "MD5";
14369             break;
14370 #endif
14371 #ifndef NO_SHA
14372         case sha_mac:
14373             macStr = "SHA1";
14374             break;
14375 #endif
14376 #ifdef HAVE_SHA224
14377         case sha224_mac:
14378             macStr = "SHA224";
14379             break;
14380 #endif
14381 #ifndef NO_SHA256
14382         case sha256_mac:
14383             macStr = "SHA256";
14384             break;
14385 #endif
14386 #ifdef HAVE_SHA384
14387         case sha384_mac:
14388             macStr = "SHA384";
14389             break;
14390 #endif
14391 #ifdef HAVE_SHA512
14392         case sha512_mac:
14393             macStr = "SHA512";
14394             break;
14395 #endif
14396 #ifdef HAVE_BLAKE2
14397         case blake2b_mac:
14398             macStr = "BLAKE2b";
14399             break;
14400 #endif
14401         default:
14402             macStr = "unknown";
14403             break;
14404     }
14405 
14406     /* Build up the string by copying onto the end. */
14407     XSTRNCPY(in, wolfSSL_CIPHER_get_name(cipher), len);
14408     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
14409 
14410     XSTRNCPY(in, " ", len);
14411     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
14412     XSTRNCPY(in, wolfSSL_get_version(cipher->ssl), len);
14413     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
14414 
14415     XSTRNCPY(in, " Kx=", len);
14416     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
14417     XSTRNCPY(in, keaStr, len);
14418     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
14419 
14420     XSTRNCPY(in, " Au=", len);
14421     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
14422     XSTRNCPY(in, authStr, len);
14423     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
14424 
14425     XSTRNCPY(in, " Enc=", len);
14426     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
14427     XSTRNCPY(in, encStr, len);
14428     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
14429 
14430     XSTRNCPY(in, " Mac=", len);
14431     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
14432     XSTRNCPY(in, macStr, len);
14433     in[len-1] = '\0';
14434 
14435     return ret;
14436 }
14437 
14438 
14439 #ifndef NO_SESSION_CACHE
14440 
14441 WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl)
14442 {
14443     if (ssl == NULL) {
14444         return NULL;
14445     }
14446 
14447     /* sessions are stored statically, no need for reference count */
14448     return wolfSSL_get_session(ssl);
14449 }
14450 
14451 #endif /* NO_SESSION_CACHE */
14452 
14453 #ifndef NO_CERTS
14454 void wolfSSL_X509_free(WOLFSSL_X509* x509)
14455 {
14456     WOLFSSL_ENTER("wolfSSL_X509_free");
14457     ExternalFreeX509(x509);
14458 }
14459 #endif /* NO_CERTS */
14460 
14461 
14462 int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, char** path,
14463                    int* ssl)
14464 {
14465     (void)url;
14466     (void)host;
14467     (void)port;
14468     (void)path;
14469     (void)ssl;
14470     return 0;
14471 }
14472 
14473 
14474 WOLFSSL_METHOD* wolfSSLv2_client_method(void)
14475 {
14476     return 0;
14477 }
14478 
14479 
14480 WOLFSSL_METHOD* wolfSSLv2_server_method(void)
14481 {
14482     return 0;
14483 }
14484 
14485 
14486 #ifndef NO_MD4
14487 
14488 void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX* md4)
14489 {
14490     /* make sure we have a big enough buffer */
14491     typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1];
14492     (void) sizeof(ok);
14493 
14494     WOLFSSL_ENTER("MD4_Init");
14495     wc_InitMd4((Md4*)md4);
14496 }
14497 
14498 
14499 void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX* md4, const void* data,
14500                        unsigned long len)
14501 {
14502     WOLFSSL_ENTER("MD4_Update");
14503     wc_Md4Update((Md4*)md4, (const byte*)data, (word32)len);
14504 }
14505 
14506 
14507 void wolfSSL_MD4_Final(unsigned char* digest, WOLFSSL_MD4_CTX* md4)
14508 {
14509     WOLFSSL_ENTER("MD4_Final");
14510     wc_Md4Final((Md4*)md4, digest);
14511 }
14512 
14513 #endif /* NO_MD4 */
14514 
14515 
14516 WOLFSSL_BIO* wolfSSL_BIO_pop(WOLFSSL_BIO* top)
14517 {
14518     (void)top;
14519     return 0;
14520 }
14521 
14522 
14523 int wolfSSL_BIO_pending(WOLFSSL_BIO* bio)
14524 {
14525     if (bio && bio->type == BIO_MEMORY)
14526         return bio->memLen;
14527     return 0;
14528 }
14529 
14530 
14531 
14532 WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_mem(void)
14533 {
14534     static WOLFSSL_BIO_METHOD meth;
14535 
14536     WOLFSSL_ENTER("BIO_s_mem");
14537     meth.type = BIO_MEMORY;
14538 
14539     return &meth;
14540 }
14541 
14542 
14543 WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_base64(void)
14544 {
14545     return 0;
14546 }
14547 
14548 
14549 void wolfSSL_BIO_set_flags(WOLFSSL_BIO* bio, int flags)
14550 {
14551     (void)bio;
14552     (void)flags;
14553 }
14554 
14555 
14556 
14557 void wolfSSL_RAND_screen(void)
14558 {
14559 
14560 }
14561 
14562 
14563 const char* wolfSSL_RAND_file_name(char* fname, unsigned long len)
14564 {
14565     (void)fname;
14566     (void)len;
14567     return 0;
14568 }
14569 
14570 
14571 int wolfSSL_RAND_write_file(const char* fname)
14572 {
14573     (void)fname;
14574     return 0;
14575 }
14576 
14577 
14578 int wolfSSL_RAND_load_file(const char* fname, long len)
14579 {
14580     (void)fname;
14581     /* wolfCrypt provides enough entropy internally or will report error */
14582     if (len == -1)
14583         return 1024;
14584     else
14585         return (int)len;
14586 }
14587 
14588 
14589 int wolfSSL_RAND_egd(const char* path)
14590 {
14591     (void)path;
14592     return 0;
14593 }
14594 
14595 
14596 
14597 WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void)
14598 {
14599     return 0;
14600 }
14601 
14602 
14603 WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void)
14604 {
14605     return 0;
14606 }
14607 
14608 int wolfSSL_COMP_add_compression_method(int method, void* data)
14609 {
14610     (void)method;
14611     (void)data;
14612     return 0;
14613 }
14614 
14615 
14616 void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f)(
14617                                                           const char*, int))
14618 {
14619     (void)f;
14620 }
14621 
14622 
14623 void wolfSSL_set_dynlock_lock_callback(
14624              void (*f)(int, WOLFSSL_dynlock_value*, const char*, int))
14625 {
14626     (void)f;
14627 }
14628 
14629 
14630 void wolfSSL_set_dynlock_destroy_callback(
14631                   void (*f)(WOLFSSL_dynlock_value*, const char*, int))
14632 {
14633     (void)f;
14634 }
14635 
14636 
14637 
14638 const char* wolfSSL_X509_verify_cert_error_string(long err)
14639 {
14640     return wolfSSL_ERR_reason_error_string(err);
14641 }
14642 
14643 
14644 
14645 int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup, const char* dir,
14646                                long len)
14647 {
14648     (void)lookup;
14649     (void)dir;
14650     (void)len;
14651     return 0;
14652 }
14653 
14654 
14655 int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
14656                                  const char* file, long type)
14657 {
14658 #ifndef NO_FILESYSTEM
14659     int           ret = SSL_FAILURE;
14660     XFILE         fp;
14661     long          sz;
14662     byte*         pem = NULL;
14663     WOLFSSL_X509* x509;
14664 
14665     if (type != X509_FILETYPE_PEM)
14666         return BAD_FUNC_ARG;
14667 
14668     fp = XFOPEN(file, "r");
14669     if (fp == NULL)
14670         return BAD_FUNC_ARG;
14671 
14672     XFSEEK(fp, 0, XSEEK_END);
14673     sz = XFTELL(fp);
14674     XREWIND(fp);
14675 
14676     if (sz <= 0)
14677         goto end;
14678 
14679     pem = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_TMP_BUFFER);
14680     if (pem == NULL) {
14681         ret = MEMORY_ERROR;
14682         goto end;
14683     }
14684 
14685     /* Read in file which may be a CRL or certificate. */
14686     if (XFREAD(pem, (size_t)sz, 1, fp) != 1)
14687         goto end;
14688 
14689     if (XSTRNSTR((char*)pem, BEGIN_X509_CRL, (unsigned int)sz) != NULL) {
14690 #ifdef HAVE_CRL
14691         ret = wolfSSL_CertManagerLoadCRLBuffer(lookup->store->cm, pem, sz,
14692                 SSL_FILETYPE_PEM);
14693 #endif
14694     }
14695     else {
14696         x509 = wolfSSL_X509_load_certificate_buffer(pem, (int)sz,
14697                                                     SSL_FILETYPE_PEM);
14698         if (x509 == NULL)
14699              goto end;
14700         ret = wolfSSL_X509_STORE_add_cert(lookup->store, x509);
14701     }
14702 
14703 end:
14704     if (pem != NULL)
14705         XFREE(pem, 0, DYNAMIC_TYPE_TMP_BUFFER);
14706     XFCLOSE(fp);
14707     return ret;
14708 #else
14709     (void)lookup;
14710     (void)file;
14711     (void)type;
14712     return SSL_FAILURE;
14713 #endif
14714 }
14715 
14716 
14717 WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void)
14718 {
14719     /* Method implementation in functions. */
14720     static WOLFSSL_X509_LOOKUP_METHOD meth = { 1 };
14721     return &meth;
14722 }
14723 
14724 WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void)
14725 {
14726     /* Method implementation in functions. */
14727     static WOLFSSL_X509_LOOKUP_METHOD meth = { 0 };
14728     return &meth;
14729 }
14730 
14731 
14732 WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
14733                                                WOLFSSL_X509_LOOKUP_METHOD* m)
14734 {
14735     /* Method is a dummy value and is not needed. */
14736     (void)m;
14737     /* Make sure the lookup has a back reference to the store. */
14738     store->lookup.store = store;
14739     return &store->lookup;
14740 }
14741 
14742 
14743 #ifndef NO_CERTS
14744 WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
14745 {
14746     WOLFSSL_X509* localX509 = NULL;
14747     unsigned char* mem  = NULL;
14748     int    ret;
14749     word32 size;
14750 
14751     WOLFSSL_ENTER("wolfSSL_d2i_X509_bio");
14752 
14753     if (bio == NULL) {
14754         WOLFSSL_MSG("Bad Function Argument bio is NULL");
14755         return NULL;
14756     }
14757 
14758     ret = wolfSSL_BIO_get_mem_data(bio, &mem);
14759     if (mem == NULL || ret <= 0) {
14760         WOLFSSL_MSG("Failed to get data from bio struct");
14761         return NULL;
14762     }
14763     size = ret;
14764 
14765     localX509 = wolfSSL_X509_d2i(NULL, mem, size);
14766     if (localX509 == NULL) {
14767         return NULL;
14768     }
14769 
14770     if (x509 != NULL) {
14771         *x509 = localX509;
14772     }
14773 
14774     return localX509;
14775 }
14776 
14777 
14778 #if !defined(NO_ASN) && !defined(NO_PWDBASED)
14779 WC_PKCS12* wolfSSL_d2i_PKCS12_bio(WOLFSSL_BIO* bio, WC_PKCS12** pkcs12)
14780 {
14781     WC_PKCS12* localPkcs12    = NULL;
14782     unsigned char* mem  = NULL;
14783     int ret;
14784     word32 size;
14785 
14786     WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_bio");
14787 
14788     if (bio == NULL) {
14789         WOLFSSL_MSG("Bad Function Argument bio is NULL");
14790         return NULL;
14791     }
14792 
14793     localPkcs12 = wc_PKCS12_new();
14794     if (localPkcs12 == NULL) {
14795         WOLFSSL_MSG("Memory error");
14796         return NULL;
14797     }
14798 
14799     if (pkcs12 != NULL) {
14800         *pkcs12 = localPkcs12;
14801     }
14802 
14803     ret = wolfSSL_BIO_get_mem_data(bio, &mem);
14804     if (mem == NULL || ret <= 0) {
14805         WOLFSSL_MSG("Failed to get data from bio struct");
14806         wc_PKCS12_free(localPkcs12);
14807         if (pkcs12 != NULL) {
14808             *pkcs12 = NULL;
14809         }
14810         return NULL;
14811     }
14812     size = ret;
14813 
14814     ret = wc_d2i_PKCS12(mem, size, localPkcs12);
14815     if (ret <= 0) {
14816         WOLFSSL_MSG("Failed to get PKCS12 sequence");
14817         wc_PKCS12_free(localPkcs12);
14818         if (pkcs12 != NULL) {
14819             *pkcs12 = NULL;
14820         }
14821         return NULL;
14822     }
14823 
14824     return localPkcs12;
14825 }
14826 
14827 
14828 /* return 1 on success, 0 on failure */
14829 int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
14830       WOLFSSL_EVP_PKEY** pkey, WOLFSSL_X509** cert, STACK_OF(WOLFSSL_X509)** ca)
14831 {
14832     DecodedCert DeCert;
14833     void* heap = NULL;
14834     int ret;
14835     byte* certData = NULL;
14836     word32 certDataSz;
14837     byte* pk = NULL;
14838     word32 pkSz;
14839     WC_DerCertList* certList = NULL;
14840 
14841     WOLFSSL_ENTER("wolfSSL_PKCS12_parse");
14842 
14843     if (pkcs12 == NULL || psw == NULL || pkey == NULL || cert == NULL) {
14844         WOLFSSL_MSG("Bad argument value");
14845         return 0;
14846     }
14847 
14848     heap  = wc_PKCS12_GetHeap(pkcs12);
14849     *pkey = NULL;
14850     *cert = NULL;
14851 
14852     if (ca == NULL) {
14853         ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
14854             NULL);
14855     }
14856     else {
14857         *ca = NULL;
14858         ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
14859             &certList);
14860     }
14861     if (ret < 0) {
14862         WOLFSSL_LEAVE("wolfSSL_PKCS12_parse", ret);
14863         return 0;
14864     }
14865 
14866     /* Decode cert and place in X509 stack struct */
14867     if (certList != NULL) {
14868         WC_DerCertList* current = certList;
14869 
14870         *ca = (STACK_OF(WOLFSSL_X509)*)XMALLOC(sizeof(STACK_OF(WOLFSSL_X509)),
14871                                                heap, DYNAMIC_TYPE_X509);
14872         if (*ca == NULL) {
14873             if (pk != NULL) {
14874                 XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
14875             }
14876             if (certData != NULL) {
14877                 XFREE(*cert, heap, DYNAMIC_TYPE_PKCS); *cert = NULL;
14878             }
14879             /* Free up WC_DerCertList and move on */
14880             while (current != NULL) {
14881                 WC_DerCertList* next = current->next;
14882 
14883                 XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
14884                 XFREE(current, heap, DYNAMIC_TYPE_PKCS);
14885                 current = next;
14886             }
14887             return 0;
14888         }
14889         XMEMSET(*ca, 0, sizeof(STACK_OF(WOLFSSL_X509)));
14890 
14891         /* add list of DER certs as X509's to stack */
14892         while (current != NULL) {
14893             WC_DerCertList*  toFree = current;
14894             WOLFSSL_X509* x509;
14895 
14896             x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
14897                                                              DYNAMIC_TYPE_X509);
14898             InitX509(x509, 1, heap);
14899             InitDecodedCert(&DeCert, current->buffer, current->bufferSz, heap);
14900             if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
14901                 WOLFSSL_MSG("Issue with parsing certificate");
14902                 FreeDecodedCert(&DeCert);
14903                 wolfSSL_X509_free(x509);
14904             }
14905             else {
14906                 if ((ret = CopyDecodedToX509(x509, &DeCert)) != 0) {
14907                     WOLFSSL_MSG("Failed to copy decoded cert");
14908                     FreeDecodedCert(&DeCert);
14909                     wolfSSL_X509_free(x509);
14910                     wolfSSL_sk_X509_free(*ca); *ca = NULL;
14911                     if (pk != NULL) {
14912                         XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
14913                     }
14914                     if (certData != NULL) {
14915                         XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
14916                     }
14917                     /* Free up WC_DerCertList */
14918                     while (current != NULL) {
14919                         WC_DerCertList* next = current->next;
14920 
14921                         XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
14922                         XFREE(current, heap, DYNAMIC_TYPE_PKCS);
14923                         current = next;
14924                     }
14925                     return 0;
14926                 }
14927                 FreeDecodedCert(&DeCert);
14928 
14929                 if (wolfSSL_sk_X509_push(*ca, x509) != 1) {
14930                     WOLFSSL_MSG("Failed to push x509 onto stack");
14931                     wolfSSL_X509_free(x509);
14932                     wolfSSL_sk_X509_free(*ca); *ca = NULL;
14933                     if (pk != NULL) {
14934                         XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
14935                     }
14936                     if (certData != NULL) {
14937                         XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
14938                     }
14939 
14940                     /* Free up WC_DerCertList */
14941                     while (current != NULL) {
14942                         WC_DerCertList* next = current->next;
14943 
14944                         XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
14945                         XFREE(current, heap, DYNAMIC_TYPE_PKCS);
14946                         current = next;
14947                     }
14948                     return 0;
14949                 }
14950             }
14951             current = current->next;
14952             XFREE(toFree->buffer, heap, DYNAMIC_TYPE_PKCS);
14953             XFREE(toFree, heap, DYNAMIC_TYPE_PKCS);
14954         }
14955     }
14956 
14957 
14958     /* Decode cert and place in X509 struct */
14959     if (certData != NULL) {
14960         *cert = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
14961                                                              DYNAMIC_TYPE_X509);
14962         if (*cert == NULL) {
14963             if (pk != NULL) {
14964                 XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
14965             }
14966             if (ca != NULL) {
14967                 wolfSSL_sk_X509_free(*ca); *ca = NULL;
14968             }
14969             XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
14970             return 0;
14971         }
14972         InitX509(*cert, 1, heap);
14973         InitDecodedCert(&DeCert, certData, certDataSz, heap);
14974         if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
14975             WOLFSSL_MSG("Issue with parsing certificate");
14976         }
14977         if ((ret = CopyDecodedToX509(*cert, &DeCert)) != 0) {
14978             WOLFSSL_MSG("Failed to copy decoded cert");
14979             FreeDecodedCert(&DeCert);
14980             if (pk != NULL) {
14981                 XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
14982             }
14983             if (ca != NULL) {
14984                 wolfSSL_sk_X509_free(*ca); *ca = NULL;
14985             }
14986             wolfSSL_X509_free(*cert); *cert = NULL;
14987             return 0;
14988         }
14989         FreeDecodedCert(&DeCert);
14990         XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
14991     }
14992 
14993 
14994     /* get key type */
14995     ret = BAD_STATE_E;
14996     if (pk != NULL) { /* decode key if present */
14997         /* using dynamic type public key because of wolfSSL_EVP_PKEY_free */
14998         *pkey = (WOLFSSL_EVP_PKEY*)XMALLOC(sizeof(WOLFSSL_EVP_PKEY),
14999                                                heap, DYNAMIC_TYPE_PUBLIC_KEY);
15000         if (*pkey == NULL) {
15001             wolfSSL_X509_free(*cert); *cert = NULL;
15002             if (ca != NULL) {
15003                 wolfSSL_sk_X509_free(*ca); *ca = NULL;
15004             }
15005             XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
15006             return 0;
15007         }
15008         #ifndef NO_RSA
15009         {
15010             word32 keyIdx = 0;
15011             RsaKey key;
15012 
15013             if (wc_InitRsaKey(&key, heap) != 0) {
15014                 ret = BAD_STATE_E;
15015             }
15016             else {
15017                 if ((ret = wc_RsaPrivateKeyDecode(pk, &keyIdx, &key, pkSz))
15018                                                                          == 0) {
15019                     (*pkey)->type = RSAk;
15020                     WOLFSSL_MSG("Found PKCS12 RSA key");
15021                 }
15022                 wc_FreeRsaKey(&key);
15023             }
15024         }
15025         #endif /* NO_RSA */
15026 
15027         #ifdef HAVE_ECC
15028         {
15029             word32  keyIdx = 0;
15030             ecc_key key;
15031 
15032             if (ret != 0) { /* if is in fail state check if ECC key */
15033                 if (wc_ecc_init(&key) != 0) {
15034                     wolfSSL_X509_free(*cert); *cert = NULL;
15035                     if (ca != NULL) {
15036                         wolfSSL_sk_X509_free(*ca); *ca = NULL;
15037                     }
15038                     XFREE(*pkey, heap, DYNAMIC_TYPE_PUBLIC_KEY); *pkey = NULL;
15039                     XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
15040                     return 0;
15041                 }
15042 
15043                 if ((ret = wc_EccPrivateKeyDecode(pk, &keyIdx, &key, pkSz))
15044                                                                          != 0) {
15045                     wolfSSL_X509_free(*cert); *cert = NULL;
15046                     if (ca != NULL) {
15047                         wolfSSL_sk_X509_free(*ca); *ca = NULL;
15048                     }
15049                     XFREE(*pkey, heap, DYNAMIC_TYPE_PUBLIC_KEY); *pkey = NULL;
15050                     XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
15051                     WOLFSSL_MSG("Bad PKCS12 key format");
15052                     return 0;
15053                 }
15054                 (*pkey)->type = ECDSAk;
15055                 (*pkey)->pkey_curve = key.dp->oidSum;
15056                 wc_ecc_free(&key);
15057                 WOLFSSL_MSG("Found PKCS12 ECC key");
15058             }
15059         }
15060         #else
15061         if (ret != 0) { /* if is in fail state and no ECC then fail */
15062             wolfSSL_X509_free(*cert); *cert = NULL;
15063             if (ca != NULL) {
15064                 wolfSSL_sk_X509_free(*ca); *ca = NULL;
15065             }
15066             XFREE(*pkey, heap, DYNAMIC_TYPE_PUBLIC_KEY); *pkey = NULL;
15067             XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
15068             WOLFSSL_MSG("Bad PKCS12 key format");
15069             return 0;
15070         }
15071         #endif /* HAVE_ECC */
15072 
15073         (*pkey)->save_type = 0;
15074         (*pkey)->pkey_sz   = pkSz;
15075         (*pkey)->pkey.ptr  = (char*)pk;
15076     }
15077 
15078     (void)ret;
15079     (void)ca;
15080 
15081     return 1;
15082 }
15083 #endif /* !defined(NO_ASN) && !defined(NO_PWDBASED) */
15084 
15085 
15086 /* no-op function. Was initially used for adding encryption algorithms available
15087  * for PKCS12 */
15088 void wolfSSL_PKCS12_PBE_add(void)
15089 {
15090     WOLFSSL_ENTER("wolfSSL_PKCS12_PBE_add");
15091 }
15092 
15093 
15094 
15095 WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx)
15096 {
15097     if (ctx == NULL) {
15098         return NULL;
15099     }
15100 
15101     return ctx->chain;
15102 }
15103 
15104 
15105 int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509)
15106 {
15107     int result = SSL_FATAL_ERROR;
15108 
15109     WOLFSSL_ENTER("wolfSSL_X509_STORE_add_cert");
15110     if (store != NULL && store->cm != NULL && x509 != NULL
15111                                                 && x509->derCert != NULL) {
15112         DerBuffer* derCert = NULL;
15113 
15114         result = AllocDer(&derCert, x509->derCert->length,
15115             x509->derCert->type, NULL);
15116         if (result == 0) {
15117             /* AddCA() frees the buffer. */
15118             XMEMCPY(derCert->buffer,
15119                             x509->derCert->buffer, x509->derCert->length);
15120             result = AddCA(store->cm, &derCert, WOLFSSL_USER_CA, 1);
15121         }
15122     }
15123 
15124     WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_cert", result);
15125 
15126     if (result != SSL_SUCCESS) {
15127         result = SSL_FATAL_ERROR;
15128     }
15129 
15130     return result;
15131 }
15132 
15133 
15134 WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void)
15135 {
15136     WOLFSSL_X509_STORE* store = NULL;
15137 
15138     store = (WOLFSSL_X509_STORE*)XMALLOC(sizeof(WOLFSSL_X509_STORE), NULL,
15139                                          DYNAMIC_TYPE_X509_STORE);
15140     if (store != NULL) {
15141         store->cm = wolfSSL_CertManagerNew();
15142         if (store->cm == NULL) {
15143             XFREE(store, NULL, DYNAMIC_TYPE_X509_STORE);
15144             store = NULL;
15145         }
15146         else
15147             store->isDynamic = 1;
15148     }
15149 
15150     return store;
15151 }
15152 
15153 
15154 void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store)
15155 {
15156     if (store != NULL && store->isDynamic) {
15157         if (store->cm != NULL)
15158         wolfSSL_CertManagerFree(store->cm);
15159         XFREE(store, NULL, DYNAMIC_TYPE_X509_STORE);
15160     }
15161 }
15162 
15163 
15164 int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, unsigned long flag)
15165 {
15166     int ret = SSL_SUCCESS;
15167 
15168     WOLFSSL_ENTER("wolfSSL_X509_STORE_set_flags");
15169 
15170     if ((flag & WOLFSSL_CRL_CHECKALL) || (flag & WOLFSSL_CRL_CHECK)) {
15171         ret = wolfSSL_CertManagerEnableCRL(store->cm, (int)flag);
15172     }
15173 
15174     (void)store;
15175     (void)flag;
15176 
15177     return ret;
15178 }
15179 
15180 
15181 int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE* store)
15182 {
15183     (void)store;
15184     return SSL_SUCCESS;
15185 }
15186 
15187 
15188 int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX* ctx, int idx,
15189                             WOLFSSL_X509_NAME* name, WOLFSSL_X509_OBJECT* obj)
15190 {
15191     (void)ctx;
15192     (void)idx;
15193     (void)name;
15194     (void)obj;
15195     return 0;
15196 }
15197 
15198 
15199 WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new(void)
15200 {
15201     WOLFSSL_X509_STORE_CTX* ctx = (WOLFSSL_X509_STORE_CTX*)XMALLOC(
15202                                     sizeof(WOLFSSL_X509_STORE_CTX), NULL,
15203                                     DYNAMIC_TYPE_X509_CTX);
15204     if (ctx != NULL)
15205         wolfSSL_X509_STORE_CTX_init(ctx, NULL, NULL, NULL);
15206 
15207     return ctx;
15208 }
15209 
15210 
15211 int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
15212      WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509, STACK_OF(WOLFSSL_X509)* sk)
15213 {
15214     (void)sk;
15215     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_init");
15216     if (ctx != NULL) {
15217         ctx->store = store;
15218         ctx->current_cert = x509;
15219         ctx->chain  = sk;
15220         ctx->domain = NULL;
15221 #ifdef HAVE_EX_DATA
15222         ctx->ex_data = NULL;
15223 #endif
15224         ctx->userCtx = NULL;
15225         ctx->error = 0;
15226         ctx->error_depth = 0;
15227         ctx->discardSessionCerts = 0;
15228         return SSL_SUCCESS;
15229     }
15230     return SSL_FATAL_ERROR;
15231 }
15232 
15233 
15234 void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx)
15235 {
15236     if (ctx != NULL) {
15237         if (ctx->store != NULL)
15238             wolfSSL_X509_STORE_free(ctx->store);
15239         if (ctx->current_cert != NULL)
15240             wolfSSL_FreeX509(ctx->current_cert);
15241         if (ctx->chain != NULL)
15242             wolfSSL_sk_X509_free(ctx->chain);
15243         XFREE(ctx, NULL, DYNAMIC_TYPE_X509_CTX);
15244     }
15245 }
15246 
15247 
15248 void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX* ctx)
15249 {
15250     (void)ctx;
15251 }
15252 
15253 
15254 int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
15255 {
15256     if (ctx != NULL && ctx->store != NULL && ctx->store->cm != NULL
15257          && ctx->current_cert != NULL && ctx->current_cert->derCert != NULL) {
15258         return wolfSSL_CertManagerVerifyBuffer(ctx->store->cm,
15259                     ctx->current_cert->derCert->buffer,
15260                     ctx->current_cert->derCert->length,
15261                     SSL_FILETYPE_ASN1);
15262     }
15263     return SSL_FATAL_ERROR;
15264 }
15265 #endif /* NO_CERTS */
15266 
15267 
15268 WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl)
15269 {
15270     (void)crl;
15271     return 0;
15272 }
15273 
15274 
15275 WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
15276 {
15277     (void)crl;
15278     return 0;
15279 }
15280 
15281 
15282 
15283 WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
15284 {
15285     WOLFSSL_EVP_PKEY* key = NULL;
15286     if (x509 != NULL) {
15287         key = (WOLFSSL_EVP_PKEY*)XMALLOC(
15288                     sizeof(WOLFSSL_EVP_PKEY), x509->heap,
15289                                                        DYNAMIC_TYPE_PUBLIC_KEY);
15290         if (key != NULL) {
15291             key->type = x509->pubKeyOID;
15292             key->save_type = 0;
15293             key->pkey.ptr = (char*)XMALLOC(
15294                         x509->pubKey.length, x509->heap,
15295                                                        DYNAMIC_TYPE_PUBLIC_KEY);
15296             if (key->pkey.ptr == NULL) {
15297                 XFREE(key, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
15298                 return NULL;
15299             }
15300             XMEMCPY(key->pkey.ptr,
15301                                   x509->pubKey.buffer, x509->pubKey.length);
15302             key->pkey_sz = x509->pubKey.length;
15303             #ifdef HAVE_ECC
15304                 key->pkey_curve = (int)x509->pkCurveOID;
15305             #endif /* HAVE_ECC */
15306         }
15307     }
15308     return key;
15309 }
15310 
15311 
15312 int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
15313 {
15314     (void)crl;
15315     (void)key;
15316     return 0;
15317 }
15318 
15319 
15320 void wolfSSL_X509_STORE_CTX_set_error(WOLFSSL_X509_STORE_CTX* ctx, int err)
15321 {
15322     (void)ctx;
15323     (void)err;
15324 }
15325 
15326 
15327 void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj)
15328 {
15329     (void)obj;
15330 }
15331 
15332 
15333 WOLFSSL_EVP_PKEY* wolfSSL_PKEY_new()
15334 {
15335     WOLFSSL_EVP_PKEY* pkey;
15336 
15337     pkey = (WOLFSSL_EVP_PKEY*)XMALLOC(sizeof(WOLFSSL_EVP_PKEY), NULL,
15338             DYNAMIC_TYPE_PUBLIC_KEY);
15339     if (pkey != NULL) {
15340         XMEMSET(pkey, 0, sizeof(WOLFSSL_EVP_PKEY));
15341     }
15342 
15343     return pkey;
15344 }
15345 
15346 
15347 void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key)
15348 {
15349     if (key != NULL) {
15350         if (key->pkey.ptr != NULL)
15351             XFREE(key->pkey.ptr, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
15352         XFREE(key, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
15353     }
15354 }
15355 
15356 
15357 int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME* asnTime)
15358 {
15359     (void)asnTime;
15360     return 0;
15361 }
15362 
15363 
15364 int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED* revoked)
15365 {
15366     (void)revoked;
15367     return 0;
15368 }
15369 
15370 
15371 
15372 WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL* crl)
15373 {
15374     (void)crl;
15375     return 0;
15376 }
15377 
15378 
15379 WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(
15380                                     WOLFSSL_X509_REVOKED* revoked, int value)
15381 {
15382     (void)revoked;
15383     (void)value;
15384     return 0;
15385 }
15386 
15387 
15388 
15389 WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
15390 {
15391     WOLFSSL_ASN1_INTEGER* a;
15392     int i = 0;
15393 
15394     WOLFSSL_ENTER("wolfSSL_X509_get_serialNumber");
15395 
15396     a = (WOLFSSL_ASN1_INTEGER*)XMALLOC(sizeof(WOLFSSL_ASN1_INTEGER), NULL,
15397                                        DYNAMIC_TYPE_OPENSSL);
15398     if (a == NULL)
15399         return NULL;
15400 
15401     /* Make sure there is space for the data, ASN.1 type and length. */
15402     if (x509->serialSz > (int)(sizeof(WOLFSSL_ASN1_INTEGER) - 2)) {
15403         XFREE(a, NULL, DYNAMIC_TYPE_OPENSSL);
15404         return NULL;
15405     }
15406 
15407     a->data[i++] = ASN_INTEGER;
15408     a->data[i++] = (unsigned char)x509->serialSz;
15409     XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
15410 
15411     return a;
15412 }
15413 
15414 
15415 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
15416 int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime)
15417 {
15418     char buf[MAX_TIME_STRING_SZ];
15419 
15420     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_print");
15421 
15422     if (bio == NULL || asnTime == NULL)
15423         return BAD_FUNC_ARG;
15424 
15425     wolfSSL_ASN1_TIME_to_string((WOLFSSL_ASN1_TIME*)asnTime, buf, sizeof(buf));
15426     wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf));
15427 
15428     return 0;
15429 }
15430 #endif
15431 
15432 
15433 #if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
15434 char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* t, char* buf, int len)
15435 {
15436     int format;
15437     int dateLen;
15438     byte* date = (byte*)t;
15439 
15440     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_string");
15441 
15442     if (t == NULL || buf == NULL || len < 5) {
15443         WOLFSSL_MSG("Bad argument");
15444         return NULL;
15445     }
15446 
15447     format  = *date; date++;
15448     dateLen = *date; date++;
15449     if (dateLen > len) {
15450         WOLFSSL_MSG("Length of date is longer then buffer");
15451         return NULL;
15452     }
15453 
15454     if (!GetTimeString(date, format, buf, len)) {
15455         return NULL;
15456     }
15457 
15458     return buf;
15459 }
15460 #endif /* WOLFSSL_MYSQL_COMPATIBLE */
15461 
15462 
15463 int wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER* a,
15464                             const WOLFSSL_ASN1_INTEGER* b)
15465 {
15466     (void)a;
15467     (void)b;
15468     return 0;
15469 }
15470 
15471 
15472 long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER* i)
15473 {
15474     (void)i;
15475     return 0;
15476 }
15477 
15478 
15479 void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx)
15480 {
15481     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_ex_data");
15482 #if defined(HAVE_EX_DATA) || defined(FORTRESS)
15483     if (ctx != NULL && idx == 0)
15484         return ctx->ex_data;
15485 #else
15486     (void)ctx;
15487     (void)idx;
15488 #endif
15489     return 0;
15490 }
15491 
15492 
15493 int wolfSSL_get_ex_data_X509_STORE_CTX_idx(void)
15494 {
15495     WOLFSSL_ENTER("wolfSSL_get_ex_data_X509_STORE_CTX_idx");
15496     return 0;
15497 }
15498 
15499 
15500 void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX* ctx,
15501        void (*f)(const WOLFSSL* ssl, int type, int val))
15502 {
15503     (void)ctx;
15504     (void)f;
15505 }
15506 
15507 
15508 unsigned long wolfSSL_ERR_peek_error(void)
15509 {
15510     WOLFSSL_ENTER("wolfSSL_ERR_peek_error");
15511 
15512 #ifdef OPENSSL_EXTRA
15513     return wolfSSL_ERR_peek_error_line_data(NULL, NULL, NULL, NULL);
15514 #else
15515     return 0;
15516 #endif
15517 }
15518 
15519 
15520 int wolfSSL_ERR_GET_REASON(unsigned long err)
15521 {
15522 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
15523     /* Nginx looks for this error to know to stop parsing certificates. */
15524     if (err == ((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE))
15525         return PEM_R_NO_START_LINE;
15526 #endif
15527     (void)err;
15528     return 0;
15529 }
15530 
15531 
15532 char* wolfSSL_alert_type_string_long(int alertID)
15533 {
15534     (void)alertID;
15535     return 0;
15536 }
15537 
15538 
15539 char* wolfSSL_alert_desc_string_long(int alertID)
15540 {
15541     (void)alertID;
15542     return 0;
15543 }
15544 
15545 
15546 char* wolfSSL_state_string_long(const WOLFSSL* ssl)
15547 {
15548     (void)ssl;
15549     return 0;
15550 }
15551 
15552 
15553 int wolfSSL_PEM_def_callback(char* name, int num, int w, void* key)
15554 {
15555     (void)name;
15556     (void)num;
15557     (void)w;
15558     (void)key;
15559     return 0;
15560 }
15561 
15562 
15563 unsigned long wolfSSL_set_options(WOLFSSL* ssl, unsigned long op)
15564 {
15565     WOLFSSL_ENTER("wolfSSL_set_options");
15566 
15567     if (ssl == NULL) {
15568         return 0;
15569     }
15570 
15571     /* if SSL_OP_ALL then turn all bug workarounds one */
15572     if ((op & SSL_OP_ALL) == SSL_OP_ALL) {
15573         WOLFSSL_MSG("\tSSL_OP_ALL");
15574 
15575         op |= SSL_OP_MICROSOFT_SESS_ID_BUG;
15576         op |= SSL_OP_NETSCAPE_CHALLENGE_BUG;
15577         op |= SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
15578         op |= SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG;
15579         op |= SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER;
15580         op |= SSL_OP_MSIE_SSLV2_RSA_PADDING;
15581         op |= SSL_OP_SSLEAY_080_CLIENT_DH_BUG;
15582         op |= SSL_OP_TLS_D5_BUG;
15583         op |= SSL_OP_TLS_BLOCK_PADDING_BUG;
15584         op |= SSL_OP_TLS_ROLLBACK_BUG;
15585         op |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
15586     }
15587 
15588     ssl->options.mask |= op;
15589 
15590     /* by default cookie exchange is on with DTLS */
15591     if ((ssl->options.mask & SSL_OP_COOKIE_EXCHANGE) == SSL_OP_COOKIE_EXCHANGE) {
15592         WOLFSSL_MSG("\tSSL_OP_COOKIE_EXCHANGE : on by default");
15593     }
15594 
15595     if ((ssl->options.mask & SSL_OP_NO_SSLv2) == SSL_OP_NO_SSLv2) {
15596         WOLFSSL_MSG("\tSSL_OP_NO_SSLv2 : wolfSSL does not support SSLv2");
15597     }
15598 
15599     if ((ssl->options.mask & SSL_OP_NO_TLSv1_2) == SSL_OP_NO_TLSv1_2) {
15600         WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_2");
15601         if (ssl->version.minor == TLSv1_2_MINOR)
15602             ssl->version.minor = TLSv1_1_MINOR;
15603     }
15604 
15605     if ((ssl->options.mask & SSL_OP_NO_TLSv1_1) == SSL_OP_NO_TLSv1_1) {
15606         WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_1");
15607         if (ssl->version.minor == TLSv1_1_MINOR)
15608             ssl->version.minor = TLSv1_MINOR;
15609     }
15610 
15611     if ((ssl->options.mask & SSL_OP_NO_TLSv1) == SSL_OP_NO_TLSv1) {
15612         WOLFSSL_MSG("\tSSL_OP_NO_TLSv1");
15613         if (ssl->version.minor == TLSv1_MINOR)
15614             ssl->version.minor = SSLv3_MINOR;
15615     }
15616 
15617     if ((ssl->options.mask & SSL_OP_NO_SSLv3) == SSL_OP_NO_SSLv3) {
15618         WOLFSSL_MSG("\tSSL_OP_NO_SSLv3");
15619     }
15620 
15621     if ((ssl->options.mask & SSL_OP_NO_COMPRESSION) == SSL_OP_NO_COMPRESSION) {
15622     #ifdef HAVE_LIBZ
15623         WOLFSSL_MSG("SSL_OP_NO_COMPRESSION");
15624         ssl->options.usingCompression = 0;
15625     #else
15626         WOLFSSL_MSG("SSL_OP_NO_COMPRESSION: compression not compiled in");
15627     #endif
15628     }
15629 
15630     return ssl->options.mask;
15631 }
15632 
15633 
15634 unsigned long wolfSSL_get_options(const WOLFSSL* ssl)
15635 {
15636     WOLFSSL_ENTER("wolfSSL_get_options");
15637 
15638     return ssl->options.mask;
15639 }
15640 
15641 /*** TBD ***/
15642 WOLFSSL_API long wolfSSL_clear_num_renegotiations(WOLFSSL *s)
15643 {
15644     (void)s;
15645     return 0;
15646 }
15647 
15648 /*** TBD ***/
15649 WOLFSSL_API long wolfSSL_total_renegotiations(WOLFSSL *s)
15650 {
15651     (void)s;
15652     return 0;
15653 }
15654 
15655 
15656 #ifndef NO_DH
15657 long wolfSSL_set_tmp_dh(WOLFSSL *ssl, WOLFSSL_DH *dh)
15658 {
15659     int pSz, gSz;
15660     byte *p, *g;
15661     int ret = 0;
15662 
15663     WOLFSSL_ENTER("wolfSSL_set_tmp_dh");
15664 
15665     if (!ssl || !dh)
15666         return BAD_FUNC_ARG;
15667 
15668     /* Get needed size for p and g */
15669     pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
15670     gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
15671 
15672     if (pSz <= 0 || gSz <= 0)
15673         return SSL_FATAL_ERROR;
15674 
15675     p = (byte*)XMALLOC(pSz, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
15676     if (!p)
15677         return MEMORY_E;
15678 
15679     g = (byte*)XMALLOC(gSz, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
15680     if (!g) {
15681         XFREE(p, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
15682         return MEMORY_E;
15683     }
15684 
15685     pSz = wolfSSL_BN_bn2bin(dh->p, p);
15686     gSz = wolfSSL_BN_bn2bin(dh->g, g);
15687 
15688     if (pSz >= 0 && gSz >= 0) /* Conversion successful */
15689         ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
15690 
15691     XFREE(p, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
15692     XFREE(g, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
15693 
15694     return pSz > 0 && gSz > 0 ? ret : SSL_FATAL_ERROR;
15695 }
15696 #endif /* !NO_DH */
15697 
15698 
15699 #ifdef HAVE_PK_CALLBACKS
15700 long wolfSSL_set_tlsext_debug_arg(WOLFSSL* ssl, void *arg)
15701 {
15702     if (ssl == NULL) {
15703         return SSL_FAILURE;
15704     }
15705 
15706     ssl->loggingCtx = arg;
15707     return SSL_SUCCESS;
15708 }
15709 #endif /* HAVE_PK_CALLBACKS */
15710 
15711 #ifdef WOLFSSL_HAPROXY
15712 const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *sess, unsigned int *sid_ctx_length)
15713 {
15714     const byte *c = wolfSSL_SESSION_get_id((SSL_SESSION *)sess, sid_ctx_length);
15715     return c;
15716 }
15717 #endif
15718 
15719 /*** TBD ***/
15720 WOLFSSL_API int wolfSSL_sk_SSL_COMP_zero(WOLFSSL_STACK* st)
15721 {
15722     (void)st;
15723     WOLFSSL_STUB("wolfSSL_sk_SSL_COMP_zero");
15724     //wolfSSL_set_options(ssl, SSL_OP_NO_COMPRESSION);
15725     return SSL_FAILURE;
15726 }
15727 
15728 
15729 /*** TBD ***/
15730 WOLFSSL_API long wolfSSL_set_tlsext_status_type(WOLFSSL *s, int type)
15731 {
15732     (void)s;
15733     (void)type;
15734     WOLFSSL_STUB("wolfSSL_set_tlsext_status_type");
15735     return SSL_FAILURE;
15736 }
15737 
15738 /*** TBD ***/
15739 WOLFSSL_API long wolfSSL_get_tlsext_status_exts(WOLFSSL *s, void *arg)
15740 {
15741     (void)s;
15742     (void)arg;
15743     WOLFSSL_STUB("wolfSSL_get_tlsext_status_exts");
15744     return SSL_FAILURE;
15745 }
15746 
15747 /*** TBD ***/
15748 WOLFSSL_API long wolfSSL_set_tlsext_status_exts(WOLFSSL *s, void *arg)
15749 {
15750     (void)s;
15751     (void)arg;
15752     WOLFSSL_STUB("wolfSSL_set_tlsext_status_exts");
15753     return SSL_FAILURE;
15754 }
15755 
15756 /*** TBD ***/
15757 WOLFSSL_API long wolfSSL_get_tlsext_status_ids(WOLFSSL *s, void *arg)
15758 {
15759     (void)s;
15760     (void)arg;
15761     WOLFSSL_STUB("wolfSSL_get_tlsext_status_ids");
15762     return SSL_FAILURE;
15763 }
15764 
15765 /*** TBD ***/
15766 WOLFSSL_API long wolfSSL_set_tlsext_status_ids(WOLFSSL *s, void *arg)
15767 {
15768     (void)s;
15769     (void)arg;
15770     WOLFSSL_STUB("wolfSSL_set_tlsext_status_ids");
15771     return SSL_FAILURE;
15772 }
15773 
15774 /*** TBD ***/
15775 WOLFSSL_API int SSL_SESSION_set1_id(WOLFSSL_SESSION *s, const unsigned char *sid, unsigned int sid_len)
15776 {
15777     (void)s;
15778     (void)sid;
15779     (void)sid_len;
15780     WOLFSSL_STUB("SSL_SESSION_set1_id");
15781     return SSL_FAILURE;
15782 }
15783 
15784 /*** TBD ***/
15785 WOLFSSL_API int SSL_SESSION_set1_id_context(WOLFSSL_SESSION *s, const unsigned char *sid_ctx, unsigned int sid_ctx_len)
15786 {
15787     (void)s;
15788     (void)sid_ctx;
15789     (void)sid_ctx_len;
15790     WOLFSSL_STUB("SSL_SESSION_set1_id_context");
15791     return SSL_FAILURE;
15792 }
15793 
15794 /*** TBD ***/
15795 WOLFSSL_API void *X509_get0_tbs_sigalg(const WOLFSSL_X509 *x)
15796 {
15797     (void)x;
15798     WOLFSSL_STUB("X509_get0_tbs_sigalg");
15799     return NULL;
15800 }
15801 
15802 /*** TBD ***/
15803 WOLFSSL_API void X509_ALGOR_get0(WOLFSSL_ASN1_OBJECT **paobj, int *pptype, const void **ppval, const void *algor)
15804 {
15805     (void)paobj;
15806     (void)pptype;
15807     (void)ppval;
15808     (void)algor;
15809     WOLFSSL_STUB("X509_ALGOR_get0");
15810 }
15811 
15812 /*** TBD ***/
15813 WOLFSSL_API void *X509_get_X509_PUBKEY(void * x)
15814 {
15815     (void)x;
15816     WOLFSSL_STUB("X509_get_X509_PUBKEY");
15817     return NULL;
15818 }
15819 
15820 /*** TBD ***/
15821 WOLFSSL_API int X509_PUBKEY_get0_param(WOLFSSL_ASN1_OBJECT **ppkalg, const unsigned char **pk, int *ppklen, void **pa, WOLFSSL_EVP_PKEY *pub)
15822 {
15823     (void)ppkalg;
15824     (void)pk;
15825     (void)ppklen;
15826     (void)pa;
15827     (void)pub;
15828     WOLFSSL_STUB("X509_PUBKEY_get0_param");
15829     return SSL_FAILURE;
15830 }
15831 
15832 /*** TBD ***/
15833 WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_get_privatekey(const WOLFSSL *ssl)
15834 {
15835     (void)ssl;
15836     WOLFSSL_STUB("SSL_get_privatekey");
15837     return NULL;
15838 }
15839 
15840 /*** TBD ***/
15841 WOLFSSL_API int EVP_PKEY_bits(WOLFSSL_EVP_PKEY *pkey)
15842 {
15843     (void)pkey;
15844     WOLFSSL_STUB("EVP_PKEY_bits");
15845     return SSL_FAILURE;
15846 }
15847 
15848 /*** TBD ***/
15849 WOLFSSL_API int i2d_X509(WOLFSSL_X509 *x, unsigned char **out)
15850 {
15851     (void)x;
15852     (void)out;
15853     WOLFSSL_STUB("i2d_X509");
15854     return -1;
15855 }
15856 
15857 /*** TBD ***/
15858 WOLFSSL_API int i2t_ASN1_OBJECT(char *buf, int buf_len, WOLFSSL_ASN1_OBJECT *a)
15859 {
15860     (void)buf;
15861     (void)buf_len;
15862     (void)a;
15863     WOLFSSL_STUB("i2t_ASN1_OBJECT");
15864     return -1;
15865 }
15866 
15867 /*** TBD ***/
15868 WOLFSSL_API size_t SSL_get_finished(const WOLFSSL *s, void *buf, size_t count)
15869 {
15870     (void)s;
15871     (void)buf;
15872     (void)count;
15873     WOLFSSL_STUB("SSL_get_finished");
15874     return SSL_FAILURE;
15875 }
15876 
15877 /*** TBD ***/
15878 WOLFSSL_API size_t SSL_get_peer_finished(const WOLFSSL *s, void *buf, size_t count)
15879 {
15880     (void)s;
15881     (void)buf;
15882     (void)count;
15883     WOLFSSL_STUB("SSL_get_peer_finished");
15884     return SSL_FAILURE;
15885 }
15886 
15887 /*** TBD ***/
15888 WOLFSSL_API void SSL_CTX_set_tmp_dh_callback(WOLFSSL_CTX *ctx, WOLFSSL_DH *(*dh) (WOLFSSL *ssl, int is_export, int keylength))
15889 {
15890     (void)ctx;
15891     (void)dh;
15892     WOLFSSL_STUB("SSL_CTX_set_tmp_dh_callback");
15893 }
15894 
15895 /*** TBD ***/
15896 WOLFSSL_API STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
15897 {
15898     WOLFSSL_STUB("SSL_COMP_get_compression_methods");
15899     return NULL;
15900 }
15901 
15902 /*** TBD ***/
15903 WOLFSSL_API int wolfSSL_sk_SSL_CIPHER_num(const void * p)
15904 {
15905     (void)p;
15906     WOLFSSL_STUB("wolfSSL_sk_SSL_CIPHER_num");
15907     return -1;
15908 }
15909 
15910 #if !defined(NO_FILESYSTEM)
15911 /*** TBD ***/
15912 WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_X509(FILE *fp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u)
15913 {
15914     (void)fp;
15915     (void)x;
15916     (void)cb;
15917     (void)u;
15918     WOLFSSL_STUB("PEM_read_X509");
15919     return NULL;
15920 }
15921 
15922 /*** TBD ***/
15923 WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PrivateKey(FILE *fp, WOLFSSL_EVP_PKEY **x, pem_password_cb *cb, void *u)
15924 {
15925     (void)fp;
15926     (void)x;
15927     (void)cb;
15928     (void)u;
15929     WOLFSSL_STUB("PEM_read_PrivateKey");
15930     return NULL;
15931 }
15932 #endif
15933 
15934 /*** TBD ***/
15935 WOLFSSL_API int X509_STORE_load_locations(WOLFSSL_X509_STORE *ctx, const char *file, const char *dir)
15936 {
15937     (void)ctx;
15938     (void)file;
15939     (void)dir;
15940     WOLFSSL_STUB("X509_STORE_load_locations");
15941     return SSL_FAILURE;
15942 }
15943 
15944 /*** TBD ***/
15945 WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_value(void *ciphers, int idx)
15946 {
15947     (void)ciphers;
15948     (void)idx;
15949     WOLFSSL_STUB("wolfSSL_sk_SSL_CIPHER_value");
15950     return NULL;
15951 }
15952 
15953 WOLFSSL_API void ERR_load_SSL_strings(void)
15954 {
15955 
15956 }
15957 
15958 WOLFSSL_API long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char **resp)
15959 {
15960     if (s == NULL || resp == NULL)
15961         return 0;
15962 
15963     *resp = s->ocspResp;
15964     return s->ocspRespSz;
15965 }
15966 
15967 WOLFSSL_API long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *s,
15968     unsigned char *resp, int len)
15969 {
15970     if (s == NULL)
15971         return SSL_FAILURE;
15972 
15973     s->ocspResp   = resp;
15974     s->ocspRespSz = len;
15975 
15976     return SSL_SUCCESS;
15977 }
15978 
15979 
15980 long wolfSSL_get_verify_result(const WOLFSSL *ssl)
15981 {
15982     if (ssl == NULL) {
15983         return SSL_FAILURE;
15984     }
15985 
15986     return ssl->peerVerifyRet;
15987 }
15988 
15989 
15990 long wolfSSL_CTX_sess_accept(WOLFSSL_CTX* ctx)
15991 {
15992     (void)ctx;
15993     return 0;
15994 }
15995 
15996 long wolfSSL_CTX_sess_connect(WOLFSSL_CTX* ctx)
15997 {
15998     (void)ctx;
15999     return 0;
16000 }
16001 
16002 
16003 long wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX* ctx)
16004 {
16005     (void)ctx;
16006     return 0;
16007 }
16008 
16009 
16010 long wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX* ctx)
16011 {
16012     (void)ctx;
16013     return 0;
16014 }
16015 
16016 
16017 long wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX* ctx)
16018 {
16019     (void)ctx;
16020     return 0;
16021 }
16022 
16023 
16024 long wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX* ctx)
16025 {
16026     (void)ctx;
16027     return 0;
16028 }
16029 
16030 
16031 long wolfSSL_CTX_sess_hits(WOLFSSL_CTX* ctx)
16032 {
16033     (void)ctx;
16034     return 0;
16035 }
16036 
16037 
16038 long wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX* ctx)
16039 {
16040     (void)ctx;
16041     return 0;
16042 }
16043 
16044 
16045 long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX* ctx)
16046 {
16047     (void)ctx;
16048     return 0;
16049 }
16050 
16051 
16052 long wolfSSL_CTX_sess_misses(WOLFSSL_CTX* ctx)
16053 {
16054     (void)ctx;
16055     return 0;
16056 }
16057 
16058 
16059 long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX* ctx)
16060 {
16061     (void)ctx;
16062     return 0;
16063 }
16064 
16065 
16066 long wolfSSL_CTX_sess_number(WOLFSSL_CTX* ctx)
16067 {
16068     (void)ctx;
16069     return 0;
16070 }
16071 
16072 
16073 #ifndef NO_CERTS
16074 long wolfSSL_CTX_add_extra_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
16075 {
16076     byte* chain = NULL;
16077     long  chainSz = 0;
16078     int   derSz;
16079     const byte* der;
16080     int   ret;
16081     int   idx = 0;
16082     DerBuffer *derBuffer = NULL;
16083 
16084     WOLFSSL_ENTER("wolfSSL_CTX_add_extra_chain_cert");
16085 
16086     if (ctx == NULL || x509 == NULL) {
16087         WOLFSSL_MSG("Bad Argument");
16088         return SSL_FAILURE;
16089     }
16090 
16091     der = wolfSSL_X509_get_der(x509, &derSz);
16092     if (der == NULL || derSz <= 0) {
16093         WOLFSSL_MSG("Error getting X509 DER");
16094         return SSL_FAILURE;
16095     }
16096 
16097     if (ctx->certificate == NULL) {
16098         /* Process buffer makes first certificate the leaf. */
16099         ret = ProcessBuffer(ctx, der, derSz, SSL_FILETYPE_ASN1, CERT_TYPE,
16100                             NULL, NULL, 1);
16101         if (ret != SSL_SUCCESS) {
16102             WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret);
16103             return SSL_FAILURE;
16104         }
16105     }
16106     else {
16107         /* TODO: Do this elsewhere. */
16108         ret = AllocDer(&derBuffer, derSz, CERT_TYPE, ctx->heap);
16109         if (ret != 0) {
16110             WOLFSSL_MSG("Memory Error");
16111             return SSL_FAILURE;
16112         }
16113         XMEMCPY(derBuffer->buffer, der, derSz);
16114         ret = AddCA(ctx->cm, &derBuffer, WOLFSSL_USER_CA, !ctx->verifyNone);
16115         if (ret != SSL_SUCCESS) {
16116             WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret);
16117             return SSL_FAILURE;
16118         }
16119 
16120         /* adding cert to existing chain */
16121         if (ctx->certChain != NULL && ctx->certChain->length > 0) {
16122             chainSz += ctx->certChain->length;
16123         }
16124         chainSz += OPAQUE24_LEN + derSz;
16125 
16126         chain = (byte*)XMALLOC(chainSz, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
16127         if (chain == NULL) {
16128             WOLFSSL_MSG("Memory Error");
16129             return SSL_FAILURE;
16130         }
16131 
16132         if (ctx->certChain != NULL && ctx->certChain->length > 0) {
16133             XMEMCPY(chain, ctx->certChain->buffer, ctx->certChain->length);
16134             idx = ctx->certChain->length;
16135         }
16136         c32to24(derSz, chain + idx);
16137         idx += OPAQUE24_LEN,
16138         XMEMCPY(chain + idx, der, derSz);
16139         idx += derSz;
16140 
16141         FreeDer(&ctx->certChain);
16142         ret = AllocDer(&ctx->certChain, idx, CERT_TYPE, ctx->heap);
16143         if (ret == 0) {
16144             XMEMCPY(ctx->certChain->buffer, chain, idx);
16145         }
16146     }
16147 
16148     /* on success WOLFSSL_X509 memory is responsibility of ctx */
16149     wolfSSL_X509_free(x509);
16150     if (chain != NULL)
16151         XFREE(chain, ctx->heap, CERT_TYPE);
16152 
16153     return SSL_SUCCESS;
16154 }
16155 
16156 
16157 long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX* ctx, void* arg)
16158 {
16159     if (ctx == NULL || ctx->cm == NULL) {
16160         return SSL_FAILURE;
16161     }
16162 
16163     ctx->cm->ocspIOCtx = arg;
16164     return SSL_SUCCESS;
16165 }
16166 
16167 #endif /* NO_CERTS */
16168 
16169 
16170 /*** TBC ***/
16171 WOLFSSL_API long wolfSSL_CTX_get_session_cache_mode(WOLFSSL_CTX* ctx)
16172 {
16173     (void)ctx;
16174     return 0;
16175 }
16176 
16177 
16178 int wolfSSL_CTX_get_read_ahead(WOLFSSL_CTX* ctx)
16179 {
16180     if (ctx == NULL) {
16181         return SSL_FAILURE;
16182     }
16183 
16184     return ctx->readAhead;
16185 }
16186 
16187 
16188 int wolfSSL_CTX_set_read_ahead(WOLFSSL_CTX* ctx, int v)
16189 {
16190     if (ctx == NULL) {
16191         return SSL_FAILURE;
16192     }
16193 
16194     ctx->readAhead = (byte)v;
16195 
16196     return SSL_SUCCESS;
16197 }
16198 
16199 
16200 long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg(WOLFSSL_CTX* ctx,
16201         void* arg)
16202 {
16203     if (ctx == NULL) {
16204         return SSL_FAILURE;
16205     }
16206 
16207     ctx->userPRFArg = arg;
16208     return SSL_SUCCESS;
16209 }
16210 
16211 
16212 #ifndef NO_DES3
16213 /* 0 on success */
16214 int wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* myDes,
16215                                                WOLFSSL_DES_key_schedule* key)
16216 {
16217 #ifdef WOLFSSL_CHECK_DESKEY
16218     return wolfSSL_DES_set_key_checked(myDes, key);
16219 #else
16220     wolfSSL_DES_set_key_unchecked(myDes, key);
16221     return 0;
16222 #endif
16223 }
16224 
16225 
16226 
16227 /* return true in fail case (1) */
16228 static int DES_check(word32 mask, word32 mask2, unsigned char* key)
16229 {
16230     word32 value[2];
16231 
16232     /* sanity check on length made in wolfSSL_DES_set_key_checked */
16233     value[0] = mask;
16234     value[1] = mask2;
16235     return (XMEMCMP(value, key, sizeof(value)) == 0)? 1: 0;
16236 }
16237 
16238 
16239 /* check that the key is odd parity and is not a weak key
16240  * returns -1 if parity is wrong, -2 if weak/null key and 0 on success */
16241 int wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes,
16242                                                WOLFSSL_DES_key_schedule* key)
16243 {
16244     if (myDes == NULL || key == NULL) {
16245         WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_set_key_checked");
16246         return -2;
16247     }
16248     else {
16249         word32 i, mask, mask2;
16250         word32 sz = sizeof(WOLFSSL_DES_key_schedule);
16251 
16252         /* sanity check before call to DES_check */
16253         if (sz != (sizeof(word32) * 2)) {
16254             WOLFSSL_MSG("Unexpected WOLFSSL_DES_key_schedule size");
16255             return -2;
16256         }
16257 
16258         /* check odd parity */
16259         for (i = 0; i < sz; i++) {
16260             unsigned char c = *((unsigned char*)key + i);
16261             if (((c & 0x01) ^
16262                 ((c >> 1) & 0x01) ^
16263                 ((c >> 2) & 0x01) ^
16264                 ((c >> 3) & 0x01) ^
16265                 ((c >> 4) & 0x01) ^
16266                 ((c >> 5) & 0x01) ^
16267                 ((c >> 6) & 0x01) ^
16268                 ((c >> 7) & 0x01)) != 1) {
16269                 WOLFSSL_MSG("Odd parity test fail");
16270                 return -1;
16271             }
16272         }
16273 
16274         /* check is not weak. Weak key list from Nist
16275            "Recommendation for the Triple
16276            Data Encryption Algorithm
16277            (TDEA) Block Cipher" */
16278         mask = 0x01010101; mask2 = 0x01010101;
16279         if (DES_check(mask, mask2, *key)) {
16280             WOLFSSL_MSG("Weak key found");
16281             return -2;
16282         }
16283 
16284         mask = 0xFEFEFEFE; mask2 = 0xFEFEFEFE;
16285         if (DES_check(mask, mask2, *key)) {
16286             WOLFSSL_MSG("Weak key found");
16287             return -2;
16288         }
16289 
16290         mask = 0xE0E0E0E0; mask2 = 0xF1F1F1F1;
16291         if (DES_check(mask, mask2, *key)) {
16292             WOLFSSL_MSG("Weak key found");
16293             return -2;
16294         }
16295 
16296         mask = 0x1F1F1F1F; mask2 = 0x0E0E0E0E;
16297         if (DES_check(mask, mask2, *key)) {
16298             WOLFSSL_MSG("Weak key found");
16299             return -2;
16300         }
16301 
16302         /* semi-weak *key check (list from same Nist paper) */
16303         mask  = 0x011F011F; mask2 = 0x010E010E;
16304         if (DES_check(mask, mask2, *key) ||
16305            DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
16306             WOLFSSL_MSG("Weak key found");
16307             return -2;
16308         }
16309 
16310         mask  = 0x01E001E0; mask2 = 0x01F101F1;
16311         if (DES_check(mask, mask2, *key) ||
16312            DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
16313             WOLFSSL_MSG("Weak key found");
16314             return -2;
16315         }
16316 
16317         mask  = 0x01FE01FE; mask2 = 0x01FE01FE;
16318         if (DES_check(mask, mask2, *key) ||
16319            DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
16320             WOLFSSL_MSG("Weak key found");
16321             return -2;
16322         }
16323 
16324         mask  = 0x1FE01FE0; mask2 = 0x0EF10EF1;
16325         if (DES_check(mask, mask2, *key) ||
16326            DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
16327             WOLFSSL_MSG("Weak key found");
16328             return -2;
16329         }
16330 
16331         mask  = 0x1FFE1FFE; mask2 = 0x0EFE0EFE;
16332         if (DES_check(mask, mask2, *key) ||
16333            DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
16334             WOLFSSL_MSG("Weak key found");
16335             return -2;
16336         }
16337 
16338         /* passed tests, now copy over key */
16339         XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock));
16340 
16341         return 0;
16342     }
16343 }
16344 
16345 
16346 void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock* myDes,
16347                                                WOLFSSL_DES_key_schedule* key)
16348 {
16349     if (myDes != NULL && key != NULL) {
16350         XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock));
16351     }
16352 }
16353 
16354 
16355 void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* myDes)
16356 {
16357     (void)myDes;
16358     WOLFSSL_STUB("wolfSSL_DES_set_odd_parity");
16359 }
16360 
16361 
16362 #ifdef WOLFSSL_DES_ECB
16363 /* Encrpyt or decrypt input message desa with key and get output in desb.
16364  * if enc is DES_ENCRYPT,input message is encrypted or
16365  * if enc is DES_DECRYPT,input message is decrypted.
16366  * */
16367 void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* desa,
16368              WOLFSSL_DES_cblock* desb, WOLFSSL_DES_key_schedule* key, int enc)
16369 {
16370     Des myDes;
16371 
16372     WOLFSSL_ENTER("wolfSSL_DES_ecb_encrypt");
16373 
16374     if (desa == NULL || key == NULL || desb == NULL ||
16375         (enc != DES_ENCRYPT && enc != DES_DECRYPT)) {
16376         WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_ecb_encrypt");
16377     } else {
16378         if (wc_Des_SetKey(&myDes, (const byte*) key,
16379                            (const byte*) NULL, !enc) != 0) {
16380             WOLFSSL_MSG("wc_Des_SetKey return error.");
16381             return;
16382         }
16383         if (wc_Des_EcbEncrypt(&myDes, (byte*) desb,
16384                               (const byte*)desa, sizeof(WOLFSSL_DES_cblock)) != 0){
16385             WOLFSSL_MSG("wc_Des_EcbEncrypt return error.");
16386         }
16387     }
16388 }
16389 #endif
16390 
16391 #endif /* NO_DES3 */
16392 
16393 int wolfSSL_BIO_printf(WOLFSSL_BIO* bio, const char* format, ...)
16394 {
16395     (void)bio;
16396     (void)format;
16397     return 0;
16398 }
16399 
16400 
16401 int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a)
16402 {
16403     (void)bio;
16404     (void)a;
16405     return 0;
16406 }
16407 
16408 /* Return the month as a string.
16409  *
16410  * n  The number of the month as a two characters (1 based).
16411  * returns the month as a string.
16412  */
16413 static INLINE const char* MonthStr(const char* n)
16414 {
16415     static const char monthStr[12][4] = {
16416             "Jan", "Feb", "Mar", "Apr", "May", "Jun",
16417             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
16418     return monthStr[(n[0] - '0') * 10 + (n[1] - '0') - 1];
16419 }
16420 
16421 int wolfSSL_ASN1_GENERALIZEDTIME_print(WOLFSSL_BIO* bio,
16422     const WOLFSSL_ASN1_GENERALIZEDTIME* asnTime)
16423 {
16424     const char* p = (const char *)(asnTime->data + 2);
16425     WOLFSSL_ENTER("wolfSSL_ASN1_GENERALIZEDTIME_print");
16426 
16427     if (bio == NULL || asnTime == NULL)
16428         return BAD_FUNC_ARG;
16429 
16430     /* GetTimeString not always available. */
16431     wolfSSL_BIO_write(bio, MonthStr(p + 4), 3);
16432     wolfSSL_BIO_write(bio, " ", 1);
16433     /* Day */
16434     wolfSSL_BIO_write(bio, p + 6, 2);
16435     wolfSSL_BIO_write(bio, " ", 1);
16436     /* Hour */
16437     wolfSSL_BIO_write(bio, p + 8, 2);
16438     wolfSSL_BIO_write(bio, ":", 1);
16439     /* Min */
16440     wolfSSL_BIO_write(bio, p + 10, 2);
16441     wolfSSL_BIO_write(bio, ":", 1);
16442     /* Secs */
16443     wolfSSL_BIO_write(bio, p + 12, 2);
16444     wolfSSL_BIO_write(bio, " ", 1);
16445     wolfSSL_BIO_write(bio, p, 4);
16446 
16447     return 0;
16448 }
16449 
16450 int  wolfSSL_sk_num(WOLFSSL_X509_REVOKED* rev)
16451 {
16452     (void)rev;
16453     return 0;
16454 }
16455 
16456 
16457 void* wolfSSL_sk_value(WOLFSSL_X509_REVOKED* rev, int i)
16458 {
16459     (void)rev;
16460     (void)i;
16461     return 0;
16462 }
16463 
16464 
16465 /* stunnel 4.28 needs */
16466 void wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX* ctx,
16467                     WOLFSSL_SESSION*(*f)(WOLFSSL*, unsigned char*, int, int*))
16468 {
16469 #ifdef HAVE_EXT_CACHE
16470     ctx->get_sess_cb = f;
16471 #else
16472     (void)ctx;
16473     (void)f;
16474 #endif
16475 }
16476 
16477 
16478 void wolfSSL_CTX_sess_set_new_cb(WOLFSSL_CTX* ctx,
16479                              int (*f)(WOLFSSL*, WOLFSSL_SESSION*))
16480 {
16481 #ifdef HAVE_EXT_CACHE
16482     ctx->new_sess_cb = f;
16483 #else
16484     (void)ctx;
16485     (void)f;
16486 #endif
16487 }
16488 
16489 
16490 void wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX* ctx, void (*f)(WOLFSSL_CTX*,
16491                                                         WOLFSSL_SESSION*))
16492 {
16493 #ifdef HAVE_EXT_CACHE
16494     ctx->rem_sess_cb = f;
16495 #else
16496     (void)ctx;
16497     (void)f;
16498 #endif
16499 }
16500 
16501 #ifdef HAVE_EXT_CACHE
16502 /* convert 32 bit integer to opaque */
16503 static INLINE void c32toa(word32 u32, byte* c)
16504 {
16505     c[0] = (u32 >> 24) & 0xff;
16506     c[1] = (u32 >> 16) & 0xff;
16507     c[2] = (u32 >>  8) & 0xff;
16508     c[3] =  u32 & 0xff;
16509 }
16510 
16511 static INLINE void c16toa(word16 u16, byte* c)
16512 {
16513     c[0] = (u16 >> 8) & 0xff;
16514     c[1] =  u16 & 0xff;
16515 }
16516 #endif
16517 
16518 int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
16519 {
16520     int size = 0;
16521 #ifdef HAVE_EXT_CACHE
16522     int idx = 0;
16523 #ifdef SESSION_CERTS
16524     int i;
16525 #endif
16526     unsigned char *data;
16527 
16528     /* bornOn | timeout | sessionID len | sessionID | masterSecret | haveEMS */
16529     size += OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN + sess->sessionIDSz +
16530             SECRET_LEN + OPAQUE8_LEN;
16531 #ifdef SESSION_CERTS
16532     /* Peer chain */
16533     size += OPAQUE8_LEN;
16534     for (i = 0; i < sess->chain.count; i++)
16535         size += OPAQUE16_LEN + sess->chain.certs[i].length;
16536     /* Protocol version + cipher suite */
16537     size += OPAQUE16_LEN + OPAQUE16_LEN;
16538 #endif
16539 #ifndef NO_CLIENT_CACHE
16540     /* ServerID len | ServerID */
16541     size += OPAQUE16_LEN + sess->idLen;
16542 #endif
16543 #ifdef HAVE_SESSION_TICKET
16544     /* ticket len | ticket */
16545     size += OPAQUE16_LEN + sess->ticketLen;
16546 #endif
16547 
16548     if (p != NULL) {
16549         if (*p == NULL)
16550             *p = (unsigned char*)XMALLOC(size, NULL, DYNAMIC_TYPE_OPENSSL);
16551         if (*p == NULL)
16552             return 0;
16553         data = *p;
16554 
16555         c32toa(sess->bornOn, data + idx); idx += OPAQUE32_LEN;
16556         c32toa(sess->timeout, data + idx); idx += OPAQUE32_LEN;
16557         data[idx++] = sess->sessionIDSz;
16558         XMEMCPY(data + idx, sess->sessionID, sess->sessionIDSz);
16559         idx += sess->sessionIDSz;
16560         XMEMCPY(data + idx, sess->masterSecret, SECRET_LEN); idx += SECRET_LEN;
16561         data[idx++] = sess->haveEMS;
16562 #ifdef SESSION_CERTS
16563         data[idx++] = sess->chain.count;
16564         for (i = 0; i < sess->chain.count; i++) {
16565             c16toa(sess->chain.certs[i].length, data + idx);
16566             idx += OPAQUE16_LEN;
16567             XMEMCPY(data + idx, sess->chain.certs[i].buffer,
16568                     sess->chain.certs[i].length);
16569             idx += sess->chain.certs[i].length;
16570         }
16571         data[idx++] = sess->version.major;
16572         data[idx++] = sess->version.minor;
16573         data[idx++] = sess->cipherSuite0;
16574         data[idx++] = sess->cipherSuite;
16575 #endif
16576 #ifndef NO_CLIENT_CACHE
16577         c16toa(sess->idLen, data + idx); idx += OPAQUE16_LEN;
16578         XMEMCPY(data + idx, sess->serverID, sess->idLen);
16579         idx += sess->idLen;
16580 #endif
16581 #ifdef HAVE_SESSION_TICKET
16582         c16toa(sess->ticketLen, data + idx); idx += OPAQUE16_LEN;
16583         XMEMCPY(data + idx, sess->ticket, sess->ticketLen);
16584         idx += sess->ticketLen;
16585 #endif
16586     }
16587 #endif
16588 
16589     (void)sess;
16590     (void)p;
16591 #ifdef HAVE_EXT_CACHE
16592     (void)idx;
16593 #endif
16594 
16595     return size;
16596 }
16597 
16598 #ifdef HAVE_EXT_CACHE
16599 /* convert opaque to 16 bit integer */
16600 static INLINE void ato16(const byte* c, word16* u16)
16601 {
16602     *u16 = (word16) ((c[0] << 8) | (c[1]));
16603 }
16604 
16605 /* convert opaque to 32 bit integer */
16606 static INLINE void ato32(const byte* c, word32* u32)
16607 {
16608     *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
16609 }
16610 #endif
16611 
16612 /* TODO: no function to free new session. */
16613 WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
16614                                 const unsigned char** p, long i)
16615 {
16616     WOLFSSL_SESSION* s = NULL;
16617     int ret = 0;
16618 #if defined(HAVE_EXT_CACHE)
16619     int idx;
16620     byte* data;
16621 #ifdef SESSION_CERTS
16622     int j;
16623     word16 length;
16624 #endif
16625 #endif
16626 
16627     (void)p;
16628     (void)i;
16629     (void)ret;
16630 
16631     if (sess != NULL)
16632         s = *sess;
16633 
16634 #ifdef HAVE_EXT_CACHE
16635     if (p == NULL || *p == NULL)
16636         return NULL;
16637 
16638     if (s == NULL) {
16639         s = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), NULL,
16640                                       DYNAMIC_TYPE_OPENSSL);
16641         if (s == NULL)
16642             return NULL;
16643         s->isAlloced = 1;
16644         s->isDynamic = 0;
16645     }
16646 
16647     idx = 0;
16648     data = (byte*)*p;
16649 
16650     /* bornOn | timeout | sessionID len */
16651     if (i < OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN) {
16652         ret = BUFFER_ERROR;
16653         goto end;
16654     }
16655     ato32(data + idx, &s->bornOn); idx += OPAQUE32_LEN;
16656     ato32(data + idx, &s->timeout); idx += OPAQUE32_LEN;
16657     s->sessionIDSz = data[idx++];
16658 
16659     /* sessionID | secret | haveEMS */
16660     if (i - idx < s->sessionIDSz + SECRET_LEN + OPAQUE8_LEN) {
16661         ret = BUFFER_ERROR;
16662         goto end;
16663     }
16664     XMEMCPY(s->sessionID, data + idx, s->sessionIDSz);
16665     idx  += s->sessionIDSz;
16666     XMEMCPY(s->masterSecret, data + idx, SECRET_LEN); idx += SECRET_LEN;
16667     s->haveEMS = data[idx++];
16668 
16669 #ifdef SESSION_CERTS
16670     /* Certificate chain */
16671     if (i - idx == 0) {
16672         ret = BUFFER_ERROR;
16673         goto end;
16674     }
16675     s->chain.count = data[idx++];
16676     for (j = 0; j < s->chain.count; j++) {
16677         if (i - idx < OPAQUE16_LEN) {
16678             ret = BUFFER_ERROR;
16679             goto end;
16680         }
16681         ato16(data + idx, &length); idx += OPAQUE16_LEN;
16682         s->chain.certs[j].length = length;
16683         if (i - idx < length) {
16684             ret = BUFFER_ERROR;
16685             goto end;
16686         }
16687         XMEMCPY(s->chain.certs[j].buffer, data + idx, length);
16688         idx += length;
16689     }
16690 
16691     /* Protocol Version | Cipher suite */
16692     if (i - idx < OPAQUE16_LEN + OPAQUE16_LEN) {
16693         ret = BUFFER_ERROR;
16694         goto end;
16695     }
16696     s->version.major = data[idx++];
16697     s->version.minor = data[idx++];
16698     s->cipherSuite0 = data[idx++];
16699     s->cipherSuite = data[idx++];
16700 #endif
16701 #ifndef NO_CLIENT_CACHE
16702     /* ServerID len */
16703     if (i - idx < OPAQUE16_LEN) {
16704         ret = BUFFER_ERROR;
16705         goto end;
16706     }
16707     ato16(data + idx, &s->idLen); idx += OPAQUE16_LEN;
16708 
16709     /* ServerID */
16710     if (i - idx < s->idLen) {
16711         ret = BUFFER_ERROR;
16712         goto end;
16713     }
16714     XMEMCPY(s->serverID, data + idx, s->idLen); idx += s->idLen;
16715 #endif
16716 #ifdef HAVE_SESSION_TICKET
16717     /* ticket len */
16718     if (i - idx < OPAQUE16_LEN) {
16719         ret = BUFFER_ERROR;
16720         goto end;
16721     }
16722     ato16(data + idx, &s->ticketLen); idx += OPAQUE16_LEN;
16723 
16724     /* Dispose of ol dynamic ticket and ensure space for new ticket. */
16725     if (s->isDynamic)
16726         XFREE(s->ticket, NULL, DYNAMIC_TYPE_SESSION_TICK);
16727     if (s->ticketLen <= SESSION_TICKET_LEN)
16728         s->ticket = s->staticTicket;
16729     else {
16730         s->ticket = (byte*)XMALLOC(s->ticketLen, NULL,
16731                                    DYNAMIC_TYPE_SESSION_TICK);
16732         if (s->ticket == NULL) {
16733             ret = MEMORY_ERROR;
16734             goto end;
16735         }
16736         s->isDynamic = 1;
16737     }
16738 
16739     /* ticket */
16740     if (i - idx < s->ticketLen) {
16741         ret = BUFFER_ERROR;
16742         goto end;
16743     }
16744     XMEMCPY(s->ticket, data + idx, s->ticketLen); idx += s->ticketLen;
16745 #endif
16746     (void)idx;
16747 
16748     if (sess != NULL)
16749         *sess = s;
16750 
16751     *p += idx;
16752 
16753 end:
16754     if (ret != 0 && (sess == NULL || *sess != s))
16755         wolfSSL_SESSION_free(s);
16756 #endif
16757     return s;
16758 }
16759 
16760 
16761 long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION* sess)
16762 {
16763     WOLFSSL_ENTER("wolfSSL_SESSION_get_timeout");
16764     return sess->timeout;
16765 }
16766 
16767 
16768 long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION* sess)
16769 {
16770     WOLFSSL_ENTER("wolfSSL_SESSION_get_time");
16771     return sess->bornOn;
16772 }
16773 
16774 
16775 #endif /* OPENSSL_EXTRA */
16776 
16777 
16778 #ifdef KEEP_PEER_CERT
16779 char*  wolfSSL_X509_get_subjectCN(WOLFSSL_X509* x509)
16780 {
16781     if (x509 == NULL)
16782         return NULL;
16783 
16784     return x509->subjectCN;
16785 }
16786 #endif /* KEEP_PEER_CERT */
16787 
16788 #ifdef OPENSSL_EXTRA
16789 
16790 #ifdef FORTRESS
16791 int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname)
16792 {
16793     int ret = SSL_FATAL_ERROR;
16794 
16795     WOLFSSL_ENTER("wolfSSL_cmp_peer_cert_to_file");
16796     if (ssl != NULL && fname != NULL)
16797     {
16798     #ifdef WOLFSSL_SMALL_STACK
16799         EncryptedInfo* info = NULL;
16800         byte           staticBuffer[1]; /* force heap usage */
16801     #else
16802         EncryptedInfo  info[1];
16803         byte           staticBuffer[FILE_BUFFER_SIZE];
16804     #endif
16805         byte*          myBuffer  = staticBuffer;
16806         int            dynamic   = 0;
16807         XFILE          file      = XBADFILE;
16808         size_t         sz        = 0;
16809         int            eccKey    = 0;
16810         WOLFSSL_CTX*   ctx       = ssl->ctx;
16811         WOLFSSL_X509*  peer_cert = &ssl->peerCert;
16812         DerBuffer*     fileDer = NULL;
16813 
16814         file = XFOPEN(fname, "rb");
16815         if (file == XBADFILE)
16816             return SSL_BAD_FILE;
16817 
16818         XFSEEK(file, 0, XSEEK_END);
16819         sz = XFTELL(file);
16820         XREWIND(file);
16821 
16822         if (sz > (long)sizeof(staticBuffer)) {
16823             WOLFSSL_MSG("Getting dynamic buffer");
16824             myBuffer = (byte*)XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
16825             dynamic = 1;
16826         }
16827 
16828     #ifdef WOLFSSL_SMALL_STACK
16829         info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
16830                                                    DYNAMIC_TYPE_TMP_BUFFER);
16831         if (info == NULL)
16832             ret = MEMORY_E;
16833         else
16834     #endif
16835         {
16836             info->set = 0;
16837             info->ctx = ctx;
16838             info->consumed = 0;
16839 
16840             if ((myBuffer != NULL) &&
16841                 (sz > 0) &&
16842                 (XFREAD(myBuffer, 1, sz, file) == sz) &&
16843                 (PemToDer(myBuffer, sz, CERT_TYPE,
16844                           &fileDer, ctx->heap, info, &eccKey) == 0) &&
16845                 (fileDer->length != 0) &&
16846                 (fileDer->length == peer_cert->derCert->length) &&
16847                 (XMEMCMP(peer_cert->derCert->buffer, fileDer->buffer,
16848                                                     fileDer->length) == 0))
16849             {
16850                 ret = 0;
16851             }
16852 
16853         #ifdef WOLFSSL_SMALL_STACK
16854             XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16855         #endif
16856         }
16857 
16858         FreeDer(&fileDer);
16859 
16860         if (dynamic)
16861             XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
16862 
16863         XFCLOSE(file);
16864     }
16865 
16866     return ret;
16867 }
16868 #endif
16869 
16870 
16871 static WC_RNG globalRNG;
16872 static int initGlobalRNG = 0;
16873 
16874 /* SSL_SUCCESS on ok */
16875 int wolfSSL_RAND_seed(const void* seed, int len)
16876 {
16877 
16878     WOLFSSL_MSG("wolfSSL_RAND_seed");
16879 
16880     (void)seed;
16881     (void)len;
16882 
16883     if (initGlobalRNG == 0) {
16884         if (wc_InitRng(&globalRNG) < 0) {
16885             WOLFSSL_MSG("wolfSSL Init Global RNG failed");
16886             return 0;
16887         }
16888         initGlobalRNG = 1;
16889     }
16890 
16891     return SSL_SUCCESS;
16892 }
16893 
16894 
16895 /* SSL_SUCCESS on ok */
16896 int wolfSSL_RAND_bytes(unsigned char* buf, int num)
16897 {
16898     int     ret = 0;
16899     int     initTmpRng = 0;
16900     WC_RNG* rng = NULL;
16901 #ifdef WOLFSSL_SMALL_STACK
16902     WC_RNG* tmpRNG = NULL;
16903 #else
16904     WC_RNG  tmpRNG[1];
16905 #endif
16906 
16907     WOLFSSL_ENTER("wolfSSL_RAND_bytes");
16908 
16909 #ifdef WOLFSSL_SMALL_STACK
16910     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
16911     if (tmpRNG == NULL)
16912         return ret;
16913 #endif
16914 
16915     if (wc_InitRng(tmpRNG) == 0) {
16916         rng = tmpRNG;
16917         initTmpRng = 1;
16918     }
16919     else if (initGlobalRNG)
16920         rng = &globalRNG;
16921 
16922     if (rng) {
16923         if (wc_RNG_GenerateBlock(rng, buf, num) != 0)
16924             WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
16925         else
16926             ret = SSL_SUCCESS;
16927     }
16928 
16929     if (initTmpRng)
16930         wc_FreeRng(tmpRNG);
16931 
16932 #ifdef WOLFSSL_SMALL_STACK
16933     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16934 #endif
16935 
16936     return ret;
16937 }
16938 
16939 WOLFSSL_BN_CTX* wolfSSL_BN_CTX_new(void)
16940 {
16941     static int ctx;  /* wolfcrypt doesn't now need ctx */
16942 
16943     WOLFSSL_MSG("wolfSSL_BN_CTX_new");
16944 
16945     return (WOLFSSL_BN_CTX*)&ctx;
16946 }
16947 
16948 void wolfSSL_BN_CTX_init(WOLFSSL_BN_CTX* ctx)
16949 {
16950     (void)ctx;
16951     WOLFSSL_MSG("wolfSSL_BN_CTX_init");
16952 }
16953 
16954 
16955 void wolfSSL_BN_CTX_free(WOLFSSL_BN_CTX* ctx)
16956 {
16957     (void)ctx;
16958     WOLFSSL_MSG("wolfSSL_BN_CTX_free");
16959 
16960     /* do free since static ctx that does nothing */
16961 }
16962 
16963 
16964 static void InitwolfSSL_BigNum(WOLFSSL_BIGNUM* bn)
16965 {
16966     WOLFSSL_MSG("InitwolfSSL_BigNum");
16967     if (bn) {
16968         bn->neg      = 0;
16969         bn->internal = NULL;
16970     }
16971 }
16972 
16973 
16974 WOLFSSL_BIGNUM* wolfSSL_BN_new(void)
16975 {
16976     WOLFSSL_BIGNUM* external;
16977     mp_int*        mpi;
16978 
16979     WOLFSSL_MSG("wolfSSL_BN_new");
16980 
16981     mpi = (mp_int*) XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
16982     if (mpi == NULL) {
16983         WOLFSSL_MSG("wolfSSL_BN_new malloc mpi failure");
16984         return NULL;
16985     }
16986 
16987     external = (WOLFSSL_BIGNUM*) XMALLOC(sizeof(WOLFSSL_BIGNUM), NULL,
16988                                         DYNAMIC_TYPE_BIGINT);
16989     if (external == NULL) {
16990         WOLFSSL_MSG("wolfSSL_BN_new malloc WOLFSSL_BIGNUM failure");
16991         XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
16992         return NULL;
16993     }
16994 
16995     InitwolfSSL_BigNum(external);
16996     external->internal = mpi;
16997     if (mp_init(mpi) != MP_OKAY) {
16998         wolfSSL_BN_free(external);
16999         return NULL;
17000     }
17001 
17002     return external;
17003 }
17004 
17005 
17006 void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn)
17007 {
17008     WOLFSSL_MSG("wolfSSL_BN_free");
17009     if (bn) {
17010         if (bn->internal) {
17011             mp_forcezero((mp_int*)bn->internal);
17012             XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT);
17013             bn->internal = NULL;
17014         }
17015         XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT);
17016         bn = NULL;
17017     }
17018 }
17019 
17020 
17021 void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM* bn)
17022 {
17023     WOLFSSL_MSG("wolfSSL_BN_clear_free");
17024 
17025     wolfSSL_BN_free(bn);
17026 }
17027 
17028 
17029 /* SSL_SUCCESS on ok */
17030 int wolfSSL_BN_sub(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
17031                   const WOLFSSL_BIGNUM* b)
17032 {
17033     WOLFSSL_MSG("wolfSSL_BN_sub");
17034 
17035     if (r == NULL || a == NULL || b == NULL)
17036         return 0;
17037 
17038     if (mp_sub((mp_int*)a->internal,(mp_int*)b->internal,
17039                (mp_int*)r->internal) == MP_OKAY)
17040         return SSL_SUCCESS;
17041 
17042     WOLFSSL_MSG("wolfSSL_BN_sub mp_sub failed");
17043     return 0;
17044 }
17045 
17046 
17047 /* SSL_SUCCESS on ok */
17048 int wolfSSL_BN_mod(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
17049                   const WOLFSSL_BIGNUM* b, const WOLFSSL_BN_CTX* c)
17050 {
17051     (void)c;
17052     WOLFSSL_MSG("wolfSSL_BN_mod");
17053 
17054     if (r == NULL || a == NULL || b == NULL)
17055         return 0;
17056 
17057     if (mp_mod((mp_int*)a->internal,(mp_int*)b->internal,
17058                (mp_int*)r->internal) == MP_OKAY)
17059         return SSL_SUCCESS;
17060 
17061     WOLFSSL_MSG("wolfSSL_BN_mod mp_mod failed");
17062     return 0;
17063 }
17064 
17065 
17066 /* r = (a^p) % m */
17067 int wolfSSL_BN_mod_exp(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
17068       const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
17069 {
17070     int ret;
17071 
17072     WOLFSSL_ENTER("wolfSSL_BN_mod_exp");
17073 
17074     (void) ctx;
17075     if (r == NULL || a == NULL || p == NULL || m == NULL) {
17076         WOLFSSL_MSG("Bad Argument");
17077         return SSL_FAILURE;
17078     }
17079 
17080     if ((ret = mp_exptmod((mp_int*)a->internal,(mp_int*)p->internal,
17081                (mp_int*)m->internal, (mp_int*)r->internal)) == MP_OKAY) {
17082         return SSL_SUCCESS;
17083     }
17084 
17085     WOLFSSL_LEAVE("wolfSSL_BN_mod_exp", ret);
17086     (void)ret;
17087 
17088     return SSL_FAILURE;
17089 }
17090 
17091 const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void)
17092 {
17093     static WOLFSSL_BIGNUM* bn_one = NULL;
17094 
17095     WOLFSSL_MSG("wolfSSL_BN_value_one");
17096 
17097     if (bn_one == NULL) {
17098         bn_one = wolfSSL_BN_new();
17099         if (bn_one) {
17100             if (mp_set_int((mp_int*)bn_one->internal, 1) != MP_OKAY) {
17101                 /* handle error by freeing BN and returning NULL */
17102                 wolfSSL_BN_free(bn_one);
17103                 bn_one = NULL;
17104             }
17105         }
17106     }
17107 
17108     return bn_one;
17109 }
17110 
17111 /* return compliant with OpenSSL
17112  *   size of BIGNUM in bytes, 0 if error */
17113 int wolfSSL_BN_num_bytes(const WOLFSSL_BIGNUM* bn)
17114 {
17115     WOLFSSL_MSG("wolfSSL_BN_num_bytes");
17116 
17117     if (bn == NULL || bn->internal == NULL)
17118         return SSL_FAILURE;
17119 
17120     return mp_unsigned_bin_size((mp_int*)bn->internal);
17121 }
17122 
17123 /* return compliant with OpenSSL
17124  *   size of BIGNUM in bits, 0 if error */
17125 int wolfSSL_BN_num_bits(const WOLFSSL_BIGNUM* bn)
17126 {
17127     WOLFSSL_MSG("wolfSSL_BN_num_bits");
17128 
17129     if (bn == NULL || bn->internal == NULL)
17130         return SSL_FAILURE;
17131 
17132     return mp_count_bits((mp_int*)bn->internal);
17133 }
17134 
17135 /* return compliant with OpenSSL
17136  *   1 if BIGNUM is zero, 0 else */
17137 int wolfSSL_BN_is_zero(const WOLFSSL_BIGNUM* bn)
17138 {
17139     WOLFSSL_MSG("wolfSSL_BN_is_zero");
17140 
17141     if (bn == NULL || bn->internal == NULL)
17142         return SSL_FAILURE;
17143 
17144     if (mp_iszero((mp_int*)bn->internal) == MP_YES)
17145         return SSL_SUCCESS;
17146 
17147     return SSL_FAILURE;
17148 }
17149 
17150 /* return compliant with OpenSSL
17151  *   1 if BIGNUM is one, 0 else */
17152 int wolfSSL_BN_is_one(const WOLFSSL_BIGNUM* bn)
17153 {
17154     WOLFSSL_MSG("wolfSSL_BN_is_one");
17155 
17156     if (bn == NULL || bn->internal == NULL)
17157         return SSL_FAILURE;
17158 
17159     if (mp_cmp_d((mp_int*)bn->internal, 1) == MP_EQ)
17160         return SSL_SUCCESS;
17161 
17162     return SSL_FAILURE;
17163 }
17164 
17165 /* return compliant with OpenSSL
17166  *   1 if BIGNUM is odd, 0 else */
17167 int wolfSSL_BN_is_odd(const WOLFSSL_BIGNUM* bn)
17168 {
17169     WOLFSSL_MSG("wolfSSL_BN_is_odd");
17170 
17171     if (bn == NULL || bn->internal == NULL)
17172         return SSL_FAILURE;
17173 
17174     if (mp_isodd((mp_int*)bn->internal) == MP_YES)
17175         return SSL_SUCCESS;
17176 
17177     return SSL_FAILURE;
17178 }
17179 
17180 /* return compliant with OpenSSL
17181  *   -1 if a < b, 0 if a == b and 1 if a > b
17182  */
17183 int wolfSSL_BN_cmp(const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b)
17184 {
17185     int ret;
17186 
17187     WOLFSSL_MSG("wolfSSL_BN_cmp");
17188 
17189     if (a == NULL || a->internal == NULL || b == NULL || b->internal == NULL)
17190         return SSL_FATAL_ERROR;
17191 
17192     ret = mp_cmp((mp_int*)a->internal, (mp_int*)b->internal);
17193 
17194     return (ret == MP_EQ ? 0 : (ret == MP_GT ? 1 : -1));
17195 }
17196 
17197 /* return compliant with OpenSSL
17198  *   length of BIGNUM in bytes, -1 if error */
17199 int wolfSSL_BN_bn2bin(const WOLFSSL_BIGNUM* bn, unsigned char* r)
17200 {
17201     WOLFSSL_MSG("wolfSSL_BN_bn2bin");
17202 
17203     if (bn == NULL || bn->internal == NULL) {
17204         WOLFSSL_MSG("NULL bn error");
17205         return SSL_FATAL_ERROR;
17206     }
17207 
17208     if (r == NULL)
17209         return mp_unsigned_bin_size((mp_int*)bn->internal);
17210 
17211     if (mp_to_unsigned_bin((mp_int*)bn->internal, r) != MP_OKAY) {
17212         WOLFSSL_MSG("mp_to_unsigned_bin error");
17213         return SSL_FATAL_ERROR;
17214     }
17215 
17216     return mp_unsigned_bin_size((mp_int*)bn->internal);
17217 }
17218 
17219 
17220 WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char* str, int len,
17221                             WOLFSSL_BIGNUM* ret)
17222 {
17223     int weOwn = 0;
17224 
17225     WOLFSSL_MSG("wolfSSL_BN_bin2bn");
17226 
17227     /* if ret is null create a BN */
17228     if (ret == NULL) {
17229         ret = wolfSSL_BN_new();
17230         weOwn = 1;
17231         if (ret == NULL)
17232             return NULL;
17233     }
17234 
17235     /* check ret and ret->internal then read in value */
17236     if (ret && ret->internal) {
17237         if (mp_read_unsigned_bin((mp_int*)ret->internal, str, len) != 0) {
17238             WOLFSSL_MSG("mp_read_unsigned_bin failure");
17239             if (weOwn)
17240                 wolfSSL_BN_free(ret);
17241             return NULL;
17242         }
17243     }
17244 
17245     return ret;
17246 }
17247 
17248 /* return compliant with OpenSSL
17249  *   1 if success, 0 if error */
17250 int wolfSSL_mask_bits(WOLFSSL_BIGNUM* bn, int n)
17251 {
17252     (void)bn;
17253     (void)n;
17254     WOLFSSL_MSG("wolfSSL_BN_mask_bits");
17255 
17256     return SSL_FAILURE;
17257 }
17258 
17259 
17260 /* SSL_SUCCESS on ok */
17261 int wolfSSL_BN_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
17262 {
17263     int           ret    = 0;
17264     int           len    = bits / 8;
17265     int           initTmpRng = 0;
17266     WC_RNG*       rng    = NULL;
17267 #ifdef WOLFSSL_SMALL_STACK
17268     WC_RNG*       tmpRNG = NULL;
17269     byte*         buff   = NULL;
17270 #else
17271     WC_RNG        tmpRNG[1];
17272     byte          buff[1024];
17273 #endif
17274 
17275     (void)top;
17276     (void)bottom;
17277     WOLFSSL_MSG("wolfSSL_BN_rand");
17278 
17279     if (bits % 8)
17280         len++;
17281 
17282 #ifdef WOLFSSL_SMALL_STACK
17283     buff   = (byte*)XMALLOC(1024,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
17284     tmpRNG = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
17285     if (buff == NULL || tmpRNG == NULL) {
17286         XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
17287         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17288         return ret;
17289     }
17290 #endif
17291 
17292     if (bn == NULL || bn->internal == NULL)
17293         WOLFSSL_MSG("Bad function arguments");
17294     else if (wc_InitRng(tmpRNG) == 0) {
17295         rng = tmpRNG;
17296         initTmpRng = 1;
17297     }
17298     else if (initGlobalRNG)
17299         rng = &globalRNG;
17300 
17301     if (rng) {
17302         if (wc_RNG_GenerateBlock(rng, buff, len) != 0)
17303             WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
17304         else {
17305             buff[0]     |= 0x80 | 0x40;
17306             buff[len-1] |= 0x01;
17307 
17308             if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY)
17309                 WOLFSSL_MSG("mp read bin failed");
17310             else
17311                 ret = SSL_SUCCESS;
17312         }
17313     }
17314 
17315     if (initTmpRng)
17316         wc_FreeRng(tmpRNG);
17317 
17318 #ifdef WOLFSSL_SMALL_STACK
17319     XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
17320     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17321 #endif
17322 
17323     return ret;
17324 }
17325 
17326 /* return code compliant with OpenSSL :
17327  *   1 if bit set, 0 else
17328  */
17329 int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM* bn, int n)
17330 {
17331     if (bn == NULL || bn->internal == NULL) {
17332         WOLFSSL_MSG("bn NULL error");
17333         return SSL_FAILURE;
17334     }
17335 
17336     if (n > DIGIT_BIT) {
17337         WOLFSSL_MSG("input bit count too large");
17338         return SSL_FAILURE;
17339     }
17340 
17341     return mp_is_bit_set((mp_int*)bn->internal, (mp_digit)n);
17342 }
17343 
17344 /* return code compliant with OpenSSL :
17345  *   1 if success, 0 else
17346  */
17347 int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n)
17348 {
17349     if (bn == NULL || bn->internal == NULL) {
17350         WOLFSSL_MSG("bn NULL error");
17351         return SSL_FAILURE;
17352     }
17353 
17354     if (mp_set_bit((mp_int*)bn->internal, n) != MP_OKAY) {
17355         WOLFSSL_MSG("mp_set_int error");
17356         return SSL_FAILURE;
17357     }
17358 
17359     return SSL_SUCCESS;
17360 }
17361 
17362 
17363 /* SSL_SUCCESS on ok */
17364 int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str)
17365 {
17366     int     ret     = 0;
17367     word32  decSz   = 1024;
17368 #ifdef WOLFSSL_SMALL_STACK
17369     byte*   decoded = NULL;
17370 #else
17371     byte    decoded[1024];
17372 #endif
17373 
17374     WOLFSSL_MSG("wolfSSL_BN_hex2bn");
17375 
17376 #ifdef WOLFSSL_SMALL_STACK
17377     decoded = (byte*)XMALLOC(decSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17378     if (decoded == NULL)
17379         return ret;
17380 #endif
17381 
17382     if (str == NULL)
17383         WOLFSSL_MSG("Bad function argument");
17384     else if (Base16_Decode((byte*)str, (int)XSTRLEN(str), decoded, &decSz) < 0)
17385         WOLFSSL_MSG("Bad Base16_Decode error");
17386     else if (bn == NULL)
17387         ret = decSz;
17388     else {
17389         if (*bn == NULL)
17390             *bn = wolfSSL_BN_new();
17391 
17392         if (*bn == NULL)
17393             WOLFSSL_MSG("BN new failed");
17394         else if (wolfSSL_BN_bin2bn(decoded, decSz, *bn) == NULL)
17395             WOLFSSL_MSG("Bad bin2bn error");
17396         else
17397             ret = SSL_SUCCESS;
17398     }
17399 
17400 #ifdef WOLFSSL_SMALL_STACK
17401     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17402 #endif
17403 
17404     return ret;
17405 }
17406 
17407 
17408 WOLFSSL_BIGNUM* wolfSSL_BN_dup(const WOLFSSL_BIGNUM* bn)
17409 {
17410     WOLFSSL_BIGNUM* ret;
17411 
17412     WOLFSSL_MSG("wolfSSL_BN_dup");
17413 
17414     if (bn == NULL || bn->internal == NULL) {
17415         WOLFSSL_MSG("bn NULL error");
17416         return NULL;
17417     }
17418 
17419     ret = wolfSSL_BN_new();
17420     if (ret == NULL) {
17421         WOLFSSL_MSG("bn new error");
17422         return NULL;
17423     }
17424 
17425     if (mp_copy((mp_int*)bn->internal, (mp_int*)ret->internal) != MP_OKAY) {
17426         WOLFSSL_MSG("mp_copy error");
17427         wolfSSL_BN_free(ret);
17428         return NULL;
17429     }
17430 
17431     ret->neg = bn->neg;
17432 
17433     return ret;
17434 }
17435 
17436 
17437 WOLFSSL_BIGNUM* wolfSSL_BN_copy(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* bn)
17438 {
17439     WOLFSSL_MSG("wolfSSL_BN_copy");
17440 
17441     if (mp_copy((mp_int*)bn->internal, (mp_int*)r->internal) != MP_OKAY) {
17442         WOLFSSL_MSG("mp_copy error");
17443         return NULL;
17444     }
17445 
17446     r->neg = bn->neg;
17447 
17448     return r;
17449 }
17450 
17451 /* return code compliant with OpenSSL :
17452  *   1 if success, 0 else
17453  */
17454 int wolfSSL_BN_set_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
17455 {
17456     WOLFSSL_MSG("wolfSSL_BN_set_word");
17457 
17458     if (mp_set_int((mp_int*)bn->internal, w) != MP_OKAY) {
17459         WOLFSSL_MSG("mp_init_set_int error");
17460         return SSL_FAILURE;
17461     }
17462 
17463     return SSL_SUCCESS;
17464 }
17465 
17466 /* return code compliant with OpenSSL :
17467  *   number length in decimal if success, 0 if error
17468  */
17469 int wolfSSL_BN_dec2bn(WOLFSSL_BIGNUM** bn, const char* str)
17470 {
17471     (void)bn;
17472     (void)str;
17473 
17474     WOLFSSL_MSG("wolfSSL_BN_dec2bn");
17475 
17476     return SSL_FAILURE;
17477 }
17478 
17479 
17480 #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
17481 char *wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM *bn)
17482 {
17483     int len = 0;
17484     char *buf;
17485 
17486     WOLFSSL_MSG("wolfSSL_BN_bn2dec");
17487 
17488     if (bn == NULL || bn->internal == NULL) {
17489         WOLFSSL_MSG("bn NULL error");
17490         return NULL;
17491     }
17492 
17493     if (mp_radix_size((mp_int*)bn->internal, 10, &len) != MP_OKAY) {
17494         WOLFSSL_MSG("mp_radix_size failure");
17495         return NULL;
17496     }
17497 
17498     buf = (char*) XMALLOC(len, NULL, DYNAMIC_TYPE_ECC);
17499     if (buf == NULL) {
17500         WOLFSSL_MSG("wolfSSL_BN_bn2hex malloc buffer failure");
17501         return NULL;
17502     }
17503 
17504     if (mp_toradix((mp_int*)bn->internal, buf, 10) != MP_OKAY) {
17505         XFREE(buf, NULL, DYNAMIC_TYPE_ECC);
17506         return NULL;
17507     }
17508 
17509     return buf;
17510 }
17511 #else
17512 char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM* bn)
17513 {
17514     (void)bn;
17515 
17516     WOLFSSL_MSG("wolfSSL_BN_bn2dec");
17517 
17518     return NULL;
17519 }
17520 #endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
17521 
17522 /* return code compliant with OpenSSL :
17523  *   1 if success, 0 else
17524  */
17525 int wolfSSL_BN_lshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
17526 {
17527     WOLFSSL_MSG("wolfSSL_BN_lshift");
17528 
17529     if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
17530         WOLFSSL_MSG("bn NULL error");
17531         return SSL_FAILURE;
17532     }
17533 
17534     if (mp_mul_2d((mp_int*)bn->internal, n, (mp_int*)r->internal) != MP_OKAY) {
17535         WOLFSSL_MSG("mp_mul_2d error");
17536         return SSL_FAILURE;
17537     }
17538 
17539     return SSL_SUCCESS;
17540 }
17541 
17542 /* return code compliant with OpenSSL :
17543  *   1 if success, 0 else
17544  */
17545 int wolfSSL_BN_rshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
17546 {
17547     WOLFSSL_MSG("wolfSSL_BN_rshift");
17548 
17549     if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
17550         WOLFSSL_MSG("bn NULL error");
17551         return SSL_FAILURE;
17552     }
17553 
17554     if (mp_div_2d((mp_int*)bn->internal, n,
17555                   (mp_int*)r->internal, NULL) != MP_OKAY) {
17556         WOLFSSL_MSG("mp_mul_2d error");
17557         return SSL_FAILURE;
17558     }
17559 
17560     return SSL_SUCCESS;
17561 }
17562 
17563 /* return code compliant with OpenSSL :
17564  *   1 if success, 0 else
17565  */
17566 int wolfSSL_BN_add_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w)
17567 {
17568     WOLFSSL_MSG("wolfSSL_BN_add_word");
17569 
17570     if (bn == NULL || bn->internal == NULL) {
17571         WOLFSSL_MSG("bn NULL error");
17572         return SSL_FAILURE;
17573     }
17574 
17575     if (mp_add_d((mp_int*)bn->internal, w, (mp_int*)bn->internal) != MP_OKAY) {
17576         WOLFSSL_MSG("mp_add_d error");
17577         return SSL_FAILURE;
17578     }
17579 
17580     return SSL_SUCCESS;
17581 }
17582 
17583 /* return code compliant with OpenSSL :
17584  *   1 if success, 0 else
17585  */
17586 int wolfSSL_BN_add(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a, WOLFSSL_BIGNUM *b)
17587 {
17588     WOLFSSL_MSG("wolfSSL_BN_add");
17589 
17590     if (r == NULL || r->internal == NULL || a == NULL || a->internal == NULL ||
17591         b == NULL || b->internal == NULL) {
17592         WOLFSSL_MSG("bn NULL error");
17593         return SSL_FAILURE;
17594     }
17595 
17596     if (mp_add((mp_int*)a->internal, (mp_int*)b->internal,
17597                (mp_int*)r->internal) != MP_OKAY) {
17598         WOLFSSL_MSG("mp_add_d error");
17599         return SSL_FAILURE;
17600     }
17601 
17602     return SSL_SUCCESS;
17603 }
17604 
17605 #ifdef WOLFSSL_KEY_GEN
17606 
17607 /* return code compliant with OpenSSL :
17608  *   1 if prime, 0 if not, -1 if error
17609  */
17610 int wolfSSL_BN_is_prime_ex(const WOLFSSL_BIGNUM *bn, int nbchecks,
17611                            WOLFSSL_BN_CTX *ctx, WOLFSSL_BN_GENCB *cb)
17612 {
17613     int res;
17614 
17615     (void)ctx;
17616     (void)cb;
17617 
17618     WOLFSSL_MSG("wolfSSL_BN_is_prime_ex");
17619 
17620     if (bn == NULL || bn->internal == NULL) {
17621         WOLFSSL_MSG("bn NULL error");
17622         return SSL_FATAL_ERROR;
17623     }
17624 
17625     if (mp_prime_is_prime((mp_int*)bn->internal, nbchecks, &res) != MP_OKAY) {
17626         WOLFSSL_MSG("mp_prime_is_prime error");
17627         return SSL_FATAL_ERROR;
17628     }
17629 
17630     if (res != MP_YES) {
17631         WOLFSSL_MSG("mp_prime_is_prime not prime");
17632         return SSL_FAILURE;
17633     }
17634 
17635     return SSL_SUCCESS;
17636 }
17637 
17638 /* return code compliant with OpenSSL :
17639  *   (bn mod w) if success, -1 if error
17640  */
17641 WOLFSSL_BN_ULONG wolfSSL_BN_mod_word(const WOLFSSL_BIGNUM *bn,
17642                                      WOLFSSL_BN_ULONG w)
17643 {
17644     WOLFSSL_BN_ULONG ret = 0;
17645 
17646     WOLFSSL_MSG("wolfSSL_BN_mod_word");
17647 
17648     if (bn == NULL || bn->internal == NULL) {
17649         WOLFSSL_MSG("bn NULL error");
17650         return (WOLFSSL_BN_ULONG)SSL_FATAL_ERROR;
17651     }
17652 
17653     if (mp_mod_d((mp_int*)bn->internal, w, &ret) != MP_OKAY) {
17654         WOLFSSL_MSG("mp_add_d error");
17655         return (WOLFSSL_BN_ULONG)SSL_FATAL_ERROR;
17656     }
17657 
17658     return ret;
17659 }
17660 #endif /* #ifdef WOLFSSL_KEY_GEN */
17661 
17662 #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
17663 char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM *bn)
17664 {
17665     int len = 0;
17666     char *buf;
17667 
17668     WOLFSSL_MSG("wolfSSL_BN_bn2hex");
17669 
17670     if (bn == NULL || bn->internal == NULL) {
17671         WOLFSSL_MSG("bn NULL error");
17672         return NULL;
17673     }
17674 
17675     if (mp_radix_size((mp_int*)bn->internal, 16, &len) != MP_OKAY) {
17676         WOLFSSL_MSG("mp_radix_size failure");
17677         return NULL;
17678     }
17679 
17680     buf = (char*) XMALLOC(len, NULL, DYNAMIC_TYPE_ECC);
17681     if (buf == NULL) {
17682         WOLFSSL_MSG("wolfSSL_BN_bn2hex malloc buffer failure");
17683         return NULL;
17684     }
17685 
17686     if (mp_toradix((mp_int*)bn->internal, buf, 16) != MP_OKAY) {
17687         XFREE(buf, NULL, DYNAMIC_TYPE_ECC);
17688         return NULL;
17689     }
17690 
17691     return buf;
17692 }
17693 
17694 #ifndef NO_FILESYSTEM
17695 /* return code compliant with OpenSSL :
17696  *   1 if success, 0 if error
17697  */
17698 int wolfSSL_BN_print_fp(FILE *fp, const WOLFSSL_BIGNUM *bn)
17699 {
17700     char *buf;
17701 
17702     WOLFSSL_MSG("wolfSSL_BN_print_fp");
17703 
17704     if (fp == NULL || bn == NULL || bn->internal == NULL) {
17705         WOLFSSL_MSG("bn NULL error");
17706         return SSL_FAILURE;
17707     }
17708 
17709     buf = wolfSSL_BN_bn2hex(bn);
17710     if (buf == NULL) {
17711         WOLFSSL_MSG("wolfSSL_BN_bn2hex failure");
17712         return SSL_FAILURE;
17713     }
17714 
17715     fprintf(fp, "%s", buf);
17716     XFREE(buf, NULL, DYNAMIC_TYPE_ECC);
17717 
17718     return SSL_SUCCESS;
17719 }
17720 #endif /* !defined(NO_FILESYSTEM) */
17721 
17722 #else /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
17723 
17724 char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM *bn)
17725 {
17726     (void)bn;
17727 
17728     WOLFSSL_MSG("wolfSSL_BN_bn2hex need WOLFSSL_KEY_GEN or HAVE_COMP_KEY");
17729 
17730     return (char*)"";
17731 }
17732 
17733 #ifndef NO_FILESYSTEM
17734 /* return code compliant with OpenSSL :
17735  *   1 if success, 0 if error
17736  */
17737 int wolfSSL_BN_print_fp(FILE *fp, const WOLFSSL_BIGNUM *bn)
17738 {
17739     (void)fp;
17740     (void)bn;
17741 
17742     WOLFSSL_MSG("wolfSSL_BN_print_fp not implemented");
17743 
17744     return SSL_SUCCESS;
17745 }
17746 #endif /* !defined(NO_FILESYSTEM) */
17747 
17748 #endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
17749 
17750 WOLFSSL_BIGNUM *wolfSSL_BN_CTX_get(WOLFSSL_BN_CTX *ctx)
17751 {
17752     /* ctx is not used, return new Bignum */
17753     (void)ctx;
17754 
17755     WOLFSSL_ENTER("wolfSSL_BN_CTX_get");
17756 
17757     return wolfSSL_BN_new();
17758 }
17759 
17760 void wolfSSL_BN_CTX_start(WOLFSSL_BN_CTX *ctx)
17761 {
17762     (void)ctx;
17763 
17764     WOLFSSL_ENTER("wolfSSL_BN_CTX_start");
17765     WOLFSSL_MSG("wolfSSL_BN_CTX_start TBD");
17766 }
17767 
17768 #ifndef NO_DH
17769 
17770 static void InitwolfSSL_DH(WOLFSSL_DH* dh)
17771 {
17772     if (dh) {
17773         dh->p        = NULL;
17774         dh->g        = NULL;
17775         dh->q        = NULL;
17776         dh->pub_key  = NULL;
17777         dh->priv_key = NULL;
17778         dh->internal = NULL;
17779         dh->inSet    = 0;
17780         dh->exSet    = 0;
17781     }
17782 }
17783 
17784 
17785 WOLFSSL_DH* wolfSSL_DH_new(void)
17786 {
17787     WOLFSSL_DH* external;
17788     DhKey*     key;
17789 
17790     WOLFSSL_MSG("wolfSSL_DH_new");
17791 
17792     key = (DhKey*) XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
17793     if (key == NULL) {
17794         WOLFSSL_MSG("wolfSSL_DH_new malloc DhKey failure");
17795         return NULL;
17796     }
17797 
17798     external = (WOLFSSL_DH*) XMALLOC(sizeof(WOLFSSL_DH), NULL,
17799                                     DYNAMIC_TYPE_DH);
17800     if (external == NULL) {
17801         WOLFSSL_MSG("wolfSSL_DH_new malloc WOLFSSL_DH failure");
17802         XFREE(key, NULL, DYNAMIC_TYPE_DH);
17803         return NULL;
17804     }
17805 
17806     InitwolfSSL_DH(external);
17807     if (wc_InitDhKey(key) != 0) {
17808         WOLFSSL_MSG("wolfSSL_DH_new InitDhKey failure");
17809         XFREE(key, NULL, DYNAMIC_TYPE_DH);
17810         XFREE(external, NULL, DYNAMIC_TYPE_DH);
17811         return NULL;
17812     }
17813     external->internal = key;
17814 
17815     return external;
17816 }
17817 
17818 
17819 void wolfSSL_DH_free(WOLFSSL_DH* dh)
17820 {
17821     WOLFSSL_MSG("wolfSSL_DH_free");
17822 
17823     if (dh) {
17824         if (dh->internal) {
17825             wc_FreeDhKey((DhKey*)dh->internal);
17826             XFREE(dh->internal, NULL, DYNAMIC_TYPE_DH);
17827             dh->internal = NULL;
17828         }
17829         wolfSSL_BN_free(dh->priv_key);
17830         wolfSSL_BN_free(dh->pub_key);
17831         wolfSSL_BN_free(dh->g);
17832         wolfSSL_BN_free(dh->p);
17833         wolfSSL_BN_free(dh->q);
17834         InitwolfSSL_DH(dh);  /* set back to NULLs for safety */
17835 
17836         XFREE(dh, NULL, DYNAMIC_TYPE_DH);
17837     }
17838 }
17839 
17840 
17841 static int SetDhInternal(WOLFSSL_DH* dh)
17842 {
17843     int            ret = SSL_FATAL_ERROR;
17844     int            pSz = 1024;
17845     int            gSz = 1024;
17846 #ifdef WOLFSSL_SMALL_STACK
17847     unsigned char* p   = NULL;
17848     unsigned char* g   = NULL;
17849 #else
17850     unsigned char  p[1024];
17851     unsigned char  g[1024];
17852 #endif
17853 
17854     WOLFSSL_ENTER("SetDhInternal");
17855 
17856     if (dh == NULL || dh->p == NULL || dh->g == NULL)
17857         WOLFSSL_MSG("Bad function arguments");
17858     else if (wolfSSL_BN_bn2bin(dh->p, NULL) > pSz)
17859         WOLFSSL_MSG("Bad p internal size");
17860     else if (wolfSSL_BN_bn2bin(dh->g, NULL) > gSz)
17861         WOLFSSL_MSG("Bad g internal size");
17862     else {
17863     #ifdef WOLFSSL_SMALL_STACK
17864         p = (unsigned char*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17865         g = (unsigned char*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17866 
17867         if (p == NULL || g == NULL) {
17868             XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17869             XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17870             return ret;
17871         }
17872     #endif
17873 
17874         pSz = wolfSSL_BN_bn2bin(dh->p, p);
17875         gSz = wolfSSL_BN_bn2bin(dh->g, g);
17876 
17877         if (pSz <= 0 || gSz <= 0)
17878             WOLFSSL_MSG("Bad BN2bin set");
17879         else if (wc_DhSetKey((DhKey*)dh->internal, p, pSz, g, gSz) < 0)
17880             WOLFSSL_MSG("Bad DH SetKey");
17881         else {
17882             dh->inSet = 1;
17883             ret = SSL_SUCCESS;
17884         }
17885 
17886     #ifdef WOLFSSL_SMALL_STACK
17887         XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17888         XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17889     #endif
17890     }
17891 
17892 
17893     return ret;
17894 }
17895 
17896 /* return code compliant with OpenSSL :
17897  *   DH prime size in bytes if success, 0 if error
17898  */
17899 int wolfSSL_DH_size(WOLFSSL_DH* dh)
17900 {
17901     WOLFSSL_MSG("wolfSSL_DH_size");
17902 
17903     if (dh == NULL)
17904         return SSL_FATAL_ERROR;
17905 
17906     return wolfSSL_BN_num_bytes(dh->p);
17907 }
17908 
17909 
17910 /* return code compliant with OpenSSL :
17911  *   1 if success, 0 if error
17912  */
17913 int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
17914 {
17915     int            ret    = SSL_FAILURE;
17916     word32         pubSz  = 768;
17917     word32         privSz = 768;
17918     int            initTmpRng = 0;
17919     WC_RNG*        rng    = NULL;
17920 #ifdef WOLFSSL_SMALL_STACK
17921     unsigned char* pub    = NULL;
17922     unsigned char* priv   = NULL;
17923     WC_RNG*        tmpRNG = NULL;
17924 #else
17925     unsigned char  pub [768];
17926     unsigned char  priv[768];
17927     WC_RNG         tmpRNG[1];
17928 #endif
17929 
17930     WOLFSSL_MSG("wolfSSL_DH_generate_key");
17931 
17932 #ifdef WOLFSSL_SMALL_STACK
17933     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
17934     pub    = (unsigned char*)XMALLOC(pubSz,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
17935     priv   = (unsigned char*)XMALLOC(privSz,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
17936 
17937     if (tmpRNG == NULL || pub == NULL || priv == NULL) {
17938         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17939         XFREE(pub,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
17940         XFREE(priv,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
17941         return ret;
17942     }
17943 #endif
17944 
17945     if (dh == NULL || dh->p == NULL || dh->g == NULL)
17946         WOLFSSL_MSG("Bad function arguments");
17947     else if (dh->inSet == 0 && SetDhInternal(dh) != SSL_SUCCESS)
17948             WOLFSSL_MSG("Bad DH set internal");
17949     else if (wc_InitRng(tmpRNG) == 0) {
17950         rng = tmpRNG;
17951         initTmpRng = 1;
17952     }
17953     else {
17954         WOLFSSL_MSG("Bad RNG Init, trying global");
17955         if (initGlobalRNG == 0)
17956             WOLFSSL_MSG("Global RNG no Init");
17957         else
17958             rng = &globalRNG;
17959     }
17960 
17961     if (rng) {
17962        if (wc_DhGenerateKeyPair((DhKey*)dh->internal, rng, priv, &privSz,
17963                                                                pub, &pubSz) < 0)
17964             WOLFSSL_MSG("Bad wc_DhGenerateKeyPair");
17965        else {
17966             if (dh->pub_key)
17967                 wolfSSL_BN_free(dh->pub_key);
17968 
17969             dh->pub_key = wolfSSL_BN_new();
17970             if (dh->pub_key == NULL) {
17971                 WOLFSSL_MSG("Bad DH new pub");
17972             }
17973             if (dh->priv_key)
17974                 wolfSSL_BN_free(dh->priv_key);
17975 
17976             dh->priv_key = wolfSSL_BN_new();
17977 
17978             if (dh->priv_key == NULL) {
17979                 WOLFSSL_MSG("Bad DH new priv");
17980             }
17981 
17982             if (dh->pub_key && dh->priv_key) {
17983                if (wolfSSL_BN_bin2bn(pub, pubSz, dh->pub_key) == NULL)
17984                    WOLFSSL_MSG("Bad DH bn2bin error pub");
17985                else if (wolfSSL_BN_bin2bn(priv, privSz, dh->priv_key) == NULL)
17986                    WOLFSSL_MSG("Bad DH bn2bin error priv");
17987                else
17988                    ret = SSL_SUCCESS;
17989             }
17990         }
17991     }
17992 
17993     if (initTmpRng)
17994         wc_FreeRng(tmpRNG);
17995 
17996 #ifdef WOLFSSL_SMALL_STACK
17997     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17998     XFREE(pub,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
17999     XFREE(priv,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
18000 #endif
18001 
18002     return ret;
18003 }
18004 
18005 
18006 /* return code compliant with OpenSSL :
18007  *   size of shared secret if success, -1 if error
18008  */
18009 int wolfSSL_DH_compute_key(unsigned char* key, WOLFSSL_BIGNUM* otherPub,
18010                           WOLFSSL_DH* dh)
18011 {
18012     int            ret    = SSL_FATAL_ERROR;
18013     word32         keySz  = 0;
18014     word32         pubSz  = 1024;
18015     word32         privSz = 1024;
18016 #ifdef WOLFSSL_SMALL_STACK
18017     unsigned char* pub    = NULL;
18018     unsigned char* priv   = NULL;
18019 #else
18020     unsigned char  pub [1024];
18021     unsigned char  priv[1024];
18022 #endif
18023 
18024     WOLFSSL_MSG("wolfSSL_DH_compute_key");
18025 
18026 #ifdef WOLFSSL_SMALL_STACK
18027     pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18028     if (pub == NULL)
18029         return ret;
18030 
18031     priv = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18032     if (priv == NULL) {
18033         XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18034         return ret;
18035     }
18036 #endif
18037 
18038     if (dh == NULL || dh->priv_key == NULL || otherPub == NULL)
18039         WOLFSSL_MSG("Bad function arguments");
18040     else if ((keySz = (word32)DH_size(dh)) == 0)
18041         WOLFSSL_MSG("Bad DH_size");
18042     else if (wolfSSL_BN_bn2bin(dh->priv_key, NULL) > (int)privSz)
18043         WOLFSSL_MSG("Bad priv internal size");
18044     else if (wolfSSL_BN_bn2bin(otherPub, NULL) > (int)pubSz)
18045         WOLFSSL_MSG("Bad otherPub size");
18046     else {
18047         privSz = wolfSSL_BN_bn2bin(dh->priv_key, priv);
18048         pubSz  = wolfSSL_BN_bn2bin(otherPub, pub);
18049 
18050         if (privSz <= 0 || pubSz <= 0)
18051             WOLFSSL_MSG("Bad BN2bin set");
18052         else if (wc_DhAgree((DhKey*)dh->internal, key, &keySz,
18053                             priv, privSz, pub, pubSz) < 0)
18054             WOLFSSL_MSG("wc_DhAgree failed");
18055         else
18056             ret = (int)keySz;
18057     }
18058 
18059 #ifdef WOLFSSL_SMALL_STACK
18060     XFREE(pub,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
18061     XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18062 #endif
18063 
18064     return ret;
18065 }
18066 #endif /* NO_DH */
18067 
18068 
18069 #ifndef NO_DSA
18070 static void InitwolfSSL_DSA(WOLFSSL_DSA* dsa)
18071 {
18072     if (dsa) {
18073         dsa->p        = NULL;
18074         dsa->q        = NULL;
18075         dsa->g        = NULL;
18076         dsa->pub_key  = NULL;
18077         dsa->priv_key = NULL;
18078         dsa->internal = NULL;
18079         dsa->inSet    = 0;
18080         dsa->exSet    = 0;
18081     }
18082 }
18083 
18084 
18085 WOLFSSL_DSA* wolfSSL_DSA_new(void)
18086 {
18087     WOLFSSL_DSA* external;
18088     DsaKey*     key;
18089 
18090     WOLFSSL_MSG("wolfSSL_DSA_new");
18091 
18092     key = (DsaKey*) XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
18093     if (key == NULL) {
18094         WOLFSSL_MSG("wolfSSL_DSA_new malloc DsaKey failure");
18095         return NULL;
18096     }
18097 
18098     external = (WOLFSSL_DSA*) XMALLOC(sizeof(WOLFSSL_DSA), NULL,
18099                                     DYNAMIC_TYPE_DSA);
18100     if (external == NULL) {
18101         WOLFSSL_MSG("wolfSSL_DSA_new malloc WOLFSSL_DSA failure");
18102         XFREE(key, NULL, DYNAMIC_TYPE_DSA);
18103         return NULL;
18104     }
18105 
18106     InitwolfSSL_DSA(external);
18107     if (wc_InitDsaKey(key) != 0) {
18108         WOLFSSL_MSG("wolfSSL_DSA_new InitDsaKey failure");
18109         XFREE(key, NULL, DYNAMIC_TYPE_DSA);
18110         return NULL;
18111     }
18112     external->internal = key;
18113 
18114     return external;
18115 }
18116 
18117 
18118 void wolfSSL_DSA_free(WOLFSSL_DSA* dsa)
18119 {
18120     WOLFSSL_MSG("wolfSSL_DSA_free");
18121 
18122     if (dsa) {
18123         if (dsa->internal) {
18124             FreeDsaKey((DsaKey*)dsa->internal);
18125             XFREE(dsa->internal, NULL, DYNAMIC_TYPE_DSA);
18126             dsa->internal = NULL;
18127         }
18128         wolfSSL_BN_free(dsa->priv_key);
18129         wolfSSL_BN_free(dsa->pub_key);
18130         wolfSSL_BN_free(dsa->g);
18131         wolfSSL_BN_free(dsa->q);
18132         wolfSSL_BN_free(dsa->p);
18133         InitwolfSSL_DSA(dsa);  /* set back to NULLs for safety */
18134 
18135         XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
18136         dsa = NULL;
18137     }
18138 }
18139 
18140 #endif /* NO_DSA */
18141 
18142 #ifndef NO_RSA
18143 static void InitwolfSSL_Rsa(WOLFSSL_RSA* rsa)
18144 {
18145     if (rsa) {
18146         rsa->n        = NULL;
18147         rsa->e        = NULL;
18148         rsa->d        = NULL;
18149         rsa->p        = NULL;
18150         rsa->q        = NULL;
18151         rsa->dmp1     = NULL;
18152         rsa->dmq1     = NULL;
18153         rsa->iqmp     = NULL;
18154         rsa->internal = NULL;
18155         rsa->inSet    = 0;
18156         rsa->exSet    = 0;
18157     }
18158 }
18159 
18160 
18161 WOLFSSL_RSA* wolfSSL_RSA_new(void)
18162 {
18163     WOLFSSL_RSA* external;
18164     RsaKey*     key;
18165 
18166     WOLFSSL_MSG("wolfSSL_RSA_new");
18167 
18168     key = (RsaKey*) XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
18169     if (key == NULL) {
18170         WOLFSSL_MSG("wolfSSL_RSA_new malloc RsaKey failure");
18171         return NULL;
18172     }
18173 
18174     external = (WOLFSSL_RSA*) XMALLOC(sizeof(WOLFSSL_RSA), NULL,
18175                                      DYNAMIC_TYPE_RSA);
18176     if (external == NULL) {
18177         WOLFSSL_MSG("wolfSSL_RSA_new malloc WOLFSSL_RSA failure");
18178         XFREE(key, NULL, DYNAMIC_TYPE_RSA);
18179         return NULL;
18180     }
18181 
18182     InitwolfSSL_Rsa(external);
18183     if (wc_InitRsaKey(key, NULL) != 0) {
18184         WOLFSSL_MSG("InitRsaKey WOLFSSL_RSA failure");
18185         XFREE(external, NULL, DYNAMIC_TYPE_RSA);
18186         XFREE(key, NULL, DYNAMIC_TYPE_RSA);
18187         return NULL;
18188     }
18189     external->internal = key;
18190 
18191     return external;
18192 }
18193 
18194 
18195 void wolfSSL_RSA_free(WOLFSSL_RSA* rsa)
18196 {
18197     WOLFSSL_MSG("wolfSSL_RSA_free");
18198 
18199     if (rsa) {
18200         if (rsa->internal) {
18201             wc_FreeRsaKey((RsaKey*)rsa->internal);
18202             XFREE(rsa->internal, NULL, DYNAMIC_TYPE_RSA);
18203             rsa->internal = NULL;
18204         }
18205         wolfSSL_BN_free(rsa->iqmp);
18206         wolfSSL_BN_free(rsa->dmq1);
18207         wolfSSL_BN_free(rsa->dmp1);
18208         wolfSSL_BN_free(rsa->q);
18209         wolfSSL_BN_free(rsa->p);
18210         wolfSSL_BN_free(rsa->d);
18211         wolfSSL_BN_free(rsa->e);
18212         wolfSSL_BN_free(rsa->n);
18213         InitwolfSSL_Rsa(rsa);  /* set back to NULLs for safety */
18214 
18215         XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
18216         rsa = NULL;
18217     }
18218 }
18219 #endif /* NO_RSA */
18220 
18221 
18222 /* these defines are to make sure the functions SetIndividualExternal is not
18223  * declared and then not used. */
18224 #if !defined(NO_ASN) || !defined(NO_DSA) || defined(HAVE_ECC) || \
18225     (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA))
18226 /* when calling SetIndividualExternal, mpi should be cleared by caller if no
18227  * longer used. ie mp_clear(mpi). This is to free data when fastmath is
18228  * disabled since a copy of mpi is made by this function and placed into bn.
18229  */
18230 static int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi)
18231 {
18232     byte dynamic = 0;
18233 
18234     WOLFSSL_MSG("Entering SetIndividualExternal");
18235 
18236     if (mpi == NULL || bn == NULL) {
18237         WOLFSSL_MSG("mpi NULL error");
18238         return SSL_FATAL_ERROR;
18239     }
18240 
18241     if (*bn == NULL) {
18242         *bn = wolfSSL_BN_new();
18243         if (*bn == NULL) {
18244             WOLFSSL_MSG("SetIndividualExternal alloc failed");
18245             return SSL_FATAL_ERROR;
18246         }
18247         dynamic = 1;
18248     }
18249 
18250     if (mp_copy(mpi, (mp_int*)((*bn)->internal)) != MP_OKAY) {
18251         WOLFSSL_MSG("mp_copy error");
18252         if (dynamic == 1) {
18253             wolfSSL_BN_free(*bn);
18254         }
18255         return SSL_FATAL_ERROR;
18256     }
18257 
18258     return SSL_SUCCESS;
18259 }
18260 
18261 static int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi)
18262 {
18263     WOLFSSL_MSG("Entering SetIndividualInternal");
18264 
18265     if (bn == NULL || bn->internal == NULL) {
18266         WOLFSSL_MSG("bn NULL error");
18267         return SSL_FATAL_ERROR;
18268     }
18269 
18270     if (mpi == NULL || (mp_init(mpi) != MP_OKAY)) {
18271         WOLFSSL_MSG("mpi NULL error");
18272         return SSL_FATAL_ERROR;
18273     }
18274 
18275     if (mp_copy((mp_int*)bn->internal, mpi) != MP_OKAY) {
18276         WOLFSSL_MSG("mp_copy error");
18277         return SSL_FATAL_ERROR;
18278     }
18279 
18280     return SSL_SUCCESS;
18281 }
18282 
18283 
18284 #ifndef NO_ASN
18285 WOLFSSL_BIGNUM *wolfSSL_ASN1_INTEGER_to_BN(const WOLFSSL_ASN1_INTEGER *ai,
18286                                        WOLFSSL_BIGNUM *bn)
18287 {
18288     mp_int mpi;
18289     word32 idx = 0;
18290     int ret;
18291 
18292     WOLFSSL_ENTER("wolfSSL_ASN1_INTEGER_to_BN");
18293 
18294     if (ai == NULL) {
18295         return NULL;
18296     }
18297 
18298     if ((ret = GetInt(&mpi, ai->data, &idx, sizeof(ai->data))) != 0) {
18299         /* expecting ASN1 format for INTEGER */
18300         WOLFSSL_LEAVE("wolfSSL_ASN1_INTEGER_to_BN", ret);
18301         return NULL;
18302     }
18303 
18304     /* mp_clear needs called because mpi is copied and causes memory leak with
18305      * --disable-fastmath */
18306     ret = SetIndividualExternal(&bn, &mpi);
18307     mp_clear(&mpi);
18308 
18309     if (ret != SSL_SUCCESS) {
18310         return NULL;
18311     }
18312     return bn;
18313 }
18314 #endif /* !NO_ASN */
18315 
18316 #if !defined(NO_DSA) && !defined(NO_DH)
18317 WOLFSSL_DH *wolfSSL_DSA_dup_DH(const WOLFSSL_DSA *dsa)
18318 {
18319     WOLFSSL_DH* dh;
18320     DhKey*      key;
18321 
18322     WOLFSSL_ENTER("wolfSSL_DSA_dup_DH");
18323 
18324     if (dsa == NULL) {
18325         return NULL;
18326     }
18327 
18328     dh = wolfSSL_DH_new();
18329     if (dh == NULL) {
18330         return NULL;
18331     }
18332     key = (DhKey*)dh->internal;
18333 
18334     if (dsa->p != NULL &&
18335         SetIndividualInternal(((WOLFSSL_DSA*)dsa)->p, &key->p) != SSL_SUCCESS) {
18336         WOLFSSL_MSG("rsa p key error");
18337         wolfSSL_DH_free(dh);
18338         return NULL;
18339     }
18340     if (dsa->g != NULL &&
18341         SetIndividualInternal(((WOLFSSL_DSA*)dsa)->g, &key->g) != SSL_SUCCESS) {
18342         WOLFSSL_MSG("rsa g key error");
18343         wolfSSL_DH_free(dh);
18344         return NULL;
18345     }
18346 
18347     if (SetIndividualExternal(&dh->p, &key->p) != SSL_SUCCESS) {
18348         WOLFSSL_MSG("dsa p key error");
18349         wolfSSL_DH_free(dh);
18350         return NULL;
18351     }
18352     if (SetIndividualExternal(&dh->g, &key->g) != SSL_SUCCESS) {
18353         WOLFSSL_MSG("dsa g key error");
18354         wolfSSL_DH_free(dh);
18355         return NULL;
18356     }
18357 
18358     return dh;
18359 }
18360 #endif /* !defined(NO_DSA) && !defined(NO_DH) */
18361 
18362 #endif /* !NO_RSA && !NO_DSA */
18363 
18364 
18365 #ifndef NO_DSA
18366 /* wolfSSL -> OpenSSL */
18367 static int SetDsaExternal(WOLFSSL_DSA* dsa)
18368 {
18369     DsaKey* key;
18370     WOLFSSL_MSG("Entering SetDsaExternal");
18371 
18372     if (dsa == NULL || dsa->internal == NULL) {
18373         WOLFSSL_MSG("dsa key NULL error");
18374         return SSL_FATAL_ERROR;
18375     }
18376 
18377     key = (DsaKey*)dsa->internal;
18378 
18379     if (SetIndividualExternal(&dsa->p, &key->p) != SSL_SUCCESS) {
18380         WOLFSSL_MSG("dsa p key error");
18381         return SSL_FATAL_ERROR;
18382     }
18383 
18384     if (SetIndividualExternal(&dsa->q, &key->q) != SSL_SUCCESS) {
18385         WOLFSSL_MSG("dsa q key error");
18386         return SSL_FATAL_ERROR;
18387     }
18388 
18389     if (SetIndividualExternal(&dsa->g, &key->g) != SSL_SUCCESS) {
18390         WOLFSSL_MSG("dsa g key error");
18391         return SSL_FATAL_ERROR;
18392     }
18393 
18394     if (SetIndividualExternal(&dsa->pub_key, &key->y) != SSL_SUCCESS) {
18395         WOLFSSL_MSG("dsa y key error");
18396         return SSL_FATAL_ERROR;
18397     }
18398 
18399     if (SetIndividualExternal(&dsa->priv_key, &key->x) != SSL_SUCCESS) {
18400         WOLFSSL_MSG("dsa x key error");
18401         return SSL_FATAL_ERROR;
18402     }
18403 
18404     dsa->exSet = 1;
18405 
18406     return SSL_SUCCESS;
18407 }
18408 
18409 /* Openssl -> WolfSSL */
18410 static int SetDsaInternal(WOLFSSL_DSA* dsa)
18411 {
18412     DsaKey* key;
18413     WOLFSSL_MSG("Entering SetDsaInternal");
18414 
18415     if (dsa == NULL || dsa->internal == NULL) {
18416         WOLFSSL_MSG("dsa key NULL error");
18417         return SSL_FATAL_ERROR;
18418     }
18419 
18420     key = (DsaKey*)dsa->internal;
18421 
18422     if (dsa->p != NULL &&
18423         SetIndividualInternal(dsa->p, &key->p) != SSL_SUCCESS) {
18424         WOLFSSL_MSG("rsa p key error");
18425         return SSL_FATAL_ERROR;
18426     }
18427 
18428     if (dsa->q != NULL &&
18429         SetIndividualInternal(dsa->q, &key->q) != SSL_SUCCESS) {
18430         WOLFSSL_MSG("rsa q key error");
18431         return SSL_FATAL_ERROR;
18432     }
18433 
18434     if (dsa->g != NULL &&
18435         SetIndividualInternal(dsa->g, &key->g) != SSL_SUCCESS) {
18436         WOLFSSL_MSG("rsa g key error");
18437         return SSL_FATAL_ERROR;
18438     }
18439 
18440     if (dsa->pub_key != NULL) {
18441         if (SetIndividualInternal(dsa->pub_key, &key->y) != SSL_SUCCESS) {
18442             WOLFSSL_MSG("rsa pub_key error");
18443             return SSL_FATAL_ERROR;
18444         }
18445 
18446         /* public key */
18447         key->type = DSA_PUBLIC;
18448     }
18449 
18450     if (dsa->priv_key != NULL) {
18451         if (SetIndividualInternal(dsa->priv_key, &key->x) != SSL_SUCCESS) {
18452             WOLFSSL_MSG("rsa priv_key error");
18453             return SSL_FATAL_ERROR;
18454         }
18455 
18456         /* private key */
18457         key->type = DSA_PRIVATE;
18458     }
18459 
18460     dsa->inSet = 1;
18461 
18462     return SSL_SUCCESS;
18463 }
18464 #endif /* NO_DSA */
18465 
18466 
18467 #if !defined(NO_RSA)
18468 #if !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
18469 /* WolfSSL -> OpenSSL */
18470 static int SetRsaExternal(WOLFSSL_RSA* rsa)
18471 {
18472     RsaKey* key;
18473     WOLFSSL_MSG("Entering SetRsaExternal");
18474 
18475     if (rsa == NULL || rsa->internal == NULL) {
18476         WOLFSSL_MSG("rsa key NULL error");
18477         return SSL_FATAL_ERROR;
18478     }
18479 
18480     key = (RsaKey*)rsa->internal;
18481 
18482     if (SetIndividualExternal(&rsa->n, &key->n) != SSL_SUCCESS) {
18483         WOLFSSL_MSG("rsa n key error");
18484         return SSL_FATAL_ERROR;
18485     }
18486 
18487     if (SetIndividualExternal(&rsa->e, &key->e) != SSL_SUCCESS) {
18488         WOLFSSL_MSG("rsa e key error");
18489         return SSL_FATAL_ERROR;
18490     }
18491 
18492     if (SetIndividualExternal(&rsa->d, &key->d) != SSL_SUCCESS) {
18493         WOLFSSL_MSG("rsa d key error");
18494         return SSL_FATAL_ERROR;
18495     }
18496 
18497     if (SetIndividualExternal(&rsa->p, &key->p) != SSL_SUCCESS) {
18498         WOLFSSL_MSG("rsa p key error");
18499         return SSL_FATAL_ERROR;
18500     }
18501 
18502     if (SetIndividualExternal(&rsa->q, &key->q) != SSL_SUCCESS) {
18503         WOLFSSL_MSG("rsa q key error");
18504         return SSL_FATAL_ERROR;
18505     }
18506 
18507     if (SetIndividualExternal(&rsa->dmp1, &key->dP) != SSL_SUCCESS) {
18508         WOLFSSL_MSG("rsa dP key error");
18509         return SSL_FATAL_ERROR;
18510     }
18511 
18512     if (SetIndividualExternal(&rsa->dmq1, &key->dQ) != SSL_SUCCESS) {
18513         WOLFSSL_MSG("rsa dQ key error");
18514         return SSL_FATAL_ERROR;
18515     }
18516 
18517     if (SetIndividualExternal(&rsa->iqmp, &key->u) != SSL_SUCCESS) {
18518         WOLFSSL_MSG("rsa u key error");
18519         return SSL_FATAL_ERROR;
18520     }
18521 
18522     rsa->exSet = 1;
18523 
18524     return SSL_SUCCESS;
18525 }
18526 
18527 /* Openssl -> WolfSSL */
18528 static int SetRsaInternal(WOLFSSL_RSA* rsa)
18529 {
18530     RsaKey* key;
18531     WOLFSSL_MSG("Entering SetRsaInternal");
18532 
18533     if (rsa == NULL || rsa->internal == NULL) {
18534         WOLFSSL_MSG("rsa key NULL error");
18535         return SSL_FATAL_ERROR;
18536     }
18537 
18538     key = (RsaKey*)rsa->internal;
18539 
18540     if (SetIndividualInternal(rsa->n, &key->n) != SSL_SUCCESS) {
18541         WOLFSSL_MSG("rsa n key error");
18542         return SSL_FATAL_ERROR;
18543     }
18544 
18545     if (SetIndividualInternal(rsa->e, &key->e) != SSL_SUCCESS) {
18546         WOLFSSL_MSG("rsa e key error");
18547         return SSL_FATAL_ERROR;
18548     }
18549 
18550     /* public key */
18551     key->type = RSA_PUBLIC;
18552 
18553     if (rsa->d != NULL) {
18554         if (SetIndividualInternal(rsa->d, &key->d) != SSL_SUCCESS) {
18555             WOLFSSL_MSG("rsa d key error");
18556             return SSL_FATAL_ERROR;
18557         }
18558 
18559         /* private key */
18560         key->type = RSA_PRIVATE;
18561     }
18562 
18563     if (rsa->p != NULL &&
18564         SetIndividualInternal(rsa->p, &key->p) != SSL_SUCCESS) {
18565         WOLFSSL_MSG("rsa p key error");
18566         return SSL_FATAL_ERROR;
18567     }
18568 
18569     if (rsa->q != NULL &&
18570         SetIndividualInternal(rsa->q, &key->q) != SSL_SUCCESS) {
18571         WOLFSSL_MSG("rsa q key error");
18572         return SSL_FATAL_ERROR;
18573     }
18574 
18575     if (rsa->dmp1 != NULL &&
18576         SetIndividualInternal(rsa->dmp1, &key->dP) != SSL_SUCCESS) {
18577         WOLFSSL_MSG("rsa dP key error");
18578         return SSL_FATAL_ERROR;
18579     }
18580 
18581     if (rsa->dmq1 != NULL &&
18582         SetIndividualInternal(rsa->dmq1, &key->dQ) != SSL_SUCCESS) {
18583         WOLFSSL_MSG("rsa dQ key error");
18584         return SSL_FATAL_ERROR;
18585     }
18586 
18587     if (rsa->iqmp != NULL &&
18588         SetIndividualInternal(rsa->iqmp, &key->u) != SSL_SUCCESS) {
18589         WOLFSSL_MSG("rsa u key error");
18590         return SSL_FATAL_ERROR;
18591     }
18592 
18593     rsa->inSet = 1;
18594 
18595     return SSL_SUCCESS;
18596 }
18597 #endif /* HAVE_USER_RSA */
18598 
18599 /* return compliant with OpenSSL
18600  *   1 if success, 0 if error
18601  */
18602 int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* bn,
18603                                 void* cb)
18604 {
18605     int ret = SSL_FAILURE;
18606 
18607     (void)cb;
18608     (void)bn;
18609     (void)bits;
18610 
18611     WOLFSSL_ENTER("wolfSSL_RSA_generate_key_ex");
18612 
18613     if (rsa == NULL || rsa->internal == NULL) {
18614         /* bit size checked during make key call */
18615         WOLFSSL_MSG("bad arguments");
18616         return SSL_FAILURE;
18617     }
18618 
18619 #ifdef WOLFSSL_KEY_GEN
18620     {
18621     #ifdef WOLFSSL_SMALL_STACK
18622         WC_RNG* rng = NULL;
18623     #else
18624         WC_RNG  rng[1];
18625     #endif
18626 
18627     #ifdef WOLFSSL_SMALL_STACK
18628         rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
18629         if (rng == NULL)
18630             return SSL_FAILURE;
18631     #endif
18632 
18633         if (wc_InitRng(rng) < 0)
18634             WOLFSSL_MSG("RNG init failed");
18635         else if (wc_MakeRsaKey((RsaKey*)rsa->internal,
18636                                bits, 65537, rng) != MP_OKAY)
18637             WOLFSSL_MSG("wc_MakeRsaKey failed");
18638         else if (SetRsaExternal(rsa) != SSL_SUCCESS)
18639             WOLFSSL_MSG("SetRsaExternal failed");
18640         else {
18641             rsa->inSet = 1;
18642             ret = SSL_SUCCESS;
18643         }
18644 
18645         wc_FreeRng(rng);
18646     #ifdef WOLFSSL_SMALL_STACK
18647         XFREE(rng, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18648     #endif
18649     }
18650 #else
18651     WOLFSSL_MSG("No Key Gen built in");
18652 #endif
18653     return ret;
18654 }
18655 
18656 
18657 /* SSL_SUCCESS on ok */
18658 int wolfSSL_RSA_blinding_on(WOLFSSL_RSA* rsa, WOLFSSL_BN_CTX* bn)
18659 {
18660     (void)rsa;
18661     (void)bn;
18662 
18663     WOLFSSL_MSG("wolfSSL_RSA_blinding_on");
18664 
18665     return SSL_SUCCESS;  /* on by default */
18666 }
18667 
18668 /* return compliant with OpenSSL
18669  *   size of encrypted data if success , -1 if error
18670  */
18671 int wolfSSL_RSA_public_encrypt(int len, unsigned char* fr,
18672                             unsigned char* to, WOLFSSL_RSA* rsa, int padding)
18673 {
18674     (void)len;
18675     (void)fr;
18676     (void)to;
18677     (void)rsa;
18678     (void)padding;
18679 
18680     WOLFSSL_MSG("wolfSSL_RSA_public_encrypt");
18681 
18682     return SSL_FATAL_ERROR;
18683 }
18684 
18685 /* return compliant with OpenSSL
18686  *   size of plain recovered data if success , -1 if error
18687  */
18688 int wolfSSL_RSA_private_decrypt(int len, unsigned char* fr,
18689                             unsigned char* to, WOLFSSL_RSA* rsa, int padding)
18690 {
18691     (void)len;
18692     (void)fr;
18693     (void)to;
18694     (void)rsa;
18695     (void)padding;
18696 
18697     WOLFSSL_MSG("wolfSSL_RSA_private_decrypt");
18698 
18699     return SSL_FATAL_ERROR;
18700 }
18701 
18702 /* return compliant with OpenSSL
18703  *   RSA modulus size in bytes, -1 if error
18704  */
18705 int wolfSSL_RSA_size(const WOLFSSL_RSA* rsa)
18706 {
18707     WOLFSSL_MSG("wolfSSL_RSA_size");
18708 
18709     if (rsa == NULL)
18710         return SSL_FATAL_ERROR;
18711 
18712     return wolfSSL_BN_num_bytes(rsa->n);
18713 }
18714 #endif /* NO_RSA */
18715 
18716 #ifndef NO_DSA
18717 /* return code compliant with OpenSSL :
18718  *   1 if success, 0 if error
18719  */
18720 int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa)
18721 {
18722     int ret = SSL_FAILURE;
18723 
18724     WOLFSSL_ENTER("wolfSSL_DSA_generate_key");
18725 
18726     if (dsa == NULL || dsa->internal == NULL) {
18727         WOLFSSL_MSG("Bad arguments");
18728         return SSL_FAILURE;
18729     }
18730 
18731     if (dsa->inSet == 0) {
18732         WOLFSSL_MSG("No DSA internal set, do it");
18733 
18734         if (SetDsaInternal(dsa) != SSL_SUCCESS) {
18735             WOLFSSL_MSG("SetDsaInternal failed");
18736             return ret;
18737         }
18738     }
18739 
18740 #ifdef WOLFSSL_KEY_GEN
18741     {
18742         int initTmpRng = 0;
18743         WC_RNG *rng = NULL;
18744 #ifdef WOLFSSL_SMALL_STACK
18745         WC_RNG *tmpRNG = NULL;
18746 #else
18747         WC_RNG tmpRNG[1];
18748 #endif
18749 
18750 #ifdef WOLFSSL_SMALL_STACK
18751         tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
18752         if (tmpRNG == NULL)
18753             return SSL_FATAL_ERROR;
18754 #endif
18755         if (wc_InitRng(tmpRNG) == 0) {
18756             rng = tmpRNG;
18757             initTmpRng = 1;
18758         }
18759         else {
18760             WOLFSSL_MSG("Bad RNG Init, trying global");
18761             if (initGlobalRNG == 0)
18762                 WOLFSSL_MSG("Global RNG no Init");
18763             else
18764                 rng = &globalRNG;
18765         }
18766 
18767         if (rng) {
18768             if (wc_MakeDsaKey(rng, (DsaKey*)dsa->internal) != MP_OKAY)
18769                 WOLFSSL_MSG("wc_MakeDsaKey failed");
18770             else if (SetDsaExternal(dsa) != SSL_SUCCESS)
18771                 WOLFSSL_MSG("SetDsaExternal failed");
18772             else
18773                 ret = SSL_SUCCESS;
18774         }
18775 
18776         if (initTmpRng)
18777             wc_FreeRng(tmpRNG);
18778 
18779 #ifdef WOLFSSL_SMALL_STACK
18780         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18781 #endif
18782     }
18783 #else /* WOLFSSL_KEY_GEN */
18784     WOLFSSL_MSG("No Key Gen built in");
18785 #endif
18786     return ret;
18787 }
18788 
18789 /* return code compliant with OpenSSL :
18790  *   1 if success, 0 if error
18791  */
18792 int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits,
18793                                        unsigned char* seed, int seedLen,
18794                                        int* counterRet,
18795                                        unsigned long* hRet, void* cb)
18796 {
18797     int ret = SSL_FAILURE;
18798 
18799     (void)bits;
18800     (void)seed;
18801     (void)seedLen;
18802     (void)counterRet;
18803     (void)hRet;
18804     (void)cb;
18805 
18806     WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters_ex");
18807 
18808     if (dsa == NULL || dsa->internal == NULL) {
18809         WOLFSSL_MSG("Bad arguments");
18810         return SSL_FAILURE;
18811     }
18812 
18813 #ifdef WOLFSSL_KEY_GEN
18814     {
18815         int initTmpRng = 0;
18816         WC_RNG *rng = NULL;
18817 #ifdef WOLFSSL_SMALL_STACK
18818         WC_RNG *tmpRNG = NULL;
18819 #else
18820         WC_RNG tmpRNG[1];
18821 #endif
18822 
18823 #ifdef WOLFSSL_SMALL_STACK
18824         tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
18825         if (tmpRNG == NULL)
18826             return SSL_FATAL_ERROR;
18827 #endif
18828         if (wc_InitRng(tmpRNG) == 0) {
18829             rng = tmpRNG;
18830             initTmpRng = 1;
18831         }
18832         else {
18833             WOLFSSL_MSG("Bad RNG Init, trying global");
18834             if (initGlobalRNG == 0)
18835                 WOLFSSL_MSG("Global RNG no Init");
18836             else
18837                 rng = &globalRNG;
18838         }
18839 
18840         if (rng) {
18841             if (wc_MakeDsaParameters(rng, bits,
18842                                      (DsaKey*)dsa->internal) != MP_OKAY)
18843                 WOLFSSL_MSG("wc_MakeDsaParameters failed");
18844             else if (SetDsaExternal(dsa) != SSL_SUCCESS)
18845                 WOLFSSL_MSG("SetDsaExternal failed");
18846             else
18847                 ret = SSL_SUCCESS;
18848         }
18849 
18850         if (initTmpRng)
18851             wc_FreeRng(tmpRNG);
18852 
18853 #ifdef WOLFSSL_SMALL_STACK
18854         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18855 #endif
18856     }
18857 #else /* WOLFSSL_KEY_GEN */
18858     WOLFSSL_MSG("No Key Gen built in");
18859 #endif
18860 
18861     return ret;
18862 }
18863 
18864 /* return SSL_SUCCESS on success, < 0 otherwise */
18865 int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
18866                        WOLFSSL_DSA* dsa)
18867 {
18868     int     ret = SSL_FATAL_ERROR;
18869     int     initTmpRng = 0;
18870     WC_RNG* rng = NULL;
18871 #ifdef WOLFSSL_SMALL_STACK
18872     WC_RNG* tmpRNG = NULL;
18873 #else
18874     WC_RNG  tmpRNG[1];
18875 #endif
18876 
18877     WOLFSSL_ENTER("wolfSSL_DSA_do_sign");
18878 
18879     if (d == NULL || sigRet == NULL || dsa == NULL) {
18880         WOLFSSL_MSG("Bad function arguments");
18881         return ret;
18882     }
18883 
18884     if (dsa->inSet == 0)
18885     {
18886         WOLFSSL_MSG("No DSA internal set, do it");
18887 
18888         if (SetDsaInternal(dsa) != SSL_SUCCESS) {
18889             WOLFSSL_MSG("SetDsaInternal failed");
18890             return ret;
18891         }
18892     }
18893 
18894 #ifdef WOLFSSL_SMALL_STACK
18895     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
18896     if (tmpRNG == NULL)
18897         return SSL_FATAL_ERROR;
18898 #endif
18899 
18900     if (wc_InitRng(tmpRNG) == 0) {
18901         rng = tmpRNG;
18902         initTmpRng = 1;
18903     }
18904     else {
18905         WOLFSSL_MSG("Bad RNG Init, trying global");
18906         if (initGlobalRNG == 0)
18907             WOLFSSL_MSG("Global RNG no Init");
18908         else
18909             rng = &globalRNG;
18910     }
18911 
18912     if (rng) {
18913         if (DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0)
18914             WOLFSSL_MSG("DsaSign failed");
18915         else
18916             ret = SSL_SUCCESS;
18917     }
18918 
18919     if (initTmpRng)
18920         wc_FreeRng(tmpRNG);
18921 #ifdef WOLFSSL_SMALL_STACK
18922     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18923 #endif
18924 
18925     return ret;
18926 }
18927 
18928 
18929 int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig,
18930                         WOLFSSL_DSA* dsa, int *dsacheck)
18931 {
18932     int    ret = SSL_FATAL_ERROR;
18933 
18934     WOLFSSL_ENTER("wolfSSL_DSA_do_verify");
18935 
18936     if (d == NULL || sig == NULL || dsa == NULL) {
18937         WOLFSSL_MSG("Bad function arguments");
18938         return SSL_FATAL_ERROR;
18939     }
18940     if (dsa->inSet == 0)
18941     {
18942         WOLFSSL_MSG("No DSA internal set, do it");
18943 
18944         if (SetDsaInternal(dsa) != SSL_SUCCESS) {
18945             WOLFSSL_MSG("SetDsaInternal failed");
18946             return SSL_FATAL_ERROR;
18947         }
18948     }
18949 
18950     ret = DsaVerify(d, sig, (DsaKey*)dsa->internal, dsacheck);
18951     if (ret != 0 || *dsacheck != 1) {
18952         WOLFSSL_MSG("DsaVerify failed");
18953         return ret;
18954     }
18955 
18956     return SSL_SUCCESS;
18957 }
18958 #endif /* NO_DSA */
18959 
18960 
18961 #ifndef NO_RSA
18962 /* return SSL_SUCCES on ok, 0 otherwise */
18963 int wolfSSL_RSA_sign(int type, const unsigned char* m,
18964                            unsigned int mLen, unsigned char* sigRet,
18965                            unsigned int* sigLen, WOLFSSL_RSA* rsa)
18966 {
18967     word32  outLen;
18968     word32  signSz;
18969     int     initTmpRng = 0;
18970     WC_RNG* rng        = NULL;
18971     int     ret        = 0;
18972 #ifdef WOLFSSL_SMALL_STACK
18973     WC_RNG* tmpRNG     = NULL;
18974     byte*   encodedSig = NULL;
18975 #else
18976     WC_RNG  tmpRNG[1];
18977     byte    encodedSig[MAX_ENCODED_SIG_SZ];
18978 #endif
18979 
18980     WOLFSSL_MSG("wolfSSL_RSA_sign");
18981 
18982     if (m == NULL || sigRet == NULL || sigLen == NULL || rsa == NULL) {
18983         WOLFSSL_MSG("Bad function arguments");
18984         return 0;
18985     }
18986 
18987     switch (type) {
18988     #ifdef WOLFSSL_MD2
18989         case NID_md2:       type = MD2h;    break;
18990     #endif
18991     #ifndef NO_MD5
18992         case NID_md5:       type = MD5h;    break;
18993     #endif
18994     #ifndef NO_SHA
18995         case NID_sha1:      type = SHAh;    break;
18996     #endif
18997     #ifndef NO_SHA256
18998         case NID_sha256:    type = SHA256h; break;
18999     #endif
19000     #ifdef WOLFSSL_SHA384
19001         case NID_sha384:    type = SHA384h; break;
19002     #endif
19003     #ifdef WOLFSSL_SHA512
19004         case NID_sha512:    type = SHA512h; break;
19005     #endif
19006         default:
19007             WOLFSSL_MSG("This NID (md type) not configured or not implemented");
19008             return 0;
19009     }
19010 
19011     if (rsa->inSet == 0)
19012     {
19013         WOLFSSL_MSG("No RSA internal set, do it");
19014 
19015         if (SetRsaInternal(rsa) != SSL_SUCCESS) {
19016             WOLFSSL_MSG("SetRsaInternal failed");
19017             return 0;
19018         }
19019     }
19020 
19021     outLen = (word32)wolfSSL_BN_num_bytes(rsa->n);
19022 
19023 #ifdef WOLFSSL_SMALL_STACK
19024     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
19025     if (tmpRNG == NULL)
19026         return 0;
19027 
19028     encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
19029                                                    DYNAMIC_TYPE_TMP_BUFFER);
19030     if (encodedSig == NULL) {
19031         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19032         return 0;
19033     }
19034 #endif
19035 
19036     if (outLen == 0)
19037         WOLFSSL_MSG("Bad RSA size");
19038     else if (wc_InitRng(tmpRNG) == 0) {
19039         rng = tmpRNG;
19040         initTmpRng = 1;
19041     }
19042     else {
19043         WOLFSSL_MSG("Bad RNG Init, trying global");
19044 
19045         if (initGlobalRNG == 0)
19046             WOLFSSL_MSG("Global RNG no Init");
19047         else
19048             rng = &globalRNG;
19049     }
19050 
19051     if (rng) {
19052 
19053         signSz = wc_EncodeSignature(encodedSig, m, mLen, type);
19054         if (signSz == 0) {
19055             WOLFSSL_MSG("Bad Encode Signature");
19056         }
19057         else {
19058             ret = wc_RsaSSL_Sign(encodedSig, signSz, sigRet, outLen,
19059                                   (RsaKey*)rsa->internal, rng);
19060             if (ret <= 0) {
19061                 WOLFSSL_MSG("Bad Rsa Sign");
19062                 ret = 0;
19063             }
19064             else {
19065                 ret = SSL_SUCCESS;
19066                 *sigLen = ret;
19067             }
19068         }
19069 
19070     }
19071 
19072     if (initTmpRng)
19073         wc_FreeRng(tmpRNG);
19074 
19075 #ifdef WOLFSSL_SMALL_STACK
19076     XFREE(tmpRNG,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
19077     XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19078 #endif
19079 
19080     if (ret == SSL_SUCCESS)
19081         WOLFSSL_MSG("wolfSSL_RSA_sign success");
19082     else {
19083         WOLFSSL_MSG("wolfSSL_RSA_sign failed");
19084     }
19085     return ret;
19086 }
19087 
19088 
19089 int wolfSSL_RSA_public_decrypt(int flen, unsigned char* from,
19090                           unsigned char* to, WOLFSSL_RSA* rsa, int padding)
19091 {
19092     int tlen = 0;
19093 
19094     WOLFSSL_MSG("wolfSSL_RSA_public_decrypt");
19095 
19096     if (rsa == NULL || rsa->internal == NULL || from == NULL) {
19097         WOLFSSL_MSG("Bad function arguments");
19098         return 0;
19099     }
19100 
19101     if (padding != RSA_PKCS1_PADDING) {
19102         WOLFSSL_MSG("wolfSSL_RSA_public_decrypt unsupported padding");
19103         return 0;
19104     }
19105 
19106     if (rsa->inSet == 0)
19107     {
19108         WOLFSSL_MSG("No RSA internal set, do it");
19109 
19110         if (SetRsaInternal(rsa) != SSL_SUCCESS) {
19111             WOLFSSL_MSG("SetRsaInternal failed");
19112             return 0;
19113         }
19114     }
19115 
19116     /* size of 'to' buffer must be size of RSA key */
19117     tlen = wc_RsaSSL_Verify(from, flen, to, wolfSSL_RSA_size(rsa),
19118                             (RsaKey*)rsa->internal);
19119     if (tlen <= 0)
19120         WOLFSSL_MSG("wolfSSL_RSA_public_decrypt failed");
19121     else {
19122         WOLFSSL_MSG("wolfSSL_RSA_public_decrypt success");
19123     }
19124     return tlen;
19125 }
19126 
19127 
19128 /* generate p-1 and q-1, SSL_SUCCESS on ok */
19129 int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
19130 {
19131     int    err;
19132     mp_int tmp;
19133 
19134     WOLFSSL_MSG("wolfSSL_RsaGenAdd");
19135 
19136     if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->d == NULL ||
19137                        rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
19138         WOLFSSL_MSG("rsa no init error");
19139         return SSL_FATAL_ERROR;
19140     }
19141 
19142     if (mp_init(&tmp) != MP_OKAY) {
19143         WOLFSSL_MSG("mp_init error");
19144         return SSL_FATAL_ERROR;
19145     }
19146 
19147     err = mp_sub_d((mp_int*)rsa->p->internal, 1, &tmp);
19148     if (err != MP_OKAY) {
19149         WOLFSSL_MSG("mp_sub_d error");
19150     }
19151     else
19152         err = mp_mod((mp_int*)rsa->d->internal, &tmp,
19153                      (mp_int*)rsa->dmp1->internal);
19154 
19155     if (err != MP_OKAY) {
19156         WOLFSSL_MSG("mp_mod error");
19157     }
19158     else
19159         err = mp_sub_d((mp_int*)rsa->q->internal, 1, &tmp);
19160     if (err != MP_OKAY) {
19161         WOLFSSL_MSG("mp_sub_d error");
19162     }
19163     else
19164         err = mp_mod((mp_int*)rsa->d->internal, &tmp,
19165                      (mp_int*)rsa->dmq1->internal);
19166 
19167     mp_clear(&tmp);
19168 
19169     if (err == MP_OKAY)
19170         return SSL_SUCCESS;
19171     else
19172         return SSL_FATAL_ERROR;
19173 }
19174 #endif /* NO_RSA */
19175 
19176 
19177 void wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen,
19178                   const EVP_MD* type)
19179 {
19180     WOLFSSL_MSG("wolfSSL_HMAC_Init");
19181 
19182     if (ctx == NULL) {
19183         WOLFSSL_MSG("no ctx on init");
19184         return;
19185     }
19186 
19187     if (type) {
19188         WOLFSSL_MSG("init has type");
19189 
19190         if (XSTRNCMP(type, "MD5", 3) == 0) {
19191             WOLFSSL_MSG("md5 hmac");
19192             ctx->type = MD5;
19193         }
19194         else if (XSTRNCMP(type, "SHA256", 6) == 0) {
19195             WOLFSSL_MSG("sha256 hmac");
19196             ctx->type = SHA256;
19197         }
19198 
19199         /* has to be last since would pick or 256, 384, or 512 too */
19200         else if (XSTRNCMP(type, "SHA", 3) == 0) {
19201             WOLFSSL_MSG("sha hmac");
19202             ctx->type = SHA;
19203         }
19204         else {
19205             WOLFSSL_MSG("bad init type");
19206         }
19207     }
19208 
19209     if (key && keylen) {
19210         WOLFSSL_MSG("keying hmac");
19211 
19212         if (wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID) == 0) {
19213             wc_HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key,
19214                                                         (word32)keylen);
19215         }
19216         /* OpenSSL compat, no error */
19217     }
19218 }
19219 
19220 int wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX* ctx, const void* key, int len,
19221                          const EVP_MD* md, void* impl)
19222 {
19223     (void)impl;
19224     wolfSSL_HMAC_Init(ctx, key, len, md);
19225     return 1;
19226 }
19227 
19228 
19229 void wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, const unsigned char* data,
19230                     int len)
19231 {
19232     WOLFSSL_MSG("wolfSSL_HMAC_Update");
19233 
19234     if (ctx && data) {
19235         WOLFSSL_MSG("updating hmac");
19236         wc_HmacUpdate(&ctx->hmac, data, (word32)len);
19237         /* OpenSSL compat, no error */
19238     }
19239 }
19240 
19241 
19242 void wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash,
19243                    unsigned int* len)
19244 {
19245     WOLFSSL_MSG("wolfSSL_HMAC_Final");
19246 
19247     if (ctx && hash) {
19248         WOLFSSL_MSG("final hmac");
19249         wc_HmacFinal(&ctx->hmac, hash);
19250         /* OpenSSL compat, no error */
19251 
19252         if (len) {
19253             WOLFSSL_MSG("setting output len");
19254             switch (ctx->type) {
19255                 case MD5:
19256                     *len = MD5_DIGEST_SIZE;
19257                     break;
19258 
19259                 case SHA:
19260                     *len = SHA_DIGEST_SIZE;
19261                     break;
19262 
19263                 case SHA256:
19264                     *len = SHA256_DIGEST_SIZE;
19265                     break;
19266 
19267                 default:
19268                     WOLFSSL_MSG("bad hmac type");
19269             }
19270         }
19271     }
19272 }
19273 
19274 
19275 void wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx)
19276 {
19277     WOLFSSL_MSG("wolfSSL_HMAC_cleanup");
19278 
19279     if (ctx)
19280         wc_HmacFree(&ctx->hmac);
19281 }
19282 
19283 
19284 const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id)
19285 {
19286     WOLFSSL_MSG("wolfSSL_get_digestbynid");
19287 
19288     switch(id) {
19289 #ifndef NO_MD5
19290         case NID_md5:
19291             return wolfSSL_EVP_md5();
19292 #endif
19293 #ifndef NO_SHA
19294         case NID_sha1:
19295             return wolfSSL_EVP_sha1();
19296 #endif
19297         default:
19298             WOLFSSL_MSG("Bad digest id value");
19299     }
19300 
19301     return NULL;
19302 }
19303 
19304 
19305 WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY* key)
19306 {
19307     (void)key;
19308     WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_RSA not implemented");
19309 
19310     return NULL;
19311 }
19312 
19313 
19314 WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY* key)
19315 {
19316     (void)key;
19317     WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_DSA not implemented");
19318 
19319     return NULL;
19320 }
19321 
19322 
19323 WOLFSSL_EC_KEY* wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* key)
19324 {
19325     (void)key;
19326     WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_EC_KEY not implemented");
19327 
19328     return NULL;
19329 }
19330 
19331 
19332 void* wolfSSL_EVP_X_STATE(const WOLFSSL_EVP_CIPHER_CTX* ctx)
19333 {
19334     WOLFSSL_MSG("wolfSSL_EVP_X_STATE");
19335 
19336     if (ctx) {
19337         switch (ctx->cipherType) {
19338             case ARC4_TYPE:
19339                 WOLFSSL_MSG("returning arc4 state");
19340                 return (void*)&ctx->cipher.arc4.x;
19341 
19342             default:
19343                 WOLFSSL_MSG("bad x state type");
19344                 return 0;
19345         }
19346     }
19347 
19348     return NULL;
19349 }
19350 
19351 
19352 int wolfSSL_EVP_X_STATE_LEN(const WOLFSSL_EVP_CIPHER_CTX* ctx)
19353 {
19354     WOLFSSL_MSG("wolfSSL_EVP_X_STATE_LEN");
19355 
19356     if (ctx) {
19357         switch (ctx->cipherType) {
19358             case ARC4_TYPE:
19359                 WOLFSSL_MSG("returning arc4 state size");
19360                 return sizeof(Arc4);
19361 
19362             default:
19363                 WOLFSSL_MSG("bad x state type");
19364                 return 0;
19365         }
19366     }
19367 
19368     return 0;
19369 }
19370 
19371 
19372 #ifndef NO_DES3
19373 
19374 void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
19375                             unsigned char* iv, int len)
19376 {
19377     (void)len;
19378 
19379     WOLFSSL_MSG("wolfSSL_3des_iv");
19380 
19381     if (ctx == NULL || iv == NULL) {
19382         WOLFSSL_MSG("Bad function argument");
19383         return;
19384     }
19385 
19386     if (doset)
19387         wc_Des3_SetIV(&ctx->cipher.des3, iv);  /* OpenSSL compat, no ret */
19388     else
19389         XMEMCPY(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
19390 }
19391 
19392 #endif /* NO_DES3 */
19393 
19394 
19395 #ifndef NO_AES
19396 
19397 void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
19398                       unsigned char* iv, int len)
19399 {
19400     (void)len;
19401 
19402     WOLFSSL_MSG("wolfSSL_aes_ctr_iv");
19403 
19404     if (ctx == NULL || iv == NULL) {
19405         WOLFSSL_MSG("Bad function argument");
19406         return;
19407     }
19408 
19409     if (doset)
19410         wc_AesSetIV(&ctx->cipher.aes, iv);  /* OpenSSL compat, no ret */
19411     else
19412         XMEMCPY(iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
19413 }
19414 
19415 #endif /* NO_AES */
19416 
19417 
19418 const WOLFSSL_EVP_MD* wolfSSL_EVP_ripemd160(void)
19419 {
19420     WOLFSSL_MSG("wolfSSL_ripemd160");
19421 
19422     return NULL;
19423 }
19424 
19425 
19426 int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* type)
19427 {
19428     WOLFSSL_MSG("wolfSSL_EVP_MD_size");
19429 
19430     if (type == NULL) {
19431         WOLFSSL_MSG("No md type arg");
19432         return BAD_FUNC_ARG;
19433     }
19434 
19435     if (XSTRNCMP(type, "SHA256", 6) == 0) {
19436         return SHA256_DIGEST_SIZE;
19437     }
19438 #ifndef NO_MD5
19439     else if (XSTRNCMP(type, "MD5", 3) == 0) {
19440         return MD5_DIGEST_SIZE;
19441     }
19442 #endif
19443 #ifdef WOLFSSL_SHA224
19444     else if (XSTRNCMP(type, "SHA224", 6) == 0) {
19445         return SHA224_DIGEST_SIZE;
19446     }
19447 #endif
19448 #ifdef WOLFSSL_SHA384
19449     else if (XSTRNCMP(type, "SHA384", 6) == 0) {
19450         return SHA384_DIGEST_SIZE;
19451     }
19452 #endif
19453 #ifdef WOLFSSL_SHA512
19454     else if (XSTRNCMP(type, "SHA512", 6) == 0) {
19455         return SHA512_DIGEST_SIZE;
19456     }
19457 #endif
19458 #ifndef NO_SHA
19459     /* has to be last since would pick or 256, 384, or 512 too */
19460     else if (XSTRNCMP(type, "SHA", 3) == 0) {
19461         return SHA_DIGEST_SIZE;
19462     }
19463 #endif
19464 
19465     return BAD_FUNC_ARG;
19466 }
19467 
19468 
19469 int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx)
19470 {
19471     WOLFSSL_MSG("wolfSSL_EVP_CIPHER_CTX_iv_length");
19472 
19473     switch (ctx->cipherType) {
19474 
19475         case AES_128_CBC_TYPE :
19476         case AES_192_CBC_TYPE :
19477         case AES_256_CBC_TYPE :
19478             WOLFSSL_MSG("AES CBC");
19479             return AES_BLOCK_SIZE;
19480 
19481 #ifdef WOLFSSL_AES_COUNTER
19482         case AES_128_CTR_TYPE :
19483         case AES_192_CTR_TYPE :
19484         case AES_256_CTR_TYPE :
19485             WOLFSSL_MSG("AES CTR");
19486             return AES_BLOCK_SIZE;
19487 #endif
19488 
19489         case DES_CBC_TYPE :
19490             WOLFSSL_MSG("DES CBC");
19491             return DES_BLOCK_SIZE;
19492 
19493         case DES_EDE3_CBC_TYPE :
19494             WOLFSSL_MSG("DES EDE3 CBC");
19495             return DES_BLOCK_SIZE;
19496 #ifdef HAVE_IDEA
19497         case IDEA_CBC_TYPE :
19498             WOLFSSL_MSG("IDEA CBC");
19499             return IDEA_BLOCK_SIZE;
19500 #endif
19501         case ARC4_TYPE :
19502             WOLFSSL_MSG("ARC4");
19503             return 0;
19504 
19505         case NULL_CIPHER_TYPE :
19506             WOLFSSL_MSG("NULL");
19507             return 0;
19508 
19509         default: {
19510             WOLFSSL_MSG("bad type");
19511         }
19512     }
19513     return 0;
19514 }
19515 
19516 int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER* cipher)
19517 {
19518     const char *name = (const char *)cipher;
19519     WOLFSSL_MSG("wolfSSL_EVP_CIPHER_iv_length");
19520 
19521 #ifndef NO_AES
19522     if ((XSTRNCMP(name, EVP_AES_128_CBC, XSTRLEN(EVP_AES_128_CBC)) == 0) ||
19523            (XSTRNCMP(name, EVP_AES_192_CBC, XSTRLEN(EVP_AES_192_CBC)) == 0) ||
19524            (XSTRNCMP(name, EVP_AES_256_CBC, XSTRLEN(EVP_AES_256_CBC)) == 0)) {
19525         return AES_BLOCK_SIZE;
19526     }
19527 #ifdef WOLFSSL_AES_COUNTER
19528     if ((XSTRNCMP(name, EVP_AES_128_CTR, XSTRLEN(EVP_AES_128_CTR)) == 0) ||
19529            (XSTRNCMP(name, EVP_AES_192_CTR, XSTRLEN(EVP_AES_192_CTR)) == 0) ||
19530            (XSTRNCMP(name, EVP_AES_256_CTR, XSTRLEN(EVP_AES_256_CTR)) == 0)) {
19531         return AES_BLOCK_SIZE;
19532     }
19533 #endif
19534 #endif
19535 
19536 #ifndef NO_DES3
19537     if ((XSTRNCMP(name, EVP_DES_CBC, XSTRLEN(EVP_DES_CBC)) == 0) ||
19538            (XSTRNCMP(name, EVP_DES_EDE3_CBC, XSTRLEN(EVP_DES_EDE3_CBC)) == 0)) {
19539         return DES_BLOCK_SIZE;
19540     }
19541 #endif
19542 
19543 #ifdef HAVE_IDEA
19544     if (XSTRNCMP(name, EVP_IDEA_CBC, XSTRLEN(EVP_IDEA_CBC)) == 0)
19545         return IDEA_BLOCK_SIZE;
19546 #endif
19547 
19548     (void)name;
19549 
19550     return 0;
19551 }
19552 
19553 /* Free the dynamically allocated data.
19554  *
19555  * p  Pointer to dynamically allocated memory.
19556  */
19557 void wolfSSL_OPENSSL_free(void* p)
19558 {
19559     WOLFSSL_MSG("wolfSSL_OPENSSL_free");
19560 
19561     XFREE(p, NULL, DYNAMIC_TYPE_OPENSSL);
19562 }
19563 
19564 #if defined(WOLFSSL_KEY_GEN)
19565 
19566 static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher,
19567                          unsigned char* passwd, int passwdSz, byte **cipherInfo)
19568 {
19569     int ret, paddingSz;
19570     word32 idx, cipherInfoSz;
19571 #ifdef WOLFSSL_SMALL_STACK
19572     EncryptedInfo* info = NULL;
19573 #else
19574     EncryptedInfo  info[1];
19575 #endif
19576 
19577     WOLFSSL_ENTER("EncryptDerKey");
19578 
19579     if (der == NULL || derSz == NULL || cipher == NULL ||
19580         passwd == NULL || cipherInfo == NULL)
19581         return BAD_FUNC_ARG;
19582 
19583 #ifdef WOLFSSL_SMALL_STACK
19584     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
19585                                    DYNAMIC_TYPE_TMP_BUFFER);
19586     if (info == NULL) {
19587         WOLFSSL_MSG("malloc failed");
19588         return SSL_FAILURE;
19589     }
19590 #endif
19591     info->set      = 0;
19592     info->ctx      = NULL;
19593     info->consumed = 0;
19594 
19595     /* set iv size */
19596     if (XSTRNCMP(cipher, "DES", 3) == 0)
19597         info->ivSz = DES_IV_SIZE;
19598     else if (XSTRNCMP(cipher, "AES", 3) == 0)
19599         info->ivSz = AES_IV_SIZE;
19600     else {
19601         WOLFSSL_MSG("unsupported cipher");
19602 #ifdef WOLFSSL_SMALL_STACK
19603         XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19604 #endif
19605         return SSL_FAILURE;
19606     }
19607 
19608     /* set the cipher name on info */
19609     XSTRNCPY(info->name, cipher, NAME_SZ);
19610     info->name[NAME_SZ-1] = '\0'; /* null term */
19611 
19612     /* Generate a random salt */
19613     if (wolfSSL_RAND_bytes(info->iv, info->ivSz) != SSL_SUCCESS) {
19614         WOLFSSL_MSG("generate iv failed");
19615 #ifdef WOLFSSL_SMALL_STACK
19616         XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19617 #endif
19618         return SSL_FAILURE;
19619     }
19620 
19621     /* add the padding before encryption */
19622     paddingSz = ((*derSz)/info->ivSz + 1) * info->ivSz - (*derSz);
19623     if (paddingSz == 0)
19624         paddingSz = info->ivSz;
19625     XMEMSET(der+(*derSz), (byte)paddingSz, paddingSz);
19626     (*derSz) += paddingSz;
19627 
19628     /* encrypt buffer */
19629     if (wolfssl_encrypt_buffer_key(der, *derSz,
19630                                    passwd, passwdSz, info) != SSL_SUCCESS) {
19631         WOLFSSL_MSG("encrypt key failed");
19632 #ifdef WOLFSSL_SMALL_STACK
19633         XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19634 #endif
19635         return SSL_FAILURE;
19636     }
19637 
19638     /* create cipher info : 'cipher_name,Salt(hex)' */
19639     cipherInfoSz = (word32)(2*info->ivSz + XSTRLEN(info->name) + 2);
19640     *cipherInfo = (byte*)XMALLOC(cipherInfoSz, NULL,
19641                                 DYNAMIC_TYPE_TMP_BUFFER);
19642     if (*cipherInfo == NULL) {
19643         WOLFSSL_MSG("malloc failed");
19644 #ifdef WOLFSSL_SMALL_STACK
19645         XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19646 #endif
19647         return SSL_FAILURE;
19648     }
19649     XSTRNCPY((char*)*cipherInfo, info->name, cipherInfoSz);
19650     XSTRNCAT((char*)*cipherInfo, ",", 1);
19651 
19652     idx = (word32)XSTRLEN((char*)*cipherInfo);
19653     cipherInfoSz -= idx;
19654     ret = Base16_Encode(info->iv, info->ivSz, *cipherInfo+idx, &cipherInfoSz);
19655 
19656 #ifdef WOLFSSL_SMALL_STACK
19657     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19658 #endif
19659     if (ret != 0) {
19660         WOLFSSL_MSG("Base16_Encode failed");
19661         XFREE(*cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19662         return SSL_FAILURE;
19663     }
19664 
19665     return SSL_SUCCESS;
19666 }
19667 #endif /* defined(WOLFSSL_KEY_GEN) */
19668 
19669 #if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN)
19670 
19671 int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
19672                                         const WOLFSSL_EVP_CIPHER* cipher,
19673                                         unsigned char* passwd, int len,
19674                                         pem_password_cb* cb, void* arg)
19675 {
19676     byte* keyDer;
19677     int pemSz;
19678     int type;
19679     int ret;
19680 
19681     (void)cipher;
19682     (void)passwd;
19683     (void)len;
19684     (void)cb;
19685     (void)arg;
19686 
19687     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PrivateKey");
19688 
19689     if (bio == NULL || key == NULL) {
19690         return SSL_FAILURE;
19691     }
19692 
19693     keyDer = (byte*)key->pkey.ptr;
19694 
19695     switch (key->type) {
19696         case EVP_PKEY_RSA:
19697             type = PRIVATEKEY_TYPE;
19698             break;
19699 
19700 #ifndef NO_DSA
19701         case EVP_PKEY_DSA:
19702             type = DSA_PRIVATEKEY_TYPE;
19703             break;
19704 #endif
19705 
19706         case EVP_PKEY_EC:
19707             type = ECC_PRIVATEKEY_TYPE;
19708             break;
19709 
19710         default:
19711             WOLFSSL_MSG("Unknown Key type!");
19712             type = PRIVATEKEY_TYPE;
19713     }
19714 
19715     pemSz = wc_DerToPem(keyDer, key->pkey_sz, NULL, 0, type);
19716     if (pemSz < 0) {
19717         WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", pemSz);
19718         return SSL_FAILURE;
19719     }
19720     if (bio->mem != NULL) {
19721         XFREE(bio->mem, NULL, DYNAMIC_TYPE_OPENSSL);
19722     }
19723     bio->mem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_OPENSSL);
19724     bio->memLen = pemSz;
19725 
19726     ret = wc_DerToPemEx(keyDer, key->pkey_sz, bio->mem, bio->memLen,
19727                                 NULL, type);
19728     if (ret < 0) {
19729         WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", ret);
19730         return SSL_FAILURE;
19731     }
19732 
19733     return SSL_SUCCESS;
19734 }
19735 #endif /* defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) */
19736 
19737 #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
19738 
19739 /* return code compliant with OpenSSL :
19740  *   1 if success, 0 if error
19741  */
19742 int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher,
19743                                         unsigned char* passwd, int passwdSz,
19744                                         unsigned char **pem, int *plen)
19745 {
19746     byte *derBuf, *tmp, *cipherInfo = NULL;
19747     int  der_max_len = 0, derSz = 0;
19748 
19749     WOLFSSL_ENTER("wolfSSL_PEM_write_mem_RSAPrivateKey");
19750 
19751     if (pem == NULL || plen == NULL || rsa == NULL || rsa->internal == NULL) {
19752         WOLFSSL_MSG("Bad function arguments");
19753         return SSL_FAILURE;
19754     }
19755 
19756     if (rsa->inSet == 0) {
19757         WOLFSSL_MSG("No RSA internal set, do it");
19758 
19759         if (SetRsaInternal(rsa) != SSL_SUCCESS) {
19760             WOLFSSL_MSG("SetRsaInternal failed");
19761             return SSL_FAILURE;
19762         }
19763     }
19764 
19765     /* 5 > size of n, d, p, q, d%(p-1), d(q-1), 1/q%p, e + ASN.1 additional
19766      *  informations
19767      */
19768     der_max_len = 5 * wolfSSL_RSA_size(rsa) + AES_BLOCK_SIZE;
19769 
19770     derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19771     if (derBuf == NULL) {
19772         WOLFSSL_MSG("malloc failed");
19773         return SSL_FAILURE;
19774     }
19775 
19776     /* Key to DER */
19777     derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, derBuf, der_max_len);
19778     if (derSz < 0) {
19779         WOLFSSL_MSG("wc_RsaKeyToDer failed");
19780         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19781         return SSL_FAILURE;
19782     }
19783 
19784     /* encrypt DER buffer if required */
19785     if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
19786         int ret;
19787 
19788         ret = EncryptDerKey(derBuf, &derSz, cipher,
19789                             passwd, passwdSz, &cipherInfo);
19790         if (ret != SSL_SUCCESS) {
19791             WOLFSSL_MSG("EncryptDerKey failed");
19792             XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19793             return ret;
19794         }
19795 
19796         /* tmp buffer with a max size */
19797         *plen = (derSz * 2) + sizeof(BEGIN_RSA_PRIV) +
19798                 sizeof(END_RSA_PRIV) + HEADER_ENCRYPTED_KEY_SIZE;
19799     }
19800     else /* tmp buffer with a max size */
19801         *plen = (derSz * 2) + sizeof(BEGIN_RSA_PRIV) + sizeof(END_RSA_PRIV);
19802 
19803     tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19804     if (tmp == NULL) {
19805         WOLFSSL_MSG("malloc failed");
19806         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19807         if (cipherInfo != NULL)
19808             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19809         return SSL_FAILURE;
19810     }
19811 
19812     /* DER to PEM */
19813     *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, PRIVATEKEY_TYPE);
19814     if (*plen <= 0) {
19815         WOLFSSL_MSG("wc_DerToPemEx failed");
19816         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19817         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19818         if (cipherInfo != NULL)
19819             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19820         return SSL_FAILURE;
19821     }
19822     XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19823     if (cipherInfo != NULL)
19824         XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19825 
19826     *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY);
19827     if (*pem == NULL) {
19828         WOLFSSL_MSG("malloc failed");
19829         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19830         return SSL_FAILURE;
19831     }
19832     XMEMSET(*pem, 0, (*plen)+1);
19833 
19834     if (XMEMCPY(*pem, tmp, *plen) == NULL) {
19835         WOLFSSL_MSG("XMEMCPY failed");
19836         XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
19837         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19838         return SSL_FAILURE;
19839     }
19840     XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19841 
19842     return SSL_SUCCESS;
19843 }
19844 
19845 
19846 #ifndef NO_FILESYSTEM
19847 /* return code compliant with OpenSSL :
19848  *   1 if success, 0 if error
19849  */
19850 int wolfSSL_PEM_write_RSAPrivateKey(FILE *fp, WOLFSSL_RSA *rsa,
19851                                     const EVP_CIPHER *enc,
19852                                     unsigned char *kstr, int klen,
19853                                     pem_password_cb *cb, void *u)
19854 {
19855     byte *pem;
19856     int  plen, ret;
19857 
19858     (void)cb;
19859     (void)u;
19860 
19861     WOLFSSL_MSG("wolfSSL_PEM_write_RSAPrivateKey");
19862 
19863     if (fp == NULL || rsa == NULL || rsa->internal == NULL) {
19864         WOLFSSL_MSG("Bad function arguments");
19865         return SSL_FAILURE;
19866     }
19867 
19868     ret = wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, enc, kstr, klen, &pem, &plen);
19869     if (ret != SSL_SUCCESS) {
19870         WOLFSSL_MSG("wolfSSL_PEM_write_mem_RSAPrivateKey failed");
19871         return SSL_FAILURE;
19872     }
19873 
19874     ret = (int)XFWRITE(pem, plen, 1, fp);
19875     if (ret != 1) {
19876         WOLFSSL_MSG("RSA private key file write failed");
19877         return SSL_FAILURE;
19878     }
19879 
19880     XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
19881     return SSL_SUCCESS;
19882 }
19883 #endif /* NO_FILESYSTEM */
19884 
19885 int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, RSA* rsa,
19886                                         const EVP_CIPHER* cipher,
19887                                         unsigned char* passwd, int len,
19888                                         pem_password_cb* cb, void* arg)
19889 {
19890     (void)bio;
19891     (void)rsa;
19892     (void)cipher;
19893     (void)passwd;
19894     (void)len;
19895     (void)cb;
19896     (void)arg;
19897 
19898     WOLFSSL_MSG("wolfSSL_PEM_write_bio_RSAPrivateKey not implemented");
19899 
19900     return SSL_FAILURE;
19901 }
19902 #endif /* defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) */
19903 
19904 #ifdef HAVE_ECC
19905 
19906 /* EC_POINT Openssl -> WolfSSL */
19907 static int SetECPointInternal(WOLFSSL_EC_POINT *p)
19908 {
19909     ecc_point* point;
19910     WOLFSSL_ENTER("SetECPointInternal");
19911 
19912     if (p == NULL || p->internal == NULL) {
19913         WOLFSSL_MSG("ECPoint NULL error");
19914         return SSL_FATAL_ERROR;
19915     }
19916 
19917     point = (ecc_point*)p->internal;
19918 
19919     if (p->X != NULL && SetIndividualInternal(p->X, point->x) != SSL_SUCCESS) {
19920         WOLFSSL_MSG("ecc point X error");
19921         return SSL_FATAL_ERROR;
19922     }
19923 
19924     if (p->Y != NULL && SetIndividualInternal(p->Y, point->y) != SSL_SUCCESS) {
19925         WOLFSSL_MSG("ecc point Y error");
19926         return SSL_FATAL_ERROR;
19927     }
19928 
19929     if (p->Z != NULL && SetIndividualInternal(p->Z, point->z) != SSL_SUCCESS) {
19930         WOLFSSL_MSG("ecc point Z error");
19931         return SSL_FATAL_ERROR;
19932     }
19933 
19934     p->inSet = 1;
19935 
19936     return SSL_SUCCESS;
19937 }
19938 
19939 /* EC_POINT WolfSSL -> OpenSSL */
19940 static int SetECPointExternal(WOLFSSL_EC_POINT *p)
19941 {
19942     ecc_point* point;
19943 
19944     WOLFSSL_ENTER("SetECPointExternal");
19945 
19946     if (p == NULL || p->internal == NULL) {
19947         WOLFSSL_MSG("ECPoint NULL error");
19948         return SSL_FATAL_ERROR;
19949     }
19950 
19951     point = (ecc_point*)p->internal;
19952 
19953     if (SetIndividualExternal(&p->X, point->x) != SSL_SUCCESS) {
19954         WOLFSSL_MSG("ecc point X error");
19955         return SSL_FATAL_ERROR;
19956     }
19957 
19958     if (SetIndividualExternal(&p->Y, point->y) != SSL_SUCCESS) {
19959         WOLFSSL_MSG("ecc point Y error");
19960         return SSL_FATAL_ERROR;
19961     }
19962 
19963     if (SetIndividualExternal(&p->Z, point->z) != SSL_SUCCESS) {
19964         WOLFSSL_MSG("ecc point Z error");
19965         return SSL_FATAL_ERROR;
19966     }
19967 
19968     p->exSet = 1;
19969 
19970     return SSL_SUCCESS;
19971 }
19972 
19973 /* EC_KEY wolfSSL -> OpenSSL */
19974 static int SetECKeyExternal(WOLFSSL_EC_KEY* eckey)
19975 {
19976     ecc_key* key;
19977 
19978     WOLFSSL_ENTER("SetECKeyExternal");
19979 
19980     if (eckey == NULL || eckey->internal == NULL) {
19981         WOLFSSL_MSG("ec key NULL error");
19982         return SSL_FATAL_ERROR;
19983     }
19984 
19985     key = (ecc_key*)eckey->internal;
19986 
19987     /* set group (OID, nid and idx) */
19988     eckey->group->curve_oid = ecc_sets[key->idx].oidSum;
19989     eckey->group->curve_nid = ecc_sets[key->idx].id;
19990     eckey->group->curve_idx = key->idx;
19991 
19992     if (eckey->pub_key->internal != NULL) {
19993         /* set the internal public key */
19994         if (wc_ecc_copy_point(&key->pubkey,
19995                              (ecc_point*)eckey->pub_key->internal) != MP_OKAY) {
19996             WOLFSSL_MSG("SetECKeyExternal ecc_copy_point failed");
19997             return SSL_FATAL_ERROR;
19998         }
19999 
20000         /* set the external pubkey (point) */
20001         if (SetECPointExternal(eckey->pub_key) != SSL_SUCCESS) {
20002             WOLFSSL_MSG("SetECKeyExternal SetECPointExternal failed");
20003             return SSL_FATAL_ERROR;
20004         }
20005     }
20006 
20007     /* set the external privkey */
20008     if (key->type == ECC_PRIVATEKEY) {
20009         if (SetIndividualExternal(&eckey->priv_key, &key->k) != SSL_SUCCESS) {
20010             WOLFSSL_MSG("ec priv key error");
20011             return SSL_FATAL_ERROR;
20012         }
20013     }
20014 
20015     eckey->exSet = 1;
20016 
20017     return SSL_SUCCESS;
20018 }
20019 
20020 /* EC_KEY Openssl -> WolfSSL */
20021 static int SetECKeyInternal(WOLFSSL_EC_KEY* eckey)
20022 {
20023     ecc_key* key;
20024 
20025     WOLFSSL_ENTER("SetECKeyInternal");
20026 
20027     if (eckey == NULL || eckey->internal == NULL) {
20028         WOLFSSL_MSG("ec key NULL error");
20029         return SSL_FATAL_ERROR;
20030     }
20031 
20032     key = (ecc_key*)eckey->internal;
20033 
20034     /* validate group */
20035     if ((eckey->group->curve_idx < 0) ||
20036         (wc_ecc_is_valid_idx(eckey->group->curve_idx) == 0)) {
20037         WOLFSSL_MSG("invalid curve idx");
20038         return SSL_FATAL_ERROR;
20039     }
20040 
20041     /* set group (idx of curve and corresponding domain parameters) */
20042     key->idx = eckey->group->curve_idx;
20043     key->dp = &ecc_sets[key->idx];
20044 
20045     /* set pubkey (point) */
20046     if (eckey->pub_key != NULL) {
20047         if (SetECPointInternal(eckey->pub_key) != SSL_SUCCESS) {
20048             WOLFSSL_MSG("ec key pub error");
20049             return SSL_FATAL_ERROR;
20050         }
20051 
20052         /* public key */
20053         key->type = ECC_PUBLICKEY;
20054     }
20055 
20056     /* set privkey */
20057     if (eckey->priv_key != NULL) {
20058         if (SetIndividualInternal(eckey->priv_key, &key->k) != SSL_SUCCESS) {
20059             WOLFSSL_MSG("ec key priv error");
20060             return SSL_FATAL_ERROR;
20061         }
20062 
20063         /* private key */
20064         key->type = ECC_PRIVATEKEY;
20065     }
20066 
20067     eckey->inSet = 1;
20068 
20069     return SSL_SUCCESS;
20070 }
20071 
20072 WOLFSSL_EC_POINT *wolfSSL_EC_KEY_get0_public_key(const WOLFSSL_EC_KEY *key)
20073 {
20074     WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_public_key");
20075 
20076     if (key == NULL) {
20077         WOLFSSL_MSG("wolfSSL_EC_KEY_get0_group Bad arguments");
20078         return NULL;
20079     }
20080 
20081     return key->pub_key;
20082 }
20083 
20084 const WOLFSSL_EC_GROUP *wolfSSL_EC_KEY_get0_group(const WOLFSSL_EC_KEY *key)
20085 {
20086     WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_group");
20087 
20088     if (key == NULL) {
20089         WOLFSSL_MSG("wolfSSL_EC_KEY_get0_group Bad arguments");
20090         return NULL;
20091     }
20092 
20093     return key->group;
20094 }
20095 
20096 
20097 /* return code compliant with OpenSSL :
20098  *   1 if success, 0 if error
20099  */
20100 int wolfSSL_EC_KEY_set_private_key(WOLFSSL_EC_KEY *key,
20101                                    const WOLFSSL_BIGNUM *priv_key)
20102 {
20103     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_private_key");
20104 
20105     if (key == NULL || priv_key == NULL) {
20106         WOLFSSL_MSG("Bad arguments");
20107         return SSL_FAILURE;
20108     }
20109 
20110     /* free key if previously set */
20111     if (key->priv_key != NULL)
20112         wolfSSL_BN_free(key->priv_key);
20113 
20114     key->priv_key = wolfSSL_BN_dup(priv_key);
20115     if (key->priv_key == NULL) {
20116         WOLFSSL_MSG("key ecc priv key NULL");
20117         return SSL_FAILURE;
20118     }
20119 
20120     if (SetECKeyInternal(key) != SSL_SUCCESS) {
20121         WOLFSSL_MSG("SetECKeyInternal failed");
20122         wolfSSL_BN_free(key->priv_key);
20123         return SSL_FAILURE;
20124     }
20125 
20126     return SSL_SUCCESS;
20127 }
20128 
20129 
20130 WOLFSSL_BIGNUM *wolfSSL_EC_KEY_get0_private_key(const WOLFSSL_EC_KEY *key)
20131 {
20132     WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_private_key");
20133 
20134     if (key == NULL) {
20135         WOLFSSL_MSG("wolfSSL_EC_KEY_get0_private_key Bad arguments");
20136         return NULL;
20137     }
20138 
20139     return key->priv_key;
20140 }
20141 
20142 WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid)
20143 {
20144     WOLFSSL_EC_KEY *key;
20145     int x;
20146 
20147     WOLFSSL_ENTER("wolfSSL_EC_KEY_new_by_curve_name");
20148 
20149     key = wolfSSL_EC_KEY_new();
20150     if (key == NULL) {
20151         WOLFSSL_MSG("wolfSSL_EC_KEY_new failure");
20152         return NULL;
20153     }
20154 
20155     /* set the nid of the curve */
20156     key->group->curve_nid = nid;
20157 
20158     /* search and set the corresponding internal curve idx */
20159     for (x = 0; ecc_sets[x].size != 0; x++)
20160         if (ecc_sets[x].id == key->group->curve_nid) {
20161             key->group->curve_idx = x;
20162             key->group->curve_oid = ecc_sets[x].oidSum;
20163             break;
20164         }
20165 
20166     return key;
20167 }
20168 
20169 static void InitwolfSSL_ECKey(WOLFSSL_EC_KEY* key)
20170 {
20171     if (key) {
20172         key->group    = NULL;
20173         key->pub_key  = NULL;
20174         key->priv_key = NULL;
20175         key->internal = NULL;
20176         key->inSet    = 0;
20177         key->exSet    = 0;
20178     }
20179 }
20180 
20181 WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void)
20182 {
20183     WOLFSSL_EC_KEY *external;
20184     ecc_key* key;
20185 
20186     WOLFSSL_ENTER("wolfSSL_EC_KEY_new");
20187 
20188     external = (WOLFSSL_EC_KEY*)XMALLOC(sizeof(WOLFSSL_EC_KEY), NULL,
20189                                         DYNAMIC_TYPE_ECC);
20190     if (external == NULL) {
20191         WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_KEY failure");
20192         return NULL;
20193     }
20194     XMEMSET(external, 0, sizeof(WOLFSSL_EC_KEY));
20195 
20196     InitwolfSSL_ECKey(external);
20197 
20198     external->internal = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL,
20199                                            DYNAMIC_TYPE_ECC);
20200     if (external->internal == NULL) {
20201         WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc ecc key failure");
20202         wolfSSL_EC_KEY_free(external);
20203         return NULL;
20204     }
20205     XMEMSET(external->internal, 0, sizeof(ecc_key));
20206 
20207     wc_ecc_init((ecc_key*)external->internal);
20208 
20209     /* public key */
20210     external->pub_key = (WOLFSSL_EC_POINT*)XMALLOC(sizeof(WOLFSSL_EC_POINT),
20211                                                    NULL, DYNAMIC_TYPE_ECC);
20212     if (external->pub_key == NULL) {
20213         WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_POINT failure");
20214         wolfSSL_EC_KEY_free(external);
20215         return NULL;
20216     }
20217     XMEMSET(external->pub_key, 0, sizeof(WOLFSSL_EC_POINT));
20218 
20219     key = (ecc_key*)external->internal;
20220     external->pub_key->internal = (ecc_point*)&key->pubkey;
20221 
20222     /* curve group */
20223     external->group = (WOLFSSL_EC_GROUP*)XMALLOC(sizeof(WOLFSSL_EC_GROUP), NULL,
20224                                                  DYNAMIC_TYPE_ECC);
20225     if (external->group == NULL) {
20226         WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_GROUP failure");
20227         wolfSSL_EC_KEY_free(external);
20228         return NULL;
20229     }
20230     XMEMSET(external->group, 0, sizeof(WOLFSSL_EC_GROUP));
20231 
20232     /* private key */
20233     external->priv_key = wolfSSL_BN_new();
20234     if (external->priv_key == NULL) {
20235         WOLFSSL_MSG("wolfSSL_BN_new failure");
20236         wolfSSL_EC_KEY_free(external);
20237         return NULL;
20238     }
20239 
20240     return external;
20241 }
20242 
20243 void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key)
20244 {
20245     WOLFSSL_ENTER("wolfSSL_EC_KEY_free");
20246 
20247     if (key != NULL) {
20248         if (key->internal != NULL) {
20249             wc_ecc_free((ecc_key*)key->internal);
20250             XFREE(key->internal, NULL, DYNAMIC_TYPE_ECC);
20251         }
20252         wolfSSL_BN_free(key->priv_key);
20253         wolfSSL_EC_POINT_free(key->pub_key);
20254         wolfSSL_EC_GROUP_free(key->group);
20255         InitwolfSSL_ECKey(key); /* set back to NULLs for safety */
20256 
20257         XFREE(key, NULL, DYNAMIC_TYPE_ECC);
20258         key = NULL;
20259     }
20260 }
20261 
20262 int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group)
20263 {
20264     (void)key;
20265     (void)group;
20266 
20267     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_group");
20268     WOLFSSL_MSG("wolfSSL_EC_KEY_set_group TBD");
20269 
20270     return -1;
20271 }
20272 
20273 int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key)
20274 {
20275     int     initTmpRng = 0;
20276     WC_RNG* rng = NULL;
20277 #ifdef WOLFSSL_SMALL_STACK
20278     WC_RNG* tmpRNG = NULL;
20279 #else
20280     WC_RNG  tmpRNG[1];
20281 #endif
20282 
20283     WOLFSSL_ENTER("wolfSSL_EC_KEY_generate_key");
20284 
20285     if (key == NULL || key->internal == NULL ||
20286         key->group == NULL || key->group->curve_idx < 0) {
20287         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key Bad arguments");
20288         return 0;
20289     }
20290 
20291 #ifdef WOLFSSL_SMALL_STACK
20292     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
20293     if (tmpRNG == NULL)
20294         return 0;
20295 #endif
20296 
20297     if (wc_InitRng(tmpRNG) == 0) {
20298         rng = tmpRNG;
20299         initTmpRng = 1;
20300     }
20301     else {
20302         WOLFSSL_MSG("Bad RNG Init, trying global");
20303         if (initGlobalRNG == 0)
20304             WOLFSSL_MSG("Global RNG no Init");
20305         else
20306             rng = &globalRNG;
20307     }
20308 
20309     if (rng == NULL) {
20310         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to set RNG");
20311 #ifdef WOLFSSL_SMALL_STACK
20312         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20313 #endif
20314         return 0;
20315     }
20316 
20317     if (wc_ecc_make_key_ex(rng, 0, (ecc_key*)key->internal,
20318                                         key->group->curve_nid) != MP_OKAY) {
20319         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key wc_ecc_make_key failed");
20320 #ifdef WOLFSSL_SMALL_STACK
20321         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20322 #endif
20323         return 0;
20324     }
20325 
20326     if (initTmpRng)
20327         wc_FreeRng(tmpRNG);
20328 #ifdef WOLFSSL_SMALL_STACK
20329     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20330 #endif
20331 
20332     if (SetECKeyExternal(key) != SSL_SUCCESS) {
20333         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key SetECKeyExternal failed");
20334         return 0;
20335     }
20336 
20337     return 1;
20338 }
20339 
20340 void wolfSSL_EC_KEY_set_asn1_flag(WOLFSSL_EC_KEY *key, int asn1_flag)
20341 {
20342     (void)key;
20343     (void)asn1_flag;
20344 
20345     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_asn1_flag");
20346     WOLFSSL_MSG("wolfSSL_EC_KEY_set_asn1_flag TBD");
20347 }
20348 
20349 /* return code compliant with OpenSSL :
20350  *   1 if success, 0 if error
20351  */
20352 int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key,
20353                                   const WOLFSSL_EC_POINT *pub)
20354 {
20355     ecc_point *pub_p, *key_p;
20356 
20357     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_public_key");
20358 
20359     if (key == NULL || key->internal == NULL ||
20360         pub == NULL || pub->internal == NULL) {
20361         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order Bad arguments");
20362         return SSL_FAILURE;
20363     }
20364 
20365     if (key->inSet == 0) {
20366         if (SetECKeyInternal(key) != SSL_SUCCESS) {
20367             WOLFSSL_MSG("SetECKeyInternal failed");
20368             return SSL_FAILURE;
20369         }
20370     }
20371 
20372     if (pub->inSet == 0) {
20373         if (SetECPointInternal((WOLFSSL_EC_POINT *)pub) != SSL_SUCCESS) {
20374             WOLFSSL_MSG("SetECPointInternal failed");
20375             return SSL_FAILURE;
20376         }
20377     }
20378 
20379     pub_p = (ecc_point*)pub->internal;
20380     key_p = (ecc_point*)key->pub_key->internal;
20381 
20382     /* create new point if required */
20383     if (key_p == NULL)
20384         key_p = wc_ecc_new_point();
20385 
20386     if (key_p == NULL) {
20387         WOLFSSL_MSG("key ecc point NULL");
20388         return SSL_FAILURE;
20389     }
20390 
20391     if (wc_ecc_copy_point(pub_p, key_p) != MP_OKAY) {
20392         WOLFSSL_MSG("ecc_copy_point failure");
20393         return SSL_FAILURE;
20394     }
20395 
20396     if (SetECKeyExternal(key) != SSL_SUCCESS) {
20397         WOLFSSL_MSG("SetECKeyInternal failed");
20398         return SSL_FAILURE;
20399     }
20400 
20401 #if defined(DEBUG_WOLFSSL) && !defined(NO_FILESYSTEM)
20402     wolfssl_EC_POINT_dump("pub", pub);
20403     wolfssl_EC_POINT_dump("key->pub_key", key->pub_key);
20404 #endif
20405     return SSL_SUCCESS;
20406 }
20407 /* End EC_KEY */
20408 
20409 #if defined(DEBUG_WOLFSSL) && !defined(NO_FILESYSTEM)
20410 void wolfssl_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *p)
20411 {
20412     char *num;
20413 
20414     WOLFSSL_ENTER("wolfssl_EC_POINT_dump");
20415 
20416     if (p == NULL) {
20417         fprintf(stderr, "%s = NULL", msg);
20418         return ;
20419     }
20420 
20421     fprintf(stderr, "%s:\n\tinSet=%d, exSet=%d\n", msg, p->inSet, p->exSet);
20422     num = wolfSSL_BN_bn2hex(p->X);
20423     fprintf(stderr, "\tX = %s\n", num);
20424     XFREE(num, NULL, DYNAMIC_TYPE_ECC);
20425     num = wolfSSL_BN_bn2hex(p->Y);
20426     fprintf(stderr, "\tY = %s\n", num);
20427     XFREE(num, NULL, DYNAMIC_TYPE_ECC);
20428 }
20429 #endif
20430 
20431 /* Start EC_GROUP */
20432 
20433 /* return code compliant with OpenSSL :
20434  *   0 if equal, 1 if not and -1 in case of error
20435  */
20436 int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b,
20437                          WOLFSSL_BN_CTX *ctx)
20438 {
20439     (void)ctx;
20440 
20441     WOLFSSL_ENTER("wolfSSL_EC_GROUP_cmp");
20442 
20443     if (a == NULL || b == NULL) {
20444         WOLFSSL_MSG("wolfSSL_EC_GROUP_cmp Bad arguments");
20445         return SSL_FATAL_ERROR;
20446     }
20447 
20448     /* ok */
20449     if ((a->curve_idx == b->curve_idx) && (a->curve_nid == b->curve_nid))
20450         return 0;
20451 
20452     /* ko */
20453     return 1;
20454 }
20455 
20456 void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group)
20457 {
20458     WOLFSSL_ENTER("wolfSSL_EC_GROUP_free");
20459 
20460     XFREE(group, NULL, DYNAMIC_TYPE_ECC);
20461     group = NULL;
20462 }
20463 
20464 void wolfSSL_EC_GROUP_set_asn1_flag(WOLFSSL_EC_GROUP *group, int flag)
20465 {
20466     (void)group;
20467     (void)flag;
20468 
20469     WOLFSSL_ENTER("wolfSSL_EC_GROUP_set_asn1_flag");
20470     WOLFSSL_MSG("wolfSSL_EC_GROUP_set_asn1_flag TBD");
20471 }
20472 
20473 WOLFSSL_EC_GROUP *wolfSSL_EC_GROUP_new_by_curve_name(int nid)
20474 {
20475     WOLFSSL_EC_GROUP *g;
20476     int x;
20477 
20478     WOLFSSL_ENTER("wolfSSL_EC_GROUP_new_by_curve_name");
20479 
20480     /* curve group */
20481     g = (WOLFSSL_EC_GROUP*) XMALLOC(sizeof(WOLFSSL_EC_GROUP), NULL,
20482                                     DYNAMIC_TYPE_ECC);
20483     if (g == NULL) {
20484         WOLFSSL_MSG("wolfSSL_EC_GROUP_new_by_curve_name malloc failure");
20485         return NULL;
20486     }
20487     XMEMSET(g, 0, sizeof(WOLFSSL_EC_GROUP));
20488 
20489     /* set the nid of the curve */
20490     g->curve_nid = nid;
20491 
20492     /* search and set the corresponding internal curve idx */
20493     for (x = 0; ecc_sets[x].size != 0; x++)
20494         if (ecc_sets[x].id == g->curve_nid) {
20495             g->curve_idx = x;
20496             g->curve_oid = ecc_sets[x].oidSum;
20497             break;
20498         }
20499 
20500     return g;
20501 }
20502 
20503 /* return code compliant with OpenSSL :
20504  *   the curve nid if success, 0 if error
20505  */
20506 int wolfSSL_EC_GROUP_get_curve_name(const WOLFSSL_EC_GROUP *group)
20507 {
20508     WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_curve_name");
20509 
20510     if (group == NULL) {
20511         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_curve_name Bad arguments");
20512         return SSL_FAILURE;
20513     }
20514 
20515     return group->curve_nid;
20516 }
20517 
20518 /* return code compliant with OpenSSL :
20519  *   the degree of the curve if success, 0 if error
20520  */
20521 int wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP *group)
20522 {
20523     WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_degree");
20524 
20525     if (group == NULL || group->curve_idx < 0) {
20526         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_degree Bad arguments");
20527         return SSL_FAILURE;
20528     }
20529 
20530     switch(group->curve_nid) {
20531         case NID_secp112r1:
20532         case NID_secp112r2:
20533             return 112;
20534         case NID_secp128r1:
20535         case NID_secp128r2:
20536             return 128;
20537         case NID_secp160k1:
20538         case NID_secp160r1:
20539         case NID_secp160r2:
20540         case NID_brainpoolP160r1:
20541             return 160;
20542         case NID_secp192k1:
20543         case NID_brainpoolP192r1:
20544         case NID_X9_62_prime192v1:
20545             return 192;
20546         case NID_secp224k1:
20547         case NID_secp224r1:
20548         case NID_brainpoolP224r1:
20549             return 224;
20550         case NID_secp256k1:
20551         case NID_brainpoolP256r1:
20552         case NID_X9_62_prime256v1:
20553             return 256;
20554         case NID_brainpoolP320r1:
20555             return 320;
20556         case NID_secp384r1:
20557         case NID_brainpoolP384r1:
20558             return 384;
20559         case NID_secp521r1:
20560         case NID_brainpoolP512r1:
20561             return 521;
20562         default:
20563             return SSL_FAILURE;
20564     }
20565 }
20566 
20567 /* return code compliant with OpenSSL :
20568  *   1 if success, 0 if error
20569  */
20570 int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group,
20571                                WOLFSSL_BIGNUM *order, WOLFSSL_BN_CTX *ctx)
20572 {
20573     (void)ctx;
20574 
20575     if (group == NULL || order == NULL || order->internal == NULL) {
20576         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order NULL error");
20577         return SSL_FAILURE;
20578     }
20579 
20580     if (mp_init((mp_int*)order->internal) != MP_OKAY) {
20581         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_init failure");
20582         return SSL_FAILURE;
20583     }
20584 
20585     if (mp_read_radix((mp_int*)order->internal,
20586                       ecc_sets[group->curve_idx].order, 16) != MP_OKAY) {
20587         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_read order failure");
20588         mp_clear((mp_int*)order->internal);
20589         return SSL_FAILURE;
20590     }
20591 
20592     return SSL_SUCCESS;
20593 }
20594 /* End EC_GROUP */
20595 
20596 /* Start EC_POINT */
20597 
20598 /* return code compliant with OpenSSL :
20599  *   1 if success, 0 if error
20600  */
20601 int wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP *group,
20602                         const WOLFSSL_EC_POINT *p,
20603                         unsigned char *out, unsigned int *len)
20604 {
20605     int err;
20606 
20607     WOLFSSL_ENTER("wolfSSL_ECPoint_i2d");
20608 
20609     if (group == NULL || p == NULL || len == NULL) {
20610         WOLFSSL_MSG("wolfSSL_ECPoint_i2d NULL error");
20611         return SSL_FAILURE;
20612     }
20613 
20614     if (p->inSet == 0) {
20615         WOLFSSL_MSG("No ECPoint internal set, do it");
20616 
20617         if (SetECPointInternal((WOLFSSL_EC_POINT *)p) != SSL_SUCCESS) {
20618             WOLFSSL_MSG("SetECPointInternal SetECPointInternal failed");
20619             return SSL_FAILURE;
20620         }
20621     }
20622 
20623 #if defined(DEBUG_WOLFSSL) && !defined(NO_FILESYSTEM)
20624     if (out != NULL) {
20625         wolfssl_EC_POINT_dump("i2d p", p);
20626     }
20627 #endif
20628     err = wc_ecc_export_point_der(group->curve_idx, (ecc_point*)p->internal,
20629                                   out, len);
20630     if (err != MP_OKAY && !(out == NULL && err == LENGTH_ONLY_E)) {
20631         WOLFSSL_MSG("wolfSSL_ECPoint_i2d wc_ecc_export_point_der failed");
20632         return SSL_FAILURE;
20633     }
20634 
20635     return SSL_SUCCESS;
20636 }
20637 
20638 /* return code compliant with OpenSSL :
20639  *   1 if success, 0 if error
20640  */
20641 int wolfSSL_ECPoint_d2i(unsigned char *in, unsigned int len,
20642                         const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *p)
20643 {
20644     WOLFSSL_ENTER("wolfSSL_ECPoint_d2i");
20645 
20646     if (group == NULL || p == NULL || p->internal == NULL || in == NULL) {
20647         WOLFSSL_MSG("wolfSSL_ECPoint_d2i NULL error");
20648         return SSL_FAILURE;
20649     }
20650 
20651     if (wc_ecc_import_point_der(in, len, group->curve_idx,
20652                                 (ecc_point*)p->internal) != MP_OKAY) {
20653         WOLFSSL_MSG("wc_ecc_import_point_der failed");
20654         return SSL_FAILURE;
20655     }
20656 
20657     if (p->exSet == 0) {
20658         WOLFSSL_MSG("No ECPoint external set, do it");
20659 
20660         if (SetECPointExternal(p) != SSL_SUCCESS) {
20661             WOLFSSL_MSG("SetECPointExternal failed");
20662             return SSL_FAILURE;
20663         }
20664     }
20665 
20666 #if defined(DEBUG_WOLFSSL) && !defined(NO_FILESYSTEM)
20667     wolfssl_EC_POINT_dump("d2i p", p);
20668 #endif
20669     return SSL_SUCCESS;
20670 }
20671 
20672 WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group)
20673 {
20674     WOLFSSL_EC_POINT *p;
20675 
20676     WOLFSSL_ENTER("wolfSSL_EC_POINT_new");
20677 
20678     if (group == NULL) {
20679         WOLFSSL_MSG("wolfSSL_EC_POINT_new NULL error");
20680         return NULL;
20681     }
20682 
20683     p = (WOLFSSL_EC_POINT *)XMALLOC(sizeof(WOLFSSL_EC_POINT), NULL,
20684                                     DYNAMIC_TYPE_ECC);
20685     if (p == NULL) {
20686         WOLFSSL_MSG("wolfSSL_EC_POINT_new malloc ecc point failure");
20687         return NULL;
20688     }
20689     XMEMSET(p, 0, sizeof(WOLFSSL_EC_POINT));
20690 
20691     p->internal = wc_ecc_new_point();
20692     if (p->internal == NULL) {
20693         WOLFSSL_MSG("ecc_new_point failure");
20694         XFREE(p, NULL, DYNAMIC_TYPE_ECC);
20695         return NULL;
20696     }
20697 
20698     return p;
20699 }
20700 
20701 /* return code compliant with OpenSSL :
20702  *   1 if success, 0 if error
20703  */
20704 int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group,
20705                                                 const WOLFSSL_EC_POINT *point,
20706                                                 WOLFSSL_BIGNUM *x,
20707                                                 WOLFSSL_BIGNUM *y,
20708                                                 WOLFSSL_BN_CTX *ctx)
20709 {
20710     (void)ctx;
20711 
20712     WOLFSSL_ENTER("wolfSSL_EC_POINT_get_affine_coordinates_GFp");
20713 
20714     if (group == NULL || point == NULL || point->internal == NULL ||
20715         x == NULL || y == NULL) {
20716         WOLFSSL_MSG("wolfSSL_EC_POINT_get_affine_coordinates_GFp NULL error");
20717         return SSL_FAILURE;
20718     }
20719 
20720     if (point->inSet == 0) {
20721         WOLFSSL_MSG("No ECPoint internal set, do it");
20722 
20723         if (SetECPointInternal((WOLFSSL_EC_POINT *)point) != SSL_SUCCESS) {
20724             WOLFSSL_MSG("SetECPointInternal failed");
20725             return SSL_FAILURE;
20726         }
20727     }
20728 
20729     BN_copy(x, point->X);
20730     BN_copy(y, point->Y);
20731 
20732     return SSL_SUCCESS;
20733 }
20734 
20735 /* return code compliant with OpenSSL :
20736  *   1 if success, 0 if error
20737  */
20738 int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r,
20739                          const WOLFSSL_BIGNUM *n, const WOLFSSL_EC_POINT *q,
20740                          const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
20741 {
20742     mp_int a, prime;
20743     int ret;
20744 
20745     (void)ctx;
20746     (void)n;
20747 
20748     WOLFSSL_ENTER("wolfSSL_EC_POINT_mul");
20749 
20750     if (group == NULL || r == NULL || r->internal == NULL ||
20751         q == NULL || q->internal == NULL || m == NULL) {
20752         WOLFSSL_MSG("wolfSSL_EC_POINT_mul NULL error");
20753         return SSL_FAILURE;
20754     }
20755 
20756     if (q->inSet == 0) {
20757         WOLFSSL_MSG("No ECPoint internal set, do it");
20758 
20759         if (SetECPointInternal((WOLFSSL_EC_POINT *)q) != SSL_SUCCESS) {
20760             WOLFSSL_MSG("SetECPointInternal q failed");
20761             return SSL_FAILURE;
20762         }
20763     }
20764 
20765     /* read the curve prime and a */
20766     if (mp_init_multi(&prime, &a, NULL, NULL, NULL, NULL) != MP_OKAY) {
20767         return SSL_FAILURE;
20768     }
20769 
20770     ret = mp_read_radix(&prime, ecc_sets[group->curve_idx].prime, 16);
20771     if (ret == MP_OKAY)
20772         ret = mp_read_radix(&a, ecc_sets[group->curve_idx].Af, 16);
20773 
20774     /* r = q * m % prime */
20775     if (ret == MP_OKAY)
20776         ret = wc_ecc_mulmod((mp_int*)m->internal, (ecc_point*)q->internal,
20777                       (ecc_point*)r->internal, &a, &prime, 1);
20778 
20779     mp_clear(&a);
20780     mp_clear(&prime);
20781 
20782     if (ret == MP_OKAY) {
20783         /* set the external value for the computed point */
20784         ret = SetECPointInternal(r);
20785         if (ret != SSL_SUCCESS) {
20786             WOLFSSL_MSG("SetECPointInternal r failed");
20787         }
20788     }
20789     else {
20790         ret = SSL_FAILURE;
20791     }
20792 
20793     return ret;
20794 }
20795 
20796 void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *p)
20797 {
20798     WOLFSSL_ENTER("wolfSSL_EC_POINT_clear_free");
20799 
20800     wolfSSL_EC_POINT_free(p);
20801 }
20802 
20803 /* return code compliant with OpenSSL :
20804  *   0 if equal, 1 if not and -1 in case of error
20805  */
20806 int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group,
20807                          const WOLFSSL_EC_POINT *a, const WOLFSSL_EC_POINT *b,
20808                          WOLFSSL_BN_CTX *ctx)
20809 {
20810     int ret;
20811 
20812     (void)ctx;
20813 
20814     WOLFSSL_ENTER("wolfSSL_EC_POINT_cmp");
20815 
20816     if (group == NULL || a == NULL || a->internal == NULL || b == NULL ||
20817         b->internal == NULL) {
20818         WOLFSSL_MSG("wolfSSL_EC_POINT_cmp Bad arguments");
20819         return SSL_FATAL_ERROR;
20820     }
20821 
20822     ret = wc_ecc_cmp_point((ecc_point*)a->internal, (ecc_point*)b->internal);
20823     if (ret == MP_EQ)
20824         return 0;
20825     else if (ret == MP_LT || ret == MP_GT)
20826         return 1;
20827 
20828     return SSL_FATAL_ERROR;
20829 }
20830 
20831 void wolfSSL_EC_POINT_free(WOLFSSL_EC_POINT *p)
20832 {
20833     WOLFSSL_ENTER("wolfSSL_EC_POINT_free");
20834 
20835     if (p != NULL) {
20836         if (p->internal == NULL) {
20837             wc_ecc_del_point((ecc_point*)p->internal);
20838             XFREE(p->internal, NULL, DYNAMIC_TYPE_ECC);
20839             p->internal = NULL;
20840         }
20841 
20842         wolfSSL_BN_free(p->X);
20843         wolfSSL_BN_free(p->Y);
20844         wolfSSL_BN_free(p->Z);
20845         p->X = NULL;
20846         p->Y = NULL;
20847         p->Z = NULL;
20848         p->inSet = p->exSet = 0;
20849 
20850         XFREE(p, NULL, DYNAMIC_TYPE_ECC);
20851         p = NULL;
20852     }
20853 }
20854 
20855 /* return code compliant with OpenSSL :
20856  *   1 if point at infinity, 0 else
20857  */
20858 int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group,
20859                                     const WOLFSSL_EC_POINT *point)
20860 {
20861     int ret;
20862 
20863     WOLFSSL_ENTER("wolfSSL_EC_POINT_is_at_infinity");
20864 
20865     if (group == NULL || point == NULL || point->internal == NULL) {
20866         WOLFSSL_MSG("wolfSSL_EC_POINT_is_at_infinity NULL error");
20867         return SSL_FAILURE;
20868     }
20869     if (point->inSet == 0) {
20870         WOLFSSL_MSG("No ECPoint internal set, do it");
20871 
20872         if (SetECPointInternal((WOLFSSL_EC_POINT *)point) != SSL_SUCCESS) {
20873             WOLFSSL_MSG("SetECPointInternal failed");
20874             return SSL_FAILURE;
20875         }
20876     }
20877 
20878     ret = wc_ecc_point_is_at_infinity((ecc_point*)point->internal);
20879     if (ret <= 0) {
20880         WOLFSSL_MSG("ecc_point_is_at_infinity failure");
20881         return SSL_FAILURE;
20882     }
20883 
20884     return SSL_SUCCESS;
20885 }
20886 
20887 /* End EC_POINT */
20888 
20889 /* Start ECDSA_SIG */
20890 void wolfSSL_ECDSA_SIG_free(WOLFSSL_ECDSA_SIG *sig)
20891 {
20892     WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_free");
20893 
20894     if (sig) {
20895         wolfSSL_BN_free(sig->r);
20896         wolfSSL_BN_free(sig->s);
20897 
20898         XFREE(sig, NULL, DYNAMIC_TYPE_ECC);
20899     }
20900 }
20901 
20902 WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_SIG_new(void)
20903 {
20904     WOLFSSL_ECDSA_SIG *sig;
20905 
20906     WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_new");
20907 
20908     sig = (WOLFSSL_ECDSA_SIG*) XMALLOC(sizeof(WOLFSSL_ECDSA_SIG), NULL,
20909                                        DYNAMIC_TYPE_ECC);
20910     if (sig == NULL) {
20911         WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA signature failure");
20912         return NULL;
20913     }
20914 
20915     sig->s = NULL;
20916     sig->r = wolfSSL_BN_new();
20917     if (sig->r == NULL) {
20918         WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA r failure");
20919         wolfSSL_ECDSA_SIG_free(sig);
20920         return NULL;
20921     }
20922 
20923     sig->s = wolfSSL_BN_new();
20924     if (sig->s == NULL) {
20925         WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA s failure");
20926         wolfSSL_ECDSA_SIG_free(sig);
20927         return NULL;
20928     }
20929 
20930     return sig;
20931 }
20932 
20933 /* return signature structure on success, NULL otherwise */
20934 WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *d, int dlen,
20935                                          WOLFSSL_EC_KEY *key)
20936 {
20937     WOLFSSL_ECDSA_SIG *sig = NULL;
20938     int     initTmpRng = 0;
20939     WC_RNG* rng = NULL;
20940 #ifdef WOLFSSL_SMALL_STACK
20941     WC_RNG* tmpRNG = NULL;
20942 #else
20943     WC_RNG  tmpRNG[1];
20944 #endif
20945 
20946     WOLFSSL_ENTER("wolfSSL_ECDSA_do_sign");
20947 
20948     if (d == NULL || key == NULL || key->internal == NULL) {
20949         WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Bad arguments");
20950         return NULL;
20951     }
20952 
20953     /* set internal key if not done */
20954     if (key->inSet == 0)
20955     {
20956         WOLFSSL_MSG("wolfSSL_ECDSA_do_sign No EC key internal set, do it");
20957 
20958         if (SetECKeyInternal(key) != SSL_SUCCESS) {
20959             WOLFSSL_MSG("wolfSSL_ECDSA_do_sign SetECKeyInternal failed");
20960             return NULL;
20961         }
20962     }
20963 
20964 #ifdef WOLFSSL_SMALL_STACK
20965     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
20966     if (tmpRNG == NULL)
20967         return NULL;
20968 #endif
20969 
20970     if (wc_InitRng(tmpRNG) == 0) {
20971         rng = tmpRNG;
20972         initTmpRng = 1;
20973     }
20974     else {
20975         WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Bad RNG Init, trying global");
20976         if (initGlobalRNG == 0)
20977             WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Global RNG no Init");
20978         else
20979             rng = &globalRNG;
20980     }
20981 
20982     if (rng) {
20983         mp_int sig_r, sig_s;
20984 
20985         if (mp_init_multi(&sig_r, &sig_s, NULL, NULL, NULL, NULL) == MP_OKAY) {
20986             if (wc_ecc_sign_hash_ex(d, dlen, rng, (ecc_key*)key->internal,
20987                                     &sig_r, &sig_s) != MP_OKAY) {
20988                 WOLFSSL_MSG("wc_ecc_sign_hash_ex failed");
20989             }
20990             else {
20991                 /* put signature blob in ECDSA structure */
20992                 sig = wolfSSL_ECDSA_SIG_new();
20993                 if (sig == NULL)
20994                     WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new failed");
20995                 else if (SetIndividualExternal(&(sig->r), &sig_r)!=SSL_SUCCESS){
20996                     WOLFSSL_MSG("ecdsa r key error");
20997                     wolfSSL_ECDSA_SIG_free(sig);
20998                     sig = NULL;
20999                 }
21000                 else if (SetIndividualExternal(&(sig->s), &sig_s)!=SSL_SUCCESS){
21001                     WOLFSSL_MSG("ecdsa s key error");
21002                     wolfSSL_ECDSA_SIG_free(sig);
21003                     sig = NULL;
21004                 }
21005 
21006             }
21007             mp_free(&sig_r);
21008             mp_free(&sig_s);
21009         }
21010     }
21011 
21012     if (initTmpRng)
21013         wc_FreeRng(tmpRNG);
21014 #ifdef WOLFSSL_SMALL_STACK
21015     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21016 #endif
21017 
21018     return sig;
21019 }
21020 
21021 /* return code compliant with OpenSSL :
21022  *   1 for a valid signature, 0 for an invalid signature and -1 on error
21023  */
21024 int wolfSSL_ECDSA_do_verify(const unsigned char *d, int dlen,
21025                             const WOLFSSL_ECDSA_SIG *sig, WOLFSSL_EC_KEY *key)
21026 {
21027     int check_sign = 0;
21028 
21029     WOLFSSL_ENTER("wolfSSL_ECDSA_do_verify");
21030 
21031     if (d == NULL || sig == NULL || key == NULL || key->internal == NULL) {
21032         WOLFSSL_MSG("wolfSSL_ECDSA_do_verify Bad arguments");
21033         return SSL_FATAL_ERROR;
21034     }
21035 
21036     /* set internal key if not done */
21037     if (key->inSet == 0)
21038     {
21039         WOLFSSL_MSG("No EC key internal set, do it");
21040 
21041         if (SetECKeyInternal(key) != SSL_SUCCESS) {
21042             WOLFSSL_MSG("SetECKeyInternal failed");
21043             return SSL_FATAL_ERROR;
21044         }
21045     }
21046 
21047     if (wc_ecc_verify_hash_ex((mp_int*)sig->r->internal,
21048                               (mp_int*)sig->s->internal, d, dlen, &check_sign,
21049                               (ecc_key *)key->internal) != MP_OKAY) {
21050         WOLFSSL_MSG("wc_ecc_verify_hash failed");
21051         return SSL_FATAL_ERROR;
21052     }
21053     else if (check_sign == 0) {
21054         WOLFSSL_MSG("wc_ecc_verify_hash incorrect signature detected");
21055         return SSL_FAILURE;
21056     }
21057 
21058     return SSL_SUCCESS;
21059 }
21060 /* End ECDSA_SIG */
21061 
21062 /* Start ECDH */
21063 /* return code compliant with OpenSSL :
21064  *   length of computed key if success, -1 if error
21065  */
21066 int wolfSSL_ECDH_compute_key(void *out, size_t outlen,
21067                              const WOLFSSL_EC_POINT *pub_key,
21068                              WOLFSSL_EC_KEY *ecdh,
21069                              void *(*KDF) (const void *in, size_t inlen,
21070                                            void *out, size_t *outlen))
21071 {
21072     word32 len;
21073     (void)KDF;
21074 
21075     (void)KDF;
21076 
21077     WOLFSSL_ENTER("wolfSSL_ECDH_compute_key");
21078 
21079     if (out == NULL || pub_key == NULL || pub_key->internal == NULL ||
21080         ecdh == NULL || ecdh->internal == NULL) {
21081         WOLFSSL_MSG("Bad function arguments");
21082         return SSL_FATAL_ERROR;
21083     }
21084 
21085     /* set internal key if not done */
21086     if (ecdh->inSet == 0)
21087     {
21088         WOLFSSL_MSG("No EC key internal set, do it");
21089 
21090         if (SetECKeyInternal(ecdh) != SSL_SUCCESS) {
21091             WOLFSSL_MSG("SetECKeyInternal failed");
21092             return SSL_FATAL_ERROR;
21093         }
21094     }
21095 
21096     len = (word32)outlen;
21097 
21098     if (wc_ecc_shared_secret_ssh((ecc_key*)ecdh->internal,
21099                                  (ecc_point*)pub_key->internal,
21100                                  (byte *)out, &len) != MP_OKAY) {
21101         WOLFSSL_MSG("wc_ecc_shared_secret failed");
21102         return SSL_FATAL_ERROR;
21103     }
21104 
21105     return len;
21106 }
21107 /* End ECDH */
21108 
21109 #if !defined(NO_FILESYSTEM)
21110 /* return code compliant with OpenSSL :
21111  *   1 if success, 0 if error
21112  */
21113 int wolfSSL_PEM_write_EC_PUBKEY(FILE *fp, WOLFSSL_EC_KEY *x)
21114 {
21115     (void)fp;
21116     (void)x;
21117 
21118     WOLFSSL_MSG("wolfSSL_PEM_write_EC_PUBKEY not implemented");
21119 
21120     return SSL_FAILURE;
21121 }
21122 #endif /* NO_FILESYSTEM */
21123 
21124 #if defined(WOLFSSL_KEY_GEN)
21125 
21126 /* return code compliant with OpenSSL :
21127  *   1 if success, 0 if error
21128  */
21129 int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ecc,
21130                                        const EVP_CIPHER* cipher,
21131                                        unsigned char* passwd, int len,
21132                                        pem_password_cb* cb, void* arg)
21133 {
21134     (void)bio;
21135     (void)ecc;
21136     (void)cipher;
21137     (void)passwd;
21138     (void)len;
21139     (void)cb;
21140     (void)arg;
21141 
21142     WOLFSSL_MSG("wolfSSL_PEM_write_bio_ECPrivateKey not implemented");
21143 
21144     return SSL_FAILURE;
21145 }
21146 
21147 /* return code compliant with OpenSSL :
21148  *   1 if success, 0 if error
21149  */
21150 int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc,
21151                                        const EVP_CIPHER* cipher,
21152                                        unsigned char* passwd, int passwdSz,
21153                                        unsigned char **pem, int *plen)
21154 {
21155     byte *derBuf, *tmp, *cipherInfo = NULL;
21156     int  der_max_len = 0, derSz = 0;
21157 
21158     WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey");
21159 
21160     if (pem == NULL || plen == NULL || ecc == NULL || ecc->internal == NULL) {
21161         WOLFSSL_MSG("Bad function arguments");
21162         return SSL_FAILURE;
21163     }
21164 
21165     if (ecc->inSet == 0) {
21166         WOLFSSL_MSG("No ECC internal set, do it");
21167 
21168         if (SetECKeyInternal(ecc) != SSL_SUCCESS) {
21169             WOLFSSL_MSG("SetDsaInternal failed");
21170             return SSL_FAILURE;
21171         }
21172     }
21173 
21174     /* 4 > size of pub, priv + ASN.1 additional informations
21175      */
21176     der_max_len = 4 * wc_ecc_size((ecc_key*)ecc->internal) + AES_BLOCK_SIZE;
21177 
21178     derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21179     if (derBuf == NULL) {
21180         WOLFSSL_MSG("malloc failed");
21181         return SSL_FAILURE;
21182     }
21183 
21184     /* Key to DER */
21185     derSz = wc_EccKeyToDer((ecc_key*)ecc->internal, derBuf, der_max_len);
21186     if (derSz < 0) {
21187         WOLFSSL_MSG("wc_DsaKeyToDer failed");
21188         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21189         return SSL_FAILURE;
21190     }
21191 
21192     /* encrypt DER buffer if required */
21193     if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
21194         int ret;
21195 
21196         ret = EncryptDerKey(derBuf, &derSz, cipher,
21197                             passwd, passwdSz, &cipherInfo);
21198         if (ret != SSL_SUCCESS) {
21199             WOLFSSL_MSG("EncryptDerKey failed");
21200             XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21201             return ret;
21202         }
21203 
21204         /* tmp buffer with a max size */
21205         *plen = (derSz * 2) + sizeof(BEGIN_EC_PRIV) +
21206         sizeof(END_EC_PRIV) + HEADER_ENCRYPTED_KEY_SIZE;
21207     }
21208     else /* tmp buffer with a max size */
21209         *plen = (derSz * 2) + sizeof(BEGIN_EC_PRIV) + sizeof(END_EC_PRIV);
21210 
21211     tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21212     if (tmp == NULL) {
21213         WOLFSSL_MSG("malloc failed");
21214         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21215         if (cipherInfo != NULL)
21216             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21217         return SSL_FAILURE;
21218     }
21219 
21220     /* DER to PEM */
21221     *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, ECC_PRIVATEKEY_TYPE);
21222     if (*plen <= 0) {
21223         WOLFSSL_MSG("wc_DerToPemEx failed");
21224         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21225         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21226         if (cipherInfo != NULL)
21227             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21228         return SSL_FAILURE;
21229     }
21230     XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21231     if (cipherInfo != NULL)
21232         XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21233 
21234     *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY);
21235     if (*pem == NULL) {
21236         WOLFSSL_MSG("malloc failed");
21237         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21238         return SSL_FAILURE;
21239     }
21240     XMEMSET(*pem, 0, (*plen)+1);
21241 
21242     if (XMEMCPY(*pem, tmp, *plen) == NULL) {
21243         WOLFSSL_MSG("XMEMCPY failed");
21244         XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
21245         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21246         return SSL_FAILURE;
21247     }
21248     XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21249 
21250     return SSL_SUCCESS;
21251 }
21252 
21253 #ifndef NO_FILESYSTEM
21254 /* return code compliant with OpenSSL :
21255  *   1 if success, 0 if error
21256  */
21257 int wolfSSL_PEM_write_ECPrivateKey(FILE *fp, WOLFSSL_EC_KEY *ecc,
21258                                    const EVP_CIPHER *enc,
21259                                    unsigned char *kstr, int klen,
21260                                    pem_password_cb *cb, void *u)
21261 {
21262     byte *pem;
21263     int  plen, ret;
21264 
21265     (void)cb;
21266     (void)u;
21267 
21268     WOLFSSL_MSG("wolfSSL_PEM_write_ECPrivateKey");
21269 
21270     if (fp == NULL || ecc == NULL || ecc->internal == NULL) {
21271         WOLFSSL_MSG("Bad function arguments");
21272         return SSL_FAILURE;
21273     }
21274 
21275     ret = wolfSSL_PEM_write_mem_ECPrivateKey(ecc, enc, kstr, klen, &pem, &plen);
21276     if (ret != SSL_SUCCESS) {
21277         WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey failed");
21278         return SSL_FAILURE;
21279     }
21280 
21281     ret = (int)XFWRITE(pem, plen, 1, fp);
21282     if (ret != 1) {
21283         WOLFSSL_MSG("ECC private key file write failed");
21284         return SSL_FAILURE;
21285     }
21286 
21287     XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
21288     return SSL_SUCCESS;
21289 }
21290 
21291 #endif /* NO_FILESYSTEM */
21292 #endif /* defined(WOLFSSL_KEY_GEN) */
21293 
21294 #endif /* HAVE_ECC */
21295 
21296 
21297 #ifndef NO_DSA
21298 
21299 #if defined(WOLFSSL_KEY_GEN)
21300 
21301 /* return code compliant with OpenSSL :
21302  *   1 if success, 0 if error
21303  */
21304 int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa,
21305                                        const EVP_CIPHER* cipher,
21306                                        unsigned char* passwd, int len,
21307                                        pem_password_cb* cb, void* arg)
21308 {
21309     (void)bio;
21310     (void)dsa;
21311     (void)cipher;
21312     (void)passwd;
21313     (void)len;
21314     (void)cb;
21315     (void)arg;
21316 
21317     WOLFSSL_MSG("wolfSSL_PEM_write_bio_DSAPrivateKey not implemented");
21318 
21319     return SSL_FAILURE;
21320 }
21321 
21322 /* return code compliant with OpenSSL :
21323  *   1 if success, 0 if error
21324  */
21325 int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa,
21326                                         const EVP_CIPHER* cipher,
21327                                         unsigned char* passwd, int passwdSz,
21328                                         unsigned char **pem, int *plen)
21329 {
21330     byte *derBuf, *tmp, *cipherInfo = NULL;
21331     int  der_max_len = 0, derSz = 0;
21332 
21333     WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey");
21334 
21335     if (pem == NULL || plen == NULL || dsa == NULL || dsa->internal == NULL) {
21336         WOLFSSL_MSG("Bad function arguments");
21337         return SSL_FAILURE;
21338     }
21339 
21340     if (dsa->inSet == 0) {
21341         WOLFSSL_MSG("No DSA internal set, do it");
21342 
21343         if (SetDsaInternal(dsa) != SSL_SUCCESS) {
21344             WOLFSSL_MSG("SetDsaInternal failed");
21345             return SSL_FAILURE;
21346         }
21347     }
21348 
21349     /* 4 > size of pub, priv, p, q, g + ASN.1 additional informations
21350      */
21351     der_max_len = 4 * wolfSSL_BN_num_bytes(dsa->g) + AES_BLOCK_SIZE;
21352 
21353     derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21354     if (derBuf == NULL) {
21355         WOLFSSL_MSG("malloc failed");
21356         return SSL_FAILURE;
21357     }
21358 
21359     /* Key to DER */
21360     derSz = wc_DsaKeyToDer((DsaKey*)dsa->internal, derBuf, der_max_len);
21361     if (derSz < 0) {
21362         WOLFSSL_MSG("wc_DsaKeyToDer failed");
21363         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21364         return SSL_FAILURE;
21365     }
21366 
21367     /* encrypt DER buffer if required */
21368     if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
21369         int ret;
21370 
21371         ret = EncryptDerKey(derBuf, &derSz, cipher,
21372                             passwd, passwdSz, &cipherInfo);
21373         if (ret != SSL_SUCCESS) {
21374             WOLFSSL_MSG("EncryptDerKey failed");
21375             XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21376             return ret;
21377         }
21378 
21379         /* tmp buffer with a max size */
21380         *plen = (derSz * 2) + sizeof(BEGIN_DSA_PRIV) +
21381         sizeof(END_DSA_PRIV) + HEADER_ENCRYPTED_KEY_SIZE;
21382     }
21383     else /* tmp buffer with a max size */
21384         *plen = (derSz * 2) + sizeof(BEGIN_DSA_PRIV) + sizeof(END_DSA_PRIV);
21385 
21386     tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21387     if (tmp == NULL) {
21388         WOLFSSL_MSG("malloc failed");
21389         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21390         if (cipherInfo != NULL)
21391             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21392         return SSL_FAILURE;
21393     }
21394 
21395     /* DER to PEM */
21396     *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, DSA_PRIVATEKEY_TYPE);
21397     if (*plen <= 0) {
21398         WOLFSSL_MSG("wc_DerToPemEx failed");
21399         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21400         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21401         if (cipherInfo != NULL)
21402             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21403         return SSL_FAILURE;
21404     }
21405     XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21406     if (cipherInfo != NULL)
21407         XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21408 
21409     *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY);
21410     if (*pem == NULL) {
21411         WOLFSSL_MSG("malloc failed");
21412         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21413         return SSL_FAILURE;
21414     }
21415     XMEMSET(*pem, 0, (*plen)+1);
21416 
21417     if (XMEMCPY(*pem, tmp, *plen) == NULL) {
21418         WOLFSSL_MSG("XMEMCPY failed");
21419         XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
21420         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21421         return SSL_FAILURE;
21422     }
21423     XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21424 
21425     return SSL_SUCCESS;
21426 }
21427 
21428 #ifndef NO_FILESYSTEM
21429 /* return code compliant with OpenSSL :
21430  *   1 if success, 0 if error
21431  */
21432 int wolfSSL_PEM_write_DSAPrivateKey(FILE *fp, WOLFSSL_DSA *dsa,
21433                                     const EVP_CIPHER *enc,
21434                                     unsigned char *kstr, int klen,
21435                                     pem_password_cb *cb, void *u)
21436 {
21437     byte *pem;
21438     int  plen, ret;
21439 
21440     (void)cb;
21441     (void)u;
21442 
21443     WOLFSSL_MSG("wolfSSL_PEM_write_DSAPrivateKey");
21444 
21445     if (fp == NULL || dsa == NULL || dsa->internal == NULL) {
21446         WOLFSSL_MSG("Bad function arguments");
21447         return SSL_FAILURE;
21448     }
21449 
21450     ret = wolfSSL_PEM_write_mem_DSAPrivateKey(dsa, enc, kstr, klen, &pem, &plen);
21451     if (ret != SSL_SUCCESS) {
21452         WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey failed");
21453         return SSL_FAILURE;
21454     }
21455 
21456     ret = (int)XFWRITE(pem, plen, 1, fp);
21457     if (ret != 1) {
21458         WOLFSSL_MSG("DSA private key file write failed");
21459         return SSL_FAILURE;
21460     }
21461 
21462     XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
21463     return SSL_SUCCESS;
21464 }
21465 
21466 #endif /* NO_FILESYSTEM */
21467 #endif /* defined(WOLFSSL_KEY_GEN) */
21468 
21469 #ifndef NO_FILESYSTEM
21470 /* return code compliant with OpenSSL :
21471  *   1 if success, 0 if error
21472  */
21473 int wolfSSL_PEM_write_DSA_PUBKEY(FILE *fp, WOLFSSL_DSA *x)
21474 {
21475     (void)fp;
21476     (void)x;
21477 
21478     WOLFSSL_MSG("wolfSSL_PEM_write_DSA_PUBKEY not implemented");
21479 
21480     return SSL_FAILURE;
21481 }
21482 #endif /* NO_FILESYSTEM */
21483 
21484 #endif /* #ifndef NO_DSA */
21485 
21486 WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
21487                     WOLFSSL_EVP_PKEY** key, pem_password_cb* cb, void* arg)
21488 {
21489     (void)bio;
21490     (void)key;
21491     (void)cb;
21492     (void)arg;
21493 
21494     WOLFSSL_MSG("wolfSSL_PEM_read_bio_PrivateKey not implemented");
21495 
21496     return NULL;
21497 }
21498 
21499 
21500 int wolfSSL_EVP_PKEY_type(int type)
21501 {
21502     (void) type;
21503     WOLFSSL_MSG("wolfSSL_EVP_PKEY_type always returns EVP_PKEY_RSA");
21504     return EVP_PKEY_RSA;
21505 }
21506 
21507 int wolfSSL_EVP_PKEY_base_id(const EVP_PKEY *pkey)
21508 {
21509     return EVP_PKEY_type(pkey->type);
21510 }
21511 
21512 
21513 #if !defined(NO_FILESYSTEM)
21514 WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x,
21515                                           pem_password_cb *cb, void *u)
21516 {
21517     (void)fp;
21518     (void)x;
21519     (void)cb;
21520     (void)u;
21521 
21522     WOLFSSL_MSG("wolfSSL_PEM_read_PUBKEY not implemented");
21523 
21524     return NULL;
21525 }
21526 #endif /* NO_FILESYSTEM */
21527 
21528 #ifndef NO_RSA
21529 
21530 #if !defined(NO_FILESYSTEM)
21531 WOLFSSL_RSA *wolfSSL_PEM_read_RSAPublicKey(FILE *fp, WOLFSSL_RSA **x,
21532                                            pem_password_cb *cb, void *u)
21533 {
21534     (void)fp;
21535     (void)x;
21536     (void)cb;
21537     (void)u;
21538 
21539     WOLFSSL_MSG("wolfSSL_PEM_read_RSAPublicKey not implemented");
21540 
21541     return NULL;
21542 }
21543 
21544 /* return code compliant with OpenSSL :
21545  *   1 if success, 0 if error
21546  */
21547 int wolfSSL_PEM_write_RSAPublicKey(FILE *fp, WOLFSSL_RSA *x)
21548 {
21549     (void)fp;
21550     (void)x;
21551 
21552     WOLFSSL_MSG("wolfSSL_PEM_write_RSAPublicKey not implemented");
21553 
21554     return SSL_FAILURE;
21555 }
21556 
21557 /* return code compliant with OpenSSL :
21558  *   1 if success, 0 if error
21559  */
21560 int wolfSSL_PEM_write_RSA_PUBKEY(FILE *fp, WOLFSSL_RSA *x)
21561 {
21562     (void)fp;
21563     (void)x;
21564 
21565     WOLFSSL_MSG("wolfSSL_PEM_write_RSA_PUBKEY not implemented");
21566 
21567     return SSL_FAILURE;
21568 }
21569 #endif /* NO_FILESYSTEM */
21570 
21571 /* return SSL_SUCCESS if success, SSL_FATAL_ERROR if error */
21572 int wolfSSL_RSA_LoadDer(WOLFSSL_RSA* rsa, const unsigned char* derBuf, int derSz)
21573 {
21574     word32 idx = 0;
21575     int    ret;
21576 
21577     WOLFSSL_ENTER("wolfSSL_RSA_LoadDer");
21578 
21579     if (rsa == NULL || rsa->internal == NULL || derBuf == NULL || derSz <= 0) {
21580         WOLFSSL_MSG("Bad function arguments");
21581         return SSL_FATAL_ERROR;
21582     }
21583 
21584     ret = wc_RsaPrivateKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal, derSz);
21585     if (ret < 0) {
21586         WOLFSSL_MSG("RsaPrivateKeyDecode failed");
21587         return SSL_FATAL_ERROR;
21588     }
21589 
21590     if (SetRsaExternal(rsa) != SSL_SUCCESS) {
21591         WOLFSSL_MSG("SetRsaExternal failed");
21592         return SSL_FATAL_ERROR;
21593     }
21594 
21595     rsa->inSet = 1;
21596 
21597     return SSL_SUCCESS;
21598 }
21599 #endif /* NO_RSA */
21600 
21601 
21602 #ifndef NO_DSA
21603 /* return SSL_SUCCESS if success, SSL_FATAL_ERROR if error */
21604 int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* derBuf, int derSz)
21605 {
21606     word32 idx = 0;
21607     int    ret;
21608 
21609     WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
21610 
21611     if (dsa == NULL || dsa->internal == NULL || derBuf == NULL || derSz <= 0) {
21612         WOLFSSL_MSG("Bad function arguments");
21613         return SSL_FATAL_ERROR;
21614     }
21615 
21616     ret = DsaPrivateKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal, derSz);
21617     if (ret < 0) {
21618         WOLFSSL_MSG("DsaPrivateKeyDecode failed");
21619         return SSL_FATAL_ERROR;
21620     }
21621 
21622     if (SetDsaExternal(dsa) != SSL_SUCCESS) {
21623         WOLFSSL_MSG("SetDsaExternal failed");
21624         return SSL_FATAL_ERROR;
21625     }
21626 
21627     dsa->inSet = 1;
21628 
21629     return SSL_SUCCESS;
21630 }
21631 #endif /* NO_DSA */
21632 
21633 #ifdef HAVE_ECC
21634 /* return SSL_SUCCESS if success, SSL_FATAL_ERROR if error */
21635 int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key,
21636                            const unsigned char* derBuf,  int derSz)
21637 {
21638     word32 idx = 0;
21639     int    ret;
21640 
21641     WOLFSSL_ENTER("wolfSSL_EC_KEY_LoadDer");
21642 
21643     if (key == NULL || key->internal == NULL || derBuf == NULL || derSz <= 0) {
21644         WOLFSSL_MSG("Bad function arguments");
21645         return SSL_FATAL_ERROR;
21646     }
21647 
21648     ret = wc_EccPrivateKeyDecode(derBuf, &idx, (ecc_key*)key->internal, derSz);
21649     if (ret < 0) {
21650         WOLFSSL_MSG("wc_EccPrivateKeyDecode failed");
21651         return SSL_FATAL_ERROR;
21652     }
21653 
21654     if (SetECKeyExternal(key) != SSL_SUCCESS) {
21655         WOLFSSL_MSG("SetECKeyExternal failed");
21656         return SSL_FATAL_ERROR;
21657     }
21658 
21659     key->inSet = 1;
21660 
21661     return SSL_SUCCESS;
21662 }
21663 #endif /* HAVE_ECC */
21664 
21665 #endif /* OPENSSL_EXTRA */
21666 
21667 
21668 #ifdef SESSION_CERTS
21669 
21670 
21671 /* Get peer's certificate chain */
21672 WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl)
21673 {
21674     WOLFSSL_ENTER("wolfSSL_get_peer_chain");
21675     if (ssl)
21676         return &ssl->session.chain;
21677 
21678     return 0;
21679 }
21680 
21681 
21682 /* Get peer's certificate chain total count */
21683 int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain)
21684 {
21685     WOLFSSL_ENTER("wolfSSL_get_chain_count");
21686     if (chain)
21687         return chain->count;
21688 
21689     return 0;
21690 }
21691 
21692 
21693 /* Get peer's ASN.1 DER certificate at index (idx) length in bytes */
21694 int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx)
21695 {
21696     WOLFSSL_ENTER("wolfSSL_get_chain_length");
21697     if (chain)
21698         return chain->certs[idx].length;
21699 
21700     return 0;
21701 }
21702 
21703 
21704 /* Get peer's ASN.1 DER certificate at index (idx) */
21705 byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx)
21706 {
21707     WOLFSSL_ENTER("wolfSSL_get_chain_cert");
21708     if (chain)
21709         return chain->certs[idx].buffer;
21710 
21711     return 0;
21712 }
21713 
21714 
21715 /* Get peer's wolfSSL X509 certificate at index (idx) */
21716 WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx)
21717 {
21718     int          ret;
21719     WOLFSSL_X509* x509 = NULL;
21720 #ifdef WOLFSSL_SMALL_STACK
21721     DecodedCert* cert = NULL;
21722 #else
21723     DecodedCert  cert[1];
21724 #endif
21725 
21726     WOLFSSL_ENTER("wolfSSL_get_chain_X509");
21727     if (chain != NULL) {
21728     #ifdef WOLFSSL_SMALL_STACK
21729         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
21730                                                        DYNAMIC_TYPE_TMP_BUFFER);
21731         if (cert != NULL)
21732     #endif
21733         {
21734             InitDecodedCert(cert, chain->certs[idx].buffer,
21735                                   chain->certs[idx].length, NULL);
21736 
21737             if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) != 0) {
21738                 WOLFSSL_MSG("Failed to parse cert");
21739             }
21740             else {
21741                 x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
21742                                                              DYNAMIC_TYPE_X509);
21743                 if (x509 == NULL) {
21744                     WOLFSSL_MSG("Failed alloc X509");
21745                 }
21746                 else {
21747                     InitX509(x509, 1, NULL);
21748 
21749                     if ((ret = CopyDecodedToX509(x509, cert)) != 0) {
21750                         WOLFSSL_MSG("Failed to copy decoded");
21751                         XFREE(x509, NULL, DYNAMIC_TYPE_X509);
21752                         x509 = NULL;
21753                     }
21754                 }
21755             }
21756 
21757             FreeDecodedCert(cert);
21758         #ifdef WOLFSSL_SMALL_STACK
21759             XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21760         #endif
21761         }
21762     }
21763     (void)ret;
21764 
21765     return x509;
21766 }
21767 
21768 
21769 /* Get peer's PEM certificate at index (idx), output to buffer if inLen big
21770    enough else return error (-1). If buffer is NULL only calculate
21771    outLen. Output length is in *outLen SSL_SUCCESS on ok */
21772 int  wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
21773                                unsigned char* buf, int inLen, int* outLen)
21774 {
21775     const char header[] = "-----BEGIN CERTIFICATE-----\n";
21776     const char footer[] = "-----END CERTIFICATE-----\n";
21777 
21778     int headerLen = sizeof(header) - 1;
21779     int footerLen = sizeof(footer) - 1;
21780     int i;
21781     int err;
21782     word32 szNeeded = 0;
21783 
21784     WOLFSSL_ENTER("wolfSSL_get_chain_cert_pem");
21785     if (!chain || !outLen || idx < 0 || idx >= wolfSSL_get_chain_count(chain))
21786         return BAD_FUNC_ARG;
21787 
21788     /* Null output buffer return size needed in outLen */
21789     if(!buf) {
21790         if(Base64_Encode(chain->certs[idx].buffer, chain->certs[idx].length,
21791                     NULL, &szNeeded) != LENGTH_ONLY_E)
21792             return SSL_FAILURE;
21793         *outLen = szNeeded + headerLen + footerLen;
21794         return LENGTH_ONLY_E;
21795     }
21796 
21797     /* don't even try if inLen too short */
21798     if (inLen < headerLen + footerLen + chain->certs[idx].length)
21799         return BAD_FUNC_ARG;
21800 
21801     /* header */
21802     if (XMEMCPY(buf, header, headerLen) == NULL)
21803         return SSL_FATAL_ERROR;
21804 
21805     i = headerLen;
21806 
21807     /* body */
21808     *outLen = inLen;  /* input to Base64_Encode */
21809     if ( (err = Base64_Encode(chain->certs[idx].buffer,
21810                        chain->certs[idx].length, buf + i, (word32*)outLen)) < 0)
21811         return err;
21812     i += *outLen;
21813 
21814     /* footer */
21815     if ( (i + footerLen) > inLen)
21816         return BAD_FUNC_ARG;
21817     if (XMEMCPY(buf + i, footer, footerLen) == NULL)
21818         return SSL_FATAL_ERROR;
21819     *outLen += headerLen + footerLen;
21820 
21821     return SSL_SUCCESS;
21822 }
21823 
21824 
21825 /* get session ID */
21826 const byte* wolfSSL_get_sessionID(const WOLFSSL_SESSION* session)
21827 {
21828     WOLFSSL_ENTER("wolfSSL_get_sessionID");
21829     if (session)
21830         return session->sessionID;
21831 
21832     return NULL;
21833 }
21834 
21835 
21836 #endif /* SESSION_CERTS */
21837 
21838 #ifdef HAVE_FUZZER
21839 void wolfSSL_SetFuzzerCb(WOLFSSL* ssl, CallbackFuzzer cbf, void* fCtx)
21840 {
21841     if (ssl) {
21842         ssl->fuzzerCb  = cbf;
21843         ssl->fuzzerCtx = fCtx;
21844     }
21845 }
21846 #endif
21847 
21848 #ifndef NO_CERTS
21849 #ifdef  HAVE_PK_CALLBACKS
21850 
21851 #ifdef HAVE_ECC
21852 
21853 void  wolfSSL_CTX_SetEccSignCb(WOLFSSL_CTX* ctx, CallbackEccSign cb)
21854 {
21855     if (ctx)
21856         ctx->EccSignCb = cb;
21857 }
21858 
21859 
21860 void  wolfSSL_SetEccSignCtx(WOLFSSL* ssl, void *ctx)
21861 {
21862     if (ssl)
21863         ssl->EccSignCtx = ctx;
21864 }
21865 
21866 
21867 void* wolfSSL_GetEccSignCtx(WOLFSSL* ssl)
21868 {
21869     if (ssl)
21870         return ssl->EccSignCtx;
21871 
21872     return NULL;
21873 }
21874 
21875 
21876 void  wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX* ctx, CallbackEccVerify cb)
21877 {
21878     if (ctx)
21879         ctx->EccVerifyCb = cb;
21880 }
21881 
21882 
21883 void  wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx)
21884 {
21885     if (ssl)
21886         ssl->EccVerifyCtx = ctx;
21887 }
21888 
21889 
21890 void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl)
21891 {
21892     if (ssl)
21893         return ssl->EccVerifyCtx;
21894 
21895     return NULL;
21896 }
21897 
21898 void wolfSSL_CTX_SetEccSharedSecretCb(WOLFSSL_CTX* ctx, CallbackEccSharedSecret cb)
21899 {
21900     if (ctx)
21901         ctx->EccSharedSecretCb = cb;
21902 }
21903 
21904 void  wolfSSL_SetEccSharedSecretCtx(WOLFSSL* ssl, void *ctx)
21905 {
21906     if (ssl)
21907         ssl->EccSharedSecretCtx = ctx;
21908 }
21909 
21910 
21911 void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl)
21912 {
21913     if (ssl)
21914         return ssl->EccSharedSecretCtx;
21915 
21916     return NULL;
21917 }
21918 #endif /* HAVE_ECC */
21919 
21920 #ifndef NO_RSA
21921 
21922 void  wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX* ctx, CallbackRsaSign cb)
21923 {
21924     if (ctx)
21925         ctx->RsaSignCb = cb;
21926 }
21927 
21928 
21929 void  wolfSSL_SetRsaSignCtx(WOLFSSL* ssl, void *ctx)
21930 {
21931     if (ssl)
21932         ssl->RsaSignCtx = ctx;
21933 }
21934 
21935 
21936 void* wolfSSL_GetRsaSignCtx(WOLFSSL* ssl)
21937 {
21938     if (ssl)
21939         return ssl->RsaSignCtx;
21940 
21941     return NULL;
21942 }
21943 
21944 
21945 void  wolfSSL_CTX_SetRsaVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
21946 {
21947     if (ctx)
21948         ctx->RsaVerifyCb = cb;
21949 }
21950 
21951 
21952 void  wolfSSL_SetRsaVerifyCtx(WOLFSSL* ssl, void *ctx)
21953 {
21954     if (ssl)
21955         ssl->RsaVerifyCtx = ctx;
21956 }
21957 
21958 
21959 void* wolfSSL_GetRsaVerifyCtx(WOLFSSL* ssl)
21960 {
21961     if (ssl)
21962         return ssl->RsaVerifyCtx;
21963 
21964     return NULL;
21965 }
21966 
21967 void  wolfSSL_CTX_SetRsaEncCb(WOLFSSL_CTX* ctx, CallbackRsaEnc cb)
21968 {
21969     if (ctx)
21970         ctx->RsaEncCb = cb;
21971 }
21972 
21973 
21974 void  wolfSSL_SetRsaEncCtx(WOLFSSL* ssl, void *ctx)
21975 {
21976     if (ssl)
21977         ssl->RsaEncCtx = ctx;
21978 }
21979 
21980 
21981 void* wolfSSL_GetRsaEncCtx(WOLFSSL* ssl)
21982 {
21983     if (ssl)
21984         return ssl->RsaEncCtx;
21985 
21986     return NULL;
21987 }
21988 
21989 void  wolfSSL_CTX_SetRsaDecCb(WOLFSSL_CTX* ctx, CallbackRsaDec cb)
21990 {
21991     if (ctx)
21992         ctx->RsaDecCb = cb;
21993 }
21994 
21995 
21996 void  wolfSSL_SetRsaDecCtx(WOLFSSL* ssl, void *ctx)
21997 {
21998     if (ssl)
21999         ssl->RsaDecCtx = ctx;
22000 }
22001 
22002 
22003 void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
22004 {
22005     if (ssl)
22006         return ssl->RsaDecCtx;
22007 
22008     return NULL;
22009 }
22010 
22011 
22012 #endif /* NO_RSA */
22013 
22014 #endif /* HAVE_PK_CALLBACKS */
22015 #endif /* NO_CERTS */
22016 
22017 
22018 #ifdef WOLFSSL_HAVE_WOLFSCEP
22019     /* Used by autoconf to see if wolfSCEP is available */
22020     void wolfSSL_wolfSCEP(void) {}
22021 #endif
22022 
22023 
22024 #ifdef WOLFSSL_HAVE_CERT_SERVICE
22025     /* Used by autoconf to see if cert service is available */
22026     void wolfSSL_cert_service(void) {}
22027 #endif
22028 
22029 
22030 #ifdef OPENSSL_EXTRA /*Lighttp compatibility*/
22031 
22032     #ifndef NO_CERTS
22033     WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
22034                                                  pem_password_cb *cb, void *u)
22035     {
22036 #ifndef NO_FILESYSTEM
22037         WOLFSSL_X509* x509 = NULL;
22038         unsigned char* pem = NULL;
22039         int pemSz;
22040         int pemAlloced = 0;
22041 
22042         WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509");
22043 
22044         if (bp == NULL) {
22045             WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", BAD_FUNC_ARG);
22046             return NULL;
22047         }
22048 
22049         if (bp->type == BIO_MEMORY) {
22050             pemSz = wolfSSL_BIO_get_mem_data(bp, &pem);
22051             if (pemSz <= 0 || pem == NULL) {
22052                 WOLFSSL_MSG("Issue getting WOLFSSL_BIO mem");
22053                 WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", pemSz);
22054                 return NULL;
22055             }
22056         }
22057         else if (bp->type == BIO_FILE) {
22058             long i;
22059             long l;
22060 
22061             /* Read in next certificate from file but no more. */
22062             i = XFTELL(bp->file);
22063             if (i < 0)
22064                 return NULL;
22065             XFSEEK(bp->file, 0, SEEK_END);
22066             l = XFTELL(bp->file);
22067             if (l < 0)
22068                 return NULL;
22069             XFSEEK(bp->file, i, SEEK_SET);
22070 
22071             /* check calulated length */
22072             if (l - i <= 0)
22073                 return NULL;
22074 
22075             pem = (unsigned char*)XMALLOC(l - i, 0, DYNAMIC_TYPE_TMP_BUFFER);
22076             if (pem == NULL)
22077                 return NULL;
22078             pemAlloced = 1;
22079 
22080             i = 0;
22081             /* TODO: Inefficient
22082              * reading in one byte at a time until see END_CERT
22083              */
22084             while ((l = wolfSSL_BIO_read(bp, (char *)&pem[i], 1)) == 1) {
22085                 i++;
22086                 if (i > 26 && XMEMCMP((char *)&pem[i-26], END_CERT, 25) == 0)
22087                     break;
22088             }
22089         #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
22090             if (l == 0)
22091                 WOLFSSL_ERROR(SSL_NO_PEM_HEADER);
22092         #endif
22093             pemSz = (int)i;
22094         }
22095         else
22096             return NULL;
22097 
22098         x509 = wolfSSL_X509_load_certificate_buffer(pem, pemSz,
22099                                                               SSL_FILETYPE_PEM);
22100 
22101         if (x != NULL) {
22102             *x = x509;
22103         }
22104 
22105         if (pemAlloced)
22106             XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22107 
22108         (void)cb;
22109         (void)u;
22110 
22111         return x509;
22112 #else
22113         (void)bp;
22114         (void)x;
22115         (void)cb;
22116         (void)u;
22117         return NULL;
22118 #endif
22119     }
22120 
22121 
22122     /*
22123      * bp : bio to read X509 from
22124      * x  : x509 to write to
22125      * cb : password call back for reading PEM
22126      * u  : password
22127      * _AUX is for working with a trusted X509 certificate
22128      */
22129     WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX(WOLFSSL_BIO *bp,
22130                                WOLFSSL_X509 **x, pem_password_cb *cb, void *u) {
22131         WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509");
22132 
22133         /* AUX info is; trusted/rejected uses, friendly name, private key id,
22134          * and potentially a stack of "other" info. wolfSSL does not store
22135          * friendly name or private key id yet in WOLFSSL_X509 for human
22136          * readibility and does not support extra trusted/rejected uses for
22137          * root CA. */
22138         return wolfSSL_PEM_read_bio_X509(bp, x, cb, u);
22139     }
22140     #endif /* ifndef NO_CERTS */
22141 
22142     #ifndef NO_CERTS
22143     void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name){
22144         FreeX509Name(name, NULL);
22145         WOLFSSL_ENTER("wolfSSL_X509_NAME_free");
22146     }
22147     #endif /* NO_CERTS */
22148 
22149 #if defined(HAVE_LIGHTY)  || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
22150     defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
22151     defined(HAVE_POCO_LIB) || defined (WOLFSSL_HAPROXY)
22152 
22153     unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n, unsigned char *md)
22154     {
22155         (void) *d; (void) n; (void) *md;
22156         WOLFSSL_ENTER("wolfSSL_SHA1");
22157         WOLFSSL_STUB("wolfssl_SHA1");
22158 
22159         return NULL;
22160     }
22161 
22162     char wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x)
22163     {
22164         int ret;
22165 
22166         WOLFSSL_ENTER("wolfSSL_CTX_use_certificate");
22167 
22168         FreeDer(&ctx->certificate); /* Make sure previous is free'd */
22169         ret = AllocDer(&ctx->certificate, x->derCert->length, CERT_TYPE,
22170                        ctx->heap);
22171         if (ret != 0)
22172             return 0;
22173 
22174         XMEMCPY(ctx->certificate->buffer, x->derCert->buffer,
22175                 x->derCert->length);
22176 #ifdef KEEP_OUR_CERT
22177         if (ctx->ourCert != NULL && ctx->ownOurCert) {
22178             FreeX509(ctx->ourCert);
22179             XFREE(ctx->ourCert, ctx->heap, DYNAMIC_TYPE_X509);
22180         }
22181         ctx->ourCert = x;
22182         ctx->ownOurCert = 0;
22183 #endif
22184 
22185         /* Update the available options with public keys. */
22186         switch (x->pubKeyOID) {
22187             case RSAk:
22188                 ctx->haveRSA = 1;
22189                 break;
22190             case ECDSAk:
22191                 ctx->haveECC = 1;
22192                 ctx->pkCurveOID = x->pkCurveOID;
22193                 break;
22194         }
22195 
22196         return SSL_SUCCESS;
22197     }
22198 
22199     int wolfSSL_BIO_read_filename(WOLFSSL_BIO *b, const char *name) {
22200     #ifndef NO_FILESYSTEM
22201         XFILE fp;
22202 
22203         WOLFSSL_ENTER("wolfSSL_BIO_new_file");
22204 
22205         if ((wolfSSL_BIO_get_fp(b, &fp) == SSL_SUCCESS) && (fp != NULL))
22206         {
22207             XFCLOSE(fp);
22208         }
22209 
22210         fp = XFOPEN(name, "r");
22211         if (fp == NULL)
22212             return SSL_BAD_FILE;
22213 
22214         if (wolfSSL_BIO_set_fp(b, fp, BIO_CLOSE) != SSL_SUCCESS) {
22215             XFCLOSE(fp);
22216             return SSL_BAD_FILE;
22217         }
22218 
22219         /* file is closed when bio is free'd */
22220         return SSL_SUCCESS;
22221     #else
22222         (void)name;
22223         (void)b;
22224         return SSL_NOT_IMPLEMENTED;
22225     #endif
22226     }
22227 
22228 #ifdef HAVE_ECC
22229     const char * wolfSSL_OBJ_nid2sn(int n) {
22230         int i;
22231         WOLFSSL_ENTER("wolfSSL_OBJ_nid2sn");
22232 
22233         /* find based on NID and return name */
22234         for (i = 0; i < ecc_sets[i].size; i++) {
22235             if (n == ecc_sets[i].id) {
22236                 return ecc_sets[i].name;
22237             }
22238         }
22239         return NULL;
22240     }
22241 
22242     int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o) {
22243         (void)o;
22244         WOLFSSL_ENTER("wolfSSL_OBJ_obj2nid");
22245         WOLFSSL_STUB("wolfSSL_OBJ_obj2nid");
22246 
22247         return 0;
22248     }
22249 
22250     int wolfSSL_OBJ_sn2nid(const char *sn) {
22251         int i;
22252         WOLFSSL_ENTER("wolfSSL_OBJ_osn2nid");
22253 
22254         /* Nginx uses this OpenSSL string. */
22255         if (XSTRNCMP(sn, "prime256v1", 10) == 0)
22256             sn = "SECP256R1";
22257         if (XSTRNCMP(sn, "secp384r1", 10) == 0)
22258             sn = "SECP384R1";
22259         /* find based on name and return NID */
22260         for (i = 0; i < ecc_sets[i].size; i++) {
22261             if (XSTRNCMP(sn, ecc_sets[i].name, ECC_MAXNAME) == 0) {
22262                 return ecc_sets[i].id;
22263             }
22264         }
22265         return -1;
22266     }
22267 #endif /* HAVE_ECC */
22268 
22269 
22270     void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx, int depth) {
22271         (void)ctx;
22272         (void)depth;
22273         WOLFSSL_ENTER("wolfSSL_CTX_set_verify_depth");
22274         WOLFSSL_STUB("wolfSSL_CTX_set_verify_depth");
22275 
22276     }
22277 
22278     void wolfSSL_set_verify_depth(WOLFSSL *ssl, int depth) {
22279         (void)ssl;
22280         (void)depth;
22281         WOLFSSL_ENTER("wolfSSL_set_verify_depth");
22282         WOLFSSL_STUB("wolfSSL_set_verify_depth");
22283 
22284     }
22285 
22286     void* wolfSSL_get_app_data( const WOLFSSL *ssl) {
22287         /* checkout exdata stuff... */
22288         return wolfSSL_get_ex_data(ssl,0);
22289     }
22290 
22291     int wolfSSL_set_app_data(WOLFSSL *ssl, void *arg) {
22292         return wolfSSL_set_ex_data(ssl,0,(char *)arg);
22293     }
22294 
22295     WOLFSSL_ASN1_OBJECT * wolfSSL_X509_NAME_ENTRY_get_object(WOLFSSL_X509_NAME_ENTRY *ne) {
22296         (void)ne;
22297         WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_object");
22298         WOLFSSL_STUB("wolfSSL_X509_NAME_ENTRY_get_object");
22299 
22300         return NULL;
22301     }
22302 
22303     WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(
22304                                              WOLFSSL_X509_NAME *name, int loc) {
22305 
22306         int maxLoc = name->fullName.fullNameLen;
22307 
22308         WOLFSSL_ENTER("wolfSSL_X509_NAME_get_entry");
22309 
22310         if (loc < 0 || loc > maxLoc) {
22311             WOLFSSL_MSG("Bad argument");
22312             return NULL;
22313         }
22314 
22315         /* common name index case */
22316         if (loc == name->fullName.cnIdx) {
22317             /* get CN shortcut from x509 since it has null terminator */
22318             name->cnEntry.data.data   = name->x509->subjectCN;
22319             name->cnEntry.data.length = name->fullName.cnLen;
22320             name->cnEntry.data.type   = ASN_COMMON_NAME;
22321             name->cnEntry.set  = 1;
22322             return &(name->cnEntry);
22323         }
22324 
22325         /* additionall cases to check for go here */
22326 
22327         WOLFSSL_MSG("Entry not found or implemented");
22328         (void)name;
22329         (void)loc;
22330 
22331         return NULL;
22332     }
22333 
22334     void wolfSSL_sk_X509_NAME_pop_free(STACK_OF(WOLFSSL_X509_NAME)* sk, void f (WOLFSSL_X509_NAME*)){
22335         (void) sk;
22336         (void) f;
22337         WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_pop_free");
22338         WOLFSSL_STUB("wolfSSL_sk_X509_NAME_pop_free");
22339     }
22340 
22341     int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key){
22342         (void) x509;
22343         (void) key;
22344         WOLFSSL_ENTER("wolfSSL_X509_check_private_key");
22345         WOLFSSL_STUB("wolfSSL_X509_check_private_key");
22346 
22347         return SSL_SUCCESS;
22348     }
22349 
22350     STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list( STACK_OF(WOLFSSL_X509_NAME) *sk ){
22351         (void) sk;
22352         WOLFSSL_ENTER("wolfSSL_dup_CA_list");
22353         WOLFSSL_STUB("wolfSSL_dup_CA_list");
22354 
22355         return NULL;
22356     }
22357 
22358 #endif /* HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE || HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
22359 #endif /* OPENSSL_EXTRA */
22360 
22361 
22362 #ifdef OPENSSL_EXTRA
22363 
22364 /* wolfSSL uses negative values for error states. This function returns an
22365  * unsigned type so the value returned is the absolute value of the error.
22366  */
22367 unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line)
22368 {
22369     WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
22370 
22371     (void)line;
22372     (void)file;
22373 #if defined(WOLFSSL_NGINX) || defined(DEBUG_WOLFSSL) || defined(WOLFSSL_HAPROXY)
22374     {
22375         int ret;
22376 
22377         if ((ret = wc_PeekErrorNode(-1, file, NULL, line)) < 0) {
22378             WOLFSSL_MSG("Issue peeking at error node in queue");
22379             return 0;
22380         }
22381     #ifdef WOLFSSL_NGINX
22382         if (ret == -SSL_NO_PEM_HEADER)
22383             return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
22384     #endif
22385         return (unsigned long)ret;
22386     }
22387 #else
22388     return (unsigned long)(0 - NOT_COMPILED_IN);
22389 #endif
22390 }
22391 
22392 
22393 #ifndef NO_CERTS
22394 int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey)
22395 {
22396     WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey");
22397 
22398     if (ctx == NULL || pkey == NULL) {
22399         return SSL_FAILURE;
22400     }
22401 
22402     return wolfSSL_CTX_use_PrivateKey_buffer(ctx,
22403                                        (const unsigned char*)pkey->pkey.ptr,
22404                                        pkey->pkey_sz, PRIVATEKEY_TYPE);
22405 }
22406 #endif /* !NO_CERTS */
22407 
22408 
22409 void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx)
22410 {
22411     WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
22412     #ifdef HAVE_EX_DATA
22413     if(ctx != NULL && idx < MAX_EX_DATA && idx >= 0) {
22414         return ctx->ex_data[idx];
22415     }
22416     #else
22417     (void)ctx;
22418     (void)idx;
22419     #endif
22420     return NULL;
22421 }
22422 
22423 int wolfSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b,
22424                                 void* c)
22425 {
22426     static int ctx_idx = 0;
22427 
22428     WOLFSSL_ENTER("wolfSSL_CTX_get_ex_new_index");
22429     (void)idx;
22430     (void)arg;
22431     (void)a;
22432     (void)b;
22433     (void)c;
22434 
22435     return ctx_idx++;
22436 }
22437 
22438 
22439 int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data)
22440 {
22441     WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data");
22442     #ifdef HAVE_EX_DATA
22443     if (ctx != NULL && idx < MAX_EX_DATA)
22444     {
22445         ctx->ex_data[idx] = data;
22446         return SSL_SUCCESS;
22447     }
22448     #else
22449     (void)ctx;
22450     (void)idx;
22451     (void)data;
22452     #endif
22453     return SSL_FAILURE;
22454 }
22455 
22456 
22457 int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data)
22458 {
22459     WOLFSSL_ENTER("wolfSSL_set_ex_data");
22460 #if defined(HAVE_EX_DATA) || defined(FORTRESS)
22461     if (ssl != NULL && idx < MAX_EX_DATA)
22462     {
22463         ssl->ex_data[idx] = data;
22464         return SSL_SUCCESS;
22465     }
22466 #else
22467     (void)ssl;
22468     (void)idx;
22469     (void)data;
22470 #endif
22471     return SSL_FAILURE;
22472 }
22473 
22474 
22475 int wolfSSL_get_ex_new_index(long idx, void* data, void* cb1, void* cb2,
22476                          void* cb3)
22477 {
22478     static int ssl_idx = 0;
22479 
22480     WOLFSSL_ENTER("wolfSSL_get_ex_new_index");
22481     (void)idx;
22482     (void)data;
22483     (void)cb1;
22484     (void)cb2;
22485     (void)cb3;
22486 
22487     return ssl_idx++;
22488 }
22489 
22490 
22491 void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx)
22492 {
22493     WOLFSSL_ENTER("wolfSSL_get_ex_data");
22494 #if defined(HAVE_EX_DATA) || defined(FORTRESS)
22495     if (ssl != NULL && idx < MAX_EX_DATA && idx >= 0)
22496         return ssl->ex_data[idx];
22497 #else
22498     (void)ssl;
22499     (void)idx;
22500 #endif
22501     return 0;
22502 }
22503 
22504 #ifndef NO_DSA
22505 WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO *bp, WOLFSSL_DSA **x,
22506         pem_password_cb *cb, void *u)
22507 {
22508     WOLFSSL_DSA* dsa;
22509     DsaKey* key;
22510     int    length;
22511     unsigned char*  buf;
22512     word32 bufSz;
22513     int ret;
22514     word32 idx = 0;
22515     DerBuffer* pDer;
22516 
22517     WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSAparams");
22518 
22519     ret = wolfSSL_BIO_get_mem_data(bp, &buf);
22520     if (ret <= 0) {
22521         WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret);
22522         return NULL;
22523     }
22524 
22525     bufSz = (word32)ret;
22526 
22527     if (cb != NULL || u != NULL) {
22528         /*
22529          * cb is for a call back when encountering encrypted PEM files
22530          * if cb == NULL and u != NULL then u = null terminated password string
22531          */
22532         WOLFSSL_MSG("Not yet supporting call back or password for encrypted PEM");
22533     }
22534 
22535     if ((ret = PemToDer(buf, (long)bufSz, DSA_PARAM_TYPE, &pDer, NULL, NULL,
22536                     NULL)) < 0 ) {
22537         WOLFSSL_MSG("Issue converting from PEM to DER");
22538         return NULL;
22539     }
22540 
22541     if ((ret = GetSequence(pDer->buffer, &idx, &length, pDer->length)) < 0) {
22542         WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret);
22543         FreeDer(&pDer);
22544         return NULL;
22545     }
22546 
22547     dsa = wolfSSL_DSA_new();
22548     if (dsa == NULL) {
22549         FreeDer(&pDer);
22550         WOLFSSL_MSG("Error creating DSA struct");
22551         return NULL;
22552     }
22553 
22554     key = (DsaKey*)dsa->internal;
22555     if (key == NULL) {
22556         FreeDer(&pDer);
22557         wolfSSL_DSA_free(dsa);
22558         WOLFSSL_MSG("Error finding DSA key struct");
22559         return NULL;
22560     }
22561 
22562     if (GetInt(&key->p,  pDer->buffer, &idx, pDer->length) < 0 ||
22563         GetInt(&key->q,  pDer->buffer, &idx, pDer->length) < 0 ||
22564         GetInt(&key->g,  pDer->buffer, &idx, pDer->length) < 0 ) {
22565         WOLFSSL_MSG("dsa key error");
22566         FreeDer(&pDer);
22567         wolfSSL_DSA_free(dsa);
22568         return NULL;
22569     }
22570 
22571     if (SetIndividualExternal(&dsa->p, &key->p) != SSL_SUCCESS) {
22572         WOLFSSL_MSG("dsa p key error");
22573         FreeDer(&pDer);
22574         wolfSSL_DSA_free(dsa);
22575         return NULL;
22576     }
22577 
22578     if (SetIndividualExternal(&dsa->q, &key->q) != SSL_SUCCESS) {
22579         WOLFSSL_MSG("dsa q key error");
22580         FreeDer(&pDer);
22581         wolfSSL_DSA_free(dsa);
22582         return NULL;
22583     }
22584 
22585     if (SetIndividualExternal(&dsa->g, &key->g) != SSL_SUCCESS) {
22586         WOLFSSL_MSG("dsa g key error");
22587         FreeDer(&pDer);
22588         wolfSSL_DSA_free(dsa);
22589         return NULL;
22590     }
22591 
22592     if (x != NULL) {
22593         *x = dsa;
22594     }
22595 
22596     FreeDer(&pDer);
22597     return dsa;
22598 }
22599 #endif /* NO_DSA */
22600 
22601 #include "src/bio.c"
22602 
22603 #endif /* OPENSSL_EXTRA */
22604 
22605 
22606 #if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
22607     || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA) || defined(WOLFSSL_HAPROXY)
22608 char * wolfSSL_OBJ_nid2ln(int n) {
22609     (void)n;
22610     WOLFSSL_ENTER("wolfSSL_OBJ_nid2ln");
22611     WOLFSSL_STUB("wolfSSL_OBJ_nid2ln");
22612 
22613     return NULL;
22614 }
22615 
22616 int wolfSSL_OBJ_txt2nid(const char* s) {
22617     (void)s;
22618     WOLFSSL_ENTER("wolfSSL_OBJ_txt2nid");
22619     WOLFSSL_STUB("wolfSSL_OBJ_txt2nid");
22620 
22621     return 0;
22622 }
22623 
22624 
22625 WOLFSSL_BIO *wolfSSL_BIO_new_file(const char *filename, const char *mode)
22626 {
22627 #ifndef NO_FILESYSTEM
22628     WOLFSSL_BIO* bio;
22629     XFILE fp;
22630 
22631     WOLFSSL_ENTER("wolfSSL_BIO_new_file");
22632 
22633     fp = XFOPEN(filename, mode);
22634     if (fp == NULL)
22635         return NULL;
22636 
22637     bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
22638     if (bio == NULL) {
22639         XFCLOSE(fp);
22640         return bio;
22641     }
22642 
22643     if (wolfSSL_BIO_set_fp(bio, fp, BIO_CLOSE) != SSL_SUCCESS) {
22644         XFCLOSE(fp);
22645         wolfSSL_BIO_free(bio);
22646         bio = NULL;
22647     }
22648 
22649     /* file is closed when BIO is free'd */
22650     return bio;
22651 #else
22652     (void)filename;
22653     (void)mode;
22654     return NULL;
22655 #endif
22656 }
22657 
22658 
22659 #ifndef NO_DH
22660 WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bio, WOLFSSL_DH **x,
22661         pem_password_cb *cb, void *u)
22662 {
22663 #ifndef NO_FILESYSTEM
22664     WOLFSSL_DH* localDh = NULL;
22665     unsigned char* mem  = NULL;
22666     word32 size;
22667     long   sz;
22668     int    ret;
22669     DerBuffer *der = NULL;
22670     byte*  p = NULL;
22671     byte*  g = NULL;
22672     word32 pSz = MAX_DH_SIZE;
22673     word32 gSz = MAX_DH_SIZE;
22674     int    memAlloced = 0;
22675 
22676     WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DHparams");
22677     (void)cb;
22678     (void)u;
22679 
22680     if (bio == NULL) {
22681         WOLFSSL_MSG("Bad Function Argument bio is NULL");
22682         return NULL;
22683     }
22684 
22685     if (bio->type == BIO_MEMORY) {
22686         /* Use the buffer directly. */
22687         ret = wolfSSL_BIO_get_mem_data(bio, &mem);
22688         if (mem == NULL || ret <= 0) {
22689             WOLFSSL_MSG("Failed to get data from bio struct");
22690             goto end;
22691         }
22692         size = ret;
22693     }
22694     else if (bio->type == BIO_FILE) {
22695         /* Read whole file into a new buffer. */
22696         XFSEEK(bio->file, 0, SEEK_END);
22697         sz = XFTELL(bio->file);
22698         XFSEEK(bio->file, 0, SEEK_SET);
22699         if (sz <= 0L)
22700             goto end;
22701         mem = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22702         if (mem == NULL)
22703             goto end;
22704         memAlloced = 1;
22705 
22706         if (wolfSSL_BIO_read(bio, (char *)mem, (int)sz) <= 0)
22707             goto end;
22708         size = (word32)sz;
22709     }
22710     else {
22711         WOLFSSL_MSG("BIO type not supported for reading DH parameters");
22712         goto end;
22713     }
22714 
22715     ret = PemToDer(mem, size, DH_PARAM_TYPE, &der, NULL, NULL, NULL);
22716     if (ret != 0)
22717         goto end;
22718 
22719     /* Use the object passed in, otherwise allocate a new object */
22720     if (x != NULL)
22721         localDh = *x;
22722     if (localDh == NULL) {
22723         localDh = (WOLFSSL_DH*)XMALLOC(sizeof(WOLFSSL_DH), NULL,
22724                                        DYNAMIC_TYPE_OPENSSL);
22725         if (localDh == NULL)
22726             goto end;
22727         XMEMSET(localDh, 0, sizeof(WOLFSSL_DH));
22728     }
22729 
22730     /* Load data in manually */
22731     p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22732     g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22733     if (p == NULL || g == NULL)
22734         goto end;
22735 
22736     /* Extract the p and g as data from the DER encoded DH parameters. */
22737     ret = wc_DhParamsLoad(der->buffer, der->length, p, &pSz, g, &gSz);
22738     if (ret != 0) {
22739         if (x != NULL && localDh != *x)
22740             XFREE(localDh, NULL, DYNAMIC_TYPE_OPENSSL);
22741         localDh = NULL;
22742         goto end;
22743     }
22744 
22745     if (x != NULL)
22746         *x = localDh;
22747 
22748     /* Put p and g in as big numbers. */
22749     if (localDh->p != NULL) {
22750         wolfSSL_BN_free(localDh->p);
22751         localDh->p = NULL;
22752     }
22753     if (localDh->g != NULL) {
22754         wolfSSL_BN_free(localDh->g);
22755         localDh->g = NULL;
22756     }
22757     localDh->p = wolfSSL_BN_bin2bn(p, pSz, NULL);
22758     localDh->g = wolfSSL_BN_bin2bn(g, gSz, NULL);
22759     if (localDh->p == NULL || localDh->g == NULL) {
22760         if (x != NULL && localDh != *x)
22761             wolfSSL_DH_free(localDh);
22762         localDh = NULL;
22763     }
22764 
22765 end:
22766     if (memAlloced) XFREE(mem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22767     if (der != NULL) FreeDer(&der);
22768     XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22769     XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22770     return localDh;
22771 #else
22772     (void)bio;
22773     (void)x;
22774     (void)cb;
22775     (void)u;
22776     return NULL;
22777 #endif
22778 }
22779 #endif
22780 
22781 
22782 int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert)
22783 {
22784     byte* certDer;
22785     int derSz;
22786     int pemSz;
22787     int ret;
22788 
22789     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509");
22790 
22791     if (bio == NULL || cert == NULL) {
22792         return SSL_FAILURE;
22793     }
22794 
22795     if (bio->type != BIO_MEMORY) {
22796         WOLFSSL_MSG("BIO type not supported for writing X509 as PEM");
22797         return SSL_FAILURE;
22798     }
22799 
22800     certDer = cert->derCert->buffer;
22801     derSz   = cert->derCert->length;
22802 
22803     /* Get PEM encoded length and allocate memory for it. */
22804     pemSz = wc_DerToPem(certDer, derSz, NULL, 0, CERT_TYPE);
22805     if (pemSz < 0) {
22806         WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_X509", pemSz);
22807         return SSL_FAILURE;
22808     }
22809     if (bio->mem != NULL) {
22810         XFREE(bio->mem, NULL, DYNAMIC_TYPE_OPENSSL);
22811     }
22812     bio->mem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_OPENSSL);
22813     if (bio->mem == NULL) {
22814         return SSL_FAILURE;
22815     }
22816     bio->memLen = pemSz;
22817 
22818     ret = wc_DerToPemEx(certDer, derSz, bio->mem, bio->memLen, NULL, CERT_TYPE);
22819     if (ret < 0) {
22820         WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_X509", ret);
22821         return SSL_FAILURE;
22822     }
22823 
22824     return SSL_SUCCESS;
22825 }
22826 
22827 
22828 #if defined(OPENSSL_EXTRA) && !defined(NO_DH)
22829 /* Intialize ctx->dh with dh's params. Return SSL_SUCCESS on ok */
22830 long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL_DH* dh)
22831 {
22832     int pSz, gSz;
22833     byte *p, *g;
22834     int ret=0;
22835 
22836     WOLFSSL_ENTER("wolfSSL_CTX_set_tmp_dh");
22837 
22838     if(!ctx || !dh)
22839         return BAD_FUNC_ARG;
22840 
22841     /* Get needed size for p and g */
22842     pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
22843     gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
22844 
22845     if(pSz <= 0 || gSz <= 0)
22846         return SSL_FATAL_ERROR;
22847 
22848     p = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_DH_BUFFER);
22849     if(!p)
22850         return MEMORY_E;
22851 
22852     g = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_DH_BUFFER);
22853     if(!g) {
22854         XFREE(p, ctx->heap, DYNAMIC_TYPE_DH_BUFFER);
22855         return MEMORY_E;
22856     }
22857 
22858     pSz = wolfSSL_BN_bn2bin(dh->p, p);
22859     gSz = wolfSSL_BN_bn2bin(dh->g, g);
22860 
22861     if(pSz >= 0 && gSz >= 0) /* Conversion successful */
22862         ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
22863 
22864     XFREE(p, ctx->heap, DYNAMIC_TYPE_DH_BUFFER);
22865     XFREE(g, ctx->heap, DYNAMIC_TYPE_DH_BUFFER);
22866 
22867     return pSz > 0 && gSz > 0 ? ret : SSL_FATAL_ERROR;
22868 }
22869 #endif /* OPENSSL_EXTRA && !NO_DH */
22870 #endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_HAPROXY */
22871 
22872 
22873 /* stunnel compatibility functions*/
22874 #if defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX))
22875 void WOLFSSL_ERR_remove_thread_state(void* pid)
22876 {
22877     (void) pid;
22878     return;
22879 }
22880 
22881 /***TBD ***/
22882 void wolfSSL_print_all_errors_fp(XFILE *fp)
22883 {
22884     (void)fp;
22885 }
22886 
22887 int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION* session, int idx, void* data)
22888 {
22889     WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data");
22890 #ifdef HAVE_EX_DATA
22891     if(session != NULL && idx < MAX_EX_DATA) {
22892         session->ex_data[idx] = data;
22893         return SSL_SUCCESS;
22894     }
22895 #endif
22896     return SSL_FAILURE;
22897 }
22898 
22899 
22900 int wolfSSL_SESSION_get_ex_new_index(long idx, void* data, void* cb1,
22901        void* cb2, CRYPTO_free_func* cb3)
22902 {
22903     WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_new_index");
22904     (void)idx;
22905     (void)cb1;
22906     (void)cb2;
22907     (void)cb3;
22908     if(XSTRNCMP((const char*)data, "redirect index", 14) == 0) {
22909         return 0;
22910     }
22911     else if(XSTRNCMP((const char*)data, "addr index", 10) == 0) {
22912         return 1;
22913     }
22914     return SSL_FAILURE;
22915 }
22916 
22917 
22918 void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION* session, int idx)
22919 {
22920     WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_data");
22921 #ifdef HAVE_EX_DATA
22922     if (session != NULL && idx < MAX_EX_DATA && idx >= 0)
22923         return session->ex_data[idx];
22924 #endif
22925     return NULL;
22926 }
22927 
22928 
22929 int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
22930                                 void *(*r) (void *, size_t, const char *,
22931                                             int), void (*f) (void *))
22932 {
22933     (void) m;
22934     (void) r;
22935     (void) f;
22936     WOLFSSL_ENTER("wolfSSL_CRYPTO_set_mem_ex_functions");
22937     WOLFSSL_STUB("wolfSSL_CRYPTO_set_mem_ex_functions");
22938 
22939     return SSL_FAILURE;
22940 }
22941 
22942 
22943 WOLFSSL_DH *wolfSSL_DH_generate_parameters(int prime_len, int generator,
22944                            void (*callback) (int, int, void *), void *cb_arg)
22945 {
22946     (void)prime_len;
22947     (void)generator;
22948     (void)callback;
22949     (void)cb_arg;
22950     WOLFSSL_ENTER("wolfSSL_DH_generate_parameters");
22951     WOLFSSL_STUB("wolfSSL_DH_generate_parameters");
22952 
22953     return NULL;
22954 }
22955 
22956 int wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH* dh, int prime_len, int generator,
22957                            void (*callback) (int, int, void *))
22958 {
22959     (void)prime_len;
22960     (void)generator;
22961     (void)callback;
22962     (void)dh;
22963     WOLFSSL_ENTER("wolfSSL_DH_generate_parameters_ex");
22964     WOLFSSL_STUB("wolfSSL_DH_generate_parameters_ex");
22965 
22966     return -1;
22967 }
22968 
22969 
22970 void wolfSSL_ERR_load_crypto_strings(void)
22971 {
22972     WOLFSSL_ENTER("wolfSSL_ERR_load_crypto_strings");
22973     WOLFSSL_ENTER("wolfSSL_ERR_load_crypto_strings");
22974     return;
22975 }
22976 
22977 
22978 unsigned long wolfSSL_ERR_peek_last_error(void)
22979 {
22980     WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
22981 
22982 #ifdef WOLFSSL_NGINX
22983     {
22984         int ret;
22985 
22986         if ((ret = wc_PeekErrorNode(-1, NULL, NULL, NULL)) < 0) {
22987             WOLFSSL_MSG("Issue peeking at error node in queue");
22988             return 0;
22989         }
22990         if (ret == -SSL_NO_PEM_HEADER)
22991             return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
22992         return (unsigned long)ret;
22993     }
22994 #else
22995     return (unsigned long)(0 - NOT_COMPILED_IN);
22996 #endif
22997 }
22998 
22999 
23000 int wolfSSL_FIPS_mode(void)
23001 {
23002     WOLFSSL_ENTER("wolfSSL_FIPS_mode");
23003     WOLFSSL_STUB("wolfSSL_FIPS_mode");
23004 
23005     return SSL_FAILURE;
23006 }
23007 
23008 int wolfSSL_FIPS_mode_set(int r)
23009 {
23010     (void)r;
23011     WOLFSSL_ENTER("wolfSSL_FIPS_mode_set");
23012     WOLFSSL_STUB("wolfSSL_FIPS_mode_set");
23013 
23014     return SSL_FAILURE;
23015 }
23016 
23017 
23018 int wolfSSL_RAND_set_rand_method(const void *meth)
23019 {
23020     (void) meth;
23021     WOLFSSL_ENTER("wolfSSL_RAND_set_rand_method");
23022     WOLFSSL_STUB("wolfSSL_RAND_set_rand_method");
23023 
23024     return SSL_FAILURE;
23025 }
23026 
23027 
23028 int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits)
23029 {
23030     int ret = SSL_FAILURE;
23031     WOLFSSL_ENTER("wolfSSL_CIPHER_get_bits");
23032     if(c != NULL && c->ssl != NULL) {
23033         ret = 8 * c->ssl->specs.key_size;
23034         if(alg_bits != NULL) {
23035             *alg_bits = ret;
23036         }
23037     }
23038     return ret;
23039 }
23040 
23041 
23042 int wolfSSL_sk_X509_NAME_num(const STACK_OF(WOLFSSL_X509_NAME) *s)
23043 {
23044     WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_num");
23045 
23046     if (s == NULL)
23047         return -1;
23048     return (int)s->num;
23049 }
23050 
23051 
23052 int wolfSSL_sk_X509_num(const STACK_OF(WOLFSSL_X509) *s)
23053 {
23054     WOLFSSL_ENTER("wolfSSL_sk_X509_num");
23055 
23056     if (s == NULL)
23057         return -1;
23058     return (int)s->num;
23059 }
23060 
23061 
23062 int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
23063                 int indent, unsigned long flags)
23064 {
23065     int i;
23066     (void)flags;
23067     WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex");
23068 
23069     for (i = 0; i < indent; i++) {
23070         if (wolfSSL_BIO_write(bio, " ", 1) != 1)
23071             return SSL_FAILURE;
23072     }
23073 
23074     if (flags == XN_FLAG_RFC2253) {
23075         if (wolfSSL_BIO_write(bio, name->name + 1, name->sz - 2)
23076                                                                 != name->sz - 2)
23077             return SSL_FAILURE;
23078     }
23079     else if (wolfSSL_BIO_write(bio, name->name, name->sz) != name->sz)
23080         return SSL_FAILURE;
23081 
23082     return SSL_SUCCESS;
23083 }
23084 
23085 
23086 WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr(const WOLFSSL_X509* x)
23087 {
23088     (void)x;
23089     WOLFSSL_ENTER("wolfSSL_X509_get0_pubkey_bitstr");
23090     WOLFSSL_STUB("wolfSSL_X509_get0_pubkey_bitstr");
23091 
23092     return NULL;
23093 }
23094 
23095 
23096 int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
23097 {
23098     (void)ctx;
23099     (void)session;
23100     WOLFSSL_ENTER("wolfSSL_CTX_add_session");
23101     WOLFSSL_STUB("wolfSSL_CTX_add_session");
23102 
23103     return SSL_SUCCESS;
23104 }
23105 
23106 
23107 int wolfSSL_get_state(const WOLFSSL* ssl)
23108 {
23109     (void)ssl;
23110     WOLFSSL_ENTER("wolfSSL_get_state");
23111     WOLFSSL_STUB("wolfSSL_get_state");
23112 
23113     return SSL_FAILURE;
23114 }
23115 
23116 
23117 void* wolfSSL_sk_X509_NAME_value(const STACK_OF(WOLFSSL_X509_NAME)* sk, int i)
23118 {
23119     WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_value");
23120 
23121     for (; sk != NULL && i > 0; i--)
23122         sk = sk->next;
23123 
23124     if (i != 0 || sk == NULL)
23125         return NULL;
23126     return sk->data.name;
23127 }
23128 
23129 
23130 void* wolfSSL_sk_X509_value(STACK_OF(WOLFSSL_X509)* sk, int i)
23131 {
23132     WOLFSSL_ENTER("wolfSSL_sk_X509_value");
23133 
23134     for (; sk != NULL && i > 0; i--)
23135         sk = sk->next;
23136 
23137     if (i != 0 || sk == NULL)
23138         return NULL;
23139     return sk->data.x509;
23140 }
23141 
23142 
23143 int wolfSSL_version(WOLFSSL* ssl)
23144 {
23145     WOLFSSL_ENTER("wolfSSL_version");
23146     if (ssl->version.major == SSLv3_MAJOR) {
23147         switch (ssl->version.minor) {
23148             case SSLv3_MINOR :
23149                 return SSL3_VERSION;
23150             case TLSv1_MINOR :
23151             case TLSv1_1_MINOR :
23152             case TLSv1_2_MINOR :
23153             case TLSv1_3_MINOR :
23154                 return TLS1_VERSION;
23155             default:
23156                 return SSL_FAILURE;
23157         }
23158     }
23159     else if (ssl->version.major == DTLS_MAJOR) {
23160         switch (ssl->version.minor) {
23161             case DTLS_MINOR :
23162             case DTLSv1_2_MINOR :
23163                 return DTLS1_VERSION;
23164             default:
23165                 return SSL_FAILURE;
23166         }
23167     }
23168     return SSL_FAILURE;
23169 }
23170 
23171 
23172 STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL* ssl)
23173 {
23174     (void)ssl;
23175     WOLFSSL_ENTER("wolfSSL_get_peer_cert_chain");
23176     WOLFSSL_STUB("wolfSSL_get_peer_cert_chain");
23177 
23178     return NULL;
23179 }
23180 
23181 
23182 WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl)
23183 {
23184     WOLFSSL_ENTER("wolfSSL_get_SSL_CTX");
23185     return ssl->ctx;
23186 }
23187 
23188 int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME* name)
23189 {
23190     WOLFSSL_ENTER("wolfSSL_X509_NAME_get_sz");
23191     if(!name)
23192         return -1;
23193     return name->sz;
23194 }
23195 
23196 
23197 #ifdef HAVE_SNI
23198 int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name)
23199 {
23200     int ret;
23201     WOLFSSL_ENTER("wolfSSL_set_tlsext_host_name");
23202     ret = wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME,
23203             host_name, XSTRLEN(host_name));
23204     WOLFSSL_LEAVE("wolfSSL_set_tlsext_host_name", ret);
23205     return ret;
23206 }
23207 
23208 
23209 #ifndef NO_WOLFSSL_SERVER
23210 const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type)
23211 {
23212     void * serverName = NULL;
23213     if (ssl == NULL)
23214         return NULL;
23215     TLSX_SNI_GetRequest(ssl->extensions, type, &serverName);
23216     return (const char *)serverName;
23217 }
23218 #endif /* NO_WOLFSSL_SERVER */
23219 #endif /* HAVE_SNI */
23220 
23221 WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
23222 {
23223     if (ssl && ctx && SetSSL_CTX(ssl, ctx, 0) == SSL_SUCCESS)
23224         return ssl->ctx;
23225     return NULL;
23226 }
23227 
23228 
23229 VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX* ctx)
23230 {
23231     WOLFSSL_ENTER("wolfSSL_CTX_get_verify_callback");
23232     if(ctx)
23233         return ctx->verifyCallback;
23234     return NULL;
23235 }
23236 
23237 
23238 void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
23239 {
23240     WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
23241     if (ctx)
23242         ctx->sniRecvCb = cb;
23243 }
23244 
23245 int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
23246                                                CallbackSniRecv cb)
23247 {
23248     WOLFSSL_ENTER("wolfSSL_CTX_set_tlsext_servername_callback");
23249     if (ctx) {
23250         ctx->sniRecvCb = cb;
23251         return 1;
23252     }
23253     return 0;
23254 }
23255 
23256 void wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
23257 {
23258     WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
23259     if (ctx)
23260         ctx->sniRecvCbArg = arg;
23261 }
23262 
23263 
23264 long wolfSSL_CTX_clear_options(WOLFSSL_CTX* ctx, long opt)
23265 {
23266     WOLFSSL_ENTER("SSL_CTX_clear_options");
23267     WOLFSSL_STUB("SSL_CTX_clear_options");
23268     (void)ctx;
23269     (void)opt;
23270     return opt;
23271 }
23272 
23273 void wolfSSL_THREADID_set_callback(void(*threadid_func)(void*))
23274 {
23275     WOLFSSL_ENTER("wolfSSL_THREADID_set_callback");
23276     WOLFSSL_STUB("wolfSSL_THREADID_set_callback");
23277     (void)threadid_func;
23278     return;
23279 }
23280 
23281 void wolfSSL_THREADID_set_numeric(void* id, unsigned long val)
23282 {
23283     WOLFSSL_ENTER("wolfSSL_THREADID_set_numeric");
23284     WOLFSSL_STUB("wolfSSL_THREADID_set_numeric");
23285     (void)id;
23286     (void)val;
23287     return;
23288 }
23289 
23290 
23291 STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs(WOLFSSL_X509_STORE_CTX* ctx,
23292                                                 WOLFSSL_X509_NAME* name)
23293 {
23294     WOLFSSL_ENTER("wolfSSL_X509_STORE_get1_certs");
23295     WOLFSSL_STUB("wolfSSL_X509_STORE_get1_certs");
23296     (void)ctx;
23297     (void)name;
23298     return NULL;
23299 }
23300 
23301 void wolfSSL_sk_X509_pop_free(STACK_OF(WOLFSSL_X509)* sk, void f (WOLFSSL_X509*)){
23302     (void) sk;
23303     (void) f;
23304     WOLFSSL_ENTER("wolfSSL_sk_X509_pop_free");
23305     WOLFSSL_STUB("wolfSSL_sk_X509_pop_free");
23306 }
23307 
23308 #endif /* OPENSSL_EXTRA and HAVE_STUNNEL */
23309 #if defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX))\
23310     || defined(WOLFSSL_HAPROXY)
23311 
23312 
23313 const byte* wolfSSL_SESSION_get_id(WOLFSSL_SESSION* sess, unsigned int* idLen)
23314 {
23315     WOLFSSL_ENTER("wolfSSL_SESSION_get_id");
23316     if(!sess || !idLen) {
23317         WOLFSSL_MSG("Bad func args. Please provide idLen");
23318         return NULL;
23319     }
23320     *idLen = sess->sessionIDSz;
23321     return sess->sessionID;
23322 }
23323 #endif
23324 
23325 #if (defined(OPENSSL_EXTRA) && defined(HAVE_STUNNEL)) \
23326     || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
23327 int wolfSSL_CTX_get_verify_mode(WOLFSSL_CTX* ctx)
23328 {
23329     int mode = 0;
23330     WOLFSSL_ENTER("wolfSSL_CTX_get_verify_mode");
23331 
23332     if(!ctx)
23333         return SSL_FATAL_ERROR;
23334 
23335     if (ctx->verifyPeer)
23336         mode |= SSL_VERIFY_PEER;
23337     else if (ctx->verifyNone)
23338         mode |= SSL_VERIFY_NONE;
23339 
23340     if (ctx->failNoCert)
23341         mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
23342 
23343     if (ctx->failNoCertxPSK)
23344         mode |= SSL_VERIFY_FAIL_EXCEPT_PSK;
23345 
23346     WOLFSSL_LEAVE("wolfSSL_CTX_get_verify_mode", mode);
23347     return mode;
23348 }
23349 #endif
23350 
23351 #if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE25519)
23352 /* return 1 if success, 0 if error
23353  * output keys are little endian format
23354  */
23355 int wolfSSL_EC25519_generate_key(unsigned char *priv, unsigned int *privSz,
23356                                  unsigned char *pub, unsigned int *pubSz)
23357 {
23358 #ifndef WOLFSSL_KEY_GEN
23359     WOLFSSL_MSG("No Key Gen built in");
23360     (void) priv;
23361     (void) privSz;
23362     (void) pub;
23363     (void) pubSz;
23364     return SSL_FAILURE;
23365 #else /* WOLFSSL_KEY_GEN */
23366     int ret = SSL_FAILURE;
23367     int initTmpRng = 0;
23368     WC_RNG *rng = NULL;
23369 #ifdef WOLFSSL_SMALL_STACK
23370     WC_RNG *tmpRNG = NULL;
23371 #else
23372     WC_RNG tmpRNG[1];
23373 #endif
23374 
23375     WOLFSSL_ENTER("wolfSSL_EC25519_generate_key");
23376 
23377     if (priv == NULL || privSz == NULL || *privSz < CURVE25519_KEYSIZE ||
23378         pub == NULL || pubSz == NULL || *pubSz < CURVE25519_KEYSIZE) {
23379         WOLFSSL_MSG("Bad arguments");
23380         return SSL_FAILURE;
23381     }
23382 
23383 #ifdef WOLFSSL_SMALL_STACK
23384     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
23385     if (tmpRNG == NULL)
23386         return SSL_FAILURE;
23387 #endif
23388     if (wc_InitRng(tmpRNG) == 0) {
23389         rng = tmpRNG;
23390         initTmpRng = 1;
23391     }
23392     else {
23393         WOLFSSL_MSG("Bad RNG Init, trying global");
23394         if (initGlobalRNG == 0)
23395             WOLFSSL_MSG("Global RNG no Init");
23396         else
23397             rng = &globalRNG;
23398     }
23399 
23400     if (rng) {
23401         curve25519_key key;
23402 
23403         if (wc_curve25519_init(&key) != MP_OKAY)
23404             WOLFSSL_MSG("wc_curve25519_init failed");
23405         else if (wc_curve25519_make_key(rng, CURVE25519_KEYSIZE, &key)!=MP_OKAY)
23406             WOLFSSL_MSG("wc_curve25519_make_key failed");
23407         /* export key pair */
23408         else if (wc_curve25519_export_key_raw_ex(&key, priv, privSz, pub,
23409                                                  pubSz, EC25519_LITTLE_ENDIAN)
23410                  != MP_OKAY)
23411             WOLFSSL_MSG("wc_curve25519_export_key_raw_ex failed");
23412         else
23413             ret = SSL_SUCCESS;
23414 
23415         wc_curve25519_free(&key);
23416     }
23417 
23418     if (initTmpRng)
23419         wc_FreeRng(tmpRNG);
23420 
23421 #ifdef WOLFSSL_SMALL_STACK
23422     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23423 #endif
23424 
23425     return ret;
23426 #endif /* WOLFSSL_KEY_GEN */
23427 }
23428 
23429 /* return 1 if success, 0 if error
23430  * input and output keys are little endian format
23431  */
23432 int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz,
23433                                const unsigned char *priv, unsigned int privSz,
23434                                const unsigned char *pub, unsigned int pubSz)
23435 {
23436 #ifndef WOLFSSL_KEY_GEN
23437     WOLFSSL_MSG("No Key Gen built in");
23438     (void) shared;
23439     (void) sharedSz;
23440     (void) priv;
23441     (void) privSz;
23442     (void) pub;
23443     (void) pubSz;
23444     return SSL_FAILURE;
23445 #else /* WOLFSSL_KEY_GEN */
23446     int ret = SSL_FAILURE;
23447     curve25519_key privkey, pubkey;
23448 
23449     WOLFSSL_ENTER("wolfSSL_EC25519_shared_key");
23450 
23451     if (shared == NULL || sharedSz == NULL || *sharedSz < CURVE25519_KEYSIZE ||
23452         priv == NULL || privSz < CURVE25519_KEYSIZE ||
23453         pub == NULL || pubSz < CURVE25519_KEYSIZE) {
23454         WOLFSSL_MSG("Bad arguments");
23455         return SSL_FAILURE;
23456     }
23457 
23458     /* import private key */
23459     if (wc_curve25519_init(&privkey) != MP_OKAY) {
23460         WOLFSSL_MSG("wc_curve25519_init privkey failed");
23461         return ret;
23462     }
23463     if (wc_curve25519_import_private_ex(priv, privSz, &privkey,
23464                                         EC25519_LITTLE_ENDIAN) != MP_OKAY) {
23465         WOLFSSL_MSG("wc_curve25519_import_private_ex failed");
23466         wc_curve25519_free(&privkey);
23467         return ret;
23468     }
23469 
23470     /* import public key */
23471     if (wc_curve25519_init(&pubkey) != MP_OKAY) {
23472         WOLFSSL_MSG("wc_curve25519_init pubkey failed");
23473         wc_curve25519_free(&privkey);
23474         return ret;
23475     }
23476     if (wc_curve25519_import_public_ex(pub, pubSz, &pubkey,
23477                                        EC25519_LITTLE_ENDIAN) != MP_OKAY) {
23478         WOLFSSL_MSG("wc_curve25519_import_public_ex failed");
23479         wc_curve25519_free(&privkey);
23480         wc_curve25519_free(&pubkey);
23481         return ret;
23482     }
23483 
23484     if (wc_curve25519_shared_secret_ex(&privkey, &pubkey,
23485                                        shared, sharedSz,
23486                                        EC25519_LITTLE_ENDIAN) != MP_OKAY)
23487         WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
23488     else
23489         ret = SSL_SUCCESS;
23490 
23491     wc_curve25519_free(&privkey);
23492     wc_curve25519_free(&pubkey);
23493 
23494     return ret;
23495 #endif /* WOLFSSL_KEY_GEN */
23496 }
23497 #endif /* OPENSSL_EXTRA && HAVE_CURVE25519 */
23498 
23499 #if defined(OPENSSL_EXTRA) && defined(HAVE_ED25519)
23500 /* return 1 if success, 0 if error
23501  * output keys are little endian format
23502  */
23503 int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz,
23504                                  unsigned char *pub, unsigned int *pubSz)
23505 {
23506 #ifndef WOLFSSL_KEY_GEN
23507     WOLFSSL_MSG("No Key Gen built in");
23508     (void) priv;
23509     (void) privSz;
23510     (void) pub;
23511     (void) pubSz;
23512     return SSL_FAILURE;
23513 #else /* WOLFSSL_KEY_GEN */
23514     int ret = SSL_FAILURE;
23515     int initTmpRng = 0;
23516     WC_RNG *rng = NULL;
23517 #ifdef WOLFSSL_SMALL_STACK
23518     WC_RNG *tmpRNG = NULL;
23519 #else
23520     WC_RNG tmpRNG[1];
23521 #endif
23522 
23523     WOLFSSL_ENTER("wolfSSL_ED25519_generate_key");
23524 
23525     if (priv == NULL || privSz == NULL || *privSz < ED25519_PRV_KEY_SIZE ||
23526         pub == NULL || pubSz == NULL || *pubSz < ED25519_PUB_KEY_SIZE) {
23527         WOLFSSL_MSG("Bad arguments");
23528         return SSL_FAILURE;
23529     }
23530 
23531 #ifdef WOLFSSL_SMALL_STACK
23532     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
23533     if (tmpRNG == NULL)
23534         return SSL_FATAL_ERROR;
23535 #endif
23536     if (wc_InitRng(tmpRNG) == 0) {
23537         rng = tmpRNG;
23538         initTmpRng = 1;
23539     }
23540     else {
23541         WOLFSSL_MSG("Bad RNG Init, trying global");
23542         if (initGlobalRNG == 0)
23543             WOLFSSL_MSG("Global RNG no Init");
23544         else
23545             rng = &globalRNG;
23546     }
23547 
23548     if (rng) {
23549         ed25519_key key;
23550 
23551         if (wc_ed25519_init(&key) != MP_OKAY)
23552             WOLFSSL_MSG("wc_ed25519_init failed");
23553         else if (wc_ed25519_make_key(rng, ED25519_KEY_SIZE, &key)!=MP_OKAY)
23554             WOLFSSL_MSG("wc_ed25519_make_key failed");
23555         /* export private key */
23556         else if (wc_ed25519_export_key(&key, priv, privSz, pub, pubSz)!=MP_OKAY)
23557             WOLFSSL_MSG("wc_ed25519_export_key failed");
23558         else
23559             ret = SSL_SUCCESS;
23560 
23561         wc_ed25519_free(&key);
23562     }
23563 
23564     if (initTmpRng)
23565         wc_FreeRng(tmpRNG);
23566 
23567 #ifdef WOLFSSL_SMALL_STACK
23568     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23569 #endif
23570 
23571     return ret;
23572 #endif /* WOLFSSL_KEY_GEN */
23573 }
23574 
23575 /* return 1 if success, 0 if error
23576  * input and output keys are little endian format
23577  * priv is a buffer containing private and public part of key
23578  */
23579 int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
23580                          const unsigned char *priv, unsigned int privSz,
23581                          unsigned char *sig, unsigned int *sigSz)
23582 {
23583 #ifndef WOLFSSL_KEY_GEN
23584     WOLFSSL_MSG("No Key Gen built in");
23585     (void) msg;
23586     (void) msgSz;
23587     (void) priv;
23588     (void) privSz;
23589     (void) sig;
23590     (void) sigSz;
23591     return SSL_FAILURE;
23592 #else /* WOLFSSL_KEY_GEN */
23593     ed25519_key key;
23594     int ret = SSL_FAILURE;
23595 
23596     WOLFSSL_ENTER("wolfSSL_ED25519_sign");
23597 
23598     if (priv == NULL || privSz != ED25519_PRV_KEY_SIZE ||
23599         msg == NULL || sig == NULL || *sigSz < ED25519_SIG_SIZE) {
23600         WOLFSSL_MSG("Bad arguments");
23601         return SSL_FAILURE;
23602     }
23603 
23604     /* import key */
23605     if (wc_ed25519_init(&key) != MP_OKAY) {
23606         WOLFSSL_MSG("wc_curve25519_init failed");
23607         return ret;
23608     }
23609     if (wc_ed25519_import_private_key(priv, privSz/2,
23610                                       priv+(privSz/2), ED25519_PUB_KEY_SIZE,
23611                                       &key) != MP_OKAY){
23612         WOLFSSL_MSG("wc_ed25519_import_private failed");
23613         wc_ed25519_free(&key);
23614         return ret;
23615     }
23616 
23617     if (wc_ed25519_sign_msg(msg, msgSz, sig, sigSz, &key) != MP_OKAY)
23618         WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
23619     else
23620         ret = SSL_SUCCESS;
23621 
23622     wc_ed25519_free(&key);
23623 
23624     return ret;
23625 #endif /* WOLFSSL_KEY_GEN */
23626 }
23627 
23628 /* return 1 if success, 0 if error
23629  * input and output keys are little endian format
23630  * pub is a buffer containing public part of key
23631  */
23632 int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
23633                            const unsigned char *pub, unsigned int pubSz,
23634                            const unsigned char *sig, unsigned int sigSz)
23635 {
23636 #ifndef WOLFSSL_KEY_GEN
23637     WOLFSSL_MSG("No Key Gen built in");
23638     (void) msg;
23639     (void) msgSz;
23640     (void) pub;
23641     (void) pubSz;
23642     (void) sig;
23643     (void) sigSz;
23644     return SSL_FAILURE;
23645 #else /* WOLFSSL_KEY_GEN */
23646     ed25519_key key;
23647     int ret = SSL_FAILURE, check = 0;
23648 
23649     WOLFSSL_ENTER("wolfSSL_ED25519_verify");
23650 
23651     if (pub == NULL || pubSz != ED25519_PUB_KEY_SIZE ||
23652         msg == NULL || sig == NULL || sigSz != ED25519_SIG_SIZE) {
23653         WOLFSSL_MSG("Bad arguments");
23654         return SSL_FAILURE;
23655     }
23656 
23657     /* import key */
23658     if (wc_ed25519_init(&key) != MP_OKAY) {
23659         WOLFSSL_MSG("wc_curve25519_init failed");
23660         return ret;
23661     }
23662     if (wc_ed25519_import_public(pub, pubSz, &key) != MP_OKAY){
23663         WOLFSSL_MSG("wc_ed25519_import_public failed");
23664         wc_ed25519_free(&key);
23665         return ret;
23666     }
23667 
23668     if ((ret = wc_ed25519_verify_msg((byte*)sig, sigSz, msg, msgSz,
23669                                      &check, &key)) != MP_OKAY) {
23670         WOLFSSL_MSG("wc_ed25519_verify_msg failed");
23671     }
23672     else if (!check)
23673         WOLFSSL_MSG("wc_ed25519_verify_msg failed (signature invalid)");
23674     else
23675         ret = SSL_SUCCESS;
23676 
23677     wc_ed25519_free(&key);
23678 
23679     return ret;
23680 #endif /* WOLFSSL_KEY_GEN */
23681 }
23682 
23683 #endif /* OPENSSL_EXTRA && HAVE_ED25519 */
23684 
23685 #ifdef WOLFSSL_JNI
23686 
23687 int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr)
23688 {
23689     WOLFSSL_ENTER("wolfSSL_set_jobject");
23690     if (ssl != NULL)
23691     {
23692         ssl->jObjectRef = objPtr;
23693         return SSL_SUCCESS;
23694     }
23695     return SSL_FAILURE;
23696 }
23697 
23698 void* wolfSSL_get_jobject(WOLFSSL* ssl)
23699 {
23700     WOLFSSL_ENTER("wolfSSL_get_jobject");
23701     if (ssl != NULL)
23702         return ssl->jObjectRef;
23703     return NULL;
23704 }
23705 
23706 #endif /* WOLFSSL_JNI */
23707 
23708 
23709 #ifdef WOLFSSL_ASYNC_CRYPT
23710 int wolfSSL_CTX_AsyncPoll(WOLFSSL_CTX* ctx, WOLF_EVENT** events, int maxEvents,
23711     WOLF_EVENT_FLAG flags, int* eventCount)
23712 {
23713     if (ctx == NULL) {
23714         return BAD_FUNC_ARG;
23715     }
23716 
23717     return wolfAsync_EventQueuePoll(&ctx->event_queue, NULL,
23718                                         events, maxEvents, flags, eventCount);
23719 }
23720 
23721 int wolfSSL_AsyncPoll(WOLFSSL* ssl, WOLF_EVENT_FLAG flags)
23722 {
23723     int ret, eventCount = 0;
23724     WOLF_EVENT* events[1];
23725 
23726     if (ssl == NULL) {
23727         return BAD_FUNC_ARG;
23728     }
23729 
23730     ret = wolfAsync_EventQueuePoll(&ssl->ctx->event_queue, ssl,
23731         events, sizeof(events)/sizeof(events), flags, &eventCount);
23732     if (ret == 0) {
23733         ret = eventCount;
23734     }
23735 
23736     return ret;
23737 }
23738 
23739 #endif /* WOLFSSL_ASYNC_CRYPT */
23740 
23741 #ifdef OPENSSL_EXTRA
23742 unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line,
23743                                                const char **data, int *flags)
23744 {
23745     WOLFSSL_ENTER("wolfSSL_ERR_peek_error_line_data");
23746 
23747     (void)line;
23748     (void)file;
23749 
23750     /* No data or flags stored - error display only in Nginx. */
23751     if (data != NULL) {
23752         *data = "";
23753     }
23754     if (flags != NULL) {
23755         *flags = 0;
23756     }
23757 
23758 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
23759     {
23760         int ret = 0;
23761 
23762         while (1) {
23763             if ((ret = wc_PeekErrorNode(-1, file, NULL, line)) < 0) {
23764                 WOLFSSL_MSG("Issue peeking at error node in queue");
23765                 return 0;
23766             }
23767             ret = -ret;
23768 
23769             if (ret == SSL_NO_PEM_HEADER)
23770                 return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
23771             if (ret != WANT_READ && ret != WANT_WRITE &&
23772                     ret != ZERO_RETURN && ret != SSL_ERROR_ZERO_RETURN &&
23773                     ret != SOCKET_PEER_CLOSED_E && ret != SOCKET_ERROR_E)
23774                 break;
23775 
23776             wc_RemoveErrorNode(-1);
23777         }
23778 
23779         return (unsigned long)ret;
23780     }
23781 #else
23782     return (unsigned long)(0 - NOT_COMPILED_IN);
23783 #endif
23784 }
23785 #endif
23786 
23787 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
23788 
23789 STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl)
23790 {
23791     (void)ssl;
23792     WOLFSSL_STUB("wolfSSL_get_ciphers_compat");
23793     return NULL;
23794 }
23795 
23796 void wolfSSL_OPENSSL_config(char *config_name)
23797 {
23798     WOLFSSL_STUB("wolfSSL_OPENSSL_config");
23799     (void)config_name;
23800 }
23801 
23802 int wolfSSL_X509_get_ex_new_index(int idx, void *arg, void *a, void *b, void *c)
23803 {
23804     static int x509_idx = 0;
23805 
23806     WOLFSSL_ENTER("wolfSSL_X509_get_ex_new_index");
23807     (void)idx;
23808     (void)arg;
23809     (void)a;
23810     (void)b;
23811     (void)c;
23812 
23813     return x509_idx++;
23814 }
23815 
23816 void *wolfSSL_X509_get_ex_data(X509 *x509, int idx)
23817 {
23818     WOLFSSL_ENTER("wolfSSL_X509_get_ex_data");
23819     #ifdef HAVE_EX_DATA
23820     if (x509 != NULL && idx < MAX_EX_DATA && idx >= 0) {
23821         return x509->ex_data[idx];
23822     }
23823     #else
23824     (void)x509;
23825     (void)idx;
23826     #endif
23827     return NULL;
23828 }
23829 int wolfSSL_X509_set_ex_data(X509 *x509, int idx, void *data)
23830 {
23831     WOLFSSL_ENTER("wolfSSL_X509_set_ex_data");
23832     #ifdef HAVE_EX_DATA
23833     if (x509 != NULL && idx < MAX_EX_DATA)
23834     {
23835         x509->ex_data[idx] = data;
23836         return SSL_SUCCESS;
23837     }
23838     #else
23839     (void)x509;
23840     (void)idx;
23841     (void)data;
23842     #endif
23843     return SSL_FAILURE;
23844 }
23845 int wolfSSL_X509_NAME_digest(const WOLFSSL_X509_NAME *name,
23846         const WOLFSSL_EVP_MD *type, unsigned char *md, unsigned int *len)
23847 {
23848     WOLFSSL_ENTER("wolfSSL_X509_NAME_digest");
23849 
23850     if (name == NULL || type == NULL)
23851         return SSL_FAILURE;
23852 
23853     return wolfSSL_EVP_Digest((unsigned char*)name->fullName.fullName,
23854                               name->fullName.fullNameLen, md, len, type, NULL);
23855 }
23856 
23857 long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx)
23858 {
23859     WOLFSSL_ENTER("wolfSSL_SSL_CTX_get_timeout");
23860 
23861     if (ctx == NULL)
23862         return 0;
23863 
23864     return ctx->timeout;
23865 }
23866 
23867 #ifdef HAVE_ECC
23868 int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx, WOLFSSL_EC_KEY *ecdh)
23869 {
23870     WOLFSSL_ENTER("wolfSSL_SSL_CTX_set_tmp_ecdh");
23871 
23872     if (ctx == NULL || ecdh == NULL)
23873         return BAD_FUNC_ARG;
23874 
23875     ctx->ecdhCurveOID = ecdh->group->curve_oid;
23876 
23877     return SSL_SUCCESS;
23878 }
23879 #endif
23880 
23881 /* Assumes that the session passed in is from the cache. */
23882 int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *s)
23883 {
23884     WOLFSSL_ENTER("wolfSSL_SSL_CTX_remove_session");
23885 
23886     if (ctx == NULL || s == NULL)
23887         return BAD_FUNC_ARG;
23888 
23889 #ifdef HAVE_EXT_CACHE
23890     if (!ctx->internalCacheOff)
23891 #endif
23892     {
23893         /* Don't remove session just timeout session. */
23894         s->timeout = 0;
23895     }
23896 
23897 #ifdef HAVE_EXT_CACHE
23898     if (ctx->rem_sess_cb != NULL)
23899         ctx->rem_sess_cb(ctx, s);
23900 #endif
23901 
23902     return 0;
23903 }
23904 
23905 BIO *wolfSSL_SSL_get_rbio(const WOLFSSL *s)
23906 {
23907     WOLFSSL_ENTER("wolfSSL_SSL_get_rbio");
23908     (void)s;
23909     /* Nginx sets the buffer size if the read BIO is different to write BIO.
23910      * The setting buffer size doesn't do anything so return NULL for both.
23911      */
23912     return NULL;
23913 }
23914 BIO *wolfSSL_SSL_get_wbio(const WOLFSSL *s)
23915 {
23916     WOLFSSL_ENTER("wolfSSL_SSL_get_wbio");
23917     (void)s;
23918     /* Nginx sets the buffer size if the read BIO is different to write BIO.
23919      * The setting buffer size doesn't do anything so return NULL for both.
23920      */
23921     return NULL;
23922 }
23923 
23924 int wolfSSL_SSL_do_handshake(WOLFSSL *s)
23925 {
23926     WOLFSSL_ENTER("wolfSSL_SSL_do_handshake");
23927 
23928     if (s == NULL)
23929         return SSL_FAILURE;
23930 
23931     if (s->options.side == WOLFSSL_CLIENT_END)
23932         return wolfSSL_connect(s);
23933     return wolfSSL_accept(s);
23934 }
23935 
23936 int wolfSSL_SSL_in_init(WOLFSSL *s)
23937 {
23938     WOLFSSL_ENTER("wolfSSL_SSL_in_init");
23939 
23940     if (s == NULL)
23941         return SSL_FAILURE;
23942 
23943     if (s->options.side == WOLFSSL_CLIENT_END)
23944         return s->options.connectState < SECOND_REPLY_DONE;
23945     return s->options.acceptState < ACCEPT_THIRD_REPLY_DONE;
23946 }
23947 
23948 WOLFSSL_SESSION *wolfSSL_SSL_get0_session(const WOLFSSL *ssl)
23949 {
23950     WOLFSSL_SESSION *session;
23951 
23952     WOLFSSL_ENTER("wolfSSL_SSL_get0_session");
23953 
23954     if (ssl == NULL) {
23955         return NULL;
23956     }
23957 
23958     session = wolfSSL_get_session((WOLFSSL*)ssl);
23959 
23960 #ifdef HAVE_EXT_CACHE
23961     ((WOLFSSL*)ssl)->extSession = session;
23962 #endif
23963 
23964     return session;
23965 }
23966 
23967 int wolfSSL_X509_check_host(X509 *x, const char *chk, size_t chklen,
23968                     unsigned int flags, char **peername)
23969 {
23970     int         ret;
23971     DecodedCert dCert;
23972 
23973     WOLFSSL_ENTER("wolfSSL_X509_check_host");
23974 
23975     /* flags and peername not needed for Nginx. */
23976     (void)flags;
23977     (void)peername;
23978 
23979     InitDecodedCert(&dCert, x->derCert->buffer, x->derCert->length, NULL);
23980     ret = ParseCertRelative(&dCert, CERT_TYPE, 0, NULL);
23981     if (ret != 0)
23982         return SSL_FAILURE;
23983 
23984     ret = CheckHostName(&dCert, (char *)chk, chklen);
23985     FreeDecodedCert(&dCert);
23986     if (ret != 0)
23987         return SSL_FAILURE;
23988     return SSL_SUCCESS;
23989 }
23990 
23991 int wolfSSL_i2a_ASN1_INTEGER(BIO *bp, const WOLFSSL_ASN1_INTEGER *a)
23992 {
23993     static char num[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
23994                             '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
23995     int    i;
23996     word32 j;
23997     word32 len = 0;
23998 
23999     WOLFSSL_ENTER("wolfSSL_i2a_ASN1_INTEGER");
24000 
24001     if (bp == NULL || a == NULL)
24002         return SSL_FAILURE;
24003 
24004     /* Skip ASN.1 INTEGER (type) byte. */
24005     i = 1;
24006     /* When indefinte length, can't determine length with data available. */
24007     if (a->data[i] == 0x80)
24008         return 0;
24009     /* One length byte if less than 0x80. */
24010     if (a->data[i] < 0x80)
24011         len = a->data[i++];
24012     /* Multiple length byte if greater than 0x80. */
24013     else if (a->data[i] > 0x80) {
24014         switch (a->data[i++] - 0x80) {
24015             case 4:
24016                 len |= a->data[i++] << 24;
24017             case 3:
24018                 len |= a->data[i++] << 16;
24019             case 2:
24020                 len |= a->data[i++] <<  8;
24021             case 1:
24022                 len |= a->data[i++];
24023                 break;
24024             default:
24025                 /* Not supporting greater than 4 bytes of length. */
24026                 return 0;
24027         }
24028     }
24029 
24030     /* Zero length integer is the value zero. */
24031     if (len == 0) {
24032         wolfSSL_BIO_write(bp, "00", 2);
24033         return 2;
24034     }
24035 
24036     /* Don't do negative - just write out every byte. */
24037     for (j = 0; j < len; i++,j++) {
24038         wolfSSL_BIO_write(bp, &num[a->data[i] >> 4], 1);
24039         wolfSSL_BIO_write(bp, &num[a->data[i] & 0xf], 1);
24040     }
24041 
24042     /* Two nibbles written for each byte. */
24043     return len * 2;
24044 }
24045 
24046 
24047 #ifdef HAVE_SESSION_TICKET
24048 /* Expected return values from implementations of OpenSSL ticket key callback.
24049  */
24050 #define TICKET_KEY_CB_RET_FAILURE    -1
24051 #define TICKET_KEY_CB_RET_NOT_FOUND   0
24052 #define TICKET_KEY_CB_RET_OK          1
24053 #define TICKET_KEY_CB_RET_RENEW       2
24054 
24055 /* The ticket key callback as used in OpenSSL is stored here. */
24056 static int (*ticketKeyCb)(WOLFSSL *ssl, unsigned char *name, unsigned char *iv,
24057     WOLFSSL_EVP_CIPHER_CTX *ectx, WOLFSSL_HMAC_CTX *hctx, int enc) = NULL;
24058 
24059 /* Implementation of session ticket encryption/decryption using OpenSSL
24060  * callback to initialize the cipher and HMAC.
24061  *
24062  * ssl           The SSL/TLS object.
24063  * keyName       The key name - used to identify the key to be used.
24064  * iv            The IV to use.
24065  * mac           The MAC of the encrypted data.
24066  * enc           Encrypt ticket.
24067  * encTicket     The ticket data.
24068  * encTicketLen  The length of the ticket data.
24069  * encLen        The encrypted/decrypted ticket length - output length.
24070  * ctx           Ignored. Application specific data.
24071  * returns WOLFSSL_TICKET_RET_OK to indicate success,
24072  *         WOLFSSL_TICKET_RET_CREATE if a new ticket is required and
24073  *         WOLFSSL_TICKET_RET_FATAL on error.
24074  */
24075 static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
24076                                   unsigned char keyName[WOLFSSL_TICKET_NAME_SZ],
24077                                   unsigned char iv[WOLFSSL_TICKET_IV_SZ],
24078                                   unsigned char mac[WOLFSSL_TICKET_MAC_SZ],
24079                                   int enc, unsigned char* encTicket,
24080                                   int encTicketLen, int* encLen, void* ctx)
24081 {
24082     byte                    digest[MAX_DIGEST_SIZE];
24083     WOLFSSL_EVP_CIPHER_CTX  evpCtx;
24084     WOLFSSL_HMAC_CTX        hmacCtx;
24085     unsigned int            mdSz = 0;
24086     int                     len = 0;
24087     int                     ret = WOLFSSL_TICKET_RET_FATAL;
24088     int                     res;
24089 
24090     (void)ctx;
24091 
24092     if (ticketKeyCb == NULL)
24093         return WOLFSSL_TICKET_RET_FATAL;
24094 
24095     wolfSSL_EVP_CIPHER_CTX_init(&evpCtx);
24096     /* Initialize the cipher and HMAC. */
24097     res = ticketKeyCb(ssl, keyName, iv, &evpCtx, &hmacCtx, enc);
24098     if (res != TICKET_KEY_CB_RET_OK && res != TICKET_KEY_CB_RET_RENEW)
24099         return WOLFSSL_TICKET_RET_FATAL;
24100 
24101     if (enc)
24102     {
24103         /* Encrypt in place. */
24104         if (!wolfSSL_EVP_CipherUpdate(&evpCtx, encTicket, &len,
24105                                       encTicket, encTicketLen))
24106             goto end;
24107         encTicketLen = len;
24108         if (!wolfSSL_EVP_EncryptFinal(&evpCtx, &encTicket[encTicketLen], &len))
24109             goto end;
24110         /* Total length of encrypted data. */
24111         encTicketLen += len;
24112         *encLen = encTicketLen;
24113 
24114         /* HMAC the encrypted data into the parameter 'mac'. */
24115         wolfSSL_HMAC_Update(&hmacCtx, encTicket, encTicketLen);
24116         wolfSSL_HMAC_Final(&hmacCtx, mac, &mdSz);
24117     }
24118     else
24119     {
24120         /* HMAC the encrypted data and compare it to the passed in data. */
24121         wolfSSL_HMAC_Update(&hmacCtx, encTicket, encTicketLen);
24122         wolfSSL_HMAC_Final(&hmacCtx, digest, &mdSz);
24123         if (XMEMCMP(mac, digest, mdSz) != 0)
24124             goto end;
24125 
24126         /* Decrypt the ticket data in place. */
24127         if (!wolfSSL_EVP_CipherUpdate(&evpCtx, encTicket, &len,
24128                                       encTicket, encTicketLen))
24129             goto end;
24130         encTicketLen = len;
24131         if (!wolfSSL_EVP_DecryptFinal(&evpCtx, &encTicket[encTicketLen], &len))
24132             goto end;
24133         /* Total length of decrypted data. */
24134         *encLen = encTicketLen + len;
24135     }
24136 
24137     ret = (res == TICKET_KEY_CB_RET_RENEW) ? WOLFSSL_TICKET_RET_CREATE :
24138                                              WOLFSSL_TICKET_RET_OK;
24139 end:
24140     return ret;
24141 }
24142 
24143 /* Set the callback to use when encrypting/decrypting tickets.
24144  *
24145  * ctx  The SSL/TLS context object.
24146  * cb   The OpenSSL session ticket callback.
24147  * returns SSL_SUCCESS to indicate success.
24148  */
24149 int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *ctx, int (*cb)(
24150     WOLFSSL *ssl, unsigned char *name, unsigned char *iv,
24151     WOLFSSL_EVP_CIPHER_CTX *ectx, WOLFSSL_HMAC_CTX *hctx, int enc))
24152 {
24153     /* Store callback in a global. */
24154     ticketKeyCb = cb;
24155     /* Set the ticket encryption callback to be a wrapper around OpenSSL
24156      * callback.
24157      */
24158     ctx->ticketEncCb = wolfSSL_TicketKeyCb;
24159 
24160     return SSL_SUCCESS;
24161 }
24162 #endif /* HAVE_SESSION_TICKET */
24163 
24164 #ifdef HAVE_OCSP
24165 /* Not an OpenSSL API. */
24166 int wolfSSL_get_ocsp_response(WOLFSSL* ssl, byte** response)
24167 {
24168     *response = ssl->ocspResp;
24169     return ssl->ocspRespSz;
24170 }
24171 
24172 /* Not an OpenSSL API. */
24173 char* wolfSSL_get_ocsp_url(WOLFSSL* ssl)
24174 {
24175     return ssl->url;
24176 }
24177 
24178 /* Not an OpenSSL API. */
24179 int wolfSSL_set_ocsp_url(WOLFSSL* ssl, char* url)
24180 {
24181     if (ssl == NULL)
24182         return SSL_FAILURE;
24183 
24184     ssl->url = url;
24185     return SSL_SUCCESS;
24186 }
24187 
24188 static INLINE void ato24(const byte* c, word32* u24)
24189 {
24190     *u24 = (c[0] << 16) | (c[1] << 8) | c[2];
24191 }
24192 
24193 int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, STACK_OF(X509)** chain)
24194 {
24195     word32         idx;
24196     word32         length;
24197     WOLFSSL_STACK* node;
24198     WOLFSSL_STACK* last = NULL;
24199 
24200     if (ctx == NULL || chain == NULL) {
24201         chain = NULL;
24202         return SSL_FAILURE;
24203     }
24204     if (ctx->x509Chain != NULL) {
24205         *chain = ctx->x509Chain;
24206         return SSL_SUCCESS;
24207     }
24208 
24209     /* If there are no chains then success! */
24210     *chain = NULL;
24211     if (ctx->certChain == NULL || ctx->certChain->length == 0) {
24212         return SSL_SUCCESS;
24213     }
24214 
24215     /* Create a new stack of WOLFSSL_X509 object from chain buffer. */
24216     for (idx = 0; idx < ctx->certChain->length; ) {
24217         node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
24218                                        DYNAMIC_TYPE_OPENSSL);
24219         if (node == NULL)
24220             return SSL_FAILURE;
24221         node->next = NULL;
24222 
24223         /* 3 byte length | X509 DER data */
24224         ato24(ctx->certChain->buffer + idx, &length);
24225         idx += 3;
24226 
24227         /* Create a new X509 from DER encoded data. */
24228         node->data.x509 = wolfSSL_X509_d2i(NULL, ctx->certChain->buffer + idx,
24229             length);
24230         if (node->data.x509 == NULL) {
24231             XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
24232             /* Return as much of the chain as we created. */
24233             ctx->x509Chain = *chain;
24234             return SSL_FAILURE;
24235         }
24236         idx += length;
24237 
24238         /* Add object to the end of the stack. */
24239         if (last == NULL) {
24240             node->num = 1;
24241             *chain = node;
24242         }
24243         else {
24244             (*chain)->num++;
24245             last->next = node;
24246         }
24247 
24248         last = node;
24249     }
24250 
24251     ctx->x509Chain = *chain;
24252 
24253     return SSL_SUCCESS;
24254 }
24255 
24256 int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx,
24257     int(*cb)(WOLFSSL*, void*))
24258 {
24259     if (ctx == NULL || ctx->cm == NULL)
24260         return SSL_FAILURE;
24261 
24262     /* Ensure stapling is on for callback to be used. */
24263     wolfSSL_CTX_EnableOCSPStapling(ctx);
24264 
24265     if (ctx->cm->ocsp_stapling == NULL)
24266         return SSL_FAILURE;
24267 
24268     ctx->cm->ocsp_stapling->statusCb = cb;
24269     return SSL_SUCCESS;
24270 }
24271 
24272 int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer,
24273     WOLFSSL_X509_STORE_CTX *ctx, WOLFSSL_X509 *x)
24274 {
24275     WOLFSSL_STACK* node;
24276     Signer* ca = NULL;
24277 #ifdef WOLFSSL_SMALL_STACK
24278     DecodedCert* cert = NULL;
24279 #else
24280     DecodedCert  cert[1];
24281 #endif
24282 
24283     if (issuer == NULL || ctx == NULL || x == NULL)
24284         return SSL_FATAL_ERROR;
24285 
24286     if (ctx->chain != NULL) {
24287         for (node = ctx->chain; node != NULL; node = node->next) {
24288             if (wolfSSL_X509_check_issued(node->data.x509, x) == X509_V_OK) {
24289                 *issuer = x;
24290                 return SSL_SUCCESS;
24291             }
24292         }
24293     }
24294 
24295 
24296 #ifdef WOLFSSL_SMALL_STACK
24297     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
24298                                  DYNAMIC_TYPE_TMP_BUFFER);
24299     if (cert == NULL)
24300         return SSL_FAILURE;
24301 #endif
24302 
24303     /* Use existing CA retrieval APIs that use DecodedCert. */
24304     InitDecodedCert(cert, x->derCert->buffer, x->derCert->length, NULL);
24305     if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
24306     #ifndef NO_SKID
24307         if (cert->extAuthKeyIdSet)
24308             ca = GetCA(ctx->store->cm, cert->extAuthKeyId);
24309         if (ca == NULL)
24310             ca = GetCAByName(ctx->store->cm, cert->issuerHash);
24311     #else /* NO_SKID */
24312         ca = GetCA(ctx->store->cm, cert->issuerHash);
24313     #endif /* NO SKID */
24314     }
24315     FreeDecodedCert(cert);
24316 #ifdef WOLFSSL_SMALL_STACK
24317     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
24318 #endif
24319 
24320     if (ca == NULL)
24321         return SSL_FAILURE;
24322 
24323     *issuer = (WOLFSSL_X509 *)XMALLOC(sizeof(WOLFSSL_X509), 0,
24324         DYNAMIC_TYPE_OPENSSL);
24325     if (*issuer == NULL)
24326         return SSL_FAILURE;
24327 
24328     /* Create an empty certificate as CA doesn't have a certificate. */
24329     XMEMSET(*issuer, 0, sizeof(WOLFSSL_X509));
24330     /* TODO: store the full certificate and dup when required. */
24331 
24332     /* Result is ignored when passed to wolfSSL_OCSP_cert_to_id(). */
24333 
24334     return SSL_SUCCESS;
24335 }
24336 
24337 void wolfSSL_X509_email_free(STACK_OF(WOLFSSL_STRING) *sk)
24338 {
24339     WOLFSSL_STACK *curr;
24340 
24341     while (sk != NULL) {
24342         curr = sk;
24343         sk = sk->next;
24344 
24345         XFREE(curr, NULL, DYNAMIC_TYPE_OPENSSL);
24346     }
24347 }
24348 
24349 STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 *x)
24350 {
24351     WOLFSSL_STACK *list = NULL;
24352 
24353     if (x->authInfoSz == 0)
24354         return NULL;
24355 
24356     list = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
24357                                    DYNAMIC_TYPE_OPENSSL);
24358     if (list == NULL)
24359         return NULL;
24360 
24361     list->data.string = (char*)x->authInfo;
24362     list->next = NULL;
24363 
24364     return list;
24365 }
24366 
24367 int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject)
24368 {
24369     WOLFSSL_X509_NAME *issuerName = wolfSSL_X509_get_issuer_name(subject);
24370     WOLFSSL_X509_NAME *subjectName = wolfSSL_X509_get_subject_name(issuer);
24371 
24372     if (issuerName == NULL || subjectName == NULL)
24373         return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
24374 
24375     /* Literal matching of encoded names and key ids. */
24376     if (issuerName->sz != subjectName->sz ||
24377            XMEMCMP(issuerName->name, subjectName->name, subjectName->sz) != 0) {
24378         return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
24379     }
24380 
24381     if (subject->authKeyId != NULL && issuer->subjKeyId != NULL) {
24382         if (subject->authKeyIdSz != issuer->subjKeyIdSz ||
24383                 XMEMCMP(subject->authKeyId, issuer->subjKeyId,
24384                         issuer->subjKeyIdSz) != 0) {
24385             return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
24386         }
24387     }
24388 
24389     return X509_V_OK;
24390 }
24391 
24392 WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x)
24393 {
24394     return wolfSSL_X509_d2i(NULL, x->derCert->buffer, x->derCert->length);
24395 }
24396 
24397 char* wolfSSL_sk_WOLFSSL_STRING_value(STACK_OF(WOLFSSL_STRING)* strings,
24398     int idx)
24399 {
24400     for (; idx > 0 && strings != NULL; idx--)
24401         strings = strings->next;
24402     if (strings == NULL)
24403         return NULL;
24404     return strings->data.string;
24405 }
24406 #endif /* HAVE_OCSP */
24407 
24408 #ifdef HAVE_ALPN
24409 void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl, const unsigned char **data,
24410                                 unsigned int *len)
24411 {
24412     word16 nameLen;
24413 
24414     if (ssl != NULL && data != NULL && len != NULL) {
24415         TLSX_ALPN_GetRequest(ssl->extensions, (void **)data, &nameLen);
24416         *len = nameLen;
24417     }
24418 }
24419 
24420 int wolfSSL_select_next_proto(unsigned char **out, unsigned char *outLen,
24421                               const unsigned char *in, unsigned int inLen,
24422                               const unsigned char *clientNames,
24423                               unsigned int clientLen)
24424 {
24425     unsigned int i, j;
24426     byte lenIn, lenClient;
24427 
24428     if (out == NULL || outLen == NULL || in == NULL || clientNames == NULL)
24429         return OPENSSL_NPN_UNSUPPORTED;
24430 
24431     for (i = 0; i < inLen; i += lenIn) {
24432         lenIn = in[i++];
24433         for (j = 0; j < clientLen; j += lenClient) {
24434             lenClient = clientNames[j++];
24435 
24436             if (lenIn != lenClient)
24437                 continue;
24438 
24439             if (XMEMCMP(in + i, clientNames + j, lenIn) == 0) {
24440                 *out = (unsigned char *)(in + i);
24441                 *outLen = lenIn;
24442                 return OPENSSL_NPN_NEGOTIATED;
24443             }
24444         }
24445     }
24446 
24447     *out = (unsigned char *)clientNames + 1;
24448     *outLen = clientNames[0];
24449     return OPENSSL_NPN_NO_OVERLAP;
24450 }
24451 
24452 void wolfSSL_CTX_set_alpn_select_cb(WOLFSSL_CTX *ctx,
24453                                     int (*cb) (WOLFSSL *ssl,
24454                                                const unsigned char **out,
24455                                                unsigned char *outlen,
24456                                                const unsigned char *in,
24457                                                unsigned int inlen,
24458                                                void *arg), void *arg)
24459 {
24460     if (ctx != NULL) {
24461         ctx->alpnSelect = cb;
24462         ctx->alpnSelectArg = arg;
24463     }
24464 }
24465 
24466 void wolfSSL_CTX_set_next_protos_advertised_cb(WOLFSSL_CTX *s,
24467                                            int (*cb) (WOLFSSL *ssl,
24468                                                       const unsigned char
24469                                                       **out,
24470                                                       unsigned int *outlen,
24471                                                       void *arg), void *arg)
24472 {
24473     (void)s;
24474     (void)cb;
24475     (void)arg;
24476     WOLFSSL_STUB("wolfSSL_CTX_set_next_protos_advertised_cb");
24477 }
24478 
24479 void wolfSSL_CTX_set_next_proto_select_cb(WOLFSSL_CTX *s,
24480                                       int (*cb) (WOLFSSL *ssl,
24481                                                  unsigned char **out,
24482                                                  unsigned char *outlen,
24483                                                  const unsigned char *in,
24484                                                  unsigned int inlen,
24485                                                  void *arg), void *arg)
24486 {
24487     (void)s;
24488     (void)cb;
24489     (void)arg;
24490     WOLFSSL_STUB("wolfSSL_CTX_set_next_proto_select_cb");
24491 }
24492 
24493 void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s, const unsigned char **data,
24494                                     unsigned *len)
24495 {
24496     (void)s;
24497     (void)data;
24498     (void)len;
24499     WOLFSSL_STUB("wolfSSL_get0_next_proto_negotiated");
24500 }
24501 #endif /* HAVE_ALPN */
24502 
24503 #endif /* WOLFSSL_NGINX  / WOLFSSL_HAPROXY */
24504 
24505 #ifdef OPENSSL_EXTRA
24506 int wolfSSL_CTX_set_msg_callback(WOLFSSL_CTX *ctx, SSL_Msg_Cb cb)
24507 {
24508     WOLFSSL_STUB("SSL_CTX_set_msg_callback");
24509     (void)ctx;
24510     (void)cb;
24511     return SSL_FAILURE;
24512 }
24513 int wolfSSL_set_msg_callback(WOLFSSL *ssl, SSL_Msg_Cb cb)
24514 {
24515     WOLFSSL_STUB("SSL_set_msg_callback");
24516     (void)ssl;
24517     (void)cb;
24518     return SSL_FAILURE;
24519 }
24520 int wolfSSL_CTX_set_msg_callback_arg(WOLFSSL_CTX *ctx, void* arg)
24521 {
24522     WOLFSSL_STUB("SSL_CTX_set_msg_callback_arg");
24523     (void)ctx;
24524     (void)arg;
24525     return SSL_FAILURE;
24526 }
24527 int wolfSSL_set_msg_callback_arg(WOLFSSL *ssl, void* arg)
24528 {
24529     WOLFSSL_STUB("SSL_set_msg_callback_arg");
24530     (void)ssl;
24531     (void)arg;
24532     return SSL_FAILURE;
24533 }
24534 #endif
24535 
24536 
24537 #endif /* WOLFCRYPT_ONLY */
24538