CyaSSL is an SSL library for devices like mbed.

Dependents:   cyassl-client Sync

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cyassl_int.c Source File

cyassl_int.c

00001 /* cyassl_int.c
00002  *
00003  * Copyright (C) 2006-2009 Sawtooth Consulting Ltd.
00004  *
00005  * This file is part of CyaSSL.
00006  *
00007  * CyaSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * CyaSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00020  */
00021 
00022 
00023 
00024 #include "cyassl_int.h"
00025 #include "cyassl_error.h"
00026 #include "asn.h"
00027 
00028 #ifdef HAVE_LIBZ
00029     #include "zlib.h"
00030 #endif
00031 
00032 #ifdef HAVE_NTRU
00033     #include "crypto_ntru.h"
00034 #endif
00035 
00036 #if defined(DEBUG_CYASSL) || defined(SHOW_SECRETS)
00037     #include <stdio.h>
00038 #endif
00039 
00040 #ifdef __sun
00041     #include <sys/filio.h>
00042 #endif
00043 
00044 #define TRUE  1
00045 #define FALSE 0
00046 
00047 
00048 int CyaSSL_negotiate(SSL*);
00049 
00050 
00051 #ifndef NO_CYASSL_CLIENT
00052     static int DoHelloVerifyRequest(SSL* ssl, const byte* input, word32*);
00053     static int DoServerHello(SSL* ssl, const byte* input, word32*);
00054     static int DoCertificateRequest(SSL* ssl, const byte* input, word32*);
00055     static int DoServerKeyExchange(SSL* ssl, const byte* input, word32*);
00056 #endif
00057 
00058 
00059 #ifndef NO_CYASSL_SERVER
00060     static int DoClientHello(SSL* ssl, const byte* input, word32*, word32,
00061                              word32);
00062     static int DoCertificateVerify(SSL* ssl, byte*, word32*, word32);
00063     static int DoClientKeyExchange(SSL* ssl, byte* input, word32*);
00064 #endif
00065 
00066 typedef enum {
00067     doProcessInit = 0,
00068 #ifndef NO_CYASSL_SERVER
00069     runProcessOldClientHello,
00070 #endif
00071     getRecordLayerHeader,
00072     getData,
00073     runProcessingOneMessage
00074 } processReply;
00075 
00076 static void Hmac(SSL* ssl, byte* digest, const byte* buffer, word32 sz,
00077                  int content, int verify);
00078 
00079 static void BuildCertHashes(SSL* ssl, Hashes* hashes);
00080 
00081 
00082 void BuildTlsFinished(SSL* ssl, Hashes* hashes, const byte* sender);
00083 
00084 
00085 #ifndef min
00086 
00087     static INLINE word32 min(word32 a, word32 b)
00088     {
00089         return a > b ? b : a;
00090     }
00091 
00092 #endif /* min */
00093 
00094 
00095 int IsTLS(const SSL* ssl)
00096 {
00097     if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_MINOR)
00098         return 1;
00099 
00100     return 0;
00101 }
00102 
00103 
00104 int IsAtLeastTLSv1_2(const SSL* ssl)
00105 {
00106     if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_2_MINOR)
00107         return 1;
00108 
00109     return 0;
00110 }
00111 
00112 
00113 #ifdef HAVE_NTRU
00114 
00115 static byte GetEntropy(ENTROPY_CMD cmd, byte* out)
00116 {
00117     /* TODO: add locking? */
00118     static RNG rng;
00119 
00120     if (cmd == INIT) {
00121         int ret = InitRng(&rng);
00122         if (ret == 0)
00123             return 1;
00124         else
00125             return 0;
00126     }
00127 
00128     if (out == NULL)
00129         return 0;
00130 
00131     if (cmd == GET_BYTE_OF_ENTROPY) {
00132         RNG_GenerateBlock(&rng, out, 1);
00133         return 1;
00134     }
00135 
00136     if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) {
00137         *out = 1;
00138         return 1;
00139     }
00140 
00141     return 0;
00142 }
00143 
00144 #endif /* HAVE_NTRU */
00145 
00146 static INLINE void c32to24(word32 in, word24 out)
00147 {
00148     out[0] = (in >> 16) & 0xff;
00149     out[1] = (in >>  8) & 0xff;
00150     out[2] =  in & 0xff;
00151 }
00152 
00153 
00154 static INLINE void c32to48(word32 in, byte out[6])
00155 {
00156     out[0] = 0;
00157     out[1] = 0;
00158     out[2] = (in >> 24) & 0xff;
00159     out[3] = (in >> 16) & 0xff;
00160     out[4] = (in >>  8) & 0xff;
00161     out[5] =  in & 0xff;
00162 }
00163 
00164 
00165 /* convert 16 bit integer to opaque */
00166 static void INLINE c16toa(word16 u16, byte* c)
00167 {
00168     c[0] = (u16 >> 8) & 0xff;
00169     c[1] =  u16 & 0xff;
00170 }
00171 
00172 
00173 /* convert 32 bit integer to opaque */
00174 static INLINE void c32toa(word32 u32, byte* c)
00175 {
00176     c[0] = (u32 >> 24) & 0xff;
00177     c[1] = (u32 >> 16) & 0xff;
00178     c[2] = (u32 >>  8) & 0xff;
00179     c[3] =  u32 & 0xff;
00180 }
00181 
00182 
00183 /* convert a 24 bit integer into a 32 bit one */
00184 static INLINE void c24to32(const word24 u24, word32* u32)
00185 {
00186     *u32 = 0;
00187     *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
00188 }
00189 
00190 
00191 /* convert opaque to 16 bit integer */
00192 static INLINE void ato16(const byte* c, word16* u16)
00193 {
00194     *u16 = 0;
00195     *u16 = (c[0] << 8) | (c[1]);
00196 }
00197 
00198 
00199 /* convert opaque to 32 bit integer */
00200 static INLINE void ato32(const byte* c, word32* u32)
00201 {
00202     *u32 = 0;
00203     *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
00204 }
00205 
00206 
00207 #ifdef HAVE_LIBZ
00208 
00209     /* alloc user allocs to work with zlib */
00210     void* myAlloc(void* opaque, unsigned int item, unsigned int size)
00211     {
00212         return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
00213     }
00214 
00215 
00216     void myFree(void* opaque, void* memory)
00217     {
00218         XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ);
00219     }
00220 
00221 
00222     /* init zlib comp/decomp streams, 0 on success */
00223     static int InitStreams(SSL* ssl)
00224     {
00225         ssl->c_stream.zalloc = (alloc_func)myAlloc;
00226         ssl->c_stream.zfree  = (free_func)myFree;
00227         ssl->c_stream.opaque = (voidpf)ssl->heap;
00228 
00229         if (deflateInit(&ssl->c_stream, 8) != Z_OK) return ZLIB_INIT_ERROR;
00230 
00231         ssl->didStreamInit = 1;
00232 
00233         ssl->d_stream.zalloc = (alloc_func)myAlloc;
00234         ssl->d_stream.zfree  = (free_func)myFree;
00235         ssl->d_stream.opaque = (voidpf)ssl->heap;
00236 
00237         if (inflateInit(&ssl->d_stream) != Z_OK) return ZLIB_INIT_ERROR;
00238 
00239         return 0;
00240     }
00241 
00242 
00243     static void FreeStreams(SSL* ssl)
00244     {
00245         if (ssl->didStreamInit) {
00246             deflateEnd(&ssl->c_stream);
00247             inflateEnd(&ssl->d_stream);
00248         }
00249     }
00250 
00251 
00252     /* compress in to out, return out size or error */
00253     static int Compress(SSL* ssl, byte* in, int inSz, byte* out, int outSz)
00254     {
00255         int    err;
00256         int    currTotal = ssl->c_stream.total_out;
00257 
00258         /* put size in front of compression */
00259         c16toa((word16)inSz, out);
00260         out   += 2;
00261         outSz -= 2;
00262 
00263         ssl->c_stream.next_in   = in;
00264         ssl->c_stream.avail_in  = inSz;
00265         ssl->c_stream.next_out  = out;
00266         ssl->c_stream.avail_out = outSz;
00267 
00268         err = deflate(&ssl->c_stream, Z_SYNC_FLUSH);
00269         if (err != Z_OK && err != Z_STREAM_END) return ZLIB_COMPRESS_ERROR;
00270 
00271         return ssl->c_stream.total_out - currTotal + sizeof(word16);
00272     }
00273         
00274 
00275     /* decompress in to out, returnn out size or error */
00276     static int DeCompress(SSL* ssl, byte* in, int inSz, byte* out, int outSz)
00277     {
00278         int    err;
00279         int    currTotal = ssl->d_stream.total_out;
00280         word16 len;
00281 
00282         /* find size in front of compression */
00283         ato16(in, &len);
00284         in   += 2;
00285         inSz -= 2;
00286 
00287         ssl->d_stream.next_in   = in;
00288         ssl->d_stream.avail_in  = inSz;
00289         ssl->d_stream.next_out  = out;
00290         ssl->d_stream.avail_out = outSz;
00291 
00292         err = inflate(&ssl->d_stream, Z_SYNC_FLUSH);
00293         if (err != Z_OK && err != Z_STREAM_END) return ZLIB_DECOMPRESS_ERROR;
00294 
00295         return ssl->d_stream.total_out - currTotal;
00296     }
00297         
00298 #endif /* HAVE_LIBZ */
00299 
00300 
00301 void InitSSL_Method(SSL_METHOD* method, ProtocolVersion pv)
00302 {
00303     method->version    = pv;
00304     method->side       = CLIENT_END;
00305     method->verifyPeer = 0;
00306     method->verifyNone = 0;
00307     method->failNoCert = 0;
00308     method->downgrade  = 0;
00309 }
00310 
00311 
00312 void InitSSL_Ctx(SSL_CTX* ctx, SSL_METHOD* method)
00313 {
00314     ctx->method = method;
00315     ctx->certificate.buffer = 0;
00316     ctx->privateKey.buffer  = 0;
00317     ctx->haveDH             = 0;
00318     ctx->haveNTRU           = 0;    /* start off */
00319     ctx->heap               = ctx;  /* defaults to self */
00320 #ifndef NO_PSK
00321     ctx->havePSK            = 0;
00322     ctx->server_hint[0]     = 0;
00323     ctx->client_psk_cb      = 0;
00324     ctx->server_psk_cb      = 0;
00325 #endif /* NO_PSK */
00326 
00327 #ifdef OPENSSL_EXTRA
00328     ctx->passwd_cb   = 0;
00329     ctx->userdata    = 0;
00330 #endif /* OPENSSL_EXTRA */
00331 
00332 #ifndef CYASSL_USER_IO
00333     ctx->CBIORecv = EmbedReceive;
00334     ctx->CBIOSend = EmbedSend;
00335 #else
00336     /* user will set */
00337     ctx->CBIORecv = NULL;
00338     ctx->CBIOSend = NULL;
00339 #endif
00340     ctx->partialWrite   = 0;
00341     ctx->verifyCallback = 0;
00342 
00343     ctx->caList = 0;
00344 #ifdef HAVE_NTRU
00345     if (method->side == CLIENT_END)
00346         ctx->haveNTRU = 1;           /* always on cliet side */
00347                                      /* server can turn on by loading key */
00348 #endif
00349     /* remove DH later if server didn't set, add psk later */
00350     InitSuites(&ctx->suites, method->version, TRUE, FALSE, ctx->haveNTRU);  
00351     ctx->verifyPeer = 0;
00352     ctx->verifyNone = 0;
00353     ctx->failNoCert = 0;
00354     ctx->sessionCacheOff      = 0;  /* initially on */
00355     ctx->sessionCacheFlushOff = 0;  /* initially on */
00356     ctx->sendVerify = 0;
00357     ctx->quietShutdown = 0;
00358 
00359 }
00360 
00361 
00362 /* In case contexts are held in array and don't want to free actual ctx */
00363 void SSL_CtxResourceFree(SSL_CTX* ctx)
00364 {
00365     XFREE(ctx->privateKey.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
00366     XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
00367     XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
00368 
00369     FreeSigners(ctx->caList, ctx->heap);
00370 }
00371 
00372 
00373 void FreeSSL_Ctx(SSL_CTX* ctx)
00374 {
00375     SSL_CtxResourceFree(ctx);
00376     XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
00377 }
00378 
00379     
00380 
00381 void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
00382                 byte haveNTRU)
00383 {
00384     word32 idx = 0;
00385     int    tls = pv.major == 3 && pv.minor >= 1;
00386 
00387     (void)tls;  /* shut up compiler */
00388 
00389 #ifdef CYASSL_DTLS
00390     if (pv.major == DTLS_MAJOR && pv.minor == DTLS_MINOR)
00391         tls = 1;
00392 #endif
00393 
00394     suites->setSuites = 0;  /* user hasn't set yet */
00395 
00396 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
00397     if (tls && haveNTRU) {
00398         suites->suites[idx++] = 0; 
00399         suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_256_CBC_SHA;
00400     }
00401 #endif
00402 
00403 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
00404     if (tls && haveNTRU) {
00405         suites->suites[idx++] = 0; 
00406         suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_128_CBC_SHA;
00407     }
00408 #endif
00409 
00410 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
00411     if (tls && haveNTRU) {
00412         suites->suites[idx++] = 0; 
00413         suites->suites[idx++] = TLS_NTRU_RSA_WITH_RC4_128_SHA;
00414     }
00415 #endif
00416 
00417 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
00418     if (tls && haveNTRU) {
00419         suites->suites[idx++] = 0; 
00420         suites->suites[idx++] = TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA;
00421     }
00422 #endif
00423 
00424 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
00425     if (tls && haveDH) {
00426         suites->suites[idx++] = 0; 
00427         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
00428     }
00429 #endif
00430 
00431 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
00432     if (tls && haveDH) {
00433         suites->suites[idx++] = 0; 
00434         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
00435     }
00436 #endif
00437 
00438 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
00439     if (tls) {
00440         suites->suites[idx++] = 0; 
00441         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA;
00442     }
00443 #endif
00444 
00445 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
00446     if (tls) {
00447         suites->suites[idx++] = 0; 
00448         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA;
00449     }
00450 #endif
00451 
00452 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
00453     if (tls && havePSK) {
00454         suites->suites[idx++] = 0; 
00455         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA;
00456     }
00457 #endif
00458 
00459 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
00460     if (tls && havePSK) {
00461         suites->suites[idx++] = 0; 
00462         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA;
00463     }
00464 #endif
00465 
00466 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
00467     suites->suites[idx++] = 0; 
00468     suites->suites[idx++] = SSL_RSA_WITH_RC4_128_SHA;
00469 #endif
00470 
00471 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
00472     suites->suites[idx++] = 0; 
00473     suites->suites[idx++] = SSL_RSA_WITH_RC4_128_MD5;
00474 #endif
00475 
00476 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
00477     suites->suites[idx++] = 0; 
00478     suites->suites[idx++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
00479 #endif
00480 
00481 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
00482     if (tls) {
00483         suites->suites[idx++] = 0; 
00484         suites->suites[idx++] = TLS_RSA_WITH_HC_128_CBC_MD5;
00485     }
00486 #endif
00487     
00488 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
00489     if (tls) {
00490         suites->suites[idx++] = 0; 
00491         suites->suites[idx++] = TLS_RSA_WITH_HC_128_CBC_SHA;
00492     }
00493 #endif
00494 
00495 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
00496     if (tls) {
00497         suites->suites[idx++] = 0; 
00498         suites->suites[idx++] = TLS_RSA_WITH_RABBIT_CBC_SHA;
00499     }
00500 #endif
00501 
00502     suites->suiteSz = idx;
00503 }
00504 
00505 
00506 int InitSSL(SSL* ssl, SSL_CTX* ctx)
00507 {
00508     int  ret;
00509     byte havePSK = 0;
00510 
00511     ssl->ctx     = ctx; /* only for passing to calls, options could change */
00512     ssl->version = ctx->method->version;
00513     ssl->suites  = ctx->suites;
00514 
00515 #ifdef HAVE_LIBZ
00516     ssl->didStreamInit = 0;
00517 #endif
00518    
00519     ssl->buffers.certificate.buffer   = 0;
00520     ssl->buffers.key.buffer           = 0;
00521     ssl->buffers.inputBuffer.length   = 0;
00522     ssl->buffers.inputBuffer.idx      = 0;
00523     ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
00524     ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
00525     ssl->buffers.inputBuffer.dynamicFlag = 0;
00526     ssl->buffers.outputBuffer.length  = 0;
00527     ssl->buffers.outputBuffer.idx     = 0;
00528     ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
00529     ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
00530     ssl->buffers.outputBuffer.dynamicFlag = 0;
00531     ssl->buffers.domainName.buffer    = 0;
00532     ssl->buffers.serverDH_P.buffer    = 0;
00533     ssl->buffers.serverDH_G.buffer    = 0;
00534     ssl->buffers.serverDH_Pub.buffer  = 0;
00535     ssl->buffers.serverDH_Priv.buffer = 0;
00536     ssl->buffers.clearOutputBuffer.buffer  = 0;
00537     ssl->buffers.clearOutputBuffer.length  = 0;
00538     ssl->buffers.prevSent                  = 0;
00539     ssl->buffers.plainSz                   = 0;
00540 
00541     if ( (ret = InitRng(&ssl->rng)) )
00542         return ret;
00543 
00544     InitMd5(&ssl->hashMd5);
00545     InitSha(&ssl->hashSha);
00546     InitRsaKey(&ssl->peerRsaKey, ctx->heap);
00547 
00548     ssl->peerRsaKeyPresent = 0;
00549     ssl->options.side      = ctx->method->side;
00550     ssl->options.downgrade = ctx->method->downgrade;
00551     ssl->error = 0;
00552     ssl->options.connReset = 0;
00553     ssl->options.isClosed  = 0;
00554     ssl->options.closeNotify  = 0;
00555     ssl->options.sentNotify   = 0;
00556     ssl->options.usingCompression = 0;
00557     ssl->options.haveDH    = ctx->haveDH;
00558     ssl->options.haveNTRU  = ctx->haveNTRU;
00559     ssl->options.havePeerCert = 0; 
00560     ssl->options.usingPSK_cipher = 0;
00561     ssl->options.sendAlertState = 0;
00562 #ifndef NO_PSK
00563     havePSK = ctx->havePSK;
00564     ssl->options.havePSK   = ctx->havePSK;
00565     ssl->options.client_psk_cb = ctx->client_psk_cb;
00566     ssl->options.server_psk_cb = ctx->server_psk_cb;
00567 #endif /* NO_PSK */
00568 
00569     ssl->options.serverState = NULL_STATE;
00570     ssl->options.clientState = NULL_STATE;
00571     ssl->options.connectState = CONNECT_BEGIN;
00572     ssl->options.acceptState  = ACCEPT_BEGIN; 
00573     ssl->options.handShakeState  = NULL_STATE; 
00574     ssl->options.processReply = doProcessInit;
00575 
00576 #ifdef CYASSL_DTLS
00577     ssl->keys.dtls_sequence_number       = 0;
00578     ssl->keys.dtls_peer_sequence_number  = 0;
00579     ssl->keys.dtls_handshake_number      = 0;
00580     ssl->keys.dtls_epoch      = 0;
00581     ssl->keys.dtls_peer_epoch = 0;
00582 #endif
00583     ssl->keys.encryptionOn = 0;     /* initially off */
00584     ssl->options.sessionCacheOff      = ctx->sessionCacheOff;
00585     ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
00586 
00587     ssl->options.verifyPeer = ctx->verifyPeer;
00588     ssl->options.verifyNone = ctx->verifyNone;
00589     ssl->options.failNoCert = ctx->failNoCert;
00590     ssl->options.sendVerify = ctx->sendVerify;
00591     
00592     ssl->options.resuming = 0;
00593     ssl->hmac = Hmac;         /* default to SSLv3 */
00594     ssl->heap = ctx->heap;    /* defaults to self */
00595     ssl->options.tls    = 0;
00596     ssl->options.tls1_1 = 0;
00597     ssl->options.dtls   = 0;
00598     ssl->options.partialWrite  = ctx->partialWrite;
00599     ssl->options.quietShutdown = ctx->quietShutdown;
00600 
00601     /* SSL_CTX still owns certificate, key, and caList buffers */
00602     ssl->buffers.certificate = ctx->certificate;
00603     ssl->buffers.key = ctx->privateKey;
00604     ssl->caList = ctx->caList;
00605 
00606 #ifdef OPENSSL_EXTRA
00607     ssl->peerCert.issuer.sz    = 0;
00608     ssl->peerCert.subject.sz   = 0;
00609 #endif
00610     
00611     /* make sure server has cert and key unless using PSK */
00612     if (ssl->options.side == SERVER_END && !havePSK)
00613         if (!ssl->buffers.certificate.buffer || !ssl->buffers.key.buffer)
00614             return NO_PRIVATE_KEY;
00615 
00616 #ifndef NO_PSK
00617     ssl->arrays.client_identity[0] = 0;
00618     if (ctx->server_hint[0])   /* set in CTX */
00619         XSTRNCPY(ssl->arrays.server_hint, ctx->server_hint, MAX_PSK_ID_LEN);
00620     else
00621         ssl->arrays.server_hint[0] = 0;
00622 #endif /* NO_PSK */
00623 
00624 #ifdef CYASSL_CALLBACKS
00625     ssl->hsInfoOn = 0;
00626     ssl->toInfoOn = 0;
00627 #endif
00628 
00629     /* make sure server has DH parms, and add PSK if there, add NTRU too */
00630     if (!ssl->ctx->suites.setSuites) {    /* trust user override */
00631         if (ssl->options.side == SERVER_END) 
00632             InitSuites(&ssl->suites, ssl->version,ssl->options.haveDH, havePSK,
00633                        ssl->options.haveNTRU);
00634         else 
00635             InitSuites(&ssl->suites, ssl->version, TRUE, havePSK,
00636                        ssl->options.haveNTRU);
00637     }
00638 
00639     ssl->rfd = -1;   /* set to invalid descriptor */
00640     ssl->wfd = -1;
00641     ssl->biord = 0;
00642     ssl->biowr = 0;
00643 
00644     ssl->IOCB_ReadCtx  = &ssl->rfd;   /* prevent invalid pointer acess if not */
00645     ssl->IOCB_WriteCtx = &ssl->wfd;   /* correctly set */
00646 
00647 #ifdef SESSION_CERTS
00648     ssl->session.chain.count = 0;
00649 #endif
00650 
00651     ssl->cipher.ssl = ssl;
00652 
00653     return 0;
00654 }
00655 
00656 
00657 int BIO_free(BIO*);  /* cyassl_int doesn't have */
00658 
00659 
00660 /* In case holding SSL object in array and don't want to free actual ssl */
00661 void SSL_ResourceFree(SSL* ssl)
00662 {
00663     XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
00664     XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH);
00665     XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
00666     XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
00667     XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
00668     FreeRsaKey(&ssl->peerRsaKey);
00669     if (ssl->buffers.inputBuffer.dynamicFlag)
00670         ShrinkInputBuffer(ssl, FORCED_FREE);
00671     if (ssl->buffers.outputBuffer.dynamicFlag)
00672         ShrinkOutputBuffer(ssl);
00673 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
00674     BIO_free(ssl->biord);
00675     if (ssl->biord != ssl->biowr)        /* in case same as write */
00676         BIO_free(ssl->biowr);
00677 #endif
00678 #ifdef HAVE_LIBZ
00679     FreeStreams(ssl);
00680 #endif
00681 }
00682 
00683 
00684 void FreeSSL(SSL* ssl)
00685 {
00686     SSL_ResourceFree(ssl);
00687     XFREE(ssl, ssl->heap, DYNAMIC_TYPE_SSL);
00688 }
00689 
00690 
00691 ProtocolVersion MakeSSLv3(void)
00692 {
00693     ProtocolVersion pv;
00694     pv.major = SSLv3_MAJOR;
00695     pv.minor = SSLv3_MINOR;
00696 
00697     return pv;
00698 }
00699 
00700 
00701 #ifdef CYASSL_DTLS
00702 
00703 ProtocolVersion MakeDTLSv1(void)
00704 {
00705     ProtocolVersion pv;
00706     pv.major = DTLS_MAJOR;
00707     pv.minor = DTLS_MINOR;
00708 
00709     return pv;
00710 }
00711 
00712 #endif /* CYASSL_DTLS */
00713 
00714 
00715 
00716 
00717 #ifdef USE_WINDOWS_API 
00718 
00719     timer_d Timer(void)
00720     {
00721         static int           init = 0;
00722         static LARGE_INTEGER freq;
00723         LARGE_INTEGER        count;
00724     
00725         if (!init) {
00726             QueryPerformanceFrequency(&freq);
00727             init = 1;
00728         }
00729 
00730         QueryPerformanceCounter(&count);
00731 
00732         return (double)count.QuadPart / freq.QuadPart;
00733     }
00734 
00735 
00736     word32 LowResTimer(void)
00737     {
00738         return (word32)Timer();
00739     }
00740 
00741 
00742 #elif defined(THREADX)
00743 
00744     #include "rtptime.h"
00745 
00746     word32 LowResTimer(void)
00747     {
00748         return (word32)rtp_get_system_sec();
00749     }
00750 
00751 
00752 #elif defined(MICRIUM)
00753 
00754     word32 LowResTimer(void)
00755     {
00756         NET_SECURE_OS_TICK  clk;
00757 
00758         #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
00759             clk = NetSecure_OS_TimeGet();
00760         #endif
00761         return (word32)clk;
00762     }
00763 
00764 #elif defined(USER_TICKS)
00765 
00766     word32 LowResTimer(void)
00767     {
00768         /*
00769         write your own clock tick function if don't want time(0)
00770         needs second accuracy but doesn't have to correlated to EPOCH
00771         */
00772     }
00773 
00774 #else /* !USE_WINDOWS_API && !THREADX && !MICRIUM && !USER_TICKS */
00775 
00776     #include <time.h>
00777 
00778     word32 LowResTimer(void)
00779     {
00780         return time(0); 
00781     }
00782 
00783 
00784 #endif /* USE_WINDOWS_API */
00785 
00786 
00787 /* add output to md5 and sha handshake hashes, exclude record header */
00788 static void HashOutput(SSL* ssl, const byte* output, int sz, int ivSz)
00789 {
00790     const byte* buffer = output + RECORD_HEADER_SZ + ivSz;
00791     sz -= RECORD_HEADER_SZ;
00792     
00793 #ifdef CYASSL_DTLS
00794     if (ssl->options.dtls) {
00795         buffer += DTLS_RECORD_EXTRA;
00796         sz     -= DTLS_RECORD_EXTRA;
00797     }
00798 #endif
00799 
00800     Md5Update(&ssl->hashMd5, buffer, sz);
00801     ShaUpdate(&ssl->hashSha, buffer, sz);
00802 }
00803 
00804 
00805 /* add input to md5 and sha handshake hashes, include handshake header */
00806 static void HashInput(SSL* ssl, const byte* input, int sz)
00807 {
00808     const byte* buffer = input - HANDSHAKE_HEADER_SZ;
00809     sz += HANDSHAKE_HEADER_SZ;
00810     
00811 #ifdef CYASSL_DTLS
00812     if (ssl->options.dtls) {
00813         buffer -= DTLS_HANDSHAKE_EXTRA;
00814         sz     += DTLS_HANDSHAKE_EXTRA;
00815     }
00816 #endif
00817 
00818     Md5Update(&ssl->hashMd5, buffer, sz);
00819     ShaUpdate(&ssl->hashSha, buffer, sz);
00820 }
00821 
00822 
00823 /* add record layer header for message */
00824 static void AddRecordHeader(byte* output, word32 length, byte type, SSL* ssl)
00825 {
00826     RecordLayerHeader* rl;
00827   
00828     /* record layer header */
00829     rl = (RecordLayerHeader*)output;
00830     rl->type    = type;
00831     rl->version = ssl->version;           /* type and version same in each */
00832 
00833     if (!ssl->options.dtls)
00834         c16toa((word16)length, rl->length);
00835     else {
00836 #ifdef CYASSL_DTLS
00837         DtlsRecordLayerHeader* dtls;
00838     
00839         /* dtls record layer header extensions */
00840         dtls = (DtlsRecordLayerHeader*)output;
00841         c16toa(ssl->keys.dtls_epoch, dtls->epoch);
00842         c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number);
00843         c16toa((word16)length, dtls->length);
00844 #endif
00845     }
00846 }
00847 
00848 
00849 /* add handshake header for message */
00850 static void AddHandShakeHeader(byte* output, word32 length, byte type, SSL* ssl)
00851 {
00852     HandShakeHeader* hs;
00853  
00854     /* handshake header */
00855     hs = (HandShakeHeader*)output;
00856     hs->type = type;
00857     c32to24(length, hs->length);         /* type and length same for each */
00858 #ifdef CYASSL_DTLS
00859     if (ssl->options.dtls) {
00860         DtlsHandShakeHeader* dtls;
00861     
00862         /* dtls handshake header extensions */
00863         dtls = (DtlsHandShakeHeader*)output;
00864         c16toa(ssl->keys.dtls_handshake_number++, dtls->message_seq);
00865         c32to24(0, dtls->fragment_offset);
00866         c32to24(length, dtls->fragment_length);
00867     }
00868 #endif
00869 }
00870 
00871 
00872 /* add both headers for handshake message */
00873 static void AddHeaders(byte* output, word32 length, byte type, SSL* ssl)
00874 {
00875     if (!ssl->options.dtls) {
00876         AddRecordHeader(output, length + HANDSHAKE_HEADER_SZ, handshake, ssl);
00877         AddHandShakeHeader(output + RECORD_HEADER_SZ, length, type, ssl);
00878     }
00879     else  {
00880         AddRecordHeader(output, length+DTLS_HANDSHAKE_HEADER_SZ, handshake,ssl);
00881         AddHandShakeHeader(output + DTLS_RECORD_HEADER_SZ, length, type, ssl);
00882     }
00883 }
00884 
00885 
00886 static int Receive(SSL* ssl, byte* buf, word32 sz, int flags)
00887 {
00888     int recvd;
00889 
00890 retry:
00891     recvd = ssl->ctx->CBIORecv((char *)buf, (int)sz, ssl->IOCB_ReadCtx);
00892     if (recvd < 0)
00893         switch (recvd) {
00894             case IO_ERR_GENERAL:        /* general/unknown error */
00895                 return -1;
00896 
00897             case IO_ERR_WANT_READ:      /* want read, would block */
00898                 return WANT_READ;
00899 
00900             case IO_ERR_CONN_RST:       /* connection reset */
00901                 ssl->options.connReset = 1;
00902                 return -1;
00903 
00904             case IO_ERR_ISR:            /* interrupt */
00905                 /* see if we got our timeout */
00906                 #ifdef CYASSL_CALLBACKS
00907                     if (ssl->toInfoOn) {
00908                         struct itimerval timeout;
00909                         getitimer(ITIMER_REAL, &timeout);
00910                         if (timeout.it_value.tv_sec == 0 && 
00911                                                 timeout.it_value.tv_usec == 0) {
00912                             XSTRNCPY(ssl->timeoutInfo.timeoutName,
00913                                     "recv() timeout", MAX_TIMEOUT_NAME_SZ);
00914                             return 0;
00915                         }
00916                     }
00917                 #endif
00918                 goto retry;
00919 
00920             case IO_ERR_CONN_CLOSE:     /* peer closed connection */
00921                 ssl->options.isClosed = 1;
00922                 return -1;
00923         }
00924 
00925     return recvd;
00926 }
00927 
00928 
00929 /* Switch dynamic output buffer back to static, buffer is assumed clear */
00930 void ShrinkOutputBuffer(SSL* ssl)
00931 {
00932     CYASSL_MSG("Shrinking output buffer\n");
00933     XFREE(ssl->buffers.outputBuffer.buffer, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
00934     ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
00935     ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
00936     ssl->buffers.outputBuffer.dynamicFlag = 0;
00937 }
00938 
00939 
00940 /* Switch dynamic input buffer back to static, keep any remaining input */
00941 /* forced free means cleaning up */
00942 void ShrinkInputBuffer(SSL* ssl, int forcedFree)
00943 {
00944     int usedLength = ssl->buffers.inputBuffer.length -
00945                      ssl->buffers.inputBuffer.idx;
00946     if (!forcedFree && usedLength > STATIC_BUFFER_LEN)
00947         return;
00948 
00949     CYASSL_MSG("Shrinking input buffer\n");
00950 
00951     if (!forcedFree && usedLength)
00952         XMEMCPY(ssl->buffers.inputBuffer.staticBuffer,
00953                ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
00954                usedLength);
00955 
00956     XFREE(ssl->buffers.inputBuffer.buffer, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
00957     ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
00958     ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
00959     ssl->buffers.inputBuffer.dynamicFlag = 0;
00960     ssl->buffers.inputBuffer.idx = 0;
00961     ssl->buffers.inputBuffer.length = usedLength;
00962 }
00963 
00964 
00965 int SendBuffered(SSL* ssl)
00966 {
00967     while (ssl->buffers.outputBuffer.length > 0) {
00968         int sent = ssl->ctx->CBIOSend((char*)ssl->buffers.outputBuffer.buffer +
00969                                       ssl->buffers.outputBuffer.idx,
00970                                       (int)ssl->buffers.outputBuffer.length,
00971                                       ssl->IOCB_WriteCtx);
00972         if (sent < 0) {
00973             switch (sent) {
00974 
00975                 case IO_ERR_WANT_WRITE:        /* would block */
00976                     return WANT_WRITE;
00977 
00978                 case IO_ERR_CONN_RST:          /* connection reset */
00979                     ssl->options.connReset = 1;
00980                     break;
00981 
00982                 case IO_ERR_ISR:               /* interrupt */
00983                     /* see if we got our timeout */
00984                     #ifdef CYASSL_CALLBACKS
00985                         if (ssl->toInfoOn) {
00986                             struct itimerval timeout;
00987                             getitimer(ITIMER_REAL, &timeout);
00988                             if (timeout.it_value.tv_sec == 0 && 
00989                                                 timeout.it_value.tv_usec == 0) {
00990                                 XSTRNCPY(ssl->timeoutInfo.timeoutName,
00991                                         "send() timeout", MAX_TIMEOUT_NAME_SZ);
00992                                 return WANT_WRITE;
00993                             }
00994                         }
00995                     #endif
00996                     continue;
00997 
00998                 case IO_ERR_CONN_CLOSE: /* epipe / conn closed, same as reset */
00999                     ssl->options.connReset = 1;
01000                     break;
01001             }
01002 
01003             return SOCKET_ERROR_E;
01004         }
01005 
01006         ssl->buffers.outputBuffer.idx += sent;
01007         ssl->buffers.outputBuffer.length -= sent;
01008     }
01009       
01010     ssl->buffers.outputBuffer.idx = 0;
01011 
01012     if (ssl->buffers.outputBuffer.dynamicFlag)
01013         ShrinkOutputBuffer(ssl);
01014 
01015     return 0;
01016 }
01017 
01018 
01019 /* Grow the output buffer, should only be to send cert, should be blank */
01020 static INLINE int GrowOutputBuffer(SSL* ssl, int size)
01021 {
01022     byte* tmp = (byte*) XMALLOC(size + ssl->buffers.outputBuffer.length,
01023                                 ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
01024     CYASSL_MSG("growing output buffer\n");
01025    
01026     if (!tmp) return -1;
01027 
01028     if (ssl->buffers.outputBuffer.length)
01029         XMEMCPY(tmp, ssl->buffers.outputBuffer.buffer,
01030                ssl->buffers.outputBuffer.length);
01031 
01032     if (ssl->buffers.outputBuffer.dynamicFlag)
01033         XFREE(ssl->buffers.outputBuffer.buffer, ssl->heap,
01034               DYNAMIC_TYPE_OUT_BUFFER);
01035     ssl->buffers.outputBuffer.dynamicFlag = 1;
01036     ssl->buffers.outputBuffer.buffer = tmp;
01037     ssl->buffers.outputBuffer.bufferSize = size +
01038                                            ssl->buffers.outputBuffer.length; 
01039     return 0;
01040 }
01041 
01042 
01043 /* Grow the input buffer, should only be to read cert or big app data */
01044 static INLINE int GrowInputBuffer(SSL* ssl, int size, int usedLength)
01045 {
01046     byte* tmp = (byte*) XMALLOC(size + usedLength, ssl->heap,
01047                                 DYNAMIC_TYPE_IN_BUFFER);
01048     CYASSL_MSG("growing input buffer\n");
01049    
01050     if (!tmp) return -1;
01051 
01052     if (usedLength)
01053         XMEMCPY(tmp, ssl->buffers.inputBuffer.buffer +
01054                     ssl->buffers.inputBuffer.idx, usedLength);
01055 
01056     if (ssl->buffers.inputBuffer.dynamicFlag)
01057         XFREE(ssl->buffers.inputBuffer.buffer,ssl->heap,DYNAMIC_TYPE_IN_BUFFER);
01058 
01059     ssl->buffers.inputBuffer.dynamicFlag = 1;
01060     ssl->buffers.inputBuffer.buffer = tmp;
01061     ssl->buffers.inputBuffer.bufferSize = size + usedLength;
01062     ssl->buffers.inputBuffer.idx    = 0;
01063     ssl->buffers.inputBuffer.length = usedLength;
01064 
01065     return 0;
01066 }
01067 
01068 
01069 /* check avalaible size into outbut buffer */
01070 static INLINE int CheckAvalaibleSize(SSL *ssl, int size)
01071 {
01072     if ((word32)size > ssl->buffers.outputBuffer.bufferSize)
01073         if (GrowOutputBuffer(ssl, size) < 0)
01074             return MEMORY_E;
01075 
01076     if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length
01077                                              < (word32)size) {
01078         if (SendBuffered(ssl) == SOCKET_ERROR_E)
01079             return SOCKET_ERROR_E;
01080         if (ssl->buffers.outputBuffer.bufferSize -
01081                                 ssl->buffers.outputBuffer.length < (word32)size)
01082             return WANT_WRITE;
01083     }
01084     return 0;
01085 }
01086 
01087 /* do all verify and sanity checks on record header */
01088 static int GetRecordHeader(SSL* ssl, const byte* input, word32* inOutIdx,
01089                            RecordLayerHeader* rh, word16 *size)
01090 {
01091     if (!ssl->options.dtls) {
01092         XMEMCPY(rh, input + *inOutIdx, RECORD_HEADER_SZ);
01093         *inOutIdx += RECORD_HEADER_SZ;
01094         ato16(rh->length, size);
01095     }
01096     else {
01097 #ifdef CYASSL_DTLS
01098         /* type and version in same sport */
01099         XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
01100         *inOutIdx += ENUM_LEN + VERSION_SZ;
01101         *inOutIdx += 4;  /* skip epoch and first 2 seq bytes for now */
01102         ato32(input + *inOutIdx, &ssl->keys.dtls_peer_sequence_number);
01103         *inOutIdx += 4;  /* advance past rest of seq */
01104         ato16(input + *inOutIdx, size);
01105         *inOutIdx += LENGTH_SZ;
01106 #endif
01107     }
01108 
01109     /* catch version mismatch */
01110     if (rh->version.major != ssl->version.major || 
01111         rh->version.minor != ssl->version.minor) {
01112         
01113         if (ssl->options.side == SERVER_END && ssl->options.downgrade == 1 &&
01114             ssl->options.acceptState == ACCEPT_BEGIN)
01115             ;                                  /* haven't negotiated yet */
01116         else
01117             return VERSION_ERROR;              /* only use requested version */
01118     }
01119 
01120     /* record layer length check */
01121     if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
01122         return LENGTH_ERROR;
01123 
01124     /* verify record type here as well */
01125     switch ((enum ContentType)rh->type) {
01126         case handshake:
01127         case change_cipher_spec:
01128         case application_data:
01129         case alert:
01130             break;
01131         default:
01132             return UNKNOWN_RECORD_TYPE;
01133     }
01134 
01135     return 0;
01136 }
01137 
01138 
01139 static int GetHandShakeHeader(SSL* ssl, const byte* input, word32* inOutIdx,
01140                               byte *type, word32 *size)
01141 {
01142     const byte *ptr = input + *inOutIdx;
01143     *inOutIdx += HANDSHAKE_HEADER_SZ;
01144     
01145 #ifdef CYASSL_DTLS
01146     if (ssl->options.dtls)
01147         *inOutIdx += DTLS_HANDSHAKE_EXTRA;
01148 #endif
01149 
01150     *type = ptr[0];
01151     c24to32(&ptr[1], size);
01152 
01153     return 0;
01154 }
01155 
01156 
01157 /* fill with MD5 pad size since biggest required */
01158 static const byte PAD1[PAD_MD5] = 
01159                               { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
01160                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
01161                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
01162                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
01163                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
01164                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
01165                               };
01166 static const byte PAD2[PAD_MD5] =
01167                               { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
01168                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
01169                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
01170                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
01171                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
01172                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
01173                               };
01174 
01175 /* calculate MD5 hash for finished */
01176 static void BuildMD5(SSL* ssl, Hashes* hashes, const byte* sender)
01177 {
01178     byte md5_result[MD5_DIGEST_SIZE];
01179 
01180     /* make md5 inner */    
01181     Md5Update(&ssl->hashMd5, sender, SIZEOF_SENDER);
01182     Md5Update(&ssl->hashMd5, ssl->arrays.masterSecret, SECRET_LEN);
01183     Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
01184     Md5Final(&ssl->hashMd5, md5_result);
01185 
01186     /* make md5 outer */
01187     Md5Update(&ssl->hashMd5, ssl->arrays.masterSecret, SECRET_LEN);
01188     Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
01189     Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
01190 
01191     Md5Final(&ssl->hashMd5, hashes->md5);
01192 }
01193 
01194 
01195 /* calculate SHA hash for finished */
01196 static void BuildSHA(SSL* ssl, Hashes* hashes, const byte* sender)
01197 {
01198     byte sha_result[SHA_DIGEST_SIZE];
01199 
01200     /* make sha inner */
01201     ShaUpdate(&ssl->hashSha, sender, SIZEOF_SENDER);
01202     ShaUpdate(&ssl->hashSha, ssl->arrays.masterSecret, SECRET_LEN);
01203     ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
01204     ShaFinal(&ssl->hashSha, sha_result);
01205 
01206     /* make sha outer */
01207     ShaUpdate(&ssl->hashSha, ssl->arrays.masterSecret, SECRET_LEN);
01208     ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
01209     ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
01210 
01211     ShaFinal(&ssl->hashSha, hashes->sha);
01212 }
01213 
01214 
01215 static void BuildFinished(SSL* ssl, Hashes* hashes, const byte* sender)
01216 {
01217     /* store current states, building requires get_digest which resets state */
01218     Md5 md5 = ssl->hashMd5;
01219     Sha sha = ssl->hashSha;
01220 
01221     if (ssl->options.tls)
01222         BuildTlsFinished(ssl, hashes, sender);
01223     else {
01224         BuildMD5(ssl, hashes, sender);
01225         BuildSHA(ssl, hashes, sender);
01226     }
01227     
01228     /* restore */
01229     ssl->hashMd5 = md5;
01230     ssl->hashSha = sha;
01231 }
01232 
01233 
01234 static int DoCertificate(SSL* ssl, byte* input, word32* inOutIdx)
01235 {
01236     word32 listSz, i = *inOutIdx;
01237     int    ret = 0;
01238     int    firstTime = 1;  /* peer's is at front */
01239     char   domain[ASN_NAME_MAX];
01240 
01241     #ifdef CYASSL_CALLBACKS
01242         if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
01243         if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo);
01244     #endif
01245     c24to32(&input[i], &listSz);
01246     i += CERT_HEADER_SZ;
01247     
01248     while (listSz && ret == 0) {
01249         /* cert size */
01250         buffer      myCert;
01251         word32      certSz;
01252         DecodedCert dCert;
01253         word32      idx = 0;
01254 
01255         c24to32(&input[i], &certSz);
01256         i += CERT_HEADER_SZ;
01257         
01258         myCert.length = certSz;
01259         myCert.buffer = input + i;
01260         i += certSz;
01261 
01262         listSz -= certSz + CERT_HEADER_SZ;
01263 
01264 #ifdef SESSION_CERTS
01265         if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
01266                                        myCert.length < MAX_X509_SIZE) {
01267             ssl->session.chain.certs[ssl->session.chain.count].length =
01268                  myCert.length;
01269             XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer,
01270                    myCert.buffer, myCert.length);
01271             ssl->session.chain.count++;
01272         } else {
01273             CYASSL_MSG("Couldn't store chain cert for session");
01274         }
01275 #endif
01276 
01277         InitDecodedCert(&dCert, myCert.buffer, ssl->heap);
01278         ret = ParseCertRelative(&dCert, myCert.length, CERT_TYPE,
01279                                 !ssl->options.verifyNone, ssl->caList);
01280 
01281         if (!firstTime) {
01282             FreeDecodedCert(&dCert);
01283             continue;
01284         }
01285 
01286         /* get rest of peer info in case user wants to continue */
01287         if (ret != 0) {
01288             if (!(ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E ||
01289                                               ret == ASN_SIG_CONFIRM_E)) {
01290                 FreeDecodedCert(&dCert);
01291                 continue;
01292             }
01293         }
01294         
01295         /* first one has peer's key */
01296         firstTime = 0;
01297 
01298         ssl->options.havePeerCert = 1;
01299         /* set X509 format */
01300 #ifdef OPENSSL_EXTRA
01301         ssl->peerCert.issuer.sz    = (int)XSTRLEN(dCert.issuer) + 1;
01302         XSTRNCPY(ssl->peerCert.issuer.name, dCert.issuer, ASN_NAME_MAX);
01303         ssl->peerCert.subject.sz   = (int)XSTRLEN(dCert.subject) + 1;
01304         XSTRNCPY(ssl->peerCert.subject.name, dCert.subject, ASN_NAME_MAX);
01305 #endif    
01306 
01307         XMEMCPY(domain, dCert.subjectCN, dCert.subjectCNLen);
01308         domain[dCert.subjectCNLen] = '\0';
01309 
01310         if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer)
01311             if (XSTRNCMP((char*)ssl->buffers.domainName.buffer,
01312                         dCert.subjectCN,
01313                         ssl->buffers.domainName.length - 1)) {
01314                 ret = DOMAIN_NAME_MISMATCH;   /* try to get peer key still */
01315             }
01316 
01317         /* decode peer key */
01318         if (dCert.keyOID == RSAk) {
01319             if (RsaPublicKeyDecode(dCert.publicKey, &idx,
01320                                &ssl->peerRsaKey, dCert.pubKeySize) != 0) {
01321                 ret = PEER_KEY_ERROR;
01322                 FreeDecodedCert(&dCert);
01323                 continue;
01324             }
01325             ssl->peerRsaKeyPresent = 1;
01326         }
01327 #ifdef HAVE_NTRU
01328         else if (dCert.keyOID == NTRUk) {
01329             if (dCert.pubKeySize > sizeof(ssl->peerNtruKey)) {
01330                 ret = PEER_KEY_ERROR;
01331                 FreeDecodedCert(&dCert);
01332                 continue;
01333             }
01334             XMEMCPY(ssl->peerNtruKey, dCert.publicKey, dCert.pubKeySize);
01335             ssl->peerNtruKeyLen = (word16)dCert.pubKeySize;
01336             ssl->peerNtruKeyPresent = 1;
01337         }
01338 #endif
01339 
01340         FreeDecodedCert(&dCert);
01341     }
01342 
01343     if (ret == 0 && ssl->options.side == CLIENT_END)
01344         ssl->options.serverState = SERVER_CERT_COMPLETE;
01345 
01346     if (ret != 0) {
01347         if (!ssl->options.verifyNone) {
01348             int why = bad_certificate;
01349             if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E)
01350                 why = certificate_expired;
01351             if (ssl->ctx->verifyCallback) {
01352                 int            ok;
01353                 X509_STORE_CTX store;
01354 
01355                 store.error = ret;
01356                 store.error_depth = 1;
01357                 store.domain = domain;
01358 #ifdef OPENSSL_EXTRA
01359                 store.current_cert = &ssl->peerCert;
01360 #else
01361                 store.current_cert = NULL;
01362 #endif
01363                 ok = ssl->ctx->verifyCallback(0, &store);
01364                 if (ok)
01365                     ret = 0;
01366             }
01367             if (ret != 0) {
01368                 SendAlert(ssl, alert_fatal, why);   /* try to send */
01369                 ssl->options.isClosed = 1;
01370             }
01371         }
01372         ssl->error = ret;
01373     }
01374 
01375     *inOutIdx = i;
01376     return ret;
01377 }
01378 
01379 
01380 int DoFinished(SSL* ssl, const byte* input, word32* inOutIdx, int sniff)
01381 {
01382     byte   verifyMAC[SHA_DIGEST_SIZE];
01383     int    finishedSz = ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ;
01384     int    headerSz = HANDSHAKE_HEADER_SZ;
01385     word32 macSz = finishedSz + HANDSHAKE_HEADER_SZ,
01386            idx = *inOutIdx,
01387            padSz = ssl->keys.encryptSz - HANDSHAKE_HEADER_SZ - finishedSz -
01388                    ssl->specs.hash_size;
01389     const byte* mac;
01390 
01391     #ifdef CYASSL_DTLS
01392         if (ssl->options.dtls) {
01393             headerSz += DTLS_HANDSHAKE_EXTRA;
01394             macSz    += DTLS_HANDSHAKE_EXTRA;
01395             padSz    -= DTLS_HANDSHAKE_EXTRA;
01396         }
01397     #endif
01398 
01399     #ifdef CYASSL_CALLBACKS
01400         if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
01401         if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
01402     #endif
01403     if (sniff == NO_SNIFF) {
01404         if (XMEMCMP(input + idx, &ssl->verifyHashes, finishedSz))
01405             return VERIFY_FINISHED_ERROR;
01406     }
01407 
01408     ssl->hmac(ssl, verifyMAC, input + idx - headerSz, macSz,
01409          handshake, 1);
01410     idx += finishedSz;
01411 
01412     /* read mac and fill */
01413     mac = input + idx;
01414     idx += ssl->specs.hash_size;
01415 
01416     if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
01417         padSz -= ssl->specs.block_size;
01418 
01419     idx += padSz;
01420 
01421     /* verify mac */
01422     if (XMEMCMP(mac, verifyMAC, ssl->specs.hash_size))
01423         return VERIFY_MAC_ERROR;
01424 
01425     if (ssl->options.side == CLIENT_END) {
01426         ssl->options.serverState = SERVER_FINISHED_COMPLETE;
01427         if (!ssl->options.resuming)
01428             ssl->options.handShakeState = HANDSHAKE_DONE;
01429     }
01430     else {
01431         ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
01432         if (ssl->options.resuming)
01433             ssl->options.handShakeState = HANDSHAKE_DONE;
01434     }
01435 
01436     *inOutIdx = idx;
01437     return 0;
01438 }
01439 
01440 
01441 static int DoHandShakeMsg(SSL* ssl, byte* input, word32* inOutIdx,
01442                           word32 totalSz)
01443 {
01444     byte type;
01445     word32 size;
01446     int ret = 0;
01447 
01448     CYASSL_ENTER("DoHandShakeMsg()");
01449 
01450     if (GetHandShakeHeader(ssl, input, inOutIdx, &type, &size) != 0)
01451         return PARSE_ERROR;
01452 
01453     if (*inOutIdx + size > totalSz)
01454         return INCOMPLETE_DATA;
01455     
01456     HashInput(ssl, input + *inOutIdx, size);
01457 #ifdef CYASSL_CALLBACKS
01458     /* add name later, add on record and handshake header  part back on */
01459     if (ssl->toInfoOn) {
01460         int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
01461         AddPacketInfo(0, &ssl->timeoutInfo, input + *inOutIdx - add,
01462                       size + add, ssl->heap);
01463         AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
01464     }
01465 #endif
01466 
01467     switch (type) {
01468 
01469 #ifndef NO_CYASSL_CLIENT
01470     case hello_verify_request:
01471         CYASSL_MSG("processing hello verify request");
01472         ret = DoHelloVerifyRequest(ssl, input,inOutIdx);
01473         break;
01474             
01475     case server_hello:
01476         CYASSL_MSG("processing server hello");
01477         ret = DoServerHello(ssl, input, inOutIdx);
01478         break;
01479 
01480     case certificate_request:
01481         CYASSL_MSG("processing certificate request");
01482         ret = DoCertificateRequest(ssl, input, inOutIdx);
01483         break;
01484 
01485     case server_key_exchange:
01486         CYASSL_MSG("processing server key exchange");
01487         ret = DoServerKeyExchange(ssl, input, inOutIdx);
01488         break;
01489 #endif
01490 
01491     case certificate:
01492         CYASSL_MSG("processing certificate");
01493         ret =  DoCertificate(ssl, input, inOutIdx);
01494         break;
01495 
01496     case server_hello_done:
01497         CYASSL_MSG("processing server hello done");
01498         #ifdef CYASSL_CALLBACKS
01499             if (ssl->hsInfoOn) 
01500                 AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
01501             if (ssl->toInfoOn)
01502                 AddLateName("ServerHelloDone", &ssl->timeoutInfo);
01503         #endif
01504         ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
01505         break;
01506 
01507     case finished:
01508         CYASSL_MSG("processing finished");
01509         ret = DoFinished(ssl, input, inOutIdx, NO_SNIFF);
01510         break;
01511 
01512 #ifndef NO_CYASSL_SERVER
01513     case client_hello:
01514         CYASSL_MSG("processing client hello");
01515         ret = DoClientHello(ssl, input, inOutIdx, totalSz, size);
01516         break;
01517 
01518     case client_key_exchange:
01519         CYASSL_MSG("processing client key exchange");
01520         ret = DoClientKeyExchange(ssl, input, inOutIdx);
01521         break;
01522 
01523     case certificate_verify:
01524         CYASSL_MSG("processing certificate verify");
01525         ret = DoCertificateVerify(ssl, input, inOutIdx, totalSz);
01526         break;
01527 
01528 #endif
01529 
01530     default:
01531         ret = UNKNOWN_HANDSHAKE_TYPE;
01532     }
01533 
01534     CYASSL_LEAVE("DoHandShakeMsg()", ret);
01535     return ret;
01536 }
01537 
01538 
01539 static INLINE void Encrypt(SSL* ssl, byte* out, const byte* input, word32 sz)
01540 {
01541     switch (ssl->specs.bulk_cipher_algorithm) {
01542         #ifdef BUILD_ARC4
01543             case rc4:
01544                 Arc4Process(&ssl->encrypt.arc4, out, input, sz);
01545                 break;
01546         #endif
01547 
01548         #ifdef BUILD_DES3
01549             case triple_des:
01550                 Des3_CbcEncrypt(&ssl->encrypt.des3, out, input, sz);
01551                 break;
01552         #endif
01553 
01554         #ifdef BUILD_AES
01555             case aes:
01556 #ifdef CYASSL_AESNI
01557                 if ((word)input % 16) {
01558                     byte buffer[MAX_RECORD_SIZE + MAX_COMP_EXTRA+MAX_MSG_EXTRA];
01559                     XMEMCPY(buffer, input, sz);
01560                     AesCbcEncrypt(&ssl->encrypt.aes, buffer, buffer, sz);
01561                     XMEMCPY(out, buffer, sz);
01562                     break;
01563                 }
01564 #endif
01565                 AesCbcEncrypt(&ssl->encrypt.aes, out, input, sz);
01566                 break;
01567         #endif
01568 
01569         #ifdef BUILD_HC128
01570             case hc128:
01571                 Hc128_Process(&ssl->encrypt.hc128, out, input, sz);
01572                 break;
01573         #endif
01574 
01575         #ifdef BUILD_RABBIT
01576             case rabbit:
01577                 RabbitProcess(&ssl->encrypt.rabbit, out, input, sz);
01578                 break;
01579         #endif
01580     }
01581 }
01582 
01583 
01584 static INLINE void Decrypt(SSL* ssl, byte* plain, const byte* input, word32 sz)
01585 {
01586     switch (ssl->specs.bulk_cipher_algorithm) {
01587         #ifdef BUILD_ARC4
01588             case rc4:
01589                 Arc4Process(&ssl->decrypt.arc4, plain, input, sz);
01590                 break;
01591         #endif
01592 
01593         #ifdef BUILD_DES3
01594             case triple_des:
01595                 Des3_CbcDecrypt(&ssl->decrypt.des3, plain, input, sz);
01596                 break;
01597         #endif
01598 
01599         #ifdef BUILD_AES
01600             case aes:
01601                 AesCbcDecrypt(&ssl->decrypt.aes, plain, input, sz);
01602                 break;
01603         #endif
01604 
01605         #ifdef BUILD_HC128
01606             case hc128:
01607                 Hc128_Process(&ssl->decrypt.hc128, plain, input, sz);
01608                 break;
01609         #endif
01610 
01611         #ifdef BUILD_RABBIT
01612             case rabbit:
01613                 RabbitProcess(&ssl->decrypt.rabbit, plain, input, sz);
01614                 break;
01615         #endif
01616     }
01617 }
01618 
01619 
01620 /* decrypt input message in place */
01621 static int DecryptMessage(SSL* ssl, byte* input, word32 sz, word32* idx)
01622 {
01623     Decrypt(ssl, input, input, sz);
01624     ssl->keys.encryptSz = sz;
01625     if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
01626         *idx += ssl->specs.block_size;  /* go past TLSv1.1 IV */
01627 
01628     return 0;
01629 }
01630 
01631 
01632 static INLINE word32 GetSEQIncrement(SSL* ssl, int verify)
01633 {
01634     if (verify)
01635         return ssl->keys.peer_sequence_number++; 
01636     else
01637         return ssl->keys.sequence_number++; 
01638 }
01639 
01640 
01641 int DoApplicationData(SSL* ssl, byte* input, word32* inOutIdx)
01642 {
01643     word32 msgSz   = ssl->keys.encryptSz;
01644     word32 pad     = 0, 
01645            padByte = 0,
01646            idx     = *inOutIdx,
01647            digestSz = ssl->specs.hash_size;
01648     int    dataSz;
01649     int    ivExtra = 0;
01650     byte*  rawData = input + idx;  /* keep current  for hmac */
01651 #ifdef HAVE_LIBZ
01652     byte   decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
01653 #endif
01654 
01655     byte        verify[SHA_DIGEST_SIZE];
01656     const byte* mac;
01657 
01658     if (ssl->specs.cipher_type == block) {
01659         if (ssl->options.tls1_1)
01660             ivExtra = ssl->specs.block_size;
01661         pad = *(input + idx + msgSz - ivExtra - 1);
01662         padByte = 1;
01663     }
01664 
01665     dataSz = msgSz - ivExtra - digestSz - pad - padByte;
01666     if (dataSz < 0)
01667         return BUFFER_ERROR;
01668 
01669     /* read data */
01670     if (dataSz) {
01671         int    rawSz   = dataSz;       /* keep raw size for hmac */
01672 
01673         ssl->hmac(ssl, verify, rawData, rawSz, application_data, 1);
01674 
01675 #ifdef HAVE_LIBZ
01676         byte  decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
01677         
01678         if (ssl->options.usingCompression) {
01679             dataSz = DeCompress(ssl, rawData, dataSz, decomp, sizeof(decomp));
01680             if (dataSz < 0) return dataSz;
01681         }
01682 #endif
01683 
01684         if (ssl->options.usingCompression)
01685             idx += rawSz;
01686         else
01687             idx += dataSz;
01688 
01689         ssl->buffers.clearOutputBuffer.buffer = rawData;
01690         ssl->buffers.clearOutputBuffer.length = dataSz;
01691     }
01692 
01693     /* read mac and fill */
01694     mac = input + idx;
01695     idx += digestSz;
01696    
01697     idx += pad;
01698     if (padByte)
01699         idx++;
01700 
01701 #ifdef HAVE_LIBZ
01702     if (ssl->options.usingCompression)
01703         XMEMMOVE(rawData, decomp, dataSz);
01704 #endif
01705 
01706     /* verify */
01707     if (dataSz) {
01708         if (XMEMCMP(mac, verify, digestSz))
01709             return VERIFY_MAC_ERROR;
01710     }
01711     else 
01712         GetSEQIncrement(ssl, 1);  /* even though no data, increment verify */
01713 
01714     *inOutIdx = idx;
01715     return 0;
01716 }
01717 
01718 
01719 /* process alert, return level */
01720 static int DoAlert(SSL* ssl, byte* input, word32* inOutIdx, int* type)
01721 {
01722     byte level;
01723 
01724     #ifdef CYASSL_CALLBACKS
01725         if (ssl->hsInfoOn)
01726             AddPacketName("Alert", &ssl->handShakeInfo);
01727         if (ssl->toInfoOn)
01728             /* add record header back on to info + 2 byte level, data */
01729             AddPacketInfo("Alert", &ssl->timeoutInfo, input + *inOutIdx -
01730                           RECORD_HEADER_SZ, 2 + RECORD_HEADER_SZ, ssl->heap);
01731     #endif
01732     level = input[(*inOutIdx)++];
01733     *type  = (int)input[(*inOutIdx)++];
01734 
01735     if (*type == close_notify)
01736         ssl->options.closeNotify = 1;
01737 
01738     if (ssl->keys.encryptionOn) {
01739         int         aSz = ALERT_SIZE;
01740         const byte* mac;
01741         byte        verify[SHA_DIGEST_SIZE];
01742         int         padSz = ssl->keys.encryptSz - aSz - ssl->specs.hash_size;
01743         
01744         ssl->hmac(ssl, verify, input + *inOutIdx - aSz, aSz, alert, 1);
01745 
01746         /* read mac and fill */
01747         mac = input + *inOutIdx;
01748         *inOutIdx += (ssl->specs.hash_size + padSz);
01749 
01750         /* verify */
01751         if (XMEMCMP(mac, verify, ssl->specs.hash_size))
01752             return VERIFY_MAC_ERROR;
01753     }
01754 
01755     return level;
01756 }
01757 
01758 static int GetInputData(SSL *ssl, size_t size)
01759 {
01760     int in;
01761     int inSz;
01762     int maxLength;
01763     int usedLength;
01764 
01765     
01766     /* check max input length */
01767     usedLength = ssl->buffers.inputBuffer.length - ssl->buffers.inputBuffer.idx;
01768     maxLength  = ssl->buffers.inputBuffer.bufferSize - usedLength;
01769     inSz       = (int)(size - usedLength);      /* from last partial read */
01770 
01771 #ifdef CYASSL_DTLS
01772     if (ssl->options.dtls)
01773         inSz = 1500;       /* read ahead up to MTU */
01774 #endif
01775     
01776     if (inSz > maxLength) {
01777         if (GrowInputBuffer(ssl, size, usedLength) < 0)
01778             return MEMORY_E;
01779     }
01780            
01781     if (inSz <= 0)
01782         return BUFFER_ERROR;
01783     
01784     /* Put buffer data at start if not there */
01785     if (usedLength > 0 && ssl->buffers.inputBuffer.idx != 0)
01786         XMEMMOVE(ssl->buffers.inputBuffer.buffer,
01787                 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
01788                 usedLength);
01789     
01790     /* remove processed data */
01791     ssl->buffers.inputBuffer.idx    = 0;
01792     ssl->buffers.inputBuffer.length = usedLength;
01793   
01794     /* read data from network */
01795     do {
01796         in = Receive(ssl, 
01797                      ssl->buffers.inputBuffer.buffer +
01798                      ssl->buffers.inputBuffer.length, 
01799                      inSz, 0);
01800         if (in == -1)
01801             return SOCKET_ERROR_E;
01802    
01803         if (in == WANT_READ)
01804             return WANT_READ;
01805         
01806         ssl->buffers.inputBuffer.length += in;
01807         inSz -= in;
01808 
01809     } while (ssl->buffers.inputBuffer.length < size);
01810 
01811     return 0;
01812 }
01813 
01814 /* process input requests, return 0 is done, 1 is call again to complete, and
01815    negative number is error */
01816 int ProcessReply(SSL* ssl)
01817 {
01818     int    ret, type, readSz;
01819     word32 startIdx = 0;
01820     byte   b0, b1;
01821 #ifdef CYASSL_DTLS
01822     int    used;
01823 #endif
01824 
01825     for (;;) {
01826         switch ((processReply)ssl->options.processReply) {
01827 
01828         /* in the CYASSL_SERVER case, get the first byte for detecting 
01829          * old client hello */
01830         case doProcessInit:
01831             
01832             readSz = RECORD_HEADER_SZ;
01833             
01834             #ifdef CYASSL_DTLS
01835                 if (ssl->options.dtls)
01836                     readSz = DTLS_RECORD_HEADER_SZ;
01837             #endif
01838 
01839             /* get header or return error */
01840             if (!ssl->options.dtls) {
01841                 if ((ret = GetInputData(ssl, readSz)) < 0)
01842                     return ret;
01843             } else {
01844             #ifdef CYASSL_DTLS
01845                 /* read ahead may already have header */
01846                 used = ssl->buffers.inputBuffer.length -
01847                        ssl->buffers.inputBuffer.idx;
01848                 if (used < readSz)
01849                     if ((ret = GetInputData(ssl, readSz)) < 0)
01850                         return ret;
01851             #endif
01852             }
01853 
01854 #ifndef NO_CYASSL_SERVER
01855 
01856             /* see if sending SSLv2 client hello */
01857             if ( ssl->options.side == SERVER_END &&
01858                  ssl->options.clientState == NULL_STATE &&
01859                  ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx]
01860                          != handshake) {
01861                 ssl->options.processReply = runProcessOldClientHello;
01862 
01863                 /* how many bytes need ProcessOldClientHello */
01864                 b0 =
01865                 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
01866                 b1 =
01867                 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
01868                 ssl->curSize = ((b0 & 0x7f) << 8) | b1;
01869             }
01870             else {
01871                 ssl->options.processReply = getRecordLayerHeader;
01872                 continue;
01873             }
01874 
01875         /* in the CYASSL_SERVER case, run the old client hello */
01876         case runProcessOldClientHello:     
01877 
01878             /* get sz bytes or return error */
01879             if (!ssl->options.dtls) {
01880                 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
01881                     return ret;
01882             } else {
01883             #ifdef CYASSL_DTLS
01884                 /* read ahead may already have */
01885                 used = ssl->buffers.inputBuffer.length -
01886                        ssl->buffers.inputBuffer.idx;
01887                 if (used < ssl->curSize)
01888                     if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
01889                         return ret;
01890             #endif  /* CYASSL_DTLS */
01891             }
01892 
01893             ret = ProcessOldClientHello(ssl, ssl->buffers.inputBuffer.buffer,
01894                                         &ssl->buffers.inputBuffer.idx,
01895                                         ssl->buffers.inputBuffer.length -
01896                                         ssl->buffers.inputBuffer.idx,
01897                                         ssl->curSize);
01898             if (ret < 0)
01899                 return ret;
01900 
01901             else if (ssl->buffers.inputBuffer.idx ==
01902                      ssl->buffers.inputBuffer.length) {
01903                 ssl->options.processReply = doProcessInit;
01904                 return 0;
01905             }
01906 
01907 #endif  /* NO_CYASSL_SERVER */
01908 
01909         /* get the record layer header */
01910         case getRecordLayerHeader:
01911 
01912             ret = GetRecordHeader(ssl, ssl->buffers.inputBuffer.buffer,
01913                                        &ssl->buffers.inputBuffer.idx,
01914                                        &ssl->curRL, &ssl->curSize);
01915             if (ret != 0)
01916                 return ret;
01917 
01918             ssl->options.processReply = getData;
01919 
01920         /* retrieve record layer data */
01921         case getData:
01922 
01923             /* get sz bytes or return error */
01924             if (!ssl->options.dtls) {
01925                 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
01926                     return ret;
01927             } else {
01928 #ifdef CYASSL_DTLS
01929                 /* read ahead may already have */
01930                 used = ssl->buffers.inputBuffer.length -
01931                        ssl->buffers.inputBuffer.idx;
01932                 if (used < ssl->curSize)
01933                     if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
01934                         return ret;
01935 #endif
01936             }
01937             
01938             ssl->options.processReply = runProcessingOneMessage;
01939             startIdx = ssl->buffers.inputBuffer.idx;  /* in case > 1 msg per */
01940 
01941         /* the record layer is here */
01942         case runProcessingOneMessage:
01943 
01944             if (ssl->keys.encryptionOn)
01945                 if (DecryptMessage(ssl, ssl->buffers.inputBuffer.buffer + 
01946                                         ssl->buffers.inputBuffer.idx,
01947                                         ssl->curSize,
01948                                         &ssl->buffers.inputBuffer.idx) < 0)
01949                     return DECRYPT_ERROR;
01950 
01951             CYASSL_MSG("received record layer msg");
01952 
01953             switch (ssl->curRL.type) {
01954                 case handshake :
01955                     /* debugging in DoHandShakeMsg */
01956                     if ((ret = DoHandShakeMsg(ssl, 
01957                                               ssl->buffers.inputBuffer.buffer,
01958                                               &ssl->buffers.inputBuffer.idx,
01959                                               ssl->buffers.inputBuffer.length))
01960                                                                            != 0)
01961                         return ret;
01962                     break;
01963 
01964                 case change_cipher_spec:
01965                     CYASSL_MSG("got CHANGE CIPHER SPEC");
01966                     #ifdef CYASSL_CALLBACKS
01967                         if (ssl->hsInfoOn)
01968                             AddPacketName("ChangeCipher", &ssl->handShakeInfo);
01969                         /* add record header back on info */
01970                         if (ssl->toInfoOn) {
01971                             AddPacketInfo("ChangeCipher", &ssl->timeoutInfo,
01972                                 ssl->buffers.inputBuffer.buffer +
01973                                 ssl->buffers.inputBuffer.idx - RECORD_HEADER_SZ,
01974                                 1 + RECORD_HEADER_SZ, ssl->heap);
01975                             AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
01976                         }
01977                     #endif
01978                     ssl->buffers.inputBuffer.idx++;
01979                     ssl->keys.encryptionOn = 1;
01980 
01981                     #ifdef CYASSL_DTLS
01982                         if (ssl->options.dtls)
01983                             ssl->keys.dtls_peer_epoch++;
01984                     #endif
01985 
01986                     #ifdef HAVE_LIBZ
01987                         if (ssl->options.usingCompression)
01988                             if ( (ret = InitStreams(ssl)) != 0)
01989                                 return ret;
01990                     #endif
01991                     if (ssl->options.resuming && ssl->options.side ==
01992                                                                     CLIENT_END)
01993                         BuildFinished(ssl, &ssl->verifyHashes, server);
01994                     else if (!ssl->options.resuming && ssl->options.side ==
01995                                                                     SERVER_END)
01996                         BuildFinished(ssl, &ssl->verifyHashes, client);
01997                     break;
01998 
01999                 case application_data:
02000                     CYASSL_MSG("got app DATA");
02001                     if ((ret = DoApplicationData(ssl,
02002                                                 ssl->buffers.inputBuffer.buffer,
02003                                                &ssl->buffers.inputBuffer.idx))
02004                                                                          != 0) {
02005                         CYASSL_ERROR(ret);
02006                         return ret;
02007                     }
02008                     break;
02009 
02010                 case alert:
02011                     CYASSL_MSG("got ALERT!");
02012                     if (DoAlert(ssl, ssl->buffers.inputBuffer.buffer,
02013                            &ssl->buffers.inputBuffer.idx, &type) == alert_fatal)
02014                         return FATAL_ERROR;
02015 
02016                     /* catch warnings that are handled as errors */
02017                     if (type == close_notify)
02018                         return ssl->error = ZERO_RETURN;
02019                            
02020                     if (type == decrypt_error)
02021                         return FATAL_ERROR;
02022                     break;
02023             
02024                 default:
02025                     CYASSL_ERROR(UNKNOWN_RECORD_TYPE);
02026                     return UNKNOWN_RECORD_TYPE;
02027             }
02028 
02029             ssl->options.processReply = doProcessInit;
02030 
02031             /* input exhausted? */
02032             if (ssl->buffers.inputBuffer.idx == ssl->buffers.inputBuffer.length)
02033                 return 0;
02034             /* more messages per record */
02035             else if ((ssl->buffers.inputBuffer.idx - startIdx) < ssl->curSize) {
02036                 #ifdef CYASSL_DTLS
02037                     /* read-ahead but dtls doesn't bundle messages per record */
02038                     if (ssl->options.dtls) {
02039                         ssl->options.processReply = doProcessInit;
02040                         continue;
02041                     }
02042                 #endif
02043                 ssl->options.processReply = runProcessingOneMessage;
02044                 continue;
02045             }
02046             /* more records */
02047             else {
02048                 ssl->options.processReply = doProcessInit;
02049                 continue;
02050             }
02051         }
02052     }
02053 }
02054 
02055 
02056 int SendChangeCipher(SSL* ssl)
02057 {
02058     byte              *output;
02059     int                sendSz = RECORD_HEADER_SZ + ENUM_LEN;
02060     int                idx    = RECORD_HEADER_SZ;
02061     int                ret;
02062 
02063     #ifdef CYASSL_DTLS
02064         if (ssl->options.dtls) {
02065             sendSz += DTLS_RECORD_EXTRA;
02066             idx    += DTLS_RECORD_EXTRA;
02067         }
02068     #endif
02069 
02070     /* check for avalaible size */
02071     if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
02072         return ret;
02073 
02074     /* get ouput buffer */
02075     output = ssl->buffers.outputBuffer.buffer + 
02076              ssl->buffers.outputBuffer.idx;
02077 
02078     AddRecordHeader(output, 1, change_cipher_spec, ssl);
02079 
02080     output[idx] = 1;             /* turn it on */
02081 
02082     #ifdef CYASSL_CALLBACKS
02083         if (ssl->hsInfoOn) AddPacketName("ChangeCipher", &ssl->handShakeInfo);
02084         if (ssl->toInfoOn)
02085             AddPacketInfo("ChangeCipher", &ssl->timeoutInfo, output, sendSz,
02086                            ssl->heap);
02087     #endif
02088     ssl->buffers.outputBuffer.length += sendSz;
02089     return SendBuffered(ssl);
02090 }
02091 
02092 
02093 static INLINE const byte* GetMacSecret(SSL* ssl, int verify)
02094 {
02095     if ( (ssl->options.side == CLIENT_END && !verify) ||
02096          (ssl->options.side == SERVER_END &&  verify) )
02097         return ssl->keys.client_write_MAC_secret;
02098     else
02099         return ssl->keys.server_write_MAC_secret;
02100 }
02101 
02102 
02103 static void Hmac(SSL* ssl, byte* digest, const byte* buffer, word32 sz,
02104                  int content, int verify)
02105 {
02106     byte   result[SHA_DIGEST_SIZE];                    /* max possible sizes */
02107     word32 digestSz = ssl->specs.hash_size;            /* actual sizes */
02108     word32 padSz    = ssl->specs.pad_size;
02109 
02110     Md5 md5;
02111     Sha sha;
02112 
02113     /* data */
02114     byte seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 };
02115     byte conLen[ENUM_LEN + LENGTH_SZ];     /* content & length */
02116     const byte* macSecret = GetMacSecret(ssl, verify);
02117     
02118     conLen[0] = content;
02119     c16toa((word16)sz, &conLen[ENUM_LEN]);
02120     c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]);
02121 
02122     if (ssl->specs.mac_algorithm == md5_mac) {
02123         InitMd5(&md5);
02124         /* inner */
02125         Md5Update(&md5, macSecret, digestSz);
02126         Md5Update(&md5, PAD1, padSz);
02127         Md5Update(&md5, seq, SEQ_SZ);
02128         Md5Update(&md5, conLen, sizeof(conLen));
02129         /* buffer */
02130         Md5Update(&md5, buffer, sz);
02131         Md5Final(&md5, result);
02132         /* outer */
02133         Md5Update(&md5, macSecret, digestSz);
02134         Md5Update(&md5, PAD2, padSz);
02135         Md5Update(&md5, result, digestSz);
02136         Md5Final(&md5, digest);        
02137     }
02138     else {
02139         InitSha(&sha);
02140         /* inner */
02141         ShaUpdate(&sha, macSecret, digestSz);
02142         ShaUpdate(&sha, PAD1, padSz);
02143         ShaUpdate(&sha, seq, SEQ_SZ);
02144         ShaUpdate(&sha, conLen, sizeof(conLen));
02145         /* buffer */
02146         ShaUpdate(&sha, buffer, sz);
02147         ShaFinal(&sha, result);
02148         /* outer */
02149         ShaUpdate(&sha, macSecret, digestSz);
02150         ShaUpdate(&sha, PAD2, padSz);
02151         ShaUpdate(&sha, result, digestSz);
02152         ShaFinal(&sha, digest);        
02153     }
02154 }
02155 
02156 
02157 static void BuildMD5_CertVerify(SSL* ssl, byte* digest)
02158 {
02159     byte md5_result[MD5_DIGEST_SIZE];
02160 
02161     /* make md5 inner */
02162     Md5Update(&ssl->hashMd5, ssl->arrays.masterSecret, SECRET_LEN);
02163     Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
02164     Md5Final(&ssl->hashMd5, md5_result);
02165 
02166     /* make md5 outer */
02167     Md5Update(&ssl->hashMd5, ssl->arrays.masterSecret, SECRET_LEN);
02168     Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
02169     Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
02170 
02171     Md5Final(&ssl->hashMd5, digest);
02172 }
02173 
02174 
02175 static void BuildSHA_CertVerify(SSL* ssl, byte* digest)
02176 {
02177     byte sha_result[SHA_DIGEST_SIZE];
02178     
02179     /* make sha inner */
02180     ShaUpdate(&ssl->hashSha, ssl->arrays.masterSecret, SECRET_LEN);
02181     ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
02182     ShaFinal(&ssl->hashSha, sha_result);
02183 
02184     /* make sha outer */
02185     ShaUpdate(&ssl->hashSha, ssl->arrays.masterSecret, SECRET_LEN);
02186     ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
02187     ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
02188 
02189     ShaFinal(&ssl->hashSha, digest);
02190 }
02191 
02192 
02193 static void BuildCertHashes(SSL* ssl, Hashes* hashes)
02194 {
02195     /* store current states, building requires get_digest which resets state */
02196     Md5 md5 = ssl->hashMd5;
02197     Sha sha = ssl->hashSha;
02198 
02199     if (ssl->options.tls) {
02200         Md5Final(&ssl->hashMd5, hashes->md5);
02201         ShaFinal(&ssl->hashSha, hashes->sha);
02202     }
02203     else {
02204         BuildMD5_CertVerify(ssl, hashes->md5);
02205         BuildSHA_CertVerify(ssl, hashes->sha);
02206     }
02207     
02208     /* restore */
02209     ssl->hashMd5 = md5;
02210     ssl->hashSha = sha;
02211 }
02212 
02213 
02214 /* Build SSL Message, encrypted */
02215 static int BuildMessage(SSL* ssl, byte* output, const byte* input, int inSz,
02216                         int type)
02217 {
02218     word32 digestSz = ssl->specs.hash_size;
02219     word32 sz = RECORD_HEADER_SZ + inSz + digestSz;                
02220     word32 pad  = 0, i;
02221     word32 idx  = RECORD_HEADER_SZ;
02222     word32 ivSz = 0;      /* TLSv1.1  IV */
02223     word32 headerSz = RECORD_HEADER_SZ;
02224     word16 size;
02225     byte               iv[AES_BLOCK_SIZE];                  /* max size */
02226 
02227 #ifdef CYASSL_DTLS
02228     if (ssl->options.dtls) {
02229         sz       += DTLS_RECORD_EXTRA;
02230         idx      += DTLS_RECORD_EXTRA; 
02231         headerSz += DTLS_RECORD_EXTRA;
02232     }
02233 #endif
02234 
02235     if (ssl->specs.cipher_type == block) {
02236         word32 blockSz = ssl->specs.block_size;
02237         if (ssl->options.tls1_1) {
02238             ivSz = blockSz;
02239             sz  += ivSz;
02240             RNG_GenerateBlock(&ssl->rng, iv, ivSz);
02241         }
02242         sz += 1;       /* pad byte */
02243         pad = (sz - headerSz) % blockSz;
02244         pad = blockSz - pad;
02245         sz += pad;
02246     }
02247 
02248     size = sz - headerSz;    /* include mac and digest */
02249     AddRecordHeader(output, size, type, ssl);    
02250 
02251     /* write to output */
02252     if (ivSz) {
02253         XMEMCPY(output + idx, iv, ivSz);
02254         idx += ivSz;
02255     }
02256     XMEMCPY(output + idx, input, inSz);
02257     idx += inSz;
02258 
02259     if (type == handshake)
02260         HashOutput(ssl, output, headerSz + inSz, ivSz);
02261     ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz, type, 0);
02262     idx += digestSz;
02263 
02264     if (ssl->specs.cipher_type == block)
02265         for (i = 0; i <= pad; i++) output[idx++] = pad; /* pad byte gets */
02266                                                         /* pad value too */
02267     Encrypt(ssl, output + headerSz, output + headerSz, size);
02268 
02269     return sz;
02270 }
02271 
02272 
02273 int SendFinished(SSL* ssl)
02274 {
02275     int              sendSz,
02276                      finishedSz = ssl->options.tls ? TLS_FINISHED_SZ :
02277                                                      FINISHED_SZ;
02278     byte             input[FINISHED_SZ + DTLS_HANDSHAKE_HEADER_SZ];  /* max */
02279     byte            *output;
02280     Hashes*          hashes;
02281     int              ret;
02282     int              headerSz = HANDSHAKE_HEADER_SZ;
02283 
02284 
02285     #ifdef CYASSL_DTLS
02286         if (ssl->options.dtls) {
02287             headerSz += DTLS_HANDSHAKE_EXTRA;
02288             ssl->keys.dtls_epoch++;
02289             ssl->keys.dtls_sequence_number = 0;  /* reset after epoch change */
02290         }
02291     #endif
02292     
02293     /* check for avalaible size */
02294     if ((ret = CheckAvalaibleSize(ssl, sizeof(input) + MAX_MSG_EXTRA)) != 0)
02295         return ret;
02296 
02297     /* get ouput buffer */
02298     output = ssl->buffers.outputBuffer.buffer + 
02299              ssl->buffers.outputBuffer.idx;
02300 
02301     AddHandShakeHeader(input, finishedSz, finished, ssl);
02302 
02303     /* make finished hashes */
02304     hashes = (Hashes*)&input[headerSz];
02305     BuildFinished(ssl, hashes, ssl->options.side == CLIENT_END ? client :
02306                   server);
02307 
02308     if ( (sendSz = BuildMessage(ssl, output, input, headerSz +
02309                                 finishedSz, handshake)) == -1)
02310         return BUILD_MSG_ERROR;
02311 
02312     if (!ssl->options.resuming) {
02313         AddSession(ssl);    /* just try */
02314         if (ssl->options.side == CLIENT_END)
02315             BuildFinished(ssl, &ssl->verifyHashes, server);
02316         else
02317             ssl->options.handShakeState = HANDSHAKE_DONE;
02318     }
02319     else {
02320         if (ssl->options.side == CLIENT_END)
02321             ssl->options.handShakeState = HANDSHAKE_DONE;
02322         else
02323             BuildFinished(ssl, &ssl->verifyHashes, client);
02324     }
02325 
02326     #ifdef CYASSL_CALLBACKS
02327         if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
02328         if (ssl->toInfoOn)
02329             AddPacketInfo("Finished", &ssl->timeoutInfo, output, sendSz,
02330                           ssl->heap);
02331     #endif
02332 
02333     ssl->buffers.outputBuffer.length += sendSz;
02334 
02335     return SendBuffered(ssl);
02336 }
02337 
02338 
02339 int SendCertificate(SSL* ssl)
02340 {
02341     int    sendSz, length, ret = 0;
02342     word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
02343     word32 certSz, listSz;
02344     byte*  output = 0;
02345 
02346     if (ssl->options.usingPSK_cipher) return 0;  /* not needed */
02347 
02348     if (ssl->options.sendVerify == SEND_BLANK_CERT) {
02349         certSz = 0;
02350         length = CERT_HEADER_SZ;
02351         listSz = 0;
02352     }
02353     else {
02354         certSz = ssl->buffers.certificate.length;
02355         /* list + cert size */
02356         length = certSz + 2 * CERT_HEADER_SZ;
02357         listSz = certSz + CERT_HEADER_SZ;
02358     }
02359     sendSz = length + RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
02360 
02361     #ifdef CYASSL_DTLS
02362         if (ssl->options.dtls) {
02363             sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
02364             i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
02365         }
02366     #endif
02367 
02368     /* check for avalaible size */
02369     if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
02370         return ret;
02371 
02372     /* get ouput buffer */
02373     output = ssl->buffers.outputBuffer.buffer +
02374              ssl->buffers.outputBuffer.idx;
02375 
02376     AddHeaders(output, length, certificate, ssl);
02377 
02378     /* list total */
02379     c32to24(listSz, output + i);
02380     i += CERT_HEADER_SZ;
02381 
02382     /* member */
02383     if (certSz) {
02384         c32to24(certSz, output + i);
02385         i += CERT_HEADER_SZ;
02386         XMEMCPY(output + i, ssl->buffers.certificate.buffer, certSz);
02387         i += certSz;
02388     }
02389     HashOutput(ssl, output, sendSz, 0);
02390     #ifdef CYASSL_CALLBACKS
02391         if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
02392         if (ssl->toInfoOn)
02393             AddPacketInfo("Certificate", &ssl->timeoutInfo, output, sendSz,
02394                            ssl->heap);
02395     #endif
02396 
02397     if (ssl->options.side == SERVER_END)
02398         ssl->options.serverState = SERVER_CERT_COMPLETE;
02399 
02400     ssl->buffers.outputBuffer.length += sendSz;
02401     return SendBuffered(ssl);
02402 }
02403 
02404 
02405 int SendCertificateRequest(SSL* ssl)
02406 {
02407     byte   *output;
02408     int    ret;
02409     int    sendSz;
02410     word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
02411     
02412     int  typeTotal = 1;  /* only rsa for now */
02413     int  reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ;  /* add auth later */
02414 
02415     if (ssl->options.usingPSK_cipher) return 0;  /* not needed */
02416 
02417     sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
02418 
02419     #ifdef CYASSL_DTLS
02420         if (ssl->options.dtls) {
02421             sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
02422             i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
02423         }
02424     #endif
02425     /* check for avalaible size */
02426     if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
02427         return ret;
02428 
02429     /* get ouput buffer */
02430     output = ssl->buffers.outputBuffer.buffer + ssl->buffers.outputBuffer.idx;
02431 
02432     AddHeaders(output, reqSz, certificate_request, ssl);
02433 
02434     /* write to output */
02435     output[i++] = typeTotal;  /* # of types */
02436     output[i++] = rsa_sign;
02437 
02438     c16toa(0, &output[i]);  /* auth's */
02439     i += REQ_HEADER_SZ;
02440 
02441     HashOutput(ssl, output, sendSz, 0);
02442 
02443     #ifdef CYASSL_CALLBACKS
02444         if (ssl->hsInfoOn)
02445             AddPacketName("CertificateRequest", &ssl->handShakeInfo);
02446         if (ssl->toInfoOn)
02447             AddPacketInfo("CertificateRequest", &ssl->timeoutInfo, output,
02448                           sendSz, ssl->heap);
02449     #endif
02450     ssl->buffers.outputBuffer.length += sendSz;
02451     return SendBuffered(ssl);
02452 }
02453 
02454 
02455 int SendData(SSL* ssl, const void* buffer, int sz)
02456 {
02457     int sent = 0,  /* plainText size */
02458         sendSz,
02459         ret;
02460 
02461     if (ssl->error == WANT_WRITE)
02462         ssl->error = 0;
02463 
02464     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
02465         int err;
02466         if ( (err = CyaSSL_negotiate(ssl)) != 0) 
02467             return  err;
02468     }
02469 
02470     /* last time system socket output buffer was full, try again to send */
02471     if (ssl->buffers.outputBuffer.length > 0) {
02472         if ( (ssl->error = SendBuffered(ssl)) < 0) {
02473             CYASSL_ERROR(ssl->error);
02474             if (ssl->error == SOCKET_ERROR_E && ssl->options.connReset)
02475                 return 0;     /* peer reset */
02476             return ssl->error;
02477         }
02478         else {
02479             /* advance sent to previous sent + plain size just sent */
02480             sent = ssl->buffers.prevSent + ssl->buffers.plainSz;
02481             CYASSL_MSG("sent write buffered data");
02482         }
02483     }
02484 
02485     for (;;) {
02486         int   len = min(sz - sent, OUTPUT_RECORD_SIZE);
02487         byte* out;
02488         byte* sendBuffer = (byte*)buffer + sent;  /* may switch on comp */
02489         int   buffSz = len;                       /* may switch on comp */
02490 #ifdef HAVE_LIBZ
02491         byte  comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
02492 #endif
02493 
02494         if (sent == sz) break;
02495 
02496 #ifdef CYASSL_DTLS
02497         if (ssl->options.dtls) {
02498             len    = min(len, MAX_UDP_SIZE);
02499             buffSz = len;
02500         }
02501 #endif
02502 
02503         /* check for avalaible size */
02504         if ((ret = CheckAvalaibleSize(ssl, len + COMP_EXTRA +
02505                                       MAX_MSG_EXTRA)) != 0)
02506             return ret;
02507 
02508         /* get ouput buffer */
02509         out = ssl->buffers.outputBuffer.buffer +
02510               ssl->buffers.outputBuffer.idx;
02511 
02512 #ifdef HAVE_LIBZ
02513         if (ssl->options.usingCompression) {
02514             buffSz = Compress(ssl, sendBuffer, buffSz, comp, sizeof(comp));
02515             if (buffSz < 0) {
02516                 return buffSz;
02517             }
02518             sendBuffer = comp;
02519         }
02520 #endif
02521         sendSz = BuildMessage(ssl, out, sendBuffer, buffSz,
02522                               application_data);
02523 
02524         ssl->buffers.outputBuffer.length += sendSz;
02525 
02526         if ( (ret = SendBuffered(ssl)) < 0) {
02527             CYASSL_ERROR(ret);
02528             /* store for next call if WANT_WRITE or user embedSend() that
02529                doesn't present like WANT_WRITE */
02530             ssl->buffers.plainSz  = len;
02531             ssl->buffers.prevSent = sent;
02532             if (ret == SOCKET_ERROR_E && ssl->options.connReset)
02533                 return 0;  /* peer reset */
02534             return ssl->error = ret;
02535         }
02536 
02537         sent += len;
02538 
02539         /* only one message per attempt */
02540         if (ssl->options.partialWrite == 1)
02541             break;
02542     }
02543  
02544     return sent;
02545 }
02546 
02547 /* process input data */
02548 int ReceiveData(SSL* ssl, byte* output, int sz)
02549 {
02550     int size;
02551 
02552     CYASSL_ENTER("ReceiveData()");
02553 
02554     if (ssl->error == WANT_READ)
02555         ssl->error = 0;
02556 
02557     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
02558         int err;
02559         if ( (err = CyaSSL_negotiate(ssl)) != 0)
02560             return  err;
02561     }
02562 
02563     while (ssl->buffers.clearOutputBuffer.length == 0)
02564         if ( (ssl->error = ProcessReply(ssl)) < 0) {
02565             CYASSL_ERROR(ssl->error);
02566             if (ssl->error == ZERO_RETURN) {
02567                 ssl->options.isClosed = 1;
02568                 return 0;         /* no more data coming */
02569             }
02570             if (ssl->error == SOCKET_ERROR_E)
02571                 if (ssl->options.connReset || ssl->options.isClosed)
02572                     return 0;     /* peer reset or closed */
02573             return ssl->error;
02574         }
02575 
02576     if (sz < (int)ssl->buffers.clearOutputBuffer.length)
02577         size = sz;
02578     else
02579         size = ssl->buffers.clearOutputBuffer.length;
02580 
02581     XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size);
02582     ssl->buffers.clearOutputBuffer.length -= size;
02583     ssl->buffers.clearOutputBuffer.buffer += size;
02584    
02585     if (ssl->buffers.clearOutputBuffer.length == 0 && 
02586                                            ssl->buffers.inputBuffer.dynamicFlag)
02587        ShrinkInputBuffer(ssl, NO_FORCED_FREE);
02588 
02589     CYASSL_LEAVE("ReceiveData()", size);
02590     return size;
02591 }
02592 
02593 
02594 /* send alert message */
02595 int SendAlert(SSL* ssl, int severity, int type)
02596 {
02597     byte input[ALERT_SIZE];
02598     byte *output;
02599     int  sendSz;
02600     int  ret;
02601 
02602     /* if sendalert is called again for nonbloking */
02603     if (ssl->options.sendAlertState != 0) {
02604         ret = SendBuffered(ssl);
02605         if (ret == 0)
02606             ssl->options.sendAlertState = 0;
02607         return ret;
02608     }
02609 
02610     /* check for avalaible size */
02611     if ((ret = CheckAvalaibleSize(ssl, ALERT_SIZE + MAX_MSG_EXTRA)) != 0)
02612         return ret;
02613 
02614     /* get ouput buffer */
02615     output = ssl->buffers.outputBuffer.buffer +
02616              ssl->buffers.outputBuffer.idx;
02617 
02618     input[0] = severity;
02619     input[1] = type;
02620 
02621     if (ssl->keys.encryptionOn)
02622         sendSz = BuildMessage(ssl, output, input, sizeof(input), alert);
02623     else {
02624         RecordLayerHeader *const rl = (RecordLayerHeader*)output;
02625         rl->type    = alert;
02626         rl->version = ssl->version;
02627         c16toa(ALERT_SIZE, rl->length);      
02628 
02629         XMEMCPY(output + RECORD_HEADER_SZ, input, sizeof(input));
02630         sendSz = RECORD_HEADER_SZ + sizeof(input);
02631     }
02632 
02633     #ifdef CYASSL_CALLBACKS
02634         if (ssl->hsInfoOn)
02635             AddPacketName("Alert", &ssl->handShakeInfo);
02636         if (ssl->toInfoOn)
02637             AddPacketInfo("Alert", &ssl->timeoutInfo, output, sendSz,ssl->heap);
02638     #endif
02639 
02640     ssl->buffers.outputBuffer.length += sendSz;
02641     ssl->options.sendAlertState = 1;
02642 
02643     return SendBuffered(ssl);
02644 }
02645 
02646 
02647 
02648 void SetErrorString(int error, char* buffer)
02649 {
02650     const int max = MAX_ERROR_SZ;  /* shorthand */
02651 
02652 #ifdef NO_ERROR_STRINGS
02653 
02654     XSTRNCPY(buffer, "no support for error strings built in", max);
02655 
02656 #else
02657 
02658     /* pass to CTaoCrypt */
02659     if (error < MAX_CODE_E && error > MIN_CODE_E) {
02660         CTaoCryptErrorString(error, buffer);
02661         return;
02662     }
02663 
02664     switch (error) {
02665 
02666     case UNSUPPORTED_SUITE :
02667         XSTRNCPY(buffer, "unsupported cipher suite", max);
02668         break;
02669 
02670     case PREFIX_ERROR :
02671         XSTRNCPY(buffer, "bad index to key rounds", max);
02672         break;
02673 
02674     case MEMORY_ERROR :
02675         XSTRNCPY(buffer, "out of memory", max);
02676         break;
02677 
02678     case VERIFY_FINISHED_ERROR :
02679         XSTRNCPY(buffer, "verify problem on finished", max);
02680         break;
02681 
02682     case VERIFY_MAC_ERROR :
02683         XSTRNCPY(buffer, "verify mac problem", max);
02684         break;
02685 
02686     case PARSE_ERROR :
02687         XSTRNCPY(buffer, "parse error on header", max);
02688         break;
02689 
02690     case SIDE_ERROR :
02691         XSTRNCPY(buffer, "wrong client/server type", max);
02692         break;
02693 
02694     case NO_PEER_CERT :
02695         XSTRNCPY(buffer, "peer didn't send cert", max);
02696         break;
02697 
02698     case UNKNOWN_HANDSHAKE_TYPE :
02699         XSTRNCPY(buffer, "weird handshake type", max);
02700         break;
02701 
02702     case SOCKET_ERROR_E :
02703         XSTRNCPY(buffer, "error state on socket", max);
02704         break;
02705 
02706     case SOCKET_NODATA :
02707         XSTRNCPY(buffer, "expected data, not there", max);
02708         break;
02709 
02710     case INCOMPLETE_DATA :
02711         XSTRNCPY(buffer, "don't have enough data to complete task", max);
02712         break;
02713 
02714     case UNKNOWN_RECORD_TYPE :
02715         XSTRNCPY(buffer, "unknown type in record hdr", max);
02716         break;
02717 
02718     case DECRYPT_ERROR :
02719         XSTRNCPY(buffer, "error during decryption", max);
02720         break;
02721 
02722     case FATAL_ERROR :
02723         XSTRNCPY(buffer, "revcd alert fatal error", max);
02724         break;
02725 
02726     case ENCRYPT_ERROR :
02727         XSTRNCPY(buffer, "error during encryption", max);
02728         break;
02729 
02730     case FREAD_ERROR :
02731         XSTRNCPY(buffer, "fread problem", max);
02732         break;
02733 
02734     case NO_PEER_KEY :
02735         XSTRNCPY(buffer, "need peer's key", max);
02736         break;
02737 
02738     case NO_PRIVATE_KEY :
02739         XSTRNCPY(buffer, "need the private key", max);
02740         break;
02741 
02742     case RSA_PRIVATE_ERROR :
02743         XSTRNCPY(buffer, "error during rsa priv op", max);
02744         break;
02745 
02746     case MATCH_SUITE_ERROR :
02747         XSTRNCPY(buffer, "can't match cipher suite", max);
02748         break;
02749 
02750     case BUILD_MSG_ERROR :
02751         XSTRNCPY(buffer, "build message failure", max);
02752         break;
02753 
02754     case BAD_HELLO :
02755         XSTRNCPY(buffer, "client hello malformed", max);
02756         break;
02757 
02758     case DOMAIN_NAME_MISMATCH :
02759         XSTRNCPY(buffer, "peer subject name mismatch", max);
02760         break;
02761 
02762     case WANT_READ :
02763         XSTRNCPY(buffer, "non-blocking socket wants data to be read", max);
02764         break;
02765 
02766     case NOT_READY_ERROR :
02767         XSTRNCPY(buffer, "handshake layer not ready yet, complete first", max);
02768         break;
02769 
02770     case PMS_VERSION_ERROR :
02771         XSTRNCPY(buffer, "premaster secret version mismatch error", max);
02772         break;
02773 
02774     case VERSION_ERROR :
02775         XSTRNCPY(buffer, "record layer version error", max);
02776         break;
02777 
02778     case WANT_WRITE :
02779         XSTRNCPY(buffer, "non-blocking socket write buffer full", max);
02780         break;
02781 
02782     case BUFFER_ERROR :
02783         XSTRNCPY(buffer, "malformed buffer input error", max);
02784         break;
02785 
02786     case VERIFY_CERT_ERROR :
02787         XSTRNCPY(buffer, "verify problem on certificate", max);
02788         break;
02789 
02790     case VERIFY_SIGN_ERROR :
02791         XSTRNCPY(buffer, "verify problem based on signature", max);
02792         break;
02793 
02794     case CLIENT_ID_ERROR :
02795         XSTRNCPY(buffer, "psk client identity error", max);
02796         break;
02797 
02798     case SERVER_HINT_ERROR:
02799         XSTRNCPY(buffer, "psk server hint error", max);
02800         break;
02801 
02802     case PSK_KEY_ERROR:
02803         XSTRNCPY(buffer, "psk key callback error", max);
02804         break;
02805 
02806     case NTRU_KEY_ERROR:
02807         XSTRNCPY(buffer, "NTRU key error", max);
02808         break;
02809 
02810     case NTRU_DRBG_ERROR:
02811         XSTRNCPY(buffer, "NTRU drbg error", max);
02812         break;
02813 
02814     case NTRU_ENCRYPT_ERROR:
02815         XSTRNCPY(buffer, "NTRU encrypt error", max);
02816         break;
02817 
02818     case NTRU_DECRYPT_ERROR:
02819         XSTRNCPY(buffer, "NTRU decrypt error", max);
02820         break;
02821 
02822     case ZLIB_INIT_ERROR:
02823         XSTRNCPY(buffer, "zlib init error", max);
02824         break;
02825 
02826     case ZLIB_COMPRESS_ERROR:
02827         XSTRNCPY(buffer, "zlib compress error", max);
02828         break;
02829 
02830     case ZLIB_DECOMPRESS_ERROR:
02831         XSTRNCPY(buffer, "zlib decompress error", max);
02832         break;
02833 
02834     case GETTIME_ERROR:
02835         XSTRNCPY(buffer, "gettimeofday() error", max);
02836         break;
02837 
02838     case GETITIMER_ERROR:
02839         XSTRNCPY(buffer, "getitimer() error", max);
02840         break;
02841 
02842     case SIGACT_ERROR:
02843         XSTRNCPY(buffer, "sigaction() error", max);
02844         break;
02845 
02846     case SETITIMER_ERROR:
02847         XSTRNCPY(buffer, "setitimer() error", max);
02848         break;
02849 
02850     case LENGTH_ERROR:
02851         XSTRNCPY(buffer, "record layer length error", max);
02852         break;
02853 
02854     case PEER_KEY_ERROR:
02855         XSTRNCPY(buffer, "cant decode peer key", max);
02856         break;
02857 
02858     case ZERO_RETURN:
02859         XSTRNCPY(buffer, "peer sent close notify alert", max);
02860         break;
02861 
02862     default :
02863         XSTRNCPY(buffer, "unknown error number", max);
02864     }
02865 
02866 #endif /* NO_ERROR_STRINGS */
02867 }
02868 
02869 
02870 
02871 /* be sure to add to cipher_name_idx too !!!! */
02872 const char* const cipher_names[] = 
02873 {
02874 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
02875     "RC4-SHA",
02876 #endif
02877 
02878 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
02879     "RC4-MD5",
02880 #endif
02881 
02882 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
02883     "DES-CBC3-SHA",
02884 #endif
02885 
02886 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
02887     "AES128-SHA",
02888 #endif
02889 
02890 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
02891     "AES256-SHA",
02892 #endif
02893 
02894 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
02895     "DHE-RSA-AES128-SHA",
02896 #endif
02897 
02898 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
02899     "DHE-RSA-AES256-SHA",
02900 #endif
02901 
02902 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
02903     "PSK-AES128-CBC-SHA",
02904 #endif
02905 
02906 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
02907     "PSK-AES256-CBC-SHA",
02908 #endif
02909 
02910 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
02911     "HC128-MD5",
02912 #endif
02913     
02914 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
02915     "HC128-SHA",
02916 #endif
02917 
02918 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
02919     "RABBIT-SHA",
02920 #endif
02921 
02922 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
02923     "NTRU-RC4-SHA",
02924 #endif
02925 
02926 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
02927     "NTRU-DES-CBC3-SHA",
02928 #endif
02929 
02930 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
02931     "NTRU-AES128-SHA",
02932 #endif
02933 
02934 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
02935     "NTRU-AES256-SHA",
02936 #endif
02937 };
02938 
02939 
02940 
02941 /* cipher suite number that matches above name table */
02942 int cipher_name_idx[] =
02943 {
02944 
02945 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
02946     SSL_RSA_WITH_RC4_128_SHA,
02947 #endif
02948 
02949 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
02950     SSL_RSA_WITH_RC4_128_MD5,
02951 #endif
02952 
02953 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
02954     SSL_RSA_WITH_3DES_EDE_CBC_SHA,
02955 #endif
02956 
02957 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
02958     TLS_RSA_WITH_AES_128_CBC_SHA,    
02959 #endif
02960 
02961 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
02962     TLS_RSA_WITH_AES_256_CBC_SHA,
02963 #endif
02964 
02965 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
02966     TLS_DHE_RSA_WITH_AES_128_CBC_SHA,    
02967 #endif
02968 
02969 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
02970     TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
02971 #endif
02972 
02973 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
02974     TLS_PSK_WITH_AES_128_CBC_SHA,    
02975 #endif
02976 
02977 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
02978     TLS_PSK_WITH_AES_256_CBC_SHA,
02979 #endif
02980 
02981 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
02982     TLS_RSA_WITH_HC_128_CBC_MD5,    
02983 #endif
02984 
02985 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
02986     TLS_RSA_WITH_HC_128_CBC_SHA,    
02987 #endif
02988 
02989 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
02990     TLS_RSA_WITH_RABBIT_CBC_SHA,    
02991 #endif
02992 
02993 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
02994     TLS_NTRU_RSA_WITH_RC4_128_SHA,
02995 #endif
02996 
02997 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
02998     TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA,
02999 #endif
03000 
03001 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
03002     TLS_NTRU_RSA_WITH_AES_128_CBC_SHA,    
03003 #endif
03004 
03005 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
03006     TLS_NTRU_RSA_WITH_AES_256_CBC_SHA,    
03007 #endif
03008 };
03009 
03010 
03011 /* return true if set, else false */
03012 /* only supports full name from cipher_name[] delimited by : */
03013 int SetCipherList(SSL_CTX* ctx, const char* list)
03014 {
03015     int  ret = 0, i;
03016     char name[MAX_SUITE_NAME];
03017 
03018     char  needle[] = ":";
03019     char* haystack = (char*)list;
03020     char* prev;
03021 
03022     const int suiteSz = sizeof(cipher_names) / sizeof(cipher_names[0]);
03023     int idx = 0;
03024 
03025     if (!list)
03026         return 0;
03027     
03028     if (*list == 0) return 1;   /* CyaSSL default */
03029 
03030     if (XSTRNCMP(haystack, "ALL", 3) == 0) return 1;  /* CyaSSL defualt */
03031 
03032     for(;;) {
03033         size_t len;
03034         prev = haystack;
03035         haystack = XSTRSTR(haystack, needle);
03036 
03037         if (!haystack)    /* last cipher */
03038             len = min(sizeof(name), XSTRLEN(prev));
03039         else
03040             len = min(sizeof(name), (size_t)(haystack - prev));
03041 
03042         XSTRNCPY(name, prev, len);
03043         name[(len == sizeof(name)) ? len - 1 : len] = 0;
03044 
03045         for (i = 0; i < suiteSz; i++)
03046             if (XSTRNCMP(name, cipher_names[i], sizeof(name)) == 0) {
03047 
03048                 ctx->suites.suites[idx++] = 0x00;  /* first byte always zero */
03049                 ctx->suites.suites[idx++] = cipher_name_idx[i];
03050 
03051                 if (!ret) ret = 1;   /* found at least one */
03052                 break;
03053             }
03054         if (!haystack) break;
03055         haystack++;
03056     }
03057 
03058     if (ret) {
03059         ctx->suites.setSuites = 1;
03060         ctx->suites.suiteSz   = idx;
03061     }
03062 
03063     return ret;
03064 }
03065 
03066 
03067 #ifdef CYASSL_CALLBACKS
03068 
03069     /* Initialisze HandShakeInfo */
03070     void InitHandShakeInfo(HandShakeInfo* info)
03071     {
03072         int i;
03073 
03074         info->cipherName[0] = 0;
03075         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
03076             info->packetNames[i][0] = 0;
03077         info->numberPackets = 0;
03078         info->negotiationError = 0;
03079     }
03080 
03081     /* Set Final HandShakeInfo parameters */
03082     void FinishHandShakeInfo(HandShakeInfo* info, const SSL* ssl)
03083     {
03084         int i;
03085         int sz = sizeof(cipher_name_idx)/sizeof(int); 
03086 
03087         for (i = 0; i < sz; i++)
03088             if (ssl->options.cipherSuite == (byte)cipher_name_idx[i]) {
03089                 XSTRNCPY(info->cipherName, cipher_names[i], MAX_CIPHERNAME_SZ);
03090                 break;
03091             }
03092 
03093         /* error max and min are negative numbers */
03094         if (ssl->error <= MIN_PARAM_ERR && ssl->error >= MAX_PARAM_ERR)
03095             info->negotiationError = ssl->error;
03096     }
03097 
03098    
03099     /* Add name to info packet names, increase packet name count */
03100     void AddPacketName(const char* name, HandShakeInfo* info)
03101     {
03102         if (info->numberPackets < MAX_PACKETS_HANDSHAKE) {
03103             XSTRNCPY(info->packetNames[info->numberPackets++], name,
03104                     MAX_PACKETNAME_SZ);
03105         }
03106     } 
03107 
03108 
03109     /* Initialisze TimeoutInfo */
03110     void InitTimeoutInfo(TimeoutInfo* info)
03111     {
03112         int i;
03113 
03114         info->timeoutName[0] = 0;
03115         info->flags          = 0;
03116 
03117         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++) {
03118             info->packets[i].packetName[0]     = 0;
03119             info->packets[i].timestamp.tv_sec  = 0;
03120             info->packets[i].timestamp.tv_usec = 0;
03121             info->packets[i].bufferValue       = 0;
03122             info->packets[i].valueSz           = 0;
03123         }
03124         info->numberPackets        = 0;
03125         info->timeoutValue.tv_sec  = 0;
03126         info->timeoutValue.tv_usec = 0;
03127     }
03128 
03129 
03130     /* Free TimeoutInfo */
03131     void FreeTimeoutInfo(TimeoutInfo* info, void* heap)
03132     {
03133         int i;
03134         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
03135             if (info->packets[i].bufferValue) {
03136                 XFREE(info->packets[i].bufferValue, heap, DYNAMIC_TYPE_INFO);
03137                 info->packets[i].bufferValue = 0;
03138             }
03139 
03140     }
03141 
03142 
03143     /* Add PacketInfo to TimeoutInfo */
03144     void AddPacketInfo(const char* name, TimeoutInfo* info, const byte* data,
03145                        int sz, void* heap)
03146     {
03147         if (info->numberPackets < (MAX_PACKETS_HANDSHAKE - 1)) {
03148             Timeval currTime;
03149 
03150             /* may add name after */
03151             if (name)
03152                 XSTRNCPY(info->packets[info->numberPackets].packetName, name,
03153                         MAX_PACKETNAME_SZ);
03154 
03155             /* add data, put in buffer if bigger than static buffer */
03156             info->packets[info->numberPackets].valueSz = sz;
03157             if (sz < MAX_VALUE_SZ)
03158                 XMEMCPY(info->packets[info->numberPackets].value, data, sz);
03159             else {
03160                 info->packets[info->numberPackets].bufferValue =
03161                            XMALLOC(sz, heap, DYNAMIC_TYPE_INFO);
03162                 if (!info->packets[info->numberPackets].bufferValue)
03163                     /* let next alloc catch, just don't fill, not fatal here  */
03164                     info->packets[info->numberPackets].valueSz = 0;
03165                 else
03166                     XMEMCPY(info->packets[info->numberPackets].bufferValue,
03167                            data, sz);
03168             }
03169             gettimeofday(&currTime, 0);
03170             info->packets[info->numberPackets].timestamp.tv_sec  =
03171                                                              currTime.tv_sec;
03172             info->packets[info->numberPackets].timestamp.tv_usec =
03173                                                              currTime.tv_usec;
03174             info->numberPackets++;
03175         }
03176     }
03177 
03178 
03179     /* Add packet name to previsouly added packet info */
03180     void AddLateName(const char* name, TimeoutInfo* info)
03181     {
03182         /* make sure we have a valid previous one */
03183         if (info->numberPackets > 0 && info->numberPackets <
03184                                                         MAX_PACKETS_HANDSHAKE) {
03185             XSTRNCPY(info->packets[info->numberPackets - 1].packetName, name,
03186                     MAX_PACKETNAME_SZ);
03187         }
03188     }
03189 
03190     /* Add record header to previsouly added packet info */
03191     void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info)
03192     {
03193         /* make sure we have a valid previous one */
03194         if (info->numberPackets > 0 && info->numberPackets <
03195                                                         MAX_PACKETS_HANDSHAKE) {
03196             if (info->packets[info->numberPackets - 1].bufferValue)
03197                 XMEMCPY(info->packets[info->numberPackets - 1].bufferValue, rl,
03198                        RECORD_HEADER_SZ);
03199             else
03200                 XMEMCPY(info->packets[info->numberPackets - 1].value, rl,
03201                        RECORD_HEADER_SZ);
03202         }
03203     }
03204 
03205 #endif /* CYASSL_CALLBACKS */
03206 
03207 
03208 
03209 /* client only parts */
03210 #ifndef NO_CYASSL_CLIENT
03211 
03212     int SendClientHello(SSL* ssl)
03213     {
03214         byte              *output;
03215         word32             length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
03216         int                sendSz;
03217         int                idSz = ssl->options.resuming ? ID_LEN : 0;
03218         int                ret;
03219 
03220         length = sizeof(ProtocolVersion) + RAN_LEN
03221                + idSz + ENUM_LEN                      
03222                + ssl->suites.suiteSz + SUITE_LEN
03223                + COMP_LEN  + ENUM_LEN;
03224 
03225         sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
03226 
03227 #ifdef CYASSL_DTLS
03228         if (ssl->options.dtls) {
03229             length += ENUM_LEN;   /* cookie */
03230             sendSz  = length + DTLS_HANDSHAKE_HEADER_SZ + DTLS_RECORD_HEADER_SZ;
03231             idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
03232         }
03233 #endif
03234 
03235         /* check for avalaible size */
03236         if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
03237             return ret;
03238 
03239         /* get ouput buffer */
03240         output = ssl->buffers.outputBuffer.buffer +
03241                  ssl->buffers.outputBuffer.idx;
03242 
03243         AddHeaders(output, length, client_hello, ssl);
03244 
03245             /* client hello, first version */
03246         XMEMCPY(output + idx, &ssl->version, sizeof(ProtocolVersion));
03247         idx += sizeof(ProtocolVersion);
03248         ssl->chVersion = ssl->version;  /* store in case changed */
03249 
03250             /* then random */
03251         if (ssl->options.connectState == CONNECT_BEGIN) {
03252             RNG_GenerateBlock(&ssl->rng, output + idx, RAN_LEN);
03253             
03254                 /* store random */
03255             XMEMCPY(ssl->arrays.clientRandom, output + idx, RAN_LEN);
03256         } else {
03257 #ifdef CYASSL_DTLS
03258                 /* send same random on hello again */
03259             XMEMCPY(output + idx, ssl->arrays.clientRandom, RAN_LEN);
03260 #endif
03261         }
03262         idx += RAN_LEN;
03263 
03264             /* then session id */
03265         output[idx++] = idSz;
03266         if (idSz) {
03267             XMEMCPY(output + idx, ssl->session.sessionID, ID_LEN);
03268             idx += ID_LEN;
03269         }
03270         
03271             /* then DTLS cookie */
03272 #ifdef CYASSL_DTLS
03273         if (ssl->options.dtls) {
03274             output[idx++] = 0;
03275         }
03276 #endif
03277             /* then cipher suites */
03278         c16toa(ssl->suites.suiteSz, output + idx);
03279         idx += 2;
03280         XMEMCPY(output + idx, &ssl->suites.suites, ssl->suites.suiteSz);
03281         idx += ssl->suites.suiteSz;
03282 
03283             /* last, compression */
03284         output[idx++] = COMP_LEN;
03285         if (ssl->options.usingCompression)
03286             output[idx++] = ZLIB_COMPRESSION;
03287         else
03288             output[idx++] = NO_COMPRESSION;
03289             
03290         HashOutput(ssl, output, sendSz, 0);
03291 
03292         ssl->options.clientState = CLIENT_HELLO_COMPLETE;
03293 
03294 #ifdef CYASSL_CALLBACKS
03295         if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
03296         if (ssl->toInfoOn)
03297             AddPacketInfo("ClientHello", &ssl->timeoutInfo, output, sendSz,
03298                           ssl->heap);
03299 #endif
03300 
03301         ssl->buffers.outputBuffer.length += sendSz;
03302 
03303         return SendBuffered(ssl);
03304     }
03305 
03306 
03307     static int DoHelloVerifyRequest(SSL* ssl, const byte* input,
03308                                     word32* inOutIdx)
03309     {
03310         ProtocolVersion pv;
03311         byte            cookieSz;
03312         
03313 #ifdef CYASSL_CALLBACKS
03314         if (ssl->hsInfoOn) AddPacketName("HelloVerifyRequest",
03315                                          &ssl->handShakeInfo);
03316         if (ssl->toInfoOn) AddLateName("HelloVerifyRequest", &ssl->timeoutInfo);
03317 #endif
03318         XMEMCPY(&pv, input + *inOutIdx, sizeof(pv));
03319         *inOutIdx += sizeof(pv);
03320         
03321         cookieSz = input[(*inOutIdx)++];
03322         
03323         if (cookieSz)
03324             *inOutIdx += cookieSz;   /* skip for now */
03325         
03326         ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
03327         return 0;
03328     }
03329 
03330 
03331     static int DoServerHello(SSL* ssl, const byte* input, word32* inOutIdx)
03332     {
03333         byte b;
03334         byte compression;
03335         ProtocolVersion pv;
03336         word32 i = *inOutIdx;
03337 
03338 #ifdef CYASSL_CALLBACKS
03339         if (ssl->hsInfoOn) AddPacketName("ServerHello", &ssl->handShakeInfo);
03340         if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
03341 #endif
03342         XMEMCPY(&pv, input + i, sizeof(pv));
03343         i += sizeof(pv);
03344         XMEMCPY(ssl->arrays.serverRandom, input + i, RAN_LEN);
03345         i += RAN_LEN;
03346         b = input[i++];
03347         if (b) {
03348             XMEMCPY(ssl->arrays.sessionID, input + i, b);
03349             i += b;
03350         }
03351         ssl->options.cipherSuite = input[++i];  
03352         compression = input[++i];
03353         ++i;   /* 2nd byte */
03354 
03355         if (compression != ZLIB_COMPRESSION && ssl->options.usingCompression)
03356             ssl->options.usingCompression = 0;  /* turn off if server refused */
03357         
03358         ssl->options.serverState = SERVER_HELLO_COMPLETE;
03359 
03360         *inOutIdx = i;
03361 
03362         if (ssl->options.resuming) {
03363             if (XMEMCMP(ssl->arrays.sessionID, ssl->session.sessionID, ID_LEN)
03364                                                                         == 0) {
03365                 if (SetCipherSpecs(ssl) == 0) {
03366                     XMEMCPY(ssl->arrays.masterSecret, ssl->session.masterSecret,
03367                            SECRET_LEN);
03368                     if (ssl->options.tls)
03369                         DeriveTlsKeys(ssl);
03370                     else
03371                         DeriveKeys(ssl);
03372                     ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
03373                     return 0;
03374                 }
03375                 else
03376                     return UNSUPPORTED_SUITE;
03377             }
03378             else
03379                 ssl->options.resuming = 0; /* server denied resumption try */
03380         }
03381 
03382         return SetCipherSpecs(ssl);
03383     }
03384 
03385 
03386     /* just read in and ignore for now TODO: */
03387     static int DoCertificateRequest(SSL* ssl, const byte* input, word32*
03388                                     inOutIdx)
03389     {
03390         word16 len;
03391        
03392         #ifdef CYASSL_CALLBACKS
03393             if (ssl->hsInfoOn)
03394                 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
03395             if (ssl->toInfoOn)
03396                 AddLateName("CertificateRequest", &ssl->timeoutInfo);
03397         #endif
03398         len = input[(*inOutIdx)++];
03399 
03400         /* types, read in here */
03401         *inOutIdx += len;
03402         ato16(&input[*inOutIdx], &len);
03403         *inOutIdx += LENGTH_SZ;
03404 
03405         /* authorities */
03406         while (len) {
03407             word16 dnSz;
03408        
03409             ato16(&input[*inOutIdx], &dnSz);
03410             *inOutIdx += (REQUEST_HEADER + dnSz);
03411             len -= dnSz + REQUEST_HEADER;
03412         }
03413 
03414         /* don't send client cert or cert verify if user hasn't provided
03415            cert and private key */
03416         if (ssl->buffers.certificate.buffer && ssl->buffers.key.buffer)
03417             ssl->options.sendVerify = SEND_CERT;
03418         else if (IsAtLeastTLSv1_2(ssl))
03419             ssl->options.sendVerify = SEND_BLANK_CERT;
03420 
03421         return 0;
03422     }
03423 
03424 
03425     static int DoServerKeyExchange(SSL* ssl, const byte* input, word32*
03426                                    inOutIdx)
03427     {
03428     #ifdef CYASSL_CALLBACKS
03429         if (ssl->hsInfoOn)
03430             AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
03431         if (ssl->toInfoOn)
03432             AddLateName("ServerKeyExchange", &ssl->timeoutInfo);
03433     #endif
03434 
03435     #ifndef NO_PSK
03436         if (ssl->specs.kea == psk_kea) {
03437             word16 length;
03438            
03439             ato16(&input[*inOutIdx], &length);
03440             *inOutIdx += LENGTH_SZ;
03441             XMEMCPY(ssl->arrays.server_hint, &input[*inOutIdx],
03442                    min(length, MAX_PSK_ID_LEN));
03443             if (length < MAX_PSK_ID_LEN)
03444                 ssl->arrays.server_hint[length] = 0;
03445             else
03446                 ssl->arrays.server_hint[MAX_PSK_ID_LEN - 1] = 0;
03447             *inOutIdx += length;
03448 
03449             return 0;
03450         }
03451     #endif
03452     #ifdef OPENSSL_EXTRA
03453         if (ssl->specs.kea == diffie_hellman_kea)
03454         {
03455         word16 length, verifySz, messageTotal = 6;  /* pSz + gSz + pubSz */
03456         byte   messageVerify[MAX_DH_SZ];
03457         byte*  signature;
03458         byte   hash[FINISHED_SZ];
03459         Md5    md5;
03460         Sha    sha;
03461 
03462         /* p */
03463         ato16(&input[*inOutIdx], &length);
03464         *inOutIdx += LENGTH_SZ;
03465         messageTotal += length;
03466 
03467         ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
03468                                                          DYNAMIC_TYPE_DH);
03469         if (ssl->buffers.serverDH_P.buffer)
03470             ssl->buffers.serverDH_P.length = length;
03471         else
03472             return MEMORY_ERROR;
03473         XMEMCPY(ssl->buffers.serverDH_P.buffer, &input[*inOutIdx], length);
03474         *inOutIdx += length;
03475 
03476         /* g */
03477         ato16(&input[*inOutIdx], &length);
03478         *inOutIdx += LENGTH_SZ;
03479         messageTotal += length;
03480 
03481         ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
03482                                                          DYNAMIC_TYPE_DH);
03483         if (ssl->buffers.serverDH_G.buffer)
03484             ssl->buffers.serverDH_G.length = length;
03485         else
03486             return MEMORY_ERROR;
03487         XMEMCPY(ssl->buffers.serverDH_G.buffer, &input[*inOutIdx], length);
03488         *inOutIdx += length;
03489 
03490         /* pub */
03491         ato16(&input[*inOutIdx], &length);
03492         *inOutIdx += LENGTH_SZ;
03493         messageTotal += length;
03494 
03495         ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap,
03496                                                            DYNAMIC_TYPE_DH);
03497         if (ssl->buffers.serverDH_Pub.buffer)
03498             ssl->buffers.serverDH_Pub.length = length;
03499         else
03500             return MEMORY_ERROR;
03501         XMEMCPY(ssl->buffers.serverDH_Pub.buffer, &input[*inOutIdx], length);
03502         *inOutIdx += length;
03503 
03504         /* save message for hash verify */
03505         if (messageTotal > sizeof(messageVerify))
03506             return BUFFER_ERROR;
03507         XMEMCPY(messageVerify, &input[*inOutIdx - messageTotal], messageTotal);
03508         verifySz = messageTotal;
03509 
03510         /* signature */
03511         ato16(&input[*inOutIdx], &length);
03512         *inOutIdx += LENGTH_SZ;
03513 
03514         signature = (byte*)&input[*inOutIdx];
03515         *inOutIdx += length;
03516 
03517         /* verify signature */
03518 
03519         /* md5 */
03520         InitMd5(&md5);
03521         Md5Update(&md5, ssl->arrays.clientRandom, RAN_LEN);
03522         Md5Update(&md5, ssl->arrays.serverRandom, RAN_LEN);
03523         Md5Update(&md5, messageVerify, verifySz);
03524         Md5Final(&md5, hash);
03525 
03526         /* sha */
03527         InitSha(&sha);
03528         ShaUpdate(&sha, ssl->arrays.clientRandom, RAN_LEN);
03529         ShaUpdate(&sha, ssl->arrays.serverRandom, RAN_LEN);
03530         ShaUpdate(&sha, messageVerify, verifySz);
03531         ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
03532 
03533         /* rsa for now */
03534         {
03535             int   ret;
03536             byte* out;
03537 
03538             if (!ssl->peerRsaKeyPresent)
03539                 return NO_PEER_KEY;
03540 
03541             ret = RsaSSL_VerifyInline(signature, length,&out, &ssl->peerRsaKey);
03542 
03543             if (IsAtLeastTLSv1_2(ssl)) {
03544                 byte   encodedSig[MAX_ENCODED_SIG_SZ];
03545                 word32 sigSz;
03546                 byte*  digest;
03547                 int    hashType;
03548                 int    digestSz;
03549 
03550                 /* sha1 for now */
03551                 digest   = &hash[MD5_DIGEST_SIZE];
03552                 hashType = SHAh;
03553                 digestSz = SHA_DIGEST_SIZE;
03554 
03555                 sigSz = EncodeSignature(encodedSig, digest, digestSz, hashType);
03556 
03557                 if (sigSz != ret || XMEMCMP(out, encodedSig, sigSz) != 0)
03558                     return VERIFY_SIGN_ERROR;
03559             }
03560             else { 
03561                 if (ret != sizeof(hash) || XMEMCMP(out, hash, sizeof(hash)))
03562                     return VERIFY_SIGN_ERROR;
03563             }
03564         }
03565 
03566         ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
03567 
03568         return 0;
03569         }  /* dh_kea */
03570     #endif /* OPENSSL_EXTRA */
03571         return -1;  /* not supported by build */
03572     }
03573 
03574 
03575     int SendClientKeyExchange(SSL* ssl)
03576     {
03577         byte   encSecret[MAX_NTRU_ENCRYPT_SZ];
03578         word32 encSz = 0;
03579         word32 idx = 0;
03580         int    ret = 0;
03581 
03582         if (ssl->specs.kea == rsa_kea) {
03583             RNG_GenerateBlock(&ssl->rng, ssl->arrays.preMasterSecret,
03584                               SECRET_LEN);
03585             ssl->arrays.preMasterSecret[0] = ssl->chVersion.major;
03586             ssl->arrays.preMasterSecret[1] = ssl->chVersion.minor;
03587             ssl->arrays.preMasterSz = SECRET_LEN;
03588 
03589             if (ssl->peerRsaKeyPresent == 0)
03590                 return NO_PEER_KEY;
03591 
03592             ret = RsaPublicEncrypt(ssl->arrays.preMasterSecret, SECRET_LEN,
03593                              encSecret, sizeof(encSecret), &ssl->peerRsaKey,
03594                              &ssl->rng);
03595             if (ret > 0) {
03596                 encSz = ret;
03597                 ret = 0;   /* set success to 0 */
03598             }
03599         #ifdef OPENSSL_EXTRA
03600         } else if (ssl->specs.kea == diffie_hellman_kea) {
03601             buffer  serverP   = ssl->buffers.serverDH_P;
03602             buffer  serverG   = ssl->buffers.serverDH_G;
03603             buffer  serverPub = ssl->buffers.serverDH_Pub;
03604             byte    priv[ENCRYPT_LEN];
03605             word32  privSz;
03606             DhKey   key;
03607 
03608             if (serverP.buffer == 0 || serverG.buffer == 0 ||
03609                                        serverPub.buffer == 0)
03610                 return NO_PEER_KEY;
03611 
03612             InitDhKey(&key);
03613             ret = DhSetKey(&key, serverP.buffer, serverP.length,
03614                            serverG.buffer, serverG.length);
03615             if (ret == 0)
03616                 /* for DH, encSecret is Yc, agree is pre-master */
03617                 ret = DhGenerateKeyPair(&key, &ssl->rng, priv, &privSz,
03618                                         encSecret, &encSz);
03619             if (ret == 0)
03620                 ret = DhAgree(&key, ssl->arrays.preMasterSecret,
03621                               &ssl->arrays.preMasterSz, priv, privSz,
03622                               serverPub.buffer, serverPub.length);
03623             FreeDhKey(&key);
03624         #endif /* OPENSSL_EXTRA */
03625         #ifndef NO_PSK
03626         } else if (ssl->specs.kea == psk_kea) {
03627             byte* pms = ssl->arrays.preMasterSecret;
03628 
03629             ssl->arrays.psk_keySz = ssl->options.client_psk_cb(ssl,
03630                 ssl->arrays.server_hint, ssl->arrays.client_identity,
03631                 MAX_PSK_ID_LEN, ssl->arrays.psk_key, MAX_PSK_KEY_LEN);
03632             if (ssl->arrays.psk_keySz == 0 || 
03633                 ssl->arrays.psk_keySz > MAX_PSK_KEY_LEN)
03634                 return PSK_KEY_ERROR;
03635             encSz = (word32)XSTRLEN(ssl->arrays.client_identity);
03636             if (encSz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR;
03637             XMEMCPY(encSecret, ssl->arrays.client_identity, encSz);
03638 
03639             /* make psk pre master secret */
03640             /* length of key + length 0s + length of key + key */
03641             c16toa((word16)ssl->arrays.psk_keySz, pms);
03642             pms += 2;
03643             XMEMSET(pms, 0, ssl->arrays.psk_keySz);
03644             pms += ssl->arrays.psk_keySz;
03645             c16toa((word16)ssl->arrays.psk_keySz, pms);
03646             pms += 2;
03647             XMEMCPY(pms, ssl->arrays.psk_key, ssl->arrays.psk_keySz);
03648             ssl->arrays.preMasterSz = ssl->arrays.psk_keySz * 2 + 4;
03649         #endif /* NO_PSK */
03650         #ifdef HAVE_NTRU
03651         } else if (ssl->specs.kea == ntru_kea) {
03652             word32 rc;
03653             word16 cipherLen = sizeof(encSecret);
03654             DRBG_HANDLE drbg;
03655             static uint8_t const cyasslStr[] = {
03656                 'C', 'y', 'a', 'S', 'S', 'L', ' ', 'N', 'T', 'R', 'U'
03657             };
03658 
03659             RNG_GenerateBlock(&ssl->rng, ssl->arrays.preMasterSecret,
03660                               SECRET_LEN);
03661             ssl->arrays.preMasterSz = SECRET_LEN;
03662 
03663             if (ssl->peerNtruKeyPresent == 0)
03664                 return NO_PEER_KEY;
03665 
03666             rc = crypto_drbg_instantiate(MAX_NTRU_BITS, cyasslStr,
03667                                           sizeof(cyasslStr), GetEntropy, &drbg);
03668             if (rc != DRBG_OK)
03669                 return NTRU_DRBG_ERROR; 
03670 
03671             rc = crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen,ssl->peerNtruKey,
03672                                      ssl->arrays.preMasterSz,
03673                                      ssl->arrays.preMasterSecret,
03674                                      &cipherLen, encSecret);
03675             crypto_drbg_uninstantiate(drbg);
03676             if (rc != NTRU_OK)
03677                 return NTRU_ENCRYPT_ERROR;
03678 
03679             encSz = cipherLen;
03680             ret = 0;
03681         #endif /* HAVE_NTRU */
03682         } else
03683             return -1; /* unsupported kea */
03684 
03685         if (ret == 0) {
03686             byte              *output;
03687             int                sendSz;
03688             word32             tlsSz = 0;
03689             
03690             if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea)
03691                 tlsSz = 2;
03692 
03693             sendSz = encSz + tlsSz + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
03694             idx    = HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
03695 
03696             #ifdef CYASSL_DTLS
03697                 if (ssl->options.dtls) {
03698                     sendSz += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
03699                     idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
03700                 }
03701             #endif
03702 
03703             /* check for avalaible size */
03704             if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
03705                 return ret;
03706 
03707             /* get ouput buffer */
03708             output = ssl->buffers.outputBuffer.buffer + 
03709                      ssl->buffers.outputBuffer.idx;
03710 
03711             AddHeaders(output, encSz + tlsSz, client_key_exchange, ssl);
03712 
03713             if (tlsSz) {
03714                 c16toa((word16)encSz, &output[idx]);
03715                 idx += 2;
03716             }
03717             XMEMCPY(output + idx, encSecret, encSz);
03718             idx += encSz;
03719 
03720             HashOutput(ssl, output, sendSz, 0);
03721 
03722             #ifdef CYASSL_CALLBACKS
03723                 if (ssl->hsInfoOn)
03724                     AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
03725                 if (ssl->toInfoOn)
03726                     AddPacketInfo("ClientKeyExchange", &ssl->timeoutInfo,
03727                                   output, sendSz, ssl->heap);
03728             #endif
03729 
03730             ssl->buffers.outputBuffer.length += sendSz;
03731 
03732             ret = SendBuffered(ssl);
03733         }
03734     
03735         if (ret == 0 || ret == WANT_WRITE) {
03736             int tmpRet = MakeMasterSecret(ssl);
03737             if (tmpRet != 0)
03738                 ret = tmpRet;   /* save WANT_WRITE unless more serious */
03739             ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
03740         }
03741 
03742         return ret;
03743     }
03744 
03745     int SendCertificateVerify(SSL* ssl)
03746     {
03747         byte              *output;
03748         int                sendSz = 0, length, ret;
03749         word32             idx = 0;
03750         RsaKey             key;
03751 
03752         if (ssl->options.sendVerify == SEND_BLANK_CERT)
03753             return 0;  /* sent blank cert, can't verify */
03754 
03755         /* check for avalaible size */
03756         if ((ret = CheckAvalaibleSize(ssl, MAX_CERT_VERIFY_SZ)) != 0)
03757             return ret;
03758 
03759         /* get ouput buffer */
03760         output = ssl->buffers.outputBuffer.buffer +
03761                  ssl->buffers.outputBuffer.idx;
03762 
03763         BuildCertHashes(ssl, &ssl->certHashes);
03764 
03765         /* TODO: when add DSS support check here  */
03766         InitRsaKey(&key, ssl->heap);
03767         ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
03768                                   ssl->buffers.key.length); 
03769         if (ret == 0) {
03770             byte*  verify = (byte*)&output[RECORD_HEADER_SZ +
03771                                            HANDSHAKE_HEADER_SZ];
03772             byte*  signBuffer = ssl->certHashes.md5;
03773             word32 signSz = sizeof(Hashes);
03774 
03775             #ifdef CYASSL_DTLS
03776                 if (ssl->options.dtls)
03777                     verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
03778             #endif
03779             length = RsaEncryptSize(&key);
03780             c16toa((word16)length, verify);   /* prepend verify header */
03781 
03782             if (IsAtLeastTLSv1_2(ssl)) {
03783                 byte  encodedSig[MAX_ENCODED_SIG_SZ];
03784                 byte* digest;
03785                 int   hashType;
03786                 int   digestSz;
03787 
03788                 /* sha1 for now */
03789                 digest   = ssl->certHashes.sha;
03790                 hashType = SHAh;
03791                 digestSz = SHA_DIGEST_SIZE;
03792 
03793                 signSz = EncodeSignature(encodedSig, digest, digestSz,hashType);
03794                 signBuffer = encodedSig;
03795             }
03796 
03797             ret = RsaSSL_Sign(signBuffer, signSz, verify +
03798                   VERIFY_HEADER, ENCRYPT_LEN, &key, &ssl->rng);
03799 
03800             if (ret > 0) {
03801                 ret = 0;  /* reset */
03802 
03803                 AddHeaders(output, length + VERIFY_HEADER, certificate_verify,
03804                            ssl);
03805 
03806                 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + length +
03807                                             VERIFY_HEADER;
03808                 #ifdef CYASSL_DTLS
03809                     if (ssl->options.dtls)
03810                         sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
03811                 #endif
03812                 HashOutput(ssl, output, sendSz, 0);
03813             }
03814         }
03815 
03816         FreeRsaKey(&key);
03817 
03818         if (ret == 0) {
03819             #ifdef CYASSL_CALLBACKS
03820                 if (ssl->hsInfoOn)
03821                     AddPacketName("CertificateVerify", &ssl->handShakeInfo);
03822                 if (ssl->toInfoOn)
03823                     AddPacketInfo("CertificateVerify", &ssl->timeoutInfo,
03824                                   output, sendSz, ssl->heap);
03825             #endif
03826             ssl->buffers.outputBuffer.length += sendSz;
03827             return SendBuffered(ssl);
03828         }
03829         else
03830             return ret;
03831     }
03832 
03833 
03834 
03835 #endif /* NO_CYASSL_CLIENT */
03836 
03837 
03838 #ifndef NO_CYASSL_SERVER
03839 
03840     int SendServerHello(SSL* ssl)
03841     {
03842         byte              *output;
03843         word32             length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
03844         int                sendSz;
03845         int                ret;
03846 
03847         length = sizeof(ProtocolVersion) + RAN_LEN
03848                + ID_LEN + ENUM_LEN                 
03849                + SUITE_LEN 
03850                + ENUM_LEN;
03851 
03852         /* check for avalaible size */
03853         if ((ret = CheckAvalaibleSize(ssl, MAX_HELLO_SZ)) != 0)
03854             return ret;
03855 
03856         /* get ouput buffer */
03857         output = ssl->buffers.outputBuffer.buffer + 
03858                  ssl->buffers.outputBuffer.idx;
03859 
03860         sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
03861         AddHeaders(output, length, server_hello, ssl);
03862 
03863         #ifdef CYASSL_DTLS
03864             if (ssl->options.dtls) {
03865                 idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
03866                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
03867             }
03868         #endif
03869         /* now write to output */
03870             /* first version */
03871         XMEMCPY(output + idx, &ssl->version, sizeof(ProtocolVersion));
03872         idx += sizeof(ProtocolVersion);
03873 
03874             /* then random */
03875         if (!ssl->options.resuming)         
03876             RNG_GenerateBlock(&ssl->rng, ssl->arrays.serverRandom, RAN_LEN);
03877         XMEMCPY(output + idx, ssl->arrays.serverRandom, RAN_LEN);
03878         idx += RAN_LEN;
03879 
03880 #ifdef SHOW_SECRETS
03881         {
03882             int j;
03883             printf("server random: ");
03884             for (j = 0; j < RAN_LEN; j++)
03885                 printf("%02x", ssl->arrays.serverRandom[j]);
03886             printf("\n");
03887         }
03888 #endif
03889             /* then session id */
03890         output[idx++] = ID_LEN;
03891         if (!ssl->options.resuming)
03892             RNG_GenerateBlock(&ssl->rng, ssl->arrays.sessionID, ID_LEN);
03893         XMEMCPY(output + idx, ssl->arrays.sessionID, ID_LEN);
03894         idx += ID_LEN;
03895 
03896             /* then cipher suite */
03897         output[idx++] = 0x00; 
03898         output[idx++] = ssl->options.cipherSuite;
03899 
03900             /* last, compression */
03901         if (ssl->options.usingCompression)
03902             output[idx++] = ZLIB_COMPRESSION;
03903         else
03904             output[idx++] = NO_COMPRESSION;
03905             
03906         ssl->buffers.outputBuffer.length += sendSz;
03907         HashOutput(ssl, output, sendSz, 0);
03908 
03909         #ifdef CYASSL_CALLBACKS
03910             if (ssl->hsInfoOn)
03911                 AddPacketName("ServerHello", &ssl->handShakeInfo);
03912             if (ssl->toInfoOn)
03913                 AddPacketInfo("ServerHello", &ssl->timeoutInfo, output, sendSz,
03914                               ssl->heap);
03915         #endif
03916 
03917         ssl->options.serverState = SERVER_HELLO_COMPLETE;
03918 
03919         return SendBuffered(ssl);
03920     }
03921 
03922     int SendServerKeyExchange(SSL* ssl)
03923     {
03924         int ret = 0;
03925 
03926         if (ssl->specs.kea != psk_kea) return 0;
03927 
03928         #ifndef NO_PSK
03929         {
03930             byte    *output;
03931             word32   length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
03932             int      sendSz;
03933             if (ssl->arrays.server_hint[0] == 0) return 0; /* don't send */
03934 
03935             /* include size part */
03936             length = (word32)XSTRLEN(ssl->arrays.server_hint);
03937             if (length > MAX_PSK_ID_LEN) return SERVER_HINT_ERROR;
03938             length += + HINT_LEN_SZ;
03939             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
03940 
03941             #ifdef CYASSL_DTLS 
03942                 if (ssl->options.dtls) {
03943                     sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
03944                     idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
03945                 }
03946             #endif
03947             /* check for avalaible size */
03948             if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
03949                return ret;
03950 
03951             /* get ouput buffer */
03952             output = ssl->buffers.outputBuffer.buffer + 
03953                      ssl->buffers.outputBuffer.idx;
03954 
03955             AddHeaders(output, length, server_key_exchange, ssl);
03956 
03957             /* key data */
03958             c16toa((word16)(length - HINT_LEN_SZ), output + idx);
03959             idx += HINT_LEN_SZ;
03960             XMEMCPY(output + idx, ssl->arrays.server_hint, length - HINT_LEN_SZ);
03961 
03962             HashOutput(ssl, output, sendSz, 0);
03963 
03964             #ifdef CYASSL_CALLBACKS
03965                 if (ssl->hsInfoOn)
03966                     AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
03967                 if (ssl->toInfoOn)
03968                     AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
03969                                   output, sendSz, ssl->heap);
03970             #endif
03971 
03972             ssl->buffers.outputBuffer.length += sendSz;
03973             ret = SendBuffered(ssl);
03974             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
03975         }
03976         #endif /*NO_PSK */
03977 
03978         return ret;
03979     }
03980 
03981 
03982     static int MatchSuite(SSL* ssl, Suites* peerSuites)
03983     {
03984         word16 i, j;
03985 
03986         /* & 0x1 equivalent % 2 */
03987         if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1)
03988             return MATCH_SUITE_ERROR;
03989 
03990         /* start with best, if a match we are good, Ciphers are at odd index
03991            since all SSL and TLS ciphers have 0x00 first byte               */
03992         for (i = 1; i < ssl->suites.suiteSz; i += 2)
03993             for (j = 1; j < peerSuites->suiteSz; j += 2)
03994                 if (ssl->suites.suites[i] == peerSuites->suites[j]) {
03995                     ssl->options.cipherSuite = ssl->suites.suites[i];
03996                     return SetCipherSpecs(ssl);
03997                 }
03998 
03999         return MATCH_SUITE_ERROR;
04000     }
04001 
04002 
04003     /* process alert, return level */
04004     int ProcessOldClientHello(SSL* ssl, const byte* input, word32* inOutIdx,
04005                               word32 inSz, word16 sz)
04006     {
04007         word32          idx = *inOutIdx;
04008         word16          sessionSz;
04009         word16          randomSz;
04010         word16          i, j;
04011         ProtocolVersion pv;
04012         Suites          clSuites;
04013 
04014 #ifdef CYASSL_CALLBACKS
04015         if (ssl->hsInfoOn)
04016             AddPacketName("ClientHello", &ssl->handShakeInfo);
04017         if (ssl->toInfoOn)
04018             AddLateName("ClientHello", &ssl->timeoutInfo);
04019 #endif
04020 
04021         /* manually hash input since different format */
04022         Md5Update(&ssl->hashMd5, input + idx, sz);
04023         ShaUpdate(&ssl->hashSha, input + idx, sz);
04024 
04025         /* does this value mean client_hello? */
04026         idx++;
04027 
04028         /* version */
04029         pv.major = input[idx++];
04030         pv.minor = input[idx++];
04031         ssl->chVersion = pv;  /* store */
04032 
04033         if (ssl->version.minor > 0 && pv.minor == 0) {
04034             if (!ssl->options.downgrade)
04035                 return VERSION_ERROR;
04036             /* turn off tls */
04037             ssl->options.tls    = 0;
04038             ssl->options.tls1_1 = 0;
04039             ssl->version.minor  = 0;
04040             InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, FALSE,
04041                        ssl->options.haveNTRU);
04042         }
04043 
04044         /* suite size */
04045         ato16(&input[idx], &clSuites.suiteSz);
04046         idx += 2;
04047 
04048         if (clSuites.suiteSz > MAX_SUITE_SZ)
04049             return BUFFER_ERROR;
04050 
04051         /* session size */
04052         ato16(&input[idx], &sessionSz);
04053         idx += 2;
04054 
04055         if (sessionSz > ID_LEN)
04056             return BUFFER_ERROR;
04057     
04058         /* random size */
04059         ato16(&input[idx], &randomSz);
04060         idx += 2;
04061 
04062         if (randomSz > RAN_LEN)
04063             return BUFFER_ERROR;
04064 
04065         /* suites */
04066         for (i = 0, j = 0; i < clSuites.suiteSz; i += 3) {    
04067             byte first = input[idx++];
04068             if (!first) { /* implicit: skip sslv2 type */
04069                 XMEMCPY(&clSuites.suites[j], &input[idx], 2);
04070                 j += 2;
04071             }
04072             idx += 2;
04073         }
04074         clSuites.suiteSz = j;
04075 
04076         /* session id */
04077         if (sessionSz) {
04078             XMEMCPY(ssl->arrays.sessionID, input + idx, sessionSz);
04079             idx += sessionSz;
04080             ssl->options.resuming = 1;
04081         }
04082 
04083         /* random */
04084         if (randomSz < RAN_LEN)
04085             XMEMSET(ssl->arrays.clientRandom, 0, RAN_LEN - randomSz);
04086         XMEMCPY(&ssl->arrays.clientRandom[RAN_LEN - randomSz], input + idx,
04087                randomSz);
04088         idx += randomSz;
04089 
04090         if (ssl->options.usingCompression)
04091             ssl->options.usingCompression = 0;  /* turn off */
04092 
04093         ssl->options.clientState = CLIENT_HELLO_COMPLETE;
04094         *inOutIdx = idx;
04095 
04096         /* DoClientHello uses same resume code */
04097         while (ssl->options.resuming) {  /* let's try */
04098             SSL_SESSION* session = GetSession(ssl, ssl->arrays.masterSecret);
04099             if (!session) {
04100                 ssl->options.resuming = 0;
04101                 break;   /* session lookup failed */
04102             }
04103             if (MatchSuite(ssl, &clSuites) < 0)
04104                 return UNSUPPORTED_SUITE;
04105 
04106             RNG_GenerateBlock(&ssl->rng, ssl->arrays.serverRandom, RAN_LEN);
04107             if (ssl->options.tls)
04108                 DeriveTlsKeys(ssl);
04109             else
04110                 DeriveKeys(ssl);
04111             ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
04112 
04113             return 0;
04114         }
04115 
04116         return MatchSuite(ssl, &clSuites);
04117     }
04118 
04119 
04120     static int DoClientHello(SSL* ssl, const byte* input, word32* inOutIdx,
04121                              word32 totalSz, word32 helloSz)
04122     {
04123         byte b;
04124         ProtocolVersion pv;
04125         Suites          clSuites;
04126         word32 i = *inOutIdx;
04127         word32 begin = i;
04128 
04129 #ifdef CYASSL_CALLBACKS
04130         if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
04131         if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
04132 #endif
04133         /* make sure can read up to session */
04134         if (i + sizeof(pv) + RAN_LEN + ENUM_LEN > totalSz)
04135             return INCOMPLETE_DATA;
04136 
04137         XMEMCPY(&pv, input + i, sizeof(pv));
04138         ssl->chVersion = pv;   /* store */
04139         i += sizeof(pv);
04140         if (ssl->version.minor > 0 && pv.minor == 0) {
04141             if (!ssl->options.downgrade)
04142                 return VERSION_ERROR;
04143             /* turn off tls */
04144             ssl->options.tls    = 0;
04145             ssl->options.tls1_1 = 0;
04146             ssl->version.minor  = 0;
04147             InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, FALSE,
04148                        ssl->options.haveNTRU);
04149         }
04150         /* random */
04151         XMEMCPY(ssl->arrays.clientRandom, input + i, RAN_LEN);
04152         i += RAN_LEN;
04153 
04154 #ifdef SHOW_SECRETS
04155         {
04156             int j;
04157             printf("client random: ");
04158             for (j = 0; j < RAN_LEN; j++)
04159                 printf("%02x", ssl->arrays.clientRandom[j]);
04160             printf("\n");
04161         }
04162 #endif
04163         /* session id */
04164         b = input[i++];
04165         if (b) {
04166             if (i + ID_LEN > totalSz)
04167                 return INCOMPLETE_DATA;
04168             XMEMCPY(ssl->arrays.sessionID, input + i, ID_LEN);
04169             i += b;
04170             ssl->options.resuming= 1; /* client wants to resume */
04171         }
04172         
04173         #ifdef CYASSL_DTLS
04174             /* cookie */
04175             if (ssl->options.dtls) {
04176                 b = input[i++];
04177                 if (b) {
04178                     if (b > MAX_COOKIE_LEN)
04179                         return BUFFER_ERROR;
04180                     if (i + b > totalSz)
04181                         return INCOMPLETE_DATA;
04182                     XMEMCPY(ssl->arrays.cookie, input + i, b);
04183                     i += b;
04184                 }
04185             }
04186         #endif
04187 
04188         if (i + LENGTH_SZ > totalSz)
04189             return INCOMPLETE_DATA;
04190         /* suites */
04191         ato16(&input[i], &clSuites.suiteSz);
04192         i += 2;
04193 
04194         /* suites and comp len */
04195         if (i + clSuites.suiteSz + ENUM_LEN > totalSz)
04196             return INCOMPLETE_DATA;
04197         if (clSuites.suiteSz > MAX_SUITE_SZ)
04198             return BUFFER_ERROR;
04199         XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
04200         i += clSuites.suiteSz;
04201 
04202         b = input[i++];  /* comp len */
04203         if (i + b > totalSz)
04204             return INCOMPLETE_DATA;
04205 
04206         if (ssl->options.usingCompression) {
04207             int match = 0;
04208             while (b--) {
04209                 byte comp = input[i++];
04210                 if (comp == ZLIB_COMPRESSION)
04211                     match = 1;
04212             }
04213             if (!match)
04214                 ssl->options.usingCompression = 0;  /* turn off */
04215         }
04216         else
04217             i += b;  /* ignore, since we're not on */
04218 
04219         ssl->options.clientState = CLIENT_HELLO_COMPLETE;
04220 
04221         *inOutIdx = i;
04222         if ( (i - begin) < helloSz)
04223             *inOutIdx = begin + helloSz;  /* skip extensions */
04224         
04225         /* ProcessOld uses same resume code */
04226         while (ssl->options.resuming) {  /* let's try */
04227             SSL_SESSION* session = GetSession(ssl, ssl->arrays.masterSecret);
04228             if (!session) {
04229                 ssl->options.resuming = 0;
04230                 break;   /* session lookup failed */
04231             }
04232             if (MatchSuite(ssl, &clSuites) < 0)
04233                 return UNSUPPORTED_SUITE;
04234 
04235             RNG_GenerateBlock(&ssl->rng, ssl->arrays.serverRandom, RAN_LEN);
04236             if (ssl->options.tls)
04237                 DeriveTlsKeys(ssl);
04238             else
04239                 DeriveKeys(ssl);
04240             ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
04241 
04242             return 0;
04243         }
04244         return MatchSuite(ssl, &clSuites);
04245     }
04246 
04247 
04248     static int DoCertificateVerify(SSL* ssl, byte* input, word32* inOutsz,
04249                                    word32 totalSz)
04250     {
04251         word16      sz = 0;
04252         word32      i = *inOutsz;
04253         int         ret = VERIFY_CERT_ERROR;   /* start in error state */
04254         byte*       sig;
04255         byte*       out;
04256         int         outLen;
04257 
04258         #ifdef CYASSL_CALLBACKS
04259             if (ssl->hsInfoOn)
04260                 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
04261             if (ssl->toInfoOn)
04262                 AddLateName("CertificateVerify", &ssl->timeoutInfo);
04263         #endif
04264         if ( (i + VERIFY_HEADER) > totalSz)
04265             return INCOMPLETE_DATA;
04266 
04267         ato16(&input[i], &sz);
04268         i += VERIFY_HEADER;
04269 
04270         if ( (i + sz) > totalSz)
04271             return INCOMPLETE_DATA;
04272 
04273         if (sz > ENCRYPT_LEN)
04274             return BUFFER_ERROR;
04275 
04276         sig = &input[i];
04277         *inOutsz = i + sz;
04278         /* TODO: when add DSS support check here  */
04279         if (ssl->peerRsaKeyPresent != 0) {
04280             outLen = RsaSSL_VerifyInline(sig, sz, &out, &ssl->peerRsaKey);
04281 
04282             if (IsAtLeastTLSv1_2(ssl)) {
04283                 byte   encodedSig[MAX_ENCODED_SIG_SZ];
04284                 word32 sigSz;
04285                 byte*  digest;
04286                 int    hashType;
04287                 int    digestSz;
04288 
04289                 /* sha1 for now */
04290                 digest   = ssl->certHashes.sha;
04291                 hashType = SHAh;
04292                 digestSz = SHA_DIGEST_SIZE;
04293 
04294                 sigSz = EncodeSignature(encodedSig, digest, digestSz, hashType);
04295 
04296                 if (outLen == sigSz && XMEMCMP(out, encodedSig, sigSz) == 0)
04297                     ret = 0;
04298             }
04299             else {
04300                 if (outLen == sizeof(ssl->certHashes) && XMEMCMP(out,
04301                              ssl->certHashes.md5, sizeof(ssl->certHashes)) == 0)
04302                     ret = 0;
04303             }
04304         }
04305         return ret;
04306     }
04307 
04308 
04309     int SendServerHelloDone(SSL* ssl)
04310     {
04311         byte              *output;
04312         int                sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
04313         int                ret;
04314 
04315         #ifdef CYASSL_DTLS
04316             if (ssl->options.dtls)
04317                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
04318         #endif
04319         /* check for avalaible size */
04320         if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
04321             return ret;
04322 
04323         /* get ouput buffer */
04324         output = ssl->buffers.outputBuffer.buffer +
04325                  ssl->buffers.outputBuffer.idx;
04326 
04327         AddHeaders(output, 0, server_hello_done, ssl);
04328 
04329         HashOutput(ssl, output, sendSz, 0);
04330 #ifdef CYASSL_CALLBACKS
04331         if (ssl->hsInfoOn)
04332             AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
04333         if (ssl->toInfoOn)
04334             AddPacketInfo("ServerHelloDone", &ssl->timeoutInfo, output, sendSz,
04335                           ssl->heap);
04336 #endif
04337         ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
04338 
04339         ssl->buffers.outputBuffer.length += sendSz;
04340 
04341         return SendBuffered(ssl);
04342     }
04343 
04344 
04345     int SendHelloVerifyRequest(SSL* ssl)
04346     {
04347         byte* output;
04348         int   length = VERSION_SZ + ENUM_LEN;
04349         int   idx    = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
04350         int   sendSz = length + idx;
04351         int   ret;
04352 
04353         /* check for avalaible size */
04354         if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
04355             return ret;
04356 
04357         /* get ouput buffer */
04358         output = ssl->buffers.outputBuffer.buffer +
04359                  ssl->buffers.outputBuffer.idx;
04360 
04361         AddHeaders(output, length, hello_verify_request, ssl);
04362 
04363         XMEMCPY(output + idx, &ssl->chVersion, VERSION_SZ);
04364         idx += VERSION_SZ;
04365         output[idx++] = 0;     /* no cookie for now */
04366 
04367         HashOutput(ssl, output, sendSz, 0);
04368 #ifdef CYASSL_CALLBACKS
04369         if (ssl->hsInfoOn)
04370             AddPacketName("HelloVerifyRequest", &ssl->handShakeInfo);
04371         if (ssl->toInfoOn)
04372             AddPacketInfo("HelloVerifyRequest", &ssl->timeoutInfo, output,
04373                           sendSz, ssl->heap);
04374 #endif
04375         ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
04376 
04377         ssl->buffers.outputBuffer.length += sendSz;
04378 
04379         return SendBuffered(ssl);
04380     }
04381 
04382 
04383     static int DoClientKeyExchange(SSL* ssl, byte* input,
04384                                    word32* inOutIdx)
04385     {
04386         int    ret = 0;
04387         word32 length = 0;
04388         byte*  out;
04389 
04390         if (ssl->options.verifyPeer && ssl->options.failNoCert)
04391             if (!ssl->options.havePeerCert) {
04392                 CYASSL_MSG("client didn't present peer cert");
04393                 return NO_PEER_CERT;
04394             }
04395 
04396         #ifdef CYASSL_CALLBACKS
04397             if (ssl->hsInfoOn)
04398                 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
04399             if (ssl->toInfoOn)
04400                 AddLateName("ClientKeyExchange", &ssl->timeoutInfo);
04401         #endif
04402         if (ssl->specs.kea == rsa_kea) {
04403             word32 idx = 0;
04404             RsaKey key;
04405             byte*  tmp = 0;
04406 
04407             InitRsaKey(&key, ssl->heap);
04408 
04409             if (ssl->buffers.key.buffer)
04410                 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
04411                                           ssl->buffers.key.length);
04412             else
04413                 return NO_PRIVATE_KEY;
04414 
04415             if (ret == 0) {
04416                 length = RsaEncryptSize(&key);
04417                 ssl->arrays.preMasterSz = SECRET_LEN;
04418 
04419                 if (ssl->options.tls)
04420                     (*inOutIdx) += 2;
04421                 tmp = input + *inOutIdx;
04422                 *inOutIdx += length;
04423 
04424                 if (RsaPrivateDecryptInline(tmp, length, &out, &key) ==
04425                                                              SECRET_LEN) {
04426                     XMEMCPY(ssl->arrays.preMasterSecret, out, SECRET_LEN);
04427                     if (ssl->arrays.preMasterSecret[0] != ssl->chVersion.major
04428                      ||
04429                         ssl->arrays.preMasterSecret[1] != ssl->chVersion.minor)
04430 
04431                         ret = PMS_VERSION_ERROR;
04432                     else
04433                         ret = MakeMasterSecret(ssl);
04434                 }
04435                 else
04436                     ret = RSA_PRIVATE_ERROR;
04437             }
04438 
04439             FreeRsaKey(&key);
04440 #ifndef NO_PSK
04441         } else if (ssl->specs.kea == psk_kea) {
04442             byte* pms = ssl->arrays.preMasterSecret;
04443             word16 ci_sz;
04444 
04445             ato16(&input[*inOutIdx], &ci_sz);
04446             *inOutIdx += LENGTH_SZ;
04447             if (ci_sz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR;
04448 
04449             XMEMCPY(ssl->arrays.client_identity, &input[*inOutIdx], ci_sz);
04450             *inOutIdx += ci_sz;
04451             ssl->arrays.client_identity[ci_sz] = 0;
04452 
04453             ssl->arrays.psk_keySz = ssl->options.server_psk_cb(ssl,
04454                 ssl->arrays.client_identity, ssl->arrays.psk_key,
04455                 MAX_PSK_KEY_LEN);
04456             if (ssl->arrays.psk_keySz == 0 || 
04457                 ssl->arrays.psk_keySz > MAX_PSK_KEY_LEN) return PSK_KEY_ERROR;
04458             
04459             /* make psk pre master secret */
04460             /* length of key + length 0s + length of key + key */
04461             c16toa((word16)ssl->arrays.psk_keySz, pms);
04462             pms += 2;
04463             XMEMSET(pms, 0, ssl->arrays.psk_keySz);
04464             pms += ssl->arrays.psk_keySz;
04465             c16toa((word16)ssl->arrays.psk_keySz, pms);
04466             pms += 2;
04467             XMEMCPY(pms, ssl->arrays.psk_key, ssl->arrays.psk_keySz);
04468             ssl->arrays.preMasterSz = ssl->arrays.psk_keySz * 2 + 4;
04469 
04470             ret = MakeMasterSecret(ssl);
04471 #endif /* NO_PSK */
04472 #ifdef HAVE_NTRU
04473         } else if (ssl->specs.kea == ntru_kea) {
04474             word32 rc;
04475             word16 cipherLen;
04476             word16 plainLen = sizeof(ssl->arrays.preMasterSecret);
04477             byte*  tmp;
04478 
04479             if (!ssl->buffers.key.buffer)
04480                 return NO_PRIVATE_KEY;
04481 
04482             ato16(&input[*inOutIdx], &cipherLen);
04483             *inOutIdx += LENGTH_SZ;
04484             if (cipherLen > MAX_NTRU_ENCRYPT_SZ)
04485                 return NTRU_KEY_ERROR;
04486 
04487             tmp = input + *inOutIdx;
04488             rc = crypto_ntru_decrypt((word16)ssl->buffers.key.length,
04489                         ssl->buffers.key.buffer, cipherLen, tmp, &plainLen,
04490                         ssl->arrays.preMasterSecret);
04491 
04492             if (rc != NTRU_OK || plainLen != SECRET_LEN)
04493                 return NTRU_DECRYPT_ERROR;
04494             *inOutIdx += cipherLen;
04495 
04496             ssl->arrays.preMasterSz = plainLen;
04497             ret = MakeMasterSecret(ssl);
04498 #endif /* HAVE_NTRU */
04499         }
04500 
04501         if (ret == 0) {
04502             ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
04503             if (ssl->options.verifyPeer)
04504                 BuildCertHashes(ssl, &ssl->certHashes);
04505         }
04506 
04507         return ret;
04508     }
04509 
04510 #endif /* NO_CYASSL_SERVER */
04511 
04512 
04513 #ifdef SINGLE_THREADED
04514 
04515 int InitMutex(CyaSSL_Mutex* m)
04516 {
04517     return 0;
04518 }
04519 
04520 
04521 int FreeMutex(CyaSSL_Mutex* m)
04522 {
04523     return 0;
04524 }
04525 
04526 
04527 int LockMutex(CyaSSL_Mutex* m)
04528 {
04529     return 0;
04530 }
04531 
04532 
04533 int UnLockMutex(CyaSSL_Mutex* m)
04534 {
04535     return 0;
04536 }
04537 
04538 #else /* MULTI_THREAD */
04539 
04540     #ifdef USE_WINDOWS_API
04541 
04542         int InitMutex(CyaSSL_Mutex* m)
04543         {
04544             InitializeCriticalSection(m);
04545             return 0;
04546         }
04547 
04548 
04549         int FreeMutex(CyaSSL_Mutex* m)
04550         {
04551             DeleteCriticalSection(m);
04552             return 0;
04553         }
04554 
04555 
04556         int LockMutex(CyaSSL_Mutex* m)
04557         {
04558             EnterCriticalSection(m);
04559             return 0;
04560         }
04561 
04562 
04563         int UnLockMutex(CyaSSL_Mutex* m)
04564         {
04565             LeaveCriticalSection(m);
04566             return 0;
04567         }
04568 
04569     #elif defined(CYASSL_PTHREADS)
04570 
04571         int InitMutex(CyaSSL_Mutex* m)
04572         {
04573             if (pthread_mutex_init(m, 0) == 0)
04574                 return 0;
04575             else
04576                 return -1;
04577         }
04578 
04579 
04580         int FreeMutex(CyaSSL_Mutex* m)
04581         {
04582             if (pthread_mutex_destroy(m) == 0)
04583                 return 0;
04584             else
04585                 return -1;
04586         }
04587 
04588 
04589         int LockMutex(CyaSSL_Mutex* m)
04590         {
04591             if (pthread_mutex_lock(m) == 0)
04592                 return 0;
04593             else
04594                 return -1;
04595         }
04596 
04597 
04598         int UnLockMutex(CyaSSL_Mutex* m)
04599         {
04600             if (pthread_mutex_unlock(m) == 0)
04601                 return 0;
04602             else
04603                 return -1;
04604         }
04605 
04606     #elif defined(THREADX)
04607 
04608         int InitMutex(CyaSSL_Mutex* m)
04609         {
04610             if (tx_mutex_create(m, "CyaSSL Mutex", TX_NO_INHERIT) == 0)
04611                 return 0;
04612             else
04613                 return -1;
04614         }
04615 
04616 
04617         int FreeMutex(CyaSSL_Mutex* m)
04618         {
04619             if (tx_mutex_delete(m) == 0)
04620                 return 0;
04621             else
04622                 return -1;
04623         }
04624 
04625 
04626         int LockMutex(CyaSSL_Mutex* m)
04627         {
04628             if (tx_mutex_get(m, TX_WAIT_FOREVER) == 0)
04629                 return 0;
04630             else
04631                 return -1;
04632         }
04633 
04634 
04635         int UnLockMutex(CyaSSL_Mutex* m)
04636         {
04637             if (tx_mutex_put(m) == 0)
04638                 return 0;
04639             else
04640                 return -1;
04641         }
04642 
04643     #elif defined(MICRIUM)
04644 
04645         int InitMutex(CyaSSL_Mutex* m)
04646         {
04647             #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
04648                 if (NetSecure_OS_MutexCreate(m) == 0)
04649                     return 0;
04650                 else
04651                     return -1;
04652             #else
04653                 return 0;
04654             #endif
04655         }
04656 
04657 
04658         int FreeMutex(CyaSSL_Mutex* m)
04659         {
04660             #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
04661                 if (NetSecure_OS_FreeMutex(m) == 0)
04662                     return 0;
04663                 else
04664                     return -1;
04665             #else
04666                 return 0;
04667             #endif
04668         }
04669 
04670 
04671         int LockMutex(CyaSSL_Mutex* m)
04672         {
04673             #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
04674                 if (NetSecure_OS_LockMutex(m) == 0)
04675                     return 0;
04676                 else
04677                     return -1;
04678             #else
04679                 return 0;
04680             #endif
04681         }
04682 
04683 
04684         int UnLockMutex(CyaSSL_Mutex* m)
04685         {
04686             #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
04687                 if (NetSecure_OS_UnLockMutex(m) == 0)
04688                     return 0;
04689                 else
04690                     return -1;
04691             #else
04692                 return 0;
04693             #endif
04694 
04695         }
04696 
04697     #endif /* USE_WINDOWS_API */
04698 #endif /* SINGLE_THREADED */
04699 
04700 
04701 #ifdef DEBUG_CYASSL
04702 
04703     static int logging = 0;
04704 
04705 
04706     int CyaSSL_Debugging_ON(void)
04707     {
04708         logging = 1;
04709         return 0;
04710     }
04711 
04712 
04713     void CyaSSL_Debugging_OFF(void)
04714     {
04715         logging = 0;
04716     }
04717 
04718 
04719 #ifdef THREADX
04720     int dc_log_printf(char*, ...);
04721 #endif
04722 
04723     void CYASSL_MSG(const char* msg)
04724     {
04725         if (logging) {
04726 #ifdef THREADX
04727             dc_log_printf("%s\n", msg);
04728 #elif defined(MICRIUM)
04729         #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
04730             NetSecure_TraceOut((CPU_CHAR *)msg);
04731         #endif
04732 #else
04733             fprintf(stderr, "%s\n", msg);
04734 #endif
04735         }
04736     }
04737 
04738 
04739     void CYASSL_ENTER(const char* msg)
04740     {
04741         if (logging) {
04742             char buffer[80];
04743             sprintf(buffer, "CyaSSL Entering %s", msg);
04744             CYASSL_MSG(buffer);
04745         }
04746     }
04747 
04748 
04749     void CYASSL_LEAVE(const char* msg, int ret)
04750     {
04751         if (logging) {
04752             char buffer[80];
04753             sprintf(buffer, "CyaSSL Leaving %s, return %d", msg, ret);
04754             CYASSL_MSG(buffer);
04755         }
04756     }
04757 
04758 
04759     void CYASSL_ERROR(int error)
04760     {
04761         if (logging) {
04762             char buffer[80];
04763             sprintf(buffer, "CyaSSL error occured, error = %d", error);
04764             CYASSL_MSG(buffer);
04765         }
04766     }
04767 
04768 
04769 #else   /* DEBUG_CYASSL */
04770 
04771     int CyaSSL_Debugging_ON(void)
04772     {
04773         return -1;    /* not compiled in */
04774     }
04775 
04776 
04777     void CyaSSL_Debugging_OFF(void)
04778     {
04779         /* already off */
04780     }
04781 
04782 #endif  /* DEBUG_CYASSL */