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