This is a port of cyaSSL 2.7.0.
Dependents: CyaSSL_DTLS_Cellular CyaSSL_DTLS_Ethernet
tls.c
00001 /* tls.c 00002 * 00003 * Copyright (C) 2006-2013 wolfSSL Inc. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * CyaSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include <cyassl/ctaocrypt/settings.h> 00027 00028 #include <cyassl/ssl.h> 00029 #include <cyassl/internal.h> 00030 #include <cyassl/ctaoerror.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 void 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 byte previous[PHASH_MAX_DIGEST_SIZE]; /* max size */ 00065 byte current[PHASH_MAX_DIGEST_SIZE]; /* max size */ 00066 00067 Hmac hmac; 00068 00069 switch (hash) { 00070 #ifndef NO_MD5 00071 case md5_mac: 00072 { 00073 len = MD5_DIGEST_SIZE; 00074 hash = MD5; 00075 } 00076 break; 00077 #endif 00078 #ifndef NO_SHA256 00079 case sha256_mac: 00080 { 00081 len = SHA256_DIGEST_SIZE; 00082 hash = SHA256; 00083 } 00084 break; 00085 #endif 00086 #ifdef CYASSL_SHA384 00087 case sha384_mac: 00088 { 00089 len = SHA384_DIGEST_SIZE; 00090 hash = SHA384; 00091 } 00092 break; 00093 #endif 00094 #ifndef NO_SHA 00095 case sha_mac: 00096 default: 00097 { 00098 len = SHA_DIGEST_SIZE; 00099 hash = SHA; 00100 } 00101 break; 00102 #endif 00103 } 00104 00105 times = resLen / len; 00106 lastLen = resLen % len; 00107 if (lastLen) times += 1; 00108 lastTime = times - 1; 00109 00110 HmacSetKey(&hmac, hash, secret, secLen); 00111 HmacUpdate(&hmac, seed, seedLen); /* A0 = seed */ 00112 HmacFinal(&hmac, previous); /* A1 */ 00113 00114 for (i = 0; i < times; i++) { 00115 HmacUpdate(&hmac, previous, len); 00116 HmacUpdate(&hmac, seed, seedLen); 00117 HmacFinal(&hmac, current); 00118 00119 if ( (i == lastTime) && lastLen) 00120 XMEMCPY(&result[idx], current, min(lastLen, sizeof(current))); 00121 else { 00122 XMEMCPY(&result[idx], current, len); 00123 idx += len; 00124 HmacUpdate(&hmac, previous, len); 00125 HmacFinal(&hmac, previous); 00126 } 00127 } 00128 XMEMSET(previous, 0, sizeof previous); 00129 XMEMSET(current, 0, sizeof current); 00130 XMEMSET(&hmac, 0, sizeof hmac); 00131 } 00132 00133 00134 00135 #ifndef NO_OLD_TLS 00136 00137 /* calculate XOR for TLSv1 PRF */ 00138 static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha) 00139 { 00140 word32 i; 00141 00142 for (i = 0; i < digLen; i++) 00143 digest[i] = md5[i] ^ sha[i]; 00144 } 00145 00146 00147 /* compute TLSv1 PRF (pseudo random function using HMAC) */ 00148 static void doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen, 00149 const byte* label, word32 labLen, const byte* seed, word32 seedLen) 00150 { 00151 word32 half = (secLen + 1) / 2; 00152 00153 byte md5_half[MAX_PRF_HALF]; /* half is real size */ 00154 byte sha_half[MAX_PRF_HALF]; /* half is real size */ 00155 byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */ 00156 byte md5_result[MAX_PRF_DIG]; /* digLen is real size */ 00157 byte sha_result[MAX_PRF_DIG]; /* digLen is real size */ 00158 00159 if (half > MAX_PRF_HALF) 00160 return; 00161 if (labLen + seedLen > MAX_PRF_LABSEED) 00162 return; 00163 if (digLen > MAX_PRF_DIG) 00164 return; 00165 00166 XMEMSET(md5_result, 0, digLen); 00167 XMEMSET(sha_result, 0, digLen); 00168 00169 XMEMCPY(md5_half, secret, half); 00170 XMEMCPY(sha_half, secret + half - secLen % 2, half); 00171 00172 XMEMCPY(labelSeed, label, labLen); 00173 XMEMCPY(labelSeed + labLen, seed, seedLen); 00174 00175 p_hash(md5_result, digLen, md5_half, half, labelSeed, labLen + seedLen, 00176 md5_mac); 00177 p_hash(sha_result, digLen, sha_half, half, labelSeed, labLen + seedLen, 00178 sha_mac); 00179 get_xor(digest, digLen, md5_result, sha_result); 00180 } 00181 00182 #endif 00183 00184 00185 /* Wrapper to call straight thru to p_hash in TSL 1.2 cases to remove stack 00186 use */ 00187 static void PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen, 00188 const byte* label, word32 labLen, const byte* seed, word32 seedLen, 00189 int useAtLeastSha256, int hash_type) 00190 { 00191 if (useAtLeastSha256) { 00192 byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */ 00193 00194 if (labLen + seedLen > MAX_PRF_LABSEED) 00195 return; 00196 00197 XMEMCPY(labelSeed, label, labLen); 00198 XMEMCPY(labelSeed + labLen, seed, seedLen); 00199 00200 /* If a cipher suite wants an algorithm better than sha256, it 00201 * should use better. */ 00202 if (hash_type < sha256_mac) 00203 hash_type = sha256_mac; 00204 p_hash(digest, digLen, secret, secLen, labelSeed, labLen + seedLen, 00205 hash_type); 00206 } 00207 #ifndef NO_OLD_TLS 00208 else 00209 doPRF(digest, digLen, secret, secLen, label, labLen, seed, seedLen); 00210 #endif 00211 } 00212 00213 00214 #ifdef CYASSL_SHA384 00215 #define HSHASH_SZ SHA384_DIGEST_SIZE 00216 #else 00217 #define HSHASH_SZ FINISHED_SZ 00218 #endif 00219 00220 00221 void BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) 00222 { 00223 const byte* side; 00224 byte handshake_hash[HSHASH_SZ]; 00225 word32 hashSz = FINISHED_SZ; 00226 00227 #ifndef NO_OLD_TLS 00228 Md5Final(&ssl->hashMd5, handshake_hash); 00229 ShaFinal(&ssl->hashSha, &handshake_hash[MD5_DIGEST_SIZE]); 00230 #endif 00231 00232 if (IsAtLeastTLSv1_2(ssl)) { 00233 #ifndef NO_SHA256 00234 if (ssl->specs.mac_algorithm <= sha256_mac) { 00235 Sha256Final(&ssl->hashSha256, handshake_hash); 00236 hashSz = SHA256_DIGEST_SIZE; 00237 } 00238 #endif 00239 #ifdef CYASSL_SHA384 00240 if (ssl->specs.mac_algorithm == sha384_mac) { 00241 Sha384Final(&ssl->hashSha384, handshake_hash); 00242 hashSz = SHA384_DIGEST_SIZE; 00243 } 00244 #endif 00245 } 00246 00247 if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0) 00248 side = tls_client; 00249 else 00250 side = tls_server; 00251 00252 PRF((byte*)hashes, TLS_FINISHED_SZ, ssl->arrays->masterSecret, SECRET_LEN, 00253 side, FINISHED_LABEL_SZ, handshake_hash, hashSz, IsAtLeastTLSv1_2(ssl), 00254 ssl->specs.mac_algorithm); 00255 } 00256 00257 00258 #ifndef NO_OLD_TLS 00259 00260 ProtocolVersion MakeTLSv1(void) 00261 { 00262 ProtocolVersion pv; 00263 pv.major = SSLv3_MAJOR; 00264 pv.minor = TLSv1_MINOR; 00265 00266 return pv; 00267 } 00268 00269 00270 ProtocolVersion MakeTLSv1_1(void) 00271 { 00272 ProtocolVersion pv; 00273 pv.major = SSLv3_MAJOR; 00274 pv.minor = TLSv1_1_MINOR; 00275 00276 return pv; 00277 } 00278 00279 #endif 00280 00281 00282 ProtocolVersion MakeTLSv1_2(void) 00283 { 00284 ProtocolVersion pv; 00285 pv.major = SSLv3_MAJOR; 00286 pv.minor = TLSv1_2_MINOR; 00287 00288 return pv; 00289 } 00290 00291 00292 static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret"; 00293 static const byte key_label [KEY_LABEL_SZ + 1] = "key expansion"; 00294 00295 00296 int DeriveTlsKeys(CYASSL* ssl) 00297 { 00298 int length = 2 * ssl->specs.hash_size + 00299 2 * ssl->specs.key_size + 00300 2 * ssl->specs.iv_size; 00301 byte seed[SEED_LEN]; 00302 byte key_data[MAX_PRF_DIG]; 00303 00304 XMEMCPY(seed, ssl->arrays->serverRandom, RAN_LEN); 00305 XMEMCPY(&seed[RAN_LEN], ssl->arrays->clientRandom, RAN_LEN); 00306 00307 PRF(key_data, length, ssl->arrays->masterSecret, SECRET_LEN, key_label, 00308 KEY_LABEL_SZ, seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), 00309 ssl->specs.mac_algorithm); 00310 00311 return StoreKeys(ssl, key_data); 00312 } 00313 00314 00315 int MakeTlsMasterSecret(CYASSL* ssl) 00316 { 00317 byte seed[SEED_LEN]; 00318 00319 XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN); 00320 XMEMCPY(&seed[RAN_LEN], ssl->arrays->serverRandom, RAN_LEN); 00321 00322 PRF(ssl->arrays->masterSecret, SECRET_LEN, 00323 ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz, 00324 master_label, MASTER_LABEL_SZ, 00325 seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); 00326 00327 #ifdef SHOW_SECRETS 00328 { 00329 int i; 00330 printf("master secret: "); 00331 for (i = 0; i < SECRET_LEN; i++) 00332 printf("%02x", ssl->arrays->masterSecret[i]); 00333 printf("\n"); 00334 } 00335 #endif 00336 00337 return DeriveTlsKeys(ssl); 00338 } 00339 00340 00341 /* Used by EAP-TLS and EAP-TTLS to derive keying material from 00342 * the master_secret. */ 00343 int CyaSSL_make_eap_keys(CYASSL* ssl, void* msk, unsigned int len, 00344 const char* label) 00345 { 00346 byte seed[SEED_LEN]; 00347 00348 /* 00349 * As per RFC-5281, the order of the client and server randoms is reversed 00350 * from that used by the TLS protocol to derive keys. 00351 */ 00352 XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN); 00353 XMEMCPY(&seed[RAN_LEN], ssl->arrays->serverRandom, RAN_LEN); 00354 00355 PRF((byte*)msk, len, 00356 ssl->arrays->masterSecret, SECRET_LEN, 00357 (const byte *)label, (word32)strlen(label), 00358 seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); 00359 00360 return 0; 00361 } 00362 00363 00364 /*** next for static INLINE s copied from cyassl_int.c ***/ 00365 00366 /* convert 16 bit integer to opaque */ 00367 static INLINE void c16toa(word16 u16, byte* c) 00368 { 00369 c[0] = (u16 >> 8) & 0xff; 00370 c[1] = u16 & 0xff; 00371 } 00372 00373 /* convert opaque to 16 bit integer */ 00374 static INLINE void ato16(const byte* c, word16* u16) 00375 { 00376 *u16 = (c[0] << 8) | (c[1]); 00377 } 00378 00379 00380 /* convert 32 bit integer to opaque */ 00381 static INLINE void c32toa(word32 u32, byte* c) 00382 { 00383 c[0] = (u32 >> 24) & 0xff; 00384 c[1] = (u32 >> 16) & 0xff; 00385 c[2] = (u32 >> 8) & 0xff; 00386 c[3] = u32 & 0xff; 00387 } 00388 00389 00390 static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify) 00391 { 00392 #ifdef CYASSL_DTLS 00393 if (ssl->options.dtls) { 00394 if (verify) 00395 return ssl->keys.dtls_peer_sequence_number; /* explicit from peer */ 00396 else 00397 return ssl->keys.dtls_sequence_number - 1; /* already incremented */ 00398 } 00399 #endif 00400 if (verify) 00401 return ssl->keys.peer_sequence_number++; 00402 else 00403 return ssl->keys.sequence_number++; 00404 } 00405 00406 00407 #ifdef CYASSL_DTLS 00408 00409 static INLINE word32 GetEpoch(CYASSL* ssl, int verify) 00410 { 00411 if (verify) 00412 return ssl->keys.dtls_peer_epoch; 00413 else 00414 return ssl->keys.dtls_epoch; 00415 } 00416 00417 #endif /* CYASSL_DTLS */ 00418 00419 00420 static INLINE const byte* GetMacSecret(CYASSL* ssl, int verify) 00421 { 00422 if ( (ssl->options.side == CLIENT_END && !verify) || 00423 (ssl->options.side == SERVER_END && verify) ) 00424 return ssl->keys.client_write_MAC_secret; 00425 else 00426 return ssl->keys.server_write_MAC_secret; 00427 } 00428 00429 /*** end copy ***/ 00430 00431 00432 /* TLS type HMAC */ 00433 void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, 00434 int content, int verify) 00435 { 00436 Hmac hmac; 00437 byte seq[SEQ_SZ]; 00438 byte length[LENGTH_SZ]; 00439 byte inner[ENUM_LEN + VERSION_SZ + LENGTH_SZ]; /* type + version +len */ 00440 int type; 00441 00442 XMEMSET(seq, 0, SEQ_SZ); 00443 c16toa((word16)sz, length); 00444 #ifdef CYASSL_DTLS 00445 if (ssl->options.dtls) 00446 c16toa((word16)GetEpoch(ssl, verify), seq); 00447 #endif 00448 c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]); 00449 00450 switch (ssl->specs.mac_algorithm) { 00451 #ifndef NO_MD5 00452 case md5_mac: 00453 { 00454 type = MD5; 00455 } 00456 break; 00457 #endif 00458 #ifndef NO_SHA256 00459 case sha256_mac: 00460 { 00461 type = SHA256; 00462 } 00463 break; 00464 #endif 00465 #ifdef CYASSL_SHA384 00466 case sha384_mac: 00467 { 00468 type = SHA384; 00469 } 00470 break; 00471 #endif 00472 #ifndef NO_SHA 00473 case sha_mac: 00474 default: 00475 { 00476 type = SHA; 00477 } 00478 break; 00479 #endif 00480 } 00481 HmacSetKey(&hmac, type, GetMacSecret(ssl, verify), ssl->specs.hash_size); 00482 00483 HmacUpdate(&hmac, seq, SEQ_SZ); /* seq_num */ 00484 inner[0] = (byte)content; /* type */ 00485 inner[ENUM_LEN] = ssl->version.major; 00486 inner[ENUM_LEN + ENUM_LEN] = ssl->version.minor; /* version */ 00487 XMEMCPY(&inner[ENUM_LEN + VERSION_SZ], length, LENGTH_SZ); /* length */ 00488 HmacUpdate(&hmac, inner, sizeof(inner)); 00489 HmacUpdate(&hmac, in, sz); /* content */ 00490 HmacFinal(&hmac, digest); 00491 } 00492 00493 #ifdef HAVE_TLS_EXTENSIONS 00494 00495 static int TLSX_Append(TLSX** list, TLSX_Type type) 00496 { 00497 TLSX* extension; 00498 00499 if (list == NULL) /* won't check type since this function is static */ 00500 return BAD_FUNC_ARG; 00501 00502 if ((extension = XMALLOC(sizeof(TLSX), 0, DYNAMIC_TYPE_TLSX)) == NULL) 00503 return MEMORY_E; 00504 00505 extension->type = type; 00506 extension->data = NULL; 00507 extension->resp = 0; 00508 extension->next = *list; 00509 *list = extension; 00510 00511 return 0; 00512 } 00513 00514 #ifndef NO_CYASSL_SERVER 00515 00516 static void TLSX_SetResponse(CYASSL* ssl, TLSX_Type type) 00517 { 00518 TLSX *ext = TLSX_Find(ssl->extensions, type); 00519 00520 if (ext) 00521 ext->resp = 1; 00522 } 00523 00524 #endif 00525 00526 /* SNI - Server Name Indication */ 00527 00528 #ifdef HAVE_SNI 00529 00530 static void TLSX_SNI_Free(SNI* sni) 00531 { 00532 if (sni) { 00533 switch (sni->type) { 00534 case CYASSL_SNI_HOST_NAME: 00535 XFREE(sni->data.host_name, 0, DYNAMIC_TYPE_TLSX); 00536 break; 00537 } 00538 00539 XFREE(sni, 0, DYNAMIC_TYPE_TLSX); 00540 } 00541 } 00542 00543 static void TLSX_SNI_FreeAll(SNI* list) 00544 { 00545 SNI* sni; 00546 00547 while ((sni = list)) { 00548 list = sni->next; 00549 TLSX_SNI_Free(sni); 00550 } 00551 } 00552 00553 static int TLSX_SNI_Append(SNI** list, byte type, const void* data, word16 size) 00554 { 00555 SNI* sni; 00556 00557 if (list == NULL) 00558 return BAD_FUNC_ARG; 00559 00560 if ((sni = XMALLOC(sizeof(SNI), 0, DYNAMIC_TYPE_TLSX)) == NULL) 00561 return MEMORY_E; 00562 00563 switch (type) { 00564 case CYASSL_SNI_HOST_NAME: { 00565 sni->data.host_name = XMALLOC(size + 1, 0, DYNAMIC_TYPE_TLSX); 00566 00567 if (sni->data.host_name) { 00568 XSTRNCPY(sni->data.host_name, (const char*) data, size); 00569 sni->data.host_name[size] = 0; 00570 } else { 00571 XFREE(sni, 0, DYNAMIC_TYPE_TLSX); 00572 return MEMORY_E; 00573 } 00574 } 00575 break; 00576 00577 default: /* invalid type */ 00578 XFREE(sni, 0, DYNAMIC_TYPE_TLSX); 00579 return BAD_FUNC_ARG; 00580 break; 00581 } 00582 00583 sni->type = type; 00584 sni->next = *list; 00585 00586 #ifndef NO_CYASSL_SERVER 00587 sni->options = 0; 00588 sni->matched = 0; 00589 #endif 00590 00591 *list = sni; 00592 00593 return 0; 00594 } 00595 00596 static word16 TLSX_SNI_GetSize(SNI* list) 00597 { 00598 SNI* sni; 00599 word16 length = OPAQUE16_LEN; /* list length */ 00600 00601 while ((sni = list)) { 00602 list = sni->next; 00603 00604 length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */ 00605 00606 switch (sni->type) { 00607 case CYASSL_SNI_HOST_NAME: 00608 length += XSTRLEN((char*) sni->data.host_name); 00609 break; 00610 } 00611 } 00612 00613 return length; 00614 } 00615 00616 static word16 TLSX_SNI_Write(SNI* list, byte* output) 00617 { 00618 SNI* sni; 00619 word16 length = 0; 00620 word16 offset = OPAQUE16_LEN; /* list length offset */ 00621 00622 while ((sni = list)) { 00623 list = sni->next; 00624 00625 output[offset++] = sni->type; /* sni type */ 00626 00627 switch (sni->type) { 00628 case CYASSL_SNI_HOST_NAME: 00629 length = XSTRLEN((char*) sni->data.host_name); 00630 00631 c16toa(length, output + offset); /* sni length */ 00632 offset += OPAQUE16_LEN; 00633 00634 XMEMCPY(output + offset, sni->data.host_name, length); 00635 00636 offset += length; 00637 break; 00638 } 00639 } 00640 00641 c16toa(offset - OPAQUE16_LEN, output); /* writing list length */ 00642 00643 return offset; 00644 } 00645 00646 static SNI* TLSX_SNI_Find(SNI *list, byte type) 00647 { 00648 SNI *sni = list; 00649 00650 while (sni && sni->type != type) 00651 sni = sni->next; 00652 00653 return sni; 00654 } 00655 00656 #ifndef NO_CYASSL_SERVER 00657 static void TLSX_SNI_SetMatched(TLSX* extensions, byte type) 00658 { 00659 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); 00660 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); 00661 00662 if (sni) { 00663 sni->matched = 1; 00664 CYASSL_MSG("SNI did match!"); 00665 } 00666 } 00667 00668 byte TLSX_SNI_Matched(TLSX* extensions, byte type) 00669 { 00670 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); 00671 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); 00672 00673 if (sni) 00674 return sni->matched; 00675 00676 return 0; 00677 } 00678 #endif 00679 00680 static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length, 00681 byte isRequest) 00682 { 00683 #ifndef NO_CYASSL_SERVER 00684 word16 size = 0; 00685 word16 offset = 0; 00686 #endif 00687 00688 TLSX *extension = TLSX_Find(ssl->extensions, SERVER_NAME_INDICATION); 00689 00690 if (!extension) 00691 extension = TLSX_Find(ssl->ctx->extensions, SERVER_NAME_INDICATION); 00692 00693 if (!extension || !extension->data) { 00694 if (!isRequest) { 00695 CYASSL_MSG("Unexpected SNI response from server"); 00696 } 00697 00698 return 0; /* not using SNI */ 00699 } 00700 00701 if (!isRequest) { 00702 if (length) { 00703 CYASSL_MSG("SNI response should be empty!"); 00704 } 00705 00706 return 0; /* nothing to do */ 00707 } 00708 00709 #ifndef NO_CYASSL_SERVER 00710 00711 if (OPAQUE16_LEN > length) 00712 return INCOMPLETE_DATA; 00713 00714 ato16(input, &size); 00715 offset += OPAQUE16_LEN; 00716 00717 /* validating sni list length */ 00718 if (length != OPAQUE16_LEN + size) 00719 return INCOMPLETE_DATA; 00720 00721 for (size = 0; offset < length; offset += size) { 00722 SNI *sni; 00723 byte type = input[offset++]; 00724 00725 if (offset + OPAQUE16_LEN > length) 00726 return INCOMPLETE_DATA; 00727 00728 ato16(input + offset, &size); 00729 offset += OPAQUE16_LEN; 00730 00731 if (offset + size > length) 00732 return INCOMPLETE_DATA; 00733 00734 if (!(sni = TLSX_SNI_Find((SNI *) extension->data, type))) { 00735 continue; /* not using this SNI type */ 00736 } 00737 00738 switch(type) { 00739 case CYASSL_SNI_HOST_NAME: { 00740 byte matched = (XSTRLEN(sni->data.host_name) == size) 00741 && (XSTRNCMP(sni->data.host_name, 00742 (const char *) input + offset, size) == 0); 00743 00744 if (matched || sni->options & CYASSL_SNI_ANSWER_ON_MISMATCH) { 00745 int r = TLSX_UseSNI(&ssl->extensions, type, (byte *) "", 0); 00746 00747 if (r) return r; /* throw error */ 00748 00749 if (matched) TLSX_SNI_SetMatched(ssl->extensions, type); 00750 } else if (!(sni->options & CYASSL_SNI_CONTINUE_ON_MISMATCH)) { 00751 SendAlert(ssl, alert_fatal, unrecognized_name); 00752 00753 return UNKNOWN_SNI_HOST_NAME_E; 00754 } 00755 break; 00756 } 00757 } 00758 00759 TLSX_SetResponse(ssl, SERVER_NAME_INDICATION); 00760 } 00761 00762 #endif 00763 00764 return 0; 00765 } 00766 00767 int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size) 00768 { 00769 TLSX* extension = NULL; 00770 SNI* sni = NULL; 00771 int ret = 0; 00772 00773 if (extensions == NULL || data == NULL) 00774 return BAD_FUNC_ARG; 00775 00776 if ((ret = TLSX_SNI_Append(&sni, type, data, size)) != 0) 00777 return ret; 00778 00779 extension = *extensions; 00780 00781 /* find SNI extension if it already exists. */ 00782 while (extension && extension->type != SERVER_NAME_INDICATION) 00783 extension = extension->next; 00784 00785 /* push new SNI extension if it doesn't exists. */ 00786 if (!extension) { 00787 if ((ret = TLSX_Append(extensions, SERVER_NAME_INDICATION)) != 0) { 00788 TLSX_SNI_Free(sni); 00789 return ret; 00790 } 00791 00792 extension = *extensions; 00793 } 00794 00795 /* push new SNI object to extension data. */ 00796 sni->next = (SNI*) extension->data; 00797 extension->data = (void*) sni; 00798 00799 /* look for another server name of the same type to remove (replacement) */ 00800 while ((sni = sni->next)) { 00801 if (sni->next && sni->next->type == type) { 00802 SNI *next = sni->next; 00803 00804 sni->next = next->next; 00805 TLSX_SNI_Free(next); 00806 00807 break; 00808 } 00809 } 00810 00811 return 0; 00812 } 00813 00814 #ifndef NO_CYASSL_SERVER 00815 void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options) 00816 { 00817 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); 00818 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); 00819 00820 if (sni) 00821 sni->options = options; 00822 } 00823 #endif 00824 00825 #define SNI_FREE_ALL TLSX_SNI_FreeAll 00826 #define SNI_GET_SIZE TLSX_SNI_GetSize 00827 #define SNI_WRITE TLSX_SNI_Write 00828 #define SNI_PARSE TLSX_SNI_Parse 00829 00830 #else 00831 00832 #define SNI_FREE_ALL(x) 00833 #define SNI_GET_SIZE(x) 0 00834 #define SNI_WRITE(x) 0 00835 #define SNI_PARSE(x) 0 00836 00837 #endif /* HAVE_SNI */ 00838 00839 TLSX* TLSX_Find(TLSX* list, TLSX_Type type) 00840 { 00841 TLSX* extension = list; 00842 00843 while (extension && extension->type != type) 00844 extension = extension->next; 00845 00846 return extension; 00847 } 00848 00849 void TLSX_FreeAll(TLSX* list) 00850 { 00851 TLSX* extension; 00852 00853 while ((extension = list)) { 00854 list = extension->next; 00855 00856 switch (extension->type) { 00857 case SERVER_NAME_INDICATION: 00858 SNI_FREE_ALL((SNI *) extension->data); 00859 break; 00860 } 00861 00862 XFREE(extension, 0, DYNAMIC_TYPE_TLSX); 00863 } 00864 } 00865 00866 #define IS_OFF(semaphore, light) \ 00867 ((semaphore)[(light) / 8] ^ (byte) (0x01 << ((light) % 8))) 00868 00869 #define TURN_ON(semaphore, light) \ 00870 ((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8))) 00871 00872 static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest) 00873 { 00874 TLSX* extension; 00875 word16 length = 0; 00876 00877 while ((extension = list)) { 00878 list = extension->next; 00879 00880 if (!isRequest && !extension->resp) 00881 continue; /* skip! */ 00882 00883 if (IS_OFF(semaphore, extension->type)) { 00884 /* type + data length */ 00885 length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN; 00886 00887 switch (extension->type) { 00888 case SERVER_NAME_INDICATION: 00889 if (isRequest) 00890 length += SNI_GET_SIZE((SNI *) extension->data); 00891 break; 00892 } 00893 00894 TURN_ON(semaphore, extension->type); 00895 } 00896 } 00897 00898 return length; 00899 } 00900 00901 static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore, 00902 byte isRequest) 00903 { 00904 TLSX* extension; 00905 word16 offset = 0; 00906 word16 length_offset = 0; 00907 00908 while ((extension = list)) { 00909 list = extension->next; 00910 00911 if (!isRequest && !extension->resp) 00912 continue; /* skip! */ 00913 00914 if (IS_OFF(semaphore, extension->type)) { 00915 /* extension type */ 00916 c16toa(extension->type, output + offset); 00917 offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN; 00918 length_offset = offset; 00919 00920 /* extension data should be written internally */ 00921 switch (extension->type) { 00922 case SERVER_NAME_INDICATION: 00923 if (isRequest) 00924 offset += SNI_WRITE((SNI *) extension->data, 00925 output + offset); 00926 break; 00927 } 00928 00929 /* writing extension data length */ 00930 c16toa(offset - length_offset, 00931 output + length_offset - OPAQUE16_LEN); 00932 00933 TURN_ON(semaphore, extension->type); 00934 } 00935 } 00936 00937 return offset; 00938 } 00939 00940 #ifndef NO_CYASSL_CLIENT 00941 00942 word16 TLSX_GetRequestSize(CYASSL* ssl) 00943 { 00944 word16 length = 0; 00945 00946 if (ssl && IsTLS(ssl)) { 00947 byte semaphore[16] = {0}; 00948 00949 if (ssl->extensions) 00950 length += TLSX_GetSize(ssl->extensions, semaphore, 1); 00951 00952 if (ssl->ctx && ssl->ctx->extensions) 00953 length += TLSX_GetSize(ssl->ctx->extensions, semaphore, 1); 00954 00955 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) 00956 length += ssl->suites->hashSigAlgoSz + HELLO_EXT_LEN; 00957 } 00958 00959 if (length) 00960 length += OPAQUE16_LEN; /* for total length storage */ 00961 00962 return length; 00963 } 00964 00965 word16 TLSX_WriteRequest(CYASSL* ssl, byte* output) 00966 { 00967 word16 offset = 0; 00968 00969 if (ssl && IsTLS(ssl) && output) { 00970 byte semaphore[16] = {0}; 00971 00972 offset += OPAQUE16_LEN; /* extensions length */ 00973 00974 if (ssl->extensions) 00975 offset += TLSX_Write(ssl->extensions, output + offset, 00976 semaphore, 1); 00977 00978 if (ssl->ctx && ssl->ctx->extensions) 00979 offset += TLSX_Write(ssl->ctx->extensions, output + offset, 00980 semaphore, 1); 00981 00982 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) 00983 { 00984 int i; 00985 /* extension type */ 00986 c16toa(HELLO_EXT_SIG_ALGO, output + offset); 00987 offset += HELLO_EXT_TYPE_SZ; 00988 00989 /* extension data length */ 00990 c16toa(OPAQUE16_LEN + ssl->suites->hashSigAlgoSz, output + offset); 00991 offset += OPAQUE16_LEN; 00992 00993 /* sig algos length */ 00994 c16toa(ssl->suites->hashSigAlgoSz, output + offset); 00995 offset += OPAQUE16_LEN; 00996 00997 /* sig algos */ 00998 for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, offset++) 00999 output[offset] = ssl->suites->hashSigAlgo[i]; 01000 } 01001 01002 if (offset > OPAQUE16_LEN) 01003 c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ 01004 } 01005 01006 return offset; 01007 } 01008 01009 #endif /* NO_CYASSL_CLIENT */ 01010 01011 #ifndef NO_CYASSL_SERVER 01012 01013 word16 TLSX_GetResponseSize(CYASSL* ssl) 01014 { 01015 word16 length = 0; 01016 byte semaphore[16] = {0}; 01017 01018 if (ssl && IsTLS(ssl)) 01019 length += TLSX_GetSize(ssl->extensions, semaphore, 0); 01020 01021 /* All the response data is set at the ssl object only, so no ctx here. */ 01022 01023 if (length) 01024 length += OPAQUE16_LEN; /* for total length storage */ 01025 01026 return length; 01027 } 01028 01029 word16 TLSX_WriteResponse(CYASSL *ssl, byte* output) 01030 { 01031 word16 offset = 0; 01032 01033 if (ssl && IsTLS(ssl) && output) { 01034 byte semaphore[16] = {0}; 01035 01036 offset += OPAQUE16_LEN; /* extensions length */ 01037 01038 offset += TLSX_Write(ssl->extensions, output + offset, semaphore, 0); 01039 01040 if (offset > OPAQUE16_LEN) 01041 c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ 01042 } 01043 01044 return offset; 01045 } 01046 01047 #endif /* NO_CYASSL_SERVER */ 01048 01049 int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest, 01050 Suites *suites) 01051 { 01052 int ret = 0; 01053 word16 offset = 0; 01054 01055 if (!ssl || !input || !suites) 01056 return BAD_FUNC_ARG; 01057 01058 while (ret == 0 && offset < length) { 01059 word16 type; 01060 word16 size; 01061 01062 if (length - offset < HELLO_EXT_TYPE_SZ + OPAQUE16_LEN) 01063 return INCOMPLETE_DATA; 01064 01065 ato16(input + offset, &type); 01066 offset += HELLO_EXT_TYPE_SZ; 01067 01068 ato16(input + offset, &size); 01069 offset += OPAQUE16_LEN; 01070 01071 if (offset + size > length) 01072 return INCOMPLETE_DATA; 01073 01074 switch (type) { 01075 case SERVER_NAME_INDICATION: 01076 CYASSL_MSG("SNI extension received"); 01077 01078 ret = SNI_PARSE(ssl, input + offset, size, isRequest); 01079 break; 01080 01081 case HELLO_EXT_SIG_ALGO: 01082 if (isRequest) { 01083 /* do not mess with offset inside the switch! */ 01084 if (IsAtLeastTLSv1_2(ssl)) { 01085 ato16(input + offset, &suites->hashSigAlgoSz); 01086 01087 if (suites->hashSigAlgoSz > size - OPAQUE16_LEN) 01088 return INCOMPLETE_DATA; 01089 01090 XMEMCPY(suites->hashSigAlgo, 01091 input + offset + OPAQUE16_LEN, 01092 min(suites->hashSigAlgoSz, 01093 HELLO_EXT_SIGALGO_MAX)); 01094 } 01095 } else { 01096 CYASSL_MSG("Servers MUST NOT send SIG ALGO extension."); 01097 } 01098 01099 break; 01100 } 01101 01102 /* offset should be updated here! */ 01103 offset += size; 01104 } 01105 01106 return ret; 01107 } 01108 01109 /* undefining semaphore macros */ 01110 #undef IS_OFF 01111 #undef TURN_ON 01112 01113 #endif /* HAVE_TLS_EXTENSIONS */ 01114 01115 01116 #ifndef NO_CYASSL_CLIENT 01117 01118 #ifndef NO_OLD_TLS 01119 01120 CYASSL_METHOD* CyaTLSv1_client_method(void) 01121 { 01122 CYASSL_METHOD* method = 01123 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01124 DYNAMIC_TYPE_METHOD); 01125 if (method) 01126 InitSSL_Method(method, MakeTLSv1()); 01127 return method; 01128 } 01129 01130 01131 CYASSL_METHOD* CyaTLSv1_1_client_method(void) 01132 { 01133 CYASSL_METHOD* method = 01134 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01135 DYNAMIC_TYPE_METHOD); 01136 if (method) 01137 InitSSL_Method(method, MakeTLSv1_1()); 01138 return method; 01139 } 01140 01141 #endif /* !NO_OLD_TLS */ 01142 01143 #ifndef NO_SHA256 /* can't use without SHA256 */ 01144 01145 CYASSL_METHOD* CyaTLSv1_2_client_method(void) 01146 { 01147 CYASSL_METHOD* method = 01148 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01149 DYNAMIC_TYPE_METHOD); 01150 if (method) 01151 InitSSL_Method(method, MakeTLSv1_2()); 01152 return method; 01153 } 01154 01155 #endif 01156 01157 01158 CYASSL_METHOD* CyaSSLv23_client_method(void) 01159 { 01160 CYASSL_METHOD* method = 01161 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01162 DYNAMIC_TYPE_METHOD); 01163 if (method) { 01164 #ifndef NO_SHA256 /* 1.2 requires SHA256 */ 01165 InitSSL_Method(method, MakeTLSv1_2()); 01166 #else 01167 InitSSL_Method(method, MakeTLSv1_1()); 01168 #endif 01169 #ifndef NO_OLD_TLS 01170 method->downgrade = 1; 01171 #endif 01172 } 01173 return method; 01174 } 01175 01176 01177 #endif /* NO_CYASSL_CLIENT */ 01178 01179 01180 01181 #ifndef NO_CYASSL_SERVER 01182 01183 #ifndef NO_OLD_TLS 01184 01185 CYASSL_METHOD* CyaTLSv1_server_method(void) 01186 { 01187 CYASSL_METHOD* method = 01188 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01189 DYNAMIC_TYPE_METHOD); 01190 if (method) { 01191 InitSSL_Method(method, MakeTLSv1()); 01192 method->side = SERVER_END; 01193 } 01194 return method; 01195 } 01196 01197 01198 CYASSL_METHOD* CyaTLSv1_1_server_method(void) 01199 { 01200 CYASSL_METHOD* method = 01201 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01202 DYNAMIC_TYPE_METHOD); 01203 if (method) { 01204 InitSSL_Method(method, MakeTLSv1_1()); 01205 method->side = SERVER_END; 01206 } 01207 return method; 01208 } 01209 01210 #endif /* !NO_OLD_TLS */ 01211 01212 #ifndef NO_SHA256 /* can't use without SHA256 */ 01213 01214 CYASSL_METHOD* CyaTLSv1_2_server_method(void) 01215 { 01216 CYASSL_METHOD* method = 01217 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01218 DYNAMIC_TYPE_METHOD); 01219 if (method) { 01220 InitSSL_Method(method, MakeTLSv1_2()); 01221 method->side = SERVER_END; 01222 } 01223 return method; 01224 } 01225 01226 #endif 01227 01228 01229 CYASSL_METHOD* CyaSSLv23_server_method(void) 01230 { 01231 CYASSL_METHOD* method = 01232 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0, 01233 DYNAMIC_TYPE_METHOD); 01234 if (method) { 01235 #ifndef NO_SHA256 /* 1.2 requires SHA256 */ 01236 InitSSL_Method(method, MakeTLSv1_2()); 01237 #else 01238 InitSSL_Method(method, MakeTLSv1_1()); 01239 #endif 01240 method->side = SERVER_END; 01241 #ifndef NO_OLD_TLS 01242 method->downgrade = 1; 01243 #endif /* !NO_OLD_TLS */ 01244 } 01245 return method; 01246 } 01247 01248 01249 01250 #endif /* NO_CYASSL_SERVER */ 01251 #endif /* NO_TLS */ 01252
Generated on Tue Jul 12 2022 20:44:52 by 1.7.2