A library for setting up Secure Socket Layer (SSL) connections and verifying remote hosts using certificates. Contains only the source files for mbed platform implementation of the library.

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

Committer:
Mike Fiore
Date:
Mon Mar 23 16:51:07 2015 -0500
Revision:
6:cf58d49e1a86
Parent:
0:b86d15c6ba29
fix whitespace in sha512.c

Who changed what in which revision?

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