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.
Dependents: HTTPClient-SSL HTTPClient HTTPClient-SSL http_access ... more
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 Wed Jul 13 2022 02:18:40 by
 1.7.2
 1.7.2 
    