Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
tls.c
00001 /* tls.c 00002 * 00003 * Copyright (C) 2006-2013 wolfSSL Inc. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * CyaSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include <cyassl/ctaocrypt/settings.h> 00027 00028 #include <cyassl/ssl.h> 00029 #include <cyassl/internal.h> 00030 #include <cyassl/error-ssl.h> 00031 #include <cyassl/ctaocrypt/hmac.h> 00032 00033 00034 00035 #ifndef NO_TLS 00036 00037 00038 #ifndef min 00039 00040 static INLINE word32 min(word32 a, word32 b) 00041 { 00042 return a > b ? b : a; 00043 } 00044 00045 #endif /* min */ 00046 00047 00048 #ifdef CYASSL_SHA384 00049 #define PHASH_MAX_DIGEST_SIZE SHA384_DIGEST_SIZE 00050 #else 00051 #define PHASH_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE 00052 #endif 00053 00054 /* compute p_hash for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1 PRF */ 00055 static int p_hash(byte* result, word32 resLen, const byte* secret, 00056 word32 secLen, const byte* seed, word32 seedLen, int hash) 00057 { 00058 word32 len = PHASH_MAX_DIGEST_SIZE; 00059 word32 times; 00060 word32 lastLen; 00061 word32 lastTime; 00062 word32 i; 00063 word32 idx = 0; 00064 int ret; 00065 byte previous[PHASH_MAX_DIGEST_SIZE]; /* max size */ 00066 byte current[PHASH_MAX_DIGEST_SIZE]; /* max size */ 00067 00068 Hmac hmac; 00069 00070 switch (hash) { 00071 #ifndef NO_MD5 00072 case md5_mac: 00073 { 00074 len = MD5_DIGEST_SIZE; 00075 hash = MD5; 00076 } 00077 break; 00078 #endif 00079 #ifndef NO_SHA256 00080 case sha256_mac: 00081 { 00082 len = SHA256_DIGEST_SIZE; 00083 hash = SHA256; 00084 } 00085 break; 00086 #endif 00087 #ifdef CYASSL_SHA384 00088 case sha384_mac: 00089 { 00090 len = SHA384_DIGEST_SIZE; 00091 hash = SHA384; 00092 } 00093 break; 00094 #endif 00095 #ifndef NO_SHA 00096 case sha_mac: 00097 default: 00098 { 00099 len = SHA_DIGEST_SIZE; 00100 hash = SHA; 00101 } 00102 break; 00103 #endif 00104 } 00105 00106 times = resLen / len; 00107 lastLen = resLen % len; 00108 if (lastLen) times += 1; 00109 lastTime = times - 1; 00110 00111 ret = HmacSetKey(&hmac, hash, secret, secLen); 00112 if (ret != 0) 00113 return ret; 00114 HmacUpdate(&hmac, seed, seedLen); /* A0 = seed */ 00115 HmacFinal(&hmac, previous); /* A1 */ 00116 00117 for (i = 0; i < times; i++) { 00118 HmacUpdate(&hmac, previous, len); 00119 HmacUpdate(&hmac, seed, seedLen); 00120 HmacFinal(&hmac, current); 00121 00122 if ( (i == lastTime) && lastLen) 00123 XMEMCPY(&result[idx], current, min(lastLen, sizeof(current))); 00124 else { 00125 XMEMCPY(&result[idx], current, len); 00126 idx += len; 00127 HmacUpdate(&hmac, previous, len); 00128 HmacFinal(&hmac, previous); 00129 } 00130 } 00131 XMEMSET(previous, 0, sizeof previous); 00132 XMEMSET(current, 0, sizeof current); 00133 XMEMSET(&hmac, 0, sizeof hmac); 00134 00135 return 0; 00136 } 00137 00138 00139 00140 #ifndef NO_OLD_TLS 00141 00142 /* calculate XOR for TLSv1 PRF */ 00143 static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha) 00144 { 00145 word32 i; 00146 00147 for (i = 0; i < digLen; i++) 00148 digest[i] = md5[i] ^ sha[i]; 00149 } 00150 00151 00152 /* compute TLSv1 PRF (pseudo random function using HMAC) */ 00153 static int doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen, 00154 const byte* label, word32 labLen, const byte* seed, 00155 word32 seedLen) 00156 { 00157 int ret; 00158 word32 half = (secLen + 1) / 2; 00159 00160 byte md5_half[MAX_PRF_HALF]; /* half is real size */ 00161 byte sha_half[MAX_PRF_HALF]; /* half is real size */ 00162 byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */ 00163 byte md5_result[MAX_PRF_DIG]; /* digLen is real size */ 00164 byte sha_result[MAX_PRF_DIG]; /* digLen is real size */ 00165 00166 if (half > MAX_PRF_HALF) 00167 return BUFFER_E; 00168 if (labLen + seedLen > MAX_PRF_LABSEED) 00169 return BUFFER_E; 00170 if (digLen > MAX_PRF_DIG) 00171 return BUFFER_E; 00172 00173 XMEMSET(md5_result, 0, digLen); 00174 XMEMSET(sha_result, 0, digLen); 00175 00176 XMEMCPY(md5_half, secret, half); 00177 XMEMCPY(sha_half, secret + half - secLen % 2, half); 00178 00179 XMEMCPY(labelSeed, label, labLen); 00180 XMEMCPY(labelSeed + labLen, seed, seedLen); 00181 00182 ret = p_hash(md5_result, digLen, md5_half, half, labelSeed, 00183 labLen + seedLen, md5_mac); 00184 if (ret != 0) 00185 return ret; 00186 ret = p_hash(sha_result, digLen, sha_half, half, labelSeed, 00187 labLen + seedLen, sha_mac); 00188 if (ret != 0) 00189 return ret; 00190 get_xor(digest, digLen, md5_result, sha_result); 00191 00192 return 0; 00193 } 00194 00195 #endif 00196 00197 00198 /* Wrapper to call straight thru to p_hash in TSL 1.2 cases to remove stack 00199 use */ 00200 static int PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen, 00201 const byte* label, word32 labLen, const byte* seed, word32 seedLen, 00202 int useAtLeastSha256, int hash_type) 00203 { 00204 int ret = 0; 00205 00206 if (useAtLeastSha256) { 00207 byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */ 00208 00209 if (labLen + seedLen > MAX_PRF_LABSEED) 00210 return BUFFER_E; 00211 00212 XMEMCPY(labelSeed, label, labLen); 00213 XMEMCPY(labelSeed + labLen, seed, seedLen); 00214 00215 /* If a cipher suite wants an algorithm better than sha256, it 00216 * should use better. */ 00217 if (hash_type < sha256_mac) 00218 hash_type = sha256_mac; 00219 ret = p_hash(digest, digLen, secret, secLen, labelSeed, 00220 labLen + seedLen, hash_type); 00221 } 00222 #ifndef NO_OLD_TLS 00223 else { 00224 ret = doPRF(digest, digLen, secret, secLen, label, labLen, seed, 00225 seedLen); 00226 } 00227 #endif 00228 00229 return ret; 00230 } 00231 00232 00233 #ifdef CYASSL_SHA384 00234 #define HSHASH_SZ SHA384_DIGEST_SIZE 00235 #else 00236 #define HSHASH_SZ FINISHED_SZ 00237 #endif 00238 00239 00240 int BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) 00241 { 00242 const byte* side; 00243 byte handshake_hash[HSHASH_SZ]; 00244 word32 hashSz = FINISHED_SZ; 00245 00246 #ifndef NO_OLD_TLS 00247 Md5Final(&ssl->hashMd5, handshake_hash); 00248 ShaFinal(&ssl->hashSha, &handshake_hash[MD5_DIGEST_SIZE]); 00249 #endif 00250 00251 if (IsAtLeastTLSv1_2(ssl)) { 00252 #ifndef NO_SHA256 00253 if (ssl->specs.mac_algorithm <= sha256_mac) { 00254 Sha256Final(&ssl->hashSha256, handshake_hash); 00255 hashSz = SHA256_DIGEST_SIZE; 00256 } 00257 #endif 00258 #ifdef CYASSL_SHA384 00259 if (ssl->specs.mac_algorithm == sha384_mac) { 00260 Sha384Final(&ssl->hashSha384, handshake_hash); 00261 hashSz = SHA384_DIGEST_SIZE; 00262 } 00263 #endif 00264 } 00265 00266 if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0) 00267 side = tls_client; 00268 else 00269 side = tls_server; 00270 00271 return PRF((byte*)hashes, TLS_FINISHED_SZ, ssl->arrays->masterSecret, 00272 SECRET_LEN, side, FINISHED_LABEL_SZ, handshake_hash, hashSz, 00273 IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); 00274 } 00275 00276 00277 #ifndef NO_OLD_TLS 00278 00279 ProtocolVersion MakeTLSv1(void) 00280 { 00281 ProtocolVersion pv; 00282 pv.major = SSLv3_MAJOR; 00283 pv.minor = TLSv1_MINOR; 00284 00285 return pv; 00286 } 00287 00288 00289 ProtocolVersion MakeTLSv1_1(void) 00290 { 00291 ProtocolVersion pv; 00292 pv.major = SSLv3_MAJOR; 00293 pv.minor = TLSv1_1_MINOR; 00294 00295 return pv; 00296 } 00297 00298 #endif 00299 00300 00301 ProtocolVersion MakeTLSv1_2(void) 00302 { 00303 ProtocolVersion pv; 00304 pv.major = SSLv3_MAJOR; 00305 pv.minor = TLSv1_2_MINOR; 00306 00307 return pv; 00308 } 00309 00310 00311 static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret"; 00312 static const byte key_label [KEY_LABEL_SZ + 1] = "key expansion"; 00313 00314 00315 int DeriveTlsKeys(CYASSL* ssl) 00316 { 00317 int ret; 00318 int length = 2 * ssl->specs.hash_size + 00319 2 * ssl->specs.key_size + 00320 2 * ssl->specs.iv_size; 00321 byte seed[SEED_LEN]; 00322 byte key_data[MAX_PRF_DIG]; 00323 00324 XMEMCPY(seed, ssl->arrays->serverRandom, RAN_LEN); 00325 XMEMCPY(&seed[RAN_LEN], ssl->arrays->clientRandom, RAN_LEN); 00326 00327 ret = PRF(key_data, length, ssl->arrays->masterSecret, SECRET_LEN, 00328 key_label, KEY_LABEL_SZ, seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), 00329 ssl->specs.mac_algorithm); 00330 if (ret != 0) 00331 return ret; 00332 00333 return StoreKeys(ssl, key_data); 00334 } 00335 00336 00337 int MakeTlsMasterSecret(CYASSL* ssl) 00338 { 00339 int ret; 00340 byte seed[SEED_LEN]; 00341 00342 XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN); 00343 XMEMCPY(&seed[RAN_LEN], ssl->arrays->serverRandom, RAN_LEN); 00344 00345 ret = PRF(ssl->arrays->masterSecret, SECRET_LEN, 00346 ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz, 00347 master_label, MASTER_LABEL_SZ, 00348 seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); 00349 if (ret != 0) 00350 return ret; 00351 00352 #ifdef SHOW_SECRETS 00353 { 00354 int i; 00355 printf("master secret: "); 00356 for (i = 0; i < SECRET_LEN; i++) 00357 printf("%02x", ssl->arrays->masterSecret[i]); 00358 printf("\n"); 00359 } 00360 #endif 00361 00362 return DeriveTlsKeys(ssl); 00363 } 00364 00365 00366 /* Used by EAP-TLS and EAP-TTLS to derive keying material from 00367 * the master_secret. */ 00368 int CyaSSL_make_eap_keys(CYASSL* ssl, void* msk, unsigned int len, 00369 const char* label) 00370 { 00371 byte seed[SEED_LEN]; 00372 00373 /* 00374 * As per RFC-5281, the order of the client and server randoms is reversed 00375 * from that used by the TLS protocol to derive keys. 00376 */ 00377 XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN); 00378 XMEMCPY(&seed[RAN_LEN], ssl->arrays->serverRandom, RAN_LEN); 00379 00380 return PRF((byte*)msk, len, 00381 ssl->arrays->masterSecret, SECRET_LEN, 00382 (const byte *)label, (word32)strlen(label), 00383 seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); 00384 00385 } 00386 00387 00388 /*** next for static INLINE s copied internal.c ***/ 00389 00390 /* convert 16 bit integer to opaque */ 00391 static INLINE void c16toa(word16 u16, byte* c) 00392 { 00393 c[0] = (u16 >> 8) & 0xff; 00394 c[1] = u16 & 0xff; 00395 } 00396 00397 #ifdef HAVE_TLS_EXTENSIONS 00398 /* convert opaque to 16 bit integer */ 00399 static INLINE void ato16(const byte* c, word16* u16) 00400 { 00401 *u16 = (c[0] << 8) | (c[1]); 00402 } 00403 00404 #ifdef HAVE_SNI 00405 /* convert a 24 bit integer into a 32 bit one */ 00406 static INLINE void c24to32(const word24 u24, word32* u32) 00407 { 00408 *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2]; 00409 } 00410 #endif 00411 #endif 00412 00413 /* convert 32 bit integer to opaque */ 00414 static INLINE void c32toa(word32 u32, byte* c) 00415 { 00416 c[0] = (u32 >> 24) & 0xff; 00417 c[1] = (u32 >> 16) & 0xff; 00418 c[2] = (u32 >> 8) & 0xff; 00419 c[3] = u32 & 0xff; 00420 } 00421 00422 00423 static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify) 00424 { 00425 #ifdef CYASSL_DTLS 00426 if (ssl->options.dtls) { 00427 if (verify) 00428 return ssl->keys.dtls_state.curSeq; /* explicit from peer */ 00429 else 00430 return ssl->keys.dtls_sequence_number - 1; /* already incremented */ 00431 } 00432 #endif 00433 if (verify) 00434 return ssl->keys.peer_sequence_number++; 00435 else 00436 return ssl->keys.sequence_number++; 00437 } 00438 00439 00440 #ifdef CYASSL_DTLS 00441 00442 static INLINE word32 GetEpoch(CYASSL* ssl, int verify) 00443 { 00444 if (verify) 00445 return ssl->keys.dtls_state.curEpoch; 00446 else 00447 return ssl->keys.dtls_epoch; 00448 } 00449 00450 #endif /* CYASSL_DTLS */ 00451 00452 00453 /*** end copy ***/ 00454 00455 00456 /* return HMAC digest type in CyaSSL format */ 00457 int CyaSSL_GetHmacType(CYASSL* ssl) 00458 { 00459 if (ssl == NULL) 00460 return BAD_FUNC_ARG; 00461 00462 switch (ssl->specs.mac_algorithm) { 00463 #ifndef NO_MD5 00464 case md5_mac: 00465 { 00466 return MD5; 00467 } 00468 #endif 00469 #ifndef NO_SHA256 00470 case sha256_mac: 00471 { 00472 return SHA256; 00473 } 00474 #endif 00475 #ifdef CYASSL_SHA384 00476 case sha384_mac: 00477 { 00478 return SHA384; 00479 } 00480 00481 #endif 00482 #ifndef NO_SHA 00483 case sha_mac: 00484 { 00485 return SHA; 00486 } 00487 #endif 00488 #ifdef HAVE_BLAKE2 00489 case blake2b_mac: 00490 { 00491 return BLAKE2B_ID; 00492 } 00493 #endif 00494 default: 00495 { 00496 return SSL_FATAL_ERROR; 00497 } 00498 } 00499 } 00500 00501 00502 int CyaSSL_SetTlsHmacInner(CYASSL* ssl, byte* inner, word32 sz, int content, 00503 int verify) 00504 { 00505 if (ssl == NULL || inner == NULL) 00506 return BAD_FUNC_ARG; 00507 00508 XMEMSET(inner, 0, CYASSL_TLS_HMAC_INNER_SZ); 00509 00510 #ifdef CYASSL_DTLS 00511 if (ssl->options.dtls) 00512 c16toa((word16)GetEpoch(ssl, verify), inner); 00513 #endif 00514 c32toa(GetSEQIncrement(ssl, verify), &inner[sizeof(word32)]); 00515 inner[SEQ_SZ] = (byte)content; 00516 inner[SEQ_SZ + ENUM_LEN] = ssl->version.major; 00517 inner[SEQ_SZ + ENUM_LEN + ENUM_LEN] = ssl->version.minor; 00518 c16toa((word16)sz, inner + SEQ_SZ + ENUM_LEN + VERSION_SZ); 00519 00520 return 0; 00521 } 00522 00523 00524 /* TLS type HMAC */ 00525 int TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, 00526 int content, int verify) 00527 { 00528 Hmac hmac; 00529 int ret; 00530 byte myInner[CYASSL_TLS_HMAC_INNER_SZ]; 00531 00532 CyaSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify); 00533 00534 ret = HmacSetKey(&hmac, CyaSSL_GetHmacType(ssl), 00535 CyaSSL_GetMacSecret(ssl, verify), ssl->specs.hash_size); 00536 if (ret != 0) 00537 return ret; 00538 HmacUpdate(&hmac, myInner, sizeof(myInner)); 00539 HmacUpdate(&hmac, in, sz); /* content */ 00540 HmacFinal(&hmac, digest); 00541 00542 return 0; 00543 } 00544 00545 #ifdef HAVE_TLS_EXTENSIONS 00546 00547 #define IS_OFF(semaphore, light) \ 00548 ((semaphore)[(light) / 8] ^ (byte) (0x01 << ((light) % 8))) 00549 00550 #define TURN_ON(semaphore, light) \ 00551 ((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8))) 00552 00553 static int TLSX_Append(TLSX** list, TLSX_Type type) 00554 { 00555 TLSX* extension; 00556 00557 if (list == NULL) /* won't check type since this function is static */ 00558 return BAD_FUNC_ARG; 00559 00560 if ((extension = XMALLOC(sizeof(TLSX), 0, DYNAMIC_TYPE_TLSX)) == NULL) 00561 return MEMORY_E; 00562 00563 extension->type = type; 00564 extension->data = NULL; 00565 extension->resp = 0; 00566 extension->next = *list; 00567 *list = extension; 00568 00569 return 0; 00570 } 00571 00572 #ifndef NO_CYASSL_SERVER 00573 00574 void TLSX_SetResponse(CYASSL* ssl, TLSX_Type type); 00575 00576 void TLSX_SetResponse(CYASSL* ssl, TLSX_Type type) 00577 { 00578 TLSX *ext = TLSX_Find(ssl->extensions, type); 00579 00580 if (ext) 00581 ext->resp = 1; 00582 } 00583 00584 #endif 00585 00586 /* SNI - Server Name Indication */ 00587 00588 #ifdef HAVE_SNI 00589 00590 static void TLSX_SNI_Free(SNI* sni) 00591 { 00592 if (sni) { 00593 switch (sni->type) { 00594 case CYASSL_SNI_HOST_NAME: 00595 XFREE(sni->data.host_name, 0, DYNAMIC_TYPE_TLSX); 00596 break; 00597 } 00598 00599 XFREE(sni, 0, DYNAMIC_TYPE_TLSX); 00600 } 00601 } 00602 00603 static void TLSX_SNI_FreeAll(SNI* list) 00604 { 00605 SNI* sni; 00606 00607 while ((sni = list)) { 00608 list = sni->next; 00609 TLSX_SNI_Free(sni); 00610 } 00611 } 00612 00613 static int TLSX_SNI_Append(SNI** list, byte type, const void* data, word16 size) 00614 { 00615 SNI* sni; 00616 00617 if (list == NULL) 00618 return BAD_FUNC_ARG; 00619 00620 if ((sni = XMALLOC(sizeof(SNI), 0, DYNAMIC_TYPE_TLSX)) == NULL) 00621 return MEMORY_E; 00622 00623 switch (type) { 00624 case CYASSL_SNI_HOST_NAME: { 00625 sni->data.host_name = XMALLOC(size + 1, 0, DYNAMIC_TYPE_TLSX); 00626 00627 if (sni->data.host_name) { 00628 XSTRNCPY(sni->data.host_name, (const char*) data, size); 00629 sni->data.host_name[size] = 0; 00630 } else { 00631 XFREE(sni, 0, DYNAMIC_TYPE_TLSX); 00632 return MEMORY_E; 00633 } 00634 } 00635 break; 00636 00637 default: /* invalid type */ 00638 XFREE(sni, 0, DYNAMIC_TYPE_TLSX); 00639 return BAD_FUNC_ARG; 00640 } 00641 00642 sni->type = type; 00643 sni->next = *list; 00644 00645 #ifndef NO_CYASSL_SERVER 00646 sni->options = 0; 00647 sni->status = CYASSL_SNI_NO_MATCH; 00648 #endif 00649 00650 *list = sni; 00651 00652 return 0; 00653 } 00654 00655 static word16 TLSX_SNI_GetSize(SNI* list) 00656 { 00657 SNI* sni; 00658 word16 length = OPAQUE16_LEN; /* list length */ 00659 00660 while ((sni = list)) { 00661 list = sni->next; 00662 00663 length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */ 00664 00665 switch (sni->type) { 00666 case CYASSL_SNI_HOST_NAME: 00667 length += XSTRLEN((char*) sni->data.host_name); 00668 break; 00669 } 00670 } 00671 00672 return length; 00673 } 00674 00675 static word16 TLSX_SNI_Write(SNI* list, byte* output) 00676 { 00677 SNI* sni; 00678 word16 length = 0; 00679 word16 offset = OPAQUE16_LEN; /* list length offset */ 00680 00681 while ((sni = list)) { 00682 list = sni->next; 00683 00684 output[offset++] = sni->type; /* sni type */ 00685 00686 switch (sni->type) { 00687 case CYASSL_SNI_HOST_NAME: 00688 length = XSTRLEN((char*) sni->data.host_name); 00689 00690 c16toa(length, output + offset); /* sni length */ 00691 offset += OPAQUE16_LEN; 00692 00693 XMEMCPY(output + offset, sni->data.host_name, length); 00694 00695 offset += length; 00696 break; 00697 } 00698 } 00699 00700 c16toa(offset - OPAQUE16_LEN, output); /* writing list length */ 00701 00702 return offset; 00703 } 00704 00705 static SNI* TLSX_SNI_Find(SNI *list, byte type) 00706 { 00707 SNI *sni = list; 00708 00709 while (sni && sni->type != type) 00710 sni = sni->next; 00711 00712 return sni; 00713 } 00714 00715 #ifndef NO_CYASSL_SERVER 00716 static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status) 00717 { 00718 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); 00719 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); 00720 00721 if (sni) { 00722 sni->status = status; 00723 CYASSL_MSG("SNI did match!"); 00724 } 00725 } 00726 00727 byte TLSX_SNI_Status(TLSX* extensions, byte type) 00728 { 00729 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); 00730 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); 00731 00732 if (sni) 00733 return sni->status; 00734 00735 return 0; 00736 } 00737 #endif 00738 00739 static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length, 00740 byte isRequest) 00741 { 00742 #ifndef NO_CYASSL_SERVER 00743 word16 size = 0; 00744 word16 offset = 0; 00745 #endif 00746 00747 TLSX *extension = TLSX_Find(ssl->extensions, SERVER_NAME_INDICATION); 00748 00749 if (!extension) 00750 extension = TLSX_Find(ssl->ctx->extensions, SERVER_NAME_INDICATION); 00751 00752 if (!extension || !extension->data) 00753 return isRequest ? 0 : BUFFER_ERROR; /* not using SNI OR unexpected 00754 SNI response from server. */ 00755 00756 if (!isRequest) 00757 return length ? BUFFER_ERROR : 0; /* SNI response must be empty! 00758 Nothing else to do. */ 00759 00760 #ifndef NO_CYASSL_SERVER 00761 00762 if (OPAQUE16_LEN > length) 00763 return BUFFER_ERROR; 00764 00765 ato16(input, &size); 00766 offset += OPAQUE16_LEN; 00767 00768 /* validating sni list length */ 00769 if (length != OPAQUE16_LEN + size) 00770 return BUFFER_ERROR; 00771 00772 for (size = 0; offset < length; offset += size) { 00773 SNI *sni; 00774 byte type = input[offset++]; 00775 00776 if (offset + OPAQUE16_LEN > length) 00777 return BUFFER_ERROR; 00778 00779 ato16(input + offset, &size); 00780 offset += OPAQUE16_LEN; 00781 00782 if (offset + size > length) 00783 return BUFFER_ERROR; 00784 00785 if (!(sni = TLSX_SNI_Find((SNI *) extension->data, type))) { 00786 continue; /* not using this SNI type */ 00787 } 00788 00789 switch(type) { 00790 case CYASSL_SNI_HOST_NAME: { 00791 byte matched = (XSTRLEN(sni->data.host_name) == size) 00792 && (XSTRNCMP(sni->data.host_name, 00793 (const char *) input + offset, size) == 0); 00794 00795 if (matched || sni->options & CYASSL_SNI_ANSWER_ON_MISMATCH) { 00796 int r = TLSX_UseSNI(&ssl->extensions, 00797 type, input + offset, size); 00798 00799 if (r != SSL_SUCCESS) return r; /* throw error */ 00800 00801 TLSX_SNI_SetStatus(ssl->extensions, type, 00802 matched ? CYASSL_SNI_REAL_MATCH : CYASSL_SNI_FAKE_MATCH); 00803 00804 } else if (!(sni->options & CYASSL_SNI_CONTINUE_ON_MISMATCH)) { 00805 SendAlert(ssl, alert_fatal, unrecognized_name); 00806 00807 return UNKNOWN_SNI_HOST_NAME_E; 00808 } 00809 break; 00810 } 00811 } 00812 00813 TLSX_SetResponse(ssl, SERVER_NAME_INDICATION); 00814 } 00815 00816 #endif 00817 00818 return 0; 00819 } 00820 00821 int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size) 00822 { 00823 TLSX* extension = NULL; 00824 SNI* sni = NULL; 00825 int ret = 0; 00826 00827 if (extensions == NULL || data == NULL) 00828 return BAD_FUNC_ARG; 00829 00830 if ((ret = TLSX_SNI_Append(&sni, type, data, size)) != 0) 00831 return ret; 00832 00833 extension = *extensions; 00834 00835 /* find SNI extension if it already exists. */ 00836 while (extension && extension->type != SERVER_NAME_INDICATION) 00837 extension = extension->next; 00838 00839 /* push new SNI extension if it doesn't exists. */ 00840 if (!extension) { 00841 if ((ret = TLSX_Append(extensions, SERVER_NAME_INDICATION)) != 0) { 00842 TLSX_SNI_Free(sni); 00843 return ret; 00844 } 00845 00846 extension = *extensions; 00847 } 00848 00849 /* push new SNI object to extension data. */ 00850 sni->next = (SNI*) extension->data; 00851 extension->data = (void*) sni; 00852 00853 /* look for another server name of the same type to remove (replacement) */ 00854 do { 00855 if (sni->next && sni->next->type == type) { 00856 SNI *next = sni->next; 00857 00858 sni->next = next->next; 00859 TLSX_SNI_Free(next); 00860 00861 break; 00862 } 00863 } while ((sni = sni->next)); 00864 00865 return SSL_SUCCESS; 00866 } 00867 00868 #ifndef NO_CYASSL_SERVER 00869 word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data) 00870 { 00871 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); 00872 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); 00873 00874 if (sni && sni->status != CYASSL_SNI_NO_MATCH) { 00875 switch (sni->type) { 00876 case CYASSL_SNI_HOST_NAME: 00877 *data = sni->data.host_name; 00878 return XSTRLEN(*data); 00879 } 00880 } 00881 00882 return 0; 00883 } 00884 00885 void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options) 00886 { 00887 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); 00888 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); 00889 00890 if (sni) 00891 sni->options = options; 00892 } 00893 00894 int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, 00895 byte type, byte* sni, word32* inOutSz) 00896 { 00897 word32 offset = 0; 00898 word32 len32 = 0; 00899 word16 len16 = 0; 00900 00901 if (helloSz < RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + CLIENT_HELLO_FIRST) 00902 return INCOMPLETE_DATA; 00903 00904 /* TLS record header */ 00905 if ((enum ContentType) clientHello[offset++] != handshake) 00906 return BUFFER_ERROR; 00907 00908 if (clientHello[offset++] != SSLv3_MAJOR) 00909 return BUFFER_ERROR; 00910 00911 if (clientHello[offset++] < TLSv1_MINOR) 00912 return BUFFER_ERROR; 00913 00914 ato16(clientHello + offset, &len16); 00915 offset += OPAQUE16_LEN; 00916 00917 if (offset + len16 > helloSz) 00918 return INCOMPLETE_DATA; 00919 00920 /* Handshake header */ 00921 if ((enum HandShakeType) clientHello[offset] != client_hello) 00922 return BUFFER_ERROR; 00923 00924 c24to32(clientHello + offset + 1, &len32); 00925 offset += HANDSHAKE_HEADER_SZ; 00926 00927 if (offset + len32 > helloSz) 00928 return BUFFER_ERROR; 00929 00930 /* client hello */ 00931 offset += VERSION_SZ + RAN_LEN; /* version, random */ 00932 00933 if (helloSz < offset + clientHello[offset]) 00934 return BUFFER_ERROR; 00935 00936 offset += ENUM_LEN + clientHello[offset]; /* skip session id */ 00937 00938 /* cypher suites */ 00939 if (helloSz < offset + OPAQUE16_LEN) 00940 return BUFFER_ERROR; 00941 00942 ato16(clientHello + offset, &len16); 00943 offset += OPAQUE16_LEN; 00944 00945 if (helloSz < offset + len16) 00946 return BUFFER_ERROR; 00947 00948 offset += len16; /* skip cypher suites */ 00949 00950 /* compression methods */ 00951 if (helloSz < offset + 1) 00952 return BUFFER_ERROR; 00953 00954 if (helloSz < offset + clientHello[offset]) 00955 return BUFFER_ERROR; 00956 00957 offset += ENUM_LEN + clientHello[offset]; /* skip compression methods */ 00958 00959 /* extensions */ 00960 if (helloSz < offset + OPAQUE16_LEN) 00961 return 0; /* no extensions in client hello. */ 00962 00963 ato16(clientHello + offset, &len16); 00964 offset += OPAQUE16_LEN; 00965 00966 if (helloSz < offset + len16) 00967 return BUFFER_ERROR; 00968 00969 while (len16 > OPAQUE16_LEN + OPAQUE16_LEN) { 00970 word16 extType; 00971 word16 extLen; 00972 00973 ato16(clientHello + offset, &extType); 00974 offset += OPAQUE16_LEN; 00975 00976 ato16(clientHello + offset, &extLen); 00977 offset += OPAQUE16_LEN; 00978 00979 if (helloSz < offset + extLen) 00980 return BUFFER_ERROR; 00981 00982 if (extType != SERVER_NAME_INDICATION) { 00983 offset += extLen; /* skip extension */ 00984 } else { 00985 word16 listLen; 00986 00987 ato16(clientHello + offset, &listLen); 00988 offset += OPAQUE16_LEN; 00989 00990 if (helloSz < offset + listLen) 00991 return BUFFER_ERROR; 00992 00993 while (listLen > ENUM_LEN + OPAQUE16_LEN) { 00994 byte sniType = clientHello[offset++]; 00995 word16 sniLen; 00996 00997 ato16(clientHello + offset, &sniLen); 00998 offset += OPAQUE16_LEN; 00999 01000 if (helloSz < offset + sniLen) 01001 return BUFFER_ERROR; 01002 01003 if (sniType != type) { 01004 offset += sniLen; 01005 listLen -= min(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen); 01006 continue; 01007 } 01008 01009 *inOutSz = min(sniLen, *inOutSz); 01010 XMEMCPY(sni, clientHello + offset, *inOutSz); 01011 01012 return SSL_SUCCESS; 01013 } 01014 } 01015 01016 len16 -= min(2 * OPAQUE16_LEN + extLen, len16); 01017 } 01018 01019 return len16 ? BUFFER_ERROR : SSL_SUCCESS; 01020 } 01021 01022 #endif 01023 01024 #define SNI_FREE_ALL TLSX_SNI_FreeAll 01025 #define SNI_GET_SIZE TLSX_SNI_GetSize 01026 #define SNI_WRITE TLSX_SNI_Write 01027 #define SNI_PARSE TLSX_SNI_Parse 01028 01029 #else 01030 01031 #define SNI_FREE_ALL(list) 01032 #define SNI_GET_SIZE(list) 0 01033 #define SNI_WRITE(a, b) 0 01034 #define SNI_PARSE(a, b, c, d) 0 01035 01036 #endif /* HAVE_SNI */ 01037 01038 #ifdef HAVE_MAX_FRAGMENT 01039 01040 static word16 TLSX_MFL_Write(byte* data, byte* output) 01041 { 01042 output[0] = data[0]; 01043 01044 return ENUM_LEN; 01045 } 01046 01047 static int TLSX_MFL_Parse(CYASSL* ssl, byte* input, word16 length, 01048 byte isRequest) 01049 { 01050 if (length != ENUM_LEN) 01051 return BUFFER_ERROR; 01052 01053 switch (*input) { 01054 case CYASSL_MFL_2_9 : ssl->max_fragment = 512; break; 01055 case CYASSL_MFL_2_10: ssl->max_fragment = 1024; break; 01056 case CYASSL_MFL_2_11: ssl->max_fragment = 2048; break; 01057 case CYASSL_MFL_2_12: ssl->max_fragment = 4096; break; 01058 case CYASSL_MFL_2_13: ssl->max_fragment = 8192; break; 01059 01060 default: 01061 SendAlert(ssl, alert_fatal, illegal_parameter); 01062 01063 return UNKNOWN_MAX_FRAG_LEN_E; 01064 } 01065 01066 #ifndef NO_CYASSL_SERVER 01067 if (isRequest) { 01068 int r = TLSX_UseMaxFragment(&ssl->extensions, *input); 01069 01070 if (r != SSL_SUCCESS) return r; /* throw error */ 01071 01072 TLSX_SetResponse(ssl, MAX_FRAGMENT_LENGTH); 01073 } 01074 #endif 01075 01076 return 0; 01077 } 01078 01079 int TLSX_UseMaxFragment(TLSX** extensions, byte mfl) 01080 { 01081 TLSX* extension = NULL; 01082 byte* data = NULL; 01083 int ret = 0; 01084 01085 if (extensions == NULL) 01086 return BAD_FUNC_ARG; 01087 01088 if (mfl < CYASSL_MFL_2_9 || CYASSL_MFL_2_13 < mfl) 01089 return BAD_FUNC_ARG; 01090 01091 if ((data = XMALLOC(ENUM_LEN, 0, DYNAMIC_TYPE_TLSX)) == NULL) 01092 return MEMORY_E; 01093 01094 data[0] = mfl; 01095 01096 /* push new MFL extension. */ 01097 if ((ret = TLSX_Append(extensions, MAX_FRAGMENT_LENGTH)) != 0) { 01098 XFREE(data, 0, DYNAMIC_TYPE_TLSX); 01099 return ret; 01100 } 01101 01102 /* place new mfl to extension data. */ 01103 extension = *extensions; 01104 extension->data = (void*) data; 01105 01106 /* remove duplicated extensions */ 01107 do { 01108 if (extension->next && extension->next->type == MAX_FRAGMENT_LENGTH) { 01109 TLSX *next = extension->next; 01110 01111 extension->next = next->next; 01112 next->next = NULL; 01113 01114 TLSX_FreeAll(next); 01115 01116 break; 01117 } 01118 } while ((extension = extension->next)); 01119 01120 return SSL_SUCCESS; 01121 } 01122 01123 01124 #define MFL_FREE_ALL(data) XFREE(data, 0, DYNAMIC_TYPE_TLSX) 01125 #define MFL_GET_SIZE(data) ENUM_LEN 01126 #define MFL_WRITE TLSX_MFL_Write 01127 #define MFL_PARSE TLSX_MFL_Parse 01128 01129 #else 01130 01131 #define MFL_FREE_ALL(a) 01132 #define MFL_GET_SIZE(a) 0 01133 #define MFL_WRITE(a, b) 0 01134 #define MFL_PARSE(a, b, c, d) 0 01135 01136 #endif /* HAVE_MAX_FRAGMENT */ 01137 01138 #ifdef HAVE_TRUNCATED_HMAC 01139 01140 int TLSX_UseTruncatedHMAC(TLSX** extensions) 01141 { 01142 int ret = 0; 01143 01144 if (extensions == NULL) 01145 return BAD_FUNC_ARG; 01146 01147 if (!TLSX_Find(*extensions, TRUNCATED_HMAC)) 01148 if ((ret = TLSX_Append(extensions, TRUNCATED_HMAC)) != 0) 01149 return ret; 01150 01151 return SSL_SUCCESS; 01152 } 01153 01154 static int TLSX_THM_Parse(CYASSL* ssl, byte* input, word16 length, 01155 byte isRequest) 01156 { 01157 if (length != 0 || input == NULL) 01158 return BUFFER_ERROR; 01159 01160 #ifndef NO_CYASSL_SERVER 01161 if (isRequest) { 01162 int r = TLSX_UseTruncatedHMAC(&ssl->extensions); 01163 01164 if (r != SSL_SUCCESS) return r; /* throw error */ 01165 01166 TLSX_SetResponse(ssl, TRUNCATED_HMAC); 01167 } 01168 #endif 01169 01170 ssl->truncated_hmac = 1; 01171 01172 return 0; 01173 } 01174 01175 #define THM_PARSE TLSX_THM_Parse 01176 01177 #else 01178 01179 #define THM_PARSE(a, b, c, d) 0 01180 01181 #endif /* HAVE_TRUNCATED_HMAC */ 01182 01183 #ifdef HAVE_SUPPORTED_CURVES 01184 01185 #ifndef HAVE_ECC 01186 #error "Elliptic Curves Extension requires Elliptic Curve Cryptography. \ 01187 Use --enable-ecc in the configure script or define HAVE_ECC." 01188 #endif 01189 01190 static void TLSX_EllipticCurve_FreeAll(EllipticCurve* list) 01191 { 01192 EllipticCurve* curve; 01193 01194 while ((curve = list)) { 01195 list = curve->next; 01196 XFREE(curve, 0, DYNAMIC_TYPE_TLSX); 01197 } 01198 } 01199 01200 static int TLSX_EllipticCurve_Append(EllipticCurve** list, word16 name) 01201 { 01202 EllipticCurve* curve; 01203 01204 if (list == NULL) 01205 return BAD_FUNC_ARG; 01206 01207 if ((curve = XMALLOC(sizeof(EllipticCurve), 0, DYNAMIC_TYPE_TLSX)) == NULL) 01208 return MEMORY_E; 01209 01210 curve->name = name; 01211 curve->next = *list; 01212 01213 *list = curve; 01214 01215 return 0; 01216 } 01217 01218 #ifndef NO_CYASSL_CLIENT 01219 01220 static void TLSX_EllipticCurve_ValidateRequest(CYASSL* ssl, byte* semaphore) 01221 { 01222 int i; 01223 01224 for (i = 0; i < ssl->suites->suiteSz; i+= 2) 01225 if (ssl->suites->suites[i] == ECC_BYTE) 01226 return; 01227 01228 /* No elliptic curve suite found */ 01229 TURN_ON(semaphore, ELLIPTIC_CURVES); 01230 } 01231 01232 static word16 TLSX_EllipticCurve_GetSize(EllipticCurve* list) 01233 { 01234 EllipticCurve* curve; 01235 word16 length = OPAQUE16_LEN; /* list length */ 01236 01237 while ((curve = list)) { 01238 list = curve->next; 01239 length += OPAQUE16_LEN; /* curve length */ 01240 } 01241 01242 return length; 01243 } 01244 01245 static word16 TLSX_EllipticCurve_WriteR(EllipticCurve* curve, byte* output); 01246 static word16 TLSX_EllipticCurve_WriteR(EllipticCurve* curve, byte* output) 01247 { 01248 word16 offset = 0; 01249 01250 if (!curve) 01251 return offset; 01252 01253 offset = TLSX_EllipticCurve_WriteR(curve->next, output); 01254 c16toa(curve->name, output + offset); 01255 01256 return OPAQUE16_LEN + offset; 01257 } 01258 01259 static word16 TLSX_EllipticCurve_Write(EllipticCurve* list, byte* output) 01260 { 01261 word16 length = TLSX_EllipticCurve_WriteR(list, output + OPAQUE16_LEN); 01262 01263 c16toa(length, output); /* writing list length */ 01264 01265 return OPAQUE16_LEN + length; 01266 } 01267 01268 #endif /* NO_CYASSL_CLIENT */ 01269 #ifndef NO_CYASSL_SERVER 01270 01271 static int TLSX_EllipticCurve_Parse(CYASSL* ssl, byte* input, word16 length, 01272 byte isRequest) 01273 { 01274 word16 offset; 01275 word16 name; 01276 int r; 01277 01278 (void) isRequest; /* shut up compiler! */ 01279 01280 if (OPAQUE16_LEN > length || length % OPAQUE16_LEN) 01281 return BUFFER_ERROR; 01282 01283 ato16(input, &offset); 01284 01285 /* validating curve list length */ 01286 if (length != OPAQUE16_LEN + offset) 01287 return BUFFER_ERROR; 01288 01289 while (offset) { 01290 ato16(input + offset, &name); 01291 offset -= OPAQUE16_LEN; 01292 01293 r = TLSX_UseSupportedCurve(&ssl->extensions, name); 01294 01295 if (r != SSL_SUCCESS) return r; /* throw error */ 01296 } 01297 01298 return 0; 01299 } 01300 01301 int TLSX_ValidateEllipticCurves(CYASSL* ssl, byte first, byte second) { 01302 TLSX* extension = (first == ECC_BYTE) 01303 ? TLSX_Find(ssl->extensions, ELLIPTIC_CURVES) 01304 : NULL; 01305 EllipticCurve* curve = NULL; 01306 word32 oid = 0; 01307 word16 octets = 0; /* acording to 'ecc_set_type ecc_sets[];' */ 01308 int sig = 0; /* valitade signature */ 01309 int key = 0; /* validate key */ 01310 01311 if (!extension) 01312 return 1; /* no suite restriction */ 01313 01314 for (curve = extension->data; curve && !(sig && key); curve = curve->next) { 01315 01316 switch (curve->name) { 01317 case CYASSL_ECC_SECP160R1: oid = ECC_160R1; octets = 20; break; 01318 case CYASSL_ECC_SECP192R1: oid = ECC_192R1; octets = 24; break; 01319 case CYASSL_ECC_SECP224R1: oid = ECC_224R1; octets = 28; break; 01320 case CYASSL_ECC_SECP256R1: oid = ECC_256R1; octets = 32; break; 01321 case CYASSL_ECC_SECP384R1: oid = ECC_384R1; octets = 48; break; 01322 case CYASSL_ECC_SECP521R1: oid = ECC_521R1; octets = 66; break; 01323 default: continue; /* unsupported curve */ 01324 } 01325 01326 switch (second) { 01327 #ifndef NO_DSA 01328 /* ECDHE_ECDSA */ 01329 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: 01330 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: 01331 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: 01332 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: 01333 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: 01334 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: 01335 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: 01336 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: 01337 case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: 01338 case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: 01339 sig |= ssl->pkCurveOID == oid; 01340 key |= ssl->eccTempKeySz == octets; 01341 break; 01342 01343 /* ECDH_ECDSA */ 01344 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: 01345 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: 01346 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: 01347 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: 01348 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: 01349 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: 01350 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: 01351 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: 01352 sig |= ssl->pkCurveOID == oid; 01353 key |= ssl->pkCurveOID == oid; 01354 break; 01355 #endif 01356 #ifndef NO_RSA 01357 /* ECDHE_RSA */ 01358 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: 01359 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: 01360 case TLS_ECDHE_RSA_WITH_RC4_128_SHA: 01361 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: 01362 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: 01363 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: 01364 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: 01365 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: 01366 sig = 1; 01367 key |= ssl->eccTempKeySz == octets; 01368 break; 01369 01370 /* ECDH_RSA */ 01371 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: 01372 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: 01373 case TLS_ECDH_RSA_WITH_RC4_128_SHA: 01374 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: 01375 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: 01376 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: 01377 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: 01378 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: 01379 sig = 1; 01380 key |= ssl->pkCurveOID == oid; 01381 break; 01382 #endif 01383 default: 01384 sig = 1; 01385 key = 1; 01386 break; 01387 } 01388 } 01389 01390 return sig && key; 01391 } 01392 01393 #endif /* NO_CYASSL_SERVER */ 01394 01395 int TLSX_UseSupportedCurve(TLSX** extensions, word16 name) 01396 { 01397 TLSX* extension = NULL; 01398 EllipticCurve* curve = NULL; 01399 int ret = 0; 01400 01401 if (extensions == NULL) 01402 return BAD_FUNC_ARG; 01403 01404 if ((ret = TLSX_EllipticCurve_Append(&curve, name)) != 0) 01405 return ret; 01406 01407 extension = *extensions; 01408 01409 /* find EllipticCurve extension if it already exists. */ 01410 while (extension && extension->type != ELLIPTIC_CURVES) 01411 extension = extension->next; 01412 01413 /* push new EllipticCurve extension if it doesn't exists. */ 01414 if (!extension) { 01415 if ((ret = TLSX_Append(extensions, ELLIPTIC_CURVES)) != 0) { 01416 XFREE(curve, 0, DYNAMIC_TYPE_TLSX); 01417 return ret; 01418 } 01419 01420 extension = *extensions; 01421 } 01422 01423 /* push new EllipticCurve object to extension data. */ 01424 curve->next = (EllipticCurve*) extension->data; 01425 extension->data = (void*) curve; 01426 01427 /* look for another curve of the same name to remove (replacement) */ 01428 do { 01429 if (curve->next && curve->next->name == name) { 01430 EllipticCurve *next = curve->next; 01431 01432 curve->next = next->next; 01433 XFREE(next, 0, DYNAMIC_TYPE_TLSX); 01434 01435 break; 01436 } 01437 } while ((curve = curve->next)); 01438 01439 return SSL_SUCCESS; 01440 } 01441 01442 #define EC_FREE_ALL TLSX_EllipticCurve_FreeAll 01443 #define EC_VALIDATE_REQUEST TLSX_EllipticCurve_ValidateRequest 01444 01445 #ifndef NO_CYASSL_CLIENT 01446 #define EC_GET_SIZE TLSX_EllipticCurve_GetSize 01447 #define EC_WRITE TLSX_EllipticCurve_Write 01448 #else 01449 #define EC_GET_SIZE(list) 0 01450 #define EC_WRITE(a, b) 0 01451 #endif 01452 01453 #ifndef NO_CYASSL_SERVER 01454 #define EC_PARSE TLSX_EllipticCurve_Parse 01455 #else 01456 #define EC_PARSE(a, b, c, d) 0 01457 #endif 01458 01459 #else 01460 01461 #define EC_FREE_ALL(list) 01462 #define EC_GET_SIZE(list) 0 01463 #define EC_WRITE(a, b) 0 01464 #define EC_PARSE(a, b, c, d) 0 01465 #define EC_VALIDATE_REQUEST(a, b) 01466 01467 #endif /* HAVE_SUPPORTED_CURVES */ 01468 01469 TLSX* TLSX_Find(TLSX* list, TLSX_Type type) 01470 { 01471 TLSX* extension = list; 01472 01473 while (extension && extension->type != type) 01474 extension = extension->next; 01475 01476 return extension; 01477 } 01478 01479 void TLSX_FreeAll(TLSX* list) 01480 { 01481 TLSX* extension; 01482 01483 while ((extension = list)) { 01484 list = extension->next; 01485 01486 switch (extension->type) { 01487 case SERVER_NAME_INDICATION: 01488 SNI_FREE_ALL((SNI *) extension->data); 01489 break; 01490 01491 case MAX_FRAGMENT_LENGTH: 01492 MFL_FREE_ALL(extension->data); 01493 break; 01494 01495 case TRUNCATED_HMAC: 01496 /* Nothing to do. */ 01497 break; 01498 01499 case ELLIPTIC_CURVES: 01500 EC_FREE_ALL(extension->data); 01501 break; 01502 } 01503 01504 XFREE(extension, 0, DYNAMIC_TYPE_TLSX); 01505 } 01506 } 01507 01508 static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest) 01509 { 01510 TLSX* extension; 01511 word16 length = 0; 01512 01513 while ((extension = list)) { 01514 list = extension->next; 01515 01516 if (!isRequest && !extension->resp) 01517 continue; /* skip! */ 01518 01519 if (IS_OFF(semaphore, extension->type)) { 01520 /* type + data length */ 01521 length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN; 01522 01523 switch (extension->type) { 01524 case SERVER_NAME_INDICATION: 01525 if (isRequest) 01526 length += SNI_GET_SIZE((SNI *) extension->data); 01527 break; 01528 case MAX_FRAGMENT_LENGTH: 01529 length += MFL_GET_SIZE(extension->data); 01530 break; 01531 01532 case TRUNCATED_HMAC: 01533 /* empty extension. */ 01534 break; 01535 01536 case ELLIPTIC_CURVES: 01537 length += EC_GET_SIZE((EllipticCurve *) extension->data); 01538 break; 01539 } 01540 01541 TURN_ON(semaphore, extension->type); 01542 } 01543 } 01544 01545 return length; 01546 } 01547 01548 static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore, 01549 byte isRequest) 01550 { 01551 TLSX* extension; 01552 word16 offset = 0; 01553 word16 length_offset = 0; 01554 01555 while ((extension = list)) { 01556 list = extension->next; 01557 01558 if (!isRequest && !extension->resp) 01559 continue; /* skip! */ 01560 01561 if (IS_OFF(semaphore, extension->type)) { 01562 /* extension type */ 01563 c16toa(extension->type, output + offset); 01564 offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN; 01565 length_offset = offset; 01566 01567 /* extension data should be written internally */ 01568 switch (extension->type) { 01569 case SERVER_NAME_INDICATION: 01570 if (isRequest) 01571 offset += SNI_WRITE((SNI *) extension->data, 01572 output + offset); 01573 break; 01574 01575 case MAX_FRAGMENT_LENGTH: 01576 offset += MFL_WRITE((byte *) extension->data, 01577 output + offset); 01578 break; 01579 01580 case TRUNCATED_HMAC: 01581 /* empty extension. */ 01582 break; 01583 01584 case ELLIPTIC_CURVES: 01585 offset += EC_WRITE((EllipticCurve *) extension->data, 01586 output + offset); 01587 break; 01588 } 01589 01590 /* writing extension data length */ 01591 c16toa(offset - length_offset, 01592 output + length_offset - OPAQUE16_LEN); 01593 01594 TURN_ON(semaphore, extension->type); 01595 } 01596 } 01597 01598 return offset; 01599 } 01600 01601 #ifndef NO_CYASSL_CLIENT 01602 01603 word16 TLSX_GetRequestSize(CYASSL* ssl) 01604 { 01605 word16 length = 0; 01606 01607 if (ssl && IsTLS(ssl)) { 01608 byte semaphore[16] = {0}; 01609 01610 EC_VALIDATE_REQUEST(ssl, semaphore); 01611 01612 if (ssl->extensions) 01613 length += TLSX_GetSize(ssl->extensions, semaphore, 1); 01614 01615 if (ssl->ctx && ssl->ctx->extensions) 01616 length += TLSX_GetSize(ssl->ctx->extensions, semaphore, 1); 01617 01618 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) 01619 length += ssl->suites->hashSigAlgoSz + HELLO_EXT_LEN; 01620 } 01621 01622 if (length) 01623 length += OPAQUE16_LEN; /* for total length storage */ 01624 01625 return length; 01626 } 01627 01628 word16 TLSX_WriteRequest(CYASSL* ssl, byte* output) 01629 { 01630 word16 offset = 0; 01631 01632 if (ssl && IsTLS(ssl) && output) { 01633 byte semaphore[16] = {0}; 01634 01635 offset += OPAQUE16_LEN; /* extensions length */ 01636 01637 EC_VALIDATE_REQUEST(ssl, semaphore); 01638 01639 if (ssl->extensions) 01640 offset += TLSX_Write(ssl->extensions, output + offset, 01641 semaphore, 1); 01642 01643 if (ssl->ctx && ssl->ctx->extensions) 01644 offset += TLSX_Write(ssl->ctx->extensions, output + offset, 01645 semaphore, 1); 01646 01647 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) 01648 { 01649 int i; 01650 /* extension type */ 01651 c16toa(HELLO_EXT_SIG_ALGO, output + offset); 01652 offset += HELLO_EXT_TYPE_SZ; 01653 01654 /* extension data length */ 01655 c16toa(OPAQUE16_LEN + ssl->suites->hashSigAlgoSz, output + offset); 01656 offset += OPAQUE16_LEN; 01657 01658 /* sig algos length */ 01659 c16toa(ssl->suites->hashSigAlgoSz, output + offset); 01660 offset += OPAQUE16_LEN; 01661 01662 /* sig algos */ 01663 for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, offset++) 01664 output[offset] = ssl->suites->hashSigAlgo[i]; 01665 } 01666 01667 if (offset > OPAQUE16_LEN) 01668 c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ 01669 } 01670 01671 return offset; 01672 } 01673 01674 #endif /* NO_CYASSL_CLIENT */ 01675 01676 #ifndef NO_CYASSL_SERVER 01677 01678 word16 TLSX_GetResponseSize(CYASSL* ssl) 01679 { 01680 word16 length = 0; 01681 byte semaphore[16] = {0}; 01682 01683 if (ssl && IsTLS(ssl)) 01684 length += TLSX_GetSize(ssl->extensions, semaphore, 0); 01685 01686 /* All the response data is set at the ssl object only, so no ctx here. */ 01687 01688 if (length) 01689 length += OPAQUE16_LEN; /* for total length storage */ 01690 01691 return length; 01692 } 01693 01694 word16 TLSX_WriteResponse(CYASSL *ssl, byte* output) 01695 { 01696 word16 offset = 0; 01697 01698 if (ssl && IsTLS(ssl) && output) { 01699 byte semaphore[16] = {0}; 01700 01701 offset += OPAQUE16_LEN; /* extensions length */ 01702 01703 offset += TLSX_Write(ssl->extensions, output + offset, semaphore, 0); 01704 01705 if (offset > OPAQUE16_LEN) 01706 c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ 01707 } 01708 01709 return offset; 01710 } 01711 01712 #endif /* NO_CYASSL_SERVER */ 01713 01714 int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest, 01715 Suites *suites) 01716 { 01717 int ret = 0; 01718 word16 offset = 0; 01719 01720 if (!ssl || !input || !suites) 01721 return BAD_FUNC_ARG; 01722 01723 while (ret == 0 && offset < length) { 01724 word16 type; 01725 word16 size; 01726 01727 if (length - offset < HELLO_EXT_TYPE_SZ + OPAQUE16_LEN) 01728 return BUFFER_ERROR; 01729 01730 ato16(input + offset, &type); 01731 offset += HELLO_EXT_TYPE_SZ; 01732 01733 ato16(input + offset, &size); 01734 offset += OPAQUE16_LEN; 01735 01736 if (offset + size > length) 01737 return BUFFER_ERROR; 01738 01739 switch (type) { 01740 case SERVER_NAME_INDICATION: 01741 CYASSL_MSG("SNI extension received"); 01742 01743 ret = SNI_PARSE(ssl, input + offset, size, isRequest); 01744 break; 01745 01746 case MAX_FRAGMENT_LENGTH: 01747 CYASSL_MSG("Max Fragment Length extension received"); 01748 01749 ret = MFL_PARSE(ssl, input + offset, size, isRequest); 01750 break; 01751 01752 case TRUNCATED_HMAC: 01753 CYASSL_MSG("Truncated HMAC extension received"); 01754 01755 ret = THM_PARSE(ssl, input + offset, size, isRequest); 01756 break; 01757 01758 case ELLIPTIC_CURVES: 01759 CYASSL_MSG("Elliptic Curves extension received"); 01760 01761 ret = EC_PARSE(ssl, input + offset, size, isRequest); 01762 break; 01763 01764 case HELLO_EXT_SIG_ALGO: 01765 if (isRequest) { 01766 /* do not mess with offset inside the switch! */ 01767 if (IsAtLeastTLSv1_2(ssl)) { 01768 ato16(input + offset, &suites->hashSigAlgoSz); 01769 01770 if (suites->hashSigAlgoSz > size - OPAQUE16_LEN) 01771 return BUFFER_ERROR; 01772 01773 XMEMCPY(suites->hashSigAlgo, 01774 input + offset + OPAQUE16_LEN, 01775 min(suites->hashSigAlgoSz, 01776 HELLO_EXT_SIGALGO_MAX)); 01777 } 01778 } else { 01779 CYASSL_MSG("Servers MUST NOT send SIG ALGO extension."); 01780 } 01781 01782 break; 01783 } 01784 01785 /* offset should be updated here! */ 01786 offset += size; 01787 } 01788 01789 return ret; 01790 } 01791 01792 /* undefining semaphore macros */ 01793 #undef IS_OFF 01794 #undef TURN_ON 01795 01796 #elif defined(HAVE_SNI) \ 01797 || defined(HAVE_MAX_FRAGMENT) \ 01798 || defined(HAVE_TRUNCATED_HMAC) \ 01799 || defined(HAVE_SUPPORTED_CURVES) 01800 01801 #error "Using TLS extensions requires HAVE_TLS_EXTENSIONS to be defined." 01802 01803 #endif /* HAVE_TLS_EXTENSIONS */ 01804 01805 01806 #ifndef NO_CYASSL_CLIENT 01807 01808 #ifndef NO_OLD_TLS 01809 01810 CYASSL_METHOD* CyaTLSv1_client_method(void) 01811 { 01812 CYASSL_METHOD* method = 01813 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01814 DYNAMIC_TYPE_METHOD); 01815 if (method) 01816 InitSSL_Method(method, MakeTLSv1()); 01817 return method; 01818 } 01819 01820 01821 CYASSL_METHOD* CyaTLSv1_1_client_method(void) 01822 { 01823 CYASSL_METHOD* method = 01824 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01825 DYNAMIC_TYPE_METHOD); 01826 if (method) 01827 InitSSL_Method(method, MakeTLSv1_1()); 01828 return method; 01829 } 01830 01831 #endif /* !NO_OLD_TLS */ 01832 01833 #ifndef NO_SHA256 /* can't use without SHA256 */ 01834 01835 CYASSL_METHOD* CyaTLSv1_2_client_method(void) 01836 { 01837 CYASSL_METHOD* method = 01838 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01839 DYNAMIC_TYPE_METHOD); 01840 if (method) 01841 InitSSL_Method(method, MakeTLSv1_2()); 01842 return method; 01843 } 01844 01845 #endif 01846 01847 01848 CYASSL_METHOD* CyaSSLv23_client_method(void) 01849 { 01850 CYASSL_METHOD* method = 01851 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01852 DYNAMIC_TYPE_METHOD); 01853 if (method) { 01854 #ifndef NO_SHA256 /* 1.2 requires SHA256 */ 01855 InitSSL_Method(method, MakeTLSv1_2()); 01856 #else 01857 InitSSL_Method(method, MakeTLSv1_1()); 01858 #endif 01859 #ifndef NO_OLD_TLS 01860 method->downgrade = 1; 01861 #endif 01862 } 01863 return method; 01864 } 01865 01866 01867 #endif /* NO_CYASSL_CLIENT */ 01868 01869 01870 01871 #ifndef NO_CYASSL_SERVER 01872 01873 #ifndef NO_OLD_TLS 01874 01875 CYASSL_METHOD* CyaTLSv1_server_method(void) 01876 { 01877 CYASSL_METHOD* method = 01878 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01879 DYNAMIC_TYPE_METHOD); 01880 if (method) { 01881 InitSSL_Method(method, MakeTLSv1()); 01882 method->side = CYASSL_SERVER_END; 01883 } 01884 return method; 01885 } 01886 01887 01888 CYASSL_METHOD* CyaTLSv1_1_server_method(void) 01889 { 01890 CYASSL_METHOD* method = 01891 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01892 DYNAMIC_TYPE_METHOD); 01893 if (method) { 01894 InitSSL_Method(method, MakeTLSv1_1()); 01895 method->side = CYASSL_SERVER_END; 01896 } 01897 return method; 01898 } 01899 01900 #endif /* !NO_OLD_TLS */ 01901 01902 #ifndef NO_SHA256 /* can't use without SHA256 */ 01903 01904 CYASSL_METHOD* CyaTLSv1_2_server_method(void) 01905 { 01906 CYASSL_METHOD* method = 01907 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01908 DYNAMIC_TYPE_METHOD); 01909 if (method) { 01910 InitSSL_Method(method, MakeTLSv1_2()); 01911 method->side = CYASSL_SERVER_END; 01912 } 01913 return method; 01914 } 01915 01916 #endif 01917 01918 01919 CYASSL_METHOD* CyaSSLv23_server_method(void) 01920 { 01921 CYASSL_METHOD* method = 01922 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01923 DYNAMIC_TYPE_METHOD); 01924 if (method) { 01925 #ifndef NO_SHA256 /* 1.2 requires SHA256 */ 01926 InitSSL_Method(method, MakeTLSv1_2()); 01927 #else 01928 InitSSL_Method(method, MakeTLSv1_1()); 01929 #endif 01930 method->side = CYASSL_SERVER_END; 01931 #ifndef NO_OLD_TLS 01932 method->downgrade = 1; 01933 #endif /* !NO_OLD_TLS */ 01934 } 01935 return method; 01936 } 01937 01938 01939 01940 #endif /* NO_CYASSL_SERVER */ 01941 #endif /* NO_TLS */ 01942
Generated on Tue Jul 12 2022 20:12:52 by
