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-SSL HTTPClient-SSL HTTPClient-SSL
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 P_HASH_MAX_SIZE SHA384_DIGEST_SIZE 00050 #else 00051 #define P_HASH_MAX_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 = P_HASH_MAX_SIZE; 00059 word32 times; 00060 word32 lastLen; 00061 word32 lastTime; 00062 word32 i; 00063 word32 idx = 0; 00064 int ret = 0; 00065 #ifdef CYASSL_SMALL_STACK 00066 byte* previous; 00067 byte* current; 00068 Hmac* hmac; 00069 #else 00070 byte previous[P_HASH_MAX_SIZE]; /* max size */ 00071 byte current[P_HASH_MAX_SIZE]; /* max size */ 00072 Hmac hmac[1]; 00073 #endif 00074 00075 #ifdef CYASSL_SMALL_STACK 00076 previous = (byte*)XMALLOC(P_HASH_MAX_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00077 current = (byte*)XMALLOC(P_HASH_MAX_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00078 hmac = (Hmac*)XMALLOC(sizeof(Hmac), NULL, DYNAMIC_TYPE_TMP_BUFFER); 00079 00080 if (previous == NULL || current == NULL || hmac == NULL) { 00081 if (previous) XFREE(previous, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00082 if (current) XFREE(current, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00083 if (hmac) XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00084 00085 return MEMORY_E; 00086 } 00087 #endif 00088 00089 switch (hash) { 00090 #ifndef NO_MD5 00091 case md5_mac: 00092 hash = MD5; 00093 len = MD5_DIGEST_SIZE; 00094 break; 00095 #endif 00096 00097 #ifndef NO_SHA256 00098 case sha256_mac: 00099 hash = SHA256; 00100 len = SHA256_DIGEST_SIZE; 00101 break; 00102 #endif 00103 00104 #ifdef CYASSL_SHA384 00105 case sha384_mac: 00106 hash = SHA384; 00107 len = SHA384_DIGEST_SIZE; 00108 break; 00109 #endif 00110 00111 #ifndef NO_SHA 00112 case sha_mac: 00113 default: 00114 hash = SHA; 00115 len = SHA_DIGEST_SIZE; 00116 break; 00117 #endif 00118 } 00119 00120 times = resLen / len; 00121 lastLen = resLen % len; 00122 00123 if (lastLen) 00124 times += 1; 00125 00126 lastTime = times - 1; 00127 00128 if ((ret = HmacSetKey(hmac, hash, secret, secLen)) == 0) { 00129 if ((ret = HmacUpdate(hmac, seed, seedLen)) == 0) { /* A0 = seed */ 00130 if ((ret = HmacFinal(hmac, previous)) == 0) { /* A1 */ 00131 for (i = 0; i < times; i++) { 00132 ret = HmacUpdate(hmac, previous, len); 00133 if (ret != 0) 00134 break; 00135 ret = HmacUpdate(hmac, seed, seedLen); 00136 if (ret != 0) 00137 break; 00138 ret = HmacFinal(hmac, current); 00139 if (ret != 0) 00140 break; 00141 00142 if ((i == lastTime) && lastLen) 00143 XMEMCPY(&result[idx], current, 00144 min(lastLen, P_HASH_MAX_SIZE)); 00145 else { 00146 XMEMCPY(&result[idx], current, len); 00147 idx += len; 00148 ret = HmacUpdate(hmac, previous, len); 00149 if (ret != 0) 00150 break; 00151 ret = HmacFinal(hmac, previous); 00152 if (ret != 0) 00153 break; 00154 } 00155 } 00156 } 00157 } 00158 } 00159 00160 XMEMSET(previous, 0, P_HASH_MAX_SIZE); 00161 XMEMSET(current, 0, P_HASH_MAX_SIZE); 00162 XMEMSET(hmac, 0, sizeof(Hmac)); 00163 00164 #ifdef CYASSL_SMALL_STACK 00165 XFREE(previous, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00166 XFREE(current, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00167 XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00168 #endif 00169 00170 return ret; 00171 } 00172 00173 #undef P_HASH_MAX_SIZE 00174 00175 00176 #ifndef NO_OLD_TLS 00177 00178 /* calculate XOR for TLSv1 PRF */ 00179 static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha) 00180 { 00181 word32 i; 00182 00183 for (i = 0; i < digLen; i++) 00184 digest[i] = md5[i] ^ sha[i]; 00185 } 00186 00187 00188 /* compute TLSv1 PRF (pseudo random function using HMAC) */ 00189 static int doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen, 00190 const byte* label, word32 labLen, const byte* seed, 00191 word32 seedLen) 00192 { 00193 int ret = 0; 00194 word32 half = (secLen + 1) / 2; 00195 00196 #ifdef CYASSL_SMALL_STACK 00197 byte* md5_half; 00198 byte* sha_half; 00199 byte* labelSeed; 00200 byte* md5_result; 00201 byte* sha_result; 00202 #else 00203 byte md5_half[MAX_PRF_HALF]; /* half is real size */ 00204 byte sha_half[MAX_PRF_HALF]; /* half is real size */ 00205 byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */ 00206 byte md5_result[MAX_PRF_DIG]; /* digLen is real size */ 00207 byte sha_result[MAX_PRF_DIG]; /* digLen is real size */ 00208 #endif 00209 00210 if (half > MAX_PRF_HALF) 00211 return BUFFER_E; 00212 if (labLen + seedLen > MAX_PRF_LABSEED) 00213 return BUFFER_E; 00214 if (digLen > MAX_PRF_DIG) 00215 return BUFFER_E; 00216 00217 #ifdef CYASSL_SMALL_STACK 00218 md5_half = (byte*)XMALLOC(MAX_PRF_HALF, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00219 sha_half = (byte*)XMALLOC(MAX_PRF_HALF, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00220 labelSeed = (byte*)XMALLOC(MAX_PRF_LABSEED, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00221 md5_result = (byte*)XMALLOC(MAX_PRF_DIG, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00222 sha_result = (byte*)XMALLOC(MAX_PRF_DIG, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00223 00224 if (md5_half == NULL || sha_half == NULL || labelSeed == NULL || 00225 md5_result == NULL || sha_result == NULL) { 00226 if (md5_half) XFREE(md5_half, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00227 if (sha_half) XFREE(sha_half, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00228 if (labelSeed) XFREE(labelSeed, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00229 if (md5_result) XFREE(md5_result, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00230 if (sha_result) XFREE(sha_result, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00231 00232 return MEMORY_E; 00233 } 00234 #endif 00235 00236 XMEMSET(md5_result, 0, digLen); 00237 XMEMSET(sha_result, 0, digLen); 00238 00239 XMEMCPY(md5_half, secret, half); 00240 XMEMCPY(sha_half, secret + half - secLen % 2, half); 00241 00242 XMEMCPY(labelSeed, label, labLen); 00243 XMEMCPY(labelSeed + labLen, seed, seedLen); 00244 00245 if ((ret = p_hash(md5_result, digLen, md5_half, half, labelSeed, 00246 labLen + seedLen, md5_mac)) == 0) { 00247 if ((ret = p_hash(sha_result, digLen, sha_half, half, labelSeed, 00248 labLen + seedLen, sha_mac)) == 0) { 00249 get_xor(digest, digLen, md5_result, sha_result); 00250 } 00251 } 00252 00253 #ifdef CYASSL_SMALL_STACK 00254 XFREE(md5_half, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00255 XFREE(sha_half, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00256 XFREE(labelSeed, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00257 XFREE(md5_result, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00258 XFREE(sha_result, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00259 #endif 00260 00261 return ret; 00262 } 00263 00264 #endif 00265 00266 00267 /* Wrapper to call straight thru to p_hash in TSL 1.2 cases to remove stack 00268 use */ 00269 static int PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen, 00270 const byte* label, word32 labLen, const byte* seed, word32 seedLen, 00271 int useAtLeastSha256, int hash_type) 00272 { 00273 int ret = 0; 00274 00275 if (useAtLeastSha256) { 00276 #ifdef CYASSL_SMALL_STACK 00277 byte* labelSeed; 00278 #else 00279 byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */ 00280 #endif 00281 00282 if (labLen + seedLen > MAX_PRF_LABSEED) 00283 return BUFFER_E; 00284 00285 #ifdef CYASSL_SMALL_STACK 00286 labelSeed = (byte*)XMALLOC(MAX_PRF_LABSEED, NULL, 00287 DYNAMIC_TYPE_TMP_BUFFER); 00288 if (labelSeed == NULL) 00289 return MEMORY_E; 00290 #endif 00291 00292 XMEMCPY(labelSeed, label, labLen); 00293 XMEMCPY(labelSeed + labLen, seed, seedLen); 00294 00295 /* If a cipher suite wants an algorithm better than sha256, it 00296 * should use better. */ 00297 if (hash_type < sha256_mac) 00298 hash_type = sha256_mac; 00299 ret = p_hash(digest, digLen, secret, secLen, labelSeed, 00300 labLen + seedLen, hash_type); 00301 00302 #ifdef CYASSL_SMALL_STACK 00303 XFREE(labelSeed, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00304 #endif 00305 } 00306 #ifndef NO_OLD_TLS 00307 else { 00308 ret = doPRF(digest, digLen, secret, secLen, label, labLen, seed, 00309 seedLen); 00310 } 00311 #endif 00312 00313 return ret; 00314 } 00315 00316 00317 #ifdef CYASSL_SHA384 00318 #define HSHASH_SZ SHA384_DIGEST_SIZE 00319 #else 00320 #define HSHASH_SZ FINISHED_SZ 00321 #endif 00322 00323 00324 int BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) 00325 { 00326 const byte* side; 00327 byte handshake_hash[HSHASH_SZ]; 00328 word32 hashSz = FINISHED_SZ; 00329 00330 #ifndef NO_OLD_TLS 00331 Md5Final(&ssl->hashMd5, handshake_hash); 00332 ShaFinal(&ssl->hashSha, &handshake_hash[MD5_DIGEST_SIZE]); 00333 #endif 00334 00335 if (IsAtLeastTLSv1_2(ssl)) { 00336 #ifndef NO_SHA256 00337 if (ssl->specs.mac_algorithm <= sha256_mac) { 00338 int ret = Sha256Final(&ssl->hashSha256, handshake_hash); 00339 00340 if (ret != 0) 00341 return ret; 00342 00343 hashSz = SHA256_DIGEST_SIZE; 00344 } 00345 #endif 00346 #ifdef CYASSL_SHA384 00347 if (ssl->specs.mac_algorithm == sha384_mac) { 00348 int ret = Sha384Final(&ssl->hashSha384, handshake_hash); 00349 00350 if (ret != 0) 00351 return ret; 00352 00353 hashSz = SHA384_DIGEST_SIZE; 00354 } 00355 #endif 00356 } 00357 00358 if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0) 00359 side = tls_client; 00360 else 00361 side = tls_server; 00362 00363 return PRF((byte*)hashes, TLS_FINISHED_SZ, ssl->arrays->masterSecret, 00364 SECRET_LEN, side, FINISHED_LABEL_SZ, handshake_hash, hashSz, 00365 IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); 00366 } 00367 00368 00369 #ifndef NO_OLD_TLS 00370 00371 ProtocolVersion MakeTLSv1(void) 00372 { 00373 ProtocolVersion pv; 00374 pv.major = SSLv3_MAJOR; 00375 pv.minor = TLSv1_MINOR; 00376 00377 return pv; 00378 } 00379 00380 00381 ProtocolVersion MakeTLSv1_1(void) 00382 { 00383 ProtocolVersion pv; 00384 pv.major = SSLv3_MAJOR; 00385 pv.minor = TLSv1_1_MINOR; 00386 00387 return pv; 00388 } 00389 00390 #endif 00391 00392 00393 ProtocolVersion MakeTLSv1_2(void) 00394 { 00395 ProtocolVersion pv; 00396 pv.major = SSLv3_MAJOR; 00397 pv.minor = TLSv1_2_MINOR; 00398 00399 return pv; 00400 } 00401 00402 00403 static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret"; 00404 static const byte key_label [KEY_LABEL_SZ + 1] = "key expansion"; 00405 00406 00407 /* External facing wrapper so user can call as well, 0 on success */ 00408 int CyaSSL_DeriveTlsKeys(byte* key_data, word32 keyLen, 00409 const byte* ms, word32 msLen, 00410 const byte* sr, const byte* cr, 00411 int tls1_2, int hash_type) 00412 { 00413 byte seed[SEED_LEN]; 00414 00415 XMEMCPY(seed, sr, RAN_LEN); 00416 XMEMCPY(seed + RAN_LEN, cr, RAN_LEN); 00417 00418 return PRF(key_data, keyLen, ms, msLen, key_label, KEY_LABEL_SZ, 00419 seed, SEED_LEN, tls1_2, hash_type); 00420 } 00421 00422 00423 int DeriveTlsKeys(CYASSL* ssl) 00424 { 00425 int ret; 00426 int length = 2 * ssl->specs.hash_size + 00427 2 * ssl->specs.key_size + 00428 2 * ssl->specs.iv_size; 00429 #ifdef CYASSL_SMALL_STACK 00430 byte* key_data; 00431 #else 00432 byte key_data[MAX_PRF_DIG]; 00433 #endif 00434 00435 #ifdef CYASSL_SMALL_STACK 00436 key_data = (byte*)XMALLOC(MAX_PRF_DIG, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00437 if (key_data == NULL) { 00438 return MEMORY_E; 00439 } 00440 #endif 00441 00442 ret = CyaSSL_DeriveTlsKeys(key_data, length, 00443 ssl->arrays->masterSecret, SECRET_LEN, 00444 ssl->arrays->serverRandom, ssl->arrays->clientRandom, 00445 IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); 00446 if (ret == 0) 00447 ret = StoreKeys(ssl, key_data); 00448 00449 #ifdef CYASSL_SMALL_STACK 00450 XFREE(key_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00451 #endif 00452 00453 return ret; 00454 } 00455 00456 00457 /* External facing wrapper so user can call as well, 0 on success */ 00458 int CyaSSL_MakeTlsMasterSecret(byte* ms, word32 msLen, 00459 const byte* pms, word32 pmsLen, 00460 const byte* cr, const byte* sr, 00461 int tls1_2, int hash_type) 00462 { 00463 byte seed[SEED_LEN]; 00464 00465 XMEMCPY(seed, cr, RAN_LEN); 00466 XMEMCPY(seed + RAN_LEN, sr, RAN_LEN); 00467 00468 return PRF(ms, msLen, pms, pmsLen, master_label, MASTER_LABEL_SZ, 00469 seed, SEED_LEN, tls1_2, hash_type); 00470 } 00471 00472 00473 int MakeTlsMasterSecret(CYASSL* ssl) 00474 { 00475 int ret; 00476 00477 ret = CyaSSL_MakeTlsMasterSecret(ssl->arrays->masterSecret, SECRET_LEN, 00478 ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz, 00479 ssl->arrays->clientRandom, ssl->arrays->serverRandom, 00480 IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); 00481 00482 if (ret == 0) { 00483 #ifdef SHOW_SECRETS 00484 int i; 00485 00486 printf("master secret: "); 00487 for (i = 0; i < SECRET_LEN; i++) 00488 printf("%02x", ssl->arrays->masterSecret[i]); 00489 printf("\n"); 00490 #endif 00491 00492 ret = DeriveTlsKeys(ssl); 00493 } 00494 00495 return ret; 00496 } 00497 00498 00499 /* Used by EAP-TLS and EAP-TTLS to derive keying material from 00500 * the master_secret. */ 00501 int CyaSSL_make_eap_keys(CYASSL* ssl, void* msk, unsigned int len, 00502 const char* label) 00503 { 00504 int ret; 00505 #ifdef CYASSL_SMALL_STACK 00506 byte* seed; 00507 #else 00508 byte seed[SEED_LEN]; 00509 #endif 00510 00511 #ifdef CYASSL_SMALL_STACK 00512 seed = (byte*)XMALLOC(SEED_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00513 if (seed == NULL) 00514 return MEMORY_E; 00515 #endif 00516 00517 /* 00518 * As per RFC-5281, the order of the client and server randoms is reversed 00519 * from that used by the TLS protocol to derive keys. 00520 */ 00521 XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN); 00522 XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN); 00523 00524 ret = PRF((byte*)msk, len, ssl->arrays->masterSecret, SECRET_LEN, 00525 (const byte *)label, (word32)strlen(label), seed, SEED_LEN, 00526 IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); 00527 00528 #ifdef CYASSL_SMALL_STACK 00529 XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00530 #endif 00531 00532 return ret; 00533 } 00534 00535 00536 /*** next for static INLINE s copied internal.c ***/ 00537 00538 /* convert 16 bit integer to opaque */ 00539 static INLINE void c16toa(word16 u16, byte* c) 00540 { 00541 c[0] = (u16 >> 8) & 0xff; 00542 c[1] = u16 & 0xff; 00543 } 00544 00545 #ifdef HAVE_TLS_EXTENSIONS 00546 /* convert opaque to 16 bit integer */ 00547 static INLINE void ato16(const byte* c, word16* u16) 00548 { 00549 *u16 = (c[0] << 8) | (c[1]); 00550 } 00551 00552 #ifdef HAVE_SNI 00553 /* convert a 24 bit integer into a 32 bit one */ 00554 static INLINE void c24to32(const word24 u24, word32* u32) 00555 { 00556 *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2]; 00557 } 00558 #endif 00559 #endif 00560 00561 /* convert 32 bit integer to opaque */ 00562 static INLINE void c32toa(word32 u32, byte* c) 00563 { 00564 c[0] = (u32 >> 24) & 0xff; 00565 c[1] = (u32 >> 16) & 0xff; 00566 c[2] = (u32 >> 8) & 0xff; 00567 c[3] = u32 & 0xff; 00568 } 00569 00570 00571 static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify) 00572 { 00573 #ifdef CYASSL_DTLS 00574 if (ssl->options.dtls) { 00575 if (verify) 00576 return ssl->keys.dtls_state.curSeq; /* explicit from peer */ 00577 else 00578 return ssl->keys.dtls_sequence_number - 1; /* already incremented */ 00579 } 00580 #endif 00581 if (verify) 00582 return ssl->keys.peer_sequence_number++; 00583 else 00584 return ssl->keys.sequence_number++; 00585 } 00586 00587 00588 #ifdef CYASSL_DTLS 00589 00590 static INLINE word32 GetEpoch(CYASSL* ssl, int verify) 00591 { 00592 if (verify) 00593 return ssl->keys.dtls_state.curEpoch; 00594 else 00595 return ssl->keys.dtls_epoch; 00596 } 00597 00598 #endif /* CYASSL_DTLS */ 00599 00600 00601 /*** end copy ***/ 00602 00603 00604 /* return HMAC digest type in CyaSSL format */ 00605 int CyaSSL_GetHmacType(CYASSL* ssl) 00606 { 00607 if (ssl == NULL) 00608 return BAD_FUNC_ARG; 00609 00610 switch (ssl->specs.mac_algorithm) { 00611 #ifndef NO_MD5 00612 case md5_mac: 00613 { 00614 return MD5; 00615 } 00616 #endif 00617 #ifndef NO_SHA256 00618 case sha256_mac: 00619 { 00620 return SHA256; 00621 } 00622 #endif 00623 #ifdef CYASSL_SHA384 00624 case sha384_mac: 00625 { 00626 return SHA384; 00627 } 00628 00629 #endif 00630 #ifndef NO_SHA 00631 case sha_mac: 00632 { 00633 return SHA; 00634 } 00635 #endif 00636 #ifdef HAVE_BLAKE2 00637 case blake2b_mac: 00638 { 00639 return BLAKE2B_ID; 00640 } 00641 #endif 00642 default: 00643 { 00644 return SSL_FATAL_ERROR; 00645 } 00646 } 00647 } 00648 00649 00650 int CyaSSL_SetTlsHmacInner(CYASSL* ssl, byte* inner, word32 sz, int content, 00651 int verify) 00652 { 00653 if (ssl == NULL || inner == NULL) 00654 return BAD_FUNC_ARG; 00655 00656 XMEMSET(inner, 0, CYASSL_TLS_HMAC_INNER_SZ); 00657 00658 #ifdef CYASSL_DTLS 00659 if (ssl->options.dtls) 00660 c16toa((word16)GetEpoch(ssl, verify), inner); 00661 #endif 00662 c32toa(GetSEQIncrement(ssl, verify), &inner[sizeof(word32)]); 00663 inner[SEQ_SZ] = (byte)content; 00664 inner[SEQ_SZ + ENUM_LEN] = ssl->version.major; 00665 inner[SEQ_SZ + ENUM_LEN + ENUM_LEN] = ssl->version.minor; 00666 c16toa((word16)sz, inner + SEQ_SZ + ENUM_LEN + VERSION_SZ); 00667 00668 return 0; 00669 } 00670 00671 00672 /* TLS type HMAC */ 00673 int TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, 00674 int content, int verify) 00675 { 00676 Hmac hmac; 00677 int ret; 00678 byte myInner[CYASSL_TLS_HMAC_INNER_SZ]; 00679 00680 if (ssl == NULL) 00681 return BAD_FUNC_ARG; 00682 00683 #ifdef HAVE_FUZZER 00684 if (ssl->fuzzerCb) 00685 ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx); 00686 #endif 00687 00688 CyaSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify); 00689 00690 ret = HmacSetKey(&hmac, CyaSSL_GetHmacType(ssl), 00691 CyaSSL_GetMacSecret(ssl, verify), ssl->specs.hash_size); 00692 if (ret != 0) 00693 return ret; 00694 ret = HmacUpdate(&hmac, myInner, sizeof(myInner)); 00695 if (ret != 0) 00696 return ret; 00697 ret = HmacUpdate(&hmac, in, sz); /* content */ 00698 if (ret != 0) 00699 return ret; 00700 ret = HmacFinal(&hmac, digest); 00701 if (ret != 0) 00702 return ret; 00703 00704 return 0; 00705 } 00706 00707 #ifdef HAVE_TLS_EXTENSIONS 00708 00709 00710 /** Supports up to 64 flags. Update as needed. */ 00711 #define SEMAPHORE_SIZE 8 00712 00713 00714 static INLINE word16 TLSX_ToSemaphore(word16 type) 00715 { 00716 switch (type) { 00717 case SECURE_RENEGOTIATION: 00718 return 63; 00719 00720 default: 00721 if (type > 62) { 00722 /* This message SHOULD only happens during the adding of 00723 new TLS extensions in which its IANA number overflows 00724 the current semaphore's range, or if its number already 00725 is assigned to be used by another extension. 00726 Use this check value for the new extension and decrement 00727 the check value by one. */ 00728 CYASSL_MSG("### TLSX semaphore colision or overflow detected!"); 00729 } 00730 } 00731 00732 return type; 00733 } 00734 00735 00736 #define IS_OFF(semaphore, light) \ 00737 ((semaphore)[(light) / 8] ^ (byte) (0x01 << ((light) % 8))) 00738 00739 00740 #define TURN_ON(semaphore, light) \ 00741 ((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8))) 00742 00743 00744 static int TLSX_Push(TLSX** list, TLSX_Type type, void* data) 00745 { 00746 TLSX* extension; 00747 00748 extension = (TLSX*)XMALLOC(sizeof(TLSX), 0, DYNAMIC_TYPE_TLSX); 00749 if (extension == NULL) 00750 return MEMORY_E; 00751 00752 extension->type = type; 00753 extension->data = data; 00754 extension->resp = 0; 00755 extension->next = *list; 00756 *list = extension; 00757 00758 /* remove duplicated extensions, there should be only one of each type. */ 00759 do { 00760 if (extension->next && extension->next->type == type) { 00761 TLSX *next = extension->next; 00762 00763 extension->next = next->next; 00764 next->next = NULL; 00765 00766 TLSX_FreeAll(next); 00767 00768 /* there is no way to occur more than */ 00769 /* two extensions of the same type. */ 00770 break; 00771 } 00772 } while ((extension = extension->next)); 00773 00774 return 0; 00775 } 00776 00777 00778 #ifndef NO_CYASSL_SERVER 00779 00780 void TLSX_SetResponse(CYASSL* ssl, TLSX_Type type); 00781 00782 void TLSX_SetResponse(CYASSL* ssl, TLSX_Type type) 00783 { 00784 TLSX *ext = TLSX_Find(ssl->extensions, type); 00785 00786 if (ext) 00787 ext->resp = 1; 00788 } 00789 00790 #endif 00791 00792 /* SNI - Server Name Indication */ 00793 00794 #ifdef HAVE_SNI 00795 00796 static void TLSX_SNI_Free(SNI* sni) 00797 { 00798 if (sni) { 00799 switch (sni->type) { 00800 case CYASSL_SNI_HOST_NAME: 00801 XFREE(sni->data.host_name, 0, DYNAMIC_TYPE_TLSX); 00802 break; 00803 } 00804 00805 XFREE(sni, 0, DYNAMIC_TYPE_TLSX); 00806 } 00807 } 00808 00809 static void TLSX_SNI_FreeAll(SNI* list) 00810 { 00811 SNI* sni; 00812 00813 while ((sni = list)) { 00814 list = sni->next; 00815 TLSX_SNI_Free(sni); 00816 } 00817 } 00818 00819 static int TLSX_SNI_Append(SNI** list, byte type, const void* data, word16 size) 00820 { 00821 SNI* sni; 00822 00823 if (list == NULL) 00824 return BAD_FUNC_ARG; 00825 00826 if ((sni = XMALLOC(sizeof(SNI), 0, DYNAMIC_TYPE_TLSX)) == NULL) 00827 return MEMORY_E; 00828 00829 switch (type) { 00830 case CYASSL_SNI_HOST_NAME: { 00831 sni->data.host_name = XMALLOC(size + 1, 0, DYNAMIC_TYPE_TLSX); 00832 00833 if (sni->data.host_name) { 00834 XSTRNCPY(sni->data.host_name, (const char*)data, size); 00835 sni->data.host_name[size] = 0; 00836 } else { 00837 XFREE(sni, 0, DYNAMIC_TYPE_TLSX); 00838 return MEMORY_E; 00839 } 00840 } 00841 break; 00842 00843 default: /* invalid type */ 00844 XFREE(sni, 0, DYNAMIC_TYPE_TLSX); 00845 return BAD_FUNC_ARG; 00846 } 00847 00848 sni->type = type; 00849 sni->next = *list; 00850 00851 #ifndef NO_CYASSL_SERVER 00852 sni->options = 0; 00853 sni->status = CYASSL_SNI_NO_MATCH; 00854 #endif 00855 00856 *list = sni; 00857 00858 return 0; 00859 } 00860 00861 static word16 TLSX_SNI_GetSize(SNI* list) 00862 { 00863 SNI* sni; 00864 word16 length = OPAQUE16_LEN; /* list length */ 00865 00866 while ((sni = list)) { 00867 list = sni->next; 00868 00869 length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */ 00870 00871 switch (sni->type) { 00872 case CYASSL_SNI_HOST_NAME: 00873 length += XSTRLEN((char*)sni->data.host_name); 00874 break; 00875 } 00876 } 00877 00878 return length; 00879 } 00880 00881 static word16 TLSX_SNI_Write(SNI* list, byte* output) 00882 { 00883 SNI* sni; 00884 word16 length = 0; 00885 word16 offset = OPAQUE16_LEN; /* list length offset */ 00886 00887 while ((sni = list)) { 00888 list = sni->next; 00889 00890 output[offset++] = sni->type; /* sni type */ 00891 00892 switch (sni->type) { 00893 case CYASSL_SNI_HOST_NAME: 00894 length = XSTRLEN((char*)sni->data.host_name); 00895 00896 c16toa(length, output + offset); /* sni length */ 00897 offset += OPAQUE16_LEN; 00898 00899 XMEMCPY(output + offset, sni->data.host_name, length); 00900 00901 offset += length; 00902 break; 00903 } 00904 } 00905 00906 c16toa(offset - OPAQUE16_LEN, output); /* writing list length */ 00907 00908 return offset; 00909 } 00910 00911 static SNI* TLSX_SNI_Find(SNI *list, byte type) 00912 { 00913 SNI *sni = list; 00914 00915 while (sni && sni->type != type) 00916 sni = sni->next; 00917 00918 return sni; 00919 } 00920 00921 #ifndef NO_CYASSL_SERVER 00922 static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status) 00923 { 00924 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); 00925 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); 00926 00927 if (sni) { 00928 sni->status = status; 00929 CYASSL_MSG("SNI did match!"); 00930 } 00931 } 00932 00933 byte TLSX_SNI_Status(TLSX* extensions, byte type) 00934 { 00935 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); 00936 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); 00937 00938 if (sni) 00939 return sni->status; 00940 00941 return 0; 00942 } 00943 #endif 00944 00945 static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length, 00946 byte isRequest) 00947 { 00948 #ifndef NO_CYASSL_SERVER 00949 word16 size = 0; 00950 word16 offset = 0; 00951 #endif 00952 00953 TLSX *extension = TLSX_Find(ssl->extensions, SERVER_NAME_INDICATION); 00954 00955 if (!extension) 00956 extension = TLSX_Find(ssl->ctx->extensions, SERVER_NAME_INDICATION); 00957 00958 if (!extension || !extension->data) 00959 return isRequest ? 0 : BUFFER_ERROR; /* not using SNI OR unexpected 00960 SNI response from server. */ 00961 00962 if (!isRequest) 00963 return length ? BUFFER_ERROR : 0; /* SNI response must be empty! 00964 Nothing else to do. */ 00965 00966 #ifndef NO_CYASSL_SERVER 00967 00968 if (OPAQUE16_LEN > length) 00969 return BUFFER_ERROR; 00970 00971 ato16(input, &size); 00972 offset += OPAQUE16_LEN; 00973 00974 /* validating sni list length */ 00975 if (length != OPAQUE16_LEN + size) 00976 return BUFFER_ERROR; 00977 00978 for (size = 0; offset < length; offset += size) { 00979 SNI *sni; 00980 byte type = input[offset++]; 00981 00982 if (offset + OPAQUE16_LEN > length) 00983 return BUFFER_ERROR; 00984 00985 ato16(input + offset, &size); 00986 offset += OPAQUE16_LEN; 00987 00988 if (offset + size > length) 00989 return BUFFER_ERROR; 00990 00991 if (!(sni = TLSX_SNI_Find((SNI*)extension->data, type))) { 00992 continue; /* not using this SNI type */ 00993 } 00994 00995 switch(type) { 00996 case CYASSL_SNI_HOST_NAME: { 00997 byte matched = (XSTRLEN(sni->data.host_name) == size) 00998 && (XSTRNCMP(sni->data.host_name, 00999 (const char*)input + offset, size) == 0); 01000 01001 if (matched || sni->options & CYASSL_SNI_ANSWER_ON_MISMATCH) { 01002 int r = TLSX_UseSNI(&ssl->extensions, 01003 type, input + offset, size); 01004 01005 if (r != SSL_SUCCESS) return r; /* throw error */ 01006 01007 TLSX_SNI_SetStatus(ssl->extensions, type, 01008 matched ? CYASSL_SNI_REAL_MATCH : CYASSL_SNI_FAKE_MATCH); 01009 01010 } else if (!(sni->options & CYASSL_SNI_CONTINUE_ON_MISMATCH)) { 01011 SendAlert(ssl, alert_fatal, unrecognized_name); 01012 01013 return UNKNOWN_SNI_HOST_NAME_E; 01014 } 01015 break; 01016 } 01017 } 01018 01019 TLSX_SetResponse(ssl, SERVER_NAME_INDICATION); 01020 } 01021 01022 #endif 01023 01024 return 0; 01025 } 01026 01027 int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size) 01028 { 01029 TLSX* extension = TLSX_Find(*extensions, SERVER_NAME_INDICATION); 01030 SNI* sni = NULL; 01031 int ret = 0; 01032 01033 if (extensions == NULL || data == NULL) 01034 return BAD_FUNC_ARG; 01035 01036 if ((ret = TLSX_SNI_Append(&sni, type, data, size)) != 0) 01037 return ret; 01038 01039 if (!extension) { 01040 if ((ret = TLSX_Push(extensions, SERVER_NAME_INDICATION, (void*)sni)) 01041 != 0) { 01042 TLSX_SNI_Free(sni); 01043 return ret; 01044 } 01045 } 01046 else { 01047 /* push new SNI object to extension data. */ 01048 sni->next = (SNI*)extension->data; 01049 extension->data = (void*)sni; 01050 01051 /* look for another server name of the same type to remove */ 01052 do { 01053 if (sni->next && sni->next->type == type) { 01054 SNI *next = sni->next; 01055 01056 sni->next = next->next; 01057 TLSX_SNI_Free(next); 01058 01059 break; 01060 } 01061 } while ((sni = sni->next)); 01062 } 01063 01064 return SSL_SUCCESS; 01065 } 01066 01067 #ifndef NO_CYASSL_SERVER 01068 word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data) 01069 { 01070 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); 01071 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); 01072 01073 if (sni && sni->status != CYASSL_SNI_NO_MATCH) { 01074 switch (sni->type) { 01075 case CYASSL_SNI_HOST_NAME: 01076 *data = sni->data.host_name; 01077 return XSTRLEN(*data); 01078 } 01079 } 01080 01081 return 0; 01082 } 01083 01084 void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options) 01085 { 01086 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); 01087 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); 01088 01089 if (sni) 01090 sni->options = options; 01091 } 01092 01093 int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, 01094 byte type, byte* sni, word32* inOutSz) 01095 { 01096 word32 offset = 0; 01097 word32 len32 = 0; 01098 word16 len16 = 0; 01099 01100 if (helloSz < RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + CLIENT_HELLO_FIRST) 01101 return INCOMPLETE_DATA; 01102 01103 /* TLS record header */ 01104 if ((enum ContentType) clientHello[offset++] != handshake) 01105 return BUFFER_ERROR; 01106 01107 if (clientHello[offset++] != SSLv3_MAJOR) 01108 return BUFFER_ERROR; 01109 01110 if (clientHello[offset++] < TLSv1_MINOR) 01111 return BUFFER_ERROR; 01112 01113 ato16(clientHello + offset, &len16); 01114 offset += OPAQUE16_LEN; 01115 01116 if (offset + len16 > helloSz) 01117 return INCOMPLETE_DATA; 01118 01119 /* Handshake header */ 01120 if ((enum HandShakeType) clientHello[offset] != client_hello) 01121 return BUFFER_ERROR; 01122 01123 c24to32(clientHello + offset + 1, &len32); 01124 offset += HANDSHAKE_HEADER_SZ; 01125 01126 if (offset + len32 > helloSz) 01127 return BUFFER_ERROR; 01128 01129 /* client hello */ 01130 offset += VERSION_SZ + RAN_LEN; /* version, random */ 01131 01132 if (helloSz < offset + clientHello[offset]) 01133 return BUFFER_ERROR; 01134 01135 offset += ENUM_LEN + clientHello[offset]; /* skip session id */ 01136 01137 /* cypher suites */ 01138 if (helloSz < offset + OPAQUE16_LEN) 01139 return BUFFER_ERROR; 01140 01141 ato16(clientHello + offset, &len16); 01142 offset += OPAQUE16_LEN; 01143 01144 if (helloSz < offset + len16) 01145 return BUFFER_ERROR; 01146 01147 offset += len16; /* skip cypher suites */ 01148 01149 /* compression methods */ 01150 if (helloSz < offset + 1) 01151 return BUFFER_ERROR; 01152 01153 if (helloSz < offset + clientHello[offset]) 01154 return BUFFER_ERROR; 01155 01156 offset += ENUM_LEN + clientHello[offset]; /* skip compression methods */ 01157 01158 /* extensions */ 01159 if (helloSz < offset + OPAQUE16_LEN) 01160 return 0; /* no extensions in client hello. */ 01161 01162 ato16(clientHello + offset, &len16); 01163 offset += OPAQUE16_LEN; 01164 01165 if (helloSz < offset + len16) 01166 return BUFFER_ERROR; 01167 01168 while (len16 >= OPAQUE16_LEN + OPAQUE16_LEN) { 01169 word16 extType; 01170 word16 extLen; 01171 01172 ato16(clientHello + offset, &extType); 01173 offset += OPAQUE16_LEN; 01174 01175 ato16(clientHello + offset, &extLen); 01176 offset += OPAQUE16_LEN; 01177 01178 if (helloSz < offset + extLen) 01179 return BUFFER_ERROR; 01180 01181 if (extType != SERVER_NAME_INDICATION) { 01182 offset += extLen; /* skip extension */ 01183 } else { 01184 word16 listLen; 01185 01186 ato16(clientHello + offset, &listLen); 01187 offset += OPAQUE16_LEN; 01188 01189 if (helloSz < offset + listLen) 01190 return BUFFER_ERROR; 01191 01192 while (listLen > ENUM_LEN + OPAQUE16_LEN) { 01193 byte sniType = clientHello[offset++]; 01194 word16 sniLen; 01195 01196 ato16(clientHello + offset, &sniLen); 01197 offset += OPAQUE16_LEN; 01198 01199 if (helloSz < offset + sniLen) 01200 return BUFFER_ERROR; 01201 01202 if (sniType != type) { 01203 offset += sniLen; 01204 listLen -= min(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen); 01205 continue; 01206 } 01207 01208 *inOutSz = min(sniLen, *inOutSz); 01209 XMEMCPY(sni, clientHello + offset, *inOutSz); 01210 01211 return SSL_SUCCESS; 01212 } 01213 } 01214 01215 len16 -= min(2 * OPAQUE16_LEN + extLen, len16); 01216 } 01217 01218 return len16 ? BUFFER_ERROR : 0; 01219 } 01220 01221 #endif 01222 01223 #define SNI_FREE_ALL TLSX_SNI_FreeAll 01224 #define SNI_GET_SIZE TLSX_SNI_GetSize 01225 #define SNI_WRITE TLSX_SNI_Write 01226 #define SNI_PARSE TLSX_SNI_Parse 01227 01228 #else 01229 01230 #define SNI_FREE_ALL(list) 01231 #define SNI_GET_SIZE(list) 0 01232 #define SNI_WRITE(a, b) 0 01233 #define SNI_PARSE(a, b, c, d) 0 01234 01235 #endif /* HAVE_SNI */ 01236 01237 #ifdef HAVE_MAX_FRAGMENT 01238 01239 static word16 TLSX_MFL_Write(byte* data, byte* output) 01240 { 01241 output[0] = data[0]; 01242 01243 return ENUM_LEN; 01244 } 01245 01246 static int TLSX_MFL_Parse(CYASSL* ssl, byte* input, word16 length, 01247 byte isRequest) 01248 { 01249 if (length != ENUM_LEN) 01250 return BUFFER_ERROR; 01251 01252 switch (*input) { 01253 case CYASSL_MFL_2_9 : ssl->max_fragment = 512; break; 01254 case CYASSL_MFL_2_10: ssl->max_fragment = 1024; break; 01255 case CYASSL_MFL_2_11: ssl->max_fragment = 2048; break; 01256 case CYASSL_MFL_2_12: ssl->max_fragment = 4096; break; 01257 case CYASSL_MFL_2_13: ssl->max_fragment = 8192; break; 01258 01259 default: 01260 SendAlert(ssl, alert_fatal, illegal_parameter); 01261 01262 return UNKNOWN_MAX_FRAG_LEN_E; 01263 } 01264 01265 #ifndef NO_CYASSL_SERVER 01266 if (isRequest) { 01267 int r = TLSX_UseMaxFragment(&ssl->extensions, *input); 01268 01269 if (r != SSL_SUCCESS) return r; /* throw error */ 01270 01271 TLSX_SetResponse(ssl, MAX_FRAGMENT_LENGTH); 01272 } 01273 #endif 01274 01275 return 0; 01276 } 01277 01278 int TLSX_UseMaxFragment(TLSX** extensions, byte mfl) 01279 { 01280 byte* data = NULL; 01281 int ret = 0; 01282 01283 if (extensions == NULL) 01284 return BAD_FUNC_ARG; 01285 01286 if (mfl < CYASSL_MFL_2_9 || CYASSL_MFL_2_13 < mfl) 01287 return BAD_FUNC_ARG; 01288 01289 if ((data = XMALLOC(ENUM_LEN, 0, DYNAMIC_TYPE_TLSX)) == NULL) 01290 return MEMORY_E; 01291 01292 data[0] = mfl; 01293 01294 /* push new MFL extension. */ 01295 if ((ret = TLSX_Push(extensions, MAX_FRAGMENT_LENGTH, data)) != 0) { 01296 XFREE(data, 0, DYNAMIC_TYPE_TLSX); 01297 return ret; 01298 } 01299 01300 return SSL_SUCCESS; 01301 } 01302 01303 01304 #define MFL_FREE_ALL(data) XFREE(data, 0, DYNAMIC_TYPE_TLSX) 01305 #define MFL_GET_SIZE(data) ENUM_LEN 01306 #define MFL_WRITE TLSX_MFL_Write 01307 #define MFL_PARSE TLSX_MFL_Parse 01308 01309 #else 01310 01311 #define MFL_FREE_ALL(a) 01312 #define MFL_GET_SIZE(a) 0 01313 #define MFL_WRITE(a, b) 0 01314 #define MFL_PARSE(a, b, c, d) 0 01315 01316 #endif /* HAVE_MAX_FRAGMENT */ 01317 01318 #ifdef HAVE_TRUNCATED_HMAC 01319 01320 static int TLSX_THM_Parse(CYASSL* ssl, byte* input, word16 length, 01321 byte isRequest) 01322 { 01323 if (length != 0 || input == NULL) 01324 return BUFFER_ERROR; 01325 01326 #ifndef NO_CYASSL_SERVER 01327 if (isRequest) { 01328 int r = TLSX_UseTruncatedHMAC(&ssl->extensions); 01329 01330 if (r != SSL_SUCCESS) return r; /* throw error */ 01331 01332 TLSX_SetResponse(ssl, TRUNCATED_HMAC); 01333 } 01334 #endif 01335 01336 ssl->truncated_hmac = 1; 01337 01338 return 0; 01339 } 01340 01341 int TLSX_UseTruncatedHMAC(TLSX** extensions) 01342 { 01343 int ret = 0; 01344 01345 if (extensions == NULL) 01346 return BAD_FUNC_ARG; 01347 01348 if ((ret = TLSX_Push(extensions, TRUNCATED_HMAC, NULL)) != 0) 01349 return ret; 01350 01351 return SSL_SUCCESS; 01352 } 01353 01354 #define THM_PARSE TLSX_THM_Parse 01355 01356 #else 01357 01358 #define THM_PARSE(a, b, c, d) 0 01359 01360 #endif /* HAVE_TRUNCATED_HMAC */ 01361 01362 #ifdef HAVE_SUPPORTED_CURVES 01363 01364 #ifndef HAVE_ECC 01365 #error Elliptic Curves Extension requires Elliptic Curve Cryptography. \ 01366 Use --enable-ecc in the configure script or define HAVE_ECC. 01367 #endif 01368 01369 static void TLSX_EllipticCurve_FreeAll(EllipticCurve* list) 01370 { 01371 EllipticCurve* curve; 01372 01373 while ((curve = list)) { 01374 list = curve->next; 01375 XFREE(curve, 0, DYNAMIC_TYPE_TLSX); 01376 } 01377 } 01378 01379 static int TLSX_EllipticCurve_Append(EllipticCurve** list, word16 name) 01380 { 01381 EllipticCurve* curve; 01382 01383 if (list == NULL) 01384 return BAD_FUNC_ARG; 01385 01386 if ((curve = XMALLOC(sizeof(EllipticCurve), 0, DYNAMIC_TYPE_TLSX)) == NULL) 01387 return MEMORY_E; 01388 01389 curve->name = name; 01390 curve->next = *list; 01391 01392 *list = curve; 01393 01394 return 0; 01395 } 01396 01397 #ifndef NO_CYASSL_CLIENT 01398 01399 static void TLSX_EllipticCurve_ValidateRequest(CYASSL* ssl, byte* semaphore) 01400 { 01401 int i; 01402 01403 for (i = 0; i < ssl->suites->suiteSz; i+= 2) 01404 if (ssl->suites->suites[i] == ECC_BYTE) 01405 return; 01406 01407 /* No elliptic curve suite found */ 01408 TURN_ON(semaphore, TLSX_ToSemaphore(ELLIPTIC_CURVES)); 01409 } 01410 01411 static word16 TLSX_EllipticCurve_GetSize(EllipticCurve* list) 01412 { 01413 EllipticCurve* curve; 01414 word16 length = OPAQUE16_LEN; /* list length */ 01415 01416 while ((curve = list)) { 01417 list = curve->next; 01418 length += OPAQUE16_LEN; /* curve length */ 01419 } 01420 01421 return length; 01422 } 01423 01424 static word16 TLSX_EllipticCurve_WriteR(EllipticCurve* curve, byte* output); 01425 static word16 TLSX_EllipticCurve_WriteR(EllipticCurve* curve, byte* output) 01426 { 01427 word16 offset = 0; 01428 01429 if (!curve) 01430 return offset; 01431 01432 offset = TLSX_EllipticCurve_WriteR(curve->next, output); 01433 c16toa(curve->name, output + offset); 01434 01435 return OPAQUE16_LEN + offset; 01436 } 01437 01438 static word16 TLSX_EllipticCurve_Write(EllipticCurve* list, byte* output) 01439 { 01440 word16 length = TLSX_EllipticCurve_WriteR(list, output + OPAQUE16_LEN); 01441 01442 c16toa(length, output); /* writing list length */ 01443 01444 return OPAQUE16_LEN + length; 01445 } 01446 01447 #endif /* NO_CYASSL_CLIENT */ 01448 #ifndef NO_CYASSL_SERVER 01449 01450 static int TLSX_EllipticCurve_Parse(CYASSL* ssl, byte* input, word16 length, 01451 byte isRequest) 01452 { 01453 word16 offset; 01454 word16 name; 01455 int r; 01456 01457 (void) isRequest; /* shut up compiler! */ 01458 01459 if (OPAQUE16_LEN > length || length % OPAQUE16_LEN) 01460 return BUFFER_ERROR; 01461 01462 ato16(input, &offset); 01463 01464 /* validating curve list length */ 01465 if (length != OPAQUE16_LEN + offset) 01466 return BUFFER_ERROR; 01467 01468 while (offset) { 01469 ato16(input + offset, &name); 01470 offset -= OPAQUE16_LEN; 01471 01472 r = TLSX_UseSupportedCurve(&ssl->extensions, name); 01473 01474 if (r != SSL_SUCCESS) return r; /* throw error */ 01475 } 01476 01477 return 0; 01478 } 01479 01480 int TLSX_ValidateEllipticCurves(CYASSL* ssl, byte first, byte second) { 01481 TLSX* extension = (first == ECC_BYTE) 01482 ? TLSX_Find(ssl->extensions, ELLIPTIC_CURVES) 01483 : NULL; 01484 EllipticCurve* curve = NULL; 01485 word32 oid = 0; 01486 word16 octets = 0; /* acording to 'ecc_set_type ecc_sets[];' */ 01487 int sig = 0; /* valitade signature */ 01488 int key = 0; /* validate key */ 01489 01490 (void)oid; 01491 (void)octets; 01492 01493 if (!extension) 01494 return 1; /* no suite restriction */ 01495 01496 for (curve = extension->data; curve && !(sig && key); curve = curve->next) { 01497 01498 switch (curve->name) { 01499 case CYASSL_ECC_SECP160R1: oid = ECC_160R1; octets = 20; break; 01500 case CYASSL_ECC_SECP192R1: oid = ECC_192R1; octets = 24; break; 01501 case CYASSL_ECC_SECP224R1: oid = ECC_224R1; octets = 28; break; 01502 case CYASSL_ECC_SECP256R1: oid = ECC_256R1; octets = 32; break; 01503 case CYASSL_ECC_SECP384R1: oid = ECC_384R1; octets = 48; break; 01504 case CYASSL_ECC_SECP521R1: oid = ECC_521R1; octets = 66; break; 01505 default: continue; /* unsupported curve */ 01506 } 01507 01508 switch (second) { 01509 #ifndef NO_DSA 01510 /* ECDHE_ECDSA */ 01511 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: 01512 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: 01513 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: 01514 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: 01515 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: 01516 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: 01517 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: 01518 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: 01519 case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: 01520 case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: 01521 sig |= ssl->pkCurveOID == oid; 01522 key |= ssl->eccTempKeySz == octets; 01523 break; 01524 01525 /* ECDH_ECDSA */ 01526 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: 01527 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: 01528 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: 01529 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: 01530 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: 01531 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: 01532 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: 01533 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: 01534 sig |= ssl->pkCurveOID == oid; 01535 key |= ssl->pkCurveOID == oid; 01536 break; 01537 #endif 01538 #ifndef NO_RSA 01539 /* ECDHE_RSA */ 01540 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: 01541 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: 01542 case TLS_ECDHE_RSA_WITH_RC4_128_SHA: 01543 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: 01544 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: 01545 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: 01546 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: 01547 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: 01548 sig = 1; 01549 key |= ssl->eccTempKeySz == octets; 01550 break; 01551 01552 /* ECDH_RSA */ 01553 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: 01554 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: 01555 case TLS_ECDH_RSA_WITH_RC4_128_SHA: 01556 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: 01557 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: 01558 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: 01559 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: 01560 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: 01561 sig = 1; 01562 key |= ssl->pkCurveOID == oid; 01563 break; 01564 #endif 01565 default: 01566 sig = 1; 01567 key = 1; 01568 break; 01569 } 01570 } 01571 01572 return sig && key; 01573 } 01574 01575 #endif /* NO_CYASSL_SERVER */ 01576 01577 int TLSX_UseSupportedCurve(TLSX** extensions, word16 name) 01578 { 01579 TLSX* extension = TLSX_Find(*extensions, ELLIPTIC_CURVES); 01580 EllipticCurve* curve = NULL; 01581 int ret = 0; 01582 01583 if (extensions == NULL) 01584 return BAD_FUNC_ARG; 01585 01586 if ((ret = TLSX_EllipticCurve_Append(&curve, name)) != 0) 01587 return ret; 01588 01589 if (!extension) { 01590 if ((ret = TLSX_Push(extensions, ELLIPTIC_CURVES, curve)) != 0) { 01591 XFREE(curve, 0, DYNAMIC_TYPE_TLSX); 01592 return ret; 01593 } 01594 } 01595 else { 01596 /* push new EllipticCurve object to extension data. */ 01597 curve->next = (EllipticCurve*)extension->data; 01598 extension->data = (void*)curve; 01599 01600 /* look for another curve of the same name to remove (replacement) */ 01601 do { 01602 if (curve->next && curve->next->name == name) { 01603 EllipticCurve *next = curve->next; 01604 01605 curve->next = next->next; 01606 XFREE(next, 0, DYNAMIC_TYPE_TLSX); 01607 01608 break; 01609 } 01610 } while ((curve = curve->next)); 01611 } 01612 01613 return SSL_SUCCESS; 01614 } 01615 01616 #define EC_FREE_ALL TLSX_EllipticCurve_FreeAll 01617 #define EC_VALIDATE_REQUEST TLSX_EllipticCurve_ValidateRequest 01618 01619 #ifndef NO_CYASSL_CLIENT 01620 #define EC_GET_SIZE TLSX_EllipticCurve_GetSize 01621 #define EC_WRITE TLSX_EllipticCurve_Write 01622 #else 01623 #define EC_GET_SIZE(list) 0 01624 #define EC_WRITE(a, b) 0 01625 #endif 01626 01627 #ifndef NO_CYASSL_SERVER 01628 #define EC_PARSE TLSX_EllipticCurve_Parse 01629 #else 01630 #define EC_PARSE(a, b, c, d) 0 01631 #endif 01632 01633 #else 01634 01635 #define EC_FREE_ALL(list) 01636 #define EC_GET_SIZE(list) 0 01637 #define EC_WRITE(a, b) 0 01638 #define EC_PARSE(a, b, c, d) 0 01639 #define EC_VALIDATE_REQUEST(a, b) 01640 01641 #endif /* HAVE_SUPPORTED_CURVES */ 01642 01643 #ifdef HAVE_SECURE_RENEGOTIATION 01644 01645 static byte TLSX_SecureRenegotiation_GetSize(SecureRenegotiation* data, 01646 int isRequest) 01647 { 01648 byte length = OPAQUE8_LEN; /* empty info length */ 01649 01650 if (data->enabled) { 01651 /* client sends client_verify_data only */ 01652 length += TLS_FINISHED_SZ; 01653 01654 /* server also sends server_verify_data */ 01655 if (!isRequest) 01656 length += TLS_FINISHED_SZ; 01657 } 01658 01659 return length; 01660 } 01661 01662 static word16 TLSX_SecureRenegotiation_Write(SecureRenegotiation* data, 01663 byte* output, int isRequest) 01664 { 01665 word16 offset = OPAQUE8_LEN; /* RenegotiationInfo length */ 01666 01667 if (data->enabled) { 01668 /* client sends client_verify_data only */ 01669 XMEMCPY(output + offset, data->client_verify_data, TLS_FINISHED_SZ); 01670 offset += TLS_FINISHED_SZ; 01671 01672 /* server also sends server_verify_data */ 01673 if (!isRequest) { 01674 XMEMCPY(output + offset, data->server_verify_data, TLS_FINISHED_SZ); 01675 offset += TLS_FINISHED_SZ; 01676 } 01677 } 01678 01679 output[0] = offset - 1; /* info length - self */ 01680 01681 return offset; 01682 } 01683 01684 static int TLSX_SecureRenegotiation_Parse(CYASSL* ssl, byte* input, 01685 word16 length, byte isRequest) 01686 { 01687 int ret = SECURE_RENEGOTIATION_E; 01688 01689 if (length >= OPAQUE8_LEN) { 01690 if (ssl->secure_renegotiation == NULL) { 01691 #ifndef NO_CYASSL_SERVER 01692 if (isRequest && *input == 0) { 01693 ret = 0; /* don't reply, user didn't enable */ 01694 } 01695 #endif 01696 } 01697 else if (isRequest) { 01698 #ifndef NO_CYASSL_SERVER 01699 if (*input == TLS_FINISHED_SZ) { 01700 /* TODO compare client_verify_data */ 01701 ret = 0; 01702 } 01703 #endif 01704 } 01705 else { 01706 #ifndef NO_CYASSL_CLIENT 01707 if (!ssl->secure_renegotiation->enabled) { 01708 if (*input == 0) { 01709 ssl->secure_renegotiation->enabled = 1; 01710 ret = 0; 01711 } 01712 } 01713 else if (*input == 2 * TLS_FINISHED_SZ) { 01714 /* TODO compare client_verify_data and server_verify_data */ 01715 ret = 0; 01716 } 01717 #endif 01718 } 01719 } 01720 01721 if (ret != 0) { 01722 /* TODO: turn on fatal error at ssl level too */ 01723 SendAlert(ssl, alert_fatal, handshake_failure); 01724 } 01725 01726 return ret; 01727 } 01728 01729 int TLSX_UseSecureRenegotiation(TLSX** extensions) 01730 { 01731 int ret = 0; 01732 SecureRenegotiation* data = NULL; 01733 01734 data = (SecureRenegotiation*)XMALLOC(sizeof(SecureRenegotiation), NULL, 01735 DYNAMIC_TYPE_TLSX); 01736 if (data == NULL) 01737 return MEMORY_E; 01738 01739 XMEMSET(data, 0, sizeof(SecureRenegotiation)); 01740 01741 ret = TLSX_Push(extensions, SECURE_RENEGOTIATION, data); 01742 if (ret != 0) { 01743 XFREE(data, 0, DYNAMIC_TYPE_TLSX); 01744 return ret; 01745 } 01746 01747 return SSL_SUCCESS; 01748 } 01749 01750 01751 #define SCR_FREE_ALL(data) XFREE(data, NULL, DYNAMIC_TYPE_TLSX) 01752 #define SCR_GET_SIZE TLSX_SecureRenegotiation_GetSize 01753 #define SCR_WRITE TLSX_SecureRenegotiation_Write 01754 #define SCR_PARSE TLSX_SecureRenegotiation_Parse 01755 01756 #else 01757 01758 #define SCR_FREE_ALL(a) 01759 #define SCR_GET_SIZE(a, b) 0 01760 #define SCR_WRITE(a, b, c) 0 01761 #define SCR_PARSE(a, b, c, d) 0 01762 01763 #endif /* HAVE_SECURE_RENEGOTIATION */ 01764 01765 #ifdef HAVE_SESSION_TICKET 01766 01767 static void TLSX_SessionTicket_ValidateRequest(CYASSL* ssl) 01768 { 01769 TLSX* extension = TLSX_Find(ssl->extensions, SESSION_TICKET); 01770 SessionTicket* ticket = extension ? extension->data : NULL; 01771 01772 if (ticket) { 01773 /* TODO validate ticket timeout here! */ 01774 if (ticket->lifetime == 0xfffffff) { 01775 /* send empty ticket on timeout */ 01776 TLSX_UseSessionTicket(&ssl->extensions, NULL); 01777 } 01778 } 01779 } 01780 01781 01782 static word16 TLSX_SessionTicket_GetSize(SessionTicket* ticket, int isRequest) 01783 { 01784 return isRequest && ticket ? ticket->size : 0; 01785 } 01786 01787 static word16 TLSX_SessionTicket_Write(SessionTicket* ticket, byte* output, 01788 int isRequest) 01789 { 01790 int offset = 0; /* empty ticket */ 01791 01792 if (isRequest && ticket) { 01793 XMEMCPY(output + offset, ticket->data, ticket->size); 01794 offset += ticket->size; 01795 } 01796 01797 return offset; 01798 } 01799 01800 01801 static int TLSX_SessionTicket_Parse(CYASSL* ssl, byte* input, word16 length, 01802 byte isRequest) 01803 { 01804 if (!isRequest) { 01805 if (length != 0) 01806 return BUFFER_ERROR; 01807 01808 ssl->expect_session_ticket = 1; 01809 } 01810 else { 01811 /* TODO server side */ 01812 (void)input; 01813 } 01814 01815 return 0; 01816 } 01817 01818 CYASSL_LOCAL SessionTicket* TLSX_SessionTicket_Create(word32 lifetime, 01819 byte* data, word16 size) 01820 { 01821 SessionTicket* ticket = (SessionTicket*)XMALLOC(sizeof(SessionTicket), 01822 NULL, DYNAMIC_TYPE_TLSX); 01823 if (ticket) { 01824 ticket->data = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_TLSX); 01825 if (ticket->data == NULL) { 01826 XFREE(ticket, NULL, DYNAMIC_TYPE_TLSX); 01827 return NULL; 01828 } 01829 01830 XMEMCPY(ticket->data, data, size); 01831 ticket->size = size; 01832 ticket->lifetime = lifetime; 01833 } 01834 01835 return ticket; 01836 } 01837 CYASSL_LOCAL void TLSX_SessionTicket_Free(SessionTicket* ticket) 01838 { 01839 if (ticket) { 01840 XFREE(ticket->data, NULL, DYNAMIC_TYPE_TLSX); 01841 XFREE(ticket, NULL, DYNAMIC_TYPE_TLSX); 01842 } 01843 } 01844 01845 int TLSX_UseSessionTicket(TLSX** extensions, SessionTicket* ticket) 01846 { 01847 int ret = 0; 01848 01849 if (extensions == NULL) 01850 return BAD_FUNC_ARG; 01851 01852 /* If the ticket is NULL, the client will request a new ticket from the 01853 server. Otherwise, the client will use it in the next client hello. */ 01854 if ((ret = TLSX_Push(extensions, SESSION_TICKET, (void*)ticket)) != 0) 01855 return ret; 01856 01857 return SSL_SUCCESS; 01858 } 01859 01860 #define STK_VALIDATE_REQUEST TLSX_SessionTicket_ValidateRequest 01861 #define STK_GET_SIZE TLSX_SessionTicket_GetSize 01862 #define STK_WRITE TLSX_SessionTicket_Write 01863 #define STK_PARSE TLSX_SessionTicket_Parse 01864 01865 #else 01866 01867 #define STK_VALIDATE_REQUEST(a) 01868 #define STK_GET_SIZE(a, b) 0 01869 #define STK_WRITE(a, b, c) 0 01870 #define STK_PARSE(a, b, c, d) 0 01871 01872 #endif /* HAVE_SESSION_TICKET */ 01873 01874 01875 TLSX* TLSX_Find(TLSX* list, TLSX_Type type) 01876 { 01877 TLSX* extension = list; 01878 01879 while (extension && extension->type != type) 01880 extension = extension->next; 01881 01882 return extension; 01883 } 01884 01885 void TLSX_FreeAll(TLSX* list) 01886 { 01887 TLSX* extension; 01888 01889 while ((extension = list)) { 01890 list = extension->next; 01891 01892 switch (extension->type) { 01893 case SERVER_NAME_INDICATION: 01894 SNI_FREE_ALL((SNI*)extension->data); 01895 break; 01896 01897 case MAX_FRAGMENT_LENGTH: 01898 MFL_FREE_ALL(extension->data); 01899 break; 01900 01901 case TRUNCATED_HMAC: 01902 /* Nothing to do. */ 01903 break; 01904 01905 case ELLIPTIC_CURVES: 01906 EC_FREE_ALL(extension->data); 01907 break; 01908 01909 case SECURE_RENEGOTIATION: 01910 SCR_FREE_ALL(extension->data); 01911 break; 01912 01913 case SESSION_TICKET: 01914 /* Nothing to do. */ 01915 break; 01916 } 01917 01918 XFREE(extension, 0, DYNAMIC_TYPE_TLSX); 01919 } 01920 } 01921 01922 int TLSX_SupportExtensions(CYASSL* ssl) { 01923 return ssl && (IsTLS(ssl) || ssl->version.major == DTLS_MAJOR); 01924 } 01925 01926 static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest) 01927 { 01928 TLSX* extension; 01929 word16 length = 0; 01930 01931 while ((extension = list)) { 01932 list = extension->next; 01933 01934 if (!isRequest && !extension->resp) 01935 continue; /* skip! */ 01936 01937 if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type))) 01938 continue; /* skip! */ 01939 01940 /* type + data length */ 01941 length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN; 01942 01943 switch (extension->type) { 01944 case SERVER_NAME_INDICATION: 01945 if (isRequest) 01946 length += SNI_GET_SIZE(extension->data); 01947 break; 01948 case MAX_FRAGMENT_LENGTH: 01949 length += MFL_GET_SIZE(extension->data); 01950 break; 01951 01952 case TRUNCATED_HMAC: 01953 /* empty extension. */ 01954 break; 01955 01956 case ELLIPTIC_CURVES: 01957 length += EC_GET_SIZE(extension->data); 01958 break; 01959 01960 case SECURE_RENEGOTIATION: 01961 length += SCR_GET_SIZE(extension->data, isRequest); 01962 break; 01963 01964 case SESSION_TICKET: 01965 length += STK_GET_SIZE(extension->data, isRequest); 01966 break; 01967 } 01968 01969 TURN_ON(semaphore, TLSX_ToSemaphore(extension->type)); 01970 } 01971 01972 return length; 01973 } 01974 01975 static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore, 01976 byte isRequest) 01977 { 01978 TLSX* extension; 01979 word16 offset = 0; 01980 word16 length_offset = 0; 01981 01982 while ((extension = list)) { 01983 list = extension->next; 01984 01985 if (!isRequest && !extension->resp) 01986 continue; /* skip! */ 01987 01988 if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type))) 01989 continue; /* skip! */ 01990 01991 /* extension type */ 01992 c16toa(extension->type, output + offset); 01993 offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN; 01994 length_offset = offset; 01995 01996 /* extension data should be written internally */ 01997 switch (extension->type) { 01998 case SERVER_NAME_INDICATION: 01999 if (isRequest) 02000 offset += SNI_WRITE(extension->data, output + offset); 02001 break; 02002 02003 case MAX_FRAGMENT_LENGTH: 02004 offset += MFL_WRITE(extension->data, output + offset); 02005 break; 02006 02007 case TRUNCATED_HMAC: 02008 /* empty extension. */ 02009 break; 02010 02011 case ELLIPTIC_CURVES: 02012 offset += EC_WRITE(extension->data, output + offset); 02013 break; 02014 02015 case SECURE_RENEGOTIATION: 02016 offset += SCR_WRITE(extension->data, output + offset, 02017 isRequest); 02018 break; 02019 02020 case SESSION_TICKET: 02021 offset += STK_WRITE(extension->data, output + offset, 02022 isRequest); 02023 break; 02024 } 02025 02026 /* writing extension data length */ 02027 c16toa(offset - length_offset, output + length_offset - OPAQUE16_LEN); 02028 02029 TURN_ON(semaphore, TLSX_ToSemaphore(extension->type)); 02030 } 02031 02032 return offset; 02033 } 02034 02035 #ifndef NO_CYASSL_CLIENT 02036 02037 word16 TLSX_GetRequestSize(CYASSL* ssl) 02038 { 02039 word16 length = 0; 02040 02041 if (TLSX_SupportExtensions(ssl)) { 02042 byte semaphore[SEMAPHORE_SIZE] = {0}; 02043 02044 EC_VALIDATE_REQUEST(ssl, semaphore); 02045 STK_VALIDATE_REQUEST(ssl); 02046 02047 if (ssl->extensions) 02048 length += TLSX_GetSize(ssl->extensions, semaphore, 1); 02049 02050 if (ssl->ctx && ssl->ctx->extensions) 02051 length += TLSX_GetSize(ssl->ctx->extensions, semaphore, 1); 02052 02053 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) 02054 length += ssl->suites->hashSigAlgoSz + HELLO_EXT_LEN; 02055 } 02056 02057 if (length) 02058 length += OPAQUE16_LEN; /* for total length storage */ 02059 02060 return length; 02061 } 02062 02063 word16 TLSX_WriteRequest(CYASSL* ssl, byte* output) 02064 { 02065 word16 offset = 0; 02066 02067 if (TLSX_SupportExtensions(ssl) && output) { 02068 byte semaphore[SEMAPHORE_SIZE] = {0}; 02069 02070 offset += OPAQUE16_LEN; /* extensions length */ 02071 02072 EC_VALIDATE_REQUEST(ssl, semaphore); 02073 02074 if (ssl->extensions) 02075 offset += TLSX_Write(ssl->extensions, output + offset, 02076 semaphore, 1); 02077 02078 if (ssl->ctx && ssl->ctx->extensions) 02079 offset += TLSX_Write(ssl->ctx->extensions, output + offset, 02080 semaphore, 1); 02081 02082 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) 02083 { 02084 int i; 02085 /* extension type */ 02086 c16toa(HELLO_EXT_SIG_ALGO, output + offset); 02087 offset += HELLO_EXT_TYPE_SZ; 02088 02089 /* extension data length */ 02090 c16toa(OPAQUE16_LEN + ssl->suites->hashSigAlgoSz, output + offset); 02091 offset += OPAQUE16_LEN; 02092 02093 /* sig algos length */ 02094 c16toa(ssl->suites->hashSigAlgoSz, output + offset); 02095 offset += OPAQUE16_LEN; 02096 02097 /* sig algos */ 02098 for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, offset++) 02099 output[offset] = ssl->suites->hashSigAlgo[i]; 02100 } 02101 02102 if (offset > OPAQUE16_LEN) 02103 c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ 02104 } 02105 02106 return offset; 02107 } 02108 02109 #endif /* NO_CYASSL_CLIENT */ 02110 02111 #ifndef NO_CYASSL_SERVER 02112 02113 word16 TLSX_GetResponseSize(CYASSL* ssl) 02114 { 02115 word16 length = 0; 02116 byte semaphore[SEMAPHORE_SIZE] = {0}; 02117 02118 if (TLSX_SupportExtensions(ssl)) 02119 length += TLSX_GetSize(ssl->extensions, semaphore, 0); 02120 02121 /* All the response data is set at the ssl object only, so no ctx here. */ 02122 02123 if (length) 02124 length += OPAQUE16_LEN; /* for total length storage */ 02125 02126 return length; 02127 } 02128 02129 word16 TLSX_WriteResponse(CYASSL *ssl, byte* output) 02130 { 02131 word16 offset = 0; 02132 02133 if (TLSX_SupportExtensions(ssl) && output) { 02134 byte semaphore[SEMAPHORE_SIZE] = {0}; 02135 02136 offset += OPAQUE16_LEN; /* extensions length */ 02137 02138 offset += TLSX_Write(ssl->extensions, output + offset, semaphore, 0); 02139 02140 if (offset > OPAQUE16_LEN) 02141 c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ 02142 } 02143 02144 return offset; 02145 } 02146 02147 #endif /* NO_CYASSL_SERVER */ 02148 02149 int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest, 02150 Suites *suites) 02151 { 02152 int ret = 0; 02153 word16 offset = 0; 02154 02155 if (!ssl || !input || (isRequest && !suites)) 02156 return BAD_FUNC_ARG; 02157 02158 while (ret == 0 && offset < length) { 02159 word16 type; 02160 word16 size; 02161 02162 if (length - offset < HELLO_EXT_TYPE_SZ + OPAQUE16_LEN) 02163 return BUFFER_ERROR; 02164 02165 ato16(input + offset, &type); 02166 offset += HELLO_EXT_TYPE_SZ; 02167 02168 ato16(input + offset, &size); 02169 offset += OPAQUE16_LEN; 02170 02171 if (offset + size > length) 02172 return BUFFER_ERROR; 02173 02174 switch (type) { 02175 case SERVER_NAME_INDICATION: 02176 CYASSL_MSG("SNI extension received"); 02177 02178 ret = SNI_PARSE(ssl, input + offset, size, isRequest); 02179 break; 02180 02181 case MAX_FRAGMENT_LENGTH: 02182 CYASSL_MSG("Max Fragment Length extension received"); 02183 02184 ret = MFL_PARSE(ssl, input + offset, size, isRequest); 02185 break; 02186 02187 case TRUNCATED_HMAC: 02188 CYASSL_MSG("Truncated HMAC extension received"); 02189 02190 ret = THM_PARSE(ssl, input + offset, size, isRequest); 02191 break; 02192 02193 case ELLIPTIC_CURVES: 02194 CYASSL_MSG("Elliptic Curves extension received"); 02195 02196 ret = EC_PARSE(ssl, input + offset, size, isRequest); 02197 break; 02198 02199 case SECURE_RENEGOTIATION: 02200 CYASSL_MSG("Secure Renegotiation extension received"); 02201 02202 ret = SCR_PARSE(ssl, input + offset, size, isRequest); 02203 break; 02204 02205 case SESSION_TICKET: 02206 CYASSL_MSG("Session Ticket extension received"); 02207 02208 ret = STK_PARSE(ssl, input + offset, size, isRequest); 02209 break; 02210 02211 case HELLO_EXT_SIG_ALGO: 02212 if (isRequest) { 02213 /* do not mess with offset inside the switch! */ 02214 if (IsAtLeastTLSv1_2(ssl)) { 02215 ato16(input + offset, &suites->hashSigAlgoSz); 02216 02217 if (suites->hashSigAlgoSz > size - OPAQUE16_LEN) 02218 return BUFFER_ERROR; 02219 02220 XMEMCPY(suites->hashSigAlgo, 02221 input + offset + OPAQUE16_LEN, 02222 min(suites->hashSigAlgoSz, 02223 HELLO_EXT_SIGALGO_MAX)); 02224 } 02225 } else { 02226 CYASSL_MSG("Servers MUST NOT send SIG ALGO extension."); 02227 } 02228 02229 break; 02230 } 02231 02232 /* offset should be updated here! */ 02233 offset += size; 02234 } 02235 02236 return ret; 02237 } 02238 02239 /* undefining semaphore macros */ 02240 #undef IS_OFF 02241 #undef TURN_ON 02242 #undef SEMAPHORE_SIZE 02243 02244 #endif 02245 02246 02247 #ifndef NO_CYASSL_CLIENT 02248 02249 #ifndef NO_OLD_TLS 02250 02251 CYASSL_METHOD* CyaTLSv1_client_method(void) 02252 { 02253 CYASSL_METHOD* method = 02254 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 02255 DYNAMIC_TYPE_METHOD); 02256 if (method) 02257 InitSSL_Method(method, MakeTLSv1()); 02258 return method; 02259 } 02260 02261 02262 CYASSL_METHOD* CyaTLSv1_1_client_method(void) 02263 { 02264 CYASSL_METHOD* method = 02265 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 02266 DYNAMIC_TYPE_METHOD); 02267 if (method) 02268 InitSSL_Method(method, MakeTLSv1_1()); 02269 return method; 02270 } 02271 02272 #endif /* !NO_OLD_TLS */ 02273 02274 #ifndef NO_SHA256 /* can't use without SHA256 */ 02275 02276 CYASSL_METHOD* CyaTLSv1_2_client_method(void) 02277 { 02278 CYASSL_METHOD* method = 02279 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 02280 DYNAMIC_TYPE_METHOD); 02281 if (method) 02282 InitSSL_Method(method, MakeTLSv1_2()); 02283 return method; 02284 } 02285 02286 #endif 02287 02288 02289 CYASSL_METHOD* CyaSSLv23_client_method(void) 02290 { 02291 CYASSL_METHOD* method = 02292 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 02293 DYNAMIC_TYPE_METHOD); 02294 if (method) { 02295 #ifndef NO_SHA256 /* 1.2 requires SHA256 */ 02296 InitSSL_Method(method, MakeTLSv1_2()); 02297 #else 02298 InitSSL_Method(method, MakeTLSv1_1()); 02299 #endif 02300 #ifndef NO_OLD_TLS 02301 method->downgrade = 1; 02302 #endif 02303 } 02304 return method; 02305 } 02306 02307 02308 #endif /* NO_CYASSL_CLIENT */ 02309 02310 02311 02312 #ifndef NO_CYASSL_SERVER 02313 02314 #ifndef NO_OLD_TLS 02315 02316 CYASSL_METHOD* CyaTLSv1_server_method(void) 02317 { 02318 CYASSL_METHOD* method = 02319 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 02320 DYNAMIC_TYPE_METHOD); 02321 if (method) { 02322 InitSSL_Method(method, MakeTLSv1()); 02323 method->side = CYASSL_SERVER_END; 02324 } 02325 return method; 02326 } 02327 02328 02329 CYASSL_METHOD* CyaTLSv1_1_server_method(void) 02330 { 02331 CYASSL_METHOD* method = 02332 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 02333 DYNAMIC_TYPE_METHOD); 02334 if (method) { 02335 InitSSL_Method(method, MakeTLSv1_1()); 02336 method->side = CYASSL_SERVER_END; 02337 } 02338 return method; 02339 } 02340 02341 #endif /* !NO_OLD_TLS */ 02342 02343 #ifndef NO_SHA256 /* can't use without SHA256 */ 02344 02345 CYASSL_METHOD* CyaTLSv1_2_server_method(void) 02346 { 02347 CYASSL_METHOD* method = 02348 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 02349 DYNAMIC_TYPE_METHOD); 02350 if (method) { 02351 InitSSL_Method(method, MakeTLSv1_2()); 02352 method->side = CYASSL_SERVER_END; 02353 } 02354 return method; 02355 } 02356 02357 #endif 02358 02359 02360 CYASSL_METHOD* CyaSSLv23_server_method(void) 02361 { 02362 CYASSL_METHOD* method = 02363 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 02364 DYNAMIC_TYPE_METHOD); 02365 if (method) { 02366 #ifndef NO_SHA256 /* 1.2 requires SHA256 */ 02367 InitSSL_Method(method, MakeTLSv1_2()); 02368 #else 02369 InitSSL_Method(method, MakeTLSv1_1()); 02370 #endif 02371 method->side = CYASSL_SERVER_END; 02372 #ifndef NO_OLD_TLS 02373 method->downgrade = 1; 02374 #endif /* !NO_OLD_TLS */ 02375 } 02376 return method; 02377 } 02378 02379 02380 02381 #endif /* NO_CYASSL_SERVER */ 02382 #endif /* NO_TLS */ 02383
Generated on Wed Jul 13 2022 02:33:57 by
1.7.2