wolfSSL 3.11.1 for TLS1.3 beta
Fork of wolfSSL by
src/tls.c@13:80fb167dafdf, 2017-05-30 (annotated)
- Committer:
- wolfSSL
- Date:
- Tue May 30 06:16:19 2017 +0000
- Revision:
- 13:80fb167dafdf
wolfSSL 3.11.1: TLS1.3 Beta
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wolfSSL | 13:80fb167dafdf | 1 | /* tls.c |
wolfSSL | 13:80fb167dafdf | 2 | * |
wolfSSL | 13:80fb167dafdf | 3 | * Copyright (C) 2006-2016 wolfSSL Inc. |
wolfSSL | 13:80fb167dafdf | 4 | * |
wolfSSL | 13:80fb167dafdf | 5 | * This file is part of wolfSSL. |
wolfSSL | 13:80fb167dafdf | 6 | * |
wolfSSL | 13:80fb167dafdf | 7 | * wolfSSL is free software; you can redistribute it and/or modify |
wolfSSL | 13:80fb167dafdf | 8 | * it under the terms of the GNU General Public License as published by |
wolfSSL | 13:80fb167dafdf | 9 | * the Free Software Foundation; either version 2 of the License, or |
wolfSSL | 13:80fb167dafdf | 10 | * (at your option) any later version. |
wolfSSL | 13:80fb167dafdf | 11 | * |
wolfSSL | 13:80fb167dafdf | 12 | * wolfSSL is distributed in the hope that it will be useful, |
wolfSSL | 13:80fb167dafdf | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
wolfSSL | 13:80fb167dafdf | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
wolfSSL | 13:80fb167dafdf | 15 | * GNU General Public License for more details. |
wolfSSL | 13:80fb167dafdf | 16 | * |
wolfSSL | 13:80fb167dafdf | 17 | * You should have received a copy of the GNU General Public License |
wolfSSL | 13:80fb167dafdf | 18 | * along with this program; if not, write to the Free Software |
wolfSSL | 13:80fb167dafdf | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA |
wolfSSL | 13:80fb167dafdf | 20 | */ |
wolfSSL | 13:80fb167dafdf | 21 | |
wolfSSL | 13:80fb167dafdf | 22 | |
wolfSSL | 13:80fb167dafdf | 23 | |
wolfSSL | 13:80fb167dafdf | 24 | #ifdef HAVE_CONFIG_H |
wolfSSL | 13:80fb167dafdf | 25 | #include <config.h> |
wolfSSL | 13:80fb167dafdf | 26 | #endif |
wolfSSL | 13:80fb167dafdf | 27 | |
wolfSSL | 13:80fb167dafdf | 28 | #include <wolfssl/wolfcrypt/settings.h> |
wolfSSL | 13:80fb167dafdf | 29 | |
wolfSSL | 13:80fb167dafdf | 30 | #ifndef WOLFCRYPT_ONLY |
wolfSSL | 13:80fb167dafdf | 31 | |
wolfSSL | 13:80fb167dafdf | 32 | #include <wolfssl/ssl.h> |
wolfSSL | 13:80fb167dafdf | 33 | #include <wolfssl/internal.h> |
wolfSSL | 13:80fb167dafdf | 34 | #include <wolfssl/error-ssl.h> |
wolfSSL | 13:80fb167dafdf | 35 | #include <wolfssl/wolfcrypt/hmac.h> |
wolfSSL | 13:80fb167dafdf | 36 | #ifdef NO_INLINE |
wolfSSL | 13:80fb167dafdf | 37 | #include <wolfssl/wolfcrypt/misc.h> |
wolfSSL | 13:80fb167dafdf | 38 | #else |
wolfSSL | 13:80fb167dafdf | 39 | #define WOLFSSL_MISC_INCLUDED |
wolfSSL | 13:80fb167dafdf | 40 | #include <wolfcrypt/src/misc.c> |
wolfSSL | 13:80fb167dafdf | 41 | #endif |
wolfSSL | 13:80fb167dafdf | 42 | |
wolfSSL | 13:80fb167dafdf | 43 | #ifdef HAVE_CURVE25519 |
wolfSSL | 13:80fb167dafdf | 44 | #include <wolfssl/wolfcrypt/curve25519.h> |
wolfSSL | 13:80fb167dafdf | 45 | #endif |
wolfSSL | 13:80fb167dafdf | 46 | |
wolfSSL | 13:80fb167dafdf | 47 | #ifdef HAVE_NTRU |
wolfSSL | 13:80fb167dafdf | 48 | #include "libntruencrypt/ntru_crypto.h" |
wolfSSL | 13:80fb167dafdf | 49 | #include <wolfssl/wolfcrypt/random.h> |
wolfSSL | 13:80fb167dafdf | 50 | #endif |
wolfSSL | 13:80fb167dafdf | 51 | #ifdef HAVE_QSH |
wolfSSL | 13:80fb167dafdf | 52 | static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key); |
wolfSSL | 13:80fb167dafdf | 53 | static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name); |
wolfSSL | 13:80fb167dafdf | 54 | #endif |
wolfSSL | 13:80fb167dafdf | 55 | #if defined(HAVE_NTRU) || defined(HAVE_QSH) |
wolfSSL | 13:80fb167dafdf | 56 | static int TLSX_CreateNtruKey(WOLFSSL* ssl, int type); |
wolfSSL | 13:80fb167dafdf | 57 | #endif |
wolfSSL | 13:80fb167dafdf | 58 | |
wolfSSL | 13:80fb167dafdf | 59 | |
wolfSSL | 13:80fb167dafdf | 60 | #ifndef NO_TLS |
wolfSSL | 13:80fb167dafdf | 61 | |
wolfSSL | 13:80fb167dafdf | 62 | /* Digest enable checks */ |
wolfSSL | 13:80fb167dafdf | 63 | #ifdef NO_OLD_TLS /* TLS 1.2 only */ |
wolfSSL | 13:80fb167dafdf | 64 | #if defined(NO_SHA256) && !defined(WOLFSSL_SHA384) && \ |
wolfSSL | 13:80fb167dafdf | 65 | !defined(WOLFSSL_SHA512) |
wolfSSL | 13:80fb167dafdf | 66 | #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2 |
wolfSSL | 13:80fb167dafdf | 67 | #endif |
wolfSSL | 13:80fb167dafdf | 68 | #else /* TLS 1.1 or older */ |
wolfSSL | 13:80fb167dafdf | 69 | #if defined(NO_MD5) && defined(NO_SHA) |
wolfSSL | 13:80fb167dafdf | 70 | #error Must have SHA1 and MD5 enabled for old TLS |
wolfSSL | 13:80fb167dafdf | 71 | #endif |
wolfSSL | 13:80fb167dafdf | 72 | #endif |
wolfSSL | 13:80fb167dafdf | 73 | |
wolfSSL | 13:80fb167dafdf | 74 | |
wolfSSL | 13:80fb167dafdf | 75 | #ifdef WOLFSSL_SHA384 |
wolfSSL | 13:80fb167dafdf | 76 | #define P_HASH_MAX_SIZE SHA384_DIGEST_SIZE |
wolfSSL | 13:80fb167dafdf | 77 | #else |
wolfSSL | 13:80fb167dafdf | 78 | #define P_HASH_MAX_SIZE SHA256_DIGEST_SIZE |
wolfSSL | 13:80fb167dafdf | 79 | #endif |
wolfSSL | 13:80fb167dafdf | 80 | |
wolfSSL | 13:80fb167dafdf | 81 | |
wolfSSL | 13:80fb167dafdf | 82 | /* compute p_hash for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1 PRF */ |
wolfSSL | 13:80fb167dafdf | 83 | static int p_hash(byte* result, word32 resLen, const byte* secret, |
wolfSSL | 13:80fb167dafdf | 84 | word32 secLen, const byte* seed, word32 seedLen, int hash) |
wolfSSL | 13:80fb167dafdf | 85 | { |
wolfSSL | 13:80fb167dafdf | 86 | word32 len = P_HASH_MAX_SIZE; |
wolfSSL | 13:80fb167dafdf | 87 | word32 times; |
wolfSSL | 13:80fb167dafdf | 88 | word32 lastLen; |
wolfSSL | 13:80fb167dafdf | 89 | word32 lastTime; |
wolfSSL | 13:80fb167dafdf | 90 | word32 i; |
wolfSSL | 13:80fb167dafdf | 91 | word32 idx = 0; |
wolfSSL | 13:80fb167dafdf | 92 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 93 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:80fb167dafdf | 94 | byte* previous; |
wolfSSL | 13:80fb167dafdf | 95 | byte* current; |
wolfSSL | 13:80fb167dafdf | 96 | Hmac* hmac; |
wolfSSL | 13:80fb167dafdf | 97 | #else |
wolfSSL | 13:80fb167dafdf | 98 | byte previous[P_HASH_MAX_SIZE]; /* max size */ |
wolfSSL | 13:80fb167dafdf | 99 | byte current[P_HASH_MAX_SIZE]; /* max size */ |
wolfSSL | 13:80fb167dafdf | 100 | Hmac hmac[1]; |
wolfSSL | 13:80fb167dafdf | 101 | #endif |
wolfSSL | 13:80fb167dafdf | 102 | |
wolfSSL | 13:80fb167dafdf | 103 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:80fb167dafdf | 104 | previous = (byte*)XMALLOC(P_HASH_MAX_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 105 | current = (byte*)XMALLOC(P_HASH_MAX_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 106 | hmac = (Hmac*)XMALLOC(sizeof(Hmac), NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 107 | |
wolfSSL | 13:80fb167dafdf | 108 | if (previous == NULL || current == NULL || hmac == NULL) { |
wolfSSL | 13:80fb167dafdf | 109 | if (previous) XFREE(previous, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 110 | if (current) XFREE(current, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 111 | if (hmac) XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 112 | |
wolfSSL | 13:80fb167dafdf | 113 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 114 | } |
wolfSSL | 13:80fb167dafdf | 115 | #endif |
wolfSSL | 13:80fb167dafdf | 116 | |
wolfSSL | 13:80fb167dafdf | 117 | switch (hash) { |
wolfSSL | 13:80fb167dafdf | 118 | #ifndef NO_MD5 |
wolfSSL | 13:80fb167dafdf | 119 | case md5_mac: |
wolfSSL | 13:80fb167dafdf | 120 | hash = MD5; |
wolfSSL | 13:80fb167dafdf | 121 | len = MD5_DIGEST_SIZE; |
wolfSSL | 13:80fb167dafdf | 122 | break; |
wolfSSL | 13:80fb167dafdf | 123 | #endif |
wolfSSL | 13:80fb167dafdf | 124 | |
wolfSSL | 13:80fb167dafdf | 125 | #ifndef NO_SHA256 |
wolfSSL | 13:80fb167dafdf | 126 | case sha256_mac: |
wolfSSL | 13:80fb167dafdf | 127 | hash = SHA256; |
wolfSSL | 13:80fb167dafdf | 128 | len = SHA256_DIGEST_SIZE; |
wolfSSL | 13:80fb167dafdf | 129 | break; |
wolfSSL | 13:80fb167dafdf | 130 | #endif |
wolfSSL | 13:80fb167dafdf | 131 | |
wolfSSL | 13:80fb167dafdf | 132 | #ifdef WOLFSSL_SHA384 |
wolfSSL | 13:80fb167dafdf | 133 | case sha384_mac: |
wolfSSL | 13:80fb167dafdf | 134 | hash = SHA384; |
wolfSSL | 13:80fb167dafdf | 135 | len = SHA384_DIGEST_SIZE; |
wolfSSL | 13:80fb167dafdf | 136 | break; |
wolfSSL | 13:80fb167dafdf | 137 | #endif |
wolfSSL | 13:80fb167dafdf | 138 | |
wolfSSL | 13:80fb167dafdf | 139 | #ifndef NO_SHA |
wolfSSL | 13:80fb167dafdf | 140 | case sha_mac: |
wolfSSL | 13:80fb167dafdf | 141 | default: |
wolfSSL | 13:80fb167dafdf | 142 | hash = SHA; |
wolfSSL | 13:80fb167dafdf | 143 | len = SHA_DIGEST_SIZE; |
wolfSSL | 13:80fb167dafdf | 144 | break; |
wolfSSL | 13:80fb167dafdf | 145 | #endif |
wolfSSL | 13:80fb167dafdf | 146 | } |
wolfSSL | 13:80fb167dafdf | 147 | |
wolfSSL | 13:80fb167dafdf | 148 | times = resLen / len; |
wolfSSL | 13:80fb167dafdf | 149 | lastLen = resLen % len; |
wolfSSL | 13:80fb167dafdf | 150 | |
wolfSSL | 13:80fb167dafdf | 151 | if (lastLen) |
wolfSSL | 13:80fb167dafdf | 152 | times += 1; |
wolfSSL | 13:80fb167dafdf | 153 | |
wolfSSL | 13:80fb167dafdf | 154 | lastTime = times - 1; |
wolfSSL | 13:80fb167dafdf | 155 | |
wolfSSL | 13:80fb167dafdf | 156 | ret = wc_HmacInit(hmac, NULL, INVALID_DEVID); |
wolfSSL | 13:80fb167dafdf | 157 | if (ret == 0) { |
wolfSSL | 13:80fb167dafdf | 158 | ret = wc_HmacSetKey(hmac, hash, secret, secLen); |
wolfSSL | 13:80fb167dafdf | 159 | if (ret == 0) |
wolfSSL | 13:80fb167dafdf | 160 | ret = wc_HmacUpdate(hmac, seed, seedLen); /* A0 = seed */ |
wolfSSL | 13:80fb167dafdf | 161 | if (ret == 0) |
wolfSSL | 13:80fb167dafdf | 162 | ret = wc_HmacFinal(hmac, previous); /* A1 */ |
wolfSSL | 13:80fb167dafdf | 163 | if (ret == 0) { |
wolfSSL | 13:80fb167dafdf | 164 | for (i = 0; i < times; i++) { |
wolfSSL | 13:80fb167dafdf | 165 | ret = wc_HmacUpdate(hmac, previous, len); |
wolfSSL | 13:80fb167dafdf | 166 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 167 | break; |
wolfSSL | 13:80fb167dafdf | 168 | ret = wc_HmacUpdate(hmac, seed, seedLen); |
wolfSSL | 13:80fb167dafdf | 169 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 170 | break; |
wolfSSL | 13:80fb167dafdf | 171 | ret = wc_HmacFinal(hmac, current); |
wolfSSL | 13:80fb167dafdf | 172 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 173 | break; |
wolfSSL | 13:80fb167dafdf | 174 | |
wolfSSL | 13:80fb167dafdf | 175 | if ((i == lastTime) && lastLen) |
wolfSSL | 13:80fb167dafdf | 176 | XMEMCPY(&result[idx], current, |
wolfSSL | 13:80fb167dafdf | 177 | min(lastLen, P_HASH_MAX_SIZE)); |
wolfSSL | 13:80fb167dafdf | 178 | else { |
wolfSSL | 13:80fb167dafdf | 179 | XMEMCPY(&result[idx], current, len); |
wolfSSL | 13:80fb167dafdf | 180 | idx += len; |
wolfSSL | 13:80fb167dafdf | 181 | ret = wc_HmacUpdate(hmac, previous, len); |
wolfSSL | 13:80fb167dafdf | 182 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 183 | break; |
wolfSSL | 13:80fb167dafdf | 184 | ret = wc_HmacFinal(hmac, previous); |
wolfSSL | 13:80fb167dafdf | 185 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 186 | break; |
wolfSSL | 13:80fb167dafdf | 187 | } |
wolfSSL | 13:80fb167dafdf | 188 | } |
wolfSSL | 13:80fb167dafdf | 189 | } |
wolfSSL | 13:80fb167dafdf | 190 | wc_HmacFree(hmac); |
wolfSSL | 13:80fb167dafdf | 191 | } |
wolfSSL | 13:80fb167dafdf | 192 | |
wolfSSL | 13:80fb167dafdf | 193 | ForceZero(previous, P_HASH_MAX_SIZE); |
wolfSSL | 13:80fb167dafdf | 194 | ForceZero(current, P_HASH_MAX_SIZE); |
wolfSSL | 13:80fb167dafdf | 195 | ForceZero(hmac, sizeof(Hmac)); |
wolfSSL | 13:80fb167dafdf | 196 | |
wolfSSL | 13:80fb167dafdf | 197 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:80fb167dafdf | 198 | XFREE(previous, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 199 | XFREE(current, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 200 | XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 201 | #endif |
wolfSSL | 13:80fb167dafdf | 202 | |
wolfSSL | 13:80fb167dafdf | 203 | return ret; |
wolfSSL | 13:80fb167dafdf | 204 | } |
wolfSSL | 13:80fb167dafdf | 205 | |
wolfSSL | 13:80fb167dafdf | 206 | #undef P_HASH_MAX_SIZE |
wolfSSL | 13:80fb167dafdf | 207 | |
wolfSSL | 13:80fb167dafdf | 208 | |
wolfSSL | 13:80fb167dafdf | 209 | #ifndef NO_OLD_TLS |
wolfSSL | 13:80fb167dafdf | 210 | |
wolfSSL | 13:80fb167dafdf | 211 | /* calculate XOR for TLSv1 PRF */ |
wolfSSL | 13:80fb167dafdf | 212 | static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha) |
wolfSSL | 13:80fb167dafdf | 213 | { |
wolfSSL | 13:80fb167dafdf | 214 | word32 i; |
wolfSSL | 13:80fb167dafdf | 215 | |
wolfSSL | 13:80fb167dafdf | 216 | for (i = 0; i < digLen; i++) |
wolfSSL | 13:80fb167dafdf | 217 | digest[i] = md5[i] ^ sha[i]; |
wolfSSL | 13:80fb167dafdf | 218 | } |
wolfSSL | 13:80fb167dafdf | 219 | |
wolfSSL | 13:80fb167dafdf | 220 | |
wolfSSL | 13:80fb167dafdf | 221 | /* compute TLSv1 PRF (pseudo random function using HMAC) */ |
wolfSSL | 13:80fb167dafdf | 222 | static int doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen, |
wolfSSL | 13:80fb167dafdf | 223 | const byte* label, word32 labLen, const byte* seed, |
wolfSSL | 13:80fb167dafdf | 224 | word32 seedLen) |
wolfSSL | 13:80fb167dafdf | 225 | { |
wolfSSL | 13:80fb167dafdf | 226 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 227 | word32 half = (secLen + 1) / 2; |
wolfSSL | 13:80fb167dafdf | 228 | |
wolfSSL | 13:80fb167dafdf | 229 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:80fb167dafdf | 230 | byte* md5_half; |
wolfSSL | 13:80fb167dafdf | 231 | byte* sha_half; |
wolfSSL | 13:80fb167dafdf | 232 | byte* labelSeed; |
wolfSSL | 13:80fb167dafdf | 233 | byte* md5_result; |
wolfSSL | 13:80fb167dafdf | 234 | byte* sha_result; |
wolfSSL | 13:80fb167dafdf | 235 | #else |
wolfSSL | 13:80fb167dafdf | 236 | byte md5_half[MAX_PRF_HALF]; /* half is real size */ |
wolfSSL | 13:80fb167dafdf | 237 | byte sha_half[MAX_PRF_HALF]; /* half is real size */ |
wolfSSL | 13:80fb167dafdf | 238 | byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */ |
wolfSSL | 13:80fb167dafdf | 239 | byte md5_result[MAX_PRF_DIG]; /* digLen is real size */ |
wolfSSL | 13:80fb167dafdf | 240 | byte sha_result[MAX_PRF_DIG]; /* digLen is real size */ |
wolfSSL | 13:80fb167dafdf | 241 | #endif |
wolfSSL | 13:80fb167dafdf | 242 | |
wolfSSL | 13:80fb167dafdf | 243 | if (half > MAX_PRF_HALF) |
wolfSSL | 13:80fb167dafdf | 244 | return BUFFER_E; |
wolfSSL | 13:80fb167dafdf | 245 | if (labLen + seedLen > MAX_PRF_LABSEED) |
wolfSSL | 13:80fb167dafdf | 246 | return BUFFER_E; |
wolfSSL | 13:80fb167dafdf | 247 | if (digLen > MAX_PRF_DIG) |
wolfSSL | 13:80fb167dafdf | 248 | return BUFFER_E; |
wolfSSL | 13:80fb167dafdf | 249 | |
wolfSSL | 13:80fb167dafdf | 250 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:80fb167dafdf | 251 | md5_half = (byte*)XMALLOC(MAX_PRF_HALF, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 252 | sha_half = (byte*)XMALLOC(MAX_PRF_HALF, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 253 | labelSeed = (byte*)XMALLOC(MAX_PRF_LABSEED, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 254 | md5_result = (byte*)XMALLOC(MAX_PRF_DIG, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 255 | sha_result = (byte*)XMALLOC(MAX_PRF_DIG, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 256 | |
wolfSSL | 13:80fb167dafdf | 257 | if (md5_half == NULL || sha_half == NULL || labelSeed == NULL || |
wolfSSL | 13:80fb167dafdf | 258 | md5_result == NULL || sha_result == NULL) { |
wolfSSL | 13:80fb167dafdf | 259 | if (md5_half) XFREE(md5_half, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 260 | if (sha_half) XFREE(sha_half, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 261 | if (labelSeed) XFREE(labelSeed, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 262 | if (md5_result) XFREE(md5_result, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 263 | if (sha_result) XFREE(sha_result, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 264 | |
wolfSSL | 13:80fb167dafdf | 265 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 266 | } |
wolfSSL | 13:80fb167dafdf | 267 | #endif |
wolfSSL | 13:80fb167dafdf | 268 | |
wolfSSL | 13:80fb167dafdf | 269 | XMEMSET(md5_result, 0, digLen); |
wolfSSL | 13:80fb167dafdf | 270 | XMEMSET(sha_result, 0, digLen); |
wolfSSL | 13:80fb167dafdf | 271 | |
wolfSSL | 13:80fb167dafdf | 272 | XMEMCPY(md5_half, secret, half); |
wolfSSL | 13:80fb167dafdf | 273 | XMEMCPY(sha_half, secret + half - secLen % 2, half); |
wolfSSL | 13:80fb167dafdf | 274 | |
wolfSSL | 13:80fb167dafdf | 275 | XMEMCPY(labelSeed, label, labLen); |
wolfSSL | 13:80fb167dafdf | 276 | XMEMCPY(labelSeed + labLen, seed, seedLen); |
wolfSSL | 13:80fb167dafdf | 277 | |
wolfSSL | 13:80fb167dafdf | 278 | if ((ret = p_hash(md5_result, digLen, md5_half, half, labelSeed, |
wolfSSL | 13:80fb167dafdf | 279 | labLen + seedLen, md5_mac)) == 0) { |
wolfSSL | 13:80fb167dafdf | 280 | if ((ret = p_hash(sha_result, digLen, sha_half, half, labelSeed, |
wolfSSL | 13:80fb167dafdf | 281 | labLen + seedLen, sha_mac)) == 0) { |
wolfSSL | 13:80fb167dafdf | 282 | get_xor(digest, digLen, md5_result, sha_result); |
wolfSSL | 13:80fb167dafdf | 283 | } |
wolfSSL | 13:80fb167dafdf | 284 | } |
wolfSSL | 13:80fb167dafdf | 285 | |
wolfSSL | 13:80fb167dafdf | 286 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:80fb167dafdf | 287 | XFREE(md5_half, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 288 | XFREE(sha_half, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 289 | XFREE(labelSeed, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 290 | XFREE(md5_result, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 291 | XFREE(sha_result, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 292 | #endif |
wolfSSL | 13:80fb167dafdf | 293 | |
wolfSSL | 13:80fb167dafdf | 294 | return ret; |
wolfSSL | 13:80fb167dafdf | 295 | } |
wolfSSL | 13:80fb167dafdf | 296 | |
wolfSSL | 13:80fb167dafdf | 297 | #endif |
wolfSSL | 13:80fb167dafdf | 298 | |
wolfSSL | 13:80fb167dafdf | 299 | |
wolfSSL | 13:80fb167dafdf | 300 | /* Wrapper to call straight thru to p_hash in TSL 1.2 cases to remove stack |
wolfSSL | 13:80fb167dafdf | 301 | use */ |
wolfSSL | 13:80fb167dafdf | 302 | static int PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen, |
wolfSSL | 13:80fb167dafdf | 303 | const byte* label, word32 labLen, const byte* seed, word32 seedLen, |
wolfSSL | 13:80fb167dafdf | 304 | int useAtLeastSha256, int hash_type) |
wolfSSL | 13:80fb167dafdf | 305 | { |
wolfSSL | 13:80fb167dafdf | 306 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 307 | |
wolfSSL | 13:80fb167dafdf | 308 | if (useAtLeastSha256) { |
wolfSSL | 13:80fb167dafdf | 309 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:80fb167dafdf | 310 | byte* labelSeed; |
wolfSSL | 13:80fb167dafdf | 311 | #else |
wolfSSL | 13:80fb167dafdf | 312 | byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */ |
wolfSSL | 13:80fb167dafdf | 313 | #endif |
wolfSSL | 13:80fb167dafdf | 314 | |
wolfSSL | 13:80fb167dafdf | 315 | if (labLen + seedLen > MAX_PRF_LABSEED) |
wolfSSL | 13:80fb167dafdf | 316 | return BUFFER_E; |
wolfSSL | 13:80fb167dafdf | 317 | |
wolfSSL | 13:80fb167dafdf | 318 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:80fb167dafdf | 319 | labelSeed = (byte*)XMALLOC(MAX_PRF_LABSEED, NULL, |
wolfSSL | 13:80fb167dafdf | 320 | DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 321 | if (labelSeed == NULL) |
wolfSSL | 13:80fb167dafdf | 322 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 323 | #endif |
wolfSSL | 13:80fb167dafdf | 324 | |
wolfSSL | 13:80fb167dafdf | 325 | XMEMCPY(labelSeed, label, labLen); |
wolfSSL | 13:80fb167dafdf | 326 | XMEMCPY(labelSeed + labLen, seed, seedLen); |
wolfSSL | 13:80fb167dafdf | 327 | |
wolfSSL | 13:80fb167dafdf | 328 | /* If a cipher suite wants an algorithm better than sha256, it |
wolfSSL | 13:80fb167dafdf | 329 | * should use better. */ |
wolfSSL | 13:80fb167dafdf | 330 | if (hash_type < sha256_mac || hash_type == blake2b_mac) |
wolfSSL | 13:80fb167dafdf | 331 | hash_type = sha256_mac; |
wolfSSL | 13:80fb167dafdf | 332 | ret = p_hash(digest, digLen, secret, secLen, labelSeed, |
wolfSSL | 13:80fb167dafdf | 333 | labLen + seedLen, hash_type); |
wolfSSL | 13:80fb167dafdf | 334 | |
wolfSSL | 13:80fb167dafdf | 335 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:80fb167dafdf | 336 | XFREE(labelSeed, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 337 | #endif |
wolfSSL | 13:80fb167dafdf | 338 | } |
wolfSSL | 13:80fb167dafdf | 339 | #ifndef NO_OLD_TLS |
wolfSSL | 13:80fb167dafdf | 340 | else { |
wolfSSL | 13:80fb167dafdf | 341 | ret = doPRF(digest, digLen, secret, secLen, label, labLen, seed, |
wolfSSL | 13:80fb167dafdf | 342 | seedLen); |
wolfSSL | 13:80fb167dafdf | 343 | } |
wolfSSL | 13:80fb167dafdf | 344 | #endif |
wolfSSL | 13:80fb167dafdf | 345 | |
wolfSSL | 13:80fb167dafdf | 346 | return ret; |
wolfSSL | 13:80fb167dafdf | 347 | } |
wolfSSL | 13:80fb167dafdf | 348 | |
wolfSSL | 13:80fb167dafdf | 349 | #ifdef WOLFSSL_SHA384 |
wolfSSL | 13:80fb167dafdf | 350 | #define HSHASH_SZ SHA384_DIGEST_SIZE |
wolfSSL | 13:80fb167dafdf | 351 | #else |
wolfSSL | 13:80fb167dafdf | 352 | #define HSHASH_SZ FINISHED_SZ |
wolfSSL | 13:80fb167dafdf | 353 | #endif |
wolfSSL | 13:80fb167dafdf | 354 | |
wolfSSL | 13:80fb167dafdf | 355 | |
wolfSSL | 13:80fb167dafdf | 356 | int BuildTlsHandshakeHash(WOLFSSL* ssl, byte* hash, word32* hashLen) |
wolfSSL | 13:80fb167dafdf | 357 | { |
wolfSSL | 13:80fb167dafdf | 358 | word32 hashSz = FINISHED_SZ; |
wolfSSL | 13:80fb167dafdf | 359 | |
wolfSSL | 13:80fb167dafdf | 360 | if (ssl == NULL || hash == NULL || hashLen == NULL || *hashLen < HSHASH_SZ) |
wolfSSL | 13:80fb167dafdf | 361 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 362 | |
wolfSSL | 13:80fb167dafdf | 363 | #ifndef NO_OLD_TLS |
wolfSSL | 13:80fb167dafdf | 364 | wc_Md5GetHash(&ssl->hsHashes->hashMd5, hash); |
wolfSSL | 13:80fb167dafdf | 365 | wc_ShaGetHash(&ssl->hsHashes->hashSha, &hash[MD5_DIGEST_SIZE]); |
wolfSSL | 13:80fb167dafdf | 366 | #endif |
wolfSSL | 13:80fb167dafdf | 367 | |
wolfSSL | 13:80fb167dafdf | 368 | if (IsAtLeastTLSv1_2(ssl)) { |
wolfSSL | 13:80fb167dafdf | 369 | #ifndef NO_SHA256 |
wolfSSL | 13:80fb167dafdf | 370 | if (ssl->specs.mac_algorithm <= sha256_mac || |
wolfSSL | 13:80fb167dafdf | 371 | ssl->specs.mac_algorithm == blake2b_mac) { |
wolfSSL | 13:80fb167dafdf | 372 | int ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash); |
wolfSSL | 13:80fb167dafdf | 373 | |
wolfSSL | 13:80fb167dafdf | 374 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 375 | return ret; |
wolfSSL | 13:80fb167dafdf | 376 | |
wolfSSL | 13:80fb167dafdf | 377 | hashSz = SHA256_DIGEST_SIZE; |
wolfSSL | 13:80fb167dafdf | 378 | } |
wolfSSL | 13:80fb167dafdf | 379 | #endif |
wolfSSL | 13:80fb167dafdf | 380 | #ifdef WOLFSSL_SHA384 |
wolfSSL | 13:80fb167dafdf | 381 | if (ssl->specs.mac_algorithm == sha384_mac) { |
wolfSSL | 13:80fb167dafdf | 382 | int ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash); |
wolfSSL | 13:80fb167dafdf | 383 | |
wolfSSL | 13:80fb167dafdf | 384 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 385 | return ret; |
wolfSSL | 13:80fb167dafdf | 386 | |
wolfSSL | 13:80fb167dafdf | 387 | hashSz = SHA384_DIGEST_SIZE; |
wolfSSL | 13:80fb167dafdf | 388 | } |
wolfSSL | 13:80fb167dafdf | 389 | #endif |
wolfSSL | 13:80fb167dafdf | 390 | } |
wolfSSL | 13:80fb167dafdf | 391 | |
wolfSSL | 13:80fb167dafdf | 392 | *hashLen = hashSz; |
wolfSSL | 13:80fb167dafdf | 393 | |
wolfSSL | 13:80fb167dafdf | 394 | return 0; |
wolfSSL | 13:80fb167dafdf | 395 | } |
wolfSSL | 13:80fb167dafdf | 396 | |
wolfSSL | 13:80fb167dafdf | 397 | |
wolfSSL | 13:80fb167dafdf | 398 | int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) |
wolfSSL | 13:80fb167dafdf | 399 | { |
wolfSSL | 13:80fb167dafdf | 400 | int ret; |
wolfSSL | 13:80fb167dafdf | 401 | const byte* side; |
wolfSSL | 13:80fb167dafdf | 402 | byte* handshake_hash; |
wolfSSL | 13:80fb167dafdf | 403 | word32 hashSz = HSHASH_SZ; |
wolfSSL | 13:80fb167dafdf | 404 | |
wolfSSL | 13:80fb167dafdf | 405 | /* using allocate here to allow async hardware to use buffer directly */ |
wolfSSL | 13:80fb167dafdf | 406 | handshake_hash = (byte*)XMALLOC(hashSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 407 | if (handshake_hash == NULL) |
wolfSSL | 13:80fb167dafdf | 408 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 409 | |
wolfSSL | 13:80fb167dafdf | 410 | ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz); |
wolfSSL | 13:80fb167dafdf | 411 | if (ret == 0) { |
wolfSSL | 13:80fb167dafdf | 412 | if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0) |
wolfSSL | 13:80fb167dafdf | 413 | side = tls_client; |
wolfSSL | 13:80fb167dafdf | 414 | else |
wolfSSL | 13:80fb167dafdf | 415 | side = tls_server; |
wolfSSL | 13:80fb167dafdf | 416 | |
wolfSSL | 13:80fb167dafdf | 417 | ret = PRF((byte*)hashes, TLS_FINISHED_SZ, ssl->arrays->masterSecret, |
wolfSSL | 13:80fb167dafdf | 418 | SECRET_LEN, side, FINISHED_LABEL_SZ, handshake_hash, hashSz, |
wolfSSL | 13:80fb167dafdf | 419 | IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); |
wolfSSL | 13:80fb167dafdf | 420 | } |
wolfSSL | 13:80fb167dafdf | 421 | |
wolfSSL | 13:80fb167dafdf | 422 | XFREE(handshake_hash, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 423 | |
wolfSSL | 13:80fb167dafdf | 424 | return ret; |
wolfSSL | 13:80fb167dafdf | 425 | } |
wolfSSL | 13:80fb167dafdf | 426 | |
wolfSSL | 13:80fb167dafdf | 427 | |
wolfSSL | 13:80fb167dafdf | 428 | #ifndef NO_OLD_TLS |
wolfSSL | 13:80fb167dafdf | 429 | |
wolfSSL | 13:80fb167dafdf | 430 | ProtocolVersion MakeTLSv1(void) |
wolfSSL | 13:80fb167dafdf | 431 | { |
wolfSSL | 13:80fb167dafdf | 432 | ProtocolVersion pv; |
wolfSSL | 13:80fb167dafdf | 433 | pv.major = SSLv3_MAJOR; |
wolfSSL | 13:80fb167dafdf | 434 | pv.minor = TLSv1_MINOR; |
wolfSSL | 13:80fb167dafdf | 435 | |
wolfSSL | 13:80fb167dafdf | 436 | return pv; |
wolfSSL | 13:80fb167dafdf | 437 | } |
wolfSSL | 13:80fb167dafdf | 438 | |
wolfSSL | 13:80fb167dafdf | 439 | |
wolfSSL | 13:80fb167dafdf | 440 | ProtocolVersion MakeTLSv1_1(void) |
wolfSSL | 13:80fb167dafdf | 441 | { |
wolfSSL | 13:80fb167dafdf | 442 | ProtocolVersion pv; |
wolfSSL | 13:80fb167dafdf | 443 | pv.major = SSLv3_MAJOR; |
wolfSSL | 13:80fb167dafdf | 444 | pv.minor = TLSv1_1_MINOR; |
wolfSSL | 13:80fb167dafdf | 445 | |
wolfSSL | 13:80fb167dafdf | 446 | return pv; |
wolfSSL | 13:80fb167dafdf | 447 | } |
wolfSSL | 13:80fb167dafdf | 448 | |
wolfSSL | 13:80fb167dafdf | 449 | #endif |
wolfSSL | 13:80fb167dafdf | 450 | |
wolfSSL | 13:80fb167dafdf | 451 | |
wolfSSL | 13:80fb167dafdf | 452 | ProtocolVersion MakeTLSv1_2(void) |
wolfSSL | 13:80fb167dafdf | 453 | { |
wolfSSL | 13:80fb167dafdf | 454 | ProtocolVersion pv; |
wolfSSL | 13:80fb167dafdf | 455 | pv.major = SSLv3_MAJOR; |
wolfSSL | 13:80fb167dafdf | 456 | pv.minor = TLSv1_2_MINOR; |
wolfSSL | 13:80fb167dafdf | 457 | |
wolfSSL | 13:80fb167dafdf | 458 | return pv; |
wolfSSL | 13:80fb167dafdf | 459 | } |
wolfSSL | 13:80fb167dafdf | 460 | |
wolfSSL | 13:80fb167dafdf | 461 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 462 | /* The TLS v1.3 protocol version. |
wolfSSL | 13:80fb167dafdf | 463 | * |
wolfSSL | 13:80fb167dafdf | 464 | * returns the protocol version data for TLS v1.3. |
wolfSSL | 13:80fb167dafdf | 465 | */ |
wolfSSL | 13:80fb167dafdf | 466 | ProtocolVersion MakeTLSv1_3(void) |
wolfSSL | 13:80fb167dafdf | 467 | { |
wolfSSL | 13:80fb167dafdf | 468 | ProtocolVersion pv; |
wolfSSL | 13:80fb167dafdf | 469 | pv.major = SSLv3_MAJOR; |
wolfSSL | 13:80fb167dafdf | 470 | pv.minor = TLSv1_3_MINOR; |
wolfSSL | 13:80fb167dafdf | 471 | |
wolfSSL | 13:80fb167dafdf | 472 | return pv; |
wolfSSL | 13:80fb167dafdf | 473 | } |
wolfSSL | 13:80fb167dafdf | 474 | #endif |
wolfSSL | 13:80fb167dafdf | 475 | |
wolfSSL | 13:80fb167dafdf | 476 | |
wolfSSL | 13:80fb167dafdf | 477 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:80fb167dafdf | 478 | static const byte ext_master_label[EXT_MASTER_LABEL_SZ + 1] = |
wolfSSL | 13:80fb167dafdf | 479 | "extended master secret"; |
wolfSSL | 13:80fb167dafdf | 480 | #endif |
wolfSSL | 13:80fb167dafdf | 481 | static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret"; |
wolfSSL | 13:80fb167dafdf | 482 | static const byte key_label [KEY_LABEL_SZ + 1] = "key expansion"; |
wolfSSL | 13:80fb167dafdf | 483 | |
wolfSSL | 13:80fb167dafdf | 484 | |
wolfSSL | 13:80fb167dafdf | 485 | /* External facing wrapper so user can call as well, 0 on success */ |
wolfSSL | 13:80fb167dafdf | 486 | int wolfSSL_DeriveTlsKeys(byte* key_data, word32 keyLen, |
wolfSSL | 13:80fb167dafdf | 487 | const byte* ms, word32 msLen, |
wolfSSL | 13:80fb167dafdf | 488 | const byte* sr, const byte* cr, |
wolfSSL | 13:80fb167dafdf | 489 | int tls1_2, int hash_type) |
wolfSSL | 13:80fb167dafdf | 490 | { |
wolfSSL | 13:80fb167dafdf | 491 | byte seed[SEED_LEN]; |
wolfSSL | 13:80fb167dafdf | 492 | |
wolfSSL | 13:80fb167dafdf | 493 | XMEMCPY(seed, sr, RAN_LEN); |
wolfSSL | 13:80fb167dafdf | 494 | XMEMCPY(seed + RAN_LEN, cr, RAN_LEN); |
wolfSSL | 13:80fb167dafdf | 495 | |
wolfSSL | 13:80fb167dafdf | 496 | return PRF(key_data, keyLen, ms, msLen, key_label, KEY_LABEL_SZ, |
wolfSSL | 13:80fb167dafdf | 497 | seed, SEED_LEN, tls1_2, hash_type); |
wolfSSL | 13:80fb167dafdf | 498 | } |
wolfSSL | 13:80fb167dafdf | 499 | |
wolfSSL | 13:80fb167dafdf | 500 | |
wolfSSL | 13:80fb167dafdf | 501 | int DeriveTlsKeys(WOLFSSL* ssl) |
wolfSSL | 13:80fb167dafdf | 502 | { |
wolfSSL | 13:80fb167dafdf | 503 | int ret; |
wolfSSL | 13:80fb167dafdf | 504 | int length = 2 * ssl->specs.hash_size + |
wolfSSL | 13:80fb167dafdf | 505 | 2 * ssl->specs.key_size + |
wolfSSL | 13:80fb167dafdf | 506 | 2 * ssl->specs.iv_size; |
wolfSSL | 13:80fb167dafdf | 507 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:80fb167dafdf | 508 | byte* key_data; |
wolfSSL | 13:80fb167dafdf | 509 | #else |
wolfSSL | 13:80fb167dafdf | 510 | byte key_data[MAX_PRF_DIG]; |
wolfSSL | 13:80fb167dafdf | 511 | #endif |
wolfSSL | 13:80fb167dafdf | 512 | |
wolfSSL | 13:80fb167dafdf | 513 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:80fb167dafdf | 514 | key_data = (byte*)XMALLOC(MAX_PRF_DIG, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 515 | if (key_data == NULL) { |
wolfSSL | 13:80fb167dafdf | 516 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 517 | } |
wolfSSL | 13:80fb167dafdf | 518 | #endif |
wolfSSL | 13:80fb167dafdf | 519 | |
wolfSSL | 13:80fb167dafdf | 520 | ret = wolfSSL_DeriveTlsKeys(key_data, length, |
wolfSSL | 13:80fb167dafdf | 521 | ssl->arrays->masterSecret, SECRET_LEN, |
wolfSSL | 13:80fb167dafdf | 522 | ssl->arrays->serverRandom, ssl->arrays->clientRandom, |
wolfSSL | 13:80fb167dafdf | 523 | IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); |
wolfSSL | 13:80fb167dafdf | 524 | if (ret == 0) |
wolfSSL | 13:80fb167dafdf | 525 | ret = StoreKeys(ssl, key_data); |
wolfSSL | 13:80fb167dafdf | 526 | |
wolfSSL | 13:80fb167dafdf | 527 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:80fb167dafdf | 528 | XFREE(key_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 529 | #endif |
wolfSSL | 13:80fb167dafdf | 530 | |
wolfSSL | 13:80fb167dafdf | 531 | return ret; |
wolfSSL | 13:80fb167dafdf | 532 | } |
wolfSSL | 13:80fb167dafdf | 533 | |
wolfSSL | 13:80fb167dafdf | 534 | |
wolfSSL | 13:80fb167dafdf | 535 | /* External facing wrapper so user can call as well, 0 on success */ |
wolfSSL | 13:80fb167dafdf | 536 | int wolfSSL_MakeTlsMasterSecret(byte* ms, word32 msLen, |
wolfSSL | 13:80fb167dafdf | 537 | const byte* pms, word32 pmsLen, |
wolfSSL | 13:80fb167dafdf | 538 | const byte* cr, const byte* sr, |
wolfSSL | 13:80fb167dafdf | 539 | int tls1_2, int hash_type) |
wolfSSL | 13:80fb167dafdf | 540 | { |
wolfSSL | 13:80fb167dafdf | 541 | byte seed[SEED_LEN]; |
wolfSSL | 13:80fb167dafdf | 542 | |
wolfSSL | 13:80fb167dafdf | 543 | XMEMCPY(seed, cr, RAN_LEN); |
wolfSSL | 13:80fb167dafdf | 544 | XMEMCPY(seed + RAN_LEN, sr, RAN_LEN); |
wolfSSL | 13:80fb167dafdf | 545 | |
wolfSSL | 13:80fb167dafdf | 546 | return PRF(ms, msLen, pms, pmsLen, master_label, MASTER_LABEL_SZ, |
wolfSSL | 13:80fb167dafdf | 547 | seed, SEED_LEN, tls1_2, hash_type); |
wolfSSL | 13:80fb167dafdf | 548 | } |
wolfSSL | 13:80fb167dafdf | 549 | |
wolfSSL | 13:80fb167dafdf | 550 | |
wolfSSL | 13:80fb167dafdf | 551 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:80fb167dafdf | 552 | |
wolfSSL | 13:80fb167dafdf | 553 | /* External facing wrapper so user can call as well, 0 on success */ |
wolfSSL | 13:80fb167dafdf | 554 | int wolfSSL_MakeTlsExtendedMasterSecret(byte* ms, word32 msLen, |
wolfSSL | 13:80fb167dafdf | 555 | const byte* pms, word32 pmsLen, |
wolfSSL | 13:80fb167dafdf | 556 | const byte* sHash, word32 sHashLen, |
wolfSSL | 13:80fb167dafdf | 557 | int tls1_2, int hash_type) |
wolfSSL | 13:80fb167dafdf | 558 | { |
wolfSSL | 13:80fb167dafdf | 559 | return PRF(ms, msLen, pms, pmsLen, ext_master_label, EXT_MASTER_LABEL_SZ, |
wolfSSL | 13:80fb167dafdf | 560 | sHash, sHashLen, tls1_2, hash_type); |
wolfSSL | 13:80fb167dafdf | 561 | } |
wolfSSL | 13:80fb167dafdf | 562 | |
wolfSSL | 13:80fb167dafdf | 563 | #endif /* HAVE_EXTENDED_MASTER */ |
wolfSSL | 13:80fb167dafdf | 564 | |
wolfSSL | 13:80fb167dafdf | 565 | |
wolfSSL | 13:80fb167dafdf | 566 | int MakeTlsMasterSecret(WOLFSSL* ssl) |
wolfSSL | 13:80fb167dafdf | 567 | { |
wolfSSL | 13:80fb167dafdf | 568 | int ret; |
wolfSSL | 13:80fb167dafdf | 569 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:80fb167dafdf | 570 | if (ssl->options.haveEMS) { |
wolfSSL | 13:80fb167dafdf | 571 | byte* handshake_hash; |
wolfSSL | 13:80fb167dafdf | 572 | word32 hashSz = HSHASH_SZ; |
wolfSSL | 13:80fb167dafdf | 573 | |
wolfSSL | 13:80fb167dafdf | 574 | handshake_hash = (byte*)XMALLOC(HSHASH_SZ, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 575 | if (handshake_hash == NULL) |
wolfSSL | 13:80fb167dafdf | 576 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 577 | |
wolfSSL | 13:80fb167dafdf | 578 | ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz); |
wolfSSL | 13:80fb167dafdf | 579 | if (ret < 0) { |
wolfSSL | 13:80fb167dafdf | 580 | XFREE(handshake_hash, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 581 | return ret; |
wolfSSL | 13:80fb167dafdf | 582 | } |
wolfSSL | 13:80fb167dafdf | 583 | |
wolfSSL | 13:80fb167dafdf | 584 | ret = wolfSSL_MakeTlsExtendedMasterSecret( |
wolfSSL | 13:80fb167dafdf | 585 | ssl->arrays->masterSecret, SECRET_LEN, |
wolfSSL | 13:80fb167dafdf | 586 | ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz, |
wolfSSL | 13:80fb167dafdf | 587 | handshake_hash, hashSz, |
wolfSSL | 13:80fb167dafdf | 588 | IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); |
wolfSSL | 13:80fb167dafdf | 589 | |
wolfSSL | 13:80fb167dafdf | 590 | XFREE(handshake_hash, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 591 | } else |
wolfSSL | 13:80fb167dafdf | 592 | #endif |
wolfSSL | 13:80fb167dafdf | 593 | ret = wolfSSL_MakeTlsMasterSecret(ssl->arrays->masterSecret, SECRET_LEN, |
wolfSSL | 13:80fb167dafdf | 594 | ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz, |
wolfSSL | 13:80fb167dafdf | 595 | ssl->arrays->clientRandom, ssl->arrays->serverRandom, |
wolfSSL | 13:80fb167dafdf | 596 | IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); |
wolfSSL | 13:80fb167dafdf | 597 | |
wolfSSL | 13:80fb167dafdf | 598 | if (ret == 0) { |
wolfSSL | 13:80fb167dafdf | 599 | #ifdef SHOW_SECRETS |
wolfSSL | 13:80fb167dafdf | 600 | int i; |
wolfSSL | 13:80fb167dafdf | 601 | |
wolfSSL | 13:80fb167dafdf | 602 | printf("master secret: "); |
wolfSSL | 13:80fb167dafdf | 603 | for (i = 0; i < SECRET_LEN; i++) |
wolfSSL | 13:80fb167dafdf | 604 | printf("%02x", ssl->arrays->masterSecret[i]); |
wolfSSL | 13:80fb167dafdf | 605 | printf("\n"); |
wolfSSL | 13:80fb167dafdf | 606 | #endif |
wolfSSL | 13:80fb167dafdf | 607 | |
wolfSSL | 13:80fb167dafdf | 608 | ret = DeriveTlsKeys(ssl); |
wolfSSL | 13:80fb167dafdf | 609 | } |
wolfSSL | 13:80fb167dafdf | 610 | |
wolfSSL | 13:80fb167dafdf | 611 | return ret; |
wolfSSL | 13:80fb167dafdf | 612 | } |
wolfSSL | 13:80fb167dafdf | 613 | |
wolfSSL | 13:80fb167dafdf | 614 | |
wolfSSL | 13:80fb167dafdf | 615 | /* Used by EAP-TLS and EAP-TTLS to derive keying material from |
wolfSSL | 13:80fb167dafdf | 616 | * the master_secret. */ |
wolfSSL | 13:80fb167dafdf | 617 | int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* msk, unsigned int len, |
wolfSSL | 13:80fb167dafdf | 618 | const char* label) |
wolfSSL | 13:80fb167dafdf | 619 | { |
wolfSSL | 13:80fb167dafdf | 620 | int ret; |
wolfSSL | 13:80fb167dafdf | 621 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:80fb167dafdf | 622 | byte* seed; |
wolfSSL | 13:80fb167dafdf | 623 | #else |
wolfSSL | 13:80fb167dafdf | 624 | byte seed[SEED_LEN]; |
wolfSSL | 13:80fb167dafdf | 625 | #endif |
wolfSSL | 13:80fb167dafdf | 626 | |
wolfSSL | 13:80fb167dafdf | 627 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:80fb167dafdf | 628 | seed = (byte*)XMALLOC(SEED_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 629 | if (seed == NULL) |
wolfSSL | 13:80fb167dafdf | 630 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 631 | #endif |
wolfSSL | 13:80fb167dafdf | 632 | |
wolfSSL | 13:80fb167dafdf | 633 | /* |
wolfSSL | 13:80fb167dafdf | 634 | * As per RFC-5281, the order of the client and server randoms is reversed |
wolfSSL | 13:80fb167dafdf | 635 | * from that used by the TLS protocol to derive keys. |
wolfSSL | 13:80fb167dafdf | 636 | */ |
wolfSSL | 13:80fb167dafdf | 637 | XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN); |
wolfSSL | 13:80fb167dafdf | 638 | XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN); |
wolfSSL | 13:80fb167dafdf | 639 | |
wolfSSL | 13:80fb167dafdf | 640 | ret = PRF((byte*)msk, len, ssl->arrays->masterSecret, SECRET_LEN, |
wolfSSL | 13:80fb167dafdf | 641 | (const byte *)label, (word32)XSTRLEN(label), seed, SEED_LEN, |
wolfSSL | 13:80fb167dafdf | 642 | IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); |
wolfSSL | 13:80fb167dafdf | 643 | |
wolfSSL | 13:80fb167dafdf | 644 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 13:80fb167dafdf | 645 | XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 646 | #endif |
wolfSSL | 13:80fb167dafdf | 647 | |
wolfSSL | 13:80fb167dafdf | 648 | return ret; |
wolfSSL | 13:80fb167dafdf | 649 | } |
wolfSSL | 13:80fb167dafdf | 650 | |
wolfSSL | 13:80fb167dafdf | 651 | |
wolfSSL | 13:80fb167dafdf | 652 | /*** next for static INLINE s copied internal.c ***/ |
wolfSSL | 13:80fb167dafdf | 653 | |
wolfSSL | 13:80fb167dafdf | 654 | /* convert 16 bit integer to opaque */ |
wolfSSL | 13:80fb167dafdf | 655 | static INLINE void c16toa(word16 u16, byte* c) |
wolfSSL | 13:80fb167dafdf | 656 | { |
wolfSSL | 13:80fb167dafdf | 657 | c[0] = (u16 >> 8) & 0xff; |
wolfSSL | 13:80fb167dafdf | 658 | c[1] = u16 & 0xff; |
wolfSSL | 13:80fb167dafdf | 659 | } |
wolfSSL | 13:80fb167dafdf | 660 | |
wolfSSL | 13:80fb167dafdf | 661 | #ifdef HAVE_TLS_EXTENSIONS |
wolfSSL | 13:80fb167dafdf | 662 | /* convert opaque to 16 bit integer */ |
wolfSSL | 13:80fb167dafdf | 663 | static INLINE void ato16(const byte* c, word16* u16) |
wolfSSL | 13:80fb167dafdf | 664 | { |
wolfSSL | 13:80fb167dafdf | 665 | *u16 = (c[0] << 8) | (c[1]); |
wolfSSL | 13:80fb167dafdf | 666 | } |
wolfSSL | 13:80fb167dafdf | 667 | |
wolfSSL | 13:80fb167dafdf | 668 | #if defined(HAVE_SNI) && !defined(NO_WOLFSSL_SERVER) |
wolfSSL | 13:80fb167dafdf | 669 | /* convert a 24 bit integer into a 32 bit one */ |
wolfSSL | 13:80fb167dafdf | 670 | static INLINE void c24to32(const word24 u24, word32* u32) |
wolfSSL | 13:80fb167dafdf | 671 | { |
wolfSSL | 13:80fb167dafdf | 672 | *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2]; |
wolfSSL | 13:80fb167dafdf | 673 | } |
wolfSSL | 13:80fb167dafdf | 674 | #endif |
wolfSSL | 13:80fb167dafdf | 675 | |
wolfSSL | 13:80fb167dafdf | 676 | #if defined(WOLFSSL_TLS13) && !defined(NO_PSK) |
wolfSSL | 13:80fb167dafdf | 677 | /* Convert opaque data to a 32-bit unsigned integer. |
wolfSSL | 13:80fb167dafdf | 678 | * |
wolfSSL | 13:80fb167dafdf | 679 | * c The opaque data holding a 32-bit integer. |
wolfSSL | 13:80fb167dafdf | 680 | * u32 The 32-bit unsigned integer. |
wolfSSL | 13:80fb167dafdf | 681 | */ |
wolfSSL | 13:80fb167dafdf | 682 | static INLINE void ato32(const byte* c, word32* u32) |
wolfSSL | 13:80fb167dafdf | 683 | { |
wolfSSL | 13:80fb167dafdf | 684 | *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; |
wolfSSL | 13:80fb167dafdf | 685 | } |
wolfSSL | 13:80fb167dafdf | 686 | #endif |
wolfSSL | 13:80fb167dafdf | 687 | #endif /* HAVE_TLS_EXTENSIONS */ |
wolfSSL | 13:80fb167dafdf | 688 | |
wolfSSL | 13:80fb167dafdf | 689 | /* convert 32 bit integer to opaque */ |
wolfSSL | 13:80fb167dafdf | 690 | static INLINE void c32toa(word32 u32, byte* c) |
wolfSSL | 13:80fb167dafdf | 691 | { |
wolfSSL | 13:80fb167dafdf | 692 | c[0] = (u32 >> 24) & 0xff; |
wolfSSL | 13:80fb167dafdf | 693 | c[1] = (u32 >> 16) & 0xff; |
wolfSSL | 13:80fb167dafdf | 694 | c[2] = (u32 >> 8) & 0xff; |
wolfSSL | 13:80fb167dafdf | 695 | c[3] = u32 & 0xff; |
wolfSSL | 13:80fb167dafdf | 696 | } |
wolfSSL | 13:80fb167dafdf | 697 | |
wolfSSL | 13:80fb167dafdf | 698 | |
wolfSSL | 13:80fb167dafdf | 699 | static INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2]) |
wolfSSL | 13:80fb167dafdf | 700 | { |
wolfSSL | 13:80fb167dafdf | 701 | if (verify) { |
wolfSSL | 13:80fb167dafdf | 702 | seq[0] = ssl->keys.peer_sequence_number_hi; |
wolfSSL | 13:80fb167dafdf | 703 | seq[1] = ssl->keys.peer_sequence_number_lo++; |
wolfSSL | 13:80fb167dafdf | 704 | if (seq[1] > ssl->keys.peer_sequence_number_lo) { |
wolfSSL | 13:80fb167dafdf | 705 | /* handle rollover */ |
wolfSSL | 13:80fb167dafdf | 706 | ssl->keys.peer_sequence_number_hi++; |
wolfSSL | 13:80fb167dafdf | 707 | } |
wolfSSL | 13:80fb167dafdf | 708 | } |
wolfSSL | 13:80fb167dafdf | 709 | else { |
wolfSSL | 13:80fb167dafdf | 710 | seq[0] = ssl->keys.sequence_number_hi; |
wolfSSL | 13:80fb167dafdf | 711 | seq[1] = ssl->keys.sequence_number_lo++; |
wolfSSL | 13:80fb167dafdf | 712 | if (seq[1] > ssl->keys.sequence_number_lo) { |
wolfSSL | 13:80fb167dafdf | 713 | /* handle rollover */ |
wolfSSL | 13:80fb167dafdf | 714 | ssl->keys.sequence_number_hi++; |
wolfSSL | 13:80fb167dafdf | 715 | } |
wolfSSL | 13:80fb167dafdf | 716 | } |
wolfSSL | 13:80fb167dafdf | 717 | } |
wolfSSL | 13:80fb167dafdf | 718 | |
wolfSSL | 13:80fb167dafdf | 719 | |
wolfSSL | 13:80fb167dafdf | 720 | #ifdef WOLFSSL_DTLS |
wolfSSL | 13:80fb167dafdf | 721 | static INLINE void DtlsGetSEQ(WOLFSSL* ssl, int order, word32 seq[2]) |
wolfSSL | 13:80fb167dafdf | 722 | { |
wolfSSL | 13:80fb167dafdf | 723 | if (order == PREV_ORDER) { |
wolfSSL | 13:80fb167dafdf | 724 | /* Previous epoch case */ |
wolfSSL | 13:80fb167dafdf | 725 | seq[0] = ((ssl->keys.dtls_epoch - 1) << 16) | |
wolfSSL | 13:80fb167dafdf | 726 | (ssl->keys.dtls_prev_sequence_number_hi & 0xFFFF); |
wolfSSL | 13:80fb167dafdf | 727 | seq[1] = ssl->keys.dtls_prev_sequence_number_lo; |
wolfSSL | 13:80fb167dafdf | 728 | } |
wolfSSL | 13:80fb167dafdf | 729 | else if (order == PEER_ORDER) { |
wolfSSL | 13:80fb167dafdf | 730 | seq[0] = (ssl->keys.curEpoch << 16) | |
wolfSSL | 13:80fb167dafdf | 731 | (ssl->keys.curSeq_hi & 0xFFFF); |
wolfSSL | 13:80fb167dafdf | 732 | seq[1] = ssl->keys.curSeq_lo; /* explicit from peer */ |
wolfSSL | 13:80fb167dafdf | 733 | } |
wolfSSL | 13:80fb167dafdf | 734 | else { |
wolfSSL | 13:80fb167dafdf | 735 | seq[0] = (ssl->keys.dtls_epoch << 16) | |
wolfSSL | 13:80fb167dafdf | 736 | (ssl->keys.dtls_sequence_number_hi & 0xFFFF); |
wolfSSL | 13:80fb167dafdf | 737 | seq[1] = ssl->keys.dtls_sequence_number_lo; |
wolfSSL | 13:80fb167dafdf | 738 | } |
wolfSSL | 13:80fb167dafdf | 739 | } |
wolfSSL | 13:80fb167dafdf | 740 | #endif /* WOLFSSL_DTLS */ |
wolfSSL | 13:80fb167dafdf | 741 | |
wolfSSL | 13:80fb167dafdf | 742 | |
wolfSSL | 13:80fb167dafdf | 743 | static INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out) |
wolfSSL | 13:80fb167dafdf | 744 | { |
wolfSSL | 13:80fb167dafdf | 745 | word32 seq[2] = {0, 0}; |
wolfSSL | 13:80fb167dafdf | 746 | |
wolfSSL | 13:80fb167dafdf | 747 | if (!ssl->options.dtls) { |
wolfSSL | 13:80fb167dafdf | 748 | GetSEQIncrement(ssl, verifyOrder, seq); |
wolfSSL | 13:80fb167dafdf | 749 | } |
wolfSSL | 13:80fb167dafdf | 750 | else { |
wolfSSL | 13:80fb167dafdf | 751 | #ifdef WOLFSSL_DTLS |
wolfSSL | 13:80fb167dafdf | 752 | DtlsGetSEQ(ssl, verifyOrder, seq); |
wolfSSL | 13:80fb167dafdf | 753 | #endif |
wolfSSL | 13:80fb167dafdf | 754 | } |
wolfSSL | 13:80fb167dafdf | 755 | |
wolfSSL | 13:80fb167dafdf | 756 | c32toa(seq[0], out); |
wolfSSL | 13:80fb167dafdf | 757 | c32toa(seq[1], out + OPAQUE32_LEN); |
wolfSSL | 13:80fb167dafdf | 758 | } |
wolfSSL | 13:80fb167dafdf | 759 | |
wolfSSL | 13:80fb167dafdf | 760 | |
wolfSSL | 13:80fb167dafdf | 761 | /*** end copy ***/ |
wolfSSL | 13:80fb167dafdf | 762 | |
wolfSSL | 13:80fb167dafdf | 763 | |
wolfSSL | 13:80fb167dafdf | 764 | /* return HMAC digest type in wolfSSL format */ |
wolfSSL | 13:80fb167dafdf | 765 | int wolfSSL_GetHmacType(WOLFSSL* ssl) |
wolfSSL | 13:80fb167dafdf | 766 | { |
wolfSSL | 13:80fb167dafdf | 767 | if (ssl == NULL) |
wolfSSL | 13:80fb167dafdf | 768 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 769 | |
wolfSSL | 13:80fb167dafdf | 770 | switch (ssl->specs.mac_algorithm) { |
wolfSSL | 13:80fb167dafdf | 771 | #ifndef NO_MD5 |
wolfSSL | 13:80fb167dafdf | 772 | case md5_mac: |
wolfSSL | 13:80fb167dafdf | 773 | { |
wolfSSL | 13:80fb167dafdf | 774 | return MD5; |
wolfSSL | 13:80fb167dafdf | 775 | } |
wolfSSL | 13:80fb167dafdf | 776 | #endif |
wolfSSL | 13:80fb167dafdf | 777 | #ifndef NO_SHA256 |
wolfSSL | 13:80fb167dafdf | 778 | case sha256_mac: |
wolfSSL | 13:80fb167dafdf | 779 | { |
wolfSSL | 13:80fb167dafdf | 780 | return SHA256; |
wolfSSL | 13:80fb167dafdf | 781 | } |
wolfSSL | 13:80fb167dafdf | 782 | #endif |
wolfSSL | 13:80fb167dafdf | 783 | #ifdef WOLFSSL_SHA384 |
wolfSSL | 13:80fb167dafdf | 784 | case sha384_mac: |
wolfSSL | 13:80fb167dafdf | 785 | { |
wolfSSL | 13:80fb167dafdf | 786 | return SHA384; |
wolfSSL | 13:80fb167dafdf | 787 | } |
wolfSSL | 13:80fb167dafdf | 788 | |
wolfSSL | 13:80fb167dafdf | 789 | #endif |
wolfSSL | 13:80fb167dafdf | 790 | #ifndef NO_SHA |
wolfSSL | 13:80fb167dafdf | 791 | case sha_mac: |
wolfSSL | 13:80fb167dafdf | 792 | { |
wolfSSL | 13:80fb167dafdf | 793 | return SHA; |
wolfSSL | 13:80fb167dafdf | 794 | } |
wolfSSL | 13:80fb167dafdf | 795 | #endif |
wolfSSL | 13:80fb167dafdf | 796 | #ifdef HAVE_BLAKE2 |
wolfSSL | 13:80fb167dafdf | 797 | case blake2b_mac: |
wolfSSL | 13:80fb167dafdf | 798 | { |
wolfSSL | 13:80fb167dafdf | 799 | return BLAKE2B_ID; |
wolfSSL | 13:80fb167dafdf | 800 | } |
wolfSSL | 13:80fb167dafdf | 801 | #endif |
wolfSSL | 13:80fb167dafdf | 802 | default: |
wolfSSL | 13:80fb167dafdf | 803 | { |
wolfSSL | 13:80fb167dafdf | 804 | return SSL_FATAL_ERROR; |
wolfSSL | 13:80fb167dafdf | 805 | } |
wolfSSL | 13:80fb167dafdf | 806 | } |
wolfSSL | 13:80fb167dafdf | 807 | } |
wolfSSL | 13:80fb167dafdf | 808 | |
wolfSSL | 13:80fb167dafdf | 809 | |
wolfSSL | 13:80fb167dafdf | 810 | int wolfSSL_SetTlsHmacInner(WOLFSSL* ssl, byte* inner, word32 sz, int content, |
wolfSSL | 13:80fb167dafdf | 811 | int verify) |
wolfSSL | 13:80fb167dafdf | 812 | { |
wolfSSL | 13:80fb167dafdf | 813 | if (ssl == NULL || inner == NULL) |
wolfSSL | 13:80fb167dafdf | 814 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 815 | |
wolfSSL | 13:80fb167dafdf | 816 | XMEMSET(inner, 0, WOLFSSL_TLS_HMAC_INNER_SZ); |
wolfSSL | 13:80fb167dafdf | 817 | |
wolfSSL | 13:80fb167dafdf | 818 | WriteSEQ(ssl, verify, inner); |
wolfSSL | 13:80fb167dafdf | 819 | inner[SEQ_SZ] = (byte)content; |
wolfSSL | 13:80fb167dafdf | 820 | inner[SEQ_SZ + ENUM_LEN] = ssl->version.major; |
wolfSSL | 13:80fb167dafdf | 821 | inner[SEQ_SZ + ENUM_LEN + ENUM_LEN] = ssl->version.minor; |
wolfSSL | 13:80fb167dafdf | 822 | c16toa((word16)sz, inner + SEQ_SZ + ENUM_LEN + VERSION_SZ); |
wolfSSL | 13:80fb167dafdf | 823 | |
wolfSSL | 13:80fb167dafdf | 824 | return 0; |
wolfSSL | 13:80fb167dafdf | 825 | } |
wolfSSL | 13:80fb167dafdf | 826 | |
wolfSSL | 13:80fb167dafdf | 827 | |
wolfSSL | 13:80fb167dafdf | 828 | /* TLS type HMAC */ |
wolfSSL | 13:80fb167dafdf | 829 | int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, |
wolfSSL | 13:80fb167dafdf | 830 | int content, int verify) |
wolfSSL | 13:80fb167dafdf | 831 | { |
wolfSSL | 13:80fb167dafdf | 832 | Hmac hmac; |
wolfSSL | 13:80fb167dafdf | 833 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 834 | byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ]; |
wolfSSL | 13:80fb167dafdf | 835 | |
wolfSSL | 13:80fb167dafdf | 836 | if (ssl == NULL) |
wolfSSL | 13:80fb167dafdf | 837 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 838 | |
wolfSSL | 13:80fb167dafdf | 839 | #ifdef HAVE_FUZZER |
wolfSSL | 13:80fb167dafdf | 840 | if (ssl->fuzzerCb) |
wolfSSL | 13:80fb167dafdf | 841 | ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx); |
wolfSSL | 13:80fb167dafdf | 842 | #endif |
wolfSSL | 13:80fb167dafdf | 843 | |
wolfSSL | 13:80fb167dafdf | 844 | wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify); |
wolfSSL | 13:80fb167dafdf | 845 | |
wolfSSL | 13:80fb167dafdf | 846 | ret = wc_HmacInit(&hmac, NULL, ssl->devId); |
wolfSSL | 13:80fb167dafdf | 847 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 848 | return ret; |
wolfSSL | 13:80fb167dafdf | 849 | |
wolfSSL | 13:80fb167dafdf | 850 | ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl), |
wolfSSL | 13:80fb167dafdf | 851 | wolfSSL_GetMacSecret(ssl, verify), ssl->specs.hash_size); |
wolfSSL | 13:80fb167dafdf | 852 | if (ret == 0) { |
wolfSSL | 13:80fb167dafdf | 853 | ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner)); |
wolfSSL | 13:80fb167dafdf | 854 | if (ret == 0) |
wolfSSL | 13:80fb167dafdf | 855 | ret = wc_HmacUpdate(&hmac, in, sz); /* content */ |
wolfSSL | 13:80fb167dafdf | 856 | if (ret == 0) |
wolfSSL | 13:80fb167dafdf | 857 | ret = wc_HmacFinal(&hmac, digest); |
wolfSSL | 13:80fb167dafdf | 858 | } |
wolfSSL | 13:80fb167dafdf | 859 | wc_HmacFree(&hmac); |
wolfSSL | 13:80fb167dafdf | 860 | |
wolfSSL | 13:80fb167dafdf | 861 | return ret; |
wolfSSL | 13:80fb167dafdf | 862 | } |
wolfSSL | 13:80fb167dafdf | 863 | |
wolfSSL | 13:80fb167dafdf | 864 | #ifdef HAVE_TLS_EXTENSIONS |
wolfSSL | 13:80fb167dafdf | 865 | |
wolfSSL | 13:80fb167dafdf | 866 | /** |
wolfSSL | 13:80fb167dafdf | 867 | * The TLSX semaphore is used to calculate the size of the extensions to be sent |
wolfSSL | 13:80fb167dafdf | 868 | * from one peer to another. |
wolfSSL | 13:80fb167dafdf | 869 | */ |
wolfSSL | 13:80fb167dafdf | 870 | |
wolfSSL | 13:80fb167dafdf | 871 | /** Supports up to 64 flags. Increase as needed. */ |
wolfSSL | 13:80fb167dafdf | 872 | #define SEMAPHORE_SIZE 8 |
wolfSSL | 13:80fb167dafdf | 873 | |
wolfSSL | 13:80fb167dafdf | 874 | /** |
wolfSSL | 13:80fb167dafdf | 875 | * Converts the extension type (id) to an index in the semaphore. |
wolfSSL | 13:80fb167dafdf | 876 | * |
wolfSSL | 13:80fb167dafdf | 877 | * Oficial reference for TLS extension types: |
wolfSSL | 13:80fb167dafdf | 878 | * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xml |
wolfSSL | 13:80fb167dafdf | 879 | * |
wolfSSL | 13:80fb167dafdf | 880 | * Motivation: |
wolfSSL | 13:80fb167dafdf | 881 | * Previously, we used the extension type itself as the index of that |
wolfSSL | 13:80fb167dafdf | 882 | * extension in the semaphore as the extension types were declared |
wolfSSL | 13:80fb167dafdf | 883 | * sequentially, but maintain a semaphore as big as the number of available |
wolfSSL | 13:80fb167dafdf | 884 | * extensions is no longer an option since the release of renegotiation_info. |
wolfSSL | 13:80fb167dafdf | 885 | * |
wolfSSL | 13:80fb167dafdf | 886 | * How to update: |
wolfSSL | 13:80fb167dafdf | 887 | * Assign extension types that extrapolate the number of available semaphores |
wolfSSL | 13:80fb167dafdf | 888 | * to the first available index going backwards in the semaphore array. |
wolfSSL | 13:80fb167dafdf | 889 | * When adding a new extension type that don't extrapolate the number of |
wolfSSL | 13:80fb167dafdf | 890 | * available semaphores, check for a possible collision with with a |
wolfSSL | 13:80fb167dafdf | 891 | * 'remapped' extension type. |
wolfSSL | 13:80fb167dafdf | 892 | */ |
wolfSSL | 13:80fb167dafdf | 893 | static INLINE word16 TLSX_ToSemaphore(word16 type) |
wolfSSL | 13:80fb167dafdf | 894 | { |
wolfSSL | 13:80fb167dafdf | 895 | switch (type) { |
wolfSSL | 13:80fb167dafdf | 896 | |
wolfSSL | 13:80fb167dafdf | 897 | case TLSX_RENEGOTIATION_INFO: /* 0xFF01 */ |
wolfSSL | 13:80fb167dafdf | 898 | return 63; |
wolfSSL | 13:80fb167dafdf | 899 | |
wolfSSL | 13:80fb167dafdf | 900 | default: |
wolfSSL | 13:80fb167dafdf | 901 | if (type > 62) { |
wolfSSL | 13:80fb167dafdf | 902 | /* This message SHOULD only happens during the adding of |
wolfSSL | 13:80fb167dafdf | 903 | new TLS extensions in which its IANA number overflows |
wolfSSL | 13:80fb167dafdf | 904 | the current semaphore's range, or if its number already |
wolfSSL | 13:80fb167dafdf | 905 | is assigned to be used by another extension. |
wolfSSL | 13:80fb167dafdf | 906 | Use this check value for the new extension and decrement |
wolfSSL | 13:80fb167dafdf | 907 | the check value by one. */ |
wolfSSL | 13:80fb167dafdf | 908 | WOLFSSL_MSG("### TLSX semaphore colision or overflow detected!"); |
wolfSSL | 13:80fb167dafdf | 909 | } |
wolfSSL | 13:80fb167dafdf | 910 | } |
wolfSSL | 13:80fb167dafdf | 911 | |
wolfSSL | 13:80fb167dafdf | 912 | return type; |
wolfSSL | 13:80fb167dafdf | 913 | } |
wolfSSL | 13:80fb167dafdf | 914 | |
wolfSSL | 13:80fb167dafdf | 915 | /** Checks if a specific light (tls extension) is not set in the semaphore. */ |
wolfSSL | 13:80fb167dafdf | 916 | #define IS_OFF(semaphore, light) \ |
wolfSSL | 13:80fb167dafdf | 917 | (!(((semaphore)[(light) / 8] & (byte) (0x01 << ((light) % 8))))) |
wolfSSL | 13:80fb167dafdf | 918 | |
wolfSSL | 13:80fb167dafdf | 919 | /** Turn on a specific light (tls extension) in the semaphore. */ |
wolfSSL | 13:80fb167dafdf | 920 | #define TURN_ON(semaphore, light) \ |
wolfSSL | 13:80fb167dafdf | 921 | ((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8))) |
wolfSSL | 13:80fb167dafdf | 922 | |
wolfSSL | 13:80fb167dafdf | 923 | /** Turn off a specific light (tls extension) in the semaphore. */ |
wolfSSL | 13:80fb167dafdf | 924 | #define TURN_OFF(semaphore, light) \ |
wolfSSL | 13:80fb167dafdf | 925 | ((semaphore)[(light) / 8] &= (byte) ~(0x01 << ((light) % 8))) |
wolfSSL | 13:80fb167dafdf | 926 | |
wolfSSL | 13:80fb167dafdf | 927 | /** Creates a new extension. */ |
wolfSSL | 13:80fb167dafdf | 928 | static TLSX* TLSX_New(TLSX_Type type, void* data, void* heap) |
wolfSSL | 13:80fb167dafdf | 929 | { |
wolfSSL | 13:80fb167dafdf | 930 | TLSX* extension = (TLSX*)XMALLOC(sizeof(TLSX), heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 931 | |
wolfSSL | 13:80fb167dafdf | 932 | if (extension) { |
wolfSSL | 13:80fb167dafdf | 933 | extension->type = type; |
wolfSSL | 13:80fb167dafdf | 934 | extension->data = data; |
wolfSSL | 13:80fb167dafdf | 935 | extension->resp = 0; |
wolfSSL | 13:80fb167dafdf | 936 | extension->next = NULL; |
wolfSSL | 13:80fb167dafdf | 937 | } |
wolfSSL | 13:80fb167dafdf | 938 | |
wolfSSL | 13:80fb167dafdf | 939 | return extension; |
wolfSSL | 13:80fb167dafdf | 940 | } |
wolfSSL | 13:80fb167dafdf | 941 | |
wolfSSL | 13:80fb167dafdf | 942 | /** |
wolfSSL | 13:80fb167dafdf | 943 | * Creates a new extension and pushes it to the provided list. |
wolfSSL | 13:80fb167dafdf | 944 | * Checks for duplicate extensions, keeps the newest. |
wolfSSL | 13:80fb167dafdf | 945 | */ |
wolfSSL | 13:80fb167dafdf | 946 | static int TLSX_Push(TLSX** list, TLSX_Type type, void* data, void* heap) |
wolfSSL | 13:80fb167dafdf | 947 | { |
wolfSSL | 13:80fb167dafdf | 948 | TLSX* extension = TLSX_New(type, data, heap); |
wolfSSL | 13:80fb167dafdf | 949 | |
wolfSSL | 13:80fb167dafdf | 950 | if (extension == NULL) |
wolfSSL | 13:80fb167dafdf | 951 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 952 | |
wolfSSL | 13:80fb167dafdf | 953 | /* pushes the new extension on the list. */ |
wolfSSL | 13:80fb167dafdf | 954 | extension->next = *list; |
wolfSSL | 13:80fb167dafdf | 955 | *list = extension; |
wolfSSL | 13:80fb167dafdf | 956 | |
wolfSSL | 13:80fb167dafdf | 957 | /* remove duplicate extensions, there should be only one of each type. */ |
wolfSSL | 13:80fb167dafdf | 958 | do { |
wolfSSL | 13:80fb167dafdf | 959 | if (extension->next && extension->next->type == type) { |
wolfSSL | 13:80fb167dafdf | 960 | TLSX *next = extension->next; |
wolfSSL | 13:80fb167dafdf | 961 | |
wolfSSL | 13:80fb167dafdf | 962 | extension->next = next->next; |
wolfSSL | 13:80fb167dafdf | 963 | next->next = NULL; |
wolfSSL | 13:80fb167dafdf | 964 | |
wolfSSL | 13:80fb167dafdf | 965 | TLSX_FreeAll(next, heap); |
wolfSSL | 13:80fb167dafdf | 966 | |
wolfSSL | 13:80fb167dafdf | 967 | /* there is no way to occur more than */ |
wolfSSL | 13:80fb167dafdf | 968 | /* two extensions of the same type. */ |
wolfSSL | 13:80fb167dafdf | 969 | break; |
wolfSSL | 13:80fb167dafdf | 970 | } |
wolfSSL | 13:80fb167dafdf | 971 | } while ((extension = extension->next)); |
wolfSSL | 13:80fb167dafdf | 972 | |
wolfSSL | 13:80fb167dafdf | 973 | return 0; |
wolfSSL | 13:80fb167dafdf | 974 | } |
wolfSSL | 13:80fb167dafdf | 975 | |
wolfSSL | 13:80fb167dafdf | 976 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 977 | |
wolfSSL | 13:80fb167dafdf | 978 | /** Mark an extension to be sent back to the client. */ |
wolfSSL | 13:80fb167dafdf | 979 | void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type); |
wolfSSL | 13:80fb167dafdf | 980 | |
wolfSSL | 13:80fb167dafdf | 981 | void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type) |
wolfSSL | 13:80fb167dafdf | 982 | { |
wolfSSL | 13:80fb167dafdf | 983 | TLSX *ext = TLSX_Find(ssl->extensions, type); |
wolfSSL | 13:80fb167dafdf | 984 | |
wolfSSL | 13:80fb167dafdf | 985 | if (ext) |
wolfSSL | 13:80fb167dafdf | 986 | ext->resp = 1; |
wolfSSL | 13:80fb167dafdf | 987 | } |
wolfSSL | 13:80fb167dafdf | 988 | |
wolfSSL | 13:80fb167dafdf | 989 | #endif |
wolfSSL | 13:80fb167dafdf | 990 | |
wolfSSL | 13:80fb167dafdf | 991 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 992 | /* Application-Layer Protocol Negotiation */ |
wolfSSL | 13:80fb167dafdf | 993 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 994 | |
wolfSSL | 13:80fb167dafdf | 995 | #ifdef HAVE_ALPN |
wolfSSL | 13:80fb167dafdf | 996 | /** Creates a new ALPN object, providing protocol name to use. */ |
wolfSSL | 13:80fb167dafdf | 997 | static ALPN* TLSX_ALPN_New(char *protocol_name, word16 protocol_nameSz, |
wolfSSL | 13:80fb167dafdf | 998 | void* heap) |
wolfSSL | 13:80fb167dafdf | 999 | { |
wolfSSL | 13:80fb167dafdf | 1000 | ALPN *alpn; |
wolfSSL | 13:80fb167dafdf | 1001 | |
wolfSSL | 13:80fb167dafdf | 1002 | WOLFSSL_ENTER("TLSX_ALPN_New"); |
wolfSSL | 13:80fb167dafdf | 1003 | |
wolfSSL | 13:80fb167dafdf | 1004 | if (protocol_name == NULL || |
wolfSSL | 13:80fb167dafdf | 1005 | protocol_nameSz > WOLFSSL_MAX_ALPN_PROTO_NAME_LEN) { |
wolfSSL | 13:80fb167dafdf | 1006 | WOLFSSL_MSG("Invalid arguments"); |
wolfSSL | 13:80fb167dafdf | 1007 | return NULL; |
wolfSSL | 13:80fb167dafdf | 1008 | } |
wolfSSL | 13:80fb167dafdf | 1009 | |
wolfSSL | 13:80fb167dafdf | 1010 | alpn = (ALPN*)XMALLOC(sizeof(ALPN), heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 1011 | if (alpn == NULL) { |
wolfSSL | 13:80fb167dafdf | 1012 | WOLFSSL_MSG("Memory failure"); |
wolfSSL | 13:80fb167dafdf | 1013 | return NULL; |
wolfSSL | 13:80fb167dafdf | 1014 | } |
wolfSSL | 13:80fb167dafdf | 1015 | |
wolfSSL | 13:80fb167dafdf | 1016 | alpn->next = NULL; |
wolfSSL | 13:80fb167dafdf | 1017 | alpn->negotiated = 0; |
wolfSSL | 13:80fb167dafdf | 1018 | alpn->options = 0; |
wolfSSL | 13:80fb167dafdf | 1019 | |
wolfSSL | 13:80fb167dafdf | 1020 | alpn->protocol_name = (char*)XMALLOC(protocol_nameSz + 1, |
wolfSSL | 13:80fb167dafdf | 1021 | heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 1022 | if (alpn->protocol_name == NULL) { |
wolfSSL | 13:80fb167dafdf | 1023 | WOLFSSL_MSG("Memory failure"); |
wolfSSL | 13:80fb167dafdf | 1024 | XFREE(alpn, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 1025 | return NULL; |
wolfSSL | 13:80fb167dafdf | 1026 | } |
wolfSSL | 13:80fb167dafdf | 1027 | |
wolfSSL | 13:80fb167dafdf | 1028 | XMEMCPY(alpn->protocol_name, protocol_name, protocol_nameSz); |
wolfSSL | 13:80fb167dafdf | 1029 | alpn->protocol_name[protocol_nameSz] = 0; |
wolfSSL | 13:80fb167dafdf | 1030 | |
wolfSSL | 13:80fb167dafdf | 1031 | return alpn; |
wolfSSL | 13:80fb167dafdf | 1032 | } |
wolfSSL | 13:80fb167dafdf | 1033 | |
wolfSSL | 13:80fb167dafdf | 1034 | /** Releases an ALPN object. */ |
wolfSSL | 13:80fb167dafdf | 1035 | static void TLSX_ALPN_Free(ALPN *alpn, void* heap) |
wolfSSL | 13:80fb167dafdf | 1036 | { |
wolfSSL | 13:80fb167dafdf | 1037 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 1038 | |
wolfSSL | 13:80fb167dafdf | 1039 | if (alpn == NULL) |
wolfSSL | 13:80fb167dafdf | 1040 | return; |
wolfSSL | 13:80fb167dafdf | 1041 | |
wolfSSL | 13:80fb167dafdf | 1042 | XFREE(alpn->protocol_name, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 1043 | XFREE(alpn, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 1044 | } |
wolfSSL | 13:80fb167dafdf | 1045 | |
wolfSSL | 13:80fb167dafdf | 1046 | /** Releases all ALPN objects in the provided list. */ |
wolfSSL | 13:80fb167dafdf | 1047 | static void TLSX_ALPN_FreeAll(ALPN *list, void* heap) |
wolfSSL | 13:80fb167dafdf | 1048 | { |
wolfSSL | 13:80fb167dafdf | 1049 | ALPN* alpn; |
wolfSSL | 13:80fb167dafdf | 1050 | |
wolfSSL | 13:80fb167dafdf | 1051 | while ((alpn = list)) { |
wolfSSL | 13:80fb167dafdf | 1052 | list = alpn->next; |
wolfSSL | 13:80fb167dafdf | 1053 | TLSX_ALPN_Free(alpn, heap); |
wolfSSL | 13:80fb167dafdf | 1054 | } |
wolfSSL | 13:80fb167dafdf | 1055 | } |
wolfSSL | 13:80fb167dafdf | 1056 | |
wolfSSL | 13:80fb167dafdf | 1057 | /** Tells the buffered size of the ALPN objects in a list. */ |
wolfSSL | 13:80fb167dafdf | 1058 | static word16 TLSX_ALPN_GetSize(ALPN *list) |
wolfSSL | 13:80fb167dafdf | 1059 | { |
wolfSSL | 13:80fb167dafdf | 1060 | ALPN* alpn; |
wolfSSL | 13:80fb167dafdf | 1061 | word16 length = OPAQUE16_LEN; /* list length */ |
wolfSSL | 13:80fb167dafdf | 1062 | |
wolfSSL | 13:80fb167dafdf | 1063 | while ((alpn = list)) { |
wolfSSL | 13:80fb167dafdf | 1064 | list = alpn->next; |
wolfSSL | 13:80fb167dafdf | 1065 | |
wolfSSL | 13:80fb167dafdf | 1066 | length++; /* protocol name length is on one byte */ |
wolfSSL | 13:80fb167dafdf | 1067 | length += (word16)XSTRLEN(alpn->protocol_name); |
wolfSSL | 13:80fb167dafdf | 1068 | } |
wolfSSL | 13:80fb167dafdf | 1069 | |
wolfSSL | 13:80fb167dafdf | 1070 | return length; |
wolfSSL | 13:80fb167dafdf | 1071 | } |
wolfSSL | 13:80fb167dafdf | 1072 | |
wolfSSL | 13:80fb167dafdf | 1073 | /** Writes the ALPN objects of a list in a buffer. */ |
wolfSSL | 13:80fb167dafdf | 1074 | static word16 TLSX_ALPN_Write(ALPN *list, byte *output) |
wolfSSL | 13:80fb167dafdf | 1075 | { |
wolfSSL | 13:80fb167dafdf | 1076 | ALPN* alpn; |
wolfSSL | 13:80fb167dafdf | 1077 | word16 length = 0; |
wolfSSL | 13:80fb167dafdf | 1078 | word16 offset = OPAQUE16_LEN; /* list length offset */ |
wolfSSL | 13:80fb167dafdf | 1079 | |
wolfSSL | 13:80fb167dafdf | 1080 | while ((alpn = list)) { |
wolfSSL | 13:80fb167dafdf | 1081 | list = alpn->next; |
wolfSSL | 13:80fb167dafdf | 1082 | |
wolfSSL | 13:80fb167dafdf | 1083 | length = (word16)XSTRLEN(alpn->protocol_name); |
wolfSSL | 13:80fb167dafdf | 1084 | |
wolfSSL | 13:80fb167dafdf | 1085 | /* protocol name length */ |
wolfSSL | 13:80fb167dafdf | 1086 | output[offset++] = (byte)length; |
wolfSSL | 13:80fb167dafdf | 1087 | |
wolfSSL | 13:80fb167dafdf | 1088 | /* protocol name value */ |
wolfSSL | 13:80fb167dafdf | 1089 | XMEMCPY(output + offset, alpn->protocol_name, length); |
wolfSSL | 13:80fb167dafdf | 1090 | |
wolfSSL | 13:80fb167dafdf | 1091 | offset += length; |
wolfSSL | 13:80fb167dafdf | 1092 | } |
wolfSSL | 13:80fb167dafdf | 1093 | |
wolfSSL | 13:80fb167dafdf | 1094 | /* writing list length */ |
wolfSSL | 13:80fb167dafdf | 1095 | c16toa(offset - OPAQUE16_LEN, output); |
wolfSSL | 13:80fb167dafdf | 1096 | |
wolfSSL | 13:80fb167dafdf | 1097 | return offset; |
wolfSSL | 13:80fb167dafdf | 1098 | } |
wolfSSL | 13:80fb167dafdf | 1099 | |
wolfSSL | 13:80fb167dafdf | 1100 | /** Finds a protocol name in the provided ALPN list */ |
wolfSSL | 13:80fb167dafdf | 1101 | static ALPN* TLSX_ALPN_Find(ALPN *list, char *protocol_name, word16 size) |
wolfSSL | 13:80fb167dafdf | 1102 | { |
wolfSSL | 13:80fb167dafdf | 1103 | ALPN *alpn; |
wolfSSL | 13:80fb167dafdf | 1104 | |
wolfSSL | 13:80fb167dafdf | 1105 | if (list == NULL || protocol_name == NULL) |
wolfSSL | 13:80fb167dafdf | 1106 | return NULL; |
wolfSSL | 13:80fb167dafdf | 1107 | |
wolfSSL | 13:80fb167dafdf | 1108 | alpn = list; |
wolfSSL | 13:80fb167dafdf | 1109 | while (alpn != NULL && ( |
wolfSSL | 13:80fb167dafdf | 1110 | (word16)XSTRLEN(alpn->protocol_name) != size || |
wolfSSL | 13:80fb167dafdf | 1111 | XSTRNCMP(alpn->protocol_name, protocol_name, size))) |
wolfSSL | 13:80fb167dafdf | 1112 | alpn = alpn->next; |
wolfSSL | 13:80fb167dafdf | 1113 | |
wolfSSL | 13:80fb167dafdf | 1114 | return alpn; |
wolfSSL | 13:80fb167dafdf | 1115 | } |
wolfSSL | 13:80fb167dafdf | 1116 | |
wolfSSL | 13:80fb167dafdf | 1117 | /** Set the ALPN matching client and server requirements */ |
wolfSSL | 13:80fb167dafdf | 1118 | static int TLSX_SetALPN(TLSX** extensions, const void* data, word16 size, |
wolfSSL | 13:80fb167dafdf | 1119 | void* heap) |
wolfSSL | 13:80fb167dafdf | 1120 | { |
wolfSSL | 13:80fb167dafdf | 1121 | ALPN *alpn; |
wolfSSL | 13:80fb167dafdf | 1122 | int ret; |
wolfSSL | 13:80fb167dafdf | 1123 | |
wolfSSL | 13:80fb167dafdf | 1124 | if (extensions == NULL || data == NULL) |
wolfSSL | 13:80fb167dafdf | 1125 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 1126 | |
wolfSSL | 13:80fb167dafdf | 1127 | alpn = TLSX_ALPN_New((char *)data, size, heap); |
wolfSSL | 13:80fb167dafdf | 1128 | if (alpn == NULL) { |
wolfSSL | 13:80fb167dafdf | 1129 | WOLFSSL_MSG("Memory failure"); |
wolfSSL | 13:80fb167dafdf | 1130 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 1131 | } |
wolfSSL | 13:80fb167dafdf | 1132 | |
wolfSSL | 13:80fb167dafdf | 1133 | alpn->negotiated = 1; |
wolfSSL | 13:80fb167dafdf | 1134 | |
wolfSSL | 13:80fb167dafdf | 1135 | ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL, (void*)alpn, |
wolfSSL | 13:80fb167dafdf | 1136 | heap); |
wolfSSL | 13:80fb167dafdf | 1137 | if (ret != 0) { |
wolfSSL | 13:80fb167dafdf | 1138 | TLSX_ALPN_Free(alpn, heap); |
wolfSSL | 13:80fb167dafdf | 1139 | return ret; |
wolfSSL | 13:80fb167dafdf | 1140 | } |
wolfSSL | 13:80fb167dafdf | 1141 | |
wolfSSL | 13:80fb167dafdf | 1142 | return SSL_SUCCESS; |
wolfSSL | 13:80fb167dafdf | 1143 | } |
wolfSSL | 13:80fb167dafdf | 1144 | |
wolfSSL | 13:80fb167dafdf | 1145 | /** Parses a buffer of ALPN extensions and set the first one matching |
wolfSSL | 13:80fb167dafdf | 1146 | * client and server requirements */ |
wolfSSL | 13:80fb167dafdf | 1147 | static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length, |
wolfSSL | 13:80fb167dafdf | 1148 | byte isRequest) |
wolfSSL | 13:80fb167dafdf | 1149 | { |
wolfSSL | 13:80fb167dafdf | 1150 | word16 size = 0, offset = 0, idx = 0; |
wolfSSL | 13:80fb167dafdf | 1151 | int r = BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1152 | byte match = 0; |
wolfSSL | 13:80fb167dafdf | 1153 | TLSX *extension; |
wolfSSL | 13:80fb167dafdf | 1154 | ALPN *alpn = NULL, *list; |
wolfSSL | 13:80fb167dafdf | 1155 | |
wolfSSL | 13:80fb167dafdf | 1156 | if (OPAQUE16_LEN > length) |
wolfSSL | 13:80fb167dafdf | 1157 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1158 | |
wolfSSL | 13:80fb167dafdf | 1159 | ato16(input, &size); |
wolfSSL | 13:80fb167dafdf | 1160 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 1161 | |
wolfSSL | 13:80fb167dafdf | 1162 | extension = TLSX_Find(ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL); |
wolfSSL | 13:80fb167dafdf | 1163 | if (extension == NULL) |
wolfSSL | 13:80fb167dafdf | 1164 | extension = TLSX_Find(ssl->ctx->extensions, |
wolfSSL | 13:80fb167dafdf | 1165 | TLSX_APPLICATION_LAYER_PROTOCOL); |
wolfSSL | 13:80fb167dafdf | 1166 | |
wolfSSL | 13:80fb167dafdf | 1167 | #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) |
wolfSSL | 13:80fb167dafdf | 1168 | if (ssl->alpnSelect != NULL) { |
wolfSSL | 13:80fb167dafdf | 1169 | const byte* out; |
wolfSSL | 13:80fb167dafdf | 1170 | unsigned char outLen; |
wolfSSL | 13:80fb167dafdf | 1171 | |
wolfSSL | 13:80fb167dafdf | 1172 | if (ssl->alpnSelect(ssl, &out, &outLen, input + offset, size, |
wolfSSL | 13:80fb167dafdf | 1173 | ssl->alpnSelectArg) == 0) { |
wolfSSL | 13:80fb167dafdf | 1174 | WOLFSSL_MSG("ALPN protocol match"); |
wolfSSL | 13:80fb167dafdf | 1175 | if (TLSX_UseALPN(&ssl->extensions, (char*)out, outLen, 0, ssl->heap) |
wolfSSL | 13:80fb167dafdf | 1176 | == SSL_SUCCESS) { |
wolfSSL | 13:80fb167dafdf | 1177 | if (extension == NULL) { |
wolfSSL | 13:80fb167dafdf | 1178 | extension = TLSX_Find(ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 1179 | TLSX_APPLICATION_LAYER_PROTOCOL); |
wolfSSL | 13:80fb167dafdf | 1180 | } |
wolfSSL | 13:80fb167dafdf | 1181 | } |
wolfSSL | 13:80fb167dafdf | 1182 | } |
wolfSSL | 13:80fb167dafdf | 1183 | } |
wolfSSL | 13:80fb167dafdf | 1184 | #endif |
wolfSSL | 13:80fb167dafdf | 1185 | |
wolfSSL | 13:80fb167dafdf | 1186 | if (extension == NULL || extension->data == NULL) { |
wolfSSL | 13:80fb167dafdf | 1187 | WOLFSSL_MSG("No ALPN extensions not used or bad"); |
wolfSSL | 13:80fb167dafdf | 1188 | return isRequest ? 0 /* not using ALPN */ |
wolfSSL | 13:80fb167dafdf | 1189 | : BUFFER_ERROR; /* unexpected ALPN response */ |
wolfSSL | 13:80fb167dafdf | 1190 | } |
wolfSSL | 13:80fb167dafdf | 1191 | |
wolfSSL | 13:80fb167dafdf | 1192 | /* validating alpn list length */ |
wolfSSL | 13:80fb167dafdf | 1193 | if (length != OPAQUE16_LEN + size) |
wolfSSL | 13:80fb167dafdf | 1194 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1195 | |
wolfSSL | 13:80fb167dafdf | 1196 | list = (ALPN*)extension->data; |
wolfSSL | 13:80fb167dafdf | 1197 | |
wolfSSL | 13:80fb167dafdf | 1198 | /* keep the list sent by client */ |
wolfSSL | 13:80fb167dafdf | 1199 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 1200 | if (ssl->alpn_client_list != NULL) |
wolfSSL | 13:80fb167dafdf | 1201 | XFREE(ssl->alpn_client_list, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 1202 | |
wolfSSL | 13:80fb167dafdf | 1203 | ssl->alpn_client_list = (char *)XMALLOC(size, ssl->heap, |
wolfSSL | 13:80fb167dafdf | 1204 | DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 1205 | if (ssl->alpn_client_list == NULL) |
wolfSSL | 13:80fb167dafdf | 1206 | return MEMORY_ERROR; |
wolfSSL | 13:80fb167dafdf | 1207 | } |
wolfSSL | 13:80fb167dafdf | 1208 | |
wolfSSL | 13:80fb167dafdf | 1209 | for (size = 0; offset < length; offset += size) { |
wolfSSL | 13:80fb167dafdf | 1210 | |
wolfSSL | 13:80fb167dafdf | 1211 | size = input[offset++]; |
wolfSSL | 13:80fb167dafdf | 1212 | if (offset + size > length) |
wolfSSL | 13:80fb167dafdf | 1213 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1214 | |
wolfSSL | 13:80fb167dafdf | 1215 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 1216 | XMEMCPY(ssl->alpn_client_list+idx, (char*)input + offset, size); |
wolfSSL | 13:80fb167dafdf | 1217 | idx += size; |
wolfSSL | 13:80fb167dafdf | 1218 | ssl->alpn_client_list[idx++] = ','; |
wolfSSL | 13:80fb167dafdf | 1219 | } |
wolfSSL | 13:80fb167dafdf | 1220 | |
wolfSSL | 13:80fb167dafdf | 1221 | if (!match) { |
wolfSSL | 13:80fb167dafdf | 1222 | alpn = TLSX_ALPN_Find(list, (char*)input + offset, size); |
wolfSSL | 13:80fb167dafdf | 1223 | if (alpn != NULL) { |
wolfSSL | 13:80fb167dafdf | 1224 | WOLFSSL_MSG("ALPN protocol match"); |
wolfSSL | 13:80fb167dafdf | 1225 | match = 1; |
wolfSSL | 13:80fb167dafdf | 1226 | |
wolfSSL | 13:80fb167dafdf | 1227 | /* skip reading other values if not required */ |
wolfSSL | 13:80fb167dafdf | 1228 | if (!isRequest) |
wolfSSL | 13:80fb167dafdf | 1229 | break; |
wolfSSL | 13:80fb167dafdf | 1230 | } |
wolfSSL | 13:80fb167dafdf | 1231 | } |
wolfSSL | 13:80fb167dafdf | 1232 | } |
wolfSSL | 13:80fb167dafdf | 1233 | |
wolfSSL | 13:80fb167dafdf | 1234 | if (isRequest) |
wolfSSL | 13:80fb167dafdf | 1235 | ssl->alpn_client_list[idx-1] = 0; |
wolfSSL | 13:80fb167dafdf | 1236 | |
wolfSSL | 13:80fb167dafdf | 1237 | if (!match) { |
wolfSSL | 13:80fb167dafdf | 1238 | WOLFSSL_MSG("No ALPN protocol match"); |
wolfSSL | 13:80fb167dafdf | 1239 | |
wolfSSL | 13:80fb167dafdf | 1240 | /* do nothing if no protocol match between client and server and option |
wolfSSL | 13:80fb167dafdf | 1241 | is set to continue (like OpenSSL) */ |
wolfSSL | 13:80fb167dafdf | 1242 | if (list->options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) { |
wolfSSL | 13:80fb167dafdf | 1243 | WOLFSSL_MSG("Continue on mismatch"); |
wolfSSL | 13:80fb167dafdf | 1244 | return 0; |
wolfSSL | 13:80fb167dafdf | 1245 | } |
wolfSSL | 13:80fb167dafdf | 1246 | |
wolfSSL | 13:80fb167dafdf | 1247 | SendAlert(ssl, alert_fatal, no_application_protocol); |
wolfSSL | 13:80fb167dafdf | 1248 | return UNKNOWN_ALPN_PROTOCOL_NAME_E; |
wolfSSL | 13:80fb167dafdf | 1249 | } |
wolfSSL | 13:80fb167dafdf | 1250 | |
wolfSSL | 13:80fb167dafdf | 1251 | /* set the matching negotiated protocol */ |
wolfSSL | 13:80fb167dafdf | 1252 | r = TLSX_SetALPN(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 1253 | alpn->protocol_name, |
wolfSSL | 13:80fb167dafdf | 1254 | (word16)XSTRLEN(alpn->protocol_name), |
wolfSSL | 13:80fb167dafdf | 1255 | ssl->heap); |
wolfSSL | 13:80fb167dafdf | 1256 | if (r != SSL_SUCCESS) { |
wolfSSL | 13:80fb167dafdf | 1257 | WOLFSSL_MSG("TLSX_UseALPN failed"); |
wolfSSL | 13:80fb167dafdf | 1258 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1259 | } |
wolfSSL | 13:80fb167dafdf | 1260 | |
wolfSSL | 13:80fb167dafdf | 1261 | /* reply to ALPN extension sent from client */ |
wolfSSL | 13:80fb167dafdf | 1262 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 1263 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 1264 | TLSX_SetResponse(ssl, TLSX_APPLICATION_LAYER_PROTOCOL); |
wolfSSL | 13:80fb167dafdf | 1265 | #endif |
wolfSSL | 13:80fb167dafdf | 1266 | } |
wolfSSL | 13:80fb167dafdf | 1267 | |
wolfSSL | 13:80fb167dafdf | 1268 | return 0; |
wolfSSL | 13:80fb167dafdf | 1269 | } |
wolfSSL | 13:80fb167dafdf | 1270 | |
wolfSSL | 13:80fb167dafdf | 1271 | /** Add a protocol name to the list of accepted usable ones */ |
wolfSSL | 13:80fb167dafdf | 1272 | int TLSX_UseALPN(TLSX** extensions, const void* data, word16 size, byte options, |
wolfSSL | 13:80fb167dafdf | 1273 | void* heap) |
wolfSSL | 13:80fb167dafdf | 1274 | { |
wolfSSL | 13:80fb167dafdf | 1275 | ALPN *alpn; |
wolfSSL | 13:80fb167dafdf | 1276 | TLSX *extension; |
wolfSSL | 13:80fb167dafdf | 1277 | int ret; |
wolfSSL | 13:80fb167dafdf | 1278 | |
wolfSSL | 13:80fb167dafdf | 1279 | if (extensions == NULL || data == NULL) |
wolfSSL | 13:80fb167dafdf | 1280 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 1281 | |
wolfSSL | 13:80fb167dafdf | 1282 | alpn = TLSX_ALPN_New((char *)data, size, heap); |
wolfSSL | 13:80fb167dafdf | 1283 | if (alpn == NULL) { |
wolfSSL | 13:80fb167dafdf | 1284 | WOLFSSL_MSG("Memory failure"); |
wolfSSL | 13:80fb167dafdf | 1285 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 1286 | } |
wolfSSL | 13:80fb167dafdf | 1287 | |
wolfSSL | 13:80fb167dafdf | 1288 | /* Set Options of ALPN */ |
wolfSSL | 13:80fb167dafdf | 1289 | alpn->options = options; |
wolfSSL | 13:80fb167dafdf | 1290 | |
wolfSSL | 13:80fb167dafdf | 1291 | extension = TLSX_Find(*extensions, TLSX_APPLICATION_LAYER_PROTOCOL); |
wolfSSL | 13:80fb167dafdf | 1292 | if (extension == NULL) { |
wolfSSL | 13:80fb167dafdf | 1293 | ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL, |
wolfSSL | 13:80fb167dafdf | 1294 | (void*)alpn, heap); |
wolfSSL | 13:80fb167dafdf | 1295 | if (ret != 0) { |
wolfSSL | 13:80fb167dafdf | 1296 | TLSX_ALPN_Free(alpn, heap); |
wolfSSL | 13:80fb167dafdf | 1297 | return ret; |
wolfSSL | 13:80fb167dafdf | 1298 | } |
wolfSSL | 13:80fb167dafdf | 1299 | } |
wolfSSL | 13:80fb167dafdf | 1300 | else { |
wolfSSL | 13:80fb167dafdf | 1301 | /* push new ALPN object to extension data. */ |
wolfSSL | 13:80fb167dafdf | 1302 | alpn->next = (ALPN*)extension->data; |
wolfSSL | 13:80fb167dafdf | 1303 | extension->data = (void*)alpn; |
wolfSSL | 13:80fb167dafdf | 1304 | } |
wolfSSL | 13:80fb167dafdf | 1305 | |
wolfSSL | 13:80fb167dafdf | 1306 | return SSL_SUCCESS; |
wolfSSL | 13:80fb167dafdf | 1307 | } |
wolfSSL | 13:80fb167dafdf | 1308 | |
wolfSSL | 13:80fb167dafdf | 1309 | /** Get the protocol name set by the server */ |
wolfSSL | 13:80fb167dafdf | 1310 | int TLSX_ALPN_GetRequest(TLSX* extensions, void** data, word16 *dataSz) |
wolfSSL | 13:80fb167dafdf | 1311 | { |
wolfSSL | 13:80fb167dafdf | 1312 | TLSX *extension; |
wolfSSL | 13:80fb167dafdf | 1313 | ALPN *alpn; |
wolfSSL | 13:80fb167dafdf | 1314 | |
wolfSSL | 13:80fb167dafdf | 1315 | if (extensions == NULL || data == NULL || dataSz == NULL) |
wolfSSL | 13:80fb167dafdf | 1316 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 1317 | |
wolfSSL | 13:80fb167dafdf | 1318 | extension = TLSX_Find(extensions, TLSX_APPLICATION_LAYER_PROTOCOL); |
wolfSSL | 13:80fb167dafdf | 1319 | if (extension == NULL) { |
wolfSSL | 13:80fb167dafdf | 1320 | WOLFSSL_MSG("TLS extension not found"); |
wolfSSL | 13:80fb167dafdf | 1321 | return SSL_ALPN_NOT_FOUND; |
wolfSSL | 13:80fb167dafdf | 1322 | } |
wolfSSL | 13:80fb167dafdf | 1323 | |
wolfSSL | 13:80fb167dafdf | 1324 | alpn = (ALPN *)extension->data; |
wolfSSL | 13:80fb167dafdf | 1325 | if (alpn == NULL) { |
wolfSSL | 13:80fb167dafdf | 1326 | WOLFSSL_MSG("ALPN extension not found"); |
wolfSSL | 13:80fb167dafdf | 1327 | *data = NULL; |
wolfSSL | 13:80fb167dafdf | 1328 | *dataSz = 0; |
wolfSSL | 13:80fb167dafdf | 1329 | return SSL_FATAL_ERROR; |
wolfSSL | 13:80fb167dafdf | 1330 | } |
wolfSSL | 13:80fb167dafdf | 1331 | |
wolfSSL | 13:80fb167dafdf | 1332 | if (alpn->negotiated != 1) { |
wolfSSL | 13:80fb167dafdf | 1333 | |
wolfSSL | 13:80fb167dafdf | 1334 | /* consider as an error */ |
wolfSSL | 13:80fb167dafdf | 1335 | if (alpn->options & WOLFSSL_ALPN_FAILED_ON_MISMATCH) { |
wolfSSL | 13:80fb167dafdf | 1336 | WOLFSSL_MSG("No protocol match with peer -> Failed"); |
wolfSSL | 13:80fb167dafdf | 1337 | return SSL_FATAL_ERROR; |
wolfSSL | 13:80fb167dafdf | 1338 | } |
wolfSSL | 13:80fb167dafdf | 1339 | |
wolfSSL | 13:80fb167dafdf | 1340 | /* continue without negotiated protocol */ |
wolfSSL | 13:80fb167dafdf | 1341 | WOLFSSL_MSG("No protocol match with peer -> Continue"); |
wolfSSL | 13:80fb167dafdf | 1342 | return SSL_ALPN_NOT_FOUND; |
wolfSSL | 13:80fb167dafdf | 1343 | } |
wolfSSL | 13:80fb167dafdf | 1344 | |
wolfSSL | 13:80fb167dafdf | 1345 | if (alpn->next != NULL) { |
wolfSSL | 13:80fb167dafdf | 1346 | WOLFSSL_MSG("Only one protocol name must be accepted"); |
wolfSSL | 13:80fb167dafdf | 1347 | return SSL_FATAL_ERROR; |
wolfSSL | 13:80fb167dafdf | 1348 | } |
wolfSSL | 13:80fb167dafdf | 1349 | |
wolfSSL | 13:80fb167dafdf | 1350 | *data = alpn->protocol_name; |
wolfSSL | 13:80fb167dafdf | 1351 | *dataSz = (word16)XSTRLEN((char*)*data); |
wolfSSL | 13:80fb167dafdf | 1352 | |
wolfSSL | 13:80fb167dafdf | 1353 | return SSL_SUCCESS; |
wolfSSL | 13:80fb167dafdf | 1354 | } |
wolfSSL | 13:80fb167dafdf | 1355 | |
wolfSSL | 13:80fb167dafdf | 1356 | #define ALPN_FREE_ALL TLSX_ALPN_FreeAll |
wolfSSL | 13:80fb167dafdf | 1357 | #define ALPN_GET_SIZE TLSX_ALPN_GetSize |
wolfSSL | 13:80fb167dafdf | 1358 | #define ALPN_WRITE TLSX_ALPN_Write |
wolfSSL | 13:80fb167dafdf | 1359 | #define ALPN_PARSE TLSX_ALPN_ParseAndSet |
wolfSSL | 13:80fb167dafdf | 1360 | |
wolfSSL | 13:80fb167dafdf | 1361 | #else /* HAVE_ALPN */ |
wolfSSL | 13:80fb167dafdf | 1362 | |
wolfSSL | 13:80fb167dafdf | 1363 | #define ALPN_FREE_ALL(list, heap) |
wolfSSL | 13:80fb167dafdf | 1364 | #define ALPN_GET_SIZE(list) 0 |
wolfSSL | 13:80fb167dafdf | 1365 | #define ALPN_WRITE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 1366 | #define ALPN_PARSE(a, b, c, d) 0 |
wolfSSL | 13:80fb167dafdf | 1367 | |
wolfSSL | 13:80fb167dafdf | 1368 | #endif /* HAVE_ALPN */ |
wolfSSL | 13:80fb167dafdf | 1369 | |
wolfSSL | 13:80fb167dafdf | 1370 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 1371 | /* Server Name Indication */ |
wolfSSL | 13:80fb167dafdf | 1372 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 1373 | |
wolfSSL | 13:80fb167dafdf | 1374 | #ifdef HAVE_SNI |
wolfSSL | 13:80fb167dafdf | 1375 | |
wolfSSL | 13:80fb167dafdf | 1376 | /** Creates a new SNI object. */ |
wolfSSL | 13:80fb167dafdf | 1377 | static SNI* TLSX_SNI_New(byte type, const void* data, word16 size, void* heap) |
wolfSSL | 13:80fb167dafdf | 1378 | { |
wolfSSL | 13:80fb167dafdf | 1379 | SNI* sni = (SNI*)XMALLOC(sizeof(SNI), heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 1380 | |
wolfSSL | 13:80fb167dafdf | 1381 | if (sni) { |
wolfSSL | 13:80fb167dafdf | 1382 | sni->type = type; |
wolfSSL | 13:80fb167dafdf | 1383 | sni->next = NULL; |
wolfSSL | 13:80fb167dafdf | 1384 | |
wolfSSL | 13:80fb167dafdf | 1385 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 1386 | sni->options = 0; |
wolfSSL | 13:80fb167dafdf | 1387 | sni->status = WOLFSSL_SNI_NO_MATCH; |
wolfSSL | 13:80fb167dafdf | 1388 | #endif |
wolfSSL | 13:80fb167dafdf | 1389 | |
wolfSSL | 13:80fb167dafdf | 1390 | switch (sni->type) { |
wolfSSL | 13:80fb167dafdf | 1391 | case WOLFSSL_SNI_HOST_NAME: |
wolfSSL | 13:80fb167dafdf | 1392 | sni->data.host_name = (char*)XMALLOC(size + 1, heap, |
wolfSSL | 13:80fb167dafdf | 1393 | DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 1394 | if (sni->data.host_name) { |
wolfSSL | 13:80fb167dafdf | 1395 | XSTRNCPY(sni->data.host_name, (const char*)data, size); |
wolfSSL | 13:80fb167dafdf | 1396 | sni->data.host_name[size] = 0; |
wolfSSL | 13:80fb167dafdf | 1397 | } else { |
wolfSSL | 13:80fb167dafdf | 1398 | XFREE(sni, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 1399 | sni = NULL; |
wolfSSL | 13:80fb167dafdf | 1400 | } |
wolfSSL | 13:80fb167dafdf | 1401 | break; |
wolfSSL | 13:80fb167dafdf | 1402 | |
wolfSSL | 13:80fb167dafdf | 1403 | default: /* invalid type */ |
wolfSSL | 13:80fb167dafdf | 1404 | XFREE(sni, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 1405 | sni = NULL; |
wolfSSL | 13:80fb167dafdf | 1406 | } |
wolfSSL | 13:80fb167dafdf | 1407 | } |
wolfSSL | 13:80fb167dafdf | 1408 | |
wolfSSL | 13:80fb167dafdf | 1409 | return sni; |
wolfSSL | 13:80fb167dafdf | 1410 | } |
wolfSSL | 13:80fb167dafdf | 1411 | |
wolfSSL | 13:80fb167dafdf | 1412 | /** Releases a SNI object. */ |
wolfSSL | 13:80fb167dafdf | 1413 | static void TLSX_SNI_Free(SNI* sni, void* heap) |
wolfSSL | 13:80fb167dafdf | 1414 | { |
wolfSSL | 13:80fb167dafdf | 1415 | if (sni) { |
wolfSSL | 13:80fb167dafdf | 1416 | switch (sni->type) { |
wolfSSL | 13:80fb167dafdf | 1417 | case WOLFSSL_SNI_HOST_NAME: |
wolfSSL | 13:80fb167dafdf | 1418 | XFREE(sni->data.host_name, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 1419 | break; |
wolfSSL | 13:80fb167dafdf | 1420 | } |
wolfSSL | 13:80fb167dafdf | 1421 | |
wolfSSL | 13:80fb167dafdf | 1422 | XFREE(sni, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 1423 | } |
wolfSSL | 13:80fb167dafdf | 1424 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 1425 | } |
wolfSSL | 13:80fb167dafdf | 1426 | |
wolfSSL | 13:80fb167dafdf | 1427 | /** Releases all SNI objects in the provided list. */ |
wolfSSL | 13:80fb167dafdf | 1428 | static void TLSX_SNI_FreeAll(SNI* list, void* heap) |
wolfSSL | 13:80fb167dafdf | 1429 | { |
wolfSSL | 13:80fb167dafdf | 1430 | SNI* sni; |
wolfSSL | 13:80fb167dafdf | 1431 | |
wolfSSL | 13:80fb167dafdf | 1432 | while ((sni = list)) { |
wolfSSL | 13:80fb167dafdf | 1433 | list = sni->next; |
wolfSSL | 13:80fb167dafdf | 1434 | TLSX_SNI_Free(sni, heap); |
wolfSSL | 13:80fb167dafdf | 1435 | } |
wolfSSL | 13:80fb167dafdf | 1436 | } |
wolfSSL | 13:80fb167dafdf | 1437 | |
wolfSSL | 13:80fb167dafdf | 1438 | /** Tells the buffered size of the SNI objects in a list. */ |
wolfSSL | 13:80fb167dafdf | 1439 | static word16 TLSX_SNI_GetSize(SNI* list) |
wolfSSL | 13:80fb167dafdf | 1440 | { |
wolfSSL | 13:80fb167dafdf | 1441 | SNI* sni; |
wolfSSL | 13:80fb167dafdf | 1442 | word16 length = OPAQUE16_LEN; /* list length */ |
wolfSSL | 13:80fb167dafdf | 1443 | |
wolfSSL | 13:80fb167dafdf | 1444 | while ((sni = list)) { |
wolfSSL | 13:80fb167dafdf | 1445 | list = sni->next; |
wolfSSL | 13:80fb167dafdf | 1446 | |
wolfSSL | 13:80fb167dafdf | 1447 | length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */ |
wolfSSL | 13:80fb167dafdf | 1448 | |
wolfSSL | 13:80fb167dafdf | 1449 | switch (sni->type) { |
wolfSSL | 13:80fb167dafdf | 1450 | case WOLFSSL_SNI_HOST_NAME: |
wolfSSL | 13:80fb167dafdf | 1451 | length += (word16)XSTRLEN((char*)sni->data.host_name); |
wolfSSL | 13:80fb167dafdf | 1452 | break; |
wolfSSL | 13:80fb167dafdf | 1453 | } |
wolfSSL | 13:80fb167dafdf | 1454 | } |
wolfSSL | 13:80fb167dafdf | 1455 | |
wolfSSL | 13:80fb167dafdf | 1456 | return length; |
wolfSSL | 13:80fb167dafdf | 1457 | } |
wolfSSL | 13:80fb167dafdf | 1458 | |
wolfSSL | 13:80fb167dafdf | 1459 | /** Writes the SNI objects of a list in a buffer. */ |
wolfSSL | 13:80fb167dafdf | 1460 | static word16 TLSX_SNI_Write(SNI* list, byte* output) |
wolfSSL | 13:80fb167dafdf | 1461 | { |
wolfSSL | 13:80fb167dafdf | 1462 | SNI* sni; |
wolfSSL | 13:80fb167dafdf | 1463 | word16 length = 0; |
wolfSSL | 13:80fb167dafdf | 1464 | word16 offset = OPAQUE16_LEN; /* list length offset */ |
wolfSSL | 13:80fb167dafdf | 1465 | |
wolfSSL | 13:80fb167dafdf | 1466 | while ((sni = list)) { |
wolfSSL | 13:80fb167dafdf | 1467 | list = sni->next; |
wolfSSL | 13:80fb167dafdf | 1468 | |
wolfSSL | 13:80fb167dafdf | 1469 | output[offset++] = sni->type; /* sni type */ |
wolfSSL | 13:80fb167dafdf | 1470 | |
wolfSSL | 13:80fb167dafdf | 1471 | switch (sni->type) { |
wolfSSL | 13:80fb167dafdf | 1472 | case WOLFSSL_SNI_HOST_NAME: |
wolfSSL | 13:80fb167dafdf | 1473 | length = (word16)XSTRLEN((char*)sni->data.host_name); |
wolfSSL | 13:80fb167dafdf | 1474 | |
wolfSSL | 13:80fb167dafdf | 1475 | c16toa(length, output + offset); /* sni length */ |
wolfSSL | 13:80fb167dafdf | 1476 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 1477 | |
wolfSSL | 13:80fb167dafdf | 1478 | XMEMCPY(output + offset, sni->data.host_name, length); |
wolfSSL | 13:80fb167dafdf | 1479 | |
wolfSSL | 13:80fb167dafdf | 1480 | offset += length; |
wolfSSL | 13:80fb167dafdf | 1481 | break; |
wolfSSL | 13:80fb167dafdf | 1482 | } |
wolfSSL | 13:80fb167dafdf | 1483 | } |
wolfSSL | 13:80fb167dafdf | 1484 | |
wolfSSL | 13:80fb167dafdf | 1485 | c16toa(offset - OPAQUE16_LEN, output); /* writing list length */ |
wolfSSL | 13:80fb167dafdf | 1486 | |
wolfSSL | 13:80fb167dafdf | 1487 | return offset; |
wolfSSL | 13:80fb167dafdf | 1488 | } |
wolfSSL | 13:80fb167dafdf | 1489 | |
wolfSSL | 13:80fb167dafdf | 1490 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 1491 | |
wolfSSL | 13:80fb167dafdf | 1492 | /** Finds a SNI object in the provided list. */ |
wolfSSL | 13:80fb167dafdf | 1493 | static SNI* TLSX_SNI_Find(SNI *list, byte type) |
wolfSSL | 13:80fb167dafdf | 1494 | { |
wolfSSL | 13:80fb167dafdf | 1495 | SNI *sni = list; |
wolfSSL | 13:80fb167dafdf | 1496 | |
wolfSSL | 13:80fb167dafdf | 1497 | while (sni && sni->type != type) |
wolfSSL | 13:80fb167dafdf | 1498 | sni = sni->next; |
wolfSSL | 13:80fb167dafdf | 1499 | |
wolfSSL | 13:80fb167dafdf | 1500 | return sni; |
wolfSSL | 13:80fb167dafdf | 1501 | } |
wolfSSL | 13:80fb167dafdf | 1502 | |
wolfSSL | 13:80fb167dafdf | 1503 | |
wolfSSL | 13:80fb167dafdf | 1504 | /** Sets the status of a SNI object. */ |
wolfSSL | 13:80fb167dafdf | 1505 | static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status) |
wolfSSL | 13:80fb167dafdf | 1506 | { |
wolfSSL | 13:80fb167dafdf | 1507 | TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:80fb167dafdf | 1508 | SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type); |
wolfSSL | 13:80fb167dafdf | 1509 | |
wolfSSL | 13:80fb167dafdf | 1510 | if (sni) |
wolfSSL | 13:80fb167dafdf | 1511 | sni->status = status; |
wolfSSL | 13:80fb167dafdf | 1512 | } |
wolfSSL | 13:80fb167dafdf | 1513 | |
wolfSSL | 13:80fb167dafdf | 1514 | /** Gets the status of a SNI object. */ |
wolfSSL | 13:80fb167dafdf | 1515 | byte TLSX_SNI_Status(TLSX* extensions, byte type) |
wolfSSL | 13:80fb167dafdf | 1516 | { |
wolfSSL | 13:80fb167dafdf | 1517 | TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:80fb167dafdf | 1518 | SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type); |
wolfSSL | 13:80fb167dafdf | 1519 | |
wolfSSL | 13:80fb167dafdf | 1520 | if (sni) |
wolfSSL | 13:80fb167dafdf | 1521 | return sni->status; |
wolfSSL | 13:80fb167dafdf | 1522 | |
wolfSSL | 13:80fb167dafdf | 1523 | return 0; |
wolfSSL | 13:80fb167dafdf | 1524 | } |
wolfSSL | 13:80fb167dafdf | 1525 | |
wolfSSL | 13:80fb167dafdf | 1526 | #endif /* NO_WOLFSSL_SERVER */ |
wolfSSL | 13:80fb167dafdf | 1527 | |
wolfSSL | 13:80fb167dafdf | 1528 | /** Parses a buffer of SNI extensions. */ |
wolfSSL | 13:80fb167dafdf | 1529 | static int TLSX_SNI_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:80fb167dafdf | 1530 | byte isRequest) |
wolfSSL | 13:80fb167dafdf | 1531 | { |
wolfSSL | 13:80fb167dafdf | 1532 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 1533 | word16 size = 0; |
wolfSSL | 13:80fb167dafdf | 1534 | word16 offset = 0; |
wolfSSL | 13:80fb167dafdf | 1535 | int cacheOnly = 0; |
wolfSSL | 13:80fb167dafdf | 1536 | #endif |
wolfSSL | 13:80fb167dafdf | 1537 | |
wolfSSL | 13:80fb167dafdf | 1538 | TLSX *extension = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:80fb167dafdf | 1539 | |
wolfSSL | 13:80fb167dafdf | 1540 | if (!extension) |
wolfSSL | 13:80fb167dafdf | 1541 | extension = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:80fb167dafdf | 1542 | |
wolfSSL | 13:80fb167dafdf | 1543 | (void)isRequest; |
wolfSSL | 13:80fb167dafdf | 1544 | (void)input; |
wolfSSL | 13:80fb167dafdf | 1545 | |
wolfSSL | 13:80fb167dafdf | 1546 | if (!extension || !extension->data) { |
wolfSSL | 13:80fb167dafdf | 1547 | #if defined(WOLFSSL_ALWAYS_KEEP_SNI) && !defined(NO_WOLFSSL_SERVER) |
wolfSSL | 13:80fb167dafdf | 1548 | /* This will keep SNI even though TLSX_UseSNI has not been called. |
wolfSSL | 13:80fb167dafdf | 1549 | * Enable it so that the received sni is available to functions |
wolfSSL | 13:80fb167dafdf | 1550 | * that use a custom callback when SNI is received */ |
wolfSSL | 13:80fb167dafdf | 1551 | cacheOnly = 1; |
wolfSSL | 13:80fb167dafdf | 1552 | WOLFSSL_MSG("Forcing SSL object to store SNI parameter"); |
wolfSSL | 13:80fb167dafdf | 1553 | #else |
wolfSSL | 13:80fb167dafdf | 1554 | return isRequest ? 0 /* not using SNI. */ |
wolfSSL | 13:80fb167dafdf | 1555 | : BUFFER_ERROR; /* unexpected SNI response. */ |
wolfSSL | 13:80fb167dafdf | 1556 | #endif |
wolfSSL | 13:80fb167dafdf | 1557 | } |
wolfSSL | 13:80fb167dafdf | 1558 | |
wolfSSL | 13:80fb167dafdf | 1559 | if (!isRequest) |
wolfSSL | 13:80fb167dafdf | 1560 | return length ? BUFFER_ERROR /* SNI response MUST be empty. */ |
wolfSSL | 13:80fb167dafdf | 1561 | : 0; /* nothing else to do. */ |
wolfSSL | 13:80fb167dafdf | 1562 | |
wolfSSL | 13:80fb167dafdf | 1563 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 1564 | |
wolfSSL | 13:80fb167dafdf | 1565 | if (OPAQUE16_LEN > length) |
wolfSSL | 13:80fb167dafdf | 1566 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1567 | |
wolfSSL | 13:80fb167dafdf | 1568 | ato16(input, &size); |
wolfSSL | 13:80fb167dafdf | 1569 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 1570 | |
wolfSSL | 13:80fb167dafdf | 1571 | /* validating sni list length */ |
wolfSSL | 13:80fb167dafdf | 1572 | if (length != OPAQUE16_LEN + size) |
wolfSSL | 13:80fb167dafdf | 1573 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1574 | |
wolfSSL | 13:80fb167dafdf | 1575 | for (size = 0; offset < length; offset += size) { |
wolfSSL | 13:80fb167dafdf | 1576 | SNI *sni = NULL; |
wolfSSL | 13:80fb167dafdf | 1577 | byte type = input[offset++]; |
wolfSSL | 13:80fb167dafdf | 1578 | |
wolfSSL | 13:80fb167dafdf | 1579 | if (offset + OPAQUE16_LEN > length) |
wolfSSL | 13:80fb167dafdf | 1580 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1581 | |
wolfSSL | 13:80fb167dafdf | 1582 | ato16(input + offset, &size); |
wolfSSL | 13:80fb167dafdf | 1583 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 1584 | |
wolfSSL | 13:80fb167dafdf | 1585 | if (offset + size > length) |
wolfSSL | 13:80fb167dafdf | 1586 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1587 | |
wolfSSL | 13:80fb167dafdf | 1588 | if (!cacheOnly && !(sni = TLSX_SNI_Find((SNI*)extension->data, type))) |
wolfSSL | 13:80fb167dafdf | 1589 | continue; /* not using this type of SNI. */ |
wolfSSL | 13:80fb167dafdf | 1590 | |
wolfSSL | 13:80fb167dafdf | 1591 | switch(type) { |
wolfSSL | 13:80fb167dafdf | 1592 | case WOLFSSL_SNI_HOST_NAME: { |
wolfSSL | 13:80fb167dafdf | 1593 | int matchStat; |
wolfSSL | 13:80fb167dafdf | 1594 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 1595 | /* Don't process the second ClientHello SNI extension if there |
wolfSSL | 13:80fb167dafdf | 1596 | * was problems with the first. |
wolfSSL | 13:80fb167dafdf | 1597 | */ |
wolfSSL | 13:80fb167dafdf | 1598 | if (sni->status != 0) |
wolfSSL | 13:80fb167dafdf | 1599 | break; |
wolfSSL | 13:80fb167dafdf | 1600 | #endif |
wolfSSL | 13:80fb167dafdf | 1601 | byte matched = cacheOnly || |
wolfSSL | 13:80fb167dafdf | 1602 | ((XSTRLEN(sni->data.host_name) == size) |
wolfSSL | 13:80fb167dafdf | 1603 | && (XSTRNCMP(sni->data.host_name, |
wolfSSL | 13:80fb167dafdf | 1604 | (const char*)input + offset, size) == 0)); |
wolfSSL | 13:80fb167dafdf | 1605 | |
wolfSSL | 13:80fb167dafdf | 1606 | if (matched || sni->options & WOLFSSL_SNI_ANSWER_ON_MISMATCH) { |
wolfSSL | 13:80fb167dafdf | 1607 | int r = TLSX_UseSNI(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 1608 | type, input + offset, size, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 1609 | |
wolfSSL | 13:80fb167dafdf | 1610 | if (r != SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 1611 | return r; /* throws error. */ |
wolfSSL | 13:80fb167dafdf | 1612 | |
wolfSSL | 13:80fb167dafdf | 1613 | if(cacheOnly) { |
wolfSSL | 13:80fb167dafdf | 1614 | WOLFSSL_MSG("Forcing storage of SNI, Fake match"); |
wolfSSL | 13:80fb167dafdf | 1615 | matchStat = WOLFSSL_SNI_FORCE_KEEP; |
wolfSSL | 13:80fb167dafdf | 1616 | } else if(matched) { |
wolfSSL | 13:80fb167dafdf | 1617 | WOLFSSL_MSG("SNI did match!"); |
wolfSSL | 13:80fb167dafdf | 1618 | matchStat = WOLFSSL_SNI_REAL_MATCH; |
wolfSSL | 13:80fb167dafdf | 1619 | } else { |
wolfSSL | 13:80fb167dafdf | 1620 | WOLFSSL_MSG("fake SNI match from ANSWER_ON_MISMATCH"); |
wolfSSL | 13:80fb167dafdf | 1621 | matchStat = WOLFSSL_SNI_FAKE_MATCH; |
wolfSSL | 13:80fb167dafdf | 1622 | } |
wolfSSL | 13:80fb167dafdf | 1623 | |
wolfSSL | 13:80fb167dafdf | 1624 | TLSX_SNI_SetStatus(ssl->extensions, type, matchStat); |
wolfSSL | 13:80fb167dafdf | 1625 | |
wolfSSL | 13:80fb167dafdf | 1626 | if(!cacheOnly) |
wolfSSL | 13:80fb167dafdf | 1627 | TLSX_SetResponse(ssl, TLSX_SERVER_NAME); |
wolfSSL | 13:80fb167dafdf | 1628 | |
wolfSSL | 13:80fb167dafdf | 1629 | } else if (!(sni->options & WOLFSSL_SNI_CONTINUE_ON_MISMATCH)) { |
wolfSSL | 13:80fb167dafdf | 1630 | SendAlert(ssl, alert_fatal, unrecognized_name); |
wolfSSL | 13:80fb167dafdf | 1631 | |
wolfSSL | 13:80fb167dafdf | 1632 | return UNKNOWN_SNI_HOST_NAME_E; |
wolfSSL | 13:80fb167dafdf | 1633 | } |
wolfSSL | 13:80fb167dafdf | 1634 | break; |
wolfSSL | 13:80fb167dafdf | 1635 | } |
wolfSSL | 13:80fb167dafdf | 1636 | } |
wolfSSL | 13:80fb167dafdf | 1637 | } |
wolfSSL | 13:80fb167dafdf | 1638 | |
wolfSSL | 13:80fb167dafdf | 1639 | #endif |
wolfSSL | 13:80fb167dafdf | 1640 | |
wolfSSL | 13:80fb167dafdf | 1641 | return 0; |
wolfSSL | 13:80fb167dafdf | 1642 | } |
wolfSSL | 13:80fb167dafdf | 1643 | |
wolfSSL | 13:80fb167dafdf | 1644 | static int TLSX_SNI_VerifyParse(WOLFSSL* ssl, byte isRequest) |
wolfSSL | 13:80fb167dafdf | 1645 | { |
wolfSSL | 13:80fb167dafdf | 1646 | (void)ssl; |
wolfSSL | 13:80fb167dafdf | 1647 | |
wolfSSL | 13:80fb167dafdf | 1648 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 1649 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 1650 | TLSX* ctx_ext = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:80fb167dafdf | 1651 | TLSX* ssl_ext = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:80fb167dafdf | 1652 | SNI* ctx_sni = ctx_ext ? (SNI*)ctx_ext->data : NULL; |
wolfSSL | 13:80fb167dafdf | 1653 | SNI* ssl_sni = ssl_ext ? (SNI*)ssl_ext->data : NULL; |
wolfSSL | 13:80fb167dafdf | 1654 | SNI* sni = NULL; |
wolfSSL | 13:80fb167dafdf | 1655 | |
wolfSSL | 13:80fb167dafdf | 1656 | for (; ctx_sni; ctx_sni = ctx_sni->next) { |
wolfSSL | 13:80fb167dafdf | 1657 | if (ctx_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) { |
wolfSSL | 13:80fb167dafdf | 1658 | sni = TLSX_SNI_Find(ssl_sni, ctx_sni->type); |
wolfSSL | 13:80fb167dafdf | 1659 | |
wolfSSL | 13:80fb167dafdf | 1660 | if (sni) { |
wolfSSL | 13:80fb167dafdf | 1661 | if (sni->status != WOLFSSL_SNI_NO_MATCH) |
wolfSSL | 13:80fb167dafdf | 1662 | continue; |
wolfSSL | 13:80fb167dafdf | 1663 | |
wolfSSL | 13:80fb167dafdf | 1664 | /* if ssl level overrides ctx level, it is ok. */ |
wolfSSL | 13:80fb167dafdf | 1665 | if ((sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) == 0) |
wolfSSL | 13:80fb167dafdf | 1666 | continue; |
wolfSSL | 13:80fb167dafdf | 1667 | } |
wolfSSL | 13:80fb167dafdf | 1668 | |
wolfSSL | 13:80fb167dafdf | 1669 | SendAlert(ssl, alert_fatal, handshake_failure); |
wolfSSL | 13:80fb167dafdf | 1670 | return SNI_ABSENT_ERROR; |
wolfSSL | 13:80fb167dafdf | 1671 | } |
wolfSSL | 13:80fb167dafdf | 1672 | } |
wolfSSL | 13:80fb167dafdf | 1673 | |
wolfSSL | 13:80fb167dafdf | 1674 | for (; ssl_sni; ssl_sni = ssl_sni->next) { |
wolfSSL | 13:80fb167dafdf | 1675 | if (ssl_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) { |
wolfSSL | 13:80fb167dafdf | 1676 | if (ssl_sni->status != WOLFSSL_SNI_NO_MATCH) |
wolfSSL | 13:80fb167dafdf | 1677 | continue; |
wolfSSL | 13:80fb167dafdf | 1678 | |
wolfSSL | 13:80fb167dafdf | 1679 | SendAlert(ssl, alert_fatal, handshake_failure); |
wolfSSL | 13:80fb167dafdf | 1680 | return SNI_ABSENT_ERROR; |
wolfSSL | 13:80fb167dafdf | 1681 | } |
wolfSSL | 13:80fb167dafdf | 1682 | } |
wolfSSL | 13:80fb167dafdf | 1683 | #endif /* NO_WOLFSSL_SERVER */ |
wolfSSL | 13:80fb167dafdf | 1684 | } |
wolfSSL | 13:80fb167dafdf | 1685 | |
wolfSSL | 13:80fb167dafdf | 1686 | return 0; |
wolfSSL | 13:80fb167dafdf | 1687 | } |
wolfSSL | 13:80fb167dafdf | 1688 | |
wolfSSL | 13:80fb167dafdf | 1689 | int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size, |
wolfSSL | 13:80fb167dafdf | 1690 | void* heap) |
wolfSSL | 13:80fb167dafdf | 1691 | { |
wolfSSL | 13:80fb167dafdf | 1692 | TLSX* extension; |
wolfSSL | 13:80fb167dafdf | 1693 | SNI* sni = NULL; |
wolfSSL | 13:80fb167dafdf | 1694 | |
wolfSSL | 13:80fb167dafdf | 1695 | if (extensions == NULL || data == NULL) |
wolfSSL | 13:80fb167dafdf | 1696 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 1697 | |
wolfSSL | 13:80fb167dafdf | 1698 | if ((sni = TLSX_SNI_New(type, data, size, heap)) == NULL) |
wolfSSL | 13:80fb167dafdf | 1699 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 1700 | |
wolfSSL | 13:80fb167dafdf | 1701 | extension = TLSX_Find(*extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:80fb167dafdf | 1702 | if (!extension) { |
wolfSSL | 13:80fb167dafdf | 1703 | int ret = TLSX_Push(extensions, TLSX_SERVER_NAME, (void*)sni, heap); |
wolfSSL | 13:80fb167dafdf | 1704 | if (ret != 0) { |
wolfSSL | 13:80fb167dafdf | 1705 | TLSX_SNI_Free(sni, heap); |
wolfSSL | 13:80fb167dafdf | 1706 | return ret; |
wolfSSL | 13:80fb167dafdf | 1707 | } |
wolfSSL | 13:80fb167dafdf | 1708 | } |
wolfSSL | 13:80fb167dafdf | 1709 | else { |
wolfSSL | 13:80fb167dafdf | 1710 | /* push new SNI object to extension data. */ |
wolfSSL | 13:80fb167dafdf | 1711 | sni->next = (SNI*)extension->data; |
wolfSSL | 13:80fb167dafdf | 1712 | extension->data = (void*)sni; |
wolfSSL | 13:80fb167dafdf | 1713 | |
wolfSSL | 13:80fb167dafdf | 1714 | /* remove duplicate SNI, there should be only one of each type. */ |
wolfSSL | 13:80fb167dafdf | 1715 | do { |
wolfSSL | 13:80fb167dafdf | 1716 | if (sni->next && sni->next->type == type) { |
wolfSSL | 13:80fb167dafdf | 1717 | SNI *next = sni->next; |
wolfSSL | 13:80fb167dafdf | 1718 | |
wolfSSL | 13:80fb167dafdf | 1719 | sni->next = next->next; |
wolfSSL | 13:80fb167dafdf | 1720 | TLSX_SNI_Free(next, heap); |
wolfSSL | 13:80fb167dafdf | 1721 | |
wolfSSL | 13:80fb167dafdf | 1722 | /* there is no way to occur more than */ |
wolfSSL | 13:80fb167dafdf | 1723 | /* two SNIs of the same type. */ |
wolfSSL | 13:80fb167dafdf | 1724 | break; |
wolfSSL | 13:80fb167dafdf | 1725 | } |
wolfSSL | 13:80fb167dafdf | 1726 | } while ((sni = sni->next)); |
wolfSSL | 13:80fb167dafdf | 1727 | } |
wolfSSL | 13:80fb167dafdf | 1728 | |
wolfSSL | 13:80fb167dafdf | 1729 | return SSL_SUCCESS; |
wolfSSL | 13:80fb167dafdf | 1730 | } |
wolfSSL | 13:80fb167dafdf | 1731 | |
wolfSSL | 13:80fb167dafdf | 1732 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 1733 | |
wolfSSL | 13:80fb167dafdf | 1734 | /** Tells the SNI requested by the client. */ |
wolfSSL | 13:80fb167dafdf | 1735 | word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data) |
wolfSSL | 13:80fb167dafdf | 1736 | { |
wolfSSL | 13:80fb167dafdf | 1737 | TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:80fb167dafdf | 1738 | SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type); |
wolfSSL | 13:80fb167dafdf | 1739 | |
wolfSSL | 13:80fb167dafdf | 1740 | if (sni && sni->status != WOLFSSL_SNI_NO_MATCH) { |
wolfSSL | 13:80fb167dafdf | 1741 | switch (sni->type) { |
wolfSSL | 13:80fb167dafdf | 1742 | case WOLFSSL_SNI_HOST_NAME: |
wolfSSL | 13:80fb167dafdf | 1743 | if (data) { |
wolfSSL | 13:80fb167dafdf | 1744 | *data = sni->data.host_name; |
wolfSSL | 13:80fb167dafdf | 1745 | return (word16)XSTRLEN((char*)*data); |
wolfSSL | 13:80fb167dafdf | 1746 | } |
wolfSSL | 13:80fb167dafdf | 1747 | } |
wolfSSL | 13:80fb167dafdf | 1748 | } |
wolfSSL | 13:80fb167dafdf | 1749 | |
wolfSSL | 13:80fb167dafdf | 1750 | return 0; |
wolfSSL | 13:80fb167dafdf | 1751 | } |
wolfSSL | 13:80fb167dafdf | 1752 | |
wolfSSL | 13:80fb167dafdf | 1753 | /** Sets the options for a SNI object. */ |
wolfSSL | 13:80fb167dafdf | 1754 | void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options) |
wolfSSL | 13:80fb167dafdf | 1755 | { |
wolfSSL | 13:80fb167dafdf | 1756 | TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME); |
wolfSSL | 13:80fb167dafdf | 1757 | SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type); |
wolfSSL | 13:80fb167dafdf | 1758 | |
wolfSSL | 13:80fb167dafdf | 1759 | if (sni) |
wolfSSL | 13:80fb167dafdf | 1760 | sni->options = options; |
wolfSSL | 13:80fb167dafdf | 1761 | } |
wolfSSL | 13:80fb167dafdf | 1762 | |
wolfSSL | 13:80fb167dafdf | 1763 | /** Retrieves a SNI request from a client hello buffer. */ |
wolfSSL | 13:80fb167dafdf | 1764 | int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, |
wolfSSL | 13:80fb167dafdf | 1765 | byte type, byte* sni, word32* inOutSz) |
wolfSSL | 13:80fb167dafdf | 1766 | { |
wolfSSL | 13:80fb167dafdf | 1767 | word32 offset = 0; |
wolfSSL | 13:80fb167dafdf | 1768 | word32 len32 = 0; |
wolfSSL | 13:80fb167dafdf | 1769 | word16 len16 = 0; |
wolfSSL | 13:80fb167dafdf | 1770 | |
wolfSSL | 13:80fb167dafdf | 1771 | if (helloSz < RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + CLIENT_HELLO_FIRST) |
wolfSSL | 13:80fb167dafdf | 1772 | return INCOMPLETE_DATA; |
wolfSSL | 13:80fb167dafdf | 1773 | |
wolfSSL | 13:80fb167dafdf | 1774 | /* TLS record header */ |
wolfSSL | 13:80fb167dafdf | 1775 | if ((enum ContentType) clientHello[offset++] != handshake) { |
wolfSSL | 13:80fb167dafdf | 1776 | |
wolfSSL | 13:80fb167dafdf | 1777 | /* checking for SSLv2.0 client hello according to: */ |
wolfSSL | 13:80fb167dafdf | 1778 | /* http://tools.ietf.org/html/rfc4346#appendix-E.1 */ |
wolfSSL | 13:80fb167dafdf | 1779 | if ((enum HandShakeType) clientHello[++offset] == client_hello) { |
wolfSSL | 13:80fb167dafdf | 1780 | offset += ENUM_LEN + VERSION_SZ; /* skip version */ |
wolfSSL | 13:80fb167dafdf | 1781 | |
wolfSSL | 13:80fb167dafdf | 1782 | ato16(clientHello + offset, &len16); |
wolfSSL | 13:80fb167dafdf | 1783 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 1784 | |
wolfSSL | 13:80fb167dafdf | 1785 | if (len16 % 3) /* cipher_spec_length must be multiple of 3 */ |
wolfSSL | 13:80fb167dafdf | 1786 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1787 | |
wolfSSL | 13:80fb167dafdf | 1788 | ato16(clientHello + offset, &len16); |
wolfSSL | 13:80fb167dafdf | 1789 | /* Returning SNI_UNSUPPORTED do not increment offset here */ |
wolfSSL | 13:80fb167dafdf | 1790 | |
wolfSSL | 13:80fb167dafdf | 1791 | if (len16 != 0) /* session_id_length must be 0 */ |
wolfSSL | 13:80fb167dafdf | 1792 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1793 | |
wolfSSL | 13:80fb167dafdf | 1794 | return SNI_UNSUPPORTED; |
wolfSSL | 13:80fb167dafdf | 1795 | } |
wolfSSL | 13:80fb167dafdf | 1796 | |
wolfSSL | 13:80fb167dafdf | 1797 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1798 | } |
wolfSSL | 13:80fb167dafdf | 1799 | |
wolfSSL | 13:80fb167dafdf | 1800 | if (clientHello[offset++] != SSLv3_MAJOR) |
wolfSSL | 13:80fb167dafdf | 1801 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1802 | |
wolfSSL | 13:80fb167dafdf | 1803 | if (clientHello[offset++] < TLSv1_MINOR) |
wolfSSL | 13:80fb167dafdf | 1804 | return SNI_UNSUPPORTED; |
wolfSSL | 13:80fb167dafdf | 1805 | |
wolfSSL | 13:80fb167dafdf | 1806 | ato16(clientHello + offset, &len16); |
wolfSSL | 13:80fb167dafdf | 1807 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 1808 | |
wolfSSL | 13:80fb167dafdf | 1809 | if (offset + len16 > helloSz) |
wolfSSL | 13:80fb167dafdf | 1810 | return INCOMPLETE_DATA; |
wolfSSL | 13:80fb167dafdf | 1811 | |
wolfSSL | 13:80fb167dafdf | 1812 | /* Handshake header */ |
wolfSSL | 13:80fb167dafdf | 1813 | if ((enum HandShakeType) clientHello[offset] != client_hello) |
wolfSSL | 13:80fb167dafdf | 1814 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1815 | |
wolfSSL | 13:80fb167dafdf | 1816 | c24to32(clientHello + offset + 1, &len32); |
wolfSSL | 13:80fb167dafdf | 1817 | offset += HANDSHAKE_HEADER_SZ; |
wolfSSL | 13:80fb167dafdf | 1818 | |
wolfSSL | 13:80fb167dafdf | 1819 | if (offset + len32 > helloSz) |
wolfSSL | 13:80fb167dafdf | 1820 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1821 | |
wolfSSL | 13:80fb167dafdf | 1822 | /* client hello */ |
wolfSSL | 13:80fb167dafdf | 1823 | offset += VERSION_SZ + RAN_LEN; /* version, random */ |
wolfSSL | 13:80fb167dafdf | 1824 | |
wolfSSL | 13:80fb167dafdf | 1825 | if (helloSz < offset + clientHello[offset]) |
wolfSSL | 13:80fb167dafdf | 1826 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1827 | |
wolfSSL | 13:80fb167dafdf | 1828 | offset += ENUM_LEN + clientHello[offset]; /* skip session id */ |
wolfSSL | 13:80fb167dafdf | 1829 | |
wolfSSL | 13:80fb167dafdf | 1830 | /* cypher suites */ |
wolfSSL | 13:80fb167dafdf | 1831 | if (helloSz < offset + OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 1832 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1833 | |
wolfSSL | 13:80fb167dafdf | 1834 | ato16(clientHello + offset, &len16); |
wolfSSL | 13:80fb167dafdf | 1835 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 1836 | |
wolfSSL | 13:80fb167dafdf | 1837 | if (helloSz < offset + len16) |
wolfSSL | 13:80fb167dafdf | 1838 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1839 | |
wolfSSL | 13:80fb167dafdf | 1840 | offset += len16; /* skip cypher suites */ |
wolfSSL | 13:80fb167dafdf | 1841 | |
wolfSSL | 13:80fb167dafdf | 1842 | /* compression methods */ |
wolfSSL | 13:80fb167dafdf | 1843 | if (helloSz < offset + 1) |
wolfSSL | 13:80fb167dafdf | 1844 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1845 | |
wolfSSL | 13:80fb167dafdf | 1846 | if (helloSz < offset + clientHello[offset]) |
wolfSSL | 13:80fb167dafdf | 1847 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1848 | |
wolfSSL | 13:80fb167dafdf | 1849 | offset += ENUM_LEN + clientHello[offset]; /* skip compression methods */ |
wolfSSL | 13:80fb167dafdf | 1850 | |
wolfSSL | 13:80fb167dafdf | 1851 | /* extensions */ |
wolfSSL | 13:80fb167dafdf | 1852 | if (helloSz < offset + OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 1853 | return 0; /* no extensions in client hello. */ |
wolfSSL | 13:80fb167dafdf | 1854 | |
wolfSSL | 13:80fb167dafdf | 1855 | ato16(clientHello + offset, &len16); |
wolfSSL | 13:80fb167dafdf | 1856 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 1857 | |
wolfSSL | 13:80fb167dafdf | 1858 | if (helloSz < offset + len16) |
wolfSSL | 13:80fb167dafdf | 1859 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1860 | |
wolfSSL | 13:80fb167dafdf | 1861 | while (len16 >= OPAQUE16_LEN + OPAQUE16_LEN) { |
wolfSSL | 13:80fb167dafdf | 1862 | word16 extType; |
wolfSSL | 13:80fb167dafdf | 1863 | word16 extLen; |
wolfSSL | 13:80fb167dafdf | 1864 | |
wolfSSL | 13:80fb167dafdf | 1865 | ato16(clientHello + offset, &extType); |
wolfSSL | 13:80fb167dafdf | 1866 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 1867 | |
wolfSSL | 13:80fb167dafdf | 1868 | ato16(clientHello + offset, &extLen); |
wolfSSL | 13:80fb167dafdf | 1869 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 1870 | |
wolfSSL | 13:80fb167dafdf | 1871 | if (helloSz < offset + extLen) |
wolfSSL | 13:80fb167dafdf | 1872 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1873 | |
wolfSSL | 13:80fb167dafdf | 1874 | if (extType != TLSX_SERVER_NAME) { |
wolfSSL | 13:80fb167dafdf | 1875 | offset += extLen; /* skip extension */ |
wolfSSL | 13:80fb167dafdf | 1876 | } else { |
wolfSSL | 13:80fb167dafdf | 1877 | word16 listLen; |
wolfSSL | 13:80fb167dafdf | 1878 | |
wolfSSL | 13:80fb167dafdf | 1879 | ato16(clientHello + offset, &listLen); |
wolfSSL | 13:80fb167dafdf | 1880 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 1881 | |
wolfSSL | 13:80fb167dafdf | 1882 | if (helloSz < offset + listLen) |
wolfSSL | 13:80fb167dafdf | 1883 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1884 | |
wolfSSL | 13:80fb167dafdf | 1885 | while (listLen > ENUM_LEN + OPAQUE16_LEN) { |
wolfSSL | 13:80fb167dafdf | 1886 | byte sniType = clientHello[offset++]; |
wolfSSL | 13:80fb167dafdf | 1887 | word16 sniLen; |
wolfSSL | 13:80fb167dafdf | 1888 | |
wolfSSL | 13:80fb167dafdf | 1889 | ato16(clientHello + offset, &sniLen); |
wolfSSL | 13:80fb167dafdf | 1890 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 1891 | |
wolfSSL | 13:80fb167dafdf | 1892 | if (helloSz < offset + sniLen) |
wolfSSL | 13:80fb167dafdf | 1893 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1894 | |
wolfSSL | 13:80fb167dafdf | 1895 | if (sniType != type) { |
wolfSSL | 13:80fb167dafdf | 1896 | offset += sniLen; |
wolfSSL | 13:80fb167dafdf | 1897 | listLen -= min(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen); |
wolfSSL | 13:80fb167dafdf | 1898 | continue; |
wolfSSL | 13:80fb167dafdf | 1899 | } |
wolfSSL | 13:80fb167dafdf | 1900 | |
wolfSSL | 13:80fb167dafdf | 1901 | *inOutSz = min(sniLen, *inOutSz); |
wolfSSL | 13:80fb167dafdf | 1902 | XMEMCPY(sni, clientHello + offset, *inOutSz); |
wolfSSL | 13:80fb167dafdf | 1903 | |
wolfSSL | 13:80fb167dafdf | 1904 | return SSL_SUCCESS; |
wolfSSL | 13:80fb167dafdf | 1905 | } |
wolfSSL | 13:80fb167dafdf | 1906 | } |
wolfSSL | 13:80fb167dafdf | 1907 | |
wolfSSL | 13:80fb167dafdf | 1908 | len16 -= min(2 * OPAQUE16_LEN + extLen, len16); |
wolfSSL | 13:80fb167dafdf | 1909 | } |
wolfSSL | 13:80fb167dafdf | 1910 | |
wolfSSL | 13:80fb167dafdf | 1911 | return len16 ? BUFFER_ERROR : 0; |
wolfSSL | 13:80fb167dafdf | 1912 | } |
wolfSSL | 13:80fb167dafdf | 1913 | |
wolfSSL | 13:80fb167dafdf | 1914 | #endif |
wolfSSL | 13:80fb167dafdf | 1915 | |
wolfSSL | 13:80fb167dafdf | 1916 | #define SNI_FREE_ALL TLSX_SNI_FreeAll |
wolfSSL | 13:80fb167dafdf | 1917 | #define SNI_GET_SIZE TLSX_SNI_GetSize |
wolfSSL | 13:80fb167dafdf | 1918 | #define SNI_WRITE TLSX_SNI_Write |
wolfSSL | 13:80fb167dafdf | 1919 | #define SNI_PARSE TLSX_SNI_Parse |
wolfSSL | 13:80fb167dafdf | 1920 | #define SNI_VERIFY_PARSE TLSX_SNI_VerifyParse |
wolfSSL | 13:80fb167dafdf | 1921 | |
wolfSSL | 13:80fb167dafdf | 1922 | #else |
wolfSSL | 13:80fb167dafdf | 1923 | |
wolfSSL | 13:80fb167dafdf | 1924 | #define SNI_FREE_ALL(list, heap) |
wolfSSL | 13:80fb167dafdf | 1925 | #define SNI_GET_SIZE(list) 0 |
wolfSSL | 13:80fb167dafdf | 1926 | #define SNI_WRITE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 1927 | #define SNI_PARSE(a, b, c, d) 0 |
wolfSSL | 13:80fb167dafdf | 1928 | #define SNI_VERIFY_PARSE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 1929 | |
wolfSSL | 13:80fb167dafdf | 1930 | #endif /* HAVE_SNI */ |
wolfSSL | 13:80fb167dafdf | 1931 | |
wolfSSL | 13:80fb167dafdf | 1932 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 1933 | /* Max Fragment Length Negotiation */ |
wolfSSL | 13:80fb167dafdf | 1934 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 1935 | |
wolfSSL | 13:80fb167dafdf | 1936 | #ifdef HAVE_MAX_FRAGMENT |
wolfSSL | 13:80fb167dafdf | 1937 | |
wolfSSL | 13:80fb167dafdf | 1938 | static word16 TLSX_MFL_Write(byte* data, byte* output) |
wolfSSL | 13:80fb167dafdf | 1939 | { |
wolfSSL | 13:80fb167dafdf | 1940 | output[0] = data[0]; |
wolfSSL | 13:80fb167dafdf | 1941 | |
wolfSSL | 13:80fb167dafdf | 1942 | return ENUM_LEN; |
wolfSSL | 13:80fb167dafdf | 1943 | } |
wolfSSL | 13:80fb167dafdf | 1944 | |
wolfSSL | 13:80fb167dafdf | 1945 | static int TLSX_MFL_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:80fb167dafdf | 1946 | byte isRequest) |
wolfSSL | 13:80fb167dafdf | 1947 | { |
wolfSSL | 13:80fb167dafdf | 1948 | (void)isRequest; |
wolfSSL | 13:80fb167dafdf | 1949 | |
wolfSSL | 13:80fb167dafdf | 1950 | if (length != ENUM_LEN) |
wolfSSL | 13:80fb167dafdf | 1951 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 1952 | |
wolfSSL | 13:80fb167dafdf | 1953 | switch (*input) { |
wolfSSL | 13:80fb167dafdf | 1954 | case WOLFSSL_MFL_2_9 : ssl->max_fragment = 512; break; |
wolfSSL | 13:80fb167dafdf | 1955 | case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break; |
wolfSSL | 13:80fb167dafdf | 1956 | case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break; |
wolfSSL | 13:80fb167dafdf | 1957 | case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break; |
wolfSSL | 13:80fb167dafdf | 1958 | case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break; |
wolfSSL | 13:80fb167dafdf | 1959 | |
wolfSSL | 13:80fb167dafdf | 1960 | default: |
wolfSSL | 13:80fb167dafdf | 1961 | SendAlert(ssl, alert_fatal, illegal_parameter); |
wolfSSL | 13:80fb167dafdf | 1962 | |
wolfSSL | 13:80fb167dafdf | 1963 | return UNKNOWN_MAX_FRAG_LEN_E; |
wolfSSL | 13:80fb167dafdf | 1964 | } |
wolfSSL | 13:80fb167dafdf | 1965 | |
wolfSSL | 13:80fb167dafdf | 1966 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 1967 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 1968 | int r = TLSX_UseMaxFragment(&ssl->extensions, *input, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 1969 | |
wolfSSL | 13:80fb167dafdf | 1970 | if (r != SSL_SUCCESS) return r; /* throw error */ |
wolfSSL | 13:80fb167dafdf | 1971 | |
wolfSSL | 13:80fb167dafdf | 1972 | TLSX_SetResponse(ssl, TLSX_MAX_FRAGMENT_LENGTH); |
wolfSSL | 13:80fb167dafdf | 1973 | } |
wolfSSL | 13:80fb167dafdf | 1974 | #endif |
wolfSSL | 13:80fb167dafdf | 1975 | |
wolfSSL | 13:80fb167dafdf | 1976 | return 0; |
wolfSSL | 13:80fb167dafdf | 1977 | } |
wolfSSL | 13:80fb167dafdf | 1978 | |
wolfSSL | 13:80fb167dafdf | 1979 | int TLSX_UseMaxFragment(TLSX** extensions, byte mfl, void* heap) |
wolfSSL | 13:80fb167dafdf | 1980 | { |
wolfSSL | 13:80fb167dafdf | 1981 | byte* data = NULL; |
wolfSSL | 13:80fb167dafdf | 1982 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 1983 | |
wolfSSL | 13:80fb167dafdf | 1984 | if (extensions == NULL) |
wolfSSL | 13:80fb167dafdf | 1985 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 1986 | |
wolfSSL | 13:80fb167dafdf | 1987 | if (mfl < WOLFSSL_MFL_2_9 || WOLFSSL_MFL_2_13 < mfl) |
wolfSSL | 13:80fb167dafdf | 1988 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 1989 | |
wolfSSL | 13:80fb167dafdf | 1990 | if ((data = (byte*)XMALLOC(ENUM_LEN, heap, DYNAMIC_TYPE_TLSX)) == NULL) |
wolfSSL | 13:80fb167dafdf | 1991 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 1992 | |
wolfSSL | 13:80fb167dafdf | 1993 | data[0] = mfl; |
wolfSSL | 13:80fb167dafdf | 1994 | |
wolfSSL | 13:80fb167dafdf | 1995 | /* push new MFL extension. */ |
wolfSSL | 13:80fb167dafdf | 1996 | if ((ret = TLSX_Push(extensions, TLSX_MAX_FRAGMENT_LENGTH, data, heap)) |
wolfSSL | 13:80fb167dafdf | 1997 | != 0) { |
wolfSSL | 13:80fb167dafdf | 1998 | XFREE(data, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 1999 | return ret; |
wolfSSL | 13:80fb167dafdf | 2000 | } |
wolfSSL | 13:80fb167dafdf | 2001 | |
wolfSSL | 13:80fb167dafdf | 2002 | return SSL_SUCCESS; |
wolfSSL | 13:80fb167dafdf | 2003 | } |
wolfSSL | 13:80fb167dafdf | 2004 | |
wolfSSL | 13:80fb167dafdf | 2005 | |
wolfSSL | 13:80fb167dafdf | 2006 | #define MFL_FREE_ALL(data, heap) XFREE(data, (heap), DYNAMIC_TYPE_TLSX) |
wolfSSL | 13:80fb167dafdf | 2007 | #define MFL_GET_SIZE(data) ENUM_LEN |
wolfSSL | 13:80fb167dafdf | 2008 | #define MFL_WRITE TLSX_MFL_Write |
wolfSSL | 13:80fb167dafdf | 2009 | #define MFL_PARSE TLSX_MFL_Parse |
wolfSSL | 13:80fb167dafdf | 2010 | |
wolfSSL | 13:80fb167dafdf | 2011 | #else |
wolfSSL | 13:80fb167dafdf | 2012 | |
wolfSSL | 13:80fb167dafdf | 2013 | #define MFL_FREE_ALL(a, b) |
wolfSSL | 13:80fb167dafdf | 2014 | #define MFL_GET_SIZE(a) 0 |
wolfSSL | 13:80fb167dafdf | 2015 | #define MFL_WRITE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 2016 | #define MFL_PARSE(a, b, c, d) 0 |
wolfSSL | 13:80fb167dafdf | 2017 | |
wolfSSL | 13:80fb167dafdf | 2018 | #endif /* HAVE_MAX_FRAGMENT */ |
wolfSSL | 13:80fb167dafdf | 2019 | |
wolfSSL | 13:80fb167dafdf | 2020 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 2021 | /* Truncated HMAC */ |
wolfSSL | 13:80fb167dafdf | 2022 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 2023 | |
wolfSSL | 13:80fb167dafdf | 2024 | #ifdef HAVE_TRUNCATED_HMAC |
wolfSSL | 13:80fb167dafdf | 2025 | |
wolfSSL | 13:80fb167dafdf | 2026 | static int TLSX_THM_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:80fb167dafdf | 2027 | byte isRequest) |
wolfSSL | 13:80fb167dafdf | 2028 | { |
wolfSSL | 13:80fb167dafdf | 2029 | (void)isRequest; |
wolfSSL | 13:80fb167dafdf | 2030 | |
wolfSSL | 13:80fb167dafdf | 2031 | if (length != 0 || input == NULL) |
wolfSSL | 13:80fb167dafdf | 2032 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 2033 | |
wolfSSL | 13:80fb167dafdf | 2034 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 2035 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 2036 | int r = TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 2037 | |
wolfSSL | 13:80fb167dafdf | 2038 | if (r != SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 2039 | return r; /* throw error */ |
wolfSSL | 13:80fb167dafdf | 2040 | |
wolfSSL | 13:80fb167dafdf | 2041 | TLSX_SetResponse(ssl, TLSX_TRUNCATED_HMAC); |
wolfSSL | 13:80fb167dafdf | 2042 | } |
wolfSSL | 13:80fb167dafdf | 2043 | #endif |
wolfSSL | 13:80fb167dafdf | 2044 | |
wolfSSL | 13:80fb167dafdf | 2045 | ssl->truncated_hmac = 1; |
wolfSSL | 13:80fb167dafdf | 2046 | |
wolfSSL | 13:80fb167dafdf | 2047 | return 0; |
wolfSSL | 13:80fb167dafdf | 2048 | } |
wolfSSL | 13:80fb167dafdf | 2049 | |
wolfSSL | 13:80fb167dafdf | 2050 | int TLSX_UseTruncatedHMAC(TLSX** extensions, void* heap) |
wolfSSL | 13:80fb167dafdf | 2051 | { |
wolfSSL | 13:80fb167dafdf | 2052 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 2053 | |
wolfSSL | 13:80fb167dafdf | 2054 | if (extensions == NULL) |
wolfSSL | 13:80fb167dafdf | 2055 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 2056 | |
wolfSSL | 13:80fb167dafdf | 2057 | if ((ret = TLSX_Push(extensions, TLSX_TRUNCATED_HMAC, NULL, heap)) != 0) |
wolfSSL | 13:80fb167dafdf | 2058 | return ret; |
wolfSSL | 13:80fb167dafdf | 2059 | |
wolfSSL | 13:80fb167dafdf | 2060 | return SSL_SUCCESS; |
wolfSSL | 13:80fb167dafdf | 2061 | } |
wolfSSL | 13:80fb167dafdf | 2062 | |
wolfSSL | 13:80fb167dafdf | 2063 | #define THM_PARSE TLSX_THM_Parse |
wolfSSL | 13:80fb167dafdf | 2064 | |
wolfSSL | 13:80fb167dafdf | 2065 | #else |
wolfSSL | 13:80fb167dafdf | 2066 | |
wolfSSL | 13:80fb167dafdf | 2067 | #define THM_PARSE(a, b, c, d) 0 |
wolfSSL | 13:80fb167dafdf | 2068 | |
wolfSSL | 13:80fb167dafdf | 2069 | #endif /* HAVE_TRUNCATED_HMAC */ |
wolfSSL | 13:80fb167dafdf | 2070 | |
wolfSSL | 13:80fb167dafdf | 2071 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 2072 | /* Certificate Status Request */ |
wolfSSL | 13:80fb167dafdf | 2073 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 2074 | |
wolfSSL | 13:80fb167dafdf | 2075 | #ifdef HAVE_CERTIFICATE_STATUS_REQUEST |
wolfSSL | 13:80fb167dafdf | 2076 | |
wolfSSL | 13:80fb167dafdf | 2077 | static void TLSX_CSR_Free(CertificateStatusRequest* csr, void* heap) |
wolfSSL | 13:80fb167dafdf | 2078 | { |
wolfSSL | 13:80fb167dafdf | 2079 | switch (csr->status_type) { |
wolfSSL | 13:80fb167dafdf | 2080 | case WOLFSSL_CSR_OCSP: |
wolfSSL | 13:80fb167dafdf | 2081 | FreeOcspRequest(&csr->request.ocsp); |
wolfSSL | 13:80fb167dafdf | 2082 | break; |
wolfSSL | 13:80fb167dafdf | 2083 | } |
wolfSSL | 13:80fb167dafdf | 2084 | |
wolfSSL | 13:80fb167dafdf | 2085 | XFREE(csr, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 2086 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 2087 | } |
wolfSSL | 13:80fb167dafdf | 2088 | |
wolfSSL | 13:80fb167dafdf | 2089 | static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest) |
wolfSSL | 13:80fb167dafdf | 2090 | { |
wolfSSL | 13:80fb167dafdf | 2091 | word16 size = 0; |
wolfSSL | 13:80fb167dafdf | 2092 | |
wolfSSL | 13:80fb167dafdf | 2093 | /* shut up compiler warnings */ |
wolfSSL | 13:80fb167dafdf | 2094 | (void) csr; (void) isRequest; |
wolfSSL | 13:80fb167dafdf | 2095 | |
wolfSSL | 13:80fb167dafdf | 2096 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:80fb167dafdf | 2097 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 2098 | switch (csr->status_type) { |
wolfSSL | 13:80fb167dafdf | 2099 | case WOLFSSL_CSR_OCSP: |
wolfSSL | 13:80fb167dafdf | 2100 | size += ENUM_LEN + 2 * OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 2101 | |
wolfSSL | 13:80fb167dafdf | 2102 | if (csr->request.ocsp.nonceSz) |
wolfSSL | 13:80fb167dafdf | 2103 | size += OCSP_NONCE_EXT_SZ; |
wolfSSL | 13:80fb167dafdf | 2104 | break; |
wolfSSL | 13:80fb167dafdf | 2105 | } |
wolfSSL | 13:80fb167dafdf | 2106 | } |
wolfSSL | 13:80fb167dafdf | 2107 | #endif |
wolfSSL | 13:80fb167dafdf | 2108 | |
wolfSSL | 13:80fb167dafdf | 2109 | return size; |
wolfSSL | 13:80fb167dafdf | 2110 | } |
wolfSSL | 13:80fb167dafdf | 2111 | |
wolfSSL | 13:80fb167dafdf | 2112 | static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output, |
wolfSSL | 13:80fb167dafdf | 2113 | byte isRequest) |
wolfSSL | 13:80fb167dafdf | 2114 | { |
wolfSSL | 13:80fb167dafdf | 2115 | /* shut up compiler warnings */ |
wolfSSL | 13:80fb167dafdf | 2116 | (void) csr; (void) output; (void) isRequest; |
wolfSSL | 13:80fb167dafdf | 2117 | |
wolfSSL | 13:80fb167dafdf | 2118 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:80fb167dafdf | 2119 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 2120 | word16 offset = 0; |
wolfSSL | 13:80fb167dafdf | 2121 | word16 length = 0; |
wolfSSL | 13:80fb167dafdf | 2122 | |
wolfSSL | 13:80fb167dafdf | 2123 | /* type */ |
wolfSSL | 13:80fb167dafdf | 2124 | output[offset++] = csr->status_type; |
wolfSSL | 13:80fb167dafdf | 2125 | |
wolfSSL | 13:80fb167dafdf | 2126 | switch (csr->status_type) { |
wolfSSL | 13:80fb167dafdf | 2127 | case WOLFSSL_CSR_OCSP: |
wolfSSL | 13:80fb167dafdf | 2128 | /* responder id list */ |
wolfSSL | 13:80fb167dafdf | 2129 | c16toa(0, output + offset); |
wolfSSL | 13:80fb167dafdf | 2130 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 2131 | |
wolfSSL | 13:80fb167dafdf | 2132 | /* request extensions */ |
wolfSSL | 13:80fb167dafdf | 2133 | if (csr->request.ocsp.nonceSz) |
wolfSSL | 13:80fb167dafdf | 2134 | length = (word16)EncodeOcspRequestExtensions( |
wolfSSL | 13:80fb167dafdf | 2135 | &csr->request.ocsp, |
wolfSSL | 13:80fb167dafdf | 2136 | output + offset + OPAQUE16_LEN, |
wolfSSL | 13:80fb167dafdf | 2137 | OCSP_NONCE_EXT_SZ); |
wolfSSL | 13:80fb167dafdf | 2138 | |
wolfSSL | 13:80fb167dafdf | 2139 | c16toa(length, output + offset); |
wolfSSL | 13:80fb167dafdf | 2140 | offset += OPAQUE16_LEN + length; |
wolfSSL | 13:80fb167dafdf | 2141 | |
wolfSSL | 13:80fb167dafdf | 2142 | break; |
wolfSSL | 13:80fb167dafdf | 2143 | } |
wolfSSL | 13:80fb167dafdf | 2144 | |
wolfSSL | 13:80fb167dafdf | 2145 | return offset; |
wolfSSL | 13:80fb167dafdf | 2146 | } |
wolfSSL | 13:80fb167dafdf | 2147 | #endif |
wolfSSL | 13:80fb167dafdf | 2148 | |
wolfSSL | 13:80fb167dafdf | 2149 | return 0; |
wolfSSL | 13:80fb167dafdf | 2150 | } |
wolfSSL | 13:80fb167dafdf | 2151 | |
wolfSSL | 13:80fb167dafdf | 2152 | static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:80fb167dafdf | 2153 | byte isRequest) |
wolfSSL | 13:80fb167dafdf | 2154 | { |
wolfSSL | 13:80fb167dafdf | 2155 | int ret; |
wolfSSL | 13:80fb167dafdf | 2156 | |
wolfSSL | 13:80fb167dafdf | 2157 | /* shut up compiler warnings */ |
wolfSSL | 13:80fb167dafdf | 2158 | (void) ssl; (void) input; |
wolfSSL | 13:80fb167dafdf | 2159 | |
wolfSSL | 13:80fb167dafdf | 2160 | if (!isRequest) { |
wolfSSL | 13:80fb167dafdf | 2161 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:80fb167dafdf | 2162 | TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST); |
wolfSSL | 13:80fb167dafdf | 2163 | CertificateStatusRequest* csr = extension ? |
wolfSSL | 13:80fb167dafdf | 2164 | (CertificateStatusRequest*)extension->data : NULL; |
wolfSSL | 13:80fb167dafdf | 2165 | |
wolfSSL | 13:80fb167dafdf | 2166 | if (!csr) { |
wolfSSL | 13:80fb167dafdf | 2167 | /* look at context level */ |
wolfSSL | 13:80fb167dafdf | 2168 | extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST); |
wolfSSL | 13:80fb167dafdf | 2169 | csr = extension ? (CertificateStatusRequest*)extension->data : NULL; |
wolfSSL | 13:80fb167dafdf | 2170 | |
wolfSSL | 13:80fb167dafdf | 2171 | if (!csr) |
wolfSSL | 13:80fb167dafdf | 2172 | return BUFFER_ERROR; /* unexpected extension */ |
wolfSSL | 13:80fb167dafdf | 2173 | |
wolfSSL | 13:80fb167dafdf | 2174 | /* enable extension at ssl level */ |
wolfSSL | 13:80fb167dafdf | 2175 | ret = TLSX_UseCertificateStatusRequest(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 2176 | csr->status_type, csr->options, ssl->heap, |
wolfSSL | 13:80fb167dafdf | 2177 | ssl->devId); |
wolfSSL | 13:80fb167dafdf | 2178 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 2179 | return ret; |
wolfSSL | 13:80fb167dafdf | 2180 | |
wolfSSL | 13:80fb167dafdf | 2181 | switch (csr->status_type) { |
wolfSSL | 13:80fb167dafdf | 2182 | case WOLFSSL_CSR_OCSP: |
wolfSSL | 13:80fb167dafdf | 2183 | /* propagate nonce */ |
wolfSSL | 13:80fb167dafdf | 2184 | if (csr->request.ocsp.nonceSz) { |
wolfSSL | 13:80fb167dafdf | 2185 | OcspRequest* request = |
wolfSSL | 13:80fb167dafdf | 2186 | (OcspRequest*)TLSX_CSR_GetRequest(ssl->extensions); |
wolfSSL | 13:80fb167dafdf | 2187 | |
wolfSSL | 13:80fb167dafdf | 2188 | if (request) { |
wolfSSL | 13:80fb167dafdf | 2189 | XMEMCPY(request->nonce, csr->request.ocsp.nonce, |
wolfSSL | 13:80fb167dafdf | 2190 | csr->request.ocsp.nonceSz); |
wolfSSL | 13:80fb167dafdf | 2191 | request->nonceSz = csr->request.ocsp.nonceSz; |
wolfSSL | 13:80fb167dafdf | 2192 | } |
wolfSSL | 13:80fb167dafdf | 2193 | } |
wolfSSL | 13:80fb167dafdf | 2194 | break; |
wolfSSL | 13:80fb167dafdf | 2195 | } |
wolfSSL | 13:80fb167dafdf | 2196 | } |
wolfSSL | 13:80fb167dafdf | 2197 | |
wolfSSL | 13:80fb167dafdf | 2198 | ssl->status_request = 1; |
wolfSSL | 13:80fb167dafdf | 2199 | |
wolfSSL | 13:80fb167dafdf | 2200 | return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */ |
wolfSSL | 13:80fb167dafdf | 2201 | #endif |
wolfSSL | 13:80fb167dafdf | 2202 | } |
wolfSSL | 13:80fb167dafdf | 2203 | else { |
wolfSSL | 13:80fb167dafdf | 2204 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 2205 | byte status_type; |
wolfSSL | 13:80fb167dafdf | 2206 | word16 offset = 0; |
wolfSSL | 13:80fb167dafdf | 2207 | word16 size = 0; |
wolfSSL | 13:80fb167dafdf | 2208 | |
wolfSSL | 13:80fb167dafdf | 2209 | if (length < ENUM_LEN) |
wolfSSL | 13:80fb167dafdf | 2210 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 2211 | |
wolfSSL | 13:80fb167dafdf | 2212 | status_type = input[offset++]; |
wolfSSL | 13:80fb167dafdf | 2213 | |
wolfSSL | 13:80fb167dafdf | 2214 | switch (status_type) { |
wolfSSL | 13:80fb167dafdf | 2215 | case WOLFSSL_CSR_OCSP: { |
wolfSSL | 13:80fb167dafdf | 2216 | |
wolfSSL | 13:80fb167dafdf | 2217 | /* skip responder_id_list */ |
wolfSSL | 13:80fb167dafdf | 2218 | if (length - offset < OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 2219 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 2220 | |
wolfSSL | 13:80fb167dafdf | 2221 | ato16(input + offset, &size); |
wolfSSL | 13:80fb167dafdf | 2222 | offset += OPAQUE16_LEN + size; |
wolfSSL | 13:80fb167dafdf | 2223 | |
wolfSSL | 13:80fb167dafdf | 2224 | /* skip request_extensions */ |
wolfSSL | 13:80fb167dafdf | 2225 | if (length - offset < OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 2226 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 2227 | |
wolfSSL | 13:80fb167dafdf | 2228 | ato16(input + offset, &size); |
wolfSSL | 13:80fb167dafdf | 2229 | offset += OPAQUE16_LEN + size; |
wolfSSL | 13:80fb167dafdf | 2230 | |
wolfSSL | 13:80fb167dafdf | 2231 | if (offset > length) |
wolfSSL | 13:80fb167dafdf | 2232 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 2233 | |
wolfSSL | 13:80fb167dafdf | 2234 | /* is able to send OCSP response? */ |
wolfSSL | 13:80fb167dafdf | 2235 | if (ssl->ctx->cm == NULL || !ssl->ctx->cm->ocspStaplingEnabled) |
wolfSSL | 13:80fb167dafdf | 2236 | return 0; |
wolfSSL | 13:80fb167dafdf | 2237 | } |
wolfSSL | 13:80fb167dafdf | 2238 | break; |
wolfSSL | 13:80fb167dafdf | 2239 | |
wolfSSL | 13:80fb167dafdf | 2240 | /* unknown status type */ |
wolfSSL | 13:80fb167dafdf | 2241 | default: |
wolfSSL | 13:80fb167dafdf | 2242 | return 0; |
wolfSSL | 13:80fb167dafdf | 2243 | } |
wolfSSL | 13:80fb167dafdf | 2244 | |
wolfSSL | 13:80fb167dafdf | 2245 | /* if using status_request and already sending it, skip this one */ |
wolfSSL | 13:80fb167dafdf | 2246 | #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 |
wolfSSL | 13:80fb167dafdf | 2247 | if (ssl->status_request_v2) |
wolfSSL | 13:80fb167dafdf | 2248 | return 0; |
wolfSSL | 13:80fb167dafdf | 2249 | #endif |
wolfSSL | 13:80fb167dafdf | 2250 | |
wolfSSL | 13:80fb167dafdf | 2251 | /* accept the first good status_type and return */ |
wolfSSL | 13:80fb167dafdf | 2252 | ret = TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type, |
wolfSSL | 13:80fb167dafdf | 2253 | 0, ssl->heap, ssl->devId); |
wolfSSL | 13:80fb167dafdf | 2254 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 2255 | return ret; /* throw error */ |
wolfSSL | 13:80fb167dafdf | 2256 | |
wolfSSL | 13:80fb167dafdf | 2257 | TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST); |
wolfSSL | 13:80fb167dafdf | 2258 | ssl->status_request = status_type; |
wolfSSL | 13:80fb167dafdf | 2259 | |
wolfSSL | 13:80fb167dafdf | 2260 | #endif |
wolfSSL | 13:80fb167dafdf | 2261 | } |
wolfSSL | 13:80fb167dafdf | 2262 | |
wolfSSL | 13:80fb167dafdf | 2263 | return 0; |
wolfSSL | 13:80fb167dafdf | 2264 | } |
wolfSSL | 13:80fb167dafdf | 2265 | |
wolfSSL | 13:80fb167dafdf | 2266 | int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert, void* heap) |
wolfSSL | 13:80fb167dafdf | 2267 | { |
wolfSSL | 13:80fb167dafdf | 2268 | TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST); |
wolfSSL | 13:80fb167dafdf | 2269 | CertificateStatusRequest* csr = extension ? |
wolfSSL | 13:80fb167dafdf | 2270 | (CertificateStatusRequest*)extension->data : NULL; |
wolfSSL | 13:80fb167dafdf | 2271 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 2272 | |
wolfSSL | 13:80fb167dafdf | 2273 | if (csr) { |
wolfSSL | 13:80fb167dafdf | 2274 | switch (csr->status_type) { |
wolfSSL | 13:80fb167dafdf | 2275 | case WOLFSSL_CSR_OCSP: { |
wolfSSL | 13:80fb167dafdf | 2276 | byte nonce[MAX_OCSP_NONCE_SZ]; |
wolfSSL | 13:80fb167dafdf | 2277 | int nonceSz = csr->request.ocsp.nonceSz; |
wolfSSL | 13:80fb167dafdf | 2278 | |
wolfSSL | 13:80fb167dafdf | 2279 | /* preserve nonce */ |
wolfSSL | 13:80fb167dafdf | 2280 | XMEMCPY(nonce, csr->request.ocsp.nonce, nonceSz); |
wolfSSL | 13:80fb167dafdf | 2281 | |
wolfSSL | 13:80fb167dafdf | 2282 | if ((ret = InitOcspRequest(&csr->request.ocsp, cert, 0, heap)) |
wolfSSL | 13:80fb167dafdf | 2283 | != 0) |
wolfSSL | 13:80fb167dafdf | 2284 | return ret; |
wolfSSL | 13:80fb167dafdf | 2285 | |
wolfSSL | 13:80fb167dafdf | 2286 | /* restore nonce */ |
wolfSSL | 13:80fb167dafdf | 2287 | XMEMCPY(csr->request.ocsp.nonce, nonce, nonceSz); |
wolfSSL | 13:80fb167dafdf | 2288 | csr->request.ocsp.nonceSz = nonceSz; |
wolfSSL | 13:80fb167dafdf | 2289 | } |
wolfSSL | 13:80fb167dafdf | 2290 | break; |
wolfSSL | 13:80fb167dafdf | 2291 | } |
wolfSSL | 13:80fb167dafdf | 2292 | } |
wolfSSL | 13:80fb167dafdf | 2293 | |
wolfSSL | 13:80fb167dafdf | 2294 | return ret; |
wolfSSL | 13:80fb167dafdf | 2295 | } |
wolfSSL | 13:80fb167dafdf | 2296 | |
wolfSSL | 13:80fb167dafdf | 2297 | void* TLSX_CSR_GetRequest(TLSX* extensions) |
wolfSSL | 13:80fb167dafdf | 2298 | { |
wolfSSL | 13:80fb167dafdf | 2299 | TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST); |
wolfSSL | 13:80fb167dafdf | 2300 | CertificateStatusRequest* csr = extension ? |
wolfSSL | 13:80fb167dafdf | 2301 | (CertificateStatusRequest*)extension->data : NULL; |
wolfSSL | 13:80fb167dafdf | 2302 | |
wolfSSL | 13:80fb167dafdf | 2303 | if (csr) { |
wolfSSL | 13:80fb167dafdf | 2304 | switch (csr->status_type) { |
wolfSSL | 13:80fb167dafdf | 2305 | case WOLFSSL_CSR_OCSP: |
wolfSSL | 13:80fb167dafdf | 2306 | return &csr->request.ocsp; |
wolfSSL | 13:80fb167dafdf | 2307 | break; |
wolfSSL | 13:80fb167dafdf | 2308 | } |
wolfSSL | 13:80fb167dafdf | 2309 | } |
wolfSSL | 13:80fb167dafdf | 2310 | |
wolfSSL | 13:80fb167dafdf | 2311 | return NULL; |
wolfSSL | 13:80fb167dafdf | 2312 | } |
wolfSSL | 13:80fb167dafdf | 2313 | |
wolfSSL | 13:80fb167dafdf | 2314 | int TLSX_CSR_ForceRequest(WOLFSSL* ssl) |
wolfSSL | 13:80fb167dafdf | 2315 | { |
wolfSSL | 13:80fb167dafdf | 2316 | TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST); |
wolfSSL | 13:80fb167dafdf | 2317 | CertificateStatusRequest* csr = extension ? |
wolfSSL | 13:80fb167dafdf | 2318 | (CertificateStatusRequest*)extension->data : NULL; |
wolfSSL | 13:80fb167dafdf | 2319 | |
wolfSSL | 13:80fb167dafdf | 2320 | if (csr) { |
wolfSSL | 13:80fb167dafdf | 2321 | switch (csr->status_type) { |
wolfSSL | 13:80fb167dafdf | 2322 | case WOLFSSL_CSR_OCSP: |
wolfSSL | 13:80fb167dafdf | 2323 | if (ssl->ctx->cm->ocspEnabled) { |
wolfSSL | 13:80fb167dafdf | 2324 | #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) |
wolfSSL | 13:80fb167dafdf | 2325 | csr->request.ocsp.ssl = ssl; |
wolfSSL | 13:80fb167dafdf | 2326 | #endif |
wolfSSL | 13:80fb167dafdf | 2327 | return CheckOcspRequest(ssl->ctx->cm->ocsp, |
wolfSSL | 13:80fb167dafdf | 2328 | &csr->request.ocsp, NULL); |
wolfSSL | 13:80fb167dafdf | 2329 | } |
wolfSSL | 13:80fb167dafdf | 2330 | else |
wolfSSL | 13:80fb167dafdf | 2331 | return OCSP_LOOKUP_FAIL; |
wolfSSL | 13:80fb167dafdf | 2332 | } |
wolfSSL | 13:80fb167dafdf | 2333 | } |
wolfSSL | 13:80fb167dafdf | 2334 | |
wolfSSL | 13:80fb167dafdf | 2335 | return 0; |
wolfSSL | 13:80fb167dafdf | 2336 | } |
wolfSSL | 13:80fb167dafdf | 2337 | |
wolfSSL | 13:80fb167dafdf | 2338 | int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type, |
wolfSSL | 13:80fb167dafdf | 2339 | byte options, void* heap, int devId) |
wolfSSL | 13:80fb167dafdf | 2340 | { |
wolfSSL | 13:80fb167dafdf | 2341 | CertificateStatusRequest* csr = NULL; |
wolfSSL | 13:80fb167dafdf | 2342 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 2343 | |
wolfSSL | 13:80fb167dafdf | 2344 | if (!extensions || status_type != WOLFSSL_CSR_OCSP) |
wolfSSL | 13:80fb167dafdf | 2345 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 2346 | |
wolfSSL | 13:80fb167dafdf | 2347 | csr = (CertificateStatusRequest*) |
wolfSSL | 13:80fb167dafdf | 2348 | XMALLOC(sizeof(CertificateStatusRequest), heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 2349 | if (!csr) |
wolfSSL | 13:80fb167dafdf | 2350 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 2351 | |
wolfSSL | 13:80fb167dafdf | 2352 | ForceZero(csr, sizeof(CertificateStatusRequest)); |
wolfSSL | 13:80fb167dafdf | 2353 | |
wolfSSL | 13:80fb167dafdf | 2354 | csr->status_type = status_type; |
wolfSSL | 13:80fb167dafdf | 2355 | csr->options = options; |
wolfSSL | 13:80fb167dafdf | 2356 | |
wolfSSL | 13:80fb167dafdf | 2357 | switch (csr->status_type) { |
wolfSSL | 13:80fb167dafdf | 2358 | case WOLFSSL_CSR_OCSP: |
wolfSSL | 13:80fb167dafdf | 2359 | if (options & WOLFSSL_CSR_OCSP_USE_NONCE) { |
wolfSSL | 13:80fb167dafdf | 2360 | WC_RNG rng; |
wolfSSL | 13:80fb167dafdf | 2361 | |
wolfSSL | 13:80fb167dafdf | 2362 | #ifndef HAVE_FIPS |
wolfSSL | 13:80fb167dafdf | 2363 | ret = wc_InitRng_ex(&rng, heap, devId); |
wolfSSL | 13:80fb167dafdf | 2364 | #else |
wolfSSL | 13:80fb167dafdf | 2365 | ret = wc_InitRng(&rng); |
wolfSSL | 13:80fb167dafdf | 2366 | (void)devId; |
wolfSSL | 13:80fb167dafdf | 2367 | #endif |
wolfSSL | 13:80fb167dafdf | 2368 | if (ret == 0) { |
wolfSSL | 13:80fb167dafdf | 2369 | if (wc_RNG_GenerateBlock(&rng, csr->request.ocsp.nonce, |
wolfSSL | 13:80fb167dafdf | 2370 | MAX_OCSP_NONCE_SZ) == 0) |
wolfSSL | 13:80fb167dafdf | 2371 | csr->request.ocsp.nonceSz = MAX_OCSP_NONCE_SZ; |
wolfSSL | 13:80fb167dafdf | 2372 | |
wolfSSL | 13:80fb167dafdf | 2373 | wc_FreeRng(&rng); |
wolfSSL | 13:80fb167dafdf | 2374 | } |
wolfSSL | 13:80fb167dafdf | 2375 | } |
wolfSSL | 13:80fb167dafdf | 2376 | break; |
wolfSSL | 13:80fb167dafdf | 2377 | } |
wolfSSL | 13:80fb167dafdf | 2378 | |
wolfSSL | 13:80fb167dafdf | 2379 | if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST, csr, heap)) != 0) { |
wolfSSL | 13:80fb167dafdf | 2380 | XFREE(csr, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 2381 | return ret; |
wolfSSL | 13:80fb167dafdf | 2382 | } |
wolfSSL | 13:80fb167dafdf | 2383 | |
wolfSSL | 13:80fb167dafdf | 2384 | return SSL_SUCCESS; |
wolfSSL | 13:80fb167dafdf | 2385 | } |
wolfSSL | 13:80fb167dafdf | 2386 | |
wolfSSL | 13:80fb167dafdf | 2387 | #define CSR_FREE_ALL TLSX_CSR_Free |
wolfSSL | 13:80fb167dafdf | 2388 | #define CSR_GET_SIZE TLSX_CSR_GetSize |
wolfSSL | 13:80fb167dafdf | 2389 | #define CSR_WRITE TLSX_CSR_Write |
wolfSSL | 13:80fb167dafdf | 2390 | #define CSR_PARSE TLSX_CSR_Parse |
wolfSSL | 13:80fb167dafdf | 2391 | |
wolfSSL | 13:80fb167dafdf | 2392 | #else |
wolfSSL | 13:80fb167dafdf | 2393 | |
wolfSSL | 13:80fb167dafdf | 2394 | #define CSR_FREE_ALL(data, heap) |
wolfSSL | 13:80fb167dafdf | 2395 | #define CSR_GET_SIZE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 2396 | #define CSR_WRITE(a, b, c) 0 |
wolfSSL | 13:80fb167dafdf | 2397 | #define CSR_PARSE(a, b, c, d) 0 |
wolfSSL | 13:80fb167dafdf | 2398 | |
wolfSSL | 13:80fb167dafdf | 2399 | #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */ |
wolfSSL | 13:80fb167dafdf | 2400 | |
wolfSSL | 13:80fb167dafdf | 2401 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 2402 | /* Certificate Status Request v2 */ |
wolfSSL | 13:80fb167dafdf | 2403 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 2404 | |
wolfSSL | 13:80fb167dafdf | 2405 | #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 |
wolfSSL | 13:80fb167dafdf | 2406 | |
wolfSSL | 13:80fb167dafdf | 2407 | static void TLSX_CSR2_FreeAll(CertificateStatusRequestItemV2* csr2, void* heap) |
wolfSSL | 13:80fb167dafdf | 2408 | { |
wolfSSL | 13:80fb167dafdf | 2409 | CertificateStatusRequestItemV2* next; |
wolfSSL | 13:80fb167dafdf | 2410 | |
wolfSSL | 13:80fb167dafdf | 2411 | for (; csr2; csr2 = next) { |
wolfSSL | 13:80fb167dafdf | 2412 | next = csr2->next; |
wolfSSL | 13:80fb167dafdf | 2413 | |
wolfSSL | 13:80fb167dafdf | 2414 | switch (csr2->status_type) { |
wolfSSL | 13:80fb167dafdf | 2415 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:80fb167dafdf | 2416 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:80fb167dafdf | 2417 | while(csr2->requests--) |
wolfSSL | 13:80fb167dafdf | 2418 | FreeOcspRequest(&csr2->request.ocsp[csr2->requests]); |
wolfSSL | 13:80fb167dafdf | 2419 | break; |
wolfSSL | 13:80fb167dafdf | 2420 | } |
wolfSSL | 13:80fb167dafdf | 2421 | |
wolfSSL | 13:80fb167dafdf | 2422 | XFREE(csr2, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 2423 | } |
wolfSSL | 13:80fb167dafdf | 2424 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 2425 | } |
wolfSSL | 13:80fb167dafdf | 2426 | |
wolfSSL | 13:80fb167dafdf | 2427 | static word16 TLSX_CSR2_GetSize(CertificateStatusRequestItemV2* csr2, |
wolfSSL | 13:80fb167dafdf | 2428 | byte isRequest) |
wolfSSL | 13:80fb167dafdf | 2429 | { |
wolfSSL | 13:80fb167dafdf | 2430 | word16 size = 0; |
wolfSSL | 13:80fb167dafdf | 2431 | |
wolfSSL | 13:80fb167dafdf | 2432 | /* shut up compiler warnings */ |
wolfSSL | 13:80fb167dafdf | 2433 | (void) csr2; (void) isRequest; |
wolfSSL | 13:80fb167dafdf | 2434 | |
wolfSSL | 13:80fb167dafdf | 2435 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:80fb167dafdf | 2436 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 2437 | CertificateStatusRequestItemV2* next; |
wolfSSL | 13:80fb167dafdf | 2438 | |
wolfSSL | 13:80fb167dafdf | 2439 | for (size = OPAQUE16_LEN; csr2; csr2 = next) { |
wolfSSL | 13:80fb167dafdf | 2440 | next = csr2->next; |
wolfSSL | 13:80fb167dafdf | 2441 | |
wolfSSL | 13:80fb167dafdf | 2442 | switch (csr2->status_type) { |
wolfSSL | 13:80fb167dafdf | 2443 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:80fb167dafdf | 2444 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:80fb167dafdf | 2445 | size += ENUM_LEN + 3 * OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 2446 | |
wolfSSL | 13:80fb167dafdf | 2447 | if (csr2->request.ocsp[0].nonceSz) |
wolfSSL | 13:80fb167dafdf | 2448 | size += OCSP_NONCE_EXT_SZ; |
wolfSSL | 13:80fb167dafdf | 2449 | break; |
wolfSSL | 13:80fb167dafdf | 2450 | } |
wolfSSL | 13:80fb167dafdf | 2451 | } |
wolfSSL | 13:80fb167dafdf | 2452 | } |
wolfSSL | 13:80fb167dafdf | 2453 | #endif |
wolfSSL | 13:80fb167dafdf | 2454 | |
wolfSSL | 13:80fb167dafdf | 2455 | return size; |
wolfSSL | 13:80fb167dafdf | 2456 | } |
wolfSSL | 13:80fb167dafdf | 2457 | |
wolfSSL | 13:80fb167dafdf | 2458 | static word16 TLSX_CSR2_Write(CertificateStatusRequestItemV2* csr2, |
wolfSSL | 13:80fb167dafdf | 2459 | byte* output, byte isRequest) |
wolfSSL | 13:80fb167dafdf | 2460 | { |
wolfSSL | 13:80fb167dafdf | 2461 | /* shut up compiler warnings */ |
wolfSSL | 13:80fb167dafdf | 2462 | (void) csr2; (void) output; (void) isRequest; |
wolfSSL | 13:80fb167dafdf | 2463 | |
wolfSSL | 13:80fb167dafdf | 2464 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:80fb167dafdf | 2465 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 2466 | word16 offset; |
wolfSSL | 13:80fb167dafdf | 2467 | word16 length; |
wolfSSL | 13:80fb167dafdf | 2468 | |
wolfSSL | 13:80fb167dafdf | 2469 | for (offset = OPAQUE16_LEN; csr2 != NULL; csr2 = csr2->next) { |
wolfSSL | 13:80fb167dafdf | 2470 | /* status_type */ |
wolfSSL | 13:80fb167dafdf | 2471 | output[offset++] = csr2->status_type; |
wolfSSL | 13:80fb167dafdf | 2472 | |
wolfSSL | 13:80fb167dafdf | 2473 | /* request */ |
wolfSSL | 13:80fb167dafdf | 2474 | switch (csr2->status_type) { |
wolfSSL | 13:80fb167dafdf | 2475 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:80fb167dafdf | 2476 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:80fb167dafdf | 2477 | /* request_length */ |
wolfSSL | 13:80fb167dafdf | 2478 | length = 2 * OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 2479 | |
wolfSSL | 13:80fb167dafdf | 2480 | if (csr2->request.ocsp[0].nonceSz) |
wolfSSL | 13:80fb167dafdf | 2481 | length += OCSP_NONCE_EXT_SZ; |
wolfSSL | 13:80fb167dafdf | 2482 | |
wolfSSL | 13:80fb167dafdf | 2483 | c16toa(length, output + offset); |
wolfSSL | 13:80fb167dafdf | 2484 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 2485 | |
wolfSSL | 13:80fb167dafdf | 2486 | /* responder id list */ |
wolfSSL | 13:80fb167dafdf | 2487 | c16toa(0, output + offset); |
wolfSSL | 13:80fb167dafdf | 2488 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 2489 | |
wolfSSL | 13:80fb167dafdf | 2490 | /* request extensions */ |
wolfSSL | 13:80fb167dafdf | 2491 | length = 0; |
wolfSSL | 13:80fb167dafdf | 2492 | |
wolfSSL | 13:80fb167dafdf | 2493 | if (csr2->request.ocsp[0].nonceSz) |
wolfSSL | 13:80fb167dafdf | 2494 | length = (word16)EncodeOcspRequestExtensions( |
wolfSSL | 13:80fb167dafdf | 2495 | &csr2->request.ocsp[0], |
wolfSSL | 13:80fb167dafdf | 2496 | output + offset + OPAQUE16_LEN, |
wolfSSL | 13:80fb167dafdf | 2497 | OCSP_NONCE_EXT_SZ); |
wolfSSL | 13:80fb167dafdf | 2498 | |
wolfSSL | 13:80fb167dafdf | 2499 | c16toa(length, output + offset); |
wolfSSL | 13:80fb167dafdf | 2500 | offset += OPAQUE16_LEN + length; |
wolfSSL | 13:80fb167dafdf | 2501 | break; |
wolfSSL | 13:80fb167dafdf | 2502 | } |
wolfSSL | 13:80fb167dafdf | 2503 | } |
wolfSSL | 13:80fb167dafdf | 2504 | |
wolfSSL | 13:80fb167dafdf | 2505 | /* list size */ |
wolfSSL | 13:80fb167dafdf | 2506 | c16toa(offset - OPAQUE16_LEN, output); |
wolfSSL | 13:80fb167dafdf | 2507 | |
wolfSSL | 13:80fb167dafdf | 2508 | return offset; |
wolfSSL | 13:80fb167dafdf | 2509 | } |
wolfSSL | 13:80fb167dafdf | 2510 | #endif |
wolfSSL | 13:80fb167dafdf | 2511 | |
wolfSSL | 13:80fb167dafdf | 2512 | return 0; |
wolfSSL | 13:80fb167dafdf | 2513 | } |
wolfSSL | 13:80fb167dafdf | 2514 | |
wolfSSL | 13:80fb167dafdf | 2515 | static int TLSX_CSR2_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:80fb167dafdf | 2516 | byte isRequest) |
wolfSSL | 13:80fb167dafdf | 2517 | { |
wolfSSL | 13:80fb167dafdf | 2518 | int ret; |
wolfSSL | 13:80fb167dafdf | 2519 | |
wolfSSL | 13:80fb167dafdf | 2520 | /* shut up compiler warnings */ |
wolfSSL | 13:80fb167dafdf | 2521 | (void) ssl; (void) input; |
wolfSSL | 13:80fb167dafdf | 2522 | |
wolfSSL | 13:80fb167dafdf | 2523 | if (!isRequest) { |
wolfSSL | 13:80fb167dafdf | 2524 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:80fb167dafdf | 2525 | TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2); |
wolfSSL | 13:80fb167dafdf | 2526 | CertificateStatusRequestItemV2* csr2 = extension ? |
wolfSSL | 13:80fb167dafdf | 2527 | (CertificateStatusRequestItemV2*)extension->data : NULL; |
wolfSSL | 13:80fb167dafdf | 2528 | |
wolfSSL | 13:80fb167dafdf | 2529 | if (!csr2) { |
wolfSSL | 13:80fb167dafdf | 2530 | /* look at context level */ |
wolfSSL | 13:80fb167dafdf | 2531 | extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST_V2); |
wolfSSL | 13:80fb167dafdf | 2532 | csr2 = extension ? |
wolfSSL | 13:80fb167dafdf | 2533 | (CertificateStatusRequestItemV2*)extension->data : NULL; |
wolfSSL | 13:80fb167dafdf | 2534 | |
wolfSSL | 13:80fb167dafdf | 2535 | if (!csr2) |
wolfSSL | 13:80fb167dafdf | 2536 | return BUFFER_ERROR; /* unexpected extension */ |
wolfSSL | 13:80fb167dafdf | 2537 | |
wolfSSL | 13:80fb167dafdf | 2538 | /* enable extension at ssl level */ |
wolfSSL | 13:80fb167dafdf | 2539 | for (; csr2; csr2 = csr2->next) { |
wolfSSL | 13:80fb167dafdf | 2540 | ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 2541 | csr2->status_type, csr2->options, ssl->heap, ssl->devId); |
wolfSSL | 13:80fb167dafdf | 2542 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 2543 | return ret; |
wolfSSL | 13:80fb167dafdf | 2544 | |
wolfSSL | 13:80fb167dafdf | 2545 | switch (csr2->status_type) { |
wolfSSL | 13:80fb167dafdf | 2546 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:80fb167dafdf | 2547 | /* followed by */ |
wolfSSL | 13:80fb167dafdf | 2548 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:80fb167dafdf | 2549 | /* propagate nonce */ |
wolfSSL | 13:80fb167dafdf | 2550 | if (csr2->request.ocsp[0].nonceSz) { |
wolfSSL | 13:80fb167dafdf | 2551 | OcspRequest* request = |
wolfSSL | 13:80fb167dafdf | 2552 | (OcspRequest*)TLSX_CSR2_GetRequest(ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 2553 | csr2->status_type, 0); |
wolfSSL | 13:80fb167dafdf | 2554 | |
wolfSSL | 13:80fb167dafdf | 2555 | if (request) { |
wolfSSL | 13:80fb167dafdf | 2556 | XMEMCPY(request->nonce, |
wolfSSL | 13:80fb167dafdf | 2557 | csr2->request.ocsp[0].nonce, |
wolfSSL | 13:80fb167dafdf | 2558 | csr2->request.ocsp[0].nonceSz); |
wolfSSL | 13:80fb167dafdf | 2559 | |
wolfSSL | 13:80fb167dafdf | 2560 | request->nonceSz = |
wolfSSL | 13:80fb167dafdf | 2561 | csr2->request.ocsp[0].nonceSz; |
wolfSSL | 13:80fb167dafdf | 2562 | } |
wolfSSL | 13:80fb167dafdf | 2563 | } |
wolfSSL | 13:80fb167dafdf | 2564 | break; |
wolfSSL | 13:80fb167dafdf | 2565 | } |
wolfSSL | 13:80fb167dafdf | 2566 | } |
wolfSSL | 13:80fb167dafdf | 2567 | } |
wolfSSL | 13:80fb167dafdf | 2568 | |
wolfSSL | 13:80fb167dafdf | 2569 | ssl->status_request_v2 = 1; |
wolfSSL | 13:80fb167dafdf | 2570 | |
wolfSSL | 13:80fb167dafdf | 2571 | return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */ |
wolfSSL | 13:80fb167dafdf | 2572 | #endif |
wolfSSL | 13:80fb167dafdf | 2573 | } |
wolfSSL | 13:80fb167dafdf | 2574 | else { |
wolfSSL | 13:80fb167dafdf | 2575 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 2576 | byte status_type; |
wolfSSL | 13:80fb167dafdf | 2577 | word16 request_length; |
wolfSSL | 13:80fb167dafdf | 2578 | word16 offset = 0; |
wolfSSL | 13:80fb167dafdf | 2579 | word16 size = 0; |
wolfSSL | 13:80fb167dafdf | 2580 | |
wolfSSL | 13:80fb167dafdf | 2581 | /* list size */ |
wolfSSL | 13:80fb167dafdf | 2582 | ato16(input + offset, &request_length); |
wolfSSL | 13:80fb167dafdf | 2583 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 2584 | |
wolfSSL | 13:80fb167dafdf | 2585 | if (length - OPAQUE16_LEN != request_length) |
wolfSSL | 13:80fb167dafdf | 2586 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 2587 | |
wolfSSL | 13:80fb167dafdf | 2588 | while (length > offset) { |
wolfSSL | 13:80fb167dafdf | 2589 | if (length - offset < ENUM_LEN + OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 2590 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 2591 | |
wolfSSL | 13:80fb167dafdf | 2592 | status_type = input[offset++]; |
wolfSSL | 13:80fb167dafdf | 2593 | |
wolfSSL | 13:80fb167dafdf | 2594 | ato16(input + offset, &request_length); |
wolfSSL | 13:80fb167dafdf | 2595 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 2596 | |
wolfSSL | 13:80fb167dafdf | 2597 | if (length - offset < request_length) |
wolfSSL | 13:80fb167dafdf | 2598 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 2599 | |
wolfSSL | 13:80fb167dafdf | 2600 | switch (status_type) { |
wolfSSL | 13:80fb167dafdf | 2601 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:80fb167dafdf | 2602 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:80fb167dafdf | 2603 | /* skip responder_id_list */ |
wolfSSL | 13:80fb167dafdf | 2604 | if (length - offset < OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 2605 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 2606 | |
wolfSSL | 13:80fb167dafdf | 2607 | ato16(input + offset, &size); |
wolfSSL | 13:80fb167dafdf | 2608 | offset += OPAQUE16_LEN + size; |
wolfSSL | 13:80fb167dafdf | 2609 | |
wolfSSL | 13:80fb167dafdf | 2610 | /* skip request_extensions */ |
wolfSSL | 13:80fb167dafdf | 2611 | if (length - offset < OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 2612 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 2613 | |
wolfSSL | 13:80fb167dafdf | 2614 | ato16(input + offset, &size); |
wolfSSL | 13:80fb167dafdf | 2615 | offset += OPAQUE16_LEN + size; |
wolfSSL | 13:80fb167dafdf | 2616 | |
wolfSSL | 13:80fb167dafdf | 2617 | if (offset > length) |
wolfSSL | 13:80fb167dafdf | 2618 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 2619 | |
wolfSSL | 13:80fb167dafdf | 2620 | /* is able to send OCSP response? */ |
wolfSSL | 13:80fb167dafdf | 2621 | if (ssl->ctx->cm == NULL |
wolfSSL | 13:80fb167dafdf | 2622 | || !ssl->ctx->cm->ocspStaplingEnabled) |
wolfSSL | 13:80fb167dafdf | 2623 | continue; |
wolfSSL | 13:80fb167dafdf | 2624 | break; |
wolfSSL | 13:80fb167dafdf | 2625 | |
wolfSSL | 13:80fb167dafdf | 2626 | default: |
wolfSSL | 13:80fb167dafdf | 2627 | /* unknown status type, skipping! */ |
wolfSSL | 13:80fb167dafdf | 2628 | offset += request_length; |
wolfSSL | 13:80fb167dafdf | 2629 | continue; |
wolfSSL | 13:80fb167dafdf | 2630 | } |
wolfSSL | 13:80fb167dafdf | 2631 | |
wolfSSL | 13:80fb167dafdf | 2632 | /* if using status_request and already sending it, skip this one */ |
wolfSSL | 13:80fb167dafdf | 2633 | #ifdef HAVE_CERTIFICATE_STATUS_REQUEST |
wolfSSL | 13:80fb167dafdf | 2634 | if (ssl->status_request) |
wolfSSL | 13:80fb167dafdf | 2635 | return 0; |
wolfSSL | 13:80fb167dafdf | 2636 | #endif |
wolfSSL | 13:80fb167dafdf | 2637 | |
wolfSSL | 13:80fb167dafdf | 2638 | /* accept the first good status_type and return */ |
wolfSSL | 13:80fb167dafdf | 2639 | ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 2640 | status_type, 0, ssl->heap, ssl->devId); |
wolfSSL | 13:80fb167dafdf | 2641 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 2642 | return ret; /* throw error */ |
wolfSSL | 13:80fb167dafdf | 2643 | |
wolfSSL | 13:80fb167dafdf | 2644 | TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST_V2); |
wolfSSL | 13:80fb167dafdf | 2645 | ssl->status_request_v2 = status_type; |
wolfSSL | 13:80fb167dafdf | 2646 | |
wolfSSL | 13:80fb167dafdf | 2647 | return 0; |
wolfSSL | 13:80fb167dafdf | 2648 | } |
wolfSSL | 13:80fb167dafdf | 2649 | #endif |
wolfSSL | 13:80fb167dafdf | 2650 | } |
wolfSSL | 13:80fb167dafdf | 2651 | |
wolfSSL | 13:80fb167dafdf | 2652 | return 0; |
wolfSSL | 13:80fb167dafdf | 2653 | } |
wolfSSL | 13:80fb167dafdf | 2654 | |
wolfSSL | 13:80fb167dafdf | 2655 | int TLSX_CSR2_InitRequests(TLSX* extensions, DecodedCert* cert, byte isPeer, |
wolfSSL | 13:80fb167dafdf | 2656 | void* heap) |
wolfSSL | 13:80fb167dafdf | 2657 | { |
wolfSSL | 13:80fb167dafdf | 2658 | TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2); |
wolfSSL | 13:80fb167dafdf | 2659 | CertificateStatusRequestItemV2* csr2 = extension ? |
wolfSSL | 13:80fb167dafdf | 2660 | (CertificateStatusRequestItemV2*)extension->data : NULL; |
wolfSSL | 13:80fb167dafdf | 2661 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 2662 | |
wolfSSL | 13:80fb167dafdf | 2663 | for (; csr2; csr2 = csr2->next) { |
wolfSSL | 13:80fb167dafdf | 2664 | switch (csr2->status_type) { |
wolfSSL | 13:80fb167dafdf | 2665 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:80fb167dafdf | 2666 | if (!isPeer || csr2->requests != 0) |
wolfSSL | 13:80fb167dafdf | 2667 | break; |
wolfSSL | 13:80fb167dafdf | 2668 | |
wolfSSL | 13:80fb167dafdf | 2669 | /* followed by */ |
wolfSSL | 13:80fb167dafdf | 2670 | |
wolfSSL | 13:80fb167dafdf | 2671 | case WOLFSSL_CSR2_OCSP_MULTI: { |
wolfSSL | 13:80fb167dafdf | 2672 | if (csr2->requests < 1 + MAX_CHAIN_DEPTH) { |
wolfSSL | 13:80fb167dafdf | 2673 | byte nonce[MAX_OCSP_NONCE_SZ]; |
wolfSSL | 13:80fb167dafdf | 2674 | int nonceSz = csr2->request.ocsp[0].nonceSz; |
wolfSSL | 13:80fb167dafdf | 2675 | |
wolfSSL | 13:80fb167dafdf | 2676 | /* preserve nonce, replicating nonce of ocsp[0] */ |
wolfSSL | 13:80fb167dafdf | 2677 | XMEMCPY(nonce, csr2->request.ocsp[0].nonce, nonceSz); |
wolfSSL | 13:80fb167dafdf | 2678 | |
wolfSSL | 13:80fb167dafdf | 2679 | if ((ret = InitOcspRequest( |
wolfSSL | 13:80fb167dafdf | 2680 | &csr2->request.ocsp[csr2->requests], cert, |
wolfSSL | 13:80fb167dafdf | 2681 | 0, heap)) != 0) |
wolfSSL | 13:80fb167dafdf | 2682 | return ret; |
wolfSSL | 13:80fb167dafdf | 2683 | |
wolfSSL | 13:80fb167dafdf | 2684 | /* restore nonce */ |
wolfSSL | 13:80fb167dafdf | 2685 | XMEMCPY(csr2->request.ocsp[csr2->requests].nonce, |
wolfSSL | 13:80fb167dafdf | 2686 | nonce, nonceSz); |
wolfSSL | 13:80fb167dafdf | 2687 | csr2->request.ocsp[csr2->requests].nonceSz = nonceSz; |
wolfSSL | 13:80fb167dafdf | 2688 | csr2->requests++; |
wolfSSL | 13:80fb167dafdf | 2689 | } |
wolfSSL | 13:80fb167dafdf | 2690 | } |
wolfSSL | 13:80fb167dafdf | 2691 | break; |
wolfSSL | 13:80fb167dafdf | 2692 | } |
wolfSSL | 13:80fb167dafdf | 2693 | } |
wolfSSL | 13:80fb167dafdf | 2694 | |
wolfSSL | 13:80fb167dafdf | 2695 | (void)cert; |
wolfSSL | 13:80fb167dafdf | 2696 | return ret; |
wolfSSL | 13:80fb167dafdf | 2697 | } |
wolfSSL | 13:80fb167dafdf | 2698 | |
wolfSSL | 13:80fb167dafdf | 2699 | void* TLSX_CSR2_GetRequest(TLSX* extensions, byte status_type, byte idx) |
wolfSSL | 13:80fb167dafdf | 2700 | { |
wolfSSL | 13:80fb167dafdf | 2701 | TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2); |
wolfSSL | 13:80fb167dafdf | 2702 | CertificateStatusRequestItemV2* csr2 = extension ? |
wolfSSL | 13:80fb167dafdf | 2703 | (CertificateStatusRequestItemV2*)extension->data : NULL; |
wolfSSL | 13:80fb167dafdf | 2704 | |
wolfSSL | 13:80fb167dafdf | 2705 | for (; csr2; csr2 = csr2->next) { |
wolfSSL | 13:80fb167dafdf | 2706 | if (csr2->status_type == status_type) { |
wolfSSL | 13:80fb167dafdf | 2707 | switch (csr2->status_type) { |
wolfSSL | 13:80fb167dafdf | 2708 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:80fb167dafdf | 2709 | /* followed by */ |
wolfSSL | 13:80fb167dafdf | 2710 | |
wolfSSL | 13:80fb167dafdf | 2711 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:80fb167dafdf | 2712 | /* requests are initialized in the reverse order */ |
wolfSSL | 13:80fb167dafdf | 2713 | return idx < csr2->requests |
wolfSSL | 13:80fb167dafdf | 2714 | ? &csr2->request.ocsp[csr2->requests - idx - 1] |
wolfSSL | 13:80fb167dafdf | 2715 | : NULL; |
wolfSSL | 13:80fb167dafdf | 2716 | break; |
wolfSSL | 13:80fb167dafdf | 2717 | } |
wolfSSL | 13:80fb167dafdf | 2718 | } |
wolfSSL | 13:80fb167dafdf | 2719 | } |
wolfSSL | 13:80fb167dafdf | 2720 | |
wolfSSL | 13:80fb167dafdf | 2721 | return NULL; |
wolfSSL | 13:80fb167dafdf | 2722 | } |
wolfSSL | 13:80fb167dafdf | 2723 | |
wolfSSL | 13:80fb167dafdf | 2724 | int TLSX_CSR2_ForceRequest(WOLFSSL* ssl) |
wolfSSL | 13:80fb167dafdf | 2725 | { |
wolfSSL | 13:80fb167dafdf | 2726 | TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2); |
wolfSSL | 13:80fb167dafdf | 2727 | CertificateStatusRequestItemV2* csr2 = extension ? |
wolfSSL | 13:80fb167dafdf | 2728 | (CertificateStatusRequestItemV2*)extension->data : NULL; |
wolfSSL | 13:80fb167dafdf | 2729 | |
wolfSSL | 13:80fb167dafdf | 2730 | /* forces only the first one */ |
wolfSSL | 13:80fb167dafdf | 2731 | if (csr2) { |
wolfSSL | 13:80fb167dafdf | 2732 | switch (csr2->status_type) { |
wolfSSL | 13:80fb167dafdf | 2733 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:80fb167dafdf | 2734 | /* followed by */ |
wolfSSL | 13:80fb167dafdf | 2735 | |
wolfSSL | 13:80fb167dafdf | 2736 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:80fb167dafdf | 2737 | if (ssl->ctx->cm->ocspEnabled) { |
wolfSSL | 13:80fb167dafdf | 2738 | #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) |
wolfSSL | 13:80fb167dafdf | 2739 | csr2->request.ocsp[0].ssl = ssl; |
wolfSSL | 13:80fb167dafdf | 2740 | #endif |
wolfSSL | 13:80fb167dafdf | 2741 | return CheckOcspRequest(ssl->ctx->cm->ocsp, |
wolfSSL | 13:80fb167dafdf | 2742 | &csr2->request.ocsp[0], NULL); |
wolfSSL | 13:80fb167dafdf | 2743 | } |
wolfSSL | 13:80fb167dafdf | 2744 | else |
wolfSSL | 13:80fb167dafdf | 2745 | return OCSP_LOOKUP_FAIL; |
wolfSSL | 13:80fb167dafdf | 2746 | } |
wolfSSL | 13:80fb167dafdf | 2747 | } |
wolfSSL | 13:80fb167dafdf | 2748 | |
wolfSSL | 13:80fb167dafdf | 2749 | return 0; |
wolfSSL | 13:80fb167dafdf | 2750 | } |
wolfSSL | 13:80fb167dafdf | 2751 | |
wolfSSL | 13:80fb167dafdf | 2752 | int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type, |
wolfSSL | 13:80fb167dafdf | 2753 | byte options, void* heap, int devId) |
wolfSSL | 13:80fb167dafdf | 2754 | { |
wolfSSL | 13:80fb167dafdf | 2755 | TLSX* extension = NULL; |
wolfSSL | 13:80fb167dafdf | 2756 | CertificateStatusRequestItemV2* csr2 = NULL; |
wolfSSL | 13:80fb167dafdf | 2757 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 2758 | |
wolfSSL | 13:80fb167dafdf | 2759 | if (!extensions) |
wolfSSL | 13:80fb167dafdf | 2760 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 2761 | |
wolfSSL | 13:80fb167dafdf | 2762 | if (status_type != WOLFSSL_CSR2_OCSP |
wolfSSL | 13:80fb167dafdf | 2763 | && status_type != WOLFSSL_CSR2_OCSP_MULTI) |
wolfSSL | 13:80fb167dafdf | 2764 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 2765 | |
wolfSSL | 13:80fb167dafdf | 2766 | csr2 = (CertificateStatusRequestItemV2*) |
wolfSSL | 13:80fb167dafdf | 2767 | XMALLOC(sizeof(CertificateStatusRequestItemV2), heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 2768 | if (!csr2) |
wolfSSL | 13:80fb167dafdf | 2769 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 2770 | |
wolfSSL | 13:80fb167dafdf | 2771 | ForceZero(csr2, sizeof(CertificateStatusRequestItemV2)); |
wolfSSL | 13:80fb167dafdf | 2772 | |
wolfSSL | 13:80fb167dafdf | 2773 | csr2->status_type = status_type; |
wolfSSL | 13:80fb167dafdf | 2774 | csr2->options = options; |
wolfSSL | 13:80fb167dafdf | 2775 | csr2->next = NULL; |
wolfSSL | 13:80fb167dafdf | 2776 | |
wolfSSL | 13:80fb167dafdf | 2777 | switch (csr2->status_type) { |
wolfSSL | 13:80fb167dafdf | 2778 | case WOLFSSL_CSR2_OCSP: |
wolfSSL | 13:80fb167dafdf | 2779 | case WOLFSSL_CSR2_OCSP_MULTI: |
wolfSSL | 13:80fb167dafdf | 2780 | if (options & WOLFSSL_CSR2_OCSP_USE_NONCE) { |
wolfSSL | 13:80fb167dafdf | 2781 | WC_RNG rng; |
wolfSSL | 13:80fb167dafdf | 2782 | |
wolfSSL | 13:80fb167dafdf | 2783 | #ifndef HAVE_FIPS |
wolfSSL | 13:80fb167dafdf | 2784 | ret = wc_InitRng_ex(&rng, heap, devId); |
wolfSSL | 13:80fb167dafdf | 2785 | #else |
wolfSSL | 13:80fb167dafdf | 2786 | ret = wc_InitRng(&rng); |
wolfSSL | 13:80fb167dafdf | 2787 | (void)devId; |
wolfSSL | 13:80fb167dafdf | 2788 | #endif |
wolfSSL | 13:80fb167dafdf | 2789 | if (ret == 0) { |
wolfSSL | 13:80fb167dafdf | 2790 | if (wc_RNG_GenerateBlock(&rng, csr2->request.ocsp[0].nonce, |
wolfSSL | 13:80fb167dafdf | 2791 | MAX_OCSP_NONCE_SZ) == 0) |
wolfSSL | 13:80fb167dafdf | 2792 | csr2->request.ocsp[0].nonceSz = MAX_OCSP_NONCE_SZ; |
wolfSSL | 13:80fb167dafdf | 2793 | |
wolfSSL | 13:80fb167dafdf | 2794 | wc_FreeRng(&rng); |
wolfSSL | 13:80fb167dafdf | 2795 | } |
wolfSSL | 13:80fb167dafdf | 2796 | } |
wolfSSL | 13:80fb167dafdf | 2797 | break; |
wolfSSL | 13:80fb167dafdf | 2798 | } |
wolfSSL | 13:80fb167dafdf | 2799 | |
wolfSSL | 13:80fb167dafdf | 2800 | /* append new item */ |
wolfSSL | 13:80fb167dafdf | 2801 | if ((extension = TLSX_Find(*extensions, TLSX_STATUS_REQUEST_V2))) { |
wolfSSL | 13:80fb167dafdf | 2802 | CertificateStatusRequestItemV2* last = |
wolfSSL | 13:80fb167dafdf | 2803 | (CertificateStatusRequestItemV2*)extension->data; |
wolfSSL | 13:80fb167dafdf | 2804 | |
wolfSSL | 13:80fb167dafdf | 2805 | for (; last->next; last = last->next); |
wolfSSL | 13:80fb167dafdf | 2806 | |
wolfSSL | 13:80fb167dafdf | 2807 | last->next = csr2; |
wolfSSL | 13:80fb167dafdf | 2808 | } |
wolfSSL | 13:80fb167dafdf | 2809 | else if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST_V2, csr2,heap))) { |
wolfSSL | 13:80fb167dafdf | 2810 | XFREE(csr2, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 2811 | return ret; |
wolfSSL | 13:80fb167dafdf | 2812 | } |
wolfSSL | 13:80fb167dafdf | 2813 | |
wolfSSL | 13:80fb167dafdf | 2814 | return SSL_SUCCESS; |
wolfSSL | 13:80fb167dafdf | 2815 | } |
wolfSSL | 13:80fb167dafdf | 2816 | |
wolfSSL | 13:80fb167dafdf | 2817 | #define CSR2_FREE_ALL TLSX_CSR2_FreeAll |
wolfSSL | 13:80fb167dafdf | 2818 | #define CSR2_GET_SIZE TLSX_CSR2_GetSize |
wolfSSL | 13:80fb167dafdf | 2819 | #define CSR2_WRITE TLSX_CSR2_Write |
wolfSSL | 13:80fb167dafdf | 2820 | #define CSR2_PARSE TLSX_CSR2_Parse |
wolfSSL | 13:80fb167dafdf | 2821 | |
wolfSSL | 13:80fb167dafdf | 2822 | #else |
wolfSSL | 13:80fb167dafdf | 2823 | |
wolfSSL | 13:80fb167dafdf | 2824 | #define CSR2_FREE_ALL(data, heap) |
wolfSSL | 13:80fb167dafdf | 2825 | #define CSR2_GET_SIZE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 2826 | #define CSR2_WRITE(a, b, c) 0 |
wolfSSL | 13:80fb167dafdf | 2827 | #define CSR2_PARSE(a, b, c, d) 0 |
wolfSSL | 13:80fb167dafdf | 2828 | |
wolfSSL | 13:80fb167dafdf | 2829 | #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */ |
wolfSSL | 13:80fb167dafdf | 2830 | |
wolfSSL | 13:80fb167dafdf | 2831 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 2832 | /* Supported Elliptic Curves */ |
wolfSSL | 13:80fb167dafdf | 2833 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 2834 | |
wolfSSL | 13:80fb167dafdf | 2835 | #ifdef HAVE_SUPPORTED_CURVES |
wolfSSL | 13:80fb167dafdf | 2836 | |
wolfSSL | 13:80fb167dafdf | 2837 | #ifndef HAVE_ECC |
wolfSSL | 13:80fb167dafdf | 2838 | #error Elliptic Curves Extension requires Elliptic Curve Cryptography. \ |
wolfSSL | 13:80fb167dafdf | 2839 | Use --enable-ecc in the configure script or define HAVE_ECC. |
wolfSSL | 13:80fb167dafdf | 2840 | #endif |
wolfSSL | 13:80fb167dafdf | 2841 | |
wolfSSL | 13:80fb167dafdf | 2842 | static void TLSX_EllipticCurve_FreeAll(EllipticCurve* list, void* heap) |
wolfSSL | 13:80fb167dafdf | 2843 | { |
wolfSSL | 13:80fb167dafdf | 2844 | EllipticCurve* curve; |
wolfSSL | 13:80fb167dafdf | 2845 | |
wolfSSL | 13:80fb167dafdf | 2846 | while ((curve = list)) { |
wolfSSL | 13:80fb167dafdf | 2847 | list = curve->next; |
wolfSSL | 13:80fb167dafdf | 2848 | XFREE(curve, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 2849 | } |
wolfSSL | 13:80fb167dafdf | 2850 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 2851 | } |
wolfSSL | 13:80fb167dafdf | 2852 | |
wolfSSL | 13:80fb167dafdf | 2853 | static int TLSX_EllipticCurve_Append(EllipticCurve** list, word16 name, |
wolfSSL | 13:80fb167dafdf | 2854 | void* heap) |
wolfSSL | 13:80fb167dafdf | 2855 | { |
wolfSSL | 13:80fb167dafdf | 2856 | EllipticCurve* curve = NULL; |
wolfSSL | 13:80fb167dafdf | 2857 | |
wolfSSL | 13:80fb167dafdf | 2858 | if (list == NULL) |
wolfSSL | 13:80fb167dafdf | 2859 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 2860 | |
wolfSSL | 13:80fb167dafdf | 2861 | curve = (EllipticCurve*)XMALLOC(sizeof(EllipticCurve), heap, |
wolfSSL | 13:80fb167dafdf | 2862 | DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 2863 | if (curve == NULL) |
wolfSSL | 13:80fb167dafdf | 2864 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 2865 | |
wolfSSL | 13:80fb167dafdf | 2866 | curve->name = name; |
wolfSSL | 13:80fb167dafdf | 2867 | curve->next = *list; |
wolfSSL | 13:80fb167dafdf | 2868 | |
wolfSSL | 13:80fb167dafdf | 2869 | *list = curve; |
wolfSSL | 13:80fb167dafdf | 2870 | |
wolfSSL | 13:80fb167dafdf | 2871 | return 0; |
wolfSSL | 13:80fb167dafdf | 2872 | } |
wolfSSL | 13:80fb167dafdf | 2873 | |
wolfSSL | 13:80fb167dafdf | 2874 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:80fb167dafdf | 2875 | |
wolfSSL | 13:80fb167dafdf | 2876 | static void TLSX_EllipticCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore) |
wolfSSL | 13:80fb167dafdf | 2877 | { |
wolfSSL | 13:80fb167dafdf | 2878 | int i; |
wolfSSL | 13:80fb167dafdf | 2879 | |
wolfSSL | 13:80fb167dafdf | 2880 | for (i = 0; i < ssl->suites->suiteSz; i+= 2) |
wolfSSL | 13:80fb167dafdf | 2881 | if (ssl->suites->suites[i] == ECC_BYTE || |
wolfSSL | 13:80fb167dafdf | 2882 | ssl->suites->suites[i] == CHACHA_BYTE || |
wolfSSL | 13:80fb167dafdf | 2883 | ssl->suites->suites[i] == TLS13_BYTE) |
wolfSSL | 13:80fb167dafdf | 2884 | return; |
wolfSSL | 13:80fb167dafdf | 2885 | |
wolfSSL | 13:80fb167dafdf | 2886 | /* turns semaphore on to avoid sending this extension. */ |
wolfSSL | 13:80fb167dafdf | 2887 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS)); |
wolfSSL | 13:80fb167dafdf | 2888 | } |
wolfSSL | 13:80fb167dafdf | 2889 | |
wolfSSL | 13:80fb167dafdf | 2890 | static word16 TLSX_EllipticCurve_GetSize(EllipticCurve* list) |
wolfSSL | 13:80fb167dafdf | 2891 | { |
wolfSSL | 13:80fb167dafdf | 2892 | EllipticCurve* curve; |
wolfSSL | 13:80fb167dafdf | 2893 | word16 length = OPAQUE16_LEN; /* list length */ |
wolfSSL | 13:80fb167dafdf | 2894 | |
wolfSSL | 13:80fb167dafdf | 2895 | while ((curve = list)) { |
wolfSSL | 13:80fb167dafdf | 2896 | list = curve->next; |
wolfSSL | 13:80fb167dafdf | 2897 | length += OPAQUE16_LEN; /* curve length */ |
wolfSSL | 13:80fb167dafdf | 2898 | } |
wolfSSL | 13:80fb167dafdf | 2899 | |
wolfSSL | 13:80fb167dafdf | 2900 | return length; |
wolfSSL | 13:80fb167dafdf | 2901 | } |
wolfSSL | 13:80fb167dafdf | 2902 | |
wolfSSL | 13:80fb167dafdf | 2903 | static word16 TLSX_EllipticCurve_WriteR(EllipticCurve* curve, byte* output); |
wolfSSL | 13:80fb167dafdf | 2904 | static word16 TLSX_EllipticCurve_WriteR(EllipticCurve* curve, byte* output) |
wolfSSL | 13:80fb167dafdf | 2905 | { |
wolfSSL | 13:80fb167dafdf | 2906 | word16 offset = 0; |
wolfSSL | 13:80fb167dafdf | 2907 | |
wolfSSL | 13:80fb167dafdf | 2908 | if (!curve) |
wolfSSL | 13:80fb167dafdf | 2909 | return offset; |
wolfSSL | 13:80fb167dafdf | 2910 | |
wolfSSL | 13:80fb167dafdf | 2911 | offset = TLSX_EllipticCurve_WriteR(curve->next, output); |
wolfSSL | 13:80fb167dafdf | 2912 | c16toa(curve->name, output + offset); |
wolfSSL | 13:80fb167dafdf | 2913 | |
wolfSSL | 13:80fb167dafdf | 2914 | return OPAQUE16_LEN + offset; |
wolfSSL | 13:80fb167dafdf | 2915 | } |
wolfSSL | 13:80fb167dafdf | 2916 | |
wolfSSL | 13:80fb167dafdf | 2917 | static word16 TLSX_EllipticCurve_Write(EllipticCurve* list, byte* output) |
wolfSSL | 13:80fb167dafdf | 2918 | { |
wolfSSL | 13:80fb167dafdf | 2919 | word16 length = TLSX_EllipticCurve_WriteR(list, output + OPAQUE16_LEN); |
wolfSSL | 13:80fb167dafdf | 2920 | |
wolfSSL | 13:80fb167dafdf | 2921 | c16toa(length, output); /* writing list length */ |
wolfSSL | 13:80fb167dafdf | 2922 | |
wolfSSL | 13:80fb167dafdf | 2923 | return OPAQUE16_LEN + length; |
wolfSSL | 13:80fb167dafdf | 2924 | } |
wolfSSL | 13:80fb167dafdf | 2925 | |
wolfSSL | 13:80fb167dafdf | 2926 | #endif /* NO_WOLFSSL_CLIENT */ |
wolfSSL | 13:80fb167dafdf | 2927 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 2928 | |
wolfSSL | 13:80fb167dafdf | 2929 | static int TLSX_EllipticCurve_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:80fb167dafdf | 2930 | byte isRequest) |
wolfSSL | 13:80fb167dafdf | 2931 | { |
wolfSSL | 13:80fb167dafdf | 2932 | word16 offset; |
wolfSSL | 13:80fb167dafdf | 2933 | word16 name; |
wolfSSL | 13:80fb167dafdf | 2934 | int r; |
wolfSSL | 13:80fb167dafdf | 2935 | |
wolfSSL | 13:80fb167dafdf | 2936 | (void) isRequest; /* shut up compiler! */ |
wolfSSL | 13:80fb167dafdf | 2937 | |
wolfSSL | 13:80fb167dafdf | 2938 | if (OPAQUE16_LEN > length || length % OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 2939 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 2940 | |
wolfSSL | 13:80fb167dafdf | 2941 | ato16(input, &offset); |
wolfSSL | 13:80fb167dafdf | 2942 | |
wolfSSL | 13:80fb167dafdf | 2943 | /* validating curve list length */ |
wolfSSL | 13:80fb167dafdf | 2944 | if (length != OPAQUE16_LEN + offset) |
wolfSSL | 13:80fb167dafdf | 2945 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 2946 | |
wolfSSL | 13:80fb167dafdf | 2947 | while (offset) { |
wolfSSL | 13:80fb167dafdf | 2948 | ato16(input + offset, &name); |
wolfSSL | 13:80fb167dafdf | 2949 | offset -= OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 2950 | |
wolfSSL | 13:80fb167dafdf | 2951 | r = TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 2952 | |
wolfSSL | 13:80fb167dafdf | 2953 | if (r != SSL_SUCCESS) return r; /* throw error */ |
wolfSSL | 13:80fb167dafdf | 2954 | } |
wolfSSL | 13:80fb167dafdf | 2955 | |
wolfSSL | 13:80fb167dafdf | 2956 | return 0; |
wolfSSL | 13:80fb167dafdf | 2957 | } |
wolfSSL | 13:80fb167dafdf | 2958 | |
wolfSSL | 13:80fb167dafdf | 2959 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 2960 | /* Searches the supported groups extension for the specified named group. |
wolfSSL | 13:80fb167dafdf | 2961 | * |
wolfSSL | 13:80fb167dafdf | 2962 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 2963 | * name The group name to match. |
wolfSSL | 13:80fb167dafdf | 2964 | * returns 1 when the extension has the group name and 0 otherwise. |
wolfSSL | 13:80fb167dafdf | 2965 | */ |
wolfSSL | 13:80fb167dafdf | 2966 | static int TLSX_SupportedGroups_Find(WOLFSSL* ssl, word16 name) |
wolfSSL | 13:80fb167dafdf | 2967 | { |
wolfSSL | 13:80fb167dafdf | 2968 | TLSX* extension; |
wolfSSL | 13:80fb167dafdf | 2969 | EllipticCurve* curve = NULL; |
wolfSSL | 13:80fb167dafdf | 2970 | |
wolfSSL | 13:80fb167dafdf | 2971 | if ((extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS)) == NULL) |
wolfSSL | 13:80fb167dafdf | 2972 | return 0; |
wolfSSL | 13:80fb167dafdf | 2973 | |
wolfSSL | 13:80fb167dafdf | 2974 | for (curve = (EllipticCurve*)extension->data; curve; curve = curve->next) { |
wolfSSL | 13:80fb167dafdf | 2975 | if (curve->name == name) |
wolfSSL | 13:80fb167dafdf | 2976 | return 1; |
wolfSSL | 13:80fb167dafdf | 2977 | } |
wolfSSL | 13:80fb167dafdf | 2978 | return 0; |
wolfSSL | 13:80fb167dafdf | 2979 | } |
wolfSSL | 13:80fb167dafdf | 2980 | #endif /* WOLFSSL_TLS13 */ |
wolfSSL | 13:80fb167dafdf | 2981 | |
wolfSSL | 13:80fb167dafdf | 2982 | int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) { |
wolfSSL | 13:80fb167dafdf | 2983 | TLSX* extension = (first == ECC_BYTE || first == CHACHA_BYTE) |
wolfSSL | 13:80fb167dafdf | 2984 | ? TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS) |
wolfSSL | 13:80fb167dafdf | 2985 | : NULL; |
wolfSSL | 13:80fb167dafdf | 2986 | EllipticCurve* curve = NULL; |
wolfSSL | 13:80fb167dafdf | 2987 | word32 oid = 0; |
wolfSSL | 13:80fb167dafdf | 2988 | word32 defOid = 0; |
wolfSSL | 13:80fb167dafdf | 2989 | word32 defSz = 80; /* Maximum known curve size is 66. */ |
wolfSSL | 13:80fb167dafdf | 2990 | word32 nextOid = 0; |
wolfSSL | 13:80fb167dafdf | 2991 | word32 nextSz = 80; /* Maximum known curve size is 66. */ |
wolfSSL | 13:80fb167dafdf | 2992 | word32 currOid = ssl->ecdhCurveOID; |
wolfSSL | 13:80fb167dafdf | 2993 | int ephmSuite = 0; |
wolfSSL | 13:80fb167dafdf | 2994 | word16 octets = 0; /* according to 'ecc_set_type ecc_sets[];' */ |
wolfSSL | 13:80fb167dafdf | 2995 | int sig = 0; /* validate signature */ |
wolfSSL | 13:80fb167dafdf | 2996 | int key = 0; /* validate key */ |
wolfSSL | 13:80fb167dafdf | 2997 | |
wolfSSL | 13:80fb167dafdf | 2998 | (void)oid; |
wolfSSL | 13:80fb167dafdf | 2999 | |
wolfSSL | 13:80fb167dafdf | 3000 | if (!extension) |
wolfSSL | 13:80fb167dafdf | 3001 | return 1; /* no suite restriction */ |
wolfSSL | 13:80fb167dafdf | 3002 | |
wolfSSL | 13:80fb167dafdf | 3003 | for (curve = (EllipticCurve*)extension->data; |
wolfSSL | 13:80fb167dafdf | 3004 | curve && !(sig && key); |
wolfSSL | 13:80fb167dafdf | 3005 | curve = curve->next) { |
wolfSSL | 13:80fb167dafdf | 3006 | |
wolfSSL | 13:80fb167dafdf | 3007 | /* find supported curve */ |
wolfSSL | 13:80fb167dafdf | 3008 | switch (curve->name) { |
wolfSSL | 13:80fb167dafdf | 3009 | #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 3010 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 3011 | case WOLFSSL_ECC_SECP160R1: |
wolfSSL | 13:80fb167dafdf | 3012 | oid = ECC_SECP160R1_OID; |
wolfSSL | 13:80fb167dafdf | 3013 | octets = 20; |
wolfSSL | 13:80fb167dafdf | 3014 | break; |
wolfSSL | 13:80fb167dafdf | 3015 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:80fb167dafdf | 3016 | #ifdef HAVE_ECC_SECPR2 |
wolfSSL | 13:80fb167dafdf | 3017 | case WOLFSSL_ECC_SECP160R2: |
wolfSSL | 13:80fb167dafdf | 3018 | oid = ECC_SECP160R2_OID; |
wolfSSL | 13:80fb167dafdf | 3019 | octets = 20; |
wolfSSL | 13:80fb167dafdf | 3020 | break; |
wolfSSL | 13:80fb167dafdf | 3021 | #endif /* HAVE_ECC_SECPR2 */ |
wolfSSL | 13:80fb167dafdf | 3022 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:80fb167dafdf | 3023 | case WOLFSSL_ECC_SECP160K1: |
wolfSSL | 13:80fb167dafdf | 3024 | oid = ECC_SECP160K1_OID; |
wolfSSL | 13:80fb167dafdf | 3025 | octets = 20; |
wolfSSL | 13:80fb167dafdf | 3026 | break; |
wolfSSL | 13:80fb167dafdf | 3027 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 13:80fb167dafdf | 3028 | #endif |
wolfSSL | 13:80fb167dafdf | 3029 | #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 3030 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 3031 | case WOLFSSL_ECC_SECP192R1: |
wolfSSL | 13:80fb167dafdf | 3032 | oid = ECC_SECP192R1_OID; |
wolfSSL | 13:80fb167dafdf | 3033 | octets = 24; |
wolfSSL | 13:80fb167dafdf | 3034 | break; |
wolfSSL | 13:80fb167dafdf | 3035 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:80fb167dafdf | 3036 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:80fb167dafdf | 3037 | case WOLFSSL_ECC_SECP192K1: |
wolfSSL | 13:80fb167dafdf | 3038 | oid = ECC_SECP192K1_OID; |
wolfSSL | 13:80fb167dafdf | 3039 | octets = 24; |
wolfSSL | 13:80fb167dafdf | 3040 | break; |
wolfSSL | 13:80fb167dafdf | 3041 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 13:80fb167dafdf | 3042 | #endif |
wolfSSL | 13:80fb167dafdf | 3043 | #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 3044 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 3045 | case WOLFSSL_ECC_SECP224R1: |
wolfSSL | 13:80fb167dafdf | 3046 | oid = ECC_SECP224R1_OID; |
wolfSSL | 13:80fb167dafdf | 3047 | octets = 28; |
wolfSSL | 13:80fb167dafdf | 3048 | break; |
wolfSSL | 13:80fb167dafdf | 3049 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:80fb167dafdf | 3050 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:80fb167dafdf | 3051 | case WOLFSSL_ECC_SECP224K1: |
wolfSSL | 13:80fb167dafdf | 3052 | oid = ECC_SECP224K1_OID; |
wolfSSL | 13:80fb167dafdf | 3053 | octets = 28; |
wolfSSL | 13:80fb167dafdf | 3054 | break; |
wolfSSL | 13:80fb167dafdf | 3055 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 13:80fb167dafdf | 3056 | #endif |
wolfSSL | 13:80fb167dafdf | 3057 | #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 3058 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 3059 | case WOLFSSL_ECC_SECP256R1: |
wolfSSL | 13:80fb167dafdf | 3060 | oid = ECC_SECP256R1_OID; |
wolfSSL | 13:80fb167dafdf | 3061 | octets = 32; |
wolfSSL | 13:80fb167dafdf | 3062 | break; |
wolfSSL | 13:80fb167dafdf | 3063 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:80fb167dafdf | 3064 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:80fb167dafdf | 3065 | case WOLFSSL_ECC_SECP256K1: |
wolfSSL | 13:80fb167dafdf | 3066 | oid = ECC_SECP256K1_OID; |
wolfSSL | 13:80fb167dafdf | 3067 | octets = 32; |
wolfSSL | 13:80fb167dafdf | 3068 | break; |
wolfSSL | 13:80fb167dafdf | 3069 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 13:80fb167dafdf | 3070 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 13:80fb167dafdf | 3071 | case WOLFSSL_ECC_BRAINPOOLP256R1: |
wolfSSL | 13:80fb167dafdf | 3072 | oid = ECC_BRAINPOOLP256R1_OID; |
wolfSSL | 13:80fb167dafdf | 3073 | octets = 32; |
wolfSSL | 13:80fb167dafdf | 3074 | break; |
wolfSSL | 13:80fb167dafdf | 3075 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 13:80fb167dafdf | 3076 | #endif |
wolfSSL | 13:80fb167dafdf | 3077 | #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 3078 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 3079 | case WOLFSSL_ECC_SECP384R1: |
wolfSSL | 13:80fb167dafdf | 3080 | oid = ECC_SECP384R1_OID; |
wolfSSL | 13:80fb167dafdf | 3081 | octets = 48; |
wolfSSL | 13:80fb167dafdf | 3082 | break; |
wolfSSL | 13:80fb167dafdf | 3083 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:80fb167dafdf | 3084 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 13:80fb167dafdf | 3085 | case WOLFSSL_ECC_BRAINPOOLP384R1: |
wolfSSL | 13:80fb167dafdf | 3086 | oid = ECC_BRAINPOOLP384R1_OID; |
wolfSSL | 13:80fb167dafdf | 3087 | octets = 48; |
wolfSSL | 13:80fb167dafdf | 3088 | break; |
wolfSSL | 13:80fb167dafdf | 3089 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 13:80fb167dafdf | 3090 | #endif |
wolfSSL | 13:80fb167dafdf | 3091 | #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 3092 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 13:80fb167dafdf | 3093 | case WOLFSSL_ECC_BRAINPOOLP512R1: |
wolfSSL | 13:80fb167dafdf | 3094 | oid = ECC_BRAINPOOLP512R1_OID; |
wolfSSL | 13:80fb167dafdf | 3095 | octets = 64; |
wolfSSL | 13:80fb167dafdf | 3096 | break; |
wolfSSL | 13:80fb167dafdf | 3097 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 13:80fb167dafdf | 3098 | #endif |
wolfSSL | 13:80fb167dafdf | 3099 | #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 3100 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 3101 | case WOLFSSL_ECC_SECP521R1: |
wolfSSL | 13:80fb167dafdf | 3102 | oid = ECC_SECP521R1_OID; |
wolfSSL | 13:80fb167dafdf | 3103 | octets = 66; |
wolfSSL | 13:80fb167dafdf | 3104 | break; |
wolfSSL | 13:80fb167dafdf | 3105 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:80fb167dafdf | 3106 | #endif |
wolfSSL | 13:80fb167dafdf | 3107 | default: continue; /* unsupported curve */ |
wolfSSL | 13:80fb167dafdf | 3108 | } |
wolfSSL | 13:80fb167dafdf | 3109 | |
wolfSSL | 13:80fb167dafdf | 3110 | /* Set default Oid */ |
wolfSSL | 13:80fb167dafdf | 3111 | if (defOid == 0 && ssl->eccTempKeySz <= octets && defSz > octets) { |
wolfSSL | 13:80fb167dafdf | 3112 | defOid = oid; |
wolfSSL | 13:80fb167dafdf | 3113 | defSz = octets; |
wolfSSL | 13:80fb167dafdf | 3114 | } |
wolfSSL | 13:80fb167dafdf | 3115 | |
wolfSSL | 13:80fb167dafdf | 3116 | if (currOid == 0 && ssl->eccTempKeySz == octets) |
wolfSSL | 13:80fb167dafdf | 3117 | currOid = oid; |
wolfSSL | 13:80fb167dafdf | 3118 | if ((nextOid == 0 || nextSz > octets) && ssl->eccTempKeySz <= octets) { |
wolfSSL | 13:80fb167dafdf | 3119 | nextOid = oid; |
wolfSSL | 13:80fb167dafdf | 3120 | nextSz = octets; |
wolfSSL | 13:80fb167dafdf | 3121 | } |
wolfSSL | 13:80fb167dafdf | 3122 | |
wolfSSL | 13:80fb167dafdf | 3123 | if (first == ECC_BYTE) { |
wolfSSL | 13:80fb167dafdf | 3124 | switch (second) { |
wolfSSL | 13:80fb167dafdf | 3125 | /* ECDHE_ECDSA */ |
wolfSSL | 13:80fb167dafdf | 3126 | case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: |
wolfSSL | 13:80fb167dafdf | 3127 | case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: |
wolfSSL | 13:80fb167dafdf | 3128 | case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: |
wolfSSL | 13:80fb167dafdf | 3129 | case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: |
wolfSSL | 13:80fb167dafdf | 3130 | case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: |
wolfSSL | 13:80fb167dafdf | 3131 | case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: |
wolfSSL | 13:80fb167dafdf | 3132 | case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: |
wolfSSL | 13:80fb167dafdf | 3133 | case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: |
wolfSSL | 13:80fb167dafdf | 3134 | case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: |
wolfSSL | 13:80fb167dafdf | 3135 | case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: |
wolfSSL | 13:80fb167dafdf | 3136 | sig |= ssl->pkCurveOID == oid; |
wolfSSL | 13:80fb167dafdf | 3137 | key |= ssl->ecdhCurveOID == oid; |
wolfSSL | 13:80fb167dafdf | 3138 | ephmSuite = 1; |
wolfSSL | 13:80fb167dafdf | 3139 | break; |
wolfSSL | 13:80fb167dafdf | 3140 | |
wolfSSL | 13:80fb167dafdf | 3141 | #ifdef WOLFSSL_STATIC_DH |
wolfSSL | 13:80fb167dafdf | 3142 | /* ECDH_ECDSA */ |
wolfSSL | 13:80fb167dafdf | 3143 | case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: |
wolfSSL | 13:80fb167dafdf | 3144 | case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: |
wolfSSL | 13:80fb167dafdf | 3145 | case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: |
wolfSSL | 13:80fb167dafdf | 3146 | case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: |
wolfSSL | 13:80fb167dafdf | 3147 | case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: |
wolfSSL | 13:80fb167dafdf | 3148 | case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: |
wolfSSL | 13:80fb167dafdf | 3149 | case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: |
wolfSSL | 13:80fb167dafdf | 3150 | case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: |
wolfSSL | 13:80fb167dafdf | 3151 | sig |= ssl->pkCurveOID == oid; |
wolfSSL | 13:80fb167dafdf | 3152 | key |= ssl->pkCurveOID == oid; |
wolfSSL | 13:80fb167dafdf | 3153 | break; |
wolfSSL | 13:80fb167dafdf | 3154 | #endif /* WOLFSSL_STATIC_DH */ |
wolfSSL | 13:80fb167dafdf | 3155 | #ifndef NO_RSA |
wolfSSL | 13:80fb167dafdf | 3156 | /* ECDHE_RSA */ |
wolfSSL | 13:80fb167dafdf | 3157 | case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: |
wolfSSL | 13:80fb167dafdf | 3158 | case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: |
wolfSSL | 13:80fb167dafdf | 3159 | case TLS_ECDHE_RSA_WITH_RC4_128_SHA: |
wolfSSL | 13:80fb167dafdf | 3160 | case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: |
wolfSSL | 13:80fb167dafdf | 3161 | case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: |
wolfSSL | 13:80fb167dafdf | 3162 | case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: |
wolfSSL | 13:80fb167dafdf | 3163 | case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: |
wolfSSL | 13:80fb167dafdf | 3164 | case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: |
wolfSSL | 13:80fb167dafdf | 3165 | sig = 1; |
wolfSSL | 13:80fb167dafdf | 3166 | key |= ssl->ecdhCurveOID == oid; |
wolfSSL | 13:80fb167dafdf | 3167 | ephmSuite = 1; |
wolfSSL | 13:80fb167dafdf | 3168 | break; |
wolfSSL | 13:80fb167dafdf | 3169 | |
wolfSSL | 13:80fb167dafdf | 3170 | #ifdef WOLFSSL_STATIC_DH |
wolfSSL | 13:80fb167dafdf | 3171 | /* ECDH_RSA */ |
wolfSSL | 13:80fb167dafdf | 3172 | case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: |
wolfSSL | 13:80fb167dafdf | 3173 | case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: |
wolfSSL | 13:80fb167dafdf | 3174 | case TLS_ECDH_RSA_WITH_RC4_128_SHA: |
wolfSSL | 13:80fb167dafdf | 3175 | case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: |
wolfSSL | 13:80fb167dafdf | 3176 | case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: |
wolfSSL | 13:80fb167dafdf | 3177 | case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: |
wolfSSL | 13:80fb167dafdf | 3178 | case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: |
wolfSSL | 13:80fb167dafdf | 3179 | case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: |
wolfSSL | 13:80fb167dafdf | 3180 | sig = 1; |
wolfSSL | 13:80fb167dafdf | 3181 | key |= ssl->pkCurveOID == oid; |
wolfSSL | 13:80fb167dafdf | 3182 | break; |
wolfSSL | 13:80fb167dafdf | 3183 | #endif /* WOLFSSL_STATIC_DH */ |
wolfSSL | 13:80fb167dafdf | 3184 | #endif |
wolfSSL | 13:80fb167dafdf | 3185 | default: |
wolfSSL | 13:80fb167dafdf | 3186 | sig = 1; |
wolfSSL | 13:80fb167dafdf | 3187 | key = 1; |
wolfSSL | 13:80fb167dafdf | 3188 | break; |
wolfSSL | 13:80fb167dafdf | 3189 | } |
wolfSSL | 13:80fb167dafdf | 3190 | } |
wolfSSL | 13:80fb167dafdf | 3191 | |
wolfSSL | 13:80fb167dafdf | 3192 | /* ChaCha20-Poly1305 ECC cipher suites */ |
wolfSSL | 13:80fb167dafdf | 3193 | if (first == CHACHA_BYTE) { |
wolfSSL | 13:80fb167dafdf | 3194 | switch (second) { |
wolfSSL | 13:80fb167dafdf | 3195 | /* ECDHE_ECDSA */ |
wolfSSL | 13:80fb167dafdf | 3196 | case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 : |
wolfSSL | 13:80fb167dafdf | 3197 | case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : |
wolfSSL | 13:80fb167dafdf | 3198 | sig |= ssl->pkCurveOID == oid; |
wolfSSL | 13:80fb167dafdf | 3199 | key |= ssl->ecdhCurveOID == oid; |
wolfSSL | 13:80fb167dafdf | 3200 | ephmSuite = 1; |
wolfSSL | 13:80fb167dafdf | 3201 | break; |
wolfSSL | 13:80fb167dafdf | 3202 | #ifndef NO_RSA |
wolfSSL | 13:80fb167dafdf | 3203 | /* ECDHE_RSA */ |
wolfSSL | 13:80fb167dafdf | 3204 | case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 : |
wolfSSL | 13:80fb167dafdf | 3205 | case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : |
wolfSSL | 13:80fb167dafdf | 3206 | sig = 1; |
wolfSSL | 13:80fb167dafdf | 3207 | key |= ssl->ecdhCurveOID == oid; |
wolfSSL | 13:80fb167dafdf | 3208 | ephmSuite = 1; |
wolfSSL | 13:80fb167dafdf | 3209 | break; |
wolfSSL | 13:80fb167dafdf | 3210 | #endif |
wolfSSL | 13:80fb167dafdf | 3211 | default: |
wolfSSL | 13:80fb167dafdf | 3212 | sig = 1; |
wolfSSL | 13:80fb167dafdf | 3213 | key = 1; |
wolfSSL | 13:80fb167dafdf | 3214 | break; |
wolfSSL | 13:80fb167dafdf | 3215 | } |
wolfSSL | 13:80fb167dafdf | 3216 | } |
wolfSSL | 13:80fb167dafdf | 3217 | } |
wolfSSL | 13:80fb167dafdf | 3218 | |
wolfSSL | 13:80fb167dafdf | 3219 | /* Choose the default if it is at the required strength. */ |
wolfSSL | 13:80fb167dafdf | 3220 | if (ssl->ecdhCurveOID == 0 && defSz == ssl->eccTempKeySz) { |
wolfSSL | 13:80fb167dafdf | 3221 | key = 1; |
wolfSSL | 13:80fb167dafdf | 3222 | ssl->ecdhCurveOID = defOid; |
wolfSSL | 13:80fb167dafdf | 3223 | } |
wolfSSL | 13:80fb167dafdf | 3224 | /* Choose any curve at the required strength. */ |
wolfSSL | 13:80fb167dafdf | 3225 | if (ssl->ecdhCurveOID == 0) { |
wolfSSL | 13:80fb167dafdf | 3226 | key = 1; |
wolfSSL | 13:80fb167dafdf | 3227 | ssl->ecdhCurveOID = currOid; |
wolfSSL | 13:80fb167dafdf | 3228 | } |
wolfSSL | 13:80fb167dafdf | 3229 | /* Choose the default if it is at the next highest strength. */ |
wolfSSL | 13:80fb167dafdf | 3230 | if (ssl->ecdhCurveOID == 0 && defSz == nextSz) |
wolfSSL | 13:80fb167dafdf | 3231 | ssl->ecdhCurveOID = defOid; |
wolfSSL | 13:80fb167dafdf | 3232 | /* Choose any curve at the next highest strength. */ |
wolfSSL | 13:80fb167dafdf | 3233 | if (ssl->ecdhCurveOID == 0) |
wolfSSL | 13:80fb167dafdf | 3234 | ssl->ecdhCurveOID = nextOid; |
wolfSSL | 13:80fb167dafdf | 3235 | /* No curve and ephemeral ECC suite requires a matching curve. */ |
wolfSSL | 13:80fb167dafdf | 3236 | if (ssl->ecdhCurveOID == 0 && ephmSuite) |
wolfSSL | 13:80fb167dafdf | 3237 | key = 0; |
wolfSSL | 13:80fb167dafdf | 3238 | |
wolfSSL | 13:80fb167dafdf | 3239 | return sig && key; |
wolfSSL | 13:80fb167dafdf | 3240 | } |
wolfSSL | 13:80fb167dafdf | 3241 | |
wolfSSL | 13:80fb167dafdf | 3242 | #endif /* NO_WOLFSSL_SERVER */ |
wolfSSL | 13:80fb167dafdf | 3243 | |
wolfSSL | 13:80fb167dafdf | 3244 | int TLSX_UseSupportedCurve(TLSX** extensions, word16 name, void* heap) |
wolfSSL | 13:80fb167dafdf | 3245 | { |
wolfSSL | 13:80fb167dafdf | 3246 | TLSX* extension; |
wolfSSL | 13:80fb167dafdf | 3247 | EllipticCurve* curve = NULL; |
wolfSSL | 13:80fb167dafdf | 3248 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 3249 | |
wolfSSL | 13:80fb167dafdf | 3250 | if (extensions == NULL) |
wolfSSL | 13:80fb167dafdf | 3251 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 3252 | |
wolfSSL | 13:80fb167dafdf | 3253 | if ((ret = TLSX_EllipticCurve_Append(&curve, name, heap)) != 0) |
wolfSSL | 13:80fb167dafdf | 3254 | return ret; |
wolfSSL | 13:80fb167dafdf | 3255 | |
wolfSSL | 13:80fb167dafdf | 3256 | extension = TLSX_Find(*extensions, TLSX_SUPPORTED_GROUPS); |
wolfSSL | 13:80fb167dafdf | 3257 | if (!extension) { |
wolfSSL | 13:80fb167dafdf | 3258 | if ((ret = TLSX_Push(extensions, TLSX_SUPPORTED_GROUPS, curve, heap)) |
wolfSSL | 13:80fb167dafdf | 3259 | != 0) { |
wolfSSL | 13:80fb167dafdf | 3260 | XFREE(curve, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 3261 | return ret; |
wolfSSL | 13:80fb167dafdf | 3262 | } |
wolfSSL | 13:80fb167dafdf | 3263 | } |
wolfSSL | 13:80fb167dafdf | 3264 | else { |
wolfSSL | 13:80fb167dafdf | 3265 | /* push new EllipticCurve object to extension data. */ |
wolfSSL | 13:80fb167dafdf | 3266 | curve->next = (EllipticCurve*)extension->data; |
wolfSSL | 13:80fb167dafdf | 3267 | extension->data = (void*)curve; |
wolfSSL | 13:80fb167dafdf | 3268 | |
wolfSSL | 13:80fb167dafdf | 3269 | /* look for another curve of the same name to remove (replacement) */ |
wolfSSL | 13:80fb167dafdf | 3270 | do { |
wolfSSL | 13:80fb167dafdf | 3271 | if (curve->next && curve->next->name == name) { |
wolfSSL | 13:80fb167dafdf | 3272 | EllipticCurve *next = curve->next; |
wolfSSL | 13:80fb167dafdf | 3273 | |
wolfSSL | 13:80fb167dafdf | 3274 | curve->next = next->next; |
wolfSSL | 13:80fb167dafdf | 3275 | XFREE(next, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 3276 | |
wolfSSL | 13:80fb167dafdf | 3277 | break; |
wolfSSL | 13:80fb167dafdf | 3278 | } |
wolfSSL | 13:80fb167dafdf | 3279 | } while ((curve = curve->next)); |
wolfSSL | 13:80fb167dafdf | 3280 | } |
wolfSSL | 13:80fb167dafdf | 3281 | |
wolfSSL | 13:80fb167dafdf | 3282 | return SSL_SUCCESS; |
wolfSSL | 13:80fb167dafdf | 3283 | } |
wolfSSL | 13:80fb167dafdf | 3284 | |
wolfSSL | 13:80fb167dafdf | 3285 | #define EC_FREE_ALL TLSX_EllipticCurve_FreeAll |
wolfSSL | 13:80fb167dafdf | 3286 | #define EC_VALIDATE_REQUEST TLSX_EllipticCurve_ValidateRequest |
wolfSSL | 13:80fb167dafdf | 3287 | |
wolfSSL | 13:80fb167dafdf | 3288 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:80fb167dafdf | 3289 | #define EC_GET_SIZE TLSX_EllipticCurve_GetSize |
wolfSSL | 13:80fb167dafdf | 3290 | #define EC_WRITE TLSX_EllipticCurve_Write |
wolfSSL | 13:80fb167dafdf | 3291 | #else |
wolfSSL | 13:80fb167dafdf | 3292 | #define EC_GET_SIZE(list) 0 |
wolfSSL | 13:80fb167dafdf | 3293 | #define EC_WRITE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 3294 | #endif |
wolfSSL | 13:80fb167dafdf | 3295 | |
wolfSSL | 13:80fb167dafdf | 3296 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 3297 | #define EC_PARSE TLSX_EllipticCurve_Parse |
wolfSSL | 13:80fb167dafdf | 3298 | #else |
wolfSSL | 13:80fb167dafdf | 3299 | #define EC_PARSE(a, b, c, d) 0 |
wolfSSL | 13:80fb167dafdf | 3300 | #endif |
wolfSSL | 13:80fb167dafdf | 3301 | |
wolfSSL | 13:80fb167dafdf | 3302 | #else |
wolfSSL | 13:80fb167dafdf | 3303 | |
wolfSSL | 13:80fb167dafdf | 3304 | #define EC_FREE_ALL(list, heap) |
wolfSSL | 13:80fb167dafdf | 3305 | #define EC_GET_SIZE(list) 0 |
wolfSSL | 13:80fb167dafdf | 3306 | #define EC_WRITE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 3307 | #define EC_PARSE(a, b, c, d) 0 |
wolfSSL | 13:80fb167dafdf | 3308 | #define EC_VALIDATE_REQUEST(a, b) |
wolfSSL | 13:80fb167dafdf | 3309 | |
wolfSSL | 13:80fb167dafdf | 3310 | #endif /* HAVE_SUPPORTED_CURVES */ |
wolfSSL | 13:80fb167dafdf | 3311 | |
wolfSSL | 13:80fb167dafdf | 3312 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 3313 | /* Renegotiation Indication */ |
wolfSSL | 13:80fb167dafdf | 3314 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 3315 | |
wolfSSL | 13:80fb167dafdf | 3316 | #if defined(HAVE_SECURE_RENEGOTIATION) \ |
wolfSSL | 13:80fb167dafdf | 3317 | || defined(HAVE_SERVER_RENEGOTIATION_INFO) |
wolfSSL | 13:80fb167dafdf | 3318 | |
wolfSSL | 13:80fb167dafdf | 3319 | static byte TLSX_SecureRenegotiation_GetSize(SecureRenegotiation* data, |
wolfSSL | 13:80fb167dafdf | 3320 | int isRequest) |
wolfSSL | 13:80fb167dafdf | 3321 | { |
wolfSSL | 13:80fb167dafdf | 3322 | byte length = OPAQUE8_LEN; /* empty info length */ |
wolfSSL | 13:80fb167dafdf | 3323 | |
wolfSSL | 13:80fb167dafdf | 3324 | /* data will be NULL for HAVE_SERVER_RENEGOTIATION_INFO only */ |
wolfSSL | 13:80fb167dafdf | 3325 | if (data && data->enabled) { |
wolfSSL | 13:80fb167dafdf | 3326 | /* client sends client_verify_data only */ |
wolfSSL | 13:80fb167dafdf | 3327 | length += TLS_FINISHED_SZ; |
wolfSSL | 13:80fb167dafdf | 3328 | |
wolfSSL | 13:80fb167dafdf | 3329 | /* server also sends server_verify_data */ |
wolfSSL | 13:80fb167dafdf | 3330 | if (!isRequest) |
wolfSSL | 13:80fb167dafdf | 3331 | length += TLS_FINISHED_SZ; |
wolfSSL | 13:80fb167dafdf | 3332 | } |
wolfSSL | 13:80fb167dafdf | 3333 | |
wolfSSL | 13:80fb167dafdf | 3334 | return length; |
wolfSSL | 13:80fb167dafdf | 3335 | } |
wolfSSL | 13:80fb167dafdf | 3336 | |
wolfSSL | 13:80fb167dafdf | 3337 | static word16 TLSX_SecureRenegotiation_Write(SecureRenegotiation* data, |
wolfSSL | 13:80fb167dafdf | 3338 | byte* output, int isRequest) |
wolfSSL | 13:80fb167dafdf | 3339 | { |
wolfSSL | 13:80fb167dafdf | 3340 | word16 offset = OPAQUE8_LEN; /* RenegotiationInfo length */ |
wolfSSL | 13:80fb167dafdf | 3341 | |
wolfSSL | 13:80fb167dafdf | 3342 | if (data && data->enabled) { |
wolfSSL | 13:80fb167dafdf | 3343 | /* client sends client_verify_data only */ |
wolfSSL | 13:80fb167dafdf | 3344 | XMEMCPY(output + offset, data->client_verify_data, TLS_FINISHED_SZ); |
wolfSSL | 13:80fb167dafdf | 3345 | offset += TLS_FINISHED_SZ; |
wolfSSL | 13:80fb167dafdf | 3346 | |
wolfSSL | 13:80fb167dafdf | 3347 | /* server also sends server_verify_data */ |
wolfSSL | 13:80fb167dafdf | 3348 | if (!isRequest) { |
wolfSSL | 13:80fb167dafdf | 3349 | XMEMCPY(output + offset, data->server_verify_data, TLS_FINISHED_SZ); |
wolfSSL | 13:80fb167dafdf | 3350 | offset += TLS_FINISHED_SZ; |
wolfSSL | 13:80fb167dafdf | 3351 | } |
wolfSSL | 13:80fb167dafdf | 3352 | } |
wolfSSL | 13:80fb167dafdf | 3353 | |
wolfSSL | 13:80fb167dafdf | 3354 | output[0] = (byte)(offset - 1); /* info length - self */ |
wolfSSL | 13:80fb167dafdf | 3355 | |
wolfSSL | 13:80fb167dafdf | 3356 | return offset; |
wolfSSL | 13:80fb167dafdf | 3357 | } |
wolfSSL | 13:80fb167dafdf | 3358 | |
wolfSSL | 13:80fb167dafdf | 3359 | static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, byte* input, |
wolfSSL | 13:80fb167dafdf | 3360 | word16 length, byte isRequest) |
wolfSSL | 13:80fb167dafdf | 3361 | { |
wolfSSL | 13:80fb167dafdf | 3362 | int ret = SECURE_RENEGOTIATION_E; |
wolfSSL | 13:80fb167dafdf | 3363 | |
wolfSSL | 13:80fb167dafdf | 3364 | if (length >= OPAQUE8_LEN) { |
wolfSSL | 13:80fb167dafdf | 3365 | if (ssl->secure_renegotiation == NULL) { |
wolfSSL | 13:80fb167dafdf | 3366 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 3367 | if (isRequest && *input == 0) { |
wolfSSL | 13:80fb167dafdf | 3368 | #ifdef HAVE_SERVER_RENEGOTIATION_INFO |
wolfSSL | 13:80fb167dafdf | 3369 | if (length == OPAQUE8_LEN) { |
wolfSSL | 13:80fb167dafdf | 3370 | if (TLSX_Find(ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 3371 | TLSX_RENEGOTIATION_INFO) == NULL) { |
wolfSSL | 13:80fb167dafdf | 3372 | ret = TLSX_AddEmptyRenegotiationInfo(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 3373 | ssl->heap); |
wolfSSL | 13:80fb167dafdf | 3374 | if (ret == SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 3375 | ret = 0; |
wolfSSL | 13:80fb167dafdf | 3376 | |
wolfSSL | 13:80fb167dafdf | 3377 | } else { |
wolfSSL | 13:80fb167dafdf | 3378 | ret = 0; |
wolfSSL | 13:80fb167dafdf | 3379 | } |
wolfSSL | 13:80fb167dafdf | 3380 | } |
wolfSSL | 13:80fb167dafdf | 3381 | #else |
wolfSSL | 13:80fb167dafdf | 3382 | ret = 0; /* don't reply, user didn't enable */ |
wolfSSL | 13:80fb167dafdf | 3383 | #endif /* HAVE_SERVER_RENEGOTIATION_INFO */ |
wolfSSL | 13:80fb167dafdf | 3384 | } |
wolfSSL | 13:80fb167dafdf | 3385 | #ifdef HAVE_SERVER_RENEGOTIATION_INFO |
wolfSSL | 13:80fb167dafdf | 3386 | else if (!isRequest) { |
wolfSSL | 13:80fb167dafdf | 3387 | /* don't do anything on client side */ |
wolfSSL | 13:80fb167dafdf | 3388 | ret = 0; |
wolfSSL | 13:80fb167dafdf | 3389 | } |
wolfSSL | 13:80fb167dafdf | 3390 | #endif |
wolfSSL | 13:80fb167dafdf | 3391 | #endif |
wolfSSL | 13:80fb167dafdf | 3392 | } |
wolfSSL | 13:80fb167dafdf | 3393 | else if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 3394 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 3395 | if (*input == TLS_FINISHED_SZ) { |
wolfSSL | 13:80fb167dafdf | 3396 | /* TODO compare client_verify_data */ |
wolfSSL | 13:80fb167dafdf | 3397 | ret = 0; |
wolfSSL | 13:80fb167dafdf | 3398 | } |
wolfSSL | 13:80fb167dafdf | 3399 | #endif |
wolfSSL | 13:80fb167dafdf | 3400 | } |
wolfSSL | 13:80fb167dafdf | 3401 | else { |
wolfSSL | 13:80fb167dafdf | 3402 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:80fb167dafdf | 3403 | if (!ssl->secure_renegotiation->enabled) { |
wolfSSL | 13:80fb167dafdf | 3404 | if (*input == 0) { |
wolfSSL | 13:80fb167dafdf | 3405 | ssl->secure_renegotiation->enabled = 1; |
wolfSSL | 13:80fb167dafdf | 3406 | ret = 0; |
wolfSSL | 13:80fb167dafdf | 3407 | } |
wolfSSL | 13:80fb167dafdf | 3408 | } |
wolfSSL | 13:80fb167dafdf | 3409 | else if (*input == 2 * TLS_FINISHED_SZ && |
wolfSSL | 13:80fb167dafdf | 3410 | length == 2 * TLS_FINISHED_SZ + OPAQUE8_LEN) { |
wolfSSL | 13:80fb167dafdf | 3411 | input++; /* get past size */ |
wolfSSL | 13:80fb167dafdf | 3412 | |
wolfSSL | 13:80fb167dafdf | 3413 | /* validate client and server verify data */ |
wolfSSL | 13:80fb167dafdf | 3414 | if (XMEMCMP(input, |
wolfSSL | 13:80fb167dafdf | 3415 | ssl->secure_renegotiation->client_verify_data, |
wolfSSL | 13:80fb167dafdf | 3416 | TLS_FINISHED_SZ) == 0 && |
wolfSSL | 13:80fb167dafdf | 3417 | XMEMCMP(input + TLS_FINISHED_SZ, |
wolfSSL | 13:80fb167dafdf | 3418 | ssl->secure_renegotiation->server_verify_data, |
wolfSSL | 13:80fb167dafdf | 3419 | TLS_FINISHED_SZ) == 0) { |
wolfSSL | 13:80fb167dafdf | 3420 | WOLFSSL_MSG("SCR client and server verify data match"); |
wolfSSL | 13:80fb167dafdf | 3421 | ret = 0; /* verified */ |
wolfSSL | 13:80fb167dafdf | 3422 | } else { |
wolfSSL | 13:80fb167dafdf | 3423 | /* already in error state */ |
wolfSSL | 13:80fb167dafdf | 3424 | WOLFSSL_MSG("SCR client and server verify data Failure"); |
wolfSSL | 13:80fb167dafdf | 3425 | } |
wolfSSL | 13:80fb167dafdf | 3426 | } |
wolfSSL | 13:80fb167dafdf | 3427 | #endif |
wolfSSL | 13:80fb167dafdf | 3428 | } |
wolfSSL | 13:80fb167dafdf | 3429 | } |
wolfSSL | 13:80fb167dafdf | 3430 | |
wolfSSL | 13:80fb167dafdf | 3431 | if (ret != 0) { |
wolfSSL | 13:80fb167dafdf | 3432 | SendAlert(ssl, alert_fatal, handshake_failure); |
wolfSSL | 13:80fb167dafdf | 3433 | } |
wolfSSL | 13:80fb167dafdf | 3434 | |
wolfSSL | 13:80fb167dafdf | 3435 | return ret; |
wolfSSL | 13:80fb167dafdf | 3436 | } |
wolfSSL | 13:80fb167dafdf | 3437 | |
wolfSSL | 13:80fb167dafdf | 3438 | int TLSX_UseSecureRenegotiation(TLSX** extensions, void* heap) |
wolfSSL | 13:80fb167dafdf | 3439 | { |
wolfSSL | 13:80fb167dafdf | 3440 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 3441 | SecureRenegotiation* data = NULL; |
wolfSSL | 13:80fb167dafdf | 3442 | |
wolfSSL | 13:80fb167dafdf | 3443 | data = (SecureRenegotiation*)XMALLOC(sizeof(SecureRenegotiation), heap, |
wolfSSL | 13:80fb167dafdf | 3444 | DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 3445 | if (data == NULL) |
wolfSSL | 13:80fb167dafdf | 3446 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 3447 | |
wolfSSL | 13:80fb167dafdf | 3448 | XMEMSET(data, 0, sizeof(SecureRenegotiation)); |
wolfSSL | 13:80fb167dafdf | 3449 | |
wolfSSL | 13:80fb167dafdf | 3450 | ret = TLSX_Push(extensions, TLSX_RENEGOTIATION_INFO, data, heap); |
wolfSSL | 13:80fb167dafdf | 3451 | if (ret != 0) { |
wolfSSL | 13:80fb167dafdf | 3452 | XFREE(data, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 3453 | return ret; |
wolfSSL | 13:80fb167dafdf | 3454 | } |
wolfSSL | 13:80fb167dafdf | 3455 | |
wolfSSL | 13:80fb167dafdf | 3456 | return SSL_SUCCESS; |
wolfSSL | 13:80fb167dafdf | 3457 | } |
wolfSSL | 13:80fb167dafdf | 3458 | |
wolfSSL | 13:80fb167dafdf | 3459 | #ifdef HAVE_SERVER_RENEGOTIATION_INFO |
wolfSSL | 13:80fb167dafdf | 3460 | |
wolfSSL | 13:80fb167dafdf | 3461 | int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions, void* heap) |
wolfSSL | 13:80fb167dafdf | 3462 | { |
wolfSSL | 13:80fb167dafdf | 3463 | int ret; |
wolfSSL | 13:80fb167dafdf | 3464 | |
wolfSSL | 13:80fb167dafdf | 3465 | ret = TLSX_Push(extensions, TLSX_RENEGOTIATION_INFO, NULL, heap); |
wolfSSL | 13:80fb167dafdf | 3466 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 3467 | return ret; |
wolfSSL | 13:80fb167dafdf | 3468 | |
wolfSSL | 13:80fb167dafdf | 3469 | /* send empty renegotiation_info extension */ |
wolfSSL | 13:80fb167dafdf | 3470 | TLSX* ext = TLSX_Find(*extensions, TLSX_RENEGOTIATION_INFO); |
wolfSSL | 13:80fb167dafdf | 3471 | if (ext) |
wolfSSL | 13:80fb167dafdf | 3472 | ext->resp = 1; |
wolfSSL | 13:80fb167dafdf | 3473 | |
wolfSSL | 13:80fb167dafdf | 3474 | return SSL_SUCCESS; |
wolfSSL | 13:80fb167dafdf | 3475 | } |
wolfSSL | 13:80fb167dafdf | 3476 | |
wolfSSL | 13:80fb167dafdf | 3477 | #endif /* HAVE_SERVER_RENEGOTIATION_INFO */ |
wolfSSL | 13:80fb167dafdf | 3478 | |
wolfSSL | 13:80fb167dafdf | 3479 | |
wolfSSL | 13:80fb167dafdf | 3480 | #define SCR_FREE_ALL(data, heap) XFREE(data, (heap), DYNAMIC_TYPE_TLSX) |
wolfSSL | 13:80fb167dafdf | 3481 | #define SCR_GET_SIZE TLSX_SecureRenegotiation_GetSize |
wolfSSL | 13:80fb167dafdf | 3482 | #define SCR_WRITE TLSX_SecureRenegotiation_Write |
wolfSSL | 13:80fb167dafdf | 3483 | #define SCR_PARSE TLSX_SecureRenegotiation_Parse |
wolfSSL | 13:80fb167dafdf | 3484 | |
wolfSSL | 13:80fb167dafdf | 3485 | #else |
wolfSSL | 13:80fb167dafdf | 3486 | |
wolfSSL | 13:80fb167dafdf | 3487 | #define SCR_FREE_ALL(a, heap) |
wolfSSL | 13:80fb167dafdf | 3488 | #define SCR_GET_SIZE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 3489 | #define SCR_WRITE(a, b, c) 0 |
wolfSSL | 13:80fb167dafdf | 3490 | #define SCR_PARSE(a, b, c, d) 0 |
wolfSSL | 13:80fb167dafdf | 3491 | |
wolfSSL | 13:80fb167dafdf | 3492 | #endif /* HAVE_SECURE_RENEGOTIATION */ |
wolfSSL | 13:80fb167dafdf | 3493 | |
wolfSSL | 13:80fb167dafdf | 3494 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 3495 | /* Session Tickets */ |
wolfSSL | 13:80fb167dafdf | 3496 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 3497 | |
wolfSSL | 13:80fb167dafdf | 3498 | #ifdef HAVE_SESSION_TICKET |
wolfSSL | 13:80fb167dafdf | 3499 | |
wolfSSL | 13:80fb167dafdf | 3500 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:80fb167dafdf | 3501 | static void TLSX_SessionTicket_ValidateRequest(WOLFSSL* ssl) |
wolfSSL | 13:80fb167dafdf | 3502 | { |
wolfSSL | 13:80fb167dafdf | 3503 | TLSX* extension = TLSX_Find(ssl->extensions, TLSX_SESSION_TICKET); |
wolfSSL | 13:80fb167dafdf | 3504 | SessionTicket* ticket = extension ? |
wolfSSL | 13:80fb167dafdf | 3505 | (SessionTicket*)extension->data : NULL; |
wolfSSL | 13:80fb167dafdf | 3506 | |
wolfSSL | 13:80fb167dafdf | 3507 | if (ticket) { |
wolfSSL | 13:80fb167dafdf | 3508 | /* TODO validate ticket timeout here! */ |
wolfSSL | 13:80fb167dafdf | 3509 | if (ticket->lifetime == 0xfffffff) { |
wolfSSL | 13:80fb167dafdf | 3510 | /* send empty ticket on timeout */ |
wolfSSL | 13:80fb167dafdf | 3511 | TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 3512 | } |
wolfSSL | 13:80fb167dafdf | 3513 | } |
wolfSSL | 13:80fb167dafdf | 3514 | } |
wolfSSL | 13:80fb167dafdf | 3515 | #endif /* NO_WOLFSSL_CLIENT */ |
wolfSSL | 13:80fb167dafdf | 3516 | |
wolfSSL | 13:80fb167dafdf | 3517 | |
wolfSSL | 13:80fb167dafdf | 3518 | static word16 TLSX_SessionTicket_GetSize(SessionTicket* ticket, int isRequest) |
wolfSSL | 13:80fb167dafdf | 3519 | { |
wolfSSL | 13:80fb167dafdf | 3520 | (void)isRequest; |
wolfSSL | 13:80fb167dafdf | 3521 | return ticket ? ticket->size : 0; |
wolfSSL | 13:80fb167dafdf | 3522 | } |
wolfSSL | 13:80fb167dafdf | 3523 | |
wolfSSL | 13:80fb167dafdf | 3524 | static word16 TLSX_SessionTicket_Write(SessionTicket* ticket, byte* output, |
wolfSSL | 13:80fb167dafdf | 3525 | int isRequest) |
wolfSSL | 13:80fb167dafdf | 3526 | { |
wolfSSL | 13:80fb167dafdf | 3527 | word16 offset = 0; /* empty ticket */ |
wolfSSL | 13:80fb167dafdf | 3528 | |
wolfSSL | 13:80fb167dafdf | 3529 | if (isRequest && ticket) { |
wolfSSL | 13:80fb167dafdf | 3530 | XMEMCPY(output + offset, ticket->data, ticket->size); |
wolfSSL | 13:80fb167dafdf | 3531 | offset += ticket->size; |
wolfSSL | 13:80fb167dafdf | 3532 | } |
wolfSSL | 13:80fb167dafdf | 3533 | |
wolfSSL | 13:80fb167dafdf | 3534 | return offset; |
wolfSSL | 13:80fb167dafdf | 3535 | } |
wolfSSL | 13:80fb167dafdf | 3536 | |
wolfSSL | 13:80fb167dafdf | 3537 | |
wolfSSL | 13:80fb167dafdf | 3538 | static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:80fb167dafdf | 3539 | byte isRequest) |
wolfSSL | 13:80fb167dafdf | 3540 | { |
wolfSSL | 13:80fb167dafdf | 3541 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 3542 | |
wolfSSL | 13:80fb167dafdf | 3543 | (void) input; /* avoid unused parameter if NO_WOLFSSL_SERVER defined */ |
wolfSSL | 13:80fb167dafdf | 3544 | |
wolfSSL | 13:80fb167dafdf | 3545 | if (!isRequest) { |
wolfSSL | 13:80fb167dafdf | 3546 | /* client side */ |
wolfSSL | 13:80fb167dafdf | 3547 | if (length != 0) |
wolfSSL | 13:80fb167dafdf | 3548 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 3549 | |
wolfSSL | 13:80fb167dafdf | 3550 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:80fb167dafdf | 3551 | ssl->expect_session_ticket = 1; |
wolfSSL | 13:80fb167dafdf | 3552 | #endif |
wolfSSL | 13:80fb167dafdf | 3553 | } |
wolfSSL | 13:80fb167dafdf | 3554 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 3555 | else { |
wolfSSL | 13:80fb167dafdf | 3556 | /* server side */ |
wolfSSL | 13:80fb167dafdf | 3557 | if (ssl->ctx->ticketEncCb == NULL) { |
wolfSSL | 13:80fb167dafdf | 3558 | WOLFSSL_MSG("Client sent session ticket, server has no callback"); |
wolfSSL | 13:80fb167dafdf | 3559 | return 0; |
wolfSSL | 13:80fb167dafdf | 3560 | } |
wolfSSL | 13:80fb167dafdf | 3561 | |
wolfSSL | 13:80fb167dafdf | 3562 | if (length == 0) { |
wolfSSL | 13:80fb167dafdf | 3563 | /* blank ticket */ |
wolfSSL | 13:80fb167dafdf | 3564 | ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 3565 | if (ret == SSL_SUCCESS) { |
wolfSSL | 13:80fb167dafdf | 3566 | ret = 0; |
wolfSSL | 13:80fb167dafdf | 3567 | TLSX_SetResponse(ssl, TLSX_SESSION_TICKET); /* send blank ticket */ |
wolfSSL | 13:80fb167dafdf | 3568 | ssl->options.createTicket = 1; /* will send ticket msg */ |
wolfSSL | 13:80fb167dafdf | 3569 | ssl->options.useTicket = 1; |
wolfSSL | 13:80fb167dafdf | 3570 | ssl->options.resuming = 0; /* no standard resumption */ |
wolfSSL | 13:80fb167dafdf | 3571 | ssl->arrays->sessionIDSz = 0; /* no echo on blank ticket */ |
wolfSSL | 13:80fb167dafdf | 3572 | } |
wolfSSL | 13:80fb167dafdf | 3573 | } else { |
wolfSSL | 13:80fb167dafdf | 3574 | /* got actual ticket from client */ |
wolfSSL | 13:80fb167dafdf | 3575 | ret = DoClientTicket(ssl, input, length); |
wolfSSL | 13:80fb167dafdf | 3576 | if (ret == WOLFSSL_TICKET_RET_OK) { /* use ticket to resume */ |
wolfSSL | 13:80fb167dafdf | 3577 | WOLFSSL_MSG("Using exisitng client ticket"); |
wolfSSL | 13:80fb167dafdf | 3578 | ssl->options.useTicket = 1; |
wolfSSL | 13:80fb167dafdf | 3579 | ssl->options.resuming = 1; |
wolfSSL | 13:80fb167dafdf | 3580 | } else if (ret == WOLFSSL_TICKET_RET_CREATE) { |
wolfSSL | 13:80fb167dafdf | 3581 | WOLFSSL_MSG("Using existing client ticket, creating new one"); |
wolfSSL | 13:80fb167dafdf | 3582 | ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 3583 | if (ret == SSL_SUCCESS) { |
wolfSSL | 13:80fb167dafdf | 3584 | ret = 0; |
wolfSSL | 13:80fb167dafdf | 3585 | TLSX_SetResponse(ssl, TLSX_SESSION_TICKET); |
wolfSSL | 13:80fb167dafdf | 3586 | /* send blank ticket */ |
wolfSSL | 13:80fb167dafdf | 3587 | ssl->options.createTicket = 1; /* will send ticket msg */ |
wolfSSL | 13:80fb167dafdf | 3588 | ssl->options.useTicket = 1; |
wolfSSL | 13:80fb167dafdf | 3589 | ssl->options.resuming = 1; |
wolfSSL | 13:80fb167dafdf | 3590 | } |
wolfSSL | 13:80fb167dafdf | 3591 | } else if (ret == WOLFSSL_TICKET_RET_REJECT) { |
wolfSSL | 13:80fb167dafdf | 3592 | WOLFSSL_MSG("Process client ticket rejected, not using"); |
wolfSSL | 13:80fb167dafdf | 3593 | ssl->options.rejectTicket = 1; |
wolfSSL | 13:80fb167dafdf | 3594 | ret = 0; /* not fatal */ |
wolfSSL | 13:80fb167dafdf | 3595 | } else if (ret == WOLFSSL_TICKET_RET_FATAL || ret < 0) { |
wolfSSL | 13:80fb167dafdf | 3596 | WOLFSSL_MSG("Process client ticket fatal error, not using"); |
wolfSSL | 13:80fb167dafdf | 3597 | } |
wolfSSL | 13:80fb167dafdf | 3598 | } |
wolfSSL | 13:80fb167dafdf | 3599 | } |
wolfSSL | 13:80fb167dafdf | 3600 | #endif /* NO_WOLFSSL_SERVER */ |
wolfSSL | 13:80fb167dafdf | 3601 | |
wolfSSL | 13:80fb167dafdf | 3602 | return ret; |
wolfSSL | 13:80fb167dafdf | 3603 | } |
wolfSSL | 13:80fb167dafdf | 3604 | |
wolfSSL | 13:80fb167dafdf | 3605 | WOLFSSL_LOCAL SessionTicket* TLSX_SessionTicket_Create(word32 lifetime, |
wolfSSL | 13:80fb167dafdf | 3606 | byte* data, word16 size, void* heap) |
wolfSSL | 13:80fb167dafdf | 3607 | { |
wolfSSL | 13:80fb167dafdf | 3608 | SessionTicket* ticket = (SessionTicket*)XMALLOC(sizeof(SessionTicket), |
wolfSSL | 13:80fb167dafdf | 3609 | heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 3610 | if (ticket) { |
wolfSSL | 13:80fb167dafdf | 3611 | ticket->data = (byte*)XMALLOC(size, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 3612 | if (ticket->data == NULL) { |
wolfSSL | 13:80fb167dafdf | 3613 | XFREE(ticket, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 3614 | return NULL; |
wolfSSL | 13:80fb167dafdf | 3615 | } |
wolfSSL | 13:80fb167dafdf | 3616 | |
wolfSSL | 13:80fb167dafdf | 3617 | XMEMCPY(ticket->data, data, size); |
wolfSSL | 13:80fb167dafdf | 3618 | ticket->size = size; |
wolfSSL | 13:80fb167dafdf | 3619 | ticket->lifetime = lifetime; |
wolfSSL | 13:80fb167dafdf | 3620 | } |
wolfSSL | 13:80fb167dafdf | 3621 | |
wolfSSL | 13:80fb167dafdf | 3622 | return ticket; |
wolfSSL | 13:80fb167dafdf | 3623 | } |
wolfSSL | 13:80fb167dafdf | 3624 | WOLFSSL_LOCAL void TLSX_SessionTicket_Free(SessionTicket* ticket, void* heap) |
wolfSSL | 13:80fb167dafdf | 3625 | { |
wolfSSL | 13:80fb167dafdf | 3626 | if (ticket) { |
wolfSSL | 13:80fb167dafdf | 3627 | XFREE(ticket->data, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 3628 | XFREE(ticket, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 3629 | } |
wolfSSL | 13:80fb167dafdf | 3630 | |
wolfSSL | 13:80fb167dafdf | 3631 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 3632 | } |
wolfSSL | 13:80fb167dafdf | 3633 | |
wolfSSL | 13:80fb167dafdf | 3634 | int TLSX_UseSessionTicket(TLSX** extensions, SessionTicket* ticket, void* heap) |
wolfSSL | 13:80fb167dafdf | 3635 | { |
wolfSSL | 13:80fb167dafdf | 3636 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 3637 | |
wolfSSL | 13:80fb167dafdf | 3638 | if (extensions == NULL) |
wolfSSL | 13:80fb167dafdf | 3639 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 3640 | |
wolfSSL | 13:80fb167dafdf | 3641 | /* If the ticket is NULL, the client will request a new ticket from the |
wolfSSL | 13:80fb167dafdf | 3642 | server. Otherwise, the client will use it in the next client hello. */ |
wolfSSL | 13:80fb167dafdf | 3643 | if ((ret = TLSX_Push(extensions, TLSX_SESSION_TICKET, (void*)ticket, heap)) |
wolfSSL | 13:80fb167dafdf | 3644 | != 0) |
wolfSSL | 13:80fb167dafdf | 3645 | return ret; |
wolfSSL | 13:80fb167dafdf | 3646 | |
wolfSSL | 13:80fb167dafdf | 3647 | return SSL_SUCCESS; |
wolfSSL | 13:80fb167dafdf | 3648 | } |
wolfSSL | 13:80fb167dafdf | 3649 | |
wolfSSL | 13:80fb167dafdf | 3650 | #define WOLF_STK_VALIDATE_REQUEST TLSX_SessionTicket_ValidateRequest |
wolfSSL | 13:80fb167dafdf | 3651 | #define WOLF_STK_GET_SIZE TLSX_SessionTicket_GetSize |
wolfSSL | 13:80fb167dafdf | 3652 | #define WOLF_STK_WRITE TLSX_SessionTicket_Write |
wolfSSL | 13:80fb167dafdf | 3653 | #define WOLF_STK_PARSE TLSX_SessionTicket_Parse |
wolfSSL | 13:80fb167dafdf | 3654 | #define WOLF_STK_FREE(stk, heap) TLSX_SessionTicket_Free((SessionTicket*)stk,(heap)) |
wolfSSL | 13:80fb167dafdf | 3655 | |
wolfSSL | 13:80fb167dafdf | 3656 | #else |
wolfSSL | 13:80fb167dafdf | 3657 | |
wolfSSL | 13:80fb167dafdf | 3658 | #define WOLF_STK_FREE(a, b) |
wolfSSL | 13:80fb167dafdf | 3659 | #define WOLF_STK_VALIDATE_REQUEST(a) |
wolfSSL | 13:80fb167dafdf | 3660 | #define WOLF_STK_GET_SIZE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 3661 | #define WOLF_STK_WRITE(a, b, c) 0 |
wolfSSL | 13:80fb167dafdf | 3662 | #define WOLF_STK_PARSE(a, b, c, d) 0 |
wolfSSL | 13:80fb167dafdf | 3663 | |
wolfSSL | 13:80fb167dafdf | 3664 | #endif /* HAVE_SESSION_TICKET */ |
wolfSSL | 13:80fb167dafdf | 3665 | |
wolfSSL | 13:80fb167dafdf | 3666 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 3667 | /* Quantum-Safe-Hybrid */ |
wolfSSL | 13:80fb167dafdf | 3668 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 3669 | |
wolfSSL | 13:80fb167dafdf | 3670 | #if defined(HAVE_NTRU) && defined(HAVE_QSH) |
wolfSSL | 13:80fb167dafdf | 3671 | static WC_RNG* rng; |
wolfSSL | 13:80fb167dafdf | 3672 | static wolfSSL_Mutex* rngMutex; |
wolfSSL | 13:80fb167dafdf | 3673 | #endif |
wolfSSL | 13:80fb167dafdf | 3674 | |
wolfSSL | 13:80fb167dafdf | 3675 | #ifdef HAVE_QSH |
wolfSSL | 13:80fb167dafdf | 3676 | static void TLSX_QSH_FreeAll(QSHScheme* list, void* heap) |
wolfSSL | 13:80fb167dafdf | 3677 | { |
wolfSSL | 13:80fb167dafdf | 3678 | QSHScheme* current; |
wolfSSL | 13:80fb167dafdf | 3679 | |
wolfSSL | 13:80fb167dafdf | 3680 | while ((current = list)) { |
wolfSSL | 13:80fb167dafdf | 3681 | list = current->next; |
wolfSSL | 13:80fb167dafdf | 3682 | XFREE(current, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 3683 | } |
wolfSSL | 13:80fb167dafdf | 3684 | |
wolfSSL | 13:80fb167dafdf | 3685 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 3686 | } |
wolfSSL | 13:80fb167dafdf | 3687 | |
wolfSSL | 13:80fb167dafdf | 3688 | static int TLSX_QSH_Append(QSHScheme** list, word16 name, byte* pub, |
wolfSSL | 13:80fb167dafdf | 3689 | word16 pubLen) |
wolfSSL | 13:80fb167dafdf | 3690 | { |
wolfSSL | 13:80fb167dafdf | 3691 | QSHScheme* temp; |
wolfSSL | 13:80fb167dafdf | 3692 | |
wolfSSL | 13:80fb167dafdf | 3693 | if (list == NULL) |
wolfSSL | 13:80fb167dafdf | 3694 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 3695 | |
wolfSSL | 13:80fb167dafdf | 3696 | if ((temp = (QSHScheme*)XMALLOC(sizeof(QSHScheme), NULL, |
wolfSSL | 13:80fb167dafdf | 3697 | DYNAMIC_TYPE_TLSX)) == NULL) |
wolfSSL | 13:80fb167dafdf | 3698 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 3699 | |
wolfSSL | 13:80fb167dafdf | 3700 | temp->name = name; |
wolfSSL | 13:80fb167dafdf | 3701 | temp->PK = pub; |
wolfSSL | 13:80fb167dafdf | 3702 | temp->PKLen = pubLen; |
wolfSSL | 13:80fb167dafdf | 3703 | temp->next = *list; |
wolfSSL | 13:80fb167dafdf | 3704 | |
wolfSSL | 13:80fb167dafdf | 3705 | *list = temp; |
wolfSSL | 13:80fb167dafdf | 3706 | |
wolfSSL | 13:80fb167dafdf | 3707 | return 0; |
wolfSSL | 13:80fb167dafdf | 3708 | } |
wolfSSL | 13:80fb167dafdf | 3709 | |
wolfSSL | 13:80fb167dafdf | 3710 | |
wolfSSL | 13:80fb167dafdf | 3711 | /* request for server's public key : 02 indicates 0-2 requested */ |
wolfSSL | 13:80fb167dafdf | 3712 | static byte TLSX_QSH_SerPKReq(byte* output, byte isRequest) |
wolfSSL | 13:80fb167dafdf | 3713 | { |
wolfSSL | 13:80fb167dafdf | 3714 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 3715 | /* only request one public key from the server */ |
wolfSSL | 13:80fb167dafdf | 3716 | output[0] = 0x01; |
wolfSSL | 13:80fb167dafdf | 3717 | |
wolfSSL | 13:80fb167dafdf | 3718 | return OPAQUE8_LEN; |
wolfSSL | 13:80fb167dafdf | 3719 | } |
wolfSSL | 13:80fb167dafdf | 3720 | else { |
wolfSSL | 13:80fb167dafdf | 3721 | return 0; |
wolfSSL | 13:80fb167dafdf | 3722 | } |
wolfSSL | 13:80fb167dafdf | 3723 | } |
wolfSSL | 13:80fb167dafdf | 3724 | |
wolfSSL | 13:80fb167dafdf | 3725 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:80fb167dafdf | 3726 | |
wolfSSL | 13:80fb167dafdf | 3727 | /* check for TLS_QSH suite */ |
wolfSSL | 13:80fb167dafdf | 3728 | static void TLSX_QSH_ValidateRequest(WOLFSSL* ssl, byte* semaphore) |
wolfSSL | 13:80fb167dafdf | 3729 | { |
wolfSSL | 13:80fb167dafdf | 3730 | int i; |
wolfSSL | 13:80fb167dafdf | 3731 | |
wolfSSL | 13:80fb167dafdf | 3732 | for (i = 0; i < ssl->suites->suiteSz; i+= 2) |
wolfSSL | 13:80fb167dafdf | 3733 | if (ssl->suites->suites[i] == QSH_BYTE) |
wolfSSL | 13:80fb167dafdf | 3734 | return; |
wolfSSL | 13:80fb167dafdf | 3735 | |
wolfSSL | 13:80fb167dafdf | 3736 | /* No QSH suite found */ |
wolfSSL | 13:80fb167dafdf | 3737 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_QUANTUM_SAFE_HYBRID)); |
wolfSSL | 13:80fb167dafdf | 3738 | } |
wolfSSL | 13:80fb167dafdf | 3739 | |
wolfSSL | 13:80fb167dafdf | 3740 | |
wolfSSL | 13:80fb167dafdf | 3741 | /* return the size of the QSH hello extension |
wolfSSL | 13:80fb167dafdf | 3742 | list the list of QSHScheme structs containing id and key |
wolfSSL | 13:80fb167dafdf | 3743 | isRequest if 1 then is being sent to the server |
wolfSSL | 13:80fb167dafdf | 3744 | */ |
wolfSSL | 13:80fb167dafdf | 3745 | word16 TLSX_QSH_GetSize(QSHScheme* list, byte isRequest) |
wolfSSL | 13:80fb167dafdf | 3746 | { |
wolfSSL | 13:80fb167dafdf | 3747 | QSHScheme* temp = list; |
wolfSSL | 13:80fb167dafdf | 3748 | word16 length = 0; |
wolfSSL | 13:80fb167dafdf | 3749 | |
wolfSSL | 13:80fb167dafdf | 3750 | /* account for size of scheme list and public key list */ |
wolfSSL | 13:80fb167dafdf | 3751 | if (isRequest) |
wolfSSL | 13:80fb167dafdf | 3752 | length = OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 3753 | length += OPAQUE24_LEN; |
wolfSSL | 13:80fb167dafdf | 3754 | |
wolfSSL | 13:80fb167dafdf | 3755 | /* for each non null element in list add size */ |
wolfSSL | 13:80fb167dafdf | 3756 | while ((temp)) { |
wolfSSL | 13:80fb167dafdf | 3757 | /* add public key info Scheme | Key Length | Key */ |
wolfSSL | 13:80fb167dafdf | 3758 | length += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 3759 | length += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 3760 | length += temp->PKLen; |
wolfSSL | 13:80fb167dafdf | 3761 | |
wolfSSL | 13:80fb167dafdf | 3762 | /* if client add name size for scheme list |
wolfSSL | 13:80fb167dafdf | 3763 | advance to next QSHScheme struct in list */ |
wolfSSL | 13:80fb167dafdf | 3764 | if (isRequest) |
wolfSSL | 13:80fb167dafdf | 3765 | length += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 3766 | temp = temp->next; |
wolfSSL | 13:80fb167dafdf | 3767 | } |
wolfSSL | 13:80fb167dafdf | 3768 | |
wolfSSL | 13:80fb167dafdf | 3769 | /* add length for request server public keys */ |
wolfSSL | 13:80fb167dafdf | 3770 | if (isRequest) |
wolfSSL | 13:80fb167dafdf | 3771 | length += OPAQUE8_LEN; |
wolfSSL | 13:80fb167dafdf | 3772 | |
wolfSSL | 13:80fb167dafdf | 3773 | return length; |
wolfSSL | 13:80fb167dafdf | 3774 | } |
wolfSSL | 13:80fb167dafdf | 3775 | |
wolfSSL | 13:80fb167dafdf | 3776 | |
wolfSSL | 13:80fb167dafdf | 3777 | /* write out a list of QSHScheme IDs */ |
wolfSSL | 13:80fb167dafdf | 3778 | static word16 TLSX_QSH_Write(QSHScheme* list, byte* output) |
wolfSSL | 13:80fb167dafdf | 3779 | { |
wolfSSL | 13:80fb167dafdf | 3780 | QSHScheme* current = list; |
wolfSSL | 13:80fb167dafdf | 3781 | word16 length = 0; |
wolfSSL | 13:80fb167dafdf | 3782 | |
wolfSSL | 13:80fb167dafdf | 3783 | length += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 3784 | |
wolfSSL | 13:80fb167dafdf | 3785 | while (current) { |
wolfSSL | 13:80fb167dafdf | 3786 | c16toa(current->name, output + length); |
wolfSSL | 13:80fb167dafdf | 3787 | length += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 3788 | current = (QSHScheme*)current->next; |
wolfSSL | 13:80fb167dafdf | 3789 | } |
wolfSSL | 13:80fb167dafdf | 3790 | |
wolfSSL | 13:80fb167dafdf | 3791 | c16toa(length - OPAQUE16_LEN, output); /* writing list length */ |
wolfSSL | 13:80fb167dafdf | 3792 | |
wolfSSL | 13:80fb167dafdf | 3793 | return length; |
wolfSSL | 13:80fb167dafdf | 3794 | } |
wolfSSL | 13:80fb167dafdf | 3795 | |
wolfSSL | 13:80fb167dafdf | 3796 | |
wolfSSL | 13:80fb167dafdf | 3797 | /* write public key list in extension */ |
wolfSSL | 13:80fb167dafdf | 3798 | static word16 TLSX_QSHPK_WriteR(QSHScheme* format, byte* output); |
wolfSSL | 13:80fb167dafdf | 3799 | static word16 TLSX_QSHPK_WriteR(QSHScheme* format, byte* output) |
wolfSSL | 13:80fb167dafdf | 3800 | { |
wolfSSL | 13:80fb167dafdf | 3801 | word32 offset = 0; |
wolfSSL | 13:80fb167dafdf | 3802 | word16 public_len = 0; |
wolfSSL | 13:80fb167dafdf | 3803 | |
wolfSSL | 13:80fb167dafdf | 3804 | if (!format) |
wolfSSL | 13:80fb167dafdf | 3805 | return offset; |
wolfSSL | 13:80fb167dafdf | 3806 | |
wolfSSL | 13:80fb167dafdf | 3807 | /* write scheme ID */ |
wolfSSL | 13:80fb167dafdf | 3808 | c16toa(format->name, output + offset); |
wolfSSL | 13:80fb167dafdf | 3809 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 3810 | |
wolfSSL | 13:80fb167dafdf | 3811 | /* write public key matching scheme */ |
wolfSSL | 13:80fb167dafdf | 3812 | public_len = format->PKLen; |
wolfSSL | 13:80fb167dafdf | 3813 | c16toa(public_len, output + offset); |
wolfSSL | 13:80fb167dafdf | 3814 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 3815 | if (format->PK) { |
wolfSSL | 13:80fb167dafdf | 3816 | XMEMCPY(output+offset, format->PK, public_len); |
wolfSSL | 13:80fb167dafdf | 3817 | } |
wolfSSL | 13:80fb167dafdf | 3818 | |
wolfSSL | 13:80fb167dafdf | 3819 | return public_len + offset; |
wolfSSL | 13:80fb167dafdf | 3820 | } |
wolfSSL | 13:80fb167dafdf | 3821 | |
wolfSSL | 13:80fb167dafdf | 3822 | word16 TLSX_QSHPK_Write(QSHScheme* list, byte* output) |
wolfSSL | 13:80fb167dafdf | 3823 | { |
wolfSSL | 13:80fb167dafdf | 3824 | QSHScheme* current = list; |
wolfSSL | 13:80fb167dafdf | 3825 | word32 length = 0; |
wolfSSL | 13:80fb167dafdf | 3826 | word24 toWire; |
wolfSSL | 13:80fb167dafdf | 3827 | |
wolfSSL | 13:80fb167dafdf | 3828 | length += OPAQUE24_LEN; |
wolfSSL | 13:80fb167dafdf | 3829 | |
wolfSSL | 13:80fb167dafdf | 3830 | while (current) { |
wolfSSL | 13:80fb167dafdf | 3831 | length += TLSX_QSHPK_WriteR(current, output + length); |
wolfSSL | 13:80fb167dafdf | 3832 | current = (QSHScheme*)current->next; |
wolfSSL | 13:80fb167dafdf | 3833 | } |
wolfSSL | 13:80fb167dafdf | 3834 | /* length of public keys sent */ |
wolfSSL | 13:80fb167dafdf | 3835 | c32to24(length - OPAQUE24_LEN, toWire); |
wolfSSL | 13:80fb167dafdf | 3836 | output[0] = toWire[0]; |
wolfSSL | 13:80fb167dafdf | 3837 | output[1] = toWire[1]; |
wolfSSL | 13:80fb167dafdf | 3838 | output[2] = toWire[2]; |
wolfSSL | 13:80fb167dafdf | 3839 | |
wolfSSL | 13:80fb167dafdf | 3840 | return length; |
wolfSSL | 13:80fb167dafdf | 3841 | } |
wolfSSL | 13:80fb167dafdf | 3842 | |
wolfSSL | 13:80fb167dafdf | 3843 | #endif /* NO_WOLFSSL_CLIENT */ |
wolfSSL | 13:80fb167dafdf | 3844 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 3845 | |
wolfSSL | 13:80fb167dafdf | 3846 | static void TLSX_QSHAgreement(TLSX** extensions, void* heap) |
wolfSSL | 13:80fb167dafdf | 3847 | { |
wolfSSL | 13:80fb167dafdf | 3848 | TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID); |
wolfSSL | 13:80fb167dafdf | 3849 | QSHScheme* format = NULL; |
wolfSSL | 13:80fb167dafdf | 3850 | QSHScheme* del = NULL; |
wolfSSL | 13:80fb167dafdf | 3851 | QSHScheme* prev = NULL; |
wolfSSL | 13:80fb167dafdf | 3852 | |
wolfSSL | 13:80fb167dafdf | 3853 | if (extension == NULL) |
wolfSSL | 13:80fb167dafdf | 3854 | return; |
wolfSSL | 13:80fb167dafdf | 3855 | |
wolfSSL | 13:80fb167dafdf | 3856 | format = (QSHScheme*)extension->data; |
wolfSSL | 13:80fb167dafdf | 3857 | while (format) { |
wolfSSL | 13:80fb167dafdf | 3858 | if (format->PKLen == 0) { |
wolfSSL | 13:80fb167dafdf | 3859 | /* case of head */ |
wolfSSL | 13:80fb167dafdf | 3860 | if (format == extension->data) { |
wolfSSL | 13:80fb167dafdf | 3861 | extension->data = format->next; |
wolfSSL | 13:80fb167dafdf | 3862 | } |
wolfSSL | 13:80fb167dafdf | 3863 | if (prev) |
wolfSSL | 13:80fb167dafdf | 3864 | prev->next = format->next; |
wolfSSL | 13:80fb167dafdf | 3865 | del = format; |
wolfSSL | 13:80fb167dafdf | 3866 | format = format->next; |
wolfSSL | 13:80fb167dafdf | 3867 | XFREE(del, heap, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 3868 | del = NULL; |
wolfSSL | 13:80fb167dafdf | 3869 | } else { |
wolfSSL | 13:80fb167dafdf | 3870 | prev = format; |
wolfSSL | 13:80fb167dafdf | 3871 | format = format->next; |
wolfSSL | 13:80fb167dafdf | 3872 | } |
wolfSSL | 13:80fb167dafdf | 3873 | } |
wolfSSL | 13:80fb167dafdf | 3874 | |
wolfSSL | 13:80fb167dafdf | 3875 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 3876 | } |
wolfSSL | 13:80fb167dafdf | 3877 | |
wolfSSL | 13:80fb167dafdf | 3878 | |
wolfSSL | 13:80fb167dafdf | 3879 | /* Parse in hello extension |
wolfSSL | 13:80fb167dafdf | 3880 | input the byte stream to process |
wolfSSL | 13:80fb167dafdf | 3881 | length length of total extension found |
wolfSSL | 13:80fb167dafdf | 3882 | isRequest set to 1 if being sent to the server |
wolfSSL | 13:80fb167dafdf | 3883 | */ |
wolfSSL | 13:80fb167dafdf | 3884 | static int TLSX_QSH_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:80fb167dafdf | 3885 | byte isRequest) |
wolfSSL | 13:80fb167dafdf | 3886 | { |
wolfSSL | 13:80fb167dafdf | 3887 | byte numKeys = 0; |
wolfSSL | 13:80fb167dafdf | 3888 | word16 offset = 0; |
wolfSSL | 13:80fb167dafdf | 3889 | word16 schemSz = 0; |
wolfSSL | 13:80fb167dafdf | 3890 | word16 offset_len = 0; |
wolfSSL | 13:80fb167dafdf | 3891 | word32 offset_pk = 0; |
wolfSSL | 13:80fb167dafdf | 3892 | word16 name = 0; |
wolfSSL | 13:80fb167dafdf | 3893 | word16 PKLen = 0; |
wolfSSL | 13:80fb167dafdf | 3894 | byte* PK = NULL; |
wolfSSL | 13:80fb167dafdf | 3895 | int r; |
wolfSSL | 13:80fb167dafdf | 3896 | |
wolfSSL | 13:80fb167dafdf | 3897 | |
wolfSSL | 13:80fb167dafdf | 3898 | if (OPAQUE16_LEN > length) |
wolfSSL | 13:80fb167dafdf | 3899 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 3900 | |
wolfSSL | 13:80fb167dafdf | 3901 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 3902 | ato16(input, &schemSz); |
wolfSSL | 13:80fb167dafdf | 3903 | |
wolfSSL | 13:80fb167dafdf | 3904 | /* list of public keys available for QSH schemes */ |
wolfSSL | 13:80fb167dafdf | 3905 | offset_len = schemSz + OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 3906 | } |
wolfSSL | 13:80fb167dafdf | 3907 | |
wolfSSL | 13:80fb167dafdf | 3908 | offset_pk = ((input[offset_len] << 16) & 0xFF00000) | |
wolfSSL | 13:80fb167dafdf | 3909 | (((input[offset_len + 1]) << 8) & 0xFF00) | |
wolfSSL | 13:80fb167dafdf | 3910 | (input[offset_len + 2] & 0xFF); |
wolfSSL | 13:80fb167dafdf | 3911 | offset_len += OPAQUE24_LEN; |
wolfSSL | 13:80fb167dafdf | 3912 | |
wolfSSL | 13:80fb167dafdf | 3913 | /* check buffer size */ |
wolfSSL | 13:80fb167dafdf | 3914 | if (offset_pk > length) |
wolfSSL | 13:80fb167dafdf | 3915 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 3916 | |
wolfSSL | 13:80fb167dafdf | 3917 | /* set maximum number of keys the client will accept */ |
wolfSSL | 13:80fb167dafdf | 3918 | if (!isRequest) |
wolfSSL | 13:80fb167dafdf | 3919 | numKeys = (ssl->maxRequest < 1)? 1 : ssl->maxRequest; |
wolfSSL | 13:80fb167dafdf | 3920 | |
wolfSSL | 13:80fb167dafdf | 3921 | /* hello extension read list of scheme ids */ |
wolfSSL | 13:80fb167dafdf | 3922 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 3923 | |
wolfSSL | 13:80fb167dafdf | 3924 | /* read in request for public keys */ |
wolfSSL | 13:80fb167dafdf | 3925 | ssl->minRequest = (input[length -1] >> 4) & 0xFF; |
wolfSSL | 13:80fb167dafdf | 3926 | ssl->maxRequest = input[length -1] & 0x0F; |
wolfSSL | 13:80fb167dafdf | 3927 | |
wolfSSL | 13:80fb167dafdf | 3928 | /* choose the min between min requested by client and 1 */ |
wolfSSL | 13:80fb167dafdf | 3929 | numKeys = (ssl->minRequest > 1) ? ssl->minRequest : 1; |
wolfSSL | 13:80fb167dafdf | 3930 | |
wolfSSL | 13:80fb167dafdf | 3931 | if (ssl->minRequest > ssl->maxRequest) |
wolfSSL | 13:80fb167dafdf | 3932 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 3933 | |
wolfSSL | 13:80fb167dafdf | 3934 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 3935 | schemSz += offset; |
wolfSSL | 13:80fb167dafdf | 3936 | |
wolfSSL | 13:80fb167dafdf | 3937 | /* check buffer size */ |
wolfSSL | 13:80fb167dafdf | 3938 | if (schemSz > length) |
wolfSSL | 13:80fb167dafdf | 3939 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 3940 | |
wolfSSL | 13:80fb167dafdf | 3941 | while ((offset < schemSz) && numKeys) { |
wolfSSL | 13:80fb167dafdf | 3942 | /* Scheme ID list */ |
wolfSSL | 13:80fb167dafdf | 3943 | ato16(input + offset, &name); |
wolfSSL | 13:80fb167dafdf | 3944 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 3945 | |
wolfSSL | 13:80fb167dafdf | 3946 | /* validate we have scheme id */ |
wolfSSL | 13:80fb167dafdf | 3947 | if (ssl->user_set_QSHSchemes && |
wolfSSL | 13:80fb167dafdf | 3948 | !TLSX_ValidateQSHScheme(&ssl->extensions, name)) { |
wolfSSL | 13:80fb167dafdf | 3949 | continue; |
wolfSSL | 13:80fb167dafdf | 3950 | } |
wolfSSL | 13:80fb167dafdf | 3951 | |
wolfSSL | 13:80fb167dafdf | 3952 | /* server create keys on demand */ |
wolfSSL | 13:80fb167dafdf | 3953 | if ((r = TLSX_CreateNtruKey(ssl, name)) != 0) { |
wolfSSL | 13:80fb167dafdf | 3954 | WOLFSSL_MSG("Error creating ntru keys"); |
wolfSSL | 13:80fb167dafdf | 3955 | return r; |
wolfSSL | 13:80fb167dafdf | 3956 | } |
wolfSSL | 13:80fb167dafdf | 3957 | |
wolfSSL | 13:80fb167dafdf | 3958 | /* peer sent an agreed upon scheme */ |
wolfSSL | 13:80fb167dafdf | 3959 | r = TLSX_UseQSHScheme(&ssl->extensions, name, NULL, 0, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 3960 | |
wolfSSL | 13:80fb167dafdf | 3961 | if (r != SSL_SUCCESS) return r; /* throw error */ |
wolfSSL | 13:80fb167dafdf | 3962 | |
wolfSSL | 13:80fb167dafdf | 3963 | numKeys--; |
wolfSSL | 13:80fb167dafdf | 3964 | } |
wolfSSL | 13:80fb167dafdf | 3965 | |
wolfSSL | 13:80fb167dafdf | 3966 | /* choose the min between min requested by client and 1 */ |
wolfSSL | 13:80fb167dafdf | 3967 | numKeys = (ssl->minRequest > 1) ? ssl->minRequest : 1; |
wolfSSL | 13:80fb167dafdf | 3968 | } |
wolfSSL | 13:80fb167dafdf | 3969 | |
wolfSSL | 13:80fb167dafdf | 3970 | /* QSHPK struct */ |
wolfSSL | 13:80fb167dafdf | 3971 | offset_pk += offset_len; |
wolfSSL | 13:80fb167dafdf | 3972 | while ((offset_len < offset_pk) && numKeys) { |
wolfSSL | 13:80fb167dafdf | 3973 | QSHKey * temp; |
wolfSSL | 13:80fb167dafdf | 3974 | |
wolfSSL | 13:80fb167dafdf | 3975 | if ((temp = (QSHKey*)XMALLOC(sizeof(QSHKey), ssl->heap, |
wolfSSL | 13:80fb167dafdf | 3976 | DYNAMIC_TYPE_TLSX)) == NULL) |
wolfSSL | 13:80fb167dafdf | 3977 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 3978 | |
wolfSSL | 13:80fb167dafdf | 3979 | /* initialize */ |
wolfSSL | 13:80fb167dafdf | 3980 | temp->next = NULL; |
wolfSSL | 13:80fb167dafdf | 3981 | temp->pub.buffer = NULL; |
wolfSSL | 13:80fb167dafdf | 3982 | temp->pub.length = 0; |
wolfSSL | 13:80fb167dafdf | 3983 | temp->pri.buffer = NULL; |
wolfSSL | 13:80fb167dafdf | 3984 | temp->pri.length = 0; |
wolfSSL | 13:80fb167dafdf | 3985 | |
wolfSSL | 13:80fb167dafdf | 3986 | /* scheme id */ |
wolfSSL | 13:80fb167dafdf | 3987 | ato16(input + offset_len, &(temp->name)); |
wolfSSL | 13:80fb167dafdf | 3988 | offset_len += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 3989 | |
wolfSSL | 13:80fb167dafdf | 3990 | /* public key length */ |
wolfSSL | 13:80fb167dafdf | 3991 | ato16(input + offset_len, &PKLen); |
wolfSSL | 13:80fb167dafdf | 3992 | temp->pub.length = PKLen; |
wolfSSL | 13:80fb167dafdf | 3993 | offset_len += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 3994 | |
wolfSSL | 13:80fb167dafdf | 3995 | |
wolfSSL | 13:80fb167dafdf | 3996 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 3997 | /* validate we have scheme id */ |
wolfSSL | 13:80fb167dafdf | 3998 | if (ssl->user_set_QSHSchemes && |
wolfSSL | 13:80fb167dafdf | 3999 | (!TLSX_ValidateQSHScheme(&ssl->extensions, temp->name))) { |
wolfSSL | 13:80fb167dafdf | 4000 | offset_len += PKLen; |
wolfSSL | 13:80fb167dafdf | 4001 | XFREE(temp, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4002 | continue; |
wolfSSL | 13:80fb167dafdf | 4003 | } |
wolfSSL | 13:80fb167dafdf | 4004 | } |
wolfSSL | 13:80fb167dafdf | 4005 | |
wolfSSL | 13:80fb167dafdf | 4006 | /* read in public key */ |
wolfSSL | 13:80fb167dafdf | 4007 | if (PKLen > 0) { |
wolfSSL | 13:80fb167dafdf | 4008 | temp->pub.buffer = (byte*)XMALLOC(temp->pub.length, |
wolfSSL | 13:80fb167dafdf | 4009 | ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); |
wolfSSL | 13:80fb167dafdf | 4010 | XMEMCPY(temp->pub.buffer, input + offset_len, temp->pub.length); |
wolfSSL | 13:80fb167dafdf | 4011 | offset_len += PKLen; |
wolfSSL | 13:80fb167dafdf | 4012 | } |
wolfSSL | 13:80fb167dafdf | 4013 | else { |
wolfSSL | 13:80fb167dafdf | 4014 | PK = NULL; |
wolfSSL | 13:80fb167dafdf | 4015 | } |
wolfSSL | 13:80fb167dafdf | 4016 | |
wolfSSL | 13:80fb167dafdf | 4017 | /* use own key when adding to extensions list for sending reply */ |
wolfSSL | 13:80fb167dafdf | 4018 | PKLen = 0; |
wolfSSL | 13:80fb167dafdf | 4019 | PK = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, &PKLen, temp->name); |
wolfSSL | 13:80fb167dafdf | 4020 | r = TLSX_UseQSHScheme(&ssl->extensions, temp->name, PK, PKLen, |
wolfSSL | 13:80fb167dafdf | 4021 | ssl->heap); |
wolfSSL | 13:80fb167dafdf | 4022 | |
wolfSSL | 13:80fb167dafdf | 4023 | /* store peers key */ |
wolfSSL | 13:80fb167dafdf | 4024 | ssl->peerQSHKeyPresent = 1; |
wolfSSL | 13:80fb167dafdf | 4025 | if (TLSX_AddQSHKey(&ssl->peerQSHKey, temp) != 0) |
wolfSSL | 13:80fb167dafdf | 4026 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 4027 | |
wolfSSL | 13:80fb167dafdf | 4028 | if (temp->pub.length == 0) { |
wolfSSL | 13:80fb167dafdf | 4029 | XFREE(temp, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4030 | } |
wolfSSL | 13:80fb167dafdf | 4031 | |
wolfSSL | 13:80fb167dafdf | 4032 | if (r != SSL_SUCCESS) {return r;} /* throw error */ |
wolfSSL | 13:80fb167dafdf | 4033 | |
wolfSSL | 13:80fb167dafdf | 4034 | numKeys--; |
wolfSSL | 13:80fb167dafdf | 4035 | } |
wolfSSL | 13:80fb167dafdf | 4036 | |
wolfSSL | 13:80fb167dafdf | 4037 | /* reply to a QSH extension sent from client */ |
wolfSSL | 13:80fb167dafdf | 4038 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 4039 | TLSX_SetResponse(ssl, TLSX_QUANTUM_SAFE_HYBRID); |
wolfSSL | 13:80fb167dafdf | 4040 | /* only use schemes we have key generated for -- free the rest */ |
wolfSSL | 13:80fb167dafdf | 4041 | TLSX_QSHAgreement(&ssl->extensions, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 4042 | } |
wolfSSL | 13:80fb167dafdf | 4043 | |
wolfSSL | 13:80fb167dafdf | 4044 | return 0; |
wolfSSL | 13:80fb167dafdf | 4045 | } |
wolfSSL | 13:80fb167dafdf | 4046 | |
wolfSSL | 13:80fb167dafdf | 4047 | |
wolfSSL | 13:80fb167dafdf | 4048 | /* Used for parsing in QSHCipher structs on Key Exchange */ |
wolfSSL | 13:80fb167dafdf | 4049 | int TLSX_QSHCipher_Parse(WOLFSSL* ssl, const byte* input, word16 length, |
wolfSSL | 13:80fb167dafdf | 4050 | byte isServer) |
wolfSSL | 13:80fb167dafdf | 4051 | { |
wolfSSL | 13:80fb167dafdf | 4052 | QSHKey* key; |
wolfSSL | 13:80fb167dafdf | 4053 | word16 Max_Secret_Len = 48; |
wolfSSL | 13:80fb167dafdf | 4054 | word16 offset = 0; |
wolfSSL | 13:80fb167dafdf | 4055 | word16 offset_len = 0; |
wolfSSL | 13:80fb167dafdf | 4056 | word32 offset_pk = 0; |
wolfSSL | 13:80fb167dafdf | 4057 | word16 name = 0; |
wolfSSL | 13:80fb167dafdf | 4058 | word16 secretLen = 0; |
wolfSSL | 13:80fb167dafdf | 4059 | byte* secret = NULL; |
wolfSSL | 13:80fb167dafdf | 4060 | word16 buffLen = 0; |
wolfSSL | 13:80fb167dafdf | 4061 | byte buff[145]; /* size enough for 3 secrets */ |
wolfSSL | 13:80fb167dafdf | 4062 | buffer* buf; |
wolfSSL | 13:80fb167dafdf | 4063 | |
wolfSSL | 13:80fb167dafdf | 4064 | /* pointer to location where secret should be stored */ |
wolfSSL | 13:80fb167dafdf | 4065 | if (isServer) { |
wolfSSL | 13:80fb167dafdf | 4066 | buf = ssl->QSH_secret->CliSi; |
wolfSSL | 13:80fb167dafdf | 4067 | } |
wolfSSL | 13:80fb167dafdf | 4068 | else { |
wolfSSL | 13:80fb167dafdf | 4069 | buf = ssl->QSH_secret->SerSi; |
wolfSSL | 13:80fb167dafdf | 4070 | } |
wolfSSL | 13:80fb167dafdf | 4071 | |
wolfSSL | 13:80fb167dafdf | 4072 | offset_pk = ((input[offset_len] << 16) & 0xFF0000) | |
wolfSSL | 13:80fb167dafdf | 4073 | (((input[offset_len + 1]) << 8) & 0xFF00) | |
wolfSSL | 13:80fb167dafdf | 4074 | (input[offset_len + 2] & 0xFF); |
wolfSSL | 13:80fb167dafdf | 4075 | offset_len += OPAQUE24_LEN; |
wolfSSL | 13:80fb167dafdf | 4076 | |
wolfSSL | 13:80fb167dafdf | 4077 | /* validating extension list length -- check if trying to read over edge |
wolfSSL | 13:80fb167dafdf | 4078 | of buffer */ |
wolfSSL | 13:80fb167dafdf | 4079 | if (length < (offset_pk + OPAQUE24_LEN)) { |
wolfSSL | 13:80fb167dafdf | 4080 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 4081 | } |
wolfSSL | 13:80fb167dafdf | 4082 | |
wolfSSL | 13:80fb167dafdf | 4083 | /* QSHCipherList struct */ |
wolfSSL | 13:80fb167dafdf | 4084 | offset_pk += offset_len; |
wolfSSL | 13:80fb167dafdf | 4085 | while (offset_len < offset_pk) { |
wolfSSL | 13:80fb167dafdf | 4086 | |
wolfSSL | 13:80fb167dafdf | 4087 | /* scheme id */ |
wolfSSL | 13:80fb167dafdf | 4088 | ato16(input + offset_len, &name); |
wolfSSL | 13:80fb167dafdf | 4089 | offset_len += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 4090 | |
wolfSSL | 13:80fb167dafdf | 4091 | /* public key length */ |
wolfSSL | 13:80fb167dafdf | 4092 | ato16(input + offset_len, &secretLen); |
wolfSSL | 13:80fb167dafdf | 4093 | offset_len += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 4094 | |
wolfSSL | 13:80fb167dafdf | 4095 | /* read in public key */ |
wolfSSL | 13:80fb167dafdf | 4096 | if (secretLen > 0) { |
wolfSSL | 13:80fb167dafdf | 4097 | secret = (byte*)(input + offset_len); |
wolfSSL | 13:80fb167dafdf | 4098 | offset_len += secretLen; |
wolfSSL | 13:80fb167dafdf | 4099 | } |
wolfSSL | 13:80fb167dafdf | 4100 | else { |
wolfSSL | 13:80fb167dafdf | 4101 | secret = NULL; |
wolfSSL | 13:80fb167dafdf | 4102 | } |
wolfSSL | 13:80fb167dafdf | 4103 | |
wolfSSL | 13:80fb167dafdf | 4104 | /* no secret sent */ |
wolfSSL | 13:80fb167dafdf | 4105 | if (secret == NULL) |
wolfSSL | 13:80fb167dafdf | 4106 | continue; |
wolfSSL | 13:80fb167dafdf | 4107 | |
wolfSSL | 13:80fb167dafdf | 4108 | /* find corresponding key */ |
wolfSSL | 13:80fb167dafdf | 4109 | key = ssl->QSH_Key; |
wolfSSL | 13:80fb167dafdf | 4110 | while (key) { |
wolfSSL | 13:80fb167dafdf | 4111 | if (key->name == name) |
wolfSSL | 13:80fb167dafdf | 4112 | break; |
wolfSSL | 13:80fb167dafdf | 4113 | else |
wolfSSL | 13:80fb167dafdf | 4114 | key = (QSHKey*)key->next; |
wolfSSL | 13:80fb167dafdf | 4115 | } |
wolfSSL | 13:80fb167dafdf | 4116 | |
wolfSSL | 13:80fb167dafdf | 4117 | /* if we do not have the key than there was a big issue negotiation */ |
wolfSSL | 13:80fb167dafdf | 4118 | if (key == NULL) { |
wolfSSL | 13:80fb167dafdf | 4119 | WOLFSSL_MSG("key was null for decryption!!!\n"); |
wolfSSL | 13:80fb167dafdf | 4120 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 4121 | } |
wolfSSL | 13:80fb167dafdf | 4122 | |
wolfSSL | 13:80fb167dafdf | 4123 | /* Decrypt sent secret */ |
wolfSSL | 13:80fb167dafdf | 4124 | buffLen = Max_Secret_Len; |
wolfSSL | 13:80fb167dafdf | 4125 | QSH_Decrypt(key, secret, secretLen, buff + offset, &buffLen); |
wolfSSL | 13:80fb167dafdf | 4126 | offset += buffLen; |
wolfSSL | 13:80fb167dafdf | 4127 | } |
wolfSSL | 13:80fb167dafdf | 4128 | |
wolfSSL | 13:80fb167dafdf | 4129 | /* allocate memory for buffer */ |
wolfSSL | 13:80fb167dafdf | 4130 | buf->length = offset; |
wolfSSL | 13:80fb167dafdf | 4131 | buf->buffer = (byte*)XMALLOC(offset, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 13:80fb167dafdf | 4132 | if (buf->buffer == NULL) |
wolfSSL | 13:80fb167dafdf | 4133 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 4134 | |
wolfSSL | 13:80fb167dafdf | 4135 | /* store secrets */ |
wolfSSL | 13:80fb167dafdf | 4136 | XMEMCPY(buf->buffer, buff, offset); |
wolfSSL | 13:80fb167dafdf | 4137 | ForceZero(buff, offset); |
wolfSSL | 13:80fb167dafdf | 4138 | |
wolfSSL | 13:80fb167dafdf | 4139 | return offset_len; |
wolfSSL | 13:80fb167dafdf | 4140 | } |
wolfSSL | 13:80fb167dafdf | 4141 | |
wolfSSL | 13:80fb167dafdf | 4142 | |
wolfSSL | 13:80fb167dafdf | 4143 | /* return 1 on success */ |
wolfSSL | 13:80fb167dafdf | 4144 | int TLSX_ValidateQSHScheme(TLSX** extensions, word16 theirs) { |
wolfSSL | 13:80fb167dafdf | 4145 | TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID); |
wolfSSL | 13:80fb167dafdf | 4146 | QSHScheme* format = NULL; |
wolfSSL | 13:80fb167dafdf | 4147 | |
wolfSSL | 13:80fb167dafdf | 4148 | /* if no extension is sent then do not use QSH */ |
wolfSSL | 13:80fb167dafdf | 4149 | if (!extension) { |
wolfSSL | 13:80fb167dafdf | 4150 | WOLFSSL_MSG("No QSH Extension"); |
wolfSSL | 13:80fb167dafdf | 4151 | return 0; |
wolfSSL | 13:80fb167dafdf | 4152 | } |
wolfSSL | 13:80fb167dafdf | 4153 | |
wolfSSL | 13:80fb167dafdf | 4154 | for (format = (QSHScheme*)extension->data; format; format = format->next) { |
wolfSSL | 13:80fb167dafdf | 4155 | if (format->name == theirs) { |
wolfSSL | 13:80fb167dafdf | 4156 | WOLFSSL_MSG("Found Matching QSH Scheme"); |
wolfSSL | 13:80fb167dafdf | 4157 | return 1; /* have QSH */ |
wolfSSL | 13:80fb167dafdf | 4158 | } |
wolfSSL | 13:80fb167dafdf | 4159 | } |
wolfSSL | 13:80fb167dafdf | 4160 | |
wolfSSL | 13:80fb167dafdf | 4161 | return 0; |
wolfSSL | 13:80fb167dafdf | 4162 | } |
wolfSSL | 13:80fb167dafdf | 4163 | #endif /* NO_WOLFSSL_SERVER */ |
wolfSSL | 13:80fb167dafdf | 4164 | |
wolfSSL | 13:80fb167dafdf | 4165 | /* test if the QSH Scheme is implemented |
wolfSSL | 13:80fb167dafdf | 4166 | return 1 if yes 0 if no */ |
wolfSSL | 13:80fb167dafdf | 4167 | static int TLSX_HaveQSHScheme(word16 name) |
wolfSSL | 13:80fb167dafdf | 4168 | { |
wolfSSL | 13:80fb167dafdf | 4169 | switch(name) { |
wolfSSL | 13:80fb167dafdf | 4170 | #ifdef HAVE_NTRU |
wolfSSL | 13:80fb167dafdf | 4171 | case WOLFSSL_NTRU_EESS439: |
wolfSSL | 13:80fb167dafdf | 4172 | case WOLFSSL_NTRU_EESS593: |
wolfSSL | 13:80fb167dafdf | 4173 | case WOLFSSL_NTRU_EESS743: |
wolfSSL | 13:80fb167dafdf | 4174 | return 1; |
wolfSSL | 13:80fb167dafdf | 4175 | #endif |
wolfSSL | 13:80fb167dafdf | 4176 | case WOLFSSL_LWE_XXX: |
wolfSSL | 13:80fb167dafdf | 4177 | case WOLFSSL_HFE_XXX: |
wolfSSL | 13:80fb167dafdf | 4178 | return 0; /* not supported yet */ |
wolfSSL | 13:80fb167dafdf | 4179 | |
wolfSSL | 13:80fb167dafdf | 4180 | default: |
wolfSSL | 13:80fb167dafdf | 4181 | return 0; |
wolfSSL | 13:80fb167dafdf | 4182 | } |
wolfSSL | 13:80fb167dafdf | 4183 | } |
wolfSSL | 13:80fb167dafdf | 4184 | |
wolfSSL | 13:80fb167dafdf | 4185 | |
wolfSSL | 13:80fb167dafdf | 4186 | /* Add a QSHScheme struct to list of usable ones */ |
wolfSSL | 13:80fb167dafdf | 4187 | int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz, |
wolfSSL | 13:80fb167dafdf | 4188 | void* heap) |
wolfSSL | 13:80fb167dafdf | 4189 | { |
wolfSSL | 13:80fb167dafdf | 4190 | TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID); |
wolfSSL | 13:80fb167dafdf | 4191 | QSHScheme* format = NULL; |
wolfSSL | 13:80fb167dafdf | 4192 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 4193 | |
wolfSSL | 13:80fb167dafdf | 4194 | /* sanity check */ |
wolfSSL | 13:80fb167dafdf | 4195 | if (extensions == NULL || (pKey == NULL && pkeySz != 0)) |
wolfSSL | 13:80fb167dafdf | 4196 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 4197 | |
wolfSSL | 13:80fb167dafdf | 4198 | /* if scheme is implemented than add */ |
wolfSSL | 13:80fb167dafdf | 4199 | if (TLSX_HaveQSHScheme(name)) { |
wolfSSL | 13:80fb167dafdf | 4200 | if ((ret = TLSX_QSH_Append(&format, name, pKey, pkeySz)) != 0) |
wolfSSL | 13:80fb167dafdf | 4201 | return ret; |
wolfSSL | 13:80fb167dafdf | 4202 | |
wolfSSL | 13:80fb167dafdf | 4203 | if (!extension) { |
wolfSSL | 13:80fb167dafdf | 4204 | if ((ret = TLSX_Push(extensions, TLSX_QUANTUM_SAFE_HYBRID, format, |
wolfSSL | 13:80fb167dafdf | 4205 | heap)) != 0) { |
wolfSSL | 13:80fb167dafdf | 4206 | XFREE(format, 0, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4207 | return ret; |
wolfSSL | 13:80fb167dafdf | 4208 | } |
wolfSSL | 13:80fb167dafdf | 4209 | } |
wolfSSL | 13:80fb167dafdf | 4210 | else { |
wolfSSL | 13:80fb167dafdf | 4211 | /* push new QSH object to extension data. */ |
wolfSSL | 13:80fb167dafdf | 4212 | format->next = (QSHScheme*)extension->data; |
wolfSSL | 13:80fb167dafdf | 4213 | extension->data = (void*)format; |
wolfSSL | 13:80fb167dafdf | 4214 | |
wolfSSL | 13:80fb167dafdf | 4215 | /* look for another format of the same name to remove (replacement) */ |
wolfSSL | 13:80fb167dafdf | 4216 | do { |
wolfSSL | 13:80fb167dafdf | 4217 | if (format->next && (format->next->name == name)) { |
wolfSSL | 13:80fb167dafdf | 4218 | QSHScheme* next = format->next; |
wolfSSL | 13:80fb167dafdf | 4219 | |
wolfSSL | 13:80fb167dafdf | 4220 | format->next = next->next; |
wolfSSL | 13:80fb167dafdf | 4221 | XFREE(next, 0, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4222 | |
wolfSSL | 13:80fb167dafdf | 4223 | break; |
wolfSSL | 13:80fb167dafdf | 4224 | } |
wolfSSL | 13:80fb167dafdf | 4225 | } while ((format = format->next)); |
wolfSSL | 13:80fb167dafdf | 4226 | } |
wolfSSL | 13:80fb167dafdf | 4227 | } |
wolfSSL | 13:80fb167dafdf | 4228 | return SSL_SUCCESS; |
wolfSSL | 13:80fb167dafdf | 4229 | } |
wolfSSL | 13:80fb167dafdf | 4230 | |
wolfSSL | 13:80fb167dafdf | 4231 | #define QSH_FREE_ALL TLSX_QSH_FreeAll |
wolfSSL | 13:80fb167dafdf | 4232 | #define QSH_VALIDATE_REQUEST TLSX_QSH_ValidateRequest |
wolfSSL | 13:80fb167dafdf | 4233 | |
wolfSSL | 13:80fb167dafdf | 4234 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:80fb167dafdf | 4235 | #define QSH_GET_SIZE TLSX_QSH_GetSize |
wolfSSL | 13:80fb167dafdf | 4236 | #define QSH_WRITE TLSX_QSH_Write |
wolfSSL | 13:80fb167dafdf | 4237 | #else |
wolfSSL | 13:80fb167dafdf | 4238 | #define QSH_GET_SIZE(list) 0 |
wolfSSL | 13:80fb167dafdf | 4239 | #define QSH_WRITE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 4240 | #endif |
wolfSSL | 13:80fb167dafdf | 4241 | |
wolfSSL | 13:80fb167dafdf | 4242 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 4243 | #define QSH_PARSE TLSX_QSH_Parse |
wolfSSL | 13:80fb167dafdf | 4244 | #else |
wolfSSL | 13:80fb167dafdf | 4245 | #define QSH_PARSE(a, b, c, d) 0 |
wolfSSL | 13:80fb167dafdf | 4246 | #endif |
wolfSSL | 13:80fb167dafdf | 4247 | |
wolfSSL | 13:80fb167dafdf | 4248 | #define QSHPK_WRITE TLSX_QSHPK_Write |
wolfSSL | 13:80fb167dafdf | 4249 | #define QSH_SERREQ TLSX_QSH_SerPKReq |
wolfSSL | 13:80fb167dafdf | 4250 | #else |
wolfSSL | 13:80fb167dafdf | 4251 | |
wolfSSL | 13:80fb167dafdf | 4252 | #define QSH_FREE_ALL(list, heap) |
wolfSSL | 13:80fb167dafdf | 4253 | #define QSH_GET_SIZE(list, a) 0 |
wolfSSL | 13:80fb167dafdf | 4254 | #define QSH_WRITE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 4255 | #define QSH_PARSE(a, b, c, d) 0 |
wolfSSL | 13:80fb167dafdf | 4256 | #define QSHPK_WRITE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 4257 | #define QSH_SERREQ(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 4258 | #define QSH_VALIDATE_REQUEST(a, b) |
wolfSSL | 13:80fb167dafdf | 4259 | |
wolfSSL | 13:80fb167dafdf | 4260 | #endif /* HAVE_QSH */ |
wolfSSL | 13:80fb167dafdf | 4261 | |
wolfSSL | 13:80fb167dafdf | 4262 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 4263 | /* Supported Versions */ |
wolfSSL | 13:80fb167dafdf | 4264 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 4265 | |
wolfSSL | 13:80fb167dafdf | 4266 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 4267 | /* Return the size of the SupportedVersions extension's data. |
wolfSSL | 13:80fb167dafdf | 4268 | * |
wolfSSL | 13:80fb167dafdf | 4269 | * data The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 4270 | * returns the length of data that will be in the extension. |
wolfSSL | 13:80fb167dafdf | 4271 | */ |
wolfSSL | 13:80fb167dafdf | 4272 | static word16 TLSX_SupportedVersions_GetSize(byte* data) |
wolfSSL | 13:80fb167dafdf | 4273 | { |
wolfSSL | 13:80fb167dafdf | 4274 | (void)data; |
wolfSSL | 13:80fb167dafdf | 4275 | |
wolfSSL | 13:80fb167dafdf | 4276 | /* TLS v1.2 and TLS v1.3 */ |
wolfSSL | 13:80fb167dafdf | 4277 | int cnt = 2; |
wolfSSL | 13:80fb167dafdf | 4278 | |
wolfSSL | 13:80fb167dafdf | 4279 | #ifndef NO_OLD_TLS |
wolfSSL | 13:80fb167dafdf | 4280 | /* TLS v1 and TLS v1.1 */ |
wolfSSL | 13:80fb167dafdf | 4281 | cnt += 2; |
wolfSSL | 13:80fb167dafdf | 4282 | #endif |
wolfSSL | 13:80fb167dafdf | 4283 | |
wolfSSL | 13:80fb167dafdf | 4284 | return OPAQUE8_LEN + cnt * OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 4285 | } |
wolfSSL | 13:80fb167dafdf | 4286 | |
wolfSSL | 13:80fb167dafdf | 4287 | /* Writes the SupportedVersions extension into the buffer. |
wolfSSL | 13:80fb167dafdf | 4288 | * |
wolfSSL | 13:80fb167dafdf | 4289 | * data The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 4290 | * output The buffer to write the extension into. |
wolfSSL | 13:80fb167dafdf | 4291 | * returns the length of data that was written. |
wolfSSL | 13:80fb167dafdf | 4292 | */ |
wolfSSL | 13:80fb167dafdf | 4293 | static word16 TLSX_SupportedVersions_Write(byte* data, byte* output) |
wolfSSL | 13:80fb167dafdf | 4294 | { |
wolfSSL | 13:80fb167dafdf | 4295 | WOLFSSL* ssl = (WOLFSSL*)data; |
wolfSSL | 13:80fb167dafdf | 4296 | ProtocolVersion pv = ssl->ctx->method->version; |
wolfSSL | 13:80fb167dafdf | 4297 | int i; |
wolfSSL | 13:80fb167dafdf | 4298 | /* TLS v1.2 and TLS v1.3 */ |
wolfSSL | 13:80fb167dafdf | 4299 | int cnt = 2; |
wolfSSL | 13:80fb167dafdf | 4300 | |
wolfSSL | 13:80fb167dafdf | 4301 | #ifndef NO_OLD_TLS |
wolfSSL | 13:80fb167dafdf | 4302 | /* TLS v1 and TLS v1.1 */ |
wolfSSL | 13:80fb167dafdf | 4303 | cnt += 2; |
wolfSSL | 13:80fb167dafdf | 4304 | #endif |
wolfSSL | 13:80fb167dafdf | 4305 | |
wolfSSL | 13:80fb167dafdf | 4306 | *(output++) = cnt * OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 4307 | for (i = 0; i < cnt; i++) { |
wolfSSL | 13:80fb167dafdf | 4308 | /* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */ |
wolfSSL | 13:80fb167dafdf | 4309 | if (pv.minor - i == TLSv1_3_MINOR) { |
wolfSSL | 13:80fb167dafdf | 4310 | /* The TLS draft major number. */ |
wolfSSL | 13:80fb167dafdf | 4311 | *(output++) = TLS_DRAFT_MAJOR; |
wolfSSL | 13:80fb167dafdf | 4312 | /* Version of draft supported. */ |
wolfSSL | 13:80fb167dafdf | 4313 | *(output++) = TLS_DRAFT_MINOR; |
wolfSSL | 13:80fb167dafdf | 4314 | continue; |
wolfSSL | 13:80fb167dafdf | 4315 | } |
wolfSSL | 13:80fb167dafdf | 4316 | |
wolfSSL | 13:80fb167dafdf | 4317 | *(output++) = pv.major; |
wolfSSL | 13:80fb167dafdf | 4318 | *(output++) = pv.minor - i; |
wolfSSL | 13:80fb167dafdf | 4319 | } |
wolfSSL | 13:80fb167dafdf | 4320 | |
wolfSSL | 13:80fb167dafdf | 4321 | return OPAQUE8_LEN + cnt * OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 4322 | } |
wolfSSL | 13:80fb167dafdf | 4323 | |
wolfSSL | 13:80fb167dafdf | 4324 | /* Parse the SupportedVersions extension. |
wolfSSL | 13:80fb167dafdf | 4325 | * |
wolfSSL | 13:80fb167dafdf | 4326 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 4327 | * input The buffer with the extension data. |
wolfSSL | 13:80fb167dafdf | 4328 | * length The length of the extension data. |
wolfSSL | 13:80fb167dafdf | 4329 | * returns 0 on success, otherwise failure. |
wolfSSL | 13:80fb167dafdf | 4330 | */ |
wolfSSL | 13:80fb167dafdf | 4331 | static int TLSX_SupportedVersions_Parse(WOLFSSL *ssl, byte* input, |
wolfSSL | 13:80fb167dafdf | 4332 | word16 length) |
wolfSSL | 13:80fb167dafdf | 4333 | { |
wolfSSL | 13:80fb167dafdf | 4334 | ProtocolVersion pv = ssl->ctx->method->version; |
wolfSSL | 13:80fb167dafdf | 4335 | int i; |
wolfSSL | 13:80fb167dafdf | 4336 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 4337 | int len; |
wolfSSL | 13:80fb167dafdf | 4338 | |
wolfSSL | 13:80fb167dafdf | 4339 | /* Must contain a length and at least one version. */ |
wolfSSL | 13:80fb167dafdf | 4340 | if (length < OPAQUE8_LEN + OPAQUE16_LEN || (length & 1) != 1) |
wolfSSL | 13:80fb167dafdf | 4341 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 4342 | |
wolfSSL | 13:80fb167dafdf | 4343 | len = *input; |
wolfSSL | 13:80fb167dafdf | 4344 | |
wolfSSL | 13:80fb167dafdf | 4345 | /* Protocol version array must fill rest of data. */ |
wolfSSL | 13:80fb167dafdf | 4346 | if (length != OPAQUE8_LEN + len) |
wolfSSL | 13:80fb167dafdf | 4347 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 4348 | |
wolfSSL | 13:80fb167dafdf | 4349 | input++; |
wolfSSL | 13:80fb167dafdf | 4350 | |
wolfSSL | 13:80fb167dafdf | 4351 | /* Find first match. */ |
wolfSSL | 13:80fb167dafdf | 4352 | for (i = 0; i < len; i += OPAQUE16_LEN) { |
wolfSSL | 13:80fb167dafdf | 4353 | /* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */ |
wolfSSL | 13:80fb167dafdf | 4354 | if (input[i] == TLS_DRAFT_MAJOR && |
wolfSSL | 13:80fb167dafdf | 4355 | input[i + OPAQUE8_LEN] == TLS_DRAFT_MINOR) { |
wolfSSL | 13:80fb167dafdf | 4356 | ssl->version.minor = TLSv1_3_MINOR; |
wolfSSL | 13:80fb167dafdf | 4357 | ssl->options.tls1_3 = 1; |
wolfSSL | 13:80fb167dafdf | 4358 | TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, input, |
wolfSSL | 13:80fb167dafdf | 4359 | ssl->heap); |
wolfSSL | 13:80fb167dafdf | 4360 | break; |
wolfSSL | 13:80fb167dafdf | 4361 | } |
wolfSSL | 13:80fb167dafdf | 4362 | |
wolfSSL | 13:80fb167dafdf | 4363 | if (input[i] != pv.major) |
wolfSSL | 13:80fb167dafdf | 4364 | continue; |
wolfSSL | 13:80fb167dafdf | 4365 | |
wolfSSL | 13:80fb167dafdf | 4366 | #ifndef NO_OLD_TLS |
wolfSSL | 13:80fb167dafdf | 4367 | if (input[i + OPAQUE8_LEN] == TLSv1_MINOR || |
wolfSSL | 13:80fb167dafdf | 4368 | input[i + OPAQUE8_LEN] == TLSv1_1_MINOR) { |
wolfSSL | 13:80fb167dafdf | 4369 | ssl->version.minor = input[i + OPAQUE8_LEN]; |
wolfSSL | 13:80fb167dafdf | 4370 | break; |
wolfSSL | 13:80fb167dafdf | 4371 | } |
wolfSSL | 13:80fb167dafdf | 4372 | #endif |
wolfSSL | 13:80fb167dafdf | 4373 | if (input[i + OPAQUE8_LEN] == TLSv1_2_MINOR) { |
wolfSSL | 13:80fb167dafdf | 4374 | ssl->version.minor = input[i + OPAQUE8_LEN]; |
wolfSSL | 13:80fb167dafdf | 4375 | TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, input, |
wolfSSL | 13:80fb167dafdf | 4376 | ssl->heap); |
wolfSSL | 13:80fb167dafdf | 4377 | break; |
wolfSSL | 13:80fb167dafdf | 4378 | } |
wolfSSL | 13:80fb167dafdf | 4379 | if (input[i + OPAQUE8_LEN] == TLSv1_3_MINOR) { |
wolfSSL | 13:80fb167dafdf | 4380 | ssl->version.minor = input[i + OPAQUE8_LEN]; |
wolfSSL | 13:80fb167dafdf | 4381 | ssl->options.tls1_3 = 1; |
wolfSSL | 13:80fb167dafdf | 4382 | TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, input, |
wolfSSL | 13:80fb167dafdf | 4383 | ssl->heap); |
wolfSSL | 13:80fb167dafdf | 4384 | break; |
wolfSSL | 13:80fb167dafdf | 4385 | } |
wolfSSL | 13:80fb167dafdf | 4386 | } |
wolfSSL | 13:80fb167dafdf | 4387 | |
wolfSSL | 13:80fb167dafdf | 4388 | return ret; |
wolfSSL | 13:80fb167dafdf | 4389 | } |
wolfSSL | 13:80fb167dafdf | 4390 | |
wolfSSL | 13:80fb167dafdf | 4391 | /* Sets a new SupportedVersions extension into the extension list. |
wolfSSL | 13:80fb167dafdf | 4392 | * |
wolfSSL | 13:80fb167dafdf | 4393 | * extensions The list of extensions. |
wolfSSL | 13:80fb167dafdf | 4394 | * data The extensions specific data. |
wolfSSL | 13:80fb167dafdf | 4395 | * heap The heap used for allocation. |
wolfSSL | 13:80fb167dafdf | 4396 | * returns 0 on success, otherwise failure. |
wolfSSL | 13:80fb167dafdf | 4397 | */ |
wolfSSL | 13:80fb167dafdf | 4398 | static int TLSX_SetSupportedVersions(TLSX** extensions, const void* data, |
wolfSSL | 13:80fb167dafdf | 4399 | void* heap) |
wolfSSL | 13:80fb167dafdf | 4400 | { |
wolfSSL | 13:80fb167dafdf | 4401 | if (extensions == NULL || data == NULL) |
wolfSSL | 13:80fb167dafdf | 4402 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 4403 | |
wolfSSL | 13:80fb167dafdf | 4404 | return TLSX_Push(extensions, TLSX_SUPPORTED_VERSIONS, (void *)data, heap); |
wolfSSL | 13:80fb167dafdf | 4405 | } |
wolfSSL | 13:80fb167dafdf | 4406 | |
wolfSSL | 13:80fb167dafdf | 4407 | #define SV_GET_SIZE TLSX_SupportedVersions_GetSize |
wolfSSL | 13:80fb167dafdf | 4408 | #define SV_WRITE TLSX_SupportedVersions_Write |
wolfSSL | 13:80fb167dafdf | 4409 | #define SV_PARSE TLSX_SupportedVersions_Parse |
wolfSSL | 13:80fb167dafdf | 4410 | |
wolfSSL | 13:80fb167dafdf | 4411 | #else |
wolfSSL | 13:80fb167dafdf | 4412 | |
wolfSSL | 13:80fb167dafdf | 4413 | #define SV_GET_SIZE(a) 0 |
wolfSSL | 13:80fb167dafdf | 4414 | #define SV_WRITE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 4415 | #define SV_PARSE(a, b, c) 0 |
wolfSSL | 13:80fb167dafdf | 4416 | |
wolfSSL | 13:80fb167dafdf | 4417 | #endif /* WOLFSSL_TLS13 */ |
wolfSSL | 13:80fb167dafdf | 4418 | |
wolfSSL | 13:80fb167dafdf | 4419 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 4420 | /* Sugnature Algorithms */ |
wolfSSL | 13:80fb167dafdf | 4421 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 4422 | |
wolfSSL | 13:80fb167dafdf | 4423 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 4424 | /* Return the size of the SignatureAlgorithms extension's data. |
wolfSSL | 13:80fb167dafdf | 4425 | * |
wolfSSL | 13:80fb167dafdf | 4426 | * data Unused |
wolfSSL | 13:80fb167dafdf | 4427 | * returns the length of data that will be in the extension. |
wolfSSL | 13:80fb167dafdf | 4428 | */ |
wolfSSL | 13:80fb167dafdf | 4429 | static word16 TLSX_SignatureAlgorithms_GetSize(byte* data) |
wolfSSL | 13:80fb167dafdf | 4430 | { |
wolfSSL | 13:80fb167dafdf | 4431 | WOLFSSL* ssl = (WOLFSSL*)data; |
wolfSSL | 13:80fb167dafdf | 4432 | int cnt = 0; |
wolfSSL | 13:80fb167dafdf | 4433 | |
wolfSSL | 13:80fb167dafdf | 4434 | (void)data; |
wolfSSL | 13:80fb167dafdf | 4435 | |
wolfSSL | 13:80fb167dafdf | 4436 | #ifndef NO_RSA |
wolfSSL | 13:80fb167dafdf | 4437 | #ifndef NO_SHA1 |
wolfSSL | 13:80fb167dafdf | 4438 | cnt++; |
wolfSSL | 13:80fb167dafdf | 4439 | #endif |
wolfSSL | 13:80fb167dafdf | 4440 | #ifndef NO_SHA256 |
wolfSSL | 13:80fb167dafdf | 4441 | cnt++; |
wolfSSL | 13:80fb167dafdf | 4442 | #endif |
wolfSSL | 13:80fb167dafdf | 4443 | #ifdef HAVE_SHA384 |
wolfSSL | 13:80fb167dafdf | 4444 | cnt++; |
wolfSSL | 13:80fb167dafdf | 4445 | #endif |
wolfSSL | 13:80fb167dafdf | 4446 | #ifdef HAVE_SHA512 |
wolfSSL | 13:80fb167dafdf | 4447 | cnt++; |
wolfSSL | 13:80fb167dafdf | 4448 | #endif |
wolfSSL | 13:80fb167dafdf | 4449 | #ifdef WC_RSA_PSS |
wolfSSL | 13:80fb167dafdf | 4450 | if (IsAtLeastTLSv1_3(ssl->version)) { |
wolfSSL | 13:80fb167dafdf | 4451 | #ifndef NO_SHA256 |
wolfSSL | 13:80fb167dafdf | 4452 | cnt++; |
wolfSSL | 13:80fb167dafdf | 4453 | #endif |
wolfSSL | 13:80fb167dafdf | 4454 | #ifdef HAVE_SHA384 |
wolfSSL | 13:80fb167dafdf | 4455 | cnt++; |
wolfSSL | 13:80fb167dafdf | 4456 | #endif |
wolfSSL | 13:80fb167dafdf | 4457 | #ifdef HAVE_SHA512 |
wolfSSL | 13:80fb167dafdf | 4458 | cnt++; |
wolfSSL | 13:80fb167dafdf | 4459 | #endif |
wolfSSL | 13:80fb167dafdf | 4460 | } |
wolfSSL | 13:80fb167dafdf | 4461 | #endif |
wolfSSL | 13:80fb167dafdf | 4462 | #endif |
wolfSSL | 13:80fb167dafdf | 4463 | |
wolfSSL | 13:80fb167dafdf | 4464 | #ifdef HAVE_ECC |
wolfSSL | 13:80fb167dafdf | 4465 | #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 4466 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 4467 | cnt++; |
wolfSSL | 13:80fb167dafdf | 4468 | #endif |
wolfSSL | 13:80fb167dafdf | 4469 | #endif |
wolfSSL | 13:80fb167dafdf | 4470 | #if !defined(NO_ECC384) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 4471 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 4472 | cnt++; |
wolfSSL | 13:80fb167dafdf | 4473 | #endif |
wolfSSL | 13:80fb167dafdf | 4474 | #endif |
wolfSSL | 13:80fb167dafdf | 4475 | #if !defined(NO_ECC521) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 4476 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 4477 | cnt++; |
wolfSSL | 13:80fb167dafdf | 4478 | #endif |
wolfSSL | 13:80fb167dafdf | 4479 | #endif |
wolfSSL | 13:80fb167dafdf | 4480 | #endif |
wolfSSL | 13:80fb167dafdf | 4481 | |
wolfSSL | 13:80fb167dafdf | 4482 | return OPAQUE16_LEN + cnt * OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 4483 | } |
wolfSSL | 13:80fb167dafdf | 4484 | |
wolfSSL | 13:80fb167dafdf | 4485 | /* Writes the SignatureAlgorithms extension into the buffer. |
wolfSSL | 13:80fb167dafdf | 4486 | * |
wolfSSL | 13:80fb167dafdf | 4487 | * data Unused |
wolfSSL | 13:80fb167dafdf | 4488 | * output The buffer to write the extension into. |
wolfSSL | 13:80fb167dafdf | 4489 | * returns the length of data that was written. |
wolfSSL | 13:80fb167dafdf | 4490 | */ |
wolfSSL | 13:80fb167dafdf | 4491 | static word16 TLSX_SignatureAlgorithms_Write(byte* data, byte* output) |
wolfSSL | 13:80fb167dafdf | 4492 | { |
wolfSSL | 13:80fb167dafdf | 4493 | WOLFSSL* ssl = (WOLFSSL*)data; |
wolfSSL | 13:80fb167dafdf | 4494 | int idx = OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 4495 | |
wolfSSL | 13:80fb167dafdf | 4496 | |
wolfSSL | 13:80fb167dafdf | 4497 | #ifndef NO_RSA |
wolfSSL | 13:80fb167dafdf | 4498 | #ifndef NO_SHA1 |
wolfSSL | 13:80fb167dafdf | 4499 | output[idx++] = 0x02; |
wolfSSL | 13:80fb167dafdf | 4500 | output[idx++] = 0x01; |
wolfSSL | 13:80fb167dafdf | 4501 | #endif |
wolfSSL | 13:80fb167dafdf | 4502 | #ifndef NO_SHA256 |
wolfSSL | 13:80fb167dafdf | 4503 | output[idx++] = 0x04; |
wolfSSL | 13:80fb167dafdf | 4504 | output[idx++] = 0x01; |
wolfSSL | 13:80fb167dafdf | 4505 | #endif |
wolfSSL | 13:80fb167dafdf | 4506 | #ifdef HAVE_SHA384 |
wolfSSL | 13:80fb167dafdf | 4507 | output[idx++] = 0x05; |
wolfSSL | 13:80fb167dafdf | 4508 | output[idx++] = 0x01; |
wolfSSL | 13:80fb167dafdf | 4509 | #endif |
wolfSSL | 13:80fb167dafdf | 4510 | #ifdef HAVE_SHA512 |
wolfSSL | 13:80fb167dafdf | 4511 | output[idx++] = 0x06; |
wolfSSL | 13:80fb167dafdf | 4512 | output[idx++] = 0x01; |
wolfSSL | 13:80fb167dafdf | 4513 | #endif |
wolfSSL | 13:80fb167dafdf | 4514 | #ifdef WC_RSA_PSS |
wolfSSL | 13:80fb167dafdf | 4515 | if (IsAtLeastTLSv1_3(ssl->version)) { |
wolfSSL | 13:80fb167dafdf | 4516 | #ifndef NO_SHA256 |
wolfSSL | 13:80fb167dafdf | 4517 | output[idx++] = 0x08; |
wolfSSL | 13:80fb167dafdf | 4518 | output[idx++] = 0x04; |
wolfSSL | 13:80fb167dafdf | 4519 | #endif |
wolfSSL | 13:80fb167dafdf | 4520 | #ifdef HAVE_SHA384 |
wolfSSL | 13:80fb167dafdf | 4521 | output[idx++] = 0x08; |
wolfSSL | 13:80fb167dafdf | 4522 | output[idx++] = 0x05; |
wolfSSL | 13:80fb167dafdf | 4523 | #endif |
wolfSSL | 13:80fb167dafdf | 4524 | #ifdef HAVE_SHA512 |
wolfSSL | 13:80fb167dafdf | 4525 | output[idx++] = 0x08; |
wolfSSL | 13:80fb167dafdf | 4526 | output[idx++] = 0x06; |
wolfSSL | 13:80fb167dafdf | 4527 | #endif |
wolfSSL | 13:80fb167dafdf | 4528 | } |
wolfSSL | 13:80fb167dafdf | 4529 | #endif |
wolfSSL | 13:80fb167dafdf | 4530 | #endif |
wolfSSL | 13:80fb167dafdf | 4531 | |
wolfSSL | 13:80fb167dafdf | 4532 | #ifdef HAVE_ECC |
wolfSSL | 13:80fb167dafdf | 4533 | #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 4534 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 4535 | output[idx++] = 0x04; |
wolfSSL | 13:80fb167dafdf | 4536 | output[idx++] = 0x03; |
wolfSSL | 13:80fb167dafdf | 4537 | #endif |
wolfSSL | 13:80fb167dafdf | 4538 | #endif |
wolfSSL | 13:80fb167dafdf | 4539 | #if !defined(NO_ECC384) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 4540 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 4541 | output[idx++] = 0x05; |
wolfSSL | 13:80fb167dafdf | 4542 | output[idx++] = 0x03; |
wolfSSL | 13:80fb167dafdf | 4543 | #endif |
wolfSSL | 13:80fb167dafdf | 4544 | #endif |
wolfSSL | 13:80fb167dafdf | 4545 | #if !defined(NO_ECC521) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 4546 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 4547 | output[idx++] = 0x06; |
wolfSSL | 13:80fb167dafdf | 4548 | output[idx++] = 0x03; |
wolfSSL | 13:80fb167dafdf | 4549 | #endif |
wolfSSL | 13:80fb167dafdf | 4550 | #endif |
wolfSSL | 13:80fb167dafdf | 4551 | #endif |
wolfSSL | 13:80fb167dafdf | 4552 | |
wolfSSL | 13:80fb167dafdf | 4553 | output[0] = (idx - OPAQUE16_LEN) >> 8; |
wolfSSL | 13:80fb167dafdf | 4554 | output[1] = idx - OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 4555 | |
wolfSSL | 13:80fb167dafdf | 4556 | return idx; |
wolfSSL | 13:80fb167dafdf | 4557 | } |
wolfSSL | 13:80fb167dafdf | 4558 | |
wolfSSL | 13:80fb167dafdf | 4559 | /* Parse the SignatureAlgorithms extension. |
wolfSSL | 13:80fb167dafdf | 4560 | * |
wolfSSL | 13:80fb167dafdf | 4561 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 4562 | * input The buffer with the extension data. |
wolfSSL | 13:80fb167dafdf | 4563 | * length The length of the extension data. |
wolfSSL | 13:80fb167dafdf | 4564 | * returns 0 on success, otherwise failure. |
wolfSSL | 13:80fb167dafdf | 4565 | */ |
wolfSSL | 13:80fb167dafdf | 4566 | static int TLSX_SignatureAlgorithms_Parse(WOLFSSL *ssl, byte* input, |
wolfSSL | 13:80fb167dafdf | 4567 | word16 length) |
wolfSSL | 13:80fb167dafdf | 4568 | { |
wolfSSL | 13:80fb167dafdf | 4569 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 4570 | word16 len; |
wolfSSL | 13:80fb167dafdf | 4571 | |
wolfSSL | 13:80fb167dafdf | 4572 | (void)ssl; |
wolfSSL | 13:80fb167dafdf | 4573 | |
wolfSSL | 13:80fb167dafdf | 4574 | /* Must contain a length and at least algorithm. */ |
wolfSSL | 13:80fb167dafdf | 4575 | if (length < OPAQUE16_LEN + OPAQUE16_LEN || (length & 1) != 0) |
wolfSSL | 13:80fb167dafdf | 4576 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 4577 | |
wolfSSL | 13:80fb167dafdf | 4578 | ato16(input, &len); |
wolfSSL | 13:80fb167dafdf | 4579 | |
wolfSSL | 13:80fb167dafdf | 4580 | /* Algorithm array must fill rest of data. */ |
wolfSSL | 13:80fb167dafdf | 4581 | if (length != OPAQUE16_LEN + len) |
wolfSSL | 13:80fb167dafdf | 4582 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 4583 | |
wolfSSL | 13:80fb167dafdf | 4584 | /* Ignore for now. */ |
wolfSSL | 13:80fb167dafdf | 4585 | |
wolfSSL | 13:80fb167dafdf | 4586 | return ret; |
wolfSSL | 13:80fb167dafdf | 4587 | } |
wolfSSL | 13:80fb167dafdf | 4588 | |
wolfSSL | 13:80fb167dafdf | 4589 | /* Sets a new SupportedVersions extension into the extension list. |
wolfSSL | 13:80fb167dafdf | 4590 | * |
wolfSSL | 13:80fb167dafdf | 4591 | * extensions The list of extensions. |
wolfSSL | 13:80fb167dafdf | 4592 | * data The extensions specific data. |
wolfSSL | 13:80fb167dafdf | 4593 | * heap The heap used for allocation. |
wolfSSL | 13:80fb167dafdf | 4594 | * returns 0 on success, otherwise failure. |
wolfSSL | 13:80fb167dafdf | 4595 | */ |
wolfSSL | 13:80fb167dafdf | 4596 | static int TLSX_SetSignatureAlgorithms(TLSX** extensions, const void* data, |
wolfSSL | 13:80fb167dafdf | 4597 | void* heap) |
wolfSSL | 13:80fb167dafdf | 4598 | { |
wolfSSL | 13:80fb167dafdf | 4599 | if (extensions == NULL) |
wolfSSL | 13:80fb167dafdf | 4600 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 4601 | |
wolfSSL | 13:80fb167dafdf | 4602 | return TLSX_Push(extensions, TLSX_SIGNATURE_ALGORITHMS, (void *)data, heap); |
wolfSSL | 13:80fb167dafdf | 4603 | } |
wolfSSL | 13:80fb167dafdf | 4604 | |
wolfSSL | 13:80fb167dafdf | 4605 | #define SA_GET_SIZE TLSX_SignatureAlgorithms_GetSize |
wolfSSL | 13:80fb167dafdf | 4606 | #define SA_WRITE TLSX_SignatureAlgorithms_Write |
wolfSSL | 13:80fb167dafdf | 4607 | #define SA_PARSE TLSX_SignatureAlgorithms_Parse |
wolfSSL | 13:80fb167dafdf | 4608 | |
wolfSSL | 13:80fb167dafdf | 4609 | #else |
wolfSSL | 13:80fb167dafdf | 4610 | |
wolfSSL | 13:80fb167dafdf | 4611 | #define SA_GET_SIZE(a) 0 |
wolfSSL | 13:80fb167dafdf | 4612 | #define SA_WRITE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 4613 | #define SA_PARSE(a, b, c) 0 |
wolfSSL | 13:80fb167dafdf | 4614 | |
wolfSSL | 13:80fb167dafdf | 4615 | #endif |
wolfSSL | 13:80fb167dafdf | 4616 | |
wolfSSL | 13:80fb167dafdf | 4617 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 4618 | /* Key Share */ |
wolfSSL | 13:80fb167dafdf | 4619 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 4620 | |
wolfSSL | 13:80fb167dafdf | 4621 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 4622 | #ifndef NO_DH |
wolfSSL | 13:80fb167dafdf | 4623 | /* Create a key share entry using named Diffie-Hellman parameters group. |
wolfSSL | 13:80fb167dafdf | 4624 | * Generates a key pair. |
wolfSSL | 13:80fb167dafdf | 4625 | * |
wolfSSL | 13:80fb167dafdf | 4626 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 4627 | * kse The key share entry object. |
wolfSSL | 13:80fb167dafdf | 4628 | * returns 0 on success, otherwise failure. |
wolfSSL | 13:80fb167dafdf | 4629 | */ |
wolfSSL | 13:80fb167dafdf | 4630 | static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse) |
wolfSSL | 13:80fb167dafdf | 4631 | { |
wolfSSL | 13:80fb167dafdf | 4632 | int ret; |
wolfSSL | 13:80fb167dafdf | 4633 | byte* keyData; |
wolfSSL | 13:80fb167dafdf | 4634 | void* key = NULL; |
wolfSSL | 13:80fb167dafdf | 4635 | word32 keySz; |
wolfSSL | 13:80fb167dafdf | 4636 | word32 dataSz; |
wolfSSL | 13:80fb167dafdf | 4637 | const DhParams* params; |
wolfSSL | 13:80fb167dafdf | 4638 | DhKey dhKey; |
wolfSSL | 13:80fb167dafdf | 4639 | |
wolfSSL | 13:80fb167dafdf | 4640 | /* TODO: [TLS13] The key size should come from wolfcrypt. */ |
wolfSSL | 13:80fb167dafdf | 4641 | /* Pick the parameters from the named group. */ |
wolfSSL | 13:80fb167dafdf | 4642 | switch (kse->group) { |
wolfSSL | 13:80fb167dafdf | 4643 | #ifdef HAVE_FFDHE_2048 |
wolfSSL | 13:80fb167dafdf | 4644 | case WOLFSSL_FFDHE_2048: |
wolfSSL | 13:80fb167dafdf | 4645 | params = wc_Dh_ffdhe2048_Get(); |
wolfSSL | 13:80fb167dafdf | 4646 | keySz = 29; |
wolfSSL | 13:80fb167dafdf | 4647 | break; |
wolfSSL | 13:80fb167dafdf | 4648 | #endif |
wolfSSL | 13:80fb167dafdf | 4649 | #ifdef HAVE_FFDHE_3072 |
wolfSSL | 13:80fb167dafdf | 4650 | case WOLFSSL_FFDHE_3072: |
wolfSSL | 13:80fb167dafdf | 4651 | params = wc_Dh_ffdhe3072_Get(); |
wolfSSL | 13:80fb167dafdf | 4652 | keySz = 34; |
wolfSSL | 13:80fb167dafdf | 4653 | break; |
wolfSSL | 13:80fb167dafdf | 4654 | #endif |
wolfSSL | 13:80fb167dafdf | 4655 | #ifdef HAVE_FFDHE_4096 |
wolfSSL | 13:80fb167dafdf | 4656 | case WOLFSSL_FFDHE_4096: |
wolfSSL | 13:80fb167dafdf | 4657 | params = wc_Dh_ffdhe4096_Get(); |
wolfSSL | 13:80fb167dafdf | 4658 | keySz = 39; |
wolfSSL | 13:80fb167dafdf | 4659 | break; |
wolfSSL | 13:80fb167dafdf | 4660 | #endif |
wolfSSL | 13:80fb167dafdf | 4661 | #ifdef HAVE_FFDHE_6144 |
wolfSSL | 13:80fb167dafdf | 4662 | case WOLFSSL_FFDHE_6144: |
wolfSSL | 13:80fb167dafdf | 4663 | params = wc_Dh_ffdhe6144_Get(); |
wolfSSL | 13:80fb167dafdf | 4664 | keySz = 46; |
wolfSSL | 13:80fb167dafdf | 4665 | break; |
wolfSSL | 13:80fb167dafdf | 4666 | #endif |
wolfSSL | 13:80fb167dafdf | 4667 | #ifdef HAVE_FFDHE_8192 |
wolfSSL | 13:80fb167dafdf | 4668 | case WOLFSSL_FFDHE_8192: |
wolfSSL | 13:80fb167dafdf | 4669 | params = wc_Dh_ffdhe8192_Get(); |
wolfSSL | 13:80fb167dafdf | 4670 | keySz = 52; |
wolfSSL | 13:80fb167dafdf | 4671 | break; |
wolfSSL | 13:80fb167dafdf | 4672 | #endif |
wolfSSL | 13:80fb167dafdf | 4673 | default: |
wolfSSL | 13:80fb167dafdf | 4674 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 4675 | } |
wolfSSL | 13:80fb167dafdf | 4676 | |
wolfSSL | 13:80fb167dafdf | 4677 | ret = wc_InitDhKey_ex(&dhKey, ssl->heap, ssl->devId); |
wolfSSL | 13:80fb167dafdf | 4678 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 4679 | return ret; |
wolfSSL | 13:80fb167dafdf | 4680 | |
wolfSSL | 13:80fb167dafdf | 4681 | /* Allocate space for the public key. */ |
wolfSSL | 13:80fb167dafdf | 4682 | dataSz = params->p_len; |
wolfSSL | 13:80fb167dafdf | 4683 | keyData = (byte*)XMALLOC(dataSz, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4684 | if (keyData == NULL) { |
wolfSSL | 13:80fb167dafdf | 4685 | ret = MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 4686 | goto end; |
wolfSSL | 13:80fb167dafdf | 4687 | } |
wolfSSL | 13:80fb167dafdf | 4688 | /* Allocate space for the private key. */ |
wolfSSL | 13:80fb167dafdf | 4689 | key = (byte*)XMALLOC(keySz, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4690 | if (key == NULL) { |
wolfSSL | 13:80fb167dafdf | 4691 | ret = MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 4692 | goto end; |
wolfSSL | 13:80fb167dafdf | 4693 | } |
wolfSSL | 13:80fb167dafdf | 4694 | |
wolfSSL | 13:80fb167dafdf | 4695 | /* Set key */ |
wolfSSL | 13:80fb167dafdf | 4696 | ret = wc_DhSetKey(&dhKey, |
wolfSSL | 13:80fb167dafdf | 4697 | (byte*)params->p, params->p_len, |
wolfSSL | 13:80fb167dafdf | 4698 | (byte*)params->g, params->g_len); |
wolfSSL | 13:80fb167dafdf | 4699 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 4700 | goto end; |
wolfSSL | 13:80fb167dafdf | 4701 | |
wolfSSL | 13:80fb167dafdf | 4702 | /* Generate a new key pair. */ |
wolfSSL | 13:80fb167dafdf | 4703 | ret = wc_DhGenerateKeyPair(&dhKey, ssl->rng, key, &keySz, keyData, &dataSz); |
wolfSSL | 13:80fb167dafdf | 4704 | #ifdef WOLFSSL_ASYNC_CRYPT |
wolfSSL | 13:80fb167dafdf | 4705 | /* TODO: Make this function non-blocking */ |
wolfSSL | 13:80fb167dafdf | 4706 | if (ret == WC_PENDING_E) { |
wolfSSL | 13:80fb167dafdf | 4707 | ret = wc_AsyncWait(ret, &dhKey.asyncDev, WC_ASYNC_FLAG_NONE); |
wolfSSL | 13:80fb167dafdf | 4708 | } |
wolfSSL | 13:80fb167dafdf | 4709 | #endif |
wolfSSL | 13:80fb167dafdf | 4710 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 4711 | goto end; |
wolfSSL | 13:80fb167dafdf | 4712 | |
wolfSSL | 13:80fb167dafdf | 4713 | if (params->p_len != dataSz) { |
wolfSSL | 13:80fb167dafdf | 4714 | /* Pad the front of the key data with zeros. */ |
wolfSSL | 13:80fb167dafdf | 4715 | XMEMMOVE(keyData + params->p_len - dataSz, keyData, dataSz); |
wolfSSL | 13:80fb167dafdf | 4716 | XMEMSET(keyData, 0, params->p_len - dataSz); |
wolfSSL | 13:80fb167dafdf | 4717 | } |
wolfSSL | 13:80fb167dafdf | 4718 | |
wolfSSL | 13:80fb167dafdf | 4719 | kse->ke = keyData; |
wolfSSL | 13:80fb167dafdf | 4720 | kse->keLen = params->p_len; |
wolfSSL | 13:80fb167dafdf | 4721 | kse->key = key; |
wolfSSL | 13:80fb167dafdf | 4722 | kse->keyLen = keySz; |
wolfSSL | 13:80fb167dafdf | 4723 | |
wolfSSL | 13:80fb167dafdf | 4724 | #ifdef WOLFSSL_DEBUG_TLS |
wolfSSL | 13:80fb167dafdf | 4725 | WOLFSSL_MSG("Public DH Key"); |
wolfSSL | 13:80fb167dafdf | 4726 | WOLFSSL_BUFFER(keyData, params->p_len); |
wolfSSL | 13:80fb167dafdf | 4727 | #endif |
wolfSSL | 13:80fb167dafdf | 4728 | |
wolfSSL | 13:80fb167dafdf | 4729 | end: |
wolfSSL | 13:80fb167dafdf | 4730 | |
wolfSSL | 13:80fb167dafdf | 4731 | wc_FreeDhKey(&dhKey); |
wolfSSL | 13:80fb167dafdf | 4732 | |
wolfSSL | 13:80fb167dafdf | 4733 | if (ret != 0) { |
wolfSSL | 13:80fb167dafdf | 4734 | /* Data owned by key share entry otherwise. */ |
wolfSSL | 13:80fb167dafdf | 4735 | if (keyData != NULL) |
wolfSSL | 13:80fb167dafdf | 4736 | XFREE(keyData, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4737 | if (key != NULL) |
wolfSSL | 13:80fb167dafdf | 4738 | XFREE(key, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4739 | } |
wolfSSL | 13:80fb167dafdf | 4740 | |
wolfSSL | 13:80fb167dafdf | 4741 | return ret; |
wolfSSL | 13:80fb167dafdf | 4742 | } |
wolfSSL | 13:80fb167dafdf | 4743 | #endif |
wolfSSL | 13:80fb167dafdf | 4744 | |
wolfSSL | 13:80fb167dafdf | 4745 | #ifndef NO_ECC |
wolfSSL | 13:80fb167dafdf | 4746 | /* Create a key share entry using named elliptic curve parameters group. |
wolfSSL | 13:80fb167dafdf | 4747 | * Generates a key pair. |
wolfSSL | 13:80fb167dafdf | 4748 | * |
wolfSSL | 13:80fb167dafdf | 4749 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 4750 | * kse The key share entry object. |
wolfSSL | 13:80fb167dafdf | 4751 | * returns 0 on success, otherwise failure. |
wolfSSL | 13:80fb167dafdf | 4752 | */ |
wolfSSL | 13:80fb167dafdf | 4753 | static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) |
wolfSSL | 13:80fb167dafdf | 4754 | { |
wolfSSL | 13:80fb167dafdf | 4755 | int ret; |
wolfSSL | 13:80fb167dafdf | 4756 | byte* keyData = NULL; |
wolfSSL | 13:80fb167dafdf | 4757 | word32 dataSize; |
wolfSSL | 13:80fb167dafdf | 4758 | word32 keySize; |
wolfSSL | 13:80fb167dafdf | 4759 | ecc_key* eccKey; |
wolfSSL | 13:80fb167dafdf | 4760 | word16 curveId; |
wolfSSL | 13:80fb167dafdf | 4761 | |
wolfSSL | 13:80fb167dafdf | 4762 | /* TODO: [TLS13] The key sizes should come from wolfcrypt. */ |
wolfSSL | 13:80fb167dafdf | 4763 | /* Translate named group to a curve id. */ |
wolfSSL | 13:80fb167dafdf | 4764 | switch (kse->group) { |
wolfSSL | 13:80fb167dafdf | 4765 | #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 4766 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 4767 | case WOLFSSL_ECC_SECP256R1: |
wolfSSL | 13:80fb167dafdf | 4768 | curveId = ECC_SECP256R1; |
wolfSSL | 13:80fb167dafdf | 4769 | keySize = 32; |
wolfSSL | 13:80fb167dafdf | 4770 | dataSize = keySize * 2 + 1; |
wolfSSL | 13:80fb167dafdf | 4771 | break; |
wolfSSL | 13:80fb167dafdf | 4772 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:80fb167dafdf | 4773 | #endif |
wolfSSL | 13:80fb167dafdf | 4774 | #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 4775 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 4776 | case WOLFSSL_ECC_SECP384R1: |
wolfSSL | 13:80fb167dafdf | 4777 | curveId = ECC_SECP384R1; |
wolfSSL | 13:80fb167dafdf | 4778 | keySize = 48; |
wolfSSL | 13:80fb167dafdf | 4779 | dataSize = keySize * 2 + 1; |
wolfSSL | 13:80fb167dafdf | 4780 | break; |
wolfSSL | 13:80fb167dafdf | 4781 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:80fb167dafdf | 4782 | #endif |
wolfSSL | 13:80fb167dafdf | 4783 | #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 4784 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 4785 | case WOLFSSL_ECC_SECP521R1: |
wolfSSL | 13:80fb167dafdf | 4786 | curveId = ECC_SECP521R1; |
wolfSSL | 13:80fb167dafdf | 4787 | keySize = 66; |
wolfSSL | 13:80fb167dafdf | 4788 | dataSize = keySize * 2 + 1; |
wolfSSL | 13:80fb167dafdf | 4789 | break; |
wolfSSL | 13:80fb167dafdf | 4790 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:80fb167dafdf | 4791 | #endif |
wolfSSL | 13:80fb167dafdf | 4792 | #ifdef HAVE_CURVE25519 |
wolfSSL | 13:80fb167dafdf | 4793 | case WOLFSSL_ECC_X25519: |
wolfSSL | 13:80fb167dafdf | 4794 | { |
wolfSSL | 13:80fb167dafdf | 4795 | curve25519_key* key; |
wolfSSL | 13:80fb167dafdf | 4796 | /* Allocate an ECC key to hold private key. */ |
wolfSSL | 13:80fb167dafdf | 4797 | key = (curve25519_key*)XMALLOC(sizeof(curve25519_key), |
wolfSSL | 13:80fb167dafdf | 4798 | ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4799 | if (key == NULL) { |
wolfSSL | 13:80fb167dafdf | 4800 | WOLFSSL_MSG("EccTempKey Memory error"); |
wolfSSL | 13:80fb167dafdf | 4801 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 4802 | } |
wolfSSL | 13:80fb167dafdf | 4803 | |
wolfSSL | 13:80fb167dafdf | 4804 | dataSize = keySize = 32; |
wolfSSL | 13:80fb167dafdf | 4805 | |
wolfSSL | 13:80fb167dafdf | 4806 | /* Make an ECC key. */ |
wolfSSL | 13:80fb167dafdf | 4807 | ret = wc_curve25519_init(key); |
wolfSSL | 13:80fb167dafdf | 4808 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 4809 | goto end; |
wolfSSL | 13:80fb167dafdf | 4810 | ret = wc_curve25519_make_key(ssl->rng, keySize, key); |
wolfSSL | 13:80fb167dafdf | 4811 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 4812 | goto end; |
wolfSSL | 13:80fb167dafdf | 4813 | |
wolfSSL | 13:80fb167dafdf | 4814 | /* Allocate space for the public key. */ |
wolfSSL | 13:80fb167dafdf | 4815 | keyData = XMALLOC(dataSize, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4816 | if (keyData == NULL) { |
wolfSSL | 13:80fb167dafdf | 4817 | WOLFSSL_MSG("Key data Memory error"); |
wolfSSL | 13:80fb167dafdf | 4818 | ret = MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 4819 | goto end; |
wolfSSL | 13:80fb167dafdf | 4820 | } |
wolfSSL | 13:80fb167dafdf | 4821 | |
wolfSSL | 13:80fb167dafdf | 4822 | /* Export public key. */ |
wolfSSL | 13:80fb167dafdf | 4823 | if (wc_curve25519_export_public_ex(key, keyData, &dataSize, |
wolfSSL | 13:80fb167dafdf | 4824 | EC25519_LITTLE_ENDIAN) != 0) { |
wolfSSL | 13:80fb167dafdf | 4825 | ret = ECC_EXPORT_ERROR; |
wolfSSL | 13:80fb167dafdf | 4826 | goto end; |
wolfSSL | 13:80fb167dafdf | 4827 | } |
wolfSSL | 13:80fb167dafdf | 4828 | |
wolfSSL | 13:80fb167dafdf | 4829 | kse->ke = keyData; |
wolfSSL | 13:80fb167dafdf | 4830 | kse->keLen = dataSize; |
wolfSSL | 13:80fb167dafdf | 4831 | kse->key = key; |
wolfSSL | 13:80fb167dafdf | 4832 | |
wolfSSL | 13:80fb167dafdf | 4833 | #ifdef WOLFSSL_DEBUG_TLS |
wolfSSL | 13:80fb167dafdf | 4834 | WOLFSSL_MSG("Public ECC Key"); |
wolfSSL | 13:80fb167dafdf | 4835 | WOLFSSL_BUFFER(keyData, dataSize); |
wolfSSL | 13:80fb167dafdf | 4836 | #endif |
wolfSSL | 13:80fb167dafdf | 4837 | |
wolfSSL | 13:80fb167dafdf | 4838 | goto end; |
wolfSSL | 13:80fb167dafdf | 4839 | } |
wolfSSL | 13:80fb167dafdf | 4840 | #endif |
wolfSSL | 13:80fb167dafdf | 4841 | #ifdef HAVE_X448 |
wolfSSL | 13:80fb167dafdf | 4842 | case WOLFSSL_ECC_X448: |
wolfSSL | 13:80fb167dafdf | 4843 | curveId = ECC_X448; |
wolfSSL | 13:80fb167dafdf | 4844 | dataSize = keySize = 56; |
wolfSSL | 13:80fb167dafdf | 4845 | break; |
wolfSSL | 13:80fb167dafdf | 4846 | #endif |
wolfSSL | 13:80fb167dafdf | 4847 | default: |
wolfSSL | 13:80fb167dafdf | 4848 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 4849 | } |
wolfSSL | 13:80fb167dafdf | 4850 | |
wolfSSL | 13:80fb167dafdf | 4851 | /* Allocate an ECC key to hold private key. */ |
wolfSSL | 13:80fb167dafdf | 4852 | eccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4853 | if (eccKey == NULL) { |
wolfSSL | 13:80fb167dafdf | 4854 | WOLFSSL_MSG("EccTempKey Memory error"); |
wolfSSL | 13:80fb167dafdf | 4855 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 4856 | } |
wolfSSL | 13:80fb167dafdf | 4857 | |
wolfSSL | 13:80fb167dafdf | 4858 | /* Make an ECC key. */ |
wolfSSL | 13:80fb167dafdf | 4859 | ret = wc_ecc_init_ex(eccKey, ssl->heap, ssl->devId); |
wolfSSL | 13:80fb167dafdf | 4860 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 4861 | goto end; |
wolfSSL | 13:80fb167dafdf | 4862 | ret = wc_ecc_make_key_ex(ssl->rng, keySize, eccKey, curveId); |
wolfSSL | 13:80fb167dafdf | 4863 | #ifdef WOLFSSL_ASYNC_CRYPT |
wolfSSL | 13:80fb167dafdf | 4864 | /* TODO: Make this function non-blocking */ |
wolfSSL | 13:80fb167dafdf | 4865 | if (ret == WC_PENDING_E) { |
wolfSSL | 13:80fb167dafdf | 4866 | ret = wc_AsyncWait(ret, &eccKey->asyncDev, WC_ASYNC_FLAG_NONE); |
wolfSSL | 13:80fb167dafdf | 4867 | } |
wolfSSL | 13:80fb167dafdf | 4868 | #endif |
wolfSSL | 13:80fb167dafdf | 4869 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 4870 | goto end; |
wolfSSL | 13:80fb167dafdf | 4871 | |
wolfSSL | 13:80fb167dafdf | 4872 | /* Allocate space for the public key. */ |
wolfSSL | 13:80fb167dafdf | 4873 | keyData = XMALLOC(dataSize, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4874 | if (keyData == NULL) { |
wolfSSL | 13:80fb167dafdf | 4875 | WOLFSSL_MSG("Key data Memory error"); |
wolfSSL | 13:80fb167dafdf | 4876 | ret = MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 4877 | goto end; |
wolfSSL | 13:80fb167dafdf | 4878 | } |
wolfSSL | 13:80fb167dafdf | 4879 | |
wolfSSL | 13:80fb167dafdf | 4880 | /* Export public key. */ |
wolfSSL | 13:80fb167dafdf | 4881 | if (wc_ecc_export_x963(eccKey, keyData, &dataSize) != 0) { |
wolfSSL | 13:80fb167dafdf | 4882 | ret = ECC_EXPORT_ERROR; |
wolfSSL | 13:80fb167dafdf | 4883 | goto end; |
wolfSSL | 13:80fb167dafdf | 4884 | } |
wolfSSL | 13:80fb167dafdf | 4885 | |
wolfSSL | 13:80fb167dafdf | 4886 | kse->ke = keyData; |
wolfSSL | 13:80fb167dafdf | 4887 | kse->keLen = dataSize; |
wolfSSL | 13:80fb167dafdf | 4888 | kse->key = eccKey; |
wolfSSL | 13:80fb167dafdf | 4889 | |
wolfSSL | 13:80fb167dafdf | 4890 | #ifdef WOLFSSL_DEBUG_TLS |
wolfSSL | 13:80fb167dafdf | 4891 | WOLFSSL_MSG("Public ECC Key"); |
wolfSSL | 13:80fb167dafdf | 4892 | WOLFSSL_BUFFER(keyData, dataSize); |
wolfSSL | 13:80fb167dafdf | 4893 | #endif |
wolfSSL | 13:80fb167dafdf | 4894 | |
wolfSSL | 13:80fb167dafdf | 4895 | end: |
wolfSSL | 13:80fb167dafdf | 4896 | if (ret != 0) { |
wolfSSL | 13:80fb167dafdf | 4897 | /* Data owned by key share entry otherwise. */ |
wolfSSL | 13:80fb167dafdf | 4898 | if (eccKey != NULL) |
wolfSSL | 13:80fb167dafdf | 4899 | XFREE(eccKey, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4900 | if (keyData != NULL) |
wolfSSL | 13:80fb167dafdf | 4901 | XFREE(keyData, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4902 | } |
wolfSSL | 13:80fb167dafdf | 4903 | return ret; |
wolfSSL | 13:80fb167dafdf | 4904 | } |
wolfSSL | 13:80fb167dafdf | 4905 | #endif /* !NO_ECC */ |
wolfSSL | 13:80fb167dafdf | 4906 | |
wolfSSL | 13:80fb167dafdf | 4907 | /* Generate a secret/key using the key share entry. |
wolfSSL | 13:80fb167dafdf | 4908 | * |
wolfSSL | 13:80fb167dafdf | 4909 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 4910 | * kse The key share entry holding peer data. |
wolfSSL | 13:80fb167dafdf | 4911 | */ |
wolfSSL | 13:80fb167dafdf | 4912 | static int TLSX_KeyShare_GenKey(WOLFSSL *ssl, KeyShareEntry *kse) |
wolfSSL | 13:80fb167dafdf | 4913 | { |
wolfSSL | 13:80fb167dafdf | 4914 | /* Named FFHE groups have a bit set to identify them. */ |
wolfSSL | 13:80fb167dafdf | 4915 | if ((kse->group & NAMED_DH_MASK) == NAMED_DH_MASK) |
wolfSSL | 13:80fb167dafdf | 4916 | return TLSX_KeyShare_GenDhKey(ssl, kse); |
wolfSSL | 13:80fb167dafdf | 4917 | return TLSX_KeyShare_GenEccKey(ssl, kse); |
wolfSSL | 13:80fb167dafdf | 4918 | } |
wolfSSL | 13:80fb167dafdf | 4919 | |
wolfSSL | 13:80fb167dafdf | 4920 | /* Free the key share dynamic data. |
wolfSSL | 13:80fb167dafdf | 4921 | * |
wolfSSL | 13:80fb167dafdf | 4922 | * list The linked list of key share entry objects. |
wolfSSL | 13:80fb167dafdf | 4923 | * heap The heap used for allocation. |
wolfSSL | 13:80fb167dafdf | 4924 | */ |
wolfSSL | 13:80fb167dafdf | 4925 | static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap) |
wolfSSL | 13:80fb167dafdf | 4926 | { |
wolfSSL | 13:80fb167dafdf | 4927 | KeyShareEntry* current; |
wolfSSL | 13:80fb167dafdf | 4928 | |
wolfSSL | 13:80fb167dafdf | 4929 | while ((current = list) != NULL) { |
wolfSSL | 13:80fb167dafdf | 4930 | list = current->next; |
wolfSSL | 13:80fb167dafdf | 4931 | XFREE(current->key, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4932 | XFREE(current->ke, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4933 | XFREE(current, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 4934 | } |
wolfSSL | 13:80fb167dafdf | 4935 | |
wolfSSL | 13:80fb167dafdf | 4936 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 4937 | } |
wolfSSL | 13:80fb167dafdf | 4938 | |
wolfSSL | 13:80fb167dafdf | 4939 | /* Get the size of the encoded key share extension. |
wolfSSL | 13:80fb167dafdf | 4940 | * |
wolfSSL | 13:80fb167dafdf | 4941 | * list The linked list of key share extensions. |
wolfSSL | 13:80fb167dafdf | 4942 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:80fb167dafdf | 4943 | * returns the number of bytes of the encoded key share extension. |
wolfSSL | 13:80fb167dafdf | 4944 | */ |
wolfSSL | 13:80fb167dafdf | 4945 | static word16 TLSX_KeyShare_GetSize(KeyShareEntry* list, byte msgType) |
wolfSSL | 13:80fb167dafdf | 4946 | { |
wolfSSL | 13:80fb167dafdf | 4947 | int len = 0; |
wolfSSL | 13:80fb167dafdf | 4948 | byte isRequest = (msgType == client_hello); |
wolfSSL | 13:80fb167dafdf | 4949 | KeyShareEntry* current; |
wolfSSL | 13:80fb167dafdf | 4950 | |
wolfSSL | 13:80fb167dafdf | 4951 | /* The named group the server wants to use. */ |
wolfSSL | 13:80fb167dafdf | 4952 | if (msgType == hello_retry_request) |
wolfSSL | 13:80fb167dafdf | 4953 | return OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 4954 | |
wolfSSL | 13:80fb167dafdf | 4955 | /* List of key exchange groups. */ |
wolfSSL | 13:80fb167dafdf | 4956 | if (isRequest) |
wolfSSL | 13:80fb167dafdf | 4957 | len += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 4958 | while ((current = list) != NULL) { |
wolfSSL | 13:80fb167dafdf | 4959 | list = current->next; |
wolfSSL | 13:80fb167dafdf | 4960 | |
wolfSSL | 13:80fb167dafdf | 4961 | if (!isRequest && current->key == NULL) |
wolfSSL | 13:80fb167dafdf | 4962 | continue; |
wolfSSL | 13:80fb167dafdf | 4963 | |
wolfSSL | 13:80fb167dafdf | 4964 | len += OPAQUE16_LEN + OPAQUE16_LEN + current->keLen; |
wolfSSL | 13:80fb167dafdf | 4965 | } |
wolfSSL | 13:80fb167dafdf | 4966 | |
wolfSSL | 13:80fb167dafdf | 4967 | return len; |
wolfSSL | 13:80fb167dafdf | 4968 | } |
wolfSSL | 13:80fb167dafdf | 4969 | |
wolfSSL | 13:80fb167dafdf | 4970 | /* Writes the key share extension into the output buffer. |
wolfSSL | 13:80fb167dafdf | 4971 | * Assumes that the the output buffer is big enough to hold data. |
wolfSSL | 13:80fb167dafdf | 4972 | * |
wolfSSL | 13:80fb167dafdf | 4973 | * list The linked list of key share entries. |
wolfSSL | 13:80fb167dafdf | 4974 | * output The buffer to write into. |
wolfSSL | 13:80fb167dafdf | 4975 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:80fb167dafdf | 4976 | * returns the number of bytes written into the buffer. |
wolfSSL | 13:80fb167dafdf | 4977 | */ |
wolfSSL | 13:80fb167dafdf | 4978 | static word16 TLSX_KeyShare_Write(KeyShareEntry* list, byte* output, |
wolfSSL | 13:80fb167dafdf | 4979 | byte msgType) |
wolfSSL | 13:80fb167dafdf | 4980 | { |
wolfSSL | 13:80fb167dafdf | 4981 | word16 i = 0; |
wolfSSL | 13:80fb167dafdf | 4982 | byte isRequest = (msgType == client_hello); |
wolfSSL | 13:80fb167dafdf | 4983 | KeyShareEntry* current; |
wolfSSL | 13:80fb167dafdf | 4984 | |
wolfSSL | 13:80fb167dafdf | 4985 | if (msgType == hello_retry_request) { |
wolfSSL | 13:80fb167dafdf | 4986 | c16toa(list->group, output); |
wolfSSL | 13:80fb167dafdf | 4987 | return OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 4988 | } |
wolfSSL | 13:80fb167dafdf | 4989 | |
wolfSSL | 13:80fb167dafdf | 4990 | /* ClientHello has a list but ServerHello is only the chosen. */ |
wolfSSL | 13:80fb167dafdf | 4991 | if (isRequest) |
wolfSSL | 13:80fb167dafdf | 4992 | i += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 4993 | |
wolfSSL | 13:80fb167dafdf | 4994 | /* Write out all in the list. */ |
wolfSSL | 13:80fb167dafdf | 4995 | while ((current = list) != NULL) { |
wolfSSL | 13:80fb167dafdf | 4996 | list = current->next; |
wolfSSL | 13:80fb167dafdf | 4997 | |
wolfSSL | 13:80fb167dafdf | 4998 | if (!isRequest && current->key == NULL) |
wolfSSL | 13:80fb167dafdf | 4999 | continue; |
wolfSSL | 13:80fb167dafdf | 5000 | |
wolfSSL | 13:80fb167dafdf | 5001 | c16toa(current->group, &output[i]); |
wolfSSL | 13:80fb167dafdf | 5002 | i += KE_GROUP_LEN; |
wolfSSL | 13:80fb167dafdf | 5003 | c16toa(current->keLen, &output[i]); |
wolfSSL | 13:80fb167dafdf | 5004 | i += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 5005 | XMEMCPY(&output[i], current->ke, current->keLen); |
wolfSSL | 13:80fb167dafdf | 5006 | i += current->keLen; |
wolfSSL | 13:80fb167dafdf | 5007 | } |
wolfSSL | 13:80fb167dafdf | 5008 | /* Write the length of the list if required. */ |
wolfSSL | 13:80fb167dafdf | 5009 | if (isRequest) |
wolfSSL | 13:80fb167dafdf | 5010 | c16toa(i - OPAQUE16_LEN, output); |
wolfSSL | 13:80fb167dafdf | 5011 | |
wolfSSL | 13:80fb167dafdf | 5012 | return i; |
wolfSSL | 13:80fb167dafdf | 5013 | } |
wolfSSL | 13:80fb167dafdf | 5014 | |
wolfSSL | 13:80fb167dafdf | 5015 | /* Process the DH key share extension on the client side. |
wolfSSL | 13:80fb167dafdf | 5016 | * |
wolfSSL | 13:80fb167dafdf | 5017 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 5018 | * keyShareEntry The key share entry object to use to calculate shared secret. |
wolfSSL | 13:80fb167dafdf | 5019 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:80fb167dafdf | 5020 | */ |
wolfSSL | 13:80fb167dafdf | 5021 | static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) |
wolfSSL | 13:80fb167dafdf | 5022 | { |
wolfSSL | 13:80fb167dafdf | 5023 | #ifndef NO_DH |
wolfSSL | 13:80fb167dafdf | 5024 | int ret; |
wolfSSL | 13:80fb167dafdf | 5025 | const DhParams* params; |
wolfSSL | 13:80fb167dafdf | 5026 | word16 i; |
wolfSSL | 13:80fb167dafdf | 5027 | byte b; |
wolfSSL | 13:80fb167dafdf | 5028 | DhKey dhKey; |
wolfSSL | 13:80fb167dafdf | 5029 | |
wolfSSL | 13:80fb167dafdf | 5030 | switch (keyShareEntry->group) { |
wolfSSL | 13:80fb167dafdf | 5031 | #ifdef HAVE_FFDHE_2048 |
wolfSSL | 13:80fb167dafdf | 5032 | case WOLFSSL_FFDHE_2048: |
wolfSSL | 13:80fb167dafdf | 5033 | params = wc_Dh_ffdhe2048_Get(); |
wolfSSL | 13:80fb167dafdf | 5034 | break; |
wolfSSL | 13:80fb167dafdf | 5035 | #endif |
wolfSSL | 13:80fb167dafdf | 5036 | #ifdef HAVE_FFDHE_3072 |
wolfSSL | 13:80fb167dafdf | 5037 | case WOLFSSL_FFDHE_3072: |
wolfSSL | 13:80fb167dafdf | 5038 | params = wc_Dh_ffdhe3072_Get(); |
wolfSSL | 13:80fb167dafdf | 5039 | break; |
wolfSSL | 13:80fb167dafdf | 5040 | #endif |
wolfSSL | 13:80fb167dafdf | 5041 | #ifdef HAVE_FFDHE_4096 |
wolfSSL | 13:80fb167dafdf | 5042 | case WOLFSSL_FFDHE_4096: |
wolfSSL | 13:80fb167dafdf | 5043 | params = wc_Dh_ffdhe4096_Get(); |
wolfSSL | 13:80fb167dafdf | 5044 | break; |
wolfSSL | 13:80fb167dafdf | 5045 | #endif |
wolfSSL | 13:80fb167dafdf | 5046 | #ifdef HAVE_FFDHE_6144 |
wolfSSL | 13:80fb167dafdf | 5047 | case WOLFSSL_FFDHE_6144: |
wolfSSL | 13:80fb167dafdf | 5048 | params = wc_Dh_ffdhe6144_Get(); |
wolfSSL | 13:80fb167dafdf | 5049 | break; |
wolfSSL | 13:80fb167dafdf | 5050 | #endif |
wolfSSL | 13:80fb167dafdf | 5051 | #ifdef HAVE_FFDHE_8192 |
wolfSSL | 13:80fb167dafdf | 5052 | case WOLFSSL_FFDHE_8192: |
wolfSSL | 13:80fb167dafdf | 5053 | params = wc_Dh_ffdhe8192_Get(); |
wolfSSL | 13:80fb167dafdf | 5054 | break; |
wolfSSL | 13:80fb167dafdf | 5055 | #endif |
wolfSSL | 13:80fb167dafdf | 5056 | default: |
wolfSSL | 13:80fb167dafdf | 5057 | return PEER_KEY_ERROR; |
wolfSSL | 13:80fb167dafdf | 5058 | } |
wolfSSL | 13:80fb167dafdf | 5059 | |
wolfSSL | 13:80fb167dafdf | 5060 | #ifdef WOLFSSL_DEBUG_TLS |
wolfSSL | 13:80fb167dafdf | 5061 | WOLFSSL_MSG("Peer DH Key"); |
wolfSSL | 13:80fb167dafdf | 5062 | WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen); |
wolfSSL | 13:80fb167dafdf | 5063 | #endif |
wolfSSL | 13:80fb167dafdf | 5064 | |
wolfSSL | 13:80fb167dafdf | 5065 | if (params->p_len != keyShareEntry->keLen) |
wolfSSL | 13:80fb167dafdf | 5066 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 5067 | |
wolfSSL | 13:80fb167dafdf | 5068 | /* TODO: [TLS13] move this check down into wolfcrypt. */ |
wolfSSL | 13:80fb167dafdf | 5069 | /* Check that public DH key is not 0 or 1. */ |
wolfSSL | 13:80fb167dafdf | 5070 | b = 0; |
wolfSSL | 13:80fb167dafdf | 5071 | for (i = 0; i < params->p_len - 1; i++) |
wolfSSL | 13:80fb167dafdf | 5072 | b |= keyShareEntry->ke[i]; |
wolfSSL | 13:80fb167dafdf | 5073 | if (b == 0 && (keyShareEntry->ke[i] == 0x00 || |
wolfSSL | 13:80fb167dafdf | 5074 | keyShareEntry->ke[i] == 0x01)) { |
wolfSSL | 13:80fb167dafdf | 5075 | return PEER_KEY_ERROR; |
wolfSSL | 13:80fb167dafdf | 5076 | } |
wolfSSL | 13:80fb167dafdf | 5077 | /* Check that public DH key is not mod, mod + 1 or mod - 1. */ |
wolfSSL | 13:80fb167dafdf | 5078 | b = 0; |
wolfSSL | 13:80fb167dafdf | 5079 | for (i = 0; i < params->p_len - 1; i++) |
wolfSSL | 13:80fb167dafdf | 5080 | b |= params->p[i] ^ keyShareEntry->ke[i]; |
wolfSSL | 13:80fb167dafdf | 5081 | if (b == 0 && (params->p[i] == keyShareEntry->ke[i] || |
wolfSSL | 13:80fb167dafdf | 5082 | params->p[i] - 1 == keyShareEntry->ke[i] || |
wolfSSL | 13:80fb167dafdf | 5083 | params->p[i] + 1 == keyShareEntry->ke[i])) { |
wolfSSL | 13:80fb167dafdf | 5084 | return PEER_KEY_ERROR; |
wolfSSL | 13:80fb167dafdf | 5085 | } |
wolfSSL | 13:80fb167dafdf | 5086 | |
wolfSSL | 13:80fb167dafdf | 5087 | ret = wc_InitDhKey_ex(&dhKey, ssl->heap, ssl->devId); |
wolfSSL | 13:80fb167dafdf | 5088 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 5089 | return ret; |
wolfSSL | 13:80fb167dafdf | 5090 | |
wolfSSL | 13:80fb167dafdf | 5091 | /* Set key */ |
wolfSSL | 13:80fb167dafdf | 5092 | ret = wc_DhSetKey(&dhKey, |
wolfSSL | 13:80fb167dafdf | 5093 | (byte*)params->p, params->p_len, |
wolfSSL | 13:80fb167dafdf | 5094 | (byte*)params->g, params->g_len); |
wolfSSL | 13:80fb167dafdf | 5095 | if (ret != 0) { |
wolfSSL | 13:80fb167dafdf | 5096 | wc_FreeDhKey(&dhKey); |
wolfSSL | 13:80fb167dafdf | 5097 | return ret; |
wolfSSL | 13:80fb167dafdf | 5098 | } |
wolfSSL | 13:80fb167dafdf | 5099 | |
wolfSSL | 13:80fb167dafdf | 5100 | /* Derive secret from private key and peer's public key. */ |
wolfSSL | 13:80fb167dafdf | 5101 | ret = wc_DhAgree(&dhKey, |
wolfSSL | 13:80fb167dafdf | 5102 | ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, |
wolfSSL | 13:80fb167dafdf | 5103 | keyShareEntry->key, keyShareEntry->keyLen, |
wolfSSL | 13:80fb167dafdf | 5104 | keyShareEntry->ke, keyShareEntry->keLen); |
wolfSSL | 13:80fb167dafdf | 5105 | #ifdef WOLFSSL_ASYNC_CRYPT |
wolfSSL | 13:80fb167dafdf | 5106 | /* TODO: Make this function non-blocking */ |
wolfSSL | 13:80fb167dafdf | 5107 | if (ret == WC_PENDING_E) { |
wolfSSL | 13:80fb167dafdf | 5108 | ret = wc_AsyncWait(ret, &dhKey.asyncDev, WC_ASYNC_FLAG_NONE); |
wolfSSL | 13:80fb167dafdf | 5109 | } |
wolfSSL | 13:80fb167dafdf | 5110 | #endif |
wolfSSL | 13:80fb167dafdf | 5111 | |
wolfSSL | 13:80fb167dafdf | 5112 | wc_FreeDhKey(&dhKey); |
wolfSSL | 13:80fb167dafdf | 5113 | |
wolfSSL | 13:80fb167dafdf | 5114 | return ret; |
wolfSSL | 13:80fb167dafdf | 5115 | #else |
wolfSSL | 13:80fb167dafdf | 5116 | return PEER_KEY_ERROR; |
wolfSSL | 13:80fb167dafdf | 5117 | #endif |
wolfSSL | 13:80fb167dafdf | 5118 | } |
wolfSSL | 13:80fb167dafdf | 5119 | |
wolfSSL | 13:80fb167dafdf | 5120 | /* Process the ECC key share extension on the client side. |
wolfSSL | 13:80fb167dafdf | 5121 | * |
wolfSSL | 13:80fb167dafdf | 5122 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 5123 | * keyShareEntry The key share entry object to use to calculate shared secret. |
wolfSSL | 13:80fb167dafdf | 5124 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:80fb167dafdf | 5125 | */ |
wolfSSL | 13:80fb167dafdf | 5126 | static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) |
wolfSSL | 13:80fb167dafdf | 5127 | { |
wolfSSL | 13:80fb167dafdf | 5128 | #ifndef NO_ECC |
wolfSSL | 13:80fb167dafdf | 5129 | int ret; |
wolfSSL | 13:80fb167dafdf | 5130 | int curveId; |
wolfSSL | 13:80fb167dafdf | 5131 | ecc_key* keyShareKey = (ecc_key*)keyShareEntry->key; |
wolfSSL | 13:80fb167dafdf | 5132 | |
wolfSSL | 13:80fb167dafdf | 5133 | if (ssl->peerEccKey != NULL) |
wolfSSL | 13:80fb167dafdf | 5134 | wc_ecc_free(ssl->peerEccKey); |
wolfSSL | 13:80fb167dafdf | 5135 | |
wolfSSL | 13:80fb167dafdf | 5136 | ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->heap, |
wolfSSL | 13:80fb167dafdf | 5137 | DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 5138 | if (ssl->peerEccKey == NULL) { |
wolfSSL | 13:80fb167dafdf | 5139 | WOLFSSL_MSG("PeerEccKey Memory error"); |
wolfSSL | 13:80fb167dafdf | 5140 | return MEMORY_ERROR; |
wolfSSL | 13:80fb167dafdf | 5141 | } |
wolfSSL | 13:80fb167dafdf | 5142 | ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, ssl->devId); |
wolfSSL | 13:80fb167dafdf | 5143 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 5144 | return ret; |
wolfSSL | 13:80fb167dafdf | 5145 | |
wolfSSL | 13:80fb167dafdf | 5146 | /* find supported curve */ |
wolfSSL | 13:80fb167dafdf | 5147 | switch (keyShareEntry->group) { |
wolfSSL | 13:80fb167dafdf | 5148 | #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 5149 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 5150 | case WOLFSSL_ECC_SECP256R1: |
wolfSSL | 13:80fb167dafdf | 5151 | curveId = ECC_SECP256R1; |
wolfSSL | 13:80fb167dafdf | 5152 | break; |
wolfSSL | 13:80fb167dafdf | 5153 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:80fb167dafdf | 5154 | #endif |
wolfSSL | 13:80fb167dafdf | 5155 | #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 5156 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 5157 | case WOLFSSL_ECC_SECP384R1: |
wolfSSL | 13:80fb167dafdf | 5158 | curveId = ECC_SECP384R1; |
wolfSSL | 13:80fb167dafdf | 5159 | break; |
wolfSSL | 13:80fb167dafdf | 5160 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:80fb167dafdf | 5161 | #endif |
wolfSSL | 13:80fb167dafdf | 5162 | #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 5163 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 5164 | case WOLFSSL_ECC_SECP521R1: |
wolfSSL | 13:80fb167dafdf | 5165 | curveId = ECC_SECP521R1; |
wolfSSL | 13:80fb167dafdf | 5166 | break; |
wolfSSL | 13:80fb167dafdf | 5167 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:80fb167dafdf | 5168 | #endif |
wolfSSL | 13:80fb167dafdf | 5169 | #ifdef HAVE_CURVE25519 |
wolfSSL | 13:80fb167dafdf | 5170 | case WOLFSSL_ECC_X25519: |
wolfSSL | 13:80fb167dafdf | 5171 | { |
wolfSSL | 13:80fb167dafdf | 5172 | curve25519_key* key = (curve25519_key*)keyShareEntry->key; |
wolfSSL | 13:80fb167dafdf | 5173 | curve25519_key* peerEccKey; |
wolfSSL | 13:80fb167dafdf | 5174 | |
wolfSSL | 13:80fb167dafdf | 5175 | if (ssl->peerEccKey != NULL) |
wolfSSL | 13:80fb167dafdf | 5176 | wc_ecc_free(ssl->peerEccKey); |
wolfSSL | 13:80fb167dafdf | 5177 | |
wolfSSL | 13:80fb167dafdf | 5178 | peerEccKey = (curve25519_key*)XMALLOC(sizeof(curve25519_key), |
wolfSSL | 13:80fb167dafdf | 5179 | ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 5180 | if (peerEccKey == NULL) { |
wolfSSL | 13:80fb167dafdf | 5181 | WOLFSSL_MSG("PeerEccKey Memory error"); |
wolfSSL | 13:80fb167dafdf | 5182 | return MEMORY_ERROR; |
wolfSSL | 13:80fb167dafdf | 5183 | } |
wolfSSL | 13:80fb167dafdf | 5184 | ret = wc_curve25519_init(peerEccKey); |
wolfSSL | 13:80fb167dafdf | 5185 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 5186 | return ret; |
wolfSSL | 13:80fb167dafdf | 5187 | #ifdef WOLFSSL_DEBUG_TLS |
wolfSSL | 13:80fb167dafdf | 5188 | WOLFSSL_MSG("Peer ECC Key"); |
wolfSSL | 13:80fb167dafdf | 5189 | WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen); |
wolfSSL | 13:80fb167dafdf | 5190 | #endif |
wolfSSL | 13:80fb167dafdf | 5191 | |
wolfSSL | 13:80fb167dafdf | 5192 | /* Point is validated by import function. */ |
wolfSSL | 13:80fb167dafdf | 5193 | if (wc_curve25519_import_public_ex(keyShareEntry->ke, |
wolfSSL | 13:80fb167dafdf | 5194 | keyShareEntry->keLen, peerEccKey, |
wolfSSL | 13:80fb167dafdf | 5195 | EC25519_LITTLE_ENDIAN) != 0) { |
wolfSSL | 13:80fb167dafdf | 5196 | return ECC_PEERKEY_ERROR; |
wolfSSL | 13:80fb167dafdf | 5197 | } |
wolfSSL | 13:80fb167dafdf | 5198 | |
wolfSSL | 13:80fb167dafdf | 5199 | ssl->arrays->preMasterSz = ENCRYPT_LEN; |
wolfSSL | 13:80fb167dafdf | 5200 | ret = wc_curve25519_shared_secret_ex(key, peerEccKey, |
wolfSSL | 13:80fb167dafdf | 5201 | ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, |
wolfSSL | 13:80fb167dafdf | 5202 | EC25519_LITTLE_ENDIAN); |
wolfSSL | 13:80fb167dafdf | 5203 | wc_curve25519_free(peerEccKey); |
wolfSSL | 13:80fb167dafdf | 5204 | XFREE(peerEccKey, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 5205 | return ret; |
wolfSSL | 13:80fb167dafdf | 5206 | } |
wolfSSL | 13:80fb167dafdf | 5207 | #endif |
wolfSSL | 13:80fb167dafdf | 5208 | #ifdef HAVE_X448 |
wolfSSL | 13:80fb167dafdf | 5209 | case WOLFSSL_ECC_X448: |
wolfSSL | 13:80fb167dafdf | 5210 | curveId = ECC_X448; |
wolfSSL | 13:80fb167dafdf | 5211 | break; |
wolfSSL | 13:80fb167dafdf | 5212 | #endif |
wolfSSL | 13:80fb167dafdf | 5213 | default: |
wolfSSL | 13:80fb167dafdf | 5214 | /* unsupported curve */ |
wolfSSL | 13:80fb167dafdf | 5215 | return ECC_PEERKEY_ERROR; |
wolfSSL | 13:80fb167dafdf | 5216 | } |
wolfSSL | 13:80fb167dafdf | 5217 | |
wolfSSL | 13:80fb167dafdf | 5218 | #ifdef WOLFSSL_DEBUG_TLS |
wolfSSL | 13:80fb167dafdf | 5219 | WOLFSSL_MSG("Peer ECC Key"); |
wolfSSL | 13:80fb167dafdf | 5220 | WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen); |
wolfSSL | 13:80fb167dafdf | 5221 | #endif |
wolfSSL | 13:80fb167dafdf | 5222 | |
wolfSSL | 13:80fb167dafdf | 5223 | /* Point is validated by import function. */ |
wolfSSL | 13:80fb167dafdf | 5224 | if (wc_ecc_import_x963_ex(keyShareEntry->ke, keyShareEntry->keLen, |
wolfSSL | 13:80fb167dafdf | 5225 | ssl->peerEccKey, curveId) != 0) { |
wolfSSL | 13:80fb167dafdf | 5226 | return ECC_PEERKEY_ERROR; |
wolfSSL | 13:80fb167dafdf | 5227 | } |
wolfSSL | 13:80fb167dafdf | 5228 | |
wolfSSL | 13:80fb167dafdf | 5229 | ssl->arrays->preMasterSz = ENCRYPT_LEN; |
wolfSSL | 13:80fb167dafdf | 5230 | do { |
wolfSSL | 13:80fb167dafdf | 5231 | #if defined(WOLFSSL_ASYNC_CRYPT) |
wolfSSL | 13:80fb167dafdf | 5232 | ret = wc_AsyncWait(ret, &keyShareKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); |
wolfSSL | 13:80fb167dafdf | 5233 | #endif |
wolfSSL | 13:80fb167dafdf | 5234 | if (ret >= 0) |
wolfSSL | 13:80fb167dafdf | 5235 | ret = wc_ecc_shared_secret(keyShareKey, ssl->peerEccKey, |
wolfSSL | 13:80fb167dafdf | 5236 | ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz); |
wolfSSL | 13:80fb167dafdf | 5237 | } while (ret == WC_PENDING_E); |
wolfSSL | 13:80fb167dafdf | 5238 | |
wolfSSL | 13:80fb167dafdf | 5239 | #if 0 |
wolfSSL | 13:80fb167dafdf | 5240 | /* TODO: Switch to support async here and use: */ |
wolfSSL | 13:80fb167dafdf | 5241 | ret = EccSharedSecret(ssl, keyShareEntry->key, ssl->peerEccKey, |
wolfSSL | 13:80fb167dafdf | 5242 | keyShareEntry->ke, &keyShareEntry->keLen, |
wolfSSL | 13:80fb167dafdf | 5243 | ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, |
wolfSSL | 13:80fb167dafdf | 5244 | ssl->options.side, |
wolfSSL | 13:80fb167dafdf | 5245 | #ifdef HAVE_PK_CALLBACKS |
wolfSSL | 13:80fb167dafdf | 5246 | ssl->EccSharedSecretCtx |
wolfSSL | 13:80fb167dafdf | 5247 | #else |
wolfSSL | 13:80fb167dafdf | 5248 | NULL |
wolfSSL | 13:80fb167dafdf | 5249 | #endif |
wolfSSL | 13:80fb167dafdf | 5250 | ); |
wolfSSL | 13:80fb167dafdf | 5251 | #endif |
wolfSSL | 13:80fb167dafdf | 5252 | |
wolfSSL | 13:80fb167dafdf | 5253 | return ret; |
wolfSSL | 13:80fb167dafdf | 5254 | #else |
wolfSSL | 13:80fb167dafdf | 5255 | return PEER_KEY_ERROR; |
wolfSSL | 13:80fb167dafdf | 5256 | #endif |
wolfSSL | 13:80fb167dafdf | 5257 | } |
wolfSSL | 13:80fb167dafdf | 5258 | |
wolfSSL | 13:80fb167dafdf | 5259 | /* Process the key share extension on the client side. |
wolfSSL | 13:80fb167dafdf | 5260 | * |
wolfSSL | 13:80fb167dafdf | 5261 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 5262 | * keyShareEntry The key share entry object to use to calculate shared secret. |
wolfSSL | 13:80fb167dafdf | 5263 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:80fb167dafdf | 5264 | */ |
wolfSSL | 13:80fb167dafdf | 5265 | static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) |
wolfSSL | 13:80fb167dafdf | 5266 | { |
wolfSSL | 13:80fb167dafdf | 5267 | int ret; |
wolfSSL | 13:80fb167dafdf | 5268 | |
wolfSSL | 13:80fb167dafdf | 5269 | #ifdef HAVE_SESSION_TICKET |
wolfSSL | 13:80fb167dafdf | 5270 | ssl->session.namedGroup = keyShareEntry->group; |
wolfSSL | 13:80fb167dafdf | 5271 | #endif |
wolfSSL | 13:80fb167dafdf | 5272 | /* Use Key Share Data from server. */ |
wolfSSL | 13:80fb167dafdf | 5273 | if (keyShareEntry->group & NAMED_DH_MASK) |
wolfSSL | 13:80fb167dafdf | 5274 | ret = TLSX_KeyShare_ProcessDh(ssl, keyShareEntry); |
wolfSSL | 13:80fb167dafdf | 5275 | else |
wolfSSL | 13:80fb167dafdf | 5276 | ret = TLSX_KeyShare_ProcessEcc(ssl, keyShareEntry); |
wolfSSL | 13:80fb167dafdf | 5277 | |
wolfSSL | 13:80fb167dafdf | 5278 | #ifdef WOLFSSL_DEBUG_TLS |
wolfSSL | 13:80fb167dafdf | 5279 | WOLFSSL_MSG("KE Secret"); |
wolfSSL | 13:80fb167dafdf | 5280 | WOLFSSL_BUFFER(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz); |
wolfSSL | 13:80fb167dafdf | 5281 | #endif |
wolfSSL | 13:80fb167dafdf | 5282 | |
wolfSSL | 13:80fb167dafdf | 5283 | return ret; |
wolfSSL | 13:80fb167dafdf | 5284 | } |
wolfSSL | 13:80fb167dafdf | 5285 | |
wolfSSL | 13:80fb167dafdf | 5286 | /* Parse an entry of the KeyShare extension. |
wolfSSL | 13:80fb167dafdf | 5287 | * |
wolfSSL | 13:80fb167dafdf | 5288 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 5289 | * input The extension data. |
wolfSSL | 13:80fb167dafdf | 5290 | * length The length of the extension data. |
wolfSSL | 13:80fb167dafdf | 5291 | * kse The new key share entry object. |
wolfSSL | 13:80fb167dafdf | 5292 | * returns a positive number to indicate amount of data parsed and a negative |
wolfSSL | 13:80fb167dafdf | 5293 | * number on error. |
wolfSSL | 13:80fb167dafdf | 5294 | */ |
wolfSSL | 13:80fb167dafdf | 5295 | static int TLSX_KeyShareEntry_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:80fb167dafdf | 5296 | KeyShareEntry **kse) |
wolfSSL | 13:80fb167dafdf | 5297 | { |
wolfSSL | 13:80fb167dafdf | 5298 | int ret; |
wolfSSL | 13:80fb167dafdf | 5299 | word16 group; |
wolfSSL | 13:80fb167dafdf | 5300 | word16 keLen; |
wolfSSL | 13:80fb167dafdf | 5301 | int offset = 0; |
wolfSSL | 13:80fb167dafdf | 5302 | byte* ke; |
wolfSSL | 13:80fb167dafdf | 5303 | |
wolfSSL | 13:80fb167dafdf | 5304 | if (length < OPAQUE16_LEN + OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 5305 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 5306 | /* Named group */ |
wolfSSL | 13:80fb167dafdf | 5307 | ato16(&input[offset], &group); |
wolfSSL | 13:80fb167dafdf | 5308 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 5309 | /* Key exchange data - public key. */ |
wolfSSL | 13:80fb167dafdf | 5310 | ato16(&input[offset], &keLen); |
wolfSSL | 13:80fb167dafdf | 5311 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 5312 | if (keLen < 1 || keLen > length - offset) |
wolfSSL | 13:80fb167dafdf | 5313 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 5314 | |
wolfSSL | 13:80fb167dafdf | 5315 | /* Store a copy in the key share object. */ |
wolfSSL | 13:80fb167dafdf | 5316 | ke = XMALLOC(keLen, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 5317 | if (ke == NULL) |
wolfSSL | 13:80fb167dafdf | 5318 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 5319 | XMEMCPY(ke, &input[offset], keLen); |
wolfSSL | 13:80fb167dafdf | 5320 | |
wolfSSL | 13:80fb167dafdf | 5321 | /* Populate a key share object in the extension. */ |
wolfSSL | 13:80fb167dafdf | 5322 | ret = TLSX_KeyShare_Use(ssl, group, keLen, ke, kse); |
wolfSSL | 13:80fb167dafdf | 5323 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 5324 | return ret; |
wolfSSL | 13:80fb167dafdf | 5325 | |
wolfSSL | 13:80fb167dafdf | 5326 | /* Total length of the parsed data. */ |
wolfSSL | 13:80fb167dafdf | 5327 | return offset + keLen; |
wolfSSL | 13:80fb167dafdf | 5328 | } |
wolfSSL | 13:80fb167dafdf | 5329 | |
wolfSSL | 13:80fb167dafdf | 5330 | /* Searches the groups sent for the specified named group. |
wolfSSL | 13:80fb167dafdf | 5331 | * |
wolfSSL | 13:80fb167dafdf | 5332 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 5333 | * name The group name to match. |
wolfSSL | 13:80fb167dafdf | 5334 | * returns 1 when the extension has the group name and 0 otherwise. |
wolfSSL | 13:80fb167dafdf | 5335 | */ |
wolfSSL | 13:80fb167dafdf | 5336 | static int TLSX_KeyShare_Find(WOLFSSL* ssl, word16 group) |
wolfSSL | 13:80fb167dafdf | 5337 | { |
wolfSSL | 13:80fb167dafdf | 5338 | TLSX* extension; |
wolfSSL | 13:80fb167dafdf | 5339 | KeyShareEntry* list; |
wolfSSL | 13:80fb167dafdf | 5340 | |
wolfSSL | 13:80fb167dafdf | 5341 | extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); |
wolfSSL | 13:80fb167dafdf | 5342 | if (extension == NULL) |
wolfSSL | 13:80fb167dafdf | 5343 | return 0; |
wolfSSL | 13:80fb167dafdf | 5344 | |
wolfSSL | 13:80fb167dafdf | 5345 | list = (KeyShareEntry*)extension->data; |
wolfSSL | 13:80fb167dafdf | 5346 | while (list != NULL) { |
wolfSSL | 13:80fb167dafdf | 5347 | if (list->group == group) { |
wolfSSL | 13:80fb167dafdf | 5348 | return 1; |
wolfSSL | 13:80fb167dafdf | 5349 | } |
wolfSSL | 13:80fb167dafdf | 5350 | list = list->next; |
wolfSSL | 13:80fb167dafdf | 5351 | } |
wolfSSL | 13:80fb167dafdf | 5352 | |
wolfSSL | 13:80fb167dafdf | 5353 | return 0; |
wolfSSL | 13:80fb167dafdf | 5354 | } |
wolfSSL | 13:80fb167dafdf | 5355 | |
wolfSSL | 13:80fb167dafdf | 5356 | /* Parse the KeyShare extension. |
wolfSSL | 13:80fb167dafdf | 5357 | * Different formats in different messages. |
wolfSSL | 13:80fb167dafdf | 5358 | * |
wolfSSL | 13:80fb167dafdf | 5359 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 5360 | * input The extension data. |
wolfSSL | 13:80fb167dafdf | 5361 | * length The length of the extension data. |
wolfSSL | 13:80fb167dafdf | 5362 | * msgType The type of the message this extension is being parsed from. |
wolfSSL | 13:80fb167dafdf | 5363 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:80fb167dafdf | 5364 | */ |
wolfSSL | 13:80fb167dafdf | 5365 | static int TLSX_KeyShare_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:80fb167dafdf | 5366 | byte msgType) |
wolfSSL | 13:80fb167dafdf | 5367 | { |
wolfSSL | 13:80fb167dafdf | 5368 | int ret; |
wolfSSL | 13:80fb167dafdf | 5369 | KeyShareEntry *keyShareEntry; |
wolfSSL | 13:80fb167dafdf | 5370 | |
wolfSSL | 13:80fb167dafdf | 5371 | if (msgType == client_hello) { |
wolfSSL | 13:80fb167dafdf | 5372 | int offset = 0; |
wolfSSL | 13:80fb167dafdf | 5373 | word16 len; |
wolfSSL | 13:80fb167dafdf | 5374 | |
wolfSSL | 13:80fb167dafdf | 5375 | if (length < OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 5376 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 5377 | |
wolfSSL | 13:80fb167dafdf | 5378 | /* ClientHello contains zero or more key share entries. */ |
wolfSSL | 13:80fb167dafdf | 5379 | ato16(input, &len); |
wolfSSL | 13:80fb167dafdf | 5380 | if (len != length - OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 5381 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 5382 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 5383 | |
wolfSSL | 13:80fb167dafdf | 5384 | while (offset < length) { |
wolfSSL | 13:80fb167dafdf | 5385 | ret = TLSX_KeyShareEntry_Parse(ssl, &input[offset], length, |
wolfSSL | 13:80fb167dafdf | 5386 | &keyShareEntry); |
wolfSSL | 13:80fb167dafdf | 5387 | if (ret < 0) |
wolfSSL | 13:80fb167dafdf | 5388 | return ret; |
wolfSSL | 13:80fb167dafdf | 5389 | |
wolfSSL | 13:80fb167dafdf | 5390 | offset += ret; |
wolfSSL | 13:80fb167dafdf | 5391 | } |
wolfSSL | 13:80fb167dafdf | 5392 | |
wolfSSL | 13:80fb167dafdf | 5393 | ret = 0; |
wolfSSL | 13:80fb167dafdf | 5394 | } |
wolfSSL | 13:80fb167dafdf | 5395 | else if (msgType == server_hello) { |
wolfSSL | 13:80fb167dafdf | 5396 | int len; |
wolfSSL | 13:80fb167dafdf | 5397 | |
wolfSSL | 13:80fb167dafdf | 5398 | /* ServerHello contains one key share entry. */ |
wolfSSL | 13:80fb167dafdf | 5399 | len = TLSX_KeyShareEntry_Parse(ssl, input, length, &keyShareEntry); |
wolfSSL | 13:80fb167dafdf | 5400 | if (len != length) |
wolfSSL | 13:80fb167dafdf | 5401 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 5402 | |
wolfSSL | 13:80fb167dafdf | 5403 | /* Not in list sent if there isn't a private key. */ |
wolfSSL | 13:80fb167dafdf | 5404 | if (keyShareEntry->key == NULL) |
wolfSSL | 13:80fb167dafdf | 5405 | return BAD_KEY_SHARE_DATA; |
wolfSSL | 13:80fb167dafdf | 5406 | |
wolfSSL | 13:80fb167dafdf | 5407 | /* Process the entry to calculate the secret. */ |
wolfSSL | 13:80fb167dafdf | 5408 | ret = TLSX_KeyShare_Process(ssl, keyShareEntry); |
wolfSSL | 13:80fb167dafdf | 5409 | } |
wolfSSL | 13:80fb167dafdf | 5410 | else if (msgType == hello_retry_request) { |
wolfSSL | 13:80fb167dafdf | 5411 | word16 group; |
wolfSSL | 13:80fb167dafdf | 5412 | |
wolfSSL | 13:80fb167dafdf | 5413 | if (length != OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 5414 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 5415 | |
wolfSSL | 13:80fb167dafdf | 5416 | /* The data is the named group the server wants to use. */ |
wolfSSL | 13:80fb167dafdf | 5417 | ato16(input, &group); |
wolfSSL | 13:80fb167dafdf | 5418 | |
wolfSSL | 13:80fb167dafdf | 5419 | /* Check the selected group was supported by ClientHello extensions. */ |
wolfSSL | 13:80fb167dafdf | 5420 | if (!TLSX_SupportedGroups_Find(ssl, group)) |
wolfSSL | 13:80fb167dafdf | 5421 | return BAD_KEY_SHARE_DATA; |
wolfSSL | 13:80fb167dafdf | 5422 | |
wolfSSL | 13:80fb167dafdf | 5423 | /* Check if the group was sent. */ |
wolfSSL | 13:80fb167dafdf | 5424 | if (TLSX_KeyShare_Find(ssl, group)) |
wolfSSL | 13:80fb167dafdf | 5425 | return BAD_KEY_SHARE_DATA; |
wolfSSL | 13:80fb167dafdf | 5426 | |
wolfSSL | 13:80fb167dafdf | 5427 | /* Try to use the server's group. */ |
wolfSSL | 13:80fb167dafdf | 5428 | ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL); |
wolfSSL | 13:80fb167dafdf | 5429 | } |
wolfSSL | 13:80fb167dafdf | 5430 | else { |
wolfSSL | 13:80fb167dafdf | 5431 | /* Not a message type that is allowed to have this extension. */ |
wolfSSL | 13:80fb167dafdf | 5432 | return SANITY_MSG_E; |
wolfSSL | 13:80fb167dafdf | 5433 | } |
wolfSSL | 13:80fb167dafdf | 5434 | |
wolfSSL | 13:80fb167dafdf | 5435 | return ret; |
wolfSSL | 13:80fb167dafdf | 5436 | } |
wolfSSL | 13:80fb167dafdf | 5437 | |
wolfSSL | 13:80fb167dafdf | 5438 | /* Create a new key share entry and put it into the list. |
wolfSSL | 13:80fb167dafdf | 5439 | * |
wolfSSL | 13:80fb167dafdf | 5440 | * list The linked list of key share entries. |
wolfSSL | 13:80fb167dafdf | 5441 | * group The named group. |
wolfSSL | 13:80fb167dafdf | 5442 | * heap The memory to allocate with. |
wolfSSL | 13:80fb167dafdf | 5443 | * keyShareEntry The new key share entry object. |
wolfSSL | 13:80fb167dafdf | 5444 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:80fb167dafdf | 5445 | */ |
wolfSSL | 13:80fb167dafdf | 5446 | static int TLSX_KeyShare_New(KeyShareEntry** list, int group, void *heap, |
wolfSSL | 13:80fb167dafdf | 5447 | KeyShareEntry** keyShareEntry) |
wolfSSL | 13:80fb167dafdf | 5448 | { |
wolfSSL | 13:80fb167dafdf | 5449 | KeyShareEntry* kse; |
wolfSSL | 13:80fb167dafdf | 5450 | |
wolfSSL | 13:80fb167dafdf | 5451 | kse = (KeyShareEntry*)XMALLOC(sizeof(KeyShareEntry), heap, |
wolfSSL | 13:80fb167dafdf | 5452 | DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 5453 | if (kse == NULL) |
wolfSSL | 13:80fb167dafdf | 5454 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 5455 | |
wolfSSL | 13:80fb167dafdf | 5456 | XMEMSET(kse, 0, sizeof(*kse)); |
wolfSSL | 13:80fb167dafdf | 5457 | kse->group = group; |
wolfSSL | 13:80fb167dafdf | 5458 | |
wolfSSL | 13:80fb167dafdf | 5459 | /* Add it to the back and maintain the links. */ |
wolfSSL | 13:80fb167dafdf | 5460 | while (*list != NULL) |
wolfSSL | 13:80fb167dafdf | 5461 | list = &((*list)->next); |
wolfSSL | 13:80fb167dafdf | 5462 | *list = kse; |
wolfSSL | 13:80fb167dafdf | 5463 | *keyShareEntry = kse; |
wolfSSL | 13:80fb167dafdf | 5464 | |
wolfSSL | 13:80fb167dafdf | 5465 | return 0; |
wolfSSL | 13:80fb167dafdf | 5466 | } |
wolfSSL | 13:80fb167dafdf | 5467 | |
wolfSSL | 13:80fb167dafdf | 5468 | /* Use the data to create a new key share object in the extensions. |
wolfSSL | 13:80fb167dafdf | 5469 | * |
wolfSSL | 13:80fb167dafdf | 5470 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 5471 | * group The named group. |
wolfSSL | 13:80fb167dafdf | 5472 | * len The length of the public key data. |
wolfSSL | 13:80fb167dafdf | 5473 | * data The public key data. |
wolfSSL | 13:80fb167dafdf | 5474 | * kse The new key share entry object. |
wolfSSL | 13:80fb167dafdf | 5475 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:80fb167dafdf | 5476 | */ |
wolfSSL | 13:80fb167dafdf | 5477 | int TLSX_KeyShare_Use(WOLFSSL* ssl, word16 group, word16 len, byte* data, |
wolfSSL | 13:80fb167dafdf | 5478 | KeyShareEntry **kse) |
wolfSSL | 13:80fb167dafdf | 5479 | { |
wolfSSL | 13:80fb167dafdf | 5480 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 5481 | TLSX* extension; |
wolfSSL | 13:80fb167dafdf | 5482 | KeyShareEntry* keyShareEntry = NULL; |
wolfSSL | 13:80fb167dafdf | 5483 | |
wolfSSL | 13:80fb167dafdf | 5484 | /* Find the KeyShare extension if it exists. */ |
wolfSSL | 13:80fb167dafdf | 5485 | extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); |
wolfSSL | 13:80fb167dafdf | 5486 | if (extension == NULL) { |
wolfSSL | 13:80fb167dafdf | 5487 | /* Push new KeyShare extension. */ |
wolfSSL | 13:80fb167dafdf | 5488 | ret = TLSX_Push(&ssl->extensions, TLSX_KEY_SHARE, NULL, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 5489 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 5490 | return ret; |
wolfSSL | 13:80fb167dafdf | 5491 | |
wolfSSL | 13:80fb167dafdf | 5492 | extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); |
wolfSSL | 13:80fb167dafdf | 5493 | if (extension == NULL) |
wolfSSL | 13:80fb167dafdf | 5494 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 5495 | } |
wolfSSL | 13:80fb167dafdf | 5496 | |
wolfSSL | 13:80fb167dafdf | 5497 | /* Try to find the key share entry with this group. */ |
wolfSSL | 13:80fb167dafdf | 5498 | keyShareEntry = (KeyShareEntry*)extension->data; |
wolfSSL | 13:80fb167dafdf | 5499 | while (keyShareEntry != NULL) { |
wolfSSL | 13:80fb167dafdf | 5500 | if (keyShareEntry->group == group) |
wolfSSL | 13:80fb167dafdf | 5501 | break; |
wolfSSL | 13:80fb167dafdf | 5502 | keyShareEntry = keyShareEntry->next; |
wolfSSL | 13:80fb167dafdf | 5503 | } |
wolfSSL | 13:80fb167dafdf | 5504 | |
wolfSSL | 13:80fb167dafdf | 5505 | /* Create a new key share entry if not found. */ |
wolfSSL | 13:80fb167dafdf | 5506 | if (keyShareEntry == NULL) { |
wolfSSL | 13:80fb167dafdf | 5507 | ret = TLSX_KeyShare_New((KeyShareEntry**)&extension->data, group, |
wolfSSL | 13:80fb167dafdf | 5508 | ssl->heap, &keyShareEntry); |
wolfSSL | 13:80fb167dafdf | 5509 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 5510 | return ret; |
wolfSSL | 13:80fb167dafdf | 5511 | } |
wolfSSL | 13:80fb167dafdf | 5512 | |
wolfSSL | 13:80fb167dafdf | 5513 | if (data != NULL) { |
wolfSSL | 13:80fb167dafdf | 5514 | /* Keep the public key data and free when finished. */ |
wolfSSL | 13:80fb167dafdf | 5515 | if (keyShareEntry->ke != NULL) |
wolfSSL | 13:80fb167dafdf | 5516 | XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 5517 | keyShareEntry->ke = data; |
wolfSSL | 13:80fb167dafdf | 5518 | keyShareEntry->keLen = len; |
wolfSSL | 13:80fb167dafdf | 5519 | } |
wolfSSL | 13:80fb167dafdf | 5520 | else { |
wolfSSL | 13:80fb167dafdf | 5521 | /* Generate a key pair. */ |
wolfSSL | 13:80fb167dafdf | 5522 | ret = TLSX_KeyShare_GenKey(ssl, keyShareEntry); |
wolfSSL | 13:80fb167dafdf | 5523 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 5524 | return ret; |
wolfSSL | 13:80fb167dafdf | 5525 | } |
wolfSSL | 13:80fb167dafdf | 5526 | |
wolfSSL | 13:80fb167dafdf | 5527 | if (kse != NULL) |
wolfSSL | 13:80fb167dafdf | 5528 | *kse = keyShareEntry; |
wolfSSL | 13:80fb167dafdf | 5529 | |
wolfSSL | 13:80fb167dafdf | 5530 | return 0; |
wolfSSL | 13:80fb167dafdf | 5531 | } |
wolfSSL | 13:80fb167dafdf | 5532 | |
wolfSSL | 13:80fb167dafdf | 5533 | /* Set an empty Key Share extension. |
wolfSSL | 13:80fb167dafdf | 5534 | * |
wolfSSL | 13:80fb167dafdf | 5535 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 5536 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:80fb167dafdf | 5537 | */ |
wolfSSL | 13:80fb167dafdf | 5538 | int TLSX_KeyShare_Empty(WOLFSSL* ssl) |
wolfSSL | 13:80fb167dafdf | 5539 | { |
wolfSSL | 13:80fb167dafdf | 5540 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 5541 | TLSX* extension; |
wolfSSL | 13:80fb167dafdf | 5542 | |
wolfSSL | 13:80fb167dafdf | 5543 | /* Find the KeyShare extension if it exists. */ |
wolfSSL | 13:80fb167dafdf | 5544 | extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); |
wolfSSL | 13:80fb167dafdf | 5545 | if (extension == NULL) { |
wolfSSL | 13:80fb167dafdf | 5546 | /* Push new KeyShare extension. */ |
wolfSSL | 13:80fb167dafdf | 5547 | ret = TLSX_Push(&ssl->extensions, TLSX_KEY_SHARE, NULL, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 5548 | } |
wolfSSL | 13:80fb167dafdf | 5549 | else if (extension->data != NULL) { |
wolfSSL | 13:80fb167dafdf | 5550 | TLSX_KeyShare_FreeAll(extension->data, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 5551 | extension->data = NULL; |
wolfSSL | 13:80fb167dafdf | 5552 | } |
wolfSSL | 13:80fb167dafdf | 5553 | |
wolfSSL | 13:80fb167dafdf | 5554 | return ret; |
wolfSSL | 13:80fb167dafdf | 5555 | } |
wolfSSL | 13:80fb167dafdf | 5556 | |
wolfSSL | 13:80fb167dafdf | 5557 | /* Returns whether this group is supported. |
wolfSSL | 13:80fb167dafdf | 5558 | * |
wolfSSL | 13:80fb167dafdf | 5559 | * namedGroup The named group to check. |
wolfSSL | 13:80fb167dafdf | 5560 | * returns 1 when supported or 0 otherwise. |
wolfSSL | 13:80fb167dafdf | 5561 | */ |
wolfSSL | 13:80fb167dafdf | 5562 | static int TLSX_KeyShare_IsSupported(int namedGroup) |
wolfSSL | 13:80fb167dafdf | 5563 | { |
wolfSSL | 13:80fb167dafdf | 5564 | switch (namedGroup) { |
wolfSSL | 13:80fb167dafdf | 5565 | #ifdef HAVE_FFDHE_2048 |
wolfSSL | 13:80fb167dafdf | 5566 | case WOLFSSL_FFDHE_2048: |
wolfSSL | 13:80fb167dafdf | 5567 | break; |
wolfSSL | 13:80fb167dafdf | 5568 | #endif |
wolfSSL | 13:80fb167dafdf | 5569 | #ifdef HAVE_FFDHE_3072 |
wolfSSL | 13:80fb167dafdf | 5570 | case WOLFSSL_FFDHE_3072: |
wolfSSL | 13:80fb167dafdf | 5571 | break; |
wolfSSL | 13:80fb167dafdf | 5572 | #endif |
wolfSSL | 13:80fb167dafdf | 5573 | #ifdef HAVE_FFDHE_4096 |
wolfSSL | 13:80fb167dafdf | 5574 | case WOLFSSL_FFDHE_4096: |
wolfSSL | 13:80fb167dafdf | 5575 | break; |
wolfSSL | 13:80fb167dafdf | 5576 | #endif |
wolfSSL | 13:80fb167dafdf | 5577 | #ifdef HAVE_FFDHE_6144 |
wolfSSL | 13:80fb167dafdf | 5578 | case WOLFSSL_FFDHE_6144: |
wolfSSL | 13:80fb167dafdf | 5579 | break; |
wolfSSL | 13:80fb167dafdf | 5580 | #endif |
wolfSSL | 13:80fb167dafdf | 5581 | #ifdef HAVE_FFDHE_8192 |
wolfSSL | 13:80fb167dafdf | 5582 | case WOLFSSL_FFDHE_8192: |
wolfSSL | 13:80fb167dafdf | 5583 | break; |
wolfSSL | 13:80fb167dafdf | 5584 | #endif |
wolfSSL | 13:80fb167dafdf | 5585 | #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 5586 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 5587 | case WOLFSSL_ECC_SECP256R1: |
wolfSSL | 13:80fb167dafdf | 5588 | break; |
wolfSSL | 13:80fb167dafdf | 5589 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:80fb167dafdf | 5590 | #endif |
wolfSSL | 13:80fb167dafdf | 5591 | #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 5592 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 5593 | case WOLFSSL_ECC_SECP384R1: |
wolfSSL | 13:80fb167dafdf | 5594 | break; |
wolfSSL | 13:80fb167dafdf | 5595 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:80fb167dafdf | 5596 | #endif |
wolfSSL | 13:80fb167dafdf | 5597 | #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 5598 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 5599 | case WOLFSSL_ECC_SECP521R1: |
wolfSSL | 13:80fb167dafdf | 5600 | break; |
wolfSSL | 13:80fb167dafdf | 5601 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 13:80fb167dafdf | 5602 | #endif |
wolfSSL | 13:80fb167dafdf | 5603 | #ifdef HAVE_CURVE25519 |
wolfSSL | 13:80fb167dafdf | 5604 | case WOLFSSL_ECC_X25519: |
wolfSSL | 13:80fb167dafdf | 5605 | break; |
wolfSSL | 13:80fb167dafdf | 5606 | #endif |
wolfSSL | 13:80fb167dafdf | 5607 | #ifdef HAVE_X448 |
wolfSSL | 13:80fb167dafdf | 5608 | case WOLFSSL_ECC_X448: |
wolfSSL | 13:80fb167dafdf | 5609 | break; |
wolfSSL | 13:80fb167dafdf | 5610 | #endif |
wolfSSL | 13:80fb167dafdf | 5611 | default: |
wolfSSL | 13:80fb167dafdf | 5612 | return 0; |
wolfSSL | 13:80fb167dafdf | 5613 | } |
wolfSSL | 13:80fb167dafdf | 5614 | |
wolfSSL | 13:80fb167dafdf | 5615 | return 1; |
wolfSSL | 13:80fb167dafdf | 5616 | } |
wolfSSL | 13:80fb167dafdf | 5617 | |
wolfSSL | 13:80fb167dafdf | 5618 | /* Set a key share that is supported by the client into extensions. |
wolfSSL | 13:80fb167dafdf | 5619 | * |
wolfSSL | 13:80fb167dafdf | 5620 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 5621 | * returns BAD_KEY_SHARE_DATA if no supported group has a key share, |
wolfSSL | 13:80fb167dafdf | 5622 | * 0 if a supported group has a key share and other values indicate an error. |
wolfSSL | 13:80fb167dafdf | 5623 | */ |
wolfSSL | 13:80fb167dafdf | 5624 | static int TLSX_KeyShare_SetSupported(WOLFSSL* ssl) |
wolfSSL | 13:80fb167dafdf | 5625 | { |
wolfSSL | 13:80fb167dafdf | 5626 | int ret; |
wolfSSL | 13:80fb167dafdf | 5627 | TLSX* extension; |
wolfSSL | 13:80fb167dafdf | 5628 | EllipticCurve* curve = NULL; |
wolfSSL | 13:80fb167dafdf | 5629 | |
wolfSSL | 13:80fb167dafdf | 5630 | /* Use SupportedGroup's order. */ |
wolfSSL | 13:80fb167dafdf | 5631 | extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS); |
wolfSSL | 13:80fb167dafdf | 5632 | if (extension != NULL) |
wolfSSL | 13:80fb167dafdf | 5633 | curve = (EllipticCurve*)extension->data; |
wolfSSL | 13:80fb167dafdf | 5634 | for (; curve != NULL; curve = curve->next) { |
wolfSSL | 13:80fb167dafdf | 5635 | if (TLSX_KeyShare_IsSupported(curve->name) && |
wolfSSL | 13:80fb167dafdf | 5636 | !TLSX_KeyShare_Find(ssl, curve->name)) { |
wolfSSL | 13:80fb167dafdf | 5637 | break; |
wolfSSL | 13:80fb167dafdf | 5638 | } |
wolfSSL | 13:80fb167dafdf | 5639 | } |
wolfSSL | 13:80fb167dafdf | 5640 | if (curve == NULL) |
wolfSSL | 13:80fb167dafdf | 5641 | return BAD_KEY_SHARE_DATA; |
wolfSSL | 13:80fb167dafdf | 5642 | |
wolfSSL | 13:80fb167dafdf | 5643 | /* Delete the old key share data list. */ |
wolfSSL | 13:80fb167dafdf | 5644 | extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); |
wolfSSL | 13:80fb167dafdf | 5645 | if (extension != NULL) { |
wolfSSL | 13:80fb167dafdf | 5646 | TLSX_KeyShare_FreeAll(extension->data, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 5647 | extension->data = NULL; |
wolfSSL | 13:80fb167dafdf | 5648 | } |
wolfSSL | 13:80fb167dafdf | 5649 | |
wolfSSL | 13:80fb167dafdf | 5650 | /* Add in the chosen group. */ |
wolfSSL | 13:80fb167dafdf | 5651 | ret = TLSX_KeyShare_Use(ssl, curve->name, 0, NULL, NULL); |
wolfSSL | 13:80fb167dafdf | 5652 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 5653 | return ret; |
wolfSSL | 13:80fb167dafdf | 5654 | |
wolfSSL | 13:80fb167dafdf | 5655 | /* Set extension to be in reponse. */ |
wolfSSL | 13:80fb167dafdf | 5656 | extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); |
wolfSSL | 13:80fb167dafdf | 5657 | extension->resp = 1; |
wolfSSL | 13:80fb167dafdf | 5658 | |
wolfSSL | 13:80fb167dafdf | 5659 | return 0; |
wolfSSL | 13:80fb167dafdf | 5660 | } |
wolfSSL | 13:80fb167dafdf | 5661 | |
wolfSSL | 13:80fb167dafdf | 5662 | /* Establish the secret based on the key shares received from the client. |
wolfSSL | 13:80fb167dafdf | 5663 | * |
wolfSSL | 13:80fb167dafdf | 5664 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 5665 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:80fb167dafdf | 5666 | */ |
wolfSSL | 13:80fb167dafdf | 5667 | int TLSX_KeyShare_Establish(WOLFSSL *ssl) |
wolfSSL | 13:80fb167dafdf | 5668 | { |
wolfSSL | 13:80fb167dafdf | 5669 | int ret; |
wolfSSL | 13:80fb167dafdf | 5670 | TLSX* extension; |
wolfSSL | 13:80fb167dafdf | 5671 | KeyShareEntry* clientKSE = NULL; |
wolfSSL | 13:80fb167dafdf | 5672 | KeyShareEntry* serverKSE; |
wolfSSL | 13:80fb167dafdf | 5673 | KeyShareEntry* list = NULL; |
wolfSSL | 13:80fb167dafdf | 5674 | byte* ke; |
wolfSSL | 13:80fb167dafdf | 5675 | word16 keLen; |
wolfSSL | 13:80fb167dafdf | 5676 | |
wolfSSL | 13:80fb167dafdf | 5677 | /* Find the KeyShare extension if it exists. */ |
wolfSSL | 13:80fb167dafdf | 5678 | extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); |
wolfSSL | 13:80fb167dafdf | 5679 | if (extension != NULL) |
wolfSSL | 13:80fb167dafdf | 5680 | list = (KeyShareEntry*)extension->data; |
wolfSSL | 13:80fb167dafdf | 5681 | |
wolfSSL | 13:80fb167dafdf | 5682 | /* TODO: [TLS13] Server's preference and sending back SupportedGroups */ |
wolfSSL | 13:80fb167dafdf | 5683 | /* Use client's preference. */ |
wolfSSL | 13:80fb167dafdf | 5684 | for (clientKSE = list; clientKSE != NULL; clientKSE = clientKSE->next) { |
wolfSSL | 13:80fb167dafdf | 5685 | /* Check consistency now - extensions in any order. */ |
wolfSSL | 13:80fb167dafdf | 5686 | if (!TLSX_SupportedGroups_Find(ssl, clientKSE->group)) |
wolfSSL | 13:80fb167dafdf | 5687 | return BAD_KEY_SHARE_DATA; |
wolfSSL | 13:80fb167dafdf | 5688 | |
wolfSSL | 13:80fb167dafdf | 5689 | /* Check if server supports group. */ |
wolfSSL | 13:80fb167dafdf | 5690 | if (TLSX_KeyShare_IsSupported(clientKSE->group)) |
wolfSSL | 13:80fb167dafdf | 5691 | break; |
wolfSSL | 13:80fb167dafdf | 5692 | } |
wolfSSL | 13:80fb167dafdf | 5693 | /* No supported group found - send HelloRetryRequest. */ |
wolfSSL | 13:80fb167dafdf | 5694 | if (clientKSE == NULL) { |
wolfSSL | 13:80fb167dafdf | 5695 | ret = TLSX_KeyShare_SetSupported(ssl); |
wolfSSL | 13:80fb167dafdf | 5696 | /* Return KEY_SHARE_ERROR to indicate HelloRetryRequest required. */ |
wolfSSL | 13:80fb167dafdf | 5697 | if (ret == 0) |
wolfSSL | 13:80fb167dafdf | 5698 | return KEY_SHARE_ERROR; |
wolfSSL | 13:80fb167dafdf | 5699 | return ret; |
wolfSSL | 13:80fb167dafdf | 5700 | } |
wolfSSL | 13:80fb167dafdf | 5701 | |
wolfSSL | 13:80fb167dafdf | 5702 | list = NULL; |
wolfSSL | 13:80fb167dafdf | 5703 | /* Generate a new key pair. */ |
wolfSSL | 13:80fb167dafdf | 5704 | ret = TLSX_KeyShare_New(&list, clientKSE->group, ssl->heap, &serverKSE); |
wolfSSL | 13:80fb167dafdf | 5705 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 5706 | return ret; |
wolfSSL | 13:80fb167dafdf | 5707 | ret = TLSX_KeyShare_GenKey(ssl, serverKSE); |
wolfSSL | 13:80fb167dafdf | 5708 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 5709 | return ret; |
wolfSSL | 13:80fb167dafdf | 5710 | |
wolfSSL | 13:80fb167dafdf | 5711 | /* Move private key to client entry. */ |
wolfSSL | 13:80fb167dafdf | 5712 | if (clientKSE->key != NULL) |
wolfSSL | 13:80fb167dafdf | 5713 | XFREE(clientKSE->key, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 5714 | clientKSE->key = serverKSE->key; |
wolfSSL | 13:80fb167dafdf | 5715 | serverKSE->key = NULL; |
wolfSSL | 13:80fb167dafdf | 5716 | clientKSE->keyLen = serverKSE->keyLen; |
wolfSSL | 13:80fb167dafdf | 5717 | |
wolfSSL | 13:80fb167dafdf | 5718 | /* Calculate secret. */ |
wolfSSL | 13:80fb167dafdf | 5719 | ret = TLSX_KeyShare_Process(ssl, clientKSE); |
wolfSSL | 13:80fb167dafdf | 5720 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 5721 | return ret; |
wolfSSL | 13:80fb167dafdf | 5722 | |
wolfSSL | 13:80fb167dafdf | 5723 | /* Swap public keys for sending to client. */ |
wolfSSL | 13:80fb167dafdf | 5724 | ke = serverKSE->ke; |
wolfSSL | 13:80fb167dafdf | 5725 | keLen = serverKSE->keLen; |
wolfSSL | 13:80fb167dafdf | 5726 | serverKSE->ke = clientKSE->ke; |
wolfSSL | 13:80fb167dafdf | 5727 | serverKSE->keLen = clientKSE->keLen; |
wolfSSL | 13:80fb167dafdf | 5728 | clientKSE->ke = ke; |
wolfSSL | 13:80fb167dafdf | 5729 | clientKSE->keLen = keLen; |
wolfSSL | 13:80fb167dafdf | 5730 | |
wolfSSL | 13:80fb167dafdf | 5731 | extension->resp = 1; |
wolfSSL | 13:80fb167dafdf | 5732 | |
wolfSSL | 13:80fb167dafdf | 5733 | /* Dispose of temporary server extension. */ |
wolfSSL | 13:80fb167dafdf | 5734 | TLSX_KeyShare_FreeAll(list, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 5735 | |
wolfSSL | 13:80fb167dafdf | 5736 | return 0; |
wolfSSL | 13:80fb167dafdf | 5737 | } |
wolfSSL | 13:80fb167dafdf | 5738 | |
wolfSSL | 13:80fb167dafdf | 5739 | #define KS_FREE_ALL TLSX_KeyShare_FreeAll |
wolfSSL | 13:80fb167dafdf | 5740 | #define KS_GET_SIZE TLSX_KeyShare_GetSize |
wolfSSL | 13:80fb167dafdf | 5741 | #define KS_WRITE TLSX_KeyShare_Write |
wolfSSL | 13:80fb167dafdf | 5742 | #define KS_PARSE TLSX_KeyShare_Parse |
wolfSSL | 13:80fb167dafdf | 5743 | |
wolfSSL | 13:80fb167dafdf | 5744 | #else |
wolfSSL | 13:80fb167dafdf | 5745 | |
wolfSSL | 13:80fb167dafdf | 5746 | #define KS_FREE_ALL(a, b) |
wolfSSL | 13:80fb167dafdf | 5747 | #define KS_GET_SIZE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 5748 | #define KS_WRITE(a, b, c) 0 |
wolfSSL | 13:80fb167dafdf | 5749 | #define KS_PARSE(a, b, c, d) 0 |
wolfSSL | 13:80fb167dafdf | 5750 | |
wolfSSL | 13:80fb167dafdf | 5751 | #endif /* WOLFSSL_TLS13 */ |
wolfSSL | 13:80fb167dafdf | 5752 | |
wolfSSL | 13:80fb167dafdf | 5753 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 5754 | /* Pre-Shared Key */ |
wolfSSL | 13:80fb167dafdf | 5755 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 5756 | |
wolfSSL | 13:80fb167dafdf | 5757 | #if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) && !defined(NO_PSK) |
wolfSSL | 13:80fb167dafdf | 5758 | /* Free the pre-shared key dynamic data. |
wolfSSL | 13:80fb167dafdf | 5759 | * |
wolfSSL | 13:80fb167dafdf | 5760 | * list The linked list of key share entry objects. |
wolfSSL | 13:80fb167dafdf | 5761 | * heap The heap used for allocation. |
wolfSSL | 13:80fb167dafdf | 5762 | */ |
wolfSSL | 13:80fb167dafdf | 5763 | static void TLSX_PreSharedKey_FreeAll(PreSharedKey* list, void* heap) |
wolfSSL | 13:80fb167dafdf | 5764 | { |
wolfSSL | 13:80fb167dafdf | 5765 | PreSharedKey* current; |
wolfSSL | 13:80fb167dafdf | 5766 | |
wolfSSL | 13:80fb167dafdf | 5767 | while ((current = list) != NULL) { |
wolfSSL | 13:80fb167dafdf | 5768 | list = current->next; |
wolfSSL | 13:80fb167dafdf | 5769 | XFREE(current->identity, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 5770 | XFREE(current, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 5771 | } |
wolfSSL | 13:80fb167dafdf | 5772 | |
wolfSSL | 13:80fb167dafdf | 5773 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 5774 | } |
wolfSSL | 13:80fb167dafdf | 5775 | |
wolfSSL | 13:80fb167dafdf | 5776 | /* Get the size of the encoded pre shared key extension. |
wolfSSL | 13:80fb167dafdf | 5777 | * |
wolfSSL | 13:80fb167dafdf | 5778 | * list The linked list of pre-shared key extensions. |
wolfSSL | 13:80fb167dafdf | 5779 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:80fb167dafdf | 5780 | * returns the number of bytes of the encoded pre-shared key extension or |
wolfSSL | 13:80fb167dafdf | 5781 | * SANITY_MSG_E to indicate invalid message type. |
wolfSSL | 13:80fb167dafdf | 5782 | */ |
wolfSSL | 13:80fb167dafdf | 5783 | static word16 TLSX_PreSharedKey_GetSize(PreSharedKey* list, byte msgType) |
wolfSSL | 13:80fb167dafdf | 5784 | { |
wolfSSL | 13:80fb167dafdf | 5785 | if (msgType == client_hello) { |
wolfSSL | 13:80fb167dafdf | 5786 | /* Length of identities + Length of binders. */ |
wolfSSL | 13:80fb167dafdf | 5787 | word16 len = OPAQUE16_LEN + OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 5788 | while (list != NULL) { |
wolfSSL | 13:80fb167dafdf | 5789 | /* Each entry has: identity, ticket age and binder. */ |
wolfSSL | 13:80fb167dafdf | 5790 | len += OPAQUE16_LEN + list->identityLen + OPAQUE32_LEN + |
wolfSSL | 13:80fb167dafdf | 5791 | OPAQUE8_LEN + list->binderLen; |
wolfSSL | 13:80fb167dafdf | 5792 | list = list->next; |
wolfSSL | 13:80fb167dafdf | 5793 | } |
wolfSSL | 13:80fb167dafdf | 5794 | return len; |
wolfSSL | 13:80fb167dafdf | 5795 | } |
wolfSSL | 13:80fb167dafdf | 5796 | |
wolfSSL | 13:80fb167dafdf | 5797 | if (msgType == server_hello) { |
wolfSSL | 13:80fb167dafdf | 5798 | return OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 5799 | } |
wolfSSL | 13:80fb167dafdf | 5800 | |
wolfSSL | 13:80fb167dafdf | 5801 | return 0; |
wolfSSL | 13:80fb167dafdf | 5802 | } |
wolfSSL | 13:80fb167dafdf | 5803 | |
wolfSSL | 13:80fb167dafdf | 5804 | /* The number of bytes to be written for the binders. |
wolfSSL | 13:80fb167dafdf | 5805 | * |
wolfSSL | 13:80fb167dafdf | 5806 | * list The linked list of pre-shared key extensions. |
wolfSSL | 13:80fb167dafdf | 5807 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:80fb167dafdf | 5808 | * returns the number of bytes of the encoded pre-shared key extension or |
wolfSSL | 13:80fb167dafdf | 5809 | * SANITY_MSG_E to indicate invalid message type. |
wolfSSL | 13:80fb167dafdf | 5810 | */ |
wolfSSL | 13:80fb167dafdf | 5811 | word16 TLSX_PreSharedKey_GetSizeBinders(PreSharedKey* list, byte msgType) |
wolfSSL | 13:80fb167dafdf | 5812 | { |
wolfSSL | 13:80fb167dafdf | 5813 | word16 len; |
wolfSSL | 13:80fb167dafdf | 5814 | |
wolfSSL | 13:80fb167dafdf | 5815 | if (msgType != client_hello) |
wolfSSL | 13:80fb167dafdf | 5816 | return SANITY_MSG_E; |
wolfSSL | 13:80fb167dafdf | 5817 | |
wolfSSL | 13:80fb167dafdf | 5818 | /* Length of all binders. */ |
wolfSSL | 13:80fb167dafdf | 5819 | len = OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 5820 | while (list != NULL) { |
wolfSSL | 13:80fb167dafdf | 5821 | len += OPAQUE8_LEN + list->binderLen; |
wolfSSL | 13:80fb167dafdf | 5822 | list = list->next; |
wolfSSL | 13:80fb167dafdf | 5823 | } |
wolfSSL | 13:80fb167dafdf | 5824 | |
wolfSSL | 13:80fb167dafdf | 5825 | return len; |
wolfSSL | 13:80fb167dafdf | 5826 | } |
wolfSSL | 13:80fb167dafdf | 5827 | |
wolfSSL | 13:80fb167dafdf | 5828 | /* Writes the pre-shared key extension into the output buffer - binders only. |
wolfSSL | 13:80fb167dafdf | 5829 | * Assumes that the the output buffer is big enough to hold data. |
wolfSSL | 13:80fb167dafdf | 5830 | * |
wolfSSL | 13:80fb167dafdf | 5831 | * list The linked list of key share entries. |
wolfSSL | 13:80fb167dafdf | 5832 | * output The buffer to write into. |
wolfSSL | 13:80fb167dafdf | 5833 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:80fb167dafdf | 5834 | * returns the number of bytes written into the buffer. |
wolfSSL | 13:80fb167dafdf | 5835 | */ |
wolfSSL | 13:80fb167dafdf | 5836 | word16 TLSX_PreSharedKey_WriteBinders(PreSharedKey* list, byte* output, |
wolfSSL | 13:80fb167dafdf | 5837 | byte msgType) |
wolfSSL | 13:80fb167dafdf | 5838 | { |
wolfSSL | 13:80fb167dafdf | 5839 | PreSharedKey* current = list; |
wolfSSL | 13:80fb167dafdf | 5840 | word16 idx = 0; |
wolfSSL | 13:80fb167dafdf | 5841 | word16 lenIdx; |
wolfSSL | 13:80fb167dafdf | 5842 | word16 len; |
wolfSSL | 13:80fb167dafdf | 5843 | |
wolfSSL | 13:80fb167dafdf | 5844 | if (msgType != client_hello) |
wolfSSL | 13:80fb167dafdf | 5845 | return SANITY_MSG_E; |
wolfSSL | 13:80fb167dafdf | 5846 | |
wolfSSL | 13:80fb167dafdf | 5847 | /* Skip length of all binders. */ |
wolfSSL | 13:80fb167dafdf | 5848 | lenIdx = idx; |
wolfSSL | 13:80fb167dafdf | 5849 | idx += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 5850 | while (current != NULL) { |
wolfSSL | 13:80fb167dafdf | 5851 | /* Binder data length. */ |
wolfSSL | 13:80fb167dafdf | 5852 | output[idx++] = current->binderLen; |
wolfSSL | 13:80fb167dafdf | 5853 | /* Binder data. */ |
wolfSSL | 13:80fb167dafdf | 5854 | XMEMCPY(output + idx, current->binder, current->binderLen); |
wolfSSL | 13:80fb167dafdf | 5855 | idx += current->binderLen; |
wolfSSL | 13:80fb167dafdf | 5856 | |
wolfSSL | 13:80fb167dafdf | 5857 | current = current->next; |
wolfSSL | 13:80fb167dafdf | 5858 | } |
wolfSSL | 13:80fb167dafdf | 5859 | /* Length of the binders. */ |
wolfSSL | 13:80fb167dafdf | 5860 | len = idx - lenIdx - OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 5861 | c16toa(len, output + lenIdx); |
wolfSSL | 13:80fb167dafdf | 5862 | |
wolfSSL | 13:80fb167dafdf | 5863 | return idx; |
wolfSSL | 13:80fb167dafdf | 5864 | } |
wolfSSL | 13:80fb167dafdf | 5865 | |
wolfSSL | 13:80fb167dafdf | 5866 | |
wolfSSL | 13:80fb167dafdf | 5867 | /* Writes the pre-shared key extension into the output buffer. |
wolfSSL | 13:80fb167dafdf | 5868 | * Assumes that the the output buffer is big enough to hold data. |
wolfSSL | 13:80fb167dafdf | 5869 | * |
wolfSSL | 13:80fb167dafdf | 5870 | * list The linked list of key share entries. |
wolfSSL | 13:80fb167dafdf | 5871 | * output The buffer to write into. |
wolfSSL | 13:80fb167dafdf | 5872 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:80fb167dafdf | 5873 | * returns the number of bytes written into the buffer. |
wolfSSL | 13:80fb167dafdf | 5874 | */ |
wolfSSL | 13:80fb167dafdf | 5875 | static word16 TLSX_PreSharedKey_Write(PreSharedKey* list, byte* output, |
wolfSSL | 13:80fb167dafdf | 5876 | byte msgType) |
wolfSSL | 13:80fb167dafdf | 5877 | { |
wolfSSL | 13:80fb167dafdf | 5878 | if (msgType == client_hello) { |
wolfSSL | 13:80fb167dafdf | 5879 | PreSharedKey* current = list; |
wolfSSL | 13:80fb167dafdf | 5880 | word16 idx = 0; |
wolfSSL | 13:80fb167dafdf | 5881 | word16 lenIdx; |
wolfSSL | 13:80fb167dafdf | 5882 | word16 len; |
wolfSSL | 13:80fb167dafdf | 5883 | |
wolfSSL | 13:80fb167dafdf | 5884 | /* Write identites only. Binders after HMACing over this. */ |
wolfSSL | 13:80fb167dafdf | 5885 | lenIdx = idx; |
wolfSSL | 13:80fb167dafdf | 5886 | idx += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 5887 | while (current != NULL) { |
wolfSSL | 13:80fb167dafdf | 5888 | /* Identity length */ |
wolfSSL | 13:80fb167dafdf | 5889 | c16toa(current->identityLen, output + idx); |
wolfSSL | 13:80fb167dafdf | 5890 | idx += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 5891 | /* Identity data */ |
wolfSSL | 13:80fb167dafdf | 5892 | XMEMCPY(output + idx, current->identity, current->identityLen); |
wolfSSL | 13:80fb167dafdf | 5893 | idx += current->identityLen; |
wolfSSL | 13:80fb167dafdf | 5894 | |
wolfSSL | 13:80fb167dafdf | 5895 | /* Obfuscated ticket age. */ |
wolfSSL | 13:80fb167dafdf | 5896 | c32toa(current->ticketAge, output + idx); |
wolfSSL | 13:80fb167dafdf | 5897 | idx += OPAQUE32_LEN; |
wolfSSL | 13:80fb167dafdf | 5898 | |
wolfSSL | 13:80fb167dafdf | 5899 | current = current->next; |
wolfSSL | 13:80fb167dafdf | 5900 | } |
wolfSSL | 13:80fb167dafdf | 5901 | /* Length of the identites. */ |
wolfSSL | 13:80fb167dafdf | 5902 | len = idx - lenIdx - OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 5903 | c16toa(len, output + lenIdx); |
wolfSSL | 13:80fb167dafdf | 5904 | |
wolfSSL | 13:80fb167dafdf | 5905 | /* Don't include binders here. |
wolfSSL | 13:80fb167dafdf | 5906 | * The binders are based on the hash of all the ClientHello data up to |
wolfSSL | 13:80fb167dafdf | 5907 | * and include the identities written above. |
wolfSSL | 13:80fb167dafdf | 5908 | */ |
wolfSSL | 13:80fb167dafdf | 5909 | idx += TLSX_PreSharedKey_GetSizeBinders(list, msgType); |
wolfSSL | 13:80fb167dafdf | 5910 | |
wolfSSL | 13:80fb167dafdf | 5911 | return idx; |
wolfSSL | 13:80fb167dafdf | 5912 | } |
wolfSSL | 13:80fb167dafdf | 5913 | |
wolfSSL | 13:80fb167dafdf | 5914 | if (msgType == server_hello) { |
wolfSSL | 13:80fb167dafdf | 5915 | word16 i; |
wolfSSL | 13:80fb167dafdf | 5916 | |
wolfSSL | 13:80fb167dafdf | 5917 | /* Find the index of the chosen identity. */ |
wolfSSL | 13:80fb167dafdf | 5918 | for (i=0; list != NULL && !list->chosen; i++) |
wolfSSL | 13:80fb167dafdf | 5919 | list = list->next; |
wolfSSL | 13:80fb167dafdf | 5920 | if (list == NULL) |
wolfSSL | 13:80fb167dafdf | 5921 | return BUILD_MSG_ERROR; |
wolfSSL | 13:80fb167dafdf | 5922 | |
wolfSSL | 13:80fb167dafdf | 5923 | /* The index of the identity chosen by the server from the list supplied |
wolfSSL | 13:80fb167dafdf | 5924 | * by the client. |
wolfSSL | 13:80fb167dafdf | 5925 | */ |
wolfSSL | 13:80fb167dafdf | 5926 | c16toa(i, output); |
wolfSSL | 13:80fb167dafdf | 5927 | return OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 5928 | } |
wolfSSL | 13:80fb167dafdf | 5929 | |
wolfSSL | 13:80fb167dafdf | 5930 | return 0; |
wolfSSL | 13:80fb167dafdf | 5931 | } |
wolfSSL | 13:80fb167dafdf | 5932 | |
wolfSSL | 13:80fb167dafdf | 5933 | /* Parse the pre-shared key extension. |
wolfSSL | 13:80fb167dafdf | 5934 | * Different formats in different messages. |
wolfSSL | 13:80fb167dafdf | 5935 | * |
wolfSSL | 13:80fb167dafdf | 5936 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 5937 | * input The extension data. |
wolfSSL | 13:80fb167dafdf | 5938 | * length The length of the extension data. |
wolfSSL | 13:80fb167dafdf | 5939 | * msgType The type of the message this extension is being parsed from. |
wolfSSL | 13:80fb167dafdf | 5940 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:80fb167dafdf | 5941 | */ |
wolfSSL | 13:80fb167dafdf | 5942 | static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:80fb167dafdf | 5943 | byte msgType) |
wolfSSL | 13:80fb167dafdf | 5944 | { |
wolfSSL | 13:80fb167dafdf | 5945 | TLSX* extension; |
wolfSSL | 13:80fb167dafdf | 5946 | PreSharedKey* list; |
wolfSSL | 13:80fb167dafdf | 5947 | |
wolfSSL | 13:80fb167dafdf | 5948 | if (msgType == client_hello) { |
wolfSSL | 13:80fb167dafdf | 5949 | int ret; |
wolfSSL | 13:80fb167dafdf | 5950 | word16 len; |
wolfSSL | 13:80fb167dafdf | 5951 | word16 idx = 0; |
wolfSSL | 13:80fb167dafdf | 5952 | |
wolfSSL | 13:80fb167dafdf | 5953 | /* Length of identities and of binders. */ |
wolfSSL | 13:80fb167dafdf | 5954 | if (length - idx < OPAQUE16_LEN + OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 5955 | return BUFFER_E; |
wolfSSL | 13:80fb167dafdf | 5956 | |
wolfSSL | 13:80fb167dafdf | 5957 | /* Length of identities. */ |
wolfSSL | 13:80fb167dafdf | 5958 | ato16(input + idx, &len); |
wolfSSL | 13:80fb167dafdf | 5959 | idx += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 5960 | if (len < MIN_PSK_ID_LEN || length - idx < len) |
wolfSSL | 13:80fb167dafdf | 5961 | return BUFFER_E; |
wolfSSL | 13:80fb167dafdf | 5962 | |
wolfSSL | 13:80fb167dafdf | 5963 | /* Create a pre-shared key object for each identity. */ |
wolfSSL | 13:80fb167dafdf | 5964 | while (len > 0) { |
wolfSSL | 13:80fb167dafdf | 5965 | byte* identity; |
wolfSSL | 13:80fb167dafdf | 5966 | word16 identityLen; |
wolfSSL | 13:80fb167dafdf | 5967 | word32 age; |
wolfSSL | 13:80fb167dafdf | 5968 | |
wolfSSL | 13:80fb167dafdf | 5969 | if (len < OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 5970 | return BUFFER_E; |
wolfSSL | 13:80fb167dafdf | 5971 | |
wolfSSL | 13:80fb167dafdf | 5972 | /* Length of identity. */ |
wolfSSL | 13:80fb167dafdf | 5973 | ato16(input + idx, &identityLen); |
wolfSSL | 13:80fb167dafdf | 5974 | idx += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 5975 | if (len < OPAQUE16_LEN + identityLen + OPAQUE32_LEN) |
wolfSSL | 13:80fb167dafdf | 5976 | return BUFFER_E; |
wolfSSL | 13:80fb167dafdf | 5977 | /* Cache identity pointer. */ |
wolfSSL | 13:80fb167dafdf | 5978 | identity = input + idx; |
wolfSSL | 13:80fb167dafdf | 5979 | idx += identityLen; |
wolfSSL | 13:80fb167dafdf | 5980 | /* Ticket age. */ |
wolfSSL | 13:80fb167dafdf | 5981 | ato32(input + idx, &age); |
wolfSSL | 13:80fb167dafdf | 5982 | idx += OPAQUE32_LEN; |
wolfSSL | 13:80fb167dafdf | 5983 | |
wolfSSL | 13:80fb167dafdf | 5984 | ret = TLSX_PreSharedKey_Use(ssl, identity, identityLen, age, 0, 1, |
wolfSSL | 13:80fb167dafdf | 5985 | NULL); |
wolfSSL | 13:80fb167dafdf | 5986 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 5987 | return ret; |
wolfSSL | 13:80fb167dafdf | 5988 | |
wolfSSL | 13:80fb167dafdf | 5989 | /* Done with this identity. */ |
wolfSSL | 13:80fb167dafdf | 5990 | len -= OPAQUE16_LEN + identityLen + OPAQUE32_LEN; |
wolfSSL | 13:80fb167dafdf | 5991 | } |
wolfSSL | 13:80fb167dafdf | 5992 | |
wolfSSL | 13:80fb167dafdf | 5993 | /* Find the list of identities sent to server. */ |
wolfSSL | 13:80fb167dafdf | 5994 | extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY); |
wolfSSL | 13:80fb167dafdf | 5995 | if (extension == NULL) |
wolfSSL | 13:80fb167dafdf | 5996 | return PSK_KEY_ERROR; |
wolfSSL | 13:80fb167dafdf | 5997 | list = (PreSharedKey*)extension->data; |
wolfSSL | 13:80fb167dafdf | 5998 | |
wolfSSL | 13:80fb167dafdf | 5999 | /* Length of binders. */ |
wolfSSL | 13:80fb167dafdf | 6000 | ato16(input + idx, &len); |
wolfSSL | 13:80fb167dafdf | 6001 | idx += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 6002 | if (len < MIN_PSK_BINDERS_LEN || length - idx < len) |
wolfSSL | 13:80fb167dafdf | 6003 | return BUFFER_E; |
wolfSSL | 13:80fb167dafdf | 6004 | |
wolfSSL | 13:80fb167dafdf | 6005 | /* Set binder for each identity. */ |
wolfSSL | 13:80fb167dafdf | 6006 | while (list != NULL && len > 0) { |
wolfSSL | 13:80fb167dafdf | 6007 | /* Length of binder */ |
wolfSSL | 13:80fb167dafdf | 6008 | list->binderLen = input[idx++]; |
wolfSSL | 13:80fb167dafdf | 6009 | if (list->binderLen < SHA256_DIGEST_SIZE || |
wolfSSL | 13:80fb167dafdf | 6010 | list->binderLen > MAX_DIGEST_SIZE) |
wolfSSL | 13:80fb167dafdf | 6011 | return BUFFER_E; |
wolfSSL | 13:80fb167dafdf | 6012 | if (len < OPAQUE8_LEN + list->binderLen) |
wolfSSL | 13:80fb167dafdf | 6013 | return BUFFER_E; |
wolfSSL | 13:80fb167dafdf | 6014 | |
wolfSSL | 13:80fb167dafdf | 6015 | /* Copy binder into static buffer. */ |
wolfSSL | 13:80fb167dafdf | 6016 | XMEMCPY(list->binder, input + idx, list->binderLen); |
wolfSSL | 13:80fb167dafdf | 6017 | idx += list->binderLen; |
wolfSSL | 13:80fb167dafdf | 6018 | |
wolfSSL | 13:80fb167dafdf | 6019 | /* Done with binder entry. */ |
wolfSSL | 13:80fb167dafdf | 6020 | len -= OPAQUE8_LEN + list->binderLen; |
wolfSSL | 13:80fb167dafdf | 6021 | |
wolfSSL | 13:80fb167dafdf | 6022 | /* Next identity. */ |
wolfSSL | 13:80fb167dafdf | 6023 | list = list->next; |
wolfSSL | 13:80fb167dafdf | 6024 | } |
wolfSSL | 13:80fb167dafdf | 6025 | if (list != NULL || len != 0) |
wolfSSL | 13:80fb167dafdf | 6026 | return BUFFER_E; |
wolfSSL | 13:80fb167dafdf | 6027 | |
wolfSSL | 13:80fb167dafdf | 6028 | return 0; |
wolfSSL | 13:80fb167dafdf | 6029 | } |
wolfSSL | 13:80fb167dafdf | 6030 | |
wolfSSL | 13:80fb167dafdf | 6031 | if (msgType == server_hello) { |
wolfSSL | 13:80fb167dafdf | 6032 | word16 idx; |
wolfSSL | 13:80fb167dafdf | 6033 | |
wolfSSL | 13:80fb167dafdf | 6034 | /* Index of identity chosen by server. */ |
wolfSSL | 13:80fb167dafdf | 6035 | if (length != OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 6036 | return BUFFER_E; |
wolfSSL | 13:80fb167dafdf | 6037 | ato16(input, &idx); |
wolfSSL | 13:80fb167dafdf | 6038 | |
wolfSSL | 13:80fb167dafdf | 6039 | /* Find the list of identities sent to server. */ |
wolfSSL | 13:80fb167dafdf | 6040 | extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY); |
wolfSSL | 13:80fb167dafdf | 6041 | if (extension == NULL) |
wolfSSL | 13:80fb167dafdf | 6042 | return PSK_KEY_ERROR; |
wolfSSL | 13:80fb167dafdf | 6043 | list = (PreSharedKey*)extension->data; |
wolfSSL | 13:80fb167dafdf | 6044 | |
wolfSSL | 13:80fb167dafdf | 6045 | /* Mark the identity as chosen. */ |
wolfSSL | 13:80fb167dafdf | 6046 | for (; list != NULL && idx > 0; idx--) |
wolfSSL | 13:80fb167dafdf | 6047 | list = list->next; |
wolfSSL | 13:80fb167dafdf | 6048 | if (list == NULL) |
wolfSSL | 13:80fb167dafdf | 6049 | return PSK_KEY_ERROR; |
wolfSSL | 13:80fb167dafdf | 6050 | list->chosen = 1; |
wolfSSL | 13:80fb167dafdf | 6051 | |
wolfSSL | 13:80fb167dafdf | 6052 | if (list->resumption) { |
wolfSSL | 13:80fb167dafdf | 6053 | /* Check that the session's details are the same as the server's. */ |
wolfSSL | 13:80fb167dafdf | 6054 | if (ssl->options.cipherSuite0 != ssl->session.cipherSuite0 || |
wolfSSL | 13:80fb167dafdf | 6055 | ssl->options.cipherSuite != ssl->session.cipherSuite || |
wolfSSL | 13:80fb167dafdf | 6056 | ssl->session.version.major != ssl->version.major || |
wolfSSL | 13:80fb167dafdf | 6057 | ssl->session.version.minor != ssl->version.minor ) { |
wolfSSL | 13:80fb167dafdf | 6058 | return PSK_KEY_ERROR; |
wolfSSL | 13:80fb167dafdf | 6059 | } |
wolfSSL | 13:80fb167dafdf | 6060 | } |
wolfSSL | 13:80fb167dafdf | 6061 | /* TODO: [TLS13] More checks of consistency. |
wolfSSL | 13:80fb167dafdf | 6062 | * the "key_share", and "signature_algorithms" extensions are |
wolfSSL | 13:80fb167dafdf | 6063 | * consistent with the indicated ke_modes and auth_modes values |
wolfSSL | 13:80fb167dafdf | 6064 | */ |
wolfSSL | 13:80fb167dafdf | 6065 | |
wolfSSL | 13:80fb167dafdf | 6066 | return 0; |
wolfSSL | 13:80fb167dafdf | 6067 | } |
wolfSSL | 13:80fb167dafdf | 6068 | |
wolfSSL | 13:80fb167dafdf | 6069 | return SANITY_MSG_E; |
wolfSSL | 13:80fb167dafdf | 6070 | } |
wolfSSL | 13:80fb167dafdf | 6071 | |
wolfSSL | 13:80fb167dafdf | 6072 | /* Create a new pre-shared key and put it into the list. |
wolfSSL | 13:80fb167dafdf | 6073 | * |
wolfSSL | 13:80fb167dafdf | 6074 | * list The linked list of pre-shared key. |
wolfSSL | 13:80fb167dafdf | 6075 | * identity The identity. |
wolfSSL | 13:80fb167dafdf | 6076 | * len The length of the identity data. |
wolfSSL | 13:80fb167dafdf | 6077 | * heap The memory to allocate with. |
wolfSSL | 13:80fb167dafdf | 6078 | * preSharedKey The new pre-shared key object. |
wolfSSL | 13:80fb167dafdf | 6079 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:80fb167dafdf | 6080 | */ |
wolfSSL | 13:80fb167dafdf | 6081 | static int TLSX_PreSharedKey_New(PreSharedKey** list, byte* identity, |
wolfSSL | 13:80fb167dafdf | 6082 | word16 len, void *heap, |
wolfSSL | 13:80fb167dafdf | 6083 | PreSharedKey** preSharedKey) |
wolfSSL | 13:80fb167dafdf | 6084 | { |
wolfSSL | 13:80fb167dafdf | 6085 | PreSharedKey* psk; |
wolfSSL | 13:80fb167dafdf | 6086 | |
wolfSSL | 13:80fb167dafdf | 6087 | psk = (PreSharedKey*)XMALLOC(sizeof(PreSharedKey), heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 6088 | if (psk == NULL) |
wolfSSL | 13:80fb167dafdf | 6089 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 6090 | XMEMSET(psk, 0, sizeof(*psk)); |
wolfSSL | 13:80fb167dafdf | 6091 | |
wolfSSL | 13:80fb167dafdf | 6092 | /* Make a copy of the identity data. */ |
wolfSSL | 13:80fb167dafdf | 6093 | psk->identity = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 6094 | if (psk->identity == NULL) { |
wolfSSL | 13:80fb167dafdf | 6095 | XFREE(psk, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 6096 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 6097 | } |
wolfSSL | 13:80fb167dafdf | 6098 | XMEMCPY(psk->identity, identity, len); |
wolfSSL | 13:80fb167dafdf | 6099 | psk->identityLen = len; |
wolfSSL | 13:80fb167dafdf | 6100 | |
wolfSSL | 13:80fb167dafdf | 6101 | /* Add it to the end and maintain the links. */ |
wolfSSL | 13:80fb167dafdf | 6102 | while (*list != NULL) |
wolfSSL | 13:80fb167dafdf | 6103 | list = &((*list)->next); |
wolfSSL | 13:80fb167dafdf | 6104 | *list = psk; |
wolfSSL | 13:80fb167dafdf | 6105 | *preSharedKey = psk; |
wolfSSL | 13:80fb167dafdf | 6106 | |
wolfSSL | 13:80fb167dafdf | 6107 | return 0; |
wolfSSL | 13:80fb167dafdf | 6108 | } |
wolfSSL | 13:80fb167dafdf | 6109 | |
wolfSSL | 13:80fb167dafdf | 6110 | static INLINE byte GetHmacLength(int hmac) |
wolfSSL | 13:80fb167dafdf | 6111 | { |
wolfSSL | 13:80fb167dafdf | 6112 | switch (hmac) { |
wolfSSL | 13:80fb167dafdf | 6113 | #ifndef NO_SHA256 |
wolfSSL | 13:80fb167dafdf | 6114 | case sha256_mac: |
wolfSSL | 13:80fb167dafdf | 6115 | return SHA256_DIGEST_SIZE; |
wolfSSL | 13:80fb167dafdf | 6116 | #endif |
wolfSSL | 13:80fb167dafdf | 6117 | #ifndef NO_SHA384 |
wolfSSL | 13:80fb167dafdf | 6118 | case sha384_mac: |
wolfSSL | 13:80fb167dafdf | 6119 | return SHA384_DIGEST_SIZE; |
wolfSSL | 13:80fb167dafdf | 6120 | #endif |
wolfSSL | 13:80fb167dafdf | 6121 | #ifndef NO_SHA512 |
wolfSSL | 13:80fb167dafdf | 6122 | case sha512_mac: |
wolfSSL | 13:80fb167dafdf | 6123 | return SHA512_DIGEST_SIZE; |
wolfSSL | 13:80fb167dafdf | 6124 | #endif |
wolfSSL | 13:80fb167dafdf | 6125 | } |
wolfSSL | 13:80fb167dafdf | 6126 | return 0; |
wolfSSL | 13:80fb167dafdf | 6127 | } |
wolfSSL | 13:80fb167dafdf | 6128 | |
wolfSSL | 13:80fb167dafdf | 6129 | /* Use the data to create a new pre-shared key object in the extensions. |
wolfSSL | 13:80fb167dafdf | 6130 | * |
wolfSSL | 13:80fb167dafdf | 6131 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 6132 | * identity The identity. |
wolfSSL | 13:80fb167dafdf | 6133 | * len The length of the identity data. |
wolfSSL | 13:80fb167dafdf | 6134 | * age The age of the identity. |
wolfSSL | 13:80fb167dafdf | 6135 | * hmac The HMAC algorithm. |
wolfSSL | 13:80fb167dafdf | 6136 | * resumption The PSK is for resumption of a session. |
wolfSSL | 13:80fb167dafdf | 6137 | * preSharedKey The new pre-shared key object. |
wolfSSL | 13:80fb167dafdf | 6138 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:80fb167dafdf | 6139 | */ |
wolfSSL | 13:80fb167dafdf | 6140 | int TLSX_PreSharedKey_Use(WOLFSSL* ssl, byte* identity, word16 len, word32 age, |
wolfSSL | 13:80fb167dafdf | 6141 | byte hmac, byte resumption, |
wolfSSL | 13:80fb167dafdf | 6142 | PreSharedKey **preSharedKey) |
wolfSSL | 13:80fb167dafdf | 6143 | { |
wolfSSL | 13:80fb167dafdf | 6144 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 6145 | TLSX* extension; |
wolfSSL | 13:80fb167dafdf | 6146 | PreSharedKey* psk = NULL; |
wolfSSL | 13:80fb167dafdf | 6147 | |
wolfSSL | 13:80fb167dafdf | 6148 | /* Find the pre-shared key extension if it exists. */ |
wolfSSL | 13:80fb167dafdf | 6149 | extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY); |
wolfSSL | 13:80fb167dafdf | 6150 | if (extension == NULL) { |
wolfSSL | 13:80fb167dafdf | 6151 | /* Push new pre-shared key extension. */ |
wolfSSL | 13:80fb167dafdf | 6152 | ret = TLSX_Push(&ssl->extensions, TLSX_PRE_SHARED_KEY, NULL, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 6153 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 6154 | return ret; |
wolfSSL | 13:80fb167dafdf | 6155 | |
wolfSSL | 13:80fb167dafdf | 6156 | extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY); |
wolfSSL | 13:80fb167dafdf | 6157 | if (extension == NULL) |
wolfSSL | 13:80fb167dafdf | 6158 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 6159 | } |
wolfSSL | 13:80fb167dafdf | 6160 | |
wolfSSL | 13:80fb167dafdf | 6161 | /* Try to find the pre-shared key with this identity. */ |
wolfSSL | 13:80fb167dafdf | 6162 | psk = (PreSharedKey*)extension->data; |
wolfSSL | 13:80fb167dafdf | 6163 | while (psk != NULL) { |
wolfSSL | 13:80fb167dafdf | 6164 | if ((psk->identityLen == len) && |
wolfSSL | 13:80fb167dafdf | 6165 | (XMEMCMP(psk->identity, identity, len) == 0)) { |
wolfSSL | 13:80fb167dafdf | 6166 | break; |
wolfSSL | 13:80fb167dafdf | 6167 | } |
wolfSSL | 13:80fb167dafdf | 6168 | psk = psk->next; |
wolfSSL | 13:80fb167dafdf | 6169 | } |
wolfSSL | 13:80fb167dafdf | 6170 | |
wolfSSL | 13:80fb167dafdf | 6171 | /* Create a new pre-shared key object if not found. */ |
wolfSSL | 13:80fb167dafdf | 6172 | if (psk == NULL) { |
wolfSSL | 13:80fb167dafdf | 6173 | ret = TLSX_PreSharedKey_New((PreSharedKey**)&extension->data, identity, |
wolfSSL | 13:80fb167dafdf | 6174 | len, ssl->heap, &psk); |
wolfSSL | 13:80fb167dafdf | 6175 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 6176 | return ret; |
wolfSSL | 13:80fb167dafdf | 6177 | } |
wolfSSL | 13:80fb167dafdf | 6178 | |
wolfSSL | 13:80fb167dafdf | 6179 | /* Update/set age and HMAC algorithm. */ |
wolfSSL | 13:80fb167dafdf | 6180 | psk->ticketAge = age; |
wolfSSL | 13:80fb167dafdf | 6181 | psk->hmac = hmac; |
wolfSSL | 13:80fb167dafdf | 6182 | psk->resumption = resumption; |
wolfSSL | 13:80fb167dafdf | 6183 | psk->binderLen = GetHmacLength(psk->hmac); |
wolfSSL | 13:80fb167dafdf | 6184 | |
wolfSSL | 13:80fb167dafdf | 6185 | if (preSharedKey != NULL) |
wolfSSL | 13:80fb167dafdf | 6186 | *preSharedKey = psk; |
wolfSSL | 13:80fb167dafdf | 6187 | |
wolfSSL | 13:80fb167dafdf | 6188 | return 0; |
wolfSSL | 13:80fb167dafdf | 6189 | } |
wolfSSL | 13:80fb167dafdf | 6190 | |
wolfSSL | 13:80fb167dafdf | 6191 | #define PSK_FREE_ALL TLSX_PreSharedKey_FreeAll |
wolfSSL | 13:80fb167dafdf | 6192 | #define PSK_GET_SIZE TLSX_PreSharedKey_GetSize |
wolfSSL | 13:80fb167dafdf | 6193 | #define PSK_WRITE TLSX_PreSharedKey_Write |
wolfSSL | 13:80fb167dafdf | 6194 | #define PSK_PARSE TLSX_PreSharedKey_Parse |
wolfSSL | 13:80fb167dafdf | 6195 | |
wolfSSL | 13:80fb167dafdf | 6196 | #else |
wolfSSL | 13:80fb167dafdf | 6197 | |
wolfSSL | 13:80fb167dafdf | 6198 | #define PSK_FREE_ALL(a, b) |
wolfSSL | 13:80fb167dafdf | 6199 | #define PSK_GET_SIZE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 6200 | #define PSK_WRITE(a, b, c) 0 |
wolfSSL | 13:80fb167dafdf | 6201 | #define PSK_PARSE(a, b, c, d) 0 |
wolfSSL | 13:80fb167dafdf | 6202 | |
wolfSSL | 13:80fb167dafdf | 6203 | #endif |
wolfSSL | 13:80fb167dafdf | 6204 | |
wolfSSL | 13:80fb167dafdf | 6205 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 6206 | /* PSK Key Exchange Modes */ |
wolfSSL | 13:80fb167dafdf | 6207 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 6208 | |
wolfSSL | 13:80fb167dafdf | 6209 | #if defined(WOLFSSL_TLS13) && !defined(NO_PSK) |
wolfSSL | 13:80fb167dafdf | 6210 | /* Get the size of the encoded PSK KE modes extension. |
wolfSSL | 13:80fb167dafdf | 6211 | * Only in ClientHello. |
wolfSSL | 13:80fb167dafdf | 6212 | * |
wolfSSL | 13:80fb167dafdf | 6213 | * modes The PSK KE mode bit string. |
wolfSSL | 13:80fb167dafdf | 6214 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:80fb167dafdf | 6215 | * returns the number of bytes of the encoded key share extension. |
wolfSSL | 13:80fb167dafdf | 6216 | */ |
wolfSSL | 13:80fb167dafdf | 6217 | static word16 TLSX_PskKeModes_GetSize(byte modes, byte msgType) |
wolfSSL | 13:80fb167dafdf | 6218 | { |
wolfSSL | 13:80fb167dafdf | 6219 | if (msgType == client_hello) { |
wolfSSL | 13:80fb167dafdf | 6220 | /* Format: Len | Modes* */ |
wolfSSL | 13:80fb167dafdf | 6221 | word16 len = OPAQUE8_LEN; |
wolfSSL | 13:80fb167dafdf | 6222 | /* Check whether each possible mode is to be written. */ |
wolfSSL | 13:80fb167dafdf | 6223 | if (modes & (1 << PSK_KE)) |
wolfSSL | 13:80fb167dafdf | 6224 | len += OPAQUE8_LEN; |
wolfSSL | 13:80fb167dafdf | 6225 | if (modes & (1 << PSK_DHE_KE)) |
wolfSSL | 13:80fb167dafdf | 6226 | len += OPAQUE8_LEN; |
wolfSSL | 13:80fb167dafdf | 6227 | return len; |
wolfSSL | 13:80fb167dafdf | 6228 | } |
wolfSSL | 13:80fb167dafdf | 6229 | |
wolfSSL | 13:80fb167dafdf | 6230 | return SANITY_MSG_E; |
wolfSSL | 13:80fb167dafdf | 6231 | } |
wolfSSL | 13:80fb167dafdf | 6232 | |
wolfSSL | 13:80fb167dafdf | 6233 | /* Writes the PSK KE modes extension into the output buffer. |
wolfSSL | 13:80fb167dafdf | 6234 | * Assumes that the the output buffer is big enough to hold data. |
wolfSSL | 13:80fb167dafdf | 6235 | * Only in ClientHello. |
wolfSSL | 13:80fb167dafdf | 6236 | * |
wolfSSL | 13:80fb167dafdf | 6237 | * modes The PSK KE mode bit string. |
wolfSSL | 13:80fb167dafdf | 6238 | * output The buffer to write into. |
wolfSSL | 13:80fb167dafdf | 6239 | * msgType The type of the message this extension is being written into. |
wolfSSL | 13:80fb167dafdf | 6240 | * returns the number of bytes written into the buffer. |
wolfSSL | 13:80fb167dafdf | 6241 | */ |
wolfSSL | 13:80fb167dafdf | 6242 | static word16 TLSX_PskKeModes_Write(byte modes, byte* output, byte msgType) |
wolfSSL | 13:80fb167dafdf | 6243 | { |
wolfSSL | 13:80fb167dafdf | 6244 | if (msgType == client_hello) { |
wolfSSL | 13:80fb167dafdf | 6245 | /* Format: Len | Modes* */ |
wolfSSL | 13:80fb167dafdf | 6246 | int idx = OPAQUE8_LEN; |
wolfSSL | 13:80fb167dafdf | 6247 | |
wolfSSL | 13:80fb167dafdf | 6248 | /* Write out each possible mode. */ |
wolfSSL | 13:80fb167dafdf | 6249 | if (modes & (1 << PSK_KE)) |
wolfSSL | 13:80fb167dafdf | 6250 | output[idx++] = PSK_KE; |
wolfSSL | 13:80fb167dafdf | 6251 | if (modes & (1 << PSK_DHE_KE)) |
wolfSSL | 13:80fb167dafdf | 6252 | output[idx++] = PSK_DHE_KE; |
wolfSSL | 13:80fb167dafdf | 6253 | /* Write out length of mode list. */ |
wolfSSL | 13:80fb167dafdf | 6254 | output[0] = idx - OPAQUE8_LEN; |
wolfSSL | 13:80fb167dafdf | 6255 | |
wolfSSL | 13:80fb167dafdf | 6256 | return idx; |
wolfSSL | 13:80fb167dafdf | 6257 | } |
wolfSSL | 13:80fb167dafdf | 6258 | |
wolfSSL | 13:80fb167dafdf | 6259 | return SANITY_MSG_E; |
wolfSSL | 13:80fb167dafdf | 6260 | } |
wolfSSL | 13:80fb167dafdf | 6261 | |
wolfSSL | 13:80fb167dafdf | 6262 | /* Parse the PSK KE modes extension. |
wolfSSL | 13:80fb167dafdf | 6263 | * Only in ClientHello. |
wolfSSL | 13:80fb167dafdf | 6264 | * |
wolfSSL | 13:80fb167dafdf | 6265 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 6266 | * input The extension data. |
wolfSSL | 13:80fb167dafdf | 6267 | * length The length of the extension data. |
wolfSSL | 13:80fb167dafdf | 6268 | * msgType The type of the message this extension is being parsed from. |
wolfSSL | 13:80fb167dafdf | 6269 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:80fb167dafdf | 6270 | */ |
wolfSSL | 13:80fb167dafdf | 6271 | static int TLSX_PskKeModes_Parse(WOLFSSL* ssl, byte* input, word16 length, |
wolfSSL | 13:80fb167dafdf | 6272 | byte msgType) |
wolfSSL | 13:80fb167dafdf | 6273 | { |
wolfSSL | 13:80fb167dafdf | 6274 | int ret; |
wolfSSL | 13:80fb167dafdf | 6275 | |
wolfSSL | 13:80fb167dafdf | 6276 | if (msgType == client_hello) { |
wolfSSL | 13:80fb167dafdf | 6277 | /* Format: Len | Modes* */ |
wolfSSL | 13:80fb167dafdf | 6278 | int idx = 0; |
wolfSSL | 13:80fb167dafdf | 6279 | int len; |
wolfSSL | 13:80fb167dafdf | 6280 | byte modes = 0; |
wolfSSL | 13:80fb167dafdf | 6281 | |
wolfSSL | 13:80fb167dafdf | 6282 | /* Ensure length byte exists. */ |
wolfSSL | 13:80fb167dafdf | 6283 | if (length < OPAQUE8_LEN) |
wolfSSL | 13:80fb167dafdf | 6284 | return BUFFER_E; |
wolfSSL | 13:80fb167dafdf | 6285 | |
wolfSSL | 13:80fb167dafdf | 6286 | /* Get length of mode list and ensure that is the only data. */ |
wolfSSL | 13:80fb167dafdf | 6287 | len = input[0]; |
wolfSSL | 13:80fb167dafdf | 6288 | if (length - OPAQUE8_LEN != len) |
wolfSSL | 13:80fb167dafdf | 6289 | return BUFFER_E; |
wolfSSL | 13:80fb167dafdf | 6290 | |
wolfSSL | 13:80fb167dafdf | 6291 | idx = OPAQUE8_LEN; |
wolfSSL | 13:80fb167dafdf | 6292 | /* Set a bit for each recognized modes. */ |
wolfSSL | 13:80fb167dafdf | 6293 | while (len > 0) { |
wolfSSL | 13:80fb167dafdf | 6294 | /* Ignore unrecognized modes. */ |
wolfSSL | 13:80fb167dafdf | 6295 | if (input[idx] <= PSK_DHE_KE) |
wolfSSL | 13:80fb167dafdf | 6296 | modes |= 1 << input[idx]; |
wolfSSL | 13:80fb167dafdf | 6297 | idx++; |
wolfSSL | 13:80fb167dafdf | 6298 | len--; |
wolfSSL | 13:80fb167dafdf | 6299 | } |
wolfSSL | 13:80fb167dafdf | 6300 | |
wolfSSL | 13:80fb167dafdf | 6301 | ret = TLSX_PskKeModes_Use(ssl, modes); |
wolfSSL | 13:80fb167dafdf | 6302 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 6303 | return ret; |
wolfSSL | 13:80fb167dafdf | 6304 | |
wolfSSL | 13:80fb167dafdf | 6305 | return 0; |
wolfSSL | 13:80fb167dafdf | 6306 | } |
wolfSSL | 13:80fb167dafdf | 6307 | |
wolfSSL | 13:80fb167dafdf | 6308 | return SANITY_MSG_E; |
wolfSSL | 13:80fb167dafdf | 6309 | } |
wolfSSL | 13:80fb167dafdf | 6310 | |
wolfSSL | 13:80fb167dafdf | 6311 | /* Use the data to create a new PSK Key Exchange Modes object in the extensions. |
wolfSSL | 13:80fb167dafdf | 6312 | * |
wolfSSL | 13:80fb167dafdf | 6313 | * ssl The SSL/TLS object. |
wolfSSL | 13:80fb167dafdf | 6314 | * modes The PSK key exchange modes. |
wolfSSL | 13:80fb167dafdf | 6315 | * returns 0 on success and other values indicate failure. |
wolfSSL | 13:80fb167dafdf | 6316 | */ |
wolfSSL | 13:80fb167dafdf | 6317 | int TLSX_PskKeModes_Use(WOLFSSL* ssl, byte modes) |
wolfSSL | 13:80fb167dafdf | 6318 | { |
wolfSSL | 13:80fb167dafdf | 6319 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 6320 | TLSX* extension; |
wolfSSL | 13:80fb167dafdf | 6321 | |
wolfSSL | 13:80fb167dafdf | 6322 | /* Find the PSK key exchange modes extension if it exists. */ |
wolfSSL | 13:80fb167dafdf | 6323 | extension = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES); |
wolfSSL | 13:80fb167dafdf | 6324 | if (extension == NULL) { |
wolfSSL | 13:80fb167dafdf | 6325 | /* Push new PSK key exchange modes extension. */ |
wolfSSL | 13:80fb167dafdf | 6326 | ret = TLSX_Push(&ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES, NULL, |
wolfSSL | 13:80fb167dafdf | 6327 | ssl->heap); |
wolfSSL | 13:80fb167dafdf | 6328 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 6329 | return ret; |
wolfSSL | 13:80fb167dafdf | 6330 | |
wolfSSL | 13:80fb167dafdf | 6331 | extension = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES); |
wolfSSL | 13:80fb167dafdf | 6332 | if (extension == NULL) |
wolfSSL | 13:80fb167dafdf | 6333 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 6334 | } |
wolfSSL | 13:80fb167dafdf | 6335 | |
wolfSSL | 13:80fb167dafdf | 6336 | extension->val = modes; |
wolfSSL | 13:80fb167dafdf | 6337 | |
wolfSSL | 13:80fb167dafdf | 6338 | return 0; |
wolfSSL | 13:80fb167dafdf | 6339 | } |
wolfSSL | 13:80fb167dafdf | 6340 | |
wolfSSL | 13:80fb167dafdf | 6341 | #define PKM_GET_SIZE TLSX_PskKeModes_GetSize |
wolfSSL | 13:80fb167dafdf | 6342 | #define PKM_WRITE TLSX_PskKeModes_Write |
wolfSSL | 13:80fb167dafdf | 6343 | #define PKM_PARSE TLSX_PskKeModes_Parse |
wolfSSL | 13:80fb167dafdf | 6344 | |
wolfSSL | 13:80fb167dafdf | 6345 | #else |
wolfSSL | 13:80fb167dafdf | 6346 | |
wolfSSL | 13:80fb167dafdf | 6347 | #define PKM_GET_SIZE(a, b) 0 |
wolfSSL | 13:80fb167dafdf | 6348 | #define PKM_WRITE(a, b, c) 0 |
wolfSSL | 13:80fb167dafdf | 6349 | #define PKM_PARSE(a, b, c, d) 0 |
wolfSSL | 13:80fb167dafdf | 6350 | |
wolfSSL | 13:80fb167dafdf | 6351 | #endif |
wolfSSL | 13:80fb167dafdf | 6352 | |
wolfSSL | 13:80fb167dafdf | 6353 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 6354 | /* TLS Extensions Framework */ |
wolfSSL | 13:80fb167dafdf | 6355 | /******************************************************************************/ |
wolfSSL | 13:80fb167dafdf | 6356 | |
wolfSSL | 13:80fb167dafdf | 6357 | /** Finds an extension in the provided list. */ |
wolfSSL | 13:80fb167dafdf | 6358 | TLSX* TLSX_Find(TLSX* list, TLSX_Type type) |
wolfSSL | 13:80fb167dafdf | 6359 | { |
wolfSSL | 13:80fb167dafdf | 6360 | TLSX* extension = list; |
wolfSSL | 13:80fb167dafdf | 6361 | |
wolfSSL | 13:80fb167dafdf | 6362 | while (extension && extension->type != type) |
wolfSSL | 13:80fb167dafdf | 6363 | extension = extension->next; |
wolfSSL | 13:80fb167dafdf | 6364 | |
wolfSSL | 13:80fb167dafdf | 6365 | return extension; |
wolfSSL | 13:80fb167dafdf | 6366 | } |
wolfSSL | 13:80fb167dafdf | 6367 | |
wolfSSL | 13:80fb167dafdf | 6368 | /** Releases all extensions in the provided list. */ |
wolfSSL | 13:80fb167dafdf | 6369 | void TLSX_FreeAll(TLSX* list, void* heap) |
wolfSSL | 13:80fb167dafdf | 6370 | { |
wolfSSL | 13:80fb167dafdf | 6371 | TLSX* extension; |
wolfSSL | 13:80fb167dafdf | 6372 | |
wolfSSL | 13:80fb167dafdf | 6373 | while ((extension = list)) { |
wolfSSL | 13:80fb167dafdf | 6374 | list = extension->next; |
wolfSSL | 13:80fb167dafdf | 6375 | |
wolfSSL | 13:80fb167dafdf | 6376 | switch (extension->type) { |
wolfSSL | 13:80fb167dafdf | 6377 | |
wolfSSL | 13:80fb167dafdf | 6378 | case TLSX_SERVER_NAME: |
wolfSSL | 13:80fb167dafdf | 6379 | SNI_FREE_ALL((SNI*)extension->data, heap); |
wolfSSL | 13:80fb167dafdf | 6380 | break; |
wolfSSL | 13:80fb167dafdf | 6381 | |
wolfSSL | 13:80fb167dafdf | 6382 | case TLSX_MAX_FRAGMENT_LENGTH: |
wolfSSL | 13:80fb167dafdf | 6383 | MFL_FREE_ALL(extension->data, heap); |
wolfSSL | 13:80fb167dafdf | 6384 | break; |
wolfSSL | 13:80fb167dafdf | 6385 | |
wolfSSL | 13:80fb167dafdf | 6386 | case TLSX_TRUNCATED_HMAC: |
wolfSSL | 13:80fb167dafdf | 6387 | /* Nothing to do. */ |
wolfSSL | 13:80fb167dafdf | 6388 | break; |
wolfSSL | 13:80fb167dafdf | 6389 | |
wolfSSL | 13:80fb167dafdf | 6390 | case TLSX_SUPPORTED_GROUPS: |
wolfSSL | 13:80fb167dafdf | 6391 | EC_FREE_ALL((EllipticCurve*)extension->data, heap); |
wolfSSL | 13:80fb167dafdf | 6392 | break; |
wolfSSL | 13:80fb167dafdf | 6393 | |
wolfSSL | 13:80fb167dafdf | 6394 | case TLSX_STATUS_REQUEST: |
wolfSSL | 13:80fb167dafdf | 6395 | CSR_FREE_ALL((CertificateStatusRequest*)extension->data, heap); |
wolfSSL | 13:80fb167dafdf | 6396 | break; |
wolfSSL | 13:80fb167dafdf | 6397 | |
wolfSSL | 13:80fb167dafdf | 6398 | case TLSX_STATUS_REQUEST_V2: |
wolfSSL | 13:80fb167dafdf | 6399 | CSR2_FREE_ALL((CertificateStatusRequestItemV2*)extension->data, |
wolfSSL | 13:80fb167dafdf | 6400 | heap); |
wolfSSL | 13:80fb167dafdf | 6401 | break; |
wolfSSL | 13:80fb167dafdf | 6402 | |
wolfSSL | 13:80fb167dafdf | 6403 | case TLSX_RENEGOTIATION_INFO: |
wolfSSL | 13:80fb167dafdf | 6404 | SCR_FREE_ALL(extension->data, heap); |
wolfSSL | 13:80fb167dafdf | 6405 | break; |
wolfSSL | 13:80fb167dafdf | 6406 | |
wolfSSL | 13:80fb167dafdf | 6407 | case TLSX_SESSION_TICKET: |
wolfSSL | 13:80fb167dafdf | 6408 | WOLF_STK_FREE(extension->data, heap); |
wolfSSL | 13:80fb167dafdf | 6409 | break; |
wolfSSL | 13:80fb167dafdf | 6410 | |
wolfSSL | 13:80fb167dafdf | 6411 | case TLSX_QUANTUM_SAFE_HYBRID: |
wolfSSL | 13:80fb167dafdf | 6412 | QSH_FREE_ALL((QSHScheme*)extension->data, heap); |
wolfSSL | 13:80fb167dafdf | 6413 | break; |
wolfSSL | 13:80fb167dafdf | 6414 | |
wolfSSL | 13:80fb167dafdf | 6415 | case TLSX_APPLICATION_LAYER_PROTOCOL: |
wolfSSL | 13:80fb167dafdf | 6416 | ALPN_FREE_ALL((ALPN*)extension->data, heap); |
wolfSSL | 13:80fb167dafdf | 6417 | break; |
wolfSSL | 13:80fb167dafdf | 6418 | |
wolfSSL | 13:80fb167dafdf | 6419 | case TLSX_SIGNATURE_ALGORITHMS: |
wolfSSL | 13:80fb167dafdf | 6420 | break; |
wolfSSL | 13:80fb167dafdf | 6421 | |
wolfSSL | 13:80fb167dafdf | 6422 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 6423 | case TLSX_SUPPORTED_VERSIONS: |
wolfSSL | 13:80fb167dafdf | 6424 | break; |
wolfSSL | 13:80fb167dafdf | 6425 | |
wolfSSL | 13:80fb167dafdf | 6426 | case TLSX_KEY_SHARE: |
wolfSSL | 13:80fb167dafdf | 6427 | KS_FREE_ALL((KeyShareEntry*)extension->data, heap); |
wolfSSL | 13:80fb167dafdf | 6428 | break; |
wolfSSL | 13:80fb167dafdf | 6429 | |
wolfSSL | 13:80fb167dafdf | 6430 | #ifndef NO_PSK |
wolfSSL | 13:80fb167dafdf | 6431 | case TLSX_PRE_SHARED_KEY: |
wolfSSL | 13:80fb167dafdf | 6432 | PSK_FREE_ALL((PreSharedKey*)extension->data, heap); |
wolfSSL | 13:80fb167dafdf | 6433 | break; |
wolfSSL | 13:80fb167dafdf | 6434 | |
wolfSSL | 13:80fb167dafdf | 6435 | case TLSX_PSK_KEY_EXCHANGE_MODES: |
wolfSSL | 13:80fb167dafdf | 6436 | break; |
wolfSSL | 13:80fb167dafdf | 6437 | #endif |
wolfSSL | 13:80fb167dafdf | 6438 | #endif |
wolfSSL | 13:80fb167dafdf | 6439 | } |
wolfSSL | 13:80fb167dafdf | 6440 | |
wolfSSL | 13:80fb167dafdf | 6441 | XFREE(extension, heap, DYNAMIC_TYPE_TLSX); |
wolfSSL | 13:80fb167dafdf | 6442 | } |
wolfSSL | 13:80fb167dafdf | 6443 | |
wolfSSL | 13:80fb167dafdf | 6444 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 6445 | } |
wolfSSL | 13:80fb167dafdf | 6446 | |
wolfSSL | 13:80fb167dafdf | 6447 | /** Checks if the tls extensions are supported based on the protocol version. */ |
wolfSSL | 13:80fb167dafdf | 6448 | int TLSX_SupportExtensions(WOLFSSL* ssl) { |
wolfSSL | 13:80fb167dafdf | 6449 | return ssl && (IsTLS(ssl) || ssl->version.major == DTLS_MAJOR); |
wolfSSL | 13:80fb167dafdf | 6450 | } |
wolfSSL | 13:80fb167dafdf | 6451 | |
wolfSSL | 13:80fb167dafdf | 6452 | /** Tells the buffered size of the extensions in a list. */ |
wolfSSL | 13:80fb167dafdf | 6453 | static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType) |
wolfSSL | 13:80fb167dafdf | 6454 | { |
wolfSSL | 13:80fb167dafdf | 6455 | TLSX* extension; |
wolfSSL | 13:80fb167dafdf | 6456 | word16 length = 0; |
wolfSSL | 13:80fb167dafdf | 6457 | byte isRequest = (msgType == client_hello); |
wolfSSL | 13:80fb167dafdf | 6458 | |
wolfSSL | 13:80fb167dafdf | 6459 | while ((extension = list)) { |
wolfSSL | 13:80fb167dafdf | 6460 | list = extension->next; |
wolfSSL | 13:80fb167dafdf | 6461 | |
wolfSSL | 13:80fb167dafdf | 6462 | /* only extensions marked as response are sent back to the client. */ |
wolfSSL | 13:80fb167dafdf | 6463 | if (!isRequest && !extension->resp) |
wolfSSL | 13:80fb167dafdf | 6464 | continue; /* skip! */ |
wolfSSL | 13:80fb167dafdf | 6465 | |
wolfSSL | 13:80fb167dafdf | 6466 | /* ssl level extensions are expected to override ctx level ones. */ |
wolfSSL | 13:80fb167dafdf | 6467 | if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type))) |
wolfSSL | 13:80fb167dafdf | 6468 | continue; /* skip! */ |
wolfSSL | 13:80fb167dafdf | 6469 | |
wolfSSL | 13:80fb167dafdf | 6470 | /* extension type + extension data length. */ |
wolfSSL | 13:80fb167dafdf | 6471 | length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 6472 | |
wolfSSL | 13:80fb167dafdf | 6473 | |
wolfSSL | 13:80fb167dafdf | 6474 | switch (extension->type) { |
wolfSSL | 13:80fb167dafdf | 6475 | |
wolfSSL | 13:80fb167dafdf | 6476 | case TLSX_SERVER_NAME: |
wolfSSL | 13:80fb167dafdf | 6477 | /* SNI only sends the name on the request. */ |
wolfSSL | 13:80fb167dafdf | 6478 | if (isRequest) |
wolfSSL | 13:80fb167dafdf | 6479 | length += SNI_GET_SIZE((SNI*)extension->data); |
wolfSSL | 13:80fb167dafdf | 6480 | break; |
wolfSSL | 13:80fb167dafdf | 6481 | |
wolfSSL | 13:80fb167dafdf | 6482 | case TLSX_MAX_FRAGMENT_LENGTH: |
wolfSSL | 13:80fb167dafdf | 6483 | length += MFL_GET_SIZE(extension->data); |
wolfSSL | 13:80fb167dafdf | 6484 | break; |
wolfSSL | 13:80fb167dafdf | 6485 | |
wolfSSL | 13:80fb167dafdf | 6486 | case TLSX_TRUNCATED_HMAC: |
wolfSSL | 13:80fb167dafdf | 6487 | /* always empty. */ |
wolfSSL | 13:80fb167dafdf | 6488 | break; |
wolfSSL | 13:80fb167dafdf | 6489 | |
wolfSSL | 13:80fb167dafdf | 6490 | case TLSX_SUPPORTED_GROUPS: |
wolfSSL | 13:80fb167dafdf | 6491 | length += EC_GET_SIZE((EllipticCurve*)extension->data); |
wolfSSL | 13:80fb167dafdf | 6492 | break; |
wolfSSL | 13:80fb167dafdf | 6493 | |
wolfSSL | 13:80fb167dafdf | 6494 | case TLSX_STATUS_REQUEST: |
wolfSSL | 13:80fb167dafdf | 6495 | length += CSR_GET_SIZE( |
wolfSSL | 13:80fb167dafdf | 6496 | (CertificateStatusRequest*)extension->data, isRequest); |
wolfSSL | 13:80fb167dafdf | 6497 | break; |
wolfSSL | 13:80fb167dafdf | 6498 | |
wolfSSL | 13:80fb167dafdf | 6499 | case TLSX_STATUS_REQUEST_V2: |
wolfSSL | 13:80fb167dafdf | 6500 | length += CSR2_GET_SIZE( |
wolfSSL | 13:80fb167dafdf | 6501 | (CertificateStatusRequestItemV2*)extension->data, |
wolfSSL | 13:80fb167dafdf | 6502 | isRequest); |
wolfSSL | 13:80fb167dafdf | 6503 | break; |
wolfSSL | 13:80fb167dafdf | 6504 | |
wolfSSL | 13:80fb167dafdf | 6505 | case TLSX_RENEGOTIATION_INFO: |
wolfSSL | 13:80fb167dafdf | 6506 | length += SCR_GET_SIZE((SecureRenegotiation*)extension->data, |
wolfSSL | 13:80fb167dafdf | 6507 | isRequest); |
wolfSSL | 13:80fb167dafdf | 6508 | break; |
wolfSSL | 13:80fb167dafdf | 6509 | |
wolfSSL | 13:80fb167dafdf | 6510 | case TLSX_SESSION_TICKET: |
wolfSSL | 13:80fb167dafdf | 6511 | length += WOLF_STK_GET_SIZE((SessionTicket*)extension->data, |
wolfSSL | 13:80fb167dafdf | 6512 | isRequest); |
wolfSSL | 13:80fb167dafdf | 6513 | break; |
wolfSSL | 13:80fb167dafdf | 6514 | |
wolfSSL | 13:80fb167dafdf | 6515 | case TLSX_QUANTUM_SAFE_HYBRID: |
wolfSSL | 13:80fb167dafdf | 6516 | length += QSH_GET_SIZE((QSHScheme*)extension->data, isRequest); |
wolfSSL | 13:80fb167dafdf | 6517 | break; |
wolfSSL | 13:80fb167dafdf | 6518 | |
wolfSSL | 13:80fb167dafdf | 6519 | case TLSX_APPLICATION_LAYER_PROTOCOL: |
wolfSSL | 13:80fb167dafdf | 6520 | length += ALPN_GET_SIZE((ALPN*)extension->data); |
wolfSSL | 13:80fb167dafdf | 6521 | break; |
wolfSSL | 13:80fb167dafdf | 6522 | |
wolfSSL | 13:80fb167dafdf | 6523 | case TLSX_SIGNATURE_ALGORITHMS: |
wolfSSL | 13:80fb167dafdf | 6524 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 6525 | length += SA_GET_SIZE(extension->data); |
wolfSSL | 13:80fb167dafdf | 6526 | #endif |
wolfSSL | 13:80fb167dafdf | 6527 | break; |
wolfSSL | 13:80fb167dafdf | 6528 | |
wolfSSL | 13:80fb167dafdf | 6529 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 6530 | case TLSX_SUPPORTED_VERSIONS: |
wolfSSL | 13:80fb167dafdf | 6531 | length += SV_GET_SIZE(extension->data); |
wolfSSL | 13:80fb167dafdf | 6532 | break; |
wolfSSL | 13:80fb167dafdf | 6533 | |
wolfSSL | 13:80fb167dafdf | 6534 | case TLSX_KEY_SHARE: |
wolfSSL | 13:80fb167dafdf | 6535 | length += KS_GET_SIZE(extension->data, msgType); |
wolfSSL | 13:80fb167dafdf | 6536 | break; |
wolfSSL | 13:80fb167dafdf | 6537 | |
wolfSSL | 13:80fb167dafdf | 6538 | #ifndef NO_PSK |
wolfSSL | 13:80fb167dafdf | 6539 | case TLSX_PRE_SHARED_KEY: |
wolfSSL | 13:80fb167dafdf | 6540 | length += PSK_GET_SIZE(extension->data, msgType); |
wolfSSL | 13:80fb167dafdf | 6541 | break; |
wolfSSL | 13:80fb167dafdf | 6542 | |
wolfSSL | 13:80fb167dafdf | 6543 | case TLSX_PSK_KEY_EXCHANGE_MODES: |
wolfSSL | 13:80fb167dafdf | 6544 | length += PKM_GET_SIZE(extension->val, msgType); |
wolfSSL | 13:80fb167dafdf | 6545 | break; |
wolfSSL | 13:80fb167dafdf | 6546 | #endif |
wolfSSL | 13:80fb167dafdf | 6547 | #endif |
wolfSSL | 13:80fb167dafdf | 6548 | } |
wolfSSL | 13:80fb167dafdf | 6549 | |
wolfSSL | 13:80fb167dafdf | 6550 | /* marks the extension as processed so ctx level */ |
wolfSSL | 13:80fb167dafdf | 6551 | /* extensions don't overlap with ssl level ones. */ |
wolfSSL | 13:80fb167dafdf | 6552 | TURN_ON(semaphore, TLSX_ToSemaphore(extension->type)); |
wolfSSL | 13:80fb167dafdf | 6553 | } |
wolfSSL | 13:80fb167dafdf | 6554 | |
wolfSSL | 13:80fb167dafdf | 6555 | return length; |
wolfSSL | 13:80fb167dafdf | 6556 | } |
wolfSSL | 13:80fb167dafdf | 6557 | |
wolfSSL | 13:80fb167dafdf | 6558 | /** Writes the extensions of a list in a buffer. */ |
wolfSSL | 13:80fb167dafdf | 6559 | static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore, |
wolfSSL | 13:80fb167dafdf | 6560 | byte msgType) |
wolfSSL | 13:80fb167dafdf | 6561 | { |
wolfSSL | 13:80fb167dafdf | 6562 | TLSX* extension; |
wolfSSL | 13:80fb167dafdf | 6563 | word16 offset = 0; |
wolfSSL | 13:80fb167dafdf | 6564 | word16 length_offset = 0; |
wolfSSL | 13:80fb167dafdf | 6565 | byte isRequest = (msgType == client_hello); |
wolfSSL | 13:80fb167dafdf | 6566 | |
wolfSSL | 13:80fb167dafdf | 6567 | while ((extension = list)) { |
wolfSSL | 13:80fb167dafdf | 6568 | list = extension->next; |
wolfSSL | 13:80fb167dafdf | 6569 | |
wolfSSL | 13:80fb167dafdf | 6570 | /* only extensions marked as response are written in a response. */ |
wolfSSL | 13:80fb167dafdf | 6571 | if (!isRequest && !extension->resp) |
wolfSSL | 13:80fb167dafdf | 6572 | continue; /* skip! */ |
wolfSSL | 13:80fb167dafdf | 6573 | |
wolfSSL | 13:80fb167dafdf | 6574 | /* ssl level extensions are expected to override ctx level ones. */ |
wolfSSL | 13:80fb167dafdf | 6575 | if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type))) |
wolfSSL | 13:80fb167dafdf | 6576 | continue; /* skip! */ |
wolfSSL | 13:80fb167dafdf | 6577 | |
wolfSSL | 13:80fb167dafdf | 6578 | /* writes extension type. */ |
wolfSSL | 13:80fb167dafdf | 6579 | c16toa(extension->type, output + offset); |
wolfSSL | 13:80fb167dafdf | 6580 | offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 6581 | length_offset = offset; |
wolfSSL | 13:80fb167dafdf | 6582 | |
wolfSSL | 13:80fb167dafdf | 6583 | /* extension data should be written internally. */ |
wolfSSL | 13:80fb167dafdf | 6584 | switch (extension->type) { |
wolfSSL | 13:80fb167dafdf | 6585 | case TLSX_SERVER_NAME: |
wolfSSL | 13:80fb167dafdf | 6586 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 6587 | WOLFSSL_MSG("SNI extension to write"); |
wolfSSL | 13:80fb167dafdf | 6588 | offset += SNI_WRITE((SNI*)extension->data, output + offset); |
wolfSSL | 13:80fb167dafdf | 6589 | } |
wolfSSL | 13:80fb167dafdf | 6590 | break; |
wolfSSL | 13:80fb167dafdf | 6591 | |
wolfSSL | 13:80fb167dafdf | 6592 | case TLSX_MAX_FRAGMENT_LENGTH: |
wolfSSL | 13:80fb167dafdf | 6593 | WOLFSSL_MSG("Max Fragment Length extension to write"); |
wolfSSL | 13:80fb167dafdf | 6594 | offset += MFL_WRITE((byte*)extension->data, output + offset); |
wolfSSL | 13:80fb167dafdf | 6595 | break; |
wolfSSL | 13:80fb167dafdf | 6596 | |
wolfSSL | 13:80fb167dafdf | 6597 | case TLSX_TRUNCATED_HMAC: |
wolfSSL | 13:80fb167dafdf | 6598 | WOLFSSL_MSG("Truncated HMAC extension to write"); |
wolfSSL | 13:80fb167dafdf | 6599 | /* always empty. */ |
wolfSSL | 13:80fb167dafdf | 6600 | break; |
wolfSSL | 13:80fb167dafdf | 6601 | |
wolfSSL | 13:80fb167dafdf | 6602 | case TLSX_SUPPORTED_GROUPS: |
wolfSSL | 13:80fb167dafdf | 6603 | WOLFSSL_MSG("Elliptic Curves extension to write"); |
wolfSSL | 13:80fb167dafdf | 6604 | offset += EC_WRITE((EllipticCurve*)extension->data, |
wolfSSL | 13:80fb167dafdf | 6605 | output + offset); |
wolfSSL | 13:80fb167dafdf | 6606 | break; |
wolfSSL | 13:80fb167dafdf | 6607 | |
wolfSSL | 13:80fb167dafdf | 6608 | case TLSX_STATUS_REQUEST: |
wolfSSL | 13:80fb167dafdf | 6609 | WOLFSSL_MSG("Certificate Status Request extension to write"); |
wolfSSL | 13:80fb167dafdf | 6610 | offset += CSR_WRITE((CertificateStatusRequest*)extension->data, |
wolfSSL | 13:80fb167dafdf | 6611 | output + offset, isRequest); |
wolfSSL | 13:80fb167dafdf | 6612 | break; |
wolfSSL | 13:80fb167dafdf | 6613 | |
wolfSSL | 13:80fb167dafdf | 6614 | case TLSX_STATUS_REQUEST_V2: |
wolfSSL | 13:80fb167dafdf | 6615 | WOLFSSL_MSG("Certificate Status Request v2 extension to write"); |
wolfSSL | 13:80fb167dafdf | 6616 | offset += CSR2_WRITE( |
wolfSSL | 13:80fb167dafdf | 6617 | (CertificateStatusRequestItemV2*)extension->data, |
wolfSSL | 13:80fb167dafdf | 6618 | output + offset, isRequest); |
wolfSSL | 13:80fb167dafdf | 6619 | break; |
wolfSSL | 13:80fb167dafdf | 6620 | |
wolfSSL | 13:80fb167dafdf | 6621 | case TLSX_RENEGOTIATION_INFO: |
wolfSSL | 13:80fb167dafdf | 6622 | WOLFSSL_MSG("Secure Renegotiation extension to write"); |
wolfSSL | 13:80fb167dafdf | 6623 | offset += SCR_WRITE((SecureRenegotiation*)extension->data, |
wolfSSL | 13:80fb167dafdf | 6624 | output + offset, isRequest); |
wolfSSL | 13:80fb167dafdf | 6625 | break; |
wolfSSL | 13:80fb167dafdf | 6626 | |
wolfSSL | 13:80fb167dafdf | 6627 | case TLSX_SESSION_TICKET: |
wolfSSL | 13:80fb167dafdf | 6628 | WOLFSSL_MSG("Session Ticket extension to write"); |
wolfSSL | 13:80fb167dafdf | 6629 | offset += WOLF_STK_WRITE((SessionTicket*)extension->data, |
wolfSSL | 13:80fb167dafdf | 6630 | output + offset, isRequest); |
wolfSSL | 13:80fb167dafdf | 6631 | break; |
wolfSSL | 13:80fb167dafdf | 6632 | |
wolfSSL | 13:80fb167dafdf | 6633 | case TLSX_QUANTUM_SAFE_HYBRID: |
wolfSSL | 13:80fb167dafdf | 6634 | WOLFSSL_MSG("Quantum-Safe-Hybrid extension to write"); |
wolfSSL | 13:80fb167dafdf | 6635 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 6636 | offset += QSH_WRITE((QSHScheme*)extension->data, output + offset); |
wolfSSL | 13:80fb167dafdf | 6637 | } |
wolfSSL | 13:80fb167dafdf | 6638 | offset += QSHPK_WRITE((QSHScheme*)extension->data, output + offset); |
wolfSSL | 13:80fb167dafdf | 6639 | offset += QSH_SERREQ(output + offset, isRequest); |
wolfSSL | 13:80fb167dafdf | 6640 | break; |
wolfSSL | 13:80fb167dafdf | 6641 | |
wolfSSL | 13:80fb167dafdf | 6642 | case TLSX_APPLICATION_LAYER_PROTOCOL: |
wolfSSL | 13:80fb167dafdf | 6643 | WOLFSSL_MSG("ALPN extension to write"); |
wolfSSL | 13:80fb167dafdf | 6644 | offset += ALPN_WRITE((ALPN*)extension->data, output + offset); |
wolfSSL | 13:80fb167dafdf | 6645 | break; |
wolfSSL | 13:80fb167dafdf | 6646 | |
wolfSSL | 13:80fb167dafdf | 6647 | case TLSX_SIGNATURE_ALGORITHMS: |
wolfSSL | 13:80fb167dafdf | 6648 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 6649 | WOLFSSL_MSG("Signature Algorithms extension to write"); |
wolfSSL | 13:80fb167dafdf | 6650 | offset += SA_WRITE(extension->data, output + offset); |
wolfSSL | 13:80fb167dafdf | 6651 | #endif |
wolfSSL | 13:80fb167dafdf | 6652 | break; |
wolfSSL | 13:80fb167dafdf | 6653 | |
wolfSSL | 13:80fb167dafdf | 6654 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 6655 | case TLSX_SUPPORTED_VERSIONS: |
wolfSSL | 13:80fb167dafdf | 6656 | WOLFSSL_MSG("Supported Versions extension to write"); |
wolfSSL | 13:80fb167dafdf | 6657 | offset += SV_WRITE(extension->data, output + offset); |
wolfSSL | 13:80fb167dafdf | 6658 | break; |
wolfSSL | 13:80fb167dafdf | 6659 | |
wolfSSL | 13:80fb167dafdf | 6660 | case TLSX_KEY_SHARE: |
wolfSSL | 13:80fb167dafdf | 6661 | WOLFSSL_MSG("Key Share extension to write"); |
wolfSSL | 13:80fb167dafdf | 6662 | offset += KS_WRITE(extension->data, output + offset, msgType); |
wolfSSL | 13:80fb167dafdf | 6663 | break; |
wolfSSL | 13:80fb167dafdf | 6664 | |
wolfSSL | 13:80fb167dafdf | 6665 | #ifndef NO_PSK |
wolfSSL | 13:80fb167dafdf | 6666 | case TLSX_PRE_SHARED_KEY: |
wolfSSL | 13:80fb167dafdf | 6667 | WOLFSSL_MSG("Pre-Shared Key extension to write"); |
wolfSSL | 13:80fb167dafdf | 6668 | offset += PSK_WRITE(extension->data, output + offset, msgType); |
wolfSSL | 13:80fb167dafdf | 6669 | break; |
wolfSSL | 13:80fb167dafdf | 6670 | |
wolfSSL | 13:80fb167dafdf | 6671 | case TLSX_PSK_KEY_EXCHANGE_MODES: |
wolfSSL | 13:80fb167dafdf | 6672 | WOLFSSL_MSG("PSK Key Exchange Modes extension to write"); |
wolfSSL | 13:80fb167dafdf | 6673 | offset += PKM_WRITE(extension->val, output + offset, msgType); |
wolfSSL | 13:80fb167dafdf | 6674 | break; |
wolfSSL | 13:80fb167dafdf | 6675 | #endif |
wolfSSL | 13:80fb167dafdf | 6676 | #endif |
wolfSSL | 13:80fb167dafdf | 6677 | } |
wolfSSL | 13:80fb167dafdf | 6678 | |
wolfSSL | 13:80fb167dafdf | 6679 | /* writes extension data length. */ |
wolfSSL | 13:80fb167dafdf | 6680 | c16toa(offset - length_offset, output + length_offset - OPAQUE16_LEN); |
wolfSSL | 13:80fb167dafdf | 6681 | |
wolfSSL | 13:80fb167dafdf | 6682 | /* marks the extension as processed so ctx level */ |
wolfSSL | 13:80fb167dafdf | 6683 | /* extensions don't overlap with ssl level ones. */ |
wolfSSL | 13:80fb167dafdf | 6684 | TURN_ON(semaphore, TLSX_ToSemaphore(extension->type)); |
wolfSSL | 13:80fb167dafdf | 6685 | } |
wolfSSL | 13:80fb167dafdf | 6686 | |
wolfSSL | 13:80fb167dafdf | 6687 | return offset; |
wolfSSL | 13:80fb167dafdf | 6688 | } |
wolfSSL | 13:80fb167dafdf | 6689 | |
wolfSSL | 13:80fb167dafdf | 6690 | |
wolfSSL | 13:80fb167dafdf | 6691 | #ifdef HAVE_NTRU |
wolfSSL | 13:80fb167dafdf | 6692 | |
wolfSSL | 13:80fb167dafdf | 6693 | static word32 GetEntropy(unsigned char* out, word32 num_bytes) |
wolfSSL | 13:80fb167dafdf | 6694 | { |
wolfSSL | 13:80fb167dafdf | 6695 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 6696 | |
wolfSSL | 13:80fb167dafdf | 6697 | if (rng == NULL) { |
wolfSSL | 13:80fb167dafdf | 6698 | if ((rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, |
wolfSSL | 13:80fb167dafdf | 6699 | DYNAMIC_TYPE_TLSX)) == NULL) |
wolfSSL | 13:80fb167dafdf | 6700 | return DRBG_OUT_OF_MEMORY; |
wolfSSL | 13:80fb167dafdf | 6701 | wc_InitRng(rng); |
wolfSSL | 13:80fb167dafdf | 6702 | } |
wolfSSL | 13:80fb167dafdf | 6703 | |
wolfSSL | 13:80fb167dafdf | 6704 | if (rngMutex == NULL) { |
wolfSSL | 13:80fb167dafdf | 6705 | if ((rngMutex = (wolfSSL_Mutex*)XMALLOC(sizeof(wolfSSL_Mutex), NULL, |
wolfSSL | 13:80fb167dafdf | 6706 | DYNAMIC_TYPE_TLSX)) == NULL) |
wolfSSL | 13:80fb167dafdf | 6707 | return DRBG_OUT_OF_MEMORY; |
wolfSSL | 13:80fb167dafdf | 6708 | wc_InitMutex(rngMutex); |
wolfSSL | 13:80fb167dafdf | 6709 | } |
wolfSSL | 13:80fb167dafdf | 6710 | |
wolfSSL | 13:80fb167dafdf | 6711 | ret |= wc_LockMutex(rngMutex); |
wolfSSL | 13:80fb167dafdf | 6712 | ret |= wc_RNG_GenerateBlock(rng, out, num_bytes); |
wolfSSL | 13:80fb167dafdf | 6713 | ret |= wc_UnLockMutex(rngMutex); |
wolfSSL | 13:80fb167dafdf | 6714 | |
wolfSSL | 13:80fb167dafdf | 6715 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 6716 | return DRBG_ENTROPY_FAIL; |
wolfSSL | 13:80fb167dafdf | 6717 | |
wolfSSL | 13:80fb167dafdf | 6718 | return DRBG_OK; |
wolfSSL | 13:80fb167dafdf | 6719 | } |
wolfSSL | 13:80fb167dafdf | 6720 | #endif |
wolfSSL | 13:80fb167dafdf | 6721 | |
wolfSSL | 13:80fb167dafdf | 6722 | |
wolfSSL | 13:80fb167dafdf | 6723 | #ifdef HAVE_QSH |
wolfSSL | 13:80fb167dafdf | 6724 | static int TLSX_CreateQSHKey(WOLFSSL* ssl, int type) |
wolfSSL | 13:80fb167dafdf | 6725 | { |
wolfSSL | 13:80fb167dafdf | 6726 | int ret; |
wolfSSL | 13:80fb167dafdf | 6727 | |
wolfSSL | 13:80fb167dafdf | 6728 | (void)ssl; |
wolfSSL | 13:80fb167dafdf | 6729 | |
wolfSSL | 13:80fb167dafdf | 6730 | switch (type) { |
wolfSSL | 13:80fb167dafdf | 6731 | #ifdef HAVE_NTRU |
wolfSSL | 13:80fb167dafdf | 6732 | case WOLFSSL_NTRU_EESS439: |
wolfSSL | 13:80fb167dafdf | 6733 | case WOLFSSL_NTRU_EESS593: |
wolfSSL | 13:80fb167dafdf | 6734 | case WOLFSSL_NTRU_EESS743: |
wolfSSL | 13:80fb167dafdf | 6735 | ret = TLSX_CreateNtruKey(ssl, type); |
wolfSSL | 13:80fb167dafdf | 6736 | break; |
wolfSSL | 13:80fb167dafdf | 6737 | #endif |
wolfSSL | 13:80fb167dafdf | 6738 | default: |
wolfSSL | 13:80fb167dafdf | 6739 | WOLFSSL_MSG("Unknown type for creating NTRU key"); |
wolfSSL | 13:80fb167dafdf | 6740 | return -1; |
wolfSSL | 13:80fb167dafdf | 6741 | } |
wolfSSL | 13:80fb167dafdf | 6742 | |
wolfSSL | 13:80fb167dafdf | 6743 | return ret; |
wolfSSL | 13:80fb167dafdf | 6744 | } |
wolfSSL | 13:80fb167dafdf | 6745 | |
wolfSSL | 13:80fb167dafdf | 6746 | |
wolfSSL | 13:80fb167dafdf | 6747 | static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key) |
wolfSSL | 13:80fb167dafdf | 6748 | { |
wolfSSL | 13:80fb167dafdf | 6749 | QSHKey* current; |
wolfSSL | 13:80fb167dafdf | 6750 | |
wolfSSL | 13:80fb167dafdf | 6751 | if (key == NULL) |
wolfSSL | 13:80fb167dafdf | 6752 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 6753 | |
wolfSSL | 13:80fb167dafdf | 6754 | /* if no public key stored in key then do not add */ |
wolfSSL | 13:80fb167dafdf | 6755 | if (key->pub.length == 0 || key->pub.buffer == NULL) |
wolfSSL | 13:80fb167dafdf | 6756 | return 0; |
wolfSSL | 13:80fb167dafdf | 6757 | |
wolfSSL | 13:80fb167dafdf | 6758 | /* first element to be added to the list */ |
wolfSSL | 13:80fb167dafdf | 6759 | current = *list; |
wolfSSL | 13:80fb167dafdf | 6760 | if (current == NULL) { |
wolfSSL | 13:80fb167dafdf | 6761 | *list = key; |
wolfSSL | 13:80fb167dafdf | 6762 | return 0; |
wolfSSL | 13:80fb167dafdf | 6763 | } |
wolfSSL | 13:80fb167dafdf | 6764 | |
wolfSSL | 13:80fb167dafdf | 6765 | while (current->next) { |
wolfSSL | 13:80fb167dafdf | 6766 | /* can only have one of the key in the list */ |
wolfSSL | 13:80fb167dafdf | 6767 | if (current->name == key->name) |
wolfSSL | 13:80fb167dafdf | 6768 | return -1; |
wolfSSL | 13:80fb167dafdf | 6769 | current = (QSHKey*)current->next; |
wolfSSL | 13:80fb167dafdf | 6770 | } |
wolfSSL | 13:80fb167dafdf | 6771 | |
wolfSSL | 13:80fb167dafdf | 6772 | current->next = (struct QSHKey*)key; |
wolfSSL | 13:80fb167dafdf | 6773 | |
wolfSSL | 13:80fb167dafdf | 6774 | return 0; |
wolfSSL | 13:80fb167dafdf | 6775 | } |
wolfSSL | 13:80fb167dafdf | 6776 | |
wolfSSL | 13:80fb167dafdf | 6777 | |
wolfSSL | 13:80fb167dafdf | 6778 | #if defined(HAVE_NTRU) || defined(HAVE_QSH) |
wolfSSL | 13:80fb167dafdf | 6779 | int TLSX_CreateNtruKey(WOLFSSL* ssl, int type) |
wolfSSL | 13:80fb167dafdf | 6780 | { |
wolfSSL | 13:80fb167dafdf | 6781 | int ret = -1; |
wolfSSL | 13:80fb167dafdf | 6782 | #ifdef HAVE_NTRU |
wolfSSL | 13:80fb167dafdf | 6783 | int ntruType; |
wolfSSL | 13:80fb167dafdf | 6784 | |
wolfSSL | 13:80fb167dafdf | 6785 | /* variable declarations for NTRU*/ |
wolfSSL | 13:80fb167dafdf | 6786 | QSHKey* temp = NULL; |
wolfSSL | 13:80fb167dafdf | 6787 | byte public_key[1027]; |
wolfSSL | 13:80fb167dafdf | 6788 | word16 public_key_len = sizeof(public_key); |
wolfSSL | 13:80fb167dafdf | 6789 | byte private_key[1120]; |
wolfSSL | 13:80fb167dafdf | 6790 | word16 private_key_len = sizeof(private_key); |
wolfSSL | 13:80fb167dafdf | 6791 | DRBG_HANDLE drbg; |
wolfSSL | 13:80fb167dafdf | 6792 | |
wolfSSL | 13:80fb167dafdf | 6793 | if (ssl == NULL) |
wolfSSL | 13:80fb167dafdf | 6794 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 6795 | |
wolfSSL | 13:80fb167dafdf | 6796 | switch (type) { |
wolfSSL | 13:80fb167dafdf | 6797 | case WOLFSSL_NTRU_EESS439: |
wolfSSL | 13:80fb167dafdf | 6798 | ntruType = NTRU_EES439EP1; |
wolfSSL | 13:80fb167dafdf | 6799 | break; |
wolfSSL | 13:80fb167dafdf | 6800 | case WOLFSSL_NTRU_EESS593: |
wolfSSL | 13:80fb167dafdf | 6801 | ntruType = NTRU_EES593EP1; |
wolfSSL | 13:80fb167dafdf | 6802 | break; |
wolfSSL | 13:80fb167dafdf | 6803 | case WOLFSSL_NTRU_EESS743: |
wolfSSL | 13:80fb167dafdf | 6804 | ntruType = NTRU_EES743EP1; |
wolfSSL | 13:80fb167dafdf | 6805 | break; |
wolfSSL | 13:80fb167dafdf | 6806 | default: |
wolfSSL | 13:80fb167dafdf | 6807 | WOLFSSL_MSG("Unknown type for creating NTRU key"); |
wolfSSL | 13:80fb167dafdf | 6808 | return -1; |
wolfSSL | 13:80fb167dafdf | 6809 | } |
wolfSSL | 13:80fb167dafdf | 6810 | ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg); |
wolfSSL | 13:80fb167dafdf | 6811 | if (ret != DRBG_OK) { |
wolfSSL | 13:80fb167dafdf | 6812 | WOLFSSL_MSG("NTRU drbg instantiate failed\n"); |
wolfSSL | 13:80fb167dafdf | 6813 | return ret; |
wolfSSL | 13:80fb167dafdf | 6814 | } |
wolfSSL | 13:80fb167dafdf | 6815 | |
wolfSSL | 13:80fb167dafdf | 6816 | if ((ret = ntru_crypto_ntru_encrypt_keygen(drbg, ntruType, |
wolfSSL | 13:80fb167dafdf | 6817 | &public_key_len, NULL, &private_key_len, NULL)) != NTRU_OK) |
wolfSSL | 13:80fb167dafdf | 6818 | return ret; |
wolfSSL | 13:80fb167dafdf | 6819 | |
wolfSSL | 13:80fb167dafdf | 6820 | if ((ret = ntru_crypto_ntru_encrypt_keygen(drbg, ntruType, |
wolfSSL | 13:80fb167dafdf | 6821 | &public_key_len, public_key, &private_key_len, private_key)) != NTRU_OK) |
wolfSSL | 13:80fb167dafdf | 6822 | return ret; |
wolfSSL | 13:80fb167dafdf | 6823 | |
wolfSSL | 13:80fb167dafdf | 6824 | ret = ntru_crypto_drbg_uninstantiate(drbg); |
wolfSSL | 13:80fb167dafdf | 6825 | if (ret != NTRU_OK) { |
wolfSSL | 13:80fb167dafdf | 6826 | WOLFSSL_MSG("NTRU drbg uninstantiate failed\n"); |
wolfSSL | 13:80fb167dafdf | 6827 | return ret; |
wolfSSL | 13:80fb167dafdf | 6828 | } |
wolfSSL | 13:80fb167dafdf | 6829 | |
wolfSSL | 13:80fb167dafdf | 6830 | if ((temp = (QSHKey*)XMALLOC(sizeof(QSHKey), ssl->heap, |
wolfSSL | 13:80fb167dafdf | 6831 | DYNAMIC_TYPE_TLSX)) == NULL) |
wolfSSL | 13:80fb167dafdf | 6832 | return MEMORY_E; |
wolfSSL | 13:80fb167dafdf | 6833 | temp->name = type; |
wolfSSL | 13:80fb167dafdf | 6834 | temp->pub.length = public_key_len; |
wolfSSL | 13:80fb167dafdf | 6835 | temp->pub.buffer = (byte*)XMALLOC(public_key_len, ssl->heap, |
wolfSSL | 13:80fb167dafdf | 6836 | DYNAMIC_TYPE_PUBLIC_KEY); |
wolfSSL | 13:80fb167dafdf | 6837 | XMEMCPY(temp->pub.buffer, public_key, public_key_len); |
wolfSSL | 13:80fb167dafdf | 6838 | temp->pri.length = private_key_len; |
wolfSSL | 13:80fb167dafdf | 6839 | temp->pri.buffer = (byte*)XMALLOC(private_key_len, ssl->heap, |
wolfSSL | 13:80fb167dafdf | 6840 | DYNAMIC_TYPE_ARRAYS); |
wolfSSL | 13:80fb167dafdf | 6841 | XMEMCPY(temp->pri.buffer, private_key, private_key_len); |
wolfSSL | 13:80fb167dafdf | 6842 | temp->next = NULL; |
wolfSSL | 13:80fb167dafdf | 6843 | |
wolfSSL | 13:80fb167dafdf | 6844 | TLSX_AddQSHKey(&ssl->QSH_Key, temp); |
wolfSSL | 13:80fb167dafdf | 6845 | #endif |
wolfSSL | 13:80fb167dafdf | 6846 | |
wolfSSL | 13:80fb167dafdf | 6847 | (void)ssl; |
wolfSSL | 13:80fb167dafdf | 6848 | (void)type; |
wolfSSL | 13:80fb167dafdf | 6849 | |
wolfSSL | 13:80fb167dafdf | 6850 | return ret; |
wolfSSL | 13:80fb167dafdf | 6851 | } |
wolfSSL | 13:80fb167dafdf | 6852 | #endif |
wolfSSL | 13:80fb167dafdf | 6853 | |
wolfSSL | 13:80fb167dafdf | 6854 | |
wolfSSL | 13:80fb167dafdf | 6855 | /* |
wolfSSL | 13:80fb167dafdf | 6856 | Used to find a public key from the list of keys |
wolfSSL | 13:80fb167dafdf | 6857 | pubLen length of array |
wolfSSL | 13:80fb167dafdf | 6858 | name input the name of the scheme looking for ie WOLFSSL_NTRU_ESSXXX |
wolfSSL | 13:80fb167dafdf | 6859 | |
wolfSSL | 13:80fb167dafdf | 6860 | returns a pointer to public key byte* or NULL if not found |
wolfSSL | 13:80fb167dafdf | 6861 | */ |
wolfSSL | 13:80fb167dafdf | 6862 | static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name) |
wolfSSL | 13:80fb167dafdf | 6863 | { |
wolfSSL | 13:80fb167dafdf | 6864 | QSHKey* current = qsh; |
wolfSSL | 13:80fb167dafdf | 6865 | |
wolfSSL | 13:80fb167dafdf | 6866 | if (qsh == NULL || pubLen == NULL) |
wolfSSL | 13:80fb167dafdf | 6867 | return NULL; |
wolfSSL | 13:80fb167dafdf | 6868 | |
wolfSSL | 13:80fb167dafdf | 6869 | *pubLen = 0; |
wolfSSL | 13:80fb167dafdf | 6870 | |
wolfSSL | 13:80fb167dafdf | 6871 | while(current) { |
wolfSSL | 13:80fb167dafdf | 6872 | if (current->name == name) { |
wolfSSL | 13:80fb167dafdf | 6873 | *pubLen = current->pub.length; |
wolfSSL | 13:80fb167dafdf | 6874 | return current->pub.buffer; |
wolfSSL | 13:80fb167dafdf | 6875 | } |
wolfSSL | 13:80fb167dafdf | 6876 | current = (QSHKey*)current->next; |
wolfSSL | 13:80fb167dafdf | 6877 | } |
wolfSSL | 13:80fb167dafdf | 6878 | |
wolfSSL | 13:80fb167dafdf | 6879 | return NULL; |
wolfSSL | 13:80fb167dafdf | 6880 | } |
wolfSSL | 13:80fb167dafdf | 6881 | #endif /* HAVE_QSH */ |
wolfSSL | 13:80fb167dafdf | 6882 | |
wolfSSL | 13:80fb167dafdf | 6883 | int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) |
wolfSSL | 13:80fb167dafdf | 6884 | { |
wolfSSL | 13:80fb167dafdf | 6885 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 6886 | byte* public_key = NULL; |
wolfSSL | 13:80fb167dafdf | 6887 | word16 public_key_len = 0; |
wolfSSL | 13:80fb167dafdf | 6888 | #ifdef HAVE_QSH |
wolfSSL | 13:80fb167dafdf | 6889 | TLSX* extension; |
wolfSSL | 13:80fb167dafdf | 6890 | QSHScheme* qsh; |
wolfSSL | 13:80fb167dafdf | 6891 | QSHScheme* next; |
wolfSSL | 13:80fb167dafdf | 6892 | |
wolfSSL | 13:80fb167dafdf | 6893 | /* add supported QSHSchemes */ |
wolfSSL | 13:80fb167dafdf | 6894 | WOLFSSL_MSG("Adding supported QSH Schemes"); |
wolfSSL | 13:80fb167dafdf | 6895 | #endif |
wolfSSL | 13:80fb167dafdf | 6896 | |
wolfSSL | 13:80fb167dafdf | 6897 | /* server will add extension depending on whats parsed from client */ |
wolfSSL | 13:80fb167dafdf | 6898 | if (!isServer) { |
wolfSSL | 13:80fb167dafdf | 6899 | #ifdef HAVE_QSH |
wolfSSL | 13:80fb167dafdf | 6900 | /* test if user has set a specific scheme already */ |
wolfSSL | 13:80fb167dafdf | 6901 | if (!ssl->user_set_QSHSchemes) { |
wolfSSL | 13:80fb167dafdf | 6902 | if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) { |
wolfSSL | 13:80fb167dafdf | 6903 | if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS743)) != 0) { |
wolfSSL | 13:80fb167dafdf | 6904 | WOLFSSL_MSG("Error creating ntru keys"); |
wolfSSL | 13:80fb167dafdf | 6905 | return ret; |
wolfSSL | 13:80fb167dafdf | 6906 | } |
wolfSSL | 13:80fb167dafdf | 6907 | if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS593)) != 0) { |
wolfSSL | 13:80fb167dafdf | 6908 | WOLFSSL_MSG("Error creating ntru keys"); |
wolfSSL | 13:80fb167dafdf | 6909 | return ret; |
wolfSSL | 13:80fb167dafdf | 6910 | } |
wolfSSL | 13:80fb167dafdf | 6911 | if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS439)) != 0) { |
wolfSSL | 13:80fb167dafdf | 6912 | WOLFSSL_MSG("Error creating ntru keys"); |
wolfSSL | 13:80fb167dafdf | 6913 | return ret; |
wolfSSL | 13:80fb167dafdf | 6914 | } |
wolfSSL | 13:80fb167dafdf | 6915 | |
wolfSSL | 13:80fb167dafdf | 6916 | /* add NTRU 256 */ |
wolfSSL | 13:80fb167dafdf | 6917 | public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, |
wolfSSL | 13:80fb167dafdf | 6918 | &public_key_len, WOLFSSL_NTRU_EESS743); |
wolfSSL | 13:80fb167dafdf | 6919 | } |
wolfSSL | 13:80fb167dafdf | 6920 | if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS743, |
wolfSSL | 13:80fb167dafdf | 6921 | public_key, public_key_len, ssl->heap) |
wolfSSL | 13:80fb167dafdf | 6922 | != SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 6923 | ret = -1; |
wolfSSL | 13:80fb167dafdf | 6924 | |
wolfSSL | 13:80fb167dafdf | 6925 | /* add NTRU 196 */ |
wolfSSL | 13:80fb167dafdf | 6926 | if (ssl->sendQSHKeys) { |
wolfSSL | 13:80fb167dafdf | 6927 | public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, |
wolfSSL | 13:80fb167dafdf | 6928 | &public_key_len, WOLFSSL_NTRU_EESS593); |
wolfSSL | 13:80fb167dafdf | 6929 | } |
wolfSSL | 13:80fb167dafdf | 6930 | if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS593, |
wolfSSL | 13:80fb167dafdf | 6931 | public_key, public_key_len, ssl->heap) |
wolfSSL | 13:80fb167dafdf | 6932 | != SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 6933 | ret = -1; |
wolfSSL | 13:80fb167dafdf | 6934 | |
wolfSSL | 13:80fb167dafdf | 6935 | /* add NTRU 128 */ |
wolfSSL | 13:80fb167dafdf | 6936 | if (ssl->sendQSHKeys) { |
wolfSSL | 13:80fb167dafdf | 6937 | public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, |
wolfSSL | 13:80fb167dafdf | 6938 | &public_key_len, WOLFSSL_NTRU_EESS439); |
wolfSSL | 13:80fb167dafdf | 6939 | } |
wolfSSL | 13:80fb167dafdf | 6940 | if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS439, |
wolfSSL | 13:80fb167dafdf | 6941 | public_key, public_key_len, ssl->heap) |
wolfSSL | 13:80fb167dafdf | 6942 | != SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 6943 | ret = -1; |
wolfSSL | 13:80fb167dafdf | 6944 | } |
wolfSSL | 13:80fb167dafdf | 6945 | else if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) { |
wolfSSL | 13:80fb167dafdf | 6946 | /* for each scheme make a client key */ |
wolfSSL | 13:80fb167dafdf | 6947 | extension = TLSX_Find(ssl->extensions, TLSX_QUANTUM_SAFE_HYBRID); |
wolfSSL | 13:80fb167dafdf | 6948 | if (extension) { |
wolfSSL | 13:80fb167dafdf | 6949 | qsh = (QSHScheme*)extension->data; |
wolfSSL | 13:80fb167dafdf | 6950 | |
wolfSSL | 13:80fb167dafdf | 6951 | while (qsh) { |
wolfSSL | 13:80fb167dafdf | 6952 | if ((ret = TLSX_CreateQSHKey(ssl, qsh->name)) != 0) |
wolfSSL | 13:80fb167dafdf | 6953 | return ret; |
wolfSSL | 13:80fb167dafdf | 6954 | |
wolfSSL | 13:80fb167dafdf | 6955 | /* get next now because qsh could be freed */ |
wolfSSL | 13:80fb167dafdf | 6956 | next = qsh->next; |
wolfSSL | 13:80fb167dafdf | 6957 | |
wolfSSL | 13:80fb167dafdf | 6958 | /* find the public key created and add to extension*/ |
wolfSSL | 13:80fb167dafdf | 6959 | public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, |
wolfSSL | 13:80fb167dafdf | 6960 | &public_key_len, qsh->name); |
wolfSSL | 13:80fb167dafdf | 6961 | if (TLSX_UseQSHScheme(&ssl->extensions, qsh->name, |
wolfSSL | 13:80fb167dafdf | 6962 | public_key, public_key_len, |
wolfSSL | 13:80fb167dafdf | 6963 | ssl->heap) != SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 6964 | ret = -1; |
wolfSSL | 13:80fb167dafdf | 6965 | qsh = next; |
wolfSSL | 13:80fb167dafdf | 6966 | } |
wolfSSL | 13:80fb167dafdf | 6967 | } |
wolfSSL | 13:80fb167dafdf | 6968 | } |
wolfSSL | 13:80fb167dafdf | 6969 | #endif |
wolfSSL | 13:80fb167dafdf | 6970 | |
wolfSSL | 13:80fb167dafdf | 6971 | #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES) |
wolfSSL | 13:80fb167dafdf | 6972 | if (!ssl->options.userCurves && !ssl->ctx->userCurves) { |
wolfSSL | 13:80fb167dafdf | 6973 | #ifndef HAVE_FIPS |
wolfSSL | 13:80fb167dafdf | 6974 | #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 6975 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 6976 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 6977 | WOLFSSL_ECC_SECP160R1, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 6978 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:80fb167dafdf | 6979 | #endif |
wolfSSL | 13:80fb167dafdf | 6980 | #ifdef HAVE_ECC_SECPR2 |
wolfSSL | 13:80fb167dafdf | 6981 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 6982 | WOLFSSL_ECC_SECP160R2, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 6983 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:80fb167dafdf | 6984 | #endif |
wolfSSL | 13:80fb167dafdf | 6985 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:80fb167dafdf | 6986 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 6987 | WOLFSSL_ECC_SECP160K1, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 6988 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:80fb167dafdf | 6989 | #endif |
wolfSSL | 13:80fb167dafdf | 6990 | #endif |
wolfSSL | 13:80fb167dafdf | 6991 | #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 6992 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 6993 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 6994 | WOLFSSL_ECC_SECP192R1, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 6995 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:80fb167dafdf | 6996 | #endif |
wolfSSL | 13:80fb167dafdf | 6997 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:80fb167dafdf | 6998 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 6999 | WOLFSSL_ECC_SECP192K1, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7000 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:80fb167dafdf | 7001 | #endif |
wolfSSL | 13:80fb167dafdf | 7002 | #endif |
wolfSSL | 13:80fb167dafdf | 7003 | #endif |
wolfSSL | 13:80fb167dafdf | 7004 | #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 7005 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 7006 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 7007 | WOLFSSL_ECC_SECP224R1, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7008 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:80fb167dafdf | 7009 | #endif |
wolfSSL | 13:80fb167dafdf | 7010 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:80fb167dafdf | 7011 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 7012 | WOLFSSL_ECC_SECP224K1, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7013 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:80fb167dafdf | 7014 | #endif |
wolfSSL | 13:80fb167dafdf | 7015 | #endif |
wolfSSL | 13:80fb167dafdf | 7016 | #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 7017 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 7018 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 7019 | WOLFSSL_ECC_SECP256R1, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7020 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:80fb167dafdf | 7021 | #endif |
wolfSSL | 13:80fb167dafdf | 7022 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 13:80fb167dafdf | 7023 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 7024 | WOLFSSL_ECC_SECP256K1, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7025 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:80fb167dafdf | 7026 | #endif |
wolfSSL | 13:80fb167dafdf | 7027 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 13:80fb167dafdf | 7028 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 7029 | WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7030 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:80fb167dafdf | 7031 | #endif |
wolfSSL | 13:80fb167dafdf | 7032 | #endif |
wolfSSL | 13:80fb167dafdf | 7033 | #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 7034 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 7035 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 7036 | WOLFSSL_ECC_SECP384R1, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7037 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:80fb167dafdf | 7038 | #endif |
wolfSSL | 13:80fb167dafdf | 7039 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 13:80fb167dafdf | 7040 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 7041 | WOLFSSL_ECC_BRAINPOOLP384R1, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7042 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:80fb167dafdf | 7043 | #endif |
wolfSSL | 13:80fb167dafdf | 7044 | #endif |
wolfSSL | 13:80fb167dafdf | 7045 | #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 7046 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 13:80fb167dafdf | 7047 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 7048 | WOLFSSL_ECC_BRAINPOOLP512R1, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7049 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:80fb167dafdf | 7050 | #endif |
wolfSSL | 13:80fb167dafdf | 7051 | #endif |
wolfSSL | 13:80fb167dafdf | 7052 | #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) |
wolfSSL | 13:80fb167dafdf | 7053 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 7054 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 7055 | WOLFSSL_ECC_SECP521R1, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7056 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:80fb167dafdf | 7057 | #endif |
wolfSSL | 13:80fb167dafdf | 7058 | #endif |
wolfSSL | 13:80fb167dafdf | 7059 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7060 | #if defined(HAVE_CURVE25519) |
wolfSSL | 13:80fb167dafdf | 7061 | #ifndef NO_ECC_SECP |
wolfSSL | 13:80fb167dafdf | 7062 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 7063 | WOLFSSL_ECC_X25519, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7064 | if (ret != SSL_SUCCESS) return ret; |
wolfSSL | 13:80fb167dafdf | 7065 | #endif |
wolfSSL | 13:80fb167dafdf | 7066 | #endif |
wolfSSL | 13:80fb167dafdf | 7067 | #endif |
wolfSSL | 13:80fb167dafdf | 7068 | } |
wolfSSL | 13:80fb167dafdf | 7069 | #endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */ |
wolfSSL | 13:80fb167dafdf | 7070 | } /* is not server */ |
wolfSSL | 13:80fb167dafdf | 7071 | |
wolfSSL | 13:80fb167dafdf | 7072 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7073 | WOLFSSL_MSG("Adding signature algorithms extension"); |
wolfSSL | 13:80fb167dafdf | 7074 | if ((ret = TLSX_SetSignatureAlgorithms(&ssl->extensions, ssl, |
wolfSSL | 13:80fb167dafdf | 7075 | ssl->heap)) != 0) |
wolfSSL | 13:80fb167dafdf | 7076 | return ret; |
wolfSSL | 13:80fb167dafdf | 7077 | |
wolfSSL | 13:80fb167dafdf | 7078 | if (!isServer && IsAtLeastTLSv1_3(ssl->version)) { |
wolfSSL | 13:80fb167dafdf | 7079 | /* Add mandatory TLS v1.3 extension: supported version */ |
wolfSSL | 13:80fb167dafdf | 7080 | WOLFSSL_MSG("Adding supported versions extension"); |
wolfSSL | 13:80fb167dafdf | 7081 | if ((ret = TLSX_SetSupportedVersions(&ssl->extensions, ssl, |
wolfSSL | 13:80fb167dafdf | 7082 | ssl->heap)) != 0) |
wolfSSL | 13:80fb167dafdf | 7083 | return ret; |
wolfSSL | 13:80fb167dafdf | 7084 | |
wolfSSL | 13:80fb167dafdf | 7085 | /* Add FFDHE supported groups. */ |
wolfSSL | 13:80fb167dafdf | 7086 | #ifdef HAVE_FFDHE_2048 |
wolfSSL | 13:80fb167dafdf | 7087 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 7088 | WOLFSSL_FFDHE_2048, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7089 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 7090 | return ret; |
wolfSSL | 13:80fb167dafdf | 7091 | #endif |
wolfSSL | 13:80fb167dafdf | 7092 | #ifdef HAVE_FFDHE_3072 |
wolfSSL | 13:80fb167dafdf | 7093 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 7094 | WOLFSSL_FFDHE_3072, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7095 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 7096 | return ret; |
wolfSSL | 13:80fb167dafdf | 7097 | #endif |
wolfSSL | 13:80fb167dafdf | 7098 | #ifdef HAVE_FFDHE_4096 |
wolfSSL | 13:80fb167dafdf | 7099 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 7100 | WOLFSSL_FFDHE_4096, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7101 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 7102 | return ret; |
wolfSSL | 13:80fb167dafdf | 7103 | #endif |
wolfSSL | 13:80fb167dafdf | 7104 | #ifdef HAVE_FFDHE_6144 |
wolfSSL | 13:80fb167dafdf | 7105 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 7106 | WOLFSSL_FFDHE_6144, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7107 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 7108 | return ret; |
wolfSSL | 13:80fb167dafdf | 7109 | #endif |
wolfSSL | 13:80fb167dafdf | 7110 | #ifdef HAVE_FFDHE_8192 |
wolfSSL | 13:80fb167dafdf | 7111 | ret = TLSX_UseSupportedCurve(&ssl->extensions, |
wolfSSL | 13:80fb167dafdf | 7112 | WOLFSSL_FFDHE_8192, ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7113 | if (ret != SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 7114 | return ret; |
wolfSSL | 13:80fb167dafdf | 7115 | #endif |
wolfSSL | 13:80fb167dafdf | 7116 | ret = 0; |
wolfSSL | 13:80fb167dafdf | 7117 | |
wolfSSL | 13:80fb167dafdf | 7118 | if (TLSX_Find(ssl->extensions, TLSX_KEY_SHARE) == NULL) { |
wolfSSL | 13:80fb167dafdf | 7119 | #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \ |
wolfSSL | 13:80fb167dafdf | 7120 | !defined(NO_ECC_SECP) |
wolfSSL | 13:80fb167dafdf | 7121 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_ECC_SECP256R1, 0, NULL, |
wolfSSL | 13:80fb167dafdf | 7122 | NULL); |
wolfSSL | 13:80fb167dafdf | 7123 | #elif (!defined(NO_ECC384) || defined(HAVE_ALL_CURVES)) && \ |
wolfSSL | 13:80fb167dafdf | 7124 | !defined(NO_ECC_SECP) |
wolfSSL | 13:80fb167dafdf | 7125 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_ECC_SECP384R1, 0, NULL, |
wolfSSL | 13:80fb167dafdf | 7126 | NULL); |
wolfSSL | 13:80fb167dafdf | 7127 | #elif (!defined(NO_ECC521) || defined(HAVE_ALL_CURVES)) && \ |
wolfSSL | 13:80fb167dafdf | 7128 | !defined(NO_ECC_SECP) |
wolfSSL | 13:80fb167dafdf | 7129 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_ECC_SECP521R1, 0, NULL, |
wolfSSL | 13:80fb167dafdf | 7130 | NULL); |
wolfSSL | 13:80fb167dafdf | 7131 | #elif defined(HAVE_FFDHE_2048) |
wolfSSL | 13:80fb167dafdf | 7132 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_FFDHE_2048, 0, NULL, NULL); |
wolfSSL | 13:80fb167dafdf | 7133 | #elif defined(HAVE_FFDHE_3072) |
wolfSSL | 13:80fb167dafdf | 7134 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_FFDHE_3072, 0, NULL, NULL); |
wolfSSL | 13:80fb167dafdf | 7135 | #elif defined(HAVE_FFDHE_4096) |
wolfSSL | 13:80fb167dafdf | 7136 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_FFDHE_4096, 0, NULL, NULL); |
wolfSSL | 13:80fb167dafdf | 7137 | #elif defined(HAVE_FFDHE_6144) |
wolfSSL | 13:80fb167dafdf | 7138 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_FFDHE_6144, 0, NULL, NULL); |
wolfSSL | 13:80fb167dafdf | 7139 | #elif defined(HAVE_FFDHE_8192) |
wolfSSL | 13:80fb167dafdf | 7140 | ret = TLSX_KeyShare_Use(ssl, WOLFSSL_FFDHE_8192, 0, NULL, NULL); |
wolfSSL | 13:80fb167dafdf | 7141 | #else |
wolfSSL | 13:80fb167dafdf | 7142 | ret = KEY_SHARE_ERROR; |
wolfSSL | 13:80fb167dafdf | 7143 | #endif |
wolfSSL | 13:80fb167dafdf | 7144 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 7145 | return ret; |
wolfSSL | 13:80fb167dafdf | 7146 | } |
wolfSSL | 13:80fb167dafdf | 7147 | |
wolfSSL | 13:80fb167dafdf | 7148 | #if defined(HAVE_SESSION_TICKET) && !defined(NO_PSK) |
wolfSSL | 13:80fb167dafdf | 7149 | if (ssl->options.resuming) { |
wolfSSL | 13:80fb167dafdf | 7150 | WOLFSSL_SESSION* sess = &ssl->session; |
wolfSSL | 13:80fb167dafdf | 7151 | word32 milli; |
wolfSSL | 13:80fb167dafdf | 7152 | byte modes; |
wolfSSL | 13:80fb167dafdf | 7153 | |
wolfSSL | 13:80fb167dafdf | 7154 | /* Determine the MAC algorithm for the cipher suite used. */ |
wolfSSL | 13:80fb167dafdf | 7155 | ssl->options.cipherSuite0 = sess->cipherSuite0; |
wolfSSL | 13:80fb167dafdf | 7156 | ssl->options.cipherSuite = sess->cipherSuite; |
wolfSSL | 13:80fb167dafdf | 7157 | SetCipherSpecs(ssl); |
wolfSSL | 13:80fb167dafdf | 7158 | milli = TimeNowInMilliseconds() - sess->ticketSeen + |
wolfSSL | 13:80fb167dafdf | 7159 | sess->ticketAdd; |
wolfSSL | 13:80fb167dafdf | 7160 | /* Pre-shared key is mandatory extension for resumption. */ |
wolfSSL | 13:80fb167dafdf | 7161 | ret = TLSX_PreSharedKey_Use(ssl, sess->ticket, sess->ticketLen, |
wolfSSL | 13:80fb167dafdf | 7162 | milli, ssl->specs.mac_algorithm, 1, |
wolfSSL | 13:80fb167dafdf | 7163 | ssl->heap); |
wolfSSL | 13:80fb167dafdf | 7164 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 7165 | return ret; |
wolfSSL | 13:80fb167dafdf | 7166 | |
wolfSSL | 13:80fb167dafdf | 7167 | /* Pre-shared key modes: mandatory extension for resumption. */ |
wolfSSL | 13:80fb167dafdf | 7168 | modes = 1 << PSK_KE; |
wolfSSL | 13:80fb167dafdf | 7169 | #if !defined(NO_DH) || defined(HAVE_ECC) |
wolfSSL | 13:80fb167dafdf | 7170 | if (!ssl->options.noPskDheKe) |
wolfSSL | 13:80fb167dafdf | 7171 | modes |= 1 << PSK_DHE_KE; |
wolfSSL | 13:80fb167dafdf | 7172 | #endif |
wolfSSL | 13:80fb167dafdf | 7173 | ret = TLSX_PskKeModes_Use(ssl, modes); |
wolfSSL | 13:80fb167dafdf | 7174 | if (ret != 0) |
wolfSSL | 13:80fb167dafdf | 7175 | return ret; |
wolfSSL | 13:80fb167dafdf | 7176 | } |
wolfSSL | 13:80fb167dafdf | 7177 | #endif |
wolfSSL | 13:80fb167dafdf | 7178 | /* TODO: [TLS13] Add PSKs */ |
wolfSSL | 13:80fb167dafdf | 7179 | } |
wolfSSL | 13:80fb167dafdf | 7180 | |
wolfSSL | 13:80fb167dafdf | 7181 | #endif |
wolfSSL | 13:80fb167dafdf | 7182 | |
wolfSSL | 13:80fb167dafdf | 7183 | (void)isServer; |
wolfSSL | 13:80fb167dafdf | 7184 | (void)public_key; |
wolfSSL | 13:80fb167dafdf | 7185 | (void)public_key_len; |
wolfSSL | 13:80fb167dafdf | 7186 | (void)ssl; |
wolfSSL | 13:80fb167dafdf | 7187 | |
wolfSSL | 13:80fb167dafdf | 7188 | if (ret == SSL_SUCCESS) |
wolfSSL | 13:80fb167dafdf | 7189 | ret = 0; |
wolfSSL | 13:80fb167dafdf | 7190 | |
wolfSSL | 13:80fb167dafdf | 7191 | return ret; |
wolfSSL | 13:80fb167dafdf | 7192 | } |
wolfSSL | 13:80fb167dafdf | 7193 | |
wolfSSL | 13:80fb167dafdf | 7194 | |
wolfSSL | 13:80fb167dafdf | 7195 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:80fb167dafdf | 7196 | |
wolfSSL | 13:80fb167dafdf | 7197 | /** Tells the buffered size of extensions to be sent into the client hello. */ |
wolfSSL | 13:80fb167dafdf | 7198 | word16 TLSX_GetRequestSize(WOLFSSL* ssl) |
wolfSSL | 13:80fb167dafdf | 7199 | { |
wolfSSL | 13:80fb167dafdf | 7200 | word16 length = 0; |
wolfSSL | 13:80fb167dafdf | 7201 | |
wolfSSL | 13:80fb167dafdf | 7202 | if (TLSX_SupportExtensions(ssl)) { |
wolfSSL | 13:80fb167dafdf | 7203 | byte semaphore[SEMAPHORE_SIZE] = {0}; |
wolfSSL | 13:80fb167dafdf | 7204 | |
wolfSSL | 13:80fb167dafdf | 7205 | EC_VALIDATE_REQUEST(ssl, semaphore); |
wolfSSL | 13:80fb167dafdf | 7206 | QSH_VALIDATE_REQUEST(ssl, semaphore); |
wolfSSL | 13:80fb167dafdf | 7207 | WOLF_STK_VALIDATE_REQUEST(ssl); |
wolfSSL | 13:80fb167dafdf | 7208 | #if defined(WOLFSSL_TLS13) |
wolfSSL | 13:80fb167dafdf | 7209 | if (!IsAtLeastTLSv1_2(ssl)) |
wolfSSL | 13:80fb167dafdf | 7210 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS)); |
wolfSSL | 13:80fb167dafdf | 7211 | if (!IsAtLeastTLSv1_3(ssl->version)) { |
wolfSSL | 13:80fb167dafdf | 7212 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS)); |
wolfSSL | 13:80fb167dafdf | 7213 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); |
wolfSSL | 13:80fb167dafdf | 7214 | #ifndef NO_PSK |
wolfSSL | 13:80fb167dafdf | 7215 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); |
wolfSSL | 13:80fb167dafdf | 7216 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES)); |
wolfSSL | 13:80fb167dafdf | 7217 | #endif |
wolfSSL | 13:80fb167dafdf | 7218 | } |
wolfSSL | 13:80fb167dafdf | 7219 | #endif |
wolfSSL | 13:80fb167dafdf | 7220 | |
wolfSSL | 13:80fb167dafdf | 7221 | if (ssl->extensions) |
wolfSSL | 13:80fb167dafdf | 7222 | length += TLSX_GetSize(ssl->extensions, semaphore, client_hello); |
wolfSSL | 13:80fb167dafdf | 7223 | |
wolfSSL | 13:80fb167dafdf | 7224 | if (ssl->ctx && ssl->ctx->extensions) { |
wolfSSL | 13:80fb167dafdf | 7225 | length += TLSX_GetSize(ssl->ctx->extensions, semaphore, |
wolfSSL | 13:80fb167dafdf | 7226 | client_hello); |
wolfSSL | 13:80fb167dafdf | 7227 | } |
wolfSSL | 13:80fb167dafdf | 7228 | |
wolfSSL | 13:80fb167dafdf | 7229 | #ifndef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7230 | if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) |
wolfSSL | 13:80fb167dafdf | 7231 | length += HELLO_EXT_SZ + OPAQUE16_LEN + |
wolfSSL | 13:80fb167dafdf | 7232 | + ssl->suites->hashSigAlgoSz; |
wolfSSL | 13:80fb167dafdf | 7233 | #endif |
wolfSSL | 13:80fb167dafdf | 7234 | |
wolfSSL | 13:80fb167dafdf | 7235 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:80fb167dafdf | 7236 | if (ssl->options.haveEMS) |
wolfSSL | 13:80fb167dafdf | 7237 | length += HELLO_EXT_SZ; |
wolfSSL | 13:80fb167dafdf | 7238 | #endif |
wolfSSL | 13:80fb167dafdf | 7239 | } |
wolfSSL | 13:80fb167dafdf | 7240 | |
wolfSSL | 13:80fb167dafdf | 7241 | if (length) |
wolfSSL | 13:80fb167dafdf | 7242 | length += OPAQUE16_LEN; /* for total length storage. */ |
wolfSSL | 13:80fb167dafdf | 7243 | |
wolfSSL | 13:80fb167dafdf | 7244 | return length; |
wolfSSL | 13:80fb167dafdf | 7245 | } |
wolfSSL | 13:80fb167dafdf | 7246 | |
wolfSSL | 13:80fb167dafdf | 7247 | /** Writes the extensions to be sent into the client hello. */ |
wolfSSL | 13:80fb167dafdf | 7248 | word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output) |
wolfSSL | 13:80fb167dafdf | 7249 | { |
wolfSSL | 13:80fb167dafdf | 7250 | word16 offset = 0; |
wolfSSL | 13:80fb167dafdf | 7251 | |
wolfSSL | 13:80fb167dafdf | 7252 | if (TLSX_SupportExtensions(ssl) && output) { |
wolfSSL | 13:80fb167dafdf | 7253 | byte semaphore[SEMAPHORE_SIZE] = {0}; |
wolfSSL | 13:80fb167dafdf | 7254 | |
wolfSSL | 13:80fb167dafdf | 7255 | offset += OPAQUE16_LEN; /* extensions length */ |
wolfSSL | 13:80fb167dafdf | 7256 | |
wolfSSL | 13:80fb167dafdf | 7257 | EC_VALIDATE_REQUEST(ssl, semaphore); |
wolfSSL | 13:80fb167dafdf | 7258 | WOLF_STK_VALIDATE_REQUEST(ssl); |
wolfSSL | 13:80fb167dafdf | 7259 | QSH_VALIDATE_REQUEST(ssl, semaphore); |
wolfSSL | 13:80fb167dafdf | 7260 | #if defined(WOLFSSL_TLS13) |
wolfSSL | 13:80fb167dafdf | 7261 | if (!IsAtLeastTLSv1_2(ssl)) |
wolfSSL | 13:80fb167dafdf | 7262 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS)); |
wolfSSL | 13:80fb167dafdf | 7263 | if (!IsAtLeastTLSv1_3(ssl->version)) { |
wolfSSL | 13:80fb167dafdf | 7264 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS)); |
wolfSSL | 13:80fb167dafdf | 7265 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); |
wolfSSL | 13:80fb167dafdf | 7266 | #ifndef NO_PSK |
wolfSSL | 13:80fb167dafdf | 7267 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES)); |
wolfSSL | 13:80fb167dafdf | 7268 | #endif |
wolfSSL | 13:80fb167dafdf | 7269 | } |
wolfSSL | 13:80fb167dafdf | 7270 | #ifndef NO_PSK |
wolfSSL | 13:80fb167dafdf | 7271 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); |
wolfSSL | 13:80fb167dafdf | 7272 | #endif |
wolfSSL | 13:80fb167dafdf | 7273 | #endif |
wolfSSL | 13:80fb167dafdf | 7274 | |
wolfSSL | 13:80fb167dafdf | 7275 | if (ssl->extensions) |
wolfSSL | 13:80fb167dafdf | 7276 | offset += TLSX_Write(ssl->extensions, output + offset, semaphore, |
wolfSSL | 13:80fb167dafdf | 7277 | client_hello); |
wolfSSL | 13:80fb167dafdf | 7278 | |
wolfSSL | 13:80fb167dafdf | 7279 | if (ssl->ctx && ssl->ctx->extensions) |
wolfSSL | 13:80fb167dafdf | 7280 | offset += TLSX_Write(ssl->ctx->extensions, output + offset, |
wolfSSL | 13:80fb167dafdf | 7281 | semaphore, client_hello); |
wolfSSL | 13:80fb167dafdf | 7282 | |
wolfSSL | 13:80fb167dafdf | 7283 | #ifndef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7284 | if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) { |
wolfSSL | 13:80fb167dafdf | 7285 | int i; |
wolfSSL | 13:80fb167dafdf | 7286 | /* extension type */ |
wolfSSL | 13:80fb167dafdf | 7287 | c16toa(TLSX_SIGNATURE_ALGORITHMS, output + offset); |
wolfSSL | 13:80fb167dafdf | 7288 | offset += HELLO_EXT_TYPE_SZ; |
wolfSSL | 13:80fb167dafdf | 7289 | |
wolfSSL | 13:80fb167dafdf | 7290 | /* extension data length */ |
wolfSSL | 13:80fb167dafdf | 7291 | c16toa(OPAQUE16_LEN + ssl->suites->hashSigAlgoSz, |
wolfSSL | 13:80fb167dafdf | 7292 | output + offset); |
wolfSSL | 13:80fb167dafdf | 7293 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 7294 | |
wolfSSL | 13:80fb167dafdf | 7295 | /* sig algos length */ |
wolfSSL | 13:80fb167dafdf | 7296 | c16toa(ssl->suites->hashSigAlgoSz, output + offset); |
wolfSSL | 13:80fb167dafdf | 7297 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 7298 | |
wolfSSL | 13:80fb167dafdf | 7299 | /* sig algos */ |
wolfSSL | 13:80fb167dafdf | 7300 | for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, offset++) |
wolfSSL | 13:80fb167dafdf | 7301 | output[offset] = ssl->suites->hashSigAlgo[i]; |
wolfSSL | 13:80fb167dafdf | 7302 | } |
wolfSSL | 13:80fb167dafdf | 7303 | #endif |
wolfSSL | 13:80fb167dafdf | 7304 | |
wolfSSL | 13:80fb167dafdf | 7305 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:80fb167dafdf | 7306 | if (ssl->options.haveEMS) { |
wolfSSL | 13:80fb167dafdf | 7307 | c16toa(HELLO_EXT_EXTMS, output + offset); |
wolfSSL | 13:80fb167dafdf | 7308 | offset += HELLO_EXT_TYPE_SZ; |
wolfSSL | 13:80fb167dafdf | 7309 | c16toa(0, output + offset); |
wolfSSL | 13:80fb167dafdf | 7310 | offset += HELLO_EXT_SZ_SZ; |
wolfSSL | 13:80fb167dafdf | 7311 | } |
wolfSSL | 13:80fb167dafdf | 7312 | #endif |
wolfSSL | 13:80fb167dafdf | 7313 | |
wolfSSL | 13:80fb167dafdf | 7314 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7315 | if (IsAtLeastTLSv1_3(ssl->version) && ssl->options.resuming) { |
wolfSSL | 13:80fb167dafdf | 7316 | #ifndef NO_PSK |
wolfSSL | 13:80fb167dafdf | 7317 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); |
wolfSSL | 13:80fb167dafdf | 7318 | #endif |
wolfSSL | 13:80fb167dafdf | 7319 | offset += TLSX_Write(ssl->extensions, output + offset, semaphore, |
wolfSSL | 13:80fb167dafdf | 7320 | client_hello); |
wolfSSL | 13:80fb167dafdf | 7321 | } |
wolfSSL | 13:80fb167dafdf | 7322 | #endif |
wolfSSL | 13:80fb167dafdf | 7323 | |
wolfSSL | 13:80fb167dafdf | 7324 | if (offset > OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 7325 | c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ |
wolfSSL | 13:80fb167dafdf | 7326 | } |
wolfSSL | 13:80fb167dafdf | 7327 | |
wolfSSL | 13:80fb167dafdf | 7328 | return offset; |
wolfSSL | 13:80fb167dafdf | 7329 | } |
wolfSSL | 13:80fb167dafdf | 7330 | |
wolfSSL | 13:80fb167dafdf | 7331 | #endif /* NO_WOLFSSL_CLIENT */ |
wolfSSL | 13:80fb167dafdf | 7332 | |
wolfSSL | 13:80fb167dafdf | 7333 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 7334 | |
wolfSSL | 13:80fb167dafdf | 7335 | /** Tells the buffered size of extensions to be sent into the server hello. */ |
wolfSSL | 13:80fb167dafdf | 7336 | word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType) |
wolfSSL | 13:80fb167dafdf | 7337 | { |
wolfSSL | 13:80fb167dafdf | 7338 | word16 length = 0; |
wolfSSL | 13:80fb167dafdf | 7339 | byte semaphore[SEMAPHORE_SIZE] = {0}; |
wolfSSL | 13:80fb167dafdf | 7340 | |
wolfSSL | 13:80fb167dafdf | 7341 | switch (msgType) { |
wolfSSL | 13:80fb167dafdf | 7342 | case server_hello: |
wolfSSL | 13:80fb167dafdf | 7343 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7344 | case hello_retry_request: |
wolfSSL | 13:80fb167dafdf | 7345 | if (ssl->options.tls1_3) { |
wolfSSL | 13:80fb167dafdf | 7346 | XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE); |
wolfSSL | 13:80fb167dafdf | 7347 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); |
wolfSSL | 13:80fb167dafdf | 7348 | #ifndef NO_PSK |
wolfSSL | 13:80fb167dafdf | 7349 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); |
wolfSSL | 13:80fb167dafdf | 7350 | #endif |
wolfSSL | 13:80fb167dafdf | 7351 | } |
wolfSSL | 13:80fb167dafdf | 7352 | break; |
wolfSSL | 13:80fb167dafdf | 7353 | case encrypted_extensions: |
wolfSSL | 13:80fb167dafdf | 7354 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET)); |
wolfSSL | 13:80fb167dafdf | 7355 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); |
wolfSSL | 13:80fb167dafdf | 7356 | #ifndef NO_PSK |
wolfSSL | 13:80fb167dafdf | 7357 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); |
wolfSSL | 13:80fb167dafdf | 7358 | #endif |
wolfSSL | 13:80fb167dafdf | 7359 | #endif |
wolfSSL | 13:80fb167dafdf | 7360 | break; |
wolfSSL | 13:80fb167dafdf | 7361 | } |
wolfSSL | 13:80fb167dafdf | 7362 | |
wolfSSL | 13:80fb167dafdf | 7363 | #ifdef HAVE_QSH |
wolfSSL | 13:80fb167dafdf | 7364 | /* change response if not using TLS_QSH */ |
wolfSSL | 13:80fb167dafdf | 7365 | if (!ssl->options.haveQSH) { |
wolfSSL | 13:80fb167dafdf | 7366 | TLSX* ext = TLSX_Find(ssl->extensions, TLSX_QUANTUM_SAFE_HYBRID); |
wolfSSL | 13:80fb167dafdf | 7367 | if (ext) |
wolfSSL | 13:80fb167dafdf | 7368 | ext->resp = 0; |
wolfSSL | 13:80fb167dafdf | 7369 | } |
wolfSSL | 13:80fb167dafdf | 7370 | #endif |
wolfSSL | 13:80fb167dafdf | 7371 | |
wolfSSL | 13:80fb167dafdf | 7372 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:80fb167dafdf | 7373 | if (ssl->options.haveEMS && msgType == server_hello) |
wolfSSL | 13:80fb167dafdf | 7374 | length += HELLO_EXT_SZ; |
wolfSSL | 13:80fb167dafdf | 7375 | #endif |
wolfSSL | 13:80fb167dafdf | 7376 | |
wolfSSL | 13:80fb167dafdf | 7377 | if (TLSX_SupportExtensions(ssl)) |
wolfSSL | 13:80fb167dafdf | 7378 | length += TLSX_GetSize(ssl->extensions, semaphore, msgType); |
wolfSSL | 13:80fb167dafdf | 7379 | |
wolfSSL | 13:80fb167dafdf | 7380 | /* All the response data is set at the ssl object only, so no ctx here. */ |
wolfSSL | 13:80fb167dafdf | 7381 | |
wolfSSL | 13:80fb167dafdf | 7382 | if (length || (msgType != server_hello)) |
wolfSSL | 13:80fb167dafdf | 7383 | length += OPAQUE16_LEN; /* for total length storage. */ |
wolfSSL | 13:80fb167dafdf | 7384 | |
wolfSSL | 13:80fb167dafdf | 7385 | return length; |
wolfSSL | 13:80fb167dafdf | 7386 | } |
wolfSSL | 13:80fb167dafdf | 7387 | |
wolfSSL | 13:80fb167dafdf | 7388 | /** Writes the server hello extensions into a buffer. */ |
wolfSSL | 13:80fb167dafdf | 7389 | word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType) |
wolfSSL | 13:80fb167dafdf | 7390 | { |
wolfSSL | 13:80fb167dafdf | 7391 | word16 offset = 0; |
wolfSSL | 13:80fb167dafdf | 7392 | |
wolfSSL | 13:80fb167dafdf | 7393 | if (TLSX_SupportExtensions(ssl) && output) { |
wolfSSL | 13:80fb167dafdf | 7394 | byte semaphore[SEMAPHORE_SIZE] = {0}; |
wolfSSL | 13:80fb167dafdf | 7395 | |
wolfSSL | 13:80fb167dafdf | 7396 | switch (msgType) { |
wolfSSL | 13:80fb167dafdf | 7397 | case server_hello: |
wolfSSL | 13:80fb167dafdf | 7398 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7399 | case hello_retry_request: |
wolfSSL | 13:80fb167dafdf | 7400 | if (ssl->options.tls1_3) { |
wolfSSL | 13:80fb167dafdf | 7401 | XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE); |
wolfSSL | 13:80fb167dafdf | 7402 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); |
wolfSSL | 13:80fb167dafdf | 7403 | #ifndef NO_PSK |
wolfSSL | 13:80fb167dafdf | 7404 | TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); |
wolfSSL | 13:80fb167dafdf | 7405 | #endif |
wolfSSL | 13:80fb167dafdf | 7406 | } |
wolfSSL | 13:80fb167dafdf | 7407 | break; |
wolfSSL | 13:80fb167dafdf | 7408 | case encrypted_extensions: |
wolfSSL | 13:80fb167dafdf | 7409 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET)); |
wolfSSL | 13:80fb167dafdf | 7410 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); |
wolfSSL | 13:80fb167dafdf | 7411 | #ifndef NO_PSK |
wolfSSL | 13:80fb167dafdf | 7412 | TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); |
wolfSSL | 13:80fb167dafdf | 7413 | #endif |
wolfSSL | 13:80fb167dafdf | 7414 | #endif |
wolfSSL | 13:80fb167dafdf | 7415 | break; |
wolfSSL | 13:80fb167dafdf | 7416 | } |
wolfSSL | 13:80fb167dafdf | 7417 | |
wolfSSL | 13:80fb167dafdf | 7418 | offset += OPAQUE16_LEN; /* extensions length */ |
wolfSSL | 13:80fb167dafdf | 7419 | |
wolfSSL | 13:80fb167dafdf | 7420 | offset += TLSX_Write(ssl->extensions, output + offset, semaphore, |
wolfSSL | 13:80fb167dafdf | 7421 | msgType); |
wolfSSL | 13:80fb167dafdf | 7422 | |
wolfSSL | 13:80fb167dafdf | 7423 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:80fb167dafdf | 7424 | if (ssl->options.haveEMS && msgType == server_hello) { |
wolfSSL | 13:80fb167dafdf | 7425 | c16toa(HELLO_EXT_EXTMS, output + offset); |
wolfSSL | 13:80fb167dafdf | 7426 | offset += HELLO_EXT_TYPE_SZ; |
wolfSSL | 13:80fb167dafdf | 7427 | c16toa(0, output + offset); |
wolfSSL | 13:80fb167dafdf | 7428 | offset += HELLO_EXT_SZ_SZ; |
wolfSSL | 13:80fb167dafdf | 7429 | } |
wolfSSL | 13:80fb167dafdf | 7430 | #endif |
wolfSSL | 13:80fb167dafdf | 7431 | |
wolfSSL | 13:80fb167dafdf | 7432 | if (offset > OPAQUE16_LEN || msgType == encrypted_extensions) |
wolfSSL | 13:80fb167dafdf | 7433 | c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ |
wolfSSL | 13:80fb167dafdf | 7434 | } |
wolfSSL | 13:80fb167dafdf | 7435 | |
wolfSSL | 13:80fb167dafdf | 7436 | return offset; |
wolfSSL | 13:80fb167dafdf | 7437 | } |
wolfSSL | 13:80fb167dafdf | 7438 | |
wolfSSL | 13:80fb167dafdf | 7439 | #endif /* NO_WOLFSSL_SERVER */ |
wolfSSL | 13:80fb167dafdf | 7440 | |
wolfSSL | 13:80fb167dafdf | 7441 | /** Parses a buffer of TLS extensions. */ |
wolfSSL | 13:80fb167dafdf | 7442 | int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, |
wolfSSL | 13:80fb167dafdf | 7443 | Suites *suites) |
wolfSSL | 13:80fb167dafdf | 7444 | { |
wolfSSL | 13:80fb167dafdf | 7445 | int ret = 0; |
wolfSSL | 13:80fb167dafdf | 7446 | word16 offset = 0; |
wolfSSL | 13:80fb167dafdf | 7447 | byte isRequest = (msgType == client_hello); |
wolfSSL | 13:80fb167dafdf | 7448 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:80fb167dafdf | 7449 | byte pendingEMS = 0; |
wolfSSL | 13:80fb167dafdf | 7450 | #endif |
wolfSSL | 13:80fb167dafdf | 7451 | |
wolfSSL | 13:80fb167dafdf | 7452 | if (!ssl || !input || (isRequest && !suites)) |
wolfSSL | 13:80fb167dafdf | 7453 | return BAD_FUNC_ARG; |
wolfSSL | 13:80fb167dafdf | 7454 | |
wolfSSL | 13:80fb167dafdf | 7455 | while (ret == 0 && offset < length) { |
wolfSSL | 13:80fb167dafdf | 7456 | word16 type; |
wolfSSL | 13:80fb167dafdf | 7457 | word16 size; |
wolfSSL | 13:80fb167dafdf | 7458 | |
wolfSSL | 13:80fb167dafdf | 7459 | if (length - offset < HELLO_EXT_TYPE_SZ + OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 7460 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 7461 | |
wolfSSL | 13:80fb167dafdf | 7462 | ato16(input + offset, &type); |
wolfSSL | 13:80fb167dafdf | 7463 | offset += HELLO_EXT_TYPE_SZ; |
wolfSSL | 13:80fb167dafdf | 7464 | |
wolfSSL | 13:80fb167dafdf | 7465 | ato16(input + offset, &size); |
wolfSSL | 13:80fb167dafdf | 7466 | offset += OPAQUE16_LEN; |
wolfSSL | 13:80fb167dafdf | 7467 | |
wolfSSL | 13:80fb167dafdf | 7468 | if (offset + size > length) |
wolfSSL | 13:80fb167dafdf | 7469 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 7470 | |
wolfSSL | 13:80fb167dafdf | 7471 | switch (type) { |
wolfSSL | 13:80fb167dafdf | 7472 | case TLSX_SERVER_NAME: |
wolfSSL | 13:80fb167dafdf | 7473 | WOLFSSL_MSG("SNI extension received"); |
wolfSSL | 13:80fb167dafdf | 7474 | |
wolfSSL | 13:80fb167dafdf | 7475 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7476 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:80fb167dafdf | 7477 | msgType != client_hello && |
wolfSSL | 13:80fb167dafdf | 7478 | msgType != encrypted_extensions) { |
wolfSSL | 13:80fb167dafdf | 7479 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:80fb167dafdf | 7480 | } |
wolfSSL | 13:80fb167dafdf | 7481 | #endif |
wolfSSL | 13:80fb167dafdf | 7482 | ret = SNI_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:80fb167dafdf | 7483 | break; |
wolfSSL | 13:80fb167dafdf | 7484 | |
wolfSSL | 13:80fb167dafdf | 7485 | case TLSX_MAX_FRAGMENT_LENGTH: |
wolfSSL | 13:80fb167dafdf | 7486 | WOLFSSL_MSG("Max Fragment Length extension received"); |
wolfSSL | 13:80fb167dafdf | 7487 | |
wolfSSL | 13:80fb167dafdf | 7488 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7489 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:80fb167dafdf | 7490 | msgType != client_hello && |
wolfSSL | 13:80fb167dafdf | 7491 | msgType != encrypted_extensions) { |
wolfSSL | 13:80fb167dafdf | 7492 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:80fb167dafdf | 7493 | } |
wolfSSL | 13:80fb167dafdf | 7494 | #endif |
wolfSSL | 13:80fb167dafdf | 7495 | ret = MFL_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:80fb167dafdf | 7496 | break; |
wolfSSL | 13:80fb167dafdf | 7497 | |
wolfSSL | 13:80fb167dafdf | 7498 | case TLSX_TRUNCATED_HMAC: |
wolfSSL | 13:80fb167dafdf | 7499 | WOLFSSL_MSG("Truncated HMAC extension received"); |
wolfSSL | 13:80fb167dafdf | 7500 | |
wolfSSL | 13:80fb167dafdf | 7501 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7502 | if (IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:80fb167dafdf | 7503 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:80fb167dafdf | 7504 | #endif |
wolfSSL | 13:80fb167dafdf | 7505 | ret = THM_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:80fb167dafdf | 7506 | break; |
wolfSSL | 13:80fb167dafdf | 7507 | |
wolfSSL | 13:80fb167dafdf | 7508 | case TLSX_SUPPORTED_GROUPS: |
wolfSSL | 13:80fb167dafdf | 7509 | WOLFSSL_MSG("Elliptic Curves extension received"); |
wolfSSL | 13:80fb167dafdf | 7510 | |
wolfSSL | 13:80fb167dafdf | 7511 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7512 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:80fb167dafdf | 7513 | msgType != client_hello && |
wolfSSL | 13:80fb167dafdf | 7514 | msgType != encrypted_extensions) { |
wolfSSL | 13:80fb167dafdf | 7515 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:80fb167dafdf | 7516 | } |
wolfSSL | 13:80fb167dafdf | 7517 | #endif |
wolfSSL | 13:80fb167dafdf | 7518 | ret = EC_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:80fb167dafdf | 7519 | break; |
wolfSSL | 13:80fb167dafdf | 7520 | |
wolfSSL | 13:80fb167dafdf | 7521 | case TLSX_STATUS_REQUEST: |
wolfSSL | 13:80fb167dafdf | 7522 | WOLFSSL_MSG("Certificate Status Request extension received"); |
wolfSSL | 13:80fb167dafdf | 7523 | |
wolfSSL | 13:80fb167dafdf | 7524 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7525 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:80fb167dafdf | 7526 | msgType != client_hello && |
wolfSSL | 13:80fb167dafdf | 7527 | msgType != encrypted_extensions) { |
wolfSSL | 13:80fb167dafdf | 7528 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:80fb167dafdf | 7529 | } |
wolfSSL | 13:80fb167dafdf | 7530 | #endif |
wolfSSL | 13:80fb167dafdf | 7531 | ret = CSR_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:80fb167dafdf | 7532 | break; |
wolfSSL | 13:80fb167dafdf | 7533 | |
wolfSSL | 13:80fb167dafdf | 7534 | case TLSX_STATUS_REQUEST_V2: |
wolfSSL | 13:80fb167dafdf | 7535 | WOLFSSL_MSG("Certificate Status Request v2 extension received"); |
wolfSSL | 13:80fb167dafdf | 7536 | |
wolfSSL | 13:80fb167dafdf | 7537 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7538 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:80fb167dafdf | 7539 | msgType != client_hello && |
wolfSSL | 13:80fb167dafdf | 7540 | msgType != encrypted_extensions) { |
wolfSSL | 13:80fb167dafdf | 7541 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:80fb167dafdf | 7542 | } |
wolfSSL | 13:80fb167dafdf | 7543 | #endif |
wolfSSL | 13:80fb167dafdf | 7544 | ret = CSR2_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:80fb167dafdf | 7545 | break; |
wolfSSL | 13:80fb167dafdf | 7546 | |
wolfSSL | 13:80fb167dafdf | 7547 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:80fb167dafdf | 7548 | case HELLO_EXT_EXTMS: |
wolfSSL | 13:80fb167dafdf | 7549 | WOLFSSL_MSG("Extended Master Secret extension received"); |
wolfSSL | 13:80fb167dafdf | 7550 | |
wolfSSL | 13:80fb167dafdf | 7551 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7552 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:80fb167dafdf | 7553 | msgType != client_hello) { |
wolfSSL | 13:80fb167dafdf | 7554 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:80fb167dafdf | 7555 | } |
wolfSSL | 13:80fb167dafdf | 7556 | #endif |
wolfSSL | 13:80fb167dafdf | 7557 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 7558 | if (isRequest && !IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:80fb167dafdf | 7559 | ssl->options.haveEMS = 1; |
wolfSSL | 13:80fb167dafdf | 7560 | #endif |
wolfSSL | 13:80fb167dafdf | 7561 | pendingEMS = 1; |
wolfSSL | 13:80fb167dafdf | 7562 | break; |
wolfSSL | 13:80fb167dafdf | 7563 | #endif |
wolfSSL | 13:80fb167dafdf | 7564 | |
wolfSSL | 13:80fb167dafdf | 7565 | case TLSX_RENEGOTIATION_INFO: |
wolfSSL | 13:80fb167dafdf | 7566 | WOLFSSL_MSG("Secure Renegotiation extension received"); |
wolfSSL | 13:80fb167dafdf | 7567 | |
wolfSSL | 13:80fb167dafdf | 7568 | ret = SCR_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:80fb167dafdf | 7569 | break; |
wolfSSL | 13:80fb167dafdf | 7570 | |
wolfSSL | 13:80fb167dafdf | 7571 | case TLSX_SESSION_TICKET: |
wolfSSL | 13:80fb167dafdf | 7572 | WOLFSSL_MSG("Session Ticket extension received"); |
wolfSSL | 13:80fb167dafdf | 7573 | |
wolfSSL | 13:80fb167dafdf | 7574 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7575 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:80fb167dafdf | 7576 | msgType != client_hello) { |
wolfSSL | 13:80fb167dafdf | 7577 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:80fb167dafdf | 7578 | } |
wolfSSL | 13:80fb167dafdf | 7579 | #endif |
wolfSSL | 13:80fb167dafdf | 7580 | ret = WOLF_STK_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:80fb167dafdf | 7581 | break; |
wolfSSL | 13:80fb167dafdf | 7582 | |
wolfSSL | 13:80fb167dafdf | 7583 | case TLSX_QUANTUM_SAFE_HYBRID: |
wolfSSL | 13:80fb167dafdf | 7584 | WOLFSSL_MSG("Quantum-Safe-Hybrid extension received"); |
wolfSSL | 13:80fb167dafdf | 7585 | |
wolfSSL | 13:80fb167dafdf | 7586 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7587 | if (IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:80fb167dafdf | 7588 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:80fb167dafdf | 7589 | #endif |
wolfSSL | 13:80fb167dafdf | 7590 | ret = QSH_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:80fb167dafdf | 7591 | break; |
wolfSSL | 13:80fb167dafdf | 7592 | |
wolfSSL | 13:80fb167dafdf | 7593 | case TLSX_APPLICATION_LAYER_PROTOCOL: |
wolfSSL | 13:80fb167dafdf | 7594 | WOLFSSL_MSG("ALPN extension received"); |
wolfSSL | 13:80fb167dafdf | 7595 | |
wolfSSL | 13:80fb167dafdf | 7596 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7597 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:80fb167dafdf | 7598 | msgType != client_hello && |
wolfSSL | 13:80fb167dafdf | 7599 | msgType != encrypted_extensions) { |
wolfSSL | 13:80fb167dafdf | 7600 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:80fb167dafdf | 7601 | } |
wolfSSL | 13:80fb167dafdf | 7602 | #endif |
wolfSSL | 13:80fb167dafdf | 7603 | ret = ALPN_PARSE(ssl, input + offset, size, isRequest); |
wolfSSL | 13:80fb167dafdf | 7604 | break; |
wolfSSL | 13:80fb167dafdf | 7605 | |
wolfSSL | 13:80fb167dafdf | 7606 | #ifndef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7607 | case TLSX_SIGNATURE_ALGORITHMS: |
wolfSSL | 13:80fb167dafdf | 7608 | WOLFSSL_MSG("Extended signature algorithm extension received"); |
wolfSSL | 13:80fb167dafdf | 7609 | |
wolfSSL | 13:80fb167dafdf | 7610 | if (isRequest) { |
wolfSSL | 13:80fb167dafdf | 7611 | /* do not mess with offset inside the switch! */ |
wolfSSL | 13:80fb167dafdf | 7612 | if (IsAtLeastTLSv1_2(ssl)) { |
wolfSSL | 13:80fb167dafdf | 7613 | ato16(input + offset, &suites->hashSigAlgoSz); |
wolfSSL | 13:80fb167dafdf | 7614 | |
wolfSSL | 13:80fb167dafdf | 7615 | if (suites->hashSigAlgoSz > size - OPAQUE16_LEN) |
wolfSSL | 13:80fb167dafdf | 7616 | return BUFFER_ERROR; |
wolfSSL | 13:80fb167dafdf | 7617 | |
wolfSSL | 13:80fb167dafdf | 7618 | XMEMCPY(suites->hashSigAlgo, |
wolfSSL | 13:80fb167dafdf | 7619 | input + offset + OPAQUE16_LEN, |
wolfSSL | 13:80fb167dafdf | 7620 | min(suites->hashSigAlgoSz, |
wolfSSL | 13:80fb167dafdf | 7621 | HELLO_EXT_SIGALGO_MAX)); |
wolfSSL | 13:80fb167dafdf | 7622 | } |
wolfSSL | 13:80fb167dafdf | 7623 | } else { |
wolfSSL | 13:80fb167dafdf | 7624 | WOLFSSL_MSG("Servers MUST NOT send SIG ALGO extension."); |
wolfSSL | 13:80fb167dafdf | 7625 | } |
wolfSSL | 13:80fb167dafdf | 7626 | |
wolfSSL | 13:80fb167dafdf | 7627 | break; |
wolfSSL | 13:80fb167dafdf | 7628 | #endif |
wolfSSL | 13:80fb167dafdf | 7629 | |
wolfSSL | 13:80fb167dafdf | 7630 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7631 | case TLSX_SUPPORTED_VERSIONS: |
wolfSSL | 13:80fb167dafdf | 7632 | WOLFSSL_MSG("Supported Versions extension received"); |
wolfSSL | 13:80fb167dafdf | 7633 | |
wolfSSL | 13:80fb167dafdf | 7634 | if (!IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:80fb167dafdf | 7635 | break; |
wolfSSL | 13:80fb167dafdf | 7636 | |
wolfSSL | 13:80fb167dafdf | 7637 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:80fb167dafdf | 7638 | msgType != client_hello) { |
wolfSSL | 13:80fb167dafdf | 7639 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:80fb167dafdf | 7640 | } |
wolfSSL | 13:80fb167dafdf | 7641 | ret = SV_PARSE(ssl, input + offset, size); |
wolfSSL | 13:80fb167dafdf | 7642 | break; |
wolfSSL | 13:80fb167dafdf | 7643 | |
wolfSSL | 13:80fb167dafdf | 7644 | case TLSX_SIGNATURE_ALGORITHMS: |
wolfSSL | 13:80fb167dafdf | 7645 | WOLFSSL_MSG("Signature Algorithms extension received"); |
wolfSSL | 13:80fb167dafdf | 7646 | |
wolfSSL | 13:80fb167dafdf | 7647 | if (!IsAtLeastTLSv1_2(ssl)) |
wolfSSL | 13:80fb167dafdf | 7648 | break; |
wolfSSL | 13:80fb167dafdf | 7649 | |
wolfSSL | 13:80fb167dafdf | 7650 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:80fb167dafdf | 7651 | msgType != client_hello) { |
wolfSSL | 13:80fb167dafdf | 7652 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:80fb167dafdf | 7653 | } |
wolfSSL | 13:80fb167dafdf | 7654 | ret = SA_PARSE(ssl, input + offset, size); |
wolfSSL | 13:80fb167dafdf | 7655 | break; |
wolfSSL | 13:80fb167dafdf | 7656 | |
wolfSSL | 13:80fb167dafdf | 7657 | case TLSX_KEY_SHARE: |
wolfSSL | 13:80fb167dafdf | 7658 | WOLFSSL_MSG("Key Share extension received"); |
wolfSSL | 13:80fb167dafdf | 7659 | |
wolfSSL | 13:80fb167dafdf | 7660 | if (!IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:80fb167dafdf | 7661 | break; |
wolfSSL | 13:80fb167dafdf | 7662 | |
wolfSSL | 13:80fb167dafdf | 7663 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:80fb167dafdf | 7664 | msgType != client_hello && msgType != server_hello && |
wolfSSL | 13:80fb167dafdf | 7665 | msgType != hello_retry_request) { |
wolfSSL | 13:80fb167dafdf | 7666 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:80fb167dafdf | 7667 | } |
wolfSSL | 13:80fb167dafdf | 7668 | ret = KS_PARSE(ssl, input + offset, size, msgType); |
wolfSSL | 13:80fb167dafdf | 7669 | break; |
wolfSSL | 13:80fb167dafdf | 7670 | |
wolfSSL | 13:80fb167dafdf | 7671 | #ifndef NO_PSK |
wolfSSL | 13:80fb167dafdf | 7672 | case TLSX_PRE_SHARED_KEY: |
wolfSSL | 13:80fb167dafdf | 7673 | WOLFSSL_MSG("Pre-Shared Key extension received"); |
wolfSSL | 13:80fb167dafdf | 7674 | |
wolfSSL | 13:80fb167dafdf | 7675 | if (!IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:80fb167dafdf | 7676 | break; |
wolfSSL | 13:80fb167dafdf | 7677 | |
wolfSSL | 13:80fb167dafdf | 7678 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:80fb167dafdf | 7679 | msgType != client_hello && msgType != server_hello) { |
wolfSSL | 13:80fb167dafdf | 7680 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:80fb167dafdf | 7681 | } |
wolfSSL | 13:80fb167dafdf | 7682 | ret = PSK_PARSE(ssl, input + offset, size, msgType); |
wolfSSL | 13:80fb167dafdf | 7683 | break; |
wolfSSL | 13:80fb167dafdf | 7684 | |
wolfSSL | 13:80fb167dafdf | 7685 | case TLSX_PSK_KEY_EXCHANGE_MODES: |
wolfSSL | 13:80fb167dafdf | 7686 | WOLFSSL_MSG("PSK Key Exchange Modes extension received"); |
wolfSSL | 13:80fb167dafdf | 7687 | |
wolfSSL | 13:80fb167dafdf | 7688 | if (!IsAtLeastTLSv1_3(ssl->version)) |
wolfSSL | 13:80fb167dafdf | 7689 | break; |
wolfSSL | 13:80fb167dafdf | 7690 | |
wolfSSL | 13:80fb167dafdf | 7691 | if (IsAtLeastTLSv1_3(ssl->version) && |
wolfSSL | 13:80fb167dafdf | 7692 | msgType != client_hello) { |
wolfSSL | 13:80fb167dafdf | 7693 | return EXT_NOT_ALLOWED; |
wolfSSL | 13:80fb167dafdf | 7694 | } |
wolfSSL | 13:80fb167dafdf | 7695 | ret = PKM_PARSE(ssl, input + offset, size, msgType); |
wolfSSL | 13:80fb167dafdf | 7696 | break; |
wolfSSL | 13:80fb167dafdf | 7697 | #endif |
wolfSSL | 13:80fb167dafdf | 7698 | #endif |
wolfSSL | 13:80fb167dafdf | 7699 | } |
wolfSSL | 13:80fb167dafdf | 7700 | |
wolfSSL | 13:80fb167dafdf | 7701 | /* offset should be updated here! */ |
wolfSSL | 13:80fb167dafdf | 7702 | offset += size; |
wolfSSL | 13:80fb167dafdf | 7703 | } |
wolfSSL | 13:80fb167dafdf | 7704 | |
wolfSSL | 13:80fb167dafdf | 7705 | #ifdef HAVE_EXTENDED_MASTER |
wolfSSL | 13:80fb167dafdf | 7706 | if (!isRequest && ssl->options.haveEMS && !pendingEMS) |
wolfSSL | 13:80fb167dafdf | 7707 | ssl->options.haveEMS = 0; |
wolfSSL | 13:80fb167dafdf | 7708 | #endif |
wolfSSL | 13:80fb167dafdf | 7709 | |
wolfSSL | 13:80fb167dafdf | 7710 | if (ret == 0) |
wolfSSL | 13:80fb167dafdf | 7711 | ret = SNI_VERIFY_PARSE(ssl, isRequest); |
wolfSSL | 13:80fb167dafdf | 7712 | |
wolfSSL | 13:80fb167dafdf | 7713 | return ret; |
wolfSSL | 13:80fb167dafdf | 7714 | } |
wolfSSL | 13:80fb167dafdf | 7715 | |
wolfSSL | 13:80fb167dafdf | 7716 | /* undefining semaphore macros */ |
wolfSSL | 13:80fb167dafdf | 7717 | #undef IS_OFF |
wolfSSL | 13:80fb167dafdf | 7718 | #undef TURN_ON |
wolfSSL | 13:80fb167dafdf | 7719 | #undef SEMAPHORE_SIZE |
wolfSSL | 13:80fb167dafdf | 7720 | |
wolfSSL | 13:80fb167dafdf | 7721 | #endif /* HAVE_TLS_EXTENSIONS */ |
wolfSSL | 13:80fb167dafdf | 7722 | |
wolfSSL | 13:80fb167dafdf | 7723 | #ifndef NO_WOLFSSL_CLIENT |
wolfSSL | 13:80fb167dafdf | 7724 | |
wolfSSL | 13:80fb167dafdf | 7725 | #ifndef NO_OLD_TLS |
wolfSSL | 13:80fb167dafdf | 7726 | |
wolfSSL | 13:80fb167dafdf | 7727 | WOLFSSL_METHOD* wolfTLSv1_client_method(void) |
wolfSSL | 13:80fb167dafdf | 7728 | { |
wolfSSL | 13:80fb167dafdf | 7729 | return wolfTLSv1_client_method_ex(NULL); |
wolfSSL | 13:80fb167dafdf | 7730 | } |
wolfSSL | 13:80fb167dafdf | 7731 | |
wolfSSL | 13:80fb167dafdf | 7732 | |
wolfSSL | 13:80fb167dafdf | 7733 | WOLFSSL_METHOD* wolfTLSv1_1_client_method(void) |
wolfSSL | 13:80fb167dafdf | 7734 | { |
wolfSSL | 13:80fb167dafdf | 7735 | return wolfTLSv1_1_client_method_ex(NULL); |
wolfSSL | 13:80fb167dafdf | 7736 | } |
wolfSSL | 13:80fb167dafdf | 7737 | |
wolfSSL | 13:80fb167dafdf | 7738 | WOLFSSL_METHOD* wolfTLSv1_client_method_ex(void* heap) |
wolfSSL | 13:80fb167dafdf | 7739 | { |
wolfSSL | 13:80fb167dafdf | 7740 | WOLFSSL_METHOD* method = |
wolfSSL | 13:80fb167dafdf | 7741 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:80fb167dafdf | 7742 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:80fb167dafdf | 7743 | if (method) |
wolfSSL | 13:80fb167dafdf | 7744 | InitSSL_Method(method, MakeTLSv1()); |
wolfSSL | 13:80fb167dafdf | 7745 | return method; |
wolfSSL | 13:80fb167dafdf | 7746 | } |
wolfSSL | 13:80fb167dafdf | 7747 | |
wolfSSL | 13:80fb167dafdf | 7748 | |
wolfSSL | 13:80fb167dafdf | 7749 | WOLFSSL_METHOD* wolfTLSv1_1_client_method_ex(void* heap) |
wolfSSL | 13:80fb167dafdf | 7750 | { |
wolfSSL | 13:80fb167dafdf | 7751 | WOLFSSL_METHOD* method = |
wolfSSL | 13:80fb167dafdf | 7752 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:80fb167dafdf | 7753 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:80fb167dafdf | 7754 | if (method) |
wolfSSL | 13:80fb167dafdf | 7755 | InitSSL_Method(method, MakeTLSv1_1()); |
wolfSSL | 13:80fb167dafdf | 7756 | return method; |
wolfSSL | 13:80fb167dafdf | 7757 | } |
wolfSSL | 13:80fb167dafdf | 7758 | |
wolfSSL | 13:80fb167dafdf | 7759 | #endif /* !NO_OLD_TLS */ |
wolfSSL | 13:80fb167dafdf | 7760 | |
wolfSSL | 13:80fb167dafdf | 7761 | |
wolfSSL | 13:80fb167dafdf | 7762 | WOLFSSL_METHOD* wolfTLSv1_2_client_method(void) |
wolfSSL | 13:80fb167dafdf | 7763 | { |
wolfSSL | 13:80fb167dafdf | 7764 | return wolfTLSv1_2_client_method_ex(NULL); |
wolfSSL | 13:80fb167dafdf | 7765 | } |
wolfSSL | 13:80fb167dafdf | 7766 | |
wolfSSL | 13:80fb167dafdf | 7767 | WOLFSSL_METHOD* wolfTLSv1_2_client_method_ex(void* heap) |
wolfSSL | 13:80fb167dafdf | 7768 | { |
wolfSSL | 13:80fb167dafdf | 7769 | WOLFSSL_METHOD* method = |
wolfSSL | 13:80fb167dafdf | 7770 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:80fb167dafdf | 7771 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:80fb167dafdf | 7772 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 7773 | if (method) |
wolfSSL | 13:80fb167dafdf | 7774 | InitSSL_Method(method, MakeTLSv1_2()); |
wolfSSL | 13:80fb167dafdf | 7775 | return method; |
wolfSSL | 13:80fb167dafdf | 7776 | } |
wolfSSL | 13:80fb167dafdf | 7777 | |
wolfSSL | 13:80fb167dafdf | 7778 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7779 | /* The TLS v1.3 client method data. |
wolfSSL | 13:80fb167dafdf | 7780 | * |
wolfSSL | 13:80fb167dafdf | 7781 | * returns the method data for a TLS v1.3 client. |
wolfSSL | 13:80fb167dafdf | 7782 | */ |
wolfSSL | 13:80fb167dafdf | 7783 | WOLFSSL_METHOD* wolfTLSv1_3_client_method(void) |
wolfSSL | 13:80fb167dafdf | 7784 | { |
wolfSSL | 13:80fb167dafdf | 7785 | return wolfTLSv1_3_client_method_ex(NULL); |
wolfSSL | 13:80fb167dafdf | 7786 | } |
wolfSSL | 13:80fb167dafdf | 7787 | |
wolfSSL | 13:80fb167dafdf | 7788 | /* The TLS v1.3 client method data. |
wolfSSL | 13:80fb167dafdf | 7789 | * |
wolfSSL | 13:80fb167dafdf | 7790 | * heap The heap used for allocation. |
wolfSSL | 13:80fb167dafdf | 7791 | * returns the method data for a TLS v1.3 client. |
wolfSSL | 13:80fb167dafdf | 7792 | */ |
wolfSSL | 13:80fb167dafdf | 7793 | WOLFSSL_METHOD* wolfTLSv1_3_client_method_ex(void* heap) |
wolfSSL | 13:80fb167dafdf | 7794 | { |
wolfSSL | 13:80fb167dafdf | 7795 | WOLFSSL_METHOD* method = (WOLFSSL_METHOD*) |
wolfSSL | 13:80fb167dafdf | 7796 | XMALLOC(sizeof(WOLFSSL_METHOD), heap, |
wolfSSL | 13:80fb167dafdf | 7797 | DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:80fb167dafdf | 7798 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 7799 | if (method) { |
wolfSSL | 13:80fb167dafdf | 7800 | InitSSL_Method(method, MakeTLSv1_3()); |
wolfSSL | 13:80fb167dafdf | 7801 | method->downgrade = 1; |
wolfSSL | 13:80fb167dafdf | 7802 | } |
wolfSSL | 13:80fb167dafdf | 7803 | return method; |
wolfSSL | 13:80fb167dafdf | 7804 | } |
wolfSSL | 13:80fb167dafdf | 7805 | #endif /* WOLFSSL_TLS13 */ |
wolfSSL | 13:80fb167dafdf | 7806 | |
wolfSSL | 13:80fb167dafdf | 7807 | |
wolfSSL | 13:80fb167dafdf | 7808 | WOLFSSL_METHOD* wolfSSLv23_client_method(void) |
wolfSSL | 13:80fb167dafdf | 7809 | { |
wolfSSL | 13:80fb167dafdf | 7810 | return wolfSSLv23_client_method_ex(NULL); |
wolfSSL | 13:80fb167dafdf | 7811 | } |
wolfSSL | 13:80fb167dafdf | 7812 | |
wolfSSL | 13:80fb167dafdf | 7813 | |
wolfSSL | 13:80fb167dafdf | 7814 | WOLFSSL_METHOD* wolfSSLv23_client_method_ex(void* heap) |
wolfSSL | 13:80fb167dafdf | 7815 | { |
wolfSSL | 13:80fb167dafdf | 7816 | WOLFSSL_METHOD* method = |
wolfSSL | 13:80fb167dafdf | 7817 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:80fb167dafdf | 7818 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:80fb167dafdf | 7819 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 7820 | if (method) { |
wolfSSL | 13:80fb167dafdf | 7821 | #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512) |
wolfSSL | 13:80fb167dafdf | 7822 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7823 | InitSSL_Method(method, MakeTLSv1_3()); |
wolfSSL | 13:80fb167dafdf | 7824 | #else |
wolfSSL | 13:80fb167dafdf | 7825 | InitSSL_Method(method, MakeTLSv1_2()); |
wolfSSL | 13:80fb167dafdf | 7826 | #endif |
wolfSSL | 13:80fb167dafdf | 7827 | #else |
wolfSSL | 13:80fb167dafdf | 7828 | #ifndef NO_OLD_TLS |
wolfSSL | 13:80fb167dafdf | 7829 | InitSSL_Method(method, MakeTLSv1_1()); |
wolfSSL | 13:80fb167dafdf | 7830 | #endif |
wolfSSL | 13:80fb167dafdf | 7831 | #endif |
wolfSSL | 13:80fb167dafdf | 7832 | #ifndef NO_OLD_TLS |
wolfSSL | 13:80fb167dafdf | 7833 | method->downgrade = 1; |
wolfSSL | 13:80fb167dafdf | 7834 | #endif |
wolfSSL | 13:80fb167dafdf | 7835 | } |
wolfSSL | 13:80fb167dafdf | 7836 | return method; |
wolfSSL | 13:80fb167dafdf | 7837 | } |
wolfSSL | 13:80fb167dafdf | 7838 | |
wolfSSL | 13:80fb167dafdf | 7839 | #endif /* NO_WOLFSSL_CLIENT */ |
wolfSSL | 13:80fb167dafdf | 7840 | |
wolfSSL | 13:80fb167dafdf | 7841 | |
wolfSSL | 13:80fb167dafdf | 7842 | |
wolfSSL | 13:80fb167dafdf | 7843 | #ifndef NO_WOLFSSL_SERVER |
wolfSSL | 13:80fb167dafdf | 7844 | |
wolfSSL | 13:80fb167dafdf | 7845 | #ifndef NO_OLD_TLS |
wolfSSL | 13:80fb167dafdf | 7846 | |
wolfSSL | 13:80fb167dafdf | 7847 | WOLFSSL_METHOD* wolfTLSv1_server_method(void) |
wolfSSL | 13:80fb167dafdf | 7848 | { |
wolfSSL | 13:80fb167dafdf | 7849 | return wolfTLSv1_server_method_ex(NULL); |
wolfSSL | 13:80fb167dafdf | 7850 | } |
wolfSSL | 13:80fb167dafdf | 7851 | |
wolfSSL | 13:80fb167dafdf | 7852 | |
wolfSSL | 13:80fb167dafdf | 7853 | WOLFSSL_METHOD* wolfTLSv1_1_server_method(void) |
wolfSSL | 13:80fb167dafdf | 7854 | { |
wolfSSL | 13:80fb167dafdf | 7855 | return wolfTLSv1_1_server_method_ex(NULL); |
wolfSSL | 13:80fb167dafdf | 7856 | } |
wolfSSL | 13:80fb167dafdf | 7857 | |
wolfSSL | 13:80fb167dafdf | 7858 | WOLFSSL_METHOD* wolfTLSv1_server_method_ex(void* heap) |
wolfSSL | 13:80fb167dafdf | 7859 | { |
wolfSSL | 13:80fb167dafdf | 7860 | WOLFSSL_METHOD* method = |
wolfSSL | 13:80fb167dafdf | 7861 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:80fb167dafdf | 7862 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:80fb167dafdf | 7863 | if (method) { |
wolfSSL | 13:80fb167dafdf | 7864 | InitSSL_Method(method, MakeTLSv1()); |
wolfSSL | 13:80fb167dafdf | 7865 | method->side = WOLFSSL_SERVER_END; |
wolfSSL | 13:80fb167dafdf | 7866 | } |
wolfSSL | 13:80fb167dafdf | 7867 | return method; |
wolfSSL | 13:80fb167dafdf | 7868 | } |
wolfSSL | 13:80fb167dafdf | 7869 | |
wolfSSL | 13:80fb167dafdf | 7870 | |
wolfSSL | 13:80fb167dafdf | 7871 | WOLFSSL_METHOD* wolfTLSv1_1_server_method_ex(void* heap) |
wolfSSL | 13:80fb167dafdf | 7872 | { |
wolfSSL | 13:80fb167dafdf | 7873 | WOLFSSL_METHOD* method = |
wolfSSL | 13:80fb167dafdf | 7874 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:80fb167dafdf | 7875 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:80fb167dafdf | 7876 | if (method) { |
wolfSSL | 13:80fb167dafdf | 7877 | InitSSL_Method(method, MakeTLSv1_1()); |
wolfSSL | 13:80fb167dafdf | 7878 | method->side = WOLFSSL_SERVER_END; |
wolfSSL | 13:80fb167dafdf | 7879 | } |
wolfSSL | 13:80fb167dafdf | 7880 | return method; |
wolfSSL | 13:80fb167dafdf | 7881 | } |
wolfSSL | 13:80fb167dafdf | 7882 | #endif /* !NO_OLD_TLS */ |
wolfSSL | 13:80fb167dafdf | 7883 | |
wolfSSL | 13:80fb167dafdf | 7884 | |
wolfSSL | 13:80fb167dafdf | 7885 | WOLFSSL_METHOD* wolfTLSv1_2_server_method(void) |
wolfSSL | 13:80fb167dafdf | 7886 | { |
wolfSSL | 13:80fb167dafdf | 7887 | return wolfTLSv1_2_server_method_ex(NULL); |
wolfSSL | 13:80fb167dafdf | 7888 | } |
wolfSSL | 13:80fb167dafdf | 7889 | |
wolfSSL | 13:80fb167dafdf | 7890 | WOLFSSL_METHOD* wolfTLSv1_2_server_method_ex(void* heap) |
wolfSSL | 13:80fb167dafdf | 7891 | { |
wolfSSL | 13:80fb167dafdf | 7892 | WOLFSSL_METHOD* method = |
wolfSSL | 13:80fb167dafdf | 7893 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:80fb167dafdf | 7894 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:80fb167dafdf | 7895 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 7896 | if (method) { |
wolfSSL | 13:80fb167dafdf | 7897 | InitSSL_Method(method, MakeTLSv1_2()); |
wolfSSL | 13:80fb167dafdf | 7898 | method->side = WOLFSSL_SERVER_END; |
wolfSSL | 13:80fb167dafdf | 7899 | } |
wolfSSL | 13:80fb167dafdf | 7900 | return method; |
wolfSSL | 13:80fb167dafdf | 7901 | } |
wolfSSL | 13:80fb167dafdf | 7902 | |
wolfSSL | 13:80fb167dafdf | 7903 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7904 | /* The TLS v1.3 server method data. |
wolfSSL | 13:80fb167dafdf | 7905 | * |
wolfSSL | 13:80fb167dafdf | 7906 | * returns the method data for a TLS v1.3 server. |
wolfSSL | 13:80fb167dafdf | 7907 | */ |
wolfSSL | 13:80fb167dafdf | 7908 | WOLFSSL_METHOD* wolfTLSv1_3_server_method(void) |
wolfSSL | 13:80fb167dafdf | 7909 | { |
wolfSSL | 13:80fb167dafdf | 7910 | return wolfTLSv1_3_server_method_ex(NULL); |
wolfSSL | 13:80fb167dafdf | 7911 | } |
wolfSSL | 13:80fb167dafdf | 7912 | |
wolfSSL | 13:80fb167dafdf | 7913 | /* The TLS v1.3 server method data. |
wolfSSL | 13:80fb167dafdf | 7914 | * |
wolfSSL | 13:80fb167dafdf | 7915 | * heap The heap used for allocation. |
wolfSSL | 13:80fb167dafdf | 7916 | * returns the method data for a TLS v1.3 server. |
wolfSSL | 13:80fb167dafdf | 7917 | */ |
wolfSSL | 13:80fb167dafdf | 7918 | WOLFSSL_METHOD* wolfTLSv1_3_server_method_ex(void* heap) |
wolfSSL | 13:80fb167dafdf | 7919 | { |
wolfSSL | 13:80fb167dafdf | 7920 | WOLFSSL_METHOD* method = |
wolfSSL | 13:80fb167dafdf | 7921 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:80fb167dafdf | 7922 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:80fb167dafdf | 7923 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 7924 | if (method) { |
wolfSSL | 13:80fb167dafdf | 7925 | InitSSL_Method(method, MakeTLSv1_3()); |
wolfSSL | 13:80fb167dafdf | 7926 | method->side = WOLFSSL_SERVER_END; |
wolfSSL | 13:80fb167dafdf | 7927 | } |
wolfSSL | 13:80fb167dafdf | 7928 | return method; |
wolfSSL | 13:80fb167dafdf | 7929 | } |
wolfSSL | 13:80fb167dafdf | 7930 | #endif /* WOLFSSL_TLS13 */ |
wolfSSL | 13:80fb167dafdf | 7931 | |
wolfSSL | 13:80fb167dafdf | 7932 | WOLFSSL_METHOD* wolfSSLv23_server_method(void) |
wolfSSL | 13:80fb167dafdf | 7933 | { |
wolfSSL | 13:80fb167dafdf | 7934 | return wolfSSLv23_server_method_ex(NULL); |
wolfSSL | 13:80fb167dafdf | 7935 | } |
wolfSSL | 13:80fb167dafdf | 7936 | |
wolfSSL | 13:80fb167dafdf | 7937 | WOLFSSL_METHOD* wolfSSLv23_server_method_ex(void* heap) |
wolfSSL | 13:80fb167dafdf | 7938 | { |
wolfSSL | 13:80fb167dafdf | 7939 | WOLFSSL_METHOD* method = |
wolfSSL | 13:80fb167dafdf | 7940 | (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), |
wolfSSL | 13:80fb167dafdf | 7941 | heap, DYNAMIC_TYPE_METHOD); |
wolfSSL | 13:80fb167dafdf | 7942 | (void)heap; |
wolfSSL | 13:80fb167dafdf | 7943 | if (method) { |
wolfSSL | 13:80fb167dafdf | 7944 | #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512) |
wolfSSL | 13:80fb167dafdf | 7945 | #ifdef WOLFSSL_TLS13 |
wolfSSL | 13:80fb167dafdf | 7946 | InitSSL_Method(method, MakeTLSv1_3()); |
wolfSSL | 13:80fb167dafdf | 7947 | #else |
wolfSSL | 13:80fb167dafdf | 7948 | InitSSL_Method(method, MakeTLSv1_2()); |
wolfSSL | 13:80fb167dafdf | 7949 | #endif |
wolfSSL | 13:80fb167dafdf | 7950 | #else |
wolfSSL | 13:80fb167dafdf | 7951 | #ifndef NO_OLD_TLS |
wolfSSL | 13:80fb167dafdf | 7952 | InitSSL_Method(method, MakeTLSv1_1()); |
wolfSSL | 13:80fb167dafdf | 7953 | #else |
wolfSSL | 13:80fb167dafdf | 7954 | #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2 |
wolfSSL | 13:80fb167dafdf | 7955 | #endif |
wolfSSL | 13:80fb167dafdf | 7956 | #endif |
wolfSSL | 13:80fb167dafdf | 7957 | #ifndef NO_OLD_TLS |
wolfSSL | 13:80fb167dafdf | 7958 | method->downgrade = 1; |
wolfSSL | 13:80fb167dafdf | 7959 | #endif |
wolfSSL | 13:80fb167dafdf | 7960 | method->side = WOLFSSL_SERVER_END; |
wolfSSL | 13:80fb167dafdf | 7961 | } |
wolfSSL | 13:80fb167dafdf | 7962 | return method; |
wolfSSL | 13:80fb167dafdf | 7963 | } |
wolfSSL | 13:80fb167dafdf | 7964 | |
wolfSSL | 13:80fb167dafdf | 7965 | |
wolfSSL | 13:80fb167dafdf | 7966 | #endif /* NO_WOLFSSL_SERVER */ |
wolfSSL | 13:80fb167dafdf | 7967 | #endif /* NO_TLS */ |
wolfSSL | 13:80fb167dafdf | 7968 | #endif /* WOLFCRYPT_ONLY */ |
wolfSSL | 13:80fb167dafdf | 7969 |