cyassl re-port with cellular comms, PSK test

Dependencies:   VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers internal.c Source File

internal.c

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