wolf SSL / CyaSSL-2.9.4

Dependents:  

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