Francois Berder / cyassl-lib

Dependents:   TLS_cyassl TLS_cyassl

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ssl.c Source File

ssl.c

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