Renesas / SecureDweet
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     #include <wolfcrypt/src/misc.c>
00042 #endif
00043 
00044 
00045 #ifndef WOLFSSL_ALLOW_NO_SUITES
00046     #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA) \
00047                   && !defined(WOLFSSL_STATIC_DH) && !defined(WOLFSSL_STATIC_PSK)
00048         #error "No cipher suites defined because DH disabled, ECC disabled, and no static suites defined. Please see top of README"
00049     #endif
00050 #endif
00051 
00052 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
00053                               defined(WOLFSSL_KEY_GEN)
00054     #include <wolfssl/openssl/evp.h>
00055     /* openssl headers end, wolfssl internal headers next */
00056     #include <wolfssl/wolfcrypt/wc_encrypt.h>
00057 #endif
00058 
00059 #ifdef OPENSSL_EXTRA
00060     /* openssl headers begin */
00061     #include <wolfssl/openssl/hmac.h>
00062     #include <wolfssl/openssl/crypto.h>
00063     #include <wolfssl/openssl/des.h>
00064     #include <wolfssl/openssl/bn.h>
00065     #include <wolfssl/openssl/dh.h>
00066     #include <wolfssl/openssl/rsa.h>
00067     #include <wolfssl/openssl/pem.h>
00068     #include <wolfssl/openssl/ec.h>
00069     #include <wolfssl/openssl/ec25519.h>
00070     #include <wolfssl/openssl/ed25519.h>
00071     #include <wolfssl/openssl/ecdsa.h>
00072     #include <wolfssl/openssl/ecdh.h>
00073     /* openssl headers end, wolfssl internal headers next */
00074     #include <wolfssl/wolfcrypt/hmac.h>
00075     #include <wolfssl/wolfcrypt/random.h>
00076     #include <wolfssl/wolfcrypt/des3.h>
00077     #include <wolfssl/wolfcrypt/md4.h>
00078     #include <wolfssl/wolfcrypt/md5.h>
00079     #include <wolfssl/wolfcrypt/arc4.h>
00080     #include <wolfssl/wolfcrypt/idea.h>
00081     #include <wolfssl/wolfcrypt/curve25519.h>
00082     #include <wolfssl/wolfcrypt/ed25519.h>
00083     #ifdef HAVE_STUNNEL
00084         #include <wolfssl/openssl/ocsp.h>
00085     #endif /* WITH_STUNNEL */
00086     #ifdef WOLFSSL_SHA512
00087         #include <wolfssl/wolfcrypt/sha512.h>
00088     #endif
00089 #endif
00090 
00091 #ifndef NO_FILESYSTEM
00092     #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR) \
00093             && !defined(EBSNET)
00094         #include <dirent.h>
00095         #include <sys/stat.h>
00096     #endif
00097     #ifdef EBSNET
00098         #include "vfapi.h"
00099         #include "vfile.h"
00100     #endif
00101 #endif /* NO_FILESYSTEM */
00102 
00103 #ifndef TRUE
00104     #define TRUE  1
00105 #endif
00106 #ifndef FALSE
00107     #define FALSE 0
00108 #endif
00109 
00110 #ifndef WOLFSSL_HAVE_MIN
00111 #define WOLFSSL_HAVE_MIN
00112 
00113     static INLINE word32 min(word32 a, word32 b)
00114     {
00115         return a > b ? b : a;
00116     }
00117 
00118 #endif /* WOLFSSSL_HAVE_MIN */
00119 
00120 #if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_HAVE_MAX)
00121 #define WOLFSSL_HAVE_MAX
00122 
00123     static INLINE word32 max(word32 a, word32 b)
00124     {
00125         return a > b ? a : b;
00126     }
00127 
00128 #endif /* WOLFSSL_DTLS && !WOLFSSL_HAVE_MAX */
00129 
00130 
00131 #ifndef WOLFSSL_LEANPSK
00132 char* mystrnstr(const char* s1, const char* s2, unsigned int n)
00133 {
00134     unsigned int s2_len = (unsigned int)XSTRLEN(s2);
00135 
00136     if (s2_len == 0)
00137         return (char*)s1;
00138 
00139     while (n >= s2_len && s1[0]) {
00140         if (s1[0] == s2[0])
00141             if (XMEMCMP(s1, s2, s2_len) == 0)
00142                 return (char*)s1;
00143         s1++;
00144         n--;
00145     }
00146 
00147     return NULL;
00148 }
00149 #endif
00150 
00151 
00152 /* prevent multiple mutex initializations */
00153 static volatile int initRefCount = 0;
00154 static wolfSSL_Mutex count_mutex;   /* init ref count mutex */
00155 
00156 
00157 WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method)
00158 {
00159     WOLFSSL_CTX* ctx = NULL;
00160 
00161     WOLFSSL_ENTER("WOLFSSL_CTX_new");
00162 
00163     if (initRefCount == 0) {
00164         /* user no longer forced to call Init themselves */
00165         int ret = wolfSSL_Init();
00166         if (ret != SSL_SUCCESS) {
00167             WOLFSSL_MSG("wolfSSL_Init failed");
00168             WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
00169             return NULL;
00170         }
00171     }
00172 
00173     if (method == NULL)
00174         return ctx;
00175 
00176     ctx = (WOLFSSL_CTX*) XMALLOC(sizeof(WOLFSSL_CTX), 0, DYNAMIC_TYPE_CTX);
00177     if (ctx) {
00178         if (InitSSL_Ctx(ctx, method) < 0) {
00179             WOLFSSL_MSG("Init CTX failed");
00180             wolfSSL_CTX_free(ctx);
00181             ctx = NULL;
00182         }
00183     }
00184     else {
00185         WOLFSSL_MSG("Alloc CTX failed, method freed");
00186         XFREE(method, NULL, DYNAMIC_TYPE_METHOD);
00187     }
00188 
00189     WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
00190     return ctx;
00191 }
00192 
00193 
00194 void wolfSSL_CTX_free(WOLFSSL_CTX* ctx)
00195 {
00196     WOLFSSL_ENTER("SSL_CTX_free");
00197     if (ctx)
00198         FreeSSL_Ctx(ctx);
00199     WOLFSSL_LEAVE("SSL_CTX_free", 0);
00200 }
00201 
00202 
00203 WOLFSSL* wolfSSL_new(WOLFSSL_CTX* ctx)
00204 {
00205     WOLFSSL* ssl = NULL;
00206     int ret = 0;
00207 
00208     (void)ret;
00209     WOLFSSL_ENTER("SSL_new");
00210 
00211     if (ctx == NULL)
00212         return ssl;
00213 
00214     ssl = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ctx->heap,DYNAMIC_TYPE_SSL);
00215     if (ssl)
00216         if ( (ret = InitSSL(ssl, ctx)) < 0) {
00217             FreeSSL(ssl);
00218             ssl = 0;
00219         }
00220 
00221     WOLFSSL_LEAVE("SSL_new", ret);
00222     return ssl;
00223 }
00224 
00225 
00226 void wolfSSL_free(WOLFSSL* ssl)
00227 {
00228     WOLFSSL_ENTER("SSL_free");
00229     if (ssl)
00230         FreeSSL(ssl);
00231     WOLFSSL_LEAVE("SSL_free", 0);
00232 }
00233 
00234 #ifdef HAVE_POLY1305
00235 /* set if to use old poly 1 for yes 0 to use new poly */
00236 int wolfSSL_use_old_poly(WOLFSSL* ssl, int value)
00237 {
00238     WOLFSSL_ENTER("SSL_use_old_poly");
00239     WOLFSSL_MSG("Warning SSL connection auto detects old/new and this function"
00240             "is depriciated");
00241     ssl->options.oldPoly = (word16)value;
00242     WOLFSSL_LEAVE("SSL_use_old_poly", 0);
00243     return 0;
00244 }
00245 #endif
00246 
00247 int wolfSSL_set_fd(WOLFSSL* ssl, int fd)
00248 {
00249     WOLFSSL_ENTER("SSL_set_fd");
00250     ssl->rfd = fd;      /* not used directly to allow IO callbacks */
00251     ssl->wfd = fd;
00252 
00253     ssl->IOCB_ReadCtx  = &ssl->rfd;
00254     ssl->IOCB_WriteCtx = &ssl->wfd;
00255 
00256     #ifdef WOLFSSL_DTLS
00257         if (ssl->options.dtls) {
00258             ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
00259             ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
00260             ssl->buffers.dtlsCtx.fd = fd;
00261         }
00262     #endif
00263 
00264     WOLFSSL_LEAVE("SSL_set_fd", SSL_SUCCESS);
00265     return SSL_SUCCESS;
00266 }
00267 
00268 
00269 /**
00270   * Get the name of cipher at priority level passed in.
00271   */
00272 char* wolfSSL_get_cipher_list(int priority)
00273 {
00274     const char* const* ciphers = GetCipherNames();
00275 
00276     if (priority >= GetCipherNamesSize() || priority < 0) {
00277         return 0;
00278     }
00279 
00280     return (char*)ciphers[priority];
00281 }
00282 
00283 
00284 int wolfSSL_get_ciphers(char* buf, int len)
00285 {
00286     const char* const* ciphers = GetCipherNames();
00287     int  totalInc = 0;
00288     int  step     = 0;
00289     char delim    = ':';
00290     int  size     = GetCipherNamesSize();
00291     int  i;
00292 
00293     if (buf == NULL || len <= 0)
00294         return BAD_FUNC_ARG;
00295 
00296     /* Add each member to the buffer delimited by a : */
00297     for (i = 0; i < size; i++) {
00298         step = (int)(XSTRLEN(ciphers[i]) + 1);  /* delimiter */
00299         totalInc += step;
00300 
00301         /* Check to make sure buf is large enough and will not overflow */
00302         if (totalInc < len) {
00303             XSTRNCPY(buf, ciphers[i], XSTRLEN(ciphers[i]));
00304             buf += XSTRLEN(ciphers[i]);
00305 
00306             if (i < size - 1)
00307                 *buf++ = delim;
00308             else
00309                 *buf++ = '\0';
00310         }
00311         else
00312             return BUFFER_E;
00313     }
00314     return SSL_SUCCESS;
00315 }
00316 
00317 
00318 int wolfSSL_get_fd(const WOLFSSL* ssl)
00319 {
00320     WOLFSSL_ENTER("SSL_get_fd");
00321     WOLFSSL_LEAVE("SSL_get_fd", ssl->rfd);
00322     return ssl->rfd;
00323 }
00324 
00325 
00326 int wolfSSL_get_using_nonblock(WOLFSSL* ssl)
00327 {
00328     WOLFSSL_ENTER("wolfSSL_get_using_nonblock");
00329     WOLFSSL_LEAVE("wolfSSL_get_using_nonblock", ssl->options.usingNonblock);
00330     return ssl->options.usingNonblock;
00331 }
00332 
00333 
00334 int wolfSSL_dtls(WOLFSSL* ssl)
00335 {
00336     return ssl->options.dtls;
00337 }
00338 
00339 
00340 #ifndef WOLFSSL_LEANPSK
00341 void wolfSSL_set_using_nonblock(WOLFSSL* ssl, int nonblock)
00342 {
00343     WOLFSSL_ENTER("wolfSSL_set_using_nonblock");
00344     ssl->options.usingNonblock = (nonblock != 0);
00345 }
00346 
00347 
00348 int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
00349 {
00350 #ifdef WOLFSSL_DTLS
00351     void* sa = (void*)XMALLOC(peerSz, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
00352     if (sa != NULL) {
00353         if (ssl->buffers.dtlsCtx.peer.sa != NULL)
00354             XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
00355         XMEMCPY(sa, peer, peerSz);
00356         ssl->buffers.dtlsCtx.peer.sa = sa;
00357         ssl->buffers.dtlsCtx.peer.sz = peerSz;
00358         return SSL_SUCCESS;
00359     }
00360     return SSL_FAILURE;
00361 #else
00362     (void)ssl;
00363     (void)peer;
00364     (void)peerSz;
00365     return SSL_NOT_IMPLEMENTED;
00366 #endif
00367 }
00368 
00369 int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
00370 {
00371 #ifdef WOLFSSL_DTLS
00372     if (peer != NULL && peerSz != NULL
00373             && *peerSz >= ssl->buffers.dtlsCtx.peer.sz) {
00374         *peerSz = ssl->buffers.dtlsCtx.peer.sz;
00375         XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
00376         return SSL_SUCCESS;
00377     }
00378     return SSL_FAILURE;
00379 #else
00380     (void)ssl;
00381     (void)peer;
00382     (void)peerSz;
00383     return SSL_NOT_IMPLEMENTED;
00384 #endif
00385 }
00386 #endif /* WOLFSSL_LEANPSK */
00387 
00388 
00389 /* return underlying connect or accept, SSL_SUCCESS on ok */
00390 int wolfSSL_negotiate(WOLFSSL* ssl)
00391 {
00392     int err = SSL_FATAL_ERROR;
00393 
00394     WOLFSSL_ENTER("wolfSSL_negotiate");
00395 #ifndef NO_WOLFSSL_SERVER
00396     if (ssl->options.side == WOLFSSL_SERVER_END)
00397         err = wolfSSL_accept(ssl);
00398 #endif
00399 
00400 #ifndef NO_WOLFSSL_CLIENT
00401     if (ssl->options.side == WOLFSSL_CLIENT_END)
00402         err = wolfSSL_connect(ssl);
00403 #endif
00404 
00405     WOLFSSL_LEAVE("wolfSSL_negotiate", err);
00406 
00407     return err;
00408 }
00409 
00410 
00411 #ifndef WOLFSSL_LEANPSK
00412 /* object size based on build */
00413 int wolfSSL_GetObjectSize(void)
00414 {
00415 #ifdef SHOW_SIZES
00416     printf("sizeof suites           = %lu\n", sizeof(Suites));
00417     printf("sizeof ciphers(2)       = %lu\n", sizeof(Ciphers));
00418 #ifndef NO_RC4
00419     printf("    sizeof arc4         = %lu\n", sizeof(Arc4));
00420 #endif
00421     printf("    sizeof aes          = %lu\n", sizeof(Aes));
00422 #ifndef NO_DES3
00423     printf("    sizeof des3         = %lu\n", sizeof(Des3));
00424 #endif
00425 #ifndef NO_RABBIT
00426     printf("    sizeof rabbit       = %lu\n", sizeof(Rabbit));
00427 #endif
00428 #ifdef HAVE_CHACHA
00429     printf("    sizeof chacha       = %lu\n", sizeof(ChaCha));
00430 #endif
00431     printf("sizeof cipher specs     = %lu\n", sizeof(CipherSpecs));
00432     printf("sizeof keys             = %lu\n", sizeof(Keys));
00433     printf("sizeof Hashes(2)        = %lu\n", sizeof(Hashes));
00434 #ifndef NO_MD5
00435     printf("    sizeof MD5          = %lu\n", sizeof(Md5));
00436 #endif
00437 #ifndef NO_SHA
00438     printf("    sizeof SHA          = %lu\n", sizeof(Sha));
00439 #endif
00440 #ifndef NO_SHA256
00441     printf("    sizeof SHA256       = %lu\n", sizeof(Sha256));
00442 #endif
00443 #ifdef WOLFSSL_SHA384
00444     printf("    sizeof SHA384       = %lu\n", sizeof(Sha384));
00445 #endif
00446 #ifdef WOLFSSL_SHA384
00447     printf("    sizeof SHA512       = %lu\n", sizeof(Sha512));
00448 #endif
00449     printf("sizeof Buffers          = %lu\n", sizeof(Buffers));
00450     printf("sizeof Options          = %lu\n", sizeof(Options));
00451     printf("sizeof Arrays           = %lu\n", sizeof(Arrays));
00452 #ifndef NO_RSA
00453     printf("sizeof RsaKey           = %lu\n", sizeof(RsaKey));
00454 #endif
00455 #ifdef HAVE_ECC
00456     printf("sizeof ecc_key          = %lu\n", sizeof(ecc_key));
00457 #endif
00458     printf("sizeof WOLFSSL_CIPHER    = %lu\n", sizeof(WOLFSSL_CIPHER));
00459     printf("sizeof WOLFSSL_SESSION   = %lu\n", sizeof(WOLFSSL_SESSION));
00460     printf("sizeof WOLFSSL           = %lu\n", sizeof(WOLFSSL));
00461     printf("sizeof WOLFSSL_CTX       = %lu\n", sizeof(WOLFSSL_CTX));
00462 #endif
00463 
00464     return sizeof(WOLFSSL);
00465 }
00466 #endif
00467 
00468 
00469 #ifndef NO_DH
00470 /* server Diffie-Hellman parameters, SSL_SUCCESS on ok */
00471 int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
00472                     const unsigned char* g, int gSz)
00473 {
00474     word16 havePSK = 0;
00475     word16 haveRSA = 1;
00476 
00477     WOLFSSL_ENTER("wolfSSL_SetTmpDH");
00478     if (ssl == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
00479 
00480     if (pSz < ssl->options.minDhKeySz)
00481         return DH_KEY_SIZE_E;
00482 
00483     if (ssl->options.side != WOLFSSL_SERVER_END)
00484         return SIDE_ERROR;
00485 
00486     if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH)
00487         XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
00488     if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH)
00489         XFREE(ssl->buffers.serverDH_G.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
00490 
00491     ssl->buffers.weOwnDH = 1;  /* SSL owns now */
00492     ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->ctx->heap,
00493                                                     DYNAMIC_TYPE_DH);
00494     if (ssl->buffers.serverDH_P.buffer == NULL)
00495         return MEMORY_E;
00496 
00497     ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, ssl->ctx->heap,
00498                                                     DYNAMIC_TYPE_DH);
00499     if (ssl->buffers.serverDH_G.buffer == NULL) {
00500         XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
00501         return MEMORY_E;
00502     }
00503 
00504     ssl->buffers.serverDH_P.length = pSz;
00505     ssl->buffers.serverDH_G.length = gSz;
00506 
00507     XMEMCPY(ssl->buffers.serverDH_P.buffer, p, pSz);
00508     XMEMCPY(ssl->buffers.serverDH_G.buffer, g, gSz);
00509 
00510     ssl->options.haveDH = 1;
00511     #ifndef NO_PSK
00512         havePSK = ssl->options.havePSK;
00513     #endif
00514     #ifdef NO_RSA
00515         haveRSA = 0;
00516     #endif
00517     InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH,
00518                ssl->options.haveNTRU, ssl->options.haveECDSAsig,
00519                ssl->options.haveECC, ssl->options.haveStaticECC,
00520                ssl->options.side);
00521 
00522     WOLFSSL_LEAVE("wolfSSL_SetTmpDH", 0);
00523     return SSL_SUCCESS;
00524 }
00525 
00526 /* server ctx Diffie-Hellman parameters, SSL_SUCCESS on ok */
00527 int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
00528                          const unsigned char* g, int gSz)
00529 {
00530     WOLFSSL_ENTER("wolfSSL_CTX_SetTmpDH");
00531     if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
00532 
00533     if (pSz < ctx->minDhKeySz)
00534         return DH_KEY_SIZE_E;
00535 
00536     XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
00537     XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
00538 
00539     ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap,DYNAMIC_TYPE_DH);
00540     if (ctx->serverDH_P.buffer == NULL)
00541        return MEMORY_E;
00542 
00543     ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap,DYNAMIC_TYPE_DH);
00544     if (ctx->serverDH_G.buffer == NULL) {
00545         XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
00546         return MEMORY_E;
00547     }
00548 
00549     ctx->serverDH_P.length = pSz;
00550     ctx->serverDH_G.length = gSz;
00551 
00552     XMEMCPY(ctx->serverDH_P.buffer, p, pSz);
00553     XMEMCPY(ctx->serverDH_G.buffer, g, gSz);
00554 
00555     ctx->haveDH = 1;
00556 
00557     WOLFSSL_LEAVE("wolfSSL_CTX_SetTmpDH", 0);
00558     return SSL_SUCCESS;
00559 }
00560 
00561 
00562 int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz)
00563 {
00564     if (ctx == NULL || keySz > 16000 || keySz % 8 != 0)
00565         return BAD_FUNC_ARG;
00566 
00567     ctx->minDhKeySz = keySz / 8;
00568     return SSL_SUCCESS;
00569 }
00570 
00571 
00572 int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz)
00573 {
00574     if (ssl == NULL || keySz > 16000 || keySz % 8 != 0)
00575         return BAD_FUNC_ARG;
00576 
00577     ssl->options.minDhKeySz = keySz / 8;
00578     return SSL_SUCCESS;
00579 }
00580 
00581 
00582 int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl)
00583 {
00584     if (ssl == NULL)
00585         return BAD_FUNC_ARG;
00586 
00587     return (ssl->options.dhKeySz * 8);
00588 }
00589 
00590 #endif /* !NO_DH */
00591 
00592 
00593 int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
00594 {
00595     int ret;
00596 
00597     WOLFSSL_ENTER("SSL_write()");
00598 
00599     if (ssl == NULL || data == NULL || sz < 0)
00600         return BAD_FUNC_ARG;
00601 
00602 #ifdef HAVE_ERRNO_H
00603     errno = 0;
00604 #endif
00605 
00606     ret = SendData(ssl, data, sz);
00607 
00608     WOLFSSL_LEAVE("SSL_write()", ret);
00609 
00610     if (ret < 0)
00611         return SSL_FATAL_ERROR;
00612     else
00613         return ret;
00614 }
00615 
00616 
00617 static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
00618 {
00619     int ret;
00620 
00621     WOLFSSL_ENTER("wolfSSL_read_internal()");
00622 
00623     if (ssl == NULL || data == NULL || sz < 0)
00624         return BAD_FUNC_ARG;
00625 
00626 #ifdef HAVE_ERRNO_H
00627         errno = 0;
00628 #endif
00629 #ifdef WOLFSSL_DTLS
00630     if (ssl->options.dtls)
00631         ssl->dtls_expected_rx = max(sz + 100, MAX_MTU);
00632 #endif
00633 
00634 #ifdef HAVE_MAX_FRAGMENT
00635     ret = ReceiveData(ssl, (byte*)data,
00636                       min(sz, min(ssl->max_fragment, OUTPUT_RECORD_SIZE)),peek);
00637 #else
00638     ret = ReceiveData(ssl, (byte*)data, min(sz, OUTPUT_RECORD_SIZE), peek);
00639 #endif
00640 
00641     WOLFSSL_LEAVE("wolfSSL_read_internal()", ret);
00642 
00643     if (ret < 0)
00644         return SSL_FATAL_ERROR;
00645     else
00646         return ret;
00647 }
00648 
00649 
00650 int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz)
00651 {
00652     WOLFSSL_ENTER("wolfSSL_peek()");
00653 
00654     return wolfSSL_read_internal(ssl, data, sz, TRUE);
00655 }
00656 
00657 
00658 int wolfSSL_read(WOLFSSL* ssl, void* data, int sz)
00659 {
00660     WOLFSSL_ENTER("wolfSSL_read()");
00661 
00662     return wolfSSL_read_internal(ssl, data, sz, FALSE);
00663 }
00664 
00665 
00666 #ifdef HAVE_CAVIUM
00667 
00668 /* let's use cavium, SSL_SUCCESS on ok */
00669 int wolfSSL_UseCavium(WOLFSSL* ssl, int devId)
00670 {
00671     if (ssl == NULL)
00672         return BAD_FUNC_ARG;
00673 
00674     ssl->devId = devId;
00675 
00676     return SSL_SUCCESS;
00677 }
00678 
00679 
00680 /* let's use cavium, SSL_SUCCESS on ok */
00681 int wolfSSL_CTX_UseCavium(WOLFSSL_CTX* ctx, int devId)
00682 {
00683     if (ctx == NULL)
00684         return BAD_FUNC_ARG;
00685 
00686     ctx->devId = devId;
00687 
00688     return SSL_SUCCESS;
00689 }
00690 
00691 
00692 #endif /* HAVE_CAVIUM */
00693 
00694 #ifdef HAVE_SNI
00695 
00696 int wolfSSL_UseSNI(WOLFSSL* ssl, byte type, const void* data, word16 size)
00697 {
00698     if (ssl == NULL)
00699         return BAD_FUNC_ARG;
00700 
00701     return TLSX_UseSNI(&ssl->extensions, type, data, size);
00702 }
00703 
00704 
00705 int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, const void* data,
00706                                                                     word16 size)
00707 {
00708     if (ctx == NULL)
00709         return BAD_FUNC_ARG;
00710 
00711     return TLSX_UseSNI(&ctx->extensions, type, data, size);
00712 }
00713 
00714 #ifndef NO_WOLFSSL_SERVER
00715 
00716 void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options)
00717 {
00718     if (ssl && ssl->extensions)
00719         TLSX_SNI_SetOptions(ssl->extensions, type, options);
00720 }
00721 
00722 
00723 void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options)
00724 {
00725     if (ctx && ctx->extensions)
00726         TLSX_SNI_SetOptions(ctx->extensions, type, options);
00727 }
00728 
00729 
00730 byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type)
00731 {
00732     return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type);
00733 }
00734 
00735 
00736 word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data)
00737 {
00738     if (data)
00739         *data = NULL;
00740 
00741     if (ssl && ssl->extensions)
00742         return TLSX_SNI_GetRequest(ssl->extensions, type, data);
00743 
00744     return 0;
00745 }
00746 
00747 
00748 int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
00749                               byte type, byte* sni, word32* inOutSz)
00750 {
00751     if (clientHello && helloSz > 0 && sni && inOutSz && *inOutSz > 0)
00752         return TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
00753 
00754     return BAD_FUNC_ARG;
00755 }
00756 
00757 #endif /* NO_WOLFSSL_SERVER */
00758 
00759 #endif /* HAVE_SNI */
00760 
00761 
00762 #ifdef HAVE_MAX_FRAGMENT
00763 #ifndef NO_WOLFSSL_CLIENT
00764 
00765 int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl)
00766 {
00767     if (ssl == NULL)
00768         return BAD_FUNC_ARG;
00769 
00770     return TLSX_UseMaxFragment(&ssl->extensions, mfl);
00771 }
00772 
00773 
00774 int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl)
00775 {
00776     if (ctx == NULL)
00777         return BAD_FUNC_ARG;
00778 
00779     return TLSX_UseMaxFragment(&ctx->extensions, mfl);
00780 }
00781 
00782 #endif /* NO_WOLFSSL_CLIENT */
00783 #endif /* HAVE_MAX_FRAGMENT */
00784 
00785 #ifdef HAVE_TRUNCATED_HMAC
00786 #ifndef NO_WOLFSSL_CLIENT
00787 
00788 int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl)
00789 {
00790     if (ssl == NULL)
00791         return BAD_FUNC_ARG;
00792 
00793     return TLSX_UseTruncatedHMAC(&ssl->extensions);
00794 }
00795 
00796 
00797 int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
00798 {
00799     if (ctx == NULL)
00800         return BAD_FUNC_ARG;
00801 
00802     return TLSX_UseTruncatedHMAC(&ctx->extensions);
00803 }
00804 
00805 #endif /* NO_WOLFSSL_CLIENT */
00806 #endif /* HAVE_TRUNCATED_HMAC */
00807 
00808 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
00809 
00810 int wolfSSL_UseOCSPStapling(WOLFSSL* ssl, byte status_type, byte options)
00811 {
00812     if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
00813         return BAD_FUNC_ARG;
00814 
00815     return TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
00816                                                                        options);
00817 }
00818 
00819 
00820 int wolfSSL_CTX_UseOCSPStapling(WOLFSSL_CTX* ctx, byte status_type,
00821                                                                    byte options)
00822 {
00823     if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
00824         return BAD_FUNC_ARG;
00825 
00826     return TLSX_UseCertificateStatusRequest(&ctx->extensions, status_type,
00827                                                                        options);
00828 }
00829 
00830 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
00831 
00832 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
00833 
00834 int wolfSSL_UseOCSPStaplingV2(WOLFSSL* ssl, byte status_type, byte options)
00835 {
00836     if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
00837         return BAD_FUNC_ARG;
00838 
00839     return TLSX_UseCertificateStatusRequestV2(&ssl->extensions, status_type,
00840                                                                        options);
00841 }
00842 
00843 
00844 int wolfSSL_CTX_UseOCSPStaplingV2(WOLFSSL_CTX* ctx,
00845                                                  byte status_type, byte options)
00846 {
00847     if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
00848         return BAD_FUNC_ARG;
00849 
00850     return TLSX_UseCertificateStatusRequestV2(&ctx->extensions, status_type,
00851                                                                        options);
00852 }
00853 
00854 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
00855 
00856 /* Elliptic Curves */
00857 #ifdef HAVE_SUPPORTED_CURVES
00858 #ifndef NO_WOLFSSL_CLIENT
00859 
00860 int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
00861 {
00862     if (ssl == NULL)
00863         return BAD_FUNC_ARG;
00864 
00865     switch (name) {
00866         case WOLFSSL_ECC_SECP160R1:
00867         case WOLFSSL_ECC_SECP192R1:
00868         case WOLFSSL_ECC_SECP224R1:
00869         case WOLFSSL_ECC_SECP256R1:
00870         case WOLFSSL_ECC_SECP384R1:
00871         case WOLFSSL_ECC_SECP521R1:
00872             break;
00873 
00874         default:
00875             return BAD_FUNC_ARG;
00876     }
00877 
00878     return TLSX_UseSupportedCurve(&ssl->extensions, name);
00879 }
00880 
00881 
00882 int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
00883 {
00884     if (ctx == NULL)
00885         return BAD_FUNC_ARG;
00886 
00887     switch (name) {
00888         case WOLFSSL_ECC_SECP160R1:
00889         case WOLFSSL_ECC_SECP192R1:
00890         case WOLFSSL_ECC_SECP224R1:
00891         case WOLFSSL_ECC_SECP256R1:
00892         case WOLFSSL_ECC_SECP384R1:
00893         case WOLFSSL_ECC_SECP521R1:
00894             break;
00895 
00896         default:
00897             return BAD_FUNC_ARG;
00898     }
00899 
00900     return TLSX_UseSupportedCurve(&ctx->extensions, name);
00901 }
00902 
00903 #endif /* NO_WOLFSSL_CLIENT */
00904 #endif /* HAVE_SUPPORTED_CURVES */
00905 
00906 /* QSH quantum safe handshake */
00907 #ifdef HAVE_QSH
00908 /* returns 1 if QSH has been used 0 otherwise */
00909 int wolfSSL_isQSH(WOLFSSL* ssl)
00910 {
00911     /* if no ssl struct than QSH was not used */
00912     if (ssl == NULL)
00913         return 0;
00914 
00915     return ssl->isQSH;
00916 }
00917 
00918 
00919 int wolfSSL_UseSupportedQSH(WOLFSSL* ssl, word16 name)
00920 {
00921     if (ssl == NULL)
00922         return BAD_FUNC_ARG;
00923 
00924     switch (name) {
00925     #ifdef HAVE_NTRU
00926         case WOLFSSL_NTRU_EESS439:
00927         case WOLFSSL_NTRU_EESS593:
00928         case WOLFSSL_NTRU_EESS743:
00929             break;
00930     #endif
00931         default:
00932             return BAD_FUNC_ARG;
00933     }
00934 
00935     ssl->user_set_QSHSchemes = 1;
00936 
00937     return TLSX_UseQSHScheme(&ssl->extensions, name, NULL, 0);
00938 }
00939 
00940 #ifndef NO_WOLFSSL_CLIENT
00941     /* user control over sending client public key in hello
00942        when flag = 1 will send keys if flag is 0 or function is not called
00943        then will not send keys in the hello extension
00944        return 0 on success
00945      */
00946     int wolfSSL_UseClientQSHKeys(WOLFSSL* ssl, unsigned char flag)
00947     {
00948         if (ssl == NULL)
00949             return BAD_FUNC_ARG;
00950 
00951         ssl->sendQSHKeys = flag;
00952 
00953         return 0;
00954     }
00955 #endif /* NO_WOLFSSL_CLIENT */
00956 #endif /* HAVE_QSH */
00957 
00958 
00959 /* Application-Layer Protocol Negotiation */
00960 #ifdef HAVE_ALPN
00961 
00962 int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
00963                     word32 protocol_name_listSz, byte options)
00964 {
00965     char    *list, *ptr, *token[10];
00966     word16  len;
00967     int     idx = 0;
00968     int     ret = SSL_FAILURE;
00969 
00970     WOLFSSL_ENTER("wolfSSL_UseALPN");
00971 
00972     if (ssl == NULL || protocol_name_list == NULL)
00973         return BAD_FUNC_ARG;
00974 
00975     if (protocol_name_listSz > (WOLFSSL_MAX_ALPN_NUMBER *
00976                                 WOLFSSL_MAX_ALPN_PROTO_NAME_LEN +
00977                                 WOLFSSL_MAX_ALPN_NUMBER)) {
00978         WOLFSSL_MSG("Invalid arguments, protocol name list too long");
00979         return BAD_FUNC_ARG;
00980     }
00981 
00982     if (!(options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) &&
00983         !(options & WOLFSSL_ALPN_FAILED_ON_MISMATCH)) {
00984             WOLFSSL_MSG("Invalid arguments, options not supported");
00985             return BAD_FUNC_ARG;
00986         }
00987 
00988 
00989     list = (char *)XMALLOC(protocol_name_listSz+1, NULL,
00990                            DYNAMIC_TYPE_TMP_BUFFER);
00991     if (list == NULL) {
00992         WOLFSSL_MSG("Memory failure");
00993         return MEMORY_ERROR;
00994     }
00995 
00996     XMEMSET(list, 0, protocol_name_listSz+1);
00997     XSTRNCPY(list, protocol_name_list, protocol_name_listSz);
00998 
00999     /* read all protocol name from the list */
01000     token[idx] = XSTRTOK(list, ",", &ptr);
01001     while (token[idx] != NULL)
01002         token[++idx] = XSTRTOK(NULL, ",", &ptr);
01003 
01004     /* add protocol name list in the TLS extension in reverse order */
01005     while ((idx--) > 0) {
01006         len = (word16)XSTRLEN(token[idx]);
01007 
01008         ret = TLSX_UseALPN(&ssl->extensions, token[idx], len, options);
01009         if (ret != SSL_SUCCESS) {
01010             WOLFSSL_MSG("TLSX_UseALPN failure");
01011             break;
01012         }
01013     }
01014 
01015     XFREE(list, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01016 
01017     return ret;
01018 }
01019 
01020 int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name, word16 *size)
01021 {
01022     return TLSX_ALPN_GetRequest(ssl ? ssl->extensions : NULL,
01023                                (void **)protocol_name, size);
01024 }
01025 
01026 int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, word16 *listSz)
01027 {
01028     if (list == NULL || listSz == NULL)
01029         return BAD_FUNC_ARG;
01030 
01031     if (ssl->alpn_client_list == NULL)
01032         return BUFFER_ERROR;
01033 
01034     *listSz = (word16)XSTRLEN(ssl->alpn_client_list);
01035     if (*listSz == 0)
01036         return BUFFER_ERROR;
01037 
01038     *list = (char *)XMALLOC((*listSz)+1, NULL, DYNAMIC_TYPE_TLSX);
01039     if (*list == NULL)
01040         return MEMORY_ERROR;
01041 
01042     XSTRNCPY(*list, ssl->alpn_client_list, (*listSz)+1);
01043     (*list)[*listSz] = 0;
01044 
01045     return SSL_SUCCESS;
01046 }
01047 
01048 #endif /* HAVE_ALPN */
01049 
01050 /* Secure Renegotiation */
01051 #ifdef HAVE_SECURE_RENEGOTIATION
01052 
01053 /* user is forcing ability to use secure renegotiation, we discourage it */
01054 int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl)
01055 {
01056     int ret = BAD_FUNC_ARG;
01057 
01058     if (ssl)
01059         ret = TLSX_UseSecureRenegotiation(&ssl->extensions);
01060 
01061     if (ret == SSL_SUCCESS) {
01062         TLSX* extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO);
01063 
01064         if (extension)
01065             ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
01066     }
01067 
01068     return ret;
01069 }
01070 
01071 
01072 /* do a secure renegotiation handshake, user forced, we discourage */
01073 int wolfSSL_Rehandshake(WOLFSSL* ssl)
01074 {
01075     int ret;
01076 
01077     if (ssl == NULL)
01078         return BAD_FUNC_ARG;
01079 
01080     if (ssl->secure_renegotiation == NULL) {
01081         WOLFSSL_MSG("Secure Renegotiation not forced on by user");
01082         return SECURE_RENEGOTIATION_E;
01083     }
01084 
01085     if (ssl->secure_renegotiation->enabled == 0) {
01086         WOLFSSL_MSG("Secure Renegotiation not enabled at extension level");
01087         return SECURE_RENEGOTIATION_E;
01088     }
01089 
01090     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
01091         WOLFSSL_MSG("Can't renegotiate until previous handshake complete");
01092         return SECURE_RENEGOTIATION_E;
01093     }
01094 
01095 #ifndef NO_FORCE_SCR_SAME_SUITE
01096     /* force same suite */
01097     if (ssl->suites) {
01098         ssl->suites->suiteSz = SUITE_LEN;
01099         ssl->suites->suites[0] = ssl->options.cipherSuite0;
01100         ssl->suites->suites[1] = ssl->options.cipherSuite;
01101     }
01102 #endif
01103 
01104     /* reset handshake states */
01105     ssl->options.serverState = NULL_STATE;
01106     ssl->options.clientState = NULL_STATE;
01107     ssl->options.connectState  = CONNECT_BEGIN;
01108     ssl->options.acceptState   = ACCEPT_BEGIN;
01109     ssl->options.handShakeState = NULL_STATE;
01110     ssl->options.processReply  = 0;  /* TODO, move states in internal.h */
01111 
01112     XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
01113 
01114     ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
01115 
01116 #ifndef NO_OLD_TLS
01117 #ifndef NO_MD5
01118     wc_InitMd5(&ssl->hsHashes->hashMd5);
01119 #endif
01120 #ifndef NO_SHA
01121     ret = wc_InitSha(&ssl->hsHashes->hashSha);
01122     if (ret !=0)
01123         return ret;
01124 #endif
01125 #endif /* NO_OLD_TLS */
01126 #ifndef NO_SHA256
01127     ret = wc_InitSha256(&ssl->hsHashes->hashSha256);
01128     if (ret !=0)
01129         return ret;
01130 #endif
01131 #ifdef WOLFSSL_SHA384
01132     ret = wc_InitSha384(&ssl->hsHashes->hashSha384);
01133     if (ret !=0)
01134         return ret;
01135 #endif
01136 #ifdef WOLFSSL_SHA512
01137     ret = wc_InitSha512(&ssl->hsHashes->hashSha512);
01138     if (ret !=0)
01139         return ret;
01140 #endif
01141 
01142     ret = wolfSSL_negotiate(ssl);
01143     return ret;
01144 }
01145 
01146 #endif /* HAVE_SECURE_RENEGOTIATION */
01147 
01148 /* Session Ticket */
01149 #if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SESSION_TICKET)
01150 /* SSL_SUCCESS on ok */
01151 int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
01152 {
01153     if (ctx == NULL)
01154         return BAD_FUNC_ARG;
01155 
01156     ctx->ticketEncCb = cb;
01157 
01158     return SSL_SUCCESS;
01159 }
01160 
01161 /* set hint interval, SSL_SUCCESS on ok */
01162 int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
01163 {
01164     if (ctx == NULL)
01165         return BAD_FUNC_ARG;
01166 
01167     ctx->ticketHint = hint;
01168 
01169     return SSL_SUCCESS;
01170 }
01171 
01172 /* set user context, SSL_SUCCESS on ok */
01173 int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void* userCtx)
01174 {
01175     if (ctx == NULL)
01176         return BAD_FUNC_ARG;
01177 
01178     ctx->ticketEncCtx = userCtx;
01179 
01180     return SSL_SUCCESS;
01181 }
01182 
01183 #endif /* !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET) */
01184 
01185 /* Session Ticket */
01186 #if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET)
01187 int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
01188 {
01189     if (ssl == NULL)
01190         return BAD_FUNC_ARG;
01191 
01192     return TLSX_UseSessionTicket(&ssl->extensions, NULL);
01193 }
01194 
01195 int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx)
01196 {
01197     if (ctx == NULL)
01198         return BAD_FUNC_ARG;
01199 
01200     return TLSX_UseSessionTicket(&ctx->extensions, NULL);
01201 }
01202 
01203 WOLFSSL_API int wolfSSL_get_SessionTicket(WOLFSSL* ssl,
01204                                           byte* buf, word32* bufSz)
01205 {
01206     if (ssl == NULL || buf == NULL || bufSz == NULL || *bufSz == 0)
01207         return BAD_FUNC_ARG;
01208 
01209     if (ssl->session.ticketLen <= *bufSz) {
01210         XMEMCPY(buf, ssl->session.ticket, ssl->session.ticketLen);
01211         *bufSz = ssl->session.ticketLen;
01212     }
01213     else
01214         *bufSz = 0;
01215 
01216     return SSL_SUCCESS;
01217 }
01218 
01219 WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL* ssl, byte* buf, word32 bufSz)
01220 {
01221     if (ssl == NULL || (buf == NULL && bufSz > 0))
01222         return BAD_FUNC_ARG;
01223 
01224     if (bufSz > 0)
01225         XMEMCPY(ssl->session.ticket, buf, bufSz);
01226     ssl->session.ticketLen = (word16)bufSz;
01227 
01228     return SSL_SUCCESS;
01229 }
01230 
01231 
01232 WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
01233                                             CallbackSessionTicket cb, void* ctx)
01234 {
01235     if (ssl == NULL)
01236         return BAD_FUNC_ARG;
01237 
01238     ssl->session_ticket_cb = cb;
01239     ssl->session_ticket_ctx = ctx;
01240 
01241     return SSL_SUCCESS;
01242 }
01243 #endif
01244 
01245 #ifndef WOLFSSL_LEANPSK
01246 
01247 int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags)
01248 {
01249     int ret;
01250     int oldFlags;
01251 
01252     WOLFSSL_ENTER("wolfSSL_send()");
01253 
01254     if (ssl == NULL || data == NULL || sz < 0)
01255         return BAD_FUNC_ARG;
01256 
01257     oldFlags = ssl->wflags;
01258 
01259     ssl->wflags = flags;
01260     ret = wolfSSL_write(ssl, data, sz);
01261     ssl->wflags = oldFlags;
01262 
01263     WOLFSSL_LEAVE("wolfSSL_send()", ret);
01264 
01265     return ret;
01266 }
01267 
01268 
01269 int wolfSSL_recv(WOLFSSL* ssl, void* data, int sz, int flags)
01270 {
01271     int ret;
01272     int oldFlags;
01273 
01274     WOLFSSL_ENTER("wolfSSL_recv()");
01275 
01276     if (ssl == NULL || data == NULL || sz < 0)
01277         return BAD_FUNC_ARG;
01278 
01279     oldFlags = ssl->rflags;
01280 
01281     ssl->rflags = flags;
01282     ret = wolfSSL_read(ssl, data, sz);
01283     ssl->rflags = oldFlags;
01284 
01285     WOLFSSL_LEAVE("wolfSSL_recv()", ret);
01286 
01287     return ret;
01288 }
01289 #endif
01290 
01291 
01292 /* SSL_SUCCESS on ok */
01293 int wolfSSL_shutdown(WOLFSSL* ssl)
01294 {
01295     int  ret = SSL_FATAL_ERROR;
01296     byte tmp;
01297     WOLFSSL_ENTER("SSL_shutdown()");
01298 
01299     if (ssl == NULL)
01300         return SSL_FATAL_ERROR;
01301 
01302     if (ssl->options.quietShutdown) {
01303         WOLFSSL_MSG("quiet shutdown, no close notify sent");
01304         return SSL_SUCCESS;
01305     }
01306 
01307     /* try to send close notify, not an error if can't */
01308     if (!ssl->options.isClosed && !ssl->options.connReset &&
01309                                   !ssl->options.sentNotify) {
01310         ssl->error = SendAlert(ssl, alert_warning, close_notify);
01311         if (ssl->error < 0) {
01312             WOLFSSL_ERROR(ssl->error);
01313             return SSL_FATAL_ERROR;
01314         }
01315         ssl->options.sentNotify = 1;  /* don't send close_notify twice */
01316         if (ssl->options.closeNotify)
01317             ret = SSL_SUCCESS;
01318         else
01319             ret = SSL_SHUTDOWN_NOT_DONE;
01320 
01321         WOLFSSL_LEAVE("SSL_shutdown()", ret);
01322         return ret;
01323     }
01324 
01325     /* call wolfSSL_shutdown again for bidirectional shutdown */
01326     if (ssl->options.sentNotify && !ssl->options.closeNotify) {
01327         ret = wolfSSL_read(ssl, &tmp, 0);
01328         if (ret < 0) {
01329             WOLFSSL_ERROR(ssl->error);
01330             ret = SSL_FATAL_ERROR;
01331         } else if (ssl->options.closeNotify) {
01332             ssl->error = SSL_ERROR_SYSCALL;   /* simulate OpenSSL behavior */
01333             ret = SSL_SUCCESS;
01334         }
01335     }
01336 
01337     WOLFSSL_LEAVE("SSL_shutdown()", ret);
01338 
01339     return ret;
01340 }
01341 
01342 
01343 int wolfSSL_get_error(WOLFSSL* ssl, int ret)
01344 {
01345     WOLFSSL_ENTER("SSL_get_error");
01346 
01347     if (ret > 0)
01348         return SSL_ERROR_NONE;
01349     if (ssl == NULL)
01350         return BAD_FUNC_ARG;
01351 
01352     WOLFSSL_LEAVE("SSL_get_error", ssl->error);
01353 
01354     /* make sure converted types are handled in SetErrorString() too */
01355     if (ssl->error == WANT_READ)
01356         return SSL_ERROR_WANT_READ;         /* convert to OpenSSL type */
01357     else if (ssl->error == WANT_WRITE)
01358         return SSL_ERROR_WANT_WRITE;        /* convert to OpenSSL type */
01359     else if (ssl->error == ZERO_RETURN)
01360         return SSL_ERROR_ZERO_RETURN;       /* convert to OpenSSL type */
01361     return ssl->error;
01362 }
01363 
01364 
01365 /* retrive alert history, SSL_SUCCESS on ok */
01366 int wolfSSL_get_alert_history(WOLFSSL* ssl, WOLFSSL_ALERT_HISTORY *h)
01367 {
01368     if (ssl && h) {
01369         *h = ssl->alert_history;
01370     }
01371     return SSL_SUCCESS;
01372 }
01373 
01374 
01375 /* return TRUE if current error is want read */
01376 int wolfSSL_want_read(WOLFSSL* ssl)
01377 {
01378     WOLFSSL_ENTER("SSL_want_read");
01379     if (ssl->error == WANT_READ)
01380         return 1;
01381 
01382     return 0;
01383 }
01384 
01385 
01386 /* return TRUE if current error is want write */
01387 int wolfSSL_want_write(WOLFSSL* ssl)
01388 {
01389     WOLFSSL_ENTER("SSL_want_write");
01390     if (ssl->error == WANT_WRITE)
01391         return 1;
01392 
01393     return 0;
01394 }
01395 
01396 
01397 char* wolfSSL_ERR_error_string(unsigned long errNumber, char* data)
01398 {
01399     static const char* msg = "Please supply a buffer for error string";
01400 
01401     WOLFSSL_ENTER("ERR_error_string");
01402     if (data) {
01403         SetErrorString((int)errNumber, data);
01404         return data;
01405     }
01406 
01407     return (char*)msg;
01408 }
01409 
01410 
01411 void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
01412 {
01413     WOLFSSL_ENTER("wolfSSL_ERR_error_string_n");
01414     if (len >= WOLFSSL_MAX_ERROR_SZ)
01415         wolfSSL_ERR_error_string(e, buf);
01416     else {
01417         char tmp[WOLFSSL_MAX_ERROR_SZ];
01418 
01419         WOLFSSL_MSG("Error buffer too short, truncating");
01420         if (len) {
01421             wolfSSL_ERR_error_string(e, tmp);
01422             XMEMCPY(buf, tmp, len-1);
01423             buf[len-1] = '\0';
01424         }
01425     }
01426 }
01427 
01428 
01429 /* don't free temporary arrays at end of handshake */
01430 void wolfSSL_KeepArrays(WOLFSSL* ssl)
01431 {
01432     if (ssl)
01433         ssl->options.saveArrays = 1;
01434 }
01435 
01436 
01437 /* user doesn't need temporary arrays anymore, Free */
01438 void wolfSSL_FreeArrays(WOLFSSL* ssl)
01439 {
01440     if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
01441         ssl->options.saveArrays = 0;
01442         FreeArrays(ssl, 1);
01443     }
01444 }
01445 
01446 
01447 const byte* wolfSSL_GetMacSecret(WOLFSSL* ssl, int verify)
01448 {
01449     if (ssl == NULL)
01450         return NULL;
01451 
01452     if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
01453          (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
01454         return ssl->keys.client_write_MAC_secret;
01455     else
01456         return ssl->keys.server_write_MAC_secret;
01457 }
01458 
01459 
01460 #ifdef ATOMIC_USER
01461 
01462 void  wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX* ctx, CallbackMacEncrypt cb)
01463 {
01464     if (ctx)
01465         ctx->MacEncryptCb = cb;
01466 }
01467 
01468 
01469 void  wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx)
01470 {
01471     if (ssl)
01472         ssl->MacEncryptCtx = ctx;
01473 }
01474 
01475 
01476 void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl)
01477 {
01478     if (ssl)
01479         return ssl->MacEncryptCtx;
01480 
01481     return NULL;
01482 }
01483 
01484 
01485 void  wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX* ctx, CallbackDecryptVerify cb)
01486 {
01487     if (ctx)
01488         ctx->DecryptVerifyCb = cb;
01489 }
01490 
01491 
01492 void  wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx)
01493 {
01494     if (ssl)
01495         ssl->DecryptVerifyCtx = ctx;
01496 }
01497 
01498 
01499 void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl)
01500 {
01501     if (ssl)
01502         return ssl->DecryptVerifyCtx;
01503 
01504     return NULL;
01505 }
01506 
01507 
01508 const byte* wolfSSL_GetClientWriteKey(WOLFSSL* ssl)
01509 {
01510     if (ssl)
01511         return ssl->keys.client_write_key;
01512 
01513     return NULL;
01514 }
01515 
01516 
01517 const byte* wolfSSL_GetClientWriteIV(WOLFSSL* ssl)
01518 {
01519     if (ssl)
01520         return ssl->keys.client_write_IV;
01521 
01522     return NULL;
01523 }
01524 
01525 
01526 const byte* wolfSSL_GetServerWriteKey(WOLFSSL* ssl)
01527 {
01528     if (ssl)
01529         return ssl->keys.server_write_key;
01530 
01531     return NULL;
01532 }
01533 
01534 
01535 const byte* wolfSSL_GetServerWriteIV(WOLFSSL* ssl)
01536 {
01537     if (ssl)
01538         return ssl->keys.server_write_IV;
01539 
01540     return NULL;
01541 }
01542 
01543 
01544 int wolfSSL_GetKeySize(WOLFSSL* ssl)
01545 {
01546     if (ssl)
01547         return ssl->specs.key_size;
01548 
01549     return BAD_FUNC_ARG;
01550 }
01551 
01552 
01553 int wolfSSL_GetIVSize(WOLFSSL* ssl)
01554 {
01555     if (ssl)
01556         return ssl->specs.iv_size;
01557 
01558     return BAD_FUNC_ARG;
01559 }
01560 
01561 
01562 int wolfSSL_GetBulkCipher(WOLFSSL* ssl)
01563 {
01564     if (ssl)
01565         return ssl->specs.bulk_cipher_algorithm;
01566 
01567     return BAD_FUNC_ARG;
01568 }
01569 
01570 
01571 int wolfSSL_GetCipherType(WOLFSSL* ssl)
01572 {
01573     if (ssl == NULL)
01574         return BAD_FUNC_ARG;
01575 
01576     if (ssl->specs.cipher_type == block)
01577         return WOLFSSL_BLOCK_TYPE;
01578     if (ssl->specs.cipher_type == stream)
01579         return WOLFSSL_STREAM_TYPE;
01580     if (ssl->specs.cipher_type == aead)
01581         return WOLFSSL_AEAD_TYPE;
01582 
01583     return -1;
01584 }
01585 
01586 
01587 int wolfSSL_GetCipherBlockSize(WOLFSSL* ssl)
01588 {
01589     if (ssl == NULL)
01590         return BAD_FUNC_ARG;
01591 
01592     return ssl->specs.block_size;
01593 }
01594 
01595 
01596 int wolfSSL_GetAeadMacSize(WOLFSSL* ssl)
01597 {
01598     if (ssl == NULL)
01599         return BAD_FUNC_ARG;
01600 
01601     return ssl->specs.aead_mac_size;
01602 }
01603 
01604 
01605 int wolfSSL_IsTLSv1_1(WOLFSSL* ssl)
01606 {
01607     if (ssl == NULL)
01608         return BAD_FUNC_ARG;
01609 
01610     if (ssl->options.tls1_1)
01611         return 1;
01612 
01613     return 0;
01614 }
01615 
01616 
01617 int wolfSSL_GetSide(WOLFSSL* ssl)
01618 {
01619     if (ssl)
01620         return ssl->options.side;
01621 
01622     return BAD_FUNC_ARG;
01623 }
01624 
01625 
01626 int wolfSSL_GetHmacSize(WOLFSSL* ssl)
01627 {
01628     /* AEAD ciphers don't have HMAC keys */
01629     if (ssl)
01630         return (ssl->specs.cipher_type != aead) ? ssl->specs.hash_size : 0;
01631 
01632     return BAD_FUNC_ARG;
01633 }
01634 
01635 #endif /* ATOMIC_USER */
01636 
01637 #ifndef NO_CERTS
01638 
01639 int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
01640 {
01641     int ret = BAD_FUNC_ARG;
01642     if (pDer) {
01643         int dynType = 0;
01644         DerBuffer* der;
01645 
01646         /* Determine dynamic type */
01647         switch (type) {
01648             case CA_TYPE:   dynType = DYNAMIC_TYPE_CA;   break;
01649             case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;
01650             case CRL_TYPE:  dynType = DYNAMIC_TYPE_CRL;  break;
01651             case DSA_TYPE:  dynType = DYNAMIC_TYPE_DSA;  break;
01652             case ECC_TYPE:  dynType = DYNAMIC_TYPE_ECC;  break;
01653             case RSA_TYPE:  dynType = DYNAMIC_TYPE_RSA;  break;
01654             default:        dynType = DYNAMIC_TYPE_KEY;  break;
01655         }
01656 
01657         /* Setup new buffer */
01658         *pDer = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + length, heap, dynType);
01659         if (*pDer == NULL) {
01660             return MEMORY_ERROR;
01661         }
01662 
01663         der = *pDer;
01664         der->type = type;
01665         der->dynType = dynType; /* Cache this for FreeDer */
01666         der->heap = heap;
01667         der->buffer = (byte*)der + sizeof(DerBuffer);
01668         der->length = length;
01669         ret = 0; /* Success */
01670     }
01671     return ret;
01672 }
01673 
01674 void FreeDer(DerBuffer** pDer)
01675 {
01676     if (pDer && *pDer)
01677     {
01678         DerBuffer* der = (DerBuffer*)*pDer;
01679 
01680         /* ForceZero private keys */
01681         if (der->type == PRIVATEKEY_TYPE) {
01682             ForceZero(der->buffer, der->length);
01683         }
01684         der->buffer = NULL;
01685         der->length = 0;
01686         XFREE(der, der->heap, der->dynType);
01687 
01688         *pDer = NULL;
01689     }
01690 }
01691 
01692 WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void)
01693 {
01694     WOLFSSL_CERT_MANAGER* cm = NULL;
01695 
01696     WOLFSSL_ENTER("wolfSSL_CertManagerNew");
01697 
01698     cm = (WOLFSSL_CERT_MANAGER*) XMALLOC(sizeof(WOLFSSL_CERT_MANAGER), 0,
01699                                          DYNAMIC_TYPE_CERT_MANAGER);
01700     if (cm) {
01701         XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER));
01702 
01703         if (InitMutex(&cm->caLock) != 0) {
01704             WOLFSSL_MSG("Bad mutex init");
01705             wolfSSL_CertManagerFree(cm);
01706             return NULL;
01707         }
01708 
01709         #ifdef WOLFSSL_TRUST_PEER_CERT
01710         if (InitMutex(&cm->tpLock) != 0) {
01711             WOLFSSL_MSG("Bad mutex init");
01712             wolfSSL_CertManagerFree(cm);
01713             return NULL;
01714         }
01715         #endif
01716     }
01717 
01718     return cm;
01719 }
01720 
01721 
01722 void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
01723 {
01724     WOLFSSL_ENTER("wolfSSL_CertManagerFree");
01725 
01726     if (cm) {
01727         #ifdef HAVE_CRL
01728             if (cm->crl)
01729                 FreeCRL(cm->crl, 1);
01730         #endif
01731         #ifdef HAVE_OCSP
01732             if (cm->ocsp)
01733                 FreeOCSP(cm->ocsp, 1);
01734         #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
01735          || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
01736             if (cm->ocsp_stapling)
01737                 FreeOCSP(cm->ocsp_stapling, 1);
01738         #endif
01739         #endif
01740         FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
01741         FreeMutex(&cm->caLock);
01742 
01743         #ifdef WOLFSSL_TRUST_PEER_CERT
01744         FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, NULL);
01745         FreeMutex(&cm->tpLock);
01746         #endif
01747 
01748         XFREE(cm, NULL, DYNAMIC_TYPE_CERT_MANAGER);
01749     }
01750 
01751 }
01752 
01753 
01754 /* Unload the CA signer list */
01755 int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
01756 {
01757     WOLFSSL_ENTER("wolfSSL_CertManagerUnloadCAs");
01758 
01759     if (cm == NULL)
01760         return BAD_FUNC_ARG;
01761 
01762     if (LockMutex(&cm->caLock) != 0)
01763         return BAD_MUTEX_E;
01764 
01765     FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
01766 
01767     UnLockMutex(&cm->caLock);
01768 
01769 
01770     return SSL_SUCCESS;
01771 }
01772 
01773 
01774 #ifdef WOLFSSL_TRUST_PEER_CERT
01775 int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm)
01776 {
01777     WOLFSSL_ENTER("wolfSSL_CertManagerUnload_trust_peers");
01778 
01779     if (cm == NULL)
01780         return BAD_FUNC_ARG;
01781 
01782     if (LockMutex(&cm->tpLock) != 0)
01783         return BAD_MUTEX_E;
01784 
01785     FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, NULL);
01786 
01787     UnLockMutex(&cm->tpLock);
01788 
01789 
01790     return SSL_SUCCESS;
01791 }
01792 #endif /* WOLFSSL_TRUST_PEER_CERT */
01793 
01794 
01795 /* Return bytes written to buff or < 0 for error */
01796 int wolfSSL_CertPemToDer(const unsigned char* pem, int pemSz,
01797                         unsigned char* buff, int buffSz, int type)
01798 {
01799     int            eccKey = 0;
01800     int            ret;
01801     DerBuffer*     der = NULL;
01802 #ifdef WOLFSSL_SMALL_STACK
01803     EncryptedInfo* info = NULL;
01804 #else
01805     EncryptedInfo  info[1];
01806 #endif
01807 
01808     WOLFSSL_ENTER("wolfSSL_CertPemToDer");
01809 
01810     if (pem == NULL || buff == NULL || buffSz <= 0) {
01811         WOLFSSL_MSG("Bad pem der args");
01812         return BAD_FUNC_ARG;
01813     }
01814 
01815     if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) {
01816         WOLFSSL_MSG("Bad cert type");
01817         return BAD_FUNC_ARG;
01818     }
01819 
01820 #ifdef WOLFSSL_SMALL_STACK
01821     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
01822                                    DYNAMIC_TYPE_TMP_BUFFER);
01823     if (info == NULL)
01824         return MEMORY_E;
01825 #endif
01826 
01827     info->set      = 0;
01828     info->ctx      = NULL;
01829     info->consumed = 0;
01830 
01831     ret = PemToDer(pem, pemSz, type, &der, NULL, info, &eccKey);
01832 
01833 #ifdef WOLFSSL_SMALL_STACK
01834     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01835 #endif
01836 
01837     if (ret < 0) {
01838         WOLFSSL_MSG("Bad Pem To Der");
01839     }
01840     else {
01841         if (der->length <= (word32)buffSz) {
01842             XMEMCPY(buff, der->buffer, der->length);
01843             ret = der->length;
01844         }
01845         else {
01846             WOLFSSL_MSG("Bad der length");
01847             ret = BAD_FUNC_ARG;
01848         }
01849     }
01850 
01851     FreeDer(&der);
01852     return ret;
01853 }
01854 
01855 
01856 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
01857 
01858 static const char *EVP_AES_128_CBC = "AES-128-CBC";
01859 static const char *EVP_AES_192_CBC = "AES-192-CBC";
01860 static const char *EVP_AES_256_CBC = "AES-256-CBC";
01861 #if defined(OPENSSL_EXTRA)
01862     static const char *EVP_AES_128_CTR = "AES-128-CTR";
01863     static const char *EVP_AES_192_CTR = "AES-192-CTR";
01864     static const char *EVP_AES_256_CTR = "AES-256-CTR";
01865 #endif
01866 static const int  EVP_AES_SIZE = 11;
01867 
01868 static const char *EVP_DES_CBC = "DES-CBC";
01869 static const int  EVP_DES_SIZE = 7;
01870 
01871 static const char *EVP_DES_EDE3_CBC = "DES-EDE3-CBC";
01872 static const int  EVP_DES_EDE3_SIZE = 12;
01873 
01874 #ifdef HAVE_IDEA
01875 static const char *EVP_IDEA_CBC = "IDEA-CBC";
01876 static const int  EVP_IDEA_SIZE = 8;
01877 #endif
01878 
01879 /* our KeyPemToDer password callback, password in userData */
01880 static INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
01881 {
01882     (void)rw;
01883 
01884     if (userdata == NULL)
01885         return 0;
01886 
01887     XSTRNCPY(passwd, (char*)userdata, sz);
01888     return min((word32)sz, (word32)XSTRLEN((char*)userdata));
01889 }
01890 
01891 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
01892 
01893 
01894 /* Return bytes written to buff or < 0 for error */
01895 int wolfSSL_KeyPemToDer(const unsigned char* pem, int pemSz,
01896                         unsigned char* buff, int buffSz, const char* pass)
01897 {
01898     int            eccKey = 0;
01899     int            ret;
01900     DerBuffer*     der = NULL;
01901 #ifdef WOLFSSL_SMALL_STACK
01902     EncryptedInfo* info = NULL;
01903 #else
01904     EncryptedInfo  info[1];
01905 #endif
01906 
01907     WOLFSSL_ENTER("wolfSSL_KeyPemToDer");
01908 
01909     if (pem == NULL || buff == NULL || buffSz <= 0) {
01910         WOLFSSL_MSG("Bad pem der args");
01911         return BAD_FUNC_ARG;
01912     }
01913 
01914 #ifdef WOLFSSL_SMALL_STACK
01915     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
01916                                    DYNAMIC_TYPE_TMP_BUFFER);
01917     if (info == NULL)
01918         return MEMORY_E;
01919 #endif
01920 
01921     info->set      = 0;
01922     info->ctx      = NULL;
01923     info->consumed = 0;
01924 
01925 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
01926     if (pass) {
01927         info->ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
01928         if (info->ctx == NULL) {
01929         #ifdef WOLFSSL_SMALL_STACK
01930             XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01931         #endif
01932             return MEMORY_E;
01933         }
01934 
01935         wolfSSL_CTX_set_default_passwd_cb(info->ctx, OurPasswordCb);
01936         wolfSSL_CTX_set_default_passwd_cb_userdata(info->ctx, (void*)pass);
01937     }
01938 #else
01939     (void)pass;
01940 #endif
01941 
01942     ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, &eccKey);
01943 
01944     if (info->ctx)
01945         wolfSSL_CTX_free(info->ctx);
01946 
01947 #ifdef WOLFSSL_SMALL_STACK
01948     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01949 #endif
01950 
01951     if (ret < 0) {
01952         WOLFSSL_MSG("Bad Pem To Der");
01953     }
01954     else {
01955         if (der->length <= (word32)buffSz) {
01956             XMEMCPY(buff, der->buffer, der->length);
01957             ret = der->length;
01958         }
01959         else {
01960             WOLFSSL_MSG("Bad der length");
01961             ret = BAD_FUNC_ARG;
01962         }
01963     }
01964 
01965     FreeDer(&der);
01966     return ret;
01967 }
01968 
01969 #endif /* !NO_CERTS */
01970 
01971 
01972 
01973 #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
01974 
01975 void wolfSSL_ERR_print_errors_fp(FILE* fp, int err)
01976 {
01977     char data[WOLFSSL_MAX_ERROR_SZ + 1];
01978 
01979     WOLFSSL_ENTER("wolfSSL_ERR_print_errors_fp");
01980     SetErrorString(err, data);
01981     fprintf(fp, "%s", data);
01982 }
01983 
01984 #endif
01985 
01986 
01987 int wolfSSL_pending(WOLFSSL* ssl)
01988 {
01989     WOLFSSL_ENTER("SSL_pending");
01990     return ssl->buffers.clearOutputBuffer.length;
01991 }
01992 
01993 
01994 #ifndef WOLFSSL_LEANPSK
01995 /* turn on handshake group messages for context */
01996 int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx)
01997 {
01998     if (ctx == NULL)
01999        return BAD_FUNC_ARG;
02000 
02001     ctx->groupMessages = 1;
02002 
02003     return SSL_SUCCESS;
02004 }
02005 #endif
02006 
02007 
02008 #ifndef NO_WOLFSSL_CLIENT
02009 /* connect enough to get peer cert chain */
02010 int wolfSSL_connect_cert(WOLFSSL* ssl)
02011 {
02012     int  ret;
02013 
02014     if (ssl == NULL)
02015         return SSL_FAILURE;
02016 
02017     ssl->options.certOnly = 1;
02018     ret = wolfSSL_connect(ssl);
02019     ssl->options.certOnly   = 0;
02020 
02021     return ret;
02022 }
02023 #endif
02024 
02025 
02026 #ifndef WOLFSSL_LEANPSK
02027 /* turn on handshake group messages for ssl object */
02028 int wolfSSL_set_group_messages(WOLFSSL* ssl)
02029 {
02030     if (ssl == NULL)
02031        return BAD_FUNC_ARG;
02032 
02033     ssl->options.groupMessages = 1;
02034 
02035     return SSL_SUCCESS;
02036 }
02037 
02038 
02039 /* make minVersion the internal equivalent SSL version */
02040 static int SetMinVersionHelper(byte* minVersion, int version)
02041 {
02042     switch (version) {
02043 #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
02044         case WOLFSSL_SSLV3:
02045             *minVersion = SSLv3_MINOR;
02046             break;
02047 #endif
02048 
02049 #ifndef NO_TLS
02050     #ifndef NO_OLD_TLS
02051         case WOLFSSL_TLSV1:
02052             *minVersion = TLSv1_MINOR;
02053             break;
02054 
02055         case WOLFSSL_TLSV1_1:
02056             *minVersion = TLSv1_1_MINOR;
02057             break;
02058     #endif
02059         case WOLFSSL_TLSV1_2:
02060             *minVersion = TLSv1_2_MINOR;
02061             break;
02062 #endif
02063 
02064         default:
02065             WOLFSSL_MSG("Bad function argument");
02066             return BAD_FUNC_ARG;
02067     }
02068 
02069     return SSL_SUCCESS;
02070 }
02071 
02072 
02073 /* Set minimum downgrade version allowed, SSL_SUCCESS on ok */
02074 int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version)
02075 {
02076     WOLFSSL_ENTER("wolfSSL_CTX_SetMinVersion");
02077 
02078     if (ctx == NULL) {
02079         WOLFSSL_MSG("Bad function argument");
02080         return BAD_FUNC_ARG;
02081     }
02082 
02083     return SetMinVersionHelper(&ctx->minDowngrade, version);
02084 }
02085 
02086 
02087 /* Set minimum downgrade version allowed, SSL_SUCCESS on ok */
02088 int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version)
02089 {
02090     WOLFSSL_ENTER("wolfSSL_SetMinVersion");
02091 
02092     if (ssl == NULL) {
02093         WOLFSSL_MSG("Bad function argument");
02094         return BAD_FUNC_ARG;
02095     }
02096 
02097     return SetMinVersionHelper(&ssl->options.minDowngrade, version);
02098 }
02099 
02100 
02101 int wolfSSL_SetVersion(WOLFSSL* ssl, int version)
02102 {
02103     word16 haveRSA = 1;
02104     word16 havePSK = 0;
02105 
02106     WOLFSSL_ENTER("wolfSSL_SetVersion");
02107 
02108     if (ssl == NULL) {
02109         WOLFSSL_MSG("Bad function argument");
02110         return BAD_FUNC_ARG;
02111     }
02112 
02113     switch (version) {
02114 #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
02115         case WOLFSSL_SSLV3:
02116             ssl->version = MakeSSLv3();
02117             break;
02118 #endif
02119 
02120 #ifndef NO_TLS
02121     #ifndef NO_OLD_TLS
02122         case WOLFSSL_TLSV1:
02123             ssl->version = MakeTLSv1();
02124             break;
02125 
02126         case WOLFSSL_TLSV1_1:
02127             ssl->version = MakeTLSv1_1();
02128             break;
02129     #endif
02130         case WOLFSSL_TLSV1_2:
02131             ssl->version = MakeTLSv1_2();
02132             break;
02133 #endif
02134 
02135         default:
02136             WOLFSSL_MSG("Bad function argument");
02137             return BAD_FUNC_ARG;
02138     }
02139 
02140     #ifdef NO_RSA
02141         haveRSA = 0;
02142     #endif
02143     #ifndef NO_PSK
02144         havePSK = ssl->options.havePSK;
02145     #endif
02146 
02147     InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH,
02148                 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
02149                 ssl->options.haveECC, ssl->options.haveStaticECC,
02150                 ssl->options.side);
02151 
02152     return SSL_SUCCESS;
02153 }
02154 #endif /* !leanpsk */
02155 
02156 
02157 #if !defined(NO_CERTS) || !defined(NO_SESSION_CACHE)
02158 
02159 /* Make a work from the front of random hash */
02160 static INLINE word32 MakeWordFromHash(const byte* hashID)
02161 {
02162     return (hashID[0] << 24) | (hashID[1] << 16) | (hashID[2] <<  8) |
02163             hashID[3];
02164 }
02165 
02166 #endif /* !NO_CERTS || !NO_SESSION_CACHE */
02167 
02168 
02169 #ifndef NO_CERTS
02170 
02171 /* hash is the SHA digest of name, just use first 32 bits as hash */
02172 static INLINE word32 HashSigner(const byte* hash)
02173 {
02174     return MakeWordFromHash(hash) % CA_TABLE_SIZE;
02175 }
02176 
02177 
02178 /* does CA already exist on signer list */
02179 int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash)
02180 {
02181     Signer* signers;
02182     int     ret = 0;
02183     word32  row = HashSigner(hash);
02184 
02185     if (LockMutex(&cm->caLock) != 0)
02186         return  ret;
02187     signers = cm->caTable[row];
02188     while (signers) {
02189         byte* subjectHash;
02190         #ifndef NO_SKID
02191             subjectHash = signers->subjectKeyIdHash;
02192         #else
02193             subjectHash = signers->subjectNameHash;
02194         #endif
02195         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
02196             ret = 1;
02197             break;
02198         }
02199         signers = signers->next;
02200     }
02201     UnLockMutex(&cm->caLock);
02202 
02203     return ret;
02204 }
02205 
02206 
02207 #ifdef WOLFSSL_TRUST_PEER_CERT
02208 /* hash is the SHA digest of name, just use first 32 bits as hash */
02209 static INLINE word32 TrustedPeerHashSigner(const byte* hash)
02210 {
02211     return MakeWordFromHash(hash) % TP_TABLE_SIZE;
02212 }
02213 
02214 /* does trusted peer already exist on signer list */
02215 int AlreadyTrustedPeer(WOLFSSL_CERT_MANAGER* cm, byte* hash)
02216 {
02217     TrustedPeerCert* tp;
02218     int     ret = 0;
02219     word32  row = TrustedPeerHashSigner(hash);
02220 
02221     if (LockMutex(&cm->tpLock) != 0)
02222         return  ret;
02223     tp = cm->tpTable[row];
02224     while (tp) {
02225         byte* subjectHash;
02226         #ifndef NO_SKID
02227             subjectHash = tp->subjectKeyIdHash;
02228         #else
02229             subjectHash = tp->subjectNameHash;
02230         #endif
02231         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
02232             ret = 1;
02233             break;
02234         }
02235         tp = tp->next;
02236     }
02237     UnLockMutex(&cm->tpLock);
02238 
02239     return ret;
02240 }
02241 
02242 
02243 /* return Trusted Peer if found, otherwise NULL
02244     type is what to match on
02245  */
02246 TrustedPeerCert* GetTrustedPeer(void* vp, byte* hash, int type)
02247 {
02248     WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
02249     TrustedPeerCert* ret = NULL;
02250     TrustedPeerCert* tp  = NULL;
02251     word32  row;
02252 
02253     if (cm == NULL || hash == NULL)
02254         return NULL;
02255 
02256     row = TrustedPeerHashSigner(hash);
02257 
02258     if (LockMutex(&cm->tpLock) != 0)
02259         return ret;
02260 
02261     tp = cm->tpTable[row];
02262     while (tp) {
02263         byte* subjectHash;
02264         switch (type) {
02265             #ifndef NO_SKID
02266             case WC_MATCH_SKID:
02267                 subjectHash = tp->subjectKeyIdHash;
02268                 break;
02269             #endif
02270             case WC_MATCH_NAME:
02271                 subjectHash = tp->subjectNameHash;
02272                 break;
02273             default:
02274                 WOLFSSL_MSG("Unknown search type");
02275                 UnLockMutex(&cm->tpLock);
02276                 return NULL;
02277         }
02278         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
02279             ret = tp;
02280             break;
02281         }
02282         tp = tp->next;
02283     }
02284     UnLockMutex(&cm->tpLock);
02285 
02286     return ret;
02287 }
02288 
02289 
02290 int MatchTrustedPeer(TrustedPeerCert* tp, DecodedCert* cert)
02291 {
02292     if (tp == NULL || cert == NULL)
02293         return BAD_FUNC_ARG;
02294 
02295     /* subject key id or subject hash has been compared when searching
02296        tpTable for the cert from function GetTrustedPeer */
02297 
02298     /* compare signatures */
02299     if (tp->sigLen == cert->sigLength) {
02300         if (XMEMCMP(tp->sig, cert->signature, cert->sigLength)) {
02301             return SSL_FAILURE;
02302         }
02303     }
02304     else {
02305         return SSL_FAILURE;
02306     }
02307 
02308     return SSL_SUCCESS;
02309 }
02310 #endif /* WOLFSSL_TRUST_PEER_CERT */
02311 
02312 
02313 /* return CA if found, otherwise NULL */
02314 Signer* GetCA(void* vp, byte* hash)
02315 {
02316     WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
02317     Signer* ret = NULL;
02318     Signer* signers;
02319     word32  row = HashSigner(hash);
02320 
02321     if (cm == NULL)
02322         return NULL;
02323 
02324     if (LockMutex(&cm->caLock) != 0)
02325         return ret;
02326 
02327     signers = cm->caTable[row];
02328     while (signers) {
02329         byte* subjectHash;
02330         #ifndef NO_SKID
02331             subjectHash = signers->subjectKeyIdHash;
02332         #else
02333             subjectHash = signers->subjectNameHash;
02334         #endif
02335         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
02336             ret = signers;
02337             break;
02338         }
02339         signers = signers->next;
02340     }
02341     UnLockMutex(&cm->caLock);
02342 
02343     return ret;
02344 }
02345 
02346 
02347 #ifndef NO_SKID
02348 /* return CA if found, otherwise NULL. Walk through hash table. */
02349 Signer* GetCAByName(void* vp, byte* hash)
02350 {
02351     WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
02352     Signer* ret = NULL;
02353     Signer* signers;
02354     word32  row;
02355 
02356     if (cm == NULL)
02357         return NULL;
02358 
02359     if (LockMutex(&cm->caLock) != 0)
02360         return ret;
02361 
02362     for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
02363         signers = cm->caTable[row];
02364         while (signers && ret == NULL) {
02365             if (XMEMCMP(hash, signers->subjectNameHash,
02366                         SIGNER_DIGEST_SIZE) == 0) {
02367                 ret = signers;
02368             }
02369             signers = signers->next;
02370         }
02371     }
02372     UnLockMutex(&cm->caLock);
02373 
02374     return ret;
02375 }
02376 #endif
02377 
02378 
02379 #ifdef WOLFSSL_TRUST_PEER_CERT
02380 /* add a trusted peer cert to linked list */
02381 int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify)
02382 {
02383     int ret, row;
02384     TrustedPeerCert* peerCert;
02385     DecodedCert* cert = NULL;
02386     DerBuffer*   der = *pDer;
02387     byte* subjectHash = NULL;
02388 
02389     WOLFSSL_MSG("Adding a Trusted Peer Cert");
02390 
02391     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
02392                                  DYNAMIC_TYPE_TMP_BUFFER);
02393     if (cert == NULL)
02394         return MEMORY_E;
02395 
02396     InitDecodedCert(cert, der->buffer, der->length, cm->heap);
02397     if ((ret = ParseCert(cert, TRUSTED_PEER_TYPE, verify, cm)) != 0) {
02398         XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02399         return ret;
02400     }
02401     WOLFSSL_MSG("    Parsed new trusted peer cert");
02402 
02403     peerCert = (TrustedPeerCert*)XMALLOC(sizeof(TrustedPeerCert), NULL,
02404                                                              DYNAMIC_TYPE_CERT);
02405     if (peerCert == NULL) {
02406         FreeDecodedCert(cert);
02407         XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02408         return MEMORY_E;
02409     }
02410     XMEMSET(peerCert, 0, sizeof(TrustedPeerCert));
02411 
02412 #ifndef NO_SKID
02413     if (cert->extAuthKeyIdSet) {
02414         subjectHash = cert->extSubjKeyId;
02415     }
02416     else {
02417         subjectHash = cert->subjectHash;
02418     }
02419 #else
02420     subjectHash = cert->subjectHash;
02421 #endif
02422 
02423     #ifndef IGNORE_NAME_CONSTRAINTS
02424         if (peerCert->permittedNames)
02425             FreeNameSubtrees(peerCert->permittedNames, cm->heap);
02426         if (peerCert->excludedNames)
02427             FreeNameSubtrees(peerCert->excludedNames, cm->heap);
02428     #endif
02429 
02430     if (AlreadyTrustedPeer(cm, subjectHash)) {
02431         WOLFSSL_MSG("    Already have this CA, not adding again");
02432         (void)ret;
02433     }
02434     else {
02435         /* add trusted peer signature */
02436         peerCert->sigLen = cert->sigLength;
02437         peerCert->sig = XMALLOC(cert->sigLength, cm->heap,
02438                                                         DYNAMIC_TYPE_SIGNATURE);
02439         if (peerCert->sig == NULL) {
02440             FreeDecodedCert(cert);
02441             XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02442             FreeTrustedPeer(peerCert, cm->heap);
02443             return MEMORY_E;
02444         }
02445         XMEMCPY(peerCert->sig, cert->signature, cert->sigLength);
02446 
02447         /* add trusted peer name */
02448         peerCert->nameLen = cert->subjectCNLen;
02449         peerCert->name    = cert->subjectCN;
02450         #ifndef IGNORE_NAME_CONSTRAINTS
02451             peerCert->permittedNames = cert->permittedNames;
02452             peerCert->excludedNames  = cert->excludedNames;
02453         #endif
02454 
02455         /* add SKID when available and hash of name */
02456         #ifndef NO_SKID
02457             XMEMCPY(peerCert->subjectKeyIdHash, cert->extSubjKeyId,
02458                     SIGNER_DIGEST_SIZE);
02459         #endif
02460             XMEMCPY(peerCert->subjectNameHash, cert->subjectHash,
02461                     SIGNER_DIGEST_SIZE);
02462             peerCert->next    = NULL; /* If Key Usage not set, all uses valid. */
02463             cert->subjectCN = 0;
02464         #ifndef IGNORE_NAME_CONSTRAINTS
02465             cert->permittedNames = NULL;
02466             cert->excludedNames = NULL;
02467         #endif
02468 
02469         #ifndef NO_SKID
02470             if (cert->extAuthKeyIdSet) {
02471                 row = TrustedPeerHashSigner(peerCert->subjectKeyIdHash);
02472             }
02473             else {
02474                 row = TrustedPeerHashSigner(peerCert->subjectNameHash);
02475             }
02476         #else
02477             row = TrustedPeerHashSigner(peerCert->subjectNameHash);
02478         #endif
02479 
02480             if (LockMutex(&cm->tpLock) == 0) {
02481                 peerCert->next = cm->tpTable[row];
02482                 cm->tpTable[row] = peerCert;   /* takes ownership */
02483                 UnLockMutex(&cm->tpLock);
02484             }
02485             else {
02486                 WOLFSSL_MSG("    Trusted Peer Cert Mutex Lock failed");
02487                 FreeDecodedCert(cert);
02488                 XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02489                 FreeTrustedPeer(peerCert, cm->heap);
02490                 return BAD_MUTEX_E;
02491             }
02492         }
02493 
02494     WOLFSSL_MSG("    Freeing parsed trusted peer cert");
02495     FreeDecodedCert(cert);
02496     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02497     WOLFSSL_MSG("    Freeing der trusted peer cert");
02498     FreeDer(&der);
02499     WOLFSSL_MSG("        OK Freeing der trusted peer cert");
02500     WOLFSSL_LEAVE("AddTrustedPeer", ret);
02501 
02502     return SSL_SUCCESS;
02503 }
02504 #endif /* WOLFSSL_TRUST_PEER_CERT */
02505 
02506 
02507 /* owns der, internal now uses too */
02508 /* type flag ids from user or from chain received during verify
02509    don't allow chain ones to be added w/o isCA extension */
02510 int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
02511 {
02512     int         ret;
02513     Signer*     signer = 0;
02514     word32      row;
02515     byte*       subjectHash;
02516 #ifdef WOLFSSL_SMALL_STACK
02517     DecodedCert* cert = NULL;
02518 #else
02519     DecodedCert  cert[1];
02520 #endif
02521     DerBuffer*   der = *pDer;
02522 
02523     WOLFSSL_MSG("Adding a CA");
02524 
02525 #ifdef WOLFSSL_SMALL_STACK
02526     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
02527                                  DYNAMIC_TYPE_TMP_BUFFER);
02528     if (cert == NULL)
02529         return MEMORY_E;
02530 #endif
02531 
02532     InitDecodedCert(cert, der->buffer, der->length, cm->heap);
02533     ret = ParseCert(cert, CA_TYPE, verify, cm);
02534     WOLFSSL_MSG("    Parsed new CA");
02535 
02536 #ifndef NO_SKID
02537     subjectHash = cert->extSubjKeyId;
02538 #else
02539     subjectHash = cert->subjectHash;
02540 #endif
02541 
02542     if (ret == 0 && cert->isCA == 0 && type != WOLFSSL_USER_CA) {
02543         WOLFSSL_MSG("    Can't add as CA if not actually one");
02544         ret = NOT_CA_ERROR;
02545     }
02546 #ifndef ALLOW_INVALID_CERTSIGN
02547     else if (ret == 0 && cert->isCA == 1 && type != WOLFSSL_USER_CA &&
02548              (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) == 0) {
02549         /* Intermediate CA certs are required to have the keyCertSign
02550         * extension set. User loaded root certs are not. */
02551         WOLFSSL_MSG("    Doesn't have key usage certificate signing");
02552         ret = NOT_CA_ERROR;
02553     }
02554 #endif
02555     else if (ret == 0 && AlreadySigner(cm, subjectHash)) {
02556         WOLFSSL_MSG("    Already have this CA, not adding again");
02557         (void)ret;
02558     }
02559     else if (ret == 0) {
02560         /* take over signer parts */
02561         signer = MakeSigner(cm->heap);
02562         if (!signer)
02563             ret = MEMORY_ERROR;
02564         else {
02565             signer->keyOID         = cert->keyOID;
02566             signer->publicKey      = cert->publicKey;
02567             signer->pubKeySize     = cert->pubKeySize;
02568             signer->nameLen        = cert->subjectCNLen;
02569             signer->name           = cert->subjectCN;
02570         #ifndef IGNORE_NAME_CONSTRAINTS
02571             signer->permittedNames = cert->permittedNames;
02572             signer->excludedNames  = cert->excludedNames;
02573         #endif
02574         #ifndef NO_SKID
02575             XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
02576                     SIGNER_DIGEST_SIZE);
02577         #endif
02578             XMEMCPY(signer->subjectNameHash, cert->subjectHash,
02579                     SIGNER_DIGEST_SIZE);
02580             signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
02581                                                     : 0xFFFF;
02582             signer->next    = NULL; /* If Key Usage not set, all uses valid. */
02583             cert->publicKey = 0;    /* in case lock fails don't free here.   */
02584             cert->subjectCN = 0;
02585         #ifndef IGNORE_NAME_CONSTRAINTS
02586             cert->permittedNames = NULL;
02587             cert->excludedNames = NULL;
02588         #endif
02589 
02590         #ifndef NO_SKID
02591             row = HashSigner(signer->subjectKeyIdHash);
02592         #else
02593             row = HashSigner(signer->subjectNameHash);
02594         #endif
02595 
02596             if (LockMutex(&cm->caLock) == 0) {
02597                 signer->next = cm->caTable[row];
02598                 cm->caTable[row] = signer;   /* takes ownership */
02599                 UnLockMutex(&cm->caLock);
02600                 if (cm->caCacheCallback)
02601                     cm->caCacheCallback(der->buffer, (int)der->length, type);
02602             }
02603             else {
02604                 WOLFSSL_MSG("    CA Mutex Lock failed");
02605                 ret = BAD_MUTEX_E;
02606                 FreeSigner(signer, cm->heap);
02607             }
02608         }
02609     }
02610 
02611     WOLFSSL_MSG("    Freeing Parsed CA");
02612     FreeDecodedCert(cert);
02613 #ifdef WOLFSSL_SMALL_STACK
02614     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02615 #endif
02616     WOLFSSL_MSG("    Freeing der CA");
02617     FreeDer(pDer);
02618     WOLFSSL_MSG("        OK Freeing der CA");
02619 
02620     WOLFSSL_LEAVE("AddCA", ret);
02621 
02622     return ret == 0 ? SSL_SUCCESS : ret;
02623 }
02624 
02625 #endif /* !NO_CERTS */
02626 
02627 
02628 #ifndef NO_SESSION_CACHE
02629 
02630     /* basic config gives a cache with 33 sessions, adequate for clients and
02631        embedded servers
02632 
02633        MEDIUM_SESSION_CACHE allows 1055 sessions, adequate for servers that
02634        aren't under heavy load, basically allows 200 new sessions per minute
02635 
02636        BIG_SESSION_CACHE yields 20,027 sessions
02637 
02638        HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
02639        allows over 13,000 new sessions per minute or over 200 new sessions per
02640        second
02641 
02642        SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients
02643        or systems where the default of nearly 3kB is too much RAM, this define
02644        uses less than 500 bytes RAM
02645 
02646        default SESSION_CACHE stores 33 sessions (no XXX_SESSION_CACHE defined)
02647     */
02648     #ifdef HUGE_SESSION_CACHE
02649         #define SESSIONS_PER_ROW 11
02650         #define SESSION_ROWS 5981
02651     #elif defined(BIG_SESSION_CACHE)
02652         #define SESSIONS_PER_ROW 7
02653         #define SESSION_ROWS 2861
02654     #elif defined(MEDIUM_SESSION_CACHE)
02655         #define SESSIONS_PER_ROW 5
02656         #define SESSION_ROWS 211
02657     #elif defined(SMALL_SESSION_CACHE)
02658         #define SESSIONS_PER_ROW 2
02659         #define SESSION_ROWS 3
02660     #else
02661         #define SESSIONS_PER_ROW 3
02662         #define SESSION_ROWS 11
02663     #endif
02664 
02665     typedef struct SessionRow {
02666         int nextIdx;                           /* where to place next one   */
02667         int totalCount;                        /* sessions ever on this row */
02668         WOLFSSL_SESSION Sessions[SESSIONS_PER_ROW];
02669     } SessionRow;
02670 
02671     static SessionRow SessionCache[SESSION_ROWS];
02672 
02673     #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
02674         static word32 PeakSessions;
02675     #endif
02676 
02677     static wolfSSL_Mutex session_mutex;   /* SessionCache mutex */
02678 
02679     #ifndef NO_CLIENT_CACHE
02680 
02681         typedef struct ClientSession {
02682             word16 serverRow;            /* SessionCache Row id */
02683             word16 serverIdx;            /* SessionCache Idx (column) */
02684         } ClientSession;
02685 
02686         typedef struct ClientRow {
02687             int nextIdx;                /* where to place next one   */
02688             int totalCount;             /* sessions ever on this row */
02689             ClientSession Clients[SESSIONS_PER_ROW];
02690         } ClientRow;
02691 
02692         static ClientRow ClientCache[SESSION_ROWS];  /* Client Cache */
02693                                                      /* uses session mutex */
02694     #endif  /* NO_CLIENT_CACHE */
02695 
02696 #endif /* NO_SESSION_CACHE */
02697 
02698 int wolfSSL_Init(void)
02699 {
02700     WOLFSSL_ENTER("wolfSSL_Init");
02701 
02702     if (initRefCount == 0) {
02703         /* Initialize crypto for use with TLS connection */
02704         if (wolfCrypt_Init() != 0) {
02705             WOLFSSL_MSG("Bad wolfCrypt Init");
02706             return WC_INIT_E;
02707         }
02708 #ifndef NO_SESSION_CACHE
02709         if (InitMutex(&session_mutex) != 0) {
02710             WOLFSSL_MSG("Bad Init Mutex session");
02711             return BAD_MUTEX_E;
02712         }
02713 #endif
02714         if (InitMutex(&count_mutex) != 0) {
02715             WOLFSSL_MSG("Bad Init Mutex count");
02716             return BAD_MUTEX_E;
02717         }
02718     }
02719 
02720     if (LockMutex(&count_mutex) != 0) {
02721         WOLFSSL_MSG("Bad Lock Mutex count");
02722         return BAD_MUTEX_E;
02723     }
02724 
02725     initRefCount++;
02726     UnLockMutex(&count_mutex);
02727 
02728     return SSL_SUCCESS;
02729 }
02730 
02731 
02732 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
02733 
02734 /* SSL_SUCCESS if ok, <= 0 else */
02735 static int wolfssl_decrypt_buffer_key(DerBuffer* der, byte* password,
02736                                       int passwordSz, EncryptedInfo* info)
02737 {
02738     int ret = SSL_BAD_FILE;
02739 
02740 #ifdef WOLFSSL_SMALL_STACK
02741     byte* key      = NULL;
02742 #else
02743     byte  key[AES_256_KEY_SIZE];
02744 #endif
02745 
02746     WOLFSSL_ENTER("wolfssl_decrypt_buffer_key");
02747 
02748     if (der == NULL || password == NULL || info == NULL) {
02749         WOLFSSL_MSG("bad arguments");
02750         return SSL_FATAL_ERROR;
02751     }
02752 
02753     /* use file's salt for key derivation, hex decode first */
02754     if (Base16_Decode(info->iv, info->ivSz, info->iv, &info->ivSz) != 0) {
02755         WOLFSSL_MSG("base16 decode failed");
02756         return SSL_FATAL_ERROR;
02757     }
02758 
02759 #ifndef NO_MD5
02760 
02761 #ifdef WOLFSSL_SMALL_STACK
02762     key = (byte*)XMALLOC(AES_256_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02763     if (key == NULL) {
02764         WOLFSSL_MSG("memory failure");
02765         return SSL_FATAL_ERROR;
02766     }
02767 #endif /* WOLFSSL_SMALL_STACK */
02768 
02769     if ((ret = wolfSSL_EVP_BytesToKey(info->name, "MD5", info->iv,
02770                               password, passwordSz, 1, key, NULL)) <= 0) {
02771         WOLFSSL_MSG("bytes to key failure");
02772 #ifdef WOLFSSL_SMALL_STACK
02773         XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02774 #endif
02775         return SSL_FATAL_ERROR;
02776     }
02777 #else
02778     (void) passwordSz;
02779 #endif /* NO_MD5 */
02780 
02781 #ifndef NO_DES3
02782     if (XSTRNCMP(info->name, EVP_DES_CBC, EVP_DES_SIZE) == 0)
02783         ret = wc_Des_CbcDecryptWithKey(der->buffer, der->buffer, der->length,
02784                                        key, info->iv);
02785     else if (XSTRNCMP(info->name, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)
02786         ret = wc_Des3_CbcDecryptWithKey(der->buffer, der->buffer, der->length,
02787                                         key, info->iv);
02788 #endif /* NO_DES3 */
02789 #if !defined(NO_AES) && defined(HAVE_AES_CBC)
02790     if (XSTRNCMP(info->name, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)
02791         ret = wc_AesCbcDecryptWithKey(der->buffer, der->buffer, der->length,
02792                                       key, AES_128_KEY_SIZE, info->iv);
02793     else if (XSTRNCMP(info->name, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)
02794         ret = wc_AesCbcDecryptWithKey(der->buffer, der->buffer, der->length,
02795                                       key, AES_192_KEY_SIZE, info->iv);
02796     else if (XSTRNCMP(info->name, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)
02797         ret = wc_AesCbcDecryptWithKey(der->buffer, der->buffer, der->length,
02798                                       key, AES_256_KEY_SIZE, info->iv);
02799 #endif /* !NO_AES && HAVE_AES_CBC */
02800 
02801 #ifdef WOLFSSL_SMALL_STACK
02802     XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02803 #endif
02804 
02805     if (ret == MP_OKAY)
02806         return SSL_SUCCESS;
02807     else if (ret == SSL_BAD_FILE)
02808         return SSL_BAD_FILE;
02809 
02810     return SSL_FATAL_ERROR;
02811 }
02812 #endif /* defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) */
02813 
02814 
02815 #if defined(WOLFSSL_KEY_GEN) && defined(OPENSSL_EXTRA)
02816 static int wolfssl_encrypt_buffer_key(byte* der, word32 derSz, byte* password,
02817                                       int passwordSz, EncryptedInfo* info)
02818 {
02819     int ret = SSL_BAD_FILE;
02820 
02821 #ifdef WOLFSSL_SMALL_STACK
02822     byte* key      = NULL;
02823 #else
02824     byte  key[AES_256_KEY_SIZE];
02825 #endif
02826 
02827     WOLFSSL_ENTER("wolfssl_encrypt_buffer_key");
02828 
02829     if (der == NULL || password == NULL || info == NULL || info->ivSz == 0) {
02830         WOLFSSL_MSG("bad arguments");
02831         return SSL_FATAL_ERROR;
02832     }
02833 
02834 #ifndef NO_MD5
02835 
02836 #ifdef WOLFSSL_SMALL_STACK
02837     key = (byte*)XMALLOC(AES_256_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02838     if (key == NULL) {
02839         WOLFSSL_MSG("memory failure");
02840         return SSL_FATAL_ERROR;
02841     }
02842 #endif /* WOLFSSL_SMALL_STACK */
02843 
02844     if ((ret = wolfSSL_EVP_BytesToKey(info->name, "MD5", info->iv,
02845                               password, passwordSz, 1, key, NULL)) <= 0) {
02846         WOLFSSL_MSG("bytes to key failure");
02847 #ifdef WOLFSSL_SMALL_STACK
02848         XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02849 #endif
02850         return SSL_FATAL_ERROR;
02851     }
02852 #else
02853     (void) passwordSz;
02854 #endif /* NO_MD5 */
02855 
02856 #ifndef NO_DES3
02857     if (XSTRNCMP(info->name, EVP_DES_CBC, EVP_DES_SIZE) == 0)
02858         ret = wc_Des_CbcEncryptWithKey(der, der, derSz, key, info->iv);
02859     else if (XSTRNCMP(info->name, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)
02860         ret = wc_Des3_CbcEncryptWithKey(der, der, derSz, key, info->iv);
02861 #endif /* NO_DES3 */
02862 #ifndef NO_AES
02863     if (XSTRNCMP(info->name, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)
02864         ret = wc_AesCbcEncryptWithKey(der, der, derSz,
02865                                       key, AES_128_KEY_SIZE, info->iv);
02866     else if (XSTRNCMP(info->name, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)
02867         ret = wc_AesCbcEncryptWithKey(der, der, derSz,
02868                                       key, AES_192_KEY_SIZE, info->iv);
02869     else if (XSTRNCMP(info->name, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)
02870         ret = wc_AesCbcEncryptWithKey(der, der, derSz,
02871                                       key, AES_256_KEY_SIZE, info->iv);
02872 #endif /* NO_AES */
02873 
02874 #ifdef WOLFSSL_SMALL_STACK
02875     XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02876 #endif
02877 
02878     if (ret == MP_OKAY)
02879         return SSL_SUCCESS;
02880     else if (ret == SSL_BAD_FILE)
02881         return SSL_BAD_FILE;
02882 
02883     return SSL_FATAL_ERROR;
02884 }
02885 #endif /* defined(WOLFSSL_KEY_GEN) */
02886 
02887 
02888 #ifndef NO_CERTS
02889 
02890 /* Remove PEM header/footer, convert to ASN1, store any encrypted data
02891    info->consumed tracks of PEM bytes consumed in case multiple parts */
02892 int PemToDer(const unsigned char* buff, long longSz, int type,
02893               DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
02894 {
02895     const char* header      = NULL;
02896     const char* footer      = NULL;
02897     char*       headerEnd;
02898     char*       footerEnd;
02899     char*       consumedEnd;
02900     char*       bufferEnd   = (char*)(buff + longSz);
02901     long        neededSz;
02902     int         ret         = 0;
02903     int         sz          = (int)longSz;
02904     int         encrypted_key = 0;
02905     DerBuffer*  der;
02906 
02907     WOLFSSL_ENTER("PemToDer");
02908 
02909     switch (type) {
02910         case CA_TYPE:       /* same as below */
02911         case TRUSTED_PEER_TYPE:
02912         case CERT_TYPE:      header=BEGIN_CERT;     footer=END_CERT;     break;
02913         case CRL_TYPE:       header=BEGIN_X509_CRL; footer=END_X509_CRL; break;
02914         case DH_PARAM_TYPE:  header=BEGIN_DH_PARAM; footer=END_DH_PARAM; break;
02915         case CERTREQ_TYPE:   header=BEGIN_CERT_REQ; footer=END_CERT_REQ; break;
02916         case DSA_TYPE:       header=BEGIN_DSA_PRIV; footer=END_DSA_PRIV; break;
02917         case ECC_TYPE:       header=BEGIN_EC_PRIV;  footer=END_EC_PRIV;  break;
02918         case RSA_TYPE:       header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV; break;
02919         case PUBLICKEY_TYPE: header=BEGIN_PUB_KEY;  footer=END_PUB_KEY;  break;
02920         default:             header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV; break;
02921     }
02922 
02923     /* find header */
02924     for (;;) {
02925         headerEnd = XSTRNSTR((char*)buff, header, sz);
02926 
02927         if (headerEnd || type != PRIVATEKEY_TYPE) {
02928             break;
02929         } else if (header == BEGIN_RSA_PRIV) {
02930                    header =  BEGIN_PRIV_KEY;       footer = END_PRIV_KEY;
02931         } else if (header == BEGIN_PRIV_KEY) {
02932                    header =  BEGIN_ENC_PRIV_KEY;   footer = END_ENC_PRIV_KEY;
02933         } else if (header == BEGIN_ENC_PRIV_KEY) {
02934                    header =  BEGIN_EC_PRIV;        footer = END_EC_PRIV;
02935         } else if (header == BEGIN_EC_PRIV) {
02936                    header =  BEGIN_DSA_PRIV;       footer = END_DSA_PRIV;
02937         } else
02938             break;
02939     }
02940 
02941     if (!headerEnd) {
02942         WOLFSSL_MSG("Couldn't find PEM header");
02943         return SSL_NO_PEM_HEADER;
02944     }
02945 
02946     headerEnd += XSTRLEN(header);
02947 
02948     /* eat end of line */
02949     if (headerEnd[0] == '\n')
02950         headerEnd++;
02951     else if (headerEnd[1] == '\n')
02952         headerEnd += 2;
02953     else {
02954         if (info)
02955             info->consumed = (long)(headerEnd+2 - (char*)buff);
02956         return SSL_BAD_FILE;
02957     }
02958 
02959     if (type == PRIVATEKEY_TYPE) {
02960         if (eccKey)
02961             *eccKey = header == BEGIN_EC_PRIV;
02962     }
02963 
02964 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
02965     {
02966         /* remove encrypted header if there */
02967         char encHeader[] = "Proc-Type";
02968         char* line = XSTRNSTR(headerEnd, encHeader, PEM_LINE_LEN);
02969         if (line) {
02970             char* newline;
02971             char* finish;
02972             char* start  = XSTRNSTR(line, "DES", PEM_LINE_LEN);
02973 
02974             if (!start)
02975                 start = XSTRNSTR(line, "AES", PEM_LINE_LEN);
02976 
02977             if (!start) return SSL_BAD_FILE;
02978             if (!info)  return SSL_BAD_FILE;
02979 
02980             finish = XSTRNSTR(start, ",", PEM_LINE_LEN);
02981 
02982             if (start && finish && (start < finish)) {
02983                 newline = XSTRNSTR(finish, "\r", PEM_LINE_LEN);
02984 
02985                 if (XMEMCPY(info->name, start, finish - start) == NULL)
02986                     return SSL_FATAL_ERROR;
02987                 info->name[finish - start] = 0;
02988                 if (XMEMCPY(info->iv, finish + 1, sizeof(info->iv)) == NULL)
02989                     return SSL_FATAL_ERROR;
02990 
02991                 if (!newline) newline = XSTRNSTR(finish, "\n", PEM_LINE_LEN);
02992                 if (newline && (newline > finish)) {
02993                     info->ivSz = (word32)(newline - (finish + 1));
02994                     info->set = 1;
02995                 }
02996                 else
02997                     return SSL_BAD_FILE;
02998             }
02999             else
03000                 return SSL_BAD_FILE;
03001 
03002             /* eat blank line */
03003             while (*newline == '\r' || *newline == '\n')
03004                 newline++;
03005             headerEnd = newline;
03006 
03007             encrypted_key = 1;
03008         }
03009     }
03010 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
03011 
03012     /* find footer */
03013     footerEnd = XSTRNSTR((char*)buff, footer, sz);
03014     if (!footerEnd) {
03015         if (info)
03016             info->consumed = longSz; /* No more certs if no footer */
03017         return SSL_BAD_FILE;
03018     }
03019 
03020     consumedEnd = footerEnd + XSTRLEN(footer);
03021 
03022     if (consumedEnd < bufferEnd) {  /* handle no end of line on last line */
03023         /* eat end of line */
03024         if (consumedEnd[0] == '\n')
03025             consumedEnd++;
03026         else if (consumedEnd[1] == '\n')
03027             consumedEnd += 2;
03028         else {
03029             if (info)
03030                 info->consumed = (long)(consumedEnd+2 - (char*)buff);
03031             return SSL_BAD_FILE;
03032         }
03033     }
03034 
03035     if (info)
03036         info->consumed = (long)(consumedEnd - (char*)buff);
03037 
03038     /* set up der buffer */
03039     neededSz = (long)(footerEnd - headerEnd);
03040     if (neededSz > sz || neededSz < 0)
03041         return SSL_BAD_FILE;
03042 
03043     ret = AllocDer(pDer, (word32)neededSz, type, heap);
03044     if (ret < 0) {
03045         return ret;
03046     }
03047     der = *pDer;
03048 
03049     if (Base64_Decode((byte*)headerEnd, (word32)neededSz,
03050                       der->buffer, &der->length) < 0)
03051         return SSL_BAD_FILE;
03052 
03053     if (header == BEGIN_PRIV_KEY && !encrypted_key) {
03054         /* pkcs8 key, convert and adjust length */
03055         if ((ret = ToTraditional(der->buffer, der->length)) < 0)
03056             return ret;
03057 
03058         der->length = ret;
03059         return 0;
03060     }
03061 
03062 #if (defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)) && !defined(NO_PWDBASED)
03063     if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
03064         int   passwordSz;
03065     #ifdef WOLFSSL_SMALL_STACK
03066         char* password = NULL;
03067     #else
03068         char  password[80];
03069     #endif
03070 
03071         if (!info || !info->ctx || !info->ctx->passwd_cb)
03072             return SSL_BAD_FILE;  /* no callback error */
03073 
03074     #ifdef WOLFSSL_SMALL_STACK
03075         password = (char*)XMALLOC(80, heap, DYNAMIC_TYPE_TMP_BUFFER);
03076         if (password == NULL)
03077             return MEMORY_E;
03078     #endif
03079         passwordSz = info->ctx->passwd_cb(password, sizeof(password), 0,
03080                                           info->ctx->userdata);
03081         /* convert and adjust length */
03082         if (header == BEGIN_ENC_PRIV_KEY) {
03083             ret = ToTraditionalEnc(der->buffer, der->length,
03084                                    password, passwordSz);
03085     #ifdef WOLFSSL_SMALL_STACK
03086             XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03087     #endif
03088             if (ret < 0) {
03089                 return ret;
03090             }
03091 
03092             der->length = ret;
03093         }
03094         /* decrypt the key */
03095         else {
03096             ret = wolfssl_decrypt_buffer_key(der, (byte*)password,
03097                                              passwordSz, info);
03098     #ifdef WOLFSSL_SMALL_STACK
03099             XFREE(password, heap, DYNAMIC_TYPE_TMP_BUFFER);
03100     #endif
03101             if (ret != SSL_SUCCESS) {
03102                 return ret;
03103             }
03104         }
03105     }
03106 #endif  /* OPENSSL_EXTRA || HAVE_WEBSERVER || NO_PWDBASED */
03107 
03108     return 0;
03109 }
03110 
03111 
03112 /* process the buffer buff, length sz, into ctx of format and type
03113    used tracks bytes consumed, userChain specifies a user cert chain
03114    to pass during the handshake */
03115 static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
03116                          long sz, int format, int type, WOLFSSL* ssl,
03117                          long* used, int userChain)
03118 {
03119     DerBuffer*    der = NULL;        /* holds DER or RAW (for NTRU) */
03120     int           ret;
03121     int           eccKey = 0;
03122     int           rsaKey = 0;
03123     void*         heap = ctx ? ctx->heap : NULL;
03124 #ifdef WOLFSSL_SMALL_STACK
03125     EncryptedInfo* info = NULL;
03126 #else
03127     EncryptedInfo  info[1];
03128 #endif
03129 
03130     (void)rsaKey;
03131 
03132     if (used)
03133         *used = sz;     /* used bytes default to sz, PEM chain may shorten*/
03134 
03135     if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM
03136                                     && format != SSL_FILETYPE_RAW)
03137         return SSL_BAD_FILETYPE;
03138 
03139     if (ctx == NULL && ssl == NULL)
03140         return BAD_FUNC_ARG;
03141 
03142 #ifdef WOLFSSL_SMALL_STACK
03143     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), heap,
03144                                    DYNAMIC_TYPE_TMP_BUFFER);
03145     if (info == NULL)
03146         return MEMORY_E;
03147 #endif
03148 
03149     info->set      = 0;
03150     info->ctx      = ctx;
03151     info->consumed = 0;
03152 
03153     if (format == SSL_FILETYPE_PEM) {
03154         ret = PemToDer(buff, sz, type, &der, heap, info, &eccKey);
03155 
03156         if (used)
03157             *used = info->consumed;
03158 
03159         if (ret < 0) {
03160         #ifdef WOLFSSL_SMALL_STACK
03161             XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
03162         #endif
03163             FreeDer(&der);
03164             return ret;
03165         }
03166 
03167         /* we may have a user cert chain, try to consume */
03168         if (userChain && type == CERT_TYPE && info->consumed < sz) {
03169         #ifdef WOLFSSL_SMALL_STACK
03170             byte   staticBuffer[1];                 /* force heap usage */
03171         #else
03172             byte   staticBuffer[FILE_BUFFER_SIZE];  /* tmp chain buffer */
03173         #endif
03174             byte*  chainBuffer = staticBuffer;
03175             int    dynamicBuffer = 0;
03176             word32 bufferSz = sizeof(staticBuffer);
03177             long   consumed = info->consumed;
03178             word32 idx = 0;
03179             int    gotOne = 0;
03180 
03181             if ( (sz - consumed) > (int)bufferSz) {
03182                 WOLFSSL_MSG("Growing Tmp Chain Buffer");
03183                 bufferSz = (word32)(sz - consumed);
03184                            /* will shrink to actual size */
03185                 chainBuffer = (byte*)XMALLOC(bufferSz, heap, DYNAMIC_TYPE_FILE);
03186                 if (chainBuffer == NULL) {
03187                 #ifdef WOLFSSL_SMALL_STACK
03188                     XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
03189                 #endif
03190                     FreeDer(&der);
03191                     return MEMORY_E;
03192                 }
03193                 dynamicBuffer = 1;
03194             }
03195 
03196             WOLFSSL_MSG("Processing Cert Chain");
03197             while (consumed < sz) {
03198                 DerBuffer* part = NULL;
03199                 info->consumed = 0;
03200 
03201                 ret = PemToDer(buff + consumed, sz - consumed, type, &part,
03202                                heap, info, &eccKey);
03203                 if (ret == 0) {
03204                     gotOne = 1;
03205                     if ( (idx + part->length) > bufferSz) {
03206                         WOLFSSL_MSG("   Cert Chain bigger than buffer");
03207                         ret = BUFFER_E;
03208                     }
03209                     else {
03210                         c32to24(part->length, &chainBuffer[idx]);
03211                         idx += CERT_HEADER_SZ;
03212                         XMEMCPY(&chainBuffer[idx], part->buffer, part->length);
03213                         idx += part->length;
03214                         consumed  += info->consumed;
03215                         if (used)
03216                             *used += info->consumed;
03217                     }
03218                 }
03219                 FreeDer(&part);
03220 
03221                 if (ret == SSL_NO_PEM_HEADER && gotOne) {
03222                     WOLFSSL_MSG("We got one good PEM so stuff at end ok");
03223                     break;
03224                 }
03225 
03226                 if (ret < 0) {
03227                     WOLFSSL_MSG("   Error in Cert in Chain");
03228                     if (dynamicBuffer)
03229                         XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
03230                 #ifdef WOLFSSL_SMALL_STACK
03231                     XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
03232                 #endif
03233                     FreeDer(&der);
03234                     return ret;
03235                 }
03236                 WOLFSSL_MSG("   Consumed another Cert in Chain");
03237             }
03238             WOLFSSL_MSG("Finished Processing Cert Chain");
03239 
03240             /* only retain actual size used */
03241             ret = 0;
03242             if (idx > 0) {
03243                 if (ssl) {
03244                     if (ssl->buffers.weOwnCertChain) {
03245                         FreeDer(&ssl->buffers.certChain);
03246                     }
03247                     ret = AllocDer(&ssl->buffers.certChain, idx, type, heap);
03248                     if (ret == 0) {
03249                         XMEMCPY(ssl->buffers.certChain->buffer, chainBuffer, idx);
03250                         ssl->buffers.weOwnCertChain = 1;
03251                     }
03252                 } else if (ctx) {
03253                     FreeDer(&ctx->certChain);
03254                     ret = AllocDer(&ctx->certChain, idx, type, heap);
03255                     if (ret == 0) {
03256                         XMEMCPY(ctx->certChain->buffer, chainBuffer, idx);
03257                     }
03258                 }
03259             }
03260 
03261             if (dynamicBuffer)
03262                 XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
03263 
03264             if (ret < 0) {
03265             #ifdef WOLFSSL_SMALL_STACK
03266                 XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
03267             #endif
03268                 FreeDer(&der);
03269                 return ret;
03270             }
03271         }
03272     }
03273     else {  /* ASN1 (DER) or RAW (NTRU) */
03274         ret = AllocDer(&der, (word32)sz, type, heap);
03275         if (ret < 0) {
03276         #ifdef WOLFSSL_SMALL_STACK
03277             XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
03278         #endif
03279             return ret;
03280         }
03281 
03282         XMEMCPY(der->buffer, buff, sz);
03283     }
03284 
03285 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
03286     /* for SSL_FILETYPE_PEM, PemToDer manage the decryption if required */
03287     if (info->set && (format != SSL_FILETYPE_PEM)) {
03288         /* decrypt */
03289         int   passwordSz;
03290 #ifdef WOLFSSL_SMALL_STACK
03291         char* password = NULL;
03292 #else
03293         char  password[80];
03294 #endif
03295 
03296     #ifdef WOLFSSL_SMALL_STACK
03297         password = (char*)XMALLOC(80, heap, DYNAMIC_TYPE_TMP_BUFFER);
03298         if (password == NULL)
03299             ret = MEMORY_E;
03300         else
03301     #endif
03302         if (!ctx || !ctx->passwd_cb) {
03303             ret = NO_PASSWORD;
03304         }
03305         else {
03306             passwordSz = ctx->passwd_cb(password, sizeof(password),
03307                                         0, ctx->userdata);
03308 
03309             /* decrypt the key */
03310             ret = wolfssl_decrypt_buffer_key(der, (byte*)password,
03311                                              passwordSz, info);
03312         }
03313 
03314     #ifdef WOLFSSL_SMALL_STACK
03315         XFREE(password, heap, DYNAMIC_TYPE_TMP_BUFFER);
03316     #endif
03317 
03318         if (ret != SSL_SUCCESS) {
03319         #ifdef WOLFSSL_SMALL_STACK
03320             XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
03321         #endif
03322             FreeDer(&der);
03323             return ret;
03324         }
03325     }
03326 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
03327 
03328 #ifdef WOLFSSL_SMALL_STACK
03329     XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
03330 #endif
03331 
03332     /* Handle DER owner */
03333     if (type == CA_TYPE) {
03334         if (ctx == NULL) {
03335             WOLFSSL_MSG("Need context for CA load");
03336             FreeDer(&der);
03337             return BAD_FUNC_ARG;
03338         }
03339         /* verify CA unless user set to no verify */
03340         return AddCA(ctx->cm, &der, WOLFSSL_USER_CA, !ctx->verifyNone);
03341     }
03342 #ifdef WOLFSSL_TRUST_PEER_CERT
03343     else if (type == TRUSTED_PEER_TYPE) {
03344         if (ctx == NULL) {
03345             WOLFSSL_MSG("Need context for trusted peer cert load");
03346             FreeDer(&der);
03347             return BAD_FUNC_ARG;
03348         }
03349         /* add trusted peer cert */
03350         return AddTrustedPeer(ctx->cm, &der, !ctx->verifyNone);
03351     }
03352 #endif /* WOLFSSL_TRUST_PEER_CERT */
03353     else if (type == CERT_TYPE) {
03354         if (ssl) {
03355              /* Make sure previous is free'd */
03356             if (ssl->buffers.weOwnCert) {
03357                 FreeDer(&ssl->buffers.certificate);
03358             }
03359             XMEMCPY(&ssl->buffers.certificate, &der, sizeof(der));
03360             ssl->buffers.weOwnCert = 1;
03361         }
03362         else if (ctx) {
03363             FreeDer(&ctx->certificate); /* Make sure previous is free'd */
03364             XMEMCPY(&ctx->certificate, &der, sizeof(der));
03365         }
03366     }
03367     else if (type == PRIVATEKEY_TYPE) {
03368         if (ssl) {
03369              /* Make sure previous is free'd */
03370             if (ssl->buffers.weOwnKey) {
03371                 FreeDer(&ssl->buffers.key);
03372             }
03373             XMEMCPY(&ssl->buffers.key, &der, sizeof(der));
03374             ssl->buffers.weOwnKey = 1;
03375         }
03376         else if (ctx) {
03377             FreeDer(&ctx->privateKey);
03378             XMEMCPY(&ctx->privateKey, &der, sizeof(der));
03379         }
03380     }
03381     else {
03382         FreeDer(&der);
03383         return SSL_BAD_CERTTYPE;
03384     }
03385 
03386     if (type == PRIVATEKEY_TYPE && format != SSL_FILETYPE_RAW) {
03387     #ifndef NO_RSA
03388         if (!eccKey) {
03389             /* make sure RSA key can be used */
03390             word32 idx = 0;
03391         #ifdef WOLFSSL_SMALL_STACK
03392             RsaKey* key = NULL;
03393         #else
03394             RsaKey  key[1];
03395         #endif
03396 
03397         #ifdef WOLFSSL_SMALL_STACK
03398             key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap,
03399                                    DYNAMIC_TYPE_TMP_BUFFER);
03400             if (key == NULL)
03401                 return MEMORY_E;
03402         #endif
03403 
03404             ret = wc_InitRsaKey(key, 0);
03405             if (ret == 0) {
03406                 if (wc_RsaPrivateKeyDecode(der->buffer, &idx, key, der->length)
03407                     != 0) {
03408                 #ifdef HAVE_ECC
03409                     /* could have DER ECC (or pkcs8 ecc), no easy way to tell */
03410                     eccKey = 1;  /* so try it out */
03411                 #endif
03412                     if (!eccKey)
03413                         ret = SSL_BAD_FILE;
03414                 } else {
03415                     rsaKey = 1;
03416                     (void)rsaKey;  /* for no ecc builds */
03417                 }
03418             }
03419 
03420             wc_FreeRsaKey(key);
03421 
03422         #ifdef WOLFSSL_SMALL_STACK
03423             XFREE(key, heap, DYNAMIC_TYPE_TMP_BUFFER);
03424         #endif
03425 
03426             if (ret != 0)
03427                 return ret;
03428         }
03429     #endif
03430     #ifdef HAVE_ECC
03431         if (!rsaKey) {
03432             /* make sure ECC key can be used */
03433             word32  idx = 0;
03434             ecc_key key;
03435 
03436             wc_ecc_init(&key);
03437             if (wc_EccPrivateKeyDecode(der->buffer, &idx, &key, 
03438                                                         der->length) != 0) {
03439                 wc_ecc_free(&key);
03440                 return SSL_BAD_FILE;
03441             }
03442             wc_ecc_free(&key);
03443             eccKey = 1;
03444             if (ctx)
03445                 ctx->haveStaticECC = 1;
03446             if (ssl)
03447                 ssl->options.haveStaticECC = 1;
03448         }
03449     #endif /* HAVE_ECC */
03450     }
03451     else if (type == CERT_TYPE) {
03452     #ifdef WOLFSSL_SMALL_STACK
03453         DecodedCert* cert = NULL;
03454     #else
03455         DecodedCert  cert[1];
03456     #endif
03457 
03458     #ifdef WOLFSSL_SMALL_STACK
03459         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap,
03460                                      DYNAMIC_TYPE_TMP_BUFFER);
03461         if (cert == NULL)
03462             return MEMORY_E;
03463     #endif
03464 
03465         WOLFSSL_MSG("Checking cert signature type");
03466         InitDecodedCert(cert, der->buffer, der->length, heap);
03467 
03468         if (DecodeToKey(cert, 0) < 0) {
03469             WOLFSSL_MSG("Decode to key failed");
03470         #ifdef WOLFSSL_SMALL_STACK
03471             XFREE(cert, heap, DYNAMIC_TYPE_TMP_BUFFER);
03472         #endif
03473             return SSL_BAD_FILE;
03474         }
03475         switch (cert->signatureOID) {
03476             case CTC_SHAwECDSA:
03477             case CTC_SHA256wECDSA:
03478             case CTC_SHA384wECDSA:
03479             case CTC_SHA512wECDSA:
03480                 WOLFSSL_MSG("ECDSA cert signature");
03481                 if (ctx)
03482                     ctx->haveECDSAsig = 1;
03483                 if (ssl)
03484                     ssl->options.haveECDSAsig = 1;
03485                 break;
03486             default:
03487                 WOLFSSL_MSG("Not ECDSA cert signature");
03488                 break;
03489         }
03490 
03491     #ifdef HAVE_ECC
03492         if (ctx) {
03493             ctx->pkCurveOID = cert->pkCurveOID;
03494         #ifndef WC_STRICT_SIG
03495             if (cert->keyOID == ECDSAk) {
03496                 ctx->haveECC = 1;
03497             }
03498         #else
03499             ctx->haveECC = ctx->haveECDSAsig;
03500         #endif
03501         }
03502         if (ssl) {
03503             ssl->pkCurveOID = cert->pkCurveOID;
03504         #ifndef WC_STRICT_SIG
03505             if (cert->keyOID == ECDSAk) {
03506                 ssl->options.haveECC = 1;
03507             }
03508         #else
03509             ssl->options.haveECC = ssl->options.haveECDSAsig;
03510         #endif
03511         }
03512     #endif
03513 
03514         FreeDecodedCert(cert);
03515     #ifdef WOLFSSL_SMALL_STACK
03516         XFREE(cert, heap, DYNAMIC_TYPE_TMP_BUFFER);
03517     #endif
03518     }
03519 
03520     return SSL_SUCCESS;
03521 }
03522 
03523 
03524 /* CA PEM file for verification, may have multiple/chain certs to process */
03525 static int ProcessChainBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
03526                             long sz, int format, int type, WOLFSSL* ssl)
03527 {
03528     long used   = 0;
03529     int  ret    = 0;
03530     int  gotOne = 0;
03531 
03532     WOLFSSL_MSG("Processing CA PEM file");
03533     while (used < sz) {
03534         long consumed = 0;
03535 
03536         ret = ProcessBuffer(ctx, buff + used, sz - used, format, type, ssl,
03537                             &consumed, 0);
03538 
03539         if (ret < 0)
03540         {
03541             if(consumed > 0) { /* Made progress in file */
03542                 WOLFSSL_ERROR(ret);
03543                 WOLFSSL_MSG("CA Parse failed, with progress in file.");
03544                 WOLFSSL_MSG("Search for other certs in file");
03545             } else {
03546                 WOLFSSL_MSG("CA Parse failed, no progress in file.");
03547                 WOLFSSL_MSG("Do not continue search for other certs in file");
03548                 break;
03549             }
03550         } else {
03551             WOLFSSL_MSG("   Processed a CA");
03552             gotOne = 1;
03553         }
03554         used += consumed;
03555     }
03556 
03557     if(gotOne)
03558     {
03559         WOLFSSL_MSG("Processed at least one valid CA. Other stuff OK");
03560         return SSL_SUCCESS;
03561     }
03562     return ret;
03563 }
03564 
03565 
03566 static INLINE WOLFSSL_METHOD* cm_pick_method(void)
03567 {
03568     #ifndef NO_WOLFSSL_CLIENT
03569         #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
03570             return wolfSSLv3_client_method();
03571         #else
03572             return wolfTLSv1_2_client_method();
03573         #endif
03574     #elif !defined(NO_WOLFSSL_SERVER)
03575         #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
03576             return wolfSSLv3_server_method();
03577         #else
03578             return wolfTLSv1_2_server_method();
03579         #endif
03580     #else
03581         return NULL;
03582     #endif
03583 }
03584 
03585 
03586 /* like load verify locations, 1 for success, < 0 for error */
03587 int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm,
03588                                    const unsigned char* in, long sz, int format)
03589 {
03590     int ret = SSL_FATAL_ERROR;
03591     WOLFSSL_CTX* tmp;
03592 
03593     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCABuffer");
03594 
03595     if (cm == NULL) {
03596         WOLFSSL_MSG("No CertManager error");
03597         return ret;
03598     }
03599     tmp = wolfSSL_CTX_new(cm_pick_method());
03600 
03601     if (tmp == NULL) {
03602         WOLFSSL_MSG("CTX new failed");
03603         return ret;
03604     }
03605 
03606     /* for tmp use */
03607     wolfSSL_CertManagerFree(tmp->cm);
03608     tmp->cm = cm;
03609 
03610     ret = wolfSSL_CTX_load_verify_buffer(tmp, in, sz, format);
03611 
03612     /* don't loose our good one */
03613     tmp->cm = NULL;
03614     wolfSSL_CTX_free(tmp);
03615 
03616     return ret;
03617 }
03618 
03619 #ifdef HAVE_CRL
03620 
03621 int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER* cm,
03622                                    const unsigned char* buff, long sz, int type)
03623 {
03624     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLBuffer");
03625     if (cm == NULL)
03626         return BAD_FUNC_ARG;
03627 
03628     if (cm->crl == NULL) {
03629         if (wolfSSL_CertManagerEnableCRL(cm, 0) != SSL_SUCCESS) {
03630             WOLFSSL_MSG("Enable CRL failed");
03631             return SSL_FATAL_ERROR;
03632         }
03633     }
03634 
03635     return BufferLoadCRL(cm->crl, buff, sz, type);
03636 }
03637 
03638 #endif /* HAVE_CRL */
03639 
03640 /* turn on CRL if off and compiled in, set options */
03641 int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, int options)
03642 {
03643     int ret = SSL_SUCCESS;
03644 
03645     (void)options;
03646 
03647     WOLFSSL_ENTER("wolfSSL_CertManagerEnableCRL");
03648     if (cm == NULL)
03649         return BAD_FUNC_ARG;
03650 
03651     #ifdef HAVE_CRL
03652         if (cm->crl == NULL) {
03653             cm->crl = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), cm->heap,
03654                                            DYNAMIC_TYPE_CRL);
03655             if (cm->crl == NULL)
03656                 return MEMORY_E;
03657 
03658             if (InitCRL(cm->crl, cm) != 0) {
03659                 WOLFSSL_MSG("Init CRL failed");
03660                 FreeCRL(cm->crl, 1);
03661                 cm->crl = NULL;
03662                 return SSL_FAILURE;
03663             }
03664         }
03665         cm->crlEnabled = 1;
03666         if (options & WOLFSSL_CRL_CHECKALL)
03667             cm->crlCheckAll = 1;
03668     #else
03669         ret = NOT_COMPILED_IN;
03670     #endif
03671 
03672     return ret;
03673 }
03674 
03675 
03676 int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER* cm)
03677 {
03678     WOLFSSL_ENTER("wolfSSL_CertManagerDisableCRL");
03679     if (cm == NULL)
03680         return BAD_FUNC_ARG;
03681 
03682     cm->crlEnabled = 0;
03683 
03684     return SSL_SUCCESS;
03685 }
03686 /* Verify the certificate, SSL_SUCCESS for ok, < 0 for error */
03687 int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
03688                                     long sz, int format)
03689 {
03690     int ret = 0;
03691     DerBuffer* der = NULL;
03692 #ifdef WOLFSSL_SMALL_STACK
03693     DecodedCert* cert = NULL;
03694 #else
03695     DecodedCert  cert[1];
03696 #endif
03697 
03698     WOLFSSL_ENTER("wolfSSL_CertManagerVerifyBuffer");
03699 
03700 #ifdef WOLFSSL_SMALL_STACK
03701     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
03702                                  DYNAMIC_TYPE_TMP_BUFFER);
03703     if (cert == NULL)
03704         return MEMORY_E;
03705 #endif
03706 
03707     if (format == SSL_FILETYPE_PEM) {
03708         int eccKey = 0; /* not used */
03709     #ifdef WOLFSSL_SMALL_STACK
03710         EncryptedInfo* info = NULL;
03711     #else
03712         EncryptedInfo  info[1];
03713     #endif
03714 
03715     #ifdef WOLFSSL_SMALL_STACK
03716         info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), cm->heap,
03717                                        DYNAMIC_TYPE_TMP_BUFFER);
03718         if (info == NULL) {
03719             XFREE(cert, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
03720             return MEMORY_E;
03721         }
03722     #endif
03723 
03724         info->set      = 0;
03725         info->ctx      = NULL;
03726         info->consumed = 0;
03727 
03728         ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, info, &eccKey);
03729         InitDecodedCert(cert, der->buffer, der->length, cm->heap);
03730 
03731     #ifdef WOLFSSL_SMALL_STACK
03732         XFREE(info, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
03733     #endif
03734     }
03735     else
03736         InitDecodedCert(cert, (byte*)buff, (word32)sz, cm->heap);
03737 
03738     if (ret == 0)
03739         ret = ParseCertRelative(cert, CERT_TYPE, 1, cm);
03740 
03741 #ifdef HAVE_CRL
03742     if (ret == 0 && cm->crlEnabled)
03743         ret = CheckCertCRL(cm->crl, cert);
03744 #endif
03745 
03746     FreeDecodedCert(cert);
03747     FreeDer(&der);
03748 #ifdef WOLFSSL_SMALL_STACK
03749     XFREE(cert, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
03750 #endif
03751 
03752     return ret == 0 ? SSL_SUCCESS : ret;
03753 }
03754 
03755 
03756 /* turn on OCSP if off and compiled in, set options */
03757 int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, int options)
03758 {
03759     int ret = SSL_SUCCESS;
03760 
03761     (void)options;
03762 
03763     WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSP");
03764     if (cm == NULL)
03765         return BAD_FUNC_ARG;
03766 
03767     #ifdef HAVE_OCSP
03768         if (cm->ocsp == NULL) {
03769             cm->ocsp = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), cm->heap,
03770                                               DYNAMIC_TYPE_OCSP);
03771             if (cm->ocsp == NULL)
03772                 return MEMORY_E;
03773 
03774             if (InitOCSP(cm->ocsp, cm) != 0) {
03775                 WOLFSSL_MSG("Init OCSP failed");
03776                 FreeOCSP(cm->ocsp, 1);
03777                 cm->ocsp = NULL;
03778                 return SSL_FAILURE;
03779             }
03780         }
03781         cm->ocspEnabled = 1;
03782         if (options & WOLFSSL_OCSP_URL_OVERRIDE)
03783             cm->ocspUseOverrideURL = 1;
03784         if (options & WOLFSSL_OCSP_NO_NONCE)
03785             cm->ocspSendNonce = 0;
03786         else
03787             cm->ocspSendNonce = 1;
03788         if (options & WOLFSSL_OCSP_CHECKALL)
03789             cm->ocspCheckAll = 1;
03790         #ifndef WOLFSSL_USER_IO
03791             cm->ocspIOCb = EmbedOcspLookup;
03792             cm->ocspRespFreeCb = EmbedOcspRespFree;
03793         #endif /* WOLFSSL_USER_IO */
03794     #else
03795         ret = NOT_COMPILED_IN;
03796     #endif
03797 
03798     return ret;
03799 }
03800 
03801 
03802 int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm)
03803 {
03804     WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSP");
03805     if (cm == NULL)
03806         return BAD_FUNC_ARG;
03807 
03808     cm->ocspEnabled = 0;
03809 
03810     return SSL_SUCCESS;
03811 }
03812 
03813 /* turn on OCSP Stapling if off and compiled in, set options */
03814 int wolfSSL_CertManagerEnableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
03815 {
03816     int ret = SSL_SUCCESS;
03817 
03818     WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPStapling");
03819     if (cm == NULL)
03820         return BAD_FUNC_ARG;
03821 
03822     #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
03823      || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
03824         if (cm->ocsp_stapling == NULL) {
03825             cm->ocsp_stapling = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP),
03826                                                    cm->heap, DYNAMIC_TYPE_OCSP);
03827             if (cm->ocsp_stapling == NULL)
03828                 return MEMORY_E;
03829 
03830             if (InitOCSP(cm->ocsp_stapling, cm) != 0) {
03831                 WOLFSSL_MSG("Init OCSP failed");
03832                 FreeOCSP(cm->ocsp_stapling, 1);
03833                 cm->ocsp_stapling = NULL;
03834                 return SSL_FAILURE;
03835             }
03836         }
03837         cm->ocspStaplingEnabled = 1;
03838 
03839         #ifndef WOLFSSL_USER_IO
03840             cm->ocspIOCb = EmbedOcspLookup;
03841             cm->ocspRespFreeCb = EmbedOcspRespFree;
03842         #endif /* WOLFSSL_USER_IO */
03843     #else
03844         ret = NOT_COMPILED_IN;
03845     #endif
03846 
03847     return ret;
03848 }
03849 
03850 
03851 #ifdef HAVE_OCSP
03852 
03853 
03854 /* check CRL if enabled, SSL_SUCCESS  */
03855 int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
03856 {
03857     int ret;
03858 #ifdef WOLFSSL_SMALL_STACK
03859     DecodedCert* cert = NULL;
03860 #else
03861     DecodedCert  cert[1];
03862 #endif
03863 
03864     WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSP");
03865 
03866     if (cm == NULL)
03867         return BAD_FUNC_ARG;
03868 
03869     if (cm->ocspEnabled == 0)
03870         return SSL_SUCCESS;
03871 
03872 #ifdef WOLFSSL_SMALL_STACK
03873     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
03874                                  DYNAMIC_TYPE_TMP_BUFFER);
03875     if (cert == NULL)
03876         return MEMORY_E;
03877 #endif
03878 
03879     InitDecodedCert(cert, der, sz, NULL);
03880 
03881     if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, cm)) != 0) {
03882         WOLFSSL_MSG("ParseCert failed");
03883     }
03884     else if ((ret = CheckCertOCSP(cm->ocsp, cert, NULL)) != 0) {
03885         WOLFSSL_MSG("CheckCertOCSP failed");
03886     }
03887 
03888     FreeDecodedCert(cert);
03889 #ifdef WOLFSSL_SMALL_STACK
03890     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03891 #endif
03892 
03893     return ret == 0 ? SSL_SUCCESS : ret;
03894 }
03895 
03896 
03897 int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER* cm,
03898                                           const char* url)
03899 {
03900     WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSPOverrideURL");
03901     if (cm == NULL)
03902         return BAD_FUNC_ARG;
03903 
03904     XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
03905     if (url != NULL) {
03906         int urlSz = (int)XSTRLEN(url) + 1;
03907         cm->ocspOverrideURL = (char*)XMALLOC(urlSz, cm->heap, DYNAMIC_TYPE_URL);
03908         if (cm->ocspOverrideURL != NULL) {
03909             XMEMCPY(cm->ocspOverrideURL, url, urlSz);
03910         }
03911         else
03912             return MEMORY_E;
03913     }
03914     else
03915         cm->ocspOverrideURL = NULL;
03916 
03917     return SSL_SUCCESS;
03918 }
03919 
03920 
03921 int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER* cm,
03922                         CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
03923 {
03924     WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSP_Cb");
03925     if (cm == NULL)
03926         return BAD_FUNC_ARG;
03927 
03928     cm->ocspIOCb = ioCb;
03929     cm->ocspRespFreeCb = respFreeCb;
03930     cm->ocspIOCtx = ioCbCtx;
03931 
03932     return SSL_SUCCESS;
03933 }
03934 
03935 
03936 int wolfSSL_EnableOCSP(WOLFSSL* ssl, int options)
03937 {
03938     WOLFSSL_ENTER("wolfSSL_EnableOCSP");
03939     if (ssl)
03940         return wolfSSL_CertManagerEnableOCSP(ssl->ctx->cm, options);
03941     else
03942         return BAD_FUNC_ARG;
03943 }
03944 
03945 
03946 int wolfSSL_DisableOCSP(WOLFSSL* ssl)
03947 {
03948     WOLFSSL_ENTER("wolfSSL_DisableOCSP");
03949     if (ssl)
03950         return wolfSSL_CertManagerDisableOCSP(ssl->ctx->cm);
03951     else
03952         return BAD_FUNC_ARG;
03953 }
03954 
03955 
03956 int wolfSSL_SetOCSP_OverrideURL(WOLFSSL* ssl, const char* url)
03957 {
03958     WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
03959     if (ssl)
03960         return wolfSSL_CertManagerSetOCSPOverrideURL(ssl->ctx->cm, url);
03961     else
03962         return BAD_FUNC_ARG;
03963 }
03964 
03965 
03966 int wolfSSL_SetOCSP_Cb(WOLFSSL* ssl,
03967                         CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
03968 {
03969     WOLFSSL_ENTER("wolfSSL_SetOCSP_Cb");
03970     if (ssl)
03971         return wolfSSL_CertManagerSetOCSP_Cb(ssl->ctx->cm,
03972                                              ioCb, respFreeCb, ioCbCtx);
03973     else
03974         return BAD_FUNC_ARG;
03975 }
03976 
03977 
03978 int wolfSSL_CTX_EnableOCSP(WOLFSSL_CTX* ctx, int options)
03979 {
03980     WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSP");
03981     if (ctx)
03982         return wolfSSL_CertManagerEnableOCSP(ctx->cm, options);
03983     else
03984         return BAD_FUNC_ARG;
03985 }
03986 
03987 
03988 int wolfSSL_CTX_DisableOCSP(WOLFSSL_CTX* ctx)
03989 {
03990     WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSP");
03991     if (ctx)
03992         return wolfSSL_CertManagerDisableOCSP(ctx->cm);
03993     else
03994         return BAD_FUNC_ARG;
03995 }
03996 
03997 
03998 int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX* ctx, const char* url)
03999 {
04000     WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
04001     if (ctx)
04002         return wolfSSL_CertManagerSetOCSPOverrideURL(ctx->cm, url);
04003     else
04004         return BAD_FUNC_ARG;
04005 }
04006 
04007 
04008 int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX* ctx, CbOCSPIO ioCb,
04009                            CbOCSPRespFree respFreeCb, void* ioCbCtx)
04010 {
04011     WOLFSSL_ENTER("wolfSSL_CTX_SetOCSP_Cb");
04012     if (ctx)
04013         return wolfSSL_CertManagerSetOCSP_Cb(ctx->cm, ioCb,
04014                                              respFreeCb, ioCbCtx);
04015     else
04016         return BAD_FUNC_ARG;
04017 }
04018 
04019 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
04020  || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
04021 int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX* ctx)
04022 {
04023     WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPStapling");
04024     if (ctx)
04025         return wolfSSL_CertManagerEnableOCSPStapling(ctx->cm);
04026     else
04027         return BAD_FUNC_ARG;
04028 }
04029 #endif
04030 
04031 #endif /* HAVE_OCSP */
04032 
04033 
04034 #ifndef NO_FILESYSTEM
04035 
04036 /* process a file with name fname into ctx of format and type
04037    userChain specifies a user certificate chain to pass during handshake */
04038 int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type,
04039                 WOLFSSL* ssl, int userChain, WOLFSSL_CRL* crl)
04040 {
04041 #ifdef WOLFSSL_SMALL_STACK
04042     byte   staticBuffer[1]; /* force heap usage */
04043 #else
04044     byte   staticBuffer[FILE_BUFFER_SIZE];
04045 #endif
04046     byte*  myBuffer = staticBuffer;
04047     int    dynamic = 0;
04048     int    ret;
04049     long   sz = 0;
04050     XFILE  file;
04051     void*  heapHint = ctx ? ctx->heap : NULL;
04052 
04053     (void)crl;
04054     (void)heapHint;
04055 
04056     if (fname == NULL) return SSL_BAD_FILE;
04057 
04058     file = XFOPEN(fname, "rb");
04059     if (file == XBADFILE) return SSL_BAD_FILE;
04060     XFSEEK(file, 0, XSEEK_END);
04061     sz = XFTELL(file);
04062     XREWIND(file);
04063 
04064     if (sz > (long)sizeof(staticBuffer)) {
04065         WOLFSSL_MSG("Getting dynamic buffer");
04066         myBuffer = (byte*)XMALLOC(sz, heapHint, DYNAMIC_TYPE_FILE);
04067         if (myBuffer == NULL) {
04068             XFCLOSE(file);
04069             return SSL_BAD_FILE;
04070         }
04071         dynamic = 1;
04072     }
04073     else if (sz < 0) {
04074         XFCLOSE(file);
04075         return SSL_BAD_FILE;
04076     }
04077 
04078     if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
04079         ret = SSL_BAD_FILE;
04080     else {
04081         if ((type == CA_TYPE || type == TRUSTED_PEER_TYPE)
04082                                                   && format == SSL_FILETYPE_PEM)
04083             ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl);
04084 #ifdef HAVE_CRL
04085         else if (type == CRL_TYPE)
04086             ret = BufferLoadCRL(crl, myBuffer, sz, format);
04087 #endif
04088         else
04089             ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL,
04090                                 userChain);
04091     }
04092 
04093     XFCLOSE(file);
04094     if (dynamic)
04095         XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
04096 
04097     return ret;
04098 }
04099 
04100 
04101 /* loads file then loads each file in path, no c_rehash */
04102 int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
04103                                      const char* path)
04104 {
04105     int ret = SSL_SUCCESS;
04106 
04107     WOLFSSL_ENTER("wolfSSL_CTX_load_verify_locations");
04108     (void)path;
04109 
04110     if (ctx == NULL || (file == NULL && path == NULL) )
04111         return SSL_FAILURE;
04112 
04113     if (file)
04114         ret = ProcessFile(ctx, file, SSL_FILETYPE_PEM, CA_TYPE, NULL, 0, NULL);
04115 
04116     if (ret == SSL_SUCCESS && path) {
04117         /* try to load each regular file in path */
04118     #ifdef USE_WINDOWS_API
04119         WIN32_FIND_DATAA FindFileData;
04120         HANDLE hFind;
04121     #ifdef WOLFSSL_SMALL_STACK
04122         char*  name = NULL;
04123     #else
04124         char   name[MAX_FILENAME_SZ];
04125     #endif
04126 
04127     #ifdef WOLFSSL_SMALL_STACK
04128         name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04129         if (name == NULL)
04130             return MEMORY_E;
04131     #endif
04132 
04133         XMEMSET(name, 0, MAX_FILENAME_SZ);
04134         XSTRNCPY(name, path, MAX_FILENAME_SZ - 4);
04135         XSTRNCAT(name, "\\*", 3);
04136 
04137         hFind = FindFirstFileA(name, &FindFileData);
04138         if (hFind == INVALID_HANDLE_VALUE) {
04139             WOLFSSL_MSG("FindFirstFile for path verify locations failed");
04140         #ifdef WOLFSSL_SMALL_STACK
04141             XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04142         #endif
04143             return BAD_PATH_ERROR;
04144         }
04145 
04146         do {
04147             if (FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
04148                 XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 3);
04149                 XSTRNCAT(name, "\\", 2);
04150                 XSTRNCAT(name, FindFileData.cFileName, MAX_FILENAME_SZ/2);
04151 
04152                 ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE,
04153                                   NULL, 0, NULL);
04154             }
04155         } while (ret == SSL_SUCCESS && FindNextFileA(hFind, &FindFileData));
04156 
04157     #ifdef WOLFSSL_SMALL_STACK
04158         XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04159     #endif
04160 
04161         FindClose(hFind);
04162     #elif !defined(NO_WOLFSSL_DIR)
04163         struct dirent* entry;
04164         DIR*   dir = opendir(path);
04165     #ifdef WOLFSSL_SMALL_STACK
04166         char*  name = NULL;
04167     #else
04168         char   name[MAX_FILENAME_SZ];
04169     #endif
04170 
04171         if (dir == NULL) {
04172             WOLFSSL_MSG("opendir path verify locations failed");
04173             return BAD_PATH_ERROR;
04174         }
04175 
04176     #ifdef WOLFSSL_SMALL_STACK
04177         name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04178         if (name == NULL) {
04179             closedir(dir);
04180             return MEMORY_E;
04181         }
04182     #endif
04183 
04184         while ( ret == SSL_SUCCESS && (entry = readdir(dir)) != NULL) {
04185             struct stat s;
04186 
04187             XMEMSET(name, 0, MAX_FILENAME_SZ);
04188             XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
04189             XSTRNCAT(name, "/", 1);
04190             XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
04191 
04192             if (stat(name, &s) != 0) {
04193                 WOLFSSL_MSG("stat on name failed");
04194                 ret = BAD_PATH_ERROR;
04195             } else if (s.st_mode & S_IFREG)
04196                 ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE,
04197                                   NULL, 0, NULL);
04198         }
04199 
04200     #ifdef WOLFSSL_SMALL_STACK
04201         XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04202     #endif
04203 
04204         closedir(dir);
04205     #endif
04206     }
04207 
04208     return ret;
04209 }
04210 
04211 
04212 #ifdef WOLFSSL_TRUST_PEER_CERT
04213 /* Used to specify a peer cert to match when connecting
04214     ctx : the ctx structure to load in peer cert
04215     file: the string name of cert file
04216     type: type of format such as PEM/DER
04217  */
04218 int wolfSSL_CTX_trust_peer_cert(WOLFSSL_CTX* ctx, const char* file, int type)
04219 {
04220     WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_cert");
04221 
04222     if (ctx == NULL || file == NULL) {
04223         return SSL_FAILURE;
04224     }
04225 
04226     return ProcessFile(ctx, file, type, TRUSTED_PEER_TYPE, NULL, 0, NULL);
04227 }
04228 #endif /* WOLFSSL_TRUST_PEER_CERT */
04229 
04230 
04231 /* Verify the certificate, SSL_SUCCESS for ok, < 0 for error */
04232 int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* fname,
04233                              int format)
04234 {
04235     int    ret = SSL_FATAL_ERROR;
04236 #ifdef WOLFSSL_SMALL_STACK
04237     byte   staticBuffer[1]; /* force heap usage */
04238 #else
04239     byte   staticBuffer[FILE_BUFFER_SIZE];
04240 #endif
04241     byte*  myBuffer = staticBuffer;
04242     int    dynamic = 0;
04243     long   sz = 0;
04244     XFILE  file = XFOPEN(fname, "rb");
04245 
04246     WOLFSSL_ENTER("wolfSSL_CertManagerVerify");
04247 
04248     if (file == XBADFILE) return SSL_BAD_FILE;
04249     XFSEEK(file, 0, XSEEK_END);
04250     sz = XFTELL(file);
04251     XREWIND(file);
04252 
04253     if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
04254         WOLFSSL_MSG("CertManagerVerify file bad size");
04255         XFCLOSE(file);
04256         return SSL_BAD_FILE;
04257     }
04258 
04259     if (sz > (long)sizeof(staticBuffer)) {
04260         WOLFSSL_MSG("Getting dynamic buffer");
04261         myBuffer = (byte*) XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE);
04262         if (myBuffer == NULL) {
04263             XFCLOSE(file);
04264             return SSL_BAD_FILE;
04265         }
04266         dynamic = 1;
04267     }
04268 
04269     if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
04270         ret = SSL_BAD_FILE;
04271     else
04272         ret = wolfSSL_CertManagerVerifyBuffer(cm, myBuffer, sz, format);
04273 
04274     XFCLOSE(file);
04275     if (dynamic)
04276         XFREE(myBuffer, cm->heap, DYNAMIC_TYPE_FILE);
04277 
04278     return ret;
04279 }
04280 
04281 
04282 /* like load verify locations, 1 for success, < 0 for error */
04283 int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* file,
04284                              const char* path)
04285 {
04286     int ret = SSL_FATAL_ERROR;
04287     WOLFSSL_CTX* tmp;
04288 
04289     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCA");
04290 
04291     if (cm == NULL) {
04292         WOLFSSL_MSG("No CertManager error");
04293         return ret;
04294     }
04295     tmp = wolfSSL_CTX_new(cm_pick_method());
04296 
04297     if (tmp == NULL) {
04298         WOLFSSL_MSG("CTX new failed");
04299         return ret;
04300     }
04301 
04302     /* for tmp use */
04303     wolfSSL_CertManagerFree(tmp->cm);
04304     tmp->cm = cm;
04305 
04306     ret = wolfSSL_CTX_load_verify_locations(tmp, file, path);
04307 
04308     /* don't loose our good one */
04309     tmp->cm = NULL;
04310     wolfSSL_CTX_free(tmp);
04311 
04312     return ret;
04313 }
04314 
04315 
04316 
04317 
04318 int wolfSSL_CTX_check_private_key(WOLFSSL_CTX* ctx)
04319 {
04320     /* TODO: check private against public for RSA match */
04321     (void)ctx;
04322     WOLFSSL_ENTER("SSL_CTX_check_private_key");
04323     return SSL_SUCCESS;
04324 }
04325 
04326 
04327 #ifdef HAVE_CRL
04328 
04329 
04330 /* check CRL if enabled, SSL_SUCCESS  */
04331 int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
04332 {
04333     int ret = 0;
04334 #ifdef WOLFSSL_SMALL_STACK
04335     DecodedCert* cert = NULL;
04336 #else
04337     DecodedCert  cert[1];
04338 #endif
04339 
04340     WOLFSSL_ENTER("wolfSSL_CertManagerCheckCRL");
04341 
04342     if (cm == NULL)
04343         return BAD_FUNC_ARG;
04344 
04345     if (cm->crlEnabled == 0)
04346         return SSL_SUCCESS;
04347 
04348 #ifdef WOLFSSL_SMALL_STACK
04349     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
04350                                  DYNAMIC_TYPE_TMP_BUFFER);
04351     if (cert == NULL)
04352         return MEMORY_E;
04353 #endif
04354 
04355     InitDecodedCert(cert, der, sz, NULL);
04356 
04357     if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, cm)) != 0) {
04358         WOLFSSL_MSG("ParseCert failed");
04359     }
04360     else if ((ret = CheckCertCRL(cm->crl, cert)) != 0) {
04361         WOLFSSL_MSG("CheckCertCRL failed");
04362     }
04363 
04364     FreeDecodedCert(cert);
04365 #ifdef WOLFSSL_SMALL_STACK
04366     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04367 #endif
04368 
04369     return ret == 0 ? SSL_SUCCESS : ret;
04370 }
04371 
04372 
04373 int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, CbMissingCRL cb)
04374 {
04375     WOLFSSL_ENTER("wolfSSL_CertManagerSetCRL_Cb");
04376     if (cm == NULL)
04377         return BAD_FUNC_ARG;
04378 
04379     cm->cbMissingCRL = cb;
04380 
04381     return SSL_SUCCESS;
04382 }
04383 
04384 
04385 int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER* cm, const char* path,
04386                               int type, int monitor)
04387 {
04388     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRL");
04389     if (cm == NULL)
04390         return BAD_FUNC_ARG;
04391 
04392     if (cm->crl == NULL) {
04393         if (wolfSSL_CertManagerEnableCRL(cm, 0) != SSL_SUCCESS) {
04394             WOLFSSL_MSG("Enable CRL failed");
04395             return SSL_FATAL_ERROR;
04396         }
04397     }
04398 
04399     return LoadCRL(cm->crl, path, type, monitor);
04400 }
04401 
04402 
04403 int wolfSSL_EnableCRL(WOLFSSL* ssl, int options)
04404 {
04405     WOLFSSL_ENTER("wolfSSL_EnableCRL");
04406     if (ssl)
04407         return wolfSSL_CertManagerEnableCRL(ssl->ctx->cm, options);
04408     else
04409         return BAD_FUNC_ARG;
04410 }
04411 
04412 
04413 int wolfSSL_DisableCRL(WOLFSSL* ssl)
04414 {
04415     WOLFSSL_ENTER("wolfSSL_DisableCRL");
04416     if (ssl)
04417         return wolfSSL_CertManagerDisableCRL(ssl->ctx->cm);
04418     else
04419         return BAD_FUNC_ARG;
04420 }
04421 
04422 
04423 int wolfSSL_LoadCRL(WOLFSSL* ssl, const char* path, int type, int monitor)
04424 {
04425     WOLFSSL_ENTER("wolfSSL_LoadCRL");
04426     if (ssl)
04427         return wolfSSL_CertManagerLoadCRL(ssl->ctx->cm, path, type, monitor);
04428     else
04429         return BAD_FUNC_ARG;
04430 }
04431 
04432 
04433 int wolfSSL_SetCRL_Cb(WOLFSSL* ssl, CbMissingCRL cb)
04434 {
04435     WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
04436     if (ssl)
04437         return wolfSSL_CertManagerSetCRL_Cb(ssl->ctx->cm, cb);
04438     else
04439         return BAD_FUNC_ARG;
04440 }
04441 
04442 
04443 int wolfSSL_CTX_EnableCRL(WOLFSSL_CTX* ctx, int options)
04444 {
04445     WOLFSSL_ENTER("wolfSSL_CTX_EnableCRL");
04446     if (ctx)
04447         return wolfSSL_CertManagerEnableCRL(ctx->cm, options);
04448     else
04449         return BAD_FUNC_ARG;
04450 }
04451 
04452 
04453 int wolfSSL_CTX_DisableCRL(WOLFSSL_CTX* ctx)
04454 {
04455     WOLFSSL_ENTER("wolfSSL_CTX_DisableCRL");
04456     if (ctx)
04457         return wolfSSL_CertManagerDisableCRL(ctx->cm);
04458     else
04459         return BAD_FUNC_ARG;
04460 }
04461 
04462 
04463 int wolfSSL_CTX_LoadCRL(WOLFSSL_CTX* ctx, const char* path,
04464                         int type, int monitor)
04465 {
04466     WOLFSSL_ENTER("wolfSSL_CTX_LoadCRL");
04467     if (ctx)
04468         return wolfSSL_CertManagerLoadCRL(ctx->cm, path, type, monitor);
04469     else
04470         return BAD_FUNC_ARG;
04471 }
04472 
04473 
04474 int wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX* ctx, CbMissingCRL cb)
04475 {
04476     WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_Cb");
04477     if (ctx)
04478         return wolfSSL_CertManagerSetCRL_Cb(ctx->cm, cb);
04479     else
04480         return BAD_FUNC_ARG;
04481 }
04482 
04483 
04484 #endif /* HAVE_CRL */
04485 
04486 
04487 #ifdef WOLFSSL_DER_LOAD
04488 
04489 /* Add format parameter to allow DER load of CA files */
04490 int wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
04491                                           int format)
04492 {
04493     WOLFSSL_ENTER("wolfSSL_CTX_der_load_verify_locations");
04494     if (ctx == NULL || file == NULL)
04495         return SSL_FAILURE;
04496 
04497     if (ProcessFile(ctx, file, format, CA_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
04498         return SSL_SUCCESS;
04499 
04500     return SSL_FAILURE;
04501 }
04502 
04503 #endif /* WOLFSSL_DER_LOAD */
04504 
04505 
04506 #ifdef WOLFSSL_CERT_GEN
04507 
04508 /* load pem cert from file into der buffer, return der size or error */
04509 int wolfSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
04510 {
04511 #ifdef WOLFSSL_SMALL_STACK
04512     EncryptedInfo* info = NULL;
04513     byte   staticBuffer[1]; /* force XMALLOC */
04514 #else
04515     EncryptedInfo info[1];
04516     byte   staticBuffer[FILE_BUFFER_SIZE];
04517 #endif
04518     byte*  fileBuf = staticBuffer;
04519     int    dynamic = 0;
04520     int    ret     = 0;
04521     int    ecc     = 0;
04522     long   sz      = 0;
04523     XFILE  file    = XFOPEN(fileName, "rb");
04524     DerBuffer* converted = NULL;
04525 
04526     WOLFSSL_ENTER("wolfSSL_PemCertToDer");
04527 
04528     if (file == XBADFILE) {
04529         ret = SSL_BAD_FILE;
04530     }
04531     else {
04532         XFSEEK(file, 0, XSEEK_END);
04533         sz = XFTELL(file);
04534         XREWIND(file);
04535 
04536         if (sz < 0) {
04537             ret = SSL_BAD_FILE;
04538         }
04539         else if (sz > (long)sizeof(staticBuffer)) {
04540             fileBuf = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
04541             if (fileBuf == NULL)
04542                 ret = MEMORY_E;
04543             else
04544                 dynamic = 1;
04545         }
04546         
04547         if (ret == 0) {
04548             if ( (ret = (int)XFREAD(fileBuf, sz, 1, file)) < 0) {
04549                 ret = SSL_BAD_FILE;
04550             }
04551             else {
04552             #ifdef WOLFSSL_SMALL_STACK
04553                 info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
04554                                                DYNAMIC_TYPE_TMP_BUFFER);
04555                 if (info == NULL)
04556                     ret = MEMORY_E;
04557                 else
04558             #endif
04559                 {
04560                     ret = PemToDer(fileBuf, sz, CA_TYPE, &converted,
04561                                    0, info, &ecc);
04562                 #ifdef WOLFSSL_SMALL_STACK
04563                     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04564                 #endif
04565                 }
04566             }
04567 
04568             if (ret == 0) {
04569                 if (converted->length < (word32)derSz) {
04570                     XMEMCPY(derBuf, converted->buffer, converted->length);
04571                     ret = converted->length;
04572                 }
04573                 else
04574                     ret = BUFFER_E;
04575             }
04576 
04577             FreeDer(&converted);
04578         }
04579 
04580         XFCLOSE(file);
04581         if (dynamic)
04582             XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE);
04583     }
04584 
04585     return ret;
04586 }
04587 
04588 #endif /* WOLFSSL_CERT_GEN */
04589 
04590 #ifdef WOLFSSL_CERT_EXT
04591 #ifndef NO_FILESYSTEM
04592 /* load pem public key from file into der buffer, return der size or error */
04593 int wolfSSL_PemPubKeyToDer(const char* fileName,
04594                            unsigned char* derBuf, int derSz)
04595 {
04596 #ifdef WOLFSSL_SMALL_STACK
04597     byte   staticBuffer[1]; /* force XMALLOC */
04598 #else
04599     byte   staticBuffer[FILE_BUFFER_SIZE];
04600 #endif
04601     byte*  fileBuf = staticBuffer;
04602     int    dynamic = 0;
04603     int    ret     = 0;
04604     long   sz      = 0;
04605     XFILE  file    = XFOPEN(fileName, "rb");
04606     DerBuffer* converted = NULL;
04607 
04608     WOLFSSL_ENTER("wolfSSL_PemPubKeyToDer");
04609 
04610     if (file == XBADFILE) {
04611         ret = SSL_BAD_FILE;
04612     }
04613     else {
04614         XFSEEK(file, 0, XSEEK_END);
04615         sz = XFTELL(file);
04616         XREWIND(file);
04617 
04618         if (sz < 0) {
04619             ret = SSL_BAD_FILE;
04620         }
04621         else if (sz > (long)sizeof(staticBuffer)) {
04622             fileBuf = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
04623             if (fileBuf == NULL)
04624                 ret = MEMORY_E;
04625             else
04626                 dynamic = 1;
04627         }
04628         if (ret == 0) {
04629             if ( (ret = (int)XFREAD(fileBuf, sz, 1, file)) < 0)
04630                 ret = SSL_BAD_FILE;
04631             else
04632                 ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, &converted,
04633                                0, NULL, NULL);
04634 
04635             if (ret == 0) {
04636                 if (converted->length < (word32)derSz) {
04637                     XMEMCPY(derBuf, converted->buffer, converted->length);
04638                     ret = converted->length;
04639                 }
04640                 else
04641                     ret = BUFFER_E;
04642             }
04643 
04644             FreeDer(&converted);
04645         }
04646 
04647         XFCLOSE(file);
04648         if (dynamic)
04649             XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE);
04650     }
04651 
04652     return ret;
04653 }
04654 #endif /* NO_FILESYSTEM */
04655 
04656 /* Return bytes written to buff or < 0 for error */
04657 int wolfSSL_PubKeyPemToDer(const unsigned char* pem, int pemSz,
04658                            unsigned char* buff, int buffSz)
04659 {
04660     int ret;
04661     DerBuffer* der = NULL;
04662 
04663     WOLFSSL_ENTER("wolfSSL_PubKeyPemToDer");
04664 
04665     if (pem == NULL || buff == NULL || buffSz <= 0) {
04666         WOLFSSL_MSG("Bad pem der args");
04667         return BAD_FUNC_ARG;
04668     }
04669 
04670     ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, NULL);
04671     if (ret < 0) {
04672         WOLFSSL_MSG("Bad Pem To Der");
04673     }
04674     else {
04675         if (der->length <= (word32)buffSz) {
04676             XMEMCPY(buff, der->buffer, der->length);
04677             ret = der->length;
04678         }
04679         else {
04680             WOLFSSL_MSG("Bad der length");
04681             ret = BAD_FUNC_ARG;
04682         }
04683     }
04684 
04685     FreeDer(&der);
04686     return ret;
04687 }
04688 
04689 #endif /* WOLFSSL_CERT_EXT */
04690 
04691 int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
04692                                      int format)
04693 {
04694     WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_file");
04695     if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
04696         return SSL_SUCCESS;
04697 
04698     return SSL_FAILURE;
04699 }
04700 
04701 
04702 int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX* ctx, const char* file,
04703                                     int format)
04704 {
04705     WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_file");
04706     if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL)
04707                     == SSL_SUCCESS)
04708         return SSL_SUCCESS;
04709 
04710     return SSL_FAILURE;
04711 }
04712 
04713 
04714 /* get cert chaining depth using ssl struct */
04715 long wolfSSL_get_verify_depth(WOLFSSL* ssl)
04716 {
04717     if(ssl == NULL) {
04718         return BAD_FUNC_ARG;
04719     }
04720     return MAX_CHAIN_DEPTH;
04721 }
04722 
04723 
04724 /* get cert chaining depth using ctx struct */
04725 long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx)
04726 {
04727     if(ctx == NULL) {
04728         return BAD_FUNC_ARG;
04729     }
04730     return MAX_CHAIN_DEPTH;
04731 }
04732 
04733 
04734 int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX* ctx, const char* file)
04735 {
04736    /* process up to MAX_CHAIN_DEPTH plus subject cert */
04737    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file");
04738    if (ProcessFile(ctx, file, SSL_FILETYPE_PEM,CERT_TYPE,NULL,1, NULL)
04739                    == SSL_SUCCESS)
04740        return SSL_SUCCESS;
04741 
04742    return SSL_FAILURE;
04743 }
04744 
04745 
04746 #ifndef NO_DH
04747 
04748 /* server Diffie-Hellman parameters */
04749 static int wolfSSL_SetTmpDH_file_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
04750                                         const char* fname, int format)
04751 {
04752 #ifdef WOLFSSL_SMALL_STACK
04753     byte   staticBuffer[1]; /* force heap usage */
04754 #else
04755     byte   staticBuffer[FILE_BUFFER_SIZE];
04756 #endif
04757     byte*  myBuffer = staticBuffer;
04758     int    dynamic = 0;
04759     int    ret;
04760     long   sz = 0;
04761     XFILE  file;
04762 
04763     if (ctx == NULL || fname == NULL)
04764         return BAD_FUNC_ARG;
04765 
04766     file = XFOPEN(fname, "rb");
04767     if (file == XBADFILE) return SSL_BAD_FILE;
04768     XFSEEK(file, 0, XSEEK_END);
04769     sz = XFTELL(file);
04770     XREWIND(file);
04771 
04772     if (sz > (long)sizeof(staticBuffer)) {
04773         WOLFSSL_MSG("Getting dynamic buffer");
04774         myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
04775         if (myBuffer == NULL) {
04776             XFCLOSE(file);
04777             return SSL_BAD_FILE;
04778         }
04779         dynamic = 1;
04780     }
04781     else if (sz < 0) {
04782         XFCLOSE(file);
04783         return SSL_BAD_FILE;
04784     }
04785 
04786     if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
04787         ret = SSL_BAD_FILE;
04788     else {
04789         if (ssl)
04790             ret = wolfSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format);
04791         else
04792             ret = wolfSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format);
04793     }
04794 
04795     XFCLOSE(file);
04796     if (dynamic)
04797         XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
04798 
04799     return ret;
04800 }
04801 
04802 /* server Diffie-Hellman parameters */
04803 int wolfSSL_SetTmpDH_file(WOLFSSL* ssl, const char* fname, int format)
04804 {
04805     if (ssl == NULL)
04806         return BAD_FUNC_ARG;
04807 
04808     return wolfSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format);
04809 }
04810 
04811 
04812 /* server Diffie-Hellman parameters */
04813 int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format)
04814 {
04815     return wolfSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format);
04816 }
04817 
04818 #endif /* NO_DH */
04819 
04820 
04821 #ifdef OPENSSL_EXTRA
04822 /* put SSL type in extra for now, not very common */
04823 
04824 int wolfSSL_use_certificate_file(WOLFSSL* ssl, const char* file, int format)
04825 {
04826     WOLFSSL_ENTER("wolfSSL_use_certificate_file");
04827     if (ProcessFile(ssl->ctx, file, format, CERT_TYPE,
04828                     ssl, 0, NULL) == SSL_SUCCESS)
04829         return SSL_SUCCESS;
04830 
04831     return SSL_FAILURE;
04832 }
04833 
04834 
04835 int wolfSSL_use_PrivateKey_file(WOLFSSL* ssl, const char* file, int format)
04836 {
04837     WOLFSSL_ENTER("wolfSSL_use_PrivateKey_file");
04838     if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE,
04839                     ssl, 0, NULL) == SSL_SUCCESS)
04840         return SSL_SUCCESS;
04841 
04842     return SSL_FAILURE;
04843 }
04844 
04845 
04846 int wolfSSL_use_certificate_chain_file(WOLFSSL* ssl, const char* file)
04847 {
04848    /* process up to MAX_CHAIN_DEPTH plus subject cert */
04849    WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file");
04850    if (ProcessFile(ssl->ctx, file, SSL_FILETYPE_PEM, CERT_TYPE,
04851                    ssl, 1, NULL) == SSL_SUCCESS)
04852        return SSL_SUCCESS;
04853 
04854    return SSL_FAILURE;
04855 }
04856 
04857 
04858 
04859 #ifdef HAVE_ECC
04860 
04861 /* Set Temp CTX EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
04862 int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX* ctx, word16 sz)
04863 {
04864     if (ctx == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
04865         return BAD_FUNC_ARG;
04866 
04867     ctx->eccTempKeySz = sz;
04868 
04869     return SSL_SUCCESS;
04870 }
04871 
04872 
04873 /* Set Temp SSL EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
04874 int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL* ssl, word16 sz)
04875 {
04876     if (ssl == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
04877         return BAD_FUNC_ARG;
04878 
04879     ssl->eccTempKeySz = sz;
04880 
04881     return SSL_SUCCESS;
04882 }
04883 
04884 #endif /* HAVE_ECC */
04885 
04886 
04887 
04888 
04889 int wolfSSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX* ctx,const char* file,
04890                                    int format)
04891 {
04892     WOLFSSL_ENTER("SSL_CTX_use_RSAPrivateKey_file");
04893 
04894     return wolfSSL_CTX_use_PrivateKey_file(ctx, file, format);
04895 }
04896 
04897 
04898 int wolfSSL_use_RSAPrivateKey_file(WOLFSSL* ssl, const char* file, int format)
04899 {
04900     WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_file");
04901 
04902     return wolfSSL_use_PrivateKey_file(ssl, file, format);
04903 }
04904 
04905 #endif /* OPENSSL_EXTRA */
04906 
04907 #ifdef HAVE_NTRU
04908 
04909 int wolfSSL_CTX_use_NTRUPrivateKey_file(WOLFSSL_CTX* ctx, const char* file)
04910 {
04911     WOLFSSL_ENTER("wolfSSL_CTX_use_NTRUPrivateKey_file");
04912     if (ctx == NULL)
04913         return SSL_FAILURE;
04914 
04915     if (ProcessFile(ctx, file, SSL_FILETYPE_RAW, PRIVATEKEY_TYPE, NULL, 0, NULL)
04916                          == SSL_SUCCESS) {
04917         ctx->haveNTRU = 1;
04918         return SSL_SUCCESS;
04919     }
04920 
04921     return SSL_FAILURE;
04922 }
04923 
04924 #endif /* HAVE_NTRU */
04925 
04926 
04927 #endif /* NO_FILESYSTEM */
04928 
04929 
04930 void wolfSSL_CTX_set_verify(WOLFSSL_CTX* ctx, int mode, VerifyCallback vc)
04931 {
04932     WOLFSSL_ENTER("wolfSSL_CTX_set_verify");
04933     if (mode & SSL_VERIFY_PEER) {
04934         ctx->verifyPeer = 1;
04935         ctx->verifyNone = 0;  /* in case previously set */
04936     }
04937 
04938     if (mode == SSL_VERIFY_NONE) {
04939         ctx->verifyNone = 1;
04940         ctx->verifyPeer = 0;  /* in case previously set */
04941     }
04942 
04943     if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
04944         ctx->failNoCert = 1;
04945 
04946     if (mode & SSL_VERIFY_FAIL_EXCEPT_PSK) {
04947         ctx->failNoCert    = 0; /* fail on all is set to fail on PSK */
04948         ctx->failNoCertxPSK = 1;
04949     }
04950 
04951     ctx->verifyCallback = vc;
04952 }
04953 
04954 
04955 void wolfSSL_set_verify(WOLFSSL* ssl, int mode, VerifyCallback vc)
04956 {
04957     WOLFSSL_ENTER("wolfSSL_set_verify");
04958     if (mode & SSL_VERIFY_PEER) {
04959         ssl->options.verifyPeer = 1;
04960         ssl->options.verifyNone = 0;  /* in case previously set */
04961     }
04962 
04963     if (mode == SSL_VERIFY_NONE) {
04964         ssl->options.verifyNone = 1;
04965         ssl->options.verifyPeer = 0;  /* in case previously set */
04966     }
04967 
04968     if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
04969         ssl->options.failNoCert = 1;
04970 
04971     if (mode & SSL_VERIFY_FAIL_EXCEPT_PSK) {
04972         ssl->options.failNoCert    = 0; /* fail on all is set to fail on PSK */
04973         ssl->options.failNoCertxPSK = 1;
04974     }
04975 
04976     ssl->verifyCallback = vc;
04977 }
04978 
04979 
04980 /* store user ctx for verify callback */
04981 void wolfSSL_SetCertCbCtx(WOLFSSL* ssl, void* ctx)
04982 {
04983     WOLFSSL_ENTER("wolfSSL_SetCertCbCtx");
04984     if (ssl)
04985         ssl->verifyCbCtx = ctx;
04986 }
04987 
04988 
04989 /* store context CA Cache addition callback */
04990 void wolfSSL_CTX_SetCACb(WOLFSSL_CTX* ctx, CallbackCACache cb)
04991 {
04992     if (ctx && ctx->cm)
04993         ctx->cm->caCacheCallback = cb;
04994 }
04995 
04996 
04997 #if defined(PERSIST_CERT_CACHE)
04998 
04999 #if !defined(NO_FILESYSTEM)
05000 
05001 /* Persist cert cache to file */
05002 int wolfSSL_CTX_save_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
05003 {
05004     WOLFSSL_ENTER("wolfSSL_CTX_save_cert_cache");
05005 
05006     if (ctx == NULL || fname == NULL)
05007         return BAD_FUNC_ARG;
05008 
05009     return CM_SaveCertCache(ctx->cm, fname);
05010 }
05011 
05012 
05013 /* Persist cert cache from file */
05014 int wolfSSL_CTX_restore_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
05015 {
05016     WOLFSSL_ENTER("wolfSSL_CTX_restore_cert_cache");
05017 
05018     if (ctx == NULL || fname == NULL)
05019         return BAD_FUNC_ARG;
05020 
05021     return CM_RestoreCertCache(ctx->cm, fname);
05022 }
05023 
05024 #endif /* NO_FILESYSTEM */
05025 
05026 /* Persist cert cache to memory */
05027 int wolfSSL_CTX_memsave_cert_cache(WOLFSSL_CTX* ctx, void* mem,
05028                                    int sz, int* used)
05029 {
05030     WOLFSSL_ENTER("wolfSSL_CTX_memsave_cert_cache");
05031 
05032     if (ctx == NULL || mem == NULL || used == NULL || sz <= 0)
05033         return BAD_FUNC_ARG;
05034 
05035     return CM_MemSaveCertCache(ctx->cm, mem, sz, used);
05036 }
05037 
05038 
05039 /* Restore cert cache from memory */
05040 int wolfSSL_CTX_memrestore_cert_cache(WOLFSSL_CTX* ctx, const void* mem, int sz)
05041 {
05042     WOLFSSL_ENTER("wolfSSL_CTX_memrestore_cert_cache");
05043 
05044     if (ctx == NULL || mem == NULL || sz <= 0)
05045         return BAD_FUNC_ARG;
05046 
05047     return CM_MemRestoreCertCache(ctx->cm, mem, sz);
05048 }
05049 
05050 
05051 /* get how big the the cert cache save buffer needs to be */
05052 int wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX* ctx)
05053 {
05054     WOLFSSL_ENTER("wolfSSL_CTX_get_cert_cache_memsize");
05055 
05056     if (ctx == NULL)
05057         return BAD_FUNC_ARG;
05058 
05059     return CM_GetCertCacheMemSize(ctx->cm);
05060 }
05061 
05062 #endif /* PERSISTE_CERT_CACHE */
05063 #endif /* !NO_CERTS */
05064 
05065 
05066 #ifndef NO_SESSION_CACHE
05067 
05068 WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl)
05069 {
05070     WOLFSSL_ENTER("SSL_get_session");
05071     if (ssl)
05072         return GetSession(ssl, 0);
05073 
05074     return NULL;
05075 }
05076 
05077 
05078 int wolfSSL_set_session(WOLFSSL* ssl, WOLFSSL_SESSION* session)
05079 {
05080     WOLFSSL_ENTER("SSL_set_session");
05081     if (session)
05082         return SetSession(ssl, session);
05083 
05084     return SSL_FAILURE;
05085 }
05086 
05087 
05088 #ifndef NO_CLIENT_CACHE
05089 
05090 /* Associate client session with serverID, find existing or store for saving
05091    if newSession flag on, don't reuse existing session
05092    SSL_SUCCESS on ok */
05093 int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
05094 {
05095     WOLFSSL_SESSION* session = NULL;
05096 
05097     WOLFSSL_ENTER("wolfSSL_SetServerID");
05098 
05099     if (ssl == NULL || id == NULL || len <= 0)
05100         return BAD_FUNC_ARG;
05101 
05102     if (newSession == 0) {
05103         session = GetSessionClient(ssl, id, len);
05104         if (session) {
05105             if (SetSession(ssl, session) != SSL_SUCCESS) {
05106                 WOLFSSL_MSG("SetSession failed");
05107                 session = NULL;
05108             }
05109         }
05110     }
05111 
05112     if (session == NULL) {
05113         WOLFSSL_MSG("Valid ServerID not cached already");
05114 
05115         ssl->session.idLen = (word16)min(SERVER_ID_LEN, (word32)len);
05116         XMEMCPY(ssl->session.serverID, id, ssl->session.idLen);
05117     }
05118 
05119     return SSL_SUCCESS;
05120 }
05121 
05122 #endif /* NO_CLIENT_CACHE */
05123 
05124 #if defined(PERSIST_SESSION_CACHE)
05125 
05126 /* for persistence, if changes to layout need to increment and modify
05127    save_session_cache() and restore_session_cache and memory versions too */
05128 #define WOLFSSL_CACHE_VERSION 2
05129 
05130 /* Session Cache Header information */
05131 typedef struct {
05132     int version;     /* cache layout version id */
05133     int rows;        /* session rows */
05134     int columns;     /* session columns */
05135     int sessionSz;   /* sizeof WOLFSSL_SESSION */
05136 } cache_header_t;
05137 
05138 /* current persistence layout is:
05139 
05140    1) cache_header_t
05141    2) SessionCache
05142    3) ClientCache
05143 
05144    update WOLFSSL_CACHE_VERSION if change layout for the following
05145    PERSISTENT_SESSION_CACHE functions
05146 */
05147 
05148 
05149 /* get how big the the session cache save buffer needs to be */
05150 int wolfSSL_get_session_cache_memsize(void)
05151 {
05152     int sz  = (int)(sizeof(SessionCache) + sizeof(cache_header_t));
05153 
05154     #ifndef NO_CLIENT_CACHE
05155         sz += (int)(sizeof(ClientCache));
05156     #endif
05157 
05158     return sz;
05159 }
05160 
05161 
05162 /* Persist session cache to memory */
05163 int wolfSSL_memsave_session_cache(void* mem, int sz)
05164 {
05165     int i;
05166     cache_header_t cache_header;
05167     SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
05168 #ifndef NO_CLIENT_CACHE
05169     ClientRow*     clRow;
05170 #endif
05171 
05172     WOLFSSL_ENTER("wolfSSL_memsave_session_cache");
05173 
05174     if (sz < wolfSSL_get_session_cache_memsize()) {
05175         WOLFSSL_MSG("Memory buffer too small");
05176         return BUFFER_E;
05177     }
05178 
05179     cache_header.version   = WOLFSSL_CACHE_VERSION;
05180     cache_header.rows      = SESSION_ROWS;
05181     cache_header.columns   = SESSIONS_PER_ROW;
05182     cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
05183     XMEMCPY(mem, &cache_header, sizeof(cache_header));
05184 
05185     if (LockMutex(&session_mutex) != 0) {
05186         WOLFSSL_MSG("Session cache mutex lock failed");
05187         return BAD_MUTEX_E;
05188     }
05189 
05190     for (i = 0; i < cache_header.rows; ++i)
05191         XMEMCPY(row++, SessionCache + i, sizeof(SessionRow));
05192 
05193 #ifndef NO_CLIENT_CACHE
05194     clRow = (ClientRow*)row;
05195     for (i = 0; i < cache_header.rows; ++i)
05196         XMEMCPY(clRow++, ClientCache + i, sizeof(ClientRow));
05197 #endif
05198 
05199     UnLockMutex(&session_mutex);
05200 
05201     WOLFSSL_LEAVE("wolfSSL_memsave_session_cache", SSL_SUCCESS);
05202 
05203     return SSL_SUCCESS;
05204 }
05205 
05206 
05207 /* Restore the persistent session cache from memory */
05208 int wolfSSL_memrestore_session_cache(const void* mem, int sz)
05209 {
05210     int    i;
05211     cache_header_t cache_header;
05212     SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
05213 #ifndef NO_CLIENT_CACHE
05214     ClientRow*     clRow;
05215 #endif
05216 
05217     WOLFSSL_ENTER("wolfSSL_memrestore_session_cache");
05218 
05219     if (sz < wolfSSL_get_session_cache_memsize()) {
05220         WOLFSSL_MSG("Memory buffer too small");
05221         return BUFFER_E;
05222     }
05223 
05224     XMEMCPY(&cache_header, mem, sizeof(cache_header));
05225     if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
05226         cache_header.rows      != SESSION_ROWS ||
05227         cache_header.columns   != SESSIONS_PER_ROW ||
05228         cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
05229 
05230         WOLFSSL_MSG("Session cache header match failed");
05231         return CACHE_MATCH_ERROR;
05232     }
05233 
05234     if (LockMutex(&session_mutex) != 0) {
05235         WOLFSSL_MSG("Session cache mutex lock failed");
05236         return BAD_MUTEX_E;
05237     }
05238 
05239     for (i = 0; i < cache_header.rows; ++i)
05240         XMEMCPY(SessionCache + i, row++, sizeof(SessionRow));
05241 
05242 #ifndef NO_CLIENT_CACHE
05243     clRow = (ClientRow*)row;
05244     for (i = 0; i < cache_header.rows; ++i)
05245         XMEMCPY(ClientCache + i, clRow++, sizeof(ClientRow));
05246 #endif
05247 
05248     UnLockMutex(&session_mutex);
05249 
05250     WOLFSSL_LEAVE("wolfSSL_memrestore_session_cache", SSL_SUCCESS);
05251 
05252     return SSL_SUCCESS;
05253 }
05254 
05255 #if !defined(NO_FILESYSTEM)
05256 
05257 /* Persist session cache to file */
05258 /* doesn't use memsave because of additional memory use */
05259 int wolfSSL_save_session_cache(const char *fname)
05260 {
05261     XFILE  file;
05262     int    ret;
05263     int    rc = SSL_SUCCESS;
05264     int    i;
05265     cache_header_t cache_header;
05266 
05267     WOLFSSL_ENTER("wolfSSL_save_session_cache");
05268 
05269     file = XFOPEN(fname, "w+b");
05270     if (file == XBADFILE) {
05271         WOLFSSL_MSG("Couldn't open session cache save file");
05272         return SSL_BAD_FILE;
05273     }
05274     cache_header.version   = WOLFSSL_CACHE_VERSION;
05275     cache_header.rows      = SESSION_ROWS;
05276     cache_header.columns   = SESSIONS_PER_ROW;
05277     cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
05278 
05279     /* cache header */
05280     ret = (int)XFWRITE(&cache_header, sizeof cache_header, 1, file);
05281     if (ret != 1) {
05282         WOLFSSL_MSG("Session cache header file write failed");
05283         XFCLOSE(file);
05284         return FWRITE_ERROR;
05285     }
05286 
05287     if (LockMutex(&session_mutex) != 0) {
05288         WOLFSSL_MSG("Session cache mutex lock failed");
05289         XFCLOSE(file);
05290         return BAD_MUTEX_E;
05291     }
05292 
05293     /* session cache */
05294     for (i = 0; i < cache_header.rows; ++i) {
05295         ret = (int)XFWRITE(SessionCache + i, sizeof(SessionRow), 1, file);
05296         if (ret != 1) {
05297             WOLFSSL_MSG("Session cache member file write failed");
05298             rc = FWRITE_ERROR;
05299             break;
05300         }
05301     }
05302 
05303 #ifndef NO_CLIENT_CACHE
05304     /* client cache */
05305     for (i = 0; i < cache_header.rows; ++i) {
05306         ret = (int)XFWRITE(ClientCache + i, sizeof(ClientRow), 1, file);
05307         if (ret != 1) {
05308             WOLFSSL_MSG("Client cache member file write failed");
05309             rc = FWRITE_ERROR;
05310             break;
05311         }
05312     }
05313 #endif /* NO_CLIENT_CACHE */
05314 
05315     UnLockMutex(&session_mutex);
05316 
05317     XFCLOSE(file);
05318     WOLFSSL_LEAVE("wolfSSL_save_session_cache", rc);
05319 
05320     return rc;
05321 }
05322 
05323 
05324 /* Restore the persistent session cache from file */
05325 /* doesn't use memstore because of additional memory use */
05326 int wolfSSL_restore_session_cache(const char *fname)
05327 {
05328     XFILE  file;
05329     int    rc = SSL_SUCCESS;
05330     int    ret;
05331     int    i;
05332     cache_header_t cache_header;
05333 
05334     WOLFSSL_ENTER("wolfSSL_restore_session_cache");
05335 
05336     file = XFOPEN(fname, "rb");
05337     if (file == XBADFILE) {
05338         WOLFSSL_MSG("Couldn't open session cache save file");
05339         return SSL_BAD_FILE;
05340     }
05341     /* cache header */
05342     ret = (int)XFREAD(&cache_header, sizeof cache_header, 1, file);
05343     if (ret != 1) {
05344         WOLFSSL_MSG("Session cache header file read failed");
05345         XFCLOSE(file);
05346         return FREAD_ERROR;
05347     }
05348     if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
05349         cache_header.rows      != SESSION_ROWS ||
05350         cache_header.columns   != SESSIONS_PER_ROW ||
05351         cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
05352 
05353         WOLFSSL_MSG("Session cache header match failed");
05354         XFCLOSE(file);
05355         return CACHE_MATCH_ERROR;
05356     }
05357 
05358     if (LockMutex(&session_mutex) != 0) {
05359         WOLFSSL_MSG("Session cache mutex lock failed");
05360         XFCLOSE(file);
05361         return BAD_MUTEX_E;
05362     }
05363 
05364     /* session cache */
05365     for (i = 0; i < cache_header.rows; ++i) {
05366         ret = (int)XFREAD(SessionCache + i, sizeof(SessionRow), 1, file);
05367         if (ret != 1) {
05368             WOLFSSL_MSG("Session cache member file read failed");
05369             XMEMSET(SessionCache, 0, sizeof SessionCache);
05370             rc = FREAD_ERROR;
05371             break;
05372         }
05373     }
05374 
05375 #ifndef NO_CLIENT_CACHE
05376     /* client cache */
05377     for (i = 0; i < cache_header.rows; ++i) {
05378         ret = (int)XFREAD(ClientCache + i, sizeof(ClientRow), 1, file);
05379         if (ret != 1) {
05380             WOLFSSL_MSG("Client cache member file read failed");
05381             XMEMSET(ClientCache, 0, sizeof ClientCache);
05382             rc = FREAD_ERROR;
05383             break;
05384         }
05385     }
05386 
05387 #endif /* NO_CLIENT_CACHE */
05388 
05389     UnLockMutex(&session_mutex);
05390 
05391     XFCLOSE(file);
05392     WOLFSSL_LEAVE("wolfSSL_restore_session_cache", rc);
05393 
05394     return rc;
05395 }
05396 
05397 #endif /* !NO_FILESYSTEM */
05398 #endif /* PERSIST_SESSION_CACHE */
05399 #endif /* NO_SESSION_CACHE */
05400 
05401 
05402 void wolfSSL_load_error_strings(void)   /* compatibility only */
05403 {}
05404 
05405 
05406 int wolfSSL_library_init(void)
05407 {
05408     WOLFSSL_ENTER("SSL_library_init");
05409     if (wolfSSL_Init() == SSL_SUCCESS)
05410         return SSL_SUCCESS;
05411     else
05412         return SSL_FATAL_ERROR;
05413 }
05414 
05415 
05416 #ifdef HAVE_SECRET_CALLBACK
05417 
05418 int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx)
05419 {
05420     WOLFSSL_ENTER("wolfSSL_set_session_secret_cb");
05421     if (ssl == NULL)
05422         return SSL_FATAL_ERROR;
05423 
05424     ssl->sessionSecretCb = cb;
05425     ssl->sessionSecretCtx = ctx;
05426     /* If using a pre-set key, assume session resumption. */
05427     ssl->session.sessionIDSz = 0;
05428     ssl->options.resuming = 1;
05429 
05430     return SSL_SUCCESS;
05431 }
05432 
05433 #endif
05434 
05435 
05436 #ifndef NO_SESSION_CACHE
05437 
05438 /* on by default if built in but allow user to turn off */
05439 long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX* ctx, long mode)
05440 {
05441     WOLFSSL_ENTER("SSL_CTX_set_session_cache_mode");
05442     if (mode == SSL_SESS_CACHE_OFF)
05443         ctx->sessionCacheOff = 1;
05444 
05445     if (mode == SSL_SESS_CACHE_NO_AUTO_CLEAR)
05446         ctx->sessionCacheFlushOff = 1;
05447 
05448     return SSL_SUCCESS;
05449 }
05450 
05451 #endif /* NO_SESSION_CACHE */
05452 
05453 
05454 #if !defined(NO_CERTS)
05455 #if defined(PERSIST_CERT_CACHE)
05456 
05457 
05458 #define WOLFSSL_CACHE_CERT_VERSION 1
05459 
05460 typedef struct {
05461     int version;                 /* cache cert layout version id */
05462     int rows;                    /* hash table rows, CA_TABLE_SIZE */
05463     int columns[CA_TABLE_SIZE];  /* columns per row on list */
05464     int signerSz;                /* sizeof Signer object */
05465 } CertCacheHeader;
05466 
05467 /* current cert persistence layout is:
05468 
05469    1) CertCacheHeader
05470    2) caTable
05471 
05472    update WOLFSSL_CERT_CACHE_VERSION if change layout for the following
05473    PERSIST_CERT_CACHE functions
05474 */
05475 
05476 
05477 /* Return memory needed to persist this signer, have lock */
05478 static INLINE int GetSignerMemory(Signer* signer)
05479 {
05480     int sz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID)
05481            + sizeof(signer->nameLen)    + sizeof(signer->subjectNameHash);
05482 
05483 #if !defined(NO_SKID)
05484         sz += (int)sizeof(signer->subjectKeyIdHash);
05485 #endif
05486 
05487     /* add dynamic bytes needed */
05488     sz += signer->pubKeySize;
05489     sz += signer->nameLen;
05490 
05491     return sz;
05492 }
05493 
05494 
05495 /* Return memory needed to persist this row, have lock */
05496 static INLINE int GetCertCacheRowMemory(Signer* row)
05497 {
05498     int sz = 0;
05499 
05500     while (row) {
05501         sz += GetSignerMemory(row);
05502         row = row->next;
05503     }
05504 
05505     return sz;
05506 }
05507 
05508 
05509 /* get the size of persist cert cache, have lock */
05510 static INLINE int GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
05511 {
05512     int sz;
05513     int i;
05514 
05515     sz = sizeof(CertCacheHeader);
05516 
05517     for (i = 0; i < CA_TABLE_SIZE; i++)
05518         sz += GetCertCacheRowMemory(cm->caTable[i]);
05519 
05520     return sz;
05521 }
05522 
05523 
05524 /* Store cert cache header columns with number of items per list, have lock */
05525 static INLINE void SetCertHeaderColumns(WOLFSSL_CERT_MANAGER* cm, int* columns)
05526 {
05527     int     i;
05528     Signer* row;
05529 
05530     for (i = 0; i < CA_TABLE_SIZE; i++) {
05531         int count = 0;
05532         row = cm->caTable[i];
05533 
05534         while (row) {
05535             ++count;
05536             row = row->next;
05537         }
05538         columns[i] = count;
05539     }
05540 }
05541 
05542 
05543 /* Restore whole cert row from memory, have lock, return bytes consumed,
05544    < 0 on error, have lock */
05545 static INLINE int RestoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current,
05546                                  int row, int listSz, const byte* end)
05547 {
05548     int idx = 0;
05549 
05550     if (listSz < 0) {
05551         WOLFSSL_MSG("Row header corrupted, negative value");
05552         return PARSE_ERROR;
05553     }
05554 
05555     while (listSz) {
05556         Signer* signer;
05557         byte*   start = current + idx;  /* for end checks on this signer */
05558         int     minSz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) +
05559                       sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
05560         #ifndef NO_SKID
05561                 minSz += (int)sizeof(signer->subjectKeyIdHash);
05562         #endif
05563 
05564         if (start + minSz > end) {
05565             WOLFSSL_MSG("Would overread restore buffer");
05566             return BUFFER_E;
05567         }
05568         signer = MakeSigner(cm->heap);
05569         if (signer == NULL)
05570             return MEMORY_E;
05571 
05572         /* pubKeySize */
05573         XMEMCPY(&signer->pubKeySize, current + idx, sizeof(signer->pubKeySize));
05574         idx += (int)sizeof(signer->pubKeySize);
05575 
05576         /* keyOID */
05577         XMEMCPY(&signer->keyOID, current + idx, sizeof(signer->keyOID));
05578         idx += (int)sizeof(signer->keyOID);
05579 
05580         /* pulicKey */
05581         if (start + minSz + signer->pubKeySize > end) {
05582             WOLFSSL_MSG("Would overread restore buffer");
05583             FreeSigner(signer, cm->heap);
05584             return BUFFER_E;
05585         }
05586         signer->publicKey = (byte*)XMALLOC(signer->pubKeySize, cm->heap,
05587                                            DYNAMIC_TYPE_KEY);
05588         if (signer->publicKey == NULL) {
05589             FreeSigner(signer, cm->heap);
05590             return MEMORY_E;
05591         }
05592 
05593         XMEMCPY(signer->publicKey, current + idx, signer->pubKeySize);
05594         idx += signer->pubKeySize;
05595 
05596         /* nameLen */
05597         XMEMCPY(&signer->nameLen, current + idx, sizeof(signer->nameLen));
05598         idx += (int)sizeof(signer->nameLen);
05599 
05600         /* name */
05601         if (start + minSz + signer->pubKeySize + signer->nameLen > end) {
05602             WOLFSSL_MSG("Would overread restore buffer");
05603             FreeSigner(signer, cm->heap);
05604             return BUFFER_E;
05605         }
05606         signer->name = (char*)XMALLOC(signer->nameLen, cm->heap,
05607                                       DYNAMIC_TYPE_SUBJECT_CN);
05608         if (signer->name == NULL) {
05609             FreeSigner(signer, cm->heap);
05610             return MEMORY_E;
05611         }
05612 
05613         XMEMCPY(signer->name, current + idx, signer->nameLen);
05614         idx += signer->nameLen;
05615 
05616         /* subjectNameHash */
05617         XMEMCPY(signer->subjectNameHash, current + idx, SIGNER_DIGEST_SIZE);
05618         idx += SIGNER_DIGEST_SIZE;
05619 
05620         #ifndef NO_SKID
05621             /* subjectKeyIdHash */
05622             XMEMCPY(signer->subjectKeyIdHash, current + idx,SIGNER_DIGEST_SIZE);
05623             idx += SIGNER_DIGEST_SIZE;
05624         #endif
05625 
05626         signer->next = cm->caTable[row];
05627         cm->caTable[row] = signer;
05628 
05629         --listSz;
05630     }
05631 
05632     return idx;
05633 }
05634 
05635 
05636 /* Store whole cert row into memory, have lock, return bytes added */
05637 static INLINE int StoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current, int row)
05638 {
05639     int     added  = 0;
05640     Signer* list   = cm->caTable[row];
05641 
05642     while (list) {
05643         XMEMCPY(current + added, &list->pubKeySize, sizeof(list->pubKeySize));
05644         added += (int)sizeof(list->pubKeySize);
05645 
05646         XMEMCPY(current + added, &list->keyOID,     sizeof(list->keyOID));
05647         added += (int)sizeof(list->keyOID);
05648 
05649         XMEMCPY(current + added, list->publicKey, list->pubKeySize);
05650         added += list->pubKeySize;
05651 
05652         XMEMCPY(current + added, &list->nameLen, sizeof(list->nameLen));
05653         added += (int)sizeof(list->nameLen);
05654 
05655         XMEMCPY(current + added, list->name, list->nameLen);
05656         added += list->nameLen;
05657 
05658         XMEMCPY(current + added, list->subjectNameHash, SIGNER_DIGEST_SIZE);
05659         added += SIGNER_DIGEST_SIZE;
05660 
05661         #ifndef NO_SKID
05662             XMEMCPY(current + added, list->subjectKeyIdHash,SIGNER_DIGEST_SIZE);
05663             added += SIGNER_DIGEST_SIZE;
05664         #endif
05665 
05666         list = list->next;
05667     }
05668 
05669     return added;
05670 }
05671 
05672 
05673 /* Persist cert cache to memory, have lock */
05674 static INLINE int DoMemSaveCertCache(WOLFSSL_CERT_MANAGER* cm,
05675                                      void* mem, int sz)
05676 {
05677     int realSz;
05678     int ret = SSL_SUCCESS;
05679     int i;
05680 
05681     WOLFSSL_ENTER("DoMemSaveCertCache");
05682 
05683     realSz = GetCertCacheMemSize(cm);
05684     if (realSz > sz) {
05685         WOLFSSL_MSG("Mem output buffer too small");
05686         ret = BUFFER_E;
05687     }
05688     else {
05689         byte*           current;
05690         CertCacheHeader hdr;
05691 
05692         hdr.version  = WOLFSSL_CACHE_CERT_VERSION;
05693         hdr.rows     = CA_TABLE_SIZE;
05694         SetCertHeaderColumns(cm, hdr.columns);
05695         hdr.signerSz = (int)sizeof(Signer);
05696 
05697         XMEMCPY(mem, &hdr, sizeof(CertCacheHeader));
05698         current = (byte*)mem + sizeof(CertCacheHeader);
05699 
05700         for (i = 0; i < CA_TABLE_SIZE; ++i)
05701             current += StoreCertRow(cm, current, i);
05702     }
05703 
05704     return ret;
05705 }
05706 
05707 
05708 #if !defined(NO_FILESYSTEM)
05709 
05710 /* Persist cert cache to file */
05711 int CM_SaveCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
05712 {
05713     XFILE file;
05714     int   rc = SSL_SUCCESS;
05715     int   memSz;
05716     byte* mem;
05717 
05718     WOLFSSL_ENTER("CM_SaveCertCache");
05719 
05720     file = XFOPEN(fname, "w+b");
05721     if (file == XBADFILE) {
05722        WOLFSSL_MSG("Couldn't open cert cache save file");
05723        return SSL_BAD_FILE;
05724     }
05725 
05726     if (LockMutex(&cm->caLock) != 0) {
05727         WOLFSSL_MSG("LockMutex on caLock failed");
05728         XFCLOSE(file);
05729         return BAD_MUTEX_E;
05730     }
05731 
05732     memSz = GetCertCacheMemSize(cm);
05733     mem   = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
05734     if (mem == NULL) {
05735         WOLFSSL_MSG("Alloc for tmp buffer failed");
05736         rc = MEMORY_E;
05737     } else {
05738         rc = DoMemSaveCertCache(cm, mem, memSz);
05739         if (rc == SSL_SUCCESS) {
05740             int ret = (int)XFWRITE(mem, memSz, 1, file);
05741             if (ret != 1) {
05742                 WOLFSSL_MSG("Cert cache file write failed");
05743                 rc = FWRITE_ERROR;
05744             }
05745         }
05746         XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
05747     }
05748 
05749     UnLockMutex(&cm->caLock);
05750     XFCLOSE(file);
05751 
05752     return rc;
05753 }
05754 
05755 
05756 /* Restore cert cache from file */
05757 int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
05758 {
05759     XFILE file;
05760     int   rc = SSL_SUCCESS;
05761     int   ret;
05762     int   memSz;
05763     byte* mem;
05764 
05765     WOLFSSL_ENTER("CM_RestoreCertCache");
05766 
05767     file = XFOPEN(fname, "rb");
05768     if (file == XBADFILE) {
05769        WOLFSSL_MSG("Couldn't open cert cache save file");
05770        return SSL_BAD_FILE;
05771     }
05772 
05773     XFSEEK(file, 0, XSEEK_END);
05774     memSz = (int)XFTELL(file);
05775     XREWIND(file);
05776 
05777     if (memSz <= 0) {
05778         WOLFSSL_MSG("Bad file size");
05779         XFCLOSE(file);
05780         return SSL_BAD_FILE;
05781     }
05782 
05783     mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
05784     if (mem == NULL) {
05785         WOLFSSL_MSG("Alloc for tmp buffer failed");
05786         XFCLOSE(file);
05787         return MEMORY_E;
05788     }
05789 
05790     ret = (int)XFREAD(mem, memSz, 1, file);
05791     if (ret != 1) {
05792         WOLFSSL_MSG("Cert file read error");
05793         rc = FREAD_ERROR;
05794     } else {
05795         rc = CM_MemRestoreCertCache(cm, mem, memSz);
05796         if (rc != SSL_SUCCESS) {
05797             WOLFSSL_MSG("Mem restore cert cache failed");
05798         }
05799     }
05800 
05801     XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
05802     XFCLOSE(file);
05803 
05804     return rc;
05805 }
05806 
05807 #endif /* NO_FILESYSTEM */
05808 
05809 
05810 /* Persist cert cache to memory */
05811 int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, void* mem, int sz, int* used)
05812 {
05813     int ret = SSL_SUCCESS;
05814 
05815     WOLFSSL_ENTER("CM_MemSaveCertCache");
05816 
05817     if (LockMutex(&cm->caLock) != 0) {
05818         WOLFSSL_MSG("LockMutex on caLock failed");
05819         return BAD_MUTEX_E;
05820     }
05821 
05822     ret = DoMemSaveCertCache(cm, mem, sz);
05823     if (ret == SSL_SUCCESS)
05824         *used  = GetCertCacheMemSize(cm);
05825 
05826     UnLockMutex(&cm->caLock);
05827 
05828     return ret;
05829 }
05830 
05831 
05832 /* Restore cert cache from memory */
05833 int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const void* mem, int sz)
05834 {
05835     int ret = SSL_SUCCESS;
05836     int i;
05837     CertCacheHeader* hdr = (CertCacheHeader*)mem;
05838     byte*            current = (byte*)mem + sizeof(CertCacheHeader);
05839     byte*            end     = (byte*)mem + sz;  /* don't go over */
05840 
05841     WOLFSSL_ENTER("CM_MemRestoreCertCache");
05842 
05843     if (current > end) {
05844         WOLFSSL_MSG("Cert Cache Memory buffer too small");
05845         return BUFFER_E;
05846     }
05847 
05848     if (hdr->version  != WOLFSSL_CACHE_CERT_VERSION ||
05849         hdr->rows     != CA_TABLE_SIZE ||
05850         hdr->signerSz != (int)sizeof(Signer)) {
05851 
05852         WOLFSSL_MSG("Cert Cache Memory header mismatch");
05853         return CACHE_MATCH_ERROR;
05854     }
05855 
05856     if (LockMutex(&cm->caLock) != 0) {
05857         WOLFSSL_MSG("LockMutex on caLock failed");
05858         return BAD_MUTEX_E;
05859     }
05860 
05861     FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
05862 
05863     for (i = 0; i < CA_TABLE_SIZE; ++i) {
05864         int added = RestoreCertRow(cm, current, i, hdr->columns[i], end);
05865         if (added < 0) {
05866             WOLFSSL_MSG("RestoreCertRow error");
05867             ret = added;
05868             break;
05869         }
05870         current += added;
05871     }
05872 
05873     UnLockMutex(&cm->caLock);
05874 
05875     return ret;
05876 }
05877 
05878 
05879 /* get how big the the cert cache save buffer needs to be */
05880 int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
05881 {
05882     int sz;
05883 
05884     WOLFSSL_ENTER("CM_GetCertCacheMemSize");
05885 
05886     if (LockMutex(&cm->caLock) != 0) {
05887         WOLFSSL_MSG("LockMutex on caLock failed");
05888         return BAD_MUTEX_E;
05889     }
05890 
05891     sz = GetCertCacheMemSize(cm);
05892 
05893     UnLockMutex(&cm->caLock);
05894 
05895     return sz;
05896 }
05897 
05898 #endif /* PERSIST_CERT_CACHE */
05899 #endif /* NO_CERTS */
05900 
05901 
05902 int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX* ctx, const char* list)
05903 {
05904     WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list");
05905 
05906     /* alloc/init on demand only */
05907     if (ctx->suites == NULL) {
05908         ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap,
05909                                        DYNAMIC_TYPE_SUITES);
05910         if (ctx->suites == NULL) {
05911             WOLFSSL_MSG("Memory alloc for Suites failed");
05912             return SSL_FAILURE;
05913         }
05914         XMEMSET(ctx->suites, 0, sizeof(Suites));
05915     }
05916 
05917     return (SetCipherList(ctx->suites, list)) ? SSL_SUCCESS : SSL_FAILURE;
05918 }
05919 
05920 
05921 int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list)
05922 {
05923     WOLFSSL_ENTER("wolfSSL_set_cipher_list");
05924     return (SetCipherList(ssl->suites, list)) ? SSL_SUCCESS : SSL_FAILURE;
05925 }
05926 
05927 
05928 #ifndef WOLFSSL_LEANPSK
05929 #ifdef WOLFSSL_DTLS
05930 
05931 int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl)
05932 {
05933     (void)ssl;
05934 
05935     return ssl->dtls_timeout;
05936 }
05937 
05938 
05939 /* user may need to alter init dtls recv timeout, SSL_SUCCESS on ok */
05940 int wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int timeout)
05941 {
05942     if (ssl == NULL || timeout < 0)
05943         return BAD_FUNC_ARG;
05944 
05945     if (timeout > ssl->dtls_timeout_max) {
05946         WOLFSSL_MSG("Can't set dtls timeout init greater than dtls timeout max");
05947         return BAD_FUNC_ARG;
05948     }
05949 
05950     ssl->dtls_timeout_init = timeout;
05951     ssl->dtls_timeout = timeout;
05952 
05953     return SSL_SUCCESS;
05954 }
05955 
05956 
05957 /* user may need to alter max dtls recv timeout, SSL_SUCCESS on ok */
05958 int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int timeout)
05959 {
05960     if (ssl == NULL || timeout < 0)
05961         return BAD_FUNC_ARG;
05962 
05963     if (timeout < ssl->dtls_timeout_init) {
05964         WOLFSSL_MSG("Can't set dtls timeout max less than dtls timeout init");
05965         return BAD_FUNC_ARG;
05966     }
05967 
05968     ssl->dtls_timeout_max = timeout;
05969 
05970     return SSL_SUCCESS;
05971 }
05972 
05973 
05974 int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
05975 {
05976     int result = SSL_SUCCESS;
05977 
05978     DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
05979     ssl->dtls_msg_list = NULL;
05980     if (DtlsPoolTimeout(ssl) < 0 || DtlsPoolSend(ssl) < 0) {
05981         result = SSL_FATAL_ERROR;
05982     }
05983     return result;
05984 }
05985 
05986 #endif /* DTLS */
05987 #endif /* LEANPSK */
05988 
05989 
05990 #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
05991 
05992 /* Not an SSL function, return 0 for success, error code otherwise */
05993 /* Prereq: ssl's RNG needs to be initialized. */
05994 int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
05995                                  const byte* secret, word32 secretSz)
05996 {
05997     WOLFSSL_ENTER("wolfSSL_DTLS_SetCookieSecret");
05998 
05999     if (ssl == NULL) {
06000         WOLFSSL_MSG("need a SSL object");
06001         return BAD_FUNC_ARG;
06002     }
06003 
06004     if (secret != NULL && secretSz == 0) {
06005         WOLFSSL_MSG("can't have a new secret without a size");
06006         return BAD_FUNC_ARG;
06007     }
06008 
06009     /* If secretSz is 0, use the default size. */
06010     if (secretSz == 0)
06011         secretSz = COOKIE_SECRET_SZ;
06012 
06013     if (secretSz != ssl->buffers.dtlsCookieSecret.length) {
06014         byte* newSecret;
06015 
06016         if (ssl->buffers.dtlsCookieSecret.buffer != NULL) {
06017             ForceZero(ssl->buffers.dtlsCookieSecret.buffer,
06018                       ssl->buffers.dtlsCookieSecret.length);
06019             XFREE(ssl->buffers.dtlsCookieSecret.buffer,
06020                   ssl->heap, DYNAMIC_TYPE_NONE);
06021         }
06022 
06023         newSecret = (byte*)XMALLOC(secretSz, ssl->heap,DYNAMIC_TYPE_COOKIE_PWD);
06024         if (newSecret == NULL) {
06025             ssl->buffers.dtlsCookieSecret.buffer = NULL;
06026             ssl->buffers.dtlsCookieSecret.length = 0;
06027             WOLFSSL_MSG("couldn't allocate new cookie secret");
06028             return MEMORY_ERROR;
06029         }
06030         ssl->buffers.dtlsCookieSecret.buffer = newSecret;
06031         ssl->buffers.dtlsCookieSecret.length = secretSz;
06032     }
06033 
06034     /* If the supplied secret is NULL, randomly generate a new secret. */
06035     if (secret == NULL)
06036         wc_RNG_GenerateBlock(ssl->rng,
06037                              ssl->buffers.dtlsCookieSecret.buffer, secretSz);
06038     else
06039         XMEMCPY(ssl->buffers.dtlsCookieSecret.buffer, secret, secretSz);
06040 
06041     WOLFSSL_LEAVE("wolfSSL_DTLS_SetCookieSecret", 0);
06042     return 0;
06043 }
06044 
06045 #endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
06046 
06047 
06048 /* client only parts */
06049 #ifndef NO_WOLFSSL_CLIENT
06050 
06051     #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
06052     WOLFSSL_METHOD* wolfSSLv3_client_method(void)
06053     {
06054         WOLFSSL_METHOD* method =
06055                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
06056                                                         0, DYNAMIC_TYPE_METHOD);
06057         WOLFSSL_ENTER("SSLv3_client_method");
06058         if (method)
06059             InitSSL_Method(method, MakeSSLv3());
06060         return method;
06061     }
06062     #endif
06063 
06064     #ifdef WOLFSSL_DTLS
06065 
06066         #ifndef NO_OLD_TLS
06067         WOLFSSL_METHOD* wolfDTLSv1_client_method(void)
06068         {
06069             WOLFSSL_METHOD* method =
06070                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
06071                                                         0, DYNAMIC_TYPE_METHOD);
06072             WOLFSSL_ENTER("DTLSv1_client_method");
06073             if (method)
06074                 InitSSL_Method(method, MakeDTLSv1());
06075             return method;
06076         }
06077         #endif  /* NO_OLD_TLS */
06078 
06079         WOLFSSL_METHOD* wolfDTLSv1_2_client_method(void)
06080         {
06081             WOLFSSL_METHOD* method =
06082                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
06083                                                         0, DYNAMIC_TYPE_METHOD);
06084             WOLFSSL_ENTER("DTLSv1_2_client_method");
06085             if (method)
06086                 InitSSL_Method(method, MakeDTLSv1_2());
06087             return method;
06088         }
06089     #endif
06090 
06091 
06092     /* please see note at top of README if you get an error from connect */
06093     int wolfSSL_connect(WOLFSSL* ssl)
06094     {
06095         int neededState;
06096 
06097         WOLFSSL_ENTER("SSL_connect()");
06098 
06099         #ifdef HAVE_ERRNO_H
06100             errno = 0;
06101         #endif
06102 
06103         if (ssl->options.side != WOLFSSL_CLIENT_END) {
06104             WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
06105             return SSL_FATAL_ERROR;
06106         }
06107 
06108         #ifdef WOLFSSL_DTLS
06109             if (ssl->version.major == DTLS_MAJOR) {
06110                 ssl->options.dtls   = 1;
06111                 ssl->options.tls    = 1;
06112                 ssl->options.tls1_1 = 1;
06113 
06114                 if (DtlsPoolInit(ssl) != 0) {
06115                     ssl->error = MEMORY_ERROR;
06116                     WOLFSSL_ERROR(ssl->error);
06117                     return SSL_FATAL_ERROR;
06118                 }
06119             }
06120         #endif
06121 
06122         if (ssl->buffers.outputBuffer.length > 0) {
06123             if ( (ssl->error = SendBuffered(ssl)) == 0) {
06124                 /* fragOffset is non-zero when sending fragments. On the last
06125                  * fragment, fragOffset is zero again, and the state can be
06126                  * advanced. */
06127                 if (ssl->fragOffset == 0) {
06128                     ssl->options.connectState++;
06129                     WOLFSSL_MSG("connect state: "
06130                                 "Advanced from last buffered fragment send");
06131                 }
06132                 else {
06133                     WOLFSSL_MSG("connect state: "
06134                                 "Not advanced, more fragments to send");
06135                 }
06136             }
06137             else {
06138                 WOLFSSL_ERROR(ssl->error);
06139                 return SSL_FATAL_ERROR;
06140             }
06141         }
06142 
06143         switch (ssl->options.connectState) {
06144 
06145         case CONNECT_BEGIN :
06146             /* always send client hello first */
06147             if ( (ssl->error = SendClientHello(ssl)) != 0) {
06148                 WOLFSSL_ERROR(ssl->error);
06149                 return SSL_FATAL_ERROR;
06150             }
06151             ssl->options.connectState = CLIENT_HELLO_SENT;
06152             WOLFSSL_MSG("connect state: CLIENT_HELLO_SENT");
06153 
06154         case CLIENT_HELLO_SENT :
06155             neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
06156                                           SERVER_HELLODONE_COMPLETE;
06157             #ifdef WOLFSSL_DTLS
06158                 /* In DTLS, when resuming, we can go straight to FINISHED,
06159                  * or do a cookie exchange and then skip to FINISHED, assume
06160                  * we need the cookie exchange first. */
06161                 if (ssl->options.dtls)
06162                     neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
06163             #endif
06164             /* get response */
06165             while (ssl->options.serverState < neededState) {
06166                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
06167                     WOLFSSL_ERROR(ssl->error);
06168                     return SSL_FATAL_ERROR;
06169                 }
06170                 /* if resumption failed, reset needed state */
06171                 else if (neededState == SERVER_FINISHED_COMPLETE)
06172                     if (!ssl->options.resuming) {
06173                         if (!ssl->options.dtls)
06174                             neededState = SERVER_HELLODONE_COMPLETE;
06175                         else
06176                             neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
06177                     }
06178             }
06179 
06180             ssl->options.connectState = HELLO_AGAIN;
06181             WOLFSSL_MSG("connect state: HELLO_AGAIN");
06182 
06183         case HELLO_AGAIN :
06184             if (ssl->options.certOnly)
06185                 return SSL_SUCCESS;
06186 
06187             #ifdef WOLFSSL_DTLS
06188                 if (ssl->options.dtls) {
06189                     /* re-init hashes, exclude first hello and verify request */
06190 #ifndef NO_OLD_TLS
06191                     wc_InitMd5(&ssl->hsHashes->hashMd5);
06192                     if ( (ssl->error = wc_InitSha(&ssl->hsHashes->hashSha))
06193                                                                          != 0) {
06194                         WOLFSSL_ERROR(ssl->error);
06195                         return SSL_FATAL_ERROR;
06196                     }
06197 #endif
06198                     if (IsAtLeastTLSv1_2(ssl)) {
06199                         #ifndef NO_SHA256
06200                             if ( (ssl->error = wc_InitSha256(
06201                                             &ssl->hsHashes->hashSha256)) != 0) {
06202                                 WOLFSSL_ERROR(ssl->error);
06203                                 return SSL_FATAL_ERROR;
06204                             }
06205                         #endif
06206                         #ifdef WOLFSSL_SHA384
06207                             if ( (ssl->error = wc_InitSha384(
06208                                             &ssl->hsHashes->hashSha384)) != 0) {
06209                                 WOLFSSL_ERROR(ssl->error);
06210                                 return SSL_FATAL_ERROR;
06211                             }
06212                         #endif
06213                         #ifdef WOLFSSL_SHA512
06214                             if ( (ssl->error = wc_InitSha512(
06215                                             &ssl->hsHashes->hashSha512)) != 0) {
06216                                 WOLFSSL_ERROR(ssl->error);
06217                                 return SSL_FATAL_ERROR;
06218                             }
06219                         #endif
06220                     }
06221                     if ( (ssl->error = SendClientHello(ssl)) != 0) {
06222                         WOLFSSL_ERROR(ssl->error);
06223                         return SSL_FATAL_ERROR;
06224                     }
06225                 }
06226             #endif
06227 
06228             ssl->options.connectState = HELLO_AGAIN_REPLY;
06229             WOLFSSL_MSG("connect state: HELLO_AGAIN_REPLY");
06230 
06231         case HELLO_AGAIN_REPLY :
06232             #ifdef WOLFSSL_DTLS
06233                 if (ssl->options.dtls) {
06234                     neededState = ssl->options.resuming ?
06235                            SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
06236 
06237                     /* get response */
06238                     while (ssl->options.serverState < neededState) {
06239                         if ( (ssl->error = ProcessReply(ssl)) < 0) {
06240                                 WOLFSSL_ERROR(ssl->error);
06241                                 return SSL_FATAL_ERROR;
06242                         }
06243                         /* if resumption failed, reset needed state */
06244                         else if (neededState == SERVER_FINISHED_COMPLETE)
06245                             if (!ssl->options.resuming)
06246                                 neededState = SERVER_HELLODONE_COMPLETE;
06247                     }
06248                 }
06249             #endif
06250 
06251             ssl->options.connectState = FIRST_REPLY_DONE;
06252             WOLFSSL_MSG("connect state: FIRST_REPLY_DONE");
06253 
06254         case FIRST_REPLY_DONE :
06255             #ifndef NO_CERTS
06256                 if (ssl->options.sendVerify) {
06257                     if ( (ssl->error = SendCertificate(ssl)) != 0) {
06258                         WOLFSSL_ERROR(ssl->error);
06259                         return SSL_FATAL_ERROR;
06260                     }
06261                     WOLFSSL_MSG("sent: certificate");
06262                 }
06263 
06264             #endif
06265             ssl->options.connectState = FIRST_REPLY_FIRST;
06266             WOLFSSL_MSG("connect state: FIRST_REPLY_FIRST");
06267 
06268         case FIRST_REPLY_FIRST :
06269             if (!ssl->options.resuming) {
06270                 if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
06271                     WOLFSSL_ERROR(ssl->error);
06272                     return SSL_FATAL_ERROR;
06273                 }
06274                 WOLFSSL_MSG("sent: client key exchange");
06275             }
06276 
06277             ssl->options.connectState = FIRST_REPLY_SECOND;
06278             WOLFSSL_MSG("connect state: FIRST_REPLY_SECOND");
06279 
06280         case FIRST_REPLY_SECOND :
06281             #ifndef NO_CERTS
06282                 if (ssl->options.sendVerify) {
06283                     if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
06284                         WOLFSSL_ERROR(ssl->error);
06285                         return SSL_FATAL_ERROR;
06286                     }
06287                     WOLFSSL_MSG("sent: certificate verify");
06288                 }
06289             #endif
06290             ssl->options.connectState = FIRST_REPLY_THIRD;
06291             WOLFSSL_MSG("connect state: FIRST_REPLY_THIRD");
06292 
06293         case FIRST_REPLY_THIRD :
06294             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
06295                 WOLFSSL_ERROR(ssl->error);
06296                 return SSL_FATAL_ERROR;
06297             }
06298             WOLFSSL_MSG("sent: change cipher spec");
06299             ssl->options.connectState = FIRST_REPLY_FOURTH;
06300             WOLFSSL_MSG("connect state: FIRST_REPLY_FOURTH");
06301 
06302         case FIRST_REPLY_FOURTH :
06303             if ( (ssl->error = SendFinished(ssl)) != 0) {
06304                 WOLFSSL_ERROR(ssl->error);
06305                 return SSL_FATAL_ERROR;
06306             }
06307             WOLFSSL_MSG("sent: finished");
06308             ssl->options.connectState = FINISHED_DONE;
06309             WOLFSSL_MSG("connect state: FINISHED_DONE");
06310 
06311         case FINISHED_DONE :
06312             /* get response */
06313             while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
06314                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
06315                     WOLFSSL_ERROR(ssl->error);
06316                     return SSL_FATAL_ERROR;
06317                 }
06318 
06319             ssl->options.connectState = SECOND_REPLY_DONE;
06320             WOLFSSL_MSG("connect state: SECOND_REPLY_DONE");
06321 
06322         case SECOND_REPLY_DONE:
06323 #ifndef NO_HANDSHAKE_DONE_CB
06324             if (ssl->hsDoneCb) {
06325                 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
06326                 if (cbret < 0) {
06327                     ssl->error = cbret;
06328                     WOLFSSL_MSG("HandShake Done Cb don't continue error");
06329                     return SSL_FATAL_ERROR;
06330                 }
06331             }
06332 #endif /* NO_HANDSHAKE_DONE_CB */
06333 
06334             if (!ssl->options.dtls) {
06335                 FreeHandshakeResources(ssl);
06336             }
06337 #ifdef WOLFSSL_DTLS
06338             else {
06339                 ssl->options.dtlsHsRetain = 1;
06340             }
06341 #endif /* WOLFSSL_DTLS */
06342 
06343             WOLFSSL_LEAVE("SSL_connect()", SSL_SUCCESS);
06344             return SSL_SUCCESS;
06345 
06346         default:
06347             WOLFSSL_MSG("Unknown connect state ERROR");
06348             return SSL_FATAL_ERROR; /* unknown connect state */
06349         }
06350     }
06351 
06352 #endif /* NO_WOLFSSL_CLIENT */
06353 
06354 
06355 /* server only parts */
06356 #ifndef NO_WOLFSSL_SERVER
06357 
06358     #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
06359     WOLFSSL_METHOD* wolfSSLv3_server_method(void)
06360     {
06361         WOLFSSL_METHOD* method =
06362                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
06363                                                         0, DYNAMIC_TYPE_METHOD);
06364         WOLFSSL_ENTER("SSLv3_server_method");
06365         if (method) {
06366             InitSSL_Method(method, MakeSSLv3());
06367             method->side = WOLFSSL_SERVER_END;
06368         }
06369         return method;
06370     }
06371     #endif
06372 
06373 
06374     #ifdef WOLFSSL_DTLS
06375 
06376         #ifndef NO_OLD_TLS
06377         WOLFSSL_METHOD* wolfDTLSv1_server_method(void)
06378         {
06379             WOLFSSL_METHOD* method =
06380                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
06381                                                         0, DYNAMIC_TYPE_METHOD);
06382             WOLFSSL_ENTER("DTLSv1_server_method");
06383             if (method) {
06384                 InitSSL_Method(method, MakeDTLSv1());
06385                 method->side = WOLFSSL_SERVER_END;
06386             }
06387             return method;
06388         }
06389         #endif /* NO_OLD_TLS */
06390 
06391         WOLFSSL_METHOD* wolfDTLSv1_2_server_method(void)
06392         {
06393             WOLFSSL_METHOD* method =
06394                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
06395                                                         0, DYNAMIC_TYPE_METHOD);
06396             WOLFSSL_ENTER("DTLSv1_2_server_method");
06397             if (method) {
06398                 InitSSL_Method(method, MakeDTLSv1_2());
06399                 method->side = WOLFSSL_SERVER_END;
06400             }
06401             return method;
06402         }
06403     #endif
06404 
06405 
06406     int wolfSSL_accept(WOLFSSL* ssl)
06407     {
06408         word16 havePSK = 0;
06409         word16 haveAnon = 0;
06410         WOLFSSL_ENTER("SSL_accept()");
06411 
06412         #ifdef HAVE_ERRNO_H
06413             errno = 0;
06414         #endif
06415 
06416         #ifndef NO_PSK
06417             havePSK = ssl->options.havePSK;
06418         #endif
06419         (void)havePSK;
06420 
06421         #ifdef HAVE_ANON
06422             haveAnon = ssl->options.haveAnon;
06423         #endif
06424         (void)haveAnon;
06425 
06426         if (ssl->options.side != WOLFSSL_SERVER_END) {
06427             WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
06428             return SSL_FATAL_ERROR;
06429         }
06430 
06431         #ifndef NO_CERTS
06432             /* in case used set_accept_state after init */
06433             if (!havePSK && !haveAnon && 
06434                 (!ssl->buffers.certificate || 
06435                  !ssl->buffers.certificate->buffer ||
06436                  !ssl->buffers.key || 
06437                  !ssl->buffers.key->buffer)) {
06438                 WOLFSSL_MSG("accept error: don't have server cert and key");
06439                 ssl->error = NO_PRIVATE_KEY;
06440                 WOLFSSL_ERROR(ssl->error);
06441                 return SSL_FATAL_ERROR;
06442             }
06443         #endif
06444 
06445         #ifdef WOLFSSL_DTLS
06446             if (ssl->version.major == DTLS_MAJOR) {
06447                 ssl->options.dtls   = 1;
06448                 ssl->options.tls    = 1;
06449                 ssl->options.tls1_1 = 1;
06450 
06451                 if (DtlsPoolInit(ssl) != 0) {
06452                     ssl->error = MEMORY_ERROR;
06453                     WOLFSSL_ERROR(ssl->error);
06454                     return SSL_FATAL_ERROR;
06455                 }
06456             }
06457         #endif
06458 
06459         if (ssl->buffers.outputBuffer.length > 0) {
06460             if ( (ssl->error = SendBuffered(ssl)) == 0) {
06461                 /* fragOffset is non-zero when sending fragments. On the last
06462                  * fragment, fragOffset is zero again, and the state can be
06463                  * advanced. */
06464                 if (ssl->fragOffset == 0) {
06465                     ssl->options.acceptState++;
06466                     WOLFSSL_MSG("accept state: "
06467                                 "Advanced from last buffered fragment send");
06468                 }
06469                 else {
06470                     WOLFSSL_MSG("accept state: "
06471                                 "Not advanced, more fragments to send");
06472                 }
06473             }
06474             else {
06475                 WOLFSSL_ERROR(ssl->error);
06476                 return SSL_FATAL_ERROR;
06477             }
06478         }
06479 
06480         switch (ssl->options.acceptState) {
06481 
06482         case ACCEPT_BEGIN :
06483             /* get response */
06484             while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
06485                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
06486                     WOLFSSL_ERROR(ssl->error);
06487                     return SSL_FATAL_ERROR;
06488                 }
06489             ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
06490             WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
06491 
06492         case ACCEPT_CLIENT_HELLO_DONE :
06493             ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
06494             WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
06495 
06496         case ACCEPT_FIRST_REPLY_DONE :
06497             if ( (ssl->error = SendServerHello(ssl)) != 0) {
06498                 WOLFSSL_ERROR(ssl->error);
06499                 return SSL_FATAL_ERROR;
06500             }
06501             ssl->options.acceptState = SERVER_HELLO_SENT;
06502             WOLFSSL_MSG("accept state SERVER_HELLO_SENT");
06503 
06504         case SERVER_HELLO_SENT :
06505             #ifndef NO_CERTS
06506                 if (!ssl->options.resuming)
06507                     if ( (ssl->error = SendCertificate(ssl)) != 0) {
06508                         WOLFSSL_ERROR(ssl->error);
06509                         return SSL_FATAL_ERROR;
06510                     }
06511             #endif
06512             ssl->options.acceptState = CERT_SENT;
06513             WOLFSSL_MSG("accept state CERT_SENT");
06514 
06515         case CERT_SENT :
06516             #ifndef NO_CERTS
06517             if (!ssl->options.resuming)
06518                 if ( (ssl->error = SendCertificateStatus(ssl)) != 0) {
06519                     WOLFSSL_ERROR(ssl->error);
06520                     return SSL_FATAL_ERROR;
06521                 }
06522             #endif
06523             ssl->options.acceptState = CERT_STATUS_SENT;
06524             WOLFSSL_MSG("accept state CERT_STATUS_SENT");
06525 
06526         case CERT_STATUS_SENT :
06527             if (!ssl->options.resuming)
06528                 if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
06529                     WOLFSSL_ERROR(ssl->error);
06530                     return SSL_FATAL_ERROR;
06531                 }
06532             ssl->options.acceptState = KEY_EXCHANGE_SENT;
06533             WOLFSSL_MSG("accept state KEY_EXCHANGE_SENT");
06534 
06535         case KEY_EXCHANGE_SENT :
06536             #ifndef NO_CERTS
06537                 if (!ssl->options.resuming)
06538                     if (ssl->options.verifyPeer)
06539                         if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
06540                             WOLFSSL_ERROR(ssl->error);
06541                             return SSL_FATAL_ERROR;
06542                         }
06543             #endif
06544             ssl->options.acceptState = CERT_REQ_SENT;
06545             WOLFSSL_MSG("accept state CERT_REQ_SENT");
06546 
06547         case CERT_REQ_SENT :
06548             if (!ssl->options.resuming)
06549                 if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
06550                     WOLFSSL_ERROR(ssl->error);
06551                     return SSL_FATAL_ERROR;
06552                 }
06553             ssl->options.acceptState = SERVER_HELLO_DONE;
06554             WOLFSSL_MSG("accept state SERVER_HELLO_DONE");
06555 
06556         case SERVER_HELLO_DONE :
06557             if (!ssl->options.resuming) {
06558                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
06559                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
06560                         WOLFSSL_ERROR(ssl->error);
06561                         return SSL_FATAL_ERROR;
06562                     }
06563             }
06564             ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
06565             WOLFSSL_MSG("accept state  ACCEPT_SECOND_REPLY_DONE");
06566 
06567         case ACCEPT_SECOND_REPLY_DONE :
06568 #ifdef HAVE_SESSION_TICKET
06569             if (ssl->options.createTicket) {
06570                 if ( (ssl->error = SendTicket(ssl)) != 0) {
06571                     WOLFSSL_ERROR(ssl->error);
06572                     return SSL_FATAL_ERROR;
06573                 }
06574             }
06575 #endif /* HAVE_SESSION_TICKET */
06576             ssl->options.acceptState = TICKET_SENT;
06577             WOLFSSL_MSG("accept state  TICKET_SENT");
06578 
06579         case TICKET_SENT:
06580             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
06581                 WOLFSSL_ERROR(ssl->error);
06582                 return SSL_FATAL_ERROR;
06583             }
06584             ssl->options.acceptState = CHANGE_CIPHER_SENT;
06585             WOLFSSL_MSG("accept state  CHANGE_CIPHER_SENT");
06586 
06587         case CHANGE_CIPHER_SENT :
06588             if ( (ssl->error = SendFinished(ssl)) != 0) {
06589                 WOLFSSL_ERROR(ssl->error);
06590                 return SSL_FATAL_ERROR;
06591             }
06592 
06593             ssl->options.acceptState = ACCEPT_FINISHED_DONE;
06594             WOLFSSL_MSG("accept state ACCEPT_FINISHED_DONE");
06595 
06596         case ACCEPT_FINISHED_DONE :
06597             if (ssl->options.resuming)
06598                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
06599                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
06600                         WOLFSSL_ERROR(ssl->error);
06601                         return SSL_FATAL_ERROR;
06602                     }
06603 
06604             ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
06605             WOLFSSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
06606 
06607         case ACCEPT_THIRD_REPLY_DONE :
06608 #ifndef NO_HANDSHAKE_DONE_CB
06609             if (ssl->hsDoneCb) {
06610                 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
06611                 if (cbret < 0) {
06612                     ssl->error = cbret;
06613                     WOLFSSL_MSG("HandShake Done Cb don't continue error");
06614                     return SSL_FATAL_ERROR;
06615                 }
06616             }
06617 #endif /* NO_HANDSHAKE_DONE_CB */
06618 
06619             if (!ssl->options.dtls) {
06620                 FreeHandshakeResources(ssl);
06621             }
06622 #ifdef WOLFSSL_DTLS
06623             else {
06624                 ssl->options.dtlsHsRetain = 1;
06625             }
06626 #endif /* WOLFSSL_DTLS */
06627 
06628             WOLFSSL_LEAVE("SSL_accept()", SSL_SUCCESS);
06629             return SSL_SUCCESS;
06630 
06631         default :
06632             WOLFSSL_MSG("Unknown accept state ERROR");
06633             return SSL_FATAL_ERROR;
06634         }
06635     }
06636 
06637 #endif /* NO_WOLFSSL_SERVER */
06638 
06639 
06640 #ifndef NO_HANDSHAKE_DONE_CB
06641 
06642 int wolfSSL_SetHsDoneCb(WOLFSSL* ssl, HandShakeDoneCb cb, void* user_ctx)
06643 {
06644     WOLFSSL_ENTER("wolfSSL_SetHsDoneCb");
06645 
06646     if (ssl == NULL)
06647         return BAD_FUNC_ARG;
06648 
06649     ssl->hsDoneCb  = cb;
06650     ssl->hsDoneCtx = user_ctx;
06651 
06652 
06653     return SSL_SUCCESS;
06654 }
06655 
06656 #endif /* NO_HANDSHAKE_DONE_CB */
06657 
06658 
06659 int wolfSSL_Cleanup(void)
06660 {
06661     int ret = SSL_SUCCESS;
06662     int release = 0;
06663 
06664     WOLFSSL_ENTER("wolfSSL_Cleanup");
06665 
06666     if (initRefCount == 0)
06667         return ret;  /* possibly no init yet, but not failure either way */
06668 
06669     if (LockMutex(&count_mutex) != 0) {
06670         WOLFSSL_MSG("Bad Lock Mutex count");
06671         return BAD_MUTEX_E;
06672     }
06673 
06674     release = initRefCount-- == 1;
06675     if (initRefCount < 0)
06676         initRefCount = 0;
06677 
06678     UnLockMutex(&count_mutex);
06679 
06680     if (!release)
06681         return ret;
06682 
06683 #ifndef NO_SESSION_CACHE
06684     if (FreeMutex(&session_mutex) != 0)
06685         ret = BAD_MUTEX_E;
06686 #endif
06687     if (FreeMutex(&count_mutex) != 0)
06688         ret = BAD_MUTEX_E;
06689 
06690 #if defined(HAVE_ECC) && defined(FP_ECC)
06691     wc_ecc_fp_free();
06692 #endif
06693 
06694     return ret;
06695 }
06696 
06697 
06698 #ifndef NO_SESSION_CACHE
06699 
06700 
06701 /* some session IDs aren't random after all, let's make them random */
06702 static INLINE word32 HashSession(const byte* sessionID, word32 len, int* error)
06703 {
06704     byte digest[MAX_DIGEST_SIZE];
06705 
06706 #ifndef NO_MD5
06707     *error =  wc_Md5Hash(sessionID, len, digest);
06708 #elif !defined(NO_SHA)
06709     *error =  wc_ShaHash(sessionID, len, digest);
06710 #elif !defined(NO_SHA256)
06711     *error =  wc_Sha256Hash(sessionID, len, digest);
06712 #else
06713     #error "We need a digest to hash the session IDs"
06714 #endif
06715 
06716     return *error == 0 ? MakeWordFromHash(digest) : 0; /* 0 on failure */
06717 }
06718 
06719 
06720 void wolfSSL_flush_sessions(WOLFSSL_CTX* ctx, long tm)
06721 {
06722     /* static table now, no flushing needed */
06723     (void)ctx;
06724     (void)tm;
06725 }
06726 
06727 
06728 /* set ssl session timeout in seconds */
06729 int wolfSSL_set_timeout(WOLFSSL* ssl, unsigned int to)
06730 {
06731     if (ssl == NULL)
06732         return BAD_FUNC_ARG;
06733 
06734     ssl->timeout = to;
06735 
06736     return SSL_SUCCESS;
06737 }
06738 
06739 
06740 /* set ctx session timeout in seconds */
06741 int wolfSSL_CTX_set_timeout(WOLFSSL_CTX* ctx, unsigned int to)
06742 {
06743     if (ctx == NULL)
06744         return BAD_FUNC_ARG;
06745 
06746     ctx->timeout = to;
06747 
06748     return SSL_SUCCESS;
06749 }
06750 
06751 
06752 #ifndef NO_CLIENT_CACHE
06753 
06754 /* Get Session from Client cache based on id/len, return NULL on failure */
06755 WOLFSSL_SESSION* GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
06756 {
06757     WOLFSSL_SESSION* ret = NULL;
06758     word32          row;
06759     int             idx;
06760     int             count;
06761     int             error = 0;
06762 
06763     WOLFSSL_ENTER("GetSessionClient");
06764 
06765     if (ssl->options.side == WOLFSSL_SERVER_END)
06766         return NULL;
06767 
06768     len = min(SERVER_ID_LEN, (word32)len);
06769     row = HashSession(id, len, &error) % SESSION_ROWS;
06770     if (error != 0) {
06771         WOLFSSL_MSG("Hash session failed");
06772         return NULL;
06773     }
06774 
06775     if (LockMutex(&session_mutex) != 0) {
06776         WOLFSSL_MSG("Lock session mutex failed");
06777         return NULL;
06778     }
06779 
06780     /* start from most recently used */
06781     count = min((word32)ClientCache[row].totalCount, SESSIONS_PER_ROW);
06782     idx = ClientCache[row].nextIdx - 1;
06783     if (idx < 0)
06784         idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
06785 
06786     for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
06787         WOLFSSL_SESSION* current;
06788         ClientSession   clSess;
06789 
06790         if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
06791             WOLFSSL_MSG("Bad idx");
06792             break;
06793         }
06794 
06795         clSess = ClientCache[row].Clients[idx];
06796 
06797         current = &SessionCache[clSess.serverRow].Sessions[clSess.serverIdx];
06798         if (XMEMCMP(current->serverID, id, len) == 0) {
06799             WOLFSSL_MSG("Found a serverid match for client");
06800             if (LowResTimer() < (current->bornOn + current->timeout)) {
06801                 WOLFSSL_MSG("Session valid");
06802                 ret = current;
06803                 break;
06804             } else {
06805                 WOLFSSL_MSG("Session timed out");  /* could have more for id */
06806             }
06807         } else {
06808             WOLFSSL_MSG("ServerID not a match from client table");
06809         }
06810     }
06811 
06812     UnLockMutex(&session_mutex);
06813 
06814     return ret;
06815 }
06816 
06817 #endif /* NO_CLIENT_CACHE */
06818 
06819 
06820 WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret)
06821 {
06822     WOLFSSL_SESSION* ret = 0;
06823     const byte*  id = NULL;
06824     word32       row;
06825     int          idx;
06826     int          count;
06827     int          error = 0;
06828 
06829     if (ssl->options.sessionCacheOff)
06830         return NULL;
06831 
06832     if (ssl->options.haveSessionId == 0)
06833         return NULL;
06834 
06835 #ifdef HAVE_SESSION_TICKET
06836     if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
06837         return NULL;
06838 #endif
06839 
06840     if (ssl->arrays)
06841         id = ssl->arrays->sessionID;
06842     else
06843         id = ssl->session.sessionID;
06844 
06845     row = HashSession(id, ID_LEN, &error) % SESSION_ROWS;
06846     if (error != 0) {
06847         WOLFSSL_MSG("Hash session failed");
06848         return NULL;
06849     }
06850 
06851     if (LockMutex(&session_mutex) != 0)
06852         return 0;
06853 
06854     /* start from most recently used */
06855     count = min((word32)SessionCache[row].totalCount, SESSIONS_PER_ROW);
06856     idx = SessionCache[row].nextIdx - 1;
06857     if (idx < 0)
06858         idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
06859 
06860     for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
06861         WOLFSSL_SESSION* current;
06862 
06863         if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
06864             WOLFSSL_MSG("Bad idx");
06865             break;
06866         }
06867 
06868         current = &SessionCache[row].Sessions[idx];
06869         if (XMEMCMP(current->sessionID, id, ID_LEN) == 0) {
06870             WOLFSSL_MSG("Found a session match");
06871             if (LowResTimer() < (current->bornOn + current->timeout)) {
06872                 WOLFSSL_MSG("Session valid");
06873                 ret = current;
06874                 if (masterSecret)
06875                     XMEMCPY(masterSecret, current->masterSecret, SECRET_LEN);
06876             } else {
06877                 WOLFSSL_MSG("Session timed out");
06878             }
06879             break;  /* no more sessionIDs whether valid or not that match */
06880         } else {
06881             WOLFSSL_MSG("SessionID not a match at this idx");
06882         }
06883     }
06884 
06885     UnLockMutex(&session_mutex);
06886 
06887     return ret;
06888 }
06889 
06890 
06891 int SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
06892 {
06893     if (ssl->options.sessionCacheOff)
06894         return SSL_FAILURE;
06895 
06896     if (LowResTimer() < (session->bornOn + session->timeout)) {
06897         ssl->session  = *session;
06898         ssl->options.resuming = 1;
06899 
06900 #ifdef SESSION_CERTS
06901         ssl->version              = session->version;
06902         ssl->options.cipherSuite0 = session->cipherSuite0;
06903         ssl->options.cipherSuite  = session->cipherSuite;
06904 #endif
06905 
06906         return SSL_SUCCESS;
06907     }
06908     return SSL_FAILURE;  /* session timed out */
06909 }
06910 
06911 
06912 #ifdef WOLFSSL_SESSION_STATS
06913 static int get_locked_session_stats(word32* active, word32* total,
06914                                     word32* peak);
06915 #endif
06916 
06917 int AddSession(WOLFSSL* ssl)
06918 {
06919     word32 row, idx;
06920     int    error = 0;
06921 
06922     if (ssl->options.sessionCacheOff)
06923         return 0;
06924 
06925     if (ssl->options.haveSessionId == 0)
06926         return 0;
06927 
06928 #ifdef HAVE_SESSION_TICKET
06929     if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
06930         return 0;
06931 #endif
06932 
06933     row = HashSession(ssl->arrays->sessionID, ID_LEN, &error) % SESSION_ROWS;
06934     if (error != 0) {
06935         WOLFSSL_MSG("Hash session failed");
06936         return error;
06937     }
06938 
06939     if (LockMutex(&session_mutex) != 0)
06940         return BAD_MUTEX_E;
06941 
06942     idx = SessionCache[row].nextIdx++;
06943 #ifdef SESSION_INDEX
06944     ssl->sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx;
06945 #endif
06946 
06947     XMEMCPY(SessionCache[row].Sessions[idx].masterSecret,
06948            ssl->arrays->masterSecret, SECRET_LEN);
06949     XMEMCPY(SessionCache[row].Sessions[idx].sessionID, ssl->arrays->sessionID,
06950            ID_LEN);
06951     SessionCache[row].Sessions[idx].sessionIDSz = ssl->arrays->sessionIDSz;
06952 
06953     SessionCache[row].Sessions[idx].timeout = ssl->timeout;
06954     SessionCache[row].Sessions[idx].bornOn  = LowResTimer();
06955 
06956 #ifdef HAVE_SESSION_TICKET
06957     SessionCache[row].Sessions[idx].ticketLen     = ssl->session.ticketLen;
06958     XMEMCPY(SessionCache[row].Sessions[idx].ticket,
06959                                    ssl->session.ticket, ssl->session.ticketLen);
06960 #endif
06961 
06962 #ifdef SESSION_CERTS
06963     SessionCache[row].Sessions[idx].chain.count = ssl->session.chain.count;
06964     XMEMCPY(SessionCache[row].Sessions[idx].chain.certs,
06965            ssl->session.chain.certs, sizeof(x509_buffer) * MAX_CHAIN_DEPTH);
06966 
06967     SessionCache[row].Sessions[idx].version      = ssl->version;
06968     SessionCache[row].Sessions[idx].cipherSuite0 = ssl->options.cipherSuite0;
06969     SessionCache[row].Sessions[idx].cipherSuite  = ssl->options.cipherSuite;
06970 #endif /* SESSION_CERTS */
06971 
06972     SessionCache[row].totalCount++;
06973     if (SessionCache[row].nextIdx == SESSIONS_PER_ROW)
06974         SessionCache[row].nextIdx = 0;
06975 
06976 #ifndef NO_CLIENT_CACHE
06977     if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->session.idLen) {
06978         word32 clientRow, clientIdx;
06979 
06980         WOLFSSL_MSG("Adding client cache entry");
06981 
06982         SessionCache[row].Sessions[idx].idLen = ssl->session.idLen;
06983         XMEMCPY(SessionCache[row].Sessions[idx].serverID, ssl->session.serverID,
06984                 ssl->session.idLen);
06985 
06986         clientRow = HashSession(ssl->session.serverID, ssl->session.idLen,
06987                                 &error) % SESSION_ROWS;
06988         if (error != 0) {
06989             WOLFSSL_MSG("Hash session failed");
06990         } else {
06991             clientIdx = ClientCache[clientRow].nextIdx++;
06992 
06993             ClientCache[clientRow].Clients[clientIdx].serverRow = (word16)row;
06994             ClientCache[clientRow].Clients[clientIdx].serverIdx = (word16)idx;
06995 
06996             ClientCache[clientRow].totalCount++;
06997             if (ClientCache[clientRow].nextIdx == SESSIONS_PER_ROW)
06998                 ClientCache[clientRow].nextIdx = 0;
06999         }
07000     }
07001     else
07002         SessionCache[row].Sessions[idx].idLen = 0;
07003 #endif /* NO_CLIENT_CACHE */
07004 
07005 #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
07006     if (error == 0) {
07007         word32 active = 0;
07008 
07009         error = get_locked_session_stats(&active, NULL, NULL);
07010         if (error == SSL_SUCCESS) {
07011             error = 0;  /* back to this function ok */
07012 
07013             if (active > PeakSessions)
07014                 PeakSessions = active;
07015         }
07016     }
07017 #endif /* defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS) */
07018 
07019     if (UnLockMutex(&session_mutex) != 0)
07020         return BAD_MUTEX_E;
07021 
07022     return error;
07023 }
07024 
07025 
07026 #ifdef SESSION_INDEX
07027 
07028 int wolfSSL_GetSessionIndex(WOLFSSL* ssl)
07029 {
07030     WOLFSSL_ENTER("wolfSSL_GetSessionIndex");
07031     WOLFSSL_LEAVE("wolfSSL_GetSessionIndex", ssl->sessionIndex);
07032     return ssl->sessionIndex;
07033 }
07034 
07035 
07036 int wolfSSL_GetSessionAtIndex(int idx, WOLFSSL_SESSION* session)
07037 {
07038     int row, col, result = SSL_FAILURE;
07039 
07040     WOLFSSL_ENTER("wolfSSL_GetSessionAtIndex");
07041 
07042     row = idx >> SESSIDX_ROW_SHIFT;
07043     col = idx & SESSIDX_IDX_MASK;
07044 
07045     if (LockMutex(&session_mutex) != 0) {
07046         return BAD_MUTEX_E;
07047     }
07048 
07049     if (row < SESSION_ROWS &&
07050         col < (int)min(SessionCache[row].totalCount, SESSIONS_PER_ROW)) {
07051         XMEMCPY(session,
07052                  &SessionCache[row].Sessions[col], sizeof(WOLFSSL_SESSION));
07053         result = SSL_SUCCESS;
07054     }
07055 
07056     if (UnLockMutex(&session_mutex) != 0)
07057         result = BAD_MUTEX_E;
07058 
07059     WOLFSSL_LEAVE("wolfSSL_GetSessionAtIndex", result);
07060     return result;
07061 }
07062 
07063 #endif /* SESSION_INDEX */
07064 
07065 #if defined(SESSION_INDEX) && defined(SESSION_CERTS)
07066 
07067 WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session)
07068 {
07069     WOLFSSL_X509_CHAIN* chain = NULL;
07070 
07071     WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
07072     if (session)
07073         chain = &session->chain;
07074 
07075     WOLFSSL_LEAVE("wolfSSL_SESSION_get_peer_chain", chain ? 1 : 0);
07076     return chain;
07077 }
07078 
07079 #endif /* SESSION_INDEX && SESSION_CERTS */
07080 
07081 
07082 #ifdef WOLFSSL_SESSION_STATS
07083 
07084 /* requires session_mutex lock held, SSL_SUCCESS on ok */
07085 static int get_locked_session_stats(word32* active, word32* total, word32* peak)
07086 {
07087     int result = SSL_SUCCESS;
07088     int i;
07089     int count;
07090     int idx;
07091     word32 now   = 0;
07092     word32 seen  = 0;
07093     word32 ticks = LowResTimer();
07094 
07095     (void)peak;
07096 
07097     WOLFSSL_ENTER("get_locked_session_stats");
07098 
07099     for (i = 0; i < SESSION_ROWS; i++) {
07100         seen += SessionCache[i].totalCount;
07101 
07102         if (active == NULL)
07103             continue;  /* no need to calculate what we can't set */
07104 
07105         count = min((word32)SessionCache[i].totalCount, SESSIONS_PER_ROW);
07106         idx   = SessionCache[i].nextIdx - 1;
07107         if (idx < 0)
07108             idx = SESSIONS_PER_ROW - 1; /* if back to front previous was end */
07109 
07110         for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
07111             if (idx >= SESSIONS_PER_ROW || idx < 0) {  /* sanity check */
07112                 WOLFSSL_MSG("Bad idx");
07113                 break;
07114             }
07115 
07116             /* if not expried then good */
07117             if (ticks < (SessionCache[i].Sessions[idx].bornOn +
07118                          SessionCache[i].Sessions[idx].timeout) ) {
07119                 now++;
07120             }
07121         }
07122     }
07123 
07124     if (active)
07125         *active = now;
07126 
07127     if (total)
07128         *total = seen;
07129 
07130 #ifdef WOLFSSL_PEAK_SESSIONS
07131     if (peak)
07132         *peak = PeakSessions;
07133 #endif
07134 
07135     WOLFSSL_LEAVE("get_locked_session_stats", result);
07136 
07137     return result;
07138 }
07139 
07140 
07141 /* return SSL_SUCCESS on ok */
07142 int wolfSSL_get_session_stats(word32* active, word32* total, word32* peak,
07143                               word32* maxSessions)
07144 {
07145     int result = SSL_SUCCESS;
07146 
07147     WOLFSSL_ENTER("wolfSSL_get_session_stats");
07148 
07149     if (maxSessions) {
07150         *maxSessions = SESSIONS_PER_ROW * SESSION_ROWS;
07151 
07152         if (active == NULL && total == NULL && peak == NULL)
07153             return result;  /* we're done */
07154     }
07155 
07156     /* user must provide at least one query value */
07157     if (active == NULL && total == NULL && peak == NULL)
07158         return BAD_FUNC_ARG;
07159 
07160     if (LockMutex(&session_mutex) != 0) {
07161         return BAD_MUTEX_E;
07162     }
07163 
07164     result = get_locked_session_stats(active, total, peak);
07165 
07166     if (UnLockMutex(&session_mutex) != 0)
07167         result = BAD_MUTEX_E;
07168 
07169     WOLFSSL_LEAVE("wolfSSL_get_session_stats", result);
07170 
07171     return result;
07172 }
07173 
07174 #endif /* WOLFSSL_SESSION_STATS */
07175 
07176 
07177     #ifdef PRINT_SESSION_STATS
07178 
07179     /* SSL_SUCCESS on ok */
07180     int wolfSSL_PrintSessionStats(void)
07181     {
07182         word32 totalSessionsSeen = 0;
07183         word32 totalSessionsNow = 0;
07184         word32 peak = 0;
07185         word32 maxSessions = 0;
07186         int    i;
07187         int    ret;
07188         double E;               /* expected freq */
07189         double chiSquare = 0;
07190 
07191         ret = wolfSSL_get_session_stats(&totalSessionsNow, &totalSessionsSeen,
07192                                         &peak, &maxSessions);
07193         if (ret != SSL_SUCCESS)
07194             return ret;
07195         printf("Total Sessions Seen = %d\n", totalSessionsSeen);
07196         printf("Total Sessions Now  = %d\n", totalSessionsNow);
07197 #ifdef WOLFSSL_PEAK_SESSIONS
07198         printf("Peak  Sessions      = %d\n", peak);
07199 #endif
07200         printf("Max   Sessions      = %d\n", maxSessions);
07201 
07202         E = (double)totalSessionsSeen / SESSION_ROWS;
07203 
07204         for (i = 0; i < SESSION_ROWS; i++) {
07205             double diff = SessionCache[i].totalCount - E;
07206             diff *= diff;                /* square    */
07207             diff /= E;                   /* normalize */
07208 
07209             chiSquare += diff;
07210         }
07211         printf("  chi-square = %5.1f, d.f. = %d\n", chiSquare,
07212                                                      SESSION_ROWS - 1);
07213         #if (SESSION_ROWS == 11)
07214             printf(" .05 p value =  18.3, chi-square should be less\n");
07215         #elif (SESSION_ROWS == 211)
07216             printf(".05 p value  = 244.8, chi-square should be less\n");
07217         #elif (SESSION_ROWS == 5981)
07218             printf(".05 p value  = 6161.0, chi-square should be less\n");
07219         #elif (SESSION_ROWS == 3)
07220             printf(".05 p value  =   6.0, chi-square should be less\n");
07221         #elif (SESSION_ROWS == 2861)
07222             printf(".05 p value  = 2985.5, chi-square should be less\n");
07223         #endif
07224         printf("\n");
07225 
07226         return ret;
07227     }
07228 
07229     #endif /* SESSION_STATS */
07230 
07231 #else  /* NO_SESSION_CACHE */
07232 
07233 /* No session cache version */
07234 WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret)
07235 {
07236     (void)ssl;
07237     (void)masterSecret;
07238 
07239     return NULL;
07240 }
07241 
07242 #endif /* NO_SESSION_CACHE */
07243 
07244 
07245 /* call before SSL_connect, if verifying will add name check to
07246    date check and signature check */
07247 int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
07248 {
07249     WOLFSSL_ENTER("wolfSSL_check_domain_name");
07250     if (ssl->buffers.domainName.buffer)
07251         XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
07252 
07253     ssl->buffers.domainName.length = (word32)XSTRLEN(dn) + 1;
07254     ssl->buffers.domainName.buffer = (byte*) XMALLOC(
07255                 ssl->buffers.domainName.length, ssl->heap, DYNAMIC_TYPE_DOMAIN);
07256 
07257     if (ssl->buffers.domainName.buffer) {
07258         XSTRNCPY((char*)ssl->buffers.domainName.buffer, dn,
07259                 ssl->buffers.domainName.length);
07260         return SSL_SUCCESS;
07261     }
07262     else {
07263         ssl->error = MEMORY_ERROR;
07264         return SSL_FAILURE;
07265     }
07266 }
07267 
07268 
07269 /* turn on wolfSSL zlib compression
07270    returns SSL_SUCCESS for success, else error (not built in)
07271 */
07272 int wolfSSL_set_compression(WOLFSSL* ssl)
07273 {
07274     WOLFSSL_ENTER("wolfSSL_set_compression");
07275     (void)ssl;
07276 #ifdef HAVE_LIBZ
07277     ssl->options.usingCompression = 1;
07278     return SSL_SUCCESS;
07279 #else
07280     return NOT_COMPILED_IN;
07281 #endif
07282 }
07283 
07284 
07285 #ifndef USE_WINDOWS_API
07286     #ifndef NO_WRITEV
07287 
07288         /* simulate writev semantics, doesn't actually do block at a time though
07289            because of SSL_write behavior and because front adds may be small */
07290         int wolfSSL_writev(WOLFSSL* ssl, const struct iovec* iov, int iovcnt)
07291         {
07292         #ifdef WOLFSSL_SMALL_STACK
07293             byte   staticBuffer[1]; /* force heap usage */
07294         #else
07295             byte   staticBuffer[FILE_BUFFER_SIZE];
07296         #endif
07297             byte* myBuffer  = staticBuffer;
07298             int   dynamic   = 0;
07299             int   sending   = 0;
07300             int   idx       = 0;
07301             int   i;
07302             int   ret;
07303 
07304             WOLFSSL_ENTER("wolfSSL_writev");
07305 
07306             for (i = 0; i < iovcnt; i++)
07307                 sending += (int)iov[i].iov_len;
07308 
07309             if (sending > (int)sizeof(staticBuffer)) {
07310                 myBuffer = (byte*)XMALLOC(sending, ssl->heap,
07311                                                            DYNAMIC_TYPE_WRITEV);
07312                 if (!myBuffer)
07313                     return MEMORY_ERROR;
07314 
07315                 dynamic = 1;
07316             }
07317 
07318             for (i = 0; i < iovcnt; i++) {
07319                 XMEMCPY(&myBuffer[idx], iov[i].iov_base, iov[i].iov_len);
07320                 idx += (int)iov[i].iov_len;
07321             }
07322 
07323             ret = wolfSSL_write(ssl, myBuffer, sending);
07324 
07325             if (dynamic)
07326                 XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
07327 
07328             return ret;
07329         }
07330     #endif
07331 #endif
07332 
07333 
07334 #ifdef WOLFSSL_CALLBACKS
07335 
07336     typedef struct itimerval Itimerval;
07337 
07338     /* don't keep calling simple functions while setting up timer and signals
07339        if no inlining these are the next best */
07340 
07341     #define AddTimes(a, b, c)                       \
07342         do {                                        \
07343             c.tv_sec  = a.tv_sec  + b.tv_sec;       \
07344             c.tv_usec = a.tv_usec + b.tv_usec;      \
07345             if (c.tv_usec >=  1000000) {            \
07346                 c.tv_sec++;                         \
07347                 c.tv_usec -= 1000000;               \
07348             }                                       \
07349         } while (0)
07350 
07351 
07352     #define SubtractTimes(a, b, c)                  \
07353         do {                                        \
07354             c.tv_sec  = a.tv_sec  - b.tv_sec;       \
07355             c.tv_usec = a.tv_usec - b.tv_usec;      \
07356             if (c.tv_usec < 0) {                    \
07357                 c.tv_sec--;                         \
07358                 c.tv_usec += 1000000;               \
07359             }                                       \
07360         } while (0)
07361 
07362     #define CmpTimes(a, b, cmp)                     \
07363         ((a.tv_sec  ==  b.tv_sec) ?                 \
07364             (a.tv_usec cmp b.tv_usec) :             \
07365             (a.tv_sec  cmp b.tv_sec))               \
07366 
07367 
07368     /* do nothing handler */
07369     static void myHandler(int signo)
07370     {
07371         (void)signo;
07372         return;
07373     }
07374 
07375 
07376     static int wolfSSL_ex_wrapper(WOLFSSL* ssl, HandShakeCallBack hsCb,
07377                                  TimeoutCallBack toCb, Timeval timeout)
07378     {
07379         int       ret        = SSL_FATAL_ERROR;
07380         int       oldTimerOn = 0;   /* was timer already on */
07381         Timeval   startTime;
07382         Timeval   endTime;
07383         Timeval   totalTime;
07384         Itimerval myTimeout;
07385         Itimerval oldTimeout; /* if old timer adjust from total time to reset */
07386         struct sigaction act, oact;
07387 
07388         #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
07389 
07390         if (hsCb) {
07391             ssl->hsInfoOn = 1;
07392             InitHandShakeInfo(&ssl->handShakeInfo);
07393         }
07394         if (toCb) {
07395             ssl->toInfoOn = 1;
07396             InitTimeoutInfo(&ssl->timeoutInfo);
07397 
07398             if (gettimeofday(&startTime, 0) < 0)
07399                 ERR_OUT(GETTIME_ERROR);
07400 
07401             /* use setitimer to simulate getitimer, init 0 myTimeout */
07402             myTimeout.it_interval.tv_sec  = 0;
07403             myTimeout.it_interval.tv_usec = 0;
07404             myTimeout.it_value.tv_sec     = 0;
07405             myTimeout.it_value.tv_usec    = 0;
07406             if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
07407                 ERR_OUT(SETITIMER_ERROR);
07408 
07409             if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
07410                 oldTimerOn = 1;
07411 
07412                 /* is old timer going to expire before ours */
07413                 if (CmpTimes(oldTimeout.it_value, timeout, <)) {
07414                     timeout.tv_sec  = oldTimeout.it_value.tv_sec;
07415                     timeout.tv_usec = oldTimeout.it_value.tv_usec;
07416                 }
07417             }
07418             myTimeout.it_value.tv_sec  = timeout.tv_sec;
07419             myTimeout.it_value.tv_usec = timeout.tv_usec;
07420 
07421             /* set up signal handler, don't restart socket send/recv */
07422             act.sa_handler = myHandler;
07423             sigemptyset(&act.sa_mask);
07424             act.sa_flags = 0;
07425 #ifdef SA_INTERRUPT
07426             act.sa_flags |= SA_INTERRUPT;
07427 #endif
07428             if (sigaction(SIGALRM, &act, &oact) < 0)
07429                 ERR_OUT(SIGACT_ERROR);
07430 
07431             if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
07432                 ERR_OUT(SETITIMER_ERROR);
07433         }
07434 
07435         /* do main work */
07436 #ifndef NO_WOLFSSL_CLIENT
07437         if (ssl->options.side == WOLFSSL_CLIENT_END)
07438             ret = wolfSSL_connect(ssl);
07439 #endif
07440 #ifndef NO_WOLFSSL_SERVER
07441         if (ssl->options.side == WOLFSSL_SERVER_END)
07442             ret = wolfSSL_accept(ssl);
07443 #endif
07444 
07445         /* do callbacks */
07446         if (toCb) {
07447             if (oldTimerOn) {
07448                 gettimeofday(&endTime, 0);
07449                 SubtractTimes(endTime, startTime, totalTime);
07450                 /* adjust old timer for elapsed time */
07451                 if (CmpTimes(totalTime, oldTimeout.it_value, <))
07452                     SubtractTimes(oldTimeout.it_value, totalTime,
07453                                   oldTimeout.it_value);
07454                 else {
07455                     /* reset value to interval, may be off */
07456                     oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
07457                     oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
07458                 }
07459                 /* keep iter the same whether there or not */
07460             }
07461             /* restore old handler */
07462             if (sigaction(SIGALRM, &oact, 0) < 0)
07463                 ret = SIGACT_ERROR;    /* more pressing error, stomp */
07464             else
07465                 /* use old settings which may turn off (expired or not there) */
07466                 if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
07467                     ret = SETITIMER_ERROR;
07468 
07469             /* if we had a timeout call callback */
07470             if (ssl->timeoutInfo.timeoutName[0]) {
07471                 ssl->timeoutInfo.timeoutValue.tv_sec  = timeout.tv_sec;
07472                 ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
07473                 (toCb)(&ssl->timeoutInfo);
07474             }
07475             /* clean up */
07476             FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
07477             ssl->toInfoOn = 0;
07478         }
07479         if (hsCb) {
07480             FinishHandShakeInfo(&ssl->handShakeInfo, ssl);
07481             (hsCb)(&ssl->handShakeInfo);
07482             ssl->hsInfoOn = 0;
07483         }
07484         return ret;
07485     }
07486 
07487 
07488 #ifndef NO_WOLFSSL_CLIENT
07489 
07490     int wolfSSL_connect_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
07491                           TimeoutCallBack toCb, Timeval timeout)
07492     {
07493         WOLFSSL_ENTER("wolfSSL_connect_ex");
07494         return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
07495     }
07496 
07497 #endif
07498 
07499 
07500 #ifndef NO_WOLFSSL_SERVER
07501 
07502     int wolfSSL_accept_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
07503                          TimeoutCallBack toCb,Timeval timeout)
07504     {
07505         WOLFSSL_ENTER("wolfSSL_accept_ex");
07506         return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
07507     }
07508 
07509 #endif
07510 
07511 #endif /* WOLFSSL_CALLBACKS */
07512 
07513 
07514 #ifndef NO_PSK
07515 
07516     void wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX* ctx,
07517                                          wc_psk_client_callback cb)
07518     {
07519         WOLFSSL_ENTER("SSL_CTX_set_psk_client_callback");
07520         ctx->havePSK = 1;
07521         ctx->client_psk_cb = cb;
07522     }
07523 
07524 
07525     void wolfSSL_set_psk_client_callback(WOLFSSL* ssl,wc_psk_client_callback cb)
07526     {
07527         byte haveRSA = 1;
07528 
07529         WOLFSSL_ENTER("SSL_set_psk_client_callback");
07530         ssl->options.havePSK = 1;
07531         ssl->options.client_psk_cb = cb;
07532 
07533         #ifdef NO_RSA
07534             haveRSA = 0;
07535         #endif
07536         InitSuites(ssl->suites, ssl->version, haveRSA, TRUE,
07537                    ssl->options.haveDH, ssl->options.haveNTRU,
07538                    ssl->options.haveECDSAsig, ssl->options.haveECC,
07539                    ssl->options.haveStaticECC, ssl->options.side);
07540     }
07541 
07542 
07543     void wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX* ctx,
07544                                          wc_psk_server_callback cb)
07545     {
07546         WOLFSSL_ENTER("SSL_CTX_set_psk_server_callback");
07547         ctx->havePSK = 1;
07548         ctx->server_psk_cb = cb;
07549     }
07550 
07551 
07552     void wolfSSL_set_psk_server_callback(WOLFSSL* ssl,wc_psk_server_callback cb)
07553     {
07554         byte haveRSA = 1;
07555 
07556         WOLFSSL_ENTER("SSL_set_psk_server_callback");
07557         ssl->options.havePSK = 1;
07558         ssl->options.server_psk_cb = cb;
07559 
07560         #ifdef NO_RSA
07561             haveRSA = 0;
07562         #endif
07563         InitSuites(ssl->suites, ssl->version, haveRSA, TRUE,
07564                    ssl->options.haveDH, ssl->options.haveNTRU,
07565                    ssl->options.haveECDSAsig, ssl->options.haveECC,
07566                    ssl->options.haveStaticECC, ssl->options.side);
07567     }
07568 
07569 
07570     const char* wolfSSL_get_psk_identity_hint(const WOLFSSL* ssl)
07571     {
07572         WOLFSSL_ENTER("SSL_get_psk_identity_hint");
07573 
07574         if (ssl == NULL || ssl->arrays == NULL)
07575             return NULL;
07576 
07577         return ssl->arrays->server_hint;
07578     }
07579 
07580 
07581     const char* wolfSSL_get_psk_identity(const WOLFSSL* ssl)
07582     {
07583         WOLFSSL_ENTER("SSL_get_psk_identity");
07584 
07585         if (ssl == NULL || ssl->arrays == NULL)
07586             return NULL;
07587 
07588         return ssl->arrays->client_identity;
07589     }
07590 
07591 
07592     int wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX* ctx, const char* hint)
07593     {
07594         WOLFSSL_ENTER("SSL_CTX_use_psk_identity_hint");
07595         if (hint == 0)
07596             ctx->server_hint[0] = 0;
07597         else {
07598             XSTRNCPY(ctx->server_hint, hint, MAX_PSK_ID_LEN);
07599             ctx->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
07600         }
07601         return SSL_SUCCESS;
07602     }
07603 
07604 
07605     int wolfSSL_use_psk_identity_hint(WOLFSSL* ssl, const char* hint)
07606     {
07607         WOLFSSL_ENTER("SSL_use_psk_identity_hint");
07608 
07609         if (ssl == NULL || ssl->arrays == NULL)
07610             return SSL_FAILURE;
07611 
07612         if (hint == 0)
07613             ssl->arrays->server_hint[0] = 0;
07614         else {
07615             XSTRNCPY(ssl->arrays->server_hint, hint, MAX_PSK_ID_LEN);
07616             ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
07617         }
07618         return SSL_SUCCESS;
07619     }
07620 
07621 #endif /* NO_PSK */
07622 
07623 
07624 #ifdef HAVE_ANON
07625 
07626     int wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX* ctx)
07627     {
07628         WOLFSSL_ENTER("wolfSSL_CTX_allow_anon_cipher");
07629 
07630         if (ctx == NULL)
07631             return SSL_FAILURE;
07632 
07633         ctx->haveAnon = 1;
07634 
07635         return SSL_SUCCESS;
07636     }
07637 
07638 #endif /* HAVE_ANON */
07639 
07640 
07641 #ifndef NO_CERTS
07642 /* used to be defined on NO_FILESYSTEM only, but are generally useful */
07643 
07644     /* wolfSSL extension allows DER files to be loaded from buffers as well */
07645     int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX* ctx,
07646                                        const unsigned char* in,
07647                                        long sz, int format)
07648     {
07649         WOLFSSL_ENTER("wolfSSL_CTX_load_verify_buffer");
07650         if (format == SSL_FILETYPE_PEM)
07651             return ProcessChainBuffer(ctx, in, sz, format, CA_TYPE, NULL);
07652         else
07653             return ProcessBuffer(ctx, in, sz, format, CA_TYPE, NULL,NULL,0);
07654     }
07655 
07656 
07657 #ifdef WOLFSSL_TRUST_PEER_CERT
07658     int wolfSSL_CTX_trust_peer_buffer(WOLFSSL_CTX* ctx,
07659                                        const unsigned char* in,
07660                                        long sz, int format)
07661     {
07662         WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_buffer");
07663 
07664         /* sanity check on arguments */
07665         if (sz < 0 || in == NULL || ctx == NULL) {
07666             return BAD_FUNC_ARG;
07667         }
07668 
07669         if (format == SSL_FILETYPE_PEM)
07670             return ProcessChainBuffer(ctx, in, sz, format,
07671                                                        TRUSTED_PEER_TYPE, NULL);
07672         else
07673             return ProcessBuffer(ctx, in, sz, format, TRUSTED_PEER_TYPE,
07674                                                                    NULL,NULL,0);
07675     }
07676 #endif /* WOLFSSL_TRUST_PEER_CERT */
07677 
07678 
07679     int wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX* ctx,
07680                                  const unsigned char* in, long sz, int format)
07681     {
07682         WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_buffer");
07683         return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 0);
07684     }
07685 
07686 
07687     int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX* ctx,
07688                                  const unsigned char* in, long sz, int format)
07689     {
07690         WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_buffer");
07691         return ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL,NULL,0);
07692     }
07693 
07694 
07695     int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
07696                                  const unsigned char* in, long sz)
07697     {
07698         WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_buffer");
07699         return ProcessBuffer(ctx, in, sz, SSL_FILETYPE_PEM, CERT_TYPE, NULL,
07700                              NULL, 1);
07701     }
07702 
07703 
07704 #ifndef NO_DH
07705 
07706     /* server wrapper for ctx or ssl Diffie-Hellman parameters */
07707     static int wolfSSL_SetTmpDH_buffer_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
07708                                                const unsigned char* buf,
07709                                                long sz, int format)
07710     {
07711         DerBuffer* der = NULL;
07712         int    ret      = 0;
07713         word32 pSz = MAX_DH_SIZE;
07714         word32 gSz = MAX_DH_SIZE;
07715     #ifdef WOLFSSL_SMALL_STACK
07716         byte*  p = NULL;
07717         byte*  g = NULL;
07718     #else
07719         byte   p[MAX_DH_SIZE];
07720         byte   g[MAX_DH_SIZE];
07721     #endif
07722 
07723         if (ctx == NULL || buf == NULL)
07724             return BAD_FUNC_ARG;
07725 
07726         ret = AllocDer(&der, 0, DH_PARAM_TYPE, ctx->heap);
07727         if (ret != 0) {
07728             return ret;
07729         }
07730         der->buffer = (byte*)buf;
07731         der->length = (word32)sz;
07732 
07733     #ifdef WOLFSSL_SMALL_STACK
07734         p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07735         g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07736 
07737         if (p == NULL || g == NULL) {
07738             XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07739             XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07740             return MEMORY_E;
07741         }
07742     #endif
07743 
07744         if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM)
07745             ret = SSL_BAD_FILETYPE;
07746         else {
07747             if (format == SSL_FILETYPE_PEM) {
07748                 FreeDer(&der);
07749                 ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap,
07750                                NULL, NULL);
07751             }
07752 
07753             if (ret == 0) {
07754                 if (wc_DhParamsLoad(der->buffer, der->length, p, &pSz, g, &gSz) < 0)
07755                     ret = SSL_BAD_FILETYPE;
07756                 else if (ssl)
07757                     ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
07758                 else
07759                     ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
07760             }
07761         }
07762 
07763         FreeDer(&der);
07764 
07765     #ifdef WOLFSSL_SMALL_STACK
07766         XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07767         XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07768     #endif
07769 
07770         return ret;
07771     }
07772 
07773 
07774     /* server Diffie-Hellman parameters, SSL_SUCCESS on ok */
07775     int wolfSSL_SetTmpDH_buffer(WOLFSSL* ssl, const unsigned char* buf, long sz,
07776                                int format)
07777     {
07778         if (ssl == NULL)
07779             return BAD_FUNC_ARG;
07780 
07781         return wolfSSL_SetTmpDH_buffer_wrapper(ssl->ctx, ssl, buf, sz, format);
07782     }
07783 
07784 
07785     /* server ctx Diffie-Hellman parameters, SSL_SUCCESS on ok */
07786     int wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX* ctx, const unsigned char* buf,
07787                                    long sz, int format)
07788     {
07789         return wolfSSL_SetTmpDH_buffer_wrapper(ctx, NULL, buf, sz, format);
07790     }
07791 
07792 #endif /* NO_DH */
07793 
07794 
07795     int wolfSSL_use_certificate_buffer(WOLFSSL* ssl,
07796                                  const unsigned char* in, long sz, int format)
07797     {
07798         WOLFSSL_ENTER("wolfSSL_use_certificate_buffer");
07799         return ProcessBuffer(ssl->ctx, in, sz, format,CERT_TYPE,ssl,NULL,0);
07800     }
07801 
07802 
07803     int wolfSSL_use_PrivateKey_buffer(WOLFSSL* ssl,
07804                                  const unsigned char* in, long sz, int format)
07805     {
07806         WOLFSSL_ENTER("wolfSSL_use_PrivateKey_buffer");
07807         return ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE,
07808                              ssl, NULL, 0);
07809     }
07810 
07811 
07812     int wolfSSL_use_certificate_chain_buffer(WOLFSSL* ssl,
07813                                  const unsigned char* in, long sz)
07814     {
07815         WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer");
07816         return ProcessBuffer(ssl->ctx, in, sz, SSL_FILETYPE_PEM, CERT_TYPE,
07817                              ssl, NULL, 1);
07818     }
07819 
07820 
07821     /* unload any certs or keys that SSL owns, leave CTX as is
07822        SSL_SUCCESS on ok */
07823     int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl)
07824     {
07825         if (ssl == NULL) {
07826             WOLFSSL_MSG("Null function arg");
07827             return BAD_FUNC_ARG;
07828         }
07829 
07830         if (ssl->buffers.weOwnCert) {
07831             WOLFSSL_MSG("Unloading cert");
07832             FreeDer(&ssl->buffers.certificate);
07833             ssl->buffers.weOwnCert = 0;
07834         }
07835 
07836         if (ssl->buffers.weOwnCertChain) {
07837             WOLFSSL_MSG("Unloading cert chain");
07838             FreeDer(&ssl->buffers.certChain);
07839             ssl->buffers.weOwnCertChain = 0;
07840         }
07841 
07842         if (ssl->buffers.weOwnKey) {
07843             WOLFSSL_MSG("Unloading key");
07844             FreeDer(&ssl->buffers.key);
07845             ssl->buffers.weOwnKey = 0;
07846         }
07847 
07848         return SSL_SUCCESS;
07849     }
07850 
07851 
07852     int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx)
07853     {
07854         WOLFSSL_ENTER("wolfSSL_CTX_UnloadCAs");
07855 
07856         if (ctx == NULL)
07857             return BAD_FUNC_ARG;
07858 
07859         return wolfSSL_CertManagerUnloadCAs(ctx->cm);
07860     }
07861 
07862 
07863 #ifdef WOLFSSL_TRUST_PEER_CERT
07864     int wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX* ctx)
07865     {
07866         WOLFSSL_ENTER("wolfSSL_CTX_Unload_trust_peers");
07867 
07868         if (ctx == NULL)
07869             return BAD_FUNC_ARG;
07870 
07871         return wolfSSL_CertManagerUnload_trust_peers(ctx->cm);
07872     }
07873 #endif /* WOLFSSL_TRUST_PEER_CERT */
07874 /* old NO_FILESYSTEM end */
07875 #endif /* !NO_CERTS */
07876 
07877 
07878 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
07879 
07880 
07881     int wolfSSL_add_all_algorithms(void)
07882     {
07883         WOLFSSL_ENTER("wolfSSL_add_all_algorithms");
07884         if (wolfSSL_Init() == SSL_SUCCESS)
07885             return SSL_SUCCESS;
07886         else
07887             return SSL_FATAL_ERROR;
07888     }
07889 
07890 
07891     long wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX* ctx, long sz)
07892     {
07893         /* cache size fixed at compile time in wolfSSL */
07894         (void)ctx;
07895         (void)sz;
07896         return 0;
07897     }
07898 
07899 
07900     void wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX* ctx, int mode)
07901     {
07902         WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
07903         if (mode)
07904             ctx->quietShutdown = 1;
07905     }
07906 
07907 
07908     void wolfSSL_set_quiet_shutdown(WOLFSSL* ssl, int mode)
07909     {
07910         WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
07911         if (mode)
07912             ssl->options.quietShutdown = 1;
07913     }
07914 
07915 
07916     void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr)
07917     {
07918         WOLFSSL_ENTER("SSL_set_bio");
07919         wolfSSL_set_rfd(ssl, rd->fd);
07920         wolfSSL_set_wfd(ssl, wr->fd);
07921 
07922         ssl->biord = rd;
07923         ssl->biowr = wr;
07924     }
07925 
07926 
07927     void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX* ctx,
07928                                        STACK_OF(WOLFSSL_X509_NAME)* names)
07929     {
07930         (void)ctx;
07931         (void)names;
07932     }
07933 
07934 
07935     STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char* fname)
07936     {
07937         (void)fname;
07938         return 0;
07939     }
07940 
07941 
07942     int wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX* ctx)
07943     {
07944         /* TODO:, not needed in goahead */
07945         (void)ctx;
07946         return SSL_NOT_IMPLEMENTED;
07947     }
07948 
07949 
07950     /* keyblock size in bytes or -1 */
07951     int wolfSSL_get_keyblock_size(WOLFSSL* ssl)
07952     {
07953         if (ssl == NULL)
07954             return SSL_FATAL_ERROR;
07955 
07956         return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
07957                     ssl->specs.hash_size);
07958     }
07959 
07960 
07961     /* store keys returns SSL_SUCCESS or -1 on error */
07962     int wolfSSL_get_keys(WOLFSSL* ssl, unsigned char** ms, unsigned int* msLen,
07963                                      unsigned char** sr, unsigned int* srLen,
07964                                      unsigned char** cr, unsigned int* crLen)
07965     {
07966         if (ssl == NULL || ssl->arrays == NULL)
07967             return SSL_FATAL_ERROR;
07968 
07969         *ms = ssl->arrays->masterSecret;
07970         *sr = ssl->arrays->serverRandom;
07971         *cr = ssl->arrays->clientRandom;
07972 
07973         *msLen = SECRET_LEN;
07974         *srLen = RAN_LEN;
07975         *crLen = RAN_LEN;
07976 
07977         return SSL_SUCCESS;
07978     }
07979 
07980 
07981     void wolfSSL_set_accept_state(WOLFSSL* ssl)
07982     {
07983         word16 haveRSA = 1;
07984         word16 havePSK = 0;
07985 
07986         WOLFSSL_ENTER("SSL_set_accept_state");
07987         ssl->options.side = WOLFSSL_SERVER_END;
07988         /* reset suites in case user switched */
07989 
07990         #ifdef NO_RSA
07991             haveRSA = 0;
07992         #endif
07993         #ifndef NO_PSK
07994             havePSK = ssl->options.havePSK;
07995         #endif
07996         InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
07997                    ssl->options.haveDH, ssl->options.haveNTRU,
07998                    ssl->options.haveECDSAsig, ssl->options.haveECC,
07999                    ssl->options.haveStaticECC, ssl->options.side);
08000     }
08001 #endif
08002 
08003     /* return true if connection established */
08004     int wolfSSL_is_init_finished(WOLFSSL* ssl)
08005     {
08006         if (ssl == NULL)
08007             return 0;
08008 
08009         if (ssl->options.handShakeState == HANDSHAKE_DONE)
08010             return 1;
08011 
08012         return 0;
08013     }
08014 
08015 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
08016     void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX* ctx,
08017                                       WOLFSSL_RSA*(*f)(WOLFSSL*, int, int))
08018     {
08019         /* wolfSSL verifies all these internally */
08020         (void)ctx;
08021         (void)f;
08022     }
08023 
08024 
08025     void wolfSSL_set_shutdown(WOLFSSL* ssl, int opt)
08026     {
08027         WOLFSSL_ENTER("wolfSSL_set_shutdown");
08028         if(ssl==NULL) {
08029             WOLFSSL_MSG("Shutdown not set. ssl is null");
08030             return;
08031         }
08032 
08033         ssl->options.sentNotify =  (opt&SSL_SENT_SHUTDOWN) > 0;
08034         ssl->options.closeNotify = (opt&SSL_RECEIVED_SHUTDOWN) > 0;
08035     }
08036 
08037 
08038     long wolfSSL_CTX_set_options(WOLFSSL_CTX* ctx, long opt)
08039     {
08040         /* goahead calls with 0, do nothing */
08041         WOLFSSL_ENTER("SSL_CTX_set_options");
08042         (void)ctx;
08043         return opt;
08044     }
08045 
08046 
08047     int wolfSSL_set_rfd(WOLFSSL* ssl, int rfd)
08048     {
08049         WOLFSSL_ENTER("SSL_set_rfd");
08050         ssl->rfd = rfd;      /* not used directly to allow IO callbacks */
08051 
08052         ssl->IOCB_ReadCtx  = &ssl->rfd;
08053 
08054         return SSL_SUCCESS;
08055     }
08056 
08057 
08058     int wolfSSL_set_wfd(WOLFSSL* ssl, int wfd)
08059     {
08060         WOLFSSL_ENTER("SSL_set_wfd");
08061         ssl->wfd = wfd;      /* not used directly to allow IO callbacks */
08062 
08063         ssl->IOCB_WriteCtx  = &ssl->wfd;
08064 
08065         return SSL_SUCCESS;
08066     }
08067 
08068 
08069     WOLFSSL_RSA* wolfSSL_RSA_generate_key(int len, unsigned long bits,
08070                                           void(*f)(int, int, void*), void* data)
08071     {
08072         /* no tmp key needed, actual generation not supported */
08073         WOLFSSL_ENTER("RSA_generate_key");
08074         (void)len;
08075         (void)bits;
08076         (void)f;
08077         (void)data;
08078         return NULL;
08079     }
08080 
08081 
08082 
08083     WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get_current_cert(
08084                                                     WOLFSSL_X509_STORE_CTX* ctx)
08085     {
08086         WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_current_cert");
08087         if(ctx)
08088             return ctx->current_cert;
08089         return NULL;
08090     }
08091 
08092 
08093     int wolfSSL_X509_STORE_CTX_get_error(WOLFSSL_X509_STORE_CTX* ctx)
08094     {
08095         WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error");
08096         if (ctx != NULL)
08097             return ctx->error;
08098         return 0;
08099     }
08100 
08101 
08102     int wolfSSL_X509_STORE_CTX_get_error_depth(WOLFSSL_X509_STORE_CTX* ctx)
08103     {
08104         WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error_depth");
08105         if(ctx)
08106             return ctx->error_depth;
08107         return SSL_FATAL_ERROR;
08108     }
08109 
08110 
08111     WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_buffer(void)
08112     {
08113         static WOLFSSL_BIO_METHOD meth;
08114 
08115         WOLFSSL_ENTER("BIO_f_buffer");
08116         meth.type = BIO_BUFFER;
08117 
08118         return &meth;
08119     }
08120 
08121 
08122     long wolfSSL_BIO_set_write_buffer_size(WOLFSSL_BIO* bio, long size)
08123     {
08124         /* wolfSSL has internal buffer, compatibility only */
08125         WOLFSSL_ENTER("BIO_set_write_buffer_size");
08126         (void)bio;
08127         return size;
08128     }
08129 
08130 
08131     WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_ssl(void)
08132     {
08133         static WOLFSSL_BIO_METHOD meth;
08134 
08135         WOLFSSL_ENTER("BIO_f_ssl");
08136         meth.type = BIO_SSL;
08137 
08138         return &meth;
08139     }
08140 
08141 
08142     WOLFSSL_BIO* wolfSSL_BIO_new_socket(int sfd, int closeF)
08143     {
08144         WOLFSSL_BIO* bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0,
08145                                                 DYNAMIC_TYPE_OPENSSL);
08146 
08147         WOLFSSL_ENTER("BIO_new_socket");
08148         if (bio) {
08149             bio->type  = BIO_SOCKET;
08150             bio->close = (byte)closeF;
08151             bio->eof   = 0;
08152             bio->ssl   = 0;
08153             bio->fd    = sfd;
08154             bio->prev  = 0;
08155             bio->next  = 0;
08156             bio->mem   = NULL;
08157             bio->memLen = 0;
08158         }
08159         return bio;
08160     }
08161 
08162 
08163     int wolfSSL_BIO_eof(WOLFSSL_BIO* b)
08164     {
08165         WOLFSSL_ENTER("BIO_eof");
08166         if (b->eof)
08167             return 1;
08168 
08169         return 0;
08170     }
08171 
08172 
08173     long wolfSSL_BIO_set_ssl(WOLFSSL_BIO* b, WOLFSSL* ssl, int closeF)
08174     {
08175         WOLFSSL_ENTER("BIO_set_ssl");
08176         b->ssl   = ssl;
08177         b->close = (byte)closeF;
08178     /* add to ssl for bio free if SSL_free called before/instead of free_all? */
08179 
08180         return 0;
08181     }
08182 
08183 
08184     WOLFSSL_BIO* wolfSSL_BIO_new(WOLFSSL_BIO_METHOD* method)
08185     {
08186         WOLFSSL_BIO* bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0,
08187                                                 DYNAMIC_TYPE_OPENSSL);
08188         WOLFSSL_ENTER("BIO_new");
08189         if (bio) {
08190             bio->type   = method->type;
08191             bio->close  = 0;
08192             bio->eof    = 0;
08193             bio->ssl    = NULL;
08194             bio->mem    = NULL;
08195             bio->memLen = 0;
08196             bio->fd     = 0;
08197             bio->prev   = NULL;
08198             bio->next   = NULL;
08199         }
08200         return bio;
08201     }
08202 
08203 
08204     int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, const byte** p)
08205     {
08206         if (bio == NULL || p == NULL)
08207             return SSL_FATAL_ERROR;
08208 
08209         *p = bio->mem;
08210 
08211         return bio->memLen;
08212     }
08213 
08214 
08215     WOLFSSL_BIO* wolfSSL_BIO_new_mem_buf(void* buf, int len)
08216     {
08217         WOLFSSL_BIO* bio = NULL;
08218         if (buf == NULL)
08219             return bio;
08220 
08221         bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
08222         if (bio == NULL)
08223             return bio;
08224 
08225         bio->memLen = len;
08226         bio->mem    = (byte*)XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL);
08227         if (bio->mem == NULL) {
08228             XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
08229             return NULL;
08230         }
08231 
08232         XMEMCPY(bio->mem, buf, len);
08233 
08234         return bio;
08235     }
08236 
08237 
08238 #ifdef USE_WINDOWS_API
08239     #define CloseSocket(s) closesocket(s)
08240 #elif defined(WOLFSSL_MDK_ARM)  || defined(WOLFSSL_KEIL_TCP_NET)
08241     #define CloseSocket(s) closesocket(s)
08242     extern int closesocket(int) ;
08243 #else
08244     #define CloseSocket(s) close(s)
08245 #endif
08246 
08247     int wolfSSL_BIO_free(WOLFSSL_BIO* bio)
08248     {
08249         /* unchain?, doesn't matter in goahead since from free all */
08250         WOLFSSL_ENTER("BIO_free");
08251         if (bio) {
08252             if (bio->close) {
08253                 if (bio->ssl)
08254                     wolfSSL_free(bio->ssl);
08255                 if (bio->fd)
08256                     CloseSocket(bio->fd);
08257             }
08258             if (bio->mem)
08259                 XFREE(bio->mem, 0, DYNAMIC_TYPE_OPENSSL);
08260             XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
08261         }
08262         return 0;
08263     }
08264 
08265 
08266     int wolfSSL_BIO_free_all(WOLFSSL_BIO* bio)
08267     {
08268         WOLFSSL_ENTER("BIO_free_all");
08269         while (bio) {
08270             WOLFSSL_BIO* next = bio->next;
08271             wolfSSL_BIO_free(bio);
08272             bio = next;
08273         }
08274         return 0;
08275     }
08276 
08277 
08278     int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
08279     {
08280         int  ret;
08281         WOLFSSL* ssl = 0;
08282         WOLFSSL_BIO* front = bio;
08283 
08284         WOLFSSL_ENTER("BIO_read");
08285         /* already got eof, again is error */
08286         if (front->eof)
08287             return SSL_FATAL_ERROR;
08288 
08289         while(bio && ((ssl = bio->ssl) == 0) )
08290             bio = bio->next;
08291 
08292         if (ssl == 0) return BAD_FUNC_ARG;
08293 
08294         ret = wolfSSL_read(ssl, buf, len);
08295         if (ret == 0)
08296             front->eof = 1;
08297         else if (ret < 0) {
08298             int err = wolfSSL_get_error(ssl, 0);
08299             if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
08300                 front->eof = 1;
08301         }
08302         return ret;
08303     }
08304 
08305 
08306     int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
08307     {
08308         int  ret;
08309         WOLFSSL* ssl = 0;
08310         WOLFSSL_BIO* front = bio;
08311 
08312         WOLFSSL_ENTER("BIO_write");
08313         /* already got eof, again is error */
08314         if (front->eof)
08315             return SSL_FATAL_ERROR;
08316 
08317         while(bio && ((ssl = bio->ssl) == 0) )
08318             bio = bio->next;
08319 
08320         if (ssl == 0) return BAD_FUNC_ARG;
08321 
08322         ret = wolfSSL_write(ssl, data, len);
08323         if (ret == 0)
08324             front->eof = 1;
08325         else if (ret < 0) {
08326             int err = wolfSSL_get_error(ssl, 0);
08327             if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
08328                 front->eof = 1;
08329         }
08330 
08331         return ret;
08332     }
08333 
08334 
08335     WOLFSSL_BIO* wolfSSL_BIO_push(WOLFSSL_BIO* top, WOLFSSL_BIO* append)
08336     {
08337         WOLFSSL_ENTER("BIO_push");
08338         top->next    = append;
08339         append->prev = top;
08340 
08341         return top;
08342     }
08343 
08344 
08345     int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
08346     {
08347         /* for wolfSSL no flushing needed */
08348         WOLFSSL_ENTER("BIO_flush");
08349         (void)bio;
08350         return 1;
08351     }
08352 
08353 
08354 #endif /* OPENSSL_EXTRA || GOAHEAD_WS */
08355 
08356 
08357 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
08358 
08359     void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX* ctx,
08360                                                    void* userdata)
08361     {
08362         WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb_userdata");
08363         ctx->userdata = userdata;
08364     }
08365 
08366 
08367     void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX* ctx, pem_password_cb cb)
08368     {
08369         WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb");
08370         ctx->passwd_cb = cb;
08371     }
08372 
08373     int wolfSSL_num_locks(void)
08374     {
08375         return 0;
08376     }
08377 
08378     void wolfSSL_set_locking_callback(void (*f)(int, int, const char*, int))
08379     {
08380         (void)f;
08381     }
08382 
08383     void wolfSSL_set_id_callback(unsigned long (*f)(void))
08384     {
08385         (void)f;
08386     }
08387 
08388     unsigned long wolfSSL_ERR_get_error(void)
08389     {
08390         /* TODO: */
08391         return 0;
08392     }
08393 
08394 #ifndef NO_MD5
08395 
08396     int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER* type,
08397                        const WOLFSSL_EVP_MD* md, const byte* salt,
08398                        const byte* data, int sz, int count, byte* key, byte* iv)
08399     {
08400         int  keyLen = 0;
08401         int  ivLen  = 0;
08402         int  j;
08403         int  keyLeft;
08404         int  ivLeft;
08405         int  keyOutput = 0;
08406         byte digest[MD5_DIGEST_SIZE];
08407     #ifdef WOLFSSL_SMALL_STACK
08408         Md5* md5 = NULL;
08409     #else
08410         Md5  md5[1];
08411     #endif
08412 
08413     #ifdef WOLFSSL_SMALL_STACK
08414         md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
08415         if (md5 == NULL)
08416             return 0;
08417     #endif
08418 
08419         WOLFSSL_ENTER("wolfSSL_EVP_BytesToKey");
08420         wc_InitMd5(md5);
08421 
08422         /* only support MD5 for now */
08423         if (XSTRNCMP(md, "MD5", 3) != 0) return 0;
08424 
08425         /* only support CBC DES and AES for now */
08426         if (XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0) {
08427             keyLen = DES_KEY_SIZE;
08428             ivLen  = DES_IV_SIZE;
08429         }
08430         else if (XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0) {
08431             keyLen = DES3_KEY_SIZE;
08432             ivLen  = DES_IV_SIZE;
08433         }
08434         else if (XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0) {
08435             keyLen = AES_128_KEY_SIZE;
08436             ivLen  = AES_IV_SIZE;
08437         }
08438         else if (XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0) {
08439             keyLen = AES_192_KEY_SIZE;
08440             ivLen  = AES_IV_SIZE;
08441         }
08442         else if (XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0) {
08443             keyLen = AES_256_KEY_SIZE;
08444             ivLen  = AES_IV_SIZE;
08445         }
08446         else {
08447         #ifdef WOLFSSL_SMALL_STACK
08448             XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08449         #endif
08450             return 0;
08451         }
08452 
08453         keyLeft   = keyLen;
08454         ivLeft    = ivLen;
08455 
08456         while (keyOutput < (keyLen + ivLen)) {
08457             int digestLeft = MD5_DIGEST_SIZE;
08458             /* D_(i - 1) */
08459             if (keyOutput)                      /* first time D_0 is empty */
08460                 wc_Md5Update(md5, digest, MD5_DIGEST_SIZE);
08461             /* data */
08462             wc_Md5Update(md5, data, sz);
08463             /* salt */
08464             if (salt)
08465                 wc_Md5Update(md5, salt, EVP_SALT_SIZE);
08466             wc_Md5Final(md5, digest);
08467             /* count */
08468             for (j = 1; j < count; j++) {
08469                 wc_Md5Update(md5, digest, MD5_DIGEST_SIZE);
08470                 wc_Md5Final(md5, digest);
08471             }
08472 
08473             if (keyLeft) {
08474                 int store = min(keyLeft, MD5_DIGEST_SIZE);
08475                 XMEMCPY(&key[keyLen - keyLeft], digest, store);
08476 
08477                 keyOutput  += store;
08478                 keyLeft    -= store;
08479                 digestLeft -= store;
08480             }
08481 
08482             if (ivLeft && digestLeft) {
08483                 int store = min(ivLeft, digestLeft);
08484                 if (iv != NULL)
08485                     XMEMCPY(&iv[ivLen - ivLeft],
08486                             &digest[MD5_DIGEST_SIZE - digestLeft], store);
08487                 keyOutput += store;
08488                 ivLeft    -= store;
08489             }
08490         }
08491 
08492     #ifdef WOLFSSL_SMALL_STACK
08493         XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08494     #endif
08495 
08496         return keyOutput == (keyLen + ivLen) ? keyOutput : 0;
08497     }
08498 
08499 #endif /* NO_MD5 */
08500 
08501 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
08502 
08503 
08504 #ifdef OPENSSL_EXTRA
08505 
08506     unsigned long wolfSSLeay(void)
08507     {
08508         return SSLEAY_VERSION_NUMBER;
08509     }
08510 
08511 
08512     const char* wolfSSLeay_version(int type)
08513     {
08514         static const char* version = "SSLeay wolfSSL compatibility";
08515         (void)type;
08516         return version;
08517     }
08518 
08519 
08520 #ifndef NO_MD5
08521     void wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5)
08522     {
08523         typedef char md5_test[sizeof(MD5_CTX) >= sizeof(Md5) ? 1 : -1];
08524         (void)sizeof(md5_test);
08525 
08526         WOLFSSL_ENTER("MD5_Init");
08527         wc_InitMd5((Md5*)md5);
08528     }
08529 
08530 
08531     void wolfSSL_MD5_Update(WOLFSSL_MD5_CTX* md5, const void* input,
08532                            unsigned long sz)
08533     {
08534         WOLFSSL_ENTER("wolfSSL_MD5_Update");
08535         wc_Md5Update((Md5*)md5, (const byte*)input, (word32)sz);
08536     }
08537 
08538 
08539     void wolfSSL_MD5_Final(byte* input, WOLFSSL_MD5_CTX* md5)
08540     {
08541         WOLFSSL_ENTER("MD5_Final");
08542         wc_Md5Final((Md5*)md5, input);
08543     }
08544 #endif /* NO_MD5 */
08545 
08546 
08547 #ifndef NO_SHA
08548     void wolfSSL_SHA_Init(WOLFSSL_SHA_CTX* sha)
08549     {
08550         typedef char sha_test[sizeof(SHA_CTX) >= sizeof(Sha) ? 1 : -1];
08551         (void)sizeof(sha_test);
08552 
08553         WOLFSSL_ENTER("SHA_Init");
08554         wc_InitSha((Sha*)sha);  /* OpenSSL compat, no ret */
08555     }
08556 
08557 
08558     void wolfSSL_SHA_Update(WOLFSSL_SHA_CTX* sha, const void* input,
08559                            unsigned long sz)
08560     {
08561         WOLFSSL_ENTER("SHA_Update");
08562         wc_ShaUpdate((Sha*)sha, (const byte*)input, (word32)sz);
08563     }
08564 
08565 
08566     void wolfSSL_SHA_Final(byte* input, WOLFSSL_SHA_CTX* sha)
08567     {
08568         WOLFSSL_ENTER("SHA_Final");
08569         wc_ShaFinal((Sha*)sha, input);
08570     }
08571 
08572 
08573     void wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX* sha)
08574     {
08575         WOLFSSL_ENTER("SHA1_Init");
08576         SHA_Init(sha);
08577     }
08578 
08579 
08580     void wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX* sha, const void* input,
08581                             unsigned long sz)
08582     {
08583         WOLFSSL_ENTER("SHA1_Update");
08584         SHA_Update(sha, input, sz);
08585     }
08586 
08587 
08588     void wolfSSL_SHA1_Final(byte* input, WOLFSSL_SHA_CTX* sha)
08589     {
08590         WOLFSSL_ENTER("SHA1_Final");
08591         SHA_Final(input, sha);
08592     }
08593 #endif /* NO_SHA */
08594 
08595 
08596     void wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX* sha256)
08597     {
08598         typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(Sha256) ? 1 : -1];
08599         (void)sizeof(sha_test);
08600 
08601         WOLFSSL_ENTER("SHA256_Init");
08602         wc_InitSha256((Sha256*)sha256);  /* OpenSSL compat, no error */
08603     }
08604 
08605 
08606     void wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX* sha, const void* input,
08607                               unsigned long sz)
08608     {
08609         WOLFSSL_ENTER("SHA256_Update");
08610         wc_Sha256Update((Sha256*)sha, (const byte*)input, (word32)sz);
08611         /* OpenSSL compat, no error */
08612     }
08613 
08614 
08615     void wolfSSL_SHA256_Final(byte* input, WOLFSSL_SHA256_CTX* sha)
08616     {
08617         WOLFSSL_ENTER("SHA256_Final");
08618         wc_Sha256Final((Sha256*)sha, input);
08619         /* OpenSSL compat, no error */
08620     }
08621 
08622 
08623     #ifdef WOLFSSL_SHA384
08624 
08625     void wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX* sha)
08626     {
08627         typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(Sha384) ? 1 : -1];
08628         (void)sizeof(sha_test);
08629 
08630         WOLFSSL_ENTER("SHA384_Init");
08631         wc_InitSha384((Sha384*)sha);   /* OpenSSL compat, no error */
08632     }
08633 
08634 
08635     void wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX* sha, const void* input,
08636                            unsigned long sz)
08637     {
08638         WOLFSSL_ENTER("SHA384_Update");
08639         wc_Sha384Update((Sha384*)sha, (const byte*)input, (word32)sz);
08640         /* OpenSSL compat, no error */
08641     }
08642 
08643 
08644     void wolfSSL_SHA384_Final(byte* input, WOLFSSL_SHA384_CTX* sha)
08645     {
08646         WOLFSSL_ENTER("SHA384_Final");
08647         wc_Sha384Final((Sha384*)sha, input);
08648         /* OpenSSL compat, no error */
08649     }
08650 
08651     #endif /* WOLFSSL_SHA384 */
08652 
08653 
08654    #ifdef WOLFSSL_SHA512
08655 
08656     void wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha)
08657     {
08658         typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(Sha512) ? 1 : -1];
08659         (void)sizeof(sha_test);
08660 
08661         WOLFSSL_ENTER("SHA512_Init");
08662         wc_InitSha512((Sha512*)sha);  /* OpenSSL compat, no error */
08663     }
08664 
08665 
08666     void wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX* sha, const void* input,
08667                            unsigned long sz)
08668     {
08669         WOLFSSL_ENTER("SHA512_Update");
08670         wc_Sha512Update((Sha512*)sha, (const byte*)input, (word32)sz);
08671         /* OpenSSL compat, no error */
08672     }
08673 
08674 
08675     void wolfSSL_SHA512_Final(byte* input, WOLFSSL_SHA512_CTX* sha)
08676     {
08677         WOLFSSL_ENTER("SHA512_Final");
08678         wc_Sha512Final((Sha512*)sha, input);
08679         /* OpenSSL compat, no error */
08680     }
08681 
08682     #endif /* WOLFSSL_SHA512 */
08683 
08684 
08685     #ifndef NO_MD5
08686 
08687     const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void)
08688     {
08689         static const char* type = "MD5";
08690         WOLFSSL_ENTER("EVP_md5");
08691         return type;
08692     }
08693 
08694     #endif /* NO_MD5 */
08695 
08696 
08697 #ifndef NO_SHA
08698     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void)
08699     {
08700         static const char* type = "SHA";
08701         WOLFSSL_ENTER("EVP_sha1");
08702         return type;
08703     }
08704 #endif /* NO_SHA */
08705 
08706 
08707     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void)
08708     {
08709         static const char* type = "SHA256";
08710         WOLFSSL_ENTER("EVP_sha256");
08711         return type;
08712     }
08713 
08714     #ifdef WOLFSSL_SHA384
08715 
08716     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void)
08717     {
08718         static const char* type = "SHA384";
08719         WOLFSSL_ENTER("EVP_sha384");
08720         return type;
08721     }
08722 
08723     #endif /* WOLFSSL_SHA384 */
08724 
08725     #ifdef WOLFSSL_SHA512
08726 
08727     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void)
08728     {
08729         static const char* type = "SHA512";
08730         WOLFSSL_ENTER("EVP_sha512");
08731         return type;
08732     }
08733 
08734     #endif /* WOLFSSL_SHA512 */
08735 
08736 
08737     void wolfSSL_EVP_MD_CTX_init(WOLFSSL_EVP_MD_CTX* ctx)
08738     {
08739         WOLFSSL_ENTER("EVP_CIPHER_MD_CTX_init");
08740         (void)ctx;
08741         /* do nothing */
08742     }
08743 
08744     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void)
08745     {
08746         WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cbc");
08747         return EVP_AES_128_CBC;
08748     }
08749 
08750 
08751     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void)
08752     {
08753         WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cbc");
08754         return EVP_AES_192_CBC;
08755     }
08756 
08757 
08758     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void)
08759     {
08760         WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cbc");
08761         return EVP_AES_256_CBC;
08762     }
08763 
08764 
08765     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void)
08766     {
08767         WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ctr");
08768         return EVP_AES_128_CTR;
08769     }
08770 
08771 
08772     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void)
08773     {
08774         WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ctr");
08775         return EVP_AES_192_CTR;
08776     }
08777 
08778 
08779     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void)
08780     {
08781         WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ctr");
08782         return EVP_AES_256_CTR;
08783     }
08784 
08785 
08786     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void)
08787     {
08788         WOLFSSL_ENTER("wolfSSL_EVP_des_cbc");
08789         return EVP_DES_CBC;
08790     }
08791 
08792 
08793     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void)
08794     {
08795         WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_cbc");
08796         return EVP_DES_EDE3_CBC;
08797     }
08798 
08799 
08800     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc4(void)
08801     {
08802         static const char* type = "ARC4";
08803         WOLFSSL_ENTER("wolfSSL_EVP_rc4");
08804         return type;
08805     }
08806 
08807 #ifdef HAVE_IDEA
08808     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_idea_cbc(void)
08809     {
08810         WOLFSSL_ENTER("wolfSSL_EVP_idea_cbc");
08811         return EVP_IDEA_CBC;
08812     }
08813 #endif
08814     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void)
08815     {
08816         static const char* type = "NULL";
08817         WOLFSSL_ENTER("wolfSSL_EVP_enc_null");
08818         return type;
08819     }
08820 
08821 
08822     int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx)
08823     {
08824         WOLFSSL_ENTER("EVP_MD_CTX_cleanup");
08825         (void)ctx;
08826         return 0;
08827     }
08828 
08829 
08830 
08831     void wolfSSL_EVP_CIPHER_CTX_init(WOLFSSL_EVP_CIPHER_CTX* ctx)
08832     {
08833         WOLFSSL_ENTER("EVP_CIPHER_CTX_init");
08834         if (ctx) {
08835             ctx->cipherType = 0xff;   /* no init */
08836             ctx->keyLen     = 0;
08837             ctx->enc        = 1;      /* start in encrypt mode */
08838         }
08839     }
08840 
08841 
08842     /* SSL_SUCCESS on ok */
08843     int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx)
08844     {
08845         WOLFSSL_ENTER("EVP_CIPHER_CTX_cleanup");
08846         if (ctx) {
08847             ctx->cipherType = 0xff;  /* no more init */
08848             ctx->keyLen     = 0;
08849         }
08850 
08851         return SSL_SUCCESS;
08852     }
08853 
08854 
08855     /* return SSL_SUCCESS on ok, 0 on failure to match API compatibility */
08856     int  wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
08857                                const WOLFSSL_EVP_CIPHER* type, byte* key,
08858                                byte* iv, int enc)
08859     {
08860         int ret = -1;  /* failure local, during function 0 means success
08861                           because internal functions work that way */
08862         (void)iv;
08863         (void)enc;
08864 
08865         WOLFSSL_ENTER("wolfSSL_EVP_CipherInit");
08866         if (ctx == NULL) {
08867             WOLFSSL_MSG("no ctx");
08868             return 0;   /* failure */
08869         }
08870 
08871         if (type == NULL && ctx->cipherType == 0xff) {
08872             WOLFSSL_MSG("no type set");
08873             return 0;   /* failure */
08874         }
08875 
08876 #ifndef NO_AES
08877         if (ctx->cipherType == AES_128_CBC_TYPE ||
08878             (type && XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)) {
08879             WOLFSSL_MSG(EVP_AES_128_CBC);
08880             ctx->cipherType = AES_128_CBC_TYPE;
08881             ctx->keyLen     = 16;
08882             if (enc == 0 || enc == 1)
08883                 ctx->enc = enc ? 1 : 0;
08884             if (key) {
08885                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
08886                                 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
08887                 if (ret != 0)
08888                     return ret;
08889             }
08890             if (iv && key == NULL) {
08891                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
08892                 if (ret != 0)
08893                     return ret;
08894             }
08895         }
08896         else if (ctx->cipherType == AES_192_CBC_TYPE ||
08897                  (type && XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)) {
08898             WOLFSSL_MSG(EVP_AES_192_CBC);
08899             ctx->cipherType = AES_192_CBC_TYPE;
08900             ctx->keyLen     = 24;
08901             if (enc == 0 || enc == 1)
08902                 ctx->enc = enc ? 1 : 0;
08903             if (key) {
08904                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
08905                                 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
08906                 if (ret != 0)
08907                     return ret;
08908             }
08909             if (iv && key == NULL) {
08910                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
08911                 if (ret != 0)
08912                     return ret;
08913             }
08914         }
08915         else if (ctx->cipherType == AES_256_CBC_TYPE ||
08916                  (type && XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)) {
08917             WOLFSSL_MSG(EVP_AES_256_CBC);
08918             ctx->cipherType = AES_256_CBC_TYPE;
08919             ctx->keyLen     = 32;
08920             if (enc == 0 || enc == 1)
08921                 ctx->enc = enc ? 1 : 0;
08922             if (key) {
08923                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
08924                                 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
08925                 if (ret != 0)
08926                     return ret;
08927             }
08928             if (iv && key == NULL) {
08929                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
08930                 if (ret != 0)
08931                     return ret;
08932             }
08933         }
08934 #ifdef WOLFSSL_AES_COUNTER
08935         else if (ctx->cipherType == AES_128_CTR_TYPE ||
08936                  (type && XSTRNCMP(type, EVP_AES_128_CTR, EVP_AES_SIZE) == 0)) {
08937             WOLFSSL_MSG(EVP_AES_128_CTR);
08938             ctx->cipherType = AES_128_CTR_TYPE;
08939             ctx->keyLen     = 16;
08940             if (enc == 0 || enc == 1)
08941                 ctx->enc = enc ? 1 : 0;
08942             if (key) {
08943                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
08944                                 AES_ENCRYPTION);
08945                 if (ret != 0)
08946                     return ret;
08947             }
08948             if (iv && key == NULL) {
08949                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
08950                 if (ret != 0)
08951                     return ret;
08952             }
08953         }
08954         else if (ctx->cipherType == AES_192_CTR_TYPE ||
08955                  (type && XSTRNCMP(type, EVP_AES_192_CTR, EVP_AES_SIZE) == 0)) {
08956             WOLFSSL_MSG(EVP_AES_192_CTR);
08957             ctx->cipherType = AES_192_CTR_TYPE;
08958             ctx->keyLen     = 24;
08959             if (enc == 0 || enc == 1)
08960                 ctx->enc = enc ? 1 : 0;
08961             if (key) {
08962                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
08963                                 AES_ENCRYPTION);
08964                 if (ret != 0)
08965                     return ret;
08966             }
08967             if (iv && key == NULL) {
08968                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
08969                 if (ret != 0)
08970                     return ret;
08971             }
08972         }
08973         else if (ctx->cipherType == AES_256_CTR_TYPE ||
08974                  (type && XSTRNCMP(type, EVP_AES_256_CTR, EVP_AES_SIZE) == 0)) {
08975             WOLFSSL_MSG(EVP_AES_256_CTR);
08976             ctx->cipherType = AES_256_CTR_TYPE;
08977             ctx->keyLen     = 32;
08978             if (enc == 0 || enc == 1)
08979                 ctx->enc = enc ? 1 : 0;
08980             if (key) {
08981                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
08982                                 AES_ENCRYPTION);
08983                 if (ret != 0)
08984                     return ret;
08985             }
08986             if (iv && key == NULL) {
08987                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
08988                 if (ret != 0)
08989                     return ret;
08990             }
08991         }
08992 #endif /* WOLFSSL_AES_CTR */
08993 #endif /* NO_AES */
08994 
08995 #ifndef NO_DES3
08996         if (ctx->cipherType == DES_CBC_TYPE ||
08997                  (type && XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0)) {
08998             WOLFSSL_MSG(EVP_DES_CBC);
08999             ctx->cipherType = DES_CBC_TYPE;
09000             ctx->keyLen     = 8;
09001             if (enc == 0 || enc == 1)
09002                 ctx->enc = enc ? 1 : 0;
09003             if (key) {
09004                 ret = wc_Des_SetKey(&ctx->cipher.des, key, iv,
09005                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
09006                 if (ret != 0)
09007                     return ret;
09008             }
09009 
09010             if (iv && key == NULL)
09011                 wc_Des_SetIV(&ctx->cipher.des, iv);
09012         }
09013         else if (ctx->cipherType == DES_EDE3_CBC_TYPE ||
09014                  (type &&
09015                   XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)) {
09016             WOLFSSL_MSG(EVP_DES_EDE3_CBC);
09017             ctx->cipherType = DES_EDE3_CBC_TYPE;
09018             ctx->keyLen     = 24;
09019             if (enc == 0 || enc == 1)
09020                 ctx->enc = enc ? 1 : 0;
09021             if (key) {
09022                 ret = wc_Des3_SetKey(&ctx->cipher.des3, key, iv,
09023                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
09024                 if (ret != 0)
09025                     return ret;
09026             }
09027 
09028             if (iv && key == NULL) {
09029                 ret = wc_Des3_SetIV(&ctx->cipher.des3, iv);
09030                 if (ret != 0)
09031                     return ret;
09032             }
09033         }
09034 #endif /* NO_DES3 */
09035 #ifndef NO_RC4
09036         if (ctx->cipherType == ARC4_TYPE || (type &&
09037                                      XSTRNCMP(type, "ARC4", 4) == 0)) {
09038             WOLFSSL_MSG("ARC4");
09039             ctx->cipherType = ARC4_TYPE;
09040             if (ctx->keyLen == 0)  /* user may have already set */
09041                 ctx->keyLen = 16;  /* default to 128 */
09042             if (key)
09043                 wc_Arc4SetKey(&ctx->cipher.arc4, key, ctx->keyLen);
09044             ret = 0;  /* success */
09045         }
09046 #endif /* NO_RC4 */
09047 #ifdef HAVE_IDEA
09048         if (ctx->cipherType == IDEA_CBC_TYPE ||
09049                  (type && XSTRNCMP(type, EVP_IDEA_CBC, EVP_IDEA_SIZE) == 0)) {
09050             WOLFSSL_MSG(EVP_IDEA_CBC);
09051             ctx->cipherType = IDEA_CBC_TYPE;
09052             ctx->keyLen     = IDEA_KEY_SIZE;
09053             if (enc == 0 || enc == 1)
09054                 ctx->enc = enc ? 1 : 0;
09055             if (key) {
09056                 ret = wc_IdeaSetKey(&ctx->cipher.idea, key, (word16)ctx->keyLen,
09057                                     iv, ctx->enc ? IDEA_ENCRYPTION :
09058                                                    IDEA_DECRYPTION);
09059                 if (ret != 0)
09060                     return ret;
09061             }
09062 
09063             if (iv && key == NULL)
09064                 wc_IdeaSetIV(&ctx->cipher.idea, iv);
09065         }
09066 #endif /* HAVE_IDEA */
09067         if (ctx->cipherType == NULL_CIPHER_TYPE || (type &&
09068                                      XSTRNCMP(type, "NULL", 4) == 0)) {
09069             WOLFSSL_MSG("NULL cipher");
09070             ctx->cipherType = NULL_CIPHER_TYPE;
09071             ctx->keyLen = 0;
09072             ret = 0;  /* success */
09073         }
09074 
09075         if (ret == 0)
09076             return SSL_SUCCESS;
09077         else
09078             return 0;  /* overall failure */
09079     }
09080 
09081 
09082     /* SSL_SUCCESS on ok */
09083     int wolfSSL_EVP_CIPHER_CTX_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx)
09084     {
09085         WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_key_length");
09086         if (ctx)
09087             return ctx->keyLen;
09088 
09089         return 0;   /* failure */
09090     }
09091 
09092 
09093     /* SSL_SUCCESS on ok */
09094     int wolfSSL_EVP_CIPHER_CTX_set_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx,
09095                                              int keylen)
09096     {
09097         WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_set_key_length");
09098         if (ctx)
09099             ctx->keyLen = keylen;
09100         else
09101             return 0;  /* failure */
09102 
09103         return SSL_SUCCESS;
09104     }
09105 
09106 
09107     /* SSL_SUCCESS on ok */
09108     int wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* dst, byte* src,
09109                           word32 len)
09110     {
09111         int ret = 0;
09112         WOLFSSL_ENTER("wolfSSL_EVP_Cipher");
09113 
09114         if (ctx == NULL || dst == NULL || src == NULL) {
09115             WOLFSSL_MSG("Bad function argument");
09116             return 0;  /* failure */
09117         }
09118 
09119         if (ctx->cipherType == 0xff) {
09120             WOLFSSL_MSG("no init");
09121             return 0;  /* failure */
09122         }
09123 
09124         switch (ctx->cipherType) {
09125 
09126 #ifndef NO_AES
09127 #ifdef HAVE_AES_CBC
09128             case AES_128_CBC_TYPE :
09129             case AES_192_CBC_TYPE :
09130             case AES_256_CBC_TYPE :
09131                 WOLFSSL_MSG("AES CBC");
09132                 if (ctx->enc)
09133                     ret = wc_AesCbcEncrypt(&ctx->cipher.aes, dst, src, len);
09134                 else
09135                     ret = wc_AesCbcDecrypt(&ctx->cipher.aes, dst, src, len);
09136                 break;
09137 #endif /* HAVE_AES_CBC */
09138 #ifdef WOLFSSL_AES_COUNTER
09139             case AES_128_CTR_TYPE :
09140             case AES_192_CTR_TYPE :
09141             case AES_256_CTR_TYPE :
09142                     WOLFSSL_MSG("AES CTR");
09143                     wc_AesCtrEncrypt(&ctx->cipher.aes, dst, src, len);
09144                 break;
09145 #endif /* WOLFSSL_AES_COUNTER */
09146 #endif /* NO_AES */
09147 
09148 #ifndef NO_DES3
09149             case DES_CBC_TYPE :
09150                 if (ctx->enc)
09151                     wc_Des_CbcEncrypt(&ctx->cipher.des, dst, src, len);
09152                 else
09153                     wc_Des_CbcDecrypt(&ctx->cipher.des, dst, src, len);
09154                 break;
09155 
09156             case DES_EDE3_CBC_TYPE :
09157                 if (ctx->enc)
09158                     ret = wc_Des3_CbcEncrypt(&ctx->cipher.des3, dst, src, len);
09159                 else
09160                     ret = wc_Des3_CbcDecrypt(&ctx->cipher.des3, dst, src, len);
09161                 break;
09162 #endif
09163 
09164 #ifndef NO_RC4
09165             case ARC4_TYPE :
09166                 wc_Arc4Process(&ctx->cipher.arc4, dst, src, len);
09167                 break;
09168 #endif
09169 
09170 #ifdef HAVE_IDEA
09171             case IDEA_CBC_TYPE :
09172                 if (ctx->enc)
09173                     wc_IdeaCbcEncrypt(&ctx->cipher.idea, dst, src, len);
09174                 else
09175                     wc_IdeaCbcDecrypt(&ctx->cipher.idea, dst, src, len);
09176                 break;
09177 #endif
09178             case NULL_CIPHER_TYPE :
09179                 XMEMCPY(dst, src, len);
09180                 break;
09181 
09182             default: {
09183                 WOLFSSL_MSG("bad type");
09184                 return 0;  /* failure */
09185             }
09186         }
09187 
09188         if (ret != 0) {
09189             WOLFSSL_MSG("wolfSSL_EVP_Cipher failure");
09190             return 0;  /* failuer */
09191         }
09192 
09193         WOLFSSL_MSG("wolfSSL_EVP_Cipher success");
09194         return SSL_SUCCESS;  /* success */
09195     }
09196 
09197 
09198     /* store for external read of iv, SSL_SUCCESS on success */
09199     int  wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
09200     {
09201         WOLFSSL_ENTER("wolfSSL_StoreExternalIV");
09202 
09203         if (ctx == NULL) {
09204             WOLFSSL_MSG("Bad function argument");
09205             return SSL_FATAL_ERROR;
09206         }
09207 
09208         switch (ctx->cipherType) {
09209 
09210 #ifndef NO_AES
09211             case AES_128_CBC_TYPE :
09212             case AES_192_CBC_TYPE :
09213             case AES_256_CBC_TYPE :
09214                 WOLFSSL_MSG("AES CBC");
09215                 XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
09216                 break;
09217 
09218 #ifdef WOLFSSL_AES_COUNTER
09219             case AES_128_CTR_TYPE :
09220             case AES_192_CTR_TYPE :
09221             case AES_256_CTR_TYPE :
09222                 WOLFSSL_MSG("AES CTR");
09223                 XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
09224                 break;
09225 #endif /* WOLFSSL_AES_COUNTER */
09226 
09227 #endif /* NO_AES */
09228 
09229 #ifndef NO_DES3
09230             case DES_CBC_TYPE :
09231                 WOLFSSL_MSG("DES CBC");
09232                 XMEMCPY(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
09233                 break;
09234 
09235             case DES_EDE3_CBC_TYPE :
09236                 WOLFSSL_MSG("DES EDE3 CBC");
09237                 XMEMCPY(ctx->iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
09238                 break;
09239 #endif
09240 
09241 #ifdef HAVE_IDEA
09242             case IDEA_CBC_TYPE :
09243                 WOLFSSL_MSG("IDEA CBC");
09244                 XMEMCPY(ctx->iv, &ctx->cipher.idea.reg, IDEA_BLOCK_SIZE);
09245                 break;
09246 #endif
09247             case ARC4_TYPE :
09248                 WOLFSSL_MSG("ARC4");
09249                 break;
09250 
09251             case NULL_CIPHER_TYPE :
09252                 WOLFSSL_MSG("NULL");
09253                 break;
09254 
09255             default: {
09256                 WOLFSSL_MSG("bad type");
09257                 return SSL_FATAL_ERROR;
09258             }
09259         }
09260         return SSL_SUCCESS;
09261     }
09262 
09263 
09264     /* set internal IV from external, SSL_SUCCESS on success */
09265     int  wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
09266     {
09267 
09268         WOLFSSL_ENTER("wolfSSL_SetInternalIV");
09269 
09270         if (ctx == NULL) {
09271             WOLFSSL_MSG("Bad function argument");
09272             return SSL_FATAL_ERROR;
09273         }
09274 
09275         switch (ctx->cipherType) {
09276 
09277 #ifndef NO_AES
09278             case AES_128_CBC_TYPE :
09279             case AES_192_CBC_TYPE :
09280             case AES_256_CBC_TYPE :
09281                 WOLFSSL_MSG("AES CBC");
09282                 XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
09283                 break;
09284 
09285 #ifdef WOLFSSL_AES_COUNTER
09286             case AES_128_CTR_TYPE :
09287             case AES_192_CTR_TYPE :
09288             case AES_256_CTR_TYPE :
09289                 WOLFSSL_MSG("AES CTR");
09290                 XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
09291                 break;
09292 #endif
09293 
09294 #endif /* NO_AES */
09295 
09296 #ifndef NO_DES3
09297             case DES_CBC_TYPE :
09298                 WOLFSSL_MSG("DES CBC");
09299                 XMEMCPY(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
09300                 break;
09301 
09302             case DES_EDE3_CBC_TYPE :
09303                 WOLFSSL_MSG("DES EDE3 CBC");
09304                 XMEMCPY(&ctx->cipher.des3.reg, ctx->iv, DES_BLOCK_SIZE);
09305                 break;
09306 #endif
09307 
09308 #ifdef HAVE_IDEA
09309             case IDEA_CBC_TYPE :
09310                 WOLFSSL_MSG("IDEA CBC");
09311                 XMEMCPY(&ctx->cipher.idea.reg, ctx->iv, IDEA_BLOCK_SIZE);
09312                 break;
09313 #endif
09314             case ARC4_TYPE :
09315                 WOLFSSL_MSG("ARC4");
09316                 break;
09317 
09318             case NULL_CIPHER_TYPE :
09319                 WOLFSSL_MSG("NULL");
09320                 break;
09321 
09322             default: {
09323                 WOLFSSL_MSG("bad type");
09324                 return SSL_FATAL_ERROR;
09325             }
09326         }
09327         return SSL_SUCCESS;
09328     }
09329 
09330 
09331     /* SSL_SUCCESS on ok */
09332     int wolfSSL_EVP_DigestInit(WOLFSSL_EVP_MD_CTX* ctx,
09333                                const WOLFSSL_EVP_MD* type)
09334     {
09335         WOLFSSL_ENTER("EVP_DigestInit");
09336         if (XSTRNCMP(type, "SHA256", 6) == 0) {
09337              ctx->macType = SHA256;
09338              wolfSSL_SHA256_Init((SHA256_CTX*)&ctx->hash);
09339         }
09340     #ifdef WOLFSSL_SHA384
09341         else if (XSTRNCMP(type, "SHA384", 6) == 0) {
09342              ctx->macType = SHA384;
09343              wolfSSL_SHA384_Init((SHA384_CTX*)&ctx->hash);
09344         }
09345     #endif
09346     #ifdef WOLFSSL_SHA512
09347         else if (XSTRNCMP(type, "SHA512", 6) == 0) {
09348              ctx->macType = SHA512;
09349              wolfSSL_SHA512_Init((SHA512_CTX*)&ctx->hash);
09350         }
09351     #endif
09352     #ifndef NO_MD5
09353         else if (XSTRNCMP(type, "MD5", 3) == 0) {
09354             ctx->macType = MD5;
09355             wolfSSL_MD5_Init((MD5_CTX*)&ctx->hash);
09356         }
09357     #endif
09358     #ifndef NO_SHA
09359         /* has to be last since would pick or 256, 384, or 512 too */
09360         else if (XSTRNCMP(type, "SHA", 3) == 0) {
09361              ctx->macType = SHA;
09362              wolfSSL_SHA_Init((SHA_CTX*)&ctx->hash);
09363         }
09364     #endif /* NO_SHA */
09365         else
09366              return BAD_FUNC_ARG;
09367 
09368         return SSL_SUCCESS;
09369     }
09370 
09371 
09372     /* SSL_SUCCESS on ok */
09373     int wolfSSL_EVP_DigestUpdate(WOLFSSL_EVP_MD_CTX* ctx, const void* data,
09374                                 unsigned long sz)
09375     {
09376         WOLFSSL_ENTER("EVP_DigestUpdate");
09377 
09378         switch (ctx->macType) {
09379 #ifndef NO_MD5
09380             case MD5:
09381                 wolfSSL_MD5_Update((MD5_CTX*)&ctx->hash, data,
09382                                   (unsigned long)sz);
09383                 break;
09384 #endif
09385 #ifndef NO_SHA
09386             case SHA:
09387                 wolfSSL_SHA_Update((SHA_CTX*)&ctx->hash, data,
09388                                   (unsigned long)sz);
09389                 break;
09390 #endif
09391 #ifndef NO_SHA256
09392             case SHA256:
09393                 wolfSSL_SHA256_Update((SHA256_CTX*)&ctx->hash, data,
09394                                      (unsigned long)sz);
09395                 break;
09396 #endif
09397 #ifdef WOLFSSL_SHA384
09398             case SHA384:
09399                 wolfSSL_SHA384_Update((SHA384_CTX*)&ctx->hash, data,
09400                                      (unsigned long)sz);
09401                 break;
09402 #endif
09403 #ifdef WOLFSSL_SHA512
09404             case SHA512:
09405                 wolfSSL_SHA512_Update((SHA512_CTX*)&ctx->hash, data,
09406                                      (unsigned long)sz);
09407                 break;
09408 #endif
09409             default:
09410                 return BAD_FUNC_ARG;
09411         }
09412 
09413         return SSL_SUCCESS;
09414     }
09415 
09416 
09417     /* SSL_SUCCESS on ok */
09418     int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md,
09419                                unsigned int* s)
09420     {
09421         WOLFSSL_ENTER("EVP_DigestFinal");
09422         switch (ctx->macType) {
09423 #ifndef NO_MD5
09424             case MD5:
09425                 wolfSSL_MD5_Final(md, (MD5_CTX*)&ctx->hash);
09426                 if (s) *s = MD5_DIGEST_SIZE;
09427                 break;
09428 #endif
09429 #ifndef NO_SHA
09430             case SHA:
09431                 wolfSSL_SHA_Final(md, (SHA_CTX*)&ctx->hash);
09432                 if (s) *s = SHA_DIGEST_SIZE;
09433                 break;
09434 #endif
09435 #ifndef NO_SHA256
09436             case SHA256:
09437                 wolfSSL_SHA256_Final(md, (SHA256_CTX*)&ctx->hash);
09438                 if (s) *s = SHA256_DIGEST_SIZE;
09439                 break;
09440 #endif
09441 #ifdef WOLFSSL_SHA384
09442             case SHA384:
09443                 wolfSSL_SHA384_Final(md, (SHA384_CTX*)&ctx->hash);
09444                 if (s) *s = SHA384_DIGEST_SIZE;
09445                 break;
09446 #endif
09447 #ifdef WOLFSSL_SHA512
09448             case SHA512:
09449                 wolfSSL_SHA512_Final(md, (SHA512_CTX*)&ctx->hash);
09450                 if (s) *s = SHA512_DIGEST_SIZE;
09451                 break;
09452 #endif
09453             default:
09454                 return BAD_FUNC_ARG;
09455         }
09456 
09457         return SSL_SUCCESS;
09458     }
09459 
09460 
09461     /* SSL_SUCCESS on ok */
09462     int wolfSSL_EVP_DigestFinal_ex(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md,
09463                                    unsigned int* s)
09464     {
09465         WOLFSSL_ENTER("EVP_DigestFinal_ex");
09466         return EVP_DigestFinal(ctx, md, s);
09467     }
09468 
09469 
09470     unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, const void* key,
09471                                 int key_len, const unsigned char* d, int n,
09472                                 unsigned char* md, unsigned int* md_len)
09473     {
09474         int type;
09475         unsigned char* ret = NULL;
09476 #ifdef WOLFSSL_SMALL_STACK
09477         Hmac* hmac = NULL;
09478 #else
09479         Hmac  hmac[1];
09480 #endif
09481 
09482         WOLFSSL_ENTER("HMAC");
09483         if (!md)
09484             return NULL;  /* no static buffer support */
09485 
09486         if (XSTRNCMP(evp_md, "MD5", 3) == 0)
09487             type = MD5;
09488         else if (XSTRNCMP(evp_md, "SHA", 3) == 0)
09489             type = SHA;
09490         else
09491             return NULL;
09492 
09493     #ifdef WOLFSSL_SMALL_STACK
09494         hmac = (Hmac*)XMALLOC(sizeof(Hmac), NULL, DYNAMIC_TYPE_TMP_BUFFER);
09495         if (hmac == NULL)
09496             return NULL;
09497     #endif
09498 
09499         if (wc_HmacSetKey(hmac, type, (const byte*)key, key_len) == 0)
09500             if (wc_HmacUpdate(hmac, d, n) == 0)
09501                 if (wc_HmacFinal(hmac, md) == 0) {
09502                     if (md_len)
09503                         *md_len = (type == MD5) ? (int)MD5_DIGEST_SIZE
09504                                                 : (int)SHA_DIGEST_SIZE;
09505                     ret = md;
09506                 }
09507 
09508     #ifdef WOLFSSL_SMALL_STACK
09509         XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER);
09510     #endif
09511 
09512         return ret;
09513     }
09514 
09515     void wolfSSL_ERR_clear_error(void)
09516     {
09517         /* TODO: */
09518     }
09519 
09520 
09521     int wolfSSL_RAND_status(void)
09522     {
09523         return SSL_SUCCESS;  /* wolfCrypt provides enough seed internally */
09524     }
09525 
09526 
09527 
09528     void wolfSSL_RAND_add(const void* add, int len, double entropy)
09529     {
09530         (void)add;
09531         (void)len;
09532         (void)entropy;
09533 
09534         /* wolfSSL seeds/adds internally, use explicit RNG if you want
09535            to take control */
09536     }
09537 
09538 
09539 #ifndef NO_DES3
09540     /* SSL_SUCCESS on ok */
09541     int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key,
09542                               WOLFSSL_DES_key_schedule* schedule)
09543     {
09544         WOLFSSL_ENTER("DES_key_sched");
09545         XMEMCPY(schedule, key, sizeof(const_DES_cblock));
09546         return SSL_SUCCESS;
09547     }
09548 
09549 
09550     void wolfSSL_DES_cbc_encrypt(const unsigned char* input,
09551                                  unsigned char* output, long length,
09552                                  WOLFSSL_DES_key_schedule* schedule,
09553                                  WOLFSSL_DES_cblock* ivec, int enc)
09554     {
09555         Des myDes;
09556 
09557         WOLFSSL_ENTER("DES_cbc_encrypt");
09558 
09559         /* OpenSSL compat, no ret */
09560         wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
09561 
09562         if (enc)
09563             wc_Des_CbcEncrypt(&myDes, output, input, (word32)length);
09564         else
09565             wc_Des_CbcDecrypt(&myDes, output, input, (word32)length);
09566     }
09567 
09568 
09569     /* correctly sets ivec for next call */
09570     void wolfSSL_DES_ncbc_encrypt(const unsigned char* input,
09571                      unsigned char* output, long length,
09572                      WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec,
09573                      int enc)
09574     {
09575         Des myDes;
09576 
09577         WOLFSSL_ENTER("DES_ncbc_encrypt");
09578 
09579         /* OpenSSL compat, no ret */
09580         wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
09581 
09582         if (enc)
09583             wc_Des_CbcEncrypt(&myDes, output, input, (word32)length);
09584         else
09585             wc_Des_CbcDecrypt(&myDes, output, input, (word32)length);
09586 
09587         XMEMCPY(ivec, output + length - sizeof(DES_cblock), sizeof(DES_cblock));
09588     }
09589 
09590 #endif /* NO_DES3 */
09591 
09592 
09593     void wolfSSL_ERR_free_strings(void)
09594     {
09595         /* handled internally */
09596     }
09597 
09598 
09599     void wolfSSL_ERR_remove_state(unsigned long state)
09600     {
09601         /* TODO: GetErrors().Remove(); */
09602         (void)state;
09603     }
09604 
09605 
09606     void wolfSSL_EVP_cleanup(void)
09607     {
09608         /* nothing to do here */
09609     }
09610 
09611 
09612     void wolfSSL_cleanup_all_ex_data(void)
09613     {
09614         /* nothing to do here */
09615     }
09616 
09617 
09618     int wolfSSL_clear(WOLFSSL* ssl)
09619     {
09620         (void)ssl;
09621         /* TODO: GetErrors().Remove(); */
09622         return SSL_SUCCESS;
09623     }
09624 
09625 
09626     long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t)
09627     {
09628         word32 tmptime;
09629         if (!ses || t < 0)
09630             return BAD_FUNC_ARG;
09631 
09632         tmptime = t & 0xFFFFFFFF;
09633 
09634         ses->timeout = tmptime;
09635 
09636         return SSL_SUCCESS;
09637     }
09638 
09639 
09640     long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode)
09641     {
09642         /* SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
09643 
09644         WOLFSSL_ENTER("SSL_CTX_set_mode");
09645         if (mode == SSL_MODE_ENABLE_PARTIAL_WRITE)
09646             ctx->partialWrite = 1;
09647 
09648         return mode;
09649     }
09650 
09651 
09652     long wolfSSL_SSL_get_mode(WOLFSSL* ssl)
09653     {
09654         /* TODO: */
09655         (void)ssl;
09656         return 0;
09657     }
09658 
09659 
09660     long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx)
09661     {
09662         /* TODO: */
09663         (void)ctx;
09664         return 0;
09665     }
09666 
09667 
09668     void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m)
09669     {
09670         /* TODO: maybe? */
09671         (void)ctx;
09672         (void)m;
09673     }
09674 
09675 
09676     int wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX* ctx,
09677                                            const unsigned char* sid_ctx,
09678                                            unsigned int sid_ctx_len)
09679     {
09680         /* No application specific context needed for wolfSSL */
09681         (void)ctx;
09682         (void)sid_ctx;
09683         (void)sid_ctx_len;
09684         return SSL_SUCCESS;
09685     }
09686 
09687 
09688     long wolfSSL_CTX_sess_get_cache_size(WOLFSSL_CTX* ctx)
09689     {
09690         /* TODO: maybe? */
09691         (void)ctx;
09692         return (~0);
09693     }
09694 
09695     unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line,
09696                                                   const char** data, int *flags)
09697     {
09698         /* Not implemented */
09699         (void)file;
09700         (void)line;
09701         (void)data;
09702         (void)flags;
09703         return 0;
09704     }
09705 
09706 #endif /* OPENSSL_EXTRA */
09707 
09708 
09709 #if defined(KEEP_PEER_CERT)
09710 
09711     WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl)
09712     {
09713         WOLFSSL_ENTER("SSL_get_peer_certificate");
09714         if (ssl->peerCert.issuer.sz)
09715             return &ssl->peerCert;
09716         else
09717             return 0;
09718     }
09719 
09720 #endif /* KEEP_PEER_CERT */
09721 
09722 
09723 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || defined(OPENSSSL_EXTRA)
09724 
09725 /* user externally called free X509, if dynamic go ahead with free, otherwise
09726  * don't */
09727 static void ExternalFreeX509(WOLFSSL_X509* x509)
09728 {
09729     WOLFSSL_ENTER("ExternalFreeX509");
09730     if (x509) {
09731         if (x509->dynamicMemory) {
09732             FreeX509(x509);
09733             XFREE(x509, NULL, DYNAMIC_TYPE_X509);
09734         } else {
09735             WOLFSSL_MSG("free called on non dynamic object, not freeing");
09736         }
09737     }
09738 }
09739 
09740 #endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSSL_EXTRA */
09741 
09742 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
09743 
09744     void wolfSSL_FreeX509(WOLFSSL_X509* x509)
09745     {
09746         WOLFSSL_ENTER("wolfSSL_FreeX509");
09747         ExternalFreeX509(x509);
09748     }
09749 
09750 
09751     /* return the next, if any, altname from the peer cert */
09752     char* wolfSSL_X509_get_next_altname(WOLFSSL_X509* cert)
09753     {
09754         char* ret = NULL;
09755         WOLFSSL_ENTER("wolfSSL_X509_get_next_altname");
09756 
09757         /* don't have any to work with */
09758         if (cert == NULL || cert->altNames == NULL)
09759             return NULL;
09760 
09761         /* already went through them */
09762         if (cert->altNamesNext == NULL)
09763             return NULL;
09764 
09765         ret = cert->altNamesNext->name;
09766         cert->altNamesNext = cert->altNamesNext->next;
09767 
09768         return ret;
09769     }
09770 
09771 
09772     WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509* cert)
09773     {
09774         WOLFSSL_ENTER("X509_get_issuer_name");
09775         if(cert)
09776             return &cert->issuer;
09777         return NULL;
09778     }
09779 
09780 
09781     WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
09782     {
09783         WOLFSSL_ENTER("wolfSSL_X509_get_subject_name");
09784         if(cert)
09785             return &cert->subject;
09786         return NULL;
09787     }
09788 
09789 
09790     int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509)
09791     {
09792         int isCA = 0;
09793 
09794         WOLFSSL_ENTER("wolfSSL_X509_get_isCA");
09795 
09796         if (x509 != NULL)
09797             isCA = x509->isCa;
09798 
09799         WOLFSSL_LEAVE("wolfSSL_X509_get_isCA", isCA);
09800 
09801         return isCA;
09802     }
09803 
09804 
09805 #ifdef OPENSSL_EXTRA
09806     int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509* x509, int nid)
09807     {
09808         int isSet = 0;
09809 
09810         WOLFSSL_ENTER("wolfSSL_X509_ext_isSet_by_NID");
09811 
09812         if (x509 != NULL) {
09813             switch (nid) {
09814                 case BASIC_CA_OID: isSet = x509->basicConstSet; break;
09815                 case ALT_NAMES_OID: isSet = x509->subjAltNameSet; break;
09816                 case AUTH_KEY_OID: isSet = x509->authKeyIdSet; break;
09817                 case SUBJ_KEY_OID: isSet = x509->subjKeyIdSet; break;
09818                 case KEY_USAGE_OID: isSet = x509->keyUsageSet; break;
09819                 #ifdef WOLFSSL_SEP
09820                     case CERT_POLICY_OID: isSet = x509->certPolicySet; break;
09821                 #endif /* WOLFSSL_SEP */
09822             }
09823         }
09824 
09825         WOLFSSL_LEAVE("wolfSSL_X509_ext_isSet_by_NID", isSet);
09826 
09827         return isSet;
09828     }
09829 
09830 
09831     int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509* x509, int nid)
09832     {
09833         int crit = 0;
09834 
09835         WOLFSSL_ENTER("wolfSSL_X509_ext_get_critical_by_NID");
09836 
09837         if (x509 != NULL) {
09838             switch (nid) {
09839                 case BASIC_CA_OID: crit = x509->basicConstCrit; break;
09840                 case ALT_NAMES_OID: crit = x509->subjAltNameCrit; break;
09841                 case AUTH_KEY_OID: crit = x509->authKeyIdCrit; break;
09842                 case SUBJ_KEY_OID: crit = x509->subjKeyIdCrit; break;
09843                 case KEY_USAGE_OID: crit = x509->keyUsageCrit; break;
09844                 #ifdef WOLFSSL_SEP
09845                     case CERT_POLICY_OID: crit = x509->certPolicyCrit; break;
09846                 #endif /* WOLFSSL_SEP */
09847             }
09848         }
09849 
09850         WOLFSSL_LEAVE("wolfSSL_X509_ext_get_critical_by_NID", crit);
09851 
09852         return crit;
09853     }
09854 
09855 
09856     int wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509* x509)
09857     {
09858         int isSet = 0;
09859 
09860         WOLFSSL_ENTER("wolfSSL_X509_get_isSet_pathLength");
09861 
09862         if (x509 != NULL)
09863             isSet = x509->basicConstPlSet;
09864 
09865         WOLFSSL_LEAVE("wolfSSL_X509_get_isSet_pathLength", isSet);
09866 
09867         return isSet;
09868     }
09869 
09870 
09871     word32 wolfSSL_X509_get_pathLength(WOLFSSL_X509* x509)
09872     {
09873         word32 pathLength = 0;
09874 
09875         WOLFSSL_ENTER("wolfSSL_X509_get_pathLength");
09876 
09877         if (x509 != NULL)
09878             pathLength = x509->pathLength;
09879 
09880         WOLFSSL_LEAVE("wolfSSL_X509_get_pathLength", pathLength);
09881 
09882         return pathLength;
09883     }
09884 
09885 
09886     unsigned int wolfSSL_X509_get_keyUsage(WOLFSSL_X509* x509)
09887     {
09888         word16 usage = 0;
09889 
09890         WOLFSSL_ENTER("wolfSSL_X509_get_keyUsage");
09891 
09892         if (x509 != NULL)
09893             usage = x509->keyUsage;
09894 
09895         WOLFSSL_LEAVE("wolfSSL_X509_get_keyUsage", usage);
09896 
09897         return usage;
09898     }
09899 
09900 
09901     byte* wolfSSL_X509_get_authorityKeyID(WOLFSSL_X509* x509,
09902                                           byte* dst, int* dstLen)
09903     {
09904         byte *id = NULL;
09905         int copySz = 0;
09906 
09907         WOLFSSL_ENTER("wolfSSL_X509_get_authorityKeyID");
09908 
09909         if (x509 != NULL) {
09910             if (x509->authKeyIdSet) {
09911                 copySz = min(dstLen != NULL ? *dstLen : 0,
09912                              (int)x509->authKeyIdSz);
09913                 id = x509->authKeyId;
09914             }
09915 
09916             if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
09917                 XMEMCPY(dst, id, copySz);
09918                 id = dst;
09919                 *dstLen = copySz;
09920             }
09921         }
09922 
09923         WOLFSSL_LEAVE("wolfSSL_X509_get_authorityKeyID", copySz);
09924 
09925         return id;
09926     }
09927 
09928 
09929     byte* wolfSSL_X509_get_subjectKeyID(WOLFSSL_X509* x509,
09930                                         byte* dst, int* dstLen)
09931     {
09932         byte *id = NULL;
09933         int copySz = 0;
09934 
09935         WOLFSSL_ENTER("wolfSSL_X509_get_subjectKeyID");
09936 
09937         if (x509 != NULL) {
09938             if (x509->subjKeyIdSet) {
09939                 copySz = min(dstLen != NULL ? *dstLen : 0,
09940                                                         (int)x509->subjKeyIdSz);
09941                 id = x509->subjKeyId;
09942             }
09943 
09944             if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
09945                 XMEMCPY(dst, id, copySz);
09946                 id = dst;
09947                 *dstLen = copySz;
09948             }
09949         }
09950 
09951         WOLFSSL_LEAVE("wolfSSL_X509_get_subjectKeyID", copySz);
09952 
09953         return id;
09954     }
09955 
09956 
09957     int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME* name)
09958     {
09959         int count = 0;
09960 
09961         WOLFSSL_ENTER("wolfSSL_X509_NAME_entry_count");
09962 
09963         if (name != NULL)
09964             count = name->fullName.entryCount;
09965 
09966         WOLFSSL_LEAVE("wolfSSL_X509_NAME_entry_count", count);
09967         return count;
09968     }
09969 
09970 
09971     int wolfSSL_X509_NAME_get_text_by_NID(WOLFSSL_X509_NAME* name,
09972                                           int nid, char* buf, int len)
09973     {
09974         char *text = NULL;
09975         int textSz = 0;
09976 
09977         WOLFSSL_ENTER("wolfSSL_X509_NAME_get_text_by_NID");
09978 
09979         switch (nid) {
09980             case ASN_COMMON_NAME:
09981                 text = name->fullName.fullName + name->fullName.cnIdx;
09982                 textSz = name->fullName.cnLen;
09983                 break;
09984             case ASN_SUR_NAME:
09985                 text = name->fullName.fullName + name->fullName.snIdx;
09986                 textSz = name->fullName.snLen;
09987                 break;
09988             case ASN_SERIAL_NUMBER:
09989                 text = name->fullName.fullName + name->fullName.serialIdx;
09990                 textSz = name->fullName.serialLen;
09991                 break;
09992             case ASN_COUNTRY_NAME:
09993                 text = name->fullName.fullName + name->fullName.cIdx;
09994                 textSz = name->fullName.cLen;
09995                 break;
09996             case ASN_LOCALITY_NAME:
09997                 text = name->fullName.fullName + name->fullName.lIdx;
09998                 textSz = name->fullName.lLen;
09999                 break;
10000             case ASN_STATE_NAME:
10001                 text = name->fullName.fullName + name->fullName.stIdx;
10002                 textSz = name->fullName.stLen;
10003                 break;
10004             case ASN_ORG_NAME:
10005                 text = name->fullName.fullName + name->fullName.oIdx;
10006                 textSz = name->fullName.oLen;
10007                 break;
10008             case ASN_ORGUNIT_NAME:
10009                 text = name->fullName.fullName + name->fullName.ouIdx;
10010                 textSz = name->fullName.ouLen;
10011                 break;
10012             default:
10013                 break;
10014         }
10015 
10016         if (buf != NULL && text != NULL) {
10017             textSz = min(textSz, len);
10018             XMEMCPY(buf, text, textSz);
10019             buf[textSz] = '\0';
10020         }
10021 
10022         WOLFSSL_LEAVE("wolfSSL_X509_NAME_get_text_by_NID", textSz);
10023         return textSz;
10024     }
10025 #endif
10026 
10027 
10028     /* copy name into in buffer, at most sz bytes, if buffer is null will
10029        malloc buffer, call responsible for freeing                     */
10030     char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
10031     {
10032         int copySz = min(sz, name->sz);
10033 
10034         WOLFSSL_ENTER("wolfSSL_X509_NAME_oneline");
10035         if (!name->sz) return in;
10036 
10037         if (!in) {
10038             in = (char*)XMALLOC(name->sz, 0, DYNAMIC_TYPE_OPENSSL);
10039             if (!in ) return in;
10040             copySz = name->sz;
10041         }
10042 
10043         if (copySz == 0)
10044             return in;
10045 
10046         XMEMCPY(in, name->name, copySz - 1);
10047         in[copySz - 1] = 0;
10048 
10049         return in;
10050     }
10051 
10052 
10053     int wolfSSL_X509_get_signature_type(WOLFSSL_X509* x509)
10054     {
10055         int type = 0;
10056 
10057         WOLFSSL_ENTER("wolfSSL_X509_get_signature_type");
10058 
10059         if (x509 != NULL)
10060             type = x509->sigOID;
10061 
10062         return type;
10063     }
10064 
10065 
10066     int wolfSSL_X509_get_signature(WOLFSSL_X509* x509,
10067                                                  unsigned char* buf, int* bufSz)
10068     {
10069         WOLFSSL_ENTER("wolfSSL_X509_get_signature");
10070         if (x509 == NULL || bufSz == NULL || *bufSz < (int)x509->sig.length)
10071             return SSL_FATAL_ERROR;
10072 
10073         if (buf != NULL)
10074             XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
10075         *bufSz = x509->sig.length;
10076 
10077         return SSL_SUCCESS;
10078     }
10079 
10080 
10081     /* write X509 serial number in unsigned binary to buffer
10082        buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
10083        return SSL_SUCCESS on success */
10084     int wolfSSL_X509_get_serial_number(WOLFSSL_X509* x509,
10085                                        byte* in, int* inOutSz)
10086     {
10087         WOLFSSL_ENTER("wolfSSL_X509_get_serial_number");
10088         if (x509 == NULL || in == NULL ||
10089                                    inOutSz == NULL || *inOutSz < x509->serialSz)
10090             return BAD_FUNC_ARG;
10091 
10092         XMEMCPY(in, x509->serial, x509->serialSz);
10093         *inOutSz = x509->serialSz;
10094 
10095         return SSL_SUCCESS;
10096     }
10097 
10098 
10099     const byte* wolfSSL_X509_get_der(WOLFSSL_X509* x509, int* outSz)
10100     {
10101         WOLFSSL_ENTER("wolfSSL_X509_get_der");
10102 
10103         if (x509 == NULL || outSz == NULL)
10104             return NULL;
10105 
10106         *outSz = (int)x509->derCert->length;
10107         return x509->derCert->buffer;
10108     }
10109 
10110 
10111     int wolfSSL_X509_version(WOLFSSL_X509* x509)
10112     {
10113         WOLFSSL_ENTER("wolfSSL_X509_version");
10114 
10115         if (x509 == NULL)
10116             return 0;
10117 
10118         return x509->version;
10119     }
10120 
10121 
10122     const byte* wolfSSL_X509_notBefore(WOLFSSL_X509* x509)
10123     {
10124         WOLFSSL_ENTER("wolfSSL_X509_notBefore");
10125 
10126         if (x509 == NULL)
10127             return NULL;
10128 
10129         return x509->notBefore;
10130     }
10131 
10132 
10133     const byte* wolfSSL_X509_notAfter(WOLFSSL_X509* x509)
10134     {
10135         WOLFSSL_ENTER("wolfSSL_X509_notAfter");
10136 
10137         if (x509 == NULL)
10138             return NULL;
10139 
10140         return x509->notAfter;
10141     }
10142 
10143 
10144 #ifdef WOLFSSL_SEP
10145 
10146 /* copy oid into in buffer, at most *inOutSz bytes, if buffer is null will
10147    malloc buffer, call responsible for freeing. Actual size returned in
10148    *inOutSz. Requires inOutSz be non-null */
10149 byte* wolfSSL_X509_get_device_type(WOLFSSL_X509* x509, byte* in, int *inOutSz)
10150 {
10151     int copySz;
10152 
10153     WOLFSSL_ENTER("wolfSSL_X509_get_dev_type");
10154     if (inOutSz == NULL) return NULL;
10155     if (!x509->deviceTypeSz) return in;
10156 
10157     copySz = min(*inOutSz, x509->deviceTypeSz);
10158 
10159     if (!in) {
10160         in = (byte*)XMALLOC(x509->deviceTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
10161         if (!in) return in;
10162         copySz = x509->deviceTypeSz;
10163     }
10164 
10165     XMEMCPY(in, x509->deviceType, copySz);
10166     *inOutSz = copySz;
10167 
10168     return in;
10169 }
10170 
10171 
10172 byte* wolfSSL_X509_get_hw_type(WOLFSSL_X509* x509, byte* in, int* inOutSz)
10173 {
10174     int copySz;
10175 
10176     WOLFSSL_ENTER("wolfSSL_X509_get_hw_type");
10177     if (inOutSz == NULL) return NULL;
10178     if (!x509->hwTypeSz) return in;
10179 
10180     copySz = min(*inOutSz, x509->hwTypeSz);
10181 
10182     if (!in) {
10183         in = (byte*)XMALLOC(x509->hwTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
10184         if (!in) return in;
10185         copySz = x509->hwTypeSz;
10186     }
10187 
10188     XMEMCPY(in, x509->hwType, copySz);
10189     *inOutSz = copySz;
10190 
10191     return in;
10192 }
10193 
10194 
10195 byte* wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509* x509,byte* in,
10196                                         int* inOutSz)
10197 {
10198     int copySz;
10199 
10200     WOLFSSL_ENTER("wolfSSL_X509_get_hw_serial_number");
10201     if (inOutSz == NULL) return NULL;
10202     if (!x509->hwTypeSz) return in;
10203 
10204     copySz = min(*inOutSz, x509->hwSerialNumSz);
10205 
10206     if (!in) {
10207         in = (byte*)XMALLOC(x509->hwSerialNumSz, 0, DYNAMIC_TYPE_OPENSSL);
10208         if (!in) return in;
10209         copySz = x509->hwSerialNumSz;
10210     }
10211 
10212     XMEMCPY(in, x509->hwSerialNum, copySz);
10213     *inOutSz = copySz;
10214 
10215     return in;
10216 }
10217 
10218 #endif /* WOLFSSL_SEP */
10219 
10220 
10221 WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
10222 {
10223     WOLFSSL_X509 *newX509 = NULL;
10224 
10225     WOLFSSL_ENTER("wolfSSL_X509_d2i");
10226 
10227     if (in != NULL && len != 0) {
10228     #ifdef WOLFSSL_SMALL_STACK
10229         DecodedCert* cert = NULL;
10230     #else
10231         DecodedCert  cert[1];
10232     #endif
10233 
10234     #ifdef WOLFSSL_SMALL_STACK
10235         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
10236                                      DYNAMIC_TYPE_TMP_BUFFER);
10237         if (cert == NULL)
10238             return NULL;
10239     #endif
10240 
10241         InitDecodedCert(cert, (byte*)in, len, NULL);
10242         if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
10243             newX509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
10244                                              DYNAMIC_TYPE_X509);
10245             if (newX509 != NULL) {
10246                 InitX509(newX509, 1);
10247                 if (CopyDecodedToX509(newX509, cert) != 0) {
10248                     XFREE(newX509, NULL, DYNAMIC_TYPE_X509);
10249                     newX509 = NULL;
10250                 }
10251             }
10252         }
10253         FreeDecodedCert(cert);
10254     #ifdef WOLFSSL_SMALL_STACK
10255         XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10256     #endif
10257     }
10258 
10259     if (x509 != NULL)
10260         *x509 = newX509;
10261 
10262     return newX509;
10263 }
10264 
10265 
10266 #ifndef NO_FILESYSTEM
10267 
10268 #ifndef NO_STDIO_FILESYSTEM
10269 
10270 WOLFSSL_X509* wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file)
10271 {
10272     WOLFSSL_X509* newX509 = NULL;
10273 
10274     WOLFSSL_ENTER("wolfSSL_X509_d2i_fp");
10275 
10276     if (file != XBADFILE) {
10277         byte* fileBuffer = NULL;
10278         long sz = 0;
10279 
10280         XFSEEK(file, 0, XSEEK_END);
10281         sz = XFTELL(file);
10282         XREWIND(file);
10283 
10284         if (sz < 0) {
10285             WOLFSSL_MSG("Bad tell on FILE");
10286             return NULL;
10287         }
10288 
10289         fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
10290         if (fileBuffer != NULL) {
10291             int ret = (int)XFREAD(fileBuffer, sz, 1, file);
10292             if (ret > 0) {
10293                 newX509 = wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
10294             }
10295             XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
10296         }
10297     }
10298 
10299     if (x509 != NULL)
10300         *x509 = newX509;
10301 
10302     return newX509;
10303 }
10304 
10305 #endif /* NO_STDIO_FILESYSTEM */
10306 
10307 WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format)
10308 {
10309 #ifdef WOLFSSL_SMALL_STACK
10310     byte  staticBuffer[1]; /* force heap usage */
10311 #else
10312     byte  staticBuffer[FILE_BUFFER_SIZE];
10313 #endif
10314     byte* fileBuffer = staticBuffer;
10315     int   dynamic = 0;
10316     int   ret;
10317     long  sz = 0;
10318     XFILE file;
10319 
10320     WOLFSSL_X509* x509 = NULL;
10321     DerBuffer* der = NULL;
10322 
10323     WOLFSSL_ENTER("wolfSSL_X509_load_certificate");
10324 
10325     /* Check the inputs */
10326     if ((fname == NULL) ||
10327         (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM))
10328         return NULL;
10329 
10330     file = XFOPEN(fname, "rb");
10331     if (file == XBADFILE)
10332         return NULL;
10333 
10334     XFSEEK(file, 0, XSEEK_END);
10335     sz = XFTELL(file);
10336     XREWIND(file);
10337 
10338     if (sz > (long)sizeof(staticBuffer)) {
10339         fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
10340         if (fileBuffer == NULL) {
10341             XFCLOSE(file);
10342             return NULL;
10343         }
10344         dynamic = 1;
10345     }
10346     else if (sz < 0) {
10347         XFCLOSE(file);
10348         return NULL;
10349     }
10350 
10351     ret = (int)XFREAD(fileBuffer, sz, 1, file);
10352     if (ret < 0) {
10353         XFCLOSE(file);
10354         if (dynamic)
10355             XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
10356         return NULL;
10357     }
10358 
10359     XFCLOSE(file);
10360 
10361     if (format == SSL_FILETYPE_PEM) {
10362         int ecc = 0;
10363     #ifdef WOLFSSL_SMALL_STACK
10364         EncryptedInfo* info = NULL;
10365     #else
10366         EncryptedInfo  info[1];
10367     #endif
10368 
10369     #ifdef WOLFSSL_SMALL_STACK
10370         info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
10371                                                       DYNAMIC_TYPE_TMP_BUFFER);
10372         if (info == NULL) {
10373             if (dynamic)
10374                 XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
10375 
10376             return NULL;
10377         }
10378     #endif
10379 
10380         info->set = 0;
10381         info->ctx = NULL;
10382         info->consumed = 0;
10383 
10384         if (PemToDer(fileBuffer, sz, CERT_TYPE, &der, NULL, info, &ecc) != 0) {
10385             FreeDer(&der);
10386         }
10387 
10388     #ifdef WOLFSSL_SMALL_STACK
10389         XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10390     #endif
10391     }
10392     else {
10393         ret = AllocDer(&der, (word32)sz, CERT_TYPE, NULL);
10394         if (ret == 0) {
10395             XMEMCPY(der->buffer, fileBuffer, sz);
10396         }
10397     }
10398 
10399     if (dynamic)
10400         XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
10401 
10402     /* At this point we want `der` to have the certificate in DER format */
10403     /* ready to be decoded. */
10404     if (der != NULL && der->buffer != NULL) {
10405     #ifdef WOLFSSL_SMALL_STACK
10406         DecodedCert* cert = NULL;
10407     #else
10408         DecodedCert  cert[1];
10409     #endif
10410 
10411     #ifdef WOLFSSL_SMALL_STACK
10412         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
10413                                                        DYNAMIC_TYPE_TMP_BUFFER);
10414         if (cert != NULL)
10415     #endif
10416         {
10417             InitDecodedCert(cert, der->buffer, der->length, NULL);
10418             if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
10419                 x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
10420                                                              DYNAMIC_TYPE_X509);
10421                 if (x509 != NULL) {
10422                     InitX509(x509, 1);
10423                     if (CopyDecodedToX509(x509, cert) != 0) {
10424                         XFREE(x509, NULL, DYNAMIC_TYPE_X509);
10425                         x509 = NULL;
10426                     }
10427                 }
10428             }
10429 
10430             FreeDecodedCert(cert);
10431         #ifdef WOLFSSL_SMALL_STACK
10432             XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10433         #endif
10434         }
10435 
10436         FreeDer(&der);
10437     }
10438 
10439     return x509;
10440 }
10441 
10442 #endif /* NO_FILESYSTEM */
10443 
10444 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
10445 
10446 
10447 #ifdef OPENSSL_EXTRA
10448 int wolfSSL_set_session_id_context(WOLFSSL* ssl, const unsigned char* id,
10449                                unsigned int len)
10450 {
10451     (void)ssl;
10452     (void)id;
10453     (void)len;
10454     return 0;
10455 }
10456 
10457 
10458 void wolfSSL_set_connect_state(WOLFSSL* ssl)
10459 {
10460     (void)ssl;
10461     /* client by default */
10462 }
10463 #endif
10464 
10465 int wolfSSL_get_shutdown(const WOLFSSL* ssl)
10466 {
10467     WOLFSSL_ENTER("wolfSSL_get_shutdown");
10468     /* in OpenSSL, SSL_SENT_SHUTDOWN = 1, when closeNotifySent   *
10469      * SSL_RECEIVED_SHUTDOWN = 2, from close notify or fatal err */
10470     return ((ssl->options.closeNotify||ssl->options.connReset) << 1)
10471             | (ssl->options.sentNotify);
10472 }
10473 
10474 
10475 int wolfSSL_session_reused(WOLFSSL* ssl)
10476 {
10477     return ssl->options.resuming;
10478 }
10479 
10480 #ifdef OPENSSL_EXTRA
10481 void wolfSSL_SESSION_free(WOLFSSL_SESSION* session)
10482 {
10483     /* No need to free since cache is static */
10484     (void)session;
10485 }
10486 #endif
10487 
10488 const char* wolfSSL_get_version(WOLFSSL* ssl)
10489 {
10490     WOLFSSL_ENTER("SSL_get_version");
10491     if (ssl->version.major == SSLv3_MAJOR) {
10492         switch (ssl->version.minor) {
10493             case SSLv3_MINOR :
10494                 return "SSLv3";
10495             case TLSv1_MINOR :
10496                 return "TLSv1";
10497             case TLSv1_1_MINOR :
10498                 return "TLSv1.1";
10499             case TLSv1_2_MINOR :
10500                 return "TLSv1.2";
10501             default:
10502                 return "unknown";
10503         }
10504     }
10505     else if (ssl->version.major == DTLS_MAJOR) {
10506         switch (ssl->version.minor) {
10507             case DTLS_MINOR :
10508                 return "DTLS";
10509             case DTLSv1_2_MINOR :
10510                 return "DTLSv1.2";
10511             default:
10512                 return "unknown";
10513         }
10514     }
10515     return "unknown";
10516 }
10517 
10518 
10519 /* current library version */
10520 const char* wolfSSL_lib_version(void)
10521 {
10522     return LIBWOLFSSL_VERSION_STRING;
10523 }
10524 
10525 
10526 /* current library version in hex */
10527 word32 wolfSSL_lib_version_hex(void)
10528 {
10529     return LIBWOLFSSL_VERSION_HEX;
10530 }
10531 
10532 
10533 int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl)
10534 {
10535     WOLFSSL_ENTER("SSL_get_current_cipher_suite");
10536     if (ssl)
10537         return (ssl->options.cipherSuite0 << 8) | ssl->options.cipherSuite;
10538     return 0;
10539 }
10540 
10541 WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL* ssl)
10542 {
10543     WOLFSSL_ENTER("SSL_get_current_cipher");
10544     if (ssl)
10545         return &ssl->cipher;
10546     else
10547         return NULL;
10548 }
10549 
10550 
10551 const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher)
10552 {
10553     (void)cipher;
10554 
10555     WOLFSSL_ENTER("SSL_CIPHER_get_name");
10556 #ifndef NO_ERROR_STRINGS
10557     if (cipher) {
10558 #if defined(HAVE_CHACHA)
10559         if (cipher->ssl->options.cipherSuite0 == CHACHA_BYTE) {
10560         /* ChaCha suites */
10561         switch (cipher->ssl->options.cipherSuite) {
10562 #ifdef HAVE_POLY1305
10563 #ifndef NO_RSA
10564             case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
10565                 return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
10566 
10567             case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
10568                 return "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
10569 
10570             case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
10571                 return "TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256";
10572 
10573             case TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
10574                 return "TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256";
10575 #endif
10576             case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
10577                 return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
10578 
10579             case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
10580                 return "TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256";
10581 #ifndef NO_PSK
10582             case TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 :
10583                 return "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256";
10584             case TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 :
10585                 return "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256";
10586             case TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 :
10587                 return "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256";
10588 #endif /* NO_PSK */
10589 #endif /* HAVE_POLY1305 */
10590             }
10591         }
10592 #endif
10593 
10594 #if defined(HAVE_ECC) || defined(HAVE_AESCCM)
10595         /* Awkwardly, the ECC cipher suites use the ECC_BYTE as expected,
10596          * but the AES-CCM cipher suites also use it, even the ones that
10597          * aren't ECC. */
10598         if (cipher->ssl->options.cipherSuite0 == ECC_BYTE) {
10599         /* ECC suites */
10600         switch (cipher->ssl->options.cipherSuite) {
10601 #ifdef HAVE_ECC
10602 #ifndef NO_RSA
10603             case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
10604                 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
10605 #endif
10606             case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
10607                 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
10608 #ifndef NO_RSA
10609             case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
10610                 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
10611 #endif
10612             case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
10613                 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
10614 #ifndef NO_RSA
10615             case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
10616                 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
10617 #endif
10618             case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
10619                 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
10620 #ifndef NO_RSA
10621             case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
10622                 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
10623 #endif
10624             case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
10625                 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
10626 #ifndef NO_SHA
10627 #ifndef NO_RSA
10628             case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
10629                 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
10630             case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
10631                 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
10632 #endif
10633             case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
10634                 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
10635             case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
10636                 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
10637 #ifndef NO_RC4
10638     #ifndef NO_RSA
10639             case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
10640                 return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
10641     #endif
10642             case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
10643                 return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
10644 #endif
10645 #ifndef NO_DES3
10646     #ifndef NO_RSA
10647             case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
10648                 return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
10649     #endif
10650             case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
10651                 return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
10652 #endif
10653 
10654 #ifndef NO_RSA
10655             case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
10656                 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
10657             case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
10658                 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
10659 #endif
10660             case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
10661                 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
10662             case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
10663                 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
10664 #ifndef NO_RC4
10665     #ifndef NO_RSA
10666             case TLS_ECDH_RSA_WITH_RC4_128_SHA :
10667                 return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
10668     #endif
10669             case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
10670                 return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
10671 #endif
10672 #ifndef NO_DES3
10673     #ifndef NO_RSA
10674             case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
10675                 return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
10676     #endif
10677             case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
10678                 return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
10679 #endif
10680 #endif /* NO_SHA */
10681 
10682 #ifdef HAVE_AESGCM
10683 #ifndef NO_RSA
10684             case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
10685                 return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
10686             case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
10687                 return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
10688 #endif
10689             case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
10690                 return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
10691             case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
10692                 return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
10693 #ifndef NO_RSA
10694             case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
10695                 return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
10696             case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
10697                 return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
10698 #endif
10699             case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
10700                 return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
10701             case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
10702                 return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
10703 #endif
10704             case TLS_ECDHE_ECDSA_WITH_NULL_SHA :
10705                 return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
10706 #ifndef NO_PSK
10707             case TLS_ECDHE_PSK_WITH_NULL_SHA256 :
10708                 return "TLS_ECDHE_PSK_WITH_NULL_SHA256";
10709             case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 :
10710                 return "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256";
10711 #endif
10712 #endif /* HAVE_ECC */
10713 
10714 #ifdef HAVE_AESCCM
10715 #ifndef NO_RSA
10716             case TLS_RSA_WITH_AES_128_CCM_8 :
10717                 return "TLS_RSA_WITH_AES_128_CCM_8";
10718             case TLS_RSA_WITH_AES_256_CCM_8 :
10719                 return "TLS_RSA_WITH_AES_256_CCM_8";
10720 #endif
10721 #ifndef NO_PSK
10722             case TLS_PSK_WITH_AES_128_CCM_8 :
10723                 return "TLS_PSK_WITH_AES_128_CCM_8";
10724             case TLS_PSK_WITH_AES_256_CCM_8 :
10725                 return "TLS_PSK_WITH_AES_256_CCM_8";
10726             case TLS_PSK_WITH_AES_128_CCM :
10727                 return "TLS_PSK_WITH_AES_128_CCM";
10728             case TLS_PSK_WITH_AES_256_CCM :
10729                 return "TLS_PSK_WITH_AES_256_CCM";
10730             case TLS_DHE_PSK_WITH_AES_128_CCM :
10731                 return "TLS_DHE_PSK_WITH_AES_128_CCM";
10732             case TLS_DHE_PSK_WITH_AES_256_CCM :
10733                 return "TLS_DHE_PSK_WITH_AES_256_CCM";
10734 #endif
10735 #ifdef HAVE_ECC
10736             case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
10737                 return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8";
10738             case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
10739                 return "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8";
10740 #endif
10741 #endif
10742 
10743             default:
10744                 return "NONE";
10745         }
10746         }
10747 #endif  /* ECC */
10748         if (cipher->ssl->options.cipherSuite0 != ECC_BYTE &&
10749             cipher->ssl->options.cipherSuite0 != CHACHA_BYTE) {
10750 
10751             /* normal suites */
10752         switch (cipher->ssl->options.cipherSuite) {
10753 #ifndef NO_RSA
10754 #ifndef NO_RC4
10755     #ifndef NO_SHA
10756             case SSL_RSA_WITH_RC4_128_SHA :
10757                 return "SSL_RSA_WITH_RC4_128_SHA";
10758     #endif
10759     #ifndef NO_MD5
10760             case SSL_RSA_WITH_RC4_128_MD5 :
10761                 return "SSL_RSA_WITH_RC4_128_MD5";
10762     #endif
10763 #endif
10764 #ifndef NO_SHA
10765     #ifndef NO_DES3
10766             case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
10767                 return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
10768     #endif
10769     #ifdef HAVE_IDEA
10770             case SSL_RSA_WITH_IDEA_CBC_SHA :
10771                 return "SSL_RSA_WITH_IDEA_CBC_SHA";
10772     #endif
10773 
10774             case TLS_RSA_WITH_AES_128_CBC_SHA :
10775                 return "TLS_RSA_WITH_AES_128_CBC_SHA";
10776             case TLS_RSA_WITH_AES_256_CBC_SHA :
10777                 return "TLS_RSA_WITH_AES_256_CBC_SHA";
10778 #endif
10779             case TLS_RSA_WITH_AES_128_CBC_SHA256 :
10780                 return "TLS_RSA_WITH_AES_128_CBC_SHA256";
10781             case TLS_RSA_WITH_AES_256_CBC_SHA256 :
10782                 return "TLS_RSA_WITH_AES_256_CBC_SHA256";
10783     #ifdef HAVE_BLAKE2
10784             case TLS_RSA_WITH_AES_128_CBC_B2B256:
10785                 return "TLS_RSA_WITH_AES_128_CBC_B2B256";
10786             case TLS_RSA_WITH_AES_256_CBC_B2B256:
10787                 return "TLS_RSA_WITH_AES_256_CBC_B2B256";
10788     #endif
10789 #ifndef NO_SHA
10790             case TLS_RSA_WITH_NULL_SHA :
10791                 return "TLS_RSA_WITH_NULL_SHA";
10792 #endif
10793             case TLS_RSA_WITH_NULL_SHA256 :
10794                 return "TLS_RSA_WITH_NULL_SHA256";
10795 #endif /* NO_RSA */
10796 #ifndef NO_PSK
10797 #ifndef NO_SHA
10798             case TLS_PSK_WITH_AES_128_CBC_SHA :
10799                 return "TLS_PSK_WITH_AES_128_CBC_SHA";
10800             case TLS_PSK_WITH_AES_256_CBC_SHA :
10801                 return "TLS_PSK_WITH_AES_256_CBC_SHA";
10802 #endif
10803 #ifndef NO_SHA256
10804             case TLS_PSK_WITH_AES_128_CBC_SHA256 :
10805                 return "TLS_PSK_WITH_AES_128_CBC_SHA256";
10806             case TLS_PSK_WITH_NULL_SHA256 :
10807                 return "TLS_PSK_WITH_NULL_SHA256";
10808             case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 :
10809                 return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
10810             case TLS_DHE_PSK_WITH_NULL_SHA256 :
10811                 return "TLS_DHE_PSK_WITH_NULL_SHA256";
10812     #ifdef HAVE_AESGCM
10813             case TLS_PSK_WITH_AES_128_GCM_SHA256 :
10814                 return "TLS_PSK_WITH_AES_128_GCM_SHA256";
10815             case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 :
10816                 return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
10817     #endif
10818 #endif
10819 #ifdef WOLFSSL_SHA384
10820             case TLS_PSK_WITH_AES_256_CBC_SHA384 :
10821                 return "TLS_PSK_WITH_AES_256_CBC_SHA384";
10822             case TLS_PSK_WITH_NULL_SHA384 :
10823                 return "TLS_PSK_WITH_NULL_SHA384";
10824             case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 :
10825                 return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
10826             case TLS_DHE_PSK_WITH_NULL_SHA384 :
10827                 return "TLS_DHE_PSK_WITH_NULL_SHA384";
10828     #ifdef HAVE_AESGCM
10829             case TLS_PSK_WITH_AES_256_GCM_SHA384 :
10830                 return "TLS_PSK_WITH_AES_256_GCM_SHA384";
10831             case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 :
10832                 return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
10833     #endif
10834 #endif
10835 #ifndef NO_SHA
10836             case TLS_PSK_WITH_NULL_SHA :
10837                 return "TLS_PSK_WITH_NULL_SHA";
10838 #endif
10839 #endif /* NO_PSK */
10840 #ifndef NO_RSA
10841             case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
10842                 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
10843             case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
10844                 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
10845 #ifndef NO_SHA
10846             case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
10847                 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
10848             case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
10849                 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
10850 #endif
10851 #ifndef NO_HC128
10852     #ifndef NO_MD5
10853             case TLS_RSA_WITH_HC_128_MD5 :
10854                 return "TLS_RSA_WITH_HC_128_MD5";
10855     #endif
10856     #ifndef NO_SHA
10857             case TLS_RSA_WITH_HC_128_SHA :
10858                 return "TLS_RSA_WITH_HC_128_SHA";
10859     #endif
10860     #ifdef HAVE_BLAKE2
10861             case TLS_RSA_WITH_HC_128_B2B256:
10862                 return "TLS_RSA_WITH_HC_128_B2B256";
10863     #endif
10864 #endif /* NO_HC128 */
10865 #ifndef NO_SHA
10866     #ifndef NO_RABBIT
10867             case TLS_RSA_WITH_RABBIT_SHA :
10868                 return "TLS_RSA_WITH_RABBIT_SHA";
10869     #endif
10870     #ifdef HAVE_NTRU
10871         #ifndef NO_RC4
10872             case TLS_NTRU_RSA_WITH_RC4_128_SHA :
10873                 return "TLS_NTRU_RSA_WITH_RC4_128_SHA";
10874         #endif
10875         #ifndef NO_DES3
10876             case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
10877                 return "TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA";
10878         #endif
10879             case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
10880                 return "TLS_NTRU_RSA_WITH_AES_128_CBC_SHA";
10881             case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
10882                 return "TLS_NTRU_RSA_WITH_AES_256_CBC_SHA";
10883     #endif /* HAVE_NTRU */
10884     #ifdef HAVE_QSH
10885             case TLS_QSH :
10886                 return "TLS_QSH";
10887     #endif /* HAVE_QSH*/
10888 #endif /* NO_SHA */
10889             case TLS_RSA_WITH_AES_128_GCM_SHA256 :
10890                 return "TLS_RSA_WITH_AES_128_GCM_SHA256";
10891             case TLS_RSA_WITH_AES_256_GCM_SHA384 :
10892                 return "TLS_RSA_WITH_AES_256_GCM_SHA384";
10893             case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
10894                 return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
10895             case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
10896                 return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
10897 #ifndef NO_SHA
10898             case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
10899                 return "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA";
10900             case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
10901                 return "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA";
10902 #endif
10903             case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
10904                 return "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256";
10905             case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
10906                 return "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256";
10907 #ifndef NO_SHA
10908             case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
10909                 return "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA";
10910             case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
10911                 return "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA";
10912 #endif
10913             case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
10914                 return "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256";
10915             case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
10916                 return "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256";
10917 #endif /* NO_RSA */
10918 #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
10919             case TLS_DH_anon_WITH_AES_128_CBC_SHA :
10920                 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
10921 #endif
10922             default:
10923                 return "NONE";
10924         }  /* switch */
10925         }  /* normal / ECC */
10926     }
10927 #endif /* NO_ERROR_STRINGS */
10928     return "NONE";
10929 }
10930 
10931 
10932 const char* wolfSSL_get_cipher(WOLFSSL* ssl)
10933 {
10934     WOLFSSL_ENTER("wolfSSL_get_cipher");
10935     return wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl));
10936 }
10937 
10938 #ifdef OPENSSL_EXTRA
10939 
10940 
10941 
10942 char* wolfSSL_CIPHER_description(WOLFSSL_CIPHER* cipher, char* in, int len)
10943 {
10944     (void)cipher;
10945     (void)in;
10946     (void)len;
10947     return 0;
10948 }
10949 
10950 
10951 WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl)
10952 {
10953     /* sessions are stored statically, no need for reference count */
10954     return wolfSSL_get_session(ssl);
10955 }
10956 
10957 
10958 void wolfSSL_X509_free(WOLFSSL_X509* x509)
10959 {
10960     WOLFSSL_ENTER("wolfSSL_X509_free");
10961     ExternalFreeX509(x509);
10962 }
10963 
10964 
10965 /* was do nothing */
10966 /*
10967 void OPENSSL_free(void* buf)
10968 {
10969     (void)buf;
10970 }
10971 */
10972 
10973 
10974 int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, char** path,
10975                    int* ssl)
10976 {
10977     (void)url;
10978     (void)host;
10979     (void)port;
10980     (void)path;
10981     (void)ssl;
10982     return 0;
10983 }
10984 
10985 
10986 WOLFSSL_METHOD* wolfSSLv2_client_method(void)
10987 {
10988     return 0;
10989 }
10990 
10991 
10992 WOLFSSL_METHOD* wolfSSLv2_server_method(void)
10993 {
10994     return 0;
10995 }
10996 
10997 
10998 #ifndef NO_MD4
10999 
11000 void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX* md4)
11001 {
11002     /* make sure we have a big enough buffer */
11003     typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1];
11004     (void) sizeof(ok);
11005 
11006     WOLFSSL_ENTER("MD4_Init");
11007     wc_InitMd4((Md4*)md4);
11008 }
11009 
11010 
11011 void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX* md4, const void* data,
11012                        unsigned long len)
11013 {
11014     WOLFSSL_ENTER("MD4_Update");
11015     wc_Md4Update((Md4*)md4, (const byte*)data, (word32)len);
11016 }
11017 
11018 
11019 void wolfSSL_MD4_Final(unsigned char* digest, WOLFSSL_MD4_CTX* md4)
11020 {
11021     WOLFSSL_ENTER("MD4_Final");
11022     wc_Md4Final((Md4*)md4, digest);
11023 }
11024 
11025 #endif /* NO_MD4 */
11026 
11027 
11028 WOLFSSL_BIO* wolfSSL_BIO_pop(WOLFSSL_BIO* top)
11029 {
11030     (void)top;
11031     return 0;
11032 }
11033 
11034 
11035 int wolfSSL_BIO_pending(WOLFSSL_BIO* bio)
11036 {
11037     (void)bio;
11038     return 0;
11039 }
11040 
11041 
11042 
11043 WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_mem(void)
11044 {
11045     static WOLFSSL_BIO_METHOD meth;
11046 
11047     WOLFSSL_ENTER("BIO_s_mem");
11048     meth.type = BIO_MEMORY;
11049 
11050     return &meth;
11051 }
11052 
11053 
11054 WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_base64(void)
11055 {
11056     return 0;
11057 }
11058 
11059 
11060 void wolfSSL_BIO_set_flags(WOLFSSL_BIO* bio, int flags)
11061 {
11062     (void)bio;
11063     (void)flags;
11064 }
11065 
11066 
11067 
11068 void wolfSSL_RAND_screen(void)
11069 {
11070 
11071 }
11072 
11073 
11074 const char* wolfSSL_RAND_file_name(char* fname, unsigned long len)
11075 {
11076     (void)fname;
11077     (void)len;
11078     return 0;
11079 }
11080 
11081 
11082 int wolfSSL_RAND_write_file(const char* fname)
11083 {
11084     (void)fname;
11085     return 0;
11086 }
11087 
11088 
11089 int wolfSSL_RAND_load_file(const char* fname, long len)
11090 {
11091     (void)fname;
11092     /* wolfCrypt provides enough entropy internally or will report error */
11093     if (len == -1)
11094         return 1024;
11095     else
11096         return (int)len;
11097 }
11098 
11099 
11100 int wolfSSL_RAND_egd(const char* path)
11101 {
11102     (void)path;
11103     return 0;
11104 }
11105 
11106 
11107 
11108 WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void)
11109 {
11110     return 0;
11111 }
11112 
11113 
11114 WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void)
11115 {
11116     return 0;
11117 }
11118 
11119 
11120 int wolfSSL_COMP_add_compression_method(int method, void* data)
11121 {
11122     (void)method;
11123     (void)data;
11124     return 0;
11125 }
11126 
11127 
11128 void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f)(
11129                                                           const char*, int))
11130 {
11131     (void)f;
11132 }
11133 
11134 
11135 void wolfSSL_set_dynlock_lock_callback(
11136              void (*f)(int, WOLFSSL_dynlock_value*, const char*, int))
11137 {
11138     (void)f;
11139 }
11140 
11141 
11142 void wolfSSL_set_dynlock_destroy_callback(
11143                   void (*f)(WOLFSSL_dynlock_value*, const char*, int))
11144 {
11145     (void)f;
11146 }
11147 
11148 
11149 
11150 const char* wolfSSL_X509_verify_cert_error_string(long err)
11151 {
11152     return wolfSSL_ERR_reason_error_string(err);
11153 }
11154 
11155 
11156 
11157 int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup, const char* dir,
11158                                long len)
11159 {
11160     (void)lookup;
11161     (void)dir;
11162     (void)len;
11163     return 0;
11164 }
11165 
11166 
11167 int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
11168                                  const char* file, long len)
11169 {
11170     (void)lookup;
11171     (void)file;
11172     (void)len;
11173     return 0;
11174 }
11175 
11176 
11177 WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void)
11178 {
11179     return 0;
11180 }
11181 
11182 
11183 WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void)
11184 {
11185     return 0;
11186 }
11187 
11188 
11189 
11190 WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
11191                                                WOLFSSL_X509_LOOKUP_METHOD* m)
11192 {
11193     (void)store;
11194     (void)m;
11195     return 0;
11196 }
11197 
11198 
11199 int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509)
11200 {
11201     int result = SSL_FATAL_ERROR;
11202 
11203     WOLFSSL_ENTER("wolfSSL_X509_STORE_add_cert");
11204     if (store != NULL && store->cm != NULL && x509 != NULL 
11205                                                 && x509->derCert != NULL) {
11206         DerBuffer* derCert = NULL;
11207         
11208         result = AllocDer(&derCert, x509->derCert->length,
11209             x509->derCert->type, NULL);
11210         if (result == 0) {
11211             /* AddCA() frees the buffer. */
11212             XMEMCPY(derCert->buffer,
11213                             x509->derCert->buffer, x509->derCert->length);
11214             result = AddCA(store->cm, &derCert, WOLFSSL_USER_CA, 1);
11215         }
11216     }
11217 
11218     WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_cert", result);
11219 
11220     if (result != SSL_SUCCESS) {
11221         result = SSL_FATAL_ERROR;
11222     }
11223 
11224     return result;
11225 }
11226 
11227 
11228 WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void)
11229 {
11230     WOLFSSL_X509_STORE* store = NULL;
11231 
11232     store = (WOLFSSL_X509_STORE*)XMALLOC(sizeof(WOLFSSL_X509_STORE), NULL,
11233                                          DYNAMIC_TYPE_X509_STORE);
11234     if (store != NULL) {
11235         store->cm = wolfSSL_CertManagerNew();
11236         if (store->cm == NULL) {
11237             XFREE(store, NULL, DYNAMIC_TYPE_X509_STORE);
11238             store = NULL;
11239         }
11240     }
11241 
11242     return store;
11243 }
11244 
11245 
11246 void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store)
11247 {
11248     if (store != NULL) {
11249         if (store->cm != NULL)
11250         wolfSSL_CertManagerFree(store->cm);
11251         XFREE(store, NULL, DYNAMIC_TYPE_X509_STORE);
11252     }
11253 }
11254 
11255 
11256 int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE* store)
11257 {
11258     (void)store;
11259     return SSL_SUCCESS;
11260 }
11261 
11262 
11263 int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX* ctx, int idx,
11264                             WOLFSSL_X509_NAME* name, WOLFSSL_X509_OBJECT* obj)
11265 {
11266     (void)ctx;
11267     (void)idx;
11268     (void)name;
11269     (void)obj;
11270     return 0;
11271 }
11272 
11273 
11274 WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new(void)
11275 {
11276     WOLFSSL_X509_STORE_CTX* ctx = (WOLFSSL_X509_STORE_CTX*)XMALLOC(
11277                                     sizeof(WOLFSSL_X509_STORE_CTX), NULL,
11278                                     DYNAMIC_TYPE_X509_CTX);
11279     if (ctx != NULL)
11280         wolfSSL_X509_STORE_CTX_init(ctx, NULL, NULL, NULL);
11281 
11282     return ctx;
11283 }
11284 
11285 
11286 int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
11287      WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509, STACK_OF(WOLFSSL_X509)* sk)
11288 {
11289     (void)sk;
11290     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_init");
11291     if (ctx != NULL) {
11292         ctx->store = store;
11293         ctx->current_cert = x509;
11294         ctx->domain = NULL;
11295         ctx->ex_data = NULL;
11296         ctx->userCtx = NULL;
11297         ctx->error = 0;
11298         ctx->error_depth = 0;
11299         ctx->discardSessionCerts = 0;
11300         return SSL_SUCCESS;
11301     }
11302     return SSL_FATAL_ERROR;
11303 }
11304 
11305 
11306 void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx)
11307 {
11308     if (ctx != NULL) {
11309         if (ctx->store != NULL)
11310             wolfSSL_X509_STORE_free(ctx->store);
11311         if (ctx->current_cert != NULL)
11312             wolfSSL_FreeX509(ctx->current_cert);
11313         XFREE(ctx, NULL, DYNAMIC_TYPE_X509_CTX);
11314     }
11315 }
11316 
11317 
11318 void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX* ctx)
11319 {
11320     (void)ctx;
11321 }
11322 
11323 
11324 int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
11325 {
11326     if (ctx != NULL && ctx->store != NULL && ctx->store->cm != NULL
11327          && ctx->current_cert != NULL && ctx->current_cert->derCert != NULL) {
11328         return wolfSSL_CertManagerVerifyBuffer(ctx->store->cm,
11329                     ctx->current_cert->derCert->buffer,
11330                     ctx->current_cert->derCert->length,
11331                     SSL_FILETYPE_ASN1);
11332     }
11333     return SSL_FATAL_ERROR;
11334 }
11335 
11336 
11337 WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl)
11338 {
11339     (void)crl;
11340     return 0;
11341 }
11342 
11343 
11344 WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
11345 {
11346     (void)crl;
11347     return 0;
11348 }
11349 
11350 
11351 
11352 WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
11353 {
11354     WOLFSSL_EVP_PKEY* key = NULL;
11355     if (x509 != NULL) {
11356         key = (WOLFSSL_EVP_PKEY*)XMALLOC(
11357                     sizeof(WOLFSSL_EVP_PKEY), NULL, DYNAMIC_TYPE_PUBLIC_KEY);
11358         if (key != NULL) {
11359             key->type = x509->pubKeyOID;
11360             key->save_type = 0;
11361             key->pkey.ptr = (char*)XMALLOC(
11362                         x509->pubKey.length, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
11363             if (key->pkey.ptr == NULL) {
11364                 XFREE(key, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
11365                 return NULL;
11366             }
11367             XMEMCPY(key->pkey.ptr,
11368                                   x509->pubKey.buffer, x509->pubKey.length);
11369             key->pkey_sz = x509->pubKey.length;
11370             #ifdef HAVE_ECC
11371                 key->pkey_curve = (int)x509->pkCurveOID;
11372             #endif /* HAVE_ECC */
11373         }
11374     }
11375     return key;
11376 }
11377 
11378 
11379 int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
11380 {
11381     (void)crl;
11382     (void)key;
11383     return 0;
11384 }
11385 
11386 
11387 void wolfSSL_X509_STORE_CTX_set_error(WOLFSSL_X509_STORE_CTX* ctx, int err)
11388 {
11389     (void)ctx;
11390     (void)err;
11391 }
11392 
11393 
11394 void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj)
11395 {
11396     (void)obj;
11397 }
11398 
11399 
11400 void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key)
11401 {
11402     if (key != NULL) {
11403         if (key->pkey.ptr != NULL)
11404             XFREE(key->pkey.ptr, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
11405         XFREE(key, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
11406     }
11407 }
11408 
11409 
11410 int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME* asnTime)
11411 {
11412     (void)asnTime;
11413     return 0;
11414 }
11415 
11416 
11417 int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED* revoked)
11418 {
11419     (void)revoked;
11420     return 0;
11421 }
11422 
11423 
11424 
11425 WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL* crl)
11426 {
11427     (void)crl;
11428     return 0;
11429 }
11430 
11431 
11432 WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(
11433                                     WOLFSSL_X509_REVOKED* revoked, int value)
11434 {
11435     (void)revoked;
11436     (void)value;
11437     return 0;
11438 }
11439 
11440 
11441 
11442 WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
11443 {
11444     (void)x509;
11445     return 0;
11446 }
11447 
11448 
11449 int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime)
11450 {
11451     (void)bio;
11452     (void)asnTime;
11453     return 0;
11454 }
11455 
11456 
11457 
11458 int wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER* a,
11459                             const WOLFSSL_ASN1_INTEGER* b)
11460 {
11461     (void)a;
11462     (void)b;
11463     return 0;
11464 }
11465 
11466 
11467 long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER* i)
11468 {
11469     (void)i;
11470     return 0;
11471 }
11472 
11473 
11474 
11475 void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx)
11476 {
11477     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_ex_data");
11478 #if defined(FORTRESS) || defined(HAVE_STUNNEL)
11479     if (ctx != NULL && idx == 0)
11480         return ctx->ex_data;
11481 #else
11482     (void)ctx;
11483     (void)idx;
11484 #endif
11485     return 0;
11486 }
11487 
11488 
11489 int wolfSSL_get_ex_data_X509_STORE_CTX_idx(void)
11490 {
11491     WOLFSSL_ENTER("wolfSSL_get_ex_data_X509_STORE_CTX_idx");
11492     return 0;
11493 }
11494 
11495 
11496 void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX* ctx,
11497        void (*f)(const WOLFSSL* ssl, int type, int val))
11498 {
11499     (void)ctx;
11500     (void)f;
11501 }
11502 
11503 
11504 unsigned long wolfSSL_ERR_peek_error(void)
11505 {
11506     return 0;
11507 }
11508 
11509 
11510 int wolfSSL_ERR_GET_REASON(unsigned long err)
11511 {
11512     (void)err;
11513     return 0;
11514 }
11515 
11516 
11517 char* wolfSSL_alert_type_string_long(int alertID)
11518 {
11519     (void)alertID;
11520     return 0;
11521 }
11522 
11523 
11524 char* wolfSSL_alert_desc_string_long(int alertID)
11525 {
11526     (void)alertID;
11527     return 0;
11528 }
11529 
11530 
11531 char* wolfSSL_state_string_long(const WOLFSSL* ssl)
11532 {
11533     (void)ssl;
11534     return 0;
11535 }
11536 
11537 
11538 int wolfSSL_PEM_def_callback(char* name, int num, int w, void* key)
11539 {
11540     (void)name;
11541     (void)num;
11542     (void)w;
11543     (void)key;
11544     return 0;
11545 }
11546 
11547 
11548 long wolfSSL_CTX_sess_accept(WOLFSSL_CTX* ctx)
11549 {
11550     (void)ctx;
11551     return 0;
11552 }
11553 
11554 
11555 long wolfSSL_CTX_sess_connect(WOLFSSL_CTX* ctx)
11556 {
11557     (void)ctx;
11558     return 0;
11559 }
11560 
11561 
11562 long wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX* ctx)
11563 {
11564     (void)ctx;
11565     return 0;
11566 }
11567 
11568 
11569 long wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX* ctx)
11570 {
11571     (void)ctx;
11572     return 0;
11573 }
11574 
11575 
11576 long wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX* ctx)
11577 {
11578     (void)ctx;
11579     return 0;
11580 }
11581 
11582 
11583 long wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX* ctx)
11584 {
11585     (void)ctx;
11586     return 0;
11587 }
11588 
11589 
11590 long wolfSSL_CTX_sess_hits(WOLFSSL_CTX* ctx)
11591 {
11592     (void)ctx;
11593     return 0;
11594 }
11595 
11596 
11597 long wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX* ctx)
11598 {
11599     (void)ctx;
11600     return 0;
11601 }
11602 
11603 
11604 long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX* ctx)
11605 {
11606     (void)ctx;
11607     return 0;
11608 }
11609 
11610 
11611 long wolfSSL_CTX_sess_misses(WOLFSSL_CTX* ctx)
11612 {
11613     (void)ctx;
11614     return 0;
11615 }
11616 
11617 
11618 long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX* ctx)
11619 {
11620     (void)ctx;
11621     return 0;
11622 }
11623 
11624 
11625 long wolfSSL_CTX_sess_number(WOLFSSL_CTX* ctx)
11626 {
11627     (void)ctx;
11628     return 0;
11629 }
11630 
11631 #ifndef NO_DES3
11632 
11633 void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock* myDes,
11634                                                WOLFSSL_DES_key_schedule* key)
11635 {
11636     (void)myDes;
11637     (void)key;
11638 }
11639 
11640 
11641 void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* myDes)
11642 {
11643     (void)myDes;
11644 }
11645 
11646 
11647 void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* desa,
11648              WOLFSSL_DES_cblock* desb, WOLFSSL_DES_key_schedule* key, int len)
11649 {
11650     (void)desa;
11651     (void)desb;
11652     (void)key;
11653     (void)len;
11654 }
11655 
11656 #endif /* NO_DES3 */
11657 
11658 int wolfSSL_BIO_printf(WOLFSSL_BIO* bio, const char* format, ...)
11659 {
11660     (void)bio;
11661     (void)format;
11662     return 0;
11663 }
11664 
11665 
11666 int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a)
11667 {
11668     (void)bio;
11669     (void)a;
11670     return 0;
11671 }
11672 
11673 
11674 int  wolfSSL_sk_num(WOLFSSL_X509_REVOKED* rev)
11675 {
11676     (void)rev;
11677     return 0;
11678 }
11679 
11680 
11681 void* wolfSSL_sk_value(WOLFSSL_X509_REVOKED* rev, int i)
11682 {
11683     (void)rev;
11684     (void)i;
11685     return 0;
11686 }
11687 
11688 
11689 /* stunnel 4.28 needs */
11690 void wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX* ctx,
11691                     WOLFSSL_SESSION*(*f)(WOLFSSL*, unsigned char*, int, int*))
11692 {
11693     (void)ctx;
11694     (void)f;
11695 }
11696 
11697 
11698 void wolfSSL_CTX_sess_set_new_cb(WOLFSSL_CTX* ctx,
11699                              int (*f)(WOLFSSL*, WOLFSSL_SESSION*))
11700 {
11701     (void)ctx;
11702     (void)f;
11703 }
11704 
11705 
11706 void wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX* ctx, void (*f)(WOLFSSL_CTX*,
11707                                                         WOLFSSL_SESSION*))
11708 {
11709     (void)ctx;
11710     (void)f;
11711 }
11712 
11713 
11714 int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
11715 {
11716     (void)sess;
11717     (void)p;
11718     return sizeof(WOLFSSL_SESSION);
11719 }
11720 
11721 
11722 WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
11723                                 const unsigned char** p, long i)
11724 {
11725     (void)p;
11726     (void)i;
11727     if (sess)
11728         return *sess;
11729     return NULL;
11730 }
11731 
11732 
11733 long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION* sess)
11734 {
11735     WOLFSSL_ENTER("wolfSSL_SESSION_get_timeout");
11736     return sess->timeout;
11737 }
11738 
11739 
11740 long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION* sess)
11741 {
11742     WOLFSSL_ENTER("wolfSSL_SESSION_get_time");
11743     return sess->bornOn;
11744 }
11745 
11746 
11747 #endif /* OPENSSL_EXTRA */
11748 
11749 
11750 #ifdef KEEP_PEER_CERT
11751 char*  wolfSSL_X509_get_subjectCN(WOLFSSL_X509* x509)
11752 {
11753     if (x509 == NULL)
11754         return NULL;
11755 
11756     return x509->subjectCN;
11757 }
11758 #endif /* KEEP_PEER_CERT */
11759 
11760 #ifdef OPENSSL_EXTRA
11761 
11762 #ifdef FORTRESS
11763 int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname)
11764 {
11765     int ret = SSL_FATAL_ERROR;
11766 
11767     WOLFSSL_ENTER("wolfSSL_cmp_peer_cert_to_file");
11768     if (ssl != NULL && fname != NULL)
11769     {
11770     #ifdef WOLFSSL_SMALL_STACK
11771         EncryptedInfo* info = NULL;
11772         byte           staticBuffer[1]; /* force heap usage */
11773     #else
11774         EncryptedInfo  info[1];
11775         byte           staticBuffer[FILE_BUFFER_SIZE];
11776     #endif
11777         byte*          myBuffer  = staticBuffer;
11778         int            dynamic   = 0;
11779         XFILE          file      = XBADFILE;
11780         long           sz        = 0;
11781         int            eccKey    = 0;
11782         WOLFSSL_CTX*   ctx       = ssl->ctx;
11783         WOLFSSL_X509*  peer_cert = &ssl->peerCert;
11784         DerBuffer*     fileDer = NULL;
11785 
11786         file = XFOPEN(fname, "rb");
11787         if (file == XBADFILE)
11788             return SSL_BAD_FILE;
11789 
11790         XFSEEK(file, 0, XSEEK_END);
11791         sz = XFTELL(file);
11792         XREWIND(file);
11793 
11794         if (sz > (long)sizeof(staticBuffer)) {
11795             WOLFSSL_MSG("Getting dynamic buffer");
11796             myBuffer = (byte*)XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
11797             dynamic = 1;
11798         }
11799 
11800     #ifdef WOLFSSL_SMALL_STACK
11801         info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
11802                                                    DYNAMIC_TYPE_TMP_BUFFER);
11803         if (info == NULL)
11804             ret = MEMORY_E;
11805         else
11806     #endif
11807         {
11808             info->set = 0;
11809             info->ctx = ctx;
11810             info->consumed = 0;
11811 
11812             if ((myBuffer != NULL) &&
11813                 (sz > 0) &&
11814                 (XFREAD(myBuffer, sz, 1, file) > 0) &&
11815                 (PemToDer(myBuffer, sz, CERT_TYPE,
11816                           &fileDer, ctx->heap, info, &eccKey) == 0) &&
11817                 (fileDer->length != 0) &&
11818                 (fileDer->length == peer_cert->derCert->length) &&
11819                 (XMEMCMP(peer_cert->derCert->buffer, fileDer->buffer,
11820                                                     fileDer->length) == 0))
11821             {
11822                 ret = 0;
11823             }
11824 
11825         #ifdef WOLFSSL_SMALL_STACK
11826             XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11827         #endif
11828         }
11829 
11830         FreeDer(&fileDer);
11831 
11832         if (dynamic)
11833             XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
11834 
11835         XFCLOSE(file);
11836     }
11837 
11838     return ret;
11839 }
11840 #endif
11841 
11842 
11843 static WC_RNG globalRNG;
11844 static int initGlobalRNG = 0;
11845 
11846 /* SSL_SUCCESS on ok */
11847 int wolfSSL_RAND_seed(const void* seed, int len)
11848 {
11849 
11850     WOLFSSL_MSG("wolfSSL_RAND_seed");
11851 
11852     (void)seed;
11853     (void)len;
11854 
11855     if (initGlobalRNG == 0) {
11856         if (wc_InitRng(&globalRNG) < 0) {
11857             WOLFSSL_MSG("wolfSSL Init Global RNG failed");
11858             return 0;
11859         }
11860         initGlobalRNG = 1;
11861     }
11862 
11863     return SSL_SUCCESS;
11864 }
11865 
11866 
11867 /* SSL_SUCCESS on ok */
11868 int wolfSSL_RAND_bytes(unsigned char* buf, int num)
11869 {
11870     int     ret = 0;
11871     int     initTmpRng = 0;
11872     WC_RNG* rng = NULL;
11873 #ifdef WOLFSSL_SMALL_STACK
11874     WC_RNG* tmpRNG = NULL;
11875 #else
11876     WC_RNG  tmpRNG[1];
11877 #endif
11878 
11879     WOLFSSL_ENTER("wolfSSL_RAND_bytes");
11880 
11881 #ifdef WOLFSSL_SMALL_STACK
11882     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
11883     if (tmpRNG == NULL)
11884         return ret;
11885 #endif
11886 
11887     if (wc_InitRng(tmpRNG) == 0) {
11888         rng = tmpRNG;
11889         initTmpRng = 1;
11890     }
11891     else if (initGlobalRNG)
11892         rng = &globalRNG;
11893 
11894     if (rng) {
11895         if (wc_RNG_GenerateBlock(rng, buf, num) != 0)
11896             WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
11897         else
11898             ret = SSL_SUCCESS;
11899     }
11900 
11901     if (initTmpRng)
11902         wc_FreeRng(tmpRNG);
11903 
11904 #ifdef WOLFSSL_SMALL_STACK
11905     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11906 #endif
11907 
11908     return ret;
11909 }
11910 
11911 WOLFSSL_BN_CTX* wolfSSL_BN_CTX_new(void)
11912 {
11913     static int ctx;  /* wolfcrypt doesn't now need ctx */
11914 
11915     WOLFSSL_MSG("wolfSSL_BN_CTX_new");
11916 
11917     return (WOLFSSL_BN_CTX*)&ctx;
11918 }
11919 
11920 void wolfSSL_BN_CTX_init(WOLFSSL_BN_CTX* ctx)
11921 {
11922     (void)ctx;
11923     WOLFSSL_MSG("wolfSSL_BN_CTX_init");
11924 }
11925 
11926 
11927 void wolfSSL_BN_CTX_free(WOLFSSL_BN_CTX* ctx)
11928 {
11929     (void)ctx;
11930     WOLFSSL_MSG("wolfSSL_BN_CTX_free");
11931 
11932     /* do free since static ctx that does nothing */
11933 }
11934 
11935 
11936 static void InitwolfSSL_BigNum(WOLFSSL_BIGNUM* bn)
11937 {
11938     WOLFSSL_MSG("InitwolfSSL_BigNum");
11939     if (bn) {
11940         bn->neg      = 0;
11941         bn->internal = NULL;
11942     }
11943 }
11944 
11945 
11946 WOLFSSL_BIGNUM* wolfSSL_BN_new(void)
11947 {
11948     WOLFSSL_BIGNUM* external;
11949     mp_int*        mpi;
11950 
11951     WOLFSSL_MSG("wolfSSL_BN_new");
11952 
11953     mpi = (mp_int*) XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11954     if (mpi == NULL) {
11955         WOLFSSL_MSG("wolfSSL_BN_new malloc mpi failure");
11956         return NULL;
11957     }
11958 
11959     external = (WOLFSSL_BIGNUM*) XMALLOC(sizeof(WOLFSSL_BIGNUM), NULL,
11960                                         DYNAMIC_TYPE_BIGINT);
11961     if (external == NULL) {
11962         WOLFSSL_MSG("wolfSSL_BN_new malloc WOLFSSL_BIGNUM failure");
11963         XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
11964         return NULL;
11965     }
11966 
11967     InitwolfSSL_BigNum(external);
11968     external->internal = mpi;
11969     if (mp_init(mpi) != MP_OKAY) {
11970         wolfSSL_BN_free(external);
11971         return NULL;
11972     }
11973 
11974     return external;
11975 }
11976 
11977 
11978 void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn)
11979 {
11980     WOLFSSL_MSG("wolfSSL_BN_free");
11981     if (bn) {
11982         if (bn->internal) {
11983             mp_clear((mp_int*)bn->internal);
11984             XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT);
11985             bn->internal = NULL;
11986         }
11987         XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT);
11988         bn = NULL;
11989     }
11990 }
11991 
11992 
11993 void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM* bn)
11994 {
11995     WOLFSSL_MSG("wolfSSL_BN_clear_free");
11996 
11997     wolfSSL_BN_free(bn);
11998 }
11999 
12000 
12001 /* SSL_SUCCESS on ok */
12002 int wolfSSL_BN_sub(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
12003                   const WOLFSSL_BIGNUM* b)
12004 {
12005     WOLFSSL_MSG("wolfSSL_BN_sub");
12006 
12007     if (r == NULL || a == NULL || b == NULL)
12008         return 0;
12009 
12010     if (mp_sub((mp_int*)a->internal,(mp_int*)b->internal,
12011                (mp_int*)r->internal) == MP_OKAY)
12012         return SSL_SUCCESS;
12013 
12014     WOLFSSL_MSG("wolfSSL_BN_sub mp_sub failed");
12015     return 0;
12016 }
12017 
12018 
12019 /* SSL_SUCCESS on ok */
12020 int wolfSSL_BN_mod(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
12021                   const WOLFSSL_BIGNUM* b, const WOLFSSL_BN_CTX* c)
12022 {
12023     (void)c;
12024     WOLFSSL_MSG("wolfSSL_BN_mod");
12025 
12026     if (r == NULL || a == NULL || b == NULL)
12027         return 0;
12028 
12029     if (mp_mod((mp_int*)a->internal,(mp_int*)b->internal,
12030                (mp_int*)r->internal) == MP_OKAY)
12031         return SSL_SUCCESS;
12032 
12033     WOLFSSL_MSG("wolfSSL_BN_mod mp_mod failed");
12034     return 0;
12035 }
12036 
12037 
12038 const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void)
12039 {
12040     static WOLFSSL_BIGNUM* bn_one = NULL;
12041 
12042     WOLFSSL_MSG("wolfSSL_BN_value_one");
12043 
12044     if (bn_one == NULL) {
12045         bn_one = wolfSSL_BN_new();
12046         if (bn_one)
12047             mp_set_int((mp_int*)bn_one->internal, 1);
12048     }
12049 
12050     return bn_one;
12051 }
12052 
12053 /* return compliant with OpenSSL
12054  *   size of BIGNUM in bytes, 0 if error */
12055 int wolfSSL_BN_num_bytes(const WOLFSSL_BIGNUM* bn)
12056 {
12057     WOLFSSL_MSG("wolfSSL_BN_num_bytes");
12058 
12059     if (bn == NULL || bn->internal == NULL)
12060         return SSL_FAILURE;
12061 
12062     return mp_unsigned_bin_size((mp_int*)bn->internal);
12063 }
12064 
12065 /* return compliant with OpenSSL
12066  *   size of BIGNUM in bits, 0 if error */
12067 int wolfSSL_BN_num_bits(const WOLFSSL_BIGNUM* bn)
12068 {
12069     WOLFSSL_MSG("wolfSSL_BN_num_bits");
12070 
12071     if (bn == NULL || bn->internal == NULL)
12072         return SSL_FAILURE;
12073 
12074     return mp_count_bits((mp_int*)bn->internal);
12075 }
12076 
12077 /* return compliant with OpenSSL
12078  *   1 if BIGNUM is zero, 0 else */
12079 int wolfSSL_BN_is_zero(const WOLFSSL_BIGNUM* bn)
12080 {
12081     WOLFSSL_MSG("wolfSSL_BN_is_zero");
12082 
12083     if (bn == NULL || bn->internal == NULL)
12084         return SSL_FAILURE;
12085 
12086     if (mp_iszero((mp_int*)bn->internal) == MP_YES)
12087         return SSL_SUCCESS;
12088 
12089     return SSL_FAILURE;
12090 }
12091 
12092 /* return compliant with OpenSSL
12093  *   1 if BIGNUM is one, 0 else */
12094 int wolfSSL_BN_is_one(const WOLFSSL_BIGNUM* bn)
12095 {
12096     WOLFSSL_MSG("wolfSSL_BN_is_one");
12097 
12098     if (bn == NULL || bn->internal == NULL)
12099         return SSL_FAILURE;
12100 
12101     if (mp_cmp_d((mp_int*)bn->internal, 1) == MP_EQ)
12102         return SSL_SUCCESS;
12103 
12104     return SSL_FAILURE;
12105 }
12106 
12107 /* return compliant with OpenSSL
12108  *   1 if BIGNUM is odd, 0 else */
12109 int wolfSSL_BN_is_odd(const WOLFSSL_BIGNUM* bn)
12110 {
12111     WOLFSSL_MSG("wolfSSL_BN_is_odd");
12112 
12113     if (bn == NULL || bn->internal == NULL)
12114         return SSL_FAILURE;
12115 
12116     if (mp_isodd((mp_int*)bn->internal) == MP_YES)
12117         return SSL_SUCCESS;
12118 
12119     return SSL_FAILURE;
12120 }
12121 
12122 /* return compliant with OpenSSL
12123  *   -1 if a < b, 0 if a == b and 1 if a > b
12124  */
12125 int wolfSSL_BN_cmp(const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b)
12126 {
12127     int ret;
12128 
12129     WOLFSSL_MSG("wolfSSL_BN_cmp");
12130 
12131     if (a == NULL || a->internal == NULL || b == NULL || b->internal == NULL)
12132         return SSL_FATAL_ERROR;
12133 
12134     ret = mp_cmp((mp_int*)a->internal, (mp_int*)b->internal);
12135 
12136     return (ret == MP_EQ ? 0 : (ret == MP_GT ? 1 : -1));
12137 }
12138 
12139 /* return compliant with OpenSSL
12140  *   length of BIGNUM in bytes, -1 if error */
12141 int wolfSSL_BN_bn2bin(const WOLFSSL_BIGNUM* bn, unsigned char* r)
12142 {
12143     WOLFSSL_MSG("wolfSSL_BN_bn2bin");
12144 
12145     if (bn == NULL || bn->internal == NULL) {
12146         WOLFSSL_MSG("NULL bn error");
12147         return SSL_FATAL_ERROR;
12148     }
12149 
12150     if (r == NULL)
12151         return mp_unsigned_bin_size((mp_int*)bn->internal);
12152 
12153     if (mp_to_unsigned_bin((mp_int*)bn->internal, r) != MP_OKAY) {
12154         WOLFSSL_MSG("mp_to_unsigned_bin error");
12155         return SSL_FATAL_ERROR;
12156     }
12157 
12158     return mp_unsigned_bin_size((mp_int*)bn->internal);
12159 }
12160 
12161 
12162 WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char* str, int len,
12163                             WOLFSSL_BIGNUM* ret)
12164 {
12165     int weOwn = 0;
12166 
12167     WOLFSSL_MSG("wolfSSL_BN_bin2bn");
12168 
12169     /* if ret is null create a BN */
12170     if (ret == NULL) {
12171         ret = wolfSSL_BN_new();
12172         weOwn = 1;
12173         if (ret == NULL)
12174             return NULL;
12175     }
12176 
12177     /* check ret and ret->internal then read in value */
12178     if (ret && ret->internal) {
12179         if (mp_read_unsigned_bin((mp_int*)ret->internal, str, len) != 0) {
12180             WOLFSSL_MSG("mp_read_unsigned_bin failure");
12181             if (weOwn)
12182                 wolfSSL_BN_free(ret);
12183             return NULL;
12184         }
12185     }
12186 
12187     return ret;
12188 }
12189 
12190 /* return compliant with OpenSSL
12191  *   1 if success, 0 if error */
12192 int wolfSSL_mask_bits(WOLFSSL_BIGNUM* bn, int n)
12193 {
12194     (void)bn;
12195     (void)n;
12196     WOLFSSL_MSG("wolfSSL_BN_mask_bits");
12197 
12198     return SSL_FAILURE;
12199 }
12200 
12201 
12202 /* SSL_SUCCESS on ok */
12203 int wolfSSL_BN_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
12204 {
12205     int           ret    = 0;
12206     int           len    = bits / 8;
12207     int           initTmpRng = 0;
12208     WC_RNG*       rng    = NULL;
12209 #ifdef WOLFSSL_SMALL_STACK
12210     WC_RNG*       tmpRNG = NULL;
12211     byte*         buff   = NULL;
12212 #else
12213     WC_RNG        tmpRNG[1];
12214     byte          buff[1024];
12215 #endif
12216 
12217     (void)top;
12218     (void)bottom;
12219     WOLFSSL_MSG("wolfSSL_BN_rand");
12220 
12221     if (bits % 8)
12222         len++;
12223 
12224 #ifdef WOLFSSL_SMALL_STACK
12225     buff   = (byte*)XMALLOC(1024,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
12226     tmpRNG = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
12227     if (buff == NULL || tmpRNG == NULL) {
12228         XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
12229         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12230         return ret;
12231     }
12232 #endif
12233 
12234     if (bn == NULL || bn->internal == NULL)
12235         WOLFSSL_MSG("Bad function arguments");
12236     else if (wc_InitRng(tmpRNG) == 0) {
12237         rng = tmpRNG;
12238         initTmpRng = 1;
12239     }
12240     else if (initGlobalRNG)
12241         rng = &globalRNG;
12242 
12243     if (rng) {
12244         if (wc_RNG_GenerateBlock(rng, buff, len) != 0)
12245             WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
12246         else {
12247             buff[0]     |= 0x80 | 0x40;
12248             buff[len-1] |= 0x01;
12249 
12250             if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY)
12251                 WOLFSSL_MSG("mp read bin failed");
12252             else
12253                 ret = SSL_SUCCESS;
12254         }
12255     }
12256 
12257     if (initTmpRng)
12258         wc_FreeRng(tmpRNG);
12259 
12260 #ifdef WOLFSSL_SMALL_STACK
12261     XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
12262     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12263 #endif
12264 
12265     return ret;
12266 }
12267 
12268 /* return code compliant with OpenSSL :
12269  *   1 if bit set, 0 else
12270  */
12271 int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM* bn, int n)
12272 {
12273     if (bn == NULL || bn->internal == NULL) {
12274         WOLFSSL_MSG("bn NULL error");
12275         return SSL_FAILURE;
12276     }
12277 
12278     if (n > DIGIT_BIT) {
12279         WOLFSSL_MSG("input bit count too large");
12280         return SSL_FAILURE;
12281     }
12282 
12283     return mp_is_bit_set((mp_int*)bn->internal, (mp_digit)n);
12284 }
12285 
12286 /* return code compliant with OpenSSL :
12287  *   1 if success, 0 else
12288  */
12289 int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n)
12290 {
12291     if (bn == NULL || bn->internal == NULL) {
12292         WOLFSSL_MSG("bn NULL error");
12293         return SSL_FAILURE;
12294     }
12295 
12296     if (mp_set_bit((mp_int*)bn->internal, n) != MP_OKAY) {
12297         WOLFSSL_MSG("mp_set_int error");
12298         return SSL_FAILURE;
12299     }
12300 
12301     return SSL_SUCCESS;
12302 }
12303 
12304 
12305 /* SSL_SUCCESS on ok */
12306 int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str)
12307 {
12308     int     ret     = 0;
12309     word32  decSz   = 1024;
12310 #ifdef WOLFSSL_SMALL_STACK
12311     byte*   decoded = NULL;
12312 #else
12313     byte    decoded[1024];
12314 #endif
12315 
12316     WOLFSSL_MSG("wolfSSL_BN_hex2bn");
12317 
12318 #ifdef WOLFSSL_SMALL_STACK
12319     decoded = (byte*)XMALLOC(decSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12320     if (decoded == NULL)
12321         return ret;
12322 #endif
12323 
12324     if (str == NULL)
12325         WOLFSSL_MSG("Bad function argument");
12326     else if (Base16_Decode((byte*)str, (int)XSTRLEN(str), decoded, &decSz) < 0)
12327         WOLFSSL_MSG("Bad Base16_Decode error");
12328     else if (bn == NULL)
12329         ret = decSz;
12330     else {
12331         if (*bn == NULL)
12332             *bn = wolfSSL_BN_new();
12333 
12334         if (*bn == NULL)
12335             WOLFSSL_MSG("BN new failed");
12336         else if (wolfSSL_BN_bin2bn(decoded, decSz, *bn) == NULL)
12337             WOLFSSL_MSG("Bad bin2bn error");
12338         else
12339             ret = SSL_SUCCESS;
12340     }
12341 
12342 #ifdef WOLFSSL_SMALL_STACK
12343     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12344 #endif
12345 
12346     return ret;
12347 }
12348 
12349 
12350 WOLFSSL_BIGNUM* wolfSSL_BN_dup(const WOLFSSL_BIGNUM* bn)
12351 {
12352     WOLFSSL_BIGNUM* ret;
12353 
12354     WOLFSSL_MSG("wolfSSL_BN_dup");
12355 
12356     if (bn == NULL || bn->internal == NULL) {
12357         WOLFSSL_MSG("bn NULL error");
12358         return NULL;
12359     }
12360 
12361     ret = wolfSSL_BN_new();
12362     if (ret == NULL) {
12363         WOLFSSL_MSG("bn new error");
12364         return NULL;
12365     }
12366 
12367     if (mp_copy((mp_int*)bn->internal, (mp_int*)ret->internal) != MP_OKAY) {
12368         WOLFSSL_MSG("mp_copy error");
12369         wolfSSL_BN_free(ret);
12370         return NULL;
12371     }
12372 
12373     ret->neg = bn->neg;
12374 
12375     return ret;
12376 }
12377 
12378 
12379 WOLFSSL_BIGNUM* wolfSSL_BN_copy(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* bn)
12380 {
12381     WOLFSSL_MSG("wolfSSL_BN_copy");
12382 
12383     if (mp_copy((mp_int*)bn->internal, (mp_int*)r->internal) != MP_OKAY) {
12384         WOLFSSL_MSG("mp_copy error");
12385         return NULL;
12386     }
12387 
12388     r->neg = bn->neg;
12389 
12390     return r;
12391 }
12392 
12393 /* return code compliant with OpenSSL :
12394  *   1 if success, 0 else
12395  */
12396 int wolfSSL_BN_set_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
12397 {
12398     WOLFSSL_MSG("wolfSSL_BN_set_word");
12399 
12400     if (mp_set_int((mp_int*)bn->internal, w) != MP_OKAY) {
12401         WOLFSSL_MSG("mp_init_set_int error");
12402         return SSL_FAILURE;
12403     }
12404 
12405     return SSL_SUCCESS;
12406 }
12407 
12408 /* return code compliant with OpenSSL :
12409  *   number length in decimal if success, 0 if error
12410  */
12411 int wolfSSL_BN_dec2bn(WOLFSSL_BIGNUM** bn, const char* str)
12412 {
12413     (void)bn;
12414     (void)str;
12415 
12416     WOLFSSL_MSG("wolfSSL_BN_dec2bn");
12417 
12418     return SSL_FAILURE;
12419 }
12420 
12421 
12422 #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
12423 char *wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM *bn)
12424 {
12425     int len = 0;
12426     char *buf;
12427 
12428     WOLFSSL_MSG("wolfSSL_BN_bn2dec");
12429 
12430     if (bn == NULL || bn->internal == NULL) {
12431         WOLFSSL_MSG("bn NULL error");
12432         return NULL;
12433     }
12434 
12435     if (mp_radix_size((mp_int*)bn->internal, 10, &len) != MP_OKAY) {
12436         WOLFSSL_MSG("mp_radix_size failure");
12437         return NULL;
12438     }
12439 
12440     buf = (char*) XMALLOC(len, NULL, DYNAMIC_TYPE_ECC);
12441     if (buf == NULL) {
12442         WOLFSSL_MSG("wolfSSL_BN_bn2hex malloc buffer failure");
12443         return NULL;
12444     }
12445 
12446     if (mp_toradix((mp_int*)bn->internal, buf, 10) != MP_OKAY) {
12447         XFREE(buf, NULL, DYNAMIC_TYPE_ECC);
12448         return NULL;
12449     }
12450 
12451     return buf;
12452 }
12453 #else
12454 char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM* bn)
12455 {
12456     (void)bn;
12457 
12458     WOLFSSL_MSG("wolfSSL_BN_bn2dec");
12459 
12460     return NULL;
12461 }
12462 #endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
12463 
12464 /* return code compliant with OpenSSL :
12465  *   1 if success, 0 else
12466  */
12467 int wolfSSL_BN_lshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
12468 {
12469     WOLFSSL_MSG("wolfSSL_BN_lshift");
12470 
12471     if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
12472         WOLFSSL_MSG("bn NULL error");
12473         return SSL_FAILURE;
12474     }
12475 
12476     if (mp_mul_2d((mp_int*)bn->internal, n, (mp_int*)r->internal) != MP_OKAY) {
12477         WOLFSSL_MSG("mp_mul_2d error");
12478         return SSL_FAILURE;
12479     }
12480 
12481     return SSL_SUCCESS;
12482 }
12483 
12484 /* return code compliant with OpenSSL :
12485  *   1 if success, 0 else
12486  */
12487 int wolfSSL_BN_rshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
12488 {
12489     WOLFSSL_MSG("wolfSSL_BN_rshift");
12490 
12491     if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
12492         WOLFSSL_MSG("bn NULL error");
12493         return SSL_FAILURE;
12494     }
12495 
12496     if (mp_div_2d((mp_int*)bn->internal, n,
12497                   (mp_int*)r->internal, NULL) != MP_OKAY) {
12498         WOLFSSL_MSG("mp_mul_2d error");
12499         return SSL_FAILURE;
12500     }
12501 
12502     return SSL_SUCCESS;
12503 }
12504 
12505 /* return code compliant with OpenSSL :
12506  *   1 if success, 0 else
12507  */
12508 int wolfSSL_BN_add_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w)
12509 {
12510     WOLFSSL_MSG("wolfSSL_BN_add_word");
12511 
12512     if (bn == NULL || bn->internal == NULL) {
12513         WOLFSSL_MSG("bn NULL error");
12514         return SSL_FAILURE;
12515     }
12516 
12517     if (mp_add_d((mp_int*)bn->internal, w, (mp_int*)bn->internal) != MP_OKAY) {
12518         WOLFSSL_MSG("mp_add_d error");
12519         return SSL_FAILURE;
12520     }
12521 
12522     return SSL_SUCCESS;
12523 }
12524 
12525 /* return code compliant with OpenSSL :
12526  *   1 if success, 0 else
12527  */
12528 int wolfSSL_BN_add(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a, WOLFSSL_BIGNUM *b)
12529 {
12530     WOLFSSL_MSG("wolfSSL_BN_add");
12531 
12532     if (r == NULL || r->internal == NULL || a == NULL || a->internal == NULL ||
12533         b == NULL || b->internal == NULL) {
12534         WOLFSSL_MSG("bn NULL error");
12535         return SSL_FAILURE;
12536     }
12537 
12538     if (mp_add((mp_int*)a->internal, (mp_int*)b->internal,
12539                (mp_int*)r->internal) != MP_OKAY) {
12540         WOLFSSL_MSG("mp_add_d error");
12541         return SSL_FAILURE;
12542     }
12543 
12544     return SSL_SUCCESS;
12545 }
12546 
12547 #ifdef WOLFSSL_KEY_GEN
12548 
12549 /* return code compliant with OpenSSL :
12550  *   1 if prime, 0 if not, -1 if error
12551  */
12552 int wolfSSL_BN_is_prime_ex(const WOLFSSL_BIGNUM *bn, int nbchecks,
12553                            WOLFSSL_BN_CTX *ctx, WOLFSSL_BN_GENCB *cb)
12554 {
12555     int res;
12556 
12557     (void)ctx;
12558     (void)cb;
12559 
12560     WOLFSSL_MSG("wolfSSL_BN_is_prime_ex");
12561 
12562     if (bn == NULL || bn->internal == NULL) {
12563         WOLFSSL_MSG("bn NULL error");
12564         return SSL_FATAL_ERROR;
12565     }
12566 
12567     if (mp_prime_is_prime((mp_int*)bn->internal, nbchecks, &res) != MP_OKAY) {
12568         WOLFSSL_MSG("mp_prime_is_prime error");
12569         return SSL_FATAL_ERROR;
12570     }
12571 
12572     if (res != MP_YES) {
12573         WOLFSSL_MSG("mp_prime_is_prime not prime");
12574         return SSL_FAILURE;
12575     }
12576 
12577     return SSL_SUCCESS;
12578 }
12579 
12580 /* return code compliant with OpenSSL :
12581  *   (bn mod w) if success, -1 if error
12582  */
12583 WOLFSSL_BN_ULONG wolfSSL_BN_mod_word(const WOLFSSL_BIGNUM *bn,
12584                                      WOLFSSL_BN_ULONG w)
12585 {
12586     WOLFSSL_BN_ULONG ret = 0;
12587 
12588     WOLFSSL_MSG("wolfSSL_BN_mod_word");
12589 
12590     if (bn == NULL || bn->internal == NULL) {
12591         WOLFSSL_MSG("bn NULL error");
12592         return (WOLFSSL_BN_ULONG)SSL_FATAL_ERROR;
12593     }
12594 
12595     if (mp_mod_d((mp_int*)bn->internal, w, &ret) != MP_OKAY) {
12596         WOLFSSL_MSG("mp_add_d error");
12597         return (WOLFSSL_BN_ULONG)SSL_FATAL_ERROR;
12598     }
12599 
12600     return ret;
12601 }
12602 #endif /* #ifdef WOLFSSL_KEY_GEN */
12603 
12604 #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
12605 char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM *bn)
12606 {
12607     int len = 0;
12608     char *buf;
12609 
12610     WOLFSSL_MSG("wolfSSL_BN_bn2hex");
12611 
12612     if (bn == NULL || bn->internal == NULL) {
12613         WOLFSSL_MSG("bn NULL error");
12614         return NULL;
12615     }
12616 
12617     if (mp_radix_size((mp_int*)bn->internal, 16, &len) != MP_OKAY) {
12618         WOLFSSL_MSG("mp_radix_size failure");
12619         return NULL;
12620     }
12621 
12622     buf = (char*) XMALLOC(len, NULL, DYNAMIC_TYPE_ECC);
12623     if (buf == NULL) {
12624         WOLFSSL_MSG("wolfSSL_BN_bn2hex malloc buffer failure");
12625         return NULL;
12626     }
12627 
12628     if (mp_toradix((mp_int*)bn->internal, buf, 16) != MP_OKAY) {
12629         XFREE(buf, NULL, DYNAMIC_TYPE_ECC);
12630         return NULL;
12631     }
12632 
12633     return buf;
12634 }
12635 
12636 #ifndef NO_FILESYSTEM
12637 /* return code compliant with OpenSSL :
12638  *   1 if success, 0 if error
12639  */
12640 int wolfSSL_BN_print_fp(FILE *fp, const WOLFSSL_BIGNUM *bn)
12641 {
12642     char *buf;
12643 
12644     WOLFSSL_MSG("wolfSSL_BN_print_fp");
12645 
12646     if (fp == NULL || bn == NULL || bn->internal == NULL) {
12647         WOLFSSL_MSG("bn NULL error");
12648         return SSL_FAILURE;
12649     }
12650 
12651     buf = wolfSSL_BN_bn2hex(bn);
12652     if (buf == NULL) {
12653         WOLFSSL_MSG("wolfSSL_BN_bn2hex failure");
12654         return SSL_FAILURE;
12655     }
12656 
12657     fprintf(fp, "%s", buf);
12658     XFREE(buf, NULL, DYNAMIC_TYPE_ECC);
12659 
12660     return SSL_SUCCESS;
12661 }
12662 #endif /* !defined(NO_FILESYSTEM) */
12663 
12664 #else /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
12665 
12666 char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM *bn)
12667 {
12668     (void)bn;
12669 
12670     WOLFSSL_MSG("wolfSSL_BN_bn2hex not implemented");
12671 
12672     return (char*)"";
12673 }
12674 
12675 #ifndef NO_FILESYSTEM
12676 /* return code compliant with OpenSSL :
12677  *   1 if success, 0 if error
12678  */
12679 int wolfSSL_BN_print_fp(FILE *fp, const WOLFSSL_BIGNUM *bn)
12680 {
12681     (void)fp;
12682     (void)bn;
12683 
12684     WOLFSSL_MSG("wolfSSL_BN_print_fp not implemented");
12685 
12686     return SSL_SUCCESS;
12687 }
12688 #endif /* !defined(NO_FILESYSTEM) */
12689 
12690 #endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
12691 
12692 WOLFSSL_BIGNUM *wolfSSL_BN_CTX_get(WOLFSSL_BN_CTX *ctx)
12693 {
12694     /* ctx is not used, return new Bignum */
12695     (void)ctx;
12696 
12697     WOLFSSL_ENTER("wolfSSL_BN_CTX_get");
12698 
12699     return wolfSSL_BN_new();
12700 }
12701 
12702 void wolfSSL_BN_CTX_start(WOLFSSL_BN_CTX *ctx)
12703 {
12704     (void)ctx;
12705 
12706     WOLFSSL_ENTER("wolfSSL_BN_CTX_start");
12707     WOLFSSL_MSG("wolfSSL_BN_CTX_start TBD");
12708 }
12709 
12710 #ifndef NO_DH
12711 
12712 static void InitwolfSSL_DH(WOLFSSL_DH* dh)
12713 {
12714     if (dh) {
12715         dh->p        = NULL;
12716         dh->g        = NULL;
12717         dh->pub_key  = NULL;
12718         dh->priv_key = NULL;
12719         dh->internal = NULL;
12720         dh->inSet    = 0;
12721         dh->exSet    = 0;
12722     }
12723 }
12724 
12725 
12726 WOLFSSL_DH* wolfSSL_DH_new(void)
12727 {
12728     WOLFSSL_DH* external;
12729     DhKey*     key;
12730 
12731     WOLFSSL_MSG("wolfSSL_DH_new");
12732 
12733     key = (DhKey*) XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
12734     if (key == NULL) {
12735         WOLFSSL_MSG("wolfSSL_DH_new malloc DhKey failure");
12736         return NULL;
12737     }
12738 
12739     external = (WOLFSSL_DH*) XMALLOC(sizeof(WOLFSSL_DH), NULL,
12740                                     DYNAMIC_TYPE_DH);
12741     if (external == NULL) {
12742         WOLFSSL_MSG("wolfSSL_DH_new malloc WOLFSSL_DH failure");
12743         XFREE(key, NULL, DYNAMIC_TYPE_DH);
12744         return NULL;
12745     }
12746 
12747     InitwolfSSL_DH(external);
12748     wc_InitDhKey(key);
12749     external->internal = key;
12750 
12751     return external;
12752 }
12753 
12754 
12755 void wolfSSL_DH_free(WOLFSSL_DH* dh)
12756 {
12757     WOLFSSL_MSG("wolfSSL_DH_free");
12758 
12759     if (dh) {
12760         if (dh->internal) {
12761             wc_FreeDhKey((DhKey*)dh->internal);
12762             XFREE(dh->internal, NULL, DYNAMIC_TYPE_DH);
12763             dh->internal = NULL;
12764         }
12765         wolfSSL_BN_free(dh->priv_key);
12766         wolfSSL_BN_free(dh->pub_key);
12767         wolfSSL_BN_free(dh->g);
12768         wolfSSL_BN_free(dh->p);
12769         InitwolfSSL_DH(dh);  /* set back to NULLs for safety */
12770 
12771         XFREE(dh, NULL, DYNAMIC_TYPE_DH);
12772     }
12773 }
12774 
12775 
12776 static int SetDhInternal(WOLFSSL_DH* dh)
12777 {
12778     int            ret = SSL_FATAL_ERROR;
12779     int            pSz = 1024;
12780     int            gSz = 1024;
12781 #ifdef WOLFSSL_SMALL_STACK
12782     unsigned char* p   = NULL;
12783     unsigned char* g   = NULL;
12784 #else
12785     unsigned char  p[1024];
12786     unsigned char  g[1024];
12787 #endif
12788 
12789     WOLFSSL_ENTER("SetDhInternal");
12790 
12791     if (dh == NULL || dh->p == NULL || dh->g == NULL)
12792         WOLFSSL_MSG("Bad function arguments");
12793     else if (wolfSSL_BN_bn2bin(dh->p, NULL) > pSz)
12794         WOLFSSL_MSG("Bad p internal size");
12795     else if (wolfSSL_BN_bn2bin(dh->g, NULL) > gSz)
12796         WOLFSSL_MSG("Bad g internal size");
12797     else {
12798     #ifdef WOLFSSL_SMALL_STACK
12799         p = (unsigned char*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12800         g = (unsigned char*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12801 
12802         if (p == NULL || g == NULL) {
12803             XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12804             XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12805             return ret;
12806         }
12807     #endif
12808 
12809         pSz = wolfSSL_BN_bn2bin(dh->p, p);
12810         gSz = wolfSSL_BN_bn2bin(dh->g, g);
12811 
12812         if (pSz <= 0 || gSz <= 0)
12813             WOLFSSL_MSG("Bad BN2bin set");
12814         else if (wc_DhSetKey((DhKey*)dh->internal, p, pSz, g, gSz) < 0)
12815             WOLFSSL_MSG("Bad DH SetKey");
12816         else {
12817             dh->inSet = 1;
12818             ret = SSL_SUCCESS;
12819         }
12820 
12821     #ifdef WOLFSSL_SMALL_STACK
12822         XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12823         XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12824     #endif
12825     }
12826 
12827 
12828     return ret;
12829 }
12830 
12831 /* return code compliant with OpenSSL :
12832  *   DH prime size in bytes if success, 0 if error
12833  */
12834 int wolfSSL_DH_size(WOLFSSL_DH* dh)
12835 {
12836     WOLFSSL_MSG("wolfSSL_DH_size");
12837 
12838     if (dh == NULL)
12839         return SSL_FATAL_ERROR;
12840 
12841     return wolfSSL_BN_num_bytes(dh->p);
12842 }
12843 
12844 
12845 /* return code compliant with OpenSSL :
12846  *   1 if success, 0 if error
12847  */
12848 int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
12849 {
12850     int            ret    = SSL_FAILURE;
12851     word32         pubSz  = 768;
12852     word32         privSz = 768;
12853     int            initTmpRng = 0;
12854     WC_RNG*        rng    = NULL;
12855 #ifdef WOLFSSL_SMALL_STACK
12856     unsigned char* pub    = NULL;
12857     unsigned char* priv   = NULL;
12858     WC_RNG*        tmpRNG = NULL;
12859 #else
12860     unsigned char  pub [768];
12861     unsigned char  priv[768];
12862     WC_RNG         tmpRNG[1];
12863 #endif
12864 
12865     WOLFSSL_MSG("wolfSSL_DH_generate_key");
12866 
12867 #ifdef WOLFSSL_SMALL_STACK
12868     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
12869     pub    = (unsigned char*)XMALLOC(pubSz,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
12870     priv   = (unsigned char*)XMALLOC(privSz,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
12871 
12872     if (tmpRNG == NULL || pub == NULL || priv == NULL) {
12873         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12874         XFREE(pub,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
12875         XFREE(priv,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
12876         return ret;
12877     }
12878 #endif
12879 
12880     if (dh == NULL || dh->p == NULL || dh->g == NULL)
12881         WOLFSSL_MSG("Bad function arguments");
12882     else if (dh->inSet == 0 && SetDhInternal(dh) != SSL_SUCCESS)
12883             WOLFSSL_MSG("Bad DH set internal");
12884     else if (wc_InitRng(tmpRNG) == 0) {
12885         rng = tmpRNG;
12886         initTmpRng = 1;
12887     }
12888     else {
12889         WOLFSSL_MSG("Bad RNG Init, trying global");
12890         if (initGlobalRNG == 0)
12891             WOLFSSL_MSG("Global RNG no Init");
12892         else
12893             rng = &globalRNG;
12894     }
12895 
12896     if (rng) {
12897        if (wc_DhGenerateKeyPair((DhKey*)dh->internal, rng, priv, &privSz,
12898                                                                pub, &pubSz) < 0)
12899             WOLFSSL_MSG("Bad wc_DhGenerateKeyPair");
12900        else {
12901             if (dh->pub_key)
12902                 wolfSSL_BN_free(dh->pub_key);
12903 
12904             dh->pub_key = wolfSSL_BN_new();
12905             if (dh->pub_key == NULL) {
12906                 WOLFSSL_MSG("Bad DH new pub");
12907             }
12908             if (dh->priv_key)
12909                 wolfSSL_BN_free(dh->priv_key);
12910 
12911             dh->priv_key = wolfSSL_BN_new();
12912 
12913             if (dh->priv_key == NULL) {
12914                 WOLFSSL_MSG("Bad DH new priv");
12915             }
12916 
12917             if (dh->pub_key && dh->priv_key) {
12918                if (wolfSSL_BN_bin2bn(pub, pubSz, dh->pub_key) == NULL)
12919                    WOLFSSL_MSG("Bad DH bn2bin error pub");
12920                else if (wolfSSL_BN_bin2bn(priv, privSz, dh->priv_key) == NULL)
12921                    WOLFSSL_MSG("Bad DH bn2bin error priv");
12922                else
12923                    ret = SSL_SUCCESS;
12924             }
12925         }
12926     }
12927 
12928     if (initTmpRng)
12929         wc_FreeRng(tmpRNG);
12930 
12931 #ifdef WOLFSSL_SMALL_STACK
12932     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12933     XFREE(pub,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
12934     XFREE(priv,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
12935 #endif
12936 
12937     return ret;
12938 }
12939 
12940 
12941 /* return code compliant with OpenSSL :
12942  *   size of shared secret if success, -1 if error
12943  */
12944 int wolfSSL_DH_compute_key(unsigned char* key, WOLFSSL_BIGNUM* otherPub,
12945                           WOLFSSL_DH* dh)
12946 {
12947     int            ret    = SSL_FATAL_ERROR;
12948     word32         keySz  = 0;
12949     word32         pubSz  = 1024;
12950     word32         privSz = 1024;
12951 #ifdef WOLFSSL_SMALL_STACK
12952     unsigned char* pub    = NULL;
12953     unsigned char* priv   = NULL;
12954 #else
12955     unsigned char  pub [1024];
12956     unsigned char  priv[1024];
12957 #endif
12958 
12959     WOLFSSL_MSG("wolfSSL_DH_compute_key");
12960 
12961 #ifdef WOLFSSL_SMALL_STACK
12962     pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12963     if (pub == NULL)
12964         return ret;
12965 
12966     priv = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12967     if (priv == NULL) {
12968         XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12969         return ret;
12970     }
12971 #endif
12972 
12973     if (dh == NULL || dh->priv_key == NULL || otherPub == NULL)
12974         WOLFSSL_MSG("Bad function arguments");
12975     else if ((keySz = (word32)DH_size(dh)) == 0)
12976         WOLFSSL_MSG("Bad DH_size");
12977     else if (wolfSSL_BN_bn2bin(dh->priv_key, NULL) > (int)privSz)
12978         WOLFSSL_MSG("Bad priv internal size");
12979     else if (wolfSSL_BN_bn2bin(otherPub, NULL) > (int)pubSz)
12980         WOLFSSL_MSG("Bad otherPub size");
12981     else {
12982         privSz = wolfSSL_BN_bn2bin(dh->priv_key, priv);
12983         pubSz  = wolfSSL_BN_bn2bin(otherPub, pub);
12984 
12985         if (privSz <= 0 || pubSz <= 0)
12986             WOLFSSL_MSG("Bad BN2bin set");
12987         else if (wc_DhAgree((DhKey*)dh->internal, key, &keySz,
12988                             priv, privSz, pub, pubSz) < 0)
12989             WOLFSSL_MSG("wc_DhAgree failed");
12990         else
12991             ret = (int)keySz;
12992     }
12993 
12994 #ifdef WOLFSSL_SMALL_STACK
12995     XFREE(pub,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
12996     XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12997 #endif
12998 
12999     return ret;
13000 }
13001 #endif /* NO_DH */
13002 
13003 
13004 #ifndef NO_DSA
13005 static void InitwolfSSL_DSA(WOLFSSL_DSA* dsa)
13006 {
13007     if (dsa) {
13008         dsa->p        = NULL;
13009         dsa->q        = NULL;
13010         dsa->g        = NULL;
13011         dsa->pub_key  = NULL;
13012         dsa->priv_key = NULL;
13013         dsa->internal = NULL;
13014         dsa->inSet    = 0;
13015         dsa->exSet    = 0;
13016     }
13017 }
13018 
13019 
13020 WOLFSSL_DSA* wolfSSL_DSA_new(void)
13021 {
13022     WOLFSSL_DSA* external;
13023     DsaKey*     key;
13024 
13025     WOLFSSL_MSG("wolfSSL_DSA_new");
13026 
13027     key = (DsaKey*) XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
13028     if (key == NULL) {
13029         WOLFSSL_MSG("wolfSSL_DSA_new malloc DsaKey failure");
13030         return NULL;
13031     }
13032 
13033     external = (WOLFSSL_DSA*) XMALLOC(sizeof(WOLFSSL_DSA), NULL,
13034                                     DYNAMIC_TYPE_DSA);
13035     if (external == NULL) {
13036         WOLFSSL_MSG("wolfSSL_DSA_new malloc WOLFSSL_DSA failure");
13037         XFREE(key, NULL, DYNAMIC_TYPE_DSA);
13038         return NULL;
13039     }
13040 
13041     InitwolfSSL_DSA(external);
13042     InitDsaKey(key);
13043     external->internal = key;
13044 
13045     return external;
13046 }
13047 
13048 
13049 void wolfSSL_DSA_free(WOLFSSL_DSA* dsa)
13050 {
13051     WOLFSSL_MSG("wolfSSL_DSA_free");
13052 
13053     if (dsa) {
13054         if (dsa->internal) {
13055             FreeDsaKey((DsaKey*)dsa->internal);
13056             XFREE(dsa->internal, NULL, DYNAMIC_TYPE_DSA);
13057             dsa->internal = NULL;
13058         }
13059         wolfSSL_BN_free(dsa->priv_key);
13060         wolfSSL_BN_free(dsa->pub_key);
13061         wolfSSL_BN_free(dsa->g);
13062         wolfSSL_BN_free(dsa->q);
13063         wolfSSL_BN_free(dsa->p);
13064         InitwolfSSL_DSA(dsa);  /* set back to NULLs for safety */
13065 
13066         XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
13067         dsa = NULL;
13068     }
13069 }
13070 #endif /* NO_DSA */
13071 
13072 #ifndef NO_RSA
13073 static void InitwolfSSL_Rsa(WOLFSSL_RSA* rsa)
13074 {
13075     if (rsa) {
13076         rsa->n        = NULL;
13077         rsa->e        = NULL;
13078         rsa->d        = NULL;
13079         rsa->p        = NULL;
13080         rsa->q        = NULL;
13081         rsa->dmp1     = NULL;
13082         rsa->dmq1     = NULL;
13083         rsa->iqmp     = NULL;
13084         rsa->internal = NULL;
13085         rsa->inSet    = 0;
13086         rsa->exSet    = 0;
13087     }
13088 }
13089 
13090 
13091 WOLFSSL_RSA* wolfSSL_RSA_new(void)
13092 {
13093     WOLFSSL_RSA* external;
13094     RsaKey*     key;
13095 
13096     WOLFSSL_MSG("wolfSSL_RSA_new");
13097 
13098     key = (RsaKey*) XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
13099     if (key == NULL) {
13100         WOLFSSL_MSG("wolfSSL_RSA_new malloc RsaKey failure");
13101         return NULL;
13102     }
13103 
13104     external = (WOLFSSL_RSA*) XMALLOC(sizeof(WOLFSSL_RSA), NULL,
13105                                      DYNAMIC_TYPE_RSA);
13106     if (external == NULL) {
13107         WOLFSSL_MSG("wolfSSL_RSA_new malloc WOLFSSL_RSA failure");
13108         XFREE(key, NULL, DYNAMIC_TYPE_RSA);
13109         return NULL;
13110     }
13111 
13112     InitwolfSSL_Rsa(external);
13113     if (wc_InitRsaKey(key, NULL) != 0) {
13114         WOLFSSL_MSG("InitRsaKey WOLFSSL_RSA failure");
13115         XFREE(external, NULL, DYNAMIC_TYPE_RSA);
13116         XFREE(key, NULL, DYNAMIC_TYPE_RSA);
13117         return NULL;
13118     }
13119     external->internal = key;
13120 
13121     return external;
13122 }
13123 
13124 
13125 void wolfSSL_RSA_free(WOLFSSL_RSA* rsa)
13126 {
13127     WOLFSSL_MSG("wolfSSL_RSA_free");
13128 
13129     if (rsa) {
13130         if (rsa->internal) {
13131             wc_FreeRsaKey((RsaKey*)rsa->internal);
13132             XFREE(rsa->internal, NULL, DYNAMIC_TYPE_RSA);
13133             rsa->internal = NULL;
13134         }
13135         wolfSSL_BN_free(rsa->iqmp);
13136         wolfSSL_BN_free(rsa->dmq1);
13137         wolfSSL_BN_free(rsa->dmp1);
13138         wolfSSL_BN_free(rsa->q);
13139         wolfSSL_BN_free(rsa->p);
13140         wolfSSL_BN_free(rsa->d);
13141         wolfSSL_BN_free(rsa->e);
13142         wolfSSL_BN_free(rsa->n);
13143         InitwolfSSL_Rsa(rsa);  /* set back to NULLs for safety */
13144 
13145         XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
13146         rsa = NULL;
13147     }
13148 }
13149 #endif /* NO_RSA */
13150 
13151 
13152 #if (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)) \
13153     || !defined(NO_DSA) || defined(HAVE_ECC)
13154 static int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi)
13155 {
13156     WOLFSSL_MSG("Entering SetIndividualExternal");
13157 
13158     if (mpi == NULL || bn == NULL) {
13159         WOLFSSL_MSG("mpi NULL error");
13160         return SSL_FATAL_ERROR;
13161     }
13162 
13163     if (*bn == NULL) {
13164         *bn = wolfSSL_BN_new();
13165         if (*bn == NULL) {
13166             WOLFSSL_MSG("SetIndividualExternal alloc failed");
13167             return SSL_FATAL_ERROR;
13168         }
13169     }
13170 
13171     if (mp_copy(mpi, (mp_int*)((*bn)->internal)) != MP_OKAY) {
13172         WOLFSSL_MSG("mp_copy error");
13173         return SSL_FATAL_ERROR;
13174     }
13175 
13176     return SSL_SUCCESS;
13177 }
13178 
13179 static int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi)
13180 {
13181     WOLFSSL_MSG("Entering SetIndividualInternal");
13182 
13183     if (bn == NULL || bn->internal == NULL) {
13184         WOLFSSL_MSG("bn NULL error");
13185         return SSL_FATAL_ERROR;
13186     }
13187 
13188     if (mpi == NULL || (mp_init(mpi) != MP_OKAY)) {
13189         WOLFSSL_MSG("mpi NULL error");
13190         return SSL_FATAL_ERROR;
13191     }
13192 
13193     if (mp_copy((mp_int*)bn->internal, mpi) != MP_OKAY) {
13194         WOLFSSL_MSG("mp_copy error");
13195         return SSL_FATAL_ERROR;
13196     }
13197 
13198     return SSL_SUCCESS;
13199 }
13200 #endif /* !NO_RSA && !NO_DSA */
13201 
13202 
13203 #ifndef NO_DSA
13204 /* wolfSSL -> OpenSSL */
13205 static int SetDsaExternal(WOLFSSL_DSA* dsa)
13206 {
13207     DsaKey* key;
13208     WOLFSSL_MSG("Entering SetDsaExternal");
13209 
13210     if (dsa == NULL || dsa->internal == NULL) {
13211         WOLFSSL_MSG("dsa key NULL error");
13212         return SSL_FATAL_ERROR;
13213     }
13214 
13215     key = (DsaKey*)dsa->internal;
13216 
13217     if (SetIndividualExternal(&dsa->p, &key->p) != SSL_SUCCESS) {
13218         WOLFSSL_MSG("dsa p key error");
13219         return SSL_FATAL_ERROR;
13220     }
13221 
13222     if (SetIndividualExternal(&dsa->q, &key->q) != SSL_SUCCESS) {
13223         WOLFSSL_MSG("dsa q key error");
13224         return SSL_FATAL_ERROR;
13225     }
13226 
13227     if (SetIndividualExternal(&dsa->g, &key->g) != SSL_SUCCESS) {
13228         WOLFSSL_MSG("dsa g key error");
13229         return SSL_FATAL_ERROR;
13230     }
13231 
13232     if (SetIndividualExternal(&dsa->pub_key, &key->y) != SSL_SUCCESS) {
13233         WOLFSSL_MSG("dsa y key error");
13234         return SSL_FATAL_ERROR;
13235     }
13236 
13237     if (SetIndividualExternal(&dsa->priv_key, &key->x) != SSL_SUCCESS) {
13238         WOLFSSL_MSG("dsa x key error");
13239         return SSL_FATAL_ERROR;
13240     }
13241 
13242     dsa->exSet = 1;
13243 
13244     return SSL_SUCCESS;
13245 }
13246 
13247 /* Openssl -> WolfSSL */
13248 static int SetDsaInternal(WOLFSSL_DSA* dsa)
13249 {
13250     DsaKey* key;
13251     WOLFSSL_MSG("Entering SetDsaInternal");
13252 
13253     if (dsa == NULL || dsa->internal == NULL) {
13254         WOLFSSL_MSG("dsa key NULL error");
13255         return SSL_FATAL_ERROR;
13256     }
13257 
13258     key = (DsaKey*)dsa->internal;
13259 
13260     if (dsa->p != NULL &&
13261         SetIndividualInternal(dsa->p, &key->p) != SSL_SUCCESS) {
13262         WOLFSSL_MSG("rsa p key error");
13263         return SSL_FATAL_ERROR;
13264     }
13265 
13266     if (dsa->q != NULL &&
13267         SetIndividualInternal(dsa->q, &key->q) != SSL_SUCCESS) {
13268         WOLFSSL_MSG("rsa q key error");
13269         return SSL_FATAL_ERROR;
13270     }
13271 
13272     if (dsa->g != NULL &&
13273         SetIndividualInternal(dsa->g, &key->g) != SSL_SUCCESS) {
13274         WOLFSSL_MSG("rsa g key error");
13275         return SSL_FATAL_ERROR;
13276     }
13277 
13278     if (dsa->pub_key != NULL) {
13279         if (SetIndividualInternal(dsa->pub_key, &key->y) != SSL_SUCCESS) {
13280             WOLFSSL_MSG("rsa pub_key error");
13281             return SSL_FATAL_ERROR;
13282         }
13283 
13284         /* public key */
13285         key->type = DSA_PUBLIC;
13286     }
13287 
13288     if (dsa->priv_key != NULL) {
13289         if (SetIndividualInternal(dsa->priv_key, &key->x) != SSL_SUCCESS) {
13290             WOLFSSL_MSG("rsa priv_key error");
13291             return SSL_FATAL_ERROR;
13292         }
13293 
13294         /* private key */
13295         key->type = DSA_PRIVATE;
13296     }
13297 
13298     dsa->inSet = 1;
13299 
13300     return SSL_SUCCESS;
13301 }
13302 #endif /* NO_DSA */
13303 
13304 
13305 #if !defined(NO_RSA)
13306 #if !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
13307 /* WolfSSL -> OpenSSL */
13308 static int SetRsaExternal(WOLFSSL_RSA* rsa)
13309 {
13310     RsaKey* key;
13311     WOLFSSL_MSG("Entering SetRsaExternal");
13312 
13313     if (rsa == NULL || rsa->internal == NULL) {
13314         WOLFSSL_MSG("rsa key NULL error");
13315         return SSL_FATAL_ERROR;
13316     }
13317 
13318     key = (RsaKey*)rsa->internal;
13319 
13320     if (SetIndividualExternal(&rsa->n, &key->n) != SSL_SUCCESS) {
13321         WOLFSSL_MSG("rsa n key error");
13322         return SSL_FATAL_ERROR;
13323     }
13324 
13325     if (SetIndividualExternal(&rsa->e, &key->e) != SSL_SUCCESS) {
13326         WOLFSSL_MSG("rsa e key error");
13327         return SSL_FATAL_ERROR;
13328     }
13329 
13330     if (SetIndividualExternal(&rsa->d, &key->d) != SSL_SUCCESS) {
13331         WOLFSSL_MSG("rsa d key error");
13332         return SSL_FATAL_ERROR;
13333     }
13334 
13335     if (SetIndividualExternal(&rsa->p, &key->p) != SSL_SUCCESS) {
13336         WOLFSSL_MSG("rsa p key error");
13337         return SSL_FATAL_ERROR;
13338     }
13339 
13340     if (SetIndividualExternal(&rsa->q, &key->q) != SSL_SUCCESS) {
13341         WOLFSSL_MSG("rsa q key error");
13342         return SSL_FATAL_ERROR;
13343     }
13344 
13345     if (SetIndividualExternal(&rsa->dmp1, &key->dP) != SSL_SUCCESS) {
13346         WOLFSSL_MSG("rsa dP key error");
13347         return SSL_FATAL_ERROR;
13348     }
13349 
13350     if (SetIndividualExternal(&rsa->dmq1, &key->dQ) != SSL_SUCCESS) {
13351         WOLFSSL_MSG("rsa dQ key error");
13352         return SSL_FATAL_ERROR;
13353     }
13354 
13355     if (SetIndividualExternal(&rsa->iqmp, &key->u) != SSL_SUCCESS) {
13356         WOLFSSL_MSG("rsa u key error");
13357         return SSL_FATAL_ERROR;
13358     }
13359 
13360     rsa->exSet = 1;
13361 
13362     return SSL_SUCCESS;
13363 }
13364 
13365 /* Openssl -> WolfSSL */
13366 static int SetRsaInternal(WOLFSSL_RSA* rsa)
13367 {
13368     RsaKey* key;
13369     WOLFSSL_MSG("Entering SetRsaInternal");
13370 
13371     if (rsa == NULL || rsa->internal == NULL) {
13372         WOLFSSL_MSG("rsa key NULL error");
13373         return SSL_FATAL_ERROR;
13374     }
13375 
13376     key = (RsaKey*)rsa->internal;
13377 
13378     if (SetIndividualInternal(rsa->n, &key->n) != SSL_SUCCESS) {
13379         WOLFSSL_MSG("rsa n key error");
13380         return SSL_FATAL_ERROR;
13381     }
13382 
13383     if (SetIndividualInternal(rsa->e, &key->e) != SSL_SUCCESS) {
13384         WOLFSSL_MSG("rsa e key error");
13385         return SSL_FATAL_ERROR;
13386     }
13387 
13388     /* public key */
13389     key->type = RSA_PUBLIC;
13390 
13391     if (rsa->d != NULL) {
13392         if (SetIndividualInternal(rsa->d, &key->d) != SSL_SUCCESS) {
13393             WOLFSSL_MSG("rsa d key error");
13394             return SSL_FATAL_ERROR;
13395         }
13396 
13397         /* private key */
13398         key->type = RSA_PRIVATE;
13399     }
13400 
13401     if (rsa->p != NULL &&
13402         SetIndividualInternal(rsa->p, &key->p) != SSL_SUCCESS) {
13403         WOLFSSL_MSG("rsa p key error");
13404         return SSL_FATAL_ERROR;
13405     }
13406 
13407     if (rsa->q != NULL &&
13408         SetIndividualInternal(rsa->q, &key->q) != SSL_SUCCESS) {
13409         WOLFSSL_MSG("rsa q key error");
13410         return SSL_FATAL_ERROR;
13411     }
13412 
13413     if (rsa->dmp1 != NULL &&
13414         SetIndividualInternal(rsa->dmp1, &key->dP) != SSL_SUCCESS) {
13415         WOLFSSL_MSG("rsa dP key error");
13416         return SSL_FATAL_ERROR;
13417     }
13418 
13419     if (rsa->dmq1 != NULL &&
13420         SetIndividualInternal(rsa->dmq1, &key->dQ) != SSL_SUCCESS) {
13421         WOLFSSL_MSG("rsa dQ key error");
13422         return SSL_FATAL_ERROR;
13423     }
13424 
13425     if (rsa->iqmp != NULL &&
13426         SetIndividualInternal(rsa->iqmp, &key->u) != SSL_SUCCESS) {
13427         WOLFSSL_MSG("rsa u key error");
13428         return SSL_FATAL_ERROR;
13429     }
13430 
13431     rsa->inSet = 1;
13432 
13433     return SSL_SUCCESS;
13434 }
13435 #endif /* HAVE_USER_RSA */
13436 
13437 /* return compliant with OpenSSL
13438  *   1 if success, 0 if error
13439  */
13440 int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* bn,
13441                                 void* cb)
13442 {
13443     int ret = SSL_FAILURE;
13444 
13445     (void)cb;
13446     (void)bn;
13447     (void)bits;
13448 
13449     WOLFSSL_ENTER("wolfSSL_RSA_generate_key_ex");
13450 
13451     if (rsa == NULL || rsa->internal == NULL) {
13452         /* bit size checked during make key call */
13453         WOLFSSL_MSG("bad arguments");
13454         return SSL_FAILURE;
13455     }
13456 
13457 #ifdef WOLFSSL_KEY_GEN
13458     {
13459     #ifdef WOLFSSL_SMALL_STACK
13460         WC_RNG* rng = NULL;
13461     #else
13462         WC_RNG  rng[1];
13463     #endif
13464 
13465     #ifdef WOLFSSL_SMALL_STACK
13466         rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
13467         if (rng == NULL)
13468             return SSL_FAILURE;
13469     #endif
13470 
13471         if (wc_InitRng(rng) < 0)
13472             WOLFSSL_MSG("RNG init failed");
13473         else if (wc_MakeRsaKey((RsaKey*)rsa->internal,
13474                                bits, 65537, rng) != MP_OKAY)
13475             WOLFSSL_MSG("wc_MakeRsaKey failed");
13476         else if (SetRsaExternal(rsa) != SSL_SUCCESS)
13477             WOLFSSL_MSG("SetRsaExternal failed");
13478         else {
13479             rsa->inSet = 1;
13480             ret = SSL_SUCCESS;
13481         }
13482 
13483         wc_FreeRng(rng);
13484     #ifdef WOLFSSL_SMALL_STACK
13485         XFREE(rng, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13486     #endif
13487     }
13488 #else
13489     WOLFSSL_MSG("No Key Gen built in");
13490 #endif
13491     return ret;
13492 }
13493 
13494 
13495 /* SSL_SUCCESS on ok */
13496 int wolfSSL_RSA_blinding_on(WOLFSSL_RSA* rsa, WOLFSSL_BN_CTX* bn)
13497 {
13498     (void)rsa;
13499     (void)bn;
13500 
13501     WOLFSSL_MSG("wolfSSL_RSA_blinding_on");
13502 
13503     return SSL_SUCCESS;  /* on by default */
13504 }
13505 
13506 /* return compliant with OpenSSL
13507  *   size of encrypted data if success , -1 if error
13508  */
13509 int wolfSSL_RSA_public_encrypt(int len, unsigned char* fr,
13510                             unsigned char* to, WOLFSSL_RSA* rsa, int padding)
13511 {
13512     (void)len;
13513     (void)fr;
13514     (void)to;
13515     (void)rsa;
13516     (void)padding;
13517 
13518     WOLFSSL_MSG("wolfSSL_RSA_public_encrypt");
13519 
13520     return SSL_FATAL_ERROR;
13521 }
13522 
13523 /* return compliant with OpenSSL
13524  *   size of plain recovered data if success , -1 if error
13525  */
13526 int wolfSSL_RSA_private_decrypt(int len, unsigned char* fr,
13527                             unsigned char* to, WOLFSSL_RSA* rsa, int padding)
13528 {
13529     (void)len;
13530     (void)fr;
13531     (void)to;
13532     (void)rsa;
13533     (void)padding;
13534 
13535     WOLFSSL_MSG("wolfSSL_RSA_private_decrypt");
13536 
13537     return SSL_FATAL_ERROR;
13538 }
13539 
13540 /* return compliant with OpenSSL
13541  *   RSA modulus size in bytes, -1 if error
13542  */
13543 int wolfSSL_RSA_size(const WOLFSSL_RSA* rsa)
13544 {
13545     WOLFSSL_MSG("wolfSSL_RSA_size");
13546 
13547     if (rsa == NULL)
13548         return SSL_FATAL_ERROR;
13549 
13550     return wolfSSL_BN_num_bytes(rsa->n);
13551 }
13552 #endif /* NO_RSA */
13553 
13554 #ifndef NO_DSA
13555 /* return code compliant with OpenSSL :
13556  *   1 if success, 0 if error
13557  */
13558 int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa)
13559 {
13560     int ret = SSL_FAILURE;
13561 
13562     WOLFSSL_ENTER("wolfSSL_DSA_generate_key");
13563 
13564     if (dsa == NULL || dsa->internal == NULL) {
13565         WOLFSSL_MSG("Bad arguments");
13566         return SSL_FAILURE;
13567     }
13568 
13569     if (dsa->inSet == 0) {
13570         WOLFSSL_MSG("No DSA internal set, do it");
13571 
13572         if (SetDsaInternal(dsa) != SSL_SUCCESS) {
13573             WOLFSSL_MSG("SetDsaInternal failed");
13574             return ret;
13575         }
13576     }
13577 
13578 #ifdef WOLFSSL_KEY_GEN
13579     {
13580         int initTmpRng = 0;
13581         WC_RNG *rng = NULL;
13582 #ifdef WOLFSSL_SMALL_STACK
13583         WC_RNG *tmpRNG = NULL;
13584 #else
13585         WC_RNG tmpRNG[1];
13586 #endif
13587 
13588 #ifdef WOLFSSL_SMALL_STACK
13589         tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
13590         if (tmpRNG == NULL)
13591             return SSL_FATAL_ERROR;
13592 #endif
13593         if (wc_InitRng(tmpRNG) == 0) {
13594             rng = tmpRNG;
13595             initTmpRng = 1;
13596         }
13597         else {
13598             WOLFSSL_MSG("Bad RNG Init, trying global");
13599             if (initGlobalRNG == 0)
13600                 WOLFSSL_MSG("Global RNG no Init");
13601             else
13602                 rng = &globalRNG;
13603         }
13604 
13605         if (rng) {
13606             if (wc_MakeDsaKey(rng, (DsaKey*)dsa->internal) != MP_OKAY)
13607                 WOLFSSL_MSG("wc_MakeDsaKey failed");
13608             else if (SetDsaExternal(dsa) != SSL_SUCCESS)
13609                 WOLFSSL_MSG("SetDsaExternal failed");
13610             else
13611                 ret = SSL_SUCCESS;
13612         }
13613 
13614         if (initTmpRng)
13615             wc_FreeRng(tmpRNG);
13616 
13617 #ifdef WOLFSSL_SMALL_STACK
13618         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13619 #endif
13620     }
13621 #else /* WOLFSSL_KEY_GEN */
13622     WOLFSSL_MSG("No Key Gen built in");
13623 #endif
13624     return ret;
13625 }
13626 
13627 /* return code compliant with OpenSSL :
13628  *   1 if success, 0 if error
13629  */
13630 int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits,
13631                                        unsigned char* seed, int seedLen,
13632                                        int* counterRet,
13633                                        unsigned long* hRet, void* cb)
13634 {
13635     int ret = SSL_FAILURE;
13636 
13637     (void)bits;
13638     (void)seed;
13639     (void)seedLen;
13640     (void)counterRet;
13641     (void)hRet;
13642     (void)cb;
13643 
13644     WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters_ex");
13645 
13646     if (dsa == NULL || dsa->internal == NULL) {
13647         WOLFSSL_MSG("Bad arguments");
13648         return SSL_FAILURE;
13649     }
13650 
13651 #ifdef WOLFSSL_KEY_GEN
13652     {
13653         int initTmpRng = 0;
13654         WC_RNG *rng = NULL;
13655 #ifdef WOLFSSL_SMALL_STACK
13656         WC_RNG *tmpRNG = NULL;
13657 #else
13658         WC_RNG tmpRNG[1];
13659 #endif
13660 
13661 #ifdef WOLFSSL_SMALL_STACK
13662         tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
13663         if (tmpRNG == NULL)
13664             return SSL_FATAL_ERROR;
13665 #endif
13666         if (wc_InitRng(tmpRNG) == 0) {
13667             rng = tmpRNG;
13668             initTmpRng = 1;
13669         }
13670         else {
13671             WOLFSSL_MSG("Bad RNG Init, trying global");
13672             if (initGlobalRNG == 0)
13673                 WOLFSSL_MSG("Global RNG no Init");
13674             else
13675                 rng = &globalRNG;
13676         }
13677 
13678         if (rng) {
13679             if (wc_MakeDsaParameters(rng, bits,
13680                                      (DsaKey*)dsa->internal) != MP_OKAY)
13681                 WOLFSSL_MSG("wc_MakeDsaParameters failed");
13682             else if (SetDsaExternal(dsa) != SSL_SUCCESS)
13683                 WOLFSSL_MSG("SetDsaExternal failed");
13684             else
13685                 ret = SSL_SUCCESS;
13686         }
13687 
13688         if (initTmpRng)
13689             wc_FreeRng(tmpRNG);
13690 
13691 #ifdef WOLFSSL_SMALL_STACK
13692         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13693 #endif
13694     }
13695 #else /* WOLFSSL_KEY_GEN */
13696     WOLFSSL_MSG("No Key Gen built in");
13697 #endif
13698 
13699     return ret;
13700 }
13701 
13702 /* return SSL_SUCCESS on success, < 0 otherwise */
13703 int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
13704                        WOLFSSL_DSA* dsa)
13705 {
13706     int     ret = SSL_FATAL_ERROR;
13707     int     initTmpRng = 0;
13708     WC_RNG* rng = NULL;
13709 #ifdef WOLFSSL_SMALL_STACK
13710     WC_RNG* tmpRNG = NULL;
13711 #else
13712     WC_RNG  tmpRNG[1];
13713 #endif
13714 
13715     WOLFSSL_ENTER("wolfSSL_DSA_do_sign");
13716 
13717     if (d == NULL || sigRet == NULL || dsa == NULL) {
13718         WOLFSSL_MSG("Bad function arguments");
13719         return ret;
13720     }
13721 
13722     if (dsa->inSet == 0)
13723     {
13724         WOLFSSL_MSG("No DSA internal set, do it");
13725 
13726         if (SetDsaInternal(dsa) != SSL_SUCCESS) {
13727             WOLFSSL_MSG("SetDsaInternal failed");
13728             return ret;
13729         }
13730     }
13731 
13732 #ifdef WOLFSSL_SMALL_STACK
13733     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
13734     if (tmpRNG == NULL)
13735         return SSL_FATAL_ERROR;
13736 #endif
13737 
13738     if (wc_InitRng(tmpRNG) == 0) {
13739         rng = tmpRNG;
13740         initTmpRng = 1;
13741     }
13742     else {
13743         WOLFSSL_MSG("Bad RNG Init, trying global");
13744         if (initGlobalRNG == 0)
13745             WOLFSSL_MSG("Global RNG no Init");
13746         else
13747             rng = &globalRNG;
13748     }
13749 
13750     if (rng) {
13751         if (DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0)
13752             WOLFSSL_MSG("DsaSign failed");
13753         else
13754             ret = SSL_SUCCESS;
13755     }
13756 
13757     if (initTmpRng)
13758         wc_FreeRng(tmpRNG);
13759 #ifdef WOLFSSL_SMALL_STACK
13760     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13761 #endif
13762 
13763     return ret;
13764 }
13765 
13766 
13767 int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig,
13768                         WOLFSSL_DSA* dsa, int *dsacheck)
13769 {
13770     int    ret = SSL_FATAL_ERROR;
13771 
13772     WOLFSSL_ENTER("wolfSSL_DSA_do_verify");
13773 
13774     if (d == NULL || sig == NULL || dsa == NULL) {
13775         WOLFSSL_MSG("Bad function arguments");
13776         return SSL_FATAL_ERROR;
13777     }
13778     if (dsa->inSet == 0)
13779     {
13780         WOLFSSL_MSG("No DSA internal set, do it");
13781 
13782         if (SetDsaInternal(dsa) != SSL_SUCCESS) {
13783             WOLFSSL_MSG("SetDsaInternal failed");
13784             return SSL_FATAL_ERROR;
13785         }
13786     }
13787 
13788     ret = DsaVerify(d, sig, (DsaKey*)dsa->internal, dsacheck);
13789     if (ret != 0 || *dsacheck != 1) {
13790         WOLFSSL_MSG("DsaVerify failed");
13791         return ret;
13792     }
13793 
13794     return SSL_SUCCESS;
13795 }
13796 #endif /* NO_DSA */
13797 
13798 
13799 #ifndef NO_RSA
13800 /* return SSL_SUCCES on ok, 0 otherwise */
13801 int wolfSSL_RSA_sign(int type, const unsigned char* m,
13802                            unsigned int mLen, unsigned char* sigRet,
13803                            unsigned int* sigLen, WOLFSSL_RSA* rsa)
13804 {
13805     word32  outLen;
13806     word32  signSz;
13807     int     initTmpRng = 0;
13808     WC_RNG* rng        = NULL;
13809     int     ret        = 0;
13810 #ifdef WOLFSSL_SMALL_STACK
13811     WC_RNG* tmpRNG     = NULL;
13812     byte*   encodedSig = NULL;
13813 #else
13814     WC_RNG  tmpRNG[1];
13815     byte    encodedSig[MAX_ENCODED_SIG_SZ];
13816 #endif
13817 
13818     WOLFSSL_MSG("wolfSSL_RSA_sign");
13819 
13820     if (m == NULL || sigRet == NULL || sigLen == NULL || rsa == NULL) {
13821         WOLFSSL_MSG("Bad function arguments");
13822         return 0;
13823     }
13824 
13825     switch (type) {
13826     #ifdef WOLFSSL_MD2
13827         case NID_md2:       type = MD2h;    break;
13828     #endif
13829     #ifndef NO_MD5
13830         case NID_md5:       type = MD5h;    break;
13831     #endif
13832     #ifndef NO_SHA
13833         case NID_sha1:      type = SHAh;    break;
13834     #endif
13835     #ifndef NO_SHA256
13836         case NID_sha256:    type = SHA256h; break;
13837     #endif
13838     #ifdef WOLFSSL_SHA384
13839         case NID_sha384:    type = SHA384h; break;
13840     #endif
13841     #ifdef WOLFSSL_SHA512
13842         case NID_sha512:    type = SHA512h; break;
13843     #endif
13844         default:
13845             WOLFSSL_MSG("This NID (md type) not configured or not implemented");
13846             return 0;
13847     }
13848 
13849     if (rsa->inSet == 0)
13850     {
13851         WOLFSSL_MSG("No RSA internal set, do it");
13852 
13853         if (SetRsaInternal(rsa) != SSL_SUCCESS) {
13854             WOLFSSL_MSG("SetRsaInternal failed");
13855             return 0;
13856         }
13857     }
13858 
13859     outLen = (word32)wolfSSL_BN_num_bytes(rsa->n);
13860 
13861 #ifdef WOLFSSL_SMALL_STACK
13862     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
13863     if (tmpRNG == NULL)
13864         return 0;
13865 
13866     encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
13867                                                    DYNAMIC_TYPE_TMP_BUFFER);
13868     if (encodedSig == NULL) {
13869         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13870         return 0;
13871     }
13872 #endif
13873 
13874     if (outLen == 0)
13875         WOLFSSL_MSG("Bad RSA size");
13876     else if (wc_InitRng(tmpRNG) == 0) {
13877         rng = tmpRNG;
13878         initTmpRng = 1;
13879     }
13880     else {
13881         WOLFSSL_MSG("Bad RNG Init, trying global");
13882 
13883         if (initGlobalRNG == 0)
13884             WOLFSSL_MSG("Global RNG no Init");
13885         else
13886             rng = &globalRNG;
13887     }
13888 
13889     if (rng) {
13890 
13891         signSz = wc_EncodeSignature(encodedSig, m, mLen, type);
13892         if (signSz == 0) {
13893             WOLFSSL_MSG("Bad Encode Signature");
13894         }
13895         else {
13896             *sigLen = wc_RsaSSL_Sign(encodedSig, signSz, sigRet, outLen,
13897                                   (RsaKey*)rsa->internal, rng);
13898             if (*sigLen <= 0)
13899                 WOLFSSL_MSG("Bad Rsa Sign");
13900             else
13901                 ret = SSL_SUCCESS;
13902         }
13903 
13904     }
13905 
13906     if (initTmpRng)
13907         wc_FreeRng(tmpRNG);
13908 
13909 #ifdef WOLFSSL_SMALL_STACK
13910     XFREE(tmpRNG,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
13911     XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13912 #endif
13913 
13914     if (ret == SSL_SUCCESS)
13915         WOLFSSL_MSG("wolfSSL_RSA_sign success");
13916     else {
13917         WOLFSSL_MSG("wolfSSL_RSA_sign failed");
13918     }
13919     return ret;
13920 }
13921 
13922 
13923 int wolfSSL_RSA_public_decrypt(int flen, unsigned char* from,
13924                           unsigned char* to, WOLFSSL_RSA* rsa, int padding)
13925 {
13926     int tlen = 0;
13927 
13928     WOLFSSL_MSG("wolfSSL_RSA_public_decrypt");
13929 
13930     if (rsa == NULL || rsa->internal == NULL || from == NULL) {
13931         WOLFSSL_MSG("Bad function arguments");
13932         return 0;
13933     }
13934 
13935     if (padding != RSA_PKCS1_PADDING) {
13936         WOLFSSL_MSG("wolfSSL_RSA_public_decrypt unsupported padding");
13937         return 0;
13938     }
13939 
13940     if (rsa->inSet == 0)
13941     {
13942         WOLFSSL_MSG("No RSA internal set, do it");
13943 
13944         if (SetRsaInternal(rsa) != SSL_SUCCESS) {
13945             WOLFSSL_MSG("SetRsaInternal failed");
13946             return 0;
13947         }
13948     }
13949 
13950     /* size of 'to' buffer must be size of RSA key */
13951     tlen = wc_RsaSSL_Verify(from, flen, to, wolfSSL_RSA_size(rsa),
13952                             (RsaKey*)rsa->internal);
13953     if (tlen <= 0)
13954         WOLFSSL_MSG("wolfSSL_RSA_public_decrypt failed");
13955     else {
13956         WOLFSSL_MSG("wolfSSL_RSA_public_decrypt success");
13957     }
13958     return tlen;
13959 }
13960 
13961 
13962 /* generate p-1 and q-1, SSL_SUCCESS on ok */
13963 int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
13964 {
13965     int    err;
13966     mp_int tmp;
13967 
13968     WOLFSSL_MSG("wolfSSL_RsaGenAdd");
13969 
13970     if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->d == NULL ||
13971                        rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
13972         WOLFSSL_MSG("rsa no init error");
13973         return SSL_FATAL_ERROR;
13974     }
13975 
13976     if (mp_init(&tmp) != MP_OKAY) {
13977         WOLFSSL_MSG("mp_init error");
13978         return SSL_FATAL_ERROR;
13979     }
13980 
13981     err = mp_sub_d((mp_int*)rsa->p->internal, 1, &tmp);
13982     if (err != MP_OKAY) {
13983         WOLFSSL_MSG("mp_sub_d error");
13984     }
13985     else
13986         err = mp_mod((mp_int*)rsa->d->internal, &tmp,
13987                      (mp_int*)rsa->dmp1->internal);
13988 
13989     if (err != MP_OKAY) {
13990         WOLFSSL_MSG("mp_mod error");
13991     }
13992     else
13993         err = mp_sub_d((mp_int*)rsa->q->internal, 1, &tmp);
13994     if (err != MP_OKAY) {
13995         WOLFSSL_MSG("mp_sub_d error");
13996     }
13997     else
13998         err = mp_mod((mp_int*)rsa->d->internal, &tmp,
13999                      (mp_int*)rsa->dmq1->internal);
14000 
14001     mp_clear(&tmp);
14002 
14003     if (err == MP_OKAY)
14004         return SSL_SUCCESS;
14005     else
14006         return SSL_FATAL_ERROR;
14007 }
14008 #endif /* NO_RSA */
14009 
14010 
14011 void wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen,
14012                   const EVP_MD* type)
14013 {
14014     WOLFSSL_MSG("wolfSSL_HMAC_Init");
14015 
14016     if (ctx == NULL) {
14017         WOLFSSL_MSG("no ctx on init");
14018         return;
14019     }
14020 
14021     if (type) {
14022         WOLFSSL_MSG("init has type");
14023 
14024         if (XSTRNCMP(type, "MD5", 3) == 0) {
14025             WOLFSSL_MSG("md5 hmac");
14026             ctx->type = MD5;
14027         }
14028         else if (XSTRNCMP(type, "SHA256", 6) == 0) {
14029             WOLFSSL_MSG("sha256 hmac");
14030             ctx->type = SHA256;
14031         }
14032 
14033         /* has to be last since would pick or 256, 384, or 512 too */
14034         else if (XSTRNCMP(type, "SHA", 3) == 0) {
14035             WOLFSSL_MSG("sha hmac");
14036             ctx->type = SHA;
14037         }
14038         else {
14039             WOLFSSL_MSG("bad init type");
14040         }
14041     }
14042 
14043     if (key && keylen) {
14044         WOLFSSL_MSG("keying hmac");
14045         wc_HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key, (word32)keylen);
14046         /* OpenSSL compat, no error */
14047     }
14048 }
14049 
14050 
14051 void wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, const unsigned char* data,
14052                     int len)
14053 {
14054     WOLFSSL_MSG("wolfSSL_HMAC_Update");
14055 
14056     if (ctx && data) {
14057         WOLFSSL_MSG("updating hmac");
14058         wc_HmacUpdate(&ctx->hmac, data, (word32)len);
14059         /* OpenSSL compat, no error */
14060     }
14061 }
14062 
14063 
14064 void wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash,
14065                    unsigned int* len)
14066 {
14067     WOLFSSL_MSG("wolfSSL_HMAC_Final");
14068 
14069     if (ctx && hash) {
14070         WOLFSSL_MSG("final hmac");
14071         wc_HmacFinal(&ctx->hmac, hash);
14072         /* OpenSSL compat, no error */
14073 
14074         if (len) {
14075             WOLFSSL_MSG("setting output len");
14076             switch (ctx->type) {
14077                 case MD5:
14078                     *len = MD5_DIGEST_SIZE;
14079                     break;
14080 
14081                 case SHA:
14082                     *len = SHA_DIGEST_SIZE;
14083                     break;
14084 
14085                 case SHA256:
14086                     *len = SHA256_DIGEST_SIZE;
14087                     break;
14088 
14089                 default:
14090                     WOLFSSL_MSG("bad hmac type");
14091             }
14092         }
14093     }
14094 }
14095 
14096 
14097 void wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx)
14098 {
14099     (void)ctx;
14100 
14101     WOLFSSL_MSG("wolfSSL_HMAC_cleanup");
14102 }
14103 
14104 
14105 const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id)
14106 {
14107     WOLFSSL_MSG("wolfSSL_get_digestbynid");
14108 
14109     switch(id) {
14110 #ifndef NO_MD5
14111         case NID_md5:
14112             return wolfSSL_EVP_md5();
14113 #endif
14114 #ifndef NO_SHA
14115         case NID_sha1:
14116             return wolfSSL_EVP_sha1();
14117 #endif
14118         default:
14119             WOLFSSL_MSG("Bad digest id value");
14120     }
14121 
14122     return NULL;
14123 }
14124 
14125 
14126 WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY* key)
14127 {
14128     (void)key;
14129     WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_RSA not implemented");
14130 
14131     return NULL;
14132 }
14133 
14134 
14135 WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY* key)
14136 {
14137     (void)key;
14138     WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_DSA not implemented");
14139 
14140     return NULL;
14141 }
14142 
14143 
14144 WOLFSSL_EC_KEY* wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* key)
14145 {
14146     (void)key;
14147     WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_EC_KEY not implemented");
14148 
14149     return NULL;
14150 }
14151 
14152 
14153 void* wolfSSL_EVP_X_STATE(const WOLFSSL_EVP_CIPHER_CTX* ctx)
14154 {
14155     WOLFSSL_MSG("wolfSSL_EVP_X_STATE");
14156 
14157     if (ctx) {
14158         switch (ctx->cipherType) {
14159             case ARC4_TYPE:
14160                 WOLFSSL_MSG("returning arc4 state");
14161                 return (void*)&ctx->cipher.arc4.x;
14162 
14163             default:
14164                 WOLFSSL_MSG("bad x state type");
14165                 return 0;
14166         }
14167     }
14168 
14169     return NULL;
14170 }
14171 
14172 
14173 int wolfSSL_EVP_X_STATE_LEN(const WOLFSSL_EVP_CIPHER_CTX* ctx)
14174 {
14175     WOLFSSL_MSG("wolfSSL_EVP_X_STATE_LEN");
14176 
14177     if (ctx) {
14178         switch (ctx->cipherType) {
14179             case ARC4_TYPE:
14180                 WOLFSSL_MSG("returning arc4 state size");
14181                 return sizeof(Arc4);
14182 
14183             default:
14184                 WOLFSSL_MSG("bad x state type");
14185                 return 0;
14186         }
14187     }
14188 
14189     return 0;
14190 }
14191 
14192 
14193 #ifndef NO_DES3
14194 
14195 void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
14196                             unsigned char* iv, int len)
14197 {
14198     (void)len;
14199 
14200     WOLFSSL_MSG("wolfSSL_3des_iv");
14201 
14202     if (ctx == NULL || iv == NULL) {
14203         WOLFSSL_MSG("Bad function argument");
14204         return;
14205     }
14206 
14207     if (doset)
14208         wc_Des3_SetIV(&ctx->cipher.des3, iv);  /* OpenSSL compat, no ret */
14209     else
14210         XMEMCPY(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
14211 }
14212 
14213 #endif /* NO_DES3 */
14214 
14215 
14216 #ifndef NO_AES
14217 
14218 void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
14219                       unsigned char* iv, int len)
14220 {
14221     (void)len;
14222 
14223     WOLFSSL_MSG("wolfSSL_aes_ctr_iv");
14224 
14225     if (ctx == NULL || iv == NULL) {
14226         WOLFSSL_MSG("Bad function argument");
14227         return;
14228     }
14229 
14230     if (doset)
14231         wc_AesSetIV(&ctx->cipher.aes, iv);  /* OpenSSL compat, no ret */
14232     else
14233         XMEMCPY(iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
14234 }
14235 
14236 #endif /* NO_AES */
14237 
14238 
14239 const WOLFSSL_EVP_MD* wolfSSL_EVP_ripemd160(void)
14240 {
14241     WOLFSSL_MSG("wolfSSL_ripemd160");
14242 
14243     return NULL;
14244 }
14245 
14246 
14247 int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* type)
14248 {
14249     WOLFSSL_MSG("wolfSSL_EVP_MD_size");
14250 
14251     if (type == NULL) {
14252         WOLFSSL_MSG("No md type arg");
14253         return BAD_FUNC_ARG;
14254     }
14255 
14256     if (XSTRNCMP(type, "SHA256", 6) == 0) {
14257         return SHA256_DIGEST_SIZE;
14258     }
14259 #ifndef NO_MD5
14260     else if (XSTRNCMP(type, "MD5", 3) == 0) {
14261         return MD5_DIGEST_SIZE;
14262     }
14263 #endif
14264 #ifdef WOLFSSL_SHA384
14265     else if (XSTRNCMP(type, "SHA384", 6) == 0) {
14266         return SHA384_DIGEST_SIZE;
14267     }
14268 #endif
14269 #ifdef WOLFSSL_SHA512
14270     else if (XSTRNCMP(type, "SHA512", 6) == 0) {
14271         return SHA512_DIGEST_SIZE;
14272     }
14273 #endif
14274 #ifndef NO_SHA
14275     /* has to be last since would pick or 256, 384, or 512 too */
14276     else if (XSTRNCMP(type, "SHA", 3) == 0) {
14277         return SHA_DIGEST_SIZE;
14278     }
14279 #endif
14280 
14281     return BAD_FUNC_ARG;
14282 }
14283 
14284 
14285 int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx)
14286 {
14287     WOLFSSL_MSG("wolfSSL_EVP_CIPHER_CTX_iv_length");
14288 
14289     switch (ctx->cipherType) {
14290 
14291         case AES_128_CBC_TYPE :
14292         case AES_192_CBC_TYPE :
14293         case AES_256_CBC_TYPE :
14294             WOLFSSL_MSG("AES CBC");
14295             return AES_BLOCK_SIZE;
14296 
14297 #ifdef WOLFSSL_AES_COUNTER
14298         case AES_128_CTR_TYPE :
14299         case AES_192_CTR_TYPE :
14300         case AES_256_CTR_TYPE :
14301             WOLFSSL_MSG("AES CTR");
14302             return AES_BLOCK_SIZE;
14303 #endif
14304 
14305         case DES_CBC_TYPE :
14306             WOLFSSL_MSG("DES CBC");
14307             return DES_BLOCK_SIZE;
14308 
14309         case DES_EDE3_CBC_TYPE :
14310             WOLFSSL_MSG("DES EDE3 CBC");
14311             return DES_BLOCK_SIZE;
14312 #ifdef HAVE_IDEA
14313         case IDEA_CBC_TYPE :
14314             WOLFSSL_MSG("IDEA CBC");
14315             return IDEA_BLOCK_SIZE;
14316 #endif
14317         case ARC4_TYPE :
14318             WOLFSSL_MSG("ARC4");
14319             return 0;
14320 
14321         case NULL_CIPHER_TYPE :
14322             WOLFSSL_MSG("NULL");
14323             return 0;
14324 
14325         default: {
14326             WOLFSSL_MSG("bad type");
14327         }
14328     }
14329     return 0;
14330 }
14331 
14332 
14333 void wolfSSL_OPENSSL_free(void* p)
14334 {
14335     WOLFSSL_MSG("wolfSSL_OPENSSL_free");
14336 
14337     XFREE(p, NULL, DYNAMIC_TYPE_OPENSSL);
14338 }
14339 
14340 #if defined(WOLFSSL_KEY_GEN)
14341 
14342 static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher,
14343                          unsigned char* passwd, int passwdSz, byte **cipherInfo)
14344 {
14345     int ret, paddingSz;
14346     word32 idx, cipherInfoSz;
14347 #ifdef WOLFSSL_SMALL_STACK
14348     EncryptedInfo* info = NULL;
14349 #else
14350     EncryptedInfo  info[1];
14351 #endif
14352 
14353     WOLFSSL_ENTER("EncryptDerKey");
14354 
14355     if (der == NULL || derSz == NULL || cipher == NULL ||
14356         passwd == NULL || cipherInfo == NULL)
14357         return BAD_FUNC_ARG;
14358 
14359 #ifdef WOLFSSL_SMALL_STACK
14360     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
14361                                    DYNAMIC_TYPE_TMP_BUFFER);
14362     if (info == NULL) {
14363         WOLFSSL_MSG("malloc failed");
14364         return SSL_FAILURE;
14365     }
14366 #endif
14367     info->set      = 0;
14368     info->ctx      = NULL;
14369     info->consumed = 0;
14370 
14371     /* set iv size */
14372     if (XSTRNCMP(cipher, "DES", 3) == 0)
14373         info->ivSz = DES_IV_SIZE;
14374     else if (XSTRNCMP(cipher, "AES", 3) == 0)
14375         info->ivSz = AES_IV_SIZE;
14376     else {
14377         WOLFSSL_MSG("unsupported cipher");
14378 #ifdef WOLFSSL_SMALL_STACK
14379         XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14380 #endif
14381         return SSL_FAILURE;
14382     }
14383 
14384     /* set the cipher name on info */
14385     XSTRNCPY(info->name, cipher, NAME_SZ);
14386 
14387     /* Generate a random salt */
14388     if (wolfSSL_RAND_bytes(info->iv, info->ivSz) != SSL_SUCCESS) {
14389         WOLFSSL_MSG("generate iv failed");
14390 #ifdef WOLFSSL_SMALL_STACK
14391         XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14392 #endif
14393         return SSL_FAILURE;
14394     }
14395 
14396     /* add the padding before encryption */
14397     paddingSz = ((*derSz)/info->ivSz + 1) * info->ivSz - (*derSz);
14398     if (paddingSz == 0)
14399         paddingSz = info->ivSz;
14400     XMEMSET(der+(*derSz), (byte)paddingSz, paddingSz);
14401     (*derSz) += paddingSz;
14402 
14403     /* encrypt buffer */
14404     if (wolfssl_encrypt_buffer_key(der, *derSz,
14405                                    passwd, passwdSz, info) != SSL_SUCCESS) {
14406         WOLFSSL_MSG("encrypt key failed");
14407 #ifdef WOLFSSL_SMALL_STACK
14408         XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14409 #endif
14410         return SSL_FAILURE;
14411     }
14412 
14413     /* create cipher info : 'cipher_name,Salt(hex)' */
14414     cipherInfoSz = (word32)(2*info->ivSz + XSTRLEN(info->name) + 2);
14415     *cipherInfo = (byte*)XMALLOC(cipherInfoSz, NULL,
14416                                 DYNAMIC_TYPE_TMP_BUFFER);
14417     if (*cipherInfo == NULL) {
14418         WOLFSSL_MSG("malloc failed");
14419 #ifdef WOLFSSL_SMALL_STACK
14420         XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14421 #endif
14422         return SSL_FAILURE;
14423     }
14424     XSTRNCPY((char*)*cipherInfo, info->name, cipherInfoSz);
14425     XSTRNCAT((char*)*cipherInfo, ",", 1);
14426 
14427     idx = (word32)XSTRLEN((char*)*cipherInfo);
14428     cipherInfoSz -= idx;
14429     ret = Base16_Encode(info->iv, info->ivSz, *cipherInfo+idx, &cipherInfoSz);
14430 
14431 #ifdef WOLFSSL_SMALL_STACK
14432     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14433 #endif
14434     if (ret != 0) {
14435         WOLFSSL_MSG("Base16_Encode failed");
14436         XFREE(*cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14437         return SSL_FAILURE;
14438     }
14439 
14440     return SSL_SUCCESS;
14441 }
14442 #endif /* defined(WOLFSSL_KEY_GEN) */
14443 
14444 #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
14445 
14446 /* return code compliant with OpenSSL :
14447  *   1 if success, 0 if error
14448  */
14449 int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher,
14450                                         unsigned char* passwd, int passwdSz,
14451                                         unsigned char **pem, int *plen)
14452 {
14453     byte *derBuf, *tmp, *cipherInfo = NULL;
14454     int  der_max_len = 0, derSz = 0;
14455 
14456     WOLFSSL_ENTER("wolfSSL_PEM_write_mem_RSAPrivateKey");
14457 
14458     if (pem == NULL || plen == NULL || rsa == NULL || rsa->internal == NULL) {
14459         WOLFSSL_MSG("Bad function arguments");
14460         return SSL_FAILURE;
14461     }
14462 
14463     if (rsa->inSet == 0) {
14464         WOLFSSL_MSG("No RSA internal set, do it");
14465 
14466         if (SetRsaInternal(rsa) != SSL_SUCCESS) {
14467             WOLFSSL_MSG("SetRsaInternal failed");
14468             return SSL_FAILURE;
14469         }
14470     }
14471 
14472     /* 5 > size of n, d, p, q, d%(p-1), d(q-1), 1/q%p, e + ASN.1 additional
14473      *  informations
14474      */
14475     der_max_len = 5 * wolfSSL_RSA_size(rsa) + AES_BLOCK_SIZE;
14476 
14477     derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14478     if (derBuf == NULL) {
14479         WOLFSSL_MSG("malloc failed");
14480         return SSL_FAILURE;
14481     }
14482 
14483     /* Key to DER */
14484     derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, derBuf, der_max_len);
14485     if (derSz < 0) {
14486         WOLFSSL_MSG("wc_RsaKeyToDer failed");
14487         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14488         return SSL_FAILURE;
14489     }
14490 
14491     /* encrypt DER buffer if required */
14492     if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
14493         int ret;
14494 
14495         ret = EncryptDerKey(derBuf, &derSz, cipher,
14496                             passwd, passwdSz, &cipherInfo);
14497         if (ret != SSL_SUCCESS) {
14498             WOLFSSL_MSG("EncryptDerKey failed");
14499             XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14500             return ret;
14501         }
14502 
14503         /* tmp buffer with a max size */
14504         *plen = (derSz * 2) + sizeof(BEGIN_RSA_PRIV) +
14505                 sizeof(END_RSA_PRIV) + HEADER_ENCRYPTED_KEY_SIZE;
14506     }
14507     else /* tmp buffer with a max size */
14508         *plen = (derSz * 2) + sizeof(BEGIN_RSA_PRIV) + sizeof(END_RSA_PRIV);
14509 
14510     tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14511     if (tmp == NULL) {
14512         WOLFSSL_MSG("malloc failed");
14513         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14514         if (cipherInfo != NULL)
14515             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14516         return SSL_FAILURE;
14517     }
14518 
14519     /* DER to PEM */
14520     *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, PRIVATEKEY_TYPE);
14521     if (*plen <= 0) {
14522         WOLFSSL_MSG("wc_DerToPemEx failed");
14523         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14524         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14525         if (cipherInfo != NULL)
14526             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14527         return SSL_FAILURE;
14528     }
14529     XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14530     if (cipherInfo != NULL)
14531         XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14532 
14533     *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY);
14534     if (*pem == NULL) {
14535         WOLFSSL_MSG("malloc failed");
14536         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14537         return SSL_FAILURE;
14538     }
14539     XMEMSET(*pem, 0, (*plen)+1);
14540 
14541     if (XMEMCPY(*pem, tmp, *plen) == NULL) {
14542         WOLFSSL_MSG("XMEMCPY failed");
14543         XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
14544         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14545         return SSL_FAILURE;
14546     }
14547     XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14548 
14549     return SSL_SUCCESS;
14550 }
14551 
14552 
14553 #ifndef NO_FILESYSTEM
14554 /* return code compliant with OpenSSL :
14555  *   1 if success, 0 if error
14556  */
14557 int wolfSSL_PEM_write_RSAPrivateKey(FILE *fp, WOLFSSL_RSA *rsa,
14558                                     const EVP_CIPHER *enc,
14559                                     unsigned char *kstr, int klen,
14560                                     pem_password_cb *cb, void *u)
14561 {
14562     byte *pem;
14563     int  plen, ret;
14564 
14565     (void)cb;
14566     (void)u;
14567 
14568     WOLFSSL_MSG("wolfSSL_PEM_write_RSAPrivateKey");
14569 
14570     if (fp == NULL || rsa == NULL || rsa->internal == NULL) {
14571         WOLFSSL_MSG("Bad function arguments");
14572         return SSL_FAILURE;
14573     }
14574 
14575     ret = wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, enc, kstr, klen, &pem, &plen);
14576     if (ret != SSL_SUCCESS) {
14577         WOLFSSL_MSG("wolfSSL_PEM_write_mem_RSAPrivateKey failed");
14578         return SSL_FAILURE;
14579     }
14580 
14581     ret = (int)XFWRITE(pem, plen, 1, fp);
14582     if (ret != 1) {
14583         WOLFSSL_MSG("RSA private key file write failed");
14584         return SSL_FAILURE;
14585     }
14586 
14587     XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
14588     return SSL_SUCCESS;
14589 }
14590 #endif /* NO_FILESYSTEM */
14591 
14592 int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, RSA* rsa,
14593                                         const EVP_CIPHER* cipher,
14594                                         unsigned char* passwd, int len,
14595                                         pem_password_cb cb, void* arg)
14596 {
14597     (void)bio;
14598     (void)rsa;
14599     (void)cipher;
14600     (void)passwd;
14601     (void)len;
14602     (void)cb;
14603     (void)arg;
14604 
14605     WOLFSSL_MSG("wolfSSL_PEM_write_bio_RSAPrivateKey not implemented");
14606 
14607     return SSL_FAILURE;
14608 }
14609 #endif /* defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) */
14610 
14611 #ifdef HAVE_ECC
14612 
14613 /* EC_POINT Openssl -> WolfSSL */
14614 static int SetECPointInternal(WOLFSSL_EC_POINT *p)
14615 {
14616     ecc_point* point;
14617     WOLFSSL_ENTER("SetECPointInternal");
14618 
14619     if (p == NULL || p->internal == NULL) {
14620         WOLFSSL_MSG("ECPoint NULL error");
14621         return SSL_FATAL_ERROR;
14622     }
14623 
14624     point = (ecc_point*)p->internal;
14625 
14626     if (p->X != NULL && SetIndividualInternal(p->X, point->x) != SSL_SUCCESS) {
14627         WOLFSSL_MSG("ecc point X error");
14628         return SSL_FATAL_ERROR;
14629     }
14630 
14631     if (p->Y != NULL && SetIndividualInternal(p->Y, point->y) != SSL_SUCCESS) {
14632         WOLFSSL_MSG("ecc point Y error");
14633         return SSL_FATAL_ERROR;
14634     }
14635 
14636     if (p->Z != NULL && SetIndividualInternal(p->Z, point->z) != SSL_SUCCESS) {
14637         WOLFSSL_MSG("ecc point Z error");
14638         return SSL_FATAL_ERROR;
14639     }
14640 
14641     p->inSet = 1;
14642 
14643     return SSL_SUCCESS;
14644 }
14645 
14646 /* EC_POINT WolfSSL -> OpenSSL */
14647 static int SetECPointExternal(WOLFSSL_EC_POINT *p)
14648 {
14649     ecc_point* point;
14650 
14651     WOLFSSL_ENTER("SetECPointExternal");
14652 
14653     if (p == NULL || p->internal == NULL) {
14654         WOLFSSL_MSG("ECPoint NULL error");
14655         return SSL_FATAL_ERROR;
14656     }
14657 
14658     point = (ecc_point*)p->internal;
14659 
14660     if (SetIndividualExternal(&p->X, point->x) != SSL_SUCCESS) {
14661         WOLFSSL_MSG("ecc point X error");
14662         return SSL_FATAL_ERROR;
14663     }
14664 
14665     if (SetIndividualExternal(&p->Y, point->y) != SSL_SUCCESS) {
14666         WOLFSSL_MSG("ecc point Y error");
14667         return SSL_FATAL_ERROR;
14668     }
14669 
14670     if (SetIndividualExternal(&p->Z, point->z) != SSL_SUCCESS) {
14671         WOLFSSL_MSG("ecc point Z error");
14672         return SSL_FATAL_ERROR;
14673     }
14674 
14675     p->exSet = 1;
14676 
14677     return SSL_SUCCESS;
14678 }
14679 
14680 /* EC_KEY wolfSSL -> OpenSSL */
14681 static int SetECKeyExternal(WOLFSSL_EC_KEY* eckey)
14682 {
14683     ecc_key* key;
14684 
14685     WOLFSSL_ENTER("SetECKeyExternal");
14686 
14687     if (eckey == NULL || eckey->internal == NULL) {
14688         WOLFSSL_MSG("ec key NULL error");
14689         return SSL_FATAL_ERROR;
14690     }
14691 
14692     key = (ecc_key*)eckey->internal;
14693 
14694     /* set group (nid and idx) */
14695     eckey->group->curve_nid = ecc_sets[key->idx].nid;
14696     eckey->group->curve_idx = key->idx;
14697 
14698     if (eckey->pub_key->internal != NULL) {
14699         /* set the internal public key */
14700         if (wc_ecc_copy_point(&key->pubkey,
14701                              (ecc_point*)eckey->pub_key->internal) != MP_OKAY) {
14702             WOLFSSL_MSG("SetECKeyExternal ecc_copy_point failed");
14703             return SSL_FATAL_ERROR;
14704         }
14705 
14706         /* set the external pubkey (point) */
14707         if (SetECPointExternal(eckey->pub_key) != SSL_SUCCESS) {
14708             WOLFSSL_MSG("SetECKeyExternal SetECPointExternal failed");
14709             return SSL_FATAL_ERROR;
14710         }
14711     }
14712 
14713     /* set the external privkey */
14714     if (key->type == ECC_PRIVATEKEY) {
14715         if (SetIndividualExternal(&eckey->priv_key, &key->k) != SSL_SUCCESS) {
14716             WOLFSSL_MSG("ec priv key error");
14717             return SSL_FATAL_ERROR;
14718         }
14719     }
14720 
14721     eckey->exSet = 1;
14722 
14723     return SSL_SUCCESS;
14724 }
14725 
14726 /* EC_KEY Openssl -> WolfSSL */
14727 static int SetECKeyInternal(WOLFSSL_EC_KEY* eckey)
14728 {
14729     ecc_key* key;
14730 
14731     WOLFSSL_ENTER("SetECKeyInternal");
14732 
14733     if (eckey == NULL || eckey->internal == NULL) {
14734         WOLFSSL_MSG("ec key NULL error");
14735         return SSL_FATAL_ERROR;
14736     }
14737 
14738     key = (ecc_key*)eckey->internal;
14739 
14740     /* validate group */
14741     if ((eckey->group->curve_idx < 0) ||
14742         (wc_ecc_is_valid_idx(eckey->group->curve_idx) == 0)) {
14743         WOLFSSL_MSG("invalid curve idx");
14744         return SSL_FATAL_ERROR;
14745     }
14746 
14747     /* set group (idx of curve and corresponding domain parameters) */
14748     key->idx = eckey->group->curve_idx;
14749     key->dp = &ecc_sets[key->idx];
14750 
14751     /* set pubkey (point) */
14752     if (eckey->pub_key != NULL) {
14753         if (SetECPointInternal(eckey->pub_key) != SSL_SUCCESS) {
14754             WOLFSSL_MSG("ec key pub error");
14755             return SSL_FATAL_ERROR;
14756         }
14757 
14758         /* public key */
14759         key->type = ECC_PUBLICKEY;
14760     }
14761 
14762     /* set privkey */
14763     if (eckey->priv_key != NULL) {
14764         if (SetIndividualInternal(eckey->priv_key, &key->k) != SSL_SUCCESS) {
14765             WOLFSSL_MSG("ec key priv error");
14766             return SSL_FATAL_ERROR;
14767         }
14768 
14769         /* private key */
14770         key->type = ECC_PRIVATEKEY;
14771     }
14772 
14773     eckey->inSet = 1;
14774 
14775     return SSL_SUCCESS;
14776 }
14777 
14778 WOLFSSL_EC_POINT *wolfSSL_EC_KEY_get0_public_key(const WOLFSSL_EC_KEY *key)
14779 {
14780     WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_public_key");
14781 
14782     if (key == NULL) {
14783         WOLFSSL_MSG("wolfSSL_EC_KEY_get0_group Bad arguments");
14784         return NULL;
14785     }
14786 
14787     return key->pub_key;
14788 }
14789 
14790 const WOLFSSL_EC_GROUP *wolfSSL_EC_KEY_get0_group(const WOLFSSL_EC_KEY *key)
14791 {
14792     WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_group");
14793 
14794     if (key == NULL) {
14795         WOLFSSL_MSG("wolfSSL_EC_KEY_get0_group Bad arguments");
14796         return NULL;
14797     }
14798 
14799     return key->group;
14800 }
14801 
14802 
14803 /* return code compliant with OpenSSL :
14804  *   1 if success, 0 if error
14805  */
14806 int wolfSSL_EC_KEY_set_private_key(WOLFSSL_EC_KEY *key,
14807                                    const WOLFSSL_BIGNUM *priv_key)
14808 {
14809     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_private_key");
14810 
14811     if (key == NULL || priv_key == NULL) {
14812         WOLFSSL_MSG("Bad arguments");
14813         return SSL_FAILURE;
14814     }
14815 
14816     /* free key if previously set */
14817     if (key->priv_key != NULL)
14818         wolfSSL_BN_free(key->priv_key);
14819 
14820     key->priv_key = wolfSSL_BN_dup(priv_key);
14821     if (key->priv_key == NULL) {
14822         WOLFSSL_MSG("key ecc priv key NULL");
14823         return SSL_FAILURE;
14824     }
14825 
14826     if (SetECKeyInternal(key) != SSL_SUCCESS) {
14827         WOLFSSL_MSG("SetECKeyInternal failed");
14828         wolfSSL_BN_free(key->priv_key);
14829         return SSL_FAILURE;
14830     }
14831 
14832     return SSL_SUCCESS;
14833 }
14834 
14835 
14836 WOLFSSL_BIGNUM *wolfSSL_EC_KEY_get0_private_key(const WOLFSSL_EC_KEY *key)
14837 {
14838     WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_private_key");
14839 
14840     if (key == NULL) {
14841         WOLFSSL_MSG("wolfSSL_EC_KEY_get0_private_key Bad arguments");
14842         return NULL;
14843     }
14844 
14845     return key->priv_key;
14846 }
14847 
14848 WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid)
14849 {
14850     WOLFSSL_EC_KEY *key;
14851     int x;
14852 
14853     WOLFSSL_ENTER("wolfSSL_EC_KEY_new_by_curve_name");
14854 
14855     key = wolfSSL_EC_KEY_new();
14856     if (key == NULL) {
14857         WOLFSSL_MSG("wolfSSL_EC_KEY_new failure");
14858         return NULL;
14859     }
14860 
14861     /* set the nid of the curve */
14862     key->group->curve_nid = nid;
14863 
14864     /* search and set the corresponding internal curve idx */
14865     for (x = 0; ecc_sets[x].size != 0; x++)
14866         if (ecc_sets[x].nid == key->group->curve_nid) {
14867             key->group->curve_idx = x;
14868             break;
14869         }
14870 
14871     return key;
14872 }
14873 
14874 static void InitwolfSSL_ECKey(WOLFSSL_EC_KEY* key)
14875 {
14876     if (key) {
14877         key->group    = NULL;
14878         key->pub_key  = NULL;
14879         key->priv_key = NULL;
14880         key->internal = NULL;
14881         key->inSet    = 0;
14882         key->exSet    = 0;
14883     }
14884 }
14885 
14886 WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void)
14887 {
14888     WOLFSSL_EC_KEY *external;
14889     ecc_key* key;
14890 
14891     WOLFSSL_ENTER("wolfSSL_EC_KEY_new");
14892 
14893     external = (WOLFSSL_EC_KEY*)XMALLOC(sizeof(WOLFSSL_EC_KEY), NULL,
14894                                         DYNAMIC_TYPE_ECC);
14895     if (external == NULL) {
14896         WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_KEY failure");
14897         return NULL;
14898     }
14899     XMEMSET(external, 0, sizeof(WOLFSSL_EC_KEY));
14900 
14901     InitwolfSSL_ECKey(external);
14902 
14903     external->internal = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL,
14904                                            DYNAMIC_TYPE_ECC);
14905     if (external->internal == NULL) {
14906         WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc ecc key failure");
14907         wolfSSL_EC_KEY_free(external);
14908         return NULL;
14909     }
14910     XMEMSET(external->internal, 0, sizeof(ecc_key));
14911 
14912     wc_ecc_init((ecc_key*)external->internal);
14913 
14914     /* public key */
14915     external->pub_key = (WOLFSSL_EC_POINT*)XMALLOC(sizeof(WOLFSSL_EC_POINT),
14916                                                    NULL, DYNAMIC_TYPE_ECC);
14917     if (external->pub_key == NULL) {
14918         WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_POINT failure");
14919         wolfSSL_EC_KEY_free(external);
14920         return NULL;
14921     }
14922     XMEMSET(external->pub_key, 0, sizeof(WOLFSSL_EC_POINT));
14923 
14924     key = (ecc_key*)external->internal;
14925     external->pub_key->internal = (ecc_point*)&key->pubkey;
14926 
14927     /* curve group */
14928     external->group = (WOLFSSL_EC_GROUP*)XMALLOC(sizeof(WOLFSSL_EC_GROUP), NULL,
14929                                                  DYNAMIC_TYPE_ECC);
14930     if (external->group == NULL) {
14931         WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_GROUP failure");
14932         wolfSSL_EC_KEY_free(external);
14933         return NULL;
14934     }
14935     XMEMSET(external->group, 0, sizeof(WOLFSSL_EC_GROUP));
14936 
14937     /* private key */
14938     external->priv_key = wolfSSL_BN_new();
14939     if (external->priv_key == NULL) {
14940         WOLFSSL_MSG("wolfSSL_BN_new failure");
14941         wolfSSL_EC_KEY_free(external);
14942         return NULL;
14943     }
14944 
14945     return external;
14946 }
14947 
14948 void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key)
14949 {
14950     WOLFSSL_ENTER("wolfSSL_EC_KEY_free");
14951 
14952     if (key != NULL) {
14953         if (key->internal != NULL) {
14954             wc_ecc_free((ecc_key*)key->internal);
14955             XFREE(key->internal, NULL, DYNAMIC_TYPE_ECC);
14956         }
14957         wolfSSL_BN_free(key->priv_key);
14958         wolfSSL_EC_POINT_free(key->pub_key);
14959         wolfSSL_EC_GROUP_free(key->group);
14960         InitwolfSSL_ECKey(key); /* set back to NULLs for safety */
14961 
14962         XFREE(key, NULL, DYNAMIC_TYPE_ECC);
14963         key = NULL;
14964     }
14965 }
14966 
14967 int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group)
14968 {
14969     (void)key;
14970     (void)group;
14971 
14972     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_group");
14973     WOLFSSL_MSG("wolfSSL_EC_KEY_set_group TBD");
14974 
14975     return -1;
14976 }
14977 
14978 int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key)
14979 {
14980     int     initTmpRng = 0;
14981     WC_RNG* rng = NULL;
14982 #ifdef WOLFSSL_SMALL_STACK
14983     WC_RNG* tmpRNG = NULL;
14984 #else
14985     WC_RNG  tmpRNG[1];
14986 #endif
14987 
14988     WOLFSSL_ENTER("wolfSSL_EC_KEY_generate_key");
14989 
14990     if (key == NULL || key->internal == NULL ||
14991         key->group == NULL || key->group->curve_idx < 0) {
14992         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key Bad arguments");
14993         return 0;
14994     }
14995 
14996 #ifdef WOLFSSL_SMALL_STACK
14997     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
14998     if (tmpRNG == NULL)
14999         return 0;
15000 #endif
15001 
15002     if (wc_InitRng(tmpRNG) == 0) {
15003         rng = tmpRNG;
15004         initTmpRng = 1;
15005     }
15006     else {
15007         WOLFSSL_MSG("Bad RNG Init, trying global");
15008         if (initGlobalRNG == 0)
15009             WOLFSSL_MSG("Global RNG no Init");
15010         else
15011             rng = &globalRNG;
15012     }
15013 
15014     if (rng == NULL) {
15015         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to set RNG");
15016 #ifdef WOLFSSL_SMALL_STACK
15017         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15018 #endif
15019         return 0;
15020     }
15021 
15022     if (wc_ecc_make_key(rng, ecc_sets[key->group->curve_idx].size,
15023                         (ecc_key*)key->internal) != MP_OKAY) {
15024         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key wc_ecc_make_key failed");
15025 #ifdef WOLFSSL_SMALL_STACK
15026         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15027 #endif
15028         return 0;
15029     }
15030 
15031     if (initTmpRng)
15032         wc_FreeRng(tmpRNG);
15033 #ifdef WOLFSSL_SMALL_STACK
15034     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15035 #endif
15036 
15037     if (SetECKeyExternal(key) != SSL_SUCCESS) {
15038         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key SetECKeyExternal failed");
15039         return 0;
15040     }
15041 
15042     return 1;
15043 }
15044 
15045 void wolfSSL_EC_KEY_set_asn1_flag(WOLFSSL_EC_KEY *key, int asn1_flag)
15046 {
15047     (void)key;
15048     (void)asn1_flag;
15049 
15050     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_asn1_flag");
15051     WOLFSSL_MSG("wolfSSL_EC_KEY_set_asn1_flag TBD");
15052 }
15053 
15054 /* return code compliant with OpenSSL :
15055  *   1 if success, 0 if error
15056  */
15057 int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key,
15058                                   const WOLFSSL_EC_POINT *pub)
15059 {
15060     ecc_point *pub_p, *key_p;
15061 
15062     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_public_key");
15063 
15064     if (key == NULL || key->internal == NULL ||
15065         pub == NULL || pub->internal == NULL) {
15066         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order Bad arguments");
15067         return SSL_FAILURE;
15068     }
15069 
15070     if (key->inSet == 0) {
15071         if (SetECKeyInternal(key) != SSL_SUCCESS) {
15072             WOLFSSL_MSG("SetECKeyInternal failed");
15073             return SSL_FAILURE;
15074         }
15075     }
15076 
15077     if (pub->inSet == 0) {
15078         if (SetECPointInternal((WOLFSSL_EC_POINT *)pub) != SSL_SUCCESS) {
15079             WOLFSSL_MSG("SetECPointInternal failed");
15080             return SSL_FAILURE;
15081         }
15082     }
15083 
15084     pub_p = (ecc_point*)pub->internal;
15085     key_p = (ecc_point*)key->pub_key->internal;
15086 
15087     /* create new point if required */
15088     if (key_p == NULL)
15089         key_p = wc_ecc_new_point();
15090 
15091     if (key_p == NULL) {
15092         WOLFSSL_MSG("key ecc point NULL");
15093         return SSL_FAILURE;
15094     }
15095 
15096     if (wc_ecc_copy_point(pub_p, key_p) != MP_OKAY) {
15097         WOLFSSL_MSG("ecc_copy_point failure");
15098         return SSL_FAILURE;
15099     }
15100 
15101     if (SetECKeyExternal(key) != SSL_SUCCESS) {
15102         WOLFSSL_MSG("SetECKeyInternal failed");
15103         return SSL_FAILURE;
15104     }
15105 
15106 #if defined(DEBUG_WOLFSSL) && !defined(NO_FILESYSTEM)
15107     wolfssl_EC_POINT_dump("pub", pub);
15108     wolfssl_EC_POINT_dump("key->pub_key", key->pub_key);
15109 #endif
15110     return SSL_SUCCESS;
15111 }
15112 /* End EC_KEY */
15113 
15114 #if defined(DEBUG_WOLFSSL) && !defined(NO_FILESYSTEM)
15115 void wolfssl_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *p)
15116 {
15117     char *num;
15118 
15119     WOLFSSL_ENTER("wolfssl_EC_POINT_dump");
15120 
15121     if (p == NULL) {
15122         fprintf(stderr, "%s = NULL", msg);
15123         return ;
15124     }
15125 
15126     fprintf(stderr, "%s:\n\tinSet=%d, exSet=%d\n", msg, p->inSet, p->exSet);
15127     num = wolfSSL_BN_bn2hex(p->X);
15128     fprintf(stderr, "\tX = %s\n", num);
15129     XFREE(num, NULL, DYNAMIC_TYPE_ECC);
15130     num = wolfSSL_BN_bn2hex(p->Y);
15131     fprintf(stderr, "\tY = %s\n", num);
15132     XFREE(num, NULL, DYNAMIC_TYPE_ECC);
15133 }
15134 #endif
15135 
15136 /* Start EC_GROUP */
15137 
15138 /* return code compliant with OpenSSL :
15139  *   0 if equal, 1 if not and -1 in case of error
15140  */
15141 int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b,
15142                          WOLFSSL_BN_CTX *ctx)
15143 {
15144     (void)ctx;
15145 
15146     WOLFSSL_ENTER("wolfSSL_EC_GROUP_cmp");
15147 
15148     if (a == NULL || b == NULL) {
15149         WOLFSSL_MSG("wolfSSL_EC_GROUP_cmp Bad arguments");
15150         return SSL_FATAL_ERROR;
15151     }
15152 
15153     /* ok */
15154     if ((a->curve_idx == b->curve_idx) && (a->curve_nid == b->curve_nid))
15155         return 0;
15156 
15157     /* ko */
15158     return 1;
15159 }
15160 
15161 void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group)
15162 {
15163     WOLFSSL_ENTER("wolfSSL_EC_GROUP_free");
15164 
15165     XFREE(group, NULL, DYNAMIC_TYPE_ECC);
15166     group = NULL;
15167 }
15168 
15169 void wolfSSL_EC_GROUP_set_asn1_flag(WOLFSSL_EC_GROUP *group, int flag)
15170 {
15171     (void)group;
15172     (void)flag;
15173 
15174     WOLFSSL_ENTER("wolfSSL_EC_GROUP_set_asn1_flag");
15175     WOLFSSL_MSG("wolfSSL_EC_GROUP_set_asn1_flag TBD");
15176 }
15177 
15178 WOLFSSL_EC_GROUP *wolfSSL_EC_GROUP_new_by_curve_name(int nid)
15179 {
15180     WOLFSSL_EC_GROUP *g;
15181     int x;
15182 
15183     WOLFSSL_ENTER("wolfSSL_EC_GROUP_new_by_curve_name");
15184 
15185     /* curve group */
15186     g = (WOLFSSL_EC_GROUP*) XMALLOC(sizeof(WOLFSSL_EC_GROUP), NULL,
15187                                     DYNAMIC_TYPE_ECC);
15188     if (g == NULL) {
15189         WOLFSSL_MSG("wolfSSL_EC_GROUP_new_by_curve_name malloc failure");
15190         return NULL;
15191     }
15192     XMEMSET(g, 0, sizeof(WOLFSSL_EC_GROUP));
15193 
15194     /* set the nid of the curve */
15195     g->curve_nid = nid;
15196 
15197     /* search and set the corresponding internal curve idx */
15198     for (x = 0; ecc_sets[x].size != 0; x++)
15199         if (ecc_sets[x].nid == g->curve_nid) {
15200             g->curve_idx = x;
15201             break;
15202         }
15203 
15204     return g;
15205 }
15206 
15207 /* return code compliant with OpenSSL :
15208  *   the curve nid if success, 0 if error
15209  */
15210 int wolfSSL_EC_GROUP_get_curve_name(const WOLFSSL_EC_GROUP *group)
15211 {
15212     WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_curve_name");
15213 
15214     if (group == NULL) {
15215         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_curve_name Bad arguments");
15216         return SSL_FAILURE;
15217     }
15218 
15219     return group->curve_nid;
15220 }
15221 
15222 /* return code compliant with OpenSSL :
15223  *   the degree of the curve if success, 0 if error
15224  */
15225 int wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP *group)
15226 {
15227     WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_degree");
15228 
15229     if (group == NULL || group->curve_idx < 0) {
15230         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_degree Bad arguments");
15231         return SSL_FAILURE;
15232     }
15233 
15234     switch(group->curve_nid) {
15235         case NID_X9_62_prime256v1:
15236             return 256;
15237             break;
15238         case NID_secp384r1:
15239             return 384;
15240             break;
15241         case NID_secp521r1:
15242             return 521;
15243             break;
15244         default :
15245             return SSL_FAILURE;
15246             break;
15247     }
15248 }
15249 
15250 /* return code compliant with OpenSSL :
15251  *   1 if success, 0 if error
15252  */
15253 int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group,
15254                                WOLFSSL_BIGNUM *order, WOLFSSL_BN_CTX *ctx)
15255 {
15256     (void)ctx;
15257 
15258     if (group == NULL || order == NULL || order->internal == NULL) {
15259         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order NULL error");
15260         return SSL_FAILURE;
15261     }
15262 
15263     if (mp_init((mp_int*)order->internal) != MP_OKAY) {
15264         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_init failure");
15265         return SSL_FAILURE;
15266     }
15267 
15268     if (mp_read_radix((mp_int*)order->internal,
15269                       ecc_sets[group->curve_idx].order, 16) != MP_OKAY) {
15270         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_read order failure");
15271         mp_clear((mp_int*)order->internal);
15272         return SSL_FAILURE;
15273     }
15274 
15275     return SSL_SUCCESS;
15276 }
15277 /* End EC_GROUP */
15278 
15279 /* Start EC_POINT */
15280 
15281 /* return code compliant with OpenSSL :
15282  *   1 if success, 0 if error
15283  */
15284 int wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP *group,
15285                         const WOLFSSL_EC_POINT *p,
15286                         unsigned char *out, unsigned int *len)
15287 {
15288     int err;
15289 
15290     WOLFSSL_ENTER("wolfSSL_ECPoint_i2d");
15291 
15292     if (group == NULL || p == NULL || len == NULL) {
15293         WOLFSSL_MSG("wolfSSL_ECPoint_i2d NULL error");
15294         return SSL_FAILURE;
15295     }
15296 
15297     if (p->inSet == 0) {
15298         WOLFSSL_MSG("No ECPoint internal set, do it");
15299 
15300         if (SetECPointInternal((WOLFSSL_EC_POINT *)p) != SSL_SUCCESS) {
15301             WOLFSSL_MSG("SetECPointInternal SetECPointInternal failed");
15302             return SSL_FAILURE;
15303         }
15304     }
15305 
15306 #if defined(DEBUG_WOLFSSL) && !defined(NO_FILESYSTEM)
15307     if (out != NULL) {
15308         wolfssl_EC_POINT_dump("i2d p", p);
15309     }
15310 #endif
15311     err = wc_ecc_export_point_der(group->curve_idx, (ecc_point*)p->internal,
15312                                   out, len);
15313     if (err != MP_OKAY && !(out == NULL && err == LENGTH_ONLY_E)) {
15314         WOLFSSL_MSG("wolfSSL_ECPoint_i2d wc_ecc_export_point_der failed");
15315         return SSL_FAILURE;
15316     }
15317 
15318     return SSL_SUCCESS;
15319 }
15320 
15321 /* return code compliant with OpenSSL :
15322  *   1 if success, 0 if error
15323  */
15324 int wolfSSL_ECPoint_d2i(unsigned char *in, unsigned int len,
15325                         const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *p)
15326 {
15327     WOLFSSL_ENTER("wolfSSL_ECPoint_d2i");
15328 
15329     if (group == NULL || p == NULL || p->internal == NULL || in == NULL) {
15330         WOLFSSL_MSG("wolfSSL_ECPoint_d2i NULL error");
15331         return SSL_FAILURE;
15332     }
15333 
15334     if (wc_ecc_import_point_der(in, len, group->curve_idx,
15335                                 (ecc_point*)p->internal) != MP_OKAY) {
15336         WOLFSSL_MSG("wc_ecc_import_point_der failed");
15337         return SSL_FAILURE;
15338     }
15339 
15340     if (p->exSet == 0) {
15341         WOLFSSL_MSG("No ECPoint external set, do it");
15342 
15343         if (SetECPointExternal(p) != SSL_SUCCESS) {
15344             WOLFSSL_MSG("SetECPointExternal failed");
15345             return SSL_FAILURE;
15346         }
15347     }
15348 
15349 #if defined(DEBUG_WOLFSSL) && !defined(NO_FILESYSTEM)
15350     wolfssl_EC_POINT_dump("d2i p", p);
15351 #endif
15352     return SSL_SUCCESS;
15353 }
15354 
15355 WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group)
15356 {
15357     WOLFSSL_EC_POINT *p;
15358 
15359     WOLFSSL_ENTER("wolfSSL_EC_POINT_new");
15360 
15361     if (group == NULL) {
15362         WOLFSSL_MSG("wolfSSL_EC_POINT_new NULL error");
15363         return NULL;
15364     }
15365 
15366     p = (WOLFSSL_EC_POINT *)XMALLOC(sizeof(WOLFSSL_EC_POINT), NULL,
15367                                     DYNAMIC_TYPE_ECC);
15368     if (p == NULL) {
15369         WOLFSSL_MSG("wolfSSL_EC_POINT_new malloc ecc point failure");
15370         return NULL;
15371     }
15372     XMEMSET(p, 0, sizeof(WOLFSSL_EC_POINT));
15373 
15374     p->internal = wc_ecc_new_point();
15375     if (p->internal == NULL) {
15376         WOLFSSL_MSG("ecc_new_point failure");
15377         XFREE(p, NULL, DYNAMIC_TYPE_ECC);
15378         return NULL;
15379     }
15380 
15381     return p;
15382 }
15383 
15384 /* return code compliant with OpenSSL :
15385  *   1 if success, 0 if error
15386  */
15387 int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group,
15388                                                 const WOLFSSL_EC_POINT *point,
15389                                                 WOLFSSL_BIGNUM *x,
15390                                                 WOLFSSL_BIGNUM *y,
15391                                                 WOLFSSL_BN_CTX *ctx)
15392 {
15393     (void)ctx;
15394 
15395     WOLFSSL_ENTER("wolfSSL_EC_POINT_get_affine_coordinates_GFp");
15396 
15397     if (group == NULL || point == NULL || point->internal == NULL ||
15398         x == NULL || y == NULL) {
15399         WOLFSSL_MSG("wolfSSL_EC_POINT_get_affine_coordinates_GFp NULL error");
15400         return SSL_FAILURE;
15401     }
15402 
15403     if (point->inSet == 0) {
15404         WOLFSSL_MSG("No ECPoint internal set, do it");
15405 
15406         if (SetECPointInternal((WOLFSSL_EC_POINT *)point) != SSL_SUCCESS) {
15407             WOLFSSL_MSG("SetECPointInternal failed");
15408             return SSL_FAILURE;
15409         }
15410     }
15411 
15412     BN_copy(x, point->X);
15413     BN_copy(y, point->Y);
15414 
15415     return SSL_SUCCESS;
15416 }
15417 
15418 /* return code compliant with OpenSSL :
15419  *   1 if success, 0 if error
15420  */
15421 int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r,
15422                          const WOLFSSL_BIGNUM *n, const WOLFSSL_EC_POINT *q,
15423                          const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
15424 {
15425     mp_int prime;
15426 
15427     (void)ctx;
15428     (void)n;
15429 
15430     WOLFSSL_ENTER("wolfSSL_EC_POINT_mul");
15431 
15432     if (group == NULL || r == NULL || r->internal == NULL ||
15433         q == NULL || q->internal == NULL || m == NULL) {
15434         WOLFSSL_MSG("wolfSSL_EC_POINT_mul NULL error");
15435         return SSL_FAILURE;
15436     }
15437 
15438     if (q->inSet == 0) {
15439         WOLFSSL_MSG("No ECPoint internal set, do it");
15440 
15441         if (SetECPointInternal((WOLFSSL_EC_POINT *)q) != SSL_SUCCESS) {
15442             WOLFSSL_MSG("SetECPointInternal failed");
15443             return SSL_FAILURE;
15444         }
15445     }
15446 
15447     /* compute the prime value of the curve */
15448     if (mp_init(&prime) != MP_OKAY) {
15449         WOLFSSL_MSG("wolfSSL_EC_POINT_mul init BN failed");
15450         return SSL_FAILURE;
15451     }
15452 
15453     if (mp_read_radix(&prime, ecc_sets[group->curve_idx].prime, 16) != MP_OKAY){
15454         WOLFSSL_MSG("wolfSSL_EC_POINT_mul read prime curve value failed");
15455         return SSL_FAILURE;
15456     }
15457 
15458     /* r = q * m % prime */
15459     if (wc_ecc_mulmod((mp_int*)m->internal, (ecc_point*)q->internal,
15460                       (ecc_point*)r->internal, &prime, 1) != MP_OKAY) {
15461         WOLFSSL_MSG("ecc_mulmod failure");
15462         mp_clear(&prime);
15463         return SSL_FAILURE;
15464     }
15465 
15466     mp_clear(&prime);
15467 
15468     /* set the external value for the computed point */
15469     if (SetECPointInternal(r) != SSL_SUCCESS) {
15470         WOLFSSL_MSG("SetECPointInternal failed");
15471         return SSL_FAILURE;
15472     }
15473 
15474     return SSL_SUCCESS;
15475 }
15476 
15477 void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *p)
15478 {
15479     WOLFSSL_ENTER("wolfSSL_EC_POINT_clear_free");
15480 
15481     wolfSSL_EC_POINT_free(p);
15482 }
15483 
15484 /* return code compliant with OpenSSL :
15485  *   0 if equal, 1 if not and -1 in case of error
15486  */
15487 int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group,
15488                          const WOLFSSL_EC_POINT *a, const WOLFSSL_EC_POINT *b,
15489                          WOLFSSL_BN_CTX *ctx)
15490 {
15491     int ret;
15492 
15493     (void)ctx;
15494 
15495     WOLFSSL_ENTER("wolfSSL_EC_POINT_cmp");
15496 
15497     if (group == NULL || a == NULL || a->internal == NULL || b == NULL ||
15498         b->internal == NULL) {
15499         WOLFSSL_MSG("wolfSSL_EC_POINT_cmp Bad arguments");
15500         return SSL_FATAL_ERROR;
15501     }
15502 
15503     ret = wc_ecc_cmp_point((ecc_point*)a->internal, (ecc_point*)b->internal);
15504     if (ret == MP_EQ)
15505         return 0;
15506     else if (ret == MP_LT || ret == MP_GT)
15507         return 1;
15508 
15509     return SSL_FATAL_ERROR;
15510 }
15511 
15512 void wolfSSL_EC_POINT_free(WOLFSSL_EC_POINT *p)
15513 {
15514     WOLFSSL_ENTER("wolfSSL_EC_POINT_free");
15515 
15516     if (p != NULL) {
15517         if (p->internal == NULL) {
15518             wc_ecc_del_point((ecc_point*)p->internal);
15519             XFREE(p->internal, NULL, DYNAMIC_TYPE_ECC);
15520             p->internal = NULL;
15521         }
15522 
15523         wolfSSL_BN_free(p->X);
15524         wolfSSL_BN_free(p->Y);
15525         wolfSSL_BN_free(p->Z);
15526         p->X = NULL;
15527         p->Y = NULL;
15528         p->Z = NULL;
15529         p->inSet = p->exSet = 0;
15530 
15531         XFREE(p, NULL, DYNAMIC_TYPE_ECC);
15532         p = NULL;
15533     }
15534 }
15535 
15536 /* return code compliant with OpenSSL :
15537  *   1 if point at infinity, 0 else
15538  */
15539 int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group,
15540                                     const WOLFSSL_EC_POINT *point)
15541 {
15542     int ret;
15543 
15544     WOLFSSL_ENTER("wolfSSL_EC_POINT_is_at_infinity");
15545 
15546     if (group == NULL || point == NULL || point->internal == NULL) {
15547         WOLFSSL_MSG("wolfSSL_EC_POINT_is_at_infinity NULL error");
15548         return SSL_FAILURE;
15549     }
15550     if (point->inSet == 0) {
15551         WOLFSSL_MSG("No ECPoint internal set, do it");
15552 
15553         if (SetECPointInternal((WOLFSSL_EC_POINT *)point) != SSL_SUCCESS) {
15554             WOLFSSL_MSG("SetECPointInternal failed");
15555             return SSL_FAILURE;
15556         }
15557     }
15558 
15559     ret = wc_ecc_point_is_at_infinity((ecc_point*)point->internal);
15560     if (ret <= 0) {
15561         WOLFSSL_MSG("ecc_point_is_at_infinity failure");
15562         return SSL_FAILURE;
15563     }
15564 
15565     return SSL_SUCCESS;
15566 }
15567 
15568 /* End EC_POINT */
15569 
15570 /* Start ECDSA_SIG */
15571 void wolfSSL_ECDSA_SIG_free(WOLFSSL_ECDSA_SIG *sig)
15572 {
15573     WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_free");
15574 
15575     if (sig) {
15576         wolfSSL_BN_free(sig->r);
15577         wolfSSL_BN_free(sig->s);
15578 
15579         XFREE(sig, NULL, DYNAMIC_TYPE_ECC);
15580     }
15581 }
15582 
15583 WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_SIG_new(void)
15584 {
15585     WOLFSSL_ECDSA_SIG *sig;
15586 
15587     WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_new");
15588 
15589     sig = (WOLFSSL_ECDSA_SIG*) XMALLOC(sizeof(WOLFSSL_ECDSA_SIG), NULL,
15590                                        DYNAMIC_TYPE_ECC);
15591     if (sig == NULL) {
15592         WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA signature failure");
15593         return NULL;
15594     }
15595 
15596     sig->s = NULL;
15597     sig->r = wolfSSL_BN_new();
15598     if (sig->r == NULL) {
15599         WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA r failure");
15600         wolfSSL_ECDSA_SIG_free(sig);
15601         return NULL;
15602     }
15603 
15604     sig->s = wolfSSL_BN_new();
15605     if (sig->s == NULL) {
15606         WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA s failure");
15607         wolfSSL_ECDSA_SIG_free(sig);
15608         return NULL;
15609     }
15610 
15611     return sig;
15612 }
15613 
15614 /* return signature structure on success, NULL otherwise */
15615 WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *d, int dlen,
15616                                          WOLFSSL_EC_KEY *key)
15617 {
15618     WOLFSSL_ECDSA_SIG *sig = NULL;
15619     int     initTmpRng = 0;
15620     WC_RNG* rng = NULL;
15621 #ifdef WOLFSSL_SMALL_STACK
15622     WC_RNG* tmpRNG = NULL;
15623 #else
15624     WC_RNG  tmpRNG[1];
15625 #endif
15626 
15627     WOLFSSL_ENTER("wolfSSL_ECDSA_do_sign");
15628 
15629     if (d == NULL || key == NULL || key->internal == NULL) {
15630         WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Bad arguments");
15631         return NULL;
15632     }
15633 
15634     /* set internal key if not done */
15635     if (key->inSet == 0)
15636     {
15637         WOLFSSL_MSG("wolfSSL_ECDSA_do_sign No EC key internal set, do it");
15638 
15639         if (SetECKeyInternal(key) != SSL_SUCCESS) {
15640             WOLFSSL_MSG("wolfSSL_ECDSA_do_sign SetECKeyInternal failed");
15641             return NULL;
15642         }
15643     }
15644 
15645 #ifdef WOLFSSL_SMALL_STACK
15646     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
15647     if (tmpRNG == NULL)
15648         return NULL;
15649 #endif
15650 
15651     if (wc_InitRng(tmpRNG) == 0) {
15652         rng = tmpRNG;
15653         initTmpRng = 1;
15654     }
15655     else {
15656         WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Bad RNG Init, trying global");
15657         if (initGlobalRNG == 0)
15658             WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Global RNG no Init");
15659         else
15660             rng = &globalRNG;
15661     }
15662 
15663     if (rng) {
15664         mp_int sig_r, sig_s;
15665 
15666         if (mp_init_multi(&sig_r, &sig_s, NULL, NULL, NULL, NULL) == MP_OKAY) {
15667             if (wc_ecc_sign_hash_ex(d, dlen, rng, (ecc_key*)key->internal,
15668                                     &sig_r, &sig_s) != MP_OKAY) {
15669                 WOLFSSL_MSG("wc_ecc_sign_hash_ex failed");
15670             }
15671             else {
15672                 /* put signature blob in ECDSA structure */
15673                 sig = wolfSSL_ECDSA_SIG_new();
15674                 if (sig == NULL)
15675                     WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new failed");
15676                 else if (SetIndividualExternal(&(sig->r), &sig_r)!=SSL_SUCCESS){
15677                     WOLFSSL_MSG("ecdsa r key error");
15678                     wolfSSL_ECDSA_SIG_free(sig);
15679                     sig = NULL;
15680                 }
15681                 else if (SetIndividualExternal(&(sig->s), &sig_s)!=SSL_SUCCESS){
15682                     WOLFSSL_MSG("ecdsa s key error");
15683                     wolfSSL_ECDSA_SIG_free(sig);
15684                     sig = NULL;
15685                 }
15686 
15687                 mp_clear(&sig_r);
15688                 mp_clear(&sig_s);
15689             }
15690         }
15691     }
15692 
15693     if (initTmpRng)
15694         wc_FreeRng(tmpRNG);
15695 #ifdef WOLFSSL_SMALL_STACK
15696     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15697 #endif
15698 
15699     return sig;
15700 }
15701 
15702 /* return code compliant with OpenSSL :
15703  *   1 for a valid signature, 0 for an invalid signature and -1 on error
15704  */
15705 int wolfSSL_ECDSA_do_verify(const unsigned char *d, int dlen,
15706                             const WOLFSSL_ECDSA_SIG *sig, WOLFSSL_EC_KEY *key)
15707 {
15708     int check_sign = 0;
15709 
15710     WOLFSSL_ENTER("wolfSSL_ECDSA_do_verify");
15711 
15712     if (d == NULL || sig == NULL || key == NULL || key->internal == NULL) {
15713         WOLFSSL_MSG("wolfSSL_ECDSA_do_verify Bad arguments");
15714         return SSL_FATAL_ERROR;
15715     }
15716 
15717     /* set internal key if not done */
15718     if (key->inSet == 0)
15719     {
15720         WOLFSSL_MSG("No EC key internal set, do it");
15721 
15722         if (SetECKeyInternal(key) != SSL_SUCCESS) {
15723             WOLFSSL_MSG("SetECKeyInternal failed");
15724             return SSL_FATAL_ERROR;
15725         }
15726     }
15727 
15728     if (wc_ecc_verify_hash_ex((mp_int*)sig->r->internal,
15729                               (mp_int*)sig->s->internal, d, dlen, &check_sign,
15730                               (ecc_key *)key->internal) != MP_OKAY) {
15731         WOLFSSL_MSG("wc_ecc_verify_hash failed");
15732         return SSL_FATAL_ERROR;
15733     }
15734     else if (check_sign == 0) {
15735         WOLFSSL_MSG("wc_ecc_verify_hash incorrect signature detected");
15736         return SSL_FAILURE;
15737     }
15738 
15739     return SSL_SUCCESS;
15740 }
15741 /* End ECDSA_SIG */
15742 
15743 /* Start ECDH */
15744 /* return code compliant with OpenSSL :
15745  *   length of computed key if success, -1 if error
15746  */
15747 int wolfSSL_ECDH_compute_key(void *out, size_t outlen,
15748                              const WOLFSSL_EC_POINT *pub_key,
15749                              WOLFSSL_EC_KEY *ecdh,
15750                              void *(*KDF) (const void *in, size_t inlen,
15751                                            void *out, size_t *outlen))
15752 {
15753     word32 len;
15754     (void)KDF;
15755 
15756     (void)KDF;
15757 
15758     WOLFSSL_ENTER("wolfSSL_ECDH_compute_key");
15759 
15760     if (out == NULL || pub_key == NULL || pub_key->internal == NULL ||
15761         ecdh == NULL || ecdh->internal == NULL) {
15762         WOLFSSL_MSG("Bad function arguments");
15763         return SSL_FATAL_ERROR;
15764     }
15765 
15766     /* set internal key if not done */
15767     if (ecdh->inSet == 0)
15768     {
15769         WOLFSSL_MSG("No EC key internal set, do it");
15770 
15771         if (SetECKeyInternal(ecdh) != SSL_SUCCESS) {
15772             WOLFSSL_MSG("SetECKeyInternal failed");
15773             return SSL_FATAL_ERROR;
15774         }
15775     }
15776 
15777     len = (word32)outlen;
15778 
15779     if (wc_ecc_shared_secret_ssh((ecc_key*)ecdh->internal,
15780                                  (ecc_point*)pub_key->internal,
15781                                  (byte *)out, &len) != MP_OKAY) {
15782         WOLFSSL_MSG("wc_ecc_shared_secret failed");
15783         return SSL_FATAL_ERROR;
15784     }
15785 
15786     return len;
15787 }
15788 /* End ECDH */
15789 
15790 #if !defined(NO_FILESYSTEM)
15791 /* return code compliant with OpenSSL :
15792  *   1 if success, 0 if error
15793  */
15794 int wolfSSL_PEM_write_EC_PUBKEY(FILE *fp, WOLFSSL_EC_KEY *x)
15795 {
15796     (void)fp;
15797     (void)x;
15798 
15799     WOLFSSL_MSG("wolfSSL_PEM_write_EC_PUBKEY not implemented");
15800 
15801     return SSL_FAILURE;
15802 }
15803 #endif /* NO_FILESYSTEM */
15804 
15805 #if defined(WOLFSSL_KEY_GEN)
15806 
15807 /* return code compliant with OpenSSL :
15808  *   1 if success, 0 if error
15809  */
15810 int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ecc,
15811                                        const EVP_CIPHER* cipher,
15812                                        unsigned char* passwd, int len,
15813                                        pem_password_cb cb, void* arg)
15814 {
15815     (void)bio;
15816     (void)ecc;
15817     (void)cipher;
15818     (void)passwd;
15819     (void)len;
15820     (void)cb;
15821     (void)arg;
15822 
15823     WOLFSSL_MSG("wolfSSL_PEM_write_bio_ECPrivateKey not implemented");
15824 
15825     return SSL_FAILURE;
15826 }
15827 
15828 /* return code compliant with OpenSSL :
15829  *   1 if success, 0 if error
15830  */
15831 int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc,
15832                                        const EVP_CIPHER* cipher,
15833                                        unsigned char* passwd, int passwdSz,
15834                                        unsigned char **pem, int *plen)
15835 {
15836     byte *derBuf, *tmp, *cipherInfo = NULL;
15837     int  der_max_len = 0, derSz = 0;
15838 
15839     WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey");
15840 
15841     if (pem == NULL || plen == NULL || ecc == NULL || ecc->internal == NULL) {
15842         WOLFSSL_MSG("Bad function arguments");
15843         return SSL_FAILURE;
15844     }
15845 
15846     if (ecc->inSet == 0) {
15847         WOLFSSL_MSG("No ECC internal set, do it");
15848 
15849         if (SetECKeyInternal(ecc) != SSL_SUCCESS) {
15850             WOLFSSL_MSG("SetDsaInternal failed");
15851             return SSL_FAILURE;
15852         }
15853     }
15854 
15855     /* 4 > size of pub, priv + ASN.1 additional informations
15856      */
15857     der_max_len = 4 * wc_ecc_size((ecc_key*)ecc->internal) + AES_BLOCK_SIZE;
15858 
15859     derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15860     if (derBuf == NULL) {
15861         WOLFSSL_MSG("malloc failed");
15862         return SSL_FAILURE;
15863     }
15864 
15865     /* Key to DER */
15866     derSz = wc_EccKeyToDer((ecc_key*)ecc->internal, derBuf, der_max_len);
15867     if (derSz < 0) {
15868         WOLFSSL_MSG("wc_DsaKeyToDer failed");
15869         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15870         return SSL_FAILURE;
15871     }
15872 
15873     /* encrypt DER buffer if required */
15874     if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
15875         int ret;
15876 
15877         ret = EncryptDerKey(derBuf, &derSz, cipher,
15878                             passwd, passwdSz, &cipherInfo);
15879         if (ret != SSL_SUCCESS) {
15880             WOLFSSL_MSG("EncryptDerKey failed");
15881             XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15882             return ret;
15883         }
15884 
15885         /* tmp buffer with a max size */
15886         *plen = (derSz * 2) + sizeof(BEGIN_EC_PRIV) +
15887         sizeof(END_EC_PRIV) + HEADER_ENCRYPTED_KEY_SIZE;
15888     }
15889     else /* tmp buffer with a max size */
15890         *plen = (derSz * 2) + sizeof(BEGIN_EC_PRIV) + sizeof(END_EC_PRIV);
15891 
15892     tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15893     if (tmp == NULL) {
15894         WOLFSSL_MSG("malloc failed");
15895         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15896         if (cipherInfo != NULL)
15897             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15898         return SSL_FAILURE;
15899     }
15900 
15901     /* DER to PEM */
15902     *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, ECC_PRIVATEKEY_TYPE);
15903     if (*plen <= 0) {
15904         WOLFSSL_MSG("wc_DerToPemEx failed");
15905         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15906         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15907         if (cipherInfo != NULL)
15908             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15909         return SSL_FAILURE;
15910     }
15911     XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15912     if (cipherInfo != NULL)
15913         XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15914 
15915     *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY);
15916     if (*pem == NULL) {
15917         WOLFSSL_MSG("malloc failed");
15918         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15919         return SSL_FAILURE;
15920     }
15921     XMEMSET(*pem, 0, (*plen)+1);
15922 
15923     if (XMEMCPY(*pem, tmp, *plen) == NULL) {
15924         WOLFSSL_MSG("XMEMCPY failed");
15925         XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
15926         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15927         return SSL_FAILURE;
15928     }
15929     XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15930 
15931     return SSL_SUCCESS;
15932 }
15933 
15934 #ifndef NO_FILESYSTEM
15935 /* return code compliant with OpenSSL :
15936  *   1 if success, 0 if error
15937  */
15938 int wolfSSL_PEM_write_ECPrivateKey(FILE *fp, WOLFSSL_EC_KEY *ecc,
15939                                    const EVP_CIPHER *enc,
15940                                    unsigned char *kstr, int klen,
15941                                    pem_password_cb *cb, void *u)
15942 {
15943     byte *pem;
15944     int  plen, ret;
15945 
15946     (void)cb;
15947     (void)u;
15948 
15949     WOLFSSL_MSG("wolfSSL_PEM_write_ECPrivateKey");
15950 
15951     if (fp == NULL || ecc == NULL || ecc->internal == NULL) {
15952         WOLFSSL_MSG("Bad function arguments");
15953         return SSL_FAILURE;
15954     }
15955 
15956     ret = wolfSSL_PEM_write_mem_ECPrivateKey(ecc, enc, kstr, klen, &pem, &plen);
15957     if (ret != SSL_SUCCESS) {
15958         WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey failed");
15959         return SSL_FAILURE;
15960     }
15961 
15962     ret = (int)XFWRITE(pem, plen, 1, fp);
15963     if (ret != 1) {
15964         WOLFSSL_MSG("ECC private key file write failed");
15965         return SSL_FAILURE;
15966     }
15967 
15968     XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
15969     return SSL_SUCCESS;
15970 }
15971 
15972 #endif /* NO_FILESYSTEM */
15973 #endif /* defined(WOLFSSL_KEY_GEN) */
15974 
15975 #endif /* HAVE_ECC */
15976 
15977 
15978 #ifndef NO_DSA
15979 
15980 #if defined(WOLFSSL_KEY_GEN)
15981 
15982 /* return code compliant with OpenSSL :
15983  *   1 if success, 0 if error
15984  */
15985 int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa,
15986                                        const EVP_CIPHER* cipher,
15987                                        unsigned char* passwd, int len,
15988                                        pem_password_cb cb, void* arg)
15989 {
15990     (void)bio;
15991     (void)dsa;
15992     (void)cipher;
15993     (void)passwd;
15994     (void)len;
15995     (void)cb;
15996     (void)arg;
15997 
15998     WOLFSSL_MSG("wolfSSL_PEM_write_bio_DSAPrivateKey not implemented");
15999 
16000     return SSL_FAILURE;
16001 }
16002 
16003 /* return code compliant with OpenSSL :
16004  *   1 if success, 0 if error
16005  */
16006 int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa,
16007                                         const EVP_CIPHER* cipher,
16008                                         unsigned char* passwd, int passwdSz,
16009                                         unsigned char **pem, int *plen)
16010 {
16011     byte *derBuf, *tmp, *cipherInfo = NULL;
16012     int  der_max_len = 0, derSz = 0;
16013 
16014     WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey");
16015 
16016     if (pem == NULL || plen == NULL || dsa == NULL || dsa->internal == NULL) {
16017         WOLFSSL_MSG("Bad function arguments");
16018         return SSL_FAILURE;
16019     }
16020 
16021     if (dsa->inSet == 0) {
16022         WOLFSSL_MSG("No DSA internal set, do it");
16023 
16024         if (SetDsaInternal(dsa) != SSL_SUCCESS) {
16025             WOLFSSL_MSG("SetDsaInternal failed");
16026             return SSL_FAILURE;
16027         }
16028     }
16029 
16030     /* 4 > size of pub, priv, p, q, g + ASN.1 additional informations
16031      */
16032     der_max_len = 4 * wolfSSL_BN_num_bytes(dsa->g) + AES_BLOCK_SIZE;
16033 
16034     derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16035     if (derBuf == NULL) {
16036         WOLFSSL_MSG("malloc failed");
16037         return SSL_FAILURE;
16038     }
16039 
16040     /* Key to DER */
16041     derSz = wc_DsaKeyToDer((DsaKey*)dsa->internal, derBuf, der_max_len);
16042     if (derSz < 0) {
16043         WOLFSSL_MSG("wc_DsaKeyToDer failed");
16044         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16045         return SSL_FAILURE;
16046     }
16047 
16048     /* encrypt DER buffer if required */
16049     if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
16050         int ret;
16051 
16052         ret = EncryptDerKey(derBuf, &derSz, cipher,
16053                             passwd, passwdSz, &cipherInfo);
16054         if (ret != SSL_SUCCESS) {
16055             WOLFSSL_MSG("EncryptDerKey failed");
16056             XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16057             return ret;
16058         }
16059 
16060         /* tmp buffer with a max size */
16061         *plen = (derSz * 2) + sizeof(BEGIN_DSA_PRIV) +
16062         sizeof(END_DSA_PRIV) + HEADER_ENCRYPTED_KEY_SIZE;
16063     }
16064     else /* tmp buffer with a max size */
16065         *plen = (derSz * 2) + sizeof(BEGIN_DSA_PRIV) + sizeof(END_DSA_PRIV);
16066 
16067     tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16068     if (tmp == NULL) {
16069         WOLFSSL_MSG("malloc failed");
16070         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16071         if (cipherInfo != NULL)
16072             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16073         return SSL_FAILURE;
16074     }
16075 
16076     /* DER to PEM */
16077     *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, DSA_PRIVATEKEY_TYPE);
16078     if (*plen <= 0) {
16079         WOLFSSL_MSG("wc_DerToPemEx failed");
16080         XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16081         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16082         if (cipherInfo != NULL)
16083             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16084         return SSL_FAILURE;
16085     }
16086     XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16087     if (cipherInfo != NULL)
16088         XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16089 
16090     *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY);
16091     if (*pem == NULL) {
16092         WOLFSSL_MSG("malloc failed");
16093         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16094         return SSL_FAILURE;
16095     }
16096     XMEMSET(*pem, 0, (*plen)+1);
16097 
16098     if (XMEMCPY(*pem, tmp, *plen) == NULL) {
16099         WOLFSSL_MSG("XMEMCPY failed");
16100         XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
16101         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16102         return SSL_FAILURE;
16103     }
16104     XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16105 
16106     return SSL_SUCCESS;
16107 }
16108 
16109 #ifndef NO_FILESYSTEM
16110 /* return code compliant with OpenSSL :
16111  *   1 if success, 0 if error
16112  */
16113 int wolfSSL_PEM_write_DSAPrivateKey(FILE *fp, WOLFSSL_DSA *dsa,
16114                                     const EVP_CIPHER *enc,
16115                                     unsigned char *kstr, int klen,
16116                                     pem_password_cb *cb, void *u)
16117 {
16118     byte *pem;
16119     int  plen, ret;
16120 
16121     (void)cb;
16122     (void)u;
16123 
16124     WOLFSSL_MSG("wolfSSL_PEM_write_DSAPrivateKey");
16125 
16126     if (fp == NULL || dsa == NULL || dsa->internal == NULL) {
16127         WOLFSSL_MSG("Bad function arguments");
16128         return SSL_FAILURE;
16129     }
16130 
16131     ret = wolfSSL_PEM_write_mem_DSAPrivateKey(dsa, enc, kstr, klen, &pem, &plen);
16132     if (ret != SSL_SUCCESS) {
16133         WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey failed");
16134         return SSL_FAILURE;
16135     }
16136 
16137     ret = (int)XFWRITE(pem, plen, 1, fp);
16138     if (ret != 1) {
16139         WOLFSSL_MSG("DSA private key file write failed");
16140         return SSL_FAILURE;
16141     }
16142 
16143     XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
16144     return SSL_SUCCESS;
16145 }
16146 
16147 #endif /* NO_FILESYSTEM */
16148 #endif /* defined(WOLFSSL_KEY_GEN) */
16149 
16150 #ifndef NO_FILESYSTEM
16151 /* return code compliant with OpenSSL :
16152  *   1 if success, 0 if error
16153  */
16154 int wolfSSL_PEM_write_DSA_PUBKEY(FILE *fp, WOLFSSL_DSA *x)
16155 {
16156     (void)fp;
16157     (void)x;
16158 
16159     WOLFSSL_MSG("wolfSSL_PEM_write_DSA_PUBKEY not implemented");
16160 
16161     return SSL_FAILURE;
16162 }
16163 #endif /* NO_FILESYSTEM */
16164 
16165 #endif /* #ifndef NO_DSA */
16166 
16167 WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
16168                     WOLFSSL_EVP_PKEY** key, pem_password_cb cb, void* arg)
16169 {
16170     (void)bio;
16171     (void)key;
16172     (void)cb;
16173     (void)arg;
16174 
16175     WOLFSSL_MSG("wolfSSL_PEM_read_bio_PrivateKey not implemented");
16176 
16177     return NULL;
16178 }
16179 
16180 
16181 int wolfSSL_EVP_PKEY_type(int type)
16182 {
16183     (void)type;
16184 
16185     WOLFSSL_MSG("wolfSSL_EVP_PKEY_type not implemented");
16186 
16187     return SSL_FATAL_ERROR;
16188 }
16189 
16190 
16191 #if !defined(NO_FILESYSTEM)
16192 WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x,
16193                                           pem_password_cb *cb, void *u)
16194 {
16195     (void)fp;
16196     (void)x;
16197     (void)cb;
16198     (void)u;
16199 
16200     WOLFSSL_MSG("wolfSSL_PEM_read_PUBKEY not implemented");
16201 
16202     return NULL;
16203 }
16204 #endif /* NO_FILESYSTEM */
16205 
16206 #ifndef NO_RSA
16207 
16208 #if !defined(NO_FILESYSTEM)
16209 WOLFSSL_RSA *wolfSSL_PEM_read_RSAPublicKey(FILE *fp, WOLFSSL_RSA **x,
16210                                            pem_password_cb *cb, void *u)
16211 {
16212     (void)fp;
16213     (void)x;
16214     (void)cb;
16215     (void)u;
16216 
16217     WOLFSSL_MSG("wolfSSL_PEM_read_RSAPublicKey not implemented");
16218 
16219     return NULL;
16220 }
16221 
16222 /* return code compliant with OpenSSL :
16223  *   1 if success, 0 if error
16224  */
16225 int wolfSSL_PEM_write_RSAPublicKey(FILE *fp, WOLFSSL_RSA *x)
16226 {
16227     (void)fp;
16228     (void)x;
16229 
16230     WOLFSSL_MSG("wolfSSL_PEM_write_RSAPublicKey not implemented");
16231 
16232     return SSL_FAILURE;
16233 }
16234 
16235 /* return code compliant with OpenSSL :
16236  *   1 if success, 0 if error
16237  */
16238 int wolfSSL_PEM_write_RSA_PUBKEY(FILE *fp, WOLFSSL_RSA *x)
16239 {
16240     (void)fp;
16241     (void)x;
16242 
16243     WOLFSSL_MSG("wolfSSL_PEM_write_RSA_PUBKEY not implemented");
16244 
16245     return SSL_FAILURE;
16246 }
16247 #endif /* NO_FILESYSTEM */
16248 
16249 /* return SSL_SUCCESS if success, SSL_FATAL_ERROR if error */
16250 int wolfSSL_RSA_LoadDer(WOLFSSL_RSA* rsa, const unsigned char* derBuf, int derSz)
16251 {
16252     word32 idx = 0;
16253     int    ret;
16254 
16255     WOLFSSL_ENTER("wolfSSL_RSA_LoadDer");
16256 
16257     if (rsa == NULL || rsa->internal == NULL || derBuf == NULL || derSz <= 0) {
16258         WOLFSSL_MSG("Bad function arguments");
16259         return SSL_FATAL_ERROR;
16260     }
16261 
16262     ret = wc_RsaPrivateKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal, derSz);
16263     if (ret < 0) {
16264         WOLFSSL_MSG("RsaPrivateKeyDecode failed");
16265         return SSL_FATAL_ERROR;
16266     }
16267 
16268     if (SetRsaExternal(rsa) != SSL_SUCCESS) {
16269         WOLFSSL_MSG("SetRsaExternal failed");
16270         return SSL_FATAL_ERROR;
16271     }
16272 
16273     rsa->inSet = 1;
16274 
16275     return SSL_SUCCESS;
16276 }
16277 #endif /* NO_RSA */
16278 
16279 
16280 #ifndef NO_DSA
16281 /* return SSL_SUCCESS if success, SSL_FATAL_ERROR if error */
16282 int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* derBuf, int derSz)
16283 {
16284     word32 idx = 0;
16285     int    ret;
16286 
16287     WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
16288 
16289     if (dsa == NULL || dsa->internal == NULL || derBuf == NULL || derSz <= 0) {
16290         WOLFSSL_MSG("Bad function arguments");
16291         return SSL_FATAL_ERROR;
16292     }
16293 
16294     ret = DsaPrivateKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal, derSz);
16295     if (ret < 0) {
16296         WOLFSSL_MSG("DsaPrivateKeyDecode failed");
16297         return SSL_FATAL_ERROR;
16298     }
16299 
16300     if (SetDsaExternal(dsa) != SSL_SUCCESS) {
16301         WOLFSSL_MSG("SetDsaExternal failed");
16302         return SSL_FATAL_ERROR;
16303     }
16304 
16305     dsa->inSet = 1;
16306 
16307     return SSL_SUCCESS;
16308 }
16309 #endif /* NO_DSA */
16310 
16311 #ifdef HAVE_ECC
16312 /* return SSL_SUCCESS if success, SSL_FATAL_ERROR if error */
16313 int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key,
16314                            const unsigned char* derBuf,  int derSz)
16315 {
16316     word32 idx = 0;
16317     int    ret;
16318 
16319     WOLFSSL_ENTER("wolfSSL_EC_KEY_LoadDer");
16320 
16321     if (key == NULL || key->internal == NULL || derBuf == NULL || derSz <= 0) {
16322         WOLFSSL_MSG("Bad function arguments");
16323         return SSL_FATAL_ERROR;
16324     }
16325 
16326     ret = wc_EccPrivateKeyDecode(derBuf, &idx, (ecc_key*)key->internal, derSz);
16327     if (ret < 0) {
16328         WOLFSSL_MSG("wc_EccPrivateKeyDecode failed");
16329         return SSL_FATAL_ERROR;
16330     }
16331 
16332     if (SetECKeyExternal(key) != SSL_SUCCESS) {
16333         WOLFSSL_MSG("SetECKeyExternal failed");
16334         return SSL_FATAL_ERROR;
16335     }
16336 
16337     key->inSet = 1;
16338 
16339     return SSL_SUCCESS;
16340 }
16341 #endif /* HAVE_ECC */
16342 
16343 #endif /* OPENSSL_EXTRA */
16344 
16345 
16346 #ifdef SESSION_CERTS
16347 
16348 
16349 /* Get peer's certificate chain */
16350 WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl)
16351 {
16352     WOLFSSL_ENTER("wolfSSL_get_peer_chain");
16353     if (ssl)
16354         return &ssl->session.chain;
16355 
16356     return 0;
16357 }
16358 
16359 
16360 /* Get peer's certificate chain total count */
16361 int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain)
16362 {
16363     WOLFSSL_ENTER("wolfSSL_get_chain_count");
16364     if (chain)
16365         return chain->count;
16366 
16367     return 0;
16368 }
16369 
16370 
16371 /* Get peer's ASN.1 DER certificate at index (idx) length in bytes */
16372 int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx)
16373 {
16374     WOLFSSL_ENTER("wolfSSL_get_chain_length");
16375     if (chain)
16376         return chain->certs[idx].length;
16377 
16378     return 0;
16379 }
16380 
16381 
16382 /* Get peer's ASN.1 DER certificate at index (idx) */
16383 byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx)
16384 {
16385     WOLFSSL_ENTER("wolfSSL_get_chain_cert");
16386     if (chain)
16387         return chain->certs[idx].buffer;
16388 
16389     return 0;
16390 }
16391 
16392 
16393 /* Get peer's wolfSSL X509 certificate at index (idx) */
16394 WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx)
16395 {
16396     int          ret;
16397     WOLFSSL_X509* x509 = NULL;
16398 #ifdef WOLFSSL_SMALL_STACK
16399     DecodedCert* cert = NULL;
16400 #else
16401     DecodedCert  cert[1];
16402 #endif
16403 
16404     WOLFSSL_ENTER("wolfSSL_get_chain_X509");
16405     if (chain != NULL) {
16406     #ifdef WOLFSSL_SMALL_STACK
16407         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
16408                                                        DYNAMIC_TYPE_TMP_BUFFER);
16409         if (cert != NULL)
16410     #endif
16411         {
16412             InitDecodedCert(cert, chain->certs[idx].buffer,
16413                                   chain->certs[idx].length, NULL);
16414 
16415             if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) != 0)
16416                 WOLFSSL_MSG("Failed to parse cert");
16417             else {
16418                 x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
16419                                                              DYNAMIC_TYPE_X509);
16420                 if (x509 == NULL) {
16421                     WOLFSSL_MSG("Failed alloc X509");
16422                 }
16423                 else {
16424                     InitX509(x509, 1);
16425 
16426                     if ((ret = CopyDecodedToX509(x509, cert)) != 0) {
16427                         WOLFSSL_MSG("Failed to copy decoded");
16428                         XFREE(x509, NULL, DYNAMIC_TYPE_X509);
16429                         x509 = NULL;
16430                     }
16431                 }
16432             }
16433 
16434             FreeDecodedCert(cert);
16435         #ifdef WOLFSSL_SMALL_STACK
16436             XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16437         #endif
16438         }
16439     }
16440 
16441     return x509;
16442 }
16443 
16444 
16445 /* Get peer's PEM certificate at index (idx), output to buffer if inLen big
16446    enough else return error (-1). If buffer is NULL only calculate
16447    outLen. Output length is in *outLen SSL_SUCCESS on ok */
16448 int  wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
16449                                unsigned char* buf, int inLen, int* outLen)
16450 {
16451     const char header[] = "-----BEGIN CERTIFICATE-----\n";
16452     const char footer[] = "-----END CERTIFICATE-----\n";
16453 
16454     int headerLen = sizeof(header) - 1;
16455     int footerLen = sizeof(footer) - 1;
16456     int i;
16457     int err;
16458     word32 szNeeded = 0;
16459 
16460     WOLFSSL_ENTER("wolfSSL_get_chain_cert_pem");
16461     if (!chain || !outLen || idx < 0 || idx >= wolfSSL_get_chain_count(chain))
16462         return BAD_FUNC_ARG;
16463 
16464     /* Null output buffer return size needed in outLen */
16465     if(!buf) {
16466         if(Base64_Encode(chain->certs[idx].buffer, chain->certs[idx].length,
16467                     NULL, &szNeeded) != LENGTH_ONLY_E)
16468             return SSL_FAILURE;
16469         *outLen = szNeeded + headerLen + footerLen;
16470         return LENGTH_ONLY_E;
16471     }
16472 
16473     /* don't even try if inLen too short */
16474     if (inLen < headerLen + footerLen + chain->certs[idx].length)
16475         return BAD_FUNC_ARG;
16476 
16477     /* header */
16478     if (XMEMCPY(buf, header, headerLen) == NULL)
16479         return SSL_FATAL_ERROR;
16480 
16481     i = headerLen;
16482 
16483     /* body */
16484     *outLen = inLen;  /* input to Base64_Encode */
16485     if ( (err = Base64_Encode(chain->certs[idx].buffer,
16486                        chain->certs[idx].length, buf + i, (word32*)outLen)) < 0)
16487         return err;
16488     i += *outLen;
16489 
16490     /* footer */
16491     if ( (i + footerLen) > inLen)
16492         return BAD_FUNC_ARG;
16493     if (XMEMCPY(buf + i, footer, footerLen) == NULL)
16494         return SSL_FATAL_ERROR;
16495     *outLen += headerLen + footerLen;
16496 
16497     return SSL_SUCCESS;
16498 }
16499 
16500 
16501 /* get session ID */
16502 const byte* wolfSSL_get_sessionID(const WOLFSSL_SESSION* session)
16503 {
16504     WOLFSSL_ENTER("wolfSSL_get_sessionID");
16505     if (session)
16506         return session->sessionID;
16507 
16508     return NULL;
16509 }
16510 
16511 
16512 #endif /* SESSION_CERTS */
16513 
16514 #ifdef HAVE_FUZZER
16515 void wolfSSL_SetFuzzerCb(WOLFSSL* ssl, CallbackFuzzer cbf, void* fCtx)
16516 {
16517     if (ssl) {
16518         ssl->fuzzerCb  = cbf;
16519         ssl->fuzzerCtx = fCtx;
16520     }
16521 }
16522 #endif
16523 
16524 #ifndef NO_CERTS
16525 #ifdef  HAVE_PK_CALLBACKS
16526 
16527 #ifdef HAVE_ECC
16528 
16529 void  wolfSSL_CTX_SetEccSignCb(WOLFSSL_CTX* ctx, CallbackEccSign cb)
16530 {
16531     if (ctx)
16532         ctx->EccSignCb = cb;
16533 }
16534 
16535 
16536 void  wolfSSL_SetEccSignCtx(WOLFSSL* ssl, void *ctx)
16537 {
16538     if (ssl)
16539         ssl->EccSignCtx = ctx;
16540 }
16541 
16542 
16543 void* wolfSSL_GetEccSignCtx(WOLFSSL* ssl)
16544 {
16545     if (ssl)
16546         return ssl->EccSignCtx;
16547 
16548     return NULL;
16549 }
16550 
16551 
16552 void  wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX* ctx, CallbackEccVerify cb)
16553 {
16554     if (ctx)
16555         ctx->EccVerifyCb = cb;
16556 }
16557 
16558 
16559 void  wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx)
16560 {
16561     if (ssl)
16562         ssl->EccVerifyCtx = ctx;
16563 }
16564 
16565 
16566 void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl)
16567 {
16568     if (ssl)
16569         return ssl->EccVerifyCtx;
16570 
16571     return NULL;
16572 }
16573 
16574 #endif /* HAVE_ECC */
16575 
16576 #ifndef NO_RSA
16577 
16578 void  wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX* ctx, CallbackRsaSign cb)
16579 {
16580     if (ctx)
16581         ctx->RsaSignCb = cb;
16582 }
16583 
16584 
16585 void  wolfSSL_SetRsaSignCtx(WOLFSSL* ssl, void *ctx)
16586 {
16587     if (ssl)
16588         ssl->RsaSignCtx = ctx;
16589 }
16590 
16591 
16592 void* wolfSSL_GetRsaSignCtx(WOLFSSL* ssl)
16593 {
16594     if (ssl)
16595         return ssl->RsaSignCtx;
16596 
16597     return NULL;
16598 }
16599 
16600 
16601 void  wolfSSL_CTX_SetRsaVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
16602 {
16603     if (ctx)
16604         ctx->RsaVerifyCb = cb;
16605 }
16606 
16607 
16608 void  wolfSSL_SetRsaVerifyCtx(WOLFSSL* ssl, void *ctx)
16609 {
16610     if (ssl)
16611         ssl->RsaVerifyCtx = ctx;
16612 }
16613 
16614 
16615 void* wolfSSL_GetRsaVerifyCtx(WOLFSSL* ssl)
16616 {
16617     if (ssl)
16618         return ssl->RsaVerifyCtx;
16619 
16620     return NULL;
16621 }
16622 
16623 void  wolfSSL_CTX_SetRsaEncCb(WOLFSSL_CTX* ctx, CallbackRsaEnc cb)
16624 {
16625     if (ctx)
16626         ctx->RsaEncCb = cb;
16627 }
16628 
16629 
16630 void  wolfSSL_SetRsaEncCtx(WOLFSSL* ssl, void *ctx)
16631 {
16632     if (ssl)
16633         ssl->RsaEncCtx = ctx;
16634 }
16635 
16636 
16637 void* wolfSSL_GetRsaEncCtx(WOLFSSL* ssl)
16638 {
16639     if (ssl)
16640         return ssl->RsaEncCtx;
16641 
16642     return NULL;
16643 }
16644 
16645 void  wolfSSL_CTX_SetRsaDecCb(WOLFSSL_CTX* ctx, CallbackRsaDec cb)
16646 {
16647     if (ctx)
16648         ctx->RsaDecCb = cb;
16649 }
16650 
16651 
16652 void  wolfSSL_SetRsaDecCtx(WOLFSSL* ssl, void *ctx)
16653 {
16654     if (ssl)
16655         ssl->RsaDecCtx = ctx;
16656 }
16657 
16658 
16659 void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
16660 {
16661     if (ssl)
16662         return ssl->RsaDecCtx;
16663 
16664     return NULL;
16665 }
16666 
16667 
16668 #endif /* NO_RSA */
16669 
16670 #endif /* HAVE_PK_CALLBACKS */
16671 #endif /* NO_CERTS */
16672 
16673 
16674 #ifdef WOLFSSL_HAVE_WOLFSCEP
16675     /* Used by autoconf to see if wolfSCEP is available */
16676     void wolfSSL_wolfSCEP(void) {}
16677 #endif
16678 
16679 
16680 #ifdef WOLFSSL_HAVE_CERT_SERVICE
16681     /* Used by autoconf to see if cert service is available */
16682     void wolfSSL_cert_service(void) {}
16683 #endif
16684 
16685 
16686 #ifdef OPENSSL_EXTRA /*Lighttp compatibility*/
16687 #ifdef HAVE_LIGHTY
16688 
16689     unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n, unsigned char *md)
16690     {
16691         (void) *d; (void) n; (void) *md;
16692         WOLFSSL_ENTER("wolfSSL_SHA1");
16693         WOLFSSL_STUB("wolfssl_SHA1");
16694 
16695         return NULL;
16696     }
16697 
16698     char wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x) {
16699         (void)ctx;
16700         (void)x;
16701         WOLFSSL_ENTER("wolfSSL_CTX_use_certificate");
16702         WOLFSSL_STUB("wolfSSL_CTX_use_certificate");
16703 
16704         return 0;
16705     }
16706 
16707     int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey) {
16708         (void)ctx;
16709         (void)pkey;
16710         WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey");
16711         WOLFSSL_STUB("wolfSSL_CTX_use_PrivateKey");
16712 
16713         return 0;
16714     }
16715 
16716 
16717     int wolfSSL_BIO_read_filename(WOLFSSL_BIO *b, const char *name) {
16718         (void)b;
16719         (void)name;
16720         WOLFSSL_ENTER("wolfSSL_BIO_read_filename");
16721         WOLFSSL_STUB("wolfSSL_BIO_read_filename");
16722 
16723         return 0;
16724     }
16725 
16726     WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_file(void) {
16727         WOLFSSL_ENTER("wolfSSL_BIO_s_file");
16728         WOLFSSL_STUB("wolfSSL_BIO_s_file");
16729 
16730         return NULL;
16731     }
16732 
16733     const char * wolf_OBJ_nid2sn(int n) {
16734         (void)n;
16735         WOLFSSL_ENTER("wolf_OBJ_nid2sn");
16736         WOLFSSL_STUB("wolf_OBJ_nid2sn");
16737 
16738         return 0;
16739     }
16740 
16741     int wolf_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o) {
16742         (void)o;
16743         WOLFSSL_ENTER("wolf_OBJ_obj2nid");
16744         WOLFSSL_STUB("wolf_OBJ_obj2nid");
16745 
16746         return 0;
16747     }
16748 
16749     int wolf_OBJ_sn2nid(const char *sn) {
16750         (void)sn;
16751         WOLFSSL_ENTER("wolf_OBJ_osn2nid");
16752         WOLFSSL_STUB("wolf_OBJ_osn2nid");
16753 
16754         return 0;
16755     }
16756 
16757 
16758     WOLFSSL_X509 *PEM_read_bio_WOLFSSL_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u) {
16759         (void)bp;
16760         (void)x;
16761         (void)cb;
16762         (void)u;
16763         WOLFSSL_ENTER("PEM_read_bio_WOLFSSL_X509");
16764         WOLFSSL_STUB("PEM_read_bio_WOLFSSL_X509");
16765 
16766         return NULL;
16767     }
16768 
16769     void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx, int depth) {
16770         (void)ctx;
16771         (void)depth;
16772         WOLFSSL_ENTER("wolfSSL_CTX_set_verify_depth");
16773         WOLFSSL_STUB("wolfSSL_CTX_set_verify_depth");
16774 
16775     }
16776 
16777     void* wolfSSL_get_app_data( const WOLFSSL *ssl)
16778     {
16779         /* checkout exdata stuff... */
16780         (void)ssl;
16781         WOLFSSL_ENTER("wolfSSL_get_app_data");
16782         WOLFSSL_STUB("wolfSSL_get_app_data");
16783 
16784         return 0;
16785     }
16786 
16787     void wolfSSL_set_app_data(WOLFSSL *ssl, void *arg) {
16788         (void)ssl;
16789         (void)arg;
16790         WOLFSSL_ENTER("wolfSSL_set_app_data");
16791         WOLFSSL_STUB("wolfSSL_set_app_data");
16792     }
16793 
16794     WOLFSSL_ASN1_OBJECT * wolfSSL_X509_NAME_ENTRY_get_object(WOLFSSL_X509_NAME_ENTRY *ne) {
16795         (void)ne;
16796         WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_object");
16797         WOLFSSL_STUB("wolfSSL_X509_NAME_ENTRY_get_object");
16798 
16799         return NULL;
16800     }
16801 
16802     WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(WOLFSSL_X509_NAME *name, int loc) {
16803         (void)name;
16804         (void)loc;
16805         WOLFSSL_ENTER("wolfSSL_X509_NAME_get_entry");
16806         WOLFSSL_STUB("wolfSSL_X509_NAME_get_entry");
16807 
16808         return NULL;
16809     }
16810 
16811     void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name){
16812         FreeX509Name(name);
16813         WOLFSSL_ENTER("wolfSSL_X509_NAME_free");
16814         WOLFSSL_STUB("wolfSSL_X509_NAME_free");
16815     }
16816 
16817     void wolfSSL_sk_X509_NAME_pop_free(STACK_OF(WOLFSSL_X509_NAME)* sk, void f (WOLFSSL_X509_NAME*)){
16818         (void) sk;
16819         (void) f;
16820         WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_pop_free");
16821         WOLFSSL_STUB("wolfSSL_sk_X509_NAME_pop_free");
16822     }
16823 
16824     int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key){
16825         (void) x509;
16826         (void) key;
16827         WOLFSSL_ENTER("wolfSSL_X509_check_private_key");
16828         WOLFSSL_STUB("wolfSSL_X509_check_private_key");
16829 
16830         return SSL_SUCCESS;
16831     }
16832 
16833     STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list( STACK_OF(WOLFSSL_X509_NAME) *sk ){
16834         (void) sk;
16835         WOLFSSL_ENTER("wolfSSL_dup_CA_list");
16836         WOLFSSL_STUB("wolfSSL_dup_CA_list");
16837 
16838         return NULL;
16839     }
16840 
16841 #endif
16842 #endif
16843 
16844 
16845 #ifdef OPENSSL_EXTRA
16846 void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx)
16847 {
16848     WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
16849     #ifdef HAVE_STUNNEL
16850     if(ctx != NULL && idx < MAX_EX_DATA && idx >= 0) {
16851         return ctx->ex_data[idx];
16852     }
16853     #else
16854     (void)ctx;
16855     (void)idx;
16856     #endif
16857     return NULL;
16858 }
16859 
16860 
16861 int wolfSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b,
16862                                 void* c)
16863 {
16864     WOLFSSL_ENTER("wolfSSL_CTX_get_ex_new_index");
16865     (void)idx;
16866     (void)arg;
16867     (void)a;
16868     (void)b;
16869     (void)c;
16870     return 0;
16871 }
16872 
16873 
16874 int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data)
16875 {
16876     WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data");
16877     #ifdef HAVE_STUNNEL
16878     if (ctx != NULL && idx < MAX_EX_DATA)
16879     {
16880         ctx->ex_data[idx] = data;
16881         return SSL_SUCCESS;
16882     }
16883     #else
16884     (void)ctx;
16885     (void)idx;
16886     (void)data;
16887     #endif
16888     return SSL_FAILURE;
16889 }
16890 
16891 
16892 int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data)
16893 {
16894     WOLFSSL_ENTER("wolfSSL_set_ex_data");
16895 #if defined(FORTRESS) || defined(HAVE_STUNNEL)
16896     if (ssl != NULL && idx < MAX_EX_DATA)
16897     {
16898         ssl->ex_data[idx] = data;
16899         return SSL_SUCCESS;
16900     }
16901 #else
16902     (void)ssl;
16903     (void)idx;
16904     (void)data;
16905 #endif
16906     return SSL_FAILURE;
16907 }
16908 
16909 
16910 int wolfSSL_get_ex_new_index(long idx, void* data, void* cb1, void* cb2,
16911                          void* cb3)
16912 {
16913     WOLFSSL_ENTER("wolfSSL_get_ex_new_index");
16914     (void)idx;
16915     (void)data;
16916     (void)cb1;
16917     (void)cb2;
16918     (void)cb3;
16919     return 0;
16920 }
16921 
16922 
16923 void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx)
16924 {
16925     WOLFSSL_ENTER("wolfSSL_get_ex_data");
16926 #if defined(FORTRESS) || defined(HAVE_STUNNEL)
16927     if (ssl != NULL && idx < MAX_EX_DATA && idx >= 0)
16928         return ssl->ex_data[idx];
16929 #else
16930     (void)ssl;
16931     (void)idx;
16932 #endif
16933     return 0;
16934 }
16935 #endif /* OPENSSL_EXTRA */
16936 
16937 
16938 #if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL)
16939 char * wolf_OBJ_nid2ln(int n) {
16940     (void)n;
16941     WOLFSSL_ENTER("wolf_OBJ_nid2ln");
16942     WOLFSSL_STUB("wolf_OBJ_nid2ln");
16943 
16944     return NULL;
16945 }
16946 
16947 int wolf_OBJ_txt2nid(const char* s) {
16948     (void)s;
16949     WOLFSSL_ENTER("wolf_OBJ_txt2nid");
16950     WOLFSSL_STUB("wolf_OBJ_txt2nid");
16951 
16952     return 0;
16953 }
16954 
16955 
16956 WOLFSSL_BIO *wolfSSL_BIO_new_file(const char *filename, const char *mode) {
16957     (void)filename;
16958     (void)mode;
16959     WOLFSSL_ENTER("wolfSSL_BIO_new_file");
16960     WOLFSSL_STUB("wolfSSL_BIO_new_file");
16961 
16962     return NULL;
16963 }
16964 
16965 
16966 WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bp, WOLFSSL_DH **x, pem_password_cb *cb, void *u)
16967 {
16968     (void) bp;
16969     (void) x;
16970     (void) cb;
16971     (void) u;
16972 
16973     WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DHparams");
16974     WOLFSSL_STUB("wolfSSL_PEM_read_bio_DHparams");
16975 
16976     return NULL;
16977 }
16978 
16979 int PEM_write_bio_WOLFSSL_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 *x) {
16980     (void)bp;
16981     (void)x;
16982     WOLFSSL_ENTER("PEM_write_bio_WOLFSSL_X509");
16983     WOLFSSL_STUB("PEM_write_bio_WOLFSSL_X509");
16984 
16985     return 0;
16986 }
16987 
16988 
16989 #ifndef NO_DH
16990 /* Intialize ctx->dh with dh's params. Return SSL_SUCCESS on ok */
16991 long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL_DH* dh)
16992 {
16993     int pSz, gSz;
16994     byte *p, *g;
16995     int ret=0;
16996 
16997     WOLFSSL_ENTER("wolfSSL_CTX_set_tmp_dh");
16998 
16999     if(!ctx || !dh)
17000         return BAD_FUNC_ARG;
17001 
17002     /* Get needed size for p and g */
17003     pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
17004     gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
17005 
17006     if(pSz <= 0 || gSz <= 0)
17007         return SSL_FATAL_ERROR;
17008 
17009     p = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_DH);
17010     if(!p)
17011         return MEMORY_E;
17012 
17013     g = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_DH);
17014     if(!g) {
17015         XFREE(p, ctx->heap, DYNAMIC_TYPE_DH);
17016         return MEMORY_E;
17017     }
17018 
17019     pSz = wolfSSL_BN_bn2bin(dh->p, p);
17020     gSz = wolfSSL_BN_bn2bin(dh->g, g);
17021 
17022     if(pSz >= 0 && gSz >= 0) /* Conversion successful */
17023         ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
17024 
17025     XFREE(p, ctx->heap, DYNAMIC_TYPE_DH);
17026     XFREE(g, ctx->heap, DYNAMIC_TYPE_DH);
17027 
17028     return pSz > 0 && gSz > 0 ? ret : SSL_FATAL_ERROR;
17029 }
17030 #endif /* NO_DH */
17031 #endif /* HAVE_LIGHTY || HAVE_STUNNEL */
17032 
17033 
17034 /* stunnel compatibility functions*/
17035 #if defined(OPENSSL_EXTRA) && defined(HAVE_STUNNEL)
17036 void WOLFSSL_ERR_remove_thread_state(void* pid)
17037 {
17038     (void) pid;
17039     return;
17040 }
17041 
17042 
17043 int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION* session, int idx, void* data)
17044 {
17045     WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data");
17046     if(session != NULL && idx < MAX_EX_DATA) {
17047         session->ex_data[idx] = data;
17048         return SSL_SUCCESS;
17049     }
17050     return SSL_FAILURE;
17051 }
17052 
17053 
17054 int wolfSSL_SESSION_get_ex_new_index(long idx, void* data, void* cb1,
17055        void* cb2, CRYPTO_free_func* cb3)
17056 {
17057     WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_new_index");
17058     (void)idx;
17059     (void)cb1;
17060     (void)cb2;
17061     (void)cb3;
17062     if(XSTRNCMP((const char*)data, "redirect index", 14) == 0) {
17063         return 0;
17064     }
17065     else if(XSTRNCMP((const char*)data, "addr index", 10) == 0) {
17066         return 1;
17067     }
17068     return SSL_FAILURE;
17069 }
17070 
17071 
17072 void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION* session, int idx)
17073 {
17074     WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_data");
17075     if (session != NULL && idx < MAX_EX_DATA && idx >= 0)
17076         return session->ex_data[idx];
17077     return NULL;
17078 }
17079 
17080 
17081 int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
17082                                 void *(*r) (void *, size_t, const char *,
17083                                             int), void (*f) (void *))
17084 {
17085     (void) m;
17086     (void) r;
17087     (void) f;
17088     WOLFSSL_ENTER("wolfSSL_CRYPTO_set_mem_ex_functions");
17089     WOLFSSL_STUB("wolfSSL_CRYPTO_set_mem_ex_functions");
17090 
17091     return SSL_FAILURE;
17092 }
17093 
17094 
17095 WOLFSSL_DH *wolfSSL_DH_generate_parameters(int prime_len, int generator,
17096                            void (*callback) (int, int, void *), void *cb_arg)
17097 {
17098     (void)prime_len;
17099     (void)generator;
17100     (void)callback;
17101     (void)cb_arg;
17102     WOLFSSL_ENTER("wolfSSL_DH_generate_parameters");
17103     WOLFSSL_STUB("wolfSSL_DH_generate_parameters");
17104 
17105     return NULL;
17106 }
17107 
17108 int wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH* dh, int prime_len, int generator,
17109                            void (*callback) (int, int, void *))
17110 {
17111     (void)prime_len;
17112     (void)generator;
17113     (void)callback;
17114     (void)dh;
17115     WOLFSSL_ENTER("wolfSSL_DH_generate_parameters_ex");
17116     WOLFSSL_STUB("wolfSSL_DH_generate_parameters_ex");
17117 
17118     return -1;
17119 }
17120 
17121 
17122 void wolfSSL_ERR_load_crypto_strings(void)
17123 {
17124     WOLFSSL_ENTER("wolfSSL_ERR_load_crypto_strings");
17125     WOLFSSL_ENTER("wolfSSL_ERR_load_crypto_strings");
17126     return;
17127 }
17128 
17129 
17130 unsigned long wolfSSL_ERR_peek_last_error(void)
17131 {
17132     unsigned long l = 0UL;
17133     WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
17134     WOLFSSL_STUB("wolfSSL_ERR_peek_last_error");
17135 
17136     return l;
17137 }
17138 
17139 
17140 int wolfSSL_FIPS_mode(void)
17141 {
17142     WOLFSSL_ENTER("wolfSSL_FIPS_mode");
17143     WOLFSSL_STUB("wolfSSL_FIPS_mode");
17144 
17145     return SSL_FAILURE;
17146 }
17147 
17148 int wolfSSL_FIPS_mode_set(int r)
17149 {
17150     (void)r;
17151     WOLFSSL_ENTER("wolfSSL_FIPS_mode_set");
17152     WOLFSSL_STUB("wolfSSL_FIPS_mode_set");
17153 
17154     return SSL_FAILURE;
17155 }
17156 
17157 
17158 int wolfSSL_RAND_set_rand_method(const void *meth)
17159 {
17160     (void) meth;
17161     WOLFSSL_ENTER("wolfSSL_RAND_set_rand_method");
17162     WOLFSSL_STUB("wolfSSL_RAND_set_rand_method");
17163 
17164     return SSL_FAILURE;
17165 }
17166 
17167 
17168 int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits)
17169 {
17170     int ret = SSL_FAILURE;
17171     WOLFSSL_ENTER("wolfSSL_CIPHER_get_bits");
17172     if(c != NULL && c->ssl != NULL) {
17173         ret = 8 * c->ssl->specs.key_size;
17174         if(alg_bits != NULL) {
17175             *alg_bits = ret;
17176         }
17177     }
17178     return ret;
17179 }
17180 
17181 
17182 int wolfSSL_sk_X509_NAME_num(const STACK_OF(WOLFSSL_X509_NAME) *s)
17183 {
17184     (void) s;
17185     WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_num");
17186     WOLFSSL_STUB("wolfSSL_sk_X509_NAME_num");
17187 
17188     return SSL_FAILURE;
17189 }
17190 
17191 
17192 int wolfSSL_sk_X509_num(const STACK_OF(WOLFSSL_X509) *s)
17193 {
17194     (void) s;
17195     WOLFSSL_ENTER("wolfSSL_sk_X509_num");
17196     WOLFSSL_STUB("wolfSSL_sk_X509_num");
17197 
17198     return SSL_FAILURE;
17199 }
17200 
17201 
17202 int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* nm,
17203                 int indent, unsigned long flags)
17204 {
17205     (void)bio;
17206     (void)nm;
17207     (void)indent;
17208     (void)flags;
17209     WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex");
17210     WOLFSSL_STUB("wolfSSL_X509_NAME_print_ex");
17211 
17212     return SSL_FAILURE;
17213 }
17214 
17215 
17216 WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr(const WOLFSSL_X509* x)
17217 {
17218     (void)x;
17219     WOLFSSL_ENTER("wolfSSL_X509_get0_pubkey_bitstr");
17220     WOLFSSL_STUB("wolfSSL_X509_get0_pubkey_bitstr");
17221 
17222     return NULL;
17223 }
17224 
17225 
17226 int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
17227 {
17228     (void)ctx;
17229     (void)session;
17230     WOLFSSL_ENTER("wolfSSL_CTX_add_session");
17231     WOLFSSL_STUB("wolfSSL_CTX_add_session");
17232 
17233     return SSL_SUCCESS;
17234 }
17235 
17236 
17237 int wolfSSL_get_state(const WOLFSSL* ssl)
17238 {
17239     (void)ssl;
17240     WOLFSSL_ENTER("wolfSSL_get_state");
17241     WOLFSSL_STUB("wolfSSL_get_state");
17242 
17243     return SSL_FAILURE;
17244 }
17245 
17246 
17247 void* wolfSSL_sk_X509_NAME_value(STACK_OF(WOLFSSL_X509_NAME)* sk, int i)
17248 {
17249     (void)sk;
17250     (void)i;
17251     WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_value");
17252     WOLFSSL_STUB("wolfSSL_sk_X509_NAME_value");
17253 
17254     return NULL;
17255 }
17256 
17257 
17258 void* wolfSSL_sk_X509_value(STACK_OF(WOLFSSL_X509)* sk, int i)
17259 {
17260     (void)sk;
17261     (void)i;
17262     WOLFSSL_ENTER("wolfSSL_sk_X509_value");
17263     WOLFSSL_STUB("wolfSSL_sk_X509_value");
17264 
17265     return NULL;
17266 }
17267 
17268 
17269 int wolfSSL_version(WOLFSSL* ssl)
17270 {
17271     WOLFSSL_ENTER("wolfSSL_version");
17272     if (ssl->version.major == SSLv3_MAJOR) {
17273         switch (ssl->version.minor) {
17274             case SSLv3_MINOR :
17275                 return SSL3_VERSION;
17276             case TLSv1_MINOR :
17277             case TLSv1_1_MINOR :
17278             case TLSv1_2_MINOR :
17279                 return TLS1_VERSION;
17280             default:
17281                 return SSL_FAILURE;
17282         }
17283     }
17284     else if (ssl->version.major == DTLS_MAJOR) {
17285         switch (ssl->version.minor) {
17286             case DTLS_MINOR :
17287             case DTLSv1_2_MINOR :
17288                 return DTLS1_VERSION;
17289             default:
17290                 return SSL_FAILURE;
17291         }
17292     }
17293     return SSL_FAILURE;
17294 }
17295 
17296 
17297 STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL* ssl)
17298 {
17299     (void)ssl;
17300     WOLFSSL_ENTER("wolfSSL_get_peer_cert_chain");
17301     WOLFSSL_STUB("wolfSSL_get_peer_cert_chain");
17302 
17303     return NULL;
17304 }
17305 
17306 
17307 long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx)
17308 {
17309     (void)ctx;
17310     WOLFSSL_ENTER("wolfSSL_CTX_get_options");
17311     WOLFSSL_STUB("wolfSSL_CTX_get_options");
17312 
17313     return 0;
17314 }
17315 
17316 
17317 WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl)
17318 {
17319     WOLFSSL_ENTER("wolfSSL_get_SSL_CTX");
17320     return ssl->ctx;
17321 }
17322 
17323 int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME* name)
17324 {
17325     WOLFSSL_ENTER("wolfSSL_X509_NAME_get_sz");
17326     if(!name)
17327         return -1;
17328     return name->sz;
17329 }
17330 
17331 
17332 const byte* wolfSSL_SESSION_get_id(WOLFSSL_SESSION* sess, unsigned int* idLen)
17333 {
17334     WOLFSSL_ENTER("wolfSSL_SESSION_get_id");
17335     WOLFSSL_STUB("wolfSSL_SESSION_get_id");
17336     if(!sess || !idLen) {
17337         WOLFSSL_MSG("Bad func args. Please provide idLen");
17338         return NULL;
17339     }
17340     *idLen = sess->sessionIDSz;
17341     return sess->sessionID;
17342 }
17343 
17344 #ifdef HAVE_SNI
17345 int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name)
17346 {
17347     int ret;
17348     WOLFSSL_ENTER("wolfSSL_set_tlsext_host_name");
17349     ret = wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME,
17350             host_name, XSTRLEN(host_name));
17351     WOLFSSL_LEAVE("wolfSSL_set_tlsext_host_name", ret);
17352     return ret;
17353 }
17354 
17355 
17356 const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type)
17357 {
17358     void * serverName = NULL;
17359     if (ssl == NULL)
17360         return NULL;
17361     TLSX_SNI_GetRequest(ssl->extensions, type, &serverName);
17362     return (const char *)serverName;
17363 }
17364 #endif /* HAVE_SNI */
17365 
17366 
17367 WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
17368 {
17369     if (ssl && ctx && SetSSL_CTX(ssl, ctx) == SSL_SUCCESS)
17370         return ssl->ctx;
17371     return NULL;
17372 }
17373 
17374 
17375 VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX* ctx)
17376 {
17377     WOLFSSL_ENTER("wolfSSL_CTX_get_verify_callback");
17378     if(ctx)
17379         return ctx->verifyCallback;
17380     return NULL;
17381 }
17382 
17383 
17384 void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
17385 {
17386     WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
17387     if (ctx)
17388         ctx->sniRecvCb = cb;
17389 }
17390 
17391 
17392 void wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
17393 {
17394     WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
17395     if (ctx)
17396         ctx->sniRecvCbArg = arg;
17397 }
17398 
17399 
17400 long wolfSSL_CTX_clear_options(WOLFSSL_CTX* ctx, long opt)
17401 {
17402     WOLFSSL_ENTER("SSL_CTX_clear_options");
17403     WOLFSSL_STUB("SSL_CTX_clear_options");
17404     (void)ctx;
17405     (void)opt;
17406     return opt;
17407 }
17408 
17409 void wolfSSL_THREADID_set_callback(void(*threadid_func)(void*))
17410 {
17411     WOLFSSL_ENTER("wolfSSL_THREADID_set_callback");
17412     WOLFSSL_STUB("wolfSSL_THREADID_set_callback");
17413     (void)threadid_func;
17414     return;
17415 }
17416 
17417 void wolfSSL_THREADID_set_numeric(void* id, unsigned long val)
17418 {
17419     WOLFSSL_ENTER("wolfSSL_THREADID_set_numeric");
17420     WOLFSSL_STUB("wolfSSL_THREADID_set_numeric");
17421     (void)id;
17422     (void)val;
17423     return;
17424 }
17425 
17426 
17427 WOLFSSL_X509* wolfSSL_X509_STORE_get1_certs(WOLFSSL_X509_STORE_CTX* ctx,
17428                                                 WOLFSSL_X509_NAME* name)
17429 {
17430     WOLFSSL_ENTER("wolfSSL_X509_STORE_get1_certs");
17431     WOLFSSL_STUB("wolfSSL_X509_STORE_get1_certs");
17432     (void)ctx;
17433     (void)name;
17434     return NULL;
17435 }
17436 
17437 void wolfSSL_sk_X509_pop_free(STACK_OF(WOLFSSL_X509)* sk, void f (WOLFSSL_X509*)){
17438     (void) sk;
17439     (void) f;
17440     WOLFSSL_ENTER("wolfSSL_sk_X509_pop_free");
17441     WOLFSSL_STUB("wolfSSL_sk_X509_pop_free");
17442 }
17443 
17444 #endif /* OPENSSL_EXTRA and HAVE_STUNNEL */
17445 
17446 
17447 #if (defined(OPENSSL_EXTRA) && defined(HAVE_STUNNEL)) \
17448     || defined(WOLFSSL_MYSQL_COMPATIBLE)
17449 int wolfSSL_CTX_get_verify_mode(WOLFSSL_CTX* ctx)
17450 {
17451     int mode = 0;
17452     WOLFSSL_ENTER("wolfSSL_CTX_get_verify_mode");
17453 
17454     if(!ctx)
17455         return SSL_FATAL_ERROR;
17456 
17457     if (ctx->verifyPeer)
17458         mode |= SSL_VERIFY_PEER;
17459     else if (ctx->verifyNone)
17460         mode |= SSL_VERIFY_NONE;
17461 
17462     if (ctx->failNoCert)
17463         mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
17464 
17465     if (ctx->failNoCertxPSK)
17466         mode |= SSL_VERIFY_FAIL_EXCEPT_PSK;
17467 
17468     WOLFSSL_LEAVE("wolfSSL_CTX_get_verify_mode", mode);
17469     return mode;
17470 }
17471 #endif
17472 
17473 #if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE25519)
17474 /* return 1 if success, 0 if error
17475  * output keys are little endian format
17476  */
17477 int wolfSSL_EC25519_generate_key(unsigned char *priv, unsigned int *privSz,
17478                                  unsigned char *pub, unsigned int *pubSz)
17479 {
17480 #ifndef WOLFSSL_KEY_GEN
17481     WOLFSSL_MSG("No Key Gen built in");
17482     (void) priv;
17483     (void) privSz;
17484     (void) pub;
17485     (void) pubSz;
17486     return SSL_FAILURE;
17487 #else /* WOLFSSL_KEY_GEN */
17488     int ret = SSL_FAILURE;
17489     int initTmpRng = 0;
17490     WC_RNG *rng = NULL;
17491 #ifdef WOLFSSL_SMALL_STACK
17492     WC_RNG *tmpRNG = NULL;
17493 #else
17494     WC_RNG tmpRNG[1];
17495 #endif
17496 
17497     WOLFSSL_ENTER("wolfSSL_EC25519_generate_key");
17498 
17499     if (priv == NULL || privSz == NULL || *privSz < CURVE25519_KEYSIZE ||
17500         pub == NULL || pubSz == NULL || *pubSz < CURVE25519_KEYSIZE) {
17501         WOLFSSL_MSG("Bad arguments");
17502         return SSL_FAILURE;
17503     }
17504 
17505 #ifdef WOLFSSL_SMALL_STACK
17506     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
17507     if (tmpRNG == NULL)
17508         return SSL_FAILURE;
17509 #endif
17510     if (wc_InitRng(tmpRNG) == 0) {
17511         rng = tmpRNG;
17512         initTmpRng = 1;
17513     }
17514     else {
17515         WOLFSSL_MSG("Bad RNG Init, trying global");
17516         if (initGlobalRNG == 0)
17517             WOLFSSL_MSG("Global RNG no Init");
17518         else
17519             rng = &globalRNG;
17520     }
17521 
17522     if (rng) {
17523         curve25519_key key;
17524 
17525         if (wc_curve25519_init(&key) != MP_OKAY)
17526             WOLFSSL_MSG("wc_curve25519_init failed");
17527         else if (wc_curve25519_make_key(rng, CURVE25519_KEYSIZE, &key)!=MP_OKAY)
17528             WOLFSSL_MSG("wc_curve25519_make_key failed");
17529         /* export key pair */
17530         else if (wc_curve25519_export_key_raw_ex(&key, priv, privSz, pub,
17531                                                  pubSz, EC25519_LITTLE_ENDIAN)
17532                  != MP_OKAY)
17533             WOLFSSL_MSG("wc_curve25519_export_key_raw_ex failed");
17534         else
17535             ret = SSL_SUCCESS;
17536 
17537         wc_curve25519_free(&key);
17538     }
17539 
17540     if (initTmpRng)
17541         wc_FreeRng(tmpRNG);
17542 
17543 #ifdef WOLFSSL_SMALL_STACK
17544     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17545 #endif
17546 
17547     return ret;
17548 #endif /* WOLFSSL_KEY_GEN */
17549 }
17550 
17551 /* return 1 if success, 0 if error
17552  * input and output keys are little endian format
17553  */
17554 int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz,
17555                                const unsigned char *priv, unsigned int privSz,
17556                                const unsigned char *pub, unsigned int pubSz)
17557 {
17558 #ifndef WOLFSSL_KEY_GEN
17559     WOLFSSL_MSG("No Key Gen built in");
17560     (void) shared;
17561     (void) sharedSz;
17562     (void) priv;
17563     (void) privSz;
17564     (void) pub;
17565     (void) pubSz;
17566     return SSL_FAILURE;
17567 #else /* WOLFSSL_KEY_GEN */
17568     int ret = SSL_FAILURE;
17569     curve25519_key privkey, pubkey;
17570 
17571     WOLFSSL_ENTER("wolfSSL_EC25519_shared_key");
17572 
17573     if (shared == NULL || sharedSz == NULL || *sharedSz < CURVE25519_KEYSIZE ||
17574         priv == NULL || privSz < CURVE25519_KEYSIZE ||
17575         pub == NULL || pubSz < CURVE25519_KEYSIZE) {
17576         WOLFSSL_MSG("Bad arguments");
17577         return SSL_FAILURE;
17578     }
17579 
17580     /* import private key */
17581     if (wc_curve25519_init(&privkey) != MP_OKAY) {
17582         WOLFSSL_MSG("wc_curve25519_init privkey failed");
17583         return ret;
17584     }
17585     if (wc_curve25519_import_private_ex(priv, privSz, &privkey,
17586                                         EC25519_LITTLE_ENDIAN) != MP_OKAY) {
17587         WOLFSSL_MSG("wc_curve25519_import_private_ex failed");
17588         wc_curve25519_free(&privkey);
17589         return ret;
17590     }
17591 
17592     /* import public key */
17593     if (wc_curve25519_init(&pubkey) != MP_OKAY) {
17594         WOLFSSL_MSG("wc_curve25519_init pubkey failed");
17595         wc_curve25519_free(&privkey);
17596         return ret;
17597     }
17598     if (wc_curve25519_import_public_ex(pub, pubSz, &pubkey,
17599                                        EC25519_LITTLE_ENDIAN) != MP_OKAY) {
17600         WOLFSSL_MSG("wc_curve25519_import_public_ex failed");
17601         wc_curve25519_free(&privkey);
17602         wc_curve25519_free(&pubkey);
17603         return ret;
17604     }
17605 
17606     if (wc_curve25519_shared_secret_ex(&privkey, &pubkey,
17607                                        shared, sharedSz,
17608                                        EC25519_LITTLE_ENDIAN) != MP_OKAY)
17609         WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
17610     else
17611         ret = SSL_SUCCESS;
17612 
17613     wc_curve25519_free(&privkey);
17614     wc_curve25519_free(&pubkey);
17615 
17616     return ret;
17617 #endif /* WOLFSSL_KEY_GEN */
17618 }
17619 #endif /* OPENSSL_EXTRA && HAVE_CURVE25519 */
17620 
17621 #if defined(OPENSSL_EXTRA) && defined(HAVE_ED25519)
17622 /* return 1 if success, 0 if error
17623  * output keys are little endian format
17624  */
17625 int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz,
17626                                  unsigned char *pub, unsigned int *pubSz)
17627 {
17628 #ifndef WOLFSSL_KEY_GEN
17629     WOLFSSL_MSG("No Key Gen built in");
17630     (void) priv;
17631     (void) privSz;
17632     (void) pub;
17633     (void) pubSz;
17634     return SSL_FAILURE;
17635 #else /* WOLFSSL_KEY_GEN */
17636     int ret = SSL_FAILURE;
17637     int initTmpRng = 0;
17638     WC_RNG *rng = NULL;
17639 #ifdef WOLFSSL_SMALL_STACK
17640     WC_RNG *tmpRNG = NULL;
17641 #else
17642     WC_RNG tmpRNG[1];
17643 #endif
17644 
17645     WOLFSSL_ENTER("wolfSSL_ED25519_generate_key");
17646 
17647     if (priv == NULL || privSz == NULL || *privSz < ED25519_PRV_KEY_SIZE ||
17648         pub == NULL || pubSz == NULL || *pubSz < ED25519_PUB_KEY_SIZE) {
17649         WOLFSSL_MSG("Bad arguments");
17650         return SSL_FAILURE;
17651     }
17652 
17653 #ifdef WOLFSSL_SMALL_STACK
17654     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
17655     if (tmpRNG == NULL)
17656         return SSL_FATAL_ERROR;
17657 #endif
17658     if (wc_InitRng(tmpRNG) == 0) {
17659         rng = tmpRNG;
17660         initTmpRng = 1;
17661     }
17662     else {
17663         WOLFSSL_MSG("Bad RNG Init, trying global");
17664         if (initGlobalRNG == 0)
17665             WOLFSSL_MSG("Global RNG no Init");
17666         else
17667             rng = &globalRNG;
17668     }
17669 
17670     if (rng) {
17671         ed25519_key key;
17672 
17673         if (wc_ed25519_init(&key) != MP_OKAY)
17674             WOLFSSL_MSG("wc_ed25519_init failed");
17675         else if (wc_ed25519_make_key(rng, ED25519_KEY_SIZE, &key)!=MP_OKAY)
17676             WOLFSSL_MSG("wc_ed25519_make_key failed");
17677         /* export private key */
17678         else if (wc_ed25519_export_key(&key, priv, privSz, pub, pubSz)!=MP_OKAY)
17679             WOLFSSL_MSG("wc_ed25519_export_key failed");
17680         else
17681             ret = SSL_SUCCESS;
17682 
17683         wc_ed25519_free(&key);
17684     }
17685 
17686     if (initTmpRng)
17687         wc_FreeRng(tmpRNG);
17688 
17689 #ifdef WOLFSSL_SMALL_STACK
17690     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17691 #endif
17692 
17693     return ret;
17694 #endif /* WOLFSSL_KEY_GEN */
17695 }
17696 
17697 /* return 1 if success, 0 if error
17698  * input and output keys are little endian format
17699  * priv is a buffer containing private and public part of key
17700  */
17701 int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
17702                          const unsigned char *priv, unsigned int privSz,
17703                          unsigned char *sig, unsigned int *sigSz)
17704 {
17705 #ifndef WOLFSSL_KEY_GEN
17706     WOLFSSL_MSG("No Key Gen built in");
17707     (void) msg;
17708     (void) msgSz;
17709     (void) priv;
17710     (void) privSz;
17711     (void) sig;
17712     (void) sigSz;
17713     return SSL_FAILURE;
17714 #else /* WOLFSSL_KEY_GEN */
17715     ed25519_key key;
17716     int ret = SSL_FAILURE;
17717 
17718     WOLFSSL_ENTER("wolfSSL_ED25519_sign");
17719 
17720     if (priv == NULL || privSz != ED25519_PRV_KEY_SIZE ||
17721         msg == NULL || sig == NULL || *sigSz < ED25519_SIG_SIZE) {
17722         WOLFSSL_MSG("Bad arguments");
17723         return SSL_FAILURE;
17724     }
17725 
17726     /* import key */
17727     if (wc_ed25519_init(&key) != MP_OKAY) {
17728         WOLFSSL_MSG("wc_curve25519_init failed");
17729         return ret;
17730     }
17731     if (wc_ed25519_import_private_key(priv, privSz/2,
17732                                       priv+(privSz/2), ED25519_PUB_KEY_SIZE,
17733                                       &key) != MP_OKAY){
17734         WOLFSSL_MSG("wc_ed25519_import_private failed");
17735         wc_ed25519_free(&key);
17736         return ret;
17737     }
17738 
17739     if (wc_ed25519_sign_msg(msg, msgSz, sig, sigSz, &key) != MP_OKAY)
17740         WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
17741     else
17742         ret = SSL_SUCCESS;
17743 
17744     wc_ed25519_free(&key);
17745 
17746     return ret;
17747 #endif /* WOLFSSL_KEY_GEN */
17748 }
17749 
17750 /* return 1 if success, 0 if error
17751  * input and output keys are little endian format
17752  * pub is a buffer containing public part of key
17753  */
17754 int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
17755                            const unsigned char *pub, unsigned int pubSz,
17756                            const unsigned char *sig, unsigned int sigSz)
17757 {
17758 #ifndef WOLFSSL_KEY_GEN
17759     WOLFSSL_MSG("No Key Gen built in");
17760     (void) msg;
17761     (void) msgSz;
17762     (void) pub;
17763     (void) pubSz;
17764     (void) sig;
17765     (void) sigSz;
17766     return SSL_FAILURE;
17767 #else /* WOLFSSL_KEY_GEN */
17768     ed25519_key key;
17769     int ret = SSL_FAILURE, check = 0;
17770 
17771     WOLFSSL_ENTER("wolfSSL_ED25519_verify");
17772 
17773     if (pub == NULL || pubSz != ED25519_PUB_KEY_SIZE ||
17774         msg == NULL || sig == NULL || sigSz != ED25519_SIG_SIZE) {
17775         WOLFSSL_MSG("Bad arguments");
17776         return SSL_FAILURE;
17777     }
17778 
17779     /* import key */
17780     if (wc_ed25519_init(&key) != MP_OKAY) {
17781         WOLFSSL_MSG("wc_curve25519_init failed");
17782         return ret;
17783     }
17784     if (wc_ed25519_import_public(pub, pubSz, &key) != MP_OKAY){
17785         WOLFSSL_MSG("wc_ed25519_import_public failed");
17786         wc_ed25519_free(&key);
17787         return ret;
17788     }
17789 
17790     if ((ret = wc_ed25519_verify_msg((byte*)sig, sigSz, msg, msgSz,
17791                                      &check, &key)) != MP_OKAY) {
17792         WOLFSSL_MSG("wc_ed25519_verify_msg failed");
17793     }
17794     else if (!check)
17795         WOLFSSL_MSG("wc_ed25519_verify_msg failed (signature invalid)");
17796     else
17797         ret = SSL_SUCCESS;
17798 
17799     wc_ed25519_free(&key);
17800 
17801     return ret;
17802 #endif /* WOLFSSL_KEY_GEN */
17803 }
17804 
17805 #endif /* OPENSSL_EXTRA && HAVE_ED25519 */
17806 
17807 #ifdef WOLFSSL_JNI
17808 
17809 int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr)
17810 {
17811     WOLFSSL_ENTER("wolfSSL_set_jobject");
17812     if (ssl != NULL)
17813     {
17814         ssl->jObjectRef = objPtr;
17815         return SSL_SUCCESS;
17816     }
17817     return SSL_FAILURE;
17818 }
17819 
17820 void* wolfSSL_get_jobject(WOLFSSL* ssl)
17821 {
17822     WOLFSSL_ENTER("wolfSSL_get_jobject");
17823     if (ssl != NULL)
17824         return ssl->jObjectRef;
17825     return NULL;
17826 }
17827 
17828 #endif /* WOLFSSL_JNI */
17829 
17830 #endif /* WOLFCRYPT_ONLY */
17831