fork of cyassl-lib

Dependents:   TLS_cyassl TLS_cyassl

Committer:
feb11
Date:
Mon Sep 16 09:53:35 2013 +0000
Revision:
4:f377303c41be
Parent:
0:714293de3836
changed settings

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:714293de3836 1 /* tls.c
ashleymills 0:714293de3836 2 *
ashleymills 0:714293de3836 3 * Copyright (C) 2006-2013 wolfSSL Inc.
ashleymills 0:714293de3836 4 *
ashleymills 0:714293de3836 5 * This file is part of CyaSSL.
ashleymills 0:714293de3836 6 *
ashleymills 0:714293de3836 7 * CyaSSL is free software; you can redistribute it and/or modify
ashleymills 0:714293de3836 8 * it under the terms of the GNU General Public License as published by
ashleymills 0:714293de3836 9 * the Free Software Foundation; either version 2 of the License, or
ashleymills 0:714293de3836 10 * (at your option) any later version.
ashleymills 0:714293de3836 11 *
ashleymills 0:714293de3836 12 * CyaSSL is distributed in the hope that it will be useful,
ashleymills 0:714293de3836 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ashleymills 0:714293de3836 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ashleymills 0:714293de3836 15 * GNU General Public License for more details.
ashleymills 0:714293de3836 16 *
ashleymills 0:714293de3836 17 * You should have received a copy of the GNU General Public License
ashleymills 0:714293de3836 18 * along with this program; if not, write to the Free Software
ashleymills 0:714293de3836 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
ashleymills 0:714293de3836 20 */
ashleymills 0:714293de3836 21
ashleymills 0:714293de3836 22 #ifdef HAVE_CONFIG_H
ashleymills 0:714293de3836 23 #include <config.h>
ashleymills 0:714293de3836 24 #endif
ashleymills 0:714293de3836 25
ashleymills 0:714293de3836 26 #include <cyassl/ctaocrypt/settings.h>
ashleymills 0:714293de3836 27
ashleymills 0:714293de3836 28 #include <cyassl/ssl.h>
ashleymills 0:714293de3836 29 #include <cyassl/internal.h>
ashleymills 0:714293de3836 30 #include <cyassl/ctaoerror.h>
ashleymills 0:714293de3836 31 #include <cyassl/ctaocrypt/hmac.h>
ashleymills 0:714293de3836 32
ashleymills 0:714293de3836 33
ashleymills 0:714293de3836 34
ashleymills 0:714293de3836 35 #ifndef NO_TLS
ashleymills 0:714293de3836 36
ashleymills 0:714293de3836 37
ashleymills 0:714293de3836 38 #ifndef min
ashleymills 0:714293de3836 39
ashleymills 0:714293de3836 40 static INLINE word32 min(word32 a, word32 b)
ashleymills 0:714293de3836 41 {
ashleymills 0:714293de3836 42 return a > b ? b : a;
ashleymills 0:714293de3836 43 }
ashleymills 0:714293de3836 44
ashleymills 0:714293de3836 45 #endif /* min */
ashleymills 0:714293de3836 46
ashleymills 0:714293de3836 47
ashleymills 0:714293de3836 48 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 49 #define PHASH_MAX_DIGEST_SIZE SHA384_DIGEST_SIZE
ashleymills 0:714293de3836 50 #else
ashleymills 0:714293de3836 51 #define PHASH_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE
ashleymills 0:714293de3836 52 #endif
ashleymills 0:714293de3836 53
ashleymills 0:714293de3836 54 /* compute p_hash for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1 PRF */
ashleymills 0:714293de3836 55 static void p_hash(byte* result, word32 resLen, const byte* secret,
ashleymills 0:714293de3836 56 word32 secLen, const byte* seed, word32 seedLen, int hash)
ashleymills 0:714293de3836 57 {
ashleymills 0:714293de3836 58 word32 len = PHASH_MAX_DIGEST_SIZE;
ashleymills 0:714293de3836 59 word32 times;
ashleymills 0:714293de3836 60 word32 lastLen;
ashleymills 0:714293de3836 61 word32 lastTime;
ashleymills 0:714293de3836 62 word32 i;
ashleymills 0:714293de3836 63 word32 idx = 0;
ashleymills 0:714293de3836 64 byte previous[PHASH_MAX_DIGEST_SIZE]; /* max size */
ashleymills 0:714293de3836 65 byte current[PHASH_MAX_DIGEST_SIZE]; /* max size */
ashleymills 0:714293de3836 66
ashleymills 0:714293de3836 67 Hmac hmac;
ashleymills 0:714293de3836 68
ashleymills 0:714293de3836 69 switch (hash) {
ashleymills 0:714293de3836 70 #ifndef NO_MD5
ashleymills 0:714293de3836 71 case md5_mac:
ashleymills 0:714293de3836 72 {
ashleymills 0:714293de3836 73 len = MD5_DIGEST_SIZE;
ashleymills 0:714293de3836 74 hash = MD5;
ashleymills 0:714293de3836 75 }
ashleymills 0:714293de3836 76 break;
ashleymills 0:714293de3836 77 #endif
ashleymills 0:714293de3836 78 #ifndef NO_SHA256
ashleymills 0:714293de3836 79 case sha256_mac:
ashleymills 0:714293de3836 80 {
ashleymills 0:714293de3836 81 len = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 82 hash = SHA256;
ashleymills 0:714293de3836 83 }
ashleymills 0:714293de3836 84 break;
ashleymills 0:714293de3836 85 #endif
ashleymills 0:714293de3836 86 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 87 case sha384_mac:
ashleymills 0:714293de3836 88 {
ashleymills 0:714293de3836 89 len = SHA384_DIGEST_SIZE;
ashleymills 0:714293de3836 90 hash = SHA384;
ashleymills 0:714293de3836 91 }
ashleymills 0:714293de3836 92 break;
ashleymills 0:714293de3836 93 #endif
ashleymills 0:714293de3836 94 #ifndef NO_SHA
ashleymills 0:714293de3836 95 case sha_mac:
ashleymills 0:714293de3836 96 default:
ashleymills 0:714293de3836 97 {
ashleymills 0:714293de3836 98 len = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 99 hash = SHA;
ashleymills 0:714293de3836 100 }
ashleymills 0:714293de3836 101 break;
ashleymills 0:714293de3836 102 #endif
ashleymills 0:714293de3836 103 }
ashleymills 0:714293de3836 104
ashleymills 0:714293de3836 105 times = resLen / len;
ashleymills 0:714293de3836 106 lastLen = resLen % len;
ashleymills 0:714293de3836 107 if (lastLen) times += 1;
ashleymills 0:714293de3836 108 lastTime = times - 1;
ashleymills 0:714293de3836 109
ashleymills 0:714293de3836 110 HmacSetKey(&hmac, hash, secret, secLen);
ashleymills 0:714293de3836 111 HmacUpdate(&hmac, seed, seedLen); /* A0 = seed */
ashleymills 0:714293de3836 112 HmacFinal(&hmac, previous); /* A1 */
ashleymills 0:714293de3836 113
ashleymills 0:714293de3836 114 for (i = 0; i < times; i++) {
ashleymills 0:714293de3836 115 HmacUpdate(&hmac, previous, len);
ashleymills 0:714293de3836 116 HmacUpdate(&hmac, seed, seedLen);
ashleymills 0:714293de3836 117 HmacFinal(&hmac, current);
ashleymills 0:714293de3836 118
ashleymills 0:714293de3836 119 if ( (i == lastTime) && lastLen)
ashleymills 0:714293de3836 120 XMEMCPY(&result[idx], current, min(lastLen, sizeof(current)));
ashleymills 0:714293de3836 121 else {
ashleymills 0:714293de3836 122 XMEMCPY(&result[idx], current, len);
ashleymills 0:714293de3836 123 idx += len;
ashleymills 0:714293de3836 124 HmacUpdate(&hmac, previous, len);
ashleymills 0:714293de3836 125 HmacFinal(&hmac, previous);
ashleymills 0:714293de3836 126 }
ashleymills 0:714293de3836 127 }
ashleymills 0:714293de3836 128 XMEMSET(previous, 0, sizeof previous);
ashleymills 0:714293de3836 129 XMEMSET(current, 0, sizeof current);
ashleymills 0:714293de3836 130 XMEMSET(&hmac, 0, sizeof hmac);
ashleymills 0:714293de3836 131 }
ashleymills 0:714293de3836 132
ashleymills 0:714293de3836 133
ashleymills 0:714293de3836 134
ashleymills 0:714293de3836 135 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 136
ashleymills 0:714293de3836 137 /* calculate XOR for TLSv1 PRF */
ashleymills 0:714293de3836 138 static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha)
ashleymills 0:714293de3836 139 {
ashleymills 0:714293de3836 140 word32 i;
ashleymills 0:714293de3836 141
ashleymills 0:714293de3836 142 for (i = 0; i < digLen; i++)
ashleymills 0:714293de3836 143 digest[i] = md5[i] ^ sha[i];
ashleymills 0:714293de3836 144 }
ashleymills 0:714293de3836 145
ashleymills 0:714293de3836 146
ashleymills 0:714293de3836 147 /* compute TLSv1 PRF (pseudo random function using HMAC) */
ashleymills 0:714293de3836 148 static void doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen,
ashleymills 0:714293de3836 149 const byte* label, word32 labLen, const byte* seed, word32 seedLen)
ashleymills 0:714293de3836 150 {
ashleymills 0:714293de3836 151 word32 half = (secLen + 1) / 2;
ashleymills 0:714293de3836 152
ashleymills 0:714293de3836 153 byte md5_half[MAX_PRF_HALF]; /* half is real size */
ashleymills 0:714293de3836 154 byte sha_half[MAX_PRF_HALF]; /* half is real size */
ashleymills 0:714293de3836 155 byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */
ashleymills 0:714293de3836 156 byte md5_result[MAX_PRF_DIG]; /* digLen is real size */
ashleymills 0:714293de3836 157 byte sha_result[MAX_PRF_DIG]; /* digLen is real size */
ashleymills 0:714293de3836 158
ashleymills 0:714293de3836 159 if (half > MAX_PRF_HALF)
ashleymills 0:714293de3836 160 return;
ashleymills 0:714293de3836 161 if (labLen + seedLen > MAX_PRF_LABSEED)
ashleymills 0:714293de3836 162 return;
ashleymills 0:714293de3836 163 if (digLen > MAX_PRF_DIG)
ashleymills 0:714293de3836 164 return;
ashleymills 0:714293de3836 165
ashleymills 0:714293de3836 166 XMEMSET(md5_result, 0, digLen);
ashleymills 0:714293de3836 167 XMEMSET(sha_result, 0, digLen);
ashleymills 0:714293de3836 168
ashleymills 0:714293de3836 169 XMEMCPY(md5_half, secret, half);
ashleymills 0:714293de3836 170 XMEMCPY(sha_half, secret + half - secLen % 2, half);
ashleymills 0:714293de3836 171
ashleymills 0:714293de3836 172 XMEMCPY(labelSeed, label, labLen);
ashleymills 0:714293de3836 173 XMEMCPY(labelSeed + labLen, seed, seedLen);
ashleymills 0:714293de3836 174
ashleymills 0:714293de3836 175 p_hash(md5_result, digLen, md5_half, half, labelSeed, labLen + seedLen,
ashleymills 0:714293de3836 176 md5_mac);
ashleymills 0:714293de3836 177 p_hash(sha_result, digLen, sha_half, half, labelSeed, labLen + seedLen,
ashleymills 0:714293de3836 178 sha_mac);
ashleymills 0:714293de3836 179 get_xor(digest, digLen, md5_result, sha_result);
ashleymills 0:714293de3836 180 }
ashleymills 0:714293de3836 181
ashleymills 0:714293de3836 182 #endif
ashleymills 0:714293de3836 183
ashleymills 0:714293de3836 184
ashleymills 0:714293de3836 185 /* Wrapper to call straight thru to p_hash in TSL 1.2 cases to remove stack
ashleymills 0:714293de3836 186 use */
ashleymills 0:714293de3836 187 static void PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen,
ashleymills 0:714293de3836 188 const byte* label, word32 labLen, const byte* seed, word32 seedLen,
ashleymills 0:714293de3836 189 int useAtLeastSha256, int hash_type)
ashleymills 0:714293de3836 190 {
ashleymills 0:714293de3836 191 if (useAtLeastSha256) {
ashleymills 0:714293de3836 192 byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */
ashleymills 0:714293de3836 193
ashleymills 0:714293de3836 194 if (labLen + seedLen > MAX_PRF_LABSEED)
ashleymills 0:714293de3836 195 return;
ashleymills 0:714293de3836 196
ashleymills 0:714293de3836 197 XMEMCPY(labelSeed, label, labLen);
ashleymills 0:714293de3836 198 XMEMCPY(labelSeed + labLen, seed, seedLen);
ashleymills 0:714293de3836 199
ashleymills 0:714293de3836 200 /* If a cipher suite wants an algorithm better than sha256, it
ashleymills 0:714293de3836 201 * should use better. */
ashleymills 0:714293de3836 202 if (hash_type < sha256_mac)
ashleymills 0:714293de3836 203 hash_type = sha256_mac;
ashleymills 0:714293de3836 204 p_hash(digest, digLen, secret, secLen, labelSeed, labLen + seedLen,
ashleymills 0:714293de3836 205 hash_type);
ashleymills 0:714293de3836 206 }
ashleymills 0:714293de3836 207 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 208 else
ashleymills 0:714293de3836 209 doPRF(digest, digLen, secret, secLen, label, labLen, seed, seedLen);
ashleymills 0:714293de3836 210 #endif
ashleymills 0:714293de3836 211 }
ashleymills 0:714293de3836 212
ashleymills 0:714293de3836 213
ashleymills 0:714293de3836 214 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 215 #define HSHASH_SZ SHA384_DIGEST_SIZE
ashleymills 0:714293de3836 216 #else
ashleymills 0:714293de3836 217 #define HSHASH_SZ FINISHED_SZ
ashleymills 0:714293de3836 218 #endif
ashleymills 0:714293de3836 219
ashleymills 0:714293de3836 220
ashleymills 0:714293de3836 221 void BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
ashleymills 0:714293de3836 222 {
ashleymills 0:714293de3836 223 const byte* side;
ashleymills 0:714293de3836 224 byte handshake_hash[HSHASH_SZ];
ashleymills 0:714293de3836 225 word32 hashSz = FINISHED_SZ;
ashleymills 0:714293de3836 226
ashleymills 0:714293de3836 227 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 228 Md5Final(&ssl->hashMd5, handshake_hash);
ashleymills 0:714293de3836 229 ShaFinal(&ssl->hashSha, &handshake_hash[MD5_DIGEST_SIZE]);
ashleymills 0:714293de3836 230 #endif
ashleymills 0:714293de3836 231
ashleymills 0:714293de3836 232 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 233 #ifndef NO_SHA256
ashleymills 0:714293de3836 234 if (ssl->specs.mac_algorithm <= sha256_mac) {
ashleymills 0:714293de3836 235 Sha256Final(&ssl->hashSha256, handshake_hash);
ashleymills 0:714293de3836 236 hashSz = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 237 }
ashleymills 0:714293de3836 238 #endif
ashleymills 0:714293de3836 239 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 240 if (ssl->specs.mac_algorithm == sha384_mac) {
ashleymills 0:714293de3836 241 Sha384Final(&ssl->hashSha384, handshake_hash);
ashleymills 0:714293de3836 242 hashSz = SHA384_DIGEST_SIZE;
ashleymills 0:714293de3836 243 }
ashleymills 0:714293de3836 244 #endif
ashleymills 0:714293de3836 245 }
ashleymills 0:714293de3836 246
ashleymills 0:714293de3836 247 if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0)
ashleymills 0:714293de3836 248 side = tls_client;
ashleymills 0:714293de3836 249 else
ashleymills 0:714293de3836 250 side = tls_server;
ashleymills 0:714293de3836 251
ashleymills 0:714293de3836 252 PRF((byte*)hashes, TLS_FINISHED_SZ, ssl->arrays->masterSecret, SECRET_LEN,
ashleymills 0:714293de3836 253 side, FINISHED_LABEL_SZ, handshake_hash, hashSz, IsAtLeastTLSv1_2(ssl),
ashleymills 0:714293de3836 254 ssl->specs.mac_algorithm);
ashleymills 0:714293de3836 255 }
ashleymills 0:714293de3836 256
ashleymills 0:714293de3836 257
ashleymills 0:714293de3836 258 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 259
ashleymills 0:714293de3836 260 ProtocolVersion MakeTLSv1(void)
ashleymills 0:714293de3836 261 {
ashleymills 0:714293de3836 262 ProtocolVersion pv;
ashleymills 0:714293de3836 263 pv.major = SSLv3_MAJOR;
ashleymills 0:714293de3836 264 pv.minor = TLSv1_MINOR;
ashleymills 0:714293de3836 265
ashleymills 0:714293de3836 266 return pv;
ashleymills 0:714293de3836 267 }
ashleymills 0:714293de3836 268
ashleymills 0:714293de3836 269
ashleymills 0:714293de3836 270 ProtocolVersion MakeTLSv1_1(void)
ashleymills 0:714293de3836 271 {
ashleymills 0:714293de3836 272 ProtocolVersion pv;
ashleymills 0:714293de3836 273 pv.major = SSLv3_MAJOR;
ashleymills 0:714293de3836 274 pv.minor = TLSv1_1_MINOR;
ashleymills 0:714293de3836 275
ashleymills 0:714293de3836 276 return pv;
ashleymills 0:714293de3836 277 }
ashleymills 0:714293de3836 278
ashleymills 0:714293de3836 279 #endif
ashleymills 0:714293de3836 280
ashleymills 0:714293de3836 281
ashleymills 0:714293de3836 282 ProtocolVersion MakeTLSv1_2(void)
ashleymills 0:714293de3836 283 {
ashleymills 0:714293de3836 284 ProtocolVersion pv;
ashleymills 0:714293de3836 285 pv.major = SSLv3_MAJOR;
ashleymills 0:714293de3836 286 pv.minor = TLSv1_2_MINOR;
ashleymills 0:714293de3836 287
ashleymills 0:714293de3836 288 return pv;
ashleymills 0:714293de3836 289 }
ashleymills 0:714293de3836 290
ashleymills 0:714293de3836 291
ashleymills 0:714293de3836 292 static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret";
ashleymills 0:714293de3836 293 static const byte key_label [KEY_LABEL_SZ + 1] = "key expansion";
ashleymills 0:714293de3836 294
ashleymills 0:714293de3836 295
ashleymills 0:714293de3836 296 int DeriveTlsKeys(CYASSL* ssl)
ashleymills 0:714293de3836 297 {
ashleymills 0:714293de3836 298 int length = 2 * ssl->specs.hash_size +
ashleymills 0:714293de3836 299 2 * ssl->specs.key_size +
ashleymills 0:714293de3836 300 2 * ssl->specs.iv_size;
ashleymills 0:714293de3836 301 byte seed[SEED_LEN];
ashleymills 0:714293de3836 302 byte key_data[MAX_PRF_DIG];
ashleymills 0:714293de3836 303
ashleymills 0:714293de3836 304 XMEMCPY(seed, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 305 XMEMCPY(&seed[RAN_LEN], ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 306
ashleymills 0:714293de3836 307 PRF(key_data, length, ssl->arrays->masterSecret, SECRET_LEN, key_label,
ashleymills 0:714293de3836 308 KEY_LABEL_SZ, seed, SEED_LEN, IsAtLeastTLSv1_2(ssl),
ashleymills 0:714293de3836 309 ssl->specs.mac_algorithm);
ashleymills 0:714293de3836 310
ashleymills 0:714293de3836 311 return StoreKeys(ssl, key_data);
ashleymills 0:714293de3836 312 }
ashleymills 0:714293de3836 313
ashleymills 0:714293de3836 314
ashleymills 0:714293de3836 315 int MakeTlsMasterSecret(CYASSL* ssl)
ashleymills 0:714293de3836 316 {
ashleymills 0:714293de3836 317 byte seed[SEED_LEN];
ashleymills 0:714293de3836 318
ashleymills 0:714293de3836 319 XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 320 XMEMCPY(&seed[RAN_LEN], ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 321
ashleymills 0:714293de3836 322 PRF(ssl->arrays->masterSecret, SECRET_LEN,
ashleymills 0:714293de3836 323 ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
ashleymills 0:714293de3836 324 master_label, MASTER_LABEL_SZ,
ashleymills 0:714293de3836 325 seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
ashleymills 0:714293de3836 326
ashleymills 0:714293de3836 327 #ifdef SHOW_SECRETS
ashleymills 0:714293de3836 328 {
ashleymills 0:714293de3836 329 int i;
ashleymills 0:714293de3836 330 printf("master secret: ");
ashleymills 0:714293de3836 331 for (i = 0; i < SECRET_LEN; i++)
ashleymills 0:714293de3836 332 printf("%02x", ssl->arrays->masterSecret[i]);
ashleymills 0:714293de3836 333 printf("\n");
ashleymills 0:714293de3836 334 }
ashleymills 0:714293de3836 335 #endif
ashleymills 0:714293de3836 336
ashleymills 0:714293de3836 337 return DeriveTlsKeys(ssl);
ashleymills 0:714293de3836 338 }
ashleymills 0:714293de3836 339
ashleymills 0:714293de3836 340
ashleymills 0:714293de3836 341 /* Used by EAP-TLS and EAP-TTLS to derive keying material from
ashleymills 0:714293de3836 342 * the master_secret. */
ashleymills 0:714293de3836 343 int CyaSSL_make_eap_keys(CYASSL* ssl, void* msk, unsigned int len,
ashleymills 0:714293de3836 344 const char* label)
ashleymills 0:714293de3836 345 {
ashleymills 0:714293de3836 346 byte seed[SEED_LEN];
ashleymills 0:714293de3836 347
ashleymills 0:714293de3836 348 /*
ashleymills 0:714293de3836 349 * As per RFC-5281, the order of the client and server randoms is reversed
ashleymills 0:714293de3836 350 * from that used by the TLS protocol to derive keys.
ashleymills 0:714293de3836 351 */
ashleymills 0:714293de3836 352 XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 353 XMEMCPY(&seed[RAN_LEN], ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 354
ashleymills 0:714293de3836 355 PRF((byte*)msk, len,
ashleymills 0:714293de3836 356 ssl->arrays->masterSecret, SECRET_LEN,
ashleymills 0:714293de3836 357 (const byte *)label, (word32)strlen(label),
ashleymills 0:714293de3836 358 seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
ashleymills 0:714293de3836 359
ashleymills 0:714293de3836 360 return 0;
ashleymills 0:714293de3836 361 }
ashleymills 0:714293de3836 362
ashleymills 0:714293de3836 363
ashleymills 0:714293de3836 364 /*** next for static INLINE s copied from cyassl_int.c ***/
ashleymills 0:714293de3836 365
ashleymills 0:714293de3836 366 /* convert 16 bit integer to opaque */
ashleymills 0:714293de3836 367 static INLINE void c16toa(word16 u16, byte* c)
ashleymills 0:714293de3836 368 {
ashleymills 0:714293de3836 369 c[0] = (u16 >> 8) & 0xff;
ashleymills 0:714293de3836 370 c[1] = u16 & 0xff;
ashleymills 0:714293de3836 371 }
ashleymills 0:714293de3836 372
ashleymills 0:714293de3836 373 /* convert opaque to 16 bit integer */
ashleymills 0:714293de3836 374 static INLINE void ato16(const byte* c, word16* u16)
ashleymills 0:714293de3836 375 {
ashleymills 0:714293de3836 376 *u16 = (c[0] << 8) | (c[1]);
ashleymills 0:714293de3836 377 }
ashleymills 0:714293de3836 378
ashleymills 0:714293de3836 379
ashleymills 0:714293de3836 380 /* convert 32 bit integer to opaque */
ashleymills 0:714293de3836 381 static INLINE void c32toa(word32 u32, byte* c)
ashleymills 0:714293de3836 382 {
ashleymills 0:714293de3836 383 c[0] = (u32 >> 24) & 0xff;
ashleymills 0:714293de3836 384 c[1] = (u32 >> 16) & 0xff;
ashleymills 0:714293de3836 385 c[2] = (u32 >> 8) & 0xff;
ashleymills 0:714293de3836 386 c[3] = u32 & 0xff;
ashleymills 0:714293de3836 387 }
ashleymills 0:714293de3836 388
ashleymills 0:714293de3836 389
ashleymills 0:714293de3836 390 static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
ashleymills 0:714293de3836 391 {
ashleymills 0:714293de3836 392 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 393 if (ssl->options.dtls) {
ashleymills 0:714293de3836 394 if (verify)
ashleymills 0:714293de3836 395 return ssl->keys.dtls_peer_sequence_number; /* explicit from peer */
ashleymills 0:714293de3836 396 else
ashleymills 0:714293de3836 397 return ssl->keys.dtls_sequence_number - 1; /* already incremented */
ashleymills 0:714293de3836 398 }
ashleymills 0:714293de3836 399 #endif
ashleymills 0:714293de3836 400 if (verify)
ashleymills 0:714293de3836 401 return ssl->keys.peer_sequence_number++;
ashleymills 0:714293de3836 402 else
ashleymills 0:714293de3836 403 return ssl->keys.sequence_number++;
ashleymills 0:714293de3836 404 }
ashleymills 0:714293de3836 405
ashleymills 0:714293de3836 406
ashleymills 0:714293de3836 407 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 408
ashleymills 0:714293de3836 409 static INLINE word32 GetEpoch(CYASSL* ssl, int verify)
ashleymills 0:714293de3836 410 {
ashleymills 0:714293de3836 411 if (verify)
ashleymills 0:714293de3836 412 return ssl->keys.dtls_peer_epoch;
ashleymills 0:714293de3836 413 else
ashleymills 0:714293de3836 414 return ssl->keys.dtls_epoch;
ashleymills 0:714293de3836 415 }
ashleymills 0:714293de3836 416
ashleymills 0:714293de3836 417 #endif /* CYASSL_DTLS */
ashleymills 0:714293de3836 418
ashleymills 0:714293de3836 419
ashleymills 0:714293de3836 420 static INLINE const byte* GetMacSecret(CYASSL* ssl, int verify)
ashleymills 0:714293de3836 421 {
ashleymills 0:714293de3836 422 if ( (ssl->options.side == CLIENT_END && !verify) ||
ashleymills 0:714293de3836 423 (ssl->options.side == SERVER_END && verify) )
ashleymills 0:714293de3836 424 return ssl->keys.client_write_MAC_secret;
ashleymills 0:714293de3836 425 else
ashleymills 0:714293de3836 426 return ssl->keys.server_write_MAC_secret;
ashleymills 0:714293de3836 427 }
ashleymills 0:714293de3836 428
ashleymills 0:714293de3836 429 /*** end copy ***/
ashleymills 0:714293de3836 430
ashleymills 0:714293de3836 431
ashleymills 0:714293de3836 432 /* TLS type HMAC */
ashleymills 0:714293de3836 433 void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
ashleymills 0:714293de3836 434 int content, int verify)
ashleymills 0:714293de3836 435 {
ashleymills 0:714293de3836 436 Hmac hmac;
ashleymills 0:714293de3836 437 byte seq[SEQ_SZ];
ashleymills 0:714293de3836 438 byte length[LENGTH_SZ];
ashleymills 0:714293de3836 439 byte inner[ENUM_LEN + VERSION_SZ + LENGTH_SZ]; /* type + version +len */
ashleymills 0:714293de3836 440 int type;
ashleymills 0:714293de3836 441
ashleymills 0:714293de3836 442 XMEMSET(seq, 0, SEQ_SZ);
ashleymills 0:714293de3836 443 c16toa((word16)sz, length);
ashleymills 0:714293de3836 444 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 445 if (ssl->options.dtls)
ashleymills 0:714293de3836 446 c16toa((word16)GetEpoch(ssl, verify), seq);
ashleymills 0:714293de3836 447 #endif
ashleymills 0:714293de3836 448 c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]);
ashleymills 0:714293de3836 449
ashleymills 0:714293de3836 450 switch (ssl->specs.mac_algorithm) {
ashleymills 0:714293de3836 451 #ifndef NO_MD5
ashleymills 0:714293de3836 452 case md5_mac:
ashleymills 0:714293de3836 453 {
ashleymills 0:714293de3836 454 type = MD5;
ashleymills 0:714293de3836 455 }
ashleymills 0:714293de3836 456 break;
ashleymills 0:714293de3836 457 #endif
ashleymills 0:714293de3836 458 #ifndef NO_SHA256
ashleymills 0:714293de3836 459 case sha256_mac:
ashleymills 0:714293de3836 460 {
ashleymills 0:714293de3836 461 type = SHA256;
ashleymills 0:714293de3836 462 }
ashleymills 0:714293de3836 463 break;
ashleymills 0:714293de3836 464 #endif
ashleymills 0:714293de3836 465 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 466 case sha384_mac:
ashleymills 0:714293de3836 467 {
ashleymills 0:714293de3836 468 type = SHA384;
ashleymills 0:714293de3836 469 }
ashleymills 0:714293de3836 470 break;
ashleymills 0:714293de3836 471 #endif
ashleymills 0:714293de3836 472 #ifndef NO_SHA
ashleymills 0:714293de3836 473 case sha_mac:
ashleymills 0:714293de3836 474 default:
ashleymills 0:714293de3836 475 {
ashleymills 0:714293de3836 476 type = SHA;
ashleymills 0:714293de3836 477 }
ashleymills 0:714293de3836 478 break;
ashleymills 0:714293de3836 479 #endif
ashleymills 0:714293de3836 480 }
ashleymills 0:714293de3836 481 HmacSetKey(&hmac, type, GetMacSecret(ssl, verify), ssl->specs.hash_size);
ashleymills 0:714293de3836 482
ashleymills 0:714293de3836 483 HmacUpdate(&hmac, seq, SEQ_SZ); /* seq_num */
ashleymills 0:714293de3836 484 inner[0] = (byte)content; /* type */
ashleymills 0:714293de3836 485 inner[ENUM_LEN] = ssl->version.major;
ashleymills 0:714293de3836 486 inner[ENUM_LEN + ENUM_LEN] = ssl->version.minor; /* version */
ashleymills 0:714293de3836 487 XMEMCPY(&inner[ENUM_LEN + VERSION_SZ], length, LENGTH_SZ); /* length */
ashleymills 0:714293de3836 488 HmacUpdate(&hmac, inner, sizeof(inner));
ashleymills 0:714293de3836 489 HmacUpdate(&hmac, in, sz); /* content */
ashleymills 0:714293de3836 490 HmacFinal(&hmac, digest);
ashleymills 0:714293de3836 491 }
ashleymills 0:714293de3836 492
ashleymills 0:714293de3836 493 #ifdef HAVE_TLS_EXTENSIONS
ashleymills 0:714293de3836 494
ashleymills 0:714293de3836 495 static int TLSX_Append(TLSX** list, TLSX_Type type)
ashleymills 0:714293de3836 496 {
ashleymills 0:714293de3836 497 TLSX* extension;
ashleymills 0:714293de3836 498
ashleymills 0:714293de3836 499 if (list == NULL) /* won't check type since this function is static */
ashleymills 0:714293de3836 500 return BAD_FUNC_ARG;
ashleymills 0:714293de3836 501
ashleymills 0:714293de3836 502 if ((extension = XMALLOC(sizeof(TLSX), 0, DYNAMIC_TYPE_TLSX)) == NULL)
ashleymills 0:714293de3836 503 return MEMORY_E;
ashleymills 0:714293de3836 504
ashleymills 0:714293de3836 505 extension->type = type;
ashleymills 0:714293de3836 506 extension->data = NULL;
ashleymills 0:714293de3836 507 extension->resp = 0;
ashleymills 0:714293de3836 508 extension->next = *list;
ashleymills 0:714293de3836 509 *list = extension;
ashleymills 0:714293de3836 510
ashleymills 0:714293de3836 511 return 0;
ashleymills 0:714293de3836 512 }
ashleymills 0:714293de3836 513
ashleymills 0:714293de3836 514 #ifndef NO_CYASSL_SERVER
ashleymills 0:714293de3836 515
ashleymills 0:714293de3836 516 static void TLSX_SetResponse(CYASSL* ssl, TLSX_Type type)
ashleymills 0:714293de3836 517 {
ashleymills 0:714293de3836 518 TLSX *ext = TLSX_Find(ssl->extensions, type);
ashleymills 0:714293de3836 519
ashleymills 0:714293de3836 520 if (ext)
ashleymills 0:714293de3836 521 ext->resp = 1;
ashleymills 0:714293de3836 522 }
ashleymills 0:714293de3836 523
ashleymills 0:714293de3836 524 #endif
ashleymills 0:714293de3836 525
ashleymills 0:714293de3836 526 /* SNI - Server Name Indication */
ashleymills 0:714293de3836 527
ashleymills 0:714293de3836 528 #ifdef HAVE_SNI
ashleymills 0:714293de3836 529
ashleymills 0:714293de3836 530 static void TLSX_SNI_Free(SNI* sni)
ashleymills 0:714293de3836 531 {
ashleymills 0:714293de3836 532 if (sni) {
ashleymills 0:714293de3836 533 switch (sni->type) {
ashleymills 0:714293de3836 534 case CYASSL_SNI_HOST_NAME:
ashleymills 0:714293de3836 535 XFREE(sni->data.host_name, 0, DYNAMIC_TYPE_TLSX);
ashleymills 0:714293de3836 536 break;
ashleymills 0:714293de3836 537 }
ashleymills 0:714293de3836 538
ashleymills 0:714293de3836 539 XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
ashleymills 0:714293de3836 540 }
ashleymills 0:714293de3836 541 }
ashleymills 0:714293de3836 542
ashleymills 0:714293de3836 543 static void TLSX_SNI_FreeAll(SNI* list)
ashleymills 0:714293de3836 544 {
ashleymills 0:714293de3836 545 SNI* sni;
ashleymills 0:714293de3836 546
ashleymills 0:714293de3836 547 while ((sni = list)) {
ashleymills 0:714293de3836 548 list = sni->next;
ashleymills 0:714293de3836 549 TLSX_SNI_Free(sni);
ashleymills 0:714293de3836 550 }
ashleymills 0:714293de3836 551 }
ashleymills 0:714293de3836 552
ashleymills 0:714293de3836 553 static int TLSX_SNI_Append(SNI** list, byte type, const void* data, word16 size)
ashleymills 0:714293de3836 554 {
ashleymills 0:714293de3836 555 SNI* sni;
ashleymills 0:714293de3836 556
ashleymills 0:714293de3836 557 if (list == NULL)
ashleymills 0:714293de3836 558 return BAD_FUNC_ARG;
ashleymills 0:714293de3836 559
ashleymills 0:714293de3836 560 if ((sni = XMALLOC(sizeof(SNI), 0, DYNAMIC_TYPE_TLSX)) == NULL)
ashleymills 0:714293de3836 561 return MEMORY_E;
ashleymills 0:714293de3836 562
ashleymills 0:714293de3836 563 switch (type) {
ashleymills 0:714293de3836 564 case CYASSL_SNI_HOST_NAME: {
ashleymills 0:714293de3836 565 sni->data.host_name = XMALLOC(size + 1, 0, DYNAMIC_TYPE_TLSX);
ashleymills 0:714293de3836 566
ashleymills 0:714293de3836 567 if (sni->data.host_name) {
ashleymills 0:714293de3836 568 XSTRNCPY(sni->data.host_name, (const char*) data, size);
ashleymills 0:714293de3836 569 sni->data.host_name[size] = 0;
ashleymills 0:714293de3836 570 } else {
ashleymills 0:714293de3836 571 XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
ashleymills 0:714293de3836 572 return MEMORY_E;
ashleymills 0:714293de3836 573 }
ashleymills 0:714293de3836 574 }
ashleymills 0:714293de3836 575 break;
ashleymills 0:714293de3836 576
ashleymills 0:714293de3836 577 default: /* invalid type */
ashleymills 0:714293de3836 578 XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
ashleymills 0:714293de3836 579 return BAD_FUNC_ARG;
ashleymills 0:714293de3836 580 break;
ashleymills 0:714293de3836 581 }
ashleymills 0:714293de3836 582
ashleymills 0:714293de3836 583 sni->type = type;
ashleymills 0:714293de3836 584 sni->next = *list;
ashleymills 0:714293de3836 585
ashleymills 0:714293de3836 586 #ifndef NO_CYASSL_SERVER
ashleymills 0:714293de3836 587 sni->options = 0;
ashleymills 0:714293de3836 588 sni->matched = 0;
ashleymills 0:714293de3836 589 #endif
ashleymills 0:714293de3836 590
ashleymills 0:714293de3836 591 *list = sni;
ashleymills 0:714293de3836 592
ashleymills 0:714293de3836 593 return 0;
ashleymills 0:714293de3836 594 }
ashleymills 0:714293de3836 595
ashleymills 0:714293de3836 596 static word16 TLSX_SNI_GetSize(SNI* list)
ashleymills 0:714293de3836 597 {
ashleymills 0:714293de3836 598 SNI* sni;
ashleymills 0:714293de3836 599 word16 length = OPAQUE16_LEN; /* list length */
ashleymills 0:714293de3836 600
ashleymills 0:714293de3836 601 while ((sni = list)) {
ashleymills 0:714293de3836 602 list = sni->next;
ashleymills 0:714293de3836 603
ashleymills 0:714293de3836 604 length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */
ashleymills 0:714293de3836 605
ashleymills 0:714293de3836 606 switch (sni->type) {
ashleymills 0:714293de3836 607 case CYASSL_SNI_HOST_NAME:
ashleymills 0:714293de3836 608 length += XSTRLEN((char*) sni->data.host_name);
ashleymills 0:714293de3836 609 break;
ashleymills 0:714293de3836 610 }
ashleymills 0:714293de3836 611 }
ashleymills 0:714293de3836 612
ashleymills 0:714293de3836 613 return length;
ashleymills 0:714293de3836 614 }
ashleymills 0:714293de3836 615
ashleymills 0:714293de3836 616 static word16 TLSX_SNI_Write(SNI* list, byte* output)
ashleymills 0:714293de3836 617 {
ashleymills 0:714293de3836 618 SNI* sni;
ashleymills 0:714293de3836 619 word16 length = 0;
ashleymills 0:714293de3836 620 word16 offset = OPAQUE16_LEN; /* list length offset */
ashleymills 0:714293de3836 621
ashleymills 0:714293de3836 622 while ((sni = list)) {
ashleymills 0:714293de3836 623 list = sni->next;
ashleymills 0:714293de3836 624
ashleymills 0:714293de3836 625 output[offset++] = sni->type; /* sni type */
ashleymills 0:714293de3836 626
ashleymills 0:714293de3836 627 switch (sni->type) {
ashleymills 0:714293de3836 628 case CYASSL_SNI_HOST_NAME:
ashleymills 0:714293de3836 629 length = XSTRLEN((char*) sni->data.host_name);
ashleymills 0:714293de3836 630
ashleymills 0:714293de3836 631 c16toa(length, output + offset); /* sni length */
ashleymills 0:714293de3836 632 offset += OPAQUE16_LEN;
ashleymills 0:714293de3836 633
ashleymills 0:714293de3836 634 XMEMCPY(output + offset, sni->data.host_name, length);
ashleymills 0:714293de3836 635
ashleymills 0:714293de3836 636 offset += length;
ashleymills 0:714293de3836 637 break;
ashleymills 0:714293de3836 638 }
ashleymills 0:714293de3836 639 }
ashleymills 0:714293de3836 640
ashleymills 0:714293de3836 641 c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
ashleymills 0:714293de3836 642
ashleymills 0:714293de3836 643 return offset;
ashleymills 0:714293de3836 644 }
ashleymills 0:714293de3836 645
ashleymills 0:714293de3836 646 static SNI* TLSX_SNI_Find(SNI *list, byte type)
ashleymills 0:714293de3836 647 {
ashleymills 0:714293de3836 648 SNI *sni = list;
ashleymills 0:714293de3836 649
ashleymills 0:714293de3836 650 while (sni && sni->type != type)
ashleymills 0:714293de3836 651 sni = sni->next;
ashleymills 0:714293de3836 652
ashleymills 0:714293de3836 653 return sni;
ashleymills 0:714293de3836 654 }
ashleymills 0:714293de3836 655
ashleymills 0:714293de3836 656 #ifndef NO_CYASSL_SERVER
ashleymills 0:714293de3836 657 static void TLSX_SNI_SetMatched(TLSX* extensions, byte type)
ashleymills 0:714293de3836 658 {
ashleymills 0:714293de3836 659 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
ashleymills 0:714293de3836 660 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
ashleymills 0:714293de3836 661
ashleymills 0:714293de3836 662 if (sni) {
ashleymills 0:714293de3836 663 sni->matched = 1;
ashleymills 0:714293de3836 664 CYASSL_MSG("SNI did match!");
ashleymills 0:714293de3836 665 }
ashleymills 0:714293de3836 666 }
ashleymills 0:714293de3836 667
ashleymills 0:714293de3836 668 byte TLSX_SNI_Matched(TLSX* extensions, byte type)
ashleymills 0:714293de3836 669 {
ashleymills 0:714293de3836 670 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
ashleymills 0:714293de3836 671 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
ashleymills 0:714293de3836 672
ashleymills 0:714293de3836 673 if (sni)
ashleymills 0:714293de3836 674 return sni->matched;
ashleymills 0:714293de3836 675
ashleymills 0:714293de3836 676 return 0;
ashleymills 0:714293de3836 677 }
ashleymills 0:714293de3836 678 #endif
ashleymills 0:714293de3836 679
ashleymills 0:714293de3836 680 static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length,
ashleymills 0:714293de3836 681 byte isRequest)
ashleymills 0:714293de3836 682 {
ashleymills 0:714293de3836 683 #ifndef NO_CYASSL_SERVER
ashleymills 0:714293de3836 684 word16 size = 0;
ashleymills 0:714293de3836 685 word16 offset = 0;
ashleymills 0:714293de3836 686 #endif
ashleymills 0:714293de3836 687
ashleymills 0:714293de3836 688 TLSX *extension = TLSX_Find(ssl->extensions, SERVER_NAME_INDICATION);
ashleymills 0:714293de3836 689
ashleymills 0:714293de3836 690 if (!extension)
ashleymills 0:714293de3836 691 extension = TLSX_Find(ssl->ctx->extensions, SERVER_NAME_INDICATION);
ashleymills 0:714293de3836 692
ashleymills 0:714293de3836 693 if (!extension || !extension->data) {
ashleymills 0:714293de3836 694 if (!isRequest) {
ashleymills 0:714293de3836 695 CYASSL_MSG("Unexpected SNI response from server");
ashleymills 0:714293de3836 696 }
ashleymills 0:714293de3836 697
ashleymills 0:714293de3836 698 return 0; /* not using SNI */
ashleymills 0:714293de3836 699 }
ashleymills 0:714293de3836 700
ashleymills 0:714293de3836 701 if (!isRequest) {
ashleymills 0:714293de3836 702 if (length) {
ashleymills 0:714293de3836 703 CYASSL_MSG("SNI response should be empty!");
ashleymills 0:714293de3836 704 }
ashleymills 0:714293de3836 705
ashleymills 0:714293de3836 706 return 0; /* nothing to do */
ashleymills 0:714293de3836 707 }
ashleymills 0:714293de3836 708
ashleymills 0:714293de3836 709 #ifndef NO_CYASSL_SERVER
ashleymills 0:714293de3836 710
ashleymills 0:714293de3836 711 if (OPAQUE16_LEN > length)
ashleymills 0:714293de3836 712 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 713
ashleymills 0:714293de3836 714 ato16(input, &size);
ashleymills 0:714293de3836 715 offset += OPAQUE16_LEN;
ashleymills 0:714293de3836 716
ashleymills 0:714293de3836 717 /* validating sni list length */
ashleymills 0:714293de3836 718 if (length != OPAQUE16_LEN + size)
ashleymills 0:714293de3836 719 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 720
ashleymills 0:714293de3836 721 for (size = 0; offset < length; offset += size) {
ashleymills 0:714293de3836 722 SNI *sni;
ashleymills 0:714293de3836 723 byte type = input[offset++];
ashleymills 0:714293de3836 724
ashleymills 0:714293de3836 725 if (offset + OPAQUE16_LEN > length)
ashleymills 0:714293de3836 726 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 727
ashleymills 0:714293de3836 728 ato16(input + offset, &size);
ashleymills 0:714293de3836 729 offset += OPAQUE16_LEN;
ashleymills 0:714293de3836 730
ashleymills 0:714293de3836 731 if (offset + size > length)
ashleymills 0:714293de3836 732 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 733
ashleymills 0:714293de3836 734 if (!(sni = TLSX_SNI_Find((SNI *) extension->data, type))) {
ashleymills 0:714293de3836 735 continue; /* not using this SNI type */
ashleymills 0:714293de3836 736 }
ashleymills 0:714293de3836 737
ashleymills 0:714293de3836 738 switch(type) {
ashleymills 0:714293de3836 739 case CYASSL_SNI_HOST_NAME: {
ashleymills 0:714293de3836 740 byte matched = (XSTRLEN(sni->data.host_name) == size)
ashleymills 0:714293de3836 741 && (XSTRNCMP(sni->data.host_name,
ashleymills 0:714293de3836 742 (const char *) input + offset, size) == 0);
ashleymills 0:714293de3836 743
ashleymills 0:714293de3836 744 if (matched || sni->options & CYASSL_SNI_ANSWER_ON_MISMATCH) {
ashleymills 0:714293de3836 745 int r = TLSX_UseSNI(&ssl->extensions, type, (byte *) "", 0);
ashleymills 0:714293de3836 746
ashleymills 0:714293de3836 747 if (r) return r; /* throw error */
ashleymills 0:714293de3836 748
ashleymills 0:714293de3836 749 if (matched) TLSX_SNI_SetMatched(ssl->extensions, type);
ashleymills 0:714293de3836 750 } else if (!(sni->options & CYASSL_SNI_CONTINUE_ON_MISMATCH)) {
ashleymills 0:714293de3836 751 SendAlert(ssl, alert_fatal, unrecognized_name);
ashleymills 0:714293de3836 752
ashleymills 0:714293de3836 753 return UNKNOWN_SNI_HOST_NAME_E;
ashleymills 0:714293de3836 754 }
ashleymills 0:714293de3836 755 break;
ashleymills 0:714293de3836 756 }
ashleymills 0:714293de3836 757 }
ashleymills 0:714293de3836 758
ashleymills 0:714293de3836 759 TLSX_SetResponse(ssl, SERVER_NAME_INDICATION);
ashleymills 0:714293de3836 760 }
ashleymills 0:714293de3836 761
ashleymills 0:714293de3836 762 #endif
ashleymills 0:714293de3836 763
ashleymills 0:714293de3836 764 return 0;
ashleymills 0:714293de3836 765 }
ashleymills 0:714293de3836 766
ashleymills 0:714293de3836 767 int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size)
ashleymills 0:714293de3836 768 {
ashleymills 0:714293de3836 769 TLSX* extension = NULL;
ashleymills 0:714293de3836 770 SNI* sni = NULL;
ashleymills 0:714293de3836 771 int ret = 0;
ashleymills 0:714293de3836 772
ashleymills 0:714293de3836 773 if (extensions == NULL || data == NULL)
ashleymills 0:714293de3836 774 return BAD_FUNC_ARG;
ashleymills 0:714293de3836 775
ashleymills 0:714293de3836 776 if ((ret = TLSX_SNI_Append(&sni, type, data, size)) != 0)
ashleymills 0:714293de3836 777 return ret;
ashleymills 0:714293de3836 778
ashleymills 0:714293de3836 779 extension = *extensions;
ashleymills 0:714293de3836 780
ashleymills 0:714293de3836 781 /* find SNI extension if it already exists. */
ashleymills 0:714293de3836 782 while (extension && extension->type != SERVER_NAME_INDICATION)
ashleymills 0:714293de3836 783 extension = extension->next;
ashleymills 0:714293de3836 784
ashleymills 0:714293de3836 785 /* push new SNI extension if it doesn't exists. */
ashleymills 0:714293de3836 786 if (!extension) {
ashleymills 0:714293de3836 787 if ((ret = TLSX_Append(extensions, SERVER_NAME_INDICATION)) != 0) {
ashleymills 0:714293de3836 788 TLSX_SNI_Free(sni);
ashleymills 0:714293de3836 789 return ret;
ashleymills 0:714293de3836 790 }
ashleymills 0:714293de3836 791
ashleymills 0:714293de3836 792 extension = *extensions;
ashleymills 0:714293de3836 793 }
ashleymills 0:714293de3836 794
ashleymills 0:714293de3836 795 /* push new SNI object to extension data. */
ashleymills 0:714293de3836 796 sni->next = (SNI*) extension->data;
ashleymills 0:714293de3836 797 extension->data = (void*) sni;
ashleymills 0:714293de3836 798
ashleymills 0:714293de3836 799 /* look for another server name of the same type to remove (replacement) */
ashleymills 0:714293de3836 800 while ((sni = sni->next)) {
ashleymills 0:714293de3836 801 if (sni->next && sni->next->type == type) {
ashleymills 0:714293de3836 802 SNI *next = sni->next;
ashleymills 0:714293de3836 803
ashleymills 0:714293de3836 804 sni->next = next->next;
ashleymills 0:714293de3836 805 TLSX_SNI_Free(next);
ashleymills 0:714293de3836 806
ashleymills 0:714293de3836 807 break;
ashleymills 0:714293de3836 808 }
ashleymills 0:714293de3836 809 }
ashleymills 0:714293de3836 810
ashleymills 0:714293de3836 811 return 0;
ashleymills 0:714293de3836 812 }
ashleymills 0:714293de3836 813
ashleymills 0:714293de3836 814 #ifndef NO_CYASSL_SERVER
ashleymills 0:714293de3836 815 void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options)
ashleymills 0:714293de3836 816 {
ashleymills 0:714293de3836 817 TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
ashleymills 0:714293de3836 818 SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
ashleymills 0:714293de3836 819
ashleymills 0:714293de3836 820 if (sni)
ashleymills 0:714293de3836 821 sni->options = options;
ashleymills 0:714293de3836 822 }
ashleymills 0:714293de3836 823 #endif
ashleymills 0:714293de3836 824
ashleymills 0:714293de3836 825 #define SNI_FREE_ALL TLSX_SNI_FreeAll
ashleymills 0:714293de3836 826 #define SNI_GET_SIZE TLSX_SNI_GetSize
ashleymills 0:714293de3836 827 #define SNI_WRITE TLSX_SNI_Write
ashleymills 0:714293de3836 828 #define SNI_PARSE TLSX_SNI_Parse
ashleymills 0:714293de3836 829
ashleymills 0:714293de3836 830 #else
ashleymills 0:714293de3836 831
ashleymills 0:714293de3836 832 #define SNI_FREE_ALL(x)
ashleymills 0:714293de3836 833 #define SNI_GET_SIZE(x) 0
ashleymills 0:714293de3836 834 #define SNI_WRITE(x) 0
ashleymills 0:714293de3836 835 #define SNI_PARSE(x) 0
ashleymills 0:714293de3836 836
ashleymills 0:714293de3836 837 #endif /* HAVE_SNI */
ashleymills 0:714293de3836 838
ashleymills 0:714293de3836 839 TLSX* TLSX_Find(TLSX* list, TLSX_Type type)
ashleymills 0:714293de3836 840 {
ashleymills 0:714293de3836 841 TLSX* extension = list;
ashleymills 0:714293de3836 842
ashleymills 0:714293de3836 843 while (extension && extension->type != type)
ashleymills 0:714293de3836 844 extension = extension->next;
ashleymills 0:714293de3836 845
ashleymills 0:714293de3836 846 return extension;
ashleymills 0:714293de3836 847 }
ashleymills 0:714293de3836 848
ashleymills 0:714293de3836 849 void TLSX_FreeAll(TLSX* list)
ashleymills 0:714293de3836 850 {
ashleymills 0:714293de3836 851 TLSX* extension;
ashleymills 0:714293de3836 852
ashleymills 0:714293de3836 853 while ((extension = list)) {
ashleymills 0:714293de3836 854 list = extension->next;
ashleymills 0:714293de3836 855
ashleymills 0:714293de3836 856 switch (extension->type) {
ashleymills 0:714293de3836 857 case SERVER_NAME_INDICATION:
ashleymills 0:714293de3836 858 SNI_FREE_ALL((SNI *) extension->data);
ashleymills 0:714293de3836 859 break;
ashleymills 0:714293de3836 860 }
ashleymills 0:714293de3836 861
ashleymills 0:714293de3836 862 XFREE(extension, 0, DYNAMIC_TYPE_TLSX);
ashleymills 0:714293de3836 863 }
ashleymills 0:714293de3836 864 }
ashleymills 0:714293de3836 865
ashleymills 0:714293de3836 866 #define IS_OFF(semaphore, light) \
ashleymills 0:714293de3836 867 ((semaphore)[(light) / 8] ^ (byte) (0x01 << ((light) % 8)))
ashleymills 0:714293de3836 868
ashleymills 0:714293de3836 869 #define TURN_ON(semaphore, light) \
ashleymills 0:714293de3836 870 ((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8)))
ashleymills 0:714293de3836 871
ashleymills 0:714293de3836 872 static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest)
ashleymills 0:714293de3836 873 {
ashleymills 0:714293de3836 874 TLSX* extension;
ashleymills 0:714293de3836 875 word16 length = 0;
ashleymills 0:714293de3836 876
ashleymills 0:714293de3836 877 while ((extension = list)) {
ashleymills 0:714293de3836 878 list = extension->next;
ashleymills 0:714293de3836 879
ashleymills 0:714293de3836 880 if (!isRequest && !extension->resp)
ashleymills 0:714293de3836 881 continue; /* skip! */
ashleymills 0:714293de3836 882
ashleymills 0:714293de3836 883 if (IS_OFF(semaphore, extension->type)) {
ashleymills 0:714293de3836 884 /* type + data length */
ashleymills 0:714293de3836 885 length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
ashleymills 0:714293de3836 886
ashleymills 0:714293de3836 887 switch (extension->type) {
ashleymills 0:714293de3836 888 case SERVER_NAME_INDICATION:
ashleymills 0:714293de3836 889 if (isRequest)
ashleymills 0:714293de3836 890 length += SNI_GET_SIZE((SNI *) extension->data);
ashleymills 0:714293de3836 891 break;
ashleymills 0:714293de3836 892 }
ashleymills 0:714293de3836 893
ashleymills 0:714293de3836 894 TURN_ON(semaphore, extension->type);
ashleymills 0:714293de3836 895 }
ashleymills 0:714293de3836 896 }
ashleymills 0:714293de3836 897
ashleymills 0:714293de3836 898 return length;
ashleymills 0:714293de3836 899 }
ashleymills 0:714293de3836 900
ashleymills 0:714293de3836 901 static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
ashleymills 0:714293de3836 902 byte isRequest)
ashleymills 0:714293de3836 903 {
ashleymills 0:714293de3836 904 TLSX* extension;
ashleymills 0:714293de3836 905 word16 offset = 0;
ashleymills 0:714293de3836 906 word16 length_offset = 0;
ashleymills 0:714293de3836 907
ashleymills 0:714293de3836 908 while ((extension = list)) {
ashleymills 0:714293de3836 909 list = extension->next;
ashleymills 0:714293de3836 910
ashleymills 0:714293de3836 911 if (!isRequest && !extension->resp)
ashleymills 0:714293de3836 912 continue; /* skip! */
ashleymills 0:714293de3836 913
ashleymills 0:714293de3836 914 if (IS_OFF(semaphore, extension->type)) {
ashleymills 0:714293de3836 915 /* extension type */
ashleymills 0:714293de3836 916 c16toa(extension->type, output + offset);
ashleymills 0:714293de3836 917 offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
ashleymills 0:714293de3836 918 length_offset = offset;
ashleymills 0:714293de3836 919
ashleymills 0:714293de3836 920 /* extension data should be written internally */
ashleymills 0:714293de3836 921 switch (extension->type) {
ashleymills 0:714293de3836 922 case SERVER_NAME_INDICATION:
ashleymills 0:714293de3836 923 if (isRequest)
ashleymills 0:714293de3836 924 offset += SNI_WRITE((SNI *) extension->data,
ashleymills 0:714293de3836 925 output + offset);
ashleymills 0:714293de3836 926 break;
ashleymills 0:714293de3836 927 }
ashleymills 0:714293de3836 928
ashleymills 0:714293de3836 929 /* writing extension data length */
ashleymills 0:714293de3836 930 c16toa(offset - length_offset,
ashleymills 0:714293de3836 931 output + length_offset - OPAQUE16_LEN);
ashleymills 0:714293de3836 932
ashleymills 0:714293de3836 933 TURN_ON(semaphore, extension->type);
ashleymills 0:714293de3836 934 }
ashleymills 0:714293de3836 935 }
ashleymills 0:714293de3836 936
ashleymills 0:714293de3836 937 return offset;
ashleymills 0:714293de3836 938 }
ashleymills 0:714293de3836 939
ashleymills 0:714293de3836 940 #ifndef NO_CYASSL_CLIENT
ashleymills 0:714293de3836 941
ashleymills 0:714293de3836 942 word16 TLSX_GetRequestSize(CYASSL* ssl)
ashleymills 0:714293de3836 943 {
ashleymills 0:714293de3836 944 word16 length = 0;
ashleymills 0:714293de3836 945
ashleymills 0:714293de3836 946 if (ssl && IsTLS(ssl)) {
ashleymills 0:714293de3836 947 byte semaphore[16] = {0};
ashleymills 0:714293de3836 948
ashleymills 0:714293de3836 949 if (ssl->extensions)
ashleymills 0:714293de3836 950 length += TLSX_GetSize(ssl->extensions, semaphore, 1);
ashleymills 0:714293de3836 951
ashleymills 0:714293de3836 952 if (ssl->ctx && ssl->ctx->extensions)
ashleymills 0:714293de3836 953 length += TLSX_GetSize(ssl->ctx->extensions, semaphore, 1);
ashleymills 0:714293de3836 954
ashleymills 0:714293de3836 955 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
ashleymills 0:714293de3836 956 length += ssl->suites->hashSigAlgoSz + HELLO_EXT_LEN;
ashleymills 0:714293de3836 957 }
ashleymills 0:714293de3836 958
ashleymills 0:714293de3836 959 if (length)
ashleymills 0:714293de3836 960 length += OPAQUE16_LEN; /* for total length storage */
ashleymills 0:714293de3836 961
ashleymills 0:714293de3836 962 return length;
ashleymills 0:714293de3836 963 }
ashleymills 0:714293de3836 964
ashleymills 0:714293de3836 965 word16 TLSX_WriteRequest(CYASSL* ssl, byte* output)
ashleymills 0:714293de3836 966 {
ashleymills 0:714293de3836 967 word16 offset = 0;
ashleymills 0:714293de3836 968
ashleymills 0:714293de3836 969 if (ssl && IsTLS(ssl) && output) {
ashleymills 0:714293de3836 970 byte semaphore[16] = {0};
ashleymills 0:714293de3836 971
ashleymills 0:714293de3836 972 offset += OPAQUE16_LEN; /* extensions length */
ashleymills 0:714293de3836 973
ashleymills 0:714293de3836 974 if (ssl->extensions)
ashleymills 0:714293de3836 975 offset += TLSX_Write(ssl->extensions, output + offset,
ashleymills 0:714293de3836 976 semaphore, 1);
ashleymills 0:714293de3836 977
ashleymills 0:714293de3836 978 if (ssl->ctx && ssl->ctx->extensions)
ashleymills 0:714293de3836 979 offset += TLSX_Write(ssl->ctx->extensions, output + offset,
ashleymills 0:714293de3836 980 semaphore, 1);
ashleymills 0:714293de3836 981
ashleymills 0:714293de3836 982 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
ashleymills 0:714293de3836 983 {
ashleymills 0:714293de3836 984 int i;
ashleymills 0:714293de3836 985 /* extension type */
ashleymills 0:714293de3836 986 c16toa(HELLO_EXT_SIG_ALGO, output + offset);
ashleymills 0:714293de3836 987 offset += HELLO_EXT_TYPE_SZ;
ashleymills 0:714293de3836 988
ashleymills 0:714293de3836 989 /* extension data length */
ashleymills 0:714293de3836 990 c16toa(OPAQUE16_LEN + ssl->suites->hashSigAlgoSz, output + offset);
ashleymills 0:714293de3836 991 offset += OPAQUE16_LEN;
ashleymills 0:714293de3836 992
ashleymills 0:714293de3836 993 /* sig algos length */
ashleymills 0:714293de3836 994 c16toa(ssl->suites->hashSigAlgoSz, output + offset);
ashleymills 0:714293de3836 995 offset += OPAQUE16_LEN;
ashleymills 0:714293de3836 996
ashleymills 0:714293de3836 997 /* sig algos */
ashleymills 0:714293de3836 998 for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, offset++)
ashleymills 0:714293de3836 999 output[offset] = ssl->suites->hashSigAlgo[i];
ashleymills 0:714293de3836 1000 }
ashleymills 0:714293de3836 1001
ashleymills 0:714293de3836 1002 if (offset > OPAQUE16_LEN)
ashleymills 0:714293de3836 1003 c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
ashleymills 0:714293de3836 1004 }
ashleymills 0:714293de3836 1005
ashleymills 0:714293de3836 1006 return offset;
ashleymills 0:714293de3836 1007 }
ashleymills 0:714293de3836 1008
ashleymills 0:714293de3836 1009 #endif /* NO_CYASSL_CLIENT */
ashleymills 0:714293de3836 1010
ashleymills 0:714293de3836 1011 #ifndef NO_CYASSL_SERVER
ashleymills 0:714293de3836 1012
ashleymills 0:714293de3836 1013 word16 TLSX_GetResponseSize(CYASSL* ssl)
ashleymills 0:714293de3836 1014 {
ashleymills 0:714293de3836 1015 word16 length = 0;
ashleymills 0:714293de3836 1016 byte semaphore[16] = {0};
ashleymills 0:714293de3836 1017
ashleymills 0:714293de3836 1018 if (ssl && IsTLS(ssl))
ashleymills 0:714293de3836 1019 length += TLSX_GetSize(ssl->extensions, semaphore, 0);
ashleymills 0:714293de3836 1020
ashleymills 0:714293de3836 1021 /* All the response data is set at the ssl object only, so no ctx here. */
ashleymills 0:714293de3836 1022
ashleymills 0:714293de3836 1023 if (length)
ashleymills 0:714293de3836 1024 length += OPAQUE16_LEN; /* for total length storage */
ashleymills 0:714293de3836 1025
ashleymills 0:714293de3836 1026 return length;
ashleymills 0:714293de3836 1027 }
ashleymills 0:714293de3836 1028
ashleymills 0:714293de3836 1029 word16 TLSX_WriteResponse(CYASSL *ssl, byte* output)
ashleymills 0:714293de3836 1030 {
ashleymills 0:714293de3836 1031 word16 offset = 0;
ashleymills 0:714293de3836 1032
ashleymills 0:714293de3836 1033 if (ssl && IsTLS(ssl) && output) {
ashleymills 0:714293de3836 1034 byte semaphore[16] = {0};
ashleymills 0:714293de3836 1035
ashleymills 0:714293de3836 1036 offset += OPAQUE16_LEN; /* extensions length */
ashleymills 0:714293de3836 1037
ashleymills 0:714293de3836 1038 offset += TLSX_Write(ssl->extensions, output + offset, semaphore, 0);
ashleymills 0:714293de3836 1039
ashleymills 0:714293de3836 1040 if (offset > OPAQUE16_LEN)
ashleymills 0:714293de3836 1041 c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
ashleymills 0:714293de3836 1042 }
ashleymills 0:714293de3836 1043
ashleymills 0:714293de3836 1044 return offset;
ashleymills 0:714293de3836 1045 }
ashleymills 0:714293de3836 1046
ashleymills 0:714293de3836 1047 #endif /* NO_CYASSL_SERVER */
ashleymills 0:714293de3836 1048
ashleymills 0:714293de3836 1049 int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
ashleymills 0:714293de3836 1050 Suites *suites)
ashleymills 0:714293de3836 1051 {
ashleymills 0:714293de3836 1052 int ret = 0;
ashleymills 0:714293de3836 1053 word16 offset = 0;
ashleymills 0:714293de3836 1054
ashleymills 0:714293de3836 1055 if (!ssl || !input || !suites)
ashleymills 0:714293de3836 1056 return BAD_FUNC_ARG;
ashleymills 0:714293de3836 1057
ashleymills 0:714293de3836 1058 while (ret == 0 && offset < length) {
ashleymills 0:714293de3836 1059 word16 type;
ashleymills 0:714293de3836 1060 word16 size;
ashleymills 0:714293de3836 1061
ashleymills 0:714293de3836 1062 if (length - offset < HELLO_EXT_TYPE_SZ + OPAQUE16_LEN)
ashleymills 0:714293de3836 1063 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 1064
ashleymills 0:714293de3836 1065 ato16(input + offset, &type);
ashleymills 0:714293de3836 1066 offset += HELLO_EXT_TYPE_SZ;
ashleymills 0:714293de3836 1067
ashleymills 0:714293de3836 1068 ato16(input + offset, &size);
ashleymills 0:714293de3836 1069 offset += OPAQUE16_LEN;
ashleymills 0:714293de3836 1070
ashleymills 0:714293de3836 1071 if (offset + size > length)
ashleymills 0:714293de3836 1072 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 1073
ashleymills 0:714293de3836 1074 switch (type) {
ashleymills 0:714293de3836 1075 case SERVER_NAME_INDICATION:
ashleymills 0:714293de3836 1076 CYASSL_MSG("SNI extension received");
ashleymills 0:714293de3836 1077
ashleymills 0:714293de3836 1078 ret = SNI_PARSE(ssl, input + offset, size, isRequest);
ashleymills 0:714293de3836 1079 break;
ashleymills 0:714293de3836 1080
ashleymills 0:714293de3836 1081 case HELLO_EXT_SIG_ALGO:
ashleymills 0:714293de3836 1082 if (isRequest) {
ashleymills 0:714293de3836 1083 /* do not mess with offset inside the switch! */
ashleymills 0:714293de3836 1084 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 1085 ato16(input + offset, &suites->hashSigAlgoSz);
ashleymills 0:714293de3836 1086
ashleymills 0:714293de3836 1087 if (suites->hashSigAlgoSz > size - OPAQUE16_LEN)
ashleymills 0:714293de3836 1088 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 1089
ashleymills 0:714293de3836 1090 XMEMCPY(suites->hashSigAlgo,
ashleymills 0:714293de3836 1091 input + offset + OPAQUE16_LEN,
ashleymills 0:714293de3836 1092 min(suites->hashSigAlgoSz,
ashleymills 0:714293de3836 1093 HELLO_EXT_SIGALGO_MAX));
ashleymills 0:714293de3836 1094 }
ashleymills 0:714293de3836 1095 } else {
ashleymills 0:714293de3836 1096 CYASSL_MSG("Servers MUST NOT send SIG ALGO extension.");
ashleymills 0:714293de3836 1097 }
ashleymills 0:714293de3836 1098
ashleymills 0:714293de3836 1099 break;
ashleymills 0:714293de3836 1100 }
ashleymills 0:714293de3836 1101
ashleymills 0:714293de3836 1102 /* offset should be updated here! */
ashleymills 0:714293de3836 1103 offset += size;
ashleymills 0:714293de3836 1104 }
ashleymills 0:714293de3836 1105
ashleymills 0:714293de3836 1106 return ret;
ashleymills 0:714293de3836 1107 }
ashleymills 0:714293de3836 1108
ashleymills 0:714293de3836 1109 /* undefining semaphore macros */
ashleymills 0:714293de3836 1110 #undef IS_OFF
ashleymills 0:714293de3836 1111 #undef TURN_ON
ashleymills 0:714293de3836 1112
ashleymills 0:714293de3836 1113 #endif /* HAVE_TLS_EXTENSIONS */
ashleymills 0:714293de3836 1114
ashleymills 0:714293de3836 1115
ashleymills 0:714293de3836 1116 #ifndef NO_CYASSL_CLIENT
ashleymills 0:714293de3836 1117
ashleymills 0:714293de3836 1118 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 1119
ashleymills 0:714293de3836 1120 CYASSL_METHOD* CyaTLSv1_client_method(void)
ashleymills 0:714293de3836 1121 {
ashleymills 0:714293de3836 1122 CYASSL_METHOD* method =
ashleymills 0:714293de3836 1123 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:714293de3836 1124 DYNAMIC_TYPE_METHOD);
ashleymills 0:714293de3836 1125 if (method)
ashleymills 0:714293de3836 1126 InitSSL_Method(method, MakeTLSv1());
ashleymills 0:714293de3836 1127 return method;
ashleymills 0:714293de3836 1128 }
ashleymills 0:714293de3836 1129
ashleymills 0:714293de3836 1130
ashleymills 0:714293de3836 1131 CYASSL_METHOD* CyaTLSv1_1_client_method(void)
ashleymills 0:714293de3836 1132 {
ashleymills 0:714293de3836 1133 CYASSL_METHOD* method =
ashleymills 0:714293de3836 1134 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:714293de3836 1135 DYNAMIC_TYPE_METHOD);
ashleymills 0:714293de3836 1136 if (method)
ashleymills 0:714293de3836 1137 InitSSL_Method(method, MakeTLSv1_1());
ashleymills 0:714293de3836 1138 return method;
ashleymills 0:714293de3836 1139 }
ashleymills 0:714293de3836 1140
ashleymills 0:714293de3836 1141 #endif /* !NO_OLD_TLS */
ashleymills 0:714293de3836 1142
ashleymills 0:714293de3836 1143 #ifndef NO_SHA256 /* can't use without SHA256 */
ashleymills 0:714293de3836 1144
ashleymills 0:714293de3836 1145 CYASSL_METHOD* CyaTLSv1_2_client_method(void)
ashleymills 0:714293de3836 1146 {
ashleymills 0:714293de3836 1147 CYASSL_METHOD* method =
ashleymills 0:714293de3836 1148 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:714293de3836 1149 DYNAMIC_TYPE_METHOD);
ashleymills 0:714293de3836 1150 if (method)
ashleymills 0:714293de3836 1151 InitSSL_Method(method, MakeTLSv1_2());
ashleymills 0:714293de3836 1152 return method;
ashleymills 0:714293de3836 1153 }
ashleymills 0:714293de3836 1154
ashleymills 0:714293de3836 1155 #endif
ashleymills 0:714293de3836 1156
ashleymills 0:714293de3836 1157
ashleymills 0:714293de3836 1158 CYASSL_METHOD* CyaSSLv23_client_method(void)
ashleymills 0:714293de3836 1159 {
ashleymills 0:714293de3836 1160 CYASSL_METHOD* method =
ashleymills 0:714293de3836 1161 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:714293de3836 1162 DYNAMIC_TYPE_METHOD);
ashleymills 0:714293de3836 1163 if (method) {
ashleymills 0:714293de3836 1164 #ifndef NO_SHA256 /* 1.2 requires SHA256 */
ashleymills 0:714293de3836 1165 InitSSL_Method(method, MakeTLSv1_2());
ashleymills 0:714293de3836 1166 #else
ashleymills 0:714293de3836 1167 InitSSL_Method(method, MakeTLSv1_1());
ashleymills 0:714293de3836 1168 #endif
ashleymills 0:714293de3836 1169 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 1170 method->downgrade = 1;
ashleymills 0:714293de3836 1171 #endif
ashleymills 0:714293de3836 1172 }
ashleymills 0:714293de3836 1173 return method;
ashleymills 0:714293de3836 1174 }
ashleymills 0:714293de3836 1175
ashleymills 0:714293de3836 1176
ashleymills 0:714293de3836 1177 #endif /* NO_CYASSL_CLIENT */
ashleymills 0:714293de3836 1178
ashleymills 0:714293de3836 1179
ashleymills 0:714293de3836 1180
ashleymills 0:714293de3836 1181 #ifndef NO_CYASSL_SERVER
ashleymills 0:714293de3836 1182
ashleymills 0:714293de3836 1183 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 1184
ashleymills 0:714293de3836 1185 CYASSL_METHOD* CyaTLSv1_server_method(void)
ashleymills 0:714293de3836 1186 {
ashleymills 0:714293de3836 1187 CYASSL_METHOD* method =
ashleymills 0:714293de3836 1188 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:714293de3836 1189 DYNAMIC_TYPE_METHOD);
ashleymills 0:714293de3836 1190 if (method) {
ashleymills 0:714293de3836 1191 InitSSL_Method(method, MakeTLSv1());
ashleymills 0:714293de3836 1192 method->side = SERVER_END;
ashleymills 0:714293de3836 1193 }
ashleymills 0:714293de3836 1194 return method;
ashleymills 0:714293de3836 1195 }
ashleymills 0:714293de3836 1196
ashleymills 0:714293de3836 1197
ashleymills 0:714293de3836 1198 CYASSL_METHOD* CyaTLSv1_1_server_method(void)
ashleymills 0:714293de3836 1199 {
ashleymills 0:714293de3836 1200 CYASSL_METHOD* method =
ashleymills 0:714293de3836 1201 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:714293de3836 1202 DYNAMIC_TYPE_METHOD);
ashleymills 0:714293de3836 1203 if (method) {
ashleymills 0:714293de3836 1204 InitSSL_Method(method, MakeTLSv1_1());
ashleymills 0:714293de3836 1205 method->side = SERVER_END;
ashleymills 0:714293de3836 1206 }
ashleymills 0:714293de3836 1207 return method;
ashleymills 0:714293de3836 1208 }
ashleymills 0:714293de3836 1209
ashleymills 0:714293de3836 1210 #endif /* !NO_OLD_TLS */
ashleymills 0:714293de3836 1211
ashleymills 0:714293de3836 1212 #ifndef NO_SHA256 /* can't use without SHA256 */
ashleymills 0:714293de3836 1213
ashleymills 0:714293de3836 1214 CYASSL_METHOD* CyaTLSv1_2_server_method(void)
ashleymills 0:714293de3836 1215 {
ashleymills 0:714293de3836 1216 CYASSL_METHOD* method =
ashleymills 0:714293de3836 1217 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:714293de3836 1218 DYNAMIC_TYPE_METHOD);
ashleymills 0:714293de3836 1219 if (method) {
ashleymills 0:714293de3836 1220 InitSSL_Method(method, MakeTLSv1_2());
ashleymills 0:714293de3836 1221 method->side = SERVER_END;
ashleymills 0:714293de3836 1222 }
ashleymills 0:714293de3836 1223 return method;
ashleymills 0:714293de3836 1224 }
ashleymills 0:714293de3836 1225
ashleymills 0:714293de3836 1226 #endif
ashleymills 0:714293de3836 1227
ashleymills 0:714293de3836 1228
ashleymills 0:714293de3836 1229 CYASSL_METHOD* CyaSSLv23_server_method(void)
ashleymills 0:714293de3836 1230 {
ashleymills 0:714293de3836 1231 CYASSL_METHOD* method =
ashleymills 0:714293de3836 1232 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:714293de3836 1233 DYNAMIC_TYPE_METHOD);
ashleymills 0:714293de3836 1234 if (method) {
ashleymills 0:714293de3836 1235 #ifndef NO_SHA256 /* 1.2 requires SHA256 */
ashleymills 0:714293de3836 1236 InitSSL_Method(method, MakeTLSv1_2());
ashleymills 0:714293de3836 1237 #else
ashleymills 0:714293de3836 1238 InitSSL_Method(method, MakeTLSv1_1());
ashleymills 0:714293de3836 1239 #endif
ashleymills 0:714293de3836 1240 method->side = SERVER_END;
ashleymills 0:714293de3836 1241 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 1242 method->downgrade = 1;
ashleymills 0:714293de3836 1243 #endif /* !NO_OLD_TLS */
ashleymills 0:714293de3836 1244 }
ashleymills 0:714293de3836 1245 return method;
ashleymills 0:714293de3836 1246 }
ashleymills 0:714293de3836 1247
ashleymills 0:714293de3836 1248
ashleymills 0:714293de3836 1249
ashleymills 0:714293de3836 1250 #endif /* NO_CYASSL_SERVER */
ashleymills 0:714293de3836 1251 #endif /* NO_TLS */
ashleymills 0:714293de3836 1252