SSL/TLS Library

Dependents:  

CyaSSL is SSL/TLS library for embedded systems.

wolfssl.com

Committer:
wolfSSL
Date:
Sun Apr 20 12:40:57 2014 +0000
Revision:
0:9d17e4342598
CyaSSL SSL/TLS Library 2.9.4;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 0:9d17e4342598 1 /* tls.c
wolfSSL 0:9d17e4342598 2 *
wolfSSL 0:9d17e4342598 3 * Copyright (C) 2006-2013 wolfSSL Inc.
wolfSSL 0:9d17e4342598 4 *
wolfSSL 0:9d17e4342598 5 * This file is part of CyaSSL.
wolfSSL 0:9d17e4342598 6 *
wolfSSL 0:9d17e4342598 7 * CyaSSL is free software; you can redistribute it and/or modify
wolfSSL 0:9d17e4342598 8 * it under the terms of the GNU General Public License as published by
wolfSSL 0:9d17e4342598 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 0:9d17e4342598 10 * (at your option) any later version.
wolfSSL 0:9d17e4342598 11 *
wolfSSL 0:9d17e4342598 12 * CyaSSL is distributed in the hope that it will be useful,
wolfSSL 0:9d17e4342598 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 0:9d17e4342598 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 0:9d17e4342598 15 * GNU General Public License for more details.
wolfSSL 0:9d17e4342598 16 *
wolfSSL 0:9d17e4342598 17 * You should have received a copy of the GNU General Public License
wolfSSL 0:9d17e4342598 18 * along with this program; if not, write to the Free Software
wolfSSL 0:9d17e4342598 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
wolfSSL 0:9d17e4342598 20 */
wolfSSL 0:9d17e4342598 21
wolfSSL 0:9d17e4342598 22 #ifdef HAVE_CONFIG_H
wolfSSL 0:9d17e4342598 23 #include <config.h>
wolfSSL 0:9d17e4342598 24 #endif
wolfSSL 0:9d17e4342598 25
wolfSSL 0:9d17e4342598 26 #include <cyassl/ctaocrypt/settings.h>
wolfSSL 0:9d17e4342598 27
wolfSSL 0:9d17e4342598 28 #include <cyassl/ssl.h>
wolfSSL 0:9d17e4342598 29 #include <cyassl/internal.h>
wolfSSL 0:9d17e4342598 30 #include <cyassl/error-ssl.h>
wolfSSL 0:9d17e4342598 31 #include <cyassl/ctaocrypt/hmac.h>
wolfSSL 0:9d17e4342598 32
wolfSSL 0:9d17e4342598 33
wolfSSL 0:9d17e4342598 34
wolfSSL 0:9d17e4342598 35 #ifndef NO_TLS
wolfSSL 0:9d17e4342598 36
wolfSSL 0:9d17e4342598 37
wolfSSL 0:9d17e4342598 38 #ifndef min
wolfSSL 0:9d17e4342598 39
wolfSSL 0:9d17e4342598 40 static INLINE word32 min(word32 a, word32 b)
wolfSSL 0:9d17e4342598 41 {
wolfSSL 0:9d17e4342598 42 return a > b ? b : a;
wolfSSL 0:9d17e4342598 43 }
wolfSSL 0:9d17e4342598 44
wolfSSL 0:9d17e4342598 45 #endif /* min */
wolfSSL 0:9d17e4342598 46
wolfSSL 0:9d17e4342598 47
wolfSSL 0:9d17e4342598 48 #ifdef CYASSL_SHA384
wolfSSL 0:9d17e4342598 49 #define PHASH_MAX_DIGEST_SIZE SHA384_DIGEST_SIZE
wolfSSL 0:9d17e4342598 50 #else
wolfSSL 0:9d17e4342598 51 #define PHASH_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE
wolfSSL 0:9d17e4342598 52 #endif
wolfSSL 0:9d17e4342598 53
wolfSSL 0:9d17e4342598 54 /* compute p_hash for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1 PRF */
wolfSSL 0:9d17e4342598 55 static int p_hash(byte* result, word32 resLen, const byte* secret,
wolfSSL 0:9d17e4342598 56 word32 secLen, const byte* seed, word32 seedLen, int hash)
wolfSSL 0:9d17e4342598 57 {
wolfSSL 0:9d17e4342598 58 word32 len = PHASH_MAX_DIGEST_SIZE;
wolfSSL 0:9d17e4342598 59 word32 times;
wolfSSL 0:9d17e4342598 60 word32 lastLen;
wolfSSL 0:9d17e4342598 61 word32 lastTime;
wolfSSL 0:9d17e4342598 62 word32 i;
wolfSSL 0:9d17e4342598 63 word32 idx = 0;
wolfSSL 0:9d17e4342598 64 int ret;
wolfSSL 0:9d17e4342598 65 byte previous[PHASH_MAX_DIGEST_SIZE]; /* max size */
wolfSSL 0:9d17e4342598 66 byte current[PHASH_MAX_DIGEST_SIZE]; /* max size */
wolfSSL 0:9d17e4342598 67
wolfSSL 0:9d17e4342598 68 Hmac hmac;
wolfSSL 0:9d17e4342598 69
wolfSSL 0:9d17e4342598 70 switch (hash) {
wolfSSL 0:9d17e4342598 71 #ifndef NO_MD5
wolfSSL 0:9d17e4342598 72 case md5_mac:
wolfSSL 0:9d17e4342598 73 {
wolfSSL 0:9d17e4342598 74 len = MD5_DIGEST_SIZE;
wolfSSL 0:9d17e4342598 75 hash = MD5;
wolfSSL 0:9d17e4342598 76 }
wolfSSL 0:9d17e4342598 77 break;
wolfSSL 0:9d17e4342598 78 #endif
wolfSSL 0:9d17e4342598 79 #ifndef NO_SHA256
wolfSSL 0:9d17e4342598 80 case sha256_mac:
wolfSSL 0:9d17e4342598 81 {
wolfSSL 0:9d17e4342598 82 len = SHA256_DIGEST_SIZE;
wolfSSL 0:9d17e4342598 83 hash = SHA256;
wolfSSL 0:9d17e4342598 84 }
wolfSSL 0:9d17e4342598 85 break;
wolfSSL 0:9d17e4342598 86 #endif
wolfSSL 0:9d17e4342598 87 #ifdef CYASSL_SHA384
wolfSSL 0:9d17e4342598 88 case sha384_mac:
wolfSSL 0:9d17e4342598 89 {
wolfSSL 0:9d17e4342598 90 len = SHA384_DIGEST_SIZE;
wolfSSL 0:9d17e4342598 91 hash = SHA384;
wolfSSL 0:9d17e4342598 92 }
wolfSSL 0:9d17e4342598 93 break;
wolfSSL 0:9d17e4342598 94 #endif
wolfSSL 0:9d17e4342598 95 #ifndef NO_SHA
wolfSSL 0:9d17e4342598 96 case sha_mac:
wolfSSL 0:9d17e4342598 97 default:
wolfSSL 0:9d17e4342598 98 {
wolfSSL 0:9d17e4342598 99 len = SHA_DIGEST_SIZE;
wolfSSL 0:9d17e4342598 100 hash = SHA;
wolfSSL 0:9d17e4342598 101 }
wolfSSL 0:9d17e4342598 102 break;
wolfSSL 0:9d17e4342598 103 #endif
wolfSSL 0:9d17e4342598 104 }
wolfSSL 0:9d17e4342598 105
wolfSSL 0:9d17e4342598 106 times = resLen / len;
wolfSSL 0:9d17e4342598 107 lastLen = resLen % len;
wolfSSL 0:9d17e4342598 108 if (lastLen) times += 1;
wolfSSL 0:9d17e4342598 109 lastTime = times - 1;
wolfSSL 0:9d17e4342598 110
wolfSSL 0:9d17e4342598 111 ret = HmacSetKey(&hmac, hash, secret, secLen);
wolfSSL 0:9d17e4342598 112 if (ret != 0)
wolfSSL 0:9d17e4342598 113 return ret;
wolfSSL 0:9d17e4342598 114 HmacUpdate(&hmac, seed, seedLen); /* A0 = seed */
wolfSSL 0:9d17e4342598 115 HmacFinal(&hmac, previous); /* A1 */
wolfSSL 0:9d17e4342598 116
wolfSSL 0:9d17e4342598 117 for (i = 0; i < times; i++) {
wolfSSL 0:9d17e4342598 118 HmacUpdate(&hmac, previous, len);
wolfSSL 0:9d17e4342598 119 HmacUpdate(&hmac, seed, seedLen);
wolfSSL 0:9d17e4342598 120 HmacFinal(&hmac, current);
wolfSSL 0:9d17e4342598 121
wolfSSL 0:9d17e4342598 122 if ( (i == lastTime) && lastLen)
wolfSSL 0:9d17e4342598 123 XMEMCPY(&result[idx], current, min(lastLen, sizeof(current)));
wolfSSL 0:9d17e4342598 124 else {
wolfSSL 0:9d17e4342598 125 XMEMCPY(&result[idx], current, len);
wolfSSL 0:9d17e4342598 126 idx += len;
wolfSSL 0:9d17e4342598 127 HmacUpdate(&hmac, previous, len);
wolfSSL 0:9d17e4342598 128 HmacFinal(&hmac, previous);
wolfSSL 0:9d17e4342598 129 }
wolfSSL 0:9d17e4342598 130 }
wolfSSL 0:9d17e4342598 131 XMEMSET(previous, 0, sizeof previous);
wolfSSL 0:9d17e4342598 132 XMEMSET(current, 0, sizeof current);
wolfSSL 0:9d17e4342598 133 XMEMSET(&hmac, 0, sizeof hmac);
wolfSSL 0:9d17e4342598 134
wolfSSL 0:9d17e4342598 135 return 0;
wolfSSL 0:9d17e4342598 136 }
wolfSSL 0:9d17e4342598 137
wolfSSL 0:9d17e4342598 138
wolfSSL 0:9d17e4342598 139
wolfSSL 0:9d17e4342598 140 #ifndef NO_OLD_TLS
wolfSSL 0:9d17e4342598 141
wolfSSL 0:9d17e4342598 142 /* calculate XOR for TLSv1 PRF */
wolfSSL 0:9d17e4342598 143 static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha)
wolfSSL 0:9d17e4342598 144 {
wolfSSL 0:9d17e4342598 145 word32 i;
wolfSSL 0:9d17e4342598 146
wolfSSL 0:9d17e4342598 147 for (i = 0; i < digLen; i++)
wolfSSL 0:9d17e4342598 148 digest[i] = md5[i] ^ sha[i];
wolfSSL 0:9d17e4342598 149 }
wolfSSL 0:9d17e4342598 150
wolfSSL 0:9d17e4342598 151
wolfSSL 0:9d17e4342598 152 /* compute TLSv1 PRF (pseudo random function using HMAC) */
wolfSSL 0:9d17e4342598 153 static int doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen,
wolfSSL 0:9d17e4342598 154 const byte* label, word32 labLen, const byte* seed,
wolfSSL 0:9d17e4342598 155 word32 seedLen)
wolfSSL 0:9d17e4342598 156 {
wolfSSL 0:9d17e4342598 157 int ret;
wolfSSL 0:9d17e4342598 158 word32 half = (secLen + 1) / 2;
wolfSSL 0:9d17e4342598 159
wolfSSL 0:9d17e4342598 160 byte md5_half[MAX_PRF_HALF]; /* half is real size */
wolfSSL 0:9d17e4342598 161 byte sha_half[MAX_PRF_HALF]; /* half is real size */
wolfSSL 0:9d17e4342598 162 byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */
wolfSSL 0:9d17e4342598 163 byte md5_result[MAX_PRF_DIG]; /* digLen is real size */
wolfSSL 0:9d17e4342598 164 byte sha_result[MAX_PRF_DIG]; /* digLen is real size */
wolfSSL 0:9d17e4342598 165
wolfSSL 0:9d17e4342598 166 if (half > MAX_PRF_HALF)
wolfSSL 0:9d17e4342598 167 return BUFFER_E;
wolfSSL 0:9d17e4342598 168 if (labLen + seedLen > MAX_PRF_LABSEED)
wolfSSL 0:9d17e4342598 169 return BUFFER_E;
wolfSSL 0:9d17e4342598 170 if (digLen > MAX_PRF_DIG)
wolfSSL 0:9d17e4342598 171 return BUFFER_E;
wolfSSL 0:9d17e4342598 172
wolfSSL 0:9d17e4342598 173 XMEMSET(md5_result, 0, digLen);
wolfSSL 0:9d17e4342598 174 XMEMSET(sha_result, 0, digLen);
wolfSSL 0:9d17e4342598 175
wolfSSL 0:9d17e4342598 176 XMEMCPY(md5_half, secret, half);
wolfSSL 0:9d17e4342598 177 XMEMCPY(sha_half, secret + half - secLen % 2, half);
wolfSSL 0:9d17e4342598 178
wolfSSL 0:9d17e4342598 179 XMEMCPY(labelSeed, label, labLen);
wolfSSL 0:9d17e4342598 180 XMEMCPY(labelSeed + labLen, seed, seedLen);
wolfSSL 0:9d17e4342598 181
wolfSSL 0:9d17e4342598 182 ret = p_hash(md5_result, digLen, md5_half, half, labelSeed,
wolfSSL 0:9d17e4342598 183 labLen + seedLen, md5_mac);
wolfSSL 0:9d17e4342598 184 if (ret != 0)
wolfSSL 0:9d17e4342598 185 return ret;
wolfSSL 0:9d17e4342598 186 ret = p_hash(sha_result, digLen, sha_half, half, labelSeed,
wolfSSL 0:9d17e4342598 187 labLen + seedLen, sha_mac);
wolfSSL 0:9d17e4342598 188 if (ret != 0)
wolfSSL 0:9d17e4342598 189 return ret;
wolfSSL 0:9d17e4342598 190 get_xor(digest, digLen, md5_result, sha_result);
wolfSSL 0:9d17e4342598 191
wolfSSL 0:9d17e4342598 192 return 0;
wolfSSL 0:9d17e4342598 193 }
wolfSSL 0:9d17e4342598 194
wolfSSL 0:9d17e4342598 195 #endif
wolfSSL 0:9d17e4342598 196
wolfSSL 0:9d17e4342598 197
wolfSSL 0:9d17e4342598 198 /* Wrapper to call straight thru to p_hash in TSL 1.2 cases to remove stack
wolfSSL 0:9d17e4342598 199 use */
wolfSSL 0:9d17e4342598 200 static int PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen,
wolfSSL 0:9d17e4342598 201 const byte* label, word32 labLen, const byte* seed, word32 seedLen,
wolfSSL 0:9d17e4342598 202 int useAtLeastSha256, int hash_type)
wolfSSL 0:9d17e4342598 203 {
wolfSSL 0:9d17e4342598 204 int ret = 0;
wolfSSL 0:9d17e4342598 205
wolfSSL 0:9d17e4342598 206 if (useAtLeastSha256) {
wolfSSL 0:9d17e4342598 207 byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */
wolfSSL 0:9d17e4342598 208
wolfSSL 0:9d17e4342598 209 if (labLen + seedLen > MAX_PRF_LABSEED)
wolfSSL 0:9d17e4342598 210 return BUFFER_E;
wolfSSL 0:9d17e4342598 211
wolfSSL 0:9d17e4342598 212 XMEMCPY(labelSeed, label, labLen);
wolfSSL 0:9d17e4342598 213 XMEMCPY(labelSeed + labLen, seed, seedLen);
wolfSSL 0:9d17e4342598 214
wolfSSL 0:9d17e4342598 215 /* If a cipher suite wants an algorithm better than sha256, it
wolfSSL 0:9d17e4342598 216 * should use better. */
wolfSSL 0:9d17e4342598 217 if (hash_type < sha256_mac)
wolfSSL 0:9d17e4342598 218 hash_type = sha256_mac;
wolfSSL 0:9d17e4342598 219 ret = p_hash(digest, digLen, secret, secLen, labelSeed,
wolfSSL 0:9d17e4342598 220 labLen + seedLen, hash_type);
wolfSSL 0:9d17e4342598 221 }
wolfSSL 0:9d17e4342598 222 #ifndef NO_OLD_TLS
wolfSSL 0:9d17e4342598 223 else {
wolfSSL 0:9d17e4342598 224 ret = doPRF(digest, digLen, secret, secLen, label, labLen, seed,
wolfSSL 0:9d17e4342598 225 seedLen);
wolfSSL 0:9d17e4342598 226 }
wolfSSL 0:9d17e4342598 227 #endif
wolfSSL 0:9d17e4342598 228
wolfSSL 0:9d17e4342598 229 return ret;
wolfSSL 0:9d17e4342598 230 }
wolfSSL 0:9d17e4342598 231
wolfSSL 0:9d17e4342598 232
wolfSSL 0:9d17e4342598 233 #ifdef CYASSL_SHA384
wolfSSL 0:9d17e4342598 234 #define HSHASH_SZ SHA384_DIGEST_SIZE
wolfSSL 0:9d17e4342598 235 #else
wolfSSL 0:9d17e4342598 236 #define HSHASH_SZ FINISHED_SZ
wolfSSL 0:9d17e4342598 237 #endif
wolfSSL 0:9d17e4342598 238
wolfSSL 0:9d17e4342598 239
wolfSSL 0:9d17e4342598 240 int BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
wolfSSL 0:9d17e4342598 241 {
wolfSSL 0:9d17e4342598 242 const byte* side;
wolfSSL 0:9d17e4342598 243 byte handshake_hash[HSHASH_SZ];
wolfSSL 0:9d17e4342598 244 word32 hashSz = FINISHED_SZ;
wolfSSL 0:9d17e4342598 245
wolfSSL 0:9d17e4342598 246 #ifndef NO_OLD_TLS
wolfSSL 0:9d17e4342598 247 Md5Final(&ssl->hashMd5, handshake_hash);
wolfSSL 0:9d17e4342598 248 ShaFinal(&ssl->hashSha, &handshake_hash[MD5_DIGEST_SIZE]);
wolfSSL 0:9d17e4342598 249 #endif
wolfSSL 0:9d17e4342598 250
wolfSSL 0:9d17e4342598 251 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:9d17e4342598 252 #ifndef NO_SHA256
wolfSSL 0:9d17e4342598 253 if (ssl->specs.mac_algorithm <= sha256_mac) {
wolfSSL 0:9d17e4342598 254 Sha256Final(&ssl->hashSha256, handshake_hash);
wolfSSL 0:9d17e4342598 255 hashSz = SHA256_DIGEST_SIZE;
wolfSSL 0:9d17e4342598 256 }
wolfSSL 0:9d17e4342598 257 #endif
wolfSSL 0:9d17e4342598 258 #ifdef CYASSL_SHA384
wolfSSL 0:9d17e4342598 259 if (ssl->specs.mac_algorithm == sha384_mac) {
wolfSSL 0:9d17e4342598 260 Sha384Final(&ssl->hashSha384, handshake_hash);
wolfSSL 0:9d17e4342598 261 hashSz = SHA384_DIGEST_SIZE;
wolfSSL 0:9d17e4342598 262 }
wolfSSL 0:9d17e4342598 263 #endif
wolfSSL 0:9d17e4342598 264 }
wolfSSL 0:9d17e4342598 265
wolfSSL 0:9d17e4342598 266 if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0)
wolfSSL 0:9d17e4342598 267 side = tls_client;
wolfSSL 0:9d17e4342598 268 else
wolfSSL 0:9d17e4342598 269 side = tls_server;
wolfSSL 0:9d17e4342598 270
wolfSSL 0:9d17e4342598 271 return PRF((byte*)hashes, TLS_FINISHED_SZ, ssl->arrays->masterSecret,
wolfSSL 0:9d17e4342598 272 SECRET_LEN, side, FINISHED_LABEL_SZ, handshake_hash, hashSz,
wolfSSL 0:9d17e4342598 273 IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
wolfSSL 0:9d17e4342598 274 }
wolfSSL 0:9d17e4342598 275
wolfSSL 0:9d17e4342598 276
wolfSSL 0:9d17e4342598 277 #ifndef NO_OLD_TLS
wolfSSL 0:9d17e4342598 278
wolfSSL 0:9d17e4342598 279 ProtocolVersion MakeTLSv1(void)
wolfSSL 0:9d17e4342598 280 {
wolfSSL 0:9d17e4342598 281 ProtocolVersion pv;
wolfSSL 0:9d17e4342598 282 pv.major = SSLv3_MAJOR;
wolfSSL 0:9d17e4342598 283 pv.minor = TLSv1_MINOR;
wolfSSL 0:9d17e4342598 284
wolfSSL 0:9d17e4342598 285 return pv;
wolfSSL 0:9d17e4342598 286 }
wolfSSL 0:9d17e4342598 287
wolfSSL 0:9d17e4342598 288
wolfSSL 0:9d17e4342598 289 ProtocolVersion MakeTLSv1_1(void)
wolfSSL 0:9d17e4342598 290 {
wolfSSL 0:9d17e4342598 291 ProtocolVersion pv;
wolfSSL 0:9d17e4342598 292 pv.major = SSLv3_MAJOR;
wolfSSL 0:9d17e4342598 293 pv.minor = TLSv1_1_MINOR;
wolfSSL 0:9d17e4342598 294
wolfSSL 0:9d17e4342598 295 return pv;
wolfSSL 0:9d17e4342598 296 }
wolfSSL 0:9d17e4342598 297
wolfSSL 0:9d17e4342598 298 #endif
wolfSSL 0:9d17e4342598 299
wolfSSL 0:9d17e4342598 300
wolfSSL 0:9d17e4342598 301 ProtocolVersion MakeTLSv1_2(void)
wolfSSL 0:9d17e4342598 302 {
wolfSSL 0:9d17e4342598 303 ProtocolVersion pv;
wolfSSL 0:9d17e4342598 304 pv.major = SSLv3_MAJOR;
wolfSSL 0:9d17e4342598 305 pv.minor = TLSv1_2_MINOR;
wolfSSL 0:9d17e4342598 306
wolfSSL 0:9d17e4342598 307 return pv;
wolfSSL 0:9d17e4342598 308 }
wolfSSL 0:9d17e4342598 309
wolfSSL 0:9d17e4342598 310
wolfSSL 0:9d17e4342598 311 static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret";
wolfSSL 0:9d17e4342598 312 static const byte key_label [KEY_LABEL_SZ + 1] = "key expansion";
wolfSSL 0:9d17e4342598 313
wolfSSL 0:9d17e4342598 314
wolfSSL 0:9d17e4342598 315 int DeriveTlsKeys(CYASSL* ssl)
wolfSSL 0:9d17e4342598 316 {
wolfSSL 0:9d17e4342598 317 int ret;
wolfSSL 0:9d17e4342598 318 int length = 2 * ssl->specs.hash_size +
wolfSSL 0:9d17e4342598 319 2 * ssl->specs.key_size +
wolfSSL 0:9d17e4342598 320 2 * ssl->specs.iv_size;
wolfSSL 0:9d17e4342598 321 byte seed[SEED_LEN];
wolfSSL 0:9d17e4342598 322 byte key_data[MAX_PRF_DIG];
wolfSSL 0:9d17e4342598 323
wolfSSL 0:9d17e4342598 324 XMEMCPY(seed, ssl->arrays->serverRandom, RAN_LEN);
wolfSSL 0:9d17e4342598 325 XMEMCPY(&seed[RAN_LEN], ssl->arrays->clientRandom, RAN_LEN);
wolfSSL 0:9d17e4342598 326
wolfSSL 0:9d17e4342598 327 ret = PRF(key_data, length, ssl->arrays->masterSecret, SECRET_LEN,
wolfSSL 0:9d17e4342598 328 key_label, KEY_LABEL_SZ, seed, SEED_LEN, IsAtLeastTLSv1_2(ssl),
wolfSSL 0:9d17e4342598 329 ssl->specs.mac_algorithm);
wolfSSL 0:9d17e4342598 330 if (ret != 0)
wolfSSL 0:9d17e4342598 331 return ret;
wolfSSL 0:9d17e4342598 332
wolfSSL 0:9d17e4342598 333 return StoreKeys(ssl, key_data);
wolfSSL 0:9d17e4342598 334 }
wolfSSL 0:9d17e4342598 335
wolfSSL 0:9d17e4342598 336
wolfSSL 0:9d17e4342598 337 int MakeTlsMasterSecret(CYASSL* ssl)
wolfSSL 0:9d17e4342598 338 {
wolfSSL 0:9d17e4342598 339 int ret;
wolfSSL 0:9d17e4342598 340 byte seed[SEED_LEN];
wolfSSL 0:9d17e4342598 341
wolfSSL 0:9d17e4342598 342 XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN);
wolfSSL 0:9d17e4342598 343 XMEMCPY(&seed[RAN_LEN], ssl->arrays->serverRandom, RAN_LEN);
wolfSSL 0:9d17e4342598 344
wolfSSL 0:9d17e4342598 345 ret = PRF(ssl->arrays->masterSecret, SECRET_LEN,
wolfSSL 0:9d17e4342598 346 ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
wolfSSL 0:9d17e4342598 347 master_label, MASTER_LABEL_SZ,
wolfSSL 0:9d17e4342598 348 seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
wolfSSL 0:9d17e4342598 349 if (ret != 0)
wolfSSL 0:9d17e4342598 350 return ret;
wolfSSL 0:9d17e4342598 351
wolfSSL 0:9d17e4342598 352 #ifdef SHOW_SECRETS
wolfSSL 0:9d17e4342598 353 {
wolfSSL 0:9d17e4342598 354 int i;
wolfSSL 0:9d17e4342598 355 printf("master secret: ");
wolfSSL 0:9d17e4342598 356 for (i = 0; i < SECRET_LEN; i++)
wolfSSL 0:9d17e4342598 357 printf("%02x", ssl->arrays->masterSecret[i]);
wolfSSL 0:9d17e4342598 358 printf("\n");
wolfSSL 0:9d17e4342598 359 }
wolfSSL 0:9d17e4342598 360 #endif
wolfSSL 0:9d17e4342598 361
wolfSSL 0:9d17e4342598 362 return DeriveTlsKeys(ssl);
wolfSSL 0:9d17e4342598 363 }
wolfSSL 0:9d17e4342598 364
wolfSSL 0:9d17e4342598 365
wolfSSL 0:9d17e4342598 366 /* Used by EAP-TLS and EAP-TTLS to derive keying material from
wolfSSL 0:9d17e4342598 367 * the master_secret. */
wolfSSL 0:9d17e4342598 368 int CyaSSL_make_eap_keys(CYASSL* ssl, void* msk, unsigned int len,
wolfSSL 0:9d17e4342598 369 const char* label)
wolfSSL 0:9d17e4342598 370 {
wolfSSL 0:9d17e4342598 371 byte seed[SEED_LEN];
wolfSSL 0:9d17e4342598 372
wolfSSL 0:9d17e4342598 373 /*
wolfSSL 0:9d17e4342598 374 * As per RFC-5281, the order of the client and server randoms is reversed
wolfSSL 0:9d17e4342598 375 * from that used by the TLS protocol to derive keys.
wolfSSL 0:9d17e4342598 376 */
wolfSSL 0:9d17e4342598 377 XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN);
wolfSSL 0:9d17e4342598 378 XMEMCPY(&seed[RAN_LEN], ssl->arrays->serverRandom, RAN_LEN);
wolfSSL 0:9d17e4342598 379
wolfSSL 0:9d17e4342598 380 return PRF((byte*)msk, len,
wolfSSL 0:9d17e4342598 381 ssl->arrays->masterSecret, SECRET_LEN,
wolfSSL 0:9d17e4342598 382 (const byte *)label, (word32)strlen(label),
wolfSSL 0:9d17e4342598 383 seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
wolfSSL 0:9d17e4342598 384
wolfSSL 0:9d17e4342598 385 }
wolfSSL 0:9d17e4342598 386
wolfSSL 0:9d17e4342598 387
wolfSSL 0:9d17e4342598 388 /*** next for static INLINE s copied internal.c ***/
wolfSSL 0:9d17e4342598 389
wolfSSL 0:9d17e4342598 390 /* convert 16 bit integer to opaque */
wolfSSL 0:9d17e4342598 391 static INLINE void c16toa(word16 u16, byte* c)
wolfSSL 0:9d17e4342598 392 {
wolfSSL 0:9d17e4342598 393 c[0] = (u16 >> 8) & 0xff;
wolfSSL 0:9d17e4342598 394 c[1] = u16 & 0xff;
wolfSSL 0:9d17e4342598 395 }
wolfSSL 0:9d17e4342598 396
wolfSSL 0:9d17e4342598 397 #ifdef HAVE_TLS_EXTENSIONS
wolfSSL 0:9d17e4342598 398 /* convert opaque to 16 bit integer */
wolfSSL 0:9d17e4342598 399 static INLINE void ato16(const byte* c, word16* u16)
wolfSSL 0:9d17e4342598 400 {
wolfSSL 0:9d17e4342598 401 *u16 = (c[0] << 8) | (c[1]);
wolfSSL 0:9d17e4342598 402 }
wolfSSL 0:9d17e4342598 403
wolfSSL 0:9d17e4342598 404 #ifdef HAVE_SNI
wolfSSL 0:9d17e4342598 405 /* convert a 24 bit integer into a 32 bit one */
wolfSSL 0:9d17e4342598 406 static INLINE void c24to32(const word24 u24, word32* u32)
wolfSSL 0:9d17e4342598 407 {
wolfSSL 0:9d17e4342598 408 *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
wolfSSL 0:9d17e4342598 409 }
wolfSSL 0:9d17e4342598 410 #endif
wolfSSL 0:9d17e4342598 411 #endif
wolfSSL 0:9d17e4342598 412
wolfSSL 0:9d17e4342598 413 /* convert 32 bit integer to opaque */
wolfSSL 0:9d17e4342598 414 static INLINE void c32toa(word32 u32, byte* c)
wolfSSL 0:9d17e4342598 415 {
wolfSSL 0:9d17e4342598 416 c[0] = (u32 >> 24) & 0xff;
wolfSSL 0:9d17e4342598 417 c[1] = (u32 >> 16) & 0xff;
wolfSSL 0:9d17e4342598 418 c[2] = (u32 >> 8) & 0xff;
wolfSSL 0:9d17e4342598 419 c[3] = u32 & 0xff;
wolfSSL 0:9d17e4342598 420 }
wolfSSL 0:9d17e4342598 421
wolfSSL 0:9d17e4342598 422
wolfSSL 0:9d17e4342598 423 static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
wolfSSL 0:9d17e4342598 424 {
wolfSSL 0:9d17e4342598 425 #ifdef CYASSL_DTLS
wolfSSL 0:9d17e4342598 426 if (ssl->options.dtls) {
wolfSSL 0:9d17e4342598 427 if (verify)
wolfSSL 0:9d17e4342598 428 return ssl->keys.dtls_state.curSeq; /* explicit from peer */
wolfSSL 0:9d17e4342598 429 else
wolfSSL 0:9d17e4342598 430 return ssl->keys.dtls_sequence_number - 1; /* already incremented */
wolfSSL 0:9d17e4342598 431 }
wolfSSL 0:9d17e4342598 432 #endif
wolfSSL 0:9d17e4342598 433 if (verify)
wolfSSL 0:9d17e4342598 434 return ssl->keys.peer_sequence_number++;
wolfSSL 0:9d17e4342598 435 else
wolfSSL 0:9d17e4342598 436 return ssl->keys.sequence_number++;
wolfSSL 0:9d17e4342598 437 }
wolfSSL 0:9d17e4342598 438
wolfSSL 0:9d17e4342598 439
wolfSSL 0:9d17e4342598 440 #ifdef CYASSL_DTLS
wolfSSL 0:9d17e4342598 441
wolfSSL 0:9d17e4342598 442 static INLINE word32 GetEpoch(CYASSL* ssl, int verify)
wolfSSL 0:9d17e4342598 443 {
wolfSSL 0:9d17e4342598 444 if (verify)
wolfSSL 0:9d17e4342598 445 return ssl->keys.dtls_state.curEpoch;
wolfSSL 0:9d17e4342598 446 else
wolfSSL 0:9d17e4342598 447 return ssl->keys.dtls_epoch;
wolfSSL 0:9d17e4342598 448 }
wolfSSL 0:9d17e4342598 449
wolfSSL 0:9d17e4342598 450 #endif /* CYASSL_DTLS */
wolfSSL 0:9d17e4342598 451
wolfSSL 0:9d17e4342598 452
wolfSSL 0:9d17e4342598 453 /*** end copy ***/
wolfSSL 0:9d17e4342598 454
wolfSSL 0:9d17e4342598 455
wolfSSL 0:9d17e4342598 456 /* return HMAC digest type in CyaSSL format */
wolfSSL 0:9d17e4342598 457 int CyaSSL_GetHmacType(CYASSL* ssl)
wolfSSL 0:9d17e4342598 458 {
wolfSSL 0:9d17e4342598 459 if (ssl == NULL)
wolfSSL 0:9d17e4342598 460 return BAD_FUNC_ARG;
wolfSSL 0:9d17e4342598 461
wolfSSL 0:9d17e4342598 462 switch (ssl->specs.mac_algorithm) {
wolfSSL 0:9d17e4342598 463 #ifndef NO_MD5
wolfSSL 0:9d17e4342598 464 case md5_mac:
wolfSSL 0:9d17e4342598 465 {
wolfSSL 0:9d17e4342598 466 return MD5;
wolfSSL 0:9d17e4342598 467 }
wolfSSL 0:9d17e4342598 468 #endif
wolfSSL 0:9d17e4342598 469 #ifndef NO_SHA256
wolfSSL 0:9d17e4342598 470 case sha256_mac:
wolfSSL 0:9d17e4342598 471 {
wolfSSL 0:9d17e4342598 472 return SHA256;
wolfSSL 0:9d17e4342598 473 }
wolfSSL 0:9d17e4342598 474 #endif
wolfSSL 0:9d17e4342598 475 #ifdef CYASSL_SHA384
wolfSSL 0:9d17e4342598 476 case sha384_mac:
wolfSSL 0:9d17e4342598 477 {
wolfSSL 0:9d17e4342598 478 return SHA384;
wolfSSL 0:9d17e4342598 479 }
wolfSSL 0:9d17e4342598 480
wolfSSL 0:9d17e4342598 481 #endif
wolfSSL 0:9d17e4342598 482 #ifndef NO_SHA
wolfSSL 0:9d17e4342598 483 case sha_mac:
wolfSSL 0:9d17e4342598 484 {
wolfSSL 0:9d17e4342598 485 return SHA;
wolfSSL 0:9d17e4342598 486 }
wolfSSL 0:9d17e4342598 487 #endif
wolfSSL 0:9d17e4342598 488 #ifdef HAVE_BLAKE2
wolfSSL 0:9d17e4342598 489 case blake2b_mac:
wolfSSL 0:9d17e4342598 490 {
wolfSSL 0:9d17e4342598 491 return BLAKE2B_ID;
wolfSSL 0:9d17e4342598 492 }
wolfSSL 0:9d17e4342598 493 #endif
wolfSSL 0:9d17e4342598 494 default:
wolfSSL 0:9d17e4342598 495 {
wolfSSL 0:9d17e4342598 496 return SSL_FATAL_ERROR;
wolfSSL 0:9d17e4342598 497 }
wolfSSL 0:9d17e4342598 498 }
wolfSSL 0:9d17e4342598 499 }
wolfSSL 0:9d17e4342598 500
wolfSSL 0:9d17e4342598 501
wolfSSL 0:9d17e4342598 502 int CyaSSL_SetTlsHmacInner(CYASSL* ssl, byte* inner, word32 sz, int content,
wolfSSL 0:9d17e4342598 503 int verify)
wolfSSL 0:9d17e4342598 504 {
wolfSSL 0:9d17e4342598 505 if (ssl == NULL || inner == NULL)
wolfSSL 0:9d17e4342598 506 return BAD_FUNC_ARG;
wolfSSL 0:9d17e4342598 507
wolfSSL 0:9d17e4342598 508 XMEMSET(inner, 0, CYASSL_TLS_HMAC_INNER_SZ);
wolfSSL 0:9d17e4342598 509
wolfSSL 0:9d17e4342598 510 #ifdef CYASSL_DTLS
wolfSSL 0:9d17e4342598 511 if (ssl->options.dtls)
wolfSSL 0:9d17e4342598 512 c16toa((word16)GetEpoch(ssl, verify), inner);
wolfSSL 0:9d17e4342598 513 #endif
wolfSSL 0:9d17e4342598 514 c32toa(GetSEQIncrement(ssl, verify), &inner[sizeof(word32)]);
wolfSSL 0:9d17e4342598 515 inner[SEQ_SZ] = (byte)content;
wolfSSL 0:9d17e4342598 516 inner[SEQ_SZ + ENUM_LEN] = ssl->version.major;
wolfSSL 0:9d17e4342598 517 inner[SEQ_SZ + ENUM_LEN + ENUM_LEN] = ssl->version.minor;
wolfSSL 0:9d17e4342598 518 c16toa((word16)sz, inner + SEQ_SZ + ENUM_LEN + VERSION_SZ);
wolfSSL 0:9d17e4342598 519
wolfSSL 0:9d17e4342598 520 return 0;
wolfSSL 0:9d17e4342598 521 }
wolfSSL 0:9d17e4342598 522
wolfSSL 0:9d17e4342598 523
wolfSSL 0:9d17e4342598 524 /* TLS type HMAC */
wolfSSL 0:9d17e4342598 525 int TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
wolfSSL 0:9d17e4342598 526 int content, int verify)
wolfSSL 0:9d17e4342598 527 {
wolfSSL 0:9d17e4342598 528 Hmac hmac;
wolfSSL 0:9d17e4342598 529 int ret;
wolfSSL 0:9d17e4342598 530 byte myInner[CYASSL_TLS_HMAC_INNER_SZ];
wolfSSL 0:9d17e4342598 531
wolfSSL 0:9d17e4342598 532 CyaSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify);
wolfSSL 0:9d17e4342598 533
wolfSSL 0:9d17e4342598 534 ret = HmacSetKey(&hmac, CyaSSL_GetHmacType(ssl),
wolfSSL 0:9d17e4342598 535 CyaSSL_GetMacSecret(ssl, verify), ssl->specs.hash_size);
wolfSSL 0:9d17e4342598 536 if (ret != 0)
wolfSSL 0:9d17e4342598 537 return ret;
wolfSSL 0:9d17e4342598 538 HmacUpdate(&hmac, myInner, sizeof(myInner));
wolfSSL 0:9d17e4342598 539 HmacUpdate(&hmac, in, sz); /* content */
wolfSSL 0:9d17e4342598 540 HmacFinal(&hmac, digest);
wolfSSL 0:9d17e4342598 541
wolfSSL 0:9d17e4342598 542 return 0;
wolfSSL 0:9d17e4342598 543 }
wolfSSL 0:9d17e4342598 544
wolfSSL 0:9d17e4342598 545 #ifdef HAVE_TLS_EXTENSIONS
wolfSSL 0:9d17e4342598 546
wolfSSL 0:9d17e4342598 547 #define IS_OFF(semaphore, light) \
wolfSSL 0:9d17e4342598 548 ((semaphore)[(light) / 8] ^ (byte) (0x01 << ((light) % 8)))
wolfSSL 0:9d17e4342598 549
wolfSSL 0:9d17e4342598 550 #define TURN_ON(semaphore, light) \
wolfSSL 0:9d17e4342598 551 ((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8)))
wolfSSL 0:9d17e4342598 552
wolfSSL 0:9d17e4342598 553 static int TLSX_Append(TLSX** list, TLSX_Type type)
wolfSSL 0:9d17e4342598 554 {
wolfSSL 0:9d17e4342598 555 TLSX* extension;
wolfSSL 0:9d17e4342598 556
wolfSSL 0:9d17e4342598 557 if (list == NULL) /* won't check type since this function is static */
wolfSSL 0:9d17e4342598 558 return BAD_FUNC_ARG;
wolfSSL 0:9d17e4342598 559
wolfSSL 0:9d17e4342598 560 if ((extension = XMALLOC(sizeof(TLSX), 0, DYNAMIC_TYPE_TLSX)) == NULL)
wolfSSL 0:9d17e4342598 561 return MEMORY_E;
wolfSSL 0:9d17e4342598 562
wolfSSL 0:9d17e4342598 563 extension->type = type;
wolfSSL 0:9d17e4342598 564 extension->data = NULL;
wolfSSL 0:9d17e4342598 565 extension->resp = 0;
wolfSSL 0:9d17e4342598 566 extension->next = *list;
wolfSSL 0:9d17e4342598 567 *list = extension;
wolfSSL 0:9d17e4342598 568
wolfSSL 0:9d17e4342598 569 return 0;
wolfSSL 0:9d17e4342598 570 }
wolfSSL 0:9d17e4342598 571
wolfSSL 0:9d17e4342598 572 #ifndef NO_CYASSL_SERVER
wolfSSL 0:9d17e4342598 573
wolfSSL 0:9d17e4342598 574 void TLSX_SetResponse(CYASSL* ssl, TLSX_Type type);
wolfSSL 0:9d17e4342598 575
wolfSSL 0:9d17e4342598 576 void TLSX_SetResponse(CYASSL* ssl, TLSX_Type type)
wolfSSL 0:9d17e4342598 577 {
wolfSSL 0:9d17e4342598 578 TLSX *ext = TLSX_Find(ssl->extensions, type);
wolfSSL 0:9d17e4342598 579
wolfSSL 0:9d17e4342598 580 if (ext)
wolfSSL 0:9d17e4342598 581 ext->resp = 1;
wolfSSL 0:9d17e4342598 582 }
wolfSSL 0:9d17e4342598 583
wolfSSL 0:9d17e4342598 584 #endif
wolfSSL 0:9d17e4342598 585
wolfSSL 0:9d17e4342598 586 /* SNI - Server Name Indication */
wolfSSL 0:9d17e4342598 587
wolfSSL 0:9d17e4342598 588 #ifdef HAVE_SNI
wolfSSL 0:9d17e4342598 589
wolfSSL 0:9d17e4342598 590 static void TLSX_SNI_Free(SNI* sni)
wolfSSL 0:9d17e4342598 591 {
wolfSSL 0:9d17e4342598 592 if (sni) {
wolfSSL 0:9d17e4342598 593 switch (sni->type) {
wolfSSL 0:9d17e4342598 594 case CYASSL_SNI_HOST_NAME:
wolfSSL 0:9d17e4342598 595 XFREE(sni->data.host_name, 0, DYNAMIC_TYPE_TLSX);
wolfSSL 0:9d17e4342598 596 break;
wolfSSL 0:9d17e4342598 597 }
wolfSSL 0:9d17e4342598 598
wolfSSL 0:9d17e4342598 599 XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
wolfSSL 0:9d17e4342598 600 }
wolfSSL 0:9d17e4342598 601 }
wolfSSL 0:9d17e4342598 602
wolfSSL 0:9d17e4342598 603 static void TLSX_SNI_FreeAll(SNI* list)
wolfSSL 0:9d17e4342598 604 {
wolfSSL 0:9d17e4342598 605 SNI* sni;
wolfSSL 0:9d17e4342598 606
wolfSSL 0:9d17e4342598 607 while ((sni = list)) {
wolfSSL 0:9d17e4342598 608 list = sni->next;
wolfSSL 0:9d17e4342598 609 TLSX_SNI_Free(sni);
wolfSSL 0:9d17e4342598 610 }
wolfSSL 0:9d17e4342598 611 }
wolfSSL 0:9d17e4342598 612
wolfSSL 0:9d17e4342598 613 static int TLSX_SNI_Append(SNI** list, byte type, const void* data, word16 size)
wolfSSL 0:9d17e4342598 614 {
wolfSSL 0:9d17e4342598 615 SNI* sni;
wolfSSL 0:9d17e4342598 616
wolfSSL 0:9d17e4342598 617 if (list == NULL)
wolfSSL 0:9d17e4342598 618 return BAD_FUNC_ARG;
wolfSSL 0:9d17e4342598 619
wolfSSL 0:9d17e4342598 620 if ((sni = XMALLOC(sizeof(SNI), 0, DYNAMIC_TYPE_TLSX)) == NULL)
wolfSSL 0:9d17e4342598 621 return MEMORY_E;
wolfSSL 0:9d17e4342598 622
wolfSSL 0:9d17e4342598 623 switch (type) {
wolfSSL 0:9d17e4342598 624 case CYASSL_SNI_HOST_NAME: {
wolfSSL 0:9d17e4342598 625 sni->data.host_name = XMALLOC(size + 1, 0, DYNAMIC_TYPE_TLSX);
wolfSSL 0:9d17e4342598 626
wolfSSL 0:9d17e4342598 627 if (sni->data.host_name) {
wolfSSL 0:9d17e4342598 628 XSTRNCPY(sni->data.host_name, (const char*) data, size);
wolfSSL 0:9d17e4342598 629 sni->data.host_name[size] = 0;
wolfSSL 0:9d17e4342598 630 } else {
wolfSSL 0:9d17e4342598 631 XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
wolfSSL 0:9d17e4342598 632 return MEMORY_E;
wolfSSL 0:9d17e4342598 633 }
wolfSSL 0:9d17e4342598 634 }
wolfSSL 0:9d17e4342598 635 break;
wolfSSL 0:9d17e4342598 636
wolfSSL 0:9d17e4342598 637 default: /* invalid type */
wolfSSL 0:9d17e4342598 638 XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
wolfSSL 0:9d17e4342598 639 return BAD_FUNC_ARG;
wolfSSL 0:9d17e4342598 640 }
wolfSSL 0:9d17e4342598 641
wolfSSL 0:9d17e4342598 642 sni->type = type;
wolfSSL 0:9d17e4342598 643 sni->next = *list;
wolfSSL 0:9d17e4342598 644
wolfSSL 0:9d17e4342598 645 #ifndef NO_CYASSL_SERVER
wolfSSL 0:9d17e4342598 646 sni->options = 0;
wolfSSL 0:9d17e4342598 647 sni->status = CYASSL_SNI_NO_MATCH;
wolfSSL 0:9d17e4342598 648 #endif
wolfSSL 0:9d17e4342598 649
wolfSSL 0:9d17e4342598 650 *list = sni;
wolfSSL 0:9d17e4342598 651
wolfSSL 0:9d17e4342598 652 return 0;
wolfSSL 0:9d17e4342598 653 }
wolfSSL 0:9d17e4342598 654
wolfSSL 0:9d17e4342598 655 static word16 TLSX_SNI_GetSize(SNI* list)
wolfSSL 0:9d17e4342598 656 {
wolfSSL 0:9d17e4342598 657 SNI* sni;
wolfSSL 0:9d17e4342598 658 word16 length = OPAQUE16_LEN; /* list length */
wolfSSL 0:9d17e4342598 659
wolfSSL 0:9d17e4342598 660 while ((sni = list)) {
wolfSSL 0:9d17e4342598 661 list = sni->next;
wolfSSL 0:9d17e4342598 662
wolfSSL 0:9d17e4342598 663 length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */
wolfSSL 0:9d17e4342598 664
wolfSSL 0:9d17e4342598 665 switch (sni->type) {
wolfSSL 0:9d17e4342598 666 case CYASSL_SNI_HOST_NAME:
wolfSSL 0:9d17e4342598 667 length += XSTRLEN((char*) sni->data.host_name);
wolfSSL 0:9d17e4342598 668 break;
wolfSSL 0:9d17e4342598 669 }
wolfSSL 0:9d17e4342598 670 }
wolfSSL 0:9d17e4342598 671
wolfSSL 0:9d17e4342598 672 return length;
wolfSSL 0:9d17e4342598 673 }
wolfSSL 0:9d17e4342598 674
wolfSSL 0:9d17e4342598 675 static word16 TLSX_SNI_Write(SNI* list, byte* output)
wolfSSL 0:9d17e4342598 676 {
wolfSSL 0:9d17e4342598 677 SNI* sni;
wolfSSL 0:9d17e4342598 678 word16 length = 0;
wolfSSL 0:9d17e4342598 679 word16 offset = OPAQUE16_LEN; /* list length offset */
wolfSSL 0:9d17e4342598 680
wolfSSL 0:9d17e4342598 681 while ((sni = list)) {
wolfSSL 0:9d17e4342598 682 list = sni->next;
wolfSSL 0:9d17e4342598 683
wolfSSL 0:9d17e4342598 684 output[offset++] = sni->type; /* sni type */
wolfSSL 0:9d17e4342598 685
wolfSSL 0:9d17e4342598 686 switch (sni->type) {
wolfSSL 0:9d17e4342598 687 case CYASSL_SNI_HOST_NAME:
wolfSSL 0:9d17e4342598 688 length = XSTRLEN((char*) sni->data.host_name);
wolfSSL 0:9d17e4342598 689
wolfSSL 0:9d17e4342598 690 c16toa(length, output + offset); /* sni length */
wolfSSL 0:9d17e4342598 691 offset += OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 692
wolfSSL 0:9d17e4342598 693 XMEMCPY(output + offset, sni->data.host_name, length);
wolfSSL 0:9d17e4342598 694
wolfSSL 0:9d17e4342598 695 offset += length;
wolfSSL 0:9d17e4342598 696 break;
wolfSSL 0:9d17e4342598 697 }
wolfSSL 0:9d17e4342598 698 }
wolfSSL 0:9d17e4342598 699
wolfSSL 0:9d17e4342598 700 c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
wolfSSL 0:9d17e4342598 701
wolfSSL 0:9d17e4342598 702 return offset;
wolfSSL 0:9d17e4342598 703 }
wolfSSL 0:9d17e4342598 704
wolfSSL 0:9d17e4342598 705 static SNI* TLSX_SNI_Find(SNI *list, byte type)
wolfSSL 0:9d17e4342598 706 {
wolfSSL 0:9d17e4342598 707 SNI *sni = list;
wolfSSL 0:9d17e4342598 708
wolfSSL 0:9d17e4342598 709 while (sni && sni->type != type)
wolfSSL 0:9d17e4342598 710 sni = sni->next;
wolfSSL 0:9d17e4342598 711
wolfSSL 0:9d17e4342598 712 return sni;
wolfSSL 0:9d17e4342598 713 }
wolfSSL 0:9d17e4342598 714
wolfSSL 0:9d17e4342598 715 #ifndef NO_CYASSL_SERVER
wolfSSL 0:9d17e4342598 716 static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status)
wolfSSL 0:9d17e4342598 717 {
wolfSSL 0:9d17e4342598 718 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
wolfSSL 0:9d17e4342598 719 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
wolfSSL 0:9d17e4342598 720
wolfSSL 0:9d17e4342598 721 if (sni) {
wolfSSL 0:9d17e4342598 722 sni->status = status;
wolfSSL 0:9d17e4342598 723 CYASSL_MSG("SNI did match!");
wolfSSL 0:9d17e4342598 724 }
wolfSSL 0:9d17e4342598 725 }
wolfSSL 0:9d17e4342598 726
wolfSSL 0:9d17e4342598 727 byte TLSX_SNI_Status(TLSX* extensions, byte type)
wolfSSL 0:9d17e4342598 728 {
wolfSSL 0:9d17e4342598 729 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
wolfSSL 0:9d17e4342598 730 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
wolfSSL 0:9d17e4342598 731
wolfSSL 0:9d17e4342598 732 if (sni)
wolfSSL 0:9d17e4342598 733 return sni->status;
wolfSSL 0:9d17e4342598 734
wolfSSL 0:9d17e4342598 735 return 0;
wolfSSL 0:9d17e4342598 736 }
wolfSSL 0:9d17e4342598 737 #endif
wolfSSL 0:9d17e4342598 738
wolfSSL 0:9d17e4342598 739 static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length,
wolfSSL 0:9d17e4342598 740 byte isRequest)
wolfSSL 0:9d17e4342598 741 {
wolfSSL 0:9d17e4342598 742 #ifndef NO_CYASSL_SERVER
wolfSSL 0:9d17e4342598 743 word16 size = 0;
wolfSSL 0:9d17e4342598 744 word16 offset = 0;
wolfSSL 0:9d17e4342598 745 #endif
wolfSSL 0:9d17e4342598 746
wolfSSL 0:9d17e4342598 747 TLSX *extension = TLSX_Find(ssl->extensions, SERVER_NAME_INDICATION);
wolfSSL 0:9d17e4342598 748
wolfSSL 0:9d17e4342598 749 if (!extension)
wolfSSL 0:9d17e4342598 750 extension = TLSX_Find(ssl->ctx->extensions, SERVER_NAME_INDICATION);
wolfSSL 0:9d17e4342598 751
wolfSSL 0:9d17e4342598 752 if (!extension || !extension->data)
wolfSSL 0:9d17e4342598 753 return isRequest ? 0 : BUFFER_ERROR; /* not using SNI OR unexpected
wolfSSL 0:9d17e4342598 754 SNI response from server. */
wolfSSL 0:9d17e4342598 755
wolfSSL 0:9d17e4342598 756 if (!isRequest)
wolfSSL 0:9d17e4342598 757 return length ? BUFFER_ERROR : 0; /* SNI response must be empty!
wolfSSL 0:9d17e4342598 758 Nothing else to do. */
wolfSSL 0:9d17e4342598 759
wolfSSL 0:9d17e4342598 760 #ifndef NO_CYASSL_SERVER
wolfSSL 0:9d17e4342598 761
wolfSSL 0:9d17e4342598 762 if (OPAQUE16_LEN > length)
wolfSSL 0:9d17e4342598 763 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 764
wolfSSL 0:9d17e4342598 765 ato16(input, &size);
wolfSSL 0:9d17e4342598 766 offset += OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 767
wolfSSL 0:9d17e4342598 768 /* validating sni list length */
wolfSSL 0:9d17e4342598 769 if (length != OPAQUE16_LEN + size)
wolfSSL 0:9d17e4342598 770 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 771
wolfSSL 0:9d17e4342598 772 for (size = 0; offset < length; offset += size) {
wolfSSL 0:9d17e4342598 773 SNI *sni;
wolfSSL 0:9d17e4342598 774 byte type = input[offset++];
wolfSSL 0:9d17e4342598 775
wolfSSL 0:9d17e4342598 776 if (offset + OPAQUE16_LEN > length)
wolfSSL 0:9d17e4342598 777 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 778
wolfSSL 0:9d17e4342598 779 ato16(input + offset, &size);
wolfSSL 0:9d17e4342598 780 offset += OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 781
wolfSSL 0:9d17e4342598 782 if (offset + size > length)
wolfSSL 0:9d17e4342598 783 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 784
wolfSSL 0:9d17e4342598 785 if (!(sni = TLSX_SNI_Find((SNI *) extension->data, type))) {
wolfSSL 0:9d17e4342598 786 continue; /* not using this SNI type */
wolfSSL 0:9d17e4342598 787 }
wolfSSL 0:9d17e4342598 788
wolfSSL 0:9d17e4342598 789 switch(type) {
wolfSSL 0:9d17e4342598 790 case CYASSL_SNI_HOST_NAME: {
wolfSSL 0:9d17e4342598 791 byte matched = (XSTRLEN(sni->data.host_name) == size)
wolfSSL 0:9d17e4342598 792 && (XSTRNCMP(sni->data.host_name,
wolfSSL 0:9d17e4342598 793 (const char *) input + offset, size) == 0);
wolfSSL 0:9d17e4342598 794
wolfSSL 0:9d17e4342598 795 if (matched || sni->options & CYASSL_SNI_ANSWER_ON_MISMATCH) {
wolfSSL 0:9d17e4342598 796 int r = TLSX_UseSNI(&ssl->extensions,
wolfSSL 0:9d17e4342598 797 type, input + offset, size);
wolfSSL 0:9d17e4342598 798
wolfSSL 0:9d17e4342598 799 if (r != SSL_SUCCESS) return r; /* throw error */
wolfSSL 0:9d17e4342598 800
wolfSSL 0:9d17e4342598 801 TLSX_SNI_SetStatus(ssl->extensions, type,
wolfSSL 0:9d17e4342598 802 matched ? CYASSL_SNI_REAL_MATCH : CYASSL_SNI_FAKE_MATCH);
wolfSSL 0:9d17e4342598 803
wolfSSL 0:9d17e4342598 804 } else if (!(sni->options & CYASSL_SNI_CONTINUE_ON_MISMATCH)) {
wolfSSL 0:9d17e4342598 805 SendAlert(ssl, alert_fatal, unrecognized_name);
wolfSSL 0:9d17e4342598 806
wolfSSL 0:9d17e4342598 807 return UNKNOWN_SNI_HOST_NAME_E;
wolfSSL 0:9d17e4342598 808 }
wolfSSL 0:9d17e4342598 809 break;
wolfSSL 0:9d17e4342598 810 }
wolfSSL 0:9d17e4342598 811 }
wolfSSL 0:9d17e4342598 812
wolfSSL 0:9d17e4342598 813 TLSX_SetResponse(ssl, SERVER_NAME_INDICATION);
wolfSSL 0:9d17e4342598 814 }
wolfSSL 0:9d17e4342598 815
wolfSSL 0:9d17e4342598 816 #endif
wolfSSL 0:9d17e4342598 817
wolfSSL 0:9d17e4342598 818 return 0;
wolfSSL 0:9d17e4342598 819 }
wolfSSL 0:9d17e4342598 820
wolfSSL 0:9d17e4342598 821 int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size)
wolfSSL 0:9d17e4342598 822 {
wolfSSL 0:9d17e4342598 823 TLSX* extension = NULL;
wolfSSL 0:9d17e4342598 824 SNI* sni = NULL;
wolfSSL 0:9d17e4342598 825 int ret = 0;
wolfSSL 0:9d17e4342598 826
wolfSSL 0:9d17e4342598 827 if (extensions == NULL || data == NULL)
wolfSSL 0:9d17e4342598 828 return BAD_FUNC_ARG;
wolfSSL 0:9d17e4342598 829
wolfSSL 0:9d17e4342598 830 if ((ret = TLSX_SNI_Append(&sni, type, data, size)) != 0)
wolfSSL 0:9d17e4342598 831 return ret;
wolfSSL 0:9d17e4342598 832
wolfSSL 0:9d17e4342598 833 extension = *extensions;
wolfSSL 0:9d17e4342598 834
wolfSSL 0:9d17e4342598 835 /* find SNI extension if it already exists. */
wolfSSL 0:9d17e4342598 836 while (extension && extension->type != SERVER_NAME_INDICATION)
wolfSSL 0:9d17e4342598 837 extension = extension->next;
wolfSSL 0:9d17e4342598 838
wolfSSL 0:9d17e4342598 839 /* push new SNI extension if it doesn't exists. */
wolfSSL 0:9d17e4342598 840 if (!extension) {
wolfSSL 0:9d17e4342598 841 if ((ret = TLSX_Append(extensions, SERVER_NAME_INDICATION)) != 0) {
wolfSSL 0:9d17e4342598 842 TLSX_SNI_Free(sni);
wolfSSL 0:9d17e4342598 843 return ret;
wolfSSL 0:9d17e4342598 844 }
wolfSSL 0:9d17e4342598 845
wolfSSL 0:9d17e4342598 846 extension = *extensions;
wolfSSL 0:9d17e4342598 847 }
wolfSSL 0:9d17e4342598 848
wolfSSL 0:9d17e4342598 849 /* push new SNI object to extension data. */
wolfSSL 0:9d17e4342598 850 sni->next = (SNI*) extension->data;
wolfSSL 0:9d17e4342598 851 extension->data = (void*) sni;
wolfSSL 0:9d17e4342598 852
wolfSSL 0:9d17e4342598 853 /* look for another server name of the same type to remove (replacement) */
wolfSSL 0:9d17e4342598 854 do {
wolfSSL 0:9d17e4342598 855 if (sni->next && sni->next->type == type) {
wolfSSL 0:9d17e4342598 856 SNI *next = sni->next;
wolfSSL 0:9d17e4342598 857
wolfSSL 0:9d17e4342598 858 sni->next = next->next;
wolfSSL 0:9d17e4342598 859 TLSX_SNI_Free(next);
wolfSSL 0:9d17e4342598 860
wolfSSL 0:9d17e4342598 861 break;
wolfSSL 0:9d17e4342598 862 }
wolfSSL 0:9d17e4342598 863 } while ((sni = sni->next));
wolfSSL 0:9d17e4342598 864
wolfSSL 0:9d17e4342598 865 return SSL_SUCCESS;
wolfSSL 0:9d17e4342598 866 }
wolfSSL 0:9d17e4342598 867
wolfSSL 0:9d17e4342598 868 #ifndef NO_CYASSL_SERVER
wolfSSL 0:9d17e4342598 869 word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data)
wolfSSL 0:9d17e4342598 870 {
wolfSSL 0:9d17e4342598 871 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
wolfSSL 0:9d17e4342598 872 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
wolfSSL 0:9d17e4342598 873
wolfSSL 0:9d17e4342598 874 if (sni && sni->status != CYASSL_SNI_NO_MATCH) {
wolfSSL 0:9d17e4342598 875 switch (sni->type) {
wolfSSL 0:9d17e4342598 876 case CYASSL_SNI_HOST_NAME:
wolfSSL 0:9d17e4342598 877 *data = sni->data.host_name;
wolfSSL 0:9d17e4342598 878 return XSTRLEN(*data);
wolfSSL 0:9d17e4342598 879 }
wolfSSL 0:9d17e4342598 880 }
wolfSSL 0:9d17e4342598 881
wolfSSL 0:9d17e4342598 882 return 0;
wolfSSL 0:9d17e4342598 883 }
wolfSSL 0:9d17e4342598 884
wolfSSL 0:9d17e4342598 885 void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options)
wolfSSL 0:9d17e4342598 886 {
wolfSSL 0:9d17e4342598 887 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
wolfSSL 0:9d17e4342598 888 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
wolfSSL 0:9d17e4342598 889
wolfSSL 0:9d17e4342598 890 if (sni)
wolfSSL 0:9d17e4342598 891 sni->options = options;
wolfSSL 0:9d17e4342598 892 }
wolfSSL 0:9d17e4342598 893
wolfSSL 0:9d17e4342598 894 int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
wolfSSL 0:9d17e4342598 895 byte type, byte* sni, word32* inOutSz)
wolfSSL 0:9d17e4342598 896 {
wolfSSL 0:9d17e4342598 897 word32 offset = 0;
wolfSSL 0:9d17e4342598 898 word32 len32 = 0;
wolfSSL 0:9d17e4342598 899 word16 len16 = 0;
wolfSSL 0:9d17e4342598 900
wolfSSL 0:9d17e4342598 901 if (helloSz < RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + CLIENT_HELLO_FIRST)
wolfSSL 0:9d17e4342598 902 return INCOMPLETE_DATA;
wolfSSL 0:9d17e4342598 903
wolfSSL 0:9d17e4342598 904 /* TLS record header */
wolfSSL 0:9d17e4342598 905 if ((enum ContentType) clientHello[offset++] != handshake)
wolfSSL 0:9d17e4342598 906 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 907
wolfSSL 0:9d17e4342598 908 if (clientHello[offset++] != SSLv3_MAJOR)
wolfSSL 0:9d17e4342598 909 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 910
wolfSSL 0:9d17e4342598 911 if (clientHello[offset++] < TLSv1_MINOR)
wolfSSL 0:9d17e4342598 912 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 913
wolfSSL 0:9d17e4342598 914 ato16(clientHello + offset, &len16);
wolfSSL 0:9d17e4342598 915 offset += OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 916
wolfSSL 0:9d17e4342598 917 if (offset + len16 > helloSz)
wolfSSL 0:9d17e4342598 918 return INCOMPLETE_DATA;
wolfSSL 0:9d17e4342598 919
wolfSSL 0:9d17e4342598 920 /* Handshake header */
wolfSSL 0:9d17e4342598 921 if ((enum HandShakeType) clientHello[offset] != client_hello)
wolfSSL 0:9d17e4342598 922 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 923
wolfSSL 0:9d17e4342598 924 c24to32(clientHello + offset + 1, &len32);
wolfSSL 0:9d17e4342598 925 offset += HANDSHAKE_HEADER_SZ;
wolfSSL 0:9d17e4342598 926
wolfSSL 0:9d17e4342598 927 if (offset + len32 > helloSz)
wolfSSL 0:9d17e4342598 928 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 929
wolfSSL 0:9d17e4342598 930 /* client hello */
wolfSSL 0:9d17e4342598 931 offset += VERSION_SZ + RAN_LEN; /* version, random */
wolfSSL 0:9d17e4342598 932
wolfSSL 0:9d17e4342598 933 if (helloSz < offset + clientHello[offset])
wolfSSL 0:9d17e4342598 934 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 935
wolfSSL 0:9d17e4342598 936 offset += ENUM_LEN + clientHello[offset]; /* skip session id */
wolfSSL 0:9d17e4342598 937
wolfSSL 0:9d17e4342598 938 /* cypher suites */
wolfSSL 0:9d17e4342598 939 if (helloSz < offset + OPAQUE16_LEN)
wolfSSL 0:9d17e4342598 940 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 941
wolfSSL 0:9d17e4342598 942 ato16(clientHello + offset, &len16);
wolfSSL 0:9d17e4342598 943 offset += OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 944
wolfSSL 0:9d17e4342598 945 if (helloSz < offset + len16)
wolfSSL 0:9d17e4342598 946 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 947
wolfSSL 0:9d17e4342598 948 offset += len16; /* skip cypher suites */
wolfSSL 0:9d17e4342598 949
wolfSSL 0:9d17e4342598 950 /* compression methods */
wolfSSL 0:9d17e4342598 951 if (helloSz < offset + 1)
wolfSSL 0:9d17e4342598 952 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 953
wolfSSL 0:9d17e4342598 954 if (helloSz < offset + clientHello[offset])
wolfSSL 0:9d17e4342598 955 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 956
wolfSSL 0:9d17e4342598 957 offset += ENUM_LEN + clientHello[offset]; /* skip compression methods */
wolfSSL 0:9d17e4342598 958
wolfSSL 0:9d17e4342598 959 /* extensions */
wolfSSL 0:9d17e4342598 960 if (helloSz < offset + OPAQUE16_LEN)
wolfSSL 0:9d17e4342598 961 return 0; /* no extensions in client hello. */
wolfSSL 0:9d17e4342598 962
wolfSSL 0:9d17e4342598 963 ato16(clientHello + offset, &len16);
wolfSSL 0:9d17e4342598 964 offset += OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 965
wolfSSL 0:9d17e4342598 966 if (helloSz < offset + len16)
wolfSSL 0:9d17e4342598 967 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 968
wolfSSL 0:9d17e4342598 969 while (len16 > OPAQUE16_LEN + OPAQUE16_LEN) {
wolfSSL 0:9d17e4342598 970 word16 extType;
wolfSSL 0:9d17e4342598 971 word16 extLen;
wolfSSL 0:9d17e4342598 972
wolfSSL 0:9d17e4342598 973 ato16(clientHello + offset, &extType);
wolfSSL 0:9d17e4342598 974 offset += OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 975
wolfSSL 0:9d17e4342598 976 ato16(clientHello + offset, &extLen);
wolfSSL 0:9d17e4342598 977 offset += OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 978
wolfSSL 0:9d17e4342598 979 if (helloSz < offset + extLen)
wolfSSL 0:9d17e4342598 980 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 981
wolfSSL 0:9d17e4342598 982 if (extType != SERVER_NAME_INDICATION) {
wolfSSL 0:9d17e4342598 983 offset += extLen; /* skip extension */
wolfSSL 0:9d17e4342598 984 } else {
wolfSSL 0:9d17e4342598 985 word16 listLen;
wolfSSL 0:9d17e4342598 986
wolfSSL 0:9d17e4342598 987 ato16(clientHello + offset, &listLen);
wolfSSL 0:9d17e4342598 988 offset += OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 989
wolfSSL 0:9d17e4342598 990 if (helloSz < offset + listLen)
wolfSSL 0:9d17e4342598 991 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 992
wolfSSL 0:9d17e4342598 993 while (listLen > ENUM_LEN + OPAQUE16_LEN) {
wolfSSL 0:9d17e4342598 994 byte sniType = clientHello[offset++];
wolfSSL 0:9d17e4342598 995 word16 sniLen;
wolfSSL 0:9d17e4342598 996
wolfSSL 0:9d17e4342598 997 ato16(clientHello + offset, &sniLen);
wolfSSL 0:9d17e4342598 998 offset += OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 999
wolfSSL 0:9d17e4342598 1000 if (helloSz < offset + sniLen)
wolfSSL 0:9d17e4342598 1001 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 1002
wolfSSL 0:9d17e4342598 1003 if (sniType != type) {
wolfSSL 0:9d17e4342598 1004 offset += sniLen;
wolfSSL 0:9d17e4342598 1005 listLen -= min(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen);
wolfSSL 0:9d17e4342598 1006 continue;
wolfSSL 0:9d17e4342598 1007 }
wolfSSL 0:9d17e4342598 1008
wolfSSL 0:9d17e4342598 1009 *inOutSz = min(sniLen, *inOutSz);
wolfSSL 0:9d17e4342598 1010 XMEMCPY(sni, clientHello + offset, *inOutSz);
wolfSSL 0:9d17e4342598 1011
wolfSSL 0:9d17e4342598 1012 return SSL_SUCCESS;
wolfSSL 0:9d17e4342598 1013 }
wolfSSL 0:9d17e4342598 1014 }
wolfSSL 0:9d17e4342598 1015
wolfSSL 0:9d17e4342598 1016 len16 -= min(2 * OPAQUE16_LEN + extLen, len16);
wolfSSL 0:9d17e4342598 1017 }
wolfSSL 0:9d17e4342598 1018
wolfSSL 0:9d17e4342598 1019 return len16 ? BUFFER_ERROR : SSL_SUCCESS;
wolfSSL 0:9d17e4342598 1020 }
wolfSSL 0:9d17e4342598 1021
wolfSSL 0:9d17e4342598 1022 #endif
wolfSSL 0:9d17e4342598 1023
wolfSSL 0:9d17e4342598 1024 #define SNI_FREE_ALL TLSX_SNI_FreeAll
wolfSSL 0:9d17e4342598 1025 #define SNI_GET_SIZE TLSX_SNI_GetSize
wolfSSL 0:9d17e4342598 1026 #define SNI_WRITE TLSX_SNI_Write
wolfSSL 0:9d17e4342598 1027 #define SNI_PARSE TLSX_SNI_Parse
wolfSSL 0:9d17e4342598 1028
wolfSSL 0:9d17e4342598 1029 #else
wolfSSL 0:9d17e4342598 1030
wolfSSL 0:9d17e4342598 1031 #define SNI_FREE_ALL(list)
wolfSSL 0:9d17e4342598 1032 #define SNI_GET_SIZE(list) 0
wolfSSL 0:9d17e4342598 1033 #define SNI_WRITE(a, b) 0
wolfSSL 0:9d17e4342598 1034 #define SNI_PARSE(a, b, c, d) 0
wolfSSL 0:9d17e4342598 1035
wolfSSL 0:9d17e4342598 1036 #endif /* HAVE_SNI */
wolfSSL 0:9d17e4342598 1037
wolfSSL 0:9d17e4342598 1038 #ifdef HAVE_MAX_FRAGMENT
wolfSSL 0:9d17e4342598 1039
wolfSSL 0:9d17e4342598 1040 static word16 TLSX_MFL_Write(byte* data, byte* output)
wolfSSL 0:9d17e4342598 1041 {
wolfSSL 0:9d17e4342598 1042 output[0] = data[0];
wolfSSL 0:9d17e4342598 1043
wolfSSL 0:9d17e4342598 1044 return ENUM_LEN;
wolfSSL 0:9d17e4342598 1045 }
wolfSSL 0:9d17e4342598 1046
wolfSSL 0:9d17e4342598 1047 static int TLSX_MFL_Parse(CYASSL* ssl, byte* input, word16 length,
wolfSSL 0:9d17e4342598 1048 byte isRequest)
wolfSSL 0:9d17e4342598 1049 {
wolfSSL 0:9d17e4342598 1050 if (length != ENUM_LEN)
wolfSSL 0:9d17e4342598 1051 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 1052
wolfSSL 0:9d17e4342598 1053 switch (*input) {
wolfSSL 0:9d17e4342598 1054 case CYASSL_MFL_2_9 : ssl->max_fragment = 512; break;
wolfSSL 0:9d17e4342598 1055 case CYASSL_MFL_2_10: ssl->max_fragment = 1024; break;
wolfSSL 0:9d17e4342598 1056 case CYASSL_MFL_2_11: ssl->max_fragment = 2048; break;
wolfSSL 0:9d17e4342598 1057 case CYASSL_MFL_2_12: ssl->max_fragment = 4096; break;
wolfSSL 0:9d17e4342598 1058 case CYASSL_MFL_2_13: ssl->max_fragment = 8192; break;
wolfSSL 0:9d17e4342598 1059
wolfSSL 0:9d17e4342598 1060 default:
wolfSSL 0:9d17e4342598 1061 SendAlert(ssl, alert_fatal, illegal_parameter);
wolfSSL 0:9d17e4342598 1062
wolfSSL 0:9d17e4342598 1063 return UNKNOWN_MAX_FRAG_LEN_E;
wolfSSL 0:9d17e4342598 1064 }
wolfSSL 0:9d17e4342598 1065
wolfSSL 0:9d17e4342598 1066 #ifndef NO_CYASSL_SERVER
wolfSSL 0:9d17e4342598 1067 if (isRequest) {
wolfSSL 0:9d17e4342598 1068 int r = TLSX_UseMaxFragment(&ssl->extensions, *input);
wolfSSL 0:9d17e4342598 1069
wolfSSL 0:9d17e4342598 1070 if (r != SSL_SUCCESS) return r; /* throw error */
wolfSSL 0:9d17e4342598 1071
wolfSSL 0:9d17e4342598 1072 TLSX_SetResponse(ssl, MAX_FRAGMENT_LENGTH);
wolfSSL 0:9d17e4342598 1073 }
wolfSSL 0:9d17e4342598 1074 #endif
wolfSSL 0:9d17e4342598 1075
wolfSSL 0:9d17e4342598 1076 return 0;
wolfSSL 0:9d17e4342598 1077 }
wolfSSL 0:9d17e4342598 1078
wolfSSL 0:9d17e4342598 1079 int TLSX_UseMaxFragment(TLSX** extensions, byte mfl)
wolfSSL 0:9d17e4342598 1080 {
wolfSSL 0:9d17e4342598 1081 TLSX* extension = NULL;
wolfSSL 0:9d17e4342598 1082 byte* data = NULL;
wolfSSL 0:9d17e4342598 1083 int ret = 0;
wolfSSL 0:9d17e4342598 1084
wolfSSL 0:9d17e4342598 1085 if (extensions == NULL)
wolfSSL 0:9d17e4342598 1086 return BAD_FUNC_ARG;
wolfSSL 0:9d17e4342598 1087
wolfSSL 0:9d17e4342598 1088 if (mfl < CYASSL_MFL_2_9 || CYASSL_MFL_2_13 < mfl)
wolfSSL 0:9d17e4342598 1089 return BAD_FUNC_ARG;
wolfSSL 0:9d17e4342598 1090
wolfSSL 0:9d17e4342598 1091 if ((data = XMALLOC(ENUM_LEN, 0, DYNAMIC_TYPE_TLSX)) == NULL)
wolfSSL 0:9d17e4342598 1092 return MEMORY_E;
wolfSSL 0:9d17e4342598 1093
wolfSSL 0:9d17e4342598 1094 data[0] = mfl;
wolfSSL 0:9d17e4342598 1095
wolfSSL 0:9d17e4342598 1096 /* push new MFL extension. */
wolfSSL 0:9d17e4342598 1097 if ((ret = TLSX_Append(extensions, MAX_FRAGMENT_LENGTH)) != 0) {
wolfSSL 0:9d17e4342598 1098 XFREE(data, 0, DYNAMIC_TYPE_TLSX);
wolfSSL 0:9d17e4342598 1099 return ret;
wolfSSL 0:9d17e4342598 1100 }
wolfSSL 0:9d17e4342598 1101
wolfSSL 0:9d17e4342598 1102 /* place new mfl to extension data. */
wolfSSL 0:9d17e4342598 1103 extension = *extensions;
wolfSSL 0:9d17e4342598 1104 extension->data = (void*) data;
wolfSSL 0:9d17e4342598 1105
wolfSSL 0:9d17e4342598 1106 /* remove duplicated extensions */
wolfSSL 0:9d17e4342598 1107 do {
wolfSSL 0:9d17e4342598 1108 if (extension->next && extension->next->type == MAX_FRAGMENT_LENGTH) {
wolfSSL 0:9d17e4342598 1109 TLSX *next = extension->next;
wolfSSL 0:9d17e4342598 1110
wolfSSL 0:9d17e4342598 1111 extension->next = next->next;
wolfSSL 0:9d17e4342598 1112 next->next = NULL;
wolfSSL 0:9d17e4342598 1113
wolfSSL 0:9d17e4342598 1114 TLSX_FreeAll(next);
wolfSSL 0:9d17e4342598 1115
wolfSSL 0:9d17e4342598 1116 break;
wolfSSL 0:9d17e4342598 1117 }
wolfSSL 0:9d17e4342598 1118 } while ((extension = extension->next));
wolfSSL 0:9d17e4342598 1119
wolfSSL 0:9d17e4342598 1120 return SSL_SUCCESS;
wolfSSL 0:9d17e4342598 1121 }
wolfSSL 0:9d17e4342598 1122
wolfSSL 0:9d17e4342598 1123
wolfSSL 0:9d17e4342598 1124 #define MFL_FREE_ALL(data) XFREE(data, 0, DYNAMIC_TYPE_TLSX)
wolfSSL 0:9d17e4342598 1125 #define MFL_GET_SIZE(data) ENUM_LEN
wolfSSL 0:9d17e4342598 1126 #define MFL_WRITE TLSX_MFL_Write
wolfSSL 0:9d17e4342598 1127 #define MFL_PARSE TLSX_MFL_Parse
wolfSSL 0:9d17e4342598 1128
wolfSSL 0:9d17e4342598 1129 #else
wolfSSL 0:9d17e4342598 1130
wolfSSL 0:9d17e4342598 1131 #define MFL_FREE_ALL(a)
wolfSSL 0:9d17e4342598 1132 #define MFL_GET_SIZE(a) 0
wolfSSL 0:9d17e4342598 1133 #define MFL_WRITE(a, b) 0
wolfSSL 0:9d17e4342598 1134 #define MFL_PARSE(a, b, c, d) 0
wolfSSL 0:9d17e4342598 1135
wolfSSL 0:9d17e4342598 1136 #endif /* HAVE_MAX_FRAGMENT */
wolfSSL 0:9d17e4342598 1137
wolfSSL 0:9d17e4342598 1138 #ifdef HAVE_TRUNCATED_HMAC
wolfSSL 0:9d17e4342598 1139
wolfSSL 0:9d17e4342598 1140 int TLSX_UseTruncatedHMAC(TLSX** extensions)
wolfSSL 0:9d17e4342598 1141 {
wolfSSL 0:9d17e4342598 1142 int ret = 0;
wolfSSL 0:9d17e4342598 1143
wolfSSL 0:9d17e4342598 1144 if (extensions == NULL)
wolfSSL 0:9d17e4342598 1145 return BAD_FUNC_ARG;
wolfSSL 0:9d17e4342598 1146
wolfSSL 0:9d17e4342598 1147 if (!TLSX_Find(*extensions, TRUNCATED_HMAC))
wolfSSL 0:9d17e4342598 1148 if ((ret = TLSX_Append(extensions, TRUNCATED_HMAC)) != 0)
wolfSSL 0:9d17e4342598 1149 return ret;
wolfSSL 0:9d17e4342598 1150
wolfSSL 0:9d17e4342598 1151 return SSL_SUCCESS;
wolfSSL 0:9d17e4342598 1152 }
wolfSSL 0:9d17e4342598 1153
wolfSSL 0:9d17e4342598 1154 static int TLSX_THM_Parse(CYASSL* ssl, byte* input, word16 length,
wolfSSL 0:9d17e4342598 1155 byte isRequest)
wolfSSL 0:9d17e4342598 1156 {
wolfSSL 0:9d17e4342598 1157 if (length != 0 || input == NULL)
wolfSSL 0:9d17e4342598 1158 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 1159
wolfSSL 0:9d17e4342598 1160 #ifndef NO_CYASSL_SERVER
wolfSSL 0:9d17e4342598 1161 if (isRequest) {
wolfSSL 0:9d17e4342598 1162 int r = TLSX_UseTruncatedHMAC(&ssl->extensions);
wolfSSL 0:9d17e4342598 1163
wolfSSL 0:9d17e4342598 1164 if (r != SSL_SUCCESS) return r; /* throw error */
wolfSSL 0:9d17e4342598 1165
wolfSSL 0:9d17e4342598 1166 TLSX_SetResponse(ssl, TRUNCATED_HMAC);
wolfSSL 0:9d17e4342598 1167 }
wolfSSL 0:9d17e4342598 1168 #endif
wolfSSL 0:9d17e4342598 1169
wolfSSL 0:9d17e4342598 1170 ssl->truncated_hmac = 1;
wolfSSL 0:9d17e4342598 1171
wolfSSL 0:9d17e4342598 1172 return 0;
wolfSSL 0:9d17e4342598 1173 }
wolfSSL 0:9d17e4342598 1174
wolfSSL 0:9d17e4342598 1175 #define THM_PARSE TLSX_THM_Parse
wolfSSL 0:9d17e4342598 1176
wolfSSL 0:9d17e4342598 1177 #else
wolfSSL 0:9d17e4342598 1178
wolfSSL 0:9d17e4342598 1179 #define THM_PARSE(a, b, c, d) 0
wolfSSL 0:9d17e4342598 1180
wolfSSL 0:9d17e4342598 1181 #endif /* HAVE_TRUNCATED_HMAC */
wolfSSL 0:9d17e4342598 1182
wolfSSL 0:9d17e4342598 1183 #ifdef HAVE_SUPPORTED_CURVES
wolfSSL 0:9d17e4342598 1184
wolfSSL 0:9d17e4342598 1185 #ifndef HAVE_ECC
wolfSSL 0:9d17e4342598 1186 #error "Elliptic Curves Extension requires Elliptic Curve Cryptography. \
wolfSSL 0:9d17e4342598 1187 Use --enable-ecc in the configure script or define HAVE_ECC."
wolfSSL 0:9d17e4342598 1188 #endif
wolfSSL 0:9d17e4342598 1189
wolfSSL 0:9d17e4342598 1190 static void TLSX_EllipticCurve_FreeAll(EllipticCurve* list)
wolfSSL 0:9d17e4342598 1191 {
wolfSSL 0:9d17e4342598 1192 EllipticCurve* curve;
wolfSSL 0:9d17e4342598 1193
wolfSSL 0:9d17e4342598 1194 while ((curve = list)) {
wolfSSL 0:9d17e4342598 1195 list = curve->next;
wolfSSL 0:9d17e4342598 1196 XFREE(curve, 0, DYNAMIC_TYPE_TLSX);
wolfSSL 0:9d17e4342598 1197 }
wolfSSL 0:9d17e4342598 1198 }
wolfSSL 0:9d17e4342598 1199
wolfSSL 0:9d17e4342598 1200 static int TLSX_EllipticCurve_Append(EllipticCurve** list, word16 name)
wolfSSL 0:9d17e4342598 1201 {
wolfSSL 0:9d17e4342598 1202 EllipticCurve* curve;
wolfSSL 0:9d17e4342598 1203
wolfSSL 0:9d17e4342598 1204 if (list == NULL)
wolfSSL 0:9d17e4342598 1205 return BAD_FUNC_ARG;
wolfSSL 0:9d17e4342598 1206
wolfSSL 0:9d17e4342598 1207 if ((curve = XMALLOC(sizeof(EllipticCurve), 0, DYNAMIC_TYPE_TLSX)) == NULL)
wolfSSL 0:9d17e4342598 1208 return MEMORY_E;
wolfSSL 0:9d17e4342598 1209
wolfSSL 0:9d17e4342598 1210 curve->name = name;
wolfSSL 0:9d17e4342598 1211 curve->next = *list;
wolfSSL 0:9d17e4342598 1212
wolfSSL 0:9d17e4342598 1213 *list = curve;
wolfSSL 0:9d17e4342598 1214
wolfSSL 0:9d17e4342598 1215 return 0;
wolfSSL 0:9d17e4342598 1216 }
wolfSSL 0:9d17e4342598 1217
wolfSSL 0:9d17e4342598 1218 #ifndef NO_CYASSL_CLIENT
wolfSSL 0:9d17e4342598 1219
wolfSSL 0:9d17e4342598 1220 static void TLSX_EllipticCurve_ValidateRequest(CYASSL* ssl, byte* semaphore)
wolfSSL 0:9d17e4342598 1221 {
wolfSSL 0:9d17e4342598 1222 int i;
wolfSSL 0:9d17e4342598 1223
wolfSSL 0:9d17e4342598 1224 for (i = 0; i < ssl->suites->suiteSz; i+= 2)
wolfSSL 0:9d17e4342598 1225 if (ssl->suites->suites[i] == ECC_BYTE)
wolfSSL 0:9d17e4342598 1226 return;
wolfSSL 0:9d17e4342598 1227
wolfSSL 0:9d17e4342598 1228 /* No elliptic curve suite found */
wolfSSL 0:9d17e4342598 1229 TURN_ON(semaphore, ELLIPTIC_CURVES);
wolfSSL 0:9d17e4342598 1230 }
wolfSSL 0:9d17e4342598 1231
wolfSSL 0:9d17e4342598 1232 static word16 TLSX_EllipticCurve_GetSize(EllipticCurve* list)
wolfSSL 0:9d17e4342598 1233 {
wolfSSL 0:9d17e4342598 1234 EllipticCurve* curve;
wolfSSL 0:9d17e4342598 1235 word16 length = OPAQUE16_LEN; /* list length */
wolfSSL 0:9d17e4342598 1236
wolfSSL 0:9d17e4342598 1237 while ((curve = list)) {
wolfSSL 0:9d17e4342598 1238 list = curve->next;
wolfSSL 0:9d17e4342598 1239 length += OPAQUE16_LEN; /* curve length */
wolfSSL 0:9d17e4342598 1240 }
wolfSSL 0:9d17e4342598 1241
wolfSSL 0:9d17e4342598 1242 return length;
wolfSSL 0:9d17e4342598 1243 }
wolfSSL 0:9d17e4342598 1244
wolfSSL 0:9d17e4342598 1245 static word16 TLSX_EllipticCurve_WriteR(EllipticCurve* curve, byte* output);
wolfSSL 0:9d17e4342598 1246 static word16 TLSX_EllipticCurve_WriteR(EllipticCurve* curve, byte* output)
wolfSSL 0:9d17e4342598 1247 {
wolfSSL 0:9d17e4342598 1248 word16 offset = 0;
wolfSSL 0:9d17e4342598 1249
wolfSSL 0:9d17e4342598 1250 if (!curve)
wolfSSL 0:9d17e4342598 1251 return offset;
wolfSSL 0:9d17e4342598 1252
wolfSSL 0:9d17e4342598 1253 offset = TLSX_EllipticCurve_WriteR(curve->next, output);
wolfSSL 0:9d17e4342598 1254 c16toa(curve->name, output + offset);
wolfSSL 0:9d17e4342598 1255
wolfSSL 0:9d17e4342598 1256 return OPAQUE16_LEN + offset;
wolfSSL 0:9d17e4342598 1257 }
wolfSSL 0:9d17e4342598 1258
wolfSSL 0:9d17e4342598 1259 static word16 TLSX_EllipticCurve_Write(EllipticCurve* list, byte* output)
wolfSSL 0:9d17e4342598 1260 {
wolfSSL 0:9d17e4342598 1261 word16 length = TLSX_EllipticCurve_WriteR(list, output + OPAQUE16_LEN);
wolfSSL 0:9d17e4342598 1262
wolfSSL 0:9d17e4342598 1263 c16toa(length, output); /* writing list length */
wolfSSL 0:9d17e4342598 1264
wolfSSL 0:9d17e4342598 1265 return OPAQUE16_LEN + length;
wolfSSL 0:9d17e4342598 1266 }
wolfSSL 0:9d17e4342598 1267
wolfSSL 0:9d17e4342598 1268 #endif /* NO_CYASSL_CLIENT */
wolfSSL 0:9d17e4342598 1269 #ifndef NO_CYASSL_SERVER
wolfSSL 0:9d17e4342598 1270
wolfSSL 0:9d17e4342598 1271 static int TLSX_EllipticCurve_Parse(CYASSL* ssl, byte* input, word16 length,
wolfSSL 0:9d17e4342598 1272 byte isRequest)
wolfSSL 0:9d17e4342598 1273 {
wolfSSL 0:9d17e4342598 1274 word16 offset;
wolfSSL 0:9d17e4342598 1275 word16 name;
wolfSSL 0:9d17e4342598 1276 int r;
wolfSSL 0:9d17e4342598 1277
wolfSSL 0:9d17e4342598 1278 (void) isRequest; /* shut up compiler! */
wolfSSL 0:9d17e4342598 1279
wolfSSL 0:9d17e4342598 1280 if (OPAQUE16_LEN > length || length % OPAQUE16_LEN)
wolfSSL 0:9d17e4342598 1281 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 1282
wolfSSL 0:9d17e4342598 1283 ato16(input, &offset);
wolfSSL 0:9d17e4342598 1284
wolfSSL 0:9d17e4342598 1285 /* validating curve list length */
wolfSSL 0:9d17e4342598 1286 if (length != OPAQUE16_LEN + offset)
wolfSSL 0:9d17e4342598 1287 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 1288
wolfSSL 0:9d17e4342598 1289 while (offset) {
wolfSSL 0:9d17e4342598 1290 ato16(input + offset, &name);
wolfSSL 0:9d17e4342598 1291 offset -= OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 1292
wolfSSL 0:9d17e4342598 1293 r = TLSX_UseSupportedCurve(&ssl->extensions, name);
wolfSSL 0:9d17e4342598 1294
wolfSSL 0:9d17e4342598 1295 if (r != SSL_SUCCESS) return r; /* throw error */
wolfSSL 0:9d17e4342598 1296 }
wolfSSL 0:9d17e4342598 1297
wolfSSL 0:9d17e4342598 1298 return 0;
wolfSSL 0:9d17e4342598 1299 }
wolfSSL 0:9d17e4342598 1300
wolfSSL 0:9d17e4342598 1301 int TLSX_ValidateEllipticCurves(CYASSL* ssl, byte first, byte second) {
wolfSSL 0:9d17e4342598 1302 TLSX* extension = (first == ECC_BYTE)
wolfSSL 0:9d17e4342598 1303 ? TLSX_Find(ssl->extensions, ELLIPTIC_CURVES)
wolfSSL 0:9d17e4342598 1304 : NULL;
wolfSSL 0:9d17e4342598 1305 EllipticCurve* curve = NULL;
wolfSSL 0:9d17e4342598 1306 word32 oid = 0;
wolfSSL 0:9d17e4342598 1307 word16 octets = 0; /* acording to 'ecc_set_type ecc_sets[];' */
wolfSSL 0:9d17e4342598 1308 int sig = 0; /* valitade signature */
wolfSSL 0:9d17e4342598 1309 int key = 0; /* validate key */
wolfSSL 0:9d17e4342598 1310
wolfSSL 0:9d17e4342598 1311 if (!extension)
wolfSSL 0:9d17e4342598 1312 return 1; /* no suite restriction */
wolfSSL 0:9d17e4342598 1313
wolfSSL 0:9d17e4342598 1314 for (curve = extension->data; curve && !(sig && key); curve = curve->next) {
wolfSSL 0:9d17e4342598 1315
wolfSSL 0:9d17e4342598 1316 switch (curve->name) {
wolfSSL 0:9d17e4342598 1317 case CYASSL_ECC_SECP160R1: oid = ECC_160R1; octets = 20; break;
wolfSSL 0:9d17e4342598 1318 case CYASSL_ECC_SECP192R1: oid = ECC_192R1; octets = 24; break;
wolfSSL 0:9d17e4342598 1319 case CYASSL_ECC_SECP224R1: oid = ECC_224R1; octets = 28; break;
wolfSSL 0:9d17e4342598 1320 case CYASSL_ECC_SECP256R1: oid = ECC_256R1; octets = 32; break;
wolfSSL 0:9d17e4342598 1321 case CYASSL_ECC_SECP384R1: oid = ECC_384R1; octets = 48; break;
wolfSSL 0:9d17e4342598 1322 case CYASSL_ECC_SECP521R1: oid = ECC_521R1; octets = 66; break;
wolfSSL 0:9d17e4342598 1323 default: continue; /* unsupported curve */
wolfSSL 0:9d17e4342598 1324 }
wolfSSL 0:9d17e4342598 1325
wolfSSL 0:9d17e4342598 1326 switch (second) {
wolfSSL 0:9d17e4342598 1327 #ifndef NO_DSA
wolfSSL 0:9d17e4342598 1328 /* ECDHE_ECDSA */
wolfSSL 0:9d17e4342598 1329 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
wolfSSL 0:9d17e4342598 1330 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
wolfSSL 0:9d17e4342598 1331 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
wolfSSL 0:9d17e4342598 1332 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
wolfSSL 0:9d17e4342598 1333 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
wolfSSL 0:9d17e4342598 1334 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
wolfSSL 0:9d17e4342598 1335 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
wolfSSL 0:9d17e4342598 1336 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
wolfSSL 0:9d17e4342598 1337 case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
wolfSSL 0:9d17e4342598 1338 case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
wolfSSL 0:9d17e4342598 1339 sig |= ssl->pkCurveOID == oid;
wolfSSL 0:9d17e4342598 1340 key |= ssl->eccTempKeySz == octets;
wolfSSL 0:9d17e4342598 1341 break;
wolfSSL 0:9d17e4342598 1342
wolfSSL 0:9d17e4342598 1343 /* ECDH_ECDSA */
wolfSSL 0:9d17e4342598 1344 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
wolfSSL 0:9d17e4342598 1345 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
wolfSSL 0:9d17e4342598 1346 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
wolfSSL 0:9d17e4342598 1347 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
wolfSSL 0:9d17e4342598 1348 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
wolfSSL 0:9d17e4342598 1349 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
wolfSSL 0:9d17e4342598 1350 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
wolfSSL 0:9d17e4342598 1351 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
wolfSSL 0:9d17e4342598 1352 sig |= ssl->pkCurveOID == oid;
wolfSSL 0:9d17e4342598 1353 key |= ssl->pkCurveOID == oid;
wolfSSL 0:9d17e4342598 1354 break;
wolfSSL 0:9d17e4342598 1355 #endif
wolfSSL 0:9d17e4342598 1356 #ifndef NO_RSA
wolfSSL 0:9d17e4342598 1357 /* ECDHE_RSA */
wolfSSL 0:9d17e4342598 1358 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
wolfSSL 0:9d17e4342598 1359 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
wolfSSL 0:9d17e4342598 1360 case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
wolfSSL 0:9d17e4342598 1361 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
wolfSSL 0:9d17e4342598 1362 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
wolfSSL 0:9d17e4342598 1363 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
wolfSSL 0:9d17e4342598 1364 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
wolfSSL 0:9d17e4342598 1365 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
wolfSSL 0:9d17e4342598 1366 sig = 1;
wolfSSL 0:9d17e4342598 1367 key |= ssl->eccTempKeySz == octets;
wolfSSL 0:9d17e4342598 1368 break;
wolfSSL 0:9d17e4342598 1369
wolfSSL 0:9d17e4342598 1370 /* ECDH_RSA */
wolfSSL 0:9d17e4342598 1371 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
wolfSSL 0:9d17e4342598 1372 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
wolfSSL 0:9d17e4342598 1373 case TLS_ECDH_RSA_WITH_RC4_128_SHA:
wolfSSL 0:9d17e4342598 1374 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
wolfSSL 0:9d17e4342598 1375 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
wolfSSL 0:9d17e4342598 1376 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
wolfSSL 0:9d17e4342598 1377 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
wolfSSL 0:9d17e4342598 1378 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
wolfSSL 0:9d17e4342598 1379 sig = 1;
wolfSSL 0:9d17e4342598 1380 key |= ssl->pkCurveOID == oid;
wolfSSL 0:9d17e4342598 1381 break;
wolfSSL 0:9d17e4342598 1382 #endif
wolfSSL 0:9d17e4342598 1383 default:
wolfSSL 0:9d17e4342598 1384 sig = 1;
wolfSSL 0:9d17e4342598 1385 key = 1;
wolfSSL 0:9d17e4342598 1386 break;
wolfSSL 0:9d17e4342598 1387 }
wolfSSL 0:9d17e4342598 1388 }
wolfSSL 0:9d17e4342598 1389
wolfSSL 0:9d17e4342598 1390 return sig && key;
wolfSSL 0:9d17e4342598 1391 }
wolfSSL 0:9d17e4342598 1392
wolfSSL 0:9d17e4342598 1393 #endif /* NO_CYASSL_SERVER */
wolfSSL 0:9d17e4342598 1394
wolfSSL 0:9d17e4342598 1395 int TLSX_UseSupportedCurve(TLSX** extensions, word16 name)
wolfSSL 0:9d17e4342598 1396 {
wolfSSL 0:9d17e4342598 1397 TLSX* extension = NULL;
wolfSSL 0:9d17e4342598 1398 EllipticCurve* curve = NULL;
wolfSSL 0:9d17e4342598 1399 int ret = 0;
wolfSSL 0:9d17e4342598 1400
wolfSSL 0:9d17e4342598 1401 if (extensions == NULL)
wolfSSL 0:9d17e4342598 1402 return BAD_FUNC_ARG;
wolfSSL 0:9d17e4342598 1403
wolfSSL 0:9d17e4342598 1404 if ((ret = TLSX_EllipticCurve_Append(&curve, name)) != 0)
wolfSSL 0:9d17e4342598 1405 return ret;
wolfSSL 0:9d17e4342598 1406
wolfSSL 0:9d17e4342598 1407 extension = *extensions;
wolfSSL 0:9d17e4342598 1408
wolfSSL 0:9d17e4342598 1409 /* find EllipticCurve extension if it already exists. */
wolfSSL 0:9d17e4342598 1410 while (extension && extension->type != ELLIPTIC_CURVES)
wolfSSL 0:9d17e4342598 1411 extension = extension->next;
wolfSSL 0:9d17e4342598 1412
wolfSSL 0:9d17e4342598 1413 /* push new EllipticCurve extension if it doesn't exists. */
wolfSSL 0:9d17e4342598 1414 if (!extension) {
wolfSSL 0:9d17e4342598 1415 if ((ret = TLSX_Append(extensions, ELLIPTIC_CURVES)) != 0) {
wolfSSL 0:9d17e4342598 1416 XFREE(curve, 0, DYNAMIC_TYPE_TLSX);
wolfSSL 0:9d17e4342598 1417 return ret;
wolfSSL 0:9d17e4342598 1418 }
wolfSSL 0:9d17e4342598 1419
wolfSSL 0:9d17e4342598 1420 extension = *extensions;
wolfSSL 0:9d17e4342598 1421 }
wolfSSL 0:9d17e4342598 1422
wolfSSL 0:9d17e4342598 1423 /* push new EllipticCurve object to extension data. */
wolfSSL 0:9d17e4342598 1424 curve->next = (EllipticCurve*) extension->data;
wolfSSL 0:9d17e4342598 1425 extension->data = (void*) curve;
wolfSSL 0:9d17e4342598 1426
wolfSSL 0:9d17e4342598 1427 /* look for another curve of the same name to remove (replacement) */
wolfSSL 0:9d17e4342598 1428 do {
wolfSSL 0:9d17e4342598 1429 if (curve->next && curve->next->name == name) {
wolfSSL 0:9d17e4342598 1430 EllipticCurve *next = curve->next;
wolfSSL 0:9d17e4342598 1431
wolfSSL 0:9d17e4342598 1432 curve->next = next->next;
wolfSSL 0:9d17e4342598 1433 XFREE(next, 0, DYNAMIC_TYPE_TLSX);
wolfSSL 0:9d17e4342598 1434
wolfSSL 0:9d17e4342598 1435 break;
wolfSSL 0:9d17e4342598 1436 }
wolfSSL 0:9d17e4342598 1437 } while ((curve = curve->next));
wolfSSL 0:9d17e4342598 1438
wolfSSL 0:9d17e4342598 1439 return SSL_SUCCESS;
wolfSSL 0:9d17e4342598 1440 }
wolfSSL 0:9d17e4342598 1441
wolfSSL 0:9d17e4342598 1442 #define EC_FREE_ALL TLSX_EllipticCurve_FreeAll
wolfSSL 0:9d17e4342598 1443 #define EC_VALIDATE_REQUEST TLSX_EllipticCurve_ValidateRequest
wolfSSL 0:9d17e4342598 1444
wolfSSL 0:9d17e4342598 1445 #ifndef NO_CYASSL_CLIENT
wolfSSL 0:9d17e4342598 1446 #define EC_GET_SIZE TLSX_EllipticCurve_GetSize
wolfSSL 0:9d17e4342598 1447 #define EC_WRITE TLSX_EllipticCurve_Write
wolfSSL 0:9d17e4342598 1448 #else
wolfSSL 0:9d17e4342598 1449 #define EC_GET_SIZE(list) 0
wolfSSL 0:9d17e4342598 1450 #define EC_WRITE(a, b) 0
wolfSSL 0:9d17e4342598 1451 #endif
wolfSSL 0:9d17e4342598 1452
wolfSSL 0:9d17e4342598 1453 #ifndef NO_CYASSL_SERVER
wolfSSL 0:9d17e4342598 1454 #define EC_PARSE TLSX_EllipticCurve_Parse
wolfSSL 0:9d17e4342598 1455 #else
wolfSSL 0:9d17e4342598 1456 #define EC_PARSE(a, b, c, d) 0
wolfSSL 0:9d17e4342598 1457 #endif
wolfSSL 0:9d17e4342598 1458
wolfSSL 0:9d17e4342598 1459 #else
wolfSSL 0:9d17e4342598 1460
wolfSSL 0:9d17e4342598 1461 #define EC_FREE_ALL(list)
wolfSSL 0:9d17e4342598 1462 #define EC_GET_SIZE(list) 0
wolfSSL 0:9d17e4342598 1463 #define EC_WRITE(a, b) 0
wolfSSL 0:9d17e4342598 1464 #define EC_PARSE(a, b, c, d) 0
wolfSSL 0:9d17e4342598 1465 #define EC_VALIDATE_REQUEST(a, b)
wolfSSL 0:9d17e4342598 1466
wolfSSL 0:9d17e4342598 1467 #endif /* HAVE_SUPPORTED_CURVES */
wolfSSL 0:9d17e4342598 1468
wolfSSL 0:9d17e4342598 1469 TLSX* TLSX_Find(TLSX* list, TLSX_Type type)
wolfSSL 0:9d17e4342598 1470 {
wolfSSL 0:9d17e4342598 1471 TLSX* extension = list;
wolfSSL 0:9d17e4342598 1472
wolfSSL 0:9d17e4342598 1473 while (extension && extension->type != type)
wolfSSL 0:9d17e4342598 1474 extension = extension->next;
wolfSSL 0:9d17e4342598 1475
wolfSSL 0:9d17e4342598 1476 return extension;
wolfSSL 0:9d17e4342598 1477 }
wolfSSL 0:9d17e4342598 1478
wolfSSL 0:9d17e4342598 1479 void TLSX_FreeAll(TLSX* list)
wolfSSL 0:9d17e4342598 1480 {
wolfSSL 0:9d17e4342598 1481 TLSX* extension;
wolfSSL 0:9d17e4342598 1482
wolfSSL 0:9d17e4342598 1483 while ((extension = list)) {
wolfSSL 0:9d17e4342598 1484 list = extension->next;
wolfSSL 0:9d17e4342598 1485
wolfSSL 0:9d17e4342598 1486 switch (extension->type) {
wolfSSL 0:9d17e4342598 1487 case SERVER_NAME_INDICATION:
wolfSSL 0:9d17e4342598 1488 SNI_FREE_ALL((SNI *) extension->data);
wolfSSL 0:9d17e4342598 1489 break;
wolfSSL 0:9d17e4342598 1490
wolfSSL 0:9d17e4342598 1491 case MAX_FRAGMENT_LENGTH:
wolfSSL 0:9d17e4342598 1492 MFL_FREE_ALL(extension->data);
wolfSSL 0:9d17e4342598 1493 break;
wolfSSL 0:9d17e4342598 1494
wolfSSL 0:9d17e4342598 1495 case TRUNCATED_HMAC:
wolfSSL 0:9d17e4342598 1496 /* Nothing to do. */
wolfSSL 0:9d17e4342598 1497 break;
wolfSSL 0:9d17e4342598 1498
wolfSSL 0:9d17e4342598 1499 case ELLIPTIC_CURVES:
wolfSSL 0:9d17e4342598 1500 EC_FREE_ALL(extension->data);
wolfSSL 0:9d17e4342598 1501 break;
wolfSSL 0:9d17e4342598 1502 }
wolfSSL 0:9d17e4342598 1503
wolfSSL 0:9d17e4342598 1504 XFREE(extension, 0, DYNAMIC_TYPE_TLSX);
wolfSSL 0:9d17e4342598 1505 }
wolfSSL 0:9d17e4342598 1506 }
wolfSSL 0:9d17e4342598 1507
wolfSSL 0:9d17e4342598 1508 static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest)
wolfSSL 0:9d17e4342598 1509 {
wolfSSL 0:9d17e4342598 1510 TLSX* extension;
wolfSSL 0:9d17e4342598 1511 word16 length = 0;
wolfSSL 0:9d17e4342598 1512
wolfSSL 0:9d17e4342598 1513 while ((extension = list)) {
wolfSSL 0:9d17e4342598 1514 list = extension->next;
wolfSSL 0:9d17e4342598 1515
wolfSSL 0:9d17e4342598 1516 if (!isRequest && !extension->resp)
wolfSSL 0:9d17e4342598 1517 continue; /* skip! */
wolfSSL 0:9d17e4342598 1518
wolfSSL 0:9d17e4342598 1519 if (IS_OFF(semaphore, extension->type)) {
wolfSSL 0:9d17e4342598 1520 /* type + data length */
wolfSSL 0:9d17e4342598 1521 length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 1522
wolfSSL 0:9d17e4342598 1523 switch (extension->type) {
wolfSSL 0:9d17e4342598 1524 case SERVER_NAME_INDICATION:
wolfSSL 0:9d17e4342598 1525 if (isRequest)
wolfSSL 0:9d17e4342598 1526 length += SNI_GET_SIZE((SNI *) extension->data);
wolfSSL 0:9d17e4342598 1527 break;
wolfSSL 0:9d17e4342598 1528 case MAX_FRAGMENT_LENGTH:
wolfSSL 0:9d17e4342598 1529 length += MFL_GET_SIZE(extension->data);
wolfSSL 0:9d17e4342598 1530 break;
wolfSSL 0:9d17e4342598 1531
wolfSSL 0:9d17e4342598 1532 case TRUNCATED_HMAC:
wolfSSL 0:9d17e4342598 1533 /* empty extension. */
wolfSSL 0:9d17e4342598 1534 break;
wolfSSL 0:9d17e4342598 1535
wolfSSL 0:9d17e4342598 1536 case ELLIPTIC_CURVES:
wolfSSL 0:9d17e4342598 1537 length += EC_GET_SIZE((EllipticCurve *) extension->data);
wolfSSL 0:9d17e4342598 1538 break;
wolfSSL 0:9d17e4342598 1539 }
wolfSSL 0:9d17e4342598 1540
wolfSSL 0:9d17e4342598 1541 TURN_ON(semaphore, extension->type);
wolfSSL 0:9d17e4342598 1542 }
wolfSSL 0:9d17e4342598 1543 }
wolfSSL 0:9d17e4342598 1544
wolfSSL 0:9d17e4342598 1545 return length;
wolfSSL 0:9d17e4342598 1546 }
wolfSSL 0:9d17e4342598 1547
wolfSSL 0:9d17e4342598 1548 static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
wolfSSL 0:9d17e4342598 1549 byte isRequest)
wolfSSL 0:9d17e4342598 1550 {
wolfSSL 0:9d17e4342598 1551 TLSX* extension;
wolfSSL 0:9d17e4342598 1552 word16 offset = 0;
wolfSSL 0:9d17e4342598 1553 word16 length_offset = 0;
wolfSSL 0:9d17e4342598 1554
wolfSSL 0:9d17e4342598 1555 while ((extension = list)) {
wolfSSL 0:9d17e4342598 1556 list = extension->next;
wolfSSL 0:9d17e4342598 1557
wolfSSL 0:9d17e4342598 1558 if (!isRequest && !extension->resp)
wolfSSL 0:9d17e4342598 1559 continue; /* skip! */
wolfSSL 0:9d17e4342598 1560
wolfSSL 0:9d17e4342598 1561 if (IS_OFF(semaphore, extension->type)) {
wolfSSL 0:9d17e4342598 1562 /* extension type */
wolfSSL 0:9d17e4342598 1563 c16toa(extension->type, output + offset);
wolfSSL 0:9d17e4342598 1564 offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 1565 length_offset = offset;
wolfSSL 0:9d17e4342598 1566
wolfSSL 0:9d17e4342598 1567 /* extension data should be written internally */
wolfSSL 0:9d17e4342598 1568 switch (extension->type) {
wolfSSL 0:9d17e4342598 1569 case SERVER_NAME_INDICATION:
wolfSSL 0:9d17e4342598 1570 if (isRequest)
wolfSSL 0:9d17e4342598 1571 offset += SNI_WRITE((SNI *) extension->data,
wolfSSL 0:9d17e4342598 1572 output + offset);
wolfSSL 0:9d17e4342598 1573 break;
wolfSSL 0:9d17e4342598 1574
wolfSSL 0:9d17e4342598 1575 case MAX_FRAGMENT_LENGTH:
wolfSSL 0:9d17e4342598 1576 offset += MFL_WRITE((byte *) extension->data,
wolfSSL 0:9d17e4342598 1577 output + offset);
wolfSSL 0:9d17e4342598 1578 break;
wolfSSL 0:9d17e4342598 1579
wolfSSL 0:9d17e4342598 1580 case TRUNCATED_HMAC:
wolfSSL 0:9d17e4342598 1581 /* empty extension. */
wolfSSL 0:9d17e4342598 1582 break;
wolfSSL 0:9d17e4342598 1583
wolfSSL 0:9d17e4342598 1584 case ELLIPTIC_CURVES:
wolfSSL 0:9d17e4342598 1585 offset += EC_WRITE((EllipticCurve *) extension->data,
wolfSSL 0:9d17e4342598 1586 output + offset);
wolfSSL 0:9d17e4342598 1587 break;
wolfSSL 0:9d17e4342598 1588 }
wolfSSL 0:9d17e4342598 1589
wolfSSL 0:9d17e4342598 1590 /* writing extension data length */
wolfSSL 0:9d17e4342598 1591 c16toa(offset - length_offset,
wolfSSL 0:9d17e4342598 1592 output + length_offset - OPAQUE16_LEN);
wolfSSL 0:9d17e4342598 1593
wolfSSL 0:9d17e4342598 1594 TURN_ON(semaphore, extension->type);
wolfSSL 0:9d17e4342598 1595 }
wolfSSL 0:9d17e4342598 1596 }
wolfSSL 0:9d17e4342598 1597
wolfSSL 0:9d17e4342598 1598 return offset;
wolfSSL 0:9d17e4342598 1599 }
wolfSSL 0:9d17e4342598 1600
wolfSSL 0:9d17e4342598 1601 #ifndef NO_CYASSL_CLIENT
wolfSSL 0:9d17e4342598 1602
wolfSSL 0:9d17e4342598 1603 word16 TLSX_GetRequestSize(CYASSL* ssl)
wolfSSL 0:9d17e4342598 1604 {
wolfSSL 0:9d17e4342598 1605 word16 length = 0;
wolfSSL 0:9d17e4342598 1606
wolfSSL 0:9d17e4342598 1607 if (ssl && IsTLS(ssl)) {
wolfSSL 0:9d17e4342598 1608 byte semaphore[16] = {0};
wolfSSL 0:9d17e4342598 1609
wolfSSL 0:9d17e4342598 1610 EC_VALIDATE_REQUEST(ssl, semaphore);
wolfSSL 0:9d17e4342598 1611
wolfSSL 0:9d17e4342598 1612 if (ssl->extensions)
wolfSSL 0:9d17e4342598 1613 length += TLSX_GetSize(ssl->extensions, semaphore, 1);
wolfSSL 0:9d17e4342598 1614
wolfSSL 0:9d17e4342598 1615 if (ssl->ctx && ssl->ctx->extensions)
wolfSSL 0:9d17e4342598 1616 length += TLSX_GetSize(ssl->ctx->extensions, semaphore, 1);
wolfSSL 0:9d17e4342598 1617
wolfSSL 0:9d17e4342598 1618 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
wolfSSL 0:9d17e4342598 1619 length += ssl->suites->hashSigAlgoSz + HELLO_EXT_LEN;
wolfSSL 0:9d17e4342598 1620 }
wolfSSL 0:9d17e4342598 1621
wolfSSL 0:9d17e4342598 1622 if (length)
wolfSSL 0:9d17e4342598 1623 length += OPAQUE16_LEN; /* for total length storage */
wolfSSL 0:9d17e4342598 1624
wolfSSL 0:9d17e4342598 1625 return length;
wolfSSL 0:9d17e4342598 1626 }
wolfSSL 0:9d17e4342598 1627
wolfSSL 0:9d17e4342598 1628 word16 TLSX_WriteRequest(CYASSL* ssl, byte* output)
wolfSSL 0:9d17e4342598 1629 {
wolfSSL 0:9d17e4342598 1630 word16 offset = 0;
wolfSSL 0:9d17e4342598 1631
wolfSSL 0:9d17e4342598 1632 if (ssl && IsTLS(ssl) && output) {
wolfSSL 0:9d17e4342598 1633 byte semaphore[16] = {0};
wolfSSL 0:9d17e4342598 1634
wolfSSL 0:9d17e4342598 1635 offset += OPAQUE16_LEN; /* extensions length */
wolfSSL 0:9d17e4342598 1636
wolfSSL 0:9d17e4342598 1637 EC_VALIDATE_REQUEST(ssl, semaphore);
wolfSSL 0:9d17e4342598 1638
wolfSSL 0:9d17e4342598 1639 if (ssl->extensions)
wolfSSL 0:9d17e4342598 1640 offset += TLSX_Write(ssl->extensions, output + offset,
wolfSSL 0:9d17e4342598 1641 semaphore, 1);
wolfSSL 0:9d17e4342598 1642
wolfSSL 0:9d17e4342598 1643 if (ssl->ctx && ssl->ctx->extensions)
wolfSSL 0:9d17e4342598 1644 offset += TLSX_Write(ssl->ctx->extensions, output + offset,
wolfSSL 0:9d17e4342598 1645 semaphore, 1);
wolfSSL 0:9d17e4342598 1646
wolfSSL 0:9d17e4342598 1647 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
wolfSSL 0:9d17e4342598 1648 {
wolfSSL 0:9d17e4342598 1649 int i;
wolfSSL 0:9d17e4342598 1650 /* extension type */
wolfSSL 0:9d17e4342598 1651 c16toa(HELLO_EXT_SIG_ALGO, output + offset);
wolfSSL 0:9d17e4342598 1652 offset += HELLO_EXT_TYPE_SZ;
wolfSSL 0:9d17e4342598 1653
wolfSSL 0:9d17e4342598 1654 /* extension data length */
wolfSSL 0:9d17e4342598 1655 c16toa(OPAQUE16_LEN + ssl->suites->hashSigAlgoSz, output + offset);
wolfSSL 0:9d17e4342598 1656 offset += OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 1657
wolfSSL 0:9d17e4342598 1658 /* sig algos length */
wolfSSL 0:9d17e4342598 1659 c16toa(ssl->suites->hashSigAlgoSz, output + offset);
wolfSSL 0:9d17e4342598 1660 offset += OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 1661
wolfSSL 0:9d17e4342598 1662 /* sig algos */
wolfSSL 0:9d17e4342598 1663 for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, offset++)
wolfSSL 0:9d17e4342598 1664 output[offset] = ssl->suites->hashSigAlgo[i];
wolfSSL 0:9d17e4342598 1665 }
wolfSSL 0:9d17e4342598 1666
wolfSSL 0:9d17e4342598 1667 if (offset > OPAQUE16_LEN)
wolfSSL 0:9d17e4342598 1668 c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
wolfSSL 0:9d17e4342598 1669 }
wolfSSL 0:9d17e4342598 1670
wolfSSL 0:9d17e4342598 1671 return offset;
wolfSSL 0:9d17e4342598 1672 }
wolfSSL 0:9d17e4342598 1673
wolfSSL 0:9d17e4342598 1674 #endif /* NO_CYASSL_CLIENT */
wolfSSL 0:9d17e4342598 1675
wolfSSL 0:9d17e4342598 1676 #ifndef NO_CYASSL_SERVER
wolfSSL 0:9d17e4342598 1677
wolfSSL 0:9d17e4342598 1678 word16 TLSX_GetResponseSize(CYASSL* ssl)
wolfSSL 0:9d17e4342598 1679 {
wolfSSL 0:9d17e4342598 1680 word16 length = 0;
wolfSSL 0:9d17e4342598 1681 byte semaphore[16] = {0};
wolfSSL 0:9d17e4342598 1682
wolfSSL 0:9d17e4342598 1683 if (ssl && IsTLS(ssl))
wolfSSL 0:9d17e4342598 1684 length += TLSX_GetSize(ssl->extensions, semaphore, 0);
wolfSSL 0:9d17e4342598 1685
wolfSSL 0:9d17e4342598 1686 /* All the response data is set at the ssl object only, so no ctx here. */
wolfSSL 0:9d17e4342598 1687
wolfSSL 0:9d17e4342598 1688 if (length)
wolfSSL 0:9d17e4342598 1689 length += OPAQUE16_LEN; /* for total length storage */
wolfSSL 0:9d17e4342598 1690
wolfSSL 0:9d17e4342598 1691 return length;
wolfSSL 0:9d17e4342598 1692 }
wolfSSL 0:9d17e4342598 1693
wolfSSL 0:9d17e4342598 1694 word16 TLSX_WriteResponse(CYASSL *ssl, byte* output)
wolfSSL 0:9d17e4342598 1695 {
wolfSSL 0:9d17e4342598 1696 word16 offset = 0;
wolfSSL 0:9d17e4342598 1697
wolfSSL 0:9d17e4342598 1698 if (ssl && IsTLS(ssl) && output) {
wolfSSL 0:9d17e4342598 1699 byte semaphore[16] = {0};
wolfSSL 0:9d17e4342598 1700
wolfSSL 0:9d17e4342598 1701 offset += OPAQUE16_LEN; /* extensions length */
wolfSSL 0:9d17e4342598 1702
wolfSSL 0:9d17e4342598 1703 offset += TLSX_Write(ssl->extensions, output + offset, semaphore, 0);
wolfSSL 0:9d17e4342598 1704
wolfSSL 0:9d17e4342598 1705 if (offset > OPAQUE16_LEN)
wolfSSL 0:9d17e4342598 1706 c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
wolfSSL 0:9d17e4342598 1707 }
wolfSSL 0:9d17e4342598 1708
wolfSSL 0:9d17e4342598 1709 return offset;
wolfSSL 0:9d17e4342598 1710 }
wolfSSL 0:9d17e4342598 1711
wolfSSL 0:9d17e4342598 1712 #endif /* NO_CYASSL_SERVER */
wolfSSL 0:9d17e4342598 1713
wolfSSL 0:9d17e4342598 1714 int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
wolfSSL 0:9d17e4342598 1715 Suites *suites)
wolfSSL 0:9d17e4342598 1716 {
wolfSSL 0:9d17e4342598 1717 int ret = 0;
wolfSSL 0:9d17e4342598 1718 word16 offset = 0;
wolfSSL 0:9d17e4342598 1719
wolfSSL 0:9d17e4342598 1720 if (!ssl || !input || !suites)
wolfSSL 0:9d17e4342598 1721 return BAD_FUNC_ARG;
wolfSSL 0:9d17e4342598 1722
wolfSSL 0:9d17e4342598 1723 while (ret == 0 && offset < length) {
wolfSSL 0:9d17e4342598 1724 word16 type;
wolfSSL 0:9d17e4342598 1725 word16 size;
wolfSSL 0:9d17e4342598 1726
wolfSSL 0:9d17e4342598 1727 if (length - offset < HELLO_EXT_TYPE_SZ + OPAQUE16_LEN)
wolfSSL 0:9d17e4342598 1728 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 1729
wolfSSL 0:9d17e4342598 1730 ato16(input + offset, &type);
wolfSSL 0:9d17e4342598 1731 offset += HELLO_EXT_TYPE_SZ;
wolfSSL 0:9d17e4342598 1732
wolfSSL 0:9d17e4342598 1733 ato16(input + offset, &size);
wolfSSL 0:9d17e4342598 1734 offset += OPAQUE16_LEN;
wolfSSL 0:9d17e4342598 1735
wolfSSL 0:9d17e4342598 1736 if (offset + size > length)
wolfSSL 0:9d17e4342598 1737 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 1738
wolfSSL 0:9d17e4342598 1739 switch (type) {
wolfSSL 0:9d17e4342598 1740 case SERVER_NAME_INDICATION:
wolfSSL 0:9d17e4342598 1741 CYASSL_MSG("SNI extension received");
wolfSSL 0:9d17e4342598 1742
wolfSSL 0:9d17e4342598 1743 ret = SNI_PARSE(ssl, input + offset, size, isRequest);
wolfSSL 0:9d17e4342598 1744 break;
wolfSSL 0:9d17e4342598 1745
wolfSSL 0:9d17e4342598 1746 case MAX_FRAGMENT_LENGTH:
wolfSSL 0:9d17e4342598 1747 CYASSL_MSG("Max Fragment Length extension received");
wolfSSL 0:9d17e4342598 1748
wolfSSL 0:9d17e4342598 1749 ret = MFL_PARSE(ssl, input + offset, size, isRequest);
wolfSSL 0:9d17e4342598 1750 break;
wolfSSL 0:9d17e4342598 1751
wolfSSL 0:9d17e4342598 1752 case TRUNCATED_HMAC:
wolfSSL 0:9d17e4342598 1753 CYASSL_MSG("Truncated HMAC extension received");
wolfSSL 0:9d17e4342598 1754
wolfSSL 0:9d17e4342598 1755 ret = THM_PARSE(ssl, input + offset, size, isRequest);
wolfSSL 0:9d17e4342598 1756 break;
wolfSSL 0:9d17e4342598 1757
wolfSSL 0:9d17e4342598 1758 case ELLIPTIC_CURVES:
wolfSSL 0:9d17e4342598 1759 CYASSL_MSG("Elliptic Curves extension received");
wolfSSL 0:9d17e4342598 1760
wolfSSL 0:9d17e4342598 1761 ret = EC_PARSE(ssl, input + offset, size, isRequest);
wolfSSL 0:9d17e4342598 1762 break;
wolfSSL 0:9d17e4342598 1763
wolfSSL 0:9d17e4342598 1764 case HELLO_EXT_SIG_ALGO:
wolfSSL 0:9d17e4342598 1765 if (isRequest) {
wolfSSL 0:9d17e4342598 1766 /* do not mess with offset inside the switch! */
wolfSSL 0:9d17e4342598 1767 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:9d17e4342598 1768 ato16(input + offset, &suites->hashSigAlgoSz);
wolfSSL 0:9d17e4342598 1769
wolfSSL 0:9d17e4342598 1770 if (suites->hashSigAlgoSz > size - OPAQUE16_LEN)
wolfSSL 0:9d17e4342598 1771 return BUFFER_ERROR;
wolfSSL 0:9d17e4342598 1772
wolfSSL 0:9d17e4342598 1773 XMEMCPY(suites->hashSigAlgo,
wolfSSL 0:9d17e4342598 1774 input + offset + OPAQUE16_LEN,
wolfSSL 0:9d17e4342598 1775 min(suites->hashSigAlgoSz,
wolfSSL 0:9d17e4342598 1776 HELLO_EXT_SIGALGO_MAX));
wolfSSL 0:9d17e4342598 1777 }
wolfSSL 0:9d17e4342598 1778 } else {
wolfSSL 0:9d17e4342598 1779 CYASSL_MSG("Servers MUST NOT send SIG ALGO extension.");
wolfSSL 0:9d17e4342598 1780 }
wolfSSL 0:9d17e4342598 1781
wolfSSL 0:9d17e4342598 1782 break;
wolfSSL 0:9d17e4342598 1783 }
wolfSSL 0:9d17e4342598 1784
wolfSSL 0:9d17e4342598 1785 /* offset should be updated here! */
wolfSSL 0:9d17e4342598 1786 offset += size;
wolfSSL 0:9d17e4342598 1787 }
wolfSSL 0:9d17e4342598 1788
wolfSSL 0:9d17e4342598 1789 return ret;
wolfSSL 0:9d17e4342598 1790 }
wolfSSL 0:9d17e4342598 1791
wolfSSL 0:9d17e4342598 1792 /* undefining semaphore macros */
wolfSSL 0:9d17e4342598 1793 #undef IS_OFF
wolfSSL 0:9d17e4342598 1794 #undef TURN_ON
wolfSSL 0:9d17e4342598 1795
wolfSSL 0:9d17e4342598 1796 #elif defined(HAVE_SNI) \
wolfSSL 0:9d17e4342598 1797 || defined(HAVE_MAX_FRAGMENT) \
wolfSSL 0:9d17e4342598 1798 || defined(HAVE_TRUNCATED_HMAC) \
wolfSSL 0:9d17e4342598 1799 || defined(HAVE_SUPPORTED_CURVES)
wolfSSL 0:9d17e4342598 1800
wolfSSL 0:9d17e4342598 1801 #error "Using TLS extensions requires HAVE_TLS_EXTENSIONS to be defined."
wolfSSL 0:9d17e4342598 1802
wolfSSL 0:9d17e4342598 1803 #endif /* HAVE_TLS_EXTENSIONS */
wolfSSL 0:9d17e4342598 1804
wolfSSL 0:9d17e4342598 1805
wolfSSL 0:9d17e4342598 1806 #ifndef NO_CYASSL_CLIENT
wolfSSL 0:9d17e4342598 1807
wolfSSL 0:9d17e4342598 1808 #ifndef NO_OLD_TLS
wolfSSL 0:9d17e4342598 1809
wolfSSL 0:9d17e4342598 1810 CYASSL_METHOD* CyaTLSv1_client_method(void)
wolfSSL 0:9d17e4342598 1811 {
wolfSSL 0:9d17e4342598 1812 CYASSL_METHOD* method =
wolfSSL 0:9d17e4342598 1813 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
wolfSSL 0:9d17e4342598 1814 DYNAMIC_TYPE_METHOD);
wolfSSL 0:9d17e4342598 1815 if (method)
wolfSSL 0:9d17e4342598 1816 InitSSL_Method(method, MakeTLSv1());
wolfSSL 0:9d17e4342598 1817 return method;
wolfSSL 0:9d17e4342598 1818 }
wolfSSL 0:9d17e4342598 1819
wolfSSL 0:9d17e4342598 1820
wolfSSL 0:9d17e4342598 1821 CYASSL_METHOD* CyaTLSv1_1_client_method(void)
wolfSSL 0:9d17e4342598 1822 {
wolfSSL 0:9d17e4342598 1823 CYASSL_METHOD* method =
wolfSSL 0:9d17e4342598 1824 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
wolfSSL 0:9d17e4342598 1825 DYNAMIC_TYPE_METHOD);
wolfSSL 0:9d17e4342598 1826 if (method)
wolfSSL 0:9d17e4342598 1827 InitSSL_Method(method, MakeTLSv1_1());
wolfSSL 0:9d17e4342598 1828 return method;
wolfSSL 0:9d17e4342598 1829 }
wolfSSL 0:9d17e4342598 1830
wolfSSL 0:9d17e4342598 1831 #endif /* !NO_OLD_TLS */
wolfSSL 0:9d17e4342598 1832
wolfSSL 0:9d17e4342598 1833 #ifndef NO_SHA256 /* can't use without SHA256 */
wolfSSL 0:9d17e4342598 1834
wolfSSL 0:9d17e4342598 1835 CYASSL_METHOD* CyaTLSv1_2_client_method(void)
wolfSSL 0:9d17e4342598 1836 {
wolfSSL 0:9d17e4342598 1837 CYASSL_METHOD* method =
wolfSSL 0:9d17e4342598 1838 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
wolfSSL 0:9d17e4342598 1839 DYNAMIC_TYPE_METHOD);
wolfSSL 0:9d17e4342598 1840 if (method)
wolfSSL 0:9d17e4342598 1841 InitSSL_Method(method, MakeTLSv1_2());
wolfSSL 0:9d17e4342598 1842 return method;
wolfSSL 0:9d17e4342598 1843 }
wolfSSL 0:9d17e4342598 1844
wolfSSL 0:9d17e4342598 1845 #endif
wolfSSL 0:9d17e4342598 1846
wolfSSL 0:9d17e4342598 1847
wolfSSL 0:9d17e4342598 1848 CYASSL_METHOD* CyaSSLv23_client_method(void)
wolfSSL 0:9d17e4342598 1849 {
wolfSSL 0:9d17e4342598 1850 CYASSL_METHOD* method =
wolfSSL 0:9d17e4342598 1851 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
wolfSSL 0:9d17e4342598 1852 DYNAMIC_TYPE_METHOD);
wolfSSL 0:9d17e4342598 1853 if (method) {
wolfSSL 0:9d17e4342598 1854 #ifndef NO_SHA256 /* 1.2 requires SHA256 */
wolfSSL 0:9d17e4342598 1855 InitSSL_Method(method, MakeTLSv1_2());
wolfSSL 0:9d17e4342598 1856 #else
wolfSSL 0:9d17e4342598 1857 InitSSL_Method(method, MakeTLSv1_1());
wolfSSL 0:9d17e4342598 1858 #endif
wolfSSL 0:9d17e4342598 1859 #ifndef NO_OLD_TLS
wolfSSL 0:9d17e4342598 1860 method->downgrade = 1;
wolfSSL 0:9d17e4342598 1861 #endif
wolfSSL 0:9d17e4342598 1862 }
wolfSSL 0:9d17e4342598 1863 return method;
wolfSSL 0:9d17e4342598 1864 }
wolfSSL 0:9d17e4342598 1865
wolfSSL 0:9d17e4342598 1866
wolfSSL 0:9d17e4342598 1867 #endif /* NO_CYASSL_CLIENT */
wolfSSL 0:9d17e4342598 1868
wolfSSL 0:9d17e4342598 1869
wolfSSL 0:9d17e4342598 1870
wolfSSL 0:9d17e4342598 1871 #ifndef NO_CYASSL_SERVER
wolfSSL 0:9d17e4342598 1872
wolfSSL 0:9d17e4342598 1873 #ifndef NO_OLD_TLS
wolfSSL 0:9d17e4342598 1874
wolfSSL 0:9d17e4342598 1875 CYASSL_METHOD* CyaTLSv1_server_method(void)
wolfSSL 0:9d17e4342598 1876 {
wolfSSL 0:9d17e4342598 1877 CYASSL_METHOD* method =
wolfSSL 0:9d17e4342598 1878 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
wolfSSL 0:9d17e4342598 1879 DYNAMIC_TYPE_METHOD);
wolfSSL 0:9d17e4342598 1880 if (method) {
wolfSSL 0:9d17e4342598 1881 InitSSL_Method(method, MakeTLSv1());
wolfSSL 0:9d17e4342598 1882 method->side = CYASSL_SERVER_END;
wolfSSL 0:9d17e4342598 1883 }
wolfSSL 0:9d17e4342598 1884 return method;
wolfSSL 0:9d17e4342598 1885 }
wolfSSL 0:9d17e4342598 1886
wolfSSL 0:9d17e4342598 1887
wolfSSL 0:9d17e4342598 1888 CYASSL_METHOD* CyaTLSv1_1_server_method(void)
wolfSSL 0:9d17e4342598 1889 {
wolfSSL 0:9d17e4342598 1890 CYASSL_METHOD* method =
wolfSSL 0:9d17e4342598 1891 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
wolfSSL 0:9d17e4342598 1892 DYNAMIC_TYPE_METHOD);
wolfSSL 0:9d17e4342598 1893 if (method) {
wolfSSL 0:9d17e4342598 1894 InitSSL_Method(method, MakeTLSv1_1());
wolfSSL 0:9d17e4342598 1895 method->side = CYASSL_SERVER_END;
wolfSSL 0:9d17e4342598 1896 }
wolfSSL 0:9d17e4342598 1897 return method;
wolfSSL 0:9d17e4342598 1898 }
wolfSSL 0:9d17e4342598 1899
wolfSSL 0:9d17e4342598 1900 #endif /* !NO_OLD_TLS */
wolfSSL 0:9d17e4342598 1901
wolfSSL 0:9d17e4342598 1902 #ifndef NO_SHA256 /* can't use without SHA256 */
wolfSSL 0:9d17e4342598 1903
wolfSSL 0:9d17e4342598 1904 CYASSL_METHOD* CyaTLSv1_2_server_method(void)
wolfSSL 0:9d17e4342598 1905 {
wolfSSL 0:9d17e4342598 1906 CYASSL_METHOD* method =
wolfSSL 0:9d17e4342598 1907 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
wolfSSL 0:9d17e4342598 1908 DYNAMIC_TYPE_METHOD);
wolfSSL 0:9d17e4342598 1909 if (method) {
wolfSSL 0:9d17e4342598 1910 InitSSL_Method(method, MakeTLSv1_2());
wolfSSL 0:9d17e4342598 1911 method->side = CYASSL_SERVER_END;
wolfSSL 0:9d17e4342598 1912 }
wolfSSL 0:9d17e4342598 1913 return method;
wolfSSL 0:9d17e4342598 1914 }
wolfSSL 0:9d17e4342598 1915
wolfSSL 0:9d17e4342598 1916 #endif
wolfSSL 0:9d17e4342598 1917
wolfSSL 0:9d17e4342598 1918
wolfSSL 0:9d17e4342598 1919 CYASSL_METHOD* CyaSSLv23_server_method(void)
wolfSSL 0:9d17e4342598 1920 {
wolfSSL 0:9d17e4342598 1921 CYASSL_METHOD* method =
wolfSSL 0:9d17e4342598 1922 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
wolfSSL 0:9d17e4342598 1923 DYNAMIC_TYPE_METHOD);
wolfSSL 0:9d17e4342598 1924 if (method) {
wolfSSL 0:9d17e4342598 1925 #ifndef NO_SHA256 /* 1.2 requires SHA256 */
wolfSSL 0:9d17e4342598 1926 InitSSL_Method(method, MakeTLSv1_2());
wolfSSL 0:9d17e4342598 1927 #else
wolfSSL 0:9d17e4342598 1928 InitSSL_Method(method, MakeTLSv1_1());
wolfSSL 0:9d17e4342598 1929 #endif
wolfSSL 0:9d17e4342598 1930 method->side = CYASSL_SERVER_END;
wolfSSL 0:9d17e4342598 1931 #ifndef NO_OLD_TLS
wolfSSL 0:9d17e4342598 1932 method->downgrade = 1;
wolfSSL 0:9d17e4342598 1933 #endif /* !NO_OLD_TLS */
wolfSSL 0:9d17e4342598 1934 }
wolfSSL 0:9d17e4342598 1935 return method;
wolfSSL 0:9d17e4342598 1936 }
wolfSSL 0:9d17e4342598 1937
wolfSSL 0:9d17e4342598 1938
wolfSSL 0:9d17e4342598 1939
wolfSSL 0:9d17e4342598 1940 #endif /* NO_CYASSL_SERVER */
wolfSSL 0:9d17e4342598 1941 #endif /* NO_TLS */
wolfSSL 0:9d17e4342598 1942