Francois Berder / cyassl-lib

Dependents:   TLS_cyassl TLS_cyassl

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers internal.c Source File

internal.c

00001 /* internal.c
00002  *
00003  * Copyright (C) 2006-2013 wolfSSL Inc.
00004  *
00005  * This file is part of CyaSSL.
00006  *
00007  * CyaSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * CyaSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00020  */
00021 
00022 
00023 #ifdef HAVE_CONFIG_H
00024     #include <config.h>
00025 #endif
00026 
00027 #include <cyassl/ctaocrypt/settings.h>
00028 
00029 #include <cyassl/internal.h>
00030 #include <cyassl/ctaoerror.h>
00031 #include <cyassl/ctaocrypt/asn.h>
00032 
00033 #ifdef HAVE_LIBZ
00034     #include "zlib.h"
00035 #endif
00036 
00037 #ifdef HAVE_NTRU
00038     #include "crypto_ntru.h"
00039 #endif
00040 
00041 #if defined(DEBUG_CYASSL) || defined(SHOW_SECRETS)
00042     #ifdef FREESCALE_MQX
00043         #include <fio.h>
00044     #else
00045         #include <stdio.h>
00046     #endif
00047 #endif
00048 
00049 #ifdef __sun
00050     #include <sys/filio.h>
00051 #endif
00052 
00053 #ifndef TRUE
00054     #define TRUE  1
00055 #endif
00056 #ifndef FALSE
00057     #define FALSE 0
00058 #endif
00059 
00060 
00061 #if defined(OPENSSL_EXTRA) && defined(NO_DH)
00062     #error OPENSSL_EXTRA needs DH, please remove NO_DH
00063 #endif
00064 
00065 #if defined(CYASSL_CALLBACKS) && !defined(LARGE_STATIC_BUFFERS)
00066     #error \
00067 CYASSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
00068 #endif
00069 
00070 
00071 #ifndef NO_CYASSL_CLIENT
00072     static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input, word32*);
00073     static int DoServerHello(CYASSL* ssl, const byte* input, word32*, word32);
00074     static int DoServerKeyExchange(CYASSL* ssl, const byte* input, word32*);
00075     #ifndef NO_CERTS
00076         static int DoCertificateRequest(CYASSL* ssl, const byte* input,word32*);
00077     #endif
00078 #endif
00079 
00080 
00081 #ifndef NO_CYASSL_SERVER
00082     static int DoClientHello(CYASSL* ssl, const byte* input, word32*, word32,
00083                              word32);
00084     static int DoClientKeyExchange(CYASSL* ssl, byte* input, word32*, word32);
00085     #if !defined(NO_RSA) || defined(HAVE_ECC)
00086         static int DoCertificateVerify(CYASSL* ssl, byte*, word32*, word32);
00087     #endif
00088 #endif
00089 
00090 typedef enum {
00091     doProcessInit = 0,
00092 #ifndef NO_CYASSL_SERVER
00093     runProcessOldClientHello,
00094 #endif
00095     getRecordLayerHeader,
00096     getData,
00097     runProcessingOneMessage
00098 } processReply;
00099 
00100 #ifndef NO_OLD_TLS
00101 static void Hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
00102                  int content, int verify);
00103 
00104 #endif
00105 
00106 #ifndef NO_CERTS
00107 static void BuildCertHashes(CYASSL* ssl, Hashes* hashes);
00108 #endif
00109 
00110 static void PickHashSigAlgo(CYASSL* ssl,
00111                                 const byte* hashSigAlgo, word32 hashSigAlgoSz);
00112 
00113 #ifndef min
00114 
00115     static INLINE word32 min(word32 a, word32 b)
00116     {
00117         return a > b ? b : a;
00118     }
00119 
00120 #endif /* min */
00121 
00122 
00123 int IsTLS(const CYASSL* ssl)
00124 {
00125     if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_MINOR)
00126         return 1;
00127 
00128     return 0;
00129 }
00130 
00131 
00132 int IsAtLeastTLSv1_2(const CYASSL* ssl)
00133 {
00134     if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_2_MINOR)
00135         return 1;
00136     if (ssl->version.major == DTLS_MAJOR && ssl->version.minor <= DTLSv1_2_MINOR)
00137         return 1;
00138 
00139     return 0;
00140 }
00141 
00142 
00143 #ifdef HAVE_NTRU
00144 
00145 static byte GetEntropy(ENTROPY_CMD cmd, byte* out)
00146 {
00147     /* TODO: add locking? */
00148     static RNG rng;
00149 
00150     if (cmd == INIT) {
00151         int ret = InitRng(&rng);
00152         if (ret == 0)
00153             return 1;
00154         else
00155             return 0;
00156     }
00157 
00158     if (out == NULL)
00159         return 0;
00160 
00161     if (cmd == GET_BYTE_OF_ENTROPY) {
00162         RNG_GenerateBlock(&rng, out, 1);
00163         return 1;
00164     }
00165 
00166     if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) {
00167         *out = 1;
00168         return 1;
00169     }
00170 
00171     return 0;
00172 }
00173 
00174 #endif /* HAVE_NTRU */
00175 
00176 /* used by ssl.c too */
00177 void c32to24(word32 in, word24 out)
00178 {
00179     out[0] = (in >> 16) & 0xff;
00180     out[1] = (in >>  8) & 0xff;
00181     out[2] =  in & 0xff;
00182 }
00183 
00184 
00185 #ifdef CYASSL_DTLS
00186 
00187 static INLINE void c32to48(word32 in, byte out[6])
00188 {
00189     out[0] = 0;
00190     out[1] = 0;
00191     out[2] = (in >> 24) & 0xff;
00192     out[3] = (in >> 16) & 0xff;
00193     out[4] = (in >>  8) & 0xff;
00194     out[5] =  in & 0xff;
00195 }
00196 
00197 #endif /* CYASSL_DTLS */
00198 
00199 
00200 /* convert 16 bit integer to opaque */
00201 static INLINE void c16toa(word16 u16, byte* c)
00202 {
00203     c[0] = (u16 >> 8) & 0xff;
00204     c[1] =  u16 & 0xff;
00205 }
00206 
00207 
00208 /* convert 32 bit integer to opaque */
00209 static INLINE void c32toa(word32 u32, byte* c)
00210 {
00211     c[0] = (u32 >> 24) & 0xff;
00212     c[1] = (u32 >> 16) & 0xff;
00213     c[2] = (u32 >>  8) & 0xff;
00214     c[3] =  u32 & 0xff;
00215 }
00216 
00217 
00218 /* convert a 24 bit integer into a 32 bit one */
00219 static INLINE void c24to32(const word24 u24, word32* u32)
00220 {
00221     *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
00222 }
00223 
00224 
00225 /* convert opaque to 16 bit integer */
00226 static INLINE void ato16(const byte* c, word16* u16)
00227 {
00228     *u16 = (c[0] << 8) | (c[1]);
00229 }
00230 
00231 
00232 #ifdef CYASSL_DTLS
00233 
00234 /* convert opaque to 32 bit integer */
00235 static INLINE void ato32(const byte* c, word32* u32)
00236 {
00237     *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
00238 }
00239 
00240 #endif /* CYASSL_DTLS */
00241 
00242 
00243 #ifdef HAVE_LIBZ
00244 
00245     /* alloc user allocs to work with zlib */
00246     static void* myAlloc(void* opaque, unsigned int item, unsigned int size)
00247     {
00248         (void)opaque;
00249         return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
00250     }
00251 
00252 
00253     static void myFree(void* opaque, void* memory)
00254     {
00255         (void)opaque;
00256         XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ);
00257     }
00258 
00259 
00260     /* init zlib comp/decomp streams, 0 on success */
00261     static int InitStreams(CYASSL* ssl)
00262     {
00263         ssl->c_stream.zalloc = (alloc_func)myAlloc;
00264         ssl->c_stream.zfree  = (free_func)myFree;
00265         ssl->c_stream.opaque = (voidpf)ssl->heap;
00266 
00267         if (deflateInit(&ssl->c_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
00268             return ZLIB_INIT_ERROR;
00269 
00270         ssl->didStreamInit = 1;
00271 
00272         ssl->d_stream.zalloc = (alloc_func)myAlloc;
00273         ssl->d_stream.zfree  = (free_func)myFree;
00274         ssl->d_stream.opaque = (voidpf)ssl->heap;
00275 
00276         if (inflateInit(&ssl->d_stream) != Z_OK) return ZLIB_INIT_ERROR;
00277 
00278         return 0;
00279     }
00280 
00281 
00282     static void FreeStreams(CYASSL* ssl)
00283     {
00284         if (ssl->didStreamInit) {
00285             deflateEnd(&ssl->c_stream);
00286             inflateEnd(&ssl->d_stream);
00287         }
00288     }
00289 
00290 
00291     /* compress in to out, return out size or error */
00292     static int myCompress(CYASSL* ssl, byte* in, int inSz, byte* out, int outSz)
00293     {
00294         int    err;
00295         int    currTotal = (int)ssl->c_stream.total_out;
00296 
00297         ssl->c_stream.next_in   = in;
00298         ssl->c_stream.avail_in  = inSz;
00299         ssl->c_stream.next_out  = out;
00300         ssl->c_stream.avail_out = outSz;
00301 
00302         err = deflate(&ssl->c_stream, Z_SYNC_FLUSH);
00303         if (err != Z_OK && err != Z_STREAM_END) return ZLIB_COMPRESS_ERROR;
00304 
00305         return (int)ssl->c_stream.total_out - currTotal;
00306     }
00307         
00308 
00309     /* decompress in to out, returnn out size or error */
00310     static int myDeCompress(CYASSL* ssl, byte* in,int inSz, byte* out,int outSz)
00311     {
00312         int    err;
00313         int    currTotal = (int)ssl->d_stream.total_out;
00314 
00315         ssl->d_stream.next_in   = in;
00316         ssl->d_stream.avail_in  = inSz;
00317         ssl->d_stream.next_out  = out;
00318         ssl->d_stream.avail_out = outSz;
00319 
00320         err = inflate(&ssl->d_stream, Z_SYNC_FLUSH);
00321         if (err != Z_OK && err != Z_STREAM_END) return ZLIB_DECOMPRESS_ERROR;
00322 
00323         return (int)ssl->d_stream.total_out - currTotal;
00324     }
00325         
00326 #endif /* HAVE_LIBZ */
00327 
00328 
00329 void InitSSL_Method(CYASSL_METHOD* method, ProtocolVersion pv)
00330 {
00331     method->version    = pv;
00332     method->side       = CLIENT_END;
00333     method->downgrade  = 0;
00334 }
00335 
00336 
00337 /* Initialze SSL context, return 0 on success */
00338 int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
00339 {
00340     ctx->method = method;
00341     ctx->refCount = 1;          /* so either CTX_free or SSL_free can release */
00342 #ifndef NO_CERTS
00343     ctx->certificate.buffer = 0;
00344     ctx->certChain.buffer   = 0;
00345     ctx->privateKey.buffer  = 0;
00346     ctx->serverDH_P.buffer  = 0;
00347     ctx->serverDH_G.buffer  = 0;
00348 #endif
00349     ctx->haveDH             = 0;
00350     ctx->haveNTRU           = 0;    /* start off */
00351     ctx->haveECDSAsig       = 0;    /* start off */
00352     ctx->haveStaticECC      = 0;    /* start off */
00353     ctx->heap               = ctx;  /* defaults to self */
00354 #ifndef NO_PSK
00355     ctx->havePSK            = 0;
00356     ctx->server_hint[0]     = 0;
00357     ctx->client_psk_cb      = 0;
00358     ctx->server_psk_cb      = 0;
00359 #endif /* NO_PSK */
00360 #ifdef HAVE_ECC
00361     ctx->eccTempKeySz       = ECDHE_SIZE;   
00362 #endif
00363 
00364 #ifdef OPENSSL_EXTRA
00365     ctx->passwd_cb   = 0;
00366     ctx->userdata    = 0;
00367 #endif /* OPENSSL_EXTRA */
00368 
00369     ctx->timeout = DEFAULT_TIMEOUT;
00370 
00371 #ifndef CYASSL_USER_IO
00372     ctx->CBIORecv = EmbedReceive;
00373     ctx->CBIOSend = EmbedSend;
00374     #ifdef CYASSL_DTLS
00375         if (method->version.major == DTLS_MAJOR) {
00376             ctx->CBIORecv   = EmbedReceiveFrom;
00377             ctx->CBIOSend   = EmbedSendTo;
00378             ctx->CBIOCookie = EmbedGenerateCookie;
00379         }
00380     #endif
00381 #else
00382     /* user will set */
00383     ctx->CBIORecv   = NULL;
00384     ctx->CBIOSend   = NULL;
00385     #ifdef CYASSL_DTLS
00386         ctx->CBIOCookie = NULL;
00387     #endif
00388 #endif
00389     ctx->partialWrite   = 0;
00390     ctx->verifyCallback = 0;
00391 
00392 #ifndef NO_CERTS
00393     ctx->cm = CyaSSL_CertManagerNew();
00394 #endif
00395 #ifdef HAVE_NTRU
00396     if (method->side == CLIENT_END)
00397         ctx->haveNTRU = 1;           /* always on cliet side */
00398                                      /* server can turn on by loading key */
00399 #endif
00400 #ifdef HAVE_ECC
00401     if (method->side == CLIENT_END) {
00402         ctx->haveECDSAsig  = 1;        /* always on cliet side */
00403         ctx->haveStaticECC = 1;        /* server can turn on by loading key */
00404     }
00405 #endif
00406     ctx->suites.setSuites = 0;  /* user hasn't set yet */
00407     /* remove DH later if server didn't set, add psk later */
00408     InitSuites(&ctx->suites, method->version, TRUE, FALSE, TRUE, ctx->haveNTRU,
00409                ctx->haveECDSAsig, ctx->haveStaticECC, method->side);  
00410     ctx->verifyPeer = 0;
00411     ctx->verifyNone = 0;
00412     ctx->failNoCert = 0;
00413     ctx->sessionCacheOff      = 0;  /* initially on */
00414     ctx->sessionCacheFlushOff = 0;  /* initially on */
00415     ctx->sendVerify = 0;
00416     ctx->quietShutdown = 0;
00417     ctx->groupMessages = 0;
00418 #ifdef HAVE_OCSP
00419     CyaSSL_OCSP_Init(&ctx->ocsp);
00420 #endif
00421 #ifdef HAVE_CAVIUM
00422     ctx->devId = NO_CAVIUM_DEVICE; 
00423 #endif
00424 #ifdef HAVE_TLS_EXTENSIONS
00425     ctx->extensions = NULL;
00426 #endif
00427 
00428     if (InitMutex(&ctx->countMutex) < 0) {
00429         CYASSL_MSG("Mutex error on CTX init");
00430         return BAD_MUTEX_ERROR;
00431     } 
00432 #ifndef NO_CERTS
00433     if (ctx->cm == NULL) {
00434         CYASSL_MSG("Bad Cert Manager New");
00435         return BAD_CERT_MANAGER_ERROR;
00436     }
00437 #endif
00438     return 0;
00439 }
00440 
00441 
00442 /* In case contexts are held in array and don't want to free actual ctx */
00443 void SSL_CtxResourceFree(CYASSL_CTX* ctx)
00444 {
00445     XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
00446 
00447 #ifndef NO_CERTS
00448     XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
00449     XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
00450     XFREE(ctx->privateKey.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
00451     XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
00452     XFREE(ctx->certChain.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
00453     CyaSSL_CertManagerFree(ctx->cm);
00454 #endif
00455 #ifdef HAVE_OCSP
00456     CyaSSL_OCSP_Cleanup(&ctx->ocsp);
00457 #endif
00458 #ifdef HAVE_TLS_EXTENSIONS
00459     TLSX_FreeAll(ctx->extensions);
00460 #endif
00461 }
00462 
00463 
00464 void FreeSSL_Ctx(CYASSL_CTX* ctx)
00465 {
00466     int doFree = 0;
00467 
00468     if (LockMutex(&ctx->countMutex) != 0) {
00469         CYASSL_MSG("Couldn't lock count mutex");
00470         return;
00471     }
00472     ctx->refCount--;
00473     if (ctx->refCount == 0)
00474         doFree = 1;
00475     UnLockMutex(&ctx->countMutex);
00476 
00477     if (doFree) {
00478         CYASSL_MSG("CTX ref count down to 0, doing full free");
00479         SSL_CtxResourceFree(ctx);
00480         FreeMutex(&ctx->countMutex);
00481         XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
00482     }
00483     else {
00484         (void)ctx;
00485         CYASSL_MSG("CTX ref count not 0 yet, no free");
00486     }
00487 }
00488 
00489 
00490 /* Set cipher pointers to null */
00491 void InitCiphers(CYASSL* ssl)
00492 {
00493 #ifdef BUILD_ARC4
00494     ssl->encrypt.arc4 = NULL;
00495     ssl->decrypt.arc4 = NULL;
00496 #endif
00497 #ifdef BUILD_DES3
00498     ssl->encrypt.des3 = NULL;
00499     ssl->decrypt.des3 = NULL;
00500 #endif
00501 #ifdef BUILD_AES
00502     ssl->encrypt.aes = NULL;
00503     ssl->decrypt.aes = NULL;
00504 #endif
00505 #ifdef HAVE_CAMELLIA
00506     ssl->encrypt.cam = NULL;
00507     ssl->decrypt.cam = NULL;
00508 #endif
00509 #ifdef HAVE_HC128
00510     ssl->encrypt.hc128 = NULL;
00511     ssl->decrypt.hc128 = NULL;
00512 #endif
00513 #ifdef BUILD_RABBIT
00514     ssl->encrypt.rabbit = NULL;
00515     ssl->decrypt.rabbit = NULL;
00516 #endif
00517     ssl->encrypt.setup = 0;
00518     ssl->decrypt.setup = 0;
00519 }
00520 
00521 
00522 /* Free ciphers */
00523 void FreeCiphers(CYASSL* ssl)
00524 {
00525     (void)ssl;
00526 #ifdef BUILD_ARC4
00527     #ifdef HAVE_CAVIUM
00528     if (ssl->devId != NO_CAVIUM_DEVICE) {
00529         Arc4FreeCavium(ssl->encrypt.arc4);
00530         Arc4FreeCavium(ssl->decrypt.arc4);
00531     }
00532     #endif
00533     XFREE(ssl->encrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
00534     XFREE(ssl->decrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
00535 #endif
00536 #ifdef BUILD_DES3
00537     #ifdef HAVE_CAVIUM
00538     if (ssl->devId != NO_CAVIUM_DEVICE) {
00539         Des3_FreeCavium(ssl->encrypt.des3);
00540         Des3_FreeCavium(ssl->decrypt.des3);
00541     }
00542     #endif
00543     XFREE(ssl->encrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
00544     XFREE(ssl->decrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
00545 #endif
00546 #ifdef BUILD_AES
00547     #ifdef HAVE_CAVIUM
00548     if (ssl->devId != NO_CAVIUM_DEVICE) {
00549         AesFreeCavium(ssl->encrypt.aes);
00550         AesFreeCavium(ssl->decrypt.aes);
00551     }
00552     #endif
00553     XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
00554     XFREE(ssl->decrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
00555 #endif
00556 #ifdef BUILD_CAMELLIA
00557     XFREE(ssl->encrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
00558     XFREE(ssl->decrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
00559 #endif
00560 #ifdef HAVE_HC128
00561     XFREE(ssl->encrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
00562     XFREE(ssl->decrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
00563 #endif
00564 #ifdef BUILD_RABBIT
00565     XFREE(ssl->encrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
00566     XFREE(ssl->decrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
00567 #endif
00568 }
00569 
00570 
00571 void InitCipherSpecs(CipherSpecs* cs)
00572 {
00573     cs->bulk_cipher_algorithm = INVALID_BYTE;
00574     cs->cipher_type           = INVALID_BYTE;
00575     cs->mac_algorithm         = INVALID_BYTE;
00576     cs->kea                   = INVALID_BYTE;
00577     cs->sig_algo              = INVALID_BYTE;
00578 
00579     cs->hash_size   = 0;
00580     cs->static_ecdh = 0;
00581     cs->key_size    = 0;
00582     cs->iv_size     = 0;
00583     cs->block_size  = 0;
00584 }
00585 
00586 
00587 void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK,
00588                 byte haveDH, byte haveNTRU, byte haveECDSAsig,
00589                 byte haveStaticECC, int side)
00590 {
00591     word16 idx = 0;
00592     int    tls    = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR;
00593     int    tls1_2 = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_2_MINOR;
00594     int    haveRSAsig = 1;
00595 
00596     (void)tls;  /* shut up compiler */
00597     (void)tls1_2;
00598     (void)haveDH;
00599     (void)havePSK;
00600     (void)haveNTRU;
00601     (void)haveStaticECC;
00602 
00603     if (suites == NULL) {
00604         CYASSL_MSG("InitSuites pointer error");
00605         return; 
00606     }
00607 
00608     if (suites->setSuites)
00609         return;      /* trust user settings, don't override */
00610 
00611     if (side == SERVER_END && haveStaticECC)
00612         haveRSA = 0;   /* can't do RSA with ECDSA key */
00613 
00614     if (side == SERVER_END && haveECDSAsig) {
00615         haveRSAsig = 0;     /* can't have RSA sig if signed by ECDSA */
00616         (void)haveRSAsig;   /* non ecc builds won't read */
00617     }
00618 
00619 #ifdef CYASSL_DTLS
00620     if (pv.major == DTLS_MAJOR) {
00621         tls    = 1;
00622         tls1_2 = pv.minor <= DTLSv1_2_MINOR;
00623     }
00624 #endif
00625 
00626 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
00627     if (tls && haveNTRU && haveRSA) {
00628         suites->suites[idx++] = 0; 
00629         suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_256_CBC_SHA;
00630     }
00631 #endif
00632 
00633 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
00634     if (tls && haveNTRU && haveRSA) {
00635         suites->suites[idx++] = 0; 
00636         suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_128_CBC_SHA;
00637     }
00638 #endif
00639 
00640 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
00641     if (tls && haveNTRU && haveRSA) {
00642         suites->suites[idx++] = 0; 
00643         suites->suites[idx++] = TLS_NTRU_RSA_WITH_RC4_128_SHA;
00644     }
00645 #endif
00646 
00647 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
00648     if (tls && haveNTRU && haveRSA) {
00649         suites->suites[idx++] = 0; 
00650         suites->suites[idx++] = TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA;
00651     }
00652 #endif
00653 
00654 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
00655     if (tls1_2 && haveRSAsig) {
00656         suites->suites[idx++] = ECC_BYTE;
00657         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256;
00658     }
00659 #endif
00660 
00661 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
00662     if (tls1_2 && haveECDSAsig) {
00663         suites->suites[idx++] = ECC_BYTE;
00664         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
00665     }
00666 #endif
00667 
00668 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
00669     if (tls1_2 && haveRSAsig && haveStaticECC) {
00670         suites->suites[idx++] = ECC_BYTE;
00671         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256;
00672     }
00673 #endif
00674 
00675 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
00676     if (tls1_2 && haveECDSAsig && haveStaticECC) {
00677         suites->suites[idx++] = ECC_BYTE;
00678         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256;
00679     }
00680 #endif
00681 
00682 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
00683     if (tls1_2 && haveRSAsig) {
00684         suites->suites[idx++] = ECC_BYTE;
00685         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384;
00686     }
00687 #endif
00688 
00689 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
00690     if (tls1_2 && haveECDSAsig) {
00691         suites->suites[idx++] = ECC_BYTE;
00692         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384;
00693     }
00694 #endif
00695 
00696 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
00697     if (tls1_2 && haveRSAsig && haveStaticECC) {
00698         suites->suites[idx++] = ECC_BYTE;
00699         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384;
00700     }
00701 #endif
00702 
00703 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
00704     if (tls1_2 && haveECDSAsig && haveStaticECC) {
00705         suites->suites[idx++] = ECC_BYTE;
00706         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384;
00707     }
00708 #endif
00709 
00710 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
00711     if (tls1_2 && haveECDSAsig) {
00712         suites->suites[idx++] = ECC_BYTE;
00713         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
00714     }
00715 #endif
00716 
00717 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
00718     if (tls && haveECDSAsig) {
00719         suites->suites[idx++] = ECC_BYTE; 
00720         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA;
00721     }
00722 #endif
00723 
00724 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
00725     if (tls1_2 && haveECDSAsig && haveStaticECC) {
00726         suites->suites[idx++] = ECC_BYTE;
00727         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
00728     }
00729 #endif
00730 
00731 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
00732     if (tls && haveECDSAsig && haveStaticECC) {
00733         suites->suites[idx++] = ECC_BYTE; 
00734         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA;
00735     }
00736 #endif
00737 
00738 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
00739     if (tls1_2 && haveECDSAsig) {
00740         suites->suites[idx++] = ECC_BYTE;
00741         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
00742     }
00743 #endif
00744 
00745 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
00746     if (tls && haveECDSAsig) {
00747         suites->suites[idx++] = ECC_BYTE; 
00748         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA;
00749     }
00750 #endif
00751 
00752 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
00753     if (tls1_2 && haveECDSAsig && haveStaticECC) {
00754         suites->suites[idx++] = ECC_BYTE;
00755         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
00756     }
00757 #endif
00758 
00759 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
00760     if (tls && haveECDSAsig && haveStaticECC) {
00761         suites->suites[idx++] = ECC_BYTE; 
00762         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA;
00763     }
00764 #endif
00765 
00766 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
00767     if (tls && haveECDSAsig) {
00768         suites->suites[idx++] = ECC_BYTE; 
00769         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA;
00770     }
00771 #endif
00772 
00773 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
00774     if (tls && haveECDSAsig && haveStaticECC) {
00775         suites->suites[idx++] = ECC_BYTE; 
00776         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA;
00777     }
00778 #endif
00779 
00780 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
00781     if (tls && haveECDSAsig) {
00782         suites->suites[idx++] = ECC_BYTE; 
00783         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA;
00784     }
00785 #endif
00786 
00787 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
00788     if (tls && haveECDSAsig && haveStaticECC) {
00789         suites->suites[idx++] = ECC_BYTE; 
00790         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA;
00791     }
00792 #endif
00793 
00794 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
00795     if (tls1_2 && haveRSA) {
00796         suites->suites[idx++] = ECC_BYTE;
00797         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
00798     }
00799 #endif
00800 
00801 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
00802     if (tls && haveRSA) {
00803         suites->suites[idx++] = ECC_BYTE; 
00804         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
00805     }
00806 #endif
00807 
00808 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
00809     if (tls1_2 && haveRSAsig && haveStaticECC) {
00810         suites->suites[idx++] = ECC_BYTE;
00811         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
00812     }
00813 #endif
00814 
00815 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
00816     if (tls && haveRSAsig && haveStaticECC) {
00817         suites->suites[idx++] = ECC_BYTE; 
00818         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA;
00819     }
00820 #endif
00821 
00822 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
00823     if (tls1_2 && haveRSA) {
00824         suites->suites[idx++] = ECC_BYTE;
00825         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
00826     }
00827 #endif
00828 
00829 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
00830     if (tls && haveRSA) {
00831         suites->suites[idx++] = ECC_BYTE; 
00832         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA;
00833     }
00834 #endif
00835 
00836 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
00837     if (tls1_2 && haveRSAsig && haveStaticECC) {
00838         suites->suites[idx++] = ECC_BYTE;
00839         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
00840     }
00841 #endif
00842 
00843 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
00844     if (tls && haveRSAsig && haveStaticECC) {
00845         suites->suites[idx++] = ECC_BYTE; 
00846         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA;
00847     }
00848 #endif
00849 
00850 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
00851     if (tls && haveRSA) {
00852         suites->suites[idx++] = ECC_BYTE; 
00853         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_RC4_128_SHA;
00854     }
00855 #endif
00856 
00857 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
00858     if (tls && haveRSAsig && haveStaticECC) {
00859         suites->suites[idx++] = ECC_BYTE; 
00860         suites->suites[idx++] = TLS_ECDH_RSA_WITH_RC4_128_SHA;
00861     }
00862 #endif
00863 
00864 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
00865     if (tls && haveRSA) {
00866         suites->suites[idx++] = ECC_BYTE; 
00867         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA;
00868     }
00869 #endif
00870 
00871 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
00872     if (tls && haveRSAsig && haveStaticECC) {
00873         suites->suites[idx++] = ECC_BYTE; 
00874         suites->suites[idx++] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA;
00875     }
00876 #endif
00877 
00878 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
00879     if (tls1_2 && haveDH && haveRSA) {
00880         suites->suites[idx++] = 0;
00881         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
00882     }
00883 #endif
00884 
00885 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
00886     if (tls1_2 && haveECDSAsig) {
00887         suites->suites[idx++] = ECC_BYTE; 
00888         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
00889     }
00890 #endif
00891 
00892 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
00893     if (tls1_2 && haveECDSAsig) {
00894         suites->suites[idx++] = ECC_BYTE; 
00895         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8;
00896     }
00897 #endif
00898 
00899 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
00900     if (tls1_2 && haveRSA) {
00901         suites->suites[idx++] = ECC_BYTE; 
00902         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CCM_8;
00903     }
00904 #endif
00905 
00906 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
00907     if (tls1_2 && haveRSA) {
00908         suites->suites[idx++] = ECC_BYTE; 
00909         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CCM_8;
00910     }
00911 #endif
00912 
00913 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
00914     if (tls1_2 && haveDH && haveRSA) {
00915         suites->suites[idx++] = 0; 
00916         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
00917     }
00918 #endif
00919 
00920 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
00921     if (tls1_2 && haveDH && haveRSA) {
00922         suites->suites[idx++] = 0;
00923         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
00924     }
00925 #endif
00926 
00927 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
00928     if (tls1_2 && haveDH && haveRSA) {
00929         suites->suites[idx++] = 0; 
00930         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
00931     }
00932 #endif
00933 
00934 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
00935     if (tls && haveDH && haveRSA) {
00936         suites->suites[idx++] = 0; 
00937         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
00938     }
00939 #endif
00940 
00941 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
00942     if (tls && haveDH && haveRSA) {
00943         suites->suites[idx++] = 0; 
00944         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
00945     }
00946 #endif
00947 
00948 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
00949     if (tls1_2 && haveRSA) {
00950         suites->suites[idx++] = 0;
00951         suites->suites[idx++] = TLS_RSA_WITH_AES_256_GCM_SHA384;
00952     }
00953 #endif
00954 
00955 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
00956     if (tls1_2 && haveRSA) {
00957         suites->suites[idx++] = 0; 
00958         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
00959     }
00960 #endif
00961 
00962 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
00963     if (tls1_2 && haveRSA) {
00964         suites->suites[idx++] = 0;
00965         suites->suites[idx++] = TLS_RSA_WITH_AES_128_GCM_SHA256;
00966     }
00967 #endif
00968 
00969 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
00970     if (tls1_2 && haveRSA) {
00971         suites->suites[idx++] = 0; 
00972         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
00973     }
00974 #endif
00975 
00976 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
00977     if (tls && haveRSA) {
00978         suites->suites[idx++] = 0; 
00979         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA;
00980     }
00981 #endif
00982 
00983 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
00984     if (tls && haveRSA) {
00985         suites->suites[idx++] = 0; 
00986         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA;
00987     }
00988 #endif
00989 
00990 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
00991     if (tls && haveRSA) {
00992         suites->suites[idx++] = 0; 
00993         suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA;
00994     }
00995 #endif
00996 
00997 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
00998     if (tls && haveRSA) {
00999         suites->suites[idx++] = 0; 
01000         suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA256;
01001     }
01002 #endif
01003 
01004 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
01005     if (tls && havePSK) {
01006         suites->suites[idx++] = 0; 
01007         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA;
01008     }
01009 #endif
01010 
01011 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
01012     if (tls && havePSK) {
01013         suites->suites[idx++] = 0; 
01014         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA256;
01015     }
01016 #endif
01017 
01018 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
01019     if (tls && havePSK) {
01020         suites->suites[idx++] = 0; 
01021         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA;
01022     }
01023 #endif
01024 
01025 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
01026     if (tls && havePSK) {
01027         suites->suites[idx++] = ECC_BYTE; 
01028         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM_8;
01029     }
01030 #endif
01031 
01032 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
01033     if (tls && havePSK) {
01034         suites->suites[idx++] = ECC_BYTE; 
01035         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM_8;
01036     }
01037 #endif
01038 
01039 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
01040     if (tls && havePSK) {
01041         suites->suites[idx++] = 0;
01042         suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA256;
01043     }
01044 #endif
01045 
01046 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
01047     if (tls && havePSK) {
01048         suites->suites[idx++] = 0;
01049         suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA;
01050     }
01051 #endif
01052 
01053 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
01054     if (haveRSA ) {
01055         suites->suites[idx++] = 0; 
01056         suites->suites[idx++] = SSL_RSA_WITH_RC4_128_SHA;
01057     }
01058 #endif
01059 
01060 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
01061     if (haveRSA ) {
01062         suites->suites[idx++] = 0; 
01063         suites->suites[idx++] = SSL_RSA_WITH_RC4_128_MD5;
01064     }
01065 #endif
01066 
01067 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
01068     if (haveRSA ) {
01069         suites->suites[idx++] = 0; 
01070         suites->suites[idx++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
01071     }
01072 #endif
01073 
01074 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
01075     if (tls && haveRSA) {
01076         suites->suites[idx++] = 0; 
01077         suites->suites[idx++] = TLS_RSA_WITH_HC_128_CBC_MD5;
01078     }
01079 #endif
01080     
01081 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
01082     if (tls && haveRSA) {
01083         suites->suites[idx++] = 0; 
01084         suites->suites[idx++] = TLS_RSA_WITH_HC_128_CBC_SHA;
01085     }
01086 #endif
01087 
01088 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
01089     if (tls && haveRSA) {
01090         suites->suites[idx++] = 0; 
01091         suites->suites[idx++] = TLS_RSA_WITH_RABBIT_CBC_SHA;
01092     }
01093 #endif
01094 
01095 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
01096     if (tls && haveRSA) {
01097         suites->suites[idx++] = 0; 
01098         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA;
01099     }
01100 #endif
01101 
01102 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
01103     if (tls && haveDH && haveRSA) {
01104         suites->suites[idx++] = 0; 
01105         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA;
01106     }
01107 #endif
01108 
01109 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
01110     if (tls && haveRSA) {
01111         suites->suites[idx++] = 0; 
01112         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA;
01113     }
01114 #endif
01115 
01116 #ifdef BUILD_TLS_DHE_WITH_RSA_CAMELLIA_256_CBC_SHA
01117     if (tls && haveDH && haveRSA) {
01118         suites->suites[idx++] = 0; 
01119         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA;
01120     }
01121 #endif
01122 
01123 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
01124     if (tls && haveRSA) {
01125         suites->suites[idx++] = 0; 
01126         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256;
01127     }
01128 #endif
01129 
01130 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
01131     if (tls && haveDH && haveRSA) {
01132         suites->suites[idx++] = 0; 
01133         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256;
01134     }
01135 #endif
01136 
01137 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
01138     if (tls && haveRSA) {
01139         suites->suites[idx++] = 0; 
01140         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256;
01141     }
01142 #endif
01143 
01144 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
01145     if (tls && haveDH && haveRSA) {
01146         suites->suites[idx++] = 0; 
01147         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256;
01148     }
01149 #endif
01150 
01151     suites->suiteSz = idx;
01152 
01153     {
01154         idx = 0;
01155         
01156         if (haveECDSAsig) {
01157             #ifdef CYASSL_SHA384
01158                 suites->hashSigAlgo[idx++] = sha384_mac;
01159                 suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
01160             #endif
01161             #ifndef NO_SHA256
01162                 suites->hashSigAlgo[idx++] = sha256_mac;
01163                 suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
01164             #endif
01165             #ifndef NO_SHA
01166                 suites->hashSigAlgo[idx++] = sha_mac;
01167                 suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
01168             #endif
01169         }
01170 
01171         if (haveRSAsig) {
01172             #ifdef CYASSL_SHA384
01173                 suites->hashSigAlgo[idx++] = sha384_mac;
01174                 suites->hashSigAlgo[idx++] = rsa_sa_algo;
01175             #endif
01176             #ifndef NO_SHA256
01177                 suites->hashSigAlgo[idx++] = sha256_mac;
01178                 suites->hashSigAlgo[idx++] = rsa_sa_algo;
01179             #endif
01180             #ifndef NO_SHA
01181                 suites->hashSigAlgo[idx++] = sha_mac;
01182                 suites->hashSigAlgo[idx++] = rsa_sa_algo;
01183             #endif
01184         }
01185 
01186         suites->hashSigAlgoSz = idx;
01187     }
01188 }
01189 
01190 
01191 #ifndef NO_CERTS
01192 
01193 /* Initialize CyaSSL X509 type */
01194 void InitX509(CYASSL_X509* x509, int dynamicFlag)
01195 {
01196     x509->derCert.buffer = NULL;
01197     x509->altNames       = NULL;
01198     x509->altNamesNext   = NULL;
01199     x509->dynamicMemory  = (byte)dynamicFlag;
01200 }
01201 
01202 
01203 /* Free CyaSSL X509 type */
01204 void FreeX509(CYASSL_X509* x509)
01205 {
01206     if (x509 == NULL)
01207         return;
01208 
01209     XFREE(x509->derCert.buffer, NULL, DYNAMIC_TYPE_CERT);
01210     if (x509->altNames)
01211         FreeAltNames(x509->altNames, NULL);
01212     if (x509->dynamicMemory)
01213         XFREE(x509, NULL, DYNAMIC_TYPE_X509);
01214 }
01215 
01216 #endif /* NO_CERTS */
01217 
01218 
01219 /* init everything to 0, NULL, default values before calling anything that may
01220    fail so that desctructor has a "good" state to cleanup */
01221 int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
01222 {
01223     int  ret;
01224     byte haveRSA = 0;
01225     byte havePSK = 0;
01226 
01227     ssl->ctx     = ctx; /* only for passing to calls, options could change */
01228     ssl->version = ctx->method->version;
01229     ssl->suites  = NULL;
01230 
01231 #ifdef HAVE_LIBZ
01232     ssl->didStreamInit = 0;
01233 #endif
01234 #ifndef NO_RSA
01235     haveRSA = 1;
01236 #endif
01237    
01238 #ifndef NO_CERTS
01239     ssl->buffers.certificate.buffer   = 0;
01240     ssl->buffers.key.buffer           = 0;
01241     ssl->buffers.certChain.buffer     = 0;
01242 #endif
01243     ssl->buffers.inputBuffer.length   = 0;
01244     ssl->buffers.inputBuffer.idx      = 0;
01245     ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
01246     ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
01247     ssl->buffers.inputBuffer.dynamicFlag = 0;
01248     ssl->buffers.inputBuffer.offset   = 0;
01249     ssl->buffers.outputBuffer.length  = 0;
01250     ssl->buffers.outputBuffer.idx     = 0;
01251     ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
01252     ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
01253     ssl->buffers.outputBuffer.dynamicFlag = 0;
01254     ssl->buffers.outputBuffer.offset      = 0;
01255     ssl->buffers.domainName.buffer    = 0;
01256 #ifndef NO_CERTS
01257     ssl->buffers.serverDH_P.buffer    = 0;
01258     ssl->buffers.serverDH_G.buffer    = 0;
01259     ssl->buffers.serverDH_Pub.buffer  = 0;
01260     ssl->buffers.serverDH_Priv.buffer = 0;
01261 #endif
01262     ssl->buffers.clearOutputBuffer.buffer  = 0;
01263     ssl->buffers.clearOutputBuffer.length  = 0;
01264     ssl->buffers.prevSent                  = 0;
01265     ssl->buffers.plainSz                   = 0;
01266 
01267 #ifdef KEEP_PEER_CERT
01268     InitX509(&ssl->peerCert, 0);
01269 #endif
01270 
01271 #ifdef HAVE_ECC
01272     ssl->eccTempKeySz = ctx->eccTempKeySz;
01273     ssl->peerEccKeyPresent = 0;
01274     ssl->peerEccDsaKeyPresent = 0;
01275     ssl->eccDsaKeyPresent = 0;
01276     ssl->eccTempKeyPresent = 0;
01277     ssl->peerEccKey = NULL;
01278     ssl->peerEccDsaKey = NULL;
01279     ssl->eccDsaKey = NULL;
01280     ssl->eccTempKey = NULL;
01281 #endif
01282 
01283     ssl->timeout = ctx->timeout;
01284     ssl->rfd = -1;   /* set to invalid descriptor */
01285     ssl->wfd = -1;
01286     ssl->rflags = 0;    /* no user flags yet */
01287     ssl->wflags = 0;    /* no user flags yet */
01288     ssl->biord = 0;
01289     ssl->biowr = 0;
01290 
01291     ssl->IOCB_ReadCtx  = &ssl->rfd;  /* prevent invalid pointer access if not */
01292     ssl->IOCB_WriteCtx = &ssl->wfd;  /* correctly set */
01293 #ifdef CYASSL_DTLS
01294     ssl->IOCB_CookieCtx = NULL;      /* we don't use for default cb */
01295     ssl->dtls_expected_rx = MAX_MTU;
01296 #endif
01297 
01298 #ifndef NO_OLD_TLS
01299 #ifndef NO_MD5
01300     InitMd5(&ssl->hashMd5);
01301 #endif
01302 #ifndef NO_SHA
01303     InitSha(&ssl->hashSha);
01304 #endif
01305 #endif
01306 #ifndef NO_SHA256
01307     InitSha256(&ssl->hashSha256);
01308 #endif
01309 #ifdef CYASSL_SHA384
01310     InitSha384(&ssl->hashSha384);
01311 #endif
01312 #ifndef NO_RSA
01313     ssl->peerRsaKey = NULL;
01314     ssl->peerRsaKeyPresent = 0;
01315 #endif
01316     ssl->verifyCallback    = ctx->verifyCallback;
01317     ssl->verifyCbCtx       = NULL;
01318     ssl->options.side      = ctx->method->side;
01319     ssl->options.downgrade = ctx->method->downgrade;
01320     ssl->error = 0;
01321     ssl->options.connReset = 0;
01322     ssl->options.isClosed  = 0;
01323     ssl->options.closeNotify  = 0;
01324     ssl->options.sentNotify   = 0;
01325     ssl->options.usingCompression = 0;
01326     if (ssl->options.side == SERVER_END)
01327         ssl->options.haveDH = ctx->haveDH;
01328     else
01329         ssl->options.haveDH = 0;
01330     ssl->options.haveNTRU      = ctx->haveNTRU;
01331     ssl->options.haveECDSAsig  = ctx->haveECDSAsig;
01332     ssl->options.haveStaticECC = ctx->haveStaticECC;
01333     ssl->options.havePeerCert    = 0; 
01334     ssl->options.havePeerVerify  = 0;
01335     ssl->options.usingPSK_cipher = 0;
01336     ssl->options.sendAlertState = 0;
01337 #ifndef NO_PSK
01338     havePSK = ctx->havePSK;
01339     ssl->options.havePSK   = ctx->havePSK;
01340     ssl->options.client_psk_cb = ctx->client_psk_cb;
01341     ssl->options.server_psk_cb = ctx->server_psk_cb;
01342 #endif /* NO_PSK */
01343 
01344     ssl->options.serverState = NULL_STATE;
01345     ssl->options.clientState = NULL_STATE;
01346     ssl->options.connectState = CONNECT_BEGIN;
01347     ssl->options.acceptState  = ACCEPT_BEGIN; 
01348     ssl->options.handShakeState  = NULL_STATE; 
01349     ssl->options.processReply = doProcessInit;
01350 
01351 #ifdef CYASSL_DTLS
01352     ssl->keys.dtls_sequence_number      = 0;
01353     ssl->keys.dtls_peer_sequence_number = 0;
01354     ssl->keys.dtls_expected_peer_sequence_number = 0;
01355     ssl->keys.dtls_handshake_number     = 0;
01356     ssl->keys.dtls_expected_peer_handshake_number = 0;
01357     ssl->keys.dtls_epoch                = 0;
01358     ssl->keys.dtls_peer_epoch           = 0;
01359     ssl->keys.dtls_expected_peer_epoch  = 0;
01360     ssl->dtls_timeout_init              = DTLS_TIMEOUT_INIT;
01361     ssl->dtls_timeout_max               = DTLS_TIMEOUT_MAX;
01362     ssl->dtls_timeout                   = ssl->dtls_timeout_init;
01363     ssl->dtls_pool                      = NULL;
01364     ssl->dtls_msg_list                  = NULL;
01365 #endif
01366     ssl->keys.encryptSz    = 0;
01367     ssl->keys.encryptionOn = 0;     /* initially off */
01368     ssl->keys.decryptedCur = 0;     /* initially off */
01369     ssl->options.sessionCacheOff      = ctx->sessionCacheOff;
01370     ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
01371 
01372     ssl->options.verifyPeer = ctx->verifyPeer;
01373     ssl->options.verifyNone = ctx->verifyNone;
01374     ssl->options.failNoCert = ctx->failNoCert;
01375     ssl->options.sendVerify = ctx->sendVerify;
01376     
01377     ssl->options.resuming = 0;
01378     ssl->options.haveSessionId = 0;
01379     #ifndef NO_OLD_TLS
01380         ssl->hmac = Hmac;         /* default to SSLv3 */
01381     #else
01382         ssl->hmac = TLS_hmac;
01383     #endif
01384     ssl->heap = ctx->heap;    /* defaults to self */
01385     ssl->options.tls    = 0;
01386     ssl->options.tls1_1 = 0;
01387     ssl->options.dtls = ssl->version.major == DTLS_MAJOR;
01388     ssl->options.partialWrite  = ctx->partialWrite;
01389     ssl->options.quietShutdown = ctx->quietShutdown;
01390     ssl->options.certOnly = 0;
01391     ssl->options.groupMessages = ctx->groupMessages;
01392     ssl->options.usingNonblock = 0;
01393     ssl->options.saveArrays = 0;
01394 
01395 #ifndef NO_CERTS
01396     /* ctx still owns certificate, certChain, key, dh, and cm */
01397     ssl->buffers.certificate = ctx->certificate;
01398     ssl->buffers.certChain = ctx->certChain;
01399     ssl->buffers.key = ctx->privateKey;
01400     if (ssl->options.side == SERVER_END) {
01401         ssl->buffers.serverDH_P = ctx->serverDH_P;
01402         ssl->buffers.serverDH_G = ctx->serverDH_G;
01403     }
01404 #endif
01405     ssl->buffers.weOwnCert = 0;
01406     ssl->buffers.weOwnKey  = 0;
01407     ssl->buffers.weOwnDH   = 0;
01408 
01409 #ifdef CYASSL_DTLS
01410     ssl->buffers.dtlsCtx.fd = -1;
01411     ssl->buffers.dtlsCtx.peer.sa = NULL;
01412     ssl->buffers.dtlsCtx.peer.sz = 0;
01413 #endif
01414 
01415 #ifdef KEEP_PEER_CERT
01416     ssl->peerCert.issuer.sz    = 0;
01417     ssl->peerCert.subject.sz   = 0;
01418 #endif
01419   
01420 #ifdef SESSION_CERTS
01421     ssl->session.chain.count = 0;
01422 #endif
01423 
01424 #ifndef NO_CLIENT_CACHE
01425     ssl->session.idLen = 0;
01426 #endif
01427 
01428     ssl->cipher.ssl = ssl;
01429 
01430 #ifdef FORTRESS
01431     ssl->ex_data[0] = 0;
01432     ssl->ex_data[1] = 0;
01433     ssl->ex_data[2] = 0;
01434 #endif
01435 
01436 #ifdef CYASSL_CALLBACKS
01437     ssl->hsInfoOn = 0;
01438     ssl->toInfoOn = 0;
01439 #endif
01440 
01441 #ifdef HAVE_CAVIUM
01442     ssl->devId = ctx->devId; 
01443 #endif
01444 
01445 #ifdef HAVE_TLS_EXTENSIONS
01446     ssl->extensions = NULL;
01447 #endif
01448 
01449     ssl->rng    = NULL;
01450     ssl->arrays = NULL;
01451 
01452     /* default alert state (none) */
01453     ssl->alert_history.last_rx.code  = -1;
01454     ssl->alert_history.last_rx.level = -1;
01455     ssl->alert_history.last_tx.code  = -1;
01456     ssl->alert_history.last_tx.level = -1;
01457 
01458     InitCiphers(ssl);
01459     InitCipherSpecs(&ssl->specs);
01460     /* all done with init, now can return errors, call other stuff */
01461 
01462     /* increment CTX reference count */
01463     if (LockMutex(&ctx->countMutex) != 0) {
01464         CYASSL_MSG("Couldn't lock CTX count mutex");
01465         return BAD_MUTEX_ERROR;
01466     }
01467     ctx->refCount++;
01468     UnLockMutex(&ctx->countMutex);
01469 
01470     /* arrays */
01471     ssl->arrays = (Arrays*)XMALLOC(sizeof(Arrays), ssl->heap,
01472                                    DYNAMIC_TYPE_ARRAYS);
01473     if (ssl->arrays == NULL) {
01474         CYASSL_MSG("Arrays Memory error");
01475         return MEMORY_E;
01476     }
01477 
01478 #ifndef NO_PSK
01479     ssl->arrays->client_identity[0] = 0;
01480     if (ctx->server_hint[0]) {   /* set in CTX */
01481         XSTRNCPY(ssl->arrays->server_hint, ctx->server_hint, MAX_PSK_ID_LEN);
01482         ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
01483     }
01484     else
01485         ssl->arrays->server_hint[0] = 0;
01486 #endif /* NO_PSK */
01487 
01488 #ifdef CYASSL_DTLS
01489     ssl->arrays->cookieSz = 0;
01490 #endif
01491 
01492     /* RNG */
01493     ssl->rng = (RNG*)XMALLOC(sizeof(RNG), ssl->heap, DYNAMIC_TYPE_RNG);
01494     if (ssl->rng == NULL) {
01495         CYASSL_MSG("RNG Memory error");
01496         return MEMORY_E;
01497     }
01498 
01499     if ( (ret = InitRng(ssl->rng)) != 0) {
01500         CYASSL_MSG("RNG Init error");
01501         return ret;
01502     }
01503 
01504     /* suites */
01505     ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
01506                                    DYNAMIC_TYPE_SUITES);
01507     if (ssl->suites == NULL) {
01508         CYASSL_MSG("Suites Memory error");
01509         return MEMORY_E;
01510     }
01511     *ssl->suites = ctx->suites;
01512 
01513     /* peer key */
01514 #ifndef NO_RSA
01515     ssl->peerRsaKey = (RsaKey*)XMALLOC(sizeof(RsaKey), ssl->heap,
01516                                        DYNAMIC_TYPE_RSA);
01517     if (ssl->peerRsaKey == NULL) {
01518         CYASSL_MSG("PeerRsaKey Memory error");
01519         return MEMORY_E;
01520     }
01521     InitRsaKey(ssl->peerRsaKey, ctx->heap);
01522 #endif
01523 #ifndef NO_CERTS
01524     /* make sure server has cert and key unless using PSK */
01525     if (ssl->options.side == SERVER_END && !havePSK)
01526         if (!ssl->buffers.certificate.buffer || !ssl->buffers.key.buffer) {
01527             CYASSL_MSG("Server missing certificate and/or private key"); 
01528             return NO_PRIVATE_KEY;
01529         }
01530 #endif
01531 #ifdef HAVE_ECC
01532     ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
01533                                                    ctx->heap, DYNAMIC_TYPE_ECC);
01534     if (ssl->peerEccKey == NULL) {
01535         CYASSL_MSG("PeerEccKey Memory error");
01536         return MEMORY_E;
01537     }
01538     ssl->peerEccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
01539                                                    ctx->heap, DYNAMIC_TYPE_ECC);
01540     if (ssl->peerEccDsaKey == NULL) {
01541         CYASSL_MSG("PeerEccDsaKey Memory error");
01542         return MEMORY_E;
01543     }
01544     ssl->eccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
01545                                                    ctx->heap, DYNAMIC_TYPE_ECC);
01546     if (ssl->eccDsaKey == NULL) {
01547         CYASSL_MSG("EccDsaKey Memory error");
01548         return MEMORY_E;
01549     }
01550     ssl->eccTempKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
01551                                                    ctx->heap, DYNAMIC_TYPE_ECC);
01552     if (ssl->eccTempKey == NULL) {
01553         CYASSL_MSG("EccTempKey Memory error");
01554         return MEMORY_E;
01555     }
01556     ecc_init(ssl->peerEccKey);
01557     ecc_init(ssl->peerEccDsaKey);
01558     ecc_init(ssl->eccDsaKey);
01559     ecc_init(ssl->eccTempKey);
01560 #endif
01561 
01562     /* make sure server has DH parms, and add PSK if there, add NTRU too */
01563     if (ssl->options.side == SERVER_END) 
01564         InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
01565                    ssl->options.haveDH, ssl->options.haveNTRU,
01566                    ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
01567                    ssl->options.side);
01568     else 
01569         InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, TRUE,
01570                    ssl->options.haveNTRU, ssl->options.haveECDSAsig,
01571                    ssl->options.haveStaticECC, ssl->options.side);
01572 
01573     return 0;
01574 }
01575 
01576 
01577 /* free use of temporary arrays */
01578 void FreeArrays(CYASSL* ssl, int keep)
01579 {
01580     if (ssl->arrays && keep) {
01581         /* keeps session id for user retrieval */
01582         XMEMCPY(ssl->session.sessionID, ssl->arrays->sessionID, ID_LEN);
01583     }
01584     XFREE(ssl->arrays, ssl->heap, DYNAMIC_TYPE_ARRAYS);
01585     ssl->arrays = NULL;
01586 }
01587 
01588 
01589 /* In case holding SSL object in array and don't want to free actual ssl */
01590 void SSL_ResourceFree(CYASSL* ssl)
01591 {
01592     FreeCiphers(ssl);
01593     FreeArrays(ssl, 0);
01594     XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
01595     XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
01596     XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
01597 
01598 #ifndef NO_CERTS
01599     XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
01600     XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH);
01601     /* parameters (p,g) may be owned by ctx */
01602     if (ssl->buffers.weOwnDH || ssl->options.side == CLIENT_END) {
01603         XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
01604         XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
01605     }
01606 
01607     /* CYASSL_CTX always owns certChain */
01608     if (ssl->buffers.weOwnCert)
01609         XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
01610     if (ssl->buffers.weOwnKey)
01611         XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
01612 #endif
01613 #ifndef NO_RSA
01614     if (ssl->peerRsaKey) {
01615         FreeRsaKey(ssl->peerRsaKey);
01616         XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
01617     }
01618 #endif
01619     if (ssl->buffers.inputBuffer.dynamicFlag)
01620         ShrinkInputBuffer(ssl, FORCED_FREE);
01621     if (ssl->buffers.outputBuffer.dynamicFlag)
01622         ShrinkOutputBuffer(ssl);
01623 #ifdef CYASSL_DTLS
01624     if (ssl->dtls_pool != NULL) {
01625         DtlsPoolReset(ssl);
01626         XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_NONE);
01627     }
01628     if (ssl->dtls_msg_list != NULL) {
01629         DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
01630         ssl->dtls_msg_list = NULL;
01631     }
01632     XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
01633     ssl->buffers.dtlsCtx.peer.sa = NULL;
01634 #endif
01635 #if defined(KEEP_PEER_CERT) || defined(GOAHEAD_WS)
01636     FreeX509(&ssl->peerCert);
01637 #endif
01638 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
01639     CyaSSL_BIO_free(ssl->biord);
01640     if (ssl->biord != ssl->biowr)        /* in case same as write */
01641         CyaSSL_BIO_free(ssl->biowr);
01642 #endif
01643 #ifdef HAVE_LIBZ
01644     FreeStreams(ssl);
01645 #endif
01646 #ifdef HAVE_ECC
01647     if (ssl->peerEccKey) {
01648         if (ssl->peerEccKeyPresent)
01649             ecc_free(ssl->peerEccKey);
01650         XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
01651     }
01652     if (ssl->peerEccDsaKey) {
01653         if (ssl->peerEccDsaKeyPresent)
01654             ecc_free(ssl->peerEccDsaKey);
01655         XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
01656     }
01657     if (ssl->eccTempKey) {
01658         if (ssl->eccTempKeyPresent)
01659             ecc_free(ssl->eccTempKey);
01660         XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
01661     }
01662     if (ssl->eccDsaKey) {
01663         if (ssl->eccDsaKeyPresent)
01664             ecc_free(ssl->eccDsaKey);
01665         XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
01666     }
01667 #endif
01668 #ifdef HAVE_TLS_EXTENSIONS
01669     TLSX_FreeAll(ssl->extensions);
01670 #endif
01671 }
01672 
01673 
01674 /* Free any handshake resources no longer needed */
01675 void FreeHandshakeResources(CYASSL* ssl)
01676 {
01677     /* input buffer */
01678     if (ssl->buffers.inputBuffer.dynamicFlag)
01679         ShrinkInputBuffer(ssl, NO_FORCED_FREE);
01680 
01681     /* suites */
01682     XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
01683     ssl->suites = NULL;
01684 
01685     /* RNG */
01686     if (ssl->specs.cipher_type == stream || ssl->options.tls1_1 == 0) {
01687         XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
01688         ssl->rng = NULL;
01689     }
01690 
01691 #ifdef CYASSL_DTLS
01692     /* DTLS_POOL */
01693     if (ssl->options.dtls && ssl->dtls_pool != NULL) {
01694         DtlsPoolReset(ssl);
01695         XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
01696         ssl->dtls_pool = NULL;
01697     }
01698 #endif
01699 
01700     /* arrays */
01701     if (ssl->options.saveArrays)
01702         FreeArrays(ssl, 1);
01703 
01704 #ifndef NO_RSA
01705     /* peerRsaKey */
01706     if (ssl->peerRsaKey) {
01707         FreeRsaKey(ssl->peerRsaKey);
01708         XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
01709         ssl->peerRsaKey = NULL;
01710     }
01711 #endif
01712 
01713 #ifdef HAVE_ECC
01714     if (ssl->peerEccKey)
01715     {
01716         if (ssl->peerEccKeyPresent) {
01717             ecc_free(ssl->peerEccKey);
01718             ssl->peerEccKeyPresent = 0;
01719         }
01720         XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
01721         ssl->peerEccKey = NULL;
01722     }
01723     if (ssl->peerEccDsaKey)
01724     {
01725         if (ssl->peerEccDsaKeyPresent) {
01726             ecc_free(ssl->peerEccDsaKey);
01727             ssl->peerEccDsaKeyPresent = 0;
01728         }
01729         XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
01730         ssl->peerEccDsaKey = NULL;
01731     }
01732     if (ssl->eccTempKey)
01733     {
01734         if (ssl->eccTempKeyPresent) {
01735             ecc_free(ssl->eccTempKey);
01736             ssl->eccTempKeyPresent = 0;
01737         }
01738         XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
01739         ssl->eccTempKey = NULL;
01740     }
01741     if (ssl->eccDsaKey)
01742     {
01743         if (ssl->eccDsaKeyPresent) {
01744             ecc_free(ssl->eccDsaKey);
01745             ssl->eccDsaKeyPresent = 0;
01746         }
01747         XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
01748         ssl->eccDsaKey = NULL;
01749     }
01750 #endif
01751 }
01752 
01753 
01754 void FreeSSL(CYASSL* ssl)
01755 {
01756     FreeSSL_Ctx(ssl->ctx);  /* will decrement and free underyling CTX if 0 */
01757     SSL_ResourceFree(ssl);
01758     XFREE(ssl, ssl->heap, DYNAMIC_TYPE_SSL);
01759 }
01760 
01761 
01762 #ifdef CYASSL_DTLS
01763 
01764 int DtlsPoolInit(CYASSL* ssl)
01765 {
01766     if (ssl->dtls_pool == NULL) {
01767         DtlsPool *pool = (DtlsPool*)XMALLOC(sizeof(DtlsPool),
01768                                              ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
01769         if (pool == NULL) {
01770             CYASSL_MSG("DTLS Buffer Pool Memory error");
01771             return MEMORY_E;
01772         }
01773         else {
01774             int i;
01775             
01776             for (i = 0; i < DTLS_POOL_SZ; i++) {
01777                 pool->buf[i].length = 0;
01778                 pool->buf[i].buffer = NULL;
01779             }
01780             pool->used = 0;
01781             ssl->dtls_pool = pool;
01782         }
01783     }
01784     return 0;
01785 }
01786 
01787 
01788 int DtlsPoolSave(CYASSL* ssl, const byte *src, int sz)
01789 {
01790     DtlsPool *pool = ssl->dtls_pool;
01791     if (pool != NULL && pool->used < DTLS_POOL_SZ) {
01792         buffer *pBuf = &pool->buf[pool->used];
01793         pBuf->buffer = (byte*)XMALLOC(sz, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
01794         if (pBuf->buffer == NULL) {
01795             CYASSL_MSG("DTLS Buffer Memory error");
01796             return MEMORY_ERROR;
01797         }
01798         XMEMCPY(pBuf->buffer, src, sz);
01799         pBuf->length = (word32)sz;
01800         pool->used++;
01801     }
01802     return 0;
01803 }
01804 
01805 
01806 void DtlsPoolReset(CYASSL* ssl)
01807 {
01808     DtlsPool *pool = ssl->dtls_pool;
01809     if (pool != NULL) {
01810         buffer *pBuf;
01811         int i, used;
01812 
01813         used = pool->used;
01814         for (i = 0, pBuf = &pool->buf[0]; i < used; i++, pBuf++) {
01815             XFREE(pBuf->buffer, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
01816             pBuf->buffer = NULL;
01817             pBuf->length = 0;
01818         }
01819         pool->used = 0;
01820     }
01821     ssl->dtls_timeout = ssl->dtls_timeout_init;
01822 }
01823 
01824 
01825 int DtlsPoolTimeout(CYASSL* ssl)
01826 {
01827     int result = -1;
01828     if (ssl->dtls_timeout <  ssl->dtls_timeout_max) {
01829         ssl->dtls_timeout *= DTLS_TIMEOUT_MULTIPLIER;
01830         result = 0;
01831     }
01832     return result;
01833 }
01834 
01835 
01836 int DtlsPoolSend(CYASSL* ssl)
01837 {
01838     int ret;
01839     DtlsPool *pool = ssl->dtls_pool;
01840 
01841     if (pool != NULL && pool->used > 0) {
01842         int i;
01843         for (i = 0; i < pool->used; i++) {
01844             int sendResult;
01845             buffer* buf = &pool->buf[i];
01846 
01847             DtlsRecordLayerHeader* dtls = (DtlsRecordLayerHeader*)buf->buffer;
01848 
01849             word16 message_epoch;
01850             ato16(dtls->epoch, &message_epoch);
01851             if (message_epoch == ssl->keys.dtls_epoch) {
01852                 /* Increment record sequence number on retransmitted handshake
01853                  * messages */
01854                 c32to48(ssl->keys.dtls_sequence_number, dtls->sequence_number);
01855                 ssl->keys.dtls_sequence_number++;
01856             }
01857             else {
01858                 /* The Finished message is sent with the next epoch, keep its
01859                  * sequence number */
01860             }
01861 
01862             if ((ret = CheckAvailableSize(ssl, buf->length)) != 0)
01863                 return ret;
01864 
01865             XMEMCPY(ssl->buffers.outputBuffer.buffer, buf->buffer, buf->length);
01866             ssl->buffers.outputBuffer.idx = 0;
01867             ssl->buffers.outputBuffer.length = buf->length;
01868 
01869             sendResult = SendBuffered(ssl);
01870             if (sendResult < 0) {
01871                 return sendResult;
01872             }
01873         }
01874     }
01875     return 0;
01876 }
01877 
01878 
01879 /* functions for managing DTLS datagram reordering */
01880 
01881 /* Need to allocate space for the handshake message header. The hashing
01882  * routines assume the message pointer is still within the buffer that
01883  * has the headers, and will include those headers in the hash. The store
01884  * routines need to take that into account as well. New will allocate
01885  * extra space for the headers. */
01886 DtlsMsg* DtlsMsgNew(word32 sz, void* heap)
01887 {
01888     DtlsMsg* msg = NULL;
01889     
01890     msg = (DtlsMsg*)XMALLOC(sizeof(DtlsMsg), heap, DYNAMIC_TYPE_DTLS_MSG);
01891 
01892     if (msg != NULL) {
01893         msg->buf = (byte*)XMALLOC(sz + DTLS_HANDSHAKE_HEADER_SZ,
01894                                                      heap, DYNAMIC_TYPE_NONE);
01895         if (msg->buf != NULL) {
01896             msg->next = NULL;
01897             msg->seq = 0;
01898             msg->sz = sz;
01899             msg->fragSz = 0;
01900             msg->msg = msg->buf + DTLS_HANDSHAKE_HEADER_SZ;
01901         }
01902         else {
01903             XFREE(msg, heap, DYNAMIC_TYPE_DTLS_MSG);
01904             msg = NULL;
01905         }
01906     }
01907 
01908     return msg;
01909 }
01910 
01911 void DtlsMsgDelete(DtlsMsg* item, void* heap)
01912 {
01913     (void)heap;
01914 
01915     if (item != NULL) {
01916         if (item->buf != NULL)
01917             XFREE(item->buf, heap, DYNAMIC_TYPE_NONE);
01918         XFREE(item, heap, DYNAMIC_TYPE_DTLS_MSG);
01919     }
01920 }
01921 
01922 
01923 void DtlsMsgListDelete(DtlsMsg* head, void* heap)
01924 {
01925     DtlsMsg* next;
01926     while (head) {
01927         next = head->next;
01928         DtlsMsgDelete(head, heap);
01929         head = next;
01930     }
01931 }
01932 
01933 
01934 void DtlsMsgSet(DtlsMsg* msg, word32 seq, const byte* data, byte type,
01935                                               word32 fragOffset, word32 fragSz)
01936 {
01937     if (msg != NULL && data != NULL && msg->fragSz <= msg->sz) {
01938         msg->seq = seq;
01939         msg->type = type;
01940         msg->fragSz += fragSz;
01941         /* If fragOffset is zero, this is either a full message that is out
01942          * of order, or the first fragment of a fragmented message. Copy the
01943          * handshake message header as well as the message data. */
01944         if (fragOffset == 0)
01945             XMEMCPY(msg->buf, data - DTLS_HANDSHAKE_HEADER_SZ,
01946                                             fragSz + DTLS_HANDSHAKE_HEADER_SZ);
01947         else {
01948             /* If fragOffet is non-zero, this is an additional fragment that
01949              * needs to be copied to its location in the message buffer. Also
01950              * copy the total size of the message over the fragment size. The
01951              * hash routines look at a defragmented message if it had actually
01952              * come across as a single handshake message. */
01953             XMEMCPY(msg->msg + fragOffset, data, fragSz);
01954             c32to24(msg->sz, msg->msg - DTLS_HANDSHAKE_FRAG_SZ);
01955         }
01956     }
01957 }
01958 
01959 
01960 DtlsMsg* DtlsMsgFind(DtlsMsg* head, word32 seq)
01961 {
01962     while (head != NULL && head->seq != seq) {
01963         head = head->next;
01964     }
01965     return head;
01966 }
01967 
01968 
01969 DtlsMsg* DtlsMsgStore(DtlsMsg* head, word32 seq, const byte* data, 
01970         word32 dataSz, byte type, word32 fragOffset, word32 fragSz, void* heap)
01971 {
01972 
01973     /* See if seq exists in the list. If it isn't in the list, make
01974      * a new item of size dataSz, copy fragSz bytes from data to msg->msg
01975      * starting at offset fragOffset, and add fragSz to msg->fragSz. If
01976      * the seq is in the list and it isn't full, copy fragSz bytes from
01977      * data to msg->msg starting at offset fragOffset, and add fragSz to
01978      * msg->fragSz. The new item should be inserted into the list in its
01979      * proper position.
01980      *
01981      * 1. Find seq in list, or where seq should go in list. If seq not in
01982      *    list, create new item and insert into list. Either case, keep
01983      *    pointer to item.
01984      * 2. If msg->fragSz + fragSz < sz, copy data to msg->msg at offset
01985      *    fragOffset. Add fragSz to msg->fragSz.
01986      */
01987 
01988     if (head != NULL) {
01989         DtlsMsg* cur = DtlsMsgFind(head, seq);
01990         if (cur == NULL) {
01991             cur = DtlsMsgNew(dataSz, heap);
01992             DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz);
01993             head = DtlsMsgInsert(head, cur);
01994         }
01995         else {
01996             DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz);
01997         }
01998     }
01999     else {
02000         head = DtlsMsgNew(dataSz, heap);
02001         DtlsMsgSet(head, seq, data, type, fragOffset, fragSz);
02002     }
02003 
02004     return head;
02005 }
02006 
02007 
02008 /* DtlsMsgInsert() is an in-order insert. */
02009 DtlsMsg* DtlsMsgInsert(DtlsMsg* head, DtlsMsg* item)
02010 {
02011     if (head == NULL || item->seq < head->seq) {
02012         item->next = head;
02013         head = item;
02014     }
02015     else if (head->next == NULL) {
02016         head->next = item;
02017     }
02018     else {
02019         DtlsMsg* cur = head->next;
02020         DtlsMsg* prev = head;
02021         while (cur) {
02022             if (item->seq < cur->seq) {
02023                 item->next = cur;
02024                 prev->next = item;
02025                 break;
02026             }
02027             prev = cur;
02028             cur = cur->next;
02029         }
02030         if (cur == NULL) {
02031             prev->next = item;
02032         }
02033     }
02034 
02035     return head;
02036 }
02037 
02038 #endif /* CYASSL_DTLS */
02039 
02040 #ifndef NO_OLD_TLS
02041 
02042 ProtocolVersion MakeSSLv3(void)
02043 {
02044     ProtocolVersion pv;
02045     pv.major = SSLv3_MAJOR;
02046     pv.minor = SSLv3_MINOR;
02047 
02048     return pv;
02049 }
02050 
02051 #endif /* NO_OLD_TLS */
02052 
02053 
02054 #ifdef CYASSL_DTLS
02055 
02056 ProtocolVersion MakeDTLSv1(void)
02057 {
02058     ProtocolVersion pv;
02059     pv.major = DTLS_MAJOR;
02060     pv.minor = DTLS_MINOR;
02061 
02062     return pv;
02063 }
02064 
02065 ProtocolVersion MakeDTLSv1_2(void)
02066 {
02067     ProtocolVersion pv;
02068     pv.major = DTLS_MAJOR;
02069     pv.minor = DTLSv1_2_MINOR;
02070 
02071     return pv;
02072 }
02073 
02074 #endif /* CYASSL_DTLS */
02075 
02076 
02077 
02078 
02079 #ifdef USE_WINDOWS_API 
02080 
02081     word32 LowResTimer(void)
02082     {
02083         static int           init = 0;
02084         static LARGE_INTEGER freq;
02085         LARGE_INTEGER        count;
02086     
02087         if (!init) {
02088             QueryPerformanceFrequency(&freq);
02089             init = 1;
02090         }
02091 
02092         QueryPerformanceCounter(&count);
02093 
02094         return (word32)(count.QuadPart / freq.QuadPart);
02095     }
02096 
02097 #elif defined(HAVE_RTP_SYS)
02098 
02099     #include "rtptime.h"
02100 
02101     word32 LowResTimer(void)
02102     {
02103         return (word32)rtp_get_system_sec();
02104     }
02105 
02106 
02107 #elif defined(MICRIUM)
02108 
02109     word32 LowResTimer(void)
02110     {
02111         NET_SECURE_OS_TICK  clk;
02112 
02113         #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
02114             clk = NetSecure_OS_TimeGet();
02115         #endif
02116         return (word32)clk;
02117     }
02118 
02119 
02120 #elif defined(MICROCHIP_TCPIP_V5)
02121 
02122     word32 LowResTimer(void)
02123     {
02124         return (word32) TickGet();
02125     }
02126 
02127 
02128 #elif defined(MICROCHIP_TCPIP)
02129 
02130     word32 LowResTimer(void)
02131     {
02132         return (word32) SYS_TICK_Get();
02133     }
02134 
02135 
02136 #elif defined(USER_TICKS)
02137 #if 0
02138     word32 LowResTimer(void)
02139     {
02140         /*
02141         write your own clock tick function if don't want time(0)
02142         needs second accuracy but doesn't have to correlated to EPOCH
02143         */
02144     }
02145 #endif
02146 #else /* !USE_WINDOWS_API && !HAVE_RTP_SYS && !MICRIUM && !USER_TICKS */
02147 
02148     #include <time.h>
02149 
02150     word32 LowResTimer(void)
02151     {
02152         return (word32)time(0); 
02153     }
02154 
02155 
02156 #endif /* USE_WINDOWS_API */
02157 
02158 
02159 /* add output to md5 and sha handshake hashes, exclude record header */
02160 static void HashOutput(CYASSL* ssl, const byte* output, int sz, int ivSz)
02161 {
02162     const byte* adj = output + RECORD_HEADER_SZ + ivSz;
02163     sz -= RECORD_HEADER_SZ;
02164     
02165 #ifdef CYASSL_DTLS
02166     if (ssl->options.dtls) {
02167         adj += DTLS_RECORD_EXTRA;
02168         sz  -= DTLS_RECORD_EXTRA;
02169     }
02170 #endif
02171 #ifndef NO_OLD_TLS
02172 #ifndef NO_SHA
02173     ShaUpdate(&ssl->hashSha, adj, sz);
02174 #endif
02175 #ifndef NO_MD5
02176     Md5Update(&ssl->hashMd5, adj, sz);
02177 #endif
02178 #endif
02179 
02180     if (IsAtLeastTLSv1_2(ssl)) {
02181 #ifndef NO_SHA256
02182         Sha256Update(&ssl->hashSha256, adj, sz);
02183 #endif
02184 #ifdef CYASSL_SHA384
02185         Sha384Update(&ssl->hashSha384, adj, sz);
02186 #endif
02187     }
02188 }
02189 
02190 
02191 /* add input to md5 and sha handshake hashes, include handshake header */
02192 static void HashInput(CYASSL* ssl, const byte* input, int sz)
02193 {
02194     const byte* adj = input - HANDSHAKE_HEADER_SZ;
02195     sz += HANDSHAKE_HEADER_SZ;
02196     
02197 #ifdef CYASSL_DTLS
02198     if (ssl->options.dtls) {
02199         adj -= DTLS_HANDSHAKE_EXTRA;
02200         sz  += DTLS_HANDSHAKE_EXTRA;
02201     }
02202 #endif
02203 
02204 #ifndef NO_OLD_TLS
02205 #ifndef NO_SHA
02206     ShaUpdate(&ssl->hashSha, adj, sz);
02207 #endif
02208 #ifndef NO_MD5
02209     Md5Update(&ssl->hashMd5, adj, sz);
02210 #endif
02211 #endif
02212 
02213     if (IsAtLeastTLSv1_2(ssl)) {
02214 #ifndef NO_SHA256
02215         Sha256Update(&ssl->hashSha256, adj, sz);
02216 #endif
02217 #ifdef CYASSL_SHA384
02218         Sha384Update(&ssl->hashSha384, adj, sz);
02219 #endif
02220     }
02221 }
02222 
02223 
02224 /* add record layer header for message */
02225 static void AddRecordHeader(byte* output, word32 length, byte type, CYASSL* ssl)
02226 {
02227     RecordLayerHeader* rl;
02228   
02229     /* record layer header */
02230     rl = (RecordLayerHeader*)output;
02231     rl->type    = type;
02232     rl->pvMajor = ssl->version.major;       /* type and version same in each */
02233     rl->pvMinor = ssl->version.minor;
02234 
02235     if (!ssl->options.dtls)
02236         c16toa((word16)length, rl->length);
02237     else {
02238 #ifdef CYASSL_DTLS
02239         DtlsRecordLayerHeader* dtls;
02240     
02241         /* dtls record layer header extensions */
02242         dtls = (DtlsRecordLayerHeader*)output;
02243         c16toa(ssl->keys.dtls_epoch, dtls->epoch);
02244         c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number);
02245         c16toa((word16)length, dtls->length);
02246 #endif
02247     }
02248 }
02249 
02250 
02251 /* add handshake header for message */
02252 static void AddHandShakeHeader(byte* output, word32 length, byte type,
02253                                CYASSL* ssl)
02254 {
02255     HandShakeHeader* hs;
02256     (void)ssl;
02257  
02258     /* handshake header */
02259     hs = (HandShakeHeader*)output;
02260     hs->type = type;
02261     c32to24(length, hs->length);         /* type and length same for each */
02262 #ifdef CYASSL_DTLS
02263     if (ssl->options.dtls) {
02264         DtlsHandShakeHeader* dtls;
02265     
02266         /* dtls handshake header extensions */
02267         dtls = (DtlsHandShakeHeader*)output;
02268         c16toa(ssl->keys.dtls_handshake_number++, dtls->message_seq);
02269         c32to24(0, dtls->fragment_offset);
02270         c32to24(length, dtls->fragment_length);
02271     }
02272 #endif
02273 }
02274 
02275 
02276 /* add both headers for handshake message */
02277 static void AddHeaders(byte* output, word32 length, byte type, CYASSL* ssl)
02278 {
02279     if (!ssl->options.dtls) {
02280         AddRecordHeader(output, length + HANDSHAKE_HEADER_SZ, handshake, ssl);
02281         AddHandShakeHeader(output + RECORD_HEADER_SZ, length, type, ssl);
02282     }
02283 #ifdef CYASSL_DTLS
02284     else  {
02285         AddRecordHeader(output, length+DTLS_HANDSHAKE_HEADER_SZ, handshake,ssl);
02286         AddHandShakeHeader(output + DTLS_RECORD_HEADER_SZ, length, type, ssl);
02287     }
02288 #endif
02289 }
02290 
02291 
02292 /* return bytes received, -1 on error */
02293 static int Receive(CYASSL* ssl, byte* buf, word32 sz)
02294 {
02295     int recvd;
02296 
02297     if (ssl->ctx->CBIORecv == NULL) {
02298         CYASSL_MSG("Your IO Recv callback is null, please set");
02299         return -1;
02300     }
02301 
02302 retry:
02303     recvd = ssl->ctx->CBIORecv(ssl, (char *)buf, (int)sz, ssl->IOCB_ReadCtx);
02304     if (recvd < 0)
02305         switch (recvd) {
02306             case CYASSL_CBIO_ERR_GENERAL:        /* general/unknown error */
02307                 return -1;
02308 
02309             case CYASSL_CBIO_ERR_WANT_READ:      /* want read, would block */
02310                 return WANT_READ;
02311 
02312             case CYASSL_CBIO_ERR_CONN_RST:       /* connection reset */
02313                 #ifdef USE_WINDOWS_API
02314                 if (ssl->options.dtls) {
02315                     goto retry;
02316                 }
02317                 #endif
02318                 ssl->options.connReset = 1;
02319                 return -1;
02320 
02321             case CYASSL_CBIO_ERR_ISR:            /* interrupt */
02322                 /* see if we got our timeout */
02323                 #ifdef CYASSL_CALLBACKS
02324                     if (ssl->toInfoOn) {
02325                         struct itimerval timeout;
02326                         getitimer(ITIMER_REAL, &timeout);
02327                         if (timeout.it_value.tv_sec == 0 && 
02328                                                 timeout.it_value.tv_usec == 0) {
02329                             XSTRNCPY(ssl->timeoutInfo.timeoutName,
02330                                     "recv() timeout", MAX_TIMEOUT_NAME_SZ);
02331                             CYASSL_MSG("Got our timeout"); 
02332                             return WANT_READ;
02333                         }
02334                     }
02335                 #endif
02336                 goto retry;
02337 
02338             case CYASSL_CBIO_ERR_CONN_CLOSE:     /* peer closed connection */
02339                 ssl->options.isClosed = 1;
02340                 return -1;
02341 
02342             case CYASSL_CBIO_ERR_TIMEOUT:
02343 #ifdef CYASSL_DTLS
02344                 if (DtlsPoolTimeout(ssl) == 0 && DtlsPoolSend(ssl) == 0)
02345                     goto retry;
02346                 else
02347 #endif
02348                     return -1;
02349 
02350             default:
02351                 return recvd;
02352         }
02353 
02354     return recvd;
02355 }
02356 
02357 
02358 /* Switch dynamic output buffer back to static, buffer is assumed clear */
02359 void ShrinkOutputBuffer(CYASSL* ssl)
02360 {
02361     CYASSL_MSG("Shrinking output buffer\n");
02362     XFREE(ssl->buffers.outputBuffer.buffer - ssl->buffers.outputBuffer.offset,
02363           ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
02364     ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
02365     ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
02366     ssl->buffers.outputBuffer.dynamicFlag = 0;
02367     ssl->buffers.outputBuffer.offset      = 0;
02368 }
02369 
02370 
02371 /* Switch dynamic input buffer back to static, keep any remaining input */
02372 /* forced free means cleaning up */
02373 void ShrinkInputBuffer(CYASSL* ssl, int forcedFree)
02374 {
02375     int usedLength = ssl->buffers.inputBuffer.length -
02376                      ssl->buffers.inputBuffer.idx;
02377     if (!forcedFree && usedLength > STATIC_BUFFER_LEN)
02378         return;
02379 
02380     CYASSL_MSG("Shrinking input buffer\n");
02381 
02382     if (!forcedFree && usedLength)
02383         XMEMCPY(ssl->buffers.inputBuffer.staticBuffer,
02384                ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
02385                usedLength);
02386 
02387     XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
02388           ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
02389     ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
02390     ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
02391     ssl->buffers.inputBuffer.dynamicFlag = 0;
02392     ssl->buffers.inputBuffer.offset      = 0;
02393     ssl->buffers.inputBuffer.idx = 0;
02394     ssl->buffers.inputBuffer.length = usedLength;
02395 }
02396 
02397 
02398 int SendBuffered(CYASSL* ssl)
02399 {
02400     if (ssl->ctx->CBIOSend == NULL) {
02401         CYASSL_MSG("Your IO Send callback is null, please set");
02402         return SOCKET_ERROR_E;
02403     }
02404 
02405     while (ssl->buffers.outputBuffer.length > 0) {
02406         int sent = ssl->ctx->CBIOSend(ssl,
02407                                       (char*)ssl->buffers.outputBuffer.buffer +
02408                                       ssl->buffers.outputBuffer.idx,
02409                                       (int)ssl->buffers.outputBuffer.length,
02410                                       ssl->IOCB_WriteCtx);
02411         if (sent < 0) {
02412             switch (sent) {
02413 
02414                 case CYASSL_CBIO_ERR_WANT_WRITE:        /* would block */
02415                     return WANT_WRITE;
02416 
02417                 case CYASSL_CBIO_ERR_CONN_RST:          /* connection reset */
02418                     ssl->options.connReset = 1;
02419                     break;
02420 
02421                 case CYASSL_CBIO_ERR_ISR:               /* interrupt */
02422                     /* see if we got our timeout */
02423                     #ifdef CYASSL_CALLBACKS
02424                         if (ssl->toInfoOn) {
02425                             struct itimerval timeout;
02426                             getitimer(ITIMER_REAL, &timeout);
02427                             if (timeout.it_value.tv_sec == 0 && 
02428                                                 timeout.it_value.tv_usec == 0) {
02429                                 XSTRNCPY(ssl->timeoutInfo.timeoutName,
02430                                         "send() timeout", MAX_TIMEOUT_NAME_SZ);
02431                                 CYASSL_MSG("Got our timeout"); 
02432                                 return WANT_WRITE;
02433                             }
02434                         }
02435                     #endif
02436                     continue;
02437 
02438                 case CYASSL_CBIO_ERR_CONN_CLOSE: /* epipe / conn closed */
02439                     ssl->options.connReset = 1;  /* treat same as reset */
02440                     break;
02441 
02442                 default:
02443                     return SOCKET_ERROR_E;
02444             }
02445 
02446             return SOCKET_ERROR_E;
02447         }
02448 
02449         ssl->buffers.outputBuffer.idx += sent;
02450         ssl->buffers.outputBuffer.length -= sent;
02451     }
02452       
02453     ssl->buffers.outputBuffer.idx = 0;
02454 
02455     if (ssl->buffers.outputBuffer.dynamicFlag)
02456         ShrinkOutputBuffer(ssl);
02457 
02458     return 0;
02459 }
02460 
02461 
02462 /* Grow the output buffer */
02463 static INLINE int GrowOutputBuffer(CYASSL* ssl, int size)
02464 {
02465     byte* tmp;
02466     byte  hdrSz = ssl->options.dtls ? DTLS_RECORD_HEADER_SZ :
02467                                       RECORD_HEADER_SZ; 
02468     byte  align = CYASSL_GENERAL_ALIGNMENT;
02469     /* the encrypted data will be offset from the front of the buffer by
02470        the header, if the user wants encrypted alignment they need
02471        to define their alignment requirement */
02472 
02473     if (align) {
02474        while (align < hdrSz)
02475            align *= 2;
02476     }
02477 
02478     tmp = (byte*) XMALLOC(size + ssl->buffers.outputBuffer.length + align,
02479                           ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
02480     CYASSL_MSG("growing output buffer\n");
02481    
02482     if (!tmp) return MEMORY_E;
02483     if (align)
02484         tmp += align - hdrSz;
02485 
02486     if (ssl->buffers.outputBuffer.length)
02487         XMEMCPY(tmp, ssl->buffers.outputBuffer.buffer,
02488                ssl->buffers.outputBuffer.length);
02489 
02490     if (ssl->buffers.outputBuffer.dynamicFlag)
02491         XFREE(ssl->buffers.outputBuffer.buffer -
02492               ssl->buffers.outputBuffer.offset, ssl->heap,
02493               DYNAMIC_TYPE_OUT_BUFFER);
02494     ssl->buffers.outputBuffer.dynamicFlag = 1;
02495     if (align)
02496         ssl->buffers.outputBuffer.offset = align - hdrSz;
02497     else
02498         ssl->buffers.outputBuffer.offset = 0;
02499     ssl->buffers.outputBuffer.buffer = tmp;
02500     ssl->buffers.outputBuffer.bufferSize = size +
02501                                            ssl->buffers.outputBuffer.length; 
02502     return 0;
02503 }
02504 
02505 
02506 /* Grow the input buffer, should only be to read cert or big app data */
02507 int GrowInputBuffer(CYASSL* ssl, int size, int usedLength)
02508 {
02509     byte* tmp;
02510     byte  hdrSz = DTLS_RECORD_HEADER_SZ;
02511     byte  align = ssl->options.dtls ? CYASSL_GENERAL_ALIGNMENT : 0;
02512     /* the encrypted data will be offset from the front of the buffer by
02513        the dtls record header, if the user wants encrypted alignment they need
02514        to define their alignment requirement. in tls we read record header
02515        to get size of record and put actual data back at front, so don't need */
02516 
02517     if (align) {
02518        while (align < hdrSz)
02519            align *= 2;
02520     }
02521     tmp = (byte*) XMALLOC(size + usedLength + align, ssl->heap,
02522                           DYNAMIC_TYPE_IN_BUFFER);
02523     CYASSL_MSG("growing input buffer\n");
02524    
02525     if (!tmp) return MEMORY_E;
02526     if (align)
02527         tmp += align - hdrSz;
02528 
02529     if (usedLength)
02530         XMEMCPY(tmp, ssl->buffers.inputBuffer.buffer +
02531                     ssl->buffers.inputBuffer.idx, usedLength);
02532 
02533     if (ssl->buffers.inputBuffer.dynamicFlag)
02534         XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
02535               ssl->heap,DYNAMIC_TYPE_IN_BUFFER);
02536 
02537     ssl->buffers.inputBuffer.dynamicFlag = 1;
02538     if (align)
02539         ssl->buffers.inputBuffer.offset = align - hdrSz;
02540     else
02541         ssl->buffers.inputBuffer.offset = 0;
02542     ssl->buffers.inputBuffer.buffer = tmp;
02543     ssl->buffers.inputBuffer.bufferSize = size + usedLength;
02544     ssl->buffers.inputBuffer.idx    = 0;
02545     ssl->buffers.inputBuffer.length = usedLength;
02546 
02547     return 0;
02548 }
02549 
02550 
02551 /* check available size into output buffer, make room if needed */
02552 int CheckAvailableSize(CYASSL *ssl, int size)
02553 {
02554     if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length
02555                                              < (word32)size) {
02556         if (GrowOutputBuffer(ssl, size) < 0)
02557             return MEMORY_E;
02558     }
02559 
02560     return 0;
02561 }
02562 
02563 
02564 /* do all verify and sanity checks on record header */
02565 static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
02566                            RecordLayerHeader* rh, word16 *size)
02567 {
02568     if (!ssl->options.dtls) {
02569         XMEMCPY(rh, input + *inOutIdx, RECORD_HEADER_SZ);
02570         *inOutIdx += RECORD_HEADER_SZ;
02571         ato16(rh->length, size);
02572     }
02573     else {
02574 #ifdef CYASSL_DTLS
02575         /* type and version in same sport */
02576         XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
02577         *inOutIdx += ENUM_LEN + VERSION_SZ;
02578         ato16(input + *inOutIdx, &ssl->keys.dtls_peer_epoch);
02579         *inOutIdx += 4; /* advance past epoch, skip first 2 seq bytes for now */
02580         ato32(input + *inOutIdx, &ssl->keys.dtls_peer_sequence_number);
02581         *inOutIdx += 4;  /* advance past rest of seq */
02582         ato16(input + *inOutIdx, size);
02583         *inOutIdx += LENGTH_SZ;
02584 #endif
02585     }
02586 
02587     /* catch version mismatch */
02588     if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor){
02589         if (ssl->options.side == SERVER_END &&
02590             ssl->options.acceptState == ACCEPT_BEGIN)
02591             CYASSL_MSG("Client attempting to connect with different version"); 
02592         else if (ssl->options.side == CLIENT_END && ssl->options.downgrade &&
02593                  ssl->options.connectState < FIRST_REPLY_DONE)
02594             CYASSL_MSG("Server attempting to accept with different version"); 
02595         else {
02596             CYASSL_MSG("SSL version error"); 
02597             return VERSION_ERROR;              /* only use requested version */
02598         }
02599     }
02600 #if 0
02601     /* Instead of this, check the datagram against the sliding window of
02602      * received datagram goodness. */
02603 #ifdef CYASSL_DTLS
02604     /* If DTLS, check the sequence number against expected. If out of
02605      * order, drop the record. Allows newer records in and resets the
02606      * expected to the next record. */
02607     if (ssl->options.dtls) {
02608         if ((ssl->keys.dtls_expected_peer_epoch ==
02609                                         ssl->keys.dtls_peer_epoch) &&
02610                 (ssl->keys.dtls_peer_sequence_number >=
02611                                 ssl->keys.dtls_expected_peer_sequence_number)) {
02612             ssl->keys.dtls_expected_peer_sequence_number =
02613                             ssl->keys.dtls_peer_sequence_number + 1;
02614         }
02615         else {
02616             return SEQUENCE_ERROR;
02617         }
02618     }
02619 #endif
02620 #endif
02621     /* record layer length check */
02622     if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
02623         return LENGTH_ERROR;
02624 
02625     /* verify record type here as well */
02626     switch ((enum ContentType)rh->type) {
02627         case handshake:
02628         case change_cipher_spec:
02629         case application_data:
02630         case alert:
02631             break;
02632         case no_type:
02633         default:
02634             CYASSL_MSG("Unknown Record Type"); 
02635             return UNKNOWN_RECORD_TYPE;
02636     }
02637 
02638     /* haven't decrypted this record yet */
02639     ssl->keys.decryptedCur = 0;
02640 
02641     return 0;
02642 }
02643 
02644 
02645 static int GetHandShakeHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
02646                               byte *type, word32 *size)
02647 {
02648     const byte *ptr = input + *inOutIdx;
02649     (void)ssl;
02650     *inOutIdx += HANDSHAKE_HEADER_SZ;
02651     
02652     *type = ptr[0];
02653     c24to32(&ptr[1], size);
02654 
02655     return 0;
02656 }
02657 
02658 
02659 #ifdef CYASSL_DTLS
02660 static int GetDtlsHandShakeHeader(CYASSL* ssl, const byte* input,
02661                                     word32* inOutIdx, byte *type, word32 *size,
02662                                     word32 *fragOffset, word32 *fragSz)
02663 {
02664     word32 idx = *inOutIdx;
02665 
02666     *inOutIdx += HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA;
02667     
02668     *type = input[idx++];
02669     c24to32(input + idx, size);
02670     idx += BYTE3_LEN;
02671 
02672     ato16(input + idx, &ssl->keys.dtls_peer_handshake_number);
02673     idx += DTLS_HANDSHAKE_SEQ_SZ;
02674 
02675     c24to32(input + idx, fragOffset);
02676     idx += DTLS_HANDSHAKE_FRAG_SZ;
02677     c24to32(input + idx, fragSz);
02678 
02679     return 0;
02680 }
02681 #endif
02682 
02683 
02684 #ifndef NO_OLD_TLS
02685 /* fill with MD5 pad size since biggest required */
02686 static const byte PAD1[PAD_MD5] = 
02687                               { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
02688                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
02689                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
02690                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
02691                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
02692                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
02693                               };
02694 static const byte PAD2[PAD_MD5] =
02695                               { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
02696                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
02697                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
02698                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
02699                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
02700                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
02701                               };
02702 
02703 /* calculate MD5 hash for finished */
02704 static void BuildMD5(CYASSL* ssl, Hashes* hashes, const byte* sender)
02705 {
02706     byte md5_result[MD5_DIGEST_SIZE];
02707 
02708     /* make md5 inner */    
02709     Md5Update(&ssl->hashMd5, sender, SIZEOF_SENDER);
02710     Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
02711     Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
02712     Md5Final(&ssl->hashMd5, md5_result);
02713 
02714     /* make md5 outer */
02715     Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
02716     Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
02717     Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
02718 
02719     Md5Final(&ssl->hashMd5, hashes->md5);
02720 }
02721 
02722 
02723 /* calculate SHA hash for finished */
02724 static void BuildSHA(CYASSL* ssl, Hashes* hashes, const byte* sender)
02725 {
02726     byte sha_result[SHA_DIGEST_SIZE];
02727 
02728     /* make sha inner */
02729     ShaUpdate(&ssl->hashSha, sender, SIZEOF_SENDER);
02730     ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
02731     ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
02732     ShaFinal(&ssl->hashSha, sha_result);
02733 
02734     /* make sha outer */
02735     ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
02736     ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
02737     ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
02738 
02739     ShaFinal(&ssl->hashSha, hashes->sha);
02740 }
02741 #endif
02742 
02743 
02744 static void BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
02745 {
02746     /* store current states, building requires get_digest which resets state */
02747 #ifndef NO_OLD_TLS
02748 #ifndef NO_MD5
02749     Md5 md5 = ssl->hashMd5;
02750 #endif
02751 #ifndef NO_SHA
02752     Sha sha = ssl->hashSha;
02753 #endif
02754 #endif
02755 #ifndef NO_SHA256
02756     Sha256 sha256 = ssl->hashSha256;
02757 #endif
02758 #ifdef CYASSL_SHA384
02759     Sha384 sha384 = ssl->hashSha384;
02760 #endif
02761 
02762 #ifndef NO_TLS
02763     if (ssl->options.tls) {
02764         BuildTlsFinished(ssl, hashes, sender);
02765     }
02766 #endif
02767 #ifndef NO_OLD_TLS
02768     if (!ssl->options.tls) {
02769         BuildMD5(ssl, hashes, sender);
02770         BuildSHA(ssl, hashes, sender);
02771     }
02772 #endif
02773     
02774     /* restore */
02775 #ifndef NO_OLD_TLS
02776     #ifndef NO_MD5
02777         ssl->hashMd5 = md5;
02778     #endif
02779     #ifndef NO_SHA
02780     ssl->hashSha = sha;
02781     #endif
02782 #endif
02783     if (IsAtLeastTLSv1_2(ssl)) {
02784     #ifndef NO_SHA256
02785         ssl->hashSha256 = sha256;
02786     #endif
02787     #ifdef CYASSL_SHA384
02788         ssl->hashSha384 = sha384;
02789     #endif
02790     }
02791 }
02792 
02793 
02794 #ifndef NO_CERTS
02795 
02796 
02797 /* Match names with wildcards, each wildcard can represent a single name
02798    component or fragment but not mulitple names, i.e.,
02799    *.z.com matches y.z.com but not x.y.z.com 
02800 
02801    return 1 on success */
02802 static int MatchDomainName(const char* pattern, int len, const char* str)
02803 {
02804     char p, s;
02805 
02806     if (pattern == NULL || str == NULL || len <= 0)
02807         return 0;
02808 
02809     while (len > 0 && (p = (char)(*pattern++))) {
02810         if (p == '*') {
02811             while (--len > 0 && (p = (char)(*pattern++)) == '*')
02812                 ;
02813 
02814             if (len == 0)
02815                 p = '\0';
02816 
02817             while ( (s = (char)(*str)) != '\0') {
02818                 if (s == p)
02819                     break;
02820                 if (s == '.')
02821                     return 0;
02822                 str++;
02823             }
02824         }
02825         else {
02826             if (p != (char)(*str))
02827                 return 0;
02828         }
02829 
02830         if (*str != '\0')
02831             str++;
02832 
02833         if (len > 0)
02834             len--;
02835     }
02836 
02837     return *str == '\0';
02838 }
02839 
02840 
02841 /* try to find an altName match to domain, return 1 on success */
02842 static int CheckAltNames(DecodedCert* dCert, char* domain)
02843 {
02844     int        match = 0;
02845     DNS_entry* altName = NULL;
02846 
02847     CYASSL_MSG("Checking AltNames");
02848 
02849     if (dCert)
02850         altName = dCert->altNames;
02851 
02852     while (altName) {
02853         CYASSL_MSG("    individual AltName check");
02854 
02855         if (MatchDomainName(altName->name,(int)XSTRLEN(altName->name), domain)){
02856             match = 1;
02857             break;
02858         }
02859            
02860         altName = altName->next;
02861     }
02862 
02863     return match;
02864 }
02865 
02866 
02867 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
02868 
02869 /* Copy parts X509 needs from Decoded cert, 0 on success */
02870 int CopyDecodedToX509(CYASSL_X509* x509, DecodedCert* dCert)
02871 {
02872     int ret = 0;
02873 
02874     if (x509 == NULL || dCert == NULL)
02875         return BAD_FUNC_ARG;
02876 
02877     XSTRNCPY(x509->issuer.name, dCert->issuer, ASN_NAME_MAX);
02878     x509->issuer.name[ASN_NAME_MAX - 1] = '\0';
02879     x509->issuer.sz = (int)XSTRLEN(x509->issuer.name) + 1;
02880 
02881     XSTRNCPY(x509->subject.name, dCert->subject, ASN_NAME_MAX);
02882     x509->subject.name[ASN_NAME_MAX - 1] = '\0';
02883     x509->subject.sz = (int)XSTRLEN(x509->subject.name) + 1;
02884 
02885     XMEMCPY(x509->serial, dCert->serial, EXTERNAL_SERIAL_SIZE);
02886     x509->serialSz = dCert->serialSz;
02887     if (dCert->subjectCNLen < ASN_NAME_MAX) {
02888         XMEMCPY(x509->subjectCN, dCert->subjectCN, dCert->subjectCNLen);
02889         x509->subjectCN[dCert->subjectCNLen] = '\0';
02890     }
02891     else
02892         x509->subjectCN[0] = '\0';
02893 
02894     /* store cert for potential retrieval */
02895     x509->derCert.buffer = (byte*)XMALLOC(dCert->maxIdx, NULL,
02896                                           DYNAMIC_TYPE_CERT);
02897     if (x509->derCert.buffer == NULL) {
02898         ret = MEMORY_E;
02899     }
02900     else {
02901         XMEMCPY(x509->derCert.buffer, dCert->source, dCert->maxIdx);
02902         x509->derCert.length = dCert->maxIdx;
02903     }
02904 
02905     x509->altNames     = dCert->altNames;
02906     dCert->altNames    = NULL;     /* takes ownership */
02907     x509->altNamesNext = x509->altNames;  /* index hint */
02908 
02909     return ret;
02910 }
02911 
02912 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
02913 
02914 
02915 static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
02916 {
02917     word32 listSz, i = *inOutIdx;
02918     int    ret = 0;
02919     int    anyError = 0;
02920     int    totalCerts = 0;    /* number of certs in certs buffer */
02921     int    count;
02922     char   domain[ASN_NAME_MAX];
02923     buffer certs[MAX_CHAIN_DEPTH];
02924 
02925     #ifdef CYASSL_CALLBACKS
02926         if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
02927         if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo);
02928     #endif
02929     c24to32(&input[i], &listSz);
02930     i += CERT_HEADER_SZ;
02931 
02932     CYASSL_MSG("Loading peer's cert chain");
02933     /* first put cert chain into buffer so can verify top down
02934        we're sent bottom up */
02935     while (listSz) {
02936         /* cert size */
02937         word32 certSz;
02938 
02939         if (totalCerts >= MAX_CHAIN_DEPTH)
02940             return MAX_CHAIN_ERROR;
02941 
02942         c24to32(&input[i], &certSz);
02943         i += CERT_HEADER_SZ;
02944        
02945         if (listSz > MAX_RECORD_SIZE || certSz > MAX_RECORD_SIZE)
02946             return BUFFER_E;
02947 
02948         certs[totalCerts].length = certSz;
02949         certs[totalCerts].buffer = input + i;
02950 
02951 #ifdef SESSION_CERTS
02952         if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
02953                                        certSz < MAX_X509_SIZE) {
02954             ssl->session.chain.certs[ssl->session.chain.count].length = certSz;
02955             XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer,
02956                     input + i, certSz);
02957             ssl->session.chain.count++;
02958         } else {
02959             CYASSL_MSG("Couldn't store chain cert for session");
02960         }
02961 #endif
02962 
02963         i += certSz;
02964         listSz -= certSz + CERT_HEADER_SZ;
02965 
02966         totalCerts++;
02967         CYASSL_MSG("    Put another cert into chain");
02968     }
02969 
02970     count = totalCerts;
02971 
02972     /* verify up to peer's first */
02973     while (count > 1) {
02974         buffer myCert = certs[count - 1];
02975         DecodedCert dCert;
02976         byte* subjectHash;
02977 
02978         InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
02979         ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
02980                                 ssl->ctx->cm);
02981         #ifndef NO_SKID
02982             subjectHash = dCert.extSubjKeyId;
02983         #else
02984             subjectHash = dCert.subjectHash;
02985         #endif
02986 
02987         if (ret == 0 && dCert.isCA == 0) {
02988             CYASSL_MSG("Chain cert is not a CA, not adding as one");
02989         }
02990         else if (ret == 0 && ssl->options.verifyNone) {
02991             CYASSL_MSG("Chain cert not verified by option, not adding as CA");
02992         }
02993         else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, subjectHash)) {
02994             buffer add;
02995             add.length = myCert.length;
02996             add.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
02997                                         DYNAMIC_TYPE_CA);
02998             CYASSL_MSG("Adding CA from chain");
02999 
03000             if (add.buffer == NULL)
03001                 return MEMORY_E;
03002             XMEMCPY(add.buffer, myCert.buffer, myCert.length);
03003 
03004             ret = AddCA(ssl->ctx->cm, add, CYASSL_CHAIN_CA,
03005                         ssl->ctx->verifyPeer);
03006             if (ret == 1) ret = 0;   /* SSL_SUCCESS for external */
03007         }
03008         else if (ret != 0) {
03009             CYASSL_MSG("Failed to verify CA from chain");
03010         }
03011         else {
03012             CYASSL_MSG("Verified CA from chain and already had it");
03013         }
03014 
03015 #ifdef HAVE_CRL
03016         if (ret == 0 && ssl->ctx->cm->crlEnabled && ssl->ctx->cm->crlCheckAll) {
03017             CYASSL_MSG("Doing Non Leaf CRL check");
03018             ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert);
03019 
03020             if (ret != 0) {
03021                 CYASSL_MSG("\tCRL check not ok");
03022             }
03023         }
03024 #endif /* HAVE_CRL */
03025 
03026         if (ret != 0 && anyError == 0)
03027             anyError = ret;   /* save error from last time */
03028 
03029         FreeDecodedCert(&dCert);
03030         count--;
03031     }
03032 
03033     /* peer's, may not have one if blank client cert sent by TLSv1.2 */
03034     if (count) {
03035         buffer myCert = certs[0];
03036         DecodedCert dCert;
03037         int         fatal = 0;
03038 
03039         CYASSL_MSG("Verifying Peer's cert");
03040 
03041         InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
03042         ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
03043                                 ssl->ctx->cm);
03044         if (ret == 0) {
03045             CYASSL_MSG("Verified Peer's cert");
03046             fatal = 0;
03047         }
03048         else if (ret == ASN_PARSE_E) {
03049             CYASSL_MSG("Got Peer cert ASN PARSE ERROR, fatal");
03050             fatal = 1;
03051         }
03052         else {
03053             CYASSL_MSG("Failed to verify Peer's cert");
03054             if (ssl->verifyCallback) {
03055                 CYASSL_MSG("\tCallback override available, will continue");
03056                 fatal = 0;
03057             }
03058             else {
03059                 CYASSL_MSG("\tNo callback override available, fatal");
03060                 fatal = 1;
03061             }
03062         }
03063 
03064 #ifdef HAVE_OCSP
03065         if (fatal == 0) {
03066             ret = CyaSSL_OCSP_Lookup_Cert(&ssl->ctx->ocsp, &dCert);
03067             if (ret != 0) {
03068                 CYASSL_MSG("\tOCSP Lookup not ok");
03069                 fatal = 0;
03070             }
03071         }
03072 #endif
03073 
03074 #ifdef HAVE_CRL
03075         if (fatal == 0 && ssl->ctx->cm->crlEnabled) {
03076             int doCrlLookup = 1;
03077 
03078             #ifdef HAVE_OCSP
03079             if (ssl->ctx->ocsp.enabled) {
03080                 doCrlLookup = (ret == OCSP_CERT_UNKNOWN);
03081             }
03082             #endif /* HAVE_OCSP */
03083 
03084             if (doCrlLookup) {
03085                 CYASSL_MSG("Doing Leaf CRL check");
03086                 ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert);
03087     
03088                 if (ret != 0) {
03089                     CYASSL_MSG("\tCRL check not ok");
03090                     fatal = 0;
03091                 }
03092             }
03093         }
03094 
03095 #endif /* HAVE_CRL */
03096 
03097 #ifdef KEEP_PEER_CERT
03098         {
03099         /* set X509 format for peer cert even if fatal */
03100         int copyRet = CopyDecodedToX509(&ssl->peerCert, &dCert);
03101         if (copyRet == MEMORY_E)
03102             fatal = 1;
03103         }
03104 #endif    
03105 
03106         if (fatal) {
03107             FreeDecodedCert(&dCert);
03108             ssl->error = ret;
03109             return ret;
03110         }
03111         ssl->options.havePeerCert = 1;
03112 
03113         /* store for callback use */
03114         if (dCert.subjectCNLen < ASN_NAME_MAX) {
03115             XMEMCPY(domain, dCert.subjectCN, dCert.subjectCNLen);
03116             domain[dCert.subjectCNLen] = '\0';
03117         }
03118         else
03119             domain[0] = '\0';
03120 
03121         if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer) {
03122             if (MatchDomainName(dCert.subjectCN, dCert.subjectCNLen, 
03123                                 (char*)ssl->buffers.domainName.buffer) == 0) {
03124                 CYASSL_MSG("DomainName match on common name failed");
03125                 if (CheckAltNames(&dCert,
03126                                  (char*)ssl->buffers.domainName.buffer) == 0 ) {
03127                     CYASSL_MSG("DomainName match on alt names failed too");
03128                     ret = DOMAIN_NAME_MISMATCH; /* try to get peer key still */
03129                 }
03130             }
03131         }
03132 
03133         /* decode peer key */
03134         switch (dCert.keyOID) {
03135         #ifndef NO_RSA
03136             case RSAk:
03137                 {
03138                     word32 idx = 0;
03139                     if (RsaPublicKeyDecode(dCert.publicKey, &idx,
03140                                       ssl->peerRsaKey, dCert.pubKeySize) != 0) {
03141                         ret = PEER_KEY_ERROR;
03142                     }
03143                     else
03144                         ssl->peerRsaKeyPresent = 1;
03145                 }
03146                 break;
03147         #endif /* NO_RSA */
03148         #ifdef HAVE_NTRU
03149             case NTRUk:
03150                 {
03151                     if (dCert.pubKeySize > sizeof(ssl->peerNtruKey)) {
03152                         ret = PEER_KEY_ERROR;
03153                     }
03154                     else {
03155                         XMEMCPY(ssl->peerNtruKey, dCert.publicKey, dCert.pubKeySize);
03156                         ssl->peerNtruKeyLen = (word16)dCert.pubKeySize;
03157                         ssl->peerNtruKeyPresent = 1;
03158                     }
03159                 }
03160                 break;
03161         #endif /* HAVE_NTRU */
03162         #ifdef HAVE_ECC
03163             case ECDSAk:
03164                 {
03165                     if (ecc_import_x963(dCert.publicKey, dCert.pubKeySize,
03166                                         ssl->peerEccDsaKey) != 0) {
03167                         ret = PEER_KEY_ERROR;
03168                     }
03169                     else
03170                         ssl->peerEccDsaKeyPresent = 1;
03171                 }
03172                 break;
03173         #endif /* HAVE_ECC */
03174             default:
03175                 break;
03176         }
03177 
03178         FreeDecodedCert(&dCert);
03179     }
03180     
03181     if (anyError != 0 && ret == 0)
03182         ret = anyError;
03183 
03184     if (ret == 0 && ssl->options.side == CLIENT_END)
03185         ssl->options.serverState = SERVER_CERT_COMPLETE;
03186 
03187     if (ret != 0) {
03188         if (!ssl->options.verifyNone) {
03189             int why = bad_certificate;
03190             if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E)
03191                 why = certificate_expired;
03192             if (ssl->verifyCallback) {
03193                 int            ok;
03194                 CYASSL_X509_STORE_CTX store;
03195 
03196                 store.error = ret;
03197                 store.error_depth = totalCerts;
03198                 store.discardSessionCerts = 0;
03199                 store.domain = domain;
03200                 store.userCtx = ssl->verifyCbCtx;
03201 #ifdef KEEP_PEER_CERT
03202                 store.current_cert = &ssl->peerCert;
03203 #else
03204                 store.current_cert = NULL;
03205 #endif
03206 #ifdef FORTRESS
03207                 store.ex_data = ssl;
03208 #endif
03209                 ok = ssl->verifyCallback(0, &store);
03210                 if (ok) {
03211                     CYASSL_MSG("Verify callback overriding error!"); 
03212                     ret = 0;
03213                 }
03214                 #ifdef SESSION_CERTS
03215                 if (store.discardSessionCerts) {
03216                     CYASSL_MSG("Verify callback requested discard sess certs");
03217                     ssl->session.chain.count = 0;
03218                 }
03219                 #endif
03220             }
03221             if (ret != 0) {
03222                 SendAlert(ssl, alert_fatal, why);   /* try to send */
03223                 ssl->options.isClosed = 1;
03224             }
03225         }
03226         ssl->error = ret;
03227     }
03228 #ifdef FORTRESS
03229     else {
03230         if (ssl->verifyCallback) {
03231             int ok;
03232             CYASSL_X509_STORE_CTX store;
03233 
03234             store.error = ret;
03235             store.error_depth = totalCerts;
03236             store.discardSessionCerts = 0;
03237             store.domain = domain;
03238             store.userCtx = ssl->verifyCbCtx;
03239             store.current_cert = &ssl->peerCert;
03240             store.ex_data = ssl;
03241 
03242             ok = ssl->verifyCallback(1, &store);
03243             if (!ok) {
03244                 CYASSL_MSG("Verify callback overriding valid certificate!");
03245                 ret = -1;
03246                 SendAlert(ssl, alert_fatal, bad_certificate);
03247                 ssl->options.isClosed = 1;
03248             }
03249             #ifdef SESSION_CERTS
03250             if (store.discardSessionCerts) {
03251                 CYASSL_MSG("Verify callback requested discard sess certs");
03252                 ssl->session.chain.count = 0;
03253             }
03254             #endif
03255         }
03256     }
03257 #endif
03258 
03259     *inOutIdx = i;
03260     return ret;
03261 }
03262 
03263 #endif /* !NO_CERTS */
03264 
03265 
03266 static int DoHelloRequest(CYASSL* ssl, const byte* input, word32* inOutIdx)
03267 {
03268     if (ssl->keys.encryptionOn) {
03269         const byte* mac;
03270         int         padSz = ssl->keys.encryptSz - HANDSHAKE_HEADER_SZ - 
03271                             ssl->specs.hash_size;
03272         byte        verify[SHA256_DIGEST_SIZE];
03273        
03274         ssl->hmac(ssl, verify, input + *inOutIdx - HANDSHAKE_HEADER_SZ,
03275                   HANDSHAKE_HEADER_SZ, handshake, 1);
03276         /* read mac and fill */
03277         mac = input + *inOutIdx;
03278         *inOutIdx += ssl->specs.hash_size;
03279 
03280         if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
03281             padSz -= ssl->specs.block_size;
03282 
03283         *inOutIdx += padSz;
03284 
03285         /* verify */
03286         if (XMEMCMP(mac, verify, ssl->specs.hash_size) != 0) {
03287             CYASSL_MSG("    hello_request verify mac error");
03288             return VERIFY_MAC_ERROR;
03289         }
03290     }
03291 
03292     if (ssl->options.side == SERVER_END) {
03293         SendAlert(ssl, alert_fatal, unexpected_message); /* try */
03294         return FATAL_ERROR;
03295     }
03296     else
03297         return SendAlert(ssl, alert_warning, no_renegotiation);
03298 }
03299 
03300 
03301 int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, int sniff)
03302 {
03303     int    finishedSz = ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ;
03304     int    headerSz = HANDSHAKE_HEADER_SZ;
03305     word32 macSz = finishedSz + HANDSHAKE_HEADER_SZ,
03306            idx = *inOutIdx,
03307            padSz = ssl->keys.encryptSz - HANDSHAKE_HEADER_SZ - finishedSz -
03308                    ssl->specs.hash_size;
03309     const byte* mac;
03310 
03311     #ifdef CYASSL_DTLS
03312         if (ssl->options.dtls) {
03313             headerSz += DTLS_HANDSHAKE_EXTRA;
03314             macSz    += DTLS_HANDSHAKE_EXTRA;
03315             padSz    -= DTLS_HANDSHAKE_EXTRA;
03316         }
03317     #endif
03318 
03319     #ifdef CYASSL_CALLBACKS
03320         if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
03321         if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
03322     #endif
03323     if (sniff == NO_SNIFF) {
03324         if (XMEMCMP(input + idx, &ssl->verifyHashes, finishedSz) != 0) {
03325             CYASSL_MSG("Verify finished error on hashes");
03326             return VERIFY_FINISHED_ERROR;
03327         }
03328     }
03329 
03330     if (ssl->specs.cipher_type != aead) {
03331         byte verifyMAC[MAX_DIGEST_SIZE];
03332         ssl->hmac(ssl, verifyMAC, input + idx - headerSz, macSz,
03333              handshake, 1);
03334         idx += finishedSz;
03335 
03336         /* read mac and fill */
03337         mac = input + idx;
03338         idx += ssl->specs.hash_size;
03339 
03340         if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
03341             padSz -= ssl->specs.block_size;
03342 
03343         idx += padSz;
03344 
03345         /* verify mac */
03346         if (XMEMCMP(mac, verifyMAC, ssl->specs.hash_size) != 0) {
03347             CYASSL_MSG("Verify finished error on mac");
03348             return VERIFY_MAC_ERROR;
03349         }
03350     }
03351     else {
03352         idx += (finishedSz + ssl->specs.aead_mac_size);
03353     }
03354 
03355     if (ssl->options.side == CLIENT_END) {
03356         ssl->options.serverState = SERVER_FINISHED_COMPLETE;
03357         if (!ssl->options.resuming) {
03358             ssl->options.handShakeState = HANDSHAKE_DONE;
03359 #ifdef CYASSL_DTLS
03360             if (ssl->options.dtls) {
03361                 /* Other side has received our Finished, go to next epoch */
03362                 ssl->keys.dtls_epoch++;
03363                 ssl->keys.dtls_sequence_number = 1;
03364             }
03365 #endif
03366         }
03367     }
03368     else {
03369         ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
03370         if (ssl->options.resuming) {
03371             ssl->options.handShakeState = HANDSHAKE_DONE;
03372 #ifdef CYASSL_DTLS
03373             if (ssl->options.dtls) {
03374                 /* Other side has received our Finished, go to next epoch */
03375                 ssl->keys.dtls_epoch++;
03376                 ssl->keys.dtls_sequence_number = 1;
03377             }
03378 #endif
03379         }
03380     }
03381 
03382     *inOutIdx = idx;
03383     return 0;
03384 }
03385 
03386 
03387 static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
03388                           byte type, word32 size, word32 totalSz)
03389 {
03390     int ret = 0;
03391     (void)totalSz;
03392 
03393     CYASSL_ENTER("DoHandShakeMsgType");
03394 
03395     HashInput(ssl, input + *inOutIdx, size);
03396 #ifdef CYASSL_CALLBACKS
03397     /* add name later, add on record and handshake header part back on */
03398     if (ssl->toInfoOn) {
03399         int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
03400         AddPacketInfo(0, &ssl->timeoutInfo, input + *inOutIdx - add,
03401                       size + add, ssl->heap);
03402         AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
03403     }
03404 #endif
03405 
03406     if (ssl->options.handShakeState == HANDSHAKE_DONE && type != hello_request){
03407         CYASSL_MSG("HandShake message after handshake complete");
03408         SendAlert(ssl, alert_fatal, unexpected_message);
03409         return OUT_OF_ORDER_E;
03410     }
03411 
03412     if (ssl->options.side == CLIENT_END && ssl->options.dtls == 0 &&
03413                ssl->options.serverState == NULL_STATE && type != server_hello) {
03414         CYASSL_MSG("First server message not server hello");
03415         SendAlert(ssl, alert_fatal, unexpected_message);
03416         return OUT_OF_ORDER_E;
03417     }
03418 
03419     if (ssl->options.side == CLIENT_END && ssl->options.dtls &&
03420             type == server_hello_done &&
03421             ssl->options.serverState < SERVER_HELLO_COMPLETE) {
03422         CYASSL_MSG("Server hello done received before server hello in DTLS");
03423         SendAlert(ssl, alert_fatal, unexpected_message);
03424         return OUT_OF_ORDER_E;
03425     }
03426 
03427     if (ssl->options.side == SERVER_END &&
03428                ssl->options.clientState == NULL_STATE && type != client_hello) {
03429         CYASSL_MSG("First client message not client hello");
03430         SendAlert(ssl, alert_fatal, unexpected_message);
03431         return OUT_OF_ORDER_E;
03432     }
03433 
03434 
03435     switch (type) {
03436 
03437     case hello_request:
03438         CYASSL_MSG("processing hello request");
03439         ret = DoHelloRequest(ssl, input, inOutIdx);
03440         break;
03441 
03442 #ifndef NO_CYASSL_CLIENT
03443     case hello_verify_request:
03444         CYASSL_MSG("processing hello verify request");
03445         ret = DoHelloVerifyRequest(ssl, input,inOutIdx);
03446         break;
03447             
03448     case server_hello:
03449         CYASSL_MSG("processing server hello");
03450         ret = DoServerHello(ssl, input, inOutIdx, size);
03451         break;
03452 
03453 #ifndef NO_CERTS
03454     case certificate_request:
03455         CYASSL_MSG("processing certificate request");
03456         ret = DoCertificateRequest(ssl, input, inOutIdx);
03457         break;
03458 #endif
03459 
03460     case server_key_exchange:
03461         CYASSL_MSG("processing server key exchange");
03462         ret = DoServerKeyExchange(ssl, input, inOutIdx);
03463         break;
03464 #endif
03465 
03466 #ifndef NO_CERTS
03467     case certificate:
03468         CYASSL_MSG("processing certificate");
03469         ret =  DoCertificate(ssl, input, inOutIdx);
03470         break;
03471 #endif
03472 
03473     case server_hello_done:
03474         CYASSL_MSG("processing server hello done");
03475         #ifdef CYASSL_CALLBACKS
03476             if (ssl->hsInfoOn) 
03477                 AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
03478             if (ssl->toInfoOn)
03479                 AddLateName("ServerHelloDone", &ssl->timeoutInfo);
03480         #endif
03481         ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
03482         break;
03483 
03484     case finished:
03485         CYASSL_MSG("processing finished");
03486         ret = DoFinished(ssl, input, inOutIdx, NO_SNIFF);
03487         break;
03488 
03489 #ifndef NO_CYASSL_SERVER
03490     case client_hello:
03491         CYASSL_MSG("processing client hello");
03492         ret = DoClientHello(ssl, input, inOutIdx, totalSz, size);
03493         break;
03494 
03495     case client_key_exchange:
03496         CYASSL_MSG("processing client key exchange");
03497         ret = DoClientKeyExchange(ssl, input, inOutIdx, totalSz);
03498         break;
03499 
03500 #if !defined(NO_RSA) || defined(HAVE_ECC)
03501     case certificate_verify:
03502         CYASSL_MSG("processing certificate verify");
03503         ret = DoCertificateVerify(ssl, input, inOutIdx, totalSz);
03504         break;
03505 #endif /* !NO_RSA || HAVE_ECC */
03506 
03507 #endif /* !NO_CYASSL_SERVER */
03508 
03509     default:
03510         CYASSL_MSG("Unknown handshake message type");
03511         ret = UNKNOWN_HANDSHAKE_TYPE;
03512     }
03513 
03514     CYASSL_LEAVE("DoHandShakeMsgType()", ret);
03515     return ret;
03516 }
03517 
03518 
03519 static int DoHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
03520                           word32 totalSz)
03521 {
03522     byte type;
03523     word32 size;
03524     int ret = 0;
03525 
03526     CYASSL_ENTER("DoHandShakeMsg()");
03527 
03528     if (GetHandShakeHeader(ssl, input, inOutIdx, &type, &size) != 0)
03529         return PARSE_ERROR;
03530 
03531     if (*inOutIdx + size > totalSz)
03532         return INCOMPLETE_DATA;
03533 
03534     ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
03535 
03536     CYASSL_LEAVE("DoHandShakeMsg()", ret);
03537     return ret;
03538 }
03539 
03540 
03541 #ifdef CYASSL_DTLS
03542 static int DtlsMsgDrain(CYASSL* ssl)
03543 {
03544     DtlsMsg* item = ssl->dtls_msg_list;
03545     int ret = 0;
03546     word32 idx = 0;
03547 
03548     /* While there is an item in the store list, and it is the expected
03549      * message, and it is complete, and there hasn't been an error in the
03550      * last messge... */
03551     while (item != NULL &&
03552             ssl->keys.dtls_expected_peer_handshake_number == item->seq &&
03553             item->fragSz == item->sz &&
03554             ret == 0) {
03555         ssl->keys.dtls_expected_peer_handshake_number++;
03556         ret = DoHandShakeMsgType(ssl, item->msg,
03557                                  &idx, item->type, item->sz, item->sz);
03558         ssl->dtls_msg_list = item->next;
03559         DtlsMsgDelete(item, ssl->heap);
03560         item = ssl->dtls_msg_list;
03561     }
03562 
03563     return ret;
03564 }
03565 
03566 
03567 static int DoDtlsHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
03568                           word32 totalSz)
03569 {
03570     byte type;
03571     word32 size;
03572     word32 fragOffset, fragSz;
03573     int ret = 0;
03574 
03575     CYASSL_ENTER("DoDtlsHandShakeMsg()");
03576     if (GetDtlsHandShakeHeader(ssl, input, inOutIdx, &type,
03577                                             &size, &fragOffset, &fragSz) != 0)
03578         return PARSE_ERROR;
03579 
03580     if (*inOutIdx + fragSz > totalSz)
03581         return INCOMPLETE_DATA;
03582 
03583     /* Check the handshake sequence number first. If out of order,
03584      * add the current message to the list. If the message is in order,
03585      * but it is a fragment, add the current message to the list, then
03586      * check the head of the list to see if it is complete, if so, pop
03587      * it out as the current message. If the message is complete and in
03588      * order, process it. Check the head of the list to see if it is in
03589      * order, if so, process it. (Repeat until list exhausted.) If the
03590      * head is out of order, return for more processing.
03591      */
03592     if (ssl->keys.dtls_peer_handshake_number >
03593                                 ssl->keys.dtls_expected_peer_handshake_number) {
03594         /* Current message is out of order. It will get stored in the list.
03595          * Storing also takes care of defragmentation. */
03596         ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
03597                         ssl->keys.dtls_peer_handshake_number, input + *inOutIdx,
03598                         size, type, fragOffset, fragSz, ssl->heap);
03599         *inOutIdx += fragSz;
03600         ret = 0;
03601     }
03602     else if (ssl->keys.dtls_peer_handshake_number <
03603                                 ssl->keys.dtls_expected_peer_handshake_number) {
03604         /* Already saw this message and processed it. It can be ignored. */
03605         *inOutIdx += fragSz;
03606         ret = 0;
03607     }
03608     else if (fragSz < size) {
03609         /* Since this branch is in order, but fragmented, dtls_msg_list will be
03610          * pointing to the message with this fragment in it. Check it to see
03611          * if it is completed. */
03612         ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
03613                         ssl->keys.dtls_peer_handshake_number, input + *inOutIdx,
03614                         size, type, fragOffset, fragSz, ssl->heap);
03615         *inOutIdx += fragSz;
03616         ret = 0;
03617         if (ssl->dtls_msg_list->fragSz >= ssl->dtls_msg_list->sz)
03618             ret = DtlsMsgDrain(ssl);
03619     }
03620     else {
03621         /* This branch is in order next, and a complete message. */
03622         ssl->keys.dtls_expected_peer_handshake_number++;
03623         ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
03624         if (ret == 0 && ssl->dtls_msg_list != NULL)
03625             ret = DtlsMsgDrain(ssl);
03626     }
03627 
03628     CYASSL_LEAVE("DoDtlsHandShakeMsg()", ret);
03629     return ret;
03630 }
03631 #endif
03632 
03633 
03634 static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
03635 {
03636     if (verify)
03637         return ssl->keys.peer_sequence_number++; 
03638     else
03639         return ssl->keys.sequence_number++; 
03640 }
03641 
03642 
03643 #ifdef HAVE_AEAD
03644 static INLINE void AeadIncrementExpIV(CYASSL* ssl)
03645 {
03646     int i;
03647     for (i = AEAD_EXP_IV_SZ-1; i >= 0; i--) {
03648         if (++ssl->keys.aead_exp_IV[i]) return;
03649     }
03650 }
03651 #endif
03652 
03653 
03654 static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz)
03655 {
03656     (void)out;
03657     (void)input;
03658     (void)sz;
03659 
03660     if (ssl->encrypt.setup == 0) {
03661         CYASSL_MSG("Encrypt ciphers not setup");
03662         return ENCRYPT_ERROR;
03663     }
03664 
03665     switch (ssl->specs.bulk_cipher_algorithm) {
03666         #ifdef BUILD_ARC4
03667             case rc4:
03668                 Arc4Process(ssl->encrypt.arc4, out, input, sz);
03669                 break;
03670         #endif
03671 
03672         #ifdef BUILD_DES3
03673             case triple_des:
03674                 Des3_CbcEncrypt(ssl->encrypt.des3, out, input, sz);
03675                 break;
03676         #endif
03677 
03678         #ifdef BUILD_AES
03679             case aes:
03680                 return AesCbcEncrypt(ssl->encrypt.aes, out, input, sz);
03681                 break;
03682         #endif
03683 
03684         #ifdef BUILD_AESGCM
03685             case aes_gcm:
03686                 {
03687                     byte additional[AES_BLOCK_SIZE];
03688                     byte nonce[AEAD_NONCE_SZ];
03689                     const byte* additionalSrc = input - 5;
03690 
03691                     XMEMSET(additional, 0, AES_BLOCK_SIZE);
03692 
03693                     /* sequence number field is 64-bits, we only use 32-bits */
03694                     c32toa(GetSEQIncrement(ssl, 0),
03695                                             additional + AEAD_SEQ_OFFSET);
03696 
03697                     /* Store the type, version. Unfortunately, they are in
03698                      * the input buffer ahead of the plaintext. */
03699                     #ifdef CYASSL_DTLS
03700                         if (ssl->options.dtls)
03701                             additionalSrc -= DTLS_HANDSHAKE_EXTRA;
03702                     #endif
03703                     XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
03704 
03705                     /* Store the length of the plain text minus the explicit
03706                      * IV length minus the authentication tag size. */
03707                     c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
03708                                                 additional + AEAD_LEN_OFFSET);
03709                     XMEMCPY(nonce,
03710                                  ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ);
03711                     XMEMCPY(nonce + AEAD_IMP_IV_SZ,
03712                                      ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
03713                     AesGcmEncrypt(ssl->encrypt.aes,
03714                         out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ,
03715                             sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
03716                         nonce, AEAD_NONCE_SZ,
03717                         out + sz - ssl->specs.aead_mac_size,
03718                         ssl->specs.aead_mac_size, additional,
03719                         AEAD_AUTH_DATA_SZ);
03720                     AeadIncrementExpIV(ssl);
03721                     XMEMSET(nonce, 0, AEAD_NONCE_SZ);
03722                 }
03723                 break;
03724         #endif
03725 
03726         #ifdef HAVE_AESCCM
03727             case aes_ccm:
03728                 {
03729                     byte additional[AES_BLOCK_SIZE];
03730                     byte nonce[AEAD_NONCE_SZ];
03731                     const byte* additionalSrc = input - 5;
03732 
03733                     XMEMSET(additional, 0, AES_BLOCK_SIZE);
03734 
03735                     /* sequence number field is 64-bits, we only use 32-bits */
03736                     c32toa(GetSEQIncrement(ssl, 0),
03737                                             additional + AEAD_SEQ_OFFSET);
03738 
03739                     /* Store the type, version. Unfortunately, they are in
03740                      * the input buffer ahead of the plaintext. */
03741                     #ifdef CYASSL_DTLS
03742                         if (ssl->options.dtls)
03743                             additionalSrc -= DTLS_HANDSHAKE_EXTRA;
03744                     #endif
03745                     XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
03746 
03747                     /* Store the length of the plain text minus the explicit
03748                      * IV length minus the authentication tag size. */
03749                     c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
03750                                                 additional + AEAD_LEN_OFFSET);
03751                     XMEMCPY(nonce,
03752                                  ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ);
03753                     XMEMCPY(nonce + AEAD_IMP_IV_SZ,
03754                                      ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
03755                     AesCcmEncrypt(ssl->encrypt.aes,
03756                         out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ,
03757                             sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
03758                         nonce, AEAD_NONCE_SZ,
03759                         out + sz - ssl->specs.aead_mac_size,
03760                         ssl->specs.aead_mac_size,
03761                         additional, AEAD_AUTH_DATA_SZ);
03762                     AeadIncrementExpIV(ssl);
03763                     XMEMSET(nonce, 0, AEAD_NONCE_SZ);
03764                 }
03765                 break;
03766         #endif
03767 
03768         #ifdef HAVE_CAMELLIA
03769             case camellia:
03770                 CamelliaCbcEncrypt(ssl->encrypt.cam, out, input, sz);
03771                 break;
03772         #endif
03773 
03774         #ifdef HAVE_HC128
03775             case hc128:
03776                 return Hc128_Process(ssl->encrypt.hc128, out, input, sz);
03777                 break;
03778         #endif
03779 
03780         #ifdef BUILD_RABBIT
03781             case rabbit:
03782                 return RabbitProcess(ssl->encrypt.rabbit, out, input, sz);
03783                 break;
03784         #endif
03785 
03786         #ifdef HAVE_NULL_CIPHER
03787             case cipher_null:
03788                 if (input != out) {
03789                     XMEMMOVE(out, input, sz);
03790                 }
03791                 break;
03792         #endif
03793 
03794             default:
03795                 CYASSL_MSG("CyaSSL Encrypt programming error");
03796                 return ENCRYPT_ERROR;
03797     }
03798 
03799     return 0;
03800 }
03801 
03802 
03803 static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input,
03804                            word32 sz)
03805 {
03806     (void)plain;
03807     (void)input;
03808     (void)sz;
03809 
03810     if (ssl->decrypt.setup == 0) {
03811         CYASSL_MSG("Decrypt ciphers not setup");
03812         return DECRYPT_ERROR;
03813     }
03814 
03815     switch (ssl->specs.bulk_cipher_algorithm) {
03816         #ifdef BUILD_ARC4
03817             case rc4:
03818                 Arc4Process(ssl->decrypt.arc4, plain, input, sz);
03819                 break;
03820         #endif
03821 
03822         #ifdef BUILD_DES3
03823             case triple_des:
03824                 Des3_CbcDecrypt(ssl->decrypt.des3, plain, input, sz);
03825                 break;
03826         #endif
03827 
03828         #ifdef BUILD_AES
03829             case aes:
03830                 return AesCbcDecrypt(ssl->decrypt.aes, plain, input, sz);
03831                 break;
03832         #endif
03833 
03834         #ifdef BUILD_AESGCM
03835             case aes_gcm:
03836             {
03837                 byte additional[AES_BLOCK_SIZE];
03838                 byte nonce[AEAD_NONCE_SZ];
03839 
03840                 XMEMSET(additional, 0, AES_BLOCK_SIZE);
03841 
03842                 /* sequence number field is 64-bits, we only use 32-bits */
03843                 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
03844                 
03845                 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
03846                 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
03847                 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
03848 
03849                 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
03850                                         additional + AEAD_LEN_OFFSET);
03851                 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
03852                 XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
03853                 if (AesGcmDecrypt(ssl->decrypt.aes,
03854                             plain + AEAD_EXP_IV_SZ,
03855                             input + AEAD_EXP_IV_SZ,
03856                                 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
03857                             nonce, AEAD_NONCE_SZ,
03858                             input + sz - ssl->specs.aead_mac_size,
03859                             ssl->specs.aead_mac_size,
03860                             additional, AEAD_AUTH_DATA_SZ) < 0) {
03861                     SendAlert(ssl, alert_fatal, bad_record_mac);
03862                     XMEMSET(nonce, 0, AEAD_NONCE_SZ);
03863                     return VERIFY_MAC_ERROR;
03864                 }
03865                 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
03866                 break;
03867             }
03868         #endif
03869 
03870         #ifdef HAVE_AESCCM
03871             case aes_ccm:
03872             {
03873                 byte additional[AES_BLOCK_SIZE];
03874                 byte nonce[AEAD_NONCE_SZ];
03875 
03876                 XMEMSET(additional, 0, AES_BLOCK_SIZE);
03877 
03878                 /* sequence number field is 64-bits, we only use 32-bits */
03879                 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
03880                 
03881                 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
03882                 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
03883                 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
03884 
03885                 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
03886                                         additional + AEAD_LEN_OFFSET);
03887                 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
03888                 XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
03889                 if (AesCcmDecrypt(ssl->decrypt.aes,
03890                             plain + AEAD_EXP_IV_SZ,
03891                             input + AEAD_EXP_IV_SZ,
03892                                 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
03893                             nonce, AEAD_NONCE_SZ,
03894                             input + sz - ssl->specs.aead_mac_size,
03895                             ssl->specs.aead_mac_size,
03896                             additional, AEAD_AUTH_DATA_SZ) < 0) {
03897                     SendAlert(ssl, alert_fatal, bad_record_mac);
03898                     XMEMSET(nonce, 0, AEAD_NONCE_SZ);
03899                     return VERIFY_MAC_ERROR;
03900                 }
03901                 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
03902                 break;
03903             }
03904         #endif
03905 
03906         #ifdef HAVE_CAMELLIA
03907             case camellia:
03908                 CamelliaCbcDecrypt(ssl->decrypt.cam, plain, input, sz);
03909                 break;
03910         #endif
03911 
03912         #ifdef HAVE_HC128
03913             case hc128:
03914                 return Hc128_Process(ssl->decrypt.hc128, plain, input, sz);
03915                 break;
03916         #endif
03917 
03918         #ifdef BUILD_RABBIT
03919             case rabbit:
03920                 return RabbitProcess(ssl->decrypt.rabbit, plain, input, sz);
03921                 break;
03922         #endif
03923 
03924         #ifdef HAVE_NULL_CIPHER
03925             case cipher_null:
03926                 if (input != plain) {
03927                     XMEMMOVE(plain, input, sz);
03928                 }
03929                 break;
03930         #endif
03931                 
03932             default:
03933                 CYASSL_MSG("CyaSSL Decrypt programming error");
03934                 return DECRYPT_ERROR;
03935     }
03936     return 0;
03937 }
03938 
03939 
03940 /* check cipher text size for sanity */
03941 static int SanityCheckCipherText(CYASSL* ssl, word32 encryptSz)
03942 {
03943     word32 minLength = 0;
03944 
03945     if (ssl->specs.cipher_type == block) {
03946         if (encryptSz % ssl->specs.block_size) {
03947             CYASSL_MSG("Block ciphertext not block size");
03948             return SANITY_CIPHER_E;
03949         }
03950         minLength = ssl->specs.hash_size + 1;  /* pad byte */
03951         if (ssl->specs.block_size > minLength)
03952             minLength = ssl->specs.block_size;
03953 
03954         if (ssl->options.tls1_1)
03955             minLength += ssl->specs.block_size;  /* explicit IV */
03956     }
03957     else if (ssl->specs.cipher_type == stream) {
03958         minLength = ssl->specs.hash_size;
03959     }
03960     else if (ssl->specs.cipher_type == aead) {
03961         minLength = ssl->specs.block_size; /* explicit IV + implicit IV + CTR */
03962     }
03963 
03964     if (encryptSz < minLength) {
03965         CYASSL_MSG("Ciphertext not minimum size");
03966         return SANITY_CIPHER_E;
03967     }
03968 
03969     return 0;
03970 }
03971 
03972 
03973 /* decrypt input message in place */
03974 static int DecryptMessage(CYASSL* ssl, byte* input, word32 sz, word32* idx)
03975 {
03976     int decryptResult;
03977     int sanityResult = SanityCheckCipherText(ssl, sz);
03978 
03979     if (sanityResult != 0)
03980         return sanityResult;
03981 
03982     decryptResult = Decrypt(ssl, input, input, sz);
03983 
03984     if (decryptResult == 0)
03985     {
03986         ssl->keys.encryptSz    = sz;
03987         ssl->keys.decryptedCur = 1;
03988 
03989         if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
03990             *idx += ssl->specs.block_size;  /* go past TLSv1.1 IV */
03991         if (ssl->specs.cipher_type == aead)
03992             *idx += AEAD_EXP_IV_SZ;
03993     }
03994 
03995     return decryptResult;
03996 }
03997 
03998 
03999 #ifndef NO_OLD_TLS
04000 
04001 static INLINE void Md5Rounds(int rounds, const byte* data, int sz)
04002 {
04003     Md5 md5;
04004     int i;
04005 
04006     InitMd5(&md5);
04007 
04008     for (i = 0; i < rounds; i++)
04009         Md5Update(&md5, data, sz);
04010 }
04011 
04012 
04013 
04014 static INLINE void ShaRounds(int rounds, const byte* data, int sz)
04015 {
04016     Sha sha;
04017     int i;
04018 
04019     InitSha(&sha);
04020 
04021     for (i = 0; i < rounds; i++)
04022         ShaUpdate(&sha, data, sz);
04023 }
04024 #endif
04025 
04026 
04027 #ifndef NO_SHA256
04028 
04029 static INLINE void Sha256Rounds(int rounds, const byte* data, int sz)
04030 {
04031     Sha256 sha256;
04032     int i;
04033 
04034     InitSha256(&sha256);
04035 
04036     for (i = 0; i < rounds; i++)
04037         Sha256Update(&sha256, data, sz);
04038 }
04039 
04040 #endif
04041 
04042 
04043 #ifdef CYASSL_SHA384
04044 
04045 static INLINE void Sha384Rounds(int rounds, const byte* data, int sz)
04046 {
04047     Sha384 sha384;
04048     int i;
04049 
04050     InitSha384(&sha384);
04051 
04052     for (i = 0; i < rounds; i++)
04053         Sha384Update(&sha384, data, sz);
04054 }
04055 
04056 #endif
04057 
04058 
04059 #ifdef CYASSL_SHA512
04060 
04061 static INLINE void Sha512Rounds(int rounds, const byte* data, int sz)
04062 {
04063     Sha512 sha512;
04064     int i;
04065 
04066     InitSha512(&sha512);
04067 
04068     for (i = 0; i < rounds; i++)
04069         Sha512Update(&sha512, data, sz);
04070 }
04071 
04072 #endif
04073 
04074 
04075 #ifdef CYASSL_RIPEMD
04076 
04077 static INLINE void RmdRounds(int rounds, const byte* data, int sz)
04078 {
04079     RipeMd ripemd;
04080     int i;
04081 
04082     InitRipeMd(&ripemd);
04083 
04084     for (i = 0; i < rounds; i++)
04085         RipeMdUpdate(&ripemd, data, sz);
04086 }
04087 
04088 #endif
04089 
04090 
04091 static INLINE void DoRounds(int type, int rounds, const byte* data, int sz)
04092 {
04093     switch (type) {
04094     
04095         case no_mac :
04096             break;
04097 
04098 #ifndef NO_OLD_TLS
04099 #ifndef NO_MD5
04100         case md5_mac :
04101             Md5Rounds(rounds, data, sz);
04102             break;
04103 #endif
04104 
04105 #ifndef NO_SHA
04106         case sha_mac :
04107             ShaRounds(rounds, data, sz);
04108             break;
04109 #endif
04110 #endif
04111 
04112 #ifndef NO_SHA256
04113         case sha256_mac :
04114             Sha256Rounds(rounds, data, sz);
04115             break;
04116 #endif
04117 
04118 #ifdef CYASSL_SHA384
04119         case sha384_mac :
04120             Sha384Rounds(rounds, data, sz);
04121             break;
04122 #endif
04123 
04124 #ifdef CYASSL_SHA512
04125         case sha512_mac :
04126             Sha512Rounds(rounds, data, sz);
04127             break;
04128 #endif
04129 
04130 #ifdef CYASSL_RIPEMD 
04131         case rmd_mac :
04132             RmdRounds(rounds, data, sz);
04133             break;
04134 #endif
04135 
04136         default:
04137             CYASSL_MSG("Bad round type");
04138             break;
04139     }
04140 }
04141 
04142 
04143 /* do number of compression rounds on dummy data */
04144 static INLINE void CompressRounds(CYASSL* ssl, int rounds, const byte* dummy)
04145 {
04146     if (rounds)
04147         DoRounds(ssl->specs.mac_algorithm, rounds, dummy, COMPRESS_LOWER);
04148 }
04149 
04150 
04151 /* check all length bytes for equality, return 0 on success */
04152 static int ConstantCompare(const byte* a, const byte* b, int length)
04153 {
04154     int i;
04155     int good = 0;
04156     int bad  = 0;
04157 
04158     for (i = 0; i < length; i++) {
04159         if (a[i] == b[i])
04160             good++;
04161         else
04162             bad++;
04163     }
04164 
04165     if (good == length)
04166         return 0;
04167     else
04168         return 0 - bad;  /* compare failed */
04169 }
04170 
04171 
04172 /* check all length bytes for the pad value, return 0 on success */
04173 static int PadCheck(const byte* input, byte pad, int length)
04174 {
04175     int i;
04176     int good = 0;
04177     int bad  = 0;
04178 
04179     for (i = 0; i < length; i++) {
04180         if (input[i] == pad)
04181             good++;
04182         else
04183             bad++;
04184     }
04185 
04186     if (good == length)
04187         return 0;
04188     else
04189         return 0 - bad;  /* pad check failed */
04190 }
04191 
04192 
04193 /* get compression extra rounds */
04194 static INLINE int GetRounds(int pLen, int padLen, int t)
04195 {
04196     int  roundL1 = 1;  /* round up flags */
04197     int  roundL2 = 1;
04198 
04199     int L1 = COMPRESS_CONSTANT + pLen - t;
04200     int L2 = COMPRESS_CONSTANT + pLen - padLen - 1 - t;
04201 
04202     L1 -= COMPRESS_UPPER;
04203     L2 -= COMPRESS_UPPER;
04204 
04205     if ( (L1 % COMPRESS_LOWER) == 0)
04206         roundL1 = 0;
04207     if ( (L2 % COMPRESS_LOWER) == 0)
04208         roundL2 = 0;
04209 
04210     L1 /= COMPRESS_LOWER;
04211     L2 /= COMPRESS_LOWER;
04212 
04213     L1 += roundL1;
04214     L2 += roundL2;
04215 
04216     return L1 - L2;
04217 }
04218 
04219 
04220 /* timing resistant pad/verify check, return 0 on success */
04221 static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t,
04222                            int pLen)
04223 {
04224     byte verify[MAX_DIGEST_SIZE];
04225     byte dummy[MAX_PAD_SIZE];
04226 
04227     XMEMSET(dummy, 1, sizeof(dummy));
04228 
04229     if ( (t + padLen + 1) > pLen) {
04230         CYASSL_MSG("Plain Len not long enough for pad/mac");
04231         PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE);
04232         ssl->hmac(ssl, verify, input, pLen - t, application_data, 1);
04233         ConstantCompare(verify, input + pLen - t, t);
04234 
04235         return VERIFY_MAC_ERROR;
04236     }
04237 
04238     if (PadCheck(input + pLen - (padLen + 1), (byte)padLen, padLen + 1) != 0) {
04239         CYASSL_MSG("PadCheck failed");
04240         PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
04241         ssl->hmac(ssl, verify, input, pLen - t, application_data, 1);
04242         ConstantCompare(verify, input + pLen - t, t);
04243 
04244         return VERIFY_MAC_ERROR;
04245     }
04246 
04247     PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
04248     ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, application_data, 1);
04249 
04250     CompressRounds(ssl, GetRounds(pLen, padLen, t), dummy);
04251 
04252     if (ConstantCompare(verify, input + (pLen - padLen - 1 - t), t) != 0) {
04253         CYASSL_MSG("Verify MAC compare failed");
04254         return VERIFY_MAC_ERROR;
04255     }
04256 
04257     return 0;
04258 }
04259 
04260 
04261 int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx)
04262 {
04263     word32 msgSz   = ssl->keys.encryptSz;
04264     word32 pad     = 0, 
04265            padByte = 0,
04266            idx     = *inOutIdx,
04267            digestSz = ssl->specs.hash_size;
04268     int    dataSz, ret;
04269     int    ivExtra = 0;
04270     byte*  rawData = input + idx;  /* keep current  for hmac */
04271 #ifdef HAVE_LIBZ
04272     byte   decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
04273 #endif
04274     byte   verify[MAX_DIGEST_SIZE];
04275 
04276     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
04277         CYASSL_MSG("Received App data before handshake complete");
04278         SendAlert(ssl, alert_fatal, unexpected_message);
04279         return OUT_OF_ORDER_E;
04280     }
04281 
04282     if (ssl->specs.cipher_type == block) {
04283         if (ssl->options.tls1_1)
04284             ivExtra = ssl->specs.block_size;
04285         pad = *(input + idx + msgSz - ivExtra - 1);
04286         padByte = 1;
04287 
04288         if (ssl->options.tls) {
04289             ret = TimingPadVerify(ssl, input + idx, pad, digestSz,
04290                                   msgSz - ivExtra);
04291             if (ret != 0)
04292                 return ret;
04293         }
04294         else {  /* sslv3, some implementations have bad padding */
04295             ssl->hmac(ssl, verify, rawData, msgSz - digestSz - pad - 1,
04296                       application_data, 1);
04297             if (ConstantCompare(verify, rawData + msgSz - digestSz - pad - 1,
04298                                 digestSz) != 0)
04299                 return VERIFY_MAC_ERROR;
04300         }
04301     }
04302     else if (ssl->specs.cipher_type == stream) {
04303         ssl->hmac(ssl, verify, rawData, msgSz - digestSz, application_data, 1);
04304         if (ConstantCompare(verify, rawData + msgSz - digestSz, digestSz) != 0){
04305             return VERIFY_MAC_ERROR;
04306         }
04307     }
04308     else if (ssl->specs.cipher_type == aead) {
04309         ivExtra = AEAD_EXP_IV_SZ;
04310         digestSz = ssl->specs.aead_mac_size;
04311     }
04312 
04313     dataSz = msgSz - ivExtra - digestSz - pad - padByte;
04314     if (dataSz < 0) {
04315         CYASSL_MSG("App data buffer error, malicious input?"); 
04316         return BUFFER_ERROR;
04317     }
04318 
04319     /* read data */
04320     if (dataSz) {
04321         int rawSz = dataSz;       /* keep raw size for idx adjustment */
04322 
04323 #ifdef HAVE_LIBZ
04324         if (ssl->options.usingCompression) {
04325             dataSz = myDeCompress(ssl, rawData, dataSz, decomp, sizeof(decomp));
04326             if (dataSz < 0) return dataSz;
04327         }
04328 #endif
04329         idx += rawSz;
04330 
04331         ssl->buffers.clearOutputBuffer.buffer = rawData;
04332         ssl->buffers.clearOutputBuffer.length = dataSz;
04333     }
04334 
04335     idx += digestSz;
04336     idx += pad;
04337     if (padByte)
04338         idx++;
04339 
04340 #ifdef HAVE_LIBZ
04341     /* decompress could be bigger, overwrite after verify */
04342     if (ssl->options.usingCompression)
04343         XMEMMOVE(rawData, decomp, dataSz);
04344 #endif
04345 
04346     *inOutIdx = idx;
04347     return 0;
04348 }
04349 
04350 
04351 /* process alert, return level */
04352 static int DoAlert(CYASSL* ssl, byte* input, word32* inOutIdx, int* type)
04353 {
04354     byte level;
04355     byte code;
04356 
04357     #ifdef CYASSL_CALLBACKS
04358         if (ssl->hsInfoOn)
04359             AddPacketName("Alert", &ssl->handShakeInfo);
04360         if (ssl->toInfoOn)
04361             /* add record header back on to info + 2 byte level, data */
04362             AddPacketInfo("Alert", &ssl->timeoutInfo, input + *inOutIdx -
04363                           RECORD_HEADER_SZ, 2 + RECORD_HEADER_SZ, ssl->heap);
04364     #endif
04365     level = input[(*inOutIdx)++];
04366     code  = (int)input[(*inOutIdx)++];
04367     ssl->alert_history.last_rx.code = code;
04368     ssl->alert_history.last_rx.level = level;
04369     *type = code;
04370     if (level == alert_fatal) {
04371         ssl->options.isClosed = 1;  /* Don't send close_notify */
04372     }
04373 
04374     CYASSL_MSG("Got alert");
04375     if (*type == close_notify) {
04376         CYASSL_MSG("    close notify");
04377         ssl->options.closeNotify = 1;
04378     }
04379     CYASSL_ERROR(*type);
04380 
04381     if (ssl->keys.encryptionOn) {
04382         if (ssl->specs.cipher_type != aead) {
04383             int     aSz = ALERT_SIZE;
04384             const byte* mac;
04385             byte    verify[MAX_DIGEST_SIZE];
04386             int     padSz = ssl->keys.encryptSz - aSz - ssl->specs.hash_size;
04387 
04388             ssl->hmac(ssl, verify, input + *inOutIdx - aSz, aSz, alert, 1);
04389     
04390             /* read mac and fill */
04391             mac = input + *inOutIdx;
04392             *inOutIdx += (ssl->specs.hash_size + padSz);
04393     
04394             /* verify */
04395             if (XMEMCMP(mac, verify, ssl->specs.hash_size) != 0) {
04396                 CYASSL_MSG("    alert verify mac error");
04397                 return VERIFY_MAC_ERROR;
04398             }
04399         }
04400         else {
04401             *inOutIdx += ssl->specs.aead_mac_size;
04402         }
04403     }
04404 
04405     return level;
04406 }
04407 
04408 static int GetInputData(CYASSL *ssl, word32 size)
04409 {
04410     int in;
04411     int inSz;
04412     int maxLength;
04413     int usedLength;
04414     int dtlsExtra = 0;
04415 
04416     
04417     /* check max input length */
04418     usedLength = ssl->buffers.inputBuffer.length - ssl->buffers.inputBuffer.idx;
04419     maxLength  = ssl->buffers.inputBuffer.bufferSize - usedLength;
04420     inSz       = (int)(size - usedLength);      /* from last partial read */
04421 
04422 #ifdef CYASSL_DTLS
04423     if (ssl->options.dtls) {
04424         if (size < ssl->dtls_expected_rx)
04425             dtlsExtra = (int)(ssl->dtls_expected_rx - size);
04426         inSz = ssl->dtls_expected_rx;  
04427     }
04428 #endif
04429     
04430     if (inSz > maxLength) {
04431         if (GrowInputBuffer(ssl, size + dtlsExtra, usedLength) < 0)
04432             return MEMORY_E;
04433     }
04434            
04435     if (inSz <= 0)
04436         return BUFFER_ERROR;
04437     
04438     /* Put buffer data at start if not there */
04439     if (usedLength > 0 && ssl->buffers.inputBuffer.idx != 0)
04440         XMEMMOVE(ssl->buffers.inputBuffer.buffer,
04441                 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
04442                 usedLength);
04443     
04444     /* remove processed data */
04445     ssl->buffers.inputBuffer.idx    = 0;
04446     ssl->buffers.inputBuffer.length = usedLength;
04447   
04448     /* read data from network */
04449     do {
04450         in = Receive(ssl, 
04451                      ssl->buffers.inputBuffer.buffer +
04452                      ssl->buffers.inputBuffer.length, 
04453                      inSz);
04454         if (in == -1)
04455             return SOCKET_ERROR_E;
04456    
04457         if (in == WANT_READ)
04458             return WANT_READ;
04459 
04460         if (in > inSz)
04461             return RECV_OVERFLOW_E;
04462         
04463         ssl->buffers.inputBuffer.length += in;
04464         inSz -= in;
04465 
04466     } while (ssl->buffers.inputBuffer.length < size);
04467 
04468     return 0;
04469 }
04470 
04471 /* process input requests, return 0 is done, 1 is call again to complete, and
04472    negative number is error */
04473 int ProcessReply(CYASSL* ssl)
04474 {
04475     int    ret = 0, type, readSz;
04476     word32 startIdx = 0;
04477 #ifndef NO_CYASSL_SERVER
04478     byte   b0, b1;
04479 #endif
04480 #ifdef CYASSL_DTLS
04481     int    used;
04482 #endif
04483 
04484     for (;;) {
04485         switch ((processReply)ssl->options.processReply) {
04486 
04487         /* in the CYASSL_SERVER case, get the first byte for detecting 
04488          * old client hello */
04489         case doProcessInit:
04490             
04491             readSz = RECORD_HEADER_SZ;
04492             
04493             #ifdef CYASSL_DTLS
04494                 if (ssl->options.dtls)
04495                     readSz = DTLS_RECORD_HEADER_SZ;
04496             #endif
04497 
04498             /* get header or return error */
04499             if (!ssl->options.dtls) {
04500                 if ((ret = GetInputData(ssl, readSz)) < 0)
04501                     return ret;
04502             } else {
04503             #ifdef CYASSL_DTLS
04504                 /* read ahead may already have header */
04505                 used = ssl->buffers.inputBuffer.length -
04506                        ssl->buffers.inputBuffer.idx;
04507                 if (used < readSz)
04508                     if ((ret = GetInputData(ssl, readSz)) < 0)
04509                         return ret;
04510             #endif
04511             }
04512 
04513 #ifndef NO_CYASSL_SERVER
04514 
04515             /* see if sending SSLv2 client hello */
04516             if ( ssl->options.side == SERVER_END &&
04517                  ssl->options.clientState == NULL_STATE &&
04518                  ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx]
04519                          != handshake) {
04520                 ssl->options.processReply = runProcessOldClientHello;
04521 
04522                 /* how many bytes need ProcessOldClientHello */
04523                 b0 =
04524                 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
04525                 b1 =
04526                 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
04527                 ssl->curSize = ((b0 & 0x7f) << 8) | b1;
04528             }
04529             else {
04530                 ssl->options.processReply = getRecordLayerHeader;
04531                 continue;
04532             }
04533 
04534         /* in the CYASSL_SERVER case, run the old client hello */
04535         case runProcessOldClientHello:     
04536 
04537             /* get sz bytes or return error */
04538             if (!ssl->options.dtls) {
04539                 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
04540                     return ret;
04541             } else {
04542             #ifdef CYASSL_DTLS
04543                 /* read ahead may already have */
04544                 used = ssl->buffers.inputBuffer.length -
04545                        ssl->buffers.inputBuffer.idx;
04546                 if (used < ssl->curSize)
04547                     if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
04548                         return ret;
04549             #endif  /* CYASSL_DTLS */
04550             }
04551 
04552             ret = ProcessOldClientHello(ssl, ssl->buffers.inputBuffer.buffer,
04553                                         &ssl->buffers.inputBuffer.idx,
04554                                         ssl->buffers.inputBuffer.length -
04555                                         ssl->buffers.inputBuffer.idx,
04556                                         ssl->curSize);
04557             if (ret < 0)
04558                 return ret;
04559 
04560             else if (ssl->buffers.inputBuffer.idx ==
04561                      ssl->buffers.inputBuffer.length) {
04562                 ssl->options.processReply = doProcessInit;
04563                 return 0;
04564             }
04565 
04566 #endif  /* NO_CYASSL_SERVER */
04567 
04568         /* get the record layer header */
04569         case getRecordLayerHeader:
04570 
04571             ret = GetRecordHeader(ssl, ssl->buffers.inputBuffer.buffer,
04572                                        &ssl->buffers.inputBuffer.idx,
04573                                        &ssl->curRL, &ssl->curSize);
04574 #ifdef CYASSL_DTLS
04575             if (ssl->options.dtls && ret == SEQUENCE_ERROR) {
04576                 /* This message is out of order. If we are handshaking, save
04577                  *it for later. Otherwise go ahead and process it. */
04578                 ssl->options.processReply = doProcessInit;
04579                 ssl->buffers.inputBuffer.length = 0;
04580                 ssl->buffers.inputBuffer.idx = 0;
04581                 continue;
04582             }
04583 #endif
04584             if (ret != 0)
04585                 return ret;
04586 
04587             ssl->options.processReply = getData;
04588 
04589         /* retrieve record layer data */
04590         case getData:
04591 
04592             /* get sz bytes or return error */
04593             if (!ssl->options.dtls) {
04594                 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
04595                     return ret;
04596             } else {
04597 #ifdef CYASSL_DTLS
04598                 /* read ahead may already have */
04599                 used = ssl->buffers.inputBuffer.length -
04600                        ssl->buffers.inputBuffer.idx;
04601                 if (used < ssl->curSize)
04602                     if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
04603                         return ret;
04604 #endif
04605             }
04606             
04607             ssl->options.processReply = runProcessingOneMessage;
04608             startIdx = ssl->buffers.inputBuffer.idx;  /* in case > 1 msg per */
04609 
04610         /* the record layer is here */
04611         case runProcessingOneMessage:
04612 
04613             if (ssl->keys.encryptionOn && ssl->keys.decryptedCur == 0) {
04614                 ret = DecryptMessage(ssl, ssl->buffers.inputBuffer.buffer + 
04615                                      ssl->buffers.inputBuffer.idx,
04616                                      ssl->curSize,
04617                                      &ssl->buffers.inputBuffer.idx);
04618                 if (ret < 0) {
04619                     CYASSL_ERROR(ret);
04620                     return DECRYPT_ERROR;
04621                 }
04622             }
04623 
04624             CYASSL_MSG("received record layer msg");
04625 
04626             switch (ssl->curRL.type) {
04627                 case handshake :
04628                     /* debugging in DoHandShakeMsg */
04629                     if (!ssl->options.dtls) {
04630                         ret = DoHandShakeMsg(ssl, 
04631                                             ssl->buffers.inputBuffer.buffer,
04632                                             &ssl->buffers.inputBuffer.idx,
04633                                             ssl->buffers.inputBuffer.length);
04634                     }
04635                     else {
04636 #ifdef CYASSL_DTLS
04637                         ret = DoDtlsHandShakeMsg(ssl, 
04638                                             ssl->buffers.inputBuffer.buffer,
04639                                             &ssl->buffers.inputBuffer.idx,
04640                                             ssl->buffers.inputBuffer.length);
04641 #endif
04642                     }
04643                     if (ret != 0)
04644                         return ret;
04645                     break;
04646 
04647                 case change_cipher_spec:
04648                     CYASSL_MSG("got CHANGE CIPHER SPEC");
04649                     #ifdef CYASSL_CALLBACKS
04650                         if (ssl->hsInfoOn)
04651                             AddPacketName("ChangeCipher", &ssl->handShakeInfo);
04652                         /* add record header back on info */
04653                         if (ssl->toInfoOn) {
04654                             AddPacketInfo("ChangeCipher", &ssl->timeoutInfo,
04655                                 ssl->buffers.inputBuffer.buffer +
04656                                 ssl->buffers.inputBuffer.idx - RECORD_HEADER_SZ,
04657                                 1 + RECORD_HEADER_SZ, ssl->heap);
04658                             AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
04659                         }
04660                     #endif
04661 
04662                     if (ssl->curSize != 1) {
04663                         CYASSL_MSG("Malicious or corrupted ChangeCipher msg");
04664                         return LENGTH_ERROR;
04665                     }
04666                     #ifndef NO_CERTS
04667                         if (ssl->options.side == SERVER_END &&
04668                                  ssl->options.verifyPeer &&
04669                                  ssl->options.havePeerCert)
04670                             if (!ssl->options.havePeerVerify) {
04671                                 CYASSL_MSG("client didn't send cert verify");
04672                                 return NO_PEER_VERIFY;
04673                             }
04674                     #endif
04675 
04676 
04677                     ssl->buffers.inputBuffer.idx++;
04678                     ssl->keys.encryptionOn = 1;
04679 
04680                     #ifdef CYASSL_DTLS
04681                         if (ssl->options.dtls) {
04682                             DtlsPoolReset(ssl);
04683                             ssl->keys.dtls_expected_peer_epoch++;
04684                             ssl->keys.dtls_expected_peer_sequence_number = 0;
04685                         }
04686                     #endif
04687 
04688                     #ifdef HAVE_LIBZ
04689                         if (ssl->options.usingCompression)
04690                             if ( (ret = InitStreams(ssl)) != 0)
04691                                 return ret;
04692                     #endif
04693                     if (ssl->options.resuming && ssl->options.side ==
04694                                                                     CLIENT_END)
04695                         BuildFinished(ssl, &ssl->verifyHashes, server);
04696                     else if (!ssl->options.resuming && ssl->options.side ==
04697                                                                     SERVER_END)
04698                         BuildFinished(ssl, &ssl->verifyHashes, client);
04699                     break;
04700 
04701                 case application_data:
04702                     CYASSL_MSG("got app DATA");
04703                     if ((ret = DoApplicationData(ssl,
04704                                                 ssl->buffers.inputBuffer.buffer,
04705                                                &ssl->buffers.inputBuffer.idx))
04706                                                                          != 0) {
04707                         CYASSL_ERROR(ret);
04708                         return ret;
04709                     }
04710                     break;
04711 
04712                 case alert:
04713                     CYASSL_MSG("got ALERT!");
04714                     if (DoAlert(ssl, ssl->buffers.inputBuffer.buffer,
04715                            &ssl->buffers.inputBuffer.idx, &type) == alert_fatal)
04716                         return FATAL_ERROR;
04717 
04718                     /* catch warnings that are handled as errors */
04719                     if (type == close_notify)
04720                         return ssl->error = ZERO_RETURN;
04721                            
04722                     if (type == decrypt_error)
04723                         return FATAL_ERROR;
04724                     break;
04725             
04726                 default:
04727                     CYASSL_ERROR(UNKNOWN_RECORD_TYPE);
04728                     return UNKNOWN_RECORD_TYPE;
04729             }
04730 
04731             ssl->options.processReply = doProcessInit;
04732 
04733             /* input exhausted? */
04734             if (ssl->buffers.inputBuffer.idx == ssl->buffers.inputBuffer.length)
04735                 return 0;
04736             /* more messages per record */
04737             else if ((ssl->buffers.inputBuffer.idx - startIdx) < ssl->curSize) {
04738                 CYASSL_MSG("More messages in record");
04739                 #ifdef CYASSL_DTLS
04740                     /* read-ahead but dtls doesn't bundle messages per record */
04741                     if (ssl->options.dtls) {
04742                         ssl->options.processReply = doProcessInit;
04743                         continue;
04744                     }
04745                 #endif
04746                 ssl->options.processReply = runProcessingOneMessage;
04747                 continue;
04748             }
04749             /* more records */
04750             else {
04751                 CYASSL_MSG("More records in input");
04752                 ssl->options.processReply = doProcessInit;
04753                 continue;
04754             }
04755         default:
04756             CYASSL_MSG("Bad process input state, programming error");
04757             return INPUT_CASE_ERROR;
04758         }
04759     }
04760 }
04761 
04762 
04763 int SendChangeCipher(CYASSL* ssl)
04764 {
04765     byte              *output;
04766     int                sendSz = RECORD_HEADER_SZ + ENUM_LEN;
04767     int                idx    = RECORD_HEADER_SZ;
04768     int                ret;
04769 
04770     #ifdef CYASSL_DTLS
04771         if (ssl->options.dtls) {
04772             sendSz += DTLS_RECORD_EXTRA;
04773             idx    += DTLS_RECORD_EXTRA;
04774         }
04775     #endif
04776 
04777     /* check for avalaible size */
04778     if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
04779         return ret;
04780 
04781     /* get ouput buffer */
04782     output = ssl->buffers.outputBuffer.buffer + 
04783              ssl->buffers.outputBuffer.length;
04784 
04785     AddRecordHeader(output, 1, change_cipher_spec, ssl);
04786 
04787     output[idx] = 1;             /* turn it on */
04788 
04789     #ifdef CYASSL_DTLS
04790         if (ssl->options.dtls) {
04791             if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
04792                 return ret;
04793         }
04794     #endif
04795     #ifdef CYASSL_CALLBACKS
04796         if (ssl->hsInfoOn) AddPacketName("ChangeCipher", &ssl->handShakeInfo);
04797         if (ssl->toInfoOn)
04798             AddPacketInfo("ChangeCipher", &ssl->timeoutInfo, output, sendSz,
04799                            ssl->heap);
04800     #endif
04801     ssl->buffers.outputBuffer.length += sendSz;
04802 
04803     if (ssl->options.groupMessages)
04804         return 0;
04805     #ifdef CYASSL_DTLS
04806     else if (ssl->options.dtls) {
04807         /* If using DTLS, force the ChangeCipherSpec message to be in the
04808          * same datagram as the finished message. */
04809         return 0;
04810     }
04811     #endif
04812     else
04813         return SendBuffered(ssl);
04814 }
04815 
04816 
04817 static INLINE const byte* GetMacSecret(CYASSL* ssl, int verify)
04818 {
04819     if ( (ssl->options.side == CLIENT_END && !verify) ||
04820          (ssl->options.side == SERVER_END &&  verify) )
04821         return ssl->keys.client_write_MAC_secret;
04822     else
04823         return ssl->keys.server_write_MAC_secret;
04824 }
04825 
04826 #ifndef NO_OLD_TLS
04827 static void Hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
04828                  int content, int verify)
04829 {
04830     byte   result[MAX_DIGEST_SIZE];
04831     word32 digestSz = ssl->specs.hash_size;            /* actual sizes */
04832     word32 padSz    = ssl->specs.pad_size;
04833 
04834     Md5 md5;
04835     Sha sha;
04836 
04837     /* data */
04838     byte seq[SEQ_SZ];
04839     byte conLen[ENUM_LEN + LENGTH_SZ];     /* content & length */
04840     const byte* macSecret = GetMacSecret(ssl, verify);
04841     
04842     XMEMSET(seq, 0, SEQ_SZ);
04843     conLen[0] = (byte)content;
04844     c16toa((word16)sz, &conLen[ENUM_LEN]);
04845     c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]);
04846 
04847     if (ssl->specs.mac_algorithm == md5_mac) {
04848         InitMd5(&md5);
04849         /* inner */
04850         Md5Update(&md5, macSecret, digestSz);
04851         Md5Update(&md5, PAD1, padSz);
04852         Md5Update(&md5, seq, SEQ_SZ);
04853         Md5Update(&md5, conLen, sizeof(conLen));
04854         /* in buffer */
04855         Md5Update(&md5, in, sz);
04856         Md5Final(&md5, result);
04857         /* outer */
04858         Md5Update(&md5, macSecret, digestSz);
04859         Md5Update(&md5, PAD2, padSz);
04860         Md5Update(&md5, result, digestSz);
04861         Md5Final(&md5, digest);        
04862     }
04863     else {
04864         InitSha(&sha);
04865         /* inner */
04866         ShaUpdate(&sha, macSecret, digestSz);
04867         ShaUpdate(&sha, PAD1, padSz);
04868         ShaUpdate(&sha, seq, SEQ_SZ);
04869         ShaUpdate(&sha, conLen, sizeof(conLen));
04870         /* in buffer */
04871         ShaUpdate(&sha, in, sz);
04872         ShaFinal(&sha, result);
04873         /* outer */
04874         ShaUpdate(&sha, macSecret, digestSz);
04875         ShaUpdate(&sha, PAD2, padSz);
04876         ShaUpdate(&sha, result, digestSz);
04877         ShaFinal(&sha, digest);        
04878     }
04879 }
04880 
04881 #ifndef NO_CERTS
04882 static void BuildMD5_CertVerify(CYASSL* ssl, byte* digest)
04883 {
04884     byte md5_result[MD5_DIGEST_SIZE];
04885 
04886     /* make md5 inner */
04887     Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
04888     Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
04889     Md5Final(&ssl->hashMd5, md5_result);
04890 
04891     /* make md5 outer */
04892     Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
04893     Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
04894     Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
04895 
04896     Md5Final(&ssl->hashMd5, digest);
04897 }
04898 
04899 
04900 static void BuildSHA_CertVerify(CYASSL* ssl, byte* digest)
04901 {
04902     byte sha_result[SHA_DIGEST_SIZE];
04903     
04904     /* make sha inner */
04905     ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
04906     ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
04907     ShaFinal(&ssl->hashSha, sha_result);
04908 
04909     /* make sha outer */
04910     ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
04911     ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
04912     ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
04913 
04914     ShaFinal(&ssl->hashSha, digest);
04915 }
04916 #endif /* NO_CERTS */
04917 #endif /* NO_OLD_TLS */
04918 
04919 
04920 #ifndef NO_CERTS
04921 
04922 static void BuildCertHashes(CYASSL* ssl, Hashes* hashes)
04923 {
04924     /* store current states, building requires get_digest which resets state */
04925     #ifndef NO_OLD_TLS
04926     Md5 md5 = ssl->hashMd5;
04927     Sha sha = ssl->hashSha;
04928     #endif
04929     #ifndef NO_SHA256
04930         Sha256 sha256 = ssl->hashSha256;
04931     #endif
04932     #ifdef CYASSL_SHA384
04933         Sha384 sha384 = ssl->hashSha384;
04934     #endif
04935     
04936     if (ssl->options.tls) {
04937 #if ! defined( NO_OLD_TLS )
04938         Md5Final(&ssl->hashMd5, hashes->md5);
04939         ShaFinal(&ssl->hashSha, hashes->sha);
04940 #endif
04941         if (IsAtLeastTLSv1_2(ssl)) {
04942             #ifndef NO_SHA256
04943                 Sha256Final(&ssl->hashSha256, hashes->sha256);
04944             #endif
04945             #ifdef CYASSL_SHA384
04946                 Sha384Final(&ssl->hashSha384, hashes->sha384);
04947             #endif
04948         }
04949     }
04950 #if ! defined( NO_OLD_TLS )
04951     else {
04952         BuildMD5_CertVerify(ssl, hashes->md5);
04953         BuildSHA_CertVerify(ssl, hashes->sha);
04954     }
04955     
04956     /* restore */
04957     ssl->hashMd5 = md5;
04958     ssl->hashSha = sha;
04959 #endif
04960     if (IsAtLeastTLSv1_2(ssl)) {
04961         #ifndef NO_SHA256
04962             ssl->hashSha256 = sha256;
04963         #endif
04964         #ifdef CYASSL_SHA384
04965             ssl->hashSha384 = sha384;
04966         #endif
04967     }
04968 }
04969 
04970 #endif /* CYASSL_LEANPSK */
04971 
04972 /* Build SSL Message, encrypted */
04973 static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz,
04974                         int type)
04975 {
04976     word32 digestSz = ssl->specs.hash_size;
04977     word32 sz = RECORD_HEADER_SZ + inSz + digestSz;                
04978     word32 pad  = 0, i;
04979     word32 idx  = RECORD_HEADER_SZ;
04980     word32 ivSz = 0;      /* TLSv1.1  IV */
04981     word32 headerSz = RECORD_HEADER_SZ;
04982     word16 size;
04983     byte               iv[AES_BLOCK_SIZE];                  /* max size */
04984     int ret  = 0;
04985 
04986 #ifdef CYASSL_DTLS
04987     if (ssl->options.dtls) {
04988         sz       += DTLS_RECORD_EXTRA;
04989         idx      += DTLS_RECORD_EXTRA; 
04990         headerSz += DTLS_RECORD_EXTRA;
04991     }
04992 #endif
04993 
04994     if (ssl->specs.cipher_type == block) {
04995         word32 blockSz = ssl->specs.block_size;
04996         if (ssl->options.tls1_1) {
04997             ivSz = blockSz;
04998             sz  += ivSz;
04999             RNG_GenerateBlock(ssl->rng, iv, ivSz);
05000         }
05001         sz += 1;       /* pad byte */
05002         pad = (sz - headerSz) % blockSz;
05003         pad = blockSz - pad;
05004         sz += pad;
05005     }
05006 
05007 #ifdef HAVE_AEAD
05008     if (ssl->specs.cipher_type == aead) {
05009         ivSz = AEAD_EXP_IV_SZ;
05010         sz += (ivSz + ssl->specs.aead_mac_size - digestSz);
05011         XMEMCPY(iv, ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
05012     }
05013 #endif
05014     size = (word16)(sz - headerSz);    /* include mac and digest */
05015     AddRecordHeader(output, size, (byte)type, ssl);    
05016 
05017     /* write to output */
05018     if (ivSz) {
05019         XMEMCPY(output + idx, iv, min(ivSz, sizeof(iv)));
05020         idx += ivSz;
05021     }
05022     XMEMCPY(output + idx, input, inSz);
05023     idx += inSz;
05024 
05025     if (type == handshake) {
05026         HashOutput(ssl, output, headerSz + inSz, ivSz);
05027     }
05028 
05029     if (ssl->specs.cipher_type != aead) {
05030         ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz, type, 0);
05031         idx += digestSz;
05032     }
05033 
05034     if (ssl->specs.cipher_type == block)
05035         for (i = 0; i <= pad; i++)
05036             output[idx++] = (byte)pad; /* pad byte gets pad value too */
05037 
05038     if ( (ret = Encrypt(ssl, output + headerSz, output + headerSz, size)) != 0)
05039         return ret;
05040 
05041     return sz;
05042 }
05043 
05044 
05045 int SendFinished(CYASSL* ssl)
05046 {
05047     int              sendSz,
05048                      finishedSz = ssl->options.tls ? TLS_FINISHED_SZ :
05049                                                      FINISHED_SZ;
05050     byte             input[FINISHED_SZ + DTLS_HANDSHAKE_HEADER_SZ];  /* max */
05051     byte            *output;
05052     Hashes*          hashes;
05053     int              ret;
05054     int              headerSz = HANDSHAKE_HEADER_SZ;
05055 
05056     #ifdef CYASSL_DTLS
05057         word32 sequence_number = ssl->keys.dtls_sequence_number;
05058         word16 epoch           = ssl->keys.dtls_epoch;
05059     #endif
05060 
05061 
05062     /* check for available size */
05063     if ((ret = CheckAvailableSize(ssl, sizeof(input) + MAX_MSG_EXTRA)) != 0)
05064         return ret;
05065 
05066     #ifdef CYASSL_DTLS
05067         if (ssl->options.dtls) {
05068             /* Send Finished message with the next epoch, but don't commit that
05069              * change until the other end confirms its reception. */
05070             headerSz += DTLS_HANDSHAKE_EXTRA;
05071             ssl->keys.dtls_epoch++;
05072             ssl->keys.dtls_sequence_number = 0;  /* reset after epoch change */
05073         }
05074     #endif
05075 
05076     /* get ouput buffer */
05077     output = ssl->buffers.outputBuffer.buffer + 
05078              ssl->buffers.outputBuffer.length;
05079 
05080     AddHandShakeHeader(input, finishedSz, finished, ssl);
05081 
05082     /* make finished hashes */
05083     hashes = (Hashes*)&input[headerSz];
05084     BuildFinished(ssl, hashes, ssl->options.side == CLIENT_END ? client :
05085                   server);
05086 
05087     sendSz = BuildMessage(ssl, output, input, headerSz + finishedSz, handshake);
05088 
05089     #ifdef CYASSL_DTLS
05090     if (ssl->options.dtls) {
05091         ssl->keys.dtls_epoch = epoch;
05092         ssl->keys.dtls_sequence_number = sequence_number;
05093     }
05094     #endif
05095 
05096     if (sendSz < 0)
05097         return BUILD_MSG_ERROR;
05098 
05099     if (!ssl->options.resuming) {
05100 #ifndef NO_SESSION_CACHE
05101         AddSession(ssl);    /* just try */
05102 #endif
05103         if (ssl->options.side == CLIENT_END) {
05104             BuildFinished(ssl, &ssl->verifyHashes, server);
05105         }
05106         else {
05107             ssl->options.handShakeState = HANDSHAKE_DONE;
05108             #ifdef CYASSL_DTLS
05109                 if (ssl->options.dtls) {
05110                     /* Other side will soon receive our Finished, go to next
05111                      * epoch. */
05112                     ssl->keys.dtls_epoch++;
05113                     ssl->keys.dtls_sequence_number = 1;
05114                 }
05115             #endif
05116         }
05117     }
05118     else {
05119         if (ssl->options.side == CLIENT_END) {
05120             ssl->options.handShakeState = HANDSHAKE_DONE;
05121             #ifdef CYASSL_DTLS
05122                 if (ssl->options.dtls) {
05123                     /* Other side will soon receive our Finished, go to next
05124                      * epoch. */
05125                     ssl->keys.dtls_epoch++;
05126                     ssl->keys.dtls_sequence_number = 1;
05127                 }
05128             #endif
05129         }
05130         else {
05131             BuildFinished(ssl, &ssl->verifyHashes, client);
05132         }
05133     }
05134     #ifdef CYASSL_DTLS
05135         if (ssl->options.dtls) {
05136             if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
05137                 return ret;
05138         }
05139     #endif
05140 
05141     #ifdef CYASSL_CALLBACKS
05142         if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
05143         if (ssl->toInfoOn)
05144             AddPacketInfo("Finished", &ssl->timeoutInfo, output, sendSz,
05145                           ssl->heap);
05146     #endif
05147 
05148     ssl->buffers.outputBuffer.length += sendSz;
05149 
05150     return SendBuffered(ssl);
05151 }
05152 
05153 #ifndef NO_CERTS
05154 int SendCertificate(CYASSL* ssl)
05155 {
05156     int    sendSz, length, ret = 0;
05157     word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
05158     word32 certSz, listSz;
05159     byte*  output = 0;
05160 
05161     if (ssl->options.usingPSK_cipher) return 0;  /* not needed */
05162 
05163     if (ssl->options.sendVerify == SEND_BLANK_CERT) {
05164         certSz = 0;
05165         length = CERT_HEADER_SZ;
05166         listSz = 0;
05167     }
05168     else {
05169         certSz = ssl->buffers.certificate.length;
05170         /* list + cert size */
05171         length = certSz + 2 * CERT_HEADER_SZ;
05172         listSz = certSz + CERT_HEADER_SZ;
05173 
05174         /* may need to send rest of chain, already has leading size(s) */
05175         if (ssl->buffers.certChain.buffer) {
05176             length += ssl->buffers.certChain.length;
05177             listSz += ssl->buffers.certChain.length;
05178         }
05179     }
05180     sendSz = length + RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
05181 
05182     #ifdef CYASSL_DTLS
05183         if (ssl->options.dtls) {
05184             sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
05185             i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
05186         }
05187     #endif
05188 
05189     /* check for available size */
05190     if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
05191         return ret;
05192 
05193     /* get ouput buffer */
05194     output = ssl->buffers.outputBuffer.buffer +
05195              ssl->buffers.outputBuffer.length;
05196 
05197     AddHeaders(output, length, certificate, ssl);
05198 
05199     /* list total */
05200     c32to24(listSz, output + i);
05201     i += CERT_HEADER_SZ;
05202 
05203     /* member */
05204     if (certSz) {
05205         c32to24(certSz, output + i);
05206         i += CERT_HEADER_SZ;
05207         XMEMCPY(output + i, ssl->buffers.certificate.buffer, certSz);
05208         i += certSz;
05209 
05210         /* send rest of chain? */
05211         if (ssl->buffers.certChain.buffer) {
05212             XMEMCPY(output + i, ssl->buffers.certChain.buffer,
05213                                 ssl->buffers.certChain.length);
05214             /* if add more to output adjust i
05215                i += ssl->buffers.certChain.length; */
05216         }
05217     }
05218     #ifdef CYASSL_DTLS
05219         if (ssl->options.dtls) {
05220             if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
05221                 return ret;
05222         }
05223     #endif
05224     HashOutput(ssl, output, sendSz, 0);
05225     #ifdef CYASSL_CALLBACKS
05226         if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
05227         if (ssl->toInfoOn)
05228             AddPacketInfo("Certificate", &ssl->timeoutInfo, output, sendSz,
05229                            ssl->heap);
05230     #endif
05231 
05232     if (ssl->options.side == SERVER_END)
05233         ssl->options.serverState = SERVER_CERT_COMPLETE;
05234 
05235     ssl->buffers.outputBuffer.length += sendSz;
05236     if (ssl->options.groupMessages)
05237         return 0;
05238     else
05239         return SendBuffered(ssl);
05240 }
05241 
05242 
05243 int SendCertificateRequest(CYASSL* ssl)
05244 {
05245     byte   *output;
05246     int    ret;
05247     int    sendSz;
05248     word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
05249     
05250     int  typeTotal = 1;  /* only rsa for now */
05251     int  reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ;  /* add auth later */
05252 
05253     if (IsAtLeastTLSv1_2(ssl))
05254         reqSz += LENGTH_SZ + ssl->suites->hashSigAlgoSz;
05255 
05256     if (ssl->options.usingPSK_cipher) return 0;  /* not needed */
05257 
05258     sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
05259 
05260     #ifdef CYASSL_DTLS
05261         if (ssl->options.dtls) {
05262             sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
05263             i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
05264         }
05265     #endif
05266     /* check for available size */
05267     if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
05268         return ret;
05269 
05270     /* get ouput buffer */
05271     output = ssl->buffers.outputBuffer.buffer +
05272              ssl->buffers.outputBuffer.length;
05273 
05274     AddHeaders(output, reqSz, certificate_request, ssl);
05275 
05276     /* write to output */
05277     output[i++] = (byte)typeTotal;  /* # of types */
05278     output[i++] = rsa_sign;
05279 
05280     /* supported hash/sig */
05281     if (IsAtLeastTLSv1_2(ssl)) {
05282         c16toa(ssl->suites->hashSigAlgoSz, &output[i]);
05283         i += LENGTH_SZ;
05284 
05285         XMEMCPY(&output[i],
05286                          ssl->suites->hashSigAlgo, ssl->suites->hashSigAlgoSz);
05287         i += ssl->suites->hashSigAlgoSz;
05288     }
05289 
05290     c16toa(0, &output[i]);  /* auth's */
05291     /* if add more to output, adjust i
05292     i += REQ_HEADER_SZ; */
05293 
05294     #ifdef CYASSL_DTLS
05295         if (ssl->options.dtls) {
05296             if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
05297                 return ret;
05298         }
05299     #endif
05300     HashOutput(ssl, output, sendSz, 0);
05301 
05302     #ifdef CYASSL_CALLBACKS
05303         if (ssl->hsInfoOn)
05304             AddPacketName("CertificateRequest", &ssl->handShakeInfo);
05305         if (ssl->toInfoOn)
05306             AddPacketInfo("CertificateRequest", &ssl->timeoutInfo, output,
05307                           sendSz, ssl->heap);
05308     #endif
05309     ssl->buffers.outputBuffer.length += sendSz;
05310     if (ssl->options.groupMessages)
05311         return 0;
05312     else
05313         return SendBuffered(ssl);
05314 }
05315 #endif /* !NO_CERTS */
05316 
05317 
05318 int SendData(CYASSL* ssl, const void* data, int sz)
05319 {
05320     int sent = 0,  /* plainText size */
05321         sendSz,
05322         ret;
05323 
05324     if (ssl->error == WANT_WRITE)
05325         ssl->error = 0;
05326 
05327     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
05328         int err;
05329         CYASSL_MSG("handshake not complete, trying to finish");
05330         if ( (err = CyaSSL_negotiate(ssl)) != SSL_SUCCESS) 
05331             return  err;
05332     }
05333 
05334     /* last time system socket output buffer was full, try again to send */
05335     if (ssl->buffers.outputBuffer.length > 0) {
05336         CYASSL_MSG("output buffer was full, trying to send again");
05337         if ( (ssl->error = SendBuffered(ssl)) < 0) {
05338             CYASSL_ERROR(ssl->error);
05339             if (ssl->error == SOCKET_ERROR_E && ssl->options.connReset)
05340                 return 0;     /* peer reset */
05341             return ssl->error;
05342         }
05343         else {
05344             /* advance sent to previous sent + plain size just sent */
05345             sent = ssl->buffers.prevSent + ssl->buffers.plainSz;
05346             CYASSL_MSG("sent write buffered data");
05347         }
05348     }
05349 
05350     for (;;) {
05351         int   len = min(sz - sent, OUTPUT_RECORD_SIZE);
05352         byte* out;
05353         byte* sendBuffer = (byte*)data + sent;  /* may switch on comp */
05354         int   buffSz = len;                       /* may switch on comp */
05355 #ifdef HAVE_LIBZ
05356         byte  comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
05357 #endif
05358 
05359         if (sent == sz) break;
05360 
05361 #ifdef CYASSL_DTLS
05362         if (ssl->options.dtls) {
05363             len    = min(len, MAX_UDP_SIZE);
05364             buffSz = len;
05365         }
05366 #endif
05367 
05368         /* check for available size */
05369         if ((ret = CheckAvailableSize(ssl, len + COMP_EXTRA +
05370                                       MAX_MSG_EXTRA)) != 0)
05371             return ssl->error = ret;
05372 
05373         /* get ouput buffer */
05374         out = ssl->buffers.outputBuffer.buffer +
05375               ssl->buffers.outputBuffer.length;
05376 
05377 #ifdef HAVE_LIBZ
05378         if (ssl->options.usingCompression) {
05379             buffSz = myCompress(ssl, sendBuffer, buffSz, comp, sizeof(comp));
05380             if (buffSz < 0) {
05381                 return buffSz;
05382             }
05383             sendBuffer = comp;
05384         }
05385 #endif
05386         sendSz = BuildMessage(ssl, out, sendBuffer, buffSz,
05387                               application_data);
05388 
05389         ssl->buffers.outputBuffer.length += sendSz;
05390 
05391         if ( (ret = SendBuffered(ssl)) < 0) {
05392             CYASSL_ERROR(ret);
05393             /* store for next call if WANT_WRITE or user embedSend() that
05394                doesn't present like WANT_WRITE */
05395             ssl->buffers.plainSz  = len;
05396             ssl->buffers.prevSent = sent;
05397             if (ret == SOCKET_ERROR_E && ssl->options.connReset)
05398                 return 0;  /* peer reset */
05399             return ssl->error = ret;
05400         }
05401 
05402         sent += len;
05403 
05404         /* only one message per attempt */
05405         if (ssl->options.partialWrite == 1) {
05406             CYASSL_MSG("Paritial Write on, only sending one record");
05407             break;
05408         }
05409     }
05410  
05411     return sent;
05412 }
05413 
05414 /* process input data */
05415 int ReceiveData(CYASSL* ssl, byte* output, int sz, int peek)
05416 {
05417     int size;
05418 
05419     CYASSL_ENTER("ReceiveData()");
05420 
05421     if (ssl->error == WANT_READ)
05422         ssl->error = 0;
05423 
05424     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
05425         int err;
05426         CYASSL_MSG("Handshake not complete, trying to finish");
05427         if ( (err = CyaSSL_negotiate(ssl)) != SSL_SUCCESS)
05428             return  err;
05429     }
05430 
05431     while (ssl->buffers.clearOutputBuffer.length == 0)
05432         if ( (ssl->error = ProcessReply(ssl)) < 0) {
05433             CYASSL_ERROR(ssl->error);
05434             if (ssl->error == ZERO_RETURN) {
05435                 CYASSL_MSG("Zero return, no more data coming");
05436                 return 0;         /* no more data coming */
05437             }
05438             if (ssl->error == SOCKET_ERROR_E) {
05439                 if (ssl->options.connReset || ssl->options.isClosed) {
05440                     CYASSL_MSG("Peer reset or closed, connection done");
05441                     return 0;     /* peer reset or closed */
05442                 }
05443             }
05444             return ssl->error;
05445         }
05446 
05447     if (sz < (int)ssl->buffers.clearOutputBuffer.length)
05448         size = sz;
05449     else
05450         size = ssl->buffers.clearOutputBuffer.length;
05451 
05452     XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size);
05453 
05454     if (peek == 0) {
05455         ssl->buffers.clearOutputBuffer.length -= size;
05456         ssl->buffers.clearOutputBuffer.buffer += size;
05457     }
05458    
05459     if (ssl->buffers.clearOutputBuffer.length == 0 && 
05460                                            ssl->buffers.inputBuffer.dynamicFlag)
05461        ShrinkInputBuffer(ssl, NO_FORCED_FREE);
05462 
05463     CYASSL_LEAVE("ReceiveData()", size);
05464     return size;
05465 }
05466 
05467 
05468 /* send alert message */
05469 int SendAlert(CYASSL* ssl, int severity, int type)
05470 {
05471     byte input[ALERT_SIZE];
05472     byte *output;
05473     int  sendSz;
05474     int  ret;
05475     int  dtlsExtra = 0;
05476 
05477     /* if sendalert is called again for nonbloking */
05478     if (ssl->options.sendAlertState != 0) {
05479         ret = SendBuffered(ssl);
05480         if (ret == 0)
05481             ssl->options.sendAlertState = 0;
05482         return ret;
05483     }
05484 
05485    #ifdef CYASSL_DTLS
05486         if (ssl->options.dtls)
05487            dtlsExtra = DTLS_RECORD_EXTRA; 
05488    #endif
05489 
05490     /* check for available size */
05491     if ((ret = CheckAvailableSize(ssl,
05492                                   ALERT_SIZE + MAX_MSG_EXTRA + dtlsExtra)) != 0)
05493         return ret;
05494 
05495     /* get ouput buffer */
05496     output = ssl->buffers.outputBuffer.buffer +
05497              ssl->buffers.outputBuffer.length;
05498 
05499     input[0] = (byte)severity;
05500     input[1] = (byte)type;
05501     ssl->alert_history.last_tx.code = type;
05502     ssl->alert_history.last_tx.level = severity;
05503     if (severity == alert_fatal) {
05504         ssl->options.isClosed = 1;  /* Don't send close_notify */
05505     }
05506 
05507     /* only send encrypted alert if handshake actually complete, otherwise
05508        other side may not be able to handle it */
05509     if (ssl->keys.encryptionOn && ssl->options.handShakeState == HANDSHAKE_DONE)
05510         sendSz = BuildMessage(ssl, output, input, ALERT_SIZE, alert);
05511     else {
05512 
05513         AddRecordHeader(output, ALERT_SIZE, alert, ssl);
05514         output += RECORD_HEADER_SZ;
05515         #ifdef CYASSL_DTLS
05516             if (ssl->options.dtls)
05517                 output += DTLS_RECORD_EXTRA;
05518         #endif
05519         XMEMCPY(output, input, ALERT_SIZE);
05520 
05521         sendSz = RECORD_HEADER_SZ + ALERT_SIZE;
05522         #ifdef CYASSL_DTLS
05523             if (ssl->options.dtls)
05524                 sendSz += DTLS_RECORD_EXTRA;
05525         #endif
05526     }
05527 
05528     #ifdef CYASSL_CALLBACKS
05529         if (ssl->hsInfoOn)
05530             AddPacketName("Alert", &ssl->handShakeInfo);
05531         if (ssl->toInfoOn)
05532             AddPacketInfo("Alert", &ssl->timeoutInfo, output, sendSz,ssl->heap);
05533     #endif
05534 
05535     ssl->buffers.outputBuffer.length += sendSz;
05536     ssl->options.sendAlertState = 1;
05537 
05538     return SendBuffered(ssl);
05539 }
05540 
05541 
05542 
05543 void SetErrorString(int error, char* str)
05544 {
05545     const int max = MAX_ERROR_SZ;  /* shorthand */
05546 
05547 #ifdef NO_ERROR_STRINGS
05548 
05549     (void)error;
05550     XSTRNCPY(str, "no support for error strings built in", max);
05551 
05552 #else
05553 
05554     /* pass to CTaoCrypt */
05555     if (error < MAX_CODE_E && error > MIN_CODE_E) {
05556         CTaoCryptErrorString(error, str);
05557         return;
05558     }
05559 
05560     switch (error) {
05561 
05562     case UNSUPPORTED_SUITE :
05563         XSTRNCPY(str, "unsupported cipher suite", max);
05564         break;
05565 
05566     case INPUT_CASE_ERROR :
05567         XSTRNCPY(str, "input state error", max);
05568         break;
05569 
05570     case PREFIX_ERROR :
05571         XSTRNCPY(str, "bad index to key rounds", max);
05572         break;
05573 
05574     case MEMORY_ERROR :
05575         XSTRNCPY(str, "out of memory", max);
05576         break;
05577 
05578     case VERIFY_FINISHED_ERROR :
05579         XSTRNCPY(str, "verify problem on finished", max);
05580         break;
05581 
05582     case VERIFY_MAC_ERROR :
05583         XSTRNCPY(str, "verify mac problem", max);
05584         break;
05585 
05586     case PARSE_ERROR :
05587         XSTRNCPY(str, "parse error on header", max);
05588         break;
05589 
05590     case SIDE_ERROR :
05591         XSTRNCPY(str, "wrong client/server type", max);
05592         break;
05593 
05594     case NO_PEER_CERT :
05595         XSTRNCPY(str, "peer didn't send cert", max);
05596         break;
05597 
05598     case UNKNOWN_HANDSHAKE_TYPE :
05599         XSTRNCPY(str, "weird handshake type", max);
05600         break;
05601 
05602     case SOCKET_ERROR_E :
05603         XSTRNCPY(str, "error state on socket", max);
05604         break;
05605 
05606     case SOCKET_NODATA :
05607         XSTRNCPY(str, "expected data, not there", max);
05608         break;
05609 
05610     case INCOMPLETE_DATA :
05611         XSTRNCPY(str, "don't have enough data to complete task", max);
05612         break;
05613 
05614     case UNKNOWN_RECORD_TYPE :
05615         XSTRNCPY(str, "unknown type in record hdr", max);
05616         break;
05617 
05618     case DECRYPT_ERROR :
05619         XSTRNCPY(str, "error during decryption", max);
05620         break;
05621 
05622     case FATAL_ERROR :
05623         XSTRNCPY(str, "revcd alert fatal error", max);
05624         break;
05625 
05626     case ENCRYPT_ERROR :
05627         XSTRNCPY(str, "error during encryption", max);
05628         break;
05629 
05630     case FREAD_ERROR :
05631         XSTRNCPY(str, "fread problem", max);
05632         break;
05633 
05634     case NO_PEER_KEY :
05635         XSTRNCPY(str, "need peer's key", max);
05636         break;
05637 
05638     case NO_PRIVATE_KEY :
05639         XSTRNCPY(str, "need the private key", max);
05640         break;
05641 
05642     case NO_DH_PARAMS :
05643         XSTRNCPY(str, "server missing DH params", max);
05644         break;
05645 
05646     case RSA_PRIVATE_ERROR :
05647         XSTRNCPY(str, "error during rsa priv op", max);
05648         break;
05649 
05650     case MATCH_SUITE_ERROR :
05651         XSTRNCPY(str, "can't match cipher suite", max);
05652         break;
05653 
05654     case BUILD_MSG_ERROR :
05655         XSTRNCPY(str, "build message failure", max);
05656         break;
05657 
05658     case BAD_HELLO :
05659         XSTRNCPY(str, "client hello malformed", max);
05660         break;
05661 
05662     case DOMAIN_NAME_MISMATCH :
05663         XSTRNCPY(str, "peer subject name mismatch", max);
05664         break;
05665 
05666     case WANT_READ :
05667     case SSL_ERROR_WANT_READ :
05668         XSTRNCPY(str, "non-blocking socket wants data to be read", max);
05669         break;
05670 
05671     case NOT_READY_ERROR :
05672         XSTRNCPY(str, "handshake layer not ready yet, complete first", max);
05673         break;
05674 
05675     case PMS_VERSION_ERROR :
05676         XSTRNCPY(str, "premaster secret version mismatch error", max);
05677         break;
05678 
05679     case VERSION_ERROR :
05680         XSTRNCPY(str, "record layer version error", max);
05681         break;
05682 
05683     case WANT_WRITE :
05684     case SSL_ERROR_WANT_WRITE :
05685         XSTRNCPY(str, "non-blocking socket write buffer full", max);
05686         break;
05687 
05688     case BUFFER_ERROR :
05689         XSTRNCPY(str, "malformed buffer input error", max);
05690         break;
05691 
05692     case VERIFY_CERT_ERROR :
05693         XSTRNCPY(str, "verify problem on certificate", max);
05694         break;
05695 
05696     case VERIFY_SIGN_ERROR :
05697         XSTRNCPY(str, "verify problem based on signature", max);
05698         break;
05699 
05700     case CLIENT_ID_ERROR :
05701         XSTRNCPY(str, "psk client identity error", max);
05702         break;
05703 
05704     case SERVER_HINT_ERROR:
05705         XSTRNCPY(str, "psk server hint error", max);
05706         break;
05707 
05708     case PSK_KEY_ERROR:
05709         XSTRNCPY(str, "psk key callback error", max);
05710         break;
05711 
05712     case NTRU_KEY_ERROR:
05713         XSTRNCPY(str, "NTRU key error", max);
05714         break;
05715 
05716     case NTRU_DRBG_ERROR:
05717         XSTRNCPY(str, "NTRU drbg error", max);
05718         break;
05719 
05720     case NTRU_ENCRYPT_ERROR:
05721         XSTRNCPY(str, "NTRU encrypt error", max);
05722         break;
05723 
05724     case NTRU_DECRYPT_ERROR:
05725         XSTRNCPY(str, "NTRU decrypt error", max);
05726         break;
05727 
05728     case ZLIB_INIT_ERROR:
05729         XSTRNCPY(str, "zlib init error", max);
05730         break;
05731 
05732     case ZLIB_COMPRESS_ERROR:
05733         XSTRNCPY(str, "zlib compress error", max);
05734         break;
05735 
05736     case ZLIB_DECOMPRESS_ERROR:
05737         XSTRNCPY(str, "zlib decompress error", max);
05738         break;
05739 
05740     case GETTIME_ERROR:
05741         XSTRNCPY(str, "gettimeofday() error", max);
05742         break;
05743 
05744     case GETITIMER_ERROR:
05745         XSTRNCPY(str, "getitimer() error", max);
05746         break;
05747 
05748     case SIGACT_ERROR:
05749         XSTRNCPY(str, "sigaction() error", max);
05750         break;
05751 
05752     case SETITIMER_ERROR:
05753         XSTRNCPY(str, "setitimer() error", max);
05754         break;
05755 
05756     case LENGTH_ERROR:
05757         XSTRNCPY(str, "record layer length error", max);
05758         break;
05759 
05760     case PEER_KEY_ERROR:
05761         XSTRNCPY(str, "cant decode peer key", max);
05762         break;
05763 
05764     case ZERO_RETURN:
05765     case SSL_ERROR_ZERO_RETURN:
05766         XSTRNCPY(str, "peer sent close notify alert", max);
05767         break;
05768 
05769     case ECC_CURVETYPE_ERROR:
05770         XSTRNCPY(str, "Bad ECC Curve Type or unsupported", max);
05771         break;
05772 
05773     case ECC_CURVE_ERROR:
05774         XSTRNCPY(str, "Bad ECC Curve or unsupported", max);
05775         break;
05776 
05777     case ECC_PEERKEY_ERROR:
05778         XSTRNCPY(str, "Bad ECC Peer Key", max);
05779         break;
05780 
05781     case ECC_MAKEKEY_ERROR:
05782         XSTRNCPY(str, "ECC Make Key failure", max);
05783         break;
05784 
05785     case ECC_EXPORT_ERROR:
05786         XSTRNCPY(str, "ECC Export Key failure", max);
05787         break;
05788 
05789     case ECC_SHARED_ERROR:
05790         XSTRNCPY(str, "ECC DHE shared failure", max);
05791         break;
05792 
05793     case BAD_MUTEX_ERROR:
05794         XSTRNCPY(str, "Bad mutex, operation failed", max);
05795         break;
05796 
05797     case NOT_CA_ERROR:
05798         XSTRNCPY(str, "Not a CA by basic constraint error", max);
05799         break;
05800 
05801     case BAD_PATH_ERROR:
05802         XSTRNCPY(str, "Bad path for opendir error", max);
05803         break;
05804 
05805     case BAD_CERT_MANAGER_ERROR:
05806         XSTRNCPY(str, "Bad Cert Manager error", max);
05807         break;
05808 
05809     case OCSP_CERT_REVOKED:
05810         XSTRNCPY(str, "OCSP Cert revoked", max);
05811         break;
05812 
05813     case CRL_CERT_REVOKED:
05814         XSTRNCPY(str, "CRL Cert revoked", max);
05815         break;
05816 
05817     case CRL_MISSING:
05818         XSTRNCPY(str, "CRL missing, not loaded", max);
05819         break;
05820 
05821     case MONITOR_RUNNING_E:
05822         XSTRNCPY(str, "CRL monitor already running", max);
05823         break;
05824 
05825     case THREAD_CREATE_E:
05826         XSTRNCPY(str, "Thread creation problem", max);
05827         break;
05828 
05829     case OCSP_NEED_URL:
05830         XSTRNCPY(str, "OCSP need URL", max);
05831         break;
05832 
05833     case OCSP_CERT_UNKNOWN:
05834         XSTRNCPY(str, "OCSP Cert unknown", max);
05835         break;
05836 
05837     case OCSP_LOOKUP_FAIL:
05838         XSTRNCPY(str, "OCSP Responder lookup fail", max);
05839         break;
05840 
05841     case MAX_CHAIN_ERROR:
05842         XSTRNCPY(str, "Maximum Chain Depth Exceeded", max);
05843         break;
05844 
05845     case COOKIE_ERROR:
05846         XSTRNCPY(str, "DTLS Cookie Error", max);
05847         break;
05848 
05849     case SEQUENCE_ERROR:
05850         XSTRNCPY(str, "DTLS Sequence Error", max);
05851         break;
05852 
05853     case SUITES_ERROR:
05854         XSTRNCPY(str, "Suites Pointer Error", max);
05855         break;
05856 
05857     case SSL_NO_PEM_HEADER:
05858         XSTRNCPY(str, "No PEM Header Error", max);
05859         break;
05860 
05861     case OUT_OF_ORDER_E:
05862         XSTRNCPY(str, "Out of order message, fatal", max);
05863         break;
05864 
05865     case BAD_KEA_TYPE_E:
05866         XSTRNCPY(str, "Bad KEA type found", max);
05867         break;
05868 
05869     case SANITY_CIPHER_E:
05870         XSTRNCPY(str, "Sanity check on ciphertext failed", max);
05871         break;
05872 
05873     case RECV_OVERFLOW_E:
05874         XSTRNCPY(str, "Receive callback returned more than requested", max);
05875         break;
05876 
05877     case GEN_COOKIE_E:
05878         XSTRNCPY(str, "Generate Cookie Error", max);
05879         break;
05880 
05881     case NO_PEER_VERIFY:
05882         XSTRNCPY(str, "Need peer certificate verify Error", max);
05883         break;
05884 
05885     case FWRITE_ERROR:
05886         XSTRNCPY(str, "fwrite Error", max);
05887         break;
05888 
05889     case CACHE_MATCH_ERROR:
05890         XSTRNCPY(str, "Cache restore header match Error", max);
05891         break;
05892 
05893     case UNKNOWN_SNI_HOST_NAME_E:
05894         XSTRNCPY(str, "Unrecognized host name Error", max);
05895         break;
05896 
05897     default :
05898         XSTRNCPY(str, "unknown error number", max);
05899     }
05900 
05901 #endif /* NO_ERROR_STRINGS */
05902 }
05903 
05904 
05905 
05906 /* be sure to add to cipher_name_idx too !!!! */
05907 const char* const cipher_names[] = 
05908 {
05909 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
05910     "RC4-SHA",
05911 #endif
05912 
05913 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
05914     "RC4-MD5",
05915 #endif
05916 
05917 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
05918     "DES-CBC3-SHA",
05919 #endif
05920 
05921 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
05922     "AES128-SHA",
05923 #endif
05924 
05925 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
05926     "AES256-SHA",
05927 #endif
05928 
05929 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
05930     "NULL-SHA",
05931 #endif
05932 
05933 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
05934     "NULL-SHA256",
05935 #endif
05936 
05937 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
05938     "DHE-RSA-AES128-SHA",
05939 #endif
05940 
05941 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
05942     "DHE-RSA-AES256-SHA",
05943 #endif
05944 
05945 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
05946     "PSK-AES128-CBC-SHA256",
05947 #endif
05948 
05949 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
05950     "PSK-AES128-CBC-SHA",
05951 #endif
05952 
05953 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
05954     "PSK-AES256-CBC-SHA",
05955 #endif
05956 
05957 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
05958     "PSK-AES128-CCM-8",
05959 #endif
05960 
05961 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
05962     "PSK-AES256-CCM-8",
05963 #endif
05964 
05965 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
05966     "PSK-NULL-SHA256",
05967 #endif
05968 
05969 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
05970     "PSK-NULL-SHA",
05971 #endif
05972 
05973 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
05974     "HC128-MD5",
05975 #endif
05976     
05977 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
05978     "HC128-SHA",
05979 #endif
05980 
05981 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
05982     "RABBIT-SHA",
05983 #endif
05984 
05985 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
05986     "NTRU-RC4-SHA",
05987 #endif
05988 
05989 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
05990     "NTRU-DES-CBC3-SHA",
05991 #endif
05992 
05993 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
05994     "NTRU-AES128-SHA",
05995 #endif
05996 
05997 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
05998     "NTRU-AES256-SHA",
05999 #endif
06000 
06001 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
06002     "AES128-CCM-8",
06003 #endif
06004 
06005 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
06006     "AES256-CCM-8",
06007 #endif
06008 
06009 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
06010     "ECDHE-ECDSA-AES128-CCM-8",
06011 #endif
06012 
06013 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
06014     "ECDHE-ECDSA-AES256-CCM-8",
06015 #endif
06016 
06017 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
06018     "ECDHE-RSA-AES128-SHA",
06019 #endif
06020 
06021 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
06022     "ECDHE-RSA-AES256-SHA",
06023 #endif
06024 
06025 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
06026     "ECDHE-ECDSA-AES128-SHA",
06027 #endif
06028 
06029 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
06030     "ECDHE-ECDSA-AES256-SHA",
06031 #endif
06032 
06033 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
06034     "ECDHE-RSA-RC4-SHA",
06035 #endif
06036 
06037 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
06038     "ECDHE-RSA-DES-CBC3-SHA",
06039 #endif
06040 
06041 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
06042     "ECDHE-ECDSA-RC4-SHA",
06043 #endif
06044 
06045 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
06046     "ECDHE-ECDSA-DES-CBC3-SHA",
06047 #endif
06048 
06049 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
06050     "AES128-SHA256",
06051 #endif
06052 
06053 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
06054     "AES256-SHA256",
06055 #endif
06056 
06057 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
06058     "DHE-RSA-AES128-SHA256",
06059 #endif
06060 
06061 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
06062     "DHE-RSA-AES256-SHA256",
06063 #endif
06064 
06065 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
06066     "ECDH-RSA-AES128-SHA",
06067 #endif
06068 
06069 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
06070     "ECDH-RSA-AES256-SHA",
06071 #endif
06072 
06073 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
06074     "ECDH-ECDSA-AES128-SHA",
06075 #endif
06076 
06077 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
06078     "ECDH-ECDSA-AES256-SHA",
06079 #endif
06080 
06081 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
06082     "ECDH-RSA-RC4-SHA",
06083 #endif
06084 
06085 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
06086     "ECDH-RSA-DES-CBC3-SHA",
06087 #endif
06088 
06089 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
06090     "ECDH-ECDSA-RC4-SHA",
06091 #endif
06092 
06093 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
06094     "ECDH-ECDSA-DES-CBC3-SHA",
06095 #endif
06096 
06097 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
06098     "AES128-GCM-SHA256",
06099 #endif
06100 
06101 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
06102     "AES256-GCM-SHA384",
06103 #endif
06104 
06105 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
06106     "DHE-RSA-AES128-GCM-SHA256",
06107 #endif
06108 
06109 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
06110     "DHE-RSA-AES256-GCM-SHA384",
06111 #endif
06112 
06113 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
06114     "ECDHE-RSA-AES128-GCM-SHA256",
06115 #endif
06116 
06117 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
06118     "ECDHE-RSA-AES256-GCM-SHA384",
06119 #endif
06120 
06121 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
06122     "ECDHE-ECDSA-AES128-GCM-SHA256",
06123 #endif
06124 
06125 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
06126     "ECDHE-ECDSA-AES256-GCM-SHA384",
06127 #endif
06128 
06129 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
06130     "ECDH-RSA-AES128-GCM-SHA256",
06131 #endif
06132 
06133 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
06134     "ECDH-RSA-AES256-GCM-SHA384",
06135 #endif
06136 
06137 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
06138     "ECDH-ECDSA-AES128-GCM-SHA256",
06139 #endif
06140 
06141 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
06142     "ECDH-ECDSA-AES256-GCM-SHA384",
06143 #endif
06144 
06145 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
06146     "CAMELLIA128-SHA",
06147 #endif
06148 
06149 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
06150     "DHE-RSA-CAMELLIA128-SHA",
06151 #endif
06152 
06153 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
06154     "CAMELLIA256-SHA",
06155 #endif
06156 
06157 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
06158     "DHE-RSA-CAMELLIA256-SHA",
06159 #endif
06160 
06161 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
06162     "CAMELLIA128-SHA256",
06163 #endif
06164 
06165 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
06166     "DHE-RSA-CAMELLIA128-SHA256",
06167 #endif
06168 
06169 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
06170     "CAMELLIA256-SHA256",
06171 #endif
06172 
06173 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
06174     "DHE-RSA-CAMELLIA256-SHA256",
06175 #endif
06176 
06177 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
06178     "ECDHE-RSA-AES128-SHA256",
06179 #endif
06180 
06181 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
06182     "ECDHE-ECDSA-AES128-SHA256",
06183 #endif
06184 
06185 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
06186     "ECDH-RSA-AES128-SHA256",
06187 #endif
06188 
06189 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
06190     "ECDH-ECDSA-AES128-SHA256",
06191 #endif
06192 
06193 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
06194     "ECDHE-RSA-AES256-SHA384",
06195 #endif
06196 
06197 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
06198     "ECDHE-ECDSA-AES256-SHA384",
06199 #endif
06200 
06201 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
06202     "ECDH-RSA-AES256-SHA384",
06203 #endif
06204 
06205 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
06206     "ECDH-ECDSA-AES256-SHA384",
06207 #endif
06208 
06209 };
06210 
06211 
06212 
06213 /* cipher suite number that matches above name table */
06214 int cipher_name_idx[] =
06215 {
06216 
06217 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
06218     SSL_RSA_WITH_RC4_128_SHA,
06219 #endif
06220 
06221 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
06222     SSL_RSA_WITH_RC4_128_MD5,
06223 #endif
06224 
06225 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
06226     SSL_RSA_WITH_3DES_EDE_CBC_SHA,
06227 #endif
06228 
06229 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
06230     TLS_RSA_WITH_AES_128_CBC_SHA,    
06231 #endif
06232 
06233 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
06234     TLS_RSA_WITH_AES_256_CBC_SHA,
06235 #endif
06236 
06237 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
06238     TLS_RSA_WITH_NULL_SHA,
06239 #endif
06240 
06241 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
06242     TLS_RSA_WITH_NULL_SHA256,
06243 #endif
06244 
06245 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
06246     TLS_DHE_RSA_WITH_AES_128_CBC_SHA,    
06247 #endif
06248 
06249 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
06250     TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
06251 #endif
06252 
06253 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
06254     TLS_PSK_WITH_AES_128_CBC_SHA256,    
06255 #endif
06256 
06257 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
06258     TLS_PSK_WITH_AES_128_CBC_SHA,    
06259 #endif
06260 
06261 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
06262     TLS_PSK_WITH_AES_256_CBC_SHA,
06263 #endif
06264 
06265 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
06266     TLS_PSK_WITH_AES_128_CCM_8,
06267 #endif
06268 
06269 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
06270     TLS_PSK_WITH_AES_256_CCM_8,
06271 #endif
06272 
06273 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
06274     TLS_PSK_WITH_NULL_SHA256,
06275 #endif
06276 
06277 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
06278     TLS_PSK_WITH_NULL_SHA,
06279 #endif
06280 
06281 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
06282     TLS_RSA_WITH_HC_128_CBC_MD5,    
06283 #endif
06284 
06285 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
06286     TLS_RSA_WITH_HC_128_CBC_SHA,    
06287 #endif
06288 
06289 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
06290     TLS_RSA_WITH_RABBIT_CBC_SHA,    
06291 #endif
06292 
06293 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
06294     TLS_NTRU_RSA_WITH_RC4_128_SHA,
06295 #endif
06296 
06297 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
06298     TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA,
06299 #endif
06300 
06301 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
06302     TLS_NTRU_RSA_WITH_AES_128_CBC_SHA,    
06303 #endif
06304 
06305 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
06306     TLS_NTRU_RSA_WITH_AES_256_CBC_SHA,    
06307 #endif
06308 
06309 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
06310     TLS_RSA_WITH_AES_128_CCM_8,
06311 #endif
06312 
06313 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
06314     TLS_RSA_WITH_AES_256_CCM_8,
06315 #endif
06316 
06317 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
06318     TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
06319 #endif
06320 
06321 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
06322     TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
06323 #endif
06324 
06325 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
06326     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,    
06327 #endif
06328 
06329 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
06330     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
06331 #endif
06332 
06333 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
06334     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,    
06335 #endif
06336 
06337 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
06338     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
06339 #endif
06340 
06341 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
06342     TLS_ECDHE_RSA_WITH_RC4_128_SHA,    
06343 #endif
06344 
06345 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
06346     TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,    
06347 #endif
06348 
06349 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
06350     TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,    
06351 #endif
06352 
06353 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
06354     TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,    
06355 #endif
06356 
06357 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
06358     TLS_RSA_WITH_AES_128_CBC_SHA256,    
06359 #endif
06360 
06361 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
06362     TLS_RSA_WITH_AES_256_CBC_SHA256,
06363 #endif
06364 
06365 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
06366     TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,    
06367 #endif
06368 
06369 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
06370     TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
06371 #endif
06372 
06373 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
06374     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
06375 #endif
06376 
06377 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
06378     TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
06379 #endif
06380 
06381 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
06382     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
06383 #endif
06384 
06385 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
06386     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
06387 #endif
06388 
06389 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
06390     TLS_ECDH_RSA_WITH_RC4_128_SHA,
06391 #endif
06392 
06393 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
06394     TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
06395 #endif
06396 
06397 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
06398     TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
06399 #endif
06400 
06401 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
06402     TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
06403 #endif
06404 
06405 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
06406     TLS_RSA_WITH_AES_128_GCM_SHA256,
06407 #endif
06408 
06409 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
06410     TLS_RSA_WITH_AES_256_GCM_SHA384,
06411 #endif
06412 
06413 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
06414     TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
06415 #endif
06416 
06417 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
06418     TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
06419 #endif
06420 
06421 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
06422     TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
06423 #endif
06424 
06425 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
06426     TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
06427 #endif
06428 
06429 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
06430     TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
06431 #endif
06432 
06433 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
06434     TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
06435 #endif
06436 
06437 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
06438     TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
06439 #endif
06440 
06441 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
06442     TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
06443 #endif
06444 
06445 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
06446     TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
06447 #endif
06448 
06449 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
06450     TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
06451 #endif
06452 
06453 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
06454     TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
06455 #endif
06456 
06457 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
06458     TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
06459 #endif
06460 
06461 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
06462     TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
06463 #endif
06464 
06465 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
06466     TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
06467 #endif
06468 
06469 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
06470     TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
06471 #endif
06472 
06473 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
06474     TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
06475 #endif
06476 
06477 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
06478     TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
06479 #endif
06480 
06481 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
06482     TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
06483 #endif
06484 
06485 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
06486     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
06487 #endif
06488 
06489 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
06490     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
06491 #endif
06492 
06493 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
06494     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
06495 #endif
06496 
06497 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
06498     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
06499 #endif
06500 
06501 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
06502     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
06503 #endif
06504 
06505 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
06506     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
06507 #endif
06508 
06509 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
06510     TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
06511 #endif
06512 
06513 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
06514     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
06515 #endif
06516 };
06517 
06518 
06519 /* return true if set, else false */
06520 /* only supports full name from cipher_name[] delimited by : */
06521 int SetCipherList(Suites* s, const char* list)
06522 {
06523     int  ret = 0, i;
06524     char name[MAX_SUITE_NAME];
06525 
06526     char  needle[] = ":";
06527     char* haystack = (char*)list;
06528     char* prev;
06529 
06530     const int suiteSz = sizeof(cipher_names) / sizeof(cipher_names[0]);
06531     int idx = 0;
06532     int haveRSA = 0, haveECDSA = 0;
06533 
06534     if (s == NULL) {
06535         CYASSL_MSG("SetCipherList suite pointer error");
06536         return 0;    
06537     }
06538 
06539     if (!list)
06540         return 0;
06541     
06542     if (*list == 0) return 1;   /* CyaSSL default */
06543 
06544     if (XSTRNCMP(haystack, "ALL", 3) == 0) return 1;  /* CyaSSL defualt */
06545 
06546     for(;;) {
06547         word32 len;
06548         prev = haystack;
06549         haystack = XSTRSTR(haystack, needle);
06550 
06551         if (!haystack)    /* last cipher */
06552             len = min(sizeof(name), (word32)XSTRLEN(prev));
06553         else
06554             len = min(sizeof(name), (word32)(haystack - prev));
06555 
06556         XSTRNCPY(name, prev, len);
06557         name[(len == sizeof(name)) ? len - 1 : len] = 0;
06558 
06559         for (i = 0; i < suiteSz; i++)
06560             if (XSTRNCMP(name, cipher_names[i], sizeof(name)) == 0) {
06561                 if (XSTRSTR(name, "EC") || XSTRSTR(name, "CCM"))
06562                     s->suites[idx++] = ECC_BYTE;  /* ECC suite */
06563                 else
06564                     s->suites[idx++] = 0x00;      /* normal */
06565                 s->suites[idx++] = (byte)cipher_name_idx[i];
06566 
06567                 /* The suites are either ECDSA, RSA, or PSK. The RSA suites
06568                  * don't necessarily have RSA in the name. */
06569                 if ((haveECDSA == 0) && XSTRSTR(name, "ECDSA")) {
06570                     haveECDSA = 1;
06571                 }
06572                 else if ((haveRSA == 0) && (XSTRSTR(name, "PSK") == NULL)) {
06573                     haveRSA = 1;
06574                 }
06575 
06576                 if (!ret) ret = 1;   /* found at least one */
06577                 break;
06578             }
06579         if (!haystack) break;
06580         haystack++;
06581     }
06582 
06583     if (ret) {
06584         s->setSuites = 1;
06585         s->suiteSz   = (word16)idx;
06586 
06587         idx = 0;
06588         
06589         if (haveECDSA) {
06590             #ifdef CYASSL_SHA384
06591                 s->hashSigAlgo[idx++] = sha384_mac;
06592                 s->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
06593             #endif
06594             #ifndef NO_SHA256
06595                 s->hashSigAlgo[idx++] = sha256_mac;
06596                 s->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
06597             #endif
06598             s->hashSigAlgo[idx++] = sha_mac;
06599             s->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
06600         }
06601 
06602         if (haveRSA) {
06603             #ifdef CYASSL_SHA384
06604                 s->hashSigAlgo[idx++] = sha384_mac;
06605                 s->hashSigAlgo[idx++] = rsa_sa_algo;
06606             #endif
06607             #ifndef NO_SHA256
06608                 s->hashSigAlgo[idx++] = sha256_mac;
06609                 s->hashSigAlgo[idx++] = rsa_sa_algo;
06610             #endif
06611             s->hashSigAlgo[idx++] = sha_mac;
06612             s->hashSigAlgo[idx++] = rsa_sa_algo;
06613         }
06614 
06615         s->hashSigAlgoSz = (word16)idx;
06616     }
06617 
06618     return ret;
06619 }
06620 
06621 
06622 static void PickHashSigAlgo(CYASSL* ssl,
06623                              const byte* hashSigAlgo, word32 hashSigAlgoSz)
06624 {
06625     word32 i;
06626 
06627     ssl->suites->sigAlgo = ssl->specs.sig_algo;
06628     ssl->suites->hashAlgo = sha_mac;
06629 
06630     for (i = 0; i < hashSigAlgoSz; i += 2) {
06631         if (hashSigAlgo[i+1] == ssl->specs.sig_algo) {
06632             if (hashSigAlgo[i] == sha_mac) {
06633                 break;
06634             }
06635             #ifndef NO_SHA256
06636             else if (hashSigAlgo[i] == sha256_mac) {
06637                 ssl->suites->hashAlgo = sha256_mac;
06638                 break;
06639             }
06640             #endif
06641             #ifdef CYASSL_SHA384
06642             else if (hashSigAlgo[i] == sha384_mac) {
06643                 ssl->suites->hashAlgo = sha384_mac;
06644                 break;
06645             }
06646             #endif
06647         }
06648     }
06649 }
06650 
06651 
06652 #ifdef CYASSL_CALLBACKS
06653 
06654     /* Initialisze HandShakeInfo */
06655     void InitHandShakeInfo(HandShakeInfo* info)
06656     {
06657         int i;
06658 
06659         info->cipherName[0] = 0;
06660         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
06661             info->packetNames[i][0] = 0;
06662         info->numberPackets = 0;
06663         info->negotiationError = 0;
06664     }
06665 
06666     /* Set Final HandShakeInfo parameters */
06667     void FinishHandShakeInfo(HandShakeInfo* info, const CYASSL* ssl)
06668     {
06669         int i;
06670         int sz = sizeof(cipher_name_idx)/sizeof(int); 
06671 
06672         for (i = 0; i < sz; i++)
06673             if (ssl->options.cipherSuite == (byte)cipher_name_idx[i]) {
06674                 if (ssl->options.cipherSuite0 == ECC_BYTE)
06675                     continue;   /* ECC suites at end */
06676                 XSTRNCPY(info->cipherName, cipher_names[i], MAX_CIPHERNAME_SZ);
06677                 break;
06678             }
06679 
06680         /* error max and min are negative numbers */
06681         if (ssl->error <= MIN_PARAM_ERR && ssl->error >= MAX_PARAM_ERR)
06682             info->negotiationError = ssl->error;
06683     }
06684 
06685    
06686     /* Add name to info packet names, increase packet name count */
06687     void AddPacketName(const char* name, HandShakeInfo* info)
06688     {
06689         if (info->numberPackets < MAX_PACKETS_HANDSHAKE) {
06690             XSTRNCPY(info->packetNames[info->numberPackets++], name,
06691                     MAX_PACKETNAME_SZ);
06692         }
06693     } 
06694 
06695 
06696     /* Initialisze TimeoutInfo */
06697     void InitTimeoutInfo(TimeoutInfo* info)
06698     {
06699         int i;
06700 
06701         info->timeoutName[0] = 0;
06702         info->flags          = 0;
06703 
06704         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++) {
06705             info->packets[i].packetName[0]     = 0;
06706             info->packets[i].timestamp.tv_sec  = 0;
06707             info->packets[i].timestamp.tv_usec = 0;
06708             info->packets[i].bufferValue       = 0;
06709             info->packets[i].valueSz           = 0;
06710         }
06711         info->numberPackets        = 0;
06712         info->timeoutValue.tv_sec  = 0;
06713         info->timeoutValue.tv_usec = 0;
06714     }
06715 
06716 
06717     /* Free TimeoutInfo */
06718     void FreeTimeoutInfo(TimeoutInfo* info, void* heap)
06719     {
06720         int i;
06721         (void)heap;
06722         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
06723             if (info->packets[i].bufferValue) {
06724                 XFREE(info->packets[i].bufferValue, heap, DYNAMIC_TYPE_INFO);
06725                 info->packets[i].bufferValue = 0;
06726             }
06727 
06728     }
06729 
06730 
06731     /* Add PacketInfo to TimeoutInfo */
06732     void AddPacketInfo(const char* name, TimeoutInfo* info, const byte* data,
06733                        int sz, void* heap)
06734     {
06735         if (info->numberPackets < (MAX_PACKETS_HANDSHAKE - 1)) {
06736             Timeval currTime;
06737 
06738             /* may add name after */
06739             if (name)
06740                 XSTRNCPY(info->packets[info->numberPackets].packetName, name,
06741                         MAX_PACKETNAME_SZ);
06742 
06743             /* add data, put in buffer if bigger than static buffer */
06744             info->packets[info->numberPackets].valueSz = sz;
06745             if (sz < MAX_VALUE_SZ)
06746                 XMEMCPY(info->packets[info->numberPackets].value, data, sz);
06747             else {
06748                 info->packets[info->numberPackets].bufferValue =
06749                            XMALLOC(sz, heap, DYNAMIC_TYPE_INFO);
06750                 if (!info->packets[info->numberPackets].bufferValue)
06751                     /* let next alloc catch, just don't fill, not fatal here  */
06752                     info->packets[info->numberPackets].valueSz = 0;
06753                 else
06754                     XMEMCPY(info->packets[info->numberPackets].bufferValue,
06755                            data, sz);
06756             }
06757             gettimeofday(&currTime, 0);
06758             info->packets[info->numberPackets].timestamp.tv_sec  =
06759                                                              currTime.tv_sec;
06760             info->packets[info->numberPackets].timestamp.tv_usec =
06761                                                              currTime.tv_usec;
06762             info->numberPackets++;
06763         }
06764     }
06765 
06766 
06767     /* Add packet name to previsouly added packet info */
06768     void AddLateName(const char* name, TimeoutInfo* info)
06769     {
06770         /* make sure we have a valid previous one */
06771         if (info->numberPackets > 0 && info->numberPackets <
06772                                                         MAX_PACKETS_HANDSHAKE) {
06773             XSTRNCPY(info->packets[info->numberPackets - 1].packetName, name,
06774                     MAX_PACKETNAME_SZ);
06775         }
06776     }
06777 
06778     /* Add record header to previsouly added packet info */
06779     void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info)
06780     {
06781         /* make sure we have a valid previous one */
06782         if (info->numberPackets > 0 && info->numberPackets <
06783                                                         MAX_PACKETS_HANDSHAKE) {
06784             if (info->packets[info->numberPackets - 1].bufferValue)
06785                 XMEMCPY(info->packets[info->numberPackets - 1].bufferValue, rl,
06786                        RECORD_HEADER_SZ);
06787             else
06788                 XMEMCPY(info->packets[info->numberPackets - 1].value, rl,
06789                        RECORD_HEADER_SZ);
06790         }
06791     }
06792 
06793 #endif /* CYASSL_CALLBACKS */
06794 
06795 
06796 
06797 /* client only parts */
06798 #ifndef NO_CYASSL_CLIENT
06799 
06800     int SendClientHello(CYASSL* ssl)
06801     {
06802         byte              *output;
06803         word32             length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
06804         int                sendSz;
06805         int                idSz = ssl->options.resuming ? ID_LEN : 0;
06806         int                ret;
06807 
06808         if (ssl->suites == NULL) {
06809             CYASSL_MSG("Bad suites pointer in SendClientHello");
06810             return SUITES_ERROR;
06811         } 
06812 
06813         length = VERSION_SZ + RAN_LEN
06814                + idSz + ENUM_LEN                      
06815                + ssl->suites->suiteSz + SUITE_LEN
06816                + COMP_LEN + ENUM_LEN;
06817 
06818 #ifdef HAVE_TLS_EXTENSIONS
06819         length += TLSX_GetRequestSize(ssl);
06820 #else
06821         if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) {
06822             length += ssl->suites->hashSigAlgoSz + HELLO_EXT_SZ;
06823         }
06824 #endif
06825         sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
06826 
06827 #ifdef CYASSL_DTLS
06828         if (ssl->options.dtls) {
06829             length += ENUM_LEN;   /* cookie */
06830             if (ssl->arrays->cookieSz != 0) length += ssl->arrays->cookieSz;
06831             sendSz  = length + DTLS_HANDSHAKE_HEADER_SZ + DTLS_RECORD_HEADER_SZ;
06832             idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
06833         }
06834 #endif
06835 
06836         /* check for available size */
06837         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
06838             return ret;
06839 
06840         /* get ouput buffer */
06841         output = ssl->buffers.outputBuffer.buffer +
06842                  ssl->buffers.outputBuffer.length;
06843 
06844         AddHeaders(output, length, client_hello, ssl);
06845 
06846             /* client hello, first version */
06847         output[idx++] = ssl->version.major;
06848         output[idx++] = ssl->version.minor;
06849         ssl->chVersion = ssl->version;  /* store in case changed */
06850 
06851             /* then random */
06852         if (ssl->options.connectState == CONNECT_BEGIN) {
06853             RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN);
06854             
06855                 /* store random */
06856             XMEMCPY(ssl->arrays->clientRandom, output + idx, RAN_LEN);
06857         } else {
06858 #ifdef CYASSL_DTLS
06859                 /* send same random on hello again */
06860             XMEMCPY(output + idx, ssl->arrays->clientRandom, RAN_LEN);
06861 #endif
06862         }
06863         idx += RAN_LEN;
06864 
06865             /* then session id */
06866         output[idx++] = (byte)idSz;
06867         if (idSz) {
06868             XMEMCPY(output + idx, ssl->session.sessionID, ID_LEN);
06869             idx += ID_LEN;
06870         }
06871         
06872             /* then DTLS cookie */
06873 #ifdef CYASSL_DTLS
06874         if (ssl->options.dtls) {
06875             byte cookieSz = ssl->arrays->cookieSz;
06876 
06877             output[idx++] = cookieSz;
06878             if (cookieSz) {
06879                 XMEMCPY(&output[idx], ssl->arrays->cookie, cookieSz);
06880                 idx += cookieSz;
06881             }
06882         }
06883 #endif
06884             /* then cipher suites */
06885         c16toa(ssl->suites->suiteSz, output + idx);
06886         idx += 2;
06887         XMEMCPY(output + idx, &ssl->suites->suites, ssl->suites->suiteSz);
06888         idx += ssl->suites->suiteSz;
06889 
06890             /* last, compression */
06891         output[idx++] = COMP_LEN;
06892         if (ssl->options.usingCompression)
06893             output[idx++] = ZLIB_COMPRESSION;
06894         else
06895             output[idx++] = NO_COMPRESSION;
06896 
06897 #ifdef HAVE_TLS_EXTENSIONS
06898         idx += TLSX_WriteRequest(ssl, output + idx);
06899 
06900         (void)idx; /* suppress analyzer warning, keep idx current */
06901 #else
06902         if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
06903         {
06904             int i;
06905             /* add in the extensions length */
06906             c16toa(HELLO_EXT_LEN + ssl->suites->hashSigAlgoSz, output + idx);
06907             idx += 2;
06908 
06909             c16toa(HELLO_EXT_SIG_ALGO, output + idx);
06910             idx += 2;
06911             c16toa(HELLO_EXT_SIGALGO_SZ+ssl->suites->hashSigAlgoSz, output+idx);
06912             idx += 2;
06913             c16toa(ssl->suites->hashSigAlgoSz, output + idx);
06914             idx += 2;
06915             for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, idx++) {
06916                 output[idx] = ssl->suites->hashSigAlgo[i];
06917             }
06918         }
06919 #endif
06920 
06921         #ifdef CYASSL_DTLS
06922             if (ssl->options.dtls) {
06923                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
06924                     return ret;
06925             }
06926         #endif
06927         HashOutput(ssl, output, sendSz, 0);
06928 
06929         ssl->options.clientState = CLIENT_HELLO_COMPLETE;
06930 
06931 #ifdef CYASSL_CALLBACKS
06932         if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
06933         if (ssl->toInfoOn)
06934             AddPacketInfo("ClientHello", &ssl->timeoutInfo, output, sendSz,
06935                           ssl->heap);
06936 #endif
06937 
06938         ssl->buffers.outputBuffer.length += sendSz;
06939 
06940         return SendBuffered(ssl);
06941     }
06942 
06943 
06944     static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input,
06945                                     word32* inOutIdx)
06946     {
06947         ProtocolVersion pv;
06948         byte            cookieSz;
06949         
06950 #ifdef CYASSL_CALLBACKS
06951         if (ssl->hsInfoOn) AddPacketName("HelloVerifyRequest",
06952                                          &ssl->handShakeInfo);
06953         if (ssl->toInfoOn) AddLateName("HelloVerifyRequest", &ssl->timeoutInfo);
06954 #endif
06955 #ifdef CYASSL_DTLS
06956         if (ssl->options.dtls) {
06957             DtlsPoolReset(ssl);
06958         }
06959 #endif
06960         XMEMCPY(&pv, input + *inOutIdx, sizeof(pv));
06961         *inOutIdx += (word32)sizeof(pv);
06962         
06963         cookieSz = input[(*inOutIdx)++];
06964         
06965         if (cookieSz) {
06966 #ifdef CYASSL_DTLS
06967             if (cookieSz <= MAX_COOKIE_LEN) {
06968                 XMEMCPY(ssl->arrays->cookie, input + *inOutIdx, cookieSz);
06969                 ssl->arrays->cookieSz = cookieSz;
06970             }
06971 #endif
06972             *inOutIdx += cookieSz;
06973         }
06974         
06975         ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
06976         return 0;
06977     }
06978 
06979 
06980     static int DoServerHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
06981                              word32 helloSz)
06982     {
06983         byte b;
06984         byte compression;
06985         ProtocolVersion pv;
06986         word32 i = *inOutIdx;
06987         word32 begin = i;
06988 
06989 #ifdef CYASSL_CALLBACKS
06990         if (ssl->hsInfoOn) AddPacketName("ServerHello", &ssl->handShakeInfo);
06991         if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
06992 #endif
06993         XMEMCPY(&pv, input + i, sizeof(pv));
06994         i += (word32)sizeof(pv);
06995         if (pv.minor > ssl->version.minor) {
06996             CYASSL_MSG("Server using higher version, fatal error");
06997             return VERSION_ERROR;
06998         }
06999         else if (pv.minor < ssl->version.minor) {
07000             CYASSL_MSG("server using lower version");
07001             if (!ssl->options.downgrade) {
07002                 CYASSL_MSG("    no downgrade allowed, fatal error");
07003                 return VERSION_ERROR;
07004             }
07005             else if (pv.minor == SSLv3_MINOR) {
07006                 /* turn off tls */
07007                 CYASSL_MSG("    downgrading to SSLv3");
07008                 ssl->options.tls    = 0;
07009                 ssl->options.tls1_1 = 0;
07010                 ssl->version.minor  = SSLv3_MINOR;
07011             }
07012             else if (pv.minor == TLSv1_MINOR) {
07013                 /* turn off tls 1.1+ */
07014                 CYASSL_MSG("    downgrading to TLSv1");
07015                 ssl->options.tls1_1 = 0;
07016                 ssl->version.minor  = TLSv1_MINOR;
07017             }
07018             else if (pv.minor == TLSv1_1_MINOR) {
07019                 CYASSL_MSG("    downgrading to TLSv1.1");
07020                 ssl->version.minor  = TLSv1_1_MINOR;
07021             }
07022         }
07023         XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN);
07024         i += RAN_LEN;
07025         b = input[i++];
07026         if (b) {
07027             XMEMCPY(ssl->arrays->sessionID, input + i, min(b, ID_LEN));
07028             i += b;
07029             ssl->options.haveSessionId = 1;
07030         }
07031         ssl->options.cipherSuite0 = input[i++];
07032         ssl->options.cipherSuite  = input[i++];  
07033         compression = input[i++];
07034 
07035         if (compression != ZLIB_COMPRESSION && ssl->options.usingCompression) {
07036             CYASSL_MSG("Server refused compression, turning off"); 
07037             ssl->options.usingCompression = 0;  /* turn off if server refused */
07038         }
07039 
07040         *inOutIdx = i;
07041         if ( (i - begin) < helloSz) {
07042 #ifdef HAVE_TLS_EXTENSIONS
07043             if (IsTLS(ssl)) {
07044                 int ret = 0;
07045                 word16 totalExtSz;
07046                 Suites clSuites; /* just for compatibility right now */
07047 
07048                 ato16(&input[i], &totalExtSz);
07049                 i += LENGTH_SZ;
07050                 if (totalExtSz > helloSz + begin - i)
07051                     return INCOMPLETE_DATA;
07052 
07053                 if ((ret = TLSX_Parse(ssl, (byte *) input + i,
07054                                                      totalExtSz, 0, &clSuites)))
07055                     return ret;
07056 
07057                 i += totalExtSz;
07058                 *inOutIdx = i;
07059             }
07060             else
07061 #endif
07062                 *inOutIdx = begin + helloSz;  /* skip extensions */
07063         }
07064 
07065         ssl->options.serverState = SERVER_HELLO_COMPLETE;
07066 
07067         if (ssl->options.resuming) {
07068             if (ssl->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID,
07069                                          ssl->session.sessionID, ID_LEN) == 0) {
07070                 if (SetCipherSpecs(ssl) == 0) {
07071                     int ret = -1; 
07072                     XMEMCPY(ssl->arrays->masterSecret,
07073                             ssl->session.masterSecret, SECRET_LEN);
07074                     #ifdef NO_OLD_TLS
07075                         ret = DeriveTlsKeys(ssl);
07076                     #else
07077                         #ifndef NO_TLS
07078                             if (ssl->options.tls)
07079                                 ret = DeriveTlsKeys(ssl);
07080                         #endif
07081                             if (!ssl->options.tls)
07082                                 ret = DeriveKeys(ssl);
07083                     #endif
07084                     ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
07085                     return ret;
07086                 }
07087                 else {
07088                     CYASSL_MSG("Unsupported cipher suite, DoServerHello");
07089                     return UNSUPPORTED_SUITE;
07090                 }
07091             }
07092             else {
07093                 CYASSL_MSG("Server denied resumption attempt"); 
07094                 ssl->options.resuming = 0; /* server denied resumption try */
07095             }
07096         }
07097         #ifdef CYASSL_DTLS
07098             if (ssl->options.dtls) {
07099                 DtlsPoolReset(ssl);
07100             }
07101         #endif
07102         return SetCipherSpecs(ssl);
07103     }
07104 
07105 
07106 #ifndef NO_CERTS
07107     /* just read in and ignore for now TODO: */
07108     static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32*
07109                                     inOutIdx)
07110     {
07111         word16 len;
07112        
07113         #ifdef CYASSL_CALLBACKS
07114             if (ssl->hsInfoOn)
07115                 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
07116             if (ssl->toInfoOn)
07117                 AddLateName("CertificateRequest", &ssl->timeoutInfo);
07118         #endif
07119         len = input[(*inOutIdx)++];
07120 
07121         /* types, read in here */
07122         *inOutIdx += len;
07123 
07124         if (IsAtLeastTLSv1_2(ssl)) {
07125             /* hash sig format */
07126             ato16(&input[*inOutIdx], &len);
07127             *inOutIdx += LENGTH_SZ;
07128             PickHashSigAlgo(ssl, &input[*inOutIdx], len);
07129             *inOutIdx += len;
07130         }
07131 
07132         /* authorities */
07133         ato16(&input[*inOutIdx], &len);
07134         *inOutIdx += LENGTH_SZ;
07135         while (len) {
07136             word16 dnSz;
07137        
07138             ato16(&input[*inOutIdx], &dnSz);
07139             *inOutIdx += (REQUEST_HEADER + dnSz);
07140             len -= dnSz + REQUEST_HEADER;
07141         }
07142 
07143         /* don't send client cert or cert verify if user hasn't provided
07144            cert and private key */
07145         if (ssl->buffers.certificate.buffer && ssl->buffers.key.buffer)
07146             ssl->options.sendVerify = SEND_CERT;
07147         else if (IsAtLeastTLSv1_2(ssl))
07148             ssl->options.sendVerify = SEND_BLANK_CERT;
07149 
07150         return 0;
07151     }
07152 #endif /* !NO_CERTS */
07153 
07154 
07155     static int DoServerKeyExchange(CYASSL* ssl, const byte* input,
07156                                    word32* inOutIdx)
07157     {
07158     #if defined(OPENSSL_EXTRA) || defined(HAVE_ECC)
07159         word16 length    = 0;
07160         word16 sigLen    = 0;
07161         word16 verifySz  = (word16)*inOutIdx;  /* keep start idx */
07162         byte*  signature = 0;
07163     #endif 
07164 
07165         (void)ssl;
07166         (void)input;
07167         (void)inOutIdx;
07168 
07169     #ifdef CYASSL_CALLBACKS
07170         if (ssl->hsInfoOn)
07171             AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
07172         if (ssl->toInfoOn)
07173             AddLateName("ServerKeyExchange", &ssl->timeoutInfo);
07174     #endif
07175 
07176     #ifndef NO_PSK
07177         if (ssl->specs.kea == psk_kea) {
07178             word16 pskLen = 0;
07179             ato16(&input[*inOutIdx], &pskLen);
07180             *inOutIdx += LENGTH_SZ;
07181             XMEMCPY(ssl->arrays->server_hint, &input[*inOutIdx],
07182                    min(pskLen, MAX_PSK_ID_LEN));
07183             if (pskLen < MAX_PSK_ID_LEN)
07184                 ssl->arrays->server_hint[pskLen] = 0;
07185             else
07186                 ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = 0;
07187             *inOutIdx += pskLen;
07188 
07189             return 0;
07190         }
07191     #endif
07192     #ifdef OPENSSL_EXTRA
07193         if (ssl->specs.kea == diffie_hellman_kea)
07194         {
07195         /* p */
07196         ato16(&input[*inOutIdx], &length);
07197         *inOutIdx += LENGTH_SZ;
07198 
07199         ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
07200                                                          DYNAMIC_TYPE_DH);
07201         if (ssl->buffers.serverDH_P.buffer)
07202             ssl->buffers.serverDH_P.length = length;
07203         else
07204             return MEMORY_ERROR;
07205         XMEMCPY(ssl->buffers.serverDH_P.buffer, &input[*inOutIdx], length);
07206         *inOutIdx += length;
07207 
07208         /* g */
07209         ato16(&input[*inOutIdx], &length);
07210         *inOutIdx += LENGTH_SZ;
07211 
07212         ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
07213                                                          DYNAMIC_TYPE_DH);
07214         if (ssl->buffers.serverDH_G.buffer)
07215             ssl->buffers.serverDH_G.length = length;
07216         else
07217             return MEMORY_ERROR;
07218         XMEMCPY(ssl->buffers.serverDH_G.buffer, &input[*inOutIdx], length);
07219         *inOutIdx += length;
07220 
07221         /* pub */
07222         ato16(&input[*inOutIdx], &length);
07223         *inOutIdx += LENGTH_SZ;
07224 
07225         ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap,
07226                                                            DYNAMIC_TYPE_DH);
07227         if (ssl->buffers.serverDH_Pub.buffer)
07228             ssl->buffers.serverDH_Pub.length = length;
07229         else
07230             return MEMORY_ERROR;
07231         XMEMCPY(ssl->buffers.serverDH_Pub.buffer, &input[*inOutIdx], length);
07232         *inOutIdx += length;
07233         }  /* dh_kea */
07234     #endif /* OPENSSL_EXTRA */
07235 
07236     #ifdef HAVE_ECC
07237         if (ssl->specs.kea == ecc_diffie_hellman_kea)
07238         {
07239         byte b = input[*inOutIdx];
07240         *inOutIdx += 1;
07241 
07242         if (b != named_curve)
07243             return ECC_CURVETYPE_ERROR;
07244 
07245         *inOutIdx += 1;   /* curve type, eat leading 0 */
07246         b = input[*inOutIdx];
07247         *inOutIdx += 1;
07248 
07249         if (b != secp256r1 && b != secp384r1 && b != secp521r1 && b !=
07250                  secp160r1 && b != secp192r1 && b != secp224r1)
07251             return ECC_CURVE_ERROR;
07252 
07253         length = input[*inOutIdx];
07254         *inOutIdx += 1;
07255 
07256         if (ecc_import_x963(&input[*inOutIdx], length, ssl->peerEccKey) != 0)
07257             return ECC_PEERKEY_ERROR;
07258 
07259         *inOutIdx += length;
07260         ssl->peerEccKeyPresent = 1;
07261         }
07262     #endif /* HAVE_ECC */
07263 
07264     #if defined(OPENSSL_EXTRA) || defined(HAVE_ECC)
07265     {
07266 #ifndef NO_OLD_TLS
07267         Md5    md5;
07268         Sha    sha;
07269 #endif
07270         byte   hash[FINISHED_SZ];
07271         #ifndef NO_SHA256
07272             Sha256 sha256;
07273             byte hash256[SHA256_DIGEST_SIZE];
07274         #endif
07275         #ifdef CYASSL_SHA384
07276             Sha384 sha384;
07277             byte hash384[SHA384_DIGEST_SIZE];
07278         #endif
07279         byte   messageVerify[MAX_DH_SZ];
07280         byte   hashAlgo = sha_mac;
07281         byte   sigAlgo = ssl->specs.sig_algo;
07282 
07283         /* adjust from start idx */
07284         verifySz = (word16)(*inOutIdx - verifySz);
07285 
07286         /* save message for hash verify */
07287         if (verifySz > sizeof(messageVerify))
07288             return BUFFER_ERROR;
07289         XMEMCPY(messageVerify, &input[*inOutIdx - verifySz], verifySz);
07290 
07291         if (IsAtLeastTLSv1_2(ssl)) {
07292             hashAlgo = input[*inOutIdx];
07293             *inOutIdx += 1;
07294             sigAlgo = input[*inOutIdx];
07295             *inOutIdx += 1;
07296         }
07297 
07298         /* signature */
07299         ato16(&input[*inOutIdx], &length);
07300         *inOutIdx += LENGTH_SZ;
07301 
07302         signature = (byte*)&input[*inOutIdx];
07303         *inOutIdx += length;
07304         sigLen = length;
07305 
07306         /* verify signature */
07307 #ifndef NO_OLD_TLS
07308         /* md5 */
07309         InitMd5(&md5);
07310         Md5Update(&md5, ssl->arrays->clientRandom, RAN_LEN);
07311         Md5Update(&md5, ssl->arrays->serverRandom, RAN_LEN);
07312         Md5Update(&md5, messageVerify, verifySz);
07313         Md5Final(&md5, hash);
07314 
07315         /* sha */
07316         InitSha(&sha);
07317         ShaUpdate(&sha, ssl->arrays->clientRandom, RAN_LEN);
07318         ShaUpdate(&sha, ssl->arrays->serverRandom, RAN_LEN);
07319         ShaUpdate(&sha, messageVerify, verifySz);
07320         ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
07321 #endif
07322         #ifndef NO_SHA256
07323             InitSha256(&sha256);
07324             Sha256Update(&sha256, ssl->arrays->clientRandom, RAN_LEN);
07325             Sha256Update(&sha256, ssl->arrays->serverRandom, RAN_LEN);
07326             Sha256Update(&sha256, messageVerify, verifySz);
07327             Sha256Final(&sha256, hash256);
07328         #endif
07329 
07330         #ifdef CYASSL_SHA384
07331             InitSha384(&sha384);
07332             Sha384Update(&sha384, ssl->arrays->clientRandom, RAN_LEN);
07333             Sha384Update(&sha384, ssl->arrays->serverRandom, RAN_LEN);
07334             Sha384Update(&sha384, messageVerify, verifySz);
07335             Sha384Final(&sha384, hash384);
07336         #endif
07337 #ifndef NO_RSA
07338         /* rsa */
07339         if (sigAlgo == rsa_sa_algo)
07340         {
07341             int   ret;
07342             byte* out;
07343 
07344             if (!ssl->peerRsaKeyPresent)
07345                 return NO_PEER_KEY;
07346 
07347             ret = RsaSSL_VerifyInline(signature, sigLen,&out, ssl->peerRsaKey);
07348 
07349             if (IsAtLeastTLSv1_2(ssl)) {
07350                 byte   encodedSig[MAX_ENCODED_SIG_SZ];
07351                 word32 encSigSz;
07352 #ifndef NO_OLD_TLS
07353                 byte*  digest = &hash[MD5_DIGEST_SIZE];
07354                 int    typeH = SHAh;
07355                 int    digestSz = SHA_DIGEST_SIZE;
07356 #else
07357                 byte*  digest = hash256;
07358                 int    typeH =  SHA256h;
07359                 int    digestSz = SHA256_DIGEST_SIZE;
07360 #endif
07361 
07362                 if (hashAlgo == sha_mac) {
07363                     #ifndef NO_SHA
07364                         digest   = &hash[MD5_DIGEST_SIZE];
07365                         typeH    = SHAh;
07366                         digestSz = SHA_DIGEST_SIZE;
07367                     #endif
07368                 }
07369                 else if (hashAlgo == sha256_mac) {
07370                     #ifndef NO_SHA256
07371                         digest   = hash256;
07372                         typeH    = SHA256h;
07373                         digestSz = SHA256_DIGEST_SIZE;
07374                     #endif
07375                 }
07376                 else if (hashAlgo == sha384_mac) {
07377                     #ifdef CYASSL_SHA384
07378                         digest   = hash384;
07379                         typeH    = SHA384h;
07380                         digestSz = SHA384_DIGEST_SIZE;
07381                     #endif
07382                 }
07383 
07384                 encSigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
07385 
07386                 if (encSigSz != (word32)ret || XMEMCMP(out, encodedSig,
07387                                         min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0)
07388                     return VERIFY_SIGN_ERROR;
07389             }
07390             else { 
07391                 if (ret != sizeof(hash) || XMEMCMP(out, hash,sizeof(hash)) != 0)
07392                     return VERIFY_SIGN_ERROR;
07393             }
07394         } else
07395 #endif
07396 #ifdef HAVE_ECC
07397         /* ecdsa */
07398         if (sigAlgo == ecc_dsa_sa_algo) {
07399             int verify = 0, ret;
07400 #ifndef NO_OLD_TLS
07401             byte* digest = &hash[MD5_DIGEST_SIZE];
07402             word32 digestSz = SHA_DIGEST_SIZE;
07403 #else
07404             byte* digest = hash256;
07405             word32 digestSz = SHA256_DIGEST_SIZE;
07406 #endif
07407             if (!ssl->peerEccDsaKeyPresent)
07408                 return NO_PEER_KEY;
07409 
07410             if (IsAtLeastTLSv1_2(ssl)) {
07411                 if (hashAlgo == sha_mac) {
07412                     #ifndef NO_SHA
07413                         digest   = &hash[MD5_DIGEST_SIZE];
07414                         digestSz = SHA_DIGEST_SIZE;
07415                     #endif
07416                 }
07417                 else if (hashAlgo == sha256_mac) {
07418                     #ifndef NO_SHA256
07419                         digest   = hash256;
07420                         digestSz = SHA256_DIGEST_SIZE;
07421                     #endif
07422                 }
07423                 else if (hashAlgo == sha384_mac) {
07424                     #ifdef CYASSL_SHA384
07425                         digest   = hash384;
07426                         digestSz = SHA384_DIGEST_SIZE;
07427                     #endif
07428                 }
07429             }
07430 
07431             ret = ecc_verify_hash(signature, sigLen, digest, digestSz,
07432                                   &verify, ssl->peerEccDsaKey);
07433             if (ret != 0 || verify == 0)
07434                 return VERIFY_SIGN_ERROR;
07435         }
07436         else
07437 #endif /* HAVE_ECC */
07438             return ALGO_ID_E;
07439 
07440         ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
07441 
07442         return 0;
07443 
07444     }
07445 #else  /* HAVE_OPENSSL or HAVE_ECC */
07446         return NOT_COMPILED_IN;  /* not supported by build */
07447 #endif /* HAVE_OPENSSL or HAVE_ECC */
07448     }
07449 
07450 
07451     int SendClientKeyExchange(CYASSL* ssl)
07452     {
07453         byte   encSecret[MAX_ENCRYPT_SZ];
07454         word32 encSz = 0;
07455         word32 idx = 0;
07456         int    ret = 0;
07457 
07458         switch (ssl->specs.kea) {
07459         #ifndef NO_RSA
07460             case rsa_kea:
07461                 RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret,
07462                                   SECRET_LEN);
07463                 ssl->arrays->preMasterSecret[0] = ssl->chVersion.major;
07464                 ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor;
07465                 ssl->arrays->preMasterSz = SECRET_LEN;
07466 
07467                 if (ssl->peerRsaKeyPresent == 0)
07468                     return NO_PEER_KEY;
07469 
07470                 ret = RsaPublicEncrypt(ssl->arrays->preMasterSecret, SECRET_LEN,
07471                                  encSecret, sizeof(encSecret), ssl->peerRsaKey,
07472                                  ssl->rng);
07473                 if (ret > 0) {
07474                     encSz = ret;
07475                     ret = 0;   /* set success to 0 */
07476                 }
07477                 break;
07478         #endif
07479         #ifdef OPENSSL_EXTRA
07480             case diffie_hellman_kea:
07481                 {
07482                     buffer  serverP   = ssl->buffers.serverDH_P;
07483                     buffer  serverG   = ssl->buffers.serverDH_G;
07484                     buffer  serverPub = ssl->buffers.serverDH_Pub;
07485                     byte    priv[ENCRYPT_LEN];
07486                     word32  privSz = 0;
07487                     DhKey   key;
07488 
07489                     if (serverP.buffer == 0 || serverG.buffer == 0 ||
07490                                                serverPub.buffer == 0)
07491                         return NO_PEER_KEY;
07492 
07493                     InitDhKey(&key);
07494                     ret = DhSetKey(&key, serverP.buffer, serverP.length,
07495                                    serverG.buffer, serverG.length);
07496                     if (ret == 0)
07497                         /* for DH, encSecret is Yc, agree is pre-master */
07498                         ret = DhGenerateKeyPair(&key, ssl->rng, priv, &privSz,
07499                                                 encSecret, &encSz);
07500                     if (ret == 0)
07501                         ret = DhAgree(&key, ssl->arrays->preMasterSecret,
07502                                       &ssl->arrays->preMasterSz, priv, privSz,
07503                                       serverPub.buffer, serverPub.length);
07504                     FreeDhKey(&key);
07505                 }
07506                 break;
07507         #endif /* OPENSSL_EXTRA */
07508         #ifndef NO_PSK
07509             case psk_kea:
07510                 {
07511                     byte* pms = ssl->arrays->preMasterSecret;
07512 
07513                     ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
07514                         ssl->arrays->server_hint, ssl->arrays->client_identity,
07515                         MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
07516                     if (ssl->arrays->psk_keySz == 0 || 
07517                         ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
07518                         return PSK_KEY_ERROR;
07519                     encSz = (word32)XSTRLEN(ssl->arrays->client_identity);
07520                     if (encSz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR;
07521                     XMEMCPY(encSecret, ssl->arrays->client_identity, encSz);
07522 
07523                     /* make psk pre master secret */
07524                     /* length of key + length 0s + length of key + key */
07525                     c16toa((word16)ssl->arrays->psk_keySz, pms);
07526                     pms += 2;
07527                     XMEMSET(pms, 0, ssl->arrays->psk_keySz);
07528                     pms += ssl->arrays->psk_keySz;
07529                     c16toa((word16)ssl->arrays->psk_keySz, pms);
07530                     pms += 2;
07531                     XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
07532                     ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
07533                     XMEMSET(ssl->arrays->psk_key, 0, ssl->arrays->psk_keySz);
07534                     ssl->arrays->psk_keySz = 0; /* No further need */
07535                 }
07536                 break;
07537         #endif /* NO_PSK */
07538         #ifdef HAVE_NTRU
07539             case ntru_kea:
07540                 {
07541                     word32 rc;
07542                     word16 cipherLen = sizeof(encSecret);
07543                     DRBG_HANDLE drbg;
07544                     static uint8_t const cyasslStr[] = {
07545                         'C', 'y', 'a', 'S', 'S', 'L', ' ', 'N', 'T', 'R', 'U'
07546                     };
07547 
07548                     RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret,
07549                                       SECRET_LEN);
07550                     ssl->arrays->preMasterSz = SECRET_LEN;
07551 
07552                     if (ssl->peerNtruKeyPresent == 0)
07553                         return NO_PEER_KEY;
07554 
07555                     rc = crypto_drbg_instantiate(MAX_NTRU_BITS, cyasslStr,
07556                                                   sizeof(cyasslStr), GetEntropy,
07557                                                   &drbg);
07558                     if (rc != DRBG_OK)
07559                         return NTRU_DRBG_ERROR; 
07560 
07561                     rc = crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen,
07562                                              ssl->peerNtruKey,
07563                                              ssl->arrays->preMasterSz,
07564                                              ssl->arrays->preMasterSecret,
07565                                              &cipherLen, encSecret);
07566                     crypto_drbg_uninstantiate(drbg);
07567                     if (rc != NTRU_OK)
07568                         return NTRU_ENCRYPT_ERROR;
07569 
07570                     encSz = cipherLen;
07571                     ret = 0;
07572                 }
07573                 break;
07574         #endif /* HAVE_NTRU */
07575         #ifdef HAVE_ECC
07576             case ecc_diffie_hellman_kea:
07577                 {
07578                     ecc_key  myKey;
07579                     ecc_key* peerKey = &myKey;
07580                     word32   size = sizeof(encSecret);
07581 
07582                     if (ssl->specs.static_ecdh) {
07583                         /* TODO: EccDsa is really fixed Ecc change naming */
07584                         if (!ssl->peerEccDsaKeyPresent || !ssl->peerEccDsaKey->dp)
07585                             return NO_PEER_KEY;
07586                         peerKey = ssl->peerEccDsaKey;
07587                     }
07588                     else {
07589                         if (!ssl->peerEccKeyPresent || !ssl->peerEccKey->dp)
07590                             return NO_PEER_KEY;
07591                         peerKey = ssl->peerEccKey;
07592                     }
07593 
07594                     ecc_init(&myKey);
07595                     ret = ecc_make_key(ssl->rng, peerKey->dp->size, &myKey);
07596                     if (ret != 0)
07597                         return ECC_MAKEKEY_ERROR;
07598 
07599                     /* precede export with 1 byte length */
07600                     ret = ecc_export_x963(&myKey, encSecret + 1, &size);
07601                     encSecret[0] = (byte)size;
07602                     encSz = size + 1;
07603 
07604                     if (ret != 0)
07605                         ret = ECC_EXPORT_ERROR;
07606                     else {
07607                         size = sizeof(ssl->arrays->preMasterSecret);
07608                         ret  = ecc_shared_secret(&myKey, peerKey,
07609                                                  ssl->arrays->preMasterSecret, &size);
07610                         if (ret != 0)
07611                             ret = ECC_SHARED_ERROR;
07612                     }
07613 
07614                     ssl->arrays->preMasterSz = size;
07615                     ecc_free(&myKey);
07616                 }
07617                 break;
07618         #endif /* HAVE_ECC */
07619             default:
07620                 return ALGO_ID_E; /* unsupported kea */
07621         }
07622 
07623         if (ret == 0) {
07624             byte              *output;
07625             int                sendSz;
07626             word32             tlsSz = 0;
07627             
07628             if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea)
07629                 tlsSz = 2;
07630 
07631             if (ssl->specs.kea == ecc_diffie_hellman_kea)  /* always off */
07632                 tlsSz = 0;
07633 
07634             sendSz = encSz + tlsSz + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
07635             idx    = HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
07636 
07637             #ifdef CYASSL_DTLS
07638                 if (ssl->options.dtls) {
07639                     sendSz += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
07640                     idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
07641                 }
07642             #endif
07643 
07644             /* check for available size */
07645             if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
07646                 return ret;
07647 
07648             /* get ouput buffer */
07649             output = ssl->buffers.outputBuffer.buffer + 
07650                      ssl->buffers.outputBuffer.length;
07651 
07652             AddHeaders(output, encSz + tlsSz, client_key_exchange, ssl);
07653 
07654             if (tlsSz) {
07655                 c16toa((word16)encSz, &output[idx]);
07656                 idx += 2;
07657             }
07658             XMEMCPY(output + idx, encSecret, encSz);
07659             /* if add more to output, adjust idx
07660             idx += encSz; */
07661             #ifdef CYASSL_DTLS
07662                 if (ssl->options.dtls) {
07663                     if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
07664                         return ret;
07665                 }
07666             #endif
07667             HashOutput(ssl, output, sendSz, 0);
07668 
07669             #ifdef CYASSL_CALLBACKS
07670                 if (ssl->hsInfoOn)
07671                     AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
07672                 if (ssl->toInfoOn)
07673                     AddPacketInfo("ClientKeyExchange", &ssl->timeoutInfo,
07674                                   output, sendSz, ssl->heap);
07675             #endif
07676 
07677             ssl->buffers.outputBuffer.length += sendSz;
07678 
07679             if (ssl->options.groupMessages)
07680                 ret = 0;
07681             else
07682                 ret = SendBuffered(ssl);
07683         }
07684     
07685         if (ret == 0 || ret == WANT_WRITE) {
07686             int tmpRet = MakeMasterSecret(ssl);
07687             if (tmpRet != 0)
07688                 ret = tmpRet;   /* save WANT_WRITE unless more serious */
07689             ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
07690         }
07691         /* No further need for PMS */
07692         XMEMSET(ssl->arrays->preMasterSecret, 0, ssl->arrays->preMasterSz);
07693         ssl->arrays->preMasterSz = 0;
07694 
07695         return ret;
07696     }
07697 
07698 #ifndef NO_CERTS
07699     int SendCertificateVerify(CYASSL* ssl)
07700     {
07701         byte              *output;
07702         int                sendSz = 0, length, ret;
07703         word32             idx = 0;
07704         word32             sigOutSz = 0;
07705 #ifndef NO_RSA
07706         RsaKey             key;
07707 #endif
07708         int                usingEcc = 0;
07709 #ifdef HAVE_ECC
07710         ecc_key            eccKey;
07711 #endif
07712 
07713         (void)idx;
07714 
07715         if (ssl->options.sendVerify == SEND_BLANK_CERT)
07716             return 0;  /* sent blank cert, can't verify */
07717 
07718         /* check for available size */
07719         if ((ret = CheckAvailableSize(ssl, MAX_CERT_VERIFY_SZ)) != 0)
07720             return ret;
07721 
07722         /* get ouput buffer */
07723         output = ssl->buffers.outputBuffer.buffer +
07724                  ssl->buffers.outputBuffer.length;
07725 
07726         BuildCertHashes(ssl, &ssl->certHashes);
07727 
07728 #ifdef HAVE_ECC
07729         ecc_init(&eccKey);
07730 #endif
07731 #ifndef NO_RSA
07732         InitRsaKey(&key, ssl->heap);
07733         ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
07734                                   ssl->buffers.key.length);
07735         if (ret == 0)
07736             sigOutSz = RsaEncryptSize(&key);
07737         else 
07738 #endif
07739         {
07740     #ifdef HAVE_ECC
07741             CYASSL_MSG("Trying ECC client cert, RSA didn't work");
07742            
07743             idx = 0; 
07744             ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &eccKey,
07745                                       ssl->buffers.key.length);
07746             if (ret == 0) {
07747                 CYASSL_MSG("Using ECC client cert");
07748                 usingEcc = 1;
07749                 sigOutSz = MAX_ENCODED_SIG_SZ; 
07750             }
07751             else {
07752                 CYASSL_MSG("Bad client cert type");
07753             }
07754     #endif
07755         }
07756         if (ret == 0) {
07757             byte*  verify = (byte*)&output[RECORD_HEADER_SZ +
07758                                            HANDSHAKE_HEADER_SZ];
07759 #ifndef NO_OLD_TLS
07760             byte*  signBuffer = ssl->certHashes.md5;
07761 #else
07762             byte*  signBuffer = NULL;
07763 #endif
07764             word32 signSz = FINISHED_SZ;
07765             byte   encodedSig[MAX_ENCODED_SIG_SZ];
07766             word32 extraSz = 0;  /* tls 1.2 hash/sig */
07767 
07768             (void)encodedSig;
07769             (void)signSz;
07770             (void)signBuffer;
07771 
07772             #ifdef CYASSL_DTLS
07773                 if (ssl->options.dtls)
07774                     verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
07775             #endif
07776             length = sigOutSz;
07777             if (IsAtLeastTLSv1_2(ssl)) {
07778                 verify[0] = ssl->suites->hashAlgo;
07779                 verify[1] = usingEcc ? ecc_dsa_sa_algo : rsa_sa_algo;
07780                 extraSz = HASH_SIG_SIZE;
07781             }
07782 
07783             if (usingEcc) {
07784 #ifdef HAVE_ECC
07785                 word32 localSz = MAX_ENCODED_SIG_SZ;
07786                 word32 digestSz;
07787                 byte*  digest;
07788 #ifndef NO_OLD_TLS
07789                 /* old tls default */
07790                 digestSz = SHA_DIGEST_SIZE;
07791                 digest   = ssl->certHashes.sha;
07792 #else
07793                 /* new tls default */
07794                 digestSz = SHA256_DIGEST_SIZE;
07795                 digest   = ssl->certHashes.sha256;
07796 #endif
07797 
07798                 if (IsAtLeastTLSv1_2(ssl)) {
07799                     if (ssl->suites->hashAlgo == sha_mac) {
07800                         #ifndef NO_SHA
07801                             digest = ssl->certHashes.sha;
07802                             digestSz = SHA_DIGEST_SIZE;
07803                         #endif
07804                     }
07805                     else if (ssl->suites->hashAlgo == sha256_mac) {
07806                         #ifndef NO_SHA256
07807                             digest = ssl->certHashes.sha256;
07808                             digestSz = SHA256_DIGEST_SIZE;
07809                         #endif
07810                     }
07811                     else if (ssl->suites->hashAlgo == sha384_mac) {
07812                         #ifdef CYASSL_SHA384
07813                             digest = ssl->certHashes.sha384;
07814                             digestSz = SHA384_DIGEST_SIZE;
07815                         #endif
07816                     }
07817                 }
07818 
07819                 ret = ecc_sign_hash(digest, digestSz, encodedSig,
07820                                     &localSz, ssl->rng, &eccKey);
07821                 if (ret == 0) {
07822                     length = localSz;
07823                     c16toa((word16)length, verify + extraSz); /* prepend hdr */
07824                     XMEMCPY(verify + extraSz + VERIFY_HEADER,encodedSig,length);
07825                 }
07826 #endif
07827             }
07828 #ifndef NO_RSA
07829             else {
07830                 if (IsAtLeastTLSv1_2(ssl)) {
07831 #ifndef NO_OLD_TLS
07832                     byte* digest = ssl->certHashes.sha;
07833                     int   digestSz = SHA_DIGEST_SIZE;
07834                     int   typeH = SHAh;
07835 #else
07836                     byte* digest = ssl->certHashes.sha256;
07837                     int   digestSz = SHA256_DIGEST_SIZE;
07838                     int   typeH = SHA256h;
07839 #endif
07840 
07841                     if (ssl->suites->hashAlgo == sha_mac) {
07842                         #ifndef NO_SHA
07843                             digest = ssl->certHashes.sha;
07844                             typeH    = SHAh;
07845                             digestSz = SHA_DIGEST_SIZE;
07846                         #endif
07847                     }
07848                     else if (ssl->suites->hashAlgo == sha256_mac) {
07849                         #ifndef NO_SHA256
07850                             digest = ssl->certHashes.sha256;
07851                             typeH    = SHA256h;
07852                             digestSz = SHA256_DIGEST_SIZE;
07853                         #endif
07854                     }
07855                     else if (ssl->suites->hashAlgo == sha384_mac) {
07856                         #ifdef CYASSL_SHA384
07857                             digest = ssl->certHashes.sha384;
07858                             typeH    = SHA384h;
07859                             digestSz = SHA384_DIGEST_SIZE;
07860                         #endif
07861                     }
07862 
07863                     signSz = EncodeSignature(encodedSig, digest,digestSz,typeH);
07864                     signBuffer = encodedSig;
07865                 }
07866 
07867                 c16toa((word16)length, verify + extraSz); /* prepend hdr */
07868                 ret = RsaSSL_Sign(signBuffer, signSz, verify + extraSz +
07869                                   VERIFY_HEADER, ENCRYPT_LEN, &key, ssl->rng);
07870 
07871                 if (ret > 0)
07872                     ret = 0;  /* RSA reset */
07873             }
07874 #endif
07875             if (ret == 0) {
07876                 AddHeaders(output, length + extraSz + VERIFY_HEADER,
07877                            certificate_verify, ssl);
07878 
07879                 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + length +
07880                          extraSz + VERIFY_HEADER;
07881                 #ifdef CYASSL_DTLS
07882                     if (ssl->options.dtls) {
07883                         sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
07884                         if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
07885                             return ret;
07886                     }
07887                 #endif
07888                 HashOutput(ssl, output, sendSz, 0);
07889             }
07890         }
07891 #ifndef NO_RSA
07892         FreeRsaKey(&key);
07893 #endif
07894 #ifdef HAVE_ECC
07895         ecc_free(&eccKey);
07896 #endif
07897 
07898         if (ret == 0) {
07899             #ifdef CYASSL_CALLBACKS
07900                 if (ssl->hsInfoOn)
07901                     AddPacketName("CertificateVerify", &ssl->handShakeInfo);
07902                 if (ssl->toInfoOn)
07903                     AddPacketInfo("CertificateVerify", &ssl->timeoutInfo,
07904                                   output, sendSz, ssl->heap);
07905             #endif
07906             ssl->buffers.outputBuffer.length += sendSz;
07907             if (ssl->options.groupMessages)
07908                 return 0;
07909             else
07910                 return SendBuffered(ssl);
07911         }
07912         else
07913             return ret;
07914     }
07915 #endif /* NO_CERTS */
07916 
07917 
07918 #endif /* NO_CYASSL_CLIENT */
07919 
07920 
07921 #ifndef NO_CYASSL_SERVER
07922 
07923     int SendServerHello(CYASSL* ssl)
07924     {
07925         byte              *output;
07926         word32             length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
07927         int                sendSz;
07928         int                ret;
07929 
07930         length = VERSION_SZ + RAN_LEN
07931                + ID_LEN + ENUM_LEN                 
07932                + SUITE_LEN 
07933                + ENUM_LEN;
07934 
07935 #ifdef HAVE_TLS_EXTENSIONS
07936         length += TLSX_GetResponseSize(ssl);
07937 #endif
07938 
07939         /* check for avalaible size */
07940         if ((ret = CheckAvailableSize(ssl, MAX_HELLO_SZ)) != 0)
07941             return ret;
07942 
07943         /* get ouput buffer */
07944         output = ssl->buffers.outputBuffer.buffer + 
07945                  ssl->buffers.outputBuffer.length;
07946 
07947         sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
07948         AddHeaders(output, length, server_hello, ssl);
07949 
07950         #ifdef CYASSL_DTLS
07951             if (ssl->options.dtls) {
07952                 idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
07953                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
07954             }
07955         #endif
07956         /* now write to output */
07957             /* first version */
07958         output[idx++] = ssl->version.major;
07959         output[idx++] = ssl->version.minor;
07960 
07961             /* then random */
07962         if (!ssl->options.resuming)         
07963             RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, RAN_LEN);
07964         XMEMCPY(output + idx, ssl->arrays->serverRandom, RAN_LEN);
07965         idx += RAN_LEN;
07966 
07967 #ifdef SHOW_SECRETS
07968         {
07969             int j;
07970             printf("server random: ");
07971             for (j = 0; j < RAN_LEN; j++)
07972                 printf("%02x", ssl->arrays->serverRandom[j]);
07973             printf("\n");
07974         }
07975 #endif
07976             /* then session id */
07977         output[idx++] = ID_LEN;
07978         if (!ssl->options.resuming)
07979             RNG_GenerateBlock(ssl->rng, ssl->arrays->sessionID, ID_LEN);
07980         XMEMCPY(output + idx, ssl->arrays->sessionID, ID_LEN);
07981         idx += ID_LEN;
07982 
07983             /* then cipher suite */
07984         output[idx++] = ssl->options.cipherSuite0; 
07985         output[idx++] = ssl->options.cipherSuite;
07986 
07987             /* then compression */
07988         if (ssl->options.usingCompression)
07989             output[idx++] = ZLIB_COMPRESSION;
07990         else
07991             output[idx++] = NO_COMPRESSION;
07992 
07993             /* last, extensions */
07994 #ifdef HAVE_TLS_EXTENSIONS
07995         if (IsTLS(ssl))
07996             TLSX_WriteResponse(ssl, output + idx);
07997 #endif
07998             
07999         ssl->buffers.outputBuffer.length += sendSz;
08000         #ifdef CYASSL_DTLS
08001             if (ssl->options.dtls) {
08002                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
08003                     return ret;
08004             }
08005         #endif
08006         HashOutput(ssl, output, sendSz, 0);
08007 
08008         #ifdef CYASSL_CALLBACKS
08009             if (ssl->hsInfoOn)
08010                 AddPacketName("ServerHello", &ssl->handShakeInfo);
08011             if (ssl->toInfoOn)
08012                 AddPacketInfo("ServerHello", &ssl->timeoutInfo, output, sendSz,
08013                               ssl->heap);
08014         #endif
08015 
08016         ssl->options.serverState = SERVER_HELLO_COMPLETE;
08017 
08018         if (ssl->options.groupMessages)
08019             return 0;
08020         else
08021             return SendBuffered(ssl);
08022     }
08023 
08024 
08025 #ifdef HAVE_ECC
08026 
08027     static byte SetCurveId(int size)
08028     {
08029         switch(size) {
08030             case 20:
08031                 return secp160r1;
08032                 break;
08033             case 24:
08034                 return secp192r1;
08035                 break;
08036             case 28:
08037                 return secp224r1;
08038                 break;
08039             case 32:
08040                 return secp256r1;
08041                 break;
08042             case 48:
08043                 return secp384r1;
08044                 break;
08045             case 66:
08046                 return secp521r1;
08047                 break;
08048             default:
08049                 return 0;
08050         }        
08051     }
08052 
08053 #endif /* HAVE_ECC */
08054 
08055 
08056     int SendServerKeyExchange(CYASSL* ssl)
08057     {
08058         int ret = 0;
08059         (void)ssl;
08060 
08061         #ifndef NO_PSK
08062         if (ssl->specs.kea == psk_kea)
08063         {
08064             byte    *output;
08065             word32   length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
08066             int      sendSz;
08067             if (ssl->arrays->server_hint[0] == 0) return 0; /* don't send */
08068 
08069             /* include size part */
08070             length = (word32)XSTRLEN(ssl->arrays->server_hint);
08071             if (length > MAX_PSK_ID_LEN) return SERVER_HINT_ERROR;
08072             length += HINT_LEN_SZ;
08073             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
08074 
08075             #ifdef CYASSL_DTLS 
08076                 if (ssl->options.dtls) {
08077                     sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
08078                     idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
08079                 }
08080             #endif
08081             /* check for available size */
08082             if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
08083                return ret;
08084 
08085             /* get ouput buffer */
08086             output = ssl->buffers.outputBuffer.buffer + 
08087                      ssl->buffers.outputBuffer.length;
08088 
08089             AddHeaders(output, length, server_key_exchange, ssl);
08090 
08091             /* key data */
08092             c16toa((word16)(length - HINT_LEN_SZ), output + idx);
08093             idx += HINT_LEN_SZ;
08094             XMEMCPY(output + idx, ssl->arrays->server_hint,length -HINT_LEN_SZ);
08095 
08096             HashOutput(ssl, output, sendSz, 0);
08097 
08098             #ifdef CYASSL_CALLBACKS
08099                 if (ssl->hsInfoOn)
08100                     AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
08101                 if (ssl->toInfoOn)
08102                     AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
08103                                   output, sendSz, ssl->heap);
08104             #endif
08105 
08106             ssl->buffers.outputBuffer.length += sendSz;
08107             if (ssl->options.groupMessages)
08108                 ret = 0;
08109             else
08110                 ret = SendBuffered(ssl);
08111             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
08112         }
08113         #endif /*NO_PSK */
08114 
08115         #ifdef HAVE_ECC
08116         if (ssl->specs.kea == ecc_diffie_hellman_kea)
08117         {
08118             byte    *output;
08119             word32   length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
08120             int      sendSz;
08121             byte     exportBuf[MAX_EXPORT_ECC_SZ];
08122             word32   expSz = sizeof(exportBuf);
08123             word32   sigSz;
08124             word32   preSigSz, preSigIdx;
08125 #ifndef NO_RSA
08126             RsaKey   rsaKey;
08127 #endif
08128             ecc_key  dsaKey;
08129 
08130             if (ssl->specs.static_ecdh) {
08131                 CYASSL_MSG("Using Static ECDH, not sending ServerKeyExchagne");
08132                 return 0;
08133             }
08134 
08135             /* curve type, named curve, length(1) */
08136             length = ENUM_LEN + CURVE_LEN + ENUM_LEN;
08137             /* pub key size */
08138             CYASSL_MSG("Using ephemeral ECDH");
08139             if (ecc_export_x963(ssl->eccTempKey, exportBuf, &expSz) != 0)
08140                 return ECC_EXPORT_ERROR;
08141             length += expSz;
08142 
08143             preSigSz  = length;
08144             preSigIdx = idx;
08145 
08146 #ifndef NO_RSA
08147             InitRsaKey(&rsaKey, ssl->heap);
08148 #endif
08149             ecc_init(&dsaKey);
08150 
08151             /* sig length */
08152             length += LENGTH_SZ;
08153 
08154             if (!ssl->buffers.key.buffer) {
08155 #ifndef NO_RSA
08156                 FreeRsaKey(&rsaKey);
08157 #endif
08158                 ecc_free(&dsaKey);
08159                 return NO_PRIVATE_KEY;
08160             }
08161 
08162 #ifndef NO_RSA
08163             if (ssl->specs.sig_algo == rsa_sa_algo) {
08164                 /* rsa sig size */
08165                 word32 i = 0;
08166                 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i,
08167                                           &rsaKey, ssl->buffers.key.length);
08168                 if (ret != 0) return ret;
08169                 sigSz = RsaEncryptSize(&rsaKey); 
08170             } else 
08171 #endif
08172             if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
08173                 /* ecdsa sig size */
08174                 word32 i = 0;
08175                 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
08176                                           &dsaKey, ssl->buffers.key.length);
08177                 if (ret != 0) return ret;
08178                 sigSz = ecc_sig_size(&dsaKey) + 2;  /* worst case estimate */
08179             }
08180             else {
08181 #ifndef NO_RSA
08182                 FreeRsaKey(&rsaKey);
08183 #endif
08184                 ecc_free(&dsaKey);
08185                 return ALGO_ID_E;  /* unsupported type */
08186             }
08187             length += sigSz;
08188 
08189             if (IsAtLeastTLSv1_2(ssl))
08190                 length += HASH_SIG_SIZE;
08191 
08192             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
08193 
08194             #ifdef CYASSL_DTLS 
08195                 if (ssl->options.dtls) {
08196                     sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
08197                     idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
08198                     preSigIdx = idx;
08199                 }
08200             #endif
08201             /* check for available size */
08202             if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
08203 #ifndef NO_RSA
08204                 FreeRsaKey(&rsaKey);
08205 #endif
08206                 ecc_free(&dsaKey); 
08207                 return ret;
08208             } 
08209 
08210             /* get ouput buffer */
08211             output = ssl->buffers.outputBuffer.buffer + 
08212                      ssl->buffers.outputBuffer.length;
08213 
08214             /* record and message headers will be added below, when we're sure
08215                of the sig length */
08216 
08217             /* key exchange data */
08218             output[idx++] = named_curve;
08219             output[idx++] = 0x00;          /* leading zero */
08220             output[idx++] = SetCurveId(ecc_size(ssl->eccTempKey)); 
08221             output[idx++] = (byte)expSz;
08222             XMEMCPY(output + idx, exportBuf, expSz);
08223             idx += expSz;
08224             if (IsAtLeastTLSv1_2(ssl)) {
08225                 output[idx++] = ssl->suites->hashAlgo;
08226                 output[idx++] = ssl->suites->sigAlgo;
08227             }
08228 
08229             /* Signtaure length will be written later, when we're sure what it
08230                is */
08231 
08232             /* do signature */
08233             {
08234 #ifndef NO_OLD_TLS
08235                 Md5    md5;
08236                 Sha    sha;
08237 #endif
08238                 byte   hash[FINISHED_SZ];
08239                 #ifndef NO_SHA256
08240                     Sha256 sha256;
08241                     byte hash256[SHA256_DIGEST_SIZE];
08242                 #endif
08243                 #ifdef CYASSL_SHA384
08244                     Sha384 sha384;
08245                     byte hash384[SHA384_DIGEST_SIZE];
08246                 #endif
08247 
08248 #ifndef NO_OLD_TLS
08249                 /* md5 */
08250                 InitMd5(&md5);
08251                 Md5Update(&md5, ssl->arrays->clientRandom, RAN_LEN);
08252                 Md5Update(&md5, ssl->arrays->serverRandom, RAN_LEN);
08253                 Md5Update(&md5, output + preSigIdx, preSigSz);
08254                 Md5Final(&md5, hash);
08255 
08256                 /* sha */
08257                 InitSha(&sha);
08258                 ShaUpdate(&sha, ssl->arrays->clientRandom, RAN_LEN);
08259                 ShaUpdate(&sha, ssl->arrays->serverRandom, RAN_LEN);
08260                 ShaUpdate(&sha, output + preSigIdx, preSigSz);
08261                 ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
08262 #endif
08263 
08264                 #ifndef NO_SHA256
08265                     InitSha256(&sha256);
08266                     Sha256Update(&sha256, ssl->arrays->clientRandom, RAN_LEN);
08267                     Sha256Update(&sha256, ssl->arrays->serverRandom, RAN_LEN);
08268                     Sha256Update(&sha256, output + preSigIdx, preSigSz);
08269                     Sha256Final(&sha256, hash256);
08270                 #endif
08271 
08272                 #ifdef CYASSL_SHA384
08273                     InitSha384(&sha384);
08274                     Sha384Update(&sha384, ssl->arrays->clientRandom, RAN_LEN);
08275                     Sha384Update(&sha384, ssl->arrays->serverRandom, RAN_LEN);
08276                     Sha384Update(&sha384, output + preSigIdx, preSigSz);
08277                     Sha384Final(&sha384, hash384);
08278                 #endif
08279 #ifndef NO_RSA
08280                 if (ssl->suites->sigAlgo == rsa_sa_algo) {
08281                     byte*  signBuffer = hash;
08282                     word32 signSz    = sizeof(hash);
08283                     byte   encodedSig[MAX_ENCODED_SIG_SZ];
08284                     if (IsAtLeastTLSv1_2(ssl)) {
08285                         byte* digest   = &hash[MD5_DIGEST_SIZE];
08286                         int   typeH    = SHAh;
08287                         int   digestSz = SHA_DIGEST_SIZE;
08288 
08289                         if (ssl->suites->hashAlgo == sha256_mac) {
08290                             #ifndef NO_SHA256
08291                                 digest   = hash256;
08292                                 typeH    = SHA256h;
08293                                 digestSz = SHA256_DIGEST_SIZE;
08294                             #endif
08295                         }
08296                         else if (ssl->suites->hashAlgo == sha384_mac) {
08297                             #ifdef CYASSL_SHA384
08298                                 digest   = hash384;
08299                                 typeH    = SHA384h;
08300                                 digestSz = SHA384_DIGEST_SIZE;
08301                             #endif
08302                         }
08303 
08304                         signSz = EncodeSignature(encodedSig, digest, digestSz,
08305                                                  typeH);
08306                         signBuffer = encodedSig;
08307                     }
08308                     /* write sig size here */
08309                     c16toa((word16)sigSz, output + idx);
08310                     idx += LENGTH_SZ;
08311 
08312                     ret = RsaSSL_Sign(signBuffer, signSz, output + idx, sigSz,
08313                                       &rsaKey, ssl->rng);
08314                     FreeRsaKey(&rsaKey);
08315                     ecc_free(&dsaKey);
08316                     if (ret > 0)
08317                         ret = 0;  /* reset on success */
08318                     else
08319                         return ret;
08320                 } else 
08321 #endif
08322                 if (ssl->suites->sigAlgo == ecc_dsa_sa_algo) {
08323 #ifndef NO_OLD_TLS
08324                     byte* digest = &hash[MD5_DIGEST_SIZE];
08325                     word32 digestSz = SHA_DIGEST_SIZE;
08326 #else
08327                     byte* digest = hash256;
08328                     word32 digestSz = SHA256_DIGEST_SIZE;
08329 #endif
08330                     word32 sz = sigSz;
08331 
08332                     if (IsAtLeastTLSv1_2(ssl)) {
08333                         if (ssl->suites->hashAlgo == sha_mac) {
08334                             #ifndef NO_SHA
08335                                 digest   = &hash[MD5_DIGEST_SIZE];
08336                                 digestSz = SHA_DIGEST_SIZE;
08337                             #endif
08338                         }
08339                         else if (ssl->suites->hashAlgo == sha256_mac) {
08340                             #ifndef NO_SHA256
08341                                 digest   = hash256;
08342                                 digestSz = SHA256_DIGEST_SIZE;
08343                             #endif
08344                         }
08345                         else if (ssl->suites->hashAlgo == sha384_mac) {
08346                             #ifdef CYASSL_SHA384
08347                                 digest   = hash384;
08348                                 digestSz = SHA384_DIGEST_SIZE;
08349                             #endif
08350                         }
08351                     }
08352 
08353                     ret = ecc_sign_hash(digest, digestSz,
08354                               output + LENGTH_SZ + idx, &sz, ssl->rng, &dsaKey);
08355 #ifndef NO_RSA
08356                     FreeRsaKey(&rsaKey);
08357 #endif
08358                     ecc_free(&dsaKey);
08359                     if (ret < 0) return ret;
08360 
08361                     /* Now that we know the real sig size, write it. */
08362                     c16toa((word16)sz, output + idx);
08363 
08364                     /* And adjust length and sendSz from estimates */
08365                     length += sz - sigSz;
08366                     sendSz += sz - sigSz;
08367                 }
08368             }
08369 
08370             AddHeaders(output, length, server_key_exchange, ssl);
08371             HashOutput(ssl, output, sendSz, 0);
08372 
08373             #ifdef CYASSL_CALLBACKS
08374                 if (ssl->hsInfoOn)
08375                     AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
08376                 if (ssl->toInfoOn)
08377                     AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
08378                                   output, sendSz, ssl->heap);
08379             #endif
08380 
08381             ssl->buffers.outputBuffer.length += sendSz;
08382             if (ssl->options.groupMessages)
08383                 ret = 0;
08384             else
08385                 ret = SendBuffered(ssl);
08386             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
08387         }
08388         #endif /* HAVE_ECC */
08389 
08390         #ifdef OPENSSL_EXTRA 
08391         if (ssl->specs.kea == diffie_hellman_kea) {
08392             byte    *output;
08393             word32   length = 0, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
08394             int      sendSz;
08395             word32   sigSz = 0, i = 0;
08396             word32   preSigSz = 0, preSigIdx = 0;
08397             RsaKey   rsaKey;
08398             DhKey    dhKey;
08399             
08400             if (ssl->buffers.serverDH_P.buffer == NULL ||
08401                 ssl->buffers.serverDH_G.buffer == NULL)
08402                 return NO_DH_PARAMS;
08403 
08404             if (ssl->buffers.serverDH_Pub.buffer == NULL) {
08405                 ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
08406                         ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
08407                         DYNAMIC_TYPE_DH);
08408                 if (ssl->buffers.serverDH_Pub.buffer == NULL)
08409                     return MEMORY_E;
08410             } 
08411 
08412             if (ssl->buffers.serverDH_Priv.buffer == NULL) {
08413                 ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
08414                         ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
08415                         DYNAMIC_TYPE_DH);
08416                 if (ssl->buffers.serverDH_Priv.buffer == NULL)
08417                     return MEMORY_E;
08418             } 
08419 
08420             InitDhKey(&dhKey);
08421             ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
08422                                    ssl->buffers.serverDH_P.length,
08423                                    ssl->buffers.serverDH_G.buffer,
08424                                    ssl->buffers.serverDH_G.length);
08425             if (ret == 0)
08426                 ret = DhGenerateKeyPair(&dhKey, ssl->rng,
08427                                          ssl->buffers.serverDH_Priv.buffer,
08428                                         &ssl->buffers.serverDH_Priv.length,
08429                                          ssl->buffers.serverDH_Pub.buffer,
08430                                         &ssl->buffers.serverDH_Pub.length);
08431             FreeDhKey(&dhKey);
08432 
08433             InitRsaKey(&rsaKey, ssl->heap);
08434             if (ret == 0) {
08435                 length = LENGTH_SZ * 3;  /* p, g, pub */
08436                 length += ssl->buffers.serverDH_P.length +
08437                           ssl->buffers.serverDH_G.length + 
08438                           ssl->buffers.serverDH_Pub.length;
08439 
08440                 preSigIdx = idx;
08441                 preSigSz  = length;
08442 
08443                 /* sig length */
08444                 length += LENGTH_SZ;
08445 
08446                 if (!ssl->buffers.key.buffer)
08447                     return NO_PRIVATE_KEY;
08448 
08449                 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i, &rsaKey,
08450                                           ssl->buffers.key.length);
08451                 if (ret == 0) {
08452                     sigSz = RsaEncryptSize(&rsaKey);
08453                     length += sigSz;
08454                 }
08455             }
08456             if (ret != 0) {
08457                 FreeRsaKey(&rsaKey);
08458                 return ret;
08459             }
08460                                          
08461             if (IsAtLeastTLSv1_2(ssl))
08462                 length += HASH_SIG_SIZE;
08463 
08464             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
08465 
08466             #ifdef CYASSL_DTLS 
08467                 if (ssl->options.dtls) {
08468                     sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
08469                     idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
08470                     preSigIdx = idx;
08471                 }
08472             #endif
08473             /* check for available size */
08474             if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
08475                 FreeRsaKey(&rsaKey);
08476                 return ret;
08477             } 
08478 
08479             /* get ouput buffer */
08480             output = ssl->buffers.outputBuffer.buffer + 
08481                      ssl->buffers.outputBuffer.length;
08482 
08483             AddHeaders(output, length, server_key_exchange, ssl);
08484 
08485             /* add p, g, pub */
08486             c16toa((word16)ssl->buffers.serverDH_P.length, output + idx);
08487             idx += LENGTH_SZ;
08488             XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer,
08489                                   ssl->buffers.serverDH_P.length);
08490             idx += ssl->buffers.serverDH_P.length;
08491 
08492             /*  g */
08493             c16toa((word16)ssl->buffers.serverDH_G.length, output + idx);
08494             idx += LENGTH_SZ;
08495             XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer,
08496                                   ssl->buffers.serverDH_G.length);
08497             idx += ssl->buffers.serverDH_G.length;
08498 
08499             /*  pub */
08500             c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx);
08501             idx += LENGTH_SZ;
08502             XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer,
08503                                   ssl->buffers.serverDH_Pub.length);
08504             idx += ssl->buffers.serverDH_Pub.length;
08505 
08506             /* Add signature */
08507             if (IsAtLeastTLSv1_2(ssl)) {
08508                 output[idx++] = ssl->suites->hashAlgo;
08509                 output[idx++] = ssl->suites->sigAlgo; 
08510             }
08511             /*    size */
08512             c16toa((word16)sigSz, output + idx);
08513             idx += LENGTH_SZ;
08514 
08515             /* do signature */
08516             {
08517 #ifndef NO_OLD_TLS
08518                 Md5    md5;
08519                 Sha    sha;
08520 #endif
08521                 byte   hash[FINISHED_SZ];
08522                 #ifndef NO_SHA256
08523                     Sha256 sha256;
08524                     byte hash256[SHA256_DIGEST_SIZE];
08525                 #endif
08526                 #ifdef CYASSL_SHA384
08527                     Sha384 sha384;
08528                     byte hash384[SHA384_DIGEST_SIZE];
08529                 #endif
08530 
08531 #ifndef NO_OLD_TLS
08532                 /* md5 */
08533                 InitMd5(&md5);
08534                 Md5Update(&md5, ssl->arrays->clientRandom, RAN_LEN);
08535                 Md5Update(&md5, ssl->arrays->serverRandom, RAN_LEN);
08536                 Md5Update(&md5, output + preSigIdx, preSigSz);
08537                 Md5Final(&md5, hash);
08538 
08539                 /* sha */
08540                 InitSha(&sha);
08541                 ShaUpdate(&sha, ssl->arrays->clientRandom, RAN_LEN);
08542                 ShaUpdate(&sha, ssl->arrays->serverRandom, RAN_LEN);
08543                 ShaUpdate(&sha, output + preSigIdx, preSigSz);
08544                 ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
08545 #endif
08546 
08547                 #ifndef NO_SHA256
08548                     InitSha256(&sha256);
08549                     Sha256Update(&sha256, ssl->arrays->clientRandom, RAN_LEN);
08550                     Sha256Update(&sha256, ssl->arrays->serverRandom, RAN_LEN);
08551                     Sha256Update(&sha256, output + preSigIdx, preSigSz);
08552                     Sha256Final(&sha256, hash256);
08553                 #endif
08554 
08555                 #ifdef CYASSL_SHA384
08556                     InitSha384(&sha384);
08557                     Sha384Update(&sha384, ssl->arrays->clientRandom, RAN_LEN);
08558                     Sha384Update(&sha384, ssl->arrays->serverRandom, RAN_LEN);
08559                     Sha384Update(&sha384, output + preSigIdx, preSigSz);
08560                     Sha384Final(&sha384, hash384);
08561                 #endif
08562 #ifndef NO_RSA
08563                 if (ssl->suites->sigAlgo == rsa_sa_algo) {
08564                     byte*  signBuffer = hash;
08565                     word32 signSz    = sizeof(hash);
08566                     byte   encodedSig[MAX_ENCODED_SIG_SZ];
08567                     if (IsAtLeastTLSv1_2(ssl)) {
08568                         byte* digest   = &hash[MD5_DIGEST_SIZE];
08569                         int   typeH    = SHAh;
08570                         int   digestSz = SHA_DIGEST_SIZE;
08571 
08572                         if (ssl->suites->hashAlgo == sha256_mac) {
08573                             #ifndef NO_SHA256
08574                                 digest   = hash256;
08575                                 typeH    = SHA256h;
08576                                 digestSz = SHA256_DIGEST_SIZE;
08577                             #endif
08578                         }
08579                         else if (ssl->suites->hashAlgo == sha384_mac) {
08580                             #ifdef CYASSL_SHA384
08581                                 digest   = hash384;
08582                                 typeH    = SHA384h;
08583                                 digestSz = SHA384_DIGEST_SIZE;
08584                             #endif
08585                         }
08586 
08587                         signSz = EncodeSignature(encodedSig, digest, digestSz,
08588                                                  typeH);
08589                         signBuffer = encodedSig;
08590                     }
08591                     ret = RsaSSL_Sign(signBuffer, signSz, output + idx, sigSz,
08592                                       &rsaKey, ssl->rng);
08593                     FreeRsaKey(&rsaKey);
08594                     if (ret <= 0)
08595                         return ret;
08596                 }
08597 #endif
08598             }
08599 
08600             #ifdef CYASSL_DTLS
08601                 if (ssl->options.dtls) {
08602                     if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
08603                         return ret;
08604                 }
08605             #endif
08606             HashOutput(ssl, output, sendSz, 0);
08607 
08608             #ifdef CYASSL_CALLBACKS
08609                 if (ssl->hsInfoOn)
08610                     AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
08611                 if (ssl->toInfoOn)
08612                     AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
08613                                   output, sendSz, ssl->heap);
08614             #endif
08615 
08616             ssl->buffers.outputBuffer.length += sendSz;
08617             if (ssl->options.groupMessages)
08618                 ret = 0;
08619             else
08620                 ret = SendBuffered(ssl);
08621             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
08622         }
08623         #endif /* OPENSSL_EXTRA */
08624 
08625         return ret;
08626     }
08627 
08628 
08629     /* cipher requirements */
08630     enum {
08631         REQUIRES_RSA,
08632         REQUIRES_DHE,
08633         REQUIRES_ECC_DSA,
08634         REQUIRES_ECC_STATIC,
08635         REQUIRES_PSK,
08636         REQUIRES_NTRU,
08637         REQUIRES_RSA_SIG
08638     };
08639 
08640 
08641 
08642     /* Does this cipher suite (first, second) have the requirement
08643        an ephemeral key exchange will still require the key for signing
08644        the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */
08645     static int CipherRequires(byte first, byte second, int requirement)
08646     {
08647         /* ECC extensions */
08648         if (first == ECC_BYTE) {
08649         
08650         switch (second) {
08651 
08652 #ifndef NO_RSA
08653         case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
08654             if (requirement == REQUIRES_RSA)
08655                 return 1;
08656             break;
08657 
08658         case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
08659             if (requirement == REQUIRES_ECC_STATIC)
08660                 return 1;
08661             if (requirement == REQUIRES_RSA_SIG)
08662                 return 1;
08663             break;
08664 
08665 #ifndef NO_3DES
08666         case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
08667             if (requirement == REQUIRES_RSA)
08668                 return 1;
08669             break;
08670 
08671         case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
08672             if (requirement == REQUIRES_ECC_STATIC)
08673                 return 1;
08674             if (requirement == REQUIRES_RSA_SIG)
08675                 return 1;
08676             break;
08677 #endif
08678 
08679 #ifndef NO_RC4
08680         case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
08681             if (requirement == REQUIRES_RSA)
08682                 return 1;
08683             break;
08684 
08685         case TLS_ECDH_RSA_WITH_RC4_128_SHA :
08686             if (requirement == REQUIRES_ECC_STATIC)
08687                 return 1;
08688             if (requirement == REQUIRES_RSA_SIG)
08689                 return 1;
08690             break;
08691 #endif
08692 #endif /* NO_RSA */
08693 
08694 #ifndef NO_3DES
08695         case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
08696             if (requirement == REQUIRES_ECC_DSA)
08697                 return 1;
08698             break;
08699 
08700         case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
08701             if (requirement == REQUIRES_ECC_STATIC)
08702                 return 1;
08703             break;
08704 #endif
08705 #ifndef NO_RC4
08706         case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
08707             if (requirement == REQUIRES_ECC_DSA)
08708                 return 1;
08709             break;
08710 
08711         case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
08712             if (requirement == REQUIRES_ECC_STATIC)
08713                 return 1;
08714             break;
08715 #endif
08716 #ifndef NO_RSA
08717         case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
08718             if (requirement == REQUIRES_RSA)
08719                 return 1;
08720             break;
08721 
08722         case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
08723             if (requirement == REQUIRES_ECC_STATIC)
08724                 return 1;
08725             if (requirement == REQUIRES_RSA_SIG)
08726                 return 1;
08727             break;
08728 #endif
08729 
08730         case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
08731             if (requirement == REQUIRES_ECC_DSA)
08732                 return 1;
08733             break;
08734 
08735         case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
08736             if (requirement == REQUIRES_ECC_STATIC)
08737                 return 1;
08738             break;
08739 
08740         case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
08741             if (requirement == REQUIRES_ECC_DSA)
08742                 return 1;
08743             break;
08744 
08745         case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
08746             if (requirement == REQUIRES_ECC_STATIC)
08747                 return 1;
08748             break;
08749 
08750         case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
08751             if (requirement == REQUIRES_ECC_DSA)
08752                 return 1;
08753             break;
08754 
08755         case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
08756             if (requirement == REQUIRES_ECC_DSA)
08757                 return 1;
08758             break;
08759 
08760         case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
08761             if (requirement == REQUIRES_ECC_STATIC)
08762                 return 1;
08763             break;
08764 
08765         case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
08766             if (requirement == REQUIRES_ECC_STATIC)
08767                 return 1;
08768             break;
08769 
08770 #ifndef NO_RSA
08771         case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
08772             if (requirement == REQUIRES_RSA)
08773                 return 1;
08774             break;
08775 
08776         case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
08777             if (requirement == REQUIRES_RSA)
08778                 return 1;
08779             break;
08780 
08781         case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
08782             if (requirement == REQUIRES_ECC_STATIC)
08783                 return 1;
08784             if (requirement == REQUIRES_RSA_SIG)
08785                 return 1;
08786             break;
08787 
08788         case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
08789             if (requirement == REQUIRES_ECC_STATIC)
08790                 return 1;
08791             if (requirement == REQUIRES_RSA_SIG)
08792                 return 1;
08793             break;
08794 
08795         case TLS_RSA_WITH_AES_128_CCM_8 :
08796         case TLS_RSA_WITH_AES_256_CCM_8 :
08797             if (requirement == REQUIRES_RSA)
08798                 return 1;
08799             if (requirement == REQUIRES_RSA_SIG)
08800                 return 1;
08801             break;
08802 
08803         case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
08804         case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
08805             if (requirement == REQUIRES_RSA)
08806                 return 1;
08807             if (requirement == REQUIRES_RSA_SIG)
08808                 return 1;
08809             break;
08810 
08811         case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
08812         case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
08813             if (requirement == REQUIRES_RSA_SIG)
08814                 return 1;
08815             if (requirement == REQUIRES_ECC_STATIC)
08816                 return 1;
08817             break;
08818 #endif
08819 
08820         case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 :
08821         case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
08822             if (requirement == REQUIRES_ECC_DSA)
08823                 return 1;
08824             break;
08825 
08826         case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
08827         case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
08828             if (requirement == REQUIRES_ECC_DSA)
08829                 return 1;
08830             break;
08831 
08832         case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
08833         case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
08834             if (requirement == REQUIRES_ECC_DSA)
08835                 return 1;
08836             if (requirement == REQUIRES_ECC_STATIC)
08837                 return 1;
08838             break;
08839 
08840         default:
08841             CYASSL_MSG("Unsupported cipher suite, CipherRequires ECC");
08842             return 0;
08843         }   /* switch */
08844         }   /* if     */
08845         if (first != ECC_BYTE) {   /* normal suites */
08846         switch (second) {
08847 
08848 #ifndef NO_RSA
08849         case SSL_RSA_WITH_RC4_128_SHA :
08850             if (requirement == REQUIRES_RSA)
08851                 return 1;
08852             break;
08853 
08854         case TLS_NTRU_RSA_WITH_RC4_128_SHA :
08855             if (requirement == REQUIRES_NTRU)
08856                 return 1;
08857             break;
08858 
08859         case SSL_RSA_WITH_RC4_128_MD5 :
08860             if (requirement == REQUIRES_RSA)
08861                 return 1;
08862             break;
08863 
08864         case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
08865             if (requirement == REQUIRES_RSA)
08866                 return 1;
08867             break;
08868 
08869         case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
08870             if (requirement == REQUIRES_NTRU)
08871                 return 1;
08872             break;
08873 
08874         case TLS_RSA_WITH_AES_128_CBC_SHA :
08875             if (requirement == REQUIRES_RSA)
08876                 return 1;
08877             break;
08878 
08879         case TLS_RSA_WITH_AES_128_CBC_SHA256 :
08880             if (requirement == REQUIRES_RSA)
08881                 return 1;
08882             break;
08883 
08884         case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
08885             if (requirement == REQUIRES_NTRU)
08886                 return 1;
08887             break;
08888 
08889         case TLS_RSA_WITH_AES_256_CBC_SHA :
08890             if (requirement == REQUIRES_RSA)
08891                 return 1;
08892             break;
08893 
08894         case TLS_RSA_WITH_AES_256_CBC_SHA256 :
08895             if (requirement == REQUIRES_RSA)
08896                 return 1;
08897             break;
08898 
08899         case TLS_RSA_WITH_NULL_SHA :
08900         case TLS_RSA_WITH_NULL_SHA256 :
08901             if (requirement == REQUIRES_RSA)
08902                 return 1;
08903             break;
08904 
08905         case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
08906             if (requirement == REQUIRES_NTRU)
08907                 return 1;
08908             break;
08909 #endif
08910 
08911         case TLS_PSK_WITH_AES_128_CBC_SHA256 :
08912             if (requirement == REQUIRES_PSK)
08913                 return 1;
08914             break;
08915 
08916         case TLS_PSK_WITH_AES_128_CBC_SHA :
08917             if (requirement == REQUIRES_PSK)
08918                 return 1;
08919             break;
08920 
08921         case TLS_PSK_WITH_AES_256_CBC_SHA :
08922             if (requirement == REQUIRES_PSK)
08923                 return 1;
08924             break;
08925 
08926         case TLS_PSK_WITH_NULL_SHA256 :
08927             if (requirement == REQUIRES_PSK)
08928                 return 1;
08929             break;
08930 
08931         case TLS_PSK_WITH_NULL_SHA :
08932             if (requirement == REQUIRES_PSK)
08933                 return 1;
08934             break;
08935 
08936 #ifndef NO_RSA
08937         case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
08938             if (requirement == REQUIRES_RSA)
08939                 return 1;
08940             if (requirement == REQUIRES_DHE)
08941                 return 1;
08942             break;
08943 
08944         case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
08945             if (requirement == REQUIRES_RSA)
08946                 return 1;
08947             if (requirement == REQUIRES_DHE)
08948                 return 1;
08949             break;
08950 
08951         case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
08952             if (requirement == REQUIRES_RSA)
08953                 return 1;
08954             if (requirement == REQUIRES_DHE)
08955                 return 1;
08956             break;
08957 
08958         case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
08959             if (requirement == REQUIRES_RSA)
08960                 return 1;
08961             if (requirement == REQUIRES_DHE)
08962                 return 1;
08963             break;
08964 
08965         case TLS_RSA_WITH_HC_128_CBC_MD5 :
08966             if (requirement == REQUIRES_RSA)
08967                 return 1;
08968             break;
08969                 
08970         case TLS_RSA_WITH_HC_128_CBC_SHA :
08971             if (requirement == REQUIRES_RSA)
08972                 return 1;
08973             break;
08974 
08975         case TLS_RSA_WITH_RABBIT_CBC_SHA :
08976             if (requirement == REQUIRES_RSA)
08977                 return 1;
08978             break;
08979 
08980         case TLS_RSA_WITH_AES_128_GCM_SHA256 :
08981         case TLS_RSA_WITH_AES_256_GCM_SHA384 :
08982             if (requirement == REQUIRES_RSA)
08983                 return 1;
08984             break;
08985 
08986         case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
08987         case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
08988             if (requirement == REQUIRES_RSA)
08989                 return 1;
08990             if (requirement == REQUIRES_DHE)
08991                 return 1;
08992             break;
08993 
08994         case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
08995         case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
08996         case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
08997         case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
08998             if (requirement == REQUIRES_RSA)
08999                 return 1;
09000             break;
09001 
09002         case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
09003         case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
09004         case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
09005         case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
09006             if (requirement == REQUIRES_RSA)
09007                 return 1;
09008             if (requirement == REQUIRES_RSA_SIG)
09009                 return 1;
09010             if (requirement == REQUIRES_DHE)
09011                 return 1;
09012             break;
09013 #endif
09014 
09015         default:
09016             CYASSL_MSG("Unsupported cipher suite, CipherRequires");
09017             return 0;
09018         }  /* switch */
09019         }  /* if ECC / Normal suites else */
09020 
09021         return 0;
09022     }
09023 
09024 
09025 
09026 
09027 
09028     /* Make sure cert/key are valid for this suite, true on success */
09029     static int VerifySuite(CYASSL* ssl, word16 idx)
09030     {
09031         int  haveRSA = !ssl->options.haveStaticECC;
09032         int  havePSK = 0;
09033         byte first;
09034         byte second;
09035 
09036         CYASSL_ENTER("VerifySuite");
09037 
09038         if (ssl->suites == NULL) {
09039             CYASSL_MSG("Suites pointer error");
09040             return 0;
09041         }
09042 
09043         first   = ssl->suites->suites[idx];
09044         second  = ssl->suites->suites[idx+1];
09045 
09046         #ifndef NO_PSK
09047             havePSK = ssl->options.havePSK;
09048         #endif
09049 
09050         if (ssl->options.haveNTRU)
09051             haveRSA = 0;
09052 
09053         if (CipherRequires(first, second, REQUIRES_RSA)) {
09054             CYASSL_MSG("Requires RSA");
09055             if (haveRSA == 0) {
09056                 CYASSL_MSG("Don't have RSA");
09057                 return 0;
09058             }
09059         }
09060 
09061         if (CipherRequires(first, second, REQUIRES_DHE)) {
09062             CYASSL_MSG("Requires DHE");
09063             if (ssl->options.haveDH == 0) {
09064                 CYASSL_MSG("Don't have DHE");
09065                 return 0;
09066             }
09067         }
09068 
09069         if (CipherRequires(first, second, REQUIRES_ECC_DSA)) {
09070             CYASSL_MSG("Requires ECCDSA");
09071             if (ssl->options.haveECDSAsig == 0) {
09072                 CYASSL_MSG("Don't have ECCDSA");
09073                 return 0;
09074             }
09075         }
09076 
09077         if (CipherRequires(first, second, REQUIRES_ECC_STATIC)) {
09078             CYASSL_MSG("Requires static ECC");
09079             if (ssl->options.haveStaticECC == 0) {
09080                 CYASSL_MSG("Don't have static ECC");
09081                 return 0;
09082             }
09083         }
09084 
09085         if (CipherRequires(first, second, REQUIRES_PSK)) {
09086             CYASSL_MSG("Requires PSK");
09087             if (havePSK == 0) {
09088                 CYASSL_MSG("Don't have PSK");
09089                 return 0;
09090             }
09091         }
09092 
09093         if (CipherRequires(first, second, REQUIRES_NTRU)) {
09094             CYASSL_MSG("Requires NTRU");
09095             if (ssl->options.haveNTRU == 0) {
09096                 CYASSL_MSG("Don't have NTRU");
09097                 return 0;
09098             }
09099         }
09100 
09101         if (CipherRequires(first, second, REQUIRES_RSA_SIG)) {
09102             CYASSL_MSG("Requires RSA Signature");
09103             if (ssl->options.side == SERVER_END && ssl->options.haveECDSAsig == 1) {
09104                 CYASSL_MSG("Don't have RSA Signature");
09105                 return 0;
09106             }
09107         }
09108 
09109         /* ECCDHE is always supported if ECC on */
09110 
09111         return 1;
09112     }
09113 
09114 
09115     static int MatchSuite(CYASSL* ssl, Suites* peerSuites)
09116     {
09117         word16 i, j;
09118 
09119         CYASSL_ENTER("MatchSuite");
09120 
09121         /* & 0x1 equivalent % 2 */
09122         if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1)
09123             return MATCH_SUITE_ERROR;
09124 
09125         if (ssl->suites == NULL)
09126             return SUITES_ERROR;
09127         /* start with best, if a match we are good */
09128         for (i = 0; i < ssl->suites->suiteSz; i += 2)
09129             for (j = 0; j < peerSuites->suiteSz; j += 2)
09130                 if (ssl->suites->suites[i]   == peerSuites->suites[j] &&
09131                     ssl->suites->suites[i+1] == peerSuites->suites[j+1] ) {
09132 
09133                     if (VerifySuite(ssl, i)) {
09134                         int result;
09135                         CYASSL_MSG("Verified suite validity");
09136                         ssl->options.cipherSuite0 = ssl->suites->suites[i];
09137                         ssl->options.cipherSuite  = ssl->suites->suites[i+1];
09138                         result = SetCipherSpecs(ssl);
09139                         if (result == 0)
09140                             PickHashSigAlgo(ssl, peerSuites->hashSigAlgo,
09141                                                  peerSuites->hashSigAlgoSz);
09142                         return result;
09143                     }
09144                     else {
09145                         CYASSL_MSG("Could not verify suite validity, continue");
09146                     }
09147                 }
09148 
09149         return MATCH_SUITE_ERROR;
09150     }
09151 
09152 
09153     /* process old style client hello, deprecate? */
09154     int ProcessOldClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
09155                               word32 inSz, word16 sz)
09156     {
09157         word32          idx = *inOutIdx;
09158         word16          sessionSz;
09159         word16          randomSz;
09160         word16          i, j;
09161         ProtocolVersion pv;
09162         Suites          clSuites;
09163 
09164         (void)inSz;
09165         CYASSL_MSG("Got old format client hello");
09166 #ifdef CYASSL_CALLBACKS
09167         if (ssl->hsInfoOn)
09168             AddPacketName("ClientHello", &ssl->handShakeInfo);
09169         if (ssl->toInfoOn)
09170             AddLateName("ClientHello", &ssl->timeoutInfo);
09171 #endif
09172 
09173         /* manually hash input since different format */
09174 #ifndef NO_OLD_TLS
09175 #ifndef NO_MD5
09176         Md5Update(&ssl->hashMd5, input + idx, sz);
09177 #endif
09178 #ifndef NO_SHA
09179         ShaUpdate(&ssl->hashSha, input + idx, sz);
09180 #endif
09181 #endif
09182 #ifndef NO_SHA256
09183     if (IsAtLeastTLSv1_2(ssl))
09184         Sha256Update(&ssl->hashSha256, input + idx, sz);
09185 #endif
09186 
09187         /* does this value mean client_hello? */
09188         idx++;
09189 
09190         /* version */
09191         pv.major = input[idx++];
09192         pv.minor = input[idx++];
09193         ssl->chVersion = pv;  /* store */
09194 
09195         if (ssl->version.minor > pv.minor) {
09196             byte haveRSA = 0;
09197             byte havePSK = 0;
09198             if (!ssl->options.downgrade) {
09199                 CYASSL_MSG("Client trying to connect with lesser version"); 
09200                 return VERSION_ERROR;
09201             }
09202             if (pv.minor == SSLv3_MINOR) {
09203                 /* turn off tls */
09204                 CYASSL_MSG("    downgrading to SSLv3");
09205                 ssl->options.tls    = 0;
09206                 ssl->options.tls1_1 = 0;
09207                 ssl->version.minor  = SSLv3_MINOR;
09208             }
09209             else if (pv.minor == TLSv1_MINOR) {
09210                 CYASSL_MSG("    downgrading to TLSv1");
09211                 /* turn off tls 1.1+ */
09212                 ssl->options.tls1_1 = 0;
09213                 ssl->version.minor  = TLSv1_MINOR;
09214             }
09215             else if (pv.minor == TLSv1_1_MINOR) {
09216                 CYASSL_MSG("    downgrading to TLSv1.1");
09217                 ssl->version.minor  = TLSv1_1_MINOR;
09218             }
09219 #ifndef NO_RSA
09220             haveRSA = 1;
09221 #endif
09222 #ifndef NO_PSK
09223             havePSK = ssl->options.havePSK;
09224 #endif
09225 
09226             InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
09227                        ssl->options.haveDH, ssl->options.haveNTRU,
09228                        ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
09229                        ssl->options.side);
09230         }
09231 
09232         /* suite size */
09233         ato16(&input[idx], &clSuites.suiteSz);
09234         idx += 2;
09235 
09236         if (clSuites.suiteSz > MAX_SUITE_SZ)
09237             return BUFFER_ERROR;
09238 
09239         /* session size */
09240         ato16(&input[idx], &sessionSz);
09241         idx += 2;
09242 
09243         if (sessionSz > ID_LEN)
09244             return BUFFER_ERROR;
09245     
09246         /* random size */
09247         ato16(&input[idx], &randomSz);
09248         idx += 2;
09249 
09250         if (randomSz > RAN_LEN)
09251             return BUFFER_ERROR;
09252 
09253         /* suites */
09254         for (i = 0, j = 0; i < clSuites.suiteSz; i += 3) {    
09255             byte first = input[idx++];
09256             if (!first) { /* implicit: skip sslv2 type */
09257                 XMEMCPY(&clSuites.suites[j], &input[idx], 2);
09258                 j += 2;
09259             }
09260             idx += 2;
09261         }
09262         clSuites.suiteSz = j;
09263 
09264         /* session id */
09265         if (sessionSz) {
09266             XMEMCPY(ssl->arrays->sessionID, input + idx, sessionSz);
09267             idx += sessionSz;
09268             ssl->options.resuming = 1;
09269         }
09270 
09271         /* random */
09272         if (randomSz < RAN_LEN)
09273             XMEMSET(ssl->arrays->clientRandom, 0, RAN_LEN - randomSz);
09274         XMEMCPY(&ssl->arrays->clientRandom[RAN_LEN - randomSz], input + idx,
09275                randomSz);
09276         idx += randomSz;
09277 
09278         if (ssl->options.usingCompression)
09279             ssl->options.usingCompression = 0;  /* turn off */
09280 
09281         ssl->options.clientState = CLIENT_HELLO_COMPLETE;
09282         *inOutIdx = idx;
09283 
09284         ssl->options.haveSessionId = 1;
09285         /* DoClientHello uses same resume code */
09286         if (ssl->options.resuming) {  /* let's try */
09287             int ret = -1; 
09288             CYASSL_SESSION* session = GetSession(ssl,ssl->arrays->masterSecret);
09289             if (!session) {
09290                 CYASSL_MSG("Session lookup for resume failed");
09291                 ssl->options.resuming = 0;
09292             } else {
09293                 if (MatchSuite(ssl, &clSuites) < 0) {
09294                     CYASSL_MSG("Unsupported cipher suite, OldClientHello");
09295                     return UNSUPPORTED_SUITE;
09296                 }
09297                 #ifdef SESSION_CERTS
09298                     ssl->session = *session; /* restore session certs. */
09299                 #endif
09300                 RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, RAN_LEN);
09301                 #ifdef NO_OLD_TLS
09302                     ret = DeriveTlsKeys(ssl);
09303                 #else
09304                     #ifndef NO_TLS
09305                         if (ssl->options.tls)
09306                             ret = DeriveTlsKeys(ssl);
09307                     #endif
09308                         if (!ssl->options.tls)
09309                             ret = DeriveKeys(ssl);
09310                 #endif
09311                 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
09312 
09313                 return ret;
09314             }
09315         }
09316 
09317         return MatchSuite(ssl, &clSuites);
09318     }
09319 
09320 
09321     static int DoClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
09322                              word32 totalSz, word32 helloSz)
09323     {
09324         byte b;
09325         ProtocolVersion pv;
09326         Suites          clSuites;
09327         word32 i = *inOutIdx;
09328         word32 begin = i;
09329 
09330 #ifdef CYASSL_CALLBACKS
09331         if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
09332         if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
09333 #endif
09334         /* make sure can read up to session */
09335         if (i + sizeof(pv) + RAN_LEN + ENUM_LEN > totalSz)
09336             return INCOMPLETE_DATA;
09337 
09338         XMEMCPY(&pv, input + i, sizeof(pv));
09339         ssl->chVersion = pv;   /* store */
09340         i += (word32)sizeof(pv);
09341         if (ssl->version.minor > pv.minor) {
09342             byte haveRSA = 0;
09343             byte havePSK = 0;
09344             if (!ssl->options.downgrade) {
09345                 CYASSL_MSG("Client trying to connect with lesser version"); 
09346                 return VERSION_ERROR;
09347             }
09348             if (pv.minor == SSLv3_MINOR) {
09349                 /* turn off tls */
09350                 CYASSL_MSG("    downgrading to SSLv3");
09351                 ssl->options.tls    = 0;
09352                 ssl->options.tls1_1 = 0;
09353                 ssl->version.minor  = SSLv3_MINOR;
09354             }
09355             else if (pv.minor == TLSv1_MINOR) {
09356                 /* turn off tls 1.1+ */
09357                 CYASSL_MSG("    downgrading to TLSv1");
09358                 ssl->options.tls1_1 = 0;
09359                 ssl->version.minor  = TLSv1_MINOR;
09360             }
09361             else if (pv.minor == TLSv1_1_MINOR) {
09362                 CYASSL_MSG("    downgrading to TLSv1.1");
09363                 ssl->version.minor  = TLSv1_1_MINOR;
09364             }
09365 #ifndef NO_RSA
09366             haveRSA = 1;
09367 #endif
09368 #ifndef NO_PSK
09369             havePSK = ssl->options.havePSK;
09370 #endif
09371             InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
09372                        ssl->options.haveDH, ssl->options.haveNTRU,
09373                        ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
09374                        ssl->options.side);
09375         }
09376         /* random */
09377         XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
09378         i += RAN_LEN;
09379 
09380 #ifdef SHOW_SECRETS
09381         {
09382             int j;
09383             printf("client random: ");
09384             for (j = 0; j < RAN_LEN; j++)
09385                 printf("%02x", ssl->arrays->clientRandom[j]);
09386             printf("\n");
09387         }
09388 #endif
09389         /* session id */
09390         b = input[i++];
09391         if (b) {
09392             if (i + ID_LEN > totalSz)
09393                 return INCOMPLETE_DATA;
09394             XMEMCPY(ssl->arrays->sessionID, input + i, ID_LEN);
09395             i += b;
09396             ssl->options.resuming= 1; /* client wants to resume */
09397             CYASSL_MSG("Client wants to resume session");
09398         }
09399         
09400         #ifdef CYASSL_DTLS
09401             /* cookie */
09402             if (ssl->options.dtls) {
09403                 b = input[i++];
09404                 if (b) {
09405                     byte cookie[MAX_COOKIE_LEN];
09406 
09407                     if (b > MAX_COOKIE_LEN)
09408                         return BUFFER_ERROR;
09409                     if (i + b > totalSz)
09410                         return INCOMPLETE_DATA;
09411                     if (ssl->ctx->CBIOCookie == NULL) {
09412                         CYASSL_MSG("Your Cookie callback is null, please set");
09413                         return COOKIE_ERROR;
09414                     }
09415                     if ((ssl->ctx->CBIOCookie(ssl, cookie, COOKIE_SZ,
09416                                               ssl->IOCB_CookieCtx) != COOKIE_SZ)
09417                             || (b != COOKIE_SZ)
09418                             || (XMEMCMP(cookie, input + i, b) != 0)) {
09419                         return COOKIE_ERROR;
09420                     }
09421                     i += b;
09422                 }
09423             }
09424         #endif
09425 
09426         if (i + LENGTH_SZ > totalSz)
09427             return INCOMPLETE_DATA;
09428         /* suites */
09429         ato16(&input[i], &clSuites.suiteSz);
09430         i += 2;
09431 
09432         /* suites and comp len */
09433         if (i + clSuites.suiteSz + ENUM_LEN > totalSz)
09434             return INCOMPLETE_DATA;
09435         if (clSuites.suiteSz > MAX_SUITE_SZ)
09436             return BUFFER_ERROR;
09437         XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
09438         i += clSuites.suiteSz;
09439         clSuites.hashSigAlgoSz = 0;
09440 
09441         b = input[i++];  /* comp len */
09442         if (i + b > totalSz)
09443             return INCOMPLETE_DATA;
09444 
09445         if (ssl->options.usingCompression) {
09446             int match = 0;
09447             while (b--) {
09448                 byte comp = input[i++];
09449                 if (comp == ZLIB_COMPRESSION)
09450                     match = 1;
09451             }
09452             if (!match) {
09453                 CYASSL_MSG("Not matching compression, turning off"); 
09454                 ssl->options.usingCompression = 0;  /* turn off */
09455             }
09456         }
09457         else
09458             i += b;  /* ignore, since we're not on */
09459 
09460         *inOutIdx = i;
09461         if ( (i - begin) < helloSz) {
09462 #ifdef HAVE_TLS_EXTENSIONS
09463             if (IsTLS(ssl)) {
09464                 int ret = 0;
09465 #else
09466             if (IsAtLeastTLSv1_2(ssl)) {
09467 #endif
09468                 /* Process the hello extension. Skip unsupported. */
09469                 word16 totalExtSz;
09470 
09471                 ato16(&input[i], &totalExtSz);
09472                 i += LENGTH_SZ;
09473                 if (totalExtSz > helloSz + begin - i)
09474                     return INCOMPLETE_DATA;
09475 
09476 #ifdef HAVE_TLS_EXTENSIONS
09477                 if ((ret = TLSX_Parse(ssl, (byte *) input + i,
09478                                                      totalExtSz, 1, &clSuites)))
09479                     return ret;
09480 
09481                 i += totalExtSz;
09482 #else
09483                 while (totalExtSz) {
09484                     word16 extId, extSz;
09485                    
09486                     ato16(&input[i], &extId);
09487                     i += LENGTH_SZ;
09488                     ato16(&input[i], &extSz);
09489                     i += EXT_ID_SZ;
09490                     if (extSz > totalExtSz - LENGTH_SZ - EXT_ID_SZ)
09491                         return INCOMPLETE_DATA;
09492 
09493                     if (extId == HELLO_EXT_SIG_ALGO) {
09494                         ato16(&input[i], &clSuites.hashSigAlgoSz);
09495                         i += LENGTH_SZ;
09496                         if (clSuites.hashSigAlgoSz > extSz - LENGTH_SZ)
09497                             return INCOMPLETE_DATA;
09498 
09499                         XMEMCPY(clSuites.hashSigAlgo, &input[i],
09500                             min(clSuites.hashSigAlgoSz, HELLO_EXT_SIGALGO_MAX));
09501                         i += clSuites.hashSigAlgoSz;
09502                     }
09503                     else
09504                         i += extSz;
09505 
09506                     totalExtSz -= LENGTH_SZ + EXT_ID_SZ + extSz;
09507                 }
09508 #endif
09509                 *inOutIdx = i;
09510             }
09511             else
09512                 *inOutIdx = begin + helloSz;  /* skip extensions */
09513         }
09514 
09515         ssl->options.clientState = CLIENT_HELLO_COMPLETE;
09516         
09517         ssl->options.haveSessionId = 1;
09518         /* ProcessOld uses same resume code */
09519         if (ssl->options.resuming && (!ssl->options.dtls ||
09520             ssl->options.acceptState == HELLO_VERIFY_SENT)) {  /* let's try */
09521             int ret = -1;            
09522             CYASSL_SESSION* session = GetSession(ssl,ssl->arrays->masterSecret);
09523             if (!session) {
09524                 CYASSL_MSG("Session lookup for resume failed");
09525                 ssl->options.resuming = 0;
09526             } else {
09527                 if (MatchSuite(ssl, &clSuites) < 0) {
09528                     CYASSL_MSG("Unsupported cipher suite, ClientHello");
09529                     return UNSUPPORTED_SUITE;
09530                 }
09531                 #ifdef SESSION_CERTS
09532                     ssl->session = *session; /* restore session certs. */
09533                 #endif
09534                 RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, RAN_LEN);
09535                 #ifdef NO_OLD_TLS
09536                     ret = DeriveTlsKeys(ssl);
09537                 #else
09538                     #ifndef NO_TLS
09539                         if (ssl->options.tls)
09540                             ret = DeriveTlsKeys(ssl);
09541                     #endif
09542                         if (!ssl->options.tls)
09543                             ret = DeriveKeys(ssl);
09544                 #endif
09545                 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
09546 
09547                 return ret;
09548             }
09549         }
09550         return MatchSuite(ssl, &clSuites);
09551     }
09552 
09553 #if !defined(NO_RSA) || defined(HAVE_ECC)
09554     static int DoCertificateVerify(CYASSL* ssl, byte* input, word32* inOutsz,
09555                                    word32 totalSz)
09556     {
09557         word16      sz = 0;
09558         word32      i = *inOutsz;
09559         int         ret = VERIFY_CERT_ERROR;   /* start in error state */
09560         byte*       sig;
09561         byte        hashAlgo = sha_mac;
09562         byte        sigAlgo = anonymous_sa_algo;
09563 
09564         #ifdef CYASSL_CALLBACKS
09565             if (ssl->hsInfoOn)
09566                 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
09567             if (ssl->toInfoOn)
09568                 AddLateName("CertificateVerify", &ssl->timeoutInfo);
09569         #endif
09570         if ( (i + VERIFY_HEADER) > totalSz)
09571             return INCOMPLETE_DATA;
09572 
09573         if (IsAtLeastTLSv1_2(ssl)) {
09574             hashAlgo = input[i++];
09575             sigAlgo = input[i++];
09576         }
09577         ato16(&input[i], &sz);
09578         i += VERIFY_HEADER;
09579 
09580         if ( (i + sz) > totalSz)
09581             return INCOMPLETE_DATA;
09582 
09583         if (sz > ENCRYPT_LEN)
09584             return BUFFER_ERROR;
09585 
09586         sig = &input[i];
09587         *inOutsz = i + sz;
09588 
09589         /* RSA */
09590 #ifndef NO_RSA
09591         if (ssl->peerRsaKeyPresent != 0) {
09592             byte* out;
09593             int   outLen;
09594 
09595             CYASSL_MSG("Doing RSA peer cert verify");
09596 
09597             outLen = RsaSSL_VerifyInline(sig, sz, &out, ssl->peerRsaKey);
09598 
09599             if (IsAtLeastTLSv1_2(ssl)) {
09600                 byte   encodedSig[MAX_ENCODED_SIG_SZ];
09601                 word32 sigSz;
09602                 byte*  digest = ssl->certHashes.sha;
09603                 int    typeH = SHAh;
09604                 int    digestSz = SHA_DIGEST_SIZE;
09605 
09606                 if (sigAlgo != rsa_sa_algo) {
09607                     CYASSL_MSG("Oops, peer sent RSA key but not in verify");
09608                 }
09609 
09610                 if (hashAlgo == sha256_mac) {
09611                     #ifndef NO_SHA256
09612                         digest = ssl->certHashes.sha256;
09613                         typeH    = SHA256h;
09614                         digestSz = SHA256_DIGEST_SIZE;
09615                     #endif
09616                 }
09617                 else if (hashAlgo == sha384_mac) {
09618                     #ifdef CYASSL_SHA384
09619                         digest = ssl->certHashes.sha384;
09620                         typeH    = SHA384h;
09621                         digestSz = SHA384_DIGEST_SIZE;
09622                     #endif
09623                 }
09624 
09625                 sigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
09626 
09627                 if (outLen == (int)sigSz && XMEMCMP(out, encodedSig,
09628                                            min(sigSz, MAX_ENCODED_SIG_SZ)) == 0)
09629                     ret = 0;  /* verified */
09630             }
09631             else {
09632                 if (outLen == FINISHED_SZ && XMEMCMP(out,
09633                                 &ssl->certHashes, FINISHED_SZ) == 0)
09634                     ret = 0;  /* verified */
09635             }
09636         }
09637 #endif
09638 #ifdef HAVE_ECC
09639         if (ssl->peerEccDsaKeyPresent) {
09640             int verify =  0;
09641             int err    = -1;
09642             byte* digest = ssl->certHashes.sha;
09643             word32 digestSz = SHA_DIGEST_SIZE;
09644 
09645             CYASSL_MSG("Doing ECC peer cert verify");
09646 
09647             if (IsAtLeastTLSv1_2(ssl)) {
09648                 if (sigAlgo != ecc_dsa_sa_algo) {
09649                     CYASSL_MSG("Oops, peer sent ECC key but not in verify");
09650                 }
09651                 if (hashAlgo == sha256_mac) {
09652                     #ifndef NO_SHA256
09653                         digest = ssl->certHashes.sha256;
09654                         digestSz = SHA256_DIGEST_SIZE;
09655                     #endif
09656                 }
09657                 else if (hashAlgo == sha384_mac) {
09658                     #ifdef CYASSL_SHA384
09659                         digest = ssl->certHashes.sha384;
09660                         digestSz = SHA384_DIGEST_SIZE;
09661                     #endif
09662                 }
09663             }
09664             err = ecc_verify_hash(sig, sz, digest, digestSz,
09665                                   &verify, ssl->peerEccDsaKey);
09666 
09667             if (err == 0 && verify == 1)
09668                ret = 0;   /* verified */ 
09669         }
09670 #endif
09671         if (ret == 0)
09672             ssl->options.havePeerVerify = 1;
09673           
09674         return ret;
09675     }
09676 #endif /* !NO_RSA || HAVE_ECC */
09677 
09678     int SendServerHelloDone(CYASSL* ssl)
09679     {
09680         byte              *output;
09681         int                sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
09682         int                ret;
09683 
09684         #ifdef CYASSL_DTLS
09685             if (ssl->options.dtls)
09686                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
09687         #endif
09688         /* check for available size */
09689         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
09690             return ret;
09691 
09692         /* get ouput buffer */
09693         output = ssl->buffers.outputBuffer.buffer +
09694                  ssl->buffers.outputBuffer.length;
09695 
09696         AddHeaders(output, 0, server_hello_done, ssl);
09697 
09698         #ifdef CYASSL_DTLS
09699             if (ssl->options.dtls) {
09700                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
09701                     return 0;
09702             }
09703         #endif
09704         HashOutput(ssl, output, sendSz, 0);
09705 #ifdef CYASSL_CALLBACKS
09706         if (ssl->hsInfoOn)
09707             AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
09708         if (ssl->toInfoOn)
09709             AddPacketInfo("ServerHelloDone", &ssl->timeoutInfo, output, sendSz,
09710                           ssl->heap);
09711 #endif
09712         ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
09713 
09714         ssl->buffers.outputBuffer.length += sendSz;
09715 
09716         return SendBuffered(ssl);
09717     }
09718 
09719 #ifdef CYASSL_DTLS
09720     int SendHelloVerifyRequest(CYASSL* ssl)
09721     {
09722         byte* output;
09723         byte  cookieSz = COOKIE_SZ;
09724         int   length = VERSION_SZ + ENUM_LEN + cookieSz;
09725         int   idx    = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
09726         int   sendSz = length + idx;
09727         int   ret;
09728 
09729         /* check for available size */
09730         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
09731             return ret;
09732 
09733         /* get ouput buffer */
09734         output = ssl->buffers.outputBuffer.buffer +
09735                  ssl->buffers.outputBuffer.length;
09736 
09737         AddHeaders(output, length, hello_verify_request, ssl);
09738 
09739         output[idx++] =  ssl->chVersion.major;
09740         output[idx++] =  ssl->chVersion.minor;
09741 
09742         output[idx++] = cookieSz;
09743         if (ssl->ctx->CBIOCookie == NULL) {
09744             CYASSL_MSG("Your Cookie callback is null, please set");
09745             return COOKIE_ERROR;
09746         }
09747         if ((ret = ssl->ctx->CBIOCookie(ssl, output + idx, cookieSz,
09748                                         ssl->IOCB_CookieCtx)) < 0)
09749             return ret;
09750 
09751         HashOutput(ssl, output, sendSz, 0);
09752 #ifdef CYASSL_CALLBACKS
09753         if (ssl->hsInfoOn)
09754             AddPacketName("HelloVerifyRequest", &ssl->handShakeInfo);
09755         if (ssl->toInfoOn)
09756             AddPacketInfo("HelloVerifyRequest", &ssl->timeoutInfo, output,
09757                           sendSz, ssl->heap);
09758 #endif
09759         ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
09760 
09761         ssl->buffers.outputBuffer.length += sendSz;
09762 
09763         return SendBuffered(ssl);
09764     }
09765 #endif
09766 
09767     static int DoClientKeyExchange(CYASSL* ssl, byte* input,
09768                                    word32* inOutIdx, word32 totalSz)
09769     {
09770         int    ret = 0;
09771         word32 length = 0;
09772         byte*  out = NULL;
09773 
09774         (void)length; /* shut up compiler warnings */
09775         (void)out;
09776         (void)input;
09777         (void)inOutIdx;
09778         (void)totalSz;
09779 
09780         if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
09781             CYASSL_MSG("Client sending keyexchange at wrong time");
09782             SendAlert(ssl, alert_fatal, unexpected_message);
09783             return OUT_OF_ORDER_E;
09784         }
09785 
09786         #ifndef NO_CERTS
09787             if (ssl->options.verifyPeer && ssl->options.failNoCert)
09788                 if (!ssl->options.havePeerCert) {
09789                     CYASSL_MSG("client didn't present peer cert");
09790                     return NO_PEER_CERT;
09791                 }
09792         #endif
09793 
09794         #ifdef CYASSL_CALLBACKS
09795             if (ssl->hsInfoOn)
09796                 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
09797             if (ssl->toInfoOn)
09798                 AddLateName("ClientKeyExchange", &ssl->timeoutInfo);
09799         #endif
09800 
09801         switch (ssl->specs.kea) {
09802         #ifndef NO_RSA
09803             case rsa_kea: 
09804             {
09805                 word32 idx = 0;
09806                 RsaKey key;
09807                 byte*  tmp = 0;
09808 
09809                 InitRsaKey(&key, ssl->heap);
09810 
09811                 if (ssl->buffers.key.buffer)
09812                     ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx,
09813                                              &key, ssl->buffers.key.length);
09814                 else
09815                     return NO_PRIVATE_KEY;
09816 
09817                 if (ret == 0) {
09818                     length = RsaEncryptSize(&key);
09819                     ssl->arrays->preMasterSz = SECRET_LEN;
09820 
09821                     if (ssl->options.tls) {
09822                         word16 check;
09823                         ato16(input + *inOutIdx, &check);
09824                         if ((word32)check != length) {
09825                             CYASSL_MSG("RSA explicit size doesn't match");
09826                             FreeRsaKey(&key);
09827                             return RSA_PRIVATE_ERROR;
09828                         }
09829                         (*inOutIdx) += 2;
09830                     }
09831                     tmp = input + *inOutIdx;
09832                     *inOutIdx += length;
09833 
09834                     if (*inOutIdx > totalSz) {
09835                         CYASSL_MSG("RSA message too big");
09836                         FreeRsaKey(&key);
09837                         return INCOMPLETE_DATA;
09838                     }
09839 
09840                     if (RsaPrivateDecryptInline(tmp, length, &out, &key) ==
09841                                                                    SECRET_LEN) {
09842                         XMEMCPY(ssl->arrays->preMasterSecret, out, SECRET_LEN);
09843                         if (ssl->arrays->preMasterSecret[0] !=
09844                                                            ssl->chVersion.major
09845                             || ssl->arrays->preMasterSecret[1] != 
09846                                                            ssl->chVersion.minor)
09847                             ret = PMS_VERSION_ERROR;
09848                         else
09849                             ret = MakeMasterSecret(ssl);
09850                     }
09851                     else
09852                         ret = RSA_PRIVATE_ERROR;
09853                 }
09854 
09855                 FreeRsaKey(&key);
09856             }
09857             break;
09858         #endif
09859         #ifndef NO_PSK
09860             case psk_kea:
09861             {
09862                 byte* pms = ssl->arrays->preMasterSecret;
09863                 word16 ci_sz;
09864 
09865                 ato16(&input[*inOutIdx], &ci_sz);
09866                 *inOutIdx += LENGTH_SZ;
09867                 if (ci_sz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR;
09868 
09869                 XMEMCPY(ssl->arrays->client_identity, &input[*inOutIdx], ci_sz);
09870                 *inOutIdx += ci_sz;
09871                 if (ci_sz < MAX_PSK_ID_LEN)
09872                     ssl->arrays->client_identity[ci_sz] = 0;
09873                 else
09874                     ssl->arrays->client_identity[MAX_PSK_ID_LEN-1] = 0;
09875 
09876                 ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
09877                     ssl->arrays->client_identity, ssl->arrays->psk_key,
09878                     MAX_PSK_KEY_LEN);
09879                 if (ssl->arrays->psk_keySz == 0 || 
09880                     ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
09881                     return PSK_KEY_ERROR;
09882                 
09883                 /* make psk pre master secret */
09884                 /* length of key + length 0s + length of key + key */
09885                 c16toa((word16)ssl->arrays->psk_keySz, pms);
09886                 pms += 2;
09887                 XMEMSET(pms, 0, ssl->arrays->psk_keySz);
09888                 pms += ssl->arrays->psk_keySz;
09889                 c16toa((word16)ssl->arrays->psk_keySz, pms);
09890                 pms += 2;
09891                 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
09892                 ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
09893 
09894                 ret = MakeMasterSecret(ssl);
09895                 /* No further need for PSK */
09896                 XMEMSET(ssl->arrays->psk_key, 0, ssl->arrays->psk_keySz);
09897                 ssl->arrays->psk_keySz = 0;
09898             }
09899             break;
09900         #endif /* NO_PSK */
09901         #ifdef HAVE_NTRU
09902             case ntru_kea:
09903             {
09904                 word32 rc;
09905                 word16 cipherLen;
09906                 word16 plainLen = sizeof(ssl->arrays->preMasterSecret);
09907                 byte*  tmp;
09908 
09909                 if (!ssl->buffers.key.buffer)
09910                     return NO_PRIVATE_KEY;
09911 
09912                 ato16(&input[*inOutIdx], &cipherLen);
09913                 *inOutIdx += LENGTH_SZ;
09914                 if (cipherLen > MAX_NTRU_ENCRYPT_SZ)
09915                     return NTRU_KEY_ERROR;
09916 
09917                 tmp = input + *inOutIdx;
09918                 rc = crypto_ntru_decrypt((word16)ssl->buffers.key.length,
09919                             ssl->buffers.key.buffer, cipherLen, tmp, &plainLen,
09920                             ssl->arrays->preMasterSecret);
09921 
09922                 if (rc != NTRU_OK || plainLen != SECRET_LEN)
09923                     return NTRU_DECRYPT_ERROR;
09924                 *inOutIdx += cipherLen;
09925 
09926                 ssl->arrays->preMasterSz = plainLen;
09927                 ret = MakeMasterSecret(ssl);
09928             }
09929             break;
09930         #endif /* HAVE_NTRU */
09931         #ifdef HAVE_ECC
09932             case ecc_diffie_hellman_kea:
09933             {
09934                 word32 size;
09935                 word32 bLength = input[*inOutIdx];  /* one byte length */
09936                 *inOutIdx += 1;
09937 
09938                 ret = ecc_import_x963(&input[*inOutIdx],
09939                                                       bLength, ssl->peerEccKey);
09940                 if (ret != 0)
09941                     return ECC_PEERKEY_ERROR;
09942                 *inOutIdx += bLength;
09943                 ssl->peerEccKeyPresent = 1;
09944 
09945                 size = sizeof(ssl->arrays->preMasterSecret);
09946                 if (ssl->specs.static_ecdh) {
09947                     ecc_key staticKey;
09948                     word32 i = 0;
09949 
09950                     ecc_init(&staticKey);
09951                     ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
09952                                            &staticKey, ssl->buffers.key.length);
09953                     if (ret == 0)
09954                         ret = ecc_shared_secret(&staticKey, ssl->peerEccKey,
09955                                            ssl->arrays->preMasterSecret, &size);
09956                     ecc_free(&staticKey);
09957                 }
09958                 else 
09959                     ret = ecc_shared_secret(ssl->eccTempKey, ssl->peerEccKey,
09960                                         ssl->arrays->preMasterSecret, &size);
09961                 if (ret != 0)
09962                     return ECC_SHARED_ERROR;
09963                 ssl->arrays->preMasterSz = size;
09964                 ret = MakeMasterSecret(ssl);
09965             }
09966             break;
09967         #endif /* HAVE_ECC */
09968         #ifdef OPENSSL_EXTRA 
09969             case diffie_hellman_kea:
09970             {
09971                 byte*  clientPub;
09972                 word16 clientPubSz;
09973                 DhKey  dhKey;
09974 
09975                 ato16(&input[*inOutIdx], &clientPubSz);
09976                 *inOutIdx += LENGTH_SZ;
09977 
09978                 clientPub = &input[*inOutIdx];
09979                 *inOutIdx += clientPubSz;
09980 
09981                 InitDhKey(&dhKey);
09982                 ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
09983                                        ssl->buffers.serverDH_P.length,
09984                                        ssl->buffers.serverDH_G.buffer,
09985                                        ssl->buffers.serverDH_G.length);
09986                 if (ret == 0)
09987                     ret = DhAgree(&dhKey, ssl->arrays->preMasterSecret,
09988                                          &ssl->arrays->preMasterSz,
09989                                           ssl->buffers.serverDH_Priv.buffer,
09990                                           ssl->buffers.serverDH_Priv.length,
09991                                           clientPub, clientPubSz);
09992                 FreeDhKey(&dhKey);
09993                 if (ret == 0)
09994                     ret = MakeMasterSecret(ssl);
09995             }
09996             break;
09997         #endif /* OPENSSL_EXTRA */
09998             default:
09999             {
10000                 CYASSL_MSG("Bad kea type");
10001                 ret = BAD_KEA_TYPE_E; 
10002             }
10003             break;
10004         }
10005         /* No further need for PMS */
10006         XMEMSET(ssl->arrays->preMasterSecret, 0, ssl->arrays->preMasterSz);
10007         ssl->arrays->preMasterSz = 0;
10008 
10009         if (ret == 0) {
10010             ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
10011             #ifndef NO_CERTS
10012                 if (ssl->options.verifyPeer)
10013                     BuildCertHashes(ssl, &ssl->certHashes);
10014             #endif
10015         }
10016 
10017         return ret;
10018     }
10019 
10020 #endif /* NO_CYASSL_SERVER */
10021 
10022 
10023 #ifdef SINGLE_THREADED
10024 
10025 int InitMutex(CyaSSL_Mutex* m)
10026 {
10027     (void)m;
10028     return 0;
10029 }
10030 
10031 
10032 int FreeMutex(CyaSSL_Mutex *m)
10033 {
10034     (void)m;
10035     return 0;
10036 }
10037 
10038 
10039 int LockMutex(CyaSSL_Mutex *m)
10040 {
10041     (void)m;
10042     return 0;
10043 }
10044 
10045 
10046 int UnLockMutex(CyaSSL_Mutex *m)
10047 {
10048     (void)m;
10049     return 0;
10050 }
10051 
10052 #else /* MULTI_THREAD */
10053 
10054     #if defined(FREERTOS)
10055 
10056         int InitMutex(CyaSSL_Mutex* m)
10057         {
10058             int iReturn;
10059 
10060             *m = ( CyaSSL_Mutex ) xSemaphoreCreateMutex();
10061             if( *m != NULL )
10062                 iReturn = 0;
10063             else
10064                 iReturn = BAD_MUTEX_ERROR;
10065 
10066             return iReturn;
10067         }
10068 
10069         int FreeMutex(CyaSSL_Mutex* m)
10070         {
10071             vSemaphoreDelete( *m );
10072             return 0;
10073         }
10074 
10075         int LockMutex(CyaSSL_Mutex* m)
10076         {
10077             /* Assume an infinite block, or should there be zero block? */
10078             xSemaphoreTake( *m, portMAX_DELAY );
10079             return 0;
10080         }
10081 
10082         int UnLockMutex(CyaSSL_Mutex* m)
10083         {
10084             xSemaphoreGive( *m );
10085             return 0;
10086         }
10087 
10088     #elif defined(CYASSL_SAFERTOS)
10089 
10090         int InitMutex(CyaSSL_Mutex* m)
10091         {
10092             vSemaphoreCreateBinary(m->mutexBuffer, m->mutex);
10093             if (m->mutex == NULL)
10094                 return BAD_MUTEX_ERROR;
10095 
10096             return 0;
10097         }
10098 
10099         int FreeMutex(CyaSSL_Mutex* m)
10100         {
10101             (void)m;
10102             return 0;
10103         }
10104 
10105         int LockMutex(CyaSSL_Mutex* m)
10106         {
10107             /* Assume an infinite block */
10108             xSemaphoreTake(m->mutex, portMAX_DELAY);
10109             return 0;
10110         }
10111 
10112         int UnLockMutex(CyaSSL_Mutex* m)
10113         {
10114             xSemaphoreGive(m->mutex);
10115             return 0;
10116         }
10117 
10118 
10119     #elif defined(USE_WINDOWS_API)
10120 
10121         int InitMutex(CyaSSL_Mutex* m)
10122         {
10123             InitializeCriticalSection(m);
10124             return 0;
10125         }
10126 
10127 
10128         int FreeMutex(CyaSSL_Mutex* m)
10129         {
10130             DeleteCriticalSection(m);
10131             return 0;
10132         }
10133 
10134 
10135         int LockMutex(CyaSSL_Mutex* m)
10136         {
10137             EnterCriticalSection(m);
10138             return 0;
10139         }
10140 
10141 
10142         int UnLockMutex(CyaSSL_Mutex* m)
10143         {
10144             LeaveCriticalSection(m);
10145             return 0;
10146         }
10147 
10148     #elif defined(CYASSL_PTHREADS)
10149 
10150         int InitMutex(CyaSSL_Mutex* m)
10151         {
10152             if (pthread_mutex_init(m, 0) == 0)
10153                 return 0;
10154             else
10155                 return BAD_MUTEX_ERROR;
10156         }
10157 
10158 
10159         int FreeMutex(CyaSSL_Mutex* m)
10160         {
10161             if (pthread_mutex_destroy(m) == 0)
10162                 return 0;
10163             else
10164                 return BAD_MUTEX_ERROR;
10165         }
10166 
10167 
10168         int LockMutex(CyaSSL_Mutex* m)
10169         {
10170             if (pthread_mutex_lock(m) == 0)
10171                 return 0;
10172             else
10173                 return BAD_MUTEX_ERROR;
10174         }
10175 
10176 
10177         int UnLockMutex(CyaSSL_Mutex* m)
10178         {
10179             if (pthread_mutex_unlock(m) == 0)
10180                 return 0;
10181             else
10182                 return BAD_MUTEX_ERROR;
10183         }
10184 
10185     #elif defined(THREADX)
10186 
10187         int InitMutex(CyaSSL_Mutex* m)
10188         {
10189             if (tx_mutex_create(m, "CyaSSL Mutex", TX_NO_INHERIT) == 0)
10190                 return 0;
10191             else
10192                 return BAD_MUTEX_ERROR;
10193         }
10194 
10195 
10196         int FreeMutex(CyaSSL_Mutex* m)
10197         {
10198             if (tx_mutex_delete(m) == 0)
10199                 return 0;
10200             else
10201                 return BAD_MUTEX_ERROR;
10202         }
10203 
10204 
10205         int LockMutex(CyaSSL_Mutex* m)
10206         {
10207             if (tx_mutex_get(m, TX_WAIT_FOREVER) == 0)
10208                 return 0;
10209             else
10210                 return BAD_MUTEX_ERROR;
10211         }
10212 
10213 
10214         int UnLockMutex(CyaSSL_Mutex* m)
10215         {
10216             if (tx_mutex_put(m) == 0)
10217                 return 0;
10218             else
10219                 return BAD_MUTEX_ERROR;
10220         }
10221 
10222     #elif defined(MICRIUM)
10223 
10224         int InitMutex(CyaSSL_Mutex* m)
10225         {
10226             #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
10227                 if (NetSecure_OS_MutexCreate(m) == 0)
10228                     return 0;
10229                 else
10230                     return BAD_MUTEX_ERROR;
10231             #else
10232                 return 0;
10233             #endif
10234         }
10235 
10236 
10237         int FreeMutex(CyaSSL_Mutex* m)
10238         {
10239             #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
10240                 if (NetSecure_OS_FreeMutex(m) == 0)
10241                     return 0;
10242                 else
10243                     return BAD_MUTEX_ERROR;
10244             #else
10245                 return 0;
10246             #endif
10247         }
10248 
10249 
10250         int LockMutex(CyaSSL_Mutex* m)
10251         {
10252             #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
10253                 if (NetSecure_OS_LockMutex(m) == 0)
10254                     return 0;
10255                 else
10256                     return BAD_MUTEX_ERROR;
10257             #else
10258                 return 0;
10259             #endif
10260         }
10261 
10262 
10263         int UnLockMutex(CyaSSL_Mutex* m)
10264         {
10265             #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
10266                 if (NetSecure_OS_UnLockMutex(m) == 0)
10267                     return 0;
10268                 else
10269                     return BAD_MUTEX_ERROR;
10270             #else
10271                 return 0;
10272             #endif
10273 
10274         }
10275 
10276     #elif defined(EBSNET)
10277 
10278         int InitMutex(CyaSSL_Mutex* m)
10279         {
10280             if (rtp_sig_mutex_alloc(m, "CyaSSL Mutex") == -1)
10281                 return BAD_MUTEX_ERROR;
10282             else
10283                 return 0;
10284         }
10285 
10286         int FreeMutex(CyaSSL_Mutex* m)
10287         {
10288             rtp_sig_mutex_free(*m);
10289             return 0;
10290         }
10291 
10292         int LockMutex(CyaSSL_Mutex* m)
10293         {
10294             if (rtp_sig_mutex_claim_timed(*m, RTIP_INF) == 0)
10295                 return 0;
10296             else
10297                 return BAD_MUTEX_ERROR;
10298         }
10299 
10300         int UnLockMutex(CyaSSL_Mutex* m)
10301         {
10302             rtp_sig_mutex_release(*m);
10303             return 0;
10304         }
10305 
10306     #elif defined(FREESCALE_MQX)
10307 
10308         int InitMutex(CyaSSL_Mutex* m)
10309         {
10310             if (_mutex_init(m, NULL) == MQX_EOK)
10311                 return 0;
10312             else
10313                 return BAD_MUTEX_ERROR;
10314         }
10315 
10316         int FreeMutex(CyaSSL_Mutex* m)
10317         {
10318             if (_mutex_destroy(m) == MQX_EOK)
10319                 return 0;
10320             else
10321                 return BAD_MUTEX_ERROR;
10322         }
10323 
10324         int LockMutex(CyaSSL_Mutex* m)
10325         {
10326             if (_mutex_lock(m) == MQX_EOK)
10327                 return 0;
10328             else
10329                 return BAD_MUTEX_ERROR;
10330         }
10331 
10332         int UnLockMutex(CyaSSL_Mutex* m)
10333         {
10334             if (_mutex_unlock(m) == MQX_EOK)
10335                 return 0;
10336             else
10337                 return BAD_MUTEX_ERROR;
10338         }
10339         
10340     #elif defined(CYASSL_MDK_ARM)
10341 
10342         int InitMutex(CyaSSL_Mutex* m)
10343         {
10344             os_mut_init (m); 
10345             return 0;
10346         }
10347 
10348         int FreeMutex(CyaSSL_Mutex* m)
10349         {
10350             return(0) ;
10351         }
10352 
10353         int LockMutex(CyaSSL_Mutex* m)
10354         {
10355             os_mut_wait (m, 0xffff);
10356             return(0) ;
10357         }
10358 
10359         int UnLockMutex(CyaSSL_Mutex* m)
10360         {
10361             os_mut_release (m);
10362             return 0;
10363         }
10364     #endif /* USE_WINDOWS_API */
10365 #endif /* SINGLE_THREADED */