Renesas / SecureDweet
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-2016 wolfSSL Inc.
00004  *
00005  * This file is part of wolfSSL.
00006  *
00007  * wolfSSL 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  * wolfSSL 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-1335, USA
00020  */
00021 
00022 
00023 
00024 #ifdef HAVE_CONFIG_H
00025     #include <config.h>
00026 #endif
00027 
00028 #include <wolfssl/wolfcrypt/settings.h>
00029 
00030 #ifndef WOLFCRYPT_ONLY
00031 
00032 #include <wolfssl/ssl.h>
00033 #include <wolfssl/internal.h>
00034 #include <wolfssl/error-ssl.h>
00035 #include <wolfssl/wolfcrypt/hmac.h>
00036 #ifdef NO_INLINE
00037     #include <wolfssl/wolfcrypt/misc.h>
00038 #else
00039     #include <wolfcrypt/src/misc.c>
00040 #endif
00041 
00042 #ifdef HAVE_NTRU
00043     #include "libntruencrypt/ntru_crypto.h"
00044     #include <wolfssl/wolfcrypt/random.h>
00045 #endif
00046 #ifdef HAVE_QSH
00047     static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key);
00048     static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name);
00049     static int TLSX_CreateNtruKey(WOLFSSL* ssl, int type);
00050 #endif
00051 
00052 
00053 #ifndef NO_TLS
00054 
00055 
00056 #ifndef WOLFSSL_HAVE_MIN
00057 #define WOLFSSL_HAVE_MIN
00058 
00059     static INLINE word32 min(word32 a, word32 b)
00060     {
00061         return a > b ? b : a;
00062     }
00063 
00064 #endif /* WOLFSSL_HAVE_MIN */
00065 
00066 
00067 #ifdef WOLFSSL_SHA384
00068     #define P_HASH_MAX_SIZE SHA384_DIGEST_SIZE
00069 #else
00070     #define P_HASH_MAX_SIZE SHA256_DIGEST_SIZE
00071 #endif
00072 
00073 /* compute p_hash for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1 PRF */
00074 static int p_hash(byte* result, word32 resLen, const byte* secret,
00075                    word32 secLen, const byte* seed, word32 seedLen, int hash)
00076 {
00077     word32 len = P_HASH_MAX_SIZE;
00078     word32 times;
00079     word32 lastLen;
00080     word32 lastTime;
00081     word32 i;
00082     word32 idx = 0;
00083     int    ret = 0;
00084 #ifdef WOLFSSL_SMALL_STACK
00085     byte*  previous;
00086     byte*  current;
00087     Hmac*  hmac;
00088 #else
00089     byte   previous[P_HASH_MAX_SIZE];  /* max size */
00090     byte   current[P_HASH_MAX_SIZE];   /* max size */
00091     Hmac   hmac[1];
00092 #endif
00093 
00094 #ifdef WOLFSSL_SMALL_STACK
00095     previous = (byte*)XMALLOC(P_HASH_MAX_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00096     current  = (byte*)XMALLOC(P_HASH_MAX_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00097     hmac     = (Hmac*)XMALLOC(sizeof(Hmac),    NULL, DYNAMIC_TYPE_TMP_BUFFER);
00098 
00099     if (previous == NULL || current == NULL || hmac == NULL) {
00100         if (previous) XFREE(previous, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00101         if (current)  XFREE(current,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
00102         if (hmac)     XFREE(hmac,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
00103 
00104         return MEMORY_E;
00105     }
00106 #endif
00107 
00108     switch (hash) {
00109         #ifndef NO_MD5
00110             case md5_mac:
00111                 hash = MD5;
00112                 len  = MD5_DIGEST_SIZE;
00113             break;
00114         #endif
00115 
00116         #ifndef NO_SHA256
00117             case sha256_mac:
00118                 hash = SHA256;
00119                 len  = SHA256_DIGEST_SIZE;
00120             break;
00121         #endif
00122 
00123         #ifdef WOLFSSL_SHA384
00124             case sha384_mac:
00125                 hash = SHA384;
00126                 len  = SHA384_DIGEST_SIZE;
00127             break;
00128         #endif
00129 
00130         #ifndef NO_SHA
00131             case sha_mac:
00132             default:
00133                 hash = SHA;
00134                 len  = SHA_DIGEST_SIZE;
00135             break;
00136         #endif
00137     }
00138 
00139     times   = resLen / len;
00140     lastLen = resLen % len;
00141 
00142     if (lastLen)
00143         times += 1;
00144 
00145     lastTime = times - 1;
00146 
00147     if ((ret = wc_HmacSetKey(hmac, hash, secret, secLen)) == 0) {
00148         if ((ret = wc_HmacUpdate(hmac, seed, seedLen)) == 0) { /* A0 = seed */
00149             if ((ret = wc_HmacFinal(hmac, previous)) == 0) {   /* A1 */
00150                 for (i = 0; i < times; i++) {
00151                     ret = wc_HmacUpdate(hmac, previous, len);
00152                     if (ret != 0)
00153                         break;
00154                     ret = wc_HmacUpdate(hmac, seed, seedLen);
00155                     if (ret != 0)
00156                         break;
00157                     ret = wc_HmacFinal(hmac, current);
00158                     if (ret != 0)
00159                         break;
00160 
00161                     if ((i == lastTime) && lastLen)
00162                         XMEMCPY(&result[idx], current,
00163                                                  min(lastLen, P_HASH_MAX_SIZE));
00164                     else {
00165                         XMEMCPY(&result[idx], current, len);
00166                         idx += len;
00167                         ret = wc_HmacUpdate(hmac, previous, len);
00168                         if (ret != 0)
00169                             break;
00170                         ret = wc_HmacFinal(hmac, previous);
00171                         if (ret != 0)
00172                             break;
00173                     }
00174                 }
00175             }
00176         }
00177     }
00178 
00179     ForceZero(previous,  P_HASH_MAX_SIZE);
00180     ForceZero(current,   P_HASH_MAX_SIZE);
00181     ForceZero(hmac,      sizeof(Hmac));
00182 
00183 #ifdef WOLFSSL_SMALL_STACK
00184     XFREE(previous, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00185     XFREE(current,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
00186     XFREE(hmac,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
00187 #endif
00188 
00189     return ret;
00190 }
00191 
00192 #undef P_HASH_MAX_SIZE
00193 
00194 
00195 #ifndef NO_OLD_TLS
00196 
00197 /* calculate XOR for TLSv1 PRF */
00198 static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha)
00199 {
00200     word32 i;
00201 
00202     for (i = 0; i < digLen; i++)
00203         digest[i] = md5[i] ^ sha[i];
00204 }
00205 
00206 
00207 /* compute TLSv1 PRF (pseudo random function using HMAC) */
00208 static int doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen,
00209                  const byte* label, word32 labLen, const byte* seed,
00210                  word32 seedLen)
00211 {
00212     int    ret  = 0;
00213     word32 half = (secLen + 1) / 2;
00214 
00215 #ifdef WOLFSSL_SMALL_STACK
00216     byte* md5_half;
00217     byte* sha_half;
00218     byte* labelSeed;
00219     byte* md5_result;
00220     byte* sha_result;
00221 #else
00222     byte  md5_half[MAX_PRF_HALF];     /* half is real size */
00223     byte  sha_half[MAX_PRF_HALF];     /* half is real size */
00224     byte  labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */
00225     byte  md5_result[MAX_PRF_DIG];    /* digLen is real size */
00226     byte  sha_result[MAX_PRF_DIG];    /* digLen is real size */
00227 #endif
00228 
00229     if (half > MAX_PRF_HALF)
00230         return BUFFER_E;
00231     if (labLen + seedLen > MAX_PRF_LABSEED)
00232         return BUFFER_E;
00233     if (digLen > MAX_PRF_DIG)
00234         return BUFFER_E;
00235 
00236 #ifdef WOLFSSL_SMALL_STACK
00237     md5_half   = (byte*)XMALLOC(MAX_PRF_HALF,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
00238     sha_half   = (byte*)XMALLOC(MAX_PRF_HALF,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
00239     labelSeed  = (byte*)XMALLOC(MAX_PRF_LABSEED, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00240     md5_result = (byte*)XMALLOC(MAX_PRF_DIG,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
00241     sha_result = (byte*)XMALLOC(MAX_PRF_DIG,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
00242 
00243     if (md5_half == NULL || sha_half == NULL || labelSeed == NULL ||
00244                                      md5_result == NULL || sha_result == NULL) {
00245         if (md5_half)   XFREE(md5_half,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
00246         if (sha_half)   XFREE(sha_half,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
00247         if (labelSeed)  XFREE(labelSeed,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
00248         if (md5_result) XFREE(md5_result, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00249         if (sha_result) XFREE(sha_result, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00250 
00251         return MEMORY_E;
00252     }
00253 #endif
00254 
00255     XMEMSET(md5_result, 0, digLen);
00256     XMEMSET(sha_result, 0, digLen);
00257 
00258     XMEMCPY(md5_half, secret, half);
00259     XMEMCPY(sha_half, secret + half - secLen % 2, half);
00260 
00261     XMEMCPY(labelSeed, label, labLen);
00262     XMEMCPY(labelSeed + labLen, seed, seedLen);
00263 
00264     if ((ret = p_hash(md5_result, digLen, md5_half, half, labelSeed,
00265                                              labLen + seedLen, md5_mac)) == 0) {
00266         if ((ret = p_hash(sha_result, digLen, sha_half, half, labelSeed,
00267                                              labLen + seedLen, sha_mac)) == 0) {
00268             get_xor(digest, digLen, md5_result, sha_result);
00269         }
00270     }
00271 
00272 #ifdef WOLFSSL_SMALL_STACK
00273     XFREE(md5_half,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
00274     XFREE(sha_half,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
00275     XFREE(labelSeed,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
00276     XFREE(md5_result, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00277     XFREE(sha_result, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00278 #endif
00279 
00280     return ret;
00281 }
00282 
00283 #endif
00284 
00285 
00286 /* Wrapper to call straight thru to p_hash in TSL 1.2 cases to remove stack
00287    use */
00288 static int PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen,
00289             const byte* label, word32 labLen, const byte* seed, word32 seedLen,
00290             int useAtLeastSha256, int hash_type)
00291 {
00292     int ret = 0;
00293 
00294     if (useAtLeastSha256) {
00295 #ifdef WOLFSSL_SMALL_STACK
00296         byte* labelSeed;
00297 #else
00298         byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */
00299 #endif
00300 
00301         if (labLen + seedLen > MAX_PRF_LABSEED)
00302             return BUFFER_E;
00303 
00304 #ifdef WOLFSSL_SMALL_STACK
00305         labelSeed = (byte*)XMALLOC(MAX_PRF_LABSEED, NULL,
00306                                                        DYNAMIC_TYPE_TMP_BUFFER);
00307         if (labelSeed == NULL)
00308            return MEMORY_E;
00309 #endif
00310 
00311         XMEMCPY(labelSeed, label, labLen);
00312         XMEMCPY(labelSeed + labLen, seed, seedLen);
00313 
00314         /* If a cipher suite wants an algorithm better than sha256, it
00315          * should use better. */
00316         if (hash_type < sha256_mac || hash_type == blake2b_mac)
00317             hash_type = sha256_mac;
00318         ret = p_hash(digest, digLen, secret, secLen, labelSeed,
00319                      labLen + seedLen, hash_type);
00320 
00321 #ifdef WOLFSSL_SMALL_STACK
00322         XFREE(labelSeed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00323 #endif
00324     }
00325 #ifndef NO_OLD_TLS
00326     else {
00327         ret = doPRF(digest, digLen, secret, secLen, label, labLen, seed,
00328                     seedLen);
00329     }
00330 #endif
00331 
00332     return ret;
00333 }
00334 
00335 
00336 #ifdef WOLFSSL_SHA384
00337     #define HSHASH_SZ SHA384_DIGEST_SIZE
00338 #else
00339     #define HSHASH_SZ FINISHED_SZ
00340 #endif
00341 
00342 
00343 int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
00344 {
00345     const byte* side;
00346     byte        handshake_hash[HSHASH_SZ];
00347     word32      hashSz = FINISHED_SZ;
00348 
00349 #ifndef NO_OLD_TLS
00350     wc_Md5GetHash(&ssl->hsHashes->hashMd5, handshake_hash);
00351     wc_ShaGetHash(&ssl->hsHashes->hashSha, &handshake_hash[MD5_DIGEST_SIZE]);
00352 #endif
00353 
00354     if (IsAtLeastTLSv1_2(ssl)) {
00355 #ifndef NO_SHA256
00356         if (ssl->specs.mac_algorithm <= sha256_mac || ssl->specs.mac_algorithm == blake2b_mac) {
00357             int ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256,handshake_hash);
00358 
00359             if (ret != 0)
00360                 return ret;
00361 
00362             hashSz = SHA256_DIGEST_SIZE;
00363         }
00364 #endif
00365 #ifdef WOLFSSL_SHA384
00366         if (ssl->specs.mac_algorithm == sha384_mac) {
00367             int ret = wc_Sha384Final(&ssl->hsHashes->hashSha384,handshake_hash);
00368 
00369             if (ret != 0)
00370                 return ret;
00371 
00372             hashSz = SHA384_DIGEST_SIZE;
00373         }
00374 #endif
00375     }
00376 
00377     if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0)
00378         side = tls_client;
00379     else
00380         side = tls_server;
00381 
00382     return PRF((byte*)hashes, TLS_FINISHED_SZ, ssl->arrays->masterSecret,
00383                SECRET_LEN, side, FINISHED_LABEL_SZ, handshake_hash, hashSz,
00384                IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
00385 }
00386 
00387 
00388 #ifndef NO_OLD_TLS
00389 
00390 ProtocolVersion MakeTLSv1(void)
00391 {
00392     ProtocolVersion pv;
00393     pv.major = SSLv3_MAJOR;
00394     pv.minor = TLSv1_MINOR;
00395 
00396     return pv;
00397 }
00398 
00399 
00400 ProtocolVersion MakeTLSv1_1(void)
00401 {
00402     ProtocolVersion pv;
00403     pv.major = SSLv3_MAJOR;
00404     pv.minor = TLSv1_1_MINOR;
00405 
00406     return pv;
00407 }
00408 
00409 #endif
00410 
00411 
00412 ProtocolVersion MakeTLSv1_2(void)
00413 {
00414     ProtocolVersion pv;
00415     pv.major = SSLv3_MAJOR;
00416     pv.minor = TLSv1_2_MINOR;
00417 
00418     return pv;
00419 }
00420 
00421 
00422 static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret";
00423 static const byte key_label   [KEY_LABEL_SZ + 1]    = "key expansion";
00424 
00425 
00426 /* External facing wrapper so user can call as well, 0 on success */
00427 int wolfSSL_DeriveTlsKeys(byte* key_data, word32 keyLen,
00428                          const byte* ms, word32 msLen,
00429                          const byte* sr, const byte* cr,
00430                          int tls1_2, int hash_type)
00431 {
00432     byte  seed[SEED_LEN];
00433 
00434     XMEMCPY(seed,           sr, RAN_LEN);
00435     XMEMCPY(seed + RAN_LEN, cr, RAN_LEN);
00436 
00437     return PRF(key_data, keyLen, ms, msLen, key_label, KEY_LABEL_SZ,
00438                seed, SEED_LEN, tls1_2, hash_type);
00439 }
00440 
00441 
00442 int DeriveTlsKeys(WOLFSSL* ssl)
00443 {
00444     int   ret;
00445     int   length = 2 * ssl->specs.hash_size +
00446                    2 * ssl->specs.key_size  +
00447                    2 * ssl->specs.iv_size;
00448 #ifdef WOLFSSL_SMALL_STACK
00449     byte* key_data;
00450 #else
00451     byte  key_data[MAX_PRF_DIG];
00452 #endif
00453 
00454 #ifdef WOLFSSL_SMALL_STACK
00455     key_data = (byte*)XMALLOC(MAX_PRF_DIG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00456     if (key_data == NULL) {
00457         return MEMORY_E;
00458     }
00459 #endif
00460 
00461     ret = wolfSSL_DeriveTlsKeys(key_data, length,
00462                            ssl->arrays->masterSecret, SECRET_LEN,
00463                            ssl->arrays->serverRandom, ssl->arrays->clientRandom,
00464                            IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
00465     if (ret == 0)
00466         ret = StoreKeys(ssl, key_data);
00467 
00468 #ifdef WOLFSSL_SMALL_STACK
00469     XFREE(key_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00470 #endif
00471 
00472     return ret;
00473 }
00474 
00475 
00476 /* External facing wrapper so user can call as well, 0 on success */
00477 int wolfSSL_MakeTlsMasterSecret(byte* ms, word32 msLen,
00478                                const byte* pms, word32 pmsLen,
00479                                const byte* cr, const byte* sr,
00480                                int tls1_2, int hash_type)
00481 {
00482     byte  seed[SEED_LEN];
00483 
00484     XMEMCPY(seed,           cr, RAN_LEN);
00485     XMEMCPY(seed + RAN_LEN, sr, RAN_LEN);
00486 
00487     return PRF(ms, msLen, pms, pmsLen, master_label, MASTER_LABEL_SZ,
00488                seed, SEED_LEN, tls1_2, hash_type);
00489 }
00490 
00491 
00492 int MakeTlsMasterSecret(WOLFSSL* ssl)
00493 {
00494     int   ret;
00495 
00496     ret = wolfSSL_MakeTlsMasterSecret(ssl->arrays->masterSecret, SECRET_LEN,
00497               ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
00498               ssl->arrays->clientRandom, ssl->arrays->serverRandom,
00499               IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
00500 
00501     if (ret == 0) {
00502     #ifdef SHOW_SECRETS
00503         int i;
00504 
00505         printf("master secret: ");
00506         for (i = 0; i < SECRET_LEN; i++)
00507             printf("%02x", ssl->arrays->masterSecret[i]);
00508         printf("\n");
00509     #endif
00510 
00511         ret = DeriveTlsKeys(ssl);
00512     }
00513 
00514     return ret;
00515 }
00516 
00517 
00518 /* Used by EAP-TLS and EAP-TTLS to derive keying material from
00519  * the master_secret. */
00520 int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* msk, unsigned int len,
00521                                                               const char* label)
00522 {
00523     int   ret;
00524 #ifdef WOLFSSL_SMALL_STACK
00525     byte* seed;
00526 #else
00527     byte  seed[SEED_LEN];
00528 #endif
00529 
00530 #ifdef WOLFSSL_SMALL_STACK
00531     seed = (byte*)XMALLOC(SEED_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00532     if (seed == NULL)
00533         return MEMORY_E;
00534 #endif
00535 
00536     /*
00537      * As per RFC-5281, the order of the client and server randoms is reversed
00538      * from that used by the TLS protocol to derive keys.
00539      */
00540     XMEMCPY(seed,           ssl->arrays->clientRandom, RAN_LEN);
00541     XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
00542 
00543     ret = PRF((byte*)msk, len, ssl->arrays->masterSecret, SECRET_LEN,
00544               (const byte *)label, (word32)strlen(label), seed, SEED_LEN,
00545               IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
00546 
00547 #ifdef WOLFSSL_SMALL_STACK
00548     XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00549 #endif
00550 
00551     return ret;
00552 }
00553 
00554 
00555 /*** next for static INLINE s copied internal.c ***/
00556 
00557 /* convert 16 bit integer to opaque */
00558 static INLINE void c16toa(word16 u16, byte* c)
00559 {
00560     c[0] = (u16 >> 8) & 0xff;
00561     c[1] =  u16 & 0xff;
00562 }
00563 
00564 #ifdef HAVE_TLS_EXTENSIONS
00565 /* convert opaque to 16 bit integer */
00566 static INLINE void ato16(const byte* c, word16* u16)
00567 {
00568     *u16 = (c[0] << 8) | (c[1]);
00569 }
00570 
00571 #if defined(HAVE_SNI) && !defined(NO_WOLFSSL_SERVER)
00572 /* convert a 24 bit integer into a 32 bit one */
00573 static INLINE void c24to32(const word24 u24, word32* u32)
00574 {
00575     *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
00576 }
00577 #endif
00578 #endif
00579 
00580 /* convert 32 bit integer to opaque */
00581 static INLINE void c32toa(word32 u32, byte* c)
00582 {
00583     c[0] = (u32 >> 24) & 0xff;
00584     c[1] = (u32 >> 16) & 0xff;
00585     c[2] = (u32 >>  8) & 0xff;
00586     c[3] =  u32 & 0xff;
00587 }
00588 
00589 
00590 static INLINE word32 GetSEQIncrement(WOLFSSL* ssl, int verify)
00591 {
00592 #ifdef WOLFSSL_DTLS
00593     if (ssl->options.dtls) {
00594         if (verify)
00595             return ssl->keys.dtls_state.curSeq; /* explicit from peer */
00596         else
00597             return ssl->keys.dtls_sequence_number - 1; /* already incremented */
00598     }
00599 #endif
00600     if (verify)
00601         return ssl->keys.peer_sequence_number++;
00602     else
00603         return ssl->keys.sequence_number++;
00604 }
00605 
00606 
00607 #ifdef WOLFSSL_DTLS
00608 
00609 static INLINE word32 GetEpoch(WOLFSSL* ssl, int verify)
00610 {
00611     if (verify)
00612         return ssl->keys.dtls_state.curEpoch;
00613     else
00614         return ssl->keys.dtls_epoch;
00615 }
00616 
00617 #endif /* WOLFSSL_DTLS */
00618 
00619 
00620 /*** end copy ***/
00621 
00622 
00623 /* return HMAC digest type in wolfSSL format */
00624 int wolfSSL_GetHmacType(WOLFSSL* ssl)
00625 {
00626     if (ssl == NULL)
00627         return BAD_FUNC_ARG;
00628 
00629     switch (ssl->specs.mac_algorithm) {
00630         #ifndef NO_MD5
00631         case md5_mac:
00632         {
00633             return MD5;
00634         }
00635         #endif
00636         #ifndef NO_SHA256
00637         case sha256_mac:
00638         {
00639             return SHA256;
00640         }
00641         #endif
00642         #ifdef WOLFSSL_SHA384
00643         case sha384_mac:
00644         {
00645             return SHA384;
00646         }
00647 
00648         #endif
00649         #ifndef NO_SHA
00650         case sha_mac:
00651         {
00652             return SHA;
00653         }
00654         #endif
00655         #ifdef HAVE_BLAKE2
00656         case blake2b_mac:
00657         {
00658             return BLAKE2B_ID;
00659         }
00660         #endif
00661         default:
00662         {
00663             return SSL_FATAL_ERROR;
00664         }
00665     }
00666 }
00667 
00668 
00669 int wolfSSL_SetTlsHmacInner(WOLFSSL* ssl, byte* inner, word32 sz, int content,
00670                            int verify)
00671 {
00672     if (ssl == NULL || inner == NULL)
00673         return BAD_FUNC_ARG;
00674 
00675     XMEMSET(inner, 0, WOLFSSL_TLS_HMAC_INNER_SZ);
00676 
00677 #ifdef WOLFSSL_DTLS
00678     if (ssl->options.dtls)
00679         c16toa((word16)GetEpoch(ssl, verify), inner);
00680 #endif
00681     c32toa(GetSEQIncrement(ssl, verify), &inner[sizeof(word32)]);
00682     inner[SEQ_SZ] = (byte)content;
00683     inner[SEQ_SZ + ENUM_LEN]            = ssl->version.major;
00684     inner[SEQ_SZ + ENUM_LEN + ENUM_LEN] = ssl->version.minor;
00685     c16toa((word16)sz, inner + SEQ_SZ + ENUM_LEN + VERSION_SZ);
00686 
00687     return 0;
00688 }
00689 
00690 
00691 /* TLS type HMAC */
00692 int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
00693               int content, int verify)
00694 {
00695     Hmac hmac;
00696     int  ret;
00697     byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
00698 
00699     if (ssl == NULL)
00700         return BAD_FUNC_ARG;
00701 
00702 #ifdef HAVE_FUZZER
00703     if (ssl->fuzzerCb)
00704         ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx);
00705 #endif
00706 
00707     wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify);
00708 
00709     ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
00710                      wolfSSL_GetMacSecret(ssl, verify), ssl->specs.hash_size);
00711     if (ret != 0)
00712         return ret;
00713     ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
00714     if (ret != 0)
00715         return ret;
00716     ret = wc_HmacUpdate(&hmac, in, sz);                                /* content */
00717     if (ret != 0)
00718         return ret;
00719     ret = wc_HmacFinal(&hmac, digest);
00720     if (ret != 0)
00721         return ret;
00722 
00723     return 0;
00724 }
00725 
00726 #ifdef HAVE_TLS_EXTENSIONS
00727 
00728 /**
00729  * The TLSX semaphore is used to calculate the size of the extensions to be sent
00730  * from one peer to another.
00731  */
00732 
00733 /** Supports up to 64 flags. Increase as needed. */
00734 #define SEMAPHORE_SIZE 8
00735 
00736 /**
00737  * Converts the extension type (id) to an index in the semaphore.
00738  *
00739  * Oficial reference for TLS extension types:
00740  *   http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xml
00741  *
00742  * Motivation:
00743  *   Previously, we used the extension type itself as the index of that
00744  *   extension in the semaphore as the extension types were declared
00745  *   sequentially, but maintain a semaphore as big as the number of available
00746  *   extensions is no longer an option since the release of renegotiation_info.
00747  *
00748  * How to update:
00749  *   Assign extension types that extrapolate the number of available semaphores
00750  *   to the first available index going backwards in the semaphore array.
00751  *   When adding a new extension type that don't extrapolate the number of
00752  *   available semaphores, check for a possible collision with with a
00753  *   'remapped' extension type.
00754  */
00755 static INLINE word16 TLSX_ToSemaphore(word16 type)
00756 {
00757     switch (type) {
00758 
00759         case TLSX_RENEGOTIATION_INFO: /* 0xFF01 */
00760             return 63;
00761 
00762         default:
00763             if (type > 62) {
00764                 /* This message SHOULD only happens during the adding of
00765                    new TLS extensions in which its IANA number overflows
00766                    the current semaphore's range, or if its number already
00767                    is assigned to be used by another extension.
00768                    Use this check value for the new extension and decrement
00769                    the check value by one. */
00770                 WOLFSSL_MSG("### TLSX semaphore colision or overflow detected!");
00771             }
00772     }
00773 
00774     return type;
00775 }
00776 
00777 /** Checks if a specific light (tls extension) is not set in the semaphore. */
00778 #define IS_OFF(semaphore, light) \
00779     ((semaphore)[(light) / 8] ^  (byte) (0x01 << ((light) % 8)))
00780 
00781 /** Turn on a specific light (tls extension) in the semaphore. */
00782 #define TURN_ON(semaphore, light) \
00783     ((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8)))
00784 
00785 /** Creates a new extension. */
00786 static TLSX* TLSX_New(TLSX_Type type, void* data)
00787 {
00788     TLSX* extension = (TLSX*)XMALLOC(sizeof(TLSX), NULL, DYNAMIC_TYPE_TLSX);
00789 
00790     if (extension) {
00791         extension->type = type;
00792         extension->data = data;
00793         extension->resp = 0;
00794         extension->next = NULL;
00795     }
00796 
00797     return extension;
00798 }
00799 
00800 /**
00801  * Creates a new extension and pushes it to the provided list.
00802  * Checks for duplicate extensions, keeps the newest.
00803  */
00804 static int TLSX_Push(TLSX** list, TLSX_Type type, void* data)
00805 {
00806     TLSX* extension = TLSX_New(type, data);
00807 
00808     if (extension == NULL)
00809         return MEMORY_E;
00810 
00811     /* pushes the new extension on the list. */
00812     extension->next = *list;
00813     *list = extension;
00814 
00815     /* remove duplicate extensions, there should be only one of each type. */
00816     do {
00817         if (extension->next && extension->next->type == type) {
00818             TLSX *next = extension->next;
00819 
00820             extension->next = next->next;
00821             next->next = NULL;
00822 
00823             TLSX_FreeAll(next);
00824 
00825             /* there is no way to occur more than */
00826             /* two extensions of the same type.   */
00827             break;
00828         }
00829     } while ((extension = extension->next));
00830 
00831     return 0;
00832 }
00833 
00834 #ifndef NO_WOLFSSL_SERVER
00835 
00836 /** Mark an extension to be sent back to the client. */
00837 void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type);
00838 
00839 void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type)
00840 {
00841     TLSX *ext = TLSX_Find(ssl->extensions, type);
00842 
00843     if (ext)
00844         ext->resp = 1;
00845 }
00846 
00847 #endif
00848 
00849 /******************************************************************************/
00850 /* Application-Layer Protocol Negotiation                                     */
00851 /******************************************************************************/
00852 
00853 #ifdef HAVE_ALPN
00854 /** Creates a new ALPN object, providing protocol name to use. */
00855 static ALPN* TLSX_ALPN_New(char *protocol_name, word16 protocol_nameSz)
00856 {
00857     ALPN *alpn;
00858 
00859     WOLFSSL_ENTER("TLSX_ALPN_New");
00860 
00861     if (protocol_name == NULL ||
00862         protocol_nameSz > WOLFSSL_MAX_ALPN_PROTO_NAME_LEN) {
00863         WOLFSSL_MSG("Invalid arguments");
00864         return NULL;
00865     }
00866 
00867     alpn = (ALPN*)XMALLOC(sizeof(ALPN), 0, DYNAMIC_TYPE_TLSX);
00868     if (alpn == NULL) {
00869         WOLFSSL_MSG("Memory failure");
00870         return NULL;
00871     }
00872 
00873     alpn->next = NULL;
00874     alpn->negotiated = 0;
00875     alpn->options = 0;
00876 
00877     alpn->protocol_name = XMALLOC(protocol_nameSz + 1, 0, DYNAMIC_TYPE_TLSX);
00878     if (alpn->protocol_name == NULL) {
00879         WOLFSSL_MSG("Memory failure");
00880         XFREE(alpn, 0, DYNAMIC_TYPE_TLSX);
00881         return NULL;
00882     }
00883 
00884     XMEMCPY(alpn->protocol_name, protocol_name, protocol_nameSz);
00885     alpn->protocol_name[protocol_nameSz] = 0;
00886 
00887     return alpn;
00888 }
00889 
00890 /** Releases an ALPN object. */
00891 static void TLSX_ALPN_Free(ALPN *alpn)
00892 {
00893     if (alpn == NULL)
00894         return;
00895 
00896     XFREE(alpn->protocol_name, 0, DYNAMIC_TYPE_TLSX);
00897     XFREE(alpn, 0, DYNAMIC_TYPE_TLSX);
00898 }
00899 
00900 /** Releases all ALPN objects in the provided list. */
00901 static void TLSX_ALPN_FreeAll(ALPN *list)
00902 {
00903     ALPN* alpn;
00904 
00905     while ((alpn = list)) {
00906         list = alpn->next;
00907         TLSX_ALPN_Free(alpn);
00908     }
00909 }
00910 
00911 /** Tells the buffered size of the ALPN objects in a list. */
00912 static word16 TLSX_ALPN_GetSize(ALPN *list)
00913 {
00914     ALPN* alpn;
00915     word16 length = OPAQUE16_LEN; /* list length */
00916 
00917     while ((alpn = list)) {
00918         list = alpn->next;
00919 
00920         length++; /* protocol name length is on one byte */
00921         length += (word16)XSTRLEN(alpn->protocol_name);
00922     }
00923 
00924     return length;
00925 }
00926 
00927 /** Writes the ALPN objects of a list in a buffer. */
00928 static word16 TLSX_ALPN_Write(ALPN *list, byte *output)
00929 {
00930     ALPN* alpn;
00931     word16 length = 0;
00932     word16 offset = OPAQUE16_LEN; /* list length offset */
00933 
00934     while ((alpn = list)) {
00935         list = alpn->next;
00936 
00937         length = (word16)XSTRLEN(alpn->protocol_name);
00938 
00939         /* protocol name length */
00940         output[offset++] = (byte)length;
00941 
00942         /* protocol name value */
00943         XMEMCPY(output + offset, alpn->protocol_name, length);
00944 
00945         offset += length;
00946     }
00947 
00948     /* writing list length */
00949     c16toa(offset - OPAQUE16_LEN, output);
00950 
00951     return offset;
00952 }
00953 
00954 /** Finds a protocol name in the provided ALPN list */
00955 static ALPN* TLSX_ALPN_Find(ALPN *list, char *protocol_name, word16 size)
00956 {
00957     ALPN *alpn;
00958 
00959     if (list == NULL || protocol_name == NULL)
00960         return NULL;
00961 
00962     alpn = list;
00963     while (alpn != NULL && (
00964            (word16)XSTRLEN(alpn->protocol_name) != size ||
00965            XSTRNCMP(alpn->protocol_name, protocol_name, size)))
00966         alpn = alpn->next;
00967 
00968     return alpn;
00969 }
00970 
00971 /** Set the ALPN matching client and server requirements */
00972 static int TLSX_SetALPN(TLSX** extensions, const void* data, word16 size)
00973 {
00974     ALPN *alpn;
00975     int  ret;
00976 
00977     if (extensions == NULL || data == NULL)
00978         return BAD_FUNC_ARG;
00979 
00980     alpn = TLSX_ALPN_New((char *)data, size);
00981     if (alpn == NULL) {
00982         WOLFSSL_MSG("Memory failure");
00983         return MEMORY_E;
00984     }
00985 
00986     alpn->negotiated = 1;
00987 
00988     ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL, (void*)alpn);
00989     if (ret != 0) {
00990         TLSX_ALPN_Free(alpn);
00991         return ret;
00992     }
00993 
00994     return SSL_SUCCESS;
00995 }
00996 
00997 /** Parses a buffer of ALPN extensions and set the first one matching
00998  * client and server requirements */
00999 static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length,
01000                                  byte isRequest)
01001 {
01002     word16  size = 0, offset = 0, idx = 0;
01003     int     r = BUFFER_ERROR;
01004     byte    match = 0;
01005     TLSX    *extension;
01006     ALPN    *alpn = NULL, *list;
01007 
01008     extension = TLSX_Find(ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
01009     if (extension == NULL)
01010         extension = TLSX_Find(ssl->ctx->extensions,
01011                                                TLSX_APPLICATION_LAYER_PROTOCOL);
01012 
01013     if (extension == NULL || extension->data == NULL) {
01014         WOLFSSL_MSG("No ALPN extensions not used or bad");
01015         return isRequest ? 0             /* not using ALPN */
01016                          : BUFFER_ERROR; /* unexpected ALPN response */
01017     }
01018 
01019     if (OPAQUE16_LEN > length)
01020         return BUFFER_ERROR;
01021 
01022     ato16(input, &size);
01023     offset += OPAQUE16_LEN;
01024 
01025     /* validating alpn list length */
01026     if (length != OPAQUE16_LEN + size)
01027         return BUFFER_ERROR;
01028 
01029     list = (ALPN*)extension->data;
01030 
01031     /* keep the list sent by client */
01032     if (isRequest) {
01033         if (ssl->alpn_client_list != NULL)
01034             XFREE(ssl->alpn_client_list, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01035 
01036         ssl->alpn_client_list = (char *)XMALLOC(size, NULL,
01037                                                 DYNAMIC_TYPE_TMP_BUFFER);
01038         if (ssl->alpn_client_list == NULL)
01039             return MEMORY_ERROR;
01040     }
01041 
01042     for (size = 0; offset < length; offset += size) {
01043 
01044         size = input[offset++];
01045         if (offset + size > length)
01046             return BUFFER_ERROR;
01047 
01048         if (isRequest) {
01049             XMEMCPY(ssl->alpn_client_list+idx, (char*)input + offset, size);
01050             idx += size;
01051             ssl->alpn_client_list[idx++] = ',';
01052         }
01053 
01054         if (!match) {
01055             alpn = TLSX_ALPN_Find(list, (char*)input + offset, size);
01056             if (alpn != NULL) {
01057                 WOLFSSL_MSG("ALPN protocol match");
01058                 match = 1;
01059 
01060                 /* skip reading other values if not required */
01061                 if (!isRequest)
01062                     break;
01063             }
01064         }
01065     }
01066 
01067     if (isRequest)
01068         ssl->alpn_client_list[idx-1] = 0;
01069 
01070     if (!match) {
01071         WOLFSSL_MSG("No ALPN protocol match");
01072 
01073         /* do nothing if no protocol match between client and server and option
01074          is set to continue (like OpenSSL) */
01075         if (list->options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) {
01076             WOLFSSL_MSG("Continue on mismatch");
01077             return 0;
01078         }
01079 
01080         SendAlert(ssl, alert_fatal, no_application_protocol);
01081         return UNKNOWN_ALPN_PROTOCOL_NAME_E;
01082     }
01083 
01084     /* set the matching negotiated protocol */
01085     r = TLSX_SetALPN(&ssl->extensions,
01086                      alpn->protocol_name,
01087                      (word16)XSTRLEN(alpn->protocol_name));
01088     if (r != SSL_SUCCESS) {
01089         WOLFSSL_MSG("TLSX_UseALPN failed");
01090         return BUFFER_ERROR;
01091     }
01092 
01093     /* reply to ALPN extension sent from client */
01094     if (isRequest) {
01095 #ifndef NO_WOLFSSL_SERVER
01096         TLSX_SetResponse(ssl, TLSX_APPLICATION_LAYER_PROTOCOL);
01097 #endif
01098     }
01099 
01100     return 0;
01101 }
01102 
01103 /** Add a protocol name to the list of accepted usable ones */
01104 int TLSX_UseALPN(TLSX** extensions, const void* data, word16 size, byte options)
01105 {
01106     ALPN *alpn;
01107     TLSX *extension;
01108     int  ret;
01109 
01110     if (extensions == NULL || data == NULL)
01111         return BAD_FUNC_ARG;
01112 
01113     alpn = TLSX_ALPN_New((char *)data, size);
01114     if (alpn == NULL) {
01115         WOLFSSL_MSG("Memory failure");
01116         return MEMORY_E;
01117     }
01118 
01119     /* Set Options of ALPN */
01120     alpn->options = options;
01121 
01122     extension = TLSX_Find(*extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
01123     if (extension == NULL) {
01124         ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL,
01125                                                                    (void*)alpn);
01126         if (ret != 0) {
01127             TLSX_ALPN_Free(alpn);
01128             return ret;
01129         }
01130     }
01131     else {
01132         /* push new ALPN object to extension data. */
01133         alpn->next = (ALPN*)extension->data;
01134         extension->data = (void*)alpn;
01135     }
01136 
01137     return SSL_SUCCESS;
01138 }
01139 
01140 /** Get the protocol name set by the server */
01141 int TLSX_ALPN_GetRequest(TLSX* extensions, void** data, word16 *dataSz)
01142 {
01143     TLSX *extension;
01144     ALPN *alpn;
01145 
01146     if (extensions == NULL || data == NULL || dataSz == NULL)
01147         return BAD_FUNC_ARG;
01148 
01149     extension = TLSX_Find(extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
01150     if (extension == NULL) {
01151         WOLFSSL_MSG("TLS extension not found");
01152         return SSL_ALPN_NOT_FOUND;
01153     }
01154 
01155     alpn = (ALPN *)extension->data;
01156     if (alpn == NULL) {
01157         WOLFSSL_MSG("ALPN extension not found");
01158         *data = NULL;
01159         *dataSz = 0;
01160         return SSL_FATAL_ERROR;
01161     }
01162 
01163     if (alpn->negotiated != 1) {
01164 
01165         /* consider as an error */
01166         if (alpn->options & WOLFSSL_ALPN_FAILED_ON_MISMATCH) {
01167             WOLFSSL_MSG("No protocol match with peer -> Failed");
01168             return SSL_FATAL_ERROR;
01169         }
01170 
01171         /* continue without negotiated protocol */
01172         WOLFSSL_MSG("No protocol match with peer -> Continue");
01173         return SSL_ALPN_NOT_FOUND;
01174     }
01175 
01176     if (alpn->next != NULL) {
01177         WOLFSSL_MSG("Only one protocol name must be accepted");
01178         return SSL_FATAL_ERROR;
01179     }
01180 
01181     *data = alpn->protocol_name;
01182     *dataSz = (word16)XSTRLEN(*data);
01183 
01184     return SSL_SUCCESS;
01185 }
01186 
01187 #define ALPN_FREE_ALL     TLSX_ALPN_FreeAll
01188 #define ALPN_GET_SIZE     TLSX_ALPN_GetSize
01189 #define ALPN_WRITE        TLSX_ALPN_Write
01190 #define ALPN_PARSE        TLSX_ALPN_ParseAndSet
01191 
01192 #else /* HAVE_ALPN */
01193 
01194 #define ALPN_FREE_ALL(list)
01195 #define ALPN_GET_SIZE(list)     0
01196 #define ALPN_WRITE(a, b)        0
01197 #define ALPN_PARSE(a, b, c, d)  0
01198 
01199 #endif /* HAVE_ALPN */
01200 
01201 /******************************************************************************/
01202 /* Server Name Indication                                                     */
01203 /******************************************************************************/
01204 
01205 #ifdef HAVE_SNI
01206 
01207 /** Creates a new SNI object. */
01208 static SNI* TLSX_SNI_New(byte type, const void* data, word16 size)
01209 {
01210     SNI* sni = (SNI*)XMALLOC(sizeof(SNI), NULL, DYNAMIC_TYPE_TLSX);
01211 
01212     if (sni) {
01213         sni->type = type;
01214         sni->next = NULL;
01215 
01216     #ifndef NO_WOLFSSL_SERVER
01217         sni->options = 0;
01218         sni->status  = WOLFSSL_SNI_NO_MATCH;
01219     #endif
01220 
01221         switch (sni->type) {
01222             case WOLFSSL_SNI_HOST_NAME:
01223                 sni->data.host_name = XMALLOC(size+1, NULL, DYNAMIC_TYPE_TLSX);
01224 
01225                 if (sni->data.host_name) {
01226                     XSTRNCPY(sni->data.host_name, (const char*)data, size);
01227                     sni->data.host_name[size] = 0;
01228                 } else {
01229                     XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
01230                     sni = NULL;
01231                 }
01232             break;
01233 
01234             default: /* invalid type */
01235                 XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
01236                 sni = NULL;
01237         }
01238     }
01239 
01240     return sni;
01241 }
01242 
01243 /** Releases a SNI object. */
01244 static void TLSX_SNI_Free(SNI* sni)
01245 {
01246     if (sni) {
01247         switch (sni->type) {
01248             case WOLFSSL_SNI_HOST_NAME:
01249                 XFREE(sni->data.host_name, 0, DYNAMIC_TYPE_TLSX);
01250             break;
01251         }
01252 
01253         XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
01254     }
01255 }
01256 
01257 /** Releases all SNI objects in the provided list. */
01258 static void TLSX_SNI_FreeAll(SNI* list)
01259 {
01260     SNI* sni;
01261 
01262     while ((sni = list)) {
01263         list = sni->next;
01264         TLSX_SNI_Free(sni);
01265     }
01266 }
01267 
01268 /** Tells the buffered size of the SNI objects in a list. */
01269 static word16 TLSX_SNI_GetSize(SNI* list)
01270 {
01271     SNI* sni;
01272     word16 length = OPAQUE16_LEN; /* list length */
01273 
01274     while ((sni = list)) {
01275         list = sni->next;
01276 
01277         length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */
01278 
01279         switch (sni->type) {
01280             case WOLFSSL_SNI_HOST_NAME:
01281                 length += XSTRLEN((char*)sni->data.host_name);
01282             break;
01283         }
01284     }
01285 
01286     return length;
01287 }
01288 
01289 /** Writes the SNI objects of a list in a buffer. */
01290 static word16 TLSX_SNI_Write(SNI* list, byte* output)
01291 {
01292     SNI* sni;
01293     word16 length = 0;
01294     word16 offset = OPAQUE16_LEN; /* list length offset */
01295 
01296     while ((sni = list)) {
01297         list = sni->next;
01298 
01299         output[offset++] = sni->type; /* sni type */
01300 
01301         switch (sni->type) {
01302             case WOLFSSL_SNI_HOST_NAME:
01303                 length = XSTRLEN((char*)sni->data.host_name);
01304 
01305                 c16toa(length, output + offset); /* sni length */
01306                 offset += OPAQUE16_LEN;
01307 
01308                 XMEMCPY(output + offset, sni->data.host_name, length);
01309 
01310                 offset += length;
01311             break;
01312         }
01313     }
01314 
01315     c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
01316 
01317     return offset;
01318 }
01319 
01320 #ifndef NO_WOLFSSL_SERVER
01321 
01322 /** Finds a SNI object in the provided list. */
01323 static SNI* TLSX_SNI_Find(SNI *list, byte type)
01324 {
01325     SNI *sni = list;
01326 
01327     while (sni && sni->type != type)
01328         sni = sni->next;
01329 
01330     return sni;
01331 }
01332 
01333 
01334 /** Sets the status of a SNI object. */
01335 static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status)
01336 {
01337     TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
01338     SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
01339 
01340     if (sni)
01341         sni->status = status;
01342 }
01343 
01344 /** Gets the status of a SNI object. */
01345 byte TLSX_SNI_Status(TLSX* extensions, byte type)
01346 {
01347     TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
01348     SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
01349 
01350     if (sni)
01351         return sni->status;
01352 
01353     return 0;
01354 }
01355 
01356 #endif /* NO_WOLFSSL_SERVER */
01357 
01358 /** Parses a buffer of SNI extensions. */
01359 static int TLSX_SNI_Parse(WOLFSSL* ssl, byte* input, word16 length,
01360                                                                  byte isRequest)
01361 {
01362 #ifndef NO_WOLFSSL_SERVER
01363     word16 size = 0;
01364     word16 offset = 0;
01365     int cacheOnly = 0;
01366 #endif
01367 
01368     TLSX *extension = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME);
01369 
01370     if (!extension)
01371         extension = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME);
01372 
01373     (void)isRequest;
01374     (void)input;
01375 
01376     if (!extension || !extension->data) {
01377 #if defined(WOLFSSL_ALWAYS_KEEP_SNI) && !defined(NO_WOLFSSL_SERVER)
01378         /* This will keep SNI even though TLSX_UseSNI has not been called.
01379          * Enable it so that the received sni is available to functions
01380          * that use a custom callback when SNI is received */
01381         cacheOnly = 1;
01382         WOLFSSL_MSG("Forcing SSL object to store SNI parameter");
01383 #else
01384         return isRequest ? 0             /* not using SNI.           */
01385                          : BUFFER_ERROR; /* unexpected SNI response. */
01386 #endif
01387     }
01388 
01389     if (!isRequest)
01390         return length ? BUFFER_ERROR /* SNI response MUST be empty. */
01391                       : 0;           /* nothing else to do.         */
01392 
01393 #ifndef NO_WOLFSSL_SERVER
01394 
01395     if (OPAQUE16_LEN > length)
01396         return BUFFER_ERROR;
01397 
01398     ato16(input, &size);
01399     offset += OPAQUE16_LEN;
01400 
01401     /* validating sni list length */
01402     if (length != OPAQUE16_LEN + size)
01403         return BUFFER_ERROR;
01404 
01405     for (size = 0; offset < length; offset += size) {
01406         SNI *sni = NULL;
01407         byte type = input[offset++];
01408 
01409         if (offset + OPAQUE16_LEN > length)
01410             return BUFFER_ERROR;
01411 
01412         ato16(input + offset, &size);
01413         offset += OPAQUE16_LEN;
01414 
01415         if (offset + size > length)
01416             return BUFFER_ERROR;
01417 
01418         if (!cacheOnly && !(sni = TLSX_SNI_Find((SNI*)extension->data, type)))
01419             continue; /* not using this type of SNI. */
01420 
01421         switch(type) {
01422             case WOLFSSL_SNI_HOST_NAME: {
01423                 int matchStat;
01424                 byte matched = cacheOnly ||
01425                             ((XSTRLEN(sni->data.host_name) == size)
01426                             && (XSTRNCMP(sni->data.host_name,
01427                                        (const char*)input + offset, size) == 0));
01428 
01429                 if (matched || sni->options & WOLFSSL_SNI_ANSWER_ON_MISMATCH) {
01430                     int r = TLSX_UseSNI(&ssl->extensions,
01431                                                     type, input + offset, size);
01432 
01433                     if (r != SSL_SUCCESS)
01434                         return r; /* throws error. */
01435 
01436                     if(cacheOnly) {
01437                         WOLFSSL_MSG("Forcing storage of SNI, Fake match");
01438                         matchStat = WOLFSSL_SNI_FORCE_KEEP;
01439                     } else if(matched) {
01440                         WOLFSSL_MSG("SNI did match!");
01441                         matchStat = WOLFSSL_SNI_REAL_MATCH;
01442                     } else {
01443                         WOLFSSL_MSG("fake SNI match from ANSWER_ON_MISMATCH");
01444                         matchStat = WOLFSSL_SNI_FAKE_MATCH;
01445                     }
01446 
01447                     TLSX_SNI_SetStatus(ssl->extensions, type, matchStat);
01448 
01449                     if(!cacheOnly)
01450                         TLSX_SetResponse(ssl, TLSX_SERVER_NAME);
01451 
01452                 } else if (!(sni->options & WOLFSSL_SNI_CONTINUE_ON_MISMATCH)) {
01453                     SendAlert(ssl, alert_fatal, unrecognized_name);
01454 
01455                     return UNKNOWN_SNI_HOST_NAME_E;
01456                 }
01457                 break;
01458             }
01459         }
01460     }
01461 
01462 #endif
01463 
01464     return 0;
01465 }
01466 
01467 static int TLSX_SNI_VerifyParse(WOLFSSL* ssl,  byte isRequest)
01468 {
01469     (void)ssl;
01470 
01471     if (isRequest) {
01472     #ifndef NO_WOLFSSL_SERVER
01473         TLSX* ctx_ext = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME);
01474         TLSX* ssl_ext = TLSX_Find(ssl->extensions,      TLSX_SERVER_NAME);
01475         SNI* ctx_sni = ctx_ext ? ctx_ext->data : NULL;
01476         SNI* ssl_sni = ssl_ext ? ssl_ext->data : NULL;
01477         SNI* sni = NULL;
01478 
01479         for (; ctx_sni; ctx_sni = ctx_sni->next) {
01480             if (ctx_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) {
01481                 sni = TLSX_SNI_Find(ssl_sni, ctx_sni->type);
01482 
01483                 if (sni) {
01484                     if (sni->status != WOLFSSL_SNI_NO_MATCH)
01485                         continue;
01486 
01487                     /* if ssl level overrides ctx level, it is ok. */
01488                     if ((sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) == 0)
01489                         continue;
01490                 }
01491 
01492                 SendAlert(ssl, alert_fatal, handshake_failure);
01493                 return SNI_ABSENT_ERROR;
01494             }
01495         }
01496 
01497         for (; ssl_sni; ssl_sni = ssl_sni->next) {
01498             if (ssl_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) {
01499                 if (ssl_sni->status != WOLFSSL_SNI_NO_MATCH)
01500                     continue;
01501 
01502                 SendAlert(ssl, alert_fatal, handshake_failure);
01503                 return SNI_ABSENT_ERROR;
01504             }
01505         }
01506     #endif /* NO_WOLFSSL_SERVER */
01507     }
01508 
01509     return 0;
01510 }
01511 
01512 int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size)
01513 {
01514     TLSX* extension = TLSX_Find(*extensions, TLSX_SERVER_NAME);
01515     SNI*  sni       = NULL;
01516 
01517     if (extensions == NULL || data == NULL)
01518         return BAD_FUNC_ARG;
01519 
01520     if ((sni = TLSX_SNI_New(type, data, size)) == NULL)
01521         return MEMORY_E;
01522 
01523     if (!extension) {
01524         int ret = TLSX_Push(extensions, TLSX_SERVER_NAME, (void*)sni);
01525         if (ret != 0) {
01526             TLSX_SNI_Free(sni);
01527             return ret;
01528         }
01529     }
01530     else {
01531         /* push new SNI object to extension data. */
01532         sni->next = (SNI*)extension->data;
01533         extension->data = (void*)sni;
01534 
01535         /* remove duplicate SNI, there should be only one of each type. */
01536         do {
01537             if (sni->next && sni->next->type == type) {
01538                 SNI *next = sni->next;
01539 
01540                 sni->next = next->next;
01541                 TLSX_SNI_Free(next);
01542 
01543                 /* there is no way to occur more than */
01544                 /* two SNIs of the same type.         */
01545                 break;
01546             }
01547         } while ((sni = sni->next));
01548     }
01549 
01550     return SSL_SUCCESS;
01551 }
01552 
01553 #ifndef NO_WOLFSSL_SERVER
01554 
01555 /** Tells the SNI requested by the client. */
01556 word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data)
01557 {
01558     TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
01559     SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
01560 
01561     if (sni && sni->status != WOLFSSL_SNI_NO_MATCH) {
01562         switch (sni->type) {
01563             case WOLFSSL_SNI_HOST_NAME:
01564                 *data = sni->data.host_name;
01565                 return XSTRLEN(*data);
01566         }
01567     }
01568 
01569     return 0;
01570 }
01571 
01572 /** Sets the options for a SNI object. */
01573 void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options)
01574 {
01575     TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
01576     SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
01577 
01578     if (sni)
01579         sni->options = options;
01580 }
01581 
01582 /** Retrieves a SNI request from a client hello buffer. */
01583 int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
01584                            byte type, byte* sni, word32* inOutSz)
01585 {
01586     word32 offset = 0;
01587     word32 len32  = 0;
01588     word16 len16  = 0;
01589 
01590     if (helloSz < RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + CLIENT_HELLO_FIRST)
01591         return INCOMPLETE_DATA;
01592 
01593     /* TLS record header */
01594     if ((enum ContentType) clientHello[offset++] != handshake) {
01595 
01596         /* checking for SSLv2.0 client hello according to: */
01597         /* http://tools.ietf.org/html/rfc4346#appendix-E.1 */
01598         if ((enum HandShakeType) clientHello[++offset] == client_hello) {
01599             offset += ENUM_LEN + VERSION_SZ; /* skip version */
01600 
01601             ato16(clientHello + offset, &len16);
01602             offset += OPAQUE16_LEN;
01603 
01604             if (len16 % 3) /* cipher_spec_length must be multiple of 3 */
01605                 return BUFFER_ERROR;
01606 
01607             ato16(clientHello + offset, &len16);
01608             /* Returning SNI_UNSUPPORTED do not increment offset here */
01609 
01610             if (len16 != 0) /* session_id_length must be 0 */
01611                 return BUFFER_ERROR;
01612 
01613             return SNI_UNSUPPORTED;
01614         }
01615 
01616         return BUFFER_ERROR;
01617     }
01618 
01619     if (clientHello[offset++] != SSLv3_MAJOR)
01620         return BUFFER_ERROR;
01621 
01622     if (clientHello[offset++] < TLSv1_MINOR)
01623         return SNI_UNSUPPORTED;
01624 
01625     ato16(clientHello + offset, &len16);
01626     offset += OPAQUE16_LEN;
01627 
01628     if (offset + len16 > helloSz)
01629         return INCOMPLETE_DATA;
01630 
01631     /* Handshake header */
01632     if ((enum HandShakeType) clientHello[offset] != client_hello)
01633         return BUFFER_ERROR;
01634 
01635     c24to32(clientHello + offset + 1, &len32);
01636     offset += HANDSHAKE_HEADER_SZ;
01637 
01638     if (offset + len32 > helloSz)
01639         return BUFFER_ERROR;
01640 
01641     /* client hello */
01642     offset += VERSION_SZ + RAN_LEN; /* version, random */
01643 
01644     if (helloSz < offset + clientHello[offset])
01645         return BUFFER_ERROR;
01646 
01647     offset += ENUM_LEN + clientHello[offset]; /* skip session id */
01648 
01649     /* cypher suites */
01650     if (helloSz < offset + OPAQUE16_LEN)
01651         return BUFFER_ERROR;
01652 
01653     ato16(clientHello + offset, &len16);
01654     offset += OPAQUE16_LEN;
01655 
01656     if (helloSz < offset + len16)
01657         return BUFFER_ERROR;
01658 
01659     offset += len16; /* skip cypher suites */
01660 
01661     /* compression methods */
01662     if (helloSz < offset + 1)
01663         return BUFFER_ERROR;
01664 
01665     if (helloSz < offset + clientHello[offset])
01666         return BUFFER_ERROR;
01667 
01668     offset += ENUM_LEN + clientHello[offset]; /* skip compression methods */
01669 
01670     /* extensions */
01671     if (helloSz < offset + OPAQUE16_LEN)
01672         return 0; /* no extensions in client hello. */
01673 
01674     ato16(clientHello + offset, &len16);
01675     offset += OPAQUE16_LEN;
01676 
01677     if (helloSz < offset + len16)
01678         return BUFFER_ERROR;
01679 
01680     while (len16 >= OPAQUE16_LEN + OPAQUE16_LEN) {
01681         word16 extType;
01682         word16 extLen;
01683 
01684         ato16(clientHello + offset, &extType);
01685         offset += OPAQUE16_LEN;
01686 
01687         ato16(clientHello + offset, &extLen);
01688         offset += OPAQUE16_LEN;
01689 
01690         if (helloSz < offset + extLen)
01691             return BUFFER_ERROR;
01692 
01693         if (extType != TLSX_SERVER_NAME) {
01694             offset += extLen; /* skip extension */
01695         } else {
01696             word16 listLen;
01697 
01698             ato16(clientHello + offset, &listLen);
01699             offset += OPAQUE16_LEN;
01700 
01701             if (helloSz < offset + listLen)
01702                 return BUFFER_ERROR;
01703 
01704             while (listLen > ENUM_LEN + OPAQUE16_LEN) {
01705                 byte   sniType = clientHello[offset++];
01706                 word16 sniLen;
01707 
01708                 ato16(clientHello + offset, &sniLen);
01709                 offset += OPAQUE16_LEN;
01710 
01711                 if (helloSz < offset + sniLen)
01712                     return BUFFER_ERROR;
01713 
01714                 if (sniType != type) {
01715                     offset  += sniLen;
01716                     listLen -= min(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen);
01717                     continue;
01718                 }
01719 
01720                 *inOutSz = min(sniLen, *inOutSz);
01721                 XMEMCPY(sni, clientHello + offset, *inOutSz);
01722 
01723                 return SSL_SUCCESS;
01724             }
01725         }
01726 
01727         len16 -= min(2 * OPAQUE16_LEN + extLen, len16);
01728     }
01729 
01730     return len16 ? BUFFER_ERROR : 0;
01731 }
01732 
01733 #endif
01734 
01735 #define SNI_FREE_ALL     TLSX_SNI_FreeAll
01736 #define SNI_GET_SIZE     TLSX_SNI_GetSize
01737 #define SNI_WRITE        TLSX_SNI_Write
01738 #define SNI_PARSE        TLSX_SNI_Parse
01739 #define SNI_VERIFY_PARSE TLSX_SNI_VerifyParse
01740 
01741 #else
01742 
01743 #define SNI_FREE_ALL(list)
01744 #define SNI_GET_SIZE(list)     0
01745 #define SNI_WRITE(a, b)        0
01746 #define SNI_PARSE(a, b, c, d)  0
01747 #define SNI_VERIFY_PARSE(a, b) 0
01748 
01749 #endif /* HAVE_SNI */
01750 
01751 /******************************************************************************/
01752 /* Max Fragment Length Negotiation                                            */
01753 /******************************************************************************/
01754 
01755 #ifdef HAVE_MAX_FRAGMENT
01756 
01757 static word16 TLSX_MFL_Write(byte* data, byte* output)
01758 {
01759     output[0] = data[0];
01760 
01761     return ENUM_LEN;
01762 }
01763 
01764 static int TLSX_MFL_Parse(WOLFSSL* ssl, byte* input, word16 length,
01765                                                                  byte isRequest)
01766 {
01767     (void)isRequest;
01768 
01769     if (length != ENUM_LEN)
01770         return BUFFER_ERROR;
01771 
01772     switch (*input) {
01773         case WOLFSSL_MFL_2_9 : ssl->max_fragment =  512; break;
01774         case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
01775         case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
01776         case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
01777         case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
01778 
01779         default:
01780             SendAlert(ssl, alert_fatal, illegal_parameter);
01781 
01782             return UNKNOWN_MAX_FRAG_LEN_E;
01783     }
01784 
01785 #ifndef NO_WOLFSSL_SERVER
01786     if (isRequest) {
01787         int r = TLSX_UseMaxFragment(&ssl->extensions, *input);
01788 
01789         if (r != SSL_SUCCESS) return r; /* throw error */
01790 
01791         TLSX_SetResponse(ssl, TLSX_MAX_FRAGMENT_LENGTH);
01792     }
01793 #endif
01794 
01795     return 0;
01796 }
01797 
01798 int TLSX_UseMaxFragment(TLSX** extensions, byte mfl)
01799 {
01800     byte* data = NULL;
01801     int   ret  = 0;
01802 
01803     if (extensions == NULL)
01804         return BAD_FUNC_ARG;
01805 
01806     if (mfl < WOLFSSL_MFL_2_9 || WOLFSSL_MFL_2_13 < mfl)
01807         return BAD_FUNC_ARG;
01808 
01809     if ((data = XMALLOC(ENUM_LEN, NULL, DYNAMIC_TYPE_TLSX)) == NULL)
01810         return MEMORY_E;
01811 
01812     data[0] = mfl;
01813 
01814     /* push new MFL extension. */
01815     if ((ret = TLSX_Push(extensions, TLSX_MAX_FRAGMENT_LENGTH, data)) != 0) {
01816         XFREE(data, 0, DYNAMIC_TYPE_TLSX);
01817         return ret;
01818     }
01819 
01820     return SSL_SUCCESS;
01821 }
01822 
01823 
01824 #define MFL_FREE_ALL(data) XFREE(data, 0, DYNAMIC_TYPE_TLSX)
01825 #define MFL_GET_SIZE(data) ENUM_LEN
01826 #define MFL_WRITE          TLSX_MFL_Write
01827 #define MFL_PARSE          TLSX_MFL_Parse
01828 
01829 #else
01830 
01831 #define MFL_FREE_ALL(a)
01832 #define MFL_GET_SIZE(a)       0
01833 #define MFL_WRITE(a, b)       0
01834 #define MFL_PARSE(a, b, c, d) 0
01835 
01836 #endif /* HAVE_MAX_FRAGMENT */
01837 
01838 /******************************************************************************/
01839 /* Truncated HMAC                                                             */
01840 /******************************************************************************/
01841 
01842 #ifdef HAVE_TRUNCATED_HMAC
01843 
01844 static int TLSX_THM_Parse(WOLFSSL* ssl, byte* input, word16 length,
01845                                                                  byte isRequest)
01846 {
01847     (void)isRequest;
01848 
01849     if (length != 0 || input == NULL)
01850         return BUFFER_ERROR;
01851 
01852 #ifndef NO_WOLFSSL_SERVER
01853     if (isRequest) {
01854         int r = TLSX_UseTruncatedHMAC(&ssl->extensions);
01855 
01856         if (r != SSL_SUCCESS)
01857             return r; /* throw error */
01858 
01859         TLSX_SetResponse(ssl, TLSX_TRUNCATED_HMAC);
01860     }
01861 #endif
01862 
01863     ssl->truncated_hmac = 1;
01864 
01865     return 0;
01866 }
01867 
01868 int TLSX_UseTruncatedHMAC(TLSX** extensions)
01869 {
01870     int ret = 0;
01871 
01872     if (extensions == NULL)
01873         return BAD_FUNC_ARG;
01874 
01875     if ((ret = TLSX_Push(extensions, TLSX_TRUNCATED_HMAC, NULL)) != 0)
01876         return ret;
01877 
01878     return SSL_SUCCESS;
01879 }
01880 
01881 #define THM_PARSE TLSX_THM_Parse
01882 
01883 #else
01884 
01885 #define THM_PARSE(a, b, c, d) 0
01886 
01887 #endif /* HAVE_TRUNCATED_HMAC */
01888 
01889 /******************************************************************************/
01890 /* Certificate Status Request                                                 */
01891 /******************************************************************************/
01892 
01893 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
01894 
01895 static void TLSX_CSR_Free(CertificateStatusRequest* csr)
01896 {
01897     switch (csr->status_type) {
01898         case WOLFSSL_CSR_OCSP:
01899             FreeOcspRequest(&csr->request.ocsp);
01900         break;
01901     }
01902 
01903     XFREE(csr, NULL, DYNAMIC_TYPE_TLSX);
01904 }
01905 
01906 static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest)
01907 {
01908     word16 size = 0;
01909 
01910     /* shut up compiler warnings */
01911     (void) csr; (void) isRequest;
01912 
01913 #ifndef NO_WOLFSSL_CLIENT
01914     if (isRequest) {
01915         switch (csr->status_type) {
01916             case WOLFSSL_CSR_OCSP:
01917                 size += ENUM_LEN + 2 * OPAQUE16_LEN;
01918 
01919                 if (csr->request.ocsp.nonceSz)
01920                     size += OCSP_NONCE_EXT_SZ;
01921             break;
01922         }
01923     }
01924 #endif
01925 
01926     return size;
01927 }
01928 
01929 static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output,
01930                                                                  byte isRequest)
01931 {
01932     /* shut up compiler warnings */
01933     (void) csr; (void) output; (void) isRequest;
01934 
01935 #ifndef NO_WOLFSSL_CLIENT
01936     if (isRequest) {
01937         word16 offset = 0;
01938         word16 length = 0;
01939 
01940         /* type */
01941         output[offset++] = csr->status_type;
01942 
01943         switch (csr->status_type) {
01944             case WOLFSSL_CSR_OCSP:
01945                 /* responder id list */
01946                 c16toa(0, output + offset);
01947                 offset += OPAQUE16_LEN;
01948 
01949                 /* request extensions */
01950                 if (csr->request.ocsp.nonceSz)
01951                     length = EncodeOcspRequestExtensions(
01952                                                  &csr->request.ocsp,
01953                                                  output + offset + OPAQUE16_LEN,
01954                                                  OCSP_NONCE_EXT_SZ);
01955 
01956                 c16toa(length, output + offset);
01957                 offset += OPAQUE16_LEN + length;
01958 
01959             break;
01960         }
01961 
01962         return offset;
01963     }
01964 #endif
01965 
01966     return 0;
01967 }
01968 
01969 static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
01970                                                                  byte isRequest)
01971 {
01972     int ret;
01973 
01974     /* shut up compiler warnings */
01975     (void) ssl; (void) input;
01976 
01977     if (!isRequest) {
01978 #ifndef NO_WOLFSSL_CLIENT
01979         TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
01980         CertificateStatusRequest* csr = extension ? extension->data : NULL;
01981 
01982         if (!csr) {
01983             /* look at context level */
01984 
01985             extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST);
01986             csr = extension ? extension->data : NULL;
01987 
01988             if (!csr)
01989                 return BUFFER_ERROR; /* unexpected extension */
01990 
01991             /* enable extension at ssl level */
01992             ret = TLSX_UseCertificateStatusRequest(&ssl->extensions,
01993                                                 csr->status_type, csr->options);
01994             if (ret != SSL_SUCCESS)
01995                 return ret;
01996 
01997             switch (csr->status_type) {
01998                 case WOLFSSL_CSR_OCSP:
01999                     /* propagate nonce */
02000                     if (csr->request.ocsp.nonceSz) {
02001                         OcspRequest* request =
02002                                            TLSX_CSR_GetRequest(ssl->extensions);
02003 
02004                         if (request) {
02005                             XMEMCPY(request->nonce, csr->request.ocsp.nonce,
02006                                                     csr->request.ocsp.nonceSz);
02007                             request->nonceSz = csr->request.ocsp.nonceSz;
02008                         }
02009                     }
02010                 break;
02011             }
02012         }
02013 
02014         ssl->status_request = 1;
02015 
02016         return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */
02017 #endif
02018     }
02019     else {
02020 #ifndef NO_WOLFSSL_SERVER
02021         byte   status_type;
02022         word16 offset = 0;
02023         word16 size = 0;
02024 
02025         if (length < ENUM_LEN)
02026             return BUFFER_ERROR;
02027 
02028         status_type = input[offset++];
02029 
02030         switch (status_type) {
02031             case WOLFSSL_CSR_OCSP: {
02032 
02033                 /* skip responder_id_list */
02034                 if (length - offset < OPAQUE16_LEN)
02035                     return BUFFER_ERROR;
02036 
02037                 ato16(input + offset, &size);
02038                 offset += OPAQUE16_LEN + size;
02039 
02040                 /* skip request_extensions */
02041                 if (length - offset < OPAQUE16_LEN)
02042                     return BUFFER_ERROR;
02043 
02044                 ato16(input + offset, &size);
02045                 offset += OPAQUE16_LEN + size;
02046 
02047                 if (offset > length)
02048                     return BUFFER_ERROR;
02049 
02050                 /* is able to send OCSP response? */
02051                 if (ssl->ctx->cm == NULL || !ssl->ctx->cm->ocspStaplingEnabled)
02052                     return 0;
02053             }
02054             break;
02055         }
02056 
02057         /* if using status_request and already sending it, skip this one */
02058         #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
02059         if (ssl->status_request_v2)
02060             return 0;
02061         #endif
02062 
02063         /* accept the first good status_type and return */
02064         ret = TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
02065                                                                              0);
02066         if (ret != SSL_SUCCESS)
02067             return ret; /* throw error */
02068 
02069         TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST);
02070         ssl->status_request = status_type;
02071 
02072 #endif
02073     }
02074 
02075     return 0;
02076 }
02077 
02078 int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert)
02079 {
02080     TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST);
02081     CertificateStatusRequest* csr = extension ? extension->data : NULL;
02082     int ret = 0;
02083 
02084     if (csr) {
02085         switch (csr->status_type) {
02086             case WOLFSSL_CSR_OCSP: {
02087                 byte nonce[MAX_OCSP_NONCE_SZ];
02088                 int  nonceSz = csr->request.ocsp.nonceSz;
02089 
02090                 /* preserve nonce */
02091                 XMEMCPY(nonce, csr->request.ocsp.nonce, nonceSz);
02092 
02093                 if ((ret = InitOcspRequest(&csr->request.ocsp, cert, 0)) != 0)
02094                     return ret;
02095 
02096                 /* restore nonce */
02097                 XMEMCPY(csr->request.ocsp.nonce, nonce, nonceSz);
02098                 csr->request.ocsp.nonceSz = nonceSz;
02099             }
02100             break;
02101         }
02102     }
02103 
02104     return ret;
02105 }
02106 
02107 void* TLSX_CSR_GetRequest(TLSX* extensions)
02108 {
02109     TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST);
02110     CertificateStatusRequest* csr = extension ? extension->data : NULL;
02111 
02112     if (csr) {
02113         switch (csr->status_type) {
02114             case WOLFSSL_CSR_OCSP:
02115                 return &csr->request.ocsp;
02116             break;
02117         }
02118     }
02119 
02120     return NULL;
02121 }
02122 
02123 int TLSX_CSR_ForceRequest(WOLFSSL* ssl)
02124 {
02125     TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
02126     CertificateStatusRequest* csr = extension ? extension->data : NULL;
02127 
02128     if (csr) {
02129         switch (csr->status_type) {
02130             case WOLFSSL_CSR_OCSP:
02131                 if (ssl->ctx->cm->ocspEnabled)
02132                     return CheckOcspRequest(ssl->ctx->cm->ocsp,
02133                                                       &csr->request.ocsp, NULL);
02134                 else
02135                     return OCSP_LOOKUP_FAIL;
02136         }
02137     }
02138 
02139     return 0;
02140 }
02141 
02142 int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type,
02143                                                                    byte options)
02144 {
02145     CertificateStatusRequest* csr = NULL;
02146     int ret = 0;
02147 
02148     if (!extensions || status_type != WOLFSSL_CSR_OCSP)
02149         return BAD_FUNC_ARG;
02150 
02151     csr = (CertificateStatusRequest*)
02152              XMALLOC(sizeof(CertificateStatusRequest), NULL, DYNAMIC_TYPE_TLSX);
02153     if (!csr)
02154         return MEMORY_E;
02155 
02156     ForceZero(csr, sizeof(CertificateStatusRequest));
02157 
02158     csr->status_type = status_type;
02159     csr->options     = options;
02160 
02161     switch (csr->status_type) {
02162         case WOLFSSL_CSR_OCSP:
02163             if (options & WOLFSSL_CSR_OCSP_USE_NONCE) {
02164                 WC_RNG rng;
02165 
02166                 if (wc_InitRng(&rng) == 0) {
02167                     if (wc_RNG_GenerateBlock(&rng, csr->request.ocsp.nonce,
02168                                                         MAX_OCSP_NONCE_SZ) == 0)
02169                         csr->request.ocsp.nonceSz = MAX_OCSP_NONCE_SZ;
02170 
02171                     wc_FreeRng(&rng);
02172                 }
02173             }
02174         break;
02175     }
02176 
02177     if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST, csr)) != 0) {
02178         XFREE(csr, NULL, DYNAMIC_TYPE_TLSX);
02179         return ret;
02180     }
02181 
02182     return SSL_SUCCESS;
02183 }
02184 
02185 #define CSR_FREE_ALL TLSX_CSR_Free
02186 #define CSR_GET_SIZE TLSX_CSR_GetSize
02187 #define CSR_WRITE    TLSX_CSR_Write
02188 #define CSR_PARSE    TLSX_CSR_Parse
02189 
02190 #else
02191 
02192 #define CSR_FREE_ALL(data)
02193 #define CSR_GET_SIZE(a, b)    0
02194 #define CSR_WRITE(a, b, c)    0
02195 #define CSR_PARSE(a, b, c, d) 0
02196 
02197 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
02198 
02199 /******************************************************************************/
02200 /* Certificate Status Request v2                                              */
02201 /******************************************************************************/
02202 
02203 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
02204 
02205 static void TLSX_CSR2_FreeAll(CertificateStatusRequestItemV2* csr2)
02206 {
02207     CertificateStatusRequestItemV2* next;
02208 
02209     for (; csr2; csr2 = next) {
02210         next = csr2->next;
02211 
02212         switch (csr2->status_type) {
02213             case WOLFSSL_CSR2_OCSP:
02214             case WOLFSSL_CSR2_OCSP_MULTI:
02215                 while(csr2->requests--)
02216                     FreeOcspRequest(&csr2->request.ocsp[csr2->requests]);
02217             break;
02218         }
02219 
02220         XFREE(csr2, NULL, DYNAMIC_TYPE_TLSX);
02221     }
02222 }
02223 
02224 static word16 TLSX_CSR2_GetSize(CertificateStatusRequestItemV2* csr2,
02225                                                                  byte isRequest)
02226 {
02227     word16 size = 0;
02228 
02229     /* shut up compiler warnings */
02230     (void) csr2; (void) isRequest;
02231 
02232 #ifndef NO_WOLFSSL_CLIENT
02233     if (isRequest) {
02234         CertificateStatusRequestItemV2* next;
02235 
02236         for (size = OPAQUE16_LEN; csr2; csr2 = next) {
02237             next = csr2->next;
02238 
02239             switch (csr2->status_type) {
02240                 case WOLFSSL_CSR2_OCSP:
02241                 case WOLFSSL_CSR2_OCSP_MULTI:
02242                     size += ENUM_LEN + 3 * OPAQUE16_LEN;
02243 
02244                     if (csr2->request.ocsp[0].nonceSz)
02245                         size += OCSP_NONCE_EXT_SZ;
02246                 break;
02247             }
02248         }
02249     }
02250 #endif
02251 
02252     return size;
02253 }
02254 
02255 static word16 TLSX_CSR2_Write(CertificateStatusRequestItemV2* csr2,
02256                                                    byte* output, byte isRequest)
02257 {
02258     /* shut up compiler warnings */
02259     (void) csr2; (void) output; (void) isRequest;
02260 
02261 #ifndef NO_WOLFSSL_CLIENT
02262     if (isRequest) {
02263         word16 offset;
02264         word16 length;
02265 
02266         for (offset = OPAQUE16_LEN; csr2 != NULL; csr2 = csr2->next) {
02267             /* status_type */
02268             output[offset++] = csr2->status_type;
02269 
02270             /* request */
02271             switch (csr2->status_type) {
02272                 case WOLFSSL_CSR2_OCSP:
02273                 case WOLFSSL_CSR2_OCSP_MULTI:
02274                     /* request_length */
02275                     length = 2 * OPAQUE16_LEN;
02276 
02277                     if (csr2->request.ocsp[0].nonceSz)
02278                         length += OCSP_NONCE_EXT_SZ;
02279 
02280                     c16toa(length, output + offset);
02281                     offset += OPAQUE16_LEN;
02282 
02283                     /* responder id list */
02284                     c16toa(0, output + offset);
02285                     offset += OPAQUE16_LEN;
02286 
02287                     /* request extensions */
02288                     length = 0;
02289 
02290                     if (csr2->request.ocsp[0].nonceSz)
02291                         length = EncodeOcspRequestExtensions(
02292                                                  &csr2->request.ocsp[0],
02293                                                  output + offset + OPAQUE16_LEN,
02294                                                  OCSP_NONCE_EXT_SZ);
02295 
02296                     c16toa(length, output + offset);
02297                     offset += OPAQUE16_LEN + length;
02298                 break;
02299             }
02300         }
02301 
02302         /* list size */
02303         c16toa(offset - OPAQUE16_LEN, output);
02304 
02305         return offset;
02306     }
02307 #endif
02308 
02309     return 0;
02310 }
02311 
02312 static int TLSX_CSR2_Parse(WOLFSSL* ssl, byte* input, word16 length,
02313                                                                  byte isRequest)
02314 {
02315     int ret;
02316 
02317     /* shut up compiler warnings */
02318     (void) ssl; (void) input;
02319 
02320     if (!isRequest) {
02321 #ifndef NO_WOLFSSL_CLIENT
02322         TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2);
02323         CertificateStatusRequestItemV2* csr2 = extension ? extension->data
02324                                                          : NULL;
02325 
02326         if (!csr2) {
02327             /* look at context level */
02328 
02329             extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST_V2);
02330             csr2 = extension ? extension->data : NULL;
02331 
02332             if (!csr2)
02333                 return BUFFER_ERROR; /* unexpected extension */
02334 
02335             /* enable extension at ssl level */
02336             for (; csr2; csr2 = csr2->next) {
02337                 ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions,
02338                                               csr2->status_type, csr2->options);
02339                 if (ret != SSL_SUCCESS)
02340                     return ret;
02341 
02342                 switch (csr2->status_type) {
02343                     case WOLFSSL_CSR2_OCSP:
02344                         /* followed by */
02345                     case WOLFSSL_CSR2_OCSP_MULTI:
02346                         /* propagate nonce */
02347                         if (csr2->request.ocsp[0].nonceSz) {
02348                             OcspRequest* request =
02349                                         TLSX_CSR2_GetRequest(ssl->extensions,
02350                                                           csr2->status_type, 0);
02351 
02352                             if (request) {
02353                                 XMEMCPY(request->nonce,
02354                                         csr2->request.ocsp[0].nonce,
02355                                         csr2->request.ocsp[0].nonceSz);
02356 
02357                                 request->nonceSz =
02358                                                   csr2->request.ocsp[0].nonceSz;
02359                             }
02360                         }
02361                     break;
02362                 }
02363             }
02364 
02365         }
02366 
02367         ssl->status_request_v2 = 1;
02368 
02369         return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */
02370 #endif
02371     }
02372     else {
02373 #ifndef NO_WOLFSSL_SERVER
02374         byte   status_type;
02375         word16 request_length;
02376         word16 offset = 0;
02377         word16 size = 0;
02378 
02379         /* list size */
02380         ato16(input + offset, &request_length);
02381         offset += OPAQUE16_LEN;
02382 
02383         if (length - OPAQUE16_LEN != request_length)
02384             return BUFFER_ERROR;
02385 
02386         while (length > offset) {
02387             if (length - offset < ENUM_LEN + OPAQUE16_LEN)
02388                 return BUFFER_ERROR;
02389 
02390             status_type = input[offset++];
02391 
02392             ato16(input + offset, &request_length);
02393             offset += OPAQUE16_LEN;
02394 
02395             if (length - offset < request_length)
02396                 return BUFFER_ERROR;
02397 
02398             switch (status_type) {
02399                 case WOLFSSL_CSR2_OCSP:
02400                 case WOLFSSL_CSR2_OCSP_MULTI:
02401                     /* skip responder_id_list */
02402                     if (length - offset < OPAQUE16_LEN)
02403                         return BUFFER_ERROR;
02404 
02405                     ato16(input + offset, &size);
02406                     offset += OPAQUE16_LEN + size;
02407 
02408                     /* skip request_extensions */
02409                     if (length - offset < OPAQUE16_LEN)
02410                         return BUFFER_ERROR;
02411 
02412                     ato16(input + offset, &size);
02413                     offset += OPAQUE16_LEN + size;
02414 
02415                     if (offset > length)
02416                         return BUFFER_ERROR;
02417 
02418                     /* is able to send OCSP response? */
02419                     if (ssl->ctx->cm == NULL
02420                     || !ssl->ctx->cm->ocspStaplingEnabled)
02421                         continue;
02422                 break;
02423 
02424                 default:
02425                     /* unknown status type, skipping! */
02426                     offset += request_length;
02427                     continue;
02428             }
02429 
02430             /* if using status_request and already sending it, skip this one */
02431             #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
02432             if (ssl->status_request)
02433                 return 0;
02434             #endif
02435 
02436             /* accept the first good status_type and return */
02437             ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions,
02438                                                                 status_type, 0);
02439             if (ret != SSL_SUCCESS)
02440                 return ret; /* throw error */
02441 
02442             TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST_V2);
02443             ssl->status_request_v2 = status_type;
02444 
02445             return 0;
02446         }
02447 #endif
02448     }
02449 
02450     return 0;
02451 }
02452 
02453 int TLSX_CSR2_InitRequests(TLSX* extensions, DecodedCert* cert, byte isPeer)
02454 {
02455     TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2);
02456     CertificateStatusRequestItemV2* csr2 = extension ? extension->data : NULL;
02457     int ret = 0;
02458 
02459     for (; csr2; csr2 = csr2->next) {
02460         switch (csr2->status_type) {
02461             case WOLFSSL_CSR2_OCSP:
02462                 if (!isPeer || csr2->requests != 0)
02463                     break;
02464 
02465                 /* followed by */
02466 
02467             case WOLFSSL_CSR2_OCSP_MULTI: {
02468                 if (csr2->requests < 1 + MAX_CHAIN_DEPTH) {
02469                     byte nonce[MAX_OCSP_NONCE_SZ];
02470                     int  nonceSz = csr2->request.ocsp[0].nonceSz;
02471 
02472                     /* preserve nonce, replicating nonce of ocsp[0] */
02473                     XMEMCPY(nonce, csr2->request.ocsp[0].nonce, nonceSz);
02474 
02475                     if ((ret = InitOcspRequest(
02476                             &csr2->request.ocsp[csr2->requests], cert, 0)) != 0)
02477                         return ret;
02478 
02479                     /* restore nonce */
02480                     XMEMCPY(csr2->request.ocsp[csr2->requests].nonce,
02481                                                                 nonce, nonceSz);
02482                     csr2->request.ocsp[csr2->requests].nonceSz = nonceSz;
02483                     csr2->requests++;
02484                 }
02485             }
02486             break;
02487         }
02488     }
02489 
02490     return ret;
02491 }
02492 
02493 void* TLSX_CSR2_GetRequest(TLSX* extensions, byte status_type, byte index)
02494 {
02495     TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2);
02496     CertificateStatusRequestItemV2* csr2 = extension ? extension->data : NULL;
02497 
02498     for (; csr2; csr2 = csr2->next) {
02499         if (csr2->status_type == status_type) {
02500             switch (csr2->status_type) {
02501                 case WOLFSSL_CSR2_OCSP:
02502                     /* followed by */
02503 
02504                 case WOLFSSL_CSR2_OCSP_MULTI:
02505                     /* requests are initialized in the reverse order */
02506                     return index < csr2->requests
02507                          ? &csr2->request.ocsp[csr2->requests - index - 1]
02508                          : NULL;
02509                 break;
02510             }
02511         }
02512     }
02513 
02514     return NULL;
02515 }
02516 
02517 int TLSX_CSR2_ForceRequest(WOLFSSL* ssl)
02518 {
02519     TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2);
02520     CertificateStatusRequestItemV2* csr2 = extension ? extension->data : NULL;
02521 
02522     /* forces only the first one */
02523     if (csr2) {
02524         switch (csr2->status_type) {
02525             case WOLFSSL_CSR2_OCSP:
02526                 /* followed by */
02527 
02528             case WOLFSSL_CSR2_OCSP_MULTI:
02529                 if (ssl->ctx->cm->ocspEnabled)
02530                     return CheckOcspRequest(ssl->ctx->cm->ocsp,
02531                                                   &csr2->request.ocsp[0], NULL);
02532                 else
02533                     return OCSP_LOOKUP_FAIL;
02534         }
02535     }
02536 
02537     return 0;
02538 }
02539 
02540 int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type,
02541                                                                    byte options)
02542 {
02543     TLSX* extension = NULL;
02544     CertificateStatusRequestItemV2* csr2 = NULL;
02545     int ret = 0;
02546 
02547     if (!extensions)
02548         return BAD_FUNC_ARG;
02549 
02550     if (status_type != WOLFSSL_CSR2_OCSP
02551     &&  status_type != WOLFSSL_CSR2_OCSP_MULTI)
02552         return BAD_FUNC_ARG;
02553 
02554     csr2 = (CertificateStatusRequestItemV2*)
02555        XMALLOC(sizeof(CertificateStatusRequestItemV2), NULL, DYNAMIC_TYPE_TLSX);
02556     if (!csr2)
02557         return MEMORY_E;
02558 
02559     ForceZero(csr2, sizeof(CertificateStatusRequestItemV2));
02560 
02561     csr2->status_type = status_type;
02562     csr2->options     = options;
02563     csr2->next        = NULL;
02564 
02565     switch (csr2->status_type) {
02566         case WOLFSSL_CSR2_OCSP:
02567         case WOLFSSL_CSR2_OCSP_MULTI:
02568             if (options & WOLFSSL_CSR2_OCSP_USE_NONCE) {
02569                 WC_RNG rng;
02570 
02571                 if (wc_InitRng(&rng) == 0) {
02572                     if (wc_RNG_GenerateBlock(&rng, csr2->request.ocsp[0].nonce,
02573                                                         MAX_OCSP_NONCE_SZ) == 0)
02574                         csr2->request.ocsp[0].nonceSz = MAX_OCSP_NONCE_SZ;
02575 
02576                     wc_FreeRng(&rng);
02577                 }
02578             }
02579         break;
02580     }
02581 
02582     /* append new item */
02583     if ((extension = TLSX_Find(*extensions, TLSX_STATUS_REQUEST_V2))) {
02584         CertificateStatusRequestItemV2* last =
02585                                (CertificateStatusRequestItemV2*)extension->data;
02586 
02587         for (; last->next; last = last->next);
02588 
02589         last->next = csr2;
02590     }
02591     else if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST_V2, csr2))) {
02592         XFREE(csr2, NULL, DYNAMIC_TYPE_TLSX);
02593         return ret;
02594     }
02595 
02596     return SSL_SUCCESS;
02597 }
02598 
02599 #define CSR2_FREE_ALL TLSX_CSR2_FreeAll
02600 #define CSR2_GET_SIZE TLSX_CSR2_GetSize
02601 #define CSR2_WRITE    TLSX_CSR2_Write
02602 #define CSR2_PARSE    TLSX_CSR2_Parse
02603 
02604 #else
02605 
02606 #define CSR2_FREE_ALL(data)
02607 #define CSR2_GET_SIZE(a, b)    0
02608 #define CSR2_WRITE(a, b, c)    0
02609 #define CSR2_PARSE(a, b, c, d) 0
02610 
02611 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
02612 
02613 /******************************************************************************/
02614 /* Supported Elliptic Curves                                                  */
02615 /******************************************************************************/
02616 
02617 #ifdef HAVE_SUPPORTED_CURVES
02618 
02619 #ifndef HAVE_ECC
02620 #error Elliptic Curves Extension requires Elliptic Curve Cryptography. \
02621        Use --enable-ecc in the configure script or define HAVE_ECC.
02622 #endif
02623 
02624 static void TLSX_EllipticCurve_FreeAll(EllipticCurve* list)
02625 {
02626     EllipticCurve* curve;
02627 
02628     while ((curve = list)) {
02629         list = curve->next;
02630         XFREE(curve, 0, DYNAMIC_TYPE_TLSX);
02631     }
02632 }
02633 
02634 static int TLSX_EllipticCurve_Append(EllipticCurve** list, word16 name)
02635 {
02636     EllipticCurve* curve = NULL;
02637 
02638     if (list == NULL)
02639         return BAD_FUNC_ARG;
02640 
02641     curve = (EllipticCurve*)XMALLOC(sizeof(EllipticCurve), NULL,
02642                                                              DYNAMIC_TYPE_TLSX);
02643     if (curve == NULL)
02644         return MEMORY_E;
02645 
02646     curve->name = name;
02647     curve->next = *list;
02648 
02649     *list = curve;
02650 
02651     return 0;
02652 }
02653 
02654 #ifndef NO_WOLFSSL_CLIENT
02655 
02656 static void TLSX_EllipticCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
02657 {
02658     int i;
02659 
02660     for (i = 0; i < ssl->suites->suiteSz; i+= 2)
02661         if (ssl->suites->suites[i] == ECC_BYTE ||
02662                                           ssl->suites->suites[i] == CHACHA_BYTE)
02663             return;
02664 
02665     /* turns semaphore on to avoid sending this extension. */
02666     TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS));
02667 }
02668 
02669 static word16 TLSX_EllipticCurve_GetSize(EllipticCurve* list)
02670 {
02671     EllipticCurve* curve;
02672     word16 length = OPAQUE16_LEN; /* list length */
02673 
02674     while ((curve = list)) {
02675         list = curve->next;
02676         length += OPAQUE16_LEN; /* curve length */
02677     }
02678 
02679     return length;
02680 }
02681 
02682 static word16 TLSX_EllipticCurve_WriteR(EllipticCurve* curve, byte* output);
02683 static word16 TLSX_EllipticCurve_WriteR(EllipticCurve* curve, byte* output)
02684 {
02685     word16 offset = 0;
02686 
02687     if (!curve)
02688         return offset;
02689 
02690     offset = TLSX_EllipticCurve_WriteR(curve->next, output);
02691     c16toa(curve->name, output + offset);
02692 
02693     return OPAQUE16_LEN + offset;
02694 }
02695 
02696 static word16 TLSX_EllipticCurve_Write(EllipticCurve* list, byte* output)
02697 {
02698     word16 length = TLSX_EllipticCurve_WriteR(list, output + OPAQUE16_LEN);
02699 
02700     c16toa(length, output); /* writing list length */
02701 
02702     return OPAQUE16_LEN + length;
02703 }
02704 
02705 #endif /* NO_WOLFSSL_CLIENT */
02706 #ifndef NO_WOLFSSL_SERVER
02707 
02708 static int TLSX_EllipticCurve_Parse(WOLFSSL* ssl, byte* input, word16 length,
02709                                                                  byte isRequest)
02710 {
02711     word16 offset;
02712     word16 name;
02713     int r;
02714 
02715     (void) isRequest; /* shut up compiler! */
02716 
02717     if (OPAQUE16_LEN > length || length % OPAQUE16_LEN)
02718         return BUFFER_ERROR;
02719 
02720     ato16(input, &offset);
02721 
02722     /* validating curve list length */
02723     if (length != OPAQUE16_LEN + offset)
02724         return BUFFER_ERROR;
02725 
02726     while (offset) {
02727         ato16(input + offset, &name);
02728         offset -= OPAQUE16_LEN;
02729 
02730         r = TLSX_UseSupportedCurve(&ssl->extensions, name);
02731 
02732         if (r != SSL_SUCCESS) return r; /* throw error */
02733     }
02734 
02735     return 0;
02736 }
02737 
02738 int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
02739     TLSX*          extension = (first == ECC_BYTE || first == CHACHA_BYTE)
02740                              ? TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS)
02741                              : NULL;
02742     EllipticCurve* curve     = NULL;
02743     word32         oid       = 0;
02744     word16         octets    = 0; /* according to 'ecc_set_type ecc_sets[];' */
02745     int            sig       = 0; /* validate signature */
02746     int            key       = 0; /* validate key       */
02747 
02748     (void)oid;
02749     (void)octets;
02750 
02751     if (!extension)
02752         return 1; /* no suite restriction */
02753 
02754     for (curve = extension->data; curve && !(sig && key); curve = curve->next) {
02755 
02756         switch (curve->name) {
02757 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160)
02758             case WOLFSSL_ECC_SECP160R1: oid = ECC_160R1; octets = 20; break;
02759 #endif
02760 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192)
02761             case WOLFSSL_ECC_SECP192R1: oid = ECC_192R1; octets = 24; break;
02762 #endif
02763 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224)
02764             case WOLFSSL_ECC_SECP224R1: oid = ECC_224R1; octets = 28; break;
02765 #endif
02766 #if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256)
02767             case WOLFSSL_ECC_SECP256R1: oid = ECC_256R1; octets = 32; break;
02768 #endif
02769 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384)
02770             case WOLFSSL_ECC_SECP384R1: oid = ECC_384R1; octets = 48; break;
02771 #endif
02772 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521)
02773             case WOLFSSL_ECC_SECP521R1: oid = ECC_521R1; octets = 66; break;
02774 #endif
02775             default: continue; /* unsupported curve */
02776         }
02777 
02778         if (first == ECC_BYTE) {
02779         switch (second) {
02780 #ifndef NO_DSA
02781             /* ECDHE_ECDSA */
02782             case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
02783             case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
02784             case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
02785             case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
02786             case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
02787             case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
02788             case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
02789             case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
02790             case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
02791             case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
02792                 sig |= ssl->pkCurveOID == oid;
02793                 key |= ssl->eccTempKeySz == octets;
02794             break;
02795 
02796             /* ECDH_ECDSA */
02797             case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
02798             case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
02799             case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
02800             case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
02801             case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
02802             case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
02803             case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
02804             case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
02805                 sig |= ssl->pkCurveOID == oid;
02806                 key |= ssl->pkCurveOID == oid;
02807             break;
02808 #endif
02809 #ifndef NO_RSA
02810             /* ECDHE_RSA */
02811             case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
02812             case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
02813             case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
02814             case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
02815             case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
02816             case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
02817             case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
02818             case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
02819                 sig = 1;
02820                 key |= ssl->eccTempKeySz == octets;
02821             break;
02822 
02823             /* ECDH_RSA */
02824             case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
02825             case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
02826             case TLS_ECDH_RSA_WITH_RC4_128_SHA:
02827             case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
02828             case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
02829             case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
02830             case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
02831             case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
02832                 sig = 1;
02833                 key |= ssl->pkCurveOID == oid;
02834             break;
02835 #endif
02836             default:
02837                 sig = 1;
02838                 key = 1;
02839             break;
02840         }
02841         }
02842 
02843         /* ChaCha20-Poly1305 ECC cipher suites */
02844         if (first == CHACHA_BYTE) {
02845         switch (second) {
02846 #ifndef NO_DSA
02847             /* ECDHE_ECDSA */
02848             case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
02849             case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
02850                 sig |= ssl->pkCurveOID == oid;
02851                 key |= ssl->eccTempKeySz == octets;
02852             break;
02853 #endif
02854 #ifndef NO_RSA
02855             /* ECDHE_RSA */
02856             case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
02857             case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
02858                 sig = 1;
02859                 key |= ssl->eccTempKeySz == octets;
02860             break;
02861 #endif
02862             default:
02863                 sig = 1;
02864                 key = 1;
02865             break;
02866         }
02867         }
02868     }
02869 
02870     return sig && key;
02871 }
02872 
02873 #endif /* NO_WOLFSSL_SERVER */
02874 
02875 int TLSX_UseSupportedCurve(TLSX** extensions, word16 name)
02876 {
02877     TLSX*          extension = TLSX_Find(*extensions, TLSX_SUPPORTED_GROUPS);
02878     EllipticCurve* curve     = NULL;
02879     int            ret       = 0;
02880 
02881     if (extensions == NULL)
02882         return BAD_FUNC_ARG;
02883 
02884     if ((ret = TLSX_EllipticCurve_Append(&curve, name)) != 0)
02885         return ret;
02886 
02887     if (!extension) {
02888         if ((ret = TLSX_Push(extensions, TLSX_SUPPORTED_GROUPS, curve)) != 0) {
02889             XFREE(curve, 0, DYNAMIC_TYPE_TLSX);
02890             return ret;
02891         }
02892     }
02893     else {
02894         /* push new EllipticCurve object to extension data. */
02895         curve->next = (EllipticCurve*)extension->data;
02896         extension->data = (void*)curve;
02897 
02898         /* look for another curve of the same name to remove (replacement) */
02899         do {
02900             if (curve->next && curve->next->name == name) {
02901                 EllipticCurve *next = curve->next;
02902 
02903                 curve->next = next->next;
02904                 XFREE(next, 0, DYNAMIC_TYPE_TLSX);
02905 
02906                 break;
02907             }
02908         } while ((curve = curve->next));
02909     }
02910 
02911     return SSL_SUCCESS;
02912 }
02913 
02914 #define EC_FREE_ALL         TLSX_EllipticCurve_FreeAll
02915 #define EC_VALIDATE_REQUEST TLSX_EllipticCurve_ValidateRequest
02916 
02917 #ifndef NO_WOLFSSL_CLIENT
02918 #define EC_GET_SIZE TLSX_EllipticCurve_GetSize
02919 #define EC_WRITE    TLSX_EllipticCurve_Write
02920 #else
02921 #define EC_GET_SIZE(list)         0
02922 #define EC_WRITE(a, b)            0
02923 #endif
02924 
02925 #ifndef NO_WOLFSSL_SERVER
02926 #define EC_PARSE TLSX_EllipticCurve_Parse
02927 #else
02928 #define EC_PARSE(a, b, c, d)      0
02929 #endif
02930 
02931 #else
02932 
02933 #define EC_FREE_ALL(list)
02934 #define EC_GET_SIZE(list)         0
02935 #define EC_WRITE(a, b)            0
02936 #define EC_PARSE(a, b, c, d)      0
02937 #define EC_VALIDATE_REQUEST(a, b)
02938 
02939 #endif /* HAVE_SUPPORTED_CURVES */
02940 
02941 /******************************************************************************/
02942 /* Renegotiation Indication                                                   */
02943 /******************************************************************************/
02944 
02945 #ifdef HAVE_SECURE_RENEGOTIATION
02946 
02947 static byte TLSX_SecureRenegotiation_GetSize(SecureRenegotiation* data,
02948                                                                   int isRequest)
02949 {
02950     byte length = OPAQUE8_LEN; /* empty info length */
02951 
02952     if (data->enabled) {
02953         /* client sends client_verify_data only */
02954         length += TLS_FINISHED_SZ;
02955 
02956         /* server also sends server_verify_data */
02957         if (!isRequest)
02958             length += TLS_FINISHED_SZ;
02959     }
02960 
02961     return length;
02962 }
02963 
02964 static word16 TLSX_SecureRenegotiation_Write(SecureRenegotiation* data,
02965                                                     byte* output, int isRequest)
02966 {
02967     word16 offset = OPAQUE8_LEN; /* RenegotiationInfo length */
02968 
02969     if (data->enabled) {
02970         /* client sends client_verify_data only */
02971         XMEMCPY(output + offset, data->client_verify_data, TLS_FINISHED_SZ);
02972         offset += TLS_FINISHED_SZ;
02973 
02974         /* server also sends server_verify_data */
02975         if (!isRequest) {
02976             XMEMCPY(output + offset, data->server_verify_data, TLS_FINISHED_SZ);
02977             offset += TLS_FINISHED_SZ;
02978         }
02979     }
02980 
02981     output[0] = offset - 1;  /* info length - self */
02982 
02983     return offset;
02984 }
02985 
02986 static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, byte* input,
02987                                                   word16 length, byte isRequest)
02988 {
02989     int ret = SECURE_RENEGOTIATION_E;
02990 
02991     if (length >= OPAQUE8_LEN) {
02992         if (ssl->secure_renegotiation == NULL) {
02993         #ifndef NO_WOLFSSL_SERVER
02994             if (isRequest && *input == 0) {
02995                 ret = 0;  /* don't reply, user didn't enable */
02996             }
02997         #endif
02998         }
02999         else if (isRequest) {
03000         #ifndef NO_WOLFSSL_SERVER
03001             if (*input == TLS_FINISHED_SZ) {
03002                 /* TODO compare client_verify_data */
03003                 ret = 0;
03004             }
03005         #endif
03006         }
03007         else {
03008         #ifndef NO_WOLFSSL_CLIENT
03009             if (!ssl->secure_renegotiation->enabled) {
03010                 if (*input == 0) {
03011                     ssl->secure_renegotiation->enabled = 1;
03012                     ret = 0;
03013                 }
03014             }
03015             else if (*input == 2 * TLS_FINISHED_SZ) {
03016                 /* TODO compare client_verify_data and server_verify_data */
03017                 ret = 0;
03018             }
03019         #endif
03020         }
03021     }
03022 
03023     if (ret != 0) {
03024         /* TODO: turn on fatal error at ssl level too */
03025         SendAlert(ssl, alert_fatal, handshake_failure);
03026     }
03027 
03028     return ret;
03029 }
03030 
03031 int TLSX_UseSecureRenegotiation(TLSX** extensions)
03032 {
03033     int ret = 0;
03034     SecureRenegotiation* data = NULL;
03035 
03036     data = (SecureRenegotiation*)XMALLOC(sizeof(SecureRenegotiation), NULL,
03037                                                              DYNAMIC_TYPE_TLSX);
03038     if (data == NULL)
03039         return MEMORY_E;
03040 
03041     XMEMSET(data, 0, sizeof(SecureRenegotiation));
03042 
03043     ret = TLSX_Push(extensions, TLSX_RENEGOTIATION_INFO, data);
03044     if (ret != 0) {
03045         XFREE(data, 0, DYNAMIC_TYPE_TLSX);
03046         return ret;
03047     }
03048 
03049     return SSL_SUCCESS;
03050 }
03051 
03052 
03053 #define SCR_FREE_ALL(data) XFREE(data, NULL, DYNAMIC_TYPE_TLSX)
03054 #define SCR_GET_SIZE       TLSX_SecureRenegotiation_GetSize
03055 #define SCR_WRITE          TLSX_SecureRenegotiation_Write
03056 #define SCR_PARSE          TLSX_SecureRenegotiation_Parse
03057 
03058 #else
03059 
03060 #define SCR_FREE_ALL(a)
03061 #define SCR_GET_SIZE(a, b)    0
03062 #define SCR_WRITE(a, b, c)    0
03063 #define SCR_PARSE(a, b, c, d) 0
03064 
03065 #endif /* HAVE_SECURE_RENEGOTIATION */
03066 
03067 /******************************************************************************/
03068 /* Session Tickets                                                            */
03069 /******************************************************************************/
03070 
03071 #ifdef HAVE_SESSION_TICKET
03072 
03073 static void TLSX_SessionTicket_ValidateRequest(WOLFSSL* ssl)
03074 {
03075     TLSX*          extension = TLSX_Find(ssl->extensions, TLSX_SESSION_TICKET);
03076     SessionTicket* ticket    = extension ? extension->data : NULL;
03077 
03078     if (ticket) {
03079         /* TODO validate ticket timeout here! */
03080         if (ticket->lifetime == 0xfffffff) {
03081             /* send empty ticket on timeout */
03082             TLSX_UseSessionTicket(&ssl->extensions, NULL);
03083         }
03084     }
03085 }
03086 
03087 
03088 static word16 TLSX_SessionTicket_GetSize(SessionTicket* ticket, int isRequest)
03089 {
03090     (void)isRequest;
03091     return ticket ? ticket->size : 0;
03092 }
03093 
03094 static word16 TLSX_SessionTicket_Write(SessionTicket* ticket, byte* output,
03095                                                                   int isRequest)
03096 {
03097     word16 offset = 0; /* empty ticket */
03098 
03099     if (isRequest && ticket) {
03100         XMEMCPY(output + offset, ticket->data, ticket->size);
03101         offset += ticket->size;
03102     }
03103 
03104     return offset;
03105 }
03106 
03107 
03108 static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, byte* input, word16 length,
03109                                                                  byte isRequest)
03110 {
03111     int ret = 0;
03112 
03113     if (!isRequest) {
03114         /* client side */
03115         if (length != 0)
03116             return BUFFER_ERROR;
03117 
03118         ssl->expect_session_ticket = 1;
03119     }
03120 #ifndef NO_WOLFSSL_SERVER
03121     else {
03122         /* server side */
03123         if (ssl->ctx->ticketEncCb == NULL) {
03124             WOLFSSL_MSG("Client sent session ticket, server has no callback");
03125             return 0;
03126         }
03127 
03128         if (length == 0) {
03129             /* blank ticket */
03130             ret = TLSX_UseSessionTicket(&ssl->extensions, NULL);
03131             if (ret == SSL_SUCCESS) {
03132                 ret = 0;
03133                 TLSX_SetResponse(ssl, TLSX_SESSION_TICKET);  /* send blank ticket */
03134                 ssl->options.createTicket = 1;  /* will send ticket msg */
03135                 ssl->options.useTicket    = 1;
03136             }
03137         } else {
03138             /* got actual ticket from client */
03139             ret = DoClientTicket(ssl, input, length);
03140             if (ret == WOLFSSL_TICKET_RET_OK) {    /* use ticket to resume */
03141                 WOLFSSL_MSG("Using exisitng client ticket");
03142                 ssl->options.useTicket = 1;
03143                 ssl->options.resuming  = 1;
03144             } else if (ret == WOLFSSL_TICKET_RET_CREATE) {
03145                 WOLFSSL_MSG("Using existing client ticket, creating new one");
03146                 ret = TLSX_UseSessionTicket(&ssl->extensions, NULL);
03147                 if (ret == SSL_SUCCESS) {
03148                     ret = 0;
03149                     TLSX_SetResponse(ssl, TLSX_SESSION_TICKET);
03150                                                     /* send blank ticket */
03151                     ssl->options.createTicket = 1;  /* will send ticket msg */
03152                     ssl->options.useTicket    = 1;
03153                     ssl->options.resuming     = 1;
03154                 }
03155             } else if (ret == WOLFSSL_TICKET_RET_REJECT) {
03156                 WOLFSSL_MSG("Process client ticket rejected, not using");
03157                 ret = 0;  /* not fatal */
03158             } else if (ret == WOLFSSL_TICKET_RET_FATAL || ret < 0) {
03159                 WOLFSSL_MSG("Process client ticket fatal error, not using");
03160             }
03161         }
03162     }
03163 #endif /* NO_WOLFSSL_SERVER */
03164 
03165     return ret;
03166 }
03167 
03168 WOLFSSL_LOCAL SessionTicket* TLSX_SessionTicket_Create(word32 lifetime,
03169                                                        byte* data, word16 size)
03170 {
03171     SessionTicket* ticket = (SessionTicket*)XMALLOC(sizeof(SessionTicket),
03172                                                        NULL, DYNAMIC_TYPE_TLSX);
03173     if (ticket) {
03174         ticket->data = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_TLSX);
03175         if (ticket->data == NULL) {
03176             XFREE(ticket, NULL, DYNAMIC_TYPE_TLSX);
03177             return NULL;
03178         }
03179 
03180         XMEMCPY(ticket->data, data, size);
03181         ticket->size     = size;
03182         ticket->lifetime = lifetime;
03183     }
03184 
03185     return ticket;
03186 }
03187 WOLFSSL_LOCAL void TLSX_SessionTicket_Free(SessionTicket* ticket)
03188 {
03189     if (ticket) {
03190         XFREE(ticket->data, NULL, DYNAMIC_TYPE_TLSX);
03191         XFREE(ticket,       NULL, DYNAMIC_TYPE_TLSX);
03192     }
03193 }
03194 
03195 int TLSX_UseSessionTicket(TLSX** extensions, SessionTicket* ticket)
03196 {
03197     int ret = 0;
03198 
03199     if (extensions == NULL)
03200         return BAD_FUNC_ARG;
03201 
03202     /* If the ticket is NULL, the client will request a new ticket from the
03203        server. Otherwise, the client will use it in the next client hello. */
03204     if ((ret = TLSX_Push(extensions, TLSX_SESSION_TICKET, (void*)ticket)) != 0)
03205         return ret;
03206 
03207     return SSL_SUCCESS;
03208 }
03209 
03210 #define STK_VALIDATE_REQUEST TLSX_SessionTicket_ValidateRequest
03211 #define STK_GET_SIZE         TLSX_SessionTicket_GetSize
03212 #define STK_WRITE            TLSX_SessionTicket_Write
03213 #define STK_PARSE            TLSX_SessionTicket_Parse
03214 
03215 #else
03216 
03217 #define STK_VALIDATE_REQUEST(a)
03218 #define STK_GET_SIZE(a, b)      0
03219 #define STK_WRITE(a, b, c)      0
03220 #define STK_PARSE(a, b, c, d)   0
03221 
03222 #endif /* HAVE_SESSION_TICKET */
03223 
03224 /******************************************************************************/
03225 /* Quantum-Safe-Hybrid                                                        */
03226 /******************************************************************************/
03227 
03228 #ifdef HAVE_QSH
03229 static WC_RNG* rng;
03230 static wolfSSL_Mutex* rngMutex;
03231 
03232 static void TLSX_QSH_FreeAll(QSHScheme* list)
03233 {
03234     QSHScheme* current;
03235 
03236     while ((current = list)) {
03237         list = current->next;
03238         XFREE(current, 0, DYNAMIC_TYPE_TLSX);
03239     }
03240 }
03241 
03242 static int TLSX_QSH_Append(QSHScheme** list, word16 name, byte* pub,
03243                                                                   word16 pubLen)
03244 {
03245     QSHScheme* temp;
03246 
03247     if (list == NULL)
03248         return BAD_FUNC_ARG;
03249 
03250     if ((temp = (QSHScheme*)XMALLOC(sizeof(QSHScheme), NULL,
03251                                                     DYNAMIC_TYPE_TLSX)) == NULL)
03252         return MEMORY_E;
03253 
03254     temp->name  = name;
03255     temp->PK    = pub;
03256     temp->PKLen = pubLen;
03257     temp->next  = *list;
03258 
03259     *list = temp;
03260 
03261     return 0;
03262 }
03263 
03264 
03265 /* request for server's public key : 02 indicates 0-2 requested */
03266 static byte TLSX_QSH_SerPKReq(byte* output, byte isRequest)
03267 {
03268     if (isRequest) {
03269         /* only request one public key from the server */
03270         output[0] = 0x01;
03271 
03272         return OPAQUE8_LEN;
03273     }
03274     else {
03275         return 0;
03276     }
03277 }
03278 
03279 #ifndef NO_WOLFSSL_CLIENT
03280 
03281 /* check for TLS_QSH suite */
03282 static void TLSX_QSH_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
03283 {
03284     int i;
03285 
03286     for (i = 0; i < ssl->suites->suiteSz; i+= 2)
03287         if (ssl->suites->suites[i] == QSH_BYTE)
03288             return;
03289 
03290     /* No QSH suite found */
03291     TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_QUANTUM_SAFE_HYBRID));
03292 }
03293 
03294 
03295 /* return the size of the QSH hello extension
03296    list      the list of QSHScheme structs containing id and key
03297    isRequest if 1 then is being sent to the server
03298  */
03299 word16 TLSX_QSH_GetSize(QSHScheme* list, byte isRequest)
03300 {
03301     QSHScheme* temp = list;
03302     word16 length = 0;
03303 
03304     /* account for size of scheme list and public key list */
03305     if (isRequest)
03306         length = OPAQUE16_LEN;
03307     length += OPAQUE24_LEN;
03308 
03309     /* for each non null element in list add size */
03310     while ((temp)) {
03311         /* add public key info Scheme | Key Length | Key */
03312         length += OPAQUE16_LEN;
03313         length += OPAQUE16_LEN;
03314         length += temp->PKLen;
03315 
03316         /* if client add name size for scheme list
03317            advance to next QSHScheme struct in list */
03318         if (isRequest)
03319             length += OPAQUE16_LEN;
03320         temp = temp->next;
03321     }
03322 
03323     /* add length for request server public keys */
03324     if (isRequest)
03325         length += OPAQUE8_LEN;
03326 
03327     return length;
03328 }
03329 
03330 
03331 /* write out a list of QSHScheme IDs */
03332 static word16 TLSX_QSH_Write(QSHScheme* list, byte* output)
03333 {
03334     QSHScheme* current = list;
03335     word16 length      = 0;
03336 
03337     length += OPAQUE16_LEN;
03338 
03339     while (current) {
03340         c16toa(current->name, output + length);
03341         length += OPAQUE16_LEN;
03342         current = (QSHScheme*)current->next;
03343     }
03344 
03345     c16toa(length - OPAQUE16_LEN, output); /* writing list length */
03346 
03347     return length;
03348 }
03349 
03350 
03351 /* write public key list in extension */
03352 static word16 TLSX_QSHPK_WriteR(QSHScheme* format, byte* output);
03353 static word16 TLSX_QSHPK_WriteR(QSHScheme* format, byte* output)
03354 {
03355     word32 offset = 0;
03356     word16 public_len = 0;
03357 
03358     if (!format)
03359         return offset;
03360 
03361     /* write scheme ID */
03362     c16toa(format->name, output + offset);
03363     offset += OPAQUE16_LEN;
03364 
03365     /* write public key matching scheme */
03366     public_len = format->PKLen;
03367     c16toa(public_len, output + offset);
03368     offset += OPAQUE16_LEN;
03369     if (format->PK) {
03370         XMEMCPY(output+offset, format->PK, public_len);
03371     }
03372 
03373     return public_len + offset;
03374 }
03375 
03376 word16 TLSX_QSHPK_Write(QSHScheme* list, byte* output)
03377 {
03378     QSHScheme* current = list;
03379     word32 length = 0;
03380     word24 toWire;
03381 
03382     length += OPAQUE24_LEN;
03383 
03384     while (current) {
03385         length += TLSX_QSHPK_WriteR(current, output + length);
03386         current = (QSHScheme*)current->next;
03387     }
03388     /* length of public keys sent */
03389     c32to24(length - OPAQUE24_LEN, toWire);
03390     output[0] = toWire[0];
03391     output[1] = toWire[1];
03392     output[2] = toWire[2];
03393 
03394     return length;
03395 }
03396 
03397 #endif /* NO_WOLFSSL_CLIENT */
03398 #ifndef NO_WOLFSSL_SERVER
03399 
03400 static void TLSX_QSHAgreement(TLSX** extensions)
03401 {
03402     TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID);
03403     QSHScheme* format = NULL;
03404     QSHScheme* del    = NULL;
03405     QSHScheme* prev   = NULL;
03406 
03407     if (extension == NULL)
03408         return;
03409 
03410     format = (QSHScheme*)extension->data;
03411     while (format) {
03412         if (format->PKLen == 0) {
03413             /* case of head */
03414             if (format == extension->data) {
03415                 extension->data = format->next;
03416             }
03417             if (prev)
03418                 prev->next = format->next;
03419             del = format;
03420             format = format->next;
03421             XFREE(del, 0, DYNAMIC_TYPE_TMP_ARRAY);
03422             del = NULL;
03423         } else {
03424             prev   = format;
03425             format = format->next;
03426         }
03427     }
03428 }
03429 
03430 
03431 /* Parse in hello extension
03432    input     the byte stream to process
03433    length    length of total extension found
03434    isRequest set to 1 if being sent to the server
03435  */
03436 static int TLSX_QSH_Parse(WOLFSSL* ssl, byte* input, word16 length,
03437                                                                  byte isRequest)
03438 {
03439     byte   numKeys    = 0;
03440     word16 offset     = 0;
03441     word16 schemSz    = 0;
03442     word16 offset_len = 0;
03443     word32 offset_pk  = 0;
03444     word16 name  = 0;
03445     word16 PKLen = 0;
03446     byte*  PK = NULL;
03447     int r;
03448 
03449 
03450     if (OPAQUE16_LEN > length)
03451         return BUFFER_ERROR;
03452 
03453     if (isRequest) {
03454         ato16(input, &schemSz);
03455 
03456         /* list of public keys available for QSH schemes */
03457         offset_len = schemSz + OPAQUE16_LEN;
03458     }
03459 
03460     offset_pk = ((input[offset_len] << 16)   & 0xFF00000) |
03461                 (((input[offset_len + 1]) << 8) & 0xFF00) |
03462                 (input[offset_len + 2] & 0xFF);
03463     offset_len += OPAQUE24_LEN;
03464 
03465     /* check buffer size */
03466     if (offset_pk > length)
03467         return BUFFER_ERROR;
03468 
03469     /* set maximum number of keys the client will accept */
03470     if (!isRequest)
03471         numKeys = (ssl->maxRequest < 1)? 1 : ssl->maxRequest;
03472 
03473     /* hello extension read list of scheme ids */
03474     if (isRequest) {
03475 
03476         /* read in request for public keys */
03477         ssl->minRequest = (input[length -1] >> 4) & 0xFF;
03478         ssl->maxRequest = input[length -1] & 0x0F;
03479 
03480         /* choose the min between min requested by client and 1 */
03481         numKeys = (ssl->minRequest > 1) ? ssl->minRequest : 1;
03482 
03483         if (ssl->minRequest > ssl->maxRequest)
03484             return BAD_FUNC_ARG;
03485 
03486         offset  += OPAQUE16_LEN;
03487         schemSz += offset;
03488 
03489         /* check buffer size */
03490         if (schemSz > length)
03491             return BUFFER_ERROR;
03492 
03493         while ((offset < schemSz) && numKeys) {
03494             /* Scheme ID list */
03495             ato16(input + offset, &name);
03496             offset += OPAQUE16_LEN;
03497 
03498             /* validate we have scheme id */
03499             if (ssl->user_set_QSHSchemes &&
03500                     !TLSX_ValidateQSHScheme(&ssl->extensions, name)) {
03501                 continue;
03502             }
03503 
03504             /* server create keys on demand */
03505             if ((r = TLSX_CreateNtruKey(ssl, name)) != 0) {
03506                 WOLFSSL_MSG("Error creating ntru keys");
03507                 return r;
03508             }
03509 
03510             /* peer sent an agreed upon scheme */
03511             r = TLSX_UseQSHScheme(&ssl->extensions, name, NULL, 0);
03512 
03513             if (r != SSL_SUCCESS) return r; /* throw error */
03514 
03515             numKeys--;
03516         }
03517 
03518         /* choose the min between min requested by client and 1 */
03519         numKeys = (ssl->minRequest > 1) ? ssl->minRequest : 1;
03520     }
03521 
03522     /* QSHPK struct */
03523     offset_pk += offset_len;
03524     while ((offset_len < offset_pk) && numKeys) {
03525         QSHKey * temp;
03526 
03527         if ((temp = (QSHKey*)XMALLOC(sizeof(QSHKey), NULL,
03528                                                     DYNAMIC_TYPE_TLSX)) == NULL)
03529             return MEMORY_E;
03530 
03531         /* initialize */
03532         temp->next = NULL;
03533         temp->pub.buffer = NULL;
03534         temp->pub.length = 0;
03535         temp->pri.buffer = NULL;
03536         temp->pri.length = 0;
03537 
03538         /* scheme id */
03539         ato16(input + offset_len, &(temp->name));
03540         offset_len += OPAQUE16_LEN;
03541 
03542         /* public key length */
03543         ato16(input + offset_len, &PKLen);
03544         temp->pub.length = PKLen;
03545         offset_len += OPAQUE16_LEN;
03546 
03547 
03548         if (isRequest) {
03549             /* validate we have scheme id */
03550             if (ssl->user_set_QSHSchemes &&
03551                     (!TLSX_ValidateQSHScheme(&ssl->extensions, temp->name))) {
03552                 offset_len += PKLen;
03553                 XFREE(temp, 0, DYNAMIC_TYPE_TLSX);
03554                 continue;
03555             }
03556         }
03557 
03558         /* read in public key */
03559         if (PKLen > 0) {
03560             temp->pub.buffer = (byte*)XMALLOC(temp->pub.length,
03561                                                  NULL, DYNAMIC_TYPE_PUBLIC_KEY);
03562             XMEMCPY(temp->pub.buffer, input + offset_len, temp->pub.length);
03563             offset_len += PKLen;
03564         }
03565         else {
03566             PK = NULL;
03567         }
03568 
03569         /* use own key when adding to extensions list for sending reply */
03570         PKLen = 0;
03571         PK = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, &PKLen, temp->name);
03572         r  = TLSX_UseQSHScheme(&ssl->extensions, temp->name, PK, PKLen);
03573 
03574         /* store peers key */
03575         ssl->peerQSHKeyPresent = 1;
03576         if (TLSX_AddQSHKey(&ssl->peerQSHKey, temp) != 0)
03577             return MEMORY_E;
03578 
03579         if (temp->pub.length == 0) {
03580             XFREE(temp, 0, DYNAMIC_TYPE_TLSX);
03581         }
03582 
03583         if (r != SSL_SUCCESS) {return r;} /* throw error */
03584 
03585         numKeys--;
03586     }
03587 
03588     /* reply to a QSH extension sent from client */
03589     if (isRequest) {
03590         TLSX_SetResponse(ssl, TLSX_QUANTUM_SAFE_HYBRID);
03591         /* only use schemes we have key generated for -- free the rest */
03592         TLSX_QSHAgreement(&ssl->extensions);
03593     }
03594 
03595     return 0;
03596 }
03597 
03598 
03599 /* Used for parsing in QSHCipher structs on Key Exchange */
03600 int TLSX_QSHCipher_Parse(WOLFSSL* ssl, const byte* input, word16 length,
03601                                                                   byte isServer)
03602 {
03603     QSHKey* key;
03604     word16 Max_Secret_Len = 48;
03605     word16 offset     = 0;
03606     word16 offset_len = 0;
03607     word32 offset_pk  = 0;
03608     word16 name       = 0;
03609     word16 secretLen  = 0;
03610     byte*  secret     = NULL;
03611     word16 buffLen    = 0;
03612     byte buff[145]; /* size enough for 3 secrets */
03613     buffer* buf;
03614 
03615     /* pointer to location where secret should be stored */
03616     if (isServer) {
03617         buf = ssl->QSH_secret->CliSi;
03618     }
03619     else {
03620         buf = ssl->QSH_secret->SerSi;
03621     }
03622 
03623     offset_pk = ((input[offset_len] << 16)    & 0xFF0000) |
03624                 (((input[offset_len + 1]) << 8) & 0xFF00) |
03625                 (input[offset_len + 2] & 0xFF);
03626     offset_len += OPAQUE24_LEN;
03627 
03628     /* validating extension list length -- check if trying to read over edge
03629        of buffer */
03630     if (length < (offset_pk + OPAQUE24_LEN)) {
03631         return BUFFER_ERROR;
03632     }
03633 
03634     /* QSHCipherList struct */
03635     offset_pk += offset_len;
03636     while (offset_len < offset_pk) {
03637 
03638         /* scheme id */
03639         ato16(input + offset_len, &name);
03640         offset_len += OPAQUE16_LEN;
03641 
03642         /* public key length */
03643         ato16(input + offset_len, &secretLen);
03644         offset_len += OPAQUE16_LEN;
03645 
03646         /* read in public key */
03647         if (secretLen > 0) {
03648             secret = (byte*)(input + offset_len);
03649             offset_len += secretLen;
03650         }
03651         else {
03652             secret = NULL;
03653         }
03654 
03655         /* no secret sent */
03656         if (secret == NULL)
03657             continue;
03658 
03659         /* find corresponding key */
03660         key = ssl->QSH_Key;
03661         while (key) {
03662             if (key->name == name)
03663                 break;
03664             else
03665                 key = (QSHKey*)key->next;
03666         }
03667 
03668         /* if we do not have the key than there was a big issue negotiation */
03669         if (key == NULL) {
03670             WOLFSSL_MSG("key was null for decryption!!!\n");
03671             return MEMORY_E;
03672         }
03673 
03674         /* Decrypt sent secret */
03675         buffLen = Max_Secret_Len;
03676         QSH_Decrypt(key, secret, secretLen, buff + offset, &buffLen);
03677         offset += buffLen;
03678     }
03679 
03680     /* allocate memory for buffer */
03681     buf->length = offset;
03682     buf->buffer = (byte*)XMALLOC(offset, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03683     if (buf->buffer == NULL)
03684         return MEMORY_E;
03685 
03686     /* store secrets */
03687     XMEMCPY(buf->buffer, buff, offset);
03688     ForceZero(buff, offset);
03689 
03690     return offset_len;
03691 }
03692 
03693 
03694 /* return 1 on success */
03695 int TLSX_ValidateQSHScheme(TLSX** extensions, word16 theirs) {
03696     TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID);
03697     QSHScheme* format    = NULL;
03698 
03699     /* if no extension is sent then do not use QSH */
03700     if (!extension) {
03701         WOLFSSL_MSG("No QSH Extension");
03702         return 0;
03703     }
03704 
03705     for (format = (QSHScheme*)extension->data; format; format = format->next) {
03706         if (format->name == theirs) {
03707             WOLFSSL_MSG("Found Matching QSH Scheme");
03708             return 1; /* have QSH */
03709         }
03710     }
03711 
03712     return 0;
03713 }
03714 #endif /* NO_WOLFSSL_SERVER */
03715 
03716 /* test if the QSH Scheme is implemented
03717    return 1 if yes 0 if no */
03718 static int TLSX_HaveQSHScheme(word16 name)
03719 {
03720     switch(name) {
03721         #ifdef HAVE_NTRU
03722             case WOLFSSL_NTRU_EESS439:
03723             case WOLFSSL_NTRU_EESS593:
03724             case WOLFSSL_NTRU_EESS743:
03725                     return 1;
03726         #endif
03727             case WOLFSSL_LWE_XXX:
03728             case WOLFSSL_HFE_XXX:
03729                     return 0; /* not supported yet */
03730 
03731         default:
03732             return 0;
03733     }
03734 }
03735 
03736 
03737 /* Add a QSHScheme struct to list of usable ones */
03738 int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz)
03739 {
03740     TLSX*      extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID);
03741     QSHScheme* format    = NULL;
03742     int        ret       = 0;
03743 
03744     /* sanity check */
03745     if (extensions == NULL || (pKey == NULL && pkeySz != 0))
03746         return BAD_FUNC_ARG;
03747 
03748     /* if scheme is implemented than add */
03749     if (TLSX_HaveQSHScheme(name)) {
03750         if ((ret = TLSX_QSH_Append(&format, name, pKey, pkeySz)) != 0)
03751             return ret;
03752 
03753         if (!extension) {
03754             if ((ret = TLSX_Push(extensions, TLSX_QUANTUM_SAFE_HYBRID, format))
03755                                                                          != 0) {
03756                 XFREE(format, 0, DYNAMIC_TYPE_TLSX);
03757                 return ret;
03758             }
03759         }
03760         else {
03761             /* push new QSH object to extension data. */
03762             format->next = (QSHScheme*)extension->data;
03763             extension->data = (void*)format;
03764 
03765             /* look for another format of the same name to remove (replacement) */
03766             do {
03767                 if (format->next && (format->next->name == name)) {
03768                     QSHScheme* next = format->next;
03769 
03770                     format->next = next->next;
03771                     XFREE(next, 0, DYNAMIC_TYPE_TLSX);
03772 
03773                     break;
03774                 }
03775             } while ((format = format->next));
03776         }
03777     }
03778     return SSL_SUCCESS;
03779 }
03780 
03781 #define QSH_FREE_ALL         TLSX_QSH_FreeAll
03782 #define QSH_VALIDATE_REQUEST TLSX_QSH_ValidateRequest
03783 
03784 #ifndef NO_WOLFSSL_CLIENT
03785 #define QSH_GET_SIZE TLSX_QSH_GetSize
03786 #define QSH_WRITE    TLSX_QSH_Write
03787 #else
03788 #define QSH_GET_SIZE(list)         0
03789 #define QSH_WRITE(a, b)            0
03790 #endif
03791 
03792 #ifndef NO_WOLFSSL_SERVER
03793 #define QSH_PARSE TLSX_QSH_Parse
03794 #else
03795 #define QSH_PARSE(a, b, c, d)      0
03796 #endif
03797 
03798 #define QSHPK_WRITE TLSX_QSHPK_Write
03799 #define QSH_SERREQ TLSX_QSH_SerPKReq
03800 #else
03801 
03802 #define QSH_FREE_ALL(list)
03803 #define QSH_GET_SIZE(list, a)      0
03804 #define QSH_WRITE(a, b)            0
03805 #define QSH_PARSE(a, b, c, d)      0
03806 #define QSHPK_WRITE(a, b)          0
03807 #define QSH_SERREQ(a, b)           0
03808 #define QSH_VALIDATE_REQUEST(a, b)
03809 
03810 #endif /* HAVE_QSH */
03811 
03812 /******************************************************************************/
03813 /* TLS Extensions Framework                                                   */
03814 /******************************************************************************/
03815 
03816 /** Finds an extension in the provided list. */
03817 TLSX* TLSX_Find(TLSX* list, TLSX_Type type)
03818 {
03819     TLSX* extension = list;
03820 
03821     while (extension && extension->type != type)
03822         extension = extension->next;
03823 
03824     return extension;
03825 }
03826 
03827 /** Releases all extensions in the provided list. */
03828 void TLSX_FreeAll(TLSX* list)
03829 {
03830     TLSX* extension;
03831 
03832     while ((extension = list)) {
03833         list = extension->next;
03834 
03835         switch (extension->type) {
03836 
03837             case TLSX_SERVER_NAME:
03838                 SNI_FREE_ALL((SNI*)extension->data);
03839                 break;
03840 
03841             case TLSX_MAX_FRAGMENT_LENGTH:
03842                 MFL_FREE_ALL(extension->data);
03843                 break;
03844 
03845             case TLSX_TRUNCATED_HMAC:
03846                 /* Nothing to do. */
03847                 break;
03848 
03849             case TLSX_SUPPORTED_GROUPS:
03850                 EC_FREE_ALL(extension->data);
03851                 break;
03852 
03853             case TLSX_STATUS_REQUEST:
03854                 CSR_FREE_ALL(extension->data);
03855                 break;
03856 
03857             case TLSX_STATUS_REQUEST_V2:
03858                 CSR2_FREE_ALL(extension->data);
03859                 break;
03860 
03861             case TLSX_RENEGOTIATION_INFO:
03862                 SCR_FREE_ALL(extension->data);
03863                 break;
03864 
03865             case TLSX_SESSION_TICKET:
03866                 /* Nothing to do. */
03867                 break;
03868 
03869             case TLSX_QUANTUM_SAFE_HYBRID:
03870                 QSH_FREE_ALL((QSHScheme*)extension->data);
03871                 break;
03872 
03873             case TLSX_APPLICATION_LAYER_PROTOCOL:
03874                 ALPN_FREE_ALL((ALPN*)extension->data);
03875                 break;
03876         }
03877 
03878         XFREE(extension, 0, DYNAMIC_TYPE_TLSX);
03879     }
03880 }
03881 
03882 /** Checks if the tls extensions are supported based on the protocol version. */
03883 int TLSX_SupportExtensions(WOLFSSL* ssl) {
03884     return ssl && (IsTLS(ssl) || ssl->version.major == DTLS_MAJOR);
03885 }
03886 
03887 /** Tells the buffered size of the extensions in a list. */
03888 static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest)
03889 {
03890     TLSX* extension;
03891     word16 length = 0;
03892 
03893     while ((extension = list)) {
03894         list = extension->next;
03895 
03896         /* only extensions marked as response are sent back to the client. */
03897         if (!isRequest && !extension->resp)
03898             continue; /* skip! */
03899 
03900         /* ssl level extensions are expected to override ctx level ones. */
03901         if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type)))
03902             continue; /* skip! */
03903 
03904         /* extension type + extension data length. */
03905         length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
03906 
03907 
03908         switch (extension->type) {
03909 
03910             case TLSX_SERVER_NAME:
03911                 /* SNI only sends the name on the request. */
03912                 if (isRequest)
03913                     length += SNI_GET_SIZE(extension->data);
03914                 break;
03915 
03916             case TLSX_MAX_FRAGMENT_LENGTH:
03917                 length += MFL_GET_SIZE(extension->data);
03918                 break;
03919 
03920             case TLSX_TRUNCATED_HMAC:
03921                 /* always empty. */
03922                 break;
03923 
03924             case TLSX_SUPPORTED_GROUPS:
03925                 length += EC_GET_SIZE(extension->data);
03926                 break;
03927 
03928             case TLSX_STATUS_REQUEST:
03929                 length += CSR_GET_SIZE(extension->data, isRequest);
03930                 break;
03931 
03932             case TLSX_STATUS_REQUEST_V2:
03933                 length += CSR2_GET_SIZE(extension->data, isRequest);
03934                 break;
03935 
03936             case TLSX_RENEGOTIATION_INFO:
03937                 length += SCR_GET_SIZE(extension->data, isRequest);
03938                 break;
03939 
03940             case TLSX_SESSION_TICKET:
03941                 length += STK_GET_SIZE(extension->data, isRequest);
03942                 break;
03943 
03944             case TLSX_QUANTUM_SAFE_HYBRID:
03945                 length += QSH_GET_SIZE((QSHScheme*)extension->data, isRequest);
03946                 break;
03947 
03948             case TLSX_APPLICATION_LAYER_PROTOCOL:
03949                 length += ALPN_GET_SIZE(extension->data);
03950                 break;
03951 
03952         }
03953 
03954         /* marks the extension as processed so ctx level */
03955         /* extensions don't overlap with ssl level ones. */
03956         TURN_ON(semaphore, TLSX_ToSemaphore(extension->type));
03957     }
03958 
03959     return length;
03960 }
03961 
03962 /** Writes the extensions of a list in a buffer. */
03963 static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
03964                                                                  byte isRequest)
03965 {
03966     TLSX* extension;
03967     word16 offset = 0;
03968     word16 length_offset = 0;
03969 
03970     while ((extension = list)) {
03971         list = extension->next;
03972 
03973         /* only extensions marked as response are written in a response. */
03974         if (!isRequest && !extension->resp)
03975             continue; /* skip! */
03976 
03977         /* ssl level extensions are expected to override ctx level ones. */
03978         if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type)))
03979             continue; /* skip! */
03980 
03981         /* writes extension type. */
03982         c16toa(extension->type, output + offset);
03983         offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
03984         length_offset = offset;
03985 
03986         /* extension data should be written internally. */
03987         switch (extension->type) {
03988             case TLSX_SERVER_NAME:
03989                 if (isRequest)
03990                     offset += SNI_WRITE(extension->data, output + offset);
03991                 break;
03992 
03993             case TLSX_MAX_FRAGMENT_LENGTH:
03994                 offset += MFL_WRITE(extension->data, output + offset);
03995                 break;
03996 
03997             case TLSX_TRUNCATED_HMAC:
03998                 /* always empty. */
03999                 break;
04000 
04001             case TLSX_SUPPORTED_GROUPS:
04002                 offset += EC_WRITE(extension->data, output + offset);
04003                 break;
04004 
04005             case TLSX_STATUS_REQUEST:
04006                 offset += CSR_WRITE(extension->data, output + offset,
04007                                                                      isRequest);
04008                 break;
04009 
04010             case TLSX_STATUS_REQUEST_V2:
04011                 offset += CSR2_WRITE(extension->data, output + offset,
04012                                                                      isRequest);
04013                 break;
04014 
04015             case TLSX_RENEGOTIATION_INFO:
04016                 offset += SCR_WRITE(extension->data, output + offset,
04017                                                                      isRequest);
04018                 break;
04019 
04020             case TLSX_SESSION_TICKET:
04021                 offset += STK_WRITE(extension->data, output + offset,
04022                                                                      isRequest);
04023                 break;
04024 
04025             case TLSX_QUANTUM_SAFE_HYBRID:
04026                 if (isRequest) {
04027                     offset += QSH_WRITE((QSHScheme*)extension->data, output + offset);
04028                 }
04029                 offset += QSHPK_WRITE((QSHScheme*)extension->data, output + offset);
04030                 offset += QSH_SERREQ(output + offset, isRequest);
04031                 break;
04032 
04033             case TLSX_APPLICATION_LAYER_PROTOCOL:
04034                 offset += ALPN_WRITE(extension->data, output + offset);
04035                 break;
04036         }
04037 
04038         /* writes extension data length. */
04039         c16toa(offset - length_offset, output + length_offset - OPAQUE16_LEN);
04040 
04041         /* marks the extension as processed so ctx level */
04042         /* extensions don't overlap with ssl level ones. */
04043         TURN_ON(semaphore, TLSX_ToSemaphore(extension->type));
04044     }
04045 
04046     return offset;
04047 }
04048 
04049 
04050 #ifdef HAVE_NTRU
04051 
04052 static word32 GetEntropy(unsigned char* out, word32 num_bytes)
04053 {
04054     int ret = 0;
04055 
04056     if (rng == NULL) {
04057         if ((rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL,
04058                                                     DYNAMIC_TYPE_TLSX)) == NULL)
04059             return DRBG_OUT_OF_MEMORY;
04060         wc_InitRng(rng);
04061     }
04062 
04063     if (rngMutex == NULL) {
04064         if ((rngMutex = (wolfSSL_Mutex*)XMALLOC(sizeof(wolfSSL_Mutex), NULL,
04065                                                     DYNAMIC_TYPE_TLSX)) == NULL)
04066             return DRBG_OUT_OF_MEMORY;
04067         InitMutex(rngMutex);
04068     }
04069 
04070     ret |= LockMutex(rngMutex);
04071     ret |= wc_RNG_GenerateBlock(rng, out, num_bytes);
04072     ret |= UnLockMutex(rngMutex);
04073 
04074     if (ret != 0)
04075         return DRBG_ENTROPY_FAIL;
04076 
04077     return DRBG_OK;
04078 }
04079 #endif
04080 
04081 
04082 #ifdef HAVE_QSH
04083 static int TLSX_CreateQSHKey(WOLFSSL* ssl, int type)
04084 {
04085     int ret;
04086 
04087     switch (type) {
04088 #ifdef HAVE_NTRU
04089         case WOLFSSL_NTRU_EESS439:
04090         case WOLFSSL_NTRU_EESS593:
04091         case WOLFSSL_NTRU_EESS743:
04092             ret = TLSX_CreateNtruKey(ssl, type);
04093             break;
04094 #endif
04095         default:
04096             WOLFSSL_MSG("Unknown type for creating NTRU key");
04097             return -1;
04098     }
04099 
04100     return ret;
04101 }
04102 
04103 
04104 static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key)
04105 {
04106     QSHKey* current;
04107 
04108     if (key == NULL)
04109         return BAD_FUNC_ARG;
04110 
04111     /* if no public key stored in key then do not add */
04112     if (key->pub.length == 0 || key->pub.buffer == NULL)
04113         return 0;
04114 
04115     /* first element to be added to the list */
04116     current = *list;
04117     if (current == NULL) {
04118         *list = key;
04119         return 0;
04120     }
04121 
04122     while (current->next) {
04123         /* can only have one of the key in the list */
04124         if (current->name == key->name)
04125             return -1;
04126         current = (QSHKey*)current->next;
04127     }
04128 
04129     current->next = (struct QSHKey*)key;
04130 
04131     return 0;
04132 }
04133 
04134 
04135 #ifdef HAVE_NTRU
04136 int TLSX_CreateNtruKey(WOLFSSL* ssl, int type)
04137 {
04138     int ret;
04139     int ntruType;
04140 
04141     /* variable declarations for NTRU*/
04142     QSHKey* temp = NULL;
04143     byte   public_key[1027];
04144     word16 public_key_len = sizeof(public_key);
04145     byte   private_key[1120];
04146     word16 private_key_len = sizeof(private_key);
04147     DRBG_HANDLE drbg;
04148 
04149     if (ssl == NULL)
04150         return BAD_FUNC_ARG;
04151 
04152     switch (type) {
04153         case WOLFSSL_NTRU_EESS439:
04154             ntruType = NTRU_EES439EP1;
04155             break;
04156         case WOLFSSL_NTRU_EESS593:
04157             ntruType = NTRU_EES593EP1;
04158             break;
04159         case WOLFSSL_NTRU_EESS743:
04160             ntruType = NTRU_EES743EP1;
04161             break;
04162         default:
04163             WOLFSSL_MSG("Unknown type for creating NTRU key");
04164             return -1;
04165     }
04166     ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
04167     if (ret != DRBG_OK) {
04168         WOLFSSL_MSG("NTRU drbg instantiate failed\n");
04169         return ret;
04170     }
04171 
04172     if ((ret = ntru_crypto_ntru_encrypt_keygen(drbg, ntruType,
04173                      &public_key_len, NULL, &private_key_len, NULL)) != NTRU_OK)
04174         return ret;
04175 
04176     if ((ret = ntru_crypto_ntru_encrypt_keygen(drbg, ntruType,
04177         &public_key_len, public_key, &private_key_len, private_key)) != NTRU_OK)
04178         return ret;
04179 
04180     ret = ntru_crypto_drbg_uninstantiate(drbg);
04181     if (ret != NTRU_OK) {
04182         WOLFSSL_MSG("NTRU drbg uninstantiate failed\n");
04183         return ret;
04184     }
04185 
04186     if ((temp = (QSHKey*)XMALLOC(sizeof(QSHKey), NULL,
04187                                                     DYNAMIC_TYPE_TLSX)) == NULL)
04188         return MEMORY_E;
04189     temp->name = type;
04190     temp->pub.length = public_key_len;
04191     temp->pub.buffer = (byte*)XMALLOC(public_key_len, public_key,
04192                                 DYNAMIC_TYPE_PUBLIC_KEY);
04193     XMEMCPY(temp->pub.buffer, public_key, public_key_len);
04194     temp->pri.length = private_key_len;
04195     temp->pri.buffer = (byte*)XMALLOC(private_key_len, private_key,
04196                                 DYNAMIC_TYPE_ARRAYS);
04197     XMEMCPY(temp->pri.buffer, private_key, private_key_len);
04198     temp->next = NULL;
04199 
04200     TLSX_AddQSHKey(&ssl->QSH_Key, temp);
04201 
04202     return ret;
04203 }
04204 #endif
04205 
04206 
04207 /*
04208     Used to find a public key from the list of keys
04209     pubLen length of array
04210     name   input the name of the scheme looking for ie WOLFSSL_NTRU_ESSXXX
04211 
04212     returns a pointer to public key byte* or NULL if not found
04213  */
04214 static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name)
04215 {
04216     QSHKey* current = qsh;
04217 
04218     if (qsh == NULL || pubLen == NULL)
04219         return NULL;
04220 
04221     *pubLen = 0;
04222 
04223     while(current) {
04224         if (current->name == name) {
04225             *pubLen = current->pub.length;
04226             return current->pub.buffer;
04227         }
04228         current = (QSHKey*)current->next;
04229     }
04230 
04231     return NULL;
04232 }
04233 #endif /* HAVE_QSH */
04234 
04235 
04236 int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
04237 {
04238     byte* public_key      = NULL;
04239     word16 public_key_len = 0;
04240     #ifdef HAVE_QSH
04241         TLSX* extension;
04242         QSHScheme* qsh;
04243         QSHScheme* next;
04244     #endif
04245     int ret = 0;
04246 
04247     #ifdef HAVE_QSH
04248         /* add supported QSHSchemes */
04249         WOLFSSL_MSG("Adding supported QSH Schemes");
04250 
04251         /* server will add extension depending on whats parsed from client */
04252         if (!isServer) {
04253 
04254             /* test if user has set a specific scheme already */
04255             if (!ssl->user_set_QSHSchemes) {
04256                 if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) {
04257                     if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS743)) != 0) {
04258                         WOLFSSL_MSG("Error creating ntru keys");
04259                         return ret;
04260                     }
04261                     if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS593)) != 0) {
04262                         WOLFSSL_MSG("Error creating ntru keys");
04263                         return ret;
04264                     }
04265                     if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS439)) != 0) {
04266                         WOLFSSL_MSG("Error creating ntru keys");
04267                         return ret;
04268                     }
04269 
04270                 /* add NTRU 256 */
04271                 public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
04272                         &public_key_len, WOLFSSL_NTRU_EESS743);
04273                 }
04274                 if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS743,
04275                         public_key, public_key_len) != SSL_SUCCESS)
04276                     ret = -1;
04277 
04278                 /* add NTRU 196 */
04279                 if (ssl->sendQSHKeys) {
04280                     public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
04281                         &public_key_len, WOLFSSL_NTRU_EESS593);
04282                 }
04283                 if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS593,
04284                         public_key, public_key_len) != SSL_SUCCESS)
04285                     ret = -1;
04286 
04287                 /* add NTRU 128 */
04288                 if (ssl->sendQSHKeys) {
04289                     public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
04290                         &public_key_len, WOLFSSL_NTRU_EESS439);
04291                 }
04292                 if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS439,
04293                         public_key, public_key_len) != SSL_SUCCESS)
04294                     ret = -1;
04295             }
04296             else if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) {
04297                 /* for each scheme make a client key */
04298                 extension = TLSX_Find(ssl->extensions, TLSX_QUANTUM_SAFE_HYBRID);
04299                 if (extension) {
04300                     qsh = (QSHScheme*)extension->data;
04301 
04302                     while (qsh) {
04303                         if ((ret = TLSX_CreateQSHKey(ssl, qsh->name)) != 0)
04304                             return ret;
04305 
04306                         /* get next now because qsh could be freed */
04307                         next = qsh->next;
04308 
04309                         /* find the public key created and add to extension*/
04310                         public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
04311                                  &public_key_len, qsh->name);
04312                         if (TLSX_UseQSHScheme(&ssl->extensions, qsh->name,
04313                                     public_key, public_key_len) != SSL_SUCCESS)
04314                             ret = -1;
04315                         qsh = next;
04316                     }
04317                 }
04318             }
04319          } /* is not server */
04320     #endif
04321 
04322     (void)isServer;
04323     (void)public_key;
04324     (void)public_key_len;
04325     (void)ssl;
04326 
04327     return ret;
04328 }
04329 
04330 
04331 #ifndef NO_WOLFSSL_CLIENT
04332 
04333 /** Tells the buffered size of extensions to be sent into the client hello. */
04334 word16 TLSX_GetRequestSize(WOLFSSL* ssl)
04335 {
04336     word16 length = 0;
04337 
04338     if (TLSX_SupportExtensions(ssl)) {
04339         byte semaphore[SEMAPHORE_SIZE] = {0};
04340 
04341         EC_VALIDATE_REQUEST(ssl, semaphore);
04342         QSH_VALIDATE_REQUEST(ssl, semaphore);
04343         STK_VALIDATE_REQUEST(ssl);
04344 
04345         if (ssl->extensions)
04346             length += TLSX_GetSize(ssl->extensions, semaphore, 1);
04347 
04348         if (ssl->ctx && ssl->ctx->extensions)
04349             length += TLSX_GetSize(ssl->ctx->extensions, semaphore, 1);
04350 
04351         if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
04352             length += ssl->suites->hashSigAlgoSz + HELLO_EXT_LEN;
04353     }
04354 
04355     if (length)
04356         length += OPAQUE16_LEN; /* for total length storage. */
04357 
04358     return length;
04359 }
04360 
04361 /** Writes the extensions to be sent into the client hello. */
04362 word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output)
04363 {
04364     word16 offset = 0;
04365 
04366     if (TLSX_SupportExtensions(ssl) && output) {
04367         byte semaphore[SEMAPHORE_SIZE] = {0};
04368 
04369         offset += OPAQUE16_LEN; /* extensions length */
04370 
04371         EC_VALIDATE_REQUEST(ssl, semaphore);
04372         STK_VALIDATE_REQUEST(ssl);
04373         QSH_VALIDATE_REQUEST(ssl, semaphore);
04374 
04375         if (ssl->extensions)
04376             offset += TLSX_Write(ssl->extensions, output + offset,
04377                                                                   semaphore, 1);
04378 
04379         if (ssl->ctx && ssl->ctx->extensions)
04380             offset += TLSX_Write(ssl->ctx->extensions, output + offset,
04381                                                                   semaphore, 1);
04382 
04383         if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
04384         {
04385             int i;
04386             /* extension type */
04387             c16toa(HELLO_EXT_SIG_ALGO, output + offset);
04388             offset += HELLO_EXT_TYPE_SZ;
04389 
04390             /* extension data length */
04391             c16toa(OPAQUE16_LEN + ssl->suites->hashSigAlgoSz, output + offset);
04392             offset += OPAQUE16_LEN;
04393 
04394             /* sig algos length */
04395             c16toa(ssl->suites->hashSigAlgoSz, output + offset);
04396             offset += OPAQUE16_LEN;
04397 
04398             /* sig algos */
04399             for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, offset++)
04400                 output[offset] = ssl->suites->hashSigAlgo[i];
04401         }
04402 
04403         if (offset > OPAQUE16_LEN)
04404             c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
04405     }
04406 
04407     return offset;
04408 }
04409 
04410 #endif /* NO_WOLFSSL_CLIENT */
04411 
04412 #ifndef NO_WOLFSSL_SERVER
04413 
04414 /** Tells the buffered size of extensions to be sent into the server hello. */
04415 word16 TLSX_GetResponseSize(WOLFSSL* ssl)
04416 {
04417     word16 length = 0;
04418     byte semaphore[SEMAPHORE_SIZE] = {0};
04419 
04420     #ifdef HAVE_QSH
04421         /* change response if not using TLS_QSH */
04422         if (!ssl->options.haveQSH) {
04423             TLSX* ext = TLSX_Find(ssl->extensions, TLSX_QUANTUM_SAFE_HYBRID);
04424             if (ext)
04425                 ext->resp = 0;
04426         }
04427     #endif
04428 
04429     if (TLSX_SupportExtensions(ssl))
04430         length += TLSX_GetSize(ssl->extensions, semaphore, 0);
04431 
04432     /* All the response data is set at the ssl object only, so no ctx here. */
04433 
04434     if (length)
04435         length += OPAQUE16_LEN; /* for total length storage */
04436 
04437     return length;
04438 }
04439 
04440 /** Writes the server hello extensions into a buffer. */
04441 word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output)
04442 {
04443     word16 offset = 0;
04444 
04445     if (TLSX_SupportExtensions(ssl) && output) {
04446         byte semaphore[SEMAPHORE_SIZE] = {0};
04447 
04448         offset += OPAQUE16_LEN; /* extensions length */
04449 
04450         offset += TLSX_Write(ssl->extensions, output + offset, semaphore, 0);
04451 
04452         if (offset > OPAQUE16_LEN)
04453             c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
04454     }
04455 
04456     return offset;
04457 }
04458 
04459 #endif /* NO_WOLFSSL_SERVER */
04460 
04461 /** Parses a buffer of TLS extensions. */
04462 int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest,
04463                                                                  Suites *suites)
04464 {
04465     int ret = 0;
04466     word16 offset = 0;
04467 
04468     if (!ssl || !input || (isRequest && !suites))
04469         return BAD_FUNC_ARG;
04470 
04471     while (ret == 0 && offset < length) {
04472         word16 type;
04473         word16 size;
04474 
04475         if (length - offset < HELLO_EXT_TYPE_SZ + OPAQUE16_LEN)
04476             return BUFFER_ERROR;
04477 
04478         ato16(input + offset, &type);
04479         offset += HELLO_EXT_TYPE_SZ;
04480 
04481         ato16(input + offset, &size);
04482         offset += OPAQUE16_LEN;
04483 
04484         if (offset + size > length)
04485             return BUFFER_ERROR;
04486 
04487         switch (type) {
04488             case TLSX_SERVER_NAME:
04489                 WOLFSSL_MSG("SNI extension received");
04490 
04491                 ret = SNI_PARSE(ssl, input + offset, size, isRequest);
04492                 break;
04493 
04494             case TLSX_MAX_FRAGMENT_LENGTH:
04495                 WOLFSSL_MSG("Max Fragment Length extension received");
04496 
04497                 ret = MFL_PARSE(ssl, input + offset, size, isRequest);
04498                 break;
04499 
04500             case TLSX_TRUNCATED_HMAC:
04501                 WOLFSSL_MSG("Truncated HMAC extension received");
04502 
04503                 ret = THM_PARSE(ssl, input + offset, size, isRequest);
04504                 break;
04505 
04506             case TLSX_SUPPORTED_GROUPS:
04507                 WOLFSSL_MSG("Elliptic Curves extension received");
04508 
04509                 ret = EC_PARSE(ssl, input + offset, size, isRequest);
04510                 break;
04511 
04512             case TLSX_STATUS_REQUEST:
04513                 WOLFSSL_MSG("Certificate Status Request extension received");
04514 
04515                 ret = CSR_PARSE(ssl, input + offset, size, isRequest);
04516                 break;
04517 
04518             case TLSX_STATUS_REQUEST_V2:
04519                 WOLFSSL_MSG("Certificate Status Request v2 extension received");
04520 
04521                 ret = CSR2_PARSE(ssl, input + offset, size, isRequest);
04522                 break;
04523 
04524             case TLSX_RENEGOTIATION_INFO:
04525                 WOLFSSL_MSG("Secure Renegotiation extension received");
04526 
04527                 ret = SCR_PARSE(ssl, input + offset, size, isRequest);
04528                 break;
04529 
04530             case TLSX_SESSION_TICKET:
04531                 WOLFSSL_MSG("Session Ticket extension received");
04532 
04533                 ret = STK_PARSE(ssl, input + offset, size, isRequest);
04534                 break;
04535 
04536             case TLSX_QUANTUM_SAFE_HYBRID:
04537                 WOLFSSL_MSG("Quantum-Safe-Hybrid extension received");
04538 
04539                 ret = QSH_PARSE(ssl, input + offset, size, isRequest);
04540                 break;
04541 
04542             case TLSX_APPLICATION_LAYER_PROTOCOL:
04543                 WOLFSSL_MSG("ALPN extension received");
04544 
04545                 ret = ALPN_PARSE(ssl, input + offset, size, isRequest);
04546                 break;
04547 
04548             case HELLO_EXT_SIG_ALGO:
04549                 if (isRequest) {
04550                     /* do not mess with offset inside the switch! */
04551                     if (IsAtLeastTLSv1_2(ssl)) {
04552                         ato16(input + offset, &suites->hashSigAlgoSz);
04553 
04554                         if (suites->hashSigAlgoSz > size - OPAQUE16_LEN)
04555                             return BUFFER_ERROR;
04556 
04557                         XMEMCPY(suites->hashSigAlgo,
04558                                 input + offset + OPAQUE16_LEN,
04559                                 min(suites->hashSigAlgoSz,
04560                                                         HELLO_EXT_SIGALGO_MAX));
04561                     }
04562                 } else {
04563                     WOLFSSL_MSG("Servers MUST NOT send SIG ALGO extension.");
04564                 }
04565 
04566                 break;
04567         }
04568 
04569         /* offset should be updated here! */
04570         offset += size;
04571     }
04572 
04573     if (ret == 0)
04574         ret = SNI_VERIFY_PARSE(ssl, isRequest);
04575 
04576     return ret;
04577 }
04578 
04579 /* undefining semaphore macros */
04580 #undef IS_OFF
04581 #undef TURN_ON
04582 #undef SEMAPHORE_SIZE
04583 
04584 #endif /* HAVE_TLS_EXTENSIONS */
04585 
04586 #ifndef NO_WOLFSSL_CLIENT
04587 
04588 #ifndef NO_OLD_TLS
04589 
04590     WOLFSSL_METHOD* wolfTLSv1_client_method(void)
04591     {
04592         WOLFSSL_METHOD* method =
04593                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
04594                                                       DYNAMIC_TYPE_METHOD);
04595         if (method)
04596             InitSSL_Method(method, MakeTLSv1());
04597         return method;
04598     }
04599 
04600 
04601     WOLFSSL_METHOD* wolfTLSv1_1_client_method(void)
04602     {
04603         WOLFSSL_METHOD* method =
04604                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
04605                                                        DYNAMIC_TYPE_METHOD);
04606         if (method)
04607             InitSSL_Method(method, MakeTLSv1_1());
04608         return method;
04609     }
04610 
04611 #endif /* !NO_OLD_TLS */
04612 
04613 #ifndef NO_SHA256   /* can't use without SHA256 */
04614 
04615     WOLFSSL_METHOD* wolfTLSv1_2_client_method(void)
04616     {
04617         WOLFSSL_METHOD* method =
04618                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
04619                                                        DYNAMIC_TYPE_METHOD);
04620         if (method)
04621             InitSSL_Method(method, MakeTLSv1_2());
04622         return method;
04623     }
04624 
04625 #endif
04626 
04627 
04628     WOLFSSL_METHOD* wolfSSLv23_client_method(void)
04629     {
04630         WOLFSSL_METHOD* method =
04631                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
04632                                                        DYNAMIC_TYPE_METHOD);
04633         if (method) {
04634 #ifndef NO_SHA256         /* 1.2 requires SHA256 */
04635             InitSSL_Method(method, MakeTLSv1_2());
04636 #else
04637             InitSSL_Method(method, MakeTLSv1_1());
04638 #endif
04639 #ifndef NO_OLD_TLS
04640             method->downgrade = 1;
04641 #endif
04642         }
04643         return method;
04644     }
04645 
04646 
04647 #endif /* NO_WOLFSSL_CLIENT */
04648 
04649 
04650 
04651 #ifndef NO_WOLFSSL_SERVER
04652 
04653 #ifndef NO_OLD_TLS
04654 
04655     WOLFSSL_METHOD* wolfTLSv1_server_method(void)
04656     {
04657         WOLFSSL_METHOD* method =
04658                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
04659                                                        DYNAMIC_TYPE_METHOD);
04660         if (method) {
04661             InitSSL_Method(method, MakeTLSv1());
04662             method->side = WOLFSSL_SERVER_END;
04663         }
04664         return method;
04665     }
04666 
04667 
04668     WOLFSSL_METHOD* wolfTLSv1_1_server_method(void)
04669     {
04670         WOLFSSL_METHOD* method =
04671                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
04672                                                        DYNAMIC_TYPE_METHOD);
04673         if (method) {
04674             InitSSL_Method(method, MakeTLSv1_1());
04675             method->side = WOLFSSL_SERVER_END;
04676         }
04677         return method;
04678     }
04679 
04680 #endif /* !NO_OLD_TLS */
04681 
04682 #ifndef NO_SHA256   /* can't use without SHA256 */
04683 
04684     WOLFSSL_METHOD* wolfTLSv1_2_server_method(void)
04685     {
04686         WOLFSSL_METHOD* method =
04687                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
04688                                                        DYNAMIC_TYPE_METHOD);
04689         if (method) {
04690             InitSSL_Method(method, MakeTLSv1_2());
04691             method->side = WOLFSSL_SERVER_END;
04692         }
04693         return method;
04694     }
04695 
04696 #endif
04697 
04698 
04699     WOLFSSL_METHOD* wolfSSLv23_server_method(void)
04700     {
04701         WOLFSSL_METHOD* method =
04702                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
04703                                                        DYNAMIC_TYPE_METHOD);
04704         if (method) {
04705 #ifndef NO_SHA256         /* 1.2 requires SHA256 */
04706             InitSSL_Method(method, MakeTLSv1_2());
04707 #else
04708             InitSSL_Method(method, MakeTLSv1_1());
04709 #endif
04710             method->side      = WOLFSSL_SERVER_END;
04711 #ifndef NO_OLD_TLS
04712             method->downgrade = 1;
04713 #endif /* !NO_OLD_TLS */
04714         }
04715         return method;
04716     }
04717 
04718 
04719 
04720 #endif /* NO_WOLFSSL_SERVER */
04721 #endif /* NO_TLS */
04722 #endif /* WOLFCRYPT_ONLY */
04723