wolf SSL / CyaSSL

Dependents:   HTTPClient-SSL HTTPClient HTTPClient-SSL http_access ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ssl.c Source File

ssl.c

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