Fork of CyaSSL for my specific settings

Dependents:   CyaSSL_Example

Fork of CyaSSL by wolf SSL

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