cyassl re-port with cellular comms, PSK test

Dependencies:   VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src

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