MultiTech / CyaSSL

Dependents:   HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ssl.c Source File

ssl.c

00001 /* ssl.c
00002  *
00003  * Copyright (C) 2006-2014 wolfSSL Inc.
00004  *
00005  * This file is part of CyaSSL.
00006  *
00007  * CyaSSL 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  * CyaSSL 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-1301, USA
00020  */
00021 
00022 #ifdef HAVE_CONFIG_H
00023     #include <config.h>
00024 #endif
00025 
00026 #include <cyassl/ctaocrypt/settings.h>
00027 
00028 #ifdef HAVE_ERRNO_H
00029     #include <errno.h>
00030 #endif
00031 
00032 #include <cyassl/ssl.h>
00033 #include <cyassl/internal.h>
00034 #include <cyassl/error-ssl.h>
00035 #include <cyassl/ctaocrypt/coding.h>
00036 
00037 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
00038     #include <cyassl/openssl/evp.h>
00039 #endif
00040 
00041 #ifdef OPENSSL_EXTRA
00042     /* openssl headers begin */
00043     #include <cyassl/openssl/hmac.h>
00044     #include <cyassl/openssl/crypto.h>
00045     #include <cyassl/openssl/des.h>
00046     #include <cyassl/openssl/bn.h>
00047     #include <cyassl/openssl/dh.h>
00048     #include <cyassl/openssl/rsa.h>
00049     #include <cyassl/openssl/pem.h>
00050     /* openssl headers end, cyassl internal headers next */
00051     #include <cyassl/ctaocrypt/hmac.h>
00052     #include <cyassl/ctaocrypt/random.h>
00053     #include <cyassl/ctaocrypt/des3.h>
00054     #include <cyassl/ctaocrypt/md4.h>
00055     #include <cyassl/ctaocrypt/md5.h>
00056     #include <cyassl/ctaocrypt/arc4.h>
00057     #ifdef CYASSL_SHA512
00058         #include <cyassl/ctaocrypt/sha512.h>
00059     #endif
00060 #endif
00061 
00062 #ifndef NO_FILESYSTEM
00063     #if !defined(USE_WINDOWS_API) && !defined(NO_CYASSL_DIR) \
00064             && !defined(EBSNET)
00065         #include <dirent.h>
00066         #include <sys/stat.h>
00067     #endif
00068     #ifdef EBSNET
00069         #include "vfapi.h"
00070         #include "vfile.h"
00071     #endif
00072 #endif /* NO_FILESYSTEM */
00073 
00074 #ifndef TRUE
00075     #define TRUE  1
00076 #endif
00077 #ifndef FALSE
00078     #define FALSE 0
00079 #endif
00080 
00081 #ifndef min
00082 
00083     static INLINE word32 min(word32 a, word32 b)
00084     {
00085         return a > b ? b : a;
00086     }
00087 
00088 #endif /* min */
00089 
00090 #ifndef max
00091 #ifdef CYASSL_DTLS
00092     static INLINE word32 max(word32 a, word32 b)
00093     {
00094         return a > b ? a : b;
00095     }
00096 #endif
00097 #endif /* min */
00098 
00099 
00100 #ifndef CYASSL_LEANPSK
00101 char* mystrnstr(const char* s1, const char* s2, unsigned int n)
00102 {
00103     unsigned int s2_len = (unsigned int)XSTRLEN(s2);
00104 
00105     if (s2_len == 0)
00106         return (char*)s1;
00107 
00108     while (n >= s2_len && s1[0]) {
00109         if (s1[0] == s2[0])
00110             if (XMEMCMP(s1, s2, s2_len) == 0)
00111                 return (char*)s1;
00112         s1++;
00113         n--;
00114     }
00115 
00116     return NULL;
00117 }
00118 #endif
00119 
00120 
00121 /* prevent multiple mutex initializations */
00122 static volatile int initRefCount = 0;
00123 static CyaSSL_Mutex count_mutex;   /* init ref count mutex */
00124 
00125 
00126 CYASSL_CTX* CyaSSL_CTX_new(CYASSL_METHOD* method)
00127 {
00128     CYASSL_CTX* ctx = NULL;
00129 
00130     CYASSL_ENTER("CYASSL_CTX_new");
00131 
00132     if (initRefCount == 0)
00133         CyaSSL_Init(); /* user no longer forced to call Init themselves */
00134 
00135     if (method == NULL)
00136         return ctx;
00137 
00138     ctx = (CYASSL_CTX*) XMALLOC(sizeof(CYASSL_CTX), 0, DYNAMIC_TYPE_CTX);
00139     if (ctx) {
00140         if (InitSSL_Ctx(ctx, method) < 0) {
00141             CYASSL_MSG("Init CTX failed");
00142             CyaSSL_CTX_free(ctx);
00143             ctx = NULL;
00144         }
00145     }
00146     else {
00147         CYASSL_MSG("Alloc CTX failed, method freed");
00148         XFREE(method, NULL, DYNAMIC_TYPE_METHOD);
00149     }
00150 
00151     CYASSL_LEAVE("CYASSL_CTX_new", 0);
00152     return ctx;
00153 }
00154 
00155 
00156 void CyaSSL_CTX_free(CYASSL_CTX* ctx)
00157 {
00158     CYASSL_ENTER("SSL_CTX_free");
00159     if (ctx)
00160         FreeSSL_Ctx(ctx);
00161     CYASSL_LEAVE("SSL_CTX_free", 0);
00162 }
00163 
00164 
00165 CYASSL* CyaSSL_new(CYASSL_CTX* ctx)
00166 {
00167     CYASSL* ssl = NULL;
00168     int ret = 0;
00169 
00170     (void)ret;
00171     CYASSL_ENTER("SSL_new");
00172 
00173     if (ctx == NULL)
00174         return ssl;
00175 
00176     ssl = (CYASSL*) XMALLOC(sizeof(CYASSL), ctx->heap,DYNAMIC_TYPE_SSL);
00177     if (ssl)
00178         if ( (ret = InitSSL(ssl, ctx)) < 0) {
00179             FreeSSL(ssl);
00180             ssl = 0;
00181         }
00182 
00183     CYASSL_LEAVE("SSL_new", ret);
00184     return ssl;
00185 }
00186 
00187 
00188 void CyaSSL_free(CYASSL* ssl)
00189 {
00190     CYASSL_ENTER("SSL_free");
00191     if (ssl)
00192         FreeSSL(ssl);
00193     CYASSL_LEAVE("SSL_free", 0);
00194 }
00195 
00196 #ifdef HAVE_POLY1305
00197 /* set if to use old poly 1 for yes 0 to use new poly */
00198 int CyaSSL_use_old_poly(CYASSL* ssl, int value)
00199 {
00200     CYASSL_ENTER("SSL_use_old_poly");
00201     ssl->options.oldPoly = value;
00202     CYASSL_LEAVE("SSL_use_old_poly", 0);
00203     return 0;
00204 }
00205 #endif
00206 
00207 int CyaSSL_set_fd(CYASSL* ssl, int fd)
00208 {
00209     CYASSL_ENTER("SSL_set_fd");
00210     ssl->rfd = fd;      /* not used directly to allow IO callbacks */
00211     ssl->wfd = fd;
00212 
00213     ssl->IOCB_ReadCtx  = &ssl->rfd;
00214     ssl->IOCB_WriteCtx = &ssl->wfd;
00215 
00216     #ifdef CYASSL_DTLS
00217         if (ssl->options.dtls) {
00218             ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
00219             ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
00220             ssl->buffers.dtlsCtx.fd = fd;
00221         }
00222     #endif
00223 
00224     CYASSL_LEAVE("SSL_set_fd", SSL_SUCCESS);
00225     return SSL_SUCCESS;
00226 }
00227 
00228 
00229 int CyaSSL_get_ciphers(char* buf, int len)
00230 {
00231     const char* const* ciphers = GetCipherNames();
00232     int  totalInc = 0;
00233     int  step     = 0;
00234     char delim    = ':';
00235     int  size     = GetCipherNamesSize();
00236     int  i;
00237 
00238     if (buf == NULL || len <= 0)
00239         return BAD_FUNC_ARG;
00240 
00241     /* Add each member to the buffer delimitted by a : */
00242     for (i = 0; i < size; i++) {
00243         step = (int)(XSTRLEN(ciphers[i]) + 1);  /* delimiter */
00244         totalInc += step;
00245 
00246         /* Check to make sure buf is large enough and will not overflow */
00247         if (totalInc < len) {
00248             XSTRNCPY(buf, ciphers[i], XSTRLEN(ciphers[i]));
00249             buf += XSTRLEN(ciphers[i]);
00250 
00251             if (i < size - 1)
00252                 *buf++ = delim;
00253         }
00254         else
00255             return BUFFER_E;
00256     }
00257     return SSL_SUCCESS;
00258 }
00259 
00260 
00261 int CyaSSL_get_fd(const CYASSL* ssl)
00262 {
00263     CYASSL_ENTER("SSL_get_fd");
00264     CYASSL_LEAVE("SSL_get_fd", ssl->rfd);
00265     return ssl->rfd;
00266 }
00267 
00268 
00269 int CyaSSL_get_using_nonblock(CYASSL* ssl)
00270 {
00271     CYASSL_ENTER("CyaSSL_get_using_nonblock");
00272     CYASSL_LEAVE("CyaSSL_get_using_nonblock", ssl->options.usingNonblock);
00273     return ssl->options.usingNonblock;
00274 }
00275 
00276 
00277 int CyaSSL_dtls(CYASSL* ssl)
00278 {
00279     return ssl->options.dtls;
00280 }
00281 
00282 
00283 #ifndef CYASSL_LEANPSK
00284 void CyaSSL_set_using_nonblock(CYASSL* ssl, int nonblock)
00285 {
00286     CYASSL_ENTER("CyaSSL_set_using_nonblock");
00287     ssl->options.usingNonblock = (nonblock != 0);
00288 }
00289 
00290 
00291 int CyaSSL_dtls_set_peer(CYASSL* ssl, void* peer, unsigned int peerSz)
00292 {
00293 #ifdef CYASSL_DTLS
00294     void* sa = (void*)XMALLOC(peerSz, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
00295     if (sa != NULL) {
00296         if (ssl->buffers.dtlsCtx.peer.sa != NULL)
00297             XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
00298         XMEMCPY(sa, peer, peerSz);
00299         ssl->buffers.dtlsCtx.peer.sa = sa;
00300         ssl->buffers.dtlsCtx.peer.sz = peerSz;
00301         return SSL_SUCCESS;
00302     }
00303     return SSL_FAILURE;
00304 #else
00305     (void)ssl;
00306     (void)peer;
00307     (void)peerSz;
00308     return SSL_NOT_IMPLEMENTED;
00309 #endif
00310 }
00311 
00312 int CyaSSL_dtls_get_peer(CYASSL* ssl, void* peer, unsigned int* peerSz)
00313 {
00314 #ifdef CYASSL_DTLS
00315     if (peer != NULL && peerSz != NULL
00316             && *peerSz >= ssl->buffers.dtlsCtx.peer.sz) {
00317         *peerSz = ssl->buffers.dtlsCtx.peer.sz;
00318         XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
00319         return SSL_SUCCESS;
00320     }
00321     return SSL_FAILURE;
00322 #else
00323     (void)ssl;
00324     (void)peer;
00325     (void)peerSz;
00326     return SSL_NOT_IMPLEMENTED;
00327 #endif
00328 }
00329 #endif /* CYASSL_LEANPSK */
00330 
00331 
00332 /* return underlyig connect or accept, SSL_SUCCESS on ok */
00333 int CyaSSL_negotiate(CYASSL* ssl)
00334 {
00335     int err = SSL_FATAL_ERROR;
00336 
00337     CYASSL_ENTER("CyaSSL_negotiate");
00338 #ifndef NO_CYASSL_SERVER
00339     if (ssl->options.side == CYASSL_SERVER_END)
00340         err = CyaSSL_accept(ssl);
00341 #endif
00342 
00343 #ifndef NO_CYASSL_CLIENT
00344     if (ssl->options.side == CYASSL_CLIENT_END)
00345         err = CyaSSL_connect(ssl);
00346 #endif
00347 
00348     CYASSL_LEAVE("CyaSSL_negotiate", err);
00349 
00350     return err;
00351 }
00352 
00353 
00354 #ifndef CYASSL_LEANPSK
00355 /* object size based on build */
00356 int CyaSSL_GetObjectSize(void)
00357 {
00358 #ifdef SHOW_SIZES
00359     printf("sizeof suites           = %lu\n", sizeof(Suites));
00360     printf("sizeof ciphers(2)       = %lu\n", sizeof(Ciphers));
00361 #ifndef NO_RC4
00362     printf("    sizeof arc4         = %lu\n", sizeof(Arc4));
00363 #endif
00364     printf("    sizeof aes          = %lu\n", sizeof(Aes));
00365 #ifndef NO_DES3
00366     printf("    sizeof des3         = %lu\n", sizeof(Des3));
00367 #endif
00368 #ifndef NO_RABBIT
00369     printf("    sizeof rabbit       = %lu\n", sizeof(Rabbit));
00370 #endif
00371 #ifdef HAVE_CHACHA
00372     printf("    sizeof chacha       = %lu\n", sizeof(Chacha));
00373 #endif
00374     printf("sizeof cipher specs     = %lu\n", sizeof(CipherSpecs));
00375     printf("sizeof keys             = %lu\n", sizeof(Keys));
00376     printf("sizeof Hashes(2)        = %lu\n", sizeof(Hashes));
00377 #ifndef NO_MD5
00378     printf("    sizeof MD5          = %lu\n", sizeof(Md5));
00379 #endif
00380 #ifndef NO_SHA
00381     printf("    sizeof SHA          = %lu\n", sizeof(Sha));
00382 #endif
00383 #ifndef NO_SHA256
00384     printf("    sizeof SHA256       = %lu\n", sizeof(Sha256));
00385 #endif
00386 #ifdef CYASSL_SHA384
00387     printf("    sizeof SHA384       = %lu\n", sizeof(Sha384));
00388 #endif
00389 #ifdef CYASSL_SHA384
00390     printf("    sizeof SHA512       = %lu\n", sizeof(Sha512));
00391 #endif
00392     printf("sizeof Buffers          = %lu\n", sizeof(Buffers));
00393     printf("sizeof Options          = %lu\n", sizeof(Options));
00394     printf("sizeof Arrays           = %lu\n", sizeof(Arrays));
00395 #ifndef NO_RSA
00396     printf("sizeof RsaKey           = %lu\n", sizeof(RsaKey));
00397 #endif
00398 #ifdef HAVE_ECC
00399     printf("sizeof ecc_key          = %lu\n", sizeof(ecc_key));
00400 #endif
00401     printf("sizeof CYASSL_CIPHER    = %lu\n", sizeof(CYASSL_CIPHER));
00402     printf("sizeof CYASSL_SESSION   = %lu\n", sizeof(CYASSL_SESSION));
00403     printf("sizeof CYASSL           = %lu\n", sizeof(CYASSL));
00404     printf("sizeof CYASSL_CTX       = %lu\n", sizeof(CYASSL_CTX));
00405 #endif
00406 
00407     return sizeof(CYASSL);
00408 }
00409 #endif
00410 
00411 
00412 #ifndef NO_DH
00413 /* server Diffie-Hellman parameters, SSL_SUCCESS on ok */
00414 int CyaSSL_SetTmpDH(CYASSL* ssl, const unsigned char* p, int pSz,
00415                     const unsigned char* g, int gSz)
00416 {
00417     byte havePSK = 0;
00418     byte haveRSA = 1;
00419 
00420     CYASSL_ENTER("CyaSSL_SetTmpDH");
00421     if (ssl == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
00422 
00423     if (ssl->options.side != CYASSL_SERVER_END)
00424         return SIDE_ERROR;
00425 
00426     if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH)
00427         XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
00428     if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH)
00429         XFREE(ssl->buffers.serverDH_G.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
00430 
00431     ssl->buffers.weOwnDH = 1;  /* SSL owns now */
00432     ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->ctx->heap,
00433                                                     DYNAMIC_TYPE_DH);
00434     if (ssl->buffers.serverDH_P.buffer == NULL)
00435         return MEMORY_E;
00436 
00437     ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, ssl->ctx->heap,
00438                                                     DYNAMIC_TYPE_DH);
00439     if (ssl->buffers.serverDH_G.buffer == NULL) {
00440         XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
00441         return MEMORY_E;
00442     }
00443 
00444     ssl->buffers.serverDH_P.length = pSz;
00445     ssl->buffers.serverDH_G.length = gSz;
00446 
00447     XMEMCPY(ssl->buffers.serverDH_P.buffer, p, pSz);
00448     XMEMCPY(ssl->buffers.serverDH_G.buffer, g, gSz);
00449 
00450     ssl->options.haveDH = 1;
00451     #ifndef NO_PSK
00452         havePSK = ssl->options.havePSK;
00453     #endif
00454     #ifdef NO_RSA
00455         haveRSA = 0;
00456     #endif
00457     InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH,
00458                ssl->options.haveNTRU, ssl->options.haveECDSAsig,
00459                ssl->options.haveStaticECC, ssl->options.side);
00460 
00461     CYASSL_LEAVE("CyaSSL_SetTmpDH", 0);
00462     return SSL_SUCCESS;
00463 }
00464 #endif /* !NO_DH */
00465 
00466 
00467 int CyaSSL_write(CYASSL* ssl, const void* data, int sz)
00468 {
00469     int ret;
00470 
00471     CYASSL_ENTER("SSL_write()");
00472 
00473     if (ssl == NULL || data == NULL || sz < 0)
00474         return BAD_FUNC_ARG;
00475 
00476 #ifdef HAVE_ERRNO_H
00477     errno = 0;
00478 #endif
00479 
00480     ret = SendData(ssl, data, sz);
00481 
00482     CYASSL_LEAVE("SSL_write()", ret);
00483 
00484     if (ret < 0)
00485         return SSL_FATAL_ERROR;
00486     else
00487         return ret;
00488 }
00489 
00490 
00491 static int CyaSSL_read_internal(CYASSL* ssl, void* data, int sz, int peek)
00492 {
00493     int ret;
00494 
00495     CYASSL_ENTER("CyaSSL_read_internal()");
00496 
00497     if (ssl == NULL || data == NULL || sz < 0)
00498         return BAD_FUNC_ARG;
00499 
00500 #ifdef HAVE_ERRNO_H
00501         errno = 0;
00502 #endif
00503 #ifdef CYASSL_DTLS
00504     if (ssl->options.dtls)
00505         ssl->dtls_expected_rx = max(sz + 100, MAX_MTU);
00506 #endif
00507 
00508 #ifdef HAVE_MAX_FRAGMENT
00509     ret = ReceiveData(ssl, (byte*)data,
00510                      min(sz, min(ssl->max_fragment, OUTPUT_RECORD_SIZE)), peek);
00511 #else
00512     ret = ReceiveData(ssl, (byte*)data, min(sz, OUTPUT_RECORD_SIZE), peek);
00513 #endif
00514 
00515     CYASSL_LEAVE("CyaSSL_read_internal()", ret);
00516 
00517     if (ret < 0)
00518         return SSL_FATAL_ERROR;
00519     else
00520         return ret;
00521 }
00522 
00523 
00524 int CyaSSL_peek(CYASSL* ssl, void* data, int sz)
00525 {
00526     CYASSL_ENTER("CyaSSL_peek()");
00527 
00528     return CyaSSL_read_internal(ssl, data, sz, TRUE);
00529 }
00530 
00531 
00532 int CyaSSL_read(CYASSL* ssl, void* data, int sz)
00533 {
00534     CYASSL_ENTER("CyaSSL_read()");
00535 
00536     return CyaSSL_read_internal(ssl, data, sz, FALSE);
00537 }
00538 
00539 
00540 #ifdef HAVE_CAVIUM
00541 
00542 /* let's use cavium, SSL_SUCCESS on ok */
00543 int CyaSSL_UseCavium(CYASSL* ssl, int devId)
00544 {
00545     if (ssl == NULL)
00546         return BAD_FUNC_ARG;
00547 
00548     ssl->devId = devId;
00549 
00550     return SSL_SUCCESS;
00551 }
00552 
00553 
00554 /* let's use cavium, SSL_SUCCESS on ok */
00555 int CyaSSL_CTX_UseCavium(CYASSL_CTX* ctx, int devId)
00556 {
00557     if (ctx == NULL)
00558         return BAD_FUNC_ARG;
00559 
00560     ctx->devId = devId;
00561 
00562     return SSL_SUCCESS;
00563 }
00564 
00565 
00566 #endif /* HAVE_CAVIUM */
00567 
00568 #ifdef HAVE_SNI
00569 
00570 int CyaSSL_UseSNI(CYASSL* ssl, byte type, const void* data, word16 size)
00571 {
00572     if (ssl == NULL)
00573         return BAD_FUNC_ARG;
00574 
00575     return TLSX_UseSNI(&ssl->extensions, type, data, size);
00576 }
00577 
00578 int CyaSSL_CTX_UseSNI(CYASSL_CTX* ctx, byte type, const void* data, word16 size)
00579 {
00580     if (ctx == NULL)
00581         return BAD_FUNC_ARG;
00582 
00583     return TLSX_UseSNI(&ctx->extensions, type, data, size);
00584 }
00585 
00586 #ifndef NO_CYASSL_SERVER
00587 
00588 void CyaSSL_SNI_SetOptions(CYASSL* ssl, byte type, byte options)
00589 {
00590     if (ssl && ssl->extensions)
00591         TLSX_SNI_SetOptions(ssl->extensions, type, options);
00592 }
00593 
00594 void CyaSSL_CTX_SNI_SetOptions(CYASSL_CTX* ctx, byte type, byte options)
00595 {
00596     if (ctx && ctx->extensions)
00597         TLSX_SNI_SetOptions(ctx->extensions, type, options);
00598 }
00599 
00600 byte CyaSSL_SNI_Status(CYASSL* ssl, byte type)
00601 {
00602     return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type);
00603 }
00604 
00605 word16 CyaSSL_SNI_GetRequest(CYASSL* ssl, byte type, void** data)
00606 {
00607     if (data)
00608         *data = NULL;
00609 
00610     if (ssl && ssl->extensions)
00611         return TLSX_SNI_GetRequest(ssl->extensions, type, data);
00612 
00613     return 0;
00614 }
00615 
00616 int CyaSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, byte type,
00617                                                      byte* sni, word32* inOutSz)
00618 {
00619     if (clientHello && helloSz > 0 && sni && inOutSz && *inOutSz > 0)
00620         return TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
00621 
00622     return BAD_FUNC_ARG;
00623 }
00624 
00625 #endif /* NO_CYASSL_SERVER */
00626 
00627 #endif /* HAVE_SNI */
00628 
00629 
00630 #ifdef HAVE_MAX_FRAGMENT
00631 #ifndef NO_CYASSL_CLIENT
00632 int CyaSSL_UseMaxFragment(CYASSL* ssl, byte mfl)
00633 {
00634     if (ssl == NULL)
00635         return BAD_FUNC_ARG;
00636 
00637     return TLSX_UseMaxFragment(&ssl->extensions, mfl);
00638 }
00639 
00640 int CyaSSL_CTX_UseMaxFragment(CYASSL_CTX* ctx, byte mfl)
00641 {
00642     if (ctx == NULL)
00643         return BAD_FUNC_ARG;
00644 
00645     return TLSX_UseMaxFragment(&ctx->extensions, mfl);
00646 }
00647 #endif /* NO_CYASSL_CLIENT */
00648 #endif /* HAVE_MAX_FRAGMENT */
00649 
00650 #ifdef HAVE_TRUNCATED_HMAC
00651 #ifndef NO_CYASSL_CLIENT
00652 int CyaSSL_UseTruncatedHMAC(CYASSL* ssl)
00653 {
00654     if (ssl == NULL)
00655         return BAD_FUNC_ARG;
00656 
00657     return TLSX_UseTruncatedHMAC(&ssl->extensions);
00658 }
00659 
00660 int CyaSSL_CTX_UseTruncatedHMAC(CYASSL_CTX* ctx)
00661 {
00662     if (ctx == NULL)
00663         return BAD_FUNC_ARG;
00664 
00665     return TLSX_UseTruncatedHMAC(&ctx->extensions);
00666 }
00667 #endif /* NO_CYASSL_CLIENT */
00668 #endif /* HAVE_TRUNCATED_HMAC */
00669 
00670 /* Elliptic Curves */
00671 #ifdef HAVE_SUPPORTED_CURVES
00672 #ifndef NO_CYASSL_CLIENT
00673 
00674 int CyaSSL_UseSupportedCurve(CYASSL* ssl, word16 name)
00675 {
00676     if (ssl == NULL)
00677         return BAD_FUNC_ARG;
00678 
00679     switch (name) {
00680         case CYASSL_ECC_SECP160R1:
00681         case CYASSL_ECC_SECP192R1:
00682         case CYASSL_ECC_SECP224R1:
00683         case CYASSL_ECC_SECP256R1:
00684         case CYASSL_ECC_SECP384R1:
00685         case CYASSL_ECC_SECP521R1:
00686             break;
00687 
00688         default:
00689             return BAD_FUNC_ARG;
00690     }
00691 
00692     return TLSX_UseSupportedCurve(&ssl->extensions, name);
00693 }
00694 
00695 int CyaSSL_CTX_UseSupportedCurve(CYASSL_CTX* ctx, word16 name)
00696 {
00697     if (ctx == NULL)
00698         return BAD_FUNC_ARG;
00699 
00700     switch (name) {
00701         case CYASSL_ECC_SECP160R1:
00702         case CYASSL_ECC_SECP192R1:
00703         case CYASSL_ECC_SECP224R1:
00704         case CYASSL_ECC_SECP256R1:
00705         case CYASSL_ECC_SECP384R1:
00706         case CYASSL_ECC_SECP521R1:
00707             break;
00708 
00709         default:
00710             return BAD_FUNC_ARG;
00711     }
00712 
00713     return TLSX_UseSupportedCurve(&ctx->extensions, name);
00714 }
00715 
00716 #endif /* NO_CYASSL_CLIENT */
00717 #endif /* HAVE_SUPPORTED_CURVES */
00718 
00719 /* Secure Renegotiation */
00720 #ifdef HAVE_SECURE_RENEGOTIATION
00721 
00722 /* user is forcing ability to use secure renegotiation, we discourage it */
00723 int CyaSSL_UseSecureRenegotiation(CYASSL* ssl)
00724 {
00725     int ret = BAD_FUNC_ARG;
00726 
00727     if (ssl)
00728         ret = TLSX_UseSecureRenegotiation(&ssl->extensions);
00729 
00730     if (ret == SSL_SUCCESS) {
00731         TLSX* extension = TLSX_Find(ssl->extensions, SECURE_RENEGOTIATION);
00732         
00733         if (extension)
00734             ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
00735     }
00736 
00737     return ret;
00738 }
00739 
00740 
00741 /* do a secure renegotiation handshake, user forced, we discourage */
00742 int CyaSSL_Rehandshake(CYASSL* ssl)
00743 {
00744     int ret;
00745 
00746     if (ssl == NULL)
00747         return BAD_FUNC_ARG;
00748 
00749     if (ssl->secure_renegotiation == NULL) {
00750         CYASSL_MSG("Secure Renegotiation not forced on by user");
00751         return SECURE_RENEGOTIATION_E;
00752     }
00753 
00754     if (ssl->secure_renegotiation->enabled == 0) {
00755         CYASSL_MSG("Secure Renegotiation not enabled at extension level");
00756         return SECURE_RENEGOTIATION_E;
00757     }
00758 
00759     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
00760         CYASSL_MSG("Can't renegotiate until previous handshake complete");
00761         return SECURE_RENEGOTIATION_E;
00762     }
00763 
00764 #ifndef NO_FORCE_SCR_SAME_SUITE
00765     /* force same suite */
00766     if (ssl->suites) {
00767         ssl->suites->suiteSz = SUITE_LEN;
00768         ssl->suites->suites[0] = ssl->options.cipherSuite0;
00769         ssl->suites->suites[1] = ssl->options.cipherSuite;
00770     }
00771 #endif
00772 
00773     /* reset handshake states */
00774     ssl->options.serverState = NULL_STATE;
00775     ssl->options.clientState = NULL_STATE;
00776     ssl->options.connectState  = CONNECT_BEGIN;
00777     ssl->options.acceptState   = ACCEPT_BEGIN;
00778     ssl->options.handShakeState = NULL_STATE;
00779     ssl->options.processReply  = 0;  /* TODO, move states in internal.h */
00780 
00781     XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
00782 
00783     ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
00784 
00785 #ifndef NO_OLD_TLS
00786 #ifndef NO_MD5
00787     InitMd5(&ssl->hashMd5);
00788 #endif
00789 #ifndef NO_SHA
00790     ret = InitSha(&ssl->hashSha);
00791     if (ret !=0)
00792         return ret;
00793 #endif
00794 #endif /* NO_OLD_TLS */
00795 #ifndef NO_SHA256
00796     ret = InitSha256(&ssl->hashSha256);
00797     if (ret !=0)
00798         return ret;
00799 #endif
00800 #ifdef CYASSL_SHA384
00801     ret = InitSha384(&ssl->hashSha384);
00802     if (ret !=0)
00803         return ret;
00804 #endif
00805 
00806     ret = CyaSSL_negotiate(ssl);
00807     return ret;
00808 }
00809 
00810 #endif /* HAVE_SECURE_RENEGOTIATION */
00811 
00812 /* Session Ticket */
00813 #if !defined(NO_CYASSL_CLIENT) && defined(HAVE_SESSION_TICKET)
00814 int CyaSSL_UseSessionTicket(CYASSL* ssl)
00815 {
00816     if (ssl == NULL)
00817         return BAD_FUNC_ARG;
00818 
00819     return TLSX_UseSessionTicket(&ssl->extensions, NULL);
00820 }
00821 
00822 int CyaSSL_CTX_UseSessionTicket(CYASSL_CTX* ctx)
00823 {
00824     if (ctx == NULL)
00825         return BAD_FUNC_ARG;
00826 
00827     return TLSX_UseSessionTicket(&ctx->extensions, NULL);
00828 }
00829 
00830 CYASSL_API int CyaSSL_get_SessionTicket(CYASSL* ssl, byte* buf, word32* bufSz)
00831 {
00832     if (ssl == NULL || buf == NULL || bufSz == NULL || *bufSz == 0)
00833         return BAD_FUNC_ARG;
00834 
00835     if (ssl->session.ticketLen <= *bufSz) {
00836         XMEMCPY(buf, ssl->session.ticket, ssl->session.ticketLen);
00837         *bufSz = ssl->session.ticketLen;
00838     }
00839     else
00840         *bufSz = 0;
00841 
00842     return SSL_SUCCESS;
00843 }
00844 
00845 CYASSL_API int CyaSSL_set_SessionTicket(CYASSL* ssl, byte* buf, word32 bufSz)
00846 {
00847     if (ssl == NULL || (buf == NULL && bufSz > 0))
00848         return BAD_FUNC_ARG;
00849 
00850     if (bufSz > 0)
00851         XMEMCPY(ssl->session.ticket, buf, bufSz);
00852     ssl->session.ticketLen = bufSz;
00853 
00854     return SSL_SUCCESS;
00855 }
00856 
00857 
00858 CYASSL_API int CyaSSL_set_SessionTicket_cb(CYASSL* ssl,
00859                                             CallbackSessionTicket cb, void* ctx)
00860 {
00861     if (ssl == NULL)
00862         return BAD_FUNC_ARG;
00863 
00864     ssl->session_ticket_cb = cb;
00865     ssl->session_ticket_ctx = ctx;
00866 
00867     return SSL_SUCCESS;
00868 }
00869 #endif
00870 
00871 #ifndef CYASSL_LEANPSK
00872 
00873 int CyaSSL_send(CYASSL* ssl, const void* data, int sz, int flags)
00874 {
00875     int ret;
00876     int oldFlags;
00877 
00878     CYASSL_ENTER("CyaSSL_send()");
00879 
00880     if (ssl == NULL || data == NULL || sz < 0)
00881         return BAD_FUNC_ARG;
00882 
00883     oldFlags = ssl->wflags;
00884 
00885     ssl->wflags = flags;
00886     ret = CyaSSL_write(ssl, data, sz);
00887     ssl->wflags = oldFlags;
00888 
00889     CYASSL_LEAVE("CyaSSL_send()", ret);
00890 
00891     return ret;
00892 }
00893 
00894 
00895 int CyaSSL_recv(CYASSL* ssl, void* data, int sz, int flags)
00896 {
00897     int ret;
00898     int oldFlags;
00899 
00900     CYASSL_ENTER("CyaSSL_recv()");
00901 
00902     if (ssl == NULL || data == NULL || sz < 0)
00903         return BAD_FUNC_ARG;
00904 
00905     oldFlags = ssl->rflags;
00906 
00907     ssl->rflags = flags;
00908     ret = CyaSSL_read(ssl, data, sz);
00909     ssl->rflags = oldFlags;
00910 
00911     CYASSL_LEAVE("CyaSSL_recv()", ret);
00912 
00913     return ret;
00914 }
00915 #endif
00916 
00917 
00918 /* SSL_SUCCESS on ok */
00919 int CyaSSL_shutdown(CYASSL* ssl)
00920 {
00921     CYASSL_ENTER("SSL_shutdown()");
00922 
00923     if (ssl == NULL)
00924         return SSL_FATAL_ERROR;
00925 
00926     if (ssl->options.quietShutdown) {
00927         CYASSL_MSG("quiet shutdown, no close notify sent");
00928         return SSL_SUCCESS;
00929     }
00930 
00931     /* try to send close notify, not an error if can't */
00932     if (!ssl->options.isClosed && !ssl->options.connReset &&
00933                                   !ssl->options.sentNotify) {
00934         ssl->error = SendAlert(ssl, alert_warning, close_notify);
00935         if (ssl->error < 0) {
00936             CYASSL_ERROR(ssl->error);
00937             return SSL_FATAL_ERROR;
00938         }
00939         ssl->options.sentNotify = 1;  /* don't send close_notify twice */
00940     }
00941 
00942     CYASSL_LEAVE("SSL_shutdown()", ssl->error);
00943 
00944     ssl->error = SSL_ERROR_SYSCALL;   /* simulate OpenSSL behavior */
00945 
00946     return SSL_SUCCESS;
00947 }
00948 
00949 
00950 int CyaSSL_get_error(CYASSL* ssl, int ret)
00951 {
00952     CYASSL_ENTER("SSL_get_error");
00953 
00954     if (ret > 0)
00955         return SSL_ERROR_NONE;
00956     if (ssl == NULL)
00957         return BAD_FUNC_ARG;
00958 
00959     CYASSL_LEAVE("SSL_get_error", ssl->error);
00960 
00961     /* make sure converted types are handled in SetErrorString() too */
00962     if (ssl->error == WANT_READ)
00963         return SSL_ERROR_WANT_READ;         /* convert to OpenSSL type */
00964     else if (ssl->error == WANT_WRITE)
00965         return SSL_ERROR_WANT_WRITE;        /* convert to OpenSSL type */
00966     else if (ssl->error == ZERO_RETURN)
00967         return SSL_ERROR_ZERO_RETURN;       /* convert to OpenSSL type */
00968     return ssl->error;
00969 }
00970 
00971 
00972 /* retrive alert history, SSL_SUCCESS on ok */
00973 int CyaSSL_get_alert_history(CYASSL* ssl, CYASSL_ALERT_HISTORY *h)
00974 {
00975     if (ssl && h) {
00976         *h = ssl->alert_history;
00977     }
00978     return SSL_SUCCESS;
00979 }
00980 
00981 
00982 /* return TRUE if current error is want read */
00983 int CyaSSL_want_read(CYASSL* ssl)
00984 {
00985     CYASSL_ENTER("SSL_want_read");
00986     if (ssl->error == WANT_READ)
00987         return 1;
00988 
00989     return 0;
00990 }
00991 
00992 
00993 /* return TRUE if current error is want write */
00994 int CyaSSL_want_write(CYASSL* ssl)
00995 {
00996     CYASSL_ENTER("SSL_want_write");
00997     if (ssl->error == WANT_WRITE)
00998         return 1;
00999 
01000     return 0;
01001 }
01002 
01003 
01004 char* CyaSSL_ERR_error_string(unsigned long errNumber, char* data)
01005 {
01006     static const char* msg = "Please supply a buffer for error string";
01007 
01008     CYASSL_ENTER("ERR_error_string");
01009     if (data) {
01010         SetErrorString((int)errNumber, data);
01011         return data;
01012     }
01013 
01014     return (char*)msg;
01015 }
01016 
01017 
01018 void CyaSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
01019 {
01020     CYASSL_ENTER("CyaSSL_ERR_error_string_n");
01021     if (len >= CYASSL_MAX_ERROR_SZ)
01022         CyaSSL_ERR_error_string(e, buf);
01023     else {
01024         char tmp[CYASSL_MAX_ERROR_SZ];
01025 
01026         CYASSL_MSG("Error buffer too short, truncating");
01027         if (len) {
01028             CyaSSL_ERR_error_string(e, tmp);
01029             XMEMCPY(buf, tmp, len-1);
01030             buf[len-1] = '\0';
01031         }
01032     }
01033 }
01034 
01035 
01036 /* don't free temporary arrays at end of handshake */
01037 void CyaSSL_KeepArrays(CYASSL* ssl)
01038 {
01039     if (ssl)
01040         ssl->options.saveArrays = 1;
01041 }
01042 
01043 
01044 /* user doesn't need temporary arrays anymore, Free */
01045 void CyaSSL_FreeArrays(CYASSL* ssl)
01046 {
01047     if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
01048         ssl->options.saveArrays = 0;
01049         FreeArrays(ssl, 1);
01050     }
01051 }
01052 
01053 
01054 const byte* CyaSSL_GetMacSecret(CYASSL* ssl, int verify)
01055 {
01056     if (ssl == NULL)
01057         return NULL;
01058 
01059     if ( (ssl->options.side == CYASSL_CLIENT_END && !verify) ||
01060          (ssl->options.side == CYASSL_SERVER_END &&  verify) )
01061         return ssl->keys.client_write_MAC_secret;
01062     else
01063         return ssl->keys.server_write_MAC_secret;
01064 }
01065 
01066 
01067 #ifdef ATOMIC_USER
01068 
01069 void  CyaSSL_CTX_SetMacEncryptCb(CYASSL_CTX* ctx, CallbackMacEncrypt cb)
01070 {
01071     if (ctx)
01072         ctx->MacEncryptCb = cb;
01073 }
01074 
01075 
01076 void  CyaSSL_SetMacEncryptCtx(CYASSL* ssl, void *ctx)
01077 {
01078     if (ssl)
01079         ssl->MacEncryptCtx = ctx;
01080 }
01081 
01082 
01083 void* CyaSSL_GetMacEncryptCtx(CYASSL* ssl)
01084 {
01085     if (ssl)
01086         return ssl->MacEncryptCtx;
01087 
01088     return NULL;
01089 }
01090 
01091 
01092 void  CyaSSL_CTX_SetDecryptVerifyCb(CYASSL_CTX* ctx, CallbackDecryptVerify cb)
01093 {
01094     if (ctx)
01095         ctx->DecryptVerifyCb = cb;
01096 }
01097 
01098 
01099 void  CyaSSL_SetDecryptVerifyCtx(CYASSL* ssl, void *ctx)
01100 {
01101     if (ssl)
01102         ssl->DecryptVerifyCtx = ctx;
01103 }
01104 
01105 
01106 void* CyaSSL_GetDecryptVerifyCtx(CYASSL* ssl)
01107 {
01108     if (ssl)
01109         return ssl->DecryptVerifyCtx;
01110 
01111     return NULL;
01112 }
01113 
01114 
01115 const byte* CyaSSL_GetClientWriteKey(CYASSL* ssl)
01116 {
01117     if (ssl)
01118         return ssl->keys.client_write_key;
01119 
01120     return NULL;
01121 }
01122 
01123 
01124 const byte* CyaSSL_GetClientWriteIV(CYASSL* ssl)
01125 {
01126     if (ssl)
01127         return ssl->keys.client_write_IV;
01128 
01129     return NULL;
01130 }
01131 
01132 
01133 const byte* CyaSSL_GetServerWriteKey(CYASSL* ssl)
01134 {
01135     if (ssl)
01136         return ssl->keys.server_write_key;
01137 
01138     return NULL;
01139 }
01140 
01141 
01142 const byte* CyaSSL_GetServerWriteIV(CYASSL* ssl)
01143 {
01144     if (ssl)
01145         return ssl->keys.server_write_IV;
01146 
01147     return NULL;
01148 }
01149 
01150 
01151 int CyaSSL_GetKeySize(CYASSL* ssl)
01152 {
01153     if (ssl)
01154         return ssl->specs.key_size;
01155 
01156     return BAD_FUNC_ARG;
01157 }
01158 
01159 
01160 int CyaSSL_GetIVSize(CYASSL* ssl)
01161 {
01162     if (ssl)
01163         return ssl->specs.iv_size;
01164 
01165     return BAD_FUNC_ARG;
01166 }
01167 
01168 
01169 int CyaSSL_GetBulkCipher(CYASSL* ssl)
01170 {
01171     if (ssl)
01172         return ssl->specs.bulk_cipher_algorithm;
01173 
01174     return BAD_FUNC_ARG;
01175 }
01176 
01177 
01178 int CyaSSL_GetCipherType(CYASSL* ssl)
01179 {
01180     if (ssl == NULL)
01181         return BAD_FUNC_ARG;
01182 
01183     if (ssl->specs.cipher_type == block)
01184         return CYASSL_BLOCK_TYPE;
01185     if (ssl->specs.cipher_type == stream)
01186         return CYASSL_STREAM_TYPE;
01187     if (ssl->specs.cipher_type == aead)
01188         return CYASSL_AEAD_TYPE;
01189 
01190     return -1;
01191 }
01192 
01193 
01194 int CyaSSL_GetCipherBlockSize(CYASSL* ssl)
01195 {
01196     if (ssl == NULL)
01197         return BAD_FUNC_ARG;
01198 
01199     return ssl->specs.block_size;
01200 }
01201 
01202 
01203 int CyaSSL_GetAeadMacSize(CYASSL* ssl)
01204 {
01205     if (ssl == NULL)
01206         return BAD_FUNC_ARG;
01207 
01208     return ssl->specs.aead_mac_size;
01209 }
01210 
01211 
01212 int CyaSSL_IsTLSv1_1(CYASSL* ssl)
01213 {
01214     if (ssl == NULL)
01215         return BAD_FUNC_ARG;
01216 
01217     if (ssl->options.tls1_1)
01218         return 1;
01219 
01220     return 0;
01221 }
01222 
01223 
01224 int CyaSSL_GetSide(CYASSL* ssl)
01225 {
01226     if (ssl)
01227         return ssl->options.side;
01228 
01229     return BAD_FUNC_ARG;
01230 }
01231 
01232 
01233 int CyaSSL_GetHmacSize(CYASSL* ssl)
01234 {
01235     /* AEAD ciphers don't have HMAC keys */
01236     if (ssl)
01237         return (ssl->specs.cipher_type != aead) ? ssl->specs.hash_size : 0;
01238 
01239     return BAD_FUNC_ARG;
01240 }
01241 
01242 #endif /* ATOMIC_USER */
01243 
01244 #ifndef NO_CERTS
01245 
01246 CYASSL_CERT_MANAGER* CyaSSL_CertManagerNew(void)
01247 {
01248     CYASSL_CERT_MANAGER* cm = NULL;
01249 
01250     CYASSL_ENTER("CyaSSL_CertManagerNew");
01251 
01252     cm = (CYASSL_CERT_MANAGER*) XMALLOC(sizeof(CYASSL_CERT_MANAGER), 0,
01253                                         DYNAMIC_TYPE_CERT_MANAGER);
01254     if (cm) {
01255         XMEMSET(cm, 0, sizeof(CYASSL_CERT_MANAGER));
01256 
01257         if (InitMutex(&cm->caLock) != 0) {
01258             CYASSL_MSG("Bad mutex init");
01259             CyaSSL_CertManagerFree(cm);
01260             return NULL;
01261         }
01262     }
01263 
01264     return cm;
01265 }
01266 
01267 
01268 void CyaSSL_CertManagerFree(CYASSL_CERT_MANAGER* cm)
01269 {
01270     CYASSL_ENTER("CyaSSL_CertManagerFree");
01271 
01272     if (cm) {
01273         #ifdef HAVE_CRL
01274             if (cm->crl)
01275                 FreeCRL(cm->crl, 1);
01276         #endif
01277         #ifdef HAVE_OCSP
01278             if (cm->ocsp)
01279                 FreeOCSP(cm->ocsp, 1);
01280         #endif
01281         FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
01282         FreeMutex(&cm->caLock);
01283         XFREE(cm, NULL, DYNAMIC_TYPE_CERT_MANAGER);
01284     }
01285 
01286 }
01287 
01288 
01289 /* Unload the CA signer list */
01290 int CyaSSL_CertManagerUnloadCAs(CYASSL_CERT_MANAGER* cm)
01291 {
01292     CYASSL_ENTER("CyaSSL_CertManagerUnloadCAs");
01293 
01294     if (cm == NULL)
01295         return BAD_FUNC_ARG;
01296 
01297     if (LockMutex(&cm->caLock) != 0)
01298         return BAD_MUTEX_E;
01299 
01300     FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
01301 
01302     UnLockMutex(&cm->caLock);
01303 
01304 
01305     return SSL_SUCCESS;
01306 }
01307 
01308 
01309 /* Return bytes written to buff or < 0 for error */
01310 int CyaSSL_CertPemToDer(const unsigned char* pem, int pemSz,
01311                         unsigned char* buff, int buffSz,
01312                         int type)
01313 {
01314     int            eccKey = 0;
01315     int            ret;
01316     buffer         der;
01317 #ifdef CYASSL_SMALL_STACK
01318     EncryptedInfo* info = NULL;
01319 #else
01320     EncryptedInfo  info[1];
01321 #endif
01322 
01323     CYASSL_ENTER("CyaSSL_CertPemToDer");
01324 
01325     if (pem == NULL || buff == NULL || buffSz <= 0) {
01326         CYASSL_MSG("Bad pem der args");
01327         return BAD_FUNC_ARG;
01328     }
01329 
01330     if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) {
01331         CYASSL_MSG("Bad cert type");
01332         return BAD_FUNC_ARG;
01333     }
01334 
01335 #ifdef CYASSL_SMALL_STACK
01336     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
01337                                                        DYNAMIC_TYPE_TMP_BUFFER);
01338     if (info == NULL)
01339         return MEMORY_E;
01340 #endif
01341 
01342     info->set      = 0;
01343     info->ctx      = NULL;
01344     info->consumed = 0;
01345     der.buffer     = NULL;
01346 
01347     ret = PemToDer(pem, pemSz, type, &der, NULL, info, &eccKey);
01348 
01349 #ifdef CYASSL_SMALL_STACK
01350     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01351 #endif
01352 
01353     if (ret < 0) {
01354         CYASSL_MSG("Bad Pem To Der");
01355     }
01356     else {
01357         if (der.length <= (word32)buffSz) {
01358             XMEMCPY(buff, der.buffer, der.length);
01359             ret = der.length;
01360         }
01361         else {
01362             CYASSL_MSG("Bad der length");
01363             ret = BAD_FUNC_ARG;
01364         }
01365     }
01366 
01367     XFREE(der.buffer, NULL, DYNAMIC_TYPE_KEY);
01368 
01369     return ret;
01370 }
01371 
01372 
01373 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
01374 
01375 /* our KeyPemToDer password callback, password in userData */
01376 static INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
01377 {
01378     (void)rw;
01379 
01380     if (userdata == NULL)
01381         return 0;
01382 
01383     XSTRNCPY(passwd, (char*)userdata, sz);
01384     return min((word32)sz, (word32)XSTRLEN((char*)userdata));
01385 }
01386 
01387 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
01388 
01389 
01390 /* Return bytes written to buff or < 0 for error */
01391 int CyaSSL_KeyPemToDer(const unsigned char* pem, int pemSz, unsigned char* buff,
01392                        int buffSz, const char* pass)
01393 {
01394     int            eccKey = 0;
01395     int            ret;
01396     buffer         der;
01397 #ifdef CYASSL_SMALL_STACK
01398     EncryptedInfo* info = NULL;
01399 #else
01400     EncryptedInfo  info[1];
01401 #endif
01402 
01403     (void)pass;
01404 
01405     CYASSL_ENTER("CyaSSL_KeyPemToDer");
01406 
01407     if (pem == NULL || buff == NULL || buffSz <= 0) {
01408         CYASSL_MSG("Bad pem der args");
01409         return BAD_FUNC_ARG;
01410     }
01411 
01412 #ifdef CYASSL_SMALL_STACK
01413     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
01414                                                        DYNAMIC_TYPE_TMP_BUFFER);
01415     if (info == NULL)
01416         return MEMORY_E;
01417 #endif
01418 
01419     info->set      = 0;
01420     info->ctx      = NULL;
01421     info->consumed = 0;
01422     der.buffer     = NULL;
01423 
01424 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
01425     if (pass) {
01426         info->ctx = CyaSSL_CTX_new(CyaSSLv23_client_method());
01427         if (info->ctx == NULL) {
01428         #ifdef CYASSL_SMALL_STACK
01429             XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01430         #endif
01431             return MEMORY_E;
01432         }
01433 
01434         CyaSSL_CTX_set_default_passwd_cb(info->ctx, OurPasswordCb);
01435         CyaSSL_CTX_set_default_passwd_cb_userdata(info->ctx, (void*)pass);
01436     }
01437 #endif
01438 
01439     ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, &eccKey);
01440 
01441     if (info->ctx)
01442         CyaSSL_CTX_free(info->ctx);
01443 
01444 #ifdef CYASSL_SMALL_STACK
01445     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01446 #endif
01447 
01448     if (ret < 0) {
01449         CYASSL_MSG("Bad Pem To Der");
01450     }
01451     else {
01452         if (der.length <= (word32)buffSz) {
01453             XMEMCPY(buff, der.buffer, der.length);
01454             ret = der.length;
01455         }
01456         else {
01457             CYASSL_MSG("Bad der length");
01458             ret = BAD_FUNC_ARG;
01459         }
01460     }
01461 
01462     XFREE(der.buffer, NULL, DYNAMIC_TYPE_KEY);
01463 
01464     return ret;
01465 }
01466 
01467 
01468 #endif /* !NO_CERTS */
01469 
01470 
01471 
01472 #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
01473 
01474 void CyaSSL_ERR_print_errors_fp(FILE* fp, int err)
01475 {
01476     char data[CYASSL_MAX_ERROR_SZ + 1];
01477 
01478     CYASSL_ENTER("CyaSSL_ERR_print_errors_fp");
01479     SetErrorString(err, data);
01480     fprintf(fp, "%s", data);
01481 }
01482 
01483 #endif
01484 
01485 
01486 int CyaSSL_pending(CYASSL* ssl)
01487 {
01488     CYASSL_ENTER("SSL_pending");
01489     return ssl->buffers.clearOutputBuffer.length;
01490 }
01491 
01492 
01493 #ifndef CYASSL_LEANPSK
01494 /* trun on handshake group messages for context */
01495 int CyaSSL_CTX_set_group_messages(CYASSL_CTX* ctx)
01496 {
01497     if (ctx == NULL)
01498        return BAD_FUNC_ARG;
01499 
01500     ctx->groupMessages = 1;
01501 
01502     return SSL_SUCCESS;
01503 }
01504 #endif
01505 
01506 
01507 #ifndef NO_CYASSL_CLIENT
01508 /* connect enough to get peer cert chain */
01509 int CyaSSL_connect_cert(CYASSL* ssl)
01510 {
01511     int  ret;
01512 
01513     if (ssl == NULL)
01514         return SSL_FAILURE;
01515 
01516     ssl->options.certOnly = 1;
01517     ret = CyaSSL_connect(ssl);
01518     ssl->options.certOnly   = 0;
01519 
01520     return ret;
01521 }
01522 #endif
01523 
01524 
01525 #ifndef CYASSL_LEANPSK
01526 /* trun on handshake group messages for ssl object */
01527 int CyaSSL_set_group_messages(CYASSL* ssl)
01528 {
01529     if (ssl == NULL)
01530        return BAD_FUNC_ARG;
01531 
01532     ssl->options.groupMessages = 1;
01533 
01534     return SSL_SUCCESS;
01535 }
01536 
01537 
01538 /* Set minimum downgrade version allowed, SSL_SUCCESS on ok */
01539 int CyaSSL_SetMinVersion(CYASSL* ssl, int version)
01540 {
01541     CYASSL_ENTER("CyaSSL_SetMinVersion");
01542 
01543     if (ssl == NULL) {
01544         CYASSL_MSG("Bad function argument");
01545         return BAD_FUNC_ARG;
01546     }
01547 
01548     switch (version) {
01549 #ifndef NO_OLD_TLS
01550         case CYASSL_SSLV3:
01551             ssl->options.minDowngrade = SSLv3_MINOR;
01552             break;
01553 #endif
01554 
01555 #ifndef NO_TLS
01556     #ifndef NO_OLD_TLS
01557         case CYASSL_TLSV1:
01558             ssl->options.minDowngrade = TLSv1_MINOR;
01559             break;
01560 
01561         case CYASSL_TLSV1_1:
01562             ssl->options.minDowngrade = TLSv1_1_MINOR;
01563             break;
01564     #endif
01565         case CYASSL_TLSV1_2:
01566             ssl->options.minDowngrade = TLSv1_2_MINOR;
01567             break;
01568 #endif
01569 
01570         default:
01571             CYASSL_MSG("Bad function argument");
01572             return BAD_FUNC_ARG;
01573     }
01574 
01575 
01576     return SSL_SUCCESS;
01577 }
01578 
01579 
01580 int CyaSSL_SetVersion(CYASSL* ssl, int version)
01581 {
01582     byte haveRSA = 1;
01583     byte havePSK = 0;
01584 
01585     CYASSL_ENTER("CyaSSL_SetVersion");
01586 
01587     if (ssl == NULL) {
01588         CYASSL_MSG("Bad function argument");
01589         return BAD_FUNC_ARG;
01590     }
01591 
01592     switch (version) {
01593 #ifndef NO_OLD_TLS
01594         case CYASSL_SSLV3:
01595             ssl->version = MakeSSLv3();
01596             break;
01597 #endif
01598 
01599 #ifndef NO_TLS
01600     #ifndef NO_OLD_TLS
01601         case CYASSL_TLSV1:
01602             ssl->version = MakeTLSv1();
01603             break;
01604 
01605         case CYASSL_TLSV1_1:
01606             ssl->version = MakeTLSv1_1();
01607             break;
01608     #endif
01609         case CYASSL_TLSV1_2:
01610             ssl->version = MakeTLSv1_2();
01611             break;
01612 #endif
01613 
01614         default:
01615             CYASSL_MSG("Bad function argument");
01616             return BAD_FUNC_ARG;
01617     }
01618 
01619     #ifdef NO_RSA
01620         haveRSA = 0;
01621     #endif
01622     #ifndef NO_PSK
01623         havePSK = ssl->options.havePSK;
01624     #endif
01625 
01626     InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH,
01627                 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
01628                 ssl->options.haveStaticECC, ssl->options.side);
01629 
01630     return SSL_SUCCESS;
01631 }
01632 #endif /* !leanpsk */
01633 
01634 
01635 #if !defined(NO_CERTS) || !defined(NO_SESSION_CACHE)
01636 
01637 /* Make a work from the front of random hash */
01638 static INLINE word32 MakeWordFromHash(const byte* hashID)
01639 {
01640     return (hashID[0] << 24) | (hashID[1] << 16) | (hashID[2] <<  8) |
01641             hashID[3];
01642 }
01643 
01644 #endif /* !NO_CERTS || !NO_SESSION_CACHE */
01645 
01646 
01647 #ifndef NO_CERTS
01648 
01649 /* hash is the SHA digest of name, just use first 32 bits as hash */
01650 static INLINE word32 HashSigner(const byte* hash)
01651 {
01652     return MakeWordFromHash(hash) % CA_TABLE_SIZE;
01653 }
01654 
01655 
01656 /* does CA already exist on signer list */
01657 int AlreadySigner(CYASSL_CERT_MANAGER* cm, byte* hash)
01658 {
01659     Signer* signers;
01660     int     ret = 0;
01661     word32  row = HashSigner(hash);
01662 
01663     if (LockMutex(&cm->caLock) != 0)
01664         return  ret;
01665     signers = cm->caTable[row];
01666     while (signers) {
01667         byte* subjectHash;
01668         #ifndef NO_SKID
01669             subjectHash = signers->subjectKeyIdHash;
01670         #else
01671             subjectHash = signers->subjectNameHash;
01672         #endif
01673         if (XMEMCMP(hash, subjectHash, SHA_DIGEST_SIZE) == 0) {
01674             ret = 1;
01675             break;
01676         }
01677         signers = signers->next;
01678     }
01679     UnLockMutex(&cm->caLock);
01680 
01681     return ret;
01682 }
01683 
01684 
01685 /* return CA if found, otherwise NULL */
01686 Signer* GetCA(void* vp, byte* hash)
01687 {
01688     CYASSL_CERT_MANAGER* cm = (CYASSL_CERT_MANAGER*)vp;
01689     Signer* ret = NULL;
01690     Signer* signers;
01691     word32  row = HashSigner(hash);
01692 
01693     if (cm == NULL)
01694         return NULL;
01695 
01696     if (LockMutex(&cm->caLock) != 0)
01697         return ret;
01698 
01699     signers = cm->caTable[row];
01700     while (signers) {
01701         byte* subjectHash;
01702         #ifndef NO_SKID
01703             subjectHash = signers->subjectKeyIdHash;
01704         #else
01705             subjectHash = signers->subjectNameHash;
01706         #endif
01707         if (XMEMCMP(hash, subjectHash, SHA_DIGEST_SIZE) == 0) {
01708             ret = signers;
01709             break;
01710         }
01711         signers = signers->next;
01712     }
01713     UnLockMutex(&cm->caLock);
01714 
01715     return ret;
01716 }
01717 
01718 
01719 #ifndef NO_SKID
01720 /* return CA if found, otherwise NULL. Walk through hash table. */
01721 Signer* GetCAByName(void* vp, byte* hash)
01722 {
01723     CYASSL_CERT_MANAGER* cm = (CYASSL_CERT_MANAGER*)vp;
01724     Signer* ret = NULL;
01725     Signer* signers;
01726     word32  row;
01727 
01728     if (cm == NULL)
01729         return NULL;
01730 
01731     if (LockMutex(&cm->caLock) != 0)
01732         return ret;
01733 
01734     for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
01735         signers = cm->caTable[row];
01736         while (signers && ret == NULL) {
01737             if (XMEMCMP(hash, signers->subjectNameHash, SHA_DIGEST_SIZE) == 0) {
01738                 ret = signers;
01739             }
01740             signers = signers->next;
01741         }
01742     }
01743     UnLockMutex(&cm->caLock);
01744 
01745     return ret;
01746 }
01747 #endif
01748 
01749 
01750 /* owns der, internal now uses too */
01751 /* type flag ids from user or from chain received during verify
01752    don't allow chain ones to be added w/o isCA extension */
01753 int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify)
01754 {
01755     int         ret;
01756     Signer*     signer = 0;
01757     word32      row;
01758     byte*       subjectHash;
01759 #ifdef CYASSL_SMALL_STACK
01760     DecodedCert* cert = NULL;
01761 #else
01762     DecodedCert  cert[1];
01763 #endif
01764 
01765     CYASSL_MSG("Adding a CA");
01766 
01767 #ifdef CYASSL_SMALL_STACK
01768     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
01769                                                        DYNAMIC_TYPE_TMP_BUFFER);
01770     if (cert == NULL)
01771         return MEMORY_E;
01772 #endif
01773 
01774     InitDecodedCert(cert, der.buffer, der.length, cm->heap);
01775     ret = ParseCert(cert, CA_TYPE, verify, cm);
01776     CYASSL_MSG("    Parsed new CA");
01777 
01778 #ifndef NO_SKID
01779     subjectHash = cert->extSubjKeyId;
01780 #else
01781     subjectHash = cert->subjectHash;
01782 #endif
01783 
01784     if (ret == 0 && cert->isCA == 0 && type != CYASSL_USER_CA) {
01785         CYASSL_MSG("    Can't add as CA if not actually one");
01786         ret = NOT_CA_ERROR;
01787     }
01788 #ifndef ALLOW_INVALID_CERTSIGN
01789     else if (ret == 0 && cert->isCA == 1 && type != CYASSL_USER_CA &&
01790                               (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) == 0) {
01791         /* Intermediate CA certs are required to have the keyCertSign
01792         * extension set. User loaded root certs are not. */
01793         CYASSL_MSG("    Doesn't have key usage certificate signing");
01794         ret = NOT_CA_ERROR;
01795     }
01796 #endif
01797     else if (ret == 0 && AlreadySigner(cm, subjectHash)) {
01798         CYASSL_MSG("    Already have this CA, not adding again");
01799         (void)ret;
01800     }
01801     else if (ret == 0) {
01802         /* take over signer parts */
01803         signer = MakeSigner(cm->heap);
01804         if (!signer)
01805             ret = MEMORY_ERROR;
01806         else {
01807             signer->keyOID         = cert->keyOID;
01808             signer->publicKey      = cert->publicKey;
01809             signer->pubKeySize     = cert->pubKeySize;
01810             signer->nameLen        = cert->subjectCNLen;
01811             signer->name           = cert->subjectCN;
01812         #ifndef IGNORE_NAME_CONSTRAINTS
01813             signer->permittedNames = cert->permittedNames;
01814             signer->excludedNames  = cert->excludedNames;
01815         #endif
01816         #ifndef NO_SKID
01817             XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
01818                                                                SHA_DIGEST_SIZE);
01819         #endif
01820             XMEMCPY(signer->subjectNameHash, cert->subjectHash,
01821                                                                SHA_DIGEST_SIZE);
01822             signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
01823                                                     : 0xFFFF;
01824             signer->next    = NULL; /* If Key Usage not set, all uses valid. */
01825             cert->publicKey = 0;    /* in case lock fails don't free here.   */
01826             cert->subjectCN = 0;
01827         #ifndef IGNORE_NAME_CONSTRAINTS
01828             cert->permittedNames = NULL;
01829             cert->excludedNames = NULL;
01830         #endif
01831 
01832         #ifndef NO_SKID
01833             row = HashSigner(signer->subjectKeyIdHash);
01834         #else
01835             row = HashSigner(signer->subjectNameHash);
01836         #endif
01837 
01838             if (LockMutex(&cm->caLock) == 0) {
01839                 signer->next = cm->caTable[row];
01840                 cm->caTable[row] = signer;   /* takes ownership */
01841                 UnLockMutex(&cm->caLock);
01842                 if (cm->caCacheCallback)
01843                     cm->caCacheCallback(der.buffer, (int)der.length, type);
01844             }
01845             else {
01846                 CYASSL_MSG("    CA Mutex Lock failed");
01847                 ret = BAD_MUTEX_E;
01848                 FreeSigner(signer, cm->heap);
01849             }
01850         }
01851     }
01852 
01853     CYASSL_MSG("    Freeing Parsed CA");
01854     FreeDecodedCert(cert);
01855 #ifdef CYASSL_SMALL_STACK
01856     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01857 #endif
01858     CYASSL_MSG("    Freeing der CA");
01859     XFREE(der.buffer, cm->heap, DYNAMIC_TYPE_CA);
01860     CYASSL_MSG("        OK Freeing der CA");
01861 
01862     CYASSL_LEAVE("AddCA", ret);
01863 
01864     return ret == 0 ? SSL_SUCCESS : ret;
01865 }
01866 
01867 #endif /* !NO_CERTS */
01868 
01869 
01870 #ifndef NO_SESSION_CACHE
01871 
01872     /* basic config gives a cache with 33 sessions, adequate for clients and
01873        embedded servers
01874 
01875        MEDIUM_SESSION_CACHE allows 1055 sessions, adequate for servers that
01876        aren't under heavy load, basically allows 200 new sessions per minute
01877 
01878        BIG_SESSION_CACHE yields 20,027 sessions
01879 
01880        HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
01881        allows over 13,000 new sessions per minute or over 200 new sessions per
01882        second
01883 
01884        SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients
01885        or systems where the default of nearly 3kB is too much RAM, this define
01886        uses less than 500 bytes RAM
01887 
01888        default SESSION_CACHE stores 33 sessions (no XXX_SESSION_CACHE defined)
01889     */
01890     #ifdef HUGE_SESSION_CACHE
01891         #define SESSIONS_PER_ROW 11
01892         #define SESSION_ROWS 5981
01893     #elif defined(BIG_SESSION_CACHE)
01894         #define SESSIONS_PER_ROW 7
01895         #define SESSION_ROWS 2861
01896     #elif defined(MEDIUM_SESSION_CACHE)
01897         #define SESSIONS_PER_ROW 5
01898         #define SESSION_ROWS 211
01899     #elif defined(SMALL_SESSION_CACHE)
01900         #define SESSIONS_PER_ROW 2
01901         #define SESSION_ROWS 3
01902     #else
01903         #define SESSIONS_PER_ROW 3
01904         #define SESSION_ROWS 11
01905     #endif
01906 
01907     typedef struct SessionRow {
01908         int nextIdx;                           /* where to place next one   */
01909         int totalCount;                        /* sessions ever on this row */
01910         CYASSL_SESSION Sessions[SESSIONS_PER_ROW];
01911     } SessionRow;
01912 
01913     static SessionRow SessionCache[SESSION_ROWS];
01914 
01915     static CyaSSL_Mutex session_mutex;   /* SessionCache mutex */
01916 
01917     #ifndef NO_CLIENT_CACHE
01918 
01919         typedef struct ClientSession {
01920             word16 serverRow;            /* SessionCache Row id */
01921             word16 serverIdx;            /* SessionCache Idx (column) */
01922         } ClientSession;
01923 
01924         typedef struct ClientRow {
01925             int nextIdx;                /* where to place next one   */
01926             int totalCount;             /* sessions ever on this row */
01927             ClientSession Clients[SESSIONS_PER_ROW];
01928         } ClientRow;
01929 
01930         static ClientRow ClientCache[SESSION_ROWS];  /* Client Cache */
01931                                                      /* uses session mutex */
01932     #endif  /* NO_CLIENT_CACHE */
01933 
01934 #endif /* NO_SESSION_CACHE */
01935 
01936 
01937 int CyaSSL_Init(void)
01938 {
01939     int ret = SSL_SUCCESS;
01940 
01941     CYASSL_ENTER("CyaSSL_Init");
01942 
01943     if (initRefCount == 0) {
01944 #ifndef NO_SESSION_CACHE
01945         if (InitMutex(&session_mutex) != 0)
01946             ret = BAD_MUTEX_E;
01947 #endif
01948         if (InitMutex(&count_mutex) != 0)
01949             ret = BAD_MUTEX_E;
01950     }
01951     if (ret == SSL_SUCCESS) {
01952         if (LockMutex(&count_mutex) != 0) {
01953             CYASSL_MSG("Bad Lock Mutex count");
01954             return BAD_MUTEX_E;
01955         }
01956         initRefCount++;
01957         UnLockMutex(&count_mutex);
01958     }
01959 
01960     return ret;
01961 }
01962 
01963 
01964 #ifndef NO_CERTS
01965 
01966 static const char* BEGIN_CERT         = "-----BEGIN CERTIFICATE-----";
01967 static const char* END_CERT           = "-----END CERTIFICATE-----";
01968 static const char* BEGIN_CERT_REQ     = "-----BEGIN CERTIFICATE REQUEST-----";
01969 static const char* END_CERT_REQ       = "-----END CERTIFICATE REQUEST-----";
01970 static const char* BEGIN_DH_PARAM     = "-----BEGIN DH PARAMETERS-----";
01971 static const char* END_DH_PARAM       = "-----END DH PARAMETERS-----";
01972 static const char* BEGIN_X509_CRL     = "-----BEGIN X509 CRL-----";
01973 static const char* END_X509_CRL       = "-----END X509 CRL-----";
01974 static const char* BEGIN_RSA_PRIV     = "-----BEGIN RSA PRIVATE KEY-----";
01975 static const char* END_RSA_PRIV       = "-----END RSA PRIVATE KEY-----";
01976 static const char* BEGIN_PRIV_KEY     = "-----BEGIN PRIVATE KEY-----";
01977 static const char* END_PRIV_KEY       = "-----END PRIVATE KEY-----";
01978 static const char* BEGIN_ENC_PRIV_KEY = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
01979 static const char* END_ENC_PRIV_KEY   = "-----END ENCRYPTED PRIVATE KEY-----";
01980 static const char* BEGIN_EC_PRIV      = "-----BEGIN EC PRIVATE KEY-----";
01981 static const char* END_EC_PRIV        = "-----END EC PRIVATE KEY-----";
01982 static const char* BEGIN_DSA_PRIV     = "-----BEGIN DSA PRIVATE KEY-----";
01983 static const char* END_DSA_PRIV       = "-----END DSA PRIVATE KEY-----";
01984 
01985 /* Remove PEM header/footer, convert to ASN1, store any encrypted data
01986    info->consumed tracks of PEM bytes consumed in case multiple parts */
01987 int PemToDer(const unsigned char* buff, long longSz, int type,
01988                   buffer* der, void* heap, EncryptedInfo* info, int* eccKey)
01989 {
01990     const char* header      = NULL;
01991     const char* footer      = NULL;
01992     char*       headerEnd;
01993     char*       footerEnd;
01994     char*       consumedEnd;
01995     char*       bufferEnd   = (char*)(buff + longSz);
01996     long        neededSz;
01997     int         ret         = 0;
01998     int         dynamicType = 0;
01999     int         sz          = (int)longSz;
02000 
02001     switch (type) {
02002         case CA_TYPE:       /* same as below */
02003         case CERT_TYPE:     header= BEGIN_CERT;     footer= END_CERT;     break;
02004         case CRL_TYPE:      header= BEGIN_X509_CRL; footer= END_X509_CRL; break;
02005         case DH_PARAM_TYPE: header= BEGIN_DH_PARAM; footer= END_DH_PARAM; break;
02006         case CERTREQ_TYPE:  header= BEGIN_CERT_REQ; footer= END_CERT_REQ; break;
02007         default:            header= BEGIN_RSA_PRIV; footer= END_RSA_PRIV; break;
02008     }
02009     
02010     switch (type) {
02011         case CA_TYPE:   dynamicType = DYNAMIC_TYPE_CA;   break;
02012         case CERT_TYPE: dynamicType = DYNAMIC_TYPE_CERT; break;
02013         case CRL_TYPE:  dynamicType = DYNAMIC_TYPE_CRL;  break;
02014         default:        dynamicType = DYNAMIC_TYPE_KEY;  break;
02015     }
02016 
02017     /* find header */
02018     for (;;) {
02019         headerEnd = XSTRNSTR((char*)buff, header, sz);
02020         
02021         if (headerEnd || type != PRIVATEKEY_TYPE) {
02022             break;
02023         } else if (header == BEGIN_RSA_PRIV) {
02024                    header =  BEGIN_PRIV_KEY;       footer = END_PRIV_KEY;
02025         } else if (header == BEGIN_PRIV_KEY) {
02026                    header =  BEGIN_ENC_PRIV_KEY;   footer = END_ENC_PRIV_KEY;
02027         } else if (header == BEGIN_ENC_PRIV_KEY) {
02028                    header =  BEGIN_EC_PRIV;        footer = END_EC_PRIV;
02029         } else if (header == BEGIN_ENC_PRIV_KEY) {
02030                    header =  BEGIN_DSA_PRIV;       footer = END_DSA_PRIV;
02031         } else
02032             break;
02033     }
02034 
02035     if (!headerEnd) {
02036         CYASSL_MSG("Couldn't find PEM header");
02037         return SSL_NO_PEM_HEADER;
02038     }
02039 
02040     headerEnd += XSTRLEN(header);
02041 
02042     /* eat end of line */
02043     if (headerEnd[0] == '\n')
02044         headerEnd++;
02045     else if (headerEnd[1] == '\n')
02046         headerEnd += 2;
02047     else
02048         return SSL_BAD_FILE;
02049 
02050     if (type == PRIVATEKEY_TYPE) {
02051         if (eccKey)
02052             *eccKey = header == BEGIN_EC_PRIV;      
02053     }
02054 
02055 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
02056     {
02057         /* remove encrypted header if there */
02058         char encHeader[] = "Proc-Type";
02059         char* line = XSTRNSTR(headerEnd, encHeader, PEM_LINE_LEN);
02060         if (line) {
02061             char* newline;
02062             char* finish;
02063             char* start  = XSTRNSTR(line, "DES", PEM_LINE_LEN);
02064 
02065             if (!start)
02066                 start = XSTRNSTR(line, "AES", PEM_LINE_LEN);
02067 
02068             if (!start) return SSL_BAD_FILE;
02069             if (!info)  return SSL_BAD_FILE;
02070 
02071             finish = XSTRNSTR(start, ",", PEM_LINE_LEN);
02072 
02073             if (start && finish && (start < finish)) {
02074                 newline = XSTRNSTR(finish, "\r", PEM_LINE_LEN);
02075 
02076                 XMEMCPY(info->name, start, finish - start);
02077                 info->name[finish - start] = 0;
02078                 XMEMCPY(info->iv, finish + 1, sizeof(info->iv));
02079 
02080                 if (!newline) newline = XSTRNSTR(finish, "\n", PEM_LINE_LEN);
02081                 if (newline && (newline > finish)) {
02082                     info->ivSz = (word32)(newline - (finish + 1));
02083                     info->set = 1;
02084                 }
02085                 else
02086                     return SSL_BAD_FILE;
02087             }
02088             else
02089                 return SSL_BAD_FILE;
02090 
02091             /* eat blank line */
02092             while (*newline == '\r' || *newline == '\n')
02093                 newline++;
02094             headerEnd = newline;
02095         }
02096     }
02097 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
02098 
02099     /* find footer */
02100     footerEnd = XSTRNSTR((char*)buff, footer, sz);
02101     if (!footerEnd)
02102         return SSL_BAD_FILE;
02103 
02104     consumedEnd = footerEnd + XSTRLEN(footer);
02105 
02106     if (consumedEnd < bufferEnd) {  /* handle no end of line on last line */
02107         /* eat end of line */
02108         if (consumedEnd[0] == '\n')
02109             consumedEnd++;
02110         else if (consumedEnd[1] == '\n')
02111             consumedEnd += 2;
02112         else
02113             return SSL_BAD_FILE;
02114     }
02115 
02116     if (info)
02117         info->consumed = (long)(consumedEnd - (char*)buff);
02118 
02119     /* set up der buffer */
02120     neededSz = (long)(footerEnd - headerEnd);
02121     if (neededSz > sz || neededSz < 0)
02122         return SSL_BAD_FILE;
02123 
02124     der->buffer = (byte*)XMALLOC(neededSz, heap, dynamicType);
02125     if (!der->buffer)
02126         return MEMORY_ERROR;
02127 
02128     der->length = (word32)neededSz;
02129 
02130     if (Base64_Decode((byte*)headerEnd, (word32)neededSz, der->buffer,
02131                                                               &der->length) < 0)
02132         return SSL_BAD_FILE;
02133 
02134     if (header == BEGIN_PRIV_KEY) {
02135         /* pkcs8 key, convert and adjust length */
02136         if ((ret = ToTraditional(der->buffer, der->length)) < 0)
02137             return ret;
02138 
02139         der->length = ret;
02140         return 0;
02141     }
02142 
02143 #if (defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)) && !defined(NO_PWDBASED)
02144     if (header == BEGIN_ENC_PRIV_KEY) {
02145         int   passwordSz;
02146     #ifdef CYASSL_SMALL_STACK
02147         char* password = NULL;
02148     #else
02149         char  password[80];
02150     #endif
02151 
02152         if (!info || !info->ctx || !info->ctx->passwd_cb)
02153             return SSL_BAD_FILE;  /* no callback error */
02154 
02155     #ifdef CYASSL_SMALL_STACK
02156         password = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02157         if (password == NULL)
02158             return MEMORY_E;
02159     #endif
02160         passwordSz = info->ctx->passwd_cb(password, sizeof(password), 0,
02161                                                            info->ctx->userdata);
02162         /* convert and adjust length */
02163         ret = ToTraditionalEnc(der->buffer, der->length, password, passwordSz);
02164 
02165     #ifdef CYASSL_SMALL_STACK
02166         XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02167     #endif
02168 
02169         if (ret < 0)
02170             return ret;
02171 
02172         der->length = ret;
02173         return 0;
02174     }
02175 #endif
02176 
02177     return 0;
02178 }
02179 
02180 
02181 /* process the buffer buff, legnth sz, into ctx of format and type
02182    used tracks bytes consumed, userChain specifies a user cert chain
02183    to pass during the handshake */
02184 static int ProcessBuffer(CYASSL_CTX* ctx, const unsigned char* buff,
02185                          long sz, int format, int type, CYASSL* ssl,
02186                          long* used, int userChain)
02187 {
02188     buffer        der;        /* holds DER or RAW (for NTRU) */
02189     int           ret;
02190     int           dynamicType = 0;
02191     int           eccKey = 0;
02192     int           rsaKey = 0;
02193     void*         heap = ctx ? ctx->heap : NULL;
02194 #ifdef CYASSL_SMALL_STACK
02195     EncryptedInfo* info = NULL;
02196 #else
02197     EncryptedInfo  info[1];
02198 #endif
02199 
02200     (void)dynamicType;
02201     (void)rsaKey;
02202 
02203     if (used)
02204         *used = sz;     /* used bytes default to sz, PEM chain may shorten*/
02205 
02206     if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM
02207                                     && format != SSL_FILETYPE_RAW)
02208         return SSL_BAD_FILETYPE;
02209 
02210     if (ctx == NULL && ssl == NULL)
02211         return BAD_FUNC_ARG;
02212 
02213     if (type == CA_TYPE)
02214         dynamicType = DYNAMIC_TYPE_CA;
02215     else if (type == CERT_TYPE)
02216         dynamicType = DYNAMIC_TYPE_CERT;
02217     else
02218         dynamicType = DYNAMIC_TYPE_KEY;
02219 
02220 #ifdef CYASSL_SMALL_STACK
02221     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
02222                                                        DYNAMIC_TYPE_TMP_BUFFER);
02223     if (info == NULL)
02224         return MEMORY_E;
02225 #endif
02226 
02227     info->set      = 0;
02228     info->ctx      = ctx;
02229     info->consumed = 0;
02230     der.buffer     = 0;
02231 
02232     if (format == SSL_FILETYPE_PEM) {
02233         ret = PemToDer(buff, sz, type, &der, heap, info, &eccKey);
02234         if (ret < 0) {
02235         #ifdef CYASSL_SMALL_STACK
02236             XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02237         #endif
02238             XFREE(der.buffer, heap, dynamicType);
02239             return ret;
02240         }
02241 
02242         if (used)
02243             *used = info->consumed;
02244 
02245         /* we may have a user cert chain, try to consume */
02246         if (userChain && type == CERT_TYPE && info->consumed < sz) {
02247         #ifdef CYASSL_SMALL_STACK
02248             byte   staticBuffer[1];                 /* force heap usage */
02249         #else
02250             byte   staticBuffer[FILE_BUFFER_SIZE];  /* tmp chain buffer */
02251         #endif
02252             byte*  chainBuffer = staticBuffer;
02253             byte*  shrinked    = NULL;   /* shrinked to size chainBuffer
02254                                           * or staticBuffer */
02255             int    dynamicBuffer = 0;
02256             word32 bufferSz = sizeof(staticBuffer);
02257             long   consumed = info->consumed;
02258             word32 idx = 0;
02259             int    gotOne = 0;
02260 
02261             if ( (sz - consumed) > (int)bufferSz) {
02262                 CYASSL_MSG("Growing Tmp Chain Buffer");
02263                 bufferSz = (word32)(sz - consumed);
02264                            /* will shrink to actual size */
02265                 chainBuffer = (byte*)XMALLOC(bufferSz, heap, DYNAMIC_TYPE_FILE);
02266                 if (chainBuffer == NULL) {
02267                 #ifdef CYASSL_SMALL_STACK
02268                     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02269                 #endif
02270                     XFREE(der.buffer, heap, dynamicType);
02271                     return MEMORY_E;
02272                 }
02273                 dynamicBuffer = 1;
02274             }
02275 
02276             CYASSL_MSG("Processing Cert Chain");
02277             while (consumed < sz) {
02278                 buffer part;
02279                 info->consumed = 0;
02280                 part.buffer = 0;
02281 
02282                 ret = PemToDer(buff + consumed, sz - consumed, type, &part,
02283                                                            heap, info, &eccKey);
02284                 if (ret == 0) {
02285                     gotOne = 1;
02286                     if ( (idx + part.length) > bufferSz) {
02287                         CYASSL_MSG("   Cert Chain bigger than buffer");
02288                         ret = BUFFER_E;
02289                     }
02290                     else {
02291                         c32to24(part.length, &chainBuffer[idx]);
02292                         idx += CERT_HEADER_SZ;
02293                         XMEMCPY(&chainBuffer[idx], part.buffer,part.length);
02294                         idx += part.length;
02295                         consumed  += info->consumed;
02296                         if (used)
02297                             *used += info->consumed;
02298                     }
02299                 }
02300 
02301                 XFREE(part.buffer, heap, dynamicType);
02302 
02303                 if (ret == SSL_NO_PEM_HEADER && gotOne) {
02304                     CYASSL_MSG("We got one good PEM so stuff at end ok");
02305                     break;
02306                 }
02307 
02308                 if (ret < 0) {
02309                     CYASSL_MSG("   Error in Cert in Chain");
02310                     if (dynamicBuffer)
02311                         XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
02312                 #ifdef CYASSL_SMALL_STACK
02313                     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02314                 #endif
02315                     XFREE(der.buffer, heap, dynamicType);
02316                     return ret;
02317                 }
02318                 CYASSL_MSG("   Consumed another Cert in Chain");
02319             }
02320             CYASSL_MSG("Finished Processing Cert Chain");
02321 
02322             /* only retain actual size used */
02323             shrinked = (byte*)XMALLOC(idx, heap, dynamicType);
02324             if (shrinked) {
02325                 if (ssl) {
02326                     if (ssl->buffers.certChain.buffer &&
02327                                                   ssl->buffers.weOwnCertChain) {
02328                         XFREE(ssl->buffers.certChain.buffer, heap,
02329                               dynamicType);
02330                     }
02331                     ssl->buffers.certChain.buffer = shrinked;
02332                     ssl->buffers.certChain.length = idx;
02333                     XMEMCPY(ssl->buffers.certChain.buffer, chainBuffer,idx);
02334                     ssl->buffers.weOwnCertChain = 1;
02335                 } else if (ctx) {
02336                     if (ctx->certChain.buffer)
02337                         XFREE(ctx->certChain.buffer, heap, dynamicType);
02338                     ctx->certChain.buffer = shrinked;
02339                     ctx->certChain.length = idx;
02340                     XMEMCPY(ctx->certChain.buffer, chainBuffer, idx);
02341                 }
02342             }
02343 
02344             if (dynamicBuffer)
02345                 XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
02346 
02347             if (shrinked == NULL) {
02348             #ifdef CYASSL_SMALL_STACK
02349                 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02350             #endif
02351                 XFREE(der.buffer, heap, dynamicType);
02352                 return MEMORY_E;
02353             }
02354         }
02355     }
02356     else {  /* ASN1 (DER) or RAW (NTRU) */
02357         der.buffer = (byte*) XMALLOC(sz, heap, dynamicType);
02358         if (!der.buffer) {
02359         #ifdef CYASSL_SMALL_STACK
02360             XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02361         #endif
02362             return MEMORY_ERROR;
02363         }
02364 
02365         XMEMCPY(der.buffer, buff, sz);
02366         der.length = (word32)sz;
02367     }
02368 
02369 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
02370     if (info->set) {
02371         /* decrypt */
02372         int   passwordSz;
02373 #ifdef CYASSL_SMALL_STACK
02374         char* password = NULL;
02375         byte* key      = NULL;
02376         byte* iv       = NULL;
02377 #else
02378         char  password[80];
02379         byte  key[AES_256_KEY_SIZE];
02380         byte  iv[AES_IV_SIZE];
02381 #endif
02382 
02383     #ifdef CYASSL_SMALL_STACK
02384         password = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02385         key      = (byte*)XMALLOC(AES_256_KEY_SIZE, NULL,
02386                                                    DYNAMIC_TYPE_TMP_BUFFER);
02387         iv       = (byte*)XMALLOC(AES_IV_SIZE, NULL, 
02388                                                    DYNAMIC_TYPE_TMP_BUFFER);
02389 
02390         if (password == NULL || key == NULL || iv == NULL) {
02391             XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02392             XFREE(key,      NULL, DYNAMIC_TYPE_TMP_BUFFER);
02393             XFREE(iv,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
02394             ret = MEMORY_E;
02395         }
02396         else
02397     #endif
02398         if (!ctx || !ctx->passwd_cb) {
02399             ret = NO_PASSWORD;
02400         }
02401         else {
02402             passwordSz = ctx->passwd_cb(password, sizeof(password), 0,
02403                                                              ctx->userdata);
02404 
02405             /* use file's salt for key derivation, hex decode first */
02406             if (Base16_Decode(info->iv, info->ivSz, info->iv, &info->ivSz)
02407                                                                          != 0) {
02408                 ret = ASN_INPUT_E;
02409             }
02410             else if ((ret = EVP_BytesToKey(info->name, "MD5", info->iv,
02411                            (byte*)password, passwordSz, 1, key, iv)) <= 0) {
02412                 /* empty */
02413             }
02414             else if (XSTRNCMP(info->name, "DES-CBC", 7) == 0) {
02415                 ret = Des_CbcDecryptWithKey(der.buffer, der.buffer, der.length,
02416                                                                  key, info->iv);
02417             }
02418             else if (XSTRNCMP(info->name, "DES-EDE3-CBC", 13) == 0) {
02419                 ret = Des3_CbcDecryptWithKey(der.buffer, der.buffer, der.length,
02420                                                                  key, info->iv);
02421             }
02422             else if (XSTRNCMP(info->name, "AES-128-CBC", 13) == 0) {
02423                 ret = AesCbcDecryptWithKey(der.buffer, der.buffer, der.length,
02424                                                key, AES_128_KEY_SIZE, info->iv);
02425             }
02426             else if (XSTRNCMP(info->name, "AES-192-CBC", 13) == 0) {
02427                 ret = AesCbcDecryptWithKey(der.buffer, der.buffer, der.length,
02428                                                key, AES_192_KEY_SIZE, info->iv);
02429             }
02430             else if (XSTRNCMP(info->name, "AES-256-CBC", 13) == 0) {
02431                 ret = AesCbcDecryptWithKey(der.buffer, der.buffer, der.length,
02432                                                key, AES_256_KEY_SIZE, info->iv);
02433             }
02434             else {
02435                 ret = SSL_BAD_FILE;
02436             }
02437         }
02438 
02439     #ifdef CYASSL_SMALL_STACK
02440         XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02441         XFREE(key,      NULL, DYNAMIC_TYPE_TMP_BUFFER);
02442         XFREE(iv,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
02443     #endif
02444 
02445         if (ret != 0) {
02446         #ifdef CYASSL_SMALL_STACK
02447             XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02448         #endif
02449             XFREE(der.buffer, heap, dynamicType);
02450             return ret;
02451         }
02452     }
02453 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
02454 
02455 #ifdef CYASSL_SMALL_STACK
02456     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02457 #endif
02458 
02459     if (type == CA_TYPE) {
02460         if (ctx == NULL) {
02461             CYASSL_MSG("Need context for CA load");
02462             XFREE(der.buffer, heap, dynamicType);
02463             return BAD_FUNC_ARG;
02464         }
02465         return AddCA(ctx->cm, der, CYASSL_USER_CA, ctx->verifyPeer);
02466                                                       /* takes der over */
02467     }
02468     else if (type == CERT_TYPE) {
02469         if (ssl) {
02470             if (ssl->buffers.weOwnCert && ssl->buffers.certificate.buffer)
02471                 XFREE(ssl->buffers.certificate.buffer, heap, dynamicType);
02472             ssl->buffers.certificate = der;
02473             ssl->buffers.weOwnCert = 1;
02474         }
02475         else if (ctx) {
02476             if (ctx->certificate.buffer)
02477                 XFREE(ctx->certificate.buffer, heap, dynamicType);
02478             ctx->certificate = der;     /* takes der over */
02479         }
02480     }
02481     else if (type == PRIVATEKEY_TYPE) {
02482         if (ssl) {
02483             if (ssl->buffers.weOwnKey && ssl->buffers.key.buffer)
02484                 XFREE(ssl->buffers.key.buffer, heap, dynamicType);
02485             ssl->buffers.key = der;
02486             ssl->buffers.weOwnKey = 1;
02487         }
02488         else if (ctx) {
02489             if (ctx->privateKey.buffer)
02490                 XFREE(ctx->privateKey.buffer, heap, dynamicType);
02491             ctx->privateKey = der;      /* takes der over */
02492         }
02493     }
02494     else {
02495         XFREE(der.buffer, heap, dynamicType);
02496         return SSL_BAD_CERTTYPE;
02497     }
02498 
02499     if (type == PRIVATEKEY_TYPE && format != SSL_FILETYPE_RAW) {
02500     #ifndef NO_RSA
02501         if (!eccKey) {
02502             /* make sure RSA key can be used */
02503             word32 idx = 0;
02504         #ifdef CYASSL_SMALL_STACK
02505             RsaKey* key = NULL;
02506         #else
02507             RsaKey  key[1];
02508         #endif
02509 
02510         #ifdef CYASSL_SMALL_STACK
02511             key = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL,
02512                                                        DYNAMIC_TYPE_TMP_BUFFER);
02513             if (key == NULL)
02514                 return MEMORY_E;
02515         #endif
02516 
02517             ret = InitRsaKey(key, 0);
02518             if (ret == 0) {
02519                 if (RsaPrivateKeyDecode(der.buffer, &idx, key, der.length) !=
02520                                                                             0) {
02521                 #ifdef HAVE_ECC
02522                     /* could have DER ECC (or pkcs8 ecc), no easy way to tell */
02523                     eccKey = 1;  /* so try it out */
02524                 #endif
02525                     if (!eccKey)
02526                         ret = SSL_BAD_FILE;
02527                 } else {
02528                     rsaKey = 1;
02529                     (void)rsaKey;  /* for no ecc builds */
02530                 }
02531             }
02532 
02533             FreeRsaKey(key);
02534 
02535         #ifdef CYASSL_SMALL_STACK
02536             XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02537         #endif
02538 
02539             if (ret != 0)
02540                 return ret;
02541         }
02542     #endif
02543     #ifdef HAVE_ECC
02544         if (!rsaKey) {
02545             /* make sure ECC key can be used */
02546             word32  idx = 0;
02547             ecc_key key;
02548 
02549             ecc_init(&key);
02550             if (EccPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) {
02551                 ecc_free(&key);
02552                 return SSL_BAD_FILE;
02553             }
02554             ecc_free(&key);
02555             eccKey = 1;
02556             if (ctx)
02557                 ctx->haveStaticECC = 1;
02558             if (ssl)
02559                 ssl->options.haveStaticECC = 1;
02560         }
02561     #endif /* HAVE_ECC */
02562     }
02563     else if (type == CERT_TYPE) {
02564     #ifdef CYASSL_SMALL_STACK
02565         DecodedCert* cert = NULL;
02566     #else
02567         DecodedCert  cert[1];
02568     #endif
02569 
02570     #ifdef CYASSL_SMALL_STACK
02571         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
02572                                                        DYNAMIC_TYPE_TMP_BUFFER);
02573         if (cert == NULL)
02574             return MEMORY_E;
02575     #endif
02576 
02577         CYASSL_MSG("Checking cert signature type");
02578         InitDecodedCert(cert, der.buffer, der.length, heap);
02579 
02580         if (DecodeToKey(cert, 0) < 0) {
02581             CYASSL_MSG("Decode to key failed");
02582         #ifdef CYASSL_SMALL_STACK
02583             XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02584         #endif
02585             return SSL_BAD_FILE;
02586         }
02587         switch (cert->signatureOID) {
02588             case CTC_SHAwECDSA:
02589             case CTC_SHA256wECDSA:
02590             case CTC_SHA384wECDSA:
02591             case CTC_SHA512wECDSA:
02592                 CYASSL_MSG("ECDSA cert signature");
02593                 if (ctx)
02594                     ctx->haveECDSAsig = 1;
02595                 if (ssl)
02596                     ssl->options.haveECDSAsig = 1;
02597                 break;
02598             default:
02599                 CYASSL_MSG("Not ECDSA cert signature");
02600                 break;
02601         }
02602 
02603     #ifdef HAVE_ECC
02604         if (ctx)
02605             ctx->pkCurveOID = cert->pkCurveOID;
02606         if (ssl)
02607             ssl->pkCurveOID = cert->pkCurveOID;
02608     #endif
02609 
02610         FreeDecodedCert(cert);
02611     #ifdef CYASSL_SMALL_STACK
02612         XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02613     #endif
02614     }
02615 
02616     return SSL_SUCCESS;
02617 }
02618 
02619 
02620 /* CA PEM file for verification, may have multiple/chain certs to process */
02621 static int ProcessChainBuffer(CYASSL_CTX* ctx, const unsigned char* buff,
02622                             long sz, int format, int type, CYASSL* ssl)
02623 {
02624     long used   = 0;
02625     int  ret    = 0;
02626     int  gotOne = 0;
02627 
02628     CYASSL_MSG("Processing CA PEM file");
02629     while (used < sz) {
02630         long consumed = 0;
02631 
02632         ret = ProcessBuffer(ctx, buff + used, sz - used, format, type, ssl,
02633                             &consumed, 0);
02634 
02635         if (ret == SSL_NO_PEM_HEADER && gotOne) {
02636             CYASSL_MSG("We got one good PEM file so stuff at end ok");
02637             ret = SSL_SUCCESS;
02638             break;
02639         }
02640 
02641         if (ret < 0)
02642             break;
02643 
02644         CYASSL_MSG("   Processed a CA");
02645         gotOne = 1;
02646         used += consumed;
02647     }
02648 
02649     return ret;
02650 }
02651 
02652 
02653 /* Verify the ceritficate, SSL_SUCCESS for ok, < 0 for error */
02654 int CyaSSL_CertManagerVerifyBuffer(CYASSL_CERT_MANAGER* cm, const byte* buff,
02655                                    long sz, int format)
02656 {
02657     int ret = 0;
02658     buffer der;
02659 #ifdef CYASSL_SMALL_STACK
02660     DecodedCert* cert = NULL;
02661 #else
02662     DecodedCert  cert[1];
02663 #endif
02664 
02665     CYASSL_ENTER("CyaSSL_CertManagerVerifyBuffer");
02666 
02667 #ifdef CYASSL_SMALL_STACK
02668     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
02669                                                        DYNAMIC_TYPE_TMP_BUFFER);
02670     if (cert == NULL)
02671         return MEMORY_E;
02672 #endif
02673 
02674     der.buffer = NULL;
02675     der.length = 0;
02676 
02677     if (format == SSL_FILETYPE_PEM) {
02678         int eccKey = 0; /* not used */
02679     #ifdef CYASSL_SMALL_STACK
02680         EncryptedInfo* info = NULL;
02681     #else
02682         EncryptedInfo  info[1];
02683     #endif
02684 
02685     #ifdef CYASSL_SMALL_STACK
02686         info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
02687                                                        DYNAMIC_TYPE_TMP_BUFFER);
02688         if (info == NULL) {
02689             XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02690             return MEMORY_E;
02691         }
02692     #endif
02693 
02694         info->set      = 0;
02695         info->ctx      = NULL;
02696         info->consumed = 0;
02697 
02698         ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, info, &eccKey);
02699 
02700         if (ret == 0)
02701             InitDecodedCert(cert, der.buffer, der.length, cm->heap);
02702 
02703     #ifdef CYASSL_SMALL_STACK
02704         XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02705     #endif
02706     }
02707     else
02708         InitDecodedCert(cert, (byte*)buff, (word32)sz, cm->heap);
02709 
02710     if (ret == 0)
02711         ret = ParseCertRelative(cert, CERT_TYPE, 1, cm);
02712 
02713 #ifdef HAVE_CRL
02714     if (ret == 0 && cm->crlEnabled)
02715         ret = CheckCertCRL(cm->crl, cert);
02716 #endif
02717 
02718     FreeDecodedCert(cert);
02719 
02720     XFREE(der.buffer, cm->heap, DYNAMIC_TYPE_CERT);
02721 #ifdef CYASSL_SMALL_STACK
02722     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02723 #endif
02724 
02725     return ret == 0 ? SSL_SUCCESS : ret;
02726 }
02727 
02728 
02729 /* turn on OCSP if off and compiled in, set options */
02730 int CyaSSL_CertManagerEnableOCSP(CYASSL_CERT_MANAGER* cm, int options)
02731 {
02732     int ret = SSL_SUCCESS;
02733 
02734     (void)options;
02735 
02736     CYASSL_ENTER("CyaSSL_CertManagerEnableOCSP");
02737     if (cm == NULL)
02738         return BAD_FUNC_ARG;
02739 
02740     #ifdef HAVE_OCSP
02741         if (cm->ocsp == NULL) {
02742             cm->ocsp = (CYASSL_OCSP*)XMALLOC(sizeof(CYASSL_OCSP), cm->heap,
02743                                                              DYNAMIC_TYPE_OCSP);
02744             if (cm->ocsp == NULL)
02745                 return MEMORY_E;
02746 
02747             if (InitOCSP(cm->ocsp, cm) != 0) {
02748                 CYASSL_MSG("Init OCSP failed");
02749                 FreeOCSP(cm->ocsp, 1);
02750                 cm->ocsp = NULL;
02751                 return SSL_FAILURE;
02752             }
02753         }
02754         cm->ocspEnabled = 1;
02755         if (options & CYASSL_OCSP_URL_OVERRIDE)
02756             cm->ocspUseOverrideURL = 1;
02757         if (options & CYASSL_OCSP_NO_NONCE)
02758             cm->ocspSendNonce = 0;
02759         else
02760             cm->ocspSendNonce = 1;
02761         #ifndef CYASSL_USER_IO
02762             cm->ocspIOCb = EmbedOcspLookup;
02763             cm->ocspRespFreeCb = EmbedOcspRespFree;
02764         #endif /* CYASSL_USER_IO */
02765     #else
02766         ret = NOT_COMPILED_IN;
02767     #endif
02768 
02769     return ret;
02770 }
02771 
02772 
02773 int CyaSSL_CertManagerDisableOCSP(CYASSL_CERT_MANAGER* cm)
02774 {
02775     CYASSL_ENTER("CyaSSL_CertManagerDisableOCSP");
02776     if (cm == NULL)
02777         return BAD_FUNC_ARG;
02778 
02779     cm->ocspEnabled = 0;
02780 
02781     return SSL_SUCCESS;
02782 }
02783 
02784 
02785 #ifdef HAVE_OCSP
02786 
02787 
02788 /* check CRL if enabled, SSL_SUCCESS  */
02789 int CyaSSL_CertManagerCheckOCSP(CYASSL_CERT_MANAGER* cm, byte* der, int sz)
02790 {
02791     int ret;
02792 #ifdef CYASSL_SMALL_STACK
02793     DecodedCert* cert = NULL;
02794 #else
02795     DecodedCert  cert[1];
02796 #endif
02797 
02798     CYASSL_ENTER("CyaSSL_CertManagerCheckOCSP");
02799 
02800     if (cm == NULL)
02801         return BAD_FUNC_ARG;
02802 
02803     if (cm->ocspEnabled == 0)
02804         return SSL_SUCCESS;
02805 
02806 #ifdef CYASSL_SMALL_STACK
02807     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
02808                                                        DYNAMIC_TYPE_TMP_BUFFER);
02809     if (cert == NULL)
02810         return MEMORY_E;
02811 #endif
02812 
02813     InitDecodedCert(cert, der, sz, NULL);
02814 
02815     if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, cm)) != 0) {
02816         CYASSL_MSG("ParseCert failed");
02817     }
02818     else if ((ret = CheckCertOCSP(cm->ocsp, cert)) != 0) {
02819         CYASSL_MSG("CheckCertOCSP failed");
02820     }
02821 
02822     FreeDecodedCert(cert);
02823 #ifdef CYASSL_SMALL_STACK
02824     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02825 #endif
02826 
02827     return ret == 0 ? SSL_SUCCESS : ret;
02828 }
02829 
02830 
02831 int CyaSSL_CertManagerSetOCSPOverrideURL(CYASSL_CERT_MANAGER* cm,
02832                                                                 const char* url)
02833 {
02834     CYASSL_ENTER("CyaSSL_CertManagerSetOCSPOverrideURL");
02835     if (cm == NULL)
02836         return BAD_FUNC_ARG;
02837 
02838     XFREE(cm->ocspOverrideURL, cm->heap, 0);
02839     if (url != NULL) {
02840         int urlSz = (int)XSTRLEN(url) + 1;
02841         cm->ocspOverrideURL = (char*)XMALLOC(urlSz, cm->heap, 0);
02842         if (cm->ocspOverrideURL != NULL) {
02843             XMEMCPY(cm->ocspOverrideURL, url, urlSz);
02844         }
02845         else
02846             return MEMORY_E;
02847     }
02848     else
02849         cm->ocspOverrideURL = NULL;
02850 
02851     return SSL_SUCCESS;
02852 }
02853 
02854 
02855 int CyaSSL_CertManagerSetOCSP_Cb(CYASSL_CERT_MANAGER* cm,
02856                         CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
02857 {
02858     CYASSL_ENTER("CyaSSL_CertManagerSetOCSP_Cb");
02859     if (cm == NULL)
02860         return BAD_FUNC_ARG;
02861 
02862     cm->ocspIOCb = ioCb;
02863     cm->ocspRespFreeCb = respFreeCb;
02864     cm->ocspIOCtx = ioCbCtx;
02865 
02866     return SSL_SUCCESS;
02867 }
02868 
02869 
02870 int CyaSSL_EnableOCSP(CYASSL* ssl, int options)
02871 {
02872     CYASSL_ENTER("CyaSSL_EnableOCSP");
02873     if (ssl)
02874         return CyaSSL_CertManagerEnableOCSP(ssl->ctx->cm, options);
02875     else
02876         return BAD_FUNC_ARG;
02877 }
02878 
02879 
02880 int CyaSSL_DisableOCSP(CYASSL* ssl)
02881 {
02882     CYASSL_ENTER("CyaSSL_DisableOCSP");
02883     if (ssl)
02884         return CyaSSL_CertManagerDisableOCSP(ssl->ctx->cm);
02885     else
02886         return BAD_FUNC_ARG;
02887 }
02888 
02889 
02890 int CyaSSL_SetOCSP_OverrideURL(CYASSL* ssl, const char* url)
02891 {
02892     CYASSL_ENTER("CyaSSL_SetOCSP_OverrideURL");
02893     if (ssl)
02894         return CyaSSL_CertManagerSetOCSPOverrideURL(ssl->ctx->cm, url);
02895     else
02896         return BAD_FUNC_ARG;
02897 }
02898 
02899 
02900 int CyaSSL_SetOCSP_Cb(CYASSL* ssl,
02901                         CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
02902 {
02903     CYASSL_ENTER("CyaSSL_SetOCSP_Cb");
02904     if (ssl)
02905         return CyaSSL_CertManagerSetOCSP_Cb(ssl->ctx->cm,
02906                                                      ioCb, respFreeCb, ioCbCtx);
02907     else
02908         return BAD_FUNC_ARG;
02909 }
02910 
02911 
02912 int CyaSSL_CTX_EnableOCSP(CYASSL_CTX* ctx, int options)
02913 {
02914     CYASSL_ENTER("CyaSSL_CTX_EnableOCSP");
02915     if (ctx)
02916         return CyaSSL_CertManagerEnableOCSP(ctx->cm, options);
02917     else
02918         return BAD_FUNC_ARG;
02919 }
02920 
02921 
02922 int CyaSSL_CTX_DisableOCSP(CYASSL_CTX* ctx)
02923 {
02924     CYASSL_ENTER("CyaSSL_CTX_DisableOCSP");
02925     if (ctx)
02926         return CyaSSL_CertManagerDisableOCSP(ctx->cm);
02927     else
02928         return BAD_FUNC_ARG;
02929 }
02930 
02931 
02932 int CyaSSL_CTX_SetOCSP_OverrideURL(CYASSL_CTX* ctx, const char* url)
02933 {
02934     CYASSL_ENTER("CyaSSL_SetOCSP_OverrideURL");
02935     if (ctx)
02936         return CyaSSL_CertManagerSetOCSPOverrideURL(ctx->cm, url);
02937     else
02938         return BAD_FUNC_ARG;
02939 }
02940 
02941 
02942 int CyaSSL_CTX_SetOCSP_Cb(CYASSL_CTX* ctx,
02943                         CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
02944 {
02945     CYASSL_ENTER("CyaSSL_CTX_SetOCSP_Cb");
02946     if (ctx)
02947         return CyaSSL_CertManagerSetOCSP_Cb(ctx->cm, ioCb, respFreeCb, ioCbCtx);
02948     else
02949         return BAD_FUNC_ARG;
02950 }
02951 
02952 
02953 #endif /* HAVE_OCSP */
02954 
02955 
02956 #ifndef NO_FILESYSTEM
02957 
02958     #if defined(CYASSL_MDK_ARM)
02959         extern FILE * CyaSSL_fopen(const char *name, const char *mode) ;
02960         #define XFOPEN     CyaSSL_fopen
02961     #else
02962         #define XFOPEN     fopen
02963     #endif
02964 
02965 /* process a file with name fname into ctx of format and type
02966    userChain specifies a user certificate chain to pass during handshake */
02967 int ProcessFile(CYASSL_CTX* ctx, const char* fname, int format, int type,
02968                 CYASSL* ssl, int userChain, CYASSL_CRL* crl)
02969 {
02970 #ifdef CYASSL_SMALL_STACK
02971     byte   staticBuffer[1]; /* force heap usage */
02972 #else
02973     byte   staticBuffer[FILE_BUFFER_SIZE];
02974 #endif
02975     byte*  myBuffer = staticBuffer;
02976     int    dynamic = 0;
02977     int    ret;
02978     long   sz = 0;
02979     XFILE  file;
02980     void*  heapHint = ctx ? ctx->heap : NULL;
02981 
02982     (void)crl;
02983     (void)heapHint;
02984 
02985     if (fname == NULL) return SSL_BAD_FILE;
02986 
02987     file = XFOPEN(fname, "rb");
02988     if (file == XBADFILE) return SSL_BAD_FILE;
02989     XFSEEK(file, 0, XSEEK_END);
02990     sz = XFTELL(file);
02991     XREWIND(file);
02992 
02993     if (sz > (long)sizeof(staticBuffer)) {
02994         CYASSL_MSG("Getting dynamic buffer");
02995         myBuffer = (byte*)XMALLOC(sz, heapHint, DYNAMIC_TYPE_FILE);
02996         if (myBuffer == NULL) {
02997             XFCLOSE(file);
02998             return SSL_BAD_FILE;
02999         }
03000         dynamic = 1;
03001     }
03002     else if (sz < 0) {
03003         XFCLOSE(file);
03004         return SSL_BAD_FILE;
03005     }
03006 
03007     if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
03008         ret = SSL_BAD_FILE;
03009     else {
03010         if (type == CA_TYPE && format == SSL_FILETYPE_PEM)
03011             ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl);
03012 #ifdef HAVE_CRL
03013         else if (type == CRL_TYPE)
03014             ret = BufferLoadCRL(crl, myBuffer, sz, format);
03015 #endif
03016         else
03017             ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL,
03018                                 userChain);
03019     }
03020 
03021     XFCLOSE(file);
03022     if (dynamic)
03023         XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
03024 
03025     return ret;
03026 }
03027 
03028 
03029 /* loads file then loads each file in path, no c_rehash */
03030 int CyaSSL_CTX_load_verify_locations(CYASSL_CTX* ctx, const char* file,
03031                                      const char* path)
03032 {
03033     int ret = SSL_SUCCESS;
03034 
03035     CYASSL_ENTER("CyaSSL_CTX_load_verify_locations");
03036     (void)path;
03037 
03038     if (ctx == NULL || (file == NULL && path == NULL) )
03039         return SSL_FAILURE;
03040 
03041     if (file)
03042         ret = ProcessFile(ctx, file, SSL_FILETYPE_PEM, CA_TYPE, NULL, 0, NULL);
03043 
03044     if (ret == SSL_SUCCESS && path) {
03045         /* try to load each regular file in path */
03046     #ifdef USE_WINDOWS_API
03047         WIN32_FIND_DATAA FindFileData;
03048         HANDLE hFind;
03049     #ifdef CYASSL_SMALL_STACK
03050         char*  name = NULL;
03051     #else
03052         char   name[MAX_FILENAME_SZ];
03053     #endif
03054 
03055     #ifdef CYASSL_SMALL_STACK
03056         name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03057         if (name == NULL)
03058             return MEMORY_E;
03059     #endif
03060 
03061         XMEMSET(name, 0, MAX_FILENAME_SZ);
03062         XSTRNCPY(name, path, MAX_FILENAME_SZ - 4);
03063         XSTRNCAT(name, "\\*", 3);
03064 
03065         hFind = FindFirstFileA(name, &FindFileData);
03066         if (hFind == INVALID_HANDLE_VALUE) {
03067             CYASSL_MSG("FindFirstFile for path verify locations failed");
03068         #ifdef CYASSL_SMALL_STACK
03069             XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03070         #endif
03071             return BAD_PATH_ERROR;
03072         }
03073 
03074         do {
03075             if (FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
03076                 XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 3);
03077                 XSTRNCAT(name, "\\", 2);
03078                 XSTRNCAT(name, FindFileData.cFileName, MAX_FILENAME_SZ/2);
03079 
03080                 ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0,
03081                                                                           NULL);
03082             }
03083         } while (ret == SSL_SUCCESS && FindNextFileA(hFind, &FindFileData));
03084 
03085     #ifdef CYASSL_SMALL_STACK
03086         XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03087     #endif
03088 
03089         FindClose(hFind);
03090     #elif !defined(NO_CYASSL_DIR)
03091         struct dirent* entry;
03092         DIR*   dir = opendir(path);
03093     #ifdef CYASSL_SMALL_STACK
03094         char*  name = NULL;
03095     #else
03096         char   name[MAX_FILENAME_SZ];
03097     #endif
03098 
03099         if (dir == NULL) {
03100             CYASSL_MSG("opendir path verify locations failed");
03101             return BAD_PATH_ERROR;
03102         }
03103 
03104     #ifdef CYASSL_SMALL_STACK
03105         name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03106         if (name == NULL)
03107             return MEMORY_E;
03108     #endif
03109 
03110         while ( ret == SSL_SUCCESS && (entry = readdir(dir)) != NULL) {
03111             struct stat s;
03112 
03113             XMEMSET(name, 0, MAX_FILENAME_SZ);
03114             XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
03115             XSTRNCAT(name, "/", 1);
03116             XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
03117 
03118             if (stat(name, &s) != 0) {
03119                 CYASSL_MSG("stat on name failed");
03120                 ret = BAD_PATH_ERROR;
03121             } else if (s.st_mode & S_IFREG)
03122                 ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0,
03123                                                                           NULL);
03124         }
03125 
03126     #ifdef CYASSL_SMALL_STACK
03127         XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03128     #endif
03129 
03130         closedir(dir);
03131     #endif
03132     }
03133 
03134     return ret;
03135 }
03136 
03137 
03138 /* Verify the ceritficate, SSL_SUCCESS for ok, < 0 for error */
03139 int CyaSSL_CertManagerVerify(CYASSL_CERT_MANAGER* cm, const char* fname,
03140                              int format)
03141 {
03142     int    ret = SSL_FATAL_ERROR;
03143 #ifdef CYASSL_SMALL_STACK
03144     byte   staticBuffer[1]; /* force heap usage */
03145 #else
03146     byte   staticBuffer[FILE_BUFFER_SIZE];
03147 #endif
03148     byte*  myBuffer = staticBuffer;
03149     int    dynamic = 0;
03150     long   sz = 0;
03151     XFILE  file = XFOPEN(fname, "rb");
03152 
03153     CYASSL_ENTER("CyaSSL_CertManagerVerify");
03154 
03155     if (file == XBADFILE) return SSL_BAD_FILE;
03156     XFSEEK(file, 0, XSEEK_END);
03157     sz = XFTELL(file);
03158     XREWIND(file);
03159 
03160     if (sz > MAX_CYASSL_FILE_SIZE || sz < 0) {
03161         CYASSL_MSG("CertManagerVerify file bad size");
03162         XFCLOSE(file);
03163         return SSL_BAD_FILE;
03164     }
03165 
03166     if (sz > (long)sizeof(staticBuffer)) {
03167         CYASSL_MSG("Getting dynamic buffer");
03168         myBuffer = (byte*) XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE);
03169         if (myBuffer == NULL) {
03170             XFCLOSE(file);
03171             return SSL_BAD_FILE;
03172         }
03173         dynamic = 1;
03174     }
03175 
03176     if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
03177         ret = SSL_BAD_FILE;
03178     else
03179         ret = CyaSSL_CertManagerVerifyBuffer(cm, myBuffer, sz, format);
03180 
03181     XFCLOSE(file);
03182     if (dynamic)
03183         XFREE(myBuffer, cm->heap, DYNAMIC_TYPE_FILE);
03184 
03185     return ret;
03186 }
03187 
03188 
03189 static INLINE CYASSL_METHOD* cm_pick_method(void)
03190 {
03191     #ifndef NO_CYASSL_CLIENT
03192         #ifdef NO_OLD_TLS
03193             return CyaTLSv1_2_client_method();
03194         #else
03195             return CyaSSLv3_client_method();
03196         #endif
03197     #elif !defined(NO_CYASSL_SERVER)
03198         #ifdef NO_OLD_TLS
03199             return CyaTLSv1_2_server_method();
03200         #else
03201             return CyaSSLv3_server_method();
03202         #endif
03203     #else
03204         return NULL;
03205     #endif
03206 }
03207 
03208 
03209 /* like load verify locations, 1 for success, < 0 for error */
03210 int CyaSSL_CertManagerLoadCA(CYASSL_CERT_MANAGER* cm, const char* file,
03211                              const char* path)
03212 {
03213     int ret = SSL_FATAL_ERROR;
03214     CYASSL_CTX* tmp;
03215 
03216     CYASSL_ENTER("CyaSSL_CertManagerLoadCA");
03217 
03218     if (cm == NULL) {
03219         CYASSL_MSG("No CertManager error");
03220         return ret;
03221     }
03222     tmp = CyaSSL_CTX_new(cm_pick_method());
03223 
03224     if (tmp == NULL) {
03225         CYASSL_MSG("CTX new failed");
03226         return ret;
03227     }
03228 
03229     /* for tmp use */
03230     CyaSSL_CertManagerFree(tmp->cm);
03231     tmp->cm = cm;
03232 
03233     ret = CyaSSL_CTX_load_verify_locations(tmp, file, path);
03234 
03235     /* don't loose our good one */
03236     tmp->cm = NULL;
03237     CyaSSL_CTX_free(tmp);
03238 
03239     return ret;
03240 }
03241 
03242 
03243 
03244 /* turn on CRL if off and compiled in, set options */
03245 int CyaSSL_CertManagerEnableCRL(CYASSL_CERT_MANAGER* cm, int options)
03246 {
03247     int ret = SSL_SUCCESS;
03248 
03249     (void)options;
03250 
03251     CYASSL_ENTER("CyaSSL_CertManagerEnableCRL");
03252     if (cm == NULL)
03253         return BAD_FUNC_ARG;
03254 
03255     #ifdef HAVE_CRL
03256         if (cm->crl == NULL) {
03257             cm->crl = (CYASSL_CRL*)XMALLOC(sizeof(CYASSL_CRL), cm->heap,
03258                                            DYNAMIC_TYPE_CRL);
03259             if (cm->crl == NULL)
03260                 return MEMORY_E;
03261 
03262             if (InitCRL(cm->crl, cm) != 0) {
03263                 CYASSL_MSG("Init CRL failed");
03264                 FreeCRL(cm->crl, 1);
03265                 cm->crl = NULL;
03266                 return SSL_FAILURE;
03267             }
03268         }
03269         cm->crlEnabled = 1;
03270         if (options & CYASSL_CRL_CHECKALL)
03271             cm->crlCheckAll = 1;
03272     #else
03273         ret = NOT_COMPILED_IN;
03274     #endif
03275 
03276     return ret;
03277 }
03278 
03279 
03280 int CyaSSL_CertManagerDisableCRL(CYASSL_CERT_MANAGER* cm)
03281 {
03282     CYASSL_ENTER("CyaSSL_CertManagerDisableCRL");
03283     if (cm == NULL)
03284         return BAD_FUNC_ARG;
03285 
03286     cm->crlEnabled = 0;
03287 
03288     return SSL_SUCCESS;
03289 }
03290 
03291 
03292 int CyaSSL_CTX_check_private_key(CYASSL_CTX* ctx)
03293 {
03294     /* TODO: check private against public for RSA match */
03295     (void)ctx;
03296     CYASSL_ENTER("SSL_CTX_check_private_key");
03297     return SSL_SUCCESS;
03298 }
03299 
03300 
03301 #ifdef HAVE_CRL
03302 
03303 
03304 /* check CRL if enabled, SSL_SUCCESS  */
03305 int CyaSSL_CertManagerCheckCRL(CYASSL_CERT_MANAGER* cm, byte* der, int sz)
03306 {
03307     int ret = 0;
03308 #ifdef CYASSL_SMALL_STACK
03309     DecodedCert* cert = NULL;
03310 #else
03311     DecodedCert  cert[1];
03312 #endif
03313 
03314     CYASSL_ENTER("CyaSSL_CertManagerCheckCRL");
03315 
03316     if (cm == NULL)
03317         return BAD_FUNC_ARG;
03318 
03319     if (cm->crlEnabled == 0)
03320         return SSL_SUCCESS;
03321 
03322 #ifdef CYASSL_SMALL_STACK
03323     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
03324                                                        DYNAMIC_TYPE_TMP_BUFFER);
03325     if (cert == NULL)
03326         return MEMORY_E;
03327 #endif
03328 
03329     InitDecodedCert(cert, der, sz, NULL);
03330 
03331     if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, cm)) != 0) {
03332         CYASSL_MSG("ParseCert failed");
03333     }
03334     else if ((ret = CheckCertCRL(cm->crl, cert)) != 0) {
03335         CYASSL_MSG("CheckCertCRL failed");
03336     }
03337 
03338     FreeDecodedCert(cert);
03339 #ifdef CYASSL_SMALL_STACK
03340     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03341 #endif
03342 
03343     return ret == 0 ? SSL_SUCCESS : ret;
03344 }
03345 
03346 
03347 int CyaSSL_CertManagerSetCRL_Cb(CYASSL_CERT_MANAGER* cm, CbMissingCRL cb)
03348 {
03349     CYASSL_ENTER("CyaSSL_CertManagerSetCRL_Cb");
03350     if (cm == NULL)
03351         return BAD_FUNC_ARG;
03352 
03353     cm->cbMissingCRL = cb;
03354 
03355     return SSL_SUCCESS;
03356 }
03357 
03358 
03359 int CyaSSL_CertManagerLoadCRL(CYASSL_CERT_MANAGER* cm, const char* path,
03360                               int type, int monitor)
03361 {
03362     CYASSL_ENTER("CyaSSL_CertManagerLoadCRL");
03363     if (cm == NULL)
03364         return BAD_FUNC_ARG;
03365 
03366     if (cm->crl == NULL) {
03367         if (CyaSSL_CertManagerEnableCRL(cm, 0) != SSL_SUCCESS) {
03368             CYASSL_MSG("Enable CRL failed");
03369             return SSL_FATAL_ERROR;
03370         }
03371     }
03372 
03373     return LoadCRL(cm->crl, path, type, monitor);
03374 }
03375 
03376 
03377 int CyaSSL_EnableCRL(CYASSL* ssl, int options)
03378 {
03379     CYASSL_ENTER("CyaSSL_EnableCRL");
03380     if (ssl)
03381         return CyaSSL_CertManagerEnableCRL(ssl->ctx->cm, options);
03382     else
03383         return BAD_FUNC_ARG;
03384 }
03385 
03386 
03387 int CyaSSL_DisableCRL(CYASSL* ssl)
03388 {
03389     CYASSL_ENTER("CyaSSL_DisableCRL");
03390     if (ssl)
03391         return CyaSSL_CertManagerDisableCRL(ssl->ctx->cm);
03392     else
03393         return BAD_FUNC_ARG;
03394 }
03395 
03396 
03397 int CyaSSL_LoadCRL(CYASSL* ssl, const char* path, int type, int monitor)
03398 {
03399     CYASSL_ENTER("CyaSSL_LoadCRL");
03400     if (ssl)
03401         return CyaSSL_CertManagerLoadCRL(ssl->ctx->cm, path, type, monitor);
03402     else
03403         return BAD_FUNC_ARG;
03404 }
03405 
03406 
03407 int CyaSSL_SetCRL_Cb(CYASSL* ssl, CbMissingCRL cb)
03408 {
03409     CYASSL_ENTER("CyaSSL_SetCRL_Cb");
03410     if (ssl)
03411         return CyaSSL_CertManagerSetCRL_Cb(ssl->ctx->cm, cb);
03412     else
03413         return BAD_FUNC_ARG;
03414 }
03415 
03416 
03417 int CyaSSL_CTX_EnableCRL(CYASSL_CTX* ctx, int options)
03418 {
03419     CYASSL_ENTER("CyaSSL_CTX_EnableCRL");
03420     if (ctx)
03421         return CyaSSL_CertManagerEnableCRL(ctx->cm, options);
03422     else
03423         return BAD_FUNC_ARG;
03424 }
03425 
03426 
03427 int CyaSSL_CTX_DisableCRL(CYASSL_CTX* ctx)
03428 {
03429     CYASSL_ENTER("CyaSSL_CTX_DisableCRL");
03430     if (ctx)
03431         return CyaSSL_CertManagerDisableCRL(ctx->cm);
03432     else
03433         return BAD_FUNC_ARG;
03434 }
03435 
03436 
03437 int CyaSSL_CTX_LoadCRL(CYASSL_CTX* ctx, const char* path, int type, int monitor)
03438 {
03439     CYASSL_ENTER("CyaSSL_CTX_LoadCRL");
03440     if (ctx)
03441         return CyaSSL_CertManagerLoadCRL(ctx->cm, path, type, monitor);
03442     else
03443         return BAD_FUNC_ARG;
03444 }
03445 
03446 
03447 int CyaSSL_CTX_SetCRL_Cb(CYASSL_CTX* ctx, CbMissingCRL cb)
03448 {
03449     CYASSL_ENTER("CyaSSL_CTX_SetCRL_Cb");
03450     if (ctx)
03451         return CyaSSL_CertManagerSetCRL_Cb(ctx->cm, cb);
03452     else
03453         return BAD_FUNC_ARG;
03454 }
03455 
03456 
03457 #endif /* HAVE_CRL */
03458 
03459 
03460 #ifdef CYASSL_DER_LOAD
03461 
03462 /* Add format parameter to allow DER load of CA files */
03463 int CyaSSL_CTX_der_load_verify_locations(CYASSL_CTX* ctx, const char* file,
03464                                          int format)
03465 {
03466     CYASSL_ENTER("CyaSSL_CTX_der_load_verify_locations");
03467     if (ctx == NULL || file == NULL)
03468         return SSL_FAILURE;
03469 
03470     if (ProcessFile(ctx, file, format, CA_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
03471         return SSL_SUCCESS;
03472 
03473     return SSL_FAILURE;
03474 }
03475 
03476 #endif /* CYASSL_DER_LOAD */
03477 
03478 
03479 #ifdef CYASSL_CERT_GEN
03480 
03481 /* load pem cert from file into der buffer, return der size or error */
03482 int CyaSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
03483 {
03484 #ifdef CYASSL_SMALL_STACK
03485     EncryptedInfo* info = NULL;
03486     byte   staticBuffer[1]; /* force XMALLOC */
03487 #else
03488     EncryptedInfo info[1];
03489     byte   staticBuffer[FILE_BUFFER_SIZE];
03490 #endif
03491     byte*  fileBuf = staticBuffer;
03492     int    dynamic = 0;
03493     int    ret     = 0;
03494     int    ecc     = 0;
03495     long   sz      = 0;
03496     XFILE  file    = XFOPEN(fileName, "rb");
03497     buffer converted;
03498 
03499     CYASSL_ENTER("CyaSSL_PemCertToDer");
03500 
03501     if (file == XBADFILE)
03502         ret = SSL_BAD_FILE;
03503     else {
03504         XFSEEK(file, 0, XSEEK_END);
03505         sz = XFTELL(file);
03506         XREWIND(file);
03507 
03508         if (sz < 0) {
03509             ret = SSL_BAD_FILE;
03510         }
03511         else if (sz > (long)sizeof(staticBuffer)) {
03512             fileBuf = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
03513             if (fileBuf == NULL)
03514                 ret = MEMORY_E;
03515             else
03516                 dynamic = 1;
03517         }
03518 
03519         converted.buffer = 0;
03520 
03521         if (ret == 0) {
03522             if ( (ret = (int)XFREAD(fileBuf, sz, 1, file)) < 0)
03523                 ret = SSL_BAD_FILE;
03524             else {
03525             #ifdef CYASSL_SMALL_STACK
03526                 info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
03527                                                        DYNAMIC_TYPE_TMP_BUFFER);
03528                 if (info == NULL)
03529                     ret = MEMORY_E;
03530                 else
03531             #endif
03532                 {
03533                     ret = PemToDer(fileBuf, sz, CA_TYPE, &converted, 0, info,
03534                                                                           &ecc);
03535                 #ifdef CYASSL_SMALL_STACK
03536                     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03537                 #endif
03538                 }
03539             }
03540 
03541             if (ret == 0) {
03542                 if (converted.length < (word32)derSz) {
03543                     XMEMCPY(derBuf, converted.buffer, converted.length);
03544                     ret = converted.length;
03545                 }
03546                 else
03547                     ret = BUFFER_E;
03548             }
03549 
03550             XFREE(converted.buffer, 0, DYNAMIC_TYPE_CA);
03551         }
03552 
03553         XFCLOSE(file);
03554         if (dynamic)
03555             XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE);
03556     }
03557 
03558     return ret;
03559 }
03560 
03561 #endif /* CYASSL_CERT_GEN */
03562 
03563 
03564 int CyaSSL_CTX_use_certificate_file(CYASSL_CTX* ctx, const char* file,
03565                                     int format)
03566 {
03567     CYASSL_ENTER("CyaSSL_CTX_use_certificate_file");
03568     if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
03569         return SSL_SUCCESS;
03570 
03571     return SSL_FAILURE;
03572 }
03573 
03574 
03575 int CyaSSL_CTX_use_PrivateKey_file(CYASSL_CTX* ctx, const char* file,int format)
03576 {
03577     CYASSL_ENTER("CyaSSL_CTX_use_PrivateKey_file");
03578     if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL)
03579                     == SSL_SUCCESS)
03580         return SSL_SUCCESS;
03581 
03582     return SSL_FAILURE;
03583 }
03584 
03585 
03586 int CyaSSL_CTX_use_certificate_chain_file(CYASSL_CTX* ctx, const char* file)
03587 {
03588    /* procces up to MAX_CHAIN_DEPTH plus subject cert */
03589    CYASSL_ENTER("CyaSSL_CTX_use_certificate_chain_file");
03590    if (ProcessFile(ctx, file, SSL_FILETYPE_PEM,CERT_TYPE,NULL,1, NULL)
03591                    == SSL_SUCCESS)
03592        return SSL_SUCCESS;
03593 
03594    return SSL_FAILURE;
03595 }
03596 
03597 
03598 #ifndef NO_DH
03599 
03600 /* server wrapper for ctx or ssl Diffie-Hellman parameters */
03601 static int CyaSSL_SetTmpDH_buffer_wrapper(CYASSL_CTX* ctx, CYASSL* ssl,
03602                                   const unsigned char* buf, long sz, int format)
03603 {
03604     buffer der;
03605     int    ret      = 0;
03606     int    weOwnDer = 0;
03607     word32 pSz = MAX_DH_SIZE;
03608     word32 gSz = MAX_DH_SIZE;
03609 #ifdef CYASSL_SMALL_STACK
03610     byte*  p = NULL;
03611     byte*  g = NULL;
03612 #else
03613     byte   p[MAX_DH_SIZE];
03614     byte   g[MAX_DH_SIZE];
03615 #endif
03616 
03617     der.buffer = (byte*)buf;
03618     der.length = (word32)sz;
03619 
03620 #ifdef CYASSL_SMALL_STACK
03621     p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03622     g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03623 
03624     if (p == NULL || g == NULL) {
03625         XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03626         XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03627         return MEMORY_E;
03628     }
03629 #endif
03630 
03631     if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM)
03632         ret = SSL_BAD_FILETYPE;
03633     else {
03634         if (format == SSL_FILETYPE_PEM) {
03635             der.buffer = NULL;
03636             ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap, NULL,NULL);
03637             weOwnDer = 1;
03638         }
03639         
03640         if (ret == 0) {
03641             if (DhParamsLoad(der.buffer, der.length, p, &pSz, g, &gSz) < 0)
03642                 ret = SSL_BAD_FILETYPE;
03643             else if (ssl)
03644                 ret = CyaSSL_SetTmpDH(ssl, p, pSz, g, gSz);
03645             else
03646                 ret = CyaSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
03647         }
03648     }
03649 
03650     if (weOwnDer)
03651         XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
03652 
03653 #ifdef CYASSL_SMALL_STACK
03654     XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03655     XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03656 #endif
03657 
03658     return ret;
03659 }
03660 
03661 
03662 /* server Diffie-Hellman parameters, SSL_SUCCESS on ok */
03663 int CyaSSL_SetTmpDH_buffer(CYASSL* ssl, const unsigned char* buf, long sz,
03664                            int format)
03665 {
03666     return CyaSSL_SetTmpDH_buffer_wrapper(ssl->ctx, ssl, buf, sz, format);
03667 }
03668 
03669 
03670 /* server ctx Diffie-Hellman parameters, SSL_SUCCESS on ok */
03671 int CyaSSL_CTX_SetTmpDH_buffer(CYASSL_CTX* ctx, const unsigned char* buf,
03672                                long sz, int format)
03673 {
03674     return CyaSSL_SetTmpDH_buffer_wrapper(ctx, NULL, buf, sz, format);
03675 }
03676 
03677 
03678 /* server Diffie-Hellman parameters */
03679 static int CyaSSL_SetTmpDH_file_wrapper(CYASSL_CTX* ctx, CYASSL* ssl,
03680                                         const char* fname, int format)
03681 {
03682 #ifdef CYASSL_SMALL_STACK
03683     byte   staticBuffer[1]; /* force heap usage */
03684 #else
03685     byte   staticBuffer[FILE_BUFFER_SIZE];
03686 #endif
03687     byte*  myBuffer = staticBuffer;
03688     int    dynamic = 0;
03689     int    ret;
03690     long   sz = 0;
03691     XFILE  file = XFOPEN(fname, "rb");
03692 
03693     if (file == XBADFILE) return SSL_BAD_FILE;
03694     XFSEEK(file, 0, XSEEK_END);
03695     sz = XFTELL(file);
03696     XREWIND(file);
03697 
03698     if (sz > (long)sizeof(staticBuffer)) {
03699         CYASSL_MSG("Getting dynamic buffer");
03700         myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
03701         if (myBuffer == NULL) {
03702             XFCLOSE(file);
03703             return SSL_BAD_FILE;
03704         }
03705         dynamic = 1;
03706     }
03707     else if (sz < 0) {
03708         XFCLOSE(file);
03709         return SSL_BAD_FILE;
03710     }
03711 
03712     if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
03713         ret = SSL_BAD_FILE;
03714     else {
03715         if (ssl)
03716             ret = CyaSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format);
03717         else
03718             ret = CyaSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format);
03719     }
03720 
03721     XFCLOSE(file);
03722     if (dynamic)
03723         XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
03724 
03725     return ret;
03726 }
03727 
03728 /* server Diffie-Hellman parameters */
03729 int CyaSSL_SetTmpDH_file(CYASSL* ssl, const char* fname, int format)
03730 {
03731     return CyaSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format);
03732 }
03733 
03734 
03735 /* server Diffie-Hellman parameters */
03736 int CyaSSL_CTX_SetTmpDH_file(CYASSL_CTX* ctx, const char* fname, int format)
03737 {
03738     return CyaSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format);
03739 }
03740 
03741 
03742     /* server ctx Diffie-Hellman parameters, SSL_SUCCESS on ok */
03743     int CyaSSL_CTX_SetTmpDH(CYASSL_CTX* ctx, const unsigned char* p, int pSz,
03744                             const unsigned char* g, int gSz)
03745     {
03746         CYASSL_ENTER("CyaSSL_CTX_SetTmpDH");
03747         if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
03748 
03749         XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
03750         XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
03751 
03752         ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap,DYNAMIC_TYPE_DH);
03753         if (ctx->serverDH_P.buffer == NULL)
03754             return MEMORY_E;
03755 
03756         ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap,DYNAMIC_TYPE_DH);
03757         if (ctx->serverDH_G.buffer == NULL) {
03758             XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
03759             return MEMORY_E;
03760         }
03761 
03762         ctx->serverDH_P.length = pSz;
03763         ctx->serverDH_G.length = gSz;
03764 
03765         XMEMCPY(ctx->serverDH_P.buffer, p, pSz);
03766         XMEMCPY(ctx->serverDH_G.buffer, g, gSz);
03767 
03768         ctx->haveDH = 1;
03769 
03770         CYASSL_LEAVE("CyaSSL_CTX_SetTmpDH", 0);
03771         return SSL_SUCCESS;
03772     }
03773 #endif /* NO_DH */
03774 
03775 
03776 #ifdef OPENSSL_EXTRA
03777 /* put SSL type in extra for now, not very common */
03778 
03779 int CyaSSL_use_certificate_file(CYASSL* ssl, const char* file, int format)
03780 {
03781     CYASSL_ENTER("CyaSSL_use_certificate_file");
03782     if (ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 0, NULL)
03783                     == SSL_SUCCESS)
03784         return SSL_SUCCESS;
03785 
03786     return SSL_FAILURE;
03787 }
03788 
03789 
03790 int CyaSSL_use_PrivateKey_file(CYASSL* ssl, const char* file, int format)
03791 {
03792     CYASSL_ENTER("CyaSSL_use_PrivateKey_file");
03793     if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0, NULL)
03794                                                                  == SSL_SUCCESS)
03795         return SSL_SUCCESS;
03796 
03797     return SSL_FAILURE;
03798 }
03799 
03800 
03801 int CyaSSL_use_certificate_chain_file(CYASSL* ssl, const char* file)
03802 {
03803    /* procces up to MAX_CHAIN_DEPTH plus subject cert */
03804    CYASSL_ENTER("CyaSSL_use_certificate_chain_file");
03805    if (ProcessFile(ssl->ctx, file, SSL_FILETYPE_PEM, CERT_TYPE, ssl, 1, NULL)
03806                                                                  == SSL_SUCCESS)
03807        return SSL_SUCCESS;
03808 
03809    return SSL_FAILURE;
03810 }
03811 
03812 
03813 
03814 #ifdef HAVE_ECC
03815 
03816 /* Set Temp CTX EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
03817 int CyaSSL_CTX_SetTmpEC_DHE_Sz(CYASSL_CTX* ctx, word16 sz)
03818 {
03819     if (ctx == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
03820         return BAD_FUNC_ARG;
03821 
03822     ctx->eccTempKeySz = sz;
03823 
03824     return SSL_SUCCESS;
03825 }
03826 
03827 
03828 /* Set Temp SSL EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
03829 int CyaSSL_SetTmpEC_DHE_Sz(CYASSL* ssl, word16 sz)
03830 {
03831     if (ssl == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
03832         return BAD_FUNC_ARG;
03833 
03834     ssl->eccTempKeySz = sz;
03835 
03836     return SSL_SUCCESS;
03837 }
03838 
03839 #endif /* HAVE_ECC */
03840 
03841 
03842 
03843 
03844 int CyaSSL_CTX_use_RSAPrivateKey_file(CYASSL_CTX* ctx,const char* file,
03845                                    int format)
03846 {
03847     CYASSL_ENTER("SSL_CTX_use_RSAPrivateKey_file");
03848 
03849     return CyaSSL_CTX_use_PrivateKey_file(ctx, file, format);
03850 }
03851 
03852 
03853 int CyaSSL_use_RSAPrivateKey_file(CYASSL* ssl, const char* file, int format)
03854 {
03855     CYASSL_ENTER("CyaSSL_use_RSAPrivateKey_file");
03856 
03857     return CyaSSL_use_PrivateKey_file(ssl, file, format);
03858 }
03859 
03860 #endif /* OPENSSL_EXTRA */
03861 
03862 #ifdef HAVE_NTRU
03863 
03864 int CyaSSL_CTX_use_NTRUPrivateKey_file(CYASSL_CTX* ctx, const char* file)
03865 {
03866     CYASSL_ENTER("CyaSSL_CTX_use_NTRUPrivateKey_file");
03867     if (ctx == NULL)
03868         return SSL_FAILURE;
03869 
03870     if (ProcessFile(ctx, file, SSL_FILETYPE_RAW, PRIVATEKEY_TYPE, NULL, 0, NULL)
03871                          == SSL_SUCCESS) {
03872         ctx->haveNTRU = 1;
03873         return SSL_SUCCESS;
03874     }
03875 
03876     return SSL_FAILURE;
03877 }
03878 
03879 #endif /* HAVE_NTRU */
03880 
03881 
03882 #endif /* NO_FILESYSTEM */
03883 
03884 
03885 void CyaSSL_CTX_set_verify(CYASSL_CTX* ctx, int mode, VerifyCallback vc)
03886 {
03887     CYASSL_ENTER("CyaSSL_CTX_set_verify");
03888     if (mode & SSL_VERIFY_PEER) {
03889         ctx->verifyPeer = 1;
03890         ctx->verifyNone = 0;  /* in case perviously set */
03891     }
03892 
03893     if (mode == SSL_VERIFY_NONE) {
03894         ctx->verifyNone = 1;
03895         ctx->verifyPeer = 0;  /* in case previously set */
03896     }
03897 
03898     if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
03899         ctx->failNoCert = 1;
03900 
03901     ctx->verifyCallback = vc;
03902 }
03903 
03904 
03905 void CyaSSL_set_verify(CYASSL* ssl, int mode, VerifyCallback vc)
03906 {
03907     CYASSL_ENTER("CyaSSL_set_verify");
03908     if (mode & SSL_VERIFY_PEER) {
03909         ssl->options.verifyPeer = 1;
03910         ssl->options.verifyNone = 0;  /* in case perviously set */
03911     }
03912 
03913     if (mode == SSL_VERIFY_NONE) {
03914         ssl->options.verifyNone = 1;
03915         ssl->options.verifyPeer = 0;  /* in case previously set */
03916     }
03917 
03918     if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
03919         ssl->options.failNoCert = 1;
03920 
03921     ssl->verifyCallback = vc;
03922 }
03923 
03924 
03925 /* store user ctx for verify callback */
03926 void CyaSSL_SetCertCbCtx(CYASSL* ssl, void* ctx)
03927 {
03928     CYASSL_ENTER("CyaSSL_SetCertCbCtx");
03929     if (ssl)
03930         ssl->verifyCbCtx = ctx;
03931 }
03932 
03933 
03934 /* store context CA Cache addition callback */
03935 void CyaSSL_CTX_SetCACb(CYASSL_CTX* ctx, CallbackCACache cb)
03936 {
03937     if (ctx && ctx->cm)
03938         ctx->cm->caCacheCallback = cb;
03939 }
03940 
03941 
03942 #if defined(PERSIST_CERT_CACHE)
03943 
03944 #if !defined(NO_FILESYSTEM)
03945 
03946 /* Persist cert cache to file */
03947 int CyaSSL_CTX_save_cert_cache(CYASSL_CTX* ctx, const char* fname)
03948 {
03949     CYASSL_ENTER("CyaSSL_CTX_save_cert_cache");
03950 
03951     if (ctx == NULL || fname == NULL)
03952         return BAD_FUNC_ARG;
03953 
03954     return CM_SaveCertCache(ctx->cm, fname);
03955 }
03956 
03957 
03958 /* Persist cert cache from file */
03959 int CyaSSL_CTX_restore_cert_cache(CYASSL_CTX* ctx, const char* fname)
03960 {
03961     CYASSL_ENTER("CyaSSL_CTX_restore_cert_cache");
03962 
03963     if (ctx == NULL || fname == NULL)
03964         return BAD_FUNC_ARG;
03965 
03966     return CM_RestoreCertCache(ctx->cm, fname);
03967 }
03968 
03969 #endif /* NO_FILESYSTEM */
03970 
03971 /* Persist cert cache to memory */
03972 int CyaSSL_CTX_memsave_cert_cache(CYASSL_CTX* ctx, void* mem, int sz, int* used)
03973 {
03974     CYASSL_ENTER("CyaSSL_CTX_memsave_cert_cache");
03975 
03976     if (ctx == NULL || mem == NULL || used == NULL || sz <= 0)
03977         return BAD_FUNC_ARG;
03978 
03979     return CM_MemSaveCertCache(ctx->cm, mem, sz, used);
03980 }
03981 
03982 
03983 /* Restore cert cache from memory */
03984 int CyaSSL_CTX_memrestore_cert_cache(CYASSL_CTX* ctx, const void* mem, int sz)
03985 {
03986     CYASSL_ENTER("CyaSSL_CTX_memrestore_cert_cache");
03987 
03988     if (ctx == NULL || mem == NULL || sz <= 0)
03989         return BAD_FUNC_ARG;
03990 
03991     return CM_MemRestoreCertCache(ctx->cm, mem, sz);
03992 }
03993 
03994 
03995 /* get how big the the cert cache save buffer needs to be */
03996 int CyaSSL_CTX_get_cert_cache_memsize(CYASSL_CTX* ctx)
03997 {
03998     CYASSL_ENTER("CyaSSL_CTX_get_cert_cache_memsize");
03999 
04000     if (ctx == NULL)
04001         return BAD_FUNC_ARG;
04002 
04003     return CM_GetCertCacheMemSize(ctx->cm);
04004 }
04005 
04006 #endif /* PERSISTE_CERT_CACHE */
04007 #endif /* !NO_CERTS */
04008 
04009 
04010 #ifndef NO_SESSION_CACHE
04011 
04012 CYASSL_SESSION* CyaSSL_get_session(CYASSL* ssl)
04013 {
04014     CYASSL_ENTER("SSL_get_session");
04015     if (ssl)
04016         return GetSession(ssl, 0);
04017 
04018     return NULL;
04019 }
04020 
04021 
04022 int CyaSSL_set_session(CYASSL* ssl, CYASSL_SESSION* session)
04023 {
04024     CYASSL_ENTER("SSL_set_session");
04025     if (session)
04026         return SetSession(ssl, session);
04027 
04028     return SSL_FAILURE;
04029 }
04030 
04031 
04032 #ifndef NO_CLIENT_CACHE
04033 
04034 /* Associate client session with serverID, find existing or store for saving
04035    if newSession flag on, don't reuse existing session
04036    SSL_SUCCESS on ok */
04037 int CyaSSL_SetServerID(CYASSL* ssl, const byte* id, int len, int newSession)
04038 {
04039     CYASSL_SESSION* session = NULL;
04040 
04041     CYASSL_ENTER("CyaSSL_SetServerID");
04042 
04043     if (ssl == NULL || id == NULL || len <= 0)
04044         return BAD_FUNC_ARG;
04045 
04046     if (newSession == 0) {
04047         session = GetSessionClient(ssl, id, len);
04048         if (session) {
04049             if (SetSession(ssl, session) != SSL_SUCCESS) {
04050                 CYASSL_MSG("SetSession failed");
04051                 session = NULL;
04052             }
04053         }
04054     }
04055 
04056     if (session == NULL) {
04057         CYASSL_MSG("Valid ServerID not cached already");
04058 
04059         ssl->session.idLen = (word16)min(SERVER_ID_LEN, (word32)len);
04060         XMEMCPY(ssl->session.serverID, id, ssl->session.idLen);
04061     }
04062 
04063     return SSL_SUCCESS;
04064 }
04065 
04066 #endif /* NO_CLIENT_CACHE */
04067 
04068 #if defined(PERSIST_SESSION_CACHE)
04069 
04070 /* for persistance, if changes to layout need to increment and modify
04071    save_session_cache() and restore_session_cache and memory versions too */
04072 #define CYASSL_CACHE_VERSION 2
04073 
04074 /* Session Cache Header information */
04075 typedef struct {
04076     int version;     /* cache layout version id */
04077     int rows;        /* session rows */
04078     int columns;     /* session columns */
04079     int sessionSz;   /* sizeof CYASSL_SESSION */
04080 } cache_header_t;
04081 
04082 /* current persistence layout is:
04083 
04084    1) cache_header_t
04085    2) SessionCache
04086    3) ClientCache
04087 
04088    update CYASSL_CACHE_VERSION if change layout for the following
04089    PERSISTENT_SESSION_CACHE functions
04090 */
04091 
04092 
04093 /* get how big the the session cache save buffer needs to be */
04094 int CyaSSL_get_session_cache_memsize(void)
04095 {
04096     int sz  = (int)(sizeof(SessionCache) + sizeof(cache_header_t));
04097 
04098     #ifndef NO_CLIENT_CACHE
04099         sz += (int)(sizeof(ClientCache));
04100     #endif
04101 
04102     return sz;
04103 }
04104 
04105 
04106 /* Persist session cache to memory */
04107 int CyaSSL_memsave_session_cache(void* mem, int sz)
04108 {
04109     int i;
04110     cache_header_t cache_header;
04111     SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
04112 #ifndef NO_CLIENT_CACHE
04113     ClientRow*     clRow;
04114 #endif
04115 
04116     CYASSL_ENTER("CyaSSL_memsave_session_cache");
04117 
04118     if (sz < CyaSSL_get_session_cache_memsize()) {
04119         CYASSL_MSG("Memory buffer too small");
04120         return BUFFER_E;
04121     }
04122 
04123     cache_header.version   = CYASSL_CACHE_VERSION;
04124     cache_header.rows      = SESSION_ROWS;
04125     cache_header.columns   = SESSIONS_PER_ROW;
04126     cache_header.sessionSz = (int)sizeof(CYASSL_SESSION);
04127     XMEMCPY(mem, &cache_header, sizeof(cache_header));
04128 
04129     if (LockMutex(&session_mutex) != 0) {
04130         CYASSL_MSG("Session cache mutex lock failed");
04131         return BAD_MUTEX_E;
04132     }
04133 
04134     for (i = 0; i < cache_header.rows; ++i)
04135         XMEMCPY(row++, SessionCache + i, sizeof(SessionRow));
04136 
04137 #ifndef NO_CLIENT_CACHE
04138     clRow = (ClientRow*)row;
04139     for (i = 0; i < cache_header.rows; ++i)
04140         XMEMCPY(clRow++, ClientCache + i, sizeof(ClientRow));
04141 #endif
04142 
04143     UnLockMutex(&session_mutex);
04144 
04145     CYASSL_LEAVE("CyaSSL_memsave_session_cache", SSL_SUCCESS);
04146 
04147     return SSL_SUCCESS;
04148 }
04149 
04150 
04151 /* Restore the persistant session cache from memory */
04152 int CyaSSL_memrestore_session_cache(const void* mem, int sz)
04153 {
04154     int    i;
04155     cache_header_t cache_header;
04156     SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
04157 #ifndef NO_CLIENT_CACHE
04158     ClientRow*     clRow;
04159 #endif
04160 
04161     CYASSL_ENTER("CyaSSL_memrestore_session_cache");
04162 
04163     if (sz < CyaSSL_get_session_cache_memsize()) {
04164         CYASSL_MSG("Memory buffer too small");
04165         return BUFFER_E;
04166     }
04167 
04168     XMEMCPY(&cache_header, mem, sizeof(cache_header));
04169     if (cache_header.version   != CYASSL_CACHE_VERSION ||
04170         cache_header.rows      != SESSION_ROWS ||
04171         cache_header.columns   != SESSIONS_PER_ROW ||
04172         cache_header.sessionSz != (int)sizeof(CYASSL_SESSION)) {
04173 
04174         CYASSL_MSG("Session cache header match failed");
04175         return CACHE_MATCH_ERROR;
04176     }
04177 
04178     if (LockMutex(&session_mutex) != 0) {
04179         CYASSL_MSG("Session cache mutex lock failed");
04180         return BAD_MUTEX_E;
04181     }
04182 
04183     for (i = 0; i < cache_header.rows; ++i)
04184         XMEMCPY(SessionCache + i, row++, sizeof(SessionRow));
04185 
04186 #ifndef NO_CLIENT_CACHE
04187     clRow = (ClientRow*)row;
04188     for (i = 0; i < cache_header.rows; ++i)
04189         XMEMCPY(ClientCache + i, clRow++, sizeof(ClientRow));
04190 #endif
04191 
04192     UnLockMutex(&session_mutex);
04193 
04194     CYASSL_LEAVE("CyaSSL_memrestore_session_cache", SSL_SUCCESS);
04195 
04196     return SSL_SUCCESS;
04197 }
04198 
04199 #if !defined(NO_FILESYSTEM)
04200 
04201 /* Persist session cache to file */
04202 /* doesn't use memsave because of additional memory use */
04203 int CyaSSL_save_session_cache(const char *fname)
04204 {
04205     XFILE  file;
04206     int    ret;
04207     int    rc = SSL_SUCCESS;
04208     int    i;
04209     cache_header_t cache_header;
04210 
04211     CYASSL_ENTER("CyaSSL_save_session_cache");
04212 
04213     file = XFOPEN(fname, "w+b");
04214     if (file == XBADFILE) {
04215         CYASSL_MSG("Couldn't open session cache save file");
04216         return SSL_BAD_FILE;
04217     }
04218     cache_header.version   = CYASSL_CACHE_VERSION;
04219     cache_header.rows      = SESSION_ROWS;
04220     cache_header.columns   = SESSIONS_PER_ROW;
04221     cache_header.sessionSz = (int)sizeof(CYASSL_SESSION);
04222 
04223     /* cache header */
04224     ret = (int)XFWRITE(&cache_header, sizeof cache_header, 1, file);
04225     if (ret != 1) {
04226         CYASSL_MSG("Session cache header file write failed");
04227         XFCLOSE(file);
04228         return FWRITE_ERROR;
04229     }
04230 
04231     if (LockMutex(&session_mutex) != 0) {
04232         CYASSL_MSG("Session cache mutex lock failed");
04233         XFCLOSE(file);
04234         return BAD_MUTEX_E;
04235     }
04236 
04237     /* session cache */
04238     for (i = 0; i < cache_header.rows; ++i) {
04239         ret = (int)XFWRITE(SessionCache + i, sizeof(SessionRow), 1, file);
04240         if (ret != 1) {
04241             CYASSL_MSG("Session cache member file write failed");
04242             rc = FWRITE_ERROR;
04243             break;
04244         }
04245     }
04246 
04247 #ifndef NO_CLIENT_CACHE
04248     /* client cache */
04249     for (i = 0; i < cache_header.rows; ++i) {
04250         ret = (int)XFWRITE(ClientCache + i, sizeof(ClientRow), 1, file);
04251         if (ret != 1) {
04252             CYASSL_MSG("Client cache member file write failed");
04253             rc = FWRITE_ERROR;
04254             break;
04255         }
04256     }
04257 #endif /* NO_CLIENT_CACHE */
04258 
04259     UnLockMutex(&session_mutex);
04260 
04261     XFCLOSE(file);
04262     CYASSL_LEAVE("CyaSSL_save_session_cache", rc);
04263 
04264     return rc;
04265 }
04266 
04267 
04268 /* Restore the persistant session cache from file */
04269 /* doesn't use memstore because of additional memory use */
04270 int CyaSSL_restore_session_cache(const char *fname)
04271 {
04272     XFILE  file;
04273     int    rc = SSL_SUCCESS;
04274     int    ret;
04275     int    i;
04276     cache_header_t cache_header;
04277 
04278     CYASSL_ENTER("CyaSSL_restore_session_cache");
04279 
04280     file = XFOPEN(fname, "rb");
04281     if (file == XBADFILE) {
04282         CYASSL_MSG("Couldn't open session cache save file");
04283         return SSL_BAD_FILE;
04284     }
04285     /* cache header */
04286     ret = (int)XFREAD(&cache_header, sizeof cache_header, 1, file);
04287     if (ret != 1) {
04288         CYASSL_MSG("Session cache header file read failed");
04289         XFCLOSE(file);
04290         return FREAD_ERROR;
04291     }
04292     if (cache_header.version   != CYASSL_CACHE_VERSION ||
04293         cache_header.rows      != SESSION_ROWS ||
04294         cache_header.columns   != SESSIONS_PER_ROW ||
04295         cache_header.sessionSz != (int)sizeof(CYASSL_SESSION)) {
04296 
04297         CYASSL_MSG("Session cache header match failed");
04298         XFCLOSE(file);
04299         return CACHE_MATCH_ERROR;
04300     }
04301 
04302     if (LockMutex(&session_mutex) != 0) {
04303         CYASSL_MSG("Session cache mutex lock failed");
04304         XFCLOSE(file);
04305         return BAD_MUTEX_E;
04306     }
04307 
04308     /* session cache */
04309     for (i = 0; i < cache_header.rows; ++i) {
04310         ret = (int)XFREAD(SessionCache + i, sizeof(SessionRow), 1, file);
04311         if (ret != 1) {
04312             CYASSL_MSG("Session cache member file read failed");
04313             XMEMSET(SessionCache, 0, sizeof SessionCache);
04314             rc = FREAD_ERROR;
04315             break;
04316         }
04317     }
04318 
04319 #ifndef NO_CLIENT_CACHE
04320     /* client cache */
04321     for (i = 0; i < cache_header.rows; ++i) {
04322         ret = (int)XFREAD(ClientCache + i, sizeof(ClientRow), 1, file);
04323         if (ret != 1) {
04324             CYASSL_MSG("Client cache member file read failed");
04325             XMEMSET(ClientCache, 0, sizeof ClientCache);
04326             rc = FREAD_ERROR;
04327             break;
04328         }
04329     }
04330 
04331 #endif /* NO_CLIENT_CACHE */
04332 
04333     UnLockMutex(&session_mutex);
04334 
04335     XFCLOSE(file);
04336     CYASSL_LEAVE("CyaSSL_restore_session_cache", rc);
04337 
04338     return rc;
04339 }
04340 
04341 #endif /* !NO_FILESYSTEM */
04342 #endif /* PERSIST_SESSION_CACHE */
04343 #endif /* NO_SESSION_CACHE */
04344 
04345 
04346 void CyaSSL_load_error_strings(void)   /* compatibility only */
04347 {}
04348 
04349 
04350 int CyaSSL_library_init(void)
04351 {
04352     CYASSL_ENTER("SSL_library_init");
04353     if (CyaSSL_Init() == SSL_SUCCESS)
04354         return SSL_SUCCESS;
04355     else
04356         return SSL_FATAL_ERROR;
04357 }
04358 
04359 
04360 #ifdef HAVE_SECRET_CALLBACK
04361 
04362 int CyaSSL_set_session_secret_cb(CYASSL* ssl, SessionSecretCb cb, void* ctx)
04363 {
04364     CYASSL_ENTER("CyaSSL_set_session_secret_cb");
04365     if (ssl == NULL)
04366         return SSL_FATAL_ERROR;
04367 
04368     ssl->sessionSecretCb = cb;
04369     ssl->sessionSecretCtx = ctx;
04370     /* If using a pre-set key, assume session resumption. */
04371     ssl->session.sessionIDSz = 0;
04372     ssl->options.resuming = 1;
04373 
04374     return SSL_SUCCESS;
04375 }
04376 
04377 #endif
04378 
04379 
04380 #ifndef NO_SESSION_CACHE
04381 
04382 /* on by default if built in but allow user to turn off */
04383 long CyaSSL_CTX_set_session_cache_mode(CYASSL_CTX* ctx, long mode)
04384 {
04385     CYASSL_ENTER("SSL_CTX_set_session_cache_mode");
04386     if (mode == SSL_SESS_CACHE_OFF)
04387         ctx->sessionCacheOff = 1;
04388 
04389     if (mode == SSL_SESS_CACHE_NO_AUTO_CLEAR)
04390         ctx->sessionCacheFlushOff = 1;
04391 
04392     return SSL_SUCCESS;
04393 }
04394 
04395 #endif /* NO_SESSION_CACHE */
04396 
04397 
04398 #if !defined(NO_CERTS)
04399 #if defined(PERSIST_CERT_CACHE)
04400 
04401 
04402 #define CYASSL_CACHE_CERT_VERSION 1
04403 
04404 typedef struct {
04405     int version;                 /* cache cert layout version id */
04406     int rows;                    /* hash table rows, CA_TABLE_SIZE */
04407     int columns[CA_TABLE_SIZE];  /* columns per row on list */
04408     int signerSz;                /* sizeof Signer object */
04409 } CertCacheHeader;
04410 
04411 /* current cert persistance layout is:
04412 
04413    1) CertCacheHeader
04414    2) caTable
04415 
04416    update CYASSL_CERT_CACHE_VERSION if change layout for the following
04417    PERSIST_CERT_CACHE functions
04418 */
04419 
04420 
04421 /* Return memory needed to persist this signer, have lock */
04422 static INLINE int GetSignerMemory(Signer* signer)
04423 {
04424     int sz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID)
04425            + sizeof(signer->nameLen)    + sizeof(signer->subjectNameHash);
04426 
04427 #if !defined(NO_SKID)
04428         sz += (int)sizeof(signer->subjectKeyIdHash);
04429 #endif
04430 
04431     /* add dynamic bytes needed */
04432     sz += signer->pubKeySize;
04433     sz += signer->nameLen;
04434 
04435     return sz;
04436 }
04437 
04438 
04439 /* Return memory needed to persist this row, have lock */
04440 static INLINE int GetCertCacheRowMemory(Signer* row)
04441 {
04442     int sz = 0;
04443 
04444     while (row) {
04445         sz += GetSignerMemory(row);
04446         row = row->next;
04447     }
04448 
04449     return sz;
04450 }
04451 
04452 
04453 /* get the size of persist cert cache, have lock */
04454 static INLINE int GetCertCacheMemSize(CYASSL_CERT_MANAGER* cm)
04455 {
04456     int sz;
04457     int i;
04458 
04459     sz = sizeof(CertCacheHeader);
04460 
04461     for (i = 0; i < CA_TABLE_SIZE; i++)
04462         sz += GetCertCacheRowMemory(cm->caTable[i]);
04463 
04464     return sz;
04465 }
04466 
04467 
04468 /* Store cert cache header columns with number of items per list, have lock */
04469 static INLINE void SetCertHeaderColumns(CYASSL_CERT_MANAGER* cm, int* columns)
04470 {
04471     int     i;
04472     Signer* row;
04473 
04474     for (i = 0; i < CA_TABLE_SIZE; i++) {
04475         int count = 0;
04476         row = cm->caTable[i];
04477 
04478         while (row) {
04479             ++count;
04480             row = row->next;
04481         }
04482         columns[i] = count;
04483     }
04484 }
04485 
04486 
04487 /* Restore whole cert row from memory, have lock, return bytes consumed,
04488    < 0 on error, have lock */
04489 static INLINE int RestoreCertRow(CYASSL_CERT_MANAGER* cm, byte* current,
04490                                  int row, int listSz, const byte* end)
04491 {
04492     int idx = 0;
04493 
04494     if (listSz < 0) {
04495         CYASSL_MSG("Row header corrupted, negative value");
04496         return PARSE_ERROR;
04497     }
04498 
04499     while (listSz) {
04500         Signer* signer;
04501         byte*   start = current + idx;  /* for end checks on this signer */
04502         int     minSz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) +
04503                       sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
04504         #ifndef NO_SKID
04505                 minSz += (int)sizeof(signer->subjectKeyIdHash);
04506         #endif
04507 
04508         if (start + minSz > end) {
04509             CYASSL_MSG("Would overread restore buffer");
04510             return BUFFER_E;
04511         }
04512         signer = MakeSigner(cm->heap);
04513         if (signer == NULL)
04514             return MEMORY_E;
04515 
04516         /* pubKeySize */
04517         XMEMCPY(&signer->pubKeySize, current + idx, sizeof(signer->pubKeySize));
04518         idx += (int)sizeof(signer->pubKeySize);
04519 
04520         /* keyOID */
04521         XMEMCPY(&signer->keyOID, current + idx, sizeof(signer->keyOID));
04522         idx += (int)sizeof(signer->keyOID);
04523 
04524         /* pulicKey */
04525         if (start + minSz + signer->pubKeySize > end) {
04526             CYASSL_MSG("Would overread restore buffer");
04527             FreeSigner(signer, cm->heap);
04528             return BUFFER_E;
04529         }
04530         signer->publicKey = (byte*)XMALLOC(signer->pubKeySize, cm->heap,
04531                                            DYNAMIC_TYPE_KEY);
04532         if (signer->publicKey == NULL) {
04533             FreeSigner(signer, cm->heap);
04534             return MEMORY_E;
04535         }
04536 
04537         XMEMCPY(signer->publicKey, current + idx, signer->pubKeySize);
04538         idx += signer->pubKeySize;
04539 
04540         /* nameLen */
04541         XMEMCPY(&signer->nameLen, current + idx, sizeof(signer->nameLen));
04542         idx += (int)sizeof(signer->nameLen);
04543 
04544         /* name */
04545         if (start + minSz + signer->pubKeySize + signer->nameLen > end) {
04546             CYASSL_MSG("Would overread restore buffer");
04547             FreeSigner(signer, cm->heap);
04548             return BUFFER_E;
04549         }
04550         signer->name = (char*)XMALLOC(signer->nameLen, cm->heap,
04551                                       DYNAMIC_TYPE_SUBJECT_CN);
04552         if (signer->name == NULL) {
04553             FreeSigner(signer, cm->heap);
04554             return MEMORY_E;
04555         }
04556 
04557         XMEMCPY(signer->name, current + idx, signer->nameLen);
04558         idx += signer->nameLen;
04559 
04560         /* subjectNameHash */
04561         XMEMCPY(signer->subjectNameHash, current + idx, SIGNER_DIGEST_SIZE);
04562         idx += SIGNER_DIGEST_SIZE;
04563 
04564         #ifndef NO_SKID
04565             /* subjectKeyIdHash */
04566             XMEMCPY(signer->subjectKeyIdHash, current + idx,SIGNER_DIGEST_SIZE);
04567             idx += SIGNER_DIGEST_SIZE;
04568         #endif
04569 
04570         signer->next = cm->caTable[row];
04571         cm->caTable[row] = signer;
04572 
04573         --listSz;
04574     }
04575 
04576     return idx;
04577 }
04578 
04579 
04580 /* Store whole cert row into memory, have lock, return bytes added */
04581 static INLINE int StoreCertRow(CYASSL_CERT_MANAGER* cm, byte* current, int row)
04582 {
04583     int     added  = 0;
04584     Signer* list   = cm->caTable[row];
04585 
04586     while (list) {
04587         XMEMCPY(current + added, &list->pubKeySize, sizeof(list->pubKeySize));
04588         added += (int)sizeof(list->pubKeySize);
04589 
04590         XMEMCPY(current + added, &list->keyOID,     sizeof(list->keyOID));
04591         added += (int)sizeof(list->keyOID);
04592 
04593         XMEMCPY(current + added, list->publicKey, list->pubKeySize);
04594         added += list->pubKeySize;
04595 
04596         XMEMCPY(current + added, &list->nameLen, sizeof(list->nameLen));
04597         added += (int)sizeof(list->nameLen);
04598 
04599         XMEMCPY(current + added, list->name, list->nameLen);
04600         added += list->nameLen;
04601 
04602         XMEMCPY(current + added, list->subjectNameHash, SIGNER_DIGEST_SIZE);
04603         added += SIGNER_DIGEST_SIZE;
04604 
04605         #ifndef NO_SKID
04606             XMEMCPY(current + added, list->subjectKeyIdHash,SIGNER_DIGEST_SIZE);
04607             added += SIGNER_DIGEST_SIZE;
04608         #endif
04609 
04610         list = list->next;
04611     }
04612 
04613     return added;
04614 }
04615 
04616 
04617 /* Persist cert cache to memory, have lock */
04618 static INLINE int DoMemSaveCertCache(CYASSL_CERT_MANAGER* cm, void* mem, int sz)
04619 {
04620     int realSz;
04621     int ret = SSL_SUCCESS;
04622     int i;
04623 
04624     CYASSL_ENTER("DoMemSaveCertCache");
04625 
04626     realSz = GetCertCacheMemSize(cm);
04627     if (realSz > sz) {
04628         CYASSL_MSG("Mem output buffer too small");
04629         ret = BUFFER_E;
04630     }
04631     else {
04632         byte*           current;
04633         CertCacheHeader hdr;
04634 
04635         hdr.version  = CYASSL_CACHE_CERT_VERSION;
04636         hdr.rows     = CA_TABLE_SIZE;
04637         SetCertHeaderColumns(cm, hdr.columns);
04638         hdr.signerSz = (int)sizeof(Signer);
04639 
04640         XMEMCPY(mem, &hdr, sizeof(CertCacheHeader));
04641         current = (byte*)mem + sizeof(CertCacheHeader);
04642 
04643         for (i = 0; i < CA_TABLE_SIZE; ++i)
04644             current += StoreCertRow(cm, current, i);
04645     }
04646 
04647     return ret;
04648 }
04649 
04650 
04651 #if !defined(NO_FILESYSTEM)
04652 
04653 /* Persist cert cache to file */
04654 int CM_SaveCertCache(CYASSL_CERT_MANAGER* cm, const char* fname)
04655 {
04656     XFILE file;
04657     int   rc = SSL_SUCCESS;
04658     int   memSz;
04659     byte* mem;
04660 
04661     CYASSL_ENTER("CM_SaveCertCache");
04662 
04663     file = XFOPEN(fname, "w+b");
04664     if (file == XBADFILE) {
04665        CYASSL_MSG("Couldn't open cert cache save file");
04666        return SSL_BAD_FILE;
04667     }
04668 
04669     if (LockMutex(&cm->caLock) != 0) {
04670         CYASSL_MSG("LockMutex on caLock failed");
04671         XFCLOSE(file);
04672         return BAD_MUTEX_E;
04673     }
04674 
04675     memSz = GetCertCacheMemSize(cm);
04676     mem   = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
04677     if (mem == NULL) {
04678         CYASSL_MSG("Alloc for tmp buffer failed");
04679         rc = MEMORY_E;
04680     } else {
04681         rc = DoMemSaveCertCache(cm, mem, memSz);
04682         if (rc == SSL_SUCCESS) {
04683             int ret = (int)XFWRITE(mem, memSz, 1, file);
04684             if (ret != 1) {
04685                 CYASSL_MSG("Cert cache file write failed");
04686                 rc = FWRITE_ERROR;
04687             }
04688         }
04689         XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
04690     }
04691 
04692     UnLockMutex(&cm->caLock);
04693     XFCLOSE(file);
04694 
04695     return rc;
04696 }
04697 
04698 
04699 /* Restore cert cache from file */
04700 int CM_RestoreCertCache(CYASSL_CERT_MANAGER* cm, const char* fname)
04701 {
04702     XFILE file;
04703     int   rc = SSL_SUCCESS;
04704     int   ret;
04705     int   memSz;
04706     byte* mem;
04707 
04708     CYASSL_ENTER("CM_RestoreCertCache");
04709 
04710     file = XFOPEN(fname, "rb");
04711     if (file == XBADFILE) {
04712        CYASSL_MSG("Couldn't open cert cache save file");
04713        return SSL_BAD_FILE;
04714     }
04715 
04716     XFSEEK(file, 0, XSEEK_END);
04717     memSz = (int)XFTELL(file);
04718     XREWIND(file);
04719 
04720     if (memSz <= 0) {
04721         CYASSL_MSG("Bad file size");
04722         XFCLOSE(file);
04723         return SSL_BAD_FILE;
04724     }
04725 
04726     mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
04727     if (mem == NULL) {
04728         CYASSL_MSG("Alloc for tmp buffer failed");
04729         XFCLOSE(file);
04730         return MEMORY_E;
04731     }
04732 
04733     ret = (int)XFREAD(mem, memSz, 1, file);
04734     if (ret != 1) {
04735         CYASSL_MSG("Cert file read error");
04736         rc = FREAD_ERROR;
04737     } else {
04738         rc = CM_MemRestoreCertCache(cm, mem, memSz);
04739         if (rc != SSL_SUCCESS) {
04740             CYASSL_MSG("Mem restore cert cache failed");
04741         }
04742     }
04743 
04744     XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
04745     XFCLOSE(file);
04746 
04747     return rc;
04748 }
04749 
04750 #endif /* NO_FILESYSTEM */
04751 
04752 
04753 /* Persist cert cache to memory */
04754 int CM_MemSaveCertCache(CYASSL_CERT_MANAGER* cm, void* mem, int sz, int* used)
04755 {
04756     int ret = SSL_SUCCESS;
04757 
04758     CYASSL_ENTER("CM_MemSaveCertCache");
04759 
04760     if (LockMutex(&cm->caLock) != 0) {
04761         CYASSL_MSG("LockMutex on caLock failed");
04762         return BAD_MUTEX_E;
04763     }
04764 
04765     ret = DoMemSaveCertCache(cm, mem, sz);
04766     if (ret == SSL_SUCCESS)
04767         *used  = GetCertCacheMemSize(cm);
04768 
04769     UnLockMutex(&cm->caLock);
04770 
04771     return ret;
04772 }
04773 
04774 
04775 /* Restore cert cache from memory */
04776 int CM_MemRestoreCertCache(CYASSL_CERT_MANAGER* cm, const void* mem, int sz)
04777 {
04778     int ret = SSL_SUCCESS;
04779     int i;
04780     CertCacheHeader* hdr = (CertCacheHeader*)mem;
04781     byte*            current = (byte*)mem + sizeof(CertCacheHeader);
04782     byte*            end     = (byte*)mem + sz;  /* don't go over */
04783 
04784     CYASSL_ENTER("CM_MemRestoreCertCache");
04785 
04786     if (current > end) {
04787         CYASSL_MSG("Cert Cache Memory buffer too small");
04788         return BUFFER_E;
04789     }
04790 
04791     if (hdr->version  != CYASSL_CACHE_CERT_VERSION ||
04792         hdr->rows     != CA_TABLE_SIZE ||
04793         hdr->signerSz != (int)sizeof(Signer)) {
04794 
04795         CYASSL_MSG("Cert Cache Memory header mismatch");
04796         return CACHE_MATCH_ERROR;
04797     }
04798 
04799     if (LockMutex(&cm->caLock) != 0) {
04800         CYASSL_MSG("LockMutex on caLock failed");
04801         return BAD_MUTEX_E;
04802     }
04803 
04804     FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
04805 
04806     for (i = 0; i < CA_TABLE_SIZE; ++i) {
04807         int added = RestoreCertRow(cm, current, i, hdr->columns[i], end);
04808         if (added < 0) {
04809             CYASSL_MSG("RestoreCertRow error");
04810             ret = added;
04811             break;
04812         }
04813         current += added;
04814     }
04815 
04816     UnLockMutex(&cm->caLock);
04817 
04818     return ret;
04819 }
04820 
04821 
04822 /* get how big the the cert cache save buffer needs to be */
04823 int CM_GetCertCacheMemSize(CYASSL_CERT_MANAGER* cm)
04824 {
04825     int sz;
04826 
04827     CYASSL_ENTER("CM_GetCertCacheMemSize");
04828 
04829     if (LockMutex(&cm->caLock) != 0) {
04830         CYASSL_MSG("LockMutex on caLock failed");
04831         return BAD_MUTEX_E;
04832     }
04833 
04834     sz = GetCertCacheMemSize(cm);
04835 
04836     UnLockMutex(&cm->caLock);
04837 
04838     return sz;
04839 }
04840 
04841 #endif /* PERSIST_CERT_CACHE */
04842 #endif /* NO_CERTS */
04843 
04844 
04845 int CyaSSL_CTX_set_cipher_list(CYASSL_CTX* ctx, const char* list)
04846 {
04847     CYASSL_ENTER("CyaSSL_CTX_set_cipher_list");
04848     return (SetCipherList(&ctx->suites, list)) ? SSL_SUCCESS : SSL_FAILURE;
04849 }
04850 
04851 
04852 int CyaSSL_set_cipher_list(CYASSL* ssl, const char* list)
04853 {
04854     CYASSL_ENTER("CyaSSL_set_cipher_list");
04855     return (SetCipherList(ssl->suites, list)) ? SSL_SUCCESS : SSL_FAILURE;
04856 }
04857 
04858 
04859 #ifndef CYASSL_LEANPSK
04860 #ifdef CYASSL_DTLS
04861 
04862 int CyaSSL_dtls_get_current_timeout(CYASSL* ssl)
04863 {
04864     (void)ssl;
04865 
04866     return ssl->dtls_timeout;
04867 }
04868 
04869 
04870 /* user may need to alter init dtls recv timeout, SSL_SUCCESS on ok */
04871 int CyaSSL_dtls_set_timeout_init(CYASSL* ssl, int timeout)
04872 {
04873     if (ssl == NULL || timeout < 0)
04874         return BAD_FUNC_ARG;
04875 
04876     if (timeout > ssl->dtls_timeout_max) {
04877         CYASSL_MSG("Can't set dtls timeout init greater than dtls timeout max");
04878         return BAD_FUNC_ARG;
04879     }
04880 
04881     ssl->dtls_timeout_init = timeout;
04882     ssl->dtls_timeout = timeout;
04883 
04884     return SSL_SUCCESS;
04885 }
04886 
04887 
04888 /* user may need to alter max dtls recv timeout, SSL_SUCCESS on ok */
04889 int CyaSSL_dtls_set_timeout_max(CYASSL* ssl, int timeout)
04890 {
04891     if (ssl == NULL || timeout < 0)
04892         return BAD_FUNC_ARG;
04893 
04894     if (timeout < ssl->dtls_timeout_init) {
04895         CYASSL_MSG("Can't set dtls timeout max less than dtls timeout init");
04896         return BAD_FUNC_ARG;
04897     }
04898 
04899     ssl->dtls_timeout_max = timeout;
04900 
04901     return SSL_SUCCESS;
04902 }
04903 
04904 
04905 int CyaSSL_dtls_got_timeout(CYASSL* ssl)
04906 {
04907     int result = SSL_SUCCESS;
04908 
04909     DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
04910     ssl->dtls_msg_list = NULL;
04911     if (DtlsPoolTimeout(ssl) < 0 || DtlsPoolSend(ssl) < 0) {
04912         result = SSL_FATAL_ERROR;
04913     }
04914     return result;
04915 }
04916 
04917 #endif /* DTLS */
04918 #endif /* LEANPSK */
04919 
04920 
04921 /* client only parts */
04922 #ifndef NO_CYASSL_CLIENT
04923 
04924     #ifndef NO_OLD_TLS
04925     CYASSL_METHOD* CyaSSLv3_client_method(void)
04926     {
04927         CYASSL_METHOD* method =
04928                               (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
04929                                                        DYNAMIC_TYPE_METHOD);
04930         CYASSL_ENTER("SSLv3_client_method");
04931         if (method)
04932             InitSSL_Method(method, MakeSSLv3());
04933         return method;
04934     }
04935     #endif
04936 
04937     #ifdef CYASSL_DTLS
04938         CYASSL_METHOD* CyaDTLSv1_client_method(void)
04939         {
04940             CYASSL_METHOD* method =
04941                               (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
04942                                                        DYNAMIC_TYPE_METHOD);
04943             CYASSL_ENTER("DTLSv1_client_method");
04944             if (method)
04945                 InitSSL_Method(method, MakeDTLSv1());
04946             return method;
04947         }
04948 
04949         CYASSL_METHOD* CyaDTLSv1_2_client_method(void)
04950         {
04951             CYASSL_METHOD* method =
04952                               (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
04953                                                        DYNAMIC_TYPE_METHOD);
04954             CYASSL_ENTER("DTLSv1_2_client_method");
04955             if (method)
04956                 InitSSL_Method(method, MakeDTLSv1_2());
04957             return method;
04958         }
04959     #endif
04960 
04961 
04962     /* please see note at top of README if you get an error from connect */
04963     int CyaSSL_connect(CYASSL* ssl)
04964     {
04965         int neededState;
04966 
04967         CYASSL_ENTER("SSL_connect()");
04968 
04969         #ifdef HAVE_ERRNO_H
04970             errno = 0;
04971         #endif
04972 
04973         if (ssl->options.side != CYASSL_CLIENT_END) {
04974             CYASSL_ERROR(ssl->error = SIDE_ERROR);
04975             return SSL_FATAL_ERROR;
04976         }
04977 
04978         #ifdef CYASSL_DTLS
04979             if (ssl->version.major == DTLS_MAJOR) {
04980                 ssl->options.dtls   = 1;
04981                 ssl->options.tls    = 1;
04982                 ssl->options.tls1_1 = 1;
04983 
04984                 if (DtlsPoolInit(ssl) != 0) {
04985                     ssl->error = MEMORY_ERROR;
04986                     CYASSL_ERROR(ssl->error);
04987                     return SSL_FATAL_ERROR;
04988                 }
04989             }
04990         #endif
04991 
04992         if (ssl->buffers.outputBuffer.length > 0) {
04993             if ( (ssl->error = SendBuffered(ssl)) == 0) {
04994                 ssl->options.connectState++;
04995                 CYASSL_MSG("connect state: Advanced from buffered send");
04996             }
04997             else {
04998                 CYASSL_ERROR(ssl->error);
04999                 return SSL_FATAL_ERROR;
05000             }
05001         }
05002 
05003         switch (ssl->options.connectState) {
05004 
05005         case CONNECT_BEGIN :
05006             /* always send client hello first */
05007             if ( (ssl->error = SendClientHello(ssl)) != 0) {
05008                 CYASSL_ERROR(ssl->error);
05009                 return SSL_FATAL_ERROR;
05010             }
05011             ssl->options.connectState = CLIENT_HELLO_SENT;
05012             CYASSL_MSG("connect state: CLIENT_HELLO_SENT");
05013 
05014         case CLIENT_HELLO_SENT :
05015             neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
05016                                           SERVER_HELLODONE_COMPLETE;
05017             #ifdef CYASSL_DTLS
05018                 /* In DTLS, when resuming, we can go straight to FINISHED,
05019                  * or do a cookie exchange and then skip to FINISHED, assume
05020                  * we need the cookie exchange first. */
05021                 if (ssl->options.dtls)
05022                     neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
05023             #endif
05024             /* get response */
05025             while (ssl->options.serverState < neededState) {
05026                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
05027                     CYASSL_ERROR(ssl->error);
05028                     return SSL_FATAL_ERROR;
05029                 }
05030                 /* if resumption failed, reset needed state */
05031                 else if (neededState == SERVER_FINISHED_COMPLETE)
05032                     if (!ssl->options.resuming) {
05033                         if (!ssl->options.dtls)
05034                             neededState = SERVER_HELLODONE_COMPLETE;
05035                         else
05036                             neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
05037                     }
05038             }
05039 
05040             ssl->options.connectState = HELLO_AGAIN;
05041             CYASSL_MSG("connect state: HELLO_AGAIN");
05042 
05043         case HELLO_AGAIN :
05044             if (ssl->options.certOnly)
05045                 return SSL_SUCCESS;
05046 
05047             #ifdef CYASSL_DTLS
05048                 if (ssl->options.dtls) {
05049                     /* re-init hashes, exclude first hello and verify request */
05050 #ifndef NO_OLD_TLS
05051                     InitMd5(&ssl->hashMd5);
05052                     if ( (ssl->error = InitSha(&ssl->hashSha)) != 0) {
05053                         CYASSL_ERROR(ssl->error);
05054                         return SSL_FATAL_ERROR;
05055                     }
05056 #endif
05057                     if (IsAtLeastTLSv1_2(ssl)) {
05058                         #ifndef NO_SHA256
05059                             if ( (ssl->error =
05060                                            InitSha256(&ssl->hashSha256)) != 0) {
05061                                 CYASSL_ERROR(ssl->error);
05062                                 return SSL_FATAL_ERROR;
05063                             }
05064                         #endif
05065                         #ifdef CYASSL_SHA384
05066                             if ( (ssl->error =
05067                                            InitSha384(&ssl->hashSha384)) != 0) {
05068                                 CYASSL_ERROR(ssl->error);
05069                                 return SSL_FATAL_ERROR;
05070                             }
05071                         #endif
05072                     }
05073                     if ( (ssl->error = SendClientHello(ssl)) != 0) {
05074                         CYASSL_ERROR(ssl->error);
05075                         return SSL_FATAL_ERROR;
05076                     }
05077                 }
05078             #endif
05079 
05080             ssl->options.connectState = HELLO_AGAIN_REPLY;
05081             CYASSL_MSG("connect state: HELLO_AGAIN_REPLY");
05082 
05083         case HELLO_AGAIN_REPLY :
05084             #ifdef CYASSL_DTLS
05085                 if (ssl->options.dtls) {
05086                     neededState = ssl->options.resuming ?
05087                            SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
05088 
05089                     /* get response */
05090                     while (ssl->options.serverState < neededState) {
05091                         if ( (ssl->error = ProcessReply(ssl)) < 0) {
05092                                 CYASSL_ERROR(ssl->error);
05093                                 return SSL_FATAL_ERROR;
05094                         }
05095                         /* if resumption failed, reset needed state */
05096                         else if (neededState == SERVER_FINISHED_COMPLETE)
05097                             if (!ssl->options.resuming)
05098                                 neededState = SERVER_HELLODONE_COMPLETE;
05099                     }
05100                 }
05101             #endif
05102 
05103             ssl->options.connectState = FIRST_REPLY_DONE;
05104             CYASSL_MSG("connect state: FIRST_REPLY_DONE");
05105 
05106         case FIRST_REPLY_DONE :
05107             #ifndef NO_CERTS
05108                 if (ssl->options.sendVerify) {
05109                     if ( (ssl->error = SendCertificate(ssl)) != 0) {
05110                         CYASSL_ERROR(ssl->error);
05111                         return SSL_FATAL_ERROR;
05112                     }
05113                     CYASSL_MSG("sent: certificate");
05114                 }
05115 
05116             #endif
05117             ssl->options.connectState = FIRST_REPLY_FIRST;
05118             CYASSL_MSG("connect state: FIRST_REPLY_FIRST");
05119 
05120         case FIRST_REPLY_FIRST :
05121             if (!ssl->options.resuming) {
05122                 if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
05123                     CYASSL_ERROR(ssl->error);
05124                     return SSL_FATAL_ERROR;
05125                 }
05126                 CYASSL_MSG("sent: client key exchange");
05127             }
05128 
05129             ssl->options.connectState = FIRST_REPLY_SECOND;
05130             CYASSL_MSG("connect state: FIRST_REPLY_SECOND");
05131 
05132         case FIRST_REPLY_SECOND :
05133             #ifndef NO_CERTS
05134                 if (ssl->options.sendVerify) {
05135                     if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
05136                         CYASSL_ERROR(ssl->error);
05137                         return SSL_FATAL_ERROR;
05138                     }
05139                     CYASSL_MSG("sent: certificate verify");
05140                 }
05141             #endif
05142             ssl->options.connectState = FIRST_REPLY_THIRD;
05143             CYASSL_MSG("connect state: FIRST_REPLY_THIRD");
05144 
05145         case FIRST_REPLY_THIRD :
05146             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
05147                 CYASSL_ERROR(ssl->error);
05148                 return SSL_FATAL_ERROR;
05149             }
05150             CYASSL_MSG("sent: change cipher spec");
05151             ssl->options.connectState = FIRST_REPLY_FOURTH;
05152             CYASSL_MSG("connect state: FIRST_REPLY_FOURTH");
05153 
05154         case FIRST_REPLY_FOURTH :
05155             if ( (ssl->error = SendFinished(ssl)) != 0) {
05156                 CYASSL_ERROR(ssl->error);
05157                 return SSL_FATAL_ERROR;
05158             }
05159             CYASSL_MSG("sent: finished");
05160             ssl->options.connectState = FINISHED_DONE;
05161             CYASSL_MSG("connect state: FINISHED_DONE");
05162 
05163         case FINISHED_DONE :
05164             /* get response */
05165             while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
05166                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
05167                     CYASSL_ERROR(ssl->error);
05168                     return SSL_FATAL_ERROR;
05169                 }
05170 
05171             ssl->options.connectState = SECOND_REPLY_DONE;
05172             CYASSL_MSG("connect state: SECOND_REPLY_DONE");
05173 
05174         case SECOND_REPLY_DONE:
05175             FreeHandshakeResources(ssl);
05176             CYASSL_LEAVE("SSL_connect()", SSL_SUCCESS);
05177             return SSL_SUCCESS;
05178 
05179         default:
05180             CYASSL_MSG("Unknown connect state ERROR");
05181             return SSL_FATAL_ERROR; /* unknown connect state */
05182         }
05183     }
05184 
05185 #endif /* NO_CYASSL_CLIENT */
05186 
05187 
05188 /* server only parts */
05189 #ifndef NO_CYASSL_SERVER
05190 
05191     #ifndef NO_OLD_TLS
05192     CYASSL_METHOD* CyaSSLv3_server_method(void)
05193     {
05194         CYASSL_METHOD* method =
05195                               (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
05196                                                        DYNAMIC_TYPE_METHOD);
05197         CYASSL_ENTER("SSLv3_server_method");
05198         if (method) {
05199             InitSSL_Method(method, MakeSSLv3());
05200             method->side = CYASSL_SERVER_END;
05201         }
05202         return method;
05203     }
05204     #endif
05205 
05206 
05207     #ifdef CYASSL_DTLS
05208         CYASSL_METHOD* CyaDTLSv1_server_method(void)
05209         {
05210             CYASSL_METHOD* method =
05211                               (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
05212                                                        DYNAMIC_TYPE_METHOD);
05213             CYASSL_ENTER("DTLSv1_server_method");
05214             if (method) {
05215                 InitSSL_Method(method, MakeDTLSv1());
05216                 method->side = CYASSL_SERVER_END;
05217             }
05218             return method;
05219         }
05220 
05221         CYASSL_METHOD* CyaDTLSv1_2_server_method(void)
05222         {
05223             CYASSL_METHOD* method =
05224                               (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
05225                                                        DYNAMIC_TYPE_METHOD);
05226             CYASSL_ENTER("DTLSv1_2_server_method");
05227             if (method) {
05228                 InitSSL_Method(method, MakeDTLSv1_2());
05229                 method->side = CYASSL_SERVER_END;
05230             }
05231             return method;
05232         }
05233     #endif
05234 
05235 
05236     int CyaSSL_accept(CYASSL* ssl)
05237     {
05238         byte havePSK = 0;
05239         byte haveAnon = 0;
05240         CYASSL_ENTER("SSL_accept()");
05241 
05242         #ifdef HAVE_ERRNO_H
05243             errno = 0;
05244         #endif
05245 
05246         #ifndef NO_PSK
05247             havePSK = ssl->options.havePSK;
05248         #endif
05249         (void)havePSK;
05250 
05251         #ifdef HAVE_ANON
05252             haveAnon = ssl->options.haveAnon;
05253         #endif
05254         (void)haveAnon;
05255 
05256         if (ssl->options.side != CYASSL_SERVER_END) {
05257             CYASSL_ERROR(ssl->error = SIDE_ERROR);
05258             return SSL_FATAL_ERROR;
05259         }
05260 
05261         #ifndef NO_CERTS
05262             /* in case used set_accept_state after init */
05263             if (!havePSK && !haveAnon &&
05264                             (ssl->buffers.certificate.buffer == NULL ||
05265                              ssl->buffers.key.buffer == NULL)) {
05266                 CYASSL_MSG("accept error: don't have server cert and key");
05267                 ssl->error = NO_PRIVATE_KEY;
05268                 CYASSL_ERROR(ssl->error);
05269                 return SSL_FATAL_ERROR;
05270             }
05271         #endif
05272 
05273         #ifdef CYASSL_DTLS
05274             if (ssl->version.major == DTLS_MAJOR) {
05275                 ssl->options.dtls   = 1;
05276                 ssl->options.tls    = 1;
05277                 ssl->options.tls1_1 = 1;
05278 
05279                 if (DtlsPoolInit(ssl) != 0) {
05280                     ssl->error = MEMORY_ERROR;
05281                     CYASSL_ERROR(ssl->error);
05282                     return SSL_FATAL_ERROR;
05283                 }
05284             }
05285         #endif
05286 
05287         if (ssl->buffers.outputBuffer.length > 0) {
05288             if ( (ssl->error = SendBuffered(ssl)) == 0) {
05289                 ssl->options.acceptState++;
05290                 CYASSL_MSG("accept state: Advanced from buffered send");
05291             }
05292             else {
05293                 CYASSL_ERROR(ssl->error);
05294                 return SSL_FATAL_ERROR;
05295             }
05296         }
05297 
05298         switch (ssl->options.acceptState) {
05299 
05300         case ACCEPT_BEGIN :
05301             /* get response */
05302             while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
05303                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
05304                     CYASSL_ERROR(ssl->error);
05305                     return SSL_FATAL_ERROR;
05306                 }
05307             ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
05308             CYASSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
05309 
05310         case ACCEPT_CLIENT_HELLO_DONE :
05311             #ifdef CYASSL_DTLS
05312                 if (ssl->options.dtls)
05313                     if ( (ssl->error = SendHelloVerifyRequest(ssl)) != 0) {
05314                         CYASSL_ERROR(ssl->error);
05315                         return SSL_FATAL_ERROR;
05316                     }
05317             #endif
05318             ssl->options.acceptState = HELLO_VERIFY_SENT;
05319             CYASSL_MSG("accept state HELLO_VERIFY_SENT");
05320 
05321         case HELLO_VERIFY_SENT:
05322             #ifdef CYASSL_DTLS
05323                 if (ssl->options.dtls) {
05324                     ssl->options.clientState = NULL_STATE;  /* get again */
05325                     /* reset messages received */
05326                     XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
05327                     /* re-init hashes, exclude first hello and verify request */
05328 #ifndef NO_OLD_TLS
05329                     InitMd5(&ssl->hashMd5);
05330                     if ( (ssl->error = InitSha(&ssl->hashSha)) != 0) {
05331                         CYASSL_ERROR(ssl->error);
05332                         return SSL_FATAL_ERROR;
05333                     }
05334 #endif
05335                     if (IsAtLeastTLSv1_2(ssl)) {
05336                         #ifndef NO_SHA256
05337                             if ( (ssl->error =
05338                                            InitSha256(&ssl->hashSha256)) != 0) {
05339                                CYASSL_ERROR(ssl->error);
05340                                return SSL_FATAL_ERROR;
05341                             }
05342                         #endif
05343                         #ifdef CYASSL_SHA384
05344                             if ( (ssl->error =
05345                                            InitSha384(&ssl->hashSha384)) != 0) {
05346                                CYASSL_ERROR(ssl->error);
05347                                return SSL_FATAL_ERROR;
05348                             }
05349                         #endif
05350                     }
05351 
05352                     while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
05353                         if ( (ssl->error = ProcessReply(ssl)) < 0) {
05354                             CYASSL_ERROR(ssl->error);
05355                             return SSL_FATAL_ERROR;
05356                         }
05357                 }
05358             #endif
05359             ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
05360             CYASSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
05361 
05362         case ACCEPT_FIRST_REPLY_DONE :
05363             if ( (ssl->error = SendServerHello(ssl)) != 0) {
05364                 CYASSL_ERROR(ssl->error);
05365                 return SSL_FATAL_ERROR;
05366             }
05367             ssl->options.acceptState = SERVER_HELLO_SENT;
05368             CYASSL_MSG("accept state SERVER_HELLO_SENT");
05369 
05370         case SERVER_HELLO_SENT :
05371             #ifndef NO_CERTS
05372                 if (!ssl->options.resuming)
05373                     if ( (ssl->error = SendCertificate(ssl)) != 0) {
05374                         CYASSL_ERROR(ssl->error);
05375                         return SSL_FATAL_ERROR;
05376                     }
05377             #endif
05378             ssl->options.acceptState = CERT_SENT;
05379             CYASSL_MSG("accept state CERT_SENT");
05380 
05381         case CERT_SENT :
05382             if (!ssl->options.resuming)
05383                 if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
05384                     CYASSL_ERROR(ssl->error);
05385                     return SSL_FATAL_ERROR;
05386                 }
05387             ssl->options.acceptState = KEY_EXCHANGE_SENT;
05388             CYASSL_MSG("accept state KEY_EXCHANGE_SENT");
05389 
05390         case KEY_EXCHANGE_SENT :
05391             #ifndef NO_CERTS
05392                 if (!ssl->options.resuming)
05393                     if (ssl->options.verifyPeer)
05394                         if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
05395                             CYASSL_ERROR(ssl->error);
05396                             return SSL_FATAL_ERROR;
05397                         }
05398             #endif
05399             ssl->options.acceptState = CERT_REQ_SENT;
05400             CYASSL_MSG("accept state CERT_REQ_SENT");
05401 
05402         case CERT_REQ_SENT :
05403             if (!ssl->options.resuming)
05404                 if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
05405                     CYASSL_ERROR(ssl->error);
05406                     return SSL_FATAL_ERROR;
05407                 }
05408             ssl->options.acceptState = SERVER_HELLO_DONE;
05409             CYASSL_MSG("accept state SERVER_HELLO_DONE");
05410 
05411         case SERVER_HELLO_DONE :
05412             if (!ssl->options.resuming) {
05413                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
05414                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
05415                         CYASSL_ERROR(ssl->error);
05416                         return SSL_FATAL_ERROR;
05417                     }
05418             }
05419             ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
05420             CYASSL_MSG("accept state  ACCEPT_SECOND_REPLY_DONE");
05421 
05422         case ACCEPT_SECOND_REPLY_DONE :
05423             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
05424                 CYASSL_ERROR(ssl->error);
05425                 return SSL_FATAL_ERROR;
05426             }
05427             ssl->options.acceptState = CHANGE_CIPHER_SENT;
05428             CYASSL_MSG("accept state  CHANGE_CIPHER_SENT");
05429 
05430         case CHANGE_CIPHER_SENT :
05431             if ( (ssl->error = SendFinished(ssl)) != 0) {
05432                 CYASSL_ERROR(ssl->error);
05433                 return SSL_FATAL_ERROR;
05434             }
05435 
05436             ssl->options.acceptState = ACCEPT_FINISHED_DONE;
05437             CYASSL_MSG("accept state ACCEPT_FINISHED_DONE");
05438 
05439         case ACCEPT_FINISHED_DONE :
05440             if (ssl->options.resuming)
05441                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
05442                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
05443                         CYASSL_ERROR(ssl->error);
05444                         return SSL_FATAL_ERROR;
05445                     }
05446 
05447             ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
05448             CYASSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
05449 
05450         case ACCEPT_THIRD_REPLY_DONE :
05451             FreeHandshakeResources(ssl);
05452             CYASSL_LEAVE("SSL_accept()", SSL_SUCCESS);
05453             return SSL_SUCCESS;
05454 
05455         default :
05456             CYASSL_MSG("Unknown accept state ERROR");
05457             return SSL_FATAL_ERROR;
05458         }
05459     }
05460 
05461 #endif /* NO_CYASSL_SERVER */
05462 
05463 
05464 int CyaSSL_Cleanup(void)
05465 {
05466     int ret = SSL_SUCCESS;
05467     int release = 0;
05468 
05469     CYASSL_ENTER("CyaSSL_Cleanup");
05470 
05471     if (initRefCount == 0)
05472         return ret;  /* possibly no init yet, but not failure either way */
05473 
05474     if (LockMutex(&count_mutex) != 0) {
05475         CYASSL_MSG("Bad Lock Mutex count");
05476         return BAD_MUTEX_E;
05477     }
05478 
05479     release = initRefCount-- == 1;
05480     if (initRefCount < 0)
05481         initRefCount = 0;
05482 
05483     UnLockMutex(&count_mutex);
05484 
05485     if (!release)
05486         return ret;
05487 
05488 #ifndef NO_SESSION_CACHE
05489     if (FreeMutex(&session_mutex) != 0)
05490         ret = BAD_MUTEX_E;
05491 #endif
05492     if (FreeMutex(&count_mutex) != 0)
05493         ret = BAD_MUTEX_E;
05494 
05495 #if defined(HAVE_ECC) && defined(FP_ECC)
05496     ecc_fp_free();
05497 #endif
05498 
05499     return ret;
05500 }
05501 
05502 
05503 #ifndef NO_SESSION_CACHE
05504 
05505 
05506 /* some session IDs aren't random afterall, let's make them random */
05507 static INLINE word32 HashSession(const byte* sessionID, word32 len, int* error)
05508 {
05509     byte digest[MD5_DIGEST_SIZE];
05510 
05511 #ifndef NO_MD5
05512     *error =    Md5Hash(sessionID, len, digest);
05513 #elif !defined(NO_SHA)
05514     *error =    ShaHash(sessionID, len, digest);
05515 #elif !defined(NO_SHA256)
05516     *error = Sha256Hash(sessionID, len, digest);
05517 #else
05518     #error "We need a digest to hash the session IDs"
05519 #endif
05520 
05521     return *error == 0 ? MakeWordFromHash(digest) : 0; /* 0 on failure */
05522 }
05523 
05524 
05525 void CyaSSL_flush_sessions(CYASSL_CTX* ctx, long tm)
05526 {
05527     /* static table now, no flusing needed */
05528     (void)ctx;
05529     (void)tm;
05530 }
05531 
05532 
05533 /* set ssl session timeout in seconds */
05534 int CyaSSL_set_timeout(CYASSL* ssl, unsigned int to)
05535 {
05536     if (ssl == NULL)
05537         return BAD_FUNC_ARG;
05538 
05539     ssl->timeout = to;
05540 
05541     return SSL_SUCCESS;
05542 }
05543 
05544 
05545 /* set ctx session timeout in seconds */
05546 int CyaSSL_CTX_set_timeout(CYASSL_CTX* ctx, unsigned int to)
05547 {
05548     if (ctx == NULL)
05549         return BAD_FUNC_ARG;
05550 
05551     ctx->timeout = to;
05552 
05553     return SSL_SUCCESS;
05554 }
05555 
05556 
05557 #ifndef NO_CLIENT_CACHE
05558 
05559 /* Get Session from Client cache based on id/len, return NULL on failure */
05560 CYASSL_SESSION* GetSessionClient(CYASSL* ssl, const byte* id, int len)
05561 {
05562     CYASSL_SESSION* ret = NULL;
05563     word32          row;
05564     int             idx;
05565     int             count;
05566     int             error = 0;
05567 
05568     CYASSL_ENTER("GetSessionClient");
05569 
05570     if (ssl->options.side == CYASSL_SERVER_END)
05571         return NULL;
05572 
05573     len = min(SERVER_ID_LEN, (word32)len);
05574     row = HashSession(id, len, &error) % SESSION_ROWS;
05575     if (error != 0) {
05576         CYASSL_MSG("Hash session failed");
05577         return NULL;
05578     }
05579 
05580     if (LockMutex(&session_mutex) != 0) {
05581         CYASSL_MSG("Lock session mutex failed");
05582         return NULL;
05583     }
05584 
05585     /* start from most recently used */
05586     count = min((word32)ClientCache[row].totalCount, SESSIONS_PER_ROW);
05587     idx = ClientCache[row].nextIdx - 1;
05588     if (idx < 0)
05589         idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
05590 
05591     for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
05592         CYASSL_SESSION* current;
05593         ClientSession   clSess;
05594 
05595         if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
05596             CYASSL_MSG("Bad idx");
05597             break;
05598         }
05599 
05600         clSess = ClientCache[row].Clients[idx];
05601 
05602         current = &SessionCache[clSess.serverRow].Sessions[clSess.serverIdx];
05603         if (XMEMCMP(current->serverID, id, len) == 0) {
05604             CYASSL_MSG("Found a serverid match for client");
05605             if (LowResTimer() < (current->bornOn + current->timeout)) {
05606                 CYASSL_MSG("Session valid");
05607                 ret = current;
05608                 break;
05609             } else {
05610                 CYASSL_MSG("Session timed out");  /* could have more for id */
05611             }
05612         } else {
05613             CYASSL_MSG("ServerID not a match from client table");
05614         }
05615     }
05616 
05617     UnLockMutex(&session_mutex);
05618 
05619     return ret;
05620 }
05621 
05622 #endif /* NO_CLIENT_CACHE */
05623 
05624 
05625 CYASSL_SESSION* GetSession(CYASSL* ssl, byte* masterSecret)
05626 {
05627     CYASSL_SESSION* ret = 0;
05628     const byte*  id = NULL;
05629     word32       row;
05630     int          idx;
05631     int          count;
05632     int          error = 0;
05633 
05634     if (ssl->options.sessionCacheOff)
05635         return NULL;
05636 
05637     if (ssl->options.haveSessionId == 0)
05638         return NULL;
05639 
05640     if (ssl->arrays)
05641         id = ssl->arrays->sessionID;
05642     else
05643         id = ssl->session.sessionID;
05644 
05645     row = HashSession(id, ID_LEN, &error) % SESSION_ROWS;
05646     if (error != 0) {
05647         CYASSL_MSG("Hash session failed");
05648         return NULL;
05649     }
05650 
05651     if (LockMutex(&session_mutex) != 0)
05652         return 0;
05653 
05654     /* start from most recently used */
05655     count = min((word32)SessionCache[row].totalCount, SESSIONS_PER_ROW);
05656     idx = SessionCache[row].nextIdx - 1;
05657     if (idx < 0)
05658         idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
05659 
05660     for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
05661         CYASSL_SESSION* current;
05662 
05663         if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
05664             CYASSL_MSG("Bad idx");
05665             break;
05666         }
05667 
05668         current = &SessionCache[row].Sessions[idx];
05669         if (XMEMCMP(current->sessionID, id, ID_LEN) == 0) {
05670             CYASSL_MSG("Found a session match");
05671             if (LowResTimer() < (current->bornOn + current->timeout)) {
05672                 CYASSL_MSG("Session valid");
05673                 ret = current;
05674                 if (masterSecret)
05675                     XMEMCPY(masterSecret, current->masterSecret, SECRET_LEN);
05676             } else {
05677                 CYASSL_MSG("Session timed out");
05678             }
05679             break;  /* no more sessionIDs whether valid or not that match */
05680         } else {
05681             CYASSL_MSG("SessionID not a match at this idx");
05682         }
05683     }
05684 
05685     UnLockMutex(&session_mutex);
05686 
05687     return ret;
05688 }
05689 
05690 
05691 int SetSession(CYASSL* ssl, CYASSL_SESSION* session)
05692 {
05693     if (ssl->options.sessionCacheOff)
05694         return SSL_FAILURE;
05695 
05696     if (LowResTimer() < (session->bornOn + session->timeout)) {
05697         ssl->session  = *session;
05698         ssl->options.resuming = 1;
05699 
05700 #ifdef SESSION_CERTS
05701         ssl->version              = session->version;
05702         ssl->options.cipherSuite0 = session->cipherSuite0;
05703         ssl->options.cipherSuite  = session->cipherSuite;
05704 #endif
05705 
05706         return SSL_SUCCESS;
05707     }
05708     return SSL_FAILURE;  /* session timed out */
05709 }
05710 
05711 
05712 int AddSession(CYASSL* ssl)
05713 {
05714     word32 row, idx;
05715     int    error = 0;
05716 
05717     if (ssl->options.sessionCacheOff)
05718         return 0;
05719 
05720     if (ssl->options.haveSessionId == 0)
05721         return 0;
05722 
05723     row = HashSession(ssl->arrays->sessionID, ID_LEN, &error) % SESSION_ROWS;
05724     if (error != 0) {
05725         CYASSL_MSG("Hash session failed");
05726         return error;
05727     }
05728 
05729     if (LockMutex(&session_mutex) != 0)
05730         return BAD_MUTEX_E;
05731 
05732     idx = SessionCache[row].nextIdx++;
05733 #ifdef SESSION_INDEX
05734     ssl->sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx;
05735 #endif
05736 
05737     XMEMCPY(SessionCache[row].Sessions[idx].masterSecret,
05738            ssl->arrays->masterSecret, SECRET_LEN);
05739     XMEMCPY(SessionCache[row].Sessions[idx].sessionID, ssl->arrays->sessionID,
05740            ID_LEN);
05741     SessionCache[row].Sessions[idx].sessionIDSz = ssl->arrays->sessionIDSz;
05742 
05743     SessionCache[row].Sessions[idx].timeout = ssl->timeout;
05744     SessionCache[row].Sessions[idx].bornOn  = LowResTimer();
05745 
05746 #ifdef HAVE_SESSION_TICKET
05747     SessionCache[row].Sessions[idx].ticketLen     = ssl->session.ticketLen;
05748     XMEMCPY(SessionCache[row].Sessions[idx].ticket,
05749                                    ssl->session.ticket, ssl->session.ticketLen);
05750 #endif
05751 
05752 #ifdef SESSION_CERTS
05753     SessionCache[row].Sessions[idx].chain.count = ssl->session.chain.count;
05754     XMEMCPY(SessionCache[row].Sessions[idx].chain.certs,
05755            ssl->session.chain.certs, sizeof(x509_buffer) * MAX_CHAIN_DEPTH);
05756 
05757     SessionCache[row].Sessions[idx].version      = ssl->version;
05758     SessionCache[row].Sessions[idx].cipherSuite0 = ssl->options.cipherSuite0;
05759     SessionCache[row].Sessions[idx].cipherSuite  = ssl->options.cipherSuite;
05760 #endif /* SESSION_CERTS */
05761 
05762     SessionCache[row].totalCount++;
05763     if (SessionCache[row].nextIdx == SESSIONS_PER_ROW)
05764         SessionCache[row].nextIdx = 0;
05765 
05766 #ifndef NO_CLIENT_CACHE
05767     if (ssl->options.side == CYASSL_CLIENT_END && ssl->session.idLen) {
05768         word32 clientRow, clientIdx;
05769 
05770         CYASSL_MSG("Adding client cache entry");
05771 
05772         SessionCache[row].Sessions[idx].idLen = ssl->session.idLen;
05773         XMEMCPY(SessionCache[row].Sessions[idx].serverID, ssl->session.serverID,
05774                 ssl->session.idLen);
05775 
05776         clientRow = HashSession(ssl->session.serverID, ssl->session.idLen,
05777                                 &error) % SESSION_ROWS;
05778         if (error != 0) {
05779             CYASSL_MSG("Hash session failed");
05780         } else {
05781             clientIdx = ClientCache[clientRow].nextIdx++;
05782 
05783             ClientCache[clientRow].Clients[clientIdx].serverRow = (word16)row;
05784             ClientCache[clientRow].Clients[clientIdx].serverIdx = (word16)idx;
05785 
05786             ClientCache[clientRow].totalCount++;
05787             if (ClientCache[clientRow].nextIdx == SESSIONS_PER_ROW)
05788                 ClientCache[clientRow].nextIdx = 0;
05789         }
05790     }
05791     else
05792         SessionCache[row].Sessions[idx].idLen = 0;
05793 #endif /* NO_CLIENT_CACHE */
05794 
05795     if (UnLockMutex(&session_mutex) != 0)
05796         return BAD_MUTEX_E;
05797 
05798     return error;
05799 }
05800 
05801 
05802 #ifdef SESSION_INDEX
05803 
05804 int CyaSSL_GetSessionIndex(CYASSL* ssl)
05805 {
05806     CYASSL_ENTER("CyaSSL_GetSessionIndex");
05807     CYASSL_LEAVE("CyaSSL_GetSessionIndex", ssl->sessionIndex);
05808     return ssl->sessionIndex;
05809 }
05810 
05811 
05812 int CyaSSL_GetSessionAtIndex(int idx, CYASSL_SESSION* session)
05813 {
05814     int row, col, result = SSL_FAILURE;
05815 
05816     CYASSL_ENTER("CyaSSL_GetSessionAtIndex");
05817 
05818     row = idx >> SESSIDX_ROW_SHIFT;
05819     col = idx & SESSIDX_IDX_MASK;
05820 
05821     if (LockMutex(&session_mutex) != 0) {
05822         return BAD_MUTEX_E;
05823     }
05824 
05825     if (row < SESSION_ROWS &&
05826         col < (int)min(SessionCache[row].totalCount, SESSIONS_PER_ROW)) {
05827         XMEMCPY(session,
05828                  &SessionCache[row].Sessions[col], sizeof(CYASSL_SESSION));
05829         result = SSL_SUCCESS;
05830     }
05831 
05832     if (UnLockMutex(&session_mutex) != 0)
05833         result = BAD_MUTEX_E;
05834 
05835     CYASSL_LEAVE("CyaSSL_GetSessionAtIndex", result);
05836     return result;
05837 }
05838 
05839 #endif /* SESSION_INDEX */
05840 
05841 #if defined(SESSION_INDEX) && defined(SESSION_CERTS)
05842 
05843 CYASSL_X509_CHAIN* CyaSSL_SESSION_get_peer_chain(CYASSL_SESSION* session)
05844 {
05845     CYASSL_X509_CHAIN* chain = NULL;
05846 
05847     CYASSL_ENTER("CyaSSL_SESSION_get_peer_chain");
05848     if (session)
05849         chain = &session->chain;
05850 
05851     CYASSL_LEAVE("CyaSSL_SESSION_get_peer_chain", chain ? 1 : 0);
05852     return chain;
05853 }
05854 
05855 #endif /* SESSION_INDEX && SESSION_CERTS */
05856 
05857 
05858     #ifdef SESSION_STATS
05859 
05860     CYASSL_API
05861     void PrintSessionStats(void)
05862     {
05863         word32 totalSessionsSeen = 0;
05864         word32 totalSessionsNow = 0;
05865         word32 rowNow;
05866         int    i;
05867         double E;               /* expected freq */
05868         double chiSquare = 0;
05869 
05870         for (i = 0; i < SESSION_ROWS; i++) {
05871             totalSessionsSeen += SessionCache[i].totalCount;
05872 
05873             if (SessionCache[i].totalCount >= SESSIONS_PER_ROW)
05874                 rowNow = SESSIONS_PER_ROW;
05875             else if (SessionCache[i].nextIdx == 0)
05876                 rowNow = 0;
05877             else
05878                 rowNow = SessionCache[i].nextIdx;
05879 
05880             totalSessionsNow += rowNow;
05881         }
05882 
05883         printf("Total Sessions Seen = %d\n", totalSessionsSeen);
05884         printf("Total Sessions Now  = %d\n", totalSessionsNow);
05885 
05886         E = (double)totalSessionsSeen / SESSION_ROWS;
05887 
05888         for (i = 0; i < SESSION_ROWS; i++) {
05889             double diff = SessionCache[i].totalCount - E;
05890             diff *= diff;                /* square    */
05891             diff /= E;                   /* normalize */
05892 
05893             chiSquare += diff;
05894         }
05895         printf("  chi-square = %5.1f, d.f. = %d\n", chiSquare,
05896                                                      SESSION_ROWS - 1);
05897         if (SESSION_ROWS == 11)
05898             printf(" .05 p value =  18.3, chi-square should be less\n");
05899         else if (SESSION_ROWS == 211)
05900             printf(".05 p value  = 244.8, chi-square should be less\n");
05901         else if (SESSION_ROWS == 5981)
05902             printf(".05 p value  = 6161.0, chi-square should be less\n");
05903         else if (SESSION_ROWS == 3)
05904             printf(".05 p value  =   6.0, chi-square should be less\n");
05905         else if (SESSION_ROWS == 2861)
05906             printf(".05 p value  = 2985.5, chi-square should be less\n");
05907         printf("\n");
05908     }
05909 
05910     #endif /* SESSION_STATS */
05911 
05912 #else  /* NO_SESSION_CACHE */
05913 
05914 /* No session cache version */
05915 CYASSL_SESSION* GetSession(CYASSL* ssl, byte* masterSecret)
05916 {
05917     (void)ssl;
05918     (void)masterSecret;
05919 
05920     return NULL;
05921 }
05922 
05923 #endif /* NO_SESSION_CACHE */
05924 
05925 
05926 /* call before SSL_connect, if verifying will add name check to
05927    date check and signature check */
05928 int CyaSSL_check_domain_name(CYASSL* ssl, const char* dn)
05929 {
05930     CYASSL_ENTER("CyaSSL_check_domain_name");
05931     if (ssl->buffers.domainName.buffer)
05932         XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
05933 
05934     ssl->buffers.domainName.length = (word32)XSTRLEN(dn) + 1;
05935     ssl->buffers.domainName.buffer = (byte*) XMALLOC(
05936                 ssl->buffers.domainName.length, ssl->heap, DYNAMIC_TYPE_DOMAIN);
05937 
05938     if (ssl->buffers.domainName.buffer) {
05939         XSTRNCPY((char*)ssl->buffers.domainName.buffer, dn,
05940                 ssl->buffers.domainName.length);
05941         return SSL_SUCCESS;
05942     }
05943     else {
05944         ssl->error = MEMORY_ERROR;
05945         return SSL_FAILURE;
05946     }
05947 }
05948 
05949 
05950 /* turn on CyaSSL zlib compression
05951    returns SSL_SUCCESS for success, else error (not built in)
05952 */
05953 int CyaSSL_set_compression(CYASSL* ssl)
05954 {
05955     CYASSL_ENTER("CyaSSL_set_compression");
05956     (void)ssl;
05957 #ifdef HAVE_LIBZ
05958     ssl->options.usingCompression = 1;
05959     return SSL_SUCCESS;
05960 #else
05961     return NOT_COMPILED_IN;
05962 #endif
05963 }
05964 
05965 
05966 #ifndef USE_WINDOWS_API
05967     #ifndef NO_WRITEV
05968 
05969         /* simulate writev semantics, doesn't actually do block at a time though
05970            because of SSL_write behavior and because front adds may be small */
05971         int CyaSSL_writev(CYASSL* ssl, const struct iovec* iov, int iovcnt)
05972         {
05973         #ifdef CYASSL_SMALL_STACK
05974             byte   staticBuffer[1]; /* force heap usage */
05975         #else
05976             byte   staticBuffer[FILE_BUFFER_SIZE];
05977         #endif
05978             byte* myBuffer  = staticBuffer;
05979             int   dynamic   = 0;
05980             int   sending   = 0;
05981             int   idx       = 0;
05982             int   i;
05983             int   ret;
05984 
05985             CYASSL_ENTER("CyaSSL_writev");
05986 
05987             for (i = 0; i < iovcnt; i++)
05988                 sending += (int)iov[i].iov_len;
05989 
05990             if (sending > (int)sizeof(staticBuffer)) {
05991                 myBuffer = (byte*)XMALLOC(sending, ssl->heap,
05992                                                            DYNAMIC_TYPE_WRITEV);
05993                 if (!myBuffer)
05994                     return MEMORY_ERROR;
05995 
05996                 dynamic = 1;
05997             }
05998 
05999             for (i = 0; i < iovcnt; i++) {
06000                 XMEMCPY(&myBuffer[idx], iov[i].iov_base, iov[i].iov_len);
06001                 idx += (int)iov[i].iov_len;
06002             }
06003 
06004             ret = CyaSSL_write(ssl, myBuffer, sending);
06005 
06006             if (dynamic)
06007                 XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
06008 
06009             return ret;
06010         }
06011     #endif
06012 #endif
06013 
06014 
06015 #ifdef CYASSL_CALLBACKS
06016 
06017     typedef struct itimerval Itimerval;
06018 
06019     /* don't keep calling simple functions while setting up timer and singals
06020        if no inlining these are the next best */
06021 
06022     #define AddTimes(a, b, c)                       \
06023         do {                                        \
06024             c.tv_sec  = a.tv_sec  + b.tv_sec;       \
06025             c.tv_usec = a.tv_usec + b.tv_usec;      \
06026             if (c.tv_usec >=  1000000) {            \
06027                 c.tv_sec++;                         \
06028                 c.tv_usec -= 1000000;               \
06029             }                                       \
06030         } while (0)
06031 
06032 
06033     #define SubtractTimes(a, b, c)                  \
06034         do {                                        \
06035             c.tv_sec  = a.tv_sec  - b.tv_sec;       \
06036             c.tv_usec = a.tv_usec - b.tv_usec;      \
06037             if (c.tv_usec < 0) {                    \
06038                 c.tv_sec--;                         \
06039                 c.tv_usec += 1000000;               \
06040             }                                       \
06041         } while (0)
06042 
06043     #define CmpTimes(a, b, cmp)                     \
06044         ((a.tv_sec  ==  b.tv_sec) ?                 \
06045             (a.tv_usec cmp b.tv_usec) :             \
06046             (a.tv_sec  cmp b.tv_sec))               \
06047 
06048 
06049     /* do nothing handler */
06050     static void myHandler(int signo)
06051     {
06052         (void)signo;
06053         return;
06054     }
06055 
06056 
06057     static int CyaSSL_ex_wrapper(CYASSL* ssl, HandShakeCallBack hsCb,
06058                                  TimeoutCallBack toCb, Timeval timeout)
06059     {
06060         int       ret        = SSL_FATAL_ERROR;
06061         int       oldTimerOn = 0;   /* was timer already on */
06062         Timeval   startTime;
06063         Timeval   endTime;
06064         Timeval   totalTime;
06065         Itimerval myTimeout;
06066         Itimerval oldTimeout; /* if old timer adjust from total time to reset */
06067         struct sigaction act, oact;
06068 
06069         #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
06070 
06071         if (hsCb) {
06072             ssl->hsInfoOn = 1;
06073             InitHandShakeInfo(&ssl->handShakeInfo);
06074         }
06075         if (toCb) {
06076             ssl->toInfoOn = 1;
06077             InitTimeoutInfo(&ssl->timeoutInfo);
06078 
06079             if (gettimeofday(&startTime, 0) < 0)
06080                 ERR_OUT(GETTIME_ERROR);
06081 
06082             /* use setitimer to simulate getitimer, init 0 myTimeout */
06083             myTimeout.it_interval.tv_sec  = 0;
06084             myTimeout.it_interval.tv_usec = 0;
06085             myTimeout.it_value.tv_sec     = 0;
06086             myTimeout.it_value.tv_usec    = 0;
06087             if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
06088                 ERR_OUT(SETITIMER_ERROR);
06089 
06090             if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
06091                 oldTimerOn = 1;
06092 
06093                 /* is old timer going to expire before ours */
06094                 if (CmpTimes(oldTimeout.it_value, timeout, <)) {
06095                     timeout.tv_sec  = oldTimeout.it_value.tv_sec;
06096                     timeout.tv_usec = oldTimeout.it_value.tv_usec;
06097                 }
06098             }
06099             myTimeout.it_value.tv_sec  = timeout.tv_sec;
06100             myTimeout.it_value.tv_usec = timeout.tv_usec;
06101 
06102             /* set up signal handler, don't restart socket send/recv */
06103             act.sa_handler = myHandler;
06104             sigemptyset(&act.sa_mask);
06105             act.sa_flags = 0;
06106 #ifdef SA_INTERRUPT
06107             act.sa_flags |= SA_INTERRUPT;
06108 #endif
06109             if (sigaction(SIGALRM, &act, &oact) < 0)
06110                 ERR_OUT(SIGACT_ERROR);
06111 
06112             if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
06113                 ERR_OUT(SETITIMER_ERROR);
06114         }
06115 
06116         /* do main work */
06117 #ifndef NO_CYASSL_CLIENT
06118         if (ssl->options.side == CYASSL_CLIENT_END)
06119             ret = CyaSSL_connect(ssl);
06120 #endif
06121 #ifndef NO_CYASSL_SERVER
06122         if (ssl->options.side == CYASSL_SERVER_END)
06123             ret = CyaSSL_accept(ssl);
06124 #endif
06125 
06126         /* do callbacks */
06127         if (toCb) {
06128             if (oldTimerOn) {
06129                 gettimeofday(&endTime, 0);
06130                 SubtractTimes(endTime, startTime, totalTime);
06131                 /* adjust old timer for elapsed time */
06132                 if (CmpTimes(totalTime, oldTimeout.it_value, <))
06133                     SubtractTimes(oldTimeout.it_value, totalTime,
06134                                   oldTimeout.it_value);
06135                 else {
06136                     /* reset value to interval, may be off */
06137                     oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
06138                     oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
06139                 }
06140                 /* keep iter the same whether there or not */
06141             }
06142             /* restore old handler */
06143             if (sigaction(SIGALRM, &oact, 0) < 0)
06144                 ret = SIGACT_ERROR;    /* more pressing error, stomp */
06145             else
06146                 /* use old settings which may turn off (expired or not there) */
06147                 if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
06148                     ret = SETITIMER_ERROR;
06149 
06150             /* if we had a timeout call callback */
06151             if (ssl->timeoutInfo.timeoutName[0]) {
06152                 ssl->timeoutInfo.timeoutValue.tv_sec  = timeout.tv_sec;
06153                 ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
06154                 (toCb)(&ssl->timeoutInfo);
06155             }
06156             /* clean up */
06157             FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
06158             ssl->toInfoOn = 0;
06159         }
06160         if (hsCb) {
06161             FinishHandShakeInfo(&ssl->handShakeInfo, ssl);
06162             (hsCb)(&ssl->handShakeInfo);
06163             ssl->hsInfoOn = 0;
06164         }
06165         return ret;
06166     }
06167 
06168 
06169 #ifndef NO_CYASSL_CLIENT
06170 
06171     int CyaSSL_connect_ex(CYASSL* ssl, HandShakeCallBack hsCb,
06172                           TimeoutCallBack toCb, Timeval timeout)
06173     {
06174         CYASSL_ENTER("CyaSSL_connect_ex");
06175         return CyaSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
06176     }
06177 
06178 #endif
06179 
06180 
06181 #ifndef NO_CYASSL_SERVER
06182 
06183     int CyaSSL_accept_ex(CYASSL* ssl, HandShakeCallBack hsCb,
06184                          TimeoutCallBack toCb,Timeval timeout)
06185     {
06186         CYASSL_ENTER("CyaSSL_accept_ex");
06187         return CyaSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
06188     }
06189 
06190 #endif
06191 
06192 #endif /* CYASSL_CALLBACKS */
06193 
06194 
06195 #ifndef NO_PSK
06196 
06197     void CyaSSL_CTX_set_psk_client_callback(CYASSL_CTX* ctx,
06198                                          psk_client_callback cb)
06199     {
06200         CYASSL_ENTER("SSL_CTX_set_psk_client_callback");
06201         ctx->havePSK = 1;
06202         ctx->client_psk_cb = cb;
06203     }
06204 
06205 
06206     void CyaSSL_set_psk_client_callback(CYASSL* ssl, psk_client_callback cb)
06207     {
06208         byte haveRSA = 1;
06209 
06210         CYASSL_ENTER("SSL_set_psk_client_callback");
06211         ssl->options.havePSK = 1;
06212         ssl->options.client_psk_cb = cb;
06213 
06214         #ifdef NO_RSA
06215             haveRSA = 0;
06216         #endif
06217         InitSuites(ssl->suites, ssl->version, haveRSA, TRUE,
06218                    ssl->options.haveDH, ssl->options.haveNTRU,
06219                    ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
06220                    ssl->options.side);
06221     }
06222 
06223 
06224     void CyaSSL_CTX_set_psk_server_callback(CYASSL_CTX* ctx,
06225                                          psk_server_callback cb)
06226     {
06227         CYASSL_ENTER("SSL_CTX_set_psk_server_callback");
06228         ctx->havePSK = 1;
06229         ctx->server_psk_cb = cb;
06230     }
06231 
06232 
06233     void CyaSSL_set_psk_server_callback(CYASSL* ssl, psk_server_callback cb)
06234     {
06235         byte haveRSA = 1;
06236 
06237         CYASSL_ENTER("SSL_set_psk_server_callback");
06238         ssl->options.havePSK = 1;
06239         ssl->options.server_psk_cb = cb;
06240 
06241         #ifdef NO_RSA
06242             haveRSA = 0;
06243         #endif
06244         InitSuites(ssl->suites, ssl->version, haveRSA, TRUE,
06245                    ssl->options.haveDH, ssl->options.haveNTRU,
06246                    ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
06247                    ssl->options.side);
06248     }
06249 
06250 
06251     const char* CyaSSL_get_psk_identity_hint(const CYASSL* ssl)
06252     {
06253         CYASSL_ENTER("SSL_get_psk_identity_hint");
06254 
06255         if (ssl == NULL || ssl->arrays == NULL)
06256             return NULL;
06257 
06258         return ssl->arrays->server_hint;
06259     }
06260 
06261 
06262     const char* CyaSSL_get_psk_identity(const CYASSL* ssl)
06263     {
06264         CYASSL_ENTER("SSL_get_psk_identity");
06265 
06266         if (ssl == NULL || ssl->arrays == NULL)
06267             return NULL;
06268 
06269         return ssl->arrays->client_identity;
06270     }
06271 
06272 
06273     int CyaSSL_CTX_use_psk_identity_hint(CYASSL_CTX* ctx, const char* hint)
06274     {
06275         CYASSL_ENTER("SSL_CTX_use_psk_identity_hint");
06276         if (hint == 0)
06277             ctx->server_hint[0] = 0;
06278         else {
06279             XSTRNCPY(ctx->server_hint, hint, MAX_PSK_ID_LEN);
06280             ctx->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
06281         }
06282         return SSL_SUCCESS;
06283     }
06284 
06285 
06286     int CyaSSL_use_psk_identity_hint(CYASSL* ssl, const char* hint)
06287     {
06288         CYASSL_ENTER("SSL_use_psk_identity_hint");
06289 
06290         if (ssl == NULL || ssl->arrays == NULL)
06291             return SSL_FAILURE;
06292 
06293         if (hint == 0)
06294             ssl->arrays->server_hint[0] = 0;
06295         else {
06296             XSTRNCPY(ssl->arrays->server_hint, hint, MAX_PSK_ID_LEN);
06297             ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
06298         }
06299         return SSL_SUCCESS;
06300     }
06301 
06302 #endif /* NO_PSK */
06303 
06304 
06305 #ifdef HAVE_ANON
06306 
06307     int CyaSSL_CTX_allow_anon_cipher(CYASSL_CTX* ctx)
06308     {
06309         CYASSL_ENTER("CyaSSL_CTX_allow_anon_cipher");
06310 
06311         if (ctx == NULL)
06312             return SSL_FAILURE;
06313 
06314         ctx->haveAnon = 1;
06315 
06316         return SSL_SUCCESS;
06317     }
06318 
06319 #endif /* HAVE_ANON */
06320 
06321 
06322 #ifndef NO_CERTS
06323 /* used to be defined on NO_FILESYSTEM only, but are generally useful */
06324 
06325     /* CyaSSL extension allows DER files to be loaded from buffers as well */
06326     int CyaSSL_CTX_load_verify_buffer(CYASSL_CTX* ctx, const unsigned char* in,
06327                                       long sz, int format)
06328     {
06329         CYASSL_ENTER("CyaSSL_CTX_load_verify_buffer");
06330         if (format == SSL_FILETYPE_PEM)
06331             return ProcessChainBuffer(ctx, in, sz, format, CA_TYPE, NULL);
06332         else
06333             return ProcessBuffer(ctx, in, sz, format, CA_TYPE, NULL,NULL,0);
06334     }
06335 
06336 
06337     int CyaSSL_CTX_use_certificate_buffer(CYASSL_CTX* ctx,
06338                                  const unsigned char* in, long sz, int format)
06339     {
06340         CYASSL_ENTER("CyaSSL_CTX_use_certificate_buffer");
06341         return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 0);
06342     }
06343 
06344 
06345     int CyaSSL_CTX_use_PrivateKey_buffer(CYASSL_CTX* ctx,
06346                                  const unsigned char* in, long sz, int format)
06347     {
06348         CYASSL_ENTER("CyaSSL_CTX_use_PrivateKey_buffer");
06349         return ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL,NULL,0);
06350     }
06351 
06352 
06353     int CyaSSL_CTX_use_certificate_chain_buffer(CYASSL_CTX* ctx,
06354                                  const unsigned char* in, long sz)
06355     {
06356         CYASSL_ENTER("CyaSSL_CTX_use_certificate_chain_buffer");
06357         return ProcessBuffer(ctx, in, sz, SSL_FILETYPE_PEM, CERT_TYPE, NULL,
06358                              NULL, 1);
06359     }
06360 
06361     int CyaSSL_use_certificate_buffer(CYASSL* ssl,
06362                                  const unsigned char* in, long sz, int format)
06363     {
06364         CYASSL_ENTER("CyaSSL_use_certificate_buffer");
06365         return ProcessBuffer(ssl->ctx, in, sz, format,CERT_TYPE,ssl,NULL,0);
06366     }
06367 
06368 
06369     int CyaSSL_use_PrivateKey_buffer(CYASSL* ssl,
06370                                  const unsigned char* in, long sz, int format)
06371     {
06372         CYASSL_ENTER("CyaSSL_use_PrivateKey_buffer");
06373         return ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE,
06374                              ssl, NULL, 0);
06375     }
06376 
06377 
06378     int CyaSSL_use_certificate_chain_buffer(CYASSL* ssl,
06379                                  const unsigned char* in, long sz)
06380     {
06381         CYASSL_ENTER("CyaSSL_use_certificate_chain_buffer");
06382         return ProcessBuffer(ssl->ctx, in, sz, SSL_FILETYPE_PEM, CERT_TYPE,
06383                              ssl, NULL, 1);
06384     }
06385 
06386 
06387     /* unload any certs or keys that SSL owns, leave CTX as is
06388        SSL_SUCCESS on ok */
06389     int CyaSSL_UnloadCertsKeys(CYASSL* ssl)
06390     {
06391         if (ssl == NULL) {
06392             CYASSL_MSG("Null function arg");
06393             return BAD_FUNC_ARG;
06394         }
06395 
06396         if (ssl->buffers.weOwnCert) {
06397             CYASSL_MSG("Unloading cert");
06398             XFREE(ssl->buffers.certificate.buffer, ssl->heap,DYNAMIC_TYPE_CERT);
06399             ssl->buffers.weOwnCert = 0;
06400             ssl->buffers.certificate.length = 0;
06401             ssl->buffers.certificate.buffer = NULL;
06402         }
06403 
06404         if (ssl->buffers.weOwnCertChain) {
06405             CYASSL_MSG("Unloading cert chain");
06406             XFREE(ssl->buffers.certChain.buffer, ssl->heap,DYNAMIC_TYPE_CERT);
06407             ssl->buffers.weOwnCertChain = 0;
06408             ssl->buffers.certChain.length = 0;
06409             ssl->buffers.certChain.buffer = NULL;
06410         }
06411 
06412         if (ssl->buffers.weOwnKey) {
06413             CYASSL_MSG("Unloading key");
06414             XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
06415             ssl->buffers.weOwnKey = 0;
06416             ssl->buffers.key.length = 0;
06417             ssl->buffers.key.buffer = NULL;
06418         }
06419 
06420         return SSL_SUCCESS;
06421     }
06422 
06423 
06424     int CyaSSL_CTX_UnloadCAs(CYASSL_CTX* ctx)
06425     {
06426         CYASSL_ENTER("CyaSSL_CTX_UnloadCAs");
06427 
06428         if (ctx == NULL)
06429             return BAD_FUNC_ARG;
06430 
06431         return CyaSSL_CertManagerUnloadCAs(ctx->cm);
06432     }
06433 
06434 /* old NO_FILESYSTEM end */
06435 #endif /* !NO_CERTS */
06436 
06437 
06438 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
06439 
06440 
06441     int CyaSSL_add_all_algorithms(void)
06442     {
06443         CYASSL_ENTER("CyaSSL_add_all_algorithms");
06444         CyaSSL_Init();
06445         return SSL_SUCCESS;
06446     }
06447 
06448 
06449     long CyaSSL_CTX_sess_set_cache_size(CYASSL_CTX* ctx, long sz)
06450     {
06451         /* cache size fixed at compile time in CyaSSL */
06452         (void)ctx;
06453         (void)sz;
06454         return 0;
06455     }
06456 
06457 
06458     void CyaSSL_CTX_set_quiet_shutdown(CYASSL_CTX* ctx, int mode)
06459     {
06460         CYASSL_ENTER("CyaSSL_CTX_set_quiet_shutdown");
06461         if (mode)
06462             ctx->quietShutdown = 1;
06463     }
06464 
06465 
06466     void CyaSSL_set_quiet_shutdown(CYASSL* ssl, int mode)
06467     {
06468         CYASSL_ENTER("CyaSSL_CTX_set_quiet_shutdown");
06469         if (mode)
06470             ssl->options.quietShutdown = 1;
06471     }
06472 
06473 
06474     void CyaSSL_set_bio(CYASSL* ssl, CYASSL_BIO* rd, CYASSL_BIO* wr)
06475     {
06476         CYASSL_ENTER("SSL_set_bio");
06477         CyaSSL_set_rfd(ssl, rd->fd);
06478         CyaSSL_set_wfd(ssl, wr->fd);
06479 
06480         ssl->biord = rd;
06481         ssl->biowr = wr;
06482     }
06483 
06484 
06485     void CyaSSL_CTX_set_client_CA_list(CYASSL_CTX* ctx,
06486                                        STACK_OF(CYASSL_X509_NAME)* names)
06487     {
06488         (void)ctx;
06489         (void)names;
06490     }
06491 
06492 
06493     STACK_OF(CYASSL_X509_NAME)* CyaSSL_load_client_CA_file(const char* fname)
06494     {
06495         (void)fname;
06496         return 0;
06497     }
06498 
06499 
06500     int CyaSSL_CTX_set_default_verify_paths(CYASSL_CTX* ctx)
06501     {
06502         /* TODO:, not needed in goahead */
06503         (void)ctx;
06504         return SSL_NOT_IMPLEMENTED;
06505     }
06506 
06507 
06508     /* keyblock size in bytes or -1 */
06509     int CyaSSL_get_keyblock_size(CYASSL* ssl)
06510     {
06511         if (ssl == NULL)
06512             return SSL_FATAL_ERROR;
06513 
06514         return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
06515                     ssl->specs.hash_size);
06516     }
06517 
06518 
06519     /* store keys returns SSL_SUCCESS or -1 on error */
06520     int CyaSSL_get_keys(CYASSL* ssl, unsigned char** ms, unsigned int* msLen,
06521                                      unsigned char** sr, unsigned int* srLen,
06522                                      unsigned char** cr, unsigned int* crLen)
06523     {
06524         if (ssl == NULL || ssl->arrays == NULL)
06525             return SSL_FATAL_ERROR;
06526 
06527         *ms = ssl->arrays->masterSecret;
06528         *sr = ssl->arrays->serverRandom;
06529         *cr = ssl->arrays->clientRandom;
06530 
06531         *msLen = SECRET_LEN;
06532         *srLen = RAN_LEN;
06533         *crLen = RAN_LEN;
06534 
06535         return SSL_SUCCESS;
06536     }
06537 
06538 
06539     void CyaSSL_set_accept_state(CYASSL* ssl)
06540     {
06541         byte haveRSA = 1;
06542         byte havePSK = 0;
06543 
06544         CYASSL_ENTER("SSL_set_accept_state");
06545         ssl->options.side = CYASSL_SERVER_END;
06546         /* reset suites in case user switched */
06547 
06548         #ifdef NO_RSA
06549             haveRSA = 0;
06550         #endif
06551         #ifndef NO_PSK
06552             havePSK = ssl->options.havePSK;
06553         #endif
06554         InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
06555                    ssl->options.haveDH, ssl->options.haveNTRU,
06556                    ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
06557                    ssl->options.side);
06558     }
06559 #endif
06560 
06561     /* return true if connection established */
06562     int CyaSSL_is_init_finished(CYASSL* ssl)
06563     {
06564         if (ssl == NULL)
06565             return 0;
06566 
06567         if (ssl->options.handShakeState == HANDSHAKE_DONE)
06568             return 1;
06569 
06570         return 0;
06571     }
06572 
06573 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
06574     void CyaSSL_CTX_set_tmp_rsa_callback(CYASSL_CTX* ctx,
06575                                       CYASSL_RSA*(*f)(CYASSL*, int, int))
06576     {
06577         /* CyaSSL verifies all these internally */
06578         (void)ctx;
06579         (void)f;
06580     }
06581 
06582 
06583     void CyaSSL_set_shutdown(CYASSL* ssl, int opt)
06584     {
06585         (void)ssl;
06586         (void)opt;
06587     }
06588 
06589 
06590     long CyaSSL_CTX_set_options(CYASSL_CTX* ctx, long opt)
06591     {
06592         /* goahead calls with 0, do nothing */
06593         CYASSL_ENTER("SSL_CTX_set_options");
06594         (void)ctx;
06595         return opt;
06596     }
06597 
06598 
06599     int CyaSSL_set_rfd(CYASSL* ssl, int rfd)
06600     {
06601         CYASSL_ENTER("SSL_set_rfd");
06602         ssl->rfd = rfd;      /* not used directly to allow IO callbacks */
06603 
06604         ssl->IOCB_ReadCtx  = &ssl->rfd;
06605 
06606         return SSL_SUCCESS;
06607     }
06608 
06609 
06610     int CyaSSL_set_wfd(CYASSL* ssl, int wfd)
06611     {
06612         CYASSL_ENTER("SSL_set_wfd");
06613         ssl->wfd = wfd;      /* not used directly to allow IO callbacks */
06614 
06615         ssl->IOCB_WriteCtx  = &ssl->wfd;
06616 
06617         return SSL_SUCCESS;
06618     }
06619 
06620 
06621     CYASSL_RSA* CyaSSL_RSA_generate_key(int len, unsigned long bits,
06622                                           void(*f)(int, int, void*), void* data)
06623     {
06624         /* no tmp key needed, actual generation not supported */
06625         CYASSL_ENTER("RSA_generate_key");
06626         (void)len;
06627         (void)bits;
06628         (void)f;
06629         (void)data;
06630         return NULL;
06631     }
06632 
06633 
06634 
06635     CYASSL_X509* CyaSSL_X509_STORE_CTX_get_current_cert(
06636                                                      CYASSL_X509_STORE_CTX* ctx)
06637     {
06638         (void)ctx;
06639         return 0;
06640     }
06641 
06642 
06643     int CyaSSL_X509_STORE_CTX_get_error(CYASSL_X509_STORE_CTX* ctx)
06644     {
06645         if (ctx != NULL)
06646             return ctx->error;
06647         return 0;
06648     }
06649 
06650 
06651     int CyaSSL_X509_STORE_CTX_get_error_depth(CYASSL_X509_STORE_CTX* ctx)
06652     {
06653         (void)ctx;
06654         return 0;
06655     }
06656 
06657 
06658     CYASSL_BIO_METHOD* CyaSSL_BIO_f_buffer(void)
06659     {
06660         static CYASSL_BIO_METHOD meth;
06661 
06662         CYASSL_ENTER("BIO_f_buffer");
06663         meth.type = BIO_BUFFER;
06664 
06665         return &meth;
06666     }
06667 
06668 
06669     long CyaSSL_BIO_set_write_buffer_size(CYASSL_BIO* bio, long size)
06670     {
06671         /* CyaSSL has internal buffer, compatibility only */
06672         CYASSL_ENTER("BIO_set_write_buffer_size");
06673         (void)bio;
06674         return size;
06675     }
06676 
06677 
06678     CYASSL_BIO_METHOD* CyaSSL_BIO_f_ssl(void)
06679     {
06680         static CYASSL_BIO_METHOD meth;
06681 
06682         CYASSL_ENTER("BIO_f_ssl");
06683         meth.type = BIO_SSL;
06684 
06685         return &meth;
06686     }
06687 
06688 
06689     CYASSL_BIO* CyaSSL_BIO_new_socket(int sfd, int closeF)
06690     {
06691         CYASSL_BIO* bio = (CYASSL_BIO*) XMALLOC(sizeof(CYASSL_BIO), 0,
06692                                                 DYNAMIC_TYPE_OPENSSL);
06693 
06694         CYASSL_ENTER("BIO_new_socket");
06695         if (bio) {
06696             bio->type  = BIO_SOCKET;
06697             bio->close = (byte)closeF;
06698             bio->eof   = 0;
06699             bio->ssl   = 0;
06700             bio->fd    = sfd;
06701             bio->prev  = 0;
06702             bio->next  = 0;
06703             bio->mem   = NULL;
06704             bio->memLen = 0;
06705         }
06706         return bio;
06707     }
06708 
06709 
06710     int CyaSSL_BIO_eof(CYASSL_BIO* b)
06711     {
06712         CYASSL_ENTER("BIO_eof");
06713         if (b->eof)
06714             return 1;
06715 
06716         return 0;
06717     }
06718 
06719 
06720     long CyaSSL_BIO_set_ssl(CYASSL_BIO* b, CYASSL* ssl, int closeF)
06721     {
06722         CYASSL_ENTER("BIO_set_ssl");
06723         b->ssl   = ssl;
06724         b->close = (byte)closeF;
06725     /* add to ssl for bio free if SSL_free called before/instead of free_all? */
06726 
06727         return 0;
06728     }
06729 
06730 
06731     CYASSL_BIO* CyaSSL_BIO_new(CYASSL_BIO_METHOD* method)
06732     {
06733         CYASSL_BIO* bio = (CYASSL_BIO*) XMALLOC(sizeof(CYASSL_BIO), 0,
06734                                                 DYNAMIC_TYPE_OPENSSL);
06735         CYASSL_ENTER("BIO_new");
06736         if (bio) {
06737             bio->type   = method->type;
06738             bio->close  = 0;
06739             bio->eof    = 0;
06740             bio->ssl    = NULL;
06741             bio->mem    = NULL;
06742             bio->memLen = 0;
06743             bio->fd     = 0;
06744             bio->prev   = NULL;
06745             bio->next   = NULL;
06746         }
06747         return bio;
06748     }
06749 
06750 
06751     int CyaSSL_BIO_get_mem_data(CYASSL_BIO* bio, const byte** p)
06752     {
06753         if (bio == NULL || p == NULL)
06754             return SSL_FATAL_ERROR;
06755 
06756         *p = bio->mem;
06757 
06758         return bio->memLen;
06759     }
06760 
06761 
06762     CYASSL_BIO* CyaSSL_BIO_new_mem_buf(void* buf, int len)
06763     {
06764         CYASSL_BIO* bio = NULL;
06765         if (buf == NULL)
06766             return bio;
06767 
06768         bio = CyaSSL_BIO_new(CyaSSL_BIO_s_mem());
06769         if (bio == NULL)
06770             return bio;
06771 
06772         bio->memLen = len;
06773         bio->mem    = (byte*)XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL);
06774         if (bio->mem == NULL) {
06775             XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
06776             return NULL;
06777         }
06778 
06779         XMEMCPY(bio->mem, buf, len);
06780 
06781         return bio;
06782     }
06783 
06784 
06785 #ifdef USE_WINDOWS_API
06786     #define CloseSocket(s) closesocket(s)
06787 #elif defined(CYASSL_MDK_ARM)
06788     #define CloseSocket(s) closesocket(s)
06789     extern int closesocket(int) ;
06790 #else
06791     #define CloseSocket(s) close(s)
06792 #endif
06793 
06794     int CyaSSL_BIO_free(CYASSL_BIO* bio)
06795     {
06796         /* unchain?, doesn't matter in goahead since from free all */
06797         CYASSL_ENTER("BIO_free");
06798         if (bio) {
06799             if (bio->close) {
06800                 if (bio->ssl)
06801                     CyaSSL_free(bio->ssl);
06802                 if (bio->fd)
06803                     CloseSocket(bio->fd);
06804             }
06805             if (bio->mem)
06806                 XFREE(bio->mem, 0, DYNAMIC_TYPE_OPENSSL);
06807             XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
06808         }
06809         return 0;
06810     }
06811 
06812 
06813     int CyaSSL_BIO_free_all(CYASSL_BIO* bio)
06814     {
06815         CYASSL_ENTER("BIO_free_all");
06816         while (bio) {
06817             CYASSL_BIO* next = bio->next;
06818             CyaSSL_BIO_free(bio);
06819             bio = next;
06820         }
06821         return 0;
06822     }
06823 
06824 
06825     int CyaSSL_BIO_read(CYASSL_BIO* bio, void* buf, int len)
06826     {
06827         int  ret;
06828         CYASSL* ssl = 0;
06829         CYASSL_BIO* front = bio;
06830 
06831         CYASSL_ENTER("BIO_read");
06832         /* already got eof, again is error */
06833         if (front->eof)
06834             return SSL_FATAL_ERROR;
06835 
06836         while(bio && ((ssl = bio->ssl) == 0) )
06837             bio = bio->next;
06838 
06839         if (ssl == 0) return BAD_FUNC_ARG;
06840 
06841         ret = CyaSSL_read(ssl, buf, len);
06842         if (ret == 0)
06843             front->eof = 1;
06844         else if (ret < 0) {
06845             int err = CyaSSL_get_error(ssl, 0);
06846             if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
06847                 front->eof = 1;
06848         }
06849         return ret;
06850     }
06851 
06852 
06853     int CyaSSL_BIO_write(CYASSL_BIO* bio, const void* data, int len)
06854     {
06855         int  ret;
06856         CYASSL* ssl = 0;
06857         CYASSL_BIO* front = bio;
06858 
06859         CYASSL_ENTER("BIO_write");
06860         /* already got eof, again is error */
06861         if (front->eof)
06862             return SSL_FATAL_ERROR;
06863 
06864         while(bio && ((ssl = bio->ssl) == 0) )
06865             bio = bio->next;
06866 
06867         if (ssl == 0) return BAD_FUNC_ARG;
06868 
06869         ret = CyaSSL_write(ssl, data, len);
06870         if (ret == 0)
06871             front->eof = 1;
06872         else if (ret < 0) {
06873             int err = CyaSSL_get_error(ssl, 0);
06874             if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
06875                 front->eof = 1;
06876         }
06877 
06878         return ret;
06879     }
06880 
06881 
06882     CYASSL_BIO* CyaSSL_BIO_push(CYASSL_BIO* top, CYASSL_BIO* append)
06883     {
06884         CYASSL_ENTER("BIO_push");
06885         top->next    = append;
06886         append->prev = top;
06887 
06888         return top;
06889     }
06890 
06891 
06892     int CyaSSL_BIO_flush(CYASSL_BIO* bio)
06893     {
06894         /* for CyaSSL no flushing needed */
06895         CYASSL_ENTER("BIO_flush");
06896         (void)bio;
06897         return 1;
06898     }
06899 
06900 
06901 #endif /* OPENSSL_EXTRA || GOAHEAD_WS */
06902 
06903 
06904 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
06905 
06906     void CyaSSL_CTX_set_default_passwd_cb_userdata(CYASSL_CTX* ctx,
06907                                                    void* userdata)
06908     {
06909         CYASSL_ENTER("SSL_CTX_set_default_passwd_cb_userdata");
06910         ctx->userdata = userdata;
06911     }
06912 
06913 
06914     void CyaSSL_CTX_set_default_passwd_cb(CYASSL_CTX* ctx, pem_password_cb cb)
06915     {
06916         CYASSL_ENTER("SSL_CTX_set_default_passwd_cb");
06917         ctx->passwd_cb = cb;
06918     }
06919 
06920     int CyaSSL_num_locks(void)
06921     {
06922         return 0;
06923     }
06924 
06925     void CyaSSL_set_locking_callback(void (*f)(int, int, const char*, int))
06926     {
06927         (void)f;
06928     }
06929 
06930     void CyaSSL_set_id_callback(unsigned long (*f)(void))
06931     {
06932         (void)f;
06933     }
06934 
06935     unsigned long CyaSSL_ERR_get_error(void)
06936     {
06937         /* TODO: */
06938         return 0;
06939     }
06940 
06941     int CyaSSL_EVP_BytesToKey(const CYASSL_EVP_CIPHER* type,
06942                        const CYASSL_EVP_MD* md, const byte* salt,
06943                        const byte* data, int sz, int count, byte* key, byte* iv)
06944     {
06945         int  keyLen = 0;
06946         int  ivLen  = 0;
06947         int  j;
06948         int  keyLeft;
06949         int  ivLeft;
06950         int  keyOutput = 0;
06951         byte digest[MD5_DIGEST_SIZE];
06952     #ifdef CYASSL_SMALL_STACK
06953         Md5* md5 = NULL;
06954     #else
06955         Md5  md5[1];
06956     #endif
06957 
06958     #ifdef CYASSL_SMALL_STACK
06959         md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
06960         if (md5 == NULL)
06961             return 0;
06962     #endif
06963 
06964         CYASSL_ENTER("EVP_BytesToKey");
06965         InitMd5(md5);
06966 
06967         /* only support MD5 for now */
06968         if (XSTRNCMP(md, "MD5", 3) != 0) return 0;
06969 
06970         /* only support CBC DES and AES for now */
06971         if (XSTRNCMP(type, "DES-CBC", 7) == 0) {
06972             keyLen = DES_KEY_SIZE;
06973             ivLen  = DES_IV_SIZE;
06974         }
06975         else if (XSTRNCMP(type, "DES-EDE3-CBC", 12) == 0) {
06976             keyLen = DES3_KEY_SIZE;
06977             ivLen  = DES_IV_SIZE;
06978         }
06979         else if (XSTRNCMP(type, "AES-128-CBC", 11) == 0) {
06980             keyLen = AES_128_KEY_SIZE;
06981             ivLen  = AES_IV_SIZE;
06982         }
06983         else if (XSTRNCMP(type, "AES-192-CBC", 11) == 0) {
06984             keyLen = AES_192_KEY_SIZE;
06985             ivLen  = AES_IV_SIZE;
06986         }
06987         else if (XSTRNCMP(type, "AES-256-CBC", 11) == 0) {
06988             keyLen = AES_256_KEY_SIZE;
06989             ivLen  = AES_IV_SIZE;
06990         }
06991         else {
06992         #ifdef CYASSL_SMALL_STACK
06993             XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06994         #endif
06995             return 0;
06996         }
06997 
06998         keyLeft   = keyLen;
06999         ivLeft    = ivLen;
07000 
07001         while (keyOutput < (keyLen + ivLen)) {
07002             int digestLeft = MD5_DIGEST_SIZE;
07003             /* D_(i - 1) */
07004             if (keyOutput)                      /* first time D_0 is empty */
07005                 Md5Update(md5, digest, MD5_DIGEST_SIZE);
07006             /* data */
07007             Md5Update(md5, data, sz);
07008             /* salt */
07009             if (salt)
07010                 Md5Update(md5, salt, EVP_SALT_SIZE);
07011             Md5Final(md5, digest);
07012             /* count */
07013             for (j = 1; j < count; j++) {
07014                 Md5Update(md5, digest, MD5_DIGEST_SIZE);
07015                 Md5Final(md5, digest);
07016             }
07017 
07018             if (keyLeft) {
07019                 int store = min(keyLeft, MD5_DIGEST_SIZE);
07020                 XMEMCPY(&key[keyLen - keyLeft], digest, store);
07021 
07022                 keyOutput  += store;
07023                 keyLeft    -= store;
07024                 digestLeft -= store;
07025             }
07026 
07027             if (ivLeft && digestLeft) {
07028                 int store = min(ivLeft, digestLeft);
07029                 XMEMCPY(&iv[ivLen - ivLeft], &digest[MD5_DIGEST_SIZE -
07030                                                     digestLeft], store);
07031                 keyOutput += store;
07032                 ivLeft    -= store;
07033             }
07034         }
07035 
07036     #ifdef CYASSL_SMALL_STACK
07037         XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07038     #endif
07039 
07040         return keyOutput == (keyLen + ivLen) ? keyOutput : 0;
07041     }
07042 
07043 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
07044 
07045 
07046 #ifdef OPENSSL_EXTRA
07047 
07048     unsigned long CyaSSLeay(void)
07049     {
07050         return SSLEAY_VERSION_NUMBER;
07051     }
07052 
07053 
07054     const char* CyaSSLeay_version(int type)
07055     {
07056         static const char* version = "SSLeay CyaSSL compatibility";
07057         (void)type;
07058         return version;
07059     }
07060 
07061 
07062     void CyaSSL_MD5_Init(CYASSL_MD5_CTX* md5)
07063     {
07064         typedef char md5_test[sizeof(MD5_CTX) >= sizeof(Md5) ? 1 : -1];
07065         (void)sizeof(md5_test);
07066 
07067         CYASSL_ENTER("MD5_Init");
07068         InitMd5((Md5*)md5);
07069     }
07070 
07071 
07072     void CyaSSL_MD5_Update(CYASSL_MD5_CTX* md5, const void* input,
07073                            unsigned long sz)
07074     {
07075         CYASSL_ENTER("CyaSSL_MD5_Update");
07076         Md5Update((Md5*)md5, (const byte*)input, (word32)sz);
07077     }
07078 
07079 
07080     void CyaSSL_MD5_Final(byte* input, CYASSL_MD5_CTX* md5)
07081     {
07082         CYASSL_ENTER("MD5_Final");
07083         Md5Final((Md5*)md5, input);
07084     }
07085 
07086 
07087     void CyaSSL_SHA_Init(CYASSL_SHA_CTX* sha)
07088     {
07089         typedef char sha_test[sizeof(SHA_CTX) >= sizeof(Sha) ? 1 : -1];
07090         (void)sizeof(sha_test);
07091 
07092         CYASSL_ENTER("SHA_Init");
07093         InitSha((Sha*)sha);  /* OpenSSL compat, no ret */
07094     }
07095 
07096 
07097     void CyaSSL_SHA_Update(CYASSL_SHA_CTX* sha, const void* input,
07098                            unsigned long sz)
07099     {
07100         CYASSL_ENTER("SHA_Update");
07101         ShaUpdate((Sha*)sha, (const byte*)input, (word32)sz);
07102     }
07103 
07104 
07105     void CyaSSL_SHA_Final(byte* input, CYASSL_SHA_CTX* sha)
07106     {
07107         CYASSL_ENTER("SHA_Final");
07108         ShaFinal((Sha*)sha, input);
07109     }
07110 
07111 
07112     void CyaSSL_SHA1_Init(CYASSL_SHA_CTX* sha)
07113     {
07114         CYASSL_ENTER("SHA1_Init");
07115         SHA_Init(sha);
07116     }
07117 
07118 
07119     void CyaSSL_SHA1_Update(CYASSL_SHA_CTX* sha, const void* input,
07120                             unsigned long sz)
07121     {
07122         CYASSL_ENTER("SHA1_Update");
07123         SHA_Update(sha, input, sz);
07124     }
07125 
07126 
07127     void CyaSSL_SHA1_Final(byte* input, CYASSL_SHA_CTX* sha)
07128     {
07129         CYASSL_ENTER("SHA1_Final");
07130         SHA_Final(input, sha);
07131     }
07132 
07133 
07134     void CyaSSL_SHA256_Init(CYASSL_SHA256_CTX* sha256)
07135     {
07136         typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(Sha256) ? 1 : -1];
07137         (void)sizeof(sha_test);
07138 
07139         CYASSL_ENTER("SHA256_Init");
07140         InitSha256((Sha256*)sha256);  /* OpenSSL compat, no error */
07141     }
07142 
07143 
07144     void CyaSSL_SHA256_Update(CYASSL_SHA256_CTX* sha, const void* input,
07145                               unsigned long sz)
07146     {
07147         CYASSL_ENTER("SHA256_Update");
07148         Sha256Update((Sha256*)sha, (const byte*)input, (word32)sz);
07149         /* OpenSSL compat, no error */
07150     }
07151 
07152 
07153     void CyaSSL_SHA256_Final(byte* input, CYASSL_SHA256_CTX* sha)
07154     {
07155         CYASSL_ENTER("SHA256_Final");
07156         Sha256Final((Sha256*)sha, input);
07157         /* OpenSSL compat, no error */
07158     }
07159 
07160 
07161     #ifdef CYASSL_SHA384
07162 
07163     void CyaSSL_SHA384_Init(CYASSL_SHA384_CTX* sha)
07164     {
07165         typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(Sha384) ? 1 : -1];
07166         (void)sizeof(sha_test);
07167 
07168         CYASSL_ENTER("SHA384_Init");
07169         InitSha384((Sha384*)sha);   /* OpenSSL compat, no error */
07170     }
07171 
07172 
07173     void CyaSSL_SHA384_Update(CYASSL_SHA384_CTX* sha, const void* input,
07174                            unsigned long sz)
07175     {
07176         CYASSL_ENTER("SHA384_Update");
07177         Sha384Update((Sha384*)sha, (const byte*)input, (word32)sz);
07178         /* OpenSSL compat, no error */
07179     }
07180 
07181 
07182     void CyaSSL_SHA384_Final(byte* input, CYASSL_SHA384_CTX* sha)
07183     {
07184         CYASSL_ENTER("SHA384_Final");
07185         Sha384Final((Sha384*)sha, input);
07186         /* OpenSSL compat, no error */
07187     }
07188 
07189     #endif /* CYASSL_SHA384 */
07190 
07191 
07192    #ifdef CYASSL_SHA512
07193 
07194     void CyaSSL_SHA512_Init(CYASSL_SHA512_CTX* sha)
07195     {
07196         typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(Sha512) ? 1 : -1];
07197         (void)sizeof(sha_test);
07198 
07199         CYASSL_ENTER("SHA512_Init");
07200         InitSha512((Sha512*)sha);  /* OpenSSL compat, no error */
07201     }
07202 
07203 
07204     void CyaSSL_SHA512_Update(CYASSL_SHA512_CTX* sha, const void* input,
07205                            unsigned long sz)
07206     {
07207         CYASSL_ENTER("SHA512_Update");
07208         Sha512Update((Sha512*)sha, (const byte*)input, (word32)sz);
07209         /* OpenSSL compat, no error */
07210     }
07211 
07212 
07213     void CyaSSL_SHA512_Final(byte* input, CYASSL_SHA512_CTX* sha)
07214     {
07215         CYASSL_ENTER("SHA512_Final");
07216         Sha512Final((Sha512*)sha, input);
07217         /* OpenSSL compat, no error */
07218     }
07219 
07220     #endif /* CYASSL_SHA512 */
07221 
07222 
07223     const CYASSL_EVP_MD* CyaSSL_EVP_md5(void)
07224     {
07225         static const char* type = "MD5";
07226         CYASSL_ENTER("EVP_md5");
07227         return type;
07228     }
07229 
07230 
07231     const CYASSL_EVP_MD* CyaSSL_EVP_sha1(void)
07232     {
07233         static const char* type = "SHA";
07234         CYASSL_ENTER("EVP_sha1");
07235         return type;
07236     }
07237 
07238 
07239     const CYASSL_EVP_MD* CyaSSL_EVP_sha256(void)
07240     {
07241         static const char* type = "SHA256";
07242         CYASSL_ENTER("EVP_sha256");
07243         return type;
07244     }
07245 
07246     #ifdef CYASSL_SHA384
07247 
07248     const CYASSL_EVP_MD* CyaSSL_EVP_sha384(void)
07249     {
07250         static const char* type = "SHA384";
07251         CYASSL_ENTER("EVP_sha384");
07252         return type;
07253     }
07254 
07255     #endif /* CYASSL_SHA384 */
07256 
07257     #ifdef CYASSL_SHA512
07258 
07259     const CYASSL_EVP_MD* CyaSSL_EVP_sha512(void)
07260     {
07261         static const char* type = "SHA512";
07262         CYASSL_ENTER("EVP_sha512");
07263         return type;
07264     }
07265 
07266     #endif /* CYASSL_SHA512 */
07267 
07268 
07269     void CyaSSL_EVP_MD_CTX_init(CYASSL_EVP_MD_CTX* ctx)
07270     {
07271         CYASSL_ENTER("EVP_CIPHER_MD_CTX_init");
07272         (void)ctx;
07273         /* do nothing */
07274     }
07275 
07276 
07277     const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_128_cbc(void)
07278     {
07279         static const char* type = "AES128-CBC";
07280         CYASSL_ENTER("CyaSSL_EVP_aes_128_cbc");
07281         return type;
07282     }
07283 
07284 
07285     const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_192_cbc(void)
07286     {
07287         static const char* type = "AES192-CBC";
07288         CYASSL_ENTER("CyaSSL_EVP_aes_192_cbc");
07289         return type;
07290     }
07291 
07292 
07293     const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_256_cbc(void)
07294     {
07295         static const char* type = "AES256-CBC";
07296         CYASSL_ENTER("CyaSSL_EVP_aes_256_cbc");
07297         return type;
07298     }
07299 
07300 
07301     const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_128_ctr(void)
07302     {
07303         static const char* type = "AES128-CTR";
07304         CYASSL_ENTER("CyaSSL_EVP_aes_128_ctr");
07305         return type;
07306     }
07307 
07308 
07309     const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_192_ctr(void)
07310     {
07311         static const char* type = "AES192-CTR";
07312         CYASSL_ENTER("CyaSSL_EVP_aes_192_ctr");
07313         return type;
07314     }
07315 
07316 
07317     const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_256_ctr(void)
07318     {
07319         static const char* type = "AES256-CTR";
07320         CYASSL_ENTER("CyaSSL_EVP_aes_256_ctr");
07321         return type;
07322     }
07323 
07324 
07325     const CYASSL_EVP_CIPHER* CyaSSL_EVP_des_cbc(void)
07326     {
07327         static const char* type = "DES-CBC";
07328         CYASSL_ENTER("CyaSSL_EVP_des_cbc");
07329         return type;
07330     }
07331 
07332 
07333     const CYASSL_EVP_CIPHER* CyaSSL_EVP_des_ede3_cbc(void)
07334     {
07335         static const char* type = "DES-EDE3-CBC";
07336         CYASSL_ENTER("CyaSSL_EVP_des_ede3_cbc");
07337         return type;
07338     }
07339 
07340 
07341     const CYASSL_EVP_CIPHER* CyaSSL_EVP_rc4(void)
07342     {
07343         static const char* type = "ARC4";
07344         CYASSL_ENTER("CyaSSL_EVP_rc4");
07345         return type;
07346     }
07347 
07348 
07349     const CYASSL_EVP_CIPHER* CyaSSL_EVP_enc_null(void)
07350     {
07351         static const char* type = "NULL";
07352         CYASSL_ENTER("CyaSSL_EVP_enc_null");
07353         return type;
07354     }
07355 
07356 
07357     int CyaSSL_EVP_MD_CTX_cleanup(CYASSL_EVP_MD_CTX* ctx)
07358     {
07359         CYASSL_ENTER("EVP_MD_CTX_cleanup");
07360         (void)ctx;
07361         return 0;
07362     }
07363 
07364 
07365 
07366     void CyaSSL_EVP_CIPHER_CTX_init(CYASSL_EVP_CIPHER_CTX* ctx)
07367     {
07368         CYASSL_ENTER("EVP_CIPHER_CTX_init");
07369         if (ctx) {
07370             ctx->cipherType = 0xff;   /* no init */
07371             ctx->keyLen     = 0;
07372             ctx->enc        = 1;      /* start in encrypt mode */
07373         }
07374     }
07375 
07376 
07377     /* SSL_SUCCESS on ok */
07378     int CyaSSL_EVP_CIPHER_CTX_cleanup(CYASSL_EVP_CIPHER_CTX* ctx)
07379     {
07380         CYASSL_ENTER("EVP_CIPHER_CTX_cleanup");
07381         if (ctx) {
07382             ctx->cipherType = 0xff;  /* no more init */
07383             ctx->keyLen     = 0;
07384         }
07385 
07386         return SSL_SUCCESS;
07387     }
07388 
07389 
07390     /* SSL_SUCCESS on ok */
07391     int  CyaSSL_EVP_CipherInit(CYASSL_EVP_CIPHER_CTX* ctx,
07392                                const CYASSL_EVP_CIPHER* type, byte* key,
07393                                byte* iv, int enc)
07394     {
07395         int ret = 0;
07396 
07397         CYASSL_ENTER("CyaSSL_EVP_CipherInit");
07398         if (ctx == NULL) {
07399             CYASSL_MSG("no ctx");
07400             return 0;   /* failure */
07401         }
07402 
07403         if (type == NULL && ctx->cipherType == 0xff) {
07404             CYASSL_MSG("no type set");
07405             return 0;   /* failure */
07406         }
07407 
07408         if (ctx->cipherType == AES_128_CBC_TYPE || (type &&
07409                                        XSTRNCMP(type, "AES128-CBC", 10) == 0)) {
07410             CYASSL_MSG("AES-128-CBC");
07411             ctx->cipherType = AES_128_CBC_TYPE;
07412             ctx->keyLen     = 16;
07413             if (enc == 0 || enc == 1)
07414                 ctx->enc = enc ? 1 : 0;
07415             if (key) {
07416                 ret = AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
07417                                 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
07418                 if (ret != 0)
07419                     return ret;
07420             }
07421             if (iv && key == NULL) {
07422                 ret = AesSetIV(&ctx->cipher.aes, iv);
07423                 if (ret != 0)
07424                     return ret;
07425             }
07426         }
07427         else if (ctx->cipherType == AES_192_CBC_TYPE || (type &&
07428                                        XSTRNCMP(type, "AES192-CBC", 10) == 0)) {
07429             CYASSL_MSG("AES-192-CBC");
07430             ctx->cipherType = AES_192_CBC_TYPE;
07431             ctx->keyLen     = 24;
07432             if (enc == 0 || enc == 1)
07433                 ctx->enc = enc ? 1 : 0;
07434             if (key) {
07435                 ret = AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
07436                                 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
07437                 if (ret != 0)
07438                     return ret;
07439             }
07440             if (iv && key == NULL) {
07441                 ret = AesSetIV(&ctx->cipher.aes, iv);
07442                 if (ret != 0)
07443                     return ret;
07444             }
07445         }
07446         else if (ctx->cipherType == AES_256_CBC_TYPE || (type &&
07447                                        XSTRNCMP(type, "AES256-CBC", 10) == 0)) {
07448             CYASSL_MSG("AES-256-CBC");
07449             ctx->cipherType = AES_256_CBC_TYPE;
07450             ctx->keyLen     = 32;
07451             if (enc == 0 || enc == 1)
07452                 ctx->enc = enc ? 1 : 0;
07453             if (key) {
07454                 ret = AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
07455                                 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
07456                 if (ret != 0)
07457                     return ret;
07458             }
07459             if (iv && key == NULL) {
07460                 ret = AesSetIV(&ctx->cipher.aes, iv);
07461                 if (ret != 0)
07462                     return ret;
07463             }
07464         }
07465 #ifdef CYASSL_AES_COUNTER
07466         else if (ctx->cipherType == AES_128_CTR_TYPE || (type &&
07467                                        XSTRNCMP(type, "AES128-CTR", 10) == 0)) {
07468             CYASSL_MSG("AES-128-CTR");
07469             ctx->cipherType = AES_128_CTR_TYPE;
07470             ctx->keyLen     = 16;
07471             if (enc == 0 || enc == 1)
07472                 ctx->enc = enc ? 1 : 0;
07473             if (key) {
07474                 ret = AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
07475                                 AES_ENCRYPTION);
07476                 if (ret != 0)
07477                     return ret;
07478             }
07479             if (iv && key == NULL) {
07480                 ret = AesSetIV(&ctx->cipher.aes, iv);
07481                 if (ret != 0)
07482                     return ret;
07483             }
07484         }
07485         else if (ctx->cipherType == AES_192_CTR_TYPE || (type &&
07486                                        XSTRNCMP(type, "AES192-CTR", 10) == 0)) {
07487             CYASSL_MSG("AES-192-CTR");
07488             ctx->cipherType = AES_192_CTR_TYPE;
07489             ctx->keyLen     = 24;
07490             if (enc == 0 || enc == 1)
07491                 ctx->enc = enc ? 1 : 0;
07492             if (key) {
07493                 ret = AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
07494                                 AES_ENCRYPTION);
07495                 if (ret != 0)
07496                     return ret;
07497             }
07498             if (iv && key == NULL) {
07499                 ret = AesSetIV(&ctx->cipher.aes, iv);
07500                 if (ret != 0)
07501                     return ret;
07502             }
07503         }
07504         else if (ctx->cipherType == AES_256_CTR_TYPE || (type &&
07505                                        XSTRNCMP(type, "AES256-CTR", 10) == 0)) {
07506             CYASSL_MSG("AES-256-CTR");
07507             ctx->cipherType = AES_256_CTR_TYPE;
07508             ctx->keyLen     = 32;
07509             if (enc == 0 || enc == 1)
07510                 ctx->enc = enc ? 1 : 0;
07511             if (key) {
07512                 ret = AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
07513                                 AES_ENCRYPTION);
07514                 if (ret != 0)
07515                     return ret;
07516             }
07517             if (iv && key == NULL) {
07518                 ret = AesSetIV(&ctx->cipher.aes, iv);
07519                 if (ret != 0)
07520                     return ret;
07521             }
07522         }
07523 #endif /* CYASSL_AES_CTR */
07524         else if (ctx->cipherType == DES_CBC_TYPE || (type &&
07525                                        XSTRNCMP(type, "DES-CBC", 7) == 0)) {
07526             CYASSL_MSG("DES-CBC");
07527             ctx->cipherType = DES_CBC_TYPE;
07528             ctx->keyLen     = 8;
07529             if (enc == 0 || enc == 1)
07530                 ctx->enc = enc ? 1 : 0;
07531             if (key) {
07532                 ret = Des_SetKey(&ctx->cipher.des, key, iv,
07533                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
07534                 if (ret != 0)
07535                     return ret;
07536             }
07537 
07538             if (iv && key == NULL)
07539                 Des_SetIV(&ctx->cipher.des, iv);
07540         }
07541         else if (ctx->cipherType == DES_EDE3_CBC_TYPE || (type &&
07542                                      XSTRNCMP(type, "DES-EDE3-CBC", 11) == 0)) {
07543             CYASSL_MSG("DES-EDE3-CBC");
07544             ctx->cipherType = DES_EDE3_CBC_TYPE;
07545             ctx->keyLen     = 24;
07546             if (enc == 0 || enc == 1)
07547                 ctx->enc = enc ? 1 : 0;
07548             if (key) {
07549                 ret = Des3_SetKey(&ctx->cipher.des3, key, iv,
07550                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
07551                 if (ret != 0)
07552                     return ret;
07553             }
07554 
07555             if (iv && key == NULL) {
07556                 ret = Des3_SetIV(&ctx->cipher.des3, iv);
07557                 if (ret != 0)
07558                     return ret;
07559             }
07560         }
07561         else if (ctx->cipherType == ARC4_TYPE || (type &&
07562                                      XSTRNCMP(type, "ARC4", 4) == 0)) {
07563             CYASSL_MSG("ARC4");
07564             ctx->cipherType = ARC4_TYPE;
07565             if (ctx->keyLen == 0)  /* user may have already set */
07566                 ctx->keyLen = 16;  /* default to 128 */
07567             if (key)
07568                 Arc4SetKey(&ctx->cipher.arc4, key, ctx->keyLen);
07569         }
07570         else if (ctx->cipherType == NULL_CIPHER_TYPE || (type &&
07571                                      XSTRNCMP(type, "NULL", 4) == 0)) {
07572             CYASSL_MSG("NULL cipher");
07573             ctx->cipherType = NULL_CIPHER_TYPE;
07574             ctx->keyLen = 0;
07575         }
07576         else
07577             return 0;   /* failure */
07578 
07579 
07580         return SSL_SUCCESS;
07581     }
07582 
07583 
07584     /* SSL_SUCCESS on ok */
07585     int CyaSSL_EVP_CIPHER_CTX_key_length(CYASSL_EVP_CIPHER_CTX* ctx)
07586     {
07587         CYASSL_ENTER("CyaSSL_EVP_CIPHER_CTX_key_length");
07588         if (ctx)
07589             return ctx->keyLen;
07590 
07591         return 0;   /* failure */
07592     }
07593 
07594 
07595     /* SSL_SUCCESS on ok */
07596     int CyaSSL_EVP_CIPHER_CTX_set_key_length(CYASSL_EVP_CIPHER_CTX* ctx,
07597                                              int keylen)
07598     {
07599         CYASSL_ENTER("CyaSSL_EVP_CIPHER_CTX_set_key_length");
07600         if (ctx)
07601             ctx->keyLen = keylen;
07602         else
07603             return 0;  /* failure */
07604 
07605         return SSL_SUCCESS;
07606     }
07607 
07608 
07609     /* SSL_SUCCESS on ok */
07610     int CyaSSL_EVP_Cipher(CYASSL_EVP_CIPHER_CTX* ctx, byte* dst, byte* src,
07611                           word32 len)
07612     {
07613         int ret = 0;
07614         CYASSL_ENTER("CyaSSL_EVP_Cipher");
07615 
07616         if (ctx == NULL || dst == NULL || src == NULL) {
07617             CYASSL_MSG("Bad function argument");
07618             return 0;  /* failure */
07619         }
07620 
07621         if (ctx->cipherType == 0xff) {
07622             CYASSL_MSG("no init");
07623             return 0;  /* failure */
07624         }
07625 
07626         switch (ctx->cipherType) {
07627 
07628             case AES_128_CBC_TYPE :
07629             case AES_192_CBC_TYPE :
07630             case AES_256_CBC_TYPE :
07631                 CYASSL_MSG("AES CBC");
07632                 if (ctx->enc)
07633                     ret = AesCbcEncrypt(&ctx->cipher.aes, dst, src, len);
07634                 else
07635                     ret = AesCbcDecrypt(&ctx->cipher.aes, dst, src, len);
07636                 break;
07637 
07638 #ifdef CYASSL_AES_COUNTER
07639             case AES_128_CTR_TYPE :
07640             case AES_192_CTR_TYPE :
07641             case AES_256_CTR_TYPE :
07642                     CYASSL_MSG("AES CTR");
07643                     AesCtrEncrypt(&ctx->cipher.aes, dst, src, len);
07644                 break;
07645 #endif
07646 
07647             case DES_CBC_TYPE :
07648                 if (ctx->enc)
07649                     Des_CbcEncrypt(&ctx->cipher.des, dst, src, len);
07650                 else
07651                     Des_CbcDecrypt(&ctx->cipher.des, dst, src, len);
07652                 break;
07653 
07654             case DES_EDE3_CBC_TYPE :
07655                 if (ctx->enc)
07656                     ret = Des3_CbcEncrypt(&ctx->cipher.des3, dst, src, len);
07657                 else
07658                     ret = Des3_CbcDecrypt(&ctx->cipher.des3, dst, src, len);
07659                 break;
07660 
07661             case ARC4_TYPE :
07662                 Arc4Process(&ctx->cipher.arc4, dst, src, len);
07663                 break;
07664 
07665             case NULL_CIPHER_TYPE :
07666                 XMEMCPY(dst, src, len);
07667                 break;
07668 
07669             default: {
07670                 CYASSL_MSG("bad type");
07671                 return 0;  /* failure */
07672             }
07673         }
07674 
07675         if (ret != 0) {
07676             CYASSL_MSG("CyaSSL_EVP_Cipher failure");
07677             return 0;  /* failuer */
07678         }
07679 
07680         CYASSL_MSG("CyaSSL_EVP_Cipher success");
07681         return SSL_SUCCESS;  /* success */
07682     }
07683 
07684 
07685     /* store for external read of iv, SSL_SUCCESS on success */
07686     int  CyaSSL_StoreExternalIV(CYASSL_EVP_CIPHER_CTX* ctx)
07687     {
07688         CYASSL_ENTER("CyaSSL_StoreExternalIV");
07689 
07690         if (ctx == NULL) {
07691             CYASSL_MSG("Bad function argument");
07692             return SSL_FATAL_ERROR;
07693         }
07694 
07695         switch (ctx->cipherType) {
07696 
07697             case AES_128_CBC_TYPE :
07698             case AES_192_CBC_TYPE :
07699             case AES_256_CBC_TYPE :
07700                 CYASSL_MSG("AES CBC");
07701                 memcpy(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
07702                 break;
07703 
07704 #ifdef CYASSL_AES_COUNTER
07705             case AES_128_CTR_TYPE :
07706             case AES_192_CTR_TYPE :
07707             case AES_256_CTR_TYPE :
07708                 CYASSL_MSG("AES CTR");
07709                 memcpy(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
07710                 break;
07711 #endif
07712 
07713             case DES_CBC_TYPE :
07714                 CYASSL_MSG("DES CBC");
07715                 memcpy(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
07716                 break;
07717 
07718             case DES_EDE3_CBC_TYPE :
07719                 CYASSL_MSG("DES EDE3 CBC");
07720                 memcpy(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
07721                 break;
07722 
07723             case ARC4_TYPE :
07724                 CYASSL_MSG("ARC4");
07725                 break;
07726 
07727             case NULL_CIPHER_TYPE :
07728                 CYASSL_MSG("NULL");
07729                 break;
07730 
07731             default: {
07732                 CYASSL_MSG("bad type");
07733                 return SSL_FATAL_ERROR;
07734             }
07735         }
07736         return SSL_SUCCESS;
07737     }
07738 
07739 
07740     /* set internal IV from external, SSL_SUCCESS on success */
07741     int  CyaSSL_SetInternalIV(CYASSL_EVP_CIPHER_CTX* ctx)
07742     {
07743 
07744         CYASSL_ENTER("CyaSSL_SetInternalIV");
07745 
07746         if (ctx == NULL) {
07747             CYASSL_MSG("Bad function argument");
07748             return SSL_FATAL_ERROR;
07749         }
07750 
07751         switch (ctx->cipherType) {
07752 
07753             case AES_128_CBC_TYPE :
07754             case AES_192_CBC_TYPE :
07755             case AES_256_CBC_TYPE :
07756                 CYASSL_MSG("AES CBC");
07757                 memcpy(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
07758                 break;
07759 
07760 #ifdef CYASSL_AES_COUNTER
07761             case AES_128_CTR_TYPE :
07762             case AES_192_CTR_TYPE :
07763             case AES_256_CTR_TYPE :
07764                 CYASSL_MSG("AES CTR");
07765                 memcpy(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
07766                 break;
07767 #endif
07768 
07769             case DES_CBC_TYPE :
07770                 CYASSL_MSG("DES CBC");
07771                 memcpy(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
07772                 break;
07773 
07774             case DES_EDE3_CBC_TYPE :
07775                 CYASSL_MSG("DES EDE3 CBC");
07776                 memcpy(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
07777                 break;
07778 
07779             case ARC4_TYPE :
07780                 CYASSL_MSG("ARC4");
07781                 break;
07782 
07783             case NULL_CIPHER_TYPE :
07784                 CYASSL_MSG("NULL");
07785                 break;
07786 
07787             default: {
07788                 CYASSL_MSG("bad type");
07789                 return SSL_FATAL_ERROR;
07790             }
07791         }
07792         return SSL_SUCCESS;
07793     }
07794 
07795 
07796     /* SSL_SUCCESS on ok */
07797     int CyaSSL_EVP_DigestInit(CYASSL_EVP_MD_CTX* ctx, const CYASSL_EVP_MD* type)
07798     {
07799         CYASSL_ENTER("EVP_DigestInit");
07800         if (XSTRNCMP(type, "MD5", 3) == 0) {
07801              ctx->macType = MD5;
07802              CyaSSL_MD5_Init((MD5_CTX*)&ctx->hash);
07803         }
07804         else if (XSTRNCMP(type, "SHA256", 6) == 0) {
07805              ctx->macType = SHA256;
07806              CyaSSL_SHA256_Init((SHA256_CTX*)&ctx->hash);
07807         }
07808     #ifdef CYASSL_SHA384
07809         else if (XSTRNCMP(type, "SHA384", 6) == 0) {
07810              ctx->macType = SHA384;
07811              CyaSSL_SHA384_Init((SHA384_CTX*)&ctx->hash);
07812         }
07813     #endif
07814     #ifdef CYASSL_SHA512
07815         else if (XSTRNCMP(type, "SHA512", 6) == 0) {
07816              ctx->macType = SHA512;
07817              CyaSSL_SHA512_Init((SHA512_CTX*)&ctx->hash);
07818         }
07819     #endif
07820         /* has to be last since would pick or 256, 384, or 512 too */
07821         else if (XSTRNCMP(type, "SHA", 3) == 0) {
07822              ctx->macType = SHA;
07823              CyaSSL_SHA_Init((SHA_CTX*)&ctx->hash);
07824         }
07825         else
07826              return BAD_FUNC_ARG;
07827 
07828         return SSL_SUCCESS;
07829     }
07830 
07831 
07832     /* SSL_SUCCESS on ok */
07833     int CyaSSL_EVP_DigestUpdate(CYASSL_EVP_MD_CTX* ctx, const void* data,
07834                                 unsigned long sz)
07835     {
07836         CYASSL_ENTER("EVP_DigestUpdate");
07837         if (ctx->macType == MD5)
07838             CyaSSL_MD5_Update((MD5_CTX*)&ctx->hash, data, (unsigned long)sz);
07839         else if (ctx->macType == SHA)
07840             CyaSSL_SHA_Update((SHA_CTX*)&ctx->hash, data, (unsigned long)sz);
07841         else if (ctx->macType == SHA256)
07842             CyaSSL_SHA256_Update((SHA256_CTX*)&ctx->hash, data,
07843                                  (unsigned long)sz);
07844     #ifdef CYASSL_SHA384
07845         else if (ctx->macType == SHA384)
07846             CyaSSL_SHA384_Update((SHA384_CTX*)&ctx->hash, data,
07847                                  (unsigned long)sz);
07848     #endif
07849     #ifdef CYASSL_SHA512
07850         else if (ctx->macType == SHA512)
07851             CyaSSL_SHA512_Update((SHA512_CTX*)&ctx->hash, data,
07852                                  (unsigned long)sz);
07853     #endif
07854         else
07855             return BAD_FUNC_ARG;
07856 
07857         return SSL_SUCCESS;
07858     }
07859 
07860 
07861     /* SSL_SUCCESS on ok */
07862     int CyaSSL_EVP_DigestFinal(CYASSL_EVP_MD_CTX* ctx, unsigned char* md,
07863                                unsigned int* s)
07864     {
07865         CYASSL_ENTER("EVP_DigestFinal");
07866         if (ctx->macType == MD5) {
07867             CyaSSL_MD5_Final(md, (MD5_CTX*)&ctx->hash);
07868             if (s) *s = MD5_DIGEST_SIZE;
07869         }
07870         else if (ctx->macType == SHA) {
07871             CyaSSL_SHA_Final(md, (SHA_CTX*)&ctx->hash);
07872             if (s) *s = SHA_DIGEST_SIZE;
07873         }
07874         else if (ctx->macType == SHA256) {
07875             CyaSSL_SHA256_Final(md, (SHA256_CTX*)&ctx->hash);
07876             if (s) *s = SHA256_DIGEST_SIZE;
07877         }
07878     #ifdef CYASSL_SHA384
07879         else if (ctx->macType == SHA384) {
07880             CyaSSL_SHA384_Final(md, (SHA384_CTX*)&ctx->hash);
07881             if (s) *s = SHA384_DIGEST_SIZE;
07882         }
07883     #endif
07884     #ifdef CYASSL_SHA512
07885         else if (ctx->macType == SHA512) {
07886             CyaSSL_SHA512_Final(md, (SHA512_CTX*)&ctx->hash);
07887             if (s) *s = SHA512_DIGEST_SIZE;
07888         }
07889     #endif
07890         else
07891             return BAD_FUNC_ARG;
07892 
07893         return SSL_SUCCESS;
07894     }
07895 
07896 
07897     /* SSL_SUCCESS on ok */
07898     int CyaSSL_EVP_DigestFinal_ex(CYASSL_EVP_MD_CTX* ctx, unsigned char* md,
07899                                   unsigned int* s)
07900     {
07901         CYASSL_ENTER("EVP_DigestFinal_ex");
07902         return EVP_DigestFinal(ctx, md, s);
07903     }
07904 
07905 
07906     unsigned char* CyaSSL_HMAC(const CYASSL_EVP_MD* evp_md, const void* key,
07907                                int key_len, const unsigned char* d, int n,
07908                                unsigned char* md, unsigned int* md_len)
07909     {
07910         int type;
07911         unsigned char* ret = NULL;
07912 #ifdef CYASSL_SMALL_STACK
07913         Hmac* hmac = NULL;
07914 #else
07915         Hmac  hmac[1];
07916 #endif
07917 
07918         CYASSL_ENTER("HMAC");
07919         if (!md)
07920             return NULL;  /* no static buffer support */
07921 
07922         if (XSTRNCMP(evp_md, "MD5", 3) == 0)
07923             type = MD5;
07924         else if (XSTRNCMP(evp_md, "SHA", 3) == 0)
07925             type = SHA;
07926         else
07927             return NULL;
07928 
07929     #ifdef CYASSL_SMALL_STACK
07930         hmac = (Hmac*)XMALLOC(sizeof(Hmac), NULL, DYNAMIC_TYPE_TMP_BUFFER);
07931         if (hmac == NULL)
07932             return NULL;
07933     #endif
07934 
07935         if (HmacSetKey(hmac, type, (const byte*)key, key_len) == 0)
07936             if (HmacUpdate(hmac, d, n) == 0)
07937                 if (HmacFinal(hmac, md) == 0) {
07938                     if (md_len)
07939                         *md_len = (type == MD5) ? (int)MD5_DIGEST_SIZE
07940                                                 : (int)SHA_DIGEST_SIZE;
07941                     ret = md;
07942                 }
07943 
07944     #ifdef CYASSL_SMALL_STACK
07945         XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07946     #endif
07947 
07948         return ret;
07949     }
07950 
07951     void CyaSSL_ERR_clear_error(void)
07952     {
07953         /* TODO: */
07954     }
07955 
07956 
07957     int CyaSSL_RAND_status(void)
07958     {
07959         return SSL_SUCCESS;  /* CTaoCrypt provides enough seed internally */
07960     }
07961 
07962 
07963 
07964     void CyaSSL_RAND_add(const void* add, int len, double entropy)
07965     {
07966         (void)add;
07967         (void)len;
07968         (void)entropy;
07969 
07970         /* CyaSSL seeds/adds internally, use explicit RNG if you want
07971            to take control */
07972     }
07973 
07974 
07975     /* SSL_SUCCESS on ok */
07976     int CyaSSL_DES_key_sched(CYASSL_const_DES_cblock* key,
07977                              CYASSL_DES_key_schedule* schedule)
07978     {
07979         CYASSL_ENTER("DES_key_sched");
07980         XMEMCPY(schedule, key, sizeof(const_DES_cblock));
07981         return SSL_SUCCESS;
07982     }
07983 
07984 
07985     void CyaSSL_DES_cbc_encrypt(const unsigned char* input,
07986                      unsigned char* output, long length,
07987                      CYASSL_DES_key_schedule* schedule, CYASSL_DES_cblock* ivec,
07988                      int enc)
07989     {
07990         Des myDes;
07991 
07992         CYASSL_ENTER("DES_cbc_encrypt");
07993 
07994         /* OpenSSL compat, no ret */
07995         Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
07996 
07997         if (enc)
07998             Des_CbcEncrypt(&myDes, output, input, (word32)length);
07999         else
08000             Des_CbcDecrypt(&myDes, output, input, (word32)length);
08001     }
08002 
08003 
08004     /* correctly sets ivec for next call */
08005     void CyaSSL_DES_ncbc_encrypt(const unsigned char* input,
08006                      unsigned char* output, long length,
08007                      CYASSL_DES_key_schedule* schedule, CYASSL_DES_cblock* ivec,
08008                      int enc)
08009     {
08010         Des myDes;
08011 
08012         CYASSL_ENTER("DES_ncbc_encrypt");
08013 
08014         /* OpenSSL compat, no ret */
08015         Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
08016 
08017         if (enc)
08018             Des_CbcEncrypt(&myDes, output, input, (word32)length);
08019         else
08020             Des_CbcDecrypt(&myDes, output, input, (word32)length);
08021 
08022         XMEMCPY(ivec, output + length - sizeof(DES_cblock), sizeof(DES_cblock));
08023     }
08024 
08025 
08026     void CyaSSL_ERR_free_strings(void)
08027     {
08028         /* handled internally */
08029     }
08030 
08031 
08032     void CyaSSL_ERR_remove_state(unsigned long state)
08033     {
08034         /* TODO: GetErrors().Remove(); */
08035         (void)state;
08036     }
08037 
08038 
08039     void CyaSSL_EVP_cleanup(void)
08040     {
08041         /* nothing to do here */
08042     }
08043 
08044 
08045     void CyaSSL_cleanup_all_ex_data(void)
08046     {
08047         /* nothing to do here */
08048     }
08049 
08050 
08051     long CyaSSL_CTX_set_mode(CYASSL_CTX* ctx, long mode)
08052     {
08053         /* SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is CyaSSL default mode */
08054 
08055         CYASSL_ENTER("SSL_CTX_set_mode");
08056         if (mode == SSL_MODE_ENABLE_PARTIAL_WRITE)
08057             ctx->partialWrite = 1;
08058 
08059         return mode;
08060     }
08061 
08062 
08063     long CyaSSL_CTX_get_mode(CYASSL_CTX* ctx)
08064     {
08065         /* TODO: */
08066         (void)ctx;
08067         return 0;
08068     }
08069 
08070 
08071     void CyaSSL_CTX_set_default_read_ahead(CYASSL_CTX* ctx, int m)
08072     {
08073         /* TODO: maybe? */
08074         (void)ctx;
08075         (void)m;
08076     }
08077 
08078 
08079     int CyaSSL_CTX_set_session_id_context(CYASSL_CTX* ctx,
08080                                        const unsigned char* sid_ctx,
08081                                        unsigned int sid_ctx_len)
08082     {
08083         /* No application specific context needed for cyaSSL */
08084         (void)ctx;
08085         (void)sid_ctx;
08086         (void)sid_ctx_len;
08087         return SSL_SUCCESS;
08088     }
08089 
08090 
08091     long CyaSSL_CTX_sess_get_cache_size(CYASSL_CTX* ctx)
08092     {
08093         /* TODO: maybe? */
08094         (void)ctx;
08095         return (~0);
08096     }
08097 
08098     unsigned long CyaSSL_ERR_get_error_line_data(const char** file, int* line,
08099                                           const char** data, int *flags)
08100     {
08101         /* Not implemented */
08102         (void)file;
08103         (void)line;
08104         (void)data;
08105         (void)flags;
08106         return 0;
08107     }
08108 
08109 #endif /* OPENSSL_EXTRA */
08110 
08111 
08112 #if defined(KEEP_PEER_CERT)
08113 
08114     CYASSL_X509* CyaSSL_get_peer_certificate(CYASSL* ssl)
08115     {
08116         CYASSL_ENTER("SSL_get_peer_certificate");
08117         if (ssl->peerCert.issuer.sz)
08118             return &ssl->peerCert;
08119         else
08120             return 0;
08121     }
08122 
08123 #endif /* KEEP_PEER_CERT */
08124 
08125 
08126 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
08127 
08128     void CyaSSL_FreeX509(CYASSL_X509* x509)
08129     {
08130         CYASSL_ENTER("CyaSSL_FreeX509");
08131         FreeX509(x509);
08132     }
08133 
08134 
08135     /* return the next, if any, altname from the peer cert */
08136     char* CyaSSL_X509_get_next_altname(CYASSL_X509* cert)
08137     {
08138         char* ret = NULL;
08139         CYASSL_ENTER("CyaSSL_X509_get_next_altname");
08140 
08141         /* don't have any to work with */
08142         if (cert == NULL || cert->altNames == NULL)
08143             return NULL;
08144 
08145         /* already went through them */
08146         if (cert->altNamesNext == NULL)
08147             return NULL;
08148 
08149         ret = cert->altNamesNext->name;
08150         cert->altNamesNext = cert->altNamesNext->next;
08151 
08152         return ret;
08153     }
08154 
08155 
08156     CYASSL_X509_NAME* CyaSSL_X509_get_issuer_name(CYASSL_X509* cert)
08157     {
08158         CYASSL_ENTER("X509_get_issuer_name");
08159         return &cert->issuer;
08160     }
08161 
08162 
08163     CYASSL_X509_NAME* CyaSSL_X509_get_subject_name(CYASSL_X509* cert)
08164     {
08165         CYASSL_ENTER("X509_get_subject_name");
08166         return &cert->subject;
08167     }
08168 
08169 
08170     int CyaSSL_X509_get_isCA(CYASSL_X509* x509)
08171     {
08172         int isCA = 0;
08173 
08174         CYASSL_ENTER("CyaSSL_X509_get_isCA");
08175 
08176         if (x509 != NULL)
08177             isCA = x509->isCa;
08178 
08179         CYASSL_LEAVE("CyaSSL_X509_get_isCA", isCA);
08180 
08181         return isCA;
08182     }
08183 
08184 
08185 #ifdef OPENSSL_EXTRA
08186     int CyaSSL_X509_ext_isSet_by_NID(CYASSL_X509* x509, int nid)
08187     {
08188         int isSet = 0;
08189 
08190         CYASSL_ENTER("CyaSSL_X509_ext_isSet_by_NID");
08191 
08192         if (x509 != NULL) {
08193             switch (nid) {
08194                 case BASIC_CA_OID: isSet = x509->basicConstSet; break;
08195                 case ALT_NAMES_OID: isSet = x509->subjAltNameSet; break;
08196                 case AUTH_KEY_OID: isSet = x509->authKeyIdSet; break;
08197                 case SUBJ_KEY_OID: isSet = x509->subjKeyIdSet; break;
08198                 case KEY_USAGE_OID: isSet = x509->keyUsageSet; break;
08199                 #ifdef CYASSL_SEP
08200                     case CERT_POLICY_OID: isSet = x509->certPolicySet; break;
08201                 #endif /* CYASSL_SEP */
08202             }
08203         }
08204 
08205         CYASSL_LEAVE("CyaSSL_X509_ext_isSet_by_NID", isSet);
08206 
08207         return isSet;
08208     }
08209 
08210 
08211     int CyaSSL_X509_ext_get_critical_by_NID(CYASSL_X509* x509, int nid)
08212     {
08213         int crit = 0;
08214 
08215         CYASSL_ENTER("CyaSSL_X509_ext_get_critical_by_NID");
08216 
08217         if (x509 != NULL) {
08218             switch (nid) {
08219                 case BASIC_CA_OID: crit = x509->basicConstCrit; break;
08220                 case ALT_NAMES_OID: crit = x509->subjAltNameCrit; break;
08221                 case AUTH_KEY_OID: crit = x509->authKeyIdCrit; break;
08222                 case SUBJ_KEY_OID: crit = x509->subjKeyIdCrit; break;
08223                 case KEY_USAGE_OID: crit = x509->keyUsageCrit; break;
08224                 #ifdef CYASSL_SEP
08225                     case CERT_POLICY_OID: crit = x509->certPolicyCrit; break;
08226                 #endif /* CYASSL_SEP */
08227             }
08228         }
08229 
08230         CYASSL_LEAVE("CyaSSL_X509_ext_get_critical_by_NID", crit);
08231 
08232         return crit;
08233     }
08234 
08235 
08236     int CyaSSL_X509_get_isSet_pathLength(CYASSL_X509* x509)
08237     {
08238         int isSet = 0;
08239 
08240         CYASSL_ENTER("CyaSSL_X509_get_isSet_pathLength");
08241 
08242         if (x509 != NULL)
08243             isSet = x509->basicConstPlSet;
08244 
08245         CYASSL_LEAVE("CyaSSL_X509_get_isSet_pathLength", isSet);
08246 
08247         return isSet;
08248     }
08249 
08250 
08251     word32 CyaSSL_X509_get_pathLength(CYASSL_X509* x509)
08252     {
08253         word32 pathLength = 0;
08254 
08255         CYASSL_ENTER("CyaSSL_X509_get_pathLength");
08256 
08257         if (x509 != NULL)
08258             pathLength = x509->pathLength;
08259 
08260         CYASSL_LEAVE("CyaSSL_X509_get_pathLength", pathLength);
08261 
08262         return pathLength;
08263     }
08264 
08265 
08266     unsigned int CyaSSL_X509_get_keyUsage(CYASSL_X509* x509)
08267     {
08268         word16 usage = 0;
08269 
08270         CYASSL_ENTER("CyaSSL_X509_get_keyUsage");
08271 
08272         if (x509 != NULL)
08273             usage = x509->keyUsage;
08274 
08275         CYASSL_LEAVE("CyaSSL_X509_get_keyUsage", usage);
08276 
08277         return usage;
08278     }
08279 
08280 
08281     byte* CyaSSL_X509_get_authorityKeyID(
08282                                       CYASSL_X509* x509, byte* dst, int* dstLen)
08283     {
08284         byte *id = NULL;
08285         int copySz = 0;
08286 
08287         CYASSL_ENTER("CyaSSL_X509_get_authorityKeyID");
08288 
08289         if (x509 != NULL) {
08290             if (x509->authKeyIdSet) {
08291                 copySz = min(dstLen != NULL ? *dstLen : 0,
08292                                                         (int)x509->authKeyIdSz);
08293                 id = x509->authKeyId;
08294             }
08295 
08296             if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
08297                 XMEMCPY(dst, id, copySz);
08298                 id = dst;
08299                 *dstLen = copySz;
08300             }
08301         }
08302 
08303         CYASSL_LEAVE("CyaSSL_X509_get_authorityKeyID", copySz);
08304 
08305         return id;
08306     }
08307 
08308 
08309     byte* CyaSSL_X509_get_subjectKeyID(
08310                                       CYASSL_X509* x509, byte* dst, int* dstLen)
08311     {
08312         byte *id = NULL;
08313         int copySz = 0;
08314 
08315         CYASSL_ENTER("CyaSSL_X509_get_subjectKeyID");
08316 
08317         if (x509 != NULL) {
08318             if (x509->subjKeyIdSet) {
08319                 copySz = min(dstLen != NULL ? *dstLen : 0,
08320                                                         (int)x509->subjKeyIdSz);
08321                 id = x509->subjKeyId;
08322             }
08323 
08324             if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
08325                 XMEMCPY(dst, id, copySz);
08326                 id = dst;
08327                 *dstLen = copySz;
08328             }
08329         }
08330 
08331         CYASSL_LEAVE("CyaSSL_X509_get_subjectKeyID", copySz);
08332 
08333         return id;
08334     }
08335 
08336 
08337     int CyaSSL_X509_NAME_entry_count(CYASSL_X509_NAME* name)
08338     {
08339         int count = 0;
08340 
08341         CYASSL_ENTER("CyaSSL_X509_NAME_entry_count");
08342 
08343         if (name != NULL)
08344             count = name->fullName.entryCount;
08345 
08346         CYASSL_LEAVE("CyaSSL_X509_NAME_entry_count", count);
08347         return count;
08348     }
08349 
08350 
08351     int CyaSSL_X509_NAME_get_text_by_NID(CYASSL_X509_NAME* name,
08352                                                     int nid, char* buf, int len)
08353     {
08354         char *text = NULL;
08355         int textSz = 0;
08356 
08357         CYASSL_ENTER("CyaSSL_X509_NAME_get_text_by_NID");
08358 
08359         switch (nid) {
08360             case ASN_COMMON_NAME:
08361                 text = name->fullName.fullName + name->fullName.cnIdx;
08362                 textSz = name->fullName.cnLen;
08363                 break;
08364             case ASN_SUR_NAME:
08365                 text = name->fullName.fullName + name->fullName.snIdx;
08366                 textSz = name->fullName.snLen;
08367                 break;
08368             case ASN_SERIAL_NUMBER:
08369                 text = name->fullName.fullName + name->fullName.serialIdx;
08370                 textSz = name->fullName.serialLen;
08371                 break;
08372             case ASN_COUNTRY_NAME:
08373                 text = name->fullName.fullName + name->fullName.cIdx;
08374                 textSz = name->fullName.cLen;
08375                 break;
08376             case ASN_LOCALITY_NAME:
08377                 text = name->fullName.fullName + name->fullName.lIdx;
08378                 textSz = name->fullName.lLen;
08379                 break;
08380             case ASN_STATE_NAME:
08381                 text = name->fullName.fullName + name->fullName.stIdx;
08382                 textSz = name->fullName.stLen;
08383                 break;
08384             case ASN_ORG_NAME:
08385                 text = name->fullName.fullName + name->fullName.oIdx;
08386                 textSz = name->fullName.oLen;
08387                 break;
08388             case ASN_ORGUNIT_NAME:
08389                 text = name->fullName.fullName + name->fullName.ouIdx;
08390                 textSz = name->fullName.ouLen;
08391                 break;
08392             default:
08393                 break;
08394         }
08395 
08396         if (buf != NULL && text != NULL) {
08397             textSz = min(textSz, len);
08398             XMEMCPY(buf, text, textSz);
08399             buf[textSz] = '\0';
08400         }
08401 
08402         CYASSL_LEAVE("CyaSSL_X509_NAME_get_text_by_NID", textSz);
08403         return textSz;
08404     }
08405 #endif
08406 
08407 
08408     /* copy name into in buffer, at most sz bytes, if buffer is null will
08409        malloc buffer, call responsible for freeing                     */
08410     char* CyaSSL_X509_NAME_oneline(CYASSL_X509_NAME* name, char* in, int sz)
08411     {
08412         int copySz = min(sz, name->sz);
08413 
08414         CYASSL_ENTER("CyaSSL_X509_NAME_oneline");
08415         if (!name->sz) return in;
08416 
08417         if (!in) {
08418             in = (char*)XMALLOC(name->sz, 0, DYNAMIC_TYPE_OPENSSL);
08419             if (!in ) return in;
08420             copySz = name->sz;
08421         }
08422 
08423         if (copySz == 0)
08424             return in;
08425 
08426         XMEMCPY(in, name->name, copySz - 1);
08427         in[copySz - 1] = 0;
08428 
08429         return in;
08430     }
08431 
08432 
08433     int CyaSSL_X509_get_signature_type(CYASSL_X509* x509)
08434     {
08435         int type = 0;
08436 
08437         CYASSL_ENTER("CyaSSL_X509_get_signature_type");
08438 
08439         if (x509 != NULL)
08440             type = x509->sigOID;
08441 
08442         return type;
08443     }
08444 
08445 
08446     int CyaSSL_X509_get_signature(CYASSL_X509* x509,
08447                                                  unsigned char* buf, int* bufSz)
08448     {
08449         CYASSL_ENTER("CyaSSL_X509_get_signature");
08450         if (x509 == NULL || bufSz == NULL || *bufSz < (int)x509->sig.length)
08451             return SSL_FATAL_ERROR;
08452 
08453         if (buf != NULL)
08454             XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
08455         *bufSz = x509->sig.length;
08456 
08457         return SSL_SUCCESS;
08458     }
08459 
08460 
08461     /* write X509 serial number in unsigned binary to buffer
08462        buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
08463        return SSL_SUCCESS on success */
08464     int CyaSSL_X509_get_serial_number(CYASSL_X509* x509, byte* in, int* inOutSz)
08465     {
08466         CYASSL_ENTER("CyaSSL_X509_get_serial_number");
08467         if (x509 == NULL || in == NULL ||
08468                                    inOutSz == NULL || *inOutSz < x509->serialSz)
08469             return BAD_FUNC_ARG;
08470 
08471         XMEMCPY(in, x509->serial, x509->serialSz);
08472         *inOutSz = x509->serialSz;
08473 
08474         return SSL_SUCCESS;
08475     }
08476 
08477 
08478     const byte* CyaSSL_X509_get_der(CYASSL_X509* x509, int* outSz)
08479     {
08480         CYASSL_ENTER("CyaSSL_X509_get_der");
08481 
08482         if (x509 == NULL || outSz == NULL)
08483             return NULL;
08484 
08485         *outSz = (int)x509->derCert.length;
08486         return x509->derCert.buffer;
08487     }
08488 
08489 
08490     int CyaSSL_X509_version(CYASSL_X509* x509)
08491     {
08492         CYASSL_ENTER("CyaSSL_X509_version");
08493 
08494         if (x509 == NULL)
08495             return 0;
08496 
08497         return x509->version;
08498     }
08499 
08500 
08501     const byte* CyaSSL_X509_notBefore(CYASSL_X509* x509)
08502     {
08503         CYASSL_ENTER("CyaSSL_X509_notBefore");
08504 
08505         if (x509 == NULL)
08506             return NULL;
08507 
08508         return x509->notBefore;
08509     }
08510 
08511 
08512     const byte* CyaSSL_X509_notAfter(CYASSL_X509* x509)
08513     {
08514         CYASSL_ENTER("CyaSSL_X509_notAfter");
08515 
08516         if (x509 == NULL)
08517             return NULL;
08518 
08519         return x509->notAfter;
08520     }
08521 
08522 
08523 #ifdef CYASSL_SEP
08524 
08525 /* copy oid into in buffer, at most *inOutSz bytes, if buffer is null will
08526    malloc buffer, call responsible for freeing. Actual size returned in
08527    *inOutSz. Requires inOutSz be non-null */
08528 byte* CyaSSL_X509_get_device_type(CYASSL_X509* x509, byte* in, int *inOutSz)
08529 {
08530     int copySz;
08531 
08532     CYASSL_ENTER("CyaSSL_X509_get_dev_type");
08533     if (inOutSz == NULL) return NULL;
08534     if (!x509->deviceTypeSz) return in;
08535 
08536     copySz = min(*inOutSz, x509->deviceTypeSz);
08537 
08538     if (!in) {
08539         in = (byte*)XMALLOC(x509->deviceTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
08540         if (!in) return in;
08541         copySz = x509->deviceTypeSz;
08542     }
08543 
08544     XMEMCPY(in, x509->deviceType, copySz);
08545     *inOutSz = copySz;
08546 
08547     return in;
08548 }
08549 
08550 
08551 byte* CyaSSL_X509_get_hw_type(CYASSL_X509* x509, byte* in, int* inOutSz)
08552 {
08553     int copySz;
08554 
08555     CYASSL_ENTER("CyaSSL_X509_get_hw_type");
08556     if (inOutSz == NULL) return NULL;
08557     if (!x509->hwTypeSz) return in;
08558 
08559     copySz = min(*inOutSz, x509->hwTypeSz);
08560 
08561     if (!in) {
08562         in = (byte*)XMALLOC(x509->hwTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
08563         if (!in) return in;
08564         copySz = x509->hwTypeSz;
08565     }
08566 
08567     XMEMCPY(in, x509->hwType, copySz);
08568     *inOutSz = copySz;
08569 
08570     return in;
08571 }
08572 
08573 
08574 byte* CyaSSL_X509_get_hw_serial_number(CYASSL_X509* x509,byte* in,int* inOutSz)
08575 {
08576     int copySz;
08577 
08578     CYASSL_ENTER("CyaSSL_X509_get_hw_serial_number");
08579     if (inOutSz == NULL) return NULL;
08580     if (!x509->hwTypeSz) return in;
08581 
08582     copySz = min(*inOutSz, x509->hwSerialNumSz);
08583 
08584     if (!in) {
08585         in = (byte*)XMALLOC(x509->hwSerialNumSz, 0, DYNAMIC_TYPE_OPENSSL);
08586         if (!in) return in;
08587         copySz = x509->hwSerialNumSz;
08588     }
08589 
08590     XMEMCPY(in, x509->hwSerialNum, copySz);
08591     *inOutSz = copySz;
08592 
08593     return in;
08594 }
08595 
08596 #endif /* CYASSL_SEP */
08597 
08598 
08599 CYASSL_X509* CyaSSL_X509_d2i(CYASSL_X509** x509, const byte* in, int len)
08600 {
08601     CYASSL_X509 *newX509 = NULL;
08602 
08603     CYASSL_ENTER("CyaSSL_X509_d2i");
08604 
08605     if (in != NULL && len != 0) {
08606     #ifdef CYASSL_SMALL_STACK
08607         DecodedCert* cert = NULL;
08608     #else
08609         DecodedCert  cert[1];
08610     #endif
08611 
08612     #ifdef CYASSL_SMALL_STACK
08613         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
08614                                                        DYNAMIC_TYPE_TMP_BUFFER);
08615         if (cert == NULL)
08616             return NULL;
08617     #endif
08618 
08619         InitDecodedCert(cert, (byte*)in, len, NULL);
08620         if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
08621             newX509 = (CYASSL_X509*)XMALLOC(sizeof(CYASSL_X509),
08622                                                        NULL, DYNAMIC_TYPE_X509);
08623             if (newX509 != NULL) {
08624                 InitX509(newX509, 1);
08625                 if (CopyDecodedToX509(newX509, cert) != 0) {
08626                     XFREE(newX509, NULL, DYNAMIC_TYPE_X509);
08627                     newX509 = NULL;
08628                 }
08629             }
08630         }
08631         FreeDecodedCert(cert);
08632     #ifdef CYASSL_SMALL_STACK
08633         XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08634     #endif
08635     }
08636 
08637     if (x509 != NULL)
08638         *x509 = newX509;
08639 
08640     return newX509;
08641 }
08642 
08643 
08644 #ifndef NO_FILESYSTEM
08645 
08646 #ifndef NO_STDIO_FILESYSTEM
08647 
08648 CYASSL_X509* CyaSSL_X509_d2i_fp(CYASSL_X509** x509, XFILE file)
08649 {
08650     CYASSL_X509* newX509 = NULL;
08651 
08652     CYASSL_ENTER("CyaSSL_X509_d2i_fp");
08653 
08654     if (file != XBADFILE) {
08655         byte* fileBuffer = NULL;
08656         long sz = 0;
08657 
08658         XFSEEK(file, 0, XSEEK_END);
08659         sz = XFTELL(file);
08660         XREWIND(file);
08661 
08662         if (sz < 0) {
08663             CYASSL_MSG("Bad tell on FILE");
08664             return NULL;
08665         }
08666 
08667         fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
08668         if (fileBuffer != NULL) {
08669             int ret = (int)XFREAD(fileBuffer, sz, 1, file);
08670             if (ret > 0) {
08671                 newX509 = CyaSSL_X509_d2i(NULL, fileBuffer, (int)sz);
08672             }
08673             XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
08674         }
08675     }
08676 
08677     if (x509 != NULL)
08678         *x509 = newX509;
08679 
08680     return newX509;
08681 }
08682 
08683 #endif /* NO_STDIO_FILESYSTEM */
08684 
08685 CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format)
08686 {
08687 #ifdef CYASSL_SMALL_STACK
08688     byte  staticBuffer[1]; /* force heap usage */
08689 #else
08690     byte  staticBuffer[FILE_BUFFER_SIZE];
08691 #endif
08692     byte* fileBuffer = staticBuffer;
08693     int   dynamic = 0;
08694     int   ret;
08695     long  sz = 0;
08696     XFILE file;
08697 
08698     CYASSL_X509* x509 = NULL;
08699     buffer der;
08700 
08701     CYASSL_ENTER("CyaSSL_X509_load_certificate");
08702 
08703     /* Check the inputs */
08704     if ((fname == NULL) ||
08705         (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM))
08706         return NULL;
08707 
08708     file = XFOPEN(fname, "rb");
08709     if (file == XBADFILE)
08710         return NULL;
08711 
08712     XFSEEK(file, 0, XSEEK_END);
08713     sz = XFTELL(file);
08714     XREWIND(file);
08715 
08716     if (sz > (long)sizeof(staticBuffer)) {
08717         fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
08718         if (fileBuffer == NULL) {
08719             XFCLOSE(file);
08720             return NULL;
08721         }
08722         dynamic = 1;
08723     }
08724     else if (sz < 0) {
08725         XFCLOSE(file);
08726         return NULL;
08727     }
08728 
08729     ret = (int)XFREAD(fileBuffer, sz, 1, file);
08730     if (ret < 0) {
08731         XFCLOSE(file);
08732         if (dynamic)
08733             XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
08734         return NULL;
08735     }
08736 
08737     XFCLOSE(file);
08738 
08739     der.buffer = NULL;
08740     der.length = 0;
08741 
08742     if (format == SSL_FILETYPE_PEM) {
08743         int ecc = 0;
08744     #ifdef CYASSL_SMALL_STACK
08745         EncryptedInfo* info = NULL;
08746     #else
08747         EncryptedInfo  info[1];
08748     #endif
08749 
08750     #ifdef CYASSL_SMALL_STACK
08751         info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
08752                                                        DYNAMIC_TYPE_TMP_BUFFER);
08753         if (info == NULL) {
08754             if (dynamic)
08755                 XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
08756 
08757             return NULL;
08758         }
08759     #endif
08760 
08761         info->set = 0;
08762         info->ctx = NULL;
08763         info->consumed = 0;
08764 
08765         if (PemToDer(fileBuffer, sz, CERT_TYPE, &der, NULL, info, &ecc) != 0)
08766         {
08767             /* Only time this should fail, and leave `der` with a buffer
08768                is when the Base64 Decode fails. Release `der.buffer` in
08769                that case. */
08770             if (der.buffer != NULL) {
08771                 XFREE(der.buffer, NULL, DYNAMIC_TYPE_CERT);
08772                 der.buffer = NULL;
08773             }
08774         }
08775 
08776     #ifdef CYASSL_SMALL_STACK
08777         XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08778     #endif
08779     }
08780     else {
08781         der.buffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_CERT);
08782         if (der.buffer != NULL) {
08783             XMEMCPY(der.buffer, fileBuffer, sz);
08784             der.length = (word32)sz;
08785         }
08786     }
08787 
08788     if (dynamic)
08789         XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
08790 
08791     /* At this point we want `der` to have the certificate in DER format */
08792     /* ready to be decoded. */
08793     if (der.buffer != NULL) {
08794     #ifdef CYASSL_SMALL_STACK
08795         DecodedCert* cert = NULL;
08796     #else
08797         DecodedCert  cert[1];
08798     #endif
08799 
08800     #ifdef CYASSL_SMALL_STACK
08801         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
08802                                                        DYNAMIC_TYPE_TMP_BUFFER);
08803         if (cert != NULL)
08804     #endif
08805         {
08806             InitDecodedCert(cert, der.buffer, der.length, NULL);
08807             if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
08808                 x509 = (CYASSL_X509*)XMALLOC(sizeof(CYASSL_X509), NULL,
08809                                                              DYNAMIC_TYPE_X509);
08810                 if (x509 != NULL) {
08811                     InitX509(x509, 1);
08812                     if (CopyDecodedToX509(x509, cert) != 0) {
08813                         XFREE(x509, NULL, DYNAMIC_TYPE_X509);
08814                         x509 = NULL;
08815                     }
08816                 }
08817             }
08818 
08819             FreeDecodedCert(cert);
08820         #ifdef CYASSL_SMALL_STACK
08821             XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08822         #endif
08823         }
08824 
08825         XFREE(der.buffer, NULL, DYNAMIC_TYPE_CERT);
08826     }
08827 
08828     return x509;
08829 }
08830 
08831 #endif /* NO_FILESYSTEM */
08832 
08833 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
08834 
08835 
08836 #ifdef OPENSSL_EXTRA
08837 int CyaSSL_set_ex_data(CYASSL* ssl, int idx, void* data)
08838 {
08839 #ifdef FORTRESS
08840     if (ssl != NULL && idx < MAX_EX_DATA)
08841     {
08842         ssl->ex_data[idx] = data;
08843         return SSL_SUCCESS;
08844     }
08845 #else
08846     (void)ssl;
08847     (void)idx;
08848     (void)data;
08849 #endif
08850     return SSL_FAILURE;
08851 }
08852 
08853 
08854 int CyaSSL_set_session_id_context(CYASSL* ssl, const unsigned char* id,
08855                                unsigned int len)
08856 {
08857     (void)ssl;
08858     (void)id;
08859     (void)len;
08860     return 0;
08861 }
08862 
08863 
08864 void CyaSSL_set_connect_state(CYASSL* ssl)
08865 {
08866     (void)ssl;
08867     /* client by default */
08868 }
08869 #endif
08870 
08871 int CyaSSL_get_shutdown(const CYASSL* ssl)
08872 {
08873     return (ssl->options.isClosed  ||
08874             ssl->options.connReset ||
08875             ssl->options.sentNotify);
08876 }
08877 
08878 
08879 int CyaSSL_session_reused(CYASSL* ssl)
08880 {
08881     return ssl->options.resuming;
08882 }
08883 
08884 #ifdef OPENSSL_EXTRA
08885 void CyaSSL_SESSION_free(CYASSL_SESSION* session)
08886 {
08887     (void)session;
08888 }
08889 #endif
08890 
08891 const char* CyaSSL_get_version(CYASSL* ssl)
08892 {
08893     CYASSL_ENTER("SSL_get_version");
08894     if (ssl->version.major == SSLv3_MAJOR) {
08895         switch (ssl->version.minor) {
08896             case SSLv3_MINOR :
08897                 return "SSLv3";
08898             case TLSv1_MINOR :
08899                 return "TLSv1";
08900             case TLSv1_1_MINOR :
08901                 return "TLSv1.1";
08902             case TLSv1_2_MINOR :
08903                 return "TLSv1.2";
08904             default:
08905                 return "unknown";
08906         }
08907     }
08908     else if (ssl->version.major == DTLS_MAJOR) {
08909         switch (ssl->version.minor) {
08910             case DTLS_MINOR :
08911                 return "DTLS";
08912             case DTLSv1_2_MINOR :
08913                 return "DTLSv1.2";
08914             default:
08915                 return "unknown";
08916         }
08917     }
08918     return "unknown";
08919 }
08920 
08921 int CyaSSL_get_current_cipher_suite(CYASSL* ssl)
08922 {
08923     CYASSL_ENTER("SSL_get_current_cipher_suite");
08924     if (ssl)
08925         return (ssl->options.cipherSuite0 << 8) | ssl->options.cipherSuite;
08926     return 0;
08927 }
08928 
08929 CYASSL_CIPHER* CyaSSL_get_current_cipher(CYASSL* ssl)
08930 {
08931     CYASSL_ENTER("SSL_get_current_cipher");
08932     if (ssl)
08933         return &ssl->cipher;
08934     else
08935         return NULL;
08936 }
08937 
08938 
08939 const char* CyaSSL_CIPHER_get_name(const CYASSL_CIPHER* cipher)
08940 {
08941     (void)cipher;
08942 
08943     CYASSL_ENTER("SSL_CIPHER_get_name");
08944 #ifndef NO_ERROR_STRINGS
08945     if (cipher) {
08946 #if defined(HAVE_CHACHA)
08947         if (cipher->ssl->options.cipherSuite0 == CHACHA_BYTE) {
08948         /* ChaCha suites */
08949         switch (cipher->ssl->options.cipherSuite) {
08950 #ifdef HAVE_CHACHA
08951 #ifndef NO_RSA
08952             case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
08953                 return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
08954 
08955             case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
08956                 return "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
08957 #endif
08958             case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
08959                 return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
08960 #endif
08961             }
08962         }
08963 #endif
08964 
08965 #if defined(HAVE_ECC) || defined(HAVE_AESCCM)
08966         /* Awkwardly, the ECC cipher suites use the ECC_BYTE as expected,
08967          * but the AES-CCM cipher suites also use it, even the ones that
08968          * aren't ECC. */
08969         if (cipher->ssl->options.cipherSuite0 == ECC_BYTE) {
08970         /* ECC suites */
08971         switch (cipher->ssl->options.cipherSuite) {
08972 #ifdef HAVE_ECC
08973 #ifndef NO_RSA
08974             case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
08975                 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
08976 #endif
08977             case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
08978                 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
08979 #ifndef NO_RSA
08980             case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
08981                 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
08982 #endif
08983             case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
08984                 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
08985 #ifndef NO_RSA
08986             case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
08987                 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
08988 #endif
08989             case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
08990                 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
08991 #ifndef NO_RSA
08992             case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
08993                 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
08994 #endif
08995             case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
08996                 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
08997 #ifndef NO_SHA
08998 #ifndef NO_RSA
08999             case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
09000                 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
09001             case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
09002                 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
09003 #endif
09004             case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
09005                 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
09006             case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
09007                 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
09008 #ifndef NO_RC4
09009     #ifndef NO_RSA
09010             case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
09011                 return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
09012     #endif
09013             case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
09014                 return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
09015 #endif
09016 #ifndef NO_DES3
09017     #ifndef NO_RSA
09018             case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
09019                 return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
09020     #endif
09021             case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
09022                 return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
09023 #endif
09024 
09025 #ifndef NO_RSA
09026             case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
09027                 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
09028             case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
09029                 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
09030 #endif
09031             case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
09032                 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
09033             case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
09034                 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
09035 #ifndef NO_RC4
09036     #ifndef NO_RSA
09037             case TLS_ECDH_RSA_WITH_RC4_128_SHA :
09038                 return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
09039     #endif
09040             case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
09041                 return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
09042 #endif
09043 #ifndef NO_DES3
09044     #ifndef NO_RSA
09045             case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
09046                 return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
09047     #endif
09048             case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
09049                 return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
09050 #endif
09051 #endif /* NO_SHA */
09052 
09053 #ifdef HAVE_AESGCM
09054 #ifndef NO_RSA
09055             case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
09056                 return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
09057             case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
09058                 return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
09059 #endif
09060             case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
09061                 return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
09062             case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
09063                 return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
09064 #ifndef NO_RSA
09065             case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
09066                 return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
09067             case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
09068                 return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
09069 #endif
09070             case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
09071                 return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
09072             case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
09073                 return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
09074 #endif
09075 #endif /* HAVE_ECC */
09076 
09077 #ifdef HAVE_AESCCM
09078 #ifndef NO_RSA
09079             case TLS_RSA_WITH_AES_128_CCM_8 :
09080                 return "TLS_RSA_WITH_AES_128_CCM_8";
09081             case TLS_RSA_WITH_AES_256_CCM_8 :
09082                 return "TLS_RSA_WITH_AES_256_CCM_8";
09083 #endif
09084 #ifndef NO_PSK
09085             case TLS_PSK_WITH_AES_128_CCM_8 :
09086                 return "TLS_PSK_WITH_AES_128_CCM_8";
09087             case TLS_PSK_WITH_AES_256_CCM_8 :
09088                 return "TLS_PSK_WITH_AES_256_CCM_8";
09089             case TLS_PSK_WITH_AES_128_CCM :
09090                 return "TLS_PSK_WITH_AES_128_CCM";
09091             case TLS_PSK_WITH_AES_256_CCM :
09092                 return "TLS_PSK_WITH_AES_256_CCM";
09093             case TLS_DHE_PSK_WITH_AES_128_CCM :
09094                 return "TLS_DHE_PSK_WITH_AES_128_CCM";
09095             case TLS_DHE_PSK_WITH_AES_256_CCM :
09096                 return "TLS_DHE_PSK_WITH_AES_256_CCM";
09097 #endif
09098 #ifdef HAVE_ECC
09099             case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
09100                 return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8";
09101             case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
09102                 return "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8";
09103 #endif
09104 #endif
09105 
09106             default:
09107                 return "NONE";
09108         }
09109         }
09110 #endif  /* ECC */
09111         if (cipher->ssl->options.cipherSuite0 != ECC_BYTE &&
09112             cipher->ssl->options.cipherSuite0 != CHACHA_BYTE) {
09113 
09114             /* normal suites */
09115         switch (cipher->ssl->options.cipherSuite) {
09116 #ifndef NO_RSA
09117 #ifndef NO_RC4
09118     #ifndef NO_SHA
09119             case SSL_RSA_WITH_RC4_128_SHA :
09120                 return "SSL_RSA_WITH_RC4_128_SHA";
09121     #endif
09122     #ifndef NO_MD5
09123             case SSL_RSA_WITH_RC4_128_MD5 :
09124                 return "SSL_RSA_WITH_RC4_128_MD5";
09125     #endif
09126 #endif
09127 #ifndef NO_SHA
09128     #ifndef NO_DES3
09129             case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
09130                 return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
09131     #endif
09132             case TLS_RSA_WITH_AES_128_CBC_SHA :
09133                 return "TLS_RSA_WITH_AES_128_CBC_SHA";
09134             case TLS_RSA_WITH_AES_256_CBC_SHA :
09135                 return "TLS_RSA_WITH_AES_256_CBC_SHA";
09136 #endif
09137             case TLS_RSA_WITH_AES_128_CBC_SHA256 :
09138                 return "TLS_RSA_WITH_AES_128_CBC_SHA256";
09139             case TLS_RSA_WITH_AES_256_CBC_SHA256 :
09140                 return "TLS_RSA_WITH_AES_256_CBC_SHA256";
09141     #ifdef HAVE_BLAKE2
09142             case TLS_RSA_WITH_AES_128_CBC_B2B256:
09143                 return "TLS_RSA_WITH_AES_128_CBC_B2B256";
09144             case TLS_RSA_WITH_AES_256_CBC_B2B256:
09145                 return "TLS_RSA_WITH_AES_256_CBC_B2B256";
09146     #endif
09147 #ifndef NO_SHA
09148             case TLS_RSA_WITH_NULL_SHA :
09149                 return "TLS_RSA_WITH_NULL_SHA";
09150 #endif
09151             case TLS_RSA_WITH_NULL_SHA256 :
09152                 return "TLS_RSA_WITH_NULL_SHA256";
09153 #endif /* NO_RSA */
09154 #ifndef NO_PSK
09155 #ifndef NO_SHA
09156             case TLS_PSK_WITH_AES_128_CBC_SHA :
09157                 return "TLS_PSK_WITH_AES_128_CBC_SHA";
09158             case TLS_PSK_WITH_AES_256_CBC_SHA :
09159                 return "TLS_PSK_WITH_AES_256_CBC_SHA";
09160 #endif
09161 #ifndef NO_SHA256
09162             case TLS_PSK_WITH_AES_128_CBC_SHA256 :
09163                 return "TLS_PSK_WITH_AES_128_CBC_SHA256";
09164             case TLS_PSK_WITH_NULL_SHA256 :
09165                 return "TLS_PSK_WITH_NULL_SHA256";
09166             case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 :
09167                 return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
09168             case TLS_DHE_PSK_WITH_NULL_SHA256 :
09169                 return "TLS_DHE_PSK_WITH_NULL_SHA256";
09170     #ifdef HAVE_AESGCM
09171             case TLS_PSK_WITH_AES_128_GCM_SHA256 :
09172                 return "TLS_PSK_WITH_AES_128_GCM_SHA256";
09173             case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 :
09174                 return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
09175     #endif
09176 #endif
09177 #ifdef CYASSL_SHA384
09178             case TLS_PSK_WITH_AES_256_CBC_SHA384 :
09179                 return "TLS_PSK_WITH_AES_256_CBC_SHA384";
09180             case TLS_PSK_WITH_NULL_SHA384 :
09181                 return "TLS_PSK_WITH_NULL_SHA384";
09182             case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 :
09183                 return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
09184             case TLS_DHE_PSK_WITH_NULL_SHA384 :
09185                 return "TLS_DHE_PSK_WITH_NULL_SHA384";
09186     #ifdef HAVE_AESGCM
09187             case TLS_PSK_WITH_AES_256_GCM_SHA384 :
09188                 return "TLS_PSK_WITH_AES_256_GCM_SHA384";
09189             case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 :
09190                 return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
09191     #endif
09192 #endif
09193 #ifndef NO_SHA
09194             case TLS_PSK_WITH_NULL_SHA :
09195                 return "TLS_PSK_WITH_NULL_SHA";
09196 #endif
09197 #endif /* NO_PSK */
09198 #ifndef NO_RSA
09199             case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
09200                 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
09201             case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
09202                 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
09203 #ifndef NO_SHA
09204             case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
09205                 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
09206             case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
09207                 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
09208 #endif
09209 #ifndef NO_HC128
09210     #ifndef NO_MD5
09211             case TLS_RSA_WITH_HC_128_MD5 :
09212                 return "TLS_RSA_WITH_HC_128_MD5";
09213     #endif
09214     #ifndef NO_SHA
09215             case TLS_RSA_WITH_HC_128_SHA :
09216                 return "TLS_RSA_WITH_HC_128_SHA";
09217     #endif
09218     #ifdef HAVE_BLAKE2
09219             case TLS_RSA_WITH_HC_128_B2B256:
09220                 return "TLS_RSA_WITH_HC_128_B2B256";
09221     #endif
09222 #endif /* NO_HC128 */
09223 #ifndef NO_SHA
09224     #ifndef NO_RABBIT
09225             case TLS_RSA_WITH_RABBIT_SHA :
09226                 return "TLS_RSA_WITH_RABBIT_SHA";
09227     #endif
09228     #ifdef HAVE_NTRU
09229         #ifndef NO_RC4
09230             case TLS_NTRU_RSA_WITH_RC4_128_SHA :
09231                 return "TLS_NTRU_RSA_WITH_RC4_128_SHA";
09232         #endif
09233         #ifndef NO_DES3
09234             case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
09235                 return "TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA";
09236         #endif
09237             case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
09238                 return "TLS_NTRU_RSA_WITH_AES_128_CBC_SHA";
09239             case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
09240                 return "TLS_NTRU_RSA_WITH_AES_256_CBC_SHA";
09241     #endif /* HAVE_NTRU */
09242 #endif /* NO_SHA */
09243             case TLS_RSA_WITH_AES_128_GCM_SHA256 :
09244                 return "TLS_RSA_WITH_AES_128_GCM_SHA256";
09245             case TLS_RSA_WITH_AES_256_GCM_SHA384 :
09246                 return "TLS_RSA_WITH_AES_256_GCM_SHA384";
09247             case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
09248                 return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
09249             case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
09250                 return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
09251 #ifndef NO_SHA
09252             case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
09253                 return "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA";
09254             case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
09255                 return "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA";
09256 #endif
09257             case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
09258                 return "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256";
09259             case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
09260                 return "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256";
09261 #ifndef NO_SHA
09262             case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
09263                 return "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA";
09264             case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
09265                 return "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA";
09266 #endif
09267             case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
09268                 return "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256";
09269             case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
09270                 return "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256";
09271 #endif /* NO_RSA */
09272 #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
09273             case TLS_DH_anon_WITH_AES_128_CBC_SHA :
09274                 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
09275 #endif
09276             default:
09277                 return "NONE";
09278         }  /* switch */
09279         }  /* normal / ECC */
09280     }
09281 #endif /* NO_ERROR_STRINGS */
09282     return "NONE";
09283 }
09284 
09285 
09286 const char* CyaSSL_get_cipher(CYASSL* ssl)
09287 {
09288     CYASSL_ENTER("CyaSSL_get_cipher");
09289     return CyaSSL_CIPHER_get_name(CyaSSL_get_current_cipher(ssl));
09290 }
09291 
09292 #ifdef OPENSSL_EXTRA
09293 
09294 
09295 
09296 char* CyaSSL_CIPHER_description(CYASSL_CIPHER* cipher, char* in, int len)
09297 {
09298     (void)cipher;
09299     (void)in;
09300     (void)len;
09301     return 0;
09302 }
09303 
09304 
09305 CYASSL_SESSION* CyaSSL_get1_session(CYASSL* ssl)  /* what's ref count */
09306 {
09307     (void)ssl;
09308     return 0;
09309 }
09310 
09311 
09312 void CyaSSL_X509_free(CYASSL_X509* buf)
09313 {
09314     (void)buf;
09315 }
09316 
09317 
09318 /* was do nothing */
09319 /*
09320 void OPENSSL_free(void* buf)
09321 {
09322     (void)buf;
09323 }
09324 */
09325 
09326 
09327 int CyaSSL_OCSP_parse_url(char* url, char** host, char** port, char** path,
09328                    int* ssl)
09329 {
09330     (void)url;
09331     (void)host;
09332     (void)port;
09333     (void)path;
09334     (void)ssl;
09335     return 0;
09336 }
09337 
09338 
09339 CYASSL_METHOD* CyaSSLv2_client_method(void)
09340 {
09341     return 0;
09342 }
09343 
09344 
09345 CYASSL_METHOD* CyaSSLv2_server_method(void)
09346 {
09347     return 0;
09348 }
09349 
09350 
09351 #ifndef NO_MD4
09352 
09353 void CyaSSL_MD4_Init(CYASSL_MD4_CTX* md4)
09354 {
09355     /* make sure we have a big enough buffer */
09356     typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1];
09357     (void) sizeof(ok);
09358 
09359     CYASSL_ENTER("MD4_Init");
09360     InitMd4((Md4*)md4);
09361 }
09362 
09363 
09364 void CyaSSL_MD4_Update(CYASSL_MD4_CTX* md4, const void* data,
09365                        unsigned long len)
09366 {
09367     CYASSL_ENTER("MD4_Update");
09368     Md4Update((Md4*)md4, (const byte*)data, (word32)len);
09369 }
09370 
09371 
09372 void CyaSSL_MD4_Final(unsigned char* digest, CYASSL_MD4_CTX* md4)
09373 {
09374     CYASSL_ENTER("MD4_Final");
09375     Md4Final((Md4*)md4, digest);
09376 }
09377 
09378 #endif /* NO_MD4 */
09379 
09380 
09381 CYASSL_BIO* CyaSSL_BIO_pop(CYASSL_BIO* top)
09382 {
09383     (void)top;
09384     return 0;
09385 }
09386 
09387 
09388 int CyaSSL_BIO_pending(CYASSL_BIO* bio)
09389 {
09390     (void)bio;
09391     return 0;
09392 }
09393 
09394 
09395 
09396 CYASSL_BIO_METHOD* CyaSSL_BIO_s_mem(void)
09397 {
09398     static CYASSL_BIO_METHOD meth;
09399 
09400     CYASSL_ENTER("BIO_s_mem");
09401     meth.type = BIO_MEMORY;
09402 
09403     return &meth;
09404 }
09405 
09406 
09407 CYASSL_BIO_METHOD* CyaSSL_BIO_f_base64(void)
09408 {
09409     return 0;
09410 }
09411 
09412 
09413 void CyaSSL_BIO_set_flags(CYASSL_BIO* bio, int flags)
09414 {
09415     (void)bio;
09416     (void)flags;
09417 }
09418 
09419 
09420 
09421 void CyaSSL_RAND_screen(void)
09422 {
09423 
09424 }
09425 
09426 
09427 const char* CyaSSL_RAND_file_name(char* fname, unsigned long len)
09428 {
09429     (void)fname;
09430     (void)len;
09431     return 0;
09432 }
09433 
09434 
09435 int CyaSSL_RAND_write_file(const char* fname)
09436 {
09437     (void)fname;
09438     return 0;
09439 }
09440 
09441 
09442 int CyaSSL_RAND_load_file(const char* fname, long len)
09443 {
09444     (void)fname;
09445     /* CTaoCrypt provides enough entropy internally or will report error */
09446     if (len == -1)
09447         return 1024;
09448     else
09449         return (int)len;
09450 }
09451 
09452 
09453 int CyaSSL_RAND_egd(const char* path)
09454 {
09455     (void)path;
09456     return 0;
09457 }
09458 
09459 
09460 
09461 CYASSL_COMP_METHOD* CyaSSL_COMP_zlib(void)
09462 {
09463     return 0;
09464 }
09465 
09466 
09467 CYASSL_COMP_METHOD* CyaSSL_COMP_rle(void)
09468 {
09469     return 0;
09470 }
09471 
09472 
09473 int CyaSSL_COMP_add_compression_method(int method, void* data)
09474 {
09475     (void)method;
09476     (void)data;
09477     return 0;
09478 }
09479 
09480 
09481 
09482 int CyaSSL_get_ex_new_index(long idx, void* data, void* cb1, void* cb2,
09483                          void* cb3)
09484 {
09485     (void)idx;
09486     (void)data;
09487     (void)cb1;
09488     (void)cb2;
09489     (void)cb3;
09490     return 0;
09491 }
09492 
09493 
09494 void CyaSSL_set_dynlock_create_callback(CYASSL_dynlock_value* (*f)(
09495                                                           const char*, int))
09496 {
09497     (void)f;
09498 }
09499 
09500 
09501 void CyaSSL_set_dynlock_lock_callback(
09502              void (*f)(int, CYASSL_dynlock_value*, const char*, int))
09503 {
09504     (void)f;
09505 }
09506 
09507 
09508 void CyaSSL_set_dynlock_destroy_callback(
09509                   void (*f)(CYASSL_dynlock_value*, const char*, int))
09510 {
09511     (void)f;
09512 }
09513 
09514 
09515 
09516 const char* CyaSSL_X509_verify_cert_error_string(long err)
09517 {
09518     (void)err;
09519     return 0;
09520 }
09521 
09522 
09523 
09524 int CyaSSL_X509_LOOKUP_add_dir(CYASSL_X509_LOOKUP* lookup, const char* dir,
09525                                long len)
09526 {
09527     (void)lookup;
09528     (void)dir;
09529     (void)len;
09530     return 0;
09531 }
09532 
09533 
09534 int CyaSSL_X509_LOOKUP_load_file(CYASSL_X509_LOOKUP* lookup,
09535                                  const char* file, long len)
09536 {
09537     (void)lookup;
09538     (void)file;
09539     (void)len;
09540     return 0;
09541 }
09542 
09543 
09544 CYASSL_X509_LOOKUP_METHOD* CyaSSL_X509_LOOKUP_hash_dir(void)
09545 {
09546     return 0;
09547 }
09548 
09549 
09550 CYASSL_X509_LOOKUP_METHOD* CyaSSL_X509_LOOKUP_file(void)
09551 {
09552     return 0;
09553 }
09554 
09555 
09556 
09557 CYASSL_X509_LOOKUP* CyaSSL_X509_STORE_add_lookup(CYASSL_X509_STORE* store,
09558                                                CYASSL_X509_LOOKUP_METHOD* m)
09559 {
09560     (void)store;
09561     (void)m;
09562     return 0;
09563 }
09564 
09565 
09566 int CyaSSL_X509_STORE_add_cert(CYASSL_X509_STORE* store, CYASSL_X509* x509)
09567 {
09568     int result = SSL_FATAL_ERROR;
09569 
09570     CYASSL_ENTER("CyaSSL_X509_STORE_add_cert");
09571     if (store != NULL && store->cm != NULL && x509 != NULL) {
09572         buffer derCert;
09573         derCert.buffer = (byte*)XMALLOC(x509->derCert.length,
09574                                                    NULL, DYNAMIC_TYPE_CERT);
09575         if (derCert.buffer != NULL) {
09576             derCert.length = x509->derCert.length;
09577                 /* AddCA() frees the buffer. */
09578             XMEMCPY(derCert.buffer,
09579                                 x509->derCert.buffer, x509->derCert.length);
09580             result = AddCA(store->cm, derCert, CYASSL_USER_CA, 1);
09581             if (result != SSL_SUCCESS) result = SSL_FATAL_ERROR;
09582         }
09583     }
09584 
09585     CYASSL_LEAVE("CyaSSL_X509_STORE_add_cert", result);
09586     return result;
09587 }
09588 
09589 
09590 CYASSL_X509_STORE* CyaSSL_X509_STORE_new(void)
09591 {
09592     CYASSL_X509_STORE* store = NULL;
09593 
09594     store = (CYASSL_X509_STORE*)XMALLOC(sizeof(CYASSL_X509_STORE), NULL, 0);
09595     if (store != NULL) {
09596         store->cm = CyaSSL_CertManagerNew();
09597         if (store->cm == NULL) {
09598             XFREE(store, NULL, 0);
09599             store = NULL;
09600         }
09601     }
09602 
09603     return store;
09604 }
09605 
09606 
09607 void CyaSSL_X509_STORE_free(CYASSL_X509_STORE* store)
09608 {
09609     if (store != NULL) {
09610         if (store->cm != NULL)
09611         CyaSSL_CertManagerFree(store->cm);
09612         XFREE(store, NULL, 0);
09613     }
09614 }
09615 
09616 
09617 int CyaSSL_X509_STORE_set_default_paths(CYASSL_X509_STORE* store)
09618 {
09619     (void)store;
09620     return SSL_SUCCESS;
09621 }
09622 
09623 
09624 int CyaSSL_X509_STORE_get_by_subject(CYASSL_X509_STORE_CTX* ctx, int idx,
09625                             CYASSL_X509_NAME* name, CYASSL_X509_OBJECT* obj)
09626 {
09627     (void)ctx;
09628     (void)idx;
09629     (void)name;
09630     (void)obj;
09631     return 0;
09632 }
09633 
09634 
09635 CYASSL_X509_STORE_CTX* CyaSSL_X509_STORE_CTX_new(void)
09636 {
09637     CYASSL_X509_STORE_CTX* ctx = (CYASSL_X509_STORE_CTX*)XMALLOC(
09638                                     sizeof(CYASSL_X509_STORE_CTX), NULL, 0);
09639 
09640     if (ctx != NULL)
09641         CyaSSL_X509_STORE_CTX_init(ctx, NULL, NULL, NULL);
09642 
09643     return ctx;
09644 }
09645 
09646 
09647 int CyaSSL_X509_STORE_CTX_init(CYASSL_X509_STORE_CTX* ctx,
09648      CYASSL_X509_STORE* store, CYASSL_X509* x509, STACK_OF(CYASSL_X509)* sk)
09649 {
09650     (void)sk;
09651     if (ctx != NULL) {
09652         ctx->store = store;
09653         ctx->current_cert = x509;
09654         ctx->domain = NULL;
09655         ctx->ex_data = NULL;
09656         ctx->userCtx = NULL;
09657         ctx->error = 0;
09658         ctx->error_depth = 0;
09659         ctx->discardSessionCerts = 0;
09660         return SSL_SUCCESS;
09661     }
09662     return SSL_FATAL_ERROR;
09663 }
09664 
09665 
09666 void CyaSSL_X509_STORE_CTX_free(CYASSL_X509_STORE_CTX* ctx)
09667 {
09668     if (ctx != NULL) {
09669         if (ctx->store != NULL)
09670             CyaSSL_X509_STORE_free(ctx->store);
09671         if (ctx->current_cert != NULL)
09672             CyaSSL_FreeX509(ctx->current_cert);
09673         XFREE(ctx, NULL, 0);
09674     }
09675 }
09676 
09677 
09678 void CyaSSL_X509_STORE_CTX_cleanup(CYASSL_X509_STORE_CTX* ctx)
09679 {
09680     (void)ctx;
09681 }
09682 
09683 
09684 int CyaSSL_X509_verify_cert(CYASSL_X509_STORE_CTX* ctx)
09685 {
09686     if (ctx != NULL && ctx->store != NULL && ctx->store->cm != NULL
09687                                              && ctx->current_cert != NULL) {
09688         return CyaSSL_CertManagerVerifyBuffer(ctx->store->cm,
09689                     ctx->current_cert->derCert.buffer,
09690                     ctx->current_cert->derCert.length,
09691                     SSL_FILETYPE_ASN1);
09692     }
09693     return SSL_FATAL_ERROR;
09694 }
09695 
09696 
09697 CYASSL_ASN1_TIME* CyaSSL_X509_CRL_get_lastUpdate(CYASSL_X509_CRL* crl)
09698 {
09699     (void)crl;
09700     return 0;
09701 }
09702 
09703 
09704 CYASSL_ASN1_TIME* CyaSSL_X509_CRL_get_nextUpdate(CYASSL_X509_CRL* crl)
09705 {
09706     (void)crl;
09707     return 0;
09708 }
09709 
09710 
09711 
09712 CYASSL_EVP_PKEY* CyaSSL_X509_get_pubkey(CYASSL_X509* x509)
09713 {
09714     CYASSL_EVP_PKEY* key = NULL;
09715     if (x509 != NULL) {
09716         key = (CYASSL_EVP_PKEY*)XMALLOC(
09717                     sizeof(CYASSL_EVP_PKEY), NULL, DYNAMIC_TYPE_PUBLIC_KEY);
09718         if (key != NULL) {
09719             key->type = x509->pubKeyOID;
09720             key->save_type = 0;
09721             key->pkey.ptr = (char*)XMALLOC(
09722                         x509->pubKey.length, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
09723             if (key->pkey.ptr == NULL) {
09724                 XFREE(key, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
09725                 return NULL;
09726             }
09727             XMEMCPY(key->pkey.ptr,
09728                                   x509->pubKey.buffer, x509->pubKey.length);
09729             key->pkey_sz = x509->pubKey.length;
09730             #ifdef HAVE_ECC
09731                 key->pkey_curve = (int)x509->pkCurveOID;
09732             #endif /* HAVE_ECC */
09733         }
09734     }
09735     return key;
09736 }
09737 
09738 
09739 int CyaSSL_X509_CRL_verify(CYASSL_X509_CRL* crl, CYASSL_EVP_PKEY* key)
09740 {
09741     (void)crl;
09742     (void)key;
09743     return 0;
09744 }
09745 
09746 
09747 void CyaSSL_X509_STORE_CTX_set_error(CYASSL_X509_STORE_CTX* ctx, int err)
09748 {
09749     (void)ctx;
09750     (void)err;
09751 }
09752 
09753 
09754 void CyaSSL_X509_OBJECT_free_contents(CYASSL_X509_OBJECT* obj)
09755 {
09756     (void)obj;
09757 }
09758 
09759 
09760 void CyaSSL_EVP_PKEY_free(CYASSL_EVP_PKEY* key)
09761 {
09762     if (key != NULL) {
09763         if (key->pkey.ptr != NULL)
09764             XFREE(key->pkey.ptr, NULL, 0);
09765         XFREE(key, NULL, 0);
09766     }
09767 }
09768 
09769 
09770 int CyaSSL_X509_cmp_current_time(const CYASSL_ASN1_TIME* asnTime)
09771 {
09772     (void)asnTime;
09773     return 0;
09774 }
09775 
09776 
09777 int CyaSSL_sk_X509_REVOKED_num(CYASSL_X509_REVOKED* revoked)
09778 {
09779     (void)revoked;
09780     return 0;
09781 }
09782 
09783 
09784 
09785 CYASSL_X509_REVOKED* CyaSSL_X509_CRL_get_REVOKED(CYASSL_X509_CRL* crl)
09786 {
09787     (void)crl;
09788     return 0;
09789 }
09790 
09791 
09792 CYASSL_X509_REVOKED* CyaSSL_sk_X509_REVOKED_value(
09793                                     CYASSL_X509_REVOKED* revoked, int value)
09794 {
09795     (void)revoked;
09796     (void)value;
09797     return 0;
09798 }
09799 
09800 
09801 
09802 CYASSL_ASN1_INTEGER* CyaSSL_X509_get_serialNumber(CYASSL_X509* x509)
09803 {
09804     (void)x509;
09805     return 0;
09806 }
09807 
09808 
09809 int CyaSSL_ASN1_TIME_print(CYASSL_BIO* bio, const CYASSL_ASN1_TIME* asnTime)
09810 {
09811     (void)bio;
09812     (void)asnTime;
09813     return 0;
09814 }
09815 
09816 
09817 
09818 int CyaSSL_ASN1_INTEGER_cmp(const CYASSL_ASN1_INTEGER* a,
09819                             const CYASSL_ASN1_INTEGER* b)
09820 {
09821     (void)a;
09822     (void)b;
09823     return 0;
09824 }
09825 
09826 
09827 long CyaSSL_ASN1_INTEGER_get(const CYASSL_ASN1_INTEGER* i)
09828 {
09829     (void)i;
09830     return 0;
09831 }
09832 
09833 
09834 
09835 void* CyaSSL_X509_STORE_CTX_get_ex_data(CYASSL_X509_STORE_CTX* ctx, int idx)
09836 {
09837 #ifdef FORTRESS
09838     if (ctx != NULL && idx == 0)
09839         return ctx->ex_data;
09840 #else
09841     (void)ctx;
09842     (void)idx;
09843 #endif
09844     return 0;
09845 }
09846 
09847 
09848 int CyaSSL_get_ex_data_X509_STORE_CTX_idx(void)
09849 {
09850     return 0;
09851 }
09852 
09853 
09854 void* CyaSSL_get_ex_data(const CYASSL* ssl, int idx)
09855 {
09856 #ifdef FORTRESS
09857     if (ssl != NULL && idx < MAX_EX_DATA)
09858         return ssl->ex_data[idx];
09859 #else
09860     (void)ssl;
09861     (void)idx;
09862 #endif
09863     return 0;
09864 }
09865 
09866 
09867 void CyaSSL_CTX_set_info_callback(CYASSL_CTX* ctx, void (*f)(void))
09868 {
09869     (void)ctx;
09870     (void)f;
09871 }
09872 
09873 
09874 unsigned long CyaSSL_ERR_peek_error(void)
09875 {
09876     return 0;
09877 }
09878 
09879 
09880 int CyaSSL_ERR_GET_REASON(int err)
09881 {
09882     (void)err;
09883     return 0;
09884 }
09885 
09886 
09887 char* CyaSSL_alert_type_string_long(int alertID)
09888 {
09889     (void)alertID;
09890     return 0;
09891 }
09892 
09893 
09894 char* CyaSSL_alert_desc_string_long(int alertID)
09895 {
09896     (void)alertID;
09897     return 0;
09898 }
09899 
09900 
09901 char* CyaSSL_state_string_long(CYASSL* ssl)
09902 {
09903     (void)ssl;
09904     return 0;
09905 }
09906 
09907 
09908 int CyaSSL_PEM_def_callback(char* name, int num, int w, void* key)
09909 {
09910     (void)name;
09911     (void)num;
09912     (void)w;
09913     (void)key;
09914     return 0;
09915 }
09916 
09917 
09918 long CyaSSL_CTX_sess_accept(CYASSL_CTX* ctx)
09919 {
09920     (void)ctx;
09921     return 0;
09922 }
09923 
09924 
09925 long CyaSSL_CTX_sess_connect(CYASSL_CTX* ctx)
09926 {
09927     (void)ctx;
09928     return 0;
09929 }
09930 
09931 
09932 long CyaSSL_CTX_sess_accept_good(CYASSL_CTX* ctx)
09933 {
09934     (void)ctx;
09935     return 0;
09936 }
09937 
09938 
09939 long CyaSSL_CTX_sess_connect_good(CYASSL_CTX* ctx)
09940 {
09941     (void)ctx;
09942     return 0;
09943 }
09944 
09945 
09946 long CyaSSL_CTX_sess_accept_renegotiate(CYASSL_CTX* ctx)
09947 {
09948     (void)ctx;
09949     return 0;
09950 }
09951 
09952 
09953 long CyaSSL_CTX_sess_connect_renegotiate(CYASSL_CTX* ctx)
09954 {
09955     (void)ctx;
09956     return 0;
09957 }
09958 
09959 
09960 long CyaSSL_CTX_sess_hits(CYASSL_CTX* ctx)
09961 {
09962     (void)ctx;
09963     return 0;
09964 }
09965 
09966 
09967 long CyaSSL_CTX_sess_cb_hits(CYASSL_CTX* ctx)
09968 {
09969     (void)ctx;
09970     return 0;
09971 }
09972 
09973 
09974 long CyaSSL_CTX_sess_cache_full(CYASSL_CTX* ctx)
09975 {
09976     (void)ctx;
09977     return 0;
09978 }
09979 
09980 
09981 long CyaSSL_CTX_sess_misses(CYASSL_CTX* ctx)
09982 {
09983     (void)ctx;
09984     return 0;
09985 }
09986 
09987 
09988 long CyaSSL_CTX_sess_timeouts(CYASSL_CTX* ctx)
09989 {
09990     (void)ctx;
09991     return 0;
09992 }
09993 
09994 
09995 long CyaSSL_CTX_sess_number(CYASSL_CTX* ctx)
09996 {
09997     (void)ctx;
09998     return 0;
09999 }
10000 
10001 
10002 void CyaSSL_DES_set_key_unchecked(CYASSL_const_DES_cblock* myDes,
10003                                                CYASSL_DES_key_schedule* key)
10004 {
10005     (void)myDes;
10006     (void)key;
10007 }
10008 
10009 
10010 void CyaSSL_DES_set_odd_parity(CYASSL_DES_cblock* myDes)
10011 {
10012     (void)myDes;
10013 }
10014 
10015 
10016 void CyaSSL_DES_ecb_encrypt(CYASSL_DES_cblock* desa,
10017              CYASSL_DES_cblock* desb, CYASSL_DES_key_schedule* key, int len)
10018 {
10019     (void)desa;
10020     (void)desb;
10021     (void)key;
10022     (void)len;
10023 }
10024 
10025 int CyaSSL_BIO_printf(CYASSL_BIO* bio, const char* format, ...)
10026 {
10027     (void)bio;
10028     (void)format;
10029     return 0;
10030 }
10031 
10032 
10033 int CyaSSL_ASN1_UTCTIME_print(CYASSL_BIO* bio, const CYASSL_ASN1_UTCTIME* a)
10034 {
10035     (void)bio;
10036     (void)a;
10037     return 0;
10038 }
10039 
10040 
10041 int  CyaSSL_sk_num(CYASSL_X509_REVOKED* rev)
10042 {
10043     (void)rev;
10044     return 0;
10045 }
10046 
10047 
10048 void* CyaSSL_sk_value(CYASSL_X509_REVOKED* rev, int i)
10049 {
10050     (void)rev;
10051     (void)i;
10052     return 0;
10053 }
10054 
10055 
10056 /* stunnel 4.28 needs */
10057 void* CyaSSL_CTX_get_ex_data(const CYASSL_CTX* ctx, int d)
10058 {
10059     (void)ctx;
10060     (void)d;
10061     return 0;
10062 }
10063 
10064 
10065 int CyaSSL_CTX_set_ex_data(CYASSL_CTX* ctx, int d, void* p)
10066 {
10067     (void)ctx;
10068     (void)d;
10069     (void)p;
10070     return SSL_SUCCESS;
10071 }
10072 
10073 
10074 void CyaSSL_CTX_sess_set_get_cb(CYASSL_CTX* ctx,
10075                     CYASSL_SESSION*(*f)(CYASSL*, unsigned char*, int, int*))
10076 {
10077     (void)ctx;
10078     (void)f;
10079 }
10080 
10081 
10082 void CyaSSL_CTX_sess_set_new_cb(CYASSL_CTX* ctx,
10083                              int (*f)(CYASSL*, CYASSL_SESSION*))
10084 {
10085     (void)ctx;
10086     (void)f;
10087 }
10088 
10089 
10090 void CyaSSL_CTX_sess_set_remove_cb(CYASSL_CTX* ctx, void (*f)(CYASSL_CTX*,
10091                                                         CYASSL_SESSION*))
10092 {
10093     (void)ctx;
10094     (void)f;
10095 }
10096 
10097 
10098 int CyaSSL_i2d_SSL_SESSION(CYASSL_SESSION* sess, unsigned char** p)
10099 {
10100     (void)sess;
10101     (void)p;
10102     return sizeof(CYASSL_SESSION);
10103 }
10104 
10105 
10106 CYASSL_SESSION* CyaSSL_d2i_SSL_SESSION(CYASSL_SESSION** sess,
10107                                 const unsigned char** p, long i)
10108 {
10109     (void)p;
10110     (void)i;
10111     if (sess)
10112         return *sess;
10113     return NULL;
10114 }
10115 
10116 
10117 long CyaSSL_SESSION_get_timeout(const CYASSL_SESSION* sess)
10118 {
10119     CYASSL_ENTER("CyaSSL_SESSION_get_timeout");
10120     return sess->timeout;
10121 }
10122 
10123 
10124 long CyaSSL_SESSION_get_time(const CYASSL_SESSION* sess)
10125 {
10126     CYASSL_ENTER("CyaSSL_SESSION_get_time");
10127     return sess->bornOn;
10128 }
10129 
10130 
10131 int CyaSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b,
10132                                 void* c)
10133 {
10134     (void)idx;
10135     (void)arg;
10136     (void)a;
10137     (void)b;
10138     (void)c;
10139     return 0;
10140 }
10141 
10142 #endif /* OPENSSL_EXTRA */
10143 
10144 
10145 #ifdef KEEP_PEER_CERT
10146 char*  CyaSSL_X509_get_subjectCN(CYASSL_X509* x509)
10147 {
10148     if (x509 == NULL)
10149         return NULL;
10150 
10151     return x509->subjectCN;
10152 }
10153 #endif /* KEEP_PEER_CERT */
10154 
10155 #ifdef OPENSSL_EXTRA
10156 
10157 #ifdef FORTRESS
10158 int CyaSSL_cmp_peer_cert_to_file(CYASSL* ssl, const char *fname)
10159 {
10160     int ret = SSL_FATAL_ERROR;
10161 
10162     CYASSL_ENTER("CyaSSL_cmp_peer_cert_to_file");
10163     if (ssl != NULL && fname != NULL)
10164     {
10165     #ifdef CYASSL_SMALL_STACK
10166         EncryptedInfo* info = NULL;
10167         byte           staticBuffer[1]; /* force heap usage */
10168     #else
10169         EncryptedInfo  info[1];
10170         byte           staticBuffer[FILE_BUFFER_SIZE];
10171     #endif
10172         byte*          myBuffer  = staticBuffer;
10173         int            dynamic   = 0;
10174         XFILE          file      = XBADFILE;
10175         long           sz        = 0;
10176         int            eccKey    = 0;
10177         CYASSL_CTX*    ctx       = ssl->ctx;
10178         CYASSL_X509*   peer_cert = &ssl->peerCert;
10179         buffer         fileDer;
10180 
10181         file = XFOPEN(fname, "rb");
10182         if (file == XBADFILE)
10183             return SSL_BAD_FILE;
10184 
10185         XFSEEK(file, 0, XSEEK_END);
10186         sz = XFTELL(file);
10187         XREWIND(file);
10188 
10189         if (sz > (long)sizeof(staticBuffer)) {
10190             CYASSL_MSG("Getting dynamic buffer");
10191             myBuffer = (byte*)XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
10192             dynamic = 1;
10193         }
10194 
10195     #ifdef CYASSL_SMALL_STACK
10196         info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
10197                                                    DYNAMIC_TYPE_TMP_BUFFER);
10198         if (info == NULL)
10199             ret = MEMORY_E;
10200         else
10201     #endif
10202         {
10203             info->set = 0;
10204             info->ctx = ctx;
10205             info->consumed = 0;
10206             fileDer.buffer = 0;
10207 
10208             if ((myBuffer != NULL) &&
10209                 (sz > 0) &&
10210                 (XFREAD(myBuffer, sz, 1, file) > 0) &&
10211                 (PemToDer(myBuffer, sz, CERT_TYPE,
10212                           &fileDer, ctx->heap, info, &eccKey) == 0) &&
10213                 (fileDer.length != 0) &&
10214                 (fileDer.length == peer_cert->derCert.length) &&
10215                 (XMEMCMP(peer_cert->derCert.buffer, fileDer.buffer,
10216                                                     fileDer.length) == 0))
10217             {
10218                 ret = 0;
10219             }
10220 
10221         #ifdef CYASSL_SMALL_STACK
10222             XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10223         #endif
10224         }
10225 
10226         XFREE(fileDer.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
10227         if (dynamic)
10228             XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
10229 
10230         XFCLOSE(file);
10231     }
10232 
10233     return ret;
10234 }
10235 #endif
10236 
10237 
10238 static RNG globalRNG;
10239 static int initGlobalRNG = 0;
10240 
10241 /* SSL_SUCCESS on ok */
10242 int CyaSSL_RAND_seed(const void* seed, int len)
10243 {
10244 
10245     CYASSL_MSG("CyaSSL_RAND_seed");
10246 
10247     (void)seed;
10248     (void)len;
10249 
10250     if (initGlobalRNG == 0) {
10251         if (InitRng(&globalRNG) < 0) {
10252             CYASSL_MSG("CyaSSL Init Global RNG failed");
10253             return 0;
10254         }
10255         initGlobalRNG = 1;
10256     }
10257 
10258     return SSL_SUCCESS;
10259 }
10260 
10261 
10262 /* SSL_SUCCESS on ok */
10263 int CyaSSL_RAND_bytes(unsigned char* buf, int num)
10264 {
10265     int    ret = 0;
10266     int    initTmpRng = 0;
10267     RNG*   rng = NULL;
10268 #ifdef CYASSL_SMALL_STACK
10269     RNG*   tmpRNG = NULL;
10270 #else
10271     RNG    tmpRNG[1];
10272 #endif
10273 
10274     CYASSL_ENTER("RAND_bytes");
10275 
10276 #ifdef CYASSL_SMALL_STACK
10277     tmpRNG = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
10278     if (tmpRNG == NULL)
10279         return ret;
10280 #endif
10281 
10282     if (InitRng(tmpRNG) == 0) {
10283         rng = tmpRNG;
10284         initTmpRng = 1;
10285     }
10286     else if (initGlobalRNG)
10287         rng = &globalRNG;
10288 
10289     if (rng) {
10290         if (RNG_GenerateBlock(rng, buf, num) != 0)
10291             CYASSL_MSG("Bad RNG_GenerateBlock");
10292         else
10293             ret = SSL_SUCCESS;
10294     }
10295 
10296     if (initTmpRng) {
10297         #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
10298             FreeRng(tmpRNG);
10299         #endif
10300     }
10301 
10302 #ifdef CYASSL_SMALL_STACK
10303     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10304 #endif
10305 
10306     return ret;
10307 }
10308 
10309 CYASSL_BN_CTX* CyaSSL_BN_CTX_new(void)
10310 {
10311     static int ctx;  /* ctaocrypt doesn't now need ctx */
10312 
10313     CYASSL_MSG("CyaSSL_BN_CTX_new");
10314 
10315     return (CYASSL_BN_CTX*)&ctx;
10316 }
10317 
10318 void CyaSSL_BN_CTX_init(CYASSL_BN_CTX* ctx)
10319 {
10320     (void)ctx;
10321     CYASSL_MSG("CyaSSL_BN_CTX_init");
10322 }
10323 
10324 
10325 void CyaSSL_BN_CTX_free(CYASSL_BN_CTX* ctx)
10326 {
10327     (void)ctx;
10328     CYASSL_MSG("CyaSSL_BN_CTX_free");
10329 
10330     /* do free since static ctx that does nothing */
10331 }
10332 
10333 
10334 static void InitCyaSSL_BigNum(CYASSL_BIGNUM* bn)
10335 {
10336     CYASSL_MSG("InitCyaSSL_BigNum");
10337     if (bn) {
10338         bn->neg      = 0;
10339         bn->internal = NULL;
10340     }
10341 }
10342 
10343 
10344 CYASSL_BIGNUM* CyaSSL_BN_new(void)
10345 {
10346     CYASSL_BIGNUM* external;
10347     mp_int*        mpi;
10348 
10349     CYASSL_MSG("CyaSSL_BN_new");
10350 
10351     mpi = (mp_int*) XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10352     if (mpi == NULL) {
10353         CYASSL_MSG("CyaSSL_BN_new malloc mpi failure");
10354         return NULL;
10355     }
10356 
10357     external = (CYASSL_BIGNUM*) XMALLOC(sizeof(CYASSL_BIGNUM), NULL,
10358                                         DYNAMIC_TYPE_BIGINT);
10359     if (external == NULL) {
10360         CYASSL_MSG("CyaSSL_BN_new malloc CYASSL_BIGNUM failure");
10361         XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
10362         return NULL;
10363     }
10364 
10365     InitCyaSSL_BigNum(external);
10366     external->internal = mpi;
10367     if (mp_init(mpi) != MP_OKAY) {
10368         CyaSSL_BN_free(external);
10369         return NULL;
10370     }
10371 
10372     return external;
10373 }
10374 
10375 
10376 void CyaSSL_BN_free(CYASSL_BIGNUM* bn)
10377 {
10378     CYASSL_MSG("CyaSSL_BN_free");
10379     if (bn) {
10380         if (bn->internal) {
10381             mp_clear((mp_int*)bn->internal);
10382             XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT);
10383             bn->internal = NULL;
10384         }
10385         XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT);
10386     }
10387 }
10388 
10389 
10390 void CyaSSL_BN_clear_free(CYASSL_BIGNUM* bn)
10391 {
10392     CYASSL_MSG("CyaSSL_BN_clear_free");
10393 
10394     CyaSSL_BN_free(bn);
10395 }
10396 
10397 
10398 /* SSL_SUCCESS on ok */
10399 int CyaSSL_BN_sub(CYASSL_BIGNUM* r, const CYASSL_BIGNUM* a,
10400                   const CYASSL_BIGNUM* b)
10401 {
10402     CYASSL_MSG("CyaSSL_BN_sub");
10403 
10404     if (r == NULL || a == NULL || b == NULL)
10405         return 0;
10406 
10407     if (mp_sub((mp_int*)a->internal,(mp_int*)b->internal,
10408                (mp_int*)r->internal) == MP_OKAY)
10409         return SSL_SUCCESS;
10410 
10411     CYASSL_MSG("CyaSSL_BN_sub mp_sub failed");
10412     return 0;
10413 }
10414 
10415 
10416 /* SSL_SUCCESS on ok */
10417 int CyaSSL_BN_mod(CYASSL_BIGNUM* r, const CYASSL_BIGNUM* a,
10418                   const CYASSL_BIGNUM* b, const CYASSL_BN_CTX* c)
10419 {
10420     (void)c;
10421     CYASSL_MSG("CyaSSL_BN_mod");
10422 
10423     if (r == NULL || a == NULL || b == NULL)
10424         return 0;
10425 
10426     if (mp_mod((mp_int*)a->internal,(mp_int*)b->internal,
10427                (mp_int*)r->internal) == MP_OKAY)
10428         return SSL_SUCCESS;
10429 
10430     CYASSL_MSG("CyaSSL_BN_mod mp_mod failed");
10431     return 0;
10432 }
10433 
10434 
10435 const CYASSL_BIGNUM* CyaSSL_BN_value_one(void)
10436 {
10437     static CYASSL_BIGNUM* bn_one = NULL;
10438 
10439     CYASSL_MSG("CyaSSL_BN_value_one");
10440 
10441     if (bn_one == NULL) {
10442         bn_one = CyaSSL_BN_new();
10443         if (bn_one)
10444             mp_set_int((mp_int*)bn_one->internal, 1);
10445     }
10446 
10447     return bn_one;
10448 }
10449 
10450 
10451 int CyaSSL_BN_num_bytes(const CYASSL_BIGNUM* bn)
10452 {
10453     CYASSL_MSG("CyaSSL_BN_num_bytes");
10454 
10455     if (bn == NULL || bn->internal == NULL)
10456         return 0;
10457 
10458     return mp_unsigned_bin_size((mp_int*)bn->internal);
10459 }
10460 
10461 
10462 int CyaSSL_BN_num_bits(const CYASSL_BIGNUM* bn)
10463 {
10464     CYASSL_MSG("CyaSSL_BN_num_bits");
10465 
10466     if (bn == NULL || bn->internal == NULL)
10467         return 0;
10468 
10469     return mp_count_bits((mp_int*)bn->internal);
10470 }
10471 
10472 
10473 int CyaSSL_BN_is_zero(const CYASSL_BIGNUM* bn)
10474 {
10475     CYASSL_MSG("CyaSSL_BN_is_zero");
10476 
10477     if (bn == NULL || bn->internal == NULL)
10478         return 0;
10479 
10480     return mp_iszero((mp_int*)bn->internal);
10481 }
10482 
10483 
10484 int CyaSSL_BN_is_one(const CYASSL_BIGNUM* bn)
10485 {
10486     CYASSL_MSG("CyaSSL_BN_is_one");
10487 
10488     if (bn == NULL || bn->internal == NULL)
10489         return 0;
10490 
10491     if (mp_cmp_d((mp_int*)bn->internal, 1) == 0)
10492         return 1;
10493 
10494     return 0;
10495 }
10496 
10497 
10498 int CyaSSL_BN_is_odd(const CYASSL_BIGNUM* bn)
10499 {
10500     CYASSL_MSG("CyaSSL_BN_is_odd");
10501 
10502     if (bn == NULL || bn->internal == NULL)
10503         return 0;
10504 
10505     return mp_isodd((mp_int*)bn->internal);
10506 }
10507 
10508 
10509 int CyaSSL_BN_cmp(const CYASSL_BIGNUM* a, const CYASSL_BIGNUM* b)
10510 {
10511     CYASSL_MSG("CyaSSL_BN_cmp");
10512 
10513     if (a == NULL || a->internal == NULL || b == NULL || b->internal ==NULL)
10514         return 0;
10515 
10516     return mp_cmp((mp_int*)a->internal, (mp_int*)b->internal);
10517 }
10518 
10519 
10520 int CyaSSL_BN_bn2bin(const CYASSL_BIGNUM* bn, unsigned char* r)
10521 {
10522     CYASSL_MSG("CyaSSL_BN_bn2bin");
10523 
10524     if (bn == NULL || bn->internal == NULL) {
10525         CYASSL_MSG("NULL bn error");
10526         return SSL_FATAL_ERROR;
10527     }
10528 
10529     if (r == NULL)
10530         return mp_unsigned_bin_size((mp_int*)bn->internal);
10531 
10532     if (mp_to_unsigned_bin((mp_int*)bn->internal, r) != MP_OKAY) {
10533         CYASSL_MSG("mp_to_unsigned_bin error");
10534         return SSL_FATAL_ERROR;
10535     }
10536 
10537     return mp_unsigned_bin_size((mp_int*)bn->internal);
10538 }
10539 
10540 
10541 CYASSL_BIGNUM* CyaSSL_BN_bin2bn(const unsigned char* str, int len,
10542                             CYASSL_BIGNUM* ret)
10543 {
10544     CYASSL_MSG("CyaSSL_BN_bin2bn");
10545 
10546     if (ret && ret->internal) {
10547         if (mp_read_unsigned_bin((mp_int*)ret->internal, str, len) != 0) {
10548             CYASSL_MSG("mp_read_unsigned_bin failure");
10549             return NULL;
10550         }
10551     }
10552     else {
10553         CYASSL_MSG("CyaSSL_BN_bin2bn wants return bignum");
10554     }
10555 
10556     return ret;
10557 }
10558 
10559 
10560 int CyaSSL_mask_bits(CYASSL_BIGNUM* bn, int n)
10561 {
10562     (void)bn;
10563     (void)n;
10564     CYASSL_MSG("CyaSSL_BN_mask_bits");
10565 
10566     return SSL_FATAL_ERROR;
10567 }
10568 
10569 
10570 /* SSL_SUCCESS on ok */
10571 int CyaSSL_BN_rand(CYASSL_BIGNUM* bn, int bits, int top, int bottom)
10572 {
10573     int           ret    = 0;
10574     int           len    = bits / 8;
10575     RNG*          rng    = NULL;
10576 #ifdef CYASSL_SMALL_STACK
10577     RNG*          tmpRNG = NULL;
10578     byte*         buff   = NULL;
10579 #else
10580     RNG           tmpRNG[1];
10581     byte          buff[1024];
10582 #endif
10583 
10584     (void)top;
10585     (void)bottom;
10586     CYASSL_MSG("CyaSSL_BN_rand");
10587 
10588     if (bits % 8)
10589         len++;
10590 
10591 #ifdef CYASSL_SMALL_STACK
10592     buff   = (byte*)XMALLOC(1024,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
10593     tmpRNG = (RNG*) XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
10594     if (buff == NULL || tmpRNG == NULL) {
10595         XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
10596         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10597         return ret;
10598     }
10599 #endif
10600 
10601     if (bn == NULL || bn->internal == NULL)
10602         CYASSL_MSG("Bad function arguments");
10603     else if (InitRng(tmpRNG) == 0)
10604         rng = tmpRNG;
10605     else if (initGlobalRNG)
10606         rng = &globalRNG;
10607 
10608     if (rng) {
10609         if (RNG_GenerateBlock(rng, buff, len) != 0)
10610             CYASSL_MSG("Bad RNG_GenerateBlock");
10611         else {
10612             buff[0]     |= 0x80 | 0x40;
10613             buff[len-1] |= 0x01;
10614 
10615             if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY)
10616                 CYASSL_MSG("mp read bin failed");
10617             else
10618                 ret = SSL_SUCCESS;        
10619         }        
10620     }
10621 
10622 #ifdef CYASSL_SMALL_STACK
10623     XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
10624     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10625 #endif
10626 
10627     return ret;
10628 }
10629 
10630 
10631 int CyaSSL_BN_is_bit_set(const CYASSL_BIGNUM* bn, int n)
10632 {
10633     (void)bn;
10634     (void)n;
10635 
10636     CYASSL_MSG("CyaSSL_BN_is_bit_set");
10637 
10638     return 0;
10639 }
10640 
10641 
10642 /* SSL_SUCCESS on ok */
10643 int CyaSSL_BN_hex2bn(CYASSL_BIGNUM** bn, const char* str)
10644 {
10645     int     ret     = 0;
10646     word32  decSz   = 1024;
10647 #ifdef CYASSL_SMALL_STACK
10648     byte*   decoded = NULL;
10649 #else
10650     byte    decoded[1024];
10651 #endif
10652 
10653     CYASSL_MSG("CyaSSL_BN_hex2bn");
10654 
10655 #ifdef CYASSL_SMALL_STACK
10656     decoded = (byte*)XMALLOC(decSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10657     if (decoded == NULL)
10658         return ret;
10659 #endif
10660 
10661     if (str == NULL)
10662         CYASSL_MSG("Bad function argument");
10663     else if (Base16_Decode((byte*)str, (int)XSTRLEN(str), decoded, &decSz) < 0)
10664         CYASSL_MSG("Bad Base16_Decode error");
10665     else if (bn == NULL)
10666         ret = decSz;
10667     else {
10668         if (*bn == NULL)
10669             *bn = CyaSSL_BN_new();
10670 
10671         if (*bn == NULL)
10672             CYASSL_MSG("BN new failed");
10673         else if (CyaSSL_BN_bin2bn(decoded, decSz, *bn) == NULL)
10674             CYASSL_MSG("Bad bin2bn error");
10675         else
10676             ret = SSL_SUCCESS;
10677     }
10678 
10679 #ifdef CYASSL_SMALL_STACK
10680     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10681 #endif
10682 
10683     return ret;
10684 }
10685 
10686 
10687 CYASSL_BIGNUM* CyaSSL_BN_dup(const CYASSL_BIGNUM* bn)
10688 {
10689     CYASSL_BIGNUM* ret;
10690 
10691     CYASSL_MSG("CyaSSL_BN_dup");
10692 
10693     if (bn == NULL || bn->internal == NULL) {
10694         CYASSL_MSG("bn NULL error");
10695         return NULL;
10696     }
10697 
10698     ret = CyaSSL_BN_new();
10699     if (ret == NULL) {
10700         CYASSL_MSG("bn new error");
10701         return NULL;
10702     }
10703 
10704     if (mp_copy((mp_int*)bn->internal, (mp_int*)ret->internal) != MP_OKAY) {
10705         CYASSL_MSG("mp_copy error");
10706         CyaSSL_BN_free(ret);
10707         return NULL;
10708     }
10709 
10710     return ret;
10711 }
10712 
10713 
10714 CYASSL_BIGNUM* CyaSSL_BN_copy(CYASSL_BIGNUM* r, const CYASSL_BIGNUM* bn)
10715 {
10716     (void)r;
10717     (void)bn;
10718 
10719     CYASSL_MSG("CyaSSL_BN_copy");
10720 
10721     return NULL;
10722 }
10723 
10724 
10725 int CyaSSL_BN_set_word(CYASSL_BIGNUM* bn, unsigned long w)
10726 {
10727     (void)bn;
10728     (void)w;
10729 
10730     CYASSL_MSG("CyaSSL_BN_set_word");
10731 
10732     return SSL_FATAL_ERROR;
10733 }
10734 
10735 
10736 int CyaSSL_BN_dec2bn(CYASSL_BIGNUM** bn, const char* str)
10737 {
10738     (void)bn;
10739     (void)str;
10740 
10741     CYASSL_MSG("CyaSSL_BN_dec2bn");
10742 
10743     return SSL_FATAL_ERROR;
10744 }
10745 
10746 
10747 char* CyaSSL_BN_bn2dec(const CYASSL_BIGNUM* bn)
10748 {
10749     (void)bn;
10750 
10751     CYASSL_MSG("CyaSSL_BN_bn2dec");
10752 
10753     return NULL;
10754 }
10755 
10756 
10757 #ifndef NO_DH
10758 
10759 static void InitCyaSSL_DH(CYASSL_DH* dh)
10760 {
10761     if (dh) {
10762         dh->p        = NULL;
10763         dh->g        = NULL;
10764         dh->pub_key  = NULL;
10765         dh->priv_key = NULL;
10766         dh->internal = NULL;
10767         dh->inSet    = 0;
10768         dh->exSet    = 0;
10769     }
10770 }
10771 
10772 
10773 CYASSL_DH* CyaSSL_DH_new(void)
10774 {
10775     CYASSL_DH* external;
10776     DhKey*     key;
10777 
10778     CYASSL_MSG("CyaSSL_DH_new");
10779 
10780     key = (DhKey*) XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
10781     if (key == NULL) {
10782         CYASSL_MSG("CyaSSL_DH_new malloc DhKey failure");
10783         return NULL;
10784     }
10785 
10786     external = (CYASSL_DH*) XMALLOC(sizeof(CYASSL_DH), NULL,
10787                                     DYNAMIC_TYPE_DH);
10788     if (external == NULL) {
10789         CYASSL_MSG("CyaSSL_DH_new malloc CYASSL_DH failure");
10790         XFREE(key, NULL, DYNAMIC_TYPE_DH);
10791         return NULL;
10792     }
10793 
10794     InitCyaSSL_DH(external);
10795     InitDhKey(key);
10796     external->internal = key;
10797 
10798     return external;
10799 }
10800 
10801 
10802 void CyaSSL_DH_free(CYASSL_DH* dh)
10803 {
10804     CYASSL_MSG("CyaSSL_DH_free");
10805 
10806     if (dh) {
10807         if (dh->internal) {
10808             FreeDhKey((DhKey*)dh->internal);
10809             XFREE(dh->internal, NULL, DYNAMIC_TYPE_DH);
10810             dh->internal = NULL;
10811         }
10812         CyaSSL_BN_free(dh->priv_key);
10813         CyaSSL_BN_free(dh->pub_key);
10814         CyaSSL_BN_free(dh->g);
10815         CyaSSL_BN_free(dh->p);
10816         InitCyaSSL_DH(dh);  /* set back to NULLs for safety */
10817 
10818         XFREE(dh, NULL, DYNAMIC_TYPE_DH);
10819     }
10820 }
10821 
10822 
10823 static int SetDhInternal(CYASSL_DH* dh)
10824 {
10825     int            ret = SSL_FATAL_ERROR;
10826     int            pSz = 1024;
10827     int            gSz = 1024;
10828 #ifdef CYASSL_SMALL_STACK
10829     unsigned char* p   = NULL;
10830     unsigned char* g   = NULL;
10831 #else
10832     unsigned char  p[1024];
10833     unsigned char  g[1024];
10834 #endif
10835 
10836     CYASSL_ENTER("SetDhInternal");
10837 
10838     if (dh == NULL || dh->p == NULL || dh->g == NULL)
10839         CYASSL_MSG("Bad function arguments");
10840     else if (CyaSSL_BN_bn2bin(dh->p, NULL) > pSz)
10841         CYASSL_MSG("Bad p internal size");
10842     else if (CyaSSL_BN_bn2bin(dh->g, NULL) > gSz)
10843         CYASSL_MSG("Bad g internal size");
10844     else {
10845     #ifdef CYASSL_SMALL_STACK
10846         p = (unsigned char*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10847         g = (unsigned char*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10848 
10849         if (p == NULL || g == NULL) {
10850             XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10851             XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10852             return ret;
10853         }
10854     #endif
10855 
10856         pSz = CyaSSL_BN_bn2bin(dh->p, p);
10857         gSz = CyaSSL_BN_bn2bin(dh->g, g);
10858 
10859         if (pSz <= 0 || gSz <= 0)
10860             CYASSL_MSG("Bad BN2bin set");
10861         else if (DhSetKey((DhKey*)dh->internal, p, pSz, g, gSz) < 0)
10862             CYASSL_MSG("Bad DH SetKey");
10863         else {
10864             dh->inSet = 1;
10865             ret = 0;
10866         }
10867 
10868     #ifdef CYASSL_SMALL_STACK
10869         XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10870         XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10871     #endif
10872     }
10873 
10874 
10875     return ret;
10876 }
10877 
10878 
10879 int CyaSSL_DH_size(CYASSL_DH* dh)
10880 {
10881     CYASSL_MSG("CyaSSL_DH_size");
10882 
10883     if (dh == NULL)
10884         return 0;
10885 
10886     return CyaSSL_BN_num_bytes(dh->p);
10887 }
10888 
10889 
10890 /* return SSL_SUCCESS on ok, else 0 */
10891 int CyaSSL_DH_generate_key(CYASSL_DH* dh)
10892 {
10893     int            ret    = 0;
10894     word32         pubSz  = 768;
10895     word32         privSz = 768;
10896     RNG*           rng    = NULL;
10897 #ifdef CYASSL_SMALL_STACK
10898     unsigned char* pub    = NULL;
10899     unsigned char* priv   = NULL;
10900     RNG*           tmpRNG = NULL;
10901 #else
10902     unsigned char  pub [768];
10903     unsigned char  priv[768];
10904     RNG            tmpRNG[1];
10905 #endif
10906 
10907     CYASSL_MSG("CyaSSL_DH_generate_key");
10908 
10909 #ifdef CYASSL_SMALL_STACK
10910     tmpRNG = (RNG*)XMALLOC(sizeof(RNG),      NULL, DYNAMIC_TYPE_TMP_BUFFER);
10911     pub    = (unsigned char*)XMALLOC(pubSz,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
10912     priv   = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10913 
10914     if (tmpRNG == NULL || pub == NULL || priv == NULL) {
10915         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10916         XFREE(pub,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
10917         XFREE(priv,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
10918         return ret;
10919     }
10920 #endif
10921 
10922     if (dh == NULL || dh->p == NULL || dh->g == NULL)
10923         CYASSL_MSG("Bad function arguments");
10924     else if (dh->inSet == 0 && SetDhInternal(dh) < 0)
10925             CYASSL_MSG("Bad DH set internal");
10926     else if (InitRng(tmpRNG) == 0)
10927         rng = tmpRNG;
10928     else {
10929         CYASSL_MSG("Bad RNG Init, trying global");
10930         if (initGlobalRNG == 0)
10931             CYASSL_MSG("Global RNG no Init");
10932         else
10933             rng = &globalRNG;
10934     }
10935 
10936     if (rng) {
10937        if (DhGenerateKeyPair((DhKey*)dh->internal, rng, priv, &privSz,
10938                                                                pub, &pubSz) < 0)
10939             CYASSL_MSG("Bad DhGenerateKeyPair");
10940        else {
10941             if (dh->pub_key)
10942                 CyaSSL_BN_free(dh->pub_key);
10943    
10944             dh->pub_key = CyaSSL_BN_new();
10945             if (dh->pub_key == NULL) {
10946                 CYASSL_MSG("Bad DH new pub");
10947             }
10948             if (dh->priv_key)
10949                 CyaSSL_BN_free(dh->priv_key);
10950 
10951             dh->priv_key = CyaSSL_BN_new();
10952 
10953             if (dh->priv_key == NULL) {
10954                 CYASSL_MSG("Bad DH new priv");
10955             }
10956 
10957             if (dh->pub_key && dh->priv_key) {
10958                if (CyaSSL_BN_bin2bn(pub, pubSz, dh->pub_key) == NULL)
10959                    CYASSL_MSG("Bad DH bn2bin error pub");
10960                else if (CyaSSL_BN_bin2bn(priv, privSz, dh->priv_key) == NULL)
10961                    CYASSL_MSG("Bad DH bn2bin error priv");
10962                else
10963                    ret = SSL_SUCCESS;
10964             }
10965         }
10966     }
10967 
10968 #ifdef CYASSL_SMALL_STACK
10969     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10970     XFREE(pub,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
10971     XFREE(priv,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
10972 #endif
10973 
10974     return ret;
10975 }
10976 
10977 
10978 /* return key size on ok, 0 otherwise */
10979 int CyaSSL_DH_compute_key(unsigned char* key, CYASSL_BIGNUM* otherPub,
10980                           CYASSL_DH* dh)
10981 {
10982     int            ret    = 0;
10983     word32         keySz  = 0;
10984     word32         pubSz  = 1024;
10985     word32         privSz = 1024;
10986 #ifdef CYASSL_SMALL_STACK
10987     unsigned char* pub    = NULL;
10988     unsigned char* priv   = NULL;
10989 #else
10990     unsigned char  pub [1024];
10991     unsigned char  priv[1024];
10992 #endif
10993 
10994     CYASSL_MSG("CyaSSL_DH_compute_key");
10995 
10996 #ifdef CYASSL_SMALL_STACK
10997     pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10998     if (pub == NULL)
10999         return ret;
11000 
11001     priv = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11002     if (priv == NULL) {
11003         XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11004         return 0;
11005     }
11006 #endif
11007 
11008     if (dh == NULL || dh->priv_key == NULL || otherPub == NULL)
11009         CYASSL_MSG("Bad function arguments");
11010     else if ((keySz = (word32)DH_size(dh)) == 0)
11011         CYASSL_MSG("Bad DH_size");
11012     else if (CyaSSL_BN_bn2bin(dh->priv_key, NULL) > (int)privSz)
11013         CYASSL_MSG("Bad priv internal size");
11014     else if (CyaSSL_BN_bn2bin(otherPub, NULL) > (int)pubSz)
11015         CYASSL_MSG("Bad otherPub size");
11016     else {
11017         privSz = CyaSSL_BN_bn2bin(dh->priv_key, priv);
11018         pubSz  = CyaSSL_BN_bn2bin(otherPub, pub);
11019 
11020         if (privSz <= 0 || pubSz <= 0)
11021             CYASSL_MSG("Bad BN2bin set");
11022         else if (DhAgree((DhKey*)dh->internal, key, &keySz, priv, privSz, pub,
11023                                                                      pubSz) < 0)
11024             CYASSL_MSG("DhAgree failed");
11025         else
11026             ret = (int)keySz;
11027     }
11028 
11029 #ifdef CYASSL_SMALL_STACK
11030     XFREE(pub,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
11031     XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11032 #endif
11033 
11034     return ret;
11035 }
11036 #endif /* NO_DH */
11037 
11038 
11039 #ifndef NO_DSA
11040 static void InitCyaSSL_DSA(CYASSL_DSA* dsa)
11041 {
11042     if (dsa) {
11043         dsa->p        = NULL;
11044         dsa->q        = NULL;
11045         dsa->g        = NULL;
11046         dsa->pub_key  = NULL;
11047         dsa->priv_key = NULL;
11048         dsa->internal = NULL;
11049         dsa->inSet    = 0;
11050         dsa->exSet    = 0;
11051     }
11052 }
11053 
11054 
11055 CYASSL_DSA* CyaSSL_DSA_new(void)
11056 {
11057     CYASSL_DSA* external;
11058     DsaKey*     key;
11059 
11060     CYASSL_MSG("CyaSSL_DSA_new");
11061 
11062     key = (DsaKey*) XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
11063     if (key == NULL) {
11064         CYASSL_MSG("CyaSSL_DSA_new malloc DsaKey failure");
11065         return NULL;
11066     }
11067 
11068     external = (CYASSL_DSA*) XMALLOC(sizeof(CYASSL_DSA), NULL,
11069                                     DYNAMIC_TYPE_DSA);
11070     if (external == NULL) {
11071         CYASSL_MSG("CyaSSL_DSA_new malloc CYASSL_DSA failure");
11072         XFREE(key, NULL, DYNAMIC_TYPE_DSA);
11073         return NULL;
11074     }
11075 
11076     InitCyaSSL_DSA(external);
11077     InitDsaKey(key);
11078     external->internal = key;
11079 
11080     return external;
11081 }
11082 
11083 
11084 void CyaSSL_DSA_free(CYASSL_DSA* dsa)
11085 {
11086     CYASSL_MSG("CyaSSL_DSA_free");
11087 
11088     if (dsa) {
11089         if (dsa->internal) {
11090             FreeDsaKey((DsaKey*)dsa->internal);
11091             XFREE(dsa->internal, NULL, DYNAMIC_TYPE_DSA);
11092             dsa->internal = NULL;
11093         }
11094         CyaSSL_BN_free(dsa->priv_key);
11095         CyaSSL_BN_free(dsa->pub_key);
11096         CyaSSL_BN_free(dsa->g);
11097         CyaSSL_BN_free(dsa->q);
11098         CyaSSL_BN_free(dsa->p);
11099         InitCyaSSL_DSA(dsa);  /* set back to NULLs for safety */
11100 
11101         XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
11102     }
11103 }
11104 
11105 
11106 int CyaSSL_DSA_generate_key(CYASSL_DSA* dsa)
11107 {
11108     (void)dsa;
11109 
11110     CYASSL_MSG("CyaSSL_DSA_generate_key");
11111 
11112     return 0;  /* key gen not needed by server */
11113 }
11114 
11115 
11116 int CyaSSL_DSA_generate_parameters_ex(CYASSL_DSA* dsa, int bits,
11117                unsigned char* seed, int seedLen, int* counterRet,
11118                unsigned long* hRet, void* cb)
11119 {
11120     (void)dsa;
11121     (void)bits;
11122     (void)seed;
11123     (void)seedLen;
11124     (void)counterRet;
11125     (void)hRet;
11126     (void)cb;
11127 
11128     CYASSL_MSG("CyaSSL_DSA_generate_parameters_ex");
11129 
11130     return 0;  /* key gen not needed by server */
11131 }
11132 #endif /* NO_DSA */
11133 
11134 #ifndef NO_RSA
11135 static void InitCyaSSL_Rsa(CYASSL_RSA* rsa)
11136 {
11137     if (rsa) {
11138         rsa->n        = NULL;
11139         rsa->e        = NULL;
11140         rsa->d        = NULL;
11141         rsa->p        = NULL;
11142         rsa->q        = NULL;
11143         rsa->dmp1     = NULL;
11144         rsa->dmq1     = NULL;
11145         rsa->iqmp     = NULL;
11146         rsa->internal = NULL;
11147         rsa->inSet    = 0;
11148         rsa->exSet    = 0;
11149     }
11150 }
11151 
11152 
11153 CYASSL_RSA* CyaSSL_RSA_new(void)
11154 {
11155     CYASSL_RSA* external;
11156     RsaKey*     key;
11157 
11158     CYASSL_MSG("CyaSSL_RSA_new");
11159 
11160     key = (RsaKey*) XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
11161     if (key == NULL) {
11162         CYASSL_MSG("CyaSSL_RSA_new malloc RsaKey failure");
11163         return NULL;
11164     }
11165 
11166     external = (CYASSL_RSA*) XMALLOC(sizeof(CYASSL_RSA), NULL,
11167                                      DYNAMIC_TYPE_RSA);
11168     if (external == NULL) {
11169         CYASSL_MSG("CyaSSL_RSA_new malloc CYASSL_RSA failure");
11170         XFREE(key, NULL, DYNAMIC_TYPE_RSA);
11171         return NULL;
11172     }
11173 
11174     InitCyaSSL_Rsa(external);
11175     if (InitRsaKey(key, NULL) != 0) {
11176         CYASSL_MSG("InitRsaKey CYASSL_RSA failure");
11177         XFREE(external, NULL, DYNAMIC_TYPE_RSA);
11178         XFREE(key, NULL, DYNAMIC_TYPE_RSA);
11179         return NULL;
11180     }
11181     external->internal = key;
11182 
11183     return external;
11184 }
11185 
11186 
11187 void CyaSSL_RSA_free(CYASSL_RSA* rsa)
11188 {
11189     CYASSL_MSG("CyaSSL_RSA_free");
11190 
11191     if (rsa) {
11192         if (rsa->internal) {
11193             FreeRsaKey((RsaKey*)rsa->internal);
11194             XFREE(rsa->internal, NULL, DYNAMIC_TYPE_RSA);
11195             rsa->internal = NULL;
11196         }
11197         CyaSSL_BN_free(rsa->iqmp);
11198         CyaSSL_BN_free(rsa->dmq1);
11199         CyaSSL_BN_free(rsa->dmp1);
11200         CyaSSL_BN_free(rsa->q);
11201         CyaSSL_BN_free(rsa->p);
11202         CyaSSL_BN_free(rsa->d);
11203         CyaSSL_BN_free(rsa->e);
11204         CyaSSL_BN_free(rsa->n);
11205         InitCyaSSL_Rsa(rsa);  /* set back to NULLs for safety */
11206 
11207         XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
11208     }
11209 }
11210 #endif /* NO_RSA */
11211 
11212 
11213 #if !defined(NO_RSA) || !defined(NO_DSA)
11214 static int SetIndividualExternal(CYASSL_BIGNUM** bn, mp_int* mpi)
11215 {
11216     CYASSL_MSG("Entering SetIndividualExternal");
11217 
11218     if (mpi == NULL) {
11219         CYASSL_MSG("mpi NULL error");
11220         return SSL_FATAL_ERROR;
11221     }
11222 
11223     if (*bn == NULL) {
11224         *bn = CyaSSL_BN_new();
11225         if (*bn == NULL) {
11226             CYASSL_MSG("SetIndividualExternal alloc failed");
11227             return SSL_FATAL_ERROR;
11228         }
11229     }
11230 
11231     if (mp_copy(mpi, (mp_int*)((*bn)->internal)) != MP_OKAY) {
11232         CYASSL_MSG("mp_copy error");
11233         return SSL_FATAL_ERROR;
11234     }
11235 
11236     return 0;
11237 }
11238 #endif /* !NO_RSA && !NO_DSA */
11239 
11240 
11241 #ifndef NO_DSA
11242 static int SetDsaExternal(CYASSL_DSA* dsa)
11243 {
11244     DsaKey* key;
11245     CYASSL_MSG("Entering SetDsaExternal");
11246 
11247     if (dsa == NULL || dsa->internal == NULL) {
11248         CYASSL_MSG("dsa key NULL error");
11249         return SSL_FATAL_ERROR;
11250     }
11251 
11252     key = (DsaKey*)dsa->internal;
11253 
11254     if (SetIndividualExternal(&dsa->p, &key->p) < 0) {
11255         CYASSL_MSG("dsa p key error");
11256         return SSL_FATAL_ERROR;
11257     }
11258 
11259     if (SetIndividualExternal(&dsa->q, &key->q) < 0) {
11260         CYASSL_MSG("dsa q key error");
11261         return SSL_FATAL_ERROR;
11262     }
11263 
11264     if (SetIndividualExternal(&dsa->g, &key->g) < 0) {
11265         CYASSL_MSG("dsa g key error");
11266         return SSL_FATAL_ERROR;
11267     }
11268 
11269     if (SetIndividualExternal(&dsa->pub_key, &key->y) < 0) {
11270         CYASSL_MSG("dsa y key error");
11271         return SSL_FATAL_ERROR;
11272     }
11273 
11274     if (SetIndividualExternal(&dsa->priv_key, &key->x) < 0) {
11275         CYASSL_MSG("dsa x key error");
11276         return SSL_FATAL_ERROR;
11277     }
11278 
11279     dsa->exSet = 1;
11280 
11281     return 0;
11282 }
11283 #endif /* NO_DSA */
11284 
11285 
11286 #ifndef NO_RSA
11287 static int SetRsaExternal(CYASSL_RSA* rsa)
11288 {
11289     RsaKey* key;
11290     CYASSL_MSG("Entering SetRsaExternal");
11291 
11292     if (rsa == NULL || rsa->internal == NULL) {
11293         CYASSL_MSG("rsa key NULL error");
11294         return SSL_FATAL_ERROR;
11295     }
11296 
11297     key = (RsaKey*)rsa->internal;
11298 
11299     if (SetIndividualExternal(&rsa->n, &key->n) < 0) {
11300         CYASSL_MSG("rsa n key error");
11301         return SSL_FATAL_ERROR;
11302     }
11303 
11304     if (SetIndividualExternal(&rsa->e, &key->e) < 0) {
11305         CYASSL_MSG("rsa e key error");
11306         return SSL_FATAL_ERROR;
11307     }
11308 
11309     if (SetIndividualExternal(&rsa->d, &key->d) < 0) {
11310         CYASSL_MSG("rsa d key error");
11311         return SSL_FATAL_ERROR;
11312     }
11313 
11314     if (SetIndividualExternal(&rsa->p, &key->p) < 0) {
11315         CYASSL_MSG("rsa p key error");
11316         return SSL_FATAL_ERROR;
11317     }
11318 
11319     if (SetIndividualExternal(&rsa->q, &key->q) < 0) {
11320         CYASSL_MSG("rsa q key error");
11321         return SSL_FATAL_ERROR;
11322     }
11323 
11324     if (SetIndividualExternal(&rsa->dmp1, &key->dP) < 0) {
11325         CYASSL_MSG("rsa dP key error");
11326         return SSL_FATAL_ERROR;
11327     }
11328 
11329     if (SetIndividualExternal(&rsa->dmq1, &key->dQ) < 0) {
11330         CYASSL_MSG("rsa dQ key error");
11331         return SSL_FATAL_ERROR;
11332     }
11333 
11334     if (SetIndividualExternal(&rsa->iqmp, &key->u) < 0) {
11335         CYASSL_MSG("rsa u key error");
11336         return SSL_FATAL_ERROR;
11337     }
11338 
11339     rsa->exSet = 1;
11340 
11341     return 0;
11342 }
11343 
11344 
11345 /* SSL_SUCCESS on ok */
11346 int CyaSSL_RSA_generate_key_ex(CYASSL_RSA* rsa, int bits, CYASSL_BIGNUM* bn,
11347                                void* cb)
11348 {
11349     int ret = SSL_FATAL_ERROR;
11350 
11351     CYASSL_MSG("CyaSSL_RSA_generate_key_ex");
11352 
11353     (void)rsa;
11354     (void)bits;
11355     (void)cb;
11356     (void)bn;
11357 
11358 #ifdef CYASSL_KEY_GEN
11359     {
11360     #ifdef CYASSL_SMALL_STACK
11361         RNG* rng = NULL;
11362     #else
11363         RNG  rng[1];
11364     #endif
11365 
11366     #ifdef CYASSL_SMALL_STACK
11367         rng = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
11368         if (rng == NULL)
11369             return SSL_FATAL_ERROR;
11370     #endif
11371 
11372         if (InitRng(rng) < 0)
11373             CYASSL_MSG("RNG init failed");
11374         else if (MakeRsaKey((RsaKey*)rsa->internal, bits, 65537, rng) < 0)
11375             CYASSL_MSG("MakeRsaKey failed");
11376         else if (SetRsaExternal(rsa) < 0)
11377             CYASSL_MSG("SetRsaExternal failed");
11378         else {
11379             rsa->inSet = 1;
11380             ret = SSL_SUCCESS;
11381         }
11382 
11383     #ifdef CYASSL_SMALL_STACK
11384         XFREE(rng, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11385     #endif
11386     }
11387 #else
11388     CYASSL_MSG("No Key Gen built in");
11389 #endif
11390     return ret;
11391 }
11392 
11393 
11394 /* SSL_SUCCESS on ok */
11395 int CyaSSL_RSA_blinding_on(CYASSL_RSA* rsa, CYASSL_BN_CTX* bn)
11396 {
11397     (void)rsa;
11398     (void)bn;
11399 
11400     CYASSL_MSG("CyaSSL_RSA_blinding_on");
11401 
11402     return SSL_SUCCESS;  /* on by default */
11403 }
11404 
11405 
11406 int CyaSSL_RSA_public_encrypt(int len, unsigned char* fr,
11407                             unsigned char* to, CYASSL_RSA* rsa, int padding)
11408 {
11409     (void)len;
11410     (void)fr;
11411     (void)to;
11412     (void)rsa;
11413     (void)padding;
11414 
11415     CYASSL_MSG("CyaSSL_RSA_public_encrypt");
11416 
11417     return SSL_FATAL_ERROR;
11418 }
11419 
11420 
11421 int CyaSSL_RSA_private_decrypt(int len, unsigned char* fr,
11422                             unsigned char* to, CYASSL_RSA* rsa, int padding)
11423 {
11424     (void)len;
11425     (void)fr;
11426     (void)to;
11427     (void)rsa;
11428     (void)padding;
11429 
11430     CYASSL_MSG("CyaSSL_RSA_private_decrypt");
11431 
11432     return SSL_FATAL_ERROR;
11433 }
11434 
11435 
11436 int CyaSSL_RSA_size(const CYASSL_RSA* rsa)
11437 {
11438     CYASSL_MSG("CyaSSL_RSA_size");
11439 
11440     if (rsa == NULL)
11441         return 0;
11442 
11443     return CyaSSL_BN_num_bytes(rsa->n);
11444 }
11445 #endif /* NO_RSA */
11446 
11447 
11448 #ifndef NO_DSA
11449 /* return SSL_SUCCESS on success, < 0 otherwise */
11450 int CyaSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
11451                        CYASSL_DSA* dsa)
11452 {
11453     int    ret = SSL_FATAL_ERROR;
11454     RNG*   rng = NULL;
11455 #ifdef CYASSL_SMALL_STACK
11456     RNG*   tmpRNG = NULL;
11457 #else
11458     RNG    tmpRNG[1];
11459 #endif
11460 
11461     CYASSL_MSG("CyaSSL_DSA_do_sign");
11462 
11463     if (d == NULL || sigRet == NULL || dsa == NULL)
11464         CYASSL_MSG("Bad function arguments");
11465     else if (dsa->inSet == 0)
11466         CYASSL_MSG("No DSA internal set");
11467     else {
11468     #ifdef CYASSL_SMALL_STACK
11469         tmpRNG = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
11470         if (tmpRNG == NULL)
11471             return SSL_FATAL_ERROR;
11472     #endif
11473 
11474         if (InitRng(tmpRNG) == 0)
11475             rng = tmpRNG;
11476         else {
11477             CYASSL_MSG("Bad RNG Init, trying global");
11478             if (initGlobalRNG == 0)
11479                 CYASSL_MSG("Global RNG no Init");
11480             else
11481                 rng = &globalRNG;
11482         }
11483 
11484         if (rng) {
11485             if (DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0)
11486                 CYASSL_MSG("DsaSign failed");
11487             else
11488                 ret = SSL_SUCCESS;
11489         }
11490 
11491     #ifdef CYASSL_SMALL_STACK
11492         XFREE(RNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11493     #endif
11494     }
11495 
11496     return ret;
11497 }
11498 #endif /* NO_DSA */
11499 
11500 
11501 #ifndef NO_RSA
11502 /* return SSL_SUCCES on ok, 0 otherwise */
11503 int CyaSSL_RSA_sign(int type, const unsigned char* m,
11504                            unsigned int mLen, unsigned char* sigRet,
11505                            unsigned int* sigLen, CYASSL_RSA* rsa)
11506 {
11507     word32 outLen;    
11508     word32 signSz;
11509     RNG*   rng        = NULL;
11510     int    ret        = 0;
11511 #ifdef CYASSL_SMALL_STACK
11512     RNG*   tmpRNG     = NULL;
11513     byte*  encodedSig = NULL;
11514 #else
11515     RNG    tmpRNG[1];
11516     byte   encodedSig[MAX_ENCODED_SIG_SZ];
11517 #endif
11518 
11519     CYASSL_MSG("CyaSSL_RSA_sign");
11520 
11521     if (m == NULL || sigRet == NULL || sigLen == NULL || rsa == NULL)
11522         CYASSL_MSG("Bad function arguments");
11523     else if (rsa->inSet == 0)
11524         CYASSL_MSG("No RSA internal set");
11525     else if (type != NID_md5 && type != NID_sha1)
11526         CYASSL_MSG("Bad md type");
11527     else {
11528         outLen = (word32)CyaSSL_BN_num_bytes(rsa->n);
11529 
11530     #ifdef CYASSL_SMALL_STACK
11531         tmpRNG = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
11532         if (tmpRNG == NULL)
11533             return 0;
11534 
11535         encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
11536                                                        DYNAMIC_TYPE_TMP_BUFFER);
11537         if (encodedSig == NULL) {
11538             XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11539             return 0;
11540         }
11541     #endif
11542 
11543         if (outLen == 0)
11544             CYASSL_MSG("Bad RSA size");
11545         else if (InitRng(tmpRNG) == 0)
11546             rng = tmpRNG;
11547         else {
11548             CYASSL_MSG("Bad RNG Init, trying global");
11549 
11550             if (initGlobalRNG == 0)
11551                 CYASSL_MSG("Global RNG no Init");
11552             else
11553                 rng = &globalRNG;
11554         }
11555     }
11556 
11557     if (rng) {
11558         type = (type == NID_md5) ? MD5h : SHAh;
11559 
11560         signSz = EncodeSignature(encodedSig, m, mLen, type);
11561         if (signSz == 0) {
11562             CYASSL_MSG("Bad Encode Signature");
11563         }
11564         else {
11565             *sigLen = RsaSSL_Sign(encodedSig, signSz, sigRet, outLen,
11566                                   (RsaKey*)rsa->internal, rng);
11567             if (*sigLen <= 0)
11568                 CYASSL_MSG("Bad Rsa Sign");
11569             else
11570                 ret = SSL_SUCCESS;
11571         }
11572 
11573     }
11574 
11575 #ifdef CYASSL_SMALL_STACK
11576     XFREE(tmpRNG,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
11577     XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11578 #endif
11579 
11580     CYASSL_MSG("CyaSSL_RSA_sign success");
11581     return ret;
11582 }
11583 
11584 
11585 int CyaSSL_RSA_public_decrypt(int flen, unsigned char* from,
11586                           unsigned char* to, CYASSL_RSA* rsa, int padding)
11587 {
11588     (void)flen;
11589     (void)from;
11590     (void)to;
11591     (void)rsa;
11592     (void)padding;
11593 
11594     CYASSL_MSG("CyaSSL_RSA_public_decrypt");
11595 
11596     return SSL_FATAL_ERROR;
11597 }
11598 
11599 
11600 /* generate p-1 and q-1, SSL_SUCCESS on ok */
11601 int CyaSSL_RSA_GenAdd(CYASSL_RSA* rsa)
11602 {
11603     int    err;
11604     mp_int tmp;
11605 
11606     CYASSL_MSG("CyaSSL_RsaGenAdd");
11607 
11608     if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->d == NULL ||
11609                        rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
11610         CYASSL_MSG("rsa no init error");
11611         return SSL_FATAL_ERROR;
11612     }
11613 
11614     if (mp_init(&tmp) != MP_OKAY) {
11615         CYASSL_MSG("mp_init error");
11616         return SSL_FATAL_ERROR;
11617     }
11618 
11619     err = mp_sub_d((mp_int*)rsa->p->internal, 1, &tmp);
11620     if (err != MP_OKAY) {
11621         CYASSL_MSG("mp_sub_d error");
11622     }
11623     else
11624         err = mp_mod((mp_int*)rsa->d->internal, &tmp,
11625                      (mp_int*)rsa->dmp1->internal);
11626 
11627     if (err != MP_OKAY) {
11628         CYASSL_MSG("mp_mod error");
11629     }
11630     else
11631         err = mp_sub_d((mp_int*)rsa->q->internal, 1, &tmp);
11632     if (err != MP_OKAY) {
11633         CYASSL_MSG("mp_sub_d error");
11634     }
11635     else
11636         err = mp_mod((mp_int*)rsa->d->internal, &tmp,
11637                      (mp_int*)rsa->dmq1->internal);
11638 
11639     mp_clear(&tmp);
11640 
11641     if (err == MP_OKAY)
11642         return SSL_SUCCESS;
11643     else
11644         return SSL_FATAL_ERROR;
11645 }
11646 #endif /* NO_RSA */
11647 
11648 
11649 void CyaSSL_HMAC_Init(CYASSL_HMAC_CTX* ctx, const void* key, int keylen,
11650                   const EVP_MD* type)
11651 {
11652     CYASSL_MSG("CyaSSL_HMAC_Init");
11653 
11654     if (ctx == NULL) {
11655         CYASSL_MSG("no ctx on init");
11656         return;
11657     }
11658 
11659     if (type) {
11660         CYASSL_MSG("init has type");
11661 
11662         if (XSTRNCMP(type, "MD5", 3) == 0) {
11663             CYASSL_MSG("md5 hmac");
11664             ctx->type = MD5;
11665         }
11666         else if (XSTRNCMP(type, "SHA256", 6) == 0) {
11667             CYASSL_MSG("sha256 hmac");
11668             ctx->type = SHA256;
11669         }
11670 
11671         /* has to be last since would pick or 256, 384, or 512 too */
11672         else if (XSTRNCMP(type, "SHA", 3) == 0) {
11673             CYASSL_MSG("sha hmac");
11674             ctx->type = SHA;
11675         }
11676         else {
11677             CYASSL_MSG("bad init type");
11678         }
11679     }
11680 
11681     if (key && keylen) {
11682         CYASSL_MSG("keying hmac");
11683         HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key, (word32)keylen);
11684         /* OpenSSL compat, no error */
11685     }
11686 }
11687 
11688 
11689 void CyaSSL_HMAC_Update(CYASSL_HMAC_CTX* ctx, const unsigned char* data,
11690                     int len)
11691 {
11692     CYASSL_MSG("CyaSSL_HMAC_Update");
11693 
11694     if (ctx && data) {
11695         CYASSL_MSG("updating hmac");
11696         HmacUpdate(&ctx->hmac, data, (word32)len);
11697         /* OpenSSL compat, no error */
11698     }
11699 }
11700 
11701 
11702 void CyaSSL_HMAC_Final(CYASSL_HMAC_CTX* ctx, unsigned char* hash,
11703                    unsigned int* len)
11704 {
11705     CYASSL_MSG("CyaSSL_HMAC_Final");
11706 
11707     if (ctx && hash) {
11708         CYASSL_MSG("final hmac");
11709         HmacFinal(&ctx->hmac, hash);
11710         /* OpenSSL compat, no error */
11711 
11712         if (len) {
11713             CYASSL_MSG("setting output len");
11714             switch (ctx->type) {
11715                 case MD5:
11716                     *len = MD5_DIGEST_SIZE;
11717                     break;
11718 
11719                 case SHA:
11720                     *len = SHA_DIGEST_SIZE;
11721                     break;
11722 
11723                 case SHA256:
11724                     *len = SHA256_DIGEST_SIZE;
11725                     break;
11726 
11727                 default:
11728                     CYASSL_MSG("bad hmac type");
11729             }
11730         }
11731     }
11732 }
11733 
11734 
11735 void CyaSSL_HMAC_cleanup(CYASSL_HMAC_CTX* ctx)
11736 {
11737     (void)ctx;
11738 
11739     CYASSL_MSG("CyaSSL_HMAC_cleanup");
11740 }
11741 
11742 
11743 const CYASSL_EVP_MD* CyaSSL_EVP_get_digestbynid(int id)
11744 {
11745     CYASSL_MSG("CyaSSL_get_digestbynid");
11746 
11747     switch(id) {
11748         case NID_md5:
11749             return CyaSSL_EVP_md5();
11750 
11751         case NID_sha1:
11752             return CyaSSL_EVP_sha1();
11753 
11754         default:
11755             CYASSL_MSG("Bad digest id value");
11756     }
11757 
11758     return NULL;
11759 }
11760 
11761 
11762 CYASSL_RSA* CyaSSL_EVP_PKEY_get1_RSA(CYASSL_EVP_PKEY* key)
11763 {
11764     (void)key;
11765     CYASSL_MSG("CyaSSL_EVP_PKEY_get1_RSA");
11766 
11767     return NULL;
11768 }
11769 
11770 
11771 CYASSL_DSA* CyaSSL_EVP_PKEY_get1_DSA(CYASSL_EVP_PKEY* key)
11772 {
11773     (void)key;
11774     CYASSL_MSG("CyaSSL_EVP_PKEY_get1_DSA");
11775 
11776     return NULL;
11777 }
11778 
11779 
11780 void* CyaSSL_EVP_X_STATE(const CYASSL_EVP_CIPHER_CTX* ctx)
11781 {
11782     CYASSL_MSG("CyaSSL_EVP_X_STATE");
11783 
11784     if (ctx) {
11785         switch (ctx->cipherType) {
11786             case ARC4_TYPE:
11787                 CYASSL_MSG("returning arc4 state");
11788                 return (void*)&ctx->cipher.arc4.x;
11789 
11790             default:
11791                 CYASSL_MSG("bad x state type");
11792                 return 0;
11793         }
11794     }
11795 
11796     return NULL;
11797 }
11798 
11799 
11800 int CyaSSL_EVP_X_STATE_LEN(const CYASSL_EVP_CIPHER_CTX* ctx)
11801 {
11802     CYASSL_MSG("CyaSSL_EVP_X_STATE_LEN");
11803 
11804     if (ctx) {
11805         switch (ctx->cipherType) {
11806             case ARC4_TYPE:
11807                 CYASSL_MSG("returning arc4 state size");
11808                 return sizeof(Arc4);
11809 
11810             default:
11811                 CYASSL_MSG("bad x state type");
11812                 return 0;
11813         }
11814     }
11815 
11816     return 0;
11817 }
11818 
11819 
11820 void CyaSSL_3des_iv(CYASSL_EVP_CIPHER_CTX* ctx, int doset,
11821                             unsigned char* iv, int len)
11822 {
11823     (void)len;
11824 
11825     CYASSL_MSG("CyaSSL_3des_iv");
11826 
11827     if (ctx == NULL || iv == NULL) {
11828         CYASSL_MSG("Bad function argument");
11829         return;
11830     }
11831 
11832     if (doset)
11833         Des3_SetIV(&ctx->cipher.des3, iv);  /* OpenSSL compat, no ret */
11834     else
11835         memcpy(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
11836 }
11837 
11838 
11839 void CyaSSL_aes_ctr_iv(CYASSL_EVP_CIPHER_CTX* ctx, int doset,
11840                       unsigned char* iv, int len)
11841 {
11842     (void)len;
11843 
11844     CYASSL_MSG("CyaSSL_aes_ctr_iv");
11845 
11846     if (ctx == NULL || iv == NULL) {
11847         CYASSL_MSG("Bad function argument");
11848         return;
11849     }
11850 
11851     if (doset)
11852         AesSetIV(&ctx->cipher.aes, iv);  /* OpenSSL compat, no ret */
11853     else
11854         memcpy(iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
11855 }
11856 
11857 
11858 const CYASSL_EVP_MD* CyaSSL_EVP_ripemd160(void)
11859 {
11860     CYASSL_MSG("CyaSSL_ripemd160");
11861 
11862     return NULL;
11863 }
11864 
11865 
11866 int CyaSSL_EVP_MD_size(const CYASSL_EVP_MD* type)
11867 {
11868     CYASSL_MSG("CyaSSL_EVP_MD_size");
11869 
11870     if (type == NULL) {
11871         CYASSL_MSG("No md type arg");
11872         return BAD_FUNC_ARG;
11873     }
11874 
11875     if (XSTRNCMP(type, "MD5", 3) == 0) {
11876         return MD5_DIGEST_SIZE;
11877     }
11878     else if (XSTRNCMP(type, "SHA256", 6) == 0) {
11879         return SHA256_DIGEST_SIZE;
11880     }
11881 #ifdef CYASSL_SHA384
11882     else if (XSTRNCMP(type, "SHA384", 6) == 0) {
11883         return SHA384_DIGEST_SIZE;
11884     }
11885 #endif
11886 #ifdef CYASSL_SHA512
11887     else if (XSTRNCMP(type, "SHA512", 6) == 0) {
11888         return SHA512_DIGEST_SIZE;
11889     }
11890 #endif
11891     /* has to be last since would pick or 256, 384, or 512 too */
11892     else if (XSTRNCMP(type, "SHA", 3) == 0) {
11893         return SHA_DIGEST_SIZE;
11894     }
11895 
11896     return BAD_FUNC_ARG;
11897 }
11898 
11899 
11900 int CyaSSL_EVP_CIPHER_CTX_iv_length(const CYASSL_EVP_CIPHER_CTX* ctx)
11901 {
11902     CYASSL_MSG("CyaSSL_EVP_CIPHER_CTX_iv_length");
11903 
11904     switch (ctx->cipherType) {
11905 
11906         case AES_128_CBC_TYPE :
11907         case AES_192_CBC_TYPE :
11908         case AES_256_CBC_TYPE :
11909             CYASSL_MSG("AES CBC");
11910             return AES_BLOCK_SIZE;
11911 
11912 #ifdef CYASSL_AES_COUNTER
11913         case AES_128_CTR_TYPE :
11914         case AES_192_CTR_TYPE :
11915         case AES_256_CTR_TYPE :
11916             CYASSL_MSG("AES CTR");
11917             return AES_BLOCK_SIZE;
11918 #endif
11919 
11920         case DES_CBC_TYPE :
11921             CYASSL_MSG("DES CBC");
11922             return DES_BLOCK_SIZE;
11923 
11924         case DES_EDE3_CBC_TYPE :
11925             CYASSL_MSG("DES EDE3 CBC");
11926             return DES_BLOCK_SIZE;
11927 
11928         case ARC4_TYPE :
11929             CYASSL_MSG("ARC4");
11930             return 0;
11931 
11932         case NULL_CIPHER_TYPE :
11933             CYASSL_MSG("NULL");
11934             return 0;
11935 
11936         default: {
11937             CYASSL_MSG("bad type");
11938         }
11939     }
11940     return 0;
11941 }
11942 
11943 
11944 void CyaSSL_OPENSSL_free(void* p)
11945 {
11946     CYASSL_MSG("CyaSSL_OPENSSL_free");
11947 
11948     XFREE(p, NULL, 0);
11949 }
11950 
11951 
11952 int CyaSSL_PEM_write_bio_RSAPrivateKey(CYASSL_BIO* bio, RSA* rsa,
11953                                   const EVP_CIPHER* cipher,
11954                                   unsigned char* passwd, int len,
11955                                   pem_password_cb cb, void* arg)
11956 {
11957     (void)bio;
11958     (void)rsa;
11959     (void)cipher;
11960     (void)passwd;
11961     (void)len;
11962     (void)cb;
11963     (void)arg;
11964 
11965     CYASSL_MSG("CyaSSL_PEM_write_bio_RSAPrivateKey");
11966 
11967     return SSL_FATAL_ERROR;
11968 }
11969 
11970 
11971 
11972 int CyaSSL_PEM_write_bio_DSAPrivateKey(CYASSL_BIO* bio, DSA* rsa,
11973                                   const EVP_CIPHER* cipher,
11974                                   unsigned char* passwd, int len,
11975                                   pem_password_cb cb, void* arg)
11976 {
11977     (void)bio;
11978     (void)rsa;
11979     (void)cipher;
11980     (void)passwd;
11981     (void)len;
11982     (void)cb;
11983     (void)arg;
11984 
11985     CYASSL_MSG("CyaSSL_PEM_write_bio_DSAPrivateKey");
11986 
11987     return SSL_FATAL_ERROR;
11988 }
11989 
11990 
11991 
11992 CYASSL_EVP_PKEY* CyaSSL_PEM_read_bio_PrivateKey(CYASSL_BIO* bio,
11993                     CYASSL_EVP_PKEY** key, pem_password_cb cb, void* arg)
11994 {
11995     (void)bio;
11996     (void)key;
11997     (void)cb;
11998     (void)arg;
11999 
12000     CYASSL_MSG("CyaSSL_PEM_read_bio_PrivateKey");
12001 
12002     return NULL;
12003 }
12004 
12005 
12006 
12007 #ifndef NO_RSA
12008 /* Load RSA from Der, SSL_SUCCESS on success < 0 on error */
12009 int CyaSSL_RSA_LoadDer(CYASSL_RSA* rsa, const unsigned char* der,  int derSz)
12010 {
12011     word32 idx = 0;
12012     int    ret;
12013 
12014     CYASSL_ENTER("CyaSSL_RSA_LoadDer");
12015 
12016     if (rsa == NULL || rsa->internal == NULL || der == NULL || derSz <= 0) {
12017         CYASSL_MSG("Bad function arguments");
12018         return BAD_FUNC_ARG;
12019     }
12020 
12021     ret = RsaPrivateKeyDecode(der, &idx, (RsaKey*)rsa->internal, derSz);
12022     if (ret < 0) {
12023         CYASSL_MSG("RsaPrivateKeyDecode failed");
12024         return ret;
12025     }
12026 
12027     if (SetRsaExternal(rsa) < 0) {
12028         CYASSL_MSG("SetRsaExternal failed");
12029         return SSL_FATAL_ERROR;
12030     }
12031 
12032     rsa->inSet = 1;
12033 
12034     return SSL_SUCCESS;
12035 }
12036 #endif /* NO_RSA */
12037 
12038 
12039 #ifndef NO_DSA
12040 /* Load DSA from Der, SSL_SUCCESS on success < 0 on error */
12041 int CyaSSL_DSA_LoadDer(CYASSL_DSA* dsa, const unsigned char* der,  int derSz)
12042 {
12043     word32 idx = 0;
12044     int    ret;
12045 
12046     CYASSL_ENTER("CyaSSL_DSA_LoadDer");
12047 
12048     if (dsa == NULL || dsa->internal == NULL || der == NULL || derSz <= 0) {
12049         CYASSL_MSG("Bad function arguments");
12050         return BAD_FUNC_ARG;
12051     }
12052 
12053     ret = DsaPrivateKeyDecode(der, &idx, (DsaKey*)dsa->internal, derSz);
12054     if (ret < 0) {
12055         CYASSL_MSG("DsaPrivateKeyDecode failed");
12056         return ret;
12057     }
12058 
12059     if (SetDsaExternal(dsa) < 0) {
12060         CYASSL_MSG("SetDsaExternal failed");
12061         return SSL_FATAL_ERROR;
12062     }
12063 
12064     dsa->inSet = 1;
12065 
12066     return SSL_SUCCESS;
12067 }
12068 #endif /* NO_DSA */
12069 
12070 
12071 
12072 
12073 #endif /* OPENSSL_EXTRA */
12074 
12075 
12076 #ifdef SESSION_CERTS
12077 
12078 
12079 /* Get peer's certificate chain */
12080 CYASSL_X509_CHAIN* CyaSSL_get_peer_chain(CYASSL* ssl)
12081 {
12082     CYASSL_ENTER("CyaSSL_get_peer_chain");
12083     if (ssl)
12084         return &ssl->session.chain;
12085 
12086     return 0;
12087 }
12088 
12089 
12090 /* Get peer's certificate chain total count */
12091 int CyaSSL_get_chain_count(CYASSL_X509_CHAIN* chain)
12092 {
12093     CYASSL_ENTER("CyaSSL_get_chain_count");
12094     if (chain)
12095         return chain->count;
12096 
12097     return 0;
12098 }
12099 
12100 
12101 /* Get peer's ASN.1 DER ceritifcate at index (idx) length in bytes */
12102 int CyaSSL_get_chain_length(CYASSL_X509_CHAIN* chain, int idx)
12103 {
12104     CYASSL_ENTER("CyaSSL_get_chain_length");
12105     if (chain)
12106         return chain->certs[idx].length;
12107 
12108     return 0;
12109 }
12110 
12111 
12112 /* Get peer's ASN.1 DER ceritifcate at index (idx) */
12113 byte* CyaSSL_get_chain_cert(CYASSL_X509_CHAIN* chain, int idx)
12114 {
12115     CYASSL_ENTER("CyaSSL_get_chain_cert");
12116     if (chain)
12117         return chain->certs[idx].buffer;
12118 
12119     return 0;
12120 }
12121 
12122 
12123 /* Get peer's CyaSSL X509 ceritifcate at index (idx) */
12124 CYASSL_X509* CyaSSL_get_chain_X509(CYASSL_X509_CHAIN* chain, int idx)
12125 {
12126     int          ret;
12127     CYASSL_X509* x509 = NULL;
12128 #ifdef CYASSL_SMALL_STACK
12129     DecodedCert* cert = NULL;
12130 #else
12131     DecodedCert  cert[1];
12132 #endif
12133 
12134     CYASSL_ENTER("CyaSSL_get_chain_X509");
12135     if (chain != NULL) {
12136     #ifdef CYASSL_SMALL_STACK
12137         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
12138                                                        DYNAMIC_TYPE_TMP_BUFFER);
12139         if (cert != NULL)
12140     #endif
12141         {
12142             InitDecodedCert(cert, chain->certs[idx].buffer,
12143                                   chain->certs[idx].length, NULL);
12144 
12145             if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) != 0)
12146                 CYASSL_MSG("Failed to parse cert");
12147             else {
12148                 x509 = (CYASSL_X509*)XMALLOC(sizeof(CYASSL_X509), NULL,
12149                                                              DYNAMIC_TYPE_X509);
12150                 if (x509 == NULL) {
12151                     CYASSL_MSG("Failed alloc X509");
12152                 }
12153                 else {
12154                     InitX509(x509, 1);
12155 
12156                     if ((ret = CopyDecodedToX509(x509, cert)) != 0) {
12157                         CYASSL_MSG("Failed to copy decoded");
12158                         XFREE(x509, NULL, DYNAMIC_TYPE_X509);
12159                         x509 = NULL;
12160                     }
12161                 }
12162             }
12163 
12164             FreeDecodedCert(cert);
12165         #ifdef CYASSL_SMALL_STACK
12166             XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12167         #endif
12168         }
12169     }
12170 
12171     return x509;
12172 }
12173 
12174 
12175 /* Get peer's PEM ceritifcate at index (idx), output to buffer if inLen big
12176    enough else return error (-1), output length is in *outLen
12177    SSL_SUCCESS on ok */
12178 int  CyaSSL_get_chain_cert_pem(CYASSL_X509_CHAIN* chain, int idx,
12179                                unsigned char* buf, int inLen, int* outLen)
12180 {
12181     const char header[] = "-----BEGIN CERTIFICATE-----\n";
12182     const char footer[] = "-----END CERTIFICATE-----\n";
12183 
12184     int headerLen = sizeof(header) - 1;
12185     int footerLen = sizeof(footer) - 1;
12186     int i;
12187     int err;
12188 
12189     CYASSL_ENTER("CyaSSL_get_chain_cert_pem");
12190     if (!chain || !outLen || !buf)
12191         return BAD_FUNC_ARG;
12192 
12193     /* don't even try if inLen too short */
12194     if (inLen < headerLen + footerLen + chain->certs[idx].length)
12195         return BAD_FUNC_ARG;
12196 
12197     /* header */
12198     XMEMCPY(buf, header, headerLen);
12199     i = headerLen;
12200 
12201     /* body */
12202     *outLen = inLen;  /* input to Base64_Encode */
12203     if ( (err = Base64_Encode(chain->certs[idx].buffer,
12204                        chain->certs[idx].length, buf + i, (word32*)outLen)) < 0)
12205         return err;
12206     i += *outLen;
12207 
12208     /* footer */
12209     if ( (i + footerLen) > inLen)
12210         return BAD_FUNC_ARG;
12211     XMEMCPY(buf + i, footer, footerLen);
12212     *outLen += headerLen + footerLen;
12213 
12214     return SSL_SUCCESS;
12215 }
12216 
12217 
12218 /* get session ID */
12219 const byte* CyaSSL_get_sessionID(const CYASSL_SESSION* session)
12220 {
12221     CYASSL_ENTER("CyaSSL_get_sessionID");
12222     if (session)
12223         return session->sessionID;
12224 
12225     return NULL;
12226 }
12227 
12228 
12229 #endif /* SESSION_CERTS */
12230 
12231 #ifdef HAVE_FUZZER
12232 void CyaSSL_SetFuzzerCb(CYASSL* ssl, CallbackFuzzer cbf, void* fCtx)
12233 {
12234     if (ssl) {
12235         ssl->fuzzerCb  = cbf;
12236         ssl->fuzzerCtx = fCtx;
12237     }
12238 }
12239 #endif
12240 
12241 #ifndef NO_CERTS
12242 #ifdef  HAVE_PK_CALLBACKS
12243 
12244 #ifdef HAVE_ECC
12245 
12246 void  CyaSSL_CTX_SetEccSignCb(CYASSL_CTX* ctx, CallbackEccSign cb)
12247 {
12248     if (ctx)
12249         ctx->EccSignCb = cb;
12250 }
12251 
12252 
12253 void  CyaSSL_SetEccSignCtx(CYASSL* ssl, void *ctx)
12254 {
12255     if (ssl)
12256         ssl->EccSignCtx = ctx;
12257 }
12258 
12259 
12260 void* CyaSSL_GetEccSignCtx(CYASSL* ssl)
12261 {
12262     if (ssl)
12263         return ssl->EccSignCtx;
12264 
12265     return NULL;
12266 }
12267 
12268 
12269 void  CyaSSL_CTX_SetEccVerifyCb(CYASSL_CTX* ctx, CallbackEccVerify cb)
12270 {
12271     if (ctx)
12272         ctx->EccVerifyCb = cb;
12273 }
12274 
12275 
12276 void  CyaSSL_SetEccVerifyCtx(CYASSL* ssl, void *ctx)
12277 {
12278     if (ssl)
12279         ssl->EccVerifyCtx = ctx;
12280 }
12281 
12282 
12283 void* CyaSSL_GetEccVerifyCtx(CYASSL* ssl)
12284 {
12285     if (ssl)
12286         return ssl->EccVerifyCtx;
12287 
12288     return NULL;
12289 }
12290 
12291 #endif /* HAVE_ECC */
12292 
12293 #ifndef NO_RSA
12294 
12295 void  CyaSSL_CTX_SetRsaSignCb(CYASSL_CTX* ctx, CallbackRsaSign cb)
12296 {
12297     if (ctx)
12298         ctx->RsaSignCb = cb;
12299 }
12300 
12301 
12302 void  CyaSSL_SetRsaSignCtx(CYASSL* ssl, void *ctx)
12303 {
12304     if (ssl)
12305         ssl->RsaSignCtx = ctx;
12306 }
12307 
12308 
12309 void* CyaSSL_GetRsaSignCtx(CYASSL* ssl)
12310 {
12311     if (ssl)
12312         return ssl->RsaSignCtx;
12313 
12314     return NULL;
12315 }
12316 
12317 
12318 void  CyaSSL_CTX_SetRsaVerifyCb(CYASSL_CTX* ctx, CallbackRsaVerify cb)
12319 {
12320     if (ctx)
12321         ctx->RsaVerifyCb = cb;
12322 }
12323 
12324 
12325 void  CyaSSL_SetRsaVerifyCtx(CYASSL* ssl, void *ctx)
12326 {
12327     if (ssl)
12328         ssl->RsaVerifyCtx = ctx;
12329 }
12330 
12331 
12332 void* CyaSSL_GetRsaVerifyCtx(CYASSL* ssl)
12333 {
12334     if (ssl)
12335         return ssl->RsaVerifyCtx;
12336 
12337     return NULL;
12338 }
12339 
12340 void  CyaSSL_CTX_SetRsaEncCb(CYASSL_CTX* ctx, CallbackRsaEnc cb)
12341 {
12342     if (ctx)
12343         ctx->RsaEncCb = cb;
12344 }
12345 
12346 
12347 void  CyaSSL_SetRsaEncCtx(CYASSL* ssl, void *ctx)
12348 {
12349     if (ssl)
12350         ssl->RsaEncCtx = ctx;
12351 }
12352 
12353 
12354 void* CyaSSL_GetRsaEncCtx(CYASSL* ssl)
12355 {
12356     if (ssl)
12357         return ssl->RsaEncCtx;
12358 
12359     return NULL;
12360 }
12361 
12362 void  CyaSSL_CTX_SetRsaDecCb(CYASSL_CTX* ctx, CallbackRsaDec cb)
12363 {
12364     if (ctx)
12365         ctx->RsaDecCb = cb;
12366 }
12367 
12368 
12369 void  CyaSSL_SetRsaDecCtx(CYASSL* ssl, void *ctx)
12370 {
12371     if (ssl)
12372         ssl->RsaDecCtx = ctx;
12373 }
12374 
12375 
12376 void* CyaSSL_GetRsaDecCtx(CYASSL* ssl)
12377 {
12378     if (ssl)
12379         return ssl->RsaDecCtx;
12380 
12381     return NULL;
12382 }
12383 
12384 
12385 #endif /* NO_RSA */
12386 
12387 #endif /* HAVE_PK_CALLBACKS */
12388 #endif /* NO_CERTS */
12389 
12390 
12391 #ifdef CYASSL_HAVE_WOLFSCEP
12392     /* Used by autoconf to see if wolfSCEP is available */
12393     void CyaSSL_wolfSCEP(void) {}
12394 #endif
12395 
12396 
12397 #ifdef CYASSL_HAVE_CERT_SERVICE
12398     /* Used by autoconf to see if cert service is available */
12399     void CyaSSL_cert_service(void) {}
12400 #endif
12401