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