MultiTech / CyaSSL

Dependents:   HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tls.c Source File

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