]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/CyaSSL/src/internal.c
Prepare for V7.2.0 release.
[freertos] / FreeRTOS-Plus / CyaSSL / src / internal.c
1 /* internal.c
2  *
3  * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * CyaSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22
23 #ifdef HAVE_CONFIG_H
24     #include <config.h>
25 #endif
26
27 #include <cyassl/internal.h>
28 #include <cyassl/error.h>
29 #include <cyassl/ctaocrypt/asn.h>
30
31 #ifdef HAVE_LIBZ
32     #include "zlib.h"
33 #endif
34
35 #ifdef HAVE_NTRU
36     #include "crypto_ntru.h"
37 #endif
38
39 #if defined(DEBUG_CYASSL) || defined(SHOW_SECRETS)
40     #include <stdio.h>
41 #endif
42
43 #ifdef __sun
44     #include <sys/filio.h>
45 #endif
46
47 #define TRUE  1
48 #define FALSE 0
49
50
51 #if defined(OPENSSL_EXTRA) && defined(NO_DH)
52     #error OPENSSL_EXTRA needs DH, please remove NO_DH
53 #endif
54
55
56 #ifndef NO_CYASSL_CLIENT
57     static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input, word32*);
58     static int DoServerHello(CYASSL* ssl, const byte* input, word32*, word32);
59     static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32*);
60     static int DoServerKeyExchange(CYASSL* ssl, const byte* input, word32*);
61 #endif
62
63
64 #ifndef NO_CYASSL_SERVER
65     static int DoClientHello(CYASSL* ssl, const byte* input, word32*, word32,
66                              word32);
67     static int DoCertificateVerify(CYASSL* ssl, byte*, word32*, word32);
68     static int DoClientKeyExchange(CYASSL* ssl, byte* input, word32*);
69 #endif
70
71 typedef enum {
72     doProcessInit = 0,
73 #ifndef NO_CYASSL_SERVER
74     runProcessOldClientHello,
75 #endif
76     getRecordLayerHeader,
77     getData,
78     runProcessingOneMessage
79 } processReply;
80
81 static void Hmac(CYASSL* ssl, byte* digest, const byte* buffer, word32 sz,
82                  int content, int verify);
83
84 static void BuildCertHashes(CYASSL* ssl, Hashes* hashes);
85
86
87 #ifndef min
88
89     static INLINE word32 min(word32 a, word32 b)
90     {
91         return a > b ? b : a;
92     }
93
94 #endif /* min */
95
96
97 int IsTLS(const CYASSL* ssl)
98 {
99     if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_MINOR)
100         return 1;
101
102     return 0;
103 }
104
105
106 int IsAtLeastTLSv1_2(const CYASSL* ssl)
107 {
108     if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_2_MINOR)
109         return 1;
110
111     return 0;
112 }
113
114
115 #ifdef HAVE_NTRU
116
117 static byte GetEntropy(ENTROPY_CMD cmd, byte* out)
118 {
119     /* TODO: add locking? */
120     static RNG rng;
121
122     if (cmd == INIT) {
123         int ret = InitRng(&rng);
124         if (ret == 0)
125             return 1;
126         else
127             return 0;
128     }
129
130     if (out == NULL)
131         return 0;
132
133     if (cmd == GET_BYTE_OF_ENTROPY) {
134         RNG_GenerateBlock(&rng, out, 1);
135         return 1;
136     }
137
138     if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) {
139         *out = 1;
140         return 1;
141     }
142
143     return 0;
144 }
145
146 #endif /* HAVE_NTRU */
147
148 /* used by ssl.c too */
149 void c32to24(word32 in, word24 out)
150 {
151     out[0] = (in >> 16) & 0xff;
152     out[1] = (in >>  8) & 0xff;
153     out[2] =  in & 0xff;
154 }
155
156
157 #ifdef CYASSL_DTLS
158
159 static INLINE void c32to48(word32 in, byte out[6])
160 {
161     out[0] = 0;
162     out[1] = 0;
163     out[2] = (in >> 24) & 0xff;
164     out[3] = (in >> 16) & 0xff;
165     out[4] = (in >>  8) & 0xff;
166     out[5] =  in & 0xff;
167 }
168
169 #endif /* CYASSL_DTLS */
170
171
172 /* convert 16 bit integer to opaque */
173 static INLINE void c16toa(word16 u16, byte* c)
174 {
175     c[0] = (u16 >> 8) & 0xff;
176     c[1] =  u16 & 0xff;
177 }
178
179
180 /* convert 32 bit integer to opaque */
181 static INLINE void c32toa(word32 u32, byte* c)
182 {
183     c[0] = (u32 >> 24) & 0xff;
184     c[1] = (u32 >> 16) & 0xff;
185     c[2] = (u32 >>  8) & 0xff;
186     c[3] =  u32 & 0xff;
187 }
188
189
190 /* convert a 24 bit integer into a 32 bit one */
191 static INLINE void c24to32(const word24 u24, word32* u32)
192 {
193     *u32 = 0;
194     *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
195 }
196
197
198 /* convert opaque to 16 bit integer */
199 static INLINE void ato16(const byte* c, word16* u16)
200 {
201     *u16 = 0;
202     *u16 = (c[0] << 8) | (c[1]);
203 }
204
205
206 #ifdef CYASSL_DTLS
207
208 /* convert opaque to 32 bit integer */
209 static INLINE void ato32(const byte* c, word32* u32)
210 {
211     *u32 = 0;
212     *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
213 }
214
215 #endif /* CYASSL_DTLS */
216
217
218 #ifdef HAVE_LIBZ
219
220     /* alloc user allocs to work with zlib */
221     static void* myAlloc(void* opaque, unsigned int item, unsigned int size)
222     {
223         (void)opaque;
224         return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
225     }
226
227
228     static void myFree(void* opaque, void* memory)
229     {
230         (void)opaque;
231         XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ);
232     }
233
234
235     /* init zlib comp/decomp streams, 0 on success */
236     static int InitStreams(CYASSL* ssl)
237     {
238         ssl->c_stream.zalloc = (alloc_func)myAlloc;
239         ssl->c_stream.zfree  = (free_func)myFree;
240         ssl->c_stream.opaque = (voidpf)ssl->heap;
241
242         if (deflateInit(&ssl->c_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
243             return ZLIB_INIT_ERROR;
244
245         ssl->didStreamInit = 1;
246
247         ssl->d_stream.zalloc = (alloc_func)myAlloc;
248         ssl->d_stream.zfree  = (free_func)myFree;
249         ssl->d_stream.opaque = (voidpf)ssl->heap;
250
251         if (inflateInit(&ssl->d_stream) != Z_OK) return ZLIB_INIT_ERROR;
252
253         return 0;
254     }
255
256
257     static void FreeStreams(CYASSL* ssl)
258     {
259         if (ssl->didStreamInit) {
260             deflateEnd(&ssl->c_stream);
261             inflateEnd(&ssl->d_stream);
262         }
263     }
264
265
266     /* compress in to out, return out size or error */
267     static int Compress(CYASSL* ssl, byte* in, int inSz, byte* out, int outSz)
268     {
269         int    err;
270         int    currTotal = ssl->c_stream.total_out;
271
272         ssl->c_stream.next_in   = in;
273         ssl->c_stream.avail_in  = inSz;
274         ssl->c_stream.next_out  = out;
275         ssl->c_stream.avail_out = outSz;
276
277         err = deflate(&ssl->c_stream, Z_SYNC_FLUSH);
278         if (err != Z_OK && err != Z_STREAM_END) return ZLIB_COMPRESS_ERROR;
279
280         return ssl->c_stream.total_out - currTotal;
281     }
282         
283
284     /* decompress in to out, returnn out size or error */
285     static int DeCompress(CYASSL* ssl, byte* in, int inSz, byte* out, int outSz)
286     {
287         int    err;
288         int    currTotal = ssl->d_stream.total_out;
289
290         ssl->d_stream.next_in   = in;
291         ssl->d_stream.avail_in  = inSz;
292         ssl->d_stream.next_out  = out;
293         ssl->d_stream.avail_out = outSz;
294
295         err = inflate(&ssl->d_stream, Z_SYNC_FLUSH);
296         if (err != Z_OK && err != Z_STREAM_END) return ZLIB_DECOMPRESS_ERROR;
297
298         return ssl->d_stream.total_out - currTotal;
299     }
300         
301 #endif /* HAVE_LIBZ */
302
303
304 void InitSSL_Method(CYASSL_METHOD* method, ProtocolVersion pv)
305 {
306     method->version    = pv;
307     method->side       = CLIENT_END;
308     method->downgrade  = 0;
309 }
310
311
312 /* Initialze SSL context, return 0 on success */
313 int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
314 {
315     ctx->method = method;
316     ctx->refCount = 1;          /* so either CTX_free or SSL_free can release */
317     ctx->certificate.buffer = 0;
318     ctx->certChain.buffer   = 0;
319     ctx->privateKey.buffer  = 0;
320     ctx->serverDH_P.buffer  = 0;
321     ctx->serverDH_G.buffer  = 0;
322     ctx->haveDH             = 0;
323     ctx->haveNTRU           = 0;    /* start off */
324     ctx->haveECDSAsig       = 0;    /* start off */
325     ctx->haveStaticECC      = 0;    /* start off */
326     ctx->heap               = ctx;  /* defaults to self */
327 #ifndef NO_PSK
328     ctx->havePSK            = 0;
329     ctx->server_hint[0]     = 0;
330     ctx->client_psk_cb      = 0;
331     ctx->server_psk_cb      = 0;
332 #endif /* NO_PSK */
333 #ifdef HAVE_ECC
334     ctx->eccTempKeySz       = ECDHE_SIZE;   
335 #endif
336
337 #ifdef OPENSSL_EXTRA
338     ctx->passwd_cb   = 0;
339     ctx->userdata    = 0;
340 #endif /* OPENSSL_EXTRA */
341
342     ctx->timeout = DEFAULT_TIMEOUT;
343
344 #ifndef CYASSL_USER_IO
345     ctx->CBIORecv = EmbedReceive;
346     ctx->CBIOSend = EmbedSend;
347 #else
348     /* user will set */
349     ctx->CBIORecv = NULL;
350     ctx->CBIOSend = NULL;
351 #endif
352     ctx->partialWrite   = 0;
353     ctx->verifyCallback = 0;
354
355     ctx->cm = CyaSSL_CertManagerNew();
356 #ifdef HAVE_NTRU
357     if (method->side == CLIENT_END)
358         ctx->haveNTRU = 1;           /* always on cliet side */
359                                      /* server can turn on by loading key */
360 #endif
361 #ifdef HAVE_ECC
362     if (method->side == CLIENT_END) {
363         ctx->haveECDSAsig  = 1;        /* always on cliet side */
364         ctx->haveStaticECC = 1;        /* server can turn on by loading key */
365     }
366 #endif
367     ctx->suites.setSuites = 0;  /* user hasn't set yet */
368     /* remove DH later if server didn't set, add psk later */
369     InitSuites(&ctx->suites, method->version, TRUE, FALSE, ctx->haveNTRU,
370                ctx->haveECDSAsig, ctx->haveStaticECC, method->side);  
371     ctx->verifyPeer = 0;
372     ctx->verifyNone = 0;
373     ctx->failNoCert = 0;
374     ctx->sessionCacheOff      = 0;  /* initially on */
375     ctx->sessionCacheFlushOff = 0;  /* initially on */
376     ctx->sendVerify = 0;
377     ctx->quietShutdown = 0;
378     ctx->groupMessages = 0;
379 #ifdef HAVE_OCSP
380     CyaSSL_OCSP_Init(&ctx->ocsp);
381 #endif
382
383     if (InitMutex(&ctx->countMutex) < 0) {
384         CYASSL_MSG("Mutex error on CTX init");
385         return BAD_MUTEX_ERROR;
386     } 
387     if (ctx->cm == NULL) {
388         CYASSL_MSG("Bad Cert Manager New");
389         return BAD_CERT_MANAGER_ERROR;
390     }
391     return 0;
392 }
393
394
395 /* In case contexts are held in array and don't want to free actual ctx */
396 void SSL_CtxResourceFree(CYASSL_CTX* ctx)
397 {
398     XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
399     XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
400     XFREE(ctx->privateKey.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
401     XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
402     XFREE(ctx->certChain.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
403     XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
404
405     CyaSSL_CertManagerFree(ctx->cm);
406
407 #ifdef HAVE_OCSP
408     CyaSSL_OCSP_Cleanup(&ctx->ocsp);
409 #endif
410 }
411
412
413 void FreeSSL_Ctx(CYASSL_CTX* ctx)
414 {
415     int doFree = 0;
416
417     if (LockMutex(&ctx->countMutex) != 0) {
418         CYASSL_MSG("Couldn't lock count mutex");
419         return;
420     }
421     ctx->refCount--;
422     if (ctx->refCount == 0)
423         doFree = 1;
424     UnLockMutex(&ctx->countMutex);
425
426     if (doFree) {
427         CYASSL_MSG("CTX ref count down to 0, doing full free");
428         SSL_CtxResourceFree(ctx);
429         XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
430     }
431     else {
432         (void)ctx;
433         CYASSL_MSG("CTX ref count not 0 yet, no free");
434     }
435 }
436
437     
438 void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
439                 byte haveNTRU, byte haveECDSAsig, byte haveStaticECC, int side)
440 {
441     word16 idx = 0;
442     int    tls    = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR;
443     int    tls1_2 = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_2_MINOR;
444     int    haveRSA = 1;
445     int    haveRSAsig = 1;
446
447     (void)tls;  /* shut up compiler */
448     (void)haveDH;
449     (void)havePSK;
450     (void)haveNTRU;
451     (void)haveStaticECC;
452
453     if (suites->setSuites)
454         return;      /* trust user settings, don't override */
455
456     if (side == SERVER_END && haveStaticECC)
457         haveRSA = 0;   /* can't do RSA with ECDSA key */
458
459     if (side == SERVER_END && haveECDSAsig)
460         haveRSAsig = 0;  /* can't have RSA sig if signed by ECDSA */
461
462 #ifdef CYASSL_DTLS
463     if (pv.major == DTLS_MAJOR && pv.minor == DTLS_MINOR)
464         tls = 1;
465 #endif
466
467 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
468     if (tls && haveNTRU && haveRSA) {
469         suites->suites[idx++] = 0; 
470         suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_256_CBC_SHA;
471     }
472 #endif
473
474 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
475     if (tls && haveNTRU && haveRSA) {
476         suites->suites[idx++] = 0; 
477         suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_128_CBC_SHA;
478     }
479 #endif
480
481 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
482     if (tls && haveNTRU && haveRSA) {
483         suites->suites[idx++] = 0; 
484         suites->suites[idx++] = TLS_NTRU_RSA_WITH_RC4_128_SHA;
485     }
486 #endif
487
488 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
489     if (tls && haveNTRU && haveRSA) {
490         suites->suites[idx++] = 0; 
491         suites->suites[idx++] = TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA;
492     }
493 #endif
494
495 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
496     if (tls1_2 && haveStaticECC) {
497         suites->suites[idx++] = ECC_BYTE;
498         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
499     }
500 #endif
501
502 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
503     if (tls && haveStaticECC) {
504         suites->suites[idx++] = ECC_BYTE; 
505         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA;
506     }
507 #endif
508
509 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
510     if (tls1_2 && haveECDSAsig && haveStaticECC) {
511         suites->suites[idx++] = ECC_BYTE;
512         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
513     }
514 #endif
515
516 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
517     if (tls && haveECDSAsig && haveStaticECC) {
518         suites->suites[idx++] = ECC_BYTE; 
519         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA;
520     }
521 #endif
522
523 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
524     if (tls1_2 && haveStaticECC) {
525         suites->suites[idx++] = ECC_BYTE;
526         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
527     }
528 #endif
529
530 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
531     if (tls && haveStaticECC) {
532         suites->suites[idx++] = ECC_BYTE; 
533         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA;
534     }
535 #endif
536
537 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
538     if (tls1_2 && haveECDSAsig && haveStaticECC) {
539         suites->suites[idx++] = ECC_BYTE;
540         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
541     }
542 #endif
543
544 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
545     if (tls && haveECDSAsig && haveStaticECC) {
546         suites->suites[idx++] = ECC_BYTE; 
547         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA;
548     }
549 #endif
550
551 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
552     if (tls && haveStaticECC) {
553         suites->suites[idx++] = ECC_BYTE; 
554         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA;
555     }
556 #endif
557
558 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
559     if (tls && haveECDSAsig && haveStaticECC) {
560         suites->suites[idx++] = ECC_BYTE; 
561         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA;
562     }
563 #endif
564
565 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
566     if (tls && haveStaticECC) {
567         suites->suites[idx++] = ECC_BYTE; 
568         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA;
569     }
570 #endif
571
572 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
573     if (tls && haveECDSAsig && haveStaticECC) {
574         suites->suites[idx++] = ECC_BYTE; 
575         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA;
576     }
577 #endif
578
579 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
580     if (tls1_2 && haveRSA) {
581         suites->suites[idx++] = ECC_BYTE;
582         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
583     }
584 #endif
585
586 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
587     if (tls && haveRSA) {
588         suites->suites[idx++] = ECC_BYTE; 
589         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
590     }
591 #endif
592
593 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
594     if (tls1_2 && haveRSAsig && haveStaticECC) {
595         suites->suites[idx++] = ECC_BYTE;
596         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
597     }
598 #endif
599
600 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
601     if (tls && haveRSAsig && haveStaticECC) {
602         suites->suites[idx++] = ECC_BYTE; 
603         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA;
604     }
605 #endif
606
607 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
608     if (tls1_2 && haveRSA) {
609         suites->suites[idx++] = ECC_BYTE;
610         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
611     }
612 #endif
613
614 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
615     if (tls && haveRSA) {
616         suites->suites[idx++] = ECC_BYTE; 
617         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA;
618     }
619 #endif
620
621 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
622     if (tls1_2 && haveRSAsig && haveStaticECC) {
623         suites->suites[idx++] = ECC_BYTE;
624         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
625     }
626 #endif
627
628 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
629     if (tls && haveRSAsig && haveStaticECC) {
630         suites->suites[idx++] = ECC_BYTE; 
631         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA;
632     }
633 #endif
634
635 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
636     if (tls && haveRSA) {
637         suites->suites[idx++] = ECC_BYTE; 
638         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_RC4_128_SHA;
639     }
640 #endif
641
642 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
643     if (tls && haveRSAsig && haveStaticECC) {
644         suites->suites[idx++] = ECC_BYTE; 
645         suites->suites[idx++] = TLS_ECDH_RSA_WITH_RC4_128_SHA;
646     }
647 #endif
648
649 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
650     if (tls && haveRSA) {
651         suites->suites[idx++] = ECC_BYTE; 
652         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA;
653     }
654 #endif
655
656 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
657     if (tls && haveRSAsig && haveStaticECC) {
658         suites->suites[idx++] = ECC_BYTE; 
659         suites->suites[idx++] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA;
660     }
661 #endif
662
663 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
664     if (tls1_2 && haveDH && haveRSA) {
665         suites->suites[idx++] = 0;
666         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
667     }
668 #endif
669
670 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
671     if (tls1_2 && haveDH && haveRSA) {
672         suites->suites[idx++] = 0; 
673         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
674     }
675 #endif
676
677 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
678     if (tls1_2 && haveDH && haveRSA) {
679         suites->suites[idx++] = 0;
680         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
681     }
682 #endif
683
684 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
685     if (tls1_2 && haveDH && haveRSA) {
686         suites->suites[idx++] = 0; 
687         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
688     }
689 #endif
690
691 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
692     if (tls && haveDH && haveRSA) {
693         suites->suites[idx++] = 0; 
694         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
695     }
696 #endif
697
698 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
699     if (tls && haveDH && haveRSA) {
700         suites->suites[idx++] = 0; 
701         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
702     }
703 #endif
704
705 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
706     if (tls1_2 && haveRSA) {
707         suites->suites[idx++] = 0;
708         suites->suites[idx++] = TLS_RSA_WITH_AES_256_GCM_SHA384;
709     }
710 #endif
711
712 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
713     if (tls1_2 && haveRSA) {
714         suites->suites[idx++] = 0; 
715         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
716     }
717 #endif
718
719 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
720     if (tls1_2 && haveRSA) {
721         suites->suites[idx++] = 0;
722         suites->suites[idx++] = TLS_RSA_WITH_AES_128_GCM_SHA256;
723     }
724 #endif
725
726 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
727     if (tls1_2 && haveRSA) {
728         suites->suites[idx++] = 0; 
729         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
730     }
731 #endif
732
733 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
734     if (tls && haveRSA) {
735         suites->suites[idx++] = 0; 
736         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA;
737     }
738 #endif
739
740 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
741     if (tls && haveRSA) {
742         suites->suites[idx++] = 0; 
743         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA;
744     }
745 #endif
746
747 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
748     if (tls && havePSK) {
749         suites->suites[idx++] = 0; 
750         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA;
751     }
752 #endif
753
754 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
755     if (tls && havePSK) {
756         suites->suites[idx++] = 0; 
757         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA;
758     }
759 #endif
760
761 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
762     if (haveRSA ) {
763         suites->suites[idx++] = 0; 
764         suites->suites[idx++] = SSL_RSA_WITH_RC4_128_SHA;
765     }
766 #endif
767
768 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
769     if (haveRSA ) {
770         suites->suites[idx++] = 0; 
771         suites->suites[idx++] = SSL_RSA_WITH_RC4_128_MD5;
772     }
773 #endif
774
775 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
776     if (haveRSA ) {
777         suites->suites[idx++] = 0; 
778         suites->suites[idx++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
779     }
780 #endif
781
782 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
783     if (tls && haveRSA) {
784         suites->suites[idx++] = 0; 
785         suites->suites[idx++] = TLS_RSA_WITH_HC_128_CBC_MD5;
786     }
787 #endif
788     
789 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
790     if (tls && haveRSA) {
791         suites->suites[idx++] = 0; 
792         suites->suites[idx++] = TLS_RSA_WITH_HC_128_CBC_SHA;
793     }
794 #endif
795
796 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
797     if (tls && haveRSA) {
798         suites->suites[idx++] = 0; 
799         suites->suites[idx++] = TLS_RSA_WITH_RABBIT_CBC_SHA;
800     }
801 #endif
802
803     suites->suiteSz = idx;
804 }
805
806
807 /* init everything to 0, NULL, default values before calling anything that may
808    fail so that desctructor has a "good" state to cleanup */
809 int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
810 {
811     int  ret;
812     byte havePSK = 0;
813
814     ssl->ctx     = ctx; /* only for passing to calls, options could change */
815     ssl->version = ctx->method->version;
816     ssl->suites  = ctx->suites;
817
818 #ifdef HAVE_LIBZ
819     ssl->didStreamInit = 0;
820 #endif
821    
822     ssl->buffers.certificate.buffer   = 0;
823     ssl->buffers.key.buffer           = 0;
824     ssl->buffers.certChain.buffer     = 0;
825     ssl->buffers.inputBuffer.length   = 0;
826     ssl->buffers.inputBuffer.idx      = 0;
827     ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
828     ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
829     ssl->buffers.inputBuffer.dynamicFlag = 0;
830     ssl->buffers.outputBuffer.length  = 0;
831     ssl->buffers.outputBuffer.idx     = 0;
832     ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
833     ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
834     ssl->buffers.outputBuffer.dynamicFlag = 0;
835     ssl->buffers.domainName.buffer    = 0;
836     ssl->buffers.serverDH_P.buffer    = 0;
837     ssl->buffers.serverDH_G.buffer    = 0;
838     ssl->buffers.serverDH_Pub.buffer  = 0;
839     ssl->buffers.serverDH_Priv.buffer = 0;
840     ssl->buffers.clearOutputBuffer.buffer  = 0;
841     ssl->buffers.clearOutputBuffer.length  = 0;
842     ssl->buffers.prevSent                  = 0;
843     ssl->buffers.plainSz                   = 0;
844
845 #ifdef OPENSSL_EXTRA
846     ssl->peerCert.derCert.buffer = NULL;
847     ssl->peerCert.altNames     = NULL;
848     ssl->peerCert.altNamesNext = NULL;
849 #endif
850
851 #ifdef HAVE_ECC
852     ssl->eccTempKeySz = ctx->eccTempKeySz;
853     ssl->peerEccKeyPresent = 0;
854     ssl->peerEccDsaKeyPresent = 0;
855     ssl->eccDsaKeyPresent = 0;
856     ssl->eccTempKeyPresent = 0;
857     ecc_init(&ssl->peerEccKey);
858     ecc_init(&ssl->peerEccDsaKey);
859     ecc_init(&ssl->eccDsaKey);
860     ecc_init(&ssl->eccTempKey);
861 #endif
862
863     ssl->timeout = ctx->timeout;
864     ssl->rfd = -1;   /* set to invalid descriptor */
865     ssl->wfd = -1;
866     ssl->biord = 0;
867     ssl->biowr = 0;
868
869     ssl->IOCB_ReadCtx  = &ssl->rfd;   /* prevent invalid pointer acess if not */
870     ssl->IOCB_WriteCtx = &ssl->wfd;   /* correctly set */
871
872     InitMd5(&ssl->hashMd5);
873     InitSha(&ssl->hashSha);
874 #ifndef NO_SHA256
875     InitSha256(&ssl->hashSha256);
876 #endif
877 #ifdef CYASSL_SHA384
878     InitSha384(&ssl->hashSha384);
879 #endif
880     InitRsaKey(&ssl->peerRsaKey, ctx->heap);
881
882     ssl->verifyCallback    = ctx->verifyCallback;
883     ssl->peerRsaKeyPresent = 0;
884     ssl->options.side      = ctx->method->side;
885     ssl->options.downgrade = ctx->method->downgrade;
886     ssl->error = 0;
887     ssl->options.connReset = 0;
888     ssl->options.isClosed  = 0;
889     ssl->options.closeNotify  = 0;
890     ssl->options.sentNotify   = 0;
891     ssl->options.usingCompression = 0;
892     if (ssl->options.side == SERVER_END)
893         ssl->options.haveDH = ctx->haveDH;
894     else
895         ssl->options.haveDH = 0;
896     ssl->options.haveNTRU      = ctx->haveNTRU;
897     ssl->options.haveECDSAsig  = ctx->haveECDSAsig;
898     ssl->options.haveStaticECC = ctx->haveStaticECC;
899     ssl->options.havePeerCert  = 0; 
900     ssl->options.usingPSK_cipher = 0;
901     ssl->options.sendAlertState = 0;
902 #ifndef NO_PSK
903     havePSK = ctx->havePSK;
904     ssl->options.havePSK   = ctx->havePSK;
905     ssl->options.client_psk_cb = ctx->client_psk_cb;
906     ssl->options.server_psk_cb = ctx->server_psk_cb;
907 #endif /* NO_PSK */
908
909     ssl->options.serverState = NULL_STATE;
910     ssl->options.clientState = NULL_STATE;
911     ssl->options.connectState = CONNECT_BEGIN;
912     ssl->options.acceptState  = ACCEPT_BEGIN; 
913     ssl->options.handShakeState  = NULL_STATE; 
914     ssl->options.processReply = doProcessInit;
915
916 #ifdef CYASSL_DTLS
917     ssl->keys.dtls_sequence_number       = 0;
918     ssl->keys.dtls_peer_sequence_number  = 0;
919     ssl->keys.dtls_handshake_number      = 0;
920     ssl->keys.dtls_epoch      = 0;
921     ssl->keys.dtls_peer_epoch = 0;
922     ssl->arrays.cookieSz = 0;
923 #endif
924     ssl->keys.encryptionOn = 0;     /* initially off */
925     ssl->options.sessionCacheOff      = ctx->sessionCacheOff;
926     ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
927
928     ssl->options.verifyPeer = ctx->verifyPeer;
929     ssl->options.verifyNone = ctx->verifyNone;
930     ssl->options.failNoCert = ctx->failNoCert;
931     ssl->options.sendVerify = ctx->sendVerify;
932     
933     ssl->options.resuming = 0;
934     ssl->options.haveSessionId = 0;
935     ssl->hmac = Hmac;         /* default to SSLv3 */
936     ssl->heap = ctx->heap;    /* defaults to self */
937     ssl->options.tls    = 0;
938     ssl->options.tls1_1 = 0;
939     ssl->options.dtls   = 0;
940     ssl->options.partialWrite  = ctx->partialWrite;
941     ssl->options.quietShutdown = ctx->quietShutdown;
942     ssl->options.certOnly = 0;
943     ssl->options.groupMessages = ctx->groupMessages;
944
945     /* ctx still owns certificate, certChain, key, dh, and cm */
946     ssl->buffers.certificate = ctx->certificate;
947     ssl->buffers.certChain = ctx->certChain;
948     ssl->buffers.key = ctx->privateKey;
949     if (ssl->options.side == SERVER_END) {
950         ssl->buffers.serverDH_P = ctx->serverDH_P;
951         ssl->buffers.serverDH_G = ctx->serverDH_G;
952     }
953     ssl->buffers.weOwnCert = 0;
954     ssl->buffers.weOwnKey  = 0;
955     ssl->buffers.weOwnDH   = 0;
956
957 #ifdef OPENSSL_EXTRA
958     ssl->peerCert.issuer.sz    = 0;
959     ssl->peerCert.subject.sz   = 0;
960 #endif
961   
962 #ifdef SESSION_CERTS
963     ssl->session.chain.count = 0;
964 #endif
965
966     ssl->cipher.ssl = ssl;
967
968 #ifdef FORTRESS
969     ssl->ex_data[0] = 0;
970     ssl->ex_data[1] = 0;
971     ssl->ex_data[2] = 0;
972 #endif
973
974 #ifdef CYASSL_CALLBACKS
975     ssl->hsInfoOn = 0;
976     ssl->toInfoOn = 0;
977 #endif
978
979 #ifndef NO_PSK
980     ssl->arrays.client_identity[0] = 0;
981     if (ctx->server_hint[0]) {   /* set in CTX */
982         XSTRNCPY(ssl->arrays.server_hint, ctx->server_hint, MAX_PSK_ID_LEN);
983         ssl->arrays.server_hint[MAX_PSK_ID_LEN - 1] = '\0';
984     }
985     else
986         ssl->arrays.server_hint[0] = 0;
987 #endif /* NO_PSK */
988
989     /* all done with init, now can return errors, call other stuff */
990
991     /* increment CTX reference count */
992     if (LockMutex(&ctx->countMutex) != 0) {
993         CYASSL_MSG("Couldn't lock CTX count mutex");
994         return BAD_MUTEX_ERROR;
995     }
996     ctx->refCount++;
997     UnLockMutex(&ctx->countMutex);
998
999     if ( (ret = InitRng(&ssl->rng)) != 0)
1000         return ret;
1001
1002     /* make sure server has cert and key unless using PSK */
1003     if (ssl->options.side == SERVER_END && !havePSK)
1004         if (!ssl->buffers.certificate.buffer || !ssl->buffers.key.buffer) {
1005             CYASSL_MSG("Server missing certificate and/or private key"); 
1006             return NO_PRIVATE_KEY;
1007         }
1008
1009     /* make sure server has DH parms, and add PSK if there, add NTRU too */
1010     if (ssl->options.side == SERVER_END) 
1011         InitSuites(&ssl->suites, ssl->version,ssl->options.haveDH, havePSK,
1012                    ssl->options.haveNTRU, ssl->options.haveECDSAsig,
1013                    ssl->options.haveStaticECC, ssl->options.side);
1014     else 
1015         InitSuites(&ssl->suites, ssl->version, TRUE, havePSK,
1016                    ssl->options.haveNTRU, ssl->options.haveECDSAsig,
1017                    ssl->options.haveStaticECC, ssl->options.side);
1018
1019     return 0;
1020 }
1021
1022
1023 /* In case holding SSL object in array and don't want to free actual ssl */
1024 void SSL_ResourceFree(CYASSL* ssl)
1025 {
1026     XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
1027     XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH);
1028     /* parameters (p,g) may be owned by ctx */
1029     if (ssl->buffers.weOwnDH || ssl->options.side == CLIENT_END) {
1030         XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
1031         XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
1032     }
1033     XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
1034
1035     /* CYASSL_CTX always owns certChain */
1036     if (ssl->buffers.weOwnCert)
1037         XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
1038     if (ssl->buffers.weOwnKey)
1039         XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
1040
1041     FreeRsaKey(&ssl->peerRsaKey);
1042     if (ssl->buffers.inputBuffer.dynamicFlag)
1043         ShrinkInputBuffer(ssl, FORCED_FREE);
1044     if (ssl->buffers.outputBuffer.dynamicFlag)
1045         ShrinkOutputBuffer(ssl);
1046 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
1047     XFREE(ssl->peerCert.derCert.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
1048     if (ssl->peerCert.altNames)
1049         FreeAltNames(ssl->peerCert.altNames, ssl->heap);
1050     CyaSSL_BIO_free(ssl->biord);
1051     if (ssl->biord != ssl->biowr)        /* in case same as write */
1052         CyaSSL_BIO_free(ssl->biowr);
1053 #endif
1054 #ifdef HAVE_LIBZ
1055     FreeStreams(ssl);
1056 #endif
1057 #ifdef HAVE_ECC
1058     ecc_free(&ssl->peerEccKey);
1059     ecc_free(&ssl->peerEccDsaKey);
1060     ecc_free(&ssl->eccTempKey);
1061     ecc_free(&ssl->eccDsaKey);
1062 #endif
1063 }
1064
1065
1066 void FreeSSL(CYASSL* ssl)
1067 {
1068     FreeSSL_Ctx(ssl->ctx);  /* will decrement and free underyling CTX if 0 */
1069     SSL_ResourceFree(ssl);
1070     XFREE(ssl, ssl->heap, DYNAMIC_TYPE_SSL);
1071 }
1072
1073
1074 ProtocolVersion MakeSSLv3(void)
1075 {
1076     ProtocolVersion pv;
1077     pv.major = SSLv3_MAJOR;
1078     pv.minor = SSLv3_MINOR;
1079
1080     return pv;
1081 }
1082
1083
1084 #ifdef CYASSL_DTLS
1085
1086 ProtocolVersion MakeDTLSv1(void)
1087 {
1088     ProtocolVersion pv;
1089     pv.major = DTLS_MAJOR;
1090     pv.minor = DTLS_MINOR;
1091
1092     return pv;
1093 }
1094
1095 #endif /* CYASSL_DTLS */
1096
1097
1098
1099
1100 #ifdef USE_WINDOWS_API 
1101
1102     timer_d Timer(void)
1103     {
1104         static int           init = 0;
1105         static LARGE_INTEGER freq;
1106         LARGE_INTEGER        count;
1107     
1108         if (!init) {
1109             QueryPerformanceFrequency(&freq);
1110             init = 1;
1111         }
1112
1113         QueryPerformanceCounter(&count);
1114
1115         return (double)count.QuadPart / freq.QuadPart;
1116     }
1117
1118
1119     word32 LowResTimer(void)
1120     {
1121         return (word32)Timer();
1122     }
1123
1124
1125 #elif defined(THREADX)
1126
1127     #include "rtptime.h"
1128
1129     word32 LowResTimer(void)
1130     {
1131         return (word32)rtp_get_system_sec();
1132     }
1133
1134
1135 #elif defined(MICRIUM)
1136
1137     word32 LowResTimer(void)
1138     {
1139         NET_SECURE_OS_TICK  clk;
1140
1141         #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
1142             clk = NetSecure_OS_TimeGet();
1143         #endif
1144         return (word32)clk;
1145     }
1146
1147 #elif defined(USER_TICKS)
1148
1149     word32 LowResTimer(void)
1150     {
1151         /*
1152         write your own clock tick function if don't want time(0)
1153         needs second accuracy but doesn't have to correlated to EPOCH
1154         */
1155     }
1156
1157 #else /* !USE_WINDOWS_API && !THREADX && !MICRIUM && !USER_TICKS */
1158
1159     #include <time.h>
1160
1161     word32 LowResTimer(void)
1162     {
1163         return time(0); 
1164     }
1165
1166
1167 #endif /* USE_WINDOWS_API */
1168
1169
1170 /* add output to md5 and sha handshake hashes, exclude record header */
1171 static void HashOutput(CYASSL* ssl, const byte* output, int sz, int ivSz)
1172 {
1173     const byte* adj = output + RECORD_HEADER_SZ + ivSz;
1174     sz -= RECORD_HEADER_SZ;
1175     
1176 #ifdef CYASSL_DTLS
1177     if (ssl->options.dtls) {
1178         adj += DTLS_RECORD_EXTRA;
1179         sz  -= DTLS_RECORD_EXTRA;
1180     }
1181 #endif
1182
1183     Md5Update(&ssl->hashMd5, adj, sz);
1184     ShaUpdate(&ssl->hashSha, adj, sz);
1185     if (IsAtLeastTLSv1_2(ssl)) {
1186 #ifndef NO_SHA256
1187         Sha256Update(&ssl->hashSha256, adj, sz);
1188 #endif
1189 #ifdef CYASSL_SHA384
1190         Sha384Update(&ssl->hashSha384, adj, sz);
1191 #endif
1192     }
1193 }
1194
1195
1196 /* add input to md5 and sha handshake hashes, include handshake header */
1197 static void HashInput(CYASSL* ssl, const byte* input, int sz)
1198 {
1199     const byte* adj = input - HANDSHAKE_HEADER_SZ;
1200     sz += HANDSHAKE_HEADER_SZ;
1201     
1202 #ifdef CYASSL_DTLS
1203     if (ssl->options.dtls) {
1204         adj -= DTLS_HANDSHAKE_EXTRA;
1205         sz  += DTLS_HANDSHAKE_EXTRA;
1206     }
1207 #endif
1208
1209     Md5Update(&ssl->hashMd5, adj, sz);
1210     ShaUpdate(&ssl->hashSha, adj, sz);
1211     if (IsAtLeastTLSv1_2(ssl)) {
1212 #ifndef NO_SHA256
1213         Sha256Update(&ssl->hashSha256, adj, sz);
1214 #endif
1215 #ifdef CYASSL_SHA384
1216         Sha384Update(&ssl->hashSha384, adj, sz);
1217 #endif
1218     }
1219 }
1220
1221
1222 /* add record layer header for message */
1223 static void AddRecordHeader(byte* output, word32 length, byte type, CYASSL* ssl)
1224 {
1225     RecordLayerHeader* rl;
1226   
1227     /* record layer header */
1228     rl = (RecordLayerHeader*)output;
1229     rl->type    = type;
1230     rl->version = ssl->version;           /* type and version same in each */
1231
1232     if (!ssl->options.dtls)
1233         c16toa((word16)length, rl->length);
1234     else {
1235 #ifdef CYASSL_DTLS
1236         DtlsRecordLayerHeader* dtls;
1237     
1238         /* dtls record layer header extensions */
1239         dtls = (DtlsRecordLayerHeader*)output;
1240         c16toa(ssl->keys.dtls_epoch, dtls->epoch);
1241         c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number);
1242         c16toa((word16)length, dtls->length);
1243 #endif
1244     }
1245 }
1246
1247
1248 /* add handshake header for message */
1249 static void AddHandShakeHeader(byte* output, word32 length, byte type,
1250                                CYASSL* ssl)
1251 {
1252     HandShakeHeader* hs;
1253     (void)ssl;
1254  
1255     /* handshake header */
1256     hs = (HandShakeHeader*)output;
1257     hs->type = type;
1258     c32to24(length, hs->length);         /* type and length same for each */
1259 #ifdef CYASSL_DTLS
1260     if (ssl->options.dtls) {
1261         DtlsHandShakeHeader* dtls;
1262     
1263         /* dtls handshake header extensions */
1264         dtls = (DtlsHandShakeHeader*)output;
1265         c16toa(ssl->keys.dtls_handshake_number++, dtls->message_seq);
1266         c32to24(0, dtls->fragment_offset);
1267         c32to24(length, dtls->fragment_length);
1268     }
1269 #endif
1270 }
1271
1272
1273 /* add both headers for handshake message */
1274 static void AddHeaders(byte* output, word32 length, byte type, CYASSL* ssl)
1275 {
1276     if (!ssl->options.dtls) {
1277         AddRecordHeader(output, length + HANDSHAKE_HEADER_SZ, handshake, ssl);
1278         AddHandShakeHeader(output + RECORD_HEADER_SZ, length, type, ssl);
1279     }
1280 #ifdef CYASSL_DTLS
1281     else  {
1282         AddRecordHeader(output, length+DTLS_HANDSHAKE_HEADER_SZ, handshake,ssl);
1283         AddHandShakeHeader(output + DTLS_RECORD_HEADER_SZ, length, type, ssl);
1284     }
1285 #endif
1286 }
1287
1288
1289 /* return bytes received, -1 on error */
1290 static int Receive(CYASSL* ssl, byte* buf, word32 sz)
1291 {
1292     int recvd;
1293
1294 retry:
1295     recvd = ssl->ctx->CBIORecv((char *)buf, (int)sz, ssl->IOCB_ReadCtx);
1296     if (recvd < 0)
1297         switch (recvd) {
1298             case IO_ERR_GENERAL:        /* general/unknown error */
1299                 return -1;
1300
1301             case IO_ERR_WANT_READ:      /* want read, would block */
1302                 return WANT_READ;
1303
1304             case IO_ERR_CONN_RST:       /* connection reset */
1305                 ssl->options.connReset = 1;
1306                 return -1;
1307
1308             case IO_ERR_ISR:            /* interrupt */
1309                 /* see if we got our timeout */
1310                 #ifdef CYASSL_CALLBACKS
1311                     if (ssl->toInfoOn) {
1312                         struct itimerval timeout;
1313                         getitimer(ITIMER_REAL, &timeout);
1314                         if (timeout.it_value.tv_sec == 0 && 
1315                                                 timeout.it_value.tv_usec == 0) {
1316                             XSTRNCPY(ssl->timeoutInfo.timeoutName,
1317                                     "recv() timeout", MAX_TIMEOUT_NAME_SZ);
1318                             CYASSL_MSG("Got our timeout"); 
1319                             return WANT_READ;
1320                         }
1321                     }
1322                 #endif
1323                 goto retry;
1324
1325             case IO_ERR_CONN_CLOSE:     /* peer closed connection */
1326                 ssl->options.isClosed = 1;
1327                 return -1;
1328
1329             default:
1330                 return recvd;
1331         }
1332
1333     return recvd;
1334 }
1335
1336
1337 /* Switch dynamic output buffer back to static, buffer is assumed clear */
1338 void ShrinkOutputBuffer(CYASSL* ssl)
1339 {
1340     CYASSL_MSG("Shrinking output buffer\n");
1341     XFREE(ssl->buffers.outputBuffer.buffer, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
1342     ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
1343     ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
1344     ssl->buffers.outputBuffer.dynamicFlag = 0;
1345 }
1346
1347
1348 /* Switch dynamic input buffer back to static, keep any remaining input */
1349 /* forced free means cleaning up */
1350 void ShrinkInputBuffer(CYASSL* ssl, int forcedFree)
1351 {
1352     int usedLength = ssl->buffers.inputBuffer.length -
1353                      ssl->buffers.inputBuffer.idx;
1354     if (!forcedFree && usedLength > STATIC_BUFFER_LEN)
1355         return;
1356
1357     CYASSL_MSG("Shrinking input buffer\n");
1358
1359     if (!forcedFree && usedLength)
1360         XMEMCPY(ssl->buffers.inputBuffer.staticBuffer,
1361                ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
1362                usedLength);
1363
1364     XFREE(ssl->buffers.inputBuffer.buffer, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
1365     ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
1366     ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
1367     ssl->buffers.inputBuffer.dynamicFlag = 0;
1368     ssl->buffers.inputBuffer.idx = 0;
1369     ssl->buffers.inputBuffer.length = usedLength;
1370 }
1371
1372
1373 int SendBuffered(CYASSL* ssl)
1374 {
1375     while (ssl->buffers.outputBuffer.length > 0) {
1376         int sent = ssl->ctx->CBIOSend((char*)ssl->buffers.outputBuffer.buffer +
1377                                       ssl->buffers.outputBuffer.idx,
1378                                       (int)ssl->buffers.outputBuffer.length,
1379                                       ssl->IOCB_WriteCtx);
1380         if (sent < 0) {
1381             switch (sent) {
1382
1383                 case IO_ERR_WANT_WRITE:        /* would block */
1384                     return WANT_WRITE;
1385
1386                 case IO_ERR_CONN_RST:          /* connection reset */
1387                     ssl->options.connReset = 1;
1388                     break;
1389
1390                 case IO_ERR_ISR:               /* interrupt */
1391                     /* see if we got our timeout */
1392                     #ifdef CYASSL_CALLBACKS
1393                         if (ssl->toInfoOn) {
1394                             struct itimerval timeout;
1395                             getitimer(ITIMER_REAL, &timeout);
1396                             if (timeout.it_value.tv_sec == 0 && 
1397                                                 timeout.it_value.tv_usec == 0) {
1398                                 XSTRNCPY(ssl->timeoutInfo.timeoutName,
1399                                         "send() timeout", MAX_TIMEOUT_NAME_SZ);
1400                                 CYASSL_MSG("Got our timeout"); 
1401                                 return WANT_WRITE;
1402                             }
1403                         }
1404                     #endif
1405                     continue;
1406
1407                 case IO_ERR_CONN_CLOSE: /* epipe / conn closed, same as reset */
1408                     ssl->options.connReset = 1;
1409                     break;
1410
1411                 default:
1412                     return SOCKET_ERROR_E;
1413             }
1414
1415             return SOCKET_ERROR_E;
1416         }
1417
1418         ssl->buffers.outputBuffer.idx += sent;
1419         ssl->buffers.outputBuffer.length -= sent;
1420     }
1421       
1422     ssl->buffers.outputBuffer.idx = 0;
1423
1424     if (ssl->buffers.outputBuffer.dynamicFlag)
1425         ShrinkOutputBuffer(ssl);
1426
1427     return 0;
1428 }
1429
1430
1431 /* Grow the output buffer */
1432 static INLINE int GrowOutputBuffer(CYASSL* ssl, int size)
1433 {
1434     byte* tmp = (byte*) XMALLOC(size + ssl->buffers.outputBuffer.length,
1435                                 ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
1436     CYASSL_MSG("growing output buffer\n");
1437    
1438     if (!tmp) return MEMORY_E;
1439
1440     if (ssl->buffers.outputBuffer.length)
1441         XMEMCPY(tmp, ssl->buffers.outputBuffer.buffer,
1442                ssl->buffers.outputBuffer.length);
1443
1444     if (ssl->buffers.outputBuffer.dynamicFlag)
1445         XFREE(ssl->buffers.outputBuffer.buffer, ssl->heap,
1446               DYNAMIC_TYPE_OUT_BUFFER);
1447     ssl->buffers.outputBuffer.dynamicFlag = 1;
1448     ssl->buffers.outputBuffer.buffer = tmp;
1449     ssl->buffers.outputBuffer.bufferSize = size +
1450                                            ssl->buffers.outputBuffer.length; 
1451     return 0;
1452 }
1453
1454
1455 /* Grow the input buffer, should only be to read cert or big app data */
1456 static INLINE int GrowInputBuffer(CYASSL* ssl, int size, int usedLength)
1457 {
1458     byte* tmp = (byte*) XMALLOC(size + usedLength, ssl->heap,
1459                                 DYNAMIC_TYPE_IN_BUFFER);
1460     CYASSL_MSG("growing input buffer\n");
1461    
1462     if (!tmp) return MEMORY_E;
1463
1464     if (usedLength)
1465         XMEMCPY(tmp, ssl->buffers.inputBuffer.buffer +
1466                     ssl->buffers.inputBuffer.idx, usedLength);
1467
1468     if (ssl->buffers.inputBuffer.dynamicFlag)
1469         XFREE(ssl->buffers.inputBuffer.buffer,ssl->heap,DYNAMIC_TYPE_IN_BUFFER);
1470
1471     ssl->buffers.inputBuffer.dynamicFlag = 1;
1472     ssl->buffers.inputBuffer.buffer = tmp;
1473     ssl->buffers.inputBuffer.bufferSize = size + usedLength;
1474     ssl->buffers.inputBuffer.idx    = 0;
1475     ssl->buffers.inputBuffer.length = usedLength;
1476
1477     return 0;
1478 }
1479
1480
1481 /* check avalaible size into output buffer, make room if needed */
1482 static INLINE int CheckAvalaibleSize(CYASSL *ssl, int size)
1483 {
1484     if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length
1485                                              < (word32)size) {
1486         if (GrowOutputBuffer(ssl, size) < 0)
1487             return MEMORY_E;
1488     }
1489
1490     return 0;
1491 }
1492
1493 /* do all verify and sanity checks on record header */
1494 static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
1495                            RecordLayerHeader* rh, word16 *size)
1496 {
1497     if (!ssl->options.dtls) {
1498         XMEMCPY(rh, input + *inOutIdx, RECORD_HEADER_SZ);
1499         *inOutIdx += RECORD_HEADER_SZ;
1500         ato16(rh->length, size);
1501     }
1502     else {
1503 #ifdef CYASSL_DTLS
1504         /* type and version in same sport */
1505         XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
1506         *inOutIdx += ENUM_LEN + VERSION_SZ;
1507         *inOutIdx += 4;  /* skip epoch and first 2 seq bytes for now */
1508         ato32(input + *inOutIdx, &ssl->keys.dtls_peer_sequence_number);
1509         *inOutIdx += 4;  /* advance past rest of seq */
1510         ato16(input + *inOutIdx, size);
1511         *inOutIdx += LENGTH_SZ;
1512 #endif
1513     }
1514
1515     /* catch version mismatch */
1516     if (rh->version.major != ssl->version.major || 
1517         rh->version.minor != ssl->version.minor) {
1518         
1519         if (ssl->options.side == SERVER_END &&
1520             ssl->options.acceptState == ACCEPT_BEGIN)
1521             CYASSL_MSG("Client attempting to connect with different version"); 
1522         else if (ssl->options.side == CLIENT_END && ssl->options.downgrade &&
1523                  ssl->options.connectState < FIRST_REPLY_DONE)
1524             CYASSL_MSG("Server attempting to accept with different version"); 
1525         else {
1526             CYASSL_MSG("SSL version error"); 
1527             return VERSION_ERROR;              /* only use requested version */
1528         }
1529     }
1530
1531     /* record layer length check */
1532     if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
1533         return LENGTH_ERROR;
1534
1535     /* verify record type here as well */
1536     switch ((enum ContentType)rh->type) {
1537         case handshake:
1538         case change_cipher_spec:
1539         case application_data:
1540         case alert:
1541             break;
1542         case no_type:
1543         default:
1544             CYASSL_MSG("Unknown Record Type"); 
1545             return UNKNOWN_RECORD_TYPE;
1546     }
1547
1548     return 0;
1549 }
1550
1551
1552 static int GetHandShakeHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
1553                               byte *type, word32 *size)
1554 {
1555     const byte *ptr = input + *inOutIdx;
1556     (void)ssl;
1557     *inOutIdx += HANDSHAKE_HEADER_SZ;
1558     
1559 #ifdef CYASSL_DTLS
1560     if (ssl->options.dtls)
1561         *inOutIdx += DTLS_HANDSHAKE_EXTRA;
1562 #endif
1563
1564     *type = ptr[0];
1565     c24to32(&ptr[1], size);
1566
1567     return 0;
1568 }
1569
1570
1571 /* fill with MD5 pad size since biggest required */
1572 static const byte PAD1[PAD_MD5] = 
1573                               { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1574                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1575                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1576                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1577                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1578                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
1579                               };
1580 static const byte PAD2[PAD_MD5] =
1581                               { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1582                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1583                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1584                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1585                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1586                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
1587                               };
1588
1589 /* calculate MD5 hash for finished */
1590 static void BuildMD5(CYASSL* ssl, Hashes* hashes, const byte* sender)
1591 {
1592     byte md5_result[MD5_DIGEST_SIZE];
1593
1594     /* make md5 inner */    
1595     Md5Update(&ssl->hashMd5, sender, SIZEOF_SENDER);
1596     Md5Update(&ssl->hashMd5, ssl->arrays.masterSecret, SECRET_LEN);
1597     Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
1598     Md5Final(&ssl->hashMd5, md5_result);
1599
1600     /* make md5 outer */
1601     Md5Update(&ssl->hashMd5, ssl->arrays.masterSecret, SECRET_LEN);
1602     Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
1603     Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
1604
1605     Md5Final(&ssl->hashMd5, hashes->md5);
1606 }
1607
1608
1609 /* calculate SHA hash for finished */
1610 static void BuildSHA(CYASSL* ssl, Hashes* hashes, const byte* sender)
1611 {
1612     byte sha_result[SHA_DIGEST_SIZE];
1613
1614     /* make sha inner */
1615     ShaUpdate(&ssl->hashSha, sender, SIZEOF_SENDER);
1616     ShaUpdate(&ssl->hashSha, ssl->arrays.masterSecret, SECRET_LEN);
1617     ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
1618     ShaFinal(&ssl->hashSha, sha_result);
1619
1620     /* make sha outer */
1621     ShaUpdate(&ssl->hashSha, ssl->arrays.masterSecret, SECRET_LEN);
1622     ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
1623     ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
1624
1625     ShaFinal(&ssl->hashSha, hashes->sha);
1626 }
1627
1628
1629 static void BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
1630 {
1631     /* store current states, building requires get_digest which resets state */
1632     Md5 md5 = ssl->hashMd5;
1633     Sha sha = ssl->hashSha;
1634 #ifndef NO_SHA256
1635     Sha256 sha256;
1636 #endif
1637 #ifdef CYASSL_SHA384
1638     Sha384 sha384;
1639 #endif
1640
1641 #ifndef NO_SHA256
1642     InitSha256(&sha256);
1643     if (IsAtLeastTLSv1_2(ssl))
1644         sha256 = ssl->hashSha256;
1645 #endif
1646 #ifdef CYASSL_SHA384
1647     InitSha384(&sha384);
1648     if (IsAtLeastTLSv1_2(ssl))
1649         sha384 = ssl->hashSha384;
1650 #endif
1651
1652     if (ssl->options.tls)
1653         BuildTlsFinished(ssl, hashes, sender);
1654     else {
1655         BuildMD5(ssl, hashes, sender);
1656         BuildSHA(ssl, hashes, sender);
1657     }
1658     
1659     /* restore */
1660     ssl->hashMd5 = md5;
1661     ssl->hashSha = sha;
1662     if (IsAtLeastTLSv1_2(ssl)) {
1663 #ifndef NO_SHA256
1664         ssl->hashSha256 = sha256;
1665 #endif
1666 #ifdef CYASSL_SHA384
1667         ssl->hashSha384 = sha384;
1668 #endif
1669     }
1670 }
1671
1672
1673 static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
1674 {
1675     word32 listSz, i = *inOutIdx;
1676     int    ret = 0;
1677     int    anyError = 0;
1678     int    totalCerts = 0;    /* number of certs in certs buffer */
1679     int    count;
1680     char   domain[ASN_NAME_MAX];
1681     buffer certs[MAX_CHAIN_DEPTH];
1682
1683     #ifdef CYASSL_CALLBACKS
1684         if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
1685         if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo);
1686     #endif
1687     c24to32(&input[i], &listSz);
1688     i += CERT_HEADER_SZ;
1689
1690     CYASSL_MSG("Loading peer's cert chain");
1691     /* first put cert chain into buffer so can verify top down
1692        we're sent bottom up */
1693     while (listSz) {
1694         /* cert size */
1695         word32 certSz;
1696
1697         if (totalCerts >= MAX_CHAIN_DEPTH)
1698             return MAX_CHAIN_ERROR;
1699
1700         c24to32(&input[i], &certSz);
1701         i += CERT_HEADER_SZ;
1702        
1703         if (listSz > MAX_RECORD_SIZE || certSz > MAX_RECORD_SIZE)
1704             return BUFFER_E;
1705
1706         certs[totalCerts].length = certSz;
1707         certs[totalCerts].buffer = input + i;
1708
1709 #ifdef SESSION_CERTS
1710         if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
1711                                        certSz < MAX_X509_SIZE) {
1712             ssl->session.chain.certs[ssl->session.chain.count].length = certSz;
1713             XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer,
1714                     input + i, certSz);
1715             ssl->session.chain.count++;
1716         } else {
1717             CYASSL_MSG("Couldn't store chain cert for session");
1718         }
1719 #endif
1720
1721         i += certSz;
1722         listSz -= certSz + CERT_HEADER_SZ;
1723
1724         totalCerts++;
1725         CYASSL_MSG("    Put another cert into chain");
1726     }
1727
1728     count = totalCerts;
1729
1730     /* verify up to peer's first */
1731     while (count > 1) {
1732         buffer myCert = certs[count - 1];
1733         DecodedCert dCert;
1734
1735         InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
1736         ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
1737                                 ssl->ctx->cm);
1738         if (ret == 0 && dCert.isCA == 0) {
1739             CYASSL_MSG("Chain cert is not a CA, not adding as one");
1740         }
1741         else if (ret == 0 && ssl->options.verifyNone) {
1742             CYASSL_MSG("Chain cert not verified by option, not adding as CA");
1743         }
1744         else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, dCert.subjectHash)) {
1745             buffer add;
1746             add.length = myCert.length;
1747             add.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
1748                                         DYNAMIC_TYPE_CA);
1749             CYASSL_MSG("Adding CA from chain");
1750
1751             if (add.buffer == NULL)
1752                 return MEMORY_E;
1753             XMEMCPY(add.buffer, myCert.buffer, myCert.length);
1754
1755             ret = AddCA(ssl->ctx->cm, add, CYASSL_CHAIN_CA,
1756                         ssl->ctx->verifyPeer);
1757             if (ret == 1) ret = 0;   /* SSL_SUCCESS for external */
1758         }
1759         else if (ret != 0) {
1760             CYASSL_MSG("Failed to verify CA from chain");
1761         }
1762         else {
1763             CYASSL_MSG("Verified CA from chain and already had it");
1764         }
1765
1766 #ifdef HAVE_CRL
1767         if (ret == 0 && ssl->ctx->cm->crlEnabled && ssl->ctx->cm->crlCheckAll) {
1768             CYASSL_MSG("Doing Non Leaf CRL check");
1769             ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert);
1770
1771             if (ret != 0) {
1772                 CYASSL_MSG("\tCRL check not ok");
1773             }
1774         }
1775 #endif /* HAVE_CRL */
1776
1777         if (ret != 0 && anyError == 0)
1778             anyError = ret;   /* save error from last time */
1779
1780         FreeDecodedCert(&dCert);
1781         count--;
1782     }
1783
1784     /* peer's, may not have one if blank client cert sent by TLSv1.2 */
1785     if (count) {
1786         buffer myCert = certs[0];
1787         DecodedCert dCert;
1788         int         fatal = 0;
1789
1790         CYASSL_MSG("Veriying Peer's cert");
1791
1792         InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
1793         ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
1794                                 ssl->ctx->cm);
1795         if (ret == 0) {
1796             CYASSL_MSG("Verified Peer's cert");
1797             fatal = 0;
1798         }
1799         else if (ret == ASN_PARSE_E) {
1800             CYASSL_MSG("Got Peer cert ASN PARSE ERROR, fatal");
1801             fatal = 1;
1802         }
1803         else {
1804             CYASSL_MSG("Failed to verify Peer's cert");
1805             if (ssl->verifyCallback) {
1806                 CYASSL_MSG("\tCallback override availalbe, will continue");
1807                 fatal = 0;
1808             }
1809             else {
1810                 CYASSL_MSG("\tNo callback override availalbe, fatal");
1811                 fatal = 1;
1812             }
1813         }
1814
1815 #ifdef HAVE_OCSP
1816         ret = CyaSSL_OCSP_Lookup_Cert(&ssl->ctx->ocsp, &dCert);
1817         if (ret != 0) {
1818             CYASSL_MSG("\tOCSP Lookup not ok");
1819             fatal = 0;
1820         }
1821 #endif
1822
1823 #ifdef HAVE_CRL
1824         if (fatal == 0 && ssl->ctx->cm->crlEnabled) {
1825             CYASSL_MSG("Doing Leaf CRL check");
1826             ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert);
1827
1828             if (ret != 0) {
1829                 CYASSL_MSG("\tCRL check not ok");
1830                 fatal = 0;
1831             }
1832         }
1833 #endif /* HAVE_CRL */
1834
1835 #ifdef OPENSSL_EXTRA
1836         /* set X509 format for peer cert even if fatal */
1837         XSTRNCPY(ssl->peerCert.issuer.name, dCert.issuer, ASN_NAME_MAX);
1838         ssl->peerCert.issuer.name[ASN_NAME_MAX - 1] = '\0';
1839         ssl->peerCert.issuer.sz = (int)XSTRLEN(ssl->peerCert.issuer.name) + 1;
1840
1841         XSTRNCPY(ssl->peerCert.subject.name, dCert.subject, ASN_NAME_MAX);
1842         ssl->peerCert.subject.name[ASN_NAME_MAX - 1] = '\0';
1843         ssl->peerCert.subject.sz = (int)XSTRLEN(ssl->peerCert.subject.name) + 1;
1844
1845         XMEMCPY(ssl->peerCert.serial, dCert.serial, EXTERNAL_SERIAL_SIZE);
1846         ssl->peerCert.serialSz = dCert.serialSz;
1847         if (dCert.subjectCNLen < ASN_NAME_MAX) {
1848             XMEMCPY(ssl->peerCert.subjectCN,dCert.subjectCN,dCert.subjectCNLen);
1849             ssl->peerCert.subjectCN[dCert.subjectCNLen] = '\0';
1850         }
1851         else
1852             ssl->peerCert.subjectCN[0] = '\0';
1853
1854         /* store cert for potential retrieval */
1855         ssl->peerCert.derCert.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
1856                                                       DYNAMIC_TYPE_CERT);
1857         if (ssl->peerCert.derCert.buffer == NULL) {
1858             ret   = MEMORY_E;
1859             fatal = 1;
1860         }
1861         else {
1862             XMEMCPY(ssl->peerCert.derCert.buffer, myCert.buffer, myCert.length);
1863             ssl->peerCert.derCert.length = myCert.length;
1864         }
1865
1866         ssl->peerCert.altNames = dCert.altNames;
1867         dCert.altNames = NULL;     /* takes ownership */
1868         ssl->peerCert.altNamesNext = ssl->peerCert.altNames;  /* index hint */
1869 #endif    
1870
1871         if (fatal) {
1872             FreeDecodedCert(&dCert);
1873             ssl->error = ret;
1874             return ret;
1875         }
1876         ssl->options.havePeerCert = 1;
1877
1878         /* store for callback use */
1879         if (dCert.subjectCNLen < ASN_NAME_MAX) {
1880             XMEMCPY(domain, dCert.subjectCN, dCert.subjectCNLen);
1881             domain[dCert.subjectCNLen] = '\0';
1882         }
1883         else
1884             domain[0] = '\0';
1885
1886         if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer)
1887             if (XSTRNCMP((char*)ssl->buffers.domainName.buffer,
1888                         dCert.subjectCN,
1889                         ssl->buffers.domainName.length - 1)) {
1890                 ret = DOMAIN_NAME_MISMATCH;   /* try to get peer key still */
1891             }
1892
1893         /* decode peer key */
1894         if (dCert.keyOID == RSAk) {
1895             word32 idx = 0;
1896             if (RsaPublicKeyDecode(dCert.publicKey, &idx,
1897                                &ssl->peerRsaKey, dCert.pubKeySize) != 0) {
1898                 ret = PEER_KEY_ERROR;
1899             }
1900             else
1901                 ssl->peerRsaKeyPresent = 1;
1902         }
1903 #ifdef HAVE_NTRU
1904         else if (dCert.keyOID == NTRUk) {
1905             if (dCert.pubKeySize > sizeof(ssl->peerNtruKey)) {
1906                 ret = PEER_KEY_ERROR;
1907             }
1908             else {
1909                 XMEMCPY(ssl->peerNtruKey, dCert.publicKey, dCert.pubKeySize);
1910                 ssl->peerNtruKeyLen = (word16)dCert.pubKeySize;
1911                 ssl->peerNtruKeyPresent = 1;
1912             }
1913         }
1914 #endif /* HAVE_NTRU */
1915 #ifdef HAVE_ECC
1916         else if (dCert.keyOID == ECDSAk) {
1917             if (ecc_import_x963(dCert.publicKey, dCert.pubKeySize,
1918                                 &ssl->peerEccDsaKey) != 0) {
1919                 ret = PEER_KEY_ERROR;
1920             }
1921             else
1922                 ssl->peerEccDsaKeyPresent = 1;
1923         }
1924 #endif /* HAVE_ECC */
1925
1926         FreeDecodedCert(&dCert);
1927     }
1928     
1929     if (anyError != 0 && ret == 0)
1930         ret = anyError;
1931
1932     if (ret == 0 && ssl->options.side == CLIENT_END)
1933         ssl->options.serverState = SERVER_CERT_COMPLETE;
1934
1935     if (ret != 0) {
1936         if (!ssl->options.verifyNone) {
1937             int why = bad_certificate;
1938             if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E)
1939                 why = certificate_expired;
1940             if (ssl->verifyCallback) {
1941                 int            ok;
1942                 CYASSL_X509_STORE_CTX store;
1943
1944                 store.error = ret;
1945                 store.error_depth = totalCerts;
1946                 store.domain = domain;
1947 #ifdef OPENSSL_EXTRA
1948                 store.current_cert = &ssl->peerCert;
1949 #else
1950                 store.current_cert = NULL;
1951 #endif
1952 #ifdef FORTRESS
1953                 store.ex_data = ssl;
1954 #endif
1955                 ok = ssl->verifyCallback(0, &store);
1956                 if (ok) {
1957                     CYASSL_MSG("Verify callback overriding error!"); 
1958                     ret = 0;
1959                 }
1960             }
1961             if (ret != 0) {
1962                 SendAlert(ssl, alert_fatal, why);   /* try to send */
1963                 ssl->options.isClosed = 1;
1964             }
1965         }
1966         ssl->error = ret;
1967     }
1968 #ifdef FORTRESS
1969     else {
1970         if (ssl->verifyCallback) {
1971             int ok;
1972             CYASSL_X509_STORE_CTX store;
1973
1974             store.error = ret;
1975             store.error_depth = totalCerts;
1976             store.domain = domain;
1977             store.current_cert = &ssl->peerCert;
1978             store.ex_data = ssl;
1979
1980             ok = ssl->verifyCallback(1, &store);
1981             if (!ok) {
1982                 CYASSL_MSG("Verify callback overriding valid certificate!");
1983                 ret = -1;
1984                 SendAlert(ssl, alert_fatal, bad_certificate);
1985                 ssl->options.isClosed = 1;
1986             }
1987         }
1988     }
1989 #endif
1990
1991     *inOutIdx = i;
1992     return ret;
1993 }
1994
1995
1996 static int DoHelloRequest(CYASSL* ssl, const byte* input, word32* inOutIdx)
1997 {
1998     if (ssl->keys.encryptionOn) {
1999         const byte* mac;
2000         int         padSz = ssl->keys.encryptSz - HANDSHAKE_HEADER_SZ - 
2001                             ssl->specs.hash_size;
2002         byte        verify[SHA256_DIGEST_SIZE];
2003        
2004         ssl->hmac(ssl, verify, input + *inOutIdx - HANDSHAKE_HEADER_SZ,
2005                   HANDSHAKE_HEADER_SZ, handshake, 1);
2006         /* read mac and fill */
2007         mac = input + *inOutIdx;
2008         *inOutIdx += ssl->specs.hash_size;
2009
2010         if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
2011             padSz -= ssl->specs.block_size;
2012
2013         *inOutIdx += padSz;
2014
2015         /* verify */
2016         if (XMEMCMP(mac, verify, ssl->specs.hash_size)) {
2017             CYASSL_MSG("    hello_request verify mac error");
2018             return VERIFY_MAC_ERROR;
2019         }
2020     }
2021
2022     return SendAlert(ssl, alert_warning, no_renegotiation);
2023 }
2024
2025
2026 int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, int sniff)
2027 {
2028     byte   verifyMAC[SHA256_DIGEST_SIZE];
2029     int    finishedSz = ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ;
2030     int    headerSz = HANDSHAKE_HEADER_SZ;
2031     word32 macSz = finishedSz + HANDSHAKE_HEADER_SZ,
2032            idx = *inOutIdx,
2033            padSz = ssl->keys.encryptSz - HANDSHAKE_HEADER_SZ - finishedSz -
2034                    ssl->specs.hash_size;
2035     const byte* mac;
2036
2037     #ifdef CYASSL_DTLS
2038         if (ssl->options.dtls) {
2039             headerSz += DTLS_HANDSHAKE_EXTRA;
2040             macSz    += DTLS_HANDSHAKE_EXTRA;
2041             padSz    -= DTLS_HANDSHAKE_EXTRA;
2042         }
2043     #endif
2044
2045     #ifdef CYASSL_CALLBACKS
2046         if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
2047         if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
2048     #endif
2049     if (sniff == NO_SNIFF) {
2050         if (XMEMCMP(input + idx, &ssl->verifyHashes, finishedSz)) {
2051             CYASSL_MSG("Verify finished error on hashes");
2052             return VERIFY_FINISHED_ERROR;
2053         }
2054     }
2055
2056     if (ssl->specs.cipher_type != aead) {
2057         ssl->hmac(ssl, verifyMAC, input + idx - headerSz, macSz,
2058              handshake, 1);
2059         idx += finishedSz;
2060
2061         /* read mac and fill */
2062         mac = input + idx;
2063         idx += ssl->specs.hash_size;
2064
2065         if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
2066             padSz -= ssl->specs.block_size;
2067
2068         idx += padSz;
2069
2070         /* verify mac */
2071         if (XMEMCMP(mac, verifyMAC, ssl->specs.hash_size)) {
2072             CYASSL_MSG("Verify finished error on mac");
2073             return VERIFY_MAC_ERROR;
2074         }
2075     }
2076     else {
2077         idx += (finishedSz + AEAD_AUTH_TAG_SZ);
2078     }
2079
2080     if (ssl->options.side == CLIENT_END) {
2081         ssl->options.serverState = SERVER_FINISHED_COMPLETE;
2082         if (!ssl->options.resuming)
2083             ssl->options.handShakeState = HANDSHAKE_DONE;
2084     }
2085     else {
2086         ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
2087         if (ssl->options.resuming)
2088             ssl->options.handShakeState = HANDSHAKE_DONE;
2089     }
2090
2091     *inOutIdx = idx;
2092     return 0;
2093 }
2094
2095
2096 static int DoHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
2097                           word32 totalSz)
2098 {
2099     byte type;
2100     word32 size;
2101     int ret = 0;
2102
2103     CYASSL_ENTER("DoHandShakeMsg()");
2104
2105     if (GetHandShakeHeader(ssl, input, inOutIdx, &type, &size) != 0)
2106         return PARSE_ERROR;
2107
2108     if (*inOutIdx + size > totalSz)
2109         return INCOMPLETE_DATA;
2110     
2111     HashInput(ssl, input + *inOutIdx, size);
2112 #ifdef CYASSL_CALLBACKS
2113     /* add name later, add on record and handshake header part back on */
2114     if (ssl->toInfoOn) {
2115         int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
2116         AddPacketInfo(0, &ssl->timeoutInfo, input + *inOutIdx - add,
2117                       size + add, ssl->heap);
2118         AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
2119     }
2120 #endif
2121
2122     switch (type) {
2123
2124     case hello_request:
2125         CYASSL_MSG("processing hello request");
2126         ret = DoHelloRequest(ssl, input, inOutIdx);
2127         break;
2128
2129 #ifndef NO_CYASSL_CLIENT
2130     case hello_verify_request:
2131         CYASSL_MSG("processing hello verify request");
2132         ret = DoHelloVerifyRequest(ssl, input,inOutIdx);
2133         break;
2134             
2135     case server_hello:
2136         CYASSL_MSG("processing server hello");
2137         ret = DoServerHello(ssl, input, inOutIdx, size);
2138         break;
2139
2140     case certificate_request:
2141         CYASSL_MSG("processing certificate request");
2142         ret = DoCertificateRequest(ssl, input, inOutIdx);
2143         break;
2144
2145     case server_key_exchange:
2146         CYASSL_MSG("processing server key exchange");
2147         ret = DoServerKeyExchange(ssl, input, inOutIdx);
2148         break;
2149 #endif
2150
2151     case certificate:
2152         CYASSL_MSG("processing certificate");
2153         ret =  DoCertificate(ssl, input, inOutIdx);
2154         break;
2155
2156     case server_hello_done:
2157         CYASSL_MSG("processing server hello done");
2158         #ifdef CYASSL_CALLBACKS
2159             if (ssl->hsInfoOn) 
2160                 AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
2161             if (ssl->toInfoOn)
2162                 AddLateName("ServerHelloDone", &ssl->timeoutInfo);
2163         #endif
2164         ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
2165         break;
2166
2167     case finished:
2168         CYASSL_MSG("processing finished");
2169         ret = DoFinished(ssl, input, inOutIdx, NO_SNIFF);
2170         break;
2171
2172 #ifndef NO_CYASSL_SERVER
2173     case client_hello:
2174         CYASSL_MSG("processing client hello");
2175         ret = DoClientHello(ssl, input, inOutIdx, totalSz, size);
2176         break;
2177
2178     case client_key_exchange:
2179         CYASSL_MSG("processing client key exchange");
2180         ret = DoClientKeyExchange(ssl, input, inOutIdx);
2181         break;
2182
2183     case certificate_verify:
2184         CYASSL_MSG("processing certificate verify");
2185         ret = DoCertificateVerify(ssl, input, inOutIdx, totalSz);
2186         break;
2187
2188 #endif
2189
2190     default:
2191         CYASSL_MSG("Unknown handshake message type");
2192         ret = UNKNOWN_HANDSHAKE_TYPE;
2193     }
2194
2195     CYASSL_LEAVE("DoHandShakeMsg()", ret);
2196     return ret;
2197 }
2198
2199
2200 static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
2201 {
2202     if (verify)
2203         return ssl->keys.peer_sequence_number++; 
2204     else
2205         return ssl->keys.sequence_number++; 
2206 }
2207
2208
2209 static INLINE void Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz)
2210 {
2211     switch (ssl->specs.bulk_cipher_algorithm) {
2212         #ifdef BUILD_ARC4
2213             case rc4:
2214                 Arc4Process(&ssl->encrypt.arc4, out, input, sz);
2215                 break;
2216         #endif
2217
2218         #ifdef BUILD_DES3
2219             case triple_des:
2220                 Des3_CbcEncrypt(&ssl->encrypt.des3, out, input, sz);
2221                 break;
2222         #endif
2223
2224         #ifdef BUILD_AES
2225             case aes:
2226             #ifdef CYASSL_AESNI
2227                 if ((word)input % 16) {
2228                     byte buffer[MAX_RECORD_SIZE + MAX_COMP_EXTRA+MAX_MSG_EXTRA];
2229                     XMEMCPY(buffer, input, sz);
2230                     AesCbcEncrypt(&ssl->encrypt.aes, buffer, buffer, sz);
2231                     XMEMCPY(out, buffer, sz);
2232                     break;
2233                 }
2234             #endif
2235                 AesCbcEncrypt(&ssl->encrypt.aes, out, input, sz);
2236                 break;
2237         #endif
2238
2239         #ifdef BUILD_AESGCM
2240             case aes_gcm:
2241                 {
2242                     byte additional[AES_BLOCK_SIZE];
2243
2244                     XMEMSET(additional, 0, AES_BLOCK_SIZE);
2245
2246                     /* sequence number field is 64-bits, we only use 32-bits */
2247                     c32toa(GetSEQIncrement(ssl, 0),
2248                                             additional + AEAD_SEQ_OFFSET);
2249
2250                     /* Store the type, version. Unfortunately, they are in
2251                      * the input buffer ahead of the plaintext. */
2252                     XMEMCPY(additional + AEAD_TYPE_OFFSET, input - 5, 3);
2253
2254                     /* Store the length of the plain text minus the explicit
2255                      * IV length minus the authentication tag size. */
2256                     c16toa(sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
2257                                                 additional + AEAD_LEN_OFFSET);
2258                     AesGcmEncrypt(&ssl->encrypt.aes,
2259                         out + AES_GCM_EXP_IV_SZ, input + AES_GCM_EXP_IV_SZ,
2260                             sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
2261                         out + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ,
2262                         additional, AEAD_AUTH_DATA_SZ);
2263                     AesGcmIncExpIV(&ssl->encrypt.aes);
2264                 }
2265                 break;
2266         #endif
2267
2268         #ifdef HAVE_HC128
2269             case hc128:
2270                 Hc128_Process(&ssl->encrypt.hc128, out, input, sz);
2271                 break;
2272         #endif
2273
2274         #ifdef BUILD_RABBIT
2275             case rabbit:
2276                 RabbitProcess(&ssl->encrypt.rabbit, out, input, sz);
2277                 break;
2278         #endif
2279
2280             default:
2281                 CYASSL_MSG("CyaSSL Encrypt programming error");
2282     }
2283 }
2284
2285
2286 static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input,
2287                            word32 sz)
2288 {
2289     switch (ssl->specs.bulk_cipher_algorithm) {
2290         #ifdef BUILD_ARC4
2291             case rc4:
2292                 Arc4Process(&ssl->decrypt.arc4, plain, input, sz);
2293                 break;
2294         #endif
2295
2296         #ifdef BUILD_DES3
2297             case triple_des:
2298                 Des3_CbcDecrypt(&ssl->decrypt.des3, plain, input, sz);
2299                 break;
2300         #endif
2301
2302         #ifdef BUILD_AES
2303             case aes:
2304                 AesCbcDecrypt(&ssl->decrypt.aes, plain, input, sz);
2305                 break;
2306         #endif
2307
2308         #ifdef BUILD_AESGCM
2309             case aes_gcm:
2310             {
2311                 byte additional[AES_BLOCK_SIZE];
2312
2313                 AesGcmSetExpIV(&ssl->decrypt.aes, input);
2314                 XMEMSET(additional, 0, AES_BLOCK_SIZE);
2315
2316                 /* sequence number field is 64-bits, we only use 32-bits */
2317                 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
2318                 
2319                 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
2320                 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.version.major;
2321                 additional[AEAD_VMIN_OFFSET] = ssl->curRL.version.minor;
2322
2323                 c16toa(sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
2324                                         additional + AEAD_LEN_OFFSET);
2325                 if (AesGcmDecrypt(&ssl->decrypt.aes,
2326                             plain + AES_GCM_EXP_IV_SZ,
2327                             input + AES_GCM_EXP_IV_SZ,
2328                                 sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
2329                             input + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ,
2330                             additional, AEAD_AUTH_DATA_SZ) < 0) {
2331                     SendAlert(ssl, alert_fatal, bad_record_mac);
2332                     return VERIFY_MAC_ERROR;
2333                 }
2334                 break;
2335             }
2336         #endif
2337
2338         #ifdef HAVE_HC128
2339             case hc128:
2340                 Hc128_Process(&ssl->decrypt.hc128, plain, input, sz);
2341                 break;
2342         #endif
2343
2344         #ifdef BUILD_RABBIT
2345             case rabbit:
2346                 RabbitProcess(&ssl->decrypt.rabbit, plain, input, sz);
2347                 break;
2348         #endif
2349
2350             default:
2351                 CYASSL_MSG("CyaSSL Decrypt programming error");
2352     }
2353     return 0;
2354 }
2355
2356
2357 /* decrypt input message in place */
2358 static int DecryptMessage(CYASSL* ssl, byte* input, word32 sz, word32* idx)
2359 {
2360     int decryptResult = Decrypt(ssl, input, input, sz);
2361
2362     if (decryptResult == 0)
2363     {
2364         ssl->keys.encryptSz = sz;
2365         if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
2366             *idx += ssl->specs.block_size;  /* go past TLSv1.1 IV */
2367         if (ssl->specs.cipher_type == aead)
2368             *idx += AES_GCM_EXP_IV_SZ;
2369     }
2370
2371     return decryptResult;
2372 }
2373
2374
2375 int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx)
2376 {
2377     word32 msgSz   = ssl->keys.encryptSz;
2378     word32 pad     = 0, 
2379            padByte = 0,
2380            idx     = *inOutIdx,
2381            digestSz = ssl->specs.hash_size;
2382     int    dataSz;
2383     int    ivExtra = 0;
2384     byte*  rawData = input + idx;  /* keep current  for hmac */
2385 #ifdef HAVE_LIBZ
2386     byte   decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
2387 #endif
2388
2389     byte        verify[SHA256_DIGEST_SIZE];
2390     const byte* mac;
2391
2392     if (ssl->specs.cipher_type == block) {
2393         if (ssl->options.tls1_1)
2394             ivExtra = ssl->specs.block_size;
2395         pad = *(input + idx + msgSz - ivExtra - 1);
2396         padByte = 1;
2397     }
2398     if (ssl->specs.cipher_type == aead) {
2399         ivExtra = AES_GCM_EXP_IV_SZ;
2400         digestSz = AEAD_AUTH_TAG_SZ;
2401     }
2402
2403     dataSz = msgSz - ivExtra - digestSz - pad - padByte;
2404     if (dataSz < 0) {
2405         CYASSL_MSG("App data buffer error, malicious input?"); 
2406         return BUFFER_ERROR;
2407     }
2408
2409     /* read data */
2410     if (dataSz) {
2411         int    rawSz   = dataSz;       /* keep raw size for hmac */
2412
2413         if (ssl->specs.cipher_type != aead)
2414             ssl->hmac(ssl, verify, rawData, rawSz, application_data, 1);
2415
2416 #ifdef HAVE_LIBZ
2417         if (ssl->options.usingCompression) {
2418             dataSz = DeCompress(ssl, rawData, dataSz, decomp, sizeof(decomp));
2419             if (dataSz < 0) return dataSz;
2420         }
2421 #endif
2422
2423         if (ssl->options.usingCompression)
2424             idx += rawSz;
2425         else
2426             idx += dataSz;
2427
2428         ssl->buffers.clearOutputBuffer.buffer = rawData;
2429         ssl->buffers.clearOutputBuffer.length = dataSz;
2430     }
2431
2432     /* read mac and fill */
2433     mac = input + idx;
2434     idx += digestSz;
2435    
2436     idx += pad;
2437     if (padByte)
2438         idx++;
2439
2440     /* verify */
2441     if (dataSz) {
2442         if (ssl->specs.cipher_type != aead && XMEMCMP(mac, verify, digestSz)) {
2443             CYASSL_MSG("App data verify mac error"); 
2444             return VERIFY_MAC_ERROR;
2445         }
2446     }
2447     else 
2448         GetSEQIncrement(ssl, 1);  /* even though no data, increment verify */
2449
2450 #ifdef HAVE_LIBZ
2451     /* decompress could be bigger, overwrite after verify */
2452     if (ssl->options.usingCompression)
2453         XMEMMOVE(rawData, decomp, dataSz);
2454 #endif
2455
2456     *inOutIdx = idx;
2457     return 0;
2458 }
2459
2460
2461 /* process alert, return level */
2462 static int DoAlert(CYASSL* ssl, byte* input, word32* inOutIdx, int* type)
2463 {
2464     byte level;
2465
2466     #ifdef CYASSL_CALLBACKS
2467         if (ssl->hsInfoOn)
2468             AddPacketName("Alert", &ssl->handShakeInfo);
2469         if (ssl->toInfoOn)
2470             /* add record header back on to info + 2 byte level, data */
2471             AddPacketInfo("Alert", &ssl->timeoutInfo, input + *inOutIdx -
2472                           RECORD_HEADER_SZ, 2 + RECORD_HEADER_SZ, ssl->heap);
2473     #endif
2474     level = input[(*inOutIdx)++];
2475     *type  = (int)input[(*inOutIdx)++];
2476
2477     CYASSL_MSG("Got alert");
2478     if (*type == close_notify) {
2479         CYASSL_MSG("    close notify");
2480         ssl->options.closeNotify = 1;
2481     }
2482     CYASSL_ERROR(*type);
2483
2484     if (ssl->keys.encryptionOn) {
2485         if (ssl->specs.cipher_type != aead) {
2486             int     aSz = ALERT_SIZE;
2487             const byte* mac;
2488             byte    verify[SHA256_DIGEST_SIZE];
2489             int     padSz = ssl->keys.encryptSz - aSz - ssl->specs.hash_size;
2490
2491             ssl->hmac(ssl, verify, input + *inOutIdx - aSz, aSz, alert, 1);
2492     
2493             /* read mac and fill */
2494             mac = input + *inOutIdx;
2495             *inOutIdx += (ssl->specs.hash_size + padSz);
2496     
2497             /* verify */
2498             if (XMEMCMP(mac, verify, ssl->specs.hash_size)) {
2499                 CYASSL_MSG("    alert verify mac error");
2500                 return VERIFY_MAC_ERROR;
2501             }
2502         }
2503         else {
2504             *inOutIdx += AEAD_AUTH_TAG_SZ;
2505         }
2506     }
2507
2508     return level;
2509 }
2510
2511 static int GetInputData(CYASSL *ssl, word32 size)
2512 {
2513     int in;
2514     int inSz;
2515     int maxLength;
2516     int usedLength;
2517
2518     
2519     /* check max input length */
2520     usedLength = ssl->buffers.inputBuffer.length - ssl->buffers.inputBuffer.idx;
2521     maxLength  = ssl->buffers.inputBuffer.bufferSize - usedLength;
2522     inSz       = (int)(size - usedLength);      /* from last partial read */
2523
2524 #ifdef CYASSL_DTLS
2525     if (ssl->options.dtls)
2526         inSz = MAX_MTU;       /* read ahead up to MTU */
2527 #endif
2528     
2529     if (inSz > maxLength) {
2530         if (GrowInputBuffer(ssl, size, usedLength) < 0)
2531             return MEMORY_E;
2532     }
2533            
2534     if (inSz <= 0)
2535         return BUFFER_ERROR;
2536     
2537     /* Put buffer data at start if not there */
2538     if (usedLength > 0 && ssl->buffers.inputBuffer.idx != 0)
2539         XMEMMOVE(ssl->buffers.inputBuffer.buffer,
2540                 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
2541                 usedLength);
2542     
2543     /* remove processed data */
2544     ssl->buffers.inputBuffer.idx    = 0;
2545     ssl->buffers.inputBuffer.length = usedLength;
2546   
2547     /* read data from network */
2548     do {
2549         in = Receive(ssl, 
2550                      ssl->buffers.inputBuffer.buffer +
2551                      ssl->buffers.inputBuffer.length, 
2552                      inSz);
2553         if (in == -1)
2554             return SOCKET_ERROR_E;
2555    
2556         if (in == WANT_READ)
2557             return WANT_READ;
2558         
2559         ssl->buffers.inputBuffer.length += in;
2560         inSz -= in;
2561
2562     } while (ssl->buffers.inputBuffer.length < size);
2563
2564     return 0;
2565 }
2566
2567 /* process input requests, return 0 is done, 1 is call again to complete, and
2568    negative number is error */
2569 int ProcessReply(CYASSL* ssl)
2570 {
2571     int    ret, type, readSz;
2572     word32 startIdx = 0;
2573 #ifndef NO_CYASSL_SERVER
2574     byte   b0, b1;
2575 #endif
2576 #ifdef CYASSL_DTLS
2577     int    used;
2578 #endif
2579
2580     for (;;) {
2581         switch ((processReply)ssl->options.processReply) {
2582
2583         /* in the CYASSL_SERVER case, get the first byte for detecting 
2584          * old client hello */
2585         case doProcessInit:
2586             
2587             readSz = RECORD_HEADER_SZ;
2588             
2589             #ifdef CYASSL_DTLS
2590                 if (ssl->options.dtls)
2591                     readSz = DTLS_RECORD_HEADER_SZ;
2592             #endif
2593
2594             /* get header or return error */
2595             if (!ssl->options.dtls) {
2596                 if ((ret = GetInputData(ssl, readSz)) < 0)
2597                     return ret;
2598             } else {
2599             #ifdef CYASSL_DTLS
2600                 /* read ahead may already have header */
2601                 used = ssl->buffers.inputBuffer.length -
2602                        ssl->buffers.inputBuffer.idx;
2603                 if (used < readSz)
2604                     if ((ret = GetInputData(ssl, readSz)) < 0)
2605                         return ret;
2606             #endif
2607             }
2608
2609 #ifndef NO_CYASSL_SERVER
2610
2611             /* see if sending SSLv2 client hello */
2612             if ( ssl->options.side == SERVER_END &&
2613                  ssl->options.clientState == NULL_STATE &&
2614                  ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx]
2615                          != handshake) {
2616                 ssl->options.processReply = runProcessOldClientHello;
2617
2618                 /* how many bytes need ProcessOldClientHello */
2619                 b0 =
2620                 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
2621                 b1 =
2622                 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
2623                 ssl->curSize = ((b0 & 0x7f) << 8) | b1;
2624             }
2625             else {
2626                 ssl->options.processReply = getRecordLayerHeader;
2627                 continue;
2628             }
2629
2630         /* in the CYASSL_SERVER case, run the old client hello */
2631         case runProcessOldClientHello:     
2632
2633             /* get sz bytes or return error */
2634             if (!ssl->options.dtls) {
2635                 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
2636                     return ret;
2637             } else {
2638             #ifdef CYASSL_DTLS
2639                 /* read ahead may already have */
2640                 used = ssl->buffers.inputBuffer.length -
2641                        ssl->buffers.inputBuffer.idx;
2642                 if (used < ssl->curSize)
2643                     if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
2644                         return ret;
2645             #endif  /* CYASSL_DTLS */
2646             }
2647
2648             ret = ProcessOldClientHello(ssl, ssl->buffers.inputBuffer.buffer,
2649                                         &ssl->buffers.inputBuffer.idx,
2650                                         ssl->buffers.inputBuffer.length -
2651                                         ssl->buffers.inputBuffer.idx,
2652                                         ssl->curSize);
2653             if (ret < 0)
2654                 return ret;
2655
2656             else if (ssl->buffers.inputBuffer.idx ==
2657                      ssl->buffers.inputBuffer.length) {
2658                 ssl->options.processReply = doProcessInit;
2659                 return 0;
2660             }
2661
2662 #endif  /* NO_CYASSL_SERVER */
2663
2664         /* get the record layer header */
2665         case getRecordLayerHeader:
2666
2667             ret = GetRecordHeader(ssl, ssl->buffers.inputBuffer.buffer,
2668                                        &ssl->buffers.inputBuffer.idx,
2669                                        &ssl->curRL, &ssl->curSize);
2670             if (ret != 0)
2671                 return ret;
2672
2673             ssl->options.processReply = getData;
2674
2675         /* retrieve record layer data */
2676         case getData:
2677
2678             /* get sz bytes or return error */
2679             if (!ssl->options.dtls) {
2680                 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
2681                     return ret;
2682             } else {
2683 #ifdef CYASSL_DTLS
2684                 /* read ahead may already have */
2685                 used = ssl->buffers.inputBuffer.length -
2686                        ssl->buffers.inputBuffer.idx;
2687                 if (used < ssl->curSize)
2688                     if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
2689                         return ret;
2690 #endif
2691             }
2692             
2693             ssl->options.processReply = runProcessingOneMessage;
2694             startIdx = ssl->buffers.inputBuffer.idx;  /* in case > 1 msg per */
2695
2696         /* the record layer is here */
2697         case runProcessingOneMessage:
2698
2699             if (ssl->keys.encryptionOn)
2700                 if (DecryptMessage(ssl, ssl->buffers.inputBuffer.buffer + 
2701                                         ssl->buffers.inputBuffer.idx,
2702                                         ssl->curSize,
2703                                         &ssl->buffers.inputBuffer.idx) < 0)
2704                     return DECRYPT_ERROR;
2705
2706             CYASSL_MSG("received record layer msg");
2707
2708             switch (ssl->curRL.type) {
2709                 case handshake :
2710                     /* debugging in DoHandShakeMsg */
2711                     if ((ret = DoHandShakeMsg(ssl, 
2712                                               ssl->buffers.inputBuffer.buffer,
2713                                               &ssl->buffers.inputBuffer.idx,
2714                                               ssl->buffers.inputBuffer.length))
2715                                                                            != 0)
2716                         return ret;
2717                     break;
2718
2719                 case change_cipher_spec:
2720                     CYASSL_MSG("got CHANGE CIPHER SPEC");
2721                     #ifdef CYASSL_CALLBACKS
2722                         if (ssl->hsInfoOn)
2723                             AddPacketName("ChangeCipher", &ssl->handShakeInfo);
2724                         /* add record header back on info */
2725                         if (ssl->toInfoOn) {
2726                             AddPacketInfo("ChangeCipher", &ssl->timeoutInfo,
2727                                 ssl->buffers.inputBuffer.buffer +
2728                                 ssl->buffers.inputBuffer.idx - RECORD_HEADER_SZ,
2729                                 1 + RECORD_HEADER_SZ, ssl->heap);
2730                             AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
2731                         }
2732                     #endif
2733                     ssl->buffers.inputBuffer.idx++;
2734                     ssl->keys.encryptionOn = 1;
2735
2736                     #ifdef CYASSL_DTLS
2737                         if (ssl->options.dtls)
2738                             ssl->keys.dtls_peer_epoch++;
2739                     #endif
2740
2741                     #ifdef HAVE_LIBZ
2742                         if (ssl->options.usingCompression)
2743                             if ( (ret = InitStreams(ssl)) != 0)
2744                                 return ret;
2745                     #endif
2746                     if (ssl->options.resuming && ssl->options.side ==
2747                                                                     CLIENT_END)
2748                         BuildFinished(ssl, &ssl->verifyHashes, server);
2749                     else if (!ssl->options.resuming && ssl->options.side ==
2750                                                                     SERVER_END)
2751                         BuildFinished(ssl, &ssl->verifyHashes, client);
2752                     break;
2753
2754                 case application_data:
2755                     CYASSL_MSG("got app DATA");
2756                     if ((ret = DoApplicationData(ssl,
2757                                                 ssl->buffers.inputBuffer.buffer,
2758                                                &ssl->buffers.inputBuffer.idx))
2759                                                                          != 0) {
2760                         CYASSL_ERROR(ret);
2761                         return ret;
2762                     }
2763                     break;
2764
2765                 case alert:
2766                     CYASSL_MSG("got ALERT!");
2767                     if (DoAlert(ssl, ssl->buffers.inputBuffer.buffer,
2768                            &ssl->buffers.inputBuffer.idx, &type) == alert_fatal)
2769                         return FATAL_ERROR;
2770
2771                     /* catch warnings that are handled as errors */
2772                     if (type == close_notify)
2773                         return ssl->error = ZERO_RETURN;
2774                            
2775                     if (type == decrypt_error)
2776                         return FATAL_ERROR;
2777                     break;
2778             
2779                 default:
2780                     CYASSL_ERROR(UNKNOWN_RECORD_TYPE);
2781                     return UNKNOWN_RECORD_TYPE;
2782             }
2783
2784             ssl->options.processReply = doProcessInit;
2785
2786             /* input exhausted? */
2787             if (ssl->buffers.inputBuffer.idx == ssl->buffers.inputBuffer.length)
2788                 return 0;
2789             /* more messages per record */
2790             else if ((ssl->buffers.inputBuffer.idx - startIdx) < ssl->curSize) {
2791                 CYASSL_MSG("More messages in record");
2792                 #ifdef CYASSL_DTLS
2793                     /* read-ahead but dtls doesn't bundle messages per record */
2794                     if (ssl->options.dtls) {
2795                         ssl->options.processReply = doProcessInit;
2796                         continue;
2797                     }
2798                 #endif
2799                 ssl->options.processReply = runProcessingOneMessage;
2800                 continue;
2801             }
2802             /* more records */
2803             else {
2804                 CYASSL_MSG("More records in input");
2805                 ssl->options.processReply = doProcessInit;
2806                 continue;
2807             }
2808         default:
2809             CYASSL_MSG("Bad process input state, programming error");
2810             return INPUT_CASE_ERROR;
2811         }
2812     }
2813 }
2814
2815
2816 int SendChangeCipher(CYASSL* ssl)
2817 {
2818     byte              *output;
2819     int                sendSz = RECORD_HEADER_SZ + ENUM_LEN;
2820     int                idx    = RECORD_HEADER_SZ;
2821     int                ret;
2822
2823     #ifdef CYASSL_DTLS
2824         if (ssl->options.dtls) {
2825             sendSz += DTLS_RECORD_EXTRA;
2826             idx    += DTLS_RECORD_EXTRA;
2827         }
2828     #endif
2829
2830     /* check for avalaible size */
2831     if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
2832         return ret;
2833
2834     /* get ouput buffer */
2835     output = ssl->buffers.outputBuffer.buffer + 
2836              ssl->buffers.outputBuffer.length;
2837
2838     AddRecordHeader(output, 1, change_cipher_spec, ssl);
2839
2840     output[idx] = 1;             /* turn it on */
2841
2842     #ifdef CYASSL_CALLBACKS
2843         if (ssl->hsInfoOn) AddPacketName("ChangeCipher", &ssl->handShakeInfo);
2844         if (ssl->toInfoOn)
2845             AddPacketInfo("ChangeCipher", &ssl->timeoutInfo, output, sendSz,
2846                            ssl->heap);
2847     #endif
2848     ssl->buffers.outputBuffer.length += sendSz;
2849
2850     if (ssl->options.groupMessages)
2851         return 0;
2852     else
2853         return SendBuffered(ssl);
2854 }
2855
2856
2857 static INLINE const byte* GetMacSecret(CYASSL* ssl, int verify)
2858 {
2859     if ( (ssl->options.side == CLIENT_END && !verify) ||
2860          (ssl->options.side == SERVER_END &&  verify) )
2861         return ssl->keys.client_write_MAC_secret;
2862     else
2863         return ssl->keys.server_write_MAC_secret;
2864 }
2865
2866
2867 static void Hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
2868                  int content, int verify)
2869 {
2870     byte   result[SHA256_DIGEST_SIZE];                 /* max possible sizes */
2871     word32 digestSz = ssl->specs.hash_size;            /* actual sizes */
2872     word32 padSz    = ssl->specs.pad_size;
2873
2874     Md5 md5;
2875     Sha sha;
2876
2877     /* data */
2878     byte seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 };
2879     byte conLen[ENUM_LEN + LENGTH_SZ];     /* content & length */
2880     const byte* macSecret = GetMacSecret(ssl, verify);
2881     
2882     conLen[0] = (byte)content;
2883     c16toa((word16)sz, &conLen[ENUM_LEN]);
2884     c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]);
2885
2886     if (ssl->specs.mac_algorithm == md5_mac) {
2887         InitMd5(&md5);
2888         /* inner */
2889         Md5Update(&md5, macSecret, digestSz);
2890         Md5Update(&md5, PAD1, padSz);
2891         Md5Update(&md5, seq, SEQ_SZ);
2892         Md5Update(&md5, conLen, sizeof(conLen));
2893         /* in buffer */
2894         Md5Update(&md5, in, sz);
2895         Md5Final(&md5, result);
2896         /* outer */
2897         Md5Update(&md5, macSecret, digestSz);
2898         Md5Update(&md5, PAD2, padSz);
2899         Md5Update(&md5, result, digestSz);
2900         Md5Final(&md5, digest);        
2901     }
2902     else {
2903         InitSha(&sha);
2904         /* inner */
2905         ShaUpdate(&sha, macSecret, digestSz);
2906         ShaUpdate(&sha, PAD1, padSz);
2907         ShaUpdate(&sha, seq, SEQ_SZ);
2908         ShaUpdate(&sha, conLen, sizeof(conLen));
2909         /* in buffer */
2910         ShaUpdate(&sha, in, sz);
2911         ShaFinal(&sha, result);
2912         /* outer */
2913         ShaUpdate(&sha, macSecret, digestSz);
2914         ShaUpdate(&sha, PAD2, padSz);
2915         ShaUpdate(&sha, result, digestSz);
2916         ShaFinal(&sha, digest);        
2917     }
2918 }
2919
2920
2921 static void BuildMD5_CertVerify(CYASSL* ssl, byte* digest)
2922 {
2923     byte md5_result[MD5_DIGEST_SIZE];
2924
2925     /* make md5 inner */
2926     Md5Update(&ssl->hashMd5, ssl->arrays.masterSecret, SECRET_LEN);
2927     Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
2928     Md5Final(&ssl->hashMd5, md5_result);
2929
2930     /* make md5 outer */
2931     Md5Update(&ssl->hashMd5, ssl->arrays.masterSecret, SECRET_LEN);
2932     Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
2933     Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
2934
2935     Md5Final(&ssl->hashMd5, digest);
2936 }
2937
2938
2939 static void BuildSHA_CertVerify(CYASSL* ssl, byte* digest)
2940 {
2941     byte sha_result[SHA_DIGEST_SIZE];
2942     
2943     /* make sha inner */
2944     ShaUpdate(&ssl->hashSha, ssl->arrays.masterSecret, SECRET_LEN);
2945     ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
2946     ShaFinal(&ssl->hashSha, sha_result);
2947
2948     /* make sha outer */
2949     ShaUpdate(&ssl->hashSha, ssl->arrays.masterSecret, SECRET_LEN);
2950     ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
2951     ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
2952
2953     ShaFinal(&ssl->hashSha, digest);
2954 }
2955
2956
2957 static void BuildCertHashes(CYASSL* ssl, Hashes* hashes)
2958 {
2959     /* store current states, building requires get_digest which resets state */
2960     Md5 md5 = ssl->hashMd5;
2961     Sha sha = ssl->hashSha;
2962 #ifndef NO_SHA256     /* for possible future changes */
2963     Sha256 sha256;
2964     InitSha256(&sha256);
2965     if (IsAtLeastTLSv1_2(ssl))
2966         sha256 = ssl->hashSha256;
2967 #endif
2968
2969     if (ssl->options.tls) {
2970         Md5Final(&ssl->hashMd5, hashes->md5);
2971         ShaFinal(&ssl->hashSha, hashes->sha);
2972     }
2973     else {
2974         BuildMD5_CertVerify(ssl, hashes->md5);
2975         BuildSHA_CertVerify(ssl, hashes->sha);
2976     }
2977     
2978     /* restore */
2979     ssl->hashMd5 = md5;
2980     ssl->hashSha = sha;
2981 #ifndef NO_SHA256
2982     if (IsAtLeastTLSv1_2(ssl))
2983         ssl->hashSha256 = sha256;
2984 #endif
2985 }
2986
2987
2988 /* Build SSL Message, encrypted */
2989 static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz,
2990                         int type)
2991 {
2992     word32 digestSz = ssl->specs.hash_size;
2993     word32 sz = RECORD_HEADER_SZ + inSz + digestSz;                
2994     word32 pad  = 0, i;
2995     word32 idx  = RECORD_HEADER_SZ;
2996     word32 ivSz = 0;      /* TLSv1.1  IV */
2997     word32 headerSz = RECORD_HEADER_SZ;
2998     word16 size;
2999     byte               iv[AES_BLOCK_SIZE];                  /* max size */
3000
3001 #ifdef CYASSL_DTLS
3002     if (ssl->options.dtls) {
3003         sz       += DTLS_RECORD_EXTRA;
3004         idx      += DTLS_RECORD_EXTRA; 
3005         headerSz += DTLS_RECORD_EXTRA;
3006     }
3007 #endif
3008
3009     if (ssl->specs.cipher_type == block) {
3010         word32 blockSz = ssl->specs.block_size;
3011         if (ssl->options.tls1_1) {
3012             ivSz = blockSz;
3013             sz  += ivSz;
3014             RNG_GenerateBlock(&ssl->rng, iv, ivSz);
3015         }
3016         sz += 1;       /* pad byte */
3017         pad = (sz - headerSz) % blockSz;
3018         pad = blockSz - pad;
3019         sz += pad;
3020     }
3021
3022 #ifdef BUILD_AESGCM
3023     if (ssl->specs.cipher_type == aead) {
3024         ivSz = AES_GCM_EXP_IV_SZ;
3025         sz += (ivSz + 16 - digestSz);
3026         AesGcmGetExpIV(&ssl->encrypt.aes, iv);
3027     }
3028 #endif
3029     size = (word16)(sz - headerSz);    /* include mac and digest */
3030     AddRecordHeader(output, size, (byte)type, ssl);    
3031
3032     /* write to output */
3033     if (ivSz) {
3034         XMEMCPY(output + idx, iv, min(ivSz, sizeof(iv)));
3035         idx += ivSz;
3036     }
3037     XMEMCPY(output + idx, input, inSz);
3038     idx += inSz;
3039
3040     if (type == handshake)
3041         HashOutput(ssl, output, headerSz + inSz, ivSz);
3042     if (ssl->specs.cipher_type != aead) {
3043         ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz, type, 0);
3044         idx += digestSz;
3045     }
3046
3047     if (ssl->specs.cipher_type == block)
3048         for (i = 0; i <= pad; i++)
3049             output[idx++] = (byte)pad; /* pad byte gets pad value too */
3050
3051     Encrypt(ssl, output + headerSz, output + headerSz, size);
3052
3053     return sz;
3054 }
3055
3056
3057 int SendFinished(CYASSL* ssl)
3058 {
3059     int              sendSz,
3060                      finishedSz = ssl->options.tls ? TLS_FINISHED_SZ :
3061                                                      FINISHED_SZ;
3062     byte             input[FINISHED_SZ + DTLS_HANDSHAKE_HEADER_SZ];  /* max */
3063     byte            *output;
3064     Hashes*          hashes;
3065     int              ret;
3066     int              headerSz = HANDSHAKE_HEADER_SZ;
3067
3068
3069     #ifdef CYASSL_DTLS
3070         if (ssl->options.dtls) {
3071             headerSz += DTLS_HANDSHAKE_EXTRA;
3072             ssl->keys.dtls_epoch++;
3073             ssl->keys.dtls_sequence_number = 0;  /* reset after epoch change */
3074         }
3075     #endif
3076     
3077     /* check for avalaible size */
3078     if ((ret = CheckAvalaibleSize(ssl, sizeof(input) + MAX_MSG_EXTRA)) != 0)
3079         return ret;
3080
3081     /* get ouput buffer */
3082     output = ssl->buffers.outputBuffer.buffer + 
3083              ssl->buffers.outputBuffer.length;
3084
3085     AddHandShakeHeader(input, finishedSz, finished, ssl);
3086
3087     /* make finished hashes */
3088     hashes = (Hashes*)&input[headerSz];
3089     BuildFinished(ssl, hashes, ssl->options.side == CLIENT_END ? client :
3090                   server);
3091
3092     if ( (sendSz = BuildMessage(ssl, output, input, headerSz +
3093                                 finishedSz, handshake)) < 0)
3094         return BUILD_MSG_ERROR;
3095
3096     if (!ssl->options.resuming) {
3097 #ifndef NO_SESSION_CACHE
3098         AddSession(ssl);    /* just try */
3099 #endif
3100         if (ssl->options.side == CLIENT_END)
3101             BuildFinished(ssl, &ssl->verifyHashes, server);
3102         else
3103             ssl->options.handShakeState = HANDSHAKE_DONE;
3104     }
3105     else {
3106         if (ssl->options.side == CLIENT_END)
3107             ssl->options.handShakeState = HANDSHAKE_DONE;
3108         else
3109             BuildFinished(ssl, &ssl->verifyHashes, client);
3110     }
3111
3112     #ifdef CYASSL_CALLBACKS
3113         if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
3114         if (ssl->toInfoOn)
3115             AddPacketInfo("Finished", &ssl->timeoutInfo, output, sendSz,
3116                           ssl->heap);
3117     #endif
3118
3119     ssl->buffers.outputBuffer.length += sendSz;
3120
3121     return SendBuffered(ssl);
3122 }
3123
3124
3125 int SendCertificate(CYASSL* ssl)
3126 {
3127     int    sendSz, length, ret = 0;
3128     word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
3129     word32 certSz, listSz;
3130     byte*  output = 0;
3131
3132     if (ssl->options.usingPSK_cipher) return 0;  /* not needed */
3133
3134     if (ssl->options.sendVerify == SEND_BLANK_CERT) {
3135         certSz = 0;
3136         length = CERT_HEADER_SZ;
3137         listSz = 0;
3138     }
3139     else {
3140         certSz = ssl->buffers.certificate.length;
3141         /* list + cert size */
3142         length = certSz + 2 * CERT_HEADER_SZ;
3143         listSz = certSz + CERT_HEADER_SZ;
3144
3145         /* may need to send rest of chain, already has leading size(s) */
3146         if (ssl->buffers.certChain.buffer) {
3147             length += ssl->buffers.certChain.length;
3148             listSz += ssl->buffers.certChain.length;
3149         }
3150     }
3151     sendSz = length + RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
3152
3153     #ifdef CYASSL_DTLS
3154         if (ssl->options.dtls) {
3155             sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
3156             i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
3157         }
3158     #endif
3159
3160     /* check for avalaible size */
3161     if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
3162         return ret;
3163
3164     /* get ouput buffer */
3165     output = ssl->buffers.outputBuffer.buffer +
3166              ssl->buffers.outputBuffer.length;
3167
3168     AddHeaders(output, length, certificate, ssl);
3169
3170     /* list total */
3171     c32to24(listSz, output + i);
3172     i += CERT_HEADER_SZ;
3173
3174     /* member */
3175     if (certSz) {
3176         c32to24(certSz, output + i);
3177         i += CERT_HEADER_SZ;
3178         XMEMCPY(output + i, ssl->buffers.certificate.buffer, certSz);
3179         i += certSz;
3180
3181         /* send rest of chain? */
3182         if (ssl->buffers.certChain.buffer) {
3183             XMEMCPY(output + i, ssl->buffers.certChain.buffer,
3184                                 ssl->buffers.certChain.length);
3185             i += ssl->buffers.certChain.length;
3186         }
3187     }
3188     HashOutput(ssl, output, sendSz, 0);
3189     #ifdef CYASSL_CALLBACKS
3190         if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
3191         if (ssl->toInfoOn)
3192             AddPacketInfo("Certificate", &ssl->timeoutInfo, output, sendSz,
3193                            ssl->heap);
3194     #endif
3195
3196     if (ssl->options.side == SERVER_END)
3197         ssl->options.serverState = SERVER_CERT_COMPLETE;
3198
3199     ssl->buffers.outputBuffer.length += sendSz;
3200     if (ssl->options.groupMessages)
3201         return 0;
3202     else
3203         return SendBuffered(ssl);
3204 }
3205
3206
3207 int SendCertificateRequest(CYASSL* ssl)
3208 {
3209     byte   *output;
3210     int    ret;
3211     int    sendSz;
3212     word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
3213     
3214     int  typeTotal = 1;  /* only rsa for now */
3215     int  reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ;  /* add auth later */
3216
3217     if (IsAtLeastTLSv1_2(ssl))
3218         reqSz += LENGTH_SZ + HASH_SIG_SIZE;
3219
3220     if (ssl->options.usingPSK_cipher) return 0;  /* not needed */
3221
3222     sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
3223
3224     #ifdef CYASSL_DTLS
3225         if (ssl->options.dtls) {
3226             sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
3227             i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
3228         }
3229     #endif
3230     /* check for avalaible size */
3231     if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
3232         return ret;
3233
3234     /* get ouput buffer */
3235     output = ssl->buffers.outputBuffer.buffer +
3236              ssl->buffers.outputBuffer.length;
3237
3238     AddHeaders(output, reqSz, certificate_request, ssl);
3239
3240     /* write to output */
3241     output[i++] = (byte)typeTotal;  /* # of types */
3242     output[i++] = rsa_sign;
3243
3244     /* supported hash/sig */
3245     if (IsAtLeastTLSv1_2(ssl)) {
3246         c16toa(HASH_SIG_SIZE, &output[i]);
3247         i += LENGTH_SZ;
3248
3249         output[i++] = sha_mac;      /* hash */
3250         output[i++] = rsa_sa_algo;  /* sig  */
3251     }
3252
3253     c16toa(0, &output[i]);  /* auth's */
3254     i += REQ_HEADER_SZ;
3255
3256     HashOutput(ssl, output, sendSz, 0);
3257
3258     #ifdef CYASSL_CALLBACKS
3259         if (ssl->hsInfoOn)
3260             AddPacketName("CertificateRequest", &ssl->handShakeInfo);
3261         if (ssl->toInfoOn)
3262             AddPacketInfo("CertificateRequest", &ssl->timeoutInfo, output,
3263                           sendSz, ssl->heap);
3264     #endif
3265     ssl->buffers.outputBuffer.length += sendSz;
3266     if (ssl->options.groupMessages)
3267         return 0;
3268     else
3269         return SendBuffered(ssl);
3270 }
3271
3272
3273 int SendData(CYASSL* ssl, const void* data, int sz)
3274 {
3275     int sent = 0,  /* plainText size */
3276         sendSz,
3277         ret;
3278
3279     if (ssl->error == WANT_WRITE)
3280         ssl->error = 0;
3281
3282     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
3283         int err;
3284         CYASSL_MSG("handshake not complete, trying to finish");
3285         if ( (err = CyaSSL_negotiate(ssl)) != 0) 
3286             return  err;
3287     }
3288
3289     /* last time system socket output buffer was full, try again to send */
3290     if (ssl->buffers.outputBuffer.length > 0) {
3291         CYASSL_MSG("output buffer was full, trying to send again");
3292         if ( (ssl->error = SendBuffered(ssl)) < 0) {
3293             CYASSL_ERROR(ssl->error);
3294             if (ssl->error == SOCKET_ERROR_E && ssl->options.connReset)
3295                 return 0;     /* peer reset */
3296             return ssl->error;
3297         }
3298         else {
3299             /* advance sent to previous sent + plain size just sent */
3300             sent = ssl->buffers.prevSent + ssl->buffers.plainSz;
3301             CYASSL_MSG("sent write buffered data");
3302         }
3303     }
3304
3305     for (;;) {
3306         int   len = min(sz - sent, OUTPUT_RECORD_SIZE);
3307         byte* out;
3308         byte* sendBuffer = (byte*)data + sent;  /* may switch on comp */
3309         int   buffSz = len;                       /* may switch on comp */
3310 #ifdef HAVE_LIBZ
3311         byte  comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
3312 #endif
3313
3314         if (sent == sz) break;
3315
3316 #ifdef CYASSL_DTLS
3317         if (ssl->options.dtls) {
3318             len    = min(len, MAX_UDP_SIZE);
3319             buffSz = len;
3320         }
3321 #endif
3322
3323         /* check for avalaible size */
3324         if ((ret = CheckAvalaibleSize(ssl, len + COMP_EXTRA +
3325                                       MAX_MSG_EXTRA)) != 0)
3326             return ret;
3327
3328         /* get ouput buffer */
3329         out = ssl->buffers.outputBuffer.buffer +
3330               ssl->buffers.outputBuffer.length;
3331
3332 #ifdef HAVE_LIBZ
3333         if (ssl->options.usingCompression) {
3334             buffSz = Compress(ssl, sendBuffer, buffSz, comp, sizeof(comp));
3335             if (buffSz < 0) {
3336                 return buffSz;
3337             }
3338             sendBuffer = comp;
3339         }
3340 #endif
3341         sendSz = BuildMessage(ssl, out, sendBuffer, buffSz,
3342                               application_data);
3343
3344         ssl->buffers.outputBuffer.length += sendSz;
3345
3346         if ( (ret = SendBuffered(ssl)) < 0) {
3347             CYASSL_ERROR(ret);
3348             /* store for next call if WANT_WRITE or user embedSend() that
3349                doesn't present like WANT_WRITE */
3350             ssl->buffers.plainSz  = len;
3351             ssl->buffers.prevSent = sent;
3352             if (ret == SOCKET_ERROR_E && ssl->options.connReset)
3353                 return 0;  /* peer reset */
3354             return ssl->error = ret;
3355         }
3356
3357         sent += len;
3358
3359         /* only one message per attempt */
3360         if (ssl->options.partialWrite == 1) {
3361             CYASSL_MSG("Paritial Write on, only sending one record");
3362             break;
3363         }
3364     }
3365  
3366     return sent;
3367 }
3368
3369 /* process input data */
3370 int ReceiveData(CYASSL* ssl, byte* output, int sz)
3371 {
3372     int size;
3373
3374     CYASSL_ENTER("ReceiveData()");
3375
3376     if (ssl->error == WANT_READ)
3377         ssl->error = 0;
3378
3379     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
3380         int err;
3381         CYASSL_MSG("Handshake not complete, trying to finish");
3382         if ( (err = CyaSSL_negotiate(ssl)) != 0)
3383             return  err;
3384     }
3385
3386     while (ssl->buffers.clearOutputBuffer.length == 0)
3387         if ( (ssl->error = ProcessReply(ssl)) < 0) {
3388             CYASSL_ERROR(ssl->error);
3389             if (ssl->error == ZERO_RETURN) {
3390                 CYASSL_MSG("Zero return, no more data coming");
3391                 ssl->options.isClosed = 1;
3392                 return 0;         /* no more data coming */
3393             }
3394             if (ssl->error == SOCKET_ERROR_E) {
3395                 if (ssl->options.connReset || ssl->options.isClosed) {
3396                     CYASSL_MSG("Peer reset or closed, connection done");
3397                     return 0;     /* peer reset or closed */
3398                 }
3399             }
3400             return ssl->error;
3401         }
3402
3403     if (sz < (int)ssl->buffers.clearOutputBuffer.length)
3404         size = sz;
3405     else
3406         size = ssl->buffers.clearOutputBuffer.length;
3407
3408     XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size);
3409     ssl->buffers.clearOutputBuffer.length -= size;
3410     ssl->buffers.clearOutputBuffer.buffer += size;
3411    
3412     if (ssl->buffers.clearOutputBuffer.length == 0 && 
3413                                            ssl->buffers.inputBuffer.dynamicFlag)
3414        ShrinkInputBuffer(ssl, NO_FORCED_FREE);
3415
3416     CYASSL_LEAVE("ReceiveData()", size);
3417     return size;
3418 }
3419
3420
3421 /* send alert message */
3422 int SendAlert(CYASSL* ssl, int severity, int type)
3423 {
3424     byte input[ALERT_SIZE];
3425     byte *output;
3426     int  sendSz;
3427     int  ret;
3428
3429     /* if sendalert is called again for nonbloking */
3430     if (ssl->options.sendAlertState != 0) {
3431         ret = SendBuffered(ssl);
3432         if (ret == 0)
3433             ssl->options.sendAlertState = 0;
3434         return ret;
3435     }
3436
3437     /* check for avalaible size */
3438     if ((ret = CheckAvalaibleSize(ssl, ALERT_SIZE + MAX_MSG_EXTRA)) != 0)
3439         return ret;
3440
3441     /* get ouput buffer */
3442     output = ssl->buffers.outputBuffer.buffer +
3443              ssl->buffers.outputBuffer.length;
3444
3445     input[0] = (byte)severity;
3446     input[1] = (byte)type;
3447
3448     if (ssl->keys.encryptionOn)
3449         sendSz = BuildMessage(ssl, output, input, ALERT_SIZE, alert);
3450     else {
3451         RecordLayerHeader *const rl = (RecordLayerHeader*)output;
3452         rl->type    = alert;
3453         rl->version = ssl->version;
3454         c16toa(ALERT_SIZE, rl->length);      
3455
3456         XMEMCPY(output + RECORD_HEADER_SZ, input, ALERT_SIZE);
3457         sendSz = RECORD_HEADER_SZ + ALERT_SIZE;
3458     }
3459
3460     #ifdef CYASSL_CALLBACKS
3461         if (ssl->hsInfoOn)
3462             AddPacketName("Alert", &ssl->handShakeInfo);
3463         if (ssl->toInfoOn)
3464             AddPacketInfo("Alert", &ssl->timeoutInfo, output, sendSz,ssl->heap);
3465     #endif
3466
3467     ssl->buffers.outputBuffer.length += sendSz;
3468     ssl->options.sendAlertState = 1;
3469
3470     return SendBuffered(ssl);
3471 }
3472
3473
3474
3475 void SetErrorString(int error, char* str)
3476 {
3477     const int max = MAX_ERROR_SZ;  /* shorthand */
3478
3479 #ifdef NO_ERROR_STRINGS
3480
3481     XSTRNCPY(str, "no support for error strings built in", max);
3482
3483 #else
3484
3485     /* pass to CTaoCrypt */
3486     if (error < MAX_CODE_E && error > MIN_CODE_E) {
3487         CTaoCryptErrorString(error, str);
3488         return;
3489     }
3490
3491     switch (error) {
3492
3493     case UNSUPPORTED_SUITE :
3494         XSTRNCPY(str, "unsupported cipher suite", max);
3495         break;
3496
3497     case INPUT_CASE_ERROR :
3498         XSTRNCPY(str, "input state error", max);
3499         break;
3500
3501     case PREFIX_ERROR :
3502         XSTRNCPY(str, "bad index to key rounds", max);
3503         break;
3504
3505     case MEMORY_ERROR :
3506         XSTRNCPY(str, "out of memory", max);
3507         break;
3508
3509     case VERIFY_FINISHED_ERROR :
3510         XSTRNCPY(str, "verify problem on finished", max);
3511         break;
3512
3513     case VERIFY_MAC_ERROR :
3514         XSTRNCPY(str, "verify mac problem", max);
3515         break;
3516
3517     case PARSE_ERROR :
3518         XSTRNCPY(str, "parse error on header", max);
3519         break;
3520
3521     case SIDE_ERROR :
3522         XSTRNCPY(str, "wrong client/server type", max);
3523         break;
3524
3525     case NO_PEER_CERT :
3526         XSTRNCPY(str, "peer didn't send cert", max);
3527         break;
3528
3529     case UNKNOWN_HANDSHAKE_TYPE :
3530         XSTRNCPY(str, "weird handshake type", max);
3531         break;
3532
3533     case SOCKET_ERROR_E :
3534         XSTRNCPY(str, "error state on socket", max);
3535         break;
3536
3537     case SOCKET_NODATA :
3538         XSTRNCPY(str, "expected data, not there", max);
3539         break;
3540
3541     case INCOMPLETE_DATA :
3542         XSTRNCPY(str, "don't have enough data to complete task", max);
3543         break;
3544
3545     case UNKNOWN_RECORD_TYPE :
3546         XSTRNCPY(str, "unknown type in record hdr", max);
3547         break;
3548
3549     case DECRYPT_ERROR :
3550         XSTRNCPY(str, "error during decryption", max);
3551         break;
3552
3553     case FATAL_ERROR :
3554         XSTRNCPY(str, "revcd alert fatal error", max);
3555         break;
3556
3557     case ENCRYPT_ERROR :
3558         XSTRNCPY(str, "error during encryption", max);
3559         break;
3560
3561     case FREAD_ERROR :
3562         XSTRNCPY(str, "fread problem", max);
3563         break;
3564
3565     case NO_PEER_KEY :
3566         XSTRNCPY(str, "need peer's key", max);
3567         break;
3568
3569     case NO_PRIVATE_KEY :
3570         XSTRNCPY(str, "need the private key", max);
3571         break;
3572
3573     case NO_DH_PARAMS :
3574         XSTRNCPY(str, "server missing DH params", max);
3575         break;
3576
3577     case RSA_PRIVATE_ERROR :
3578         XSTRNCPY(str, "error during rsa priv op", max);
3579         break;
3580
3581     case MATCH_SUITE_ERROR :
3582         XSTRNCPY(str, "can't match cipher suite", max);
3583         break;
3584
3585     case BUILD_MSG_ERROR :
3586         XSTRNCPY(str, "build message failure", max);
3587         break;
3588
3589     case BAD_HELLO :
3590         XSTRNCPY(str, "client hello malformed", max);
3591         break;
3592
3593     case DOMAIN_NAME_MISMATCH :
3594         XSTRNCPY(str, "peer subject name mismatch", max);
3595         break;
3596
3597     case WANT_READ :
3598         XSTRNCPY(str, "non-blocking socket wants data to be read", max);
3599         break;
3600
3601     case NOT_READY_ERROR :
3602         XSTRNCPY(str, "handshake layer not ready yet, complete first", max);
3603         break;
3604
3605     case PMS_VERSION_ERROR :
3606         XSTRNCPY(str, "premaster secret version mismatch error", max);
3607         break;
3608
3609     case VERSION_ERROR :
3610         XSTRNCPY(str, "record layer version error", max);
3611         break;
3612
3613     case WANT_WRITE :
3614         XSTRNCPY(str, "non-blocking socket write buffer full", max);
3615         break;
3616
3617     case BUFFER_ERROR :
3618         XSTRNCPY(str, "malformed buffer input error", max);
3619         break;
3620
3621     case VERIFY_CERT_ERROR :
3622         XSTRNCPY(str, "verify problem on certificate", max);
3623         break;
3624
3625     case VERIFY_SIGN_ERROR :
3626         XSTRNCPY(str, "verify problem based on signature", max);
3627         break;
3628
3629     case CLIENT_ID_ERROR :
3630         XSTRNCPY(str, "psk client identity error", max);
3631         break;
3632
3633     case SERVER_HINT_ERROR:
3634         XSTRNCPY(str, "psk server hint error", max);
3635         break;
3636
3637     case PSK_KEY_ERROR:
3638         XSTRNCPY(str, "psk key callback error", max);
3639         break;
3640
3641     case NTRU_KEY_ERROR:
3642         XSTRNCPY(str, "NTRU key error", max);
3643         break;
3644
3645     case NTRU_DRBG_ERROR:
3646         XSTRNCPY(str, "NTRU drbg error", max);
3647         break;
3648
3649     case NTRU_ENCRYPT_ERROR:
3650         XSTRNCPY(str, "NTRU encrypt error", max);
3651         break;
3652
3653     case NTRU_DECRYPT_ERROR:
3654         XSTRNCPY(str, "NTRU decrypt error", max);
3655         break;
3656
3657     case ZLIB_INIT_ERROR:
3658         XSTRNCPY(str, "zlib init error", max);
3659         break;
3660
3661     case ZLIB_COMPRESS_ERROR:
3662         XSTRNCPY(str, "zlib compress error", max);
3663         break;
3664
3665     case ZLIB_DECOMPRESS_ERROR:
3666         XSTRNCPY(str, "zlib decompress error", max);
3667         break;
3668
3669     case GETTIME_ERROR:
3670         XSTRNCPY(str, "gettimeofday() error", max);
3671         break;
3672
3673     case GETITIMER_ERROR:
3674         XSTRNCPY(str, "getitimer() error", max);
3675         break;
3676
3677     case SIGACT_ERROR:
3678         XSTRNCPY(str, "sigaction() error", max);
3679         break;
3680
3681     case SETITIMER_ERROR:
3682         XSTRNCPY(str, "setitimer() error", max);
3683         break;
3684
3685     case LENGTH_ERROR:
3686         XSTRNCPY(str, "record layer length error", max);
3687         break;
3688
3689     case PEER_KEY_ERROR:
3690         XSTRNCPY(str, "cant decode peer key", max);
3691         break;
3692
3693     case ZERO_RETURN:
3694         XSTRNCPY(str, "peer sent close notify alert", max);
3695         break;
3696
3697     case ECC_CURVETYPE_ERROR:
3698         XSTRNCPY(str, "Bad ECC Curve Type or unsupported", max);
3699         break;
3700
3701     case ECC_CURVE_ERROR:
3702         XSTRNCPY(str, "Bad ECC Curve or unsupported", max);
3703         break;
3704
3705     case ECC_PEERKEY_ERROR:
3706         XSTRNCPY(str, "Bad ECC Peer Key", max);
3707         break;
3708
3709     case ECC_MAKEKEY_ERROR:
3710         XSTRNCPY(str, "ECC Make Key failure", max);
3711         break;
3712
3713     case ECC_EXPORT_ERROR:
3714         XSTRNCPY(str, "ECC Export Key failure", max);
3715         break;
3716
3717     case ECC_SHARED_ERROR:
3718         XSTRNCPY(str, "ECC DHE shared failure", max);
3719         break;
3720
3721     case BAD_MUTEX_ERROR:
3722         XSTRNCPY(str, "Bad mutex, operation failed", max);
3723         break;
3724
3725     case NOT_CA_ERROR:
3726         XSTRNCPY(str, "Not a CA by basic constraint error", max);
3727         break;
3728
3729     case BAD_PATH_ERROR:
3730         XSTRNCPY(str, "Bad path for opendir error", max);
3731         break;
3732
3733     case BAD_CERT_MANAGER_ERROR:
3734         XSTRNCPY(str, "Bad Cert Manager error", max);
3735         break;
3736
3737     case OCSP_CERT_REVOKED:
3738         XSTRNCPY(str, "OCSP Cert revoked", max);
3739         break;
3740
3741     case CRL_CERT_REVOKED:
3742         XSTRNCPY(str, "CRL Cert revoked", max);
3743         break;
3744
3745     case CRL_MISSING:
3746         XSTRNCPY(str, "CRL missing, not loaded", max);
3747         break;
3748
3749     case MONITOR_RUNNING_E:
3750         XSTRNCPY(str, "CRL monitor already running", max);
3751         break;
3752
3753     case THREAD_CREATE_E:
3754         XSTRNCPY(str, "Thread creation problem", max);
3755         break;
3756
3757     case OCSP_NEED_URL:
3758         XSTRNCPY(str, "OCSP need URL", max);
3759         break;
3760
3761     case OCSP_CERT_UNKNOWN:
3762         XSTRNCPY(str, "OCSP Cert unknown", max);
3763         break;
3764
3765     case OCSP_LOOKUP_FAIL:
3766         XSTRNCPY(str, "OCSP Responder lookup fail", max);
3767         break;
3768
3769     case MAX_CHAIN_ERROR:
3770         XSTRNCPY(str, "Maximum Chain Depth Exceeded", max);
3771         break;
3772
3773     case COOKIE_ERROR:
3774         XSTRNCPY(str, "DTLS Cookie Error", max);
3775         break;
3776
3777     default :
3778         XSTRNCPY(str, "unknown error number", max);
3779     }
3780
3781 #endif /* NO_ERROR_STRINGS */
3782 }
3783
3784
3785
3786 /* be sure to add to cipher_name_idx too !!!! */
3787 const char* const cipher_names[] = 
3788 {
3789 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
3790     "RC4-SHA",
3791 #endif
3792
3793 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
3794     "RC4-MD5",
3795 #endif
3796
3797 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
3798     "DES-CBC3-SHA",
3799 #endif
3800
3801 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
3802     "AES128-SHA",
3803 #endif
3804
3805 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
3806     "AES256-SHA",
3807 #endif
3808
3809 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
3810     "DHE-RSA-AES128-SHA",
3811 #endif
3812
3813 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
3814     "DHE-RSA-AES256-SHA",
3815 #endif
3816
3817 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
3818     "PSK-AES128-CBC-SHA",
3819 #endif
3820
3821 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
3822     "PSK-AES256-CBC-SHA",
3823 #endif
3824
3825 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
3826     "HC128-MD5",
3827 #endif
3828     
3829 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
3830     "HC128-SHA",
3831 #endif
3832
3833 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
3834     "RABBIT-SHA",
3835 #endif
3836
3837 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
3838     "NTRU-RC4-SHA",
3839 #endif
3840
3841 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
3842     "NTRU-DES-CBC3-SHA",
3843 #endif
3844
3845 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
3846     "NTRU-AES128-SHA",
3847 #endif
3848
3849 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
3850     "NTRU-AES256-SHA",
3851 #endif
3852
3853 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
3854     "ECDHE-RSA-AES128-SHA",
3855 #endif
3856
3857 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
3858     "ECDHE-RSA-AES256-SHA",
3859 #endif
3860
3861 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
3862     "ECDHE-ECDSA-AES128-SHA",
3863 #endif
3864
3865 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
3866     "ECDHE-ECDSA-AES256-SHA",
3867 #endif
3868
3869 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
3870     "ECDHE-RSA-RC4-SHA",
3871 #endif
3872
3873 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
3874     "ECDHE-RSA-DES-CBC3-SHA",
3875 #endif
3876
3877 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
3878     "ECDHE-ECDSA-RC4-SHA",
3879 #endif
3880
3881 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
3882     "ECDHE-ECDSA-DES-CBC3-SHA",
3883 #endif
3884
3885 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
3886     "AES128-SHA256",
3887 #endif
3888
3889 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
3890     "AES256-SHA256",
3891 #endif
3892
3893 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
3894     "DHE-RSA-AES128-SHA256",
3895 #endif
3896
3897 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
3898     "DHE-RSA-AES256-SHA256",
3899 #endif
3900
3901 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
3902     "ECDH-RSA-AES128-SHA",
3903 #endif
3904
3905 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
3906     "ECDH-RSA-AES256-SHA",
3907 #endif
3908
3909 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
3910     "ECDH-ECDSA-AES128-SHA",
3911 #endif
3912
3913 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
3914     "ECDH-ECDSA-AES256-SHA",
3915 #endif
3916
3917 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
3918     "ECDH-RSA-RC4-SHA",
3919 #endif
3920
3921 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
3922     "ECDH-RSA-DES-CBC3-SHA",
3923 #endif
3924
3925 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
3926     "ECDH-ECDSA-RC4-SHA",
3927 #endif
3928
3929 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
3930     "ECDH-ECDSA-DES-CBC3-SHA",
3931 #endif
3932
3933 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
3934     "AES128-GCM-SHA256",
3935 #endif
3936
3937 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
3938     "AES256-GCM-SHA384",
3939 #endif
3940
3941 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
3942     "DHE-RSA-AES128-GCM-SHA256",
3943 #endif
3944
3945 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
3946     "DHE-RSA-AES256-GCM-SHA384",
3947 #endif
3948
3949 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
3950     "ECDHE-RSA-AES128-GCM-SHA256",
3951 #endif
3952
3953 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
3954     "ECDHE-RSA-AES256-GCM-SHA384",
3955 #endif
3956
3957 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
3958     "ECDHE-ECDSA-AES128-GCM-SHA256",
3959 #endif
3960
3961 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
3962     "ECDHE-ECDSA-AES256-GCM-SHA384",
3963 #endif
3964
3965 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
3966     "ECDH-RSA-AES128-GCM-SHA256",
3967 #endif
3968
3969 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
3970     "ECDH-RSA-AES256-GCM-SHA384",
3971 #endif
3972
3973 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
3974     "ECDH-ECDSA-AES128-GCM-SHA256",
3975 #endif
3976
3977 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
3978     "ECDH-ECDSA-AES256-GCM-SHA384"
3979 #endif
3980
3981 };
3982
3983
3984
3985 /* cipher suite number that matches above name table */
3986 int cipher_name_idx[] =
3987 {
3988
3989 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
3990     SSL_RSA_WITH_RC4_128_SHA,
3991 #endif
3992
3993 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
3994     SSL_RSA_WITH_RC4_128_MD5,
3995 #endif
3996
3997 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
3998     SSL_RSA_WITH_3DES_EDE_CBC_SHA,
3999 #endif
4000
4001 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
4002     TLS_RSA_WITH_AES_128_CBC_SHA,    
4003 #endif
4004
4005 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
4006     TLS_RSA_WITH_AES_256_CBC_SHA,
4007 #endif
4008
4009 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
4010     TLS_DHE_RSA_WITH_AES_128_CBC_SHA,    
4011 #endif
4012
4013 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
4014     TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
4015 #endif
4016
4017 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
4018     TLS_PSK_WITH_AES_128_CBC_SHA,    
4019 #endif
4020
4021 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
4022     TLS_PSK_WITH_AES_256_CBC_SHA,
4023 #endif
4024
4025 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
4026     TLS_RSA_WITH_HC_128_CBC_MD5,    
4027 #endif
4028
4029 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
4030     TLS_RSA_WITH_HC_128_CBC_SHA,    
4031 #endif
4032
4033 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
4034     TLS_RSA_WITH_RABBIT_CBC_SHA,    
4035 #endif
4036
4037 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
4038     TLS_NTRU_RSA_WITH_RC4_128_SHA,
4039 #endif
4040
4041 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
4042     TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA,
4043 #endif
4044
4045 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
4046     TLS_NTRU_RSA_WITH_AES_128_CBC_SHA,    
4047 #endif
4048
4049 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
4050     TLS_NTRU_RSA_WITH_AES_256_CBC_SHA,    
4051 #endif
4052
4053 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
4054     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,    
4055 #endif
4056
4057 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
4058     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
4059 #endif
4060
4061 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
4062     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,    
4063 #endif
4064
4065 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
4066     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
4067 #endif
4068
4069 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
4070     TLS_ECDHE_RSA_WITH_RC4_128_SHA,    
4071 #endif
4072
4073 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
4074     TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,    
4075 #endif
4076
4077 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
4078     TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,    
4079 #endif
4080
4081 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
4082     TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,    
4083 #endif
4084
4085 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
4086     TLS_RSA_WITH_AES_128_CBC_SHA256,    
4087 #endif
4088
4089 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
4090     TLS_RSA_WITH_AES_256_CBC_SHA256,
4091 #endif
4092
4093 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
4094     TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,    
4095 #endif
4096
4097 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
4098     TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
4099 #endif
4100
4101 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
4102     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
4103 #endif
4104
4105 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
4106     TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
4107 #endif
4108
4109 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
4110     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
4111 #endif
4112
4113 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
4114     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
4115 #endif
4116
4117 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
4118     TLS_ECDH_RSA_WITH_RC4_128_SHA,
4119 #endif
4120
4121 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
4122     TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
4123 #endif
4124
4125 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
4126     TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
4127 #endif
4128
4129 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
4130     TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
4131 #endif
4132
4133 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
4134     TLS_RSA_WITH_AES_128_GCM_SHA256,
4135 #endif
4136
4137 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
4138     TLS_RSA_WITH_AES_256_GCM_SHA384,
4139 #endif
4140
4141 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
4142     TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
4143 #endif
4144
4145 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
4146     TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
4147 #endif
4148
4149 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
4150     TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
4151 #endif
4152
4153 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
4154     TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
4155 #endif
4156
4157 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
4158     TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
4159 #endif
4160
4161 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
4162     TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
4163 #endif
4164
4165 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
4166     TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
4167 #endif
4168
4169 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
4170     TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
4171 #endif
4172
4173 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
4174     TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
4175 #endif
4176
4177 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
4178     TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
4179 #endif
4180
4181 };
4182
4183
4184 /* return true if set, else false */
4185 /* only supports full name from cipher_name[] delimited by : */
4186 int SetCipherList(Suites* s, const char* list)
4187 {
4188     int  ret = 0, i;
4189     char name[MAX_SUITE_NAME];
4190
4191     char  needle[] = ":";
4192     char* haystack = (char*)list;
4193     char* prev;
4194
4195     const int suiteSz = sizeof(cipher_names) / sizeof(cipher_names[0]);
4196     int idx = 0;
4197
4198     if (!list)
4199         return 0;
4200     
4201     if (*list == 0) return 1;   /* CyaSSL default */
4202
4203     if (XSTRNCMP(haystack, "ALL", 3) == 0) return 1;  /* CyaSSL defualt */
4204
4205     for(;;) {
4206         word32 len;
4207         prev = haystack;
4208         haystack = XSTRSTR(haystack, needle);
4209
4210         if (!haystack)    /* last cipher */
4211             len = min(sizeof(name), XSTRLEN(prev));
4212         else
4213             len = min(sizeof(name), (word32)(haystack - prev));
4214
4215         XSTRNCPY(name, prev, len);
4216         name[(len == sizeof(name)) ? len - 1 : len] = 0;
4217
4218         for (i = 0; i < suiteSz; i++)
4219             if (XSTRNCMP(name, cipher_names[i], sizeof(name)) == 0) {
4220                 if (XSTRSTR(name, "EC"))
4221                     s->suites[idx++] = ECC_BYTE;  /* ECC suite */
4222                 else
4223                     s->suites[idx++] = 0x00;      /* normal */
4224                 s->suites[idx++] = (byte)cipher_name_idx[i];
4225
4226                 if (!ret) ret = 1;   /* found at least one */
4227                 break;
4228             }
4229         if (!haystack) break;
4230         haystack++;
4231     }
4232
4233     if (ret) {
4234         s->setSuites = 1;
4235         s->suiteSz   = (word16)idx;
4236     }
4237
4238     return ret;
4239 }
4240
4241
4242 #ifdef CYASSL_CALLBACKS
4243
4244     /* Initialisze HandShakeInfo */
4245     void InitHandShakeInfo(HandShakeInfo* info)
4246     {
4247         int i;
4248
4249         info->cipherName[0] = 0;
4250         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
4251             info->packetNames[i][0] = 0;
4252         info->numberPackets = 0;
4253         info->negotiationError = 0;
4254     }
4255
4256     /* Set Final HandShakeInfo parameters */
4257     void FinishHandShakeInfo(HandShakeInfo* info, const CYASSL* ssl)
4258     {
4259         int i;
4260         int sz = sizeof(cipher_name_idx)/sizeof(int); 
4261
4262         for (i = 0; i < sz; i++)
4263             if (ssl->options.cipherSuite == (byte)cipher_name_idx[i]) {
4264                 if (ssl->options.cipherSuite0 == ECC_BYTE)
4265                     continue;   /* ECC suites at end */
4266                 XSTRNCPY(info->cipherName, cipher_names[i], MAX_CIPHERNAME_SZ);
4267                 break;
4268             }
4269
4270         /* error max and min are negative numbers */
4271         if (ssl->error <= MIN_PARAM_ERR && ssl->error >= MAX_PARAM_ERR)
4272             info->negotiationError = ssl->error;
4273     }
4274
4275    
4276     /* Add name to info packet names, increase packet name count */
4277     void AddPacketName(const char* name, HandShakeInfo* info)
4278     {
4279         if (info->numberPackets < MAX_PACKETS_HANDSHAKE) {
4280             XSTRNCPY(info->packetNames[info->numberPackets++], name,
4281                     MAX_PACKETNAME_SZ);
4282         }
4283     } 
4284
4285
4286     /* Initialisze TimeoutInfo */
4287     void InitTimeoutInfo(TimeoutInfo* info)
4288     {
4289         int i;
4290
4291         info->timeoutName[0] = 0;
4292         info->flags          = 0;
4293
4294         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++) {
4295             info->packets[i].packetName[0]     = 0;
4296             info->packets[i].timestamp.tv_sec  = 0;
4297             info->packets[i].timestamp.tv_usec = 0;
4298             info->packets[i].bufferValue       = 0;
4299             info->packets[i].valueSz           = 0;
4300         }
4301         info->numberPackets        = 0;
4302         info->timeoutValue.tv_sec  = 0;
4303         info->timeoutValue.tv_usec = 0;
4304     }
4305
4306
4307     /* Free TimeoutInfo */
4308     void FreeTimeoutInfo(TimeoutInfo* info, void* heap)
4309     {
4310         int i;
4311         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
4312             if (info->packets[i].bufferValue) {
4313                 XFREE(info->packets[i].bufferValue, heap, DYNAMIC_TYPE_INFO);
4314                 info->packets[i].bufferValue = 0;
4315             }
4316
4317     }
4318
4319
4320     /* Add PacketInfo to TimeoutInfo */
4321     void AddPacketInfo(const char* name, TimeoutInfo* info, const byte* data,
4322                        int sz, void* heap)
4323     {
4324         if (info->numberPackets < (MAX_PACKETS_HANDSHAKE - 1)) {
4325             Timeval currTime;
4326
4327             /* may add name after */
4328             if (name)
4329                 XSTRNCPY(info->packets[info->numberPackets].packetName, name,
4330                         MAX_PACKETNAME_SZ);
4331
4332             /* add data, put in buffer if bigger than static buffer */
4333             info->packets[info->numberPackets].valueSz = sz;
4334             if (sz < MAX_VALUE_SZ)
4335                 XMEMCPY(info->packets[info->numberPackets].value, data, sz);
4336             else {
4337                 info->packets[info->numberPackets].bufferValue =
4338                            XMALLOC(sz, heap, DYNAMIC_TYPE_INFO);
4339                 if (!info->packets[info->numberPackets].bufferValue)
4340                     /* let next alloc catch, just don't fill, not fatal here  */
4341                     info->packets[info->numberPackets].valueSz = 0;
4342                 else
4343                     XMEMCPY(info->packets[info->numberPackets].bufferValue,
4344                            data, sz);
4345             }
4346             gettimeofday(&currTime, 0);
4347             info->packets[info->numberPackets].timestamp.tv_sec  =
4348                                                              currTime.tv_sec;
4349             info->packets[info->numberPackets].timestamp.tv_usec =
4350                                                              currTime.tv_usec;
4351             info->numberPackets++;
4352         }
4353     }
4354
4355
4356     /* Add packet name to previsouly added packet info */
4357     void AddLateName(const char* name, TimeoutInfo* info)
4358     {
4359         /* make sure we have a valid previous one */
4360         if (info->numberPackets > 0 && info->numberPackets <
4361                                                         MAX_PACKETS_HANDSHAKE) {
4362             XSTRNCPY(info->packets[info->numberPackets - 1].packetName, name,
4363                     MAX_PACKETNAME_SZ);
4364         }
4365     }
4366
4367     /* Add record header to previsouly added packet info */
4368     void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info)
4369     {
4370         /* make sure we have a valid previous one */
4371         if (info->numberPackets > 0 && info->numberPackets <
4372                                                         MAX_PACKETS_HANDSHAKE) {
4373             if (info->packets[info->numberPackets - 1].bufferValue)
4374                 XMEMCPY(info->packets[info->numberPackets - 1].bufferValue, rl,
4375                        RECORD_HEADER_SZ);
4376             else
4377                 XMEMCPY(info->packets[info->numberPackets - 1].value, rl,
4378                        RECORD_HEADER_SZ);
4379         }
4380     }
4381
4382 #endif /* CYASSL_CALLBACKS */
4383
4384
4385
4386 /* client only parts */
4387 #ifndef NO_CYASSL_CLIENT
4388
4389     int SendClientHello(CYASSL* ssl)
4390     {
4391         byte              *output;
4392         word32             length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
4393         int                sendSz;
4394         int                idSz = ssl->options.resuming ? ID_LEN : 0;
4395         int                ret;
4396
4397         length = sizeof(ProtocolVersion) + RAN_LEN
4398                + idSz + ENUM_LEN                      
4399                + ssl->suites.suiteSz + SUITE_LEN
4400                + COMP_LEN + ENUM_LEN;
4401
4402         if (IsAtLeastTLSv1_2(ssl))
4403             length += HELLO_EXT_SZ;
4404
4405         sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
4406
4407 #ifdef CYASSL_DTLS
4408         if (ssl->options.dtls) {
4409             length += ENUM_LEN;   /* cookie */
4410             if (ssl->arrays.cookieSz != 0) length += ssl->arrays.cookieSz;
4411             sendSz  = length + DTLS_HANDSHAKE_HEADER_SZ + DTLS_RECORD_HEADER_SZ;
4412             idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
4413         }
4414 #endif
4415
4416         /* check for avalaible size */
4417         if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
4418             return ret;
4419
4420         /* get ouput buffer */
4421         output = ssl->buffers.outputBuffer.buffer +
4422                  ssl->buffers.outputBuffer.length;
4423
4424         AddHeaders(output, length, client_hello, ssl);
4425
4426             /* client hello, first version */
4427         XMEMCPY(output + idx, &ssl->version, sizeof(ProtocolVersion));
4428         idx += sizeof(ProtocolVersion);
4429         ssl->chVersion = ssl->version;  /* store in case changed */
4430
4431             /* then random */
4432         if (ssl->options.connectState == CONNECT_BEGIN) {
4433             RNG_GenerateBlock(&ssl->rng, output + idx, RAN_LEN);
4434             
4435                 /* store random */
4436             XMEMCPY(ssl->arrays.clientRandom, output + idx, RAN_LEN);
4437         } else {
4438 #ifdef CYASSL_DTLS
4439                 /* send same random on hello again */
4440             XMEMCPY(output + idx, ssl->arrays.clientRandom, RAN_LEN);
4441 #endif
4442         }
4443         idx += RAN_LEN;
4444
4445             /* then session id */
4446         output[idx++] = (byte)idSz;
4447         if (idSz) {
4448             XMEMCPY(output + idx, ssl->session.sessionID, ID_LEN);
4449             idx += ID_LEN;
4450         }
4451         
4452             /* then DTLS cookie */
4453 #ifdef CYASSL_DTLS
4454         if (ssl->options.dtls) {
4455             byte cookieSz = ssl->arrays.cookieSz;
4456
4457             output[idx++] = cookieSz;
4458             if (cookieSz) {
4459                 XMEMCPY(&output[idx], ssl->arrays.cookie, cookieSz);
4460                 idx += cookieSz;
4461             }
4462         }
4463 #endif
4464             /* then cipher suites */
4465         c16toa(ssl->suites.suiteSz, output + idx);
4466         idx += 2;
4467         XMEMCPY(output + idx, &ssl->suites.suites, ssl->suites.suiteSz);
4468         idx += ssl->suites.suiteSz;
4469
4470             /* last, compression */
4471         output[idx++] = COMP_LEN;
4472         if (ssl->options.usingCompression)
4473             output[idx++] = ZLIB_COMPRESSION;
4474         else
4475             output[idx++] = NO_COMPRESSION;
4476
4477         if (IsAtLeastTLSv1_2(ssl))
4478         {
4479             /* add in the extensions length */
4480             c16toa(HELLO_EXT_LEN, output + idx);
4481             idx += 2;
4482
4483             c16toa(HELLO_EXT_SIG_ALGO, output + idx);
4484             idx += 2;
4485             c16toa(HELLO_EXT_SIGALGO_SZ, output + idx);
4486             idx += 2;
4487             /* This is a lazy list setup. Eventually, we'll need to support
4488              * using other hash types or even other extensions. */
4489             c16toa(HELLO_EXT_SIGALGO_LEN, output + idx);
4490             idx += 2;
4491             output[idx++] = sha_mac;
4492             output[idx++] = rsa_sa_algo;
4493             output[idx++] = sha_mac;
4494             output[idx++] = dsa_sa_algo;
4495             output[idx++] = sha_mac;
4496             output[idx++] = ecc_dsa_sa_algo;
4497         }
4498
4499         HashOutput(ssl, output, sendSz, 0);
4500
4501         ssl->options.clientState = CLIENT_HELLO_COMPLETE;
4502
4503 #ifdef CYASSL_CALLBACKS
4504         if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
4505         if (ssl->toInfoOn)
4506             AddPacketInfo("ClientHello", &ssl->timeoutInfo, output, sendSz,
4507                           ssl->heap);
4508 #endif
4509
4510         ssl->buffers.outputBuffer.length += sendSz;
4511
4512         return SendBuffered(ssl);
4513     }
4514
4515
4516     static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input,
4517                                     word32* inOutIdx)
4518     {
4519         ProtocolVersion pv;
4520         byte            cookieSz;
4521         
4522 #ifdef CYASSL_CALLBACKS
4523         if (ssl->hsInfoOn) AddPacketName("HelloVerifyRequest",
4524                                          &ssl->handShakeInfo);
4525         if (ssl->toInfoOn) AddLateName("HelloVerifyRequest", &ssl->timeoutInfo);
4526 #endif
4527         XMEMCPY(&pv, input + *inOutIdx, sizeof(pv));
4528         *inOutIdx += sizeof(pv);
4529         
4530         cookieSz = input[(*inOutIdx)++];
4531         
4532         if (cookieSz) {
4533 #ifdef CYASSL_DTLS
4534             if (cookieSz < MAX_COOKIE_LEN) {
4535                 XMEMCPY(ssl->arrays.cookie, input + *inOutIdx, cookieSz);
4536                 ssl->arrays.cookieSz = cookieSz;
4537             }
4538 #endif
4539             *inOutIdx += cookieSz;
4540         }
4541         
4542         ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
4543         return 0;
4544     }
4545
4546
4547     static int DoServerHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
4548                              word32 helloSz)
4549     {
4550         byte b;
4551         byte compression;
4552         ProtocolVersion pv;
4553         word32 i = *inOutIdx;
4554         word32 begin = i;
4555
4556 #ifdef CYASSL_CALLBACKS
4557         if (ssl->hsInfoOn) AddPacketName("ServerHello", &ssl->handShakeInfo);
4558         if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
4559 #endif
4560         XMEMCPY(&pv, input + i, sizeof(pv));
4561         i += sizeof(pv);
4562         if (pv.minor > ssl->version.minor) {
4563             CYASSL_MSG("Server using higher version, fatal error");
4564             return VERSION_ERROR;
4565         }
4566         else if (pv.minor < ssl->version.minor) {
4567             CYASSL_MSG("server using lower version");
4568             if (!ssl->options.downgrade) {
4569                 CYASSL_MSG("    no downgrade allowed, fatal error");
4570                 return VERSION_ERROR;
4571             }
4572             else if (pv.minor == SSLv3_MINOR) {
4573                 /* turn off tls */
4574                 CYASSL_MSG("    downgrading to SSLv3");
4575                 ssl->options.tls    = 0;
4576                 ssl->options.tls1_1 = 0;
4577                 ssl->version.minor  = SSLv3_MINOR;
4578             }
4579             else if (pv.minor == TLSv1_MINOR) {
4580                 /* turn off tls 1.1+ */
4581                 CYASSL_MSG("    downgrading to TLSv1");
4582                 ssl->options.tls1_1 = 0;
4583                 ssl->version.minor  = TLSv1_MINOR;
4584             }
4585             else if (pv.minor == TLSv1_1_MINOR) {
4586                 CYASSL_MSG("    downgrading to TLSv1.1");
4587                 ssl->version.minor  = TLSv1_1_MINOR;
4588             }
4589         }
4590         XMEMCPY(ssl->arrays.serverRandom, input + i, RAN_LEN);
4591         i += RAN_LEN;
4592         b = input[i++];
4593         if (b) {
4594             XMEMCPY(ssl->arrays.sessionID, input + i, min(b, ID_LEN));
4595             i += b;
4596             ssl->options.haveSessionId = 1;
4597         }
4598         ssl->options.cipherSuite0 = input[i++];
4599         ssl->options.cipherSuite  = input[i++];  
4600         compression = input[i++];
4601
4602         if (compression != ZLIB_COMPRESSION && ssl->options.usingCompression) {
4603             CYASSL_MSG("Server refused compression, turning off"); 
4604             ssl->options.usingCompression = 0;  /* turn off if server refused */
4605         }
4606
4607         *inOutIdx = i;
4608         if ( (i - begin) < helloSz)
4609             *inOutIdx = begin + helloSz;  /* skip extensions */
4610
4611         ssl->options.serverState = SERVER_HELLO_COMPLETE;
4612
4613         *inOutIdx = i;
4614
4615         if (ssl->options.resuming) {
4616             if (ssl->options.haveSessionId && XMEMCMP(ssl->arrays.sessionID,
4617                                          ssl->session.sessionID, ID_LEN) == 0) {
4618                 if (SetCipherSpecs(ssl) == 0) {
4619                     int ret; 
4620                     XMEMCPY(ssl->arrays.masterSecret, ssl->session.masterSecret,
4621                            SECRET_LEN);
4622                     if (ssl->options.tls)
4623                         ret = DeriveTlsKeys(ssl);
4624                     else
4625                         ret = DeriveKeys(ssl);
4626                     ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
4627                     return ret;
4628                 }
4629                 else {
4630                     CYASSL_MSG("Unsupported cipher suite, DoServerHello");
4631                     return UNSUPPORTED_SUITE;
4632                 }
4633             }
4634             else {
4635                 CYASSL_MSG("Server denied resumption attempt"); 
4636                 ssl->options.resuming = 0; /* server denied resumption try */
4637             }
4638         }
4639
4640         return SetCipherSpecs(ssl);
4641     }
4642
4643
4644     /* just read in and ignore for now TODO: */
4645     static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32*
4646                                     inOutIdx)
4647     {
4648         word16 len;
4649        
4650         #ifdef CYASSL_CALLBACKS
4651             if (ssl->hsInfoOn)
4652                 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
4653             if (ssl->toInfoOn)
4654                 AddLateName("CertificateRequest", &ssl->timeoutInfo);
4655         #endif
4656         len = input[(*inOutIdx)++];
4657
4658         /* types, read in here */
4659         *inOutIdx += len;
4660         ato16(&input[*inOutIdx], &len);
4661         *inOutIdx += LENGTH_SZ;
4662
4663         if (IsAtLeastTLSv1_2(ssl)) {
4664             /* hash sig format */
4665             *inOutIdx += len;
4666             ato16(&input[*inOutIdx], &len);
4667             *inOutIdx += LENGTH_SZ;
4668         }
4669
4670         /* authorities */
4671         while (len) {
4672             word16 dnSz;
4673        
4674             ato16(&input[*inOutIdx], &dnSz);
4675             *inOutIdx += (REQUEST_HEADER + dnSz);
4676             len -= dnSz + REQUEST_HEADER;
4677         }
4678
4679         /* don't send client cert or cert verify if user hasn't provided
4680            cert and private key */
4681         if (ssl->buffers.certificate.buffer && ssl->buffers.key.buffer)
4682             ssl->options.sendVerify = SEND_CERT;
4683         else if (IsAtLeastTLSv1_2(ssl))
4684             ssl->options.sendVerify = SEND_BLANK_CERT;
4685
4686         return 0;
4687     }
4688
4689
4690     static int DoServerKeyExchange(CYASSL* ssl, const byte* input,
4691                                    word32* inOutIdx)
4692     {
4693     #if defined(OPENSSL_EXTRA) || defined(HAVE_ECC)
4694         word16 length    = 0;
4695         word16 sigLen    = 0;
4696         word16 verifySz  = (word16)*inOutIdx;  /* keep start idx */
4697         byte*  signature = 0;
4698     #endif 
4699
4700         (void)ssl;
4701         (void)input;
4702         (void)inOutIdx;
4703
4704     #ifdef CYASSL_CALLBACKS
4705         if (ssl->hsInfoOn)
4706             AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
4707         if (ssl->toInfoOn)
4708             AddLateName("ServerKeyExchange", &ssl->timeoutInfo);
4709     #endif
4710
4711     #ifndef NO_PSK
4712         if (ssl->specs.kea == psk_kea) {
4713             word16 pskLen = 0;
4714             ato16(&input[*inOutIdx], &pskLen);
4715             *inOutIdx += LENGTH_SZ;
4716             XMEMCPY(ssl->arrays.server_hint, &input[*inOutIdx],
4717                    min(pskLen, MAX_PSK_ID_LEN));
4718             if (pskLen < MAX_PSK_ID_LEN)
4719                 ssl->arrays.server_hint[pskLen] = 0;
4720             else
4721                 ssl->arrays.server_hint[MAX_PSK_ID_LEN - 1] = 0;
4722             *inOutIdx += pskLen;
4723
4724             return 0;
4725         }
4726     #endif
4727     #ifdef OPENSSL_EXTRA
4728         if (ssl->specs.kea == diffie_hellman_kea)
4729         {
4730         /* p */
4731         ato16(&input[*inOutIdx], &length);
4732         *inOutIdx += LENGTH_SZ;
4733
4734         ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
4735                                                          DYNAMIC_TYPE_DH);
4736         if (ssl->buffers.serverDH_P.buffer)
4737             ssl->buffers.serverDH_P.length = length;
4738         else
4739             return MEMORY_ERROR;
4740         XMEMCPY(ssl->buffers.serverDH_P.buffer, &input[*inOutIdx], length);
4741         *inOutIdx += length;
4742
4743         /* g */
4744         ato16(&input[*inOutIdx], &length);
4745         *inOutIdx += LENGTH_SZ;
4746
4747         ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
4748                                                          DYNAMIC_TYPE_DH);
4749         if (ssl->buffers.serverDH_G.buffer)
4750             ssl->buffers.serverDH_G.length = length;
4751         else
4752             return MEMORY_ERROR;
4753         XMEMCPY(ssl->buffers.serverDH_G.buffer, &input[*inOutIdx], length);
4754         *inOutIdx += length;
4755
4756         /* pub */
4757         ato16(&input[*inOutIdx], &length);
4758         *inOutIdx += LENGTH_SZ;
4759
4760         ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap,
4761                                                            DYNAMIC_TYPE_DH);
4762         if (ssl->buffers.serverDH_Pub.buffer)
4763             ssl->buffers.serverDH_Pub.length = length;
4764         else
4765             return MEMORY_ERROR;
4766         XMEMCPY(ssl->buffers.serverDH_Pub.buffer, &input[*inOutIdx], length);
4767         *inOutIdx += length;
4768         }  /* dh_kea */
4769     #endif /* OPENSSL_EXTRA */
4770
4771     #ifdef HAVE_ECC
4772         if (ssl->specs.kea == ecc_diffie_hellman_kea)
4773         {
4774         byte b = input[*inOutIdx];
4775         *inOutIdx += 1;
4776
4777         if (b != named_curve)
4778             return ECC_CURVETYPE_ERROR;
4779
4780         *inOutIdx += 1;   /* curve type, eat leading 0 */
4781         b = input[*inOutIdx];
4782         *inOutIdx += 1;
4783
4784         if (b != secp256r1 && b != secp384r1 && b != secp521r1 && b !=
4785                  secp160r1 && b != secp192r1 && b != secp224r1)
4786             return ECC_CURVE_ERROR;
4787
4788         length = input[*inOutIdx];
4789         *inOutIdx += 1;
4790
4791         if (ecc_import_x963(&input[*inOutIdx], length, &ssl->peerEccKey) != 0)
4792             return ECC_PEERKEY_ERROR;
4793
4794         *inOutIdx += length;
4795         ssl->peerEccKeyPresent = 1;
4796         }
4797     #endif /* HAVE_ECC */
4798
4799     #if defined(OPENSSL_EXTRA) || defined(HAVE_ECC)
4800     {
4801         Md5    md5;
4802         Sha    sha;
4803         byte   hash[FINISHED_SZ];
4804         byte   messageVerify[MAX_DH_SZ];
4805
4806         /* adjust from start idx */
4807         verifySz = (word16)(*inOutIdx - verifySz);
4808
4809         /* save message for hash verify */
4810         if (verifySz > sizeof(messageVerify))
4811             return BUFFER_ERROR;
4812         XMEMCPY(messageVerify, &input[*inOutIdx - verifySz], verifySz);
4813
4814         if (IsAtLeastTLSv1_2(ssl)) {
4815             /* just advance for now TODO: validate hash algo params */
4816             *inOutIdx += LENGTH_SZ;
4817         }
4818
4819         /* signature */
4820         ato16(&input[*inOutIdx], &length);
4821         *inOutIdx += LENGTH_SZ;
4822
4823         signature = (byte*)&input[*inOutIdx];
4824         *inOutIdx += length;
4825         sigLen = length;
4826
4827         /* verify signature */
4828
4829         /* md5 */
4830         InitMd5(&md5);
4831         Md5Update(&md5, ssl->arrays.clientRandom, RAN_LEN);
4832         Md5Update(&md5, ssl->arrays.serverRandom, RAN_LEN);
4833         Md5Update(&md5, messageVerify, verifySz);
4834         Md5Final(&md5, hash);
4835
4836         /* sha */
4837         InitSha(&sha);
4838         ShaUpdate(&sha, ssl->arrays.clientRandom, RAN_LEN);
4839         ShaUpdate(&sha, ssl->arrays.serverRandom, RAN_LEN);
4840         ShaUpdate(&sha, messageVerify, verifySz);
4841         ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
4842
4843         /* rsa */
4844         if (ssl->specs.sig_algo == rsa_sa_algo)
4845         {
4846             int   ret;
4847             byte* out;
4848
4849             if (!ssl->peerRsaKeyPresent)
4850                 return NO_PEER_KEY;
4851
4852             ret = RsaSSL_VerifyInline(signature, sigLen,&out, &ssl->peerRsaKey);
4853
4854             if (IsAtLeastTLSv1_2(ssl)) {
4855                 byte   encodedSig[MAX_ENCODED_SIG_SZ];
4856                 word32 encSigSz;
4857                 byte*  digest;
4858                 int    typeH;
4859                 int    digestSz;
4860
4861                 /* sha1 for now */
4862                 digest   = &hash[MD5_DIGEST_SIZE];
4863                 typeH    = SHAh;
4864                 digestSz = SHA_DIGEST_SIZE;
4865
4866                 encSigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
4867
4868                 if (encSigSz != (word32)ret || XMEMCMP(out, encodedSig,
4869                                         min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0)
4870                     return VERIFY_SIGN_ERROR;
4871             }
4872             else { 
4873                 if (ret != sizeof(hash) || XMEMCMP(out, hash, sizeof(hash)))
4874                     return VERIFY_SIGN_ERROR;
4875             }
4876         }
4877 #ifdef HAVE_ECC
4878         /* ecdsa */
4879         else if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
4880             int verify = 0, ret;
4881             if (!ssl->peerEccDsaKeyPresent)
4882                 return NO_PEER_KEY;
4883
4884             ret = ecc_verify_hash(signature, sigLen, &hash[MD5_DIGEST_SIZE],
4885                                  SHA_DIGEST_SIZE, &verify, &ssl->peerEccDsaKey);
4886             if (ret != 0 || verify == 0)
4887                 return VERIFY_SIGN_ERROR;
4888         }
4889 #endif /* HAVE_ECC */
4890         else
4891             return ALGO_ID_E;
4892
4893         ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
4894
4895         return 0;
4896
4897     }
4898 #else  /* HAVE_OPENSSL or HAVE_ECC */
4899         return NOT_COMPILED_IN;  /* not supported by build */
4900 #endif /* HAVE_OPENSSL or HAVE_ECC */
4901     }
4902
4903
4904     int SendClientKeyExchange(CYASSL* ssl)
4905     {
4906         byte   encSecret[MAX_NTRU_ENCRYPT_SZ];
4907         word32 encSz = 0;
4908         word32 idx = 0;
4909         int    ret = 0;
4910
4911         if (ssl->specs.kea == rsa_kea) {
4912             RNG_GenerateBlock(&ssl->rng, ssl->arrays.preMasterSecret,
4913                               SECRET_LEN);
4914             ssl->arrays.preMasterSecret[0] = ssl->chVersion.major;
4915             ssl->arrays.preMasterSecret[1] = ssl->chVersion.minor;
4916             ssl->arrays.preMasterSz = SECRET_LEN;
4917
4918             if (ssl->peerRsaKeyPresent == 0)
4919                 return NO_PEER_KEY;
4920
4921             ret = RsaPublicEncrypt(ssl->arrays.preMasterSecret, SECRET_LEN,
4922                              encSecret, sizeof(encSecret), &ssl->peerRsaKey,
4923                              &ssl->rng);
4924             if (ret > 0) {
4925                 encSz = ret;
4926                 ret = 0;   /* set success to 0 */
4927             }
4928         #ifdef OPENSSL_EXTRA
4929         } else if (ssl->specs.kea == diffie_hellman_kea) {
4930             buffer  serverP   = ssl->buffers.serverDH_P;
4931             buffer  serverG   = ssl->buffers.serverDH_G;
4932             buffer  serverPub = ssl->buffers.serverDH_Pub;
4933             byte    priv[ENCRYPT_LEN];
4934             word32  privSz = 0;
4935             DhKey   key;
4936
4937             if (serverP.buffer == 0 || serverG.buffer == 0 ||
4938                                        serverPub.buffer == 0)
4939                 return NO_PEER_KEY;
4940
4941             InitDhKey(&key);
4942             ret = DhSetKey(&key, serverP.buffer, serverP.length,
4943                            serverG.buffer, serverG.length);
4944             if (ret == 0)
4945                 /* for DH, encSecret is Yc, agree is pre-master */
4946                 ret = DhGenerateKeyPair(&key, &ssl->rng, priv, &privSz,
4947                                         encSecret, &encSz);
4948             if (ret == 0)
4949                 ret = DhAgree(&key, ssl->arrays.preMasterSecret,
4950                               &ssl->arrays.preMasterSz, priv, privSz,
4951                               serverPub.buffer, serverPub.length);
4952             FreeDhKey(&key);
4953         #endif /* OPENSSL_EXTRA */
4954         #ifndef NO_PSK
4955         } else if (ssl->specs.kea == psk_kea) {
4956             byte* pms = ssl->arrays.preMasterSecret;
4957
4958             ssl->arrays.psk_keySz = ssl->options.client_psk_cb(ssl,
4959                 ssl->arrays.server_hint, ssl->arrays.client_identity,
4960                 MAX_PSK_ID_LEN, ssl->arrays.psk_key, MAX_PSK_KEY_LEN);
4961             if (ssl->arrays.psk_keySz == 0 || 
4962                 ssl->arrays.psk_keySz > MAX_PSK_KEY_LEN)
4963                 return PSK_KEY_ERROR;
4964             encSz = (word32)XSTRLEN(ssl->arrays.client_identity);
4965             if (encSz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR;
4966             XMEMCPY(encSecret, ssl->arrays.client_identity, encSz);
4967
4968             /* make psk pre master secret */
4969             /* length of key + length 0s + length of key + key */
4970             c16toa((word16)ssl->arrays.psk_keySz, pms);
4971             pms += 2;
4972             XMEMSET(pms, 0, ssl->arrays.psk_keySz);
4973             pms += ssl->arrays.psk_keySz;
4974             c16toa((word16)ssl->arrays.psk_keySz, pms);
4975             pms += 2;
4976             XMEMCPY(pms, ssl->arrays.psk_key, ssl->arrays.psk_keySz);
4977             ssl->arrays.preMasterSz = ssl->arrays.psk_keySz * 2 + 4;
4978         #endif /* NO_PSK */
4979         #ifdef HAVE_NTRU
4980         } else if (ssl->specs.kea == ntru_kea) {
4981             word32 rc;
4982             word16 cipherLen = sizeof(encSecret);
4983             DRBG_HANDLE drbg;
4984             static uint8_t const cyasslStr[] = {
4985                 'C', 'y', 'a', 'S', 'S', 'L', ' ', 'N', 'T', 'R', 'U'
4986             };
4987
4988             RNG_GenerateBlock(&ssl->rng, ssl->arrays.preMasterSecret,
4989                               SECRET_LEN);
4990             ssl->arrays.preMasterSz = SECRET_LEN;
4991
4992             if (ssl->peerNtruKeyPresent == 0)
4993                 return NO_PEER_KEY;
4994
4995             rc = crypto_drbg_instantiate(MAX_NTRU_BITS, cyasslStr,
4996                                           sizeof(cyasslStr), GetEntropy, &drbg);
4997             if (rc != DRBG_OK)
4998                 return NTRU_DRBG_ERROR; 
4999
5000             rc = crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen,ssl->peerNtruKey,
5001                                      ssl->arrays.preMasterSz,
5002                                      ssl->arrays.preMasterSecret,
5003                                      &cipherLen, encSecret);
5004             crypto_drbg_uninstantiate(drbg);
5005             if (rc != NTRU_OK)
5006                 return NTRU_ENCRYPT_ERROR;
5007
5008             encSz = cipherLen;
5009             ret = 0;
5010         #endif /* HAVE_NTRU */
5011         #ifdef HAVE_ECC
5012         } else if (ssl->specs.kea == ecc_diffie_hellman_kea) {
5013             ecc_key  myKey;
5014             ecc_key* peerKey = &myKey;
5015             word32   size = sizeof(encSecret);
5016
5017             if (ssl->specs.static_ecdh) {
5018                 /* TODO: EccDsa is really fixed Ecc change naming */
5019                 if (!ssl->peerEccDsaKeyPresent || !ssl->peerEccDsaKey.dp)
5020                     return NO_PEER_KEY;
5021                 peerKey = &ssl->peerEccDsaKey;
5022             }
5023             else {
5024                 if (!ssl->peerEccKeyPresent || !ssl->peerEccKey.dp)
5025                     return NO_PEER_KEY;
5026                 peerKey = &ssl->peerEccKey;
5027             }
5028
5029             ecc_init(&myKey);
5030             ret = ecc_make_key(&ssl->rng, peerKey->dp->size, &myKey);
5031             if (ret != 0)
5032                 return ECC_MAKEKEY_ERROR;
5033
5034             /* precede export with 1 byte length */
5035             ret = ecc_export_x963(&myKey, encSecret + 1, &size);
5036             encSecret[0] = (byte)size;
5037             encSz = size + 1;
5038
5039             if (ret != 0)
5040                 ret = ECC_EXPORT_ERROR;
5041             else {
5042                 size = sizeof(ssl->arrays.preMasterSecret);
5043                 ret  = ecc_shared_secret(&myKey, peerKey,
5044                                          ssl->arrays.preMasterSecret, &size);
5045                 if (ret != 0)
5046                     ret = ECC_SHARED_ERROR;
5047             }
5048
5049             ssl->arrays.preMasterSz = size;
5050             ecc_free(&myKey);
5051         #endif /* HAVE_ECC */
5052         } else
5053             return ALGO_ID_E; /* unsupported kea */
5054
5055         if (ret == 0) {
5056             byte              *output;
5057             int                sendSz;
5058             word32             tlsSz = 0;
5059             
5060             if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea)
5061                 tlsSz = 2;
5062
5063             if (ssl->specs.kea == ecc_diffie_hellman_kea)  /* always off */
5064                 tlsSz = 0;
5065
5066             sendSz = encSz + tlsSz + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
5067             idx    = HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
5068
5069             #ifdef CYASSL_DTLS
5070                 if (ssl->options.dtls) {
5071                     sendSz += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
5072                     idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
5073                 }
5074             #endif
5075
5076             /* check for avalaible size */
5077             if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
5078                 return ret;
5079
5080             /* get ouput buffer */
5081             output = ssl->buffers.outputBuffer.buffer + 
5082                      ssl->buffers.outputBuffer.length;
5083
5084             AddHeaders(output, encSz + tlsSz, client_key_exchange, ssl);
5085
5086             if (tlsSz) {
5087                 c16toa((word16)encSz, &output[idx]);
5088                 idx += 2;
5089             }
5090             XMEMCPY(output + idx, encSecret, encSz);
5091             idx += encSz;
5092
5093             HashOutput(ssl, output, sendSz, 0);
5094
5095             #ifdef CYASSL_CALLBACKS
5096                 if (ssl->hsInfoOn)
5097                     AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
5098                 if (ssl->toInfoOn)
5099                     AddPacketInfo("ClientKeyExchange", &ssl->timeoutInfo,
5100                                   output, sendSz, ssl->heap);
5101             #endif
5102
5103             ssl->buffers.outputBuffer.length += sendSz;
5104
5105             if (ssl->options.groupMessages)
5106                 ret = 0;
5107             else
5108                 ret = SendBuffered(ssl);
5109         }
5110     
5111         if (ret == 0 || ret == WANT_WRITE) {
5112             int tmpRet = MakeMasterSecret(ssl);
5113             if (tmpRet != 0)
5114                 ret = tmpRet;   /* save WANT_WRITE unless more serious */
5115             ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
5116         }
5117
5118         return ret;
5119     }
5120
5121     int SendCertificateVerify(CYASSL* ssl)
5122     {
5123         byte              *output;
5124         int                sendSz = 0, length, ret;
5125         word32             idx = 0;
5126         word32             sigOutSz = 0;
5127         RsaKey             key;
5128         int                usingEcc = 0;
5129 #ifdef HAVE_ECC
5130         ecc_key            eccKey;
5131 #endif
5132
5133         if (ssl->options.sendVerify == SEND_BLANK_CERT)
5134             return 0;  /* sent blank cert, can't verify */
5135
5136         /* check for avalaible size */
5137         if ((ret = CheckAvalaibleSize(ssl, MAX_CERT_VERIFY_SZ)) != 0)
5138             return ret;
5139
5140         /* get ouput buffer */
5141         output = ssl->buffers.outputBuffer.buffer +
5142                  ssl->buffers.outputBuffer.length;
5143
5144         BuildCertHashes(ssl, &ssl->certHashes);
5145
5146 #ifdef HAVE_ECC
5147         ecc_init(&eccKey);
5148 #endif
5149         InitRsaKey(&key, ssl->heap);
5150         ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
5151                                   ssl->buffers.key.length);
5152         if (ret == 0)
5153             sigOutSz = RsaEncryptSize(&key);
5154         else {
5155     #ifdef HAVE_ECC
5156             CYASSL_MSG("Trying ECC client cert, RSA didn't work");
5157            
5158             idx = 0; 
5159             ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &eccKey,
5160                                       ssl->buffers.key.length);
5161             if (ret == 0) {
5162                 CYASSL_MSG("Using ECC client cert");
5163                 usingEcc = 1;
5164                 sigOutSz = ecc_sig_size(&eccKey);
5165             }
5166             else {
5167                 CYASSL_MSG("Bad client cert type");
5168             }
5169     #endif
5170         }
5171         if (ret == 0) {
5172             byte*  verify = (byte*)&output[RECORD_HEADER_SZ +
5173                                            HANDSHAKE_HEADER_SZ];
5174             byte*  signBuffer = ssl->certHashes.md5;
5175             word32 signSz = sizeof(Hashes);
5176             byte   encodedSig[MAX_ENCODED_SIG_SZ];
5177             word32 extraSz = 0;  /* tls 1.2 hash/sig */
5178
5179             #ifdef CYASSL_DTLS
5180                 if (ssl->options.dtls)
5181                     verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5182             #endif
5183             length = sigOutSz;
5184             if (IsAtLeastTLSv1_2(ssl)) {
5185                 verify[0] = sha_mac;
5186                 verify[1] = usingEcc ? ecc_dsa_sa_algo : rsa_sa_algo;
5187                 extraSz = HASH_SIG_SIZE;
5188             }
5189             c16toa((word16)length, verify + extraSz); /* prepend verify header*/
5190
5191             if (usingEcc) {
5192 #ifdef HAVE_ECC
5193                 word32 localSz = sigOutSz;
5194                 ret = ecc_sign_hash(signBuffer + MD5_DIGEST_SIZE,
5195                               SHA_DIGEST_SIZE, verify + extraSz + VERIFY_HEADER,
5196                               &localSz, &ssl->rng, &eccKey);
5197 #endif
5198             }
5199             else {
5200                 if (IsAtLeastTLSv1_2(ssl)) {
5201                     byte* digest;
5202                     int   typeH;
5203                     int   digestSz;
5204
5205                     /* sha1 for now */
5206                     digest   = ssl->certHashes.sha;
5207                     typeH    = SHAh;
5208                     digestSz = SHA_DIGEST_SIZE;
5209
5210                     signSz = EncodeSignature(encodedSig, digest,digestSz,typeH);
5211                     signBuffer = encodedSig;
5212                 }
5213
5214                 ret = RsaSSL_Sign(signBuffer, signSz, verify + extraSz +
5215                                   VERIFY_HEADER, ENCRYPT_LEN, &key, &ssl->rng);
5216
5217                 if (ret > 0)
5218                     ret = 0;  /* RSA reset */
5219             }
5220             
5221             if (ret == 0) {
5222                 AddHeaders(output, length + extraSz + VERIFY_HEADER,
5223                            certificate_verify, ssl);
5224
5225                 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + length +
5226                          extraSz + VERIFY_HEADER;
5227                 #ifdef CYASSL_DTLS
5228                     if (ssl->options.dtls)
5229                         sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5230                 #endif
5231                 HashOutput(ssl, output, sendSz, 0);
5232             }
5233         }
5234
5235         FreeRsaKey(&key);
5236 #ifdef HAVE_ECC
5237         ecc_free(&eccKey);
5238 #endif
5239
5240         if (ret == 0) {
5241             #ifdef CYASSL_CALLBACKS
5242                 if (ssl->hsInfoOn)
5243                     AddPacketName("CertificateVerify", &ssl->handShakeInfo);
5244                 if (ssl->toInfoOn)
5245                     AddPacketInfo("CertificateVerify", &ssl->timeoutInfo,
5246                                   output, sendSz, ssl->heap);
5247             #endif
5248             ssl->buffers.outputBuffer.length += sendSz;
5249             if (ssl->options.groupMessages)
5250                 return 0;
5251             else
5252                 return SendBuffered(ssl);
5253         }
5254         else
5255             return ret;
5256     }
5257
5258
5259
5260 #endif /* NO_CYASSL_CLIENT */
5261
5262
5263 #ifndef NO_CYASSL_SERVER
5264
5265     int SendServerHello(CYASSL* ssl)
5266     {
5267         byte              *output;
5268         word32             length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
5269         int                sendSz;
5270         int                ret;
5271
5272         length = sizeof(ProtocolVersion) + RAN_LEN
5273                + ID_LEN + ENUM_LEN                 
5274                + SUITE_LEN 
5275                + ENUM_LEN;
5276
5277         /* check for avalaible size */
5278         if ((ret = CheckAvalaibleSize(ssl, MAX_HELLO_SZ)) != 0)
5279             return ret;
5280
5281         /* get ouput buffer */
5282         output = ssl->buffers.outputBuffer.buffer + 
5283                  ssl->buffers.outputBuffer.length;
5284
5285         sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
5286         AddHeaders(output, length, server_hello, ssl);
5287
5288         #ifdef CYASSL_DTLS
5289             if (ssl->options.dtls) {
5290                 idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5291                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5292             }
5293         #endif
5294         /* now write to output */
5295             /* first version */
5296         XMEMCPY(output + idx, &ssl->version, sizeof(ProtocolVersion));
5297         idx += sizeof(ProtocolVersion);
5298
5299             /* then random */
5300         if (!ssl->options.resuming)         
5301             RNG_GenerateBlock(&ssl->rng, ssl->arrays.serverRandom, RAN_LEN);
5302         XMEMCPY(output + idx, ssl->arrays.serverRandom, RAN_LEN);
5303         idx += RAN_LEN;
5304
5305 #ifdef SHOW_SECRETS
5306         {
5307             int j;
5308             printf("server random: ");
5309             for (j = 0; j < RAN_LEN; j++)
5310                 printf("%02x", ssl->arrays.serverRandom[j]);
5311             printf("\n");
5312         }
5313 #endif
5314             /* then session id */
5315         output[idx++] = ID_LEN;
5316         if (!ssl->options.resuming)
5317             RNG_GenerateBlock(&ssl->rng, ssl->arrays.sessionID, ID_LEN);
5318         XMEMCPY(output + idx, ssl->arrays.sessionID, ID_LEN);
5319         idx += ID_LEN;
5320
5321             /* then cipher suite */
5322         output[idx++] = ssl->options.cipherSuite0; 
5323         output[idx++] = ssl->options.cipherSuite;
5324
5325             /* last, compression */
5326         if (ssl->options.usingCompression)
5327             output[idx++] = ZLIB_COMPRESSION;
5328         else
5329             output[idx++] = NO_COMPRESSION;
5330             
5331         ssl->buffers.outputBuffer.length += sendSz;
5332         HashOutput(ssl, output, sendSz, 0);
5333
5334         #ifdef CYASSL_CALLBACKS
5335             if (ssl->hsInfoOn)
5336                 AddPacketName("ServerHello", &ssl->handShakeInfo);
5337             if (ssl->toInfoOn)
5338                 AddPacketInfo("ServerHello", &ssl->timeoutInfo, output, sendSz,
5339                               ssl->heap);
5340         #endif
5341
5342         ssl->options.serverState = SERVER_HELLO_COMPLETE;
5343
5344         if (ssl->options.groupMessages)
5345             return 0;
5346         else
5347             return SendBuffered(ssl);
5348     }
5349
5350
5351 #ifdef HAVE_ECC
5352
5353     static byte SetCurveId(int size)
5354     {
5355         switch(size) {
5356             case 20:
5357                 return secp160r1;
5358                 break;
5359             case 24:
5360                 return secp192r1;
5361                 break;
5362             case 28:
5363                 return secp224r1;
5364                 break;
5365             case 32:
5366                 return secp256r1;
5367                 break;
5368             case 48:
5369                 return secp384r1;
5370                 break;
5371             case 66:
5372                 return secp521r1;
5373                 break;
5374             default:
5375                 return 0;
5376         }        
5377     }
5378
5379 #endif /* HAVE_ECC */
5380
5381
5382     int SendServerKeyExchange(CYASSL* ssl)
5383     {
5384         int ret = 0;
5385         (void)ssl;
5386
5387         #ifndef NO_PSK
5388         if (ssl->specs.kea == psk_kea)
5389         {
5390             byte    *output;
5391             word32   length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
5392             int      sendSz;
5393             if (ssl->arrays.server_hint[0] == 0) return 0; /* don't send */
5394
5395             /* include size part */
5396             length = (word32)XSTRLEN(ssl->arrays.server_hint);
5397             if (length > MAX_PSK_ID_LEN) return SERVER_HINT_ERROR;
5398             length += HINT_LEN_SZ;
5399             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
5400
5401             #ifdef CYASSL_DTLS 
5402                 if (ssl->options.dtls) {
5403                     sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5404                     idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5405                 }
5406             #endif
5407             /* check for avalaible size */
5408             if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
5409                return ret;
5410
5411             /* get ouput buffer */
5412             output = ssl->buffers.outputBuffer.buffer + 
5413                      ssl->buffers.outputBuffer.length;
5414
5415             AddHeaders(output, length, server_key_exchange, ssl);
5416
5417             /* key data */
5418             c16toa((word16)(length - HINT_LEN_SZ), output + idx);
5419             idx += HINT_LEN_SZ;
5420             XMEMCPY(output + idx, ssl->arrays.server_hint, length -HINT_LEN_SZ);
5421
5422             HashOutput(ssl, output, sendSz, 0);
5423
5424             #ifdef CYASSL_CALLBACKS
5425                 if (ssl->hsInfoOn)
5426                     AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
5427                 if (ssl->toInfoOn)
5428                     AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
5429                                   output, sendSz, ssl->heap);
5430             #endif
5431
5432             ssl->buffers.outputBuffer.length += sendSz;
5433             if (ssl->options.groupMessages)
5434                 ret = 0;
5435             else
5436                 ret = SendBuffered(ssl);
5437             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
5438         }
5439         #endif /*NO_PSK */
5440
5441         #ifdef HAVE_ECC
5442         if (ssl->specs.kea == ecc_diffie_hellman_kea)
5443         {
5444             byte    *output;
5445             word32   length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
5446             int      sendSz;
5447             byte     exportBuf[MAX_EXPORT_ECC_SZ];
5448             word32   expSz = sizeof(exportBuf);
5449             word32   sigSz;
5450             word32   preSigSz, preSigIdx;
5451             RsaKey   rsaKey;
5452             ecc_key  dsaKey;
5453
5454             if (ssl->specs.static_ecdh) {
5455                 CYASSL_MSG("Using Static ECDH, not sending ServerKeyExchagne");
5456                 return 0;
5457             }
5458
5459             /* curve type, named curve, length(1) */
5460             length = ENUM_LEN + CURVE_LEN + ENUM_LEN;
5461             /* pub key size */
5462             CYASSL_MSG("Using ephemeral ECDH");
5463             if (ecc_export_x963(&ssl->eccTempKey, exportBuf, &expSz) != 0)
5464                 return ECC_EXPORT_ERROR;
5465             length += expSz;
5466
5467             preSigSz  = length;
5468             preSigIdx = idx;
5469
5470             InitRsaKey(&rsaKey, ssl->heap);
5471             ecc_init(&dsaKey);
5472
5473             /* sig length */
5474             length += LENGTH_SZ;
5475
5476             if (!ssl->buffers.key.buffer) {
5477                 FreeRsaKey(&rsaKey);
5478                 ecc_free(&dsaKey);
5479                 return NO_PRIVATE_KEY;
5480             }
5481
5482             if (ssl->specs.sig_algo == rsa_sa_algo) {
5483                 /* rsa sig size */
5484                 word32 i = 0;
5485                 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i,
5486                                           &rsaKey, ssl->buffers.key.length);
5487                 if (ret != 0) return ret;
5488                 sigSz = RsaEncryptSize(&rsaKey); 
5489             }
5490             else if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
5491                 /* ecdsa sig size */
5492                 word32 i = 0;
5493                 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
5494                                           &dsaKey, ssl->buffers.key.length);
5495                 if (ret != 0) return ret;
5496                 sigSz = ecc_sig_size(&dsaKey);
5497             }
5498             else {
5499                 FreeRsaKey(&rsaKey);
5500                 ecc_free(&dsaKey);
5501                 return ALGO_ID_E;  /* unsupported type */
5502             }
5503             length += sigSz;
5504
5505             if (IsAtLeastTLSv1_2(ssl))
5506                 length += HASH_SIG_SIZE;
5507
5508             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
5509
5510             #ifdef CYASSL_DTLS 
5511                 if (ssl->options.dtls) {
5512                     sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5513                     idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5514                     preSigIdx = idx;
5515                 }
5516             #endif
5517             /* check for avalaible size */
5518             if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0) {
5519                 FreeRsaKey(&rsaKey);
5520                 ecc_free(&dsaKey); 
5521                 return ret;
5522             } 
5523
5524             /* get ouput buffer */
5525             output = ssl->buffers.outputBuffer.buffer + 
5526                      ssl->buffers.outputBuffer.length;
5527
5528             AddHeaders(output, length, server_key_exchange, ssl);
5529
5530             /* key exchange data */
5531             output[idx++] = named_curve;
5532             output[idx++] = 0x00;          /* leading zero */
5533             output[idx++] = SetCurveId(ecc_size(&ssl->eccTempKey)); 
5534             output[idx++] = (byte)expSz;
5535             XMEMCPY(output + idx, exportBuf, expSz);
5536             idx += expSz;
5537             if (IsAtLeastTLSv1_2(ssl)) {
5538                 output[idx++] = sha_mac;
5539                 output[idx++] = ssl->specs.sig_algo;
5540             }
5541             c16toa((word16)sigSz, output + idx);
5542             idx += LENGTH_SZ;
5543
5544             /* do signature */
5545             {
5546                 Md5    md5;
5547                 Sha    sha;
5548                 byte   hash[FINISHED_SZ];
5549                 byte*  signBuffer = hash;
5550                 word32 signSz    = sizeof(hash);
5551
5552                 /* md5 */
5553                 InitMd5(&md5);
5554                 Md5Update(&md5, ssl->arrays.clientRandom, RAN_LEN);
5555                 Md5Update(&md5, ssl->arrays.serverRandom, RAN_LEN);
5556                 Md5Update(&md5, output + preSigIdx, preSigSz);
5557                 Md5Final(&md5, hash);
5558
5559                 /* sha */
5560                 InitSha(&sha);
5561                 ShaUpdate(&sha, ssl->arrays.clientRandom, RAN_LEN);
5562                 ShaUpdate(&sha, ssl->arrays.serverRandom, RAN_LEN);
5563                 ShaUpdate(&sha, output + preSigIdx, preSigSz);
5564                 ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
5565
5566                 if (ssl->specs.sig_algo == rsa_sa_algo) {
5567                     byte encodedSig[MAX_ENCODED_SIG_SZ];
5568                     if (IsAtLeastTLSv1_2(ssl)) {
5569                         byte* digest;
5570                         int   hType;
5571                         int   digestSz;
5572
5573                         /* sha1 for now */
5574                         digest   = &hash[MD5_DIGEST_SIZE];
5575                         hType    = SHAh;
5576                         digestSz = SHA_DIGEST_SIZE;
5577
5578                         signSz = EncodeSignature(encodedSig, digest, digestSz,
5579                                                  hType);
5580                         signBuffer = encodedSig;
5581                     }
5582                     ret = RsaSSL_Sign(signBuffer, signSz, output + idx, sigSz,
5583                                       &rsaKey, &ssl->rng);
5584                     FreeRsaKey(&rsaKey);
5585                     ecc_free(&dsaKey);
5586                     if (ret > 0)
5587                         ret = 0;  /* reset on success */
5588                     else
5589                         return ret;
5590                 }
5591                 else if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
5592                     word32 sz = sigSz;
5593
5594                     ret = ecc_sign_hash(&hash[MD5_DIGEST_SIZE], SHA_DIGEST_SIZE,
5595                             output + idx, &sz, &ssl->rng, &dsaKey);
5596                     FreeRsaKey(&rsaKey);
5597                     ecc_free(&dsaKey);
5598                     if (ret < 0) return ret;
5599                 }
5600             }
5601
5602             HashOutput(ssl, output, sendSz, 0);
5603
5604             #ifdef CYASSL_CALLBACKS
5605                 if (ssl->hsInfoOn)
5606                     AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
5607                 if (ssl->toInfoOn)
5608                     AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
5609                                   output, sendSz, ssl->heap);
5610             #endif
5611
5612             ssl->buffers.outputBuffer.length += sendSz;
5613             if (ssl->options.groupMessages)
5614                 ret = 0;
5615             else
5616                 ret = SendBuffered(ssl);
5617             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
5618         }
5619         #endif /* HAVE_ECC */
5620
5621         #ifdef OPENSSL_EXTRA 
5622         if (ssl->specs.kea == diffie_hellman_kea) {
5623             byte    *output;
5624             word32   length = 0, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
5625             int      sendSz;
5626             word32   sigSz = 0, i = 0;
5627             word32   preSigSz = 0, preSigIdx = 0;
5628             RsaKey   rsaKey;
5629             DhKey    dhKey;
5630             
5631             if (ssl->buffers.serverDH_P.buffer == NULL ||
5632                 ssl->buffers.serverDH_G.buffer == NULL)
5633                 return NO_DH_PARAMS;
5634
5635             if (ssl->buffers.serverDH_Pub.buffer == NULL) {
5636                 ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
5637                         ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
5638                         DYNAMIC_TYPE_DH);
5639                 if (ssl->buffers.serverDH_Pub.buffer == NULL)
5640                     return MEMORY_E;
5641             } 
5642
5643             if (ssl->buffers.serverDH_Priv.buffer == NULL) {
5644                 ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
5645                         ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
5646                         DYNAMIC_TYPE_DH);
5647                 if (ssl->buffers.serverDH_Priv.buffer == NULL)
5648                     return MEMORY_E;
5649             } 
5650
5651             InitDhKey(&dhKey);
5652             ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
5653                                    ssl->buffers.serverDH_P.length,
5654                                    ssl->buffers.serverDH_G.buffer,
5655                                    ssl->buffers.serverDH_G.length);
5656             if (ret == 0)
5657                 ret = DhGenerateKeyPair(&dhKey, &ssl->rng,
5658                                          ssl->buffers.serverDH_Priv.buffer,
5659                                         &ssl->buffers.serverDH_Priv.length,
5660                                          ssl->buffers.serverDH_Pub.buffer,
5661                                         &ssl->buffers.serverDH_Pub.length);
5662             FreeDhKey(&dhKey);
5663
5664             if (ret == 0) {
5665                 length = LENGTH_SZ * 3;  /* p, g, pub */
5666                 length += ssl->buffers.serverDH_P.length +
5667                           ssl->buffers.serverDH_G.length + 
5668                           ssl->buffers.serverDH_Pub.length;
5669
5670                 preSigIdx = idx;
5671                 preSigSz  = length;
5672
5673                 /* sig length */
5674                 length += LENGTH_SZ;
5675
5676                 if (!ssl->buffers.key.buffer)
5677                     return NO_PRIVATE_KEY;
5678
5679                 InitRsaKey(&rsaKey, ssl->heap);
5680                 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i, &rsaKey,
5681                                           ssl->buffers.key.length);
5682                 if (ret == 0) {
5683                     sigSz = RsaEncryptSize(&rsaKey);
5684                     length += sigSz;
5685                 }
5686             }
5687             if (ret != 0) {
5688                 FreeRsaKey(&rsaKey);
5689                 return ret;
5690             }
5691                                          
5692             if (IsAtLeastTLSv1_2(ssl))
5693                 length += HASH_SIG_SIZE;
5694
5695             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
5696
5697             #ifdef CYASSL_DTLS 
5698                 if (ssl->options.dtls) {
5699                     sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5700                     idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5701                     preSigIdx = idx;
5702                 }
5703             #endif
5704             /* check for avalaible size */
5705             if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0) {
5706                 FreeRsaKey(&rsaKey);
5707                 return ret;
5708             } 
5709
5710             /* get ouput buffer */
5711             output = ssl->buffers.outputBuffer.buffer + 
5712                      ssl->buffers.outputBuffer.length;
5713
5714             AddHeaders(output, length, server_key_exchange, ssl);
5715
5716             /* add p, g, pub */
5717             c16toa((word16)ssl->buffers.serverDH_P.length, output + idx);
5718             idx += LENGTH_SZ;
5719             XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer,
5720                                   ssl->buffers.serverDH_P.length);
5721             idx += ssl->buffers.serverDH_P.length;
5722
5723             /*  g */
5724             c16toa((word16)ssl->buffers.serverDH_G.length, output + idx);
5725             idx += LENGTH_SZ;
5726             XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer,
5727                                   ssl->buffers.serverDH_G.length);
5728             idx += ssl->buffers.serverDH_G.length;
5729
5730             /*  pub */
5731             c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx);
5732             idx += LENGTH_SZ;
5733             XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer,
5734                                   ssl->buffers.serverDH_Pub.length);
5735             idx += ssl->buffers.serverDH_Pub.length;
5736
5737             /* Add signature */
5738             if (IsAtLeastTLSv1_2(ssl)) {
5739                 output[idx++] = sha_mac;
5740                 output[idx++] = ssl->specs.sig_algo; 
5741             }
5742             /*    size */
5743             c16toa((word16)sigSz, output + idx);
5744             idx += LENGTH_SZ;
5745
5746             /* do signature */
5747             {
5748                 Md5    md5;
5749                 Sha    sha;
5750                 byte   hash[FINISHED_SZ];
5751                 byte*  signBuffer = hash;
5752                 word32 signSz    = sizeof(hash);
5753
5754                 /* md5 */
5755                 InitMd5(&md5);
5756                 Md5Update(&md5, ssl->arrays.clientRandom, RAN_LEN);
5757                 Md5Update(&md5, ssl->arrays.serverRandom, RAN_LEN);
5758                 Md5Update(&md5, output + preSigIdx, preSigSz);
5759                 Md5Final(&md5, hash);
5760
5761                 /* sha */
5762                 InitSha(&sha);
5763                 ShaUpdate(&sha, ssl->arrays.clientRandom, RAN_LEN);
5764                 ShaUpdate(&sha, ssl->arrays.serverRandom, RAN_LEN);
5765                 ShaUpdate(&sha, output + preSigIdx, preSigSz);
5766                 ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
5767
5768                 if (ssl->specs.sig_algo == rsa_sa_algo) {
5769                     byte encodedSig[MAX_ENCODED_SIG_SZ];
5770                     if (IsAtLeastTLSv1_2(ssl)) {
5771                         byte* digest;
5772                         int   typeH;
5773                         int   digestSz;
5774
5775                         /* sha1 for now */
5776                         digest   = &hash[MD5_DIGEST_SIZE];
5777                         typeH    = SHAh;
5778                         digestSz = SHA_DIGEST_SIZE;
5779
5780                         signSz = EncodeSignature(encodedSig, digest, digestSz,
5781                                                  typeH);
5782                         signBuffer = encodedSig;
5783                     }
5784                     ret = RsaSSL_Sign(signBuffer, signSz, output + idx, sigSz,
5785                                       &rsaKey, &ssl->rng);
5786                     FreeRsaKey(&rsaKey);
5787                     if (ret > 0)
5788                         ret = 0;  /* reset on success */
5789                     else
5790                         return ret;
5791                 }
5792             }
5793
5794             HashOutput(ssl, output, sendSz, 0);
5795
5796             #ifdef CYASSL_CALLBACKS
5797                 if (ssl->hsInfoOn)
5798                     AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
5799                 if (ssl->toInfoOn)
5800                     AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
5801                                   output, sendSz, ssl->heap);
5802             #endif
5803
5804             ssl->buffers.outputBuffer.length += sendSz;
5805             if (ssl->options.groupMessages)
5806                 ret = 0;
5807             else
5808                 ret = SendBuffered(ssl);
5809             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
5810         }
5811         #endif /* OPENSSL_EXTRA */
5812
5813         return ret;
5814     }
5815
5816
5817     /* cipher requirements */
5818     enum {
5819         REQUIRES_RSA,
5820         REQUIRES_DHE,
5821         REQUIRES_ECC_DSA,
5822         REQUIRES_ECC_STATIC,
5823         REQUIRES_PSK,
5824         REQUIRES_NTRU,
5825         REQUIRES_RSA_SIG
5826     };
5827
5828
5829
5830     /* Does this cipher suite (first, second) have the requirement
5831        an ephemeral key exchange will still require the key for signing
5832        the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */
5833     static int CipherRequires(byte first, byte second, int requirement)
5834     {
5835         /* ECC extensions */
5836         if (first == ECC_BYTE) {
5837         
5838         switch (second) {
5839
5840         case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
5841             if (requirement == REQUIRES_RSA)
5842                 return 1;
5843             break;
5844
5845         case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
5846             if (requirement == REQUIRES_ECC_STATIC)
5847                 return 1;
5848             if (requirement == REQUIRES_RSA_SIG)
5849                 return 1;
5850             break;
5851
5852         case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
5853             if (requirement == REQUIRES_RSA)
5854                 return 1;
5855             break;
5856
5857         case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
5858             if (requirement == REQUIRES_ECC_STATIC)
5859                 return 1;
5860             if (requirement == REQUIRES_RSA_SIG)
5861                 return 1;
5862             break;
5863
5864         case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
5865             if (requirement == REQUIRES_RSA)
5866                 return 1;
5867             break;
5868
5869         case TLS_ECDH_RSA_WITH_RC4_128_SHA :
5870             if (requirement == REQUIRES_ECC_STATIC)
5871                 return 1;
5872             if (requirement == REQUIRES_RSA_SIG)
5873                 return 1;
5874             break;
5875
5876         case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
5877             if (requirement == REQUIRES_ECC_DSA)
5878                 return 1;
5879             break;
5880
5881         case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
5882             if (requirement == REQUIRES_ECC_STATIC)
5883                 return 1;
5884             break;
5885
5886         case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
5887             if (requirement == REQUIRES_ECC_DSA)
5888                 return 1;
5889             break;
5890
5891         case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
5892             if (requirement == REQUIRES_ECC_STATIC)
5893                 return 1;
5894             break;
5895
5896         case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
5897             if (requirement == REQUIRES_RSA)
5898                 return 1;
5899             break;
5900
5901         case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
5902             if (requirement == REQUIRES_ECC_STATIC)
5903                 return 1;
5904             if (requirement == REQUIRES_RSA_SIG)
5905                 return 1;
5906             break;
5907
5908         case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
5909             if (requirement == REQUIRES_ECC_DSA)
5910                 return 1;
5911             break;
5912
5913         case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
5914             if (requirement == REQUIRES_ECC_STATIC)
5915                 return 1;
5916             break;
5917
5918         case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
5919             if (requirement == REQUIRES_ECC_DSA)
5920                 return 1;
5921             break;
5922
5923         case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
5924             if (requirement == REQUIRES_ECC_STATIC)
5925                 return 1;
5926             break;
5927
5928         case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
5929             if (requirement == REQUIRES_ECC_DSA)
5930                 return 1;
5931             break;
5932
5933         case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
5934             if (requirement == REQUIRES_ECC_DSA)
5935                 return 1;
5936             break;
5937
5938         case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
5939             if (requirement == REQUIRES_ECC_STATIC)
5940                 return 1;
5941             break;
5942
5943         case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
5944             if (requirement == REQUIRES_ECC_STATIC)
5945                 return 1;
5946             break;
5947
5948         case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
5949             if (requirement == REQUIRES_RSA)
5950                 return 1;
5951             break;
5952
5953         case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
5954             if (requirement == REQUIRES_RSA)
5955                 return 1;
5956             break;
5957
5958         case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
5959             if (requirement == REQUIRES_ECC_STATIC)
5960                 return 1;
5961             if (requirement == REQUIRES_RSA_SIG)
5962                 return 1;
5963             break;
5964
5965         case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
5966             if (requirement == REQUIRES_ECC_STATIC)
5967                 return 1;
5968             if (requirement == REQUIRES_RSA_SIG)
5969                 return 1;
5970             break;
5971
5972         default:
5973             CYASSL_MSG("Unsupported cipher suite, CipherRequires ECC");
5974             return 0;
5975         }   /* switch */
5976         }   /* if     */
5977         if (first != ECC_BYTE) {   /* normal suites */
5978         switch (second) {
5979
5980         case SSL_RSA_WITH_RC4_128_SHA :
5981             if (requirement == REQUIRES_RSA)
5982                 return 1;
5983             break;
5984
5985         case TLS_NTRU_RSA_WITH_RC4_128_SHA :
5986             if (requirement == REQUIRES_NTRU)
5987                 return 1;
5988             break;
5989
5990         case SSL_RSA_WITH_RC4_128_MD5 :
5991             if (requirement == REQUIRES_RSA)
5992                 return 1;
5993             break;
5994
5995         case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
5996             if (requirement == REQUIRES_RSA)
5997                 return 1;
5998             break;
5999
6000         case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
6001             if (requirement == REQUIRES_NTRU)
6002                 return 1;
6003             break;
6004
6005         case TLS_RSA_WITH_AES_128_CBC_SHA :
6006             if (requirement == REQUIRES_RSA)
6007                 return 1;
6008             break;
6009
6010         case TLS_RSA_WITH_AES_128_CBC_SHA256 :
6011             if (requirement == REQUIRES_RSA)
6012                 return 1;
6013             break;
6014
6015         case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
6016             if (requirement == REQUIRES_NTRU)
6017                 return 1;
6018             break;
6019
6020         case TLS_RSA_WITH_AES_256_CBC_SHA :
6021             if (requirement == REQUIRES_RSA)
6022                 return 1;
6023             break;
6024
6025         case TLS_RSA_WITH_AES_256_CBC_SHA256 :
6026             if (requirement == REQUIRES_RSA)
6027                 return 1;
6028             break;
6029
6030         case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
6031             if (requirement == REQUIRES_NTRU)
6032                 return 1;
6033             break;
6034
6035         case TLS_PSK_WITH_AES_128_CBC_SHA :
6036             if (requirement == REQUIRES_PSK)
6037                 return 1;
6038             break;
6039
6040         case TLS_PSK_WITH_AES_256_CBC_SHA :
6041             if (requirement == REQUIRES_PSK)
6042                 return 1;
6043             break;
6044
6045         case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
6046             if (requirement == REQUIRES_RSA)
6047                 return 1;
6048             if (requirement == REQUIRES_DHE)
6049                 return 1;
6050             break;
6051
6052         case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
6053             if (requirement == REQUIRES_RSA)
6054                 return 1;
6055             if (requirement == REQUIRES_DHE)
6056                 return 1;
6057             break;
6058
6059         case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
6060             if (requirement == REQUIRES_RSA)
6061                 return 1;
6062             if (requirement == REQUIRES_DHE)
6063                 return 1;
6064             break;
6065
6066         case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
6067             if (requirement == REQUIRES_RSA)
6068                 return 1;
6069             if (requirement == REQUIRES_DHE)
6070                 return 1;
6071             break;
6072
6073         case TLS_RSA_WITH_HC_128_CBC_MD5 :
6074             if (requirement == REQUIRES_RSA)
6075                 return 1;
6076             break;
6077                 
6078         case TLS_RSA_WITH_HC_128_CBC_SHA :
6079             if (requirement == REQUIRES_RSA)
6080                 return 1;
6081             break;
6082
6083         case TLS_RSA_WITH_RABBIT_CBC_SHA :
6084             if (requirement == REQUIRES_RSA)
6085                 return 1;
6086             break;
6087
6088         case TLS_RSA_WITH_AES_128_GCM_SHA256 :
6089         case TLS_RSA_WITH_AES_256_GCM_SHA384 :
6090             if (requirement == REQUIRES_RSA)
6091                 return 1;
6092             break;
6093
6094         case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
6095         case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
6096             if (requirement == REQUIRES_RSA)
6097                 return 1;
6098             if (requirement == REQUIRES_DHE)
6099                 return 1;
6100             break;
6101
6102         default:
6103             CYASSL_MSG("Unsupported cipher suite, CipherRequires");
6104             return 0;
6105         }  /* switch */
6106         }  /* if ECC / Normal suites else */
6107
6108         return 0;
6109     }
6110
6111
6112
6113
6114
6115     /* Make sure cert/key are valid for this suite, true on success */
6116     static int VerifySuite(CYASSL* ssl, word16 idx)
6117     {
6118         int  haveRSA = !ssl->options.haveStaticECC;
6119         int  havePSK = 0;
6120         byte first   = ssl->suites.suites[idx];
6121         byte second  = ssl->suites.suites[idx+1];
6122
6123         CYASSL_ENTER("VerifySuite");
6124
6125         #ifndef NO_PSK
6126             havePSK = ssl->options.havePSK;
6127         #endif
6128
6129         if (ssl->options.haveNTRU)
6130             haveRSA = 0;
6131
6132         if (CipherRequires(first, second, REQUIRES_RSA)) {
6133             CYASSL_MSG("Requires RSA");
6134             if (haveRSA == 0) {
6135                 CYASSL_MSG("Don't have RSA");
6136                 return 0;
6137             }
6138         }
6139
6140         if (CipherRequires(first, second, REQUIRES_DHE)) {
6141             CYASSL_MSG("Requires DHE");
6142             if (ssl->options.haveDH == 0) {
6143                 CYASSL_MSG("Don't have DHE");
6144                 return 0;
6145             }
6146         }
6147
6148         if (CipherRequires(first, second, REQUIRES_ECC_DSA)) {
6149             CYASSL_MSG("Requires ECCDSA");
6150             if (ssl->options.haveECDSAsig == 0) {
6151                 CYASSL_MSG("Don't have ECCDSA");
6152                 return 0;
6153             }
6154         }
6155
6156         if (CipherRequires(first, second, REQUIRES_ECC_STATIC)) {
6157             CYASSL_MSG("Requires static ECC");
6158             if (ssl->options.haveStaticECC == 0) {
6159                 CYASSL_MSG("Don't have static ECC");
6160                 return 0;
6161             }
6162         }
6163
6164         if (CipherRequires(first, second, REQUIRES_PSK)) {
6165             CYASSL_MSG("Requires PSK");
6166             if (havePSK == 0) {
6167                 CYASSL_MSG("Don't have PSK");
6168                 return 0;
6169             }
6170         }
6171
6172         if (CipherRequires(first, second, REQUIRES_NTRU)) {
6173             CYASSL_MSG("Requires NTRU");
6174             if (ssl->options.haveNTRU == 0) {
6175                 CYASSL_MSG("Don't have NTRU");
6176                 return 0;
6177             }
6178         }
6179
6180         if (CipherRequires(first, second, REQUIRES_RSA_SIG)) {
6181             CYASSL_MSG("Requires RSA Signature");
6182             if (ssl->options.side == SERVER_END && ssl->options.haveECDSAsig == 1) {
6183                 CYASSL_MSG("Don't have RSA Signature");
6184                 return 0;
6185             }
6186         }
6187
6188         /* ECCDHE is always supported if ECC on */
6189
6190         return 1;
6191     }
6192
6193
6194     static int MatchSuite(CYASSL* ssl, Suites* peerSuites)
6195     {
6196         word16 i, j;
6197
6198         CYASSL_ENTER("MatchSuite");
6199
6200         /* & 0x1 equivalent % 2 */
6201         if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1)
6202             return MATCH_SUITE_ERROR;
6203
6204         /* start with best, if a match we are good */
6205         for (i = 0; i < ssl->suites.suiteSz; i += 2)
6206             for (j = 0; j < peerSuites->suiteSz; j += 2)
6207                 if (ssl->suites.suites[i]   == peerSuites->suites[j] &&
6208                     ssl->suites.suites[i+1] == peerSuites->suites[j+1] ) {
6209
6210                     if (VerifySuite(ssl, i)) {
6211                         CYASSL_MSG("Verified suite validity");
6212                         ssl->options.cipherSuite0 = ssl->suites.suites[i];
6213                         ssl->options.cipherSuite  = ssl->suites.suites[i+1];
6214                         return SetCipherSpecs(ssl);
6215                     }
6216                     else {
6217                         CYASSL_MSG("Coult not verify suite validity, continue");
6218                     }
6219                 }
6220
6221         return MATCH_SUITE_ERROR;
6222     }
6223
6224
6225     /* process old style client hello, deprecate? */
6226     int ProcessOldClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
6227                               word32 inSz, word16 sz)
6228     {
6229         word32          idx = *inOutIdx;
6230         word16          sessionSz;
6231         word16          randomSz;
6232         word16          i, j;
6233         ProtocolVersion pv;
6234         Suites          clSuites;
6235
6236         (void)inSz;
6237         CYASSL_MSG("Got old format client hello");
6238 #ifdef CYASSL_CALLBACKS
6239         if (ssl->hsInfoOn)
6240             AddPacketName("ClientHello", &ssl->handShakeInfo);
6241         if (ssl->toInfoOn)
6242             AddLateName("ClientHello", &ssl->timeoutInfo);
6243 #endif
6244
6245         /* manually hash input since different format */
6246         Md5Update(&ssl->hashMd5, input + idx, sz);
6247         ShaUpdate(&ssl->hashSha, input + idx, sz);
6248 #ifndef NO_SHA256
6249     if (IsAtLeastTLSv1_2(ssl))
6250         Sha256Update(&ssl->hashSha256, input + idx, sz);
6251 #endif
6252
6253         /* does this value mean client_hello? */
6254         idx++;
6255
6256         /* version */
6257         pv.major = input[idx++];
6258         pv.minor = input[idx++];
6259         ssl->chVersion = pv;  /* store */
6260
6261         if (ssl->version.minor > pv.minor) {
6262             byte havePSK = 0;
6263             if (!ssl->options.downgrade) {
6264                 CYASSL_MSG("Client trying to connect with lesser version"); 
6265                 return VERSION_ERROR;
6266             }
6267             if (pv.minor == SSLv3_MINOR) {
6268                 /* turn off tls */
6269                 CYASSL_MSG("    downgrading to SSLv3");
6270                 ssl->options.tls    = 0;
6271                 ssl->options.tls1_1 = 0;
6272                 ssl->version.minor  = SSLv3_MINOR;
6273             }
6274             else if (pv.minor == TLSv1_MINOR) {
6275                 CYASSL_MSG("    downgrading to TLSv1");
6276                 /* turn off tls 1.1+ */
6277                 ssl->options.tls1_1 = 0;
6278                 ssl->version.minor  = TLSv1_MINOR;
6279             }
6280             else if (pv.minor == TLSv1_1_MINOR) {
6281                 CYASSL_MSG("    downgrading to TLSv1.1");
6282                 ssl->version.minor  = TLSv1_1_MINOR;
6283             }
6284 #ifndef NO_PSK
6285             havePSK = ssl->options.havePSK;
6286 #endif
6287
6288             InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK,
6289                        ssl->options.haveNTRU, ssl->options.haveECDSAsig,
6290                        ssl->options.haveStaticECC, ssl->options.side);
6291         }
6292
6293         /* suite size */
6294         ato16(&input[idx], &clSuites.suiteSz);
6295         idx += 2;
6296
6297         if (clSuites.suiteSz > MAX_SUITE_SZ)
6298             return BUFFER_ERROR;
6299
6300         /* session size */
6301         ato16(&input[idx], &sessionSz);
6302         idx += 2;
6303
6304         if (sessionSz > ID_LEN)
6305             return BUFFER_ERROR;
6306     
6307         /* random size */
6308         ato16(&input[idx], &randomSz);
6309         idx += 2;
6310
6311         if (randomSz > RAN_LEN)
6312             return BUFFER_ERROR;
6313
6314         /* suites */
6315         for (i = 0, j = 0; i < clSuites.suiteSz; i += 3) {    
6316             byte first = input[idx++];
6317             if (!first) { /* implicit: skip sslv2 type */
6318                 XMEMCPY(&clSuites.suites[j], &input[idx], 2);
6319                 j += 2;
6320             }
6321             idx += 2;
6322         }
6323         clSuites.suiteSz = j;
6324
6325         /* session id */
6326         if (sessionSz) {
6327             XMEMCPY(ssl->arrays.sessionID, input + idx, sessionSz);
6328             idx += sessionSz;
6329             ssl->options.resuming = 1;
6330         }
6331
6332         /* random */
6333         if (randomSz < RAN_LEN)
6334             XMEMSET(ssl->arrays.clientRandom, 0, RAN_LEN - randomSz);
6335         XMEMCPY(&ssl->arrays.clientRandom[RAN_LEN - randomSz], input + idx,
6336                randomSz);
6337         idx += randomSz;
6338
6339         if (ssl->options.usingCompression)
6340             ssl->options.usingCompression = 0;  /* turn off */
6341
6342         ssl->options.clientState = CLIENT_HELLO_COMPLETE;
6343         *inOutIdx = idx;
6344
6345         ssl->options.haveSessionId = 1;
6346         /* DoClientHello uses same resume code */
6347         while (ssl->options.resuming) {  /* let's try */
6348             int ret; 
6349             CYASSL_SESSION* session = GetSession(ssl, ssl->arrays.masterSecret);
6350             if (!session) {
6351                 ssl->options.resuming = 0;
6352                 break;   /* session lookup failed */
6353             }
6354             if (MatchSuite(ssl, &clSuites) < 0) {
6355                 CYASSL_MSG("Unsupported cipher suite, OldClientHello");
6356                 return UNSUPPORTED_SUITE;
6357             }
6358
6359             RNG_GenerateBlock(&ssl->rng, ssl->arrays.serverRandom, RAN_LEN);
6360             if (ssl->options.tls)
6361                 ret = DeriveTlsKeys(ssl);
6362             else
6363                 ret = DeriveKeys(ssl);
6364             ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
6365
6366             return ret;
6367         }
6368
6369         return MatchSuite(ssl, &clSuites);
6370     }
6371
6372
6373     static int DoClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
6374                              word32 totalSz, word32 helloSz)
6375     {
6376         byte b;
6377         ProtocolVersion pv;
6378         Suites          clSuites;
6379         word32 i = *inOutIdx;
6380         word32 begin = i;
6381
6382 #ifdef CYASSL_CALLBACKS
6383         if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
6384         if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
6385 #endif
6386         /* make sure can read up to session */
6387         if (i + sizeof(pv) + RAN_LEN + ENUM_LEN > totalSz)
6388             return INCOMPLETE_DATA;
6389
6390         XMEMCPY(&pv, input + i, sizeof(pv));
6391         ssl->chVersion = pv;   /* store */
6392         i += sizeof(pv);
6393         if (ssl->version.minor > pv.minor) {
6394             byte havePSK = 0;
6395             if (!ssl->options.downgrade) {
6396                 CYASSL_MSG("Client trying to connect with lesser version"); 
6397                 return VERSION_ERROR;
6398             }
6399             if (pv.minor == SSLv3_MINOR) {
6400                 /* turn off tls */
6401                 CYASSL_MSG("    downgrading to SSLv3");
6402                 ssl->options.tls    = 0;
6403                 ssl->options.tls1_1 = 0;
6404                 ssl->version.minor  = SSLv3_MINOR;
6405             }
6406             else if (pv.minor == TLSv1_MINOR) {
6407                 /* turn off tls 1.1+ */
6408                 CYASSL_MSG("    downgrading to TLSv1");
6409                 ssl->options.tls1_1 = 0;
6410                 ssl->version.minor  = TLSv1_MINOR;
6411             }
6412             else if (pv.minor == TLSv1_1_MINOR) {
6413                 CYASSL_MSG("    downgrading to TLSv1.1");
6414                 ssl->version.minor  = TLSv1_1_MINOR;
6415             }
6416 #ifndef NO_PSK
6417             havePSK = ssl->options.havePSK;
6418 #endif
6419             InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK,
6420                        ssl->options.haveNTRU, ssl->options.haveECDSAsig,
6421                        ssl->options.haveStaticECC, ssl->options.side);
6422         }
6423         /* random */
6424         XMEMCPY(ssl->arrays.clientRandom, input + i, RAN_LEN);
6425         i += RAN_LEN;
6426
6427 #ifdef SHOW_SECRETS
6428         {
6429             int j;
6430             printf("client random: ");
6431             for (j = 0; j < RAN_LEN; j++)
6432                 printf("%02x", ssl->arrays.clientRandom[j]);
6433             printf("\n");
6434         }
6435 #endif
6436         /* session id */
6437         b = input[i++];
6438         if (b) {
6439             if (i + ID_LEN > totalSz)
6440                 return INCOMPLETE_DATA;
6441             XMEMCPY(ssl->arrays.sessionID, input + i, ID_LEN);
6442             i += b;
6443             ssl->options.resuming= 1; /* client wants to resume */
6444             CYASSL_MSG("Client wants to resume session");
6445         }
6446         
6447         #ifdef CYASSL_DTLS
6448             /* cookie */
6449             if (ssl->options.dtls) {
6450                 b = input[i++];
6451                 if (b) {
6452                     byte cookie[MAX_COOKIE_LEN];
6453                     byte cookieSz;
6454
6455                     if (b > MAX_COOKIE_LEN)
6456                         return BUFFER_ERROR;
6457                     if (i + b > totalSz)
6458                         return INCOMPLETE_DATA;
6459                     cookieSz = EmbedGenerateCookie(cookie, COOKIE_SZ, ssl);
6460                     if ((b != cookieSz) || XMEMCMP(cookie, input + i, b) != 0)
6461                         return COOKIE_ERROR;
6462                     i += b;
6463                 }
6464             }
6465         #endif
6466
6467         if (i + LENGTH_SZ > totalSz)
6468             return INCOMPLETE_DATA;
6469         /* suites */
6470         ato16(&input[i], &clSuites.suiteSz);
6471         i += 2;
6472
6473         /* suites and comp len */
6474         if (i + clSuites.suiteSz + ENUM_LEN > totalSz)
6475             return INCOMPLETE_DATA;
6476         if (clSuites.suiteSz > MAX_SUITE_SZ)
6477             return BUFFER_ERROR;
6478         XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
6479         i += clSuites.suiteSz;
6480
6481         b = input[i++];  /* comp len */
6482         if (i + b > totalSz)
6483             return INCOMPLETE_DATA;
6484
6485         if (ssl->options.usingCompression) {
6486             int match = 0;
6487             while (b--) {
6488                 byte comp = input[i++];
6489                 if (comp == ZLIB_COMPRESSION)
6490                     match = 1;
6491             }
6492             if (!match) {
6493                 CYASSL_MSG("Not matching compression, turning off"); 
6494                 ssl->options.usingCompression = 0;  /* turn off */
6495             }
6496         }
6497         else
6498             i += b;  /* ignore, since we're not on */
6499
6500         ssl->options.clientState = CLIENT_HELLO_COMPLETE;
6501
6502         *inOutIdx = i;
6503         if ( (i - begin) < helloSz)
6504             *inOutIdx = begin + helloSz;  /* skip extensions */
6505         
6506         ssl->options.haveSessionId = 1;
6507         /* ProcessOld uses same resume code */
6508         while (ssl->options.resuming) {  /* let's try */
6509             int ret;            
6510             CYASSL_SESSION* session = GetSession(ssl, ssl->arrays.masterSecret);
6511             if (!session) {
6512                 ssl->options.resuming = 0;
6513                 CYASSL_MSG("Session lookup for resume failed");
6514                 break;   /* session lookup failed */
6515             }
6516             if (MatchSuite(ssl, &clSuites) < 0) {
6517                 CYASSL_MSG("Unsupported cipher suite, ClientHello");
6518                 return UNSUPPORTED_SUITE;
6519             }
6520
6521             RNG_GenerateBlock(&ssl->rng, ssl->arrays.serverRandom, RAN_LEN);
6522             if (ssl->options.tls)
6523                 ret = DeriveTlsKeys(ssl);
6524             else
6525                 ret = DeriveKeys(ssl);
6526             ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
6527
6528             return ret;
6529         }
6530         return MatchSuite(ssl, &clSuites);
6531     }
6532
6533
6534     static int DoCertificateVerify(CYASSL* ssl, byte* input, word32* inOutsz,
6535                                    word32 totalSz)
6536     {
6537         word16      sz = 0;
6538         word32      i = *inOutsz;
6539         int         ret = VERIFY_CERT_ERROR;   /* start in error state */
6540         byte*       sig;
6541         byte*       out;
6542         int         outLen;
6543
6544         #ifdef CYASSL_CALLBACKS
6545             if (ssl->hsInfoOn)
6546                 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
6547             if (ssl->toInfoOn)
6548                 AddLateName("CertificateVerify", &ssl->timeoutInfo);
6549         #endif
6550         if ( (i + VERIFY_HEADER) > totalSz)
6551             return INCOMPLETE_DATA;
6552
6553         if (IsAtLeastTLSv1_2(ssl))
6554            i += HASH_SIG_SIZE; 
6555         ato16(&input[i], &sz);
6556         i += VERIFY_HEADER;
6557
6558         if ( (i + sz) > totalSz)
6559             return INCOMPLETE_DATA;
6560
6561         if (sz > ENCRYPT_LEN)
6562             return BUFFER_ERROR;
6563
6564         sig = &input[i];
6565         *inOutsz = i + sz;
6566
6567         /* RSA */
6568         if (ssl->peerRsaKeyPresent != 0) {
6569             CYASSL_MSG("Doing RSA peer cert verify");
6570
6571             outLen = RsaSSL_VerifyInline(sig, sz, &out, &ssl->peerRsaKey);
6572
6573             if (IsAtLeastTLSv1_2(ssl)) {
6574                 byte   encodedSig[MAX_ENCODED_SIG_SZ];
6575                 word32 sigSz;
6576                 byte*  digest;
6577                 int    typeH;
6578                 int    digestSz;
6579
6580                 /* sha1 for now */
6581                 digest   = ssl->certHashes.sha;
6582                 typeH    = SHAh;
6583                 digestSz = SHA_DIGEST_SIZE;
6584
6585                 sigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
6586
6587                 if (outLen == (int)sigSz && XMEMCMP(out, encodedSig,
6588                                            min(sigSz, MAX_ENCODED_SIG_SZ)) == 0)
6589                     ret = 0;  /* verified */
6590             }
6591             else {
6592                 if (outLen == sizeof(ssl->certHashes) && XMEMCMP(out,
6593                                 &ssl->certHashes, sizeof(ssl->certHashes)) == 0)
6594                     ret = 0;  /* verified */
6595             }
6596         }
6597 #ifdef HAVE_ECC
6598         else if (ssl->peerEccDsaKeyPresent) {
6599             int verify =  0;
6600             int err    = -1;
6601
6602             CYASSL_MSG("Doing ECC peer cert verify");
6603
6604             err = ecc_verify_hash(sig, sz, ssl->certHashes.sha, SHA_DIGEST_SIZE,
6605                                   &verify, &ssl->peerEccDsaKey);
6606
6607             if (err == 0 && verify == 1)
6608                ret = 0;   /* verified */ 
6609         }
6610 #endif
6611         return ret;
6612     }
6613
6614
6615     int SendServerHelloDone(CYASSL* ssl)
6616     {
6617         byte              *output;
6618         int                sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
6619         int                ret;
6620
6621         #ifdef CYASSL_DTLS
6622             if (ssl->options.dtls)
6623                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
6624         #endif
6625         /* check for avalaible size */
6626         if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
6627             return ret;
6628
6629         /* get ouput buffer */
6630         output = ssl->buffers.outputBuffer.buffer +
6631                  ssl->buffers.outputBuffer.length;
6632
6633         AddHeaders(output, 0, server_hello_done, ssl);
6634
6635         HashOutput(ssl, output, sendSz, 0);
6636 #ifdef CYASSL_CALLBACKS
6637         if (ssl->hsInfoOn)
6638             AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
6639         if (ssl->toInfoOn)
6640             AddPacketInfo("ServerHelloDone", &ssl->timeoutInfo, output, sendSz,
6641                           ssl->heap);
6642 #endif
6643         ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
6644
6645         ssl->buffers.outputBuffer.length += sendSz;
6646
6647         return SendBuffered(ssl);
6648     }
6649
6650 #ifdef CYASSL_DTLS
6651     int SendHelloVerifyRequest(CYASSL* ssl)
6652     {
6653         byte* output;
6654         byte  cookieSz = COOKIE_SZ;
6655         int   length = VERSION_SZ + ENUM_LEN + cookieSz;
6656         int   idx    = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
6657         int   sendSz = length + idx;
6658         int   ret;
6659
6660         /* check for avalaible size */
6661         if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
6662             return ret;
6663
6664         /* get ouput buffer */
6665         output = ssl->buffers.outputBuffer.buffer +
6666                  ssl->buffers.outputBuffer.length;
6667
6668         AddHeaders(output, length, hello_verify_request, ssl);
6669
6670         XMEMCPY(output + idx, &ssl->chVersion, VERSION_SZ);
6671         idx += VERSION_SZ;
6672
6673         output[idx++] = cookieSz;
6674         if ((ret = EmbedGenerateCookie(output + idx, cookieSz, ssl)) < 0)
6675             return ret;
6676
6677         HashOutput(ssl, output, sendSz, 0);
6678 #ifdef CYASSL_CALLBACKS
6679         if (ssl->hsInfoOn)
6680             AddPacketName("HelloVerifyRequest", &ssl->handShakeInfo);
6681         if (ssl->toInfoOn)
6682             AddPacketInfo("HelloVerifyRequest", &ssl->timeoutInfo, output,
6683                           sendSz, ssl->heap);
6684 #endif
6685         ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
6686
6687         ssl->buffers.outputBuffer.length += sendSz;
6688
6689         return SendBuffered(ssl);
6690     }
6691 #endif
6692
6693     static int DoClientKeyExchange(CYASSL* ssl, byte* input,
6694                                    word32* inOutIdx)
6695     {
6696         int    ret = 0;
6697         word32 length = 0;
6698         byte*  out;
6699
6700         if (ssl->options.verifyPeer && ssl->options.failNoCert)
6701             if (!ssl->options.havePeerCert) {
6702                 CYASSL_MSG("client didn't present peer cert");
6703                 return NO_PEER_CERT;
6704             }
6705
6706         #ifdef CYASSL_CALLBACKS
6707             if (ssl->hsInfoOn)
6708                 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
6709             if (ssl->toInfoOn)
6710                 AddLateName("ClientKeyExchange", &ssl->timeoutInfo);
6711         #endif
6712         if (ssl->specs.kea == rsa_kea) {
6713             word32 idx = 0;
6714             RsaKey key;
6715             byte*  tmp = 0;
6716
6717             InitRsaKey(&key, ssl->heap);
6718
6719             if (ssl->buffers.key.buffer)
6720                 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
6721                                           ssl->buffers.key.length);
6722             else
6723                 return NO_PRIVATE_KEY;
6724
6725             if (ret == 0) {
6726                 length = RsaEncryptSize(&key);
6727                 ssl->arrays.preMasterSz = SECRET_LEN;
6728
6729                 if (ssl->options.tls)
6730                     (*inOutIdx) += 2;
6731                 tmp = input + *inOutIdx;
6732                 *inOutIdx += length;
6733
6734                 if (RsaPrivateDecryptInline(tmp, length, &out, &key) ==
6735                                                              SECRET_LEN) {
6736                     XMEMCPY(ssl->arrays.preMasterSecret, out, SECRET_LEN);
6737                     if (ssl->arrays.preMasterSecret[0] != ssl->chVersion.major
6738                      ||
6739                         ssl->arrays.preMasterSecret[1] != ssl->chVersion.minor)
6740
6741                         ret = PMS_VERSION_ERROR;
6742                     else
6743                         ret = MakeMasterSecret(ssl);
6744                 }
6745                 else
6746                     ret = RSA_PRIVATE_ERROR;
6747             }
6748
6749             FreeRsaKey(&key);
6750 #ifndef NO_PSK
6751         } else if (ssl->specs.kea == psk_kea) {
6752             byte* pms = ssl->arrays.preMasterSecret;
6753             word16 ci_sz;
6754
6755             ato16(&input[*inOutIdx], &ci_sz);
6756             *inOutIdx += LENGTH_SZ;
6757             if (ci_sz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR;
6758
6759             XMEMCPY(ssl->arrays.client_identity, &input[*inOutIdx], ci_sz);
6760             *inOutIdx += ci_sz;
6761             ssl->arrays.client_identity[ci_sz] = 0;
6762
6763             ssl->arrays.psk_keySz = ssl->options.server_psk_cb(ssl,
6764                 ssl->arrays.client_identity, ssl->arrays.psk_key,
6765                 MAX_PSK_KEY_LEN);
6766             if (ssl->arrays.psk_keySz == 0 || 
6767                 ssl->arrays.psk_keySz > MAX_PSK_KEY_LEN) return PSK_KEY_ERROR;
6768             
6769             /* make psk pre master secret */
6770             /* length of key + length 0s + length of key + key */
6771             c16toa((word16)ssl->arrays.psk_keySz, pms);
6772             pms += 2;
6773             XMEMSET(pms, 0, ssl->arrays.psk_keySz);
6774             pms += ssl->arrays.psk_keySz;
6775             c16toa((word16)ssl->arrays.psk_keySz, pms);
6776             pms += 2;
6777             XMEMCPY(pms, ssl->arrays.psk_key, ssl->arrays.psk_keySz);
6778             ssl->arrays.preMasterSz = ssl->arrays.psk_keySz * 2 + 4;
6779
6780             ret = MakeMasterSecret(ssl);
6781 #endif /* NO_PSK */
6782 #ifdef HAVE_NTRU
6783         } else if (ssl->specs.kea == ntru_kea) {
6784             word32 rc;
6785             word16 cipherLen;
6786             word16 plainLen = sizeof(ssl->arrays.preMasterSecret);
6787             byte*  tmp;
6788
6789             if (!ssl->buffers.key.buffer)
6790                 return NO_PRIVATE_KEY;
6791
6792             ato16(&input[*inOutIdx], &cipherLen);
6793             *inOutIdx += LENGTH_SZ;
6794             if (cipherLen > MAX_NTRU_ENCRYPT_SZ)
6795                 return NTRU_KEY_ERROR;
6796
6797             tmp = input + *inOutIdx;
6798             rc = crypto_ntru_decrypt((word16)ssl->buffers.key.length,
6799                         ssl->buffers.key.buffer, cipherLen, tmp, &plainLen,
6800                         ssl->arrays.preMasterSecret);
6801
6802             if (rc != NTRU_OK || plainLen != SECRET_LEN)
6803                 return NTRU_DECRYPT_ERROR;
6804             *inOutIdx += cipherLen;
6805
6806             ssl->arrays.preMasterSz = plainLen;
6807             ret = MakeMasterSecret(ssl);
6808 #endif /* HAVE_NTRU */
6809 #ifdef HAVE_ECC
6810         } else if (ssl->specs.kea == ecc_diffie_hellman_kea) {
6811             word32 size;
6812             word32 bLength = input[*inOutIdx];  /* one byte length */
6813             *inOutIdx += 1;
6814
6815             ret = ecc_import_x963(&input[*inOutIdx], bLength, &ssl->peerEccKey);
6816             if (ret != 0)
6817                 return ECC_PEERKEY_ERROR;
6818             *inOutIdx += bLength;
6819             ssl->peerEccKeyPresent = 1;
6820
6821             size = sizeof(ssl->arrays.preMasterSecret);
6822             if (ssl->specs.static_ecdh) {
6823                 ecc_key staticKey;
6824                 word32 i = 0;
6825
6826                 ecc_init(&staticKey);
6827                 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
6828                                           &staticKey, ssl->buffers.key.length);
6829                 if (ret == 0)
6830                     ret = ecc_shared_secret(&staticKey, &ssl->peerEccKey,
6831                                             ssl->arrays.preMasterSecret, &size);
6832                 ecc_free(&staticKey);
6833             }
6834             else 
6835                 ret = ecc_shared_secret(&ssl->eccTempKey, &ssl->peerEccKey,
6836                                     ssl->arrays.preMasterSecret, &size);
6837             if (ret != 0)
6838                 return ECC_SHARED_ERROR;
6839             ssl->arrays.preMasterSz = size;
6840             ret = MakeMasterSecret(ssl);
6841 #endif /* HAVE_ECC */
6842 #ifdef OPENSSL_EXTRA 
6843         } else if (ssl->specs.kea == diffie_hellman_kea) {
6844             byte*  clientPub;
6845             word16 clientPubSz;
6846             DhKey  dhKey;
6847
6848             ato16(&input[*inOutIdx], &clientPubSz);
6849             *inOutIdx += LENGTH_SZ;
6850
6851             clientPub = &input[*inOutIdx];
6852             *inOutIdx += clientPubSz;
6853
6854             InitDhKey(&dhKey);
6855             ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
6856                                    ssl->buffers.serverDH_P.length,
6857                                    ssl->buffers.serverDH_G.buffer,
6858                                    ssl->buffers.serverDH_G.length);
6859             if (ret == 0)
6860                 ret = DhAgree(&dhKey, ssl->arrays.preMasterSecret,
6861                                      &ssl->arrays.preMasterSz,
6862                                       ssl->buffers.serverDH_Priv.buffer,
6863                                       ssl->buffers.serverDH_Priv.length,
6864                                       clientPub, clientPubSz);
6865             FreeDhKey(&dhKey);
6866             if (ret == 0)
6867                 ret = MakeMasterSecret(ssl);
6868 #endif /* OPENSSL_EXTRA */
6869         }
6870
6871         if (ret == 0) {
6872             ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
6873             if (ssl->options.verifyPeer)
6874                 BuildCertHashes(ssl, &ssl->certHashes);
6875         }
6876
6877         return ret;
6878     }
6879
6880 #endif /* NO_CYASSL_SERVER */
6881
6882
6883 #ifdef SINGLE_THREADED
6884
6885 int InitMutex(CyaSSL_Mutex* m)
6886 {
6887     return 0;
6888 }
6889
6890
6891 int FreeMutex(CyaSSL_Mutex* m)
6892 {
6893     return 0;
6894 }
6895
6896
6897 int LockMutex(CyaSSL_Mutex* m)
6898 {
6899     return 0;
6900 }
6901
6902
6903 int UnLockMutex(CyaSSL_Mutex* m)
6904 {
6905     return 0;
6906 }
6907
6908 #else /* MULTI_THREAD */
6909
6910     #if defined(FREERTOS)
6911
6912         int InitMutex(CyaSSL_Mutex* m)
6913         {
6914             int iReturn;
6915
6916             *m = ( CyaSSL_Mutex ) xSemaphoreCreateMutex();
6917             if( *m != NULL )
6918                 iReturn = 0;
6919             else
6920                 iReturn = BAD_MUTEX_ERROR;
6921
6922             return iReturn;
6923         }
6924
6925         int FreeMutex(CyaSSL_Mutex* m)
6926         {
6927             vSemaphoreDelete( *m );
6928             return 0;
6929         }
6930
6931         int LockMutex(CyaSSL_Mutex* m)
6932         {
6933             /* Assume an infinite block, or should there be zero block? */
6934             xSemaphoreTake( *m, portMAX_DELAY );
6935             return 0;
6936         }
6937
6938         int UnLockMutex(CyaSSL_Mutex* m)
6939         {
6940             xSemaphoreGive( *m );
6941             return 0;
6942         }
6943
6944     #elif defined(USE_WINDOWS_API)
6945
6946         int InitMutex(CyaSSL_Mutex* m)
6947         {
6948             InitializeCriticalSection(m);
6949             return 0;
6950         }
6951
6952
6953         int FreeMutex(CyaSSL_Mutex* m)
6954         {
6955             DeleteCriticalSection(m);
6956             return 0;
6957         }
6958
6959
6960         int LockMutex(CyaSSL_Mutex* m)
6961         {
6962             EnterCriticalSection(m);
6963             return 0;
6964         }
6965
6966
6967         int UnLockMutex(CyaSSL_Mutex* m)
6968         {
6969             LeaveCriticalSection(m);
6970             return 0;
6971         }
6972
6973     #elif defined(CYASSL_PTHREADS)
6974
6975         int InitMutex(CyaSSL_Mutex* m)
6976         {
6977             if (pthread_mutex_init(m, 0) == 0)
6978                 return 0;
6979             else
6980                 return BAD_MUTEX_ERROR;
6981         }
6982
6983
6984         int FreeMutex(CyaSSL_Mutex* m)
6985         {
6986             if (pthread_mutex_destroy(m) == 0)
6987                 return 0;
6988             else
6989                 return BAD_MUTEX_ERROR;
6990         }
6991
6992
6993         int LockMutex(CyaSSL_Mutex* m)
6994         {
6995             if (pthread_mutex_lock(m) == 0)
6996                 return 0;
6997             else
6998                 return BAD_MUTEX_ERROR;
6999         }
7000
7001
7002         int UnLockMutex(CyaSSL_Mutex* m)
7003         {
7004             if (pthread_mutex_unlock(m) == 0)
7005                 return 0;
7006             else
7007                 return BAD_MUTEX_ERROR;
7008         }
7009
7010     #elif defined(THREADX)
7011
7012         int InitMutex(CyaSSL_Mutex* m)
7013         {
7014             if (tx_mutex_create(m, "CyaSSL Mutex", TX_NO_INHERIT) == 0)
7015                 return 0;
7016             else
7017                 return BAD_MUTEX_ERROR;
7018         }
7019
7020
7021         int FreeMutex(CyaSSL_Mutex* m)
7022         {
7023             if (tx_mutex_delete(m) == 0)
7024                 return 0;
7025             else
7026                 return BAD_MUTEX_ERROR;
7027         }
7028
7029
7030         int LockMutex(CyaSSL_Mutex* m)
7031         {
7032             if (tx_mutex_get(m, TX_WAIT_FOREVER) == 0)
7033                 return 0;
7034             else
7035                 return BAD_MUTEX_ERROR;
7036         }
7037
7038
7039         int UnLockMutex(CyaSSL_Mutex* m)
7040         {
7041             if (tx_mutex_put(m) == 0)
7042                 return 0;
7043             else
7044                 return BAD_MUTEX_ERROR;
7045         }
7046
7047     #elif defined(MICRIUM)
7048
7049         int InitMutex(CyaSSL_Mutex* m)
7050         {
7051             #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
7052                 if (NetSecure_OS_MutexCreate(m) == 0)
7053                     return 0;
7054                 else
7055                     return BAD_MUTEX_ERROR;
7056             #else
7057                 return 0;
7058             #endif
7059         }
7060
7061
7062         int FreeMutex(CyaSSL_Mutex* m)
7063         {
7064             #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
7065                 if (NetSecure_OS_FreeMutex(m) == 0)
7066                     return 0;
7067                 else
7068                     return BAD_MUTEX_ERROR;
7069             #else
7070                 return 0;
7071             #endif
7072         }
7073
7074
7075         int LockMutex(CyaSSL_Mutex* m)
7076         {
7077             #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
7078                 if (NetSecure_OS_LockMutex(m) == 0)
7079                     return 0;
7080                 else
7081                     return BAD_MUTEX_ERROR;
7082             #else
7083                 return 0;
7084             #endif
7085         }
7086
7087
7088         int UnLockMutex(CyaSSL_Mutex* m)
7089         {
7090             #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
7091                 if (NetSecure_OS_UnLockMutex(m) == 0)
7092                     return 0;
7093                 else
7094                     return BAD_MUTEX_ERROR;
7095             #else
7096                 return 0;
7097             #endif
7098
7099         }
7100
7101     #endif /* USE_WINDOWS_API */
7102 #endif /* SINGLE_THREADED */