wolf SSL / CyaSSL-2.9.4

Dependents:  

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers internal.c Source File

internal.c

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