wolfSSL SSL/TLS library, support up to TLS1.3
Dependents: CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more
src/tls.c@13:f67a6c6013ca, 2017-08-22 (annotated)
- Committer:
- wolfSSL
- Date:
- Tue Aug 22 10:48:22 2017 +0000
- Revision:
- 13:f67a6c6013ca
wolfSSL3.12.0 with TLS1.3
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wolfSSL | 13:f67a6c6013ca | 1 | /* tls.c |
wolfSSL | 13:f67a6c6013ca | 2 | * |
wolfSSL | 13:f67a6c6013ca | 3 | * Copyright (C) 2006-2016 wolfSSL Inc. |
wolfSSL | 13:f67a6c6013ca | 4 | * |
wolfSSL | 13:f67a6c6013ca | 5 | * This file is part of wolfSSL. |
wolfSSL | 13:f67a6c6013ca | 6 | * |
wolfSSL | 13:f67a6c6013ca | 7 | * wolfSSL is free software; you can redistribute it and/or modify |
wolfSSL | 13:f67a6c6013ca | 8 | * it under the terms of the GNU General Public License as published by |
wolfSSL | 13:f67a6c6013ca | 9 | * the Free Software Foundation; either version 2 of the License, or |
wolfSSL | 13:f67a6c6013ca | 10 | * (at your option) any later version. |
wolfSSL | 13:f67a6c6013ca | 11 | * |
wolfSSL | 13:f67a6c6013ca | 12 | * wolfSSL is distributed in the hope that it will be useful, |
wolfSSL | 13:f67a6c6013ca | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
wolfSSL | 13:f67a6c6013ca | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
wolfSSL | 13:f67a6c6013ca | 15 | * GNU General Public License for more details. |
wolfSSL | 13:f67a6c6013ca | 16 | * |
wolfSSL | 13:f67a6c6013ca | 17 | * You should have received a copy of the GNU General Public License |
wolfSSL | 13:f67a6c6013ca | 18 | * along with this program; if not, write to the Free Software |
wolfSSL | 13:f67a6c6013ca | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA |
wolfSSL | 13:f67a6c6013ca | 20 | */ |
wolfSSL | 13:f67a6c6013ca | 21 | |
wolfSSL | 13:f67a6c6013ca | 22 | |
wolfSSL | 13:f67a6c6013ca | 23 | |
wolfSSL | 13:f67a6c6013ca | 24 | #ifdef HAVE_CONFIG_H |
wolfSSL | 13:f67a6c6013ca | 25 | #include <config.h> |
wolfSSL | 13:f67a6c6013ca | 26 | #endif |
wolfSSL | 13:f67a6c6013ca | 27 | |
wolfSSL | 13:f67a6c6013ca | 28 | #include <wolfssl/wolfcrypt/settings.h> |
wolfSSL | 13:f67a6c6013ca | 29 | |
wolfSSL | 13:f67a6c6013ca | 30 | #ifndef WOLFCRYPT_ONLY |
wolfSSL | 13:f67a6c6013ca | 31 | |
wolfSSL | 13:f67a6c6013ca | 32 | #include <wolfssl/ssl.h> |
wolfSSL | 13:f67a6c6013ca | 33 | #include <wolfssl/internal.h> |
wolfSSL | 13:f67a6c6013ca | 34 | #include <wolfssl/error-ssl.h> |
wolfSSL | 13:f67a6c6013ca | 35 | #include <wolfssl/wolfcrypt/hmac.h> |
wolfSSL | 13:f67a6c6013ca | 36 | #ifdef NO_INLINE |
wolfSSL | 13:f67a6c6013ca | 37 | #include <wolfssl/wolfcrypt/misc.h> |
wolfSSL | 13:f67a6c6013ca | 38 | #else |
wolfSSL | 13:f67a6c6013ca | 39 | #define WOLFSSL_MISC_INCLUDED |
wolfSSL | 13:f67a6c6013ca | 40 | #include <wolfcrypt/src/misc.c> |
wolfSSL | 13:f67a6c6013ca | 41 | #endif |
wolfSSL | 13:f67a6c6013ca | 42 | |
wolfSSL | 13:f67a6c6013ca | 43 | #ifdef HAVE_CURVE25519 |
wolfSSL | 13:f67a6c6013ca | 44 | #include <wolfssl/wolfcrypt/curve25519.h> |
wolfSSL | 13:f67a6c6013ca | 45 | #endif |
wolfSSL | 13:f67a6c6013ca | 46 | |
wolfSSL | 13:f67a6c6013ca | 47 | #ifdef HAVE_NTRU |
wolfSSL | 13:f67a6c6013ca | 48 | #include "libntruencrypt/ntru_crypto.h" |
wolfSSL | 13:f67a6c6013ca | 49 | #include <wolfssl/wolfcrypt/random.h> |
wolfSSL | 13:f67a6c6013ca | 50 | #endif |
wolfSSL | 13:f67a6c6013ca | 51 | #ifdef HAVE_QSH |
wolfSSL | 13:f67a6c6013ca | 52 | static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key); |
wolfSSL | 13:f67a6c6013ca | 53 | static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name); |
wolfSSL | 13:f67a6c6013ca | 54 | #endif |
wolfSSL | 13:f67a6c6013ca | 55 | #if defined(HAVE_NTRU) || defined(HAVE_QSH) |
wolfSSL | 13:f67a6c6013ca | 56 | static int TLSX_CreateNtruKey(WOLFSSL* ssl, int type); |
wolfSSL | 13:f67a6c6013ca | 57 | #endif |
wolfSSL | 13:f67a6c6013ca | 58 | |
wolfSSL | 13:f67a6c6013ca | 59 | |
wolfSSL | 13:f67a6c6013ca | 60 | #ifndef NO_TLS |
wolfSSL | 13:f67a6c6013ca | 61 | |
wolfSSL | 13:f67a6c6013ca | 62 | /* Digest enable checks */ |
wolfSSL | 13:f67a6c6013ca | 63 | #ifdef NO_OLD_TLS /* TLS 1.2 only */ |
wolfSSL | 13:f67a6c6013ca | 64 | #if defined(NO_SHA256) && !defined(WOLFSSL_SHA384) && \ |
wolfSSL | 13:f67a6c6013ca | 65 | !defined(WOLFSSL_SHA512) |
wolfSSL | 13:f67a6c6013ca | 66 | #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2 |
wolfSSL | 13:f67a6c6013ca | 67 | #endif |
wolfSSL | 13:f67a6c6013ca | 68 | #else /* TLS 1.1 or older */ |
wolfSSL | 13:f67a6c6013ca | 69 | #if defined(NO_MD5) && defined(NO_SHA) |
wolfSSL | 13:f67a6c6013ca | 70 | #error Must have SHA1 and MD5 enabled for old TLS |
wolfSSL | 13:f67a6c6013ca | 71 | #endif |
wolfSSL | 13:f67a6c6013ca | 72 | #endif |
wolfSSL | 13:f67a6c6013ca | 73 | |
wolfSSL | 13:f67a6c6013ca | 74 | |
wolfSSL | 13:f67a6c6013ca | 75 | #ifdef WOLFSSL_SHA384 |
wolfSSL | 13:f67a6c6013ca | 76 | #define P_HASH_MAX_SIZE SHA384_DIGEST_SIZE |
wolfSSL | 13:f67a6c6013ca | 77 | #else |
wolfSSL | 13:f67a6c6013ca | 78 | #define P_HASH_MAX_SIZE SHA256_DIGEST_SIZE |
wolfSSL | 13:f67a6c6013ca | 79 | #endif |
wolfSSL | 13:f67a6c6013ca | 80 | |
wolfSSL | 13:f67a6c6013ca | 81 | |
wolfSSL | 13:f67a6c6013ca | 82 | /* compute p_hash for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1 PRF */ |
wolfSSL | 13:f67a6c6013ca | 83 | static int p_hash(byte* result, word32 resLen, const byte* secret, |
wolfSSL | 13:f67a6c6013ca | 84 | word32 secLen, const byte* seed, word32 seedLen, int hash, |
wolfSSL | 13:f67a6c6013ca | 85 | void* heap, int devId) |
wolfSSL | 13:f67a6c6013ca | 86 | { |
wolfSSL | 13:f67a6c6013ca | 87 | word32 len = P_HASH_MAX_SIZE; |
wolfSSL | 13:f67a6c6013ca | 88 | word32 times; |
wolfSSL | 13:f67a6c6013ca | 89 | word32 lastLen; |
wolfSSL | 13:f67a6c6013ca | 90 | word32 lastTime; |
wolfSSL | 13:f67a6c6013ca | 91 | word32 i; |
wolfSSL | 13:f67a6c6013ca | 92 | word32 idx = 0; |
wolfSSL | 13:f67a6c6013ca | 93 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 94 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:f67a6c6013ca | 95 | byte* previous; |
wolfSSL | 13:f67a6c6013ca | 96 | byte* current; |
wolfSSL | 13:f67a6c6013ca | 97 | Hmac* hmac; |
wolfSSL | 13:f67a6c6013ca | 98 | #else |
wolfSSL | 13:f67a6c6013ca | 99 | byte previous[P_HASH_MAX_SIZE]; /* max size */ |
wolfSSL | 13:f67a6c6013ca | 100 | byte current[P_HASH_MAX_SIZE]; /* max size */ |
wolfSSL | 13:f67a6c6013ca | 101 | Hmac hmac[1]; |
wolfSSL | 13:f67a6c6013ca | 102 | #endif |
wolfSSL | 13:f67a6c6013ca | 103 | |
wolfSSL | 13:f67a6c6013ca | 104 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:f67a6c6013ca | 105 | previous = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 106 | current = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 107 | hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_HMAC); |
wolfSSL | 13:f67a6c6013ca | 108 | |
wolfSSL | 13:f67a6c6013ca | 109 | if (previous == NULL || current == NULL || hmac == NULL) { |
wolfSSL | 13:f67a6c6013ca | 110 | if (previous) XFREE(previous, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 111 | if (current) XFREE(current, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 112 | if (hmac) XFREE(hmac, heap, DYNAMIC_TYPE_HMAC); |
wolfSSL | 13:f67a6c6013ca | 113 | |
wolfSSL | 13:f67a6c6013ca | 114 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 115 | } |
wolfSSL | 13:f67a6c6013ca | 116 | #endif |
wolfSSL | 13:f67a6c6013ca | 117 | |
wolfSSL | 13:f67a6c6013ca | 118 | switch (hash) { |
wolfSSL | 13:f67a6c6013ca | 119 | #ifndef NO_MD5 |
wolfSSL | 13:f67a6c6013ca | 120 | case md5_mac: |
wolfSSL | 13:f67a6c6013ca | 121 | hash = MD5; |
wolfSSL | 13:f67a6c6013ca | 122 | len = MD5_DIGEST_SIZE; |
wolfSSL | 13:f67a6c6013ca | 123 | break; |
wolfSSL | 13:f67a6c6013ca | 124 | #endif |
wolfSSL | 13:f67a6c6013ca | 125 | |
wolfSSL | 13:f67a6c6013ca | 126 | #ifndef NO_SHA256 |
wolfSSL | 13:f67a6c6013ca | 127 | case sha256_mac: |
wolfSSL | 13:f67a6c6013ca | 128 | hash = SHA256; |
wolfSSL | 13:f67a6c6013ca | 129 | len = SHA256_DIGEST_SIZE; |
wolfSSL | 13:f67a6c6013ca | 130 | break; |
wolfSSL | 13:f67a6c6013ca | 131 | #endif |
wolfSSL | 13:f67a6c6013ca | 132 | |
wolfSSL | 13:f67a6c6013ca | 133 | #ifdef WOLFSSL_SHA384 |
wolfSSL | 13:f67a6c6013ca | 134 | case sha384_mac: |
wolfSSL | 13:f67a6c6013ca | 135 | hash = SHA384; |
wolfSSL | 13:f67a6c6013ca | 136 | len = SHA384_DIGEST_SIZE; |
wolfSSL | 13:f67a6c6013ca | 137 | break; |
wolfSSL | 13:f67a6c6013ca | 138 | #endif |
wolfSSL | 13:f67a6c6013ca | 139 | |
wolfSSL | 13:f67a6c6013ca | 140 | #ifndef NO_SHA |
wolfSSL | 13:f67a6c6013ca | 141 | case sha_mac: |
wolfSSL | 13:f67a6c6013ca | 142 | default: |
wolfSSL | 13:f67a6c6013ca | 143 | hash = SHA; |
wolfSSL | 13:f67a6c6013ca | 144 | len = SHA_DIGEST_SIZE; |
wolfSSL | 13:f67a6c6013ca | 145 | break; |
wolfSSL | 13:f67a6c6013ca | 146 | #endif |
wolfSSL | 13:f67a6c6013ca | 147 | } |
wolfSSL | 13:f67a6c6013ca | 148 | |
wolfSSL | 13:f67a6c6013ca | 149 | times = resLen / len; |
wolfSSL | 13:f67a6c6013ca | 150 | lastLen = resLen % len; |
wolfSSL | 13:f67a6c6013ca | 151 | |
wolfSSL | 13:f67a6c6013ca | 152 | if (lastLen) |
wolfSSL | 13:f67a6c6013ca | 153 | times += 1; |
wolfSSL | 13:f67a6c6013ca | 154 | |
wolfSSL | 13:f67a6c6013ca | 155 | lastTime = times - 1; |
wolfSSL | 13:f67a6c6013ca | 156 | |
wolfSSL | 13:f67a6c6013ca | 157 | ret = wc_HmacInit(hmac, heap, devId); |
wolfSSL | 13:f67a6c6013ca | 158 | if (ret == 0) { |
wolfSSL | 13:f67a6c6013ca | 159 | ret = wc_HmacSetKey(hmac, hash, secret, secLen); |
wolfSSL | 13:f67a6c6013ca | 160 | if (ret == 0) |
wolfSSL | 13:f67a6c6013ca | 161 | ret = wc_HmacUpdate(hmac, seed, seedLen); /* A0 = seed */ |
wolfSSL | 13:f67a6c6013ca | 162 | if (ret == 0) |
wolfSSL | 13:f67a6c6013ca | 163 | ret = wc_HmacFinal(hmac, previous); /* A1 */ |
wolfSSL | 13:f67a6c6013ca | 164 | if (ret == 0) { |
wolfSSL | 13:f67a6c6013ca | 165 | for (i = 0; i < times; i++) { |
wolfSSL | 13:f67a6c6013ca | 166 | ret = wc_HmacUpdate(hmac, previous, len); |
wolfSSL | 13:f67a6c6013ca | 167 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 168 | break; |
wolfSSL | 13:f67a6c6013ca | 169 | ret = wc_HmacUpdate(hmac, seed, seedLen); |
wolfSSL | 13:f67a6c6013ca | 170 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 171 | break; |
wolfSSL | 13:f67a6c6013ca | 172 | ret = wc_HmacFinal(hmac, current); |
wolfSSL | 13:f67a6c6013ca | 173 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 174 | break; |
wolfSSL | 13:f67a6c6013ca | 175 | |
wolfSSL | 13:f67a6c6013ca | 176 | if ((i == lastTime) && lastLen) |
wolfSSL | 13:f67a6c6013ca | 177 | XMEMCPY(&result[idx], current, |
wolfSSL | 13:f67a6c6013ca | 178 | min(lastLen, P_HASH_MAX_SIZE)); |
wolfSSL | 13:f67a6c6013ca | 179 | else { |
wolfSSL | 13:f67a6c6013ca | 180 | XMEMCPY(&result[idx], current, len); |
wolfSSL | 13:f67a6c6013ca | 181 | idx += len; |
wolfSSL | 13:f67a6c6013ca | 182 | ret = wc_HmacUpdate(hmac, previous, len); |
wolfSSL | 13:f67a6c6013ca | 183 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 184 | break; |
wolfSSL | 13:f67a6c6013ca | 185 | ret = wc_HmacFinal(hmac, previous); |
wolfSSL | 13:f67a6c6013ca | 186 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 187 | break; |
wolfSSL | 13:f67a6c6013ca | 188 | } |
wolfSSL | 13:f67a6c6013ca | 189 | } |
wolfSSL | 13:f67a6c6013ca | 190 | } |
wolfSSL | 13:f67a6c6013ca | 191 | wc_HmacFree(hmac); |
wolfSSL | 13:f67a6c6013ca | 192 | } |
wolfSSL | 13:f67a6c6013ca | 193 | |
wolfSSL | 13:f67a6c6013ca | 194 | ForceZero(previous, P_HASH_MAX_SIZE); |
wolfSSL | 13:f67a6c6013ca | 195 | ForceZero(current, P_HASH_MAX_SIZE); |
wolfSSL | 13:f67a6c6013ca | 196 | ForceZero(hmac, sizeof(Hmac)); |
wolfSSL | 13:f67a6c6013ca | 197 | |
wolfSSL | 13:f67a6c6013ca | 198 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:f67a6c6013ca | 199 | XFREE(previous, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 200 | XFREE(current, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 201 | XFREE(hmac, heap, DYNAMIC_TYPE_HMAC); |
wolfSSL | 13:f67a6c6013ca | 202 | #endif |
wolfSSL | 13:f67a6c6013ca | 203 | |
wolfSSL | 13:f67a6c6013ca | 204 | return ret; |
wolfSSL | 13:f67a6c6013ca | 205 | } |
wolfSSL | 13:f67a6c6013ca | 206 | |
wolfSSL | 13:f67a6c6013ca | 207 | #undef P_HASH_MAX_SIZE |
wolfSSL | 13:f67a6c6013ca | 208 | |
wolfSSL | 13:f67a6c6013ca | 209 | |
wolfSSL | 13:f67a6c6013ca | 210 | #ifndef NO_OLD_TLS |
wolfSSL | 13:f67a6c6013ca | 211 | |
wolfSSL | 13:f67a6c6013ca | 212 | /* calculate XOR for TLSv1 PRF */ |
wolfSSL | 13:f67a6c6013ca | 213 | static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha) |
wolfSSL | 13:f67a6c6013ca | 214 | { |
wolfSSL | 13:f67a6c6013ca | 215 | word32 i; |
wolfSSL | 13:f67a6c6013ca | 216 | |
wolfSSL | 13:f67a6c6013ca | 217 | for (i = 0; i < digLen; i++) |
wolfSSL | 13:f67a6c6013ca | 218 | digest[i] = md5[i] ^ sha[i]; |
wolfSSL | 13:f67a6c6013ca | 219 | } |
wolfSSL | 13:f67a6c6013ca | 220 | |
wolfSSL | 13:f67a6c6013ca | 221 | |
wolfSSL | 13:f67a6c6013ca | 222 | /* compute TLSv1 PRF (pseudo random function using HMAC) */ |
wolfSSL | 13:f67a6c6013ca | 223 | static int doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen, |
wolfSSL | 13:f67a6c6013ca | 224 | const byte* label, word32 labLen, const byte* seed, |
wolfSSL | 13:f67a6c6013ca | 225 | word32 seedLen, void* heap, int devId) |
wolfSSL | 13:f67a6c6013ca | 226 | { |
wolfSSL | 13:f67a6c6013ca | 227 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 228 | word32 half = (secLen + 1) / 2; |
wolfSSL | 13:f67a6c6013ca | 229 | |
wolfSSL | 13:f67a6c6013ca | 230 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:f67a6c6013ca | 231 | byte* md5_half; |
wolfSSL | 13:f67a6c6013ca | 232 | byte* sha_half; |
wolfSSL | 13:f67a6c6013ca | 233 | byte* labelSeed; |
wolfSSL | 13:f67a6c6013ca | 234 | byte* md5_result; |
wolfSSL | 13:f67a6c6013ca | 235 | byte* sha_result; |
wolfSSL | 13:f67a6c6013ca | 236 | #else |
wolfSSL | 13:f67a6c6013ca | 237 | byte md5_half[MAX_PRF_HALF]; /* half is real size */ |
wolfSSL | 13:f67a6c6013ca | 238 | byte sha_half[MAX_PRF_HALF]; /* half is real size */ |
wolfSSL | 13:f67a6c6013ca | 239 | byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */ |
wolfSSL | 13:f67a6c6013ca | 240 | byte md5_result[MAX_PRF_DIG]; /* digLen is real size */ |
wolfSSL | 13:f67a6c6013ca | 241 | byte sha_result[MAX_PRF_DIG]; /* digLen is real size */ |
wolfSSL | 13:f67a6c6013ca | 242 | #endif |
wolfSSL | 13:f67a6c6013ca | 243 | |
wolfSSL | 13:f67a6c6013ca | 244 | if (half > MAX_PRF_HALF) |
wolfSSL | 13:f67a6c6013ca | 245 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 246 | if (labLen + seedLen > MAX_PRF_LABSEED) |
wolfSSL | 13:f67a6c6013ca | 247 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 248 | if (digLen > MAX_PRF_DIG) |
wolfSSL | 13:f67a6c6013ca | 249 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 250 | |
wolfSSL | 13:f67a6c6013ca | 251 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:f67a6c6013ca | 252 | md5_half = (byte*)XMALLOC(MAX_PRF_HALF, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 253 | sha_half = (byte*)XMALLOC(MAX_PRF_HALF, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 254 | labelSeed = (byte*)XMALLOC(MAX_PRF_LABSEED, heap, DYNAMIC_TYPE_SEED); |
wolfSSL | 13:f67a6c6013ca | 255 | md5_result = (byte*)XMALLOC(MAX_PRF_DIG, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 256 | sha_result = (byte*)XMALLOC(MAX_PRF_DIG, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 257 | |
wolfSSL | 13:f67a6c6013ca | 258 | if (md5_half == NULL || sha_half == NULL || labelSeed == NULL || |
wolfSSL | 13:f67a6c6013ca | 259 | md5_result == NULL || sha_result == NULL) { |
wolfSSL | 13:f67a6c6013ca | 260 | if (md5_half) XFREE(md5_half, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 261 | if (sha_half) XFREE(sha_half, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 262 | if (labelSeed) XFREE(labelSeed, heap, DYNAMIC_TYPE_SEED); |
wolfSSL | 13:f67a6c6013ca | 263 | if (md5_result) XFREE(md5_result, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 264 | if (sha_result) XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 265 | |
wolfSSL | 13:f67a6c6013ca | 266 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 267 | } |
wolfSSL | 13:f67a6c6013ca | 268 | #endif |
wolfSSL | 13:f67a6c6013ca | 269 | |
wolfSSL | 13:f67a6c6013ca | 270 | XMEMSET(md5_result, 0, digLen); |
wolfSSL | 13:f67a6c6013ca | 271 | XMEMSET(sha_result, 0, digLen); |
wolfSSL | 13:f67a6c6013ca | 272 | |
wolfSSL | 13:f67a6c6013ca | 273 | XMEMCPY(md5_half, secret, half); |
wolfSSL | 13:f67a6c6013ca | 274 | XMEMCPY(sha_half, secret + half - secLen % 2, half); |
wolfSSL | 13:f67a6c6013ca | 275 | |
wolfSSL | 13:f67a6c6013ca | 276 | XMEMCPY(labelSeed, label, labLen); |
wolfSSL | 13:f67a6c6013ca | 277 | XMEMCPY(labelSeed + labLen, seed, seedLen); |
wolfSSL | 13:f67a6c6013ca | 278 | |
wolfSSL | 13:f67a6c6013ca | 279 | if ((ret = p_hash(md5_result, digLen, md5_half, half, labelSeed, |
wolfSSL | 13:f67a6c6013ca | 280 | labLen + seedLen, md5_mac, heap, devId)) == 0) { |
wolfSSL | 13:f67a6c6013ca | 281 | if ((ret = p_hash(sha_result, digLen, sha_half, half, labelSeed, |
wolfSSL | 13:f67a6c6013ca | 282 | labLen + seedLen, sha_mac, heap, devId)) == 0) { |
wolfSSL | 13:f67a6c6013ca | 283 | get_xor(digest, digLen, md5_result, sha_result); |
wolfSSL | 13:f67a6c6013ca | 284 | } |
wolfSSL | 13:f67a6c6013ca | 285 | } |
wolfSSL | 13:f67a6c6013ca | 286 | |
wolfSSL | 13:f67a6c6013ca | 287 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:f67a6c6013ca | 288 | XFREE(md5_half, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 289 | XFREE(sha_half, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 290 | XFREE(labelSeed, heap, DYNAMIC_TYPE_SEED); |
wolfSSL | 13:f67a6c6013ca | 291 | XFREE(md5_result, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 292 | XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 293 | #endif |
wolfSSL | 13:f67a6c6013ca | 294 | |
wolfSSL | 13:f67a6c6013ca | 295 | return ret; |
wolfSSL | 13:f67a6c6013ca | 296 | } |
wolfSSL | 13:f67a6c6013ca | 297 | |
wolfSSL | 13:f67a6c6013ca | 298 | #endif |
wolfSSL | 13:f67a6c6013ca | 299 | |
wolfSSL | 13:f67a6c6013ca | 300 | |
wolfSSL | 13:f67a6c6013ca | 301 | /* Wrapper to call straight thru to p_hash in TSL 1.2 cases to remove stack |
wolfSSL | 13:f67a6c6013ca | 302 | use */ |
wolfSSL | 13:f67a6c6013ca | 303 | static int PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen, |
wolfSSL | 13:f67a6c6013ca | 304 | const byte* label, word32 labLen, const byte* seed, word32 seedLen, |
wolfSSL | 13:f67a6c6013ca | 305 | int useAtLeastSha256, int hash_type, void* heap, int devId) |
wolfSSL | 13:f67a6c6013ca | 306 | { |
wolfSSL | 13:f67a6c6013ca | 307 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 308 | |
wolfSSL | 13:f67a6c6013ca | 309 | if (useAtLeastSha256) { |
wolfSSL | 13:f67a6c6013ca | 310 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:f67a6c6013ca | 311 | byte* labelSeed; |
wolfSSL | 13:f67a6c6013ca | 312 | #else |
wolfSSL | 13:f67a6c6013ca | 313 | byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */ |
wolfSSL | 13:f67a6c6013ca | 314 | #endif |
wolfSSL | 13:f67a6c6013ca | 315 | |
wolfSSL | 13:f67a6c6013ca | 316 | if (labLen + seedLen > MAX_PRF_LABSEED) |
wolfSSL | 13:f67a6c6013ca | 317 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 318 | |
wolfSSL | 13:f67a6c6013ca | 319 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:f67a6c6013ca | 320 | labelSeed = (byte*)XMALLOC(MAX_PRF_LABSEED, heap, DYNAMIC_TYPE_SEED); |
wolfSSL | 13:f67a6c6013ca | 321 | if (labelSeed == NULL) |
wolfSSL | 13:f67a6c6013ca | 322 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 323 | #endif |
wolfSSL | 13:f67a6c6013ca | 324 | |
wolfSSL | 13:f67a6c6013ca | 325 | XMEMCPY(labelSeed, label, labLen); |
wolfSSL | 13:f67a6c6013ca | 326 | XMEMCPY(labelSeed + labLen, seed, seedLen); |
wolfSSL | 13:f67a6c6013ca | 327 | |
wolfSSL | 13:f67a6c6013ca | 328 | /* If a cipher suite wants an algorithm better than sha256, it |
wolfSSL | 13:f67a6c6013ca | 329 | * should use better. */ |
wolfSSL | 13:f67a6c6013ca | 330 | if (hash_type < sha256_mac || hash_type == blake2b_mac) |
wolfSSL | 13:f67a6c6013ca | 331 | hash_type = sha256_mac; |
wolfSSL | 13:f67a6c6013ca | 332 | ret = p_hash(digest, digLen, secret, secLen, labelSeed, |
wolfSSL | 13:f67a6c6013ca | 333 | labLen + seedLen, hash_type, heap, devId); |
wolfSSL | 13:f67a6c6013ca | 334 | |
wolfSSL | 13:f67a6c6013ca | 335 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:f67a6c6013ca | 336 | XFREE(labelSeed, heap, DYNAMIC_TYPE_SEED); |
wolfSSL | 13:f67a6c6013ca | 337 | #endif |
wolfSSL | 13:f67a6c6013ca | 338 | } |
wolfSSL | 13:f67a6c6013ca | 339 | #ifndef NO_OLD_TLS |
wolfSSL | 13:f67a6c6013ca | 340 | else { |
wolfSSL | 13:f67a6c6013ca | 341 | ret = doPRF(digest, digLen, secret, secLen, label, labLen, seed, |
wolfSSL | 13:f67a6c6013ca | 342 | seedLen, heap, devId); |
wolfSSL | 13:f67a6c6013ca | 343 | } |
wolfSSL | 13:f67a6c6013ca | 344 | #endif |
wolfSSL | 13:f67a6c6013ca | 345 | |
wolfSSL | 13:f67a6c6013ca | 346 | return ret; |
wolfSSL | 13:f67a6c6013ca | 347 | } |
wolfSSL | 13:f67a6c6013ca | 348 | |
wolfSSL | 13:f67a6c6013ca | 349 | #ifdef WOLFSSL_SHA384 |
wolfSSL | 13:f67a6c6013ca | 350 | #define HSHASH_SZ SHA384_DIGEST_SIZE |
wolfSSL | 13:f67a6c6013ca | 351 | #else |
wolfSSL | 13:f67a6c6013ca | 352 | #define HSHASH_SZ FINISHED_SZ |
wolfSSL | 13:f67a6c6013ca | 353 | #endif |
wolfSSL | 13:f67a6c6013ca | 354 | |
wolfSSL | 13:f67a6c6013ca | 355 | |
wolfSSL | 13:f67a6c6013ca | 356 | int BuildTlsHandshakeHash(WOLFSSL* ssl, byte* hash, word32* hashLen) |
wolfSSL | 13:f67a6c6013ca | 357 | { |
wolfSSL | 13:f67a6c6013ca | 358 | word32 hashSz = FINISHED_SZ; |
wolfSSL | 13:f67a6c6013ca | 359 | |
wolfSSL | 13:f67a6c6013ca | 360 | if (ssl == NULL || hash == NULL || hashLen == NULL || *hashLen < HSHASH_SZ) |
wolfSSL | 13:f67a6c6013ca | 361 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 362 | |
wolfSSL | 13:f67a6c6013ca | 363 | #ifndef NO_OLD_TLS |
wolfSSL | 13:f67a6c6013ca | 364 | wc_Md5GetHash(&ssl->hsHashes->hashMd5, hash); |
wolfSSL | 13:f67a6c6013ca | 365 | wc_ShaGetHash(&ssl->hsHashes->hashSha, &hash[MD5_DIGEST_SIZE]); |
wolfSSL | 13:f67a6c6013ca | 366 | #endif |
wolfSSL | 13:f67a6c6013ca | 367 | |
wolfSSL | 13:f67a6c6013ca | 368 | if (IsAtLeastTLSv1_2(ssl)) { |
wolfSSL | 13:f67a6c6013ca | 369 | #ifndef NO_SHA256 |
wolfSSL | 13:f67a6c6013ca | 370 | if (ssl->specs.mac_algorithm <= sha256_mac || |
wolfSSL | 13:f67a6c6013ca | 371 | ssl->specs.mac_algorithm == blake2b_mac) { |
wolfSSL | 13:f67a6c6013ca | 372 | int ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash); |
wolfSSL | 13:f67a6c6013ca | 373 | |
wolfSSL | 13:f67a6c6013ca | 374 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 375 | return ret; |
wolfSSL | 13:f67a6c6013ca | 376 | |
wolfSSL | 13:f67a6c6013ca | 377 | hashSz = SHA256_DIGEST_SIZE; |
wolfSSL | 13:f67a6c6013ca | 378 | } |
wolfSSL | 13:f67a6c6013ca | 379 | #endif |
wolfSSL | 13:f67a6c6013ca | 380 | #ifdef WOLFSSL_SHA384 |
wolfSSL | 13:f67a6c6013ca | 381 | if (ssl->specs.mac_algorithm == sha384_mac) { |
wolfSSL | 13:f67a6c6013ca | 382 | int ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash); |
wolfSSL | 13:f67a6c6013ca | 383 | |
wolfSSL | 13:f67a6c6013ca | 384 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 385 | return ret; |
wolfSSL | 13:f67a6c6013ca | 386 | |
wolfSSL | 13:f67a6c6013ca | 387 | hashSz = SHA384_DIGEST_SIZE; |
wolfSSL | 13:f67a6c6013ca | 388 | } |
wolfSSL | 13:f67a6c6013ca | 389 | #endif |
wolfSSL | 13:f67a6c6013ca | 390 | } |
wolfSSL | 13:f67a6c6013ca | 391 | |
wolfSSL | 13:f67a6c6013ca | 392 | *hashLen = hashSz; |
wolfSSL | 13:f67a6c6013ca | 393 | |
wolfSSL | 13:f67a6c6013ca | 394 | return 0; |
wolfSSL | 13:f67a6c6013ca | 395 | } |
wolfSSL | 13:f67a6c6013ca | 396 | |
wolfSSL | 13:f67a6c6013ca | 397 | |
wolfSSL | 13:f67a6c6013ca | 398 | int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) |
wolfSSL | 13:f67a6c6013ca | 399 | { |
wolfSSL | 13:f67a6c6013ca | 400 | int ret; |
wolfSSL | 13:f67a6c6013ca | 401 | const byte* side; |
wolfSSL | 13:f67a6c6013ca | 402 | byte* handshake_hash; |
wolfSSL | 13:f67a6c6013ca | 403 | word32 hashSz = HSHASH_SZ; |
wolfSSL | 13:f67a6c6013ca | 404 | |
wolfSSL | 13:f67a6c6013ca | 405 | /* using allocate here to allow async hardware to use buffer directly */ |
wolfSSL | 13:f67a6c6013ca | 406 | handshake_hash = (byte*)XMALLOC(hashSz, ssl->heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 407 | if (handshake_hash == NULL) |
wolfSSL | 13:f67a6c6013ca | 408 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 409 | |
wolfSSL | 13:f67a6c6013ca | 410 | ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz); |
wolfSSL | 13:f67a6c6013ca | 411 | if (ret == 0) { |
wolfSSL | 13:f67a6c6013ca | 412 | if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0) |
wolfSSL | 13:f67a6c6013ca | 413 | side = tls_client; |
wolfSSL | 13:f67a6c6013ca | 414 | else |
wolfSSL | 13:f67a6c6013ca | 415 | side = tls_server; |
wolfSSL | 13:f67a6c6013ca | 416 | |
wolfSSL | 13:f67a6c6013ca | 417 | ret = PRF((byte*)hashes, TLS_FINISHED_SZ, ssl->arrays->masterSecret, |
wolfSSL | 13:f67a6c6013ca | 418 | SECRET_LEN, side, FINISHED_LABEL_SZ, handshake_hash, hashSz, |
wolfSSL | 13:f67a6c6013ca | 419 | IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm, |
wolfSSL | 13:f67a6c6013ca | 420 | ssl->heap, ssl->devId); |
wolfSSL | 13:f67a6c6013ca | 421 | } |
wolfSSL | 13:f67a6c6013ca | 422 | |
wolfSSL | 13:f67a6c6013ca | 423 | XFREE(handshake_hash, ssl->heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 424 | |
wolfSSL | 13:f67a6c6013ca | 425 | return ret; |
wolfSSL | 13:f67a6c6013ca | 426 | } |
wolfSSL | 13:f67a6c6013ca | 427 | |
wolfSSL | 13:f67a6c6013ca | 428 | |
wolfSSL | 13:f67a6c6013ca | 429 | #ifndef NO_OLD_TLS |
wolfSSL | 13:f67a6c6013ca | 430 | |
wolfSSL | 13:f67a6c6013ca | 431 | ProtocolVersion MakeTLSv1(void) |
wolfSSL | 13:f67a6c6013ca | 432 | { |
wolfSSL | 13:f67a6c6013ca | 433 | ProtocolVersion pv; |
wolfSSL | 13:f67a6c6013ca | 434 | pv.major = SSLv3_MAJOR; |
wolfSSL | 13:f67a6c6013ca | 435 | pv.minor = TLSv1_MINOR; |
wolfSSL | 13:f67a6c6013ca | 436 | |
wolfSSL | 13:f67a6c6013ca | 437 | return pv; |
wolfSSL | 13:f67a6c6013ca | 438 | } |
wolfSSL | 13:f67a6c6013ca | 439 | |
wolfSSL | 13:f67a6c6013ca | 440 | |
wolfSSL | 13:f67a6c6013ca | 441 | ProtocolVersion MakeTLSv1_1(void) |
wolfSSL | 13:f67a6c6013ca | 442 | { |
wolfSSL | 13:f67a6c6013ca | 443 | ProtocolVersion pv; |
wolfSSL | 13:f67a6c6013ca | 444 | pv.major = SSLv3_MAJOR; |
wolfSSL | 13:f67a6c6013ca | 445 | pv.minor = TLSv1_1_MINOR; |
wolfSSL | 13:f67a6c6013ca | 446 | |
wolfSSL | 13:f67a6c6013ca | 447 | return pv; |
wolfSSL | 13:f67a6c6013ca | 448 | } |
wolfSSL | 13:f67a6c6013ca | 449 | |
wolfSSL | 13:f67a6c6013ca | 450 | #endif |
wolfSSL | 13:f67a6c6013ca | 451 | |
wolfSSL | 13:f67a6c6013ca | 452 | |
wolfSSL | 13:f67a6c6013ca | 453 | ProtocolVersion MakeTLSv1_2(void) |
wolfSSL | 13:f67a6c6013ca | 454 | { |
wolfSSL | 13:f67a6c6013ca | 455 | ProtocolVersion pv; |
wolfSSL | 13:f67a6c6013ca | 456 | pv.major = SSLv3_MAJOR; |
wolfSSL | 13:f67a6c6013ca | 457 | pv.minor = TLSv1_2_MINOR; |
wolfSSL | 13:f67a6c6013ca | 458 | |
wolfSSL | 13:f67a6c6013ca | 459 | return pv; |
wolfSSL | 13:f67a6c6013ca | 460 | } |
wolfSSL | 13:f67a6c6013ca | 461 | |
wolfSSL | 13:f67a6c6013ca | 462 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 463 | /* The TLS v1.3 protocol version. |
wolfSSL | 13:f67a6c6013ca | 464 | * |
wolfSSL | 13:f67a6c6013ca | 465 | * returns the protocol version data for TLS v1.3. |
wolfSSL | 13:f67a6c6013ca | 466 | */ |
wolfSSL | 13:f67a6c6013ca | 467 | ProtocolVersion MakeTLSv1_3(void) |
wolfSSL | 13:f67a6c6013ca | 468 | { |
wolfSSL | 13:f67a6c6013ca | 469 | ProtocolVersion pv; |
wolfSSL | 13:f67a6c6013ca | 470 | pv.major = SSLv3_MAJOR; |
wolfSSL | 13:f67a6c6013ca | 471 | pv.minor = TLSv1_3_MINOR; |
wolfSSL | 13:f67a6c6013ca | 472 | |
wolfSSL | 13:f67a6c6013ca | 473 | return pv; |
wolfSSL | 13:f67a6c6013ca | 474 | } |
wolfSSL | 13:f67a6c6013ca | 475 | #endif |
wolfSSL | 13:f67a6c6013ca | 476 | |
wolfSSL | 13:f67a6c6013ca | 477 | |
wolfSSL | 13:f67a6c6013ca | 478 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:f67a6c6013ca | 479 | static const byte ext_master_label[EXT_MASTER_LABEL_SZ + 1] = |
wolfSSL | 13:f67a6c6013ca | 480 | "extended master secret"; |
wolfSSL | 13:f67a6c6013ca | 481 | #endif |
wolfSSL | 13:f67a6c6013ca | 482 | static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret"; |
wolfSSL | 13:f67a6c6013ca | 483 | static const byte key_label [KEY_LABEL_SZ + 1] = "key expansion"; |
wolfSSL | 13:f67a6c6013ca | 484 | |
wolfSSL | 13:f67a6c6013ca | 485 | static int _DeriveTlsKeys(byte* key_dig, word32 key_dig_len, |
wolfSSL | 13:f67a6c6013ca | 486 | const byte* ms, word32 msLen, |
wolfSSL | 13:f67a6c6013ca | 487 | const byte* sr, const byte* cr, |
wolfSSL | 13:f67a6c6013ca | 488 | int tls1_2, int hash_type, |
wolfSSL | 13:f67a6c6013ca | 489 | void* heap, int devId) |
wolfSSL | 13:f67a6c6013ca | 490 | { |
wolfSSL | 13:f67a6c6013ca | 491 | byte seed[SEED_LEN]; |
wolfSSL | 13:f67a6c6013ca | 492 | |
wolfSSL | 13:f67a6c6013ca | 493 | XMEMCPY(seed, sr, RAN_LEN); |
wolfSSL | 13:f67a6c6013ca | 494 | XMEMCPY(seed + RAN_LEN, cr, RAN_LEN); |
wolfSSL | 13:f67a6c6013ca | 495 | |
wolfSSL | 13:f67a6c6013ca | 496 | return PRF(key_dig, key_dig_len, ms, msLen, key_label, KEY_LABEL_SZ, |
wolfSSL | 13:f67a6c6013ca | 497 | seed, SEED_LEN, tls1_2, hash_type, heap, devId); |
wolfSSL | 13:f67a6c6013ca | 498 | } |
wolfSSL | 13:f67a6c6013ca | 499 | |
wolfSSL | 13:f67a6c6013ca | 500 | /* External facing wrapper so user can call as well, 0 on success */ |
wolfSSL | 13:f67a6c6013ca | 501 | int wolfSSL_DeriveTlsKeys(byte* key_dig, word32 key_dig_len, |
wolfSSL | 13:f67a6c6013ca | 502 | const byte* ms, word32 msLen, |
wolfSSL | 13:f67a6c6013ca | 503 | const byte* sr, const byte* cr, |
wolfSSL | 13:f67a6c6013ca | 504 | int tls1_2, int hash_type) |
wolfSSL | 13:f67a6c6013ca | 505 | { |
wolfSSL | 13:f67a6c6013ca | 506 | return _DeriveTlsKeys(key_dig, key_dig_len, ms, msLen, sr, cr, tls1_2, |
wolfSSL | 13:f67a6c6013ca | 507 | hash_type, NULL, INVALID_DEVID); |
wolfSSL | 13:f67a6c6013ca | 508 | } |
wolfSSL | 13:f67a6c6013ca | 509 | |
wolfSSL | 13:f67a6c6013ca | 510 | |
wolfSSL | 13:f67a6c6013ca | 511 | int DeriveTlsKeys(WOLFSSL* ssl) |
wolfSSL | 13:f67a6c6013ca | 512 | { |
wolfSSL | 13:f67a6c6013ca | 513 | int ret; |
wolfSSL | 13:f67a6c6013ca | 514 | int key_dig_len = 2 * ssl->specs.hash_size + |
wolfSSL | 13:f67a6c6013ca | 515 | 2 * ssl->specs.key_size + |
wolfSSL | 13:f67a6c6013ca | 516 | 2 * ssl->specs.iv_size; |
wolfSSL | 13:f67a6c6013ca | 517 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:f67a6c6013ca | 518 | byte* key_dig; |
wolfSSL | 13:f67a6c6013ca | 519 | #else |
wolfSSL | 13:f67a6c6013ca | 520 | byte key_dig[MAX_PRF_DIG]; |
wolfSSL | 13:f67a6c6013ca | 521 | #endif |
wolfSSL | 13:f67a6c6013ca | 522 | |
wolfSSL | 13:f67a6c6013ca | 523 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:f67a6c6013ca | 524 | key_dig = (byte*)XMALLOC(MAX_PRF_DIG, ssl->heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 525 | if (key_dig == NULL) { |
wolfSSL | 13:f67a6c6013ca | 526 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 527 | } |
wolfSSL | 13:f67a6c6013ca | 528 | #endif |
wolfSSL | 13:f67a6c6013ca | 529 | |
wolfSSL | 13:f67a6c6013ca | 530 | ret = _DeriveTlsKeys(key_dig, key_dig_len, |
wolfSSL | 13:f67a6c6013ca | 531 | ssl->arrays->masterSecret, SECRET_LEN, |
wolfSSL | 13:f67a6c6013ca | 532 | ssl->arrays->serverRandom, ssl->arrays->clientRandom, |
wolfSSL | 13:f67a6c6013ca | 533 | IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm, |
wolfSSL | 13:f67a6c6013ca | 534 | ssl->heap, ssl->devId); |
wolfSSL | 13:f67a6c6013ca | 535 | if (ret == 0) |
wolfSSL | 13:f67a6c6013ca | 536 | ret = StoreKeys(ssl, key_dig, PROVISION_CLIENT_SERVER); |
wolfSSL | 13:f67a6c6013ca | 537 | |
wolfSSL | 13:f67a6c6013ca | 538 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:f67a6c6013ca | 539 | XFREE(key_dig, ssl->heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 540 | #endif |
wolfSSL | 13:f67a6c6013ca | 541 | |
wolfSSL | 13:f67a6c6013ca | 542 | return ret; |
wolfSSL | 13:f67a6c6013ca | 543 | } |
wolfSSL | 13:f67a6c6013ca | 544 | |
wolfSSL | 13:f67a6c6013ca | 545 | static int _MakeTlsMasterSecret(byte* ms, word32 msLen, |
wolfSSL | 13:f67a6c6013ca | 546 | const byte* pms, word32 pmsLen, |
wolfSSL | 13:f67a6c6013ca | 547 | const byte* cr, const byte* sr, |
wolfSSL | 13:f67a6c6013ca | 548 | int tls1_2, int hash_type, |
wolfSSL | 13:f67a6c6013ca | 549 | void* heap, int devId) |
wolfSSL | 13:f67a6c6013ca | 550 | { |
wolfSSL | 13:f67a6c6013ca | 551 | byte seed[SEED_LEN]; |
wolfSSL | 13:f67a6c6013ca | 552 | |
wolfSSL | 13:f67a6c6013ca | 553 | XMEMCPY(seed, cr, RAN_LEN); |
wolfSSL | 13:f67a6c6013ca | 554 | XMEMCPY(seed + RAN_LEN, sr, RAN_LEN); |
wolfSSL | 13:f67a6c6013ca | 555 | |
wolfSSL | 13:f67a6c6013ca | 556 | return PRF(ms, msLen, pms, pmsLen, master_label, MASTER_LABEL_SZ, |
wolfSSL | 13:f67a6c6013ca | 557 | seed, SEED_LEN, tls1_2, hash_type, heap, devId); |
wolfSSL | 13:f67a6c6013ca | 558 | } |
wolfSSL | 13:f67a6c6013ca | 559 | |
wolfSSL | 13:f67a6c6013ca | 560 | /* External facing wrapper so user can call as well, 0 on success */ |
wolfSSL | 13:f67a6c6013ca | 561 | int wolfSSL_MakeTlsMasterSecret(byte* ms, word32 msLen, |
wolfSSL | 13:f67a6c6013ca | 562 | const byte* pms, word32 pmsLen, |
wolfSSL | 13:f67a6c6013ca | 563 | const byte* cr, const byte* sr, |
wolfSSL | 13:f67a6c6013ca | 564 | int tls1_2, int hash_type) |
wolfSSL | 13:f67a6c6013ca | 565 | { |
wolfSSL | 13:f67a6c6013ca | 566 | return _MakeTlsMasterSecret(ms, msLen, pms, pmsLen, cr, sr, tls1_2, |
wolfSSL | 13:f67a6c6013ca | 567 | hash_type, NULL, INVALID_DEVID); |
wolfSSL | 13:f67a6c6013ca | 568 | } |
wolfSSL | 13:f67a6c6013ca | 569 | |
wolfSSL | 13:f67a6c6013ca | 570 | |
wolfSSL | 13:f67a6c6013ca | 571 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:f67a6c6013ca | 572 | |
wolfSSL | 13:f67a6c6013ca | 573 | static int _MakeTlsExtendedMasterSecret(byte* ms, word32 msLen, |
wolfSSL | 13:f67a6c6013ca | 574 | const byte* pms, word32 pmsLen, |
wolfSSL | 13:f67a6c6013ca | 575 | const byte* sHash, word32 sHashLen, |
wolfSSL | 13:f67a6c6013ca | 576 | int tls1_2, int hash_type, |
wolfSSL | 13:f67a6c6013ca | 577 | void* heap, int devId) |
wolfSSL | 13:f67a6c6013ca | 578 | { |
wolfSSL | 13:f67a6c6013ca | 579 | return PRF(ms, msLen, pms, pmsLen, ext_master_label, EXT_MASTER_LABEL_SZ, |
wolfSSL | 13:f67a6c6013ca | 580 | sHash, sHashLen, tls1_2, hash_type, heap, devId); |
wolfSSL | 13:f67a6c6013ca | 581 | } |
wolfSSL | 13:f67a6c6013ca | 582 | |
wolfSSL | 13:f67a6c6013ca | 583 | /* External facing wrapper so user can call as well, 0 on success */ |
wolfSSL | 13:f67a6c6013ca | 584 | int wolfSSL_MakeTlsExtendedMasterSecret(byte* ms, word32 msLen, |
wolfSSL | 13:f67a6c6013ca | 585 | const byte* pms, word32 pmsLen, |
wolfSSL | 13:f67a6c6013ca | 586 | const byte* sHash, word32 sHashLen, |
wolfSSL | 13:f67a6c6013ca | 587 | int tls1_2, int hash_type) |
wolfSSL | 13:f67a6c6013ca | 588 | { |
wolfSSL | 13:f67a6c6013ca | 589 | return _MakeTlsExtendedMasterSecret(ms, msLen, pms, pmsLen, sHash, sHashLen, |
wolfSSL | 13:f67a6c6013ca | 590 | tls1_2, hash_type, NULL, INVALID_DEVID); |
wolfSSL | 13:f67a6c6013ca | 591 | } |
wolfSSL | 13:f67a6c6013ca | 592 | |
wolfSSL | 13:f67a6c6013ca | 593 | #endif /* HAVE_EXTENDED_MASTER */ |
wolfSSL | 13:f67a6c6013ca | 594 | |
wolfSSL | 13:f67a6c6013ca | 595 | |
wolfSSL | 13:f67a6c6013ca | 596 | int MakeTlsMasterSecret(WOLFSSL* ssl) |
wolfSSL | 13:f67a6c6013ca | 597 | { |
wolfSSL | 13:f67a6c6013ca | 598 | int ret; |
wolfSSL | 13:f67a6c6013ca | 599 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:f67a6c6013ca | 600 | if (ssl->options.haveEMS) { |
wolfSSL | 13:f67a6c6013ca | 601 | byte* handshake_hash; |
wolfSSL | 13:f67a6c6013ca | 602 | word32 hashSz = HSHASH_SZ; |
wolfSSL | 13:f67a6c6013ca | 603 | |
wolfSSL | 13:f67a6c6013ca | 604 | handshake_hash = (byte*)XMALLOC(HSHASH_SZ, ssl->heap, |
wolfSSL | 13:f67a6c6013ca | 605 | DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 606 | if (handshake_hash == NULL) |
wolfSSL | 13:f67a6c6013ca | 607 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 608 | |
wolfSSL | 13:f67a6c6013ca | 609 | ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz); |
wolfSSL | 13:f67a6c6013ca | 610 | if (ret < 0) { |
wolfSSL | 13:f67a6c6013ca | 611 | XFREE(handshake_hash, ssl->heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 612 | return ret; |
wolfSSL | 13:f67a6c6013ca | 613 | } |
wolfSSL | 13:f67a6c6013ca | 614 | |
wolfSSL | 13:f67a6c6013ca | 615 | ret = _MakeTlsExtendedMasterSecret( |
wolfSSL | 13:f67a6c6013ca | 616 | ssl->arrays->masterSecret, SECRET_LEN, |
wolfSSL | 13:f67a6c6013ca | 617 | ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz, |
wolfSSL | 13:f67a6c6013ca | 618 | handshake_hash, hashSz, |
wolfSSL | 13:f67a6c6013ca | 619 | IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm, |
wolfSSL | 13:f67a6c6013ca | 620 | ssl->heap, ssl->devId); |
wolfSSL | 13:f67a6c6013ca | 621 | |
wolfSSL | 13:f67a6c6013ca | 622 | XFREE(handshake_hash, ssl->heap, DYNAMIC_TYPE_DIGEST); |
wolfSSL | 13:f67a6c6013ca | 623 | } else |
wolfSSL | 13:f67a6c6013ca | 624 | #endif |
wolfSSL | 13:f67a6c6013ca | 625 | ret = _MakeTlsMasterSecret(ssl->arrays->masterSecret, SECRET_LEN, |
wolfSSL | 13:f67a6c6013ca | 626 | ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz, |
wolfSSL | 13:f67a6c6013ca | 627 | ssl->arrays->clientRandom, ssl->arrays->serverRandom, |
wolfSSL | 13:f67a6c6013ca | 628 | IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm, |
wolfSSL | 13:f67a6c6013ca | 629 | ssl->heap, ssl->devId); |
wolfSSL | 13:f67a6c6013ca | 630 | |
wolfSSL | 13:f67a6c6013ca | 631 | if (ret == 0) { |
wolfSSL | 13:f67a6c6013ca | 632 | #ifdef SHOW_SECRETS |
wolfSSL | 13:f67a6c6013ca | 633 | int i; |
wolfSSL | 13:f67a6c6013ca | 634 | |
wolfSSL | 13:f67a6c6013ca | 635 | printf("master secret: "); |
wolfSSL | 13:f67a6c6013ca | 636 | for (i = 0; i < SECRET_LEN; i++) |
wolfSSL | 13:f67a6c6013ca | 637 | printf("%02x", ssl->arrays->masterSecret[i]); |
wolfSSL | 13:f67a6c6013ca | 638 | printf("\n"); |
wolfSSL | 13:f67a6c6013ca | 639 | #endif |
wolfSSL | 13:f67a6c6013ca | 640 | |
wolfSSL | 13:f67a6c6013ca | 641 | ret = DeriveTlsKeys(ssl); |
wolfSSL | 13:f67a6c6013ca | 642 | } |
wolfSSL | 13:f67a6c6013ca | 643 | |
wolfSSL | 13:f67a6c6013ca | 644 | return ret; |
wolfSSL | 13:f67a6c6013ca | 645 | } |
wolfSSL | 13:f67a6c6013ca | 646 | |
wolfSSL | 13:f67a6c6013ca | 647 | |
wolfSSL | 13:f67a6c6013ca | 648 | /* Used by EAP-TLS and EAP-TTLS to derive keying material from |
wolfSSL | 13:f67a6c6013ca | 649 | * the master_secret. */ |
wolfSSL | 13:f67a6c6013ca | 650 | int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* msk, unsigned int len, |
wolfSSL | 13:f67a6c6013ca | 651 | const char* label) |
wolfSSL | 13:f67a6c6013ca | 652 | { |
wolfSSL | 13:f67a6c6013ca | 653 | int ret; |
wolfSSL | 13:f67a6c6013ca | 654 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:f67a6c6013ca | 655 | byte* seed; |
wolfSSL | 13:f67a6c6013ca | 656 | #else |
wolfSSL | 13:f67a6c6013ca | 657 | byte seed[SEED_LEN]; |
wolfSSL | 13:f67a6c6013ca | 658 | #endif |
wolfSSL | 13:f67a6c6013ca | 659 | |
wolfSSL | 13:f67a6c6013ca | 660 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:f67a6c6013ca | 661 | seed = (byte*)XMALLOC(SEED_LEN, ssl->heap, DYNAMIC_TYPE_SEED); |
wolfSSL | 13:f67a6c6013ca | 662 | if (seed == NULL) |
wolfSSL | 13:f67a6c6013ca | 663 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 664 | #endif |
wolfSSL | 13:f67a6c6013ca | 665 | |
wolfSSL | 13:f67a6c6013ca | 666 | /* |
wolfSSL | 13:f67a6c6013ca | 667 | * As per RFC-5281, the order of the client and server randoms is reversed |
wolfSSL | 13:f67a6c6013ca | 668 | * from that used by the TLS protocol to derive keys. |
wolfSSL | 13:f67a6c6013ca | 669 | */ |
wolfSSL | 13:f67a6c6013ca | 670 | XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN); |
wolfSSL | 13:f67a6c6013ca | 671 | XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN); |
wolfSSL | 13:f67a6c6013ca | 672 | |
wolfSSL | 13:f67a6c6013ca | 673 | ret = PRF((byte*)msk, len, ssl->arrays->masterSecret, SECRET_LEN, |
wolfSSL | 13:f67a6c6013ca | 674 | (const byte *)label, (word32)XSTRLEN(label), seed, SEED_LEN, |
wolfSSL | 13:f67a6c6013ca | 675 | IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm, |
wolfSSL | 13:f67a6c6013ca | 676 | ssl->heap, ssl->devId); |
wolfSSL | 13:f67a6c6013ca | 677 | |
wolfSSL | 13:f67a6c6013ca | 678 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:f67a6c6013ca | 679 | XFREE(seed, ssl->heap, DYNAMIC_TYPE_SEED); |
wolfSSL | 13:f67a6c6013ca | 680 | #endif |
wolfSSL | 13:f67a6c6013ca | 681 | |
wolfSSL | 13:f67a6c6013ca | 682 | return ret; |
wolfSSL | 13:f67a6c6013ca | 683 | } |
wolfSSL | 13:f67a6c6013ca | 684 | |
wolfSSL | 13:f67a6c6013ca | 685 | |
wolfSSL | 13:f67a6c6013ca | 686 | /*** next for static INLINE s copied internal.c ***/ |
wolfSSL | 13:f67a6c6013ca | 687 | |
wolfSSL | 13:f67a6c6013ca | 688 | /* convert 16 bit integer to opaque */ |
wolfSSL | 13:f67a6c6013ca | 689 | static INLINE void c16toa(word16 u16, byte* c) |
wolfSSL | 13:f67a6c6013ca | 690 | { |
wolfSSL | 13:f67a6c6013ca | 691 | c[0] = (u16 >> 8) & 0xff; |
wolfSSL | 13:f67a6c6013ca | 692 | c[1] = u16 & 0xff; |
wolfSSL | 13:f67a6c6013ca | 693 | } |
wolfSSL | 13:f67a6c6013ca | 694 | |
wolfSSL | 13:f67a6c6013ca | 695 | #ifdef HAVE_TLS_EXTENSIONS |
wolfSSL | 13:f67a6c6013ca | 696 | /* convert opaque to 16 bit integer */ |
wolfSSL | 13:f67a6c6013ca | 697 | static INLINE void ato16(const byte* c, word16* u16) |
wolfSSL | 13:f67a6c6013ca | 698 | { |
wolfSSL | 13:f67a6c6013ca | 699 | *u16 = (c[0] << 8) | (c[1]); |
wolfSSL | 13:f67a6c6013ca | 700 | } |
wolfSSL | 13:f67a6c6013ca | 701 | |
wolfSSL | 13:f67a6c6013ca | 702 | #if defined(HAVE_SNI) && !defined(NO_WOLFSSL_SERVER) |
wolfSSL | 13:f67a6c6013ca | 703 | /* convert a 24 bit integer into a 32 bit one */ |
wolfSSL | 13:f67a6c6013ca | 704 | static INLINE void c24to32(const word24 u24, word32* u32) |
wolfSSL | 13:f67a6c6013ca | 705 | { |
wolfSSL | 13:f67a6c6013ca | 706 | *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2]; |
wolfSSL | 13:f67a6c6013ca | 707 | } |
wolfSSL | 13:f67a6c6013ca | 708 | #endif |
wolfSSL | 13:f67a6c6013ca | 709 | |
wolfSSL | 13:f67a6c6013ca | 710 | #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)) |
wolfSSL | 13:f67a6c6013ca | 711 | /* Convert opaque data to a 32-bit unsigned integer. |
wolfSSL | 13:f67a6c6013ca | 712 | * |
wolfSSL | 13:f67a6c6013ca | 713 | * c The opaque data holding a 32-bit integer. |
wolfSSL | 13:f67a6c6013ca | 714 | * u32 The 32-bit unsigned integer. |
wolfSSL | 13:f67a6c6013ca | 715 | */ |
wolfSSL | 13:f67a6c6013ca | 716 | static INLINE void ato32(const byte* c, word32* u32) |
wolfSSL | 13:f67a6c6013ca | 717 | { |
wolfSSL | 13:f67a6c6013ca | 718 | *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; |
wolfSSL | 13:f67a6c6013ca | 719 | } |
wolfSSL | 13:f67a6c6013ca | 720 | #endif |
wolfSSL | 13:f67a6c6013ca | 721 | #endif /* HAVE_TLS_EXTENSIONS */ |
wolfSSL | 13:f67a6c6013ca | 722 | |
wolfSSL | 13:f67a6c6013ca | 723 | /* convert 32 bit integer to opaque */ |
wolfSSL | 13:f67a6c6013ca | 724 | static INLINE void c32toa(word32 u32, byte* c) |
wolfSSL | 13:f67a6c6013ca | 725 | { |
wolfSSL | 13:f67a6c6013ca | 726 | c[0] = (u32 >> 24) & 0xff; |
wolfSSL | 13:f67a6c6013ca | 727 | c[1] = (u32 >> 16) & 0xff; |
wolfSSL | 13:f67a6c6013ca | 728 | c[2] = (u32 >> 8) & 0xff; |
wolfSSL | 13:f67a6c6013ca | 729 | c[3] = u32 & 0xff; |
wolfSSL | 13:f67a6c6013ca | 730 | } |
wolfSSL | 13:f67a6c6013ca | 731 | |
wolfSSL | 13:f67a6c6013ca | 732 | |
wolfSSL | 13:f67a6c6013ca | 733 | static INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2]) |
wolfSSL | 13:f67a6c6013ca | 734 | { |
wolfSSL | 13:f67a6c6013ca | 735 | if (verify) { |
wolfSSL | 13:f67a6c6013ca | 736 | seq[0] = ssl->keys.peer_sequence_number_hi; |
wolfSSL | 13:f67a6c6013ca | 737 | seq[1] = ssl->keys.peer_sequence_number_lo++; |
wolfSSL | 13:f67a6c6013ca | 738 | if (seq[1] > ssl->keys.peer_sequence_number_lo) { |
wolfSSL | 13:f67a6c6013ca | 739 | /* handle rollover */ |
wolfSSL | 13:f67a6c6013ca | 740 | ssl->keys.peer_sequence_number_hi++; |
wolfSSL | 13:f67a6c6013ca | 741 | } |
wolfSSL | 13:f67a6c6013ca | 742 | } |
wolfSSL | 13:f67a6c6013ca | 743 | else { |
wolfSSL | 13:f67a6c6013ca | 744 | seq[0] = ssl->keys.sequence_number_hi; |
wolfSSL | 13:f67a6c6013ca | 745 | seq[1] = ssl->keys.sequence_number_lo++; |
wolfSSL | 13:f67a6c6013ca | 746 | if (seq[1] > ssl->keys.sequence_number_lo) { |
wolfSSL | 13:f67a6c6013ca | 747 | /* handle rollover */ |
wolfSSL | 13:f67a6c6013ca | 748 | ssl->keys.sequence_number_hi++; |
wolfSSL | 13:f67a6c6013ca | 749 | } |
wolfSSL | 13:f67a6c6013ca | 750 | } |
wolfSSL | 13:f67a6c6013ca | 751 | } |
wolfSSL | 13:f67a6c6013ca | 752 | |
wolfSSL | 13:f67a6c6013ca | 753 | |
wolfSSL | 13:f67a6c6013ca | 754 | #ifdef WOLFSSL_DTLS |
wolfSSL | 13:f67a6c6013ca | 755 | static INLINE void DtlsGetSEQ(WOLFSSL* ssl, int order, word32 seq[2]) |
wolfSSL | 13:f67a6c6013ca | 756 | { |
wolfSSL | 13:f67a6c6013ca | 757 | if (order == PREV_ORDER) { |
wolfSSL | 13:f67a6c6013ca | 758 | /* Previous epoch case */ |
wolfSSL | 13:f67a6c6013ca | 759 | seq[0] = ((ssl->keys.dtls_epoch - 1) << 16) | |
wolfSSL | 13:f67a6c6013ca | 760 | (ssl->keys.dtls_prev_sequence_number_hi & 0xFFFF); |
wolfSSL | 13:f67a6c6013ca | 761 | seq[1] = ssl->keys.dtls_prev_sequence_number_lo; |
wolfSSL | 13:f67a6c6013ca | 762 | } |
wolfSSL | 13:f67a6c6013ca | 763 | else if (order == PEER_ORDER) { |
wolfSSL | 13:f67a6c6013ca | 764 | seq[0] = (ssl->keys.curEpoch << 16) | |
wolfSSL | 13:f67a6c6013ca | 765 | (ssl->keys.curSeq_hi & 0xFFFF); |
wolfSSL | 13:f67a6c6013ca | 766 | seq[1] = ssl->keys.curSeq_lo; /* explicit from peer */ |
wolfSSL | 13:f67a6c6013ca | 767 | } |
wolfSSL | 13:f67a6c6013ca | 768 | else { |
wolfSSL | 13:f67a6c6013ca | 769 | seq[0] = (ssl->keys.dtls_epoch << 16) | |
wolfSSL | 13:f67a6c6013ca | 770 | (ssl->keys.dtls_sequence_number_hi & 0xFFFF); |
wolfSSL | 13:f67a6c6013ca | 771 | seq[1] = ssl->keys.dtls_sequence_number_lo; |
wolfSSL | 13:f67a6c6013ca | 772 | } |
wolfSSL | 13:f67a6c6013ca | 773 | } |
wolfSSL | 13:f67a6c6013ca | 774 | #endif /* WOLFSSL_DTLS */ |
wolfSSL | 13:f67a6c6013ca | 775 | |
wolfSSL | 13:f67a6c6013ca | 776 | |
wolfSSL | 13:f67a6c6013ca | 777 | static INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out) |
wolfSSL | 13:f67a6c6013ca | 778 | { |
wolfSSL | 13:f67a6c6013ca | 779 | word32 seq[2] = {0, 0}; |
wolfSSL | 13:f67a6c6013ca | 780 | |
wolfSSL | 13:f67a6c6013ca | 781 | if (!ssl->options.dtls) { |
wolfSSL | 13:f67a6c6013ca | 782 | GetSEQIncrement(ssl, verifyOrder, seq); |
wolfSSL | 13:f67a6c6013ca | 783 | } |
wolfSSL | 13:f67a6c6013ca | 784 | else { |
wolfSSL | 13:f67a6c6013ca | 785 | #ifdef WOLFSSL_DTLS |
wolfSSL | 13:f67a6c6013ca | 786 | DtlsGetSEQ(ssl, verifyOrder, seq); |
wolfSSL | 13:f67a6c6013ca | 787 | #endif |
wolfSSL | 13:f67a6c6013ca | 788 | } |
wolfSSL | 13:f67a6c6013ca | 789 | |
wolfSSL | 13:f67a6c6013ca | 790 | c32toa(seq[0], out); |
wolfSSL | 13:f67a6c6013ca | 791 | c32toa(seq[1], out + OPAQUE32_LEN); |
wolfSSL | 13:f67a6c6013ca | 792 | } |
wolfSSL | 13:f67a6c6013ca | 793 | |
wolfSSL | 13:f67a6c6013ca | 794 | |
wolfSSL | 13:f67a6c6013ca | 795 | /*** end copy ***/ |
wolfSSL | 13:f67a6c6013ca | 796 | |
wolfSSL | 13:f67a6c6013ca | 797 | |
wolfSSL | 13:f67a6c6013ca | 798 | /* return HMAC digest type in wolfSSL format */ |
wolfSSL | 13:f67a6c6013ca | 799 | int wolfSSL_GetHmacType(WOLFSSL* ssl) |
wolfSSL | 13:f67a6c6013ca | 800 | { |
wolfSSL | 13:f67a6c6013ca | 801 | if (ssl == NULL) |
wolfSSL | 13:f67a6c6013ca | 802 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 803 | |
wolfSSL | 13:f67a6c6013ca | 804 | switch (ssl->specs.mac_algorithm) { |
wolfSSL | 13:f67a6c6013ca | 805 | #ifndef NO_MD5 |
wolfSSL | 13:f67a6c6013ca | 806 | case md5_mac: |
wolfSSL | 13:f67a6c6013ca | 807 | { |
wolfSSL | 13:f67a6c6013ca | 808 | return MD5; |
wolfSSL | 13:f67a6c6013ca | 809 | } |
wolfSSL | 13:f67a6c6013ca | 810 | #endif |
wolfSSL | 13:f67a6c6013ca | 811 | #ifndef NO_SHA256 |
wolfSSL | 13:f67a6c6013ca | 812 | case sha256_mac: |
wolfSSL | 13:f67a6c6013ca | 813 | { |
wolfSSL | 13:f67a6c6013ca | 814 | return SHA256; |
wolfSSL | 13:f67a6c6013ca | 815 | } |
wolfSSL | 13:f67a6c6013ca | 816 | #endif |
wolfSSL | 13:f67a6c6013ca | 817 | #ifdef WOLFSSL_SHA384 |
wolfSSL | 13:f67a6c6013ca | 818 | case sha384_mac: |
wolfSSL | 13:f67a6c6013ca | 819 | { |
wolfSSL | 13:f67a6c6013ca | 820 | return SHA384; |
wolfSSL | 13:f67a6c6013ca | 821 | } |
wolfSSL | 13:f67a6c6013ca | 822 | |
wolfSSL | 13:f67a6c6013ca | 823 | #endif |
wolfSSL | 13:f67a6c6013ca | 824 | #ifndef NO_SHA |
wolfSSL | 13:f67a6c6013ca | 825 | case sha_mac: |
wolfSSL | 13:f67a6c6013ca | 826 | { |
wolfSSL | 13:f67a6c6013ca | 827 | return SHA; |
wolfSSL | 13:f67a6c6013ca | 828 | } |
wolfSSL | 13:f67a6c6013ca | 829 | #endif |
wolfSSL | 13:f67a6c6013ca | 830 | #ifdef HAVE_BLAKE2 |
wolfSSL | 13:f67a6c6013ca | 831 | case blake2b_mac: |
wolfSSL | 13:f67a6c6013ca | 832 | { |
wolfSSL | 13:f67a6c6013ca | 833 | return BLAKE2B_ID; |
wolfSSL | 13:f67a6c6013ca | 834 | } |
wolfSSL | 13:f67a6c6013ca | 835 | #endif |
wolfSSL | 13:f67a6c6013ca | 836 | default: |
wolfSSL | 13:f67a6c6013ca | 837 | { |
wolfSSL | 13:f67a6c6013ca | 838 | return SSL_FATAL_ERROR; |
wolfSSL | 13:f67a6c6013ca | 839 | } |
wolfSSL | 13:f67a6c6013ca | 840 | } |
wolfSSL | 13:f67a6c6013ca | 841 | } |
wolfSSL | 13:f67a6c6013ca | 842 | |
wolfSSL | 13:f67a6c6013ca | 843 | |
wolfSSL | 13:f67a6c6013ca | 844 | int wolfSSL_SetTlsHmacInner(WOLFSSL* ssl, byte* inner, word32 sz, int content, |
wolfSSL | 13:f67a6c6013ca | 845 | int verify) |
wolfSSL | 13:f67a6c6013ca | 846 | { |
wolfSSL | 13:f67a6c6013ca | 847 | if (ssl == NULL || inner == NULL) |
wolfSSL | 13:f67a6c6013ca | 848 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 849 | |
wolfSSL | 13:f67a6c6013ca | 850 | XMEMSET(inner, 0, WOLFSSL_TLS_HMAC_INNER_SZ); |
wolfSSL | 13:f67a6c6013ca | 851 | |
wolfSSL | 13:f67a6c6013ca | 852 | WriteSEQ(ssl, verify, inner); |
wolfSSL | 13:f67a6c6013ca | 853 | inner[SEQ_SZ] = (byte)content; |
wolfSSL | 13:f67a6c6013ca | 854 | inner[SEQ_SZ + ENUM_LEN] = ssl->version.major; |
wolfSSL | 13:f67a6c6013ca | 855 | inner[SEQ_SZ + ENUM_LEN + ENUM_LEN] = ssl->version.minor; |
wolfSSL | 13:f67a6c6013ca | 856 | c16toa((word16)sz, inner + SEQ_SZ + ENUM_LEN + VERSION_SZ); |
wolfSSL | 13:f67a6c6013ca | 857 | |
wolfSSL | 13:f67a6c6013ca | 858 | return 0; |
wolfSSL | 13:f67a6c6013ca | 859 | } |
wolfSSL | 13:f67a6c6013ca | 860 | |
wolfSSL | 13:f67a6c6013ca | 861 | |
wolfSSL | 13:f67a6c6013ca | 862 | /* TLS type HMAC */ |
wolfSSL | 13:f67a6c6013ca | 863 | int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, |
wolfSSL | 13:f67a6c6013ca | 864 | int content, int verify) |
wolfSSL | 13:f67a6c6013ca | 865 | { |
wolfSSL | 13:f67a6c6013ca | 866 | Hmac hmac; |
wolfSSL | 13:f67a6c6013ca | 867 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 868 | byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ]; |
wolfSSL | 13:f67a6c6013ca | 869 | |
wolfSSL | 13:f67a6c6013ca | 870 | if (ssl == NULL) |
wolfSSL | 13:f67a6c6013ca | 871 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 872 | |
wolfSSL | 13:f67a6c6013ca | 873 | #ifdef HAVE_FUZZER |
wolfSSL | 13:f67a6c6013ca | 874 | if (ssl->fuzzerCb) |
wolfSSL | 13:f67a6c6013ca | 875 | ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx); |
wolfSSL | 13:f67a6c6013ca | 876 | #endif |
wolfSSL | 13:f67a6c6013ca | 877 | |
wolfSSL | 13:f67a6c6013ca | 878 | wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify); |
wolfSSL | 13:f67a6c6013ca | 879 | |
wolfSSL | 13:f67a6c6013ca | 880 | ret = wc_HmacInit(&hmac, ssl->heap, ssl->devId); |
wolfSSL | 13:f67a6c6013ca | 881 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 882 | return ret; |
wolfSSL | 13:f67a6c6013ca | 883 | |
wolfSSL | 13:f67a6c6013ca | 884 | ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl), |
wolfSSL | 13:f67a6c6013ca | 885 | wolfSSL_GetMacSecret(ssl, verify), ssl->specs.hash_size); |
wolfSSL | 13:f67a6c6013ca | 886 | if (ret == 0) { |
wolfSSL | 13:f67a6c6013ca | 887 | ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner)); |
wolfSSL | 13:f67a6c6013ca | 888 | if (ret == 0) |
wolfSSL | 13:f67a6c6013ca | 889 | ret = wc_HmacUpdate(&hmac, in, sz); /* content */ |
wolfSSL | 13:f67a6c6013ca | 890 | if (ret == 0) |
wolfSSL | 13:f67a6c6013ca | 891 | ret = wc_HmacFinal(&hmac, digest); |
wolfSSL | 13:f67a6c6013ca | 892 | } |
wolfSSL | 13:f67a6c6013ca | 893 | wc_HmacFree(&hmac); |
wolfSSL | 13:f67a6c6013ca | 894 | |
wolfSSL | 13:f67a6c6013ca | 895 | return ret; |
wolfSSL | 13:f67a6c6013ca | 896 | } |
wolfSSL | 13:f67a6c6013ca | 897 | |
wolfSSL | 13:f67a6c6013ca | 898 | #ifdef HAVE_TLS_EXTENSIONS |
wolfSSL | 13:f67a6c6013ca | 899 | |
wolfSSL | 13:f67a6c6013ca | 900 | /** |
wolfSSL | 13:f67a6c6013ca | 901 | * The TLSX semaphore is used to calculate the size of the extensions to be sent |
wolfSSL | 13:f67a6c6013ca | 902 | * from one peer to another. |
wolfSSL | 13:f67a6c6013ca | 903 | */ |
wolfSSL | 13:f67a6c6013ca | 904 | |
wolfSSL | 13:f67a6c6013ca | 905 | /** Supports up to 64 flags. Increase as needed. */ |
wolfSSL | 13:f67a6c6013ca | 906 | #define SEMAPHORE_SIZE 8 |
wolfSSL | 13:f67a6c6013ca | 907 | |
wolfSSL | 13:f67a6c6013ca | 908 | /** |
wolfSSL | 13:f67a6c6013ca | 909 | * Converts the extension type (id) to an index in the semaphore. |
wolfSSL | 13:f67a6c6013ca | 910 | * |
wolfSSL | 13:f67a6c6013ca | 911 | * Oficial reference for TLS extension types: |
wolfSSL | 13:f67a6c6013ca | 912 | * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xml |
wolfSSL | 13:f67a6c6013ca | 913 | * |
wolfSSL | 13:f67a6c6013ca | 914 | * Motivation: |
wolfSSL | 13:f67a6c6013ca | 915 | * Previously, we used the extension type itself as the index of that |
wolfSSL | 13:f67a6c6013ca | 916 | * extension in the semaphore as the extension types were declared |
wolfSSL | 13:f67a6c6013ca | 917 | * sequentially, but maintain a semaphore as big as the number of available |
wolfSSL | 13:f67a6c6013ca | 918 | * extensions is no longer an option since the release of renegotiation_info. |
wolfSSL | 13:f67a6c6013ca | 919 | * |
wolfSSL | 13:f67a6c6013ca | 920 | * How to update: |
wolfSSL | 13:f67a6c6013ca | 921 | * Assign extension types that extrapolate the number of available semaphores |
wolfSSL | 13:f67a6c6013ca | 922 | * to the first available index going backwards in the semaphore array. |
wolfSSL | 13:f67a6c6013ca | 923 | * When adding a new extension type that don't extrapolate the number of |
wolfSSL | 13:f67a6c6013ca | 924 | * available semaphores, check for a possible collision with with a |
wolfSSL | 13:f67a6c6013ca | 925 | * 'remapped' extension type. |
wolfSSL | 13:f67a6c6013ca | 926 | */ |
wolfSSL | 13:f67a6c6013ca | 927 | static INLINE word16 TLSX_ToSemaphore(word16 type) |
wolfSSL | 13:f67a6c6013ca | 928 | { |
wolfSSL | 13:f67a6c6013ca | 929 | switch (type) { |
wolfSSL | 13:f67a6c6013ca | 930 | |
wolfSSL | 13:f67a6c6013ca | 931 | case TLSX_RENEGOTIATION_INFO: /* 0xFF01 */ |
wolfSSL | 13:f67a6c6013ca | 932 | return 63; |
wolfSSL | 13:f67a6c6013ca | 933 | |
wolfSSL | 13:f67a6c6013ca | 934 | default: |
wolfSSL | 13:f67a6c6013ca | 935 | if (type > 62) { |
wolfSSL | 13:f67a6c6013ca | 936 | /* This message SHOULD only happens during the adding of |
wolfSSL | 13:f67a6c6013ca | 937 | new TLS extensions in which its IANA number overflows |
wolfSSL | 13:f67a6c6013ca | 938 | the current semaphore's range, or if its number already |
wolfSSL | 13:f67a6c6013ca | 939 | is assigned to be used by another extension. |
wolfSSL | 13:f67a6c6013ca | 940 | Use this check value for the new extension and decrement |
wolfSSL | 13:f67a6c6013ca | 941 | the check value by one. */ |
wolfSSL | 13:f67a6c6013ca | 942 | WOLFSSL_MSG("### TLSX semaphore colision or overflow detected!"); |
wolfSSL | 13:f67a6c6013ca | 943 | } |
wolfSSL | 13:f67a6c6013ca | 944 | } |
wolfSSL | 13:f67a6c6013ca | 945 | |
wolfSSL | 13:f67a6c6013ca | 946 | return type; |
wolfSSL | 13:f67a6c6013ca | 947 | } |
wolfSSL | 13:f67a6c6013ca | 948 | |
wolfSSL | 13:f67a6c6013ca | 949 | /** Checks if a specific light (tls extension) is not set in the semaphore. */ |
wolfSSL | 13:f67a6c6013ca | 950 | #define IS_OFF(semaphore, light) \ |
wolfSSL | 13:f67a6c6013ca | 951 | (!(((semaphore)[(light) / 8] & (byte) (0x01 << ((light) % 8))))) |
wolfSSL | 13:f67a6c6013ca | 952 | |
wolfSSL | 13:f67a6c6013ca | 953 | /** Turn on a specific light (tls extension) in the semaphore. */ |
wolfSSL | 13:f67a6c6013ca | 954 | #define TURN_ON(semaphore, light) \ |
wolfSSL | 13:f67a6c6013ca | 955 | ((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8))) |
wolfSSL | 13:f67a6c6013ca | 956 | |
wolfSSL | 13:f67a6c6013ca | 957 | /** Turn off a specific light (tls extension) in the semaphore. */ |
wolfSSL | 13:f67a6c6013ca | 958 | #define TURN_OFF(semaphore, light) \ |
wolfSSL | 13:f67a6c6013ca | 959 | ((semaphore)[(light) / 8] &= (byte) ~(0x01 << ((light) % 8))) |
wolfSSL | 13:f67a6c6013ca | 960 | |
wolfSSL | 13:f67a6c6013ca | 961 | /** Creates a new extension. */ |
wolfSSL | 13:f67a6c6013ca | 962 | static TLSX* TLSX_New(TLSX_Type type, void* data, void* heap) |
wolfSSL | 13:f67a6c6013ca | 963 | { |
wolfSSL | 13:f67a6c6013ca | 964 | TLSX* extension = (TLSX*)XMALLOC(sizeof(TLSX), heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 965 | |
wolfSSL | 13:f67a6c6013ca | 966 | if (extension) { |
wolfSSL | 13:f67a6c6013ca | 967 | extension->type = type; |
wolfSSL | 13:f67a6c6013ca | 968 | extension->data = data; |
wolfSSL | 13:f67a6c6013ca | 969 | extension->resp = 0; |
wolfSSL | 13:f67a6c6013ca | 970 | extension->next = NULL; |
wolfSSL | 13:f67a6c6013ca | 971 | } |
wolfSSL | 13:f67a6c6013ca | 972 | |
wolfSSL | 13:f67a6c6013ca | 973 | return extension; |
wolfSSL | 13:f67a6c6013ca | 974 | } |
wolfSSL | 13:f67a6c6013ca | 975 | |
wolfSSL | 13:f67a6c6013ca | 976 | /** |
wolfSSL | 13:f67a6c6013ca | 977 | * Creates a new extension and pushes it to the provided list. |
wolfSSL | 13:f67a6c6013ca | 978 | * Checks for duplicate extensions, keeps the newest. |
wolfSSL | 13:f67a6c6013ca | 979 | */ |
wolfSSL | 13:f67a6c6013ca | 980 | static int TLSX_Push(TLSX** list, TLSX_Type type, void* data, void* heap) |
wolfSSL | 13:f67a6c6013ca | 981 | { |
wolfSSL | 13:f67a6c6013ca | 982 | TLSX* extension = TLSX_New(type, data, heap); |
wolfSSL | 13:f67a6c6013ca | 983 | |
wolfSSL | 13:f67a6c6013ca | 984 | if (extension == NULL) |
wolfSSL | 13:f67a6c6013ca | 985 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 986 | |
wolfSSL | 13:f67a6c6013ca | 987 | /* pushes the new extension on the list. */ |
wolfSSL | 13:f67a6c6013ca | 988 | extension->next = *list; |
wolfSSL | 13:f67a6c6013ca | 989 | *list = extension; |
wolfSSL | 13:f67a6c6013ca | 990 | |
wolfSSL | 13:f67a6c6013ca | 991 | /* remove duplicate extensions, there should be only one of each type. */ |
wolfSSL | 13:f67a6c6013ca | 992 | do { |
wolfSSL | 13:f67a6c6013ca | 993 | if (extension->next && extension->next->type == type) { |
wolfSSL | 13:f67a6c6013ca | 994 | TLSX *next = extension->next; |
wolfSSL | 13:f67a6c6013ca | 995 | |
wolfSSL | 13:f67a6c6013ca | 996 | extension->next = next->next; |
wolfSSL | 13:f67a6c6013ca | 997 | next->next = NULL; |
wolfSSL | 13:f67a6c6013ca | 998 | |
wolfSSL | 13:f67a6c6013ca | 999 | TLSX_FreeAll(next, heap); |
wolfSSL | 13:f67a6c6013ca | 1000 | |
wolfSSL | 13:f67a6c6013ca | 1001 | /* there is no way to occur more than */ |
wolfSSL | 13:f67a6c6013ca | 1002 | /* two extensions of the same type. */ |
wolfSSL | 13:f67a6c6013ca | 1003 | break; |
wolfSSL | 13:f67a6c6013ca | 1004 | } |
wolfSSL | 13:f67a6c6013ca | 1005 | } while ((extension = extension->next)); |
wolfSSL | 13:f67a6c6013ca | 1006 | |
wolfSSL | 13:f67a6c6013ca | 1007 | return 0; |
wolfSSL | 13:f67a6c6013ca | 1008 | } |
wolfSSL | 13:f67a6c6013ca | 1009 | |
wolfSSL | 13:f67a6c6013ca | 1010 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 1011 | |
wolfSSL | 13:f67a6c6013ca | 1012 | /** Mark an extension to be sent back to the client. */ |
wolfSSL | 13:f67a6c6013ca | 1013 | void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type); |
wolfSSL | 13:f67a6c6013ca | 1014 | |
wolfSSL | 13:f67a6c6013ca | 1015 | void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type) |
wolfSSL | 13:f67a6c6013ca | 1016 | { |
wolfSSL | 13:f67a6c6013ca | 1017 | TLSX *ext = TLSX_Find(ssl->extensions, type); |
wolfSSL | 13:f67a6c6013ca | 1018 | |
wolfSSL | 13:f67a6c6013ca | 1019 | if (ext) |
wolfSSL | 13:f67a6c6013ca | 1020 | ext->resp = 1; |
wolfSSL | 13:f67a6c6013ca | 1021 | } |
wolfSSL | 13:f67a6c6013ca | 1022 | |
wolfSSL | 13:f67a6c6013ca | 1023 | #endif |
wolfSSL | 13:f67a6c6013ca | 1024 | |
wolfSSL | 13:f67a6c6013ca | 1025 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 1026 | /* Application-Layer Protocol Negotiation */ |
wolfSSL | 13:f67a6c6013ca | 1027 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 1028 | |
wolfSSL | 13:f67a6c6013ca | 1029 | #ifdef HAVE_ALPN |
wolfSSL | 13:f67a6c6013ca | 1030 | /** Creates a new ALPN object, providing protocol name to use. */ |
wolfSSL | 13:f67a6c6013ca | 1031 | static ALPN* TLSX_ALPN_New(char *protocol_name, word16 protocol_nameSz, |
wolfSSL | 13:f67a6c6013ca | 1032 | void* heap) |
wolfSSL | 13:f67a6c6013ca | 1033 | { |
wolfSSL | 13:f67a6c6013ca | 1034 | ALPN *alpn; |
wolfSSL | 13:f67a6c6013ca | 1035 | |
wolfSSL | 13:f67a6c6013ca | 1036 | WOLFSSL_ENTER("TLSX_ALPN_New"); |
wolfSSL | 13:f67a6c6013ca | 1037 | |
wolfSSL | 13:f67a6c6013ca | 1038 | if (protocol_name == NULL || |
wolfSSL | 13:f67a6c6013ca | 1039 | protocol_nameSz > WOLFSSL_MAX_ALPN_PROTO_NAME_LEN) { |
wolfSSL | 13:f67a6c6013ca | 1040 | WOLFSSL_MSG("Invalid arguments"); |
wolfSSL | 13:f67a6c6013ca | 1041 | return NULL; |
wolfSSL | 13:f67a6c6013ca | 1042 | } |
wolfSSL | 13:f67a6c6013ca | 1043 | |
wolfSSL | 13:f67a6c6013ca | 1044 | alpn = (ALPN*)XMALLOC(sizeof(ALPN), heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 1045 | if (alpn == NULL) { |
wolfSSL | 13:f67a6c6013ca | 1046 | WOLFSSL_MSG("Memory failure"); |
wolfSSL | 13:f67a6c6013ca | 1047 | return NULL; |
wolfSSL | 13:f67a6c6013ca | 1048 | } |
wolfSSL | 13:f67a6c6013ca | 1049 | |
wolfSSL | 13:f67a6c6013ca | 1050 | alpn->next = NULL; |
wolfSSL | 13:f67a6c6013ca | 1051 | alpn->negotiated = 0; |
wolfSSL | 13:f67a6c6013ca | 1052 | alpn->options = 0; |
wolfSSL | 13:f67a6c6013ca | 1053 | |
wolfSSL | 13:f67a6c6013ca | 1054 | alpn->protocol_name = (char*)XMALLOC(protocol_nameSz + 1, |
wolfSSL | 13:f67a6c6013ca | 1055 | heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 1056 | if (alpn->protocol_name == NULL) { |
wolfSSL | 13:f67a6c6013ca | 1057 | WOLFSSL_MSG("Memory failure"); |
wolfSSL | 13:f67a6c6013ca | 1058 | XFREE(alpn, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 1059 | return NULL; |
wolfSSL | 13:f67a6c6013ca | 1060 | } |
wolfSSL | 13:f67a6c6013ca | 1061 | |
wolfSSL | 13:f67a6c6013ca | 1062 | XMEMCPY(alpn->protocol_name, protocol_name, protocol_nameSz); |
wolfSSL | 13:f67a6c6013ca | 1063 | alpn->protocol_name[protocol_nameSz] = 0; |
wolfSSL | 13:f67a6c6013ca | 1064 | |
wolfSSL | 13:f67a6c6013ca | 1065 | return alpn; |
wolfSSL | 13:f67a6c6013ca | 1066 | } |
wolfSSL | 13:f67a6c6013ca | 1067 | |
wolfSSL | 13:f67a6c6013ca | 1068 | /** Releases an ALPN object. */ |
wolfSSL | 13:f67a6c6013ca | 1069 | static void TLSX_ALPN_Free(ALPN *alpn, void* heap) |
wolfSSL | 13:f67a6c6013ca | 1070 | { |
wolfSSL | 13:f67a6c6013ca | 1071 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 1072 | |
wolfSSL | 13:f67a6c6013ca | 1073 | if (alpn == NULL) |
wolfSSL | 13:f67a6c6013ca | 1074 | return; |
wolfSSL | 13:f67a6c6013ca | 1075 | |
wolfSSL | 13:f67a6c6013ca | 1076 | XFREE(alpn->protocol_name, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 1077 | XFREE(alpn, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 1078 | } |
wolfSSL | 13:f67a6c6013ca | 1079 | |
wolfSSL | 13:f67a6c6013ca | 1080 | /** Releases all ALPN objects in the provided list. */ |
wolfSSL | 13:f67a6c6013ca | 1081 | static void TLSX_ALPN_FreeAll(ALPN *list, void* heap) |
wolfSSL | 13:f67a6c6013ca | 1082 | { |
wolfSSL | 13:f67a6c6013ca | 1083 | ALPN* alpn; |
wolfSSL | 13:f67a6c6013ca | 1084 | |
wolfSSL | 13:f67a6c6013ca | 1085 | while ((alpn = list)) { |
wolfSSL | 13:f67a6c6013ca | 1086 | list = alpn->next; |
wolfSSL | 13:f67a6c6013ca | 1087 | TLSX_ALPN_Free(alpn, heap); |
wolfSSL | 13:f67a6c6013ca | 1088 | } |
wolfSSL | 13:f67a6c6013ca | 1089 | } |
wolfSSL | 13:f67a6c6013ca | 1090 | |
wolfSSL | 13:f67a6c6013ca | 1091 | /** Tells the buffered size of the ALPN objects in a list. */ |
wolfSSL | 13:f67a6c6013ca | 1092 | static word16 TLSX_ALPN_GetSize(ALPN *list) |
wolfSSL | 13:f67a6c6013ca | 1093 | { |
wolfSSL | 13:f67a6c6013ca | 1094 | ALPN* alpn; |
wolfSSL | 13:f67a6c6013ca | 1095 | word16 length = OPAQUE16_LEN; /* list length */ |
wolfSSL | 13:f67a6c6013ca | 1096 | |
wolfSSL | 13:f67a6c6013ca | 1097 | while ((alpn = list)) { |
wolfSSL | 13:f67a6c6013ca | 1098 | list = alpn->next; |
wolfSSL | 13:f67a6c6013ca | 1099 | |
wolfSSL | 13:f67a6c6013ca | 1100 | length++; /* protocol name length is on one byte */ |
wolfSSL | 13:f67a6c6013ca | 1101 | length += (word16)XSTRLEN(alpn->protocol_name); |
wolfSSL | 13:f67a6c6013ca | 1102 | } |
wolfSSL | 13:f67a6c6013ca | 1103 | |
wolfSSL | 13:f67a6c6013ca | 1104 | return length; |
wolfSSL | 13:f67a6c6013ca | 1105 | } |
wolfSSL | 13:f67a6c6013ca | 1106 | |
wolfSSL | 13:f67a6c6013ca | 1107 | /** Writes the ALPN objects of a list in a buffer. */ |
wolfSSL | 13:f67a6c6013ca | 1108 | static word16 TLSX_ALPN_Write(ALPN *list, byte *output) |
wolfSSL | 13:f67a6c6013ca | 1109 | { |
wolfSSL | 13:f67a6c6013ca | 1110 | ALPN* alpn; |
wolfSSL | 13:f67a6c6013ca | 1111 | word16 length = 0; |
wolfSSL | 13:f67a6c6013ca | 1112 | word16 offset = OPAQUE16_LEN; /* list length offset */ |
wolfSSL | 13:f67a6c6013ca | 1113 | |
wolfSSL | 13:f67a6c6013ca | 1114 | while ((alpn = list)) { |
wolfSSL | 13:f67a6c6013ca | 1115 | list = alpn->next; |
wolfSSL | 13:f67a6c6013ca | 1116 | |
wolfSSL | 13:f67a6c6013ca | 1117 | length = (word16)XSTRLEN(alpn->protocol_name); |
wolfSSL | 13:f67a6c6013ca | 1118 | |
wolfSSL | 13:f67a6c6013ca | 1119 | /* protocol name length */ |
wolfSSL | 13:f67a6c6013ca | 1120 | output[offset++] = (byte)length; |
wolfSSL | 13:f67a6c6013ca | 1121 | |
wolfSSL | 13:f67a6c6013ca | 1122 | /* protocol name value */ |
wolfSSL | 13:f67a6c6013ca | 1123 | XMEMCPY(output + offset, alpn->protocol_name, length); |
wolfSSL | 13:f67a6c6013ca | 1124 | |
wolfSSL | 13:f67a6c6013ca | 1125 | offset += length; |
wolfSSL | 13:f67a6c6013ca | 1126 | } |
wolfSSL | 13:f67a6c6013ca | 1127 | |
wolfSSL | 13:f67a6c6013ca | 1128 | /* writing list length */ |
wolfSSL | 13:f67a6c6013ca | 1129 | c16toa(offset - OPAQUE16_LEN, output); |
wolfSSL | 13:f67a6c6013ca | 1130 | |
wolfSSL | 13:f67a6c6013ca | 1131 | return offset; |
wolfSSL | 13:f67a6c6013ca | 1132 | } |
wolfSSL | 13:f67a6c6013ca | 1133 | |
wolfSSL | 13:f67a6c6013ca | 1134 | /** Finds a protocol name in the provided ALPN list */ |
wolfSSL | 13:f67a6c6013ca | 1135 | static ALPN* TLSX_ALPN_Find(ALPN *list, char *protocol_name, word16 size) |
wolfSSL | 13:f67a6c6013ca | 1136 | { |
wolfSSL | 13:f67a6c6013ca | 1137 | ALPN *alpn; |
wolfSSL | 13:f67a6c6013ca | 1138 | |
wolfSSL | 13:f67a6c6013ca | 1139 | if (list == NULL || protocol_name == NULL) |
wolfSSL | 13:f67a6c6013ca | 1140 | return NULL; |
wolfSSL | 13:f67a6c6013ca | 1141 | |
wolfSSL | 13:f67a6c6013ca | 1142 | alpn = list; |
wolfSSL | 13:f67a6c6013ca | 1143 | while (alpn != NULL && ( |
wolfSSL | 13:f67a6c6013ca | 1144 | (word16)XSTRLEN(alpn->protocol_name) != size || |
wolfSSL | 13:f67a6c6013ca | 1145 | XSTRNCMP(alpn->protocol_name, protocol_name, size))) |
wolfSSL | 13:f67a6c6013ca | 1146 | alpn = alpn->next; |
wolfSSL | 13:f67a6c6013ca | 1147 | |
wolfSSL | 13:f67a6c6013ca | 1148 | return alpn; |
wolfSSL | 13:f67a6c6013ca | 1149 | } |
wolfSSL | 13:f67a6c6013ca | 1150 | |
wolfSSL | 13:f67a6c6013ca | 1151 | /** Set the ALPN matching client and server requirements */ |
wolfSSL | 13:f67a6c6013ca | 1152 | static int TLSX_SetALPN(TLSX** extensions, const void* data, word16 size, |
wolfSSL | 13:f67a6c6013ca | 1153 | void* heap) |
wolfSSL | 13:f67a6c6013ca | 1154 | { |
wolfSSL | 13:f67a6c6013ca | 1155 | ALPN *alpn; |
wolfSSL | 13:f67a6c6013ca | 1156 | int ret; |
wolfSSL | 13:f67a6c6013ca | 1157 | |
wolfSSL | 13:f67a6c6013ca | 1158 | if (extensions == NULL || data == NULL) |
wolfSSL | 13:f67a6c6013ca | 1159 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 1160 | |
wolfSSL | 13:f67a6c6013ca | 1161 | alpn = TLSX_ALPN_New((char *)data, size, heap); |
wolfSSL | 13:f67a6c6013ca | 1162 | if (alpn == NULL) { |
wolfSSL | 13:f67a6c6013ca | 1163 | WOLFSSL_MSG("Memory failure"); |
wolfSSL | 13:f67a6c6013ca | 1164 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 1165 | } |
wolfSSL | 13:f67a6c6013ca | 1166 | |
wolfSSL | 13:f67a6c6013ca | 1167 | alpn->negotiated = 1; |
wolfSSL | 13:f67a6c6013ca | 1168 | |
wolfSSL | 13:f67a6c6013ca | 1169 | ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL, (void*)alpn, |
wolfSSL | 13:f67a6c6013ca | 1170 | heap); |
wolfSSL | 13:f67a6c6013ca | 1171 | if (ret != 0) { |
wolfSSL | 13:f67a6c6013ca | 1172 | TLSX_ALPN_Free(alpn, heap); |
wolfSSL | 13:f67a6c6013ca | 1173 | return ret; |
wolfSSL | 13:f67a6c6013ca | 1174 | } |
wolfSSL | 13:f67a6c6013ca | 1175 | |
wolfSSL | 13:f67a6c6013ca | 1176 | return SSL_SUCCESS; |
wolfSSL | 13:f67a6c6013ca | 1177 | } |
wolfSSL | 13:f67a6c6013ca | 1178 | |
wolfSSL | 13:f67a6c6013ca | 1179 | /** Parses a buffer of ALPN extensions and set the first one matching |
wolfSSL | 13:f67a6c6013ca | 1180 | * client and server requirements */ |
wolfSSL | 13:f67a6c6013ca | 1181 | static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 1182 | byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 1183 | { |
wolfSSL | 13:f67a6c6013ca | 1184 | word16 size = 0, offset = 0, idx = 0; |
wolfSSL | 13:f67a6c6013ca | 1185 | int r = BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1186 | byte match = 0; |
wolfSSL | 13:f67a6c6013ca | 1187 | TLSX *extension; |
wolfSSL | 13:f67a6c6013ca | 1188 | ALPN *alpn = NULL, *list; |
wolfSSL | 13:f67a6c6013ca | 1189 | |
wolfSSL | 13:f67a6c6013ca | 1190 | if (OPAQUE16_LEN > length) |
wolfSSL | 13:f67a6c6013ca | 1191 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1192 | |
wolfSSL | 13:f67a6c6013ca | 1193 | ato16(input, &size); |
wolfSSL | 13:f67a6c6013ca | 1194 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 1195 | |
wolfSSL | 13:f67a6c6013ca | 1196 | extension = TLSX_Find(ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL); |
wolfSSL | 13:f67a6c6013ca | 1197 | if (extension == NULL) |
wolfSSL | 13:f67a6c6013ca | 1198 | extension = TLSX_Find(ssl->ctx->extensions, |
wolfSSL | 13:f67a6c6013ca | 1199 | TLSX_APPLICATION_LAYER_PROTOCOL); |
wolfSSL | 13:f67a6c6013ca | 1200 | |
wolfSSL | 13:f67a6c6013ca | 1201 | #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) |
wolfSSL | 13:f67a6c6013ca | 1202 | if (ssl->alpnSelect != NULL) { |
wolfSSL | 13:f67a6c6013ca | 1203 | const byte* out; |
wolfSSL | 13:f67a6c6013ca | 1204 | unsigned char outLen; |
wolfSSL | 13:f67a6c6013ca | 1205 | |
wolfSSL | 13:f67a6c6013ca | 1206 | if (ssl->alpnSelect(ssl, &out, &outLen, input + offset, size, |
wolfSSL | 13:f67a6c6013ca | 1207 | ssl->alpnSelectArg) == 0) { |
wolfSSL | 13:f67a6c6013ca | 1208 | WOLFSSL_MSG("ALPN protocol match"); |
wolfSSL | 13:f67a6c6013ca | 1209 | if (TLSX_UseALPN(&ssl->extensions, (char*)out, outLen, 0, ssl->heap) |
wolfSSL | 13:f67a6c6013ca | 1210 | == SSL_SUCCESS) { |
wolfSSL | 13:f67a6c6013ca | 1211 | if (extension == NULL) { |
wolfSSL | 13:f67a6c6013ca | 1212 | extension = TLSX_Find(ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 1213 | TLSX_APPLICATION_LAYER_PROTOCOL); |
wolfSSL | 13:f67a6c6013ca | 1214 | } |
wolfSSL | 13:f67a6c6013ca | 1215 | } |
wolfSSL | 13:f67a6c6013ca | 1216 | } |
wolfSSL | 13:f67a6c6013ca | 1217 | } |
wolfSSL | 13:f67a6c6013ca | 1218 | #endif |
wolfSSL | 13:f67a6c6013ca | 1219 | |
wolfSSL | 13:f67a6c6013ca | 1220 | if (extension == NULL || extension->data == NULL) { |
wolfSSL | 13:f67a6c6013ca | 1221 | WOLFSSL_MSG("No ALPN extensions not used or bad"); |
wolfSSL | 13:f67a6c6013ca | 1222 | return isRequest ? 0 /* not using ALPN */ |
wolfSSL | 13:f67a6c6013ca | 1223 | : BUFFER_ERROR; /* unexpected ALPN response */ |
wolfSSL | 13:f67a6c6013ca | 1224 | } |
wolfSSL | 13:f67a6c6013ca | 1225 | |
wolfSSL | 13:f67a6c6013ca | 1226 | /* validating alpn list length */ |
wolfSSL | 13:f67a6c6013ca | 1227 | if (length != OPAQUE16_LEN + size) |
wolfSSL | 13:f67a6c6013ca | 1228 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1229 | |
wolfSSL | 13:f67a6c6013ca | 1230 | list = (ALPN*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 1231 | |
wolfSSL | 13:f67a6c6013ca | 1232 | /* keep the list sent by client */ |
wolfSSL | 13:f67a6c6013ca | 1233 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 1234 | if (ssl->alpn_client_list != NULL) |
wolfSSL | 13:f67a6c6013ca | 1235 | XFREE(ssl->alpn_client_list, ssl->heap, DYNAMIC_TYPE_ALPN); |
wolfSSL | 13:f67a6c6013ca | 1236 | |
wolfSSL | 13:f67a6c6013ca | 1237 | ssl->alpn_client_list = (char *)XMALLOC(size, ssl->heap, |
wolfSSL | 13:f67a6c6013ca | 1238 | DYNAMIC_TYPE_ALPN); |
wolfSSL | 13:f67a6c6013ca | 1239 | if (ssl->alpn_client_list == NULL) |
wolfSSL | 13:f67a6c6013ca | 1240 | return MEMORY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1241 | } |
wolfSSL | 13:f67a6c6013ca | 1242 | |
wolfSSL | 13:f67a6c6013ca | 1243 | for (size = 0; offset < length; offset += size) { |
wolfSSL | 13:f67a6c6013ca | 1244 | |
wolfSSL | 13:f67a6c6013ca | 1245 | size = input[offset++]; |
wolfSSL | 13:f67a6c6013ca | 1246 | if (offset + size > length) |
wolfSSL | 13:f67a6c6013ca | 1247 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1248 | |
wolfSSL | 13:f67a6c6013ca | 1249 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 1250 | XMEMCPY(ssl->alpn_client_list+idx, (char*)input + offset, size); |
wolfSSL | 13:f67a6c6013ca | 1251 | idx += size; |
wolfSSL | 13:f67a6c6013ca | 1252 | ssl->alpn_client_list[idx++] = ','; |
wolfSSL | 13:f67a6c6013ca | 1253 | } |
wolfSSL | 13:f67a6c6013ca | 1254 | |
wolfSSL | 13:f67a6c6013ca | 1255 | if (!match) { |
wolfSSL | 13:f67a6c6013ca | 1256 | alpn = TLSX_ALPN_Find(list, (char*)input + offset, size); |
wolfSSL | 13:f67a6c6013ca | 1257 | if (alpn != NULL) { |
wolfSSL | 13:f67a6c6013ca | 1258 | WOLFSSL_MSG("ALPN protocol match"); |
wolfSSL | 13:f67a6c6013ca | 1259 | match = 1; |
wolfSSL | 13:f67a6c6013ca | 1260 | |
wolfSSL | 13:f67a6c6013ca | 1261 | /* skip reading other values if not required */ |
wolfSSL | 13:f67a6c6013ca | 1262 | if (!isRequest) |
wolfSSL | 13:f67a6c6013ca | 1263 | break; |
wolfSSL | 13:f67a6c6013ca | 1264 | } |
wolfSSL | 13:f67a6c6013ca | 1265 | } |
wolfSSL | 13:f67a6c6013ca | 1266 | } |
wolfSSL | 13:f67a6c6013ca | 1267 | |
wolfSSL | 13:f67a6c6013ca | 1268 | if (isRequest) |
wolfSSL | 13:f67a6c6013ca | 1269 | ssl->alpn_client_list[idx-1] = 0; |
wolfSSL | 13:f67a6c6013ca | 1270 | |
wolfSSL | 13:f67a6c6013ca | 1271 | if (!match) { |
wolfSSL | 13:f67a6c6013ca | 1272 | WOLFSSL_MSG("No ALPN protocol match"); |
wolfSSL | 13:f67a6c6013ca | 1273 | |
wolfSSL | 13:f67a6c6013ca | 1274 | /* do nothing if no protocol match between client and server and option |
wolfSSL | 13:f67a6c6013ca | 1275 | is set to continue (like OpenSSL) */ |
wolfSSL | 13:f67a6c6013ca | 1276 | if (list->options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) { |
wolfSSL | 13:f67a6c6013ca | 1277 | WOLFSSL_MSG("Continue on mismatch"); |
wolfSSL | 13:f67a6c6013ca | 1278 | return 0; |
wolfSSL | 13:f67a6c6013ca | 1279 | } |
wolfSSL | 13:f67a6c6013ca | 1280 | |
wolfSSL | 13:f67a6c6013ca | 1281 | SendAlert(ssl, alert_fatal, no_application_protocol); |
wolfSSL | 13:f67a6c6013ca | 1282 | return UNKNOWN_ALPN_PROTOCOL_NAME_E; |
wolfSSL | 13:f67a6c6013ca | 1283 | } |
wolfSSL | 13:f67a6c6013ca | 1284 | |
wolfSSL | 13:f67a6c6013ca | 1285 | /* set the matching negotiated protocol */ |
wolfSSL | 13:f67a6c6013ca | 1286 | r = TLSX_SetALPN(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 1287 | alpn->protocol_name, |
wolfSSL | 13:f67a6c6013ca | 1288 | (word16)XSTRLEN(alpn->protocol_name), |
wolfSSL | 13:f67a6c6013ca | 1289 | ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 1290 | if (r != SSL_SUCCESS) { |
wolfSSL | 13:f67a6c6013ca | 1291 | WOLFSSL_MSG("TLSX_UseALPN failed"); |
wolfSSL | 13:f67a6c6013ca | 1292 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1293 | } |
wolfSSL | 13:f67a6c6013ca | 1294 | |
wolfSSL | 13:f67a6c6013ca | 1295 | /* reply to ALPN extension sent from client */ |
wolfSSL | 13:f67a6c6013ca | 1296 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 1297 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 1298 | TLSX_SetResponse(ssl, TLSX_APPLICATION_LAYER_PROTOCOL); |
wolfSSL | 13:f67a6c6013ca | 1299 | #endif |
wolfSSL | 13:f67a6c6013ca | 1300 | } |
wolfSSL | 13:f67a6c6013ca | 1301 | |
wolfSSL | 13:f67a6c6013ca | 1302 | return 0; |
wolfSSL | 13:f67a6c6013ca | 1303 | } |
wolfSSL | 13:f67a6c6013ca | 1304 | |
wolfSSL | 13:f67a6c6013ca | 1305 | /** Add a protocol name to the list of accepted usable ones */ |
wolfSSL | 13:f67a6c6013ca | 1306 | int TLSX_UseALPN(TLSX** extensions, const void* data, word16 size, byte options, |
wolfSSL | 13:f67a6c6013ca | 1307 | void* heap) |
wolfSSL | 13:f67a6c6013ca | 1308 | { |
wolfSSL | 13:f67a6c6013ca | 1309 | ALPN *alpn; |
wolfSSL | 13:f67a6c6013ca | 1310 | TLSX *extension; |
wolfSSL | 13:f67a6c6013ca | 1311 | int ret; |
wolfSSL | 13:f67a6c6013ca | 1312 | |
wolfSSL | 13:f67a6c6013ca | 1313 | if (extensions == NULL || data == NULL) |
wolfSSL | 13:f67a6c6013ca | 1314 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 1315 | |
wolfSSL | 13:f67a6c6013ca | 1316 | alpn = TLSX_ALPN_New((char *)data, size, heap); |
wolfSSL | 13:f67a6c6013ca | 1317 | if (alpn == NULL) { |
wolfSSL | 13:f67a6c6013ca | 1318 | WOLFSSL_MSG("Memory failure"); |
wolfSSL | 13:f67a6c6013ca | 1319 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 1320 | } |
wolfSSL | 13:f67a6c6013ca | 1321 | |
wolfSSL | 13:f67a6c6013ca | 1322 | /* Set Options of ALPN */ |
wolfSSL | 13:f67a6c6013ca | 1323 | alpn->options = options; |
wolfSSL | 13:f67a6c6013ca | 1324 | |
wolfSSL | 13:f67a6c6013ca | 1325 | extension = TLSX_Find(*extensions, TLSX_APPLICATION_LAYER_PROTOCOL); |
wolfSSL | 13:f67a6c6013ca | 1326 | if (extension == NULL) { |
wolfSSL | 13:f67a6c6013ca | 1327 | ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL, |
wolfSSL | 13:f67a6c6013ca | 1328 | (void*)alpn, heap); |
wolfSSL | 13:f67a6c6013ca | 1329 | if (ret != 0) { |
wolfSSL | 13:f67a6c6013ca | 1330 | TLSX_ALPN_Free(alpn, heap); |
wolfSSL | 13:f67a6c6013ca | 1331 | return ret; |
wolfSSL | 13:f67a6c6013ca | 1332 | } |
wolfSSL | 13:f67a6c6013ca | 1333 | } |
wolfSSL | 13:f67a6c6013ca | 1334 | else { |
wolfSSL | 13:f67a6c6013ca | 1335 | /* push new ALPN object to extension data. */ |
wolfSSL | 13:f67a6c6013ca | 1336 | alpn->next = (ALPN*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 1337 | extension->data = (void*)alpn; |
wolfSSL | 13:f67a6c6013ca | 1338 | } |
wolfSSL | 13:f67a6c6013ca | 1339 | |
wolfSSL | 13:f67a6c6013ca | 1340 | return SSL_SUCCESS; |
wolfSSL | 13:f67a6c6013ca | 1341 | } |
wolfSSL | 13:f67a6c6013ca | 1342 | |
wolfSSL | 13:f67a6c6013ca | 1343 | /** Get the protocol name set by the server */ |
wolfSSL | 13:f67a6c6013ca | 1344 | int TLSX_ALPN_GetRequest(TLSX* extensions, void** data, word16 *dataSz) |
wolfSSL | 13:f67a6c6013ca | 1345 | { |
wolfSSL | 13:f67a6c6013ca | 1346 | TLSX *extension; |
wolfSSL | 13:f67a6c6013ca | 1347 | ALPN *alpn; |
wolfSSL | 13:f67a6c6013ca | 1348 | |
wolfSSL | 13:f67a6c6013ca | 1349 | if (extensions == NULL || data == NULL || dataSz == NULL) |
wolfSSL | 13:f67a6c6013ca | 1350 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 1351 | |
wolfSSL | 13:f67a6c6013ca | 1352 | extension = TLSX_Find(extensions, TLSX_APPLICATION_LAYER_PROTOCOL); |
wolfSSL | 13:f67a6c6013ca | 1353 | if (extension == NULL) { |
wolfSSL | 13:f67a6c6013ca | 1354 | WOLFSSL_MSG("TLS extension not found"); |
wolfSSL | 13:f67a6c6013ca | 1355 | return SSL_ALPN_NOT_FOUND; |
wolfSSL | 13:f67a6c6013ca | 1356 | } |
wolfSSL | 13:f67a6c6013ca | 1357 | |
wolfSSL | 13:f67a6c6013ca | 1358 | alpn = (ALPN *)extension->data; |
wolfSSL | 13:f67a6c6013ca | 1359 | if (alpn == NULL) { |
wolfSSL | 13:f67a6c6013ca | 1360 | WOLFSSL_MSG("ALPN extension not found"); |
wolfSSL | 13:f67a6c6013ca | 1361 | *data = NULL; |
wolfSSL | 13:f67a6c6013ca | 1362 | *dataSz = 0; |
wolfSSL | 13:f67a6c6013ca | 1363 | return SSL_FATAL_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1364 | } |
wolfSSL | 13:f67a6c6013ca | 1365 | |
wolfSSL | 13:f67a6c6013ca | 1366 | if (alpn->negotiated != 1) { |
wolfSSL | 13:f67a6c6013ca | 1367 | |
wolfSSL | 13:f67a6c6013ca | 1368 | /* consider as an error */ |
wolfSSL | 13:f67a6c6013ca | 1369 | if (alpn->options & WOLFSSL_ALPN_FAILED_ON_MISMATCH) { |
wolfSSL | 13:f67a6c6013ca | 1370 | WOLFSSL_MSG("No protocol match with peer -> Failed"); |
wolfSSL | 13:f67a6c6013ca | 1371 | return SSL_FATAL_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1372 | } |
wolfSSL | 13:f67a6c6013ca | 1373 | |
wolfSSL | 13:f67a6c6013ca | 1374 | /* continue without negotiated protocol */ |
wolfSSL | 13:f67a6c6013ca | 1375 | WOLFSSL_MSG("No protocol match with peer -> Continue"); |
wolfSSL | 13:f67a6c6013ca | 1376 | return SSL_ALPN_NOT_FOUND; |
wolfSSL | 13:f67a6c6013ca | 1377 | } |
wolfSSL | 13:f67a6c6013ca | 1378 | |
wolfSSL | 13:f67a6c6013ca | 1379 | if (alpn->next != NULL) { |
wolfSSL | 13:f67a6c6013ca | 1380 | WOLFSSL_MSG("Only one protocol name must be accepted"); |
wolfSSL | 13:f67a6c6013ca | 1381 | return SSL_FATAL_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1382 | } |
wolfSSL | 13:f67a6c6013ca | 1383 | |
wolfSSL | 13:f67a6c6013ca | 1384 | *data = alpn->protocol_name; |
wolfSSL | 13:f67a6c6013ca | 1385 | *dataSz = (word16)XSTRLEN((char*)*data); |
wolfSSL | 13:f67a6c6013ca | 1386 | |
wolfSSL | 13:f67a6c6013ca | 1387 | return SSL_SUCCESS; |
wolfSSL | 13:f67a6c6013ca | 1388 | } |
wolfSSL | 13:f67a6c6013ca | 1389 | |
wolfSSL | 13:f67a6c6013ca | 1390 | #define ALPN_FREE_ALL TLSX_ALPN_FreeAll |
wolfSSL | 13:f67a6c6013ca | 1391 | #define ALPN_GET_SIZE TLSX_ALPN_GetSize |
wolfSSL | 13:f67a6c6013ca | 1392 | #define ALPN_WRITE TLSX_ALPN_Write |
wolfSSL | 13:f67a6c6013ca | 1393 | #define ALPN_PARSE TLSX_ALPN_ParseAndSet |
wolfSSL | 13:f67a6c6013ca | 1394 | |
wolfSSL | 13:f67a6c6013ca | 1395 | #else /* HAVE_ALPN */ |
wolfSSL | 13:f67a6c6013ca | 1396 | |
wolfSSL | 13:f67a6c6013ca | 1397 | #define ALPN_FREE_ALL(list, heap) |
wolfSSL | 13:f67a6c6013ca | 1398 | #define ALPN_GET_SIZE(list) 0 |
wolfSSL | 13:f67a6c6013ca | 1399 | #define ALPN_WRITE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 1400 | #define ALPN_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 1401 | |
wolfSSL | 13:f67a6c6013ca | 1402 | #endif /* HAVE_ALPN */ |
wolfSSL | 13:f67a6c6013ca | 1403 | |
wolfSSL | 13:f67a6c6013ca | 1404 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 1405 | /* Server Name Indication */ |
wolfSSL | 13:f67a6c6013ca | 1406 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 1407 | |
wolfSSL | 13:f67a6c6013ca | 1408 | #ifdef HAVE_SNI |
wolfSSL | 13:f67a6c6013ca | 1409 | |
wolfSSL | 13:f67a6c6013ca | 1410 | /** Creates a new SNI object. */ |
wolfSSL | 13:f67a6c6013ca | 1411 | static SNI* TLSX_SNI_New(byte type, const void* data, word16 size, void* heap) |
wolfSSL | 13:f67a6c6013ca | 1412 | { |
wolfSSL | 13:f67a6c6013ca | 1413 | SNI* sni = (SNI*)XMALLOC(sizeof(SNI), heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 1414 | |
wolfSSL | 13:f67a6c6013ca | 1415 | if (sni) { |
wolfSSL | 13:f67a6c6013ca | 1416 | sni->type = type; |
wolfSSL | 13:f67a6c6013ca | 1417 | sni->next = NULL; |
wolfSSL | 13:f67a6c6013ca | 1418 | |
wolfSSL | 13:f67a6c6013ca | 1419 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 1420 | sni->options = 0; |
wolfSSL | 13:f67a6c6013ca | 1421 | sni->status = WOLFSSL_SNI_NO_MATCH; |
wolfSSL | 13:f67a6c6013ca | 1422 | #endif |
wolfSSL | 13:f67a6c6013ca | 1423 | |
wolfSSL | 13:f67a6c6013ca | 1424 | switch (sni->type) { |
wolfSSL | 13:f67a6c6013ca | 1425 | case WOLFSSL_SNI_HOST_NAME: |
wolfSSL | 13:f67a6c6013ca | 1426 | sni->data.host_name = (char*)XMALLOC(size + 1, heap, |
wolfSSL | 13:f67a6c6013ca | 1427 | DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 1428 | if (sni->data.host_name) { |
wolfSSL | 13:f67a6c6013ca | 1429 | XSTRNCPY(sni->data.host_name, (const char*)data, size); |
wolfSSL | 13:f67a6c6013ca | 1430 | sni->data.host_name[size] = 0; |
wolfSSL | 13:f67a6c6013ca | 1431 | } else { |
wolfSSL | 13:f67a6c6013ca | 1432 | XFREE(sni, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 1433 | sni = NULL; |
wolfSSL | 13:f67a6c6013ca | 1434 | } |
wolfSSL | 13:f67a6c6013ca | 1435 | break; |
wolfSSL | 13:f67a6c6013ca | 1436 | |
wolfSSL | 13:f67a6c6013ca | 1437 | default: /* invalid type */ |
wolfSSL | 13:f67a6c6013ca | 1438 | XFREE(sni, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 1439 | sni = NULL; |
wolfSSL | 13:f67a6c6013ca | 1440 | } |
wolfSSL | 13:f67a6c6013ca | 1441 | } |
wolfSSL | 13:f67a6c6013ca | 1442 | |
wolfSSL | 13:f67a6c6013ca | 1443 | return sni; |
wolfSSL | 13:f67a6c6013ca | 1444 | } |
wolfSSL | 13:f67a6c6013ca | 1445 | |
wolfSSL | 13:f67a6c6013ca | 1446 | /** Releases a SNI object. */ |
wolfSSL | 13:f67a6c6013ca | 1447 | static void TLSX_SNI_Free(SNI* sni, void* heap) |
wolfSSL | 13:f67a6c6013ca | 1448 | { |
wolfSSL | 13:f67a6c6013ca | 1449 | if (sni) { |
wolfSSL | 13:f67a6c6013ca | 1450 | switch (sni->type) { |
wolfSSL | 13:f67a6c6013ca | 1451 | case WOLFSSL_SNI_HOST_NAME: |
wolfSSL | 13:f67a6c6013ca | 1452 | XFREE(sni->data.host_name, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 1453 | break; |
wolfSSL | 13:f67a6c6013ca | 1454 | } |
wolfSSL | 13:f67a6c6013ca | 1455 | |
wolfSSL | 13:f67a6c6013ca | 1456 | XFREE(sni, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 1457 | } |
wolfSSL | 13:f67a6c6013ca | 1458 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 1459 | } |
wolfSSL | 13:f67a6c6013ca | 1460 | |
wolfSSL | 13:f67a6c6013ca | 1461 | /** Releases all SNI objects in the provided list. */ |
wolfSSL | 13:f67a6c6013ca | 1462 | static void TLSX_SNI_FreeAll(SNI* list, void* heap) |
wolfSSL | 13:f67a6c6013ca | 1463 | { |
wolfSSL | 13:f67a6c6013ca | 1464 | SNI* sni; |
wolfSSL | 13:f67a6c6013ca | 1465 | |
wolfSSL | 13:f67a6c6013ca | 1466 | while ((sni = list)) { |
wolfSSL | 13:f67a6c6013ca | 1467 | list = sni->next; |
wolfSSL | 13:f67a6c6013ca | 1468 | TLSX_SNI_Free(sni, heap); |
wolfSSL | 13:f67a6c6013ca | 1469 | } |
wolfSSL | 13:f67a6c6013ca | 1470 | } |
wolfSSL | 13:f67a6c6013ca | 1471 | |
wolfSSL | 13:f67a6c6013ca | 1472 | /** Tells the buffered size of the SNI objects in a list. */ |
wolfSSL | 13:f67a6c6013ca | 1473 | static word16 TLSX_SNI_GetSize(SNI* list) |
wolfSSL | 13:f67a6c6013ca | 1474 | { |
wolfSSL | 13:f67a6c6013ca | 1475 | SNI* sni; |
wolfSSL | 13:f67a6c6013ca | 1476 | word16 length = OPAQUE16_LEN; /* list length */ |
wolfSSL | 13:f67a6c6013ca | 1477 | |
wolfSSL | 13:f67a6c6013ca | 1478 | while ((sni = list)) { |
wolfSSL | 13:f67a6c6013ca | 1479 | list = sni->next; |
wolfSSL | 13:f67a6c6013ca | 1480 | |
wolfSSL | 13:f67a6c6013ca | 1481 | length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */ |
wolfSSL | 13:f67a6c6013ca | 1482 | |
wolfSSL | 13:f67a6c6013ca | 1483 | switch (sni->type) { |
wolfSSL | 13:f67a6c6013ca | 1484 | case WOLFSSL_SNI_HOST_NAME: |
wolfSSL | 13:f67a6c6013ca | 1485 | length += (word16)XSTRLEN((char*)sni->data.host_name); |
wolfSSL | 13:f67a6c6013ca | 1486 | break; |
wolfSSL | 13:f67a6c6013ca | 1487 | } |
wolfSSL | 13:f67a6c6013ca | 1488 | } |
wolfSSL | 13:f67a6c6013ca | 1489 | |
wolfSSL | 13:f67a6c6013ca | 1490 | return length; |
wolfSSL | 13:f67a6c6013ca | 1491 | } |
wolfSSL | 13:f67a6c6013ca | 1492 | |
wolfSSL | 13:f67a6c6013ca | 1493 | /** Writes the SNI objects of a list in a buffer. */ |
wolfSSL | 13:f67a6c6013ca | 1494 | static word16 TLSX_SNI_Write(SNI* list, byte* output) |
wolfSSL | 13:f67a6c6013ca | 1495 | { |
wolfSSL | 13:f67a6c6013ca | 1496 | SNI* sni; |
wolfSSL | 13:f67a6c6013ca | 1497 | word16 length = 0; |
wolfSSL | 13:f67a6c6013ca | 1498 | word16 offset = OPAQUE16_LEN; /* list length offset */ |
wolfSSL | 13:f67a6c6013ca | 1499 | |
wolfSSL | 13:f67a6c6013ca | 1500 | while ((sni = list)) { |
wolfSSL | 13:f67a6c6013ca | 1501 | list = sni->next; |
wolfSSL | 13:f67a6c6013ca | 1502 | |
wolfSSL | 13:f67a6c6013ca | 1503 | output[offset++] = sni->type; /* sni type */ |
wolfSSL | 13:f67a6c6013ca | 1504 | |
wolfSSL | 13:f67a6c6013ca | 1505 | switch (sni->type) { |
wolfSSL | 13:f67a6c6013ca | 1506 | case WOLFSSL_SNI_HOST_NAME: |
wolfSSL | 13:f67a6c6013ca | 1507 | length = (word16)XSTRLEN((char*)sni->data.host_name); |
wolfSSL | 13:f67a6c6013ca | 1508 | |
wolfSSL | 13:f67a6c6013ca | 1509 | c16toa(length, output + offset); /* sni length */ |
wolfSSL | 13:f67a6c6013ca | 1510 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 1511 | |
wolfSSL | 13:f67a6c6013ca | 1512 | XMEMCPY(output + offset, sni->data.host_name, length); |
wolfSSL | 13:f67a6c6013ca | 1513 | |
wolfSSL | 13:f67a6c6013ca | 1514 | offset += length; |
wolfSSL | 13:f67a6c6013ca | 1515 | break; |
wolfSSL | 13:f67a6c6013ca | 1516 | } |
wolfSSL | 13:f67a6c6013ca | 1517 | } |
wolfSSL | 13:f67a6c6013ca | 1518 | |
wolfSSL | 13:f67a6c6013ca | 1519 | c16toa(offset - OPAQUE16_LEN, output); /* writing list length */ |
wolfSSL | 13:f67a6c6013ca | 1520 | |
wolfSSL | 13:f67a6c6013ca | 1521 | return offset; |
wolfSSL | 13:f67a6c6013ca | 1522 | } |
wolfSSL | 13:f67a6c6013ca | 1523 | |
wolfSSL | 13:f67a6c6013ca | 1524 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 1525 | |
wolfSSL | 13:f67a6c6013ca | 1526 | /** Finds a SNI object in the provided list. */ |
wolfSSL | 13:f67a6c6013ca | 1527 | static SNI* TLSX_SNI_Find(SNI *list, byte type) |
wolfSSL | 13:f67a6c6013ca | 1528 | { |
wolfSSL | 13:f67a6c6013ca | 1529 | SNI *sni = list; |
wolfSSL | 13:f67a6c6013ca | 1530 | |
wolfSSL | 13:f67a6c6013ca | 1531 | while (sni && sni->type != type) |
wolfSSL | 13:f67a6c6013ca | 1532 | sni = sni->next; |
wolfSSL | 13:f67a6c6013ca | 1533 | |
wolfSSL | 13:f67a6c6013ca | 1534 | return sni; |
wolfSSL | 13:f67a6c6013ca | 1535 | } |
wolfSSL | 13:f67a6c6013ca | 1536 | |
wolfSSL | 13:f67a6c6013ca | 1537 | |
wolfSSL | 13:f67a6c6013ca | 1538 | /** Sets the status of a SNI object. */ |
wolfSSL | 13:f67a6c6013ca | 1539 | static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status) |
wolfSSL | 13:f67a6c6013ca | 1540 | { |
wolfSSL | 13:f67a6c6013ca | 1541 | TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:f67a6c6013ca | 1542 | SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type); |
wolfSSL | 13:f67a6c6013ca | 1543 | |
wolfSSL | 13:f67a6c6013ca | 1544 | if (sni) |
wolfSSL | 13:f67a6c6013ca | 1545 | sni->status = status; |
wolfSSL | 13:f67a6c6013ca | 1546 | } |
wolfSSL | 13:f67a6c6013ca | 1547 | |
wolfSSL | 13:f67a6c6013ca | 1548 | /** Gets the status of a SNI object. */ |
wolfSSL | 13:f67a6c6013ca | 1549 | byte TLSX_SNI_Status(TLSX* extensions, byte type) |
wolfSSL | 13:f67a6c6013ca | 1550 | { |
wolfSSL | 13:f67a6c6013ca | 1551 | TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:f67a6c6013ca | 1552 | SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type); |
wolfSSL | 13:f67a6c6013ca | 1553 | |
wolfSSL | 13:f67a6c6013ca | 1554 | if (sni) |
wolfSSL | 13:f67a6c6013ca | 1555 | return sni->status; |
wolfSSL | 13:f67a6c6013ca | 1556 | |
wolfSSL | 13:f67a6c6013ca | 1557 | return 0; |
wolfSSL | 13:f67a6c6013ca | 1558 | } |
wolfSSL | 13:f67a6c6013ca | 1559 | |
wolfSSL | 13:f67a6c6013ca | 1560 | #endif /* NO_WOLFSSL_SERVER */ |
wolfSSL | 13:f67a6c6013ca | 1561 | |
wolfSSL | 13:f67a6c6013ca | 1562 | /** Parses a buffer of SNI extensions. */ |
wolfSSL | 13:f67a6c6013ca | 1563 | static int TLSX_SNI_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 1564 | byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 1565 | { |
wolfSSL | 13:f67a6c6013ca | 1566 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 1567 | word16 size = 0; |
wolfSSL | 13:f67a6c6013ca | 1568 | word16 offset = 0; |
wolfSSL | 13:f67a6c6013ca | 1569 | int cacheOnly = 0; |
wolfSSL | 13:f67a6c6013ca | 1570 | #endif |
wolfSSL | 13:f67a6c6013ca | 1571 | |
wolfSSL | 13:f67a6c6013ca | 1572 | TLSX *extension = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:f67a6c6013ca | 1573 | |
wolfSSL | 13:f67a6c6013ca | 1574 | if (!extension) |
wolfSSL | 13:f67a6c6013ca | 1575 | extension = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:f67a6c6013ca | 1576 | |
wolfSSL | 13:f67a6c6013ca | 1577 | (void)isRequest; |
wolfSSL | 13:f67a6c6013ca | 1578 | (void)input; |
wolfSSL | 13:f67a6c6013ca | 1579 | |
wolfSSL | 13:f67a6c6013ca | 1580 | if (!extension || !extension->data) { |
wolfSSL | 13:f67a6c6013ca | 1581 | #if defined(WOLFSSL_ALWAYS_KEEP_SNI) && !defined(NO_WOLFSSL_SERVER) |
wolfSSL | 13:f67a6c6013ca | 1582 | /* This will keep SNI even though TLSX_UseSNI has not been called. |
wolfSSL | 13:f67a6c6013ca | 1583 | * Enable it so that the received sni is available to functions |
wolfSSL | 13:f67a6c6013ca | 1584 | * that use a custom callback when SNI is received */ |
wolfSSL | 13:f67a6c6013ca | 1585 | cacheOnly = 1; |
wolfSSL | 13:f67a6c6013ca | 1586 | WOLFSSL_MSG("Forcing SSL object to store SNI parameter"); |
wolfSSL | 13:f67a6c6013ca | 1587 | #else |
wolfSSL | 13:f67a6c6013ca | 1588 | return isRequest ? 0 /* not using SNI. */ |
wolfSSL | 13:f67a6c6013ca | 1589 | : BUFFER_ERROR; /* unexpected SNI response. */ |
wolfSSL | 13:f67a6c6013ca | 1590 | #endif |
wolfSSL | 13:f67a6c6013ca | 1591 | } |
wolfSSL | 13:f67a6c6013ca | 1592 | |
wolfSSL | 13:f67a6c6013ca | 1593 | if (!isRequest) |
wolfSSL | 13:f67a6c6013ca | 1594 | return length ? BUFFER_ERROR /* SNI response MUST be empty. */ |
wolfSSL | 13:f67a6c6013ca | 1595 | : 0; /* nothing else to do. */ |
wolfSSL | 13:f67a6c6013ca | 1596 | |
wolfSSL | 13:f67a6c6013ca | 1597 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 1598 | |
wolfSSL | 13:f67a6c6013ca | 1599 | if (OPAQUE16_LEN > length) |
wolfSSL | 13:f67a6c6013ca | 1600 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1601 | |
wolfSSL | 13:f67a6c6013ca | 1602 | ato16(input, &size); |
wolfSSL | 13:f67a6c6013ca | 1603 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 1604 | |
wolfSSL | 13:f67a6c6013ca | 1605 | /* validating sni list length */ |
wolfSSL | 13:f67a6c6013ca | 1606 | if (length != OPAQUE16_LEN + size) |
wolfSSL | 13:f67a6c6013ca | 1607 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1608 | |
wolfSSL | 13:f67a6c6013ca | 1609 | for (size = 0; offset < length; offset += size) { |
wolfSSL | 13:f67a6c6013ca | 1610 | SNI *sni = NULL; |
wolfSSL | 13:f67a6c6013ca | 1611 | byte type = input[offset++]; |
wolfSSL | 13:f67a6c6013ca | 1612 | |
wolfSSL | 13:f67a6c6013ca | 1613 | if (offset + OPAQUE16_LEN > length) |
wolfSSL | 13:f67a6c6013ca | 1614 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1615 | |
wolfSSL | 13:f67a6c6013ca | 1616 | ato16(input + offset, &size); |
wolfSSL | 13:f67a6c6013ca | 1617 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 1618 | |
wolfSSL | 13:f67a6c6013ca | 1619 | if (offset + size > length) |
wolfSSL | 13:f67a6c6013ca | 1620 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1621 | |
wolfSSL | 13:f67a6c6013ca | 1622 | if (!cacheOnly && !(sni = TLSX_SNI_Find((SNI*)extension->data, type))) |
wolfSSL | 13:f67a6c6013ca | 1623 | continue; /* not using this type of SNI. */ |
wolfSSL | 13:f67a6c6013ca | 1624 | |
wolfSSL | 13:f67a6c6013ca | 1625 | switch(type) { |
wolfSSL | 13:f67a6c6013ca | 1626 | case WOLFSSL_SNI_HOST_NAME: { |
wolfSSL | 13:f67a6c6013ca | 1627 | int matchStat; |
wolfSSL | 13:f67a6c6013ca | 1628 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 1629 | /* Don't process the second ClientHello SNI extension if there |
wolfSSL | 13:f67a6c6013ca | 1630 | * was problems with the first. |
wolfSSL | 13:f67a6c6013ca | 1631 | */ |
wolfSSL | 13:f67a6c6013ca | 1632 | if (!cacheOnly && sni->status != 0) |
wolfSSL | 13:f67a6c6013ca | 1633 | break; |
wolfSSL | 13:f67a6c6013ca | 1634 | #endif |
wolfSSL | 13:f67a6c6013ca | 1635 | byte matched = cacheOnly || |
wolfSSL | 13:f67a6c6013ca | 1636 | ((XSTRLEN(sni->data.host_name) == size) |
wolfSSL | 13:f67a6c6013ca | 1637 | && (XSTRNCMP(sni->data.host_name, |
wolfSSL | 13:f67a6c6013ca | 1638 | (const char*)input + offset, size) == 0)); |
wolfSSL | 13:f67a6c6013ca | 1639 | |
wolfSSL | 13:f67a6c6013ca | 1640 | if (matched || sni->options & WOLFSSL_SNI_ANSWER_ON_MISMATCH) { |
wolfSSL | 13:f67a6c6013ca | 1641 | int r = TLSX_UseSNI(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 1642 | type, input + offset, size, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 1643 | |
wolfSSL | 13:f67a6c6013ca | 1644 | if (r != SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 1645 | return r; /* throws error. */ |
wolfSSL | 13:f67a6c6013ca | 1646 | |
wolfSSL | 13:f67a6c6013ca | 1647 | if(cacheOnly) { |
wolfSSL | 13:f67a6c6013ca | 1648 | WOLFSSL_MSG("Forcing storage of SNI, Fake match"); |
wolfSSL | 13:f67a6c6013ca | 1649 | matchStat = WOLFSSL_SNI_FORCE_KEEP; |
wolfSSL | 13:f67a6c6013ca | 1650 | } else if(matched) { |
wolfSSL | 13:f67a6c6013ca | 1651 | WOLFSSL_MSG("SNI did match!"); |
wolfSSL | 13:f67a6c6013ca | 1652 | matchStat = WOLFSSL_SNI_REAL_MATCH; |
wolfSSL | 13:f67a6c6013ca | 1653 | } else { |
wolfSSL | 13:f67a6c6013ca | 1654 | WOLFSSL_MSG("fake SNI match from ANSWER_ON_MISMATCH"); |
wolfSSL | 13:f67a6c6013ca | 1655 | matchStat = WOLFSSL_SNI_FAKE_MATCH; |
wolfSSL | 13:f67a6c6013ca | 1656 | } |
wolfSSL | 13:f67a6c6013ca | 1657 | |
wolfSSL | 13:f67a6c6013ca | 1658 | TLSX_SNI_SetStatus(ssl->extensions, type, matchStat); |
wolfSSL | 13:f67a6c6013ca | 1659 | |
wolfSSL | 13:f67a6c6013ca | 1660 | if(!cacheOnly) |
wolfSSL | 13:f67a6c6013ca | 1661 | TLSX_SetResponse(ssl, TLSX_SERVER_NAME); |
wolfSSL | 13:f67a6c6013ca | 1662 | |
wolfSSL | 13:f67a6c6013ca | 1663 | } else if (!(sni->options & WOLFSSL_SNI_CONTINUE_ON_MISMATCH)) { |
wolfSSL | 13:f67a6c6013ca | 1664 | SendAlert(ssl, alert_fatal, unrecognized_name); |
wolfSSL | 13:f67a6c6013ca | 1665 | |
wolfSSL | 13:f67a6c6013ca | 1666 | return UNKNOWN_SNI_HOST_NAME_E; |
wolfSSL | 13:f67a6c6013ca | 1667 | } |
wolfSSL | 13:f67a6c6013ca | 1668 | break; |
wolfSSL | 13:f67a6c6013ca | 1669 | } |
wolfSSL | 13:f67a6c6013ca | 1670 | } |
wolfSSL | 13:f67a6c6013ca | 1671 | } |
wolfSSL | 13:f67a6c6013ca | 1672 | |
wolfSSL | 13:f67a6c6013ca | 1673 | #endif |
wolfSSL | 13:f67a6c6013ca | 1674 | |
wolfSSL | 13:f67a6c6013ca | 1675 | return 0; |
wolfSSL | 13:f67a6c6013ca | 1676 | } |
wolfSSL | 13:f67a6c6013ca | 1677 | |
wolfSSL | 13:f67a6c6013ca | 1678 | static int TLSX_SNI_VerifyParse(WOLFSSL* ssl, byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 1679 | { |
wolfSSL | 13:f67a6c6013ca | 1680 | (void)ssl; |
wolfSSL | 13:f67a6c6013ca | 1681 | |
wolfSSL | 13:f67a6c6013ca | 1682 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 1683 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 1684 | TLSX* ctx_ext = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:f67a6c6013ca | 1685 | TLSX* ssl_ext = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:f67a6c6013ca | 1686 | SNI* ctx_sni = ctx_ext ? (SNI*)ctx_ext->data : NULL; |
wolfSSL | 13:f67a6c6013ca | 1687 | SNI* ssl_sni = ssl_ext ? (SNI*)ssl_ext->data : NULL; |
wolfSSL | 13:f67a6c6013ca | 1688 | SNI* sni = NULL; |
wolfSSL | 13:f67a6c6013ca | 1689 | |
wolfSSL | 13:f67a6c6013ca | 1690 | for (; ctx_sni; ctx_sni = ctx_sni->next) { |
wolfSSL | 13:f67a6c6013ca | 1691 | if (ctx_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) { |
wolfSSL | 13:f67a6c6013ca | 1692 | sni = TLSX_SNI_Find(ssl_sni, ctx_sni->type); |
wolfSSL | 13:f67a6c6013ca | 1693 | |
wolfSSL | 13:f67a6c6013ca | 1694 | if (sni) { |
wolfSSL | 13:f67a6c6013ca | 1695 | if (sni->status != WOLFSSL_SNI_NO_MATCH) |
wolfSSL | 13:f67a6c6013ca | 1696 | continue; |
wolfSSL | 13:f67a6c6013ca | 1697 | |
wolfSSL | 13:f67a6c6013ca | 1698 | /* if ssl level overrides ctx level, it is ok. */ |
wolfSSL | 13:f67a6c6013ca | 1699 | if ((sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) == 0) |
wolfSSL | 13:f67a6c6013ca | 1700 | continue; |
wolfSSL | 13:f67a6c6013ca | 1701 | } |
wolfSSL | 13:f67a6c6013ca | 1702 | |
wolfSSL | 13:f67a6c6013ca | 1703 | SendAlert(ssl, alert_fatal, handshake_failure); |
wolfSSL | 13:f67a6c6013ca | 1704 | return SNI_ABSENT_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1705 | } |
wolfSSL | 13:f67a6c6013ca | 1706 | } |
wolfSSL | 13:f67a6c6013ca | 1707 | |
wolfSSL | 13:f67a6c6013ca | 1708 | for (; ssl_sni; ssl_sni = ssl_sni->next) { |
wolfSSL | 13:f67a6c6013ca | 1709 | if (ssl_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) { |
wolfSSL | 13:f67a6c6013ca | 1710 | if (ssl_sni->status != WOLFSSL_SNI_NO_MATCH) |
wolfSSL | 13:f67a6c6013ca | 1711 | continue; |
wolfSSL | 13:f67a6c6013ca | 1712 | |
wolfSSL | 13:f67a6c6013ca | 1713 | SendAlert(ssl, alert_fatal, handshake_failure); |
wolfSSL | 13:f67a6c6013ca | 1714 | return SNI_ABSENT_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1715 | } |
wolfSSL | 13:f67a6c6013ca | 1716 | } |
wolfSSL | 13:f67a6c6013ca | 1717 | #endif /* NO_WOLFSSL_SERVER */ |
wolfSSL | 13:f67a6c6013ca | 1718 | } |
wolfSSL | 13:f67a6c6013ca | 1719 | |
wolfSSL | 13:f67a6c6013ca | 1720 | return 0; |
wolfSSL | 13:f67a6c6013ca | 1721 | } |
wolfSSL | 13:f67a6c6013ca | 1722 | |
wolfSSL | 13:f67a6c6013ca | 1723 | int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size, |
wolfSSL | 13:f67a6c6013ca | 1724 | void* heap) |
wolfSSL | 13:f67a6c6013ca | 1725 | { |
wolfSSL | 13:f67a6c6013ca | 1726 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 1727 | SNI* sni = NULL; |
wolfSSL | 13:f67a6c6013ca | 1728 | |
wolfSSL | 13:f67a6c6013ca | 1729 | if (extensions == NULL || data == NULL) |
wolfSSL | 13:f67a6c6013ca | 1730 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 1731 | |
wolfSSL | 13:f67a6c6013ca | 1732 | if ((sni = TLSX_SNI_New(type, data, size, heap)) == NULL) |
wolfSSL | 13:f67a6c6013ca | 1733 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 1734 | |
wolfSSL | 13:f67a6c6013ca | 1735 | extension = TLSX_Find(*extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:f67a6c6013ca | 1736 | if (!extension) { |
wolfSSL | 13:f67a6c6013ca | 1737 | int ret = TLSX_Push(extensions, TLSX_SERVER_NAME, (void*)sni, heap); |
wolfSSL | 13:f67a6c6013ca | 1738 | if (ret != 0) { |
wolfSSL | 13:f67a6c6013ca | 1739 | TLSX_SNI_Free(sni, heap); |
wolfSSL | 13:f67a6c6013ca | 1740 | return ret; |
wolfSSL | 13:f67a6c6013ca | 1741 | } |
wolfSSL | 13:f67a6c6013ca | 1742 | } |
wolfSSL | 13:f67a6c6013ca | 1743 | else { |
wolfSSL | 13:f67a6c6013ca | 1744 | /* push new SNI object to extension data. */ |
wolfSSL | 13:f67a6c6013ca | 1745 | sni->next = (SNI*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 1746 | extension->data = (void*)sni; |
wolfSSL | 13:f67a6c6013ca | 1747 | |
wolfSSL | 13:f67a6c6013ca | 1748 | /* remove duplicate SNI, there should be only one of each type. */ |
wolfSSL | 13:f67a6c6013ca | 1749 | do { |
wolfSSL | 13:f67a6c6013ca | 1750 | if (sni->next && sni->next->type == type) { |
wolfSSL | 13:f67a6c6013ca | 1751 | SNI *next = sni->next; |
wolfSSL | 13:f67a6c6013ca | 1752 | |
wolfSSL | 13:f67a6c6013ca | 1753 | sni->next = next->next; |
wolfSSL | 13:f67a6c6013ca | 1754 | TLSX_SNI_Free(next, heap); |
wolfSSL | 13:f67a6c6013ca | 1755 | |
wolfSSL | 13:f67a6c6013ca | 1756 | /* there is no way to occur more than */ |
wolfSSL | 13:f67a6c6013ca | 1757 | /* two SNIs of the same type. */ |
wolfSSL | 13:f67a6c6013ca | 1758 | break; |
wolfSSL | 13:f67a6c6013ca | 1759 | } |
wolfSSL | 13:f67a6c6013ca | 1760 | } while ((sni = sni->next)); |
wolfSSL | 13:f67a6c6013ca | 1761 | } |
wolfSSL | 13:f67a6c6013ca | 1762 | |
wolfSSL | 13:f67a6c6013ca | 1763 | return SSL_SUCCESS; |
wolfSSL | 13:f67a6c6013ca | 1764 | } |
wolfSSL | 13:f67a6c6013ca | 1765 | |
wolfSSL | 13:f67a6c6013ca | 1766 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 1767 | |
wolfSSL | 13:f67a6c6013ca | 1768 | /** Tells the SNI requested by the client. */ |
wolfSSL | 13:f67a6c6013ca | 1769 | word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data) |
wolfSSL | 13:f67a6c6013ca | 1770 | { |
wolfSSL | 13:f67a6c6013ca | 1771 | TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:f67a6c6013ca | 1772 | SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type); |
wolfSSL | 13:f67a6c6013ca | 1773 | |
wolfSSL | 13:f67a6c6013ca | 1774 | if (sni && sni->status != WOLFSSL_SNI_NO_MATCH) { |
wolfSSL | 13:f67a6c6013ca | 1775 | switch (sni->type) { |
wolfSSL | 13:f67a6c6013ca | 1776 | case WOLFSSL_SNI_HOST_NAME: |
wolfSSL | 13:f67a6c6013ca | 1777 | if (data) { |
wolfSSL | 13:f67a6c6013ca | 1778 | *data = sni->data.host_name; |
wolfSSL | 13:f67a6c6013ca | 1779 | return (word16)XSTRLEN((char*)*data); |
wolfSSL | 13:f67a6c6013ca | 1780 | } |
wolfSSL | 13:f67a6c6013ca | 1781 | } |
wolfSSL | 13:f67a6c6013ca | 1782 | } |
wolfSSL | 13:f67a6c6013ca | 1783 | |
wolfSSL | 13:f67a6c6013ca | 1784 | return 0; |
wolfSSL | 13:f67a6c6013ca | 1785 | } |
wolfSSL | 13:f67a6c6013ca | 1786 | |
wolfSSL | 13:f67a6c6013ca | 1787 | /** Sets the options for a SNI object. */ |
wolfSSL | 13:f67a6c6013ca | 1788 | void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options) |
wolfSSL | 13:f67a6c6013ca | 1789 | { |
wolfSSL | 13:f67a6c6013ca | 1790 | TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:f67a6c6013ca | 1791 | SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type); |
wolfSSL | 13:f67a6c6013ca | 1792 | |
wolfSSL | 13:f67a6c6013ca | 1793 | if (sni) |
wolfSSL | 13:f67a6c6013ca | 1794 | sni->options = options; |
wolfSSL | 13:f67a6c6013ca | 1795 | } |
wolfSSL | 13:f67a6c6013ca | 1796 | |
wolfSSL | 13:f67a6c6013ca | 1797 | /** Retrieves a SNI request from a client hello buffer. */ |
wolfSSL | 13:f67a6c6013ca | 1798 | int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, |
wolfSSL | 13:f67a6c6013ca | 1799 | byte type, byte* sni, word32* inOutSz) |
wolfSSL | 13:f67a6c6013ca | 1800 | { |
wolfSSL | 13:f67a6c6013ca | 1801 | word32 offset = 0; |
wolfSSL | 13:f67a6c6013ca | 1802 | word32 len32 = 0; |
wolfSSL | 13:f67a6c6013ca | 1803 | word16 len16 = 0; |
wolfSSL | 13:f67a6c6013ca | 1804 | |
wolfSSL | 13:f67a6c6013ca | 1805 | if (helloSz < RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + CLIENT_HELLO_FIRST) |
wolfSSL | 13:f67a6c6013ca | 1806 | return INCOMPLETE_DATA; |
wolfSSL | 13:f67a6c6013ca | 1807 | |
wolfSSL | 13:f67a6c6013ca | 1808 | /* TLS record header */ |
wolfSSL | 13:f67a6c6013ca | 1809 | if ((enum ContentType) clientHello[offset++] != handshake) { |
wolfSSL | 13:f67a6c6013ca | 1810 | |
wolfSSL | 13:f67a6c6013ca | 1811 | /* checking for SSLv2.0 client hello according to: */ |
wolfSSL | 13:f67a6c6013ca | 1812 | /* http://tools.ietf.org/html/rfc4346#appendix-E.1 */ |
wolfSSL | 13:f67a6c6013ca | 1813 | if ((enum HandShakeType) clientHello[++offset] == client_hello) { |
wolfSSL | 13:f67a6c6013ca | 1814 | offset += ENUM_LEN + VERSION_SZ; /* skip version */ |
wolfSSL | 13:f67a6c6013ca | 1815 | |
wolfSSL | 13:f67a6c6013ca | 1816 | ato16(clientHello + offset, &len16); |
wolfSSL | 13:f67a6c6013ca | 1817 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 1818 | |
wolfSSL | 13:f67a6c6013ca | 1819 | if (len16 % 3) /* cipher_spec_length must be multiple of 3 */ |
wolfSSL | 13:f67a6c6013ca | 1820 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1821 | |
wolfSSL | 13:f67a6c6013ca | 1822 | ato16(clientHello + offset, &len16); |
wolfSSL | 13:f67a6c6013ca | 1823 | /* Returning SNI_UNSUPPORTED do not increment offset here */ |
wolfSSL | 13:f67a6c6013ca | 1824 | |
wolfSSL | 13:f67a6c6013ca | 1825 | if (len16 != 0) /* session_id_length must be 0 */ |
wolfSSL | 13:f67a6c6013ca | 1826 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1827 | |
wolfSSL | 13:f67a6c6013ca | 1828 | return SNI_UNSUPPORTED; |
wolfSSL | 13:f67a6c6013ca | 1829 | } |
wolfSSL | 13:f67a6c6013ca | 1830 | |
wolfSSL | 13:f67a6c6013ca | 1831 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1832 | } |
wolfSSL | 13:f67a6c6013ca | 1833 | |
wolfSSL | 13:f67a6c6013ca | 1834 | if (clientHello[offset++] != SSLv3_MAJOR) |
wolfSSL | 13:f67a6c6013ca | 1835 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1836 | |
wolfSSL | 13:f67a6c6013ca | 1837 | if (clientHello[offset++] < TLSv1_MINOR) |
wolfSSL | 13:f67a6c6013ca | 1838 | return SNI_UNSUPPORTED; |
wolfSSL | 13:f67a6c6013ca | 1839 | |
wolfSSL | 13:f67a6c6013ca | 1840 | ato16(clientHello + offset, &len16); |
wolfSSL | 13:f67a6c6013ca | 1841 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 1842 | |
wolfSSL | 13:f67a6c6013ca | 1843 | if (offset + len16 > helloSz) |
wolfSSL | 13:f67a6c6013ca | 1844 | return INCOMPLETE_DATA; |
wolfSSL | 13:f67a6c6013ca | 1845 | |
wolfSSL | 13:f67a6c6013ca | 1846 | /* Handshake header */ |
wolfSSL | 13:f67a6c6013ca | 1847 | if ((enum HandShakeType) clientHello[offset] != client_hello) |
wolfSSL | 13:f67a6c6013ca | 1848 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1849 | |
wolfSSL | 13:f67a6c6013ca | 1850 | c24to32(clientHello + offset + 1, &len32); |
wolfSSL | 13:f67a6c6013ca | 1851 | offset += HANDSHAKE_HEADER_SZ; |
wolfSSL | 13:f67a6c6013ca | 1852 | |
wolfSSL | 13:f67a6c6013ca | 1853 | if (offset + len32 > helloSz) |
wolfSSL | 13:f67a6c6013ca | 1854 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1855 | |
wolfSSL | 13:f67a6c6013ca | 1856 | /* client hello */ |
wolfSSL | 13:f67a6c6013ca | 1857 | offset += VERSION_SZ + RAN_LEN; /* version, random */ |
wolfSSL | 13:f67a6c6013ca | 1858 | |
wolfSSL | 13:f67a6c6013ca | 1859 | if (helloSz < offset + clientHello[offset]) |
wolfSSL | 13:f67a6c6013ca | 1860 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1861 | |
wolfSSL | 13:f67a6c6013ca | 1862 | offset += ENUM_LEN + clientHello[offset]; /* skip session id */ |
wolfSSL | 13:f67a6c6013ca | 1863 | |
wolfSSL | 13:f67a6c6013ca | 1864 | /* cypher suites */ |
wolfSSL | 13:f67a6c6013ca | 1865 | if (helloSz < offset + OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 1866 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1867 | |
wolfSSL | 13:f67a6c6013ca | 1868 | ato16(clientHello + offset, &len16); |
wolfSSL | 13:f67a6c6013ca | 1869 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 1870 | |
wolfSSL | 13:f67a6c6013ca | 1871 | if (helloSz < offset + len16) |
wolfSSL | 13:f67a6c6013ca | 1872 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1873 | |
wolfSSL | 13:f67a6c6013ca | 1874 | offset += len16; /* skip cypher suites */ |
wolfSSL | 13:f67a6c6013ca | 1875 | |
wolfSSL | 13:f67a6c6013ca | 1876 | /* compression methods */ |
wolfSSL | 13:f67a6c6013ca | 1877 | if (helloSz < offset + 1) |
wolfSSL | 13:f67a6c6013ca | 1878 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1879 | |
wolfSSL | 13:f67a6c6013ca | 1880 | if (helloSz < offset + clientHello[offset]) |
wolfSSL | 13:f67a6c6013ca | 1881 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1882 | |
wolfSSL | 13:f67a6c6013ca | 1883 | offset += ENUM_LEN + clientHello[offset]; /* skip compression methods */ |
wolfSSL | 13:f67a6c6013ca | 1884 | |
wolfSSL | 13:f67a6c6013ca | 1885 | /* extensions */ |
wolfSSL | 13:f67a6c6013ca | 1886 | if (helloSz < offset + OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 1887 | return 0; /* no extensions in client hello. */ |
wolfSSL | 13:f67a6c6013ca | 1888 | |
wolfSSL | 13:f67a6c6013ca | 1889 | ato16(clientHello + offset, &len16); |
wolfSSL | 13:f67a6c6013ca | 1890 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 1891 | |
wolfSSL | 13:f67a6c6013ca | 1892 | if (helloSz < offset + len16) |
wolfSSL | 13:f67a6c6013ca | 1893 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1894 | |
wolfSSL | 13:f67a6c6013ca | 1895 | while (len16 >= OPAQUE16_LEN + OPAQUE16_LEN) { |
wolfSSL | 13:f67a6c6013ca | 1896 | word16 extType; |
wolfSSL | 13:f67a6c6013ca | 1897 | word16 extLen; |
wolfSSL | 13:f67a6c6013ca | 1898 | |
wolfSSL | 13:f67a6c6013ca | 1899 | ato16(clientHello + offset, &extType); |
wolfSSL | 13:f67a6c6013ca | 1900 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 1901 | |
wolfSSL | 13:f67a6c6013ca | 1902 | ato16(clientHello + offset, &extLen); |
wolfSSL | 13:f67a6c6013ca | 1903 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 1904 | |
wolfSSL | 13:f67a6c6013ca | 1905 | if (helloSz < offset + extLen) |
wolfSSL | 13:f67a6c6013ca | 1906 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1907 | |
wolfSSL | 13:f67a6c6013ca | 1908 | if (extType != TLSX_SERVER_NAME) { |
wolfSSL | 13:f67a6c6013ca | 1909 | offset += extLen; /* skip extension */ |
wolfSSL | 13:f67a6c6013ca | 1910 | } else { |
wolfSSL | 13:f67a6c6013ca | 1911 | word16 listLen; |
wolfSSL | 13:f67a6c6013ca | 1912 | |
wolfSSL | 13:f67a6c6013ca | 1913 | ato16(clientHello + offset, &listLen); |
wolfSSL | 13:f67a6c6013ca | 1914 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 1915 | |
wolfSSL | 13:f67a6c6013ca | 1916 | if (helloSz < offset + listLen) |
wolfSSL | 13:f67a6c6013ca | 1917 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1918 | |
wolfSSL | 13:f67a6c6013ca | 1919 | while (listLen > ENUM_LEN + OPAQUE16_LEN) { |
wolfSSL | 13:f67a6c6013ca | 1920 | byte sniType = clientHello[offset++]; |
wolfSSL | 13:f67a6c6013ca | 1921 | word16 sniLen; |
wolfSSL | 13:f67a6c6013ca | 1922 | |
wolfSSL | 13:f67a6c6013ca | 1923 | ato16(clientHello + offset, &sniLen); |
wolfSSL | 13:f67a6c6013ca | 1924 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 1925 | |
wolfSSL | 13:f67a6c6013ca | 1926 | if (helloSz < offset + sniLen) |
wolfSSL | 13:f67a6c6013ca | 1927 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1928 | |
wolfSSL | 13:f67a6c6013ca | 1929 | if (sniType != type) { |
wolfSSL | 13:f67a6c6013ca | 1930 | offset += sniLen; |
wolfSSL | 13:f67a6c6013ca | 1931 | listLen -= min(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen); |
wolfSSL | 13:f67a6c6013ca | 1932 | continue; |
wolfSSL | 13:f67a6c6013ca | 1933 | } |
wolfSSL | 13:f67a6c6013ca | 1934 | |
wolfSSL | 13:f67a6c6013ca | 1935 | *inOutSz = min(sniLen, *inOutSz); |
wolfSSL | 13:f67a6c6013ca | 1936 | XMEMCPY(sni, clientHello + offset, *inOutSz); |
wolfSSL | 13:f67a6c6013ca | 1937 | |
wolfSSL | 13:f67a6c6013ca | 1938 | return SSL_SUCCESS; |
wolfSSL | 13:f67a6c6013ca | 1939 | } |
wolfSSL | 13:f67a6c6013ca | 1940 | } |
wolfSSL | 13:f67a6c6013ca | 1941 | |
wolfSSL | 13:f67a6c6013ca | 1942 | len16 -= min(2 * OPAQUE16_LEN + extLen, len16); |
wolfSSL | 13:f67a6c6013ca | 1943 | } |
wolfSSL | 13:f67a6c6013ca | 1944 | |
wolfSSL | 13:f67a6c6013ca | 1945 | return len16 ? BUFFER_ERROR : 0; |
wolfSSL | 13:f67a6c6013ca | 1946 | } |
wolfSSL | 13:f67a6c6013ca | 1947 | |
wolfSSL | 13:f67a6c6013ca | 1948 | #endif |
wolfSSL | 13:f67a6c6013ca | 1949 | |
wolfSSL | 13:f67a6c6013ca | 1950 | #define SNI_FREE_ALL TLSX_SNI_FreeAll |
wolfSSL | 13:f67a6c6013ca | 1951 | #define SNI_GET_SIZE TLSX_SNI_GetSize |
wolfSSL | 13:f67a6c6013ca | 1952 | #define SNI_WRITE TLSX_SNI_Write |
wolfSSL | 13:f67a6c6013ca | 1953 | #define SNI_PARSE TLSX_SNI_Parse |
wolfSSL | 13:f67a6c6013ca | 1954 | #define SNI_VERIFY_PARSE TLSX_SNI_VerifyParse |
wolfSSL | 13:f67a6c6013ca | 1955 | |
wolfSSL | 13:f67a6c6013ca | 1956 | #else |
wolfSSL | 13:f67a6c6013ca | 1957 | |
wolfSSL | 13:f67a6c6013ca | 1958 | #define SNI_FREE_ALL(list, heap) |
wolfSSL | 13:f67a6c6013ca | 1959 | #define SNI_GET_SIZE(list) 0 |
wolfSSL | 13:f67a6c6013ca | 1960 | #define SNI_WRITE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 1961 | #define SNI_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 1962 | #define SNI_VERIFY_PARSE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 1963 | |
wolfSSL | 13:f67a6c6013ca | 1964 | #endif /* HAVE_SNI */ |
wolfSSL | 13:f67a6c6013ca | 1965 | |
wolfSSL | 13:f67a6c6013ca | 1966 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 1967 | /* Max Fragment Length Negotiation */ |
wolfSSL | 13:f67a6c6013ca | 1968 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 1969 | |
wolfSSL | 13:f67a6c6013ca | 1970 | #ifdef HAVE_MAX_FRAGMENT |
wolfSSL | 13:f67a6c6013ca | 1971 | |
wolfSSL | 13:f67a6c6013ca | 1972 | static word16 TLSX_MFL_Write(byte* data, byte* output) |
wolfSSL | 13:f67a6c6013ca | 1973 | { |
wolfSSL | 13:f67a6c6013ca | 1974 | output[0] = data[0]; |
wolfSSL | 13:f67a6c6013ca | 1975 | |
wolfSSL | 13:f67a6c6013ca | 1976 | return ENUM_LEN; |
wolfSSL | 13:f67a6c6013ca | 1977 | } |
wolfSSL | 13:f67a6c6013ca | 1978 | |
wolfSSL | 13:f67a6c6013ca | 1979 | static int TLSX_MFL_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 1980 | byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 1981 | { |
wolfSSL | 13:f67a6c6013ca | 1982 | (void)isRequest; |
wolfSSL | 13:f67a6c6013ca | 1983 | |
wolfSSL | 13:f67a6c6013ca | 1984 | if (length != ENUM_LEN) |
wolfSSL | 13:f67a6c6013ca | 1985 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 1986 | |
wolfSSL | 13:f67a6c6013ca | 1987 | switch (*input) { |
wolfSSL | 13:f67a6c6013ca | 1988 | case WOLFSSL_MFL_2_9 : ssl->max_fragment = 512; break; |
wolfSSL | 13:f67a6c6013ca | 1989 | case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break; |
wolfSSL | 13:f67a6c6013ca | 1990 | case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break; |
wolfSSL | 13:f67a6c6013ca | 1991 | case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break; |
wolfSSL | 13:f67a6c6013ca | 1992 | case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break; |
wolfSSL | 13:f67a6c6013ca | 1993 | |
wolfSSL | 13:f67a6c6013ca | 1994 | default: |
wolfSSL | 13:f67a6c6013ca | 1995 | SendAlert(ssl, alert_fatal, illegal_parameter); |
wolfSSL | 13:f67a6c6013ca | 1996 | |
wolfSSL | 13:f67a6c6013ca | 1997 | return UNKNOWN_MAX_FRAG_LEN_E; |
wolfSSL | 13:f67a6c6013ca | 1998 | } |
wolfSSL | 13:f67a6c6013ca | 1999 | |
wolfSSL | 13:f67a6c6013ca | 2000 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 2001 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 2002 | int r = TLSX_UseMaxFragment(&ssl->extensions, *input, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 2003 | |
wolfSSL | 13:f67a6c6013ca | 2004 | if (r != SSL_SUCCESS) return r; /* throw error */ |
wolfSSL | 13:f67a6c6013ca | 2005 | |
wolfSSL | 13:f67a6c6013ca | 2006 | TLSX_SetResponse(ssl, TLSX_MAX_FRAGMENT_LENGTH); |
wolfSSL | 13:f67a6c6013ca | 2007 | } |
wolfSSL | 13:f67a6c6013ca | 2008 | #endif |
wolfSSL | 13:f67a6c6013ca | 2009 | |
wolfSSL | 13:f67a6c6013ca | 2010 | return 0; |
wolfSSL | 13:f67a6c6013ca | 2011 | } |
wolfSSL | 13:f67a6c6013ca | 2012 | |
wolfSSL | 13:f67a6c6013ca | 2013 | int TLSX_UseMaxFragment(TLSX** extensions, byte mfl, void* heap) |
wolfSSL | 13:f67a6c6013ca | 2014 | { |
wolfSSL | 13:f67a6c6013ca | 2015 | byte* data = NULL; |
wolfSSL | 13:f67a6c6013ca | 2016 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 2017 | |
wolfSSL | 13:f67a6c6013ca | 2018 | if (extensions == NULL) |
wolfSSL | 13:f67a6c6013ca | 2019 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 2020 | |
wolfSSL | 13:f67a6c6013ca | 2021 | if (mfl < WOLFSSL_MFL_2_9 || WOLFSSL_MFL_2_13 < mfl) |
wolfSSL | 13:f67a6c6013ca | 2022 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 2023 | |
wolfSSL | 13:f67a6c6013ca | 2024 | if ((data = (byte*)XMALLOC(ENUM_LEN, heap, DYNAMIC_TYPE_TLSX)) == NULL) |
wolfSSL | 13:f67a6c6013ca | 2025 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 2026 | |
wolfSSL | 13:f67a6c6013ca | 2027 | data[0] = mfl; |
wolfSSL | 13:f67a6c6013ca | 2028 | |
wolfSSL | 13:f67a6c6013ca | 2029 | /* push new MFL extension. */ |
wolfSSL | 13:f67a6c6013ca | 2030 | if ((ret = TLSX_Push(extensions, TLSX_MAX_FRAGMENT_LENGTH, data, heap)) |
wolfSSL | 13:f67a6c6013ca | 2031 | != 0) { |
wolfSSL | 13:f67a6c6013ca | 2032 | XFREE(data, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 2033 | return ret; |
wolfSSL | 13:f67a6c6013ca | 2034 | } |
wolfSSL | 13:f67a6c6013ca | 2035 | |
wolfSSL | 13:f67a6c6013ca | 2036 | return SSL_SUCCESS; |
wolfSSL | 13:f67a6c6013ca | 2037 | } |
wolfSSL | 13:f67a6c6013ca | 2038 | |
wolfSSL | 13:f67a6c6013ca | 2039 | |
wolfSSL | 13:f67a6c6013ca | 2040 | #define MFL_FREE_ALL(data, heap) XFREE(data, (heap), DYNAMIC_TYPE_TLSX) |
wolfSSL | 13:f67a6c6013ca | 2041 | #define MFL_GET_SIZE(data) ENUM_LEN |
wolfSSL | 13:f67a6c6013ca | 2042 | #define MFL_WRITE TLSX_MFL_Write |
wolfSSL | 13:f67a6c6013ca | 2043 | #define MFL_PARSE TLSX_MFL_Parse |
wolfSSL | 13:f67a6c6013ca | 2044 | |
wolfSSL | 13:f67a6c6013ca | 2045 | #else |
wolfSSL | 13:f67a6c6013ca | 2046 | |
wolfSSL | 13:f67a6c6013ca | 2047 | #define MFL_FREE_ALL(a, b) |
wolfSSL | 13:f67a6c6013ca | 2048 | #define MFL_GET_SIZE(a) 0 |
wolfSSL | 13:f67a6c6013ca | 2049 | #define MFL_WRITE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 2050 | #define MFL_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 2051 | |
wolfSSL | 13:f67a6c6013ca | 2052 | #endif /* HAVE_MAX_FRAGMENT */ |
wolfSSL | 13:f67a6c6013ca | 2053 | |
wolfSSL | 13:f67a6c6013ca | 2054 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 2055 | /* Truncated HMAC */ |
wolfSSL | 13:f67a6c6013ca | 2056 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 2057 | |
wolfSSL | 13:f67a6c6013ca | 2058 | #ifdef HAVE_TRUNCATED_HMAC |
wolfSSL | 13:f67a6c6013ca | 2059 | |
wolfSSL | 13:f67a6c6013ca | 2060 | static int TLSX_THM_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 2061 | byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 2062 | { |
wolfSSL | 13:f67a6c6013ca | 2063 | (void)isRequest; |
wolfSSL | 13:f67a6c6013ca | 2064 | |
wolfSSL | 13:f67a6c6013ca | 2065 | if (length != 0 || input == NULL) |
wolfSSL | 13:f67a6c6013ca | 2066 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 2067 | |
wolfSSL | 13:f67a6c6013ca | 2068 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 2069 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 2070 | int r = TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 2071 | |
wolfSSL | 13:f67a6c6013ca | 2072 | if (r != SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 2073 | return r; /* throw error */ |
wolfSSL | 13:f67a6c6013ca | 2074 | |
wolfSSL | 13:f67a6c6013ca | 2075 | TLSX_SetResponse(ssl, TLSX_TRUNCATED_HMAC); |
wolfSSL | 13:f67a6c6013ca | 2076 | } |
wolfSSL | 13:f67a6c6013ca | 2077 | #endif |
wolfSSL | 13:f67a6c6013ca | 2078 | |
wolfSSL | 13:f67a6c6013ca | 2079 | ssl->truncated_hmac = 1; |
wolfSSL | 13:f67a6c6013ca | 2080 | |
wolfSSL | 13:f67a6c6013ca | 2081 | return 0; |
wolfSSL | 13:f67a6c6013ca | 2082 | } |
wolfSSL | 13:f67a6c6013ca | 2083 | |
wolfSSL | 13:f67a6c6013ca | 2084 | int TLSX_UseTruncatedHMAC(TLSX** extensions, void* heap) |
wolfSSL | 13:f67a6c6013ca | 2085 | { |
wolfSSL | 13:f67a6c6013ca | 2086 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 2087 | |
wolfSSL | 13:f67a6c6013ca | 2088 | if (extensions == NULL) |
wolfSSL | 13:f67a6c6013ca | 2089 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 2090 | |
wolfSSL | 13:f67a6c6013ca | 2091 | if ((ret = TLSX_Push(extensions, TLSX_TRUNCATED_HMAC, NULL, heap)) != 0) |
wolfSSL | 13:f67a6c6013ca | 2092 | return ret; |
wolfSSL | 13:f67a6c6013ca | 2093 | |
wolfSSL | 13:f67a6c6013ca | 2094 | return SSL_SUCCESS; |
wolfSSL | 13:f67a6c6013ca | 2095 | } |
wolfSSL | 13:f67a6c6013ca | 2096 | |
wolfSSL | 13:f67a6c6013ca | 2097 | #define THM_PARSE TLSX_THM_Parse |
wolfSSL | 13:f67a6c6013ca | 2098 | |
wolfSSL | 13:f67a6c6013ca | 2099 | #else |
wolfSSL | 13:f67a6c6013ca | 2100 | |
wolfSSL | 13:f67a6c6013ca | 2101 | #define THM_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 2102 | |
wolfSSL | 13:f67a6c6013ca | 2103 | #endif /* HAVE_TRUNCATED_HMAC */ |
wolfSSL | 13:f67a6c6013ca | 2104 | |
wolfSSL | 13:f67a6c6013ca | 2105 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 2106 | /* Certificate Status Request */ |
wolfSSL | 13:f67a6c6013ca | 2107 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 2108 | |
wolfSSL | 13:f67a6c6013ca | 2109 | #ifdef HAVE_CERTIFICATE_STATUS_REQUEST |
wolfSSL | 13:f67a6c6013ca | 2110 | |
wolfSSL | 13:f67a6c6013ca | 2111 | static void TLSX_CSR_Free(CertificateStatusRequest* csr, void* heap) |
wolfSSL | 13:f67a6c6013ca | 2112 | { |
wolfSSL | 13:f67a6c6013ca | 2113 | switch (csr->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2114 | case WOLFSSL_CSR_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2115 | FreeOcspRequest(&csr->request.ocsp); |
wolfSSL | 13:f67a6c6013ca | 2116 | break; |
wolfSSL | 13:f67a6c6013ca | 2117 | } |
wolfSSL | 13:f67a6c6013ca | 2118 | |
wolfSSL | 13:f67a6c6013ca | 2119 | XFREE(csr, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 2120 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 2121 | } |
wolfSSL | 13:f67a6c6013ca | 2122 | |
wolfSSL | 13:f67a6c6013ca | 2123 | static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 2124 | { |
wolfSSL | 13:f67a6c6013ca | 2125 | word16 size = 0; |
wolfSSL | 13:f67a6c6013ca | 2126 | |
wolfSSL | 13:f67a6c6013ca | 2127 | /* shut up compiler warnings */ |
wolfSSL | 13:f67a6c6013ca | 2128 | (void) csr; (void) isRequest; |
wolfSSL | 13:f67a6c6013ca | 2129 | |
wolfSSL | 13:f67a6c6013ca | 2130 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:f67a6c6013ca | 2131 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 2132 | switch (csr->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2133 | case WOLFSSL_CSR_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2134 | size += ENUM_LEN + 2 * OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 2135 | |
wolfSSL | 13:f67a6c6013ca | 2136 | if (csr->request.ocsp.nonceSz) |
wolfSSL | 13:f67a6c6013ca | 2137 | size += OCSP_NONCE_EXT_SZ; |
wolfSSL | 13:f67a6c6013ca | 2138 | break; |
wolfSSL | 13:f67a6c6013ca | 2139 | } |
wolfSSL | 13:f67a6c6013ca | 2140 | } |
wolfSSL | 13:f67a6c6013ca | 2141 | #endif |
wolfSSL | 13:f67a6c6013ca | 2142 | |
wolfSSL | 13:f67a6c6013ca | 2143 | return size; |
wolfSSL | 13:f67a6c6013ca | 2144 | } |
wolfSSL | 13:f67a6c6013ca | 2145 | |
wolfSSL | 13:f67a6c6013ca | 2146 | static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output, |
wolfSSL | 13:f67a6c6013ca | 2147 | byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 2148 | { |
wolfSSL | 13:f67a6c6013ca | 2149 | /* shut up compiler warnings */ |
wolfSSL | 13:f67a6c6013ca | 2150 | (void) csr; (void) output; (void) isRequest; |
wolfSSL | 13:f67a6c6013ca | 2151 | |
wolfSSL | 13:f67a6c6013ca | 2152 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:f67a6c6013ca | 2153 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 2154 | word16 offset = 0; |
wolfSSL | 13:f67a6c6013ca | 2155 | word16 length = 0; |
wolfSSL | 13:f67a6c6013ca | 2156 | |
wolfSSL | 13:f67a6c6013ca | 2157 | /* type */ |
wolfSSL | 13:f67a6c6013ca | 2158 | output[offset++] = csr->status_type; |
wolfSSL | 13:f67a6c6013ca | 2159 | |
wolfSSL | 13:f67a6c6013ca | 2160 | switch (csr->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2161 | case WOLFSSL_CSR_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2162 | /* responder id list */ |
wolfSSL | 13:f67a6c6013ca | 2163 | c16toa(0, output + offset); |
wolfSSL | 13:f67a6c6013ca | 2164 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 2165 | |
wolfSSL | 13:f67a6c6013ca | 2166 | /* request extensions */ |
wolfSSL | 13:f67a6c6013ca | 2167 | if (csr->request.ocsp.nonceSz) |
wolfSSL | 13:f67a6c6013ca | 2168 | length = (word16)EncodeOcspRequestExtensions( |
wolfSSL | 13:f67a6c6013ca | 2169 | &csr->request.ocsp, |
wolfSSL | 13:f67a6c6013ca | 2170 | output + offset + OPAQUE16_LEN, |
wolfSSL | 13:f67a6c6013ca | 2171 | OCSP_NONCE_EXT_SZ); |
wolfSSL | 13:f67a6c6013ca | 2172 | |
wolfSSL | 13:f67a6c6013ca | 2173 | c16toa(length, output + offset); |
wolfSSL | 13:f67a6c6013ca | 2174 | offset += OPAQUE16_LEN + length; |
wolfSSL | 13:f67a6c6013ca | 2175 | |
wolfSSL | 13:f67a6c6013ca | 2176 | break; |
wolfSSL | 13:f67a6c6013ca | 2177 | } |
wolfSSL | 13:f67a6c6013ca | 2178 | |
wolfSSL | 13:f67a6c6013ca | 2179 | return offset; |
wolfSSL | 13:f67a6c6013ca | 2180 | } |
wolfSSL | 13:f67a6c6013ca | 2181 | #endif |
wolfSSL | 13:f67a6c6013ca | 2182 | |
wolfSSL | 13:f67a6c6013ca | 2183 | return 0; |
wolfSSL | 13:f67a6c6013ca | 2184 | } |
wolfSSL | 13:f67a6c6013ca | 2185 | |
wolfSSL | 13:f67a6c6013ca | 2186 | static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 2187 | byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 2188 | { |
wolfSSL | 13:f67a6c6013ca | 2189 | int ret; |
wolfSSL | 13:f67a6c6013ca | 2190 | |
wolfSSL | 13:f67a6c6013ca | 2191 | /* shut up compiler warnings */ |
wolfSSL | 13:f67a6c6013ca | 2192 | (void) ssl; (void) input; |
wolfSSL | 13:f67a6c6013ca | 2193 | |
wolfSSL | 13:f67a6c6013ca | 2194 | if (!isRequest) { |
wolfSSL | 13:f67a6c6013ca | 2195 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:f67a6c6013ca | 2196 | TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST); |
wolfSSL | 13:f67a6c6013ca | 2197 | CertificateStatusRequest* csr = extension ? |
wolfSSL | 13:f67a6c6013ca | 2198 | (CertificateStatusRequest*)extension->data : NULL; |
wolfSSL | 13:f67a6c6013ca | 2199 | |
wolfSSL | 13:f67a6c6013ca | 2200 | if (!csr) { |
wolfSSL | 13:f67a6c6013ca | 2201 | /* look at context level */ |
wolfSSL | 13:f67a6c6013ca | 2202 | extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST); |
wolfSSL | 13:f67a6c6013ca | 2203 | csr = extension ? (CertificateStatusRequest*)extension->data : NULL; |
wolfSSL | 13:f67a6c6013ca | 2204 | |
wolfSSL | 13:f67a6c6013ca | 2205 | if (!csr) |
wolfSSL | 13:f67a6c6013ca | 2206 | return BUFFER_ERROR; /* unexpected extension */ |
wolfSSL | 13:f67a6c6013ca | 2207 | |
wolfSSL | 13:f67a6c6013ca | 2208 | /* enable extension at ssl level */ |
wolfSSL | 13:f67a6c6013ca | 2209 | ret = TLSX_UseCertificateStatusRequest(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 2210 | csr->status_type, csr->options, ssl->heap, |
wolfSSL | 13:f67a6c6013ca | 2211 | ssl->devId); |
wolfSSL | 13:f67a6c6013ca | 2212 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 2213 | return ret; |
wolfSSL | 13:f67a6c6013ca | 2214 | |
wolfSSL | 13:f67a6c6013ca | 2215 | switch (csr->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2216 | case WOLFSSL_CSR_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2217 | /* propagate nonce */ |
wolfSSL | 13:f67a6c6013ca | 2218 | if (csr->request.ocsp.nonceSz) { |
wolfSSL | 13:f67a6c6013ca | 2219 | OcspRequest* request = |
wolfSSL | 13:f67a6c6013ca | 2220 | (OcspRequest*)TLSX_CSR_GetRequest(ssl->extensions); |
wolfSSL | 13:f67a6c6013ca | 2221 | |
wolfSSL | 13:f67a6c6013ca | 2222 | if (request) { |
wolfSSL | 13:f67a6c6013ca | 2223 | XMEMCPY(request->nonce, csr->request.ocsp.nonce, |
wolfSSL | 13:f67a6c6013ca | 2224 | csr->request.ocsp.nonceSz); |
wolfSSL | 13:f67a6c6013ca | 2225 | request->nonceSz = csr->request.ocsp.nonceSz; |
wolfSSL | 13:f67a6c6013ca | 2226 | } |
wolfSSL | 13:f67a6c6013ca | 2227 | } |
wolfSSL | 13:f67a6c6013ca | 2228 | break; |
wolfSSL | 13:f67a6c6013ca | 2229 | } |
wolfSSL | 13:f67a6c6013ca | 2230 | } |
wolfSSL | 13:f67a6c6013ca | 2231 | |
wolfSSL | 13:f67a6c6013ca | 2232 | ssl->status_request = 1; |
wolfSSL | 13:f67a6c6013ca | 2233 | |
wolfSSL | 13:f67a6c6013ca | 2234 | return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */ |
wolfSSL | 13:f67a6c6013ca | 2235 | #endif |
wolfSSL | 13:f67a6c6013ca | 2236 | } |
wolfSSL | 13:f67a6c6013ca | 2237 | else { |
wolfSSL | 13:f67a6c6013ca | 2238 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 2239 | byte status_type; |
wolfSSL | 13:f67a6c6013ca | 2240 | word16 offset = 0; |
wolfSSL | 13:f67a6c6013ca | 2241 | word16 size = 0; |
wolfSSL | 13:f67a6c6013ca | 2242 | |
wolfSSL | 13:f67a6c6013ca | 2243 | if (length < ENUM_LEN) |
wolfSSL | 13:f67a6c6013ca | 2244 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 2245 | |
wolfSSL | 13:f67a6c6013ca | 2246 | status_type = input[offset++]; |
wolfSSL | 13:f67a6c6013ca | 2247 | |
wolfSSL | 13:f67a6c6013ca | 2248 | switch (status_type) { |
wolfSSL | 13:f67a6c6013ca | 2249 | case WOLFSSL_CSR_OCSP: { |
wolfSSL | 13:f67a6c6013ca | 2250 | |
wolfSSL | 13:f67a6c6013ca | 2251 | /* skip responder_id_list */ |
wolfSSL | 13:f67a6c6013ca | 2252 | if (length - offset < OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 2253 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 2254 | |
wolfSSL | 13:f67a6c6013ca | 2255 | ato16(input + offset, &size); |
wolfSSL | 13:f67a6c6013ca | 2256 | offset += OPAQUE16_LEN + size; |
wolfSSL | 13:f67a6c6013ca | 2257 | |
wolfSSL | 13:f67a6c6013ca | 2258 | /* skip request_extensions */ |
wolfSSL | 13:f67a6c6013ca | 2259 | if (length - offset < OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 2260 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 2261 | |
wolfSSL | 13:f67a6c6013ca | 2262 | ato16(input + offset, &size); |
wolfSSL | 13:f67a6c6013ca | 2263 | offset += OPAQUE16_LEN + size; |
wolfSSL | 13:f67a6c6013ca | 2264 | |
wolfSSL | 13:f67a6c6013ca | 2265 | if (offset > length) |
wolfSSL | 13:f67a6c6013ca | 2266 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 2267 | |
wolfSSL | 13:f67a6c6013ca | 2268 | /* is able to send OCSP response? */ |
wolfSSL | 13:f67a6c6013ca | 2269 | if (ssl->ctx->cm == NULL || !ssl->ctx->cm->ocspStaplingEnabled) |
wolfSSL | 13:f67a6c6013ca | 2270 | return 0; |
wolfSSL | 13:f67a6c6013ca | 2271 | } |
wolfSSL | 13:f67a6c6013ca | 2272 | break; |
wolfSSL | 13:f67a6c6013ca | 2273 | |
wolfSSL | 13:f67a6c6013ca | 2274 | /* unknown status type */ |
wolfSSL | 13:f67a6c6013ca | 2275 | default: |
wolfSSL | 13:f67a6c6013ca | 2276 | return 0; |
wolfSSL | 13:f67a6c6013ca | 2277 | } |
wolfSSL | 13:f67a6c6013ca | 2278 | |
wolfSSL | 13:f67a6c6013ca | 2279 | /* if using status_request and already sending it, skip this one */ |
wolfSSL | 13:f67a6c6013ca | 2280 | #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 |
wolfSSL | 13:f67a6c6013ca | 2281 | if (ssl->status_request_v2) |
wolfSSL | 13:f67a6c6013ca | 2282 | return 0; |
wolfSSL | 13:f67a6c6013ca | 2283 | #endif |
wolfSSL | 13:f67a6c6013ca | 2284 | |
wolfSSL | 13:f67a6c6013ca | 2285 | /* accept the first good status_type and return */ |
wolfSSL | 13:f67a6c6013ca | 2286 | ret = TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type, |
wolfSSL | 13:f67a6c6013ca | 2287 | 0, ssl->heap, ssl->devId); |
wolfSSL | 13:f67a6c6013ca | 2288 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 2289 | return ret; /* throw error */ |
wolfSSL | 13:f67a6c6013ca | 2290 | |
wolfSSL | 13:f67a6c6013ca | 2291 | TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST); |
wolfSSL | 13:f67a6c6013ca | 2292 | ssl->status_request = status_type; |
wolfSSL | 13:f67a6c6013ca | 2293 | |
wolfSSL | 13:f67a6c6013ca | 2294 | #endif |
wolfSSL | 13:f67a6c6013ca | 2295 | } |
wolfSSL | 13:f67a6c6013ca | 2296 | |
wolfSSL | 13:f67a6c6013ca | 2297 | return 0; |
wolfSSL | 13:f67a6c6013ca | 2298 | } |
wolfSSL | 13:f67a6c6013ca | 2299 | |
wolfSSL | 13:f67a6c6013ca | 2300 | int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert, void* heap) |
wolfSSL | 13:f67a6c6013ca | 2301 | { |
wolfSSL | 13:f67a6c6013ca | 2302 | TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST); |
wolfSSL | 13:f67a6c6013ca | 2303 | CertificateStatusRequest* csr = extension ? |
wolfSSL | 13:f67a6c6013ca | 2304 | (CertificateStatusRequest*)extension->data : NULL; |
wolfSSL | 13:f67a6c6013ca | 2305 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 2306 | |
wolfSSL | 13:f67a6c6013ca | 2307 | if (csr) { |
wolfSSL | 13:f67a6c6013ca | 2308 | switch (csr->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2309 | case WOLFSSL_CSR_OCSP: { |
wolfSSL | 13:f67a6c6013ca | 2310 | byte nonce[MAX_OCSP_NONCE_SZ]; |
wolfSSL | 13:f67a6c6013ca | 2311 | int nonceSz = csr->request.ocsp.nonceSz; |
wolfSSL | 13:f67a6c6013ca | 2312 | |
wolfSSL | 13:f67a6c6013ca | 2313 | /* preserve nonce */ |
wolfSSL | 13:f67a6c6013ca | 2314 | XMEMCPY(nonce, csr->request.ocsp.nonce, nonceSz); |
wolfSSL | 13:f67a6c6013ca | 2315 | |
wolfSSL | 13:f67a6c6013ca | 2316 | if ((ret = InitOcspRequest(&csr->request.ocsp, cert, 0, heap)) |
wolfSSL | 13:f67a6c6013ca | 2317 | != 0) |
wolfSSL | 13:f67a6c6013ca | 2318 | return ret; |
wolfSSL | 13:f67a6c6013ca | 2319 | |
wolfSSL | 13:f67a6c6013ca | 2320 | /* restore nonce */ |
wolfSSL | 13:f67a6c6013ca | 2321 | XMEMCPY(csr->request.ocsp.nonce, nonce, nonceSz); |
wolfSSL | 13:f67a6c6013ca | 2322 | csr->request.ocsp.nonceSz = nonceSz; |
wolfSSL | 13:f67a6c6013ca | 2323 | } |
wolfSSL | 13:f67a6c6013ca | 2324 | break; |
wolfSSL | 13:f67a6c6013ca | 2325 | } |
wolfSSL | 13:f67a6c6013ca | 2326 | } |
wolfSSL | 13:f67a6c6013ca | 2327 | |
wolfSSL | 13:f67a6c6013ca | 2328 | return ret; |
wolfSSL | 13:f67a6c6013ca | 2329 | } |
wolfSSL | 13:f67a6c6013ca | 2330 | |
wolfSSL | 13:f67a6c6013ca | 2331 | void* TLSX_CSR_GetRequest(TLSX* extensions) |
wolfSSL | 13:f67a6c6013ca | 2332 | { |
wolfSSL | 13:f67a6c6013ca | 2333 | TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST); |
wolfSSL | 13:f67a6c6013ca | 2334 | CertificateStatusRequest* csr = extension ? |
wolfSSL | 13:f67a6c6013ca | 2335 | (CertificateStatusRequest*)extension->data : NULL; |
wolfSSL | 13:f67a6c6013ca | 2336 | |
wolfSSL | 13:f67a6c6013ca | 2337 | if (csr) { |
wolfSSL | 13:f67a6c6013ca | 2338 | switch (csr->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2339 | case WOLFSSL_CSR_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2340 | return &csr->request.ocsp; |
wolfSSL | 13:f67a6c6013ca | 2341 | break; |
wolfSSL | 13:f67a6c6013ca | 2342 | } |
wolfSSL | 13:f67a6c6013ca | 2343 | } |
wolfSSL | 13:f67a6c6013ca | 2344 | |
wolfSSL | 13:f67a6c6013ca | 2345 | return NULL; |
wolfSSL | 13:f67a6c6013ca | 2346 | } |
wolfSSL | 13:f67a6c6013ca | 2347 | |
wolfSSL | 13:f67a6c6013ca | 2348 | int TLSX_CSR_ForceRequest(WOLFSSL* ssl) |
wolfSSL | 13:f67a6c6013ca | 2349 | { |
wolfSSL | 13:f67a6c6013ca | 2350 | TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST); |
wolfSSL | 13:f67a6c6013ca | 2351 | CertificateStatusRequest* csr = extension ? |
wolfSSL | 13:f67a6c6013ca | 2352 | (CertificateStatusRequest*)extension->data : NULL; |
wolfSSL | 13:f67a6c6013ca | 2353 | |
wolfSSL | 13:f67a6c6013ca | 2354 | if (csr) { |
wolfSSL | 13:f67a6c6013ca | 2355 | switch (csr->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2356 | case WOLFSSL_CSR_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2357 | if (ssl->ctx->cm->ocspEnabled) { |
wolfSSL | 13:f67a6c6013ca | 2358 | #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) |
wolfSSL | 13:f67a6c6013ca | 2359 | csr->request.ocsp.ssl = ssl; |
wolfSSL | 13:f67a6c6013ca | 2360 | #endif |
wolfSSL | 13:f67a6c6013ca | 2361 | return CheckOcspRequest(ssl->ctx->cm->ocsp, |
wolfSSL | 13:f67a6c6013ca | 2362 | &csr->request.ocsp, NULL); |
wolfSSL | 13:f67a6c6013ca | 2363 | } |
wolfSSL | 13:f67a6c6013ca | 2364 | else |
wolfSSL | 13:f67a6c6013ca | 2365 | return OCSP_LOOKUP_FAIL; |
wolfSSL | 13:f67a6c6013ca | 2366 | } |
wolfSSL | 13:f67a6c6013ca | 2367 | } |
wolfSSL | 13:f67a6c6013ca | 2368 | |
wolfSSL | 13:f67a6c6013ca | 2369 | return 0; |
wolfSSL | 13:f67a6c6013ca | 2370 | } |
wolfSSL | 13:f67a6c6013ca | 2371 | |
wolfSSL | 13:f67a6c6013ca | 2372 | int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type, |
wolfSSL | 13:f67a6c6013ca | 2373 | byte options, void* heap, int devId) |
wolfSSL | 13:f67a6c6013ca | 2374 | { |
wolfSSL | 13:f67a6c6013ca | 2375 | CertificateStatusRequest* csr = NULL; |
wolfSSL | 13:f67a6c6013ca | 2376 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 2377 | |
wolfSSL | 13:f67a6c6013ca | 2378 | if (!extensions || status_type != WOLFSSL_CSR_OCSP) |
wolfSSL | 13:f67a6c6013ca | 2379 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 2380 | |
wolfSSL | 13:f67a6c6013ca | 2381 | csr = (CertificateStatusRequest*) |
wolfSSL | 13:f67a6c6013ca | 2382 | XMALLOC(sizeof(CertificateStatusRequest), heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 2383 | if (!csr) |
wolfSSL | 13:f67a6c6013ca | 2384 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 2385 | |
wolfSSL | 13:f67a6c6013ca | 2386 | ForceZero(csr, sizeof(CertificateStatusRequest)); |
wolfSSL | 13:f67a6c6013ca | 2387 | |
wolfSSL | 13:f67a6c6013ca | 2388 | csr->status_type = status_type; |
wolfSSL | 13:f67a6c6013ca | 2389 | csr->options = options; |
wolfSSL | 13:f67a6c6013ca | 2390 | |
wolfSSL | 13:f67a6c6013ca | 2391 | switch (csr->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2392 | case WOLFSSL_CSR_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2393 | if (options & WOLFSSL_CSR_OCSP_USE_NONCE) { |
wolfSSL | 13:f67a6c6013ca | 2394 | WC_RNG rng; |
wolfSSL | 13:f67a6c6013ca | 2395 | |
wolfSSL | 13:f67a6c6013ca | 2396 | #ifndef HAVE_FIPS |
wolfSSL | 13:f67a6c6013ca | 2397 | ret = wc_InitRng_ex(&rng, heap, devId); |
wolfSSL | 13:f67a6c6013ca | 2398 | #else |
wolfSSL | 13:f67a6c6013ca | 2399 | ret = wc_InitRng(&rng); |
wolfSSL | 13:f67a6c6013ca | 2400 | (void)devId; |
wolfSSL | 13:f67a6c6013ca | 2401 | #endif |
wolfSSL | 13:f67a6c6013ca | 2402 | if (ret == 0) { |
wolfSSL | 13:f67a6c6013ca | 2403 | if (wc_RNG_GenerateBlock(&rng, csr->request.ocsp.nonce, |
wolfSSL | 13:f67a6c6013ca | 2404 | MAX_OCSP_NONCE_SZ) == 0) |
wolfSSL | 13:f67a6c6013ca | 2405 | csr->request.ocsp.nonceSz = MAX_OCSP_NONCE_SZ; |
wolfSSL | 13:f67a6c6013ca | 2406 | |
wolfSSL | 13:f67a6c6013ca | 2407 | wc_FreeRng(&rng); |
wolfSSL | 13:f67a6c6013ca | 2408 | } |
wolfSSL | 13:f67a6c6013ca | 2409 | } |
wolfSSL | 13:f67a6c6013ca | 2410 | break; |
wolfSSL | 13:f67a6c6013ca | 2411 | } |
wolfSSL | 13:f67a6c6013ca | 2412 | |
wolfSSL | 13:f67a6c6013ca | 2413 | if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST, csr, heap)) != 0) { |
wolfSSL | 13:f67a6c6013ca | 2414 | XFREE(csr, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 2415 | return ret; |
wolfSSL | 13:f67a6c6013ca | 2416 | } |
wolfSSL | 13:f67a6c6013ca | 2417 | |
wolfSSL | 13:f67a6c6013ca | 2418 | return SSL_SUCCESS; |
wolfSSL | 13:f67a6c6013ca | 2419 | } |
wolfSSL | 13:f67a6c6013ca | 2420 | |
wolfSSL | 13:f67a6c6013ca | 2421 | #define CSR_FREE_ALL TLSX_CSR_Free |
wolfSSL | 13:f67a6c6013ca | 2422 | #define CSR_GET_SIZE TLSX_CSR_GetSize |
wolfSSL | 13:f67a6c6013ca | 2423 | #define CSR_WRITE TLSX_CSR_Write |
wolfSSL | 13:f67a6c6013ca | 2424 | #define CSR_PARSE TLSX_CSR_Parse |
wolfSSL | 13:f67a6c6013ca | 2425 | |
wolfSSL | 13:f67a6c6013ca | 2426 | #else |
wolfSSL | 13:f67a6c6013ca | 2427 | |
wolfSSL | 13:f67a6c6013ca | 2428 | #define CSR_FREE_ALL(data, heap) |
wolfSSL | 13:f67a6c6013ca | 2429 | #define CSR_GET_SIZE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 2430 | #define CSR_WRITE(a, b, c) 0 |
wolfSSL | 13:f67a6c6013ca | 2431 | #define CSR_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 2432 | |
wolfSSL | 13:f67a6c6013ca | 2433 | #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */ |
wolfSSL | 13:f67a6c6013ca | 2434 | |
wolfSSL | 13:f67a6c6013ca | 2435 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 2436 | /* Certificate Status Request v2 */ |
wolfSSL | 13:f67a6c6013ca | 2437 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 2438 | |
wolfSSL | 13:f67a6c6013ca | 2439 | #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 |
wolfSSL | 13:f67a6c6013ca | 2440 | |
wolfSSL | 13:f67a6c6013ca | 2441 | static void TLSX_CSR2_FreeAll(CertificateStatusRequestItemV2* csr2, void* heap) |
wolfSSL | 13:f67a6c6013ca | 2442 | { |
wolfSSL | 13:f67a6c6013ca | 2443 | CertificateStatusRequestItemV2* next; |
wolfSSL | 13:f67a6c6013ca | 2444 | |
wolfSSL | 13:f67a6c6013ca | 2445 | for (; csr2; csr2 = next) { |
wolfSSL | 13:f67a6c6013ca | 2446 | next = csr2->next; |
wolfSSL | 13:f67a6c6013ca | 2447 | |
wolfSSL | 13:f67a6c6013ca | 2448 | switch (csr2->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2449 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2450 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:f67a6c6013ca | 2451 | while(csr2->requests--) |
wolfSSL | 13:f67a6c6013ca | 2452 | FreeOcspRequest(&csr2->request.ocsp[csr2->requests]); |
wolfSSL | 13:f67a6c6013ca | 2453 | break; |
wolfSSL | 13:f67a6c6013ca | 2454 | } |
wolfSSL | 13:f67a6c6013ca | 2455 | |
wolfSSL | 13:f67a6c6013ca | 2456 | XFREE(csr2, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 2457 | } |
wolfSSL | 13:f67a6c6013ca | 2458 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 2459 | } |
wolfSSL | 13:f67a6c6013ca | 2460 | |
wolfSSL | 13:f67a6c6013ca | 2461 | static word16 TLSX_CSR2_GetSize(CertificateStatusRequestItemV2* csr2, |
wolfSSL | 13:f67a6c6013ca | 2462 | byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 2463 | { |
wolfSSL | 13:f67a6c6013ca | 2464 | word16 size = 0; |
wolfSSL | 13:f67a6c6013ca | 2465 | |
wolfSSL | 13:f67a6c6013ca | 2466 | /* shut up compiler warnings */ |
wolfSSL | 13:f67a6c6013ca | 2467 | (void) csr2; (void) isRequest; |
wolfSSL | 13:f67a6c6013ca | 2468 | |
wolfSSL | 13:f67a6c6013ca | 2469 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:f67a6c6013ca | 2470 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 2471 | CertificateStatusRequestItemV2* next; |
wolfSSL | 13:f67a6c6013ca | 2472 | |
wolfSSL | 13:f67a6c6013ca | 2473 | for (size = OPAQUE16_LEN; csr2; csr2 = next) { |
wolfSSL | 13:f67a6c6013ca | 2474 | next = csr2->next; |
wolfSSL | 13:f67a6c6013ca | 2475 | |
wolfSSL | 13:f67a6c6013ca | 2476 | switch (csr2->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2477 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2478 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:f67a6c6013ca | 2479 | size += ENUM_LEN + 3 * OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 2480 | |
wolfSSL | 13:f67a6c6013ca | 2481 | if (csr2->request.ocsp[0].nonceSz) |
wolfSSL | 13:f67a6c6013ca | 2482 | size += OCSP_NONCE_EXT_SZ; |
wolfSSL | 13:f67a6c6013ca | 2483 | break; |
wolfSSL | 13:f67a6c6013ca | 2484 | } |
wolfSSL | 13:f67a6c6013ca | 2485 | } |
wolfSSL | 13:f67a6c6013ca | 2486 | } |
wolfSSL | 13:f67a6c6013ca | 2487 | #endif |
wolfSSL | 13:f67a6c6013ca | 2488 | |
wolfSSL | 13:f67a6c6013ca | 2489 | return size; |
wolfSSL | 13:f67a6c6013ca | 2490 | } |
wolfSSL | 13:f67a6c6013ca | 2491 | |
wolfSSL | 13:f67a6c6013ca | 2492 | static word16 TLSX_CSR2_Write(CertificateStatusRequestItemV2* csr2, |
wolfSSL | 13:f67a6c6013ca | 2493 | byte* output, byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 2494 | { |
wolfSSL | 13:f67a6c6013ca | 2495 | /* shut up compiler warnings */ |
wolfSSL | 13:f67a6c6013ca | 2496 | (void) csr2; (void) output; (void) isRequest; |
wolfSSL | 13:f67a6c6013ca | 2497 | |
wolfSSL | 13:f67a6c6013ca | 2498 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:f67a6c6013ca | 2499 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 2500 | word16 offset; |
wolfSSL | 13:f67a6c6013ca | 2501 | word16 length; |
wolfSSL | 13:f67a6c6013ca | 2502 | |
wolfSSL | 13:f67a6c6013ca | 2503 | for (offset = OPAQUE16_LEN; csr2 != NULL; csr2 = csr2->next) { |
wolfSSL | 13:f67a6c6013ca | 2504 | /* status_type */ |
wolfSSL | 13:f67a6c6013ca | 2505 | output[offset++] = csr2->status_type; |
wolfSSL | 13:f67a6c6013ca | 2506 | |
wolfSSL | 13:f67a6c6013ca | 2507 | /* request */ |
wolfSSL | 13:f67a6c6013ca | 2508 | switch (csr2->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2509 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2510 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:f67a6c6013ca | 2511 | /* request_length */ |
wolfSSL | 13:f67a6c6013ca | 2512 | length = 2 * OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 2513 | |
wolfSSL | 13:f67a6c6013ca | 2514 | if (csr2->request.ocsp[0].nonceSz) |
wolfSSL | 13:f67a6c6013ca | 2515 | length += OCSP_NONCE_EXT_SZ; |
wolfSSL | 13:f67a6c6013ca | 2516 | |
wolfSSL | 13:f67a6c6013ca | 2517 | c16toa(length, output + offset); |
wolfSSL | 13:f67a6c6013ca | 2518 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 2519 | |
wolfSSL | 13:f67a6c6013ca | 2520 | /* responder id list */ |
wolfSSL | 13:f67a6c6013ca | 2521 | c16toa(0, output + offset); |
wolfSSL | 13:f67a6c6013ca | 2522 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 2523 | |
wolfSSL | 13:f67a6c6013ca | 2524 | /* request extensions */ |
wolfSSL | 13:f67a6c6013ca | 2525 | length = 0; |
wolfSSL | 13:f67a6c6013ca | 2526 | |
wolfSSL | 13:f67a6c6013ca | 2527 | if (csr2->request.ocsp[0].nonceSz) |
wolfSSL | 13:f67a6c6013ca | 2528 | length = (word16)EncodeOcspRequestExtensions( |
wolfSSL | 13:f67a6c6013ca | 2529 | &csr2->request.ocsp[0], |
wolfSSL | 13:f67a6c6013ca | 2530 | output + offset + OPAQUE16_LEN, |
wolfSSL | 13:f67a6c6013ca | 2531 | OCSP_NONCE_EXT_SZ); |
wolfSSL | 13:f67a6c6013ca | 2532 | |
wolfSSL | 13:f67a6c6013ca | 2533 | c16toa(length, output + offset); |
wolfSSL | 13:f67a6c6013ca | 2534 | offset += OPAQUE16_LEN + length; |
wolfSSL | 13:f67a6c6013ca | 2535 | break; |
wolfSSL | 13:f67a6c6013ca | 2536 | } |
wolfSSL | 13:f67a6c6013ca | 2537 | } |
wolfSSL | 13:f67a6c6013ca | 2538 | |
wolfSSL | 13:f67a6c6013ca | 2539 | /* list size */ |
wolfSSL | 13:f67a6c6013ca | 2540 | c16toa(offset - OPAQUE16_LEN, output); |
wolfSSL | 13:f67a6c6013ca | 2541 | |
wolfSSL | 13:f67a6c6013ca | 2542 | return offset; |
wolfSSL | 13:f67a6c6013ca | 2543 | } |
wolfSSL | 13:f67a6c6013ca | 2544 | #endif |
wolfSSL | 13:f67a6c6013ca | 2545 | |
wolfSSL | 13:f67a6c6013ca | 2546 | return 0; |
wolfSSL | 13:f67a6c6013ca | 2547 | } |
wolfSSL | 13:f67a6c6013ca | 2548 | |
wolfSSL | 13:f67a6c6013ca | 2549 | static int TLSX_CSR2_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 2550 | byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 2551 | { |
wolfSSL | 13:f67a6c6013ca | 2552 | int ret; |
wolfSSL | 13:f67a6c6013ca | 2553 | |
wolfSSL | 13:f67a6c6013ca | 2554 | /* shut up compiler warnings */ |
wolfSSL | 13:f67a6c6013ca | 2555 | (void) ssl; (void) input; |
wolfSSL | 13:f67a6c6013ca | 2556 | |
wolfSSL | 13:f67a6c6013ca | 2557 | if (!isRequest) { |
wolfSSL | 13:f67a6c6013ca | 2558 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:f67a6c6013ca | 2559 | TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2); |
wolfSSL | 13:f67a6c6013ca | 2560 | CertificateStatusRequestItemV2* csr2 = extension ? |
wolfSSL | 13:f67a6c6013ca | 2561 | (CertificateStatusRequestItemV2*)extension->data : NULL; |
wolfSSL | 13:f67a6c6013ca | 2562 | |
wolfSSL | 13:f67a6c6013ca | 2563 | if (!csr2) { |
wolfSSL | 13:f67a6c6013ca | 2564 | /* look at context level */ |
wolfSSL | 13:f67a6c6013ca | 2565 | extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST_V2); |
wolfSSL | 13:f67a6c6013ca | 2566 | csr2 = extension ? |
wolfSSL | 13:f67a6c6013ca | 2567 | (CertificateStatusRequestItemV2*)extension->data : NULL; |
wolfSSL | 13:f67a6c6013ca | 2568 | |
wolfSSL | 13:f67a6c6013ca | 2569 | if (!csr2) |
wolfSSL | 13:f67a6c6013ca | 2570 | return BUFFER_ERROR; /* unexpected extension */ |
wolfSSL | 13:f67a6c6013ca | 2571 | |
wolfSSL | 13:f67a6c6013ca | 2572 | /* enable extension at ssl level */ |
wolfSSL | 13:f67a6c6013ca | 2573 | for (; csr2; csr2 = csr2->next) { |
wolfSSL | 13:f67a6c6013ca | 2574 | ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 2575 | csr2->status_type, csr2->options, ssl->heap, ssl->devId); |
wolfSSL | 13:f67a6c6013ca | 2576 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 2577 | return ret; |
wolfSSL | 13:f67a6c6013ca | 2578 | |
wolfSSL | 13:f67a6c6013ca | 2579 | switch (csr2->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2580 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2581 | /* followed by */ |
wolfSSL | 13:f67a6c6013ca | 2582 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:f67a6c6013ca | 2583 | /* propagate nonce */ |
wolfSSL | 13:f67a6c6013ca | 2584 | if (csr2->request.ocsp[0].nonceSz) { |
wolfSSL | 13:f67a6c6013ca | 2585 | OcspRequest* request = |
wolfSSL | 13:f67a6c6013ca | 2586 | (OcspRequest*)TLSX_CSR2_GetRequest(ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 2587 | csr2->status_type, 0); |
wolfSSL | 13:f67a6c6013ca | 2588 | |
wolfSSL | 13:f67a6c6013ca | 2589 | if (request) { |
wolfSSL | 13:f67a6c6013ca | 2590 | XMEMCPY(request->nonce, |
wolfSSL | 13:f67a6c6013ca | 2591 | csr2->request.ocsp[0].nonce, |
wolfSSL | 13:f67a6c6013ca | 2592 | csr2->request.ocsp[0].nonceSz); |
wolfSSL | 13:f67a6c6013ca | 2593 | |
wolfSSL | 13:f67a6c6013ca | 2594 | request->nonceSz = |
wolfSSL | 13:f67a6c6013ca | 2595 | csr2->request.ocsp[0].nonceSz; |
wolfSSL | 13:f67a6c6013ca | 2596 | } |
wolfSSL | 13:f67a6c6013ca | 2597 | } |
wolfSSL | 13:f67a6c6013ca | 2598 | break; |
wolfSSL | 13:f67a6c6013ca | 2599 | } |
wolfSSL | 13:f67a6c6013ca | 2600 | } |
wolfSSL | 13:f67a6c6013ca | 2601 | } |
wolfSSL | 13:f67a6c6013ca | 2602 | |
wolfSSL | 13:f67a6c6013ca | 2603 | ssl->status_request_v2 = 1; |
wolfSSL | 13:f67a6c6013ca | 2604 | |
wolfSSL | 13:f67a6c6013ca | 2605 | return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */ |
wolfSSL | 13:f67a6c6013ca | 2606 | #endif |
wolfSSL | 13:f67a6c6013ca | 2607 | } |
wolfSSL | 13:f67a6c6013ca | 2608 | else { |
wolfSSL | 13:f67a6c6013ca | 2609 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 2610 | byte status_type; |
wolfSSL | 13:f67a6c6013ca | 2611 | word16 request_length; |
wolfSSL | 13:f67a6c6013ca | 2612 | word16 offset = 0; |
wolfSSL | 13:f67a6c6013ca | 2613 | word16 size = 0; |
wolfSSL | 13:f67a6c6013ca | 2614 | |
wolfSSL | 13:f67a6c6013ca | 2615 | /* list size */ |
wolfSSL | 13:f67a6c6013ca | 2616 | ato16(input + offset, &request_length); |
wolfSSL | 13:f67a6c6013ca | 2617 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 2618 | |
wolfSSL | 13:f67a6c6013ca | 2619 | if (length - OPAQUE16_LEN != request_length) |
wolfSSL | 13:f67a6c6013ca | 2620 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 2621 | |
wolfSSL | 13:f67a6c6013ca | 2622 | while (length > offset) { |
wolfSSL | 13:f67a6c6013ca | 2623 | if (length - offset < ENUM_LEN + OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 2624 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 2625 | |
wolfSSL | 13:f67a6c6013ca | 2626 | status_type = input[offset++]; |
wolfSSL | 13:f67a6c6013ca | 2627 | |
wolfSSL | 13:f67a6c6013ca | 2628 | ato16(input + offset, &request_length); |
wolfSSL | 13:f67a6c6013ca | 2629 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 2630 | |
wolfSSL | 13:f67a6c6013ca | 2631 | if (length - offset < request_length) |
wolfSSL | 13:f67a6c6013ca | 2632 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 2633 | |
wolfSSL | 13:f67a6c6013ca | 2634 | switch (status_type) { |
wolfSSL | 13:f67a6c6013ca | 2635 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2636 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:f67a6c6013ca | 2637 | /* skip responder_id_list */ |
wolfSSL | 13:f67a6c6013ca | 2638 | if (length - offset < OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 2639 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 2640 | |
wolfSSL | 13:f67a6c6013ca | 2641 | ato16(input + offset, &size); |
wolfSSL | 13:f67a6c6013ca | 2642 | offset += OPAQUE16_LEN + size; |
wolfSSL | 13:f67a6c6013ca | 2643 | |
wolfSSL | 13:f67a6c6013ca | 2644 | /* skip request_extensions */ |
wolfSSL | 13:f67a6c6013ca | 2645 | if (length - offset < OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 2646 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 2647 | |
wolfSSL | 13:f67a6c6013ca | 2648 | ato16(input + offset, &size); |
wolfSSL | 13:f67a6c6013ca | 2649 | offset += OPAQUE16_LEN + size; |
wolfSSL | 13:f67a6c6013ca | 2650 | |
wolfSSL | 13:f67a6c6013ca | 2651 | if (offset > length) |
wolfSSL | 13:f67a6c6013ca | 2652 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 2653 | |
wolfSSL | 13:f67a6c6013ca | 2654 | /* is able to send OCSP response? */ |
wolfSSL | 13:f67a6c6013ca | 2655 | if (ssl->ctx->cm == NULL |
wolfSSL | 13:f67a6c6013ca | 2656 | || !ssl->ctx->cm->ocspStaplingEnabled) |
wolfSSL | 13:f67a6c6013ca | 2657 | continue; |
wolfSSL | 13:f67a6c6013ca | 2658 | break; |
wolfSSL | 13:f67a6c6013ca | 2659 | |
wolfSSL | 13:f67a6c6013ca | 2660 | default: |
wolfSSL | 13:f67a6c6013ca | 2661 | /* unknown status type, skipping! */ |
wolfSSL | 13:f67a6c6013ca | 2662 | offset += request_length; |
wolfSSL | 13:f67a6c6013ca | 2663 | continue; |
wolfSSL | 13:f67a6c6013ca | 2664 | } |
wolfSSL | 13:f67a6c6013ca | 2665 | |
wolfSSL | 13:f67a6c6013ca | 2666 | /* if using status_request and already sending it, skip this one */ |
wolfSSL | 13:f67a6c6013ca | 2667 | #ifdef HAVE_CERTIFICATE_STATUS_REQUEST |
wolfSSL | 13:f67a6c6013ca | 2668 | if (ssl->status_request) |
wolfSSL | 13:f67a6c6013ca | 2669 | return 0; |
wolfSSL | 13:f67a6c6013ca | 2670 | #endif |
wolfSSL | 13:f67a6c6013ca | 2671 | |
wolfSSL | 13:f67a6c6013ca | 2672 | /* accept the first good status_type and return */ |
wolfSSL | 13:f67a6c6013ca | 2673 | ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 2674 | status_type, 0, ssl->heap, ssl->devId); |
wolfSSL | 13:f67a6c6013ca | 2675 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 2676 | return ret; /* throw error */ |
wolfSSL | 13:f67a6c6013ca | 2677 | |
wolfSSL | 13:f67a6c6013ca | 2678 | TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST_V2); |
wolfSSL | 13:f67a6c6013ca | 2679 | ssl->status_request_v2 = status_type; |
wolfSSL | 13:f67a6c6013ca | 2680 | |
wolfSSL | 13:f67a6c6013ca | 2681 | return 0; |
wolfSSL | 13:f67a6c6013ca | 2682 | } |
wolfSSL | 13:f67a6c6013ca | 2683 | #endif |
wolfSSL | 13:f67a6c6013ca | 2684 | } |
wolfSSL | 13:f67a6c6013ca | 2685 | |
wolfSSL | 13:f67a6c6013ca | 2686 | return 0; |
wolfSSL | 13:f67a6c6013ca | 2687 | } |
wolfSSL | 13:f67a6c6013ca | 2688 | |
wolfSSL | 13:f67a6c6013ca | 2689 | int TLSX_CSR2_InitRequests(TLSX* extensions, DecodedCert* cert, byte isPeer, |
wolfSSL | 13:f67a6c6013ca | 2690 | void* heap) |
wolfSSL | 13:f67a6c6013ca | 2691 | { |
wolfSSL | 13:f67a6c6013ca | 2692 | TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2); |
wolfSSL | 13:f67a6c6013ca | 2693 | CertificateStatusRequestItemV2* csr2 = extension ? |
wolfSSL | 13:f67a6c6013ca | 2694 | (CertificateStatusRequestItemV2*)extension->data : NULL; |
wolfSSL | 13:f67a6c6013ca | 2695 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 2696 | |
wolfSSL | 13:f67a6c6013ca | 2697 | for (; csr2; csr2 = csr2->next) { |
wolfSSL | 13:f67a6c6013ca | 2698 | switch (csr2->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2699 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2700 | if (!isPeer || csr2->requests != 0) |
wolfSSL | 13:f67a6c6013ca | 2701 | break; |
wolfSSL | 13:f67a6c6013ca | 2702 | |
wolfSSL | 13:f67a6c6013ca | 2703 | FALL_THROUGH; /* followed by */ |
wolfSSL | 13:f67a6c6013ca | 2704 | |
wolfSSL | 13:f67a6c6013ca | 2705 | case WOLFSSL_CSR2_OCSP_MULTI: { |
wolfSSL | 13:f67a6c6013ca | 2706 | if (csr2->requests < 1 + MAX_CHAIN_DEPTH) { |
wolfSSL | 13:f67a6c6013ca | 2707 | byte nonce[MAX_OCSP_NONCE_SZ]; |
wolfSSL | 13:f67a6c6013ca | 2708 | int nonceSz = csr2->request.ocsp[0].nonceSz; |
wolfSSL | 13:f67a6c6013ca | 2709 | |
wolfSSL | 13:f67a6c6013ca | 2710 | /* preserve nonce, replicating nonce of ocsp[0] */ |
wolfSSL | 13:f67a6c6013ca | 2711 | XMEMCPY(nonce, csr2->request.ocsp[0].nonce, nonceSz); |
wolfSSL | 13:f67a6c6013ca | 2712 | |
wolfSSL | 13:f67a6c6013ca | 2713 | if ((ret = InitOcspRequest( |
wolfSSL | 13:f67a6c6013ca | 2714 | &csr2->request.ocsp[csr2->requests], cert, |
wolfSSL | 13:f67a6c6013ca | 2715 | 0, heap)) != 0) |
wolfSSL | 13:f67a6c6013ca | 2716 | return ret; |
wolfSSL | 13:f67a6c6013ca | 2717 | |
wolfSSL | 13:f67a6c6013ca | 2718 | /* restore nonce */ |
wolfSSL | 13:f67a6c6013ca | 2719 | XMEMCPY(csr2->request.ocsp[csr2->requests].nonce, |
wolfSSL | 13:f67a6c6013ca | 2720 | nonce, nonceSz); |
wolfSSL | 13:f67a6c6013ca | 2721 | csr2->request.ocsp[csr2->requests].nonceSz = nonceSz; |
wolfSSL | 13:f67a6c6013ca | 2722 | csr2->requests++; |
wolfSSL | 13:f67a6c6013ca | 2723 | } |
wolfSSL | 13:f67a6c6013ca | 2724 | } |
wolfSSL | 13:f67a6c6013ca | 2725 | break; |
wolfSSL | 13:f67a6c6013ca | 2726 | } |
wolfSSL | 13:f67a6c6013ca | 2727 | } |
wolfSSL | 13:f67a6c6013ca | 2728 | |
wolfSSL | 13:f67a6c6013ca | 2729 | (void)cert; |
wolfSSL | 13:f67a6c6013ca | 2730 | return ret; |
wolfSSL | 13:f67a6c6013ca | 2731 | } |
wolfSSL | 13:f67a6c6013ca | 2732 | |
wolfSSL | 13:f67a6c6013ca | 2733 | void* TLSX_CSR2_GetRequest(TLSX* extensions, byte status_type, byte idx) |
wolfSSL | 13:f67a6c6013ca | 2734 | { |
wolfSSL | 13:f67a6c6013ca | 2735 | TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2); |
wolfSSL | 13:f67a6c6013ca | 2736 | CertificateStatusRequestItemV2* csr2 = extension ? |
wolfSSL | 13:f67a6c6013ca | 2737 | (CertificateStatusRequestItemV2*)extension->data : NULL; |
wolfSSL | 13:f67a6c6013ca | 2738 | |
wolfSSL | 13:f67a6c6013ca | 2739 | for (; csr2; csr2 = csr2->next) { |
wolfSSL | 13:f67a6c6013ca | 2740 | if (csr2->status_type == status_type) { |
wolfSSL | 13:f67a6c6013ca | 2741 | switch (csr2->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2742 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2743 | /* followed by */ |
wolfSSL | 13:f67a6c6013ca | 2744 | |
wolfSSL | 13:f67a6c6013ca | 2745 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:f67a6c6013ca | 2746 | /* requests are initialized in the reverse order */ |
wolfSSL | 13:f67a6c6013ca | 2747 | return idx < csr2->requests |
wolfSSL | 13:f67a6c6013ca | 2748 | ? &csr2->request.ocsp[csr2->requests - idx - 1] |
wolfSSL | 13:f67a6c6013ca | 2749 | : NULL; |
wolfSSL | 13:f67a6c6013ca | 2750 | break; |
wolfSSL | 13:f67a6c6013ca | 2751 | } |
wolfSSL | 13:f67a6c6013ca | 2752 | } |
wolfSSL | 13:f67a6c6013ca | 2753 | } |
wolfSSL | 13:f67a6c6013ca | 2754 | |
wolfSSL | 13:f67a6c6013ca | 2755 | return NULL; |
wolfSSL | 13:f67a6c6013ca | 2756 | } |
wolfSSL | 13:f67a6c6013ca | 2757 | |
wolfSSL | 13:f67a6c6013ca | 2758 | int TLSX_CSR2_ForceRequest(WOLFSSL* ssl) |
wolfSSL | 13:f67a6c6013ca | 2759 | { |
wolfSSL | 13:f67a6c6013ca | 2760 | TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2); |
wolfSSL | 13:f67a6c6013ca | 2761 | CertificateStatusRequestItemV2* csr2 = extension ? |
wolfSSL | 13:f67a6c6013ca | 2762 | (CertificateStatusRequestItemV2*)extension->data : NULL; |
wolfSSL | 13:f67a6c6013ca | 2763 | |
wolfSSL | 13:f67a6c6013ca | 2764 | /* forces only the first one */ |
wolfSSL | 13:f67a6c6013ca | 2765 | if (csr2) { |
wolfSSL | 13:f67a6c6013ca | 2766 | switch (csr2->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2767 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2768 | /* followed by */ |
wolfSSL | 13:f67a6c6013ca | 2769 | |
wolfSSL | 13:f67a6c6013ca | 2770 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:f67a6c6013ca | 2771 | if (ssl->ctx->cm->ocspEnabled) { |
wolfSSL | 13:f67a6c6013ca | 2772 | #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) |
wolfSSL | 13:f67a6c6013ca | 2773 | csr2->request.ocsp[0].ssl = ssl; |
wolfSSL | 13:f67a6c6013ca | 2774 | #endif |
wolfSSL | 13:f67a6c6013ca | 2775 | return CheckOcspRequest(ssl->ctx->cm->ocsp, |
wolfSSL | 13:f67a6c6013ca | 2776 | &csr2->request.ocsp[0], NULL); |
wolfSSL | 13:f67a6c6013ca | 2777 | } |
wolfSSL | 13:f67a6c6013ca | 2778 | else |
wolfSSL | 13:f67a6c6013ca | 2779 | return OCSP_LOOKUP_FAIL; |
wolfSSL | 13:f67a6c6013ca | 2780 | } |
wolfSSL | 13:f67a6c6013ca | 2781 | } |
wolfSSL | 13:f67a6c6013ca | 2782 | |
wolfSSL | 13:f67a6c6013ca | 2783 | return 0; |
wolfSSL | 13:f67a6c6013ca | 2784 | } |
wolfSSL | 13:f67a6c6013ca | 2785 | |
wolfSSL | 13:f67a6c6013ca | 2786 | int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type, |
wolfSSL | 13:f67a6c6013ca | 2787 | byte options, void* heap, int devId) |
wolfSSL | 13:f67a6c6013ca | 2788 | { |
wolfSSL | 13:f67a6c6013ca | 2789 | TLSX* extension = NULL; |
wolfSSL | 13:f67a6c6013ca | 2790 | CertificateStatusRequestItemV2* csr2 = NULL; |
wolfSSL | 13:f67a6c6013ca | 2791 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 2792 | |
wolfSSL | 13:f67a6c6013ca | 2793 | if (!extensions) |
wolfSSL | 13:f67a6c6013ca | 2794 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 2795 | |
wolfSSL | 13:f67a6c6013ca | 2796 | if (status_type != WOLFSSL_CSR2_OCSP |
wolfSSL | 13:f67a6c6013ca | 2797 | && status_type != WOLFSSL_CSR2_OCSP_MULTI) |
wolfSSL | 13:f67a6c6013ca | 2798 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 2799 | |
wolfSSL | 13:f67a6c6013ca | 2800 | csr2 = (CertificateStatusRequestItemV2*) |
wolfSSL | 13:f67a6c6013ca | 2801 | XMALLOC(sizeof(CertificateStatusRequestItemV2), heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 2802 | if (!csr2) |
wolfSSL | 13:f67a6c6013ca | 2803 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 2804 | |
wolfSSL | 13:f67a6c6013ca | 2805 | ForceZero(csr2, sizeof(CertificateStatusRequestItemV2)); |
wolfSSL | 13:f67a6c6013ca | 2806 | |
wolfSSL | 13:f67a6c6013ca | 2807 | csr2->status_type = status_type; |
wolfSSL | 13:f67a6c6013ca | 2808 | csr2->options = options; |
wolfSSL | 13:f67a6c6013ca | 2809 | csr2->next = NULL; |
wolfSSL | 13:f67a6c6013ca | 2810 | |
wolfSSL | 13:f67a6c6013ca | 2811 | switch (csr2->status_type) { |
wolfSSL | 13:f67a6c6013ca | 2812 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:f67a6c6013ca | 2813 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:f67a6c6013ca | 2814 | if (options & WOLFSSL_CSR2_OCSP_USE_NONCE) { |
wolfSSL | 13:f67a6c6013ca | 2815 | WC_RNG rng; |
wolfSSL | 13:f67a6c6013ca | 2816 | |
wolfSSL | 13:f67a6c6013ca | 2817 | #ifndef HAVE_FIPS |
wolfSSL | 13:f67a6c6013ca | 2818 | ret = wc_InitRng_ex(&rng, heap, devId); |
wolfSSL | 13:f67a6c6013ca | 2819 | #else |
wolfSSL | 13:f67a6c6013ca | 2820 | ret = wc_InitRng(&rng); |
wolfSSL | 13:f67a6c6013ca | 2821 | (void)devId; |
wolfSSL | 13:f67a6c6013ca | 2822 | #endif |
wolfSSL | 13:f67a6c6013ca | 2823 | if (ret == 0) { |
wolfSSL | 13:f67a6c6013ca | 2824 | if (wc_RNG_GenerateBlock(&rng, csr2->request.ocsp[0].nonce, |
wolfSSL | 13:f67a6c6013ca | 2825 | MAX_OCSP_NONCE_SZ) == 0) |
wolfSSL | 13:f67a6c6013ca | 2826 | csr2->request.ocsp[0].nonceSz = MAX_OCSP_NONCE_SZ; |
wolfSSL | 13:f67a6c6013ca | 2827 | |
wolfSSL | 13:f67a6c6013ca | 2828 | wc_FreeRng(&rng); |
wolfSSL | 13:f67a6c6013ca | 2829 | } |
wolfSSL | 13:f67a6c6013ca | 2830 | } |
wolfSSL | 13:f67a6c6013ca | 2831 | break; |
wolfSSL | 13:f67a6c6013ca | 2832 | } |
wolfSSL | 13:f67a6c6013ca | 2833 | |
wolfSSL | 13:f67a6c6013ca | 2834 | /* append new item */ |
wolfSSL | 13:f67a6c6013ca | 2835 | if ((extension = TLSX_Find(*extensions, TLSX_STATUS_REQUEST_V2))) { |
wolfSSL | 13:f67a6c6013ca | 2836 | CertificateStatusRequestItemV2* last = |
wolfSSL | 13:f67a6c6013ca | 2837 | (CertificateStatusRequestItemV2*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 2838 | |
wolfSSL | 13:f67a6c6013ca | 2839 | for (; last->next; last = last->next); |
wolfSSL | 13:f67a6c6013ca | 2840 | |
wolfSSL | 13:f67a6c6013ca | 2841 | last->next = csr2; |
wolfSSL | 13:f67a6c6013ca | 2842 | } |
wolfSSL | 13:f67a6c6013ca | 2843 | else if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST_V2, csr2,heap))) { |
wolfSSL | 13:f67a6c6013ca | 2844 | XFREE(csr2, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 2845 | return ret; |
wolfSSL | 13:f67a6c6013ca | 2846 | } |
wolfSSL | 13:f67a6c6013ca | 2847 | |
wolfSSL | 13:f67a6c6013ca | 2848 | return SSL_SUCCESS; |
wolfSSL | 13:f67a6c6013ca | 2849 | } |
wolfSSL | 13:f67a6c6013ca | 2850 | |
wolfSSL | 13:f67a6c6013ca | 2851 | #define CSR2_FREE_ALL TLSX_CSR2_FreeAll |
wolfSSL | 13:f67a6c6013ca | 2852 | #define CSR2_GET_SIZE TLSX_CSR2_GetSize |
wolfSSL | 13:f67a6c6013ca | 2853 | #define CSR2_WRITE TLSX_CSR2_Write |
wolfSSL | 13:f67a6c6013ca | 2854 | #define CSR2_PARSE TLSX_CSR2_Parse |
wolfSSL | 13:f67a6c6013ca | 2855 | |
wolfSSL | 13:f67a6c6013ca | 2856 | #else |
wolfSSL | 13:f67a6c6013ca | 2857 | |
wolfSSL | 13:f67a6c6013ca | 2858 | #define CSR2_FREE_ALL(data, heap) |
wolfSSL | 13:f67a6c6013ca | 2859 | #define CSR2_GET_SIZE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 2860 | #define CSR2_WRITE(a, b, c) 0 |
wolfSSL | 13:f67a6c6013ca | 2861 | #define CSR2_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 2862 | |
wolfSSL | 13:f67a6c6013ca | 2863 | #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */ |
wolfSSL | 13:f67a6c6013ca | 2864 | |
wolfSSL | 13:f67a6c6013ca | 2865 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 2866 | /* Supported Elliptic Curves */ |
wolfSSL | 13:f67a6c6013ca | 2867 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 2868 | |
wolfSSL | 13:f67a6c6013ca | 2869 | #ifdef HAVE_SUPPORTED_CURVES |
wolfSSL | 13:f67a6c6013ca | 2870 | |
wolfSSL | 13:f67a6c6013ca | 2871 | #ifndef HAVE_ECC |
wolfSSL | 13:f67a6c6013ca | 2872 | #error Elliptic Curves Extension requires Elliptic Curve Cryptography. \ |
wolfSSL | 13:f67a6c6013ca | 2873 | Use --enable-ecc in the configure script or define HAVE_ECC. |
wolfSSL | 13:f67a6c6013ca | 2874 | #endif |
wolfSSL | 13:f67a6c6013ca | 2875 | |
wolfSSL | 13:f67a6c6013ca | 2876 | static void TLSX_EllipticCurve_FreeAll(EllipticCurve* list, void* heap) |
wolfSSL | 13:f67a6c6013ca | 2877 | { |
wolfSSL | 13:f67a6c6013ca | 2878 | EllipticCurve* curve; |
wolfSSL | 13:f67a6c6013ca | 2879 | |
wolfSSL | 13:f67a6c6013ca | 2880 | while ((curve = list)) { |
wolfSSL | 13:f67a6c6013ca | 2881 | list = curve->next; |
wolfSSL | 13:f67a6c6013ca | 2882 | XFREE(curve, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 2883 | } |
wolfSSL | 13:f67a6c6013ca | 2884 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 2885 | } |
wolfSSL | 13:f67a6c6013ca | 2886 | |
wolfSSL | 13:f67a6c6013ca | 2887 | static int TLSX_EllipticCurve_Append(EllipticCurve** list, word16 name, |
wolfSSL | 13:f67a6c6013ca | 2888 | void* heap) |
wolfSSL | 13:f67a6c6013ca | 2889 | { |
wolfSSL | 13:f67a6c6013ca | 2890 | EllipticCurve* curve = NULL; |
wolfSSL | 13:f67a6c6013ca | 2891 | |
wolfSSL | 13:f67a6c6013ca | 2892 | if (list == NULL) |
wolfSSL | 13:f67a6c6013ca | 2893 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 2894 | |
wolfSSL | 13:f67a6c6013ca | 2895 | curve = (EllipticCurve*)XMALLOC(sizeof(EllipticCurve), heap, |
wolfSSL | 13:f67a6c6013ca | 2896 | DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 2897 | if (curve == NULL) |
wolfSSL | 13:f67a6c6013ca | 2898 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 2899 | |
wolfSSL | 13:f67a6c6013ca | 2900 | curve->name = name; |
wolfSSL | 13:f67a6c6013ca | 2901 | curve->next = *list; |
wolfSSL | 13:f67a6c6013ca | 2902 | |
wolfSSL | 13:f67a6c6013ca | 2903 | *list = curve; |
wolfSSL | 13:f67a6c6013ca | 2904 | |
wolfSSL | 13:f67a6c6013ca | 2905 | return 0; |
wolfSSL | 13:f67a6c6013ca | 2906 | } |
wolfSSL | 13:f67a6c6013ca | 2907 | |
wolfSSL | 13:f67a6c6013ca | 2908 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:f67a6c6013ca | 2909 | |
wolfSSL | 13:f67a6c6013ca | 2910 | static void TLSX_EllipticCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore) |
wolfSSL | 13:f67a6c6013ca | 2911 | { |
wolfSSL | 13:f67a6c6013ca | 2912 | int i; |
wolfSSL | 13:f67a6c6013ca | 2913 | |
wolfSSL | 13:f67a6c6013ca | 2914 | for (i = 0; i < ssl->suites->suiteSz; i+= 2) |
wolfSSL | 13:f67a6c6013ca | 2915 | if (ssl->suites->suites[i] == ECC_BYTE || |
wolfSSL | 13:f67a6c6013ca | 2916 | ssl->suites->suites[i] == CHACHA_BYTE || |
wolfSSL | 13:f67a6c6013ca | 2917 | ssl->suites->suites[i] == TLS13_BYTE) |
wolfSSL | 13:f67a6c6013ca | 2918 | return; |
wolfSSL | 13:f67a6c6013ca | 2919 | |
wolfSSL | 13:f67a6c6013ca | 2920 | /* turns semaphore on to avoid sending this extension. */ |
wolfSSL | 13:f67a6c6013ca | 2921 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS)); |
wolfSSL | 13:f67a6c6013ca | 2922 | } |
wolfSSL | 13:f67a6c6013ca | 2923 | |
wolfSSL | 13:f67a6c6013ca | 2924 | static word16 TLSX_EllipticCurve_GetSize(EllipticCurve* list) |
wolfSSL | 13:f67a6c6013ca | 2925 | { |
wolfSSL | 13:f67a6c6013ca | 2926 | EllipticCurve* curve; |
wolfSSL | 13:f67a6c6013ca | 2927 | word16 length = OPAQUE16_LEN; /* list length */ |
wolfSSL | 13:f67a6c6013ca | 2928 | |
wolfSSL | 13:f67a6c6013ca | 2929 | while ((curve = list)) { |
wolfSSL | 13:f67a6c6013ca | 2930 | list = curve->next; |
wolfSSL | 13:f67a6c6013ca | 2931 | length += OPAQUE16_LEN; /* curve length */ |
wolfSSL | 13:f67a6c6013ca | 2932 | } |
wolfSSL | 13:f67a6c6013ca | 2933 | |
wolfSSL | 13:f67a6c6013ca | 2934 | return length; |
wolfSSL | 13:f67a6c6013ca | 2935 | } |
wolfSSL | 13:f67a6c6013ca | 2936 | |
wolfSSL | 13:f67a6c6013ca | 2937 | static word16 TLSX_EllipticCurve_WriteR(EllipticCurve* curve, byte* output); |
wolfSSL | 13:f67a6c6013ca | 2938 | static word16 TLSX_EllipticCurve_WriteR(EllipticCurve* curve, byte* output) |
wolfSSL | 13:f67a6c6013ca | 2939 | { |
wolfSSL | 13:f67a6c6013ca | 2940 | word16 offset = 0; |
wolfSSL | 13:f67a6c6013ca | 2941 | |
wolfSSL | 13:f67a6c6013ca | 2942 | if (!curve) |
wolfSSL | 13:f67a6c6013ca | 2943 | return offset; |
wolfSSL | 13:f67a6c6013ca | 2944 | |
wolfSSL | 13:f67a6c6013ca | 2945 | offset = TLSX_EllipticCurve_WriteR(curve->next, output); |
wolfSSL | 13:f67a6c6013ca | 2946 | c16toa(curve->name, output + offset); |
wolfSSL | 13:f67a6c6013ca | 2947 | |
wolfSSL | 13:f67a6c6013ca | 2948 | return OPAQUE16_LEN + offset; |
wolfSSL | 13:f67a6c6013ca | 2949 | } |
wolfSSL | 13:f67a6c6013ca | 2950 | |
wolfSSL | 13:f67a6c6013ca | 2951 | static word16 TLSX_EllipticCurve_Write(EllipticCurve* list, byte* output) |
wolfSSL | 13:f67a6c6013ca | 2952 | { |
wolfSSL | 13:f67a6c6013ca | 2953 | word16 length = TLSX_EllipticCurve_WriteR(list, output + OPAQUE16_LEN); |
wolfSSL | 13:f67a6c6013ca | 2954 | |
wolfSSL | 13:f67a6c6013ca | 2955 | c16toa(length, output); /* writing list length */ |
wolfSSL | 13:f67a6c6013ca | 2956 | |
wolfSSL | 13:f67a6c6013ca | 2957 | return OPAQUE16_LEN + length; |
wolfSSL | 13:f67a6c6013ca | 2958 | } |
wolfSSL | 13:f67a6c6013ca | 2959 | |
wolfSSL | 13:f67a6c6013ca | 2960 | #endif /* NO_WOLFSSL_CLIENT */ |
wolfSSL | 13:f67a6c6013ca | 2961 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 2962 | |
wolfSSL | 13:f67a6c6013ca | 2963 | static int TLSX_EllipticCurve_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 2964 | byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 2965 | { |
wolfSSL | 13:f67a6c6013ca | 2966 | word16 offset; |
wolfSSL | 13:f67a6c6013ca | 2967 | word16 name; |
wolfSSL | 13:f67a6c6013ca | 2968 | int r; |
wolfSSL | 13:f67a6c6013ca | 2969 | |
wolfSSL | 13:f67a6c6013ca | 2970 | (void) isRequest; /* shut up compiler! */ |
wolfSSL | 13:f67a6c6013ca | 2971 | |
wolfSSL | 13:f67a6c6013ca | 2972 | if (OPAQUE16_LEN > length || length % OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 2973 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 2974 | |
wolfSSL | 13:f67a6c6013ca | 2975 | ato16(input, &offset); |
wolfSSL | 13:f67a6c6013ca | 2976 | |
wolfSSL | 13:f67a6c6013ca | 2977 | /* validating curve list length */ |
wolfSSL | 13:f67a6c6013ca | 2978 | if (length != OPAQUE16_LEN + offset) |
wolfSSL | 13:f67a6c6013ca | 2979 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 2980 | |
wolfSSL | 13:f67a6c6013ca | 2981 | while (offset) { |
wolfSSL | 13:f67a6c6013ca | 2982 | ato16(input + offset, &name); |
wolfSSL | 13:f67a6c6013ca | 2983 | offset -= OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 2984 | |
wolfSSL | 13:f67a6c6013ca | 2985 | r = TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 2986 | |
wolfSSL | 13:f67a6c6013ca | 2987 | if (r != SSL_SUCCESS) return r; /* throw error */ |
wolfSSL | 13:f67a6c6013ca | 2988 | } |
wolfSSL | 13:f67a6c6013ca | 2989 | |
wolfSSL | 13:f67a6c6013ca | 2990 | return 0; |
wolfSSL | 13:f67a6c6013ca | 2991 | } |
wolfSSL | 13:f67a6c6013ca | 2992 | |
wolfSSL | 13:f67a6c6013ca | 2993 | int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) { |
wolfSSL | 13:f67a6c6013ca | 2994 | TLSX* extension = (first == ECC_BYTE || first == CHACHA_BYTE) |
wolfSSL | 13:f67a6c6013ca | 2995 | ? TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS) |
wolfSSL | 13:f67a6c6013ca | 2996 | : NULL; |
wolfSSL | 13:f67a6c6013ca | 2997 | EllipticCurve* curve = NULL; |
wolfSSL | 13:f67a6c6013ca | 2998 | word32 oid = 0; |
wolfSSL | 13:f67a6c6013ca | 2999 | word32 pkOid = 0; |
wolfSSL | 13:f67a6c6013ca | 3000 | word32 defOid = 0; |
wolfSSL | 13:f67a6c6013ca | 3001 | word32 defSz = 80; /* Maximum known curve size is 66. */ |
wolfSSL | 13:f67a6c6013ca | 3002 | word32 nextOid = 0; |
wolfSSL | 13:f67a6c6013ca | 3003 | word32 nextSz = 80; /* Maximum known curve size is 66. */ |
wolfSSL | 13:f67a6c6013ca | 3004 | word32 currOid = ssl->ecdhCurveOID; |
wolfSSL | 13:f67a6c6013ca | 3005 | int ephmSuite = 0; |
wolfSSL | 13:f67a6c6013ca | 3006 | word16 octets = 0; /* according to 'ecc_set_type ecc_sets[];' */ |
wolfSSL | 13:f67a6c6013ca | 3007 | int sig = 0; /* validate signature */ |
wolfSSL | 13:f67a6c6013ca | 3008 | int key = 0; /* validate key */ |
wolfSSL | 13:f67a6c6013ca | 3009 | |
wolfSSL | 13:f67a6c6013ca | 3010 | (void)oid; |
wolfSSL | 13:f67a6c6013ca | 3011 | |
wolfSSL | 13:f67a6c6013ca | 3012 | if (!extension) |
wolfSSL | 13:f67a6c6013ca | 3013 | return 1; /* no suite restriction */ |
wolfSSL | 13:f67a6c6013ca | 3014 | |
wolfSSL | 13:f67a6c6013ca | 3015 | for (curve = (EllipticCurve*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 3016 | curve && !(sig && key); |
wolfSSL | 13:f67a6c6013ca | 3017 | curve = curve->next) { |
wolfSSL | 13:f67a6c6013ca | 3018 | |
wolfSSL | 13:f67a6c6013ca | 3019 | #ifdef OPENSSL_EXTRA |
wolfSSL | 13:f67a6c6013ca | 3020 | if (ssl->ctx->disabledCurves & (1 << curve->name)) |
wolfSSL | 13:f67a6c6013ca | 3021 | continue; |
wolfSSL | 13:f67a6c6013ca | 3022 | #endif |
wolfSSL | 13:f67a6c6013ca | 3023 | |
wolfSSL | 13:f67a6c6013ca | 3024 | /* find supported curve */ |
wolfSSL | 13:f67a6c6013ca | 3025 | switch (curve->name) { |
wolfSSL | 13:f67a6c6013ca | 3026 | #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 3027 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 3028 | case WOLFSSL_ECC_SECP160R1: |
wolfSSL | 13:f67a6c6013ca | 3029 | pkOid = oid = ECC_SECP160R1_OID; |
wolfSSL | 13:f67a6c6013ca | 3030 | octets = 20; |
wolfSSL | 13:f67a6c6013ca | 3031 | break; |
wolfSSL | 13:f67a6c6013ca | 3032 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:f67a6c6013ca | 3033 | #ifdef HAVE_ECC_SECPR2 |
wolfSSL | 13:f67a6c6013ca | 3034 | case WOLFSSL_ECC_SECP160R2: |
wolfSSL | 13:f67a6c6013ca | 3035 | pkOid = oid = ECC_SECP160R2_OID; |
wolfSSL | 13:f67a6c6013ca | 3036 | octets = 20; |
wolfSSL | 13:f67a6c6013ca | 3037 | break; |
wolfSSL | 13:f67a6c6013ca | 3038 | #endif /* HAVE_ECC_SECPR2 */ |
wolfSSL | 13:f67a6c6013ca | 3039 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:f67a6c6013ca | 3040 | case WOLFSSL_ECC_SECP160K1: |
wolfSSL | 13:f67a6c6013ca | 3041 | pkOid = oid = ECC_SECP160K1_OID; |
wolfSSL | 13:f67a6c6013ca | 3042 | octets = 20; |
wolfSSL | 13:f67a6c6013ca | 3043 | break; |
wolfSSL | 13:f67a6c6013ca | 3044 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 13:f67a6c6013ca | 3045 | #endif |
wolfSSL | 13:f67a6c6013ca | 3046 | #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 3047 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 3048 | case WOLFSSL_ECC_SECP192R1: |
wolfSSL | 13:f67a6c6013ca | 3049 | pkOid = oid = ECC_SECP192R1_OID; |
wolfSSL | 13:f67a6c6013ca | 3050 | octets = 24; |
wolfSSL | 13:f67a6c6013ca | 3051 | break; |
wolfSSL | 13:f67a6c6013ca | 3052 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:f67a6c6013ca | 3053 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:f67a6c6013ca | 3054 | case WOLFSSL_ECC_SECP192K1: |
wolfSSL | 13:f67a6c6013ca | 3055 | pkOid = oid = ECC_SECP192K1_OID; |
wolfSSL | 13:f67a6c6013ca | 3056 | octets = 24; |
wolfSSL | 13:f67a6c6013ca | 3057 | break; |
wolfSSL | 13:f67a6c6013ca | 3058 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 13:f67a6c6013ca | 3059 | #endif |
wolfSSL | 13:f67a6c6013ca | 3060 | #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 3061 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 3062 | case WOLFSSL_ECC_SECP224R1: |
wolfSSL | 13:f67a6c6013ca | 3063 | pkOid = oid = ECC_SECP224R1_OID; |
wolfSSL | 13:f67a6c6013ca | 3064 | octets = 28; |
wolfSSL | 13:f67a6c6013ca | 3065 | break; |
wolfSSL | 13:f67a6c6013ca | 3066 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:f67a6c6013ca | 3067 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:f67a6c6013ca | 3068 | case WOLFSSL_ECC_SECP224K1: |
wolfSSL | 13:f67a6c6013ca | 3069 | pkOid = oid = ECC_SECP224K1_OID; |
wolfSSL | 13:f67a6c6013ca | 3070 | octets = 28; |
wolfSSL | 13:f67a6c6013ca | 3071 | break; |
wolfSSL | 13:f67a6c6013ca | 3072 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 13:f67a6c6013ca | 3073 | #endif |
wolfSSL | 13:f67a6c6013ca | 3074 | #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 3075 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 3076 | case WOLFSSL_ECC_SECP256R1: |
wolfSSL | 13:f67a6c6013ca | 3077 | pkOid = oid = ECC_SECP256R1_OID; |
wolfSSL | 13:f67a6c6013ca | 3078 | octets = 32; |
wolfSSL | 13:f67a6c6013ca | 3079 | break; |
wolfSSL | 13:f67a6c6013ca | 3080 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:f67a6c6013ca | 3081 | #ifdef HAVE_CURVE25519 |
wolfSSL | 13:f67a6c6013ca | 3082 | case WOLFSSL_ECC_X25519: |
wolfSSL | 13:f67a6c6013ca | 3083 | oid = ECC_X25519_OID; |
wolfSSL | 13:f67a6c6013ca | 3084 | #ifdef HAVE_ED25519 |
wolfSSL | 13:f67a6c6013ca | 3085 | pkOid = ECC_ED25519_OID; |
wolfSSL | 13:f67a6c6013ca | 3086 | #else |
wolfSSL | 13:f67a6c6013ca | 3087 | pkOid = ECC_X25519_OID; |
wolfSSL | 13:f67a6c6013ca | 3088 | #endif |
wolfSSL | 13:f67a6c6013ca | 3089 | octets = 32; |
wolfSSL | 13:f67a6c6013ca | 3090 | break; |
wolfSSL | 13:f67a6c6013ca | 3091 | #endif /* HAVE_CURVE25519 */ |
wolfSSL | 13:f67a6c6013ca | 3092 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:f67a6c6013ca | 3093 | case WOLFSSL_ECC_SECP256K1: |
wolfSSL | 13:f67a6c6013ca | 3094 | pkOid = oid = ECC_SECP256K1_OID; |
wolfSSL | 13:f67a6c6013ca | 3095 | octets = 32; |
wolfSSL | 13:f67a6c6013ca | 3096 | break; |
wolfSSL | 13:f67a6c6013ca | 3097 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 13:f67a6c6013ca | 3098 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 13:f67a6c6013ca | 3099 | case WOLFSSL_ECC_BRAINPOOLP256R1: |
wolfSSL | 13:f67a6c6013ca | 3100 | pkOid = oid = ECC_BRAINPOOLP256R1_OID; |
wolfSSL | 13:f67a6c6013ca | 3101 | octets = 32; |
wolfSSL | 13:f67a6c6013ca | 3102 | break; |
wolfSSL | 13:f67a6c6013ca | 3103 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 13:f67a6c6013ca | 3104 | #endif |
wolfSSL | 13:f67a6c6013ca | 3105 | #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 3106 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 3107 | case WOLFSSL_ECC_SECP384R1: |
wolfSSL | 13:f67a6c6013ca | 3108 | pkOid = oid = ECC_SECP384R1_OID; |
wolfSSL | 13:f67a6c6013ca | 3109 | octets = 48; |
wolfSSL | 13:f67a6c6013ca | 3110 | break; |
wolfSSL | 13:f67a6c6013ca | 3111 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:f67a6c6013ca | 3112 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 13:f67a6c6013ca | 3113 | case WOLFSSL_ECC_BRAINPOOLP384R1: |
wolfSSL | 13:f67a6c6013ca | 3114 | pkOid = oid = ECC_BRAINPOOLP384R1_OID; |
wolfSSL | 13:f67a6c6013ca | 3115 | octets = 48; |
wolfSSL | 13:f67a6c6013ca | 3116 | break; |
wolfSSL | 13:f67a6c6013ca | 3117 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 13:f67a6c6013ca | 3118 | #endif |
wolfSSL | 13:f67a6c6013ca | 3119 | #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 3120 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 13:f67a6c6013ca | 3121 | case WOLFSSL_ECC_BRAINPOOLP512R1: |
wolfSSL | 13:f67a6c6013ca | 3122 | pkOid = oid = ECC_BRAINPOOLP512R1_OID; |
wolfSSL | 13:f67a6c6013ca | 3123 | octets = 64; |
wolfSSL | 13:f67a6c6013ca | 3124 | break; |
wolfSSL | 13:f67a6c6013ca | 3125 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 13:f67a6c6013ca | 3126 | #endif |
wolfSSL | 13:f67a6c6013ca | 3127 | #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 3128 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 3129 | case WOLFSSL_ECC_SECP521R1: |
wolfSSL | 13:f67a6c6013ca | 3130 | pkOid = oid = ECC_SECP521R1_OID; |
wolfSSL | 13:f67a6c6013ca | 3131 | octets = 66; |
wolfSSL | 13:f67a6c6013ca | 3132 | break; |
wolfSSL | 13:f67a6c6013ca | 3133 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:f67a6c6013ca | 3134 | #endif |
wolfSSL | 13:f67a6c6013ca | 3135 | default: continue; /* unsupported curve */ |
wolfSSL | 13:f67a6c6013ca | 3136 | } |
wolfSSL | 13:f67a6c6013ca | 3137 | |
wolfSSL | 13:f67a6c6013ca | 3138 | /* Set default Oid */ |
wolfSSL | 13:f67a6c6013ca | 3139 | if (defOid == 0 && ssl->eccTempKeySz <= octets && defSz > octets) { |
wolfSSL | 13:f67a6c6013ca | 3140 | defOid = oid; |
wolfSSL | 13:f67a6c6013ca | 3141 | defSz = octets; |
wolfSSL | 13:f67a6c6013ca | 3142 | } |
wolfSSL | 13:f67a6c6013ca | 3143 | |
wolfSSL | 13:f67a6c6013ca | 3144 | if (currOid == 0 && ssl->eccTempKeySz == octets) |
wolfSSL | 13:f67a6c6013ca | 3145 | currOid = oid; |
wolfSSL | 13:f67a6c6013ca | 3146 | if ((nextOid == 0 || nextSz > octets) && ssl->eccTempKeySz <= octets) { |
wolfSSL | 13:f67a6c6013ca | 3147 | nextOid = oid; |
wolfSSL | 13:f67a6c6013ca | 3148 | nextSz = octets; |
wolfSSL | 13:f67a6c6013ca | 3149 | } |
wolfSSL | 13:f67a6c6013ca | 3150 | |
wolfSSL | 13:f67a6c6013ca | 3151 | if (first == ECC_BYTE) { |
wolfSSL | 13:f67a6c6013ca | 3152 | switch (second) { |
wolfSSL | 13:f67a6c6013ca | 3153 | /* ECDHE_ECDSA */ |
wolfSSL | 13:f67a6c6013ca | 3154 | case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: |
wolfSSL | 13:f67a6c6013ca | 3155 | case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: |
wolfSSL | 13:f67a6c6013ca | 3156 | case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: |
wolfSSL | 13:f67a6c6013ca | 3157 | case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: |
wolfSSL | 13:f67a6c6013ca | 3158 | case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: |
wolfSSL | 13:f67a6c6013ca | 3159 | case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: |
wolfSSL | 13:f67a6c6013ca | 3160 | case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: |
wolfSSL | 13:f67a6c6013ca | 3161 | case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: |
wolfSSL | 13:f67a6c6013ca | 3162 | case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: |
wolfSSL | 13:f67a6c6013ca | 3163 | case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: |
wolfSSL | 13:f67a6c6013ca | 3164 | sig |= ssl->pkCurveOID == pkOid; |
wolfSSL | 13:f67a6c6013ca | 3165 | key |= ssl->ecdhCurveOID == oid; |
wolfSSL | 13:f67a6c6013ca | 3166 | ephmSuite = 1; |
wolfSSL | 13:f67a6c6013ca | 3167 | break; |
wolfSSL | 13:f67a6c6013ca | 3168 | |
wolfSSL | 13:f67a6c6013ca | 3169 | #ifdef WOLFSSL_STATIC_DH |
wolfSSL | 13:f67a6c6013ca | 3170 | /* ECDH_ECDSA */ |
wolfSSL | 13:f67a6c6013ca | 3171 | case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: |
wolfSSL | 13:f67a6c6013ca | 3172 | case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: |
wolfSSL | 13:f67a6c6013ca | 3173 | case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: |
wolfSSL | 13:f67a6c6013ca | 3174 | case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: |
wolfSSL | 13:f67a6c6013ca | 3175 | case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: |
wolfSSL | 13:f67a6c6013ca | 3176 | case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: |
wolfSSL | 13:f67a6c6013ca | 3177 | case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: |
wolfSSL | 13:f67a6c6013ca | 3178 | case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: |
wolfSSL | 13:f67a6c6013ca | 3179 | if (oid == ECC_X25519_OID && defOid == oid) { |
wolfSSL | 13:f67a6c6013ca | 3180 | defOid = 0; |
wolfSSL | 13:f67a6c6013ca | 3181 | defSz = 80; |
wolfSSL | 13:f67a6c6013ca | 3182 | } |
wolfSSL | 13:f67a6c6013ca | 3183 | sig |= ssl->pkCurveOID == pkOid; |
wolfSSL | 13:f67a6c6013ca | 3184 | key |= ssl->pkCurveOID == oid; |
wolfSSL | 13:f67a6c6013ca | 3185 | break; |
wolfSSL | 13:f67a6c6013ca | 3186 | #endif /* WOLFSSL_STATIC_DH */ |
wolfSSL | 13:f67a6c6013ca | 3187 | #ifndef NO_RSA |
wolfSSL | 13:f67a6c6013ca | 3188 | /* ECDHE_RSA */ |
wolfSSL | 13:f67a6c6013ca | 3189 | case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: |
wolfSSL | 13:f67a6c6013ca | 3190 | case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: |
wolfSSL | 13:f67a6c6013ca | 3191 | case TLS_ECDHE_RSA_WITH_RC4_128_SHA: |
wolfSSL | 13:f67a6c6013ca | 3192 | case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: |
wolfSSL | 13:f67a6c6013ca | 3193 | case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: |
wolfSSL | 13:f67a6c6013ca | 3194 | case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: |
wolfSSL | 13:f67a6c6013ca | 3195 | case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: |
wolfSSL | 13:f67a6c6013ca | 3196 | case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: |
wolfSSL | 13:f67a6c6013ca | 3197 | sig = 1; |
wolfSSL | 13:f67a6c6013ca | 3198 | key |= ssl->ecdhCurveOID == oid; |
wolfSSL | 13:f67a6c6013ca | 3199 | ephmSuite = 1; |
wolfSSL | 13:f67a6c6013ca | 3200 | break; |
wolfSSL | 13:f67a6c6013ca | 3201 | |
wolfSSL | 13:f67a6c6013ca | 3202 | #ifdef WOLFSSL_STATIC_DH |
wolfSSL | 13:f67a6c6013ca | 3203 | /* ECDH_RSA */ |
wolfSSL | 13:f67a6c6013ca | 3204 | case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: |
wolfSSL | 13:f67a6c6013ca | 3205 | case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: |
wolfSSL | 13:f67a6c6013ca | 3206 | case TLS_ECDH_RSA_WITH_RC4_128_SHA: |
wolfSSL | 13:f67a6c6013ca | 3207 | case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: |
wolfSSL | 13:f67a6c6013ca | 3208 | case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: |
wolfSSL | 13:f67a6c6013ca | 3209 | case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: |
wolfSSL | 13:f67a6c6013ca | 3210 | case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: |
wolfSSL | 13:f67a6c6013ca | 3211 | case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: |
wolfSSL | 13:f67a6c6013ca | 3212 | if (oid == ECC_X25519_OID && defOid == oid) { |
wolfSSL | 13:f67a6c6013ca | 3213 | defOid = 0; |
wolfSSL | 13:f67a6c6013ca | 3214 | defSz = 80; |
wolfSSL | 13:f67a6c6013ca | 3215 | } |
wolfSSL | 13:f67a6c6013ca | 3216 | sig = 1; |
wolfSSL | 13:f67a6c6013ca | 3217 | key |= ssl->pkCurveOID == pkOid; |
wolfSSL | 13:f67a6c6013ca | 3218 | break; |
wolfSSL | 13:f67a6c6013ca | 3219 | #endif /* WOLFSSL_STATIC_DH */ |
wolfSSL | 13:f67a6c6013ca | 3220 | #endif |
wolfSSL | 13:f67a6c6013ca | 3221 | default: |
wolfSSL | 13:f67a6c6013ca | 3222 | if (oid == ECC_X25519_OID && defOid == oid) { |
wolfSSL | 13:f67a6c6013ca | 3223 | defOid = 0; |
wolfSSL | 13:f67a6c6013ca | 3224 | defSz = 80; |
wolfSSL | 13:f67a6c6013ca | 3225 | } |
wolfSSL | 13:f67a6c6013ca | 3226 | if (oid != ECC_X25519_OID) |
wolfSSL | 13:f67a6c6013ca | 3227 | sig = 1; |
wolfSSL | 13:f67a6c6013ca | 3228 | key = 1; |
wolfSSL | 13:f67a6c6013ca | 3229 | break; |
wolfSSL | 13:f67a6c6013ca | 3230 | } |
wolfSSL | 13:f67a6c6013ca | 3231 | } |
wolfSSL | 13:f67a6c6013ca | 3232 | |
wolfSSL | 13:f67a6c6013ca | 3233 | /* ChaCha20-Poly1305 ECC cipher suites */ |
wolfSSL | 13:f67a6c6013ca | 3234 | if (first == CHACHA_BYTE) { |
wolfSSL | 13:f67a6c6013ca | 3235 | switch (second) { |
wolfSSL | 13:f67a6c6013ca | 3236 | /* ECDHE_ECDSA */ |
wolfSSL | 13:f67a6c6013ca | 3237 | case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 : |
wolfSSL | 13:f67a6c6013ca | 3238 | case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : |
wolfSSL | 13:f67a6c6013ca | 3239 | sig |= ssl->pkCurveOID == pkOid; |
wolfSSL | 13:f67a6c6013ca | 3240 | key |= ssl->ecdhCurveOID == oid; |
wolfSSL | 13:f67a6c6013ca | 3241 | ephmSuite = 1; |
wolfSSL | 13:f67a6c6013ca | 3242 | break; |
wolfSSL | 13:f67a6c6013ca | 3243 | #ifndef NO_RSA |
wolfSSL | 13:f67a6c6013ca | 3244 | /* ECDHE_RSA */ |
wolfSSL | 13:f67a6c6013ca | 3245 | case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 : |
wolfSSL | 13:f67a6c6013ca | 3246 | case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : |
wolfSSL | 13:f67a6c6013ca | 3247 | sig = 1; |
wolfSSL | 13:f67a6c6013ca | 3248 | key |= ssl->ecdhCurveOID == oid; |
wolfSSL | 13:f67a6c6013ca | 3249 | ephmSuite = 1; |
wolfSSL | 13:f67a6c6013ca | 3250 | break; |
wolfSSL | 13:f67a6c6013ca | 3251 | #endif |
wolfSSL | 13:f67a6c6013ca | 3252 | default: |
wolfSSL | 13:f67a6c6013ca | 3253 | sig = 1; |
wolfSSL | 13:f67a6c6013ca | 3254 | key = 1; |
wolfSSL | 13:f67a6c6013ca | 3255 | break; |
wolfSSL | 13:f67a6c6013ca | 3256 | } |
wolfSSL | 13:f67a6c6013ca | 3257 | } |
wolfSSL | 13:f67a6c6013ca | 3258 | } |
wolfSSL | 13:f67a6c6013ca | 3259 | |
wolfSSL | 13:f67a6c6013ca | 3260 | /* Choose the default if it is at the required strength. */ |
wolfSSL | 13:f67a6c6013ca | 3261 | if (ssl->ecdhCurveOID == 0 && defSz == ssl->eccTempKeySz) { |
wolfSSL | 13:f67a6c6013ca | 3262 | key = 1; |
wolfSSL | 13:f67a6c6013ca | 3263 | ssl->ecdhCurveOID = defOid; |
wolfSSL | 13:f67a6c6013ca | 3264 | } |
wolfSSL | 13:f67a6c6013ca | 3265 | /* Choose any curve at the required strength. */ |
wolfSSL | 13:f67a6c6013ca | 3266 | if (ssl->ecdhCurveOID == 0) { |
wolfSSL | 13:f67a6c6013ca | 3267 | key = 1; |
wolfSSL | 13:f67a6c6013ca | 3268 | ssl->ecdhCurveOID = currOid; |
wolfSSL | 13:f67a6c6013ca | 3269 | } |
wolfSSL | 13:f67a6c6013ca | 3270 | /* Choose the default if it is at the next highest strength. */ |
wolfSSL | 13:f67a6c6013ca | 3271 | if (ssl->ecdhCurveOID == 0 && defSz == nextSz) |
wolfSSL | 13:f67a6c6013ca | 3272 | ssl->ecdhCurveOID = defOid; |
wolfSSL | 13:f67a6c6013ca | 3273 | /* Choose any curve at the next highest strength. */ |
wolfSSL | 13:f67a6c6013ca | 3274 | if (ssl->ecdhCurveOID == 0) |
wolfSSL | 13:f67a6c6013ca | 3275 | ssl->ecdhCurveOID = nextOid; |
wolfSSL | 13:f67a6c6013ca | 3276 | /* No curve and ephemeral ECC suite requires a matching curve. */ |
wolfSSL | 13:f67a6c6013ca | 3277 | if (ssl->ecdhCurveOID == 0 && ephmSuite) |
wolfSSL | 13:f67a6c6013ca | 3278 | key = 0; |
wolfSSL | 13:f67a6c6013ca | 3279 | |
wolfSSL | 13:f67a6c6013ca | 3280 | return sig && key; |
wolfSSL | 13:f67a6c6013ca | 3281 | } |
wolfSSL | 13:f67a6c6013ca | 3282 | |
wolfSSL | 13:f67a6c6013ca | 3283 | #endif /* NO_WOLFSSL_SERVER */ |
wolfSSL | 13:f67a6c6013ca | 3284 | |
wolfSSL | 13:f67a6c6013ca | 3285 | int TLSX_UseSupportedCurve(TLSX** extensions, word16 name, void* heap) |
wolfSSL | 13:f67a6c6013ca | 3286 | { |
wolfSSL | 13:f67a6c6013ca | 3287 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 3288 | EllipticCurve* curve = NULL; |
wolfSSL | 13:f67a6c6013ca | 3289 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 3290 | |
wolfSSL | 13:f67a6c6013ca | 3291 | if (extensions == NULL) |
wolfSSL | 13:f67a6c6013ca | 3292 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 3293 | |
wolfSSL | 13:f67a6c6013ca | 3294 | if ((ret = TLSX_EllipticCurve_Append(&curve, name, heap)) != 0) |
wolfSSL | 13:f67a6c6013ca | 3295 | return ret; |
wolfSSL | 13:f67a6c6013ca | 3296 | |
wolfSSL | 13:f67a6c6013ca | 3297 | extension = TLSX_Find(*extensions, TLSX_SUPPORTED_GROUPS); |
wolfSSL | 13:f67a6c6013ca | 3298 | if (!extension) { |
wolfSSL | 13:f67a6c6013ca | 3299 | if ((ret = TLSX_Push(extensions, TLSX_SUPPORTED_GROUPS, curve, heap)) |
wolfSSL | 13:f67a6c6013ca | 3300 | != 0) { |
wolfSSL | 13:f67a6c6013ca | 3301 | XFREE(curve, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 3302 | return ret; |
wolfSSL | 13:f67a6c6013ca | 3303 | } |
wolfSSL | 13:f67a6c6013ca | 3304 | } |
wolfSSL | 13:f67a6c6013ca | 3305 | else { |
wolfSSL | 13:f67a6c6013ca | 3306 | /* push new EllipticCurve object to extension data. */ |
wolfSSL | 13:f67a6c6013ca | 3307 | curve->next = (EllipticCurve*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 3308 | extension->data = (void*)curve; |
wolfSSL | 13:f67a6c6013ca | 3309 | |
wolfSSL | 13:f67a6c6013ca | 3310 | /* look for another curve of the same name to remove (replacement) */ |
wolfSSL | 13:f67a6c6013ca | 3311 | do { |
wolfSSL | 13:f67a6c6013ca | 3312 | if (curve->next && curve->next->name == name) { |
wolfSSL | 13:f67a6c6013ca | 3313 | EllipticCurve *next = curve->next; |
wolfSSL | 13:f67a6c6013ca | 3314 | |
wolfSSL | 13:f67a6c6013ca | 3315 | curve->next = next->next; |
wolfSSL | 13:f67a6c6013ca | 3316 | XFREE(next, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 3317 | |
wolfSSL | 13:f67a6c6013ca | 3318 | break; |
wolfSSL | 13:f67a6c6013ca | 3319 | } |
wolfSSL | 13:f67a6c6013ca | 3320 | } while ((curve = curve->next)); |
wolfSSL | 13:f67a6c6013ca | 3321 | } |
wolfSSL | 13:f67a6c6013ca | 3322 | |
wolfSSL | 13:f67a6c6013ca | 3323 | return SSL_SUCCESS; |
wolfSSL | 13:f67a6c6013ca | 3324 | } |
wolfSSL | 13:f67a6c6013ca | 3325 | |
wolfSSL | 13:f67a6c6013ca | 3326 | #define EC_FREE_ALL TLSX_EllipticCurve_FreeAll |
wolfSSL | 13:f67a6c6013ca | 3327 | #define EC_VALIDATE_REQUEST TLSX_EllipticCurve_ValidateRequest |
wolfSSL | 13:f67a6c6013ca | 3328 | |
wolfSSL | 13:f67a6c6013ca | 3329 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:f67a6c6013ca | 3330 | #define EC_GET_SIZE TLSX_EllipticCurve_GetSize |
wolfSSL | 13:f67a6c6013ca | 3331 | #define EC_WRITE TLSX_EllipticCurve_Write |
wolfSSL | 13:f67a6c6013ca | 3332 | #else |
wolfSSL | 13:f67a6c6013ca | 3333 | #define EC_GET_SIZE(list) 0 |
wolfSSL | 13:f67a6c6013ca | 3334 | #define EC_WRITE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 3335 | #endif |
wolfSSL | 13:f67a6c6013ca | 3336 | |
wolfSSL | 13:f67a6c6013ca | 3337 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 3338 | #define EC_PARSE TLSX_EllipticCurve_Parse |
wolfSSL | 13:f67a6c6013ca | 3339 | #else |
wolfSSL | 13:f67a6c6013ca | 3340 | #define EC_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 3341 | #endif |
wolfSSL | 13:f67a6c6013ca | 3342 | |
wolfSSL | 13:f67a6c6013ca | 3343 | #else |
wolfSSL | 13:f67a6c6013ca | 3344 | |
wolfSSL | 13:f67a6c6013ca | 3345 | #define EC_FREE_ALL(list, heap) |
wolfSSL | 13:f67a6c6013ca | 3346 | #define EC_GET_SIZE(list) 0 |
wolfSSL | 13:f67a6c6013ca | 3347 | #define EC_WRITE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 3348 | #define EC_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 3349 | #define EC_VALIDATE_REQUEST(a, b) |
wolfSSL | 13:f67a6c6013ca | 3350 | |
wolfSSL | 13:f67a6c6013ca | 3351 | #endif /* HAVE_SUPPORTED_CURVES */ |
wolfSSL | 13:f67a6c6013ca | 3352 | |
wolfSSL | 13:f67a6c6013ca | 3353 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 3354 | /* Renegotiation Indication */ |
wolfSSL | 13:f67a6c6013ca | 3355 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 3356 | |
wolfSSL | 13:f67a6c6013ca | 3357 | #if defined(HAVE_SECURE_RENEGOTIATION) \ |
wolfSSL | 13:f67a6c6013ca | 3358 | || defined(HAVE_SERVER_RENEGOTIATION_INFO) |
wolfSSL | 13:f67a6c6013ca | 3359 | |
wolfSSL | 13:f67a6c6013ca | 3360 | static byte TLSX_SecureRenegotiation_GetSize(SecureRenegotiation* data, |
wolfSSL | 13:f67a6c6013ca | 3361 | int isRequest) |
wolfSSL | 13:f67a6c6013ca | 3362 | { |
wolfSSL | 13:f67a6c6013ca | 3363 | byte length = OPAQUE8_LEN; /* empty info length */ |
wolfSSL | 13:f67a6c6013ca | 3364 | |
wolfSSL | 13:f67a6c6013ca | 3365 | /* data will be NULL for HAVE_SERVER_RENEGOTIATION_INFO only */ |
wolfSSL | 13:f67a6c6013ca | 3366 | if (data && data->enabled) { |
wolfSSL | 13:f67a6c6013ca | 3367 | /* client sends client_verify_data only */ |
wolfSSL | 13:f67a6c6013ca | 3368 | length += TLS_FINISHED_SZ; |
wolfSSL | 13:f67a6c6013ca | 3369 | |
wolfSSL | 13:f67a6c6013ca | 3370 | /* server also sends server_verify_data */ |
wolfSSL | 13:f67a6c6013ca | 3371 | if (!isRequest) |
wolfSSL | 13:f67a6c6013ca | 3372 | length += TLS_FINISHED_SZ; |
wolfSSL | 13:f67a6c6013ca | 3373 | } |
wolfSSL | 13:f67a6c6013ca | 3374 | |
wolfSSL | 13:f67a6c6013ca | 3375 | return length; |
wolfSSL | 13:f67a6c6013ca | 3376 | } |
wolfSSL | 13:f67a6c6013ca | 3377 | |
wolfSSL | 13:f67a6c6013ca | 3378 | static word16 TLSX_SecureRenegotiation_Write(SecureRenegotiation* data, |
wolfSSL | 13:f67a6c6013ca | 3379 | byte* output, int isRequest) |
wolfSSL | 13:f67a6c6013ca | 3380 | { |
wolfSSL | 13:f67a6c6013ca | 3381 | word16 offset = OPAQUE8_LEN; /* RenegotiationInfo length */ |
wolfSSL | 13:f67a6c6013ca | 3382 | |
wolfSSL | 13:f67a6c6013ca | 3383 | if (data && data->enabled) { |
wolfSSL | 13:f67a6c6013ca | 3384 | /* client sends client_verify_data only */ |
wolfSSL | 13:f67a6c6013ca | 3385 | XMEMCPY(output + offset, data->client_verify_data, TLS_FINISHED_SZ); |
wolfSSL | 13:f67a6c6013ca | 3386 | offset += TLS_FINISHED_SZ; |
wolfSSL | 13:f67a6c6013ca | 3387 | |
wolfSSL | 13:f67a6c6013ca | 3388 | /* server also sends server_verify_data */ |
wolfSSL | 13:f67a6c6013ca | 3389 | if (!isRequest) { |
wolfSSL | 13:f67a6c6013ca | 3390 | XMEMCPY(output + offset, data->server_verify_data, TLS_FINISHED_SZ); |
wolfSSL | 13:f67a6c6013ca | 3391 | offset += TLS_FINISHED_SZ; |
wolfSSL | 13:f67a6c6013ca | 3392 | } |
wolfSSL | 13:f67a6c6013ca | 3393 | } |
wolfSSL | 13:f67a6c6013ca | 3394 | |
wolfSSL | 13:f67a6c6013ca | 3395 | output[0] = (byte)(offset - 1); /* info length - self */ |
wolfSSL | 13:f67a6c6013ca | 3396 | |
wolfSSL | 13:f67a6c6013ca | 3397 | return offset; |
wolfSSL | 13:f67a6c6013ca | 3398 | } |
wolfSSL | 13:f67a6c6013ca | 3399 | |
wolfSSL | 13:f67a6c6013ca | 3400 | static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, byte* input, |
wolfSSL | 13:f67a6c6013ca | 3401 | word16 length, byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 3402 | { |
wolfSSL | 13:f67a6c6013ca | 3403 | int ret = SECURE_RENEGOTIATION_E; |
wolfSSL | 13:f67a6c6013ca | 3404 | |
wolfSSL | 13:f67a6c6013ca | 3405 | if (length >= OPAQUE8_LEN) { |
wolfSSL | 13:f67a6c6013ca | 3406 | if (ssl->secure_renegotiation == NULL) { |
wolfSSL | 13:f67a6c6013ca | 3407 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 3408 | if (isRequest && *input == 0) { |
wolfSSL | 13:f67a6c6013ca | 3409 | #ifdef HAVE_SERVER_RENEGOTIATION_INFO |
wolfSSL | 13:f67a6c6013ca | 3410 | if (length == OPAQUE8_LEN) { |
wolfSSL | 13:f67a6c6013ca | 3411 | if (TLSX_Find(ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 3412 | TLSX_RENEGOTIATION_INFO) == NULL) { |
wolfSSL | 13:f67a6c6013ca | 3413 | ret = TLSX_AddEmptyRenegotiationInfo(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 3414 | ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 3415 | if (ret == SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 3416 | ret = 0; |
wolfSSL | 13:f67a6c6013ca | 3417 | |
wolfSSL | 13:f67a6c6013ca | 3418 | } else { |
wolfSSL | 13:f67a6c6013ca | 3419 | ret = 0; |
wolfSSL | 13:f67a6c6013ca | 3420 | } |
wolfSSL | 13:f67a6c6013ca | 3421 | } |
wolfSSL | 13:f67a6c6013ca | 3422 | #else |
wolfSSL | 13:f67a6c6013ca | 3423 | ret = 0; /* don't reply, user didn't enable */ |
wolfSSL | 13:f67a6c6013ca | 3424 | #endif /* HAVE_SERVER_RENEGOTIATION_INFO */ |
wolfSSL | 13:f67a6c6013ca | 3425 | } |
wolfSSL | 13:f67a6c6013ca | 3426 | #ifdef HAVE_SERVER_RENEGOTIATION_INFO |
wolfSSL | 13:f67a6c6013ca | 3427 | else if (!isRequest) { |
wolfSSL | 13:f67a6c6013ca | 3428 | /* don't do anything on client side */ |
wolfSSL | 13:f67a6c6013ca | 3429 | ret = 0; |
wolfSSL | 13:f67a6c6013ca | 3430 | } |
wolfSSL | 13:f67a6c6013ca | 3431 | #endif |
wolfSSL | 13:f67a6c6013ca | 3432 | #endif |
wolfSSL | 13:f67a6c6013ca | 3433 | } |
wolfSSL | 13:f67a6c6013ca | 3434 | else if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 3435 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 3436 | if (*input == TLS_FINISHED_SZ) { |
wolfSSL | 13:f67a6c6013ca | 3437 | /* TODO compare client_verify_data */ |
wolfSSL | 13:f67a6c6013ca | 3438 | ret = 0; |
wolfSSL | 13:f67a6c6013ca | 3439 | } |
wolfSSL | 13:f67a6c6013ca | 3440 | #endif |
wolfSSL | 13:f67a6c6013ca | 3441 | } |
wolfSSL | 13:f67a6c6013ca | 3442 | else { |
wolfSSL | 13:f67a6c6013ca | 3443 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:f67a6c6013ca | 3444 | if (!ssl->secure_renegotiation->enabled) { |
wolfSSL | 13:f67a6c6013ca | 3445 | if (*input == 0) { |
wolfSSL | 13:f67a6c6013ca | 3446 | ssl->secure_renegotiation->enabled = 1; |
wolfSSL | 13:f67a6c6013ca | 3447 | ret = 0; |
wolfSSL | 13:f67a6c6013ca | 3448 | } |
wolfSSL | 13:f67a6c6013ca | 3449 | } |
wolfSSL | 13:f67a6c6013ca | 3450 | else if (*input == 2 * TLS_FINISHED_SZ && |
wolfSSL | 13:f67a6c6013ca | 3451 | length == 2 * TLS_FINISHED_SZ + OPAQUE8_LEN) { |
wolfSSL | 13:f67a6c6013ca | 3452 | input++; /* get past size */ |
wolfSSL | 13:f67a6c6013ca | 3453 | |
wolfSSL | 13:f67a6c6013ca | 3454 | /* validate client and server verify data */ |
wolfSSL | 13:f67a6c6013ca | 3455 | if (XMEMCMP(input, |
wolfSSL | 13:f67a6c6013ca | 3456 | ssl->secure_renegotiation->client_verify_data, |
wolfSSL | 13:f67a6c6013ca | 3457 | TLS_FINISHED_SZ) == 0 && |
wolfSSL | 13:f67a6c6013ca | 3458 | XMEMCMP(input + TLS_FINISHED_SZ, |
wolfSSL | 13:f67a6c6013ca | 3459 | ssl->secure_renegotiation->server_verify_data, |
wolfSSL | 13:f67a6c6013ca | 3460 | TLS_FINISHED_SZ) == 0) { |
wolfSSL | 13:f67a6c6013ca | 3461 | WOLFSSL_MSG("SCR client and server verify data match"); |
wolfSSL | 13:f67a6c6013ca | 3462 | ret = 0; /* verified */ |
wolfSSL | 13:f67a6c6013ca | 3463 | } else { |
wolfSSL | 13:f67a6c6013ca | 3464 | /* already in error state */ |
wolfSSL | 13:f67a6c6013ca | 3465 | WOLFSSL_MSG("SCR client and server verify data Failure"); |
wolfSSL | 13:f67a6c6013ca | 3466 | } |
wolfSSL | 13:f67a6c6013ca | 3467 | } |
wolfSSL | 13:f67a6c6013ca | 3468 | #endif |
wolfSSL | 13:f67a6c6013ca | 3469 | } |
wolfSSL | 13:f67a6c6013ca | 3470 | } |
wolfSSL | 13:f67a6c6013ca | 3471 | |
wolfSSL | 13:f67a6c6013ca | 3472 | if (ret != 0) { |
wolfSSL | 13:f67a6c6013ca | 3473 | SendAlert(ssl, alert_fatal, handshake_failure); |
wolfSSL | 13:f67a6c6013ca | 3474 | } |
wolfSSL | 13:f67a6c6013ca | 3475 | |
wolfSSL | 13:f67a6c6013ca | 3476 | return ret; |
wolfSSL | 13:f67a6c6013ca | 3477 | } |
wolfSSL | 13:f67a6c6013ca | 3478 | |
wolfSSL | 13:f67a6c6013ca | 3479 | int TLSX_UseSecureRenegotiation(TLSX** extensions, void* heap) |
wolfSSL | 13:f67a6c6013ca | 3480 | { |
wolfSSL | 13:f67a6c6013ca | 3481 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 3482 | SecureRenegotiation* data = NULL; |
wolfSSL | 13:f67a6c6013ca | 3483 | |
wolfSSL | 13:f67a6c6013ca | 3484 | data = (SecureRenegotiation*)XMALLOC(sizeof(SecureRenegotiation), heap, |
wolfSSL | 13:f67a6c6013ca | 3485 | DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 3486 | if (data == NULL) |
wolfSSL | 13:f67a6c6013ca | 3487 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 3488 | |
wolfSSL | 13:f67a6c6013ca | 3489 | XMEMSET(data, 0, sizeof(SecureRenegotiation)); |
wolfSSL | 13:f67a6c6013ca | 3490 | |
wolfSSL | 13:f67a6c6013ca | 3491 | ret = TLSX_Push(extensions, TLSX_RENEGOTIATION_INFO, data, heap); |
wolfSSL | 13:f67a6c6013ca | 3492 | if (ret != 0) { |
wolfSSL | 13:f67a6c6013ca | 3493 | XFREE(data, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 3494 | return ret; |
wolfSSL | 13:f67a6c6013ca | 3495 | } |
wolfSSL | 13:f67a6c6013ca | 3496 | |
wolfSSL | 13:f67a6c6013ca | 3497 | return SSL_SUCCESS; |
wolfSSL | 13:f67a6c6013ca | 3498 | } |
wolfSSL | 13:f67a6c6013ca | 3499 | |
wolfSSL | 13:f67a6c6013ca | 3500 | #ifdef HAVE_SERVER_RENEGOTIATION_INFO |
wolfSSL | 13:f67a6c6013ca | 3501 | |
wolfSSL | 13:f67a6c6013ca | 3502 | int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions, void* heap) |
wolfSSL | 13:f67a6c6013ca | 3503 | { |
wolfSSL | 13:f67a6c6013ca | 3504 | int ret; |
wolfSSL | 13:f67a6c6013ca | 3505 | |
wolfSSL | 13:f67a6c6013ca | 3506 | ret = TLSX_Push(extensions, TLSX_RENEGOTIATION_INFO, NULL, heap); |
wolfSSL | 13:f67a6c6013ca | 3507 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 3508 | return ret; |
wolfSSL | 13:f67a6c6013ca | 3509 | |
wolfSSL | 13:f67a6c6013ca | 3510 | /* send empty renegotiation_info extension */ |
wolfSSL | 13:f67a6c6013ca | 3511 | TLSX* ext = TLSX_Find(*extensions, TLSX_RENEGOTIATION_INFO); |
wolfSSL | 13:f67a6c6013ca | 3512 | if (ext) |
wolfSSL | 13:f67a6c6013ca | 3513 | ext->resp = 1; |
wolfSSL | 13:f67a6c6013ca | 3514 | |
wolfSSL | 13:f67a6c6013ca | 3515 | return SSL_SUCCESS; |
wolfSSL | 13:f67a6c6013ca | 3516 | } |
wolfSSL | 13:f67a6c6013ca | 3517 | |
wolfSSL | 13:f67a6c6013ca | 3518 | #endif /* HAVE_SERVER_RENEGOTIATION_INFO */ |
wolfSSL | 13:f67a6c6013ca | 3519 | |
wolfSSL | 13:f67a6c6013ca | 3520 | |
wolfSSL | 13:f67a6c6013ca | 3521 | #define SCR_FREE_ALL(data, heap) XFREE(data, (heap), DYNAMIC_TYPE_TLSX) |
wolfSSL | 13:f67a6c6013ca | 3522 | #define SCR_GET_SIZE TLSX_SecureRenegotiation_GetSize |
wolfSSL | 13:f67a6c6013ca | 3523 | #define SCR_WRITE TLSX_SecureRenegotiation_Write |
wolfSSL | 13:f67a6c6013ca | 3524 | #define SCR_PARSE TLSX_SecureRenegotiation_Parse |
wolfSSL | 13:f67a6c6013ca | 3525 | |
wolfSSL | 13:f67a6c6013ca | 3526 | #else |
wolfSSL | 13:f67a6c6013ca | 3527 | |
wolfSSL | 13:f67a6c6013ca | 3528 | #define SCR_FREE_ALL(a, heap) |
wolfSSL | 13:f67a6c6013ca | 3529 | #define SCR_GET_SIZE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 3530 | #define SCR_WRITE(a, b, c) 0 |
wolfSSL | 13:f67a6c6013ca | 3531 | #define SCR_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 3532 | |
wolfSSL | 13:f67a6c6013ca | 3533 | #endif /* HAVE_SECURE_RENEGOTIATION */ |
wolfSSL | 13:f67a6c6013ca | 3534 | |
wolfSSL | 13:f67a6c6013ca | 3535 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 3536 | /* Session Tickets */ |
wolfSSL | 13:f67a6c6013ca | 3537 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 3538 | |
wolfSSL | 13:f67a6c6013ca | 3539 | #ifdef HAVE_SESSION_TICKET |
wolfSSL | 13:f67a6c6013ca | 3540 | |
wolfSSL | 13:f67a6c6013ca | 3541 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:f67a6c6013ca | 3542 | static void TLSX_SessionTicket_ValidateRequest(WOLFSSL* ssl) |
wolfSSL | 13:f67a6c6013ca | 3543 | { |
wolfSSL | 13:f67a6c6013ca | 3544 | TLSX* extension = TLSX_Find(ssl->extensions, TLSX_SESSION_TICKET); |
wolfSSL | 13:f67a6c6013ca | 3545 | SessionTicket* ticket = extension ? |
wolfSSL | 13:f67a6c6013ca | 3546 | (SessionTicket*)extension->data : NULL; |
wolfSSL | 13:f67a6c6013ca | 3547 | |
wolfSSL | 13:f67a6c6013ca | 3548 | if (ticket) { |
wolfSSL | 13:f67a6c6013ca | 3549 | /* TODO validate ticket timeout here! */ |
wolfSSL | 13:f67a6c6013ca | 3550 | if (ticket->lifetime == 0xfffffff) { |
wolfSSL | 13:f67a6c6013ca | 3551 | /* send empty ticket on timeout */ |
wolfSSL | 13:f67a6c6013ca | 3552 | TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 3553 | } |
wolfSSL | 13:f67a6c6013ca | 3554 | } |
wolfSSL | 13:f67a6c6013ca | 3555 | } |
wolfSSL | 13:f67a6c6013ca | 3556 | #endif /* NO_WOLFSSL_CLIENT */ |
wolfSSL | 13:f67a6c6013ca | 3557 | |
wolfSSL | 13:f67a6c6013ca | 3558 | |
wolfSSL | 13:f67a6c6013ca | 3559 | static word16 TLSX_SessionTicket_GetSize(SessionTicket* ticket, int isRequest) |
wolfSSL | 13:f67a6c6013ca | 3560 | { |
wolfSSL | 13:f67a6c6013ca | 3561 | (void)isRequest; |
wolfSSL | 13:f67a6c6013ca | 3562 | return ticket ? ticket->size : 0; |
wolfSSL | 13:f67a6c6013ca | 3563 | } |
wolfSSL | 13:f67a6c6013ca | 3564 | |
wolfSSL | 13:f67a6c6013ca | 3565 | static word16 TLSX_SessionTicket_Write(SessionTicket* ticket, byte* output, |
wolfSSL | 13:f67a6c6013ca | 3566 | int isRequest) |
wolfSSL | 13:f67a6c6013ca | 3567 | { |
wolfSSL | 13:f67a6c6013ca | 3568 | word16 offset = 0; /* empty ticket */ |
wolfSSL | 13:f67a6c6013ca | 3569 | |
wolfSSL | 13:f67a6c6013ca | 3570 | if (isRequest && ticket) { |
wolfSSL | 13:f67a6c6013ca | 3571 | XMEMCPY(output + offset, ticket->data, ticket->size); |
wolfSSL | 13:f67a6c6013ca | 3572 | offset += ticket->size; |
wolfSSL | 13:f67a6c6013ca | 3573 | } |
wolfSSL | 13:f67a6c6013ca | 3574 | |
wolfSSL | 13:f67a6c6013ca | 3575 | return offset; |
wolfSSL | 13:f67a6c6013ca | 3576 | } |
wolfSSL | 13:f67a6c6013ca | 3577 | |
wolfSSL | 13:f67a6c6013ca | 3578 | |
wolfSSL | 13:f67a6c6013ca | 3579 | static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 3580 | byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 3581 | { |
wolfSSL | 13:f67a6c6013ca | 3582 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 3583 | |
wolfSSL | 13:f67a6c6013ca | 3584 | (void) input; /* avoid unused parameter if NO_WOLFSSL_SERVER defined */ |
wolfSSL | 13:f67a6c6013ca | 3585 | |
wolfSSL | 13:f67a6c6013ca | 3586 | if (!isRequest) { |
wolfSSL | 13:f67a6c6013ca | 3587 | /* client side */ |
wolfSSL | 13:f67a6c6013ca | 3588 | if (length != 0) |
wolfSSL | 13:f67a6c6013ca | 3589 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 3590 | |
wolfSSL | 13:f67a6c6013ca | 3591 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:f67a6c6013ca | 3592 | ssl->expect_session_ticket = 1; |
wolfSSL | 13:f67a6c6013ca | 3593 | #endif |
wolfSSL | 13:f67a6c6013ca | 3594 | } |
wolfSSL | 13:f67a6c6013ca | 3595 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 3596 | else { |
wolfSSL | 13:f67a6c6013ca | 3597 | /* server side */ |
wolfSSL | 13:f67a6c6013ca | 3598 | if (ssl->ctx->ticketEncCb == NULL) { |
wolfSSL | 13:f67a6c6013ca | 3599 | WOLFSSL_MSG("Client sent session ticket, server has no callback"); |
wolfSSL | 13:f67a6c6013ca | 3600 | return 0; |
wolfSSL | 13:f67a6c6013ca | 3601 | } |
wolfSSL | 13:f67a6c6013ca | 3602 | |
wolfSSL | 13:f67a6c6013ca | 3603 | if (length == 0) { |
wolfSSL | 13:f67a6c6013ca | 3604 | /* blank ticket */ |
wolfSSL | 13:f67a6c6013ca | 3605 | ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 3606 | if (ret == SSL_SUCCESS) { |
wolfSSL | 13:f67a6c6013ca | 3607 | ret = 0; |
wolfSSL | 13:f67a6c6013ca | 3608 | TLSX_SetResponse(ssl, TLSX_SESSION_TICKET); /* send blank ticket */ |
wolfSSL | 13:f67a6c6013ca | 3609 | ssl->options.createTicket = 1; /* will send ticket msg */ |
wolfSSL | 13:f67a6c6013ca | 3610 | ssl->options.useTicket = 1; |
wolfSSL | 13:f67a6c6013ca | 3611 | ssl->options.resuming = 0; /* no standard resumption */ |
wolfSSL | 13:f67a6c6013ca | 3612 | ssl->arrays->sessionIDSz = 0; /* no echo on blank ticket */ |
wolfSSL | 13:f67a6c6013ca | 3613 | } |
wolfSSL | 13:f67a6c6013ca | 3614 | } else { |
wolfSSL | 13:f67a6c6013ca | 3615 | /* got actual ticket from client */ |
wolfSSL | 13:f67a6c6013ca | 3616 | ret = DoClientTicket(ssl, input, length); |
wolfSSL | 13:f67a6c6013ca | 3617 | if (ret == WOLFSSL_TICKET_RET_OK) { /* use ticket to resume */ |
wolfSSL | 13:f67a6c6013ca | 3618 | WOLFSSL_MSG("Using exisitng client ticket"); |
wolfSSL | 13:f67a6c6013ca | 3619 | ssl->options.useTicket = 1; |
wolfSSL | 13:f67a6c6013ca | 3620 | ssl->options.resuming = 1; |
wolfSSL | 13:f67a6c6013ca | 3621 | } else if (ret == WOLFSSL_TICKET_RET_CREATE) { |
wolfSSL | 13:f67a6c6013ca | 3622 | WOLFSSL_MSG("Using existing client ticket, creating new one"); |
wolfSSL | 13:f67a6c6013ca | 3623 | ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 3624 | if (ret == SSL_SUCCESS) { |
wolfSSL | 13:f67a6c6013ca | 3625 | ret = 0; |
wolfSSL | 13:f67a6c6013ca | 3626 | TLSX_SetResponse(ssl, TLSX_SESSION_TICKET); |
wolfSSL | 13:f67a6c6013ca | 3627 | /* send blank ticket */ |
wolfSSL | 13:f67a6c6013ca | 3628 | ssl->options.createTicket = 1; /* will send ticket msg */ |
wolfSSL | 13:f67a6c6013ca | 3629 | ssl->options.useTicket = 1; |
wolfSSL | 13:f67a6c6013ca | 3630 | ssl->options.resuming = 1; |
wolfSSL | 13:f67a6c6013ca | 3631 | } |
wolfSSL | 13:f67a6c6013ca | 3632 | } else if (ret == WOLFSSL_TICKET_RET_REJECT) { |
wolfSSL | 13:f67a6c6013ca | 3633 | WOLFSSL_MSG("Process client ticket rejected, not using"); |
wolfSSL | 13:f67a6c6013ca | 3634 | ssl->options.rejectTicket = 1; |
wolfSSL | 13:f67a6c6013ca | 3635 | ret = 0; /* not fatal */ |
wolfSSL | 13:f67a6c6013ca | 3636 | } else if (ret == WOLFSSL_TICKET_RET_FATAL || ret < 0) { |
wolfSSL | 13:f67a6c6013ca | 3637 | WOLFSSL_MSG("Process client ticket fatal error, not using"); |
wolfSSL | 13:f67a6c6013ca | 3638 | } |
wolfSSL | 13:f67a6c6013ca | 3639 | } |
wolfSSL | 13:f67a6c6013ca | 3640 | } |
wolfSSL | 13:f67a6c6013ca | 3641 | #endif /* NO_WOLFSSL_SERVER */ |
wolfSSL | 13:f67a6c6013ca | 3642 | |
wolfSSL | 13:f67a6c6013ca | 3643 | return ret; |
wolfSSL | 13:f67a6c6013ca | 3644 | } |
wolfSSL | 13:f67a6c6013ca | 3645 | |
wolfSSL | 13:f67a6c6013ca | 3646 | WOLFSSL_LOCAL SessionTicket* TLSX_SessionTicket_Create(word32 lifetime, |
wolfSSL | 13:f67a6c6013ca | 3647 | byte* data, word16 size, void* heap) |
wolfSSL | 13:f67a6c6013ca | 3648 | { |
wolfSSL | 13:f67a6c6013ca | 3649 | SessionTicket* ticket = (SessionTicket*)XMALLOC(sizeof(SessionTicket), |
wolfSSL | 13:f67a6c6013ca | 3650 | heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 3651 | if (ticket) { |
wolfSSL | 13:f67a6c6013ca | 3652 | ticket->data = (byte*)XMALLOC(size, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 3653 | if (ticket->data == NULL) { |
wolfSSL | 13:f67a6c6013ca | 3654 | XFREE(ticket, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 3655 | return NULL; |
wolfSSL | 13:f67a6c6013ca | 3656 | } |
wolfSSL | 13:f67a6c6013ca | 3657 | |
wolfSSL | 13:f67a6c6013ca | 3658 | XMEMCPY(ticket->data, data, size); |
wolfSSL | 13:f67a6c6013ca | 3659 | ticket->size = size; |
wolfSSL | 13:f67a6c6013ca | 3660 | ticket->lifetime = lifetime; |
wolfSSL | 13:f67a6c6013ca | 3661 | } |
wolfSSL | 13:f67a6c6013ca | 3662 | |
wolfSSL | 13:f67a6c6013ca | 3663 | return ticket; |
wolfSSL | 13:f67a6c6013ca | 3664 | } |
wolfSSL | 13:f67a6c6013ca | 3665 | WOLFSSL_LOCAL void TLSX_SessionTicket_Free(SessionTicket* ticket, void* heap) |
wolfSSL | 13:f67a6c6013ca | 3666 | { |
wolfSSL | 13:f67a6c6013ca | 3667 | if (ticket) { |
wolfSSL | 13:f67a6c6013ca | 3668 | XFREE(ticket->data, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 3669 | XFREE(ticket, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 3670 | } |
wolfSSL | 13:f67a6c6013ca | 3671 | |
wolfSSL | 13:f67a6c6013ca | 3672 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 3673 | } |
wolfSSL | 13:f67a6c6013ca | 3674 | |
wolfSSL | 13:f67a6c6013ca | 3675 | int TLSX_UseSessionTicket(TLSX** extensions, SessionTicket* ticket, void* heap) |
wolfSSL | 13:f67a6c6013ca | 3676 | { |
wolfSSL | 13:f67a6c6013ca | 3677 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 3678 | |
wolfSSL | 13:f67a6c6013ca | 3679 | if (extensions == NULL) |
wolfSSL | 13:f67a6c6013ca | 3680 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 3681 | |
wolfSSL | 13:f67a6c6013ca | 3682 | /* If the ticket is NULL, the client will request a new ticket from the |
wolfSSL | 13:f67a6c6013ca | 3683 | server. Otherwise, the client will use it in the next client hello. */ |
wolfSSL | 13:f67a6c6013ca | 3684 | if ((ret = TLSX_Push(extensions, TLSX_SESSION_TICKET, (void*)ticket, heap)) |
wolfSSL | 13:f67a6c6013ca | 3685 | != 0) |
wolfSSL | 13:f67a6c6013ca | 3686 | return ret; |
wolfSSL | 13:f67a6c6013ca | 3687 | |
wolfSSL | 13:f67a6c6013ca | 3688 | return SSL_SUCCESS; |
wolfSSL | 13:f67a6c6013ca | 3689 | } |
wolfSSL | 13:f67a6c6013ca | 3690 | |
wolfSSL | 13:f67a6c6013ca | 3691 | #define WOLF_STK_VALIDATE_REQUEST TLSX_SessionTicket_ValidateRequest |
wolfSSL | 13:f67a6c6013ca | 3692 | #define WOLF_STK_GET_SIZE TLSX_SessionTicket_GetSize |
wolfSSL | 13:f67a6c6013ca | 3693 | #define WOLF_STK_WRITE TLSX_SessionTicket_Write |
wolfSSL | 13:f67a6c6013ca | 3694 | #define WOLF_STK_PARSE TLSX_SessionTicket_Parse |
wolfSSL | 13:f67a6c6013ca | 3695 | #define WOLF_STK_FREE(stk, heap) TLSX_SessionTicket_Free((SessionTicket*)stk,(heap)) |
wolfSSL | 13:f67a6c6013ca | 3696 | |
wolfSSL | 13:f67a6c6013ca | 3697 | #else |
wolfSSL | 13:f67a6c6013ca | 3698 | |
wolfSSL | 13:f67a6c6013ca | 3699 | #define WOLF_STK_FREE(a, b) |
wolfSSL | 13:f67a6c6013ca | 3700 | #define WOLF_STK_VALIDATE_REQUEST(a) |
wolfSSL | 13:f67a6c6013ca | 3701 | #define WOLF_STK_GET_SIZE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 3702 | #define WOLF_STK_WRITE(a, b, c) 0 |
wolfSSL | 13:f67a6c6013ca | 3703 | #define WOLF_STK_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 3704 | |
wolfSSL | 13:f67a6c6013ca | 3705 | #endif /* HAVE_SESSION_TICKET */ |
wolfSSL | 13:f67a6c6013ca | 3706 | |
wolfSSL | 13:f67a6c6013ca | 3707 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 3708 | /* Quantum-Safe-Hybrid */ |
wolfSSL | 13:f67a6c6013ca | 3709 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 3710 | |
wolfSSL | 13:f67a6c6013ca | 3711 | #if defined(HAVE_NTRU) |
wolfSSL | 13:f67a6c6013ca | 3712 | static WC_RNG* gRng; |
wolfSSL | 13:f67a6c6013ca | 3713 | static wolfSSL_Mutex* gRngMutex; |
wolfSSL | 13:f67a6c6013ca | 3714 | #endif |
wolfSSL | 13:f67a6c6013ca | 3715 | |
wolfSSL | 13:f67a6c6013ca | 3716 | #ifdef HAVE_QSH |
wolfSSL | 13:f67a6c6013ca | 3717 | static void TLSX_QSH_FreeAll(QSHScheme* list, void* heap) |
wolfSSL | 13:f67a6c6013ca | 3718 | { |
wolfSSL | 13:f67a6c6013ca | 3719 | QSHScheme* current; |
wolfSSL | 13:f67a6c6013ca | 3720 | |
wolfSSL | 13:f67a6c6013ca | 3721 | while ((current = list)) { |
wolfSSL | 13:f67a6c6013ca | 3722 | list = current->next; |
wolfSSL | 13:f67a6c6013ca | 3723 | XFREE(current, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 3724 | } |
wolfSSL | 13:f67a6c6013ca | 3725 | |
wolfSSL | 13:f67a6c6013ca | 3726 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 3727 | } |
wolfSSL | 13:f67a6c6013ca | 3728 | |
wolfSSL | 13:f67a6c6013ca | 3729 | static int TLSX_QSH_Append(QSHScheme** list, word16 name, byte* pub, |
wolfSSL | 13:f67a6c6013ca | 3730 | word16 pubLen) |
wolfSSL | 13:f67a6c6013ca | 3731 | { |
wolfSSL | 13:f67a6c6013ca | 3732 | QSHScheme* temp; |
wolfSSL | 13:f67a6c6013ca | 3733 | |
wolfSSL | 13:f67a6c6013ca | 3734 | if (list == NULL) |
wolfSSL | 13:f67a6c6013ca | 3735 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 3736 | |
wolfSSL | 13:f67a6c6013ca | 3737 | if ((temp = (QSHScheme*)XMALLOC(sizeof(QSHScheme), NULL, |
wolfSSL | 13:f67a6c6013ca | 3738 | DYNAMIC_TYPE_TLSX)) == NULL) |
wolfSSL | 13:f67a6c6013ca | 3739 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 3740 | |
wolfSSL | 13:f67a6c6013ca | 3741 | temp->name = name; |
wolfSSL | 13:f67a6c6013ca | 3742 | temp->PK = pub; |
wolfSSL | 13:f67a6c6013ca | 3743 | temp->PKLen = pubLen; |
wolfSSL | 13:f67a6c6013ca | 3744 | temp->next = *list; |
wolfSSL | 13:f67a6c6013ca | 3745 | |
wolfSSL | 13:f67a6c6013ca | 3746 | *list = temp; |
wolfSSL | 13:f67a6c6013ca | 3747 | |
wolfSSL | 13:f67a6c6013ca | 3748 | return 0; |
wolfSSL | 13:f67a6c6013ca | 3749 | } |
wolfSSL | 13:f67a6c6013ca | 3750 | |
wolfSSL | 13:f67a6c6013ca | 3751 | |
wolfSSL | 13:f67a6c6013ca | 3752 | /* request for server's public key : 02 indicates 0-2 requested */ |
wolfSSL | 13:f67a6c6013ca | 3753 | static byte TLSX_QSH_SerPKReq(byte* output, byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 3754 | { |
wolfSSL | 13:f67a6c6013ca | 3755 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 3756 | /* only request one public key from the server */ |
wolfSSL | 13:f67a6c6013ca | 3757 | output[0] = 0x01; |
wolfSSL | 13:f67a6c6013ca | 3758 | |
wolfSSL | 13:f67a6c6013ca | 3759 | return OPAQUE8_LEN; |
wolfSSL | 13:f67a6c6013ca | 3760 | } |
wolfSSL | 13:f67a6c6013ca | 3761 | else { |
wolfSSL | 13:f67a6c6013ca | 3762 | return 0; |
wolfSSL | 13:f67a6c6013ca | 3763 | } |
wolfSSL | 13:f67a6c6013ca | 3764 | } |
wolfSSL | 13:f67a6c6013ca | 3765 | |
wolfSSL | 13:f67a6c6013ca | 3766 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:f67a6c6013ca | 3767 | |
wolfSSL | 13:f67a6c6013ca | 3768 | /* check for TLS_QSH suite */ |
wolfSSL | 13:f67a6c6013ca | 3769 | static void TLSX_QSH_ValidateRequest(WOLFSSL* ssl, byte* semaphore) |
wolfSSL | 13:f67a6c6013ca | 3770 | { |
wolfSSL | 13:f67a6c6013ca | 3771 | int i; |
wolfSSL | 13:f67a6c6013ca | 3772 | |
wolfSSL | 13:f67a6c6013ca | 3773 | for (i = 0; i < ssl->suites->suiteSz; i+= 2) |
wolfSSL | 13:f67a6c6013ca | 3774 | if (ssl->suites->suites[i] == QSH_BYTE) |
wolfSSL | 13:f67a6c6013ca | 3775 | return; |
wolfSSL | 13:f67a6c6013ca | 3776 | |
wolfSSL | 13:f67a6c6013ca | 3777 | /* No QSH suite found */ |
wolfSSL | 13:f67a6c6013ca | 3778 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_QUANTUM_SAFE_HYBRID)); |
wolfSSL | 13:f67a6c6013ca | 3779 | } |
wolfSSL | 13:f67a6c6013ca | 3780 | |
wolfSSL | 13:f67a6c6013ca | 3781 | |
wolfSSL | 13:f67a6c6013ca | 3782 | /* return the size of the QSH hello extension |
wolfSSL | 13:f67a6c6013ca | 3783 | list the list of QSHScheme structs containing id and key |
wolfSSL | 13:f67a6c6013ca | 3784 | isRequest if 1 then is being sent to the server |
wolfSSL | 13:f67a6c6013ca | 3785 | */ |
wolfSSL | 13:f67a6c6013ca | 3786 | word16 TLSX_QSH_GetSize(QSHScheme* list, byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 3787 | { |
wolfSSL | 13:f67a6c6013ca | 3788 | QSHScheme* temp = list; |
wolfSSL | 13:f67a6c6013ca | 3789 | word16 length = 0; |
wolfSSL | 13:f67a6c6013ca | 3790 | |
wolfSSL | 13:f67a6c6013ca | 3791 | /* account for size of scheme list and public key list */ |
wolfSSL | 13:f67a6c6013ca | 3792 | if (isRequest) |
wolfSSL | 13:f67a6c6013ca | 3793 | length = OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 3794 | length += OPAQUE24_LEN; |
wolfSSL | 13:f67a6c6013ca | 3795 | |
wolfSSL | 13:f67a6c6013ca | 3796 | /* for each non null element in list add size */ |
wolfSSL | 13:f67a6c6013ca | 3797 | while ((temp)) { |
wolfSSL | 13:f67a6c6013ca | 3798 | /* add public key info Scheme | Key Length | Key */ |
wolfSSL | 13:f67a6c6013ca | 3799 | length += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 3800 | length += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 3801 | length += temp->PKLen; |
wolfSSL | 13:f67a6c6013ca | 3802 | |
wolfSSL | 13:f67a6c6013ca | 3803 | /* if client add name size for scheme list |
wolfSSL | 13:f67a6c6013ca | 3804 | advance to next QSHScheme struct in list */ |
wolfSSL | 13:f67a6c6013ca | 3805 | if (isRequest) |
wolfSSL | 13:f67a6c6013ca | 3806 | length += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 3807 | temp = temp->next; |
wolfSSL | 13:f67a6c6013ca | 3808 | } |
wolfSSL | 13:f67a6c6013ca | 3809 | |
wolfSSL | 13:f67a6c6013ca | 3810 | /* add length for request server public keys */ |
wolfSSL | 13:f67a6c6013ca | 3811 | if (isRequest) |
wolfSSL | 13:f67a6c6013ca | 3812 | length += OPAQUE8_LEN; |
wolfSSL | 13:f67a6c6013ca | 3813 | |
wolfSSL | 13:f67a6c6013ca | 3814 | return length; |
wolfSSL | 13:f67a6c6013ca | 3815 | } |
wolfSSL | 13:f67a6c6013ca | 3816 | |
wolfSSL | 13:f67a6c6013ca | 3817 | |
wolfSSL | 13:f67a6c6013ca | 3818 | /* write out a list of QSHScheme IDs */ |
wolfSSL | 13:f67a6c6013ca | 3819 | static word16 TLSX_QSH_Write(QSHScheme* list, byte* output) |
wolfSSL | 13:f67a6c6013ca | 3820 | { |
wolfSSL | 13:f67a6c6013ca | 3821 | QSHScheme* current = list; |
wolfSSL | 13:f67a6c6013ca | 3822 | word16 length = 0; |
wolfSSL | 13:f67a6c6013ca | 3823 | |
wolfSSL | 13:f67a6c6013ca | 3824 | length += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 3825 | |
wolfSSL | 13:f67a6c6013ca | 3826 | while (current) { |
wolfSSL | 13:f67a6c6013ca | 3827 | c16toa(current->name, output + length); |
wolfSSL | 13:f67a6c6013ca | 3828 | length += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 3829 | current = (QSHScheme*)current->next; |
wolfSSL | 13:f67a6c6013ca | 3830 | } |
wolfSSL | 13:f67a6c6013ca | 3831 | |
wolfSSL | 13:f67a6c6013ca | 3832 | c16toa(length - OPAQUE16_LEN, output); /* writing list length */ |
wolfSSL | 13:f67a6c6013ca | 3833 | |
wolfSSL | 13:f67a6c6013ca | 3834 | return length; |
wolfSSL | 13:f67a6c6013ca | 3835 | } |
wolfSSL | 13:f67a6c6013ca | 3836 | |
wolfSSL | 13:f67a6c6013ca | 3837 | |
wolfSSL | 13:f67a6c6013ca | 3838 | /* write public key list in extension */ |
wolfSSL | 13:f67a6c6013ca | 3839 | static word16 TLSX_QSHPK_WriteR(QSHScheme* format, byte* output); |
wolfSSL | 13:f67a6c6013ca | 3840 | static word16 TLSX_QSHPK_WriteR(QSHScheme* format, byte* output) |
wolfSSL | 13:f67a6c6013ca | 3841 | { |
wolfSSL | 13:f67a6c6013ca | 3842 | word32 offset = 0; |
wolfSSL | 13:f67a6c6013ca | 3843 | word16 public_len = 0; |
wolfSSL | 13:f67a6c6013ca | 3844 | |
wolfSSL | 13:f67a6c6013ca | 3845 | if (!format) |
wolfSSL | 13:f67a6c6013ca | 3846 | return offset; |
wolfSSL | 13:f67a6c6013ca | 3847 | |
wolfSSL | 13:f67a6c6013ca | 3848 | /* write scheme ID */ |
wolfSSL | 13:f67a6c6013ca | 3849 | c16toa(format->name, output + offset); |
wolfSSL | 13:f67a6c6013ca | 3850 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 3851 | |
wolfSSL | 13:f67a6c6013ca | 3852 | /* write public key matching scheme */ |
wolfSSL | 13:f67a6c6013ca | 3853 | public_len = format->PKLen; |
wolfSSL | 13:f67a6c6013ca | 3854 | c16toa(public_len, output + offset); |
wolfSSL | 13:f67a6c6013ca | 3855 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 3856 | if (format->PK) { |
wolfSSL | 13:f67a6c6013ca | 3857 | XMEMCPY(output+offset, format->PK, public_len); |
wolfSSL | 13:f67a6c6013ca | 3858 | } |
wolfSSL | 13:f67a6c6013ca | 3859 | |
wolfSSL | 13:f67a6c6013ca | 3860 | return public_len + offset; |
wolfSSL | 13:f67a6c6013ca | 3861 | } |
wolfSSL | 13:f67a6c6013ca | 3862 | |
wolfSSL | 13:f67a6c6013ca | 3863 | word16 TLSX_QSHPK_Write(QSHScheme* list, byte* output) |
wolfSSL | 13:f67a6c6013ca | 3864 | { |
wolfSSL | 13:f67a6c6013ca | 3865 | QSHScheme* current = list; |
wolfSSL | 13:f67a6c6013ca | 3866 | word32 length = 0; |
wolfSSL | 13:f67a6c6013ca | 3867 | word24 toWire; |
wolfSSL | 13:f67a6c6013ca | 3868 | |
wolfSSL | 13:f67a6c6013ca | 3869 | length += OPAQUE24_LEN; |
wolfSSL | 13:f67a6c6013ca | 3870 | |
wolfSSL | 13:f67a6c6013ca | 3871 | while (current) { |
wolfSSL | 13:f67a6c6013ca | 3872 | length += TLSX_QSHPK_WriteR(current, output + length); |
wolfSSL | 13:f67a6c6013ca | 3873 | current = (QSHScheme*)current->next; |
wolfSSL | 13:f67a6c6013ca | 3874 | } |
wolfSSL | 13:f67a6c6013ca | 3875 | /* length of public keys sent */ |
wolfSSL | 13:f67a6c6013ca | 3876 | c32to24(length - OPAQUE24_LEN, toWire); |
wolfSSL | 13:f67a6c6013ca | 3877 | output[0] = toWire[0]; |
wolfSSL | 13:f67a6c6013ca | 3878 | output[1] = toWire[1]; |
wolfSSL | 13:f67a6c6013ca | 3879 | output[2] = toWire[2]; |
wolfSSL | 13:f67a6c6013ca | 3880 | |
wolfSSL | 13:f67a6c6013ca | 3881 | return length; |
wolfSSL | 13:f67a6c6013ca | 3882 | } |
wolfSSL | 13:f67a6c6013ca | 3883 | |
wolfSSL | 13:f67a6c6013ca | 3884 | #endif /* NO_WOLFSSL_CLIENT */ |
wolfSSL | 13:f67a6c6013ca | 3885 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 3886 | |
wolfSSL | 13:f67a6c6013ca | 3887 | static void TLSX_QSHAgreement(TLSX** extensions, void* heap) |
wolfSSL | 13:f67a6c6013ca | 3888 | { |
wolfSSL | 13:f67a6c6013ca | 3889 | TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID); |
wolfSSL | 13:f67a6c6013ca | 3890 | QSHScheme* format = NULL; |
wolfSSL | 13:f67a6c6013ca | 3891 | QSHScheme* del = NULL; |
wolfSSL | 13:f67a6c6013ca | 3892 | QSHScheme* prev = NULL; |
wolfSSL | 13:f67a6c6013ca | 3893 | |
wolfSSL | 13:f67a6c6013ca | 3894 | if (extension == NULL) |
wolfSSL | 13:f67a6c6013ca | 3895 | return; |
wolfSSL | 13:f67a6c6013ca | 3896 | |
wolfSSL | 13:f67a6c6013ca | 3897 | format = (QSHScheme*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 3898 | while (format) { |
wolfSSL | 13:f67a6c6013ca | 3899 | if (format->PKLen == 0) { |
wolfSSL | 13:f67a6c6013ca | 3900 | /* case of head */ |
wolfSSL | 13:f67a6c6013ca | 3901 | if (format == extension->data) { |
wolfSSL | 13:f67a6c6013ca | 3902 | extension->data = format->next; |
wolfSSL | 13:f67a6c6013ca | 3903 | } |
wolfSSL | 13:f67a6c6013ca | 3904 | if (prev) |
wolfSSL | 13:f67a6c6013ca | 3905 | prev->next = format->next; |
wolfSSL | 13:f67a6c6013ca | 3906 | del = format; |
wolfSSL | 13:f67a6c6013ca | 3907 | format = format->next; |
wolfSSL | 13:f67a6c6013ca | 3908 | XFREE(del, heap, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:f67a6c6013ca | 3909 | del = NULL; |
wolfSSL | 13:f67a6c6013ca | 3910 | } else { |
wolfSSL | 13:f67a6c6013ca | 3911 | prev = format; |
wolfSSL | 13:f67a6c6013ca | 3912 | format = format->next; |
wolfSSL | 13:f67a6c6013ca | 3913 | } |
wolfSSL | 13:f67a6c6013ca | 3914 | } |
wolfSSL | 13:f67a6c6013ca | 3915 | |
wolfSSL | 13:f67a6c6013ca | 3916 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 3917 | } |
wolfSSL | 13:f67a6c6013ca | 3918 | |
wolfSSL | 13:f67a6c6013ca | 3919 | |
wolfSSL | 13:f67a6c6013ca | 3920 | /* Parse in hello extension |
wolfSSL | 13:f67a6c6013ca | 3921 | input the byte stream to process |
wolfSSL | 13:f67a6c6013ca | 3922 | length length of total extension found |
wolfSSL | 13:f67a6c6013ca | 3923 | isRequest set to 1 if being sent to the server |
wolfSSL | 13:f67a6c6013ca | 3924 | */ |
wolfSSL | 13:f67a6c6013ca | 3925 | static int TLSX_QSH_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 3926 | byte isRequest) |
wolfSSL | 13:f67a6c6013ca | 3927 | { |
wolfSSL | 13:f67a6c6013ca | 3928 | byte numKeys = 0; |
wolfSSL | 13:f67a6c6013ca | 3929 | word16 offset = 0; |
wolfSSL | 13:f67a6c6013ca | 3930 | word16 schemSz = 0; |
wolfSSL | 13:f67a6c6013ca | 3931 | word16 offset_len = 0; |
wolfSSL | 13:f67a6c6013ca | 3932 | word32 offset_pk = 0; |
wolfSSL | 13:f67a6c6013ca | 3933 | word16 name = 0; |
wolfSSL | 13:f67a6c6013ca | 3934 | word16 PKLen = 0; |
wolfSSL | 13:f67a6c6013ca | 3935 | byte* PK = NULL; |
wolfSSL | 13:f67a6c6013ca | 3936 | int r; |
wolfSSL | 13:f67a6c6013ca | 3937 | |
wolfSSL | 13:f67a6c6013ca | 3938 | |
wolfSSL | 13:f67a6c6013ca | 3939 | if (OPAQUE16_LEN > length) |
wolfSSL | 13:f67a6c6013ca | 3940 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 3941 | |
wolfSSL | 13:f67a6c6013ca | 3942 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 3943 | ato16(input, &schemSz); |
wolfSSL | 13:f67a6c6013ca | 3944 | |
wolfSSL | 13:f67a6c6013ca | 3945 | /* list of public keys available for QSH schemes */ |
wolfSSL | 13:f67a6c6013ca | 3946 | offset_len = schemSz + OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 3947 | } |
wolfSSL | 13:f67a6c6013ca | 3948 | |
wolfSSL | 13:f67a6c6013ca | 3949 | offset_pk = ((input[offset_len] << 16) & 0xFF00000) | |
wolfSSL | 13:f67a6c6013ca | 3950 | (((input[offset_len + 1]) << 8) & 0xFF00) | |
wolfSSL | 13:f67a6c6013ca | 3951 | (input[offset_len + 2] & 0xFF); |
wolfSSL | 13:f67a6c6013ca | 3952 | offset_len += OPAQUE24_LEN; |
wolfSSL | 13:f67a6c6013ca | 3953 | |
wolfSSL | 13:f67a6c6013ca | 3954 | /* check buffer size */ |
wolfSSL | 13:f67a6c6013ca | 3955 | if (offset_pk > length) |
wolfSSL | 13:f67a6c6013ca | 3956 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 3957 | |
wolfSSL | 13:f67a6c6013ca | 3958 | /* set maximum number of keys the client will accept */ |
wolfSSL | 13:f67a6c6013ca | 3959 | if (!isRequest) |
wolfSSL | 13:f67a6c6013ca | 3960 | numKeys = (ssl->maxRequest < 1)? 1 : ssl->maxRequest; |
wolfSSL | 13:f67a6c6013ca | 3961 | |
wolfSSL | 13:f67a6c6013ca | 3962 | /* hello extension read list of scheme ids */ |
wolfSSL | 13:f67a6c6013ca | 3963 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 3964 | |
wolfSSL | 13:f67a6c6013ca | 3965 | /* read in request for public keys */ |
wolfSSL | 13:f67a6c6013ca | 3966 | ssl->minRequest = (input[length -1] >> 4) & 0xFF; |
wolfSSL | 13:f67a6c6013ca | 3967 | ssl->maxRequest = input[length -1] & 0x0F; |
wolfSSL | 13:f67a6c6013ca | 3968 | |
wolfSSL | 13:f67a6c6013ca | 3969 | /* choose the min between min requested by client and 1 */ |
wolfSSL | 13:f67a6c6013ca | 3970 | numKeys = (ssl->minRequest > 1) ? ssl->minRequest : 1; |
wolfSSL | 13:f67a6c6013ca | 3971 | |
wolfSSL | 13:f67a6c6013ca | 3972 | if (ssl->minRequest > ssl->maxRequest) |
wolfSSL | 13:f67a6c6013ca | 3973 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 3974 | |
wolfSSL | 13:f67a6c6013ca | 3975 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 3976 | schemSz += offset; |
wolfSSL | 13:f67a6c6013ca | 3977 | |
wolfSSL | 13:f67a6c6013ca | 3978 | /* check buffer size */ |
wolfSSL | 13:f67a6c6013ca | 3979 | if (schemSz > length) |
wolfSSL | 13:f67a6c6013ca | 3980 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 3981 | |
wolfSSL | 13:f67a6c6013ca | 3982 | while ((offset < schemSz) && numKeys) { |
wolfSSL | 13:f67a6c6013ca | 3983 | /* Scheme ID list */ |
wolfSSL | 13:f67a6c6013ca | 3984 | ato16(input + offset, &name); |
wolfSSL | 13:f67a6c6013ca | 3985 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 3986 | |
wolfSSL | 13:f67a6c6013ca | 3987 | /* validate we have scheme id */ |
wolfSSL | 13:f67a6c6013ca | 3988 | if (ssl->user_set_QSHSchemes && |
wolfSSL | 13:f67a6c6013ca | 3989 | !TLSX_ValidateQSHScheme(&ssl->extensions, name)) { |
wolfSSL | 13:f67a6c6013ca | 3990 | continue; |
wolfSSL | 13:f67a6c6013ca | 3991 | } |
wolfSSL | 13:f67a6c6013ca | 3992 | |
wolfSSL | 13:f67a6c6013ca | 3993 | /* server create keys on demand */ |
wolfSSL | 13:f67a6c6013ca | 3994 | if ((r = TLSX_CreateNtruKey(ssl, name)) != 0) { |
wolfSSL | 13:f67a6c6013ca | 3995 | WOLFSSL_MSG("Error creating ntru keys"); |
wolfSSL | 13:f67a6c6013ca | 3996 | return r; |
wolfSSL | 13:f67a6c6013ca | 3997 | } |
wolfSSL | 13:f67a6c6013ca | 3998 | |
wolfSSL | 13:f67a6c6013ca | 3999 | /* peer sent an agreed upon scheme */ |
wolfSSL | 13:f67a6c6013ca | 4000 | r = TLSX_UseQSHScheme(&ssl->extensions, name, NULL, 0, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 4001 | |
wolfSSL | 13:f67a6c6013ca | 4002 | if (r != SSL_SUCCESS) return r; /* throw error */ |
wolfSSL | 13:f67a6c6013ca | 4003 | |
wolfSSL | 13:f67a6c6013ca | 4004 | numKeys--; |
wolfSSL | 13:f67a6c6013ca | 4005 | } |
wolfSSL | 13:f67a6c6013ca | 4006 | |
wolfSSL | 13:f67a6c6013ca | 4007 | /* choose the min between min requested by client and 1 */ |
wolfSSL | 13:f67a6c6013ca | 4008 | numKeys = (ssl->minRequest > 1) ? ssl->minRequest : 1; |
wolfSSL | 13:f67a6c6013ca | 4009 | } |
wolfSSL | 13:f67a6c6013ca | 4010 | |
wolfSSL | 13:f67a6c6013ca | 4011 | /* QSHPK struct */ |
wolfSSL | 13:f67a6c6013ca | 4012 | offset_pk += offset_len; |
wolfSSL | 13:f67a6c6013ca | 4013 | while ((offset_len < offset_pk) && numKeys) { |
wolfSSL | 13:f67a6c6013ca | 4014 | QSHKey * temp; |
wolfSSL | 13:f67a6c6013ca | 4015 | |
wolfSSL | 13:f67a6c6013ca | 4016 | if ((temp = (QSHKey*)XMALLOC(sizeof(QSHKey), ssl->heap, |
wolfSSL | 13:f67a6c6013ca | 4017 | DYNAMIC_TYPE_TLSX)) == NULL) |
wolfSSL | 13:f67a6c6013ca | 4018 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 4019 | |
wolfSSL | 13:f67a6c6013ca | 4020 | /* initialize */ |
wolfSSL | 13:f67a6c6013ca | 4021 | temp->next = NULL; |
wolfSSL | 13:f67a6c6013ca | 4022 | temp->pub.buffer = NULL; |
wolfSSL | 13:f67a6c6013ca | 4023 | temp->pub.length = 0; |
wolfSSL | 13:f67a6c6013ca | 4024 | temp->pri.buffer = NULL; |
wolfSSL | 13:f67a6c6013ca | 4025 | temp->pri.length = 0; |
wolfSSL | 13:f67a6c6013ca | 4026 | |
wolfSSL | 13:f67a6c6013ca | 4027 | /* scheme id */ |
wolfSSL | 13:f67a6c6013ca | 4028 | ato16(input + offset_len, &(temp->name)); |
wolfSSL | 13:f67a6c6013ca | 4029 | offset_len += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 4030 | |
wolfSSL | 13:f67a6c6013ca | 4031 | /* public key length */ |
wolfSSL | 13:f67a6c6013ca | 4032 | ato16(input + offset_len, &PKLen); |
wolfSSL | 13:f67a6c6013ca | 4033 | temp->pub.length = PKLen; |
wolfSSL | 13:f67a6c6013ca | 4034 | offset_len += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 4035 | |
wolfSSL | 13:f67a6c6013ca | 4036 | |
wolfSSL | 13:f67a6c6013ca | 4037 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 4038 | /* validate we have scheme id */ |
wolfSSL | 13:f67a6c6013ca | 4039 | if (ssl->user_set_QSHSchemes && |
wolfSSL | 13:f67a6c6013ca | 4040 | (!TLSX_ValidateQSHScheme(&ssl->extensions, temp->name))) { |
wolfSSL | 13:f67a6c6013ca | 4041 | offset_len += PKLen; |
wolfSSL | 13:f67a6c6013ca | 4042 | XFREE(temp, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 4043 | continue; |
wolfSSL | 13:f67a6c6013ca | 4044 | } |
wolfSSL | 13:f67a6c6013ca | 4045 | } |
wolfSSL | 13:f67a6c6013ca | 4046 | |
wolfSSL | 13:f67a6c6013ca | 4047 | /* read in public key */ |
wolfSSL | 13:f67a6c6013ca | 4048 | if (PKLen > 0) { |
wolfSSL | 13:f67a6c6013ca | 4049 | temp->pub.buffer = (byte*)XMALLOC(temp->pub.length, |
wolfSSL | 13:f67a6c6013ca | 4050 | ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); |
wolfSSL | 13:f67a6c6013ca | 4051 | XMEMCPY(temp->pub.buffer, input + offset_len, temp->pub.length); |
wolfSSL | 13:f67a6c6013ca | 4052 | offset_len += PKLen; |
wolfSSL | 13:f67a6c6013ca | 4053 | } |
wolfSSL | 13:f67a6c6013ca | 4054 | else { |
wolfSSL | 13:f67a6c6013ca | 4055 | PK = NULL; |
wolfSSL | 13:f67a6c6013ca | 4056 | } |
wolfSSL | 13:f67a6c6013ca | 4057 | |
wolfSSL | 13:f67a6c6013ca | 4058 | /* use own key when adding to extensions list for sending reply */ |
wolfSSL | 13:f67a6c6013ca | 4059 | PKLen = 0; |
wolfSSL | 13:f67a6c6013ca | 4060 | PK = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, &PKLen, temp->name); |
wolfSSL | 13:f67a6c6013ca | 4061 | r = TLSX_UseQSHScheme(&ssl->extensions, temp->name, PK, PKLen, |
wolfSSL | 13:f67a6c6013ca | 4062 | ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 4063 | |
wolfSSL | 13:f67a6c6013ca | 4064 | /* store peers key */ |
wolfSSL | 13:f67a6c6013ca | 4065 | ssl->peerQSHKeyPresent = 1; |
wolfSSL | 13:f67a6c6013ca | 4066 | if (TLSX_AddQSHKey(&ssl->peerQSHKey, temp) != 0) |
wolfSSL | 13:f67a6c6013ca | 4067 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 4068 | |
wolfSSL | 13:f67a6c6013ca | 4069 | if (temp->pub.length == 0) { |
wolfSSL | 13:f67a6c6013ca | 4070 | XFREE(temp, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 4071 | } |
wolfSSL | 13:f67a6c6013ca | 4072 | |
wolfSSL | 13:f67a6c6013ca | 4073 | if (r != SSL_SUCCESS) {return r;} /* throw error */ |
wolfSSL | 13:f67a6c6013ca | 4074 | |
wolfSSL | 13:f67a6c6013ca | 4075 | numKeys--; |
wolfSSL | 13:f67a6c6013ca | 4076 | } |
wolfSSL | 13:f67a6c6013ca | 4077 | |
wolfSSL | 13:f67a6c6013ca | 4078 | /* reply to a QSH extension sent from client */ |
wolfSSL | 13:f67a6c6013ca | 4079 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 4080 | TLSX_SetResponse(ssl, TLSX_QUANTUM_SAFE_HYBRID); |
wolfSSL | 13:f67a6c6013ca | 4081 | /* only use schemes we have key generated for -- free the rest */ |
wolfSSL | 13:f67a6c6013ca | 4082 | TLSX_QSHAgreement(&ssl->extensions, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 4083 | } |
wolfSSL | 13:f67a6c6013ca | 4084 | |
wolfSSL | 13:f67a6c6013ca | 4085 | return 0; |
wolfSSL | 13:f67a6c6013ca | 4086 | } |
wolfSSL | 13:f67a6c6013ca | 4087 | |
wolfSSL | 13:f67a6c6013ca | 4088 | |
wolfSSL | 13:f67a6c6013ca | 4089 | /* Used for parsing in QSHCipher structs on Key Exchange */ |
wolfSSL | 13:f67a6c6013ca | 4090 | int TLSX_QSHCipher_Parse(WOLFSSL* ssl, const byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 4091 | byte isServer) |
wolfSSL | 13:f67a6c6013ca | 4092 | { |
wolfSSL | 13:f67a6c6013ca | 4093 | QSHKey* key; |
wolfSSL | 13:f67a6c6013ca | 4094 | word16 Max_Secret_Len = 48; |
wolfSSL | 13:f67a6c6013ca | 4095 | word16 offset = 0; |
wolfSSL | 13:f67a6c6013ca | 4096 | word16 offset_len = 0; |
wolfSSL | 13:f67a6c6013ca | 4097 | word32 offset_pk = 0; |
wolfSSL | 13:f67a6c6013ca | 4098 | word16 name = 0; |
wolfSSL | 13:f67a6c6013ca | 4099 | word16 secretLen = 0; |
wolfSSL | 13:f67a6c6013ca | 4100 | byte* secret = NULL; |
wolfSSL | 13:f67a6c6013ca | 4101 | word16 buffLen = 0; |
wolfSSL | 13:f67a6c6013ca | 4102 | byte buff[145]; /* size enough for 3 secrets */ |
wolfSSL | 13:f67a6c6013ca | 4103 | buffer* buf; |
wolfSSL | 13:f67a6c6013ca | 4104 | |
wolfSSL | 13:f67a6c6013ca | 4105 | /* pointer to location where secret should be stored */ |
wolfSSL | 13:f67a6c6013ca | 4106 | if (isServer) { |
wolfSSL | 13:f67a6c6013ca | 4107 | buf = ssl->QSH_secret->CliSi; |
wolfSSL | 13:f67a6c6013ca | 4108 | } |
wolfSSL | 13:f67a6c6013ca | 4109 | else { |
wolfSSL | 13:f67a6c6013ca | 4110 | buf = ssl->QSH_secret->SerSi; |
wolfSSL | 13:f67a6c6013ca | 4111 | } |
wolfSSL | 13:f67a6c6013ca | 4112 | |
wolfSSL | 13:f67a6c6013ca | 4113 | offset_pk = ((input[offset_len] << 16) & 0xFF0000) | |
wolfSSL | 13:f67a6c6013ca | 4114 | (((input[offset_len + 1]) << 8) & 0xFF00) | |
wolfSSL | 13:f67a6c6013ca | 4115 | (input[offset_len + 2] & 0xFF); |
wolfSSL | 13:f67a6c6013ca | 4116 | offset_len += OPAQUE24_LEN; |
wolfSSL | 13:f67a6c6013ca | 4117 | |
wolfSSL | 13:f67a6c6013ca | 4118 | /* validating extension list length -- check if trying to read over edge |
wolfSSL | 13:f67a6c6013ca | 4119 | of buffer */ |
wolfSSL | 13:f67a6c6013ca | 4120 | if (length < (offset_pk + OPAQUE24_LEN)) { |
wolfSSL | 13:f67a6c6013ca | 4121 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 4122 | } |
wolfSSL | 13:f67a6c6013ca | 4123 | |
wolfSSL | 13:f67a6c6013ca | 4124 | /* QSHCipherList struct */ |
wolfSSL | 13:f67a6c6013ca | 4125 | offset_pk += offset_len; |
wolfSSL | 13:f67a6c6013ca | 4126 | while (offset_len < offset_pk) { |
wolfSSL | 13:f67a6c6013ca | 4127 | |
wolfSSL | 13:f67a6c6013ca | 4128 | /* scheme id */ |
wolfSSL | 13:f67a6c6013ca | 4129 | ato16(input + offset_len, &name); |
wolfSSL | 13:f67a6c6013ca | 4130 | offset_len += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 4131 | |
wolfSSL | 13:f67a6c6013ca | 4132 | /* public key length */ |
wolfSSL | 13:f67a6c6013ca | 4133 | ato16(input + offset_len, &secretLen); |
wolfSSL | 13:f67a6c6013ca | 4134 | offset_len += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 4135 | |
wolfSSL | 13:f67a6c6013ca | 4136 | /* read in public key */ |
wolfSSL | 13:f67a6c6013ca | 4137 | if (secretLen > 0) { |
wolfSSL | 13:f67a6c6013ca | 4138 | secret = (byte*)(input + offset_len); |
wolfSSL | 13:f67a6c6013ca | 4139 | offset_len += secretLen; |
wolfSSL | 13:f67a6c6013ca | 4140 | } |
wolfSSL | 13:f67a6c6013ca | 4141 | else { |
wolfSSL | 13:f67a6c6013ca | 4142 | secret = NULL; |
wolfSSL | 13:f67a6c6013ca | 4143 | } |
wolfSSL | 13:f67a6c6013ca | 4144 | |
wolfSSL | 13:f67a6c6013ca | 4145 | /* no secret sent */ |
wolfSSL | 13:f67a6c6013ca | 4146 | if (secret == NULL) |
wolfSSL | 13:f67a6c6013ca | 4147 | continue; |
wolfSSL | 13:f67a6c6013ca | 4148 | |
wolfSSL | 13:f67a6c6013ca | 4149 | /* find corresponding key */ |
wolfSSL | 13:f67a6c6013ca | 4150 | key = ssl->QSH_Key; |
wolfSSL | 13:f67a6c6013ca | 4151 | while (key) { |
wolfSSL | 13:f67a6c6013ca | 4152 | if (key->name == name) |
wolfSSL | 13:f67a6c6013ca | 4153 | break; |
wolfSSL | 13:f67a6c6013ca | 4154 | else |
wolfSSL | 13:f67a6c6013ca | 4155 | key = (QSHKey*)key->next; |
wolfSSL | 13:f67a6c6013ca | 4156 | } |
wolfSSL | 13:f67a6c6013ca | 4157 | |
wolfSSL | 13:f67a6c6013ca | 4158 | /* if we do not have the key than there was a big issue negotiation */ |
wolfSSL | 13:f67a6c6013ca | 4159 | if (key == NULL) { |
wolfSSL | 13:f67a6c6013ca | 4160 | WOLFSSL_MSG("key was null for decryption!!!\n"); |
wolfSSL | 13:f67a6c6013ca | 4161 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 4162 | } |
wolfSSL | 13:f67a6c6013ca | 4163 | |
wolfSSL | 13:f67a6c6013ca | 4164 | /* Decrypt sent secret */ |
wolfSSL | 13:f67a6c6013ca | 4165 | buffLen = Max_Secret_Len; |
wolfSSL | 13:f67a6c6013ca | 4166 | QSH_Decrypt(key, secret, secretLen, buff + offset, &buffLen); |
wolfSSL | 13:f67a6c6013ca | 4167 | offset += buffLen; |
wolfSSL | 13:f67a6c6013ca | 4168 | } |
wolfSSL | 13:f67a6c6013ca | 4169 | |
wolfSSL | 13:f67a6c6013ca | 4170 | /* allocate memory for buffer */ |
wolfSSL | 13:f67a6c6013ca | 4171 | buf->length = offset; |
wolfSSL | 13:f67a6c6013ca | 4172 | buf->buffer = (byte*)XMALLOC(offset, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:f67a6c6013ca | 4173 | if (buf->buffer == NULL) |
wolfSSL | 13:f67a6c6013ca | 4174 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 4175 | |
wolfSSL | 13:f67a6c6013ca | 4176 | /* store secrets */ |
wolfSSL | 13:f67a6c6013ca | 4177 | XMEMCPY(buf->buffer, buff, offset); |
wolfSSL | 13:f67a6c6013ca | 4178 | ForceZero(buff, offset); |
wolfSSL | 13:f67a6c6013ca | 4179 | |
wolfSSL | 13:f67a6c6013ca | 4180 | return offset_len; |
wolfSSL | 13:f67a6c6013ca | 4181 | } |
wolfSSL | 13:f67a6c6013ca | 4182 | |
wolfSSL | 13:f67a6c6013ca | 4183 | |
wolfSSL | 13:f67a6c6013ca | 4184 | /* return 1 on success */ |
wolfSSL | 13:f67a6c6013ca | 4185 | int TLSX_ValidateQSHScheme(TLSX** extensions, word16 theirs) { |
wolfSSL | 13:f67a6c6013ca | 4186 | TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID); |
wolfSSL | 13:f67a6c6013ca | 4187 | QSHScheme* format = NULL; |
wolfSSL | 13:f67a6c6013ca | 4188 | |
wolfSSL | 13:f67a6c6013ca | 4189 | /* if no extension is sent then do not use QSH */ |
wolfSSL | 13:f67a6c6013ca | 4190 | if (!extension) { |
wolfSSL | 13:f67a6c6013ca | 4191 | WOLFSSL_MSG("No QSH Extension"); |
wolfSSL | 13:f67a6c6013ca | 4192 | return 0; |
wolfSSL | 13:f67a6c6013ca | 4193 | } |
wolfSSL | 13:f67a6c6013ca | 4194 | |
wolfSSL | 13:f67a6c6013ca | 4195 | for (format = (QSHScheme*)extension->data; format; format = format->next) { |
wolfSSL | 13:f67a6c6013ca | 4196 | if (format->name == theirs) { |
wolfSSL | 13:f67a6c6013ca | 4197 | WOLFSSL_MSG("Found Matching QSH Scheme"); |
wolfSSL | 13:f67a6c6013ca | 4198 | return 1; /* have QSH */ |
wolfSSL | 13:f67a6c6013ca | 4199 | } |
wolfSSL | 13:f67a6c6013ca | 4200 | } |
wolfSSL | 13:f67a6c6013ca | 4201 | |
wolfSSL | 13:f67a6c6013ca | 4202 | return 0; |
wolfSSL | 13:f67a6c6013ca | 4203 | } |
wolfSSL | 13:f67a6c6013ca | 4204 | #endif /* NO_WOLFSSL_SERVER */ |
wolfSSL | 13:f67a6c6013ca | 4205 | |
wolfSSL | 13:f67a6c6013ca | 4206 | /* test if the QSH Scheme is implemented |
wolfSSL | 13:f67a6c6013ca | 4207 | return 1 if yes 0 if no */ |
wolfSSL | 13:f67a6c6013ca | 4208 | static int TLSX_HaveQSHScheme(word16 name) |
wolfSSL | 13:f67a6c6013ca | 4209 | { |
wolfSSL | 13:f67a6c6013ca | 4210 | switch(name) { |
wolfSSL | 13:f67a6c6013ca | 4211 | #ifdef HAVE_NTRU |
wolfSSL | 13:f67a6c6013ca | 4212 | case WOLFSSL_NTRU_EESS439: |
wolfSSL | 13:f67a6c6013ca | 4213 | case WOLFSSL_NTRU_EESS593: |
wolfSSL | 13:f67a6c6013ca | 4214 | case WOLFSSL_NTRU_EESS743: |
wolfSSL | 13:f67a6c6013ca | 4215 | return 1; |
wolfSSL | 13:f67a6c6013ca | 4216 | #endif |
wolfSSL | 13:f67a6c6013ca | 4217 | case WOLFSSL_LWE_XXX: |
wolfSSL | 13:f67a6c6013ca | 4218 | case WOLFSSL_HFE_XXX: |
wolfSSL | 13:f67a6c6013ca | 4219 | return 0; /* not supported yet */ |
wolfSSL | 13:f67a6c6013ca | 4220 | |
wolfSSL | 13:f67a6c6013ca | 4221 | default: |
wolfSSL | 13:f67a6c6013ca | 4222 | return 0; |
wolfSSL | 13:f67a6c6013ca | 4223 | } |
wolfSSL | 13:f67a6c6013ca | 4224 | } |
wolfSSL | 13:f67a6c6013ca | 4225 | |
wolfSSL | 13:f67a6c6013ca | 4226 | |
wolfSSL | 13:f67a6c6013ca | 4227 | /* Add a QSHScheme struct to list of usable ones */ |
wolfSSL | 13:f67a6c6013ca | 4228 | int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz, |
wolfSSL | 13:f67a6c6013ca | 4229 | void* heap) |
wolfSSL | 13:f67a6c6013ca | 4230 | { |
wolfSSL | 13:f67a6c6013ca | 4231 | TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID); |
wolfSSL | 13:f67a6c6013ca | 4232 | QSHScheme* format = NULL; |
wolfSSL | 13:f67a6c6013ca | 4233 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 4234 | |
wolfSSL | 13:f67a6c6013ca | 4235 | /* sanity check */ |
wolfSSL | 13:f67a6c6013ca | 4236 | if (extensions == NULL || (pKey == NULL && pkeySz != 0)) |
wolfSSL | 13:f67a6c6013ca | 4237 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 4238 | |
wolfSSL | 13:f67a6c6013ca | 4239 | /* if scheme is implemented than add */ |
wolfSSL | 13:f67a6c6013ca | 4240 | if (TLSX_HaveQSHScheme(name)) { |
wolfSSL | 13:f67a6c6013ca | 4241 | if ((ret = TLSX_QSH_Append(&format, name, pKey, pkeySz)) != 0) |
wolfSSL | 13:f67a6c6013ca | 4242 | return ret; |
wolfSSL | 13:f67a6c6013ca | 4243 | |
wolfSSL | 13:f67a6c6013ca | 4244 | if (!extension) { |
wolfSSL | 13:f67a6c6013ca | 4245 | if ((ret = TLSX_Push(extensions, TLSX_QUANTUM_SAFE_HYBRID, format, |
wolfSSL | 13:f67a6c6013ca | 4246 | heap)) != 0) { |
wolfSSL | 13:f67a6c6013ca | 4247 | XFREE(format, 0, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 4248 | return ret; |
wolfSSL | 13:f67a6c6013ca | 4249 | } |
wolfSSL | 13:f67a6c6013ca | 4250 | } |
wolfSSL | 13:f67a6c6013ca | 4251 | else { |
wolfSSL | 13:f67a6c6013ca | 4252 | /* push new QSH object to extension data. */ |
wolfSSL | 13:f67a6c6013ca | 4253 | format->next = (QSHScheme*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 4254 | extension->data = (void*)format; |
wolfSSL | 13:f67a6c6013ca | 4255 | |
wolfSSL | 13:f67a6c6013ca | 4256 | /* look for another format of the same name to remove (replacement) */ |
wolfSSL | 13:f67a6c6013ca | 4257 | do { |
wolfSSL | 13:f67a6c6013ca | 4258 | if (format->next && (format->next->name == name)) { |
wolfSSL | 13:f67a6c6013ca | 4259 | QSHScheme* next = format->next; |
wolfSSL | 13:f67a6c6013ca | 4260 | |
wolfSSL | 13:f67a6c6013ca | 4261 | format->next = next->next; |
wolfSSL | 13:f67a6c6013ca | 4262 | XFREE(next, 0, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 4263 | |
wolfSSL | 13:f67a6c6013ca | 4264 | break; |
wolfSSL | 13:f67a6c6013ca | 4265 | } |
wolfSSL | 13:f67a6c6013ca | 4266 | } while ((format = format->next)); |
wolfSSL | 13:f67a6c6013ca | 4267 | } |
wolfSSL | 13:f67a6c6013ca | 4268 | } |
wolfSSL | 13:f67a6c6013ca | 4269 | return SSL_SUCCESS; |
wolfSSL | 13:f67a6c6013ca | 4270 | } |
wolfSSL | 13:f67a6c6013ca | 4271 | |
wolfSSL | 13:f67a6c6013ca | 4272 | #define QSH_FREE_ALL TLSX_QSH_FreeAll |
wolfSSL | 13:f67a6c6013ca | 4273 | #define QSH_VALIDATE_REQUEST TLSX_QSH_ValidateRequest |
wolfSSL | 13:f67a6c6013ca | 4274 | |
wolfSSL | 13:f67a6c6013ca | 4275 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:f67a6c6013ca | 4276 | #define QSH_GET_SIZE TLSX_QSH_GetSize |
wolfSSL | 13:f67a6c6013ca | 4277 | #define QSH_WRITE TLSX_QSH_Write |
wolfSSL | 13:f67a6c6013ca | 4278 | #else |
wolfSSL | 13:f67a6c6013ca | 4279 | #define QSH_GET_SIZE(list) 0 |
wolfSSL | 13:f67a6c6013ca | 4280 | #define QSH_WRITE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 4281 | #endif |
wolfSSL | 13:f67a6c6013ca | 4282 | |
wolfSSL | 13:f67a6c6013ca | 4283 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 4284 | #define QSH_PARSE TLSX_QSH_Parse |
wolfSSL | 13:f67a6c6013ca | 4285 | #else |
wolfSSL | 13:f67a6c6013ca | 4286 | #define QSH_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 4287 | #endif |
wolfSSL | 13:f67a6c6013ca | 4288 | |
wolfSSL | 13:f67a6c6013ca | 4289 | #define QSHPK_WRITE TLSX_QSHPK_Write |
wolfSSL | 13:f67a6c6013ca | 4290 | #define QSH_SERREQ TLSX_QSH_SerPKReq |
wolfSSL | 13:f67a6c6013ca | 4291 | #else |
wolfSSL | 13:f67a6c6013ca | 4292 | |
wolfSSL | 13:f67a6c6013ca | 4293 | #define QSH_FREE_ALL(list, heap) |
wolfSSL | 13:f67a6c6013ca | 4294 | #define QSH_GET_SIZE(list, a) 0 |
wolfSSL | 13:f67a6c6013ca | 4295 | #define QSH_WRITE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 4296 | #define QSH_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 4297 | #define QSHPK_WRITE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 4298 | #define QSH_SERREQ(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 4299 | #define QSH_VALIDATE_REQUEST(a, b) |
wolfSSL | 13:f67a6c6013ca | 4300 | |
wolfSSL | 13:f67a6c6013ca | 4301 | #endif /* HAVE_QSH */ |
wolfSSL | 13:f67a6c6013ca | 4302 | |
wolfSSL | 13:f67a6c6013ca | 4303 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 4304 | /* Supported Versions */ |
wolfSSL | 13:f67a6c6013ca | 4305 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 4306 | |
wolfSSL | 13:f67a6c6013ca | 4307 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 4308 | /* Return the size of the SupportedVersions extension's data. |
wolfSSL | 13:f67a6c6013ca | 4309 | * |
wolfSSL | 13:f67a6c6013ca | 4310 | * data The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 4311 | * returns the length of data that will be in the extension. |
wolfSSL | 13:f67a6c6013ca | 4312 | */ |
wolfSSL | 13:f67a6c6013ca | 4313 | static word16 TLSX_SupportedVersions_GetSize(void* data) |
wolfSSL | 13:f67a6c6013ca | 4314 | { |
wolfSSL | 13:f67a6c6013ca | 4315 | (void)data; |
wolfSSL | 13:f67a6c6013ca | 4316 | |
wolfSSL | 13:f67a6c6013ca | 4317 | /* TLS v1.2 and TLS v1.3 */ |
wolfSSL | 13:f67a6c6013ca | 4318 | int cnt = 2; |
wolfSSL | 13:f67a6c6013ca | 4319 | |
wolfSSL | 13:f67a6c6013ca | 4320 | #ifndef NO_OLD_TLS |
wolfSSL | 13:f67a6c6013ca | 4321 | /* TLS v1 and TLS v1.1 */ |
wolfSSL | 13:f67a6c6013ca | 4322 | cnt += 2; |
wolfSSL | 13:f67a6c6013ca | 4323 | #endif |
wolfSSL | 13:f67a6c6013ca | 4324 | |
wolfSSL | 13:f67a6c6013ca | 4325 | return OPAQUE8_LEN + cnt * OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 4326 | } |
wolfSSL | 13:f67a6c6013ca | 4327 | |
wolfSSL | 13:f67a6c6013ca | 4328 | /* Writes the SupportedVersions extension into the buffer. |
wolfSSL | 13:f67a6c6013ca | 4329 | * |
wolfSSL | 13:f67a6c6013ca | 4330 | * data The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 4331 | * output The buffer to write the extension into. |
wolfSSL | 13:f67a6c6013ca | 4332 | * returns the length of data that was written. |
wolfSSL | 13:f67a6c6013ca | 4333 | */ |
wolfSSL | 13:f67a6c6013ca | 4334 | static word16 TLSX_SupportedVersions_Write(void* data, byte* output) |
wolfSSL | 13:f67a6c6013ca | 4335 | { |
wolfSSL | 13:f67a6c6013ca | 4336 | WOLFSSL* ssl = (WOLFSSL*)data; |
wolfSSL | 13:f67a6c6013ca | 4337 | ProtocolVersion pv = ssl->ctx->method->version; |
wolfSSL | 13:f67a6c6013ca | 4338 | int i; |
wolfSSL | 13:f67a6c6013ca | 4339 | /* TLS v1.2 and TLS v1.3 */ |
wolfSSL | 13:f67a6c6013ca | 4340 | int cnt = 2; |
wolfSSL | 13:f67a6c6013ca | 4341 | |
wolfSSL | 13:f67a6c6013ca | 4342 | #ifndef NO_OLD_TLS |
wolfSSL | 13:f67a6c6013ca | 4343 | /* TLS v1 and TLS v1.1 */ |
wolfSSL | 13:f67a6c6013ca | 4344 | cnt += 2; |
wolfSSL | 13:f67a6c6013ca | 4345 | #endif |
wolfSSL | 13:f67a6c6013ca | 4346 | |
wolfSSL | 13:f67a6c6013ca | 4347 | *(output++) = cnt * OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 4348 | for (i = 0; i < cnt; i++) { |
wolfSSL | 13:f67a6c6013ca | 4349 | /* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */ |
wolfSSL | 13:f67a6c6013ca | 4350 | if (pv.minor - i == TLSv1_3_MINOR) { |
wolfSSL | 13:f67a6c6013ca | 4351 | /* The TLS draft major number. */ |
wolfSSL | 13:f67a6c6013ca | 4352 | *(output++) = TLS_DRAFT_MAJOR; |
wolfSSL | 13:f67a6c6013ca | 4353 | /* Version of draft supported. */ |
wolfSSL | 13:f67a6c6013ca | 4354 | *(output++) = TLS_DRAFT_MINOR; |
wolfSSL | 13:f67a6c6013ca | 4355 | continue; |
wolfSSL | 13:f67a6c6013ca | 4356 | } |
wolfSSL | 13:f67a6c6013ca | 4357 | |
wolfSSL | 13:f67a6c6013ca | 4358 | *(output++) = pv.major; |
wolfSSL | 13:f67a6c6013ca | 4359 | *(output++) = pv.minor - i; |
wolfSSL | 13:f67a6c6013ca | 4360 | } |
wolfSSL | 13:f67a6c6013ca | 4361 | |
wolfSSL | 13:f67a6c6013ca | 4362 | return OPAQUE8_LEN + cnt * OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 4363 | } |
wolfSSL | 13:f67a6c6013ca | 4364 | |
wolfSSL | 13:f67a6c6013ca | 4365 | /* Parse the SupportedVersions extension. |
wolfSSL | 13:f67a6c6013ca | 4366 | * |
wolfSSL | 13:f67a6c6013ca | 4367 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 4368 | * input The buffer with the extension data. |
wolfSSL | 13:f67a6c6013ca | 4369 | * length The length of the extension data. |
wolfSSL | 13:f67a6c6013ca | 4370 | * returns 0 on success, otherwise failure. |
wolfSSL | 13:f67a6c6013ca | 4371 | */ |
wolfSSL | 13:f67a6c6013ca | 4372 | static int TLSX_SupportedVersions_Parse(WOLFSSL *ssl, byte* input, |
wolfSSL | 13:f67a6c6013ca | 4373 | word16 length) |
wolfSSL | 13:f67a6c6013ca | 4374 | { |
wolfSSL | 13:f67a6c6013ca | 4375 | ProtocolVersion pv = ssl->ctx->method->version; |
wolfSSL | 13:f67a6c6013ca | 4376 | int i; |
wolfSSL | 13:f67a6c6013ca | 4377 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 4378 | int len; |
wolfSSL | 13:f67a6c6013ca | 4379 | |
wolfSSL | 13:f67a6c6013ca | 4380 | /* Must contain a length and at least one version. */ |
wolfSSL | 13:f67a6c6013ca | 4381 | if (length < OPAQUE8_LEN + OPAQUE16_LEN || (length & 1) != 1) |
wolfSSL | 13:f67a6c6013ca | 4382 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 4383 | |
wolfSSL | 13:f67a6c6013ca | 4384 | len = *input; |
wolfSSL | 13:f67a6c6013ca | 4385 | |
wolfSSL | 13:f67a6c6013ca | 4386 | /* Protocol version array must fill rest of data. */ |
wolfSSL | 13:f67a6c6013ca | 4387 | if (length != OPAQUE8_LEN + len) |
wolfSSL | 13:f67a6c6013ca | 4388 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 4389 | |
wolfSSL | 13:f67a6c6013ca | 4390 | input++; |
wolfSSL | 13:f67a6c6013ca | 4391 | |
wolfSSL | 13:f67a6c6013ca | 4392 | /* Find first match. */ |
wolfSSL | 13:f67a6c6013ca | 4393 | for (i = 0; i < len; i += OPAQUE16_LEN) { |
wolfSSL | 13:f67a6c6013ca | 4394 | /* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */ |
wolfSSL | 13:f67a6c6013ca | 4395 | if (input[i] == TLS_DRAFT_MAJOR && |
wolfSSL | 13:f67a6c6013ca | 4396 | input[i + OPAQUE8_LEN] == TLS_DRAFT_MINOR) { |
wolfSSL | 13:f67a6c6013ca | 4397 | ssl->version.minor = TLSv1_3_MINOR; |
wolfSSL | 13:f67a6c6013ca | 4398 | ssl->options.tls1_3 = 1; |
wolfSSL | 13:f67a6c6013ca | 4399 | TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, input, |
wolfSSL | 13:f67a6c6013ca | 4400 | ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 4401 | break; |
wolfSSL | 13:f67a6c6013ca | 4402 | } |
wolfSSL | 13:f67a6c6013ca | 4403 | |
wolfSSL | 13:f67a6c6013ca | 4404 | if (input[i] != pv.major) |
wolfSSL | 13:f67a6c6013ca | 4405 | continue; |
wolfSSL | 13:f67a6c6013ca | 4406 | |
wolfSSL | 13:f67a6c6013ca | 4407 | #ifndef NO_OLD_TLS |
wolfSSL | 13:f67a6c6013ca | 4408 | if (input[i + OPAQUE8_LEN] == TLSv1_MINOR || |
wolfSSL | 13:f67a6c6013ca | 4409 | input[i + OPAQUE8_LEN] == TLSv1_1_MINOR) { |
wolfSSL | 13:f67a6c6013ca | 4410 | ssl->version.minor = input[i + OPAQUE8_LEN]; |
wolfSSL | 13:f67a6c6013ca | 4411 | break; |
wolfSSL | 13:f67a6c6013ca | 4412 | } |
wolfSSL | 13:f67a6c6013ca | 4413 | #endif |
wolfSSL | 13:f67a6c6013ca | 4414 | if (input[i + OPAQUE8_LEN] == TLSv1_2_MINOR) { |
wolfSSL | 13:f67a6c6013ca | 4415 | ssl->version.minor = input[i + OPAQUE8_LEN]; |
wolfSSL | 13:f67a6c6013ca | 4416 | TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, input, |
wolfSSL | 13:f67a6c6013ca | 4417 | ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 4418 | break; |
wolfSSL | 13:f67a6c6013ca | 4419 | } |
wolfSSL | 13:f67a6c6013ca | 4420 | if (input[i + OPAQUE8_LEN] == TLSv1_3_MINOR) { |
wolfSSL | 13:f67a6c6013ca | 4421 | ssl->version.minor = input[i + OPAQUE8_LEN]; |
wolfSSL | 13:f67a6c6013ca | 4422 | ssl->options.tls1_3 = 1; |
wolfSSL | 13:f67a6c6013ca | 4423 | TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, input, |
wolfSSL | 13:f67a6c6013ca | 4424 | ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 4425 | break; |
wolfSSL | 13:f67a6c6013ca | 4426 | } |
wolfSSL | 13:f67a6c6013ca | 4427 | } |
wolfSSL | 13:f67a6c6013ca | 4428 | |
wolfSSL | 13:f67a6c6013ca | 4429 | return ret; |
wolfSSL | 13:f67a6c6013ca | 4430 | } |
wolfSSL | 13:f67a6c6013ca | 4431 | |
wolfSSL | 13:f67a6c6013ca | 4432 | /* Sets a new SupportedVersions extension into the extension list. |
wolfSSL | 13:f67a6c6013ca | 4433 | * |
wolfSSL | 13:f67a6c6013ca | 4434 | * extensions The list of extensions. |
wolfSSL | 13:f67a6c6013ca | 4435 | * data The extensions specific data. |
wolfSSL | 13:f67a6c6013ca | 4436 | * heap The heap used for allocation. |
wolfSSL | 13:f67a6c6013ca | 4437 | * returns 0 on success, otherwise failure. |
wolfSSL | 13:f67a6c6013ca | 4438 | */ |
wolfSSL | 13:f67a6c6013ca | 4439 | static int TLSX_SetSupportedVersions(TLSX** extensions, const void* data, |
wolfSSL | 13:f67a6c6013ca | 4440 | void* heap) |
wolfSSL | 13:f67a6c6013ca | 4441 | { |
wolfSSL | 13:f67a6c6013ca | 4442 | if (extensions == NULL || data == NULL) |
wolfSSL | 13:f67a6c6013ca | 4443 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 4444 | |
wolfSSL | 13:f67a6c6013ca | 4445 | return TLSX_Push(extensions, TLSX_SUPPORTED_VERSIONS, (void *)data, heap); |
wolfSSL | 13:f67a6c6013ca | 4446 | } |
wolfSSL | 13:f67a6c6013ca | 4447 | |
wolfSSL | 13:f67a6c6013ca | 4448 | #define SV_GET_SIZE TLSX_SupportedVersions_GetSize |
wolfSSL | 13:f67a6c6013ca | 4449 | #define SV_WRITE TLSX_SupportedVersions_Write |
wolfSSL | 13:f67a6c6013ca | 4450 | #define SV_PARSE TLSX_SupportedVersions_Parse |
wolfSSL | 13:f67a6c6013ca | 4451 | |
wolfSSL | 13:f67a6c6013ca | 4452 | #else |
wolfSSL | 13:f67a6c6013ca | 4453 | |
wolfSSL | 13:f67a6c6013ca | 4454 | #define SV_GET_SIZE(a) 0 |
wolfSSL | 13:f67a6c6013ca | 4455 | #define SV_WRITE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 4456 | #define SV_PARSE(a, b, c) 0 |
wolfSSL | 13:f67a6c6013ca | 4457 | |
wolfSSL | 13:f67a6c6013ca | 4458 | #endif /* WOLFSSL_TLS13 */ |
wolfSSL | 13:f67a6c6013ca | 4459 | |
wolfSSL | 13:f67a6c6013ca | 4460 | #if defined(WOLFSSL_TLS13) |
wolfSSL | 13:f67a6c6013ca | 4461 | |
wolfSSL | 13:f67a6c6013ca | 4462 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 4463 | /* Cookie */ |
wolfSSL | 13:f67a6c6013ca | 4464 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 4465 | |
wolfSSL | 13:f67a6c6013ca | 4466 | /* Free the cookie data. |
wolfSSL | 13:f67a6c6013ca | 4467 | * |
wolfSSL | 13:f67a6c6013ca | 4468 | * cookie Cookie data. |
wolfSSL | 13:f67a6c6013ca | 4469 | * heap The heap used for allocation. |
wolfSSL | 13:f67a6c6013ca | 4470 | */ |
wolfSSL | 13:f67a6c6013ca | 4471 | static void TLSX_Cookie_FreeAll(Cookie* cookie, void* heap) |
wolfSSL | 13:f67a6c6013ca | 4472 | { |
wolfSSL | 13:f67a6c6013ca | 4473 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 4474 | |
wolfSSL | 13:f67a6c6013ca | 4475 | if (cookie != NULL) |
wolfSSL | 13:f67a6c6013ca | 4476 | XFREE(cookie, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 4477 | } |
wolfSSL | 13:f67a6c6013ca | 4478 | |
wolfSSL | 13:f67a6c6013ca | 4479 | /* Get the size of the encoded Cookie extension. |
wolfSSL | 13:f67a6c6013ca | 4480 | * In messages: ClientHello and HelloRetryRequest. |
wolfSSL | 13:f67a6c6013ca | 4481 | * |
wolfSSL | 13:f67a6c6013ca | 4482 | * cookie The cookie to write. |
wolfSSL | 13:f67a6c6013ca | 4483 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:f67a6c6013ca | 4484 | * returns the number of bytes of the encoded Cookie extension. |
wolfSSL | 13:f67a6c6013ca | 4485 | */ |
wolfSSL | 13:f67a6c6013ca | 4486 | static word16 TLSX_Cookie_GetSize(Cookie* cookie, byte msgType) |
wolfSSL | 13:f67a6c6013ca | 4487 | { |
wolfSSL | 13:f67a6c6013ca | 4488 | if (msgType == client_hello || msgType == hello_retry_request) |
wolfSSL | 13:f67a6c6013ca | 4489 | return OPAQUE16_LEN + cookie->len; |
wolfSSL | 13:f67a6c6013ca | 4490 | |
wolfSSL | 13:f67a6c6013ca | 4491 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 4492 | } |
wolfSSL | 13:f67a6c6013ca | 4493 | |
wolfSSL | 13:f67a6c6013ca | 4494 | /* Writes the Cookie extension into the output buffer. |
wolfSSL | 13:f67a6c6013ca | 4495 | * Assumes that the the output buffer is big enough to hold data. |
wolfSSL | 13:f67a6c6013ca | 4496 | * In messages: ClientHello and HelloRetryRequest. |
wolfSSL | 13:f67a6c6013ca | 4497 | * |
wolfSSL | 13:f67a6c6013ca | 4498 | * cookie The cookie to write. |
wolfSSL | 13:f67a6c6013ca | 4499 | * output The buffer to write into. |
wolfSSL | 13:f67a6c6013ca | 4500 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:f67a6c6013ca | 4501 | * returns the number of bytes written into the buffer. |
wolfSSL | 13:f67a6c6013ca | 4502 | */ |
wolfSSL | 13:f67a6c6013ca | 4503 | static word16 TLSX_Cookie_Write(Cookie* cookie, byte* output, byte msgType) |
wolfSSL | 13:f67a6c6013ca | 4504 | { |
wolfSSL | 13:f67a6c6013ca | 4505 | if (msgType == client_hello || msgType == hello_retry_request) { |
wolfSSL | 13:f67a6c6013ca | 4506 | c16toa(cookie->len, output); |
wolfSSL | 13:f67a6c6013ca | 4507 | output += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 4508 | XMEMCPY(output, &cookie->data, cookie->len); |
wolfSSL | 13:f67a6c6013ca | 4509 | return OPAQUE16_LEN + cookie->len; |
wolfSSL | 13:f67a6c6013ca | 4510 | } |
wolfSSL | 13:f67a6c6013ca | 4511 | |
wolfSSL | 13:f67a6c6013ca | 4512 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 4513 | } |
wolfSSL | 13:f67a6c6013ca | 4514 | |
wolfSSL | 13:f67a6c6013ca | 4515 | /* Parse the Cookie extension. |
wolfSSL | 13:f67a6c6013ca | 4516 | * In messages: ClientHello and HelloRetryRequest. |
wolfSSL | 13:f67a6c6013ca | 4517 | * |
wolfSSL | 13:f67a6c6013ca | 4518 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 4519 | * input The extension data. |
wolfSSL | 13:f67a6c6013ca | 4520 | * length The length of the extension data. |
wolfSSL | 13:f67a6c6013ca | 4521 | * msgType The type of the message this extension is being parsed from. |
wolfSSL | 13:f67a6c6013ca | 4522 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 4523 | */ |
wolfSSL | 13:f67a6c6013ca | 4524 | static int TLSX_Cookie_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 4525 | byte msgType) |
wolfSSL | 13:f67a6c6013ca | 4526 | { |
wolfSSL | 13:f67a6c6013ca | 4527 | word16 len; |
wolfSSL | 13:f67a6c6013ca | 4528 | word16 idx = 0; |
wolfSSL | 13:f67a6c6013ca | 4529 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 4530 | Cookie* cookie; |
wolfSSL | 13:f67a6c6013ca | 4531 | |
wolfSSL | 13:f67a6c6013ca | 4532 | if (msgType != client_hello && msgType != hello_retry_request) |
wolfSSL | 13:f67a6c6013ca | 4533 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 4534 | |
wolfSSL | 13:f67a6c6013ca | 4535 | /* Message contains length and Cookie which must be at least one byte |
wolfSSL | 13:f67a6c6013ca | 4536 | * in length. |
wolfSSL | 13:f67a6c6013ca | 4537 | */ |
wolfSSL | 13:f67a6c6013ca | 4538 | if (length < OPAQUE16_LEN + 1) |
wolfSSL | 13:f67a6c6013ca | 4539 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 4540 | ato16(input + idx, &len); |
wolfSSL | 13:f67a6c6013ca | 4541 | idx += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 4542 | if (length - idx != len) |
wolfSSL | 13:f67a6c6013ca | 4543 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 4544 | |
wolfSSL | 13:f67a6c6013ca | 4545 | if (msgType == hello_retry_request) |
wolfSSL | 13:f67a6c6013ca | 4546 | return TLSX_Cookie_Use(ssl, input + idx, len, NULL, 0, 0); |
wolfSSL | 13:f67a6c6013ca | 4547 | |
wolfSSL | 13:f67a6c6013ca | 4548 | /* client_hello */ |
wolfSSL | 13:f67a6c6013ca | 4549 | extension = TLSX_Find(ssl->extensions, TLSX_COOKIE); |
wolfSSL | 13:f67a6c6013ca | 4550 | if (extension == NULL) |
wolfSSL | 13:f67a6c6013ca | 4551 | return HRR_COOKIE_ERROR; |
wolfSSL | 13:f67a6c6013ca | 4552 | |
wolfSSL | 13:f67a6c6013ca | 4553 | cookie = (Cookie*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 4554 | if (cookie->len != len || XMEMCMP(&cookie->data, input + idx, len) != 0) |
wolfSSL | 13:f67a6c6013ca | 4555 | return HRR_COOKIE_ERROR; |
wolfSSL | 13:f67a6c6013ca | 4556 | |
wolfSSL | 13:f67a6c6013ca | 4557 | /* Request seen. */ |
wolfSSL | 13:f67a6c6013ca | 4558 | extension->resp = 0; |
wolfSSL | 13:f67a6c6013ca | 4559 | |
wolfSSL | 13:f67a6c6013ca | 4560 | return 0; |
wolfSSL | 13:f67a6c6013ca | 4561 | } |
wolfSSL | 13:f67a6c6013ca | 4562 | |
wolfSSL | 13:f67a6c6013ca | 4563 | /* Use the data to create a new Cookie object in the extensions. |
wolfSSL | 13:f67a6c6013ca | 4564 | * |
wolfSSL | 13:f67a6c6013ca | 4565 | * ssl SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 4566 | * data Cookie data. |
wolfSSL | 13:f67a6c6013ca | 4567 | * len Length of cookie data in bytes. |
wolfSSL | 13:f67a6c6013ca | 4568 | * mac MAC data. |
wolfSSL | 13:f67a6c6013ca | 4569 | * macSz Length of MAC data in bytes. |
wolfSSL | 13:f67a6c6013ca | 4570 | * resp Indicates the extension will go into a response (HelloRetryRequest). |
wolfSSL | 13:f67a6c6013ca | 4571 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 4572 | */ |
wolfSSL | 13:f67a6c6013ca | 4573 | int TLSX_Cookie_Use(WOLFSSL* ssl, byte* data, word16 len, byte* mac, |
wolfSSL | 13:f67a6c6013ca | 4574 | byte macSz, int resp) |
wolfSSL | 13:f67a6c6013ca | 4575 | { |
wolfSSL | 13:f67a6c6013ca | 4576 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 4577 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 4578 | Cookie* cookie; |
wolfSSL | 13:f67a6c6013ca | 4579 | |
wolfSSL | 13:f67a6c6013ca | 4580 | /* Find the cookie extension if it exists. */ |
wolfSSL | 13:f67a6c6013ca | 4581 | extension = TLSX_Find(ssl->extensions, TLSX_COOKIE); |
wolfSSL | 13:f67a6c6013ca | 4582 | if (extension == NULL) { |
wolfSSL | 13:f67a6c6013ca | 4583 | /* Push new cookie extension. */ |
wolfSSL | 13:f67a6c6013ca | 4584 | ret = TLSX_Push(&ssl->extensions, TLSX_COOKIE, NULL, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 4585 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 4586 | return ret; |
wolfSSL | 13:f67a6c6013ca | 4587 | |
wolfSSL | 13:f67a6c6013ca | 4588 | extension = TLSX_Find(ssl->extensions, TLSX_COOKIE); |
wolfSSL | 13:f67a6c6013ca | 4589 | if (extension == NULL) |
wolfSSL | 13:f67a6c6013ca | 4590 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 4591 | } |
wolfSSL | 13:f67a6c6013ca | 4592 | |
wolfSSL | 13:f67a6c6013ca | 4593 | /* The Cookie structure has one byte for cookie data already. */ |
wolfSSL | 13:f67a6c6013ca | 4594 | cookie = (Cookie*)XMALLOC(sizeof(Cookie) + len + macSz - 1, ssl->heap, |
wolfSSL | 13:f67a6c6013ca | 4595 | DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 4596 | if (cookie == NULL) |
wolfSSL | 13:f67a6c6013ca | 4597 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 4598 | |
wolfSSL | 13:f67a6c6013ca | 4599 | cookie->len = len + macSz; |
wolfSSL | 13:f67a6c6013ca | 4600 | XMEMCPY(&cookie->data, data, len); |
wolfSSL | 13:f67a6c6013ca | 4601 | if (mac != NULL) |
wolfSSL | 13:f67a6c6013ca | 4602 | XMEMCPY(&cookie->data + len, mac, macSz); |
wolfSSL | 13:f67a6c6013ca | 4603 | |
wolfSSL | 13:f67a6c6013ca | 4604 | extension->data = (void*)cookie; |
wolfSSL | 13:f67a6c6013ca | 4605 | extension->resp = resp; |
wolfSSL | 13:f67a6c6013ca | 4606 | |
wolfSSL | 13:f67a6c6013ca | 4607 | return 0; |
wolfSSL | 13:f67a6c6013ca | 4608 | } |
wolfSSL | 13:f67a6c6013ca | 4609 | |
wolfSSL | 13:f67a6c6013ca | 4610 | #define CKE_FREE_ALL TLSX_Cookie_FreeAll |
wolfSSL | 13:f67a6c6013ca | 4611 | #define CKE_GET_SIZE TLSX_Cookie_GetSize |
wolfSSL | 13:f67a6c6013ca | 4612 | #define CKE_WRITE TLSX_Cookie_Write |
wolfSSL | 13:f67a6c6013ca | 4613 | #define CKE_PARSE TLSX_Cookie_Parse |
wolfSSL | 13:f67a6c6013ca | 4614 | |
wolfSSL | 13:f67a6c6013ca | 4615 | #else |
wolfSSL | 13:f67a6c6013ca | 4616 | |
wolfSSL | 13:f67a6c6013ca | 4617 | #define CKE_FREE_ALL(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 4618 | #define CKE_GET_SIZE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 4619 | #define CKE_WRITE(a, b, c) 0 |
wolfSSL | 13:f67a6c6013ca | 4620 | #define CKE_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 4621 | |
wolfSSL | 13:f67a6c6013ca | 4622 | #endif |
wolfSSL | 13:f67a6c6013ca | 4623 | |
wolfSSL | 13:f67a6c6013ca | 4624 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 4625 | /* Sugnature Algorithms */ |
wolfSSL | 13:f67a6c6013ca | 4626 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 4627 | |
wolfSSL | 13:f67a6c6013ca | 4628 | /* Return the size of the SignatureAlgorithms extension's data. |
wolfSSL | 13:f67a6c6013ca | 4629 | * |
wolfSSL | 13:f67a6c6013ca | 4630 | * data Unused |
wolfSSL | 13:f67a6c6013ca | 4631 | * returns the length of data that will be in the extension. |
wolfSSL | 13:f67a6c6013ca | 4632 | */ |
wolfSSL | 13:f67a6c6013ca | 4633 | static word16 TLSX_SignatureAlgorithms_GetSize(void* data) |
wolfSSL | 13:f67a6c6013ca | 4634 | { |
wolfSSL | 13:f67a6c6013ca | 4635 | WOLFSSL* ssl = (WOLFSSL*)data; |
wolfSSL | 13:f67a6c6013ca | 4636 | |
wolfSSL | 13:f67a6c6013ca | 4637 | return OPAQUE16_LEN + ssl->suites->hashSigAlgoSz; |
wolfSSL | 13:f67a6c6013ca | 4638 | } |
wolfSSL | 13:f67a6c6013ca | 4639 | |
wolfSSL | 13:f67a6c6013ca | 4640 | /* Creates a bit string of supported hash algorithms with RSA PSS. |
wolfSSL | 13:f67a6c6013ca | 4641 | * The bit string is used when determining which signature algorithm to use |
wolfSSL | 13:f67a6c6013ca | 4642 | * when creating the CertificateVerify message. |
wolfSSL | 13:f67a6c6013ca | 4643 | * Note: Valid data has an even length as each signature algorithm is two bytes. |
wolfSSL | 13:f67a6c6013ca | 4644 | * |
wolfSSL | 13:f67a6c6013ca | 4645 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 4646 | * input The buffer with the list of supported signature algorithms. |
wolfSSL | 13:f67a6c6013ca | 4647 | * length The length of the list in bytes. |
wolfSSL | 13:f67a6c6013ca | 4648 | * returns 0 on success, BUFFER_ERROR when the length is not even. |
wolfSSL | 13:f67a6c6013ca | 4649 | */ |
wolfSSL | 13:f67a6c6013ca | 4650 | static int TLSX_SignatureAlgorithms_MapPss(WOLFSSL *ssl, byte* input, |
wolfSSL | 13:f67a6c6013ca | 4651 | word16 length) |
wolfSSL | 13:f67a6c6013ca | 4652 | { |
wolfSSL | 13:f67a6c6013ca | 4653 | word16 i; |
wolfSSL | 13:f67a6c6013ca | 4654 | |
wolfSSL | 13:f67a6c6013ca | 4655 | if ((length & 1) == 1) |
wolfSSL | 13:f67a6c6013ca | 4656 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 4657 | |
wolfSSL | 13:f67a6c6013ca | 4658 | ssl->pssAlgo = 0; |
wolfSSL | 13:f67a6c6013ca | 4659 | for (i = 0; i < length; i += 2) { |
wolfSSL | 13:f67a6c6013ca | 4660 | if (input[i] == rsa_pss_sa_algo && input[i + 1] <= sha512_mac) |
wolfSSL | 13:f67a6c6013ca | 4661 | ssl->pssAlgo |= 1 << input[i + 1]; |
wolfSSL | 13:f67a6c6013ca | 4662 | } |
wolfSSL | 13:f67a6c6013ca | 4663 | |
wolfSSL | 13:f67a6c6013ca | 4664 | return 0; |
wolfSSL | 13:f67a6c6013ca | 4665 | } |
wolfSSL | 13:f67a6c6013ca | 4666 | |
wolfSSL | 13:f67a6c6013ca | 4667 | /* Writes the SignatureAlgorithms extension into the buffer. |
wolfSSL | 13:f67a6c6013ca | 4668 | * |
wolfSSL | 13:f67a6c6013ca | 4669 | * data Unused |
wolfSSL | 13:f67a6c6013ca | 4670 | * output The buffer to write the extension into. |
wolfSSL | 13:f67a6c6013ca | 4671 | * returns the length of data that was written. |
wolfSSL | 13:f67a6c6013ca | 4672 | */ |
wolfSSL | 13:f67a6c6013ca | 4673 | static word16 TLSX_SignatureAlgorithms_Write(void* data, byte* output) |
wolfSSL | 13:f67a6c6013ca | 4674 | { |
wolfSSL | 13:f67a6c6013ca | 4675 | WOLFSSL* ssl = (WOLFSSL*)data; |
wolfSSL | 13:f67a6c6013ca | 4676 | |
wolfSSL | 13:f67a6c6013ca | 4677 | c16toa(ssl->suites->hashSigAlgoSz, output); |
wolfSSL | 13:f67a6c6013ca | 4678 | XMEMCPY(output + OPAQUE16_LEN, ssl->suites->hashSigAlgo, |
wolfSSL | 13:f67a6c6013ca | 4679 | ssl->suites->hashSigAlgoSz); |
wolfSSL | 13:f67a6c6013ca | 4680 | |
wolfSSL | 13:f67a6c6013ca | 4681 | TLSX_SignatureAlgorithms_MapPss(ssl, output + OPAQUE16_LEN, |
wolfSSL | 13:f67a6c6013ca | 4682 | ssl->suites->hashSigAlgoSz); |
wolfSSL | 13:f67a6c6013ca | 4683 | |
wolfSSL | 13:f67a6c6013ca | 4684 | return OPAQUE16_LEN + ssl->suites->hashSigAlgoSz; |
wolfSSL | 13:f67a6c6013ca | 4685 | } |
wolfSSL | 13:f67a6c6013ca | 4686 | |
wolfSSL | 13:f67a6c6013ca | 4687 | /* Parse the SignatureAlgorithms extension. |
wolfSSL | 13:f67a6c6013ca | 4688 | * |
wolfSSL | 13:f67a6c6013ca | 4689 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 4690 | * input The buffer with the extension data. |
wolfSSL | 13:f67a6c6013ca | 4691 | * length The length of the extension data. |
wolfSSL | 13:f67a6c6013ca | 4692 | * returns 0 on success, otherwise failure. |
wolfSSL | 13:f67a6c6013ca | 4693 | */ |
wolfSSL | 13:f67a6c6013ca | 4694 | static int TLSX_SignatureAlgorithms_Parse(WOLFSSL *ssl, byte* input, |
wolfSSL | 13:f67a6c6013ca | 4695 | word16 length, Suites* suites) |
wolfSSL | 13:f67a6c6013ca | 4696 | { |
wolfSSL | 13:f67a6c6013ca | 4697 | word16 len; |
wolfSSL | 13:f67a6c6013ca | 4698 | |
wolfSSL | 13:f67a6c6013ca | 4699 | (void)ssl; |
wolfSSL | 13:f67a6c6013ca | 4700 | |
wolfSSL | 13:f67a6c6013ca | 4701 | /* Must contain a length and at least algorithm. */ |
wolfSSL | 13:f67a6c6013ca | 4702 | if (length < OPAQUE16_LEN + OPAQUE16_LEN || (length & 1) != 0) |
wolfSSL | 13:f67a6c6013ca | 4703 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 4704 | |
wolfSSL | 13:f67a6c6013ca | 4705 | ato16(input, &len); |
wolfSSL | 13:f67a6c6013ca | 4706 | input += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 4707 | |
wolfSSL | 13:f67a6c6013ca | 4708 | /* Algorithm array must fill rest of data. */ |
wolfSSL | 13:f67a6c6013ca | 4709 | if (length != OPAQUE16_LEN + len) |
wolfSSL | 13:f67a6c6013ca | 4710 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 4711 | |
wolfSSL | 13:f67a6c6013ca | 4712 | XMEMCPY(suites->hashSigAlgo, input, len); |
wolfSSL | 13:f67a6c6013ca | 4713 | suites->hashSigAlgoSz = len; |
wolfSSL | 13:f67a6c6013ca | 4714 | |
wolfSSL | 13:f67a6c6013ca | 4715 | return TLSX_SignatureAlgorithms_MapPss(ssl, input, len); |
wolfSSL | 13:f67a6c6013ca | 4716 | } |
wolfSSL | 13:f67a6c6013ca | 4717 | |
wolfSSL | 13:f67a6c6013ca | 4718 | /* Sets a new SupportedVersions extension into the extension list. |
wolfSSL | 13:f67a6c6013ca | 4719 | * |
wolfSSL | 13:f67a6c6013ca | 4720 | * extensions The list of extensions. |
wolfSSL | 13:f67a6c6013ca | 4721 | * data The extensions specific data. |
wolfSSL | 13:f67a6c6013ca | 4722 | * heap The heap used for allocation. |
wolfSSL | 13:f67a6c6013ca | 4723 | * returns 0 on success, otherwise failure. |
wolfSSL | 13:f67a6c6013ca | 4724 | */ |
wolfSSL | 13:f67a6c6013ca | 4725 | static int TLSX_SetSignatureAlgorithms(TLSX** extensions, const void* data, |
wolfSSL | 13:f67a6c6013ca | 4726 | void* heap) |
wolfSSL | 13:f67a6c6013ca | 4727 | { |
wolfSSL | 13:f67a6c6013ca | 4728 | if (extensions == NULL) |
wolfSSL | 13:f67a6c6013ca | 4729 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 4730 | |
wolfSSL | 13:f67a6c6013ca | 4731 | return TLSX_Push(extensions, TLSX_SIGNATURE_ALGORITHMS, (void *)data, heap); |
wolfSSL | 13:f67a6c6013ca | 4732 | } |
wolfSSL | 13:f67a6c6013ca | 4733 | |
wolfSSL | 13:f67a6c6013ca | 4734 | #define SA_GET_SIZE TLSX_SignatureAlgorithms_GetSize |
wolfSSL | 13:f67a6c6013ca | 4735 | #define SA_WRITE TLSX_SignatureAlgorithms_Write |
wolfSSL | 13:f67a6c6013ca | 4736 | #define SA_PARSE TLSX_SignatureAlgorithms_Parse |
wolfSSL | 13:f67a6c6013ca | 4737 | |
wolfSSL | 13:f67a6c6013ca | 4738 | |
wolfSSL | 13:f67a6c6013ca | 4739 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 4740 | /* Key Share */ |
wolfSSL | 13:f67a6c6013ca | 4741 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 4742 | |
wolfSSL | 13:f67a6c6013ca | 4743 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 4744 | #ifndef NO_DH |
wolfSSL | 13:f67a6c6013ca | 4745 | /* Create a key share entry using named Diffie-Hellman parameters group. |
wolfSSL | 13:f67a6c6013ca | 4746 | * Generates a key pair. |
wolfSSL | 13:f67a6c6013ca | 4747 | * |
wolfSSL | 13:f67a6c6013ca | 4748 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 4749 | * kse The key share entry object. |
wolfSSL | 13:f67a6c6013ca | 4750 | * returns 0 on success, otherwise failure. |
wolfSSL | 13:f67a6c6013ca | 4751 | */ |
wolfSSL | 13:f67a6c6013ca | 4752 | static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse) |
wolfSSL | 13:f67a6c6013ca | 4753 | { |
wolfSSL | 13:f67a6c6013ca | 4754 | int ret; |
wolfSSL | 13:f67a6c6013ca | 4755 | byte* keyData; |
wolfSSL | 13:f67a6c6013ca | 4756 | void* key = NULL; |
wolfSSL | 13:f67a6c6013ca | 4757 | word32 keySz; |
wolfSSL | 13:f67a6c6013ca | 4758 | word32 dataSz; |
wolfSSL | 13:f67a6c6013ca | 4759 | const DhParams* params; |
wolfSSL | 13:f67a6c6013ca | 4760 | DhKey dhKey; |
wolfSSL | 13:f67a6c6013ca | 4761 | |
wolfSSL | 13:f67a6c6013ca | 4762 | /* TODO: [TLS13] The key size should come from wolfcrypt. */ |
wolfSSL | 13:f67a6c6013ca | 4763 | /* Pick the parameters from the named group. */ |
wolfSSL | 13:f67a6c6013ca | 4764 | switch (kse->group) { |
wolfSSL | 13:f67a6c6013ca | 4765 | #ifdef HAVE_FFDHE_2048 |
wolfSSL | 13:f67a6c6013ca | 4766 | case WOLFSSL_FFDHE_2048: |
wolfSSL | 13:f67a6c6013ca | 4767 | params = wc_Dh_ffdhe2048_Get(); |
wolfSSL | 13:f67a6c6013ca | 4768 | keySz = 29; |
wolfSSL | 13:f67a6c6013ca | 4769 | break; |
wolfSSL | 13:f67a6c6013ca | 4770 | #endif |
wolfSSL | 13:f67a6c6013ca | 4771 | #ifdef HAVE_FFDHE_3072 |
wolfSSL | 13:f67a6c6013ca | 4772 | case WOLFSSL_FFDHE_3072: |
wolfSSL | 13:f67a6c6013ca | 4773 | params = wc_Dh_ffdhe3072_Get(); |
wolfSSL | 13:f67a6c6013ca | 4774 | keySz = 34; |
wolfSSL | 13:f67a6c6013ca | 4775 | break; |
wolfSSL | 13:f67a6c6013ca | 4776 | #endif |
wolfSSL | 13:f67a6c6013ca | 4777 | #ifdef HAVE_FFDHE_4096 |
wolfSSL | 13:f67a6c6013ca | 4778 | case WOLFSSL_FFDHE_4096: |
wolfSSL | 13:f67a6c6013ca | 4779 | params = wc_Dh_ffdhe4096_Get(); |
wolfSSL | 13:f67a6c6013ca | 4780 | keySz = 39; |
wolfSSL | 13:f67a6c6013ca | 4781 | break; |
wolfSSL | 13:f67a6c6013ca | 4782 | #endif |
wolfSSL | 13:f67a6c6013ca | 4783 | #ifdef HAVE_FFDHE_6144 |
wolfSSL | 13:f67a6c6013ca | 4784 | case WOLFSSL_FFDHE_6144: |
wolfSSL | 13:f67a6c6013ca | 4785 | params = wc_Dh_ffdhe6144_Get(); |
wolfSSL | 13:f67a6c6013ca | 4786 | keySz = 46; |
wolfSSL | 13:f67a6c6013ca | 4787 | break; |
wolfSSL | 13:f67a6c6013ca | 4788 | #endif |
wolfSSL | 13:f67a6c6013ca | 4789 | #ifdef HAVE_FFDHE_8192 |
wolfSSL | 13:f67a6c6013ca | 4790 | case WOLFSSL_FFDHE_8192: |
wolfSSL | 13:f67a6c6013ca | 4791 | params = wc_Dh_ffdhe8192_Get(); |
wolfSSL | 13:f67a6c6013ca | 4792 | keySz = 52; |
wolfSSL | 13:f67a6c6013ca | 4793 | break; |
wolfSSL | 13:f67a6c6013ca | 4794 | #endif |
wolfSSL | 13:f67a6c6013ca | 4795 | default: |
wolfSSL | 13:f67a6c6013ca | 4796 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 4797 | } |
wolfSSL | 13:f67a6c6013ca | 4798 | |
wolfSSL | 13:f67a6c6013ca | 4799 | ret = wc_InitDhKey_ex(&dhKey, ssl->heap, ssl->devId); |
wolfSSL | 13:f67a6c6013ca | 4800 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 4801 | return ret; |
wolfSSL | 13:f67a6c6013ca | 4802 | |
wolfSSL | 13:f67a6c6013ca | 4803 | /* Allocate space for the public key. */ |
wolfSSL | 13:f67a6c6013ca | 4804 | dataSz = params->p_len; |
wolfSSL | 13:f67a6c6013ca | 4805 | keyData = (byte*)XMALLOC(dataSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); |
wolfSSL | 13:f67a6c6013ca | 4806 | if (keyData == NULL) { |
wolfSSL | 13:f67a6c6013ca | 4807 | ret = MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 4808 | goto end; |
wolfSSL | 13:f67a6c6013ca | 4809 | } |
wolfSSL | 13:f67a6c6013ca | 4810 | /* Allocate space for the private key. */ |
wolfSSL | 13:f67a6c6013ca | 4811 | key = (byte*)XMALLOC(keySz, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); |
wolfSSL | 13:f67a6c6013ca | 4812 | if (key == NULL) { |
wolfSSL | 13:f67a6c6013ca | 4813 | ret = MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 4814 | goto end; |
wolfSSL | 13:f67a6c6013ca | 4815 | } |
wolfSSL | 13:f67a6c6013ca | 4816 | |
wolfSSL | 13:f67a6c6013ca | 4817 | /* Set key */ |
wolfSSL | 13:f67a6c6013ca | 4818 | ret = wc_DhSetKey(&dhKey, |
wolfSSL | 13:f67a6c6013ca | 4819 | (byte*)params->p, params->p_len, |
wolfSSL | 13:f67a6c6013ca | 4820 | (byte*)params->g, params->g_len); |
wolfSSL | 13:f67a6c6013ca | 4821 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 4822 | goto end; |
wolfSSL | 13:f67a6c6013ca | 4823 | |
wolfSSL | 13:f67a6c6013ca | 4824 | /* Generate a new key pair. */ |
wolfSSL | 13:f67a6c6013ca | 4825 | ret = wc_DhGenerateKeyPair(&dhKey, ssl->rng, (byte*)key, &keySz, keyData, |
wolfSSL | 13:f67a6c6013ca | 4826 | &dataSz); |
wolfSSL | 13:f67a6c6013ca | 4827 | #ifdef WOLFSSL_ASYNC_CRYPT |
wolfSSL | 13:f67a6c6013ca | 4828 | /* TODO: Make this function non-blocking */ |
wolfSSL | 13:f67a6c6013ca | 4829 | if (ret == WC_PENDING_E) { |
wolfSSL | 13:f67a6c6013ca | 4830 | ret = wc_AsyncWait(ret, &dhKey.asyncDev, WC_ASYNC_FLAG_NONE); |
wolfSSL | 13:f67a6c6013ca | 4831 | } |
wolfSSL | 13:f67a6c6013ca | 4832 | #endif |
wolfSSL | 13:f67a6c6013ca | 4833 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 4834 | goto end; |
wolfSSL | 13:f67a6c6013ca | 4835 | |
wolfSSL | 13:f67a6c6013ca | 4836 | if (params->p_len != dataSz) { |
wolfSSL | 13:f67a6c6013ca | 4837 | /* Pad the front of the key data with zeros. */ |
wolfSSL | 13:f67a6c6013ca | 4838 | XMEMMOVE(keyData + params->p_len - dataSz, keyData, dataSz); |
wolfSSL | 13:f67a6c6013ca | 4839 | XMEMSET(keyData, 0, params->p_len - dataSz); |
wolfSSL | 13:f67a6c6013ca | 4840 | } |
wolfSSL | 13:f67a6c6013ca | 4841 | |
wolfSSL | 13:f67a6c6013ca | 4842 | kse->ke = keyData; |
wolfSSL | 13:f67a6c6013ca | 4843 | kse->keLen = params->p_len; |
wolfSSL | 13:f67a6c6013ca | 4844 | kse->key = key; |
wolfSSL | 13:f67a6c6013ca | 4845 | kse->keyLen = keySz; |
wolfSSL | 13:f67a6c6013ca | 4846 | |
wolfSSL | 13:f67a6c6013ca | 4847 | #ifdef WOLFSSL_DEBUG_TLS |
wolfSSL | 13:f67a6c6013ca | 4848 | WOLFSSL_MSG("Public DH Key"); |
wolfSSL | 13:f67a6c6013ca | 4849 | WOLFSSL_BUFFER(keyData, params->p_len); |
wolfSSL | 13:f67a6c6013ca | 4850 | #endif |
wolfSSL | 13:f67a6c6013ca | 4851 | |
wolfSSL | 13:f67a6c6013ca | 4852 | end: |
wolfSSL | 13:f67a6c6013ca | 4853 | |
wolfSSL | 13:f67a6c6013ca | 4854 | wc_FreeDhKey(&dhKey); |
wolfSSL | 13:f67a6c6013ca | 4855 | |
wolfSSL | 13:f67a6c6013ca | 4856 | if (ret != 0) { |
wolfSSL | 13:f67a6c6013ca | 4857 | /* Data owned by key share entry otherwise. */ |
wolfSSL | 13:f67a6c6013ca | 4858 | if (keyData != NULL) |
wolfSSL | 13:f67a6c6013ca | 4859 | XFREE(keyData, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); |
wolfSSL | 13:f67a6c6013ca | 4860 | if (key != NULL) |
wolfSSL | 13:f67a6c6013ca | 4861 | XFREE(key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); |
wolfSSL | 13:f67a6c6013ca | 4862 | } |
wolfSSL | 13:f67a6c6013ca | 4863 | |
wolfSSL | 13:f67a6c6013ca | 4864 | return ret; |
wolfSSL | 13:f67a6c6013ca | 4865 | } |
wolfSSL | 13:f67a6c6013ca | 4866 | #endif |
wolfSSL | 13:f67a6c6013ca | 4867 | |
wolfSSL | 13:f67a6c6013ca | 4868 | #ifdef HAVE_ECC |
wolfSSL | 13:f67a6c6013ca | 4869 | /* Create a key share entry using named elliptic curve parameters group. |
wolfSSL | 13:f67a6c6013ca | 4870 | * Generates a key pair. |
wolfSSL | 13:f67a6c6013ca | 4871 | * |
wolfSSL | 13:f67a6c6013ca | 4872 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 4873 | * kse The key share entry object. |
wolfSSL | 13:f67a6c6013ca | 4874 | * returns 0 on success, otherwise failure. |
wolfSSL | 13:f67a6c6013ca | 4875 | */ |
wolfSSL | 13:f67a6c6013ca | 4876 | static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) |
wolfSSL | 13:f67a6c6013ca | 4877 | { |
wolfSSL | 13:f67a6c6013ca | 4878 | int ret; |
wolfSSL | 13:f67a6c6013ca | 4879 | byte* keyData = NULL; |
wolfSSL | 13:f67a6c6013ca | 4880 | word32 dataSize; |
wolfSSL | 13:f67a6c6013ca | 4881 | word32 keySize; |
wolfSSL | 13:f67a6c6013ca | 4882 | ecc_key* eccKey = NULL; |
wolfSSL | 13:f67a6c6013ca | 4883 | word16 curveId; |
wolfSSL | 13:f67a6c6013ca | 4884 | |
wolfSSL | 13:f67a6c6013ca | 4885 | /* TODO: [TLS13] The key sizes should come from wolfcrypt. */ |
wolfSSL | 13:f67a6c6013ca | 4886 | /* Translate named group to a curve id. */ |
wolfSSL | 13:f67a6c6013ca | 4887 | switch (kse->group) { |
wolfSSL | 13:f67a6c6013ca | 4888 | #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 4889 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 4890 | case WOLFSSL_ECC_SECP256R1: |
wolfSSL | 13:f67a6c6013ca | 4891 | curveId = ECC_SECP256R1; |
wolfSSL | 13:f67a6c6013ca | 4892 | keySize = 32; |
wolfSSL | 13:f67a6c6013ca | 4893 | dataSize = keySize * 2 + 1; |
wolfSSL | 13:f67a6c6013ca | 4894 | break; |
wolfSSL | 13:f67a6c6013ca | 4895 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:f67a6c6013ca | 4896 | #endif |
wolfSSL | 13:f67a6c6013ca | 4897 | #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 4898 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 4899 | case WOLFSSL_ECC_SECP384R1: |
wolfSSL | 13:f67a6c6013ca | 4900 | curveId = ECC_SECP384R1; |
wolfSSL | 13:f67a6c6013ca | 4901 | keySize = 48; |
wolfSSL | 13:f67a6c6013ca | 4902 | dataSize = keySize * 2 + 1; |
wolfSSL | 13:f67a6c6013ca | 4903 | break; |
wolfSSL | 13:f67a6c6013ca | 4904 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:f67a6c6013ca | 4905 | #endif |
wolfSSL | 13:f67a6c6013ca | 4906 | #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 4907 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 4908 | case WOLFSSL_ECC_SECP521R1: |
wolfSSL | 13:f67a6c6013ca | 4909 | curveId = ECC_SECP521R1; |
wolfSSL | 13:f67a6c6013ca | 4910 | keySize = 66; |
wolfSSL | 13:f67a6c6013ca | 4911 | dataSize = keySize * 2 + 1; |
wolfSSL | 13:f67a6c6013ca | 4912 | break; |
wolfSSL | 13:f67a6c6013ca | 4913 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:f67a6c6013ca | 4914 | #endif |
wolfSSL | 13:f67a6c6013ca | 4915 | #ifdef HAVE_CURVE25519 |
wolfSSL | 13:f67a6c6013ca | 4916 | case WOLFSSL_ECC_X25519: |
wolfSSL | 13:f67a6c6013ca | 4917 | { |
wolfSSL | 13:f67a6c6013ca | 4918 | curve25519_key* key; |
wolfSSL | 13:f67a6c6013ca | 4919 | /* Allocate an ECC key to hold private key. */ |
wolfSSL | 13:f67a6c6013ca | 4920 | key = (curve25519_key*)XMALLOC(sizeof(curve25519_key), |
wolfSSL | 13:f67a6c6013ca | 4921 | ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); |
wolfSSL | 13:f67a6c6013ca | 4922 | if (key == NULL) { |
wolfSSL | 13:f67a6c6013ca | 4923 | WOLFSSL_MSG("EccTempKey Memory error"); |
wolfSSL | 13:f67a6c6013ca | 4924 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 4925 | } |
wolfSSL | 13:f67a6c6013ca | 4926 | |
wolfSSL | 13:f67a6c6013ca | 4927 | dataSize = keySize = 32; |
wolfSSL | 13:f67a6c6013ca | 4928 | |
wolfSSL | 13:f67a6c6013ca | 4929 | /* Make an ECC key. */ |
wolfSSL | 13:f67a6c6013ca | 4930 | ret = wc_curve25519_init(key); |
wolfSSL | 13:f67a6c6013ca | 4931 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 4932 | goto end; |
wolfSSL | 13:f67a6c6013ca | 4933 | ret = wc_curve25519_make_key(ssl->rng, keySize, key); |
wolfSSL | 13:f67a6c6013ca | 4934 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 4935 | goto end; |
wolfSSL | 13:f67a6c6013ca | 4936 | |
wolfSSL | 13:f67a6c6013ca | 4937 | /* Allocate space for the public key. */ |
wolfSSL | 13:f67a6c6013ca | 4938 | keyData = (byte*)XMALLOC(dataSize, ssl->heap, |
wolfSSL | 13:f67a6c6013ca | 4939 | DYNAMIC_TYPE_PUBLIC_KEY); |
wolfSSL | 13:f67a6c6013ca | 4940 | if (keyData == NULL) { |
wolfSSL | 13:f67a6c6013ca | 4941 | WOLFSSL_MSG("Key data Memory error"); |
wolfSSL | 13:f67a6c6013ca | 4942 | ret = MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 4943 | goto end; |
wolfSSL | 13:f67a6c6013ca | 4944 | } |
wolfSSL | 13:f67a6c6013ca | 4945 | |
wolfSSL | 13:f67a6c6013ca | 4946 | /* Export public key. */ |
wolfSSL | 13:f67a6c6013ca | 4947 | if (wc_curve25519_export_public_ex(key, keyData, &dataSize, |
wolfSSL | 13:f67a6c6013ca | 4948 | EC25519_LITTLE_ENDIAN) != 0) { |
wolfSSL | 13:f67a6c6013ca | 4949 | ret = ECC_EXPORT_ERROR; |
wolfSSL | 13:f67a6c6013ca | 4950 | goto end; |
wolfSSL | 13:f67a6c6013ca | 4951 | } |
wolfSSL | 13:f67a6c6013ca | 4952 | |
wolfSSL | 13:f67a6c6013ca | 4953 | kse->ke = keyData; |
wolfSSL | 13:f67a6c6013ca | 4954 | kse->keLen = dataSize; |
wolfSSL | 13:f67a6c6013ca | 4955 | kse->key = key; |
wolfSSL | 13:f67a6c6013ca | 4956 | |
wolfSSL | 13:f67a6c6013ca | 4957 | #ifdef WOLFSSL_DEBUG_TLS |
wolfSSL | 13:f67a6c6013ca | 4958 | WOLFSSL_MSG("Public Curve25519 Key"); |
wolfSSL | 13:f67a6c6013ca | 4959 | WOLFSSL_BUFFER(keyData, dataSize); |
wolfSSL | 13:f67a6c6013ca | 4960 | #endif |
wolfSSL | 13:f67a6c6013ca | 4961 | |
wolfSSL | 13:f67a6c6013ca | 4962 | goto end; |
wolfSSL | 13:f67a6c6013ca | 4963 | } |
wolfSSL | 13:f67a6c6013ca | 4964 | #endif |
wolfSSL | 13:f67a6c6013ca | 4965 | #ifdef HAVE_X448 |
wolfSSL | 13:f67a6c6013ca | 4966 | case WOLFSSL_ECC_X448: |
wolfSSL | 13:f67a6c6013ca | 4967 | curveId = ECC_X448; |
wolfSSL | 13:f67a6c6013ca | 4968 | dataSize = keySize = 56; |
wolfSSL | 13:f67a6c6013ca | 4969 | break; |
wolfSSL | 13:f67a6c6013ca | 4970 | #endif |
wolfSSL | 13:f67a6c6013ca | 4971 | default: |
wolfSSL | 13:f67a6c6013ca | 4972 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 4973 | } |
wolfSSL | 13:f67a6c6013ca | 4974 | |
wolfSSL | 13:f67a6c6013ca | 4975 | /* Allocate an ECC key to hold private key. */ |
wolfSSL | 13:f67a6c6013ca | 4976 | eccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->heap, |
wolfSSL | 13:f67a6c6013ca | 4977 | DYNAMIC_TYPE_PRIVATE_KEY); |
wolfSSL | 13:f67a6c6013ca | 4978 | if (eccKey == NULL) { |
wolfSSL | 13:f67a6c6013ca | 4979 | WOLFSSL_MSG("EccTempKey Memory error"); |
wolfSSL | 13:f67a6c6013ca | 4980 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 4981 | } |
wolfSSL | 13:f67a6c6013ca | 4982 | |
wolfSSL | 13:f67a6c6013ca | 4983 | /* Make an ECC key. */ |
wolfSSL | 13:f67a6c6013ca | 4984 | ret = wc_ecc_init_ex(eccKey, ssl->heap, ssl->devId); |
wolfSSL | 13:f67a6c6013ca | 4985 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 4986 | goto end; |
wolfSSL | 13:f67a6c6013ca | 4987 | ret = wc_ecc_make_key_ex(ssl->rng, keySize, eccKey, curveId); |
wolfSSL | 13:f67a6c6013ca | 4988 | #ifdef WOLFSSL_ASYNC_CRYPT |
wolfSSL | 13:f67a6c6013ca | 4989 | /* TODO: Make this function non-blocking */ |
wolfSSL | 13:f67a6c6013ca | 4990 | if (ret == WC_PENDING_E) { |
wolfSSL | 13:f67a6c6013ca | 4991 | ret = wc_AsyncWait(ret, &eccKey->asyncDev, WC_ASYNC_FLAG_NONE); |
wolfSSL | 13:f67a6c6013ca | 4992 | } |
wolfSSL | 13:f67a6c6013ca | 4993 | #endif |
wolfSSL | 13:f67a6c6013ca | 4994 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 4995 | goto end; |
wolfSSL | 13:f67a6c6013ca | 4996 | |
wolfSSL | 13:f67a6c6013ca | 4997 | /* Allocate space for the public key. */ |
wolfSSL | 13:f67a6c6013ca | 4998 | keyData = (byte*)XMALLOC(dataSize, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); |
wolfSSL | 13:f67a6c6013ca | 4999 | if (keyData == NULL) { |
wolfSSL | 13:f67a6c6013ca | 5000 | WOLFSSL_MSG("Key data Memory error"); |
wolfSSL | 13:f67a6c6013ca | 5001 | ret = MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 5002 | goto end; |
wolfSSL | 13:f67a6c6013ca | 5003 | } |
wolfSSL | 13:f67a6c6013ca | 5004 | |
wolfSSL | 13:f67a6c6013ca | 5005 | /* Export public key. */ |
wolfSSL | 13:f67a6c6013ca | 5006 | if (wc_ecc_export_x963(eccKey, keyData, &dataSize) != 0) { |
wolfSSL | 13:f67a6c6013ca | 5007 | ret = ECC_EXPORT_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5008 | goto end; |
wolfSSL | 13:f67a6c6013ca | 5009 | } |
wolfSSL | 13:f67a6c6013ca | 5010 | |
wolfSSL | 13:f67a6c6013ca | 5011 | kse->ke = keyData; |
wolfSSL | 13:f67a6c6013ca | 5012 | kse->keLen = dataSize; |
wolfSSL | 13:f67a6c6013ca | 5013 | kse->key = eccKey; |
wolfSSL | 13:f67a6c6013ca | 5014 | |
wolfSSL | 13:f67a6c6013ca | 5015 | #ifdef WOLFSSL_DEBUG_TLS |
wolfSSL | 13:f67a6c6013ca | 5016 | WOLFSSL_MSG("Public ECC Key"); |
wolfSSL | 13:f67a6c6013ca | 5017 | WOLFSSL_BUFFER(keyData, dataSize); |
wolfSSL | 13:f67a6c6013ca | 5018 | #endif |
wolfSSL | 13:f67a6c6013ca | 5019 | |
wolfSSL | 13:f67a6c6013ca | 5020 | end: |
wolfSSL | 13:f67a6c6013ca | 5021 | if (ret != 0) { |
wolfSSL | 13:f67a6c6013ca | 5022 | /* Data owned by key share entry otherwise. */ |
wolfSSL | 13:f67a6c6013ca | 5023 | if (eccKey != NULL) |
wolfSSL | 13:f67a6c6013ca | 5024 | XFREE(eccKey, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 5025 | if (keyData != NULL) |
wolfSSL | 13:f67a6c6013ca | 5026 | XFREE(keyData, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 5027 | } |
wolfSSL | 13:f67a6c6013ca | 5028 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5029 | } |
wolfSSL | 13:f67a6c6013ca | 5030 | #endif /* HAVE_ECC */ |
wolfSSL | 13:f67a6c6013ca | 5031 | |
wolfSSL | 13:f67a6c6013ca | 5032 | /* Generate a secret/key using the key share entry. |
wolfSSL | 13:f67a6c6013ca | 5033 | * |
wolfSSL | 13:f67a6c6013ca | 5034 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 5035 | * kse The key share entry holding peer data. |
wolfSSL | 13:f67a6c6013ca | 5036 | */ |
wolfSSL | 13:f67a6c6013ca | 5037 | static int TLSX_KeyShare_GenKey(WOLFSSL *ssl, KeyShareEntry *kse) |
wolfSSL | 13:f67a6c6013ca | 5038 | { |
wolfSSL | 13:f67a6c6013ca | 5039 | #ifndef NO_DH |
wolfSSL | 13:f67a6c6013ca | 5040 | /* Named FFHE groups have a bit set to identify them. */ |
wolfSSL | 13:f67a6c6013ca | 5041 | if ((kse->group & NAMED_DH_MASK) == NAMED_DH_MASK) |
wolfSSL | 13:f67a6c6013ca | 5042 | return TLSX_KeyShare_GenDhKey(ssl, kse); |
wolfSSL | 13:f67a6c6013ca | 5043 | #endif |
wolfSSL | 13:f67a6c6013ca | 5044 | #ifdef HAVE_ECC |
wolfSSL | 13:f67a6c6013ca | 5045 | return TLSX_KeyShare_GenEccKey(ssl, kse); |
wolfSSL | 13:f67a6c6013ca | 5046 | #else |
wolfSSL | 13:f67a6c6013ca | 5047 | return NOT_COMPILED_IN; |
wolfSSL | 13:f67a6c6013ca | 5048 | #endif |
wolfSSL | 13:f67a6c6013ca | 5049 | } |
wolfSSL | 13:f67a6c6013ca | 5050 | |
wolfSSL | 13:f67a6c6013ca | 5051 | /* Free the key share dynamic data. |
wolfSSL | 13:f67a6c6013ca | 5052 | * |
wolfSSL | 13:f67a6c6013ca | 5053 | * list The linked list of key share entry objects. |
wolfSSL | 13:f67a6c6013ca | 5054 | * heap The heap used for allocation. |
wolfSSL | 13:f67a6c6013ca | 5055 | */ |
wolfSSL | 13:f67a6c6013ca | 5056 | static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap) |
wolfSSL | 13:f67a6c6013ca | 5057 | { |
wolfSSL | 13:f67a6c6013ca | 5058 | KeyShareEntry* current; |
wolfSSL | 13:f67a6c6013ca | 5059 | |
wolfSSL | 13:f67a6c6013ca | 5060 | while ((current = list) != NULL) { |
wolfSSL | 13:f67a6c6013ca | 5061 | list = current->next; |
wolfSSL | 13:f67a6c6013ca | 5062 | if ((current->group & NAMED_DH_MASK) == 0) { |
wolfSSL | 13:f67a6c6013ca | 5063 | #ifdef HAVE_CURVE25519 |
wolfSSL | 13:f67a6c6013ca | 5064 | if (current->group == WOLFSSL_ECC_X25519) { |
wolfSSL | 13:f67a6c6013ca | 5065 | } |
wolfSSL | 13:f67a6c6013ca | 5066 | else |
wolfSSL | 13:f67a6c6013ca | 5067 | #endif |
wolfSSL | 13:f67a6c6013ca | 5068 | wc_ecc_free((ecc_key*)(current->key)); |
wolfSSL | 13:f67a6c6013ca | 5069 | } |
wolfSSL | 13:f67a6c6013ca | 5070 | XFREE(current->key, heap, DYNAMIC_TYPE_PRIVATE_KEY); |
wolfSSL | 13:f67a6c6013ca | 5071 | XFREE(current->ke, heap, DYNAMIC_TYPE_PUBLIC_KEY); |
wolfSSL | 13:f67a6c6013ca | 5072 | XFREE(current, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 5073 | } |
wolfSSL | 13:f67a6c6013ca | 5074 | |
wolfSSL | 13:f67a6c6013ca | 5075 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 5076 | } |
wolfSSL | 13:f67a6c6013ca | 5077 | |
wolfSSL | 13:f67a6c6013ca | 5078 | /* Get the size of the encoded key share extension. |
wolfSSL | 13:f67a6c6013ca | 5079 | * |
wolfSSL | 13:f67a6c6013ca | 5080 | * list The linked list of key share extensions. |
wolfSSL | 13:f67a6c6013ca | 5081 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:f67a6c6013ca | 5082 | * returns the number of bytes of the encoded key share extension. |
wolfSSL | 13:f67a6c6013ca | 5083 | */ |
wolfSSL | 13:f67a6c6013ca | 5084 | static word16 TLSX_KeyShare_GetSize(KeyShareEntry* list, byte msgType) |
wolfSSL | 13:f67a6c6013ca | 5085 | { |
wolfSSL | 13:f67a6c6013ca | 5086 | int len = 0; |
wolfSSL | 13:f67a6c6013ca | 5087 | byte isRequest = (msgType == client_hello); |
wolfSSL | 13:f67a6c6013ca | 5088 | KeyShareEntry* current; |
wolfSSL | 13:f67a6c6013ca | 5089 | |
wolfSSL | 13:f67a6c6013ca | 5090 | /* The named group the server wants to use. */ |
wolfSSL | 13:f67a6c6013ca | 5091 | if (msgType == hello_retry_request) |
wolfSSL | 13:f67a6c6013ca | 5092 | return OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 5093 | |
wolfSSL | 13:f67a6c6013ca | 5094 | /* List of key exchange groups. */ |
wolfSSL | 13:f67a6c6013ca | 5095 | if (isRequest) |
wolfSSL | 13:f67a6c6013ca | 5096 | len += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 5097 | while ((current = list) != NULL) { |
wolfSSL | 13:f67a6c6013ca | 5098 | list = current->next; |
wolfSSL | 13:f67a6c6013ca | 5099 | |
wolfSSL | 13:f67a6c6013ca | 5100 | if (!isRequest && current->key == NULL) |
wolfSSL | 13:f67a6c6013ca | 5101 | continue; |
wolfSSL | 13:f67a6c6013ca | 5102 | |
wolfSSL | 13:f67a6c6013ca | 5103 | len += OPAQUE16_LEN + OPAQUE16_LEN + current->keLen; |
wolfSSL | 13:f67a6c6013ca | 5104 | } |
wolfSSL | 13:f67a6c6013ca | 5105 | |
wolfSSL | 13:f67a6c6013ca | 5106 | return len; |
wolfSSL | 13:f67a6c6013ca | 5107 | } |
wolfSSL | 13:f67a6c6013ca | 5108 | |
wolfSSL | 13:f67a6c6013ca | 5109 | /* Writes the key share extension into the output buffer. |
wolfSSL | 13:f67a6c6013ca | 5110 | * Assumes that the the output buffer is big enough to hold data. |
wolfSSL | 13:f67a6c6013ca | 5111 | * |
wolfSSL | 13:f67a6c6013ca | 5112 | * list The linked list of key share entries. |
wolfSSL | 13:f67a6c6013ca | 5113 | * output The buffer to write into. |
wolfSSL | 13:f67a6c6013ca | 5114 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:f67a6c6013ca | 5115 | * returns the number of bytes written into the buffer. |
wolfSSL | 13:f67a6c6013ca | 5116 | */ |
wolfSSL | 13:f67a6c6013ca | 5117 | static word16 TLSX_KeyShare_Write(KeyShareEntry* list, byte* output, |
wolfSSL | 13:f67a6c6013ca | 5118 | byte msgType) |
wolfSSL | 13:f67a6c6013ca | 5119 | { |
wolfSSL | 13:f67a6c6013ca | 5120 | word16 i = 0; |
wolfSSL | 13:f67a6c6013ca | 5121 | byte isRequest = (msgType == client_hello); |
wolfSSL | 13:f67a6c6013ca | 5122 | KeyShareEntry* current; |
wolfSSL | 13:f67a6c6013ca | 5123 | |
wolfSSL | 13:f67a6c6013ca | 5124 | if (msgType == hello_retry_request) { |
wolfSSL | 13:f67a6c6013ca | 5125 | c16toa(list->group, output); |
wolfSSL | 13:f67a6c6013ca | 5126 | return OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 5127 | } |
wolfSSL | 13:f67a6c6013ca | 5128 | |
wolfSSL | 13:f67a6c6013ca | 5129 | /* ClientHello has a list but ServerHello is only the chosen. */ |
wolfSSL | 13:f67a6c6013ca | 5130 | if (isRequest) |
wolfSSL | 13:f67a6c6013ca | 5131 | i += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 5132 | |
wolfSSL | 13:f67a6c6013ca | 5133 | /* Write out all in the list. */ |
wolfSSL | 13:f67a6c6013ca | 5134 | while ((current = list) != NULL) { |
wolfSSL | 13:f67a6c6013ca | 5135 | list = current->next; |
wolfSSL | 13:f67a6c6013ca | 5136 | |
wolfSSL | 13:f67a6c6013ca | 5137 | if (!isRequest && current->key == NULL) |
wolfSSL | 13:f67a6c6013ca | 5138 | continue; |
wolfSSL | 13:f67a6c6013ca | 5139 | |
wolfSSL | 13:f67a6c6013ca | 5140 | c16toa(current->group, &output[i]); |
wolfSSL | 13:f67a6c6013ca | 5141 | i += KE_GROUP_LEN; |
wolfSSL | 13:f67a6c6013ca | 5142 | c16toa(current->keLen, &output[i]); |
wolfSSL | 13:f67a6c6013ca | 5143 | i += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 5144 | XMEMCPY(&output[i], current->ke, current->keLen); |
wolfSSL | 13:f67a6c6013ca | 5145 | i += current->keLen; |
wolfSSL | 13:f67a6c6013ca | 5146 | } |
wolfSSL | 13:f67a6c6013ca | 5147 | /* Write the length of the list if required. */ |
wolfSSL | 13:f67a6c6013ca | 5148 | if (isRequest) |
wolfSSL | 13:f67a6c6013ca | 5149 | c16toa(i - OPAQUE16_LEN, output); |
wolfSSL | 13:f67a6c6013ca | 5150 | |
wolfSSL | 13:f67a6c6013ca | 5151 | return i; |
wolfSSL | 13:f67a6c6013ca | 5152 | } |
wolfSSL | 13:f67a6c6013ca | 5153 | |
wolfSSL | 13:f67a6c6013ca | 5154 | /* Process the DH key share extension on the client side. |
wolfSSL | 13:f67a6c6013ca | 5155 | * |
wolfSSL | 13:f67a6c6013ca | 5156 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 5157 | * keyShareEntry The key share entry object to use to calculate shared secret. |
wolfSSL | 13:f67a6c6013ca | 5158 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 5159 | */ |
wolfSSL | 13:f67a6c6013ca | 5160 | static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) |
wolfSSL | 13:f67a6c6013ca | 5161 | { |
wolfSSL | 13:f67a6c6013ca | 5162 | #ifndef NO_DH |
wolfSSL | 13:f67a6c6013ca | 5163 | int ret; |
wolfSSL | 13:f67a6c6013ca | 5164 | const DhParams* params; |
wolfSSL | 13:f67a6c6013ca | 5165 | word16 i; |
wolfSSL | 13:f67a6c6013ca | 5166 | byte b; |
wolfSSL | 13:f67a6c6013ca | 5167 | DhKey dhKey; |
wolfSSL | 13:f67a6c6013ca | 5168 | |
wolfSSL | 13:f67a6c6013ca | 5169 | switch (keyShareEntry->group) { |
wolfSSL | 13:f67a6c6013ca | 5170 | #ifdef HAVE_FFDHE_2048 |
wolfSSL | 13:f67a6c6013ca | 5171 | case WOLFSSL_FFDHE_2048: |
wolfSSL | 13:f67a6c6013ca | 5172 | params = wc_Dh_ffdhe2048_Get(); |
wolfSSL | 13:f67a6c6013ca | 5173 | break; |
wolfSSL | 13:f67a6c6013ca | 5174 | #endif |
wolfSSL | 13:f67a6c6013ca | 5175 | #ifdef HAVE_FFDHE_3072 |
wolfSSL | 13:f67a6c6013ca | 5176 | case WOLFSSL_FFDHE_3072: |
wolfSSL | 13:f67a6c6013ca | 5177 | params = wc_Dh_ffdhe3072_Get(); |
wolfSSL | 13:f67a6c6013ca | 5178 | break; |
wolfSSL | 13:f67a6c6013ca | 5179 | #endif |
wolfSSL | 13:f67a6c6013ca | 5180 | #ifdef HAVE_FFDHE_4096 |
wolfSSL | 13:f67a6c6013ca | 5181 | case WOLFSSL_FFDHE_4096: |
wolfSSL | 13:f67a6c6013ca | 5182 | params = wc_Dh_ffdhe4096_Get(); |
wolfSSL | 13:f67a6c6013ca | 5183 | break; |
wolfSSL | 13:f67a6c6013ca | 5184 | #endif |
wolfSSL | 13:f67a6c6013ca | 5185 | #ifdef HAVE_FFDHE_6144 |
wolfSSL | 13:f67a6c6013ca | 5186 | case WOLFSSL_FFDHE_6144: |
wolfSSL | 13:f67a6c6013ca | 5187 | params = wc_Dh_ffdhe6144_Get(); |
wolfSSL | 13:f67a6c6013ca | 5188 | break; |
wolfSSL | 13:f67a6c6013ca | 5189 | #endif |
wolfSSL | 13:f67a6c6013ca | 5190 | #ifdef HAVE_FFDHE_8192 |
wolfSSL | 13:f67a6c6013ca | 5191 | case WOLFSSL_FFDHE_8192: |
wolfSSL | 13:f67a6c6013ca | 5192 | params = wc_Dh_ffdhe8192_Get(); |
wolfSSL | 13:f67a6c6013ca | 5193 | break; |
wolfSSL | 13:f67a6c6013ca | 5194 | #endif |
wolfSSL | 13:f67a6c6013ca | 5195 | default: |
wolfSSL | 13:f67a6c6013ca | 5196 | return PEER_KEY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5197 | } |
wolfSSL | 13:f67a6c6013ca | 5198 | |
wolfSSL | 13:f67a6c6013ca | 5199 | #ifdef WOLFSSL_DEBUG_TLS |
wolfSSL | 13:f67a6c6013ca | 5200 | WOLFSSL_MSG("Peer DH Key"); |
wolfSSL | 13:f67a6c6013ca | 5201 | WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen); |
wolfSSL | 13:f67a6c6013ca | 5202 | #endif |
wolfSSL | 13:f67a6c6013ca | 5203 | |
wolfSSL | 13:f67a6c6013ca | 5204 | if (params->p_len != keyShareEntry->keLen) |
wolfSSL | 13:f67a6c6013ca | 5205 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5206 | ssl->options.dhKeySz = params->p_len; |
wolfSSL | 13:f67a6c6013ca | 5207 | |
wolfSSL | 13:f67a6c6013ca | 5208 | /* TODO: [TLS13] move this check down into wolfcrypt. */ |
wolfSSL | 13:f67a6c6013ca | 5209 | /* Check that public DH key is not 0 or 1. */ |
wolfSSL | 13:f67a6c6013ca | 5210 | b = 0; |
wolfSSL | 13:f67a6c6013ca | 5211 | for (i = 0; i < params->p_len - 1; i++) |
wolfSSL | 13:f67a6c6013ca | 5212 | b |= keyShareEntry->ke[i]; |
wolfSSL | 13:f67a6c6013ca | 5213 | if (b == 0 && (keyShareEntry->ke[i] == 0x00 || |
wolfSSL | 13:f67a6c6013ca | 5214 | keyShareEntry->ke[i] == 0x01)) { |
wolfSSL | 13:f67a6c6013ca | 5215 | return PEER_KEY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5216 | } |
wolfSSL | 13:f67a6c6013ca | 5217 | /* Check that public DH key is not mod, mod + 1 or mod - 1. */ |
wolfSSL | 13:f67a6c6013ca | 5218 | b = 0; |
wolfSSL | 13:f67a6c6013ca | 5219 | for (i = 0; i < params->p_len - 1; i++) |
wolfSSL | 13:f67a6c6013ca | 5220 | b |= params->p[i] ^ keyShareEntry->ke[i]; |
wolfSSL | 13:f67a6c6013ca | 5221 | if (b == 0 && (params->p[i] == keyShareEntry->ke[i] || |
wolfSSL | 13:f67a6c6013ca | 5222 | params->p[i] - 1 == keyShareEntry->ke[i] || |
wolfSSL | 13:f67a6c6013ca | 5223 | params->p[i] + 1 == keyShareEntry->ke[i])) { |
wolfSSL | 13:f67a6c6013ca | 5224 | return PEER_KEY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5225 | } |
wolfSSL | 13:f67a6c6013ca | 5226 | |
wolfSSL | 13:f67a6c6013ca | 5227 | ret = wc_InitDhKey_ex(&dhKey, ssl->heap, ssl->devId); |
wolfSSL | 13:f67a6c6013ca | 5228 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 5229 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5230 | |
wolfSSL | 13:f67a6c6013ca | 5231 | /* Set key */ |
wolfSSL | 13:f67a6c6013ca | 5232 | ret = wc_DhSetKey(&dhKey, |
wolfSSL | 13:f67a6c6013ca | 5233 | (byte*)params->p, params->p_len, |
wolfSSL | 13:f67a6c6013ca | 5234 | (byte*)params->g, params->g_len); |
wolfSSL | 13:f67a6c6013ca | 5235 | if (ret != 0) { |
wolfSSL | 13:f67a6c6013ca | 5236 | wc_FreeDhKey(&dhKey); |
wolfSSL | 13:f67a6c6013ca | 5237 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5238 | } |
wolfSSL | 13:f67a6c6013ca | 5239 | |
wolfSSL | 13:f67a6c6013ca | 5240 | /* Derive secret from private key and peer's public key. */ |
wolfSSL | 13:f67a6c6013ca | 5241 | ret = wc_DhAgree(&dhKey, |
wolfSSL | 13:f67a6c6013ca | 5242 | ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, |
wolfSSL | 13:f67a6c6013ca | 5243 | (const byte*)keyShareEntry->key, keyShareEntry->keyLen, |
wolfSSL | 13:f67a6c6013ca | 5244 | keyShareEntry->ke, keyShareEntry->keLen); |
wolfSSL | 13:f67a6c6013ca | 5245 | #ifdef WOLFSSL_ASYNC_CRYPT |
wolfSSL | 13:f67a6c6013ca | 5246 | /* TODO: Make this function non-blocking */ |
wolfSSL | 13:f67a6c6013ca | 5247 | if (ret == WC_PENDING_E) { |
wolfSSL | 13:f67a6c6013ca | 5248 | ret = wc_AsyncWait(ret, &dhKey.asyncDev, WC_ASYNC_FLAG_NONE); |
wolfSSL | 13:f67a6c6013ca | 5249 | } |
wolfSSL | 13:f67a6c6013ca | 5250 | #endif |
wolfSSL | 13:f67a6c6013ca | 5251 | |
wolfSSL | 13:f67a6c6013ca | 5252 | wc_FreeDhKey(&dhKey); |
wolfSSL | 13:f67a6c6013ca | 5253 | |
wolfSSL | 13:f67a6c6013ca | 5254 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5255 | #else |
wolfSSL | 13:f67a6c6013ca | 5256 | (void)ssl; |
wolfSSL | 13:f67a6c6013ca | 5257 | (void)keyShareEntry; |
wolfSSL | 13:f67a6c6013ca | 5258 | return PEER_KEY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5259 | #endif |
wolfSSL | 13:f67a6c6013ca | 5260 | } |
wolfSSL | 13:f67a6c6013ca | 5261 | |
wolfSSL | 13:f67a6c6013ca | 5262 | /* Process the ECC key share extension on the client side. |
wolfSSL | 13:f67a6c6013ca | 5263 | * |
wolfSSL | 13:f67a6c6013ca | 5264 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 5265 | * keyShareEntry The key share entry object to use to calculate shared secret. |
wolfSSL | 13:f67a6c6013ca | 5266 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 5267 | */ |
wolfSSL | 13:f67a6c6013ca | 5268 | static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) |
wolfSSL | 13:f67a6c6013ca | 5269 | { |
wolfSSL | 13:f67a6c6013ca | 5270 | int ret; |
wolfSSL | 13:f67a6c6013ca | 5271 | |
wolfSSL | 13:f67a6c6013ca | 5272 | #ifdef HAVE_ECC |
wolfSSL | 13:f67a6c6013ca | 5273 | int curveId; |
wolfSSL | 13:f67a6c6013ca | 5274 | ecc_key* keyShareKey = (ecc_key*)keyShareEntry->key; |
wolfSSL | 13:f67a6c6013ca | 5275 | |
wolfSSL | 13:f67a6c6013ca | 5276 | if (ssl->peerEccKey != NULL) |
wolfSSL | 13:f67a6c6013ca | 5277 | wc_ecc_free(ssl->peerEccKey); |
wolfSSL | 13:f67a6c6013ca | 5278 | |
wolfSSL | 13:f67a6c6013ca | 5279 | ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->heap, |
wolfSSL | 13:f67a6c6013ca | 5280 | DYNAMIC_TYPE_ECC); |
wolfSSL | 13:f67a6c6013ca | 5281 | if (ssl->peerEccKey == NULL) { |
wolfSSL | 13:f67a6c6013ca | 5282 | WOLFSSL_MSG("PeerEccKey Memory error"); |
wolfSSL | 13:f67a6c6013ca | 5283 | return MEMORY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5284 | } |
wolfSSL | 13:f67a6c6013ca | 5285 | ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, ssl->devId); |
wolfSSL | 13:f67a6c6013ca | 5286 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 5287 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5288 | |
wolfSSL | 13:f67a6c6013ca | 5289 | /* find supported curve */ |
wolfSSL | 13:f67a6c6013ca | 5290 | switch (keyShareEntry->group) { |
wolfSSL | 13:f67a6c6013ca | 5291 | #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 5292 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 5293 | case WOLFSSL_ECC_SECP256R1: |
wolfSSL | 13:f67a6c6013ca | 5294 | curveId = ECC_SECP256R1; |
wolfSSL | 13:f67a6c6013ca | 5295 | break; |
wolfSSL | 13:f67a6c6013ca | 5296 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:f67a6c6013ca | 5297 | #endif |
wolfSSL | 13:f67a6c6013ca | 5298 | #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 5299 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 5300 | case WOLFSSL_ECC_SECP384R1: |
wolfSSL | 13:f67a6c6013ca | 5301 | curveId = ECC_SECP384R1; |
wolfSSL | 13:f67a6c6013ca | 5302 | break; |
wolfSSL | 13:f67a6c6013ca | 5303 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:f67a6c6013ca | 5304 | #endif |
wolfSSL | 13:f67a6c6013ca | 5305 | #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 5306 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 5307 | case WOLFSSL_ECC_SECP521R1: |
wolfSSL | 13:f67a6c6013ca | 5308 | curveId = ECC_SECP521R1; |
wolfSSL | 13:f67a6c6013ca | 5309 | break; |
wolfSSL | 13:f67a6c6013ca | 5310 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:f67a6c6013ca | 5311 | #endif |
wolfSSL | 13:f67a6c6013ca | 5312 | #ifdef HAVE_CURVE25519 |
wolfSSL | 13:f67a6c6013ca | 5313 | case WOLFSSL_ECC_X25519: |
wolfSSL | 13:f67a6c6013ca | 5314 | { |
wolfSSL | 13:f67a6c6013ca | 5315 | curve25519_key* key = (curve25519_key*)keyShareEntry->key; |
wolfSSL | 13:f67a6c6013ca | 5316 | curve25519_key* peerEccKey; |
wolfSSL | 13:f67a6c6013ca | 5317 | |
wolfSSL | 13:f67a6c6013ca | 5318 | if (ssl->peerEccKey != NULL) |
wolfSSL | 13:f67a6c6013ca | 5319 | wc_ecc_free(ssl->peerEccKey); |
wolfSSL | 13:f67a6c6013ca | 5320 | |
wolfSSL | 13:f67a6c6013ca | 5321 | peerEccKey = (curve25519_key*)XMALLOC(sizeof(curve25519_key), |
wolfSSL | 13:f67a6c6013ca | 5322 | ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 5323 | if (peerEccKey == NULL) { |
wolfSSL | 13:f67a6c6013ca | 5324 | WOLFSSL_MSG("PeerEccKey Memory error"); |
wolfSSL | 13:f67a6c6013ca | 5325 | return MEMORY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5326 | } |
wolfSSL | 13:f67a6c6013ca | 5327 | ret = wc_curve25519_init(peerEccKey); |
wolfSSL | 13:f67a6c6013ca | 5328 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 5329 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5330 | #ifdef WOLFSSL_DEBUG_TLS |
wolfSSL | 13:f67a6c6013ca | 5331 | WOLFSSL_MSG("Peer Curve25519 Key"); |
wolfSSL | 13:f67a6c6013ca | 5332 | WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen); |
wolfSSL | 13:f67a6c6013ca | 5333 | #endif |
wolfSSL | 13:f67a6c6013ca | 5334 | |
wolfSSL | 13:f67a6c6013ca | 5335 | /* Point is validated by import function. */ |
wolfSSL | 13:f67a6c6013ca | 5336 | if (wc_curve25519_import_public_ex(keyShareEntry->ke, |
wolfSSL | 13:f67a6c6013ca | 5337 | keyShareEntry->keLen, peerEccKey, |
wolfSSL | 13:f67a6c6013ca | 5338 | EC25519_LITTLE_ENDIAN) != 0) { |
wolfSSL | 13:f67a6c6013ca | 5339 | return ECC_PEERKEY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5340 | } |
wolfSSL | 13:f67a6c6013ca | 5341 | |
wolfSSL | 13:f67a6c6013ca | 5342 | ssl->arrays->preMasterSz = ENCRYPT_LEN; |
wolfSSL | 13:f67a6c6013ca | 5343 | ret = wc_curve25519_shared_secret_ex(key, peerEccKey, |
wolfSSL | 13:f67a6c6013ca | 5344 | ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, |
wolfSSL | 13:f67a6c6013ca | 5345 | EC25519_LITTLE_ENDIAN); |
wolfSSL | 13:f67a6c6013ca | 5346 | wc_curve25519_free(peerEccKey); |
wolfSSL | 13:f67a6c6013ca | 5347 | XFREE(peerEccKey, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 5348 | ssl->ecdhCurveOID = ECC_X25519_OID; |
wolfSSL | 13:f67a6c6013ca | 5349 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5350 | } |
wolfSSL | 13:f67a6c6013ca | 5351 | #endif |
wolfSSL | 13:f67a6c6013ca | 5352 | #ifdef HAVE_X448 |
wolfSSL | 13:f67a6c6013ca | 5353 | case WOLFSSL_ECC_X448: |
wolfSSL | 13:f67a6c6013ca | 5354 | curveId = ECC_X448; |
wolfSSL | 13:f67a6c6013ca | 5355 | break; |
wolfSSL | 13:f67a6c6013ca | 5356 | #endif |
wolfSSL | 13:f67a6c6013ca | 5357 | default: |
wolfSSL | 13:f67a6c6013ca | 5358 | /* unsupported curve */ |
wolfSSL | 13:f67a6c6013ca | 5359 | return ECC_PEERKEY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5360 | } |
wolfSSL | 13:f67a6c6013ca | 5361 | |
wolfSSL | 13:f67a6c6013ca | 5362 | #ifdef WOLFSSL_DEBUG_TLS |
wolfSSL | 13:f67a6c6013ca | 5363 | WOLFSSL_MSG("Peer ECC Key"); |
wolfSSL | 13:f67a6c6013ca | 5364 | WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen); |
wolfSSL | 13:f67a6c6013ca | 5365 | #endif |
wolfSSL | 13:f67a6c6013ca | 5366 | |
wolfSSL | 13:f67a6c6013ca | 5367 | /* Point is validated by import function. */ |
wolfSSL | 13:f67a6c6013ca | 5368 | if (wc_ecc_import_x963_ex(keyShareEntry->ke, keyShareEntry->keLen, |
wolfSSL | 13:f67a6c6013ca | 5369 | ssl->peerEccKey, curveId) != 0) { |
wolfSSL | 13:f67a6c6013ca | 5370 | return ECC_PEERKEY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5371 | } |
wolfSSL | 13:f67a6c6013ca | 5372 | ssl->ecdhCurveOID = ssl->peerEccKey->dp->oidSum; |
wolfSSL | 13:f67a6c6013ca | 5373 | |
wolfSSL | 13:f67a6c6013ca | 5374 | ssl->arrays->preMasterSz = ENCRYPT_LEN; |
wolfSSL | 13:f67a6c6013ca | 5375 | do { |
wolfSSL | 13:f67a6c6013ca | 5376 | #if defined(WOLFSSL_ASYNC_CRYPT) |
wolfSSL | 13:f67a6c6013ca | 5377 | ret = wc_AsyncWait(ret, &keyShareKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); |
wolfSSL | 13:f67a6c6013ca | 5378 | #endif |
wolfSSL | 13:f67a6c6013ca | 5379 | if (ret >= 0) |
wolfSSL | 13:f67a6c6013ca | 5380 | ret = wc_ecc_shared_secret(keyShareKey, ssl->peerEccKey, |
wolfSSL | 13:f67a6c6013ca | 5381 | ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz); |
wolfSSL | 13:f67a6c6013ca | 5382 | } while (ret == WC_PENDING_E); |
wolfSSL | 13:f67a6c6013ca | 5383 | |
wolfSSL | 13:f67a6c6013ca | 5384 | #if 0 |
wolfSSL | 13:f67a6c6013ca | 5385 | /* TODO: Switch to support async here and use: */ |
wolfSSL | 13:f67a6c6013ca | 5386 | ret = EccSharedSecret(ssl, keyShareEntry->key, ssl->peerEccKey, |
wolfSSL | 13:f67a6c6013ca | 5387 | keyShareEntry->ke, &keyShareEntry->keLen, |
wolfSSL | 13:f67a6c6013ca | 5388 | ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, |
wolfSSL | 13:f67a6c6013ca | 5389 | ssl->options.side, |
wolfSSL | 13:f67a6c6013ca | 5390 | #ifdef HAVE_PK_CALLBACKS |
wolfSSL | 13:f67a6c6013ca | 5391 | ssl->EccSharedSecretCtx |
wolfSSL | 13:f67a6c6013ca | 5392 | #else |
wolfSSL | 13:f67a6c6013ca | 5393 | NULL |
wolfSSL | 13:f67a6c6013ca | 5394 | #endif |
wolfSSL | 13:f67a6c6013ca | 5395 | ); |
wolfSSL | 13:f67a6c6013ca | 5396 | #endif |
wolfSSL | 13:f67a6c6013ca | 5397 | |
wolfSSL | 13:f67a6c6013ca | 5398 | |
wolfSSL | 13:f67a6c6013ca | 5399 | #else |
wolfSSL | 13:f67a6c6013ca | 5400 | (void)ssl; |
wolfSSL | 13:f67a6c6013ca | 5401 | (void)keyShareEntry; |
wolfSSL | 13:f67a6c6013ca | 5402 | |
wolfSSL | 13:f67a6c6013ca | 5403 | ret = PEER_KEY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5404 | #endif /* HAVE_ECC */ |
wolfSSL | 13:f67a6c6013ca | 5405 | |
wolfSSL | 13:f67a6c6013ca | 5406 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5407 | } |
wolfSSL | 13:f67a6c6013ca | 5408 | |
wolfSSL | 13:f67a6c6013ca | 5409 | /* Process the key share extension on the client side. |
wolfSSL | 13:f67a6c6013ca | 5410 | * |
wolfSSL | 13:f67a6c6013ca | 5411 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 5412 | * keyShareEntry The key share entry object to use to calculate shared secret. |
wolfSSL | 13:f67a6c6013ca | 5413 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 5414 | */ |
wolfSSL | 13:f67a6c6013ca | 5415 | static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) |
wolfSSL | 13:f67a6c6013ca | 5416 | { |
wolfSSL | 13:f67a6c6013ca | 5417 | int ret; |
wolfSSL | 13:f67a6c6013ca | 5418 | |
wolfSSL | 13:f67a6c6013ca | 5419 | #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) |
wolfSSL | 13:f67a6c6013ca | 5420 | ssl->session.namedGroup = keyShareEntry->group; |
wolfSSL | 13:f67a6c6013ca | 5421 | #endif |
wolfSSL | 13:f67a6c6013ca | 5422 | /* Use Key Share Data from server. */ |
wolfSSL | 13:f67a6c6013ca | 5423 | if (keyShareEntry->group & NAMED_DH_MASK) |
wolfSSL | 13:f67a6c6013ca | 5424 | ret = TLSX_KeyShare_ProcessDh(ssl, keyShareEntry); |
wolfSSL | 13:f67a6c6013ca | 5425 | else |
wolfSSL | 13:f67a6c6013ca | 5426 | ret = TLSX_KeyShare_ProcessEcc(ssl, keyShareEntry); |
wolfSSL | 13:f67a6c6013ca | 5427 | |
wolfSSL | 13:f67a6c6013ca | 5428 | #ifdef WOLFSSL_DEBUG_TLS |
wolfSSL | 13:f67a6c6013ca | 5429 | WOLFSSL_MSG("KE Secret"); |
wolfSSL | 13:f67a6c6013ca | 5430 | WOLFSSL_BUFFER(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz); |
wolfSSL | 13:f67a6c6013ca | 5431 | #endif |
wolfSSL | 13:f67a6c6013ca | 5432 | |
wolfSSL | 13:f67a6c6013ca | 5433 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5434 | } |
wolfSSL | 13:f67a6c6013ca | 5435 | |
wolfSSL | 13:f67a6c6013ca | 5436 | /* Parse an entry of the KeyShare extension. |
wolfSSL | 13:f67a6c6013ca | 5437 | * |
wolfSSL | 13:f67a6c6013ca | 5438 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 5439 | * input The extension data. |
wolfSSL | 13:f67a6c6013ca | 5440 | * length The length of the extension data. |
wolfSSL | 13:f67a6c6013ca | 5441 | * kse The new key share entry object. |
wolfSSL | 13:f67a6c6013ca | 5442 | * returns a positive number to indicate amount of data parsed and a negative |
wolfSSL | 13:f67a6c6013ca | 5443 | * number on error. |
wolfSSL | 13:f67a6c6013ca | 5444 | */ |
wolfSSL | 13:f67a6c6013ca | 5445 | static int TLSX_KeyShareEntry_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 5446 | KeyShareEntry **kse) |
wolfSSL | 13:f67a6c6013ca | 5447 | { |
wolfSSL | 13:f67a6c6013ca | 5448 | int ret; |
wolfSSL | 13:f67a6c6013ca | 5449 | word16 group; |
wolfSSL | 13:f67a6c6013ca | 5450 | word16 keLen; |
wolfSSL | 13:f67a6c6013ca | 5451 | int offset = 0; |
wolfSSL | 13:f67a6c6013ca | 5452 | byte* ke; |
wolfSSL | 13:f67a6c6013ca | 5453 | |
wolfSSL | 13:f67a6c6013ca | 5454 | if (length < OPAQUE16_LEN + OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 5455 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5456 | /* Named group */ |
wolfSSL | 13:f67a6c6013ca | 5457 | ato16(&input[offset], &group); |
wolfSSL | 13:f67a6c6013ca | 5458 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 5459 | /* Key exchange data - public key. */ |
wolfSSL | 13:f67a6c6013ca | 5460 | ato16(&input[offset], &keLen); |
wolfSSL | 13:f67a6c6013ca | 5461 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 5462 | if (keLen < 1 || keLen > length - offset) |
wolfSSL | 13:f67a6c6013ca | 5463 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5464 | |
wolfSSL | 13:f67a6c6013ca | 5465 | /* Store a copy in the key share object. */ |
wolfSSL | 13:f67a6c6013ca | 5466 | ke = (byte*)XMALLOC(keLen, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); |
wolfSSL | 13:f67a6c6013ca | 5467 | if (ke == NULL) |
wolfSSL | 13:f67a6c6013ca | 5468 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 5469 | XMEMCPY(ke, &input[offset], keLen); |
wolfSSL | 13:f67a6c6013ca | 5470 | |
wolfSSL | 13:f67a6c6013ca | 5471 | /* Populate a key share object in the extension. */ |
wolfSSL | 13:f67a6c6013ca | 5472 | ret = TLSX_KeyShare_Use(ssl, group, keLen, ke, kse); |
wolfSSL | 13:f67a6c6013ca | 5473 | if (ret != 0) { |
wolfSSL | 13:f67a6c6013ca | 5474 | XFREE(ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); |
wolfSSL | 13:f67a6c6013ca | 5475 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5476 | } |
wolfSSL | 13:f67a6c6013ca | 5477 | |
wolfSSL | 13:f67a6c6013ca | 5478 | /* Total length of the parsed data. */ |
wolfSSL | 13:f67a6c6013ca | 5479 | return offset + keLen; |
wolfSSL | 13:f67a6c6013ca | 5480 | } |
wolfSSL | 13:f67a6c6013ca | 5481 | |
wolfSSL | 13:f67a6c6013ca | 5482 | /* Searches the groups sent for the specified named group. |
wolfSSL | 13:f67a6c6013ca | 5483 | * |
wolfSSL | 13:f67a6c6013ca | 5484 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 5485 | * name The group name to match. |
wolfSSL | 13:f67a6c6013ca | 5486 | * returns 1 when the extension has the group name and 0 otherwise. |
wolfSSL | 13:f67a6c6013ca | 5487 | */ |
wolfSSL | 13:f67a6c6013ca | 5488 | static int TLSX_KeyShare_Find(WOLFSSL* ssl, word16 group) |
wolfSSL | 13:f67a6c6013ca | 5489 | { |
wolfSSL | 13:f67a6c6013ca | 5490 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 5491 | KeyShareEntry* list; |
wolfSSL | 13:f67a6c6013ca | 5492 | |
wolfSSL | 13:f67a6c6013ca | 5493 | extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); |
wolfSSL | 13:f67a6c6013ca | 5494 | if (extension == NULL) |
wolfSSL | 13:f67a6c6013ca | 5495 | return 0; |
wolfSSL | 13:f67a6c6013ca | 5496 | |
wolfSSL | 13:f67a6c6013ca | 5497 | list = (KeyShareEntry*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 5498 | while (list != NULL) { |
wolfSSL | 13:f67a6c6013ca | 5499 | if (list->group == group) { |
wolfSSL | 13:f67a6c6013ca | 5500 | return 1; |
wolfSSL | 13:f67a6c6013ca | 5501 | } |
wolfSSL | 13:f67a6c6013ca | 5502 | list = list->next; |
wolfSSL | 13:f67a6c6013ca | 5503 | } |
wolfSSL | 13:f67a6c6013ca | 5504 | |
wolfSSL | 13:f67a6c6013ca | 5505 | return 0; |
wolfSSL | 13:f67a6c6013ca | 5506 | } |
wolfSSL | 13:f67a6c6013ca | 5507 | |
wolfSSL | 13:f67a6c6013ca | 5508 | |
wolfSSL | 13:f67a6c6013ca | 5509 | /* Searches the supported groups extension for the specified named group. |
wolfSSL | 13:f67a6c6013ca | 5510 | * |
wolfSSL | 13:f67a6c6013ca | 5511 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 5512 | * name The group name to match. |
wolfSSL | 13:f67a6c6013ca | 5513 | * returns 1 when the extension has the group name and 0 otherwise. |
wolfSSL | 13:f67a6c6013ca | 5514 | */ |
wolfSSL | 13:f67a6c6013ca | 5515 | static int TLSX_SupportedGroups_Find(WOLFSSL* ssl, word16 name) |
wolfSSL | 13:f67a6c6013ca | 5516 | { |
wolfSSL | 13:f67a6c6013ca | 5517 | #ifdef HAVE_SUPPORTED_CURVES |
wolfSSL | 13:f67a6c6013ca | 5518 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 5519 | EllipticCurve* curve = NULL; |
wolfSSL | 13:f67a6c6013ca | 5520 | |
wolfSSL | 13:f67a6c6013ca | 5521 | if ((extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS)) == NULL) |
wolfSSL | 13:f67a6c6013ca | 5522 | return 0; |
wolfSSL | 13:f67a6c6013ca | 5523 | |
wolfSSL | 13:f67a6c6013ca | 5524 | for (curve = (EllipticCurve*)extension->data; curve; curve = curve->next) { |
wolfSSL | 13:f67a6c6013ca | 5525 | if (curve->name == name) |
wolfSSL | 13:f67a6c6013ca | 5526 | return 1; |
wolfSSL | 13:f67a6c6013ca | 5527 | } |
wolfSSL | 13:f67a6c6013ca | 5528 | #endif |
wolfSSL | 13:f67a6c6013ca | 5529 | |
wolfSSL | 13:f67a6c6013ca | 5530 | (void)ssl; |
wolfSSL | 13:f67a6c6013ca | 5531 | (void)name; |
wolfSSL | 13:f67a6c6013ca | 5532 | |
wolfSSL | 13:f67a6c6013ca | 5533 | return 0; |
wolfSSL | 13:f67a6c6013ca | 5534 | } |
wolfSSL | 13:f67a6c6013ca | 5535 | |
wolfSSL | 13:f67a6c6013ca | 5536 | |
wolfSSL | 13:f67a6c6013ca | 5537 | /* Parse the KeyShare extension. |
wolfSSL | 13:f67a6c6013ca | 5538 | * Different formats in different messages. |
wolfSSL | 13:f67a6c6013ca | 5539 | * |
wolfSSL | 13:f67a6c6013ca | 5540 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 5541 | * input The extension data. |
wolfSSL | 13:f67a6c6013ca | 5542 | * length The length of the extension data. |
wolfSSL | 13:f67a6c6013ca | 5543 | * msgType The type of the message this extension is being parsed from. |
wolfSSL | 13:f67a6c6013ca | 5544 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 5545 | */ |
wolfSSL | 13:f67a6c6013ca | 5546 | static int TLSX_KeyShare_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 5547 | byte msgType) |
wolfSSL | 13:f67a6c6013ca | 5548 | { |
wolfSSL | 13:f67a6c6013ca | 5549 | int ret; |
wolfSSL | 13:f67a6c6013ca | 5550 | KeyShareEntry *keyShareEntry; |
wolfSSL | 13:f67a6c6013ca | 5551 | |
wolfSSL | 13:f67a6c6013ca | 5552 | if (msgType == client_hello) { |
wolfSSL | 13:f67a6c6013ca | 5553 | int offset = 0; |
wolfSSL | 13:f67a6c6013ca | 5554 | word16 len; |
wolfSSL | 13:f67a6c6013ca | 5555 | |
wolfSSL | 13:f67a6c6013ca | 5556 | if (length < OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 5557 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5558 | |
wolfSSL | 13:f67a6c6013ca | 5559 | /* ClientHello contains zero or more key share entries. */ |
wolfSSL | 13:f67a6c6013ca | 5560 | ato16(input, &len); |
wolfSSL | 13:f67a6c6013ca | 5561 | if (len != length - OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 5562 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5563 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 5564 | |
wolfSSL | 13:f67a6c6013ca | 5565 | while (offset < length) { |
wolfSSL | 13:f67a6c6013ca | 5566 | ret = TLSX_KeyShareEntry_Parse(ssl, &input[offset], length, |
wolfSSL | 13:f67a6c6013ca | 5567 | &keyShareEntry); |
wolfSSL | 13:f67a6c6013ca | 5568 | if (ret < 0) |
wolfSSL | 13:f67a6c6013ca | 5569 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5570 | |
wolfSSL | 13:f67a6c6013ca | 5571 | offset += ret; |
wolfSSL | 13:f67a6c6013ca | 5572 | } |
wolfSSL | 13:f67a6c6013ca | 5573 | |
wolfSSL | 13:f67a6c6013ca | 5574 | ret = 0; |
wolfSSL | 13:f67a6c6013ca | 5575 | } |
wolfSSL | 13:f67a6c6013ca | 5576 | else if (msgType == server_hello) { |
wolfSSL | 13:f67a6c6013ca | 5577 | int len; |
wolfSSL | 13:f67a6c6013ca | 5578 | |
wolfSSL | 13:f67a6c6013ca | 5579 | /* ServerHello contains one key share entry. */ |
wolfSSL | 13:f67a6c6013ca | 5580 | len = TLSX_KeyShareEntry_Parse(ssl, input, length, &keyShareEntry); |
wolfSSL | 13:f67a6c6013ca | 5581 | if (len != length) |
wolfSSL | 13:f67a6c6013ca | 5582 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5583 | |
wolfSSL | 13:f67a6c6013ca | 5584 | /* Not in list sent if there isn't a private key. */ |
wolfSSL | 13:f67a6c6013ca | 5585 | if (keyShareEntry->key == NULL) |
wolfSSL | 13:f67a6c6013ca | 5586 | return BAD_KEY_SHARE_DATA; |
wolfSSL | 13:f67a6c6013ca | 5587 | |
wolfSSL | 13:f67a6c6013ca | 5588 | /* Process the entry to calculate the secret. */ |
wolfSSL | 13:f67a6c6013ca | 5589 | ret = TLSX_KeyShare_Process(ssl, keyShareEntry); |
wolfSSL | 13:f67a6c6013ca | 5590 | } |
wolfSSL | 13:f67a6c6013ca | 5591 | else if (msgType == hello_retry_request) { |
wolfSSL | 13:f67a6c6013ca | 5592 | word16 group; |
wolfSSL | 13:f67a6c6013ca | 5593 | |
wolfSSL | 13:f67a6c6013ca | 5594 | if (length != OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 5595 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5596 | |
wolfSSL | 13:f67a6c6013ca | 5597 | /* The data is the named group the server wants to use. */ |
wolfSSL | 13:f67a6c6013ca | 5598 | ato16(input, &group); |
wolfSSL | 13:f67a6c6013ca | 5599 | |
wolfSSL | 13:f67a6c6013ca | 5600 | /* Check the selected group was supported by ClientHello extensions. */ |
wolfSSL | 13:f67a6c6013ca | 5601 | if (!TLSX_SupportedGroups_Find(ssl, group)) |
wolfSSL | 13:f67a6c6013ca | 5602 | return BAD_KEY_SHARE_DATA; |
wolfSSL | 13:f67a6c6013ca | 5603 | |
wolfSSL | 13:f67a6c6013ca | 5604 | /* Check if the group was sent. */ |
wolfSSL | 13:f67a6c6013ca | 5605 | if (TLSX_KeyShare_Find(ssl, group)) |
wolfSSL | 13:f67a6c6013ca | 5606 | return BAD_KEY_SHARE_DATA; |
wolfSSL | 13:f67a6c6013ca | 5607 | |
wolfSSL | 13:f67a6c6013ca | 5608 | /* Try to use the server's group. */ |
wolfSSL | 13:f67a6c6013ca | 5609 | ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL); |
wolfSSL | 13:f67a6c6013ca | 5610 | } |
wolfSSL | 13:f67a6c6013ca | 5611 | else { |
wolfSSL | 13:f67a6c6013ca | 5612 | /* Not a message type that is allowed to have this extension. */ |
wolfSSL | 13:f67a6c6013ca | 5613 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 5614 | } |
wolfSSL | 13:f67a6c6013ca | 5615 | |
wolfSSL | 13:f67a6c6013ca | 5616 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5617 | } |
wolfSSL | 13:f67a6c6013ca | 5618 | |
wolfSSL | 13:f67a6c6013ca | 5619 | /* Create a new key share entry and put it into the list. |
wolfSSL | 13:f67a6c6013ca | 5620 | * |
wolfSSL | 13:f67a6c6013ca | 5621 | * list The linked list of key share entries. |
wolfSSL | 13:f67a6c6013ca | 5622 | * group The named group. |
wolfSSL | 13:f67a6c6013ca | 5623 | * heap The memory to allocate with. |
wolfSSL | 13:f67a6c6013ca | 5624 | * keyShareEntry The new key share entry object. |
wolfSSL | 13:f67a6c6013ca | 5625 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 5626 | */ |
wolfSSL | 13:f67a6c6013ca | 5627 | static int TLSX_KeyShare_New(KeyShareEntry** list, int group, void *heap, |
wolfSSL | 13:f67a6c6013ca | 5628 | KeyShareEntry** keyShareEntry) |
wolfSSL | 13:f67a6c6013ca | 5629 | { |
wolfSSL | 13:f67a6c6013ca | 5630 | KeyShareEntry* kse; |
wolfSSL | 13:f67a6c6013ca | 5631 | |
wolfSSL | 13:f67a6c6013ca | 5632 | kse = (KeyShareEntry*)XMALLOC(sizeof(KeyShareEntry), heap, |
wolfSSL | 13:f67a6c6013ca | 5633 | DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 5634 | if (kse == NULL) |
wolfSSL | 13:f67a6c6013ca | 5635 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 5636 | |
wolfSSL | 13:f67a6c6013ca | 5637 | XMEMSET(kse, 0, sizeof(*kse)); |
wolfSSL | 13:f67a6c6013ca | 5638 | kse->group = group; |
wolfSSL | 13:f67a6c6013ca | 5639 | |
wolfSSL | 13:f67a6c6013ca | 5640 | /* Add it to the back and maintain the links. */ |
wolfSSL | 13:f67a6c6013ca | 5641 | while (*list != NULL) |
wolfSSL | 13:f67a6c6013ca | 5642 | list = &((*list)->next); |
wolfSSL | 13:f67a6c6013ca | 5643 | *list = kse; |
wolfSSL | 13:f67a6c6013ca | 5644 | *keyShareEntry = kse; |
wolfSSL | 13:f67a6c6013ca | 5645 | |
wolfSSL | 13:f67a6c6013ca | 5646 | return 0; |
wolfSSL | 13:f67a6c6013ca | 5647 | } |
wolfSSL | 13:f67a6c6013ca | 5648 | |
wolfSSL | 13:f67a6c6013ca | 5649 | /* Use the data to create a new key share object in the extensions. |
wolfSSL | 13:f67a6c6013ca | 5650 | * |
wolfSSL | 13:f67a6c6013ca | 5651 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 5652 | * group The named group. |
wolfSSL | 13:f67a6c6013ca | 5653 | * len The length of the public key data. |
wolfSSL | 13:f67a6c6013ca | 5654 | * data The public key data. |
wolfSSL | 13:f67a6c6013ca | 5655 | * kse The new key share entry object. |
wolfSSL | 13:f67a6c6013ca | 5656 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 5657 | */ |
wolfSSL | 13:f67a6c6013ca | 5658 | int TLSX_KeyShare_Use(WOLFSSL* ssl, word16 group, word16 len, byte* data, |
wolfSSL | 13:f67a6c6013ca | 5659 | KeyShareEntry **kse) |
wolfSSL | 13:f67a6c6013ca | 5660 | { |
wolfSSL | 13:f67a6c6013ca | 5661 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 5662 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 5663 | KeyShareEntry* keyShareEntry = NULL; |
wolfSSL | 13:f67a6c6013ca | 5664 | |
wolfSSL | 13:f67a6c6013ca | 5665 | /* Find the KeyShare extension if it exists. */ |
wolfSSL | 13:f67a6c6013ca | 5666 | extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); |
wolfSSL | 13:f67a6c6013ca | 5667 | if (extension == NULL) { |
wolfSSL | 13:f67a6c6013ca | 5668 | /* Push new KeyShare extension. */ |
wolfSSL | 13:f67a6c6013ca | 5669 | ret = TLSX_Push(&ssl->extensions, TLSX_KEY_SHARE, NULL, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 5670 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 5671 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5672 | |
wolfSSL | 13:f67a6c6013ca | 5673 | extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); |
wolfSSL | 13:f67a6c6013ca | 5674 | if (extension == NULL) |
wolfSSL | 13:f67a6c6013ca | 5675 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 5676 | } |
wolfSSL | 13:f67a6c6013ca | 5677 | extension->resp = 0; |
wolfSSL | 13:f67a6c6013ca | 5678 | |
wolfSSL | 13:f67a6c6013ca | 5679 | /* Try to find the key share entry with this group. */ |
wolfSSL | 13:f67a6c6013ca | 5680 | keyShareEntry = (KeyShareEntry*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 5681 | while (keyShareEntry != NULL) { |
wolfSSL | 13:f67a6c6013ca | 5682 | if (keyShareEntry->group == group) |
wolfSSL | 13:f67a6c6013ca | 5683 | break; |
wolfSSL | 13:f67a6c6013ca | 5684 | keyShareEntry = keyShareEntry->next; |
wolfSSL | 13:f67a6c6013ca | 5685 | } |
wolfSSL | 13:f67a6c6013ca | 5686 | |
wolfSSL | 13:f67a6c6013ca | 5687 | /* Create a new key share entry if not found. */ |
wolfSSL | 13:f67a6c6013ca | 5688 | if (keyShareEntry == NULL) { |
wolfSSL | 13:f67a6c6013ca | 5689 | ret = TLSX_KeyShare_New((KeyShareEntry**)&extension->data, group, |
wolfSSL | 13:f67a6c6013ca | 5690 | ssl->heap, &keyShareEntry); |
wolfSSL | 13:f67a6c6013ca | 5691 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 5692 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5693 | } |
wolfSSL | 13:f67a6c6013ca | 5694 | |
wolfSSL | 13:f67a6c6013ca | 5695 | if (data != NULL) { |
wolfSSL | 13:f67a6c6013ca | 5696 | /* Keep the public key data and free when finished. */ |
wolfSSL | 13:f67a6c6013ca | 5697 | if (keyShareEntry->ke != NULL) |
wolfSSL | 13:f67a6c6013ca | 5698 | XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); |
wolfSSL | 13:f67a6c6013ca | 5699 | keyShareEntry->ke = data; |
wolfSSL | 13:f67a6c6013ca | 5700 | keyShareEntry->keLen = len; |
wolfSSL | 13:f67a6c6013ca | 5701 | } |
wolfSSL | 13:f67a6c6013ca | 5702 | else { |
wolfSSL | 13:f67a6c6013ca | 5703 | /* Generate a key pair. */ |
wolfSSL | 13:f67a6c6013ca | 5704 | ret = TLSX_KeyShare_GenKey(ssl, keyShareEntry); |
wolfSSL | 13:f67a6c6013ca | 5705 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 5706 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5707 | } |
wolfSSL | 13:f67a6c6013ca | 5708 | |
wolfSSL | 13:f67a6c6013ca | 5709 | if (kse != NULL) |
wolfSSL | 13:f67a6c6013ca | 5710 | *kse = keyShareEntry; |
wolfSSL | 13:f67a6c6013ca | 5711 | |
wolfSSL | 13:f67a6c6013ca | 5712 | return 0; |
wolfSSL | 13:f67a6c6013ca | 5713 | } |
wolfSSL | 13:f67a6c6013ca | 5714 | |
wolfSSL | 13:f67a6c6013ca | 5715 | /* Set an empty Key Share extension. |
wolfSSL | 13:f67a6c6013ca | 5716 | * |
wolfSSL | 13:f67a6c6013ca | 5717 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 5718 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 5719 | */ |
wolfSSL | 13:f67a6c6013ca | 5720 | int TLSX_KeyShare_Empty(WOLFSSL* ssl) |
wolfSSL | 13:f67a6c6013ca | 5721 | { |
wolfSSL | 13:f67a6c6013ca | 5722 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 5723 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 5724 | |
wolfSSL | 13:f67a6c6013ca | 5725 | /* Find the KeyShare extension if it exists. */ |
wolfSSL | 13:f67a6c6013ca | 5726 | extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); |
wolfSSL | 13:f67a6c6013ca | 5727 | if (extension == NULL) { |
wolfSSL | 13:f67a6c6013ca | 5728 | /* Push new KeyShare extension. */ |
wolfSSL | 13:f67a6c6013ca | 5729 | ret = TLSX_Push(&ssl->extensions, TLSX_KEY_SHARE, NULL, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 5730 | } |
wolfSSL | 13:f67a6c6013ca | 5731 | else if (extension->data != NULL) { |
wolfSSL | 13:f67a6c6013ca | 5732 | TLSX_KeyShare_FreeAll((KeyShareEntry*)extension->data, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 5733 | extension->data = NULL; |
wolfSSL | 13:f67a6c6013ca | 5734 | } |
wolfSSL | 13:f67a6c6013ca | 5735 | |
wolfSSL | 13:f67a6c6013ca | 5736 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5737 | } |
wolfSSL | 13:f67a6c6013ca | 5738 | |
wolfSSL | 13:f67a6c6013ca | 5739 | /* Returns whether this group is supported. |
wolfSSL | 13:f67a6c6013ca | 5740 | * |
wolfSSL | 13:f67a6c6013ca | 5741 | * namedGroup The named group to check. |
wolfSSL | 13:f67a6c6013ca | 5742 | * returns 1 when supported or 0 otherwise. |
wolfSSL | 13:f67a6c6013ca | 5743 | */ |
wolfSSL | 13:f67a6c6013ca | 5744 | static int TLSX_KeyShare_IsSupported(int namedGroup) |
wolfSSL | 13:f67a6c6013ca | 5745 | { |
wolfSSL | 13:f67a6c6013ca | 5746 | switch (namedGroup) { |
wolfSSL | 13:f67a6c6013ca | 5747 | #ifdef HAVE_FFDHE_2048 |
wolfSSL | 13:f67a6c6013ca | 5748 | case WOLFSSL_FFDHE_2048: |
wolfSSL | 13:f67a6c6013ca | 5749 | break; |
wolfSSL | 13:f67a6c6013ca | 5750 | #endif |
wolfSSL | 13:f67a6c6013ca | 5751 | #ifdef HAVE_FFDHE_3072 |
wolfSSL | 13:f67a6c6013ca | 5752 | case WOLFSSL_FFDHE_3072: |
wolfSSL | 13:f67a6c6013ca | 5753 | break; |
wolfSSL | 13:f67a6c6013ca | 5754 | #endif |
wolfSSL | 13:f67a6c6013ca | 5755 | #ifdef HAVE_FFDHE_4096 |
wolfSSL | 13:f67a6c6013ca | 5756 | case WOLFSSL_FFDHE_4096: |
wolfSSL | 13:f67a6c6013ca | 5757 | break; |
wolfSSL | 13:f67a6c6013ca | 5758 | #endif |
wolfSSL | 13:f67a6c6013ca | 5759 | #ifdef HAVE_FFDHE_6144 |
wolfSSL | 13:f67a6c6013ca | 5760 | case WOLFSSL_FFDHE_6144: |
wolfSSL | 13:f67a6c6013ca | 5761 | break; |
wolfSSL | 13:f67a6c6013ca | 5762 | #endif |
wolfSSL | 13:f67a6c6013ca | 5763 | #ifdef HAVE_FFDHE_8192 |
wolfSSL | 13:f67a6c6013ca | 5764 | case WOLFSSL_FFDHE_8192: |
wolfSSL | 13:f67a6c6013ca | 5765 | break; |
wolfSSL | 13:f67a6c6013ca | 5766 | #endif |
wolfSSL | 13:f67a6c6013ca | 5767 | #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 5768 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 5769 | case WOLFSSL_ECC_SECP256R1: |
wolfSSL | 13:f67a6c6013ca | 5770 | break; |
wolfSSL | 13:f67a6c6013ca | 5771 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:f67a6c6013ca | 5772 | #endif |
wolfSSL | 13:f67a6c6013ca | 5773 | #ifdef HAVE_CURVE25519 |
wolfSSL | 13:f67a6c6013ca | 5774 | case WOLFSSL_ECC_X25519: |
wolfSSL | 13:f67a6c6013ca | 5775 | break; |
wolfSSL | 13:f67a6c6013ca | 5776 | #endif |
wolfSSL | 13:f67a6c6013ca | 5777 | #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 5778 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 5779 | case WOLFSSL_ECC_SECP384R1: |
wolfSSL | 13:f67a6c6013ca | 5780 | break; |
wolfSSL | 13:f67a6c6013ca | 5781 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:f67a6c6013ca | 5782 | #endif |
wolfSSL | 13:f67a6c6013ca | 5783 | #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 5784 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 5785 | case WOLFSSL_ECC_SECP521R1: |
wolfSSL | 13:f67a6c6013ca | 5786 | break; |
wolfSSL | 13:f67a6c6013ca | 5787 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:f67a6c6013ca | 5788 | #endif |
wolfSSL | 13:f67a6c6013ca | 5789 | #ifdef HAVE_X448 |
wolfSSL | 13:f67a6c6013ca | 5790 | case WOLFSSL_ECC_X448: |
wolfSSL | 13:f67a6c6013ca | 5791 | break; |
wolfSSL | 13:f67a6c6013ca | 5792 | #endif |
wolfSSL | 13:f67a6c6013ca | 5793 | default: |
wolfSSL | 13:f67a6c6013ca | 5794 | return 0; |
wolfSSL | 13:f67a6c6013ca | 5795 | } |
wolfSSL | 13:f67a6c6013ca | 5796 | |
wolfSSL | 13:f67a6c6013ca | 5797 | return 1; |
wolfSSL | 13:f67a6c6013ca | 5798 | } |
wolfSSL | 13:f67a6c6013ca | 5799 | |
wolfSSL | 13:f67a6c6013ca | 5800 | /* Set a key share that is supported by the client into extensions. |
wolfSSL | 13:f67a6c6013ca | 5801 | * |
wolfSSL | 13:f67a6c6013ca | 5802 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 5803 | * returns BAD_KEY_SHARE_DATA if no supported group has a key share, |
wolfSSL | 13:f67a6c6013ca | 5804 | * 0 if a supported group has a key share and other values indicate an error. |
wolfSSL | 13:f67a6c6013ca | 5805 | */ |
wolfSSL | 13:f67a6c6013ca | 5806 | static int TLSX_KeyShare_SetSupported(WOLFSSL* ssl) |
wolfSSL | 13:f67a6c6013ca | 5807 | { |
wolfSSL | 13:f67a6c6013ca | 5808 | int ret; |
wolfSSL | 13:f67a6c6013ca | 5809 | #ifdef HAVE_SUPPORTED_CURVES |
wolfSSL | 13:f67a6c6013ca | 5810 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 5811 | EllipticCurve* curve = NULL; |
wolfSSL | 13:f67a6c6013ca | 5812 | |
wolfSSL | 13:f67a6c6013ca | 5813 | /* Use SupportedGroup's order. */ |
wolfSSL | 13:f67a6c6013ca | 5814 | extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS); |
wolfSSL | 13:f67a6c6013ca | 5815 | if (extension != NULL) |
wolfSSL | 13:f67a6c6013ca | 5816 | curve = (EllipticCurve*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 5817 | for (; curve != NULL; curve = curve->next) { |
wolfSSL | 13:f67a6c6013ca | 5818 | if (TLSX_KeyShare_IsSupported(curve->name) && |
wolfSSL | 13:f67a6c6013ca | 5819 | !TLSX_KeyShare_Find(ssl, curve->name)) { |
wolfSSL | 13:f67a6c6013ca | 5820 | break; |
wolfSSL | 13:f67a6c6013ca | 5821 | } |
wolfSSL | 13:f67a6c6013ca | 5822 | } |
wolfSSL | 13:f67a6c6013ca | 5823 | if (curve == NULL) |
wolfSSL | 13:f67a6c6013ca | 5824 | return BAD_KEY_SHARE_DATA; |
wolfSSL | 13:f67a6c6013ca | 5825 | |
wolfSSL | 13:f67a6c6013ca | 5826 | /* Delete the old key share data list. */ |
wolfSSL | 13:f67a6c6013ca | 5827 | extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); |
wolfSSL | 13:f67a6c6013ca | 5828 | if (extension != NULL) { |
wolfSSL | 13:f67a6c6013ca | 5829 | TLSX_KeyShare_FreeAll((KeyShareEntry*)extension->data, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 5830 | extension->data = NULL; |
wolfSSL | 13:f67a6c6013ca | 5831 | } |
wolfSSL | 13:f67a6c6013ca | 5832 | |
wolfSSL | 13:f67a6c6013ca | 5833 | /* Add in the chosen group. */ |
wolfSSL | 13:f67a6c6013ca | 5834 | ret = TLSX_KeyShare_Use(ssl, curve->name, 0, NULL, NULL); |
wolfSSL | 13:f67a6c6013ca | 5835 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 5836 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5837 | |
wolfSSL | 13:f67a6c6013ca | 5838 | /* Set extension to be in reponse. */ |
wolfSSL | 13:f67a6c6013ca | 5839 | extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); |
wolfSSL | 13:f67a6c6013ca | 5840 | extension->resp = 1; |
wolfSSL | 13:f67a6c6013ca | 5841 | #else |
wolfSSL | 13:f67a6c6013ca | 5842 | |
wolfSSL | 13:f67a6c6013ca | 5843 | (void)ssl; |
wolfSSL | 13:f67a6c6013ca | 5844 | ret = NOT_COMPILED_IN; |
wolfSSL | 13:f67a6c6013ca | 5845 | #endif |
wolfSSL | 13:f67a6c6013ca | 5846 | |
wolfSSL | 13:f67a6c6013ca | 5847 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5848 | } |
wolfSSL | 13:f67a6c6013ca | 5849 | |
wolfSSL | 13:f67a6c6013ca | 5850 | /* Establish the secret based on the key shares received from the client. |
wolfSSL | 13:f67a6c6013ca | 5851 | * |
wolfSSL | 13:f67a6c6013ca | 5852 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 5853 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 5854 | */ |
wolfSSL | 13:f67a6c6013ca | 5855 | int TLSX_KeyShare_Establish(WOLFSSL *ssl) |
wolfSSL | 13:f67a6c6013ca | 5856 | { |
wolfSSL | 13:f67a6c6013ca | 5857 | int ret; |
wolfSSL | 13:f67a6c6013ca | 5858 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 5859 | KeyShareEntry* clientKSE = NULL; |
wolfSSL | 13:f67a6c6013ca | 5860 | KeyShareEntry* serverKSE; |
wolfSSL | 13:f67a6c6013ca | 5861 | KeyShareEntry* list = NULL; |
wolfSSL | 13:f67a6c6013ca | 5862 | byte* ke; |
wolfSSL | 13:f67a6c6013ca | 5863 | word16 keLen; |
wolfSSL | 13:f67a6c6013ca | 5864 | |
wolfSSL | 13:f67a6c6013ca | 5865 | /* Find the KeyShare extension if it exists. */ |
wolfSSL | 13:f67a6c6013ca | 5866 | extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); |
wolfSSL | 13:f67a6c6013ca | 5867 | if (extension != NULL) |
wolfSSL | 13:f67a6c6013ca | 5868 | list = (KeyShareEntry*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 5869 | |
wolfSSL | 13:f67a6c6013ca | 5870 | if (extension && extension->resp == 1) |
wolfSSL | 13:f67a6c6013ca | 5871 | return 0; |
wolfSSL | 13:f67a6c6013ca | 5872 | |
wolfSSL | 13:f67a6c6013ca | 5873 | /* TODO: [TLS13] Server's preference and sending back SupportedGroups */ |
wolfSSL | 13:f67a6c6013ca | 5874 | /* Use client's preference. */ |
wolfSSL | 13:f67a6c6013ca | 5875 | for (clientKSE = list; clientKSE != NULL; clientKSE = clientKSE->next) { |
wolfSSL | 13:f67a6c6013ca | 5876 | /* Check consistency now - extensions in any order. */ |
wolfSSL | 13:f67a6c6013ca | 5877 | if (!TLSX_SupportedGroups_Find(ssl, clientKSE->group)) |
wolfSSL | 13:f67a6c6013ca | 5878 | return BAD_KEY_SHARE_DATA; |
wolfSSL | 13:f67a6c6013ca | 5879 | |
wolfSSL | 13:f67a6c6013ca | 5880 | #ifdef OPENSSL_EXTRA |
wolfSSL | 13:f67a6c6013ca | 5881 | /* Check if server supports group. */ |
wolfSSL | 13:f67a6c6013ca | 5882 | if (ssl->ctx->disabledCurves & (1 << clientKSE->group)) |
wolfSSL | 13:f67a6c6013ca | 5883 | continue; |
wolfSSL | 13:f67a6c6013ca | 5884 | #endif |
wolfSSL | 13:f67a6c6013ca | 5885 | if (TLSX_KeyShare_IsSupported(clientKSE->group)) |
wolfSSL | 13:f67a6c6013ca | 5886 | break; |
wolfSSL | 13:f67a6c6013ca | 5887 | } |
wolfSSL | 13:f67a6c6013ca | 5888 | /* No supported group found - send HelloRetryRequest. */ |
wolfSSL | 13:f67a6c6013ca | 5889 | if (clientKSE == NULL) { |
wolfSSL | 13:f67a6c6013ca | 5890 | ret = TLSX_KeyShare_SetSupported(ssl); |
wolfSSL | 13:f67a6c6013ca | 5891 | /* Return KEY_SHARE_ERROR to indicate HelloRetryRequest required. */ |
wolfSSL | 13:f67a6c6013ca | 5892 | if (ret == 0) |
wolfSSL | 13:f67a6c6013ca | 5893 | return KEY_SHARE_ERROR; |
wolfSSL | 13:f67a6c6013ca | 5894 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5895 | } |
wolfSSL | 13:f67a6c6013ca | 5896 | |
wolfSSL | 13:f67a6c6013ca | 5897 | list = NULL; |
wolfSSL | 13:f67a6c6013ca | 5898 | /* Generate a new key pair. */ |
wolfSSL | 13:f67a6c6013ca | 5899 | ret = TLSX_KeyShare_New(&list, clientKSE->group, ssl->heap, &serverKSE); |
wolfSSL | 13:f67a6c6013ca | 5900 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 5901 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5902 | ret = TLSX_KeyShare_GenKey(ssl, serverKSE); |
wolfSSL | 13:f67a6c6013ca | 5903 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 5904 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5905 | |
wolfSSL | 13:f67a6c6013ca | 5906 | /* Move private key to client entry. */ |
wolfSSL | 13:f67a6c6013ca | 5907 | if (clientKSE->key != NULL) |
wolfSSL | 13:f67a6c6013ca | 5908 | XFREE(clientKSE->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); |
wolfSSL | 13:f67a6c6013ca | 5909 | clientKSE->key = serverKSE->key; |
wolfSSL | 13:f67a6c6013ca | 5910 | serverKSE->key = NULL; |
wolfSSL | 13:f67a6c6013ca | 5911 | clientKSE->keyLen = serverKSE->keyLen; |
wolfSSL | 13:f67a6c6013ca | 5912 | |
wolfSSL | 13:f67a6c6013ca | 5913 | /* Calculate secret. */ |
wolfSSL | 13:f67a6c6013ca | 5914 | ret = TLSX_KeyShare_Process(ssl, clientKSE); |
wolfSSL | 13:f67a6c6013ca | 5915 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 5916 | return ret; |
wolfSSL | 13:f67a6c6013ca | 5917 | |
wolfSSL | 13:f67a6c6013ca | 5918 | /* Swap public keys for sending to client. */ |
wolfSSL | 13:f67a6c6013ca | 5919 | ke = serverKSE->ke; |
wolfSSL | 13:f67a6c6013ca | 5920 | keLen = serverKSE->keLen; |
wolfSSL | 13:f67a6c6013ca | 5921 | serverKSE->ke = clientKSE->ke; |
wolfSSL | 13:f67a6c6013ca | 5922 | serverKSE->keLen = clientKSE->keLen; |
wolfSSL | 13:f67a6c6013ca | 5923 | clientKSE->ke = ke; |
wolfSSL | 13:f67a6c6013ca | 5924 | clientKSE->keLen = keLen; |
wolfSSL | 13:f67a6c6013ca | 5925 | |
wolfSSL | 13:f67a6c6013ca | 5926 | extension->resp = 1; |
wolfSSL | 13:f67a6c6013ca | 5927 | |
wolfSSL | 13:f67a6c6013ca | 5928 | /* Dispose of temporary server extension. */ |
wolfSSL | 13:f67a6c6013ca | 5929 | TLSX_KeyShare_FreeAll(list, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 5930 | |
wolfSSL | 13:f67a6c6013ca | 5931 | return 0; |
wolfSSL | 13:f67a6c6013ca | 5932 | } |
wolfSSL | 13:f67a6c6013ca | 5933 | |
wolfSSL | 13:f67a6c6013ca | 5934 | #define KS_FREE_ALL TLSX_KeyShare_FreeAll |
wolfSSL | 13:f67a6c6013ca | 5935 | #define KS_GET_SIZE TLSX_KeyShare_GetSize |
wolfSSL | 13:f67a6c6013ca | 5936 | #define KS_WRITE TLSX_KeyShare_Write |
wolfSSL | 13:f67a6c6013ca | 5937 | #define KS_PARSE TLSX_KeyShare_Parse |
wolfSSL | 13:f67a6c6013ca | 5938 | |
wolfSSL | 13:f67a6c6013ca | 5939 | #else |
wolfSSL | 13:f67a6c6013ca | 5940 | |
wolfSSL | 13:f67a6c6013ca | 5941 | #define KS_FREE_ALL(a, b) |
wolfSSL | 13:f67a6c6013ca | 5942 | #define KS_GET_SIZE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 5943 | #define KS_WRITE(a, b, c) 0 |
wolfSSL | 13:f67a6c6013ca | 5944 | #define KS_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 5945 | |
wolfSSL | 13:f67a6c6013ca | 5946 | #endif /* WOLFSSL_TLS13 */ |
wolfSSL | 13:f67a6c6013ca | 5947 | |
wolfSSL | 13:f67a6c6013ca | 5948 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 5949 | /* Pre-Shared Key */ |
wolfSSL | 13:f67a6c6013ca | 5950 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 5951 | |
wolfSSL | 13:f67a6c6013ca | 5952 | #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)) |
wolfSSL | 13:f67a6c6013ca | 5953 | /* Free the pre-shared key dynamic data. |
wolfSSL | 13:f67a6c6013ca | 5954 | * |
wolfSSL | 13:f67a6c6013ca | 5955 | * list The linked list of key share entry objects. |
wolfSSL | 13:f67a6c6013ca | 5956 | * heap The heap used for allocation. |
wolfSSL | 13:f67a6c6013ca | 5957 | */ |
wolfSSL | 13:f67a6c6013ca | 5958 | static void TLSX_PreSharedKey_FreeAll(PreSharedKey* list, void* heap) |
wolfSSL | 13:f67a6c6013ca | 5959 | { |
wolfSSL | 13:f67a6c6013ca | 5960 | PreSharedKey* current; |
wolfSSL | 13:f67a6c6013ca | 5961 | |
wolfSSL | 13:f67a6c6013ca | 5962 | while ((current = list) != NULL) { |
wolfSSL | 13:f67a6c6013ca | 5963 | list = current->next; |
wolfSSL | 13:f67a6c6013ca | 5964 | XFREE(current->identity, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 5965 | XFREE(current, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 5966 | } |
wolfSSL | 13:f67a6c6013ca | 5967 | |
wolfSSL | 13:f67a6c6013ca | 5968 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 5969 | } |
wolfSSL | 13:f67a6c6013ca | 5970 | |
wolfSSL | 13:f67a6c6013ca | 5971 | /* Get the size of the encoded pre shared key extension. |
wolfSSL | 13:f67a6c6013ca | 5972 | * |
wolfSSL | 13:f67a6c6013ca | 5973 | * list The linked list of pre-shared key extensions. |
wolfSSL | 13:f67a6c6013ca | 5974 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:f67a6c6013ca | 5975 | * returns the number of bytes of the encoded pre-shared key extension or |
wolfSSL | 13:f67a6c6013ca | 5976 | * SANITY_MSG_E to indicate invalid message type. |
wolfSSL | 13:f67a6c6013ca | 5977 | */ |
wolfSSL | 13:f67a6c6013ca | 5978 | static word16 TLSX_PreSharedKey_GetSize(PreSharedKey* list, byte msgType) |
wolfSSL | 13:f67a6c6013ca | 5979 | { |
wolfSSL | 13:f67a6c6013ca | 5980 | if (msgType == client_hello) { |
wolfSSL | 13:f67a6c6013ca | 5981 | /* Length of identities + Length of binders. */ |
wolfSSL | 13:f67a6c6013ca | 5982 | word16 len = OPAQUE16_LEN + OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 5983 | while (list != NULL) { |
wolfSSL | 13:f67a6c6013ca | 5984 | /* Each entry has: identity, ticket age and binder. */ |
wolfSSL | 13:f67a6c6013ca | 5985 | len += OPAQUE16_LEN + list->identityLen + OPAQUE32_LEN + |
wolfSSL | 13:f67a6c6013ca | 5986 | OPAQUE8_LEN + list->binderLen; |
wolfSSL | 13:f67a6c6013ca | 5987 | list = list->next; |
wolfSSL | 13:f67a6c6013ca | 5988 | } |
wolfSSL | 13:f67a6c6013ca | 5989 | return len; |
wolfSSL | 13:f67a6c6013ca | 5990 | } |
wolfSSL | 13:f67a6c6013ca | 5991 | |
wolfSSL | 13:f67a6c6013ca | 5992 | if (msgType == server_hello) { |
wolfSSL | 13:f67a6c6013ca | 5993 | return OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 5994 | } |
wolfSSL | 13:f67a6c6013ca | 5995 | |
wolfSSL | 13:f67a6c6013ca | 5996 | return 0; |
wolfSSL | 13:f67a6c6013ca | 5997 | } |
wolfSSL | 13:f67a6c6013ca | 5998 | |
wolfSSL | 13:f67a6c6013ca | 5999 | /* The number of bytes to be written for the binders. |
wolfSSL | 13:f67a6c6013ca | 6000 | * |
wolfSSL | 13:f67a6c6013ca | 6001 | * list The linked list of pre-shared key extensions. |
wolfSSL | 13:f67a6c6013ca | 6002 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:f67a6c6013ca | 6003 | * returns the number of bytes of the encoded pre-shared key extension or |
wolfSSL | 13:f67a6c6013ca | 6004 | * SANITY_MSG_E to indicate invalid message type. |
wolfSSL | 13:f67a6c6013ca | 6005 | */ |
wolfSSL | 13:f67a6c6013ca | 6006 | word16 TLSX_PreSharedKey_GetSizeBinders(PreSharedKey* list, byte msgType) |
wolfSSL | 13:f67a6c6013ca | 6007 | { |
wolfSSL | 13:f67a6c6013ca | 6008 | word16 len; |
wolfSSL | 13:f67a6c6013ca | 6009 | |
wolfSSL | 13:f67a6c6013ca | 6010 | if (msgType != client_hello) |
wolfSSL | 13:f67a6c6013ca | 6011 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 6012 | |
wolfSSL | 13:f67a6c6013ca | 6013 | /* Length of all binders. */ |
wolfSSL | 13:f67a6c6013ca | 6014 | len = OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 6015 | while (list != NULL) { |
wolfSSL | 13:f67a6c6013ca | 6016 | len += OPAQUE8_LEN + list->binderLen; |
wolfSSL | 13:f67a6c6013ca | 6017 | list = list->next; |
wolfSSL | 13:f67a6c6013ca | 6018 | } |
wolfSSL | 13:f67a6c6013ca | 6019 | |
wolfSSL | 13:f67a6c6013ca | 6020 | return len; |
wolfSSL | 13:f67a6c6013ca | 6021 | } |
wolfSSL | 13:f67a6c6013ca | 6022 | |
wolfSSL | 13:f67a6c6013ca | 6023 | /* Writes the pre-shared key extension into the output buffer - binders only. |
wolfSSL | 13:f67a6c6013ca | 6024 | * Assumes that the the output buffer is big enough to hold data. |
wolfSSL | 13:f67a6c6013ca | 6025 | * |
wolfSSL | 13:f67a6c6013ca | 6026 | * list The linked list of key share entries. |
wolfSSL | 13:f67a6c6013ca | 6027 | * output The buffer to write into. |
wolfSSL | 13:f67a6c6013ca | 6028 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:f67a6c6013ca | 6029 | * returns the number of bytes written into the buffer. |
wolfSSL | 13:f67a6c6013ca | 6030 | */ |
wolfSSL | 13:f67a6c6013ca | 6031 | word16 TLSX_PreSharedKey_WriteBinders(PreSharedKey* list, byte* output, |
wolfSSL | 13:f67a6c6013ca | 6032 | byte msgType) |
wolfSSL | 13:f67a6c6013ca | 6033 | { |
wolfSSL | 13:f67a6c6013ca | 6034 | PreSharedKey* current = list; |
wolfSSL | 13:f67a6c6013ca | 6035 | word16 idx = 0; |
wolfSSL | 13:f67a6c6013ca | 6036 | word16 lenIdx; |
wolfSSL | 13:f67a6c6013ca | 6037 | word16 len; |
wolfSSL | 13:f67a6c6013ca | 6038 | |
wolfSSL | 13:f67a6c6013ca | 6039 | if (msgType != client_hello) |
wolfSSL | 13:f67a6c6013ca | 6040 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 6041 | |
wolfSSL | 13:f67a6c6013ca | 6042 | /* Skip length of all binders. */ |
wolfSSL | 13:f67a6c6013ca | 6043 | lenIdx = idx; |
wolfSSL | 13:f67a6c6013ca | 6044 | idx += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 6045 | while (current != NULL) { |
wolfSSL | 13:f67a6c6013ca | 6046 | /* Binder data length. */ |
wolfSSL | 13:f67a6c6013ca | 6047 | output[idx++] = current->binderLen; |
wolfSSL | 13:f67a6c6013ca | 6048 | /* Binder data. */ |
wolfSSL | 13:f67a6c6013ca | 6049 | XMEMCPY(output + idx, current->binder, current->binderLen); |
wolfSSL | 13:f67a6c6013ca | 6050 | idx += current->binderLen; |
wolfSSL | 13:f67a6c6013ca | 6051 | |
wolfSSL | 13:f67a6c6013ca | 6052 | current = current->next; |
wolfSSL | 13:f67a6c6013ca | 6053 | } |
wolfSSL | 13:f67a6c6013ca | 6054 | /* Length of the binders. */ |
wolfSSL | 13:f67a6c6013ca | 6055 | len = idx - lenIdx - OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 6056 | c16toa(len, output + lenIdx); |
wolfSSL | 13:f67a6c6013ca | 6057 | |
wolfSSL | 13:f67a6c6013ca | 6058 | return idx; |
wolfSSL | 13:f67a6c6013ca | 6059 | } |
wolfSSL | 13:f67a6c6013ca | 6060 | |
wolfSSL | 13:f67a6c6013ca | 6061 | |
wolfSSL | 13:f67a6c6013ca | 6062 | /* Writes the pre-shared key extension into the output buffer. |
wolfSSL | 13:f67a6c6013ca | 6063 | * Assumes that the the output buffer is big enough to hold data. |
wolfSSL | 13:f67a6c6013ca | 6064 | * |
wolfSSL | 13:f67a6c6013ca | 6065 | * list The linked list of key share entries. |
wolfSSL | 13:f67a6c6013ca | 6066 | * output The buffer to write into. |
wolfSSL | 13:f67a6c6013ca | 6067 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:f67a6c6013ca | 6068 | * returns the number of bytes written into the buffer. |
wolfSSL | 13:f67a6c6013ca | 6069 | */ |
wolfSSL | 13:f67a6c6013ca | 6070 | static word16 TLSX_PreSharedKey_Write(PreSharedKey* list, byte* output, |
wolfSSL | 13:f67a6c6013ca | 6071 | byte msgType) |
wolfSSL | 13:f67a6c6013ca | 6072 | { |
wolfSSL | 13:f67a6c6013ca | 6073 | if (msgType == client_hello) { |
wolfSSL | 13:f67a6c6013ca | 6074 | PreSharedKey* current = list; |
wolfSSL | 13:f67a6c6013ca | 6075 | word16 idx = 0; |
wolfSSL | 13:f67a6c6013ca | 6076 | word16 lenIdx; |
wolfSSL | 13:f67a6c6013ca | 6077 | word16 len; |
wolfSSL | 13:f67a6c6013ca | 6078 | |
wolfSSL | 13:f67a6c6013ca | 6079 | /* Write identites only. Binders after HMACing over this. */ |
wolfSSL | 13:f67a6c6013ca | 6080 | lenIdx = idx; |
wolfSSL | 13:f67a6c6013ca | 6081 | idx += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 6082 | while (current != NULL) { |
wolfSSL | 13:f67a6c6013ca | 6083 | /* Identity length */ |
wolfSSL | 13:f67a6c6013ca | 6084 | c16toa(current->identityLen, output + idx); |
wolfSSL | 13:f67a6c6013ca | 6085 | idx += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 6086 | /* Identity data */ |
wolfSSL | 13:f67a6c6013ca | 6087 | XMEMCPY(output + idx, current->identity, current->identityLen); |
wolfSSL | 13:f67a6c6013ca | 6088 | idx += current->identityLen; |
wolfSSL | 13:f67a6c6013ca | 6089 | |
wolfSSL | 13:f67a6c6013ca | 6090 | /* Obfuscated ticket age. */ |
wolfSSL | 13:f67a6c6013ca | 6091 | c32toa(current->ticketAge, output + idx); |
wolfSSL | 13:f67a6c6013ca | 6092 | idx += OPAQUE32_LEN; |
wolfSSL | 13:f67a6c6013ca | 6093 | |
wolfSSL | 13:f67a6c6013ca | 6094 | current = current->next; |
wolfSSL | 13:f67a6c6013ca | 6095 | } |
wolfSSL | 13:f67a6c6013ca | 6096 | /* Length of the identites. */ |
wolfSSL | 13:f67a6c6013ca | 6097 | len = idx - lenIdx - OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 6098 | c16toa(len, output + lenIdx); |
wolfSSL | 13:f67a6c6013ca | 6099 | |
wolfSSL | 13:f67a6c6013ca | 6100 | /* Don't include binders here. |
wolfSSL | 13:f67a6c6013ca | 6101 | * The binders are based on the hash of all the ClientHello data up to |
wolfSSL | 13:f67a6c6013ca | 6102 | * and include the identities written above. |
wolfSSL | 13:f67a6c6013ca | 6103 | */ |
wolfSSL | 13:f67a6c6013ca | 6104 | idx += TLSX_PreSharedKey_GetSizeBinders(list, msgType); |
wolfSSL | 13:f67a6c6013ca | 6105 | |
wolfSSL | 13:f67a6c6013ca | 6106 | return idx; |
wolfSSL | 13:f67a6c6013ca | 6107 | } |
wolfSSL | 13:f67a6c6013ca | 6108 | |
wolfSSL | 13:f67a6c6013ca | 6109 | if (msgType == server_hello) { |
wolfSSL | 13:f67a6c6013ca | 6110 | word16 i; |
wolfSSL | 13:f67a6c6013ca | 6111 | |
wolfSSL | 13:f67a6c6013ca | 6112 | /* Find the index of the chosen identity. */ |
wolfSSL | 13:f67a6c6013ca | 6113 | for (i=0; list != NULL && !list->chosen; i++) |
wolfSSL | 13:f67a6c6013ca | 6114 | list = list->next; |
wolfSSL | 13:f67a6c6013ca | 6115 | if (list == NULL) |
wolfSSL | 13:f67a6c6013ca | 6116 | return BUILD_MSG_ERROR; |
wolfSSL | 13:f67a6c6013ca | 6117 | |
wolfSSL | 13:f67a6c6013ca | 6118 | /* The index of the identity chosen by the server from the list supplied |
wolfSSL | 13:f67a6c6013ca | 6119 | * by the client. |
wolfSSL | 13:f67a6c6013ca | 6120 | */ |
wolfSSL | 13:f67a6c6013ca | 6121 | c16toa(i, output); |
wolfSSL | 13:f67a6c6013ca | 6122 | return OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 6123 | } |
wolfSSL | 13:f67a6c6013ca | 6124 | |
wolfSSL | 13:f67a6c6013ca | 6125 | return 0; |
wolfSSL | 13:f67a6c6013ca | 6126 | } |
wolfSSL | 13:f67a6c6013ca | 6127 | |
wolfSSL | 13:f67a6c6013ca | 6128 | /* Parse the pre-shared key extension. |
wolfSSL | 13:f67a6c6013ca | 6129 | * Different formats in different messages. |
wolfSSL | 13:f67a6c6013ca | 6130 | * |
wolfSSL | 13:f67a6c6013ca | 6131 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 6132 | * input The extension data. |
wolfSSL | 13:f67a6c6013ca | 6133 | * length The length of the extension data. |
wolfSSL | 13:f67a6c6013ca | 6134 | * msgType The type of the message this extension is being parsed from. |
wolfSSL | 13:f67a6c6013ca | 6135 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 6136 | */ |
wolfSSL | 13:f67a6c6013ca | 6137 | static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 6138 | byte msgType) |
wolfSSL | 13:f67a6c6013ca | 6139 | { |
wolfSSL | 13:f67a6c6013ca | 6140 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 6141 | PreSharedKey* list; |
wolfSSL | 13:f67a6c6013ca | 6142 | |
wolfSSL | 13:f67a6c6013ca | 6143 | if (msgType == client_hello) { |
wolfSSL | 13:f67a6c6013ca | 6144 | int ret; |
wolfSSL | 13:f67a6c6013ca | 6145 | word16 len; |
wolfSSL | 13:f67a6c6013ca | 6146 | word16 idx = 0; |
wolfSSL | 13:f67a6c6013ca | 6147 | |
wolfSSL | 13:f67a6c6013ca | 6148 | /* Length of identities and of binders. */ |
wolfSSL | 13:f67a6c6013ca | 6149 | if (length - idx < OPAQUE16_LEN + OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 6150 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6151 | |
wolfSSL | 13:f67a6c6013ca | 6152 | /* Length of identities. */ |
wolfSSL | 13:f67a6c6013ca | 6153 | ato16(input + idx, &len); |
wolfSSL | 13:f67a6c6013ca | 6154 | idx += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 6155 | if (len < MIN_PSK_ID_LEN || length - idx < len) |
wolfSSL | 13:f67a6c6013ca | 6156 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6157 | |
wolfSSL | 13:f67a6c6013ca | 6158 | /* Create a pre-shared key object for each identity. */ |
wolfSSL | 13:f67a6c6013ca | 6159 | while (len > 0) { |
wolfSSL | 13:f67a6c6013ca | 6160 | byte* identity; |
wolfSSL | 13:f67a6c6013ca | 6161 | word16 identityLen; |
wolfSSL | 13:f67a6c6013ca | 6162 | word32 age; |
wolfSSL | 13:f67a6c6013ca | 6163 | |
wolfSSL | 13:f67a6c6013ca | 6164 | if (len < OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 6165 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6166 | |
wolfSSL | 13:f67a6c6013ca | 6167 | /* Length of identity. */ |
wolfSSL | 13:f67a6c6013ca | 6168 | ato16(input + idx, &identityLen); |
wolfSSL | 13:f67a6c6013ca | 6169 | idx += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 6170 | if (len < OPAQUE16_LEN + identityLen + OPAQUE32_LEN) |
wolfSSL | 13:f67a6c6013ca | 6171 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6172 | /* Cache identity pointer. */ |
wolfSSL | 13:f67a6c6013ca | 6173 | identity = input + idx; |
wolfSSL | 13:f67a6c6013ca | 6174 | idx += identityLen; |
wolfSSL | 13:f67a6c6013ca | 6175 | /* Ticket age. */ |
wolfSSL | 13:f67a6c6013ca | 6176 | ato32(input + idx, &age); |
wolfSSL | 13:f67a6c6013ca | 6177 | idx += OPAQUE32_LEN; |
wolfSSL | 13:f67a6c6013ca | 6178 | |
wolfSSL | 13:f67a6c6013ca | 6179 | ret = TLSX_PreSharedKey_Use(ssl, identity, identityLen, age, no_mac, |
wolfSSL | 13:f67a6c6013ca | 6180 | 0, 0, 1, NULL); |
wolfSSL | 13:f67a6c6013ca | 6181 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 6182 | return ret; |
wolfSSL | 13:f67a6c6013ca | 6183 | |
wolfSSL | 13:f67a6c6013ca | 6184 | /* Done with this identity. */ |
wolfSSL | 13:f67a6c6013ca | 6185 | len -= OPAQUE16_LEN + identityLen + OPAQUE32_LEN; |
wolfSSL | 13:f67a6c6013ca | 6186 | } |
wolfSSL | 13:f67a6c6013ca | 6187 | |
wolfSSL | 13:f67a6c6013ca | 6188 | /* Find the list of identities sent to server. */ |
wolfSSL | 13:f67a6c6013ca | 6189 | extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY); |
wolfSSL | 13:f67a6c6013ca | 6190 | if (extension == NULL) |
wolfSSL | 13:f67a6c6013ca | 6191 | return PSK_KEY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 6192 | list = (PreSharedKey*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 6193 | |
wolfSSL | 13:f67a6c6013ca | 6194 | /* Length of binders. */ |
wolfSSL | 13:f67a6c6013ca | 6195 | ato16(input + idx, &len); |
wolfSSL | 13:f67a6c6013ca | 6196 | idx += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 6197 | if (len < MIN_PSK_BINDERS_LEN || length - idx < len) |
wolfSSL | 13:f67a6c6013ca | 6198 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6199 | |
wolfSSL | 13:f67a6c6013ca | 6200 | /* Set binder for each identity. */ |
wolfSSL | 13:f67a6c6013ca | 6201 | while (list != NULL && len > 0) { |
wolfSSL | 13:f67a6c6013ca | 6202 | /* Length of binder */ |
wolfSSL | 13:f67a6c6013ca | 6203 | list->binderLen = input[idx++]; |
wolfSSL | 13:f67a6c6013ca | 6204 | if (list->binderLen < SHA256_DIGEST_SIZE || |
wolfSSL | 13:f67a6c6013ca | 6205 | list->binderLen > MAX_DIGEST_SIZE) |
wolfSSL | 13:f67a6c6013ca | 6206 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6207 | if (len < OPAQUE8_LEN + list->binderLen) |
wolfSSL | 13:f67a6c6013ca | 6208 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6209 | |
wolfSSL | 13:f67a6c6013ca | 6210 | /* Copy binder into static buffer. */ |
wolfSSL | 13:f67a6c6013ca | 6211 | XMEMCPY(list->binder, input + idx, list->binderLen); |
wolfSSL | 13:f67a6c6013ca | 6212 | idx += list->binderLen; |
wolfSSL | 13:f67a6c6013ca | 6213 | |
wolfSSL | 13:f67a6c6013ca | 6214 | /* Done with binder entry. */ |
wolfSSL | 13:f67a6c6013ca | 6215 | len -= OPAQUE8_LEN + list->binderLen; |
wolfSSL | 13:f67a6c6013ca | 6216 | |
wolfSSL | 13:f67a6c6013ca | 6217 | /* Next identity. */ |
wolfSSL | 13:f67a6c6013ca | 6218 | list = list->next; |
wolfSSL | 13:f67a6c6013ca | 6219 | } |
wolfSSL | 13:f67a6c6013ca | 6220 | if (list != NULL || len != 0) |
wolfSSL | 13:f67a6c6013ca | 6221 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6222 | |
wolfSSL | 13:f67a6c6013ca | 6223 | return 0; |
wolfSSL | 13:f67a6c6013ca | 6224 | } |
wolfSSL | 13:f67a6c6013ca | 6225 | |
wolfSSL | 13:f67a6c6013ca | 6226 | if (msgType == server_hello) { |
wolfSSL | 13:f67a6c6013ca | 6227 | word16 idx; |
wolfSSL | 13:f67a6c6013ca | 6228 | |
wolfSSL | 13:f67a6c6013ca | 6229 | /* Index of identity chosen by server. */ |
wolfSSL | 13:f67a6c6013ca | 6230 | if (length != OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 6231 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6232 | ato16(input, &idx); |
wolfSSL | 13:f67a6c6013ca | 6233 | |
wolfSSL | 13:f67a6c6013ca | 6234 | /* Find the list of identities sent to server. */ |
wolfSSL | 13:f67a6c6013ca | 6235 | extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY); |
wolfSSL | 13:f67a6c6013ca | 6236 | if (extension == NULL) |
wolfSSL | 13:f67a6c6013ca | 6237 | return PSK_KEY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 6238 | list = (PreSharedKey*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 6239 | |
wolfSSL | 13:f67a6c6013ca | 6240 | /* Mark the identity as chosen. */ |
wolfSSL | 13:f67a6c6013ca | 6241 | for (; list != NULL && idx > 0; idx--) |
wolfSSL | 13:f67a6c6013ca | 6242 | list = list->next; |
wolfSSL | 13:f67a6c6013ca | 6243 | if (list == NULL) |
wolfSSL | 13:f67a6c6013ca | 6244 | return PSK_KEY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 6245 | list->chosen = 1; |
wolfSSL | 13:f67a6c6013ca | 6246 | |
wolfSSL | 13:f67a6c6013ca | 6247 | #ifdef HAVE_SESSION_TICKET |
wolfSSL | 13:f67a6c6013ca | 6248 | if (list->resumption) { |
wolfSSL | 13:f67a6c6013ca | 6249 | /* Check that the session's details are the same as the server's. */ |
wolfSSL | 13:f67a6c6013ca | 6250 | if (ssl->options.cipherSuite0 != ssl->session.cipherSuite0 || |
wolfSSL | 13:f67a6c6013ca | 6251 | ssl->options.cipherSuite != ssl->session.cipherSuite || |
wolfSSL | 13:f67a6c6013ca | 6252 | ssl->session.version.major != ssl->version.major || |
wolfSSL | 13:f67a6c6013ca | 6253 | ssl->session.version.minor != ssl->version.minor ) { |
wolfSSL | 13:f67a6c6013ca | 6254 | return PSK_KEY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 6255 | } |
wolfSSL | 13:f67a6c6013ca | 6256 | } |
wolfSSL | 13:f67a6c6013ca | 6257 | #endif |
wolfSSL | 13:f67a6c6013ca | 6258 | /* TODO: [TLS13] More checks of consistency. |
wolfSSL | 13:f67a6c6013ca | 6259 | * the "key_share", and "signature_algorithms" extensions are |
wolfSSL | 13:f67a6c6013ca | 6260 | * consistent with the indicated ke_modes and auth_modes values |
wolfSSL | 13:f67a6c6013ca | 6261 | */ |
wolfSSL | 13:f67a6c6013ca | 6262 | |
wolfSSL | 13:f67a6c6013ca | 6263 | return 0; |
wolfSSL | 13:f67a6c6013ca | 6264 | } |
wolfSSL | 13:f67a6c6013ca | 6265 | |
wolfSSL | 13:f67a6c6013ca | 6266 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 6267 | } |
wolfSSL | 13:f67a6c6013ca | 6268 | |
wolfSSL | 13:f67a6c6013ca | 6269 | /* Create a new pre-shared key and put it into the list. |
wolfSSL | 13:f67a6c6013ca | 6270 | * |
wolfSSL | 13:f67a6c6013ca | 6271 | * list The linked list of pre-shared key. |
wolfSSL | 13:f67a6c6013ca | 6272 | * identity The identity. |
wolfSSL | 13:f67a6c6013ca | 6273 | * len The length of the identity data. |
wolfSSL | 13:f67a6c6013ca | 6274 | * heap The memory to allocate with. |
wolfSSL | 13:f67a6c6013ca | 6275 | * preSharedKey The new pre-shared key object. |
wolfSSL | 13:f67a6c6013ca | 6276 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 6277 | */ |
wolfSSL | 13:f67a6c6013ca | 6278 | static int TLSX_PreSharedKey_New(PreSharedKey** list, byte* identity, |
wolfSSL | 13:f67a6c6013ca | 6279 | word16 len, void *heap, |
wolfSSL | 13:f67a6c6013ca | 6280 | PreSharedKey** preSharedKey) |
wolfSSL | 13:f67a6c6013ca | 6281 | { |
wolfSSL | 13:f67a6c6013ca | 6282 | PreSharedKey* psk; |
wolfSSL | 13:f67a6c6013ca | 6283 | |
wolfSSL | 13:f67a6c6013ca | 6284 | psk = (PreSharedKey*)XMALLOC(sizeof(PreSharedKey), heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 6285 | if (psk == NULL) |
wolfSSL | 13:f67a6c6013ca | 6286 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 6287 | XMEMSET(psk, 0, sizeof(*psk)); |
wolfSSL | 13:f67a6c6013ca | 6288 | |
wolfSSL | 13:f67a6c6013ca | 6289 | /* Make a copy of the identity data. */ |
wolfSSL | 13:f67a6c6013ca | 6290 | psk->identity = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 6291 | if (psk->identity == NULL) { |
wolfSSL | 13:f67a6c6013ca | 6292 | XFREE(psk, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 6293 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 6294 | } |
wolfSSL | 13:f67a6c6013ca | 6295 | XMEMCPY(psk->identity, identity, len); |
wolfSSL | 13:f67a6c6013ca | 6296 | psk->identityLen = len; |
wolfSSL | 13:f67a6c6013ca | 6297 | |
wolfSSL | 13:f67a6c6013ca | 6298 | /* Add it to the end and maintain the links. */ |
wolfSSL | 13:f67a6c6013ca | 6299 | while (*list != NULL) |
wolfSSL | 13:f67a6c6013ca | 6300 | list = &((*list)->next); |
wolfSSL | 13:f67a6c6013ca | 6301 | *list = psk; |
wolfSSL | 13:f67a6c6013ca | 6302 | *preSharedKey = psk; |
wolfSSL | 13:f67a6c6013ca | 6303 | |
wolfSSL | 13:f67a6c6013ca | 6304 | return 0; |
wolfSSL | 13:f67a6c6013ca | 6305 | } |
wolfSSL | 13:f67a6c6013ca | 6306 | |
wolfSSL | 13:f67a6c6013ca | 6307 | static INLINE byte GetHmacLength(int hmac) |
wolfSSL | 13:f67a6c6013ca | 6308 | { |
wolfSSL | 13:f67a6c6013ca | 6309 | switch (hmac) { |
wolfSSL | 13:f67a6c6013ca | 6310 | #ifndef NO_SHA256 |
wolfSSL | 13:f67a6c6013ca | 6311 | case sha256_mac: |
wolfSSL | 13:f67a6c6013ca | 6312 | return SHA256_DIGEST_SIZE; |
wolfSSL | 13:f67a6c6013ca | 6313 | #endif |
wolfSSL | 13:f67a6c6013ca | 6314 | #ifndef NO_SHA384 |
wolfSSL | 13:f67a6c6013ca | 6315 | case sha384_mac: |
wolfSSL | 13:f67a6c6013ca | 6316 | return SHA384_DIGEST_SIZE; |
wolfSSL | 13:f67a6c6013ca | 6317 | #endif |
wolfSSL | 13:f67a6c6013ca | 6318 | #ifndef NO_SHA512 |
wolfSSL | 13:f67a6c6013ca | 6319 | case sha512_mac: |
wolfSSL | 13:f67a6c6013ca | 6320 | return SHA512_DIGEST_SIZE; |
wolfSSL | 13:f67a6c6013ca | 6321 | #endif |
wolfSSL | 13:f67a6c6013ca | 6322 | } |
wolfSSL | 13:f67a6c6013ca | 6323 | return 0; |
wolfSSL | 13:f67a6c6013ca | 6324 | } |
wolfSSL | 13:f67a6c6013ca | 6325 | |
wolfSSL | 13:f67a6c6013ca | 6326 | /* Use the data to create a new pre-shared key object in the extensions. |
wolfSSL | 13:f67a6c6013ca | 6327 | * |
wolfSSL | 13:f67a6c6013ca | 6328 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 6329 | * identity The identity. |
wolfSSL | 13:f67a6c6013ca | 6330 | * len The length of the identity data. |
wolfSSL | 13:f67a6c6013ca | 6331 | * age The age of the identity. |
wolfSSL | 13:f67a6c6013ca | 6332 | * hmac The HMAC algorithm. |
wolfSSL | 13:f67a6c6013ca | 6333 | * ciphersuite0 The first byte of the ciphersuite to use. |
wolfSSL | 13:f67a6c6013ca | 6334 | * ciphersuite The second byte of the ciphersuite to use. |
wolfSSL | 13:f67a6c6013ca | 6335 | * resumption The PSK is for resumption of a session. |
wolfSSL | 13:f67a6c6013ca | 6336 | * preSharedKey The new pre-shared key object. |
wolfSSL | 13:f67a6c6013ca | 6337 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 6338 | */ |
wolfSSL | 13:f67a6c6013ca | 6339 | int TLSX_PreSharedKey_Use(WOLFSSL* ssl, byte* identity, word16 len, word32 age, |
wolfSSL | 13:f67a6c6013ca | 6340 | byte hmac, byte cipherSuite0, |
wolfSSL | 13:f67a6c6013ca | 6341 | byte cipherSuite, byte resumption, |
wolfSSL | 13:f67a6c6013ca | 6342 | PreSharedKey **preSharedKey) |
wolfSSL | 13:f67a6c6013ca | 6343 | { |
wolfSSL | 13:f67a6c6013ca | 6344 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 6345 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 6346 | PreSharedKey* psk = NULL; |
wolfSSL | 13:f67a6c6013ca | 6347 | |
wolfSSL | 13:f67a6c6013ca | 6348 | /* Find the pre-shared key extension if it exists. */ |
wolfSSL | 13:f67a6c6013ca | 6349 | extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY); |
wolfSSL | 13:f67a6c6013ca | 6350 | if (extension == NULL) { |
wolfSSL | 13:f67a6c6013ca | 6351 | /* Push new pre-shared key extension. */ |
wolfSSL | 13:f67a6c6013ca | 6352 | ret = TLSX_Push(&ssl->extensions, TLSX_PRE_SHARED_KEY, NULL, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 6353 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 6354 | return ret; |
wolfSSL | 13:f67a6c6013ca | 6355 | |
wolfSSL | 13:f67a6c6013ca | 6356 | extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY); |
wolfSSL | 13:f67a6c6013ca | 6357 | if (extension == NULL) |
wolfSSL | 13:f67a6c6013ca | 6358 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 6359 | } |
wolfSSL | 13:f67a6c6013ca | 6360 | |
wolfSSL | 13:f67a6c6013ca | 6361 | /* Try to find the pre-shared key with this identity. */ |
wolfSSL | 13:f67a6c6013ca | 6362 | psk = (PreSharedKey*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 6363 | while (psk != NULL) { |
wolfSSL | 13:f67a6c6013ca | 6364 | if ((psk->identityLen == len) && |
wolfSSL | 13:f67a6c6013ca | 6365 | (XMEMCMP(psk->identity, identity, len) == 0)) { |
wolfSSL | 13:f67a6c6013ca | 6366 | break; |
wolfSSL | 13:f67a6c6013ca | 6367 | } |
wolfSSL | 13:f67a6c6013ca | 6368 | psk = psk->next; |
wolfSSL | 13:f67a6c6013ca | 6369 | } |
wolfSSL | 13:f67a6c6013ca | 6370 | |
wolfSSL | 13:f67a6c6013ca | 6371 | /* Create a new pre-shared key object if not found. */ |
wolfSSL | 13:f67a6c6013ca | 6372 | if (psk == NULL) { |
wolfSSL | 13:f67a6c6013ca | 6373 | ret = TLSX_PreSharedKey_New((PreSharedKey**)&extension->data, identity, |
wolfSSL | 13:f67a6c6013ca | 6374 | len, ssl->heap, &psk); |
wolfSSL | 13:f67a6c6013ca | 6375 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 6376 | return ret; |
wolfSSL | 13:f67a6c6013ca | 6377 | } |
wolfSSL | 13:f67a6c6013ca | 6378 | |
wolfSSL | 13:f67a6c6013ca | 6379 | /* Update/set age and HMAC algorithm. */ |
wolfSSL | 13:f67a6c6013ca | 6380 | psk->ticketAge = age; |
wolfSSL | 13:f67a6c6013ca | 6381 | psk->hmac = hmac; |
wolfSSL | 13:f67a6c6013ca | 6382 | psk->cipherSuite0 = cipherSuite0; |
wolfSSL | 13:f67a6c6013ca | 6383 | psk->cipherSuite = cipherSuite; |
wolfSSL | 13:f67a6c6013ca | 6384 | psk->resumption = resumption; |
wolfSSL | 13:f67a6c6013ca | 6385 | psk->binderLen = GetHmacLength(psk->hmac); |
wolfSSL | 13:f67a6c6013ca | 6386 | |
wolfSSL | 13:f67a6c6013ca | 6387 | if (preSharedKey != NULL) |
wolfSSL | 13:f67a6c6013ca | 6388 | *preSharedKey = psk; |
wolfSSL | 13:f67a6c6013ca | 6389 | |
wolfSSL | 13:f67a6c6013ca | 6390 | return 0; |
wolfSSL | 13:f67a6c6013ca | 6391 | } |
wolfSSL | 13:f67a6c6013ca | 6392 | |
wolfSSL | 13:f67a6c6013ca | 6393 | #define PSK_FREE_ALL TLSX_PreSharedKey_FreeAll |
wolfSSL | 13:f67a6c6013ca | 6394 | #define PSK_GET_SIZE TLSX_PreSharedKey_GetSize |
wolfSSL | 13:f67a6c6013ca | 6395 | #define PSK_WRITE TLSX_PreSharedKey_Write |
wolfSSL | 13:f67a6c6013ca | 6396 | #define PSK_PARSE TLSX_PreSharedKey_Parse |
wolfSSL | 13:f67a6c6013ca | 6397 | |
wolfSSL | 13:f67a6c6013ca | 6398 | #else |
wolfSSL | 13:f67a6c6013ca | 6399 | |
wolfSSL | 13:f67a6c6013ca | 6400 | #define PSK_FREE_ALL(a, b) |
wolfSSL | 13:f67a6c6013ca | 6401 | #define PSK_GET_SIZE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 6402 | #define PSK_WRITE(a, b, c) 0 |
wolfSSL | 13:f67a6c6013ca | 6403 | #define PSK_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 6404 | |
wolfSSL | 13:f67a6c6013ca | 6405 | #endif |
wolfSSL | 13:f67a6c6013ca | 6406 | |
wolfSSL | 13:f67a6c6013ca | 6407 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 6408 | /* PSK Key Exchange Modes */ |
wolfSSL | 13:f67a6c6013ca | 6409 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 6410 | |
wolfSSL | 13:f67a6c6013ca | 6411 | #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)) |
wolfSSL | 13:f67a6c6013ca | 6412 | /* Get the size of the encoded PSK KE modes extension. |
wolfSSL | 13:f67a6c6013ca | 6413 | * Only in ClientHello. |
wolfSSL | 13:f67a6c6013ca | 6414 | * |
wolfSSL | 13:f67a6c6013ca | 6415 | * modes The PSK KE mode bit string. |
wolfSSL | 13:f67a6c6013ca | 6416 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:f67a6c6013ca | 6417 | * returns the number of bytes of the encoded PSK KE mode extension. |
wolfSSL | 13:f67a6c6013ca | 6418 | */ |
wolfSSL | 13:f67a6c6013ca | 6419 | static word16 TLSX_PskKeModes_GetSize(byte modes, byte msgType) |
wolfSSL | 13:f67a6c6013ca | 6420 | { |
wolfSSL | 13:f67a6c6013ca | 6421 | if (msgType == client_hello) { |
wolfSSL | 13:f67a6c6013ca | 6422 | /* Format: Len | Modes* */ |
wolfSSL | 13:f67a6c6013ca | 6423 | word16 len = OPAQUE8_LEN; |
wolfSSL | 13:f67a6c6013ca | 6424 | /* Check whether each possible mode is to be written. */ |
wolfSSL | 13:f67a6c6013ca | 6425 | if (modes & (1 << PSK_KE)) |
wolfSSL | 13:f67a6c6013ca | 6426 | len += OPAQUE8_LEN; |
wolfSSL | 13:f67a6c6013ca | 6427 | if (modes & (1 << PSK_DHE_KE)) |
wolfSSL | 13:f67a6c6013ca | 6428 | len += OPAQUE8_LEN; |
wolfSSL | 13:f67a6c6013ca | 6429 | return len; |
wolfSSL | 13:f67a6c6013ca | 6430 | } |
wolfSSL | 13:f67a6c6013ca | 6431 | |
wolfSSL | 13:f67a6c6013ca | 6432 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 6433 | } |
wolfSSL | 13:f67a6c6013ca | 6434 | |
wolfSSL | 13:f67a6c6013ca | 6435 | /* Writes the PSK KE modes extension into the output buffer. |
wolfSSL | 13:f67a6c6013ca | 6436 | * Assumes that the the output buffer is big enough to hold data. |
wolfSSL | 13:f67a6c6013ca | 6437 | * Only in ClientHello. |
wolfSSL | 13:f67a6c6013ca | 6438 | * |
wolfSSL | 13:f67a6c6013ca | 6439 | * modes The PSK KE mode bit string. |
wolfSSL | 13:f67a6c6013ca | 6440 | * output The buffer to write into. |
wolfSSL | 13:f67a6c6013ca | 6441 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:f67a6c6013ca | 6442 | * returns the number of bytes written into the buffer. |
wolfSSL | 13:f67a6c6013ca | 6443 | */ |
wolfSSL | 13:f67a6c6013ca | 6444 | static word16 TLSX_PskKeModes_Write(byte modes, byte* output, byte msgType) |
wolfSSL | 13:f67a6c6013ca | 6445 | { |
wolfSSL | 13:f67a6c6013ca | 6446 | if (msgType == client_hello) { |
wolfSSL | 13:f67a6c6013ca | 6447 | /* Format: Len | Modes* */ |
wolfSSL | 13:f67a6c6013ca | 6448 | int idx = OPAQUE8_LEN; |
wolfSSL | 13:f67a6c6013ca | 6449 | |
wolfSSL | 13:f67a6c6013ca | 6450 | /* Write out each possible mode. */ |
wolfSSL | 13:f67a6c6013ca | 6451 | if (modes & (1 << PSK_KE)) |
wolfSSL | 13:f67a6c6013ca | 6452 | output[idx++] = PSK_KE; |
wolfSSL | 13:f67a6c6013ca | 6453 | if (modes & (1 << PSK_DHE_KE)) |
wolfSSL | 13:f67a6c6013ca | 6454 | output[idx++] = PSK_DHE_KE; |
wolfSSL | 13:f67a6c6013ca | 6455 | /* Write out length of mode list. */ |
wolfSSL | 13:f67a6c6013ca | 6456 | output[0] = idx - OPAQUE8_LEN; |
wolfSSL | 13:f67a6c6013ca | 6457 | |
wolfSSL | 13:f67a6c6013ca | 6458 | return idx; |
wolfSSL | 13:f67a6c6013ca | 6459 | } |
wolfSSL | 13:f67a6c6013ca | 6460 | |
wolfSSL | 13:f67a6c6013ca | 6461 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 6462 | } |
wolfSSL | 13:f67a6c6013ca | 6463 | |
wolfSSL | 13:f67a6c6013ca | 6464 | /* Parse the PSK KE modes extension. |
wolfSSL | 13:f67a6c6013ca | 6465 | * Only in ClientHello. |
wolfSSL | 13:f67a6c6013ca | 6466 | * |
wolfSSL | 13:f67a6c6013ca | 6467 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 6468 | * input The extension data. |
wolfSSL | 13:f67a6c6013ca | 6469 | * length The length of the extension data. |
wolfSSL | 13:f67a6c6013ca | 6470 | * msgType The type of the message this extension is being parsed from. |
wolfSSL | 13:f67a6c6013ca | 6471 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 6472 | */ |
wolfSSL | 13:f67a6c6013ca | 6473 | static int TLSX_PskKeModes_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 6474 | byte msgType) |
wolfSSL | 13:f67a6c6013ca | 6475 | { |
wolfSSL | 13:f67a6c6013ca | 6476 | int ret; |
wolfSSL | 13:f67a6c6013ca | 6477 | |
wolfSSL | 13:f67a6c6013ca | 6478 | if (msgType == client_hello) { |
wolfSSL | 13:f67a6c6013ca | 6479 | /* Format: Len | Modes* */ |
wolfSSL | 13:f67a6c6013ca | 6480 | int idx = 0; |
wolfSSL | 13:f67a6c6013ca | 6481 | int len; |
wolfSSL | 13:f67a6c6013ca | 6482 | byte modes = 0; |
wolfSSL | 13:f67a6c6013ca | 6483 | |
wolfSSL | 13:f67a6c6013ca | 6484 | /* Ensure length byte exists. */ |
wolfSSL | 13:f67a6c6013ca | 6485 | if (length < OPAQUE8_LEN) |
wolfSSL | 13:f67a6c6013ca | 6486 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6487 | |
wolfSSL | 13:f67a6c6013ca | 6488 | /* Get length of mode list and ensure that is the only data. */ |
wolfSSL | 13:f67a6c6013ca | 6489 | len = input[0]; |
wolfSSL | 13:f67a6c6013ca | 6490 | if (length - OPAQUE8_LEN != len) |
wolfSSL | 13:f67a6c6013ca | 6491 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6492 | |
wolfSSL | 13:f67a6c6013ca | 6493 | idx = OPAQUE8_LEN; |
wolfSSL | 13:f67a6c6013ca | 6494 | /* Set a bit for each recognized modes. */ |
wolfSSL | 13:f67a6c6013ca | 6495 | while (len > 0) { |
wolfSSL | 13:f67a6c6013ca | 6496 | /* Ignore unrecognized modes. */ |
wolfSSL | 13:f67a6c6013ca | 6497 | if (input[idx] <= PSK_DHE_KE) |
wolfSSL | 13:f67a6c6013ca | 6498 | modes |= 1 << input[idx]; |
wolfSSL | 13:f67a6c6013ca | 6499 | idx++; |
wolfSSL | 13:f67a6c6013ca | 6500 | len--; |
wolfSSL | 13:f67a6c6013ca | 6501 | } |
wolfSSL | 13:f67a6c6013ca | 6502 | |
wolfSSL | 13:f67a6c6013ca | 6503 | ret = TLSX_PskKeModes_Use(ssl, modes); |
wolfSSL | 13:f67a6c6013ca | 6504 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 6505 | return ret; |
wolfSSL | 13:f67a6c6013ca | 6506 | |
wolfSSL | 13:f67a6c6013ca | 6507 | return 0; |
wolfSSL | 13:f67a6c6013ca | 6508 | } |
wolfSSL | 13:f67a6c6013ca | 6509 | |
wolfSSL | 13:f67a6c6013ca | 6510 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 6511 | } |
wolfSSL | 13:f67a6c6013ca | 6512 | |
wolfSSL | 13:f67a6c6013ca | 6513 | /* Use the data to create a new PSK Key Exchange Modes object in the extensions. |
wolfSSL | 13:f67a6c6013ca | 6514 | * |
wolfSSL | 13:f67a6c6013ca | 6515 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 6516 | * modes The PSK key exchange modes. |
wolfSSL | 13:f67a6c6013ca | 6517 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 6518 | */ |
wolfSSL | 13:f67a6c6013ca | 6519 | int TLSX_PskKeModes_Use(WOLFSSL* ssl, byte modes) |
wolfSSL | 13:f67a6c6013ca | 6520 | { |
wolfSSL | 13:f67a6c6013ca | 6521 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 6522 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 6523 | |
wolfSSL | 13:f67a6c6013ca | 6524 | /* Find the PSK key exchange modes extension if it exists. */ |
wolfSSL | 13:f67a6c6013ca | 6525 | extension = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES); |
wolfSSL | 13:f67a6c6013ca | 6526 | if (extension == NULL) { |
wolfSSL | 13:f67a6c6013ca | 6527 | /* Push new PSK key exchange modes extension. */ |
wolfSSL | 13:f67a6c6013ca | 6528 | ret = TLSX_Push(&ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES, NULL, |
wolfSSL | 13:f67a6c6013ca | 6529 | ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 6530 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 6531 | return ret; |
wolfSSL | 13:f67a6c6013ca | 6532 | |
wolfSSL | 13:f67a6c6013ca | 6533 | extension = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES); |
wolfSSL | 13:f67a6c6013ca | 6534 | if (extension == NULL) |
wolfSSL | 13:f67a6c6013ca | 6535 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 6536 | } |
wolfSSL | 13:f67a6c6013ca | 6537 | |
wolfSSL | 13:f67a6c6013ca | 6538 | extension->val = modes; |
wolfSSL | 13:f67a6c6013ca | 6539 | |
wolfSSL | 13:f67a6c6013ca | 6540 | return 0; |
wolfSSL | 13:f67a6c6013ca | 6541 | } |
wolfSSL | 13:f67a6c6013ca | 6542 | |
wolfSSL | 13:f67a6c6013ca | 6543 | #define PKM_GET_SIZE TLSX_PskKeModes_GetSize |
wolfSSL | 13:f67a6c6013ca | 6544 | #define PKM_WRITE TLSX_PskKeModes_Write |
wolfSSL | 13:f67a6c6013ca | 6545 | #define PKM_PARSE TLSX_PskKeModes_Parse |
wolfSSL | 13:f67a6c6013ca | 6546 | |
wolfSSL | 13:f67a6c6013ca | 6547 | #else |
wolfSSL | 13:f67a6c6013ca | 6548 | |
wolfSSL | 13:f67a6c6013ca | 6549 | #define PKM_GET_SIZE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 6550 | #define PKM_WRITE(a, b, c) 0 |
wolfSSL | 13:f67a6c6013ca | 6551 | #define PKM_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 6552 | |
wolfSSL | 13:f67a6c6013ca | 6553 | #endif |
wolfSSL | 13:f67a6c6013ca | 6554 | |
wolfSSL | 13:f67a6c6013ca | 6555 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 6556 | /* Post-Handshake Authentication */ |
wolfSSL | 13:f67a6c6013ca | 6557 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 6558 | |
wolfSSL | 13:f67a6c6013ca | 6559 | #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) |
wolfSSL | 13:f67a6c6013ca | 6560 | /* Get the size of the encoded Post-Hanshake Authentication extension. |
wolfSSL | 13:f67a6c6013ca | 6561 | * Only in ClientHello. |
wolfSSL | 13:f67a6c6013ca | 6562 | * |
wolfSSL | 13:f67a6c6013ca | 6563 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:f67a6c6013ca | 6564 | * returns the number of bytes of the encoded Post-Hanshake Authentication |
wolfSSL | 13:f67a6c6013ca | 6565 | * extension. |
wolfSSL | 13:f67a6c6013ca | 6566 | */ |
wolfSSL | 13:f67a6c6013ca | 6567 | static word16 TLSX_PostHandAuth_GetSize(byte msgType) |
wolfSSL | 13:f67a6c6013ca | 6568 | { |
wolfSSL | 13:f67a6c6013ca | 6569 | if (msgType == client_hello) |
wolfSSL | 13:f67a6c6013ca | 6570 | return OPAQUE8_LEN; |
wolfSSL | 13:f67a6c6013ca | 6571 | |
wolfSSL | 13:f67a6c6013ca | 6572 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 6573 | } |
wolfSSL | 13:f67a6c6013ca | 6574 | |
wolfSSL | 13:f67a6c6013ca | 6575 | /* Writes the Post-Handshake Authentication extension into the output buffer. |
wolfSSL | 13:f67a6c6013ca | 6576 | * Assumes that the the output buffer is big enough to hold data. |
wolfSSL | 13:f67a6c6013ca | 6577 | * Only in ClientHello. |
wolfSSL | 13:f67a6c6013ca | 6578 | * |
wolfSSL | 13:f67a6c6013ca | 6579 | * output The buffer to write into. |
wolfSSL | 13:f67a6c6013ca | 6580 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:f67a6c6013ca | 6581 | * returns the number of bytes written into the buffer. |
wolfSSL | 13:f67a6c6013ca | 6582 | */ |
wolfSSL | 13:f67a6c6013ca | 6583 | static word16 TLSX_PostHandAuth_Write(byte* output, byte msgType) |
wolfSSL | 13:f67a6c6013ca | 6584 | { |
wolfSSL | 13:f67a6c6013ca | 6585 | if (msgType == client_hello) { |
wolfSSL | 13:f67a6c6013ca | 6586 | *output = 0; |
wolfSSL | 13:f67a6c6013ca | 6587 | return OPAQUE8_LEN; |
wolfSSL | 13:f67a6c6013ca | 6588 | } |
wolfSSL | 13:f67a6c6013ca | 6589 | |
wolfSSL | 13:f67a6c6013ca | 6590 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 6591 | } |
wolfSSL | 13:f67a6c6013ca | 6592 | |
wolfSSL | 13:f67a6c6013ca | 6593 | /* Parse the Post-Handshake Authentication extension. |
wolfSSL | 13:f67a6c6013ca | 6594 | * Only in ClientHello. |
wolfSSL | 13:f67a6c6013ca | 6595 | * |
wolfSSL | 13:f67a6c6013ca | 6596 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 6597 | * input The extension data. |
wolfSSL | 13:f67a6c6013ca | 6598 | * length The length of the extension data. |
wolfSSL | 13:f67a6c6013ca | 6599 | * msgType The type of the message this extension is being parsed from. |
wolfSSL | 13:f67a6c6013ca | 6600 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 6601 | */ |
wolfSSL | 13:f67a6c6013ca | 6602 | static int TLSX_PostHandAuth_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 6603 | byte msgType) |
wolfSSL | 13:f67a6c6013ca | 6604 | { |
wolfSSL | 13:f67a6c6013ca | 6605 | byte len; |
wolfSSL | 13:f67a6c6013ca | 6606 | |
wolfSSL | 13:f67a6c6013ca | 6607 | if (msgType == client_hello) { |
wolfSSL | 13:f67a6c6013ca | 6608 | /* Ensure length byte exists. */ |
wolfSSL | 13:f67a6c6013ca | 6609 | if (length < OPAQUE8_LEN) |
wolfSSL | 13:f67a6c6013ca | 6610 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6611 | |
wolfSSL | 13:f67a6c6013ca | 6612 | len = input[0]; |
wolfSSL | 13:f67a6c6013ca | 6613 | if (length - OPAQUE8_LEN != len || len != 0) |
wolfSSL | 13:f67a6c6013ca | 6614 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6615 | |
wolfSSL | 13:f67a6c6013ca | 6616 | ssl->options.postHandshakeAuth = 1; |
wolfSSL | 13:f67a6c6013ca | 6617 | return 0; |
wolfSSL | 13:f67a6c6013ca | 6618 | } |
wolfSSL | 13:f67a6c6013ca | 6619 | |
wolfSSL | 13:f67a6c6013ca | 6620 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 6621 | } |
wolfSSL | 13:f67a6c6013ca | 6622 | |
wolfSSL | 13:f67a6c6013ca | 6623 | /* Create a new Post-handshake authentication object in the extensions. |
wolfSSL | 13:f67a6c6013ca | 6624 | * |
wolfSSL | 13:f67a6c6013ca | 6625 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 6626 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 6627 | */ |
wolfSSL | 13:f67a6c6013ca | 6628 | static int TLSX_PostHandAuth_Use(WOLFSSL* ssl) |
wolfSSL | 13:f67a6c6013ca | 6629 | { |
wolfSSL | 13:f67a6c6013ca | 6630 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 6631 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 6632 | |
wolfSSL | 13:f67a6c6013ca | 6633 | /* Find the PSK key exchange modes extension if it exists. */ |
wolfSSL | 13:f67a6c6013ca | 6634 | extension = TLSX_Find(ssl->extensions, TLSX_POST_HANDSHAKE_AUTH); |
wolfSSL | 13:f67a6c6013ca | 6635 | if (extension == NULL) { |
wolfSSL | 13:f67a6c6013ca | 6636 | /* Push new Post-handshake Authentication extension. */ |
wolfSSL | 13:f67a6c6013ca | 6637 | ret = TLSX_Push(&ssl->extensions, TLSX_POST_HANDSHAKE_AUTH, NULL, |
wolfSSL | 13:f67a6c6013ca | 6638 | ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 6639 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 6640 | return ret; |
wolfSSL | 13:f67a6c6013ca | 6641 | } |
wolfSSL | 13:f67a6c6013ca | 6642 | |
wolfSSL | 13:f67a6c6013ca | 6643 | return 0; |
wolfSSL | 13:f67a6c6013ca | 6644 | } |
wolfSSL | 13:f67a6c6013ca | 6645 | |
wolfSSL | 13:f67a6c6013ca | 6646 | #define PHA_GET_SIZE TLSX_PostHandAuth_GetSize |
wolfSSL | 13:f67a6c6013ca | 6647 | #define PHA_WRITE TLSX_PostHandAuth_Write |
wolfSSL | 13:f67a6c6013ca | 6648 | #define PHA_PARSE TLSX_PostHandAuth_Parse |
wolfSSL | 13:f67a6c6013ca | 6649 | |
wolfSSL | 13:f67a6c6013ca | 6650 | #else |
wolfSSL | 13:f67a6c6013ca | 6651 | |
wolfSSL | 13:f67a6c6013ca | 6652 | #define PHA_GET_SIZE(a) 0 |
wolfSSL | 13:f67a6c6013ca | 6653 | #define PHA_WRITE(a, b) 0 |
wolfSSL | 13:f67a6c6013ca | 6654 | #define PHA_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 6655 | |
wolfSSL | 13:f67a6c6013ca | 6656 | #endif |
wolfSSL | 13:f67a6c6013ca | 6657 | |
wolfSSL | 13:f67a6c6013ca | 6658 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 6659 | /* Early Data Indication */ |
wolfSSL | 13:f67a6c6013ca | 6660 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 6661 | |
wolfSSL | 13:f67a6c6013ca | 6662 | #ifdef WOLFSSL_EARLY_DATA |
wolfSSL | 13:f67a6c6013ca | 6663 | /* Get the size of the encoded Early Data Indication extension. |
wolfSSL | 13:f67a6c6013ca | 6664 | * In messages: ClientHello, EncryptedExtensions and NewSessionTicket. |
wolfSSL | 13:f67a6c6013ca | 6665 | * |
wolfSSL | 13:f67a6c6013ca | 6666 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:f67a6c6013ca | 6667 | * returns the number of bytes of the encoded Early Data Indication extension. |
wolfSSL | 13:f67a6c6013ca | 6668 | */ |
wolfSSL | 13:f67a6c6013ca | 6669 | static word16 TLSX_EarlyData_GetSize(byte msgType) |
wolfSSL | 13:f67a6c6013ca | 6670 | { |
wolfSSL | 13:f67a6c6013ca | 6671 | if (msgType == client_hello || msgType == encrypted_extensions) |
wolfSSL | 13:f67a6c6013ca | 6672 | return 0; |
wolfSSL | 13:f67a6c6013ca | 6673 | if (msgType == session_ticket) |
wolfSSL | 13:f67a6c6013ca | 6674 | return OPAQUE32_LEN; |
wolfSSL | 13:f67a6c6013ca | 6675 | |
wolfSSL | 13:f67a6c6013ca | 6676 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 6677 | } |
wolfSSL | 13:f67a6c6013ca | 6678 | |
wolfSSL | 13:f67a6c6013ca | 6679 | /* Writes the Early Data Indicator extension into the output buffer. |
wolfSSL | 13:f67a6c6013ca | 6680 | * Assumes that the the output buffer is big enough to hold data. |
wolfSSL | 13:f67a6c6013ca | 6681 | * In messages: ClientHello, EncryptedExtensions and NewSessionTicket. |
wolfSSL | 13:f67a6c6013ca | 6682 | * |
wolfSSL | 13:f67a6c6013ca | 6683 | * max The maximum early data size. |
wolfSSL | 13:f67a6c6013ca | 6684 | * output The buffer to write into. |
wolfSSL | 13:f67a6c6013ca | 6685 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:f67a6c6013ca | 6686 | * returns the number of bytes written into the buffer. |
wolfSSL | 13:f67a6c6013ca | 6687 | */ |
wolfSSL | 13:f67a6c6013ca | 6688 | static word16 TLSX_EarlyData_Write(word32 max, byte* output, byte msgType) |
wolfSSL | 13:f67a6c6013ca | 6689 | { |
wolfSSL | 13:f67a6c6013ca | 6690 | if (msgType == client_hello || msgType == encrypted_extensions) { |
wolfSSL | 13:f67a6c6013ca | 6691 | return 0; |
wolfSSL | 13:f67a6c6013ca | 6692 | } |
wolfSSL | 13:f67a6c6013ca | 6693 | if (msgType == session_ticket) { |
wolfSSL | 13:f67a6c6013ca | 6694 | c32toa(max, output); |
wolfSSL | 13:f67a6c6013ca | 6695 | return OPAQUE32_LEN; |
wolfSSL | 13:f67a6c6013ca | 6696 | } |
wolfSSL | 13:f67a6c6013ca | 6697 | |
wolfSSL | 13:f67a6c6013ca | 6698 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 6699 | } |
wolfSSL | 13:f67a6c6013ca | 6700 | |
wolfSSL | 13:f67a6c6013ca | 6701 | /* Parse the Early Data Indicator extension. |
wolfSSL | 13:f67a6c6013ca | 6702 | * In messages: ClientHello, EncryptedExtensions and NewSessionTicket. |
wolfSSL | 13:f67a6c6013ca | 6703 | * |
wolfSSL | 13:f67a6c6013ca | 6704 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 6705 | * input The extension data. |
wolfSSL | 13:f67a6c6013ca | 6706 | * length The length of the extension data. |
wolfSSL | 13:f67a6c6013ca | 6707 | * msgType The type of the message this extension is being parsed from. |
wolfSSL | 13:f67a6c6013ca | 6708 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 6709 | */ |
wolfSSL | 13:f67a6c6013ca | 6710 | static int TLSX_EarlyData_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:f67a6c6013ca | 6711 | byte msgType) |
wolfSSL | 13:f67a6c6013ca | 6712 | { |
wolfSSL | 13:f67a6c6013ca | 6713 | if (msgType == client_hello) { |
wolfSSL | 13:f67a6c6013ca | 6714 | if (length != 0) |
wolfSSL | 13:f67a6c6013ca | 6715 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6716 | |
wolfSSL | 13:f67a6c6013ca | 6717 | return TLSX_EarlyData_Use(ssl, 0); |
wolfSSL | 13:f67a6c6013ca | 6718 | } |
wolfSSL | 13:f67a6c6013ca | 6719 | if (msgType == encrypted_extensions) { |
wolfSSL | 13:f67a6c6013ca | 6720 | if (length != 0) |
wolfSSL | 13:f67a6c6013ca | 6721 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6722 | |
wolfSSL | 13:f67a6c6013ca | 6723 | return TLSX_EarlyData_Use(ssl, 1); |
wolfSSL | 13:f67a6c6013ca | 6724 | } |
wolfSSL | 13:f67a6c6013ca | 6725 | if (msgType == session_ticket) { |
wolfSSL | 13:f67a6c6013ca | 6726 | word32 max; |
wolfSSL | 13:f67a6c6013ca | 6727 | |
wolfSSL | 13:f67a6c6013ca | 6728 | if (length != OPAQUE32_LEN) |
wolfSSL | 13:f67a6c6013ca | 6729 | return BUFFER_E; |
wolfSSL | 13:f67a6c6013ca | 6730 | ato32(input, &max); |
wolfSSL | 13:f67a6c6013ca | 6731 | |
wolfSSL | 13:f67a6c6013ca | 6732 | ssl->session.maxEarlyDataSz = max; |
wolfSSL | 13:f67a6c6013ca | 6733 | return 0; |
wolfSSL | 13:f67a6c6013ca | 6734 | } |
wolfSSL | 13:f67a6c6013ca | 6735 | |
wolfSSL | 13:f67a6c6013ca | 6736 | return SANITY_MSG_E; |
wolfSSL | 13:f67a6c6013ca | 6737 | } |
wolfSSL | 13:f67a6c6013ca | 6738 | |
wolfSSL | 13:f67a6c6013ca | 6739 | /* Use the data to create a new Early Data object in the extensions. |
wolfSSL | 13:f67a6c6013ca | 6740 | * |
wolfSSL | 13:f67a6c6013ca | 6741 | * ssl The SSL/TLS object. |
wolfSSL | 13:f67a6c6013ca | 6742 | * max The maximum early data size. |
wolfSSL | 13:f67a6c6013ca | 6743 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:f67a6c6013ca | 6744 | */ |
wolfSSL | 13:f67a6c6013ca | 6745 | int TLSX_EarlyData_Use(WOLFSSL* ssl, word32 max) |
wolfSSL | 13:f67a6c6013ca | 6746 | { |
wolfSSL | 13:f67a6c6013ca | 6747 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 6748 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 6749 | |
wolfSSL | 13:f67a6c6013ca | 6750 | /* Find the early data extension if it exists. */ |
wolfSSL | 13:f67a6c6013ca | 6751 | extension = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA); |
wolfSSL | 13:f67a6c6013ca | 6752 | if (extension == NULL) { |
wolfSSL | 13:f67a6c6013ca | 6753 | /* Push new early data extension. */ |
wolfSSL | 13:f67a6c6013ca | 6754 | ret = TLSX_Push(&ssl->extensions, TLSX_EARLY_DATA, NULL, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 6755 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 6756 | return ret; |
wolfSSL | 13:f67a6c6013ca | 6757 | |
wolfSSL | 13:f67a6c6013ca | 6758 | extension = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA); |
wolfSSL | 13:f67a6c6013ca | 6759 | if (extension == NULL) |
wolfSSL | 13:f67a6c6013ca | 6760 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 6761 | } |
wolfSSL | 13:f67a6c6013ca | 6762 | |
wolfSSL | 13:f67a6c6013ca | 6763 | extension->resp = 1; |
wolfSSL | 13:f67a6c6013ca | 6764 | extension->val = max; |
wolfSSL | 13:f67a6c6013ca | 6765 | |
wolfSSL | 13:f67a6c6013ca | 6766 | return 0; |
wolfSSL | 13:f67a6c6013ca | 6767 | } |
wolfSSL | 13:f67a6c6013ca | 6768 | |
wolfSSL | 13:f67a6c6013ca | 6769 | #define EDI_GET_SIZE TLSX_EarlyData_GetSize |
wolfSSL | 13:f67a6c6013ca | 6770 | #define EDI_WRITE TLSX_EarlyData_Write |
wolfSSL | 13:f67a6c6013ca | 6771 | #define EDI_PARSE TLSX_EarlyData_Parse |
wolfSSL | 13:f67a6c6013ca | 6772 | |
wolfSSL | 13:f67a6c6013ca | 6773 | #else |
wolfSSL | 13:f67a6c6013ca | 6774 | |
wolfSSL | 13:f67a6c6013ca | 6775 | #define EDI_GET_SIZE(a) 0 |
wolfSSL | 13:f67a6c6013ca | 6776 | #define EDI_WRITE(a, b, c) 0 |
wolfSSL | 13:f67a6c6013ca | 6777 | #define EDI_PARSE(a, b, c, d) 0 |
wolfSSL | 13:f67a6c6013ca | 6778 | |
wolfSSL | 13:f67a6c6013ca | 6779 | #endif |
wolfSSL | 13:f67a6c6013ca | 6780 | |
wolfSSL | 13:f67a6c6013ca | 6781 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 6782 | /* TLS Extensions Framework */ |
wolfSSL | 13:f67a6c6013ca | 6783 | /******************************************************************************/ |
wolfSSL | 13:f67a6c6013ca | 6784 | |
wolfSSL | 13:f67a6c6013ca | 6785 | /** Finds an extension in the provided list. */ |
wolfSSL | 13:f67a6c6013ca | 6786 | TLSX* TLSX_Find(TLSX* list, TLSX_Type type) |
wolfSSL | 13:f67a6c6013ca | 6787 | { |
wolfSSL | 13:f67a6c6013ca | 6788 | TLSX* extension = list; |
wolfSSL | 13:f67a6c6013ca | 6789 | |
wolfSSL | 13:f67a6c6013ca | 6790 | while (extension && extension->type != type) |
wolfSSL | 13:f67a6c6013ca | 6791 | extension = extension->next; |
wolfSSL | 13:f67a6c6013ca | 6792 | |
wolfSSL | 13:f67a6c6013ca | 6793 | return extension; |
wolfSSL | 13:f67a6c6013ca | 6794 | } |
wolfSSL | 13:f67a6c6013ca | 6795 | |
wolfSSL | 13:f67a6c6013ca | 6796 | /** Releases all extensions in the provided list. */ |
wolfSSL | 13:f67a6c6013ca | 6797 | void TLSX_FreeAll(TLSX* list, void* heap) |
wolfSSL | 13:f67a6c6013ca | 6798 | { |
wolfSSL | 13:f67a6c6013ca | 6799 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 6800 | |
wolfSSL | 13:f67a6c6013ca | 6801 | while ((extension = list)) { |
wolfSSL | 13:f67a6c6013ca | 6802 | list = extension->next; |
wolfSSL | 13:f67a6c6013ca | 6803 | |
wolfSSL | 13:f67a6c6013ca | 6804 | switch (extension->type) { |
wolfSSL | 13:f67a6c6013ca | 6805 | |
wolfSSL | 13:f67a6c6013ca | 6806 | case TLSX_SERVER_NAME: |
wolfSSL | 13:f67a6c6013ca | 6807 | SNI_FREE_ALL((SNI*)extension->data, heap); |
wolfSSL | 13:f67a6c6013ca | 6808 | break; |
wolfSSL | 13:f67a6c6013ca | 6809 | |
wolfSSL | 13:f67a6c6013ca | 6810 | case TLSX_MAX_FRAGMENT_LENGTH: |
wolfSSL | 13:f67a6c6013ca | 6811 | MFL_FREE_ALL(extension->data, heap); |
wolfSSL | 13:f67a6c6013ca | 6812 | break; |
wolfSSL | 13:f67a6c6013ca | 6813 | |
wolfSSL | 13:f67a6c6013ca | 6814 | case TLSX_TRUNCATED_HMAC: |
wolfSSL | 13:f67a6c6013ca | 6815 | /* Nothing to do. */ |
wolfSSL | 13:f67a6c6013ca | 6816 | break; |
wolfSSL | 13:f67a6c6013ca | 6817 | |
wolfSSL | 13:f67a6c6013ca | 6818 | case TLSX_SUPPORTED_GROUPS: |
wolfSSL | 13:f67a6c6013ca | 6819 | EC_FREE_ALL((EllipticCurve*)extension->data, heap); |
wolfSSL | 13:f67a6c6013ca | 6820 | break; |
wolfSSL | 13:f67a6c6013ca | 6821 | |
wolfSSL | 13:f67a6c6013ca | 6822 | case TLSX_STATUS_REQUEST: |
wolfSSL | 13:f67a6c6013ca | 6823 | CSR_FREE_ALL((CertificateStatusRequest*)extension->data, heap); |
wolfSSL | 13:f67a6c6013ca | 6824 | break; |
wolfSSL | 13:f67a6c6013ca | 6825 | |
wolfSSL | 13:f67a6c6013ca | 6826 | case TLSX_STATUS_REQUEST_V2: |
wolfSSL | 13:f67a6c6013ca | 6827 | CSR2_FREE_ALL((CertificateStatusRequestItemV2*)extension->data, |
wolfSSL | 13:f67a6c6013ca | 6828 | heap); |
wolfSSL | 13:f67a6c6013ca | 6829 | break; |
wolfSSL | 13:f67a6c6013ca | 6830 | |
wolfSSL | 13:f67a6c6013ca | 6831 | case TLSX_RENEGOTIATION_INFO: |
wolfSSL | 13:f67a6c6013ca | 6832 | SCR_FREE_ALL(extension->data, heap); |
wolfSSL | 13:f67a6c6013ca | 6833 | break; |
wolfSSL | 13:f67a6c6013ca | 6834 | |
wolfSSL | 13:f67a6c6013ca | 6835 | case TLSX_SESSION_TICKET: |
wolfSSL | 13:f67a6c6013ca | 6836 | WOLF_STK_FREE(extension->data, heap); |
wolfSSL | 13:f67a6c6013ca | 6837 | break; |
wolfSSL | 13:f67a6c6013ca | 6838 | |
wolfSSL | 13:f67a6c6013ca | 6839 | case TLSX_QUANTUM_SAFE_HYBRID: |
wolfSSL | 13:f67a6c6013ca | 6840 | QSH_FREE_ALL((QSHScheme*)extension->data, heap); |
wolfSSL | 13:f67a6c6013ca | 6841 | break; |
wolfSSL | 13:f67a6c6013ca | 6842 | |
wolfSSL | 13:f67a6c6013ca | 6843 | case TLSX_APPLICATION_LAYER_PROTOCOL: |
wolfSSL | 13:f67a6c6013ca | 6844 | ALPN_FREE_ALL((ALPN*)extension->data, heap); |
wolfSSL | 13:f67a6c6013ca | 6845 | break; |
wolfSSL | 13:f67a6c6013ca | 6846 | |
wolfSSL | 13:f67a6c6013ca | 6847 | case TLSX_SIGNATURE_ALGORITHMS: |
wolfSSL | 13:f67a6c6013ca | 6848 | break; |
wolfSSL | 13:f67a6c6013ca | 6849 | |
wolfSSL | 13:f67a6c6013ca | 6850 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 6851 | case TLSX_SUPPORTED_VERSIONS: |
wolfSSL | 13:f67a6c6013ca | 6852 | break; |
wolfSSL | 13:f67a6c6013ca | 6853 | |
wolfSSL | 13:f67a6c6013ca | 6854 | case TLSX_COOKIE: |
wolfSSL | 13:f67a6c6013ca | 6855 | CKE_FREE_ALL((Cookie*)extension->data, heap); |
wolfSSL | 13:f67a6c6013ca | 6856 | break; |
wolfSSL | 13:f67a6c6013ca | 6857 | |
wolfSSL | 13:f67a6c6013ca | 6858 | case TLSX_KEY_SHARE: |
wolfSSL | 13:f67a6c6013ca | 6859 | KS_FREE_ALL((KeyShareEntry*)extension->data, heap); |
wolfSSL | 13:f67a6c6013ca | 6860 | break; |
wolfSSL | 13:f67a6c6013ca | 6861 | |
wolfSSL | 13:f67a6c6013ca | 6862 | #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) |
wolfSSL | 13:f67a6c6013ca | 6863 | case TLSX_PRE_SHARED_KEY: |
wolfSSL | 13:f67a6c6013ca | 6864 | PSK_FREE_ALL((PreSharedKey*)extension->data, heap); |
wolfSSL | 13:f67a6c6013ca | 6865 | break; |
wolfSSL | 13:f67a6c6013ca | 6866 | |
wolfSSL | 13:f67a6c6013ca | 6867 | case TLSX_PSK_KEY_EXCHANGE_MODES: |
wolfSSL | 13:f67a6c6013ca | 6868 | break; |
wolfSSL | 13:f67a6c6013ca | 6869 | #endif |
wolfSSL | 13:f67a6c6013ca | 6870 | |
wolfSSL | 13:f67a6c6013ca | 6871 | #ifdef WOLFSSL_EARLY_DATA |
wolfSSL | 13:f67a6c6013ca | 6872 | case TLSX_EARLY_DATA: |
wolfSSL | 13:f67a6c6013ca | 6873 | break; |
wolfSSL | 13:f67a6c6013ca | 6874 | #endif |
wolfSSL | 13:f67a6c6013ca | 6875 | |
wolfSSL | 13:f67a6c6013ca | 6876 | #ifdef WOLFSSL_POST_HANDSHAKE_AUTH |
wolfSSL | 13:f67a6c6013ca | 6877 | case TLSX_POST_HANDSHAKE_AUTH: |
wolfSSL | 13:f67a6c6013ca | 6878 | break; |
wolfSSL | 13:f67a6c6013ca | 6879 | #endif |
wolfSSL | 13:f67a6c6013ca | 6880 | #endif |
wolfSSL | 13:f67a6c6013ca | 6881 | } |
wolfSSL | 13:f67a6c6013ca | 6882 | |
wolfSSL | 13:f67a6c6013ca | 6883 | XFREE(extension, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:f67a6c6013ca | 6884 | } |
wolfSSL | 13:f67a6c6013ca | 6885 | |
wolfSSL | 13:f67a6c6013ca | 6886 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 6887 | } |
wolfSSL | 13:f67a6c6013ca | 6888 | |
wolfSSL | 13:f67a6c6013ca | 6889 | /** Checks if the tls extensions are supported based on the protocol version. */ |
wolfSSL | 13:f67a6c6013ca | 6890 | int TLSX_SupportExtensions(WOLFSSL* ssl) { |
wolfSSL | 13:f67a6c6013ca | 6891 | return ssl && (IsTLS(ssl) || ssl->version.major == DTLS_MAJOR); |
wolfSSL | 13:f67a6c6013ca | 6892 | } |
wolfSSL | 13:f67a6c6013ca | 6893 | |
wolfSSL | 13:f67a6c6013ca | 6894 | /** Tells the buffered size of the extensions in a list. */ |
wolfSSL | 13:f67a6c6013ca | 6895 | static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType) |
wolfSSL | 13:f67a6c6013ca | 6896 | { |
wolfSSL | 13:f67a6c6013ca | 6897 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 6898 | word16 length = 0; |
wolfSSL | 13:f67a6c6013ca | 6899 | byte isRequest = (msgType == client_hello || |
wolfSSL | 13:f67a6c6013ca | 6900 | msgType == certificate_request); |
wolfSSL | 13:f67a6c6013ca | 6901 | |
wolfSSL | 13:f67a6c6013ca | 6902 | while ((extension = list)) { |
wolfSSL | 13:f67a6c6013ca | 6903 | list = extension->next; |
wolfSSL | 13:f67a6c6013ca | 6904 | |
wolfSSL | 13:f67a6c6013ca | 6905 | /* only extensions marked as response are sent back to the client. */ |
wolfSSL | 13:f67a6c6013ca | 6906 | if (!isRequest && !extension->resp) |
wolfSSL | 13:f67a6c6013ca | 6907 | continue; /* skip! */ |
wolfSSL | 13:f67a6c6013ca | 6908 | |
wolfSSL | 13:f67a6c6013ca | 6909 | /* ssl level extensions are expected to override ctx level ones. */ |
wolfSSL | 13:f67a6c6013ca | 6910 | if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type))) |
wolfSSL | 13:f67a6c6013ca | 6911 | continue; /* skip! */ |
wolfSSL | 13:f67a6c6013ca | 6912 | |
wolfSSL | 13:f67a6c6013ca | 6913 | /* extension type + extension data length. */ |
wolfSSL | 13:f67a6c6013ca | 6914 | length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 6915 | |
wolfSSL | 13:f67a6c6013ca | 6916 | |
wolfSSL | 13:f67a6c6013ca | 6917 | switch (extension->type) { |
wolfSSL | 13:f67a6c6013ca | 6918 | |
wolfSSL | 13:f67a6c6013ca | 6919 | case TLSX_SERVER_NAME: |
wolfSSL | 13:f67a6c6013ca | 6920 | /* SNI only sends the name on the request. */ |
wolfSSL | 13:f67a6c6013ca | 6921 | if (isRequest) |
wolfSSL | 13:f67a6c6013ca | 6922 | length += SNI_GET_SIZE((SNI*)extension->data); |
wolfSSL | 13:f67a6c6013ca | 6923 | break; |
wolfSSL | 13:f67a6c6013ca | 6924 | |
wolfSSL | 13:f67a6c6013ca | 6925 | case TLSX_MAX_FRAGMENT_LENGTH: |
wolfSSL | 13:f67a6c6013ca | 6926 | length += MFL_GET_SIZE(extension->data); |
wolfSSL | 13:f67a6c6013ca | 6927 | break; |
wolfSSL | 13:f67a6c6013ca | 6928 | |
wolfSSL | 13:f67a6c6013ca | 6929 | case TLSX_TRUNCATED_HMAC: |
wolfSSL | 13:f67a6c6013ca | 6930 | /* always empty. */ |
wolfSSL | 13:f67a6c6013ca | 6931 | break; |
wolfSSL | 13:f67a6c6013ca | 6932 | |
wolfSSL | 13:f67a6c6013ca | 6933 | case TLSX_SUPPORTED_GROUPS: |
wolfSSL | 13:f67a6c6013ca | 6934 | length += EC_GET_SIZE((EllipticCurve*)extension->data); |
wolfSSL | 13:f67a6c6013ca | 6935 | break; |
wolfSSL | 13:f67a6c6013ca | 6936 | |
wolfSSL | 13:f67a6c6013ca | 6937 | case TLSX_STATUS_REQUEST: |
wolfSSL | 13:f67a6c6013ca | 6938 | length += CSR_GET_SIZE( |
wolfSSL | 13:f67a6c6013ca | 6939 | (CertificateStatusRequest*)extension->data, isRequest); |
wolfSSL | 13:f67a6c6013ca | 6940 | break; |
wolfSSL | 13:f67a6c6013ca | 6941 | |
wolfSSL | 13:f67a6c6013ca | 6942 | case TLSX_STATUS_REQUEST_V2: |
wolfSSL | 13:f67a6c6013ca | 6943 | length += CSR2_GET_SIZE( |
wolfSSL | 13:f67a6c6013ca | 6944 | (CertificateStatusRequestItemV2*)extension->data, |
wolfSSL | 13:f67a6c6013ca | 6945 | isRequest); |
wolfSSL | 13:f67a6c6013ca | 6946 | break; |
wolfSSL | 13:f67a6c6013ca | 6947 | |
wolfSSL | 13:f67a6c6013ca | 6948 | case TLSX_RENEGOTIATION_INFO: |
wolfSSL | 13:f67a6c6013ca | 6949 | length += SCR_GET_SIZE((SecureRenegotiation*)extension->data, |
wolfSSL | 13:f67a6c6013ca | 6950 | isRequest); |
wolfSSL | 13:f67a6c6013ca | 6951 | break; |
wolfSSL | 13:f67a6c6013ca | 6952 | |
wolfSSL | 13:f67a6c6013ca | 6953 | case TLSX_SESSION_TICKET: |
wolfSSL | 13:f67a6c6013ca | 6954 | length += WOLF_STK_GET_SIZE((SessionTicket*)extension->data, |
wolfSSL | 13:f67a6c6013ca | 6955 | isRequest); |
wolfSSL | 13:f67a6c6013ca | 6956 | break; |
wolfSSL | 13:f67a6c6013ca | 6957 | |
wolfSSL | 13:f67a6c6013ca | 6958 | case TLSX_QUANTUM_SAFE_HYBRID: |
wolfSSL | 13:f67a6c6013ca | 6959 | length += QSH_GET_SIZE((QSHScheme*)extension->data, isRequest); |
wolfSSL | 13:f67a6c6013ca | 6960 | break; |
wolfSSL | 13:f67a6c6013ca | 6961 | |
wolfSSL | 13:f67a6c6013ca | 6962 | case TLSX_APPLICATION_LAYER_PROTOCOL: |
wolfSSL | 13:f67a6c6013ca | 6963 | length += ALPN_GET_SIZE((ALPN*)extension->data); |
wolfSSL | 13:f67a6c6013ca | 6964 | break; |
wolfSSL | 13:f67a6c6013ca | 6965 | |
wolfSSL | 13:f67a6c6013ca | 6966 | case TLSX_SIGNATURE_ALGORITHMS: |
wolfSSL | 13:f67a6c6013ca | 6967 | length += SA_GET_SIZE(extension->data); |
wolfSSL | 13:f67a6c6013ca | 6968 | break; |
wolfSSL | 13:f67a6c6013ca | 6969 | |
wolfSSL | 13:f67a6c6013ca | 6970 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 6971 | case TLSX_SUPPORTED_VERSIONS: |
wolfSSL | 13:f67a6c6013ca | 6972 | length += SV_GET_SIZE(extension->data); |
wolfSSL | 13:f67a6c6013ca | 6973 | break; |
wolfSSL | 13:f67a6c6013ca | 6974 | |
wolfSSL | 13:f67a6c6013ca | 6975 | case TLSX_COOKIE: |
wolfSSL | 13:f67a6c6013ca | 6976 | length += CKE_GET_SIZE((Cookie*)extension->data, msgType); |
wolfSSL | 13:f67a6c6013ca | 6977 | break; |
wolfSSL | 13:f67a6c6013ca | 6978 | |
wolfSSL | 13:f67a6c6013ca | 6979 | case TLSX_KEY_SHARE: |
wolfSSL | 13:f67a6c6013ca | 6980 | length += KS_GET_SIZE((KeyShareEntry*)extension->data, msgType); |
wolfSSL | 13:f67a6c6013ca | 6981 | break; |
wolfSSL | 13:f67a6c6013ca | 6982 | |
wolfSSL | 13:f67a6c6013ca | 6983 | #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) |
wolfSSL | 13:f67a6c6013ca | 6984 | case TLSX_PRE_SHARED_KEY: |
wolfSSL | 13:f67a6c6013ca | 6985 | length += PSK_GET_SIZE((PreSharedKey*)extension->data, msgType); |
wolfSSL | 13:f67a6c6013ca | 6986 | break; |
wolfSSL | 13:f67a6c6013ca | 6987 | |
wolfSSL | 13:f67a6c6013ca | 6988 | case TLSX_PSK_KEY_EXCHANGE_MODES: |
wolfSSL | 13:f67a6c6013ca | 6989 | length += PKM_GET_SIZE(extension->val, msgType); |
wolfSSL | 13:f67a6c6013ca | 6990 | break; |
wolfSSL | 13:f67a6c6013ca | 6991 | #endif |
wolfSSL | 13:f67a6c6013ca | 6992 | |
wolfSSL | 13:f67a6c6013ca | 6993 | #ifdef WOLFSSL_EARLY_DATA |
wolfSSL | 13:f67a6c6013ca | 6994 | case TLSX_EARLY_DATA: |
wolfSSL | 13:f67a6c6013ca | 6995 | length += EDI_GET_SIZE(msgType); |
wolfSSL | 13:f67a6c6013ca | 6996 | break; |
wolfSSL | 13:f67a6c6013ca | 6997 | #endif |
wolfSSL | 13:f67a6c6013ca | 6998 | |
wolfSSL | 13:f67a6c6013ca | 6999 | #ifdef WOLFSSL_POST_HANDSHAKE_AUTH |
wolfSSL | 13:f67a6c6013ca | 7000 | case TLSX_POST_HANDSHAKE_AUTH: |
wolfSSL | 13:f67a6c6013ca | 7001 | length += PHA_GET_SIZE(msgType); |
wolfSSL | 13:f67a6c6013ca | 7002 | break; |
wolfSSL | 13:f67a6c6013ca | 7003 | #endif |
wolfSSL | 13:f67a6c6013ca | 7004 | #endif |
wolfSSL | 13:f67a6c6013ca | 7005 | } |
wolfSSL | 13:f67a6c6013ca | 7006 | |
wolfSSL | 13:f67a6c6013ca | 7007 | /* marks the extension as processed so ctx level */ |
wolfSSL | 13:f67a6c6013ca | 7008 | /* extensions don't overlap with ssl level ones. */ |
wolfSSL | 13:f67a6c6013ca | 7009 | TURN_ON(semaphore, TLSX_ToSemaphore(extension->type)); |
wolfSSL | 13:f67a6c6013ca | 7010 | } |
wolfSSL | 13:f67a6c6013ca | 7011 | |
wolfSSL | 13:f67a6c6013ca | 7012 | return length; |
wolfSSL | 13:f67a6c6013ca | 7013 | } |
wolfSSL | 13:f67a6c6013ca | 7014 | |
wolfSSL | 13:f67a6c6013ca | 7015 | /** Writes the extensions of a list in a buffer. */ |
wolfSSL | 13:f67a6c6013ca | 7016 | static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore, |
wolfSSL | 13:f67a6c6013ca | 7017 | byte msgType) |
wolfSSL | 13:f67a6c6013ca | 7018 | { |
wolfSSL | 13:f67a6c6013ca | 7019 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 7020 | word16 offset = 0; |
wolfSSL | 13:f67a6c6013ca | 7021 | word16 length_offset = 0; |
wolfSSL | 13:f67a6c6013ca | 7022 | byte isRequest = (msgType == client_hello || |
wolfSSL | 13:f67a6c6013ca | 7023 | msgType == certificate_request); |
wolfSSL | 13:f67a6c6013ca | 7024 | |
wolfSSL | 13:f67a6c6013ca | 7025 | while ((extension = list)) { |
wolfSSL | 13:f67a6c6013ca | 7026 | list = extension->next; |
wolfSSL | 13:f67a6c6013ca | 7027 | |
wolfSSL | 13:f67a6c6013ca | 7028 | /* only extensions marked as response are written in a response. */ |
wolfSSL | 13:f67a6c6013ca | 7029 | if (!isRequest && !extension->resp) |
wolfSSL | 13:f67a6c6013ca | 7030 | continue; /* skip! */ |
wolfSSL | 13:f67a6c6013ca | 7031 | |
wolfSSL | 13:f67a6c6013ca | 7032 | /* ssl level extensions are expected to override ctx level ones. */ |
wolfSSL | 13:f67a6c6013ca | 7033 | if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type))) |
wolfSSL | 13:f67a6c6013ca | 7034 | continue; /* skip! */ |
wolfSSL | 13:f67a6c6013ca | 7035 | |
wolfSSL | 13:f67a6c6013ca | 7036 | /* writes extension type. */ |
wolfSSL | 13:f67a6c6013ca | 7037 | c16toa(extension->type, output + offset); |
wolfSSL | 13:f67a6c6013ca | 7038 | offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 7039 | length_offset = offset; |
wolfSSL | 13:f67a6c6013ca | 7040 | |
wolfSSL | 13:f67a6c6013ca | 7041 | /* extension data should be written internally. */ |
wolfSSL | 13:f67a6c6013ca | 7042 | switch (extension->type) { |
wolfSSL | 13:f67a6c6013ca | 7043 | case TLSX_SERVER_NAME: |
wolfSSL | 13:f67a6c6013ca | 7044 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 7045 | WOLFSSL_MSG("SNI extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7046 | offset += SNI_WRITE((SNI*)extension->data, output + offset); |
wolfSSL | 13:f67a6c6013ca | 7047 | } |
wolfSSL | 13:f67a6c6013ca | 7048 | break; |
wolfSSL | 13:f67a6c6013ca | 7049 | |
wolfSSL | 13:f67a6c6013ca | 7050 | case TLSX_MAX_FRAGMENT_LENGTH: |
wolfSSL | 13:f67a6c6013ca | 7051 | WOLFSSL_MSG("Max Fragment Length extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7052 | offset += MFL_WRITE((byte*)extension->data, output + offset); |
wolfSSL | 13:f67a6c6013ca | 7053 | break; |
wolfSSL | 13:f67a6c6013ca | 7054 | |
wolfSSL | 13:f67a6c6013ca | 7055 | case TLSX_TRUNCATED_HMAC: |
wolfSSL | 13:f67a6c6013ca | 7056 | WOLFSSL_MSG("Truncated HMAC extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7057 | /* always empty. */ |
wolfSSL | 13:f67a6c6013ca | 7058 | break; |
wolfSSL | 13:f67a6c6013ca | 7059 | |
wolfSSL | 13:f67a6c6013ca | 7060 | case TLSX_SUPPORTED_GROUPS: |
wolfSSL | 13:f67a6c6013ca | 7061 | WOLFSSL_MSG("Elliptic Curves extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7062 | offset += EC_WRITE((EllipticCurve*)extension->data, |
wolfSSL | 13:f67a6c6013ca | 7063 | output + offset); |
wolfSSL | 13:f67a6c6013ca | 7064 | break; |
wolfSSL | 13:f67a6c6013ca | 7065 | |
wolfSSL | 13:f67a6c6013ca | 7066 | case TLSX_STATUS_REQUEST: |
wolfSSL | 13:f67a6c6013ca | 7067 | WOLFSSL_MSG("Certificate Status Request extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7068 | offset += CSR_WRITE((CertificateStatusRequest*)extension->data, |
wolfSSL | 13:f67a6c6013ca | 7069 | output + offset, isRequest); |
wolfSSL | 13:f67a6c6013ca | 7070 | break; |
wolfSSL | 13:f67a6c6013ca | 7071 | |
wolfSSL | 13:f67a6c6013ca | 7072 | case TLSX_STATUS_REQUEST_V2: |
wolfSSL | 13:f67a6c6013ca | 7073 | WOLFSSL_MSG("Certificate Status Request v2 extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7074 | offset += CSR2_WRITE( |
wolfSSL | 13:f67a6c6013ca | 7075 | (CertificateStatusRequestItemV2*)extension->data, |
wolfSSL | 13:f67a6c6013ca | 7076 | output + offset, isRequest); |
wolfSSL | 13:f67a6c6013ca | 7077 | break; |
wolfSSL | 13:f67a6c6013ca | 7078 | |
wolfSSL | 13:f67a6c6013ca | 7079 | case TLSX_RENEGOTIATION_INFO: |
wolfSSL | 13:f67a6c6013ca | 7080 | WOLFSSL_MSG("Secure Renegotiation extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7081 | offset += SCR_WRITE((SecureRenegotiation*)extension->data, |
wolfSSL | 13:f67a6c6013ca | 7082 | output + offset, isRequest); |
wolfSSL | 13:f67a6c6013ca | 7083 | break; |
wolfSSL | 13:f67a6c6013ca | 7084 | |
wolfSSL | 13:f67a6c6013ca | 7085 | case TLSX_SESSION_TICKET: |
wolfSSL | 13:f67a6c6013ca | 7086 | WOLFSSL_MSG("Session Ticket extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7087 | offset += WOLF_STK_WRITE((SessionTicket*)extension->data, |
wolfSSL | 13:f67a6c6013ca | 7088 | output + offset, isRequest); |
wolfSSL | 13:f67a6c6013ca | 7089 | break; |
wolfSSL | 13:f67a6c6013ca | 7090 | |
wolfSSL | 13:f67a6c6013ca | 7091 | case TLSX_QUANTUM_SAFE_HYBRID: |
wolfSSL | 13:f67a6c6013ca | 7092 | WOLFSSL_MSG("Quantum-Safe-Hybrid extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7093 | if (isRequest) { |
wolfSSL | 13:f67a6c6013ca | 7094 | offset += QSH_WRITE((QSHScheme*)extension->data, output + offset); |
wolfSSL | 13:f67a6c6013ca | 7095 | } |
wolfSSL | 13:f67a6c6013ca | 7096 | offset += QSHPK_WRITE((QSHScheme*)extension->data, output + offset); |
wolfSSL | 13:f67a6c6013ca | 7097 | offset += QSH_SERREQ(output + offset, isRequest); |
wolfSSL | 13:f67a6c6013ca | 7098 | break; |
wolfSSL | 13:f67a6c6013ca | 7099 | |
wolfSSL | 13:f67a6c6013ca | 7100 | case TLSX_APPLICATION_LAYER_PROTOCOL: |
wolfSSL | 13:f67a6c6013ca | 7101 | WOLFSSL_MSG("ALPN extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7102 | offset += ALPN_WRITE((ALPN*)extension->data, output + offset); |
wolfSSL | 13:f67a6c6013ca | 7103 | break; |
wolfSSL | 13:f67a6c6013ca | 7104 | |
wolfSSL | 13:f67a6c6013ca | 7105 | case TLSX_SIGNATURE_ALGORITHMS: |
wolfSSL | 13:f67a6c6013ca | 7106 | WOLFSSL_MSG("Signature Algorithms extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7107 | offset += SA_WRITE(extension->data, output + offset); |
wolfSSL | 13:f67a6c6013ca | 7108 | break; |
wolfSSL | 13:f67a6c6013ca | 7109 | |
wolfSSL | 13:f67a6c6013ca | 7110 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 7111 | case TLSX_SUPPORTED_VERSIONS: |
wolfSSL | 13:f67a6c6013ca | 7112 | WOLFSSL_MSG("Supported Versions extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7113 | offset += SV_WRITE(extension->data, output + offset); |
wolfSSL | 13:f67a6c6013ca | 7114 | break; |
wolfSSL | 13:f67a6c6013ca | 7115 | |
wolfSSL | 13:f67a6c6013ca | 7116 | case TLSX_COOKIE: |
wolfSSL | 13:f67a6c6013ca | 7117 | WOLFSSL_MSG("Cookie extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7118 | offset += CKE_WRITE((Cookie*)extension->data, output + offset, |
wolfSSL | 13:f67a6c6013ca | 7119 | msgType); |
wolfSSL | 13:f67a6c6013ca | 7120 | break; |
wolfSSL | 13:f67a6c6013ca | 7121 | |
wolfSSL | 13:f67a6c6013ca | 7122 | case TLSX_KEY_SHARE: |
wolfSSL | 13:f67a6c6013ca | 7123 | WOLFSSL_MSG("Key Share extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7124 | offset += KS_WRITE((KeyShareEntry*)extension->data, |
wolfSSL | 13:f67a6c6013ca | 7125 | output + offset, msgType); |
wolfSSL | 13:f67a6c6013ca | 7126 | break; |
wolfSSL | 13:f67a6c6013ca | 7127 | |
wolfSSL | 13:f67a6c6013ca | 7128 | #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) |
wolfSSL | 13:f67a6c6013ca | 7129 | case TLSX_PRE_SHARED_KEY: |
wolfSSL | 13:f67a6c6013ca | 7130 | WOLFSSL_MSG("Pre-Shared Key extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7131 | offset += PSK_WRITE((PreSharedKey*)extension->data, |
wolfSSL | 13:f67a6c6013ca | 7132 | output + offset, msgType); |
wolfSSL | 13:f67a6c6013ca | 7133 | break; |
wolfSSL | 13:f67a6c6013ca | 7134 | |
wolfSSL | 13:f67a6c6013ca | 7135 | case TLSX_PSK_KEY_EXCHANGE_MODES: |
wolfSSL | 13:f67a6c6013ca | 7136 | WOLFSSL_MSG("PSK Key Exchange Modes extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7137 | offset += PKM_WRITE(extension->val, output + offset, msgType); |
wolfSSL | 13:f67a6c6013ca | 7138 | break; |
wolfSSL | 13:f67a6c6013ca | 7139 | #endif |
wolfSSL | 13:f67a6c6013ca | 7140 | |
wolfSSL | 13:f67a6c6013ca | 7141 | #ifdef WOLFSSL_EARLY_DATA |
wolfSSL | 13:f67a6c6013ca | 7142 | case TLSX_EARLY_DATA: |
wolfSSL | 13:f67a6c6013ca | 7143 | WOLFSSL_MSG("Early Data extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7144 | offset += EDI_WRITE(extension->val, output + offset, msgType); |
wolfSSL | 13:f67a6c6013ca | 7145 | break; |
wolfSSL | 13:f67a6c6013ca | 7146 | #endif |
wolfSSL | 13:f67a6c6013ca | 7147 | |
wolfSSL | 13:f67a6c6013ca | 7148 | #ifdef WOLFSSL_POST_HANDSHAKE_AUTH |
wolfSSL | 13:f67a6c6013ca | 7149 | case TLSX_POST_HANDSHAKE_AUTH: |
wolfSSL | 13:f67a6c6013ca | 7150 | WOLFSSL_MSG("Post-Handshake Authentication extension to write"); |
wolfSSL | 13:f67a6c6013ca | 7151 | offset += PHA_WRITE(output + offset, msgType); |
wolfSSL | 13:f67a6c6013ca | 7152 | break; |
wolfSSL | 13:f67a6c6013ca | 7153 | #endif |
wolfSSL | 13:f67a6c6013ca | 7154 | #endif |
wolfSSL | 13:f67a6c6013ca | 7155 | } |
wolfSSL | 13:f67a6c6013ca | 7156 | |
wolfSSL | 13:f67a6c6013ca | 7157 | /* writes extension data length. */ |
wolfSSL | 13:f67a6c6013ca | 7158 | c16toa(offset - length_offset, output + length_offset - OPAQUE16_LEN); |
wolfSSL | 13:f67a6c6013ca | 7159 | |
wolfSSL | 13:f67a6c6013ca | 7160 | /* marks the extension as processed so ctx level */ |
wolfSSL | 13:f67a6c6013ca | 7161 | /* extensions don't overlap with ssl level ones. */ |
wolfSSL | 13:f67a6c6013ca | 7162 | TURN_ON(semaphore, TLSX_ToSemaphore(extension->type)); |
wolfSSL | 13:f67a6c6013ca | 7163 | } |
wolfSSL | 13:f67a6c6013ca | 7164 | |
wolfSSL | 13:f67a6c6013ca | 7165 | return offset; |
wolfSSL | 13:f67a6c6013ca | 7166 | } |
wolfSSL | 13:f67a6c6013ca | 7167 | |
wolfSSL | 13:f67a6c6013ca | 7168 | |
wolfSSL | 13:f67a6c6013ca | 7169 | #ifdef HAVE_NTRU |
wolfSSL | 13:f67a6c6013ca | 7170 | |
wolfSSL | 13:f67a6c6013ca | 7171 | static word32 GetEntropy(unsigned char* out, word32 num_bytes) |
wolfSSL | 13:f67a6c6013ca | 7172 | { |
wolfSSL | 13:f67a6c6013ca | 7173 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 7174 | |
wolfSSL | 13:f67a6c6013ca | 7175 | if (gRng == NULL) { |
wolfSSL | 13:f67a6c6013ca | 7176 | if ((gRng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, |
wolfSSL | 13:f67a6c6013ca | 7177 | DYNAMIC_TYPE_TLSX)) == NULL) |
wolfSSL | 13:f67a6c6013ca | 7178 | return DRBG_OUT_OF_MEMORY; |
wolfSSL | 13:f67a6c6013ca | 7179 | wc_InitRng(gRng); |
wolfSSL | 13:f67a6c6013ca | 7180 | } |
wolfSSL | 13:f67a6c6013ca | 7181 | |
wolfSSL | 13:f67a6c6013ca | 7182 | if (gRngMutex == NULL) { |
wolfSSL | 13:f67a6c6013ca | 7183 | if ((gRngMutex = (wolfSSL_Mutex*)XMALLOC(sizeof(wolfSSL_Mutex), NULL, |
wolfSSL | 13:f67a6c6013ca | 7184 | DYNAMIC_TYPE_TLSX)) == NULL) |
wolfSSL | 13:f67a6c6013ca | 7185 | return DRBG_OUT_OF_MEMORY; |
wolfSSL | 13:f67a6c6013ca | 7186 | wc_InitMutex(gRngMutex); |
wolfSSL | 13:f67a6c6013ca | 7187 | } |
wolfSSL | 13:f67a6c6013ca | 7188 | |
wolfSSL | 13:f67a6c6013ca | 7189 | ret |= wc_LockMutex(gRngMutex); |
wolfSSL | 13:f67a6c6013ca | 7190 | ret |= wc_RNG_GenerateBlock(gRng, out, num_bytes); |
wolfSSL | 13:f67a6c6013ca | 7191 | ret |= wc_UnLockMutex(gRngMutex); |
wolfSSL | 13:f67a6c6013ca | 7192 | |
wolfSSL | 13:f67a6c6013ca | 7193 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 7194 | return DRBG_ENTROPY_FAIL; |
wolfSSL | 13:f67a6c6013ca | 7195 | |
wolfSSL | 13:f67a6c6013ca | 7196 | return DRBG_OK; |
wolfSSL | 13:f67a6c6013ca | 7197 | } |
wolfSSL | 13:f67a6c6013ca | 7198 | #endif |
wolfSSL | 13:f67a6c6013ca | 7199 | |
wolfSSL | 13:f67a6c6013ca | 7200 | |
wolfSSL | 13:f67a6c6013ca | 7201 | #ifdef HAVE_QSH |
wolfSSL | 13:f67a6c6013ca | 7202 | static int TLSX_CreateQSHKey(WOLFSSL* ssl, int type) |
wolfSSL | 13:f67a6c6013ca | 7203 | { |
wolfSSL | 13:f67a6c6013ca | 7204 | int ret; |
wolfSSL | 13:f67a6c6013ca | 7205 | |
wolfSSL | 13:f67a6c6013ca | 7206 | (void)ssl; |
wolfSSL | 13:f67a6c6013ca | 7207 | |
wolfSSL | 13:f67a6c6013ca | 7208 | switch (type) { |
wolfSSL | 13:f67a6c6013ca | 7209 | #ifdef HAVE_NTRU |
wolfSSL | 13:f67a6c6013ca | 7210 | case WOLFSSL_NTRU_EESS439: |
wolfSSL | 13:f67a6c6013ca | 7211 | case WOLFSSL_NTRU_EESS593: |
wolfSSL | 13:f67a6c6013ca | 7212 | case WOLFSSL_NTRU_EESS743: |
wolfSSL | 13:f67a6c6013ca | 7213 | ret = TLSX_CreateNtruKey(ssl, type); |
wolfSSL | 13:f67a6c6013ca | 7214 | break; |
wolfSSL | 13:f67a6c6013ca | 7215 | #endif |
wolfSSL | 13:f67a6c6013ca | 7216 | default: |
wolfSSL | 13:f67a6c6013ca | 7217 | WOLFSSL_MSG("Unknown type for creating NTRU key"); |
wolfSSL | 13:f67a6c6013ca | 7218 | return -1; |
wolfSSL | 13:f67a6c6013ca | 7219 | } |
wolfSSL | 13:f67a6c6013ca | 7220 | |
wolfSSL | 13:f67a6c6013ca | 7221 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7222 | } |
wolfSSL | 13:f67a6c6013ca | 7223 | |
wolfSSL | 13:f67a6c6013ca | 7224 | |
wolfSSL | 13:f67a6c6013ca | 7225 | static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key) |
wolfSSL | 13:f67a6c6013ca | 7226 | { |
wolfSSL | 13:f67a6c6013ca | 7227 | QSHKey* current; |
wolfSSL | 13:f67a6c6013ca | 7228 | |
wolfSSL | 13:f67a6c6013ca | 7229 | if (key == NULL) |
wolfSSL | 13:f67a6c6013ca | 7230 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 7231 | |
wolfSSL | 13:f67a6c6013ca | 7232 | /* if no public key stored in key then do not add */ |
wolfSSL | 13:f67a6c6013ca | 7233 | if (key->pub.length == 0 || key->pub.buffer == NULL) |
wolfSSL | 13:f67a6c6013ca | 7234 | return 0; |
wolfSSL | 13:f67a6c6013ca | 7235 | |
wolfSSL | 13:f67a6c6013ca | 7236 | /* first element to be added to the list */ |
wolfSSL | 13:f67a6c6013ca | 7237 | current = *list; |
wolfSSL | 13:f67a6c6013ca | 7238 | if (current == NULL) { |
wolfSSL | 13:f67a6c6013ca | 7239 | *list = key; |
wolfSSL | 13:f67a6c6013ca | 7240 | return 0; |
wolfSSL | 13:f67a6c6013ca | 7241 | } |
wolfSSL | 13:f67a6c6013ca | 7242 | |
wolfSSL | 13:f67a6c6013ca | 7243 | while (current->next) { |
wolfSSL | 13:f67a6c6013ca | 7244 | /* can only have one of the key in the list */ |
wolfSSL | 13:f67a6c6013ca | 7245 | if (current->name == key->name) |
wolfSSL | 13:f67a6c6013ca | 7246 | return -1; |
wolfSSL | 13:f67a6c6013ca | 7247 | current = (QSHKey*)current->next; |
wolfSSL | 13:f67a6c6013ca | 7248 | } |
wolfSSL | 13:f67a6c6013ca | 7249 | |
wolfSSL | 13:f67a6c6013ca | 7250 | current->next = (struct QSHKey*)key; |
wolfSSL | 13:f67a6c6013ca | 7251 | |
wolfSSL | 13:f67a6c6013ca | 7252 | return 0; |
wolfSSL | 13:f67a6c6013ca | 7253 | } |
wolfSSL | 13:f67a6c6013ca | 7254 | |
wolfSSL | 13:f67a6c6013ca | 7255 | |
wolfSSL | 13:f67a6c6013ca | 7256 | #if defined(HAVE_NTRU) || defined(HAVE_QSH) |
wolfSSL | 13:f67a6c6013ca | 7257 | int TLSX_CreateNtruKey(WOLFSSL* ssl, int type) |
wolfSSL | 13:f67a6c6013ca | 7258 | { |
wolfSSL | 13:f67a6c6013ca | 7259 | int ret = -1; |
wolfSSL | 13:f67a6c6013ca | 7260 | #ifdef HAVE_NTRU |
wolfSSL | 13:f67a6c6013ca | 7261 | int ntruType; |
wolfSSL | 13:f67a6c6013ca | 7262 | |
wolfSSL | 13:f67a6c6013ca | 7263 | /* variable declarations for NTRU*/ |
wolfSSL | 13:f67a6c6013ca | 7264 | QSHKey* temp = NULL; |
wolfSSL | 13:f67a6c6013ca | 7265 | byte public_key[1027]; |
wolfSSL | 13:f67a6c6013ca | 7266 | word16 public_key_len = sizeof(public_key); |
wolfSSL | 13:f67a6c6013ca | 7267 | byte private_key[1120]; |
wolfSSL | 13:f67a6c6013ca | 7268 | word16 private_key_len = sizeof(private_key); |
wolfSSL | 13:f67a6c6013ca | 7269 | DRBG_HANDLE drbg; |
wolfSSL | 13:f67a6c6013ca | 7270 | |
wolfSSL | 13:f67a6c6013ca | 7271 | if (ssl == NULL) |
wolfSSL | 13:f67a6c6013ca | 7272 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 7273 | |
wolfSSL | 13:f67a6c6013ca | 7274 | switch (type) { |
wolfSSL | 13:f67a6c6013ca | 7275 | case WOLFSSL_NTRU_EESS439: |
wolfSSL | 13:f67a6c6013ca | 7276 | ntruType = NTRU_EES439EP1; |
wolfSSL | 13:f67a6c6013ca | 7277 | break; |
wolfSSL | 13:f67a6c6013ca | 7278 | case WOLFSSL_NTRU_EESS593: |
wolfSSL | 13:f67a6c6013ca | 7279 | ntruType = NTRU_EES593EP1; |
wolfSSL | 13:f67a6c6013ca | 7280 | break; |
wolfSSL | 13:f67a6c6013ca | 7281 | case WOLFSSL_NTRU_EESS743: |
wolfSSL | 13:f67a6c6013ca | 7282 | ntruType = NTRU_EES743EP1; |
wolfSSL | 13:f67a6c6013ca | 7283 | break; |
wolfSSL | 13:f67a6c6013ca | 7284 | default: |
wolfSSL | 13:f67a6c6013ca | 7285 | WOLFSSL_MSG("Unknown type for creating NTRU key"); |
wolfSSL | 13:f67a6c6013ca | 7286 | return -1; |
wolfSSL | 13:f67a6c6013ca | 7287 | } |
wolfSSL | 13:f67a6c6013ca | 7288 | ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg); |
wolfSSL | 13:f67a6c6013ca | 7289 | if (ret != DRBG_OK) { |
wolfSSL | 13:f67a6c6013ca | 7290 | WOLFSSL_MSG("NTRU drbg instantiate failed\n"); |
wolfSSL | 13:f67a6c6013ca | 7291 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7292 | } |
wolfSSL | 13:f67a6c6013ca | 7293 | |
wolfSSL | 13:f67a6c6013ca | 7294 | if ((ret = ntru_crypto_ntru_encrypt_keygen(drbg, ntruType, |
wolfSSL | 13:f67a6c6013ca | 7295 | &public_key_len, NULL, &private_key_len, NULL)) != NTRU_OK) |
wolfSSL | 13:f67a6c6013ca | 7296 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7297 | |
wolfSSL | 13:f67a6c6013ca | 7298 | if ((ret = ntru_crypto_ntru_encrypt_keygen(drbg, ntruType, |
wolfSSL | 13:f67a6c6013ca | 7299 | &public_key_len, public_key, &private_key_len, private_key)) != NTRU_OK) |
wolfSSL | 13:f67a6c6013ca | 7300 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7301 | |
wolfSSL | 13:f67a6c6013ca | 7302 | ret = ntru_crypto_drbg_uninstantiate(drbg); |
wolfSSL | 13:f67a6c6013ca | 7303 | if (ret != NTRU_OK) { |
wolfSSL | 13:f67a6c6013ca | 7304 | WOLFSSL_MSG("NTRU drbg uninstantiate failed\n"); |
wolfSSL | 13:f67a6c6013ca | 7305 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7306 | } |
wolfSSL | 13:f67a6c6013ca | 7307 | |
wolfSSL | 13:f67a6c6013ca | 7308 | if ((temp = (QSHKey*)XMALLOC(sizeof(QSHKey), ssl->heap, |
wolfSSL | 13:f67a6c6013ca | 7309 | DYNAMIC_TYPE_TLSX)) == NULL) |
wolfSSL | 13:f67a6c6013ca | 7310 | return MEMORY_E; |
wolfSSL | 13:f67a6c6013ca | 7311 | temp->name = type; |
wolfSSL | 13:f67a6c6013ca | 7312 | temp->pub.length = public_key_len; |
wolfSSL | 13:f67a6c6013ca | 7313 | temp->pub.buffer = (byte*)XMALLOC(public_key_len, ssl->heap, |
wolfSSL | 13:f67a6c6013ca | 7314 | DYNAMIC_TYPE_PUBLIC_KEY); |
wolfSSL | 13:f67a6c6013ca | 7315 | XMEMCPY(temp->pub.buffer, public_key, public_key_len); |
wolfSSL | 13:f67a6c6013ca | 7316 | temp->pri.length = private_key_len; |
wolfSSL | 13:f67a6c6013ca | 7317 | temp->pri.buffer = (byte*)XMALLOC(private_key_len, ssl->heap, |
wolfSSL | 13:f67a6c6013ca | 7318 | DYNAMIC_TYPE_ARRAYS); |
wolfSSL | 13:f67a6c6013ca | 7319 | XMEMCPY(temp->pri.buffer, private_key, private_key_len); |
wolfSSL | 13:f67a6c6013ca | 7320 | temp->next = NULL; |
wolfSSL | 13:f67a6c6013ca | 7321 | |
wolfSSL | 13:f67a6c6013ca | 7322 | TLSX_AddQSHKey(&ssl->QSH_Key, temp); |
wolfSSL | 13:f67a6c6013ca | 7323 | #endif |
wolfSSL | 13:f67a6c6013ca | 7324 | |
wolfSSL | 13:f67a6c6013ca | 7325 | (void)ssl; |
wolfSSL | 13:f67a6c6013ca | 7326 | (void)type; |
wolfSSL | 13:f67a6c6013ca | 7327 | |
wolfSSL | 13:f67a6c6013ca | 7328 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7329 | } |
wolfSSL | 13:f67a6c6013ca | 7330 | #endif |
wolfSSL | 13:f67a6c6013ca | 7331 | |
wolfSSL | 13:f67a6c6013ca | 7332 | |
wolfSSL | 13:f67a6c6013ca | 7333 | /* |
wolfSSL | 13:f67a6c6013ca | 7334 | Used to find a public key from the list of keys |
wolfSSL | 13:f67a6c6013ca | 7335 | pubLen length of array |
wolfSSL | 13:f67a6c6013ca | 7336 | name input the name of the scheme looking for ie WOLFSSL_NTRU_ESSXXX |
wolfSSL | 13:f67a6c6013ca | 7337 | |
wolfSSL | 13:f67a6c6013ca | 7338 | returns a pointer to public key byte* or NULL if not found |
wolfSSL | 13:f67a6c6013ca | 7339 | */ |
wolfSSL | 13:f67a6c6013ca | 7340 | static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name) |
wolfSSL | 13:f67a6c6013ca | 7341 | { |
wolfSSL | 13:f67a6c6013ca | 7342 | QSHKey* current = qsh; |
wolfSSL | 13:f67a6c6013ca | 7343 | |
wolfSSL | 13:f67a6c6013ca | 7344 | if (qsh == NULL || pubLen == NULL) |
wolfSSL | 13:f67a6c6013ca | 7345 | return NULL; |
wolfSSL | 13:f67a6c6013ca | 7346 | |
wolfSSL | 13:f67a6c6013ca | 7347 | *pubLen = 0; |
wolfSSL | 13:f67a6c6013ca | 7348 | |
wolfSSL | 13:f67a6c6013ca | 7349 | while(current) { |
wolfSSL | 13:f67a6c6013ca | 7350 | if (current->name == name) { |
wolfSSL | 13:f67a6c6013ca | 7351 | *pubLen = current->pub.length; |
wolfSSL | 13:f67a6c6013ca | 7352 | return current->pub.buffer; |
wolfSSL | 13:f67a6c6013ca | 7353 | } |
wolfSSL | 13:f67a6c6013ca | 7354 | current = (QSHKey*)current->next; |
wolfSSL | 13:f67a6c6013ca | 7355 | } |
wolfSSL | 13:f67a6c6013ca | 7356 | |
wolfSSL | 13:f67a6c6013ca | 7357 | return NULL; |
wolfSSL | 13:f67a6c6013ca | 7358 | } |
wolfSSL | 13:f67a6c6013ca | 7359 | #endif /* HAVE_QSH */ |
wolfSSL | 13:f67a6c6013ca | 7360 | |
wolfSSL | 13:f67a6c6013ca | 7361 | int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) |
wolfSSL | 13:f67a6c6013ca | 7362 | { |
wolfSSL | 13:f67a6c6013ca | 7363 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 7364 | byte* public_key = NULL; |
wolfSSL | 13:f67a6c6013ca | 7365 | word16 public_key_len = 0; |
wolfSSL | 13:f67a6c6013ca | 7366 | #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)) |
wolfSSL | 13:f67a6c6013ca | 7367 | int usingPSK = 0; |
wolfSSL | 13:f67a6c6013ca | 7368 | #endif |
wolfSSL | 13:f67a6c6013ca | 7369 | #ifdef HAVE_QSH |
wolfSSL | 13:f67a6c6013ca | 7370 | TLSX* extension; |
wolfSSL | 13:f67a6c6013ca | 7371 | QSHScheme* qsh; |
wolfSSL | 13:f67a6c6013ca | 7372 | QSHScheme* next; |
wolfSSL | 13:f67a6c6013ca | 7373 | |
wolfSSL | 13:f67a6c6013ca | 7374 | /* add supported QSHSchemes */ |
wolfSSL | 13:f67a6c6013ca | 7375 | WOLFSSL_MSG("Adding supported QSH Schemes"); |
wolfSSL | 13:f67a6c6013ca | 7376 | #endif |
wolfSSL | 13:f67a6c6013ca | 7377 | |
wolfSSL | 13:f67a6c6013ca | 7378 | /* server will add extension depending on whats parsed from client */ |
wolfSSL | 13:f67a6c6013ca | 7379 | if (!isServer) { |
wolfSSL | 13:f67a6c6013ca | 7380 | #ifdef HAVE_QSH |
wolfSSL | 13:f67a6c6013ca | 7381 | /* test if user has set a specific scheme already */ |
wolfSSL | 13:f67a6c6013ca | 7382 | if (!ssl->user_set_QSHSchemes) { |
wolfSSL | 13:f67a6c6013ca | 7383 | if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) { |
wolfSSL | 13:f67a6c6013ca | 7384 | if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS743)) != 0) { |
wolfSSL | 13:f67a6c6013ca | 7385 | WOLFSSL_MSG("Error creating ntru keys"); |
wolfSSL | 13:f67a6c6013ca | 7386 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7387 | } |
wolfSSL | 13:f67a6c6013ca | 7388 | if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS593)) != 0) { |
wolfSSL | 13:f67a6c6013ca | 7389 | WOLFSSL_MSG("Error creating ntru keys"); |
wolfSSL | 13:f67a6c6013ca | 7390 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7391 | } |
wolfSSL | 13:f67a6c6013ca | 7392 | if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS439)) != 0) { |
wolfSSL | 13:f67a6c6013ca | 7393 | WOLFSSL_MSG("Error creating ntru keys"); |
wolfSSL | 13:f67a6c6013ca | 7394 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7395 | } |
wolfSSL | 13:f67a6c6013ca | 7396 | |
wolfSSL | 13:f67a6c6013ca | 7397 | /* add NTRU 256 */ |
wolfSSL | 13:f67a6c6013ca | 7398 | public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, |
wolfSSL | 13:f67a6c6013ca | 7399 | &public_key_len, WOLFSSL_NTRU_EESS743); |
wolfSSL | 13:f67a6c6013ca | 7400 | } |
wolfSSL | 13:f67a6c6013ca | 7401 | if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS743, |
wolfSSL | 13:f67a6c6013ca | 7402 | public_key, public_key_len, ssl->heap) |
wolfSSL | 13:f67a6c6013ca | 7403 | != SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 7404 | ret = -1; |
wolfSSL | 13:f67a6c6013ca | 7405 | |
wolfSSL | 13:f67a6c6013ca | 7406 | /* add NTRU 196 */ |
wolfSSL | 13:f67a6c6013ca | 7407 | if (ssl->sendQSHKeys) { |
wolfSSL | 13:f67a6c6013ca | 7408 | public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, |
wolfSSL | 13:f67a6c6013ca | 7409 | &public_key_len, WOLFSSL_NTRU_EESS593); |
wolfSSL | 13:f67a6c6013ca | 7410 | } |
wolfSSL | 13:f67a6c6013ca | 7411 | if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS593, |
wolfSSL | 13:f67a6c6013ca | 7412 | public_key, public_key_len, ssl->heap) |
wolfSSL | 13:f67a6c6013ca | 7413 | != SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 7414 | ret = -1; |
wolfSSL | 13:f67a6c6013ca | 7415 | |
wolfSSL | 13:f67a6c6013ca | 7416 | /* add NTRU 128 */ |
wolfSSL | 13:f67a6c6013ca | 7417 | if (ssl->sendQSHKeys) { |
wolfSSL | 13:f67a6c6013ca | 7418 | public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, |
wolfSSL | 13:f67a6c6013ca | 7419 | &public_key_len, WOLFSSL_NTRU_EESS439); |
wolfSSL | 13:f67a6c6013ca | 7420 | } |
wolfSSL | 13:f67a6c6013ca | 7421 | if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS439, |
wolfSSL | 13:f67a6c6013ca | 7422 | public_key, public_key_len, ssl->heap) |
wolfSSL | 13:f67a6c6013ca | 7423 | != SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 7424 | ret = -1; |
wolfSSL | 13:f67a6c6013ca | 7425 | } |
wolfSSL | 13:f67a6c6013ca | 7426 | else if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) { |
wolfSSL | 13:f67a6c6013ca | 7427 | /* for each scheme make a client key */ |
wolfSSL | 13:f67a6c6013ca | 7428 | extension = TLSX_Find(ssl->extensions, TLSX_QUANTUM_SAFE_HYBRID); |
wolfSSL | 13:f67a6c6013ca | 7429 | if (extension) { |
wolfSSL | 13:f67a6c6013ca | 7430 | qsh = (QSHScheme*)extension->data; |
wolfSSL | 13:f67a6c6013ca | 7431 | |
wolfSSL | 13:f67a6c6013ca | 7432 | while (qsh) { |
wolfSSL | 13:f67a6c6013ca | 7433 | if ((ret = TLSX_CreateQSHKey(ssl, qsh->name)) != 0) |
wolfSSL | 13:f67a6c6013ca | 7434 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7435 | |
wolfSSL | 13:f67a6c6013ca | 7436 | /* get next now because qsh could be freed */ |
wolfSSL | 13:f67a6c6013ca | 7437 | next = qsh->next; |
wolfSSL | 13:f67a6c6013ca | 7438 | |
wolfSSL | 13:f67a6c6013ca | 7439 | /* find the public key created and add to extension*/ |
wolfSSL | 13:f67a6c6013ca | 7440 | public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, |
wolfSSL | 13:f67a6c6013ca | 7441 | &public_key_len, qsh->name); |
wolfSSL | 13:f67a6c6013ca | 7442 | if (TLSX_UseQSHScheme(&ssl->extensions, qsh->name, |
wolfSSL | 13:f67a6c6013ca | 7443 | public_key, public_key_len, |
wolfSSL | 13:f67a6c6013ca | 7444 | ssl->heap) != SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 7445 | ret = -1; |
wolfSSL | 13:f67a6c6013ca | 7446 | qsh = next; |
wolfSSL | 13:f67a6c6013ca | 7447 | } |
wolfSSL | 13:f67a6c6013ca | 7448 | } |
wolfSSL | 13:f67a6c6013ca | 7449 | } |
wolfSSL | 13:f67a6c6013ca | 7450 | #endif |
wolfSSL | 13:f67a6c6013ca | 7451 | |
wolfSSL | 13:f67a6c6013ca | 7452 | #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES) |
wolfSSL | 13:f67a6c6013ca | 7453 | if (!ssl->options.userCurves && !ssl->ctx->userCurves && |
wolfSSL | 13:f67a6c6013ca | 7454 | TLSX_Find(ssl->ctx->extensions, TLSX_SUPPORTED_GROUPS) == NULL) { |
wolfSSL | 13:f67a6c6013ca | 7455 | #ifndef HAVE_FIPS |
wolfSSL | 13:f67a6c6013ca | 7456 | #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 7457 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 7458 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7459 | WOLFSSL_ECC_SECP160R1, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7460 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:f67a6c6013ca | 7461 | #endif |
wolfSSL | 13:f67a6c6013ca | 7462 | #ifdef HAVE_ECC_SECPR2 |
wolfSSL | 13:f67a6c6013ca | 7463 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7464 | WOLFSSL_ECC_SECP160R2, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7465 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:f67a6c6013ca | 7466 | #endif |
wolfSSL | 13:f67a6c6013ca | 7467 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:f67a6c6013ca | 7468 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7469 | WOLFSSL_ECC_SECP160K1, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7470 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:f67a6c6013ca | 7471 | #endif |
wolfSSL | 13:f67a6c6013ca | 7472 | #endif |
wolfSSL | 13:f67a6c6013ca | 7473 | #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 7474 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 7475 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7476 | WOLFSSL_ECC_SECP192R1, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7477 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:f67a6c6013ca | 7478 | #endif |
wolfSSL | 13:f67a6c6013ca | 7479 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:f67a6c6013ca | 7480 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7481 | WOLFSSL_ECC_SECP192K1, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7482 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:f67a6c6013ca | 7483 | #endif |
wolfSSL | 13:f67a6c6013ca | 7484 | #endif |
wolfSSL | 13:f67a6c6013ca | 7485 | #endif |
wolfSSL | 13:f67a6c6013ca | 7486 | #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 7487 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 7488 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7489 | WOLFSSL_ECC_SECP224R1, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7490 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:f67a6c6013ca | 7491 | #endif |
wolfSSL | 13:f67a6c6013ca | 7492 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:f67a6c6013ca | 7493 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7494 | WOLFSSL_ECC_SECP224K1, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7495 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:f67a6c6013ca | 7496 | #endif |
wolfSSL | 13:f67a6c6013ca | 7497 | #endif |
wolfSSL | 13:f67a6c6013ca | 7498 | #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 7499 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 7500 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7501 | WOLFSSL_ECC_SECP256R1, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7502 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:f67a6c6013ca | 7503 | #endif |
wolfSSL | 13:f67a6c6013ca | 7504 | #if defined(HAVE_CURVE25519) |
wolfSSL | 13:f67a6c6013ca | 7505 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7506 | WOLFSSL_ECC_X25519, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7507 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:f67a6c6013ca | 7508 | #endif |
wolfSSL | 13:f67a6c6013ca | 7509 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:f67a6c6013ca | 7510 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7511 | WOLFSSL_ECC_SECP256K1, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7512 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:f67a6c6013ca | 7513 | #endif |
wolfSSL | 13:f67a6c6013ca | 7514 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 13:f67a6c6013ca | 7515 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7516 | WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7517 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:f67a6c6013ca | 7518 | #endif |
wolfSSL | 13:f67a6c6013ca | 7519 | #endif |
wolfSSL | 13:f67a6c6013ca | 7520 | #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 7521 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 7522 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7523 | WOLFSSL_ECC_SECP384R1, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7524 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:f67a6c6013ca | 7525 | #endif |
wolfSSL | 13:f67a6c6013ca | 7526 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 13:f67a6c6013ca | 7527 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7528 | WOLFSSL_ECC_BRAINPOOLP384R1, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7529 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:f67a6c6013ca | 7530 | #endif |
wolfSSL | 13:f67a6c6013ca | 7531 | #endif |
wolfSSL | 13:f67a6c6013ca | 7532 | #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 7533 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 13:f67a6c6013ca | 7534 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7535 | WOLFSSL_ECC_BRAINPOOLP512R1, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7536 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:f67a6c6013ca | 7537 | #endif |
wolfSSL | 13:f67a6c6013ca | 7538 | #endif |
wolfSSL | 13:f67a6c6013ca | 7539 | #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:f67a6c6013ca | 7540 | #ifndef NO_ECC_SECP |
wolfSSL | 13:f67a6c6013ca | 7541 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7542 | WOLFSSL_ECC_SECP521R1, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7543 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:f67a6c6013ca | 7544 | #endif |
wolfSSL | 13:f67a6c6013ca | 7545 | #endif |
wolfSSL | 13:f67a6c6013ca | 7546 | } |
wolfSSL | 13:f67a6c6013ca | 7547 | #endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */ |
wolfSSL | 13:f67a6c6013ca | 7548 | } /* is not server */ |
wolfSSL | 13:f67a6c6013ca | 7549 | |
wolfSSL | 13:f67a6c6013ca | 7550 | WOLFSSL_MSG("Adding signature algorithms extension"); |
wolfSSL | 13:f67a6c6013ca | 7551 | if ((ret = TLSX_SetSignatureAlgorithms(&ssl->extensions, ssl, ssl->heap)) |
wolfSSL | 13:f67a6c6013ca | 7552 | != 0) { |
wolfSSL | 13:f67a6c6013ca | 7553 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7554 | } |
wolfSSL | 13:f67a6c6013ca | 7555 | |
wolfSSL | 13:f67a6c6013ca | 7556 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 7557 | if (!isServer && IsAtLeastTLSv1_3(ssl->version)) { |
wolfSSL | 13:f67a6c6013ca | 7558 | /* Add mandatory TLS v1.3 extension: supported version */ |
wolfSSL | 13:f67a6c6013ca | 7559 | WOLFSSL_MSG("Adding supported versions extension"); |
wolfSSL | 13:f67a6c6013ca | 7560 | if ((ret = TLSX_SetSupportedVersions(&ssl->extensions, ssl, |
wolfSSL | 13:f67a6c6013ca | 7561 | ssl->heap)) != 0) |
wolfSSL | 13:f67a6c6013ca | 7562 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7563 | |
wolfSSL | 13:f67a6c6013ca | 7564 | #ifdef HAVE_SUPPORTED_CURVES |
wolfSSL | 13:f67a6c6013ca | 7565 | if (!ssl->options.userCurves && !ssl->ctx->userCurves && |
wolfSSL | 13:f67a6c6013ca | 7566 | TLSX_Find(ssl->ctx->extensions, TLSX_SUPPORTED_GROUPS) |
wolfSSL | 13:f67a6c6013ca | 7567 | == NULL) { |
wolfSSL | 13:f67a6c6013ca | 7568 | /* Add FFDHE supported groups. */ |
wolfSSL | 13:f67a6c6013ca | 7569 | #ifdef HAVE_FFDHE_2048 |
wolfSSL | 13:f67a6c6013ca | 7570 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7571 | WOLFSSL_FFDHE_2048, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7572 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 7573 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7574 | #endif |
wolfSSL | 13:f67a6c6013ca | 7575 | #ifdef HAVE_FFDHE_3072 |
wolfSSL | 13:f67a6c6013ca | 7576 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7577 | WOLFSSL_FFDHE_3072, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7578 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 7579 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7580 | #endif |
wolfSSL | 13:f67a6c6013ca | 7581 | #ifdef HAVE_FFDHE_4096 |
wolfSSL | 13:f67a6c6013ca | 7582 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7583 | WOLFSSL_FFDHE_4096, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7584 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 7585 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7586 | #endif |
wolfSSL | 13:f67a6c6013ca | 7587 | #ifdef HAVE_FFDHE_6144 |
wolfSSL | 13:f67a6c6013ca | 7588 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7589 | WOLFSSL_FFDHE_6144, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7590 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 7591 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7592 | #endif |
wolfSSL | 13:f67a6c6013ca | 7593 | #ifdef HAVE_FFDHE_8192 |
wolfSSL | 13:f67a6c6013ca | 7594 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:f67a6c6013ca | 7595 | WOLFSSL_FFDHE_8192, ssl->heap); |
wolfSSL | 13:f67a6c6013ca | 7596 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 7597 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7598 | #endif |
wolfSSL | 13:f67a6c6013ca | 7599 | ret = 0; |
wolfSSL | 13:f67a6c6013ca | 7600 | } |
wolfSSL | 13:f67a6c6013ca | 7601 | #endif |
wolfSSL | 13:f67a6c6013ca | 7602 | |
wolfSSL | 13:f67a6c6013ca | 7603 | if (TLSX_Find(ssl->extensions, TLSX_KEY_SHARE) == NULL) { |
wolfSSL | 13:f67a6c6013ca | 7604 | #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \ |
wolfSSL | 13:f67a6c6013ca | 7605 | !defined(NO_ECC_SECP) |
wolfSSL | 13:f67a6c6013ca | 7606 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_ECC_SECP256R1, 0, NULL, |
wolfSSL | 13:f67a6c6013ca | 7607 | NULL); |
wolfSSL | 13:f67a6c6013ca | 7608 | #elif defined(HAVE_CURVE25519) |
wolfSSL | 13:f67a6c6013ca | 7609 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_ECC_X25519, 0, NULL, NULL); |
wolfSSL | 13:f67a6c6013ca | 7610 | #elif (!defined(NO_ECC384) || defined(HAVE_ALL_CURVES)) && \ |
wolfSSL | 13:f67a6c6013ca | 7611 | !defined(NO_ECC_SECP) |
wolfSSL | 13:f67a6c6013ca | 7612 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_ECC_SECP384R1, 0, NULL, |
wolfSSL | 13:f67a6c6013ca | 7613 | NULL); |
wolfSSL | 13:f67a6c6013ca | 7614 | #elif (!defined(NO_ECC521) || defined(HAVE_ALL_CURVES)) && \ |
wolfSSL | 13:f67a6c6013ca | 7615 | !defined(NO_ECC_SECP) |
wolfSSL | 13:f67a6c6013ca | 7616 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_ECC_SECP521R1, 0, NULL, |
wolfSSL | 13:f67a6c6013ca | 7617 | NULL); |
wolfSSL | 13:f67a6c6013ca | 7618 | #elif defined(HAVE_FFDHE_2048) |
wolfSSL | 13:f67a6c6013ca | 7619 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_FFDHE_2048, 0, NULL, NULL); |
wolfSSL | 13:f67a6c6013ca | 7620 | #elif defined(HAVE_FFDHE_3072) |
wolfSSL | 13:f67a6c6013ca | 7621 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_FFDHE_3072, 0, NULL, NULL); |
wolfSSL | 13:f67a6c6013ca | 7622 | #elif defined(HAVE_FFDHE_4096) |
wolfSSL | 13:f67a6c6013ca | 7623 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_FFDHE_4096, 0, NULL, NULL); |
wolfSSL | 13:f67a6c6013ca | 7624 | #elif defined(HAVE_FFDHE_6144) |
wolfSSL | 13:f67a6c6013ca | 7625 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_FFDHE_6144, 0, NULL, NULL); |
wolfSSL | 13:f67a6c6013ca | 7626 | #elif defined(HAVE_FFDHE_8192) |
wolfSSL | 13:f67a6c6013ca | 7627 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_FFDHE_8192, 0, NULL, NULL); |
wolfSSL | 13:f67a6c6013ca | 7628 | #else |
wolfSSL | 13:f67a6c6013ca | 7629 | ret = KEY_SHARE_ERROR; |
wolfSSL | 13:f67a6c6013ca | 7630 | #endif |
wolfSSL | 13:f67a6c6013ca | 7631 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 7632 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7633 | } |
wolfSSL | 13:f67a6c6013ca | 7634 | |
wolfSSL | 13:f67a6c6013ca | 7635 | #if defined(HAVE_SESSION_TICKET) |
wolfSSL | 13:f67a6c6013ca | 7636 | if (ssl->options.resuming) { |
wolfSSL | 13:f67a6c6013ca | 7637 | WOLFSSL_SESSION* sess = &ssl->session; |
wolfSSL | 13:f67a6c6013ca | 7638 | word32 milli; |
wolfSSL | 13:f67a6c6013ca | 7639 | |
wolfSSL | 13:f67a6c6013ca | 7640 | /* Determine the MAC algorithm for the cipher suite used. */ |
wolfSSL | 13:f67a6c6013ca | 7641 | ssl->options.cipherSuite0 = sess->cipherSuite0; |
wolfSSL | 13:f67a6c6013ca | 7642 | ssl->options.cipherSuite = sess->cipherSuite; |
wolfSSL | 13:f67a6c6013ca | 7643 | ret = SetCipherSpecs(ssl); |
wolfSSL | 13:f67a6c6013ca | 7644 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 7645 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7646 | milli = TimeNowInMilliseconds() - sess->ticketSeen + |
wolfSSL | 13:f67a6c6013ca | 7647 | sess->ticketAdd; |
wolfSSL | 13:f67a6c6013ca | 7648 | /* Pre-shared key is mandatory extension for resumption. */ |
wolfSSL | 13:f67a6c6013ca | 7649 | ret = TLSX_PreSharedKey_Use(ssl, sess->ticket, sess->ticketLen, |
wolfSSL | 13:f67a6c6013ca | 7650 | milli, ssl->specs.mac_algorithm, |
wolfSSL | 13:f67a6c6013ca | 7651 | ssl->options.cipherSuite0, |
wolfSSL | 13:f67a6c6013ca | 7652 | ssl->options.cipherSuite, 1, |
wolfSSL | 13:f67a6c6013ca | 7653 | NULL); |
wolfSSL | 13:f67a6c6013ca | 7654 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 7655 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7656 | |
wolfSSL | 13:f67a6c6013ca | 7657 | usingPSK = 1; |
wolfSSL | 13:f67a6c6013ca | 7658 | } |
wolfSSL | 13:f67a6c6013ca | 7659 | #endif |
wolfSSL | 13:f67a6c6013ca | 7660 | #ifndef NO_PSK |
wolfSSL | 13:f67a6c6013ca | 7661 | if (ssl->options.client_psk_cb != NULL) { |
wolfSSL | 13:f67a6c6013ca | 7662 | /* Default ciphersuite. */ |
wolfSSL | 13:f67a6c6013ca | 7663 | byte cipherSuite0 = TLS13_BYTE; |
wolfSSL | 13:f67a6c6013ca | 7664 | byte cipherSuite = WOLFSSL_DEF_PSK_CIPHER; |
wolfSSL | 13:f67a6c6013ca | 7665 | |
wolfSSL | 13:f67a6c6013ca | 7666 | ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl, |
wolfSSL | 13:f67a6c6013ca | 7667 | ssl->arrays->server_hint, ssl->arrays->client_identity, |
wolfSSL | 13:f67a6c6013ca | 7668 | MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN); |
wolfSSL | 13:f67a6c6013ca | 7669 | if (ssl->arrays->psk_keySz == 0 || |
wolfSSL | 13:f67a6c6013ca | 7670 | ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) { |
wolfSSL | 13:f67a6c6013ca | 7671 | return PSK_KEY_ERROR; |
wolfSSL | 13:f67a6c6013ca | 7672 | } |
wolfSSL | 13:f67a6c6013ca | 7673 | ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0'; |
wolfSSL | 13:f67a6c6013ca | 7674 | /* TODO: Callback should be able to change ciphersuite. */ |
wolfSSL | 13:f67a6c6013ca | 7675 | ssl->options.cipherSuite0 = cipherSuite0; |
wolfSSL | 13:f67a6c6013ca | 7676 | ssl->options.cipherSuite = cipherSuite; |
wolfSSL | 13:f67a6c6013ca | 7677 | ret = SetCipherSpecs(ssl); |
wolfSSL | 13:f67a6c6013ca | 7678 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 7679 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7680 | |
wolfSSL | 13:f67a6c6013ca | 7681 | ret = TLSX_PreSharedKey_Use(ssl, |
wolfSSL | 13:f67a6c6013ca | 7682 | (byte*)ssl->arrays->client_identity, |
wolfSSL | 13:f67a6c6013ca | 7683 | XSTRLEN(ssl->arrays->client_identity), |
wolfSSL | 13:f67a6c6013ca | 7684 | 0, ssl->specs.mac_algorithm, |
wolfSSL | 13:f67a6c6013ca | 7685 | cipherSuite0, cipherSuite, 0, |
wolfSSL | 13:f67a6c6013ca | 7686 | NULL); |
wolfSSL | 13:f67a6c6013ca | 7687 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 7688 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7689 | |
wolfSSL | 13:f67a6c6013ca | 7690 | usingPSK = 1; |
wolfSSL | 13:f67a6c6013ca | 7691 | } |
wolfSSL | 13:f67a6c6013ca | 7692 | #endif |
wolfSSL | 13:f67a6c6013ca | 7693 | #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) |
wolfSSL | 13:f67a6c6013ca | 7694 | if (usingPSK) { |
wolfSSL | 13:f67a6c6013ca | 7695 | byte modes; |
wolfSSL | 13:f67a6c6013ca | 7696 | |
wolfSSL | 13:f67a6c6013ca | 7697 | /* Pre-shared key modes: mandatory extension for resumption. */ |
wolfSSL | 13:f67a6c6013ca | 7698 | modes = 1 << PSK_KE; |
wolfSSL | 13:f67a6c6013ca | 7699 | #if !defined(NO_DH) || defined(HAVE_ECC) |
wolfSSL | 13:f67a6c6013ca | 7700 | if (!ssl->options.noPskDheKe) |
wolfSSL | 13:f67a6c6013ca | 7701 | modes |= 1 << PSK_DHE_KE; |
wolfSSL | 13:f67a6c6013ca | 7702 | #endif |
wolfSSL | 13:f67a6c6013ca | 7703 | ret = TLSX_PskKeModes_Use(ssl, modes); |
wolfSSL | 13:f67a6c6013ca | 7704 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 7705 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7706 | } |
wolfSSL | 13:f67a6c6013ca | 7707 | #endif |
wolfSSL | 13:f67a6c6013ca | 7708 | #if defined(WOLFSSL_POST_HANDSHAKE_AUTH) |
wolfSSL | 13:f67a6c6013ca | 7709 | if (!isServer && ssl->options.postHandshakeAuth) { |
wolfSSL | 13:f67a6c6013ca | 7710 | ret = TLSX_PostHandAuth_Use(ssl); |
wolfSSL | 13:f67a6c6013ca | 7711 | if (ret != 0) |
wolfSSL | 13:f67a6c6013ca | 7712 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7713 | } |
wolfSSL | 13:f67a6c6013ca | 7714 | #endif |
wolfSSL | 13:f67a6c6013ca | 7715 | } |
wolfSSL | 13:f67a6c6013ca | 7716 | |
wolfSSL | 13:f67a6c6013ca | 7717 | #endif |
wolfSSL | 13:f67a6c6013ca | 7718 | |
wolfSSL | 13:f67a6c6013ca | 7719 | (void)isServer; |
wolfSSL | 13:f67a6c6013ca | 7720 | (void)public_key; |
wolfSSL | 13:f67a6c6013ca | 7721 | (void)public_key_len; |
wolfSSL | 13:f67a6c6013ca | 7722 | (void)ssl; |
wolfSSL | 13:f67a6c6013ca | 7723 | |
wolfSSL | 13:f67a6c6013ca | 7724 | if (ret == SSL_SUCCESS) |
wolfSSL | 13:f67a6c6013ca | 7725 | ret = 0; |
wolfSSL | 13:f67a6c6013ca | 7726 | |
wolfSSL | 13:f67a6c6013ca | 7727 | return ret; |
wolfSSL | 13:f67a6c6013ca | 7728 | } |
wolfSSL | 13:f67a6c6013ca | 7729 | |
wolfSSL | 13:f67a6c6013ca | 7730 | |
wolfSSL | 13:f67a6c6013ca | 7731 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:f67a6c6013ca | 7732 | |
wolfSSL | 13:f67a6c6013ca | 7733 | /** Tells the buffered size of extensions to be sent into the client hello. */ |
wolfSSL | 13:f67a6c6013ca | 7734 | word16 TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType) |
wolfSSL | 13:f67a6c6013ca | 7735 | { |
wolfSSL | 13:f67a6c6013ca | 7736 | word16 length = 0; |
wolfSSL | 13:f67a6c6013ca | 7737 | byte semaphore[SEMAPHORE_SIZE] = {0}; |
wolfSSL | 13:f67a6c6013ca | 7738 | |
wolfSSL | 13:f67a6c6013ca | 7739 | if (!TLSX_SupportExtensions(ssl)) |
wolfSSL | 13:f67a6c6013ca | 7740 | return 0; |
wolfSSL | 13:f67a6c6013ca | 7741 | if (msgType == client_hello) { |
wolfSSL | 13:f67a6c6013ca | 7742 | EC_VALIDATE_REQUEST(ssl, semaphore); |
wolfSSL | 13:f67a6c6013ca | 7743 | QSH_VALIDATE_REQUEST(ssl, semaphore); |
wolfSSL | 13:f67a6c6013ca | 7744 | WOLF_STK_VALIDATE_REQUEST(ssl); |
wolfSSL | 13:f67a6c6013ca | 7745 | if (ssl->suites->hashSigAlgoSz == 0) |
wolfSSL | 13:f67a6c6013ca | 7746 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS)); |
wolfSSL | 13:f67a6c6013ca | 7747 | #if defined(WOLFSSL_TLS13) |
wolfSSL | 13:f67a6c6013ca | 7748 | if (!IsAtLeastTLSv1_2(ssl)) |
wolfSSL | 13:f67a6c6013ca | 7749 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS)); |
wolfSSL | 13:f67a6c6013ca | 7750 | if (!IsAtLeastTLSv1_3(ssl->version)) { |
wolfSSL | 13:f67a6c6013ca | 7751 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); |
wolfSSL | 13:f67a6c6013ca | 7752 | #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) |
wolfSSL | 13:f67a6c6013ca | 7753 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); |
wolfSSL | 13:f67a6c6013ca | 7754 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES)); |
wolfSSL | 13:f67a6c6013ca | 7755 | #endif |
wolfSSL | 13:f67a6c6013ca | 7756 | #ifdef WOLFSSL_EARLY_DATA |
wolfSSL | 13:f67a6c6013ca | 7757 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA)); |
wolfSSL | 13:f67a6c6013ca | 7758 | #endif |
wolfSSL | 13:f67a6c6013ca | 7759 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_COOKIE)); |
wolfSSL | 13:f67a6c6013ca | 7760 | #ifdef WOLFSSL_POST_HANDSHAKE_AUTH |
wolfSSL | 13:f67a6c6013ca | 7761 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH)); |
wolfSSL | 13:f67a6c6013ca | 7762 | #endif |
wolfSSL | 13:f67a6c6013ca | 7763 | } |
wolfSSL | 13:f67a6c6013ca | 7764 | #endif |
wolfSSL | 13:f67a6c6013ca | 7765 | } |
wolfSSL | 13:f67a6c6013ca | 7766 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 7767 | #ifndef NO_CERTS |
wolfSSL | 13:f67a6c6013ca | 7768 | else if (msgType == certificate_request) { |
wolfSSL | 13:f67a6c6013ca | 7769 | XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE); |
wolfSSL | 13:f67a6c6013ca | 7770 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS)); |
wolfSSL | 13:f67a6c6013ca | 7771 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST)); |
wolfSSL | 13:f67a6c6013ca | 7772 | /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP, |
wolfSSL | 13:f67a6c6013ca | 7773 | * TLSX_CERTIFICATE_AUTHORITIES, OID_FILTERS |
wolfSSL | 13:f67a6c6013ca | 7774 | */ |
wolfSSL | 13:f67a6c6013ca | 7775 | } |
wolfSSL | 13:f67a6c6013ca | 7776 | #endif |
wolfSSL | 13:f67a6c6013ca | 7777 | #endif |
wolfSSL | 13:f67a6c6013ca | 7778 | |
wolfSSL | 13:f67a6c6013ca | 7779 | if (ssl->extensions) |
wolfSSL | 13:f67a6c6013ca | 7780 | length += TLSX_GetSize(ssl->extensions, semaphore, msgType); |
wolfSSL | 13:f67a6c6013ca | 7781 | if (ssl->ctx && ssl->ctx->extensions) |
wolfSSL | 13:f67a6c6013ca | 7782 | length += TLSX_GetSize(ssl->ctx->extensions, semaphore, msgType); |
wolfSSL | 13:f67a6c6013ca | 7783 | |
wolfSSL | 13:f67a6c6013ca | 7784 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:f67a6c6013ca | 7785 | if (msgType == client_hello && ssl->options.haveEMS && |
wolfSSL | 13:f67a6c6013ca | 7786 | !IsAtLeastTLSv1_3(ssl->version)) { |
wolfSSL | 13:f67a6c6013ca | 7787 | length += HELLO_EXT_SZ; |
wolfSSL | 13:f67a6c6013ca | 7788 | } |
wolfSSL | 13:f67a6c6013ca | 7789 | #endif |
wolfSSL | 13:f67a6c6013ca | 7790 | |
wolfSSL | 13:f67a6c6013ca | 7791 | if (length) |
wolfSSL | 13:f67a6c6013ca | 7792 | length += OPAQUE16_LEN; /* for total length storage. */ |
wolfSSL | 13:f67a6c6013ca | 7793 | |
wolfSSL | 13:f67a6c6013ca | 7794 | return length; |
wolfSSL | 13:f67a6c6013ca | 7795 | } |
wolfSSL | 13:f67a6c6013ca | 7796 | |
wolfSSL | 13:f67a6c6013ca | 7797 | /** Writes the extensions to be sent into the client hello. */ |
wolfSSL | 13:f67a6c6013ca | 7798 | word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType) |
wolfSSL | 13:f67a6c6013ca | 7799 | { |
wolfSSL | 13:f67a6c6013ca | 7800 | word16 offset = 0; |
wolfSSL | 13:f67a6c6013ca | 7801 | byte semaphore[SEMAPHORE_SIZE] = {0}; |
wolfSSL | 13:f67a6c6013ca | 7802 | |
wolfSSL | 13:f67a6c6013ca | 7803 | if (!TLSX_SupportExtensions(ssl) || output == NULL) |
wolfSSL | 13:f67a6c6013ca | 7804 | return 0; |
wolfSSL | 13:f67a6c6013ca | 7805 | |
wolfSSL | 13:f67a6c6013ca | 7806 | offset += OPAQUE16_LEN; /* extensions length */ |
wolfSSL | 13:f67a6c6013ca | 7807 | |
wolfSSL | 13:f67a6c6013ca | 7808 | if (msgType == client_hello) { |
wolfSSL | 13:f67a6c6013ca | 7809 | EC_VALIDATE_REQUEST(ssl, semaphore); |
wolfSSL | 13:f67a6c6013ca | 7810 | WOLF_STK_VALIDATE_REQUEST(ssl); |
wolfSSL | 13:f67a6c6013ca | 7811 | QSH_VALIDATE_REQUEST(ssl, semaphore); |
wolfSSL | 13:f67a6c6013ca | 7812 | if (ssl->suites->hashSigAlgoSz == 0) |
wolfSSL | 13:f67a6c6013ca | 7813 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS)); |
wolfSSL | 13:f67a6c6013ca | 7814 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 7815 | if (!IsAtLeastTLSv1_2(ssl)) |
wolfSSL | 13:f67a6c6013ca | 7816 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS)); |
wolfSSL | 13:f67a6c6013ca | 7817 | if (!IsAtLeastTLSv1_3(ssl->version)) { |
wolfSSL | 13:f67a6c6013ca | 7818 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); |
wolfSSL | 13:f67a6c6013ca | 7819 | #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) |
wolfSSL | 13:f67a6c6013ca | 7820 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES)); |
wolfSSL | 13:f67a6c6013ca | 7821 | #endif |
wolfSSL | 13:f67a6c6013ca | 7822 | #ifdef WOLFSSL_EARLY_DATA |
wolfSSL | 13:f67a6c6013ca | 7823 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA)); |
wolfSSL | 13:f67a6c6013ca | 7824 | #endif |
wolfSSL | 13:f67a6c6013ca | 7825 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_COOKIE)); |
wolfSSL | 13:f67a6c6013ca | 7826 | #ifdef WOLFSSL_POST_HANDSHAKE_AUTH |
wolfSSL | 13:f67a6c6013ca | 7827 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH)); |
wolfSSL | 13:f67a6c6013ca | 7828 | #endif |
wolfSSL | 13:f67a6c6013ca | 7829 | } |
wolfSSL | 13:f67a6c6013ca | 7830 | #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) |
wolfSSL | 13:f67a6c6013ca | 7831 | /* Must write Pre-shared Key extension at the end in TLS v1.3. |
wolfSSL | 13:f67a6c6013ca | 7832 | * Must not write out Pre-shared Key extension in earlier versions of |
wolfSSL | 13:f67a6c6013ca | 7833 | * protocol. |
wolfSSL | 13:f67a6c6013ca | 7834 | */ |
wolfSSL | 13:f67a6c6013ca | 7835 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); |
wolfSSL | 13:f67a6c6013ca | 7836 | #endif |
wolfSSL | 13:f67a6c6013ca | 7837 | #endif |
wolfSSL | 13:f67a6c6013ca | 7838 | } |
wolfSSL | 13:f67a6c6013ca | 7839 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 7840 | #ifndef NO_CERT |
wolfSSL | 13:f67a6c6013ca | 7841 | else if (msgType == certificate_request) { |
wolfSSL | 13:f67a6c6013ca | 7842 | XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE); |
wolfSSL | 13:f67a6c6013ca | 7843 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS)); |
wolfSSL | 13:f67a6c6013ca | 7844 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST)); |
wolfSSL | 13:f67a6c6013ca | 7845 | /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP, |
wolfSSL | 13:f67a6c6013ca | 7846 | * TLSX_CERTIFICATE_AUTHORITIES, TLSX_OID_FILTERS |
wolfSSL | 13:f67a6c6013ca | 7847 | */ |
wolfSSL | 13:f67a6c6013ca | 7848 | } |
wolfSSL | 13:f67a6c6013ca | 7849 | #endif |
wolfSSL | 13:f67a6c6013ca | 7850 | #endif |
wolfSSL | 13:f67a6c6013ca | 7851 | |
wolfSSL | 13:f67a6c6013ca | 7852 | if (ssl->extensions) { |
wolfSSL | 13:f67a6c6013ca | 7853 | offset += TLSX_Write(ssl->extensions, output + offset, semaphore, |
wolfSSL | 13:f67a6c6013ca | 7854 | msgType); |
wolfSSL | 13:f67a6c6013ca | 7855 | } |
wolfSSL | 13:f67a6c6013ca | 7856 | if (ssl->ctx && ssl->ctx->extensions) { |
wolfSSL | 13:f67a6c6013ca | 7857 | offset += TLSX_Write(ssl->ctx->extensions, output + offset, semaphore, |
wolfSSL | 13:f67a6c6013ca | 7858 | msgType); |
wolfSSL | 13:f67a6c6013ca | 7859 | } |
wolfSSL | 13:f67a6c6013ca | 7860 | |
wolfSSL | 13:f67a6c6013ca | 7861 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:f67a6c6013ca | 7862 | if (msgType == client_hello && ssl->options.haveEMS && |
wolfSSL | 13:f67a6c6013ca | 7863 | !IsAtLeastTLSv1_3(ssl->version)) { |
wolfSSL | 13:f67a6c6013ca | 7864 | c16toa(HELLO_EXT_EXTMS, output + offset); |
wolfSSL | 13:f67a6c6013ca | 7865 | offset += HELLO_EXT_TYPE_SZ; |
wolfSSL | 13:f67a6c6013ca | 7866 | c16toa(0, output + offset); |
wolfSSL | 13:f67a6c6013ca | 7867 | offset += HELLO_EXT_SZ_SZ; |
wolfSSL | 13:f67a6c6013ca | 7868 | } |
wolfSSL | 13:f67a6c6013ca | 7869 | #endif |
wolfSSL | 13:f67a6c6013ca | 7870 | |
wolfSSL | 13:f67a6c6013ca | 7871 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 7872 | #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) |
wolfSSL | 13:f67a6c6013ca | 7873 | if (msgType == client_hello && IsAtLeastTLSv1_3(ssl->version)) { |
wolfSSL | 13:f67a6c6013ca | 7874 | /* Write out what we can of Pre-shared key extension. */ |
wolfSSL | 13:f67a6c6013ca | 7875 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); |
wolfSSL | 13:f67a6c6013ca | 7876 | offset += TLSX_Write(ssl->extensions, output + offset, semaphore, |
wolfSSL | 13:f67a6c6013ca | 7877 | client_hello); |
wolfSSL | 13:f67a6c6013ca | 7878 | } |
wolfSSL | 13:f67a6c6013ca | 7879 | #endif |
wolfSSL | 13:f67a6c6013ca | 7880 | #endif |
wolfSSL | 13:f67a6c6013ca | 7881 | |
wolfSSL | 13:f67a6c6013ca | 7882 | if (offset > OPAQUE16_LEN || msgType != client_hello) |
wolfSSL | 13:f67a6c6013ca | 7883 | c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ |
wolfSSL | 13:f67a6c6013ca | 7884 | |
wolfSSL | 13:f67a6c6013ca | 7885 | return offset; |
wolfSSL | 13:f67a6c6013ca | 7886 | } |
wolfSSL | 13:f67a6c6013ca | 7887 | |
wolfSSL | 13:f67a6c6013ca | 7888 | #endif /* NO_WOLFSSL_CLIENT */ |
wolfSSL | 13:f67a6c6013ca | 7889 | |
wolfSSL | 13:f67a6c6013ca | 7890 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 7891 | |
wolfSSL | 13:f67a6c6013ca | 7892 | /** Tells the buffered size of extensions to be sent into the server hello. */ |
wolfSSL | 13:f67a6c6013ca | 7893 | word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType) |
wolfSSL | 13:f67a6c6013ca | 7894 | { |
wolfSSL | 13:f67a6c6013ca | 7895 | word16 length = 0; |
wolfSSL | 13:f67a6c6013ca | 7896 | byte semaphore[SEMAPHORE_SIZE] = {0}; |
wolfSSL | 13:f67a6c6013ca | 7897 | |
wolfSSL | 13:f67a6c6013ca | 7898 | switch (msgType) { |
wolfSSL | 13:f67a6c6013ca | 7899 | case server_hello: |
wolfSSL | 13:f67a6c6013ca | 7900 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 7901 | if (ssl->options.tls1_3) { |
wolfSSL | 13:f67a6c6013ca | 7902 | XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE); |
wolfSSL | 13:f67a6c6013ca | 7903 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); |
wolfSSL | 13:f67a6c6013ca | 7904 | #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) |
wolfSSL | 13:f67a6c6013ca | 7905 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); |
wolfSSL | 13:f67a6c6013ca | 7906 | #endif |
wolfSSL | 13:f67a6c6013ca | 7907 | } |
wolfSSL | 13:f67a6c6013ca | 7908 | #endif |
wolfSSL | 13:f67a6c6013ca | 7909 | break; |
wolfSSL | 13:f67a6c6013ca | 7910 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 7911 | case hello_retry_request: |
wolfSSL | 13:f67a6c6013ca | 7912 | XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE); |
wolfSSL | 13:f67a6c6013ca | 7913 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); |
wolfSSL | 13:f67a6c6013ca | 7914 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE)); |
wolfSSL | 13:f67a6c6013ca | 7915 | #endif |
wolfSSL | 13:f67a6c6013ca | 7916 | break; |
wolfSSL | 13:f67a6c6013ca | 7917 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 7918 | case encrypted_extensions: |
wolfSSL | 13:f67a6c6013ca | 7919 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET)); |
wolfSSL | 13:f67a6c6013ca | 7920 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); |
wolfSSL | 13:f67a6c6013ca | 7921 | #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) |
wolfSSL | 13:f67a6c6013ca | 7922 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); |
wolfSSL | 13:f67a6c6013ca | 7923 | #endif |
wolfSSL | 13:f67a6c6013ca | 7924 | break; |
wolfSSL | 13:f67a6c6013ca | 7925 | #ifdef WOLFSSL_EARLY_DATA |
wolfSSL | 13:f67a6c6013ca | 7926 | case session_ticket: |
wolfSSL | 13:f67a6c6013ca | 7927 | if (ssl->options.tls1_3) { |
wolfSSL | 13:f67a6c6013ca | 7928 | XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE); |
wolfSSL | 13:f67a6c6013ca | 7929 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA)); |
wolfSSL | 13:f67a6c6013ca | 7930 | } |
wolfSSL | 13:f67a6c6013ca | 7931 | break; |
wolfSSL | 13:f67a6c6013ca | 7932 | #endif |
wolfSSL | 13:f67a6c6013ca | 7933 | #ifndef NO_CERT |
wolfSSL | 13:f67a6c6013ca | 7934 | case certificate: |
wolfSSL | 13:f67a6c6013ca | 7935 | XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE); |
wolfSSL | 13:f67a6c6013ca | 7936 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST)); |
wolfSSL | 13:f67a6c6013ca | 7937 | /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP, |
wolfSSL | 13:f67a6c6013ca | 7938 | * TLSX_SERVER_CERTIFICATE_TYPE |
wolfSSL | 13:f67a6c6013ca | 7939 | */ |
wolfSSL | 13:f67a6c6013ca | 7940 | break; |
wolfSSL | 13:f67a6c6013ca | 7941 | #endif |
wolfSSL | 13:f67a6c6013ca | 7942 | #endif |
wolfSSL | 13:f67a6c6013ca | 7943 | } |
wolfSSL | 13:f67a6c6013ca | 7944 | |
wolfSSL | 13:f67a6c6013ca | 7945 | #ifdef HAVE_QSH |
wolfSSL | 13:f67a6c6013ca | 7946 | /* change response if not using TLS_QSH */ |
wolfSSL | 13:f67a6c6013ca | 7947 | if (!ssl->options.haveQSH) { |
wolfSSL | 13:f67a6c6013ca | 7948 | TLSX* ext = TLSX_Find(ssl->extensions, TLSX_QUANTUM_SAFE_HYBRID); |
wolfSSL | 13:f67a6c6013ca | 7949 | if (ext) |
wolfSSL | 13:f67a6c6013ca | 7950 | ext->resp = 0; |
wolfSSL | 13:f67a6c6013ca | 7951 | } |
wolfSSL | 13:f67a6c6013ca | 7952 | #endif |
wolfSSL | 13:f67a6c6013ca | 7953 | |
wolfSSL | 13:f67a6c6013ca | 7954 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:f67a6c6013ca | 7955 | if (ssl->options.haveEMS && msgType == server_hello) |
wolfSSL | 13:f67a6c6013ca | 7956 | length += HELLO_EXT_SZ; |
wolfSSL | 13:f67a6c6013ca | 7957 | #endif |
wolfSSL | 13:f67a6c6013ca | 7958 | |
wolfSSL | 13:f67a6c6013ca | 7959 | if (TLSX_SupportExtensions(ssl)) |
wolfSSL | 13:f67a6c6013ca | 7960 | length += TLSX_GetSize(ssl->extensions, semaphore, msgType); |
wolfSSL | 13:f67a6c6013ca | 7961 | |
wolfSSL | 13:f67a6c6013ca | 7962 | /* All the response data is set at the ssl object only, so no ctx here. */ |
wolfSSL | 13:f67a6c6013ca | 7963 | |
wolfSSL | 13:f67a6c6013ca | 7964 | if (length || msgType != server_hello) |
wolfSSL | 13:f67a6c6013ca | 7965 | length += OPAQUE16_LEN; /* for total length storage. */ |
wolfSSL | 13:f67a6c6013ca | 7966 | |
wolfSSL | 13:f67a6c6013ca | 7967 | return length; |
wolfSSL | 13:f67a6c6013ca | 7968 | } |
wolfSSL | 13:f67a6c6013ca | 7969 | |
wolfSSL | 13:f67a6c6013ca | 7970 | /** Writes the server hello extensions into a buffer. */ |
wolfSSL | 13:f67a6c6013ca | 7971 | word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType) |
wolfSSL | 13:f67a6c6013ca | 7972 | { |
wolfSSL | 13:f67a6c6013ca | 7973 | word16 offset = 0; |
wolfSSL | 13:f67a6c6013ca | 7974 | |
wolfSSL | 13:f67a6c6013ca | 7975 | if (TLSX_SupportExtensions(ssl) && output) { |
wolfSSL | 13:f67a6c6013ca | 7976 | byte semaphore[SEMAPHORE_SIZE] = {0}; |
wolfSSL | 13:f67a6c6013ca | 7977 | |
wolfSSL | 13:f67a6c6013ca | 7978 | switch (msgType) { |
wolfSSL | 13:f67a6c6013ca | 7979 | case server_hello: |
wolfSSL | 13:f67a6c6013ca | 7980 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 7981 | if (ssl->options.tls1_3) { |
wolfSSL | 13:f67a6c6013ca | 7982 | XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE); |
wolfSSL | 13:f67a6c6013ca | 7983 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); |
wolfSSL | 13:f67a6c6013ca | 7984 | #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) |
wolfSSL | 13:f67a6c6013ca | 7985 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); |
wolfSSL | 13:f67a6c6013ca | 7986 | #endif |
wolfSSL | 13:f67a6c6013ca | 7987 | } |
wolfSSL | 13:f67a6c6013ca | 7988 | #endif |
wolfSSL | 13:f67a6c6013ca | 7989 | break; |
wolfSSL | 13:f67a6c6013ca | 7990 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 7991 | case hello_retry_request: |
wolfSSL | 13:f67a6c6013ca | 7992 | XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE); |
wolfSSL | 13:f67a6c6013ca | 7993 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); |
wolfSSL | 13:f67a6c6013ca | 7994 | #endif |
wolfSSL | 13:f67a6c6013ca | 7995 | break; |
wolfSSL | 13:f67a6c6013ca | 7996 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 7997 | case encrypted_extensions: |
wolfSSL | 13:f67a6c6013ca | 7998 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET)); |
wolfSSL | 13:f67a6c6013ca | 7999 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); |
wolfSSL | 13:f67a6c6013ca | 8000 | #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) |
wolfSSL | 13:f67a6c6013ca | 8001 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); |
wolfSSL | 13:f67a6c6013ca | 8002 | #endif |
wolfSSL | 13:f67a6c6013ca | 8003 | break; |
wolfSSL | 13:f67a6c6013ca | 8004 | #ifndef NO_CERTS |
wolfSSL | 13:f67a6c6013ca | 8005 | case certificate: |
wolfSSL | 13:f67a6c6013ca | 8006 | XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE); |
wolfSSL | 13:f67a6c6013ca | 8007 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST)); |
wolfSSL | 13:f67a6c6013ca | 8008 | /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP, |
wolfSSL | 13:f67a6c6013ca | 8009 | * TLSX_SERVER_CERTIFICATE_TYPE |
wolfSSL | 13:f67a6c6013ca | 8010 | */ |
wolfSSL | 13:f67a6c6013ca | 8011 | break; |
wolfSSL | 13:f67a6c6013ca | 8012 | #endif |
wolfSSL | 13:f67a6c6013ca | 8013 | #ifdef WOLFSSL_EARLY_DATA |
wolfSSL | 13:f67a6c6013ca | 8014 | case session_ticket: |
wolfSSL | 13:f67a6c6013ca | 8015 | if (ssl->options.tls1_3) { |
wolfSSL | 13:f67a6c6013ca | 8016 | XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE); |
wolfSSL | 13:f67a6c6013ca | 8017 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA)); |
wolfSSL | 13:f67a6c6013ca | 8018 | } |
wolfSSL | 13:f67a6c6013ca | 8019 | break; |
wolfSSL | 13:f67a6c6013ca | 8020 | #endif |
wolfSSL | 13:f67a6c6013ca | 8021 | #endif |
wolfSSL | 13:f67a6c6013ca | 8022 | } |
wolfSSL | 13:f67a6c6013ca | 8023 | |
wolfSSL | 13:f67a6c6013ca | 8024 | offset += OPAQUE16_LEN; /* extensions length */ |
wolfSSL | 13:f67a6c6013ca | 8025 | |
wolfSSL | 13:f67a6c6013ca | 8026 | offset += TLSX_Write(ssl->extensions, output + offset, semaphore, |
wolfSSL | 13:f67a6c6013ca | 8027 | msgType); |
wolfSSL | 13:f67a6c6013ca | 8028 | |
wolfSSL | 13:f67a6c6013ca | 8029 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 8030 | if (msgType == hello_retry_request) { |
wolfSSL | 13:f67a6c6013ca | 8031 | XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE); |
wolfSSL | 13:f67a6c6013ca | 8032 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE)); |
wolfSSL | 13:f67a6c6013ca | 8033 | offset += TLSX_Write(ssl->extensions, output + offset, semaphore, |
wolfSSL | 13:f67a6c6013ca | 8034 | msgType); |
wolfSSL | 13:f67a6c6013ca | 8035 | } |
wolfSSL | 13:f67a6c6013ca | 8036 | #endif |
wolfSSL | 13:f67a6c6013ca | 8037 | |
wolfSSL | 13:f67a6c6013ca | 8038 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:f67a6c6013ca | 8039 | if (ssl->options.haveEMS && msgType == server_hello) { |
wolfSSL | 13:f67a6c6013ca | 8040 | c16toa(HELLO_EXT_EXTMS, output + offset); |
wolfSSL | 13:f67a6c6013ca | 8041 | offset += HELLO_EXT_TYPE_SZ; |
wolfSSL | 13:f67a6c6013ca | 8042 | c16toa(0, output + offset); |
wolfSSL | 13:f67a6c6013ca | 8043 | offset += HELLO_EXT_SZ_SZ; |
wolfSSL | 13:f67a6c6013ca | 8044 | } |
wolfSSL | 13:f67a6c6013ca | 8045 | #endif |
wolfSSL | 13:f67a6c6013ca | 8046 | |
wolfSSL | 13:f67a6c6013ca | 8047 | if (offset > OPAQUE16_LEN || msgType != server_hello) |
wolfSSL | 13:f67a6c6013ca | 8048 | c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ |
wolfSSL | 13:f67a6c6013ca | 8049 | } |
wolfSSL | 13:f67a6c6013ca | 8050 | |
wolfSSL | 13:f67a6c6013ca | 8051 | return offset; |
wolfSSL | 13:f67a6c6013ca | 8052 | } |
wolfSSL | 13:f67a6c6013ca | 8053 | |
wolfSSL | 13:f67a6c6013ca | 8054 | #endif /* NO_WOLFSSL_SERVER */ |
wolfSSL | 13:f67a6c6013ca | 8055 | |
wolfSSL | 13:f67a6c6013ca | 8056 | /** Parses a buffer of TLS extensions. */ |
wolfSSL | 13:f67a6c6013ca | 8057 | int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, |
wolfSSL | 13:f67a6c6013ca | 8058 | Suites *suites) |
wolfSSL | 13:f67a6c6013ca | 8059 | { |
wolfSSL | 13:f67a6c6013ca | 8060 | int ret = 0; |
wolfSSL | 13:f67a6c6013ca | 8061 | word16 offset = 0; |
wolfSSL | 13:f67a6c6013ca | 8062 | byte isRequest = (msgType == client_hello || |
wolfSSL | 13:f67a6c6013ca | 8063 | msgType == certificate_request); |
wolfSSL | 13:f67a6c6013ca | 8064 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:f67a6c6013ca | 8065 | byte pendingEMS = 0; |
wolfSSL | 13:f67a6c6013ca | 8066 | #endif |
wolfSSL | 13:f67a6c6013ca | 8067 | |
wolfSSL | 13:f67a6c6013ca | 8068 | if (!ssl || !input || (isRequest && !suites)) |
wolfSSL | 13:f67a6c6013ca | 8069 | return BAD_FUNC_ARG; |
wolfSSL | 13:f67a6c6013ca | 8070 | |
wolfSSL | 13:f67a6c6013ca | 8071 | while (ret == 0 && offset < length) { |
wolfSSL | 13:f67a6c6013ca | 8072 | word16 type; |
wolfSSL | 13:f67a6c6013ca | 8073 | word16 size; |
wolfSSL | 13:f67a6c6013ca | 8074 | |
wolfSSL | 13:f67a6c6013ca | 8075 | if (length - offset < HELLO_EXT_TYPE_SZ + OPAQUE16_LEN) |
wolfSSL | 13:f67a6c6013ca | 8076 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 8077 | |
wolfSSL | 13:f67a6c6013ca | 8078 | ato16(input + offset, &type); |
wolfSSL | 13:f67a6c6013ca | 8079 | offset += HELLO_EXT_TYPE_SZ; |
wolfSSL | 13:f67a6c6013ca | 8080 | |
wolfSSL | 13:f67a6c6013ca | 8081 | ato16(input + offset, &size); |
wolfSSL | 13:f67a6c6013ca | 8082 | offset += OPAQUE16_LEN; |
wolfSSL | 13:f67a6c6013ca | 8083 | |
wolfSSL | 13:f67a6c6013ca | 8084 | if (offset + size > length) |
wolfSSL | 13:f67a6c6013ca | 8085 | return BUFFER_ERROR; |
wolfSSL | 13:f67a6c6013ca | 8086 | |
wolfSSL | 13:f67a6c6013ca | 8087 | switch (type) { |
wolfSSL | 13:f67a6c6013ca | 8088 | case TLSX_SERVER_NAME: |
wolfSSL | 13:f67a6c6013ca | 8089 | WOLFSSL_MSG("SNI extension received"); |
wolfSSL | 13:f67a6c6013ca | 8090 | |
wolfSSL | 13:f67a6c6013ca | 8091 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 8092 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8093 | msgType != client_hello && |
wolfSSL | 13:f67a6c6013ca | 8094 | msgType != encrypted_extensions) { |
wolfSSL | 13:f67a6c6013ca | 8095 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8096 | } |
wolfSSL | 13:f67a6c6013ca | 8097 | #endif |
wolfSSL | 13:f67a6c6013ca | 8098 | ret = SNI_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:f67a6c6013ca | 8099 | break; |
wolfSSL | 13:f67a6c6013ca | 8100 | |
wolfSSL | 13:f67a6c6013ca | 8101 | case TLSX_MAX_FRAGMENT_LENGTH: |
wolfSSL | 13:f67a6c6013ca | 8102 | WOLFSSL_MSG("Max Fragment Length extension received"); |
wolfSSL | 13:f67a6c6013ca | 8103 | |
wolfSSL | 13:f67a6c6013ca | 8104 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 8105 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8106 | msgType != client_hello && |
wolfSSL | 13:f67a6c6013ca | 8107 | msgType != encrypted_extensions) { |
wolfSSL | 13:f67a6c6013ca | 8108 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8109 | } |
wolfSSL | 13:f67a6c6013ca | 8110 | #endif |
wolfSSL | 13:f67a6c6013ca | 8111 | ret = MFL_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:f67a6c6013ca | 8112 | break; |
wolfSSL | 13:f67a6c6013ca | 8113 | |
wolfSSL | 13:f67a6c6013ca | 8114 | case TLSX_TRUNCATED_HMAC: |
wolfSSL | 13:f67a6c6013ca | 8115 | WOLFSSL_MSG("Truncated HMAC extension received"); |
wolfSSL | 13:f67a6c6013ca | 8116 | |
wolfSSL | 13:f67a6c6013ca | 8117 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 8118 | if (IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:f67a6c6013ca | 8119 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8120 | #endif |
wolfSSL | 13:f67a6c6013ca | 8121 | ret = THM_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:f67a6c6013ca | 8122 | break; |
wolfSSL | 13:f67a6c6013ca | 8123 | |
wolfSSL | 13:f67a6c6013ca | 8124 | case TLSX_SUPPORTED_GROUPS: |
wolfSSL | 13:f67a6c6013ca | 8125 | WOLFSSL_MSG("Elliptic Curves extension received"); |
wolfSSL | 13:f67a6c6013ca | 8126 | |
wolfSSL | 13:f67a6c6013ca | 8127 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 8128 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8129 | msgType != client_hello && |
wolfSSL | 13:f67a6c6013ca | 8130 | msgType != encrypted_extensions) { |
wolfSSL | 13:f67a6c6013ca | 8131 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8132 | } |
wolfSSL | 13:f67a6c6013ca | 8133 | #endif |
wolfSSL | 13:f67a6c6013ca | 8134 | ret = EC_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:f67a6c6013ca | 8135 | break; |
wolfSSL | 13:f67a6c6013ca | 8136 | |
wolfSSL | 13:f67a6c6013ca | 8137 | case TLSX_STATUS_REQUEST: |
wolfSSL | 13:f67a6c6013ca | 8138 | WOLFSSL_MSG("Certificate Status Request extension received"); |
wolfSSL | 13:f67a6c6013ca | 8139 | |
wolfSSL | 13:f67a6c6013ca | 8140 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 8141 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8142 | msgType != client_hello && |
wolfSSL | 13:f67a6c6013ca | 8143 | msgType != encrypted_extensions) { |
wolfSSL | 13:f67a6c6013ca | 8144 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8145 | } |
wolfSSL | 13:f67a6c6013ca | 8146 | #endif |
wolfSSL | 13:f67a6c6013ca | 8147 | ret = CSR_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:f67a6c6013ca | 8148 | break; |
wolfSSL | 13:f67a6c6013ca | 8149 | |
wolfSSL | 13:f67a6c6013ca | 8150 | case TLSX_STATUS_REQUEST_V2: |
wolfSSL | 13:f67a6c6013ca | 8151 | WOLFSSL_MSG("Certificate Status Request v2 extension received"); |
wolfSSL | 13:f67a6c6013ca | 8152 | |
wolfSSL | 13:f67a6c6013ca | 8153 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 8154 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8155 | msgType != client_hello && |
wolfSSL | 13:f67a6c6013ca | 8156 | msgType != encrypted_extensions) { |
wolfSSL | 13:f67a6c6013ca | 8157 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8158 | } |
wolfSSL | 13:f67a6c6013ca | 8159 | #endif |
wolfSSL | 13:f67a6c6013ca | 8160 | ret = CSR2_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:f67a6c6013ca | 8161 | break; |
wolfSSL | 13:f67a6c6013ca | 8162 | |
wolfSSL | 13:f67a6c6013ca | 8163 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:f67a6c6013ca | 8164 | case HELLO_EXT_EXTMS: |
wolfSSL | 13:f67a6c6013ca | 8165 | WOLFSSL_MSG("Extended Master Secret extension received"); |
wolfSSL | 13:f67a6c6013ca | 8166 | |
wolfSSL | 13:f67a6c6013ca | 8167 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 8168 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8169 | msgType != client_hello) { |
wolfSSL | 13:f67a6c6013ca | 8170 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8171 | } |
wolfSSL | 13:f67a6c6013ca | 8172 | #endif |
wolfSSL | 13:f67a6c6013ca | 8173 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 8174 | if (isRequest && !IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:f67a6c6013ca | 8175 | ssl->options.haveEMS = 1; |
wolfSSL | 13:f67a6c6013ca | 8176 | #endif |
wolfSSL | 13:f67a6c6013ca | 8177 | pendingEMS = 1; |
wolfSSL | 13:f67a6c6013ca | 8178 | break; |
wolfSSL | 13:f67a6c6013ca | 8179 | #endif |
wolfSSL | 13:f67a6c6013ca | 8180 | |
wolfSSL | 13:f67a6c6013ca | 8181 | case TLSX_RENEGOTIATION_INFO: |
wolfSSL | 13:f67a6c6013ca | 8182 | WOLFSSL_MSG("Secure Renegotiation extension received"); |
wolfSSL | 13:f67a6c6013ca | 8183 | |
wolfSSL | 13:f67a6c6013ca | 8184 | ret = SCR_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:f67a6c6013ca | 8185 | break; |
wolfSSL | 13:f67a6c6013ca | 8186 | |
wolfSSL | 13:f67a6c6013ca | 8187 | case TLSX_SESSION_TICKET: |
wolfSSL | 13:f67a6c6013ca | 8188 | WOLFSSL_MSG("Session Ticket extension received"); |
wolfSSL | 13:f67a6c6013ca | 8189 | |
wolfSSL | 13:f67a6c6013ca | 8190 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 8191 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8192 | msgType != client_hello) { |
wolfSSL | 13:f67a6c6013ca | 8193 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8194 | } |
wolfSSL | 13:f67a6c6013ca | 8195 | #endif |
wolfSSL | 13:f67a6c6013ca | 8196 | ret = WOLF_STK_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:f67a6c6013ca | 8197 | break; |
wolfSSL | 13:f67a6c6013ca | 8198 | |
wolfSSL | 13:f67a6c6013ca | 8199 | case TLSX_QUANTUM_SAFE_HYBRID: |
wolfSSL | 13:f67a6c6013ca | 8200 | WOLFSSL_MSG("Quantum-Safe-Hybrid extension received"); |
wolfSSL | 13:f67a6c6013ca | 8201 | |
wolfSSL | 13:f67a6c6013ca | 8202 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 8203 | if (IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:f67a6c6013ca | 8204 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8205 | #endif |
wolfSSL | 13:f67a6c6013ca | 8206 | ret = QSH_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:f67a6c6013ca | 8207 | break; |
wolfSSL | 13:f67a6c6013ca | 8208 | |
wolfSSL | 13:f67a6c6013ca | 8209 | case TLSX_APPLICATION_LAYER_PROTOCOL: |
wolfSSL | 13:f67a6c6013ca | 8210 | WOLFSSL_MSG("ALPN extension received"); |
wolfSSL | 13:f67a6c6013ca | 8211 | |
wolfSSL | 13:f67a6c6013ca | 8212 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 8213 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8214 | msgType != client_hello && |
wolfSSL | 13:f67a6c6013ca | 8215 | msgType != encrypted_extensions) { |
wolfSSL | 13:f67a6c6013ca | 8216 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8217 | } |
wolfSSL | 13:f67a6c6013ca | 8218 | #endif |
wolfSSL | 13:f67a6c6013ca | 8219 | ret = ALPN_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:f67a6c6013ca | 8220 | break; |
wolfSSL | 13:f67a6c6013ca | 8221 | |
wolfSSL | 13:f67a6c6013ca | 8222 | case TLSX_SIGNATURE_ALGORITHMS: |
wolfSSL | 13:f67a6c6013ca | 8223 | WOLFSSL_MSG("Signature Algorithms extension received"); |
wolfSSL | 13:f67a6c6013ca | 8224 | |
wolfSSL | 13:f67a6c6013ca | 8225 | if (!IsAtLeastTLSv1_2(ssl)) |
wolfSSL | 13:f67a6c6013ca | 8226 | break; |
wolfSSL | 13:f67a6c6013ca | 8227 | |
wolfSSL | 13:f67a6c6013ca | 8228 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8229 | msgType != client_hello && |
wolfSSL | 13:f67a6c6013ca | 8230 | msgType != certificate_request) { |
wolfSSL | 13:f67a6c6013ca | 8231 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8232 | } |
wolfSSL | 13:f67a6c6013ca | 8233 | ret = SA_PARSE(ssl, input + offset, size, suites); |
wolfSSL | 13:f67a6c6013ca | 8234 | break; |
wolfSSL | 13:f67a6c6013ca | 8235 | |
wolfSSL | 13:f67a6c6013ca | 8236 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 8237 | case TLSX_SUPPORTED_VERSIONS: |
wolfSSL | 13:f67a6c6013ca | 8238 | WOLFSSL_MSG("Supported Versions extension received"); |
wolfSSL | 13:f67a6c6013ca | 8239 | |
wolfSSL | 13:f67a6c6013ca | 8240 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8241 | msgType != client_hello) { |
wolfSSL | 13:f67a6c6013ca | 8242 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8243 | } |
wolfSSL | 13:f67a6c6013ca | 8244 | ret = SV_PARSE(ssl, input + offset, size); |
wolfSSL | 13:f67a6c6013ca | 8245 | break; |
wolfSSL | 13:f67a6c6013ca | 8246 | |
wolfSSL | 13:f67a6c6013ca | 8247 | case TLSX_COOKIE: |
wolfSSL | 13:f67a6c6013ca | 8248 | WOLFSSL_MSG("Cookie extension received"); |
wolfSSL | 13:f67a6c6013ca | 8249 | |
wolfSSL | 13:f67a6c6013ca | 8250 | if (!IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:f67a6c6013ca | 8251 | break; |
wolfSSL | 13:f67a6c6013ca | 8252 | |
wolfSSL | 13:f67a6c6013ca | 8253 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8254 | msgType != client_hello && |
wolfSSL | 13:f67a6c6013ca | 8255 | msgType != hello_retry_request) { |
wolfSSL | 13:f67a6c6013ca | 8256 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8257 | } |
wolfSSL | 13:f67a6c6013ca | 8258 | ret = CKE_PARSE(ssl, input + offset, size, msgType); |
wolfSSL | 13:f67a6c6013ca | 8259 | break; |
wolfSSL | 13:f67a6c6013ca | 8260 | |
wolfSSL | 13:f67a6c6013ca | 8261 | case TLSX_KEY_SHARE: |
wolfSSL | 13:f67a6c6013ca | 8262 | WOLFSSL_MSG("Key Share extension received"); |
wolfSSL | 13:f67a6c6013ca | 8263 | |
wolfSSL | 13:f67a6c6013ca | 8264 | if (!IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:f67a6c6013ca | 8265 | break; |
wolfSSL | 13:f67a6c6013ca | 8266 | |
wolfSSL | 13:f67a6c6013ca | 8267 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8268 | msgType != client_hello && msgType != server_hello && |
wolfSSL | 13:f67a6c6013ca | 8269 | msgType != hello_retry_request) { |
wolfSSL | 13:f67a6c6013ca | 8270 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8271 | } |
wolfSSL | 13:f67a6c6013ca | 8272 | ret = KS_PARSE(ssl, input + offset, size, msgType); |
wolfSSL | 13:f67a6c6013ca | 8273 | break; |
wolfSSL | 13:f67a6c6013ca | 8274 | |
wolfSSL | 13:f67a6c6013ca | 8275 | #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) |
wolfSSL | 13:f67a6c6013ca | 8276 | case TLSX_PRE_SHARED_KEY: |
wolfSSL | 13:f67a6c6013ca | 8277 | WOLFSSL_MSG("Pre-Shared Key extension received"); |
wolfSSL | 13:f67a6c6013ca | 8278 | |
wolfSSL | 13:f67a6c6013ca | 8279 | if (!IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:f67a6c6013ca | 8280 | break; |
wolfSSL | 13:f67a6c6013ca | 8281 | |
wolfSSL | 13:f67a6c6013ca | 8282 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8283 | msgType != client_hello && msgType != server_hello) { |
wolfSSL | 13:f67a6c6013ca | 8284 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8285 | } |
wolfSSL | 13:f67a6c6013ca | 8286 | ret = PSK_PARSE(ssl, input + offset, size, msgType); |
wolfSSL | 13:f67a6c6013ca | 8287 | break; |
wolfSSL | 13:f67a6c6013ca | 8288 | |
wolfSSL | 13:f67a6c6013ca | 8289 | case TLSX_PSK_KEY_EXCHANGE_MODES: |
wolfSSL | 13:f67a6c6013ca | 8290 | WOLFSSL_MSG("PSK Key Exchange Modes extension received"); |
wolfSSL | 13:f67a6c6013ca | 8291 | |
wolfSSL | 13:f67a6c6013ca | 8292 | if (!IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:f67a6c6013ca | 8293 | break; |
wolfSSL | 13:f67a6c6013ca | 8294 | |
wolfSSL | 13:f67a6c6013ca | 8295 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8296 | msgType != client_hello) { |
wolfSSL | 13:f67a6c6013ca | 8297 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8298 | } |
wolfSSL | 13:f67a6c6013ca | 8299 | ret = PKM_PARSE(ssl, input + offset, size, msgType); |
wolfSSL | 13:f67a6c6013ca | 8300 | break; |
wolfSSL | 13:f67a6c6013ca | 8301 | #endif |
wolfSSL | 13:f67a6c6013ca | 8302 | |
wolfSSL | 13:f67a6c6013ca | 8303 | #ifdef WOLFSSL_EARLY_DATA |
wolfSSL | 13:f67a6c6013ca | 8304 | case TLSX_EARLY_DATA: |
wolfSSL | 13:f67a6c6013ca | 8305 | WOLFSSL_MSG("Early Data extension received"); |
wolfSSL | 13:f67a6c6013ca | 8306 | |
wolfSSL | 13:f67a6c6013ca | 8307 | if (!IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:f67a6c6013ca | 8308 | break; |
wolfSSL | 13:f67a6c6013ca | 8309 | |
wolfSSL | 13:f67a6c6013ca | 8310 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8311 | msgType != client_hello && msgType != session_ticket && |
wolfSSL | 13:f67a6c6013ca | 8312 | msgType != encrypted_extensions) { |
wolfSSL | 13:f67a6c6013ca | 8313 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8314 | } |
wolfSSL | 13:f67a6c6013ca | 8315 | ret = EDI_PARSE(ssl, input + offset, size, msgType); |
wolfSSL | 13:f67a6c6013ca | 8316 | break; |
wolfSSL | 13:f67a6c6013ca | 8317 | #endif |
wolfSSL | 13:f67a6c6013ca | 8318 | |
wolfSSL | 13:f67a6c6013ca | 8319 | #ifdef WOLFSSL_POST_HANDSHAKE_AUTH |
wolfSSL | 13:f67a6c6013ca | 8320 | case TLSX_POST_HANDSHAKE_AUTH: |
wolfSSL | 13:f67a6c6013ca | 8321 | WOLFSSL_MSG("PSK Key Exchange Modes extension received"); |
wolfSSL | 13:f67a6c6013ca | 8322 | |
wolfSSL | 13:f67a6c6013ca | 8323 | if (!IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:f67a6c6013ca | 8324 | break; |
wolfSSL | 13:f67a6c6013ca | 8325 | |
wolfSSL | 13:f67a6c6013ca | 8326 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:f67a6c6013ca | 8327 | msgType != client_hello) { |
wolfSSL | 13:f67a6c6013ca | 8328 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:f67a6c6013ca | 8329 | } |
wolfSSL | 13:f67a6c6013ca | 8330 | ret = PHA_PARSE(ssl, input + offset, size, msgType); |
wolfSSL | 13:f67a6c6013ca | 8331 | break; |
wolfSSL | 13:f67a6c6013ca | 8332 | #endif |
wolfSSL | 13:f67a6c6013ca | 8333 | #endif |
wolfSSL | 13:f67a6c6013ca | 8334 | } |
wolfSSL | 13:f67a6c6013ca | 8335 | |
wolfSSL | 13:f67a6c6013ca | 8336 | /* offset should be updated here! */ |
wolfSSL | 13:f67a6c6013ca | 8337 | offset += size; |
wolfSSL | 13:f67a6c6013ca | 8338 | } |
wolfSSL | 13:f67a6c6013ca | 8339 | |
wolfSSL | 13:f67a6c6013ca | 8340 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:f67a6c6013ca | 8341 | if (!isRequest && ssl->options.haveEMS && !pendingEMS) |
wolfSSL | 13:f67a6c6013ca | 8342 | ssl->options.haveEMS = 0; |
wolfSSL | 13:f67a6c6013ca | 8343 | #endif |
wolfSSL | 13:f67a6c6013ca | 8344 | |
wolfSSL | 13:f67a6c6013ca | 8345 | if (ret == 0) |
wolfSSL | 13:f67a6c6013ca | 8346 | ret = SNI_VERIFY_PARSE(ssl, isRequest); |
wolfSSL | 13:f67a6c6013ca | 8347 | |
wolfSSL | 13:f67a6c6013ca | 8348 | return ret; |
wolfSSL | 13:f67a6c6013ca | 8349 | } |
wolfSSL | 13:f67a6c6013ca | 8350 | |
wolfSSL | 13:f67a6c6013ca | 8351 | /* undefining semaphore macros */ |
wolfSSL | 13:f67a6c6013ca | 8352 | #undef IS_OFF |
wolfSSL | 13:f67a6c6013ca | 8353 | #undef TURN_ON |
wolfSSL | 13:f67a6c6013ca | 8354 | #undef SEMAPHORE_SIZE |
wolfSSL | 13:f67a6c6013ca | 8355 | |
wolfSSL | 13:f67a6c6013ca | 8356 | #endif /* HAVE_TLS_EXTENSIONS */ |
wolfSSL | 13:f67a6c6013ca | 8357 | |
wolfSSL | 13:f67a6c6013ca | 8358 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:f67a6c6013ca | 8359 | |
wolfSSL | 13:f67a6c6013ca | 8360 | #ifndef NO_OLD_TLS |
wolfSSL | 13:f67a6c6013ca | 8361 | |
wolfSSL | 13:f67a6c6013ca | 8362 | WOLFSSL_METHOD* wolfTLSv1_client_method(void) |
wolfSSL | 13:f67a6c6013ca | 8363 | { |
wolfSSL | 13:f67a6c6013ca | 8364 | return wolfTLSv1_client_method_ex(NULL); |
wolfSSL | 13:f67a6c6013ca | 8365 | } |
wolfSSL | 13:f67a6c6013ca | 8366 | |
wolfSSL | 13:f67a6c6013ca | 8367 | |
wolfSSL | 13:f67a6c6013ca | 8368 | WOLFSSL_METHOD* wolfTLSv1_1_client_method(void) |
wolfSSL | 13:f67a6c6013ca | 8369 | { |
wolfSSL | 13:f67a6c6013ca | 8370 | return wolfTLSv1_1_client_method_ex(NULL); |
wolfSSL | 13:f67a6c6013ca | 8371 | } |
wolfSSL | 13:f67a6c6013ca | 8372 | |
wolfSSL | 13:f67a6c6013ca | 8373 | WOLFSSL_METHOD* wolfTLSv1_client_method_ex(void* heap) |
wolfSSL | 13:f67a6c6013ca | 8374 | { |
wolfSSL | 13:f67a6c6013ca | 8375 | WOLFSSL_METHOD* method = |
wolfSSL | 13:f67a6c6013ca | 8376 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:f67a6c6013ca | 8377 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:f67a6c6013ca | 8378 | if (method) |
wolfSSL | 13:f67a6c6013ca | 8379 | InitSSL_Method(method, MakeTLSv1()); |
wolfSSL | 13:f67a6c6013ca | 8380 | return method; |
wolfSSL | 13:f67a6c6013ca | 8381 | } |
wolfSSL | 13:f67a6c6013ca | 8382 | |
wolfSSL | 13:f67a6c6013ca | 8383 | |
wolfSSL | 13:f67a6c6013ca | 8384 | WOLFSSL_METHOD* wolfTLSv1_1_client_method_ex(void* heap) |
wolfSSL | 13:f67a6c6013ca | 8385 | { |
wolfSSL | 13:f67a6c6013ca | 8386 | WOLFSSL_METHOD* method = |
wolfSSL | 13:f67a6c6013ca | 8387 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:f67a6c6013ca | 8388 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:f67a6c6013ca | 8389 | if (method) |
wolfSSL | 13:f67a6c6013ca | 8390 | InitSSL_Method(method, MakeTLSv1_1()); |
wolfSSL | 13:f67a6c6013ca | 8391 | return method; |
wolfSSL | 13:f67a6c6013ca | 8392 | } |
wolfSSL | 13:f67a6c6013ca | 8393 | |
wolfSSL | 13:f67a6c6013ca | 8394 | #endif /* !NO_OLD_TLS */ |
wolfSSL | 13:f67a6c6013ca | 8395 | |
wolfSSL | 13:f67a6c6013ca | 8396 | |
wolfSSL | 13:f67a6c6013ca | 8397 | WOLFSSL_METHOD* wolfTLSv1_2_client_method(void) |
wolfSSL | 13:f67a6c6013ca | 8398 | { |
wolfSSL | 13:f67a6c6013ca | 8399 | return wolfTLSv1_2_client_method_ex(NULL); |
wolfSSL | 13:f67a6c6013ca | 8400 | } |
wolfSSL | 13:f67a6c6013ca | 8401 | |
wolfSSL | 13:f67a6c6013ca | 8402 | WOLFSSL_METHOD* wolfTLSv1_2_client_method_ex(void* heap) |
wolfSSL | 13:f67a6c6013ca | 8403 | { |
wolfSSL | 13:f67a6c6013ca | 8404 | WOLFSSL_METHOD* method = |
wolfSSL | 13:f67a6c6013ca | 8405 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:f67a6c6013ca | 8406 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:f67a6c6013ca | 8407 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 8408 | if (method) |
wolfSSL | 13:f67a6c6013ca | 8409 | InitSSL_Method(method, MakeTLSv1_2()); |
wolfSSL | 13:f67a6c6013ca | 8410 | return method; |
wolfSSL | 13:f67a6c6013ca | 8411 | } |
wolfSSL | 13:f67a6c6013ca | 8412 | |
wolfSSL | 13:f67a6c6013ca | 8413 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 8414 | /* The TLS v1.3 client method data. |
wolfSSL | 13:f67a6c6013ca | 8415 | * |
wolfSSL | 13:f67a6c6013ca | 8416 | * returns the method data for a TLS v1.3 client. |
wolfSSL | 13:f67a6c6013ca | 8417 | */ |
wolfSSL | 13:f67a6c6013ca | 8418 | WOLFSSL_METHOD* wolfTLSv1_3_client_method(void) |
wolfSSL | 13:f67a6c6013ca | 8419 | { |
wolfSSL | 13:f67a6c6013ca | 8420 | return wolfTLSv1_3_client_method_ex(NULL); |
wolfSSL | 13:f67a6c6013ca | 8421 | } |
wolfSSL | 13:f67a6c6013ca | 8422 | |
wolfSSL | 13:f67a6c6013ca | 8423 | /* The TLS v1.3 client method data. |
wolfSSL | 13:f67a6c6013ca | 8424 | * |
wolfSSL | 13:f67a6c6013ca | 8425 | * heap The heap used for allocation. |
wolfSSL | 13:f67a6c6013ca | 8426 | * returns the method data for a TLS v1.3 client. |
wolfSSL | 13:f67a6c6013ca | 8427 | */ |
wolfSSL | 13:f67a6c6013ca | 8428 | WOLFSSL_METHOD* wolfTLSv1_3_client_method_ex(void* heap) |
wolfSSL | 13:f67a6c6013ca | 8429 | { |
wolfSSL | 13:f67a6c6013ca | 8430 | WOLFSSL_METHOD* method = (WOLFSSL_METHOD*) |
wolfSSL | 13:f67a6c6013ca | 8431 | XMALLOC(sizeof(WOLFSSL_METHOD), heap, |
wolfSSL | 13:f67a6c6013ca | 8432 | DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:f67a6c6013ca | 8433 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 8434 | if (method) { |
wolfSSL | 13:f67a6c6013ca | 8435 | InitSSL_Method(method, MakeTLSv1_3()); |
wolfSSL | 13:f67a6c6013ca | 8436 | method->downgrade = 1; |
wolfSSL | 13:f67a6c6013ca | 8437 | } |
wolfSSL | 13:f67a6c6013ca | 8438 | return method; |
wolfSSL | 13:f67a6c6013ca | 8439 | } |
wolfSSL | 13:f67a6c6013ca | 8440 | #endif /* WOLFSSL_TLS13 */ |
wolfSSL | 13:f67a6c6013ca | 8441 | |
wolfSSL | 13:f67a6c6013ca | 8442 | |
wolfSSL | 13:f67a6c6013ca | 8443 | WOLFSSL_METHOD* wolfSSLv23_client_method(void) |
wolfSSL | 13:f67a6c6013ca | 8444 | { |
wolfSSL | 13:f67a6c6013ca | 8445 | return wolfSSLv23_client_method_ex(NULL); |
wolfSSL | 13:f67a6c6013ca | 8446 | } |
wolfSSL | 13:f67a6c6013ca | 8447 | |
wolfSSL | 13:f67a6c6013ca | 8448 | |
wolfSSL | 13:f67a6c6013ca | 8449 | WOLFSSL_METHOD* wolfSSLv23_client_method_ex(void* heap) |
wolfSSL | 13:f67a6c6013ca | 8450 | { |
wolfSSL | 13:f67a6c6013ca | 8451 | WOLFSSL_METHOD* method = |
wolfSSL | 13:f67a6c6013ca | 8452 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:f67a6c6013ca | 8453 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:f67a6c6013ca | 8454 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 8455 | if (method) { |
wolfSSL | 13:f67a6c6013ca | 8456 | #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512) |
wolfSSL | 13:f67a6c6013ca | 8457 | #if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NGINX) |
wolfSSL | 13:f67a6c6013ca | 8458 | InitSSL_Method(method, MakeTLSv1_3()); |
wolfSSL | 13:f67a6c6013ca | 8459 | #else |
wolfSSL | 13:f67a6c6013ca | 8460 | InitSSL_Method(method, MakeTLSv1_2()); |
wolfSSL | 13:f67a6c6013ca | 8461 | #endif |
wolfSSL | 13:f67a6c6013ca | 8462 | #else |
wolfSSL | 13:f67a6c6013ca | 8463 | #ifndef NO_OLD_TLS |
wolfSSL | 13:f67a6c6013ca | 8464 | InitSSL_Method(method, MakeTLSv1_1()); |
wolfSSL | 13:f67a6c6013ca | 8465 | #endif |
wolfSSL | 13:f67a6c6013ca | 8466 | #endif |
wolfSSL | 13:f67a6c6013ca | 8467 | #ifndef NO_OLD_TLS |
wolfSSL | 13:f67a6c6013ca | 8468 | method->downgrade = 1; |
wolfSSL | 13:f67a6c6013ca | 8469 | #endif |
wolfSSL | 13:f67a6c6013ca | 8470 | } |
wolfSSL | 13:f67a6c6013ca | 8471 | return method; |
wolfSSL | 13:f67a6c6013ca | 8472 | } |
wolfSSL | 13:f67a6c6013ca | 8473 | |
wolfSSL | 13:f67a6c6013ca | 8474 | #endif /* NO_WOLFSSL_CLIENT */ |
wolfSSL | 13:f67a6c6013ca | 8475 | |
wolfSSL | 13:f67a6c6013ca | 8476 | |
wolfSSL | 13:f67a6c6013ca | 8477 | |
wolfSSL | 13:f67a6c6013ca | 8478 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:f67a6c6013ca | 8479 | |
wolfSSL | 13:f67a6c6013ca | 8480 | #ifndef NO_OLD_TLS |
wolfSSL | 13:f67a6c6013ca | 8481 | |
wolfSSL | 13:f67a6c6013ca | 8482 | WOLFSSL_METHOD* wolfTLSv1_server_method(void) |
wolfSSL | 13:f67a6c6013ca | 8483 | { |
wolfSSL | 13:f67a6c6013ca | 8484 | return wolfTLSv1_server_method_ex(NULL); |
wolfSSL | 13:f67a6c6013ca | 8485 | } |
wolfSSL | 13:f67a6c6013ca | 8486 | |
wolfSSL | 13:f67a6c6013ca | 8487 | |
wolfSSL | 13:f67a6c6013ca | 8488 | WOLFSSL_METHOD* wolfTLSv1_1_server_method(void) |
wolfSSL | 13:f67a6c6013ca | 8489 | { |
wolfSSL | 13:f67a6c6013ca | 8490 | return wolfTLSv1_1_server_method_ex(NULL); |
wolfSSL | 13:f67a6c6013ca | 8491 | } |
wolfSSL | 13:f67a6c6013ca | 8492 | |
wolfSSL | 13:f67a6c6013ca | 8493 | WOLFSSL_METHOD* wolfTLSv1_server_method_ex(void* heap) |
wolfSSL | 13:f67a6c6013ca | 8494 | { |
wolfSSL | 13:f67a6c6013ca | 8495 | WOLFSSL_METHOD* method = |
wolfSSL | 13:f67a6c6013ca | 8496 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:f67a6c6013ca | 8497 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:f67a6c6013ca | 8498 | if (method) { |
wolfSSL | 13:f67a6c6013ca | 8499 | InitSSL_Method(method, MakeTLSv1()); |
wolfSSL | 13:f67a6c6013ca | 8500 | method->side = WOLFSSL_SERVER_END; |
wolfSSL | 13:f67a6c6013ca | 8501 | } |
wolfSSL | 13:f67a6c6013ca | 8502 | return method; |
wolfSSL | 13:f67a6c6013ca | 8503 | } |
wolfSSL | 13:f67a6c6013ca | 8504 | |
wolfSSL | 13:f67a6c6013ca | 8505 | |
wolfSSL | 13:f67a6c6013ca | 8506 | WOLFSSL_METHOD* wolfTLSv1_1_server_method_ex(void* heap) |
wolfSSL | 13:f67a6c6013ca | 8507 | { |
wolfSSL | 13:f67a6c6013ca | 8508 | WOLFSSL_METHOD* method = |
wolfSSL | 13:f67a6c6013ca | 8509 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:f67a6c6013ca | 8510 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:f67a6c6013ca | 8511 | if (method) { |
wolfSSL | 13:f67a6c6013ca | 8512 | InitSSL_Method(method, MakeTLSv1_1()); |
wolfSSL | 13:f67a6c6013ca | 8513 | method->side = WOLFSSL_SERVER_END; |
wolfSSL | 13:f67a6c6013ca | 8514 | } |
wolfSSL | 13:f67a6c6013ca | 8515 | return method; |
wolfSSL | 13:f67a6c6013ca | 8516 | } |
wolfSSL | 13:f67a6c6013ca | 8517 | #endif /* !NO_OLD_TLS */ |
wolfSSL | 13:f67a6c6013ca | 8518 | |
wolfSSL | 13:f67a6c6013ca | 8519 | |
wolfSSL | 13:f67a6c6013ca | 8520 | WOLFSSL_METHOD* wolfTLSv1_2_server_method(void) |
wolfSSL | 13:f67a6c6013ca | 8521 | { |
wolfSSL | 13:f67a6c6013ca | 8522 | return wolfTLSv1_2_server_method_ex(NULL); |
wolfSSL | 13:f67a6c6013ca | 8523 | } |
wolfSSL | 13:f67a6c6013ca | 8524 | |
wolfSSL | 13:f67a6c6013ca | 8525 | WOLFSSL_METHOD* wolfTLSv1_2_server_method_ex(void* heap) |
wolfSSL | 13:f67a6c6013ca | 8526 | { |
wolfSSL | 13:f67a6c6013ca | 8527 | WOLFSSL_METHOD* method = |
wolfSSL | 13:f67a6c6013ca | 8528 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:f67a6c6013ca | 8529 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:f67a6c6013ca | 8530 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 8531 | if (method) { |
wolfSSL | 13:f67a6c6013ca | 8532 | InitSSL_Method(method, MakeTLSv1_2()); |
wolfSSL | 13:f67a6c6013ca | 8533 | method->side = WOLFSSL_SERVER_END; |
wolfSSL | 13:f67a6c6013ca | 8534 | } |
wolfSSL | 13:f67a6c6013ca | 8535 | return method; |
wolfSSL | 13:f67a6c6013ca | 8536 | } |
wolfSSL | 13:f67a6c6013ca | 8537 | |
wolfSSL | 13:f67a6c6013ca | 8538 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 8539 | /* The TLS v1.3 server method data. |
wolfSSL | 13:f67a6c6013ca | 8540 | * |
wolfSSL | 13:f67a6c6013ca | 8541 | * returns the method data for a TLS v1.3 server. |
wolfSSL | 13:f67a6c6013ca | 8542 | */ |
wolfSSL | 13:f67a6c6013ca | 8543 | WOLFSSL_METHOD* wolfTLSv1_3_server_method(void) |
wolfSSL | 13:f67a6c6013ca | 8544 | { |
wolfSSL | 13:f67a6c6013ca | 8545 | return wolfTLSv1_3_server_method_ex(NULL); |
wolfSSL | 13:f67a6c6013ca | 8546 | } |
wolfSSL | 13:f67a6c6013ca | 8547 | |
wolfSSL | 13:f67a6c6013ca | 8548 | /* The TLS v1.3 server method data. |
wolfSSL | 13:f67a6c6013ca | 8549 | * |
wolfSSL | 13:f67a6c6013ca | 8550 | * heap The heap used for allocation. |
wolfSSL | 13:f67a6c6013ca | 8551 | * returns the method data for a TLS v1.3 server. |
wolfSSL | 13:f67a6c6013ca | 8552 | */ |
wolfSSL | 13:f67a6c6013ca | 8553 | WOLFSSL_METHOD* wolfTLSv1_3_server_method_ex(void* heap) |
wolfSSL | 13:f67a6c6013ca | 8554 | { |
wolfSSL | 13:f67a6c6013ca | 8555 | WOLFSSL_METHOD* method = |
wolfSSL | 13:f67a6c6013ca | 8556 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:f67a6c6013ca | 8557 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:f67a6c6013ca | 8558 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 8559 | if (method) { |
wolfSSL | 13:f67a6c6013ca | 8560 | InitSSL_Method(method, MakeTLSv1_3()); |
wolfSSL | 13:f67a6c6013ca | 8561 | method->side = WOLFSSL_SERVER_END; |
wolfSSL | 13:f67a6c6013ca | 8562 | } |
wolfSSL | 13:f67a6c6013ca | 8563 | return method; |
wolfSSL | 13:f67a6c6013ca | 8564 | } |
wolfSSL | 13:f67a6c6013ca | 8565 | #endif /* WOLFSSL_TLS13 */ |
wolfSSL | 13:f67a6c6013ca | 8566 | |
wolfSSL | 13:f67a6c6013ca | 8567 | WOLFSSL_METHOD* wolfSSLv23_server_method(void) |
wolfSSL | 13:f67a6c6013ca | 8568 | { |
wolfSSL | 13:f67a6c6013ca | 8569 | return wolfSSLv23_server_method_ex(NULL); |
wolfSSL | 13:f67a6c6013ca | 8570 | } |
wolfSSL | 13:f67a6c6013ca | 8571 | |
wolfSSL | 13:f67a6c6013ca | 8572 | WOLFSSL_METHOD* wolfSSLv23_server_method_ex(void* heap) |
wolfSSL | 13:f67a6c6013ca | 8573 | { |
wolfSSL | 13:f67a6c6013ca | 8574 | WOLFSSL_METHOD* method = |
wolfSSL | 13:f67a6c6013ca | 8575 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:f67a6c6013ca | 8576 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:f67a6c6013ca | 8577 | (void)heap; |
wolfSSL | 13:f67a6c6013ca | 8578 | if (method) { |
wolfSSL | 13:f67a6c6013ca | 8579 | #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512) |
wolfSSL | 13:f67a6c6013ca | 8580 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:f67a6c6013ca | 8581 | InitSSL_Method(method, MakeTLSv1_3()); |
wolfSSL | 13:f67a6c6013ca | 8582 | #else |
wolfSSL | 13:f67a6c6013ca | 8583 | InitSSL_Method(method, MakeTLSv1_2()); |
wolfSSL | 13:f67a6c6013ca | 8584 | #endif |
wolfSSL | 13:f67a6c6013ca | 8585 | #else |
wolfSSL | 13:f67a6c6013ca | 8586 | #ifndef NO_OLD_TLS |
wolfSSL | 13:f67a6c6013ca | 8587 | InitSSL_Method(method, MakeTLSv1_1()); |
wolfSSL | 13:f67a6c6013ca | 8588 | #else |
wolfSSL | 13:f67a6c6013ca | 8589 | #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2 |
wolfSSL | 13:f67a6c6013ca | 8590 | #endif |
wolfSSL | 13:f67a6c6013ca | 8591 | #endif |
wolfSSL | 13:f67a6c6013ca | 8592 | #ifndef NO_OLD_TLS |
wolfSSL | 13:f67a6c6013ca | 8593 | method->downgrade = 1; |
wolfSSL | 13:f67a6c6013ca | 8594 | #endif |
wolfSSL | 13:f67a6c6013ca | 8595 | method->side = WOLFSSL_SERVER_END; |
wolfSSL | 13:f67a6c6013ca | 8596 | } |
wolfSSL | 13:f67a6c6013ca | 8597 | return method; |
wolfSSL | 13:f67a6c6013ca | 8598 | } |
wolfSSL | 13:f67a6c6013ca | 8599 | |
wolfSSL | 13:f67a6c6013ca | 8600 | |
wolfSSL | 13:f67a6c6013ca | 8601 | #endif /* NO_WOLFSSL_SERVER */ |
wolfSSL | 13:f67a6c6013ca | 8602 | #endif /* NO_TLS */ |
wolfSSL | 13:f67a6c6013ca | 8603 | #endif /* WOLFCRYPT_ONLY */ |
wolfSSL | 13:f67a6c6013ca | 8604 |