CyaSSL is an SSL library for devices like mbed.
Dependents: cyassl-client Sync
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 */
Generated on Tue Jul 12 2022 18:43:19 by 1.7.2