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

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

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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Vanger 0:b86d15c6ba29 1 /* internal.c
Vanger 0:b86d15c6ba29 2 *
Vanger 0:b86d15c6ba29 3 * Copyright (C) 2006-2014 wolfSSL Inc.
Vanger 0:b86d15c6ba29 4 *
Vanger 0:b86d15c6ba29 5 * This file is part of CyaSSL.
Vanger 0:b86d15c6ba29 6 *
Vanger 0:b86d15c6ba29 7 * CyaSSL is free software; you can redistribute it and/or modify
Vanger 0:b86d15c6ba29 8 * it under the terms of the GNU General Public License as published by
Vanger 0:b86d15c6ba29 9 * the Free Software Foundation; either version 2 of the License, or
Vanger 0:b86d15c6ba29 10 * (at your option) any later version.
Vanger 0:b86d15c6ba29 11 *
Vanger 0:b86d15c6ba29 12 * CyaSSL is distributed in the hope that it will be useful,
Vanger 0:b86d15c6ba29 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Vanger 0:b86d15c6ba29 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Vanger 0:b86d15c6ba29 15 * GNU General Public License for more details.
Vanger 0:b86d15c6ba29 16 *
Vanger 0:b86d15c6ba29 17 * You should have received a copy of the GNU General Public License
Vanger 0:b86d15c6ba29 18 * along with this program; if not, write to the Free Software
Vanger 0:b86d15c6ba29 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Vanger 0:b86d15c6ba29 20 */
Vanger 0:b86d15c6ba29 21
Vanger 0:b86d15c6ba29 22
Vanger 0:b86d15c6ba29 23 #ifdef HAVE_CONFIG_H
Vanger 0:b86d15c6ba29 24 #include <config.h>
Vanger 0:b86d15c6ba29 25 #endif
Vanger 0:b86d15c6ba29 26
Vanger 0:b86d15c6ba29 27 #include <cyassl/ctaocrypt/settings.h>
Vanger 0:b86d15c6ba29 28
Vanger 0:b86d15c6ba29 29 #include <cyassl/internal.h>
Vanger 0:b86d15c6ba29 30 #include <cyassl/error-ssl.h>
Vanger 0:b86d15c6ba29 31 #include <cyassl/ctaocrypt/asn.h>
Vanger 0:b86d15c6ba29 32
Vanger 0:b86d15c6ba29 33 #ifdef HAVE_LIBZ
Vanger 0:b86d15c6ba29 34 #include "zlib.h"
Vanger 0:b86d15c6ba29 35 #endif
Vanger 0:b86d15c6ba29 36
Vanger 0:b86d15c6ba29 37 #ifdef HAVE_NTRU
Vanger 0:b86d15c6ba29 38 #include "ntru_crypto.h"
Vanger 0:b86d15c6ba29 39 #endif
Vanger 0:b86d15c6ba29 40
Vanger 0:b86d15c6ba29 41 #if defined(DEBUG_CYASSL) || defined(SHOW_SECRETS) || defined(CHACHA_AEAD_TEST)
Vanger 0:b86d15c6ba29 42 #ifdef FREESCALE_MQX
Vanger 0:b86d15c6ba29 43 #include <fio.h>
Vanger 0:b86d15c6ba29 44 #else
Vanger 0:b86d15c6ba29 45 #include <stdio.h>
Vanger 0:b86d15c6ba29 46 #endif
Vanger 0:b86d15c6ba29 47 #endif
Vanger 0:b86d15c6ba29 48
Vanger 0:b86d15c6ba29 49 #ifdef __sun
Vanger 0:b86d15c6ba29 50 #include <sys/filio.h>
Vanger 0:b86d15c6ba29 51 #endif
Vanger 0:b86d15c6ba29 52
Vanger 0:b86d15c6ba29 53 #ifndef TRUE
Vanger 0:b86d15c6ba29 54 #define TRUE 1
Vanger 0:b86d15c6ba29 55 #endif
Vanger 0:b86d15c6ba29 56 #ifndef FALSE
Vanger 0:b86d15c6ba29 57 #define FALSE 0
Vanger 0:b86d15c6ba29 58 #endif
Vanger 0:b86d15c6ba29 59
Vanger 0:b86d15c6ba29 60
Vanger 0:b86d15c6ba29 61 #if defined(CYASSL_CALLBACKS) && !defined(LARGE_STATIC_BUFFERS)
Vanger 0:b86d15c6ba29 62 #error \
Vanger 0:b86d15c6ba29 63 CYASSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
Vanger 0:b86d15c6ba29 64 #endif
Vanger 0:b86d15c6ba29 65
Vanger 0:b86d15c6ba29 66 #if defined(HAVE_SECURE_RENEGOTIATION) && defined(HAVE_RENEGOTIATION_INDICATION)
Vanger 0:b86d15c6ba29 67 #error Cannot use both secure-renegotiation and renegotiation-indication
Vanger 0:b86d15c6ba29 68 #endif
Vanger 0:b86d15c6ba29 69
Vanger 0:b86d15c6ba29 70 static int BuildMessage(CYASSL* ssl, byte* output, int outSz,
Vanger 0:b86d15c6ba29 71 const byte* input, int inSz, int type);
Vanger 0:b86d15c6ba29 72
Vanger 0:b86d15c6ba29 73 #ifndef NO_CYASSL_CLIENT
Vanger 0:b86d15c6ba29 74 static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input, word32*,
Vanger 0:b86d15c6ba29 75 word32);
Vanger 0:b86d15c6ba29 76 static int DoServerHello(CYASSL* ssl, const byte* input, word32*, word32);
Vanger 0:b86d15c6ba29 77 static int DoServerKeyExchange(CYASSL* ssl, const byte* input, word32*,
Vanger 0:b86d15c6ba29 78 word32);
Vanger 0:b86d15c6ba29 79 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 80 static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32*,
Vanger 0:b86d15c6ba29 81 word32);
Vanger 0:b86d15c6ba29 82 #endif
Vanger 0:b86d15c6ba29 83 #ifdef HAVE_SESSION_TICKET
Vanger 0:b86d15c6ba29 84 static int DoSessionTicket(CYASSL* ssl, const byte* input, word32*,
Vanger 0:b86d15c6ba29 85 word32);
Vanger 0:b86d15c6ba29 86 #endif
Vanger 0:b86d15c6ba29 87 #endif
Vanger 0:b86d15c6ba29 88
Vanger 0:b86d15c6ba29 89
Vanger 0:b86d15c6ba29 90 #ifndef NO_CYASSL_SERVER
Vanger 0:b86d15c6ba29 91 static int DoClientHello(CYASSL* ssl, const byte* input, word32*, word32);
Vanger 0:b86d15c6ba29 92 static int DoClientKeyExchange(CYASSL* ssl, byte* input, word32*, word32);
Vanger 0:b86d15c6ba29 93 #if !defined(NO_RSA) || defined(HAVE_ECC)
Vanger 0:b86d15c6ba29 94 static int DoCertificateVerify(CYASSL* ssl, byte*, word32*, word32);
Vanger 0:b86d15c6ba29 95 #endif
Vanger 0:b86d15c6ba29 96 #endif
Vanger 0:b86d15c6ba29 97
Vanger 0:b86d15c6ba29 98
Vanger 0:b86d15c6ba29 99 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 100 static INLINE int DtlsCheckWindow(DtlsState* state);
Vanger 0:b86d15c6ba29 101 static INLINE int DtlsUpdateWindow(DtlsState* state);
Vanger 0:b86d15c6ba29 102 #endif
Vanger 0:b86d15c6ba29 103
Vanger 0:b86d15c6ba29 104
Vanger 0:b86d15c6ba29 105 typedef enum {
Vanger 0:b86d15c6ba29 106 doProcessInit = 0,
Vanger 0:b86d15c6ba29 107 #ifndef NO_CYASSL_SERVER
Vanger 0:b86d15c6ba29 108 runProcessOldClientHello,
Vanger 0:b86d15c6ba29 109 #endif
Vanger 0:b86d15c6ba29 110 getRecordLayerHeader,
Vanger 0:b86d15c6ba29 111 getData,
Vanger 0:b86d15c6ba29 112 runProcessingOneMessage
Vanger 0:b86d15c6ba29 113 } processReply;
Vanger 0:b86d15c6ba29 114
Vanger 0:b86d15c6ba29 115 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 116 static int SSL_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
Vanger 0:b86d15c6ba29 117 int content, int verify);
Vanger 0:b86d15c6ba29 118
Vanger 0:b86d15c6ba29 119 #endif
Vanger 0:b86d15c6ba29 120
Vanger 0:b86d15c6ba29 121 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 122 static int BuildCertHashes(CYASSL* ssl, Hashes* hashes);
Vanger 0:b86d15c6ba29 123 #endif
Vanger 0:b86d15c6ba29 124
Vanger 0:b86d15c6ba29 125 static void PickHashSigAlgo(CYASSL* ssl,
Vanger 0:b86d15c6ba29 126 const byte* hashSigAlgo, word32 hashSigAlgoSz);
Vanger 0:b86d15c6ba29 127
Vanger 0:b86d15c6ba29 128 #ifndef min
Vanger 0:b86d15c6ba29 129
Vanger 0:b86d15c6ba29 130 static INLINE word32 min(word32 a, word32 b)
Vanger 0:b86d15c6ba29 131 {
Vanger 0:b86d15c6ba29 132 return a > b ? b : a;
Vanger 0:b86d15c6ba29 133 }
Vanger 0:b86d15c6ba29 134
Vanger 0:b86d15c6ba29 135 #endif /* min */
Vanger 0:b86d15c6ba29 136
Vanger 0:b86d15c6ba29 137
Vanger 0:b86d15c6ba29 138 int IsTLS(const CYASSL* ssl)
Vanger 0:b86d15c6ba29 139 {
Vanger 0:b86d15c6ba29 140 if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_MINOR)
Vanger 0:b86d15c6ba29 141 return 1;
Vanger 0:b86d15c6ba29 142
Vanger 0:b86d15c6ba29 143 return 0;
Vanger 0:b86d15c6ba29 144 }
Vanger 0:b86d15c6ba29 145
Vanger 0:b86d15c6ba29 146
Vanger 0:b86d15c6ba29 147 int IsAtLeastTLSv1_2(const CYASSL* ssl)
Vanger 0:b86d15c6ba29 148 {
Vanger 0:b86d15c6ba29 149 if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_2_MINOR)
Vanger 0:b86d15c6ba29 150 return 1;
Vanger 0:b86d15c6ba29 151 if (ssl->version.major == DTLS_MAJOR && ssl->version.minor <= DTLSv1_2_MINOR)
Vanger 0:b86d15c6ba29 152 return 1;
Vanger 0:b86d15c6ba29 153
Vanger 0:b86d15c6ba29 154 return 0;
Vanger 0:b86d15c6ba29 155 }
Vanger 0:b86d15c6ba29 156
Vanger 0:b86d15c6ba29 157
Vanger 0:b86d15c6ba29 158 #ifdef HAVE_NTRU
Vanger 0:b86d15c6ba29 159
Vanger 0:b86d15c6ba29 160 static byte GetEntropy(ENTROPY_CMD cmd, byte* out)
Vanger 0:b86d15c6ba29 161 {
Vanger 0:b86d15c6ba29 162 /* TODO: add locking? */
Vanger 0:b86d15c6ba29 163 static RNG rng;
Vanger 0:b86d15c6ba29 164
Vanger 0:b86d15c6ba29 165 if (cmd == INIT)
Vanger 0:b86d15c6ba29 166 return (InitRng(&rng) == 0) ? 1 : 0;
Vanger 0:b86d15c6ba29 167
Vanger 0:b86d15c6ba29 168 if (out == NULL)
Vanger 0:b86d15c6ba29 169 return 0;
Vanger 0:b86d15c6ba29 170
Vanger 0:b86d15c6ba29 171 if (cmd == GET_BYTE_OF_ENTROPY)
Vanger 0:b86d15c6ba29 172 return (RNG_GenerateBlock(&rng, out, 1) == 0) ? 1 : 0;
Vanger 0:b86d15c6ba29 173
Vanger 0:b86d15c6ba29 174 if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) {
Vanger 0:b86d15c6ba29 175 *out = 1;
Vanger 0:b86d15c6ba29 176 return 1;
Vanger 0:b86d15c6ba29 177 }
Vanger 0:b86d15c6ba29 178
Vanger 0:b86d15c6ba29 179 return 0;
Vanger 0:b86d15c6ba29 180 }
Vanger 0:b86d15c6ba29 181
Vanger 0:b86d15c6ba29 182 #endif /* HAVE_NTRU */
Vanger 0:b86d15c6ba29 183
Vanger 0:b86d15c6ba29 184 /* used by ssl.c too */
Vanger 0:b86d15c6ba29 185 void c32to24(word32 in, word24 out)
Vanger 0:b86d15c6ba29 186 {
Vanger 0:b86d15c6ba29 187 out[0] = (in >> 16) & 0xff;
Vanger 0:b86d15c6ba29 188 out[1] = (in >> 8) & 0xff;
Vanger 0:b86d15c6ba29 189 out[2] = in & 0xff;
Vanger 0:b86d15c6ba29 190 }
Vanger 0:b86d15c6ba29 191
Vanger 0:b86d15c6ba29 192
Vanger 0:b86d15c6ba29 193 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 194
Vanger 0:b86d15c6ba29 195 static INLINE void c32to48(word32 in, byte out[6])
Vanger 0:b86d15c6ba29 196 {
Vanger 0:b86d15c6ba29 197 out[0] = 0;
Vanger 0:b86d15c6ba29 198 out[1] = 0;
Vanger 0:b86d15c6ba29 199 out[2] = (in >> 24) & 0xff;
Vanger 0:b86d15c6ba29 200 out[3] = (in >> 16) & 0xff;
Vanger 0:b86d15c6ba29 201 out[4] = (in >> 8) & 0xff;
Vanger 0:b86d15c6ba29 202 out[5] = in & 0xff;
Vanger 0:b86d15c6ba29 203 }
Vanger 0:b86d15c6ba29 204
Vanger 0:b86d15c6ba29 205 #endif /* CYASSL_DTLS */
Vanger 0:b86d15c6ba29 206
Vanger 0:b86d15c6ba29 207
Vanger 0:b86d15c6ba29 208 /* convert 16 bit integer to opaque */
Vanger 0:b86d15c6ba29 209 static INLINE void c16toa(word16 u16, byte* c)
Vanger 0:b86d15c6ba29 210 {
Vanger 0:b86d15c6ba29 211 c[0] = (u16 >> 8) & 0xff;
Vanger 0:b86d15c6ba29 212 c[1] = u16 & 0xff;
Vanger 0:b86d15c6ba29 213 }
Vanger 0:b86d15c6ba29 214
Vanger 0:b86d15c6ba29 215
Vanger 0:b86d15c6ba29 216 #if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \
Vanger 0:b86d15c6ba29 217 || defined(HAVE_AESGCM)
Vanger 0:b86d15c6ba29 218 /* convert 32 bit integer to opaque */
Vanger 0:b86d15c6ba29 219 static INLINE void c32toa(word32 u32, byte* c)
Vanger 0:b86d15c6ba29 220 {
Vanger 0:b86d15c6ba29 221 c[0] = (u32 >> 24) & 0xff;
Vanger 0:b86d15c6ba29 222 c[1] = (u32 >> 16) & 0xff;
Vanger 0:b86d15c6ba29 223 c[2] = (u32 >> 8) & 0xff;
Vanger 0:b86d15c6ba29 224 c[3] = u32 & 0xff;
Vanger 0:b86d15c6ba29 225 }
Vanger 0:b86d15c6ba29 226 #endif
Vanger 0:b86d15c6ba29 227
Vanger 0:b86d15c6ba29 228
Vanger 0:b86d15c6ba29 229 /* convert a 24 bit integer into a 32 bit one */
Vanger 0:b86d15c6ba29 230 static INLINE void c24to32(const word24 u24, word32* u32)
Vanger 0:b86d15c6ba29 231 {
Vanger 0:b86d15c6ba29 232 *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
Vanger 0:b86d15c6ba29 233 }
Vanger 0:b86d15c6ba29 234
Vanger 0:b86d15c6ba29 235
Vanger 0:b86d15c6ba29 236 /* convert opaque to 16 bit integer */
Vanger 0:b86d15c6ba29 237 static INLINE void ato16(const byte* c, word16* u16)
Vanger 0:b86d15c6ba29 238 {
Vanger 0:b86d15c6ba29 239 *u16 = (word16) ((c[0] << 8) | (c[1]));
Vanger 0:b86d15c6ba29 240 }
Vanger 0:b86d15c6ba29 241
Vanger 0:b86d15c6ba29 242
Vanger 0:b86d15c6ba29 243 #if defined(CYASSL_DTLS) || defined(HAVE_SESSION_TICKET)
Vanger 0:b86d15c6ba29 244
Vanger 0:b86d15c6ba29 245 /* convert opaque to 32 bit integer */
Vanger 0:b86d15c6ba29 246 static INLINE void ato32(const byte* c, word32* u32)
Vanger 0:b86d15c6ba29 247 {
Vanger 0:b86d15c6ba29 248 *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
Vanger 0:b86d15c6ba29 249 }
Vanger 0:b86d15c6ba29 250
Vanger 0:b86d15c6ba29 251 #endif /* CYASSL_DTLS */
Vanger 0:b86d15c6ba29 252
Vanger 0:b86d15c6ba29 253
Vanger 0:b86d15c6ba29 254 #ifdef HAVE_LIBZ
Vanger 0:b86d15c6ba29 255
Vanger 0:b86d15c6ba29 256 /* alloc user allocs to work with zlib */
Vanger 0:b86d15c6ba29 257 static void* myAlloc(void* opaque, unsigned int item, unsigned int size)
Vanger 0:b86d15c6ba29 258 {
Vanger 0:b86d15c6ba29 259 (void)opaque;
Vanger 0:b86d15c6ba29 260 return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
Vanger 0:b86d15c6ba29 261 }
Vanger 0:b86d15c6ba29 262
Vanger 0:b86d15c6ba29 263
Vanger 0:b86d15c6ba29 264 static void myFree(void* opaque, void* memory)
Vanger 0:b86d15c6ba29 265 {
Vanger 0:b86d15c6ba29 266 (void)opaque;
Vanger 0:b86d15c6ba29 267 XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ);
Vanger 0:b86d15c6ba29 268 }
Vanger 0:b86d15c6ba29 269
Vanger 0:b86d15c6ba29 270
Vanger 0:b86d15c6ba29 271 /* init zlib comp/decomp streams, 0 on success */
Vanger 0:b86d15c6ba29 272 static int InitStreams(CYASSL* ssl)
Vanger 0:b86d15c6ba29 273 {
Vanger 0:b86d15c6ba29 274 ssl->c_stream.zalloc = (alloc_func)myAlloc;
Vanger 0:b86d15c6ba29 275 ssl->c_stream.zfree = (free_func)myFree;
Vanger 0:b86d15c6ba29 276 ssl->c_stream.opaque = (voidpf)ssl->heap;
Vanger 0:b86d15c6ba29 277
Vanger 0:b86d15c6ba29 278 if (deflateInit(&ssl->c_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
Vanger 0:b86d15c6ba29 279 return ZLIB_INIT_ERROR;
Vanger 0:b86d15c6ba29 280
Vanger 0:b86d15c6ba29 281 ssl->didStreamInit = 1;
Vanger 0:b86d15c6ba29 282
Vanger 0:b86d15c6ba29 283 ssl->d_stream.zalloc = (alloc_func)myAlloc;
Vanger 0:b86d15c6ba29 284 ssl->d_stream.zfree = (free_func)myFree;
Vanger 0:b86d15c6ba29 285 ssl->d_stream.opaque = (voidpf)ssl->heap;
Vanger 0:b86d15c6ba29 286
Vanger 0:b86d15c6ba29 287 if (inflateInit(&ssl->d_stream) != Z_OK) return ZLIB_INIT_ERROR;
Vanger 0:b86d15c6ba29 288
Vanger 0:b86d15c6ba29 289 return 0;
Vanger 0:b86d15c6ba29 290 }
Vanger 0:b86d15c6ba29 291
Vanger 0:b86d15c6ba29 292
Vanger 0:b86d15c6ba29 293 static void FreeStreams(CYASSL* ssl)
Vanger 0:b86d15c6ba29 294 {
Vanger 0:b86d15c6ba29 295 if (ssl->didStreamInit) {
Vanger 0:b86d15c6ba29 296 deflateEnd(&ssl->c_stream);
Vanger 0:b86d15c6ba29 297 inflateEnd(&ssl->d_stream);
Vanger 0:b86d15c6ba29 298 }
Vanger 0:b86d15c6ba29 299 }
Vanger 0:b86d15c6ba29 300
Vanger 0:b86d15c6ba29 301
Vanger 0:b86d15c6ba29 302 /* compress in to out, return out size or error */
Vanger 0:b86d15c6ba29 303 static int myCompress(CYASSL* ssl, byte* in, int inSz, byte* out, int outSz)
Vanger 0:b86d15c6ba29 304 {
Vanger 0:b86d15c6ba29 305 int err;
Vanger 0:b86d15c6ba29 306 int currTotal = (int)ssl->c_stream.total_out;
Vanger 0:b86d15c6ba29 307
Vanger 0:b86d15c6ba29 308 ssl->c_stream.next_in = in;
Vanger 0:b86d15c6ba29 309 ssl->c_stream.avail_in = inSz;
Vanger 0:b86d15c6ba29 310 ssl->c_stream.next_out = out;
Vanger 0:b86d15c6ba29 311 ssl->c_stream.avail_out = outSz;
Vanger 0:b86d15c6ba29 312
Vanger 0:b86d15c6ba29 313 err = deflate(&ssl->c_stream, Z_SYNC_FLUSH);
Vanger 0:b86d15c6ba29 314 if (err != Z_OK && err != Z_STREAM_END) return ZLIB_COMPRESS_ERROR;
Vanger 0:b86d15c6ba29 315
Vanger 0:b86d15c6ba29 316 return (int)ssl->c_stream.total_out - currTotal;
Vanger 0:b86d15c6ba29 317 }
Vanger 0:b86d15c6ba29 318
Vanger 0:b86d15c6ba29 319
Vanger 0:b86d15c6ba29 320 /* decompress in to out, returnn out size or error */
Vanger 0:b86d15c6ba29 321 static int myDeCompress(CYASSL* ssl, byte* in,int inSz, byte* out,int outSz)
Vanger 0:b86d15c6ba29 322 {
Vanger 0:b86d15c6ba29 323 int err;
Vanger 0:b86d15c6ba29 324 int currTotal = (int)ssl->d_stream.total_out;
Vanger 0:b86d15c6ba29 325
Vanger 0:b86d15c6ba29 326 ssl->d_stream.next_in = in;
Vanger 0:b86d15c6ba29 327 ssl->d_stream.avail_in = inSz;
Vanger 0:b86d15c6ba29 328 ssl->d_stream.next_out = out;
Vanger 0:b86d15c6ba29 329 ssl->d_stream.avail_out = outSz;
Vanger 0:b86d15c6ba29 330
Vanger 0:b86d15c6ba29 331 err = inflate(&ssl->d_stream, Z_SYNC_FLUSH);
Vanger 0:b86d15c6ba29 332 if (err != Z_OK && err != Z_STREAM_END) return ZLIB_DECOMPRESS_ERROR;
Vanger 0:b86d15c6ba29 333
Vanger 0:b86d15c6ba29 334 return (int)ssl->d_stream.total_out - currTotal;
Vanger 0:b86d15c6ba29 335 }
Vanger 0:b86d15c6ba29 336
Vanger 0:b86d15c6ba29 337 #endif /* HAVE_LIBZ */
Vanger 0:b86d15c6ba29 338
Vanger 0:b86d15c6ba29 339
Vanger 0:b86d15c6ba29 340 void InitSSL_Method(CYASSL_METHOD* method, ProtocolVersion pv)
Vanger 0:b86d15c6ba29 341 {
Vanger 0:b86d15c6ba29 342 method->version = pv;
Vanger 0:b86d15c6ba29 343 method->side = CYASSL_CLIENT_END;
Vanger 0:b86d15c6ba29 344 method->downgrade = 0;
Vanger 0:b86d15c6ba29 345 }
Vanger 0:b86d15c6ba29 346
Vanger 0:b86d15c6ba29 347
Vanger 0:b86d15c6ba29 348 /* Initialze SSL context, return 0 on success */
Vanger 0:b86d15c6ba29 349 int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
Vanger 0:b86d15c6ba29 350 {
Vanger 0:b86d15c6ba29 351 ctx->method = method;
Vanger 0:b86d15c6ba29 352 ctx->refCount = 1; /* so either CTX_free or SSL_free can release */
Vanger 0:b86d15c6ba29 353 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 354 ctx->certificate.buffer = 0;
Vanger 0:b86d15c6ba29 355 ctx->certChain.buffer = 0;
Vanger 0:b86d15c6ba29 356 ctx->privateKey.buffer = 0;
Vanger 0:b86d15c6ba29 357 ctx->serverDH_P.buffer = 0;
Vanger 0:b86d15c6ba29 358 ctx->serverDH_G.buffer = 0;
Vanger 0:b86d15c6ba29 359 #endif
Vanger 0:b86d15c6ba29 360 ctx->haveDH = 0;
Vanger 0:b86d15c6ba29 361 ctx->haveNTRU = 0; /* start off */
Vanger 0:b86d15c6ba29 362 ctx->haveECDSAsig = 0; /* start off */
Vanger 0:b86d15c6ba29 363 ctx->haveStaticECC = 0; /* start off */
Vanger 0:b86d15c6ba29 364 ctx->heap = ctx; /* defaults to self */
Vanger 0:b86d15c6ba29 365 #ifndef NO_PSK
Vanger 0:b86d15c6ba29 366 ctx->havePSK = 0;
Vanger 0:b86d15c6ba29 367 ctx->server_hint[0] = 0;
Vanger 0:b86d15c6ba29 368 ctx->client_psk_cb = 0;
Vanger 0:b86d15c6ba29 369 ctx->server_psk_cb = 0;
Vanger 0:b86d15c6ba29 370 #endif /* NO_PSK */
Vanger 0:b86d15c6ba29 371 #ifdef HAVE_ANON
Vanger 0:b86d15c6ba29 372 ctx->haveAnon = 0;
Vanger 0:b86d15c6ba29 373 #endif /* HAVE_ANON */
Vanger 0:b86d15c6ba29 374 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 375 ctx->eccTempKeySz = ECDHE_SIZE;
Vanger 0:b86d15c6ba29 376 #endif
Vanger 0:b86d15c6ba29 377
Vanger 0:b86d15c6ba29 378 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
Vanger 0:b86d15c6ba29 379 ctx->passwd_cb = 0;
Vanger 0:b86d15c6ba29 380 ctx->userdata = 0;
Vanger 0:b86d15c6ba29 381 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 382
Vanger 0:b86d15c6ba29 383 ctx->timeout = CYASSL_SESSION_TIMEOUT;
Vanger 0:b86d15c6ba29 384
Vanger 0:b86d15c6ba29 385 #ifndef CYASSL_USER_IO
Vanger 0:b86d15c6ba29 386 ctx->CBIORecv = EmbedReceive;
Vanger 0:b86d15c6ba29 387 ctx->CBIOSend = EmbedSend;
Vanger 0:b86d15c6ba29 388 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 389 if (method->version.major == DTLS_MAJOR) {
Vanger 0:b86d15c6ba29 390 ctx->CBIORecv = EmbedReceiveFrom;
Vanger 0:b86d15c6ba29 391 ctx->CBIOSend = EmbedSendTo;
Vanger 0:b86d15c6ba29 392 ctx->CBIOCookie = EmbedGenerateCookie;
Vanger 0:b86d15c6ba29 393 }
Vanger 0:b86d15c6ba29 394 #endif
Vanger 0:b86d15c6ba29 395 #else
Vanger 0:b86d15c6ba29 396 /* user will set */
Vanger 0:b86d15c6ba29 397 ctx->CBIORecv = NULL;
Vanger 0:b86d15c6ba29 398 ctx->CBIOSend = NULL;
Vanger 0:b86d15c6ba29 399 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 400 ctx->CBIOCookie = NULL;
Vanger 0:b86d15c6ba29 401 #endif
Vanger 0:b86d15c6ba29 402 #endif /* CYASSL_USER_IO */
Vanger 0:b86d15c6ba29 403 #ifdef HAVE_NETX
Vanger 0:b86d15c6ba29 404 ctx->CBIORecv = NetX_Receive;
Vanger 0:b86d15c6ba29 405 ctx->CBIOSend = NetX_Send;
Vanger 0:b86d15c6ba29 406 #endif
Vanger 0:b86d15c6ba29 407 ctx->partialWrite = 0;
Vanger 0:b86d15c6ba29 408 ctx->verifyCallback = 0;
Vanger 0:b86d15c6ba29 409
Vanger 0:b86d15c6ba29 410 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 411 ctx->cm = CyaSSL_CertManagerNew();
Vanger 0:b86d15c6ba29 412 #endif
Vanger 0:b86d15c6ba29 413 #ifdef HAVE_NTRU
Vanger 0:b86d15c6ba29 414 if (method->side == CYASSL_CLIENT_END)
Vanger 0:b86d15c6ba29 415 ctx->haveNTRU = 1; /* always on cliet side */
Vanger 0:b86d15c6ba29 416 /* server can turn on by loading key */
Vanger 0:b86d15c6ba29 417 #endif
Vanger 0:b86d15c6ba29 418 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 419 if (method->side == CYASSL_CLIENT_END) {
Vanger 0:b86d15c6ba29 420 ctx->haveECDSAsig = 1; /* always on cliet side */
Vanger 0:b86d15c6ba29 421 ctx->haveStaticECC = 1; /* server can turn on by loading key */
Vanger 0:b86d15c6ba29 422 }
Vanger 0:b86d15c6ba29 423 #endif
Vanger 0:b86d15c6ba29 424 ctx->suites.setSuites = 0; /* user hasn't set yet */
Vanger 0:b86d15c6ba29 425 /* remove DH later if server didn't set, add psk later */
Vanger 0:b86d15c6ba29 426 InitSuites(&ctx->suites, method->version, TRUE, FALSE, TRUE, ctx->haveNTRU,
Vanger 0:b86d15c6ba29 427 ctx->haveECDSAsig, ctx->haveStaticECC, method->side);
Vanger 0:b86d15c6ba29 428 ctx->verifyPeer = 0;
Vanger 0:b86d15c6ba29 429 ctx->verifyNone = 0;
Vanger 0:b86d15c6ba29 430 ctx->failNoCert = 0;
Vanger 0:b86d15c6ba29 431 ctx->sessionCacheOff = 0; /* initially on */
Vanger 0:b86d15c6ba29 432 ctx->sessionCacheFlushOff = 0; /* initially on */
Vanger 0:b86d15c6ba29 433 ctx->sendVerify = 0;
Vanger 0:b86d15c6ba29 434 ctx->quietShutdown = 0;
Vanger 0:b86d15c6ba29 435 ctx->groupMessages = 0;
Vanger 0:b86d15c6ba29 436 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 437 ctx->devId = NO_CAVIUM_DEVICE;
Vanger 0:b86d15c6ba29 438 #endif
Vanger 0:b86d15c6ba29 439 #ifdef HAVE_TLS_EXTENSIONS
Vanger 0:b86d15c6ba29 440 ctx->extensions = NULL;
Vanger 0:b86d15c6ba29 441 #endif
Vanger 0:b86d15c6ba29 442 #ifdef ATOMIC_USER
Vanger 0:b86d15c6ba29 443 ctx->MacEncryptCb = NULL;
Vanger 0:b86d15c6ba29 444 ctx->DecryptVerifyCb = NULL;
Vanger 0:b86d15c6ba29 445 #endif
Vanger 0:b86d15c6ba29 446 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 447 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 448 ctx->EccSignCb = NULL;
Vanger 0:b86d15c6ba29 449 ctx->EccVerifyCb = NULL;
Vanger 0:b86d15c6ba29 450 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 451 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 452 ctx->RsaSignCb = NULL;
Vanger 0:b86d15c6ba29 453 ctx->RsaVerifyCb = NULL;
Vanger 0:b86d15c6ba29 454 ctx->RsaEncCb = NULL;
Vanger 0:b86d15c6ba29 455 ctx->RsaDecCb = NULL;
Vanger 0:b86d15c6ba29 456 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 457 #endif /* HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 458
Vanger 0:b86d15c6ba29 459 if (InitMutex(&ctx->countMutex) < 0) {
Vanger 0:b86d15c6ba29 460 CYASSL_MSG("Mutex error on CTX init");
Vanger 0:b86d15c6ba29 461 return BAD_MUTEX_E;
Vanger 0:b86d15c6ba29 462 }
Vanger 0:b86d15c6ba29 463 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 464 if (ctx->cm == NULL) {
Vanger 0:b86d15c6ba29 465 CYASSL_MSG("Bad Cert Manager New");
Vanger 0:b86d15c6ba29 466 return BAD_CERT_MANAGER_ERROR;
Vanger 0:b86d15c6ba29 467 }
Vanger 0:b86d15c6ba29 468 #endif
Vanger 0:b86d15c6ba29 469 return 0;
Vanger 0:b86d15c6ba29 470 }
Vanger 0:b86d15c6ba29 471
Vanger 0:b86d15c6ba29 472
Vanger 0:b86d15c6ba29 473 /* In case contexts are held in array and don't want to free actual ctx */
Vanger 0:b86d15c6ba29 474 void SSL_CtxResourceFree(CYASSL_CTX* ctx)
Vanger 0:b86d15c6ba29 475 {
Vanger 0:b86d15c6ba29 476 XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
Vanger 0:b86d15c6ba29 477
Vanger 0:b86d15c6ba29 478 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 479 XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 480 XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 481 XFREE(ctx->privateKey.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
Vanger 0:b86d15c6ba29 482 XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
Vanger 0:b86d15c6ba29 483 XFREE(ctx->certChain.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
Vanger 0:b86d15c6ba29 484 CyaSSL_CertManagerFree(ctx->cm);
Vanger 0:b86d15c6ba29 485 #endif
Vanger 0:b86d15c6ba29 486 #ifdef HAVE_TLS_EXTENSIONS
Vanger 0:b86d15c6ba29 487 TLSX_FreeAll(ctx->extensions);
Vanger 0:b86d15c6ba29 488 #endif
Vanger 0:b86d15c6ba29 489 }
Vanger 0:b86d15c6ba29 490
Vanger 0:b86d15c6ba29 491
Vanger 0:b86d15c6ba29 492 void FreeSSL_Ctx(CYASSL_CTX* ctx)
Vanger 0:b86d15c6ba29 493 {
Vanger 0:b86d15c6ba29 494 int doFree = 0;
Vanger 0:b86d15c6ba29 495
Vanger 0:b86d15c6ba29 496 if (LockMutex(&ctx->countMutex) != 0) {
Vanger 0:b86d15c6ba29 497 CYASSL_MSG("Couldn't lock count mutex");
Vanger 0:b86d15c6ba29 498 return;
Vanger 0:b86d15c6ba29 499 }
Vanger 0:b86d15c6ba29 500 ctx->refCount--;
Vanger 0:b86d15c6ba29 501 if (ctx->refCount == 0)
Vanger 0:b86d15c6ba29 502 doFree = 1;
Vanger 0:b86d15c6ba29 503 UnLockMutex(&ctx->countMutex);
Vanger 0:b86d15c6ba29 504
Vanger 0:b86d15c6ba29 505 if (doFree) {
Vanger 0:b86d15c6ba29 506 CYASSL_MSG("CTX ref count down to 0, doing full free");
Vanger 0:b86d15c6ba29 507 SSL_CtxResourceFree(ctx);
Vanger 0:b86d15c6ba29 508 FreeMutex(&ctx->countMutex);
Vanger 0:b86d15c6ba29 509 XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
Vanger 0:b86d15c6ba29 510 }
Vanger 0:b86d15c6ba29 511 else {
Vanger 0:b86d15c6ba29 512 (void)ctx;
Vanger 0:b86d15c6ba29 513 CYASSL_MSG("CTX ref count not 0 yet, no free");
Vanger 0:b86d15c6ba29 514 }
Vanger 0:b86d15c6ba29 515 }
Vanger 0:b86d15c6ba29 516
Vanger 0:b86d15c6ba29 517
Vanger 0:b86d15c6ba29 518 /* Set cipher pointers to null */
Vanger 0:b86d15c6ba29 519 void InitCiphers(CYASSL* ssl)
Vanger 0:b86d15c6ba29 520 {
Vanger 0:b86d15c6ba29 521 #ifdef BUILD_ARC4
Vanger 0:b86d15c6ba29 522 ssl->encrypt.arc4 = NULL;
Vanger 0:b86d15c6ba29 523 ssl->decrypt.arc4 = NULL;
Vanger 0:b86d15c6ba29 524 #endif
Vanger 0:b86d15c6ba29 525 #ifdef BUILD_DES3
Vanger 0:b86d15c6ba29 526 ssl->encrypt.des3 = NULL;
Vanger 0:b86d15c6ba29 527 ssl->decrypt.des3 = NULL;
Vanger 0:b86d15c6ba29 528 #endif
Vanger 0:b86d15c6ba29 529 #ifdef BUILD_AES
Vanger 0:b86d15c6ba29 530 ssl->encrypt.aes = NULL;
Vanger 0:b86d15c6ba29 531 ssl->decrypt.aes = NULL;
Vanger 0:b86d15c6ba29 532 #endif
Vanger 0:b86d15c6ba29 533 #ifdef HAVE_CAMELLIA
Vanger 0:b86d15c6ba29 534 ssl->encrypt.cam = NULL;
Vanger 0:b86d15c6ba29 535 ssl->decrypt.cam = NULL;
Vanger 0:b86d15c6ba29 536 #endif
Vanger 0:b86d15c6ba29 537 #ifdef HAVE_HC128
Vanger 0:b86d15c6ba29 538 ssl->encrypt.hc128 = NULL;
Vanger 0:b86d15c6ba29 539 ssl->decrypt.hc128 = NULL;
Vanger 0:b86d15c6ba29 540 #endif
Vanger 0:b86d15c6ba29 541 #ifdef BUILD_RABBIT
Vanger 0:b86d15c6ba29 542 ssl->encrypt.rabbit = NULL;
Vanger 0:b86d15c6ba29 543 ssl->decrypt.rabbit = NULL;
Vanger 0:b86d15c6ba29 544 #endif
Vanger 0:b86d15c6ba29 545 #ifdef HAVE_CHACHA
Vanger 0:b86d15c6ba29 546 ssl->encrypt.chacha = NULL;
Vanger 0:b86d15c6ba29 547 ssl->decrypt.chacha = NULL;
Vanger 0:b86d15c6ba29 548 #endif
Vanger 0:b86d15c6ba29 549 #ifdef HAVE_POLY1305
Vanger 0:b86d15c6ba29 550 ssl->auth.poly1305 = NULL;
Vanger 0:b86d15c6ba29 551 #endif
Vanger 0:b86d15c6ba29 552 ssl->encrypt.setup = 0;
Vanger 0:b86d15c6ba29 553 ssl->decrypt.setup = 0;
Vanger 0:b86d15c6ba29 554 #ifdef HAVE_ONE_TIME_AUTH
Vanger 0:b86d15c6ba29 555 ssl->auth.setup = 0;
Vanger 0:b86d15c6ba29 556 #endif
Vanger 0:b86d15c6ba29 557 }
Vanger 0:b86d15c6ba29 558
Vanger 0:b86d15c6ba29 559
Vanger 0:b86d15c6ba29 560 /* Free ciphers */
Vanger 0:b86d15c6ba29 561 void FreeCiphers(CYASSL* ssl)
Vanger 0:b86d15c6ba29 562 {
Vanger 0:b86d15c6ba29 563 (void)ssl;
Vanger 0:b86d15c6ba29 564 #ifdef BUILD_ARC4
Vanger 0:b86d15c6ba29 565 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 566 if (ssl->devId != NO_CAVIUM_DEVICE) {
Vanger 0:b86d15c6ba29 567 Arc4FreeCavium(ssl->encrypt.arc4);
Vanger 0:b86d15c6ba29 568 Arc4FreeCavium(ssl->decrypt.arc4);
Vanger 0:b86d15c6ba29 569 }
Vanger 0:b86d15c6ba29 570 #endif
Vanger 0:b86d15c6ba29 571 XFREE(ssl->encrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
Vanger 0:b86d15c6ba29 572 XFREE(ssl->decrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
Vanger 0:b86d15c6ba29 573 #endif
Vanger 0:b86d15c6ba29 574 #ifdef BUILD_DES3
Vanger 0:b86d15c6ba29 575 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 576 if (ssl->devId != NO_CAVIUM_DEVICE) {
Vanger 0:b86d15c6ba29 577 Des3_FreeCavium(ssl->encrypt.des3);
Vanger 0:b86d15c6ba29 578 Des3_FreeCavium(ssl->decrypt.des3);
Vanger 0:b86d15c6ba29 579 }
Vanger 0:b86d15c6ba29 580 #endif
Vanger 0:b86d15c6ba29 581 XFREE(ssl->encrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
Vanger 0:b86d15c6ba29 582 XFREE(ssl->decrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
Vanger 0:b86d15c6ba29 583 #endif
Vanger 0:b86d15c6ba29 584 #ifdef BUILD_AES
Vanger 0:b86d15c6ba29 585 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 586 if (ssl->devId != NO_CAVIUM_DEVICE) {
Vanger 0:b86d15c6ba29 587 AesFreeCavium(ssl->encrypt.aes);
Vanger 0:b86d15c6ba29 588 AesFreeCavium(ssl->decrypt.aes);
Vanger 0:b86d15c6ba29 589 }
Vanger 0:b86d15c6ba29 590 #endif
Vanger 0:b86d15c6ba29 591 XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
Vanger 0:b86d15c6ba29 592 XFREE(ssl->decrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
Vanger 0:b86d15c6ba29 593 #endif
Vanger 0:b86d15c6ba29 594 #ifdef HAVE_CAMELLIA
Vanger 0:b86d15c6ba29 595 XFREE(ssl->encrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
Vanger 0:b86d15c6ba29 596 XFREE(ssl->decrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
Vanger 0:b86d15c6ba29 597 #endif
Vanger 0:b86d15c6ba29 598 #ifdef HAVE_HC128
Vanger 0:b86d15c6ba29 599 XFREE(ssl->encrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
Vanger 0:b86d15c6ba29 600 XFREE(ssl->decrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
Vanger 0:b86d15c6ba29 601 #endif
Vanger 0:b86d15c6ba29 602 #ifdef BUILD_RABBIT
Vanger 0:b86d15c6ba29 603 XFREE(ssl->encrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
Vanger 0:b86d15c6ba29 604 XFREE(ssl->decrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
Vanger 0:b86d15c6ba29 605 #endif
Vanger 0:b86d15c6ba29 606 #ifdef HAVE_CHACHA
Vanger 0:b86d15c6ba29 607 XFREE(ssl->encrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
Vanger 0:b86d15c6ba29 608 XFREE(ssl->decrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
Vanger 0:b86d15c6ba29 609 #endif
Vanger 0:b86d15c6ba29 610 #ifdef HAVE_POLY1305
Vanger 0:b86d15c6ba29 611 XFREE(ssl->auth.poly1305, ssl->heap, DYNAMIC_TYPE_CIPHER);
Vanger 0:b86d15c6ba29 612 #endif
Vanger 0:b86d15c6ba29 613 }
Vanger 0:b86d15c6ba29 614
Vanger 0:b86d15c6ba29 615
Vanger 0:b86d15c6ba29 616 void InitCipherSpecs(CipherSpecs* cs)
Vanger 0:b86d15c6ba29 617 {
Vanger 0:b86d15c6ba29 618 cs->bulk_cipher_algorithm = INVALID_BYTE;
Vanger 0:b86d15c6ba29 619 cs->cipher_type = INVALID_BYTE;
Vanger 0:b86d15c6ba29 620 cs->mac_algorithm = INVALID_BYTE;
Vanger 0:b86d15c6ba29 621 cs->kea = INVALID_BYTE;
Vanger 0:b86d15c6ba29 622 cs->sig_algo = INVALID_BYTE;
Vanger 0:b86d15c6ba29 623
Vanger 0:b86d15c6ba29 624 cs->hash_size = 0;
Vanger 0:b86d15c6ba29 625 cs->static_ecdh = 0;
Vanger 0:b86d15c6ba29 626 cs->key_size = 0;
Vanger 0:b86d15c6ba29 627 cs->iv_size = 0;
Vanger 0:b86d15c6ba29 628 cs->block_size = 0;
Vanger 0:b86d15c6ba29 629 }
Vanger 0:b86d15c6ba29 630
Vanger 0:b86d15c6ba29 631 static void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig,
Vanger 0:b86d15c6ba29 632 int haveRSAsig, int haveAnon)
Vanger 0:b86d15c6ba29 633 {
Vanger 0:b86d15c6ba29 634 int idx = 0;
Vanger 0:b86d15c6ba29 635
Vanger 0:b86d15c6ba29 636 if (haveECDSAsig) {
Vanger 0:b86d15c6ba29 637 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 638 suites->hashSigAlgo[idx++] = sha384_mac;
Vanger 0:b86d15c6ba29 639 suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
Vanger 0:b86d15c6ba29 640 #endif
Vanger 0:b86d15c6ba29 641 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 642 suites->hashSigAlgo[idx++] = sha256_mac;
Vanger 0:b86d15c6ba29 643 suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
Vanger 0:b86d15c6ba29 644 #endif
Vanger 0:b86d15c6ba29 645 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 646 suites->hashSigAlgo[idx++] = sha_mac;
Vanger 0:b86d15c6ba29 647 suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
Vanger 0:b86d15c6ba29 648 #endif
Vanger 0:b86d15c6ba29 649 }
Vanger 0:b86d15c6ba29 650
Vanger 0:b86d15c6ba29 651 if (haveRSAsig) {
Vanger 0:b86d15c6ba29 652 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 653 suites->hashSigAlgo[idx++] = sha384_mac;
Vanger 0:b86d15c6ba29 654 suites->hashSigAlgo[idx++] = rsa_sa_algo;
Vanger 0:b86d15c6ba29 655 #endif
Vanger 0:b86d15c6ba29 656 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 657 suites->hashSigAlgo[idx++] = sha256_mac;
Vanger 0:b86d15c6ba29 658 suites->hashSigAlgo[idx++] = rsa_sa_algo;
Vanger 0:b86d15c6ba29 659 #endif
Vanger 0:b86d15c6ba29 660 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 661 suites->hashSigAlgo[idx++] = sha_mac;
Vanger 0:b86d15c6ba29 662 suites->hashSigAlgo[idx++] = rsa_sa_algo;
Vanger 0:b86d15c6ba29 663 #endif
Vanger 0:b86d15c6ba29 664 }
Vanger 0:b86d15c6ba29 665
Vanger 0:b86d15c6ba29 666 if (haveAnon) {
Vanger 0:b86d15c6ba29 667 #ifdef HAVE_ANON
Vanger 0:b86d15c6ba29 668 suites->hashSigAlgo[idx++] = sha_mac;
Vanger 0:b86d15c6ba29 669 suites->hashSigAlgo[idx++] = anonymous_sa_algo;
Vanger 0:b86d15c6ba29 670 #endif
Vanger 0:b86d15c6ba29 671 }
Vanger 0:b86d15c6ba29 672
Vanger 0:b86d15c6ba29 673 suites->hashSigAlgoSz = (word16)idx;
Vanger 0:b86d15c6ba29 674 }
Vanger 0:b86d15c6ba29 675
Vanger 0:b86d15c6ba29 676 void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK,
Vanger 0:b86d15c6ba29 677 byte haveDH, byte haveNTRU, byte haveECDSAsig,
Vanger 0:b86d15c6ba29 678 byte haveStaticECC, int side)
Vanger 0:b86d15c6ba29 679 {
Vanger 0:b86d15c6ba29 680 word16 idx = 0;
Vanger 0:b86d15c6ba29 681 int tls = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR;
Vanger 0:b86d15c6ba29 682 int tls1_2 = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_2_MINOR;
Vanger 0:b86d15c6ba29 683 int haveRSAsig = 1;
Vanger 0:b86d15c6ba29 684
Vanger 0:b86d15c6ba29 685 (void)tls; /* shut up compiler */
Vanger 0:b86d15c6ba29 686 (void)tls1_2;
Vanger 0:b86d15c6ba29 687 (void)haveDH;
Vanger 0:b86d15c6ba29 688 (void)havePSK;
Vanger 0:b86d15c6ba29 689 (void)haveNTRU;
Vanger 0:b86d15c6ba29 690 (void)haveStaticECC;
Vanger 0:b86d15c6ba29 691
Vanger 0:b86d15c6ba29 692 if (suites == NULL) {
Vanger 0:b86d15c6ba29 693 CYASSL_MSG("InitSuites pointer error");
Vanger 0:b86d15c6ba29 694 return;
Vanger 0:b86d15c6ba29 695 }
Vanger 0:b86d15c6ba29 696
Vanger 0:b86d15c6ba29 697 if (suites->setSuites)
Vanger 0:b86d15c6ba29 698 return; /* trust user settings, don't override */
Vanger 0:b86d15c6ba29 699
Vanger 0:b86d15c6ba29 700 if (side == CYASSL_SERVER_END && haveStaticECC) {
Vanger 0:b86d15c6ba29 701 haveRSA = 0; /* can't do RSA with ECDSA key */
Vanger 0:b86d15c6ba29 702 (void)haveRSA; /* some builds won't read */
Vanger 0:b86d15c6ba29 703 }
Vanger 0:b86d15c6ba29 704
Vanger 0:b86d15c6ba29 705 if (side == CYASSL_SERVER_END && haveECDSAsig) {
Vanger 0:b86d15c6ba29 706 haveRSAsig = 0; /* can't have RSA sig if signed by ECDSA */
Vanger 0:b86d15c6ba29 707 (void)haveRSAsig; /* non ecc builds won't read */
Vanger 0:b86d15c6ba29 708 }
Vanger 0:b86d15c6ba29 709
Vanger 0:b86d15c6ba29 710 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 711 if (pv.major == DTLS_MAJOR) {
Vanger 0:b86d15c6ba29 712 tls = 1;
Vanger 0:b86d15c6ba29 713 tls1_2 = pv.minor <= DTLSv1_2_MINOR;
Vanger 0:b86d15c6ba29 714 }
Vanger 0:b86d15c6ba29 715 #endif
Vanger 0:b86d15c6ba29 716
Vanger 0:b86d15c6ba29 717 #ifdef HAVE_RENEGOTIATION_INDICATION
Vanger 0:b86d15c6ba29 718 if (side == CYASSL_CLIENT_END) {
Vanger 0:b86d15c6ba29 719 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 720 suites->suites[idx++] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV;
Vanger 0:b86d15c6ba29 721 }
Vanger 0:b86d15c6ba29 722 #endif
Vanger 0:b86d15c6ba29 723
Vanger 0:b86d15c6ba29 724 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 725 if (tls && haveNTRU && haveRSA) {
Vanger 0:b86d15c6ba29 726 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 727 suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_256_CBC_SHA;
Vanger 0:b86d15c6ba29 728 }
Vanger 0:b86d15c6ba29 729 #endif
Vanger 0:b86d15c6ba29 730
Vanger 0:b86d15c6ba29 731 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 732 if (tls && haveNTRU && haveRSA) {
Vanger 0:b86d15c6ba29 733 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 734 suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_128_CBC_SHA;
Vanger 0:b86d15c6ba29 735 }
Vanger 0:b86d15c6ba29 736 #endif
Vanger 0:b86d15c6ba29 737
Vanger 0:b86d15c6ba29 738 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 739 if (tls && haveNTRU && haveRSA) {
Vanger 0:b86d15c6ba29 740 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 741 suites->suites[idx++] = TLS_NTRU_RSA_WITH_RC4_128_SHA;
Vanger 0:b86d15c6ba29 742 }
Vanger 0:b86d15c6ba29 743 #endif
Vanger 0:b86d15c6ba29 744
Vanger 0:b86d15c6ba29 745 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 746 if (tls && haveNTRU && haveRSA) {
Vanger 0:b86d15c6ba29 747 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 748 suites->suites[idx++] = TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA;
Vanger 0:b86d15c6ba29 749 }
Vanger 0:b86d15c6ba29 750 #endif
Vanger 0:b86d15c6ba29 751
Vanger 0:b86d15c6ba29 752 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 753 if (tls1_2 && haveRSAsig) {
Vanger 0:b86d15c6ba29 754 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 755 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256;
Vanger 0:b86d15c6ba29 756 }
Vanger 0:b86d15c6ba29 757 #endif
Vanger 0:b86d15c6ba29 758
Vanger 0:b86d15c6ba29 759 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 760 if (tls1_2 && haveECDSAsig) {
Vanger 0:b86d15c6ba29 761 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 762 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
Vanger 0:b86d15c6ba29 763 }
Vanger 0:b86d15c6ba29 764 #endif
Vanger 0:b86d15c6ba29 765
Vanger 0:b86d15c6ba29 766 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 767 if (tls1_2 && haveRSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 768 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 769 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256;
Vanger 0:b86d15c6ba29 770 }
Vanger 0:b86d15c6ba29 771 #endif
Vanger 0:b86d15c6ba29 772
Vanger 0:b86d15c6ba29 773 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 774 if (tls1_2 && haveECDSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 775 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 776 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256;
Vanger 0:b86d15c6ba29 777 }
Vanger 0:b86d15c6ba29 778 #endif
Vanger 0:b86d15c6ba29 779
Vanger 0:b86d15c6ba29 780 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 781 if (tls1_2 && haveRSAsig) {
Vanger 0:b86d15c6ba29 782 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 783 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384;
Vanger 0:b86d15c6ba29 784 }
Vanger 0:b86d15c6ba29 785 #endif
Vanger 0:b86d15c6ba29 786
Vanger 0:b86d15c6ba29 787 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 788 if (tls1_2 && haveECDSAsig) {
Vanger 0:b86d15c6ba29 789 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 790 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384;
Vanger 0:b86d15c6ba29 791 }
Vanger 0:b86d15c6ba29 792 #endif
Vanger 0:b86d15c6ba29 793
Vanger 0:b86d15c6ba29 794 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 795 if (tls1_2 && haveRSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 796 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 797 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384;
Vanger 0:b86d15c6ba29 798 }
Vanger 0:b86d15c6ba29 799 #endif
Vanger 0:b86d15c6ba29 800
Vanger 0:b86d15c6ba29 801 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 802 if (tls1_2 && haveECDSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 803 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 804 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384;
Vanger 0:b86d15c6ba29 805 }
Vanger 0:b86d15c6ba29 806 #endif
Vanger 0:b86d15c6ba29 807
Vanger 0:b86d15c6ba29 808 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 809 if (tls1_2 && haveECDSAsig) {
Vanger 0:b86d15c6ba29 810 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 811 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
Vanger 0:b86d15c6ba29 812 }
Vanger 0:b86d15c6ba29 813 #endif
Vanger 0:b86d15c6ba29 814
Vanger 0:b86d15c6ba29 815 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 816 if (tls && haveECDSAsig) {
Vanger 0:b86d15c6ba29 817 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 818 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA;
Vanger 0:b86d15c6ba29 819 }
Vanger 0:b86d15c6ba29 820 #endif
Vanger 0:b86d15c6ba29 821
Vanger 0:b86d15c6ba29 822 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 823 if (tls1_2 && haveECDSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 824 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 825 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
Vanger 0:b86d15c6ba29 826 }
Vanger 0:b86d15c6ba29 827 #endif
Vanger 0:b86d15c6ba29 828
Vanger 0:b86d15c6ba29 829 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 830 if (tls && haveECDSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 831 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 832 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA;
Vanger 0:b86d15c6ba29 833 }
Vanger 0:b86d15c6ba29 834 #endif
Vanger 0:b86d15c6ba29 835
Vanger 0:b86d15c6ba29 836 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 837 if (tls1_2 && haveECDSAsig) {
Vanger 0:b86d15c6ba29 838 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 839 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
Vanger 0:b86d15c6ba29 840 }
Vanger 0:b86d15c6ba29 841 #endif
Vanger 0:b86d15c6ba29 842
Vanger 0:b86d15c6ba29 843 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 844 if (tls && haveECDSAsig) {
Vanger 0:b86d15c6ba29 845 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 846 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA;
Vanger 0:b86d15c6ba29 847 }
Vanger 0:b86d15c6ba29 848 #endif
Vanger 0:b86d15c6ba29 849
Vanger 0:b86d15c6ba29 850 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 851 if (tls1_2 && haveECDSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 852 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 853 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
Vanger 0:b86d15c6ba29 854 }
Vanger 0:b86d15c6ba29 855 #endif
Vanger 0:b86d15c6ba29 856
Vanger 0:b86d15c6ba29 857 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 858 if (tls && haveECDSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 859 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 860 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA;
Vanger 0:b86d15c6ba29 861 }
Vanger 0:b86d15c6ba29 862 #endif
Vanger 0:b86d15c6ba29 863
Vanger 0:b86d15c6ba29 864 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 865 if (tls && haveECDSAsig) {
Vanger 0:b86d15c6ba29 866 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 867 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA;
Vanger 0:b86d15c6ba29 868 }
Vanger 0:b86d15c6ba29 869 #endif
Vanger 0:b86d15c6ba29 870
Vanger 0:b86d15c6ba29 871 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 872 if (tls && haveECDSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 873 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 874 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA;
Vanger 0:b86d15c6ba29 875 }
Vanger 0:b86d15c6ba29 876 #endif
Vanger 0:b86d15c6ba29 877
Vanger 0:b86d15c6ba29 878 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 879 if (tls && haveECDSAsig) {
Vanger 0:b86d15c6ba29 880 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 881 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA;
Vanger 0:b86d15c6ba29 882 }
Vanger 0:b86d15c6ba29 883 #endif
Vanger 0:b86d15c6ba29 884
Vanger 0:b86d15c6ba29 885 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 886 if (tls && haveECDSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 887 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 888 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA;
Vanger 0:b86d15c6ba29 889 }
Vanger 0:b86d15c6ba29 890 #endif
Vanger 0:b86d15c6ba29 891
Vanger 0:b86d15c6ba29 892 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 893 if (tls1_2 && haveRSA) {
Vanger 0:b86d15c6ba29 894 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 895 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
Vanger 0:b86d15c6ba29 896 }
Vanger 0:b86d15c6ba29 897 #endif
Vanger 0:b86d15c6ba29 898
Vanger 0:b86d15c6ba29 899 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 900 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 901 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 902 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
Vanger 0:b86d15c6ba29 903 }
Vanger 0:b86d15c6ba29 904 #endif
Vanger 0:b86d15c6ba29 905
Vanger 0:b86d15c6ba29 906 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 907 if (tls1_2 && haveRSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 908 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 909 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
Vanger 0:b86d15c6ba29 910 }
Vanger 0:b86d15c6ba29 911 #endif
Vanger 0:b86d15c6ba29 912
Vanger 0:b86d15c6ba29 913 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 914 if (tls && haveRSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 915 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 916 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA;
Vanger 0:b86d15c6ba29 917 }
Vanger 0:b86d15c6ba29 918 #endif
Vanger 0:b86d15c6ba29 919
Vanger 0:b86d15c6ba29 920 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 921 if (tls1_2 && haveRSA) {
Vanger 0:b86d15c6ba29 922 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 923 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
Vanger 0:b86d15c6ba29 924 }
Vanger 0:b86d15c6ba29 925 #endif
Vanger 0:b86d15c6ba29 926
Vanger 0:b86d15c6ba29 927 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 928 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 929 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 930 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA;
Vanger 0:b86d15c6ba29 931 }
Vanger 0:b86d15c6ba29 932 #endif
Vanger 0:b86d15c6ba29 933
Vanger 0:b86d15c6ba29 934 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 935 if (tls1_2 && haveRSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 936 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 937 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
Vanger 0:b86d15c6ba29 938 }
Vanger 0:b86d15c6ba29 939 #endif
Vanger 0:b86d15c6ba29 940
Vanger 0:b86d15c6ba29 941 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 942 if (tls && haveRSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 943 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 944 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA;
Vanger 0:b86d15c6ba29 945 }
Vanger 0:b86d15c6ba29 946 #endif
Vanger 0:b86d15c6ba29 947
Vanger 0:b86d15c6ba29 948 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 949 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 950 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 951 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_RC4_128_SHA;
Vanger 0:b86d15c6ba29 952 }
Vanger 0:b86d15c6ba29 953 #endif
Vanger 0:b86d15c6ba29 954
Vanger 0:b86d15c6ba29 955 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 956 if (tls && haveRSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 957 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 958 suites->suites[idx++] = TLS_ECDH_RSA_WITH_RC4_128_SHA;
Vanger 0:b86d15c6ba29 959 }
Vanger 0:b86d15c6ba29 960 #endif
Vanger 0:b86d15c6ba29 961
Vanger 0:b86d15c6ba29 962 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 963 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 964 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 965 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA;
Vanger 0:b86d15c6ba29 966 }
Vanger 0:b86d15c6ba29 967 #endif
Vanger 0:b86d15c6ba29 968
Vanger 0:b86d15c6ba29 969 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
Vanger 0:b86d15c6ba29 970 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 971 suites->suites[idx++] = CHACHA_BYTE;
Vanger 0:b86d15c6ba29 972 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
Vanger 0:b86d15c6ba29 973 }
Vanger 0:b86d15c6ba29 974 #endif
Vanger 0:b86d15c6ba29 975
Vanger 0:b86d15c6ba29 976 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
Vanger 0:b86d15c6ba29 977 if (tls1_2 && haveECDSAsig) {
Vanger 0:b86d15c6ba29 978 suites->suites[idx++] = CHACHA_BYTE;
Vanger 0:b86d15c6ba29 979 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256;
Vanger 0:b86d15c6ba29 980 }
Vanger 0:b86d15c6ba29 981 #endif
Vanger 0:b86d15c6ba29 982
Vanger 0:b86d15c6ba29 983 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
Vanger 0:b86d15c6ba29 984 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 985 suites->suites[idx++] = CHACHA_BYTE;
Vanger 0:b86d15c6ba29 986 suites->suites[idx++] = TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
Vanger 0:b86d15c6ba29 987 }
Vanger 0:b86d15c6ba29 988 #endif
Vanger 0:b86d15c6ba29 989
Vanger 0:b86d15c6ba29 990 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 991 if (tls && haveRSAsig && haveStaticECC) {
Vanger 0:b86d15c6ba29 992 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 993 suites->suites[idx++] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA;
Vanger 0:b86d15c6ba29 994 }
Vanger 0:b86d15c6ba29 995 #endif
Vanger 0:b86d15c6ba29 996
Vanger 0:b86d15c6ba29 997 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 998 if (tls1_2 && haveDH && haveRSA) {
Vanger 0:b86d15c6ba29 999 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1000 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
Vanger 0:b86d15c6ba29 1001 }
Vanger 0:b86d15c6ba29 1002 #endif
Vanger 0:b86d15c6ba29 1003
Vanger 0:b86d15c6ba29 1004 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
Vanger 0:b86d15c6ba29 1005 if (tls1_2 && haveECDSAsig) {
Vanger 0:b86d15c6ba29 1006 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 1007 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
Vanger 0:b86d15c6ba29 1008 }
Vanger 0:b86d15c6ba29 1009 #endif
Vanger 0:b86d15c6ba29 1010
Vanger 0:b86d15c6ba29 1011 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
Vanger 0:b86d15c6ba29 1012 if (tls1_2 && haveECDSAsig) {
Vanger 0:b86d15c6ba29 1013 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 1014 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8;
Vanger 0:b86d15c6ba29 1015 }
Vanger 0:b86d15c6ba29 1016 #endif
Vanger 0:b86d15c6ba29 1017
Vanger 0:b86d15c6ba29 1018 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
Vanger 0:b86d15c6ba29 1019 if (tls1_2 && haveRSA) {
Vanger 0:b86d15c6ba29 1020 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 1021 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CCM_8;
Vanger 0:b86d15c6ba29 1022 }
Vanger 0:b86d15c6ba29 1023 #endif
Vanger 0:b86d15c6ba29 1024
Vanger 0:b86d15c6ba29 1025 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
Vanger 0:b86d15c6ba29 1026 if (tls1_2 && haveRSA) {
Vanger 0:b86d15c6ba29 1027 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 1028 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CCM_8;
Vanger 0:b86d15c6ba29 1029 }
Vanger 0:b86d15c6ba29 1030 #endif
Vanger 0:b86d15c6ba29 1031
Vanger 0:b86d15c6ba29 1032 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Vanger 0:b86d15c6ba29 1033 if (tls1_2 && haveDH && haveRSA) {
Vanger 0:b86d15c6ba29 1034 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1035 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
Vanger 0:b86d15c6ba29 1036 }
Vanger 0:b86d15c6ba29 1037 #endif
Vanger 0:b86d15c6ba29 1038
Vanger 0:b86d15c6ba29 1039 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 1040 if (tls1_2 && haveDH && haveRSA) {
Vanger 0:b86d15c6ba29 1041 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1042 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
Vanger 0:b86d15c6ba29 1043 }
Vanger 0:b86d15c6ba29 1044 #endif
Vanger 0:b86d15c6ba29 1045
Vanger 0:b86d15c6ba29 1046 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 1047 if (tls1_2 && haveDH && haveRSA) {
Vanger 0:b86d15c6ba29 1048 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1049 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
Vanger 0:b86d15c6ba29 1050 }
Vanger 0:b86d15c6ba29 1051 #endif
Vanger 0:b86d15c6ba29 1052
Vanger 0:b86d15c6ba29 1053 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 1054 if (tls && haveDH && haveRSA) {
Vanger 0:b86d15c6ba29 1055 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1056 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
Vanger 0:b86d15c6ba29 1057 }
Vanger 0:b86d15c6ba29 1058 #endif
Vanger 0:b86d15c6ba29 1059
Vanger 0:b86d15c6ba29 1060 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 1061 if (tls && haveDH && haveRSA) {
Vanger 0:b86d15c6ba29 1062 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1063 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
Vanger 0:b86d15c6ba29 1064 }
Vanger 0:b86d15c6ba29 1065 #endif
Vanger 0:b86d15c6ba29 1066
Vanger 0:b86d15c6ba29 1067 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 1068 if (tls1_2 && haveRSA) {
Vanger 0:b86d15c6ba29 1069 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1070 suites->suites[idx++] = TLS_RSA_WITH_AES_256_GCM_SHA384;
Vanger 0:b86d15c6ba29 1071 }
Vanger 0:b86d15c6ba29 1072 #endif
Vanger 0:b86d15c6ba29 1073
Vanger 0:b86d15c6ba29 1074 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
Vanger 0:b86d15c6ba29 1075 if (tls1_2 && haveRSA) {
Vanger 0:b86d15c6ba29 1076 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1077 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
Vanger 0:b86d15c6ba29 1078 }
Vanger 0:b86d15c6ba29 1079 #endif
Vanger 0:b86d15c6ba29 1080
Vanger 0:b86d15c6ba29 1081 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 1082 if (tls1_2 && haveRSA) {
Vanger 0:b86d15c6ba29 1083 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1084 suites->suites[idx++] = TLS_RSA_WITH_AES_128_GCM_SHA256;
Vanger 0:b86d15c6ba29 1085 }
Vanger 0:b86d15c6ba29 1086 #endif
Vanger 0:b86d15c6ba29 1087
Vanger 0:b86d15c6ba29 1088 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 1089 if (tls1_2 && haveRSA) {
Vanger 0:b86d15c6ba29 1090 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1091 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
Vanger 0:b86d15c6ba29 1092 }
Vanger 0:b86d15c6ba29 1093 #endif
Vanger 0:b86d15c6ba29 1094
Vanger 0:b86d15c6ba29 1095 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 1096 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 1097 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1098 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA;
Vanger 0:b86d15c6ba29 1099 }
Vanger 0:b86d15c6ba29 1100 #endif
Vanger 0:b86d15c6ba29 1101
Vanger 0:b86d15c6ba29 1102 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 1103 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 1104 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1105 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA;
Vanger 0:b86d15c6ba29 1106 }
Vanger 0:b86d15c6ba29 1107 #endif
Vanger 0:b86d15c6ba29 1108
Vanger 0:b86d15c6ba29 1109 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
Vanger 0:b86d15c6ba29 1110 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 1111 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1112 suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA;
Vanger 0:b86d15c6ba29 1113 }
Vanger 0:b86d15c6ba29 1114 #endif
Vanger 0:b86d15c6ba29 1115
Vanger 0:b86d15c6ba29 1116 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
Vanger 0:b86d15c6ba29 1117 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 1118 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1119 suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA256;
Vanger 0:b86d15c6ba29 1120 }
Vanger 0:b86d15c6ba29 1121 #endif
Vanger 0:b86d15c6ba29 1122
Vanger 0:b86d15c6ba29 1123 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 1124 if (tls1_2 && haveDH && havePSK) {
Vanger 0:b86d15c6ba29 1125 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1126 suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_GCM_SHA384;
Vanger 0:b86d15c6ba29 1127 }
Vanger 0:b86d15c6ba29 1128 #endif
Vanger 0:b86d15c6ba29 1129
Vanger 0:b86d15c6ba29 1130 #ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 1131 if (tls1_2 && havePSK) {
Vanger 0:b86d15c6ba29 1132 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1133 suites->suites[idx++] = TLS_PSK_WITH_AES_256_GCM_SHA384;
Vanger 0:b86d15c6ba29 1134 }
Vanger 0:b86d15c6ba29 1135 #endif
Vanger 0:b86d15c6ba29 1136
Vanger 0:b86d15c6ba29 1137 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 1138 if (tls && havePSK) {
Vanger 0:b86d15c6ba29 1139 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1140 suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA;
Vanger 0:b86d15c6ba29 1141 }
Vanger 0:b86d15c6ba29 1142 #endif
Vanger 0:b86d15c6ba29 1143
Vanger 0:b86d15c6ba29 1144 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 1145 if (tls && haveDH && havePSK) {
Vanger 0:b86d15c6ba29 1146 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1147 suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA384;
Vanger 0:b86d15c6ba29 1148 }
Vanger 0:b86d15c6ba29 1149 #endif
Vanger 0:b86d15c6ba29 1150
Vanger 0:b86d15c6ba29 1151 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 1152 if (tls && havePSK) {
Vanger 0:b86d15c6ba29 1153 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1154 suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA384;
Vanger 0:b86d15c6ba29 1155 }
Vanger 0:b86d15c6ba29 1156 #endif
Vanger 0:b86d15c6ba29 1157
Vanger 0:b86d15c6ba29 1158 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 1159 if (tls1_2 && haveDH && havePSK) {
Vanger 0:b86d15c6ba29 1160 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1161 suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_GCM_SHA256;
Vanger 0:b86d15c6ba29 1162 }
Vanger 0:b86d15c6ba29 1163 #endif
Vanger 0:b86d15c6ba29 1164
Vanger 0:b86d15c6ba29 1165 #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 1166 if (tls1_2 && havePSK) {
Vanger 0:b86d15c6ba29 1167 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1168 suites->suites[idx++] = TLS_PSK_WITH_AES_128_GCM_SHA256;
Vanger 0:b86d15c6ba29 1169 }
Vanger 0:b86d15c6ba29 1170 #endif
Vanger 0:b86d15c6ba29 1171
Vanger 0:b86d15c6ba29 1172 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 1173 if (tls && haveDH && havePSK) {
Vanger 0:b86d15c6ba29 1174 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1175 suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA256;
Vanger 0:b86d15c6ba29 1176 }
Vanger 0:b86d15c6ba29 1177 #endif
Vanger 0:b86d15c6ba29 1178
Vanger 0:b86d15c6ba29 1179 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 1180 if (tls && havePSK) {
Vanger 0:b86d15c6ba29 1181 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1182 suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA256;
Vanger 0:b86d15c6ba29 1183 }
Vanger 0:b86d15c6ba29 1184 #endif
Vanger 0:b86d15c6ba29 1185
Vanger 0:b86d15c6ba29 1186 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 1187 if (tls && havePSK) {
Vanger 0:b86d15c6ba29 1188 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1189 suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA;
Vanger 0:b86d15c6ba29 1190 }
Vanger 0:b86d15c6ba29 1191 #endif
Vanger 0:b86d15c6ba29 1192
Vanger 0:b86d15c6ba29 1193 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
Vanger 0:b86d15c6ba29 1194 if (tls && haveDH && havePSK) {
Vanger 0:b86d15c6ba29 1195 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 1196 suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CCM;
Vanger 0:b86d15c6ba29 1197 }
Vanger 0:b86d15c6ba29 1198 #endif
Vanger 0:b86d15c6ba29 1199
Vanger 0:b86d15c6ba29 1200 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
Vanger 0:b86d15c6ba29 1201 if (tls && haveDH && havePSK) {
Vanger 0:b86d15c6ba29 1202 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 1203 suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CCM;
Vanger 0:b86d15c6ba29 1204 }
Vanger 0:b86d15c6ba29 1205 #endif
Vanger 0:b86d15c6ba29 1206
Vanger 0:b86d15c6ba29 1207 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
Vanger 0:b86d15c6ba29 1208 if (tls && havePSK) {
Vanger 0:b86d15c6ba29 1209 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 1210 suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM;
Vanger 0:b86d15c6ba29 1211 }
Vanger 0:b86d15c6ba29 1212 #endif
Vanger 0:b86d15c6ba29 1213
Vanger 0:b86d15c6ba29 1214 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
Vanger 0:b86d15c6ba29 1215 if (tls && havePSK) {
Vanger 0:b86d15c6ba29 1216 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 1217 suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM;
Vanger 0:b86d15c6ba29 1218 }
Vanger 0:b86d15c6ba29 1219 #endif
Vanger 0:b86d15c6ba29 1220
Vanger 0:b86d15c6ba29 1221 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
Vanger 0:b86d15c6ba29 1222 if (tls && havePSK) {
Vanger 0:b86d15c6ba29 1223 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 1224 suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM_8;
Vanger 0:b86d15c6ba29 1225 }
Vanger 0:b86d15c6ba29 1226 #endif
Vanger 0:b86d15c6ba29 1227
Vanger 0:b86d15c6ba29 1228 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
Vanger 0:b86d15c6ba29 1229 if (tls && havePSK) {
Vanger 0:b86d15c6ba29 1230 suites->suites[idx++] = ECC_BYTE;
Vanger 0:b86d15c6ba29 1231 suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM_8;
Vanger 0:b86d15c6ba29 1232 }
Vanger 0:b86d15c6ba29 1233 #endif
Vanger 0:b86d15c6ba29 1234
Vanger 0:b86d15c6ba29 1235 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
Vanger 0:b86d15c6ba29 1236 if (tls && haveDH && havePSK) {
Vanger 0:b86d15c6ba29 1237 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1238 suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA384;
Vanger 0:b86d15c6ba29 1239 }
Vanger 0:b86d15c6ba29 1240 #endif
Vanger 0:b86d15c6ba29 1241
Vanger 0:b86d15c6ba29 1242 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
Vanger 0:b86d15c6ba29 1243 if (tls && havePSK) {
Vanger 0:b86d15c6ba29 1244 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1245 suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA384;
Vanger 0:b86d15c6ba29 1246 }
Vanger 0:b86d15c6ba29 1247 #endif
Vanger 0:b86d15c6ba29 1248
Vanger 0:b86d15c6ba29 1249 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
Vanger 0:b86d15c6ba29 1250 if (tls && haveDH && havePSK) {
Vanger 0:b86d15c6ba29 1251 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1252 suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA256;
Vanger 0:b86d15c6ba29 1253 }
Vanger 0:b86d15c6ba29 1254 #endif
Vanger 0:b86d15c6ba29 1255
Vanger 0:b86d15c6ba29 1256 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
Vanger 0:b86d15c6ba29 1257 if (tls && havePSK) {
Vanger 0:b86d15c6ba29 1258 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1259 suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA256;
Vanger 0:b86d15c6ba29 1260 }
Vanger 0:b86d15c6ba29 1261 #endif
Vanger 0:b86d15c6ba29 1262
Vanger 0:b86d15c6ba29 1263 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
Vanger 0:b86d15c6ba29 1264 if (tls && havePSK) {
Vanger 0:b86d15c6ba29 1265 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1266 suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA;
Vanger 0:b86d15c6ba29 1267 }
Vanger 0:b86d15c6ba29 1268 #endif
Vanger 0:b86d15c6ba29 1269
Vanger 0:b86d15c6ba29 1270 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 1271 if (haveRSA ) {
Vanger 0:b86d15c6ba29 1272 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1273 suites->suites[idx++] = SSL_RSA_WITH_RC4_128_SHA;
Vanger 0:b86d15c6ba29 1274 }
Vanger 0:b86d15c6ba29 1275 #endif
Vanger 0:b86d15c6ba29 1276
Vanger 0:b86d15c6ba29 1277 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
Vanger 0:b86d15c6ba29 1278 if (haveRSA ) {
Vanger 0:b86d15c6ba29 1279 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1280 suites->suites[idx++] = SSL_RSA_WITH_RC4_128_MD5;
Vanger 0:b86d15c6ba29 1281 }
Vanger 0:b86d15c6ba29 1282 #endif
Vanger 0:b86d15c6ba29 1283
Vanger 0:b86d15c6ba29 1284 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 1285 if (haveRSA ) {
Vanger 0:b86d15c6ba29 1286 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1287 suites->suites[idx++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
Vanger 0:b86d15c6ba29 1288 }
Vanger 0:b86d15c6ba29 1289 #endif
Vanger 0:b86d15c6ba29 1290
Vanger 0:b86d15c6ba29 1291 #ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
Vanger 0:b86d15c6ba29 1292 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 1293 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1294 suites->suites[idx++] = TLS_RSA_WITH_HC_128_MD5;
Vanger 0:b86d15c6ba29 1295 }
Vanger 0:b86d15c6ba29 1296 #endif
Vanger 0:b86d15c6ba29 1297
Vanger 0:b86d15c6ba29 1298 #ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
Vanger 0:b86d15c6ba29 1299 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 1300 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1301 suites->suites[idx++] = TLS_RSA_WITH_HC_128_SHA;
Vanger 0:b86d15c6ba29 1302 }
Vanger 0:b86d15c6ba29 1303 #endif
Vanger 0:b86d15c6ba29 1304
Vanger 0:b86d15c6ba29 1305 #ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
Vanger 0:b86d15c6ba29 1306 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 1307 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1308 suites->suites[idx++] = TLS_RSA_WITH_HC_128_B2B256;
Vanger 0:b86d15c6ba29 1309 }
Vanger 0:b86d15c6ba29 1310 #endif
Vanger 0:b86d15c6ba29 1311
Vanger 0:b86d15c6ba29 1312 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
Vanger 0:b86d15c6ba29 1313 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 1314 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1315 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_B2B256;
Vanger 0:b86d15c6ba29 1316 }
Vanger 0:b86d15c6ba29 1317 #endif
Vanger 0:b86d15c6ba29 1318
Vanger 0:b86d15c6ba29 1319 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
Vanger 0:b86d15c6ba29 1320 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 1321 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1322 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_B2B256;
Vanger 0:b86d15c6ba29 1323 }
Vanger 0:b86d15c6ba29 1324 #endif
Vanger 0:b86d15c6ba29 1325
Vanger 0:b86d15c6ba29 1326 #ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
Vanger 0:b86d15c6ba29 1327 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 1328 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1329 suites->suites[idx++] = TLS_RSA_WITH_RABBIT_SHA;
Vanger 0:b86d15c6ba29 1330 }
Vanger 0:b86d15c6ba29 1331 #endif
Vanger 0:b86d15c6ba29 1332
Vanger 0:b86d15c6ba29 1333 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
Vanger 0:b86d15c6ba29 1334 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 1335 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1336 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA;
Vanger 0:b86d15c6ba29 1337 }
Vanger 0:b86d15c6ba29 1338 #endif
Vanger 0:b86d15c6ba29 1339
Vanger 0:b86d15c6ba29 1340 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
Vanger 0:b86d15c6ba29 1341 if (tls && haveDH && haveRSA) {
Vanger 0:b86d15c6ba29 1342 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1343 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA;
Vanger 0:b86d15c6ba29 1344 }
Vanger 0:b86d15c6ba29 1345 #endif
Vanger 0:b86d15c6ba29 1346
Vanger 0:b86d15c6ba29 1347 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
Vanger 0:b86d15c6ba29 1348 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 1349 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1350 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA;
Vanger 0:b86d15c6ba29 1351 }
Vanger 0:b86d15c6ba29 1352 #endif
Vanger 0:b86d15c6ba29 1353
Vanger 0:b86d15c6ba29 1354 #ifdef BUILD_TLS_DHE_WITH_RSA_CAMELLIA_256_CBC_SHA
Vanger 0:b86d15c6ba29 1355 if (tls && haveDH && haveRSA) {
Vanger 0:b86d15c6ba29 1356 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1357 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA;
Vanger 0:b86d15c6ba29 1358 }
Vanger 0:b86d15c6ba29 1359 #endif
Vanger 0:b86d15c6ba29 1360
Vanger 0:b86d15c6ba29 1361 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
Vanger 0:b86d15c6ba29 1362 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 1363 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1364 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256;
Vanger 0:b86d15c6ba29 1365 }
Vanger 0:b86d15c6ba29 1366 #endif
Vanger 0:b86d15c6ba29 1367
Vanger 0:b86d15c6ba29 1368 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
Vanger 0:b86d15c6ba29 1369 if (tls && haveDH && haveRSA) {
Vanger 0:b86d15c6ba29 1370 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1371 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256;
Vanger 0:b86d15c6ba29 1372 }
Vanger 0:b86d15c6ba29 1373 #endif
Vanger 0:b86d15c6ba29 1374
Vanger 0:b86d15c6ba29 1375 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
Vanger 0:b86d15c6ba29 1376 if (tls && haveRSA) {
Vanger 0:b86d15c6ba29 1377 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1378 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256;
Vanger 0:b86d15c6ba29 1379 }
Vanger 0:b86d15c6ba29 1380 #endif
Vanger 0:b86d15c6ba29 1381
Vanger 0:b86d15c6ba29 1382 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
Vanger 0:b86d15c6ba29 1383 if (tls && haveDH && haveRSA) {
Vanger 0:b86d15c6ba29 1384 suites->suites[idx++] = 0;
Vanger 0:b86d15c6ba29 1385 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256;
Vanger 0:b86d15c6ba29 1386 }
Vanger 0:b86d15c6ba29 1387 #endif
Vanger 0:b86d15c6ba29 1388
Vanger 0:b86d15c6ba29 1389 suites->suiteSz = idx;
Vanger 0:b86d15c6ba29 1390
Vanger 0:b86d15c6ba29 1391 InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, 0);
Vanger 0:b86d15c6ba29 1392 }
Vanger 0:b86d15c6ba29 1393
Vanger 0:b86d15c6ba29 1394
Vanger 0:b86d15c6ba29 1395 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 1396
Vanger 0:b86d15c6ba29 1397
Vanger 0:b86d15c6ba29 1398 void InitX509Name(CYASSL_X509_NAME* name, int dynamicFlag)
Vanger 0:b86d15c6ba29 1399 {
Vanger 0:b86d15c6ba29 1400 (void)dynamicFlag;
Vanger 0:b86d15c6ba29 1401
Vanger 0:b86d15c6ba29 1402 if (name != NULL) {
Vanger 0:b86d15c6ba29 1403 name->name = name->staticName;
Vanger 0:b86d15c6ba29 1404 name->dynamicName = 0;
Vanger 0:b86d15c6ba29 1405 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 1406 XMEMSET(&name->fullName, 0, sizeof(DecodedName));
Vanger 0:b86d15c6ba29 1407 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 1408 }
Vanger 0:b86d15c6ba29 1409 }
Vanger 0:b86d15c6ba29 1410
Vanger 0:b86d15c6ba29 1411
Vanger 0:b86d15c6ba29 1412 void FreeX509Name(CYASSL_X509_NAME* name)
Vanger 0:b86d15c6ba29 1413 {
Vanger 0:b86d15c6ba29 1414 if (name != NULL) {
Vanger 0:b86d15c6ba29 1415 if (name->dynamicName)
Vanger 0:b86d15c6ba29 1416 XFREE(name->name, NULL, DYNAMIC_TYPE_SUBJECT_CN);
Vanger 0:b86d15c6ba29 1417 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 1418 if (name->fullName.fullName != NULL)
Vanger 0:b86d15c6ba29 1419 XFREE(name->fullName.fullName, NULL, DYNAMIC_TYPE_X509);
Vanger 0:b86d15c6ba29 1420 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 1421 }
Vanger 0:b86d15c6ba29 1422 }
Vanger 0:b86d15c6ba29 1423
Vanger 0:b86d15c6ba29 1424
Vanger 0:b86d15c6ba29 1425 /* Initialize CyaSSL X509 type */
Vanger 0:b86d15c6ba29 1426 void InitX509(CYASSL_X509* x509, int dynamicFlag)
Vanger 0:b86d15c6ba29 1427 {
Vanger 0:b86d15c6ba29 1428 InitX509Name(&x509->issuer, 0);
Vanger 0:b86d15c6ba29 1429 InitX509Name(&x509->subject, 0);
Vanger 0:b86d15c6ba29 1430 x509->version = 0;
Vanger 0:b86d15c6ba29 1431 x509->pubKey.buffer = NULL;
Vanger 0:b86d15c6ba29 1432 x509->sig.buffer = NULL;
Vanger 0:b86d15c6ba29 1433 x509->derCert.buffer = NULL;
Vanger 0:b86d15c6ba29 1434 x509->altNames = NULL;
Vanger 0:b86d15c6ba29 1435 x509->altNamesNext = NULL;
Vanger 0:b86d15c6ba29 1436 x509->dynamicMemory = (byte)dynamicFlag;
Vanger 0:b86d15c6ba29 1437 x509->isCa = 0;
Vanger 0:b86d15c6ba29 1438 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 1439 x509->pkCurveOID = 0;
Vanger 0:b86d15c6ba29 1440 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 1441 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 1442 x509->pathLength = 0;
Vanger 0:b86d15c6ba29 1443 x509->basicConstSet = 0;
Vanger 0:b86d15c6ba29 1444 x509->basicConstCrit = 0;
Vanger 0:b86d15c6ba29 1445 x509->basicConstPlSet = 0;
Vanger 0:b86d15c6ba29 1446 x509->subjAltNameSet = 0;
Vanger 0:b86d15c6ba29 1447 x509->subjAltNameCrit = 0;
Vanger 0:b86d15c6ba29 1448 x509->authKeyIdSet = 0;
Vanger 0:b86d15c6ba29 1449 x509->authKeyIdCrit = 0;
Vanger 0:b86d15c6ba29 1450 x509->authKeyId = NULL;
Vanger 0:b86d15c6ba29 1451 x509->authKeyIdSz = 0;
Vanger 0:b86d15c6ba29 1452 x509->subjKeyIdSet = 0;
Vanger 0:b86d15c6ba29 1453 x509->subjKeyIdCrit = 0;
Vanger 0:b86d15c6ba29 1454 x509->subjKeyId = NULL;
Vanger 0:b86d15c6ba29 1455 x509->subjKeyIdSz = 0;
Vanger 0:b86d15c6ba29 1456 x509->keyUsageSet = 0;
Vanger 0:b86d15c6ba29 1457 x509->keyUsageCrit = 0;
Vanger 0:b86d15c6ba29 1458 x509->keyUsage = 0;
Vanger 0:b86d15c6ba29 1459 #ifdef CYASSL_SEP
Vanger 0:b86d15c6ba29 1460 x509->certPolicySet = 0;
Vanger 0:b86d15c6ba29 1461 x509->certPolicyCrit = 0;
Vanger 0:b86d15c6ba29 1462 #endif /* CYASSL_SEP */
Vanger 0:b86d15c6ba29 1463 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 1464 }
Vanger 0:b86d15c6ba29 1465
Vanger 0:b86d15c6ba29 1466
Vanger 0:b86d15c6ba29 1467 /* Free CyaSSL X509 type */
Vanger 0:b86d15c6ba29 1468 void FreeX509(CYASSL_X509* x509)
Vanger 0:b86d15c6ba29 1469 {
Vanger 0:b86d15c6ba29 1470 if (x509 == NULL)
Vanger 0:b86d15c6ba29 1471 return;
Vanger 0:b86d15c6ba29 1472
Vanger 0:b86d15c6ba29 1473 FreeX509Name(&x509->issuer);
Vanger 0:b86d15c6ba29 1474 FreeX509Name(&x509->subject);
Vanger 0:b86d15c6ba29 1475 if (x509->pubKey.buffer)
Vanger 0:b86d15c6ba29 1476 XFREE(x509->pubKey.buffer, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
Vanger 0:b86d15c6ba29 1477 XFREE(x509->derCert.buffer, NULL, DYNAMIC_TYPE_SUBJECT_CN);
Vanger 0:b86d15c6ba29 1478 XFREE(x509->sig.buffer, NULL, DYNAMIC_TYPE_SIGNATURE);
Vanger 0:b86d15c6ba29 1479 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 1480 XFREE(x509->authKeyId, NULL, 0);
Vanger 0:b86d15c6ba29 1481 XFREE(x509->subjKeyId, NULL, 0);
Vanger 0:b86d15c6ba29 1482 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 1483 if (x509->altNames)
Vanger 0:b86d15c6ba29 1484 FreeAltNames(x509->altNames, NULL);
Vanger 0:b86d15c6ba29 1485 if (x509->dynamicMemory)
Vanger 0:b86d15c6ba29 1486 XFREE(x509, NULL, DYNAMIC_TYPE_X509);
Vanger 0:b86d15c6ba29 1487 }
Vanger 0:b86d15c6ba29 1488
Vanger 0:b86d15c6ba29 1489 #endif /* NO_CERTS */
Vanger 0:b86d15c6ba29 1490
Vanger 0:b86d15c6ba29 1491
Vanger 0:b86d15c6ba29 1492 /* init everything to 0, NULL, default values before calling anything that may
Vanger 0:b86d15c6ba29 1493 fail so that desctructor has a "good" state to cleanup */
Vanger 0:b86d15c6ba29 1494 int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
Vanger 0:b86d15c6ba29 1495 {
Vanger 0:b86d15c6ba29 1496 int ret;
Vanger 0:b86d15c6ba29 1497 byte haveRSA = 0;
Vanger 0:b86d15c6ba29 1498 byte havePSK = 0;
Vanger 0:b86d15c6ba29 1499 byte haveAnon = 0;
Vanger 0:b86d15c6ba29 1500
Vanger 0:b86d15c6ba29 1501 ssl->ctx = ctx; /* only for passing to calls, options could change */
Vanger 0:b86d15c6ba29 1502 ssl->version = ctx->method->version;
Vanger 0:b86d15c6ba29 1503 ssl->suites = NULL;
Vanger 0:b86d15c6ba29 1504
Vanger 0:b86d15c6ba29 1505 #ifdef HAVE_LIBZ
Vanger 0:b86d15c6ba29 1506 ssl->didStreamInit = 0;
Vanger 0:b86d15c6ba29 1507 #endif
Vanger 0:b86d15c6ba29 1508 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 1509 haveRSA = 1;
Vanger 0:b86d15c6ba29 1510 #endif
Vanger 0:b86d15c6ba29 1511
Vanger 0:b86d15c6ba29 1512 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 1513 ssl->buffers.certificate.buffer = 0;
Vanger 0:b86d15c6ba29 1514 ssl->buffers.key.buffer = 0;
Vanger 0:b86d15c6ba29 1515 ssl->buffers.certChain.buffer = 0;
Vanger 0:b86d15c6ba29 1516 #endif
Vanger 0:b86d15c6ba29 1517 ssl->buffers.inputBuffer.length = 0;
Vanger 0:b86d15c6ba29 1518 ssl->buffers.inputBuffer.idx = 0;
Vanger 0:b86d15c6ba29 1519 ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
Vanger 0:b86d15c6ba29 1520 ssl->buffers.inputBuffer.bufferSize = STATIC_BUFFER_LEN;
Vanger 0:b86d15c6ba29 1521 ssl->buffers.inputBuffer.dynamicFlag = 0;
Vanger 0:b86d15c6ba29 1522 ssl->buffers.inputBuffer.offset = 0;
Vanger 0:b86d15c6ba29 1523 ssl->buffers.outputBuffer.length = 0;
Vanger 0:b86d15c6ba29 1524 ssl->buffers.outputBuffer.idx = 0;
Vanger 0:b86d15c6ba29 1525 ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
Vanger 0:b86d15c6ba29 1526 ssl->buffers.outputBuffer.bufferSize = STATIC_BUFFER_LEN;
Vanger 0:b86d15c6ba29 1527 ssl->buffers.outputBuffer.dynamicFlag = 0;
Vanger 0:b86d15c6ba29 1528 ssl->buffers.outputBuffer.offset = 0;
Vanger 0:b86d15c6ba29 1529 ssl->buffers.domainName.buffer = 0;
Vanger 0:b86d15c6ba29 1530 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 1531 ssl->buffers.serverDH_P.buffer = 0;
Vanger 0:b86d15c6ba29 1532 ssl->buffers.serverDH_G.buffer = 0;
Vanger 0:b86d15c6ba29 1533 ssl->buffers.serverDH_Pub.buffer = 0;
Vanger 0:b86d15c6ba29 1534 ssl->buffers.serverDH_Priv.buffer = 0;
Vanger 0:b86d15c6ba29 1535 #endif
Vanger 0:b86d15c6ba29 1536 ssl->buffers.clearOutputBuffer.buffer = 0;
Vanger 0:b86d15c6ba29 1537 ssl->buffers.clearOutputBuffer.length = 0;
Vanger 0:b86d15c6ba29 1538 ssl->buffers.prevSent = 0;
Vanger 0:b86d15c6ba29 1539 ssl->buffers.plainSz = 0;
Vanger 0:b86d15c6ba29 1540 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 1541 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 1542 ssl->buffers.peerEccDsaKey.buffer = 0;
Vanger 0:b86d15c6ba29 1543 ssl->buffers.peerEccDsaKey.length = 0;
Vanger 0:b86d15c6ba29 1544 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 1545 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 1546 ssl->buffers.peerRsaKey.buffer = 0;
Vanger 0:b86d15c6ba29 1547 ssl->buffers.peerRsaKey.length = 0;
Vanger 0:b86d15c6ba29 1548 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 1549 #endif /* HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 1550
Vanger 0:b86d15c6ba29 1551 #ifdef KEEP_PEER_CERT
Vanger 0:b86d15c6ba29 1552 InitX509(&ssl->peerCert, 0);
Vanger 0:b86d15c6ba29 1553 #endif
Vanger 0:b86d15c6ba29 1554
Vanger 0:b86d15c6ba29 1555 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 1556 ssl->eccTempKeySz = ctx->eccTempKeySz;
Vanger 0:b86d15c6ba29 1557 ssl->pkCurveOID = ctx->pkCurveOID;
Vanger 0:b86d15c6ba29 1558 ssl->peerEccKeyPresent = 0;
Vanger 0:b86d15c6ba29 1559 ssl->peerEccDsaKeyPresent = 0;
Vanger 0:b86d15c6ba29 1560 ssl->eccDsaKeyPresent = 0;
Vanger 0:b86d15c6ba29 1561 ssl->eccTempKeyPresent = 0;
Vanger 0:b86d15c6ba29 1562 ssl->peerEccKey = NULL;
Vanger 0:b86d15c6ba29 1563 ssl->peerEccDsaKey = NULL;
Vanger 0:b86d15c6ba29 1564 ssl->eccDsaKey = NULL;
Vanger 0:b86d15c6ba29 1565 ssl->eccTempKey = NULL;
Vanger 0:b86d15c6ba29 1566 #endif
Vanger 0:b86d15c6ba29 1567
Vanger 0:b86d15c6ba29 1568 ssl->timeout = ctx->timeout;
Vanger 0:b86d15c6ba29 1569 ssl->rfd = -1; /* set to invalid descriptor */
Vanger 0:b86d15c6ba29 1570 ssl->wfd = -1;
Vanger 0:b86d15c6ba29 1571 ssl->rflags = 0; /* no user flags yet */
Vanger 0:b86d15c6ba29 1572 ssl->wflags = 0; /* no user flags yet */
Vanger 0:b86d15c6ba29 1573 ssl->biord = 0;
Vanger 0:b86d15c6ba29 1574 ssl->biowr = 0;
Vanger 0:b86d15c6ba29 1575
Vanger 0:b86d15c6ba29 1576 ssl->IOCB_ReadCtx = &ssl->rfd; /* prevent invalid pointer access if not */
Vanger 0:b86d15c6ba29 1577 ssl->IOCB_WriteCtx = &ssl->wfd; /* correctly set */
Vanger 0:b86d15c6ba29 1578 #ifdef HAVE_NETX
Vanger 0:b86d15c6ba29 1579 ssl->nxCtx.nxSocket = NULL;
Vanger 0:b86d15c6ba29 1580 ssl->nxCtx.nxPacket = NULL;
Vanger 0:b86d15c6ba29 1581 ssl->nxCtx.nxOffset = 0;
Vanger 0:b86d15c6ba29 1582 ssl->nxCtx.nxWait = 0;
Vanger 0:b86d15c6ba29 1583 ssl->IOCB_ReadCtx = &ssl->nxCtx; /* default NetX IO ctx, same for read */
Vanger 0:b86d15c6ba29 1584 ssl->IOCB_WriteCtx = &ssl->nxCtx; /* and write */
Vanger 0:b86d15c6ba29 1585 #endif
Vanger 0:b86d15c6ba29 1586 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 1587 ssl->IOCB_CookieCtx = NULL; /* we don't use for default cb */
Vanger 0:b86d15c6ba29 1588 ssl->dtls_expected_rx = MAX_MTU;
Vanger 0:b86d15c6ba29 1589 ssl->keys.dtls_state.window = 0;
Vanger 0:b86d15c6ba29 1590 ssl->keys.dtls_state.nextEpoch = 0;
Vanger 0:b86d15c6ba29 1591 ssl->keys.dtls_state.nextSeq = 0;
Vanger 0:b86d15c6ba29 1592 #endif
Vanger 0:b86d15c6ba29 1593
Vanger 0:b86d15c6ba29 1594 XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
Vanger 0:b86d15c6ba29 1595
Vanger 0:b86d15c6ba29 1596 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 1597 ssl->peerRsaKey = NULL;
Vanger 0:b86d15c6ba29 1598 ssl->peerRsaKeyPresent = 0;
Vanger 0:b86d15c6ba29 1599 #endif
Vanger 0:b86d15c6ba29 1600 ssl->verifyCallback = ctx->verifyCallback;
Vanger 0:b86d15c6ba29 1601 ssl->verifyCbCtx = NULL;
Vanger 0:b86d15c6ba29 1602 ssl->options.side = ctx->method->side;
Vanger 0:b86d15c6ba29 1603 ssl->options.downgrade = ctx->method->downgrade;
Vanger 0:b86d15c6ba29 1604 ssl->options.minDowngrade = TLSv1_MINOR; /* current default */
Vanger 0:b86d15c6ba29 1605 ssl->error = 0;
Vanger 0:b86d15c6ba29 1606 ssl->options.connReset = 0;
Vanger 0:b86d15c6ba29 1607 ssl->options.isClosed = 0;
Vanger 0:b86d15c6ba29 1608 ssl->options.closeNotify = 0;
Vanger 0:b86d15c6ba29 1609 ssl->options.sentNotify = 0;
Vanger 0:b86d15c6ba29 1610 ssl->options.usingCompression = 0;
Vanger 0:b86d15c6ba29 1611 if (ssl->options.side == CYASSL_SERVER_END)
Vanger 0:b86d15c6ba29 1612 ssl->options.haveDH = ctx->haveDH;
Vanger 0:b86d15c6ba29 1613 else
Vanger 0:b86d15c6ba29 1614 ssl->options.haveDH = 0;
Vanger 0:b86d15c6ba29 1615 ssl->options.haveNTRU = ctx->haveNTRU;
Vanger 0:b86d15c6ba29 1616 ssl->options.haveECDSAsig = ctx->haveECDSAsig;
Vanger 0:b86d15c6ba29 1617 ssl->options.haveStaticECC = ctx->haveStaticECC;
Vanger 0:b86d15c6ba29 1618 ssl->options.havePeerCert = 0;
Vanger 0:b86d15c6ba29 1619 ssl->options.havePeerVerify = 0;
Vanger 0:b86d15c6ba29 1620 ssl->options.usingPSK_cipher = 0;
Vanger 0:b86d15c6ba29 1621 ssl->options.usingAnon_cipher = 0;
Vanger 0:b86d15c6ba29 1622 ssl->options.sendAlertState = 0;
Vanger 0:b86d15c6ba29 1623 #ifndef NO_PSK
Vanger 0:b86d15c6ba29 1624 havePSK = ctx->havePSK;
Vanger 0:b86d15c6ba29 1625 ssl->options.havePSK = ctx->havePSK;
Vanger 0:b86d15c6ba29 1626 ssl->options.client_psk_cb = ctx->client_psk_cb;
Vanger 0:b86d15c6ba29 1627 ssl->options.server_psk_cb = ctx->server_psk_cb;
Vanger 0:b86d15c6ba29 1628 #endif /* NO_PSK */
Vanger 0:b86d15c6ba29 1629 #ifdef HAVE_ANON
Vanger 0:b86d15c6ba29 1630 haveAnon = ctx->haveAnon;
Vanger 0:b86d15c6ba29 1631 ssl->options.haveAnon = ctx->haveAnon;
Vanger 0:b86d15c6ba29 1632 #endif
Vanger 0:b86d15c6ba29 1633
Vanger 0:b86d15c6ba29 1634 ssl->options.serverState = NULL_STATE;
Vanger 0:b86d15c6ba29 1635 ssl->options.clientState = NULL_STATE;
Vanger 0:b86d15c6ba29 1636 ssl->options.connectState = CONNECT_BEGIN;
Vanger 0:b86d15c6ba29 1637 ssl->options.acceptState = ACCEPT_BEGIN;
Vanger 0:b86d15c6ba29 1638 ssl->options.handShakeState = NULL_STATE;
Vanger 0:b86d15c6ba29 1639 ssl->options.handShakeDone = 0;
Vanger 0:b86d15c6ba29 1640 ssl->options.processReply = doProcessInit;
Vanger 0:b86d15c6ba29 1641
Vanger 0:b86d15c6ba29 1642 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 1643 ssl->keys.dtls_sequence_number = 0;
Vanger 0:b86d15c6ba29 1644 ssl->keys.dtls_state.curSeq = 0;
Vanger 0:b86d15c6ba29 1645 ssl->keys.dtls_state.nextSeq = 0;
Vanger 0:b86d15c6ba29 1646 ssl->keys.dtls_handshake_number = 0;
Vanger 0:b86d15c6ba29 1647 ssl->keys.dtls_expected_peer_handshake_number = 0;
Vanger 0:b86d15c6ba29 1648 ssl->keys.dtls_epoch = 0;
Vanger 0:b86d15c6ba29 1649 ssl->keys.dtls_state.curEpoch = 0;
Vanger 0:b86d15c6ba29 1650 ssl->keys.dtls_state.nextEpoch = 0;
Vanger 0:b86d15c6ba29 1651 ssl->dtls_timeout_init = DTLS_TIMEOUT_INIT;
Vanger 0:b86d15c6ba29 1652 ssl->dtls_timeout_max = DTLS_TIMEOUT_MAX;
Vanger 0:b86d15c6ba29 1653 ssl->dtls_timeout = ssl->dtls_timeout_init;
Vanger 0:b86d15c6ba29 1654 ssl->dtls_pool = NULL;
Vanger 0:b86d15c6ba29 1655 ssl->dtls_msg_list = NULL;
Vanger 0:b86d15c6ba29 1656 #endif
Vanger 0:b86d15c6ba29 1657 ssl->keys.encryptSz = 0;
Vanger 0:b86d15c6ba29 1658 ssl->keys.padSz = 0;
Vanger 0:b86d15c6ba29 1659 ssl->keys.encryptionOn = 0; /* initially off */
Vanger 0:b86d15c6ba29 1660 ssl->keys.decryptedCur = 0; /* initially off */
Vanger 0:b86d15c6ba29 1661 ssl->options.sessionCacheOff = ctx->sessionCacheOff;
Vanger 0:b86d15c6ba29 1662 ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
Vanger 0:b86d15c6ba29 1663
Vanger 0:b86d15c6ba29 1664 ssl->options.verifyPeer = ctx->verifyPeer;
Vanger 0:b86d15c6ba29 1665 ssl->options.verifyNone = ctx->verifyNone;
Vanger 0:b86d15c6ba29 1666 ssl->options.failNoCert = ctx->failNoCert;
Vanger 0:b86d15c6ba29 1667 ssl->options.sendVerify = ctx->sendVerify;
Vanger 0:b86d15c6ba29 1668
Vanger 0:b86d15c6ba29 1669 ssl->options.resuming = 0;
Vanger 0:b86d15c6ba29 1670 ssl->options.haveSessionId = 0;
Vanger 0:b86d15c6ba29 1671 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 1672 ssl->hmac = SSL_hmac; /* default to SSLv3 */
Vanger 0:b86d15c6ba29 1673 #else
Vanger 0:b86d15c6ba29 1674 ssl->hmac = TLS_hmac;
Vanger 0:b86d15c6ba29 1675 #endif
Vanger 0:b86d15c6ba29 1676 ssl->heap = ctx->heap; /* defaults to self */
Vanger 0:b86d15c6ba29 1677 ssl->options.tls = 0;
Vanger 0:b86d15c6ba29 1678 ssl->options.tls1_1 = 0;
Vanger 0:b86d15c6ba29 1679 ssl->options.dtls = ssl->version.major == DTLS_MAJOR;
Vanger 0:b86d15c6ba29 1680 ssl->options.partialWrite = ctx->partialWrite;
Vanger 0:b86d15c6ba29 1681 ssl->options.quietShutdown = ctx->quietShutdown;
Vanger 0:b86d15c6ba29 1682 ssl->options.certOnly = 0;
Vanger 0:b86d15c6ba29 1683 ssl->options.groupMessages = ctx->groupMessages;
Vanger 0:b86d15c6ba29 1684 ssl->options.usingNonblock = 0;
Vanger 0:b86d15c6ba29 1685 ssl->options.saveArrays = 0;
Vanger 0:b86d15c6ba29 1686 #ifdef HAVE_POLY1305
Vanger 0:b86d15c6ba29 1687 ssl->options.oldPoly = 0;
Vanger 0:b86d15c6ba29 1688 #endif
Vanger 0:b86d15c6ba29 1689
Vanger 0:b86d15c6ba29 1690 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 1691 /* ctx still owns certificate, certChain, key, dh, and cm */
Vanger 0:b86d15c6ba29 1692 ssl->buffers.certificate = ctx->certificate;
Vanger 0:b86d15c6ba29 1693 ssl->buffers.certChain = ctx->certChain;
Vanger 0:b86d15c6ba29 1694 ssl->buffers.key = ctx->privateKey;
Vanger 0:b86d15c6ba29 1695 if (ssl->options.side == CYASSL_SERVER_END) {
Vanger 0:b86d15c6ba29 1696 ssl->buffers.serverDH_P = ctx->serverDH_P;
Vanger 0:b86d15c6ba29 1697 ssl->buffers.serverDH_G = ctx->serverDH_G;
Vanger 0:b86d15c6ba29 1698 }
Vanger 0:b86d15c6ba29 1699 #endif
Vanger 0:b86d15c6ba29 1700 ssl->buffers.weOwnCert = 0;
Vanger 0:b86d15c6ba29 1701 ssl->buffers.weOwnCertChain = 0;
Vanger 0:b86d15c6ba29 1702 ssl->buffers.weOwnKey = 0;
Vanger 0:b86d15c6ba29 1703 ssl->buffers.weOwnDH = 0;
Vanger 0:b86d15c6ba29 1704
Vanger 0:b86d15c6ba29 1705 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 1706 ssl->buffers.dtlsCtx.fd = -1;
Vanger 0:b86d15c6ba29 1707 ssl->buffers.dtlsCtx.peer.sa = NULL;
Vanger 0:b86d15c6ba29 1708 ssl->buffers.dtlsCtx.peer.sz = 0;
Vanger 0:b86d15c6ba29 1709 #endif
Vanger 0:b86d15c6ba29 1710
Vanger 0:b86d15c6ba29 1711 #ifdef KEEP_PEER_CERT
Vanger 0:b86d15c6ba29 1712 ssl->peerCert.issuer.sz = 0;
Vanger 0:b86d15c6ba29 1713 ssl->peerCert.subject.sz = 0;
Vanger 0:b86d15c6ba29 1714 #endif
Vanger 0:b86d15c6ba29 1715
Vanger 0:b86d15c6ba29 1716 #ifdef SESSION_CERTS
Vanger 0:b86d15c6ba29 1717 ssl->session.chain.count = 0;
Vanger 0:b86d15c6ba29 1718 #endif
Vanger 0:b86d15c6ba29 1719
Vanger 0:b86d15c6ba29 1720 #ifndef NO_CLIENT_CACHE
Vanger 0:b86d15c6ba29 1721 ssl->session.idLen = 0;
Vanger 0:b86d15c6ba29 1722 #endif
Vanger 0:b86d15c6ba29 1723
Vanger 0:b86d15c6ba29 1724 #ifdef HAVE_SESSION_TICKET
Vanger 0:b86d15c6ba29 1725 ssl->session.ticketLen = 0;
Vanger 0:b86d15c6ba29 1726 #endif
Vanger 0:b86d15c6ba29 1727
Vanger 0:b86d15c6ba29 1728 ssl->cipher.ssl = ssl;
Vanger 0:b86d15c6ba29 1729
Vanger 0:b86d15c6ba29 1730 #ifdef FORTRESS
Vanger 0:b86d15c6ba29 1731 ssl->ex_data[0] = 0;
Vanger 0:b86d15c6ba29 1732 ssl->ex_data[1] = 0;
Vanger 0:b86d15c6ba29 1733 ssl->ex_data[2] = 0;
Vanger 0:b86d15c6ba29 1734 #endif
Vanger 0:b86d15c6ba29 1735
Vanger 0:b86d15c6ba29 1736 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 1737 ssl->hsInfoOn = 0;
Vanger 0:b86d15c6ba29 1738 ssl->toInfoOn = 0;
Vanger 0:b86d15c6ba29 1739 #endif
Vanger 0:b86d15c6ba29 1740
Vanger 0:b86d15c6ba29 1741 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 1742 ssl->devId = ctx->devId;
Vanger 0:b86d15c6ba29 1743 #endif
Vanger 0:b86d15c6ba29 1744
Vanger 0:b86d15c6ba29 1745 #ifdef HAVE_TLS_EXTENSIONS
Vanger 0:b86d15c6ba29 1746 ssl->extensions = NULL;
Vanger 0:b86d15c6ba29 1747 #ifdef HAVE_MAX_FRAGMENT
Vanger 0:b86d15c6ba29 1748 ssl->max_fragment = MAX_RECORD_SIZE;
Vanger 0:b86d15c6ba29 1749 #endif
Vanger 0:b86d15c6ba29 1750 #ifdef HAVE_TRUNCATED_HMAC
Vanger 0:b86d15c6ba29 1751 ssl->truncated_hmac = 0;
Vanger 0:b86d15c6ba29 1752 #endif
Vanger 0:b86d15c6ba29 1753 #ifdef HAVE_SECURE_RENEGOTIATION
Vanger 0:b86d15c6ba29 1754 ssl->secure_renegotiation = NULL;
Vanger 0:b86d15c6ba29 1755 #endif
Vanger 0:b86d15c6ba29 1756 #if !defined(NO_CYASSL_CLIENT) && defined(HAVE_SESSION_TICKET)
Vanger 0:b86d15c6ba29 1757 ssl->session_ticket_cb = NULL;
Vanger 0:b86d15c6ba29 1758 ssl->session_ticket_ctx = NULL;
Vanger 0:b86d15c6ba29 1759 ssl->expect_session_ticket = 0;
Vanger 0:b86d15c6ba29 1760 #endif
Vanger 0:b86d15c6ba29 1761 #endif
Vanger 0:b86d15c6ba29 1762
Vanger 0:b86d15c6ba29 1763 ssl->rng = NULL;
Vanger 0:b86d15c6ba29 1764 ssl->arrays = NULL;
Vanger 0:b86d15c6ba29 1765
Vanger 0:b86d15c6ba29 1766 /* default alert state (none) */
Vanger 0:b86d15c6ba29 1767 ssl->alert_history.last_rx.code = -1;
Vanger 0:b86d15c6ba29 1768 ssl->alert_history.last_rx.level = -1;
Vanger 0:b86d15c6ba29 1769 ssl->alert_history.last_tx.code = -1;
Vanger 0:b86d15c6ba29 1770 ssl->alert_history.last_tx.level = -1;
Vanger 0:b86d15c6ba29 1771
Vanger 0:b86d15c6ba29 1772 InitCiphers(ssl);
Vanger 0:b86d15c6ba29 1773 InitCipherSpecs(&ssl->specs);
Vanger 0:b86d15c6ba29 1774 #ifdef ATOMIC_USER
Vanger 0:b86d15c6ba29 1775 ssl->MacEncryptCtx = NULL;
Vanger 0:b86d15c6ba29 1776 ssl->DecryptVerifyCtx = NULL;
Vanger 0:b86d15c6ba29 1777 #endif
Vanger 0:b86d15c6ba29 1778 #ifdef HAVE_FUZZER
Vanger 0:b86d15c6ba29 1779 ssl->fuzzerCb = NULL;
Vanger 0:b86d15c6ba29 1780 ssl->fuzzerCtx = NULL;
Vanger 0:b86d15c6ba29 1781 #endif
Vanger 0:b86d15c6ba29 1782 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 1783 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 1784 ssl->EccSignCtx = NULL;
Vanger 0:b86d15c6ba29 1785 ssl->EccVerifyCtx = NULL;
Vanger 0:b86d15c6ba29 1786 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 1787 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 1788 ssl->RsaSignCtx = NULL;
Vanger 0:b86d15c6ba29 1789 ssl->RsaVerifyCtx = NULL;
Vanger 0:b86d15c6ba29 1790 ssl->RsaEncCtx = NULL;
Vanger 0:b86d15c6ba29 1791 ssl->RsaDecCtx = NULL;
Vanger 0:b86d15c6ba29 1792 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 1793 #endif /* HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 1794
Vanger 0:b86d15c6ba29 1795 /* all done with init, now can return errors, call other stuff */
Vanger 0:b86d15c6ba29 1796
Vanger 0:b86d15c6ba29 1797 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 1798 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 1799 InitMd5(&ssl->hashMd5);
Vanger 0:b86d15c6ba29 1800 #endif
Vanger 0:b86d15c6ba29 1801 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 1802 ret = InitSha(&ssl->hashSha);
Vanger 0:b86d15c6ba29 1803 if (ret != 0) {
Vanger 0:b86d15c6ba29 1804 return ret;
Vanger 0:b86d15c6ba29 1805 }
Vanger 0:b86d15c6ba29 1806 #endif
Vanger 0:b86d15c6ba29 1807 #endif
Vanger 0:b86d15c6ba29 1808 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 1809 ret = InitSha256(&ssl->hashSha256);
Vanger 0:b86d15c6ba29 1810 if (ret != 0) {
Vanger 0:b86d15c6ba29 1811 return ret;
Vanger 0:b86d15c6ba29 1812 }
Vanger 0:b86d15c6ba29 1813 #endif
Vanger 0:b86d15c6ba29 1814 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 1815 ret = InitSha384(&ssl->hashSha384);
Vanger 0:b86d15c6ba29 1816 if (ret != 0) {
Vanger 0:b86d15c6ba29 1817 return ret;
Vanger 0:b86d15c6ba29 1818 }
Vanger 0:b86d15c6ba29 1819 #endif
Vanger 0:b86d15c6ba29 1820
Vanger 0:b86d15c6ba29 1821 /* increment CTX reference count */
Vanger 0:b86d15c6ba29 1822 if (LockMutex(&ctx->countMutex) != 0) {
Vanger 0:b86d15c6ba29 1823 CYASSL_MSG("Couldn't lock CTX count mutex");
Vanger 0:b86d15c6ba29 1824 return BAD_MUTEX_E;
Vanger 0:b86d15c6ba29 1825 }
Vanger 0:b86d15c6ba29 1826 ctx->refCount++;
Vanger 0:b86d15c6ba29 1827 UnLockMutex(&ctx->countMutex);
Vanger 0:b86d15c6ba29 1828
Vanger 0:b86d15c6ba29 1829 /* arrays */
Vanger 0:b86d15c6ba29 1830 ssl->arrays = (Arrays*)XMALLOC(sizeof(Arrays), ssl->heap,
Vanger 0:b86d15c6ba29 1831 DYNAMIC_TYPE_ARRAYS);
Vanger 0:b86d15c6ba29 1832 if (ssl->arrays == NULL) {
Vanger 0:b86d15c6ba29 1833 CYASSL_MSG("Arrays Memory error");
Vanger 0:b86d15c6ba29 1834 return MEMORY_E;
Vanger 0:b86d15c6ba29 1835 }
Vanger 0:b86d15c6ba29 1836 XMEMSET(ssl->arrays, 0, sizeof(Arrays));
Vanger 0:b86d15c6ba29 1837
Vanger 0:b86d15c6ba29 1838 #ifndef NO_PSK
Vanger 0:b86d15c6ba29 1839 ssl->arrays->client_identity[0] = 0;
Vanger 0:b86d15c6ba29 1840 if (ctx->server_hint[0]) { /* set in CTX */
Vanger 0:b86d15c6ba29 1841 XSTRNCPY(ssl->arrays->server_hint, ctx->server_hint, MAX_PSK_ID_LEN);
Vanger 0:b86d15c6ba29 1842 ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
Vanger 0:b86d15c6ba29 1843 }
Vanger 0:b86d15c6ba29 1844 else
Vanger 0:b86d15c6ba29 1845 ssl->arrays->server_hint[0] = 0;
Vanger 0:b86d15c6ba29 1846 #endif /* NO_PSK */
Vanger 0:b86d15c6ba29 1847
Vanger 0:b86d15c6ba29 1848 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 1849 ssl->arrays->cookieSz = 0;
Vanger 0:b86d15c6ba29 1850 #endif
Vanger 0:b86d15c6ba29 1851
Vanger 0:b86d15c6ba29 1852 /* RNG */
Vanger 0:b86d15c6ba29 1853 ssl->rng = (RNG*)XMALLOC(sizeof(RNG), ssl->heap, DYNAMIC_TYPE_RNG);
Vanger 0:b86d15c6ba29 1854 if (ssl->rng == NULL) {
Vanger 0:b86d15c6ba29 1855 CYASSL_MSG("RNG Memory error");
Vanger 0:b86d15c6ba29 1856 return MEMORY_E;
Vanger 0:b86d15c6ba29 1857 }
Vanger 0:b86d15c6ba29 1858
Vanger 0:b86d15c6ba29 1859 if ( (ret = InitRng(ssl->rng)) != 0) {
Vanger 0:b86d15c6ba29 1860 CYASSL_MSG("RNG Init error");
Vanger 0:b86d15c6ba29 1861 return ret;
Vanger 0:b86d15c6ba29 1862 }
Vanger 0:b86d15c6ba29 1863
Vanger 0:b86d15c6ba29 1864 /* suites */
Vanger 0:b86d15c6ba29 1865 ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
Vanger 0:b86d15c6ba29 1866 DYNAMIC_TYPE_SUITES);
Vanger 0:b86d15c6ba29 1867 if (ssl->suites == NULL) {
Vanger 0:b86d15c6ba29 1868 CYASSL_MSG("Suites Memory error");
Vanger 0:b86d15c6ba29 1869 return MEMORY_E;
Vanger 0:b86d15c6ba29 1870 }
Vanger 0:b86d15c6ba29 1871 *ssl->suites = ctx->suites;
Vanger 0:b86d15c6ba29 1872
Vanger 0:b86d15c6ba29 1873 /* peer key */
Vanger 0:b86d15c6ba29 1874 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 1875 ssl->peerRsaKey = (RsaKey*)XMALLOC(sizeof(RsaKey), ssl->heap,
Vanger 0:b86d15c6ba29 1876 DYNAMIC_TYPE_RSA);
Vanger 0:b86d15c6ba29 1877 if (ssl->peerRsaKey == NULL) {
Vanger 0:b86d15c6ba29 1878 CYASSL_MSG("PeerRsaKey Memory error");
Vanger 0:b86d15c6ba29 1879 return MEMORY_E;
Vanger 0:b86d15c6ba29 1880 }
Vanger 0:b86d15c6ba29 1881 ret = InitRsaKey(ssl->peerRsaKey, ctx->heap);
Vanger 0:b86d15c6ba29 1882 if (ret != 0) return ret;
Vanger 0:b86d15c6ba29 1883 #endif
Vanger 0:b86d15c6ba29 1884 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 1885 /* make sure server has cert and key unless using PSK or Anon */
Vanger 0:b86d15c6ba29 1886 if (ssl->options.side == CYASSL_SERVER_END && !havePSK && !haveAnon)
Vanger 0:b86d15c6ba29 1887 if (!ssl->buffers.certificate.buffer || !ssl->buffers.key.buffer) {
Vanger 0:b86d15c6ba29 1888 CYASSL_MSG("Server missing certificate and/or private key");
Vanger 0:b86d15c6ba29 1889 return NO_PRIVATE_KEY;
Vanger 0:b86d15c6ba29 1890 }
Vanger 0:b86d15c6ba29 1891 #endif
Vanger 0:b86d15c6ba29 1892 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 1893 ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
Vanger 0:b86d15c6ba29 1894 ctx->heap, DYNAMIC_TYPE_ECC);
Vanger 0:b86d15c6ba29 1895 if (ssl->peerEccKey == NULL) {
Vanger 0:b86d15c6ba29 1896 CYASSL_MSG("PeerEccKey Memory error");
Vanger 0:b86d15c6ba29 1897 return MEMORY_E;
Vanger 0:b86d15c6ba29 1898 }
Vanger 0:b86d15c6ba29 1899 ssl->peerEccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
Vanger 0:b86d15c6ba29 1900 ctx->heap, DYNAMIC_TYPE_ECC);
Vanger 0:b86d15c6ba29 1901 if (ssl->peerEccDsaKey == NULL) {
Vanger 0:b86d15c6ba29 1902 CYASSL_MSG("PeerEccDsaKey Memory error");
Vanger 0:b86d15c6ba29 1903 return MEMORY_E;
Vanger 0:b86d15c6ba29 1904 }
Vanger 0:b86d15c6ba29 1905 ssl->eccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
Vanger 0:b86d15c6ba29 1906 ctx->heap, DYNAMIC_TYPE_ECC);
Vanger 0:b86d15c6ba29 1907 if (ssl->eccDsaKey == NULL) {
Vanger 0:b86d15c6ba29 1908 CYASSL_MSG("EccDsaKey Memory error");
Vanger 0:b86d15c6ba29 1909 return MEMORY_E;
Vanger 0:b86d15c6ba29 1910 }
Vanger 0:b86d15c6ba29 1911 ssl->eccTempKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
Vanger 0:b86d15c6ba29 1912 ctx->heap, DYNAMIC_TYPE_ECC);
Vanger 0:b86d15c6ba29 1913 if (ssl->eccTempKey == NULL) {
Vanger 0:b86d15c6ba29 1914 CYASSL_MSG("EccTempKey Memory error");
Vanger 0:b86d15c6ba29 1915 return MEMORY_E;
Vanger 0:b86d15c6ba29 1916 }
Vanger 0:b86d15c6ba29 1917 ecc_init(ssl->peerEccKey);
Vanger 0:b86d15c6ba29 1918 ecc_init(ssl->peerEccDsaKey);
Vanger 0:b86d15c6ba29 1919 ecc_init(ssl->eccDsaKey);
Vanger 0:b86d15c6ba29 1920 ecc_init(ssl->eccTempKey);
Vanger 0:b86d15c6ba29 1921 #endif
Vanger 0:b86d15c6ba29 1922 #ifdef HAVE_SECRET_CALLBACK
Vanger 0:b86d15c6ba29 1923 ssl->sessionSecretCb = NULL;
Vanger 0:b86d15c6ba29 1924 ssl->sessionSecretCtx = NULL;
Vanger 0:b86d15c6ba29 1925 #endif
Vanger 0:b86d15c6ba29 1926
Vanger 0:b86d15c6ba29 1927 /* make sure server has DH parms, and add PSK if there, add NTRU too */
Vanger 0:b86d15c6ba29 1928 if (ssl->options.side == CYASSL_SERVER_END)
Vanger 0:b86d15c6ba29 1929 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
Vanger 0:b86d15c6ba29 1930 ssl->options.haveDH, ssl->options.haveNTRU,
Vanger 0:b86d15c6ba29 1931 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
Vanger 0:b86d15c6ba29 1932 ssl->options.side);
Vanger 0:b86d15c6ba29 1933 else
Vanger 0:b86d15c6ba29 1934 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, TRUE,
Vanger 0:b86d15c6ba29 1935 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
Vanger 0:b86d15c6ba29 1936 ssl->options.haveStaticECC, ssl->options.side);
Vanger 0:b86d15c6ba29 1937
Vanger 0:b86d15c6ba29 1938 return 0;
Vanger 0:b86d15c6ba29 1939 }
Vanger 0:b86d15c6ba29 1940
Vanger 0:b86d15c6ba29 1941
Vanger 0:b86d15c6ba29 1942 /* free use of temporary arrays */
Vanger 0:b86d15c6ba29 1943 void FreeArrays(CYASSL* ssl, int keep)
Vanger 0:b86d15c6ba29 1944 {
Vanger 0:b86d15c6ba29 1945 if (ssl->arrays && keep) {
Vanger 0:b86d15c6ba29 1946 /* keeps session id for user retrieval */
Vanger 0:b86d15c6ba29 1947 XMEMCPY(ssl->session.sessionID, ssl->arrays->sessionID, ID_LEN);
Vanger 0:b86d15c6ba29 1948 ssl->session.sessionIDSz = ssl->arrays->sessionIDSz;
Vanger 0:b86d15c6ba29 1949 }
Vanger 0:b86d15c6ba29 1950 XFREE(ssl->arrays, ssl->heap, DYNAMIC_TYPE_ARRAYS);
Vanger 0:b86d15c6ba29 1951 ssl->arrays = NULL;
Vanger 0:b86d15c6ba29 1952 }
Vanger 0:b86d15c6ba29 1953
Vanger 0:b86d15c6ba29 1954
Vanger 0:b86d15c6ba29 1955 /* In case holding SSL object in array and don't want to free actual ssl */
Vanger 0:b86d15c6ba29 1956 void SSL_ResourceFree(CYASSL* ssl)
Vanger 0:b86d15c6ba29 1957 {
Vanger 0:b86d15c6ba29 1958 /* Note: any resources used during the handshake should be released in the
Vanger 0:b86d15c6ba29 1959 * function FreeHandshakeResources(). Be careful with the special cases
Vanger 0:b86d15c6ba29 1960 * like the RNG which may optionally be kept for the whole session. (For
Vanger 0:b86d15c6ba29 1961 * example with the RNG, it isn't used beyond the handshake except when
Vanger 0:b86d15c6ba29 1962 * using stream ciphers where it is retained. */
Vanger 0:b86d15c6ba29 1963
Vanger 0:b86d15c6ba29 1964 FreeCiphers(ssl);
Vanger 0:b86d15c6ba29 1965 FreeArrays(ssl, 0);
Vanger 0:b86d15c6ba29 1966 #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
Vanger 0:b86d15c6ba29 1967 FreeRng(ssl->rng);
Vanger 0:b86d15c6ba29 1968 #endif
Vanger 0:b86d15c6ba29 1969 XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
Vanger 0:b86d15c6ba29 1970 XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
Vanger 0:b86d15c6ba29 1971 XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
Vanger 0:b86d15c6ba29 1972
Vanger 0:b86d15c6ba29 1973 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 1974 XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 1975 XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 1976 /* parameters (p,g) may be owned by ctx */
Vanger 0:b86d15c6ba29 1977 if (ssl->buffers.weOwnDH || ssl->options.side == CYASSL_CLIENT_END) {
Vanger 0:b86d15c6ba29 1978 XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 1979 XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 1980 }
Vanger 0:b86d15c6ba29 1981
Vanger 0:b86d15c6ba29 1982 if (ssl->buffers.weOwnCert)
Vanger 0:b86d15c6ba29 1983 XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
Vanger 0:b86d15c6ba29 1984 if (ssl->buffers.weOwnCertChain)
Vanger 0:b86d15c6ba29 1985 XFREE(ssl->buffers.certChain.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
Vanger 0:b86d15c6ba29 1986 if (ssl->buffers.weOwnKey)
Vanger 0:b86d15c6ba29 1987 XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
Vanger 0:b86d15c6ba29 1988 #endif
Vanger 0:b86d15c6ba29 1989 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 1990 if (ssl->peerRsaKey) {
Vanger 0:b86d15c6ba29 1991 FreeRsaKey(ssl->peerRsaKey);
Vanger 0:b86d15c6ba29 1992 XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
Vanger 0:b86d15c6ba29 1993 }
Vanger 0:b86d15c6ba29 1994 #endif
Vanger 0:b86d15c6ba29 1995 if (ssl->buffers.inputBuffer.dynamicFlag)
Vanger 0:b86d15c6ba29 1996 ShrinkInputBuffer(ssl, FORCED_FREE);
Vanger 0:b86d15c6ba29 1997 if (ssl->buffers.outputBuffer.dynamicFlag)
Vanger 0:b86d15c6ba29 1998 ShrinkOutputBuffer(ssl);
Vanger 0:b86d15c6ba29 1999 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 2000 if (ssl->dtls_pool != NULL) {
Vanger 0:b86d15c6ba29 2001 DtlsPoolReset(ssl);
Vanger 0:b86d15c6ba29 2002 XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_NONE);
Vanger 0:b86d15c6ba29 2003 }
Vanger 0:b86d15c6ba29 2004 if (ssl->dtls_msg_list != NULL) {
Vanger 0:b86d15c6ba29 2005 DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
Vanger 0:b86d15c6ba29 2006 ssl->dtls_msg_list = NULL;
Vanger 0:b86d15c6ba29 2007 }
Vanger 0:b86d15c6ba29 2008 XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
Vanger 0:b86d15c6ba29 2009 ssl->buffers.dtlsCtx.peer.sa = NULL;
Vanger 0:b86d15c6ba29 2010 #endif
Vanger 0:b86d15c6ba29 2011 #if defined(KEEP_PEER_CERT) || defined(GOAHEAD_WS)
Vanger 0:b86d15c6ba29 2012 FreeX509(&ssl->peerCert);
Vanger 0:b86d15c6ba29 2013 #endif
Vanger 0:b86d15c6ba29 2014 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
Vanger 0:b86d15c6ba29 2015 CyaSSL_BIO_free(ssl->biord);
Vanger 0:b86d15c6ba29 2016 if (ssl->biord != ssl->biowr) /* in case same as write */
Vanger 0:b86d15c6ba29 2017 CyaSSL_BIO_free(ssl->biowr);
Vanger 0:b86d15c6ba29 2018 #endif
Vanger 0:b86d15c6ba29 2019 #ifdef HAVE_LIBZ
Vanger 0:b86d15c6ba29 2020 FreeStreams(ssl);
Vanger 0:b86d15c6ba29 2021 #endif
Vanger 0:b86d15c6ba29 2022 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 2023 if (ssl->peerEccKey) {
Vanger 0:b86d15c6ba29 2024 if (ssl->peerEccKeyPresent)
Vanger 0:b86d15c6ba29 2025 ecc_free(ssl->peerEccKey);
Vanger 0:b86d15c6ba29 2026 XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
Vanger 0:b86d15c6ba29 2027 }
Vanger 0:b86d15c6ba29 2028 if (ssl->peerEccDsaKey) {
Vanger 0:b86d15c6ba29 2029 if (ssl->peerEccDsaKeyPresent)
Vanger 0:b86d15c6ba29 2030 ecc_free(ssl->peerEccDsaKey);
Vanger 0:b86d15c6ba29 2031 XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
Vanger 0:b86d15c6ba29 2032 }
Vanger 0:b86d15c6ba29 2033 if (ssl->eccTempKey) {
Vanger 0:b86d15c6ba29 2034 if (ssl->eccTempKeyPresent)
Vanger 0:b86d15c6ba29 2035 ecc_free(ssl->eccTempKey);
Vanger 0:b86d15c6ba29 2036 XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
Vanger 0:b86d15c6ba29 2037 }
Vanger 0:b86d15c6ba29 2038 if (ssl->eccDsaKey) {
Vanger 0:b86d15c6ba29 2039 if (ssl->eccDsaKeyPresent)
Vanger 0:b86d15c6ba29 2040 ecc_free(ssl->eccDsaKey);
Vanger 0:b86d15c6ba29 2041 XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
Vanger 0:b86d15c6ba29 2042 }
Vanger 0:b86d15c6ba29 2043 #endif
Vanger 0:b86d15c6ba29 2044 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 2045 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 2046 XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
Vanger 0:b86d15c6ba29 2047 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 2048 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 2049 XFREE(ssl->buffers.peerRsaKey.buffer, ssl->heap, DYNAMIC_TYPE_RSA);
Vanger 0:b86d15c6ba29 2050 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 2051 #endif /* HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 2052 #ifdef HAVE_TLS_EXTENSIONS
Vanger 0:b86d15c6ba29 2053 TLSX_FreeAll(ssl->extensions);
Vanger 0:b86d15c6ba29 2054 #endif
Vanger 0:b86d15c6ba29 2055 #ifdef HAVE_NETX
Vanger 0:b86d15c6ba29 2056 if (ssl->nxCtx.nxPacket)
Vanger 0:b86d15c6ba29 2057 nx_packet_release(ssl->nxCtx.nxPacket);
Vanger 0:b86d15c6ba29 2058 #endif
Vanger 0:b86d15c6ba29 2059 }
Vanger 0:b86d15c6ba29 2060
Vanger 0:b86d15c6ba29 2061
Vanger 0:b86d15c6ba29 2062 /* Free any handshake resources no longer needed */
Vanger 0:b86d15c6ba29 2063 void FreeHandshakeResources(CYASSL* ssl)
Vanger 0:b86d15c6ba29 2064 {
Vanger 0:b86d15c6ba29 2065
Vanger 0:b86d15c6ba29 2066 #ifdef HAVE_SECURE_RENEGOTIATION
Vanger 0:b86d15c6ba29 2067 if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
Vanger 0:b86d15c6ba29 2068 CYASSL_MSG("Secure Renegotiation needs to retain handshake resources");
Vanger 0:b86d15c6ba29 2069 return;
Vanger 0:b86d15c6ba29 2070 }
Vanger 0:b86d15c6ba29 2071 #endif
Vanger 0:b86d15c6ba29 2072
Vanger 0:b86d15c6ba29 2073 /* input buffer */
Vanger 0:b86d15c6ba29 2074 if (ssl->buffers.inputBuffer.dynamicFlag)
Vanger 0:b86d15c6ba29 2075 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
Vanger 0:b86d15c6ba29 2076
Vanger 0:b86d15c6ba29 2077 /* suites */
Vanger 0:b86d15c6ba29 2078 XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
Vanger 0:b86d15c6ba29 2079 ssl->suites = NULL;
Vanger 0:b86d15c6ba29 2080
Vanger 0:b86d15c6ba29 2081 /* RNG */
Vanger 0:b86d15c6ba29 2082 if (ssl->specs.cipher_type == stream || ssl->options.tls1_1 == 0) {
Vanger 0:b86d15c6ba29 2083 #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
Vanger 0:b86d15c6ba29 2084 FreeRng(ssl->rng);
Vanger 0:b86d15c6ba29 2085 #endif
Vanger 0:b86d15c6ba29 2086 XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
Vanger 0:b86d15c6ba29 2087 ssl->rng = NULL;
Vanger 0:b86d15c6ba29 2088 }
Vanger 0:b86d15c6ba29 2089
Vanger 0:b86d15c6ba29 2090 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 2091 /* DTLS_POOL */
Vanger 0:b86d15c6ba29 2092 if (ssl->options.dtls && ssl->dtls_pool != NULL) {
Vanger 0:b86d15c6ba29 2093 DtlsPoolReset(ssl);
Vanger 0:b86d15c6ba29 2094 XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
Vanger 0:b86d15c6ba29 2095 ssl->dtls_pool = NULL;
Vanger 0:b86d15c6ba29 2096 }
Vanger 0:b86d15c6ba29 2097 #endif
Vanger 0:b86d15c6ba29 2098
Vanger 0:b86d15c6ba29 2099 /* arrays */
Vanger 0:b86d15c6ba29 2100 if (ssl->options.saveArrays)
Vanger 0:b86d15c6ba29 2101 FreeArrays(ssl, 1);
Vanger 0:b86d15c6ba29 2102
Vanger 0:b86d15c6ba29 2103 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 2104 /* peerRsaKey */
Vanger 0:b86d15c6ba29 2105 if (ssl->peerRsaKey) {
Vanger 0:b86d15c6ba29 2106 FreeRsaKey(ssl->peerRsaKey);
Vanger 0:b86d15c6ba29 2107 XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
Vanger 0:b86d15c6ba29 2108 ssl->peerRsaKey = NULL;
Vanger 0:b86d15c6ba29 2109 }
Vanger 0:b86d15c6ba29 2110 #endif
Vanger 0:b86d15c6ba29 2111
Vanger 0:b86d15c6ba29 2112 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 2113 if (ssl->peerEccKey)
Vanger 0:b86d15c6ba29 2114 {
Vanger 0:b86d15c6ba29 2115 if (ssl->peerEccKeyPresent) {
Vanger 0:b86d15c6ba29 2116 ecc_free(ssl->peerEccKey);
Vanger 0:b86d15c6ba29 2117 ssl->peerEccKeyPresent = 0;
Vanger 0:b86d15c6ba29 2118 }
Vanger 0:b86d15c6ba29 2119 XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
Vanger 0:b86d15c6ba29 2120 ssl->peerEccKey = NULL;
Vanger 0:b86d15c6ba29 2121 }
Vanger 0:b86d15c6ba29 2122 if (ssl->peerEccDsaKey)
Vanger 0:b86d15c6ba29 2123 {
Vanger 0:b86d15c6ba29 2124 if (ssl->peerEccDsaKeyPresent) {
Vanger 0:b86d15c6ba29 2125 ecc_free(ssl->peerEccDsaKey);
Vanger 0:b86d15c6ba29 2126 ssl->peerEccDsaKeyPresent = 0;
Vanger 0:b86d15c6ba29 2127 }
Vanger 0:b86d15c6ba29 2128 XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
Vanger 0:b86d15c6ba29 2129 ssl->peerEccDsaKey = NULL;
Vanger 0:b86d15c6ba29 2130 }
Vanger 0:b86d15c6ba29 2131 if (ssl->eccTempKey)
Vanger 0:b86d15c6ba29 2132 {
Vanger 0:b86d15c6ba29 2133 if (ssl->eccTempKeyPresent) {
Vanger 0:b86d15c6ba29 2134 ecc_free(ssl->eccTempKey);
Vanger 0:b86d15c6ba29 2135 ssl->eccTempKeyPresent = 0;
Vanger 0:b86d15c6ba29 2136 }
Vanger 0:b86d15c6ba29 2137 XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
Vanger 0:b86d15c6ba29 2138 ssl->eccTempKey = NULL;
Vanger 0:b86d15c6ba29 2139 }
Vanger 0:b86d15c6ba29 2140 if (ssl->eccDsaKey)
Vanger 0:b86d15c6ba29 2141 {
Vanger 0:b86d15c6ba29 2142 if (ssl->eccDsaKeyPresent) {
Vanger 0:b86d15c6ba29 2143 ecc_free(ssl->eccDsaKey);
Vanger 0:b86d15c6ba29 2144 ssl->eccDsaKeyPresent = 0;
Vanger 0:b86d15c6ba29 2145 }
Vanger 0:b86d15c6ba29 2146 XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
Vanger 0:b86d15c6ba29 2147 ssl->eccDsaKey = NULL;
Vanger 0:b86d15c6ba29 2148 }
Vanger 0:b86d15c6ba29 2149 #endif
Vanger 0:b86d15c6ba29 2150 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 2151 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 2152 XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
Vanger 0:b86d15c6ba29 2153 ssl->buffers.peerEccDsaKey.buffer = NULL;
Vanger 0:b86d15c6ba29 2154 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 2155 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 2156 XFREE(ssl->buffers.peerRsaKey.buffer, ssl->heap, DYNAMIC_TYPE_RSA);
Vanger 0:b86d15c6ba29 2157 ssl->buffers.peerRsaKey.buffer = NULL;
Vanger 0:b86d15c6ba29 2158 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 2159 #endif /* HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 2160 }
Vanger 0:b86d15c6ba29 2161
Vanger 0:b86d15c6ba29 2162
Vanger 0:b86d15c6ba29 2163 void FreeSSL(CYASSL* ssl)
Vanger 0:b86d15c6ba29 2164 {
Vanger 0:b86d15c6ba29 2165 FreeSSL_Ctx(ssl->ctx); /* will decrement and free underyling CTX if 0 */
Vanger 0:b86d15c6ba29 2166 SSL_ResourceFree(ssl);
Vanger 0:b86d15c6ba29 2167 XFREE(ssl, ssl->heap, DYNAMIC_TYPE_SSL);
Vanger 0:b86d15c6ba29 2168 }
Vanger 0:b86d15c6ba29 2169
Vanger 0:b86d15c6ba29 2170
Vanger 0:b86d15c6ba29 2171 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 2172
Vanger 0:b86d15c6ba29 2173 int DtlsPoolInit(CYASSL* ssl)
Vanger 0:b86d15c6ba29 2174 {
Vanger 0:b86d15c6ba29 2175 if (ssl->dtls_pool == NULL) {
Vanger 0:b86d15c6ba29 2176 DtlsPool *pool = (DtlsPool*)XMALLOC(sizeof(DtlsPool),
Vanger 0:b86d15c6ba29 2177 ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
Vanger 0:b86d15c6ba29 2178 if (pool == NULL) {
Vanger 0:b86d15c6ba29 2179 CYASSL_MSG("DTLS Buffer Pool Memory error");
Vanger 0:b86d15c6ba29 2180 return MEMORY_E;
Vanger 0:b86d15c6ba29 2181 }
Vanger 0:b86d15c6ba29 2182 else {
Vanger 0:b86d15c6ba29 2183 int i;
Vanger 0:b86d15c6ba29 2184
Vanger 0:b86d15c6ba29 2185 for (i = 0; i < DTLS_POOL_SZ; i++) {
Vanger 0:b86d15c6ba29 2186 pool->buf[i].length = 0;
Vanger 0:b86d15c6ba29 2187 pool->buf[i].buffer = NULL;
Vanger 0:b86d15c6ba29 2188 }
Vanger 0:b86d15c6ba29 2189 pool->used = 0;
Vanger 0:b86d15c6ba29 2190 ssl->dtls_pool = pool;
Vanger 0:b86d15c6ba29 2191 }
Vanger 0:b86d15c6ba29 2192 }
Vanger 0:b86d15c6ba29 2193 return 0;
Vanger 0:b86d15c6ba29 2194 }
Vanger 0:b86d15c6ba29 2195
Vanger 0:b86d15c6ba29 2196
Vanger 0:b86d15c6ba29 2197 int DtlsPoolSave(CYASSL* ssl, const byte *src, int sz)
Vanger 0:b86d15c6ba29 2198 {
Vanger 0:b86d15c6ba29 2199 DtlsPool *pool = ssl->dtls_pool;
Vanger 0:b86d15c6ba29 2200 if (pool != NULL && pool->used < DTLS_POOL_SZ) {
Vanger 0:b86d15c6ba29 2201 buffer *pBuf = &pool->buf[pool->used];
Vanger 0:b86d15c6ba29 2202 pBuf->buffer = (byte*)XMALLOC(sz, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
Vanger 0:b86d15c6ba29 2203 if (pBuf->buffer == NULL) {
Vanger 0:b86d15c6ba29 2204 CYASSL_MSG("DTLS Buffer Memory error");
Vanger 0:b86d15c6ba29 2205 return MEMORY_ERROR;
Vanger 0:b86d15c6ba29 2206 }
Vanger 0:b86d15c6ba29 2207 XMEMCPY(pBuf->buffer, src, sz);
Vanger 0:b86d15c6ba29 2208 pBuf->length = (word32)sz;
Vanger 0:b86d15c6ba29 2209 pool->used++;
Vanger 0:b86d15c6ba29 2210 }
Vanger 0:b86d15c6ba29 2211 return 0;
Vanger 0:b86d15c6ba29 2212 }
Vanger 0:b86d15c6ba29 2213
Vanger 0:b86d15c6ba29 2214
Vanger 0:b86d15c6ba29 2215 void DtlsPoolReset(CYASSL* ssl)
Vanger 0:b86d15c6ba29 2216 {
Vanger 0:b86d15c6ba29 2217 DtlsPool *pool = ssl->dtls_pool;
Vanger 0:b86d15c6ba29 2218 if (pool != NULL) {
Vanger 0:b86d15c6ba29 2219 buffer *pBuf;
Vanger 0:b86d15c6ba29 2220 int i, used;
Vanger 0:b86d15c6ba29 2221
Vanger 0:b86d15c6ba29 2222 used = pool->used;
Vanger 0:b86d15c6ba29 2223 for (i = 0, pBuf = &pool->buf[0]; i < used; i++, pBuf++) {
Vanger 0:b86d15c6ba29 2224 XFREE(pBuf->buffer, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
Vanger 0:b86d15c6ba29 2225 pBuf->buffer = NULL;
Vanger 0:b86d15c6ba29 2226 pBuf->length = 0;
Vanger 0:b86d15c6ba29 2227 }
Vanger 0:b86d15c6ba29 2228 pool->used = 0;
Vanger 0:b86d15c6ba29 2229 }
Vanger 0:b86d15c6ba29 2230 ssl->dtls_timeout = ssl->dtls_timeout_init;
Vanger 0:b86d15c6ba29 2231 }
Vanger 0:b86d15c6ba29 2232
Vanger 0:b86d15c6ba29 2233
Vanger 0:b86d15c6ba29 2234 int DtlsPoolTimeout(CYASSL* ssl)
Vanger 0:b86d15c6ba29 2235 {
Vanger 0:b86d15c6ba29 2236 int result = -1;
Vanger 0:b86d15c6ba29 2237 if (ssl->dtls_timeout < ssl->dtls_timeout_max) {
Vanger 0:b86d15c6ba29 2238 ssl->dtls_timeout *= DTLS_TIMEOUT_MULTIPLIER;
Vanger 0:b86d15c6ba29 2239 result = 0;
Vanger 0:b86d15c6ba29 2240 }
Vanger 0:b86d15c6ba29 2241 return result;
Vanger 0:b86d15c6ba29 2242 }
Vanger 0:b86d15c6ba29 2243
Vanger 0:b86d15c6ba29 2244
Vanger 0:b86d15c6ba29 2245 int DtlsPoolSend(CYASSL* ssl)
Vanger 0:b86d15c6ba29 2246 {
Vanger 0:b86d15c6ba29 2247 int ret;
Vanger 0:b86d15c6ba29 2248 DtlsPool *pool = ssl->dtls_pool;
Vanger 0:b86d15c6ba29 2249
Vanger 0:b86d15c6ba29 2250 if (pool != NULL && pool->used > 0) {
Vanger 0:b86d15c6ba29 2251 int i;
Vanger 0:b86d15c6ba29 2252 for (i = 0; i < pool->used; i++) {
Vanger 0:b86d15c6ba29 2253 int sendResult;
Vanger 0:b86d15c6ba29 2254 buffer* buf = &pool->buf[i];
Vanger 0:b86d15c6ba29 2255
Vanger 0:b86d15c6ba29 2256 DtlsRecordLayerHeader* dtls = (DtlsRecordLayerHeader*)buf->buffer;
Vanger 0:b86d15c6ba29 2257
Vanger 0:b86d15c6ba29 2258 word16 message_epoch;
Vanger 0:b86d15c6ba29 2259 ato16(dtls->epoch, &message_epoch);
Vanger 0:b86d15c6ba29 2260 if (message_epoch == ssl->keys.dtls_epoch) {
Vanger 0:b86d15c6ba29 2261 /* Increment record sequence number on retransmitted handshake
Vanger 0:b86d15c6ba29 2262 * messages */
Vanger 0:b86d15c6ba29 2263 c32to48(ssl->keys.dtls_sequence_number, dtls->sequence_number);
Vanger 0:b86d15c6ba29 2264 ssl->keys.dtls_sequence_number++;
Vanger 0:b86d15c6ba29 2265 }
Vanger 0:b86d15c6ba29 2266 else {
Vanger 0:b86d15c6ba29 2267 /* The Finished message is sent with the next epoch, keep its
Vanger 0:b86d15c6ba29 2268 * sequence number */
Vanger 0:b86d15c6ba29 2269 }
Vanger 0:b86d15c6ba29 2270
Vanger 0:b86d15c6ba29 2271 if ((ret = CheckAvailableSize(ssl, buf->length)) != 0)
Vanger 0:b86d15c6ba29 2272 return ret;
Vanger 0:b86d15c6ba29 2273
Vanger 0:b86d15c6ba29 2274 XMEMCPY(ssl->buffers.outputBuffer.buffer, buf->buffer, buf->length);
Vanger 0:b86d15c6ba29 2275 ssl->buffers.outputBuffer.idx = 0;
Vanger 0:b86d15c6ba29 2276 ssl->buffers.outputBuffer.length = buf->length;
Vanger 0:b86d15c6ba29 2277
Vanger 0:b86d15c6ba29 2278 sendResult = SendBuffered(ssl);
Vanger 0:b86d15c6ba29 2279 if (sendResult < 0) {
Vanger 0:b86d15c6ba29 2280 return sendResult;
Vanger 0:b86d15c6ba29 2281 }
Vanger 0:b86d15c6ba29 2282 }
Vanger 0:b86d15c6ba29 2283 }
Vanger 0:b86d15c6ba29 2284 return 0;
Vanger 0:b86d15c6ba29 2285 }
Vanger 0:b86d15c6ba29 2286
Vanger 0:b86d15c6ba29 2287
Vanger 0:b86d15c6ba29 2288 /* functions for managing DTLS datagram reordering */
Vanger 0:b86d15c6ba29 2289
Vanger 0:b86d15c6ba29 2290 /* Need to allocate space for the handshake message header. The hashing
Vanger 0:b86d15c6ba29 2291 * routines assume the message pointer is still within the buffer that
Vanger 0:b86d15c6ba29 2292 * has the headers, and will include those headers in the hash. The store
Vanger 0:b86d15c6ba29 2293 * routines need to take that into account as well. New will allocate
Vanger 0:b86d15c6ba29 2294 * extra space for the headers. */
Vanger 0:b86d15c6ba29 2295 DtlsMsg* DtlsMsgNew(word32 sz, void* heap)
Vanger 0:b86d15c6ba29 2296 {
Vanger 0:b86d15c6ba29 2297 DtlsMsg* msg = NULL;
Vanger 0:b86d15c6ba29 2298
Vanger 0:b86d15c6ba29 2299 msg = (DtlsMsg*)XMALLOC(sizeof(DtlsMsg), heap, DYNAMIC_TYPE_DTLS_MSG);
Vanger 0:b86d15c6ba29 2300
Vanger 0:b86d15c6ba29 2301 if (msg != NULL) {
Vanger 0:b86d15c6ba29 2302 msg->buf = (byte*)XMALLOC(sz + DTLS_HANDSHAKE_HEADER_SZ,
Vanger 0:b86d15c6ba29 2303 heap, DYNAMIC_TYPE_NONE);
Vanger 0:b86d15c6ba29 2304 if (msg->buf != NULL) {
Vanger 0:b86d15c6ba29 2305 msg->next = NULL;
Vanger 0:b86d15c6ba29 2306 msg->seq = 0;
Vanger 0:b86d15c6ba29 2307 msg->sz = sz;
Vanger 0:b86d15c6ba29 2308 msg->fragSz = 0;
Vanger 0:b86d15c6ba29 2309 msg->msg = msg->buf + DTLS_HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 2310 }
Vanger 0:b86d15c6ba29 2311 else {
Vanger 0:b86d15c6ba29 2312 XFREE(msg, heap, DYNAMIC_TYPE_DTLS_MSG);
Vanger 0:b86d15c6ba29 2313 msg = NULL;
Vanger 0:b86d15c6ba29 2314 }
Vanger 0:b86d15c6ba29 2315 }
Vanger 0:b86d15c6ba29 2316
Vanger 0:b86d15c6ba29 2317 return msg;
Vanger 0:b86d15c6ba29 2318 }
Vanger 0:b86d15c6ba29 2319
Vanger 0:b86d15c6ba29 2320 void DtlsMsgDelete(DtlsMsg* item, void* heap)
Vanger 0:b86d15c6ba29 2321 {
Vanger 0:b86d15c6ba29 2322 (void)heap;
Vanger 0:b86d15c6ba29 2323
Vanger 0:b86d15c6ba29 2324 if (item != NULL) {
Vanger 0:b86d15c6ba29 2325 if (item->buf != NULL)
Vanger 0:b86d15c6ba29 2326 XFREE(item->buf, heap, DYNAMIC_TYPE_NONE);
Vanger 0:b86d15c6ba29 2327 XFREE(item, heap, DYNAMIC_TYPE_DTLS_MSG);
Vanger 0:b86d15c6ba29 2328 }
Vanger 0:b86d15c6ba29 2329 }
Vanger 0:b86d15c6ba29 2330
Vanger 0:b86d15c6ba29 2331
Vanger 0:b86d15c6ba29 2332 void DtlsMsgListDelete(DtlsMsg* head, void* heap)
Vanger 0:b86d15c6ba29 2333 {
Vanger 0:b86d15c6ba29 2334 DtlsMsg* next;
Vanger 0:b86d15c6ba29 2335 while (head) {
Vanger 0:b86d15c6ba29 2336 next = head->next;
Vanger 0:b86d15c6ba29 2337 DtlsMsgDelete(head, heap);
Vanger 0:b86d15c6ba29 2338 head = next;
Vanger 0:b86d15c6ba29 2339 }
Vanger 0:b86d15c6ba29 2340 }
Vanger 0:b86d15c6ba29 2341
Vanger 0:b86d15c6ba29 2342
Vanger 0:b86d15c6ba29 2343 void DtlsMsgSet(DtlsMsg* msg, word32 seq, const byte* data, byte type,
Vanger 0:b86d15c6ba29 2344 word32 fragOffset, word32 fragSz)
Vanger 0:b86d15c6ba29 2345 {
Vanger 0:b86d15c6ba29 2346 if (msg != NULL && data != NULL && msg->fragSz <= msg->sz &&
Vanger 0:b86d15c6ba29 2347 fragOffset < msg->sz && (fragOffset + fragSz) <= msg->sz) {
Vanger 0:b86d15c6ba29 2348
Vanger 0:b86d15c6ba29 2349 msg->seq = seq;
Vanger 0:b86d15c6ba29 2350 msg->type = type;
Vanger 0:b86d15c6ba29 2351 msg->fragSz += fragSz;
Vanger 0:b86d15c6ba29 2352 /* If fragOffset is zero, this is either a full message that is out
Vanger 0:b86d15c6ba29 2353 * of order, or the first fragment of a fragmented message. Copy the
Vanger 0:b86d15c6ba29 2354 * handshake message header as well as the message data. */
Vanger 0:b86d15c6ba29 2355 if (fragOffset == 0)
Vanger 0:b86d15c6ba29 2356 XMEMCPY(msg->buf, data - DTLS_HANDSHAKE_HEADER_SZ,
Vanger 0:b86d15c6ba29 2357 fragSz + DTLS_HANDSHAKE_HEADER_SZ);
Vanger 0:b86d15c6ba29 2358 else {
Vanger 0:b86d15c6ba29 2359 /* If fragOffet is non-zero, this is an additional fragment that
Vanger 0:b86d15c6ba29 2360 * needs to be copied to its location in the message buffer. Also
Vanger 0:b86d15c6ba29 2361 * copy the total size of the message over the fragment size. The
Vanger 0:b86d15c6ba29 2362 * hash routines look at a defragmented message if it had actually
Vanger 0:b86d15c6ba29 2363 * come across as a single handshake message. */
Vanger 0:b86d15c6ba29 2364 XMEMCPY(msg->msg + fragOffset, data, fragSz);
Vanger 0:b86d15c6ba29 2365 c32to24(msg->sz, msg->msg - DTLS_HANDSHAKE_FRAG_SZ);
Vanger 0:b86d15c6ba29 2366 }
Vanger 0:b86d15c6ba29 2367 }
Vanger 0:b86d15c6ba29 2368 }
Vanger 0:b86d15c6ba29 2369
Vanger 0:b86d15c6ba29 2370
Vanger 0:b86d15c6ba29 2371 DtlsMsg* DtlsMsgFind(DtlsMsg* head, word32 seq)
Vanger 0:b86d15c6ba29 2372 {
Vanger 0:b86d15c6ba29 2373 while (head != NULL && head->seq != seq) {
Vanger 0:b86d15c6ba29 2374 head = head->next;
Vanger 0:b86d15c6ba29 2375 }
Vanger 0:b86d15c6ba29 2376 return head;
Vanger 0:b86d15c6ba29 2377 }
Vanger 0:b86d15c6ba29 2378
Vanger 0:b86d15c6ba29 2379
Vanger 0:b86d15c6ba29 2380 DtlsMsg* DtlsMsgStore(DtlsMsg* head, word32 seq, const byte* data,
Vanger 0:b86d15c6ba29 2381 word32 dataSz, byte type, word32 fragOffset, word32 fragSz, void* heap)
Vanger 0:b86d15c6ba29 2382 {
Vanger 0:b86d15c6ba29 2383
Vanger 0:b86d15c6ba29 2384 /* See if seq exists in the list. If it isn't in the list, make
Vanger 0:b86d15c6ba29 2385 * a new item of size dataSz, copy fragSz bytes from data to msg->msg
Vanger 0:b86d15c6ba29 2386 * starting at offset fragOffset, and add fragSz to msg->fragSz. If
Vanger 0:b86d15c6ba29 2387 * the seq is in the list and it isn't full, copy fragSz bytes from
Vanger 0:b86d15c6ba29 2388 * data to msg->msg starting at offset fragOffset, and add fragSz to
Vanger 0:b86d15c6ba29 2389 * msg->fragSz. The new item should be inserted into the list in its
Vanger 0:b86d15c6ba29 2390 * proper position.
Vanger 0:b86d15c6ba29 2391 *
Vanger 0:b86d15c6ba29 2392 * 1. Find seq in list, or where seq should go in list. If seq not in
Vanger 0:b86d15c6ba29 2393 * list, create new item and insert into list. Either case, keep
Vanger 0:b86d15c6ba29 2394 * pointer to item.
Vanger 0:b86d15c6ba29 2395 * 2. If msg->fragSz + fragSz < sz, copy data to msg->msg at offset
Vanger 0:b86d15c6ba29 2396 * fragOffset. Add fragSz to msg->fragSz.
Vanger 0:b86d15c6ba29 2397 */
Vanger 0:b86d15c6ba29 2398
Vanger 0:b86d15c6ba29 2399 if (head != NULL) {
Vanger 0:b86d15c6ba29 2400 DtlsMsg* cur = DtlsMsgFind(head, seq);
Vanger 0:b86d15c6ba29 2401 if (cur == NULL) {
Vanger 0:b86d15c6ba29 2402 cur = DtlsMsgNew(dataSz, heap);
Vanger 0:b86d15c6ba29 2403 if (cur != NULL) {
Vanger 0:b86d15c6ba29 2404 DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz);
Vanger 0:b86d15c6ba29 2405 head = DtlsMsgInsert(head, cur);
Vanger 0:b86d15c6ba29 2406 }
Vanger 0:b86d15c6ba29 2407 }
Vanger 0:b86d15c6ba29 2408 else {
Vanger 0:b86d15c6ba29 2409 DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz);
Vanger 0:b86d15c6ba29 2410 }
Vanger 0:b86d15c6ba29 2411 }
Vanger 0:b86d15c6ba29 2412 else {
Vanger 0:b86d15c6ba29 2413 head = DtlsMsgNew(dataSz, heap);
Vanger 0:b86d15c6ba29 2414 DtlsMsgSet(head, seq, data, type, fragOffset, fragSz);
Vanger 0:b86d15c6ba29 2415 }
Vanger 0:b86d15c6ba29 2416
Vanger 0:b86d15c6ba29 2417 return head;
Vanger 0:b86d15c6ba29 2418 }
Vanger 0:b86d15c6ba29 2419
Vanger 0:b86d15c6ba29 2420
Vanger 0:b86d15c6ba29 2421 /* DtlsMsgInsert() is an in-order insert. */
Vanger 0:b86d15c6ba29 2422 DtlsMsg* DtlsMsgInsert(DtlsMsg* head, DtlsMsg* item)
Vanger 0:b86d15c6ba29 2423 {
Vanger 0:b86d15c6ba29 2424 if (head == NULL || item->seq < head->seq) {
Vanger 0:b86d15c6ba29 2425 item->next = head;
Vanger 0:b86d15c6ba29 2426 head = item;
Vanger 0:b86d15c6ba29 2427 }
Vanger 0:b86d15c6ba29 2428 else if (head->next == NULL) {
Vanger 0:b86d15c6ba29 2429 head->next = item;
Vanger 0:b86d15c6ba29 2430 }
Vanger 0:b86d15c6ba29 2431 else {
Vanger 0:b86d15c6ba29 2432 DtlsMsg* cur = head->next;
Vanger 0:b86d15c6ba29 2433 DtlsMsg* prev = head;
Vanger 0:b86d15c6ba29 2434 while (cur) {
Vanger 0:b86d15c6ba29 2435 if (item->seq < cur->seq) {
Vanger 0:b86d15c6ba29 2436 item->next = cur;
Vanger 0:b86d15c6ba29 2437 prev->next = item;
Vanger 0:b86d15c6ba29 2438 break;
Vanger 0:b86d15c6ba29 2439 }
Vanger 0:b86d15c6ba29 2440 prev = cur;
Vanger 0:b86d15c6ba29 2441 cur = cur->next;
Vanger 0:b86d15c6ba29 2442 }
Vanger 0:b86d15c6ba29 2443 if (cur == NULL) {
Vanger 0:b86d15c6ba29 2444 prev->next = item;
Vanger 0:b86d15c6ba29 2445 }
Vanger 0:b86d15c6ba29 2446 }
Vanger 0:b86d15c6ba29 2447
Vanger 0:b86d15c6ba29 2448 return head;
Vanger 0:b86d15c6ba29 2449 }
Vanger 0:b86d15c6ba29 2450
Vanger 0:b86d15c6ba29 2451 #endif /* CYASSL_DTLS */
Vanger 0:b86d15c6ba29 2452
Vanger 0:b86d15c6ba29 2453 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 2454
Vanger 0:b86d15c6ba29 2455 ProtocolVersion MakeSSLv3(void)
Vanger 0:b86d15c6ba29 2456 {
Vanger 0:b86d15c6ba29 2457 ProtocolVersion pv;
Vanger 0:b86d15c6ba29 2458 pv.major = SSLv3_MAJOR;
Vanger 0:b86d15c6ba29 2459 pv.minor = SSLv3_MINOR;
Vanger 0:b86d15c6ba29 2460
Vanger 0:b86d15c6ba29 2461 return pv;
Vanger 0:b86d15c6ba29 2462 }
Vanger 0:b86d15c6ba29 2463
Vanger 0:b86d15c6ba29 2464 #endif /* NO_OLD_TLS */
Vanger 0:b86d15c6ba29 2465
Vanger 0:b86d15c6ba29 2466
Vanger 0:b86d15c6ba29 2467 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 2468
Vanger 0:b86d15c6ba29 2469 ProtocolVersion MakeDTLSv1(void)
Vanger 0:b86d15c6ba29 2470 {
Vanger 0:b86d15c6ba29 2471 ProtocolVersion pv;
Vanger 0:b86d15c6ba29 2472 pv.major = DTLS_MAJOR;
Vanger 0:b86d15c6ba29 2473 pv.minor = DTLS_MINOR;
Vanger 0:b86d15c6ba29 2474
Vanger 0:b86d15c6ba29 2475 return pv;
Vanger 0:b86d15c6ba29 2476 }
Vanger 0:b86d15c6ba29 2477
Vanger 0:b86d15c6ba29 2478 ProtocolVersion MakeDTLSv1_2(void)
Vanger 0:b86d15c6ba29 2479 {
Vanger 0:b86d15c6ba29 2480 ProtocolVersion pv;
Vanger 0:b86d15c6ba29 2481 pv.major = DTLS_MAJOR;
Vanger 0:b86d15c6ba29 2482 pv.minor = DTLSv1_2_MINOR;
Vanger 0:b86d15c6ba29 2483
Vanger 0:b86d15c6ba29 2484 return pv;
Vanger 0:b86d15c6ba29 2485 }
Vanger 0:b86d15c6ba29 2486
Vanger 0:b86d15c6ba29 2487 #endif /* CYASSL_DTLS */
Vanger 0:b86d15c6ba29 2488
Vanger 0:b86d15c6ba29 2489
Vanger 0:b86d15c6ba29 2490
Vanger 0:b86d15c6ba29 2491
Vanger 0:b86d15c6ba29 2492 #ifdef USE_WINDOWS_API
Vanger 0:b86d15c6ba29 2493
Vanger 0:b86d15c6ba29 2494 word32 LowResTimer(void)
Vanger 0:b86d15c6ba29 2495 {
Vanger 0:b86d15c6ba29 2496 static int init = 0;
Vanger 0:b86d15c6ba29 2497 static LARGE_INTEGER freq;
Vanger 0:b86d15c6ba29 2498 LARGE_INTEGER count;
Vanger 0:b86d15c6ba29 2499
Vanger 0:b86d15c6ba29 2500 if (!init) {
Vanger 0:b86d15c6ba29 2501 QueryPerformanceFrequency(&freq);
Vanger 0:b86d15c6ba29 2502 init = 1;
Vanger 0:b86d15c6ba29 2503 }
Vanger 0:b86d15c6ba29 2504
Vanger 0:b86d15c6ba29 2505 QueryPerformanceCounter(&count);
Vanger 0:b86d15c6ba29 2506
Vanger 0:b86d15c6ba29 2507 return (word32)(count.QuadPart / freq.QuadPart);
Vanger 0:b86d15c6ba29 2508 }
Vanger 0:b86d15c6ba29 2509
Vanger 0:b86d15c6ba29 2510 #elif defined(HAVE_RTP_SYS)
Vanger 0:b86d15c6ba29 2511
Vanger 0:b86d15c6ba29 2512 #include "rtptime.h"
Vanger 0:b86d15c6ba29 2513
Vanger 0:b86d15c6ba29 2514 word32 LowResTimer(void)
Vanger 0:b86d15c6ba29 2515 {
Vanger 0:b86d15c6ba29 2516 return (word32)rtp_get_system_sec();
Vanger 0:b86d15c6ba29 2517 }
Vanger 0:b86d15c6ba29 2518
Vanger 0:b86d15c6ba29 2519
Vanger 0:b86d15c6ba29 2520 #elif defined(MICRIUM)
Vanger 0:b86d15c6ba29 2521
Vanger 0:b86d15c6ba29 2522 word32 LowResTimer(void)
Vanger 0:b86d15c6ba29 2523 {
Vanger 0:b86d15c6ba29 2524 NET_SECURE_OS_TICK clk;
Vanger 0:b86d15c6ba29 2525
Vanger 0:b86d15c6ba29 2526 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
Vanger 0:b86d15c6ba29 2527 clk = NetSecure_OS_TimeGet();
Vanger 0:b86d15c6ba29 2528 #endif
Vanger 0:b86d15c6ba29 2529 return (word32)clk;
Vanger 0:b86d15c6ba29 2530 }
Vanger 0:b86d15c6ba29 2531
Vanger 0:b86d15c6ba29 2532
Vanger 0:b86d15c6ba29 2533 #elif defined(MICROCHIP_TCPIP_V5)
Vanger 0:b86d15c6ba29 2534
Vanger 0:b86d15c6ba29 2535 word32 LowResTimer(void)
Vanger 0:b86d15c6ba29 2536 {
Vanger 0:b86d15c6ba29 2537 return (word32) TickGet();
Vanger 0:b86d15c6ba29 2538 }
Vanger 0:b86d15c6ba29 2539
Vanger 0:b86d15c6ba29 2540
Vanger 0:b86d15c6ba29 2541 #elif defined(MICROCHIP_TCPIP)
Vanger 0:b86d15c6ba29 2542
Vanger 0:b86d15c6ba29 2543 #if defined(MICROCHIP_MPLAB_HARMONY)
Vanger 0:b86d15c6ba29 2544
Vanger 0:b86d15c6ba29 2545 #include <system/tmr/sys_tmr.h>
Vanger 0:b86d15c6ba29 2546
Vanger 0:b86d15c6ba29 2547 word32 LowResTimer(void)
Vanger 0:b86d15c6ba29 2548 {
Vanger 0:b86d15c6ba29 2549 return (word32) SYS_TMR_TickCountGet();
Vanger 0:b86d15c6ba29 2550 }
Vanger 0:b86d15c6ba29 2551
Vanger 0:b86d15c6ba29 2552 #else
Vanger 0:b86d15c6ba29 2553
Vanger 0:b86d15c6ba29 2554 word32 LowResTimer(void)
Vanger 0:b86d15c6ba29 2555 {
Vanger 0:b86d15c6ba29 2556 return (word32) SYS_TICK_Get();
Vanger 0:b86d15c6ba29 2557 }
Vanger 0:b86d15c6ba29 2558
Vanger 0:b86d15c6ba29 2559 #endif
Vanger 0:b86d15c6ba29 2560
Vanger 0:b86d15c6ba29 2561 #elif defined(FREESCALE_MQX)
Vanger 0:b86d15c6ba29 2562
Vanger 0:b86d15c6ba29 2563 word32 LowResTimer(void)
Vanger 0:b86d15c6ba29 2564 {
Vanger 0:b86d15c6ba29 2565 TIME_STRUCT mqxTime;
Vanger 0:b86d15c6ba29 2566
Vanger 0:b86d15c6ba29 2567 _time_get_elapsed(&mqxTime);
Vanger 0:b86d15c6ba29 2568
Vanger 0:b86d15c6ba29 2569 return (word32) mqxTime.SECONDS;
Vanger 0:b86d15c6ba29 2570 }
Vanger 0:b86d15c6ba29 2571
Vanger 0:b86d15c6ba29 2572 #elif defined(CYASSL_TIRTOS)
Vanger 0:b86d15c6ba29 2573
Vanger 0:b86d15c6ba29 2574 word32 LowResTimer(void)
Vanger 0:b86d15c6ba29 2575 {
Vanger 0:b86d15c6ba29 2576 return (word32) MYTIME_gettime();
Vanger 0:b86d15c6ba29 2577 }
Vanger 0:b86d15c6ba29 2578
Vanger 0:b86d15c6ba29 2579 #elif defined(USER_TICKS)
Vanger 0:b86d15c6ba29 2580 #if 0
Vanger 0:b86d15c6ba29 2581 word32 LowResTimer(void)
Vanger 0:b86d15c6ba29 2582 {
Vanger 0:b86d15c6ba29 2583 /*
Vanger 0:b86d15c6ba29 2584 write your own clock tick function if don't want time(0)
Vanger 0:b86d15c6ba29 2585 needs second accuracy but doesn't have to correlated to EPOCH
Vanger 0:b86d15c6ba29 2586 */
Vanger 0:b86d15c6ba29 2587 }
Vanger 0:b86d15c6ba29 2588 #endif
Vanger 0:b86d15c6ba29 2589 #else /* !USE_WINDOWS_API && !HAVE_RTP_SYS && !MICRIUM && !USER_TICKS */
Vanger 0:b86d15c6ba29 2590
Vanger 0:b86d15c6ba29 2591 #include <time.h>
Vanger 0:b86d15c6ba29 2592
Vanger 0:b86d15c6ba29 2593 word32 LowResTimer(void)
Vanger 0:b86d15c6ba29 2594 {
Vanger 0:b86d15c6ba29 2595 return (word32)time(0);
Vanger 0:b86d15c6ba29 2596 }
Vanger 0:b86d15c6ba29 2597
Vanger 0:b86d15c6ba29 2598
Vanger 0:b86d15c6ba29 2599 #endif /* USE_WINDOWS_API */
Vanger 0:b86d15c6ba29 2600
Vanger 0:b86d15c6ba29 2601
Vanger 0:b86d15c6ba29 2602 /* add output to md5 and sha handshake hashes, exclude record header */
Vanger 0:b86d15c6ba29 2603 static int HashOutput(CYASSL* ssl, const byte* output, int sz, int ivSz)
Vanger 0:b86d15c6ba29 2604 {
Vanger 0:b86d15c6ba29 2605 const byte* adj = output + RECORD_HEADER_SZ + ivSz;
Vanger 0:b86d15c6ba29 2606 sz -= RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 2607
Vanger 0:b86d15c6ba29 2608 #ifdef HAVE_FUZZER
Vanger 0:b86d15c6ba29 2609 if (ssl->fuzzerCb)
Vanger 0:b86d15c6ba29 2610 ssl->fuzzerCb(ssl, output, sz, FUZZ_HASH, ssl->fuzzerCtx);
Vanger 0:b86d15c6ba29 2611 #endif
Vanger 0:b86d15c6ba29 2612 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 2613 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 2614 adj += DTLS_RECORD_EXTRA;
Vanger 0:b86d15c6ba29 2615 sz -= DTLS_RECORD_EXTRA;
Vanger 0:b86d15c6ba29 2616 }
Vanger 0:b86d15c6ba29 2617 #endif
Vanger 0:b86d15c6ba29 2618 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 2619 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 2620 ShaUpdate(&ssl->hashSha, adj, sz);
Vanger 0:b86d15c6ba29 2621 #endif
Vanger 0:b86d15c6ba29 2622 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 2623 Md5Update(&ssl->hashMd5, adj, sz);
Vanger 0:b86d15c6ba29 2624 #endif
Vanger 0:b86d15c6ba29 2625 #endif
Vanger 0:b86d15c6ba29 2626
Vanger 0:b86d15c6ba29 2627 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 2628 int ret;
Vanger 0:b86d15c6ba29 2629
Vanger 0:b86d15c6ba29 2630 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 2631 ret = Sha256Update(&ssl->hashSha256, adj, sz);
Vanger 0:b86d15c6ba29 2632 if (ret != 0)
Vanger 0:b86d15c6ba29 2633 return ret;
Vanger 0:b86d15c6ba29 2634 #endif
Vanger 0:b86d15c6ba29 2635 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 2636 ret = Sha384Update(&ssl->hashSha384, adj, sz);
Vanger 0:b86d15c6ba29 2637 if (ret != 0)
Vanger 0:b86d15c6ba29 2638 return ret;
Vanger 0:b86d15c6ba29 2639 #endif
Vanger 0:b86d15c6ba29 2640 }
Vanger 0:b86d15c6ba29 2641
Vanger 0:b86d15c6ba29 2642 return 0;
Vanger 0:b86d15c6ba29 2643 }
Vanger 0:b86d15c6ba29 2644
Vanger 0:b86d15c6ba29 2645
Vanger 0:b86d15c6ba29 2646 /* add input to md5 and sha handshake hashes, include handshake header */
Vanger 0:b86d15c6ba29 2647 static int HashInput(CYASSL* ssl, const byte* input, int sz)
Vanger 0:b86d15c6ba29 2648 {
Vanger 0:b86d15c6ba29 2649 const byte* adj = input - HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 2650 sz += HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 2651
Vanger 0:b86d15c6ba29 2652 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 2653 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 2654 adj -= DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 2655 sz += DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 2656 }
Vanger 0:b86d15c6ba29 2657 #endif
Vanger 0:b86d15c6ba29 2658
Vanger 0:b86d15c6ba29 2659 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 2660 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 2661 ShaUpdate(&ssl->hashSha, adj, sz);
Vanger 0:b86d15c6ba29 2662 #endif
Vanger 0:b86d15c6ba29 2663 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 2664 Md5Update(&ssl->hashMd5, adj, sz);
Vanger 0:b86d15c6ba29 2665 #endif
Vanger 0:b86d15c6ba29 2666 #endif
Vanger 0:b86d15c6ba29 2667
Vanger 0:b86d15c6ba29 2668 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 2669 int ret;
Vanger 0:b86d15c6ba29 2670
Vanger 0:b86d15c6ba29 2671 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 2672 ret = Sha256Update(&ssl->hashSha256, adj, sz);
Vanger 0:b86d15c6ba29 2673 if (ret != 0)
Vanger 0:b86d15c6ba29 2674 return ret;
Vanger 0:b86d15c6ba29 2675 #endif
Vanger 0:b86d15c6ba29 2676 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 2677 ret = Sha384Update(&ssl->hashSha384, adj, sz);
Vanger 0:b86d15c6ba29 2678 if (ret != 0)
Vanger 0:b86d15c6ba29 2679 return ret;
Vanger 0:b86d15c6ba29 2680 #endif
Vanger 0:b86d15c6ba29 2681 }
Vanger 0:b86d15c6ba29 2682
Vanger 0:b86d15c6ba29 2683 return 0;
Vanger 0:b86d15c6ba29 2684 }
Vanger 0:b86d15c6ba29 2685
Vanger 0:b86d15c6ba29 2686
Vanger 0:b86d15c6ba29 2687 /* add record layer header for message */
Vanger 0:b86d15c6ba29 2688 static void AddRecordHeader(byte* output, word32 length, byte type, CYASSL* ssl)
Vanger 0:b86d15c6ba29 2689 {
Vanger 0:b86d15c6ba29 2690 RecordLayerHeader* rl;
Vanger 0:b86d15c6ba29 2691
Vanger 0:b86d15c6ba29 2692 /* record layer header */
Vanger 0:b86d15c6ba29 2693 rl = (RecordLayerHeader*)output;
Vanger 0:b86d15c6ba29 2694 rl->type = type;
Vanger 0:b86d15c6ba29 2695 rl->pvMajor = ssl->version.major; /* type and version same in each */
Vanger 0:b86d15c6ba29 2696 rl->pvMinor = ssl->version.minor;
Vanger 0:b86d15c6ba29 2697
Vanger 0:b86d15c6ba29 2698 if (!ssl->options.dtls)
Vanger 0:b86d15c6ba29 2699 c16toa((word16)length, rl->length);
Vanger 0:b86d15c6ba29 2700 else {
Vanger 0:b86d15c6ba29 2701 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 2702 DtlsRecordLayerHeader* dtls;
Vanger 0:b86d15c6ba29 2703
Vanger 0:b86d15c6ba29 2704 /* dtls record layer header extensions */
Vanger 0:b86d15c6ba29 2705 dtls = (DtlsRecordLayerHeader*)output;
Vanger 0:b86d15c6ba29 2706 c16toa(ssl->keys.dtls_epoch, dtls->epoch);
Vanger 0:b86d15c6ba29 2707 c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number);
Vanger 0:b86d15c6ba29 2708 c16toa((word16)length, dtls->length);
Vanger 0:b86d15c6ba29 2709 #endif
Vanger 0:b86d15c6ba29 2710 }
Vanger 0:b86d15c6ba29 2711 }
Vanger 0:b86d15c6ba29 2712
Vanger 0:b86d15c6ba29 2713
Vanger 0:b86d15c6ba29 2714 /* add handshake header for message */
Vanger 0:b86d15c6ba29 2715 static void AddHandShakeHeader(byte* output, word32 length, byte type,
Vanger 0:b86d15c6ba29 2716 CYASSL* ssl)
Vanger 0:b86d15c6ba29 2717 {
Vanger 0:b86d15c6ba29 2718 HandShakeHeader* hs;
Vanger 0:b86d15c6ba29 2719 (void)ssl;
Vanger 0:b86d15c6ba29 2720
Vanger 0:b86d15c6ba29 2721 /* handshake header */
Vanger 0:b86d15c6ba29 2722 hs = (HandShakeHeader*)output;
Vanger 0:b86d15c6ba29 2723 hs->type = type;
Vanger 0:b86d15c6ba29 2724 c32to24(length, hs->length); /* type and length same for each */
Vanger 0:b86d15c6ba29 2725 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 2726 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 2727 DtlsHandShakeHeader* dtls;
Vanger 0:b86d15c6ba29 2728
Vanger 0:b86d15c6ba29 2729 /* dtls handshake header extensions */
Vanger 0:b86d15c6ba29 2730 dtls = (DtlsHandShakeHeader*)output;
Vanger 0:b86d15c6ba29 2731 c16toa(ssl->keys.dtls_handshake_number++, dtls->message_seq);
Vanger 0:b86d15c6ba29 2732 c32to24(0, dtls->fragment_offset);
Vanger 0:b86d15c6ba29 2733 c32to24(length, dtls->fragment_length);
Vanger 0:b86d15c6ba29 2734 }
Vanger 0:b86d15c6ba29 2735 #endif
Vanger 0:b86d15c6ba29 2736 }
Vanger 0:b86d15c6ba29 2737
Vanger 0:b86d15c6ba29 2738
Vanger 0:b86d15c6ba29 2739 /* add both headers for handshake message */
Vanger 0:b86d15c6ba29 2740 static void AddHeaders(byte* output, word32 length, byte type, CYASSL* ssl)
Vanger 0:b86d15c6ba29 2741 {
Vanger 0:b86d15c6ba29 2742 if (!ssl->options.dtls) {
Vanger 0:b86d15c6ba29 2743 AddRecordHeader(output, length + HANDSHAKE_HEADER_SZ, handshake, ssl);
Vanger 0:b86d15c6ba29 2744 AddHandShakeHeader(output + RECORD_HEADER_SZ, length, type, ssl);
Vanger 0:b86d15c6ba29 2745 }
Vanger 0:b86d15c6ba29 2746 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 2747 else {
Vanger 0:b86d15c6ba29 2748 AddRecordHeader(output, length+DTLS_HANDSHAKE_HEADER_SZ, handshake,ssl);
Vanger 0:b86d15c6ba29 2749 AddHandShakeHeader(output + DTLS_RECORD_HEADER_SZ, length, type, ssl);
Vanger 0:b86d15c6ba29 2750 }
Vanger 0:b86d15c6ba29 2751 #endif
Vanger 0:b86d15c6ba29 2752 }
Vanger 0:b86d15c6ba29 2753
Vanger 0:b86d15c6ba29 2754
Vanger 0:b86d15c6ba29 2755 /* return bytes received, -1 on error */
Vanger 0:b86d15c6ba29 2756 static int Receive(CYASSL* ssl, byte* buf, word32 sz)
Vanger 0:b86d15c6ba29 2757 {
Vanger 0:b86d15c6ba29 2758 int recvd;
Vanger 0:b86d15c6ba29 2759
Vanger 0:b86d15c6ba29 2760 if (ssl->ctx->CBIORecv == NULL) {
Vanger 0:b86d15c6ba29 2761 CYASSL_MSG("Your IO Recv callback is null, please set");
Vanger 0:b86d15c6ba29 2762 return -1;
Vanger 0:b86d15c6ba29 2763 }
Vanger 0:b86d15c6ba29 2764
Vanger 0:b86d15c6ba29 2765 retry:
Vanger 0:b86d15c6ba29 2766 recvd = ssl->ctx->CBIORecv(ssl, (char *)buf, (int)sz, ssl->IOCB_ReadCtx);
Vanger 0:b86d15c6ba29 2767 if (recvd < 0)
Vanger 0:b86d15c6ba29 2768 switch (recvd) {
Vanger 0:b86d15c6ba29 2769 case CYASSL_CBIO_ERR_GENERAL: /* general/unknown error */
Vanger 0:b86d15c6ba29 2770 return -1;
Vanger 0:b86d15c6ba29 2771
Vanger 0:b86d15c6ba29 2772 case CYASSL_CBIO_ERR_WANT_READ: /* want read, would block */
Vanger 0:b86d15c6ba29 2773 return WANT_READ;
Vanger 0:b86d15c6ba29 2774
Vanger 0:b86d15c6ba29 2775 case CYASSL_CBIO_ERR_CONN_RST: /* connection reset */
Vanger 0:b86d15c6ba29 2776 #ifdef USE_WINDOWS_API
Vanger 0:b86d15c6ba29 2777 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 2778 goto retry;
Vanger 0:b86d15c6ba29 2779 }
Vanger 0:b86d15c6ba29 2780 #endif
Vanger 0:b86d15c6ba29 2781 ssl->options.connReset = 1;
Vanger 0:b86d15c6ba29 2782 return -1;
Vanger 0:b86d15c6ba29 2783
Vanger 0:b86d15c6ba29 2784 case CYASSL_CBIO_ERR_ISR: /* interrupt */
Vanger 0:b86d15c6ba29 2785 /* see if we got our timeout */
Vanger 0:b86d15c6ba29 2786 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 2787 if (ssl->toInfoOn) {
Vanger 0:b86d15c6ba29 2788 struct itimerval timeout;
Vanger 0:b86d15c6ba29 2789 getitimer(ITIMER_REAL, &timeout);
Vanger 0:b86d15c6ba29 2790 if (timeout.it_value.tv_sec == 0 &&
Vanger 0:b86d15c6ba29 2791 timeout.it_value.tv_usec == 0) {
Vanger 0:b86d15c6ba29 2792 XSTRNCPY(ssl->timeoutInfo.timeoutName,
Vanger 0:b86d15c6ba29 2793 "recv() timeout", MAX_TIMEOUT_NAME_SZ);
Vanger 0:b86d15c6ba29 2794 CYASSL_MSG("Got our timeout");
Vanger 0:b86d15c6ba29 2795 return WANT_READ;
Vanger 0:b86d15c6ba29 2796 }
Vanger 0:b86d15c6ba29 2797 }
Vanger 0:b86d15c6ba29 2798 #endif
Vanger 0:b86d15c6ba29 2799 goto retry;
Vanger 0:b86d15c6ba29 2800
Vanger 0:b86d15c6ba29 2801 case CYASSL_CBIO_ERR_CONN_CLOSE: /* peer closed connection */
Vanger 0:b86d15c6ba29 2802 ssl->options.isClosed = 1;
Vanger 0:b86d15c6ba29 2803 return -1;
Vanger 0:b86d15c6ba29 2804
Vanger 0:b86d15c6ba29 2805 case CYASSL_CBIO_ERR_TIMEOUT:
Vanger 0:b86d15c6ba29 2806 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 2807 if (DtlsPoolTimeout(ssl) == 0 && DtlsPoolSend(ssl) == 0)
Vanger 0:b86d15c6ba29 2808 goto retry;
Vanger 0:b86d15c6ba29 2809 else
Vanger 0:b86d15c6ba29 2810 #endif
Vanger 0:b86d15c6ba29 2811 return -1;
Vanger 0:b86d15c6ba29 2812
Vanger 0:b86d15c6ba29 2813 default:
Vanger 0:b86d15c6ba29 2814 return recvd;
Vanger 0:b86d15c6ba29 2815 }
Vanger 0:b86d15c6ba29 2816
Vanger 0:b86d15c6ba29 2817 return recvd;
Vanger 0:b86d15c6ba29 2818 }
Vanger 0:b86d15c6ba29 2819
Vanger 0:b86d15c6ba29 2820
Vanger 0:b86d15c6ba29 2821 /* Switch dynamic output buffer back to static, buffer is assumed clear */
Vanger 0:b86d15c6ba29 2822 void ShrinkOutputBuffer(CYASSL* ssl)
Vanger 0:b86d15c6ba29 2823 {
Vanger 0:b86d15c6ba29 2824 CYASSL_MSG("Shrinking output buffer\n");
Vanger 0:b86d15c6ba29 2825 XFREE(ssl->buffers.outputBuffer.buffer - ssl->buffers.outputBuffer.offset,
Vanger 0:b86d15c6ba29 2826 ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
Vanger 0:b86d15c6ba29 2827 ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
Vanger 0:b86d15c6ba29 2828 ssl->buffers.outputBuffer.bufferSize = STATIC_BUFFER_LEN;
Vanger 0:b86d15c6ba29 2829 ssl->buffers.outputBuffer.dynamicFlag = 0;
Vanger 0:b86d15c6ba29 2830 ssl->buffers.outputBuffer.offset = 0;
Vanger 0:b86d15c6ba29 2831 }
Vanger 0:b86d15c6ba29 2832
Vanger 0:b86d15c6ba29 2833
Vanger 0:b86d15c6ba29 2834 /* Switch dynamic input buffer back to static, keep any remaining input */
Vanger 0:b86d15c6ba29 2835 /* forced free means cleaning up */
Vanger 0:b86d15c6ba29 2836 void ShrinkInputBuffer(CYASSL* ssl, int forcedFree)
Vanger 0:b86d15c6ba29 2837 {
Vanger 0:b86d15c6ba29 2838 int usedLength = ssl->buffers.inputBuffer.length -
Vanger 0:b86d15c6ba29 2839 ssl->buffers.inputBuffer.idx;
Vanger 0:b86d15c6ba29 2840 if (!forcedFree && usedLength > STATIC_BUFFER_LEN)
Vanger 0:b86d15c6ba29 2841 return;
Vanger 0:b86d15c6ba29 2842
Vanger 0:b86d15c6ba29 2843 CYASSL_MSG("Shrinking input buffer\n");
Vanger 0:b86d15c6ba29 2844
Vanger 0:b86d15c6ba29 2845 if (!forcedFree && usedLength)
Vanger 0:b86d15c6ba29 2846 XMEMCPY(ssl->buffers.inputBuffer.staticBuffer,
Vanger 0:b86d15c6ba29 2847 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
Vanger 0:b86d15c6ba29 2848 usedLength);
Vanger 0:b86d15c6ba29 2849
Vanger 0:b86d15c6ba29 2850 XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
Vanger 0:b86d15c6ba29 2851 ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
Vanger 0:b86d15c6ba29 2852 ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
Vanger 0:b86d15c6ba29 2853 ssl->buffers.inputBuffer.bufferSize = STATIC_BUFFER_LEN;
Vanger 0:b86d15c6ba29 2854 ssl->buffers.inputBuffer.dynamicFlag = 0;
Vanger 0:b86d15c6ba29 2855 ssl->buffers.inputBuffer.offset = 0;
Vanger 0:b86d15c6ba29 2856 ssl->buffers.inputBuffer.idx = 0;
Vanger 0:b86d15c6ba29 2857 ssl->buffers.inputBuffer.length = usedLength;
Vanger 0:b86d15c6ba29 2858 }
Vanger 0:b86d15c6ba29 2859
Vanger 0:b86d15c6ba29 2860
Vanger 0:b86d15c6ba29 2861 int SendBuffered(CYASSL* ssl)
Vanger 0:b86d15c6ba29 2862 {
Vanger 0:b86d15c6ba29 2863 if (ssl->ctx->CBIOSend == NULL) {
Vanger 0:b86d15c6ba29 2864 CYASSL_MSG("Your IO Send callback is null, please set");
Vanger 0:b86d15c6ba29 2865 return SOCKET_ERROR_E;
Vanger 0:b86d15c6ba29 2866 }
Vanger 0:b86d15c6ba29 2867
Vanger 0:b86d15c6ba29 2868 while (ssl->buffers.outputBuffer.length > 0) {
Vanger 0:b86d15c6ba29 2869 int sent = ssl->ctx->CBIOSend(ssl,
Vanger 0:b86d15c6ba29 2870 (char*)ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 2871 ssl->buffers.outputBuffer.idx,
Vanger 0:b86d15c6ba29 2872 (int)ssl->buffers.outputBuffer.length,
Vanger 0:b86d15c6ba29 2873 ssl->IOCB_WriteCtx);
Vanger 0:b86d15c6ba29 2874 if (sent < 0) {
Vanger 0:b86d15c6ba29 2875 switch (sent) {
Vanger 0:b86d15c6ba29 2876
Vanger 0:b86d15c6ba29 2877 case CYASSL_CBIO_ERR_WANT_WRITE: /* would block */
Vanger 0:b86d15c6ba29 2878 return WANT_WRITE;
Vanger 0:b86d15c6ba29 2879
Vanger 0:b86d15c6ba29 2880 case CYASSL_CBIO_ERR_CONN_RST: /* connection reset */
Vanger 0:b86d15c6ba29 2881 ssl->options.connReset = 1;
Vanger 0:b86d15c6ba29 2882 break;
Vanger 0:b86d15c6ba29 2883
Vanger 0:b86d15c6ba29 2884 case CYASSL_CBIO_ERR_ISR: /* interrupt */
Vanger 0:b86d15c6ba29 2885 /* see if we got our timeout */
Vanger 0:b86d15c6ba29 2886 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 2887 if (ssl->toInfoOn) {
Vanger 0:b86d15c6ba29 2888 struct itimerval timeout;
Vanger 0:b86d15c6ba29 2889 getitimer(ITIMER_REAL, &timeout);
Vanger 0:b86d15c6ba29 2890 if (timeout.it_value.tv_sec == 0 &&
Vanger 0:b86d15c6ba29 2891 timeout.it_value.tv_usec == 0) {
Vanger 0:b86d15c6ba29 2892 XSTRNCPY(ssl->timeoutInfo.timeoutName,
Vanger 0:b86d15c6ba29 2893 "send() timeout", MAX_TIMEOUT_NAME_SZ);
Vanger 0:b86d15c6ba29 2894 CYASSL_MSG("Got our timeout");
Vanger 0:b86d15c6ba29 2895 return WANT_WRITE;
Vanger 0:b86d15c6ba29 2896 }
Vanger 0:b86d15c6ba29 2897 }
Vanger 0:b86d15c6ba29 2898 #endif
Vanger 0:b86d15c6ba29 2899 continue;
Vanger 0:b86d15c6ba29 2900
Vanger 0:b86d15c6ba29 2901 case CYASSL_CBIO_ERR_CONN_CLOSE: /* epipe / conn closed */
Vanger 0:b86d15c6ba29 2902 ssl->options.connReset = 1; /* treat same as reset */
Vanger 0:b86d15c6ba29 2903 break;
Vanger 0:b86d15c6ba29 2904
Vanger 0:b86d15c6ba29 2905 default:
Vanger 0:b86d15c6ba29 2906 return SOCKET_ERROR_E;
Vanger 0:b86d15c6ba29 2907 }
Vanger 0:b86d15c6ba29 2908
Vanger 0:b86d15c6ba29 2909 return SOCKET_ERROR_E;
Vanger 0:b86d15c6ba29 2910 }
Vanger 0:b86d15c6ba29 2911
Vanger 0:b86d15c6ba29 2912 if (sent > (int)ssl->buffers.outputBuffer.length) {
Vanger 0:b86d15c6ba29 2913 CYASSL_MSG("SendBuffered() out of bounds read");
Vanger 0:b86d15c6ba29 2914 return SEND_OOB_READ_E;
Vanger 0:b86d15c6ba29 2915 }
Vanger 0:b86d15c6ba29 2916
Vanger 0:b86d15c6ba29 2917 ssl->buffers.outputBuffer.idx += sent;
Vanger 0:b86d15c6ba29 2918 ssl->buffers.outputBuffer.length -= sent;
Vanger 0:b86d15c6ba29 2919 }
Vanger 0:b86d15c6ba29 2920
Vanger 0:b86d15c6ba29 2921 ssl->buffers.outputBuffer.idx = 0;
Vanger 0:b86d15c6ba29 2922
Vanger 0:b86d15c6ba29 2923 if (ssl->buffers.outputBuffer.dynamicFlag)
Vanger 0:b86d15c6ba29 2924 ShrinkOutputBuffer(ssl);
Vanger 0:b86d15c6ba29 2925
Vanger 0:b86d15c6ba29 2926 return 0;
Vanger 0:b86d15c6ba29 2927 }
Vanger 0:b86d15c6ba29 2928
Vanger 0:b86d15c6ba29 2929
Vanger 0:b86d15c6ba29 2930 /* Grow the output buffer */
Vanger 0:b86d15c6ba29 2931 static INLINE int GrowOutputBuffer(CYASSL* ssl, int size)
Vanger 0:b86d15c6ba29 2932 {
Vanger 0:b86d15c6ba29 2933 byte* tmp;
Vanger 0:b86d15c6ba29 2934 byte hdrSz = ssl->options.dtls ? DTLS_RECORD_HEADER_SZ :
Vanger 0:b86d15c6ba29 2935 RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 2936 byte align = CYASSL_GENERAL_ALIGNMENT;
Vanger 0:b86d15c6ba29 2937 /* the encrypted data will be offset from the front of the buffer by
Vanger 0:b86d15c6ba29 2938 the header, if the user wants encrypted alignment they need
Vanger 0:b86d15c6ba29 2939 to define their alignment requirement */
Vanger 0:b86d15c6ba29 2940
Vanger 0:b86d15c6ba29 2941 if (align) {
Vanger 0:b86d15c6ba29 2942 while (align < hdrSz)
Vanger 0:b86d15c6ba29 2943 align *= 2;
Vanger 0:b86d15c6ba29 2944 }
Vanger 0:b86d15c6ba29 2945
Vanger 0:b86d15c6ba29 2946 tmp = (byte*) XMALLOC(size + ssl->buffers.outputBuffer.length + align,
Vanger 0:b86d15c6ba29 2947 ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
Vanger 0:b86d15c6ba29 2948 CYASSL_MSG("growing output buffer\n");
Vanger 0:b86d15c6ba29 2949
Vanger 0:b86d15c6ba29 2950 if (!tmp) return MEMORY_E;
Vanger 0:b86d15c6ba29 2951 if (align)
Vanger 0:b86d15c6ba29 2952 tmp += align - hdrSz;
Vanger 0:b86d15c6ba29 2953
Vanger 0:b86d15c6ba29 2954 if (ssl->buffers.outputBuffer.length)
Vanger 0:b86d15c6ba29 2955 XMEMCPY(tmp, ssl->buffers.outputBuffer.buffer,
Vanger 0:b86d15c6ba29 2956 ssl->buffers.outputBuffer.length);
Vanger 0:b86d15c6ba29 2957
Vanger 0:b86d15c6ba29 2958 if (ssl->buffers.outputBuffer.dynamicFlag)
Vanger 0:b86d15c6ba29 2959 XFREE(ssl->buffers.outputBuffer.buffer -
Vanger 0:b86d15c6ba29 2960 ssl->buffers.outputBuffer.offset, ssl->heap,
Vanger 0:b86d15c6ba29 2961 DYNAMIC_TYPE_OUT_BUFFER);
Vanger 0:b86d15c6ba29 2962 ssl->buffers.outputBuffer.dynamicFlag = 1;
Vanger 0:b86d15c6ba29 2963 if (align)
Vanger 0:b86d15c6ba29 2964 ssl->buffers.outputBuffer.offset = align - hdrSz;
Vanger 0:b86d15c6ba29 2965 else
Vanger 0:b86d15c6ba29 2966 ssl->buffers.outputBuffer.offset = 0;
Vanger 0:b86d15c6ba29 2967 ssl->buffers.outputBuffer.buffer = tmp;
Vanger 0:b86d15c6ba29 2968 ssl->buffers.outputBuffer.bufferSize = size +
Vanger 0:b86d15c6ba29 2969 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 2970 return 0;
Vanger 0:b86d15c6ba29 2971 }
Vanger 0:b86d15c6ba29 2972
Vanger 0:b86d15c6ba29 2973
Vanger 0:b86d15c6ba29 2974 /* Grow the input buffer, should only be to read cert or big app data */
Vanger 0:b86d15c6ba29 2975 int GrowInputBuffer(CYASSL* ssl, int size, int usedLength)
Vanger 0:b86d15c6ba29 2976 {
Vanger 0:b86d15c6ba29 2977 byte* tmp;
Vanger 0:b86d15c6ba29 2978 byte hdrSz = DTLS_RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 2979 byte align = ssl->options.dtls ? CYASSL_GENERAL_ALIGNMENT : 0;
Vanger 0:b86d15c6ba29 2980 /* the encrypted data will be offset from the front of the buffer by
Vanger 0:b86d15c6ba29 2981 the dtls record header, if the user wants encrypted alignment they need
Vanger 0:b86d15c6ba29 2982 to define their alignment requirement. in tls we read record header
Vanger 0:b86d15c6ba29 2983 to get size of record and put actual data back at front, so don't need */
Vanger 0:b86d15c6ba29 2984
Vanger 0:b86d15c6ba29 2985 if (align) {
Vanger 0:b86d15c6ba29 2986 while (align < hdrSz)
Vanger 0:b86d15c6ba29 2987 align *= 2;
Vanger 0:b86d15c6ba29 2988 }
Vanger 0:b86d15c6ba29 2989 tmp = (byte*) XMALLOC(size + usedLength + align, ssl->heap,
Vanger 0:b86d15c6ba29 2990 DYNAMIC_TYPE_IN_BUFFER);
Vanger 0:b86d15c6ba29 2991 CYASSL_MSG("growing input buffer\n");
Vanger 0:b86d15c6ba29 2992
Vanger 0:b86d15c6ba29 2993 if (!tmp) return MEMORY_E;
Vanger 0:b86d15c6ba29 2994 if (align)
Vanger 0:b86d15c6ba29 2995 tmp += align - hdrSz;
Vanger 0:b86d15c6ba29 2996
Vanger 0:b86d15c6ba29 2997 if (usedLength)
Vanger 0:b86d15c6ba29 2998 XMEMCPY(tmp, ssl->buffers.inputBuffer.buffer +
Vanger 0:b86d15c6ba29 2999 ssl->buffers.inputBuffer.idx, usedLength);
Vanger 0:b86d15c6ba29 3000
Vanger 0:b86d15c6ba29 3001 if (ssl->buffers.inputBuffer.dynamicFlag)
Vanger 0:b86d15c6ba29 3002 XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
Vanger 0:b86d15c6ba29 3003 ssl->heap,DYNAMIC_TYPE_IN_BUFFER);
Vanger 0:b86d15c6ba29 3004
Vanger 0:b86d15c6ba29 3005 ssl->buffers.inputBuffer.dynamicFlag = 1;
Vanger 0:b86d15c6ba29 3006 if (align)
Vanger 0:b86d15c6ba29 3007 ssl->buffers.inputBuffer.offset = align - hdrSz;
Vanger 0:b86d15c6ba29 3008 else
Vanger 0:b86d15c6ba29 3009 ssl->buffers.inputBuffer.offset = 0;
Vanger 0:b86d15c6ba29 3010 ssl->buffers.inputBuffer.buffer = tmp;
Vanger 0:b86d15c6ba29 3011 ssl->buffers.inputBuffer.bufferSize = size + usedLength;
Vanger 0:b86d15c6ba29 3012 ssl->buffers.inputBuffer.idx = 0;
Vanger 0:b86d15c6ba29 3013 ssl->buffers.inputBuffer.length = usedLength;
Vanger 0:b86d15c6ba29 3014
Vanger 0:b86d15c6ba29 3015 return 0;
Vanger 0:b86d15c6ba29 3016 }
Vanger 0:b86d15c6ba29 3017
Vanger 0:b86d15c6ba29 3018
Vanger 0:b86d15c6ba29 3019 /* check available size into output buffer, make room if needed */
Vanger 0:b86d15c6ba29 3020 int CheckAvailableSize(CYASSL *ssl, int size)
Vanger 0:b86d15c6ba29 3021 {
Vanger 0:b86d15c6ba29 3022
Vanger 0:b86d15c6ba29 3023 if (size < 0) {
Vanger 0:b86d15c6ba29 3024 CYASSL_MSG("CheckAvailableSize() called with negative number");
Vanger 0:b86d15c6ba29 3025 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 3026 }
Vanger 0:b86d15c6ba29 3027
Vanger 0:b86d15c6ba29 3028 if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length
Vanger 0:b86d15c6ba29 3029 < (word32)size) {
Vanger 0:b86d15c6ba29 3030 if (GrowOutputBuffer(ssl, size) < 0)
Vanger 0:b86d15c6ba29 3031 return MEMORY_E;
Vanger 0:b86d15c6ba29 3032 }
Vanger 0:b86d15c6ba29 3033
Vanger 0:b86d15c6ba29 3034 return 0;
Vanger 0:b86d15c6ba29 3035 }
Vanger 0:b86d15c6ba29 3036
Vanger 0:b86d15c6ba29 3037
Vanger 0:b86d15c6ba29 3038 /* do all verify and sanity checks on record header */
Vanger 0:b86d15c6ba29 3039 static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
Vanger 0:b86d15c6ba29 3040 RecordLayerHeader* rh, word16 *size)
Vanger 0:b86d15c6ba29 3041 {
Vanger 0:b86d15c6ba29 3042 if (!ssl->options.dtls) {
Vanger 0:b86d15c6ba29 3043 #ifdef HAVE_FUZZER
Vanger 0:b86d15c6ba29 3044 if (ssl->fuzzerCb)
Vanger 0:b86d15c6ba29 3045 ssl->fuzzerCb(ssl, input + *inOutIdx, RECORD_HEADER_SZ, FUZZ_HEAD,
Vanger 0:b86d15c6ba29 3046 ssl->fuzzerCtx);
Vanger 0:b86d15c6ba29 3047 #endif
Vanger 0:b86d15c6ba29 3048 XMEMCPY(rh, input + *inOutIdx, RECORD_HEADER_SZ);
Vanger 0:b86d15c6ba29 3049 *inOutIdx += RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 3050 ato16(rh->length, size);
Vanger 0:b86d15c6ba29 3051 }
Vanger 0:b86d15c6ba29 3052 else {
Vanger 0:b86d15c6ba29 3053 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 3054 /* type and version in same sport */
Vanger 0:b86d15c6ba29 3055 XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
Vanger 0:b86d15c6ba29 3056 *inOutIdx += ENUM_LEN + VERSION_SZ;
Vanger 0:b86d15c6ba29 3057 ato16(input + *inOutIdx, &ssl->keys.dtls_state.curEpoch);
Vanger 0:b86d15c6ba29 3058 *inOutIdx += 4; /* advance past epoch, skip first 2 seq bytes for now */
Vanger 0:b86d15c6ba29 3059 ato32(input + *inOutIdx, &ssl->keys.dtls_state.curSeq);
Vanger 0:b86d15c6ba29 3060 *inOutIdx += 4; /* advance past rest of seq */
Vanger 0:b86d15c6ba29 3061 ato16(input + *inOutIdx, size);
Vanger 0:b86d15c6ba29 3062 *inOutIdx += LENGTH_SZ;
Vanger 0:b86d15c6ba29 3063 #ifdef HAVE_FUZZER
Vanger 0:b86d15c6ba29 3064 if (ssl->fuzzerCb)
Vanger 0:b86d15c6ba29 3065 ssl->fuzzerCb(ssl, input + *inOutIdx - LENGTH_SZ - 8 - ENUM_LEN -
Vanger 0:b86d15c6ba29 3066 VERSION_SZ, ENUM_LEN + VERSION_SZ + 8 + LENGTH_SZ,
Vanger 0:b86d15c6ba29 3067 FUZZ_HEAD, ssl->fuzzerCtx);
Vanger 0:b86d15c6ba29 3068 #endif
Vanger 0:b86d15c6ba29 3069 #endif
Vanger 0:b86d15c6ba29 3070 }
Vanger 0:b86d15c6ba29 3071
Vanger 0:b86d15c6ba29 3072 /* catch version mismatch */
Vanger 0:b86d15c6ba29 3073 if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor){
Vanger 0:b86d15c6ba29 3074 if (ssl->options.side == CYASSL_SERVER_END &&
Vanger 0:b86d15c6ba29 3075 ssl->options.acceptState == ACCEPT_BEGIN)
Vanger 0:b86d15c6ba29 3076 CYASSL_MSG("Client attempting to connect with different version");
Vanger 0:b86d15c6ba29 3077 else if (ssl->options.side == CYASSL_CLIENT_END &&
Vanger 0:b86d15c6ba29 3078 ssl->options.downgrade &&
Vanger 0:b86d15c6ba29 3079 ssl->options.connectState < FIRST_REPLY_DONE)
Vanger 0:b86d15c6ba29 3080 CYASSL_MSG("Server attempting to accept with different version");
Vanger 0:b86d15c6ba29 3081 else {
Vanger 0:b86d15c6ba29 3082 CYASSL_MSG("SSL version error");
Vanger 0:b86d15c6ba29 3083 return VERSION_ERROR; /* only use requested version */
Vanger 0:b86d15c6ba29 3084 }
Vanger 0:b86d15c6ba29 3085 }
Vanger 0:b86d15c6ba29 3086
Vanger 0:b86d15c6ba29 3087 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 3088 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 3089 if (DtlsCheckWindow(&ssl->keys.dtls_state) != 1)
Vanger 0:b86d15c6ba29 3090 return SEQUENCE_ERROR;
Vanger 0:b86d15c6ba29 3091 }
Vanger 0:b86d15c6ba29 3092 #endif
Vanger 0:b86d15c6ba29 3093
Vanger 0:b86d15c6ba29 3094 /* record layer length check */
Vanger 0:b86d15c6ba29 3095 #ifdef HAVE_MAX_FRAGMENT
Vanger 0:b86d15c6ba29 3096 if (*size > (ssl->max_fragment + MAX_COMP_EXTRA + MAX_MSG_EXTRA)) {
Vanger 0:b86d15c6ba29 3097 SendAlert(ssl, alert_fatal, record_overflow);
Vanger 0:b86d15c6ba29 3098 return LENGTH_ERROR;
Vanger 0:b86d15c6ba29 3099 }
Vanger 0:b86d15c6ba29 3100 #else
Vanger 0:b86d15c6ba29 3101 if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
Vanger 0:b86d15c6ba29 3102 return LENGTH_ERROR;
Vanger 0:b86d15c6ba29 3103 #endif
Vanger 0:b86d15c6ba29 3104
Vanger 0:b86d15c6ba29 3105 /* verify record type here as well */
Vanger 0:b86d15c6ba29 3106 switch (rh->type) {
Vanger 0:b86d15c6ba29 3107 case handshake:
Vanger 0:b86d15c6ba29 3108 case change_cipher_spec:
Vanger 0:b86d15c6ba29 3109 case application_data:
Vanger 0:b86d15c6ba29 3110 case alert:
Vanger 0:b86d15c6ba29 3111 break;
Vanger 0:b86d15c6ba29 3112 case no_type:
Vanger 0:b86d15c6ba29 3113 default:
Vanger 0:b86d15c6ba29 3114 CYASSL_MSG("Unknown Record Type");
Vanger 0:b86d15c6ba29 3115 return UNKNOWN_RECORD_TYPE;
Vanger 0:b86d15c6ba29 3116 }
Vanger 0:b86d15c6ba29 3117
Vanger 0:b86d15c6ba29 3118 /* haven't decrypted this record yet */
Vanger 0:b86d15c6ba29 3119 ssl->keys.decryptedCur = 0;
Vanger 0:b86d15c6ba29 3120
Vanger 0:b86d15c6ba29 3121 return 0;
Vanger 0:b86d15c6ba29 3122 }
Vanger 0:b86d15c6ba29 3123
Vanger 0:b86d15c6ba29 3124
Vanger 0:b86d15c6ba29 3125 static int GetHandShakeHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
Vanger 0:b86d15c6ba29 3126 byte *type, word32 *size, word32 totalSz)
Vanger 0:b86d15c6ba29 3127 {
Vanger 0:b86d15c6ba29 3128 const byte *ptr = input + *inOutIdx;
Vanger 0:b86d15c6ba29 3129 (void)ssl;
Vanger 0:b86d15c6ba29 3130
Vanger 0:b86d15c6ba29 3131 *inOutIdx += HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 3132 if (*inOutIdx > totalSz)
Vanger 0:b86d15c6ba29 3133 return BUFFER_E;
Vanger 0:b86d15c6ba29 3134
Vanger 0:b86d15c6ba29 3135 *type = ptr[0];
Vanger 0:b86d15c6ba29 3136 c24to32(&ptr[1], size);
Vanger 0:b86d15c6ba29 3137
Vanger 0:b86d15c6ba29 3138 return 0;
Vanger 0:b86d15c6ba29 3139 }
Vanger 0:b86d15c6ba29 3140
Vanger 0:b86d15c6ba29 3141
Vanger 0:b86d15c6ba29 3142 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 3143 static int GetDtlsHandShakeHeader(CYASSL* ssl, const byte* input,
Vanger 0:b86d15c6ba29 3144 word32* inOutIdx, byte *type, word32 *size,
Vanger 0:b86d15c6ba29 3145 word32 *fragOffset, word32 *fragSz,
Vanger 0:b86d15c6ba29 3146 word32 totalSz)
Vanger 0:b86d15c6ba29 3147 {
Vanger 0:b86d15c6ba29 3148 word32 idx = *inOutIdx;
Vanger 0:b86d15c6ba29 3149
Vanger 0:b86d15c6ba29 3150 *inOutIdx += HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 3151 if (*inOutIdx > totalSz)
Vanger 0:b86d15c6ba29 3152 return BUFFER_E;
Vanger 0:b86d15c6ba29 3153
Vanger 0:b86d15c6ba29 3154 *type = input[idx++];
Vanger 0:b86d15c6ba29 3155 c24to32(input + idx, size);
Vanger 0:b86d15c6ba29 3156 idx += BYTE3_LEN;
Vanger 0:b86d15c6ba29 3157
Vanger 0:b86d15c6ba29 3158 ato16(input + idx, &ssl->keys.dtls_peer_handshake_number);
Vanger 0:b86d15c6ba29 3159 idx += DTLS_HANDSHAKE_SEQ_SZ;
Vanger 0:b86d15c6ba29 3160
Vanger 0:b86d15c6ba29 3161 c24to32(input + idx, fragOffset);
Vanger 0:b86d15c6ba29 3162 idx += DTLS_HANDSHAKE_FRAG_SZ;
Vanger 0:b86d15c6ba29 3163 c24to32(input + idx, fragSz);
Vanger 0:b86d15c6ba29 3164
Vanger 0:b86d15c6ba29 3165 return 0;
Vanger 0:b86d15c6ba29 3166 }
Vanger 0:b86d15c6ba29 3167 #endif
Vanger 0:b86d15c6ba29 3168
Vanger 0:b86d15c6ba29 3169
Vanger 0:b86d15c6ba29 3170 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 3171 /* fill with MD5 pad size since biggest required */
Vanger 0:b86d15c6ba29 3172 static const byte PAD1[PAD_MD5] =
Vanger 0:b86d15c6ba29 3173 { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
Vanger 0:b86d15c6ba29 3174 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
Vanger 0:b86d15c6ba29 3175 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
Vanger 0:b86d15c6ba29 3176 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
Vanger 0:b86d15c6ba29 3177 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
Vanger 0:b86d15c6ba29 3178 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
Vanger 0:b86d15c6ba29 3179 };
Vanger 0:b86d15c6ba29 3180 static const byte PAD2[PAD_MD5] =
Vanger 0:b86d15c6ba29 3181 { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
Vanger 0:b86d15c6ba29 3182 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
Vanger 0:b86d15c6ba29 3183 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
Vanger 0:b86d15c6ba29 3184 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
Vanger 0:b86d15c6ba29 3185 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
Vanger 0:b86d15c6ba29 3186 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
Vanger 0:b86d15c6ba29 3187 };
Vanger 0:b86d15c6ba29 3188
Vanger 0:b86d15c6ba29 3189 /* calculate MD5 hash for finished */
Vanger 0:b86d15c6ba29 3190 static void BuildMD5(CYASSL* ssl, Hashes* hashes, const byte* sender)
Vanger 0:b86d15c6ba29 3191 {
Vanger 0:b86d15c6ba29 3192 byte md5_result[MD5_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 3193
Vanger 0:b86d15c6ba29 3194 /* make md5 inner */
Vanger 0:b86d15c6ba29 3195 Md5Update(&ssl->hashMd5, sender, SIZEOF_SENDER);
Vanger 0:b86d15c6ba29 3196 Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
Vanger 0:b86d15c6ba29 3197 Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
Vanger 0:b86d15c6ba29 3198 Md5Final(&ssl->hashMd5, md5_result);
Vanger 0:b86d15c6ba29 3199
Vanger 0:b86d15c6ba29 3200 /* make md5 outer */
Vanger 0:b86d15c6ba29 3201 Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
Vanger 0:b86d15c6ba29 3202 Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
Vanger 0:b86d15c6ba29 3203 Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 3204
Vanger 0:b86d15c6ba29 3205 Md5Final(&ssl->hashMd5, hashes->md5);
Vanger 0:b86d15c6ba29 3206 }
Vanger 0:b86d15c6ba29 3207
Vanger 0:b86d15c6ba29 3208
Vanger 0:b86d15c6ba29 3209 /* calculate SHA hash for finished */
Vanger 0:b86d15c6ba29 3210 static void BuildSHA(CYASSL* ssl, Hashes* hashes, const byte* sender)
Vanger 0:b86d15c6ba29 3211 {
Vanger 0:b86d15c6ba29 3212 byte sha_result[SHA_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 3213
Vanger 0:b86d15c6ba29 3214 /* make sha inner */
Vanger 0:b86d15c6ba29 3215 ShaUpdate(&ssl->hashSha, sender, SIZEOF_SENDER);
Vanger 0:b86d15c6ba29 3216 ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
Vanger 0:b86d15c6ba29 3217 ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
Vanger 0:b86d15c6ba29 3218 ShaFinal(&ssl->hashSha, sha_result);
Vanger 0:b86d15c6ba29 3219
Vanger 0:b86d15c6ba29 3220 /* make sha outer */
Vanger 0:b86d15c6ba29 3221 ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
Vanger 0:b86d15c6ba29 3222 ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
Vanger 0:b86d15c6ba29 3223 ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 3224
Vanger 0:b86d15c6ba29 3225 ShaFinal(&ssl->hashSha, hashes->sha);
Vanger 0:b86d15c6ba29 3226 }
Vanger 0:b86d15c6ba29 3227 #endif
Vanger 0:b86d15c6ba29 3228
Vanger 0:b86d15c6ba29 3229
Vanger 0:b86d15c6ba29 3230 static int BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
Vanger 0:b86d15c6ba29 3231 {
Vanger 0:b86d15c6ba29 3232 int ret = 0;
Vanger 0:b86d15c6ba29 3233 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 3234 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 3235 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 3236 Md5* md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3237 #endif
Vanger 0:b86d15c6ba29 3238 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 3239 Sha* sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3240 #endif
Vanger 0:b86d15c6ba29 3241 #endif
Vanger 0:b86d15c6ba29 3242 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 3243 Sha256* sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
Vanger 0:b86d15c6ba29 3244 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3245 #endif
Vanger 0:b86d15c6ba29 3246 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 3247 Sha384* sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3248 #endif
Vanger 0:b86d15c6ba29 3249 #else
Vanger 0:b86d15c6ba29 3250 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 3251 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 3252 Md5 md5[1];
Vanger 0:b86d15c6ba29 3253 #endif
Vanger 0:b86d15c6ba29 3254 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 3255 Sha sha[1];
Vanger 0:b86d15c6ba29 3256 #endif
Vanger 0:b86d15c6ba29 3257 #endif
Vanger 0:b86d15c6ba29 3258 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 3259 Sha256 sha256[1];
Vanger 0:b86d15c6ba29 3260 #endif
Vanger 0:b86d15c6ba29 3261 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 3262 Sha384 sha384[1];
Vanger 0:b86d15c6ba29 3263 #endif
Vanger 0:b86d15c6ba29 3264 #endif
Vanger 0:b86d15c6ba29 3265
Vanger 0:b86d15c6ba29 3266 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 3267 if (ssl == NULL
Vanger 0:b86d15c6ba29 3268 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 3269 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 3270 || md5 == NULL
Vanger 0:b86d15c6ba29 3271 #endif
Vanger 0:b86d15c6ba29 3272 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 3273 || sha == NULL
Vanger 0:b86d15c6ba29 3274 #endif
Vanger 0:b86d15c6ba29 3275 #endif
Vanger 0:b86d15c6ba29 3276 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 3277 || sha256 == NULL
Vanger 0:b86d15c6ba29 3278 #endif
Vanger 0:b86d15c6ba29 3279 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 3280 || sha384 == NULL
Vanger 0:b86d15c6ba29 3281 #endif
Vanger 0:b86d15c6ba29 3282 ) {
Vanger 0:b86d15c6ba29 3283 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 3284 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 3285 XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3286 #endif
Vanger 0:b86d15c6ba29 3287 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 3288 XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3289 #endif
Vanger 0:b86d15c6ba29 3290 #endif
Vanger 0:b86d15c6ba29 3291 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 3292 XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3293 #endif
Vanger 0:b86d15c6ba29 3294 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 3295 XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3296 #endif
Vanger 0:b86d15c6ba29 3297 return MEMORY_E;
Vanger 0:b86d15c6ba29 3298 }
Vanger 0:b86d15c6ba29 3299 #endif
Vanger 0:b86d15c6ba29 3300
Vanger 0:b86d15c6ba29 3301 /* store current states, building requires get_digest which resets state */
Vanger 0:b86d15c6ba29 3302 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 3303 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 3304 md5[0] = ssl->hashMd5;
Vanger 0:b86d15c6ba29 3305 #endif
Vanger 0:b86d15c6ba29 3306 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 3307 sha[0] = ssl->hashSha;
Vanger 0:b86d15c6ba29 3308 #endif
Vanger 0:b86d15c6ba29 3309 #endif
Vanger 0:b86d15c6ba29 3310 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 3311 sha256[0] = ssl->hashSha256;
Vanger 0:b86d15c6ba29 3312 #endif
Vanger 0:b86d15c6ba29 3313 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 3314 sha384[0] = ssl->hashSha384;
Vanger 0:b86d15c6ba29 3315 #endif
Vanger 0:b86d15c6ba29 3316
Vanger 0:b86d15c6ba29 3317 #ifndef NO_TLS
Vanger 0:b86d15c6ba29 3318 if (ssl->options.tls) {
Vanger 0:b86d15c6ba29 3319 ret = BuildTlsFinished(ssl, hashes, sender);
Vanger 0:b86d15c6ba29 3320 }
Vanger 0:b86d15c6ba29 3321 #endif
Vanger 0:b86d15c6ba29 3322 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 3323 if (!ssl->options.tls) {
Vanger 0:b86d15c6ba29 3324 BuildMD5(ssl, hashes, sender);
Vanger 0:b86d15c6ba29 3325 BuildSHA(ssl, hashes, sender);
Vanger 0:b86d15c6ba29 3326 }
Vanger 0:b86d15c6ba29 3327 #endif
Vanger 0:b86d15c6ba29 3328
Vanger 0:b86d15c6ba29 3329 /* restore */
Vanger 0:b86d15c6ba29 3330 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 3331 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 3332 ssl->hashMd5 = md5[0];
Vanger 0:b86d15c6ba29 3333 #endif
Vanger 0:b86d15c6ba29 3334 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 3335 ssl->hashSha = sha[0];
Vanger 0:b86d15c6ba29 3336 #endif
Vanger 0:b86d15c6ba29 3337 #endif
Vanger 0:b86d15c6ba29 3338 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 3339 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 3340 ssl->hashSha256 = sha256[0];
Vanger 0:b86d15c6ba29 3341 #endif
Vanger 0:b86d15c6ba29 3342 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 3343 ssl->hashSha384 = sha384[0];
Vanger 0:b86d15c6ba29 3344 #endif
Vanger 0:b86d15c6ba29 3345 }
Vanger 0:b86d15c6ba29 3346
Vanger 0:b86d15c6ba29 3347 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 3348 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 3349 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 3350 XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3351 #endif
Vanger 0:b86d15c6ba29 3352 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 3353 XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3354 #endif
Vanger 0:b86d15c6ba29 3355 #endif
Vanger 0:b86d15c6ba29 3356 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 3357 XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3358 #endif
Vanger 0:b86d15c6ba29 3359 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 3360 XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3361 #endif
Vanger 0:b86d15c6ba29 3362 #endif
Vanger 0:b86d15c6ba29 3363
Vanger 0:b86d15c6ba29 3364 return ret;
Vanger 0:b86d15c6ba29 3365 }
Vanger 0:b86d15c6ba29 3366
Vanger 0:b86d15c6ba29 3367
Vanger 0:b86d15c6ba29 3368 /* cipher requirements */
Vanger 0:b86d15c6ba29 3369 enum {
Vanger 0:b86d15c6ba29 3370 REQUIRES_RSA,
Vanger 0:b86d15c6ba29 3371 REQUIRES_DHE,
Vanger 0:b86d15c6ba29 3372 REQUIRES_ECC_DSA,
Vanger 0:b86d15c6ba29 3373 REQUIRES_ECC_STATIC,
Vanger 0:b86d15c6ba29 3374 REQUIRES_PSK,
Vanger 0:b86d15c6ba29 3375 REQUIRES_NTRU,
Vanger 0:b86d15c6ba29 3376 REQUIRES_RSA_SIG
Vanger 0:b86d15c6ba29 3377 };
Vanger 0:b86d15c6ba29 3378
Vanger 0:b86d15c6ba29 3379
Vanger 0:b86d15c6ba29 3380
Vanger 0:b86d15c6ba29 3381 /* Does this cipher suite (first, second) have the requirement
Vanger 0:b86d15c6ba29 3382 an ephemeral key exchange will still require the key for signing
Vanger 0:b86d15c6ba29 3383 the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */
Vanger 0:b86d15c6ba29 3384 static int CipherRequires(byte first, byte second, int requirement)
Vanger 0:b86d15c6ba29 3385 {
Vanger 0:b86d15c6ba29 3386
Vanger 0:b86d15c6ba29 3387 if (first == CHACHA_BYTE) {
Vanger 0:b86d15c6ba29 3388
Vanger 0:b86d15c6ba29 3389 switch (second) {
Vanger 0:b86d15c6ba29 3390
Vanger 0:b86d15c6ba29 3391 case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
Vanger 0:b86d15c6ba29 3392 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3393 return 1;
Vanger 0:b86d15c6ba29 3394 break;
Vanger 0:b86d15c6ba29 3395
Vanger 0:b86d15c6ba29 3396 case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
Vanger 0:b86d15c6ba29 3397 if (requirement == REQUIRES_ECC_DSA)
Vanger 0:b86d15c6ba29 3398 return 1;
Vanger 0:b86d15c6ba29 3399 break;
Vanger 0:b86d15c6ba29 3400
Vanger 0:b86d15c6ba29 3401 case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
Vanger 0:b86d15c6ba29 3402 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3403 return 1;
Vanger 0:b86d15c6ba29 3404 if (requirement == REQUIRES_DHE)
Vanger 0:b86d15c6ba29 3405 return 1;
Vanger 0:b86d15c6ba29 3406 break;
Vanger 0:b86d15c6ba29 3407 }
Vanger 0:b86d15c6ba29 3408 }
Vanger 0:b86d15c6ba29 3409
Vanger 0:b86d15c6ba29 3410 /* ECC extensions */
Vanger 0:b86d15c6ba29 3411 if (first == ECC_BYTE) {
Vanger 0:b86d15c6ba29 3412
Vanger 0:b86d15c6ba29 3413 switch (second) {
Vanger 0:b86d15c6ba29 3414
Vanger 0:b86d15c6ba29 3415 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 3416 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
Vanger 0:b86d15c6ba29 3417 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3418 return 1;
Vanger 0:b86d15c6ba29 3419 break;
Vanger 0:b86d15c6ba29 3420
Vanger 0:b86d15c6ba29 3421 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
Vanger 0:b86d15c6ba29 3422 if (requirement == REQUIRES_ECC_STATIC)
Vanger 0:b86d15c6ba29 3423 return 1;
Vanger 0:b86d15c6ba29 3424 if (requirement == REQUIRES_RSA_SIG)
Vanger 0:b86d15c6ba29 3425 return 1;
Vanger 0:b86d15c6ba29 3426 break;
Vanger 0:b86d15c6ba29 3427
Vanger 0:b86d15c6ba29 3428 #ifndef NO_DES3
Vanger 0:b86d15c6ba29 3429 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
Vanger 0:b86d15c6ba29 3430 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3431 return 1;
Vanger 0:b86d15c6ba29 3432 break;
Vanger 0:b86d15c6ba29 3433
Vanger 0:b86d15c6ba29 3434 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
Vanger 0:b86d15c6ba29 3435 if (requirement == REQUIRES_ECC_STATIC)
Vanger 0:b86d15c6ba29 3436 return 1;
Vanger 0:b86d15c6ba29 3437 if (requirement == REQUIRES_RSA_SIG)
Vanger 0:b86d15c6ba29 3438 return 1;
Vanger 0:b86d15c6ba29 3439 break;
Vanger 0:b86d15c6ba29 3440 #endif
Vanger 0:b86d15c6ba29 3441
Vanger 0:b86d15c6ba29 3442 #ifndef NO_RC4
Vanger 0:b86d15c6ba29 3443 case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
Vanger 0:b86d15c6ba29 3444 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3445 return 1;
Vanger 0:b86d15c6ba29 3446 break;
Vanger 0:b86d15c6ba29 3447
Vanger 0:b86d15c6ba29 3448 case TLS_ECDH_RSA_WITH_RC4_128_SHA :
Vanger 0:b86d15c6ba29 3449 if (requirement == REQUIRES_ECC_STATIC)
Vanger 0:b86d15c6ba29 3450 return 1;
Vanger 0:b86d15c6ba29 3451 if (requirement == REQUIRES_RSA_SIG)
Vanger 0:b86d15c6ba29 3452 return 1;
Vanger 0:b86d15c6ba29 3453 break;
Vanger 0:b86d15c6ba29 3454 #endif
Vanger 0:b86d15c6ba29 3455 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 3456
Vanger 0:b86d15c6ba29 3457 #ifndef NO_DES3
Vanger 0:b86d15c6ba29 3458 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
Vanger 0:b86d15c6ba29 3459 if (requirement == REQUIRES_ECC_DSA)
Vanger 0:b86d15c6ba29 3460 return 1;
Vanger 0:b86d15c6ba29 3461 break;
Vanger 0:b86d15c6ba29 3462
Vanger 0:b86d15c6ba29 3463 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
Vanger 0:b86d15c6ba29 3464 if (requirement == REQUIRES_ECC_STATIC)
Vanger 0:b86d15c6ba29 3465 return 1;
Vanger 0:b86d15c6ba29 3466 break;
Vanger 0:b86d15c6ba29 3467 #endif
Vanger 0:b86d15c6ba29 3468 #ifndef NO_RC4
Vanger 0:b86d15c6ba29 3469 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
Vanger 0:b86d15c6ba29 3470 if (requirement == REQUIRES_ECC_DSA)
Vanger 0:b86d15c6ba29 3471 return 1;
Vanger 0:b86d15c6ba29 3472 break;
Vanger 0:b86d15c6ba29 3473
Vanger 0:b86d15c6ba29 3474 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
Vanger 0:b86d15c6ba29 3475 if (requirement == REQUIRES_ECC_STATIC)
Vanger 0:b86d15c6ba29 3476 return 1;
Vanger 0:b86d15c6ba29 3477 break;
Vanger 0:b86d15c6ba29 3478 #endif
Vanger 0:b86d15c6ba29 3479 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 3480 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
Vanger 0:b86d15c6ba29 3481 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3482 return 1;
Vanger 0:b86d15c6ba29 3483 break;
Vanger 0:b86d15c6ba29 3484
Vanger 0:b86d15c6ba29 3485 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
Vanger 0:b86d15c6ba29 3486 if (requirement == REQUIRES_ECC_STATIC)
Vanger 0:b86d15c6ba29 3487 return 1;
Vanger 0:b86d15c6ba29 3488 if (requirement == REQUIRES_RSA_SIG)
Vanger 0:b86d15c6ba29 3489 return 1;
Vanger 0:b86d15c6ba29 3490 break;
Vanger 0:b86d15c6ba29 3491 #endif
Vanger 0:b86d15c6ba29 3492
Vanger 0:b86d15c6ba29 3493 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
Vanger 0:b86d15c6ba29 3494 if (requirement == REQUIRES_ECC_DSA)
Vanger 0:b86d15c6ba29 3495 return 1;
Vanger 0:b86d15c6ba29 3496 break;
Vanger 0:b86d15c6ba29 3497
Vanger 0:b86d15c6ba29 3498 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
Vanger 0:b86d15c6ba29 3499 if (requirement == REQUIRES_ECC_STATIC)
Vanger 0:b86d15c6ba29 3500 return 1;
Vanger 0:b86d15c6ba29 3501 break;
Vanger 0:b86d15c6ba29 3502
Vanger 0:b86d15c6ba29 3503 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
Vanger 0:b86d15c6ba29 3504 if (requirement == REQUIRES_ECC_DSA)
Vanger 0:b86d15c6ba29 3505 return 1;
Vanger 0:b86d15c6ba29 3506 break;
Vanger 0:b86d15c6ba29 3507
Vanger 0:b86d15c6ba29 3508 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
Vanger 0:b86d15c6ba29 3509 if (requirement == REQUIRES_ECC_STATIC)
Vanger 0:b86d15c6ba29 3510 return 1;
Vanger 0:b86d15c6ba29 3511 break;
Vanger 0:b86d15c6ba29 3512
Vanger 0:b86d15c6ba29 3513 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
Vanger 0:b86d15c6ba29 3514 if (requirement == REQUIRES_ECC_DSA)
Vanger 0:b86d15c6ba29 3515 return 1;
Vanger 0:b86d15c6ba29 3516 break;
Vanger 0:b86d15c6ba29 3517
Vanger 0:b86d15c6ba29 3518 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
Vanger 0:b86d15c6ba29 3519 if (requirement == REQUIRES_ECC_DSA)
Vanger 0:b86d15c6ba29 3520 return 1;
Vanger 0:b86d15c6ba29 3521 break;
Vanger 0:b86d15c6ba29 3522
Vanger 0:b86d15c6ba29 3523 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
Vanger 0:b86d15c6ba29 3524 if (requirement == REQUIRES_ECC_STATIC)
Vanger 0:b86d15c6ba29 3525 return 1;
Vanger 0:b86d15c6ba29 3526 break;
Vanger 0:b86d15c6ba29 3527
Vanger 0:b86d15c6ba29 3528 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
Vanger 0:b86d15c6ba29 3529 if (requirement == REQUIRES_ECC_STATIC)
Vanger 0:b86d15c6ba29 3530 return 1;
Vanger 0:b86d15c6ba29 3531 break;
Vanger 0:b86d15c6ba29 3532
Vanger 0:b86d15c6ba29 3533 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 3534 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
Vanger 0:b86d15c6ba29 3535 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3536 return 1;
Vanger 0:b86d15c6ba29 3537 break;
Vanger 0:b86d15c6ba29 3538
Vanger 0:b86d15c6ba29 3539 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
Vanger 0:b86d15c6ba29 3540 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3541 return 1;
Vanger 0:b86d15c6ba29 3542 break;
Vanger 0:b86d15c6ba29 3543
Vanger 0:b86d15c6ba29 3544 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
Vanger 0:b86d15c6ba29 3545 if (requirement == REQUIRES_ECC_STATIC)
Vanger 0:b86d15c6ba29 3546 return 1;
Vanger 0:b86d15c6ba29 3547 if (requirement == REQUIRES_RSA_SIG)
Vanger 0:b86d15c6ba29 3548 return 1;
Vanger 0:b86d15c6ba29 3549 break;
Vanger 0:b86d15c6ba29 3550
Vanger 0:b86d15c6ba29 3551 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
Vanger 0:b86d15c6ba29 3552 if (requirement == REQUIRES_ECC_STATIC)
Vanger 0:b86d15c6ba29 3553 return 1;
Vanger 0:b86d15c6ba29 3554 if (requirement == REQUIRES_RSA_SIG)
Vanger 0:b86d15c6ba29 3555 return 1;
Vanger 0:b86d15c6ba29 3556 break;
Vanger 0:b86d15c6ba29 3557
Vanger 0:b86d15c6ba29 3558 case TLS_RSA_WITH_AES_128_CCM_8 :
Vanger 0:b86d15c6ba29 3559 case TLS_RSA_WITH_AES_256_CCM_8 :
Vanger 0:b86d15c6ba29 3560 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3561 return 1;
Vanger 0:b86d15c6ba29 3562 if (requirement == REQUIRES_RSA_SIG)
Vanger 0:b86d15c6ba29 3563 return 1;
Vanger 0:b86d15c6ba29 3564 break;
Vanger 0:b86d15c6ba29 3565
Vanger 0:b86d15c6ba29 3566 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
Vanger 0:b86d15c6ba29 3567 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
Vanger 0:b86d15c6ba29 3568 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3569 return 1;
Vanger 0:b86d15c6ba29 3570 if (requirement == REQUIRES_RSA_SIG)
Vanger 0:b86d15c6ba29 3571 return 1;
Vanger 0:b86d15c6ba29 3572 break;
Vanger 0:b86d15c6ba29 3573
Vanger 0:b86d15c6ba29 3574 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
Vanger 0:b86d15c6ba29 3575 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
Vanger 0:b86d15c6ba29 3576 if (requirement == REQUIRES_RSA_SIG)
Vanger 0:b86d15c6ba29 3577 return 1;
Vanger 0:b86d15c6ba29 3578 if (requirement == REQUIRES_ECC_STATIC)
Vanger 0:b86d15c6ba29 3579 return 1;
Vanger 0:b86d15c6ba29 3580 break;
Vanger 0:b86d15c6ba29 3581 #endif
Vanger 0:b86d15c6ba29 3582
Vanger 0:b86d15c6ba29 3583 case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 :
Vanger 0:b86d15c6ba29 3584 case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
Vanger 0:b86d15c6ba29 3585 if (requirement == REQUIRES_ECC_DSA)
Vanger 0:b86d15c6ba29 3586 return 1;
Vanger 0:b86d15c6ba29 3587 break;
Vanger 0:b86d15c6ba29 3588
Vanger 0:b86d15c6ba29 3589 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
Vanger 0:b86d15c6ba29 3590 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
Vanger 0:b86d15c6ba29 3591 if (requirement == REQUIRES_ECC_DSA)
Vanger 0:b86d15c6ba29 3592 return 1;
Vanger 0:b86d15c6ba29 3593 break;
Vanger 0:b86d15c6ba29 3594
Vanger 0:b86d15c6ba29 3595 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
Vanger 0:b86d15c6ba29 3596 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
Vanger 0:b86d15c6ba29 3597 if (requirement == REQUIRES_ECC_DSA)
Vanger 0:b86d15c6ba29 3598 return 1;
Vanger 0:b86d15c6ba29 3599 if (requirement == REQUIRES_ECC_STATIC)
Vanger 0:b86d15c6ba29 3600 return 1;
Vanger 0:b86d15c6ba29 3601 break;
Vanger 0:b86d15c6ba29 3602
Vanger 0:b86d15c6ba29 3603 case TLS_PSK_WITH_AES_128_CCM:
Vanger 0:b86d15c6ba29 3604 case TLS_PSK_WITH_AES_256_CCM:
Vanger 0:b86d15c6ba29 3605 case TLS_PSK_WITH_AES_128_CCM_8:
Vanger 0:b86d15c6ba29 3606 case TLS_PSK_WITH_AES_256_CCM_8:
Vanger 0:b86d15c6ba29 3607 if (requirement == REQUIRES_PSK)
Vanger 0:b86d15c6ba29 3608 return 1;
Vanger 0:b86d15c6ba29 3609 break;
Vanger 0:b86d15c6ba29 3610
Vanger 0:b86d15c6ba29 3611 case TLS_DHE_PSK_WITH_AES_128_CCM:
Vanger 0:b86d15c6ba29 3612 case TLS_DHE_PSK_WITH_AES_256_CCM:
Vanger 0:b86d15c6ba29 3613 if (requirement == REQUIRES_PSK)
Vanger 0:b86d15c6ba29 3614 return 1;
Vanger 0:b86d15c6ba29 3615 if (requirement == REQUIRES_DHE)
Vanger 0:b86d15c6ba29 3616 return 1;
Vanger 0:b86d15c6ba29 3617 break;
Vanger 0:b86d15c6ba29 3618
Vanger 0:b86d15c6ba29 3619 default:
Vanger 0:b86d15c6ba29 3620 CYASSL_MSG("Unsupported cipher suite, CipherRequires ECC");
Vanger 0:b86d15c6ba29 3621 return 0;
Vanger 0:b86d15c6ba29 3622 } /* switch */
Vanger 0:b86d15c6ba29 3623 } /* if */
Vanger 0:b86d15c6ba29 3624 if (first != ECC_BYTE) { /* normal suites */
Vanger 0:b86d15c6ba29 3625 switch (second) {
Vanger 0:b86d15c6ba29 3626
Vanger 0:b86d15c6ba29 3627 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 3628 case SSL_RSA_WITH_RC4_128_SHA :
Vanger 0:b86d15c6ba29 3629 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3630 return 1;
Vanger 0:b86d15c6ba29 3631 break;
Vanger 0:b86d15c6ba29 3632
Vanger 0:b86d15c6ba29 3633 case TLS_NTRU_RSA_WITH_RC4_128_SHA :
Vanger 0:b86d15c6ba29 3634 if (requirement == REQUIRES_NTRU)
Vanger 0:b86d15c6ba29 3635 return 1;
Vanger 0:b86d15c6ba29 3636 break;
Vanger 0:b86d15c6ba29 3637
Vanger 0:b86d15c6ba29 3638 case SSL_RSA_WITH_RC4_128_MD5 :
Vanger 0:b86d15c6ba29 3639 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3640 return 1;
Vanger 0:b86d15c6ba29 3641 break;
Vanger 0:b86d15c6ba29 3642
Vanger 0:b86d15c6ba29 3643 case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
Vanger 0:b86d15c6ba29 3644 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3645 return 1;
Vanger 0:b86d15c6ba29 3646 break;
Vanger 0:b86d15c6ba29 3647
Vanger 0:b86d15c6ba29 3648 case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
Vanger 0:b86d15c6ba29 3649 if (requirement == REQUIRES_NTRU)
Vanger 0:b86d15c6ba29 3650 return 1;
Vanger 0:b86d15c6ba29 3651 break;
Vanger 0:b86d15c6ba29 3652
Vanger 0:b86d15c6ba29 3653 case TLS_RSA_WITH_AES_128_CBC_SHA :
Vanger 0:b86d15c6ba29 3654 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3655 return 1;
Vanger 0:b86d15c6ba29 3656 break;
Vanger 0:b86d15c6ba29 3657
Vanger 0:b86d15c6ba29 3658 case TLS_RSA_WITH_AES_128_CBC_SHA256 :
Vanger 0:b86d15c6ba29 3659 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3660 return 1;
Vanger 0:b86d15c6ba29 3661 break;
Vanger 0:b86d15c6ba29 3662
Vanger 0:b86d15c6ba29 3663 case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
Vanger 0:b86d15c6ba29 3664 if (requirement == REQUIRES_NTRU)
Vanger 0:b86d15c6ba29 3665 return 1;
Vanger 0:b86d15c6ba29 3666 break;
Vanger 0:b86d15c6ba29 3667
Vanger 0:b86d15c6ba29 3668 case TLS_RSA_WITH_AES_256_CBC_SHA :
Vanger 0:b86d15c6ba29 3669 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3670 return 1;
Vanger 0:b86d15c6ba29 3671 break;
Vanger 0:b86d15c6ba29 3672
Vanger 0:b86d15c6ba29 3673 case TLS_RSA_WITH_AES_256_CBC_SHA256 :
Vanger 0:b86d15c6ba29 3674 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3675 return 1;
Vanger 0:b86d15c6ba29 3676 break;
Vanger 0:b86d15c6ba29 3677
Vanger 0:b86d15c6ba29 3678 case TLS_RSA_WITH_NULL_SHA :
Vanger 0:b86d15c6ba29 3679 case TLS_RSA_WITH_NULL_SHA256 :
Vanger 0:b86d15c6ba29 3680 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3681 return 1;
Vanger 0:b86d15c6ba29 3682 break;
Vanger 0:b86d15c6ba29 3683
Vanger 0:b86d15c6ba29 3684 case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
Vanger 0:b86d15c6ba29 3685 if (requirement == REQUIRES_NTRU)
Vanger 0:b86d15c6ba29 3686 return 1;
Vanger 0:b86d15c6ba29 3687 break;
Vanger 0:b86d15c6ba29 3688 #endif
Vanger 0:b86d15c6ba29 3689
Vanger 0:b86d15c6ba29 3690 case TLS_PSK_WITH_AES_128_GCM_SHA256 :
Vanger 0:b86d15c6ba29 3691 case TLS_PSK_WITH_AES_256_GCM_SHA384 :
Vanger 0:b86d15c6ba29 3692 case TLS_PSK_WITH_AES_128_CBC_SHA256 :
Vanger 0:b86d15c6ba29 3693 case TLS_PSK_WITH_AES_256_CBC_SHA384 :
Vanger 0:b86d15c6ba29 3694 case TLS_PSK_WITH_AES_128_CBC_SHA :
Vanger 0:b86d15c6ba29 3695 case TLS_PSK_WITH_AES_256_CBC_SHA :
Vanger 0:b86d15c6ba29 3696 case TLS_PSK_WITH_NULL_SHA384 :
Vanger 0:b86d15c6ba29 3697 case TLS_PSK_WITH_NULL_SHA256 :
Vanger 0:b86d15c6ba29 3698 case TLS_PSK_WITH_NULL_SHA :
Vanger 0:b86d15c6ba29 3699 if (requirement == REQUIRES_PSK)
Vanger 0:b86d15c6ba29 3700 return 1;
Vanger 0:b86d15c6ba29 3701 break;
Vanger 0:b86d15c6ba29 3702
Vanger 0:b86d15c6ba29 3703 case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 :
Vanger 0:b86d15c6ba29 3704 case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 :
Vanger 0:b86d15c6ba29 3705 case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 :
Vanger 0:b86d15c6ba29 3706 case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 :
Vanger 0:b86d15c6ba29 3707 case TLS_DHE_PSK_WITH_NULL_SHA384 :
Vanger 0:b86d15c6ba29 3708 case TLS_DHE_PSK_WITH_NULL_SHA256 :
Vanger 0:b86d15c6ba29 3709 if (requirement == REQUIRES_DHE)
Vanger 0:b86d15c6ba29 3710 return 1;
Vanger 0:b86d15c6ba29 3711 if (requirement == REQUIRES_PSK)
Vanger 0:b86d15c6ba29 3712 return 1;
Vanger 0:b86d15c6ba29 3713 break;
Vanger 0:b86d15c6ba29 3714
Vanger 0:b86d15c6ba29 3715 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 3716 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
Vanger 0:b86d15c6ba29 3717 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3718 return 1;
Vanger 0:b86d15c6ba29 3719 if (requirement == REQUIRES_DHE)
Vanger 0:b86d15c6ba29 3720 return 1;
Vanger 0:b86d15c6ba29 3721 break;
Vanger 0:b86d15c6ba29 3722
Vanger 0:b86d15c6ba29 3723 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
Vanger 0:b86d15c6ba29 3724 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3725 return 1;
Vanger 0:b86d15c6ba29 3726 if (requirement == REQUIRES_DHE)
Vanger 0:b86d15c6ba29 3727 return 1;
Vanger 0:b86d15c6ba29 3728 break;
Vanger 0:b86d15c6ba29 3729
Vanger 0:b86d15c6ba29 3730 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
Vanger 0:b86d15c6ba29 3731 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3732 return 1;
Vanger 0:b86d15c6ba29 3733 if (requirement == REQUIRES_DHE)
Vanger 0:b86d15c6ba29 3734 return 1;
Vanger 0:b86d15c6ba29 3735 break;
Vanger 0:b86d15c6ba29 3736
Vanger 0:b86d15c6ba29 3737 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
Vanger 0:b86d15c6ba29 3738 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3739 return 1;
Vanger 0:b86d15c6ba29 3740 if (requirement == REQUIRES_DHE)
Vanger 0:b86d15c6ba29 3741 return 1;
Vanger 0:b86d15c6ba29 3742 break;
Vanger 0:b86d15c6ba29 3743
Vanger 0:b86d15c6ba29 3744 case TLS_RSA_WITH_HC_128_MD5 :
Vanger 0:b86d15c6ba29 3745 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3746 return 1;
Vanger 0:b86d15c6ba29 3747 break;
Vanger 0:b86d15c6ba29 3748
Vanger 0:b86d15c6ba29 3749 case TLS_RSA_WITH_HC_128_SHA :
Vanger 0:b86d15c6ba29 3750 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3751 return 1;
Vanger 0:b86d15c6ba29 3752 break;
Vanger 0:b86d15c6ba29 3753
Vanger 0:b86d15c6ba29 3754 case TLS_RSA_WITH_HC_128_B2B256:
Vanger 0:b86d15c6ba29 3755 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3756 return 1;
Vanger 0:b86d15c6ba29 3757 break;
Vanger 0:b86d15c6ba29 3758
Vanger 0:b86d15c6ba29 3759 case TLS_RSA_WITH_AES_128_CBC_B2B256:
Vanger 0:b86d15c6ba29 3760 case TLS_RSA_WITH_AES_256_CBC_B2B256:
Vanger 0:b86d15c6ba29 3761 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3762 return 1;
Vanger 0:b86d15c6ba29 3763 break;
Vanger 0:b86d15c6ba29 3764
Vanger 0:b86d15c6ba29 3765 case TLS_RSA_WITH_RABBIT_SHA :
Vanger 0:b86d15c6ba29 3766 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3767 return 1;
Vanger 0:b86d15c6ba29 3768 break;
Vanger 0:b86d15c6ba29 3769
Vanger 0:b86d15c6ba29 3770 case TLS_RSA_WITH_AES_128_GCM_SHA256 :
Vanger 0:b86d15c6ba29 3771 case TLS_RSA_WITH_AES_256_GCM_SHA384 :
Vanger 0:b86d15c6ba29 3772 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3773 return 1;
Vanger 0:b86d15c6ba29 3774 break;
Vanger 0:b86d15c6ba29 3775
Vanger 0:b86d15c6ba29 3776 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
Vanger 0:b86d15c6ba29 3777 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
Vanger 0:b86d15c6ba29 3778 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3779 return 1;
Vanger 0:b86d15c6ba29 3780 if (requirement == REQUIRES_DHE)
Vanger 0:b86d15c6ba29 3781 return 1;
Vanger 0:b86d15c6ba29 3782 break;
Vanger 0:b86d15c6ba29 3783
Vanger 0:b86d15c6ba29 3784 case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
Vanger 0:b86d15c6ba29 3785 case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
Vanger 0:b86d15c6ba29 3786 case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
Vanger 0:b86d15c6ba29 3787 case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
Vanger 0:b86d15c6ba29 3788 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3789 return 1;
Vanger 0:b86d15c6ba29 3790 break;
Vanger 0:b86d15c6ba29 3791
Vanger 0:b86d15c6ba29 3792 case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
Vanger 0:b86d15c6ba29 3793 case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
Vanger 0:b86d15c6ba29 3794 case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
Vanger 0:b86d15c6ba29 3795 case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
Vanger 0:b86d15c6ba29 3796 if (requirement == REQUIRES_RSA)
Vanger 0:b86d15c6ba29 3797 return 1;
Vanger 0:b86d15c6ba29 3798 if (requirement == REQUIRES_RSA_SIG)
Vanger 0:b86d15c6ba29 3799 return 1;
Vanger 0:b86d15c6ba29 3800 if (requirement == REQUIRES_DHE)
Vanger 0:b86d15c6ba29 3801 return 1;
Vanger 0:b86d15c6ba29 3802 break;
Vanger 0:b86d15c6ba29 3803 #endif
Vanger 0:b86d15c6ba29 3804 #ifdef HAVE_ANON
Vanger 0:b86d15c6ba29 3805 case TLS_DH_anon_WITH_AES_128_CBC_SHA :
Vanger 0:b86d15c6ba29 3806 if (requirement == REQUIRES_DHE)
Vanger 0:b86d15c6ba29 3807 return 1;
Vanger 0:b86d15c6ba29 3808 break;
Vanger 0:b86d15c6ba29 3809 #endif
Vanger 0:b86d15c6ba29 3810
Vanger 0:b86d15c6ba29 3811 default:
Vanger 0:b86d15c6ba29 3812 CYASSL_MSG("Unsupported cipher suite, CipherRequires");
Vanger 0:b86d15c6ba29 3813 return 0;
Vanger 0:b86d15c6ba29 3814 } /* switch */
Vanger 0:b86d15c6ba29 3815 } /* if ECC / Normal suites else */
Vanger 0:b86d15c6ba29 3816
Vanger 0:b86d15c6ba29 3817 return 0;
Vanger 0:b86d15c6ba29 3818 }
Vanger 0:b86d15c6ba29 3819
Vanger 0:b86d15c6ba29 3820
Vanger 0:b86d15c6ba29 3821 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 3822
Vanger 0:b86d15c6ba29 3823
Vanger 0:b86d15c6ba29 3824 /* Match names with wildcards, each wildcard can represent a single name
Vanger 0:b86d15c6ba29 3825 component or fragment but not mulitple names, i.e.,
Vanger 0:b86d15c6ba29 3826 *.z.com matches y.z.com but not x.y.z.com
Vanger 0:b86d15c6ba29 3827
Vanger 0:b86d15c6ba29 3828 return 1 on success */
Vanger 0:b86d15c6ba29 3829 static int MatchDomainName(const char* pattern, int len, const char* str)
Vanger 0:b86d15c6ba29 3830 {
Vanger 0:b86d15c6ba29 3831 char p, s;
Vanger 0:b86d15c6ba29 3832
Vanger 0:b86d15c6ba29 3833 if (pattern == NULL || str == NULL || len <= 0)
Vanger 0:b86d15c6ba29 3834 return 0;
Vanger 0:b86d15c6ba29 3835
Vanger 0:b86d15c6ba29 3836 while (len > 0) {
Vanger 0:b86d15c6ba29 3837
Vanger 0:b86d15c6ba29 3838 p = (char)XTOLOWER(*pattern++);
Vanger 0:b86d15c6ba29 3839 if (p == 0)
Vanger 0:b86d15c6ba29 3840 break;
Vanger 0:b86d15c6ba29 3841
Vanger 0:b86d15c6ba29 3842 if (p == '*') {
Vanger 0:b86d15c6ba29 3843 while (--len > 0 && (p = (char)XTOLOWER(*pattern++)) == '*')
Vanger 0:b86d15c6ba29 3844 ;
Vanger 0:b86d15c6ba29 3845
Vanger 0:b86d15c6ba29 3846 if (len == 0)
Vanger 0:b86d15c6ba29 3847 p = '\0';
Vanger 0:b86d15c6ba29 3848
Vanger 0:b86d15c6ba29 3849 while ( (s = (char)XTOLOWER(*str)) != '\0') {
Vanger 0:b86d15c6ba29 3850 if (s == p)
Vanger 0:b86d15c6ba29 3851 break;
Vanger 0:b86d15c6ba29 3852 if (s == '.')
Vanger 0:b86d15c6ba29 3853 return 0;
Vanger 0:b86d15c6ba29 3854 str++;
Vanger 0:b86d15c6ba29 3855 }
Vanger 0:b86d15c6ba29 3856 }
Vanger 0:b86d15c6ba29 3857 else {
Vanger 0:b86d15c6ba29 3858 if (p != (char)XTOLOWER(*str))
Vanger 0:b86d15c6ba29 3859 return 0;
Vanger 0:b86d15c6ba29 3860 }
Vanger 0:b86d15c6ba29 3861
Vanger 0:b86d15c6ba29 3862 if (*str != '\0')
Vanger 0:b86d15c6ba29 3863 str++;
Vanger 0:b86d15c6ba29 3864
Vanger 0:b86d15c6ba29 3865 if (len > 0)
Vanger 0:b86d15c6ba29 3866 len--;
Vanger 0:b86d15c6ba29 3867 }
Vanger 0:b86d15c6ba29 3868
Vanger 0:b86d15c6ba29 3869 return *str == '\0';
Vanger 0:b86d15c6ba29 3870 }
Vanger 0:b86d15c6ba29 3871
Vanger 0:b86d15c6ba29 3872
Vanger 0:b86d15c6ba29 3873 /* try to find an altName match to domain, return 1 on success */
Vanger 0:b86d15c6ba29 3874 static int CheckAltNames(DecodedCert* dCert, char* domain)
Vanger 0:b86d15c6ba29 3875 {
Vanger 0:b86d15c6ba29 3876 int match = 0;
Vanger 0:b86d15c6ba29 3877 DNS_entry* altName = NULL;
Vanger 0:b86d15c6ba29 3878
Vanger 0:b86d15c6ba29 3879 CYASSL_MSG("Checking AltNames");
Vanger 0:b86d15c6ba29 3880
Vanger 0:b86d15c6ba29 3881 if (dCert)
Vanger 0:b86d15c6ba29 3882 altName = dCert->altNames;
Vanger 0:b86d15c6ba29 3883
Vanger 0:b86d15c6ba29 3884 while (altName) {
Vanger 0:b86d15c6ba29 3885 CYASSL_MSG(" individual AltName check");
Vanger 0:b86d15c6ba29 3886
Vanger 0:b86d15c6ba29 3887 if (MatchDomainName(altName->name,(int)XSTRLEN(altName->name), domain)){
Vanger 0:b86d15c6ba29 3888 match = 1;
Vanger 0:b86d15c6ba29 3889 break;
Vanger 0:b86d15c6ba29 3890 }
Vanger 0:b86d15c6ba29 3891
Vanger 0:b86d15c6ba29 3892 altName = altName->next;
Vanger 0:b86d15c6ba29 3893 }
Vanger 0:b86d15c6ba29 3894
Vanger 0:b86d15c6ba29 3895 return match;
Vanger 0:b86d15c6ba29 3896 }
Vanger 0:b86d15c6ba29 3897
Vanger 0:b86d15c6ba29 3898
Vanger 0:b86d15c6ba29 3899 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
Vanger 0:b86d15c6ba29 3900
Vanger 0:b86d15c6ba29 3901 /* Copy parts X509 needs from Decoded cert, 0 on success */
Vanger 0:b86d15c6ba29 3902 int CopyDecodedToX509(CYASSL_X509* x509, DecodedCert* dCert)
Vanger 0:b86d15c6ba29 3903 {
Vanger 0:b86d15c6ba29 3904 int ret = 0;
Vanger 0:b86d15c6ba29 3905
Vanger 0:b86d15c6ba29 3906 if (x509 == NULL || dCert == NULL)
Vanger 0:b86d15c6ba29 3907 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 3908
Vanger 0:b86d15c6ba29 3909 x509->version = dCert->version + 1;
Vanger 0:b86d15c6ba29 3910
Vanger 0:b86d15c6ba29 3911 XSTRNCPY(x509->issuer.name, dCert->issuer, ASN_NAME_MAX);
Vanger 0:b86d15c6ba29 3912 x509->issuer.name[ASN_NAME_MAX - 1] = '\0';
Vanger 0:b86d15c6ba29 3913 x509->issuer.sz = (int)XSTRLEN(x509->issuer.name) + 1;
Vanger 0:b86d15c6ba29 3914 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 3915 if (dCert->issuerName.fullName != NULL) {
Vanger 0:b86d15c6ba29 3916 XMEMCPY(&x509->issuer.fullName,
Vanger 0:b86d15c6ba29 3917 &dCert->issuerName, sizeof(DecodedName));
Vanger 0:b86d15c6ba29 3918 x509->issuer.fullName.fullName = (char*)XMALLOC(
Vanger 0:b86d15c6ba29 3919 dCert->issuerName.fullNameLen, NULL, DYNAMIC_TYPE_X509);
Vanger 0:b86d15c6ba29 3920 if (x509->issuer.fullName.fullName != NULL)
Vanger 0:b86d15c6ba29 3921 XMEMCPY(x509->issuer.fullName.fullName,
Vanger 0:b86d15c6ba29 3922 dCert->issuerName.fullName, dCert->issuerName.fullNameLen);
Vanger 0:b86d15c6ba29 3923 }
Vanger 0:b86d15c6ba29 3924 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 3925
Vanger 0:b86d15c6ba29 3926 XSTRNCPY(x509->subject.name, dCert->subject, ASN_NAME_MAX);
Vanger 0:b86d15c6ba29 3927 x509->subject.name[ASN_NAME_MAX - 1] = '\0';
Vanger 0:b86d15c6ba29 3928 x509->subject.sz = (int)XSTRLEN(x509->subject.name) + 1;
Vanger 0:b86d15c6ba29 3929 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 3930 if (dCert->subjectName.fullName != NULL) {
Vanger 0:b86d15c6ba29 3931 XMEMCPY(&x509->subject.fullName,
Vanger 0:b86d15c6ba29 3932 &dCert->subjectName, sizeof(DecodedName));
Vanger 0:b86d15c6ba29 3933 x509->subject.fullName.fullName = (char*)XMALLOC(
Vanger 0:b86d15c6ba29 3934 dCert->subjectName.fullNameLen, NULL, DYNAMIC_TYPE_X509);
Vanger 0:b86d15c6ba29 3935 if (x509->subject.fullName.fullName != NULL)
Vanger 0:b86d15c6ba29 3936 XMEMCPY(x509->subject.fullName.fullName,
Vanger 0:b86d15c6ba29 3937 dCert->subjectName.fullName, dCert->subjectName.fullNameLen);
Vanger 0:b86d15c6ba29 3938 }
Vanger 0:b86d15c6ba29 3939 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 3940
Vanger 0:b86d15c6ba29 3941 XMEMCPY(x509->serial, dCert->serial, EXTERNAL_SERIAL_SIZE);
Vanger 0:b86d15c6ba29 3942 x509->serialSz = dCert->serialSz;
Vanger 0:b86d15c6ba29 3943 if (dCert->subjectCNLen < ASN_NAME_MAX) {
Vanger 0:b86d15c6ba29 3944 XMEMCPY(x509->subjectCN, dCert->subjectCN, dCert->subjectCNLen);
Vanger 0:b86d15c6ba29 3945 x509->subjectCN[dCert->subjectCNLen] = '\0';
Vanger 0:b86d15c6ba29 3946 }
Vanger 0:b86d15c6ba29 3947 else
Vanger 0:b86d15c6ba29 3948 x509->subjectCN[0] = '\0';
Vanger 0:b86d15c6ba29 3949
Vanger 0:b86d15c6ba29 3950 #ifdef CYASSL_SEP
Vanger 0:b86d15c6ba29 3951 {
Vanger 0:b86d15c6ba29 3952 int minSz = min(dCert->deviceTypeSz, EXTERNAL_SERIAL_SIZE);
Vanger 0:b86d15c6ba29 3953 if (minSz > 0) {
Vanger 0:b86d15c6ba29 3954 x509->deviceTypeSz = minSz;
Vanger 0:b86d15c6ba29 3955 XMEMCPY(x509->deviceType, dCert->deviceType, minSz);
Vanger 0:b86d15c6ba29 3956 }
Vanger 0:b86d15c6ba29 3957 else
Vanger 0:b86d15c6ba29 3958 x509->deviceTypeSz = 0;
Vanger 0:b86d15c6ba29 3959 minSz = min(dCert->hwTypeSz, EXTERNAL_SERIAL_SIZE);
Vanger 0:b86d15c6ba29 3960 if (minSz != 0) {
Vanger 0:b86d15c6ba29 3961 x509->hwTypeSz = minSz;
Vanger 0:b86d15c6ba29 3962 XMEMCPY(x509->hwType, dCert->hwType, minSz);
Vanger 0:b86d15c6ba29 3963 }
Vanger 0:b86d15c6ba29 3964 else
Vanger 0:b86d15c6ba29 3965 x509->hwTypeSz = 0;
Vanger 0:b86d15c6ba29 3966 minSz = min(dCert->hwSerialNumSz, EXTERNAL_SERIAL_SIZE);
Vanger 0:b86d15c6ba29 3967 if (minSz != 0) {
Vanger 0:b86d15c6ba29 3968 x509->hwSerialNumSz = minSz;
Vanger 0:b86d15c6ba29 3969 XMEMCPY(x509->hwSerialNum, dCert->hwSerialNum, minSz);
Vanger 0:b86d15c6ba29 3970 }
Vanger 0:b86d15c6ba29 3971 else
Vanger 0:b86d15c6ba29 3972 x509->hwSerialNumSz = 0;
Vanger 0:b86d15c6ba29 3973 }
Vanger 0:b86d15c6ba29 3974 #endif /* CYASSL_SEP */
Vanger 0:b86d15c6ba29 3975 {
Vanger 0:b86d15c6ba29 3976 int minSz = min(dCert->beforeDateLen, MAX_DATE_SZ);
Vanger 0:b86d15c6ba29 3977 if (minSz != 0) {
Vanger 0:b86d15c6ba29 3978 x509->notBeforeSz = minSz;
Vanger 0:b86d15c6ba29 3979 XMEMCPY(x509->notBefore, dCert->beforeDate, minSz);
Vanger 0:b86d15c6ba29 3980 }
Vanger 0:b86d15c6ba29 3981 else
Vanger 0:b86d15c6ba29 3982 x509->notBeforeSz = 0;
Vanger 0:b86d15c6ba29 3983 minSz = min(dCert->afterDateLen, MAX_DATE_SZ);
Vanger 0:b86d15c6ba29 3984 if (minSz != 0) {
Vanger 0:b86d15c6ba29 3985 x509->notAfterSz = minSz;
Vanger 0:b86d15c6ba29 3986 XMEMCPY(x509->notAfter, dCert->afterDate, minSz);
Vanger 0:b86d15c6ba29 3987 }
Vanger 0:b86d15c6ba29 3988 else
Vanger 0:b86d15c6ba29 3989 x509->notAfterSz = 0;
Vanger 0:b86d15c6ba29 3990 }
Vanger 0:b86d15c6ba29 3991
Vanger 0:b86d15c6ba29 3992 if (dCert->publicKey != NULL && dCert->pubKeySize != 0) {
Vanger 0:b86d15c6ba29 3993 x509->pubKey.buffer = (byte*)XMALLOC(
Vanger 0:b86d15c6ba29 3994 dCert->pubKeySize, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
Vanger 0:b86d15c6ba29 3995 if (x509->pubKey.buffer != NULL) {
Vanger 0:b86d15c6ba29 3996 x509->pubKeyOID = dCert->keyOID;
Vanger 0:b86d15c6ba29 3997 x509->pubKey.length = dCert->pubKeySize;
Vanger 0:b86d15c6ba29 3998 XMEMCPY(x509->pubKey.buffer, dCert->publicKey, dCert->pubKeySize);
Vanger 0:b86d15c6ba29 3999 }
Vanger 0:b86d15c6ba29 4000 else
Vanger 0:b86d15c6ba29 4001 ret = MEMORY_E;
Vanger 0:b86d15c6ba29 4002 }
Vanger 0:b86d15c6ba29 4003
Vanger 0:b86d15c6ba29 4004 if (dCert->signature != NULL && dCert->sigLength != 0) {
Vanger 0:b86d15c6ba29 4005 x509->sig.buffer = (byte*)XMALLOC(
Vanger 0:b86d15c6ba29 4006 dCert->sigLength, NULL, DYNAMIC_TYPE_SIGNATURE);
Vanger 0:b86d15c6ba29 4007 if (x509->sig.buffer == NULL) {
Vanger 0:b86d15c6ba29 4008 ret = MEMORY_E;
Vanger 0:b86d15c6ba29 4009 }
Vanger 0:b86d15c6ba29 4010 else {
Vanger 0:b86d15c6ba29 4011 XMEMCPY(x509->sig.buffer, dCert->signature, dCert->sigLength);
Vanger 0:b86d15c6ba29 4012 x509->sig.length = dCert->sigLength;
Vanger 0:b86d15c6ba29 4013 x509->sigOID = dCert->signatureOID;
Vanger 0:b86d15c6ba29 4014 }
Vanger 0:b86d15c6ba29 4015 }
Vanger 0:b86d15c6ba29 4016
Vanger 0:b86d15c6ba29 4017 /* store cert for potential retrieval */
Vanger 0:b86d15c6ba29 4018 x509->derCert.buffer = (byte*)XMALLOC(dCert->maxIdx, NULL,
Vanger 0:b86d15c6ba29 4019 DYNAMIC_TYPE_CERT);
Vanger 0:b86d15c6ba29 4020 if (x509->derCert.buffer == NULL) {
Vanger 0:b86d15c6ba29 4021 ret = MEMORY_E;
Vanger 0:b86d15c6ba29 4022 }
Vanger 0:b86d15c6ba29 4023 else {
Vanger 0:b86d15c6ba29 4024 XMEMCPY(x509->derCert.buffer, dCert->source, dCert->maxIdx);
Vanger 0:b86d15c6ba29 4025 x509->derCert.length = dCert->maxIdx;
Vanger 0:b86d15c6ba29 4026 }
Vanger 0:b86d15c6ba29 4027
Vanger 0:b86d15c6ba29 4028 x509->altNames = dCert->altNames;
Vanger 0:b86d15c6ba29 4029 dCert->altNames = NULL; /* takes ownership */
Vanger 0:b86d15c6ba29 4030 x509->altNamesNext = x509->altNames; /* index hint */
Vanger 0:b86d15c6ba29 4031
Vanger 0:b86d15c6ba29 4032 x509->isCa = dCert->isCA;
Vanger 0:b86d15c6ba29 4033 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 4034 x509->pathLength = dCert->pathLength;
Vanger 0:b86d15c6ba29 4035 x509->keyUsage = dCert->extKeyUsage;
Vanger 0:b86d15c6ba29 4036
Vanger 0:b86d15c6ba29 4037 x509->basicConstSet = dCert->extBasicConstSet;
Vanger 0:b86d15c6ba29 4038 x509->basicConstCrit = dCert->extBasicConstCrit;
Vanger 0:b86d15c6ba29 4039 x509->basicConstPlSet = dCert->extBasicConstPlSet;
Vanger 0:b86d15c6ba29 4040 x509->subjAltNameSet = dCert->extSubjAltNameSet;
Vanger 0:b86d15c6ba29 4041 x509->subjAltNameCrit = dCert->extSubjAltNameCrit;
Vanger 0:b86d15c6ba29 4042 x509->authKeyIdSet = dCert->extAuthKeyIdSet;
Vanger 0:b86d15c6ba29 4043 x509->authKeyIdCrit = dCert->extAuthKeyIdCrit;
Vanger 0:b86d15c6ba29 4044 if (dCert->extAuthKeyIdSrc != NULL && dCert->extAuthKeyIdSz != 0) {
Vanger 0:b86d15c6ba29 4045 x509->authKeyId = (byte*)XMALLOC(dCert->extAuthKeyIdSz, NULL, 0);
Vanger 0:b86d15c6ba29 4046 if (x509->authKeyId != NULL) {
Vanger 0:b86d15c6ba29 4047 XMEMCPY(x509->authKeyId,
Vanger 0:b86d15c6ba29 4048 dCert->extAuthKeyIdSrc, dCert->extAuthKeyIdSz);
Vanger 0:b86d15c6ba29 4049 x509->authKeyIdSz = dCert->extAuthKeyIdSz;
Vanger 0:b86d15c6ba29 4050 }
Vanger 0:b86d15c6ba29 4051 else
Vanger 0:b86d15c6ba29 4052 ret = MEMORY_E;
Vanger 0:b86d15c6ba29 4053 }
Vanger 0:b86d15c6ba29 4054 x509->subjKeyIdSet = dCert->extSubjKeyIdSet;
Vanger 0:b86d15c6ba29 4055 x509->subjKeyIdCrit = dCert->extSubjKeyIdCrit;
Vanger 0:b86d15c6ba29 4056 if (dCert->extSubjKeyIdSrc != NULL && dCert->extSubjKeyIdSz != 0) {
Vanger 0:b86d15c6ba29 4057 x509->subjKeyId = (byte*)XMALLOC(dCert->extSubjKeyIdSz, NULL, 0);
Vanger 0:b86d15c6ba29 4058 if (x509->subjKeyId != NULL) {
Vanger 0:b86d15c6ba29 4059 XMEMCPY(x509->subjKeyId,
Vanger 0:b86d15c6ba29 4060 dCert->extSubjKeyIdSrc, dCert->extSubjKeyIdSz);
Vanger 0:b86d15c6ba29 4061 x509->subjKeyIdSz = dCert->extSubjKeyIdSz;
Vanger 0:b86d15c6ba29 4062 }
Vanger 0:b86d15c6ba29 4063 else
Vanger 0:b86d15c6ba29 4064 ret = MEMORY_E;
Vanger 0:b86d15c6ba29 4065 }
Vanger 0:b86d15c6ba29 4066 x509->keyUsageSet = dCert->extKeyUsageSet;
Vanger 0:b86d15c6ba29 4067 x509->keyUsageCrit = dCert->extKeyUsageCrit;
Vanger 0:b86d15c6ba29 4068 #ifdef CYASSL_SEP
Vanger 0:b86d15c6ba29 4069 x509->certPolicySet = dCert->extCertPolicySet;
Vanger 0:b86d15c6ba29 4070 x509->certPolicyCrit = dCert->extCertPolicyCrit;
Vanger 0:b86d15c6ba29 4071 #endif /* CYASSL_SEP */
Vanger 0:b86d15c6ba29 4072 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 4073 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 4074 x509->pkCurveOID = dCert->pkCurveOID;
Vanger 0:b86d15c6ba29 4075 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 4076
Vanger 0:b86d15c6ba29 4077 return ret;
Vanger 0:b86d15c6ba29 4078 }
Vanger 0:b86d15c6ba29 4079
Vanger 0:b86d15c6ba29 4080 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
Vanger 0:b86d15c6ba29 4081
Vanger 0:b86d15c6ba29 4082
Vanger 0:b86d15c6ba29 4083 static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx,
Vanger 0:b86d15c6ba29 4084 word32 size)
Vanger 0:b86d15c6ba29 4085 {
Vanger 0:b86d15c6ba29 4086 word32 listSz;
Vanger 0:b86d15c6ba29 4087 word32 begin = *inOutIdx;
Vanger 0:b86d15c6ba29 4088 int ret = 0;
Vanger 0:b86d15c6ba29 4089 int anyError = 0;
Vanger 0:b86d15c6ba29 4090 int totalCerts = 0; /* number of certs in certs buffer */
Vanger 0:b86d15c6ba29 4091 int count;
Vanger 0:b86d15c6ba29 4092 buffer certs[MAX_CHAIN_DEPTH];
Vanger 0:b86d15c6ba29 4093
Vanger 0:b86d15c6ba29 4094 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4095 char* domain = NULL;
Vanger 0:b86d15c6ba29 4096 DecodedCert* dCert = NULL;
Vanger 0:b86d15c6ba29 4097 CYASSL_X509_STORE_CTX* store = NULL;
Vanger 0:b86d15c6ba29 4098 #else
Vanger 0:b86d15c6ba29 4099 char domain[ASN_NAME_MAX];
Vanger 0:b86d15c6ba29 4100 DecodedCert dCert[1];
Vanger 0:b86d15c6ba29 4101 CYASSL_X509_STORE_CTX store[1];
Vanger 0:b86d15c6ba29 4102 #endif
Vanger 0:b86d15c6ba29 4103
Vanger 0:b86d15c6ba29 4104 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 4105 if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 4106 if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo);
Vanger 0:b86d15c6ba29 4107 #endif
Vanger 0:b86d15c6ba29 4108
Vanger 0:b86d15c6ba29 4109 if ((*inOutIdx - begin) + OPAQUE24_LEN > size)
Vanger 0:b86d15c6ba29 4110 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 4111
Vanger 0:b86d15c6ba29 4112 c24to32(input + *inOutIdx, &listSz);
Vanger 0:b86d15c6ba29 4113 *inOutIdx += OPAQUE24_LEN;
Vanger 0:b86d15c6ba29 4114
Vanger 0:b86d15c6ba29 4115 #ifdef HAVE_MAX_FRAGMENT
Vanger 0:b86d15c6ba29 4116 if (listSz > ssl->max_fragment) {
Vanger 0:b86d15c6ba29 4117 SendAlert(ssl, alert_fatal, record_overflow);
Vanger 0:b86d15c6ba29 4118 return BUFFER_E;
Vanger 0:b86d15c6ba29 4119 }
Vanger 0:b86d15c6ba29 4120 #else
Vanger 0:b86d15c6ba29 4121 if (listSz > MAX_RECORD_SIZE)
Vanger 0:b86d15c6ba29 4122 return BUFFER_E;
Vanger 0:b86d15c6ba29 4123 #endif
Vanger 0:b86d15c6ba29 4124
Vanger 0:b86d15c6ba29 4125 if ((*inOutIdx - begin) + listSz != size)
Vanger 0:b86d15c6ba29 4126 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 4127
Vanger 0:b86d15c6ba29 4128 CYASSL_MSG("Loading peer's cert chain");
Vanger 0:b86d15c6ba29 4129 /* first put cert chain into buffer so can verify top down
Vanger 0:b86d15c6ba29 4130 we're sent bottom up */
Vanger 0:b86d15c6ba29 4131 while (listSz) {
Vanger 0:b86d15c6ba29 4132 word32 certSz;
Vanger 0:b86d15c6ba29 4133
Vanger 0:b86d15c6ba29 4134 if (totalCerts >= MAX_CHAIN_DEPTH)
Vanger 0:b86d15c6ba29 4135 return MAX_CHAIN_ERROR;
Vanger 0:b86d15c6ba29 4136
Vanger 0:b86d15c6ba29 4137 if ((*inOutIdx - begin) + OPAQUE24_LEN > size)
Vanger 0:b86d15c6ba29 4138 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 4139
Vanger 0:b86d15c6ba29 4140 c24to32(input + *inOutIdx, &certSz);
Vanger 0:b86d15c6ba29 4141 *inOutIdx += OPAQUE24_LEN;
Vanger 0:b86d15c6ba29 4142
Vanger 0:b86d15c6ba29 4143 if ((*inOutIdx - begin) + certSz > size)
Vanger 0:b86d15c6ba29 4144 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 4145
Vanger 0:b86d15c6ba29 4146 certs[totalCerts].length = certSz;
Vanger 0:b86d15c6ba29 4147 certs[totalCerts].buffer = input + *inOutIdx;
Vanger 0:b86d15c6ba29 4148
Vanger 0:b86d15c6ba29 4149 #ifdef SESSION_CERTS
Vanger 0:b86d15c6ba29 4150 if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
Vanger 0:b86d15c6ba29 4151 certSz < MAX_X509_SIZE) {
Vanger 0:b86d15c6ba29 4152 ssl->session.chain.certs[ssl->session.chain.count].length = certSz;
Vanger 0:b86d15c6ba29 4153 XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer,
Vanger 0:b86d15c6ba29 4154 input + *inOutIdx, certSz);
Vanger 0:b86d15c6ba29 4155 ssl->session.chain.count++;
Vanger 0:b86d15c6ba29 4156 } else {
Vanger 0:b86d15c6ba29 4157 CYASSL_MSG("Couldn't store chain cert for session");
Vanger 0:b86d15c6ba29 4158 }
Vanger 0:b86d15c6ba29 4159 #endif
Vanger 0:b86d15c6ba29 4160
Vanger 0:b86d15c6ba29 4161 *inOutIdx += certSz;
Vanger 0:b86d15c6ba29 4162 listSz -= certSz + CERT_HEADER_SZ;
Vanger 0:b86d15c6ba29 4163
Vanger 0:b86d15c6ba29 4164 totalCerts++;
Vanger 0:b86d15c6ba29 4165 CYASSL_MSG(" Put another cert into chain");
Vanger 0:b86d15c6ba29 4166 }
Vanger 0:b86d15c6ba29 4167
Vanger 0:b86d15c6ba29 4168 count = totalCerts;
Vanger 0:b86d15c6ba29 4169
Vanger 0:b86d15c6ba29 4170 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4171 dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
Vanger 0:b86d15c6ba29 4172 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4173 if (dCert == NULL)
Vanger 0:b86d15c6ba29 4174 return MEMORY_E;
Vanger 0:b86d15c6ba29 4175 #endif
Vanger 0:b86d15c6ba29 4176
Vanger 0:b86d15c6ba29 4177 /* verify up to peer's first */
Vanger 0:b86d15c6ba29 4178 while (count > 1) {
Vanger 0:b86d15c6ba29 4179 buffer myCert = certs[count - 1];
Vanger 0:b86d15c6ba29 4180 byte* subjectHash;
Vanger 0:b86d15c6ba29 4181
Vanger 0:b86d15c6ba29 4182 InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap);
Vanger 0:b86d15c6ba29 4183 ret = ParseCertRelative(dCert, CERT_TYPE, !ssl->options.verifyNone,
Vanger 0:b86d15c6ba29 4184 ssl->ctx->cm);
Vanger 0:b86d15c6ba29 4185 #ifndef NO_SKID
Vanger 0:b86d15c6ba29 4186 subjectHash = dCert->extSubjKeyId;
Vanger 0:b86d15c6ba29 4187 #else
Vanger 0:b86d15c6ba29 4188 subjectHash = dCert->subjectHash;
Vanger 0:b86d15c6ba29 4189 #endif
Vanger 0:b86d15c6ba29 4190
Vanger 0:b86d15c6ba29 4191 if (ret == 0 && dCert->isCA == 0) {
Vanger 0:b86d15c6ba29 4192 CYASSL_MSG("Chain cert is not a CA, not adding as one");
Vanger 0:b86d15c6ba29 4193 }
Vanger 0:b86d15c6ba29 4194 else if (ret == 0 && ssl->options.verifyNone) {
Vanger 0:b86d15c6ba29 4195 CYASSL_MSG("Chain cert not verified by option, not adding as CA");
Vanger 0:b86d15c6ba29 4196 }
Vanger 0:b86d15c6ba29 4197 else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, subjectHash)) {
Vanger 0:b86d15c6ba29 4198 buffer add;
Vanger 0:b86d15c6ba29 4199 add.length = myCert.length;
Vanger 0:b86d15c6ba29 4200 add.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
Vanger 0:b86d15c6ba29 4201 DYNAMIC_TYPE_CA);
Vanger 0:b86d15c6ba29 4202 CYASSL_MSG("Adding CA from chain");
Vanger 0:b86d15c6ba29 4203
Vanger 0:b86d15c6ba29 4204 if (add.buffer == NULL)
Vanger 0:b86d15c6ba29 4205 return MEMORY_E;
Vanger 0:b86d15c6ba29 4206 XMEMCPY(add.buffer, myCert.buffer, myCert.length);
Vanger 0:b86d15c6ba29 4207
Vanger 0:b86d15c6ba29 4208 ret = AddCA(ssl->ctx->cm, add, CYASSL_CHAIN_CA,
Vanger 0:b86d15c6ba29 4209 ssl->ctx->verifyPeer);
Vanger 0:b86d15c6ba29 4210 if (ret == 1) ret = 0; /* SSL_SUCCESS for external */
Vanger 0:b86d15c6ba29 4211 }
Vanger 0:b86d15c6ba29 4212 else if (ret != 0) {
Vanger 0:b86d15c6ba29 4213 CYASSL_MSG("Failed to verify CA from chain");
Vanger 0:b86d15c6ba29 4214 }
Vanger 0:b86d15c6ba29 4215 else {
Vanger 0:b86d15c6ba29 4216 CYASSL_MSG("Verified CA from chain and already had it");
Vanger 0:b86d15c6ba29 4217 }
Vanger 0:b86d15c6ba29 4218
Vanger 0:b86d15c6ba29 4219 #ifdef HAVE_CRL
Vanger 0:b86d15c6ba29 4220 if (ret == 0 && ssl->ctx->cm->crlEnabled && ssl->ctx->cm->crlCheckAll) {
Vanger 0:b86d15c6ba29 4221 CYASSL_MSG("Doing Non Leaf CRL check");
Vanger 0:b86d15c6ba29 4222 ret = CheckCertCRL(ssl->ctx->cm->crl, dCert);
Vanger 0:b86d15c6ba29 4223
Vanger 0:b86d15c6ba29 4224 if (ret != 0) {
Vanger 0:b86d15c6ba29 4225 CYASSL_MSG("\tCRL check not ok");
Vanger 0:b86d15c6ba29 4226 }
Vanger 0:b86d15c6ba29 4227 }
Vanger 0:b86d15c6ba29 4228 #endif /* HAVE_CRL */
Vanger 0:b86d15c6ba29 4229
Vanger 0:b86d15c6ba29 4230 if (ret != 0 && anyError == 0)
Vanger 0:b86d15c6ba29 4231 anyError = ret; /* save error from last time */
Vanger 0:b86d15c6ba29 4232
Vanger 0:b86d15c6ba29 4233 FreeDecodedCert(dCert);
Vanger 0:b86d15c6ba29 4234 count--;
Vanger 0:b86d15c6ba29 4235 }
Vanger 0:b86d15c6ba29 4236
Vanger 0:b86d15c6ba29 4237 /* peer's, may not have one if blank client cert sent by TLSv1.2 */
Vanger 0:b86d15c6ba29 4238 if (count) {
Vanger 0:b86d15c6ba29 4239 buffer myCert = certs[0];
Vanger 0:b86d15c6ba29 4240 int fatal = 0;
Vanger 0:b86d15c6ba29 4241
Vanger 0:b86d15c6ba29 4242 CYASSL_MSG("Verifying Peer's cert");
Vanger 0:b86d15c6ba29 4243
Vanger 0:b86d15c6ba29 4244 InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap);
Vanger 0:b86d15c6ba29 4245 ret = ParseCertRelative(dCert, CERT_TYPE, !ssl->options.verifyNone,
Vanger 0:b86d15c6ba29 4246 ssl->ctx->cm);
Vanger 0:b86d15c6ba29 4247 if (ret == 0) {
Vanger 0:b86d15c6ba29 4248 CYASSL_MSG("Verified Peer's cert");
Vanger 0:b86d15c6ba29 4249 fatal = 0;
Vanger 0:b86d15c6ba29 4250 }
Vanger 0:b86d15c6ba29 4251 else if (ret == ASN_PARSE_E) {
Vanger 0:b86d15c6ba29 4252 CYASSL_MSG("Got Peer cert ASN PARSE ERROR, fatal");
Vanger 0:b86d15c6ba29 4253 fatal = 1;
Vanger 0:b86d15c6ba29 4254 }
Vanger 0:b86d15c6ba29 4255 else {
Vanger 0:b86d15c6ba29 4256 CYASSL_MSG("Failed to verify Peer's cert");
Vanger 0:b86d15c6ba29 4257 if (ssl->verifyCallback) {
Vanger 0:b86d15c6ba29 4258 CYASSL_MSG("\tCallback override available, will continue");
Vanger 0:b86d15c6ba29 4259 fatal = 0;
Vanger 0:b86d15c6ba29 4260 }
Vanger 0:b86d15c6ba29 4261 else {
Vanger 0:b86d15c6ba29 4262 CYASSL_MSG("\tNo callback override available, fatal");
Vanger 0:b86d15c6ba29 4263 fatal = 1;
Vanger 0:b86d15c6ba29 4264 }
Vanger 0:b86d15c6ba29 4265 }
Vanger 0:b86d15c6ba29 4266
Vanger 0:b86d15c6ba29 4267 #ifdef HAVE_SECURE_RENEGOTIATION
Vanger 0:b86d15c6ba29 4268 if (fatal == 0 && ssl->secure_renegotiation
Vanger 0:b86d15c6ba29 4269 && ssl->secure_renegotiation->enabled) {
Vanger 0:b86d15c6ba29 4270
Vanger 0:b86d15c6ba29 4271 if (ssl->keys.encryptionOn) {
Vanger 0:b86d15c6ba29 4272 /* compare against previous time */
Vanger 0:b86d15c6ba29 4273 if (XMEMCMP(dCert->subjectHash,
Vanger 0:b86d15c6ba29 4274 ssl->secure_renegotiation->subject_hash,
Vanger 0:b86d15c6ba29 4275 SHA_DIGEST_SIZE) != 0) {
Vanger 0:b86d15c6ba29 4276 CYASSL_MSG("Peer sent different cert during scr, fatal");
Vanger 0:b86d15c6ba29 4277 fatal = 1;
Vanger 0:b86d15c6ba29 4278 ret = SCR_DIFFERENT_CERT_E;
Vanger 0:b86d15c6ba29 4279 }
Vanger 0:b86d15c6ba29 4280 }
Vanger 0:b86d15c6ba29 4281
Vanger 0:b86d15c6ba29 4282 /* cache peer's hash */
Vanger 0:b86d15c6ba29 4283 if (fatal == 0) {
Vanger 0:b86d15c6ba29 4284 XMEMCPY(ssl->secure_renegotiation->subject_hash,
Vanger 0:b86d15c6ba29 4285 dCert->subjectHash, SHA_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 4286 }
Vanger 0:b86d15c6ba29 4287 }
Vanger 0:b86d15c6ba29 4288 #endif
Vanger 0:b86d15c6ba29 4289
Vanger 0:b86d15c6ba29 4290 #ifdef HAVE_OCSP
Vanger 0:b86d15c6ba29 4291 if (fatal == 0 && ssl->ctx->cm->ocspEnabled) {
Vanger 0:b86d15c6ba29 4292 ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert);
Vanger 0:b86d15c6ba29 4293 if (ret != 0) {
Vanger 0:b86d15c6ba29 4294 CYASSL_MSG("\tOCSP Lookup not ok");
Vanger 0:b86d15c6ba29 4295 fatal = 0;
Vanger 0:b86d15c6ba29 4296 }
Vanger 0:b86d15c6ba29 4297 }
Vanger 0:b86d15c6ba29 4298 #endif
Vanger 0:b86d15c6ba29 4299
Vanger 0:b86d15c6ba29 4300 #ifdef HAVE_CRL
Vanger 0:b86d15c6ba29 4301 if (fatal == 0 && ssl->ctx->cm->crlEnabled) {
Vanger 0:b86d15c6ba29 4302 int doCrlLookup = 1;
Vanger 0:b86d15c6ba29 4303
Vanger 0:b86d15c6ba29 4304 #ifdef HAVE_OCSP
Vanger 0:b86d15c6ba29 4305 if (ssl->ctx->cm->ocspEnabled) {
Vanger 0:b86d15c6ba29 4306 doCrlLookup = (ret == OCSP_CERT_UNKNOWN);
Vanger 0:b86d15c6ba29 4307 }
Vanger 0:b86d15c6ba29 4308 #endif /* HAVE_OCSP */
Vanger 0:b86d15c6ba29 4309
Vanger 0:b86d15c6ba29 4310 if (doCrlLookup) {
Vanger 0:b86d15c6ba29 4311 CYASSL_MSG("Doing Leaf CRL check");
Vanger 0:b86d15c6ba29 4312 ret = CheckCertCRL(ssl->ctx->cm->crl, dCert);
Vanger 0:b86d15c6ba29 4313
Vanger 0:b86d15c6ba29 4314 if (ret != 0) {
Vanger 0:b86d15c6ba29 4315 CYASSL_MSG("\tCRL check not ok");
Vanger 0:b86d15c6ba29 4316 fatal = 0;
Vanger 0:b86d15c6ba29 4317 }
Vanger 0:b86d15c6ba29 4318 }
Vanger 0:b86d15c6ba29 4319 }
Vanger 0:b86d15c6ba29 4320
Vanger 0:b86d15c6ba29 4321 #endif /* HAVE_CRL */
Vanger 0:b86d15c6ba29 4322
Vanger 0:b86d15c6ba29 4323 #ifdef KEEP_PEER_CERT
Vanger 0:b86d15c6ba29 4324 {
Vanger 0:b86d15c6ba29 4325 /* set X509 format for peer cert even if fatal */
Vanger 0:b86d15c6ba29 4326 int copyRet = CopyDecodedToX509(&ssl->peerCert, dCert);
Vanger 0:b86d15c6ba29 4327 if (copyRet == MEMORY_E)
Vanger 0:b86d15c6ba29 4328 fatal = 1;
Vanger 0:b86d15c6ba29 4329 }
Vanger 0:b86d15c6ba29 4330 #endif
Vanger 0:b86d15c6ba29 4331
Vanger 0:b86d15c6ba29 4332 #ifndef IGNORE_KEY_EXTENSIONS
Vanger 0:b86d15c6ba29 4333 if (dCert->extKeyUsageSet) {
Vanger 0:b86d15c6ba29 4334 if ((ssl->specs.kea == rsa_kea) &&
Vanger 0:b86d15c6ba29 4335 (dCert->extKeyUsage & KEYUSE_KEY_ENCIPHER) == 0) {
Vanger 0:b86d15c6ba29 4336 ret = KEYUSE_ENCIPHER_E;
Vanger 0:b86d15c6ba29 4337 }
Vanger 0:b86d15c6ba29 4338 if ((ssl->specs.sig_algo == rsa_sa_algo ||
Vanger 0:b86d15c6ba29 4339 (ssl->specs.sig_algo == ecc_dsa_sa_algo &&
Vanger 0:b86d15c6ba29 4340 !ssl->specs.static_ecdh)) &&
Vanger 0:b86d15c6ba29 4341 (dCert->extKeyUsage & KEYUSE_DIGITAL_SIG) == 0) {
Vanger 0:b86d15c6ba29 4342 CYASSL_MSG("KeyUse Digital Sig not set");
Vanger 0:b86d15c6ba29 4343 ret = KEYUSE_SIGNATURE_E;
Vanger 0:b86d15c6ba29 4344 }
Vanger 0:b86d15c6ba29 4345 }
Vanger 0:b86d15c6ba29 4346
Vanger 0:b86d15c6ba29 4347 if (dCert->extExtKeyUsageSet) {
Vanger 0:b86d15c6ba29 4348 if (ssl->options.side == CYASSL_CLIENT_END) {
Vanger 0:b86d15c6ba29 4349 if ((dCert->extExtKeyUsage &
Vanger 0:b86d15c6ba29 4350 (EXTKEYUSE_ANY | EXTKEYUSE_SERVER_AUTH)) == 0) {
Vanger 0:b86d15c6ba29 4351 CYASSL_MSG("ExtKeyUse Server Auth not set");
Vanger 0:b86d15c6ba29 4352 ret = EXTKEYUSE_AUTH_E;
Vanger 0:b86d15c6ba29 4353 }
Vanger 0:b86d15c6ba29 4354 }
Vanger 0:b86d15c6ba29 4355 else {
Vanger 0:b86d15c6ba29 4356 if ((dCert->extExtKeyUsage &
Vanger 0:b86d15c6ba29 4357 (EXTKEYUSE_ANY | EXTKEYUSE_CLIENT_AUTH)) == 0) {
Vanger 0:b86d15c6ba29 4358 CYASSL_MSG("ExtKeyUse Client Auth not set");
Vanger 0:b86d15c6ba29 4359 ret = EXTKEYUSE_AUTH_E;
Vanger 0:b86d15c6ba29 4360 }
Vanger 0:b86d15c6ba29 4361 }
Vanger 0:b86d15c6ba29 4362 }
Vanger 0:b86d15c6ba29 4363 #endif /* IGNORE_KEY_EXTENSIONS */
Vanger 0:b86d15c6ba29 4364
Vanger 0:b86d15c6ba29 4365 if (fatal) {
Vanger 0:b86d15c6ba29 4366 FreeDecodedCert(dCert);
Vanger 0:b86d15c6ba29 4367 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4368 XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4369 #endif
Vanger 0:b86d15c6ba29 4370 ssl->error = ret;
Vanger 0:b86d15c6ba29 4371 return ret;
Vanger 0:b86d15c6ba29 4372 }
Vanger 0:b86d15c6ba29 4373 ssl->options.havePeerCert = 1;
Vanger 0:b86d15c6ba29 4374
Vanger 0:b86d15c6ba29 4375 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4376 domain = (char*)XMALLOC(ASN_NAME_MAX, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4377 if (domain == NULL) {
Vanger 0:b86d15c6ba29 4378 FreeDecodedCert(dCert);
Vanger 0:b86d15c6ba29 4379 XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4380 return MEMORY_E;
Vanger 0:b86d15c6ba29 4381 }
Vanger 0:b86d15c6ba29 4382 #endif
Vanger 0:b86d15c6ba29 4383 /* store for callback use */
Vanger 0:b86d15c6ba29 4384 if (dCert->subjectCNLen < ASN_NAME_MAX) {
Vanger 0:b86d15c6ba29 4385 XMEMCPY(domain, dCert->subjectCN, dCert->subjectCNLen);
Vanger 0:b86d15c6ba29 4386 domain[dCert->subjectCNLen] = '\0';
Vanger 0:b86d15c6ba29 4387 }
Vanger 0:b86d15c6ba29 4388 else
Vanger 0:b86d15c6ba29 4389 domain[0] = '\0';
Vanger 0:b86d15c6ba29 4390
Vanger 0:b86d15c6ba29 4391 if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer) {
Vanger 0:b86d15c6ba29 4392 if (MatchDomainName(dCert->subjectCN, dCert->subjectCNLen,
Vanger 0:b86d15c6ba29 4393 (char*)ssl->buffers.domainName.buffer) == 0) {
Vanger 0:b86d15c6ba29 4394 CYASSL_MSG("DomainName match on common name failed");
Vanger 0:b86d15c6ba29 4395 if (CheckAltNames(dCert,
Vanger 0:b86d15c6ba29 4396 (char*)ssl->buffers.domainName.buffer) == 0 ) {
Vanger 0:b86d15c6ba29 4397 CYASSL_MSG("DomainName match on alt names failed too");
Vanger 0:b86d15c6ba29 4398 ret = DOMAIN_NAME_MISMATCH; /* try to get peer key still */
Vanger 0:b86d15c6ba29 4399 }
Vanger 0:b86d15c6ba29 4400 }
Vanger 0:b86d15c6ba29 4401 }
Vanger 0:b86d15c6ba29 4402
Vanger 0:b86d15c6ba29 4403 /* decode peer key */
Vanger 0:b86d15c6ba29 4404 switch (dCert->keyOID) {
Vanger 0:b86d15c6ba29 4405 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 4406 case RSAk:
Vanger 0:b86d15c6ba29 4407 {
Vanger 0:b86d15c6ba29 4408 word32 idx = 0;
Vanger 0:b86d15c6ba29 4409 int keyRet = 0;
Vanger 0:b86d15c6ba29 4410
Vanger 0:b86d15c6ba29 4411 if (ssl->peerRsaKeyPresent) { /* don't leak on reuse */
Vanger 0:b86d15c6ba29 4412 FreeRsaKey(ssl->peerRsaKey);
Vanger 0:b86d15c6ba29 4413 ssl->peerRsaKeyPresent = 0;
Vanger 0:b86d15c6ba29 4414 keyRet = InitRsaKey(ssl->peerRsaKey, ssl->heap);
Vanger 0:b86d15c6ba29 4415 }
Vanger 0:b86d15c6ba29 4416
Vanger 0:b86d15c6ba29 4417 if (keyRet != 0 || RsaPublicKeyDecode(dCert->publicKey,
Vanger 0:b86d15c6ba29 4418 &idx, ssl->peerRsaKey, dCert->pubKeySize) != 0) {
Vanger 0:b86d15c6ba29 4419 ret = PEER_KEY_ERROR;
Vanger 0:b86d15c6ba29 4420 }
Vanger 0:b86d15c6ba29 4421 else {
Vanger 0:b86d15c6ba29 4422 ssl->peerRsaKeyPresent = 1;
Vanger 0:b86d15c6ba29 4423 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 4424 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 4425 ssl->buffers.peerRsaKey.buffer =
Vanger 0:b86d15c6ba29 4426 (byte*)XMALLOC(dCert->pubKeySize,
Vanger 0:b86d15c6ba29 4427 ssl->heap, DYNAMIC_TYPE_RSA);
Vanger 0:b86d15c6ba29 4428 if (ssl->buffers.peerRsaKey.buffer == NULL)
Vanger 0:b86d15c6ba29 4429 ret = MEMORY_ERROR;
Vanger 0:b86d15c6ba29 4430 else {
Vanger 0:b86d15c6ba29 4431 XMEMCPY(ssl->buffers.peerRsaKey.buffer,
Vanger 0:b86d15c6ba29 4432 dCert->publicKey, dCert->pubKeySize);
Vanger 0:b86d15c6ba29 4433 ssl->buffers.peerRsaKey.length =
Vanger 0:b86d15c6ba29 4434 dCert->pubKeySize;
Vanger 0:b86d15c6ba29 4435 }
Vanger 0:b86d15c6ba29 4436 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 4437 #endif /*HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 4438 }
Vanger 0:b86d15c6ba29 4439 }
Vanger 0:b86d15c6ba29 4440 break;
Vanger 0:b86d15c6ba29 4441 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 4442 #ifdef HAVE_NTRU
Vanger 0:b86d15c6ba29 4443 case NTRUk:
Vanger 0:b86d15c6ba29 4444 {
Vanger 0:b86d15c6ba29 4445 if (dCert->pubKeySize > sizeof(ssl->peerNtruKey)) {
Vanger 0:b86d15c6ba29 4446 ret = PEER_KEY_ERROR;
Vanger 0:b86d15c6ba29 4447 }
Vanger 0:b86d15c6ba29 4448 else {
Vanger 0:b86d15c6ba29 4449 XMEMCPY(ssl->peerNtruKey, dCert->publicKey,
Vanger 0:b86d15c6ba29 4450 dCert->pubKeySize);
Vanger 0:b86d15c6ba29 4451 ssl->peerNtruKeyLen = (word16)dCert->pubKeySize;
Vanger 0:b86d15c6ba29 4452 ssl->peerNtruKeyPresent = 1;
Vanger 0:b86d15c6ba29 4453 }
Vanger 0:b86d15c6ba29 4454 }
Vanger 0:b86d15c6ba29 4455 break;
Vanger 0:b86d15c6ba29 4456 #endif /* HAVE_NTRU */
Vanger 0:b86d15c6ba29 4457 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 4458 case ECDSAk:
Vanger 0:b86d15c6ba29 4459 {
Vanger 0:b86d15c6ba29 4460 if (ssl->peerEccDsaKeyPresent) { /* don't leak on reuse */
Vanger 0:b86d15c6ba29 4461 ecc_free(ssl->peerEccDsaKey);
Vanger 0:b86d15c6ba29 4462 ssl->peerEccDsaKeyPresent = 0;
Vanger 0:b86d15c6ba29 4463 ecc_init(ssl->peerEccDsaKey);
Vanger 0:b86d15c6ba29 4464 }
Vanger 0:b86d15c6ba29 4465 if (ecc_import_x963(dCert->publicKey, dCert->pubKeySize,
Vanger 0:b86d15c6ba29 4466 ssl->peerEccDsaKey) != 0) {
Vanger 0:b86d15c6ba29 4467 ret = PEER_KEY_ERROR;
Vanger 0:b86d15c6ba29 4468 }
Vanger 0:b86d15c6ba29 4469 else {
Vanger 0:b86d15c6ba29 4470 ssl->peerEccDsaKeyPresent = 1;
Vanger 0:b86d15c6ba29 4471 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 4472 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 4473 ssl->buffers.peerEccDsaKey.buffer =
Vanger 0:b86d15c6ba29 4474 (byte*)XMALLOC(dCert->pubKeySize,
Vanger 0:b86d15c6ba29 4475 ssl->heap, DYNAMIC_TYPE_ECC);
Vanger 0:b86d15c6ba29 4476 if (ssl->buffers.peerEccDsaKey.buffer == NULL)
Vanger 0:b86d15c6ba29 4477 ret = MEMORY_ERROR;
Vanger 0:b86d15c6ba29 4478 else {
Vanger 0:b86d15c6ba29 4479 XMEMCPY(ssl->buffers.peerEccDsaKey.buffer,
Vanger 0:b86d15c6ba29 4480 dCert->publicKey, dCert->pubKeySize);
Vanger 0:b86d15c6ba29 4481 ssl->buffers.peerEccDsaKey.length =
Vanger 0:b86d15c6ba29 4482 dCert->pubKeySize;
Vanger 0:b86d15c6ba29 4483 }
Vanger 0:b86d15c6ba29 4484 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 4485 #endif /*HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 4486 }
Vanger 0:b86d15c6ba29 4487 }
Vanger 0:b86d15c6ba29 4488 break;
Vanger 0:b86d15c6ba29 4489 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 4490 default:
Vanger 0:b86d15c6ba29 4491 break;
Vanger 0:b86d15c6ba29 4492 }
Vanger 0:b86d15c6ba29 4493
Vanger 0:b86d15c6ba29 4494 FreeDecodedCert(dCert);
Vanger 0:b86d15c6ba29 4495 }
Vanger 0:b86d15c6ba29 4496
Vanger 0:b86d15c6ba29 4497 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4498 XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4499
Vanger 0:b86d15c6ba29 4500 store = (CYASSL_X509_STORE_CTX*)XMALLOC(sizeof(CYASSL_X509_STORE_CTX),
Vanger 0:b86d15c6ba29 4501 NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4502 if (store == NULL) {
Vanger 0:b86d15c6ba29 4503 XFREE(domain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4504 return MEMORY_E;
Vanger 0:b86d15c6ba29 4505 }
Vanger 0:b86d15c6ba29 4506 #endif
Vanger 0:b86d15c6ba29 4507
Vanger 0:b86d15c6ba29 4508 if (anyError != 0 && ret == 0)
Vanger 0:b86d15c6ba29 4509 ret = anyError;
Vanger 0:b86d15c6ba29 4510
Vanger 0:b86d15c6ba29 4511 if (ret != 0) {
Vanger 0:b86d15c6ba29 4512 if (!ssl->options.verifyNone) {
Vanger 0:b86d15c6ba29 4513 int why = bad_certificate;
Vanger 0:b86d15c6ba29 4514
Vanger 0:b86d15c6ba29 4515 if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E)
Vanger 0:b86d15c6ba29 4516 why = certificate_expired;
Vanger 0:b86d15c6ba29 4517 if (ssl->verifyCallback) {
Vanger 0:b86d15c6ba29 4518 int ok;
Vanger 0:b86d15c6ba29 4519
Vanger 0:b86d15c6ba29 4520 store->error = ret;
Vanger 0:b86d15c6ba29 4521 store->error_depth = totalCerts;
Vanger 0:b86d15c6ba29 4522 store->discardSessionCerts = 0;
Vanger 0:b86d15c6ba29 4523 store->domain = domain;
Vanger 0:b86d15c6ba29 4524 store->userCtx = ssl->verifyCbCtx;
Vanger 0:b86d15c6ba29 4525 #ifdef KEEP_PEER_CERT
Vanger 0:b86d15c6ba29 4526 store->current_cert = &ssl->peerCert;
Vanger 0:b86d15c6ba29 4527 #else
Vanger 0:b86d15c6ba29 4528 store->current_cert = NULL;
Vanger 0:b86d15c6ba29 4529 #endif
Vanger 0:b86d15c6ba29 4530 #ifdef FORTRESS
Vanger 0:b86d15c6ba29 4531 store->ex_data = ssl;
Vanger 0:b86d15c6ba29 4532 #endif
Vanger 0:b86d15c6ba29 4533 ok = ssl->verifyCallback(0, store);
Vanger 0:b86d15c6ba29 4534 if (ok) {
Vanger 0:b86d15c6ba29 4535 CYASSL_MSG("Verify callback overriding error!");
Vanger 0:b86d15c6ba29 4536 ret = 0;
Vanger 0:b86d15c6ba29 4537 }
Vanger 0:b86d15c6ba29 4538 #ifdef SESSION_CERTS
Vanger 0:b86d15c6ba29 4539 if (store->discardSessionCerts) {
Vanger 0:b86d15c6ba29 4540 CYASSL_MSG("Verify callback requested discard sess certs");
Vanger 0:b86d15c6ba29 4541 ssl->session.chain.count = 0;
Vanger 0:b86d15c6ba29 4542 }
Vanger 0:b86d15c6ba29 4543 #endif
Vanger 0:b86d15c6ba29 4544 }
Vanger 0:b86d15c6ba29 4545 if (ret != 0) {
Vanger 0:b86d15c6ba29 4546 SendAlert(ssl, alert_fatal, why); /* try to send */
Vanger 0:b86d15c6ba29 4547 ssl->options.isClosed = 1;
Vanger 0:b86d15c6ba29 4548 }
Vanger 0:b86d15c6ba29 4549 }
Vanger 0:b86d15c6ba29 4550 ssl->error = ret;
Vanger 0:b86d15c6ba29 4551 }
Vanger 0:b86d15c6ba29 4552 #ifdef CYASSL_ALWAYS_VERIFY_CB
Vanger 0:b86d15c6ba29 4553 else {
Vanger 0:b86d15c6ba29 4554 if (ssl->verifyCallback) {
Vanger 0:b86d15c6ba29 4555 int ok;
Vanger 0:b86d15c6ba29 4556
Vanger 0:b86d15c6ba29 4557 store->error = ret;
Vanger 0:b86d15c6ba29 4558 store->error_depth = totalCerts;
Vanger 0:b86d15c6ba29 4559 store->discardSessionCerts = 0;
Vanger 0:b86d15c6ba29 4560 store->domain = domain;
Vanger 0:b86d15c6ba29 4561 store->userCtx = ssl->verifyCbCtx;
Vanger 0:b86d15c6ba29 4562 #ifdef KEEP_PEER_CERT
Vanger 0:b86d15c6ba29 4563 store->current_cert = &ssl->peerCert;
Vanger 0:b86d15c6ba29 4564 #endif
Vanger 0:b86d15c6ba29 4565 store->ex_data = ssl;
Vanger 0:b86d15c6ba29 4566
Vanger 0:b86d15c6ba29 4567 ok = ssl->verifyCallback(1, store);
Vanger 0:b86d15c6ba29 4568 if (!ok) {
Vanger 0:b86d15c6ba29 4569 CYASSL_MSG("Verify callback overriding valid certificate!");
Vanger 0:b86d15c6ba29 4570 ret = -1;
Vanger 0:b86d15c6ba29 4571 SendAlert(ssl, alert_fatal, bad_certificate);
Vanger 0:b86d15c6ba29 4572 ssl->options.isClosed = 1;
Vanger 0:b86d15c6ba29 4573 }
Vanger 0:b86d15c6ba29 4574 #ifdef SESSION_CERTS
Vanger 0:b86d15c6ba29 4575 if (store->discardSessionCerts) {
Vanger 0:b86d15c6ba29 4576 CYASSL_MSG("Verify callback requested discard sess certs");
Vanger 0:b86d15c6ba29 4577 ssl->session.chain.count = 0;
Vanger 0:b86d15c6ba29 4578 }
Vanger 0:b86d15c6ba29 4579 #endif
Vanger 0:b86d15c6ba29 4580 }
Vanger 0:b86d15c6ba29 4581 }
Vanger 0:b86d15c6ba29 4582 #endif
Vanger 0:b86d15c6ba29 4583
Vanger 0:b86d15c6ba29 4584 if (ssl->options.verifyNone &&
Vanger 0:b86d15c6ba29 4585 (ret == CRL_MISSING || ret == CRL_CERT_REVOKED)) {
Vanger 0:b86d15c6ba29 4586 CYASSL_MSG("Ignoring CRL problem based on verify setting");
Vanger 0:b86d15c6ba29 4587 ret = ssl->error = 0;
Vanger 0:b86d15c6ba29 4588 }
Vanger 0:b86d15c6ba29 4589
Vanger 0:b86d15c6ba29 4590 if (ret == 0 && ssl->options.side == CYASSL_CLIENT_END)
Vanger 0:b86d15c6ba29 4591 ssl->options.serverState = SERVER_CERT_COMPLETE;
Vanger 0:b86d15c6ba29 4592
Vanger 0:b86d15c6ba29 4593 if (ssl->keys.encryptionOn) {
Vanger 0:b86d15c6ba29 4594 *inOutIdx += ssl->keys.padSz;
Vanger 0:b86d15c6ba29 4595 }
Vanger 0:b86d15c6ba29 4596
Vanger 0:b86d15c6ba29 4597 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4598 XFREE(store, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4599 XFREE(domain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4600 #endif
Vanger 0:b86d15c6ba29 4601
Vanger 0:b86d15c6ba29 4602 return ret;
Vanger 0:b86d15c6ba29 4603 }
Vanger 0:b86d15c6ba29 4604
Vanger 0:b86d15c6ba29 4605 #endif /* !NO_CERTS */
Vanger 0:b86d15c6ba29 4606
Vanger 0:b86d15c6ba29 4607
Vanger 0:b86d15c6ba29 4608 static int DoHelloRequest(CYASSL* ssl, const byte* input, word32* inOutIdx,
Vanger 0:b86d15c6ba29 4609 word32 size, word32 totalSz)
Vanger 0:b86d15c6ba29 4610 {
Vanger 0:b86d15c6ba29 4611 (void)input;
Vanger 0:b86d15c6ba29 4612
Vanger 0:b86d15c6ba29 4613 if (size) /* must be 0 */
Vanger 0:b86d15c6ba29 4614 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 4615
Vanger 0:b86d15c6ba29 4616 if (ssl->keys.encryptionOn) {
Vanger 0:b86d15c6ba29 4617 /* access beyond input + size should be checked against totalSz */
Vanger 0:b86d15c6ba29 4618 if (*inOutIdx + ssl->keys.padSz > totalSz)
Vanger 0:b86d15c6ba29 4619 return BUFFER_E;
Vanger 0:b86d15c6ba29 4620
Vanger 0:b86d15c6ba29 4621 *inOutIdx += ssl->keys.padSz;
Vanger 0:b86d15c6ba29 4622 }
Vanger 0:b86d15c6ba29 4623
Vanger 0:b86d15c6ba29 4624 if (ssl->options.side == CYASSL_SERVER_END) {
Vanger 0:b86d15c6ba29 4625 SendAlert(ssl, alert_fatal, unexpected_message); /* try */
Vanger 0:b86d15c6ba29 4626 return FATAL_ERROR;
Vanger 0:b86d15c6ba29 4627 }
Vanger 0:b86d15c6ba29 4628 #ifdef HAVE_SECURE_RENEGOTIATION
Vanger 0:b86d15c6ba29 4629 else if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
Vanger 0:b86d15c6ba29 4630 ssl->secure_renegotiation->startScr = 1;
Vanger 0:b86d15c6ba29 4631 return 0;
Vanger 0:b86d15c6ba29 4632 }
Vanger 0:b86d15c6ba29 4633 #endif
Vanger 0:b86d15c6ba29 4634 else {
Vanger 0:b86d15c6ba29 4635 return SendAlert(ssl, alert_warning, no_renegotiation);
Vanger 0:b86d15c6ba29 4636 }
Vanger 0:b86d15c6ba29 4637 }
Vanger 0:b86d15c6ba29 4638
Vanger 0:b86d15c6ba29 4639
Vanger 0:b86d15c6ba29 4640 int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, word32 size,
Vanger 0:b86d15c6ba29 4641 word32 totalSz, int sniff)
Vanger 0:b86d15c6ba29 4642 {
Vanger 0:b86d15c6ba29 4643 word32 finishedSz = (ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ);
Vanger 0:b86d15c6ba29 4644
Vanger 0:b86d15c6ba29 4645 if (finishedSz != size)
Vanger 0:b86d15c6ba29 4646 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 4647
Vanger 0:b86d15c6ba29 4648 /* check against totalSz */
Vanger 0:b86d15c6ba29 4649 if (*inOutIdx + size + ssl->keys.padSz > totalSz)
Vanger 0:b86d15c6ba29 4650 return BUFFER_E;
Vanger 0:b86d15c6ba29 4651
Vanger 0:b86d15c6ba29 4652 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 4653 if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 4654 if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
Vanger 0:b86d15c6ba29 4655 #endif
Vanger 0:b86d15c6ba29 4656
Vanger 0:b86d15c6ba29 4657 if (sniff == NO_SNIFF) {
Vanger 0:b86d15c6ba29 4658 if (XMEMCMP(input + *inOutIdx, &ssl->verifyHashes, size) != 0) {
Vanger 0:b86d15c6ba29 4659 CYASSL_MSG("Verify finished error on hashes");
Vanger 0:b86d15c6ba29 4660 return VERIFY_FINISHED_ERROR;
Vanger 0:b86d15c6ba29 4661 }
Vanger 0:b86d15c6ba29 4662 }
Vanger 0:b86d15c6ba29 4663
Vanger 0:b86d15c6ba29 4664 #ifdef HAVE_SECURE_RENEGOTIATION
Vanger 0:b86d15c6ba29 4665 if (ssl->secure_renegotiation) {
Vanger 0:b86d15c6ba29 4666 /* save peer's state */
Vanger 0:b86d15c6ba29 4667 if (ssl->options.side == CYASSL_CLIENT_END)
Vanger 0:b86d15c6ba29 4668 XMEMCPY(ssl->secure_renegotiation->server_verify_data,
Vanger 0:b86d15c6ba29 4669 input + *inOutIdx, TLS_FINISHED_SZ);
Vanger 0:b86d15c6ba29 4670 else
Vanger 0:b86d15c6ba29 4671 XMEMCPY(ssl->secure_renegotiation->client_verify_data,
Vanger 0:b86d15c6ba29 4672 input + *inOutIdx, TLS_FINISHED_SZ);
Vanger 0:b86d15c6ba29 4673 }
Vanger 0:b86d15c6ba29 4674 #endif
Vanger 0:b86d15c6ba29 4675
Vanger 0:b86d15c6ba29 4676 /* force input exhaustion at ProcessReply consuming padSz */
Vanger 0:b86d15c6ba29 4677 *inOutIdx += size + ssl->keys.padSz;
Vanger 0:b86d15c6ba29 4678
Vanger 0:b86d15c6ba29 4679 if (ssl->options.side == CYASSL_CLIENT_END) {
Vanger 0:b86d15c6ba29 4680 ssl->options.serverState = SERVER_FINISHED_COMPLETE;
Vanger 0:b86d15c6ba29 4681 if (!ssl->options.resuming) {
Vanger 0:b86d15c6ba29 4682 ssl->options.handShakeState = HANDSHAKE_DONE;
Vanger 0:b86d15c6ba29 4683 ssl->options.handShakeDone = 1;
Vanger 0:b86d15c6ba29 4684
Vanger 0:b86d15c6ba29 4685 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 4686 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 4687 /* Other side has received our Finished, go to next epoch */
Vanger 0:b86d15c6ba29 4688 ssl->keys.dtls_epoch++;
Vanger 0:b86d15c6ba29 4689 ssl->keys.dtls_sequence_number = 1;
Vanger 0:b86d15c6ba29 4690 }
Vanger 0:b86d15c6ba29 4691 #endif
Vanger 0:b86d15c6ba29 4692 }
Vanger 0:b86d15c6ba29 4693 }
Vanger 0:b86d15c6ba29 4694 else {
Vanger 0:b86d15c6ba29 4695 ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
Vanger 0:b86d15c6ba29 4696 if (ssl->options.resuming) {
Vanger 0:b86d15c6ba29 4697 ssl->options.handShakeState = HANDSHAKE_DONE;
Vanger 0:b86d15c6ba29 4698 ssl->options.handShakeDone = 1;
Vanger 0:b86d15c6ba29 4699
Vanger 0:b86d15c6ba29 4700 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 4701 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 4702 /* Other side has received our Finished, go to next epoch */
Vanger 0:b86d15c6ba29 4703 ssl->keys.dtls_epoch++;
Vanger 0:b86d15c6ba29 4704 ssl->keys.dtls_sequence_number = 1;
Vanger 0:b86d15c6ba29 4705 }
Vanger 0:b86d15c6ba29 4706 #endif
Vanger 0:b86d15c6ba29 4707 }
Vanger 0:b86d15c6ba29 4708 }
Vanger 0:b86d15c6ba29 4709
Vanger 0:b86d15c6ba29 4710 return 0;
Vanger 0:b86d15c6ba29 4711 }
Vanger 0:b86d15c6ba29 4712
Vanger 0:b86d15c6ba29 4713
Vanger 0:b86d15c6ba29 4714 /* Make sure no duplicates, no fast forward, or other problems; 0 on success */
Vanger 0:b86d15c6ba29 4715 static int SanityCheckMsgReceived(CYASSL* ssl, byte type)
Vanger 0:b86d15c6ba29 4716 {
Vanger 0:b86d15c6ba29 4717 /* verify not a duplicate, mark received, check state */
Vanger 0:b86d15c6ba29 4718 switch (type) {
Vanger 0:b86d15c6ba29 4719
Vanger 0:b86d15c6ba29 4720 #ifndef NO_CYASSL_CLIENT
Vanger 0:b86d15c6ba29 4721 case hello_request:
Vanger 0:b86d15c6ba29 4722 if (ssl->msgsReceived.got_hello_request) {
Vanger 0:b86d15c6ba29 4723 CYASSL_MSG("Duplicate HelloRequest received");
Vanger 0:b86d15c6ba29 4724 return DUPLICATE_MSG_E;
Vanger 0:b86d15c6ba29 4725 }
Vanger 0:b86d15c6ba29 4726 ssl->msgsReceived.got_hello_request = 1;
Vanger 0:b86d15c6ba29 4727
Vanger 0:b86d15c6ba29 4728 break;
Vanger 0:b86d15c6ba29 4729 #endif
Vanger 0:b86d15c6ba29 4730
Vanger 0:b86d15c6ba29 4731 #ifndef NO_CYASSL_SERVER
Vanger 0:b86d15c6ba29 4732 case client_hello:
Vanger 0:b86d15c6ba29 4733 if (ssl->msgsReceived.got_client_hello) {
Vanger 0:b86d15c6ba29 4734 CYASSL_MSG("Duplicate ClientHello received");
Vanger 0:b86d15c6ba29 4735 return DUPLICATE_MSG_E;
Vanger 0:b86d15c6ba29 4736 }
Vanger 0:b86d15c6ba29 4737 ssl->msgsReceived.got_client_hello = 1;
Vanger 0:b86d15c6ba29 4738
Vanger 0:b86d15c6ba29 4739 break;
Vanger 0:b86d15c6ba29 4740 #endif
Vanger 0:b86d15c6ba29 4741
Vanger 0:b86d15c6ba29 4742 #ifndef NO_CYASSL_CLIENT
Vanger 0:b86d15c6ba29 4743 case server_hello:
Vanger 0:b86d15c6ba29 4744 if (ssl->msgsReceived.got_server_hello) {
Vanger 0:b86d15c6ba29 4745 CYASSL_MSG("Duplicate ServerHello received");
Vanger 0:b86d15c6ba29 4746 return DUPLICATE_MSG_E;
Vanger 0:b86d15c6ba29 4747 }
Vanger 0:b86d15c6ba29 4748 ssl->msgsReceived.got_server_hello = 1;
Vanger 0:b86d15c6ba29 4749
Vanger 0:b86d15c6ba29 4750 break;
Vanger 0:b86d15c6ba29 4751 #endif
Vanger 0:b86d15c6ba29 4752
Vanger 0:b86d15c6ba29 4753 #ifndef NO_CYASSL_CLIENT
Vanger 0:b86d15c6ba29 4754 case hello_verify_request:
Vanger 0:b86d15c6ba29 4755 if (ssl->msgsReceived.got_hello_verify_request) {
Vanger 0:b86d15c6ba29 4756 CYASSL_MSG("Duplicate HelloVerifyRequest received");
Vanger 0:b86d15c6ba29 4757 return DUPLICATE_MSG_E;
Vanger 0:b86d15c6ba29 4758 }
Vanger 0:b86d15c6ba29 4759 ssl->msgsReceived.got_hello_verify_request = 1;
Vanger 0:b86d15c6ba29 4760
Vanger 0:b86d15c6ba29 4761 break;
Vanger 0:b86d15c6ba29 4762 #endif
Vanger 0:b86d15c6ba29 4763
Vanger 0:b86d15c6ba29 4764 #ifndef NO_CYASSL_CLIENT
Vanger 0:b86d15c6ba29 4765 case session_ticket:
Vanger 0:b86d15c6ba29 4766 if (ssl->msgsReceived.got_session_ticket) {
Vanger 0:b86d15c6ba29 4767 CYASSL_MSG("Duplicate SessionTicket received");
Vanger 0:b86d15c6ba29 4768 return DUPLICATE_MSG_E;
Vanger 0:b86d15c6ba29 4769 }
Vanger 0:b86d15c6ba29 4770 ssl->msgsReceived.got_session_ticket = 1;
Vanger 0:b86d15c6ba29 4771
Vanger 0:b86d15c6ba29 4772 break;
Vanger 0:b86d15c6ba29 4773 #endif
Vanger 0:b86d15c6ba29 4774
Vanger 0:b86d15c6ba29 4775 case certificate:
Vanger 0:b86d15c6ba29 4776 if (ssl->msgsReceived.got_certificate) {
Vanger 0:b86d15c6ba29 4777 CYASSL_MSG("Duplicate Certificate received");
Vanger 0:b86d15c6ba29 4778 return DUPLICATE_MSG_E;
Vanger 0:b86d15c6ba29 4779 }
Vanger 0:b86d15c6ba29 4780 ssl->msgsReceived.got_certificate = 1;
Vanger 0:b86d15c6ba29 4781
Vanger 0:b86d15c6ba29 4782 #ifndef NO_CYASSL_CLIENT
Vanger 0:b86d15c6ba29 4783 if (ssl->options.side == CYASSL_CLIENT_END) {
Vanger 0:b86d15c6ba29 4784 if ( ssl->msgsReceived.got_server_hello == 0) {
Vanger 0:b86d15c6ba29 4785 CYASSL_MSG("No ServerHello before Cert");
Vanger 0:b86d15c6ba29 4786 return OUT_OF_ORDER_E;
Vanger 0:b86d15c6ba29 4787 }
Vanger 0:b86d15c6ba29 4788 }
Vanger 0:b86d15c6ba29 4789 #endif
Vanger 0:b86d15c6ba29 4790 #ifndef NO_CYASSL_SERVER
Vanger 0:b86d15c6ba29 4791 if (ssl->options.side == CYASSL_SERVER_END) {
Vanger 0:b86d15c6ba29 4792 if ( ssl->msgsReceived.got_client_hello == 0) {
Vanger 0:b86d15c6ba29 4793 CYASSL_MSG("No ClientHello before Cert");
Vanger 0:b86d15c6ba29 4794 return OUT_OF_ORDER_E;
Vanger 0:b86d15c6ba29 4795 }
Vanger 0:b86d15c6ba29 4796 }
Vanger 0:b86d15c6ba29 4797 #endif
Vanger 0:b86d15c6ba29 4798 break;
Vanger 0:b86d15c6ba29 4799
Vanger 0:b86d15c6ba29 4800 #ifndef NO_CYASSL_CLIENT
Vanger 0:b86d15c6ba29 4801 case server_key_exchange:
Vanger 0:b86d15c6ba29 4802 if (ssl->msgsReceived.got_server_key_exchange) {
Vanger 0:b86d15c6ba29 4803 CYASSL_MSG("Duplicate ServerKeyExchange received");
Vanger 0:b86d15c6ba29 4804 return DUPLICATE_MSG_E;
Vanger 0:b86d15c6ba29 4805 }
Vanger 0:b86d15c6ba29 4806 ssl->msgsReceived.got_server_key_exchange = 1;
Vanger 0:b86d15c6ba29 4807
Vanger 0:b86d15c6ba29 4808 if ( ssl->msgsReceived.got_server_hello == 0) {
Vanger 0:b86d15c6ba29 4809 CYASSL_MSG("No ServerHello before Cert");
Vanger 0:b86d15c6ba29 4810 return OUT_OF_ORDER_E;
Vanger 0:b86d15c6ba29 4811 }
Vanger 0:b86d15c6ba29 4812
Vanger 0:b86d15c6ba29 4813 break;
Vanger 0:b86d15c6ba29 4814 #endif
Vanger 0:b86d15c6ba29 4815
Vanger 0:b86d15c6ba29 4816 #ifndef NO_CYASSL_CLIENT
Vanger 0:b86d15c6ba29 4817 case certificate_request:
Vanger 0:b86d15c6ba29 4818 if (ssl->msgsReceived.got_certificate_request) {
Vanger 0:b86d15c6ba29 4819 CYASSL_MSG("Duplicate CertificateRequest received");
Vanger 0:b86d15c6ba29 4820 return DUPLICATE_MSG_E;
Vanger 0:b86d15c6ba29 4821 }
Vanger 0:b86d15c6ba29 4822 ssl->msgsReceived.got_certificate_request = 1;
Vanger 0:b86d15c6ba29 4823
Vanger 0:b86d15c6ba29 4824 break;
Vanger 0:b86d15c6ba29 4825 #endif
Vanger 0:b86d15c6ba29 4826
Vanger 0:b86d15c6ba29 4827 #ifndef NO_CYASSL_CLIENT
Vanger 0:b86d15c6ba29 4828 case server_hello_done:
Vanger 0:b86d15c6ba29 4829 if (ssl->msgsReceived.got_server_hello_done) {
Vanger 0:b86d15c6ba29 4830 CYASSL_MSG("Duplicate ServerHelloDone received");
Vanger 0:b86d15c6ba29 4831 return DUPLICATE_MSG_E;
Vanger 0:b86d15c6ba29 4832 }
Vanger 0:b86d15c6ba29 4833 ssl->msgsReceived.got_server_hello_done = 1;
Vanger 0:b86d15c6ba29 4834
Vanger 0:b86d15c6ba29 4835 if (ssl->msgsReceived.got_certificate == 0) {
Vanger 0:b86d15c6ba29 4836 if (ssl->specs.kea == psk_kea ||
Vanger 0:b86d15c6ba29 4837 ssl->specs.kea == dhe_psk_kea ||
Vanger 0:b86d15c6ba29 4838 ssl->options.usingAnon_cipher) {
Vanger 0:b86d15c6ba29 4839 CYASSL_MSG("No Cert required");
Vanger 0:b86d15c6ba29 4840 } else {
Vanger 0:b86d15c6ba29 4841 CYASSL_MSG("No Certificate before ServerHelloDone");
Vanger 0:b86d15c6ba29 4842 return OUT_OF_ORDER_E;
Vanger 0:b86d15c6ba29 4843 }
Vanger 0:b86d15c6ba29 4844 }
Vanger 0:b86d15c6ba29 4845 if (ssl->msgsReceived.got_server_key_exchange == 0) {
Vanger 0:b86d15c6ba29 4846 if (ssl->specs.static_ecdh == 1 ||
Vanger 0:b86d15c6ba29 4847 ssl->specs.kea == rsa_kea ||
Vanger 0:b86d15c6ba29 4848 ssl->specs.kea == ntru_kea) {
Vanger 0:b86d15c6ba29 4849 CYASSL_MSG("No KeyExchange required");
Vanger 0:b86d15c6ba29 4850 } else {
Vanger 0:b86d15c6ba29 4851 CYASSL_MSG("No ServerKeyExchange before ServerDone");
Vanger 0:b86d15c6ba29 4852 return OUT_OF_ORDER_E;
Vanger 0:b86d15c6ba29 4853 }
Vanger 0:b86d15c6ba29 4854 }
Vanger 0:b86d15c6ba29 4855 break;
Vanger 0:b86d15c6ba29 4856 #endif
Vanger 0:b86d15c6ba29 4857
Vanger 0:b86d15c6ba29 4858 #ifndef NO_CYASSL_SERVER
Vanger 0:b86d15c6ba29 4859 case certificate_verify:
Vanger 0:b86d15c6ba29 4860 if (ssl->msgsReceived.got_certificate_verify) {
Vanger 0:b86d15c6ba29 4861 CYASSL_MSG("Duplicate CertificateVerify received");
Vanger 0:b86d15c6ba29 4862 return DUPLICATE_MSG_E;
Vanger 0:b86d15c6ba29 4863 }
Vanger 0:b86d15c6ba29 4864 ssl->msgsReceived.got_certificate_verify = 1;
Vanger 0:b86d15c6ba29 4865
Vanger 0:b86d15c6ba29 4866 if ( ssl->msgsReceived.got_certificate == 0) {
Vanger 0:b86d15c6ba29 4867 CYASSL_MSG("No Cert before CertVerify");
Vanger 0:b86d15c6ba29 4868 return OUT_OF_ORDER_E;
Vanger 0:b86d15c6ba29 4869 }
Vanger 0:b86d15c6ba29 4870 break;
Vanger 0:b86d15c6ba29 4871 #endif
Vanger 0:b86d15c6ba29 4872
Vanger 0:b86d15c6ba29 4873 #ifndef NO_CYASSL_SERVER
Vanger 0:b86d15c6ba29 4874 case client_key_exchange:
Vanger 0:b86d15c6ba29 4875 if (ssl->msgsReceived.got_client_key_exchange) {
Vanger 0:b86d15c6ba29 4876 CYASSL_MSG("Duplicate ClientKeyExchange received");
Vanger 0:b86d15c6ba29 4877 return DUPLICATE_MSG_E;
Vanger 0:b86d15c6ba29 4878 }
Vanger 0:b86d15c6ba29 4879 ssl->msgsReceived.got_client_key_exchange = 1;
Vanger 0:b86d15c6ba29 4880
Vanger 0:b86d15c6ba29 4881 if (ssl->msgsReceived.got_client_hello == 0) {
Vanger 0:b86d15c6ba29 4882 CYASSL_MSG("No ClientHello before ClientKeyExchange");
Vanger 0:b86d15c6ba29 4883 return OUT_OF_ORDER_E;
Vanger 0:b86d15c6ba29 4884 }
Vanger 0:b86d15c6ba29 4885 break;
Vanger 0:b86d15c6ba29 4886 #endif
Vanger 0:b86d15c6ba29 4887
Vanger 0:b86d15c6ba29 4888 case finished:
Vanger 0:b86d15c6ba29 4889 if (ssl->msgsReceived.got_finished) {
Vanger 0:b86d15c6ba29 4890 CYASSL_MSG("Duplicate Finished received");
Vanger 0:b86d15c6ba29 4891 return DUPLICATE_MSG_E;
Vanger 0:b86d15c6ba29 4892 }
Vanger 0:b86d15c6ba29 4893 ssl->msgsReceived.got_finished = 1;
Vanger 0:b86d15c6ba29 4894
Vanger 0:b86d15c6ba29 4895 if (ssl->msgsReceived.got_change_cipher == 0) {
Vanger 0:b86d15c6ba29 4896 CYASSL_MSG("Finished received before ChangeCipher");
Vanger 0:b86d15c6ba29 4897 return NO_CHANGE_CIPHER_E;
Vanger 0:b86d15c6ba29 4898 }
Vanger 0:b86d15c6ba29 4899
Vanger 0:b86d15c6ba29 4900 break;
Vanger 0:b86d15c6ba29 4901
Vanger 0:b86d15c6ba29 4902 case change_cipher_hs:
Vanger 0:b86d15c6ba29 4903 if (ssl->msgsReceived.got_change_cipher) {
Vanger 0:b86d15c6ba29 4904 CYASSL_MSG("Duplicate ChangeCipher received");
Vanger 0:b86d15c6ba29 4905 return DUPLICATE_MSG_E;
Vanger 0:b86d15c6ba29 4906 }
Vanger 0:b86d15c6ba29 4907 ssl->msgsReceived.got_change_cipher = 1;
Vanger 0:b86d15c6ba29 4908
Vanger 0:b86d15c6ba29 4909 #ifndef NO_CYASSL_CLIENT
Vanger 0:b86d15c6ba29 4910 if (ssl->options.side == CYASSL_CLIENT_END) {
Vanger 0:b86d15c6ba29 4911 if (!ssl->options.resuming &&
Vanger 0:b86d15c6ba29 4912 ssl->msgsReceived.got_server_hello_done == 0) {
Vanger 0:b86d15c6ba29 4913 CYASSL_MSG("No ServerHelloDone before ChangeCipher");
Vanger 0:b86d15c6ba29 4914 return OUT_OF_ORDER_E;
Vanger 0:b86d15c6ba29 4915 }
Vanger 0:b86d15c6ba29 4916 }
Vanger 0:b86d15c6ba29 4917 #endif
Vanger 0:b86d15c6ba29 4918 #ifndef NO_CYASSL_SERVER
Vanger 0:b86d15c6ba29 4919 if (ssl->options.side == CYASSL_SERVER_END) {
Vanger 0:b86d15c6ba29 4920 if (!ssl->options.resuming &&
Vanger 0:b86d15c6ba29 4921 ssl->msgsReceived.got_client_key_exchange == 0) {
Vanger 0:b86d15c6ba29 4922 CYASSL_MSG("No ClientKeyExchange before ChangeCipher");
Vanger 0:b86d15c6ba29 4923 return OUT_OF_ORDER_E;
Vanger 0:b86d15c6ba29 4924 }
Vanger 0:b86d15c6ba29 4925 }
Vanger 0:b86d15c6ba29 4926 #endif
Vanger 0:b86d15c6ba29 4927
Vanger 0:b86d15c6ba29 4928 break;
Vanger 0:b86d15c6ba29 4929
Vanger 0:b86d15c6ba29 4930 default:
Vanger 0:b86d15c6ba29 4931 CYASSL_MSG("Unknown message type");
Vanger 0:b86d15c6ba29 4932 return SANITY_MSG_E;
Vanger 0:b86d15c6ba29 4933 }
Vanger 0:b86d15c6ba29 4934
Vanger 0:b86d15c6ba29 4935 return 0;
Vanger 0:b86d15c6ba29 4936 }
Vanger 0:b86d15c6ba29 4937
Vanger 0:b86d15c6ba29 4938
Vanger 0:b86d15c6ba29 4939 static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
Vanger 0:b86d15c6ba29 4940 byte type, word32 size, word32 totalSz)
Vanger 0:b86d15c6ba29 4941 {
Vanger 0:b86d15c6ba29 4942 int ret = 0;
Vanger 0:b86d15c6ba29 4943 (void)totalSz;
Vanger 0:b86d15c6ba29 4944
Vanger 0:b86d15c6ba29 4945 CYASSL_ENTER("DoHandShakeMsgType");
Vanger 0:b86d15c6ba29 4946
Vanger 0:b86d15c6ba29 4947 /* make sure can read the message */
Vanger 0:b86d15c6ba29 4948 if (*inOutIdx + size > totalSz)
Vanger 0:b86d15c6ba29 4949 return INCOMPLETE_DATA;
Vanger 0:b86d15c6ba29 4950
Vanger 0:b86d15c6ba29 4951 /* sanity check msg received */
Vanger 0:b86d15c6ba29 4952 if ( (ret = SanityCheckMsgReceived(ssl, type)) != 0) {
Vanger 0:b86d15c6ba29 4953 CYASSL_MSG("Sanity Check on handshake message type received failed");
Vanger 0:b86d15c6ba29 4954 return ret;
Vanger 0:b86d15c6ba29 4955 }
Vanger 0:b86d15c6ba29 4956
Vanger 0:b86d15c6ba29 4957 /* hello_request not hashed */
Vanger 0:b86d15c6ba29 4958 if (type != hello_request) {
Vanger 0:b86d15c6ba29 4959 ret = HashInput(ssl, input + *inOutIdx, size);
Vanger 0:b86d15c6ba29 4960 if (ret != 0) return ret;
Vanger 0:b86d15c6ba29 4961 }
Vanger 0:b86d15c6ba29 4962
Vanger 0:b86d15c6ba29 4963 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 4964 /* add name later, add on record and handshake header part back on */
Vanger 0:b86d15c6ba29 4965 if (ssl->toInfoOn) {
Vanger 0:b86d15c6ba29 4966 int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 4967 AddPacketInfo(0, &ssl->timeoutInfo, input + *inOutIdx - add,
Vanger 0:b86d15c6ba29 4968 size + add, ssl->heap);
Vanger 0:b86d15c6ba29 4969 AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
Vanger 0:b86d15c6ba29 4970 }
Vanger 0:b86d15c6ba29 4971 #endif
Vanger 0:b86d15c6ba29 4972
Vanger 0:b86d15c6ba29 4973 if (ssl->options.handShakeState == HANDSHAKE_DONE && type != hello_request){
Vanger 0:b86d15c6ba29 4974 CYASSL_MSG("HandShake message after handshake complete");
Vanger 0:b86d15c6ba29 4975 SendAlert(ssl, alert_fatal, unexpected_message);
Vanger 0:b86d15c6ba29 4976 return OUT_OF_ORDER_E;
Vanger 0:b86d15c6ba29 4977 }
Vanger 0:b86d15c6ba29 4978
Vanger 0:b86d15c6ba29 4979 if (ssl->options.side == CYASSL_CLIENT_END && ssl->options.dtls == 0 &&
Vanger 0:b86d15c6ba29 4980 ssl->options.serverState == NULL_STATE && type != server_hello) {
Vanger 0:b86d15c6ba29 4981 CYASSL_MSG("First server message not server hello");
Vanger 0:b86d15c6ba29 4982 SendAlert(ssl, alert_fatal, unexpected_message);
Vanger 0:b86d15c6ba29 4983 return OUT_OF_ORDER_E;
Vanger 0:b86d15c6ba29 4984 }
Vanger 0:b86d15c6ba29 4985
Vanger 0:b86d15c6ba29 4986 if (ssl->options.side == CYASSL_CLIENT_END && ssl->options.dtls &&
Vanger 0:b86d15c6ba29 4987 type == server_hello_done &&
Vanger 0:b86d15c6ba29 4988 ssl->options.serverState < SERVER_HELLO_COMPLETE) {
Vanger 0:b86d15c6ba29 4989 CYASSL_MSG("Server hello done received before server hello in DTLS");
Vanger 0:b86d15c6ba29 4990 SendAlert(ssl, alert_fatal, unexpected_message);
Vanger 0:b86d15c6ba29 4991 return OUT_OF_ORDER_E;
Vanger 0:b86d15c6ba29 4992 }
Vanger 0:b86d15c6ba29 4993
Vanger 0:b86d15c6ba29 4994 if (ssl->options.side == CYASSL_SERVER_END &&
Vanger 0:b86d15c6ba29 4995 ssl->options.clientState == NULL_STATE && type != client_hello) {
Vanger 0:b86d15c6ba29 4996 CYASSL_MSG("First client message not client hello");
Vanger 0:b86d15c6ba29 4997 SendAlert(ssl, alert_fatal, unexpected_message);
Vanger 0:b86d15c6ba29 4998 return OUT_OF_ORDER_E;
Vanger 0:b86d15c6ba29 4999 }
Vanger 0:b86d15c6ba29 5000
Vanger 0:b86d15c6ba29 5001
Vanger 0:b86d15c6ba29 5002 switch (type) {
Vanger 0:b86d15c6ba29 5003
Vanger 0:b86d15c6ba29 5004 case hello_request:
Vanger 0:b86d15c6ba29 5005 CYASSL_MSG("processing hello request");
Vanger 0:b86d15c6ba29 5006 ret = DoHelloRequest(ssl, input, inOutIdx, size, totalSz);
Vanger 0:b86d15c6ba29 5007 break;
Vanger 0:b86d15c6ba29 5008
Vanger 0:b86d15c6ba29 5009 #ifndef NO_CYASSL_CLIENT
Vanger 0:b86d15c6ba29 5010 case hello_verify_request:
Vanger 0:b86d15c6ba29 5011 CYASSL_MSG("processing hello verify request");
Vanger 0:b86d15c6ba29 5012 ret = DoHelloVerifyRequest(ssl, input,inOutIdx, size);
Vanger 0:b86d15c6ba29 5013 break;
Vanger 0:b86d15c6ba29 5014
Vanger 0:b86d15c6ba29 5015 case server_hello:
Vanger 0:b86d15c6ba29 5016 CYASSL_MSG("processing server hello");
Vanger 0:b86d15c6ba29 5017 ret = DoServerHello(ssl, input, inOutIdx, size);
Vanger 0:b86d15c6ba29 5018 break;
Vanger 0:b86d15c6ba29 5019
Vanger 0:b86d15c6ba29 5020 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 5021 case certificate_request:
Vanger 0:b86d15c6ba29 5022 CYASSL_MSG("processing certificate request");
Vanger 0:b86d15c6ba29 5023 ret = DoCertificateRequest(ssl, input, inOutIdx, size);
Vanger 0:b86d15c6ba29 5024 break;
Vanger 0:b86d15c6ba29 5025 #endif
Vanger 0:b86d15c6ba29 5026
Vanger 0:b86d15c6ba29 5027 case server_key_exchange:
Vanger 0:b86d15c6ba29 5028 CYASSL_MSG("processing server key exchange");
Vanger 0:b86d15c6ba29 5029 ret = DoServerKeyExchange(ssl, input, inOutIdx, size);
Vanger 0:b86d15c6ba29 5030 break;
Vanger 0:b86d15c6ba29 5031
Vanger 0:b86d15c6ba29 5032 #ifdef HAVE_SESSION_TICKET
Vanger 0:b86d15c6ba29 5033 case session_ticket:
Vanger 0:b86d15c6ba29 5034 CYASSL_MSG("processing session ticket");
Vanger 0:b86d15c6ba29 5035 ret = DoSessionTicket(ssl, input, inOutIdx, size);
Vanger 0:b86d15c6ba29 5036 break;
Vanger 0:b86d15c6ba29 5037 #endif /* HAVE_SESSION_TICKET */
Vanger 0:b86d15c6ba29 5038 #endif
Vanger 0:b86d15c6ba29 5039
Vanger 0:b86d15c6ba29 5040 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 5041 case certificate:
Vanger 0:b86d15c6ba29 5042 CYASSL_MSG("processing certificate");
Vanger 0:b86d15c6ba29 5043 ret = DoCertificate(ssl, input, inOutIdx, size);
Vanger 0:b86d15c6ba29 5044 break;
Vanger 0:b86d15c6ba29 5045 #endif
Vanger 0:b86d15c6ba29 5046
Vanger 0:b86d15c6ba29 5047 case server_hello_done:
Vanger 0:b86d15c6ba29 5048 CYASSL_MSG("processing server hello done");
Vanger 0:b86d15c6ba29 5049 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 5050 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 5051 AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 5052 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 5053 AddLateName("ServerHelloDone", &ssl->timeoutInfo);
Vanger 0:b86d15c6ba29 5054 #endif
Vanger 0:b86d15c6ba29 5055 ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
Vanger 0:b86d15c6ba29 5056 if (ssl->keys.encryptionOn) {
Vanger 0:b86d15c6ba29 5057 *inOutIdx += ssl->keys.padSz;
Vanger 0:b86d15c6ba29 5058 }
Vanger 0:b86d15c6ba29 5059 break;
Vanger 0:b86d15c6ba29 5060
Vanger 0:b86d15c6ba29 5061 case finished:
Vanger 0:b86d15c6ba29 5062 CYASSL_MSG("processing finished");
Vanger 0:b86d15c6ba29 5063 ret = DoFinished(ssl, input, inOutIdx, size, totalSz, NO_SNIFF);
Vanger 0:b86d15c6ba29 5064 break;
Vanger 0:b86d15c6ba29 5065
Vanger 0:b86d15c6ba29 5066 #ifndef NO_CYASSL_SERVER
Vanger 0:b86d15c6ba29 5067 case client_hello:
Vanger 0:b86d15c6ba29 5068 CYASSL_MSG("processing client hello");
Vanger 0:b86d15c6ba29 5069 ret = DoClientHello(ssl, input, inOutIdx, size);
Vanger 0:b86d15c6ba29 5070 break;
Vanger 0:b86d15c6ba29 5071
Vanger 0:b86d15c6ba29 5072 case client_key_exchange:
Vanger 0:b86d15c6ba29 5073 CYASSL_MSG("processing client key exchange");
Vanger 0:b86d15c6ba29 5074 ret = DoClientKeyExchange(ssl, input, inOutIdx, size);
Vanger 0:b86d15c6ba29 5075 break;
Vanger 0:b86d15c6ba29 5076
Vanger 0:b86d15c6ba29 5077 #if !defined(NO_RSA) || defined(HAVE_ECC)
Vanger 0:b86d15c6ba29 5078 case certificate_verify:
Vanger 0:b86d15c6ba29 5079 CYASSL_MSG("processing certificate verify");
Vanger 0:b86d15c6ba29 5080 ret = DoCertificateVerify(ssl, input, inOutIdx, size);
Vanger 0:b86d15c6ba29 5081 break;
Vanger 0:b86d15c6ba29 5082 #endif /* !NO_RSA || HAVE_ECC */
Vanger 0:b86d15c6ba29 5083
Vanger 0:b86d15c6ba29 5084 #endif /* !NO_CYASSL_SERVER */
Vanger 0:b86d15c6ba29 5085
Vanger 0:b86d15c6ba29 5086 default:
Vanger 0:b86d15c6ba29 5087 CYASSL_MSG("Unknown handshake message type");
Vanger 0:b86d15c6ba29 5088 ret = UNKNOWN_HANDSHAKE_TYPE;
Vanger 0:b86d15c6ba29 5089 break;
Vanger 0:b86d15c6ba29 5090 }
Vanger 0:b86d15c6ba29 5091
Vanger 0:b86d15c6ba29 5092 CYASSL_LEAVE("DoHandShakeMsgType()", ret);
Vanger 0:b86d15c6ba29 5093 return ret;
Vanger 0:b86d15c6ba29 5094 }
Vanger 0:b86d15c6ba29 5095
Vanger 0:b86d15c6ba29 5096
Vanger 0:b86d15c6ba29 5097 static int DoHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
Vanger 0:b86d15c6ba29 5098 word32 totalSz)
Vanger 0:b86d15c6ba29 5099 {
Vanger 0:b86d15c6ba29 5100 byte type;
Vanger 0:b86d15c6ba29 5101 word32 size;
Vanger 0:b86d15c6ba29 5102 int ret = 0;
Vanger 0:b86d15c6ba29 5103
Vanger 0:b86d15c6ba29 5104 CYASSL_ENTER("DoHandShakeMsg()");
Vanger 0:b86d15c6ba29 5105
Vanger 0:b86d15c6ba29 5106 if (GetHandShakeHeader(ssl, input, inOutIdx, &type, &size, totalSz) != 0)
Vanger 0:b86d15c6ba29 5107 return PARSE_ERROR;
Vanger 0:b86d15c6ba29 5108
Vanger 0:b86d15c6ba29 5109 ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
Vanger 0:b86d15c6ba29 5110
Vanger 0:b86d15c6ba29 5111 CYASSL_LEAVE("DoHandShakeMsg()", ret);
Vanger 0:b86d15c6ba29 5112 return ret;
Vanger 0:b86d15c6ba29 5113 }
Vanger 0:b86d15c6ba29 5114
Vanger 0:b86d15c6ba29 5115
Vanger 0:b86d15c6ba29 5116 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 5117
Vanger 0:b86d15c6ba29 5118 static INLINE int DtlsCheckWindow(DtlsState* state)
Vanger 0:b86d15c6ba29 5119 {
Vanger 0:b86d15c6ba29 5120 word32 cur;
Vanger 0:b86d15c6ba29 5121 word32 next;
Vanger 0:b86d15c6ba29 5122 DtlsSeq window;
Vanger 0:b86d15c6ba29 5123
Vanger 0:b86d15c6ba29 5124 if (state->curEpoch == state->nextEpoch) {
Vanger 0:b86d15c6ba29 5125 next = state->nextSeq;
Vanger 0:b86d15c6ba29 5126 window = state->window;
Vanger 0:b86d15c6ba29 5127 }
Vanger 0:b86d15c6ba29 5128 else if (state->curEpoch < state->nextEpoch) {
Vanger 0:b86d15c6ba29 5129 next = state->prevSeq;
Vanger 0:b86d15c6ba29 5130 window = state->prevWindow;
Vanger 0:b86d15c6ba29 5131 }
Vanger 0:b86d15c6ba29 5132 else {
Vanger 0:b86d15c6ba29 5133 return 0;
Vanger 0:b86d15c6ba29 5134 }
Vanger 0:b86d15c6ba29 5135
Vanger 0:b86d15c6ba29 5136 cur = state->curSeq;
Vanger 0:b86d15c6ba29 5137
Vanger 0:b86d15c6ba29 5138 if ((next > DTLS_SEQ_BITS) && (cur < next - DTLS_SEQ_BITS)) {
Vanger 0:b86d15c6ba29 5139 return 0;
Vanger 0:b86d15c6ba29 5140 }
Vanger 0:b86d15c6ba29 5141 else if ((cur < next) && (window & ((DtlsSeq)1 << (next - cur - 1)))) {
Vanger 0:b86d15c6ba29 5142 return 0;
Vanger 0:b86d15c6ba29 5143 }
Vanger 0:b86d15c6ba29 5144
Vanger 0:b86d15c6ba29 5145 return 1;
Vanger 0:b86d15c6ba29 5146 }
Vanger 0:b86d15c6ba29 5147
Vanger 0:b86d15c6ba29 5148
Vanger 0:b86d15c6ba29 5149 static INLINE int DtlsUpdateWindow(DtlsState* state)
Vanger 0:b86d15c6ba29 5150 {
Vanger 0:b86d15c6ba29 5151 word32 cur;
Vanger 0:b86d15c6ba29 5152 word32* next;
Vanger 0:b86d15c6ba29 5153 DtlsSeq* window;
Vanger 0:b86d15c6ba29 5154
Vanger 0:b86d15c6ba29 5155 if (state->curEpoch == state->nextEpoch) {
Vanger 0:b86d15c6ba29 5156 next = &state->nextSeq;
Vanger 0:b86d15c6ba29 5157 window = &state->window;
Vanger 0:b86d15c6ba29 5158 }
Vanger 0:b86d15c6ba29 5159 else {
Vanger 0:b86d15c6ba29 5160 next = &state->prevSeq;
Vanger 0:b86d15c6ba29 5161 window = &state->prevWindow;
Vanger 0:b86d15c6ba29 5162 }
Vanger 0:b86d15c6ba29 5163
Vanger 0:b86d15c6ba29 5164 cur = state->curSeq;
Vanger 0:b86d15c6ba29 5165
Vanger 0:b86d15c6ba29 5166 if (cur < *next) {
Vanger 0:b86d15c6ba29 5167 *window |= ((DtlsSeq)1 << (*next - cur - 1));
Vanger 0:b86d15c6ba29 5168 }
Vanger 0:b86d15c6ba29 5169 else {
Vanger 0:b86d15c6ba29 5170 *window <<= (1 + cur - *next);
Vanger 0:b86d15c6ba29 5171 *window |= 1;
Vanger 0:b86d15c6ba29 5172 *next = cur + 1;
Vanger 0:b86d15c6ba29 5173 }
Vanger 0:b86d15c6ba29 5174
Vanger 0:b86d15c6ba29 5175 return 1;
Vanger 0:b86d15c6ba29 5176 }
Vanger 0:b86d15c6ba29 5177
Vanger 0:b86d15c6ba29 5178
Vanger 0:b86d15c6ba29 5179 static int DtlsMsgDrain(CYASSL* ssl)
Vanger 0:b86d15c6ba29 5180 {
Vanger 0:b86d15c6ba29 5181 DtlsMsg* item = ssl->dtls_msg_list;
Vanger 0:b86d15c6ba29 5182 int ret = 0;
Vanger 0:b86d15c6ba29 5183
Vanger 0:b86d15c6ba29 5184 /* While there is an item in the store list, and it is the expected
Vanger 0:b86d15c6ba29 5185 * message, and it is complete, and there hasn't been an error in the
Vanger 0:b86d15c6ba29 5186 * last messge... */
Vanger 0:b86d15c6ba29 5187 while (item != NULL &&
Vanger 0:b86d15c6ba29 5188 ssl->keys.dtls_expected_peer_handshake_number == item->seq &&
Vanger 0:b86d15c6ba29 5189 item->fragSz == item->sz &&
Vanger 0:b86d15c6ba29 5190 ret == 0) {
Vanger 0:b86d15c6ba29 5191 word32 idx = 0;
Vanger 0:b86d15c6ba29 5192 ssl->keys.dtls_expected_peer_handshake_number++;
Vanger 0:b86d15c6ba29 5193 ret = DoHandShakeMsgType(ssl, item->msg,
Vanger 0:b86d15c6ba29 5194 &idx, item->type, item->sz, item->sz);
Vanger 0:b86d15c6ba29 5195 ssl->dtls_msg_list = item->next;
Vanger 0:b86d15c6ba29 5196 DtlsMsgDelete(item, ssl->heap);
Vanger 0:b86d15c6ba29 5197 item = ssl->dtls_msg_list;
Vanger 0:b86d15c6ba29 5198 }
Vanger 0:b86d15c6ba29 5199
Vanger 0:b86d15c6ba29 5200 return ret;
Vanger 0:b86d15c6ba29 5201 }
Vanger 0:b86d15c6ba29 5202
Vanger 0:b86d15c6ba29 5203
Vanger 0:b86d15c6ba29 5204 static int DoDtlsHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
Vanger 0:b86d15c6ba29 5205 word32 totalSz)
Vanger 0:b86d15c6ba29 5206 {
Vanger 0:b86d15c6ba29 5207 byte type;
Vanger 0:b86d15c6ba29 5208 word32 size;
Vanger 0:b86d15c6ba29 5209 word32 fragOffset, fragSz;
Vanger 0:b86d15c6ba29 5210 int ret = 0;
Vanger 0:b86d15c6ba29 5211
Vanger 0:b86d15c6ba29 5212 CYASSL_ENTER("DoDtlsHandShakeMsg()");
Vanger 0:b86d15c6ba29 5213 if (GetDtlsHandShakeHeader(ssl, input, inOutIdx, &type,
Vanger 0:b86d15c6ba29 5214 &size, &fragOffset, &fragSz, totalSz) != 0)
Vanger 0:b86d15c6ba29 5215 return PARSE_ERROR;
Vanger 0:b86d15c6ba29 5216
Vanger 0:b86d15c6ba29 5217 if (*inOutIdx + fragSz > totalSz)
Vanger 0:b86d15c6ba29 5218 return INCOMPLETE_DATA;
Vanger 0:b86d15c6ba29 5219
Vanger 0:b86d15c6ba29 5220 /* Check the handshake sequence number first. If out of order,
Vanger 0:b86d15c6ba29 5221 * add the current message to the list. If the message is in order,
Vanger 0:b86d15c6ba29 5222 * but it is a fragment, add the current message to the list, then
Vanger 0:b86d15c6ba29 5223 * check the head of the list to see if it is complete, if so, pop
Vanger 0:b86d15c6ba29 5224 * it out as the current message. If the message is complete and in
Vanger 0:b86d15c6ba29 5225 * order, process it. Check the head of the list to see if it is in
Vanger 0:b86d15c6ba29 5226 * order, if so, process it. (Repeat until list exhausted.) If the
Vanger 0:b86d15c6ba29 5227 * head is out of order, return for more processing.
Vanger 0:b86d15c6ba29 5228 */
Vanger 0:b86d15c6ba29 5229 if (ssl->keys.dtls_peer_handshake_number >
Vanger 0:b86d15c6ba29 5230 ssl->keys.dtls_expected_peer_handshake_number) {
Vanger 0:b86d15c6ba29 5231 /* Current message is out of order. It will get stored in the list.
Vanger 0:b86d15c6ba29 5232 * Storing also takes care of defragmentation. */
Vanger 0:b86d15c6ba29 5233 ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
Vanger 0:b86d15c6ba29 5234 ssl->keys.dtls_peer_handshake_number, input + *inOutIdx,
Vanger 0:b86d15c6ba29 5235 size, type, fragOffset, fragSz, ssl->heap);
Vanger 0:b86d15c6ba29 5236 *inOutIdx += fragSz;
Vanger 0:b86d15c6ba29 5237 ret = 0;
Vanger 0:b86d15c6ba29 5238 }
Vanger 0:b86d15c6ba29 5239 else if (ssl->keys.dtls_peer_handshake_number <
Vanger 0:b86d15c6ba29 5240 ssl->keys.dtls_expected_peer_handshake_number) {
Vanger 0:b86d15c6ba29 5241 /* Already saw this message and processed it. It can be ignored. */
Vanger 0:b86d15c6ba29 5242 *inOutIdx += fragSz;
Vanger 0:b86d15c6ba29 5243 ret = 0;
Vanger 0:b86d15c6ba29 5244 }
Vanger 0:b86d15c6ba29 5245 else if (fragSz < size) {
Vanger 0:b86d15c6ba29 5246 /* Since this branch is in order, but fragmented, dtls_msg_list will be
Vanger 0:b86d15c6ba29 5247 * pointing to the message with this fragment in it. Check it to see
Vanger 0:b86d15c6ba29 5248 * if it is completed. */
Vanger 0:b86d15c6ba29 5249 ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
Vanger 0:b86d15c6ba29 5250 ssl->keys.dtls_peer_handshake_number, input + *inOutIdx,
Vanger 0:b86d15c6ba29 5251 size, type, fragOffset, fragSz, ssl->heap);
Vanger 0:b86d15c6ba29 5252 *inOutIdx += fragSz;
Vanger 0:b86d15c6ba29 5253 ret = 0;
Vanger 0:b86d15c6ba29 5254 if (ssl->dtls_msg_list != NULL &&
Vanger 0:b86d15c6ba29 5255 ssl->dtls_msg_list->fragSz >= ssl->dtls_msg_list->sz)
Vanger 0:b86d15c6ba29 5256 ret = DtlsMsgDrain(ssl);
Vanger 0:b86d15c6ba29 5257 }
Vanger 0:b86d15c6ba29 5258 else {
Vanger 0:b86d15c6ba29 5259 /* This branch is in order next, and a complete message. */
Vanger 0:b86d15c6ba29 5260 ssl->keys.dtls_expected_peer_handshake_number++;
Vanger 0:b86d15c6ba29 5261 ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
Vanger 0:b86d15c6ba29 5262 if (ret == 0 && ssl->dtls_msg_list != NULL)
Vanger 0:b86d15c6ba29 5263 ret = DtlsMsgDrain(ssl);
Vanger 0:b86d15c6ba29 5264 }
Vanger 0:b86d15c6ba29 5265
Vanger 0:b86d15c6ba29 5266 CYASSL_LEAVE("DoDtlsHandShakeMsg()", ret);
Vanger 0:b86d15c6ba29 5267 return ret;
Vanger 0:b86d15c6ba29 5268 }
Vanger 0:b86d15c6ba29 5269 #endif
Vanger 0:b86d15c6ba29 5270
Vanger 0:b86d15c6ba29 5271
Vanger 0:b86d15c6ba29 5272 #if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \
Vanger 0:b86d15c6ba29 5273 || defined(HAVE_AESGCM)
Vanger 0:b86d15c6ba29 5274 static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
Vanger 0:b86d15c6ba29 5275 {
Vanger 0:b86d15c6ba29 5276 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 5277 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 5278 if (verify)
Vanger 0:b86d15c6ba29 5279 return ssl->keys.dtls_state.curSeq; /* explicit from peer */
Vanger 0:b86d15c6ba29 5280 else
Vanger 0:b86d15c6ba29 5281 return ssl->keys.dtls_sequence_number - 1; /* already incremented */
Vanger 0:b86d15c6ba29 5282 }
Vanger 0:b86d15c6ba29 5283 #endif
Vanger 0:b86d15c6ba29 5284 if (verify)
Vanger 0:b86d15c6ba29 5285 return ssl->keys.peer_sequence_number++;
Vanger 0:b86d15c6ba29 5286 else
Vanger 0:b86d15c6ba29 5287 return ssl->keys.sequence_number++;
Vanger 0:b86d15c6ba29 5288 }
Vanger 0:b86d15c6ba29 5289 #endif
Vanger 0:b86d15c6ba29 5290
Vanger 0:b86d15c6ba29 5291
Vanger 0:b86d15c6ba29 5292 #ifdef HAVE_AEAD
Vanger 0:b86d15c6ba29 5293 static INLINE void AeadIncrementExpIV(CYASSL* ssl)
Vanger 0:b86d15c6ba29 5294 {
Vanger 0:b86d15c6ba29 5295 int i;
Vanger 0:b86d15c6ba29 5296 for (i = AEAD_EXP_IV_SZ-1; i >= 0; i--) {
Vanger 0:b86d15c6ba29 5297 if (++ssl->keys.aead_exp_IV[i]) return;
Vanger 0:b86d15c6ba29 5298 }
Vanger 0:b86d15c6ba29 5299 }
Vanger 0:b86d15c6ba29 5300
Vanger 0:b86d15c6ba29 5301
Vanger 0:b86d15c6ba29 5302 #ifdef HAVE_POLY1305
Vanger 0:b86d15c6ba29 5303 /*more recent rfc's concatonate input for poly1305 differently*/
Vanger 0:b86d15c6ba29 5304 static int Poly1305Tag(CYASSL* ssl, byte* additional, const byte* out,
Vanger 0:b86d15c6ba29 5305 byte* cipher, word16 sz, byte* tag)
Vanger 0:b86d15c6ba29 5306 {
Vanger 0:b86d15c6ba29 5307 int ret = 0;
Vanger 0:b86d15c6ba29 5308 int paddingSz = 0;
Vanger 0:b86d15c6ba29 5309 int msglen = (sz - ssl->specs.aead_mac_size);
Vanger 0:b86d15c6ba29 5310 word32 keySz = 32;
Vanger 0:b86d15c6ba29 5311 byte padding[16];
Vanger 0:b86d15c6ba29 5312
Vanger 0:b86d15c6ba29 5313 if (msglen < 0)
Vanger 0:b86d15c6ba29 5314 return INPUT_CASE_ERROR;
Vanger 0:b86d15c6ba29 5315
Vanger 0:b86d15c6ba29 5316 XMEMSET(padding, 0, sizeof(padding));
Vanger 0:b86d15c6ba29 5317
Vanger 0:b86d15c6ba29 5318 if ((ret = Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0)
Vanger 0:b86d15c6ba29 5319 return ret;
Vanger 0:b86d15c6ba29 5320
Vanger 0:b86d15c6ba29 5321 /* additional input to poly1305 */
Vanger 0:b86d15c6ba29 5322 if ((ret = Poly1305Update(ssl->auth.poly1305, additional,
Vanger 0:b86d15c6ba29 5323 CHACHA20_BLOCK_SIZE)) != 0)
Vanger 0:b86d15c6ba29 5324 return ret;
Vanger 0:b86d15c6ba29 5325
Vanger 0:b86d15c6ba29 5326 /* cipher input */
Vanger 0:b86d15c6ba29 5327 if ((ret = Poly1305Update(ssl->auth.poly1305, out, msglen)) != 0)
Vanger 0:b86d15c6ba29 5328 return ret;
Vanger 0:b86d15c6ba29 5329
Vanger 0:b86d15c6ba29 5330 /* handle padding for cipher input to make it 16 bytes long */
Vanger 0:b86d15c6ba29 5331 if (msglen % 16 != 0) {
Vanger 0:b86d15c6ba29 5332 paddingSz = (16 - (sz - ssl->specs.aead_mac_size) % 16);
Vanger 0:b86d15c6ba29 5333 if (paddingSz < 0)
Vanger 0:b86d15c6ba29 5334 return INPUT_CASE_ERROR;
Vanger 0:b86d15c6ba29 5335
Vanger 0:b86d15c6ba29 5336 if ((ret = Poly1305Update(ssl->auth.poly1305, padding, paddingSz))
Vanger 0:b86d15c6ba29 5337 != 0)
Vanger 0:b86d15c6ba29 5338 return ret;
Vanger 0:b86d15c6ba29 5339 }
Vanger 0:b86d15c6ba29 5340
Vanger 0:b86d15c6ba29 5341 /* add size of AD and size of cipher to poly input */
Vanger 0:b86d15c6ba29 5342 XMEMSET(padding, 0, sizeof(padding));
Vanger 0:b86d15c6ba29 5343 padding[0] = CHACHA20_BLOCK_SIZE;
Vanger 0:b86d15c6ba29 5344
Vanger 0:b86d15c6ba29 5345 /* 32 bit size of cipher to 64 bit endian */
Vanger 0:b86d15c6ba29 5346 padding[8] = msglen & 0xff;
Vanger 0:b86d15c6ba29 5347 padding[9] = (msglen >> 8) & 0xff;
Vanger 0:b86d15c6ba29 5348 padding[10] = (msglen >>16) & 0xff;
Vanger 0:b86d15c6ba29 5349 padding[11] = (msglen >>24) & 0xff;
Vanger 0:b86d15c6ba29 5350 if ((ret = Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding)))
Vanger 0:b86d15c6ba29 5351 != 0)
Vanger 0:b86d15c6ba29 5352 return ret;
Vanger 0:b86d15c6ba29 5353
Vanger 0:b86d15c6ba29 5354 /* generate tag */
Vanger 0:b86d15c6ba29 5355 if ((ret = Poly1305Final(ssl->auth.poly1305, tag)) != 0)
Vanger 0:b86d15c6ba29 5356 return ret;
Vanger 0:b86d15c6ba29 5357
Vanger 0:b86d15c6ba29 5358 return ret;
Vanger 0:b86d15c6ba29 5359 }
Vanger 0:b86d15c6ba29 5360
Vanger 0:b86d15c6ba29 5361
Vanger 0:b86d15c6ba29 5362 /* Used for the older version of creating AEAD tags with Poly1305 */
Vanger 0:b86d15c6ba29 5363 static int Poly1305TagOld(CYASSL* ssl, byte* additional, const byte* out,
Vanger 0:b86d15c6ba29 5364 byte* cipher, word16 sz, byte* tag)
Vanger 0:b86d15c6ba29 5365 {
Vanger 0:b86d15c6ba29 5366 int ret = 0;
Vanger 0:b86d15c6ba29 5367 int msglen = (sz - ssl->specs.aead_mac_size);
Vanger 0:b86d15c6ba29 5368 word32 keySz = 32;
Vanger 0:b86d15c6ba29 5369 byte padding[8]; /* used to temporarly store lengths */
Vanger 0:b86d15c6ba29 5370
Vanger 0:b86d15c6ba29 5371 #ifdef CHACHA_AEAD_TEST
Vanger 0:b86d15c6ba29 5372 printf("Using old version of poly1305 input.\n");
Vanger 0:b86d15c6ba29 5373 #endif
Vanger 0:b86d15c6ba29 5374
Vanger 0:b86d15c6ba29 5375 if (msglen < 0)
Vanger 0:b86d15c6ba29 5376 return INPUT_CASE_ERROR;
Vanger 0:b86d15c6ba29 5377
Vanger 0:b86d15c6ba29 5378 if ((ret = Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0)
Vanger 0:b86d15c6ba29 5379 return ret;
Vanger 0:b86d15c6ba29 5380
Vanger 0:b86d15c6ba29 5381 /* add TLS compressed length and additional input to poly1305 */
Vanger 0:b86d15c6ba29 5382 additional[AEAD_AUTH_DATA_SZ - 2] = (msglen >> 8) & 0xff;
Vanger 0:b86d15c6ba29 5383 additional[AEAD_AUTH_DATA_SZ - 1] = msglen & 0xff;
Vanger 0:b86d15c6ba29 5384 if ((ret = Poly1305Update(ssl->auth.poly1305, additional,
Vanger 0:b86d15c6ba29 5385 AEAD_AUTH_DATA_SZ)) != 0)
Vanger 0:b86d15c6ba29 5386 return ret;
Vanger 0:b86d15c6ba29 5387
Vanger 0:b86d15c6ba29 5388 /* length of additional input plus padding */
Vanger 0:b86d15c6ba29 5389 XMEMSET(padding, 0, sizeof(padding));
Vanger 0:b86d15c6ba29 5390 padding[0] = AEAD_AUTH_DATA_SZ;
Vanger 0:b86d15c6ba29 5391 if ((ret = Poly1305Update(ssl->auth.poly1305, padding,
Vanger 0:b86d15c6ba29 5392 sizeof(padding))) != 0)
Vanger 0:b86d15c6ba29 5393 return ret;
Vanger 0:b86d15c6ba29 5394
Vanger 0:b86d15c6ba29 5395
Vanger 0:b86d15c6ba29 5396 /* add cipher info and then its length */
Vanger 0:b86d15c6ba29 5397 XMEMSET(padding, 0, sizeof(padding));
Vanger 0:b86d15c6ba29 5398 if ((ret = Poly1305Update(ssl->auth.poly1305, out, msglen)) != 0)
Vanger 0:b86d15c6ba29 5399 return ret;
Vanger 0:b86d15c6ba29 5400
Vanger 0:b86d15c6ba29 5401 /* 32 bit size of cipher to 64 bit endian */
Vanger 0:b86d15c6ba29 5402 padding[0] = msglen & 0xff;
Vanger 0:b86d15c6ba29 5403 padding[1] = (msglen >> 8) & 0xff;
Vanger 0:b86d15c6ba29 5404 padding[2] = (msglen >> 16) & 0xff;
Vanger 0:b86d15c6ba29 5405 padding[3] = (msglen >> 24) & 0xff;
Vanger 0:b86d15c6ba29 5406 if ((ret = Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding)))
Vanger 0:b86d15c6ba29 5407 != 0)
Vanger 0:b86d15c6ba29 5408 return ret;
Vanger 0:b86d15c6ba29 5409
Vanger 0:b86d15c6ba29 5410 /* generate tag */
Vanger 0:b86d15c6ba29 5411 if ((ret = Poly1305Final(ssl->auth.poly1305, tag)) != 0)
Vanger 0:b86d15c6ba29 5412 return ret;
Vanger 0:b86d15c6ba29 5413
Vanger 0:b86d15c6ba29 5414 return ret;
Vanger 0:b86d15c6ba29 5415 }
Vanger 0:b86d15c6ba29 5416 #endif /*HAVE_POLY1305*/
Vanger 0:b86d15c6ba29 5417
Vanger 0:b86d15c6ba29 5418
Vanger 0:b86d15c6ba29 5419 #ifdef HAVE_CHACHA
Vanger 0:b86d15c6ba29 5420 static int ChachaAEADEncrypt(CYASSL* ssl, byte* out, const byte* input,
Vanger 0:b86d15c6ba29 5421 word16 sz)
Vanger 0:b86d15c6ba29 5422 {
Vanger 0:b86d15c6ba29 5423 const byte* additionalSrc = input - RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 5424 int ret = 0;
Vanger 0:b86d15c6ba29 5425 byte tag[POLY1305_AUTH_SZ];
Vanger 0:b86d15c6ba29 5426 byte additional[CHACHA20_BLOCK_SIZE];
Vanger 0:b86d15c6ba29 5427 byte nonce[AEAD_NONCE_SZ];
Vanger 0:b86d15c6ba29 5428 byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for poly1305 */
Vanger 0:b86d15c6ba29 5429 #ifdef CHACHA_AEAD_TEST
Vanger 0:b86d15c6ba29 5430 int i;
Vanger 0:b86d15c6ba29 5431 #endif
Vanger 0:b86d15c6ba29 5432
Vanger 0:b86d15c6ba29 5433 XMEMSET(tag, 0, sizeof(tag));
Vanger 0:b86d15c6ba29 5434 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
Vanger 0:b86d15c6ba29 5435 XMEMSET(cipher, 0, sizeof(cipher));
Vanger 0:b86d15c6ba29 5436 XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 5437
Vanger 0:b86d15c6ba29 5438 /* get nonce */
Vanger 0:b86d15c6ba29 5439 c32toa(ssl->keys.sequence_number, nonce + AEAD_IMP_IV_SZ
Vanger 0:b86d15c6ba29 5440 + AEAD_SEQ_OFFSET);
Vanger 0:b86d15c6ba29 5441
Vanger 0:b86d15c6ba29 5442 /* opaque SEQ number stored for AD */
Vanger 0:b86d15c6ba29 5443 c32toa(GetSEQIncrement(ssl, 0), additional + AEAD_SEQ_OFFSET);
Vanger 0:b86d15c6ba29 5444
Vanger 0:b86d15c6ba29 5445 /* Store the type, version. Unfortunately, they are in
Vanger 0:b86d15c6ba29 5446 * the input buffer ahead of the plaintext. */
Vanger 0:b86d15c6ba29 5447 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 5448 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 5449 c16toa(ssl->keys.dtls_epoch, additional);
Vanger 0:b86d15c6ba29 5450 additionalSrc -= DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 5451 }
Vanger 0:b86d15c6ba29 5452 #endif
Vanger 0:b86d15c6ba29 5453
Vanger 0:b86d15c6ba29 5454 XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
Vanger 0:b86d15c6ba29 5455
Vanger 0:b86d15c6ba29 5456 #ifdef CHACHA_AEAD_TEST
Vanger 0:b86d15c6ba29 5457 printf("Encrypt Additional : ");
Vanger 0:b86d15c6ba29 5458 for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) {
Vanger 0:b86d15c6ba29 5459 printf("%02x", additional[i]);
Vanger 0:b86d15c6ba29 5460 }
Vanger 0:b86d15c6ba29 5461 printf("\n\n");
Vanger 0:b86d15c6ba29 5462 printf("input before encryption :\n");
Vanger 0:b86d15c6ba29 5463 for (i = 0; i < sz; i++) {
Vanger 0:b86d15c6ba29 5464 printf("%02x", input[i]);
Vanger 0:b86d15c6ba29 5465 if ((i + 1) % 16 == 0)
Vanger 0:b86d15c6ba29 5466 printf("\n");
Vanger 0:b86d15c6ba29 5467 }
Vanger 0:b86d15c6ba29 5468 printf("\n");
Vanger 0:b86d15c6ba29 5469 #endif
Vanger 0:b86d15c6ba29 5470
Vanger 0:b86d15c6ba29 5471 /* set the nonce for chacha and get poly1305 key */
Vanger 0:b86d15c6ba29 5472 if ((ret = Chacha_SetIV(ssl->encrypt.chacha, nonce, 0)) != 0)
Vanger 0:b86d15c6ba29 5473 return ret;
Vanger 0:b86d15c6ba29 5474
Vanger 0:b86d15c6ba29 5475 if ((ret = Chacha_Process(ssl->encrypt.chacha, cipher,
Vanger 0:b86d15c6ba29 5476 cipher, sizeof(cipher))) != 0)
Vanger 0:b86d15c6ba29 5477 return ret;
Vanger 0:b86d15c6ba29 5478
Vanger 0:b86d15c6ba29 5479 /* encrypt the plain text */
Vanger 0:b86d15c6ba29 5480 if ((ret = Chacha_Process(ssl->encrypt.chacha, out, input,
Vanger 0:b86d15c6ba29 5481 sz - ssl->specs.aead_mac_size)) != 0)
Vanger 0:b86d15c6ba29 5482 return ret;
Vanger 0:b86d15c6ba29 5483
Vanger 0:b86d15c6ba29 5484 #ifdef HAVE_POLY1305
Vanger 0:b86d15c6ba29 5485 /* get the tag : future use of hmac could go here*/
Vanger 0:b86d15c6ba29 5486 if (ssl->options.oldPoly == 1) {
Vanger 0:b86d15c6ba29 5487 if ((ret = Poly1305TagOld(ssl, additional, (const byte* )out,
Vanger 0:b86d15c6ba29 5488 cipher, sz, tag)) != 0)
Vanger 0:b86d15c6ba29 5489 return ret;
Vanger 0:b86d15c6ba29 5490 }
Vanger 0:b86d15c6ba29 5491 else {
Vanger 0:b86d15c6ba29 5492 if ((ret = Poly1305Tag(ssl, additional, (const byte* )out,
Vanger 0:b86d15c6ba29 5493 cipher, sz, tag)) != 0)
Vanger 0:b86d15c6ba29 5494 return ret;
Vanger 0:b86d15c6ba29 5495 }
Vanger 0:b86d15c6ba29 5496 #endif
Vanger 0:b86d15c6ba29 5497
Vanger 0:b86d15c6ba29 5498 /* append tag to ciphertext */
Vanger 0:b86d15c6ba29 5499 XMEMCPY(out + sz - ssl->specs.aead_mac_size, tag, sizeof(tag));
Vanger 0:b86d15c6ba29 5500
Vanger 0:b86d15c6ba29 5501 AeadIncrementExpIV(ssl);
Vanger 0:b86d15c6ba29 5502 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
Vanger 0:b86d15c6ba29 5503
Vanger 0:b86d15c6ba29 5504 #ifdef CHACHA_AEAD_TEST
Vanger 0:b86d15c6ba29 5505 printf("mac tag :\n");
Vanger 0:b86d15c6ba29 5506 for (i = 0; i < 16; i++) {
Vanger 0:b86d15c6ba29 5507 printf("%02x", tag[i]);
Vanger 0:b86d15c6ba29 5508 if ((i + 1) % 16 == 0)
Vanger 0:b86d15c6ba29 5509 printf("\n");
Vanger 0:b86d15c6ba29 5510 }
Vanger 0:b86d15c6ba29 5511 printf("\n\noutput after encrypt :\n");
Vanger 0:b86d15c6ba29 5512 for (i = 0; i < sz; i++) {
Vanger 0:b86d15c6ba29 5513 printf("%02x", out[i]);
Vanger 0:b86d15c6ba29 5514 if ((i + 1) % 16 == 0)
Vanger 0:b86d15c6ba29 5515 printf("\n");
Vanger 0:b86d15c6ba29 5516 }
Vanger 0:b86d15c6ba29 5517 printf("\n");
Vanger 0:b86d15c6ba29 5518 #endif
Vanger 0:b86d15c6ba29 5519
Vanger 0:b86d15c6ba29 5520 return ret;
Vanger 0:b86d15c6ba29 5521 }
Vanger 0:b86d15c6ba29 5522
Vanger 0:b86d15c6ba29 5523
Vanger 0:b86d15c6ba29 5524 static int ChachaAEADDecrypt(CYASSL* ssl, byte* plain, const byte* input,
Vanger 0:b86d15c6ba29 5525 word16 sz)
Vanger 0:b86d15c6ba29 5526 {
Vanger 0:b86d15c6ba29 5527 byte additional[CHACHA20_BLOCK_SIZE];
Vanger 0:b86d15c6ba29 5528 byte nonce[AEAD_NONCE_SZ];
Vanger 0:b86d15c6ba29 5529 byte tag[POLY1305_AUTH_SZ];
Vanger 0:b86d15c6ba29 5530 byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for mac */
Vanger 0:b86d15c6ba29 5531 int i;
Vanger 0:b86d15c6ba29 5532 int ret = 0;
Vanger 0:b86d15c6ba29 5533
Vanger 0:b86d15c6ba29 5534 XMEMSET(tag, 0, sizeof(tag));
Vanger 0:b86d15c6ba29 5535 XMEMSET(cipher, 0, sizeof(cipher));
Vanger 0:b86d15c6ba29 5536 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
Vanger 0:b86d15c6ba29 5537 XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 5538
Vanger 0:b86d15c6ba29 5539 #ifdef CHACHA_AEAD_TEST
Vanger 0:b86d15c6ba29 5540 printf("input before decrypt :\n");
Vanger 0:b86d15c6ba29 5541 for (i = 0; i < sz; i++) {
Vanger 0:b86d15c6ba29 5542 printf("%02x", input[i]);
Vanger 0:b86d15c6ba29 5543 if ((i + 1) % 16 == 0)
Vanger 0:b86d15c6ba29 5544 printf("\n");
Vanger 0:b86d15c6ba29 5545 }
Vanger 0:b86d15c6ba29 5546 printf("\n");
Vanger 0:b86d15c6ba29 5547 #endif
Vanger 0:b86d15c6ba29 5548
Vanger 0:b86d15c6ba29 5549 /* get nonce */
Vanger 0:b86d15c6ba29 5550 c32toa(ssl->keys.peer_sequence_number, nonce + AEAD_IMP_IV_SZ
Vanger 0:b86d15c6ba29 5551 + AEAD_SEQ_OFFSET);
Vanger 0:b86d15c6ba29 5552
Vanger 0:b86d15c6ba29 5553 /* sequence number field is 64-bits, we only use 32-bits */
Vanger 0:b86d15c6ba29 5554 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
Vanger 0:b86d15c6ba29 5555
Vanger 0:b86d15c6ba29 5556 /* get AD info */
Vanger 0:b86d15c6ba29 5557 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
Vanger 0:b86d15c6ba29 5558 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
Vanger 0:b86d15c6ba29 5559 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
Vanger 0:b86d15c6ba29 5560
Vanger 0:b86d15c6ba29 5561 /* Store the type, version. */
Vanger 0:b86d15c6ba29 5562 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 5563 if (ssl->options.dtls)
Vanger 0:b86d15c6ba29 5564 c16toa(ssl->keys.dtls_state.curEpoch, additional);
Vanger 0:b86d15c6ba29 5565 #endif
Vanger 0:b86d15c6ba29 5566
Vanger 0:b86d15c6ba29 5567 #ifdef CHACHA_AEAD_TEST
Vanger 0:b86d15c6ba29 5568 printf("Decrypt Additional : ");
Vanger 0:b86d15c6ba29 5569 for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) {
Vanger 0:b86d15c6ba29 5570 printf("%02x", additional[i]);
Vanger 0:b86d15c6ba29 5571 }
Vanger 0:b86d15c6ba29 5572 printf("\n\n");
Vanger 0:b86d15c6ba29 5573 #endif
Vanger 0:b86d15c6ba29 5574
Vanger 0:b86d15c6ba29 5575 /* set nonce and get poly1305 key */
Vanger 0:b86d15c6ba29 5576 if ((ret = Chacha_SetIV(ssl->decrypt.chacha, nonce, 0)) != 0)
Vanger 0:b86d15c6ba29 5577 return ret;
Vanger 0:b86d15c6ba29 5578
Vanger 0:b86d15c6ba29 5579 if ((ret = Chacha_Process(ssl->decrypt.chacha, cipher,
Vanger 0:b86d15c6ba29 5580 cipher, sizeof(cipher))) != 0)
Vanger 0:b86d15c6ba29 5581 return ret;
Vanger 0:b86d15c6ba29 5582
Vanger 0:b86d15c6ba29 5583 #ifdef HAVE_POLY1305
Vanger 0:b86d15c6ba29 5584 /* get the tag : future use of hmac could go here*/
Vanger 0:b86d15c6ba29 5585 if (ssl->options.oldPoly == 1) {
Vanger 0:b86d15c6ba29 5586 if ((ret = Poly1305TagOld(ssl, additional, input, cipher,
Vanger 0:b86d15c6ba29 5587 sz, tag)) != 0)
Vanger 0:b86d15c6ba29 5588 return ret;
Vanger 0:b86d15c6ba29 5589 }
Vanger 0:b86d15c6ba29 5590 else {
Vanger 0:b86d15c6ba29 5591 if ((ret = Poly1305Tag(ssl, additional, input, cipher,
Vanger 0:b86d15c6ba29 5592 sz, tag)) != 0)
Vanger 0:b86d15c6ba29 5593 return ret;
Vanger 0:b86d15c6ba29 5594 }
Vanger 0:b86d15c6ba29 5595 #endif
Vanger 0:b86d15c6ba29 5596
Vanger 0:b86d15c6ba29 5597 /* check mac sent along with packet */
Vanger 0:b86d15c6ba29 5598 ret = 0;
Vanger 0:b86d15c6ba29 5599 for (i = 0; i < ssl->specs.aead_mac_size; i++) {
Vanger 0:b86d15c6ba29 5600 if ((input + sz - ssl->specs.aead_mac_size)[i] != tag[i])
Vanger 0:b86d15c6ba29 5601 ret = 1;
Vanger 0:b86d15c6ba29 5602 }
Vanger 0:b86d15c6ba29 5603
Vanger 0:b86d15c6ba29 5604 if (ret == 1) {
Vanger 0:b86d15c6ba29 5605 CYASSL_MSG("Mac did not match");
Vanger 0:b86d15c6ba29 5606 SendAlert(ssl, alert_fatal, bad_record_mac);
Vanger 0:b86d15c6ba29 5607 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
Vanger 0:b86d15c6ba29 5608 return VERIFY_MAC_ERROR;
Vanger 0:b86d15c6ba29 5609 }
Vanger 0:b86d15c6ba29 5610
Vanger 0:b86d15c6ba29 5611 /* if mac was good decrypt message */
Vanger 0:b86d15c6ba29 5612 if ((ret = Chacha_Process(ssl->decrypt.chacha, plain, input,
Vanger 0:b86d15c6ba29 5613 sz - ssl->specs.aead_mac_size)) != 0)
Vanger 0:b86d15c6ba29 5614 return ret;
Vanger 0:b86d15c6ba29 5615
Vanger 0:b86d15c6ba29 5616 #ifdef CHACHA_AEAD_TEST
Vanger 0:b86d15c6ba29 5617 printf("plain after decrypt :\n");
Vanger 0:b86d15c6ba29 5618 for (i = 0; i < sz; i++) {
Vanger 0:b86d15c6ba29 5619 printf("%02x", plain[i]);
Vanger 0:b86d15c6ba29 5620 if ((i + 1) % 16 == 0)
Vanger 0:b86d15c6ba29 5621 printf("\n");
Vanger 0:b86d15c6ba29 5622 }
Vanger 0:b86d15c6ba29 5623 printf("\n");
Vanger 0:b86d15c6ba29 5624 #endif
Vanger 0:b86d15c6ba29 5625
Vanger 0:b86d15c6ba29 5626 return ret;
Vanger 0:b86d15c6ba29 5627 }
Vanger 0:b86d15c6ba29 5628 #endif /* HAVE_CHACHA */
Vanger 0:b86d15c6ba29 5629 #endif
Vanger 0:b86d15c6ba29 5630
Vanger 0:b86d15c6ba29 5631
Vanger 0:b86d15c6ba29 5632 static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word16 sz)
Vanger 0:b86d15c6ba29 5633 {
Vanger 0:b86d15c6ba29 5634 (void)out;
Vanger 0:b86d15c6ba29 5635 (void)input;
Vanger 0:b86d15c6ba29 5636 (void)sz;
Vanger 0:b86d15c6ba29 5637
Vanger 0:b86d15c6ba29 5638 if (ssl->encrypt.setup == 0) {
Vanger 0:b86d15c6ba29 5639 CYASSL_MSG("Encrypt ciphers not setup");
Vanger 0:b86d15c6ba29 5640 return ENCRYPT_ERROR;
Vanger 0:b86d15c6ba29 5641 }
Vanger 0:b86d15c6ba29 5642
Vanger 0:b86d15c6ba29 5643 #ifdef HAVE_FUZZER
Vanger 0:b86d15c6ba29 5644 if (ssl->fuzzerCb)
Vanger 0:b86d15c6ba29 5645 ssl->fuzzerCb(ssl, input, sz, FUZZ_ENCRYPT, ssl->fuzzerCtx);
Vanger 0:b86d15c6ba29 5646 #endif
Vanger 0:b86d15c6ba29 5647
Vanger 0:b86d15c6ba29 5648 switch (ssl->specs.bulk_cipher_algorithm) {
Vanger 0:b86d15c6ba29 5649 #ifdef BUILD_ARC4
Vanger 0:b86d15c6ba29 5650 case cyassl_rc4:
Vanger 0:b86d15c6ba29 5651 Arc4Process(ssl->encrypt.arc4, out, input, sz);
Vanger 0:b86d15c6ba29 5652 break;
Vanger 0:b86d15c6ba29 5653 #endif
Vanger 0:b86d15c6ba29 5654
Vanger 0:b86d15c6ba29 5655 #ifdef BUILD_DES3
Vanger 0:b86d15c6ba29 5656 case cyassl_triple_des:
Vanger 0:b86d15c6ba29 5657 return Des3_CbcEncrypt(ssl->encrypt.des3, out, input, sz);
Vanger 0:b86d15c6ba29 5658 #endif
Vanger 0:b86d15c6ba29 5659
Vanger 0:b86d15c6ba29 5660 #ifdef BUILD_AES
Vanger 0:b86d15c6ba29 5661 case cyassl_aes:
Vanger 0:b86d15c6ba29 5662 return AesCbcEncrypt(ssl->encrypt.aes, out, input, sz);
Vanger 0:b86d15c6ba29 5663 #endif
Vanger 0:b86d15c6ba29 5664
Vanger 0:b86d15c6ba29 5665 #ifdef BUILD_AESGCM
Vanger 0:b86d15c6ba29 5666 case cyassl_aes_gcm:
Vanger 0:b86d15c6ba29 5667 {
Vanger 0:b86d15c6ba29 5668 int gcmRet;
Vanger 0:b86d15c6ba29 5669 byte additional[AEAD_AUTH_DATA_SZ];
Vanger 0:b86d15c6ba29 5670 byte nonce[AEAD_NONCE_SZ];
Vanger 0:b86d15c6ba29 5671 const byte* additionalSrc = input - 5;
Vanger 0:b86d15c6ba29 5672
Vanger 0:b86d15c6ba29 5673 XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
Vanger 0:b86d15c6ba29 5674
Vanger 0:b86d15c6ba29 5675 /* sequence number field is 64-bits, we only use 32-bits */
Vanger 0:b86d15c6ba29 5676 c32toa(GetSEQIncrement(ssl, 0),
Vanger 0:b86d15c6ba29 5677 additional + AEAD_SEQ_OFFSET);
Vanger 0:b86d15c6ba29 5678
Vanger 0:b86d15c6ba29 5679 /* Store the type, version. Unfortunately, they are in
Vanger 0:b86d15c6ba29 5680 * the input buffer ahead of the plaintext. */
Vanger 0:b86d15c6ba29 5681 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 5682 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 5683 c16toa(ssl->keys.dtls_epoch, additional);
Vanger 0:b86d15c6ba29 5684 additionalSrc -= DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 5685 }
Vanger 0:b86d15c6ba29 5686 #endif
Vanger 0:b86d15c6ba29 5687 XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
Vanger 0:b86d15c6ba29 5688
Vanger 0:b86d15c6ba29 5689 /* Store the length of the plain text minus the explicit
Vanger 0:b86d15c6ba29 5690 * IV length minus the authentication tag size. */
Vanger 0:b86d15c6ba29 5691 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5692 additional + AEAD_LEN_OFFSET);
Vanger 0:b86d15c6ba29 5693 XMEMCPY(nonce,
Vanger 0:b86d15c6ba29 5694 ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ);
Vanger 0:b86d15c6ba29 5695 XMEMCPY(nonce + AEAD_IMP_IV_SZ,
Vanger 0:b86d15c6ba29 5696 ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
Vanger 0:b86d15c6ba29 5697 gcmRet = AesGcmEncrypt(ssl->encrypt.aes,
Vanger 0:b86d15c6ba29 5698 out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ,
Vanger 0:b86d15c6ba29 5699 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5700 nonce, AEAD_NONCE_SZ,
Vanger 0:b86d15c6ba29 5701 out + sz - ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5702 ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5703 additional, AEAD_AUTH_DATA_SZ);
Vanger 0:b86d15c6ba29 5704 if (gcmRet == 0)
Vanger 0:b86d15c6ba29 5705 AeadIncrementExpIV(ssl);
Vanger 0:b86d15c6ba29 5706 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
Vanger 0:b86d15c6ba29 5707 return gcmRet;
Vanger 0:b86d15c6ba29 5708 }
Vanger 0:b86d15c6ba29 5709 break;
Vanger 0:b86d15c6ba29 5710 #endif
Vanger 0:b86d15c6ba29 5711
Vanger 0:b86d15c6ba29 5712 #ifdef HAVE_AESCCM
Vanger 0:b86d15c6ba29 5713 case cyassl_aes_ccm:
Vanger 0:b86d15c6ba29 5714 {
Vanger 0:b86d15c6ba29 5715 byte additional[AEAD_AUTH_DATA_SZ];
Vanger 0:b86d15c6ba29 5716 byte nonce[AEAD_NONCE_SZ];
Vanger 0:b86d15c6ba29 5717 const byte* additionalSrc = input - 5;
Vanger 0:b86d15c6ba29 5718
Vanger 0:b86d15c6ba29 5719 XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
Vanger 0:b86d15c6ba29 5720
Vanger 0:b86d15c6ba29 5721 /* sequence number field is 64-bits, we only use 32-bits */
Vanger 0:b86d15c6ba29 5722 c32toa(GetSEQIncrement(ssl, 0),
Vanger 0:b86d15c6ba29 5723 additional + AEAD_SEQ_OFFSET);
Vanger 0:b86d15c6ba29 5724
Vanger 0:b86d15c6ba29 5725 /* Store the type, version. Unfortunately, they are in
Vanger 0:b86d15c6ba29 5726 * the input buffer ahead of the plaintext. */
Vanger 0:b86d15c6ba29 5727 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 5728 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 5729 c16toa(ssl->keys.dtls_epoch, additional);
Vanger 0:b86d15c6ba29 5730 additionalSrc -= DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 5731 }
Vanger 0:b86d15c6ba29 5732 #endif
Vanger 0:b86d15c6ba29 5733 XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
Vanger 0:b86d15c6ba29 5734
Vanger 0:b86d15c6ba29 5735 /* Store the length of the plain text minus the explicit
Vanger 0:b86d15c6ba29 5736 * IV length minus the authentication tag size. */
Vanger 0:b86d15c6ba29 5737 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5738 additional + AEAD_LEN_OFFSET);
Vanger 0:b86d15c6ba29 5739 XMEMCPY(nonce,
Vanger 0:b86d15c6ba29 5740 ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ);
Vanger 0:b86d15c6ba29 5741 XMEMCPY(nonce + AEAD_IMP_IV_SZ,
Vanger 0:b86d15c6ba29 5742 ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
Vanger 0:b86d15c6ba29 5743 AesCcmEncrypt(ssl->encrypt.aes,
Vanger 0:b86d15c6ba29 5744 out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ,
Vanger 0:b86d15c6ba29 5745 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5746 nonce, AEAD_NONCE_SZ,
Vanger 0:b86d15c6ba29 5747 out + sz - ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5748 ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5749 additional, AEAD_AUTH_DATA_SZ);
Vanger 0:b86d15c6ba29 5750 AeadIncrementExpIV(ssl);
Vanger 0:b86d15c6ba29 5751 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
Vanger 0:b86d15c6ba29 5752 }
Vanger 0:b86d15c6ba29 5753 break;
Vanger 0:b86d15c6ba29 5754 #endif
Vanger 0:b86d15c6ba29 5755
Vanger 0:b86d15c6ba29 5756 #ifdef HAVE_CAMELLIA
Vanger 0:b86d15c6ba29 5757 case cyassl_camellia:
Vanger 0:b86d15c6ba29 5758 CamelliaCbcEncrypt(ssl->encrypt.cam, out, input, sz);
Vanger 0:b86d15c6ba29 5759 break;
Vanger 0:b86d15c6ba29 5760 #endif
Vanger 0:b86d15c6ba29 5761
Vanger 0:b86d15c6ba29 5762 #ifdef HAVE_HC128
Vanger 0:b86d15c6ba29 5763 case cyassl_hc128:
Vanger 0:b86d15c6ba29 5764 return Hc128_Process(ssl->encrypt.hc128, out, input, sz);
Vanger 0:b86d15c6ba29 5765 #endif
Vanger 0:b86d15c6ba29 5766
Vanger 0:b86d15c6ba29 5767 #ifdef BUILD_RABBIT
Vanger 0:b86d15c6ba29 5768 case cyassl_rabbit:
Vanger 0:b86d15c6ba29 5769 return RabbitProcess(ssl->encrypt.rabbit, out, input, sz);
Vanger 0:b86d15c6ba29 5770 #endif
Vanger 0:b86d15c6ba29 5771
Vanger 0:b86d15c6ba29 5772 #ifdef HAVE_CHACHA
Vanger 0:b86d15c6ba29 5773 case cyassl_chacha:
Vanger 0:b86d15c6ba29 5774 return ChachaAEADEncrypt(ssl, out, input, sz);
Vanger 0:b86d15c6ba29 5775 #endif
Vanger 0:b86d15c6ba29 5776
Vanger 0:b86d15c6ba29 5777 #ifdef HAVE_NULL_CIPHER
Vanger 0:b86d15c6ba29 5778 case cyassl_cipher_null:
Vanger 0:b86d15c6ba29 5779 if (input != out) {
Vanger 0:b86d15c6ba29 5780 XMEMMOVE(out, input, sz);
Vanger 0:b86d15c6ba29 5781 }
Vanger 0:b86d15c6ba29 5782 break;
Vanger 0:b86d15c6ba29 5783 #endif
Vanger 0:b86d15c6ba29 5784
Vanger 0:b86d15c6ba29 5785 default:
Vanger 0:b86d15c6ba29 5786 CYASSL_MSG("CyaSSL Encrypt programming error");
Vanger 0:b86d15c6ba29 5787 return ENCRYPT_ERROR;
Vanger 0:b86d15c6ba29 5788 }
Vanger 0:b86d15c6ba29 5789
Vanger 0:b86d15c6ba29 5790 return 0;
Vanger 0:b86d15c6ba29 5791 }
Vanger 0:b86d15c6ba29 5792
Vanger 0:b86d15c6ba29 5793
Vanger 0:b86d15c6ba29 5794
Vanger 0:b86d15c6ba29 5795 static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input,
Vanger 0:b86d15c6ba29 5796 word16 sz)
Vanger 0:b86d15c6ba29 5797 {
Vanger 0:b86d15c6ba29 5798 (void)plain;
Vanger 0:b86d15c6ba29 5799 (void)input;
Vanger 0:b86d15c6ba29 5800 (void)sz;
Vanger 0:b86d15c6ba29 5801
Vanger 0:b86d15c6ba29 5802 if (ssl->decrypt.setup == 0) {
Vanger 0:b86d15c6ba29 5803 CYASSL_MSG("Decrypt ciphers not setup");
Vanger 0:b86d15c6ba29 5804 return DECRYPT_ERROR;
Vanger 0:b86d15c6ba29 5805 }
Vanger 0:b86d15c6ba29 5806
Vanger 0:b86d15c6ba29 5807 switch (ssl->specs.bulk_cipher_algorithm) {
Vanger 0:b86d15c6ba29 5808 #ifdef BUILD_ARC4
Vanger 0:b86d15c6ba29 5809 case cyassl_rc4:
Vanger 0:b86d15c6ba29 5810 Arc4Process(ssl->decrypt.arc4, plain, input, sz);
Vanger 0:b86d15c6ba29 5811 break;
Vanger 0:b86d15c6ba29 5812 #endif
Vanger 0:b86d15c6ba29 5813
Vanger 0:b86d15c6ba29 5814 #ifdef BUILD_DES3
Vanger 0:b86d15c6ba29 5815 case cyassl_triple_des:
Vanger 0:b86d15c6ba29 5816 return Des3_CbcDecrypt(ssl->decrypt.des3, plain, input, sz);
Vanger 0:b86d15c6ba29 5817 #endif
Vanger 0:b86d15c6ba29 5818
Vanger 0:b86d15c6ba29 5819 #ifdef BUILD_AES
Vanger 0:b86d15c6ba29 5820 case cyassl_aes:
Vanger 0:b86d15c6ba29 5821 return AesCbcDecrypt(ssl->decrypt.aes, plain, input, sz);
Vanger 0:b86d15c6ba29 5822 #endif
Vanger 0:b86d15c6ba29 5823
Vanger 0:b86d15c6ba29 5824 #ifdef BUILD_AESGCM
Vanger 0:b86d15c6ba29 5825 case cyassl_aes_gcm:
Vanger 0:b86d15c6ba29 5826 {
Vanger 0:b86d15c6ba29 5827 byte additional[AEAD_AUTH_DATA_SZ];
Vanger 0:b86d15c6ba29 5828 byte nonce[AEAD_NONCE_SZ];
Vanger 0:b86d15c6ba29 5829
Vanger 0:b86d15c6ba29 5830 XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
Vanger 0:b86d15c6ba29 5831
Vanger 0:b86d15c6ba29 5832 /* sequence number field is 64-bits, we only use 32-bits */
Vanger 0:b86d15c6ba29 5833 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
Vanger 0:b86d15c6ba29 5834
Vanger 0:b86d15c6ba29 5835 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 5836 if (ssl->options.dtls)
Vanger 0:b86d15c6ba29 5837 c16toa(ssl->keys.dtls_state.curEpoch, additional);
Vanger 0:b86d15c6ba29 5838 #endif
Vanger 0:b86d15c6ba29 5839
Vanger 0:b86d15c6ba29 5840 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
Vanger 0:b86d15c6ba29 5841 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
Vanger 0:b86d15c6ba29 5842 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
Vanger 0:b86d15c6ba29 5843
Vanger 0:b86d15c6ba29 5844 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5845 additional + AEAD_LEN_OFFSET);
Vanger 0:b86d15c6ba29 5846 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
Vanger 0:b86d15c6ba29 5847 XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
Vanger 0:b86d15c6ba29 5848 if (AesGcmDecrypt(ssl->decrypt.aes,
Vanger 0:b86d15c6ba29 5849 plain + AEAD_EXP_IV_SZ,
Vanger 0:b86d15c6ba29 5850 input + AEAD_EXP_IV_SZ,
Vanger 0:b86d15c6ba29 5851 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5852 nonce, AEAD_NONCE_SZ,
Vanger 0:b86d15c6ba29 5853 input + sz - ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5854 ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5855 additional, AEAD_AUTH_DATA_SZ) < 0) {
Vanger 0:b86d15c6ba29 5856 SendAlert(ssl, alert_fatal, bad_record_mac);
Vanger 0:b86d15c6ba29 5857 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
Vanger 0:b86d15c6ba29 5858 return VERIFY_MAC_ERROR;
Vanger 0:b86d15c6ba29 5859 }
Vanger 0:b86d15c6ba29 5860 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
Vanger 0:b86d15c6ba29 5861 }
Vanger 0:b86d15c6ba29 5862 break;
Vanger 0:b86d15c6ba29 5863 #endif
Vanger 0:b86d15c6ba29 5864
Vanger 0:b86d15c6ba29 5865 #ifdef HAVE_AESCCM
Vanger 0:b86d15c6ba29 5866 case cyassl_aes_ccm:
Vanger 0:b86d15c6ba29 5867 {
Vanger 0:b86d15c6ba29 5868 byte additional[AEAD_AUTH_DATA_SZ];
Vanger 0:b86d15c6ba29 5869 byte nonce[AEAD_NONCE_SZ];
Vanger 0:b86d15c6ba29 5870
Vanger 0:b86d15c6ba29 5871 XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
Vanger 0:b86d15c6ba29 5872
Vanger 0:b86d15c6ba29 5873 /* sequence number field is 64-bits, we only use 32-bits */
Vanger 0:b86d15c6ba29 5874 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
Vanger 0:b86d15c6ba29 5875
Vanger 0:b86d15c6ba29 5876 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 5877 if (ssl->options.dtls)
Vanger 0:b86d15c6ba29 5878 c16toa(ssl->keys.dtls_state.curEpoch, additional);
Vanger 0:b86d15c6ba29 5879 #endif
Vanger 0:b86d15c6ba29 5880
Vanger 0:b86d15c6ba29 5881 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
Vanger 0:b86d15c6ba29 5882 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
Vanger 0:b86d15c6ba29 5883 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
Vanger 0:b86d15c6ba29 5884
Vanger 0:b86d15c6ba29 5885 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5886 additional + AEAD_LEN_OFFSET);
Vanger 0:b86d15c6ba29 5887 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
Vanger 0:b86d15c6ba29 5888 XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
Vanger 0:b86d15c6ba29 5889 if (AesCcmDecrypt(ssl->decrypt.aes,
Vanger 0:b86d15c6ba29 5890 plain + AEAD_EXP_IV_SZ,
Vanger 0:b86d15c6ba29 5891 input + AEAD_EXP_IV_SZ,
Vanger 0:b86d15c6ba29 5892 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5893 nonce, AEAD_NONCE_SZ,
Vanger 0:b86d15c6ba29 5894 input + sz - ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5895 ssl->specs.aead_mac_size,
Vanger 0:b86d15c6ba29 5896 additional, AEAD_AUTH_DATA_SZ) < 0) {
Vanger 0:b86d15c6ba29 5897 SendAlert(ssl, alert_fatal, bad_record_mac);
Vanger 0:b86d15c6ba29 5898 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
Vanger 0:b86d15c6ba29 5899 return VERIFY_MAC_ERROR;
Vanger 0:b86d15c6ba29 5900 }
Vanger 0:b86d15c6ba29 5901 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
Vanger 0:b86d15c6ba29 5902 }
Vanger 0:b86d15c6ba29 5903 break;
Vanger 0:b86d15c6ba29 5904 #endif
Vanger 0:b86d15c6ba29 5905
Vanger 0:b86d15c6ba29 5906 #ifdef HAVE_CAMELLIA
Vanger 0:b86d15c6ba29 5907 case cyassl_camellia:
Vanger 0:b86d15c6ba29 5908 CamelliaCbcDecrypt(ssl->decrypt.cam, plain, input, sz);
Vanger 0:b86d15c6ba29 5909 break;
Vanger 0:b86d15c6ba29 5910 #endif
Vanger 0:b86d15c6ba29 5911
Vanger 0:b86d15c6ba29 5912 #ifdef HAVE_HC128
Vanger 0:b86d15c6ba29 5913 case cyassl_hc128:
Vanger 0:b86d15c6ba29 5914 return Hc128_Process(ssl->decrypt.hc128, plain, input, sz);
Vanger 0:b86d15c6ba29 5915 #endif
Vanger 0:b86d15c6ba29 5916
Vanger 0:b86d15c6ba29 5917 #ifdef BUILD_RABBIT
Vanger 0:b86d15c6ba29 5918 case cyassl_rabbit:
Vanger 0:b86d15c6ba29 5919 return RabbitProcess(ssl->decrypt.rabbit, plain, input, sz);
Vanger 0:b86d15c6ba29 5920 #endif
Vanger 0:b86d15c6ba29 5921
Vanger 0:b86d15c6ba29 5922 #ifdef HAVE_CHACHA
Vanger 0:b86d15c6ba29 5923 case cyassl_chacha:
Vanger 0:b86d15c6ba29 5924 return ChachaAEADDecrypt(ssl, plain, input, sz);
Vanger 0:b86d15c6ba29 5925 #endif
Vanger 0:b86d15c6ba29 5926
Vanger 0:b86d15c6ba29 5927 #ifdef HAVE_NULL_CIPHER
Vanger 0:b86d15c6ba29 5928 case cyassl_cipher_null:
Vanger 0:b86d15c6ba29 5929 if (input != plain) {
Vanger 0:b86d15c6ba29 5930 XMEMMOVE(plain, input, sz);
Vanger 0:b86d15c6ba29 5931 }
Vanger 0:b86d15c6ba29 5932 break;
Vanger 0:b86d15c6ba29 5933 #endif
Vanger 0:b86d15c6ba29 5934
Vanger 0:b86d15c6ba29 5935 default:
Vanger 0:b86d15c6ba29 5936 CYASSL_MSG("CyaSSL Decrypt programming error");
Vanger 0:b86d15c6ba29 5937 return DECRYPT_ERROR;
Vanger 0:b86d15c6ba29 5938 }
Vanger 0:b86d15c6ba29 5939 return 0;
Vanger 0:b86d15c6ba29 5940 }
Vanger 0:b86d15c6ba29 5941
Vanger 0:b86d15c6ba29 5942
Vanger 0:b86d15c6ba29 5943 /* check cipher text size for sanity */
Vanger 0:b86d15c6ba29 5944 static int SanityCheckCipherText(CYASSL* ssl, word32 encryptSz)
Vanger 0:b86d15c6ba29 5945 {
Vanger 0:b86d15c6ba29 5946 #ifdef HAVE_TRUNCATED_HMAC
Vanger 0:b86d15c6ba29 5947 word32 minLength = ssl->truncated_hmac ? TRUNCATED_HMAC_SZ
Vanger 0:b86d15c6ba29 5948 : ssl->specs.hash_size;
Vanger 0:b86d15c6ba29 5949 #else
Vanger 0:b86d15c6ba29 5950 word32 minLength = ssl->specs.hash_size; /* covers stream */
Vanger 0:b86d15c6ba29 5951 #endif
Vanger 0:b86d15c6ba29 5952
Vanger 0:b86d15c6ba29 5953 if (ssl->specs.cipher_type == block) {
Vanger 0:b86d15c6ba29 5954 if (encryptSz % ssl->specs.block_size) {
Vanger 0:b86d15c6ba29 5955 CYASSL_MSG("Block ciphertext not block size");
Vanger 0:b86d15c6ba29 5956 return SANITY_CIPHER_E;
Vanger 0:b86d15c6ba29 5957 }
Vanger 0:b86d15c6ba29 5958
Vanger 0:b86d15c6ba29 5959 minLength++; /* pad byte */
Vanger 0:b86d15c6ba29 5960
Vanger 0:b86d15c6ba29 5961 if (ssl->specs.block_size > minLength)
Vanger 0:b86d15c6ba29 5962 minLength = ssl->specs.block_size;
Vanger 0:b86d15c6ba29 5963
Vanger 0:b86d15c6ba29 5964 if (ssl->options.tls1_1)
Vanger 0:b86d15c6ba29 5965 minLength += ssl->specs.block_size; /* explicit IV */
Vanger 0:b86d15c6ba29 5966 }
Vanger 0:b86d15c6ba29 5967 else if (ssl->specs.cipher_type == aead) {
Vanger 0:b86d15c6ba29 5968 minLength = ssl->specs.aead_mac_size; /* authTag size */
Vanger 0:b86d15c6ba29 5969 if (ssl->specs.bulk_cipher_algorithm != cyassl_chacha)
Vanger 0:b86d15c6ba29 5970 minLength += AEAD_EXP_IV_SZ; /* explicit IV */
Vanger 0:b86d15c6ba29 5971 }
Vanger 0:b86d15c6ba29 5972
Vanger 0:b86d15c6ba29 5973 if (encryptSz < minLength) {
Vanger 0:b86d15c6ba29 5974 CYASSL_MSG("Ciphertext not minimum size");
Vanger 0:b86d15c6ba29 5975 return SANITY_CIPHER_E;
Vanger 0:b86d15c6ba29 5976 }
Vanger 0:b86d15c6ba29 5977
Vanger 0:b86d15c6ba29 5978 return 0;
Vanger 0:b86d15c6ba29 5979 }
Vanger 0:b86d15c6ba29 5980
Vanger 0:b86d15c6ba29 5981
Vanger 0:b86d15c6ba29 5982 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 5983
Vanger 0:b86d15c6ba29 5984 static INLINE void Md5Rounds(int rounds, const byte* data, int sz)
Vanger 0:b86d15c6ba29 5985 {
Vanger 0:b86d15c6ba29 5986 Md5 md5;
Vanger 0:b86d15c6ba29 5987 int i;
Vanger 0:b86d15c6ba29 5988
Vanger 0:b86d15c6ba29 5989 InitMd5(&md5);
Vanger 0:b86d15c6ba29 5990
Vanger 0:b86d15c6ba29 5991 for (i = 0; i < rounds; i++)
Vanger 0:b86d15c6ba29 5992 Md5Update(&md5, data, sz);
Vanger 0:b86d15c6ba29 5993 }
Vanger 0:b86d15c6ba29 5994
Vanger 0:b86d15c6ba29 5995
Vanger 0:b86d15c6ba29 5996
Vanger 0:b86d15c6ba29 5997 /* do a dummy sha round */
Vanger 0:b86d15c6ba29 5998 static INLINE void ShaRounds(int rounds, const byte* data, int sz)
Vanger 0:b86d15c6ba29 5999 {
Vanger 0:b86d15c6ba29 6000 Sha sha;
Vanger 0:b86d15c6ba29 6001 int i;
Vanger 0:b86d15c6ba29 6002
Vanger 0:b86d15c6ba29 6003 InitSha(&sha); /* no error check on purpose, dummy round */
Vanger 0:b86d15c6ba29 6004
Vanger 0:b86d15c6ba29 6005 for (i = 0; i < rounds; i++)
Vanger 0:b86d15c6ba29 6006 ShaUpdate(&sha, data, sz);
Vanger 0:b86d15c6ba29 6007 }
Vanger 0:b86d15c6ba29 6008 #endif
Vanger 0:b86d15c6ba29 6009
Vanger 0:b86d15c6ba29 6010
Vanger 0:b86d15c6ba29 6011 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 6012
Vanger 0:b86d15c6ba29 6013 static INLINE void Sha256Rounds(int rounds, const byte* data, int sz)
Vanger 0:b86d15c6ba29 6014 {
Vanger 0:b86d15c6ba29 6015 Sha256 sha256;
Vanger 0:b86d15c6ba29 6016 int i;
Vanger 0:b86d15c6ba29 6017
Vanger 0:b86d15c6ba29 6018 InitSha256(&sha256); /* no error check on purpose, dummy round */
Vanger 0:b86d15c6ba29 6019
Vanger 0:b86d15c6ba29 6020 for (i = 0; i < rounds; i++) {
Vanger 0:b86d15c6ba29 6021 Sha256Update(&sha256, data, sz);
Vanger 0:b86d15c6ba29 6022 /* no error check on purpose, dummy round */
Vanger 0:b86d15c6ba29 6023 }
Vanger 0:b86d15c6ba29 6024
Vanger 0:b86d15c6ba29 6025 }
Vanger 0:b86d15c6ba29 6026
Vanger 0:b86d15c6ba29 6027 #endif
Vanger 0:b86d15c6ba29 6028
Vanger 0:b86d15c6ba29 6029
Vanger 0:b86d15c6ba29 6030 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 6031
Vanger 0:b86d15c6ba29 6032 static INLINE void Sha384Rounds(int rounds, const byte* data, int sz)
Vanger 0:b86d15c6ba29 6033 {
Vanger 0:b86d15c6ba29 6034 Sha384 sha384;
Vanger 0:b86d15c6ba29 6035 int i;
Vanger 0:b86d15c6ba29 6036
Vanger 0:b86d15c6ba29 6037 InitSha384(&sha384); /* no error check on purpose, dummy round */
Vanger 0:b86d15c6ba29 6038
Vanger 0:b86d15c6ba29 6039 for (i = 0; i < rounds; i++) {
Vanger 0:b86d15c6ba29 6040 Sha384Update(&sha384, data, sz);
Vanger 0:b86d15c6ba29 6041 /* no error check on purpose, dummy round */
Vanger 0:b86d15c6ba29 6042 }
Vanger 0:b86d15c6ba29 6043 }
Vanger 0:b86d15c6ba29 6044
Vanger 0:b86d15c6ba29 6045 #endif
Vanger 0:b86d15c6ba29 6046
Vanger 0:b86d15c6ba29 6047
Vanger 0:b86d15c6ba29 6048 #ifdef CYASSL_SHA512
Vanger 0:b86d15c6ba29 6049
Vanger 0:b86d15c6ba29 6050 static INLINE void Sha512Rounds(int rounds, const byte* data, int sz)
Vanger 0:b86d15c6ba29 6051 {
Vanger 0:b86d15c6ba29 6052 Sha512 sha512;
Vanger 0:b86d15c6ba29 6053 int i;
Vanger 0:b86d15c6ba29 6054
Vanger 0:b86d15c6ba29 6055 InitSha512(&sha512); /* no error check on purpose, dummy round */
Vanger 0:b86d15c6ba29 6056
Vanger 0:b86d15c6ba29 6057 for (i = 0; i < rounds; i++) {
Vanger 0:b86d15c6ba29 6058 Sha512Update(&sha512, data, sz);
Vanger 0:b86d15c6ba29 6059 /* no error check on purpose, dummy round */
Vanger 0:b86d15c6ba29 6060 }
Vanger 0:b86d15c6ba29 6061 }
Vanger 0:b86d15c6ba29 6062
Vanger 0:b86d15c6ba29 6063 #endif
Vanger 0:b86d15c6ba29 6064
Vanger 0:b86d15c6ba29 6065
Vanger 0:b86d15c6ba29 6066 #ifdef CYASSL_RIPEMD
Vanger 0:b86d15c6ba29 6067
Vanger 0:b86d15c6ba29 6068 static INLINE void RmdRounds(int rounds, const byte* data, int sz)
Vanger 0:b86d15c6ba29 6069 {
Vanger 0:b86d15c6ba29 6070 RipeMd ripemd;
Vanger 0:b86d15c6ba29 6071 int i;
Vanger 0:b86d15c6ba29 6072
Vanger 0:b86d15c6ba29 6073 InitRipeMd(&ripemd);
Vanger 0:b86d15c6ba29 6074
Vanger 0:b86d15c6ba29 6075 for (i = 0; i < rounds; i++)
Vanger 0:b86d15c6ba29 6076 RipeMdUpdate(&ripemd, data, sz);
Vanger 0:b86d15c6ba29 6077 }
Vanger 0:b86d15c6ba29 6078
Vanger 0:b86d15c6ba29 6079 #endif
Vanger 0:b86d15c6ba29 6080
Vanger 0:b86d15c6ba29 6081
Vanger 0:b86d15c6ba29 6082 /* Do dummy rounds */
Vanger 0:b86d15c6ba29 6083 static INLINE void DoRounds(int type, int rounds, const byte* data, int sz)
Vanger 0:b86d15c6ba29 6084 {
Vanger 0:b86d15c6ba29 6085 switch (type) {
Vanger 0:b86d15c6ba29 6086
Vanger 0:b86d15c6ba29 6087 case no_mac :
Vanger 0:b86d15c6ba29 6088 break;
Vanger 0:b86d15c6ba29 6089
Vanger 0:b86d15c6ba29 6090 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 6091 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 6092 case md5_mac :
Vanger 0:b86d15c6ba29 6093 Md5Rounds(rounds, data, sz);
Vanger 0:b86d15c6ba29 6094 break;
Vanger 0:b86d15c6ba29 6095 #endif
Vanger 0:b86d15c6ba29 6096
Vanger 0:b86d15c6ba29 6097 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 6098 case sha_mac :
Vanger 0:b86d15c6ba29 6099 ShaRounds(rounds, data, sz);
Vanger 0:b86d15c6ba29 6100 break;
Vanger 0:b86d15c6ba29 6101 #endif
Vanger 0:b86d15c6ba29 6102 #endif
Vanger 0:b86d15c6ba29 6103
Vanger 0:b86d15c6ba29 6104 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 6105 case sha256_mac :
Vanger 0:b86d15c6ba29 6106 Sha256Rounds(rounds, data, sz);
Vanger 0:b86d15c6ba29 6107 break;
Vanger 0:b86d15c6ba29 6108 #endif
Vanger 0:b86d15c6ba29 6109
Vanger 0:b86d15c6ba29 6110 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 6111 case sha384_mac :
Vanger 0:b86d15c6ba29 6112 Sha384Rounds(rounds, data, sz);
Vanger 0:b86d15c6ba29 6113 break;
Vanger 0:b86d15c6ba29 6114 #endif
Vanger 0:b86d15c6ba29 6115
Vanger 0:b86d15c6ba29 6116 #ifdef CYASSL_SHA512
Vanger 0:b86d15c6ba29 6117 case sha512_mac :
Vanger 0:b86d15c6ba29 6118 Sha512Rounds(rounds, data, sz);
Vanger 0:b86d15c6ba29 6119 break;
Vanger 0:b86d15c6ba29 6120 #endif
Vanger 0:b86d15c6ba29 6121
Vanger 0:b86d15c6ba29 6122 #ifdef CYASSL_RIPEMD
Vanger 0:b86d15c6ba29 6123 case rmd_mac :
Vanger 0:b86d15c6ba29 6124 RmdRounds(rounds, data, sz);
Vanger 0:b86d15c6ba29 6125 break;
Vanger 0:b86d15c6ba29 6126 #endif
Vanger 0:b86d15c6ba29 6127
Vanger 0:b86d15c6ba29 6128 default:
Vanger 0:b86d15c6ba29 6129 CYASSL_MSG("Bad round type");
Vanger 0:b86d15c6ba29 6130 break;
Vanger 0:b86d15c6ba29 6131 }
Vanger 0:b86d15c6ba29 6132 }
Vanger 0:b86d15c6ba29 6133
Vanger 0:b86d15c6ba29 6134
Vanger 0:b86d15c6ba29 6135 /* do number of compression rounds on dummy data */
Vanger 0:b86d15c6ba29 6136 static INLINE void CompressRounds(CYASSL* ssl, int rounds, const byte* dummy)
Vanger 0:b86d15c6ba29 6137 {
Vanger 0:b86d15c6ba29 6138 if (rounds)
Vanger 0:b86d15c6ba29 6139 DoRounds(ssl->specs.mac_algorithm, rounds, dummy, COMPRESS_LOWER);
Vanger 0:b86d15c6ba29 6140 }
Vanger 0:b86d15c6ba29 6141
Vanger 0:b86d15c6ba29 6142
Vanger 0:b86d15c6ba29 6143 /* check all length bytes for equality, return 0 on success */
Vanger 0:b86d15c6ba29 6144 static int ConstantCompare(const byte* a, const byte* b, int length)
Vanger 0:b86d15c6ba29 6145 {
Vanger 0:b86d15c6ba29 6146 int i;
Vanger 0:b86d15c6ba29 6147 int good = 0;
Vanger 0:b86d15c6ba29 6148 int bad = 0;
Vanger 0:b86d15c6ba29 6149
Vanger 0:b86d15c6ba29 6150 for (i = 0; i < length; i++) {
Vanger 0:b86d15c6ba29 6151 if (a[i] == b[i])
Vanger 0:b86d15c6ba29 6152 good++;
Vanger 0:b86d15c6ba29 6153 else
Vanger 0:b86d15c6ba29 6154 bad++;
Vanger 0:b86d15c6ba29 6155 }
Vanger 0:b86d15c6ba29 6156
Vanger 0:b86d15c6ba29 6157 if (good == length)
Vanger 0:b86d15c6ba29 6158 return 0;
Vanger 0:b86d15c6ba29 6159 else
Vanger 0:b86d15c6ba29 6160 return 0 - bad; /* compare failed */
Vanger 0:b86d15c6ba29 6161 }
Vanger 0:b86d15c6ba29 6162
Vanger 0:b86d15c6ba29 6163
Vanger 0:b86d15c6ba29 6164 /* check all length bytes for the pad value, return 0 on success */
Vanger 0:b86d15c6ba29 6165 static int PadCheck(const byte* input, byte pad, int length)
Vanger 0:b86d15c6ba29 6166 {
Vanger 0:b86d15c6ba29 6167 int i;
Vanger 0:b86d15c6ba29 6168 int good = 0;
Vanger 0:b86d15c6ba29 6169 int bad = 0;
Vanger 0:b86d15c6ba29 6170
Vanger 0:b86d15c6ba29 6171 for (i = 0; i < length; i++) {
Vanger 0:b86d15c6ba29 6172 if (input[i] == pad)
Vanger 0:b86d15c6ba29 6173 good++;
Vanger 0:b86d15c6ba29 6174 else
Vanger 0:b86d15c6ba29 6175 bad++;
Vanger 0:b86d15c6ba29 6176 }
Vanger 0:b86d15c6ba29 6177
Vanger 0:b86d15c6ba29 6178 if (good == length)
Vanger 0:b86d15c6ba29 6179 return 0;
Vanger 0:b86d15c6ba29 6180 else
Vanger 0:b86d15c6ba29 6181 return 0 - bad; /* pad check failed */
Vanger 0:b86d15c6ba29 6182 }
Vanger 0:b86d15c6ba29 6183
Vanger 0:b86d15c6ba29 6184
Vanger 0:b86d15c6ba29 6185 /* get compression extra rounds */
Vanger 0:b86d15c6ba29 6186 static INLINE int GetRounds(int pLen, int padLen, int t)
Vanger 0:b86d15c6ba29 6187 {
Vanger 0:b86d15c6ba29 6188 int roundL1 = 1; /* round up flags */
Vanger 0:b86d15c6ba29 6189 int roundL2 = 1;
Vanger 0:b86d15c6ba29 6190
Vanger 0:b86d15c6ba29 6191 int L1 = COMPRESS_CONSTANT + pLen - t;
Vanger 0:b86d15c6ba29 6192 int L2 = COMPRESS_CONSTANT + pLen - padLen - 1 - t;
Vanger 0:b86d15c6ba29 6193
Vanger 0:b86d15c6ba29 6194 L1 -= COMPRESS_UPPER;
Vanger 0:b86d15c6ba29 6195 L2 -= COMPRESS_UPPER;
Vanger 0:b86d15c6ba29 6196
Vanger 0:b86d15c6ba29 6197 if ( (L1 % COMPRESS_LOWER) == 0)
Vanger 0:b86d15c6ba29 6198 roundL1 = 0;
Vanger 0:b86d15c6ba29 6199 if ( (L2 % COMPRESS_LOWER) == 0)
Vanger 0:b86d15c6ba29 6200 roundL2 = 0;
Vanger 0:b86d15c6ba29 6201
Vanger 0:b86d15c6ba29 6202 L1 /= COMPRESS_LOWER;
Vanger 0:b86d15c6ba29 6203 L2 /= COMPRESS_LOWER;
Vanger 0:b86d15c6ba29 6204
Vanger 0:b86d15c6ba29 6205 L1 += roundL1;
Vanger 0:b86d15c6ba29 6206 L2 += roundL2;
Vanger 0:b86d15c6ba29 6207
Vanger 0:b86d15c6ba29 6208 return L1 - L2;
Vanger 0:b86d15c6ba29 6209 }
Vanger 0:b86d15c6ba29 6210
Vanger 0:b86d15c6ba29 6211
Vanger 0:b86d15c6ba29 6212 /* timing resistant pad/verify check, return 0 on success */
Vanger 0:b86d15c6ba29 6213 static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t,
Vanger 0:b86d15c6ba29 6214 int pLen, int content)
Vanger 0:b86d15c6ba29 6215 {
Vanger 0:b86d15c6ba29 6216 byte verify[MAX_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 6217 byte dummy[MAX_PAD_SIZE];
Vanger 0:b86d15c6ba29 6218 int ret = 0;
Vanger 0:b86d15c6ba29 6219
Vanger 0:b86d15c6ba29 6220 XMEMSET(dummy, 1, sizeof(dummy));
Vanger 0:b86d15c6ba29 6221
Vanger 0:b86d15c6ba29 6222 if ( (t + padLen + 1) > pLen) {
Vanger 0:b86d15c6ba29 6223 CYASSL_MSG("Plain Len not long enough for pad/mac");
Vanger 0:b86d15c6ba29 6224 PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE);
Vanger 0:b86d15c6ba29 6225 ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */
Vanger 0:b86d15c6ba29 6226 ConstantCompare(verify, input + pLen - t, t);
Vanger 0:b86d15c6ba29 6227
Vanger 0:b86d15c6ba29 6228 return VERIFY_MAC_ERROR;
Vanger 0:b86d15c6ba29 6229 }
Vanger 0:b86d15c6ba29 6230
Vanger 0:b86d15c6ba29 6231 if (PadCheck(input + pLen - (padLen + 1), (byte)padLen, padLen + 1) != 0) {
Vanger 0:b86d15c6ba29 6232 CYASSL_MSG("PadCheck failed");
Vanger 0:b86d15c6ba29 6233 PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
Vanger 0:b86d15c6ba29 6234 ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */
Vanger 0:b86d15c6ba29 6235 ConstantCompare(verify, input + pLen - t, t);
Vanger 0:b86d15c6ba29 6236
Vanger 0:b86d15c6ba29 6237 return VERIFY_MAC_ERROR;
Vanger 0:b86d15c6ba29 6238 }
Vanger 0:b86d15c6ba29 6239
Vanger 0:b86d15c6ba29 6240 PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
Vanger 0:b86d15c6ba29 6241 ret = ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, content, 1);
Vanger 0:b86d15c6ba29 6242
Vanger 0:b86d15c6ba29 6243 CompressRounds(ssl, GetRounds(pLen, padLen, t), dummy);
Vanger 0:b86d15c6ba29 6244
Vanger 0:b86d15c6ba29 6245 if (ConstantCompare(verify, input + (pLen - padLen - 1 - t), t) != 0) {
Vanger 0:b86d15c6ba29 6246 CYASSL_MSG("Verify MAC compare failed");
Vanger 0:b86d15c6ba29 6247 return VERIFY_MAC_ERROR;
Vanger 0:b86d15c6ba29 6248 }
Vanger 0:b86d15c6ba29 6249
Vanger 0:b86d15c6ba29 6250 if (ret != 0)
Vanger 0:b86d15c6ba29 6251 return VERIFY_MAC_ERROR;
Vanger 0:b86d15c6ba29 6252 return 0;
Vanger 0:b86d15c6ba29 6253 }
Vanger 0:b86d15c6ba29 6254
Vanger 0:b86d15c6ba29 6255
Vanger 0:b86d15c6ba29 6256 int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx)
Vanger 0:b86d15c6ba29 6257 {
Vanger 0:b86d15c6ba29 6258 word32 msgSz = ssl->keys.encryptSz;
Vanger 0:b86d15c6ba29 6259 word32 idx = *inOutIdx;
Vanger 0:b86d15c6ba29 6260 int dataSz;
Vanger 0:b86d15c6ba29 6261 int ivExtra = 0;
Vanger 0:b86d15c6ba29 6262 byte* rawData = input + idx; /* keep current for hmac */
Vanger 0:b86d15c6ba29 6263 #ifdef HAVE_LIBZ
Vanger 0:b86d15c6ba29 6264 byte decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
Vanger 0:b86d15c6ba29 6265 #endif
Vanger 0:b86d15c6ba29 6266
Vanger 0:b86d15c6ba29 6267 if (ssl->options.handShakeDone == 0) {
Vanger 0:b86d15c6ba29 6268 CYASSL_MSG("Received App data before a handshake completed");
Vanger 0:b86d15c6ba29 6269 SendAlert(ssl, alert_fatal, unexpected_message);
Vanger 0:b86d15c6ba29 6270 return OUT_OF_ORDER_E;
Vanger 0:b86d15c6ba29 6271 }
Vanger 0:b86d15c6ba29 6272
Vanger 0:b86d15c6ba29 6273 if (ssl->specs.cipher_type == block) {
Vanger 0:b86d15c6ba29 6274 if (ssl->options.tls1_1)
Vanger 0:b86d15c6ba29 6275 ivExtra = ssl->specs.block_size;
Vanger 0:b86d15c6ba29 6276 }
Vanger 0:b86d15c6ba29 6277 else if (ssl->specs.cipher_type == aead) {
Vanger 0:b86d15c6ba29 6278 if (ssl->specs.bulk_cipher_algorithm != cyassl_chacha)
Vanger 0:b86d15c6ba29 6279 ivExtra = AEAD_EXP_IV_SZ;
Vanger 0:b86d15c6ba29 6280 }
Vanger 0:b86d15c6ba29 6281
Vanger 0:b86d15c6ba29 6282 dataSz = msgSz - ivExtra - ssl->keys.padSz;
Vanger 0:b86d15c6ba29 6283 if (dataSz < 0) {
Vanger 0:b86d15c6ba29 6284 CYASSL_MSG("App data buffer error, malicious input?");
Vanger 0:b86d15c6ba29 6285 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 6286 }
Vanger 0:b86d15c6ba29 6287
Vanger 0:b86d15c6ba29 6288 /* read data */
Vanger 0:b86d15c6ba29 6289 if (dataSz) {
Vanger 0:b86d15c6ba29 6290 int rawSz = dataSz; /* keep raw size for idx adjustment */
Vanger 0:b86d15c6ba29 6291
Vanger 0:b86d15c6ba29 6292 #ifdef HAVE_LIBZ
Vanger 0:b86d15c6ba29 6293 if (ssl->options.usingCompression) {
Vanger 0:b86d15c6ba29 6294 dataSz = myDeCompress(ssl, rawData, dataSz, decomp, sizeof(decomp));
Vanger 0:b86d15c6ba29 6295 if (dataSz < 0) return dataSz;
Vanger 0:b86d15c6ba29 6296 }
Vanger 0:b86d15c6ba29 6297 #endif
Vanger 0:b86d15c6ba29 6298 idx += rawSz;
Vanger 0:b86d15c6ba29 6299
Vanger 0:b86d15c6ba29 6300 ssl->buffers.clearOutputBuffer.buffer = rawData;
Vanger 0:b86d15c6ba29 6301 ssl->buffers.clearOutputBuffer.length = dataSz;
Vanger 0:b86d15c6ba29 6302 }
Vanger 0:b86d15c6ba29 6303
Vanger 0:b86d15c6ba29 6304 idx += ssl->keys.padSz;
Vanger 0:b86d15c6ba29 6305
Vanger 0:b86d15c6ba29 6306 #ifdef HAVE_LIBZ
Vanger 0:b86d15c6ba29 6307 /* decompress could be bigger, overwrite after verify */
Vanger 0:b86d15c6ba29 6308 if (ssl->options.usingCompression)
Vanger 0:b86d15c6ba29 6309 XMEMMOVE(rawData, decomp, dataSz);
Vanger 0:b86d15c6ba29 6310 #endif
Vanger 0:b86d15c6ba29 6311
Vanger 0:b86d15c6ba29 6312 *inOutIdx = idx;
Vanger 0:b86d15c6ba29 6313 return 0;
Vanger 0:b86d15c6ba29 6314 }
Vanger 0:b86d15c6ba29 6315
Vanger 0:b86d15c6ba29 6316
Vanger 0:b86d15c6ba29 6317 /* process alert, return level */
Vanger 0:b86d15c6ba29 6318 static int DoAlert(CYASSL* ssl, byte* input, word32* inOutIdx, int* type,
Vanger 0:b86d15c6ba29 6319 word32 totalSz)
Vanger 0:b86d15c6ba29 6320 {
Vanger 0:b86d15c6ba29 6321 byte level;
Vanger 0:b86d15c6ba29 6322 byte code;
Vanger 0:b86d15c6ba29 6323
Vanger 0:b86d15c6ba29 6324 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 6325 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 6326 AddPacketName("Alert", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 6327 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 6328 /* add record header back on to info + 2 byte level, data */
Vanger 0:b86d15c6ba29 6329 AddPacketInfo("Alert", &ssl->timeoutInfo, input + *inOutIdx -
Vanger 0:b86d15c6ba29 6330 RECORD_HEADER_SZ, 2 + RECORD_HEADER_SZ, ssl->heap);
Vanger 0:b86d15c6ba29 6331 #endif
Vanger 0:b86d15c6ba29 6332
Vanger 0:b86d15c6ba29 6333 /* make sure can read the message */
Vanger 0:b86d15c6ba29 6334 if (*inOutIdx + ALERT_SIZE > totalSz)
Vanger 0:b86d15c6ba29 6335 return BUFFER_E;
Vanger 0:b86d15c6ba29 6336
Vanger 0:b86d15c6ba29 6337 level = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 6338 code = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 6339 ssl->alert_history.last_rx.code = code;
Vanger 0:b86d15c6ba29 6340 ssl->alert_history.last_rx.level = level;
Vanger 0:b86d15c6ba29 6341 *type = code;
Vanger 0:b86d15c6ba29 6342 if (level == alert_fatal) {
Vanger 0:b86d15c6ba29 6343 ssl->options.isClosed = 1; /* Don't send close_notify */
Vanger 0:b86d15c6ba29 6344 }
Vanger 0:b86d15c6ba29 6345
Vanger 0:b86d15c6ba29 6346 CYASSL_MSG("Got alert");
Vanger 0:b86d15c6ba29 6347 if (*type == close_notify) {
Vanger 0:b86d15c6ba29 6348 CYASSL_MSG(" close notify");
Vanger 0:b86d15c6ba29 6349 ssl->options.closeNotify = 1;
Vanger 0:b86d15c6ba29 6350 }
Vanger 0:b86d15c6ba29 6351 CYASSL_ERROR(*type);
Vanger 0:b86d15c6ba29 6352
Vanger 0:b86d15c6ba29 6353 if (ssl->keys.encryptionOn) {
Vanger 0:b86d15c6ba29 6354 if (*inOutIdx + ssl->keys.padSz > totalSz)
Vanger 0:b86d15c6ba29 6355 return BUFFER_E;
Vanger 0:b86d15c6ba29 6356 *inOutIdx += ssl->keys.padSz;
Vanger 0:b86d15c6ba29 6357 }
Vanger 0:b86d15c6ba29 6358
Vanger 0:b86d15c6ba29 6359 return level;
Vanger 0:b86d15c6ba29 6360 }
Vanger 0:b86d15c6ba29 6361
Vanger 0:b86d15c6ba29 6362 static int GetInputData(CYASSL *ssl, word32 size)
Vanger 0:b86d15c6ba29 6363 {
Vanger 0:b86d15c6ba29 6364 int in;
Vanger 0:b86d15c6ba29 6365 int inSz;
Vanger 0:b86d15c6ba29 6366 int maxLength;
Vanger 0:b86d15c6ba29 6367 int usedLength;
Vanger 0:b86d15c6ba29 6368 int dtlsExtra = 0;
Vanger 0:b86d15c6ba29 6369
Vanger 0:b86d15c6ba29 6370
Vanger 0:b86d15c6ba29 6371 /* check max input length */
Vanger 0:b86d15c6ba29 6372 usedLength = ssl->buffers.inputBuffer.length - ssl->buffers.inputBuffer.idx;
Vanger 0:b86d15c6ba29 6373 maxLength = ssl->buffers.inputBuffer.bufferSize - usedLength;
Vanger 0:b86d15c6ba29 6374 inSz = (int)(size - usedLength); /* from last partial read */
Vanger 0:b86d15c6ba29 6375
Vanger 0:b86d15c6ba29 6376 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 6377 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 6378 if (size < ssl->dtls_expected_rx)
Vanger 0:b86d15c6ba29 6379 dtlsExtra = (int)(ssl->dtls_expected_rx - size);
Vanger 0:b86d15c6ba29 6380 inSz = ssl->dtls_expected_rx;
Vanger 0:b86d15c6ba29 6381 }
Vanger 0:b86d15c6ba29 6382 #endif
Vanger 0:b86d15c6ba29 6383
Vanger 0:b86d15c6ba29 6384 if (inSz > maxLength) {
Vanger 0:b86d15c6ba29 6385 if (GrowInputBuffer(ssl, size + dtlsExtra, usedLength) < 0)
Vanger 0:b86d15c6ba29 6386 return MEMORY_E;
Vanger 0:b86d15c6ba29 6387 }
Vanger 0:b86d15c6ba29 6388
Vanger 0:b86d15c6ba29 6389 if (inSz <= 0)
Vanger 0:b86d15c6ba29 6390 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 6391
Vanger 0:b86d15c6ba29 6392 /* Put buffer data at start if not there */
Vanger 0:b86d15c6ba29 6393 if (usedLength > 0 && ssl->buffers.inputBuffer.idx != 0)
Vanger 0:b86d15c6ba29 6394 XMEMMOVE(ssl->buffers.inputBuffer.buffer,
Vanger 0:b86d15c6ba29 6395 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
Vanger 0:b86d15c6ba29 6396 usedLength);
Vanger 0:b86d15c6ba29 6397
Vanger 0:b86d15c6ba29 6398 /* remove processed data */
Vanger 0:b86d15c6ba29 6399 ssl->buffers.inputBuffer.idx = 0;
Vanger 0:b86d15c6ba29 6400 ssl->buffers.inputBuffer.length = usedLength;
Vanger 0:b86d15c6ba29 6401
Vanger 0:b86d15c6ba29 6402 /* read data from network */
Vanger 0:b86d15c6ba29 6403 do {
Vanger 0:b86d15c6ba29 6404 in = Receive(ssl,
Vanger 0:b86d15c6ba29 6405 ssl->buffers.inputBuffer.buffer +
Vanger 0:b86d15c6ba29 6406 ssl->buffers.inputBuffer.length,
Vanger 0:b86d15c6ba29 6407 inSz);
Vanger 0:b86d15c6ba29 6408 if (in == -1)
Vanger 0:b86d15c6ba29 6409 return SOCKET_ERROR_E;
Vanger 0:b86d15c6ba29 6410
Vanger 0:b86d15c6ba29 6411 if (in == WANT_READ)
Vanger 0:b86d15c6ba29 6412 return WANT_READ;
Vanger 0:b86d15c6ba29 6413
Vanger 0:b86d15c6ba29 6414 if (in > inSz)
Vanger 0:b86d15c6ba29 6415 return RECV_OVERFLOW_E;
Vanger 0:b86d15c6ba29 6416
Vanger 0:b86d15c6ba29 6417 ssl->buffers.inputBuffer.length += in;
Vanger 0:b86d15c6ba29 6418 inSz -= in;
Vanger 0:b86d15c6ba29 6419
Vanger 0:b86d15c6ba29 6420 } while (ssl->buffers.inputBuffer.length < size);
Vanger 0:b86d15c6ba29 6421
Vanger 0:b86d15c6ba29 6422 return 0;
Vanger 0:b86d15c6ba29 6423 }
Vanger 0:b86d15c6ba29 6424
Vanger 0:b86d15c6ba29 6425
Vanger 0:b86d15c6ba29 6426 static INLINE int VerifyMac(CYASSL* ssl, const byte* input, word32 msgSz,
Vanger 0:b86d15c6ba29 6427 int content, word32* padSz)
Vanger 0:b86d15c6ba29 6428 {
Vanger 0:b86d15c6ba29 6429 int ivExtra = 0;
Vanger 0:b86d15c6ba29 6430 int ret;
Vanger 0:b86d15c6ba29 6431 word32 pad = 0;
Vanger 0:b86d15c6ba29 6432 word32 padByte = 0;
Vanger 0:b86d15c6ba29 6433 #ifdef HAVE_TRUNCATED_HMAC
Vanger 0:b86d15c6ba29 6434 word32 digestSz = ssl->truncated_hmac ? TRUNCATED_HMAC_SZ
Vanger 0:b86d15c6ba29 6435 : ssl->specs.hash_size;
Vanger 0:b86d15c6ba29 6436 #else
Vanger 0:b86d15c6ba29 6437 word32 digestSz = ssl->specs.hash_size;
Vanger 0:b86d15c6ba29 6438 #endif
Vanger 0:b86d15c6ba29 6439 byte verify[MAX_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 6440
Vanger 0:b86d15c6ba29 6441 if (ssl->specs.cipher_type == block) {
Vanger 0:b86d15c6ba29 6442 if (ssl->options.tls1_1)
Vanger 0:b86d15c6ba29 6443 ivExtra = ssl->specs.block_size;
Vanger 0:b86d15c6ba29 6444 pad = *(input + msgSz - ivExtra - 1);
Vanger 0:b86d15c6ba29 6445 padByte = 1;
Vanger 0:b86d15c6ba29 6446
Vanger 0:b86d15c6ba29 6447 if (ssl->options.tls) {
Vanger 0:b86d15c6ba29 6448 ret = TimingPadVerify(ssl, input, pad, digestSz, msgSz - ivExtra,
Vanger 0:b86d15c6ba29 6449 content);
Vanger 0:b86d15c6ba29 6450 if (ret != 0)
Vanger 0:b86d15c6ba29 6451 return ret;
Vanger 0:b86d15c6ba29 6452 }
Vanger 0:b86d15c6ba29 6453 else { /* sslv3, some implementations have bad padding, but don't
Vanger 0:b86d15c6ba29 6454 * allow bad read */
Vanger 0:b86d15c6ba29 6455 int badPadLen = 0;
Vanger 0:b86d15c6ba29 6456 byte dummy[MAX_PAD_SIZE];
Vanger 0:b86d15c6ba29 6457
Vanger 0:b86d15c6ba29 6458 XMEMSET(dummy, 1, sizeof(dummy));
Vanger 0:b86d15c6ba29 6459
Vanger 0:b86d15c6ba29 6460 if (pad > (msgSz - digestSz - 1)) {
Vanger 0:b86d15c6ba29 6461 CYASSL_MSG("Plain Len not long enough for pad/mac");
Vanger 0:b86d15c6ba29 6462 pad = 0; /* no bad read */
Vanger 0:b86d15c6ba29 6463 badPadLen = 1;
Vanger 0:b86d15c6ba29 6464 }
Vanger 0:b86d15c6ba29 6465 PadCheck(dummy, (byte)pad, MAX_PAD_SIZE); /* timing only */
Vanger 0:b86d15c6ba29 6466 ret = ssl->hmac(ssl, verify, input, msgSz - digestSz - pad - 1,
Vanger 0:b86d15c6ba29 6467 content, 1);
Vanger 0:b86d15c6ba29 6468 if (ConstantCompare(verify, input + msgSz - digestSz - pad - 1,
Vanger 0:b86d15c6ba29 6469 digestSz) != 0)
Vanger 0:b86d15c6ba29 6470 return VERIFY_MAC_ERROR;
Vanger 0:b86d15c6ba29 6471 if (ret != 0 || badPadLen)
Vanger 0:b86d15c6ba29 6472 return VERIFY_MAC_ERROR;
Vanger 0:b86d15c6ba29 6473 }
Vanger 0:b86d15c6ba29 6474 }
Vanger 0:b86d15c6ba29 6475 else if (ssl->specs.cipher_type == stream) {
Vanger 0:b86d15c6ba29 6476 ret = ssl->hmac(ssl, verify, input, msgSz - digestSz, content, 1);
Vanger 0:b86d15c6ba29 6477 if (ConstantCompare(verify, input + msgSz - digestSz, digestSz) != 0){
Vanger 0:b86d15c6ba29 6478 return VERIFY_MAC_ERROR;
Vanger 0:b86d15c6ba29 6479 }
Vanger 0:b86d15c6ba29 6480 if (ret != 0)
Vanger 0:b86d15c6ba29 6481 return VERIFY_MAC_ERROR;
Vanger 0:b86d15c6ba29 6482 }
Vanger 0:b86d15c6ba29 6483
Vanger 0:b86d15c6ba29 6484 if (ssl->specs.cipher_type == aead) {
Vanger 0:b86d15c6ba29 6485 *padSz = ssl->specs.aead_mac_size;
Vanger 0:b86d15c6ba29 6486 }
Vanger 0:b86d15c6ba29 6487 else {
Vanger 0:b86d15c6ba29 6488 *padSz = digestSz + pad + padByte;
Vanger 0:b86d15c6ba29 6489 }
Vanger 0:b86d15c6ba29 6490
Vanger 0:b86d15c6ba29 6491 return 0;
Vanger 0:b86d15c6ba29 6492 }
Vanger 0:b86d15c6ba29 6493
Vanger 0:b86d15c6ba29 6494
Vanger 0:b86d15c6ba29 6495 /* process input requests, return 0 is done, 1 is call again to complete, and
Vanger 0:b86d15c6ba29 6496 negative number is error */
Vanger 0:b86d15c6ba29 6497 int ProcessReply(CYASSL* ssl)
Vanger 0:b86d15c6ba29 6498 {
Vanger 0:b86d15c6ba29 6499 int ret = 0, type, readSz;
Vanger 0:b86d15c6ba29 6500 int atomicUser = 0;
Vanger 0:b86d15c6ba29 6501 word32 startIdx = 0;
Vanger 0:b86d15c6ba29 6502 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 6503 int used;
Vanger 0:b86d15c6ba29 6504 #endif
Vanger 0:b86d15c6ba29 6505
Vanger 0:b86d15c6ba29 6506 #ifdef ATOMIC_USER
Vanger 0:b86d15c6ba29 6507 if (ssl->ctx->DecryptVerifyCb)
Vanger 0:b86d15c6ba29 6508 atomicUser = 1;
Vanger 0:b86d15c6ba29 6509 #endif
Vanger 0:b86d15c6ba29 6510
Vanger 0:b86d15c6ba29 6511 if (ssl->error != 0 && ssl->error != WANT_READ && ssl->error != WANT_WRITE){
Vanger 0:b86d15c6ba29 6512 CYASSL_MSG("ProcessReply retry in error state, not allowed");
Vanger 0:b86d15c6ba29 6513 return ssl->error;
Vanger 0:b86d15c6ba29 6514 }
Vanger 0:b86d15c6ba29 6515
Vanger 0:b86d15c6ba29 6516 for (;;) {
Vanger 0:b86d15c6ba29 6517 switch (ssl->options.processReply) {
Vanger 0:b86d15c6ba29 6518
Vanger 0:b86d15c6ba29 6519 /* in the CYASSL_SERVER case, get the first byte for detecting
Vanger 0:b86d15c6ba29 6520 * old client hello */
Vanger 0:b86d15c6ba29 6521 case doProcessInit:
Vanger 0:b86d15c6ba29 6522
Vanger 0:b86d15c6ba29 6523 readSz = RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 6524
Vanger 0:b86d15c6ba29 6525 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 6526 if (ssl->options.dtls)
Vanger 0:b86d15c6ba29 6527 readSz = DTLS_RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 6528 #endif
Vanger 0:b86d15c6ba29 6529
Vanger 0:b86d15c6ba29 6530 /* get header or return error */
Vanger 0:b86d15c6ba29 6531 if (!ssl->options.dtls) {
Vanger 0:b86d15c6ba29 6532 if ((ret = GetInputData(ssl, readSz)) < 0)
Vanger 0:b86d15c6ba29 6533 return ret;
Vanger 0:b86d15c6ba29 6534 } else {
Vanger 0:b86d15c6ba29 6535 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 6536 /* read ahead may already have header */
Vanger 0:b86d15c6ba29 6537 used = ssl->buffers.inputBuffer.length -
Vanger 0:b86d15c6ba29 6538 ssl->buffers.inputBuffer.idx;
Vanger 0:b86d15c6ba29 6539 if (used < readSz)
Vanger 0:b86d15c6ba29 6540 if ((ret = GetInputData(ssl, readSz)) < 0)
Vanger 0:b86d15c6ba29 6541 return ret;
Vanger 0:b86d15c6ba29 6542 #endif
Vanger 0:b86d15c6ba29 6543 }
Vanger 0:b86d15c6ba29 6544
Vanger 0:b86d15c6ba29 6545 #ifdef OLD_HELLO_ALLOWED
Vanger 0:b86d15c6ba29 6546
Vanger 0:b86d15c6ba29 6547 /* see if sending SSLv2 client hello */
Vanger 0:b86d15c6ba29 6548 if ( ssl->options.side == CYASSL_SERVER_END &&
Vanger 0:b86d15c6ba29 6549 ssl->options.clientState == NULL_STATE &&
Vanger 0:b86d15c6ba29 6550 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx]
Vanger 0:b86d15c6ba29 6551 != handshake) {
Vanger 0:b86d15c6ba29 6552 byte b0, b1;
Vanger 0:b86d15c6ba29 6553
Vanger 0:b86d15c6ba29 6554 ssl->options.processReply = runProcessOldClientHello;
Vanger 0:b86d15c6ba29 6555
Vanger 0:b86d15c6ba29 6556 /* sanity checks before getting size at front */
Vanger 0:b86d15c6ba29 6557 if (ssl->buffers.inputBuffer.buffer[
Vanger 0:b86d15c6ba29 6558 ssl->buffers.inputBuffer.idx + 2] != OLD_HELLO_ID) {
Vanger 0:b86d15c6ba29 6559 CYASSL_MSG("Not a valid old client hello");
Vanger 0:b86d15c6ba29 6560 return PARSE_ERROR;
Vanger 0:b86d15c6ba29 6561 }
Vanger 0:b86d15c6ba29 6562
Vanger 0:b86d15c6ba29 6563 if (ssl->buffers.inputBuffer.buffer[
Vanger 0:b86d15c6ba29 6564 ssl->buffers.inputBuffer.idx + 3] != SSLv3_MAJOR &&
Vanger 0:b86d15c6ba29 6565 ssl->buffers.inputBuffer.buffer[
Vanger 0:b86d15c6ba29 6566 ssl->buffers.inputBuffer.idx + 3] != DTLS_MAJOR) {
Vanger 0:b86d15c6ba29 6567 CYASSL_MSG("Not a valid version in old client hello");
Vanger 0:b86d15c6ba29 6568 return PARSE_ERROR;
Vanger 0:b86d15c6ba29 6569 }
Vanger 0:b86d15c6ba29 6570
Vanger 0:b86d15c6ba29 6571 /* how many bytes need ProcessOldClientHello */
Vanger 0:b86d15c6ba29 6572 b0 =
Vanger 0:b86d15c6ba29 6573 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
Vanger 0:b86d15c6ba29 6574 b1 =
Vanger 0:b86d15c6ba29 6575 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
Vanger 0:b86d15c6ba29 6576 ssl->curSize = (word16)(((b0 & 0x7f) << 8) | b1);
Vanger 0:b86d15c6ba29 6577 }
Vanger 0:b86d15c6ba29 6578 else {
Vanger 0:b86d15c6ba29 6579 ssl->options.processReply = getRecordLayerHeader;
Vanger 0:b86d15c6ba29 6580 continue;
Vanger 0:b86d15c6ba29 6581 }
Vanger 0:b86d15c6ba29 6582
Vanger 0:b86d15c6ba29 6583 /* in the CYASSL_SERVER case, run the old client hello */
Vanger 0:b86d15c6ba29 6584 case runProcessOldClientHello:
Vanger 0:b86d15c6ba29 6585
Vanger 0:b86d15c6ba29 6586 /* get sz bytes or return error */
Vanger 0:b86d15c6ba29 6587 if (!ssl->options.dtls) {
Vanger 0:b86d15c6ba29 6588 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
Vanger 0:b86d15c6ba29 6589 return ret;
Vanger 0:b86d15c6ba29 6590 } else {
Vanger 0:b86d15c6ba29 6591 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 6592 /* read ahead may already have */
Vanger 0:b86d15c6ba29 6593 used = ssl->buffers.inputBuffer.length -
Vanger 0:b86d15c6ba29 6594 ssl->buffers.inputBuffer.idx;
Vanger 0:b86d15c6ba29 6595 if (used < ssl->curSize)
Vanger 0:b86d15c6ba29 6596 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
Vanger 0:b86d15c6ba29 6597 return ret;
Vanger 0:b86d15c6ba29 6598 #endif /* CYASSL_DTLS */
Vanger 0:b86d15c6ba29 6599 }
Vanger 0:b86d15c6ba29 6600
Vanger 0:b86d15c6ba29 6601 ret = ProcessOldClientHello(ssl, ssl->buffers.inputBuffer.buffer,
Vanger 0:b86d15c6ba29 6602 &ssl->buffers.inputBuffer.idx,
Vanger 0:b86d15c6ba29 6603 ssl->buffers.inputBuffer.length -
Vanger 0:b86d15c6ba29 6604 ssl->buffers.inputBuffer.idx,
Vanger 0:b86d15c6ba29 6605 ssl->curSize);
Vanger 0:b86d15c6ba29 6606 if (ret < 0)
Vanger 0:b86d15c6ba29 6607 return ret;
Vanger 0:b86d15c6ba29 6608
Vanger 0:b86d15c6ba29 6609 else if (ssl->buffers.inputBuffer.idx ==
Vanger 0:b86d15c6ba29 6610 ssl->buffers.inputBuffer.length) {
Vanger 0:b86d15c6ba29 6611 ssl->options.processReply = doProcessInit;
Vanger 0:b86d15c6ba29 6612 return 0;
Vanger 0:b86d15c6ba29 6613 }
Vanger 0:b86d15c6ba29 6614
Vanger 0:b86d15c6ba29 6615 #endif /* OLD_HELLO_ALLOWED */
Vanger 0:b86d15c6ba29 6616
Vanger 0:b86d15c6ba29 6617 /* get the record layer header */
Vanger 0:b86d15c6ba29 6618 case getRecordLayerHeader:
Vanger 0:b86d15c6ba29 6619
Vanger 0:b86d15c6ba29 6620 ret = GetRecordHeader(ssl, ssl->buffers.inputBuffer.buffer,
Vanger 0:b86d15c6ba29 6621 &ssl->buffers.inputBuffer.idx,
Vanger 0:b86d15c6ba29 6622 &ssl->curRL, &ssl->curSize);
Vanger 0:b86d15c6ba29 6623 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 6624 if (ssl->options.dtls && ret == SEQUENCE_ERROR) {
Vanger 0:b86d15c6ba29 6625 ssl->options.processReply = doProcessInit;
Vanger 0:b86d15c6ba29 6626 ssl->buffers.inputBuffer.length = 0;
Vanger 0:b86d15c6ba29 6627 ssl->buffers.inputBuffer.idx = 0;
Vanger 0:b86d15c6ba29 6628 continue;
Vanger 0:b86d15c6ba29 6629 }
Vanger 0:b86d15c6ba29 6630 #endif
Vanger 0:b86d15c6ba29 6631 if (ret != 0)
Vanger 0:b86d15c6ba29 6632 return ret;
Vanger 0:b86d15c6ba29 6633
Vanger 0:b86d15c6ba29 6634 ssl->options.processReply = getData;
Vanger 0:b86d15c6ba29 6635
Vanger 0:b86d15c6ba29 6636 /* retrieve record layer data */
Vanger 0:b86d15c6ba29 6637 case getData:
Vanger 0:b86d15c6ba29 6638
Vanger 0:b86d15c6ba29 6639 /* get sz bytes or return error */
Vanger 0:b86d15c6ba29 6640 if (!ssl->options.dtls) {
Vanger 0:b86d15c6ba29 6641 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
Vanger 0:b86d15c6ba29 6642 return ret;
Vanger 0:b86d15c6ba29 6643 } else {
Vanger 0:b86d15c6ba29 6644 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 6645 /* read ahead may already have */
Vanger 0:b86d15c6ba29 6646 used = ssl->buffers.inputBuffer.length -
Vanger 0:b86d15c6ba29 6647 ssl->buffers.inputBuffer.idx;
Vanger 0:b86d15c6ba29 6648 if (used < ssl->curSize)
Vanger 0:b86d15c6ba29 6649 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
Vanger 0:b86d15c6ba29 6650 return ret;
Vanger 0:b86d15c6ba29 6651 #endif
Vanger 0:b86d15c6ba29 6652 }
Vanger 0:b86d15c6ba29 6653
Vanger 0:b86d15c6ba29 6654 ssl->options.processReply = runProcessingOneMessage;
Vanger 0:b86d15c6ba29 6655 startIdx = ssl->buffers.inputBuffer.idx; /* in case > 1 msg per */
Vanger 0:b86d15c6ba29 6656
Vanger 0:b86d15c6ba29 6657 /* the record layer is here */
Vanger 0:b86d15c6ba29 6658 case runProcessingOneMessage:
Vanger 0:b86d15c6ba29 6659
Vanger 0:b86d15c6ba29 6660 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 6661 if (ssl->options.dtls &&
Vanger 0:b86d15c6ba29 6662 ssl->keys.dtls_state.curEpoch < ssl->keys.dtls_state.nextEpoch)
Vanger 0:b86d15c6ba29 6663 ssl->keys.decryptedCur = 1;
Vanger 0:b86d15c6ba29 6664 #endif
Vanger 0:b86d15c6ba29 6665
Vanger 0:b86d15c6ba29 6666 if (ssl->keys.encryptionOn && ssl->keys.decryptedCur == 0)
Vanger 0:b86d15c6ba29 6667 {
Vanger 0:b86d15c6ba29 6668 ret = SanityCheckCipherText(ssl, ssl->curSize);
Vanger 0:b86d15c6ba29 6669 if (ret < 0)
Vanger 0:b86d15c6ba29 6670 return ret;
Vanger 0:b86d15c6ba29 6671
Vanger 0:b86d15c6ba29 6672 if (atomicUser) {
Vanger 0:b86d15c6ba29 6673 #ifdef ATOMIC_USER
Vanger 0:b86d15c6ba29 6674 ret = ssl->ctx->DecryptVerifyCb(ssl,
Vanger 0:b86d15c6ba29 6675 ssl->buffers.inputBuffer.buffer +
Vanger 0:b86d15c6ba29 6676 ssl->buffers.inputBuffer.idx,
Vanger 0:b86d15c6ba29 6677 ssl->buffers.inputBuffer.buffer +
Vanger 0:b86d15c6ba29 6678 ssl->buffers.inputBuffer.idx,
Vanger 0:b86d15c6ba29 6679 ssl->curSize, ssl->curRL.type, 1,
Vanger 0:b86d15c6ba29 6680 &ssl->keys.padSz, ssl->DecryptVerifyCtx);
Vanger 0:b86d15c6ba29 6681 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
Vanger 0:b86d15c6ba29 6682 ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
Vanger 0:b86d15c6ba29 6683 /* go past TLSv1.1 IV */
Vanger 0:b86d15c6ba29 6684 if (ssl->specs.cipher_type == aead &&
Vanger 0:b86d15c6ba29 6685 ssl->specs.bulk_cipher_algorithm != cyassl_chacha)
Vanger 0:b86d15c6ba29 6686 ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ;
Vanger 0:b86d15c6ba29 6687 #endif /* ATOMIC_USER */
Vanger 0:b86d15c6ba29 6688 }
Vanger 0:b86d15c6ba29 6689 else {
Vanger 0:b86d15c6ba29 6690 ret = Decrypt(ssl, ssl->buffers.inputBuffer.buffer +
Vanger 0:b86d15c6ba29 6691 ssl->buffers.inputBuffer.idx,
Vanger 0:b86d15c6ba29 6692 ssl->buffers.inputBuffer.buffer +
Vanger 0:b86d15c6ba29 6693 ssl->buffers.inputBuffer.idx,
Vanger 0:b86d15c6ba29 6694 ssl->curSize);
Vanger 0:b86d15c6ba29 6695 if (ret < 0) {
Vanger 0:b86d15c6ba29 6696 CYASSL_ERROR(ret);
Vanger 0:b86d15c6ba29 6697 return DECRYPT_ERROR;
Vanger 0:b86d15c6ba29 6698 }
Vanger 0:b86d15c6ba29 6699 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
Vanger 0:b86d15c6ba29 6700 ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
Vanger 0:b86d15c6ba29 6701 /* go past TLSv1.1 IV */
Vanger 0:b86d15c6ba29 6702 if (ssl->specs.cipher_type == aead &&
Vanger 0:b86d15c6ba29 6703 ssl->specs.bulk_cipher_algorithm != cyassl_chacha)
Vanger 0:b86d15c6ba29 6704 ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ;
Vanger 0:b86d15c6ba29 6705
Vanger 0:b86d15c6ba29 6706 ret = VerifyMac(ssl, ssl->buffers.inputBuffer.buffer +
Vanger 0:b86d15c6ba29 6707 ssl->buffers.inputBuffer.idx,
Vanger 0:b86d15c6ba29 6708 ssl->curSize, ssl->curRL.type,
Vanger 0:b86d15c6ba29 6709 &ssl->keys.padSz);
Vanger 0:b86d15c6ba29 6710 }
Vanger 0:b86d15c6ba29 6711 if (ret < 0) {
Vanger 0:b86d15c6ba29 6712 CYASSL_ERROR(ret);
Vanger 0:b86d15c6ba29 6713 return DECRYPT_ERROR;
Vanger 0:b86d15c6ba29 6714 }
Vanger 0:b86d15c6ba29 6715 ssl->keys.encryptSz = ssl->curSize;
Vanger 0:b86d15c6ba29 6716 ssl->keys.decryptedCur = 1;
Vanger 0:b86d15c6ba29 6717 }
Vanger 0:b86d15c6ba29 6718
Vanger 0:b86d15c6ba29 6719 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 6720 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 6721 DtlsUpdateWindow(&ssl->keys.dtls_state);
Vanger 0:b86d15c6ba29 6722 #endif /* CYASSL_DTLS */
Vanger 0:b86d15c6ba29 6723 }
Vanger 0:b86d15c6ba29 6724
Vanger 0:b86d15c6ba29 6725 CYASSL_MSG("received record layer msg");
Vanger 0:b86d15c6ba29 6726
Vanger 0:b86d15c6ba29 6727 switch (ssl->curRL.type) {
Vanger 0:b86d15c6ba29 6728 case handshake :
Vanger 0:b86d15c6ba29 6729 /* debugging in DoHandShakeMsg */
Vanger 0:b86d15c6ba29 6730 if (!ssl->options.dtls) {
Vanger 0:b86d15c6ba29 6731 ret = DoHandShakeMsg(ssl,
Vanger 0:b86d15c6ba29 6732 ssl->buffers.inputBuffer.buffer,
Vanger 0:b86d15c6ba29 6733 &ssl->buffers.inputBuffer.idx,
Vanger 0:b86d15c6ba29 6734 ssl->buffers.inputBuffer.length);
Vanger 0:b86d15c6ba29 6735 }
Vanger 0:b86d15c6ba29 6736 else {
Vanger 0:b86d15c6ba29 6737 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 6738 ret = DoDtlsHandShakeMsg(ssl,
Vanger 0:b86d15c6ba29 6739 ssl->buffers.inputBuffer.buffer,
Vanger 0:b86d15c6ba29 6740 &ssl->buffers.inputBuffer.idx,
Vanger 0:b86d15c6ba29 6741 ssl->buffers.inputBuffer.length);
Vanger 0:b86d15c6ba29 6742 #endif
Vanger 0:b86d15c6ba29 6743 }
Vanger 0:b86d15c6ba29 6744 if (ret != 0)
Vanger 0:b86d15c6ba29 6745 return ret;
Vanger 0:b86d15c6ba29 6746 break;
Vanger 0:b86d15c6ba29 6747
Vanger 0:b86d15c6ba29 6748 case change_cipher_spec:
Vanger 0:b86d15c6ba29 6749 CYASSL_MSG("got CHANGE CIPHER SPEC");
Vanger 0:b86d15c6ba29 6750 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 6751 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 6752 AddPacketName("ChangeCipher", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 6753 /* add record header back on info */
Vanger 0:b86d15c6ba29 6754 if (ssl->toInfoOn) {
Vanger 0:b86d15c6ba29 6755 AddPacketInfo("ChangeCipher", &ssl->timeoutInfo,
Vanger 0:b86d15c6ba29 6756 ssl->buffers.inputBuffer.buffer +
Vanger 0:b86d15c6ba29 6757 ssl->buffers.inputBuffer.idx - RECORD_HEADER_SZ,
Vanger 0:b86d15c6ba29 6758 1 + RECORD_HEADER_SZ, ssl->heap);
Vanger 0:b86d15c6ba29 6759 AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
Vanger 0:b86d15c6ba29 6760 }
Vanger 0:b86d15c6ba29 6761 #endif
Vanger 0:b86d15c6ba29 6762
Vanger 0:b86d15c6ba29 6763 ret = SanityCheckMsgReceived(ssl, change_cipher_hs);
Vanger 0:b86d15c6ba29 6764 if (ret != 0)
Vanger 0:b86d15c6ba29 6765 return ret;
Vanger 0:b86d15c6ba29 6766
Vanger 0:b86d15c6ba29 6767 #ifdef HAVE_SESSION_TICKET
Vanger 0:b86d15c6ba29 6768 if (ssl->options.side == CYASSL_CLIENT_END &&
Vanger 0:b86d15c6ba29 6769 ssl->expect_session_ticket) {
Vanger 0:b86d15c6ba29 6770 CYASSL_MSG("Expected session ticket missing");
Vanger 0:b86d15c6ba29 6771 return SESSION_TICKET_EXPECT_E;
Vanger 0:b86d15c6ba29 6772 }
Vanger 0:b86d15c6ba29 6773 #endif
Vanger 0:b86d15c6ba29 6774
Vanger 0:b86d15c6ba29 6775 if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
Vanger 0:b86d15c6ba29 6776 ssl->buffers.inputBuffer.idx += ssl->keys.padSz;
Vanger 0:b86d15c6ba29 6777 ssl->curSize -= ssl->buffers.inputBuffer.idx;
Vanger 0:b86d15c6ba29 6778 }
Vanger 0:b86d15c6ba29 6779
Vanger 0:b86d15c6ba29 6780 if (ssl->curSize != 1) {
Vanger 0:b86d15c6ba29 6781 CYASSL_MSG("Malicious or corrupted ChangeCipher msg");
Vanger 0:b86d15c6ba29 6782 return LENGTH_ERROR;
Vanger 0:b86d15c6ba29 6783 }
Vanger 0:b86d15c6ba29 6784 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 6785 if (ssl->options.side == CYASSL_SERVER_END &&
Vanger 0:b86d15c6ba29 6786 ssl->options.verifyPeer &&
Vanger 0:b86d15c6ba29 6787 ssl->options.havePeerCert)
Vanger 0:b86d15c6ba29 6788 if (!ssl->options.havePeerVerify) {
Vanger 0:b86d15c6ba29 6789 CYASSL_MSG("client didn't send cert verify");
Vanger 0:b86d15c6ba29 6790 return NO_PEER_VERIFY;
Vanger 0:b86d15c6ba29 6791 }
Vanger 0:b86d15c6ba29 6792 #endif
Vanger 0:b86d15c6ba29 6793
Vanger 0:b86d15c6ba29 6794
Vanger 0:b86d15c6ba29 6795 ssl->buffers.inputBuffer.idx++;
Vanger 0:b86d15c6ba29 6796 ssl->keys.encryptionOn = 1;
Vanger 0:b86d15c6ba29 6797
Vanger 0:b86d15c6ba29 6798 /* setup decrypt keys for following messages */
Vanger 0:b86d15c6ba29 6799 if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
Vanger 0:b86d15c6ba29 6800 return ret;
Vanger 0:b86d15c6ba29 6801
Vanger 0:b86d15c6ba29 6802 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 6803 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 6804 DtlsPoolReset(ssl);
Vanger 0:b86d15c6ba29 6805 ssl->keys.dtls_state.nextEpoch++;
Vanger 0:b86d15c6ba29 6806 ssl->keys.dtls_state.nextSeq = 0;
Vanger 0:b86d15c6ba29 6807 }
Vanger 0:b86d15c6ba29 6808 #endif
Vanger 0:b86d15c6ba29 6809
Vanger 0:b86d15c6ba29 6810 #ifdef HAVE_LIBZ
Vanger 0:b86d15c6ba29 6811 if (ssl->options.usingCompression)
Vanger 0:b86d15c6ba29 6812 if ( (ret = InitStreams(ssl)) != 0)
Vanger 0:b86d15c6ba29 6813 return ret;
Vanger 0:b86d15c6ba29 6814 #endif
Vanger 0:b86d15c6ba29 6815 if (ssl->options.resuming && ssl->options.side ==
Vanger 0:b86d15c6ba29 6816 CYASSL_CLIENT_END)
Vanger 0:b86d15c6ba29 6817 ret = BuildFinished(ssl, &ssl->verifyHashes, server);
Vanger 0:b86d15c6ba29 6818 else if (!ssl->options.resuming && ssl->options.side ==
Vanger 0:b86d15c6ba29 6819 CYASSL_SERVER_END)
Vanger 0:b86d15c6ba29 6820 ret = BuildFinished(ssl, &ssl->verifyHashes, client);
Vanger 0:b86d15c6ba29 6821 if (ret != 0)
Vanger 0:b86d15c6ba29 6822 return ret;
Vanger 0:b86d15c6ba29 6823 break;
Vanger 0:b86d15c6ba29 6824
Vanger 0:b86d15c6ba29 6825 case application_data:
Vanger 0:b86d15c6ba29 6826 CYASSL_MSG("got app DATA");
Vanger 0:b86d15c6ba29 6827 if ((ret = DoApplicationData(ssl,
Vanger 0:b86d15c6ba29 6828 ssl->buffers.inputBuffer.buffer,
Vanger 0:b86d15c6ba29 6829 &ssl->buffers.inputBuffer.idx))
Vanger 0:b86d15c6ba29 6830 != 0) {
Vanger 0:b86d15c6ba29 6831 CYASSL_ERROR(ret);
Vanger 0:b86d15c6ba29 6832 return ret;
Vanger 0:b86d15c6ba29 6833 }
Vanger 0:b86d15c6ba29 6834 break;
Vanger 0:b86d15c6ba29 6835
Vanger 0:b86d15c6ba29 6836 case alert:
Vanger 0:b86d15c6ba29 6837 CYASSL_MSG("got ALERT!");
Vanger 0:b86d15c6ba29 6838 ret = DoAlert(ssl, ssl->buffers.inputBuffer.buffer,
Vanger 0:b86d15c6ba29 6839 &ssl->buffers.inputBuffer.idx, &type,
Vanger 0:b86d15c6ba29 6840 ssl->buffers.inputBuffer.length);
Vanger 0:b86d15c6ba29 6841 if (ret == alert_fatal)
Vanger 0:b86d15c6ba29 6842 return FATAL_ERROR;
Vanger 0:b86d15c6ba29 6843 else if (ret < 0)
Vanger 0:b86d15c6ba29 6844 return ret;
Vanger 0:b86d15c6ba29 6845
Vanger 0:b86d15c6ba29 6846 /* catch warnings that are handled as errors */
Vanger 0:b86d15c6ba29 6847 if (type == close_notify)
Vanger 0:b86d15c6ba29 6848 return ssl->error = ZERO_RETURN;
Vanger 0:b86d15c6ba29 6849
Vanger 0:b86d15c6ba29 6850 if (type == decrypt_error)
Vanger 0:b86d15c6ba29 6851 return FATAL_ERROR;
Vanger 0:b86d15c6ba29 6852 break;
Vanger 0:b86d15c6ba29 6853
Vanger 0:b86d15c6ba29 6854 default:
Vanger 0:b86d15c6ba29 6855 CYASSL_ERROR(UNKNOWN_RECORD_TYPE);
Vanger 0:b86d15c6ba29 6856 return UNKNOWN_RECORD_TYPE;
Vanger 0:b86d15c6ba29 6857 }
Vanger 0:b86d15c6ba29 6858
Vanger 0:b86d15c6ba29 6859 ssl->options.processReply = doProcessInit;
Vanger 0:b86d15c6ba29 6860
Vanger 0:b86d15c6ba29 6861 /* input exhausted? */
Vanger 0:b86d15c6ba29 6862 if (ssl->buffers.inputBuffer.idx == ssl->buffers.inputBuffer.length)
Vanger 0:b86d15c6ba29 6863 return 0;
Vanger 0:b86d15c6ba29 6864 /* more messages per record */
Vanger 0:b86d15c6ba29 6865 else if ((ssl->buffers.inputBuffer.idx - startIdx) < ssl->curSize) {
Vanger 0:b86d15c6ba29 6866 CYASSL_MSG("More messages in record");
Vanger 0:b86d15c6ba29 6867 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 6868 /* read-ahead but dtls doesn't bundle messages per record */
Vanger 0:b86d15c6ba29 6869 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 6870 ssl->options.processReply = doProcessInit;
Vanger 0:b86d15c6ba29 6871 continue;
Vanger 0:b86d15c6ba29 6872 }
Vanger 0:b86d15c6ba29 6873 #endif
Vanger 0:b86d15c6ba29 6874 ssl->options.processReply = runProcessingOneMessage;
Vanger 0:b86d15c6ba29 6875
Vanger 0:b86d15c6ba29 6876 if (ssl->keys.encryptionOn) {
Vanger 0:b86d15c6ba29 6877 CYASSL_MSG("Bundled encrypted messages, remove middle pad");
Vanger 0:b86d15c6ba29 6878 ssl->buffers.inputBuffer.idx -= ssl->keys.padSz;
Vanger 0:b86d15c6ba29 6879 }
Vanger 0:b86d15c6ba29 6880
Vanger 0:b86d15c6ba29 6881 continue;
Vanger 0:b86d15c6ba29 6882 }
Vanger 0:b86d15c6ba29 6883 /* more records */
Vanger 0:b86d15c6ba29 6884 else {
Vanger 0:b86d15c6ba29 6885 CYASSL_MSG("More records in input");
Vanger 0:b86d15c6ba29 6886 ssl->options.processReply = doProcessInit;
Vanger 0:b86d15c6ba29 6887 continue;
Vanger 0:b86d15c6ba29 6888 }
Vanger 0:b86d15c6ba29 6889
Vanger 0:b86d15c6ba29 6890 default:
Vanger 0:b86d15c6ba29 6891 CYASSL_MSG("Bad process input state, programming error");
Vanger 0:b86d15c6ba29 6892 return INPUT_CASE_ERROR;
Vanger 0:b86d15c6ba29 6893 }
Vanger 0:b86d15c6ba29 6894 }
Vanger 0:b86d15c6ba29 6895 }
Vanger 0:b86d15c6ba29 6896
Vanger 0:b86d15c6ba29 6897
Vanger 0:b86d15c6ba29 6898 int SendChangeCipher(CYASSL* ssl)
Vanger 0:b86d15c6ba29 6899 {
Vanger 0:b86d15c6ba29 6900 byte *output;
Vanger 0:b86d15c6ba29 6901 int sendSz = RECORD_HEADER_SZ + ENUM_LEN;
Vanger 0:b86d15c6ba29 6902 int idx = RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 6903 int ret;
Vanger 0:b86d15c6ba29 6904
Vanger 0:b86d15c6ba29 6905 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 6906 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 6907 sendSz += DTLS_RECORD_EXTRA;
Vanger 0:b86d15c6ba29 6908 idx += DTLS_RECORD_EXTRA;
Vanger 0:b86d15c6ba29 6909 }
Vanger 0:b86d15c6ba29 6910 #endif
Vanger 0:b86d15c6ba29 6911
Vanger 0:b86d15c6ba29 6912 /* are we in scr */
Vanger 0:b86d15c6ba29 6913 if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
Vanger 0:b86d15c6ba29 6914 sendSz += MAX_MSG_EXTRA;
Vanger 0:b86d15c6ba29 6915 }
Vanger 0:b86d15c6ba29 6916
Vanger 0:b86d15c6ba29 6917 /* check for avalaible size */
Vanger 0:b86d15c6ba29 6918 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
Vanger 0:b86d15c6ba29 6919 return ret;
Vanger 0:b86d15c6ba29 6920
Vanger 0:b86d15c6ba29 6921 /* get ouput buffer */
Vanger 0:b86d15c6ba29 6922 output = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 6923 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 6924
Vanger 0:b86d15c6ba29 6925 AddRecordHeader(output, 1, change_cipher_spec, ssl);
Vanger 0:b86d15c6ba29 6926
Vanger 0:b86d15c6ba29 6927 output[idx] = 1; /* turn it on */
Vanger 0:b86d15c6ba29 6928
Vanger 0:b86d15c6ba29 6929 if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
Vanger 0:b86d15c6ba29 6930 byte input[ENUM_LEN];
Vanger 0:b86d15c6ba29 6931 int inputSz = ENUM_LEN;
Vanger 0:b86d15c6ba29 6932
Vanger 0:b86d15c6ba29 6933 input[0] = 1; /* turn it on */
Vanger 0:b86d15c6ba29 6934 sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
Vanger 0:b86d15c6ba29 6935 change_cipher_spec);
Vanger 0:b86d15c6ba29 6936 if (sendSz < 0)
Vanger 0:b86d15c6ba29 6937 return sendSz;
Vanger 0:b86d15c6ba29 6938 }
Vanger 0:b86d15c6ba29 6939
Vanger 0:b86d15c6ba29 6940 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 6941 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 6942 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
Vanger 0:b86d15c6ba29 6943 return ret;
Vanger 0:b86d15c6ba29 6944 }
Vanger 0:b86d15c6ba29 6945 #endif
Vanger 0:b86d15c6ba29 6946 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 6947 if (ssl->hsInfoOn) AddPacketName("ChangeCipher", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 6948 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 6949 AddPacketInfo("ChangeCipher", &ssl->timeoutInfo, output, sendSz,
Vanger 0:b86d15c6ba29 6950 ssl->heap);
Vanger 0:b86d15c6ba29 6951 #endif
Vanger 0:b86d15c6ba29 6952 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 6953
Vanger 0:b86d15c6ba29 6954 if (ssl->options.groupMessages)
Vanger 0:b86d15c6ba29 6955 return 0;
Vanger 0:b86d15c6ba29 6956 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 6957 else if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 6958 /* If using DTLS, force the ChangeCipherSpec message to be in the
Vanger 0:b86d15c6ba29 6959 * same datagram as the finished message. */
Vanger 0:b86d15c6ba29 6960 return 0;
Vanger 0:b86d15c6ba29 6961 }
Vanger 0:b86d15c6ba29 6962 #endif
Vanger 0:b86d15c6ba29 6963 else
Vanger 0:b86d15c6ba29 6964 return SendBuffered(ssl);
Vanger 0:b86d15c6ba29 6965 }
Vanger 0:b86d15c6ba29 6966
Vanger 0:b86d15c6ba29 6967
Vanger 0:b86d15c6ba29 6968 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 6969 static int SSL_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
Vanger 0:b86d15c6ba29 6970 int content, int verify)
Vanger 0:b86d15c6ba29 6971 {
Vanger 0:b86d15c6ba29 6972 byte result[MAX_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 6973 word32 digestSz = ssl->specs.hash_size; /* actual sizes */
Vanger 0:b86d15c6ba29 6974 word32 padSz = ssl->specs.pad_size;
Vanger 0:b86d15c6ba29 6975 int ret = 0;
Vanger 0:b86d15c6ba29 6976
Vanger 0:b86d15c6ba29 6977 Md5 md5;
Vanger 0:b86d15c6ba29 6978 Sha sha;
Vanger 0:b86d15c6ba29 6979
Vanger 0:b86d15c6ba29 6980 /* data */
Vanger 0:b86d15c6ba29 6981 byte seq[SEQ_SZ];
Vanger 0:b86d15c6ba29 6982 byte conLen[ENUM_LEN + LENGTH_SZ]; /* content & length */
Vanger 0:b86d15c6ba29 6983 const byte* macSecret = CyaSSL_GetMacSecret(ssl, verify);
Vanger 0:b86d15c6ba29 6984
Vanger 0:b86d15c6ba29 6985 #ifdef HAVE_FUZZER
Vanger 0:b86d15c6ba29 6986 if (ssl->fuzzerCb)
Vanger 0:b86d15c6ba29 6987 ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx);
Vanger 0:b86d15c6ba29 6988 #endif
Vanger 0:b86d15c6ba29 6989
Vanger 0:b86d15c6ba29 6990 XMEMSET(seq, 0, SEQ_SZ);
Vanger 0:b86d15c6ba29 6991 conLen[0] = (byte)content;
Vanger 0:b86d15c6ba29 6992 c16toa((word16)sz, &conLen[ENUM_LEN]);
Vanger 0:b86d15c6ba29 6993 c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]);
Vanger 0:b86d15c6ba29 6994
Vanger 0:b86d15c6ba29 6995 if (ssl->specs.mac_algorithm == md5_mac) {
Vanger 0:b86d15c6ba29 6996 InitMd5(&md5);
Vanger 0:b86d15c6ba29 6997 /* inner */
Vanger 0:b86d15c6ba29 6998 Md5Update(&md5, macSecret, digestSz);
Vanger 0:b86d15c6ba29 6999 Md5Update(&md5, PAD1, padSz);
Vanger 0:b86d15c6ba29 7000 Md5Update(&md5, seq, SEQ_SZ);
Vanger 0:b86d15c6ba29 7001 Md5Update(&md5, conLen, sizeof(conLen));
Vanger 0:b86d15c6ba29 7002 /* in buffer */
Vanger 0:b86d15c6ba29 7003 Md5Update(&md5, in, sz);
Vanger 0:b86d15c6ba29 7004 Md5Final(&md5, result);
Vanger 0:b86d15c6ba29 7005 /* outer */
Vanger 0:b86d15c6ba29 7006 Md5Update(&md5, macSecret, digestSz);
Vanger 0:b86d15c6ba29 7007 Md5Update(&md5, PAD2, padSz);
Vanger 0:b86d15c6ba29 7008 Md5Update(&md5, result, digestSz);
Vanger 0:b86d15c6ba29 7009 Md5Final(&md5, digest);
Vanger 0:b86d15c6ba29 7010 }
Vanger 0:b86d15c6ba29 7011 else {
Vanger 0:b86d15c6ba29 7012 ret = InitSha(&sha);
Vanger 0:b86d15c6ba29 7013 if (ret != 0)
Vanger 0:b86d15c6ba29 7014 return ret;
Vanger 0:b86d15c6ba29 7015 /* inner */
Vanger 0:b86d15c6ba29 7016 ShaUpdate(&sha, macSecret, digestSz);
Vanger 0:b86d15c6ba29 7017 ShaUpdate(&sha, PAD1, padSz);
Vanger 0:b86d15c6ba29 7018 ShaUpdate(&sha, seq, SEQ_SZ);
Vanger 0:b86d15c6ba29 7019 ShaUpdate(&sha, conLen, sizeof(conLen));
Vanger 0:b86d15c6ba29 7020 /* in buffer */
Vanger 0:b86d15c6ba29 7021 ShaUpdate(&sha, in, sz);
Vanger 0:b86d15c6ba29 7022 ShaFinal(&sha, result);
Vanger 0:b86d15c6ba29 7023 /* outer */
Vanger 0:b86d15c6ba29 7024 ShaUpdate(&sha, macSecret, digestSz);
Vanger 0:b86d15c6ba29 7025 ShaUpdate(&sha, PAD2, padSz);
Vanger 0:b86d15c6ba29 7026 ShaUpdate(&sha, result, digestSz);
Vanger 0:b86d15c6ba29 7027 ShaFinal(&sha, digest);
Vanger 0:b86d15c6ba29 7028 }
Vanger 0:b86d15c6ba29 7029 return 0;
Vanger 0:b86d15c6ba29 7030 }
Vanger 0:b86d15c6ba29 7031
Vanger 0:b86d15c6ba29 7032 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 7033 static void BuildMD5_CertVerify(CYASSL* ssl, byte* digest)
Vanger 0:b86d15c6ba29 7034 {
Vanger 0:b86d15c6ba29 7035 byte md5_result[MD5_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 7036
Vanger 0:b86d15c6ba29 7037 /* make md5 inner */
Vanger 0:b86d15c6ba29 7038 Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
Vanger 0:b86d15c6ba29 7039 Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
Vanger 0:b86d15c6ba29 7040 Md5Final(&ssl->hashMd5, md5_result);
Vanger 0:b86d15c6ba29 7041
Vanger 0:b86d15c6ba29 7042 /* make md5 outer */
Vanger 0:b86d15c6ba29 7043 Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
Vanger 0:b86d15c6ba29 7044 Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
Vanger 0:b86d15c6ba29 7045 Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 7046
Vanger 0:b86d15c6ba29 7047 Md5Final(&ssl->hashMd5, digest);
Vanger 0:b86d15c6ba29 7048 }
Vanger 0:b86d15c6ba29 7049
Vanger 0:b86d15c6ba29 7050
Vanger 0:b86d15c6ba29 7051 static void BuildSHA_CertVerify(CYASSL* ssl, byte* digest)
Vanger 0:b86d15c6ba29 7052 {
Vanger 0:b86d15c6ba29 7053 byte sha_result[SHA_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 7054
Vanger 0:b86d15c6ba29 7055 /* make sha inner */
Vanger 0:b86d15c6ba29 7056 ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
Vanger 0:b86d15c6ba29 7057 ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
Vanger 0:b86d15c6ba29 7058 ShaFinal(&ssl->hashSha, sha_result);
Vanger 0:b86d15c6ba29 7059
Vanger 0:b86d15c6ba29 7060 /* make sha outer */
Vanger 0:b86d15c6ba29 7061 ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
Vanger 0:b86d15c6ba29 7062 ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
Vanger 0:b86d15c6ba29 7063 ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 7064
Vanger 0:b86d15c6ba29 7065 ShaFinal(&ssl->hashSha, digest);
Vanger 0:b86d15c6ba29 7066 }
Vanger 0:b86d15c6ba29 7067 #endif /* NO_CERTS */
Vanger 0:b86d15c6ba29 7068 #endif /* NO_OLD_TLS */
Vanger 0:b86d15c6ba29 7069
Vanger 0:b86d15c6ba29 7070
Vanger 0:b86d15c6ba29 7071 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 7072
Vanger 0:b86d15c6ba29 7073 static int BuildCertHashes(CYASSL* ssl, Hashes* hashes)
Vanger 0:b86d15c6ba29 7074 {
Vanger 0:b86d15c6ba29 7075 /* store current states, building requires get_digest which resets state */
Vanger 0:b86d15c6ba29 7076 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 7077 Md5 md5 = ssl->hashMd5;
Vanger 0:b86d15c6ba29 7078 Sha sha = ssl->hashSha;
Vanger 0:b86d15c6ba29 7079 #endif
Vanger 0:b86d15c6ba29 7080 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 7081 Sha256 sha256 = ssl->hashSha256;
Vanger 0:b86d15c6ba29 7082 #endif
Vanger 0:b86d15c6ba29 7083 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 7084 Sha384 sha384 = ssl->hashSha384;
Vanger 0:b86d15c6ba29 7085 #endif
Vanger 0:b86d15c6ba29 7086
Vanger 0:b86d15c6ba29 7087 if (ssl->options.tls) {
Vanger 0:b86d15c6ba29 7088 #if ! defined( NO_OLD_TLS )
Vanger 0:b86d15c6ba29 7089 Md5Final(&ssl->hashMd5, hashes->md5);
Vanger 0:b86d15c6ba29 7090 ShaFinal(&ssl->hashSha, hashes->sha);
Vanger 0:b86d15c6ba29 7091 #endif
Vanger 0:b86d15c6ba29 7092 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 7093 int ret;
Vanger 0:b86d15c6ba29 7094
Vanger 0:b86d15c6ba29 7095 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 7096 ret = Sha256Final(&ssl->hashSha256, hashes->sha256);
Vanger 0:b86d15c6ba29 7097 if (ret != 0)
Vanger 0:b86d15c6ba29 7098 return ret;
Vanger 0:b86d15c6ba29 7099 #endif
Vanger 0:b86d15c6ba29 7100 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 7101 ret = Sha384Final(&ssl->hashSha384, hashes->sha384);
Vanger 0:b86d15c6ba29 7102 if (ret != 0)
Vanger 0:b86d15c6ba29 7103 return ret;
Vanger 0:b86d15c6ba29 7104 #endif
Vanger 0:b86d15c6ba29 7105 }
Vanger 0:b86d15c6ba29 7106 }
Vanger 0:b86d15c6ba29 7107 #if ! defined( NO_OLD_TLS )
Vanger 0:b86d15c6ba29 7108 else {
Vanger 0:b86d15c6ba29 7109 BuildMD5_CertVerify(ssl, hashes->md5);
Vanger 0:b86d15c6ba29 7110 BuildSHA_CertVerify(ssl, hashes->sha);
Vanger 0:b86d15c6ba29 7111 }
Vanger 0:b86d15c6ba29 7112
Vanger 0:b86d15c6ba29 7113 /* restore */
Vanger 0:b86d15c6ba29 7114 ssl->hashMd5 = md5;
Vanger 0:b86d15c6ba29 7115 ssl->hashSha = sha;
Vanger 0:b86d15c6ba29 7116 #endif
Vanger 0:b86d15c6ba29 7117 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 7118 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 7119 ssl->hashSha256 = sha256;
Vanger 0:b86d15c6ba29 7120 #endif
Vanger 0:b86d15c6ba29 7121 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 7122 ssl->hashSha384 = sha384;
Vanger 0:b86d15c6ba29 7123 #endif
Vanger 0:b86d15c6ba29 7124 }
Vanger 0:b86d15c6ba29 7125
Vanger 0:b86d15c6ba29 7126 return 0;
Vanger 0:b86d15c6ba29 7127 }
Vanger 0:b86d15c6ba29 7128
Vanger 0:b86d15c6ba29 7129 #endif /* CYASSL_LEANPSK */
Vanger 0:b86d15c6ba29 7130
Vanger 0:b86d15c6ba29 7131 /* Build SSL Message, encrypted */
Vanger 0:b86d15c6ba29 7132 static int BuildMessage(CYASSL* ssl, byte* output, int outSz,
Vanger 0:b86d15c6ba29 7133 const byte* input, int inSz, int type)
Vanger 0:b86d15c6ba29 7134 {
Vanger 0:b86d15c6ba29 7135 #ifdef HAVE_TRUNCATED_HMAC
Vanger 0:b86d15c6ba29 7136 word32 digestSz = min(ssl->specs.hash_size,
Vanger 0:b86d15c6ba29 7137 ssl->truncated_hmac ? TRUNCATED_HMAC_SZ : ssl->specs.hash_size);
Vanger 0:b86d15c6ba29 7138 #else
Vanger 0:b86d15c6ba29 7139 word32 digestSz = ssl->specs.hash_size;
Vanger 0:b86d15c6ba29 7140 #endif
Vanger 0:b86d15c6ba29 7141 word32 sz = RECORD_HEADER_SZ + inSz + digestSz;
Vanger 0:b86d15c6ba29 7142 word32 pad = 0, i;
Vanger 0:b86d15c6ba29 7143 word32 idx = RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 7144 word32 ivSz = 0; /* TLSv1.1 IV */
Vanger 0:b86d15c6ba29 7145 word32 headerSz = RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 7146 word16 size;
Vanger 0:b86d15c6ba29 7147 byte iv[AES_BLOCK_SIZE]; /* max size */
Vanger 0:b86d15c6ba29 7148 int ret = 0;
Vanger 0:b86d15c6ba29 7149 int atomicUser = 0;
Vanger 0:b86d15c6ba29 7150
Vanger 0:b86d15c6ba29 7151 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7152 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 7153 sz += DTLS_RECORD_EXTRA;
Vanger 0:b86d15c6ba29 7154 idx += DTLS_RECORD_EXTRA;
Vanger 0:b86d15c6ba29 7155 headerSz += DTLS_RECORD_EXTRA;
Vanger 0:b86d15c6ba29 7156 }
Vanger 0:b86d15c6ba29 7157 #endif
Vanger 0:b86d15c6ba29 7158
Vanger 0:b86d15c6ba29 7159 #ifdef ATOMIC_USER
Vanger 0:b86d15c6ba29 7160 if (ssl->ctx->MacEncryptCb)
Vanger 0:b86d15c6ba29 7161 atomicUser = 1;
Vanger 0:b86d15c6ba29 7162 #endif
Vanger 0:b86d15c6ba29 7163
Vanger 0:b86d15c6ba29 7164 if (ssl->specs.cipher_type == block) {
Vanger 0:b86d15c6ba29 7165 word32 blockSz = ssl->specs.block_size;
Vanger 0:b86d15c6ba29 7166 if (ssl->options.tls1_1) {
Vanger 0:b86d15c6ba29 7167 ivSz = blockSz;
Vanger 0:b86d15c6ba29 7168 sz += ivSz;
Vanger 0:b86d15c6ba29 7169
Vanger 0:b86d15c6ba29 7170 if (ivSz > (word32)sizeof(iv))
Vanger 0:b86d15c6ba29 7171 return BUFFER_E;
Vanger 0:b86d15c6ba29 7172
Vanger 0:b86d15c6ba29 7173 ret = RNG_GenerateBlock(ssl->rng, iv, ivSz);
Vanger 0:b86d15c6ba29 7174 if (ret != 0)
Vanger 0:b86d15c6ba29 7175 return ret;
Vanger 0:b86d15c6ba29 7176
Vanger 0:b86d15c6ba29 7177 }
Vanger 0:b86d15c6ba29 7178 sz += 1; /* pad byte */
Vanger 0:b86d15c6ba29 7179 pad = (sz - headerSz) % blockSz;
Vanger 0:b86d15c6ba29 7180 pad = blockSz - pad;
Vanger 0:b86d15c6ba29 7181 sz += pad;
Vanger 0:b86d15c6ba29 7182 }
Vanger 0:b86d15c6ba29 7183
Vanger 0:b86d15c6ba29 7184 #ifdef HAVE_AEAD
Vanger 0:b86d15c6ba29 7185 if (ssl->specs.cipher_type == aead) {
Vanger 0:b86d15c6ba29 7186 if (ssl->specs.bulk_cipher_algorithm != cyassl_chacha)
Vanger 0:b86d15c6ba29 7187 ivSz = AEAD_EXP_IV_SZ;
Vanger 0:b86d15c6ba29 7188
Vanger 0:b86d15c6ba29 7189 sz += (ivSz + ssl->specs.aead_mac_size - digestSz);
Vanger 0:b86d15c6ba29 7190 XMEMCPY(iv, ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
Vanger 0:b86d15c6ba29 7191 }
Vanger 0:b86d15c6ba29 7192 #endif
Vanger 0:b86d15c6ba29 7193 if (sz > (word32)outSz) {
Vanger 0:b86d15c6ba29 7194 CYASSL_MSG("Oops, want to write past output buffer size");
Vanger 0:b86d15c6ba29 7195 return BUFFER_E;
Vanger 0:b86d15c6ba29 7196 }
Vanger 0:b86d15c6ba29 7197 size = (word16)(sz - headerSz); /* include mac and digest */
Vanger 0:b86d15c6ba29 7198 AddRecordHeader(output, size, (byte)type, ssl);
Vanger 0:b86d15c6ba29 7199
Vanger 0:b86d15c6ba29 7200 /* write to output */
Vanger 0:b86d15c6ba29 7201 if (ivSz) {
Vanger 0:b86d15c6ba29 7202 XMEMCPY(output + idx, iv, min(ivSz, sizeof(iv)));
Vanger 0:b86d15c6ba29 7203 idx += ivSz;
Vanger 0:b86d15c6ba29 7204 }
Vanger 0:b86d15c6ba29 7205 XMEMCPY(output + idx, input, inSz);
Vanger 0:b86d15c6ba29 7206 idx += inSz;
Vanger 0:b86d15c6ba29 7207
Vanger 0:b86d15c6ba29 7208 if (type == handshake) {
Vanger 0:b86d15c6ba29 7209 ret = HashOutput(ssl, output, headerSz + inSz, ivSz);
Vanger 0:b86d15c6ba29 7210 if (ret != 0)
Vanger 0:b86d15c6ba29 7211 return ret;
Vanger 0:b86d15c6ba29 7212 }
Vanger 0:b86d15c6ba29 7213
Vanger 0:b86d15c6ba29 7214 if (ssl->specs.cipher_type == block) {
Vanger 0:b86d15c6ba29 7215 word32 tmpIdx = idx + digestSz;
Vanger 0:b86d15c6ba29 7216
Vanger 0:b86d15c6ba29 7217 for (i = 0; i <= pad; i++)
Vanger 0:b86d15c6ba29 7218 output[tmpIdx++] = (byte)pad; /* pad byte gets pad value too */
Vanger 0:b86d15c6ba29 7219 }
Vanger 0:b86d15c6ba29 7220
Vanger 0:b86d15c6ba29 7221 if (atomicUser) { /* User Record Layer Callback handling */
Vanger 0:b86d15c6ba29 7222 #ifdef ATOMIC_USER
Vanger 0:b86d15c6ba29 7223 if ( (ret = ssl->ctx->MacEncryptCb(ssl, output + idx,
Vanger 0:b86d15c6ba29 7224 output + headerSz + ivSz, inSz, type, 0,
Vanger 0:b86d15c6ba29 7225 output + headerSz, output + headerSz, size,
Vanger 0:b86d15c6ba29 7226 ssl->MacEncryptCtx)) != 0)
Vanger 0:b86d15c6ba29 7227 return ret;
Vanger 0:b86d15c6ba29 7228 #endif
Vanger 0:b86d15c6ba29 7229 }
Vanger 0:b86d15c6ba29 7230 else {
Vanger 0:b86d15c6ba29 7231 if (ssl->specs.cipher_type != aead) {
Vanger 0:b86d15c6ba29 7232 #ifdef HAVE_TRUNCATED_HMAC
Vanger 0:b86d15c6ba29 7233 if (ssl->truncated_hmac && ssl->specs.hash_size > digestSz) {
Vanger 0:b86d15c6ba29 7234 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 7235 byte* hmac = NULL;
Vanger 0:b86d15c6ba29 7236 #else
Vanger 0:b86d15c6ba29 7237 byte hmac[MAX_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 7238 #endif
Vanger 0:b86d15c6ba29 7239
Vanger 0:b86d15c6ba29 7240 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 7241 hmac = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL,
Vanger 0:b86d15c6ba29 7242 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 7243 if (hmac == NULL)
Vanger 0:b86d15c6ba29 7244 return MEMORY_E;
Vanger 0:b86d15c6ba29 7245 #endif
Vanger 0:b86d15c6ba29 7246
Vanger 0:b86d15c6ba29 7247 ret = ssl->hmac(ssl, hmac, output + headerSz + ivSz, inSz,
Vanger 0:b86d15c6ba29 7248 type, 0);
Vanger 0:b86d15c6ba29 7249 XMEMCPY(output + idx, hmac, digestSz);
Vanger 0:b86d15c6ba29 7250
Vanger 0:b86d15c6ba29 7251 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 7252 XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 7253 #endif
Vanger 0:b86d15c6ba29 7254 } else
Vanger 0:b86d15c6ba29 7255 #endif
Vanger 0:b86d15c6ba29 7256 ret = ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz,
Vanger 0:b86d15c6ba29 7257 type, 0);
Vanger 0:b86d15c6ba29 7258 }
Vanger 0:b86d15c6ba29 7259 if (ret != 0)
Vanger 0:b86d15c6ba29 7260 return ret;
Vanger 0:b86d15c6ba29 7261
Vanger 0:b86d15c6ba29 7262 if ( (ret = Encrypt(ssl, output + headerSz, output+headerSz,size)) != 0)
Vanger 0:b86d15c6ba29 7263 return ret;
Vanger 0:b86d15c6ba29 7264 }
Vanger 0:b86d15c6ba29 7265
Vanger 0:b86d15c6ba29 7266 return sz;
Vanger 0:b86d15c6ba29 7267 }
Vanger 0:b86d15c6ba29 7268
Vanger 0:b86d15c6ba29 7269
Vanger 0:b86d15c6ba29 7270 int SendFinished(CYASSL* ssl)
Vanger 0:b86d15c6ba29 7271 {
Vanger 0:b86d15c6ba29 7272 int sendSz,
Vanger 0:b86d15c6ba29 7273 finishedSz = ssl->options.tls ? TLS_FINISHED_SZ :
Vanger 0:b86d15c6ba29 7274 FINISHED_SZ;
Vanger 0:b86d15c6ba29 7275 byte input[FINISHED_SZ + DTLS_HANDSHAKE_HEADER_SZ]; /* max */
Vanger 0:b86d15c6ba29 7276 byte *output;
Vanger 0:b86d15c6ba29 7277 Hashes* hashes;
Vanger 0:b86d15c6ba29 7278 int ret;
Vanger 0:b86d15c6ba29 7279 int headerSz = HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 7280 int outputSz;
Vanger 0:b86d15c6ba29 7281
Vanger 0:b86d15c6ba29 7282 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7283 word32 sequence_number = ssl->keys.dtls_sequence_number;
Vanger 0:b86d15c6ba29 7284 word16 epoch = ssl->keys.dtls_epoch;
Vanger 0:b86d15c6ba29 7285 #endif
Vanger 0:b86d15c6ba29 7286
Vanger 0:b86d15c6ba29 7287 /* setup encrypt keys */
Vanger 0:b86d15c6ba29 7288 if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
Vanger 0:b86d15c6ba29 7289 return ret;
Vanger 0:b86d15c6ba29 7290
Vanger 0:b86d15c6ba29 7291 /* check for available size */
Vanger 0:b86d15c6ba29 7292 outputSz = sizeof(input) + MAX_MSG_EXTRA;
Vanger 0:b86d15c6ba29 7293 if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
Vanger 0:b86d15c6ba29 7294 return ret;
Vanger 0:b86d15c6ba29 7295
Vanger 0:b86d15c6ba29 7296 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7297 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 7298 /* Send Finished message with the next epoch, but don't commit that
Vanger 0:b86d15c6ba29 7299 * change until the other end confirms its reception. */
Vanger 0:b86d15c6ba29 7300 headerSz += DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 7301 ssl->keys.dtls_epoch++;
Vanger 0:b86d15c6ba29 7302 ssl->keys.dtls_sequence_number = 0; /* reset after epoch change */
Vanger 0:b86d15c6ba29 7303 }
Vanger 0:b86d15c6ba29 7304 #endif
Vanger 0:b86d15c6ba29 7305
Vanger 0:b86d15c6ba29 7306 /* get ouput buffer */
Vanger 0:b86d15c6ba29 7307 output = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 7308 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 7309
Vanger 0:b86d15c6ba29 7310 AddHandShakeHeader(input, finishedSz, finished, ssl);
Vanger 0:b86d15c6ba29 7311
Vanger 0:b86d15c6ba29 7312 /* make finished hashes */
Vanger 0:b86d15c6ba29 7313 hashes = (Hashes*)&input[headerSz];
Vanger 0:b86d15c6ba29 7314 ret = BuildFinished(ssl, hashes,
Vanger 0:b86d15c6ba29 7315 ssl->options.side == CYASSL_CLIENT_END ? client : server);
Vanger 0:b86d15c6ba29 7316 if (ret != 0) return ret;
Vanger 0:b86d15c6ba29 7317
Vanger 0:b86d15c6ba29 7318 #ifdef HAVE_SECURE_RENEGOTIATION
Vanger 0:b86d15c6ba29 7319 if (ssl->secure_renegotiation) {
Vanger 0:b86d15c6ba29 7320 if (ssl->options.side == CYASSL_CLIENT_END)
Vanger 0:b86d15c6ba29 7321 XMEMCPY(ssl->secure_renegotiation->client_verify_data, hashes,
Vanger 0:b86d15c6ba29 7322 TLS_FINISHED_SZ);
Vanger 0:b86d15c6ba29 7323 else
Vanger 0:b86d15c6ba29 7324 XMEMCPY(ssl->secure_renegotiation->server_verify_data, hashes,
Vanger 0:b86d15c6ba29 7325 TLS_FINISHED_SZ);
Vanger 0:b86d15c6ba29 7326 }
Vanger 0:b86d15c6ba29 7327 #endif
Vanger 0:b86d15c6ba29 7328
Vanger 0:b86d15c6ba29 7329 sendSz = BuildMessage(ssl, output, outputSz, input, headerSz + finishedSz,
Vanger 0:b86d15c6ba29 7330 handshake);
Vanger 0:b86d15c6ba29 7331 if (sendSz < 0)
Vanger 0:b86d15c6ba29 7332 return BUILD_MSG_ERROR;
Vanger 0:b86d15c6ba29 7333
Vanger 0:b86d15c6ba29 7334 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7335 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 7336 ssl->keys.dtls_epoch = epoch;
Vanger 0:b86d15c6ba29 7337 ssl->keys.dtls_sequence_number = sequence_number;
Vanger 0:b86d15c6ba29 7338 }
Vanger 0:b86d15c6ba29 7339 #endif
Vanger 0:b86d15c6ba29 7340
Vanger 0:b86d15c6ba29 7341 if (!ssl->options.resuming) {
Vanger 0:b86d15c6ba29 7342 #ifndef NO_SESSION_CACHE
Vanger 0:b86d15c6ba29 7343 AddSession(ssl); /* just try */
Vanger 0:b86d15c6ba29 7344 #endif
Vanger 0:b86d15c6ba29 7345 if (ssl->options.side == CYASSL_CLIENT_END) {
Vanger 0:b86d15c6ba29 7346 ret = BuildFinished(ssl, &ssl->verifyHashes, server);
Vanger 0:b86d15c6ba29 7347 if (ret != 0) return ret;
Vanger 0:b86d15c6ba29 7348 }
Vanger 0:b86d15c6ba29 7349 else {
Vanger 0:b86d15c6ba29 7350 ssl->options.handShakeState = HANDSHAKE_DONE;
Vanger 0:b86d15c6ba29 7351 ssl->options.handShakeDone = 1;
Vanger 0:b86d15c6ba29 7352 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7353 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 7354 /* Other side will soon receive our Finished, go to next
Vanger 0:b86d15c6ba29 7355 * epoch. */
Vanger 0:b86d15c6ba29 7356 ssl->keys.dtls_epoch++;
Vanger 0:b86d15c6ba29 7357 ssl->keys.dtls_sequence_number = 1;
Vanger 0:b86d15c6ba29 7358 }
Vanger 0:b86d15c6ba29 7359 #endif
Vanger 0:b86d15c6ba29 7360 }
Vanger 0:b86d15c6ba29 7361 }
Vanger 0:b86d15c6ba29 7362 else {
Vanger 0:b86d15c6ba29 7363 if (ssl->options.side == CYASSL_CLIENT_END) {
Vanger 0:b86d15c6ba29 7364 ssl->options.handShakeState = HANDSHAKE_DONE;
Vanger 0:b86d15c6ba29 7365 ssl->options.handShakeDone = 1;
Vanger 0:b86d15c6ba29 7366 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7367 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 7368 /* Other side will soon receive our Finished, go to next
Vanger 0:b86d15c6ba29 7369 * epoch. */
Vanger 0:b86d15c6ba29 7370 ssl->keys.dtls_epoch++;
Vanger 0:b86d15c6ba29 7371 ssl->keys.dtls_sequence_number = 1;
Vanger 0:b86d15c6ba29 7372 }
Vanger 0:b86d15c6ba29 7373 #endif
Vanger 0:b86d15c6ba29 7374 }
Vanger 0:b86d15c6ba29 7375 else {
Vanger 0:b86d15c6ba29 7376 ret = BuildFinished(ssl, &ssl->verifyHashes, client);
Vanger 0:b86d15c6ba29 7377 if (ret != 0) return ret;
Vanger 0:b86d15c6ba29 7378 }
Vanger 0:b86d15c6ba29 7379 }
Vanger 0:b86d15c6ba29 7380 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7381 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 7382 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
Vanger 0:b86d15c6ba29 7383 return ret;
Vanger 0:b86d15c6ba29 7384 }
Vanger 0:b86d15c6ba29 7385 #endif
Vanger 0:b86d15c6ba29 7386
Vanger 0:b86d15c6ba29 7387 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 7388 if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 7389 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 7390 AddPacketInfo("Finished", &ssl->timeoutInfo, output, sendSz,
Vanger 0:b86d15c6ba29 7391 ssl->heap);
Vanger 0:b86d15c6ba29 7392 #endif
Vanger 0:b86d15c6ba29 7393
Vanger 0:b86d15c6ba29 7394 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 7395
Vanger 0:b86d15c6ba29 7396 return SendBuffered(ssl);
Vanger 0:b86d15c6ba29 7397 }
Vanger 0:b86d15c6ba29 7398
Vanger 0:b86d15c6ba29 7399 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 7400 int SendCertificate(CYASSL* ssl)
Vanger 0:b86d15c6ba29 7401 {
Vanger 0:b86d15c6ba29 7402 int sendSz, length, ret = 0;
Vanger 0:b86d15c6ba29 7403 word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 7404 word32 certSz, listSz;
Vanger 0:b86d15c6ba29 7405 byte* output = 0;
Vanger 0:b86d15c6ba29 7406
Vanger 0:b86d15c6ba29 7407 if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher)
Vanger 0:b86d15c6ba29 7408 return 0; /* not needed */
Vanger 0:b86d15c6ba29 7409
Vanger 0:b86d15c6ba29 7410 if (ssl->options.sendVerify == SEND_BLANK_CERT) {
Vanger 0:b86d15c6ba29 7411 certSz = 0;
Vanger 0:b86d15c6ba29 7412 length = CERT_HEADER_SZ;
Vanger 0:b86d15c6ba29 7413 listSz = 0;
Vanger 0:b86d15c6ba29 7414 }
Vanger 0:b86d15c6ba29 7415 else {
Vanger 0:b86d15c6ba29 7416 certSz = ssl->buffers.certificate.length;
Vanger 0:b86d15c6ba29 7417 /* list + cert size */
Vanger 0:b86d15c6ba29 7418 length = certSz + 2 * CERT_HEADER_SZ;
Vanger 0:b86d15c6ba29 7419 listSz = certSz + CERT_HEADER_SZ;
Vanger 0:b86d15c6ba29 7420
Vanger 0:b86d15c6ba29 7421 /* may need to send rest of chain, already has leading size(s) */
Vanger 0:b86d15c6ba29 7422 if (ssl->buffers.certChain.buffer) {
Vanger 0:b86d15c6ba29 7423 length += ssl->buffers.certChain.length;
Vanger 0:b86d15c6ba29 7424 listSz += ssl->buffers.certChain.length;
Vanger 0:b86d15c6ba29 7425 }
Vanger 0:b86d15c6ba29 7426 }
Vanger 0:b86d15c6ba29 7427 sendSz = length + RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 7428
Vanger 0:b86d15c6ba29 7429 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7430 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 7431 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 7432 i += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 7433 }
Vanger 0:b86d15c6ba29 7434 #endif
Vanger 0:b86d15c6ba29 7435
Vanger 0:b86d15c6ba29 7436 if (ssl->keys.encryptionOn)
Vanger 0:b86d15c6ba29 7437 sendSz += MAX_MSG_EXTRA;
Vanger 0:b86d15c6ba29 7438
Vanger 0:b86d15c6ba29 7439 /* check for available size */
Vanger 0:b86d15c6ba29 7440 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
Vanger 0:b86d15c6ba29 7441 return ret;
Vanger 0:b86d15c6ba29 7442
Vanger 0:b86d15c6ba29 7443 /* get ouput buffer */
Vanger 0:b86d15c6ba29 7444 output = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 7445 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 7446
Vanger 0:b86d15c6ba29 7447 AddHeaders(output, length, certificate, ssl);
Vanger 0:b86d15c6ba29 7448
Vanger 0:b86d15c6ba29 7449 /* list total */
Vanger 0:b86d15c6ba29 7450 c32to24(listSz, output + i);
Vanger 0:b86d15c6ba29 7451 i += CERT_HEADER_SZ;
Vanger 0:b86d15c6ba29 7452
Vanger 0:b86d15c6ba29 7453 /* member */
Vanger 0:b86d15c6ba29 7454 if (certSz) {
Vanger 0:b86d15c6ba29 7455 c32to24(certSz, output + i);
Vanger 0:b86d15c6ba29 7456 i += CERT_HEADER_SZ;
Vanger 0:b86d15c6ba29 7457 XMEMCPY(output + i, ssl->buffers.certificate.buffer, certSz);
Vanger 0:b86d15c6ba29 7458 i += certSz;
Vanger 0:b86d15c6ba29 7459
Vanger 0:b86d15c6ba29 7460 /* send rest of chain? */
Vanger 0:b86d15c6ba29 7461 if (ssl->buffers.certChain.buffer) {
Vanger 0:b86d15c6ba29 7462 XMEMCPY(output + i, ssl->buffers.certChain.buffer,
Vanger 0:b86d15c6ba29 7463 ssl->buffers.certChain.length);
Vanger 0:b86d15c6ba29 7464 i += ssl->buffers.certChain.length;
Vanger 0:b86d15c6ba29 7465 }
Vanger 0:b86d15c6ba29 7466 }
Vanger 0:b86d15c6ba29 7467
Vanger 0:b86d15c6ba29 7468 if (ssl->keys.encryptionOn) {
Vanger 0:b86d15c6ba29 7469 byte* input;
Vanger 0:b86d15c6ba29 7470 int inputSz = i - RECORD_HEADER_SZ; /* build msg adds rec hdr */
Vanger 0:b86d15c6ba29 7471
Vanger 0:b86d15c6ba29 7472 input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 7473 if (input == NULL)
Vanger 0:b86d15c6ba29 7474 return MEMORY_E;
Vanger 0:b86d15c6ba29 7475
Vanger 0:b86d15c6ba29 7476 XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
Vanger 0:b86d15c6ba29 7477 sendSz = BuildMessage(ssl, output, sendSz, input,inputSz,handshake);
Vanger 0:b86d15c6ba29 7478 XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 7479
Vanger 0:b86d15c6ba29 7480 if (sendSz < 0)
Vanger 0:b86d15c6ba29 7481 return sendSz;
Vanger 0:b86d15c6ba29 7482 } else {
Vanger 0:b86d15c6ba29 7483 ret = HashOutput(ssl, output, sendSz, 0);
Vanger 0:b86d15c6ba29 7484 if (ret != 0)
Vanger 0:b86d15c6ba29 7485 return ret;
Vanger 0:b86d15c6ba29 7486 }
Vanger 0:b86d15c6ba29 7487
Vanger 0:b86d15c6ba29 7488 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7489 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 7490 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
Vanger 0:b86d15c6ba29 7491 return ret;
Vanger 0:b86d15c6ba29 7492 }
Vanger 0:b86d15c6ba29 7493 #endif
Vanger 0:b86d15c6ba29 7494
Vanger 0:b86d15c6ba29 7495 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 7496 if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 7497 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 7498 AddPacketInfo("Certificate", &ssl->timeoutInfo, output, sendSz,
Vanger 0:b86d15c6ba29 7499 ssl->heap);
Vanger 0:b86d15c6ba29 7500 #endif
Vanger 0:b86d15c6ba29 7501
Vanger 0:b86d15c6ba29 7502 if (ssl->options.side == CYASSL_SERVER_END)
Vanger 0:b86d15c6ba29 7503 ssl->options.serverState = SERVER_CERT_COMPLETE;
Vanger 0:b86d15c6ba29 7504
Vanger 0:b86d15c6ba29 7505 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 7506 if (ssl->options.groupMessages)
Vanger 0:b86d15c6ba29 7507 return 0;
Vanger 0:b86d15c6ba29 7508 else
Vanger 0:b86d15c6ba29 7509 return SendBuffered(ssl);
Vanger 0:b86d15c6ba29 7510 }
Vanger 0:b86d15c6ba29 7511
Vanger 0:b86d15c6ba29 7512
Vanger 0:b86d15c6ba29 7513 int SendCertificateRequest(CYASSL* ssl)
Vanger 0:b86d15c6ba29 7514 {
Vanger 0:b86d15c6ba29 7515 byte *output;
Vanger 0:b86d15c6ba29 7516 int ret;
Vanger 0:b86d15c6ba29 7517 int sendSz;
Vanger 0:b86d15c6ba29 7518 word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 7519
Vanger 0:b86d15c6ba29 7520 int typeTotal = 1; /* only 1 for now */
Vanger 0:b86d15c6ba29 7521 int reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ; /* add auth later */
Vanger 0:b86d15c6ba29 7522
Vanger 0:b86d15c6ba29 7523 if (IsAtLeastTLSv1_2(ssl))
Vanger 0:b86d15c6ba29 7524 reqSz += LENGTH_SZ + ssl->suites->hashSigAlgoSz;
Vanger 0:b86d15c6ba29 7525
Vanger 0:b86d15c6ba29 7526 if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher)
Vanger 0:b86d15c6ba29 7527 return 0; /* not needed */
Vanger 0:b86d15c6ba29 7528
Vanger 0:b86d15c6ba29 7529 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
Vanger 0:b86d15c6ba29 7530
Vanger 0:b86d15c6ba29 7531 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7532 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 7533 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 7534 i += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 7535 }
Vanger 0:b86d15c6ba29 7536 #endif
Vanger 0:b86d15c6ba29 7537 /* check for available size */
Vanger 0:b86d15c6ba29 7538 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
Vanger 0:b86d15c6ba29 7539 return ret;
Vanger 0:b86d15c6ba29 7540
Vanger 0:b86d15c6ba29 7541 /* get ouput buffer */
Vanger 0:b86d15c6ba29 7542 output = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 7543 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 7544
Vanger 0:b86d15c6ba29 7545 AddHeaders(output, reqSz, certificate_request, ssl);
Vanger 0:b86d15c6ba29 7546
Vanger 0:b86d15c6ba29 7547 /* write to output */
Vanger 0:b86d15c6ba29 7548 output[i++] = (byte)typeTotal; /* # of types */
Vanger 0:b86d15c6ba29 7549 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 7550 if (ssl->options.cipherSuite0 == ECC_BYTE &&
Vanger 0:b86d15c6ba29 7551 ssl->specs.sig_algo == ecc_dsa_sa_algo) {
Vanger 0:b86d15c6ba29 7552 output[i++] = ecdsa_sign;
Vanger 0:b86d15c6ba29 7553 } else
Vanger 0:b86d15c6ba29 7554 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 7555 {
Vanger 0:b86d15c6ba29 7556 output[i++] = rsa_sign;
Vanger 0:b86d15c6ba29 7557 }
Vanger 0:b86d15c6ba29 7558
Vanger 0:b86d15c6ba29 7559 /* supported hash/sig */
Vanger 0:b86d15c6ba29 7560 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 7561 c16toa(ssl->suites->hashSigAlgoSz, &output[i]);
Vanger 0:b86d15c6ba29 7562 i += LENGTH_SZ;
Vanger 0:b86d15c6ba29 7563
Vanger 0:b86d15c6ba29 7564 XMEMCPY(&output[i],
Vanger 0:b86d15c6ba29 7565 ssl->suites->hashSigAlgo, ssl->suites->hashSigAlgoSz);
Vanger 0:b86d15c6ba29 7566 i += ssl->suites->hashSigAlgoSz;
Vanger 0:b86d15c6ba29 7567 }
Vanger 0:b86d15c6ba29 7568
Vanger 0:b86d15c6ba29 7569 c16toa(0, &output[i]); /* auth's */
Vanger 0:b86d15c6ba29 7570 /* if add more to output, adjust i
Vanger 0:b86d15c6ba29 7571 i += REQ_HEADER_SZ; */
Vanger 0:b86d15c6ba29 7572
Vanger 0:b86d15c6ba29 7573 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7574 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 7575 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
Vanger 0:b86d15c6ba29 7576 return ret;
Vanger 0:b86d15c6ba29 7577 }
Vanger 0:b86d15c6ba29 7578 #endif
Vanger 0:b86d15c6ba29 7579
Vanger 0:b86d15c6ba29 7580 ret = HashOutput(ssl, output, sendSz, 0);
Vanger 0:b86d15c6ba29 7581 if (ret != 0)
Vanger 0:b86d15c6ba29 7582 return ret;
Vanger 0:b86d15c6ba29 7583
Vanger 0:b86d15c6ba29 7584 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 7585 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 7586 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 7587 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 7588 AddPacketInfo("CertificateRequest", &ssl->timeoutInfo, output,
Vanger 0:b86d15c6ba29 7589 sendSz, ssl->heap);
Vanger 0:b86d15c6ba29 7590 #endif
Vanger 0:b86d15c6ba29 7591 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 7592 if (ssl->options.groupMessages)
Vanger 0:b86d15c6ba29 7593 return 0;
Vanger 0:b86d15c6ba29 7594 else
Vanger 0:b86d15c6ba29 7595 return SendBuffered(ssl);
Vanger 0:b86d15c6ba29 7596 }
Vanger 0:b86d15c6ba29 7597 #endif /* !NO_CERTS */
Vanger 0:b86d15c6ba29 7598
Vanger 0:b86d15c6ba29 7599
Vanger 0:b86d15c6ba29 7600 int SendData(CYASSL* ssl, const void* data, int sz)
Vanger 0:b86d15c6ba29 7601 {
Vanger 0:b86d15c6ba29 7602 int sent = 0, /* plainText size */
Vanger 0:b86d15c6ba29 7603 sendSz,
Vanger 0:b86d15c6ba29 7604 ret,
Vanger 0:b86d15c6ba29 7605 dtlsExtra = 0;
Vanger 0:b86d15c6ba29 7606
Vanger 0:b86d15c6ba29 7607 if (ssl->error == WANT_WRITE)
Vanger 0:b86d15c6ba29 7608 ssl->error = 0;
Vanger 0:b86d15c6ba29 7609
Vanger 0:b86d15c6ba29 7610 if (ssl->options.handShakeState != HANDSHAKE_DONE) {
Vanger 0:b86d15c6ba29 7611 int err;
Vanger 0:b86d15c6ba29 7612 CYASSL_MSG("handshake not complete, trying to finish");
Vanger 0:b86d15c6ba29 7613 if ( (err = CyaSSL_negotiate(ssl)) != SSL_SUCCESS)
Vanger 0:b86d15c6ba29 7614 return err;
Vanger 0:b86d15c6ba29 7615 }
Vanger 0:b86d15c6ba29 7616
Vanger 0:b86d15c6ba29 7617 /* last time system socket output buffer was full, try again to send */
Vanger 0:b86d15c6ba29 7618 if (ssl->buffers.outputBuffer.length > 0) {
Vanger 0:b86d15c6ba29 7619 CYASSL_MSG("output buffer was full, trying to send again");
Vanger 0:b86d15c6ba29 7620 if ( (ssl->error = SendBuffered(ssl)) < 0) {
Vanger 0:b86d15c6ba29 7621 CYASSL_ERROR(ssl->error);
Vanger 0:b86d15c6ba29 7622 if (ssl->error == SOCKET_ERROR_E && ssl->options.connReset)
Vanger 0:b86d15c6ba29 7623 return 0; /* peer reset */
Vanger 0:b86d15c6ba29 7624 return ssl->error;
Vanger 0:b86d15c6ba29 7625 }
Vanger 0:b86d15c6ba29 7626 else {
Vanger 0:b86d15c6ba29 7627 /* advance sent to previous sent + plain size just sent */
Vanger 0:b86d15c6ba29 7628 sent = ssl->buffers.prevSent + ssl->buffers.plainSz;
Vanger 0:b86d15c6ba29 7629 CYASSL_MSG("sent write buffered data");
Vanger 0:b86d15c6ba29 7630
Vanger 0:b86d15c6ba29 7631 if (sent > sz) {
Vanger 0:b86d15c6ba29 7632 CYASSL_MSG("error: write() after WANT_WRITE with short size");
Vanger 0:b86d15c6ba29 7633 return ssl->error = BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 7634 }
Vanger 0:b86d15c6ba29 7635 }
Vanger 0:b86d15c6ba29 7636 }
Vanger 0:b86d15c6ba29 7637
Vanger 0:b86d15c6ba29 7638 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7639 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 7640 dtlsExtra = DTLS_RECORD_EXTRA;
Vanger 0:b86d15c6ba29 7641 }
Vanger 0:b86d15c6ba29 7642 #endif
Vanger 0:b86d15c6ba29 7643
Vanger 0:b86d15c6ba29 7644 for (;;) {
Vanger 0:b86d15c6ba29 7645 #ifdef HAVE_MAX_FRAGMENT
Vanger 0:b86d15c6ba29 7646 int len = min(sz - sent, min(ssl->max_fragment, OUTPUT_RECORD_SIZE));
Vanger 0:b86d15c6ba29 7647 #else
Vanger 0:b86d15c6ba29 7648 int len = min(sz - sent, OUTPUT_RECORD_SIZE);
Vanger 0:b86d15c6ba29 7649 #endif
Vanger 0:b86d15c6ba29 7650 byte* out;
Vanger 0:b86d15c6ba29 7651 byte* sendBuffer = (byte*)data + sent; /* may switch on comp */
Vanger 0:b86d15c6ba29 7652 int buffSz = len; /* may switch on comp */
Vanger 0:b86d15c6ba29 7653 int outputSz;
Vanger 0:b86d15c6ba29 7654 #ifdef HAVE_LIBZ
Vanger 0:b86d15c6ba29 7655 byte comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
Vanger 0:b86d15c6ba29 7656 #endif
Vanger 0:b86d15c6ba29 7657
Vanger 0:b86d15c6ba29 7658 if (sent == sz) break;
Vanger 0:b86d15c6ba29 7659
Vanger 0:b86d15c6ba29 7660 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7661 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 7662 len = min(len, MAX_UDP_SIZE);
Vanger 0:b86d15c6ba29 7663 buffSz = len;
Vanger 0:b86d15c6ba29 7664 }
Vanger 0:b86d15c6ba29 7665 #endif
Vanger 0:b86d15c6ba29 7666
Vanger 0:b86d15c6ba29 7667 /* check for available size */
Vanger 0:b86d15c6ba29 7668 outputSz = len + COMP_EXTRA + dtlsExtra + MAX_MSG_EXTRA;
Vanger 0:b86d15c6ba29 7669 if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
Vanger 0:b86d15c6ba29 7670 return ssl->error = ret;
Vanger 0:b86d15c6ba29 7671
Vanger 0:b86d15c6ba29 7672 /* get ouput buffer */
Vanger 0:b86d15c6ba29 7673 out = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 7674 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 7675
Vanger 0:b86d15c6ba29 7676 #ifdef HAVE_LIBZ
Vanger 0:b86d15c6ba29 7677 if (ssl->options.usingCompression) {
Vanger 0:b86d15c6ba29 7678 buffSz = myCompress(ssl, sendBuffer, buffSz, comp, sizeof(comp));
Vanger 0:b86d15c6ba29 7679 if (buffSz < 0) {
Vanger 0:b86d15c6ba29 7680 return buffSz;
Vanger 0:b86d15c6ba29 7681 }
Vanger 0:b86d15c6ba29 7682 sendBuffer = comp;
Vanger 0:b86d15c6ba29 7683 }
Vanger 0:b86d15c6ba29 7684 #endif
Vanger 0:b86d15c6ba29 7685 sendSz = BuildMessage(ssl, out, outputSz, sendBuffer, buffSz,
Vanger 0:b86d15c6ba29 7686 application_data);
Vanger 0:b86d15c6ba29 7687 if (sendSz < 0)
Vanger 0:b86d15c6ba29 7688 return BUILD_MSG_ERROR;
Vanger 0:b86d15c6ba29 7689
Vanger 0:b86d15c6ba29 7690 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 7691
Vanger 0:b86d15c6ba29 7692 if ( (ret = SendBuffered(ssl)) < 0) {
Vanger 0:b86d15c6ba29 7693 CYASSL_ERROR(ret);
Vanger 0:b86d15c6ba29 7694 /* store for next call if WANT_WRITE or user embedSend() that
Vanger 0:b86d15c6ba29 7695 doesn't present like WANT_WRITE */
Vanger 0:b86d15c6ba29 7696 ssl->buffers.plainSz = len;
Vanger 0:b86d15c6ba29 7697 ssl->buffers.prevSent = sent;
Vanger 0:b86d15c6ba29 7698 if (ret == SOCKET_ERROR_E && ssl->options.connReset)
Vanger 0:b86d15c6ba29 7699 return 0; /* peer reset */
Vanger 0:b86d15c6ba29 7700 return ssl->error = ret;
Vanger 0:b86d15c6ba29 7701 }
Vanger 0:b86d15c6ba29 7702
Vanger 0:b86d15c6ba29 7703 sent += len;
Vanger 0:b86d15c6ba29 7704
Vanger 0:b86d15c6ba29 7705 /* only one message per attempt */
Vanger 0:b86d15c6ba29 7706 if (ssl->options.partialWrite == 1) {
Vanger 0:b86d15c6ba29 7707 CYASSL_MSG("Paritial Write on, only sending one record");
Vanger 0:b86d15c6ba29 7708 break;
Vanger 0:b86d15c6ba29 7709 }
Vanger 0:b86d15c6ba29 7710 }
Vanger 0:b86d15c6ba29 7711
Vanger 0:b86d15c6ba29 7712 return sent;
Vanger 0:b86d15c6ba29 7713 }
Vanger 0:b86d15c6ba29 7714
Vanger 0:b86d15c6ba29 7715 /* process input data */
Vanger 0:b86d15c6ba29 7716 int ReceiveData(CYASSL* ssl, byte* output, int sz, int peek)
Vanger 0:b86d15c6ba29 7717 {
Vanger 0:b86d15c6ba29 7718 int size;
Vanger 0:b86d15c6ba29 7719
Vanger 0:b86d15c6ba29 7720 CYASSL_ENTER("ReceiveData()");
Vanger 0:b86d15c6ba29 7721
Vanger 0:b86d15c6ba29 7722 if (ssl->error == WANT_READ)
Vanger 0:b86d15c6ba29 7723 ssl->error = 0;
Vanger 0:b86d15c6ba29 7724
Vanger 0:b86d15c6ba29 7725 if (ssl->error != 0 && ssl->error != WANT_WRITE) {
Vanger 0:b86d15c6ba29 7726 CYASSL_MSG("User calling CyaSSL_read in error state, not allowed");
Vanger 0:b86d15c6ba29 7727 return ssl->error;
Vanger 0:b86d15c6ba29 7728 }
Vanger 0:b86d15c6ba29 7729
Vanger 0:b86d15c6ba29 7730 if (ssl->options.handShakeState != HANDSHAKE_DONE) {
Vanger 0:b86d15c6ba29 7731 int err;
Vanger 0:b86d15c6ba29 7732 CYASSL_MSG("Handshake not complete, trying to finish");
Vanger 0:b86d15c6ba29 7733 if ( (err = CyaSSL_negotiate(ssl)) != SSL_SUCCESS)
Vanger 0:b86d15c6ba29 7734 return err;
Vanger 0:b86d15c6ba29 7735 }
Vanger 0:b86d15c6ba29 7736
Vanger 0:b86d15c6ba29 7737 #ifdef HAVE_SECURE_RENEGOTIATION
Vanger 0:b86d15c6ba29 7738 startScr:
Vanger 0:b86d15c6ba29 7739 if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) {
Vanger 0:b86d15c6ba29 7740 int err;
Vanger 0:b86d15c6ba29 7741 ssl->secure_renegotiation->startScr = 0; /* only start once */
Vanger 0:b86d15c6ba29 7742 CYASSL_MSG("Need to start scr, server requested");
Vanger 0:b86d15c6ba29 7743 if ( (err = CyaSSL_Rehandshake(ssl)) != SSL_SUCCESS)
Vanger 0:b86d15c6ba29 7744 return err;
Vanger 0:b86d15c6ba29 7745 }
Vanger 0:b86d15c6ba29 7746 #endif
Vanger 0:b86d15c6ba29 7747
Vanger 0:b86d15c6ba29 7748 while (ssl->buffers.clearOutputBuffer.length == 0) {
Vanger 0:b86d15c6ba29 7749 if ( (ssl->error = ProcessReply(ssl)) < 0) {
Vanger 0:b86d15c6ba29 7750 CYASSL_ERROR(ssl->error);
Vanger 0:b86d15c6ba29 7751 if (ssl->error == ZERO_RETURN) {
Vanger 0:b86d15c6ba29 7752 CYASSL_MSG("Zero return, no more data coming");
Vanger 0:b86d15c6ba29 7753 return 0; /* no more data coming */
Vanger 0:b86d15c6ba29 7754 }
Vanger 0:b86d15c6ba29 7755 if (ssl->error == SOCKET_ERROR_E) {
Vanger 0:b86d15c6ba29 7756 if (ssl->options.connReset || ssl->options.isClosed) {
Vanger 0:b86d15c6ba29 7757 CYASSL_MSG("Peer reset or closed, connection done");
Vanger 0:b86d15c6ba29 7758 return 0; /* peer reset or closed */
Vanger 0:b86d15c6ba29 7759 }
Vanger 0:b86d15c6ba29 7760 }
Vanger 0:b86d15c6ba29 7761 return ssl->error;
Vanger 0:b86d15c6ba29 7762 }
Vanger 0:b86d15c6ba29 7763 #ifdef HAVE_SECURE_RENEGOTIATION
Vanger 0:b86d15c6ba29 7764 if (ssl->secure_renegotiation &&
Vanger 0:b86d15c6ba29 7765 ssl->secure_renegotiation->startScr) {
Vanger 0:b86d15c6ba29 7766 goto startScr;
Vanger 0:b86d15c6ba29 7767 }
Vanger 0:b86d15c6ba29 7768 #endif
Vanger 0:b86d15c6ba29 7769 }
Vanger 0:b86d15c6ba29 7770
Vanger 0:b86d15c6ba29 7771 if (sz < (int)ssl->buffers.clearOutputBuffer.length)
Vanger 0:b86d15c6ba29 7772 size = sz;
Vanger 0:b86d15c6ba29 7773 else
Vanger 0:b86d15c6ba29 7774 size = ssl->buffers.clearOutputBuffer.length;
Vanger 0:b86d15c6ba29 7775
Vanger 0:b86d15c6ba29 7776 XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size);
Vanger 0:b86d15c6ba29 7777
Vanger 0:b86d15c6ba29 7778 if (peek == 0) {
Vanger 0:b86d15c6ba29 7779 ssl->buffers.clearOutputBuffer.length -= size;
Vanger 0:b86d15c6ba29 7780 ssl->buffers.clearOutputBuffer.buffer += size;
Vanger 0:b86d15c6ba29 7781 }
Vanger 0:b86d15c6ba29 7782
Vanger 0:b86d15c6ba29 7783 if (ssl->buffers.clearOutputBuffer.length == 0 &&
Vanger 0:b86d15c6ba29 7784 ssl->buffers.inputBuffer.dynamicFlag)
Vanger 0:b86d15c6ba29 7785 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
Vanger 0:b86d15c6ba29 7786
Vanger 0:b86d15c6ba29 7787 CYASSL_LEAVE("ReceiveData()", size);
Vanger 0:b86d15c6ba29 7788 return size;
Vanger 0:b86d15c6ba29 7789 }
Vanger 0:b86d15c6ba29 7790
Vanger 0:b86d15c6ba29 7791
Vanger 0:b86d15c6ba29 7792 /* send alert message */
Vanger 0:b86d15c6ba29 7793 int SendAlert(CYASSL* ssl, int severity, int type)
Vanger 0:b86d15c6ba29 7794 {
Vanger 0:b86d15c6ba29 7795 byte input[ALERT_SIZE];
Vanger 0:b86d15c6ba29 7796 byte *output;
Vanger 0:b86d15c6ba29 7797 int sendSz;
Vanger 0:b86d15c6ba29 7798 int ret;
Vanger 0:b86d15c6ba29 7799 int outputSz;
Vanger 0:b86d15c6ba29 7800 int dtlsExtra = 0;
Vanger 0:b86d15c6ba29 7801
Vanger 0:b86d15c6ba29 7802 /* if sendalert is called again for nonbloking */
Vanger 0:b86d15c6ba29 7803 if (ssl->options.sendAlertState != 0) {
Vanger 0:b86d15c6ba29 7804 ret = SendBuffered(ssl);
Vanger 0:b86d15c6ba29 7805 if (ret == 0)
Vanger 0:b86d15c6ba29 7806 ssl->options.sendAlertState = 0;
Vanger 0:b86d15c6ba29 7807 return ret;
Vanger 0:b86d15c6ba29 7808 }
Vanger 0:b86d15c6ba29 7809
Vanger 0:b86d15c6ba29 7810 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7811 if (ssl->options.dtls)
Vanger 0:b86d15c6ba29 7812 dtlsExtra = DTLS_RECORD_EXTRA;
Vanger 0:b86d15c6ba29 7813 #endif
Vanger 0:b86d15c6ba29 7814
Vanger 0:b86d15c6ba29 7815 /* check for available size */
Vanger 0:b86d15c6ba29 7816 outputSz = ALERT_SIZE + MAX_MSG_EXTRA + dtlsExtra;
Vanger 0:b86d15c6ba29 7817 if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
Vanger 0:b86d15c6ba29 7818 return ret;
Vanger 0:b86d15c6ba29 7819
Vanger 0:b86d15c6ba29 7820 /* get ouput buffer */
Vanger 0:b86d15c6ba29 7821 output = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 7822 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 7823
Vanger 0:b86d15c6ba29 7824 input[0] = (byte)severity;
Vanger 0:b86d15c6ba29 7825 input[1] = (byte)type;
Vanger 0:b86d15c6ba29 7826 ssl->alert_history.last_tx.code = type;
Vanger 0:b86d15c6ba29 7827 ssl->alert_history.last_tx.level = severity;
Vanger 0:b86d15c6ba29 7828 if (severity == alert_fatal) {
Vanger 0:b86d15c6ba29 7829 ssl->options.isClosed = 1; /* Don't send close_notify */
Vanger 0:b86d15c6ba29 7830 }
Vanger 0:b86d15c6ba29 7831
Vanger 0:b86d15c6ba29 7832 /* only send encrypted alert if handshake actually complete, otherwise
Vanger 0:b86d15c6ba29 7833 other side may not be able to handle it */
Vanger 0:b86d15c6ba29 7834 if (ssl->keys.encryptionOn && ssl->options.handShakeDone)
Vanger 0:b86d15c6ba29 7835 sendSz = BuildMessage(ssl, output, outputSz, input, ALERT_SIZE, alert);
Vanger 0:b86d15c6ba29 7836 else {
Vanger 0:b86d15c6ba29 7837
Vanger 0:b86d15c6ba29 7838 AddRecordHeader(output, ALERT_SIZE, alert, ssl);
Vanger 0:b86d15c6ba29 7839 output += RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 7840 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7841 if (ssl->options.dtls)
Vanger 0:b86d15c6ba29 7842 output += DTLS_RECORD_EXTRA;
Vanger 0:b86d15c6ba29 7843 #endif
Vanger 0:b86d15c6ba29 7844 XMEMCPY(output, input, ALERT_SIZE);
Vanger 0:b86d15c6ba29 7845
Vanger 0:b86d15c6ba29 7846 sendSz = RECORD_HEADER_SZ + ALERT_SIZE;
Vanger 0:b86d15c6ba29 7847 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 7848 if (ssl->options.dtls)
Vanger 0:b86d15c6ba29 7849 sendSz += DTLS_RECORD_EXTRA;
Vanger 0:b86d15c6ba29 7850 #endif
Vanger 0:b86d15c6ba29 7851 }
Vanger 0:b86d15c6ba29 7852 if (sendSz < 0)
Vanger 0:b86d15c6ba29 7853 return BUILD_MSG_ERROR;
Vanger 0:b86d15c6ba29 7854
Vanger 0:b86d15c6ba29 7855 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 7856 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 7857 AddPacketName("Alert", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 7858 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 7859 AddPacketInfo("Alert", &ssl->timeoutInfo, output, sendSz,ssl->heap);
Vanger 0:b86d15c6ba29 7860 #endif
Vanger 0:b86d15c6ba29 7861
Vanger 0:b86d15c6ba29 7862 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 7863 ssl->options.sendAlertState = 1;
Vanger 0:b86d15c6ba29 7864
Vanger 0:b86d15c6ba29 7865 return SendBuffered(ssl);
Vanger 0:b86d15c6ba29 7866 }
Vanger 0:b86d15c6ba29 7867
Vanger 0:b86d15c6ba29 7868 const char* CyaSSL_ERR_reason_error_string(unsigned long e)
Vanger 0:b86d15c6ba29 7869 {
Vanger 0:b86d15c6ba29 7870 #ifdef NO_ERROR_STRINGS
Vanger 0:b86d15c6ba29 7871
Vanger 0:b86d15c6ba29 7872 (void)e;
Vanger 0:b86d15c6ba29 7873 return "no support for error strings built in";
Vanger 0:b86d15c6ba29 7874
Vanger 0:b86d15c6ba29 7875 #else
Vanger 0:b86d15c6ba29 7876
Vanger 0:b86d15c6ba29 7877 int error = (int)e;
Vanger 0:b86d15c6ba29 7878
Vanger 0:b86d15c6ba29 7879 /* pass to CTaoCrypt */
Vanger 0:b86d15c6ba29 7880 if (error < MAX_CODE_E && error > MIN_CODE_E) {
Vanger 0:b86d15c6ba29 7881 return CTaoCryptGetErrorString(error);
Vanger 0:b86d15c6ba29 7882 }
Vanger 0:b86d15c6ba29 7883
Vanger 0:b86d15c6ba29 7884 switch (error) {
Vanger 0:b86d15c6ba29 7885
Vanger 0:b86d15c6ba29 7886 case UNSUPPORTED_SUITE :
Vanger 0:b86d15c6ba29 7887 return "unsupported cipher suite";
Vanger 0:b86d15c6ba29 7888
Vanger 0:b86d15c6ba29 7889 case INPUT_CASE_ERROR :
Vanger 0:b86d15c6ba29 7890 return "input state error";
Vanger 0:b86d15c6ba29 7891
Vanger 0:b86d15c6ba29 7892 case PREFIX_ERROR :
Vanger 0:b86d15c6ba29 7893 return "bad index to key rounds";
Vanger 0:b86d15c6ba29 7894
Vanger 0:b86d15c6ba29 7895 case MEMORY_ERROR :
Vanger 0:b86d15c6ba29 7896 return "out of memory";
Vanger 0:b86d15c6ba29 7897
Vanger 0:b86d15c6ba29 7898 case VERIFY_FINISHED_ERROR :
Vanger 0:b86d15c6ba29 7899 return "verify problem on finished";
Vanger 0:b86d15c6ba29 7900
Vanger 0:b86d15c6ba29 7901 case VERIFY_MAC_ERROR :
Vanger 0:b86d15c6ba29 7902 return "verify mac problem";
Vanger 0:b86d15c6ba29 7903
Vanger 0:b86d15c6ba29 7904 case PARSE_ERROR :
Vanger 0:b86d15c6ba29 7905 return "parse error on header";
Vanger 0:b86d15c6ba29 7906
Vanger 0:b86d15c6ba29 7907 case SIDE_ERROR :
Vanger 0:b86d15c6ba29 7908 return "wrong client/server type";
Vanger 0:b86d15c6ba29 7909
Vanger 0:b86d15c6ba29 7910 case NO_PEER_CERT :
Vanger 0:b86d15c6ba29 7911 return "peer didn't send cert";
Vanger 0:b86d15c6ba29 7912
Vanger 0:b86d15c6ba29 7913 case UNKNOWN_HANDSHAKE_TYPE :
Vanger 0:b86d15c6ba29 7914 return "weird handshake type";
Vanger 0:b86d15c6ba29 7915
Vanger 0:b86d15c6ba29 7916 case SOCKET_ERROR_E :
Vanger 0:b86d15c6ba29 7917 return "error state on socket";
Vanger 0:b86d15c6ba29 7918
Vanger 0:b86d15c6ba29 7919 case SOCKET_NODATA :
Vanger 0:b86d15c6ba29 7920 return "expected data, not there";
Vanger 0:b86d15c6ba29 7921
Vanger 0:b86d15c6ba29 7922 case INCOMPLETE_DATA :
Vanger 0:b86d15c6ba29 7923 return "don't have enough data to complete task";
Vanger 0:b86d15c6ba29 7924
Vanger 0:b86d15c6ba29 7925 case UNKNOWN_RECORD_TYPE :
Vanger 0:b86d15c6ba29 7926 return "unknown type in record hdr";
Vanger 0:b86d15c6ba29 7927
Vanger 0:b86d15c6ba29 7928 case DECRYPT_ERROR :
Vanger 0:b86d15c6ba29 7929 return "error during decryption";
Vanger 0:b86d15c6ba29 7930
Vanger 0:b86d15c6ba29 7931 case FATAL_ERROR :
Vanger 0:b86d15c6ba29 7932 return "revcd alert fatal error";
Vanger 0:b86d15c6ba29 7933
Vanger 0:b86d15c6ba29 7934 case ENCRYPT_ERROR :
Vanger 0:b86d15c6ba29 7935 return "error during encryption";
Vanger 0:b86d15c6ba29 7936
Vanger 0:b86d15c6ba29 7937 case FREAD_ERROR :
Vanger 0:b86d15c6ba29 7938 return "fread problem";
Vanger 0:b86d15c6ba29 7939
Vanger 0:b86d15c6ba29 7940 case NO_PEER_KEY :
Vanger 0:b86d15c6ba29 7941 return "need peer's key";
Vanger 0:b86d15c6ba29 7942
Vanger 0:b86d15c6ba29 7943 case NO_PRIVATE_KEY :
Vanger 0:b86d15c6ba29 7944 return "need the private key";
Vanger 0:b86d15c6ba29 7945
Vanger 0:b86d15c6ba29 7946 case NO_DH_PARAMS :
Vanger 0:b86d15c6ba29 7947 return "server missing DH params";
Vanger 0:b86d15c6ba29 7948
Vanger 0:b86d15c6ba29 7949 case RSA_PRIVATE_ERROR :
Vanger 0:b86d15c6ba29 7950 return "error during rsa priv op";
Vanger 0:b86d15c6ba29 7951
Vanger 0:b86d15c6ba29 7952 case MATCH_SUITE_ERROR :
Vanger 0:b86d15c6ba29 7953 return "can't match cipher suite";
Vanger 0:b86d15c6ba29 7954
Vanger 0:b86d15c6ba29 7955 case BUILD_MSG_ERROR :
Vanger 0:b86d15c6ba29 7956 return "build message failure";
Vanger 0:b86d15c6ba29 7957
Vanger 0:b86d15c6ba29 7958 case BAD_HELLO :
Vanger 0:b86d15c6ba29 7959 return "client hello malformed";
Vanger 0:b86d15c6ba29 7960
Vanger 0:b86d15c6ba29 7961 case DOMAIN_NAME_MISMATCH :
Vanger 0:b86d15c6ba29 7962 return "peer subject name mismatch";
Vanger 0:b86d15c6ba29 7963
Vanger 0:b86d15c6ba29 7964 case WANT_READ :
Vanger 0:b86d15c6ba29 7965 case SSL_ERROR_WANT_READ :
Vanger 0:b86d15c6ba29 7966 return "non-blocking socket wants data to be read";
Vanger 0:b86d15c6ba29 7967
Vanger 0:b86d15c6ba29 7968 case NOT_READY_ERROR :
Vanger 0:b86d15c6ba29 7969 return "handshake layer not ready yet, complete first";
Vanger 0:b86d15c6ba29 7970
Vanger 0:b86d15c6ba29 7971 case PMS_VERSION_ERROR :
Vanger 0:b86d15c6ba29 7972 return "premaster secret version mismatch error";
Vanger 0:b86d15c6ba29 7973
Vanger 0:b86d15c6ba29 7974 case VERSION_ERROR :
Vanger 0:b86d15c6ba29 7975 return "record layer version error";
Vanger 0:b86d15c6ba29 7976
Vanger 0:b86d15c6ba29 7977 case WANT_WRITE :
Vanger 0:b86d15c6ba29 7978 case SSL_ERROR_WANT_WRITE :
Vanger 0:b86d15c6ba29 7979 return "non-blocking socket write buffer full";
Vanger 0:b86d15c6ba29 7980
Vanger 0:b86d15c6ba29 7981 case BUFFER_ERROR :
Vanger 0:b86d15c6ba29 7982 return "malformed buffer input error";
Vanger 0:b86d15c6ba29 7983
Vanger 0:b86d15c6ba29 7984 case VERIFY_CERT_ERROR :
Vanger 0:b86d15c6ba29 7985 return "verify problem on certificate";
Vanger 0:b86d15c6ba29 7986
Vanger 0:b86d15c6ba29 7987 case VERIFY_SIGN_ERROR :
Vanger 0:b86d15c6ba29 7988 return "verify problem based on signature";
Vanger 0:b86d15c6ba29 7989
Vanger 0:b86d15c6ba29 7990 case CLIENT_ID_ERROR :
Vanger 0:b86d15c6ba29 7991 return "psk client identity error";
Vanger 0:b86d15c6ba29 7992
Vanger 0:b86d15c6ba29 7993 case SERVER_HINT_ERROR:
Vanger 0:b86d15c6ba29 7994 return "psk server hint error";
Vanger 0:b86d15c6ba29 7995
Vanger 0:b86d15c6ba29 7996 case PSK_KEY_ERROR:
Vanger 0:b86d15c6ba29 7997 return "psk key callback error";
Vanger 0:b86d15c6ba29 7998
Vanger 0:b86d15c6ba29 7999 case NTRU_KEY_ERROR:
Vanger 0:b86d15c6ba29 8000 return "NTRU key error";
Vanger 0:b86d15c6ba29 8001
Vanger 0:b86d15c6ba29 8002 case NTRU_DRBG_ERROR:
Vanger 0:b86d15c6ba29 8003 return "NTRU drbg error";
Vanger 0:b86d15c6ba29 8004
Vanger 0:b86d15c6ba29 8005 case NTRU_ENCRYPT_ERROR:
Vanger 0:b86d15c6ba29 8006 return "NTRU encrypt error";
Vanger 0:b86d15c6ba29 8007
Vanger 0:b86d15c6ba29 8008 case NTRU_DECRYPT_ERROR:
Vanger 0:b86d15c6ba29 8009 return "NTRU decrypt error";
Vanger 0:b86d15c6ba29 8010
Vanger 0:b86d15c6ba29 8011 case ZLIB_INIT_ERROR:
Vanger 0:b86d15c6ba29 8012 return "zlib init error";
Vanger 0:b86d15c6ba29 8013
Vanger 0:b86d15c6ba29 8014 case ZLIB_COMPRESS_ERROR:
Vanger 0:b86d15c6ba29 8015 return "zlib compress error";
Vanger 0:b86d15c6ba29 8016
Vanger 0:b86d15c6ba29 8017 case ZLIB_DECOMPRESS_ERROR:
Vanger 0:b86d15c6ba29 8018 return "zlib decompress error";
Vanger 0:b86d15c6ba29 8019
Vanger 0:b86d15c6ba29 8020 case GETTIME_ERROR:
Vanger 0:b86d15c6ba29 8021 return "gettimeofday() error";
Vanger 0:b86d15c6ba29 8022
Vanger 0:b86d15c6ba29 8023 case GETITIMER_ERROR:
Vanger 0:b86d15c6ba29 8024 return "getitimer() error";
Vanger 0:b86d15c6ba29 8025
Vanger 0:b86d15c6ba29 8026 case SIGACT_ERROR:
Vanger 0:b86d15c6ba29 8027 return "sigaction() error";
Vanger 0:b86d15c6ba29 8028
Vanger 0:b86d15c6ba29 8029 case SETITIMER_ERROR:
Vanger 0:b86d15c6ba29 8030 return "setitimer() error";
Vanger 0:b86d15c6ba29 8031
Vanger 0:b86d15c6ba29 8032 case LENGTH_ERROR:
Vanger 0:b86d15c6ba29 8033 return "record layer length error";
Vanger 0:b86d15c6ba29 8034
Vanger 0:b86d15c6ba29 8035 case PEER_KEY_ERROR:
Vanger 0:b86d15c6ba29 8036 return "cant decode peer key";
Vanger 0:b86d15c6ba29 8037
Vanger 0:b86d15c6ba29 8038 case ZERO_RETURN:
Vanger 0:b86d15c6ba29 8039 case SSL_ERROR_ZERO_RETURN:
Vanger 0:b86d15c6ba29 8040 return "peer sent close notify alert";
Vanger 0:b86d15c6ba29 8041
Vanger 0:b86d15c6ba29 8042 case ECC_CURVETYPE_ERROR:
Vanger 0:b86d15c6ba29 8043 return "Bad ECC Curve Type or unsupported";
Vanger 0:b86d15c6ba29 8044
Vanger 0:b86d15c6ba29 8045 case ECC_CURVE_ERROR:
Vanger 0:b86d15c6ba29 8046 return "Bad ECC Curve or unsupported";
Vanger 0:b86d15c6ba29 8047
Vanger 0:b86d15c6ba29 8048 case ECC_PEERKEY_ERROR:
Vanger 0:b86d15c6ba29 8049 return "Bad ECC Peer Key";
Vanger 0:b86d15c6ba29 8050
Vanger 0:b86d15c6ba29 8051 case ECC_MAKEKEY_ERROR:
Vanger 0:b86d15c6ba29 8052 return "ECC Make Key failure";
Vanger 0:b86d15c6ba29 8053
Vanger 0:b86d15c6ba29 8054 case ECC_EXPORT_ERROR:
Vanger 0:b86d15c6ba29 8055 return "ECC Export Key failure";
Vanger 0:b86d15c6ba29 8056
Vanger 0:b86d15c6ba29 8057 case ECC_SHARED_ERROR:
Vanger 0:b86d15c6ba29 8058 return "ECC DHE shared failure";
Vanger 0:b86d15c6ba29 8059
Vanger 0:b86d15c6ba29 8060 case NOT_CA_ERROR:
Vanger 0:b86d15c6ba29 8061 return "Not a CA by basic constraint error";
Vanger 0:b86d15c6ba29 8062
Vanger 0:b86d15c6ba29 8063 case BAD_PATH_ERROR:
Vanger 0:b86d15c6ba29 8064 return "Bad path for opendir error";
Vanger 0:b86d15c6ba29 8065
Vanger 0:b86d15c6ba29 8066 case BAD_CERT_MANAGER_ERROR:
Vanger 0:b86d15c6ba29 8067 return "Bad Cert Manager error";
Vanger 0:b86d15c6ba29 8068
Vanger 0:b86d15c6ba29 8069 case OCSP_CERT_REVOKED:
Vanger 0:b86d15c6ba29 8070 return "OCSP Cert revoked";
Vanger 0:b86d15c6ba29 8071
Vanger 0:b86d15c6ba29 8072 case CRL_CERT_REVOKED:
Vanger 0:b86d15c6ba29 8073 return "CRL Cert revoked";
Vanger 0:b86d15c6ba29 8074
Vanger 0:b86d15c6ba29 8075 case CRL_MISSING:
Vanger 0:b86d15c6ba29 8076 return "CRL missing, not loaded";
Vanger 0:b86d15c6ba29 8077
Vanger 0:b86d15c6ba29 8078 case MONITOR_RUNNING_E:
Vanger 0:b86d15c6ba29 8079 return "CRL monitor already running";
Vanger 0:b86d15c6ba29 8080
Vanger 0:b86d15c6ba29 8081 case THREAD_CREATE_E:
Vanger 0:b86d15c6ba29 8082 return "Thread creation problem";
Vanger 0:b86d15c6ba29 8083
Vanger 0:b86d15c6ba29 8084 case OCSP_NEED_URL:
Vanger 0:b86d15c6ba29 8085 return "OCSP need URL";
Vanger 0:b86d15c6ba29 8086
Vanger 0:b86d15c6ba29 8087 case OCSP_CERT_UNKNOWN:
Vanger 0:b86d15c6ba29 8088 return "OCSP Cert unknown";
Vanger 0:b86d15c6ba29 8089
Vanger 0:b86d15c6ba29 8090 case OCSP_LOOKUP_FAIL:
Vanger 0:b86d15c6ba29 8091 return "OCSP Responder lookup fail";
Vanger 0:b86d15c6ba29 8092
Vanger 0:b86d15c6ba29 8093 case MAX_CHAIN_ERROR:
Vanger 0:b86d15c6ba29 8094 return "Maximum Chain Depth Exceeded";
Vanger 0:b86d15c6ba29 8095
Vanger 0:b86d15c6ba29 8096 case COOKIE_ERROR:
Vanger 0:b86d15c6ba29 8097 return "DTLS Cookie Error";
Vanger 0:b86d15c6ba29 8098
Vanger 0:b86d15c6ba29 8099 case SEQUENCE_ERROR:
Vanger 0:b86d15c6ba29 8100 return "DTLS Sequence Error";
Vanger 0:b86d15c6ba29 8101
Vanger 0:b86d15c6ba29 8102 case SUITES_ERROR:
Vanger 0:b86d15c6ba29 8103 return "Suites Pointer Error";
Vanger 0:b86d15c6ba29 8104
Vanger 0:b86d15c6ba29 8105 case SSL_NO_PEM_HEADER:
Vanger 0:b86d15c6ba29 8106 return "No PEM Header Error";
Vanger 0:b86d15c6ba29 8107
Vanger 0:b86d15c6ba29 8108 case OUT_OF_ORDER_E:
Vanger 0:b86d15c6ba29 8109 return "Out of order message, fatal";
Vanger 0:b86d15c6ba29 8110
Vanger 0:b86d15c6ba29 8111 case BAD_KEA_TYPE_E:
Vanger 0:b86d15c6ba29 8112 return "Bad KEA type found";
Vanger 0:b86d15c6ba29 8113
Vanger 0:b86d15c6ba29 8114 case SANITY_CIPHER_E:
Vanger 0:b86d15c6ba29 8115 return "Sanity check on ciphertext failed";
Vanger 0:b86d15c6ba29 8116
Vanger 0:b86d15c6ba29 8117 case RECV_OVERFLOW_E:
Vanger 0:b86d15c6ba29 8118 return "Receive callback returned more than requested";
Vanger 0:b86d15c6ba29 8119
Vanger 0:b86d15c6ba29 8120 case GEN_COOKIE_E:
Vanger 0:b86d15c6ba29 8121 return "Generate Cookie Error";
Vanger 0:b86d15c6ba29 8122
Vanger 0:b86d15c6ba29 8123 case NO_PEER_VERIFY:
Vanger 0:b86d15c6ba29 8124 return "Need peer certificate verify Error";
Vanger 0:b86d15c6ba29 8125
Vanger 0:b86d15c6ba29 8126 case FWRITE_ERROR:
Vanger 0:b86d15c6ba29 8127 return "fwrite Error";
Vanger 0:b86d15c6ba29 8128
Vanger 0:b86d15c6ba29 8129 case CACHE_MATCH_ERROR:
Vanger 0:b86d15c6ba29 8130 return "Cache restore header match Error";
Vanger 0:b86d15c6ba29 8131
Vanger 0:b86d15c6ba29 8132 case UNKNOWN_SNI_HOST_NAME_E:
Vanger 0:b86d15c6ba29 8133 return "Unrecognized host name Error";
Vanger 0:b86d15c6ba29 8134
Vanger 0:b86d15c6ba29 8135 case KEYUSE_SIGNATURE_E:
Vanger 0:b86d15c6ba29 8136 return "Key Use digitalSignature not set Error";
Vanger 0:b86d15c6ba29 8137
Vanger 0:b86d15c6ba29 8138 case KEYUSE_ENCIPHER_E:
Vanger 0:b86d15c6ba29 8139 return "Key Use keyEncipherment not set Error";
Vanger 0:b86d15c6ba29 8140
Vanger 0:b86d15c6ba29 8141 case EXTKEYUSE_AUTH_E:
Vanger 0:b86d15c6ba29 8142 return "Ext Key Use server/client auth not set Error";
Vanger 0:b86d15c6ba29 8143
Vanger 0:b86d15c6ba29 8144 case SEND_OOB_READ_E:
Vanger 0:b86d15c6ba29 8145 return "Send Callback Out of Bounds Read Error";
Vanger 0:b86d15c6ba29 8146
Vanger 0:b86d15c6ba29 8147 case SECURE_RENEGOTIATION_E:
Vanger 0:b86d15c6ba29 8148 return "Invalid Renegotiation Error";
Vanger 0:b86d15c6ba29 8149
Vanger 0:b86d15c6ba29 8150 case SESSION_TICKET_LEN_E:
Vanger 0:b86d15c6ba29 8151 return "Session Ticket Too Long Error";
Vanger 0:b86d15c6ba29 8152
Vanger 0:b86d15c6ba29 8153 case SESSION_TICKET_EXPECT_E:
Vanger 0:b86d15c6ba29 8154 return "Session Ticket Error";
Vanger 0:b86d15c6ba29 8155
Vanger 0:b86d15c6ba29 8156 case SCR_DIFFERENT_CERT_E:
Vanger 0:b86d15c6ba29 8157 return "Peer sent different cert during SCR";
Vanger 0:b86d15c6ba29 8158
Vanger 0:b86d15c6ba29 8159 case SESSION_SECRET_CB_E:
Vanger 0:b86d15c6ba29 8160 return "Session Secret Callback Error";
Vanger 0:b86d15c6ba29 8161
Vanger 0:b86d15c6ba29 8162 case NO_CHANGE_CIPHER_E:
Vanger 0:b86d15c6ba29 8163 return "Finished received from peer before Change Cipher Error";
Vanger 0:b86d15c6ba29 8164
Vanger 0:b86d15c6ba29 8165 case SANITY_MSG_E:
Vanger 0:b86d15c6ba29 8166 return "Sanity Check on message order Error";
Vanger 0:b86d15c6ba29 8167
Vanger 0:b86d15c6ba29 8168 case DUPLICATE_MSG_E:
Vanger 0:b86d15c6ba29 8169 return "Duplicate HandShake message Error";
Vanger 0:b86d15c6ba29 8170
Vanger 0:b86d15c6ba29 8171 default :
Vanger 0:b86d15c6ba29 8172 return "unknown error number";
Vanger 0:b86d15c6ba29 8173 }
Vanger 0:b86d15c6ba29 8174
Vanger 0:b86d15c6ba29 8175 #endif /* NO_ERROR_STRINGS */
Vanger 0:b86d15c6ba29 8176 }
Vanger 0:b86d15c6ba29 8177
Vanger 0:b86d15c6ba29 8178 void SetErrorString(int error, char* str)
Vanger 0:b86d15c6ba29 8179 {
Vanger 0:b86d15c6ba29 8180 XSTRNCPY(str, CyaSSL_ERR_reason_error_string(error), CYASSL_MAX_ERROR_SZ);
Vanger 0:b86d15c6ba29 8181 }
Vanger 0:b86d15c6ba29 8182
Vanger 0:b86d15c6ba29 8183
Vanger 0:b86d15c6ba29 8184 /* be sure to add to cipher_name_idx too !!!! */
Vanger 0:b86d15c6ba29 8185 static const char* const cipher_names[] =
Vanger 0:b86d15c6ba29 8186 {
Vanger 0:b86d15c6ba29 8187 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 8188 "RC4-SHA",
Vanger 0:b86d15c6ba29 8189 #endif
Vanger 0:b86d15c6ba29 8190
Vanger 0:b86d15c6ba29 8191 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
Vanger 0:b86d15c6ba29 8192 "RC4-MD5",
Vanger 0:b86d15c6ba29 8193 #endif
Vanger 0:b86d15c6ba29 8194
Vanger 0:b86d15c6ba29 8195 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 8196 "DES-CBC3-SHA",
Vanger 0:b86d15c6ba29 8197 #endif
Vanger 0:b86d15c6ba29 8198
Vanger 0:b86d15c6ba29 8199 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8200 "AES128-SHA",
Vanger 0:b86d15c6ba29 8201 #endif
Vanger 0:b86d15c6ba29 8202
Vanger 0:b86d15c6ba29 8203 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8204 "AES256-SHA",
Vanger 0:b86d15c6ba29 8205 #endif
Vanger 0:b86d15c6ba29 8206
Vanger 0:b86d15c6ba29 8207 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
Vanger 0:b86d15c6ba29 8208 "NULL-SHA",
Vanger 0:b86d15c6ba29 8209 #endif
Vanger 0:b86d15c6ba29 8210
Vanger 0:b86d15c6ba29 8211 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
Vanger 0:b86d15c6ba29 8212 "NULL-SHA256",
Vanger 0:b86d15c6ba29 8213 #endif
Vanger 0:b86d15c6ba29 8214
Vanger 0:b86d15c6ba29 8215 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8216 "DHE-RSA-AES128-SHA",
Vanger 0:b86d15c6ba29 8217 #endif
Vanger 0:b86d15c6ba29 8218
Vanger 0:b86d15c6ba29 8219 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8220 "DHE-RSA-AES256-SHA",
Vanger 0:b86d15c6ba29 8221 #endif
Vanger 0:b86d15c6ba29 8222
Vanger 0:b86d15c6ba29 8223 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8224 "DHE-PSK-AES256-GCM-SHA384",
Vanger 0:b86d15c6ba29 8225 #endif
Vanger 0:b86d15c6ba29 8226
Vanger 0:b86d15c6ba29 8227 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8228 "DHE-PSK-AES128-GCM-SHA256",
Vanger 0:b86d15c6ba29 8229 #endif
Vanger 0:b86d15c6ba29 8230
Vanger 0:b86d15c6ba29 8231 #ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8232 "PSK-AES256-GCM-SHA384",
Vanger 0:b86d15c6ba29 8233 #endif
Vanger 0:b86d15c6ba29 8234
Vanger 0:b86d15c6ba29 8235 #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8236 "PSK-AES128-GCM-SHA256",
Vanger 0:b86d15c6ba29 8237 #endif
Vanger 0:b86d15c6ba29 8238
Vanger 0:b86d15c6ba29 8239 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 8240 "DHE-PSK-AES256-CBC-SHA384",
Vanger 0:b86d15c6ba29 8241 #endif
Vanger 0:b86d15c6ba29 8242
Vanger 0:b86d15c6ba29 8243 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8244 "DHE-PSK-AES128-CBC-SHA256",
Vanger 0:b86d15c6ba29 8245 #endif
Vanger 0:b86d15c6ba29 8246
Vanger 0:b86d15c6ba29 8247 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 8248 "PSK-AES256-CBC-SHA384",
Vanger 0:b86d15c6ba29 8249 #endif
Vanger 0:b86d15c6ba29 8250
Vanger 0:b86d15c6ba29 8251 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8252 "PSK-AES128-CBC-SHA256",
Vanger 0:b86d15c6ba29 8253 #endif
Vanger 0:b86d15c6ba29 8254
Vanger 0:b86d15c6ba29 8255 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8256 "PSK-AES128-CBC-SHA",
Vanger 0:b86d15c6ba29 8257 #endif
Vanger 0:b86d15c6ba29 8258
Vanger 0:b86d15c6ba29 8259 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8260 "PSK-AES256-CBC-SHA",
Vanger 0:b86d15c6ba29 8261 #endif
Vanger 0:b86d15c6ba29 8262
Vanger 0:b86d15c6ba29 8263 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
Vanger 0:b86d15c6ba29 8264 "DHE-PSK-AES128-CCM",
Vanger 0:b86d15c6ba29 8265 #endif
Vanger 0:b86d15c6ba29 8266
Vanger 0:b86d15c6ba29 8267 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
Vanger 0:b86d15c6ba29 8268 "DHE-PSK-AES256-CCM",
Vanger 0:b86d15c6ba29 8269 #endif
Vanger 0:b86d15c6ba29 8270
Vanger 0:b86d15c6ba29 8271 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
Vanger 0:b86d15c6ba29 8272 "PSK-AES128-CCM",
Vanger 0:b86d15c6ba29 8273 #endif
Vanger 0:b86d15c6ba29 8274
Vanger 0:b86d15c6ba29 8275 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
Vanger 0:b86d15c6ba29 8276 "PSK-AES256-CCM",
Vanger 0:b86d15c6ba29 8277 #endif
Vanger 0:b86d15c6ba29 8278
Vanger 0:b86d15c6ba29 8279 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
Vanger 0:b86d15c6ba29 8280 "PSK-AES128-CCM-8",
Vanger 0:b86d15c6ba29 8281 #endif
Vanger 0:b86d15c6ba29 8282
Vanger 0:b86d15c6ba29 8283 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
Vanger 0:b86d15c6ba29 8284 "PSK-AES256-CCM-8",
Vanger 0:b86d15c6ba29 8285 #endif
Vanger 0:b86d15c6ba29 8286
Vanger 0:b86d15c6ba29 8287 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
Vanger 0:b86d15c6ba29 8288 "DHE-PSK-NULL-SHA384",
Vanger 0:b86d15c6ba29 8289 #endif
Vanger 0:b86d15c6ba29 8290
Vanger 0:b86d15c6ba29 8291 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
Vanger 0:b86d15c6ba29 8292 "DHE-PSK-NULL-SHA256",
Vanger 0:b86d15c6ba29 8293 #endif
Vanger 0:b86d15c6ba29 8294
Vanger 0:b86d15c6ba29 8295 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
Vanger 0:b86d15c6ba29 8296 "PSK-NULL-SHA384",
Vanger 0:b86d15c6ba29 8297 #endif
Vanger 0:b86d15c6ba29 8298
Vanger 0:b86d15c6ba29 8299 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
Vanger 0:b86d15c6ba29 8300 "PSK-NULL-SHA256",
Vanger 0:b86d15c6ba29 8301 #endif
Vanger 0:b86d15c6ba29 8302
Vanger 0:b86d15c6ba29 8303 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
Vanger 0:b86d15c6ba29 8304 "PSK-NULL-SHA",
Vanger 0:b86d15c6ba29 8305 #endif
Vanger 0:b86d15c6ba29 8306
Vanger 0:b86d15c6ba29 8307 #ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
Vanger 0:b86d15c6ba29 8308 "HC128-MD5",
Vanger 0:b86d15c6ba29 8309 #endif
Vanger 0:b86d15c6ba29 8310
Vanger 0:b86d15c6ba29 8311 #ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
Vanger 0:b86d15c6ba29 8312 "HC128-SHA",
Vanger 0:b86d15c6ba29 8313 #endif
Vanger 0:b86d15c6ba29 8314
Vanger 0:b86d15c6ba29 8315 #ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
Vanger 0:b86d15c6ba29 8316 "HC128-B2B256",
Vanger 0:b86d15c6ba29 8317 #endif
Vanger 0:b86d15c6ba29 8318
Vanger 0:b86d15c6ba29 8319 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
Vanger 0:b86d15c6ba29 8320 "AES128-B2B256",
Vanger 0:b86d15c6ba29 8321 #endif
Vanger 0:b86d15c6ba29 8322
Vanger 0:b86d15c6ba29 8323 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
Vanger 0:b86d15c6ba29 8324 "AES256-B2B256",
Vanger 0:b86d15c6ba29 8325 #endif
Vanger 0:b86d15c6ba29 8326
Vanger 0:b86d15c6ba29 8327 #ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
Vanger 0:b86d15c6ba29 8328 "RABBIT-SHA",
Vanger 0:b86d15c6ba29 8329 #endif
Vanger 0:b86d15c6ba29 8330
Vanger 0:b86d15c6ba29 8331 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 8332 "NTRU-RC4-SHA",
Vanger 0:b86d15c6ba29 8333 #endif
Vanger 0:b86d15c6ba29 8334
Vanger 0:b86d15c6ba29 8335 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 8336 "NTRU-DES-CBC3-SHA",
Vanger 0:b86d15c6ba29 8337 #endif
Vanger 0:b86d15c6ba29 8338
Vanger 0:b86d15c6ba29 8339 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8340 "NTRU-AES128-SHA",
Vanger 0:b86d15c6ba29 8341 #endif
Vanger 0:b86d15c6ba29 8342
Vanger 0:b86d15c6ba29 8343 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8344 "NTRU-AES256-SHA",
Vanger 0:b86d15c6ba29 8345 #endif
Vanger 0:b86d15c6ba29 8346
Vanger 0:b86d15c6ba29 8347 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
Vanger 0:b86d15c6ba29 8348 "AES128-CCM-8",
Vanger 0:b86d15c6ba29 8349 #endif
Vanger 0:b86d15c6ba29 8350
Vanger 0:b86d15c6ba29 8351 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
Vanger 0:b86d15c6ba29 8352 "AES256-CCM-8",
Vanger 0:b86d15c6ba29 8353 #endif
Vanger 0:b86d15c6ba29 8354
Vanger 0:b86d15c6ba29 8355 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
Vanger 0:b86d15c6ba29 8356 "ECDHE-ECDSA-AES128-CCM-8",
Vanger 0:b86d15c6ba29 8357 #endif
Vanger 0:b86d15c6ba29 8358
Vanger 0:b86d15c6ba29 8359 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
Vanger 0:b86d15c6ba29 8360 "ECDHE-ECDSA-AES256-CCM-8",
Vanger 0:b86d15c6ba29 8361 #endif
Vanger 0:b86d15c6ba29 8362
Vanger 0:b86d15c6ba29 8363 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8364 "ECDHE-RSA-AES128-SHA",
Vanger 0:b86d15c6ba29 8365 #endif
Vanger 0:b86d15c6ba29 8366
Vanger 0:b86d15c6ba29 8367 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8368 "ECDHE-RSA-AES256-SHA",
Vanger 0:b86d15c6ba29 8369 #endif
Vanger 0:b86d15c6ba29 8370
Vanger 0:b86d15c6ba29 8371 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8372 "ECDHE-ECDSA-AES128-SHA",
Vanger 0:b86d15c6ba29 8373 #endif
Vanger 0:b86d15c6ba29 8374
Vanger 0:b86d15c6ba29 8375 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8376 "ECDHE-ECDSA-AES256-SHA",
Vanger 0:b86d15c6ba29 8377 #endif
Vanger 0:b86d15c6ba29 8378
Vanger 0:b86d15c6ba29 8379 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 8380 "ECDHE-RSA-RC4-SHA",
Vanger 0:b86d15c6ba29 8381 #endif
Vanger 0:b86d15c6ba29 8382
Vanger 0:b86d15c6ba29 8383 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 8384 "ECDHE-RSA-DES-CBC3-SHA",
Vanger 0:b86d15c6ba29 8385 #endif
Vanger 0:b86d15c6ba29 8386
Vanger 0:b86d15c6ba29 8387 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 8388 "ECDHE-ECDSA-RC4-SHA",
Vanger 0:b86d15c6ba29 8389 #endif
Vanger 0:b86d15c6ba29 8390
Vanger 0:b86d15c6ba29 8391 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 8392 "ECDHE-ECDSA-DES-CBC3-SHA",
Vanger 0:b86d15c6ba29 8393 #endif
Vanger 0:b86d15c6ba29 8394
Vanger 0:b86d15c6ba29 8395 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8396 "AES128-SHA256",
Vanger 0:b86d15c6ba29 8397 #endif
Vanger 0:b86d15c6ba29 8398
Vanger 0:b86d15c6ba29 8399 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
Vanger 0:b86d15c6ba29 8400 "AES256-SHA256",
Vanger 0:b86d15c6ba29 8401 #endif
Vanger 0:b86d15c6ba29 8402
Vanger 0:b86d15c6ba29 8403 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8404 "DHE-RSA-AES128-SHA256",
Vanger 0:b86d15c6ba29 8405 #endif
Vanger 0:b86d15c6ba29 8406
Vanger 0:b86d15c6ba29 8407 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Vanger 0:b86d15c6ba29 8408 "DHE-RSA-AES256-SHA256",
Vanger 0:b86d15c6ba29 8409 #endif
Vanger 0:b86d15c6ba29 8410
Vanger 0:b86d15c6ba29 8411 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8412 "ECDH-RSA-AES128-SHA",
Vanger 0:b86d15c6ba29 8413 #endif
Vanger 0:b86d15c6ba29 8414
Vanger 0:b86d15c6ba29 8415 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8416 "ECDH-RSA-AES256-SHA",
Vanger 0:b86d15c6ba29 8417 #endif
Vanger 0:b86d15c6ba29 8418
Vanger 0:b86d15c6ba29 8419 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8420 "ECDH-ECDSA-AES128-SHA",
Vanger 0:b86d15c6ba29 8421 #endif
Vanger 0:b86d15c6ba29 8422
Vanger 0:b86d15c6ba29 8423 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8424 "ECDH-ECDSA-AES256-SHA",
Vanger 0:b86d15c6ba29 8425 #endif
Vanger 0:b86d15c6ba29 8426
Vanger 0:b86d15c6ba29 8427 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 8428 "ECDH-RSA-RC4-SHA",
Vanger 0:b86d15c6ba29 8429 #endif
Vanger 0:b86d15c6ba29 8430
Vanger 0:b86d15c6ba29 8431 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 8432 "ECDH-RSA-DES-CBC3-SHA",
Vanger 0:b86d15c6ba29 8433 #endif
Vanger 0:b86d15c6ba29 8434
Vanger 0:b86d15c6ba29 8435 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 8436 "ECDH-ECDSA-RC4-SHA",
Vanger 0:b86d15c6ba29 8437 #endif
Vanger 0:b86d15c6ba29 8438
Vanger 0:b86d15c6ba29 8439 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 8440 "ECDH-ECDSA-DES-CBC3-SHA",
Vanger 0:b86d15c6ba29 8441 #endif
Vanger 0:b86d15c6ba29 8442
Vanger 0:b86d15c6ba29 8443 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8444 "AES128-GCM-SHA256",
Vanger 0:b86d15c6ba29 8445 #endif
Vanger 0:b86d15c6ba29 8446
Vanger 0:b86d15c6ba29 8447 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8448 "AES256-GCM-SHA384",
Vanger 0:b86d15c6ba29 8449 #endif
Vanger 0:b86d15c6ba29 8450
Vanger 0:b86d15c6ba29 8451 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8452 "DHE-RSA-AES128-GCM-SHA256",
Vanger 0:b86d15c6ba29 8453 #endif
Vanger 0:b86d15c6ba29 8454
Vanger 0:b86d15c6ba29 8455 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8456 "DHE-RSA-AES256-GCM-SHA384",
Vanger 0:b86d15c6ba29 8457 #endif
Vanger 0:b86d15c6ba29 8458
Vanger 0:b86d15c6ba29 8459 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8460 "ECDHE-RSA-AES128-GCM-SHA256",
Vanger 0:b86d15c6ba29 8461 #endif
Vanger 0:b86d15c6ba29 8462
Vanger 0:b86d15c6ba29 8463 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8464 "ECDHE-RSA-AES256-GCM-SHA384",
Vanger 0:b86d15c6ba29 8465 #endif
Vanger 0:b86d15c6ba29 8466
Vanger 0:b86d15c6ba29 8467 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8468 "ECDHE-ECDSA-AES128-GCM-SHA256",
Vanger 0:b86d15c6ba29 8469 #endif
Vanger 0:b86d15c6ba29 8470
Vanger 0:b86d15c6ba29 8471 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8472 "ECDHE-ECDSA-AES256-GCM-SHA384",
Vanger 0:b86d15c6ba29 8473 #endif
Vanger 0:b86d15c6ba29 8474
Vanger 0:b86d15c6ba29 8475 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8476 "ECDH-RSA-AES128-GCM-SHA256",
Vanger 0:b86d15c6ba29 8477 #endif
Vanger 0:b86d15c6ba29 8478
Vanger 0:b86d15c6ba29 8479 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8480 "ECDH-RSA-AES256-GCM-SHA384",
Vanger 0:b86d15c6ba29 8481 #endif
Vanger 0:b86d15c6ba29 8482
Vanger 0:b86d15c6ba29 8483 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8484 "ECDH-ECDSA-AES128-GCM-SHA256",
Vanger 0:b86d15c6ba29 8485 #endif
Vanger 0:b86d15c6ba29 8486
Vanger 0:b86d15c6ba29 8487 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8488 "ECDH-ECDSA-AES256-GCM-SHA384",
Vanger 0:b86d15c6ba29 8489 #endif
Vanger 0:b86d15c6ba29 8490
Vanger 0:b86d15c6ba29 8491 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
Vanger 0:b86d15c6ba29 8492 "CAMELLIA128-SHA",
Vanger 0:b86d15c6ba29 8493 #endif
Vanger 0:b86d15c6ba29 8494
Vanger 0:b86d15c6ba29 8495 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
Vanger 0:b86d15c6ba29 8496 "DHE-RSA-CAMELLIA128-SHA",
Vanger 0:b86d15c6ba29 8497 #endif
Vanger 0:b86d15c6ba29 8498
Vanger 0:b86d15c6ba29 8499 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
Vanger 0:b86d15c6ba29 8500 "CAMELLIA256-SHA",
Vanger 0:b86d15c6ba29 8501 #endif
Vanger 0:b86d15c6ba29 8502
Vanger 0:b86d15c6ba29 8503 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
Vanger 0:b86d15c6ba29 8504 "DHE-RSA-CAMELLIA256-SHA",
Vanger 0:b86d15c6ba29 8505 #endif
Vanger 0:b86d15c6ba29 8506
Vanger 0:b86d15c6ba29 8507 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8508 "CAMELLIA128-SHA256",
Vanger 0:b86d15c6ba29 8509 #endif
Vanger 0:b86d15c6ba29 8510
Vanger 0:b86d15c6ba29 8511 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8512 "DHE-RSA-CAMELLIA128-SHA256",
Vanger 0:b86d15c6ba29 8513 #endif
Vanger 0:b86d15c6ba29 8514
Vanger 0:b86d15c6ba29 8515 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
Vanger 0:b86d15c6ba29 8516 "CAMELLIA256-SHA256",
Vanger 0:b86d15c6ba29 8517 #endif
Vanger 0:b86d15c6ba29 8518
Vanger 0:b86d15c6ba29 8519 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
Vanger 0:b86d15c6ba29 8520 "DHE-RSA-CAMELLIA256-SHA256",
Vanger 0:b86d15c6ba29 8521 #endif
Vanger 0:b86d15c6ba29 8522
Vanger 0:b86d15c6ba29 8523 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8524 "ECDHE-RSA-AES128-SHA256",
Vanger 0:b86d15c6ba29 8525 #endif
Vanger 0:b86d15c6ba29 8526
Vanger 0:b86d15c6ba29 8527 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8528 "ECDHE-ECDSA-AES128-SHA256",
Vanger 0:b86d15c6ba29 8529 #endif
Vanger 0:b86d15c6ba29 8530
Vanger 0:b86d15c6ba29 8531 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8532 "ECDH-RSA-AES128-SHA256",
Vanger 0:b86d15c6ba29 8533 #endif
Vanger 0:b86d15c6ba29 8534
Vanger 0:b86d15c6ba29 8535 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8536 "ECDH-ECDSA-AES128-SHA256",
Vanger 0:b86d15c6ba29 8537 #endif
Vanger 0:b86d15c6ba29 8538
Vanger 0:b86d15c6ba29 8539 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 8540 "ECDHE-RSA-AES256-SHA384",
Vanger 0:b86d15c6ba29 8541 #endif
Vanger 0:b86d15c6ba29 8542
Vanger 0:b86d15c6ba29 8543 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 8544 "ECDHE-ECDSA-AES256-SHA384",
Vanger 0:b86d15c6ba29 8545 #endif
Vanger 0:b86d15c6ba29 8546
Vanger 0:b86d15c6ba29 8547 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 8548 "ECDH-RSA-AES256-SHA384",
Vanger 0:b86d15c6ba29 8549 #endif
Vanger 0:b86d15c6ba29 8550
Vanger 0:b86d15c6ba29 8551 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 8552 "ECDH-ECDSA-AES256-SHA384",
Vanger 0:b86d15c6ba29 8553 #endif
Vanger 0:b86d15c6ba29 8554
Vanger 0:b86d15c6ba29 8555 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
Vanger 0:b86d15c6ba29 8556 "ECDHE-RSA-CHACHA20-POLY1305",
Vanger 0:b86d15c6ba29 8557 #endif
Vanger 0:b86d15c6ba29 8558
Vanger 0:b86d15c6ba29 8559 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
Vanger 0:b86d15c6ba29 8560 "ECDHE-ECDSA-CHACHA20-POLY1305",
Vanger 0:b86d15c6ba29 8561 #endif
Vanger 0:b86d15c6ba29 8562
Vanger 0:b86d15c6ba29 8563 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
Vanger 0:b86d15c6ba29 8564 "DHE-RSA-CHACHA20-POLY1305",
Vanger 0:b86d15c6ba29 8565 #endif
Vanger 0:b86d15c6ba29 8566
Vanger 0:b86d15c6ba29 8567 #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8568 "ADH-AES128-SHA",
Vanger 0:b86d15c6ba29 8569 #endif
Vanger 0:b86d15c6ba29 8570
Vanger 0:b86d15c6ba29 8571 #ifdef HAVE_RENEGOTIATION_INDICATION
Vanger 0:b86d15c6ba29 8572 "RENEGOTIATION-INFO",
Vanger 0:b86d15c6ba29 8573 #endif
Vanger 0:b86d15c6ba29 8574 };
Vanger 0:b86d15c6ba29 8575
Vanger 0:b86d15c6ba29 8576
Vanger 0:b86d15c6ba29 8577 /* cipher suite number that matches above name table */
Vanger 0:b86d15c6ba29 8578 static int cipher_name_idx[] =
Vanger 0:b86d15c6ba29 8579 {
Vanger 0:b86d15c6ba29 8580
Vanger 0:b86d15c6ba29 8581 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 8582 SSL_RSA_WITH_RC4_128_SHA,
Vanger 0:b86d15c6ba29 8583 #endif
Vanger 0:b86d15c6ba29 8584
Vanger 0:b86d15c6ba29 8585 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
Vanger 0:b86d15c6ba29 8586 SSL_RSA_WITH_RC4_128_MD5,
Vanger 0:b86d15c6ba29 8587 #endif
Vanger 0:b86d15c6ba29 8588
Vanger 0:b86d15c6ba29 8589 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 8590 SSL_RSA_WITH_3DES_EDE_CBC_SHA,
Vanger 0:b86d15c6ba29 8591 #endif
Vanger 0:b86d15c6ba29 8592
Vanger 0:b86d15c6ba29 8593 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8594 TLS_RSA_WITH_AES_128_CBC_SHA,
Vanger 0:b86d15c6ba29 8595 #endif
Vanger 0:b86d15c6ba29 8596
Vanger 0:b86d15c6ba29 8597 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8598 TLS_RSA_WITH_AES_256_CBC_SHA,
Vanger 0:b86d15c6ba29 8599 #endif
Vanger 0:b86d15c6ba29 8600
Vanger 0:b86d15c6ba29 8601 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
Vanger 0:b86d15c6ba29 8602 TLS_RSA_WITH_NULL_SHA,
Vanger 0:b86d15c6ba29 8603 #endif
Vanger 0:b86d15c6ba29 8604
Vanger 0:b86d15c6ba29 8605 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
Vanger 0:b86d15c6ba29 8606 TLS_RSA_WITH_NULL_SHA256,
Vanger 0:b86d15c6ba29 8607 #endif
Vanger 0:b86d15c6ba29 8608
Vanger 0:b86d15c6ba29 8609 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8610 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
Vanger 0:b86d15c6ba29 8611 #endif
Vanger 0:b86d15c6ba29 8612
Vanger 0:b86d15c6ba29 8613 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8614 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
Vanger 0:b86d15c6ba29 8615 #endif
Vanger 0:b86d15c6ba29 8616
Vanger 0:b86d15c6ba29 8617 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8618 TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
Vanger 0:b86d15c6ba29 8619 #endif
Vanger 0:b86d15c6ba29 8620
Vanger 0:b86d15c6ba29 8621 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8622 TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
Vanger 0:b86d15c6ba29 8623 #endif
Vanger 0:b86d15c6ba29 8624
Vanger 0:b86d15c6ba29 8625 #ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8626 TLS_PSK_WITH_AES_256_GCM_SHA384,
Vanger 0:b86d15c6ba29 8627 #endif
Vanger 0:b86d15c6ba29 8628
Vanger 0:b86d15c6ba29 8629 #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8630 TLS_PSK_WITH_AES_128_GCM_SHA256,
Vanger 0:b86d15c6ba29 8631 #endif
Vanger 0:b86d15c6ba29 8632
Vanger 0:b86d15c6ba29 8633 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 8634 TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
Vanger 0:b86d15c6ba29 8635 #endif
Vanger 0:b86d15c6ba29 8636
Vanger 0:b86d15c6ba29 8637 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8638 TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
Vanger 0:b86d15c6ba29 8639 #endif
Vanger 0:b86d15c6ba29 8640
Vanger 0:b86d15c6ba29 8641 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 8642 TLS_PSK_WITH_AES_256_CBC_SHA384,
Vanger 0:b86d15c6ba29 8643 #endif
Vanger 0:b86d15c6ba29 8644
Vanger 0:b86d15c6ba29 8645 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8646 TLS_PSK_WITH_AES_128_CBC_SHA256,
Vanger 0:b86d15c6ba29 8647 #endif
Vanger 0:b86d15c6ba29 8648
Vanger 0:b86d15c6ba29 8649 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8650 TLS_PSK_WITH_AES_128_CBC_SHA,
Vanger 0:b86d15c6ba29 8651 #endif
Vanger 0:b86d15c6ba29 8652
Vanger 0:b86d15c6ba29 8653 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8654 TLS_PSK_WITH_AES_256_CBC_SHA,
Vanger 0:b86d15c6ba29 8655 #endif
Vanger 0:b86d15c6ba29 8656
Vanger 0:b86d15c6ba29 8657 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
Vanger 0:b86d15c6ba29 8658 TLS_DHE_PSK_WITH_AES_128_CCM,
Vanger 0:b86d15c6ba29 8659 #endif
Vanger 0:b86d15c6ba29 8660
Vanger 0:b86d15c6ba29 8661 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
Vanger 0:b86d15c6ba29 8662 TLS_DHE_PSK_WITH_AES_256_CCM,
Vanger 0:b86d15c6ba29 8663 #endif
Vanger 0:b86d15c6ba29 8664
Vanger 0:b86d15c6ba29 8665 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
Vanger 0:b86d15c6ba29 8666 TLS_PSK_WITH_AES_128_CCM,
Vanger 0:b86d15c6ba29 8667 #endif
Vanger 0:b86d15c6ba29 8668
Vanger 0:b86d15c6ba29 8669 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
Vanger 0:b86d15c6ba29 8670 TLS_PSK_WITH_AES_256_CCM,
Vanger 0:b86d15c6ba29 8671 #endif
Vanger 0:b86d15c6ba29 8672
Vanger 0:b86d15c6ba29 8673 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
Vanger 0:b86d15c6ba29 8674 TLS_PSK_WITH_AES_128_CCM_8,
Vanger 0:b86d15c6ba29 8675 #endif
Vanger 0:b86d15c6ba29 8676
Vanger 0:b86d15c6ba29 8677 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
Vanger 0:b86d15c6ba29 8678 TLS_PSK_WITH_AES_256_CCM_8,
Vanger 0:b86d15c6ba29 8679 #endif
Vanger 0:b86d15c6ba29 8680
Vanger 0:b86d15c6ba29 8681 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
Vanger 0:b86d15c6ba29 8682 TLS_DHE_PSK_WITH_NULL_SHA384,
Vanger 0:b86d15c6ba29 8683 #endif
Vanger 0:b86d15c6ba29 8684
Vanger 0:b86d15c6ba29 8685 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
Vanger 0:b86d15c6ba29 8686 TLS_DHE_PSK_WITH_NULL_SHA256,
Vanger 0:b86d15c6ba29 8687 #endif
Vanger 0:b86d15c6ba29 8688
Vanger 0:b86d15c6ba29 8689 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
Vanger 0:b86d15c6ba29 8690 TLS_PSK_WITH_NULL_SHA384,
Vanger 0:b86d15c6ba29 8691 #endif
Vanger 0:b86d15c6ba29 8692
Vanger 0:b86d15c6ba29 8693 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
Vanger 0:b86d15c6ba29 8694 TLS_PSK_WITH_NULL_SHA256,
Vanger 0:b86d15c6ba29 8695 #endif
Vanger 0:b86d15c6ba29 8696
Vanger 0:b86d15c6ba29 8697 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
Vanger 0:b86d15c6ba29 8698 TLS_PSK_WITH_NULL_SHA,
Vanger 0:b86d15c6ba29 8699 #endif
Vanger 0:b86d15c6ba29 8700
Vanger 0:b86d15c6ba29 8701 #ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
Vanger 0:b86d15c6ba29 8702 TLS_RSA_WITH_HC_128_MD5,
Vanger 0:b86d15c6ba29 8703 #endif
Vanger 0:b86d15c6ba29 8704
Vanger 0:b86d15c6ba29 8705 #ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
Vanger 0:b86d15c6ba29 8706 TLS_RSA_WITH_HC_128_SHA,
Vanger 0:b86d15c6ba29 8707 #endif
Vanger 0:b86d15c6ba29 8708
Vanger 0:b86d15c6ba29 8709 #ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
Vanger 0:b86d15c6ba29 8710 TLS_RSA_WITH_HC_128_B2B256,
Vanger 0:b86d15c6ba29 8711 #endif
Vanger 0:b86d15c6ba29 8712
Vanger 0:b86d15c6ba29 8713 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
Vanger 0:b86d15c6ba29 8714 TLS_RSA_WITH_AES_128_CBC_B2B256,
Vanger 0:b86d15c6ba29 8715 #endif
Vanger 0:b86d15c6ba29 8716
Vanger 0:b86d15c6ba29 8717 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
Vanger 0:b86d15c6ba29 8718 TLS_RSA_WITH_AES_256_CBC_B2B256,
Vanger 0:b86d15c6ba29 8719 #endif
Vanger 0:b86d15c6ba29 8720
Vanger 0:b86d15c6ba29 8721 #ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
Vanger 0:b86d15c6ba29 8722 TLS_RSA_WITH_RABBIT_SHA,
Vanger 0:b86d15c6ba29 8723 #endif
Vanger 0:b86d15c6ba29 8724
Vanger 0:b86d15c6ba29 8725 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 8726 TLS_NTRU_RSA_WITH_RC4_128_SHA,
Vanger 0:b86d15c6ba29 8727 #endif
Vanger 0:b86d15c6ba29 8728
Vanger 0:b86d15c6ba29 8729 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 8730 TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA,
Vanger 0:b86d15c6ba29 8731 #endif
Vanger 0:b86d15c6ba29 8732
Vanger 0:b86d15c6ba29 8733 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8734 TLS_NTRU_RSA_WITH_AES_128_CBC_SHA,
Vanger 0:b86d15c6ba29 8735 #endif
Vanger 0:b86d15c6ba29 8736
Vanger 0:b86d15c6ba29 8737 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8738 TLS_NTRU_RSA_WITH_AES_256_CBC_SHA,
Vanger 0:b86d15c6ba29 8739 #endif
Vanger 0:b86d15c6ba29 8740
Vanger 0:b86d15c6ba29 8741 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
Vanger 0:b86d15c6ba29 8742 TLS_RSA_WITH_AES_128_CCM_8,
Vanger 0:b86d15c6ba29 8743 #endif
Vanger 0:b86d15c6ba29 8744
Vanger 0:b86d15c6ba29 8745 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
Vanger 0:b86d15c6ba29 8746 TLS_RSA_WITH_AES_256_CCM_8,
Vanger 0:b86d15c6ba29 8747 #endif
Vanger 0:b86d15c6ba29 8748
Vanger 0:b86d15c6ba29 8749 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
Vanger 0:b86d15c6ba29 8750 TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
Vanger 0:b86d15c6ba29 8751 #endif
Vanger 0:b86d15c6ba29 8752
Vanger 0:b86d15c6ba29 8753 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
Vanger 0:b86d15c6ba29 8754 TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
Vanger 0:b86d15c6ba29 8755 #endif
Vanger 0:b86d15c6ba29 8756
Vanger 0:b86d15c6ba29 8757 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8758 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
Vanger 0:b86d15c6ba29 8759 #endif
Vanger 0:b86d15c6ba29 8760
Vanger 0:b86d15c6ba29 8761 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8762 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
Vanger 0:b86d15c6ba29 8763 #endif
Vanger 0:b86d15c6ba29 8764
Vanger 0:b86d15c6ba29 8765 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8766 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
Vanger 0:b86d15c6ba29 8767 #endif
Vanger 0:b86d15c6ba29 8768
Vanger 0:b86d15c6ba29 8769 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8770 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
Vanger 0:b86d15c6ba29 8771 #endif
Vanger 0:b86d15c6ba29 8772
Vanger 0:b86d15c6ba29 8773 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 8774 TLS_ECDHE_RSA_WITH_RC4_128_SHA,
Vanger 0:b86d15c6ba29 8775 #endif
Vanger 0:b86d15c6ba29 8776
Vanger 0:b86d15c6ba29 8777 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 8778 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
Vanger 0:b86d15c6ba29 8779 #endif
Vanger 0:b86d15c6ba29 8780
Vanger 0:b86d15c6ba29 8781 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 8782 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
Vanger 0:b86d15c6ba29 8783 #endif
Vanger 0:b86d15c6ba29 8784
Vanger 0:b86d15c6ba29 8785 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 8786 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
Vanger 0:b86d15c6ba29 8787 #endif
Vanger 0:b86d15c6ba29 8788
Vanger 0:b86d15c6ba29 8789 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8790 TLS_RSA_WITH_AES_128_CBC_SHA256,
Vanger 0:b86d15c6ba29 8791 #endif
Vanger 0:b86d15c6ba29 8792
Vanger 0:b86d15c6ba29 8793 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
Vanger 0:b86d15c6ba29 8794 TLS_RSA_WITH_AES_256_CBC_SHA256,
Vanger 0:b86d15c6ba29 8795 #endif
Vanger 0:b86d15c6ba29 8796
Vanger 0:b86d15c6ba29 8797 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8798 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
Vanger 0:b86d15c6ba29 8799 #endif
Vanger 0:b86d15c6ba29 8800
Vanger 0:b86d15c6ba29 8801 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Vanger 0:b86d15c6ba29 8802 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
Vanger 0:b86d15c6ba29 8803 #endif
Vanger 0:b86d15c6ba29 8804
Vanger 0:b86d15c6ba29 8805 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8806 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
Vanger 0:b86d15c6ba29 8807 #endif
Vanger 0:b86d15c6ba29 8808
Vanger 0:b86d15c6ba29 8809 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8810 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
Vanger 0:b86d15c6ba29 8811 #endif
Vanger 0:b86d15c6ba29 8812
Vanger 0:b86d15c6ba29 8813 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8814 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
Vanger 0:b86d15c6ba29 8815 #endif
Vanger 0:b86d15c6ba29 8816
Vanger 0:b86d15c6ba29 8817 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Vanger 0:b86d15c6ba29 8818 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
Vanger 0:b86d15c6ba29 8819 #endif
Vanger 0:b86d15c6ba29 8820
Vanger 0:b86d15c6ba29 8821 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 8822 TLS_ECDH_RSA_WITH_RC4_128_SHA,
Vanger 0:b86d15c6ba29 8823 #endif
Vanger 0:b86d15c6ba29 8824
Vanger 0:b86d15c6ba29 8825 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 8826 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
Vanger 0:b86d15c6ba29 8827 #endif
Vanger 0:b86d15c6ba29 8828
Vanger 0:b86d15c6ba29 8829 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
Vanger 0:b86d15c6ba29 8830 TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
Vanger 0:b86d15c6ba29 8831 #endif
Vanger 0:b86d15c6ba29 8832
Vanger 0:b86d15c6ba29 8833 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
Vanger 0:b86d15c6ba29 8834 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
Vanger 0:b86d15c6ba29 8835 #endif
Vanger 0:b86d15c6ba29 8836
Vanger 0:b86d15c6ba29 8837 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8838 TLS_RSA_WITH_AES_128_GCM_SHA256,
Vanger 0:b86d15c6ba29 8839 #endif
Vanger 0:b86d15c6ba29 8840
Vanger 0:b86d15c6ba29 8841 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8842 TLS_RSA_WITH_AES_256_GCM_SHA384,
Vanger 0:b86d15c6ba29 8843 #endif
Vanger 0:b86d15c6ba29 8844
Vanger 0:b86d15c6ba29 8845 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8846 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
Vanger 0:b86d15c6ba29 8847 #endif
Vanger 0:b86d15c6ba29 8848
Vanger 0:b86d15c6ba29 8849 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8850 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
Vanger 0:b86d15c6ba29 8851 #endif
Vanger 0:b86d15c6ba29 8852
Vanger 0:b86d15c6ba29 8853 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8854 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
Vanger 0:b86d15c6ba29 8855 #endif
Vanger 0:b86d15c6ba29 8856
Vanger 0:b86d15c6ba29 8857 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8858 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
Vanger 0:b86d15c6ba29 8859 #endif
Vanger 0:b86d15c6ba29 8860
Vanger 0:b86d15c6ba29 8861 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8862 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
Vanger 0:b86d15c6ba29 8863 #endif
Vanger 0:b86d15c6ba29 8864
Vanger 0:b86d15c6ba29 8865 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8866 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
Vanger 0:b86d15c6ba29 8867 #endif
Vanger 0:b86d15c6ba29 8868
Vanger 0:b86d15c6ba29 8869 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8870 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
Vanger 0:b86d15c6ba29 8871 #endif
Vanger 0:b86d15c6ba29 8872
Vanger 0:b86d15c6ba29 8873 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8874 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
Vanger 0:b86d15c6ba29 8875 #endif
Vanger 0:b86d15c6ba29 8876
Vanger 0:b86d15c6ba29 8877 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
Vanger 0:b86d15c6ba29 8878 TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
Vanger 0:b86d15c6ba29 8879 #endif
Vanger 0:b86d15c6ba29 8880
Vanger 0:b86d15c6ba29 8881 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
Vanger 0:b86d15c6ba29 8882 TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
Vanger 0:b86d15c6ba29 8883 #endif
Vanger 0:b86d15c6ba29 8884
Vanger 0:b86d15c6ba29 8885 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
Vanger 0:b86d15c6ba29 8886 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
Vanger 0:b86d15c6ba29 8887 #endif
Vanger 0:b86d15c6ba29 8888
Vanger 0:b86d15c6ba29 8889 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
Vanger 0:b86d15c6ba29 8890 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
Vanger 0:b86d15c6ba29 8891 #endif
Vanger 0:b86d15c6ba29 8892
Vanger 0:b86d15c6ba29 8893 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
Vanger 0:b86d15c6ba29 8894 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
Vanger 0:b86d15c6ba29 8895 #endif
Vanger 0:b86d15c6ba29 8896
Vanger 0:b86d15c6ba29 8897 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
Vanger 0:b86d15c6ba29 8898 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
Vanger 0:b86d15c6ba29 8899 #endif
Vanger 0:b86d15c6ba29 8900
Vanger 0:b86d15c6ba29 8901 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8902 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
Vanger 0:b86d15c6ba29 8903 #endif
Vanger 0:b86d15c6ba29 8904
Vanger 0:b86d15c6ba29 8905 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8906 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
Vanger 0:b86d15c6ba29 8907 #endif
Vanger 0:b86d15c6ba29 8908
Vanger 0:b86d15c6ba29 8909 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
Vanger 0:b86d15c6ba29 8910 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
Vanger 0:b86d15c6ba29 8911 #endif
Vanger 0:b86d15c6ba29 8912
Vanger 0:b86d15c6ba29 8913 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
Vanger 0:b86d15c6ba29 8914 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
Vanger 0:b86d15c6ba29 8915 #endif
Vanger 0:b86d15c6ba29 8916
Vanger 0:b86d15c6ba29 8917 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8918 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
Vanger 0:b86d15c6ba29 8919 #endif
Vanger 0:b86d15c6ba29 8920
Vanger 0:b86d15c6ba29 8921 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8922 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
Vanger 0:b86d15c6ba29 8923 #endif
Vanger 0:b86d15c6ba29 8924
Vanger 0:b86d15c6ba29 8925 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8926 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
Vanger 0:b86d15c6ba29 8927 #endif
Vanger 0:b86d15c6ba29 8928
Vanger 0:b86d15c6ba29 8929 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Vanger 0:b86d15c6ba29 8930 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
Vanger 0:b86d15c6ba29 8931 #endif
Vanger 0:b86d15c6ba29 8932
Vanger 0:b86d15c6ba29 8933 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 8934 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
Vanger 0:b86d15c6ba29 8935 #endif
Vanger 0:b86d15c6ba29 8936
Vanger 0:b86d15c6ba29 8937 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 8938 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
Vanger 0:b86d15c6ba29 8939 #endif
Vanger 0:b86d15c6ba29 8940
Vanger 0:b86d15c6ba29 8941 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 8942 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
Vanger 0:b86d15c6ba29 8943 #endif
Vanger 0:b86d15c6ba29 8944
Vanger 0:b86d15c6ba29 8945 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Vanger 0:b86d15c6ba29 8946 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
Vanger 0:b86d15c6ba29 8947 #endif
Vanger 0:b86d15c6ba29 8948
Vanger 0:b86d15c6ba29 8949 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
Vanger 0:b86d15c6ba29 8950 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
Vanger 0:b86d15c6ba29 8951 #endif
Vanger 0:b86d15c6ba29 8952
Vanger 0:b86d15c6ba29 8953 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
Vanger 0:b86d15c6ba29 8954 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
Vanger 0:b86d15c6ba29 8955 #endif
Vanger 0:b86d15c6ba29 8956
Vanger 0:b86d15c6ba29 8957 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
Vanger 0:b86d15c6ba29 8958 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
Vanger 0:b86d15c6ba29 8959 #endif
Vanger 0:b86d15c6ba29 8960
Vanger 0:b86d15c6ba29 8961 #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
Vanger 0:b86d15c6ba29 8962 TLS_DH_anon_WITH_AES_128_CBC_SHA,
Vanger 0:b86d15c6ba29 8963 #endif
Vanger 0:b86d15c6ba29 8964
Vanger 0:b86d15c6ba29 8965 #ifdef HAVE_RENEGOTIATION_INDICATION
Vanger 0:b86d15c6ba29 8966 TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
Vanger 0:b86d15c6ba29 8967 #endif
Vanger 0:b86d15c6ba29 8968 };
Vanger 0:b86d15c6ba29 8969
Vanger 0:b86d15c6ba29 8970
Vanger 0:b86d15c6ba29 8971 /* returns the cipher_names array */
Vanger 0:b86d15c6ba29 8972 const char* const* GetCipherNames(void)
Vanger 0:b86d15c6ba29 8973 {
Vanger 0:b86d15c6ba29 8974 return cipher_names;
Vanger 0:b86d15c6ba29 8975 }
Vanger 0:b86d15c6ba29 8976
Vanger 0:b86d15c6ba29 8977
Vanger 0:b86d15c6ba29 8978 /* returns the size of the cipher_names array */
Vanger 0:b86d15c6ba29 8979 int GetCipherNamesSize(void)
Vanger 0:b86d15c6ba29 8980 {
Vanger 0:b86d15c6ba29 8981 return (int)(sizeof(cipher_names) / sizeof(char*));
Vanger 0:b86d15c6ba29 8982 }
Vanger 0:b86d15c6ba29 8983
Vanger 0:b86d15c6ba29 8984
Vanger 0:b86d15c6ba29 8985 /**
Vanger 0:b86d15c6ba29 8986 Set the enabled cipher suites.
Vanger 0:b86d15c6ba29 8987
Vanger 0:b86d15c6ba29 8988 @param [out] suites Suites structure.
Vanger 0:b86d15c6ba29 8989 @param [in] list List of cipher suites, only supports full name from
Vanger 0:b86d15c6ba29 8990 cipher_name[] delimited by ':'.
Vanger 0:b86d15c6ba29 8991
Vanger 0:b86d15c6ba29 8992 @return true on success, else false.
Vanger 0:b86d15c6ba29 8993 */
Vanger 0:b86d15c6ba29 8994 int SetCipherList(Suites* suites, const char* list)
Vanger 0:b86d15c6ba29 8995 {
Vanger 0:b86d15c6ba29 8996 int ret = 0;
Vanger 0:b86d15c6ba29 8997 int idx = 0;
Vanger 0:b86d15c6ba29 8998 int haveRSAsig = 0;
Vanger 0:b86d15c6ba29 8999 int haveECDSAsig = 0;
Vanger 0:b86d15c6ba29 9000 int haveAnon = 0;
Vanger 0:b86d15c6ba29 9001 const int suiteSz = GetCipherNamesSize();
Vanger 0:b86d15c6ba29 9002 char* next = (char*)list;
Vanger 0:b86d15c6ba29 9003
Vanger 0:b86d15c6ba29 9004 if (suites == NULL || list == NULL) {
Vanger 0:b86d15c6ba29 9005 CYASSL_MSG("SetCipherList parameter error");
Vanger 0:b86d15c6ba29 9006 return 0;
Vanger 0:b86d15c6ba29 9007 }
Vanger 0:b86d15c6ba29 9008
Vanger 0:b86d15c6ba29 9009 if (next[0] == 0 || XSTRNCMP(next, "ALL", 3) == 0)
Vanger 0:b86d15c6ba29 9010 return 1; /* CyaSSL defualt */
Vanger 0:b86d15c6ba29 9011
Vanger 0:b86d15c6ba29 9012 do {
Vanger 0:b86d15c6ba29 9013 char* current = next;
Vanger 0:b86d15c6ba29 9014 char name[MAX_SUITE_NAME + 1];
Vanger 0:b86d15c6ba29 9015 int i;
Vanger 0:b86d15c6ba29 9016 word32 length;
Vanger 0:b86d15c6ba29 9017
Vanger 0:b86d15c6ba29 9018 next = XSTRSTR(next, ":");
Vanger 0:b86d15c6ba29 9019 length = min(sizeof(name), !next ? (word32)XSTRLEN(current) /* last */
Vanger 0:b86d15c6ba29 9020 : (word32)(next - current));
Vanger 0:b86d15c6ba29 9021
Vanger 0:b86d15c6ba29 9022 XSTRNCPY(name, current, length);
Vanger 0:b86d15c6ba29 9023 name[(length == sizeof(name)) ? length - 1 : length] = 0;
Vanger 0:b86d15c6ba29 9024
Vanger 0:b86d15c6ba29 9025 for (i = 0; i < suiteSz; i++) {
Vanger 0:b86d15c6ba29 9026 if (XSTRNCMP(name, cipher_names[i], sizeof(name)) == 0) {
Vanger 0:b86d15c6ba29 9027 suites->suites[idx++] = (XSTRSTR(name, "CHACHA")) ? CHACHA_BYTE
Vanger 0:b86d15c6ba29 9028 : (XSTRSTR(name, "EC")) ? ECC_BYTE
Vanger 0:b86d15c6ba29 9029 : (XSTRSTR(name, "CCM")) ? ECC_BYTE
Vanger 0:b86d15c6ba29 9030 : 0x00; /* normal */
Vanger 0:b86d15c6ba29 9031
Vanger 0:b86d15c6ba29 9032 suites->suites[idx++] = (byte)cipher_name_idx[i];
Vanger 0:b86d15c6ba29 9033
Vanger 0:b86d15c6ba29 9034 /* The suites are either ECDSA, RSA, PSK, or Anon. The RSA
Vanger 0:b86d15c6ba29 9035 * suites don't necessarily have RSA in the name. */
Vanger 0:b86d15c6ba29 9036 if ((haveECDSAsig == 0) && XSTRSTR(name, "ECDSA"))
Vanger 0:b86d15c6ba29 9037 haveECDSAsig = 1;
Vanger 0:b86d15c6ba29 9038 else if (XSTRSTR(name, "ADH"))
Vanger 0:b86d15c6ba29 9039 haveAnon = 1;
Vanger 0:b86d15c6ba29 9040 else if ((haveRSAsig == 0) && (XSTRSTR(name, "PSK") == NULL))
Vanger 0:b86d15c6ba29 9041 haveRSAsig = 1;
Vanger 0:b86d15c6ba29 9042
Vanger 0:b86d15c6ba29 9043 ret = 1; /* found at least one */
Vanger 0:b86d15c6ba29 9044 break;
Vanger 0:b86d15c6ba29 9045 }
Vanger 0:b86d15c6ba29 9046 }
Vanger 0:b86d15c6ba29 9047 }
Vanger 0:b86d15c6ba29 9048 while (next++); /* ++ needed to skip ':' */
Vanger 0:b86d15c6ba29 9049
Vanger 0:b86d15c6ba29 9050 if (ret) {
Vanger 0:b86d15c6ba29 9051 suites->setSuites = 1;
Vanger 0:b86d15c6ba29 9052 suites->suiteSz = (word16)idx;
Vanger 0:b86d15c6ba29 9053 InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, haveAnon);
Vanger 0:b86d15c6ba29 9054 }
Vanger 0:b86d15c6ba29 9055
Vanger 0:b86d15c6ba29 9056 return ret;
Vanger 0:b86d15c6ba29 9057 }
Vanger 0:b86d15c6ba29 9058
Vanger 0:b86d15c6ba29 9059
Vanger 0:b86d15c6ba29 9060 static void PickHashSigAlgo(CYASSL* ssl,
Vanger 0:b86d15c6ba29 9061 const byte* hashSigAlgo, word32 hashSigAlgoSz)
Vanger 0:b86d15c6ba29 9062 {
Vanger 0:b86d15c6ba29 9063 word32 i;
Vanger 0:b86d15c6ba29 9064
Vanger 0:b86d15c6ba29 9065 ssl->suites->sigAlgo = ssl->specs.sig_algo;
Vanger 0:b86d15c6ba29 9066 ssl->suites->hashAlgo = sha_mac;
Vanger 0:b86d15c6ba29 9067
Vanger 0:b86d15c6ba29 9068 /* i+1 since peek a byte ahead for type */
Vanger 0:b86d15c6ba29 9069 for (i = 0; (i+1) < hashSigAlgoSz; i += 2) {
Vanger 0:b86d15c6ba29 9070 if (hashSigAlgo[i+1] == ssl->specs.sig_algo) {
Vanger 0:b86d15c6ba29 9071 if (hashSigAlgo[i] == sha_mac) {
Vanger 0:b86d15c6ba29 9072 break;
Vanger 0:b86d15c6ba29 9073 }
Vanger 0:b86d15c6ba29 9074 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 9075 else if (hashSigAlgo[i] == sha256_mac) {
Vanger 0:b86d15c6ba29 9076 ssl->suites->hashAlgo = sha256_mac;
Vanger 0:b86d15c6ba29 9077 break;
Vanger 0:b86d15c6ba29 9078 }
Vanger 0:b86d15c6ba29 9079 #endif
Vanger 0:b86d15c6ba29 9080 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 9081 else if (hashSigAlgo[i] == sha384_mac) {
Vanger 0:b86d15c6ba29 9082 ssl->suites->hashAlgo = sha384_mac;
Vanger 0:b86d15c6ba29 9083 break;
Vanger 0:b86d15c6ba29 9084 }
Vanger 0:b86d15c6ba29 9085 #endif
Vanger 0:b86d15c6ba29 9086 }
Vanger 0:b86d15c6ba29 9087 }
Vanger 0:b86d15c6ba29 9088 }
Vanger 0:b86d15c6ba29 9089
Vanger 0:b86d15c6ba29 9090
Vanger 0:b86d15c6ba29 9091 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 9092
Vanger 0:b86d15c6ba29 9093 /* Initialisze HandShakeInfo */
Vanger 0:b86d15c6ba29 9094 void InitHandShakeInfo(HandShakeInfo* info)
Vanger 0:b86d15c6ba29 9095 {
Vanger 0:b86d15c6ba29 9096 int i;
Vanger 0:b86d15c6ba29 9097
Vanger 0:b86d15c6ba29 9098 info->cipherName[0] = 0;
Vanger 0:b86d15c6ba29 9099 for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
Vanger 0:b86d15c6ba29 9100 info->packetNames[i][0] = 0;
Vanger 0:b86d15c6ba29 9101 info->numberPackets = 0;
Vanger 0:b86d15c6ba29 9102 info->negotiationError = 0;
Vanger 0:b86d15c6ba29 9103 }
Vanger 0:b86d15c6ba29 9104
Vanger 0:b86d15c6ba29 9105 /* Set Final HandShakeInfo parameters */
Vanger 0:b86d15c6ba29 9106 void FinishHandShakeInfo(HandShakeInfo* info, const CYASSL* ssl)
Vanger 0:b86d15c6ba29 9107 {
Vanger 0:b86d15c6ba29 9108 int i;
Vanger 0:b86d15c6ba29 9109 int sz = sizeof(cipher_name_idx)/sizeof(int);
Vanger 0:b86d15c6ba29 9110
Vanger 0:b86d15c6ba29 9111 for (i = 0; i < sz; i++)
Vanger 0:b86d15c6ba29 9112 if (ssl->options.cipherSuite == (byte)cipher_name_idx[i]) {
Vanger 0:b86d15c6ba29 9113 if (ssl->options.cipherSuite0 == ECC_BYTE)
Vanger 0:b86d15c6ba29 9114 continue; /* ECC suites at end */
Vanger 0:b86d15c6ba29 9115 XSTRNCPY(info->cipherName, cipher_names[i], MAX_CIPHERNAME_SZ);
Vanger 0:b86d15c6ba29 9116 break;
Vanger 0:b86d15c6ba29 9117 }
Vanger 0:b86d15c6ba29 9118
Vanger 0:b86d15c6ba29 9119 /* error max and min are negative numbers */
Vanger 0:b86d15c6ba29 9120 if (ssl->error <= MIN_PARAM_ERR && ssl->error >= MAX_PARAM_ERR)
Vanger 0:b86d15c6ba29 9121 info->negotiationError = ssl->error;
Vanger 0:b86d15c6ba29 9122 }
Vanger 0:b86d15c6ba29 9123
Vanger 0:b86d15c6ba29 9124
Vanger 0:b86d15c6ba29 9125 /* Add name to info packet names, increase packet name count */
Vanger 0:b86d15c6ba29 9126 void AddPacketName(const char* name, HandShakeInfo* info)
Vanger 0:b86d15c6ba29 9127 {
Vanger 0:b86d15c6ba29 9128 if (info->numberPackets < MAX_PACKETS_HANDSHAKE) {
Vanger 0:b86d15c6ba29 9129 XSTRNCPY(info->packetNames[info->numberPackets++], name,
Vanger 0:b86d15c6ba29 9130 MAX_PACKETNAME_SZ);
Vanger 0:b86d15c6ba29 9131 }
Vanger 0:b86d15c6ba29 9132 }
Vanger 0:b86d15c6ba29 9133
Vanger 0:b86d15c6ba29 9134
Vanger 0:b86d15c6ba29 9135 /* Initialisze TimeoutInfo */
Vanger 0:b86d15c6ba29 9136 void InitTimeoutInfo(TimeoutInfo* info)
Vanger 0:b86d15c6ba29 9137 {
Vanger 0:b86d15c6ba29 9138 int i;
Vanger 0:b86d15c6ba29 9139
Vanger 0:b86d15c6ba29 9140 info->timeoutName[0] = 0;
Vanger 0:b86d15c6ba29 9141 info->flags = 0;
Vanger 0:b86d15c6ba29 9142
Vanger 0:b86d15c6ba29 9143 for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++) {
Vanger 0:b86d15c6ba29 9144 info->packets[i].packetName[0] = 0;
Vanger 0:b86d15c6ba29 9145 info->packets[i].timestamp.tv_sec = 0;
Vanger 0:b86d15c6ba29 9146 info->packets[i].timestamp.tv_usec = 0;
Vanger 0:b86d15c6ba29 9147 info->packets[i].bufferValue = 0;
Vanger 0:b86d15c6ba29 9148 info->packets[i].valueSz = 0;
Vanger 0:b86d15c6ba29 9149 }
Vanger 0:b86d15c6ba29 9150 info->numberPackets = 0;
Vanger 0:b86d15c6ba29 9151 info->timeoutValue.tv_sec = 0;
Vanger 0:b86d15c6ba29 9152 info->timeoutValue.tv_usec = 0;
Vanger 0:b86d15c6ba29 9153 }
Vanger 0:b86d15c6ba29 9154
Vanger 0:b86d15c6ba29 9155
Vanger 0:b86d15c6ba29 9156 /* Free TimeoutInfo */
Vanger 0:b86d15c6ba29 9157 void FreeTimeoutInfo(TimeoutInfo* info, void* heap)
Vanger 0:b86d15c6ba29 9158 {
Vanger 0:b86d15c6ba29 9159 int i;
Vanger 0:b86d15c6ba29 9160 (void)heap;
Vanger 0:b86d15c6ba29 9161 for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
Vanger 0:b86d15c6ba29 9162 if (info->packets[i].bufferValue) {
Vanger 0:b86d15c6ba29 9163 XFREE(info->packets[i].bufferValue, heap, DYNAMIC_TYPE_INFO);
Vanger 0:b86d15c6ba29 9164 info->packets[i].bufferValue = 0;
Vanger 0:b86d15c6ba29 9165 }
Vanger 0:b86d15c6ba29 9166
Vanger 0:b86d15c6ba29 9167 }
Vanger 0:b86d15c6ba29 9168
Vanger 0:b86d15c6ba29 9169
Vanger 0:b86d15c6ba29 9170 /* Add PacketInfo to TimeoutInfo */
Vanger 0:b86d15c6ba29 9171 void AddPacketInfo(const char* name, TimeoutInfo* info, const byte* data,
Vanger 0:b86d15c6ba29 9172 int sz, void* heap)
Vanger 0:b86d15c6ba29 9173 {
Vanger 0:b86d15c6ba29 9174 if (info->numberPackets < (MAX_PACKETS_HANDSHAKE - 1)) {
Vanger 0:b86d15c6ba29 9175 Timeval currTime;
Vanger 0:b86d15c6ba29 9176
Vanger 0:b86d15c6ba29 9177 /* may add name after */
Vanger 0:b86d15c6ba29 9178 if (name)
Vanger 0:b86d15c6ba29 9179 XSTRNCPY(info->packets[info->numberPackets].packetName, name,
Vanger 0:b86d15c6ba29 9180 MAX_PACKETNAME_SZ);
Vanger 0:b86d15c6ba29 9181
Vanger 0:b86d15c6ba29 9182 /* add data, put in buffer if bigger than static buffer */
Vanger 0:b86d15c6ba29 9183 info->packets[info->numberPackets].valueSz = sz;
Vanger 0:b86d15c6ba29 9184 if (sz < MAX_VALUE_SZ)
Vanger 0:b86d15c6ba29 9185 XMEMCPY(info->packets[info->numberPackets].value, data, sz);
Vanger 0:b86d15c6ba29 9186 else {
Vanger 0:b86d15c6ba29 9187 info->packets[info->numberPackets].bufferValue =
Vanger 0:b86d15c6ba29 9188 XMALLOC(sz, heap, DYNAMIC_TYPE_INFO);
Vanger 0:b86d15c6ba29 9189 if (!info->packets[info->numberPackets].bufferValue)
Vanger 0:b86d15c6ba29 9190 /* let next alloc catch, just don't fill, not fatal here */
Vanger 0:b86d15c6ba29 9191 info->packets[info->numberPackets].valueSz = 0;
Vanger 0:b86d15c6ba29 9192 else
Vanger 0:b86d15c6ba29 9193 XMEMCPY(info->packets[info->numberPackets].bufferValue,
Vanger 0:b86d15c6ba29 9194 data, sz);
Vanger 0:b86d15c6ba29 9195 }
Vanger 0:b86d15c6ba29 9196 gettimeofday(&currTime, 0);
Vanger 0:b86d15c6ba29 9197 info->packets[info->numberPackets].timestamp.tv_sec =
Vanger 0:b86d15c6ba29 9198 currTime.tv_sec;
Vanger 0:b86d15c6ba29 9199 info->packets[info->numberPackets].timestamp.tv_usec =
Vanger 0:b86d15c6ba29 9200 currTime.tv_usec;
Vanger 0:b86d15c6ba29 9201 info->numberPackets++;
Vanger 0:b86d15c6ba29 9202 }
Vanger 0:b86d15c6ba29 9203 }
Vanger 0:b86d15c6ba29 9204
Vanger 0:b86d15c6ba29 9205
Vanger 0:b86d15c6ba29 9206 /* Add packet name to previsouly added packet info */
Vanger 0:b86d15c6ba29 9207 void AddLateName(const char* name, TimeoutInfo* info)
Vanger 0:b86d15c6ba29 9208 {
Vanger 0:b86d15c6ba29 9209 /* make sure we have a valid previous one */
Vanger 0:b86d15c6ba29 9210 if (info->numberPackets > 0 && info->numberPackets <
Vanger 0:b86d15c6ba29 9211 MAX_PACKETS_HANDSHAKE) {
Vanger 0:b86d15c6ba29 9212 XSTRNCPY(info->packets[info->numberPackets - 1].packetName, name,
Vanger 0:b86d15c6ba29 9213 MAX_PACKETNAME_SZ);
Vanger 0:b86d15c6ba29 9214 }
Vanger 0:b86d15c6ba29 9215 }
Vanger 0:b86d15c6ba29 9216
Vanger 0:b86d15c6ba29 9217 /* Add record header to previsouly added packet info */
Vanger 0:b86d15c6ba29 9218 void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info)
Vanger 0:b86d15c6ba29 9219 {
Vanger 0:b86d15c6ba29 9220 /* make sure we have a valid previous one */
Vanger 0:b86d15c6ba29 9221 if (info->numberPackets > 0 && info->numberPackets <
Vanger 0:b86d15c6ba29 9222 MAX_PACKETS_HANDSHAKE) {
Vanger 0:b86d15c6ba29 9223 if (info->packets[info->numberPackets - 1].bufferValue)
Vanger 0:b86d15c6ba29 9224 XMEMCPY(info->packets[info->numberPackets - 1].bufferValue, rl,
Vanger 0:b86d15c6ba29 9225 RECORD_HEADER_SZ);
Vanger 0:b86d15c6ba29 9226 else
Vanger 0:b86d15c6ba29 9227 XMEMCPY(info->packets[info->numberPackets - 1].value, rl,
Vanger 0:b86d15c6ba29 9228 RECORD_HEADER_SZ);
Vanger 0:b86d15c6ba29 9229 }
Vanger 0:b86d15c6ba29 9230 }
Vanger 0:b86d15c6ba29 9231
Vanger 0:b86d15c6ba29 9232 #endif /* CYASSL_CALLBACKS */
Vanger 0:b86d15c6ba29 9233
Vanger 0:b86d15c6ba29 9234
Vanger 0:b86d15c6ba29 9235
Vanger 0:b86d15c6ba29 9236 /* client only parts */
Vanger 0:b86d15c6ba29 9237 #ifndef NO_CYASSL_CLIENT
Vanger 0:b86d15c6ba29 9238
Vanger 0:b86d15c6ba29 9239 int SendClientHello(CYASSL* ssl)
Vanger 0:b86d15c6ba29 9240 {
Vanger 0:b86d15c6ba29 9241 byte *output;
Vanger 0:b86d15c6ba29 9242 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 9243 int sendSz;
Vanger 0:b86d15c6ba29 9244 int idSz = ssl->options.resuming
Vanger 0:b86d15c6ba29 9245 ? ssl->session.sessionIDSz
Vanger 0:b86d15c6ba29 9246 : 0;
Vanger 0:b86d15c6ba29 9247 int ret;
Vanger 0:b86d15c6ba29 9248
Vanger 0:b86d15c6ba29 9249 if (ssl->suites == NULL) {
Vanger 0:b86d15c6ba29 9250 CYASSL_MSG("Bad suites pointer in SendClientHello");
Vanger 0:b86d15c6ba29 9251 return SUITES_ERROR;
Vanger 0:b86d15c6ba29 9252 }
Vanger 0:b86d15c6ba29 9253
Vanger 0:b86d15c6ba29 9254 #ifdef HAVE_SESSION_TICKET
Vanger 0:b86d15c6ba29 9255 if (ssl->options.resuming && ssl->session.ticketLen > 0) {
Vanger 0:b86d15c6ba29 9256 SessionTicket* ticket;
Vanger 0:b86d15c6ba29 9257
Vanger 0:b86d15c6ba29 9258 ticket = TLSX_SessionTicket_Create(0,
Vanger 0:b86d15c6ba29 9259 ssl->session.ticket, ssl->session.ticketLen);
Vanger 0:b86d15c6ba29 9260 if (ticket == NULL) return MEMORY_E;
Vanger 0:b86d15c6ba29 9261
Vanger 0:b86d15c6ba29 9262 ret = TLSX_UseSessionTicket(&ssl->extensions, ticket);
Vanger 0:b86d15c6ba29 9263 if (ret != SSL_SUCCESS) return ret;
Vanger 0:b86d15c6ba29 9264
Vanger 0:b86d15c6ba29 9265 idSz = 0;
Vanger 0:b86d15c6ba29 9266 }
Vanger 0:b86d15c6ba29 9267 #endif
Vanger 0:b86d15c6ba29 9268
Vanger 0:b86d15c6ba29 9269 length = VERSION_SZ + RAN_LEN
Vanger 0:b86d15c6ba29 9270 + idSz + ENUM_LEN
Vanger 0:b86d15c6ba29 9271 + ssl->suites->suiteSz + SUITE_LEN
Vanger 0:b86d15c6ba29 9272 + COMP_LEN + ENUM_LEN;
Vanger 0:b86d15c6ba29 9273
Vanger 0:b86d15c6ba29 9274 #ifdef HAVE_TLS_EXTENSIONS
Vanger 0:b86d15c6ba29 9275 length += TLSX_GetRequestSize(ssl);
Vanger 0:b86d15c6ba29 9276 #else
Vanger 0:b86d15c6ba29 9277 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) {
Vanger 0:b86d15c6ba29 9278 length += ssl->suites->hashSigAlgoSz + HELLO_EXT_SZ;
Vanger 0:b86d15c6ba29 9279 }
Vanger 0:b86d15c6ba29 9280 #endif
Vanger 0:b86d15c6ba29 9281 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 9282
Vanger 0:b86d15c6ba29 9283 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 9284 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 9285 length += ENUM_LEN; /* cookie */
Vanger 0:b86d15c6ba29 9286 if (ssl->arrays->cookieSz != 0) length += ssl->arrays->cookieSz;
Vanger 0:b86d15c6ba29 9287 sendSz = length + DTLS_HANDSHAKE_HEADER_SZ + DTLS_RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 9288 idx += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
Vanger 0:b86d15c6ba29 9289 }
Vanger 0:b86d15c6ba29 9290 #endif
Vanger 0:b86d15c6ba29 9291
Vanger 0:b86d15c6ba29 9292 if (ssl->keys.encryptionOn)
Vanger 0:b86d15c6ba29 9293 sendSz += MAX_MSG_EXTRA;
Vanger 0:b86d15c6ba29 9294
Vanger 0:b86d15c6ba29 9295 /* check for available size */
Vanger 0:b86d15c6ba29 9296 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
Vanger 0:b86d15c6ba29 9297 return ret;
Vanger 0:b86d15c6ba29 9298
Vanger 0:b86d15c6ba29 9299 /* get ouput buffer */
Vanger 0:b86d15c6ba29 9300 output = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 9301 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 9302
Vanger 0:b86d15c6ba29 9303 AddHeaders(output, length, client_hello, ssl);
Vanger 0:b86d15c6ba29 9304
Vanger 0:b86d15c6ba29 9305 /* client hello, first version */
Vanger 0:b86d15c6ba29 9306 output[idx++] = ssl->version.major;
Vanger 0:b86d15c6ba29 9307 output[idx++] = ssl->version.minor;
Vanger 0:b86d15c6ba29 9308 ssl->chVersion = ssl->version; /* store in case changed */
Vanger 0:b86d15c6ba29 9309
Vanger 0:b86d15c6ba29 9310 /* then random */
Vanger 0:b86d15c6ba29 9311 if (ssl->options.connectState == CONNECT_BEGIN) {
Vanger 0:b86d15c6ba29 9312 ret = RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN);
Vanger 0:b86d15c6ba29 9313 if (ret != 0)
Vanger 0:b86d15c6ba29 9314 return ret;
Vanger 0:b86d15c6ba29 9315
Vanger 0:b86d15c6ba29 9316 /* store random */
Vanger 0:b86d15c6ba29 9317 XMEMCPY(ssl->arrays->clientRandom, output + idx, RAN_LEN);
Vanger 0:b86d15c6ba29 9318 } else {
Vanger 0:b86d15c6ba29 9319 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 9320 /* send same random on hello again */
Vanger 0:b86d15c6ba29 9321 XMEMCPY(output + idx, ssl->arrays->clientRandom, RAN_LEN);
Vanger 0:b86d15c6ba29 9322 #endif
Vanger 0:b86d15c6ba29 9323 }
Vanger 0:b86d15c6ba29 9324 idx += RAN_LEN;
Vanger 0:b86d15c6ba29 9325
Vanger 0:b86d15c6ba29 9326 /* then session id */
Vanger 0:b86d15c6ba29 9327 output[idx++] = (byte)idSz;
Vanger 0:b86d15c6ba29 9328 if (idSz) {
Vanger 0:b86d15c6ba29 9329 XMEMCPY(output + idx, ssl->session.sessionID,
Vanger 0:b86d15c6ba29 9330 ssl->session.sessionIDSz);
Vanger 0:b86d15c6ba29 9331 idx += ssl->session.sessionIDSz;
Vanger 0:b86d15c6ba29 9332 }
Vanger 0:b86d15c6ba29 9333
Vanger 0:b86d15c6ba29 9334 /* then DTLS cookie */
Vanger 0:b86d15c6ba29 9335 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 9336 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 9337 byte cookieSz = ssl->arrays->cookieSz;
Vanger 0:b86d15c6ba29 9338
Vanger 0:b86d15c6ba29 9339 output[idx++] = cookieSz;
Vanger 0:b86d15c6ba29 9340 if (cookieSz) {
Vanger 0:b86d15c6ba29 9341 XMEMCPY(&output[idx], ssl->arrays->cookie, cookieSz);
Vanger 0:b86d15c6ba29 9342 idx += cookieSz;
Vanger 0:b86d15c6ba29 9343 }
Vanger 0:b86d15c6ba29 9344 }
Vanger 0:b86d15c6ba29 9345 #endif
Vanger 0:b86d15c6ba29 9346 /* then cipher suites */
Vanger 0:b86d15c6ba29 9347 c16toa(ssl->suites->suiteSz, output + idx);
Vanger 0:b86d15c6ba29 9348 idx += 2;
Vanger 0:b86d15c6ba29 9349 XMEMCPY(output + idx, &ssl->suites->suites, ssl->suites->suiteSz);
Vanger 0:b86d15c6ba29 9350 idx += ssl->suites->suiteSz;
Vanger 0:b86d15c6ba29 9351
Vanger 0:b86d15c6ba29 9352 /* last, compression */
Vanger 0:b86d15c6ba29 9353 output[idx++] = COMP_LEN;
Vanger 0:b86d15c6ba29 9354 if (ssl->options.usingCompression)
Vanger 0:b86d15c6ba29 9355 output[idx++] = ZLIB_COMPRESSION;
Vanger 0:b86d15c6ba29 9356 else
Vanger 0:b86d15c6ba29 9357 output[idx++] = NO_COMPRESSION;
Vanger 0:b86d15c6ba29 9358
Vanger 0:b86d15c6ba29 9359 #ifdef HAVE_TLS_EXTENSIONS
Vanger 0:b86d15c6ba29 9360 idx += TLSX_WriteRequest(ssl, output + idx);
Vanger 0:b86d15c6ba29 9361
Vanger 0:b86d15c6ba29 9362 (void)idx; /* suppress analyzer warning, keep idx current */
Vanger 0:b86d15c6ba29 9363 #else
Vanger 0:b86d15c6ba29 9364 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
Vanger 0:b86d15c6ba29 9365 {
Vanger 0:b86d15c6ba29 9366 int i;
Vanger 0:b86d15c6ba29 9367 /* add in the extensions length */
Vanger 0:b86d15c6ba29 9368 c16toa(HELLO_EXT_LEN + ssl->suites->hashSigAlgoSz, output + idx);
Vanger 0:b86d15c6ba29 9369 idx += 2;
Vanger 0:b86d15c6ba29 9370
Vanger 0:b86d15c6ba29 9371 c16toa(HELLO_EXT_SIG_ALGO, output + idx);
Vanger 0:b86d15c6ba29 9372 idx += 2;
Vanger 0:b86d15c6ba29 9373 c16toa(HELLO_EXT_SIGALGO_SZ+ssl->suites->hashSigAlgoSz, output+idx);
Vanger 0:b86d15c6ba29 9374 idx += 2;
Vanger 0:b86d15c6ba29 9375 c16toa(ssl->suites->hashSigAlgoSz, output + idx);
Vanger 0:b86d15c6ba29 9376 idx += 2;
Vanger 0:b86d15c6ba29 9377 for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, idx++) {
Vanger 0:b86d15c6ba29 9378 output[idx] = ssl->suites->hashSigAlgo[i];
Vanger 0:b86d15c6ba29 9379 }
Vanger 0:b86d15c6ba29 9380 }
Vanger 0:b86d15c6ba29 9381 #endif
Vanger 0:b86d15c6ba29 9382
Vanger 0:b86d15c6ba29 9383 if (ssl->keys.encryptionOn) {
Vanger 0:b86d15c6ba29 9384 byte* input;
Vanger 0:b86d15c6ba29 9385 int inputSz = idx - RECORD_HEADER_SZ; /* build msg adds rec hdr */
Vanger 0:b86d15c6ba29 9386
Vanger 0:b86d15c6ba29 9387 input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 9388 if (input == NULL)
Vanger 0:b86d15c6ba29 9389 return MEMORY_E;
Vanger 0:b86d15c6ba29 9390
Vanger 0:b86d15c6ba29 9391 XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
Vanger 0:b86d15c6ba29 9392 sendSz = BuildMessage(ssl, output, sendSz, input,inputSz,handshake);
Vanger 0:b86d15c6ba29 9393 XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 9394
Vanger 0:b86d15c6ba29 9395 if (sendSz < 0)
Vanger 0:b86d15c6ba29 9396 return sendSz;
Vanger 0:b86d15c6ba29 9397 } else {
Vanger 0:b86d15c6ba29 9398 ret = HashOutput(ssl, output, sendSz, 0);
Vanger 0:b86d15c6ba29 9399 if (ret != 0)
Vanger 0:b86d15c6ba29 9400 return ret;
Vanger 0:b86d15c6ba29 9401 }
Vanger 0:b86d15c6ba29 9402
Vanger 0:b86d15c6ba29 9403 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 9404 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 9405 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
Vanger 0:b86d15c6ba29 9406 return ret;
Vanger 0:b86d15c6ba29 9407 }
Vanger 0:b86d15c6ba29 9408 #endif
Vanger 0:b86d15c6ba29 9409
Vanger 0:b86d15c6ba29 9410 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
Vanger 0:b86d15c6ba29 9411
Vanger 0:b86d15c6ba29 9412 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 9413 if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 9414 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 9415 AddPacketInfo("ClientHello", &ssl->timeoutInfo, output, sendSz,
Vanger 0:b86d15c6ba29 9416 ssl->heap);
Vanger 0:b86d15c6ba29 9417 #endif
Vanger 0:b86d15c6ba29 9418
Vanger 0:b86d15c6ba29 9419 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 9420
Vanger 0:b86d15c6ba29 9421 return SendBuffered(ssl);
Vanger 0:b86d15c6ba29 9422 }
Vanger 0:b86d15c6ba29 9423
Vanger 0:b86d15c6ba29 9424
Vanger 0:b86d15c6ba29 9425 static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input,
Vanger 0:b86d15c6ba29 9426 word32* inOutIdx, word32 size)
Vanger 0:b86d15c6ba29 9427 {
Vanger 0:b86d15c6ba29 9428 ProtocolVersion pv;
Vanger 0:b86d15c6ba29 9429 byte cookieSz;
Vanger 0:b86d15c6ba29 9430 word32 begin = *inOutIdx;
Vanger 0:b86d15c6ba29 9431
Vanger 0:b86d15c6ba29 9432 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 9433 if (ssl->hsInfoOn) AddPacketName("HelloVerifyRequest",
Vanger 0:b86d15c6ba29 9434 &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 9435 if (ssl->toInfoOn) AddLateName("HelloVerifyRequest", &ssl->timeoutInfo);
Vanger 0:b86d15c6ba29 9436 #endif
Vanger 0:b86d15c6ba29 9437
Vanger 0:b86d15c6ba29 9438 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 9439 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 9440 DtlsPoolReset(ssl);
Vanger 0:b86d15c6ba29 9441 }
Vanger 0:b86d15c6ba29 9442 #endif
Vanger 0:b86d15c6ba29 9443
Vanger 0:b86d15c6ba29 9444 if ((*inOutIdx - begin) + OPAQUE16_LEN + OPAQUE8_LEN > size)
Vanger 0:b86d15c6ba29 9445 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9446
Vanger 0:b86d15c6ba29 9447 XMEMCPY(&pv, input + *inOutIdx, OPAQUE16_LEN);
Vanger 0:b86d15c6ba29 9448 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 9449
Vanger 0:b86d15c6ba29 9450 cookieSz = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 9451
Vanger 0:b86d15c6ba29 9452 if (cookieSz) {
Vanger 0:b86d15c6ba29 9453 if ((*inOutIdx - begin) + cookieSz > size)
Vanger 0:b86d15c6ba29 9454 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9455
Vanger 0:b86d15c6ba29 9456 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 9457 if (cookieSz <= MAX_COOKIE_LEN) {
Vanger 0:b86d15c6ba29 9458 XMEMCPY(ssl->arrays->cookie, input + *inOutIdx, cookieSz);
Vanger 0:b86d15c6ba29 9459 ssl->arrays->cookieSz = cookieSz;
Vanger 0:b86d15c6ba29 9460 }
Vanger 0:b86d15c6ba29 9461 #endif
Vanger 0:b86d15c6ba29 9462 *inOutIdx += cookieSz;
Vanger 0:b86d15c6ba29 9463 }
Vanger 0:b86d15c6ba29 9464
Vanger 0:b86d15c6ba29 9465 ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
Vanger 0:b86d15c6ba29 9466 return 0;
Vanger 0:b86d15c6ba29 9467 }
Vanger 0:b86d15c6ba29 9468
Vanger 0:b86d15c6ba29 9469
Vanger 0:b86d15c6ba29 9470 static INLINE int DSH_CheckSessionId(CYASSL* ssl)
Vanger 0:b86d15c6ba29 9471 {
Vanger 0:b86d15c6ba29 9472 int ret = 0;
Vanger 0:b86d15c6ba29 9473
Vanger 0:b86d15c6ba29 9474 #ifdef HAVE_SECRET_CALLBACK
Vanger 0:b86d15c6ba29 9475 /* If a session secret callback exists, we are using that
Vanger 0:b86d15c6ba29 9476 * key instead of the saved session key. */
Vanger 0:b86d15c6ba29 9477 ret = ret || (ssl->sessionSecretCb != NULL);
Vanger 0:b86d15c6ba29 9478 #endif
Vanger 0:b86d15c6ba29 9479
Vanger 0:b86d15c6ba29 9480 #ifdef HAVE_SESSION_TICKET
Vanger 0:b86d15c6ba29 9481 ret = ret ||
Vanger 0:b86d15c6ba29 9482 (!ssl->expect_session_ticket && ssl->session.ticketLen > 0);
Vanger 0:b86d15c6ba29 9483 #endif
Vanger 0:b86d15c6ba29 9484
Vanger 0:b86d15c6ba29 9485 ret = ret ||
Vanger 0:b86d15c6ba29 9486 (ssl->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID,
Vanger 0:b86d15c6ba29 9487 ssl->session.sessionID, ID_LEN) == 0);
Vanger 0:b86d15c6ba29 9488
Vanger 0:b86d15c6ba29 9489 return ret;
Vanger 0:b86d15c6ba29 9490 }
Vanger 0:b86d15c6ba29 9491
Vanger 0:b86d15c6ba29 9492 static int DoServerHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
Vanger 0:b86d15c6ba29 9493 word32 helloSz)
Vanger 0:b86d15c6ba29 9494 {
Vanger 0:b86d15c6ba29 9495 byte cs0; /* cipher suite bytes 0, 1 */
Vanger 0:b86d15c6ba29 9496 byte cs1;
Vanger 0:b86d15c6ba29 9497 ProtocolVersion pv;
Vanger 0:b86d15c6ba29 9498 byte compression;
Vanger 0:b86d15c6ba29 9499 word32 i = *inOutIdx;
Vanger 0:b86d15c6ba29 9500 word32 begin = i;
Vanger 0:b86d15c6ba29 9501
Vanger 0:b86d15c6ba29 9502 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 9503 if (ssl->hsInfoOn) AddPacketName("ServerHello", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 9504 if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
Vanger 0:b86d15c6ba29 9505 #endif
Vanger 0:b86d15c6ba29 9506
Vanger 0:b86d15c6ba29 9507 /* protocol version, random and session id length check */
Vanger 0:b86d15c6ba29 9508 if ((i - begin) + OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
Vanger 0:b86d15c6ba29 9509 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9510
Vanger 0:b86d15c6ba29 9511 /* protocol version */
Vanger 0:b86d15c6ba29 9512 XMEMCPY(&pv, input + i, OPAQUE16_LEN);
Vanger 0:b86d15c6ba29 9513 i += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 9514
Vanger 0:b86d15c6ba29 9515 if (pv.minor > ssl->version.minor) {
Vanger 0:b86d15c6ba29 9516 CYASSL_MSG("Server using higher version, fatal error");
Vanger 0:b86d15c6ba29 9517 return VERSION_ERROR;
Vanger 0:b86d15c6ba29 9518 }
Vanger 0:b86d15c6ba29 9519 else if (pv.minor < ssl->version.minor) {
Vanger 0:b86d15c6ba29 9520 CYASSL_MSG("server using lower version");
Vanger 0:b86d15c6ba29 9521
Vanger 0:b86d15c6ba29 9522 if (!ssl->options.downgrade) {
Vanger 0:b86d15c6ba29 9523 CYASSL_MSG(" no downgrade allowed, fatal error");
Vanger 0:b86d15c6ba29 9524 return VERSION_ERROR;
Vanger 0:b86d15c6ba29 9525 }
Vanger 0:b86d15c6ba29 9526 if (pv.minor < ssl->options.minDowngrade) {
Vanger 0:b86d15c6ba29 9527 CYASSL_MSG(" version below minimum allowed, fatal error");
Vanger 0:b86d15c6ba29 9528 return VERSION_ERROR;
Vanger 0:b86d15c6ba29 9529 }
Vanger 0:b86d15c6ba29 9530
Vanger 0:b86d15c6ba29 9531 #ifdef HAVE_SECURE_RENEGOTIATION
Vanger 0:b86d15c6ba29 9532 if (ssl->secure_renegotiation &&
Vanger 0:b86d15c6ba29 9533 ssl->secure_renegotiation->enabled &&
Vanger 0:b86d15c6ba29 9534 ssl->options.handShakeDone) {
Vanger 0:b86d15c6ba29 9535 CYASSL_MSG("Server changed version during scr");
Vanger 0:b86d15c6ba29 9536 return VERSION_ERROR;
Vanger 0:b86d15c6ba29 9537 }
Vanger 0:b86d15c6ba29 9538 #endif
Vanger 0:b86d15c6ba29 9539
Vanger 0:b86d15c6ba29 9540 if (pv.minor == SSLv3_MINOR) {
Vanger 0:b86d15c6ba29 9541 /* turn off tls */
Vanger 0:b86d15c6ba29 9542 CYASSL_MSG(" downgrading to SSLv3");
Vanger 0:b86d15c6ba29 9543 ssl->options.tls = 0;
Vanger 0:b86d15c6ba29 9544 ssl->options.tls1_1 = 0;
Vanger 0:b86d15c6ba29 9545 ssl->version.minor = SSLv3_MINOR;
Vanger 0:b86d15c6ba29 9546 }
Vanger 0:b86d15c6ba29 9547 else if (pv.minor == TLSv1_MINOR) {
Vanger 0:b86d15c6ba29 9548 /* turn off tls 1.1+ */
Vanger 0:b86d15c6ba29 9549 CYASSL_MSG(" downgrading to TLSv1");
Vanger 0:b86d15c6ba29 9550 ssl->options.tls1_1 = 0;
Vanger 0:b86d15c6ba29 9551 ssl->version.minor = TLSv1_MINOR;
Vanger 0:b86d15c6ba29 9552 }
Vanger 0:b86d15c6ba29 9553 else if (pv.minor == TLSv1_1_MINOR) {
Vanger 0:b86d15c6ba29 9554 CYASSL_MSG(" downgrading to TLSv1.1");
Vanger 0:b86d15c6ba29 9555 ssl->version.minor = TLSv1_1_MINOR;
Vanger 0:b86d15c6ba29 9556 }
Vanger 0:b86d15c6ba29 9557 }
Vanger 0:b86d15c6ba29 9558
Vanger 0:b86d15c6ba29 9559 /* random */
Vanger 0:b86d15c6ba29 9560 XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN);
Vanger 0:b86d15c6ba29 9561 i += RAN_LEN;
Vanger 0:b86d15c6ba29 9562
Vanger 0:b86d15c6ba29 9563 /* session id */
Vanger 0:b86d15c6ba29 9564 ssl->arrays->sessionIDSz = input[i++];
Vanger 0:b86d15c6ba29 9565
Vanger 0:b86d15c6ba29 9566 if (ssl->arrays->sessionIDSz > ID_LEN) {
Vanger 0:b86d15c6ba29 9567 CYASSL_MSG("Invalid session ID size");
Vanger 0:b86d15c6ba29 9568 ssl->arrays->sessionIDSz = 0;
Vanger 0:b86d15c6ba29 9569 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9570 }
Vanger 0:b86d15c6ba29 9571 else if (ssl->arrays->sessionIDSz) {
Vanger 0:b86d15c6ba29 9572 if ((i - begin) + ssl->arrays->sessionIDSz > helloSz)
Vanger 0:b86d15c6ba29 9573 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9574
Vanger 0:b86d15c6ba29 9575 XMEMCPY(ssl->arrays->sessionID, input + i,
Vanger 0:b86d15c6ba29 9576 ssl->arrays->sessionIDSz);
Vanger 0:b86d15c6ba29 9577 i += ssl->arrays->sessionIDSz;
Vanger 0:b86d15c6ba29 9578 ssl->options.haveSessionId = 1;
Vanger 0:b86d15c6ba29 9579 }
Vanger 0:b86d15c6ba29 9580
Vanger 0:b86d15c6ba29 9581
Vanger 0:b86d15c6ba29 9582 /* suite and compression */
Vanger 0:b86d15c6ba29 9583 if ((i - begin) + OPAQUE16_LEN + OPAQUE8_LEN > helloSz)
Vanger 0:b86d15c6ba29 9584 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9585
Vanger 0:b86d15c6ba29 9586 cs0 = input[i++];
Vanger 0:b86d15c6ba29 9587 cs1 = input[i++];
Vanger 0:b86d15c6ba29 9588
Vanger 0:b86d15c6ba29 9589 #ifdef HAVE_SECURE_RENEGOTIATION
Vanger 0:b86d15c6ba29 9590 if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled &&
Vanger 0:b86d15c6ba29 9591 ssl->options.handShakeDone) {
Vanger 0:b86d15c6ba29 9592 if (ssl->options.cipherSuite0 != cs0 ||
Vanger 0:b86d15c6ba29 9593 ssl->options.cipherSuite != cs1) {
Vanger 0:b86d15c6ba29 9594 CYASSL_MSG("Server changed cipher suite during scr");
Vanger 0:b86d15c6ba29 9595 return MATCH_SUITE_ERROR;
Vanger 0:b86d15c6ba29 9596 }
Vanger 0:b86d15c6ba29 9597 }
Vanger 0:b86d15c6ba29 9598 #endif
Vanger 0:b86d15c6ba29 9599
Vanger 0:b86d15c6ba29 9600 ssl->options.cipherSuite0 = cs0;
Vanger 0:b86d15c6ba29 9601 ssl->options.cipherSuite = cs1;
Vanger 0:b86d15c6ba29 9602 compression = input[i++];
Vanger 0:b86d15c6ba29 9603
Vanger 0:b86d15c6ba29 9604 if (compression != ZLIB_COMPRESSION && ssl->options.usingCompression) {
Vanger 0:b86d15c6ba29 9605 CYASSL_MSG("Server refused compression, turning off");
Vanger 0:b86d15c6ba29 9606 ssl->options.usingCompression = 0; /* turn off if server refused */
Vanger 0:b86d15c6ba29 9607 }
Vanger 0:b86d15c6ba29 9608
Vanger 0:b86d15c6ba29 9609 *inOutIdx = i;
Vanger 0:b86d15c6ba29 9610
Vanger 0:b86d15c6ba29 9611 /* tls extensions */
Vanger 0:b86d15c6ba29 9612 if ( (i - begin) < helloSz) {
Vanger 0:b86d15c6ba29 9613 #ifdef HAVE_TLS_EXTENSIONS
Vanger 0:b86d15c6ba29 9614 if (TLSX_SupportExtensions(ssl)) {
Vanger 0:b86d15c6ba29 9615 int ret = 0;
Vanger 0:b86d15c6ba29 9616 word16 totalExtSz;
Vanger 0:b86d15c6ba29 9617
Vanger 0:b86d15c6ba29 9618 if ((i - begin) + OPAQUE16_LEN > helloSz)
Vanger 0:b86d15c6ba29 9619 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9620
Vanger 0:b86d15c6ba29 9621 ato16(&input[i], &totalExtSz);
Vanger 0:b86d15c6ba29 9622 i += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 9623
Vanger 0:b86d15c6ba29 9624 if ((i - begin) + totalExtSz > helloSz)
Vanger 0:b86d15c6ba29 9625 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9626
Vanger 0:b86d15c6ba29 9627 if ((ret = TLSX_Parse(ssl, (byte *) input + i,
Vanger 0:b86d15c6ba29 9628 totalExtSz, 0, NULL)))
Vanger 0:b86d15c6ba29 9629 return ret;
Vanger 0:b86d15c6ba29 9630
Vanger 0:b86d15c6ba29 9631 i += totalExtSz;
Vanger 0:b86d15c6ba29 9632 *inOutIdx = i;
Vanger 0:b86d15c6ba29 9633 }
Vanger 0:b86d15c6ba29 9634 else
Vanger 0:b86d15c6ba29 9635 #endif
Vanger 0:b86d15c6ba29 9636 *inOutIdx = begin + helloSz; /* skip extensions */
Vanger 0:b86d15c6ba29 9637 }
Vanger 0:b86d15c6ba29 9638
Vanger 0:b86d15c6ba29 9639 ssl->options.serverState = SERVER_HELLO_COMPLETE;
Vanger 0:b86d15c6ba29 9640
Vanger 0:b86d15c6ba29 9641 if (ssl->keys.encryptionOn) {
Vanger 0:b86d15c6ba29 9642 *inOutIdx += ssl->keys.padSz;
Vanger 0:b86d15c6ba29 9643 }
Vanger 0:b86d15c6ba29 9644
Vanger 0:b86d15c6ba29 9645 #ifdef HAVE_SECRET_CALLBACK
Vanger 0:b86d15c6ba29 9646 if (ssl->sessionSecretCb != NULL) {
Vanger 0:b86d15c6ba29 9647 int secretSz = SECRET_LEN, ret;
Vanger 0:b86d15c6ba29 9648 ret = ssl->sessionSecretCb(ssl, ssl->session.masterSecret,
Vanger 0:b86d15c6ba29 9649 &secretSz, ssl->sessionSecretCtx);
Vanger 0:b86d15c6ba29 9650 if (ret != 0 || secretSz != SECRET_LEN)
Vanger 0:b86d15c6ba29 9651 return SESSION_SECRET_CB_E;
Vanger 0:b86d15c6ba29 9652 }
Vanger 0:b86d15c6ba29 9653 #endif /* HAVE_SECRET_CALLBACK */
Vanger 0:b86d15c6ba29 9654
Vanger 0:b86d15c6ba29 9655 if (ssl->options.resuming) {
Vanger 0:b86d15c6ba29 9656 if (DSH_CheckSessionId(ssl)) {
Vanger 0:b86d15c6ba29 9657 if (SetCipherSpecs(ssl) == 0) {
Vanger 0:b86d15c6ba29 9658 int ret = -1;
Vanger 0:b86d15c6ba29 9659
Vanger 0:b86d15c6ba29 9660 XMEMCPY(ssl->arrays->masterSecret,
Vanger 0:b86d15c6ba29 9661 ssl->session.masterSecret, SECRET_LEN);
Vanger 0:b86d15c6ba29 9662 #ifdef NO_OLD_TLS
Vanger 0:b86d15c6ba29 9663 ret = DeriveTlsKeys(ssl);
Vanger 0:b86d15c6ba29 9664 #else
Vanger 0:b86d15c6ba29 9665 #ifndef NO_TLS
Vanger 0:b86d15c6ba29 9666 if (ssl->options.tls)
Vanger 0:b86d15c6ba29 9667 ret = DeriveTlsKeys(ssl);
Vanger 0:b86d15c6ba29 9668 #endif
Vanger 0:b86d15c6ba29 9669 if (!ssl->options.tls)
Vanger 0:b86d15c6ba29 9670 ret = DeriveKeys(ssl);
Vanger 0:b86d15c6ba29 9671 #endif
Vanger 0:b86d15c6ba29 9672 ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
Vanger 0:b86d15c6ba29 9673
Vanger 0:b86d15c6ba29 9674 return ret;
Vanger 0:b86d15c6ba29 9675 }
Vanger 0:b86d15c6ba29 9676 else {
Vanger 0:b86d15c6ba29 9677 CYASSL_MSG("Unsupported cipher suite, DoServerHello");
Vanger 0:b86d15c6ba29 9678 return UNSUPPORTED_SUITE;
Vanger 0:b86d15c6ba29 9679 }
Vanger 0:b86d15c6ba29 9680 }
Vanger 0:b86d15c6ba29 9681 else {
Vanger 0:b86d15c6ba29 9682 CYASSL_MSG("Server denied resumption attempt");
Vanger 0:b86d15c6ba29 9683 ssl->options.resuming = 0; /* server denied resumption try */
Vanger 0:b86d15c6ba29 9684 }
Vanger 0:b86d15c6ba29 9685 }
Vanger 0:b86d15c6ba29 9686 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 9687 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 9688 DtlsPoolReset(ssl);
Vanger 0:b86d15c6ba29 9689 }
Vanger 0:b86d15c6ba29 9690 #endif
Vanger 0:b86d15c6ba29 9691
Vanger 0:b86d15c6ba29 9692 return SetCipherSpecs(ssl);
Vanger 0:b86d15c6ba29 9693 }
Vanger 0:b86d15c6ba29 9694
Vanger 0:b86d15c6ba29 9695
Vanger 0:b86d15c6ba29 9696 /* Make sure client setup is valid for this suite, true on success */
Vanger 0:b86d15c6ba29 9697 int VerifyClientSuite(CYASSL* ssl)
Vanger 0:b86d15c6ba29 9698 {
Vanger 0:b86d15c6ba29 9699 int havePSK = 0;
Vanger 0:b86d15c6ba29 9700 byte first = ssl->options.cipherSuite0;
Vanger 0:b86d15c6ba29 9701 byte second = ssl->options.cipherSuite;
Vanger 0:b86d15c6ba29 9702
Vanger 0:b86d15c6ba29 9703 CYASSL_ENTER("VerifyClientSuite");
Vanger 0:b86d15c6ba29 9704
Vanger 0:b86d15c6ba29 9705 #ifndef NO_PSK
Vanger 0:b86d15c6ba29 9706 havePSK = ssl->options.havePSK;
Vanger 0:b86d15c6ba29 9707 #endif
Vanger 0:b86d15c6ba29 9708
Vanger 0:b86d15c6ba29 9709 if (CipherRequires(first, second, REQUIRES_PSK)) {
Vanger 0:b86d15c6ba29 9710 CYASSL_MSG("Requires PSK");
Vanger 0:b86d15c6ba29 9711 if (havePSK == 0) {
Vanger 0:b86d15c6ba29 9712 CYASSL_MSG("Don't have PSK");
Vanger 0:b86d15c6ba29 9713 return 0;
Vanger 0:b86d15c6ba29 9714 }
Vanger 0:b86d15c6ba29 9715 }
Vanger 0:b86d15c6ba29 9716
Vanger 0:b86d15c6ba29 9717 return 1; /* success */
Vanger 0:b86d15c6ba29 9718 }
Vanger 0:b86d15c6ba29 9719
Vanger 0:b86d15c6ba29 9720
Vanger 0:b86d15c6ba29 9721 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 9722 /* just read in and ignore for now TODO: */
Vanger 0:b86d15c6ba29 9723 static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32*
Vanger 0:b86d15c6ba29 9724 inOutIdx, word32 size)
Vanger 0:b86d15c6ba29 9725 {
Vanger 0:b86d15c6ba29 9726 word16 len;
Vanger 0:b86d15c6ba29 9727 word32 begin = *inOutIdx;
Vanger 0:b86d15c6ba29 9728
Vanger 0:b86d15c6ba29 9729 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 9730 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 9731 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 9732 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 9733 AddLateName("CertificateRequest", &ssl->timeoutInfo);
Vanger 0:b86d15c6ba29 9734 #endif
Vanger 0:b86d15c6ba29 9735
Vanger 0:b86d15c6ba29 9736 if ((*inOutIdx - begin) + OPAQUE8_LEN > size)
Vanger 0:b86d15c6ba29 9737 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9738
Vanger 0:b86d15c6ba29 9739 len = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 9740
Vanger 0:b86d15c6ba29 9741 if ((*inOutIdx - begin) + len > size)
Vanger 0:b86d15c6ba29 9742 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9743
Vanger 0:b86d15c6ba29 9744 /* types, read in here */
Vanger 0:b86d15c6ba29 9745 *inOutIdx += len;
Vanger 0:b86d15c6ba29 9746
Vanger 0:b86d15c6ba29 9747 /* signature and hash signature algorithm */
Vanger 0:b86d15c6ba29 9748 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 9749 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 9750 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9751
Vanger 0:b86d15c6ba29 9752 ato16(input + *inOutIdx, &len);
Vanger 0:b86d15c6ba29 9753 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 9754
Vanger 0:b86d15c6ba29 9755 if ((*inOutIdx - begin) + len > size)
Vanger 0:b86d15c6ba29 9756 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9757
Vanger 0:b86d15c6ba29 9758 PickHashSigAlgo(ssl, input + *inOutIdx, len);
Vanger 0:b86d15c6ba29 9759 *inOutIdx += len;
Vanger 0:b86d15c6ba29 9760 }
Vanger 0:b86d15c6ba29 9761
Vanger 0:b86d15c6ba29 9762 /* authorities */
Vanger 0:b86d15c6ba29 9763 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 9764 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9765
Vanger 0:b86d15c6ba29 9766 ato16(input + *inOutIdx, &len);
Vanger 0:b86d15c6ba29 9767 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 9768
Vanger 0:b86d15c6ba29 9769 if ((*inOutIdx - begin) + len > size)
Vanger 0:b86d15c6ba29 9770 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9771
Vanger 0:b86d15c6ba29 9772 while (len) {
Vanger 0:b86d15c6ba29 9773 word16 dnSz;
Vanger 0:b86d15c6ba29 9774
Vanger 0:b86d15c6ba29 9775 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 9776 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9777
Vanger 0:b86d15c6ba29 9778 ato16(input + *inOutIdx, &dnSz);
Vanger 0:b86d15c6ba29 9779 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 9780
Vanger 0:b86d15c6ba29 9781 if ((*inOutIdx - begin) + dnSz > size)
Vanger 0:b86d15c6ba29 9782 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9783
Vanger 0:b86d15c6ba29 9784 *inOutIdx += dnSz;
Vanger 0:b86d15c6ba29 9785 len -= OPAQUE16_LEN + dnSz;
Vanger 0:b86d15c6ba29 9786 }
Vanger 0:b86d15c6ba29 9787
Vanger 0:b86d15c6ba29 9788 /* don't send client cert or cert verify if user hasn't provided
Vanger 0:b86d15c6ba29 9789 cert and private key */
Vanger 0:b86d15c6ba29 9790 if (ssl->buffers.certificate.buffer && ssl->buffers.key.buffer)
Vanger 0:b86d15c6ba29 9791 ssl->options.sendVerify = SEND_CERT;
Vanger 0:b86d15c6ba29 9792 else if (IsTLS(ssl))
Vanger 0:b86d15c6ba29 9793 ssl->options.sendVerify = SEND_BLANK_CERT;
Vanger 0:b86d15c6ba29 9794
Vanger 0:b86d15c6ba29 9795 if (ssl->keys.encryptionOn)
Vanger 0:b86d15c6ba29 9796 *inOutIdx += ssl->keys.padSz;
Vanger 0:b86d15c6ba29 9797
Vanger 0:b86d15c6ba29 9798 return 0;
Vanger 0:b86d15c6ba29 9799 }
Vanger 0:b86d15c6ba29 9800 #endif /* !NO_CERTS */
Vanger 0:b86d15c6ba29 9801
Vanger 0:b86d15c6ba29 9802
Vanger 0:b86d15c6ba29 9803 static int DoServerKeyExchange(CYASSL* ssl, const byte* input,
Vanger 0:b86d15c6ba29 9804 word32* inOutIdx, word32 size)
Vanger 0:b86d15c6ba29 9805 {
Vanger 0:b86d15c6ba29 9806 word16 length = 0;
Vanger 0:b86d15c6ba29 9807 word32 begin = *inOutIdx;
Vanger 0:b86d15c6ba29 9808 int ret = 0;
Vanger 0:b86d15c6ba29 9809 #define ERROR_OUT(err, eLabel) do { ret = err; goto eLabel; } while(0)
Vanger 0:b86d15c6ba29 9810
Vanger 0:b86d15c6ba29 9811 (void)length; /* shut up compiler warnings */
Vanger 0:b86d15c6ba29 9812 (void)begin;
Vanger 0:b86d15c6ba29 9813 (void)ssl;
Vanger 0:b86d15c6ba29 9814 (void)input;
Vanger 0:b86d15c6ba29 9815 (void)size;
Vanger 0:b86d15c6ba29 9816 (void)ret;
Vanger 0:b86d15c6ba29 9817
Vanger 0:b86d15c6ba29 9818 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 9819 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 9820 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 9821 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 9822 AddLateName("ServerKeyExchange", &ssl->timeoutInfo);
Vanger 0:b86d15c6ba29 9823 #endif
Vanger 0:b86d15c6ba29 9824
Vanger 0:b86d15c6ba29 9825 #ifndef NO_PSK
Vanger 0:b86d15c6ba29 9826 if (ssl->specs.kea == psk_kea) {
Vanger 0:b86d15c6ba29 9827
Vanger 0:b86d15c6ba29 9828 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 9829 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9830
Vanger 0:b86d15c6ba29 9831 ato16(input + *inOutIdx, &length);
Vanger 0:b86d15c6ba29 9832 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 9833
Vanger 0:b86d15c6ba29 9834 if ((*inOutIdx - begin) + length > size)
Vanger 0:b86d15c6ba29 9835 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9836
Vanger 0:b86d15c6ba29 9837 XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx,
Vanger 0:b86d15c6ba29 9838 min(length, MAX_PSK_ID_LEN));
Vanger 0:b86d15c6ba29 9839
Vanger 0:b86d15c6ba29 9840 ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0;
Vanger 0:b86d15c6ba29 9841 *inOutIdx += length;
Vanger 0:b86d15c6ba29 9842
Vanger 0:b86d15c6ba29 9843 return 0;
Vanger 0:b86d15c6ba29 9844 }
Vanger 0:b86d15c6ba29 9845 #endif
Vanger 0:b86d15c6ba29 9846 #ifndef NO_DH
Vanger 0:b86d15c6ba29 9847 if (ssl->specs.kea == diffie_hellman_kea)
Vanger 0:b86d15c6ba29 9848 {
Vanger 0:b86d15c6ba29 9849 /* p */
Vanger 0:b86d15c6ba29 9850 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 9851 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9852
Vanger 0:b86d15c6ba29 9853 ato16(input + *inOutIdx, &length);
Vanger 0:b86d15c6ba29 9854 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 9855
Vanger 0:b86d15c6ba29 9856 if ((*inOutIdx - begin) + length > size)
Vanger 0:b86d15c6ba29 9857 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9858
Vanger 0:b86d15c6ba29 9859 ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
Vanger 0:b86d15c6ba29 9860 DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 9861
Vanger 0:b86d15c6ba29 9862 if (ssl->buffers.serverDH_P.buffer)
Vanger 0:b86d15c6ba29 9863 ssl->buffers.serverDH_P.length = length;
Vanger 0:b86d15c6ba29 9864 else
Vanger 0:b86d15c6ba29 9865 return MEMORY_ERROR;
Vanger 0:b86d15c6ba29 9866
Vanger 0:b86d15c6ba29 9867 XMEMCPY(ssl->buffers.serverDH_P.buffer, input + *inOutIdx, length);
Vanger 0:b86d15c6ba29 9868 *inOutIdx += length;
Vanger 0:b86d15c6ba29 9869
Vanger 0:b86d15c6ba29 9870 /* g */
Vanger 0:b86d15c6ba29 9871 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 9872 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9873
Vanger 0:b86d15c6ba29 9874 ato16(input + *inOutIdx, &length);
Vanger 0:b86d15c6ba29 9875 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 9876
Vanger 0:b86d15c6ba29 9877 if ((*inOutIdx - begin) + length > size)
Vanger 0:b86d15c6ba29 9878 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9879
Vanger 0:b86d15c6ba29 9880 ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
Vanger 0:b86d15c6ba29 9881 DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 9882
Vanger 0:b86d15c6ba29 9883 if (ssl->buffers.serverDH_G.buffer)
Vanger 0:b86d15c6ba29 9884 ssl->buffers.serverDH_G.length = length;
Vanger 0:b86d15c6ba29 9885 else
Vanger 0:b86d15c6ba29 9886 return MEMORY_ERROR;
Vanger 0:b86d15c6ba29 9887
Vanger 0:b86d15c6ba29 9888 XMEMCPY(ssl->buffers.serverDH_G.buffer, input + *inOutIdx, length);
Vanger 0:b86d15c6ba29 9889 *inOutIdx += length;
Vanger 0:b86d15c6ba29 9890
Vanger 0:b86d15c6ba29 9891 /* pub */
Vanger 0:b86d15c6ba29 9892 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 9893 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9894
Vanger 0:b86d15c6ba29 9895 ato16(input + *inOutIdx, &length);
Vanger 0:b86d15c6ba29 9896 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 9897
Vanger 0:b86d15c6ba29 9898 if ((*inOutIdx - begin) + length > size)
Vanger 0:b86d15c6ba29 9899 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9900
Vanger 0:b86d15c6ba29 9901 ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap,
Vanger 0:b86d15c6ba29 9902 DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 9903
Vanger 0:b86d15c6ba29 9904 if (ssl->buffers.serverDH_Pub.buffer)
Vanger 0:b86d15c6ba29 9905 ssl->buffers.serverDH_Pub.length = length;
Vanger 0:b86d15c6ba29 9906 else
Vanger 0:b86d15c6ba29 9907 return MEMORY_ERROR;
Vanger 0:b86d15c6ba29 9908
Vanger 0:b86d15c6ba29 9909 XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + *inOutIdx, length);
Vanger 0:b86d15c6ba29 9910 *inOutIdx += length;
Vanger 0:b86d15c6ba29 9911 } /* dh_kea */
Vanger 0:b86d15c6ba29 9912 #endif /* NO_DH */
Vanger 0:b86d15c6ba29 9913
Vanger 0:b86d15c6ba29 9914 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 9915 if (ssl->specs.kea == ecc_diffie_hellman_kea)
Vanger 0:b86d15c6ba29 9916 {
Vanger 0:b86d15c6ba29 9917 byte b;
Vanger 0:b86d15c6ba29 9918
Vanger 0:b86d15c6ba29 9919 if ((*inOutIdx - begin) + ENUM_LEN + OPAQUE16_LEN + OPAQUE8_LEN > size)
Vanger 0:b86d15c6ba29 9920 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9921
Vanger 0:b86d15c6ba29 9922 b = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 9923
Vanger 0:b86d15c6ba29 9924 if (b != named_curve)
Vanger 0:b86d15c6ba29 9925 return ECC_CURVETYPE_ERROR;
Vanger 0:b86d15c6ba29 9926
Vanger 0:b86d15c6ba29 9927 *inOutIdx += 1; /* curve type, eat leading 0 */
Vanger 0:b86d15c6ba29 9928 b = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 9929
Vanger 0:b86d15c6ba29 9930 if (b != secp256r1 && b != secp384r1 && b != secp521r1 && b !=
Vanger 0:b86d15c6ba29 9931 secp160r1 && b != secp192r1 && b != secp224r1)
Vanger 0:b86d15c6ba29 9932 return ECC_CURVE_ERROR;
Vanger 0:b86d15c6ba29 9933
Vanger 0:b86d15c6ba29 9934 length = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 9935
Vanger 0:b86d15c6ba29 9936 if ((*inOutIdx - begin) + length > size)
Vanger 0:b86d15c6ba29 9937 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9938
Vanger 0:b86d15c6ba29 9939 if (ssl->peerEccKeyPresent) { /* don't leak on reuse */
Vanger 0:b86d15c6ba29 9940 ecc_free(ssl->peerEccKey);
Vanger 0:b86d15c6ba29 9941 ssl->peerEccKeyPresent = 0;
Vanger 0:b86d15c6ba29 9942 ecc_init(ssl->peerEccKey);
Vanger 0:b86d15c6ba29 9943 }
Vanger 0:b86d15c6ba29 9944
Vanger 0:b86d15c6ba29 9945 if (ecc_import_x963(input + *inOutIdx, length, ssl->peerEccKey) != 0)
Vanger 0:b86d15c6ba29 9946 return ECC_PEERKEY_ERROR;
Vanger 0:b86d15c6ba29 9947
Vanger 0:b86d15c6ba29 9948 *inOutIdx += length;
Vanger 0:b86d15c6ba29 9949 ssl->peerEccKeyPresent = 1;
Vanger 0:b86d15c6ba29 9950 }
Vanger 0:b86d15c6ba29 9951 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 9952
Vanger 0:b86d15c6ba29 9953 #if !defined(NO_DH) && !defined(NO_PSK)
Vanger 0:b86d15c6ba29 9954 if (ssl->specs.kea == dhe_psk_kea) {
Vanger 0:b86d15c6ba29 9955 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 9956 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9957
Vanger 0:b86d15c6ba29 9958 ato16(input + *inOutIdx, &length);
Vanger 0:b86d15c6ba29 9959 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 9960
Vanger 0:b86d15c6ba29 9961 if ((*inOutIdx - begin) + length > size)
Vanger 0:b86d15c6ba29 9962 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9963
Vanger 0:b86d15c6ba29 9964 XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx,
Vanger 0:b86d15c6ba29 9965 min(length, MAX_PSK_ID_LEN));
Vanger 0:b86d15c6ba29 9966
Vanger 0:b86d15c6ba29 9967 ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0;
Vanger 0:b86d15c6ba29 9968 *inOutIdx += length;
Vanger 0:b86d15c6ba29 9969
Vanger 0:b86d15c6ba29 9970 /* p */
Vanger 0:b86d15c6ba29 9971 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 9972 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9973
Vanger 0:b86d15c6ba29 9974 ato16(input + *inOutIdx, &length);
Vanger 0:b86d15c6ba29 9975 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 9976
Vanger 0:b86d15c6ba29 9977 if ((*inOutIdx - begin) + length > size)
Vanger 0:b86d15c6ba29 9978 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9979
Vanger 0:b86d15c6ba29 9980 ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
Vanger 0:b86d15c6ba29 9981 DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 9982
Vanger 0:b86d15c6ba29 9983 if (ssl->buffers.serverDH_P.buffer)
Vanger 0:b86d15c6ba29 9984 ssl->buffers.serverDH_P.length = length;
Vanger 0:b86d15c6ba29 9985 else
Vanger 0:b86d15c6ba29 9986 return MEMORY_ERROR;
Vanger 0:b86d15c6ba29 9987
Vanger 0:b86d15c6ba29 9988 XMEMCPY(ssl->buffers.serverDH_P.buffer, input + *inOutIdx, length);
Vanger 0:b86d15c6ba29 9989 *inOutIdx += length;
Vanger 0:b86d15c6ba29 9990
Vanger 0:b86d15c6ba29 9991 /* g */
Vanger 0:b86d15c6ba29 9992 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 9993 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 9994
Vanger 0:b86d15c6ba29 9995 ato16(input + *inOutIdx, &length);
Vanger 0:b86d15c6ba29 9996 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 9997
Vanger 0:b86d15c6ba29 9998 if ((*inOutIdx - begin) + length > size)
Vanger 0:b86d15c6ba29 9999 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 10000
Vanger 0:b86d15c6ba29 10001 ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
Vanger 0:b86d15c6ba29 10002 DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 10003
Vanger 0:b86d15c6ba29 10004 if (ssl->buffers.serverDH_G.buffer)
Vanger 0:b86d15c6ba29 10005 ssl->buffers.serverDH_G.length = length;
Vanger 0:b86d15c6ba29 10006 else
Vanger 0:b86d15c6ba29 10007 return MEMORY_ERROR;
Vanger 0:b86d15c6ba29 10008
Vanger 0:b86d15c6ba29 10009 XMEMCPY(ssl->buffers.serverDH_G.buffer, input + *inOutIdx, length);
Vanger 0:b86d15c6ba29 10010 *inOutIdx += length;
Vanger 0:b86d15c6ba29 10011
Vanger 0:b86d15c6ba29 10012 /* pub */
Vanger 0:b86d15c6ba29 10013 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 10014 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 10015
Vanger 0:b86d15c6ba29 10016 ato16(input + *inOutIdx, &length);
Vanger 0:b86d15c6ba29 10017 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 10018
Vanger 0:b86d15c6ba29 10019 if ((*inOutIdx - begin) + length > size)
Vanger 0:b86d15c6ba29 10020 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 10021
Vanger 0:b86d15c6ba29 10022 ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap,
Vanger 0:b86d15c6ba29 10023 DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 10024
Vanger 0:b86d15c6ba29 10025 if (ssl->buffers.serverDH_Pub.buffer)
Vanger 0:b86d15c6ba29 10026 ssl->buffers.serverDH_Pub.length = length;
Vanger 0:b86d15c6ba29 10027 else
Vanger 0:b86d15c6ba29 10028 return MEMORY_ERROR;
Vanger 0:b86d15c6ba29 10029
Vanger 0:b86d15c6ba29 10030 XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + *inOutIdx, length);
Vanger 0:b86d15c6ba29 10031 *inOutIdx += length;
Vanger 0:b86d15c6ba29 10032 }
Vanger 0:b86d15c6ba29 10033 #endif /* !NO_DH || !NO_PSK */
Vanger 0:b86d15c6ba29 10034
Vanger 0:b86d15c6ba29 10035 #if !defined(NO_DH) || defined(HAVE_ECC)
Vanger 0:b86d15c6ba29 10036 if (!ssl->options.usingAnon_cipher &&
Vanger 0:b86d15c6ba29 10037 (ssl->specs.kea == ecc_diffie_hellman_kea ||
Vanger 0:b86d15c6ba29 10038 ssl->specs.kea == diffie_hellman_kea))
Vanger 0:b86d15c6ba29 10039 {
Vanger 0:b86d15c6ba29 10040 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 10041 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10042 Md5* md5 = NULL;
Vanger 0:b86d15c6ba29 10043 Sha* sha = NULL;
Vanger 0:b86d15c6ba29 10044 #else
Vanger 0:b86d15c6ba29 10045 Md5 md5[1];
Vanger 0:b86d15c6ba29 10046 Sha sha[1];
Vanger 0:b86d15c6ba29 10047 #endif
Vanger 0:b86d15c6ba29 10048 #endif
Vanger 0:b86d15c6ba29 10049 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 10050 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10051 Sha256* sha256 = NULL;
Vanger 0:b86d15c6ba29 10052 byte* hash256 = NULL;
Vanger 0:b86d15c6ba29 10053 #else
Vanger 0:b86d15c6ba29 10054 Sha256 sha256[1];
Vanger 0:b86d15c6ba29 10055 byte hash256[SHA256_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 10056 #endif
Vanger 0:b86d15c6ba29 10057 #endif
Vanger 0:b86d15c6ba29 10058 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 10059 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10060 Sha384* sha384 = NULL;
Vanger 0:b86d15c6ba29 10061 byte* hash384 = NULL;
Vanger 0:b86d15c6ba29 10062 #else
Vanger 0:b86d15c6ba29 10063 Sha384 sha384[1];
Vanger 0:b86d15c6ba29 10064 byte hash384[SHA384_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 10065 #endif
Vanger 0:b86d15c6ba29 10066 #endif
Vanger 0:b86d15c6ba29 10067 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10068 byte* hash = NULL;
Vanger 0:b86d15c6ba29 10069 byte* messageVerify = NULL;
Vanger 0:b86d15c6ba29 10070 #else
Vanger 0:b86d15c6ba29 10071 byte hash[FINISHED_SZ];
Vanger 0:b86d15c6ba29 10072 byte messageVerify[MAX_DH_SZ];
Vanger 0:b86d15c6ba29 10073 #endif
Vanger 0:b86d15c6ba29 10074 byte hashAlgo = sha_mac;
Vanger 0:b86d15c6ba29 10075 byte sigAlgo = ssl->specs.sig_algo;
Vanger 0:b86d15c6ba29 10076 word16 verifySz = (word16) (*inOutIdx - begin);
Vanger 0:b86d15c6ba29 10077
Vanger 0:b86d15c6ba29 10078 /* save message for hash verify */
Vanger 0:b86d15c6ba29 10079 if (verifySz > MAX_DH_SZ)
Vanger 0:b86d15c6ba29 10080 ERROR_OUT(BUFFER_ERROR, done);
Vanger 0:b86d15c6ba29 10081
Vanger 0:b86d15c6ba29 10082 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10083 messageVerify = (byte*)XMALLOC(MAX_DH_SZ, NULL,
Vanger 0:b86d15c6ba29 10084 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10085 if (messageVerify == NULL)
Vanger 0:b86d15c6ba29 10086 ERROR_OUT(MEMORY_E, done);
Vanger 0:b86d15c6ba29 10087 #endif
Vanger 0:b86d15c6ba29 10088
Vanger 0:b86d15c6ba29 10089 XMEMCPY(messageVerify, input + begin, verifySz);
Vanger 0:b86d15c6ba29 10090
Vanger 0:b86d15c6ba29 10091 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 10092 if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size)
Vanger 0:b86d15c6ba29 10093 ERROR_OUT(BUFFER_ERROR, done);
Vanger 0:b86d15c6ba29 10094
Vanger 0:b86d15c6ba29 10095 hashAlgo = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 10096 sigAlgo = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 10097 }
Vanger 0:b86d15c6ba29 10098
Vanger 0:b86d15c6ba29 10099 /* signature */
Vanger 0:b86d15c6ba29 10100 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 10101 ERROR_OUT(BUFFER_ERROR, done);
Vanger 0:b86d15c6ba29 10102
Vanger 0:b86d15c6ba29 10103 ato16(input + *inOutIdx, &length);
Vanger 0:b86d15c6ba29 10104 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 10105
Vanger 0:b86d15c6ba29 10106 if ((*inOutIdx - begin) + length > size)
Vanger 0:b86d15c6ba29 10107 ERROR_OUT(BUFFER_ERROR, done);
Vanger 0:b86d15c6ba29 10108
Vanger 0:b86d15c6ba29 10109 /* inOutIdx updated at the end of the function */
Vanger 0:b86d15c6ba29 10110
Vanger 0:b86d15c6ba29 10111 /* verify signature */
Vanger 0:b86d15c6ba29 10112 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10113 hash = (byte*)XMALLOC(FINISHED_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10114 if (hash == NULL)
Vanger 0:b86d15c6ba29 10115 ERROR_OUT(MEMORY_E, done);
Vanger 0:b86d15c6ba29 10116 #endif
Vanger 0:b86d15c6ba29 10117
Vanger 0:b86d15c6ba29 10118 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 10119 /* md5 */
Vanger 0:b86d15c6ba29 10120 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10121 md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10122 if (md5 == NULL)
Vanger 0:b86d15c6ba29 10123 ERROR_OUT(MEMORY_E, done);
Vanger 0:b86d15c6ba29 10124 #endif
Vanger 0:b86d15c6ba29 10125 InitMd5(md5);
Vanger 0:b86d15c6ba29 10126 Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN);
Vanger 0:b86d15c6ba29 10127 Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN);
Vanger 0:b86d15c6ba29 10128 Md5Update(md5, messageVerify, verifySz);
Vanger 0:b86d15c6ba29 10129 Md5Final(md5, hash);
Vanger 0:b86d15c6ba29 10130
Vanger 0:b86d15c6ba29 10131 /* sha */
Vanger 0:b86d15c6ba29 10132 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10133 sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10134 if (sha == NULL)
Vanger 0:b86d15c6ba29 10135 ERROR_OUT(MEMORY_E, done);
Vanger 0:b86d15c6ba29 10136 #endif
Vanger 0:b86d15c6ba29 10137 ret = InitSha(sha);
Vanger 0:b86d15c6ba29 10138 if (ret != 0)
Vanger 0:b86d15c6ba29 10139 goto done;
Vanger 0:b86d15c6ba29 10140 ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN);
Vanger 0:b86d15c6ba29 10141 ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN);
Vanger 0:b86d15c6ba29 10142 ShaUpdate(sha, messageVerify, verifySz);
Vanger 0:b86d15c6ba29 10143 ShaFinal(sha, hash + MD5_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 10144 #endif
Vanger 0:b86d15c6ba29 10145
Vanger 0:b86d15c6ba29 10146 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 10147 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10148 sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
Vanger 0:b86d15c6ba29 10149 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10150 hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL,
Vanger 0:b86d15c6ba29 10151 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10152 if (sha256 == NULL || hash256 == NULL)
Vanger 0:b86d15c6ba29 10153 ERROR_OUT(MEMORY_E, done);
Vanger 0:b86d15c6ba29 10154 #endif
Vanger 0:b86d15c6ba29 10155 if (!(ret = InitSha256(sha256))
Vanger 0:b86d15c6ba29 10156 && !(ret = Sha256Update(sha256, ssl->arrays->clientRandom, RAN_LEN))
Vanger 0:b86d15c6ba29 10157 && !(ret = Sha256Update(sha256, ssl->arrays->serverRandom, RAN_LEN))
Vanger 0:b86d15c6ba29 10158 && !(ret = Sha256Update(sha256, messageVerify, verifySz)))
Vanger 0:b86d15c6ba29 10159 ret = Sha256Final(sha256, hash256);
Vanger 0:b86d15c6ba29 10160 if (ret != 0)
Vanger 0:b86d15c6ba29 10161 goto done;
Vanger 0:b86d15c6ba29 10162 #endif
Vanger 0:b86d15c6ba29 10163
Vanger 0:b86d15c6ba29 10164 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 10165 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10166 sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,
Vanger 0:b86d15c6ba29 10167 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10168 hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL,
Vanger 0:b86d15c6ba29 10169 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10170 if (sha384 == NULL || hash384 == NULL)
Vanger 0:b86d15c6ba29 10171 ERROR_OUT(MEMORY_E, done);
Vanger 0:b86d15c6ba29 10172 #endif
Vanger 0:b86d15c6ba29 10173 if (!(ret = InitSha384(sha384))
Vanger 0:b86d15c6ba29 10174 && !(ret = Sha384Update(sha384, ssl->arrays->clientRandom, RAN_LEN))
Vanger 0:b86d15c6ba29 10175 && !(ret = Sha384Update(sha384, ssl->arrays->serverRandom, RAN_LEN))
Vanger 0:b86d15c6ba29 10176 && !(ret = Sha384Update(sha384, messageVerify, verifySz)))
Vanger 0:b86d15c6ba29 10177 ret = Sha384Final(sha384, hash384);
Vanger 0:b86d15c6ba29 10178 if (ret != 0)
Vanger 0:b86d15c6ba29 10179 goto done;
Vanger 0:b86d15c6ba29 10180 #endif
Vanger 0:b86d15c6ba29 10181
Vanger 0:b86d15c6ba29 10182 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 10183 /* rsa */
Vanger 0:b86d15c6ba29 10184 if (sigAlgo == rsa_sa_algo)
Vanger 0:b86d15c6ba29 10185 {
Vanger 0:b86d15c6ba29 10186 byte* out = NULL;
Vanger 0:b86d15c6ba29 10187 byte doUserRsa = 0;
Vanger 0:b86d15c6ba29 10188 word32 verifiedSz = 0;
Vanger 0:b86d15c6ba29 10189
Vanger 0:b86d15c6ba29 10190 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 10191 if (ssl->ctx->RsaVerifyCb)
Vanger 0:b86d15c6ba29 10192 doUserRsa = 1;
Vanger 0:b86d15c6ba29 10193 #endif /*HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 10194
Vanger 0:b86d15c6ba29 10195 if (!ssl->peerRsaKeyPresent)
Vanger 0:b86d15c6ba29 10196 ERROR_OUT(NO_PEER_KEY, done);
Vanger 0:b86d15c6ba29 10197
Vanger 0:b86d15c6ba29 10198 if (doUserRsa) {
Vanger 0:b86d15c6ba29 10199 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 10200 verifiedSz = ssl->ctx->RsaVerifyCb(ssl,
Vanger 0:b86d15c6ba29 10201 (byte *)input + *inOutIdx,
Vanger 0:b86d15c6ba29 10202 length, &out,
Vanger 0:b86d15c6ba29 10203 ssl->buffers.peerRsaKey.buffer,
Vanger 0:b86d15c6ba29 10204 ssl->buffers.peerRsaKey.length,
Vanger 0:b86d15c6ba29 10205 ssl->RsaVerifyCtx);
Vanger 0:b86d15c6ba29 10206 #endif /*HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 10207 }
Vanger 0:b86d15c6ba29 10208 else
Vanger 0:b86d15c6ba29 10209 verifiedSz = RsaSSL_VerifyInline((byte *)input + *inOutIdx,
Vanger 0:b86d15c6ba29 10210 length, &out, ssl->peerRsaKey);
Vanger 0:b86d15c6ba29 10211
Vanger 0:b86d15c6ba29 10212 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 10213 word32 encSigSz;
Vanger 0:b86d15c6ba29 10214 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 10215 byte* digest = &hash[MD5_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 10216 int typeH = SHAh;
Vanger 0:b86d15c6ba29 10217 int digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 10218 #else
Vanger 0:b86d15c6ba29 10219 byte* digest = hash256;
Vanger 0:b86d15c6ba29 10220 int typeH = SHA256h;
Vanger 0:b86d15c6ba29 10221 int digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 10222 #endif
Vanger 0:b86d15c6ba29 10223 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10224 byte* encodedSig = NULL;
Vanger 0:b86d15c6ba29 10225 #else
Vanger 0:b86d15c6ba29 10226 byte encodedSig[MAX_ENCODED_SIG_SZ];
Vanger 0:b86d15c6ba29 10227 #endif
Vanger 0:b86d15c6ba29 10228
Vanger 0:b86d15c6ba29 10229 if (hashAlgo == sha_mac) {
Vanger 0:b86d15c6ba29 10230 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 10231 digest = &hash[MD5_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 10232 typeH = SHAh;
Vanger 0:b86d15c6ba29 10233 digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 10234 #endif
Vanger 0:b86d15c6ba29 10235 }
Vanger 0:b86d15c6ba29 10236 else if (hashAlgo == sha256_mac) {
Vanger 0:b86d15c6ba29 10237 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 10238 digest = hash256;
Vanger 0:b86d15c6ba29 10239 typeH = SHA256h;
Vanger 0:b86d15c6ba29 10240 digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 10241 #endif
Vanger 0:b86d15c6ba29 10242 }
Vanger 0:b86d15c6ba29 10243 else if (hashAlgo == sha384_mac) {
Vanger 0:b86d15c6ba29 10244 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 10245 digest = hash384;
Vanger 0:b86d15c6ba29 10246 typeH = SHA384h;
Vanger 0:b86d15c6ba29 10247 digestSz = SHA384_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 10248 #endif
Vanger 0:b86d15c6ba29 10249 }
Vanger 0:b86d15c6ba29 10250
Vanger 0:b86d15c6ba29 10251 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10252 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
Vanger 0:b86d15c6ba29 10253 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10254 if (encodedSig == NULL)
Vanger 0:b86d15c6ba29 10255 ERROR_OUT(MEMORY_E, done);
Vanger 0:b86d15c6ba29 10256 #endif
Vanger 0:b86d15c6ba29 10257
Vanger 0:b86d15c6ba29 10258 encSigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
Vanger 0:b86d15c6ba29 10259
Vanger 0:b86d15c6ba29 10260 if (encSigSz != verifiedSz || !out || XMEMCMP(out, encodedSig,
Vanger 0:b86d15c6ba29 10261 min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0)
Vanger 0:b86d15c6ba29 10262 ret = VERIFY_SIGN_ERROR;
Vanger 0:b86d15c6ba29 10263
Vanger 0:b86d15c6ba29 10264 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10265 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10266 #endif
Vanger 0:b86d15c6ba29 10267 if (ret != 0)
Vanger 0:b86d15c6ba29 10268 goto done;
Vanger 0:b86d15c6ba29 10269 }
Vanger 0:b86d15c6ba29 10270 else if (verifiedSz != FINISHED_SZ || !out || XMEMCMP(out,
Vanger 0:b86d15c6ba29 10271 hash, FINISHED_SZ) != 0)
Vanger 0:b86d15c6ba29 10272 ERROR_OUT(VERIFY_SIGN_ERROR, done);
Vanger 0:b86d15c6ba29 10273 } else
Vanger 0:b86d15c6ba29 10274 #endif
Vanger 0:b86d15c6ba29 10275 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 10276 /* ecdsa */
Vanger 0:b86d15c6ba29 10277 if (sigAlgo == ecc_dsa_sa_algo) {
Vanger 0:b86d15c6ba29 10278 int verify = 0;
Vanger 0:b86d15c6ba29 10279 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 10280 byte* digest = &hash[MD5_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 10281 word32 digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 10282 #else
Vanger 0:b86d15c6ba29 10283 byte* digest = hash256;
Vanger 0:b86d15c6ba29 10284 word32 digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 10285 #endif
Vanger 0:b86d15c6ba29 10286 byte doUserEcc = 0;
Vanger 0:b86d15c6ba29 10287
Vanger 0:b86d15c6ba29 10288 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 10289 if (ssl->ctx->EccVerifyCb)
Vanger 0:b86d15c6ba29 10290 doUserEcc = 1;
Vanger 0:b86d15c6ba29 10291 #endif
Vanger 0:b86d15c6ba29 10292
Vanger 0:b86d15c6ba29 10293 if (!ssl->peerEccDsaKeyPresent)
Vanger 0:b86d15c6ba29 10294 ERROR_OUT(NO_PEER_KEY, done);
Vanger 0:b86d15c6ba29 10295
Vanger 0:b86d15c6ba29 10296 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 10297 if (hashAlgo == sha_mac) {
Vanger 0:b86d15c6ba29 10298 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 10299 digest = &hash[MD5_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 10300 digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 10301 #endif
Vanger 0:b86d15c6ba29 10302 }
Vanger 0:b86d15c6ba29 10303 else if (hashAlgo == sha256_mac) {
Vanger 0:b86d15c6ba29 10304 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 10305 digest = hash256;
Vanger 0:b86d15c6ba29 10306 digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 10307 #endif
Vanger 0:b86d15c6ba29 10308 }
Vanger 0:b86d15c6ba29 10309 else if (hashAlgo == sha384_mac) {
Vanger 0:b86d15c6ba29 10310 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 10311 digest = hash384;
Vanger 0:b86d15c6ba29 10312 digestSz = SHA384_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 10313 #endif
Vanger 0:b86d15c6ba29 10314 }
Vanger 0:b86d15c6ba29 10315 }
Vanger 0:b86d15c6ba29 10316 if (doUserEcc) {
Vanger 0:b86d15c6ba29 10317 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 10318 ret = ssl->ctx->EccVerifyCb(ssl, input + *inOutIdx, length,
Vanger 0:b86d15c6ba29 10319 digest, digestSz,
Vanger 0:b86d15c6ba29 10320 ssl->buffers.peerEccDsaKey.buffer,
Vanger 0:b86d15c6ba29 10321 ssl->buffers.peerEccDsaKey.length,
Vanger 0:b86d15c6ba29 10322 &verify, ssl->EccVerifyCtx);
Vanger 0:b86d15c6ba29 10323 #endif
Vanger 0:b86d15c6ba29 10324 }
Vanger 0:b86d15c6ba29 10325 else {
Vanger 0:b86d15c6ba29 10326 ret = ecc_verify_hash(input + *inOutIdx, length,
Vanger 0:b86d15c6ba29 10327 digest, digestSz, &verify, ssl->peerEccDsaKey);
Vanger 0:b86d15c6ba29 10328 }
Vanger 0:b86d15c6ba29 10329 if (ret != 0 || verify == 0)
Vanger 0:b86d15c6ba29 10330 ERROR_OUT(VERIFY_SIGN_ERROR, done);
Vanger 0:b86d15c6ba29 10331 }
Vanger 0:b86d15c6ba29 10332 else
Vanger 0:b86d15c6ba29 10333 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 10334 ERROR_OUT(ALGO_ID_E, done);
Vanger 0:b86d15c6ba29 10335
Vanger 0:b86d15c6ba29 10336 /* signature length */
Vanger 0:b86d15c6ba29 10337 *inOutIdx += length;
Vanger 0:b86d15c6ba29 10338
Vanger 0:b86d15c6ba29 10339 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
Vanger 0:b86d15c6ba29 10340
Vanger 0:b86d15c6ba29 10341 done:
Vanger 0:b86d15c6ba29 10342 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10343 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 10344 XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10345 XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10346 #endif
Vanger 0:b86d15c6ba29 10347 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 10348 XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10349 XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10350 #endif
Vanger 0:b86d15c6ba29 10351 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 10352 XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10353 XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10354 #endif
Vanger 0:b86d15c6ba29 10355 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10356 XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10357 #endif
Vanger 0:b86d15c6ba29 10358 if (ret != 0)
Vanger 0:b86d15c6ba29 10359 return ret;
Vanger 0:b86d15c6ba29 10360 }
Vanger 0:b86d15c6ba29 10361
Vanger 0:b86d15c6ba29 10362 if (ssl->keys.encryptionOn) {
Vanger 0:b86d15c6ba29 10363 *inOutIdx += ssl->keys.padSz;
Vanger 0:b86d15c6ba29 10364 }
Vanger 0:b86d15c6ba29 10365
Vanger 0:b86d15c6ba29 10366 return 0;
Vanger 0:b86d15c6ba29 10367 #else /* !NO_DH or HAVE_ECC */
Vanger 0:b86d15c6ba29 10368 return NOT_COMPILED_IN; /* not supported by build */
Vanger 0:b86d15c6ba29 10369 #endif /* !NO_DH or HAVE_ECC */
Vanger 0:b86d15c6ba29 10370
Vanger 0:b86d15c6ba29 10371 #undef ERROR_OUT
Vanger 0:b86d15c6ba29 10372 }
Vanger 0:b86d15c6ba29 10373
Vanger 0:b86d15c6ba29 10374
Vanger 0:b86d15c6ba29 10375 int SendClientKeyExchange(CYASSL* ssl)
Vanger 0:b86d15c6ba29 10376 {
Vanger 0:b86d15c6ba29 10377 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10378 byte* encSecret = NULL;
Vanger 0:b86d15c6ba29 10379 #else
Vanger 0:b86d15c6ba29 10380 byte encSecret[MAX_ENCRYPT_SZ];
Vanger 0:b86d15c6ba29 10381 #endif
Vanger 0:b86d15c6ba29 10382 word32 encSz = 0;
Vanger 0:b86d15c6ba29 10383 word32 idx = 0;
Vanger 0:b86d15c6ba29 10384 int ret = 0;
Vanger 0:b86d15c6ba29 10385 byte doUserRsa = 0;
Vanger 0:b86d15c6ba29 10386
Vanger 0:b86d15c6ba29 10387 (void)doUserRsa;
Vanger 0:b86d15c6ba29 10388
Vanger 0:b86d15c6ba29 10389 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 10390 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 10391 if (ssl->ctx->RsaEncCb)
Vanger 0:b86d15c6ba29 10392 doUserRsa = 1;
Vanger 0:b86d15c6ba29 10393 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 10394 #endif /*HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 10395
Vanger 0:b86d15c6ba29 10396 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10397 encSecret = (byte*)XMALLOC(MAX_ENCRYPT_SZ, NULL,
Vanger 0:b86d15c6ba29 10398 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10399 if (encSecret == NULL)
Vanger 0:b86d15c6ba29 10400 return MEMORY_E;
Vanger 0:b86d15c6ba29 10401 #endif
Vanger 0:b86d15c6ba29 10402
Vanger 0:b86d15c6ba29 10403 switch (ssl->specs.kea) {
Vanger 0:b86d15c6ba29 10404 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 10405 case rsa_kea:
Vanger 0:b86d15c6ba29 10406 ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret,
Vanger 0:b86d15c6ba29 10407 SECRET_LEN);
Vanger 0:b86d15c6ba29 10408 if (ret != 0) {
Vanger 0:b86d15c6ba29 10409 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10410 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10411 #endif
Vanger 0:b86d15c6ba29 10412 return ret;
Vanger 0:b86d15c6ba29 10413 }
Vanger 0:b86d15c6ba29 10414
Vanger 0:b86d15c6ba29 10415 ssl->arrays->preMasterSecret[0] = ssl->chVersion.major;
Vanger 0:b86d15c6ba29 10416 ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor;
Vanger 0:b86d15c6ba29 10417 ssl->arrays->preMasterSz = SECRET_LEN;
Vanger 0:b86d15c6ba29 10418
Vanger 0:b86d15c6ba29 10419 if (ssl->peerRsaKeyPresent == 0) {
Vanger 0:b86d15c6ba29 10420 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10421 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10422 #endif
Vanger 0:b86d15c6ba29 10423 return NO_PEER_KEY;
Vanger 0:b86d15c6ba29 10424 }
Vanger 0:b86d15c6ba29 10425
Vanger 0:b86d15c6ba29 10426 if (doUserRsa) {
Vanger 0:b86d15c6ba29 10427 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 10428 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 10429 encSz = MAX_ENCRYPT_SZ;
Vanger 0:b86d15c6ba29 10430 ret = ssl->ctx->RsaEncCb(ssl,
Vanger 0:b86d15c6ba29 10431 ssl->arrays->preMasterSecret,
Vanger 0:b86d15c6ba29 10432 SECRET_LEN,
Vanger 0:b86d15c6ba29 10433 encSecret, &encSz,
Vanger 0:b86d15c6ba29 10434 ssl->buffers.peerRsaKey.buffer,
Vanger 0:b86d15c6ba29 10435 ssl->buffers.peerRsaKey.length,
Vanger 0:b86d15c6ba29 10436 ssl->RsaEncCtx);
Vanger 0:b86d15c6ba29 10437 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 10438 #endif /*HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 10439 }
Vanger 0:b86d15c6ba29 10440 else {
Vanger 0:b86d15c6ba29 10441 ret = RsaPublicEncrypt(ssl->arrays->preMasterSecret,
Vanger 0:b86d15c6ba29 10442 SECRET_LEN, encSecret, MAX_ENCRYPT_SZ,
Vanger 0:b86d15c6ba29 10443 ssl->peerRsaKey, ssl->rng);
Vanger 0:b86d15c6ba29 10444 if (ret > 0) {
Vanger 0:b86d15c6ba29 10445 encSz = ret;
Vanger 0:b86d15c6ba29 10446 ret = 0; /* set success to 0 */
Vanger 0:b86d15c6ba29 10447 }
Vanger 0:b86d15c6ba29 10448 }
Vanger 0:b86d15c6ba29 10449 break;
Vanger 0:b86d15c6ba29 10450 #endif
Vanger 0:b86d15c6ba29 10451 #ifndef NO_DH
Vanger 0:b86d15c6ba29 10452 case diffie_hellman_kea:
Vanger 0:b86d15c6ba29 10453 {
Vanger 0:b86d15c6ba29 10454 buffer serverP = ssl->buffers.serverDH_P;
Vanger 0:b86d15c6ba29 10455 buffer serverG = ssl->buffers.serverDH_G;
Vanger 0:b86d15c6ba29 10456 buffer serverPub = ssl->buffers.serverDH_Pub;
Vanger 0:b86d15c6ba29 10457 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10458 byte* priv = NULL;
Vanger 0:b86d15c6ba29 10459 #else
Vanger 0:b86d15c6ba29 10460 byte priv[ENCRYPT_LEN];
Vanger 0:b86d15c6ba29 10461 #endif
Vanger 0:b86d15c6ba29 10462 word32 privSz = 0;
Vanger 0:b86d15c6ba29 10463 DhKey key;
Vanger 0:b86d15c6ba29 10464
Vanger 0:b86d15c6ba29 10465 if (serverP.buffer == 0 || serverG.buffer == 0 ||
Vanger 0:b86d15c6ba29 10466 serverPub.buffer == 0) {
Vanger 0:b86d15c6ba29 10467 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10468 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10469 #endif
Vanger 0:b86d15c6ba29 10470 return NO_PEER_KEY;
Vanger 0:b86d15c6ba29 10471 }
Vanger 0:b86d15c6ba29 10472
Vanger 0:b86d15c6ba29 10473 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10474 priv = (byte*)XMALLOC(ENCRYPT_LEN, NULL,
Vanger 0:b86d15c6ba29 10475 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10476 if (priv == NULL) {
Vanger 0:b86d15c6ba29 10477 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10478 return MEMORY_E;
Vanger 0:b86d15c6ba29 10479 }
Vanger 0:b86d15c6ba29 10480 #endif
Vanger 0:b86d15c6ba29 10481
Vanger 0:b86d15c6ba29 10482 InitDhKey(&key);
Vanger 0:b86d15c6ba29 10483 ret = DhSetKey(&key, serverP.buffer, serverP.length,
Vanger 0:b86d15c6ba29 10484 serverG.buffer, serverG.length);
Vanger 0:b86d15c6ba29 10485 if (ret == 0)
Vanger 0:b86d15c6ba29 10486 /* for DH, encSecret is Yc, agree is pre-master */
Vanger 0:b86d15c6ba29 10487 ret = DhGenerateKeyPair(&key, ssl->rng, priv, &privSz,
Vanger 0:b86d15c6ba29 10488 encSecret, &encSz);
Vanger 0:b86d15c6ba29 10489 if (ret == 0)
Vanger 0:b86d15c6ba29 10490 ret = DhAgree(&key, ssl->arrays->preMasterSecret,
Vanger 0:b86d15c6ba29 10491 &ssl->arrays->preMasterSz, priv, privSz,
Vanger 0:b86d15c6ba29 10492 serverPub.buffer, serverPub.length);
Vanger 0:b86d15c6ba29 10493 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10494 XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10495 #endif
Vanger 0:b86d15c6ba29 10496 FreeDhKey(&key);
Vanger 0:b86d15c6ba29 10497 }
Vanger 0:b86d15c6ba29 10498 break;
Vanger 0:b86d15c6ba29 10499 #endif /* NO_DH */
Vanger 0:b86d15c6ba29 10500 #ifndef NO_PSK
Vanger 0:b86d15c6ba29 10501 case psk_kea:
Vanger 0:b86d15c6ba29 10502 {
Vanger 0:b86d15c6ba29 10503 byte* pms = ssl->arrays->preMasterSecret;
Vanger 0:b86d15c6ba29 10504
Vanger 0:b86d15c6ba29 10505 ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
Vanger 0:b86d15c6ba29 10506 ssl->arrays->server_hint, ssl->arrays->client_identity,
Vanger 0:b86d15c6ba29 10507 MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
Vanger 0:b86d15c6ba29 10508 if (ssl->arrays->psk_keySz == 0 ||
Vanger 0:b86d15c6ba29 10509 ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
Vanger 0:b86d15c6ba29 10510 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10511 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10512 #endif
Vanger 0:b86d15c6ba29 10513 return PSK_KEY_ERROR;
Vanger 0:b86d15c6ba29 10514 }
Vanger 0:b86d15c6ba29 10515 encSz = (word32)XSTRLEN(ssl->arrays->client_identity);
Vanger 0:b86d15c6ba29 10516 if (encSz > MAX_PSK_ID_LEN) {
Vanger 0:b86d15c6ba29 10517 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10518 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10519 #endif
Vanger 0:b86d15c6ba29 10520 return CLIENT_ID_ERROR;
Vanger 0:b86d15c6ba29 10521 }
Vanger 0:b86d15c6ba29 10522 XMEMCPY(encSecret, ssl->arrays->client_identity, encSz);
Vanger 0:b86d15c6ba29 10523
Vanger 0:b86d15c6ba29 10524 /* make psk pre master secret */
Vanger 0:b86d15c6ba29 10525 /* length of key + length 0s + length of key + key */
Vanger 0:b86d15c6ba29 10526 c16toa((word16)ssl->arrays->psk_keySz, pms);
Vanger 0:b86d15c6ba29 10527 pms += 2;
Vanger 0:b86d15c6ba29 10528 XMEMSET(pms, 0, ssl->arrays->psk_keySz);
Vanger 0:b86d15c6ba29 10529 pms += ssl->arrays->psk_keySz;
Vanger 0:b86d15c6ba29 10530 c16toa((word16)ssl->arrays->psk_keySz, pms);
Vanger 0:b86d15c6ba29 10531 pms += 2;
Vanger 0:b86d15c6ba29 10532 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
Vanger 0:b86d15c6ba29 10533 ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
Vanger 0:b86d15c6ba29 10534 XMEMSET(ssl->arrays->psk_key, 0, ssl->arrays->psk_keySz);
Vanger 0:b86d15c6ba29 10535 ssl->arrays->psk_keySz = 0; /* No further need */
Vanger 0:b86d15c6ba29 10536 }
Vanger 0:b86d15c6ba29 10537 break;
Vanger 0:b86d15c6ba29 10538 #endif /* NO_PSK */
Vanger 0:b86d15c6ba29 10539 #if !defined(NO_DH) && !defined(NO_PSK)
Vanger 0:b86d15c6ba29 10540 case dhe_psk_kea:
Vanger 0:b86d15c6ba29 10541 {
Vanger 0:b86d15c6ba29 10542 byte* pms = ssl->arrays->preMasterSecret;
Vanger 0:b86d15c6ba29 10543 byte* es = encSecret;
Vanger 0:b86d15c6ba29 10544 buffer serverP = ssl->buffers.serverDH_P;
Vanger 0:b86d15c6ba29 10545 buffer serverG = ssl->buffers.serverDH_G;
Vanger 0:b86d15c6ba29 10546 buffer serverPub = ssl->buffers.serverDH_Pub;
Vanger 0:b86d15c6ba29 10547 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10548 byte* priv = NULL;
Vanger 0:b86d15c6ba29 10549 #else
Vanger 0:b86d15c6ba29 10550 byte priv[ENCRYPT_LEN];
Vanger 0:b86d15c6ba29 10551 #endif
Vanger 0:b86d15c6ba29 10552 word32 privSz = 0;
Vanger 0:b86d15c6ba29 10553 word32 pubSz = 0;
Vanger 0:b86d15c6ba29 10554 word32 esSz = 0;
Vanger 0:b86d15c6ba29 10555 DhKey key;
Vanger 0:b86d15c6ba29 10556
Vanger 0:b86d15c6ba29 10557 if (serverP.buffer == 0 || serverG.buffer == 0 ||
Vanger 0:b86d15c6ba29 10558 serverPub.buffer == 0) {
Vanger 0:b86d15c6ba29 10559 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10560 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10561 #endif
Vanger 0:b86d15c6ba29 10562 return NO_PEER_KEY;
Vanger 0:b86d15c6ba29 10563 }
Vanger 0:b86d15c6ba29 10564
Vanger 0:b86d15c6ba29 10565 ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
Vanger 0:b86d15c6ba29 10566 ssl->arrays->server_hint, ssl->arrays->client_identity,
Vanger 0:b86d15c6ba29 10567 MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
Vanger 0:b86d15c6ba29 10568 if (ssl->arrays->psk_keySz == 0 ||
Vanger 0:b86d15c6ba29 10569 ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
Vanger 0:b86d15c6ba29 10570 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10571 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10572 #endif
Vanger 0:b86d15c6ba29 10573 return PSK_KEY_ERROR;
Vanger 0:b86d15c6ba29 10574 }
Vanger 0:b86d15c6ba29 10575 esSz = (word32)XSTRLEN(ssl->arrays->client_identity);
Vanger 0:b86d15c6ba29 10576
Vanger 0:b86d15c6ba29 10577 if (esSz > MAX_PSK_ID_LEN) {
Vanger 0:b86d15c6ba29 10578 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10579 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10580 #endif
Vanger 0:b86d15c6ba29 10581 return CLIENT_ID_ERROR;
Vanger 0:b86d15c6ba29 10582 }
Vanger 0:b86d15c6ba29 10583
Vanger 0:b86d15c6ba29 10584 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10585 priv = (byte*)XMALLOC(ENCRYPT_LEN, NULL,
Vanger 0:b86d15c6ba29 10586 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10587 if (priv == NULL) {
Vanger 0:b86d15c6ba29 10588 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10589 return MEMORY_E;
Vanger 0:b86d15c6ba29 10590 }
Vanger 0:b86d15c6ba29 10591 #endif
Vanger 0:b86d15c6ba29 10592 c16toa((word16)esSz, es);
Vanger 0:b86d15c6ba29 10593 es += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 10594 XMEMCPY(es, ssl->arrays->client_identity, esSz);
Vanger 0:b86d15c6ba29 10595 es += esSz;
Vanger 0:b86d15c6ba29 10596 encSz = esSz + OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 10597
Vanger 0:b86d15c6ba29 10598 InitDhKey(&key);
Vanger 0:b86d15c6ba29 10599 ret = DhSetKey(&key, serverP.buffer, serverP.length,
Vanger 0:b86d15c6ba29 10600 serverG.buffer, serverG.length);
Vanger 0:b86d15c6ba29 10601 if (ret == 0)
Vanger 0:b86d15c6ba29 10602 /* for DH, encSecret is Yc, agree is pre-master */
Vanger 0:b86d15c6ba29 10603 ret = DhGenerateKeyPair(&key, ssl->rng, priv, &privSz,
Vanger 0:b86d15c6ba29 10604 es + OPAQUE16_LEN, &pubSz);
Vanger 0:b86d15c6ba29 10605 if (ret == 0)
Vanger 0:b86d15c6ba29 10606 ret = DhAgree(&key, pms + OPAQUE16_LEN,
Vanger 0:b86d15c6ba29 10607 &ssl->arrays->preMasterSz, priv, privSz,
Vanger 0:b86d15c6ba29 10608 serverPub.buffer, serverPub.length);
Vanger 0:b86d15c6ba29 10609 FreeDhKey(&key);
Vanger 0:b86d15c6ba29 10610 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10611 XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10612 #endif
Vanger 0:b86d15c6ba29 10613 if (ret != 0) {
Vanger 0:b86d15c6ba29 10614 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10615 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10616 #endif
Vanger 0:b86d15c6ba29 10617 return ret;
Vanger 0:b86d15c6ba29 10618 }
Vanger 0:b86d15c6ba29 10619
Vanger 0:b86d15c6ba29 10620 c16toa((word16)pubSz, es);
Vanger 0:b86d15c6ba29 10621 encSz += pubSz + OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 10622 c16toa((word16)ssl->arrays->preMasterSz, pms);
Vanger 0:b86d15c6ba29 10623 ssl->arrays->preMasterSz += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 10624 pms += ssl->arrays->preMasterSz;
Vanger 0:b86d15c6ba29 10625
Vanger 0:b86d15c6ba29 10626 /* make psk pre master secret */
Vanger 0:b86d15c6ba29 10627 /* length of key + length 0s + length of key + key */
Vanger 0:b86d15c6ba29 10628 c16toa((word16)ssl->arrays->psk_keySz, pms);
Vanger 0:b86d15c6ba29 10629 pms += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 10630 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
Vanger 0:b86d15c6ba29 10631 ssl->arrays->preMasterSz +=
Vanger 0:b86d15c6ba29 10632 ssl->arrays->psk_keySz + OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 10633 XMEMSET(ssl->arrays->psk_key, 0, ssl->arrays->psk_keySz);
Vanger 0:b86d15c6ba29 10634 ssl->arrays->psk_keySz = 0; /* No further need */
Vanger 0:b86d15c6ba29 10635 }
Vanger 0:b86d15c6ba29 10636 break;
Vanger 0:b86d15c6ba29 10637 #endif /* !NO_DH && !NO_PSK */
Vanger 0:b86d15c6ba29 10638 #ifdef HAVE_NTRU
Vanger 0:b86d15c6ba29 10639 case ntru_kea:
Vanger 0:b86d15c6ba29 10640 {
Vanger 0:b86d15c6ba29 10641 word32 rc;
Vanger 0:b86d15c6ba29 10642 word16 cipherLen = MAX_ENCRYPT_SZ;
Vanger 0:b86d15c6ba29 10643 DRBG_HANDLE drbg;
Vanger 0:b86d15c6ba29 10644 static uint8_t const cyasslStr[] = {
Vanger 0:b86d15c6ba29 10645 'C', 'y', 'a', 'S', 'S', 'L', ' ', 'N', 'T', 'R', 'U'
Vanger 0:b86d15c6ba29 10646 };
Vanger 0:b86d15c6ba29 10647
Vanger 0:b86d15c6ba29 10648 ret = RNG_GenerateBlock(ssl->rng,
Vanger 0:b86d15c6ba29 10649 ssl->arrays->preMasterSecret, SECRET_LEN);
Vanger 0:b86d15c6ba29 10650 if (ret != 0) {
Vanger 0:b86d15c6ba29 10651 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10652 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10653 #endif
Vanger 0:b86d15c6ba29 10654 return ret;
Vanger 0:b86d15c6ba29 10655 }
Vanger 0:b86d15c6ba29 10656
Vanger 0:b86d15c6ba29 10657 ssl->arrays->preMasterSz = SECRET_LEN;
Vanger 0:b86d15c6ba29 10658
Vanger 0:b86d15c6ba29 10659 if (ssl->peerNtruKeyPresent == 0) {
Vanger 0:b86d15c6ba29 10660 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10661 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10662 #endif
Vanger 0:b86d15c6ba29 10663 return NO_PEER_KEY;
Vanger 0:b86d15c6ba29 10664 }
Vanger 0:b86d15c6ba29 10665
Vanger 0:b86d15c6ba29 10666 rc = ntru_crypto_drbg_instantiate(MAX_NTRU_BITS, cyasslStr,
Vanger 0:b86d15c6ba29 10667 sizeof(cyasslStr), GetEntropy,
Vanger 0:b86d15c6ba29 10668 &drbg);
Vanger 0:b86d15c6ba29 10669 if (rc != DRBG_OK) {
Vanger 0:b86d15c6ba29 10670 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10671 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10672 #endif
Vanger 0:b86d15c6ba29 10673 return NTRU_DRBG_ERROR;
Vanger 0:b86d15c6ba29 10674 }
Vanger 0:b86d15c6ba29 10675
Vanger 0:b86d15c6ba29 10676 rc = ntru_crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen,
Vanger 0:b86d15c6ba29 10677 ssl->peerNtruKey,
Vanger 0:b86d15c6ba29 10678 ssl->arrays->preMasterSz,
Vanger 0:b86d15c6ba29 10679 ssl->arrays->preMasterSecret,
Vanger 0:b86d15c6ba29 10680 &cipherLen, encSecret);
Vanger 0:b86d15c6ba29 10681 ntru_crypto_drbg_uninstantiate(drbg);
Vanger 0:b86d15c6ba29 10682 if (rc != NTRU_OK) {
Vanger 0:b86d15c6ba29 10683 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10684 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10685 #endif
Vanger 0:b86d15c6ba29 10686 return NTRU_ENCRYPT_ERROR;
Vanger 0:b86d15c6ba29 10687 }
Vanger 0:b86d15c6ba29 10688
Vanger 0:b86d15c6ba29 10689 encSz = cipherLen;
Vanger 0:b86d15c6ba29 10690 ret = 0;
Vanger 0:b86d15c6ba29 10691 }
Vanger 0:b86d15c6ba29 10692 break;
Vanger 0:b86d15c6ba29 10693 #endif /* HAVE_NTRU */
Vanger 0:b86d15c6ba29 10694 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 10695 case ecc_diffie_hellman_kea:
Vanger 0:b86d15c6ba29 10696 {
Vanger 0:b86d15c6ba29 10697 ecc_key myKey;
Vanger 0:b86d15c6ba29 10698 ecc_key* peerKey = NULL;
Vanger 0:b86d15c6ba29 10699 word32 size = MAX_ENCRYPT_SZ;
Vanger 0:b86d15c6ba29 10700
Vanger 0:b86d15c6ba29 10701 if (ssl->specs.static_ecdh) {
Vanger 0:b86d15c6ba29 10702 /* TODO: EccDsa is really fixed Ecc change naming */
Vanger 0:b86d15c6ba29 10703 if (!ssl->peerEccDsaKeyPresent ||
Vanger 0:b86d15c6ba29 10704 !ssl->peerEccDsaKey->dp) {
Vanger 0:b86d15c6ba29 10705 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10706 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10707 #endif
Vanger 0:b86d15c6ba29 10708 return NO_PEER_KEY;
Vanger 0:b86d15c6ba29 10709 }
Vanger 0:b86d15c6ba29 10710 peerKey = ssl->peerEccDsaKey;
Vanger 0:b86d15c6ba29 10711 }
Vanger 0:b86d15c6ba29 10712 else {
Vanger 0:b86d15c6ba29 10713 if (!ssl->peerEccKeyPresent || !ssl->peerEccKey->dp) {
Vanger 0:b86d15c6ba29 10714 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10715 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10716 #endif
Vanger 0:b86d15c6ba29 10717 return NO_PEER_KEY;
Vanger 0:b86d15c6ba29 10718 }
Vanger 0:b86d15c6ba29 10719 peerKey = ssl->peerEccKey;
Vanger 0:b86d15c6ba29 10720 }
Vanger 0:b86d15c6ba29 10721
Vanger 0:b86d15c6ba29 10722 if (peerKey == NULL) {
Vanger 0:b86d15c6ba29 10723 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10724 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10725 #endif
Vanger 0:b86d15c6ba29 10726 return NO_PEER_KEY;
Vanger 0:b86d15c6ba29 10727 }
Vanger 0:b86d15c6ba29 10728
Vanger 0:b86d15c6ba29 10729 ecc_init(&myKey);
Vanger 0:b86d15c6ba29 10730 ret = ecc_make_key(ssl->rng, peerKey->dp->size, &myKey);
Vanger 0:b86d15c6ba29 10731 if (ret != 0) {
Vanger 0:b86d15c6ba29 10732 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10733 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10734 #endif
Vanger 0:b86d15c6ba29 10735 return ECC_MAKEKEY_ERROR;
Vanger 0:b86d15c6ba29 10736 }
Vanger 0:b86d15c6ba29 10737
Vanger 0:b86d15c6ba29 10738 /* precede export with 1 byte length */
Vanger 0:b86d15c6ba29 10739 ret = ecc_export_x963(&myKey, encSecret + 1, &size);
Vanger 0:b86d15c6ba29 10740 encSecret[0] = (byte)size;
Vanger 0:b86d15c6ba29 10741 encSz = size + 1;
Vanger 0:b86d15c6ba29 10742
Vanger 0:b86d15c6ba29 10743 if (ret != 0)
Vanger 0:b86d15c6ba29 10744 ret = ECC_EXPORT_ERROR;
Vanger 0:b86d15c6ba29 10745 else {
Vanger 0:b86d15c6ba29 10746 size = sizeof(ssl->arrays->preMasterSecret);
Vanger 0:b86d15c6ba29 10747 ret = ecc_shared_secret(&myKey, peerKey,
Vanger 0:b86d15c6ba29 10748 ssl->arrays->preMasterSecret, &size);
Vanger 0:b86d15c6ba29 10749 if (ret != 0)
Vanger 0:b86d15c6ba29 10750 ret = ECC_SHARED_ERROR;
Vanger 0:b86d15c6ba29 10751 }
Vanger 0:b86d15c6ba29 10752
Vanger 0:b86d15c6ba29 10753 ssl->arrays->preMasterSz = size;
Vanger 0:b86d15c6ba29 10754 ecc_free(&myKey);
Vanger 0:b86d15c6ba29 10755 }
Vanger 0:b86d15c6ba29 10756 break;
Vanger 0:b86d15c6ba29 10757 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 10758 default:
Vanger 0:b86d15c6ba29 10759 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10760 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10761 #endif
Vanger 0:b86d15c6ba29 10762 return ALGO_ID_E; /* unsupported kea */
Vanger 0:b86d15c6ba29 10763 }
Vanger 0:b86d15c6ba29 10764
Vanger 0:b86d15c6ba29 10765 if (ret == 0) {
Vanger 0:b86d15c6ba29 10766 byte *output;
Vanger 0:b86d15c6ba29 10767 int sendSz;
Vanger 0:b86d15c6ba29 10768 word32 tlsSz = 0;
Vanger 0:b86d15c6ba29 10769
Vanger 0:b86d15c6ba29 10770 if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea)
Vanger 0:b86d15c6ba29 10771 tlsSz = 2;
Vanger 0:b86d15c6ba29 10772
Vanger 0:b86d15c6ba29 10773 if (ssl->specs.kea == ecc_diffie_hellman_kea ||
Vanger 0:b86d15c6ba29 10774 ssl->specs.kea == dhe_psk_kea) /* always off */
Vanger 0:b86d15c6ba29 10775 tlsSz = 0;
Vanger 0:b86d15c6ba29 10776
Vanger 0:b86d15c6ba29 10777 sendSz = encSz + tlsSz + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 10778 idx = HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 10779
Vanger 0:b86d15c6ba29 10780 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 10781 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 10782 sendSz += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
Vanger 0:b86d15c6ba29 10783 idx += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
Vanger 0:b86d15c6ba29 10784 }
Vanger 0:b86d15c6ba29 10785 #endif
Vanger 0:b86d15c6ba29 10786
Vanger 0:b86d15c6ba29 10787 if (ssl->keys.encryptionOn)
Vanger 0:b86d15c6ba29 10788 sendSz += MAX_MSG_EXTRA;
Vanger 0:b86d15c6ba29 10789
Vanger 0:b86d15c6ba29 10790 /* check for available size */
Vanger 0:b86d15c6ba29 10791 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
Vanger 0:b86d15c6ba29 10792 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10793 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10794 #endif
Vanger 0:b86d15c6ba29 10795 return ret;
Vanger 0:b86d15c6ba29 10796 }
Vanger 0:b86d15c6ba29 10797
Vanger 0:b86d15c6ba29 10798 /* get ouput buffer */
Vanger 0:b86d15c6ba29 10799 output = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 10800 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 10801
Vanger 0:b86d15c6ba29 10802 AddHeaders(output, encSz + tlsSz, client_key_exchange, ssl);
Vanger 0:b86d15c6ba29 10803
Vanger 0:b86d15c6ba29 10804 if (tlsSz) {
Vanger 0:b86d15c6ba29 10805 c16toa((word16)encSz, &output[idx]);
Vanger 0:b86d15c6ba29 10806 idx += 2;
Vanger 0:b86d15c6ba29 10807 }
Vanger 0:b86d15c6ba29 10808 XMEMCPY(output + idx, encSecret, encSz);
Vanger 0:b86d15c6ba29 10809 idx += encSz;
Vanger 0:b86d15c6ba29 10810
Vanger 0:b86d15c6ba29 10811 if (ssl->keys.encryptionOn) {
Vanger 0:b86d15c6ba29 10812 byte* input;
Vanger 0:b86d15c6ba29 10813 int inputSz = idx-RECORD_HEADER_SZ; /* buildmsg adds rechdr */
Vanger 0:b86d15c6ba29 10814
Vanger 0:b86d15c6ba29 10815 input = (byte*)XMALLOC(inputSz, ssl->heap,
Vanger 0:b86d15c6ba29 10816 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10817 if (input == NULL) {
Vanger 0:b86d15c6ba29 10818 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10819 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10820 #endif
Vanger 0:b86d15c6ba29 10821 return MEMORY_E;
Vanger 0:b86d15c6ba29 10822 }
Vanger 0:b86d15c6ba29 10823
Vanger 0:b86d15c6ba29 10824 XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
Vanger 0:b86d15c6ba29 10825 sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
Vanger 0:b86d15c6ba29 10826 handshake);
Vanger 0:b86d15c6ba29 10827 XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10828 if (sendSz < 0) {
Vanger 0:b86d15c6ba29 10829 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10830 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10831 #endif
Vanger 0:b86d15c6ba29 10832 return sendSz;
Vanger 0:b86d15c6ba29 10833 }
Vanger 0:b86d15c6ba29 10834 } else {
Vanger 0:b86d15c6ba29 10835 ret = HashOutput(ssl, output, sendSz, 0);
Vanger 0:b86d15c6ba29 10836 if (ret != 0) {
Vanger 0:b86d15c6ba29 10837 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10838 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10839 #endif
Vanger 0:b86d15c6ba29 10840 return ret;
Vanger 0:b86d15c6ba29 10841 }
Vanger 0:b86d15c6ba29 10842 }
Vanger 0:b86d15c6ba29 10843
Vanger 0:b86d15c6ba29 10844 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 10845 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 10846 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) {
Vanger 0:b86d15c6ba29 10847 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10848 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10849 #endif
Vanger 0:b86d15c6ba29 10850 return ret;
Vanger 0:b86d15c6ba29 10851 }
Vanger 0:b86d15c6ba29 10852 }
Vanger 0:b86d15c6ba29 10853 #endif
Vanger 0:b86d15c6ba29 10854
Vanger 0:b86d15c6ba29 10855 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 10856 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 10857 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 10858 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 10859 AddPacketInfo("ClientKeyExchange", &ssl->timeoutInfo,
Vanger 0:b86d15c6ba29 10860 output, sendSz, ssl->heap);
Vanger 0:b86d15c6ba29 10861 #endif
Vanger 0:b86d15c6ba29 10862
Vanger 0:b86d15c6ba29 10863 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 10864
Vanger 0:b86d15c6ba29 10865 if (ssl->options.groupMessages)
Vanger 0:b86d15c6ba29 10866 ret = 0;
Vanger 0:b86d15c6ba29 10867 else
Vanger 0:b86d15c6ba29 10868 ret = SendBuffered(ssl);
Vanger 0:b86d15c6ba29 10869 }
Vanger 0:b86d15c6ba29 10870
Vanger 0:b86d15c6ba29 10871 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10872 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10873 #endif
Vanger 0:b86d15c6ba29 10874
Vanger 0:b86d15c6ba29 10875 if (ret == 0 || ret == WANT_WRITE) {
Vanger 0:b86d15c6ba29 10876 int tmpRet = MakeMasterSecret(ssl);
Vanger 0:b86d15c6ba29 10877 if (tmpRet != 0)
Vanger 0:b86d15c6ba29 10878 ret = tmpRet; /* save WANT_WRITE unless more serious */
Vanger 0:b86d15c6ba29 10879 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
Vanger 0:b86d15c6ba29 10880 }
Vanger 0:b86d15c6ba29 10881 /* No further need for PMS */
Vanger 0:b86d15c6ba29 10882 XMEMSET(ssl->arrays->preMasterSecret, 0, ssl->arrays->preMasterSz);
Vanger 0:b86d15c6ba29 10883 ssl->arrays->preMasterSz = 0;
Vanger 0:b86d15c6ba29 10884
Vanger 0:b86d15c6ba29 10885 return ret;
Vanger 0:b86d15c6ba29 10886 }
Vanger 0:b86d15c6ba29 10887
Vanger 0:b86d15c6ba29 10888 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 10889 int SendCertificateVerify(CYASSL* ssl)
Vanger 0:b86d15c6ba29 10890 {
Vanger 0:b86d15c6ba29 10891 byte *output;
Vanger 0:b86d15c6ba29 10892 int sendSz = MAX_CERT_VERIFY_SZ, length, ret;
Vanger 0:b86d15c6ba29 10893 word32 idx = 0;
Vanger 0:b86d15c6ba29 10894 word32 sigOutSz = 0;
Vanger 0:b86d15c6ba29 10895 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 10896 RsaKey key;
Vanger 0:b86d15c6ba29 10897 int initRsaKey = 0;
Vanger 0:b86d15c6ba29 10898 #endif
Vanger 0:b86d15c6ba29 10899 int usingEcc = 0;
Vanger 0:b86d15c6ba29 10900 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 10901 ecc_key eccKey;
Vanger 0:b86d15c6ba29 10902 #endif
Vanger 0:b86d15c6ba29 10903
Vanger 0:b86d15c6ba29 10904 (void)idx;
Vanger 0:b86d15c6ba29 10905
Vanger 0:b86d15c6ba29 10906 if (ssl->options.sendVerify == SEND_BLANK_CERT)
Vanger 0:b86d15c6ba29 10907 return 0; /* sent blank cert, can't verify */
Vanger 0:b86d15c6ba29 10908
Vanger 0:b86d15c6ba29 10909 if (ssl->keys.encryptionOn)
Vanger 0:b86d15c6ba29 10910 sendSz += MAX_MSG_EXTRA;
Vanger 0:b86d15c6ba29 10911
Vanger 0:b86d15c6ba29 10912 /* check for available size */
Vanger 0:b86d15c6ba29 10913 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
Vanger 0:b86d15c6ba29 10914 return ret;
Vanger 0:b86d15c6ba29 10915
Vanger 0:b86d15c6ba29 10916 /* get ouput buffer */
Vanger 0:b86d15c6ba29 10917 output = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 10918 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 10919
Vanger 0:b86d15c6ba29 10920 ret = BuildCertHashes(ssl, &ssl->certHashes);
Vanger 0:b86d15c6ba29 10921 if (ret != 0)
Vanger 0:b86d15c6ba29 10922 return ret;
Vanger 0:b86d15c6ba29 10923
Vanger 0:b86d15c6ba29 10924 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 10925 ecc_init(&eccKey);
Vanger 0:b86d15c6ba29 10926 #endif
Vanger 0:b86d15c6ba29 10927 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 10928 ret = InitRsaKey(&key, ssl->heap);
Vanger 0:b86d15c6ba29 10929 if (ret == 0) initRsaKey = 1;
Vanger 0:b86d15c6ba29 10930 if (ret == 0)
Vanger 0:b86d15c6ba29 10931 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
Vanger 0:b86d15c6ba29 10932 ssl->buffers.key.length);
Vanger 0:b86d15c6ba29 10933 if (ret == 0)
Vanger 0:b86d15c6ba29 10934 sigOutSz = RsaEncryptSize(&key);
Vanger 0:b86d15c6ba29 10935 else
Vanger 0:b86d15c6ba29 10936 #endif
Vanger 0:b86d15c6ba29 10937 {
Vanger 0:b86d15c6ba29 10938 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 10939 CYASSL_MSG("Trying ECC client cert, RSA didn't work");
Vanger 0:b86d15c6ba29 10940
Vanger 0:b86d15c6ba29 10941 idx = 0;
Vanger 0:b86d15c6ba29 10942 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &eccKey,
Vanger 0:b86d15c6ba29 10943 ssl->buffers.key.length);
Vanger 0:b86d15c6ba29 10944 if (ret == 0) {
Vanger 0:b86d15c6ba29 10945 CYASSL_MSG("Using ECC client cert");
Vanger 0:b86d15c6ba29 10946 usingEcc = 1;
Vanger 0:b86d15c6ba29 10947 sigOutSz = MAX_ENCODED_SIG_SZ;
Vanger 0:b86d15c6ba29 10948 }
Vanger 0:b86d15c6ba29 10949 else {
Vanger 0:b86d15c6ba29 10950 CYASSL_MSG("Bad client cert type");
Vanger 0:b86d15c6ba29 10951 }
Vanger 0:b86d15c6ba29 10952 #endif
Vanger 0:b86d15c6ba29 10953 }
Vanger 0:b86d15c6ba29 10954 if (ret == 0) {
Vanger 0:b86d15c6ba29 10955 byte* verify = (byte*)&output[RECORD_HEADER_SZ +
Vanger 0:b86d15c6ba29 10956 HANDSHAKE_HEADER_SZ];
Vanger 0:b86d15c6ba29 10957 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 10958 byte* signBuffer = ssl->certHashes.md5;
Vanger 0:b86d15c6ba29 10959 #else
Vanger 0:b86d15c6ba29 10960 byte* signBuffer = NULL;
Vanger 0:b86d15c6ba29 10961 #endif
Vanger 0:b86d15c6ba29 10962 word32 signSz = FINISHED_SZ;
Vanger 0:b86d15c6ba29 10963 word32 extraSz = 0; /* tls 1.2 hash/sig */
Vanger 0:b86d15c6ba29 10964 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10965 byte* encodedSig = NULL;
Vanger 0:b86d15c6ba29 10966 #else
Vanger 0:b86d15c6ba29 10967 byte encodedSig[MAX_ENCODED_SIG_SZ];
Vanger 0:b86d15c6ba29 10968 #endif
Vanger 0:b86d15c6ba29 10969
Vanger 0:b86d15c6ba29 10970 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 10971 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
Vanger 0:b86d15c6ba29 10972 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 10973 if (encodedSig == NULL) {
Vanger 0:b86d15c6ba29 10974 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 10975 if (initRsaKey)
Vanger 0:b86d15c6ba29 10976 FreeRsaKey(&key);
Vanger 0:b86d15c6ba29 10977 #endif
Vanger 0:b86d15c6ba29 10978 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 10979 ecc_free(&eccKey);
Vanger 0:b86d15c6ba29 10980 #endif
Vanger 0:b86d15c6ba29 10981 return MEMORY_E;
Vanger 0:b86d15c6ba29 10982 }
Vanger 0:b86d15c6ba29 10983 #endif
Vanger 0:b86d15c6ba29 10984
Vanger 0:b86d15c6ba29 10985 (void)encodedSig;
Vanger 0:b86d15c6ba29 10986 (void)signSz;
Vanger 0:b86d15c6ba29 10987 (void)signBuffer;
Vanger 0:b86d15c6ba29 10988
Vanger 0:b86d15c6ba29 10989 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 10990 if (ssl->options.dtls)
Vanger 0:b86d15c6ba29 10991 verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 10992 #endif
Vanger 0:b86d15c6ba29 10993 length = sigOutSz;
Vanger 0:b86d15c6ba29 10994 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 10995 verify[0] = ssl->suites->hashAlgo;
Vanger 0:b86d15c6ba29 10996 verify[1] = usingEcc ? ecc_dsa_sa_algo : rsa_sa_algo;
Vanger 0:b86d15c6ba29 10997 extraSz = HASH_SIG_SIZE;
Vanger 0:b86d15c6ba29 10998 }
Vanger 0:b86d15c6ba29 10999
Vanger 0:b86d15c6ba29 11000 if (usingEcc) {
Vanger 0:b86d15c6ba29 11001 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 11002 word32 localSz = MAX_ENCODED_SIG_SZ;
Vanger 0:b86d15c6ba29 11003 word32 digestSz;
Vanger 0:b86d15c6ba29 11004 byte* digest;
Vanger 0:b86d15c6ba29 11005 byte doUserEcc = 0;
Vanger 0:b86d15c6ba29 11006 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 11007 /* old tls default */
Vanger 0:b86d15c6ba29 11008 digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11009 digest = ssl->certHashes.sha;
Vanger 0:b86d15c6ba29 11010 #else
Vanger 0:b86d15c6ba29 11011 /* new tls default */
Vanger 0:b86d15c6ba29 11012 digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11013 digest = ssl->certHashes.sha256;
Vanger 0:b86d15c6ba29 11014 #endif
Vanger 0:b86d15c6ba29 11015
Vanger 0:b86d15c6ba29 11016 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 11017 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 11018 if (ssl->ctx->EccSignCb)
Vanger 0:b86d15c6ba29 11019 doUserEcc = 1;
Vanger 0:b86d15c6ba29 11020 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 11021 #endif /*HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 11022
Vanger 0:b86d15c6ba29 11023 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 11024 if (ssl->suites->hashAlgo == sha_mac) {
Vanger 0:b86d15c6ba29 11025 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 11026 digest = ssl->certHashes.sha;
Vanger 0:b86d15c6ba29 11027 digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11028 #endif
Vanger 0:b86d15c6ba29 11029 }
Vanger 0:b86d15c6ba29 11030 else if (ssl->suites->hashAlgo == sha256_mac) {
Vanger 0:b86d15c6ba29 11031 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 11032 digest = ssl->certHashes.sha256;
Vanger 0:b86d15c6ba29 11033 digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11034 #endif
Vanger 0:b86d15c6ba29 11035 }
Vanger 0:b86d15c6ba29 11036 else if (ssl->suites->hashAlgo == sha384_mac) {
Vanger 0:b86d15c6ba29 11037 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 11038 digest = ssl->certHashes.sha384;
Vanger 0:b86d15c6ba29 11039 digestSz = SHA384_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11040 #endif
Vanger 0:b86d15c6ba29 11041 }
Vanger 0:b86d15c6ba29 11042 }
Vanger 0:b86d15c6ba29 11043
Vanger 0:b86d15c6ba29 11044 if (doUserEcc) {
Vanger 0:b86d15c6ba29 11045 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 11046 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 11047 ret = ssl->ctx->EccSignCb(ssl, digest, digestSz,
Vanger 0:b86d15c6ba29 11048 encodedSig, &localSz,
Vanger 0:b86d15c6ba29 11049 ssl->buffers.key.buffer,
Vanger 0:b86d15c6ba29 11050 ssl->buffers.key.length,
Vanger 0:b86d15c6ba29 11051 ssl->EccSignCtx);
Vanger 0:b86d15c6ba29 11052 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 11053 #endif /*HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 11054 }
Vanger 0:b86d15c6ba29 11055 else {
Vanger 0:b86d15c6ba29 11056 ret = ecc_sign_hash(digest, digestSz, encodedSig,
Vanger 0:b86d15c6ba29 11057 &localSz, ssl->rng, &eccKey);
Vanger 0:b86d15c6ba29 11058 }
Vanger 0:b86d15c6ba29 11059 if (ret == 0) {
Vanger 0:b86d15c6ba29 11060 length = localSz;
Vanger 0:b86d15c6ba29 11061 c16toa((word16)length, verify + extraSz); /* prepend hdr */
Vanger 0:b86d15c6ba29 11062 XMEMCPY(verify + extraSz + VERIFY_HEADER,encodedSig,length);
Vanger 0:b86d15c6ba29 11063 }
Vanger 0:b86d15c6ba29 11064 #endif
Vanger 0:b86d15c6ba29 11065 }
Vanger 0:b86d15c6ba29 11066 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 11067 else {
Vanger 0:b86d15c6ba29 11068 byte doUserRsa = 0;
Vanger 0:b86d15c6ba29 11069
Vanger 0:b86d15c6ba29 11070 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 11071 if (ssl->ctx->RsaSignCb)
Vanger 0:b86d15c6ba29 11072 doUserRsa = 1;
Vanger 0:b86d15c6ba29 11073 #endif /*HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 11074
Vanger 0:b86d15c6ba29 11075 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 11076 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 11077 byte* digest = ssl->certHashes.sha;
Vanger 0:b86d15c6ba29 11078 int digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11079 int typeH = SHAh;
Vanger 0:b86d15c6ba29 11080 #else
Vanger 0:b86d15c6ba29 11081 byte* digest = ssl->certHashes.sha256;
Vanger 0:b86d15c6ba29 11082 int digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11083 int typeH = SHA256h;
Vanger 0:b86d15c6ba29 11084 #endif
Vanger 0:b86d15c6ba29 11085
Vanger 0:b86d15c6ba29 11086 if (ssl->suites->hashAlgo == sha_mac) {
Vanger 0:b86d15c6ba29 11087 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 11088 digest = ssl->certHashes.sha;
Vanger 0:b86d15c6ba29 11089 typeH = SHAh;
Vanger 0:b86d15c6ba29 11090 digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11091 #endif
Vanger 0:b86d15c6ba29 11092 }
Vanger 0:b86d15c6ba29 11093 else if (ssl->suites->hashAlgo == sha256_mac) {
Vanger 0:b86d15c6ba29 11094 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 11095 digest = ssl->certHashes.sha256;
Vanger 0:b86d15c6ba29 11096 typeH = SHA256h;
Vanger 0:b86d15c6ba29 11097 digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11098 #endif
Vanger 0:b86d15c6ba29 11099 }
Vanger 0:b86d15c6ba29 11100 else if (ssl->suites->hashAlgo == sha384_mac) {
Vanger 0:b86d15c6ba29 11101 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 11102 digest = ssl->certHashes.sha384;
Vanger 0:b86d15c6ba29 11103 typeH = SHA384h;
Vanger 0:b86d15c6ba29 11104 digestSz = SHA384_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11105 #endif
Vanger 0:b86d15c6ba29 11106 }
Vanger 0:b86d15c6ba29 11107
Vanger 0:b86d15c6ba29 11108 signSz = EncodeSignature(encodedSig, digest,digestSz,typeH);
Vanger 0:b86d15c6ba29 11109 signBuffer = encodedSig;
Vanger 0:b86d15c6ba29 11110 }
Vanger 0:b86d15c6ba29 11111
Vanger 0:b86d15c6ba29 11112 c16toa((word16)length, verify + extraSz); /* prepend hdr */
Vanger 0:b86d15c6ba29 11113 if (doUserRsa) {
Vanger 0:b86d15c6ba29 11114 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 11115 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 11116 word32 ioLen = ENCRYPT_LEN;
Vanger 0:b86d15c6ba29 11117 ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
Vanger 0:b86d15c6ba29 11118 verify + extraSz + VERIFY_HEADER,
Vanger 0:b86d15c6ba29 11119 &ioLen,
Vanger 0:b86d15c6ba29 11120 ssl->buffers.key.buffer,
Vanger 0:b86d15c6ba29 11121 ssl->buffers.key.length,
Vanger 0:b86d15c6ba29 11122 ssl->RsaSignCtx);
Vanger 0:b86d15c6ba29 11123 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 11124 #endif /*HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 11125 }
Vanger 0:b86d15c6ba29 11126 else {
Vanger 0:b86d15c6ba29 11127 ret = RsaSSL_Sign(signBuffer, signSz, verify + extraSz +
Vanger 0:b86d15c6ba29 11128 VERIFY_HEADER, ENCRYPT_LEN, &key, ssl->rng);
Vanger 0:b86d15c6ba29 11129 }
Vanger 0:b86d15c6ba29 11130
Vanger 0:b86d15c6ba29 11131 if (ret > 0)
Vanger 0:b86d15c6ba29 11132 ret = 0; /* RSA reset */
Vanger 0:b86d15c6ba29 11133 }
Vanger 0:b86d15c6ba29 11134 #endif
Vanger 0:b86d15c6ba29 11135 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 11136 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 11137 #endif
Vanger 0:b86d15c6ba29 11138
Vanger 0:b86d15c6ba29 11139 if (ret == 0) {
Vanger 0:b86d15c6ba29 11140 AddHeaders(output, length + extraSz + VERIFY_HEADER,
Vanger 0:b86d15c6ba29 11141 certificate_verify, ssl);
Vanger 0:b86d15c6ba29 11142
Vanger 0:b86d15c6ba29 11143 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + length +
Vanger 0:b86d15c6ba29 11144 extraSz + VERIFY_HEADER;
Vanger 0:b86d15c6ba29 11145
Vanger 0:b86d15c6ba29 11146 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 11147 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 11148 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 11149 }
Vanger 0:b86d15c6ba29 11150 #endif
Vanger 0:b86d15c6ba29 11151
Vanger 0:b86d15c6ba29 11152 if (ssl->keys.encryptionOn) {
Vanger 0:b86d15c6ba29 11153 byte* input;
Vanger 0:b86d15c6ba29 11154 int inputSz = sendSz - RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 11155 /* build msg adds rec hdr */
Vanger 0:b86d15c6ba29 11156 input = (byte*)XMALLOC(inputSz, ssl->heap,
Vanger 0:b86d15c6ba29 11157 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 11158 if (input == NULL)
Vanger 0:b86d15c6ba29 11159 ret = MEMORY_E;
Vanger 0:b86d15c6ba29 11160 else {
Vanger 0:b86d15c6ba29 11161 XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
Vanger 0:b86d15c6ba29 11162 sendSz = BuildMessage(ssl, output,
Vanger 0:b86d15c6ba29 11163 MAX_CERT_VERIFY_SZ +MAX_MSG_EXTRA,
Vanger 0:b86d15c6ba29 11164 input, inputSz, handshake);
Vanger 0:b86d15c6ba29 11165 XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 11166
Vanger 0:b86d15c6ba29 11167 if (sendSz < 0)
Vanger 0:b86d15c6ba29 11168 ret = sendSz;
Vanger 0:b86d15c6ba29 11169 }
Vanger 0:b86d15c6ba29 11170 } else {
Vanger 0:b86d15c6ba29 11171 ret = HashOutput(ssl, output, sendSz, 0);
Vanger 0:b86d15c6ba29 11172 }
Vanger 0:b86d15c6ba29 11173
Vanger 0:b86d15c6ba29 11174 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 11175 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 11176 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
Vanger 0:b86d15c6ba29 11177 return ret;
Vanger 0:b86d15c6ba29 11178 }
Vanger 0:b86d15c6ba29 11179 #endif
Vanger 0:b86d15c6ba29 11180 }
Vanger 0:b86d15c6ba29 11181 }
Vanger 0:b86d15c6ba29 11182 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 11183 if (initRsaKey)
Vanger 0:b86d15c6ba29 11184 FreeRsaKey(&key);
Vanger 0:b86d15c6ba29 11185 #endif
Vanger 0:b86d15c6ba29 11186 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 11187 ecc_free(&eccKey);
Vanger 0:b86d15c6ba29 11188 #endif
Vanger 0:b86d15c6ba29 11189
Vanger 0:b86d15c6ba29 11190 if (ret == 0) {
Vanger 0:b86d15c6ba29 11191 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 11192 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 11193 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 11194 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 11195 AddPacketInfo("CertificateVerify", &ssl->timeoutInfo,
Vanger 0:b86d15c6ba29 11196 output, sendSz, ssl->heap);
Vanger 0:b86d15c6ba29 11197 #endif
Vanger 0:b86d15c6ba29 11198 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 11199 if (ssl->options.groupMessages)
Vanger 0:b86d15c6ba29 11200 return 0;
Vanger 0:b86d15c6ba29 11201 else
Vanger 0:b86d15c6ba29 11202 return SendBuffered(ssl);
Vanger 0:b86d15c6ba29 11203 }
Vanger 0:b86d15c6ba29 11204 else
Vanger 0:b86d15c6ba29 11205 return ret;
Vanger 0:b86d15c6ba29 11206 }
Vanger 0:b86d15c6ba29 11207 #endif /* NO_CERTS */
Vanger 0:b86d15c6ba29 11208
Vanger 0:b86d15c6ba29 11209 #ifdef HAVE_SESSION_TICKET
Vanger 0:b86d15c6ba29 11210 int DoSessionTicket(CYASSL* ssl,
Vanger 0:b86d15c6ba29 11211 const byte* input, word32* inOutIdx, word32 size)
Vanger 0:b86d15c6ba29 11212 {
Vanger 0:b86d15c6ba29 11213 word32 begin = *inOutIdx;
Vanger 0:b86d15c6ba29 11214 word32 lifetime;
Vanger 0:b86d15c6ba29 11215 word16 length;
Vanger 0:b86d15c6ba29 11216
Vanger 0:b86d15c6ba29 11217 if (ssl->expect_session_ticket == 0) {
Vanger 0:b86d15c6ba29 11218 CYASSL_MSG("Unexpected session ticket");
Vanger 0:b86d15c6ba29 11219 return SESSION_TICKET_EXPECT_E;
Vanger 0:b86d15c6ba29 11220 }
Vanger 0:b86d15c6ba29 11221
Vanger 0:b86d15c6ba29 11222 if ((*inOutIdx - begin) + OPAQUE32_LEN > size)
Vanger 0:b86d15c6ba29 11223 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 11224
Vanger 0:b86d15c6ba29 11225 ato32(input + *inOutIdx, &lifetime);
Vanger 0:b86d15c6ba29 11226 *inOutIdx += OPAQUE32_LEN;
Vanger 0:b86d15c6ba29 11227
Vanger 0:b86d15c6ba29 11228 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 11229 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 11230
Vanger 0:b86d15c6ba29 11231 ato16(input + *inOutIdx, &length);
Vanger 0:b86d15c6ba29 11232 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 11233
Vanger 0:b86d15c6ba29 11234 if (length > sizeof(ssl->session.ticket))
Vanger 0:b86d15c6ba29 11235 return SESSION_TICKET_LEN_E;
Vanger 0:b86d15c6ba29 11236
Vanger 0:b86d15c6ba29 11237 if ((*inOutIdx - begin) + length > size)
Vanger 0:b86d15c6ba29 11238 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 11239
Vanger 0:b86d15c6ba29 11240 /* If the received ticket including its length is greater than
Vanger 0:b86d15c6ba29 11241 * a length value, the save it. Otherwise, don't save it. */
Vanger 0:b86d15c6ba29 11242 if (length > 0) {
Vanger 0:b86d15c6ba29 11243 XMEMCPY(ssl->session.ticket, input + *inOutIdx, length);
Vanger 0:b86d15c6ba29 11244 *inOutIdx += length;
Vanger 0:b86d15c6ba29 11245 ssl->session.ticketLen = length;
Vanger 0:b86d15c6ba29 11246 ssl->timeout = lifetime;
Vanger 0:b86d15c6ba29 11247 if (ssl->session_ticket_cb != NULL) {
Vanger 0:b86d15c6ba29 11248 ssl->session_ticket_cb(ssl,
Vanger 0:b86d15c6ba29 11249 ssl->session.ticket, ssl->session.ticketLen,
Vanger 0:b86d15c6ba29 11250 ssl->session_ticket_ctx);
Vanger 0:b86d15c6ba29 11251 }
Vanger 0:b86d15c6ba29 11252 /* Create a fake sessionID based on the ticket, this will
Vanger 0:b86d15c6ba29 11253 * supercede the existing session cache info. */
Vanger 0:b86d15c6ba29 11254 ssl->options.haveSessionId = 1;
Vanger 0:b86d15c6ba29 11255 XMEMCPY(ssl->arrays->sessionID,
Vanger 0:b86d15c6ba29 11256 ssl->session.ticket + length - ID_LEN, ID_LEN);
Vanger 0:b86d15c6ba29 11257 #ifndef NO_SESSION_CACHE
Vanger 0:b86d15c6ba29 11258 AddSession(ssl);
Vanger 0:b86d15c6ba29 11259 #endif
Vanger 0:b86d15c6ba29 11260
Vanger 0:b86d15c6ba29 11261 }
Vanger 0:b86d15c6ba29 11262 else {
Vanger 0:b86d15c6ba29 11263 ssl->session.ticketLen = 0;
Vanger 0:b86d15c6ba29 11264 }
Vanger 0:b86d15c6ba29 11265
Vanger 0:b86d15c6ba29 11266 if (ssl->keys.encryptionOn) {
Vanger 0:b86d15c6ba29 11267 *inOutIdx += ssl->keys.padSz;
Vanger 0:b86d15c6ba29 11268 }
Vanger 0:b86d15c6ba29 11269
Vanger 0:b86d15c6ba29 11270 ssl->expect_session_ticket = 0;
Vanger 0:b86d15c6ba29 11271
Vanger 0:b86d15c6ba29 11272 return BuildFinished(ssl, &ssl->verifyHashes, server);
Vanger 0:b86d15c6ba29 11273 }
Vanger 0:b86d15c6ba29 11274 #endif /* HAVE_SESSION_TICKET */
Vanger 0:b86d15c6ba29 11275
Vanger 0:b86d15c6ba29 11276 #endif /* NO_CYASSL_CLIENT */
Vanger 0:b86d15c6ba29 11277
Vanger 0:b86d15c6ba29 11278
Vanger 0:b86d15c6ba29 11279 #ifndef NO_CYASSL_SERVER
Vanger 0:b86d15c6ba29 11280
Vanger 0:b86d15c6ba29 11281 int SendServerHello(CYASSL* ssl)
Vanger 0:b86d15c6ba29 11282 {
Vanger 0:b86d15c6ba29 11283 byte *output;
Vanger 0:b86d15c6ba29 11284 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 11285 int sendSz;
Vanger 0:b86d15c6ba29 11286 int ret;
Vanger 0:b86d15c6ba29 11287
Vanger 0:b86d15c6ba29 11288 length = VERSION_SZ + RAN_LEN
Vanger 0:b86d15c6ba29 11289 + ID_LEN + ENUM_LEN
Vanger 0:b86d15c6ba29 11290 + SUITE_LEN
Vanger 0:b86d15c6ba29 11291 + ENUM_LEN;
Vanger 0:b86d15c6ba29 11292
Vanger 0:b86d15c6ba29 11293 #ifdef HAVE_TLS_EXTENSIONS
Vanger 0:b86d15c6ba29 11294 length += TLSX_GetResponseSize(ssl);
Vanger 0:b86d15c6ba29 11295 #endif
Vanger 0:b86d15c6ba29 11296
Vanger 0:b86d15c6ba29 11297 /* check for avalaible size */
Vanger 0:b86d15c6ba29 11298 if ((ret = CheckAvailableSize(ssl, MAX_HELLO_SZ)) != 0)
Vanger 0:b86d15c6ba29 11299 return ret;
Vanger 0:b86d15c6ba29 11300
Vanger 0:b86d15c6ba29 11301 /* get ouput buffer */
Vanger 0:b86d15c6ba29 11302 output = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 11303 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 11304
Vanger 0:b86d15c6ba29 11305 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 11306 AddHeaders(output, length, server_hello, ssl);
Vanger 0:b86d15c6ba29 11307
Vanger 0:b86d15c6ba29 11308 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 11309 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 11310 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 11311 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 11312 }
Vanger 0:b86d15c6ba29 11313 #endif
Vanger 0:b86d15c6ba29 11314 /* now write to output */
Vanger 0:b86d15c6ba29 11315 /* first version */
Vanger 0:b86d15c6ba29 11316 output[idx++] = ssl->version.major;
Vanger 0:b86d15c6ba29 11317 output[idx++] = ssl->version.minor;
Vanger 0:b86d15c6ba29 11318
Vanger 0:b86d15c6ba29 11319 /* then random */
Vanger 0:b86d15c6ba29 11320 if (!ssl->options.resuming) {
Vanger 0:b86d15c6ba29 11321 ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
Vanger 0:b86d15c6ba29 11322 RAN_LEN);
Vanger 0:b86d15c6ba29 11323 if (ret != 0)
Vanger 0:b86d15c6ba29 11324 return ret;
Vanger 0:b86d15c6ba29 11325 }
Vanger 0:b86d15c6ba29 11326
Vanger 0:b86d15c6ba29 11327 XMEMCPY(output + idx, ssl->arrays->serverRandom, RAN_LEN);
Vanger 0:b86d15c6ba29 11328 idx += RAN_LEN;
Vanger 0:b86d15c6ba29 11329
Vanger 0:b86d15c6ba29 11330 #ifdef SHOW_SECRETS
Vanger 0:b86d15c6ba29 11331 {
Vanger 0:b86d15c6ba29 11332 int j;
Vanger 0:b86d15c6ba29 11333 printf("server random: ");
Vanger 0:b86d15c6ba29 11334 for (j = 0; j < RAN_LEN; j++)
Vanger 0:b86d15c6ba29 11335 printf("%02x", ssl->arrays->serverRandom[j]);
Vanger 0:b86d15c6ba29 11336 printf("\n");
Vanger 0:b86d15c6ba29 11337 }
Vanger 0:b86d15c6ba29 11338 #endif
Vanger 0:b86d15c6ba29 11339 /* then session id */
Vanger 0:b86d15c6ba29 11340 output[idx++] = ID_LEN;
Vanger 0:b86d15c6ba29 11341
Vanger 0:b86d15c6ba29 11342 if (!ssl->options.resuming) {
Vanger 0:b86d15c6ba29 11343 ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->sessionID, ID_LEN);
Vanger 0:b86d15c6ba29 11344 if (ret != 0)
Vanger 0:b86d15c6ba29 11345 return ret;
Vanger 0:b86d15c6ba29 11346 }
Vanger 0:b86d15c6ba29 11347
Vanger 0:b86d15c6ba29 11348 XMEMCPY(output + idx, ssl->arrays->sessionID, ID_LEN);
Vanger 0:b86d15c6ba29 11349 idx += ID_LEN;
Vanger 0:b86d15c6ba29 11350
Vanger 0:b86d15c6ba29 11351 /* then cipher suite */
Vanger 0:b86d15c6ba29 11352 output[idx++] = ssl->options.cipherSuite0;
Vanger 0:b86d15c6ba29 11353 output[idx++] = ssl->options.cipherSuite;
Vanger 0:b86d15c6ba29 11354
Vanger 0:b86d15c6ba29 11355 /* then compression */
Vanger 0:b86d15c6ba29 11356 if (ssl->options.usingCompression)
Vanger 0:b86d15c6ba29 11357 output[idx++] = ZLIB_COMPRESSION;
Vanger 0:b86d15c6ba29 11358 else
Vanger 0:b86d15c6ba29 11359 output[idx++] = NO_COMPRESSION;
Vanger 0:b86d15c6ba29 11360
Vanger 0:b86d15c6ba29 11361 /* last, extensions */
Vanger 0:b86d15c6ba29 11362 #ifdef HAVE_TLS_EXTENSIONS
Vanger 0:b86d15c6ba29 11363 TLSX_WriteResponse(ssl, output + idx);
Vanger 0:b86d15c6ba29 11364 #endif
Vanger 0:b86d15c6ba29 11365
Vanger 0:b86d15c6ba29 11366 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 11367 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 11368 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 11369 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
Vanger 0:b86d15c6ba29 11370 return ret;
Vanger 0:b86d15c6ba29 11371 }
Vanger 0:b86d15c6ba29 11372 #endif
Vanger 0:b86d15c6ba29 11373
Vanger 0:b86d15c6ba29 11374 ret = HashOutput(ssl, output, sendSz, 0);
Vanger 0:b86d15c6ba29 11375 if (ret != 0)
Vanger 0:b86d15c6ba29 11376 return ret;
Vanger 0:b86d15c6ba29 11377
Vanger 0:b86d15c6ba29 11378 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 11379 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 11380 AddPacketName("ServerHello", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 11381 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 11382 AddPacketInfo("ServerHello", &ssl->timeoutInfo, output, sendSz,
Vanger 0:b86d15c6ba29 11383 ssl->heap);
Vanger 0:b86d15c6ba29 11384 #endif
Vanger 0:b86d15c6ba29 11385
Vanger 0:b86d15c6ba29 11386 ssl->options.serverState = SERVER_HELLO_COMPLETE;
Vanger 0:b86d15c6ba29 11387
Vanger 0:b86d15c6ba29 11388 if (ssl->options.groupMessages)
Vanger 0:b86d15c6ba29 11389 return 0;
Vanger 0:b86d15c6ba29 11390 else
Vanger 0:b86d15c6ba29 11391 return SendBuffered(ssl);
Vanger 0:b86d15c6ba29 11392 }
Vanger 0:b86d15c6ba29 11393
Vanger 0:b86d15c6ba29 11394
Vanger 0:b86d15c6ba29 11395 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 11396
Vanger 0:b86d15c6ba29 11397 static byte SetCurveId(int size)
Vanger 0:b86d15c6ba29 11398 {
Vanger 0:b86d15c6ba29 11399 switch(size) {
Vanger 0:b86d15c6ba29 11400 case 20:
Vanger 0:b86d15c6ba29 11401 return secp160r1;
Vanger 0:b86d15c6ba29 11402 case 24:
Vanger 0:b86d15c6ba29 11403 return secp192r1;
Vanger 0:b86d15c6ba29 11404 case 28:
Vanger 0:b86d15c6ba29 11405 return secp224r1;
Vanger 0:b86d15c6ba29 11406 case 32:
Vanger 0:b86d15c6ba29 11407 return secp256r1;
Vanger 0:b86d15c6ba29 11408 case 48:
Vanger 0:b86d15c6ba29 11409 return secp384r1;
Vanger 0:b86d15c6ba29 11410 case 66:
Vanger 0:b86d15c6ba29 11411 return secp521r1;
Vanger 0:b86d15c6ba29 11412 default:
Vanger 0:b86d15c6ba29 11413 return 0;
Vanger 0:b86d15c6ba29 11414 }
Vanger 0:b86d15c6ba29 11415 }
Vanger 0:b86d15c6ba29 11416
Vanger 0:b86d15c6ba29 11417 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 11418
Vanger 0:b86d15c6ba29 11419
Vanger 0:b86d15c6ba29 11420 int SendServerKeyExchange(CYASSL* ssl)
Vanger 0:b86d15c6ba29 11421 {
Vanger 0:b86d15c6ba29 11422 int ret = 0;
Vanger 0:b86d15c6ba29 11423 (void)ssl;
Vanger 0:b86d15c6ba29 11424 #define ERROR_OUT(err, eLabel) do { ret = err; goto eLabel; } while(0)
Vanger 0:b86d15c6ba29 11425
Vanger 0:b86d15c6ba29 11426 #ifndef NO_PSK
Vanger 0:b86d15c6ba29 11427 if (ssl->specs.kea == psk_kea)
Vanger 0:b86d15c6ba29 11428 {
Vanger 0:b86d15c6ba29 11429 byte *output;
Vanger 0:b86d15c6ba29 11430 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 11431 int sendSz;
Vanger 0:b86d15c6ba29 11432 if (ssl->arrays->server_hint[0] == 0) return 0; /* don't send */
Vanger 0:b86d15c6ba29 11433
Vanger 0:b86d15c6ba29 11434 /* include size part */
Vanger 0:b86d15c6ba29 11435 length = (word32)XSTRLEN(ssl->arrays->server_hint);
Vanger 0:b86d15c6ba29 11436 if (length > MAX_PSK_ID_LEN)
Vanger 0:b86d15c6ba29 11437 return SERVER_HINT_ERROR;
Vanger 0:b86d15c6ba29 11438
Vanger 0:b86d15c6ba29 11439 length += HINT_LEN_SZ;
Vanger 0:b86d15c6ba29 11440 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 11441
Vanger 0:b86d15c6ba29 11442 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 11443 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 11444 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 11445 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 11446 }
Vanger 0:b86d15c6ba29 11447 #endif
Vanger 0:b86d15c6ba29 11448 /* check for available size */
Vanger 0:b86d15c6ba29 11449 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
Vanger 0:b86d15c6ba29 11450 return ret;
Vanger 0:b86d15c6ba29 11451
Vanger 0:b86d15c6ba29 11452 /* get ouput buffer */
Vanger 0:b86d15c6ba29 11453 output = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 11454 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 11455
Vanger 0:b86d15c6ba29 11456 AddHeaders(output, length, server_key_exchange, ssl);
Vanger 0:b86d15c6ba29 11457
Vanger 0:b86d15c6ba29 11458 /* key data */
Vanger 0:b86d15c6ba29 11459 c16toa((word16)(length - HINT_LEN_SZ), output + idx);
Vanger 0:b86d15c6ba29 11460 idx += HINT_LEN_SZ;
Vanger 0:b86d15c6ba29 11461 XMEMCPY(output + idx, ssl->arrays->server_hint,length -HINT_LEN_SZ);
Vanger 0:b86d15c6ba29 11462
Vanger 0:b86d15c6ba29 11463 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 11464 if (ssl->options.dtls)
Vanger 0:b86d15c6ba29 11465 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
Vanger 0:b86d15c6ba29 11466 return ret;
Vanger 0:b86d15c6ba29 11467 #endif
Vanger 0:b86d15c6ba29 11468
Vanger 0:b86d15c6ba29 11469 ret = HashOutput(ssl, output, sendSz, 0);
Vanger 0:b86d15c6ba29 11470 if (ret != 0)
Vanger 0:b86d15c6ba29 11471 return ret;
Vanger 0:b86d15c6ba29 11472
Vanger 0:b86d15c6ba29 11473 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 11474 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 11475 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 11476 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 11477 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo, output,
Vanger 0:b86d15c6ba29 11478 sendSz, ssl->heap);
Vanger 0:b86d15c6ba29 11479 #endif
Vanger 0:b86d15c6ba29 11480
Vanger 0:b86d15c6ba29 11481 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 11482 if (ssl->options.groupMessages)
Vanger 0:b86d15c6ba29 11483 ret = 0;
Vanger 0:b86d15c6ba29 11484 else
Vanger 0:b86d15c6ba29 11485 ret = SendBuffered(ssl);
Vanger 0:b86d15c6ba29 11486 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
Vanger 0:b86d15c6ba29 11487 }
Vanger 0:b86d15c6ba29 11488 #endif /*NO_PSK */
Vanger 0:b86d15c6ba29 11489
Vanger 0:b86d15c6ba29 11490 #if !defined(NO_DH) && !defined(NO_PSK)
Vanger 0:b86d15c6ba29 11491 if (ssl->specs.kea == dhe_psk_kea) {
Vanger 0:b86d15c6ba29 11492 byte *output;
Vanger 0:b86d15c6ba29 11493 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 11494 word32 hintLen;
Vanger 0:b86d15c6ba29 11495 int sendSz;
Vanger 0:b86d15c6ba29 11496 DhKey dhKey;
Vanger 0:b86d15c6ba29 11497
Vanger 0:b86d15c6ba29 11498 if (ssl->buffers.serverDH_P.buffer == NULL ||
Vanger 0:b86d15c6ba29 11499 ssl->buffers.serverDH_G.buffer == NULL)
Vanger 0:b86d15c6ba29 11500 return NO_DH_PARAMS;
Vanger 0:b86d15c6ba29 11501
Vanger 0:b86d15c6ba29 11502 if (ssl->buffers.serverDH_Pub.buffer == NULL) {
Vanger 0:b86d15c6ba29 11503 ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
Vanger 0:b86d15c6ba29 11504 ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
Vanger 0:b86d15c6ba29 11505 DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 11506 if (ssl->buffers.serverDH_Pub.buffer == NULL)
Vanger 0:b86d15c6ba29 11507 return MEMORY_E;
Vanger 0:b86d15c6ba29 11508 }
Vanger 0:b86d15c6ba29 11509
Vanger 0:b86d15c6ba29 11510 if (ssl->buffers.serverDH_Priv.buffer == NULL) {
Vanger 0:b86d15c6ba29 11511 ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
Vanger 0:b86d15c6ba29 11512 ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
Vanger 0:b86d15c6ba29 11513 DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 11514 if (ssl->buffers.serverDH_Priv.buffer == NULL)
Vanger 0:b86d15c6ba29 11515 return MEMORY_E;
Vanger 0:b86d15c6ba29 11516 }
Vanger 0:b86d15c6ba29 11517
Vanger 0:b86d15c6ba29 11518 InitDhKey(&dhKey);
Vanger 0:b86d15c6ba29 11519 ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
Vanger 0:b86d15c6ba29 11520 ssl->buffers.serverDH_P.length,
Vanger 0:b86d15c6ba29 11521 ssl->buffers.serverDH_G.buffer,
Vanger 0:b86d15c6ba29 11522 ssl->buffers.serverDH_G.length);
Vanger 0:b86d15c6ba29 11523 if (ret == 0)
Vanger 0:b86d15c6ba29 11524 ret = DhGenerateKeyPair(&dhKey, ssl->rng,
Vanger 0:b86d15c6ba29 11525 ssl->buffers.serverDH_Priv.buffer,
Vanger 0:b86d15c6ba29 11526 &ssl->buffers.serverDH_Priv.length,
Vanger 0:b86d15c6ba29 11527 ssl->buffers.serverDH_Pub.buffer,
Vanger 0:b86d15c6ba29 11528 &ssl->buffers.serverDH_Pub.length);
Vanger 0:b86d15c6ba29 11529 FreeDhKey(&dhKey);
Vanger 0:b86d15c6ba29 11530 if (ret != 0)
Vanger 0:b86d15c6ba29 11531 return ret;
Vanger 0:b86d15c6ba29 11532
Vanger 0:b86d15c6ba29 11533 length = LENGTH_SZ * 3 + /* p, g, pub */
Vanger 0:b86d15c6ba29 11534 ssl->buffers.serverDH_P.length +
Vanger 0:b86d15c6ba29 11535 ssl->buffers.serverDH_G.length +
Vanger 0:b86d15c6ba29 11536 ssl->buffers.serverDH_Pub.length;
Vanger 0:b86d15c6ba29 11537
Vanger 0:b86d15c6ba29 11538 /* include size part */
Vanger 0:b86d15c6ba29 11539 hintLen = (word32)XSTRLEN(ssl->arrays->server_hint);
Vanger 0:b86d15c6ba29 11540 if (hintLen > MAX_PSK_ID_LEN)
Vanger 0:b86d15c6ba29 11541 return SERVER_HINT_ERROR;
Vanger 0:b86d15c6ba29 11542 length += hintLen + HINT_LEN_SZ;
Vanger 0:b86d15c6ba29 11543 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 11544
Vanger 0:b86d15c6ba29 11545 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 11546 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 11547 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 11548 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 11549 }
Vanger 0:b86d15c6ba29 11550 #endif
Vanger 0:b86d15c6ba29 11551
Vanger 0:b86d15c6ba29 11552 /* check for available size */
Vanger 0:b86d15c6ba29 11553 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
Vanger 0:b86d15c6ba29 11554 return ret;
Vanger 0:b86d15c6ba29 11555
Vanger 0:b86d15c6ba29 11556 /* get ouput buffer */
Vanger 0:b86d15c6ba29 11557 output = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 11558 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 11559
Vanger 0:b86d15c6ba29 11560 AddHeaders(output, length, server_key_exchange, ssl);
Vanger 0:b86d15c6ba29 11561
Vanger 0:b86d15c6ba29 11562 /* key data */
Vanger 0:b86d15c6ba29 11563 c16toa((word16)hintLen, output + idx);
Vanger 0:b86d15c6ba29 11564 idx += HINT_LEN_SZ;
Vanger 0:b86d15c6ba29 11565 XMEMCPY(output + idx, ssl->arrays->server_hint, hintLen);
Vanger 0:b86d15c6ba29 11566 idx += hintLen;
Vanger 0:b86d15c6ba29 11567
Vanger 0:b86d15c6ba29 11568 /* add p, g, pub */
Vanger 0:b86d15c6ba29 11569 c16toa((word16)ssl->buffers.serverDH_P.length, output + idx);
Vanger 0:b86d15c6ba29 11570 idx += LENGTH_SZ;
Vanger 0:b86d15c6ba29 11571 XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer,
Vanger 0:b86d15c6ba29 11572 ssl->buffers.serverDH_P.length);
Vanger 0:b86d15c6ba29 11573 idx += ssl->buffers.serverDH_P.length;
Vanger 0:b86d15c6ba29 11574
Vanger 0:b86d15c6ba29 11575 /* g */
Vanger 0:b86d15c6ba29 11576 c16toa((word16)ssl->buffers.serverDH_G.length, output + idx);
Vanger 0:b86d15c6ba29 11577 idx += LENGTH_SZ;
Vanger 0:b86d15c6ba29 11578 XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer,
Vanger 0:b86d15c6ba29 11579 ssl->buffers.serverDH_G.length);
Vanger 0:b86d15c6ba29 11580 idx += ssl->buffers.serverDH_G.length;
Vanger 0:b86d15c6ba29 11581
Vanger 0:b86d15c6ba29 11582 /* pub */
Vanger 0:b86d15c6ba29 11583 c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx);
Vanger 0:b86d15c6ba29 11584 idx += LENGTH_SZ;
Vanger 0:b86d15c6ba29 11585 XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer,
Vanger 0:b86d15c6ba29 11586 ssl->buffers.serverDH_Pub.length);
Vanger 0:b86d15c6ba29 11587 idx += ssl->buffers.serverDH_Pub.length;
Vanger 0:b86d15c6ba29 11588 (void)idx; /* suppress analyzer warning, and keep idx current */
Vanger 0:b86d15c6ba29 11589
Vanger 0:b86d15c6ba29 11590 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 11591 if (ssl->options.dtls)
Vanger 0:b86d15c6ba29 11592 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
Vanger 0:b86d15c6ba29 11593 return ret;
Vanger 0:b86d15c6ba29 11594 #endif
Vanger 0:b86d15c6ba29 11595
Vanger 0:b86d15c6ba29 11596 ret = HashOutput(ssl, output, sendSz, 0);
Vanger 0:b86d15c6ba29 11597
Vanger 0:b86d15c6ba29 11598 if (ret != 0)
Vanger 0:b86d15c6ba29 11599 return ret;
Vanger 0:b86d15c6ba29 11600
Vanger 0:b86d15c6ba29 11601 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 11602 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 11603 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 11604 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 11605 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo, output,
Vanger 0:b86d15c6ba29 11606 sendSz, ssl->heap);
Vanger 0:b86d15c6ba29 11607 #endif
Vanger 0:b86d15c6ba29 11608
Vanger 0:b86d15c6ba29 11609 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 11610 if (ssl->options.groupMessages)
Vanger 0:b86d15c6ba29 11611 ret = 0;
Vanger 0:b86d15c6ba29 11612 else
Vanger 0:b86d15c6ba29 11613 ret = SendBuffered(ssl);
Vanger 0:b86d15c6ba29 11614 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
Vanger 0:b86d15c6ba29 11615 }
Vanger 0:b86d15c6ba29 11616 #endif /* !NO_DH && !NO_PSK */
Vanger 0:b86d15c6ba29 11617
Vanger 0:b86d15c6ba29 11618 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 11619 if (ssl->specs.kea == ecc_diffie_hellman_kea)
Vanger 0:b86d15c6ba29 11620 {
Vanger 0:b86d15c6ba29 11621 byte *output;
Vanger 0:b86d15c6ba29 11622 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 11623 int sendSz;
Vanger 0:b86d15c6ba29 11624 word32 sigSz;
Vanger 0:b86d15c6ba29 11625 word32 preSigSz, preSigIdx;
Vanger 0:b86d15c6ba29 11626 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 11627 RsaKey rsaKey;
Vanger 0:b86d15c6ba29 11628 #endif
Vanger 0:b86d15c6ba29 11629 ecc_key dsaKey;
Vanger 0:b86d15c6ba29 11630 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 11631 byte* exportBuf = NULL;
Vanger 0:b86d15c6ba29 11632 #else
Vanger 0:b86d15c6ba29 11633 byte exportBuf[MAX_EXPORT_ECC_SZ];
Vanger 0:b86d15c6ba29 11634 #endif
Vanger 0:b86d15c6ba29 11635 word32 expSz = MAX_EXPORT_ECC_SZ;
Vanger 0:b86d15c6ba29 11636
Vanger 0:b86d15c6ba29 11637 if (ssl->specs.static_ecdh) {
Vanger 0:b86d15c6ba29 11638 CYASSL_MSG("Using Static ECDH, not sending ServerKeyExchagne");
Vanger 0:b86d15c6ba29 11639 return 0;
Vanger 0:b86d15c6ba29 11640 }
Vanger 0:b86d15c6ba29 11641
Vanger 0:b86d15c6ba29 11642 /* curve type, named curve, length(1) */
Vanger 0:b86d15c6ba29 11643 length = ENUM_LEN + CURVE_LEN + ENUM_LEN;
Vanger 0:b86d15c6ba29 11644 /* pub key size */
Vanger 0:b86d15c6ba29 11645 CYASSL_MSG("Using ephemeral ECDH");
Vanger 0:b86d15c6ba29 11646
Vanger 0:b86d15c6ba29 11647 /* need ephemeral key now, create it if missing */
Vanger 0:b86d15c6ba29 11648 if (ssl->eccTempKeyPresent == 0) {
Vanger 0:b86d15c6ba29 11649 if (ecc_make_key(ssl->rng, ssl->eccTempKeySz,
Vanger 0:b86d15c6ba29 11650 ssl->eccTempKey) != 0) {
Vanger 0:b86d15c6ba29 11651 return ECC_MAKEKEY_ERROR;
Vanger 0:b86d15c6ba29 11652 }
Vanger 0:b86d15c6ba29 11653 ssl->eccTempKeyPresent = 1;
Vanger 0:b86d15c6ba29 11654 }
Vanger 0:b86d15c6ba29 11655
Vanger 0:b86d15c6ba29 11656 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 11657 exportBuf = (byte*)XMALLOC(MAX_EXPORT_ECC_SZ, NULL,
Vanger 0:b86d15c6ba29 11658 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 11659 if (exportBuf == NULL)
Vanger 0:b86d15c6ba29 11660 return MEMORY_E;
Vanger 0:b86d15c6ba29 11661 #endif
Vanger 0:b86d15c6ba29 11662
Vanger 0:b86d15c6ba29 11663 if (ecc_export_x963(ssl->eccTempKey, exportBuf, &expSz) != 0)
Vanger 0:b86d15c6ba29 11664 ERROR_OUT(ECC_EXPORT_ERROR, done_a);
Vanger 0:b86d15c6ba29 11665 length += expSz;
Vanger 0:b86d15c6ba29 11666
Vanger 0:b86d15c6ba29 11667 preSigSz = length;
Vanger 0:b86d15c6ba29 11668 preSigIdx = idx;
Vanger 0:b86d15c6ba29 11669
Vanger 0:b86d15c6ba29 11670 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 11671 ret = InitRsaKey(&rsaKey, ssl->heap);
Vanger 0:b86d15c6ba29 11672 if (ret != 0)
Vanger 0:b86d15c6ba29 11673 goto done_a;
Vanger 0:b86d15c6ba29 11674 #endif
Vanger 0:b86d15c6ba29 11675
Vanger 0:b86d15c6ba29 11676 ecc_init(&dsaKey);
Vanger 0:b86d15c6ba29 11677
Vanger 0:b86d15c6ba29 11678 /* sig length */
Vanger 0:b86d15c6ba29 11679 length += LENGTH_SZ;
Vanger 0:b86d15c6ba29 11680
Vanger 0:b86d15c6ba29 11681 if (!ssl->buffers.key.buffer) {
Vanger 0:b86d15c6ba29 11682 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 11683 FreeRsaKey(&rsaKey);
Vanger 0:b86d15c6ba29 11684 #endif
Vanger 0:b86d15c6ba29 11685 ecc_free(&dsaKey);
Vanger 0:b86d15c6ba29 11686 ERROR_OUT(NO_PRIVATE_KEY, done_a);
Vanger 0:b86d15c6ba29 11687 }
Vanger 0:b86d15c6ba29 11688
Vanger 0:b86d15c6ba29 11689 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 11690 if (ssl->specs.sig_algo == rsa_sa_algo) {
Vanger 0:b86d15c6ba29 11691 /* rsa sig size */
Vanger 0:b86d15c6ba29 11692 word32 i = 0;
Vanger 0:b86d15c6ba29 11693 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i,
Vanger 0:b86d15c6ba29 11694 &rsaKey, ssl->buffers.key.length);
Vanger 0:b86d15c6ba29 11695 if (ret != 0)
Vanger 0:b86d15c6ba29 11696 goto done_a;
Vanger 0:b86d15c6ba29 11697 sigSz = RsaEncryptSize(&rsaKey);
Vanger 0:b86d15c6ba29 11698 } else
Vanger 0:b86d15c6ba29 11699 #endif
Vanger 0:b86d15c6ba29 11700
Vanger 0:b86d15c6ba29 11701 if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
Vanger 0:b86d15c6ba29 11702 /* ecdsa sig size */
Vanger 0:b86d15c6ba29 11703 word32 i = 0;
Vanger 0:b86d15c6ba29 11704 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
Vanger 0:b86d15c6ba29 11705 &dsaKey, ssl->buffers.key.length);
Vanger 0:b86d15c6ba29 11706 if (ret != 0)
Vanger 0:b86d15c6ba29 11707 goto done_a;
Vanger 0:b86d15c6ba29 11708 sigSz = ecc_sig_size(&dsaKey); /* worst case estimate */
Vanger 0:b86d15c6ba29 11709 }
Vanger 0:b86d15c6ba29 11710 else {
Vanger 0:b86d15c6ba29 11711 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 11712 FreeRsaKey(&rsaKey);
Vanger 0:b86d15c6ba29 11713 #endif
Vanger 0:b86d15c6ba29 11714 ecc_free(&dsaKey);
Vanger 0:b86d15c6ba29 11715 ERROR_OUT(ALGO_ID_E, done_a); /* unsupported type */
Vanger 0:b86d15c6ba29 11716 }
Vanger 0:b86d15c6ba29 11717 length += sigSz;
Vanger 0:b86d15c6ba29 11718
Vanger 0:b86d15c6ba29 11719 if (IsAtLeastTLSv1_2(ssl))
Vanger 0:b86d15c6ba29 11720 length += HASH_SIG_SIZE;
Vanger 0:b86d15c6ba29 11721
Vanger 0:b86d15c6ba29 11722 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 11723
Vanger 0:b86d15c6ba29 11724 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 11725 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 11726 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 11727 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 11728 preSigIdx = idx;
Vanger 0:b86d15c6ba29 11729 }
Vanger 0:b86d15c6ba29 11730 #endif
Vanger 0:b86d15c6ba29 11731 /* check for available size */
Vanger 0:b86d15c6ba29 11732 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
Vanger 0:b86d15c6ba29 11733 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 11734 FreeRsaKey(&rsaKey);
Vanger 0:b86d15c6ba29 11735 #endif
Vanger 0:b86d15c6ba29 11736 ecc_free(&dsaKey);
Vanger 0:b86d15c6ba29 11737 goto done_a;
Vanger 0:b86d15c6ba29 11738 }
Vanger 0:b86d15c6ba29 11739
Vanger 0:b86d15c6ba29 11740 /* get ouput buffer */
Vanger 0:b86d15c6ba29 11741 output = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 11742 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 11743
Vanger 0:b86d15c6ba29 11744 /* record and message headers will be added below, when we're sure
Vanger 0:b86d15c6ba29 11745 of the sig length */
Vanger 0:b86d15c6ba29 11746
Vanger 0:b86d15c6ba29 11747 /* key exchange data */
Vanger 0:b86d15c6ba29 11748 output[idx++] = named_curve;
Vanger 0:b86d15c6ba29 11749 output[idx++] = 0x00; /* leading zero */
Vanger 0:b86d15c6ba29 11750 output[idx++] = SetCurveId(ecc_size(ssl->eccTempKey));
Vanger 0:b86d15c6ba29 11751 output[idx++] = (byte)expSz;
Vanger 0:b86d15c6ba29 11752 XMEMCPY(output + idx, exportBuf, expSz);
Vanger 0:b86d15c6ba29 11753 idx += expSz;
Vanger 0:b86d15c6ba29 11754 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 11755 output[idx++] = ssl->suites->hashAlgo;
Vanger 0:b86d15c6ba29 11756 output[idx++] = ssl->suites->sigAlgo;
Vanger 0:b86d15c6ba29 11757 }
Vanger 0:b86d15c6ba29 11758
Vanger 0:b86d15c6ba29 11759 /* Signtaure length will be written later, when we're sure what it
Vanger 0:b86d15c6ba29 11760 is */
Vanger 0:b86d15c6ba29 11761
Vanger 0:b86d15c6ba29 11762 #ifdef HAVE_FUZZER
Vanger 0:b86d15c6ba29 11763 if (ssl->fuzzerCb)
Vanger 0:b86d15c6ba29 11764 ssl->fuzzerCb(ssl, output + preSigIdx, preSigSz, FUZZ_SIGNATURE,
Vanger 0:b86d15c6ba29 11765 ssl->fuzzerCtx);
Vanger 0:b86d15c6ba29 11766 #endif
Vanger 0:b86d15c6ba29 11767
Vanger 0:b86d15c6ba29 11768 /* do signature */
Vanger 0:b86d15c6ba29 11769 {
Vanger 0:b86d15c6ba29 11770 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 11771 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 11772 Md5* md5 = NULL;
Vanger 0:b86d15c6ba29 11773 Sha* sha = NULL;
Vanger 0:b86d15c6ba29 11774 #else
Vanger 0:b86d15c6ba29 11775 Md5 md5[1];
Vanger 0:b86d15c6ba29 11776 Sha sha[1];
Vanger 0:b86d15c6ba29 11777 #endif
Vanger 0:b86d15c6ba29 11778 #endif
Vanger 0:b86d15c6ba29 11779 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 11780 byte* hash = NULL;
Vanger 0:b86d15c6ba29 11781 #else
Vanger 0:b86d15c6ba29 11782 byte hash[FINISHED_SZ];
Vanger 0:b86d15c6ba29 11783 #endif
Vanger 0:b86d15c6ba29 11784 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 11785 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 11786 Sha256* sha256 = NULL;
Vanger 0:b86d15c6ba29 11787 byte* hash256 = NULL;
Vanger 0:b86d15c6ba29 11788 #else
Vanger 0:b86d15c6ba29 11789 Sha256 sha256[1];
Vanger 0:b86d15c6ba29 11790 byte hash256[SHA256_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 11791 #endif
Vanger 0:b86d15c6ba29 11792 #endif
Vanger 0:b86d15c6ba29 11793 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 11794 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 11795 Sha384* sha384 = NULL;
Vanger 0:b86d15c6ba29 11796 byte* hash384 = NULL;
Vanger 0:b86d15c6ba29 11797 #else
Vanger 0:b86d15c6ba29 11798 Sha384 sha384[1];
Vanger 0:b86d15c6ba29 11799 byte hash384[SHA384_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 11800 #endif
Vanger 0:b86d15c6ba29 11801 #endif
Vanger 0:b86d15c6ba29 11802
Vanger 0:b86d15c6ba29 11803 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 11804 hash = (byte*)XMALLOC(FINISHED_SZ, NULL,
Vanger 0:b86d15c6ba29 11805 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 11806 if (hash == NULL)
Vanger 0:b86d15c6ba29 11807 ERROR_OUT(MEMORY_E, done_a);
Vanger 0:b86d15c6ba29 11808 #endif
Vanger 0:b86d15c6ba29 11809
Vanger 0:b86d15c6ba29 11810 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 11811 /* md5 */
Vanger 0:b86d15c6ba29 11812 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 11813 md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 11814 if (md5 == NULL)
Vanger 0:b86d15c6ba29 11815 ERROR_OUT(MEMORY_E, done_a2);
Vanger 0:b86d15c6ba29 11816 #endif
Vanger 0:b86d15c6ba29 11817 InitMd5(md5);
Vanger 0:b86d15c6ba29 11818 Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN);
Vanger 0:b86d15c6ba29 11819 Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN);
Vanger 0:b86d15c6ba29 11820 Md5Update(md5, output + preSigIdx, preSigSz);
Vanger 0:b86d15c6ba29 11821 Md5Final(md5, hash);
Vanger 0:b86d15c6ba29 11822
Vanger 0:b86d15c6ba29 11823 /* sha */
Vanger 0:b86d15c6ba29 11824 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 11825 sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 11826 if (sha == NULL)
Vanger 0:b86d15c6ba29 11827 ERROR_OUT(MEMORY_E, done_a2);
Vanger 0:b86d15c6ba29 11828 #endif
Vanger 0:b86d15c6ba29 11829 ret = InitSha(sha);
Vanger 0:b86d15c6ba29 11830 if (ret != 0)
Vanger 0:b86d15c6ba29 11831 goto done_a2;
Vanger 0:b86d15c6ba29 11832 ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN);
Vanger 0:b86d15c6ba29 11833 ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN);
Vanger 0:b86d15c6ba29 11834 ShaUpdate(sha, output + preSigIdx, preSigSz);
Vanger 0:b86d15c6ba29 11835 ShaFinal(sha, &hash[MD5_DIGEST_SIZE]);
Vanger 0:b86d15c6ba29 11836 #endif
Vanger 0:b86d15c6ba29 11837
Vanger 0:b86d15c6ba29 11838 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 11839 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 11840 sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
Vanger 0:b86d15c6ba29 11841 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 11842 hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL,
Vanger 0:b86d15c6ba29 11843 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 11844 if (sha256 == NULL || hash256 == NULL)
Vanger 0:b86d15c6ba29 11845 ERROR_OUT(MEMORY_E, done_a2);
Vanger 0:b86d15c6ba29 11846 #endif
Vanger 0:b86d15c6ba29 11847
Vanger 0:b86d15c6ba29 11848 if (!(ret = InitSha256(sha256))
Vanger 0:b86d15c6ba29 11849 && !(ret = Sha256Update(sha256, ssl->arrays->clientRandom,
Vanger 0:b86d15c6ba29 11850 RAN_LEN))
Vanger 0:b86d15c6ba29 11851 && !(ret = Sha256Update(sha256, ssl->arrays->serverRandom,
Vanger 0:b86d15c6ba29 11852 RAN_LEN))
Vanger 0:b86d15c6ba29 11853 && !(ret = Sha256Update(sha256, output + preSigIdx, preSigSz)))
Vanger 0:b86d15c6ba29 11854 ret = Sha256Final(sha256, hash256);
Vanger 0:b86d15c6ba29 11855
Vanger 0:b86d15c6ba29 11856 if (ret != 0)
Vanger 0:b86d15c6ba29 11857 goto done_a2;
Vanger 0:b86d15c6ba29 11858 #endif
Vanger 0:b86d15c6ba29 11859
Vanger 0:b86d15c6ba29 11860 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 11861 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 11862 sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,
Vanger 0:b86d15c6ba29 11863 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 11864 hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL,
Vanger 0:b86d15c6ba29 11865 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 11866 if (sha384 == NULL || hash384 == NULL)
Vanger 0:b86d15c6ba29 11867 ERROR_OUT(MEMORY_E, done_a2);
Vanger 0:b86d15c6ba29 11868 #endif
Vanger 0:b86d15c6ba29 11869
Vanger 0:b86d15c6ba29 11870 if (!(ret = InitSha384(sha384))
Vanger 0:b86d15c6ba29 11871 && !(ret = Sha384Update(sha384, ssl->arrays->clientRandom,
Vanger 0:b86d15c6ba29 11872 RAN_LEN))
Vanger 0:b86d15c6ba29 11873 && !(ret = Sha384Update(sha384, ssl->arrays->serverRandom,
Vanger 0:b86d15c6ba29 11874 RAN_LEN))
Vanger 0:b86d15c6ba29 11875 && !(ret = Sha384Update(sha384, output + preSigIdx, preSigSz)))
Vanger 0:b86d15c6ba29 11876 ret = Sha384Final(sha384, hash384);
Vanger 0:b86d15c6ba29 11877
Vanger 0:b86d15c6ba29 11878 if (ret != 0)
Vanger 0:b86d15c6ba29 11879 goto done_a2;
Vanger 0:b86d15c6ba29 11880 #endif
Vanger 0:b86d15c6ba29 11881
Vanger 0:b86d15c6ba29 11882 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 11883 if (ssl->suites->sigAlgo == rsa_sa_algo) {
Vanger 0:b86d15c6ba29 11884 byte* signBuffer = hash;
Vanger 0:b86d15c6ba29 11885 word32 signSz = FINISHED_SZ;
Vanger 0:b86d15c6ba29 11886 byte doUserRsa = 0;
Vanger 0:b86d15c6ba29 11887 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 11888 byte* encodedSig = NULL;
Vanger 0:b86d15c6ba29 11889 #else
Vanger 0:b86d15c6ba29 11890 byte encodedSig[MAX_ENCODED_SIG_SZ];
Vanger 0:b86d15c6ba29 11891 #endif
Vanger 0:b86d15c6ba29 11892
Vanger 0:b86d15c6ba29 11893 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 11894 if (ssl->ctx->RsaSignCb)
Vanger 0:b86d15c6ba29 11895 doUserRsa = 1;
Vanger 0:b86d15c6ba29 11896 #endif
Vanger 0:b86d15c6ba29 11897
Vanger 0:b86d15c6ba29 11898 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 11899 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
Vanger 0:b86d15c6ba29 11900 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 11901 if (encodedSig == NULL)
Vanger 0:b86d15c6ba29 11902 ERROR_OUT(MEMORY_E, done_a2);
Vanger 0:b86d15c6ba29 11903 #endif
Vanger 0:b86d15c6ba29 11904
Vanger 0:b86d15c6ba29 11905 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 11906 byte* digest = &hash[MD5_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 11907 int typeH = SHAh;
Vanger 0:b86d15c6ba29 11908 int digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11909
Vanger 0:b86d15c6ba29 11910 if (ssl->suites->hashAlgo == sha256_mac) {
Vanger 0:b86d15c6ba29 11911 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 11912 digest = hash256;
Vanger 0:b86d15c6ba29 11913 typeH = SHA256h;
Vanger 0:b86d15c6ba29 11914 digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11915 #endif
Vanger 0:b86d15c6ba29 11916 }
Vanger 0:b86d15c6ba29 11917 else if (ssl->suites->hashAlgo == sha384_mac) {
Vanger 0:b86d15c6ba29 11918 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 11919 digest = hash384;
Vanger 0:b86d15c6ba29 11920 typeH = SHA384h;
Vanger 0:b86d15c6ba29 11921 digestSz = SHA384_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11922 #endif
Vanger 0:b86d15c6ba29 11923 }
Vanger 0:b86d15c6ba29 11924
Vanger 0:b86d15c6ba29 11925 signSz = EncodeSignature(encodedSig, digest, digestSz,
Vanger 0:b86d15c6ba29 11926 typeH);
Vanger 0:b86d15c6ba29 11927 signBuffer = encodedSig;
Vanger 0:b86d15c6ba29 11928 }
Vanger 0:b86d15c6ba29 11929 /* write sig size here */
Vanger 0:b86d15c6ba29 11930 c16toa((word16)sigSz, output + idx);
Vanger 0:b86d15c6ba29 11931 idx += LENGTH_SZ;
Vanger 0:b86d15c6ba29 11932
Vanger 0:b86d15c6ba29 11933 if (doUserRsa) {
Vanger 0:b86d15c6ba29 11934 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 11935 word32 ioLen = sigSz;
Vanger 0:b86d15c6ba29 11936 ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
Vanger 0:b86d15c6ba29 11937 output + idx, &ioLen,
Vanger 0:b86d15c6ba29 11938 ssl->buffers.key.buffer,
Vanger 0:b86d15c6ba29 11939 ssl->buffers.key.length,
Vanger 0:b86d15c6ba29 11940 ssl->RsaSignCtx);
Vanger 0:b86d15c6ba29 11941 #endif /*HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 11942 }
Vanger 0:b86d15c6ba29 11943 else
Vanger 0:b86d15c6ba29 11944 ret = RsaSSL_Sign(signBuffer, signSz, output + idx,
Vanger 0:b86d15c6ba29 11945 sigSz, &rsaKey, ssl->rng);
Vanger 0:b86d15c6ba29 11946
Vanger 0:b86d15c6ba29 11947 FreeRsaKey(&rsaKey);
Vanger 0:b86d15c6ba29 11948 ecc_free(&dsaKey);
Vanger 0:b86d15c6ba29 11949
Vanger 0:b86d15c6ba29 11950 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 11951 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 11952 #endif
Vanger 0:b86d15c6ba29 11953
Vanger 0:b86d15c6ba29 11954 if (ret < 0)
Vanger 0:b86d15c6ba29 11955 goto done_a2;
Vanger 0:b86d15c6ba29 11956 } else
Vanger 0:b86d15c6ba29 11957 #endif
Vanger 0:b86d15c6ba29 11958
Vanger 0:b86d15c6ba29 11959 if (ssl->suites->sigAlgo == ecc_dsa_sa_algo) {
Vanger 0:b86d15c6ba29 11960 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 11961 byte* digest = &hash[MD5_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 11962 word32 digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11963 #else
Vanger 0:b86d15c6ba29 11964 byte* digest = hash256;
Vanger 0:b86d15c6ba29 11965 word32 digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11966 #endif
Vanger 0:b86d15c6ba29 11967 word32 sz = sigSz;
Vanger 0:b86d15c6ba29 11968 byte doUserEcc = 0;
Vanger 0:b86d15c6ba29 11969
Vanger 0:b86d15c6ba29 11970 #if defined(HAVE_PK_CALLBACKS) && defined(HAVE_ECC)
Vanger 0:b86d15c6ba29 11971 if (ssl->ctx->EccSignCb)
Vanger 0:b86d15c6ba29 11972 doUserEcc = 1;
Vanger 0:b86d15c6ba29 11973 #endif
Vanger 0:b86d15c6ba29 11974
Vanger 0:b86d15c6ba29 11975 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 11976 if (ssl->suites->hashAlgo == sha_mac) {
Vanger 0:b86d15c6ba29 11977 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 11978 digest = &hash[MD5_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 11979 digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11980 #endif
Vanger 0:b86d15c6ba29 11981 }
Vanger 0:b86d15c6ba29 11982 else if (ssl->suites->hashAlgo == sha256_mac) {
Vanger 0:b86d15c6ba29 11983 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 11984 digest = hash256;
Vanger 0:b86d15c6ba29 11985 digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11986 #endif
Vanger 0:b86d15c6ba29 11987 }
Vanger 0:b86d15c6ba29 11988 else if (ssl->suites->hashAlgo == sha384_mac) {
Vanger 0:b86d15c6ba29 11989 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 11990 digest = hash384;
Vanger 0:b86d15c6ba29 11991 digestSz = SHA384_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 11992 #endif
Vanger 0:b86d15c6ba29 11993 }
Vanger 0:b86d15c6ba29 11994 }
Vanger 0:b86d15c6ba29 11995
Vanger 0:b86d15c6ba29 11996 if (doUserEcc) {
Vanger 0:b86d15c6ba29 11997 #if defined(HAVE_PK_CALLBACKS) && defined(HAVE_ECC)
Vanger 0:b86d15c6ba29 11998 ret = ssl->ctx->EccSignCb(ssl, digest, digestSz,
Vanger 0:b86d15c6ba29 11999 output + LENGTH_SZ + idx, &sz,
Vanger 0:b86d15c6ba29 12000 ssl->buffers.key.buffer,
Vanger 0:b86d15c6ba29 12001 ssl->buffers.key.length,
Vanger 0:b86d15c6ba29 12002 ssl->EccSignCtx);
Vanger 0:b86d15c6ba29 12003 #endif
Vanger 0:b86d15c6ba29 12004 }
Vanger 0:b86d15c6ba29 12005 else {
Vanger 0:b86d15c6ba29 12006 ret = ecc_sign_hash(digest, digestSz,
Vanger 0:b86d15c6ba29 12007 output + LENGTH_SZ + idx, &sz, ssl->rng, &dsaKey);
Vanger 0:b86d15c6ba29 12008 }
Vanger 0:b86d15c6ba29 12009 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 12010 FreeRsaKey(&rsaKey);
Vanger 0:b86d15c6ba29 12011 #endif
Vanger 0:b86d15c6ba29 12012 ecc_free(&dsaKey);
Vanger 0:b86d15c6ba29 12013
Vanger 0:b86d15c6ba29 12014 if (ret < 0)
Vanger 0:b86d15c6ba29 12015 goto done_a2;
Vanger 0:b86d15c6ba29 12016
Vanger 0:b86d15c6ba29 12017 /* Now that we know the real sig size, write it. */
Vanger 0:b86d15c6ba29 12018 c16toa((word16)sz, output + idx);
Vanger 0:b86d15c6ba29 12019
Vanger 0:b86d15c6ba29 12020 /* And adjust length and sendSz from estimates */
Vanger 0:b86d15c6ba29 12021 length += sz - sigSz;
Vanger 0:b86d15c6ba29 12022 sendSz += sz - sigSz;
Vanger 0:b86d15c6ba29 12023 }
Vanger 0:b86d15c6ba29 12024
Vanger 0:b86d15c6ba29 12025 done_a2:
Vanger 0:b86d15c6ba29 12026 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 12027 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 12028 XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12029 XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12030 #endif
Vanger 0:b86d15c6ba29 12031 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12032 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 12033 XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12034 XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12035 #endif
Vanger 0:b86d15c6ba29 12036 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 12037 XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12038 XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12039 #endif
Vanger 0:b86d15c6ba29 12040 #endif
Vanger 0:b86d15c6ba29 12041
Vanger 0:b86d15c6ba29 12042 if (ret < 0)
Vanger 0:b86d15c6ba29 12043 goto done_a;
Vanger 0:b86d15c6ba29 12044 }
Vanger 0:b86d15c6ba29 12045
Vanger 0:b86d15c6ba29 12046 AddHeaders(output, length, server_key_exchange, ssl);
Vanger 0:b86d15c6ba29 12047
Vanger 0:b86d15c6ba29 12048 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 12049 if (ssl->options.dtls)
Vanger 0:b86d15c6ba29 12050 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
Vanger 0:b86d15c6ba29 12051 goto done_a;
Vanger 0:b86d15c6ba29 12052 #endif
Vanger 0:b86d15c6ba29 12053
Vanger 0:b86d15c6ba29 12054 if ((ret = HashOutput(ssl, output, sendSz, 0)) != 0)
Vanger 0:b86d15c6ba29 12055 goto done_a;
Vanger 0:b86d15c6ba29 12056
Vanger 0:b86d15c6ba29 12057 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 12058 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 12059 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 12060 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 12061 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
Vanger 0:b86d15c6ba29 12062 output, sendSz, ssl->heap);
Vanger 0:b86d15c6ba29 12063 #endif
Vanger 0:b86d15c6ba29 12064
Vanger 0:b86d15c6ba29 12065 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 12066 if (ssl->options.groupMessages)
Vanger 0:b86d15c6ba29 12067 ret = 0;
Vanger 0:b86d15c6ba29 12068 else
Vanger 0:b86d15c6ba29 12069 ret = SendBuffered(ssl);
Vanger 0:b86d15c6ba29 12070 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
Vanger 0:b86d15c6ba29 12071
Vanger 0:b86d15c6ba29 12072 done_a:
Vanger 0:b86d15c6ba29 12073 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 12074 XFREE(exportBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12075 #endif
Vanger 0:b86d15c6ba29 12076
Vanger 0:b86d15c6ba29 12077 return ret;
Vanger 0:b86d15c6ba29 12078 }
Vanger 0:b86d15c6ba29 12079 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 12080
Vanger 0:b86d15c6ba29 12081 #if !defined(NO_DH) && !defined(NO_RSA)
Vanger 0:b86d15c6ba29 12082 if (ssl->specs.kea == diffie_hellman_kea) {
Vanger 0:b86d15c6ba29 12083 byte *output;
Vanger 0:b86d15c6ba29 12084 word32 length = 0, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 12085 int sendSz;
Vanger 0:b86d15c6ba29 12086 word32 sigSz = 0, i = 0;
Vanger 0:b86d15c6ba29 12087 word32 preSigSz = 0, preSigIdx = 0;
Vanger 0:b86d15c6ba29 12088 RsaKey rsaKey;
Vanger 0:b86d15c6ba29 12089 DhKey dhKey;
Vanger 0:b86d15c6ba29 12090
Vanger 0:b86d15c6ba29 12091 if (ssl->buffers.serverDH_P.buffer == NULL ||
Vanger 0:b86d15c6ba29 12092 ssl->buffers.serverDH_G.buffer == NULL)
Vanger 0:b86d15c6ba29 12093 return NO_DH_PARAMS;
Vanger 0:b86d15c6ba29 12094
Vanger 0:b86d15c6ba29 12095 if (ssl->buffers.serverDH_Pub.buffer == NULL) {
Vanger 0:b86d15c6ba29 12096 ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
Vanger 0:b86d15c6ba29 12097 ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
Vanger 0:b86d15c6ba29 12098 DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 12099 if (ssl->buffers.serverDH_Pub.buffer == NULL)
Vanger 0:b86d15c6ba29 12100 return MEMORY_E;
Vanger 0:b86d15c6ba29 12101 }
Vanger 0:b86d15c6ba29 12102
Vanger 0:b86d15c6ba29 12103 if (ssl->buffers.serverDH_Priv.buffer == NULL) {
Vanger 0:b86d15c6ba29 12104 ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
Vanger 0:b86d15c6ba29 12105 ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
Vanger 0:b86d15c6ba29 12106 DYNAMIC_TYPE_DH);
Vanger 0:b86d15c6ba29 12107 if (ssl->buffers.serverDH_Priv.buffer == NULL)
Vanger 0:b86d15c6ba29 12108 return MEMORY_E;
Vanger 0:b86d15c6ba29 12109 }
Vanger 0:b86d15c6ba29 12110
Vanger 0:b86d15c6ba29 12111 InitDhKey(&dhKey);
Vanger 0:b86d15c6ba29 12112 ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
Vanger 0:b86d15c6ba29 12113 ssl->buffers.serverDH_P.length,
Vanger 0:b86d15c6ba29 12114 ssl->buffers.serverDH_G.buffer,
Vanger 0:b86d15c6ba29 12115 ssl->buffers.serverDH_G.length);
Vanger 0:b86d15c6ba29 12116 if (ret == 0)
Vanger 0:b86d15c6ba29 12117 ret = DhGenerateKeyPair(&dhKey, ssl->rng,
Vanger 0:b86d15c6ba29 12118 ssl->buffers.serverDH_Priv.buffer,
Vanger 0:b86d15c6ba29 12119 &ssl->buffers.serverDH_Priv.length,
Vanger 0:b86d15c6ba29 12120 ssl->buffers.serverDH_Pub.buffer,
Vanger 0:b86d15c6ba29 12121 &ssl->buffers.serverDH_Pub.length);
Vanger 0:b86d15c6ba29 12122 FreeDhKey(&dhKey);
Vanger 0:b86d15c6ba29 12123
Vanger 0:b86d15c6ba29 12124 if (ret != 0) return ret;
Vanger 0:b86d15c6ba29 12125
Vanger 0:b86d15c6ba29 12126 length = LENGTH_SZ * 3; /* p, g, pub */
Vanger 0:b86d15c6ba29 12127 length += ssl->buffers.serverDH_P.length +
Vanger 0:b86d15c6ba29 12128 ssl->buffers.serverDH_G.length +
Vanger 0:b86d15c6ba29 12129 ssl->buffers.serverDH_Pub.length;
Vanger 0:b86d15c6ba29 12130
Vanger 0:b86d15c6ba29 12131 preSigIdx = idx;
Vanger 0:b86d15c6ba29 12132 preSigSz = length;
Vanger 0:b86d15c6ba29 12133
Vanger 0:b86d15c6ba29 12134 if (!ssl->options.usingAnon_cipher) {
Vanger 0:b86d15c6ba29 12135 ret = InitRsaKey(&rsaKey, ssl->heap);
Vanger 0:b86d15c6ba29 12136 if (ret != 0) return ret;
Vanger 0:b86d15c6ba29 12137
Vanger 0:b86d15c6ba29 12138 /* sig length */
Vanger 0:b86d15c6ba29 12139 length += LENGTH_SZ;
Vanger 0:b86d15c6ba29 12140
Vanger 0:b86d15c6ba29 12141 if (!ssl->buffers.key.buffer)
Vanger 0:b86d15c6ba29 12142 return NO_PRIVATE_KEY;
Vanger 0:b86d15c6ba29 12143
Vanger 0:b86d15c6ba29 12144 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i, &rsaKey,
Vanger 0:b86d15c6ba29 12145 ssl->buffers.key.length);
Vanger 0:b86d15c6ba29 12146 if (ret == 0) {
Vanger 0:b86d15c6ba29 12147 sigSz = RsaEncryptSize(&rsaKey);
Vanger 0:b86d15c6ba29 12148 length += sigSz;
Vanger 0:b86d15c6ba29 12149 }
Vanger 0:b86d15c6ba29 12150 else {
Vanger 0:b86d15c6ba29 12151 FreeRsaKey(&rsaKey);
Vanger 0:b86d15c6ba29 12152 return ret;
Vanger 0:b86d15c6ba29 12153 }
Vanger 0:b86d15c6ba29 12154
Vanger 0:b86d15c6ba29 12155 if (IsAtLeastTLSv1_2(ssl))
Vanger 0:b86d15c6ba29 12156 length += HASH_SIG_SIZE;
Vanger 0:b86d15c6ba29 12157 }
Vanger 0:b86d15c6ba29 12158
Vanger 0:b86d15c6ba29 12159 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
Vanger 0:b86d15c6ba29 12160
Vanger 0:b86d15c6ba29 12161 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 12162 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 12163 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 12164 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 12165 preSigIdx = idx;
Vanger 0:b86d15c6ba29 12166 }
Vanger 0:b86d15c6ba29 12167 #endif
Vanger 0:b86d15c6ba29 12168
Vanger 0:b86d15c6ba29 12169 /* check for available size */
Vanger 0:b86d15c6ba29 12170 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
Vanger 0:b86d15c6ba29 12171 if (!ssl->options.usingAnon_cipher)
Vanger 0:b86d15c6ba29 12172 FreeRsaKey(&rsaKey);
Vanger 0:b86d15c6ba29 12173 return ret;
Vanger 0:b86d15c6ba29 12174 }
Vanger 0:b86d15c6ba29 12175
Vanger 0:b86d15c6ba29 12176 /* get ouput buffer */
Vanger 0:b86d15c6ba29 12177 output = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 12178 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 12179
Vanger 0:b86d15c6ba29 12180 AddHeaders(output, length, server_key_exchange, ssl);
Vanger 0:b86d15c6ba29 12181
Vanger 0:b86d15c6ba29 12182 /* add p, g, pub */
Vanger 0:b86d15c6ba29 12183 c16toa((word16)ssl->buffers.serverDH_P.length, output + idx);
Vanger 0:b86d15c6ba29 12184 idx += LENGTH_SZ;
Vanger 0:b86d15c6ba29 12185 XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer,
Vanger 0:b86d15c6ba29 12186 ssl->buffers.serverDH_P.length);
Vanger 0:b86d15c6ba29 12187 idx += ssl->buffers.serverDH_P.length;
Vanger 0:b86d15c6ba29 12188
Vanger 0:b86d15c6ba29 12189 /* g */
Vanger 0:b86d15c6ba29 12190 c16toa((word16)ssl->buffers.serverDH_G.length, output + idx);
Vanger 0:b86d15c6ba29 12191 idx += LENGTH_SZ;
Vanger 0:b86d15c6ba29 12192 XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer,
Vanger 0:b86d15c6ba29 12193 ssl->buffers.serverDH_G.length);
Vanger 0:b86d15c6ba29 12194 idx += ssl->buffers.serverDH_G.length;
Vanger 0:b86d15c6ba29 12195
Vanger 0:b86d15c6ba29 12196 /* pub */
Vanger 0:b86d15c6ba29 12197 c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx);
Vanger 0:b86d15c6ba29 12198 idx += LENGTH_SZ;
Vanger 0:b86d15c6ba29 12199 XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer,
Vanger 0:b86d15c6ba29 12200 ssl->buffers.serverDH_Pub.length);
Vanger 0:b86d15c6ba29 12201 idx += ssl->buffers.serverDH_Pub.length;
Vanger 0:b86d15c6ba29 12202
Vanger 0:b86d15c6ba29 12203 #ifdef HAVE_FUZZER
Vanger 0:b86d15c6ba29 12204 if (ssl->fuzzerCb)
Vanger 0:b86d15c6ba29 12205 ssl->fuzzerCb(ssl, output + preSigIdx, preSigSz, FUZZ_SIGNATURE,
Vanger 0:b86d15c6ba29 12206 ssl->fuzzerCtx);
Vanger 0:b86d15c6ba29 12207 #endif
Vanger 0:b86d15c6ba29 12208
Vanger 0:b86d15c6ba29 12209 /* Add signature */
Vanger 0:b86d15c6ba29 12210 if (!ssl->options.usingAnon_cipher) {
Vanger 0:b86d15c6ba29 12211 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 12212 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 12213 Md5* md5 = NULL;
Vanger 0:b86d15c6ba29 12214 Sha* sha = NULL;
Vanger 0:b86d15c6ba29 12215 #else
Vanger 0:b86d15c6ba29 12216 Md5 md5[1];
Vanger 0:b86d15c6ba29 12217 Sha sha[1];
Vanger 0:b86d15c6ba29 12218 #endif
Vanger 0:b86d15c6ba29 12219 #endif
Vanger 0:b86d15c6ba29 12220 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 12221 byte* hash = NULL;
Vanger 0:b86d15c6ba29 12222 #else
Vanger 0:b86d15c6ba29 12223 byte hash[FINISHED_SZ];
Vanger 0:b86d15c6ba29 12224 #endif
Vanger 0:b86d15c6ba29 12225 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 12226 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 12227 Sha256* sha256 = NULL;
Vanger 0:b86d15c6ba29 12228 byte* hash256 = NULL;
Vanger 0:b86d15c6ba29 12229 #else
Vanger 0:b86d15c6ba29 12230 Sha256 sha256[1];
Vanger 0:b86d15c6ba29 12231 byte hash256[SHA256_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 12232 #endif
Vanger 0:b86d15c6ba29 12233 #endif
Vanger 0:b86d15c6ba29 12234 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 12235 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 12236 Sha384* sha384 = NULL;
Vanger 0:b86d15c6ba29 12237 byte* hash384 = NULL;
Vanger 0:b86d15c6ba29 12238 #else
Vanger 0:b86d15c6ba29 12239 Sha384 sha384[1];
Vanger 0:b86d15c6ba29 12240 byte hash384[SHA384_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 12241 #endif
Vanger 0:b86d15c6ba29 12242 #endif
Vanger 0:b86d15c6ba29 12243
Vanger 0:b86d15c6ba29 12244 /* Add hash/signature algo ID */
Vanger 0:b86d15c6ba29 12245 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 12246 output[idx++] = ssl->suites->hashAlgo;
Vanger 0:b86d15c6ba29 12247 output[idx++] = ssl->suites->sigAlgo;
Vanger 0:b86d15c6ba29 12248 }
Vanger 0:b86d15c6ba29 12249
Vanger 0:b86d15c6ba29 12250 /* signature size */
Vanger 0:b86d15c6ba29 12251 c16toa((word16)sigSz, output + idx);
Vanger 0:b86d15c6ba29 12252 idx += LENGTH_SZ;
Vanger 0:b86d15c6ba29 12253
Vanger 0:b86d15c6ba29 12254 /* do signature */
Vanger 0:b86d15c6ba29 12255 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 12256 hash = (byte*)XMALLOC(FINISHED_SZ, NULL,
Vanger 0:b86d15c6ba29 12257 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12258 if (hash == NULL)
Vanger 0:b86d15c6ba29 12259 return MEMORY_E; /* No heap commitment before this point,
Vanger 0:b86d15c6ba29 12260 from now on, the resources are freed
Vanger 0:b86d15c6ba29 12261 at done_b. */
Vanger 0:b86d15c6ba29 12262 #endif
Vanger 0:b86d15c6ba29 12263
Vanger 0:b86d15c6ba29 12264 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 12265 /* md5 */
Vanger 0:b86d15c6ba29 12266 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 12267 md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12268 if (md5 == NULL)
Vanger 0:b86d15c6ba29 12269 ERROR_OUT(MEMORY_E, done_b);
Vanger 0:b86d15c6ba29 12270 #endif
Vanger 0:b86d15c6ba29 12271 InitMd5(md5);
Vanger 0:b86d15c6ba29 12272 Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN);
Vanger 0:b86d15c6ba29 12273 Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN);
Vanger 0:b86d15c6ba29 12274 Md5Update(md5, output + preSigIdx, preSigSz);
Vanger 0:b86d15c6ba29 12275 Md5Final(md5, hash);
Vanger 0:b86d15c6ba29 12276
Vanger 0:b86d15c6ba29 12277 /* sha */
Vanger 0:b86d15c6ba29 12278 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 12279 sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12280 if (sha == NULL)
Vanger 0:b86d15c6ba29 12281 ERROR_OUT(MEMORY_E, done_b);
Vanger 0:b86d15c6ba29 12282 #endif
Vanger 0:b86d15c6ba29 12283
Vanger 0:b86d15c6ba29 12284 if ((ret = InitSha(sha) != 0))
Vanger 0:b86d15c6ba29 12285 goto done_b;
Vanger 0:b86d15c6ba29 12286
Vanger 0:b86d15c6ba29 12287 ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN);
Vanger 0:b86d15c6ba29 12288 ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN);
Vanger 0:b86d15c6ba29 12289 ShaUpdate(sha, output + preSigIdx, preSigSz);
Vanger 0:b86d15c6ba29 12290 ShaFinal(sha, &hash[MD5_DIGEST_SIZE]);
Vanger 0:b86d15c6ba29 12291 #endif
Vanger 0:b86d15c6ba29 12292
Vanger 0:b86d15c6ba29 12293 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 12294 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 12295 sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
Vanger 0:b86d15c6ba29 12296 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12297 hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL,
Vanger 0:b86d15c6ba29 12298 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12299 if (sha256 == NULL || hash256 == NULL)
Vanger 0:b86d15c6ba29 12300 ERROR_OUT(MEMORY_E, done_b);
Vanger 0:b86d15c6ba29 12301 #endif
Vanger 0:b86d15c6ba29 12302
Vanger 0:b86d15c6ba29 12303 if (!(ret = InitSha256(sha256))
Vanger 0:b86d15c6ba29 12304 && !(ret = Sha256Update(sha256, ssl->arrays->clientRandom,
Vanger 0:b86d15c6ba29 12305 RAN_LEN))
Vanger 0:b86d15c6ba29 12306 && !(ret = Sha256Update(sha256, ssl->arrays->serverRandom,
Vanger 0:b86d15c6ba29 12307 RAN_LEN))
Vanger 0:b86d15c6ba29 12308 && !(ret = Sha256Update(sha256, output + preSigIdx, preSigSz)))
Vanger 0:b86d15c6ba29 12309 ret = Sha256Final(sha256, hash256);
Vanger 0:b86d15c6ba29 12310
Vanger 0:b86d15c6ba29 12311 if (ret != 0)
Vanger 0:b86d15c6ba29 12312 goto done_b;
Vanger 0:b86d15c6ba29 12313 #endif
Vanger 0:b86d15c6ba29 12314
Vanger 0:b86d15c6ba29 12315 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 12316 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 12317 sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,
Vanger 0:b86d15c6ba29 12318 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12319 hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL,
Vanger 0:b86d15c6ba29 12320 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12321 if (sha384 == NULL || hash384 == NULL)
Vanger 0:b86d15c6ba29 12322 ERROR_OUT(MEMORY_E, done_b);
Vanger 0:b86d15c6ba29 12323 #endif
Vanger 0:b86d15c6ba29 12324
Vanger 0:b86d15c6ba29 12325 if (!(ret = InitSha384(sha384))
Vanger 0:b86d15c6ba29 12326 && !(ret = Sha384Update(sha384, ssl->arrays->clientRandom,
Vanger 0:b86d15c6ba29 12327 RAN_LEN))
Vanger 0:b86d15c6ba29 12328 && !(ret = Sha384Update(sha384, ssl->arrays->serverRandom,
Vanger 0:b86d15c6ba29 12329 RAN_LEN))
Vanger 0:b86d15c6ba29 12330 && !(ret = Sha384Update(sha384, output + preSigIdx, preSigSz)))
Vanger 0:b86d15c6ba29 12331 ret = Sha384Final(sha384, hash384);
Vanger 0:b86d15c6ba29 12332
Vanger 0:b86d15c6ba29 12333 if (ret != 0)
Vanger 0:b86d15c6ba29 12334 goto done_b;
Vanger 0:b86d15c6ba29 12335 #endif
Vanger 0:b86d15c6ba29 12336
Vanger 0:b86d15c6ba29 12337 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 12338 if (ssl->suites->sigAlgo == rsa_sa_algo) {
Vanger 0:b86d15c6ba29 12339 byte* signBuffer = hash;
Vanger 0:b86d15c6ba29 12340 word32 signSz = FINISHED_SZ;
Vanger 0:b86d15c6ba29 12341 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 12342 byte* encodedSig = NULL;
Vanger 0:b86d15c6ba29 12343 #else
Vanger 0:b86d15c6ba29 12344 byte encodedSig[MAX_ENCODED_SIG_SZ];
Vanger 0:b86d15c6ba29 12345 #endif
Vanger 0:b86d15c6ba29 12346 byte doUserRsa = 0;
Vanger 0:b86d15c6ba29 12347
Vanger 0:b86d15c6ba29 12348 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 12349 if (ssl->ctx->RsaSignCb)
Vanger 0:b86d15c6ba29 12350 doUserRsa = 1;
Vanger 0:b86d15c6ba29 12351 #endif
Vanger 0:b86d15c6ba29 12352
Vanger 0:b86d15c6ba29 12353 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 12354 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
Vanger 0:b86d15c6ba29 12355 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12356 if (encodedSig == NULL)
Vanger 0:b86d15c6ba29 12357 ERROR_OUT(MEMORY_E, done_b);
Vanger 0:b86d15c6ba29 12358 #endif
Vanger 0:b86d15c6ba29 12359
Vanger 0:b86d15c6ba29 12360 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 12361 byte* digest = &hash[MD5_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 12362 int typeH = SHAh;
Vanger 0:b86d15c6ba29 12363 int digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 12364
Vanger 0:b86d15c6ba29 12365 if (ssl->suites->hashAlgo == sha256_mac) {
Vanger 0:b86d15c6ba29 12366 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 12367 digest = hash256;
Vanger 0:b86d15c6ba29 12368 typeH = SHA256h;
Vanger 0:b86d15c6ba29 12369 digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 12370 #endif
Vanger 0:b86d15c6ba29 12371 }
Vanger 0:b86d15c6ba29 12372 else if (ssl->suites->hashAlgo == sha384_mac) {
Vanger 0:b86d15c6ba29 12373 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 12374 digest = hash384;
Vanger 0:b86d15c6ba29 12375 typeH = SHA384h;
Vanger 0:b86d15c6ba29 12376 digestSz = SHA384_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 12377 #endif
Vanger 0:b86d15c6ba29 12378 }
Vanger 0:b86d15c6ba29 12379
Vanger 0:b86d15c6ba29 12380 signSz = EncodeSignature(encodedSig, digest, digestSz,
Vanger 0:b86d15c6ba29 12381 typeH);
Vanger 0:b86d15c6ba29 12382 signBuffer = encodedSig;
Vanger 0:b86d15c6ba29 12383 }
Vanger 0:b86d15c6ba29 12384 if (doUserRsa) {
Vanger 0:b86d15c6ba29 12385 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 12386 word32 ioLen = sigSz;
Vanger 0:b86d15c6ba29 12387 ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
Vanger 0:b86d15c6ba29 12388 output + idx, &ioLen,
Vanger 0:b86d15c6ba29 12389 ssl->buffers.key.buffer,
Vanger 0:b86d15c6ba29 12390 ssl->buffers.key.length,
Vanger 0:b86d15c6ba29 12391 ssl->RsaSignCtx);
Vanger 0:b86d15c6ba29 12392 #endif
Vanger 0:b86d15c6ba29 12393 }
Vanger 0:b86d15c6ba29 12394 else
Vanger 0:b86d15c6ba29 12395 ret = RsaSSL_Sign(signBuffer, signSz, output + idx,
Vanger 0:b86d15c6ba29 12396 sigSz, &rsaKey, ssl->rng);
Vanger 0:b86d15c6ba29 12397
Vanger 0:b86d15c6ba29 12398 FreeRsaKey(&rsaKey);
Vanger 0:b86d15c6ba29 12399
Vanger 0:b86d15c6ba29 12400 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 12401 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12402 #endif
Vanger 0:b86d15c6ba29 12403 }
Vanger 0:b86d15c6ba29 12404 #endif
Vanger 0:b86d15c6ba29 12405
Vanger 0:b86d15c6ba29 12406 done_b:
Vanger 0:b86d15c6ba29 12407 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 12408 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 12409 XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12410 XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12411 #endif
Vanger 0:b86d15c6ba29 12412 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12413 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 12414 XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12415 XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12416 #endif
Vanger 0:b86d15c6ba29 12417 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 12418 XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12419 XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 12420 #endif
Vanger 0:b86d15c6ba29 12421 #endif
Vanger 0:b86d15c6ba29 12422
Vanger 0:b86d15c6ba29 12423 if (ret < 0) return ret;
Vanger 0:b86d15c6ba29 12424 }
Vanger 0:b86d15c6ba29 12425
Vanger 0:b86d15c6ba29 12426 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 12427 if (ssl->options.dtls)
Vanger 0:b86d15c6ba29 12428 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
Vanger 0:b86d15c6ba29 12429 return ret;
Vanger 0:b86d15c6ba29 12430 #endif
Vanger 0:b86d15c6ba29 12431
Vanger 0:b86d15c6ba29 12432 if ((ret = HashOutput(ssl, output, sendSz, 0)) != 0)
Vanger 0:b86d15c6ba29 12433 return ret;
Vanger 0:b86d15c6ba29 12434
Vanger 0:b86d15c6ba29 12435 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 12436 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 12437 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 12438 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 12439 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
Vanger 0:b86d15c6ba29 12440 output, sendSz, ssl->heap);
Vanger 0:b86d15c6ba29 12441 #endif
Vanger 0:b86d15c6ba29 12442
Vanger 0:b86d15c6ba29 12443 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 12444 if (ssl->options.groupMessages)
Vanger 0:b86d15c6ba29 12445 ret = 0;
Vanger 0:b86d15c6ba29 12446 else
Vanger 0:b86d15c6ba29 12447 ret = SendBuffered(ssl);
Vanger 0:b86d15c6ba29 12448 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
Vanger 0:b86d15c6ba29 12449 }
Vanger 0:b86d15c6ba29 12450 #endif /* NO_DH */
Vanger 0:b86d15c6ba29 12451
Vanger 0:b86d15c6ba29 12452 return ret;
Vanger 0:b86d15c6ba29 12453 #undef ERROR_OUT
Vanger 0:b86d15c6ba29 12454 }
Vanger 0:b86d15c6ba29 12455
Vanger 0:b86d15c6ba29 12456
Vanger 0:b86d15c6ba29 12457 /* Make sure server cert/key are valid for this suite, true on success */
Vanger 0:b86d15c6ba29 12458 static int VerifyServerSuite(CYASSL* ssl, word16 idx)
Vanger 0:b86d15c6ba29 12459 {
Vanger 0:b86d15c6ba29 12460 int haveRSA = !ssl->options.haveStaticECC;
Vanger 0:b86d15c6ba29 12461 int havePSK = 0;
Vanger 0:b86d15c6ba29 12462 byte first;
Vanger 0:b86d15c6ba29 12463 byte second;
Vanger 0:b86d15c6ba29 12464
Vanger 0:b86d15c6ba29 12465 CYASSL_ENTER("VerifyServerSuite");
Vanger 0:b86d15c6ba29 12466
Vanger 0:b86d15c6ba29 12467 if (ssl->suites == NULL) {
Vanger 0:b86d15c6ba29 12468 CYASSL_MSG("Suites pointer error");
Vanger 0:b86d15c6ba29 12469 return 0;
Vanger 0:b86d15c6ba29 12470 }
Vanger 0:b86d15c6ba29 12471
Vanger 0:b86d15c6ba29 12472 first = ssl->suites->suites[idx];
Vanger 0:b86d15c6ba29 12473 second = ssl->suites->suites[idx+1];
Vanger 0:b86d15c6ba29 12474
Vanger 0:b86d15c6ba29 12475 #ifndef NO_PSK
Vanger 0:b86d15c6ba29 12476 havePSK = ssl->options.havePSK;
Vanger 0:b86d15c6ba29 12477 #endif
Vanger 0:b86d15c6ba29 12478
Vanger 0:b86d15c6ba29 12479 if (ssl->options.haveNTRU)
Vanger 0:b86d15c6ba29 12480 haveRSA = 0;
Vanger 0:b86d15c6ba29 12481
Vanger 0:b86d15c6ba29 12482 if (CipherRequires(first, second, REQUIRES_RSA)) {
Vanger 0:b86d15c6ba29 12483 CYASSL_MSG("Requires RSA");
Vanger 0:b86d15c6ba29 12484 if (haveRSA == 0) {
Vanger 0:b86d15c6ba29 12485 CYASSL_MSG("Don't have RSA");
Vanger 0:b86d15c6ba29 12486 return 0;
Vanger 0:b86d15c6ba29 12487 }
Vanger 0:b86d15c6ba29 12488 }
Vanger 0:b86d15c6ba29 12489
Vanger 0:b86d15c6ba29 12490 if (CipherRequires(first, second, REQUIRES_DHE)) {
Vanger 0:b86d15c6ba29 12491 CYASSL_MSG("Requires DHE");
Vanger 0:b86d15c6ba29 12492 if (ssl->options.haveDH == 0) {
Vanger 0:b86d15c6ba29 12493 CYASSL_MSG("Don't have DHE");
Vanger 0:b86d15c6ba29 12494 return 0;
Vanger 0:b86d15c6ba29 12495 }
Vanger 0:b86d15c6ba29 12496 }
Vanger 0:b86d15c6ba29 12497
Vanger 0:b86d15c6ba29 12498 if (CipherRequires(first, second, REQUIRES_ECC_DSA)) {
Vanger 0:b86d15c6ba29 12499 CYASSL_MSG("Requires ECCDSA");
Vanger 0:b86d15c6ba29 12500 if (ssl->options.haveECDSAsig == 0) {
Vanger 0:b86d15c6ba29 12501 CYASSL_MSG("Don't have ECCDSA");
Vanger 0:b86d15c6ba29 12502 return 0;
Vanger 0:b86d15c6ba29 12503 }
Vanger 0:b86d15c6ba29 12504 }
Vanger 0:b86d15c6ba29 12505
Vanger 0:b86d15c6ba29 12506 if (CipherRequires(first, second, REQUIRES_ECC_STATIC)) {
Vanger 0:b86d15c6ba29 12507 CYASSL_MSG("Requires static ECC");
Vanger 0:b86d15c6ba29 12508 if (ssl->options.haveStaticECC == 0) {
Vanger 0:b86d15c6ba29 12509 CYASSL_MSG("Don't have static ECC");
Vanger 0:b86d15c6ba29 12510 return 0;
Vanger 0:b86d15c6ba29 12511 }
Vanger 0:b86d15c6ba29 12512 }
Vanger 0:b86d15c6ba29 12513
Vanger 0:b86d15c6ba29 12514 if (CipherRequires(first, second, REQUIRES_PSK)) {
Vanger 0:b86d15c6ba29 12515 CYASSL_MSG("Requires PSK");
Vanger 0:b86d15c6ba29 12516 if (havePSK == 0) {
Vanger 0:b86d15c6ba29 12517 CYASSL_MSG("Don't have PSK");
Vanger 0:b86d15c6ba29 12518 return 0;
Vanger 0:b86d15c6ba29 12519 }
Vanger 0:b86d15c6ba29 12520 }
Vanger 0:b86d15c6ba29 12521
Vanger 0:b86d15c6ba29 12522 if (CipherRequires(first, second, REQUIRES_NTRU)) {
Vanger 0:b86d15c6ba29 12523 CYASSL_MSG("Requires NTRU");
Vanger 0:b86d15c6ba29 12524 if (ssl->options.haveNTRU == 0) {
Vanger 0:b86d15c6ba29 12525 CYASSL_MSG("Don't have NTRU");
Vanger 0:b86d15c6ba29 12526 return 0;
Vanger 0:b86d15c6ba29 12527 }
Vanger 0:b86d15c6ba29 12528 }
Vanger 0:b86d15c6ba29 12529
Vanger 0:b86d15c6ba29 12530 if (CipherRequires(first, second, REQUIRES_RSA_SIG)) {
Vanger 0:b86d15c6ba29 12531 CYASSL_MSG("Requires RSA Signature");
Vanger 0:b86d15c6ba29 12532 if (ssl->options.side == CYASSL_SERVER_END &&
Vanger 0:b86d15c6ba29 12533 ssl->options.haveECDSAsig == 1) {
Vanger 0:b86d15c6ba29 12534 CYASSL_MSG("Don't have RSA Signature");
Vanger 0:b86d15c6ba29 12535 return 0;
Vanger 0:b86d15c6ba29 12536 }
Vanger 0:b86d15c6ba29 12537 }
Vanger 0:b86d15c6ba29 12538
Vanger 0:b86d15c6ba29 12539 #ifdef HAVE_SUPPORTED_CURVES
Vanger 0:b86d15c6ba29 12540 if (!TLSX_ValidateEllipticCurves(ssl, first, second)) {
Vanger 0:b86d15c6ba29 12541 CYASSL_MSG("Don't have matching curves");
Vanger 0:b86d15c6ba29 12542 return 0;
Vanger 0:b86d15c6ba29 12543 }
Vanger 0:b86d15c6ba29 12544 #endif
Vanger 0:b86d15c6ba29 12545
Vanger 0:b86d15c6ba29 12546 /* ECCDHE is always supported if ECC on */
Vanger 0:b86d15c6ba29 12547
Vanger 0:b86d15c6ba29 12548 return 1;
Vanger 0:b86d15c6ba29 12549 }
Vanger 0:b86d15c6ba29 12550
Vanger 0:b86d15c6ba29 12551
Vanger 0:b86d15c6ba29 12552 static int MatchSuite(CYASSL* ssl, Suites* peerSuites)
Vanger 0:b86d15c6ba29 12553 {
Vanger 0:b86d15c6ba29 12554 word16 i, j;
Vanger 0:b86d15c6ba29 12555
Vanger 0:b86d15c6ba29 12556 CYASSL_ENTER("MatchSuite");
Vanger 0:b86d15c6ba29 12557
Vanger 0:b86d15c6ba29 12558 /* & 0x1 equivalent % 2 */
Vanger 0:b86d15c6ba29 12559 if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1)
Vanger 0:b86d15c6ba29 12560 return MATCH_SUITE_ERROR;
Vanger 0:b86d15c6ba29 12561
Vanger 0:b86d15c6ba29 12562 if (ssl->suites == NULL)
Vanger 0:b86d15c6ba29 12563 return SUITES_ERROR;
Vanger 0:b86d15c6ba29 12564 /* start with best, if a match we are good */
Vanger 0:b86d15c6ba29 12565 for (i = 0; i < ssl->suites->suiteSz; i += 2)
Vanger 0:b86d15c6ba29 12566 for (j = 0; j < peerSuites->suiteSz; j += 2)
Vanger 0:b86d15c6ba29 12567 if (ssl->suites->suites[i] == peerSuites->suites[j] &&
Vanger 0:b86d15c6ba29 12568 ssl->suites->suites[i+1] == peerSuites->suites[j+1] ) {
Vanger 0:b86d15c6ba29 12569
Vanger 0:b86d15c6ba29 12570 if (VerifyServerSuite(ssl, i)) {
Vanger 0:b86d15c6ba29 12571 int result;
Vanger 0:b86d15c6ba29 12572 CYASSL_MSG("Verified suite validity");
Vanger 0:b86d15c6ba29 12573 ssl->options.cipherSuite0 = ssl->suites->suites[i];
Vanger 0:b86d15c6ba29 12574 ssl->options.cipherSuite = ssl->suites->suites[i+1];
Vanger 0:b86d15c6ba29 12575 result = SetCipherSpecs(ssl);
Vanger 0:b86d15c6ba29 12576 if (result == 0)
Vanger 0:b86d15c6ba29 12577 PickHashSigAlgo(ssl, peerSuites->hashSigAlgo,
Vanger 0:b86d15c6ba29 12578 peerSuites->hashSigAlgoSz);
Vanger 0:b86d15c6ba29 12579 return result;
Vanger 0:b86d15c6ba29 12580 }
Vanger 0:b86d15c6ba29 12581 else {
Vanger 0:b86d15c6ba29 12582 CYASSL_MSG("Could not verify suite validity, continue");
Vanger 0:b86d15c6ba29 12583 }
Vanger 0:b86d15c6ba29 12584 }
Vanger 0:b86d15c6ba29 12585
Vanger 0:b86d15c6ba29 12586 return MATCH_SUITE_ERROR;
Vanger 0:b86d15c6ba29 12587 }
Vanger 0:b86d15c6ba29 12588
Vanger 0:b86d15c6ba29 12589
Vanger 0:b86d15c6ba29 12590 #ifdef OLD_HELLO_ALLOWED
Vanger 0:b86d15c6ba29 12591
Vanger 0:b86d15c6ba29 12592 /* process old style client hello, deprecate? */
Vanger 0:b86d15c6ba29 12593 int ProcessOldClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
Vanger 0:b86d15c6ba29 12594 word32 inSz, word16 sz)
Vanger 0:b86d15c6ba29 12595 {
Vanger 0:b86d15c6ba29 12596 word32 idx = *inOutIdx;
Vanger 0:b86d15c6ba29 12597 word16 sessionSz;
Vanger 0:b86d15c6ba29 12598 word16 randomSz;
Vanger 0:b86d15c6ba29 12599 word16 i, j;
Vanger 0:b86d15c6ba29 12600 ProtocolVersion pv;
Vanger 0:b86d15c6ba29 12601 Suites clSuites;
Vanger 0:b86d15c6ba29 12602
Vanger 0:b86d15c6ba29 12603 (void)inSz;
Vanger 0:b86d15c6ba29 12604 CYASSL_MSG("Got old format client hello");
Vanger 0:b86d15c6ba29 12605 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 12606 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 12607 AddPacketName("ClientHello", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 12608 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 12609 AddLateName("ClientHello", &ssl->timeoutInfo);
Vanger 0:b86d15c6ba29 12610 #endif
Vanger 0:b86d15c6ba29 12611
Vanger 0:b86d15c6ba29 12612 /* manually hash input since different format */
Vanger 0:b86d15c6ba29 12613 #ifndef NO_OLD_TLS
Vanger 0:b86d15c6ba29 12614 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 12615 Md5Update(&ssl->hashMd5, input + idx, sz);
Vanger 0:b86d15c6ba29 12616 #endif
Vanger 0:b86d15c6ba29 12617 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 12618 ShaUpdate(&ssl->hashSha, input + idx, sz);
Vanger 0:b86d15c6ba29 12619 #endif
Vanger 0:b86d15c6ba29 12620 #endif
Vanger 0:b86d15c6ba29 12621 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 12622 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 12623 int shaRet = Sha256Update(&ssl->hashSha256, input + idx, sz);
Vanger 0:b86d15c6ba29 12624
Vanger 0:b86d15c6ba29 12625 if (shaRet != 0)
Vanger 0:b86d15c6ba29 12626 return shaRet;
Vanger 0:b86d15c6ba29 12627 }
Vanger 0:b86d15c6ba29 12628 #endif
Vanger 0:b86d15c6ba29 12629
Vanger 0:b86d15c6ba29 12630 /* does this value mean client_hello? */
Vanger 0:b86d15c6ba29 12631 idx++;
Vanger 0:b86d15c6ba29 12632
Vanger 0:b86d15c6ba29 12633 /* version */
Vanger 0:b86d15c6ba29 12634 pv.major = input[idx++];
Vanger 0:b86d15c6ba29 12635 pv.minor = input[idx++];
Vanger 0:b86d15c6ba29 12636 ssl->chVersion = pv; /* store */
Vanger 0:b86d15c6ba29 12637
Vanger 0:b86d15c6ba29 12638 if (ssl->version.minor > pv.minor) {
Vanger 0:b86d15c6ba29 12639 byte haveRSA = 0;
Vanger 0:b86d15c6ba29 12640 byte havePSK = 0;
Vanger 0:b86d15c6ba29 12641 if (!ssl->options.downgrade) {
Vanger 0:b86d15c6ba29 12642 CYASSL_MSG("Client trying to connect with lesser version");
Vanger 0:b86d15c6ba29 12643 return VERSION_ERROR;
Vanger 0:b86d15c6ba29 12644 }
Vanger 0:b86d15c6ba29 12645 if (pv.minor < ssl->options.minDowngrade) {
Vanger 0:b86d15c6ba29 12646 CYASSL_MSG(" version below minimum allowed, fatal error");
Vanger 0:b86d15c6ba29 12647 return VERSION_ERROR;
Vanger 0:b86d15c6ba29 12648 }
Vanger 0:b86d15c6ba29 12649 if (pv.minor == SSLv3_MINOR) {
Vanger 0:b86d15c6ba29 12650 /* turn off tls */
Vanger 0:b86d15c6ba29 12651 CYASSL_MSG(" downgrading to SSLv3");
Vanger 0:b86d15c6ba29 12652 ssl->options.tls = 0;
Vanger 0:b86d15c6ba29 12653 ssl->options.tls1_1 = 0;
Vanger 0:b86d15c6ba29 12654 ssl->version.minor = SSLv3_MINOR;
Vanger 0:b86d15c6ba29 12655 }
Vanger 0:b86d15c6ba29 12656 else if (pv.minor == TLSv1_MINOR) {
Vanger 0:b86d15c6ba29 12657 CYASSL_MSG(" downgrading to TLSv1");
Vanger 0:b86d15c6ba29 12658 /* turn off tls 1.1+ */
Vanger 0:b86d15c6ba29 12659 ssl->options.tls1_1 = 0;
Vanger 0:b86d15c6ba29 12660 ssl->version.minor = TLSv1_MINOR;
Vanger 0:b86d15c6ba29 12661 }
Vanger 0:b86d15c6ba29 12662 else if (pv.minor == TLSv1_1_MINOR) {
Vanger 0:b86d15c6ba29 12663 CYASSL_MSG(" downgrading to TLSv1.1");
Vanger 0:b86d15c6ba29 12664 ssl->version.minor = TLSv1_1_MINOR;
Vanger 0:b86d15c6ba29 12665 }
Vanger 0:b86d15c6ba29 12666 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 12667 haveRSA = 1;
Vanger 0:b86d15c6ba29 12668 #endif
Vanger 0:b86d15c6ba29 12669 #ifndef NO_PSK
Vanger 0:b86d15c6ba29 12670 havePSK = ssl->options.havePSK;
Vanger 0:b86d15c6ba29 12671 #endif
Vanger 0:b86d15c6ba29 12672
Vanger 0:b86d15c6ba29 12673 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
Vanger 0:b86d15c6ba29 12674 ssl->options.haveDH, ssl->options.haveNTRU,
Vanger 0:b86d15c6ba29 12675 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
Vanger 0:b86d15c6ba29 12676 ssl->options.side);
Vanger 0:b86d15c6ba29 12677 }
Vanger 0:b86d15c6ba29 12678
Vanger 0:b86d15c6ba29 12679 /* suite size */
Vanger 0:b86d15c6ba29 12680 ato16(&input[idx], &clSuites.suiteSz);
Vanger 0:b86d15c6ba29 12681 idx += 2;
Vanger 0:b86d15c6ba29 12682
Vanger 0:b86d15c6ba29 12683 if (clSuites.suiteSz > MAX_SUITE_SZ)
Vanger 0:b86d15c6ba29 12684 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12685 clSuites.hashSigAlgoSz = 0;
Vanger 0:b86d15c6ba29 12686
Vanger 0:b86d15c6ba29 12687 /* session size */
Vanger 0:b86d15c6ba29 12688 ato16(&input[idx], &sessionSz);
Vanger 0:b86d15c6ba29 12689 idx += 2;
Vanger 0:b86d15c6ba29 12690
Vanger 0:b86d15c6ba29 12691 if (sessionSz > ID_LEN)
Vanger 0:b86d15c6ba29 12692 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12693
Vanger 0:b86d15c6ba29 12694 /* random size */
Vanger 0:b86d15c6ba29 12695 ato16(&input[idx], &randomSz);
Vanger 0:b86d15c6ba29 12696 idx += 2;
Vanger 0:b86d15c6ba29 12697
Vanger 0:b86d15c6ba29 12698 if (randomSz > RAN_LEN)
Vanger 0:b86d15c6ba29 12699 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12700
Vanger 0:b86d15c6ba29 12701 /* suites */
Vanger 0:b86d15c6ba29 12702 for (i = 0, j = 0; i < clSuites.suiteSz; i += 3) {
Vanger 0:b86d15c6ba29 12703 byte first = input[idx++];
Vanger 0:b86d15c6ba29 12704 if (!first) { /* implicit: skip sslv2 type */
Vanger 0:b86d15c6ba29 12705 XMEMCPY(&clSuites.suites[j], &input[idx], 2);
Vanger 0:b86d15c6ba29 12706 j += 2;
Vanger 0:b86d15c6ba29 12707 }
Vanger 0:b86d15c6ba29 12708 idx += 2;
Vanger 0:b86d15c6ba29 12709 }
Vanger 0:b86d15c6ba29 12710 clSuites.suiteSz = j;
Vanger 0:b86d15c6ba29 12711
Vanger 0:b86d15c6ba29 12712 /* session id */
Vanger 0:b86d15c6ba29 12713 if (sessionSz) {
Vanger 0:b86d15c6ba29 12714 XMEMCPY(ssl->arrays->sessionID, input + idx, sessionSz);
Vanger 0:b86d15c6ba29 12715 idx += sessionSz;
Vanger 0:b86d15c6ba29 12716 ssl->options.resuming = 1;
Vanger 0:b86d15c6ba29 12717 }
Vanger 0:b86d15c6ba29 12718
Vanger 0:b86d15c6ba29 12719 /* random */
Vanger 0:b86d15c6ba29 12720 if (randomSz < RAN_LEN)
Vanger 0:b86d15c6ba29 12721 XMEMSET(ssl->arrays->clientRandom, 0, RAN_LEN - randomSz);
Vanger 0:b86d15c6ba29 12722 XMEMCPY(&ssl->arrays->clientRandom[RAN_LEN - randomSz], input + idx,
Vanger 0:b86d15c6ba29 12723 randomSz);
Vanger 0:b86d15c6ba29 12724 idx += randomSz;
Vanger 0:b86d15c6ba29 12725
Vanger 0:b86d15c6ba29 12726 if (ssl->options.usingCompression)
Vanger 0:b86d15c6ba29 12727 ssl->options.usingCompression = 0; /* turn off */
Vanger 0:b86d15c6ba29 12728
Vanger 0:b86d15c6ba29 12729 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
Vanger 0:b86d15c6ba29 12730 *inOutIdx = idx;
Vanger 0:b86d15c6ba29 12731
Vanger 0:b86d15c6ba29 12732 ssl->options.haveSessionId = 1;
Vanger 0:b86d15c6ba29 12733 /* DoClientHello uses same resume code */
Vanger 0:b86d15c6ba29 12734 if (ssl->options.resuming) { /* let's try */
Vanger 0:b86d15c6ba29 12735 int ret = -1;
Vanger 0:b86d15c6ba29 12736 CYASSL_SESSION* session = GetSession(ssl,ssl->arrays->masterSecret);
Vanger 0:b86d15c6ba29 12737 if (!session) {
Vanger 0:b86d15c6ba29 12738 CYASSL_MSG("Session lookup for resume failed");
Vanger 0:b86d15c6ba29 12739 ssl->options.resuming = 0;
Vanger 0:b86d15c6ba29 12740 } else {
Vanger 0:b86d15c6ba29 12741 if (MatchSuite(ssl, &clSuites) < 0) {
Vanger 0:b86d15c6ba29 12742 CYASSL_MSG("Unsupported cipher suite, OldClientHello");
Vanger 0:b86d15c6ba29 12743 return UNSUPPORTED_SUITE;
Vanger 0:b86d15c6ba29 12744 }
Vanger 0:b86d15c6ba29 12745 #ifdef SESSION_CERTS
Vanger 0:b86d15c6ba29 12746 ssl->session = *session; /* restore session certs. */
Vanger 0:b86d15c6ba29 12747 #endif
Vanger 0:b86d15c6ba29 12748
Vanger 0:b86d15c6ba29 12749 ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
Vanger 0:b86d15c6ba29 12750 RAN_LEN);
Vanger 0:b86d15c6ba29 12751 if (ret != 0)
Vanger 0:b86d15c6ba29 12752 return ret;
Vanger 0:b86d15c6ba29 12753
Vanger 0:b86d15c6ba29 12754 #ifdef NO_OLD_TLS
Vanger 0:b86d15c6ba29 12755 ret = DeriveTlsKeys(ssl);
Vanger 0:b86d15c6ba29 12756 #else
Vanger 0:b86d15c6ba29 12757 #ifndef NO_TLS
Vanger 0:b86d15c6ba29 12758 if (ssl->options.tls)
Vanger 0:b86d15c6ba29 12759 ret = DeriveTlsKeys(ssl);
Vanger 0:b86d15c6ba29 12760 #endif
Vanger 0:b86d15c6ba29 12761 if (!ssl->options.tls)
Vanger 0:b86d15c6ba29 12762 ret = DeriveKeys(ssl);
Vanger 0:b86d15c6ba29 12763 #endif
Vanger 0:b86d15c6ba29 12764 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
Vanger 0:b86d15c6ba29 12765
Vanger 0:b86d15c6ba29 12766 return ret;
Vanger 0:b86d15c6ba29 12767 }
Vanger 0:b86d15c6ba29 12768 }
Vanger 0:b86d15c6ba29 12769
Vanger 0:b86d15c6ba29 12770 return MatchSuite(ssl, &clSuites);
Vanger 0:b86d15c6ba29 12771 }
Vanger 0:b86d15c6ba29 12772
Vanger 0:b86d15c6ba29 12773 #endif /* OLD_HELLO_ALLOWED */
Vanger 0:b86d15c6ba29 12774
Vanger 0:b86d15c6ba29 12775
Vanger 0:b86d15c6ba29 12776 static int DoClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
Vanger 0:b86d15c6ba29 12777 word32 helloSz)
Vanger 0:b86d15c6ba29 12778 {
Vanger 0:b86d15c6ba29 12779 byte b;
Vanger 0:b86d15c6ba29 12780 ProtocolVersion pv;
Vanger 0:b86d15c6ba29 12781 Suites clSuites;
Vanger 0:b86d15c6ba29 12782 word32 i = *inOutIdx;
Vanger 0:b86d15c6ba29 12783 word32 begin = i;
Vanger 0:b86d15c6ba29 12784
Vanger 0:b86d15c6ba29 12785 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 12786 if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 12787 if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
Vanger 0:b86d15c6ba29 12788 #endif
Vanger 0:b86d15c6ba29 12789
Vanger 0:b86d15c6ba29 12790 /* protocol version, random and session id length check */
Vanger 0:b86d15c6ba29 12791 if ((i - begin) + OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
Vanger 0:b86d15c6ba29 12792 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12793
Vanger 0:b86d15c6ba29 12794 /* protocol version */
Vanger 0:b86d15c6ba29 12795 XMEMCPY(&pv, input + i, OPAQUE16_LEN);
Vanger 0:b86d15c6ba29 12796 ssl->chVersion = pv; /* store */
Vanger 0:b86d15c6ba29 12797 i += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 12798
Vanger 0:b86d15c6ba29 12799 if (ssl->version.minor > pv.minor) {
Vanger 0:b86d15c6ba29 12800 byte haveRSA = 0;
Vanger 0:b86d15c6ba29 12801 byte havePSK = 0;
Vanger 0:b86d15c6ba29 12802
Vanger 0:b86d15c6ba29 12803 if (!ssl->options.downgrade) {
Vanger 0:b86d15c6ba29 12804 CYASSL_MSG("Client trying to connect with lesser version");
Vanger 0:b86d15c6ba29 12805 return VERSION_ERROR;
Vanger 0:b86d15c6ba29 12806 }
Vanger 0:b86d15c6ba29 12807 if (pv.minor < ssl->options.minDowngrade) {
Vanger 0:b86d15c6ba29 12808 CYASSL_MSG(" version below minimum allowed, fatal error");
Vanger 0:b86d15c6ba29 12809 return VERSION_ERROR;
Vanger 0:b86d15c6ba29 12810 }
Vanger 0:b86d15c6ba29 12811
Vanger 0:b86d15c6ba29 12812 if (pv.minor == SSLv3_MINOR) {
Vanger 0:b86d15c6ba29 12813 /* turn off tls */
Vanger 0:b86d15c6ba29 12814 CYASSL_MSG(" downgrading to SSLv3");
Vanger 0:b86d15c6ba29 12815 ssl->options.tls = 0;
Vanger 0:b86d15c6ba29 12816 ssl->options.tls1_1 = 0;
Vanger 0:b86d15c6ba29 12817 ssl->version.minor = SSLv3_MINOR;
Vanger 0:b86d15c6ba29 12818 }
Vanger 0:b86d15c6ba29 12819 else if (pv.minor == TLSv1_MINOR) {
Vanger 0:b86d15c6ba29 12820 /* turn off tls 1.1+ */
Vanger 0:b86d15c6ba29 12821 CYASSL_MSG(" downgrading to TLSv1");
Vanger 0:b86d15c6ba29 12822 ssl->options.tls1_1 = 0;
Vanger 0:b86d15c6ba29 12823 ssl->version.minor = TLSv1_MINOR;
Vanger 0:b86d15c6ba29 12824 }
Vanger 0:b86d15c6ba29 12825 else if (pv.minor == TLSv1_1_MINOR) {
Vanger 0:b86d15c6ba29 12826 CYASSL_MSG(" downgrading to TLSv1.1");
Vanger 0:b86d15c6ba29 12827 ssl->version.minor = TLSv1_1_MINOR;
Vanger 0:b86d15c6ba29 12828 }
Vanger 0:b86d15c6ba29 12829 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 12830 haveRSA = 1;
Vanger 0:b86d15c6ba29 12831 #endif
Vanger 0:b86d15c6ba29 12832 #ifndef NO_PSK
Vanger 0:b86d15c6ba29 12833 havePSK = ssl->options.havePSK;
Vanger 0:b86d15c6ba29 12834 #endif
Vanger 0:b86d15c6ba29 12835 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
Vanger 0:b86d15c6ba29 12836 ssl->options.haveDH, ssl->options.haveNTRU,
Vanger 0:b86d15c6ba29 12837 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
Vanger 0:b86d15c6ba29 12838 ssl->options.side);
Vanger 0:b86d15c6ba29 12839 }
Vanger 0:b86d15c6ba29 12840
Vanger 0:b86d15c6ba29 12841 /* random */
Vanger 0:b86d15c6ba29 12842 XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
Vanger 0:b86d15c6ba29 12843 i += RAN_LEN;
Vanger 0:b86d15c6ba29 12844
Vanger 0:b86d15c6ba29 12845 #ifdef SHOW_SECRETS
Vanger 0:b86d15c6ba29 12846 {
Vanger 0:b86d15c6ba29 12847 int j;
Vanger 0:b86d15c6ba29 12848 printf("client random: ");
Vanger 0:b86d15c6ba29 12849 for (j = 0; j < RAN_LEN; j++)
Vanger 0:b86d15c6ba29 12850 printf("%02x", ssl->arrays->clientRandom[j]);
Vanger 0:b86d15c6ba29 12851 printf("\n");
Vanger 0:b86d15c6ba29 12852 }
Vanger 0:b86d15c6ba29 12853 #endif
Vanger 0:b86d15c6ba29 12854
Vanger 0:b86d15c6ba29 12855 /* session id */
Vanger 0:b86d15c6ba29 12856 b = input[i++];
Vanger 0:b86d15c6ba29 12857
Vanger 0:b86d15c6ba29 12858 if (b == ID_LEN) {
Vanger 0:b86d15c6ba29 12859 if ((i - begin) + ID_LEN > helloSz)
Vanger 0:b86d15c6ba29 12860 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12861
Vanger 0:b86d15c6ba29 12862 XMEMCPY(ssl->arrays->sessionID, input + i, ID_LEN);
Vanger 0:b86d15c6ba29 12863 i += ID_LEN;
Vanger 0:b86d15c6ba29 12864 ssl->options.resuming = 1; /* client wants to resume */
Vanger 0:b86d15c6ba29 12865 CYASSL_MSG("Client wants to resume session");
Vanger 0:b86d15c6ba29 12866 }
Vanger 0:b86d15c6ba29 12867 else if (b) {
Vanger 0:b86d15c6ba29 12868 CYASSL_MSG("Invalid session ID size");
Vanger 0:b86d15c6ba29 12869 return BUFFER_ERROR; /* session ID nor 0 neither 32 bytes long */
Vanger 0:b86d15c6ba29 12870 }
Vanger 0:b86d15c6ba29 12871
Vanger 0:b86d15c6ba29 12872 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 12873 /* cookie */
Vanger 0:b86d15c6ba29 12874 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 12875
Vanger 0:b86d15c6ba29 12876 if ((i - begin) + OPAQUE8_LEN > helloSz)
Vanger 0:b86d15c6ba29 12877 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12878
Vanger 0:b86d15c6ba29 12879 b = input[i++];
Vanger 0:b86d15c6ba29 12880
Vanger 0:b86d15c6ba29 12881 if (b) {
Vanger 0:b86d15c6ba29 12882 byte cookie[MAX_COOKIE_LEN];
Vanger 0:b86d15c6ba29 12883
Vanger 0:b86d15c6ba29 12884 if (b > MAX_COOKIE_LEN)
Vanger 0:b86d15c6ba29 12885 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12886
Vanger 0:b86d15c6ba29 12887 if ((i - begin) + b > helloSz)
Vanger 0:b86d15c6ba29 12888 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12889
Vanger 0:b86d15c6ba29 12890 if (ssl->ctx->CBIOCookie == NULL) {
Vanger 0:b86d15c6ba29 12891 CYASSL_MSG("Your Cookie callback is null, please set");
Vanger 0:b86d15c6ba29 12892 return COOKIE_ERROR;
Vanger 0:b86d15c6ba29 12893 }
Vanger 0:b86d15c6ba29 12894
Vanger 0:b86d15c6ba29 12895 if ((ssl->ctx->CBIOCookie(ssl, cookie, COOKIE_SZ,
Vanger 0:b86d15c6ba29 12896 ssl->IOCB_CookieCtx) != COOKIE_SZ)
Vanger 0:b86d15c6ba29 12897 || (b != COOKIE_SZ)
Vanger 0:b86d15c6ba29 12898 || (XMEMCMP(cookie, input + i, b) != 0)) {
Vanger 0:b86d15c6ba29 12899 return COOKIE_ERROR;
Vanger 0:b86d15c6ba29 12900 }
Vanger 0:b86d15c6ba29 12901
Vanger 0:b86d15c6ba29 12902 i += b;
Vanger 0:b86d15c6ba29 12903 }
Vanger 0:b86d15c6ba29 12904 }
Vanger 0:b86d15c6ba29 12905 #endif
Vanger 0:b86d15c6ba29 12906
Vanger 0:b86d15c6ba29 12907 /* suites */
Vanger 0:b86d15c6ba29 12908 if ((i - begin) + OPAQUE16_LEN > helloSz)
Vanger 0:b86d15c6ba29 12909 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12910
Vanger 0:b86d15c6ba29 12911 ato16(&input[i], &clSuites.suiteSz);
Vanger 0:b86d15c6ba29 12912 i += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 12913
Vanger 0:b86d15c6ba29 12914 /* suites and compression length check */
Vanger 0:b86d15c6ba29 12915 if ((i - begin) + clSuites.suiteSz + OPAQUE8_LEN > helloSz)
Vanger 0:b86d15c6ba29 12916 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12917
Vanger 0:b86d15c6ba29 12918 if (clSuites.suiteSz > MAX_SUITE_SZ)
Vanger 0:b86d15c6ba29 12919 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12920
Vanger 0:b86d15c6ba29 12921 XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
Vanger 0:b86d15c6ba29 12922 i += clSuites.suiteSz;
Vanger 0:b86d15c6ba29 12923 clSuites.hashSigAlgoSz = 0;
Vanger 0:b86d15c6ba29 12924
Vanger 0:b86d15c6ba29 12925 /* compression length */
Vanger 0:b86d15c6ba29 12926 b = input[i++];
Vanger 0:b86d15c6ba29 12927
Vanger 0:b86d15c6ba29 12928 if ((i - begin) + b > helloSz)
Vanger 0:b86d15c6ba29 12929 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12930
Vanger 0:b86d15c6ba29 12931 if (ssl->options.usingCompression) {
Vanger 0:b86d15c6ba29 12932 int match = 0;
Vanger 0:b86d15c6ba29 12933
Vanger 0:b86d15c6ba29 12934 while (b--) {
Vanger 0:b86d15c6ba29 12935 byte comp = input[i++];
Vanger 0:b86d15c6ba29 12936
Vanger 0:b86d15c6ba29 12937 if (comp == ZLIB_COMPRESSION)
Vanger 0:b86d15c6ba29 12938 match = 1;
Vanger 0:b86d15c6ba29 12939 }
Vanger 0:b86d15c6ba29 12940
Vanger 0:b86d15c6ba29 12941 if (!match) {
Vanger 0:b86d15c6ba29 12942 CYASSL_MSG("Not matching compression, turning off");
Vanger 0:b86d15c6ba29 12943 ssl->options.usingCompression = 0; /* turn off */
Vanger 0:b86d15c6ba29 12944 }
Vanger 0:b86d15c6ba29 12945 }
Vanger 0:b86d15c6ba29 12946 else
Vanger 0:b86d15c6ba29 12947 i += b; /* ignore, since we're not on */
Vanger 0:b86d15c6ba29 12948
Vanger 0:b86d15c6ba29 12949 *inOutIdx = i;
Vanger 0:b86d15c6ba29 12950
Vanger 0:b86d15c6ba29 12951 /* tls extensions */
Vanger 0:b86d15c6ba29 12952 if ((i - begin) < helloSz) {
Vanger 0:b86d15c6ba29 12953 #ifdef HAVE_TLS_EXTENSIONS
Vanger 0:b86d15c6ba29 12954 if (TLSX_SupportExtensions(ssl)) {
Vanger 0:b86d15c6ba29 12955 int ret = 0;
Vanger 0:b86d15c6ba29 12956 #else
Vanger 0:b86d15c6ba29 12957 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 12958 #endif
Vanger 0:b86d15c6ba29 12959 /* Process the hello extension. Skip unsupported. */
Vanger 0:b86d15c6ba29 12960 word16 totalExtSz;
Vanger 0:b86d15c6ba29 12961
Vanger 0:b86d15c6ba29 12962 if ((i - begin) + OPAQUE16_LEN > helloSz)
Vanger 0:b86d15c6ba29 12963 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12964
Vanger 0:b86d15c6ba29 12965 ato16(&input[i], &totalExtSz);
Vanger 0:b86d15c6ba29 12966 i += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 12967
Vanger 0:b86d15c6ba29 12968 if ((i - begin) + totalExtSz > helloSz)
Vanger 0:b86d15c6ba29 12969 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12970
Vanger 0:b86d15c6ba29 12971 #ifdef HAVE_TLS_EXTENSIONS
Vanger 0:b86d15c6ba29 12972 if ((ret = TLSX_Parse(ssl, (byte *) input + i,
Vanger 0:b86d15c6ba29 12973 totalExtSz, 1, &clSuites)))
Vanger 0:b86d15c6ba29 12974 return ret;
Vanger 0:b86d15c6ba29 12975
Vanger 0:b86d15c6ba29 12976 i += totalExtSz;
Vanger 0:b86d15c6ba29 12977 #else
Vanger 0:b86d15c6ba29 12978 while (totalExtSz) {
Vanger 0:b86d15c6ba29 12979 word16 extId, extSz;
Vanger 0:b86d15c6ba29 12980
Vanger 0:b86d15c6ba29 12981 if (OPAQUE16_LEN + OPAQUE16_LEN > totalExtSz)
Vanger 0:b86d15c6ba29 12982 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12983
Vanger 0:b86d15c6ba29 12984 ato16(&input[i], &extId);
Vanger 0:b86d15c6ba29 12985 i += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 12986 ato16(&input[i], &extSz);
Vanger 0:b86d15c6ba29 12987 i += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 12988
Vanger 0:b86d15c6ba29 12989 if (OPAQUE16_LEN + OPAQUE16_LEN + extSz > totalExtSz)
Vanger 0:b86d15c6ba29 12990 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12991
Vanger 0:b86d15c6ba29 12992 if (extId == HELLO_EXT_SIG_ALGO) {
Vanger 0:b86d15c6ba29 12993 ato16(&input[i], &clSuites.hashSigAlgoSz);
Vanger 0:b86d15c6ba29 12994 i += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 12995
Vanger 0:b86d15c6ba29 12996 if (OPAQUE16_LEN + clSuites.hashSigAlgoSz > extSz)
Vanger 0:b86d15c6ba29 12997 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 12998
Vanger 0:b86d15c6ba29 12999 XMEMCPY(clSuites.hashSigAlgo, &input[i],
Vanger 0:b86d15c6ba29 13000 min(clSuites.hashSigAlgoSz, HELLO_EXT_SIGALGO_MAX));
Vanger 0:b86d15c6ba29 13001 i += clSuites.hashSigAlgoSz;
Vanger 0:b86d15c6ba29 13002
Vanger 0:b86d15c6ba29 13003 if (clSuites.hashSigAlgoSz > HELLO_EXT_SIGALGO_MAX)
Vanger 0:b86d15c6ba29 13004 clSuites.hashSigAlgoSz = HELLO_EXT_SIGALGO_MAX;
Vanger 0:b86d15c6ba29 13005 }
Vanger 0:b86d15c6ba29 13006 else
Vanger 0:b86d15c6ba29 13007 i += extSz;
Vanger 0:b86d15c6ba29 13008
Vanger 0:b86d15c6ba29 13009 totalExtSz -= OPAQUE16_LEN + OPAQUE16_LEN + extSz;
Vanger 0:b86d15c6ba29 13010 }
Vanger 0:b86d15c6ba29 13011 #endif
Vanger 0:b86d15c6ba29 13012 *inOutIdx = i;
Vanger 0:b86d15c6ba29 13013 }
Vanger 0:b86d15c6ba29 13014 else
Vanger 0:b86d15c6ba29 13015 *inOutIdx = begin + helloSz; /* skip extensions */
Vanger 0:b86d15c6ba29 13016 }
Vanger 0:b86d15c6ba29 13017
Vanger 0:b86d15c6ba29 13018 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
Vanger 0:b86d15c6ba29 13019 ssl->options.haveSessionId = 1;
Vanger 0:b86d15c6ba29 13020
Vanger 0:b86d15c6ba29 13021 /* ProcessOld uses same resume code */
Vanger 0:b86d15c6ba29 13022 if (ssl->options.resuming && (!ssl->options.dtls ||
Vanger 0:b86d15c6ba29 13023 ssl->options.acceptState == HELLO_VERIFY_SENT)) { /* let's try */
Vanger 0:b86d15c6ba29 13024 int ret = -1;
Vanger 0:b86d15c6ba29 13025 CYASSL_SESSION* session = GetSession(ssl,ssl->arrays->masterSecret);
Vanger 0:b86d15c6ba29 13026
Vanger 0:b86d15c6ba29 13027 if (!session) {
Vanger 0:b86d15c6ba29 13028 CYASSL_MSG("Session lookup for resume failed");
Vanger 0:b86d15c6ba29 13029 ssl->options.resuming = 0;
Vanger 0:b86d15c6ba29 13030 }
Vanger 0:b86d15c6ba29 13031 else {
Vanger 0:b86d15c6ba29 13032 if (MatchSuite(ssl, &clSuites) < 0) {
Vanger 0:b86d15c6ba29 13033 CYASSL_MSG("Unsupported cipher suite, ClientHello");
Vanger 0:b86d15c6ba29 13034 return UNSUPPORTED_SUITE;
Vanger 0:b86d15c6ba29 13035 }
Vanger 0:b86d15c6ba29 13036 #ifdef SESSION_CERTS
Vanger 0:b86d15c6ba29 13037 ssl->session = *session; /* restore session certs. */
Vanger 0:b86d15c6ba29 13038 #endif
Vanger 0:b86d15c6ba29 13039
Vanger 0:b86d15c6ba29 13040 ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
Vanger 0:b86d15c6ba29 13041 RAN_LEN);
Vanger 0:b86d15c6ba29 13042 if (ret != 0)
Vanger 0:b86d15c6ba29 13043 return ret;
Vanger 0:b86d15c6ba29 13044
Vanger 0:b86d15c6ba29 13045 #ifdef NO_OLD_TLS
Vanger 0:b86d15c6ba29 13046 ret = DeriveTlsKeys(ssl);
Vanger 0:b86d15c6ba29 13047 #else
Vanger 0:b86d15c6ba29 13048 #ifndef NO_TLS
Vanger 0:b86d15c6ba29 13049 if (ssl->options.tls)
Vanger 0:b86d15c6ba29 13050 ret = DeriveTlsKeys(ssl);
Vanger 0:b86d15c6ba29 13051 #endif
Vanger 0:b86d15c6ba29 13052 if (!ssl->options.tls)
Vanger 0:b86d15c6ba29 13053 ret = DeriveKeys(ssl);
Vanger 0:b86d15c6ba29 13054 #endif
Vanger 0:b86d15c6ba29 13055 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
Vanger 0:b86d15c6ba29 13056
Vanger 0:b86d15c6ba29 13057 return ret;
Vanger 0:b86d15c6ba29 13058 }
Vanger 0:b86d15c6ba29 13059 }
Vanger 0:b86d15c6ba29 13060 return MatchSuite(ssl, &clSuites);
Vanger 0:b86d15c6ba29 13061 }
Vanger 0:b86d15c6ba29 13062
Vanger 0:b86d15c6ba29 13063 #if !defined(NO_RSA) || defined(HAVE_ECC)
Vanger 0:b86d15c6ba29 13064 static int DoCertificateVerify(CYASSL* ssl, byte* input, word32* inOutIdx,
Vanger 0:b86d15c6ba29 13065 word32 size)
Vanger 0:b86d15c6ba29 13066 {
Vanger 0:b86d15c6ba29 13067 word16 sz = 0;
Vanger 0:b86d15c6ba29 13068 int ret = VERIFY_CERT_ERROR; /* start in error state */
Vanger 0:b86d15c6ba29 13069 byte hashAlgo = sha_mac;
Vanger 0:b86d15c6ba29 13070 byte sigAlgo = anonymous_sa_algo;
Vanger 0:b86d15c6ba29 13071 word32 begin = *inOutIdx;
Vanger 0:b86d15c6ba29 13072
Vanger 0:b86d15c6ba29 13073 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 13074 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 13075 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 13076 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 13077 AddLateName("CertificateVerify", &ssl->timeoutInfo);
Vanger 0:b86d15c6ba29 13078 #endif
Vanger 0:b86d15c6ba29 13079
Vanger 0:b86d15c6ba29 13080
Vanger 0:b86d15c6ba29 13081 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 13082 if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size)
Vanger 0:b86d15c6ba29 13083 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13084
Vanger 0:b86d15c6ba29 13085 hashAlgo = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 13086 sigAlgo = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 13087 }
Vanger 0:b86d15c6ba29 13088
Vanger 0:b86d15c6ba29 13089 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 13090 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13091
Vanger 0:b86d15c6ba29 13092 ato16(input + *inOutIdx, &sz);
Vanger 0:b86d15c6ba29 13093 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 13094
Vanger 0:b86d15c6ba29 13095 if ((*inOutIdx - begin) + sz > size || sz > ENCRYPT_LEN)
Vanger 0:b86d15c6ba29 13096 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13097
Vanger 0:b86d15c6ba29 13098 /* RSA */
Vanger 0:b86d15c6ba29 13099 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 13100 if (ssl->peerRsaKeyPresent != 0) {
Vanger 0:b86d15c6ba29 13101 byte* out = NULL;
Vanger 0:b86d15c6ba29 13102 int outLen = 0;
Vanger 0:b86d15c6ba29 13103 byte doUserRsa = 0;
Vanger 0:b86d15c6ba29 13104
Vanger 0:b86d15c6ba29 13105 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 13106 if (ssl->ctx->RsaVerifyCb)
Vanger 0:b86d15c6ba29 13107 doUserRsa = 1;
Vanger 0:b86d15c6ba29 13108 #endif /*HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 13109
Vanger 0:b86d15c6ba29 13110 CYASSL_MSG("Doing RSA peer cert verify");
Vanger 0:b86d15c6ba29 13111
Vanger 0:b86d15c6ba29 13112 if (doUserRsa) {
Vanger 0:b86d15c6ba29 13113 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 13114 outLen = ssl->ctx->RsaVerifyCb(ssl, input + *inOutIdx, sz,
Vanger 0:b86d15c6ba29 13115 &out,
Vanger 0:b86d15c6ba29 13116 ssl->buffers.peerRsaKey.buffer,
Vanger 0:b86d15c6ba29 13117 ssl->buffers.peerRsaKey.length,
Vanger 0:b86d15c6ba29 13118 ssl->RsaVerifyCtx);
Vanger 0:b86d15c6ba29 13119 #endif /*HAVE_PK_CALLBACKS */
Vanger 0:b86d15c6ba29 13120 }
Vanger 0:b86d15c6ba29 13121 else {
Vanger 0:b86d15c6ba29 13122 outLen = RsaSSL_VerifyInline(input + *inOutIdx, sz, &out,
Vanger 0:b86d15c6ba29 13123 ssl->peerRsaKey);
Vanger 0:b86d15c6ba29 13124 }
Vanger 0:b86d15c6ba29 13125
Vanger 0:b86d15c6ba29 13126 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 13127 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 13128 byte* encodedSig = NULL;
Vanger 0:b86d15c6ba29 13129 #else
Vanger 0:b86d15c6ba29 13130 byte encodedSig[MAX_ENCODED_SIG_SZ];
Vanger 0:b86d15c6ba29 13131 #endif
Vanger 0:b86d15c6ba29 13132 word32 sigSz;
Vanger 0:b86d15c6ba29 13133 byte* digest = ssl->certHashes.sha;
Vanger 0:b86d15c6ba29 13134 int typeH = SHAh;
Vanger 0:b86d15c6ba29 13135 int digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 13136
Vanger 0:b86d15c6ba29 13137 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 13138 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
Vanger 0:b86d15c6ba29 13139 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 13140 if (encodedSig == NULL)
Vanger 0:b86d15c6ba29 13141 return MEMORY_E;
Vanger 0:b86d15c6ba29 13142 #endif
Vanger 0:b86d15c6ba29 13143
Vanger 0:b86d15c6ba29 13144 if (sigAlgo != rsa_sa_algo) {
Vanger 0:b86d15c6ba29 13145 CYASSL_MSG("Oops, peer sent RSA key but not in verify");
Vanger 0:b86d15c6ba29 13146 }
Vanger 0:b86d15c6ba29 13147
Vanger 0:b86d15c6ba29 13148 if (hashAlgo == sha256_mac) {
Vanger 0:b86d15c6ba29 13149 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 13150 digest = ssl->certHashes.sha256;
Vanger 0:b86d15c6ba29 13151 typeH = SHA256h;
Vanger 0:b86d15c6ba29 13152 digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 13153 #endif
Vanger 0:b86d15c6ba29 13154 }
Vanger 0:b86d15c6ba29 13155 else if (hashAlgo == sha384_mac) {
Vanger 0:b86d15c6ba29 13156 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 13157 digest = ssl->certHashes.sha384;
Vanger 0:b86d15c6ba29 13158 typeH = SHA384h;
Vanger 0:b86d15c6ba29 13159 digestSz = SHA384_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 13160 #endif
Vanger 0:b86d15c6ba29 13161 }
Vanger 0:b86d15c6ba29 13162
Vanger 0:b86d15c6ba29 13163 sigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
Vanger 0:b86d15c6ba29 13164
Vanger 0:b86d15c6ba29 13165 if (outLen == (int)sigSz && out && XMEMCMP(out, encodedSig,
Vanger 0:b86d15c6ba29 13166 min(sigSz, MAX_ENCODED_SIG_SZ)) == 0)
Vanger 0:b86d15c6ba29 13167 ret = 0; /* verified */
Vanger 0:b86d15c6ba29 13168
Vanger 0:b86d15c6ba29 13169 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 13170 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 13171 #endif
Vanger 0:b86d15c6ba29 13172 }
Vanger 0:b86d15c6ba29 13173 else {
Vanger 0:b86d15c6ba29 13174 if (outLen == FINISHED_SZ && out && XMEMCMP(out,
Vanger 0:b86d15c6ba29 13175 &ssl->certHashes, FINISHED_SZ) == 0)
Vanger 0:b86d15c6ba29 13176 ret = 0; /* verified */
Vanger 0:b86d15c6ba29 13177 }
Vanger 0:b86d15c6ba29 13178 }
Vanger 0:b86d15c6ba29 13179 #endif
Vanger 0:b86d15c6ba29 13180 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 13181 if (ssl->peerEccDsaKeyPresent) {
Vanger 0:b86d15c6ba29 13182 int verify = 0;
Vanger 0:b86d15c6ba29 13183 int err = -1;
Vanger 0:b86d15c6ba29 13184 byte* digest = ssl->certHashes.sha;
Vanger 0:b86d15c6ba29 13185 word32 digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 13186 byte doUserEcc = 0;
Vanger 0:b86d15c6ba29 13187
Vanger 0:b86d15c6ba29 13188 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 13189 if (ssl->ctx->EccVerifyCb)
Vanger 0:b86d15c6ba29 13190 doUserEcc = 1;
Vanger 0:b86d15c6ba29 13191 #endif
Vanger 0:b86d15c6ba29 13192
Vanger 0:b86d15c6ba29 13193 CYASSL_MSG("Doing ECC peer cert verify");
Vanger 0:b86d15c6ba29 13194
Vanger 0:b86d15c6ba29 13195 if (IsAtLeastTLSv1_2(ssl)) {
Vanger 0:b86d15c6ba29 13196 if (sigAlgo != ecc_dsa_sa_algo) {
Vanger 0:b86d15c6ba29 13197 CYASSL_MSG("Oops, peer sent ECC key but not in verify");
Vanger 0:b86d15c6ba29 13198 }
Vanger 0:b86d15c6ba29 13199
Vanger 0:b86d15c6ba29 13200 if (hashAlgo == sha256_mac) {
Vanger 0:b86d15c6ba29 13201 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 13202 digest = ssl->certHashes.sha256;
Vanger 0:b86d15c6ba29 13203 digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 13204 #endif
Vanger 0:b86d15c6ba29 13205 }
Vanger 0:b86d15c6ba29 13206 else if (hashAlgo == sha384_mac) {
Vanger 0:b86d15c6ba29 13207 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 13208 digest = ssl->certHashes.sha384;
Vanger 0:b86d15c6ba29 13209 digestSz = SHA384_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 13210 #endif
Vanger 0:b86d15c6ba29 13211 }
Vanger 0:b86d15c6ba29 13212 }
Vanger 0:b86d15c6ba29 13213
Vanger 0:b86d15c6ba29 13214 if (doUserEcc) {
Vanger 0:b86d15c6ba29 13215 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 13216 ret = ssl->ctx->EccVerifyCb(ssl, input + *inOutIdx, sz, digest,
Vanger 0:b86d15c6ba29 13217 digestSz,
Vanger 0:b86d15c6ba29 13218 ssl->buffers.peerEccDsaKey.buffer,
Vanger 0:b86d15c6ba29 13219 ssl->buffers.peerEccDsaKey.length,
Vanger 0:b86d15c6ba29 13220 &verify, ssl->EccVerifyCtx);
Vanger 0:b86d15c6ba29 13221 #endif
Vanger 0:b86d15c6ba29 13222 }
Vanger 0:b86d15c6ba29 13223 else {
Vanger 0:b86d15c6ba29 13224 err = ecc_verify_hash(input + *inOutIdx, sz, digest, digestSz,
Vanger 0:b86d15c6ba29 13225 &verify, ssl->peerEccDsaKey);
Vanger 0:b86d15c6ba29 13226 }
Vanger 0:b86d15c6ba29 13227
Vanger 0:b86d15c6ba29 13228 if (err == 0 && verify == 1)
Vanger 0:b86d15c6ba29 13229 ret = 0; /* verified */
Vanger 0:b86d15c6ba29 13230 }
Vanger 0:b86d15c6ba29 13231 #endif
Vanger 0:b86d15c6ba29 13232 *inOutIdx += sz;
Vanger 0:b86d15c6ba29 13233
Vanger 0:b86d15c6ba29 13234 if (ret == 0)
Vanger 0:b86d15c6ba29 13235 ssl->options.havePeerVerify = 1;
Vanger 0:b86d15c6ba29 13236
Vanger 0:b86d15c6ba29 13237 return ret;
Vanger 0:b86d15c6ba29 13238 }
Vanger 0:b86d15c6ba29 13239 #endif /* !NO_RSA || HAVE_ECC */
Vanger 0:b86d15c6ba29 13240
Vanger 0:b86d15c6ba29 13241 int SendServerHelloDone(CYASSL* ssl)
Vanger 0:b86d15c6ba29 13242 {
Vanger 0:b86d15c6ba29 13243 byte *output;
Vanger 0:b86d15c6ba29 13244 int sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 13245 int ret;
Vanger 0:b86d15c6ba29 13246
Vanger 0:b86d15c6ba29 13247 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 13248 if (ssl->options.dtls)
Vanger 0:b86d15c6ba29 13249 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
Vanger 0:b86d15c6ba29 13250 #endif
Vanger 0:b86d15c6ba29 13251 /* check for available size */
Vanger 0:b86d15c6ba29 13252 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
Vanger 0:b86d15c6ba29 13253 return ret;
Vanger 0:b86d15c6ba29 13254
Vanger 0:b86d15c6ba29 13255 /* get ouput buffer */
Vanger 0:b86d15c6ba29 13256 output = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 13257 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 13258
Vanger 0:b86d15c6ba29 13259 AddHeaders(output, 0, server_hello_done, ssl);
Vanger 0:b86d15c6ba29 13260
Vanger 0:b86d15c6ba29 13261 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 13262 if (ssl->options.dtls) {
Vanger 0:b86d15c6ba29 13263 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
Vanger 0:b86d15c6ba29 13264 return 0;
Vanger 0:b86d15c6ba29 13265 }
Vanger 0:b86d15c6ba29 13266 #endif
Vanger 0:b86d15c6ba29 13267
Vanger 0:b86d15c6ba29 13268 ret = HashOutput(ssl, output, sendSz, 0);
Vanger 0:b86d15c6ba29 13269 if (ret != 0)
Vanger 0:b86d15c6ba29 13270 return ret;
Vanger 0:b86d15c6ba29 13271
Vanger 0:b86d15c6ba29 13272 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 13273 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 13274 AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 13275 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 13276 AddPacketInfo("ServerHelloDone", &ssl->timeoutInfo, output, sendSz,
Vanger 0:b86d15c6ba29 13277 ssl->heap);
Vanger 0:b86d15c6ba29 13278 #endif
Vanger 0:b86d15c6ba29 13279 ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
Vanger 0:b86d15c6ba29 13280
Vanger 0:b86d15c6ba29 13281 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 13282
Vanger 0:b86d15c6ba29 13283 return SendBuffered(ssl);
Vanger 0:b86d15c6ba29 13284 }
Vanger 0:b86d15c6ba29 13285
Vanger 0:b86d15c6ba29 13286 #ifdef CYASSL_DTLS
Vanger 0:b86d15c6ba29 13287 int SendHelloVerifyRequest(CYASSL* ssl)
Vanger 0:b86d15c6ba29 13288 {
Vanger 0:b86d15c6ba29 13289 byte* output;
Vanger 0:b86d15c6ba29 13290 byte cookieSz = COOKIE_SZ;
Vanger 0:b86d15c6ba29 13291 int length = VERSION_SZ + ENUM_LEN + cookieSz;
Vanger 0:b86d15c6ba29 13292 int idx = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
Vanger 0:b86d15c6ba29 13293 int sendSz = length + idx;
Vanger 0:b86d15c6ba29 13294 int ret;
Vanger 0:b86d15c6ba29 13295
Vanger 0:b86d15c6ba29 13296 /* check for available size */
Vanger 0:b86d15c6ba29 13297 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
Vanger 0:b86d15c6ba29 13298 return ret;
Vanger 0:b86d15c6ba29 13299
Vanger 0:b86d15c6ba29 13300 /* get ouput buffer */
Vanger 0:b86d15c6ba29 13301 output = ssl->buffers.outputBuffer.buffer +
Vanger 0:b86d15c6ba29 13302 ssl->buffers.outputBuffer.length;
Vanger 0:b86d15c6ba29 13303
Vanger 0:b86d15c6ba29 13304 AddHeaders(output, length, hello_verify_request, ssl);
Vanger 0:b86d15c6ba29 13305
Vanger 0:b86d15c6ba29 13306 output[idx++] = ssl->chVersion.major;
Vanger 0:b86d15c6ba29 13307 output[idx++] = ssl->chVersion.minor;
Vanger 0:b86d15c6ba29 13308
Vanger 0:b86d15c6ba29 13309 output[idx++] = cookieSz;
Vanger 0:b86d15c6ba29 13310 if (ssl->ctx->CBIOCookie == NULL) {
Vanger 0:b86d15c6ba29 13311 CYASSL_MSG("Your Cookie callback is null, please set");
Vanger 0:b86d15c6ba29 13312 return COOKIE_ERROR;
Vanger 0:b86d15c6ba29 13313 }
Vanger 0:b86d15c6ba29 13314 if ((ret = ssl->ctx->CBIOCookie(ssl, output + idx, cookieSz,
Vanger 0:b86d15c6ba29 13315 ssl->IOCB_CookieCtx)) < 0)
Vanger 0:b86d15c6ba29 13316 return ret;
Vanger 0:b86d15c6ba29 13317
Vanger 0:b86d15c6ba29 13318 ret = HashOutput(ssl, output, sendSz, 0);
Vanger 0:b86d15c6ba29 13319 if (ret != 0)
Vanger 0:b86d15c6ba29 13320 return ret;
Vanger 0:b86d15c6ba29 13321
Vanger 0:b86d15c6ba29 13322 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 13323 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 13324 AddPacketName("HelloVerifyRequest", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 13325 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 13326 AddPacketInfo("HelloVerifyRequest", &ssl->timeoutInfo, output,
Vanger 0:b86d15c6ba29 13327 sendSz, ssl->heap);
Vanger 0:b86d15c6ba29 13328 #endif
Vanger 0:b86d15c6ba29 13329 ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
Vanger 0:b86d15c6ba29 13330
Vanger 0:b86d15c6ba29 13331 ssl->buffers.outputBuffer.length += sendSz;
Vanger 0:b86d15c6ba29 13332
Vanger 0:b86d15c6ba29 13333 return SendBuffered(ssl);
Vanger 0:b86d15c6ba29 13334 }
Vanger 0:b86d15c6ba29 13335 #endif
Vanger 0:b86d15c6ba29 13336
Vanger 0:b86d15c6ba29 13337 static int DoClientKeyExchange(CYASSL* ssl, byte* input, word32* inOutIdx,
Vanger 0:b86d15c6ba29 13338 word32 size)
Vanger 0:b86d15c6ba29 13339 {
Vanger 0:b86d15c6ba29 13340 int ret = 0;
Vanger 0:b86d15c6ba29 13341 word32 length = 0;
Vanger 0:b86d15c6ba29 13342 byte* out = NULL;
Vanger 0:b86d15c6ba29 13343 word32 begin = *inOutIdx;
Vanger 0:b86d15c6ba29 13344
Vanger 0:b86d15c6ba29 13345 (void)length; /* shut up compiler warnings */
Vanger 0:b86d15c6ba29 13346 (void)out;
Vanger 0:b86d15c6ba29 13347 (void)input;
Vanger 0:b86d15c6ba29 13348 (void)size;
Vanger 0:b86d15c6ba29 13349 (void)begin;
Vanger 0:b86d15c6ba29 13350
Vanger 0:b86d15c6ba29 13351 if (ssl->options.side != CYASSL_SERVER_END) {
Vanger 0:b86d15c6ba29 13352 CYASSL_MSG("Client received client keyexchange, attack?");
Vanger 0:b86d15c6ba29 13353 CYASSL_ERROR(ssl->error = SIDE_ERROR);
Vanger 0:b86d15c6ba29 13354 return SSL_FATAL_ERROR;
Vanger 0:b86d15c6ba29 13355 }
Vanger 0:b86d15c6ba29 13356
Vanger 0:b86d15c6ba29 13357 if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
Vanger 0:b86d15c6ba29 13358 CYASSL_MSG("Client sending keyexchange at wrong time");
Vanger 0:b86d15c6ba29 13359 SendAlert(ssl, alert_fatal, unexpected_message);
Vanger 0:b86d15c6ba29 13360 return OUT_OF_ORDER_E;
Vanger 0:b86d15c6ba29 13361 }
Vanger 0:b86d15c6ba29 13362
Vanger 0:b86d15c6ba29 13363 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 13364 if (ssl->options.verifyPeer && ssl->options.failNoCert)
Vanger 0:b86d15c6ba29 13365 if (!ssl->options.havePeerCert) {
Vanger 0:b86d15c6ba29 13366 CYASSL_MSG("client didn't present peer cert");
Vanger 0:b86d15c6ba29 13367 return NO_PEER_CERT;
Vanger 0:b86d15c6ba29 13368 }
Vanger 0:b86d15c6ba29 13369 #endif
Vanger 0:b86d15c6ba29 13370
Vanger 0:b86d15c6ba29 13371 #ifdef CYASSL_CALLBACKS
Vanger 0:b86d15c6ba29 13372 if (ssl->hsInfoOn)
Vanger 0:b86d15c6ba29 13373 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
Vanger 0:b86d15c6ba29 13374 if (ssl->toInfoOn)
Vanger 0:b86d15c6ba29 13375 AddLateName("ClientKeyExchange", &ssl->timeoutInfo);
Vanger 0:b86d15c6ba29 13376 #endif
Vanger 0:b86d15c6ba29 13377
Vanger 0:b86d15c6ba29 13378 switch (ssl->specs.kea) {
Vanger 0:b86d15c6ba29 13379 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 13380 case rsa_kea:
Vanger 0:b86d15c6ba29 13381 {
Vanger 0:b86d15c6ba29 13382 word32 idx = 0;
Vanger 0:b86d15c6ba29 13383 RsaKey key;
Vanger 0:b86d15c6ba29 13384 byte doUserRsa = 0;
Vanger 0:b86d15c6ba29 13385
Vanger 0:b86d15c6ba29 13386 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 13387 if (ssl->ctx->RsaDecCb)
Vanger 0:b86d15c6ba29 13388 doUserRsa = 1;
Vanger 0:b86d15c6ba29 13389 #endif
Vanger 0:b86d15c6ba29 13390
Vanger 0:b86d15c6ba29 13391 ret = InitRsaKey(&key, ssl->heap);
Vanger 0:b86d15c6ba29 13392 if (ret != 0) return ret;
Vanger 0:b86d15c6ba29 13393
Vanger 0:b86d15c6ba29 13394 if (ssl->buffers.key.buffer)
Vanger 0:b86d15c6ba29 13395 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx,
Vanger 0:b86d15c6ba29 13396 &key, ssl->buffers.key.length);
Vanger 0:b86d15c6ba29 13397 else
Vanger 0:b86d15c6ba29 13398 return NO_PRIVATE_KEY;
Vanger 0:b86d15c6ba29 13399
Vanger 0:b86d15c6ba29 13400 if (ret == 0) {
Vanger 0:b86d15c6ba29 13401 length = RsaEncryptSize(&key);
Vanger 0:b86d15c6ba29 13402 ssl->arrays->preMasterSz = SECRET_LEN;
Vanger 0:b86d15c6ba29 13403
Vanger 0:b86d15c6ba29 13404 if (ssl->options.tls) {
Vanger 0:b86d15c6ba29 13405 word16 check;
Vanger 0:b86d15c6ba29 13406
Vanger 0:b86d15c6ba29 13407 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 13408 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13409
Vanger 0:b86d15c6ba29 13410 ato16(input + *inOutIdx, &check);
Vanger 0:b86d15c6ba29 13411 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 13412
Vanger 0:b86d15c6ba29 13413 if ((word32) check != length) {
Vanger 0:b86d15c6ba29 13414 CYASSL_MSG("RSA explicit size doesn't match");
Vanger 0:b86d15c6ba29 13415 FreeRsaKey(&key);
Vanger 0:b86d15c6ba29 13416 return RSA_PRIVATE_ERROR;
Vanger 0:b86d15c6ba29 13417 }
Vanger 0:b86d15c6ba29 13418 }
Vanger 0:b86d15c6ba29 13419
Vanger 0:b86d15c6ba29 13420 if ((*inOutIdx - begin) + length > size) {
Vanger 0:b86d15c6ba29 13421 CYASSL_MSG("RSA message too big");
Vanger 0:b86d15c6ba29 13422 FreeRsaKey(&key);
Vanger 0:b86d15c6ba29 13423 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13424 }
Vanger 0:b86d15c6ba29 13425
Vanger 0:b86d15c6ba29 13426 if (doUserRsa) {
Vanger 0:b86d15c6ba29 13427 #ifdef HAVE_PK_CALLBACKS
Vanger 0:b86d15c6ba29 13428 ret = ssl->ctx->RsaDecCb(ssl,
Vanger 0:b86d15c6ba29 13429 input + *inOutIdx, length, &out,
Vanger 0:b86d15c6ba29 13430 ssl->buffers.key.buffer,
Vanger 0:b86d15c6ba29 13431 ssl->buffers.key.length,
Vanger 0:b86d15c6ba29 13432 ssl->RsaDecCtx);
Vanger 0:b86d15c6ba29 13433 #endif
Vanger 0:b86d15c6ba29 13434 }
Vanger 0:b86d15c6ba29 13435 else {
Vanger 0:b86d15c6ba29 13436 ret = RsaPrivateDecryptInline(input + *inOutIdx, length,
Vanger 0:b86d15c6ba29 13437 &out, &key);
Vanger 0:b86d15c6ba29 13438 }
Vanger 0:b86d15c6ba29 13439
Vanger 0:b86d15c6ba29 13440 *inOutIdx += length;
Vanger 0:b86d15c6ba29 13441
Vanger 0:b86d15c6ba29 13442 if (ret == SECRET_LEN) {
Vanger 0:b86d15c6ba29 13443 XMEMCPY(ssl->arrays->preMasterSecret, out, SECRET_LEN);
Vanger 0:b86d15c6ba29 13444 if (ssl->arrays->preMasterSecret[0] !=
Vanger 0:b86d15c6ba29 13445 ssl->chVersion.major
Vanger 0:b86d15c6ba29 13446 || ssl->arrays->preMasterSecret[1] !=
Vanger 0:b86d15c6ba29 13447 ssl->chVersion.minor)
Vanger 0:b86d15c6ba29 13448 ret = PMS_VERSION_ERROR;
Vanger 0:b86d15c6ba29 13449 else
Vanger 0:b86d15c6ba29 13450 ret = MakeMasterSecret(ssl);
Vanger 0:b86d15c6ba29 13451 }
Vanger 0:b86d15c6ba29 13452 else {
Vanger 0:b86d15c6ba29 13453 ret = RSA_PRIVATE_ERROR;
Vanger 0:b86d15c6ba29 13454 }
Vanger 0:b86d15c6ba29 13455 }
Vanger 0:b86d15c6ba29 13456
Vanger 0:b86d15c6ba29 13457 FreeRsaKey(&key);
Vanger 0:b86d15c6ba29 13458 }
Vanger 0:b86d15c6ba29 13459 break;
Vanger 0:b86d15c6ba29 13460 #endif
Vanger 0:b86d15c6ba29 13461 #ifndef NO_PSK
Vanger 0:b86d15c6ba29 13462 case psk_kea:
Vanger 0:b86d15c6ba29 13463 {
Vanger 0:b86d15c6ba29 13464 byte* pms = ssl->arrays->preMasterSecret;
Vanger 0:b86d15c6ba29 13465 word16 ci_sz;
Vanger 0:b86d15c6ba29 13466
Vanger 0:b86d15c6ba29 13467 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 13468 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13469
Vanger 0:b86d15c6ba29 13470 ato16(input + *inOutIdx, &ci_sz);
Vanger 0:b86d15c6ba29 13471 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 13472
Vanger 0:b86d15c6ba29 13473 if (ci_sz > MAX_PSK_ID_LEN)
Vanger 0:b86d15c6ba29 13474 return CLIENT_ID_ERROR;
Vanger 0:b86d15c6ba29 13475
Vanger 0:b86d15c6ba29 13476 if ((*inOutIdx - begin) + ci_sz > size)
Vanger 0:b86d15c6ba29 13477 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13478
Vanger 0:b86d15c6ba29 13479 XMEMCPY(ssl->arrays->client_identity, input + *inOutIdx, ci_sz);
Vanger 0:b86d15c6ba29 13480 *inOutIdx += ci_sz;
Vanger 0:b86d15c6ba29 13481
Vanger 0:b86d15c6ba29 13482 ssl->arrays->client_identity[min(ci_sz, MAX_PSK_ID_LEN-1)] = 0;
Vanger 0:b86d15c6ba29 13483 ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
Vanger 0:b86d15c6ba29 13484 ssl->arrays->client_identity, ssl->arrays->psk_key,
Vanger 0:b86d15c6ba29 13485 MAX_PSK_KEY_LEN);
Vanger 0:b86d15c6ba29 13486
Vanger 0:b86d15c6ba29 13487 if (ssl->arrays->psk_keySz == 0 ||
Vanger 0:b86d15c6ba29 13488 ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
Vanger 0:b86d15c6ba29 13489 return PSK_KEY_ERROR;
Vanger 0:b86d15c6ba29 13490
Vanger 0:b86d15c6ba29 13491 /* make psk pre master secret */
Vanger 0:b86d15c6ba29 13492 /* length of key + length 0s + length of key + key */
Vanger 0:b86d15c6ba29 13493 c16toa((word16) ssl->arrays->psk_keySz, pms);
Vanger 0:b86d15c6ba29 13494 pms += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 13495
Vanger 0:b86d15c6ba29 13496 XMEMSET(pms, 0, ssl->arrays->psk_keySz);
Vanger 0:b86d15c6ba29 13497 pms += ssl->arrays->psk_keySz;
Vanger 0:b86d15c6ba29 13498
Vanger 0:b86d15c6ba29 13499 c16toa((word16) ssl->arrays->psk_keySz, pms);
Vanger 0:b86d15c6ba29 13500 pms += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 13501
Vanger 0:b86d15c6ba29 13502 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
Vanger 0:b86d15c6ba29 13503 ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
Vanger 0:b86d15c6ba29 13504
Vanger 0:b86d15c6ba29 13505 ret = MakeMasterSecret(ssl);
Vanger 0:b86d15c6ba29 13506
Vanger 0:b86d15c6ba29 13507 /* No further need for PSK */
Vanger 0:b86d15c6ba29 13508 XMEMSET(ssl->arrays->psk_key, 0, ssl->arrays->psk_keySz);
Vanger 0:b86d15c6ba29 13509 ssl->arrays->psk_keySz = 0;
Vanger 0:b86d15c6ba29 13510 }
Vanger 0:b86d15c6ba29 13511 break;
Vanger 0:b86d15c6ba29 13512 #endif /* NO_PSK */
Vanger 0:b86d15c6ba29 13513 #ifdef HAVE_NTRU
Vanger 0:b86d15c6ba29 13514 case ntru_kea:
Vanger 0:b86d15c6ba29 13515 {
Vanger 0:b86d15c6ba29 13516 word16 cipherLen;
Vanger 0:b86d15c6ba29 13517 word16 plainLen = sizeof(ssl->arrays->preMasterSecret);
Vanger 0:b86d15c6ba29 13518
Vanger 0:b86d15c6ba29 13519 if (!ssl->buffers.key.buffer)
Vanger 0:b86d15c6ba29 13520 return NO_PRIVATE_KEY;
Vanger 0:b86d15c6ba29 13521
Vanger 0:b86d15c6ba29 13522 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 13523 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13524
Vanger 0:b86d15c6ba29 13525 ato16(input + *inOutIdx, &cipherLen);
Vanger 0:b86d15c6ba29 13526 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 13527
Vanger 0:b86d15c6ba29 13528 if (cipherLen > MAX_NTRU_ENCRYPT_SZ)
Vanger 0:b86d15c6ba29 13529 return NTRU_KEY_ERROR;
Vanger 0:b86d15c6ba29 13530
Vanger 0:b86d15c6ba29 13531 if ((*inOutIdx - begin) + cipherLen > size)
Vanger 0:b86d15c6ba29 13532 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13533
Vanger 0:b86d15c6ba29 13534 if (NTRU_OK != ntru_crypto_ntru_decrypt(
Vanger 0:b86d15c6ba29 13535 (word16) ssl->buffers.key.length,
Vanger 0:b86d15c6ba29 13536 ssl->buffers.key.buffer, cipherLen,
Vanger 0:b86d15c6ba29 13537 input + *inOutIdx, &plainLen,
Vanger 0:b86d15c6ba29 13538 ssl->arrays->preMasterSecret))
Vanger 0:b86d15c6ba29 13539 return NTRU_DECRYPT_ERROR;
Vanger 0:b86d15c6ba29 13540
Vanger 0:b86d15c6ba29 13541 if (plainLen != SECRET_LEN)
Vanger 0:b86d15c6ba29 13542 return NTRU_DECRYPT_ERROR;
Vanger 0:b86d15c6ba29 13543
Vanger 0:b86d15c6ba29 13544 *inOutIdx += cipherLen;
Vanger 0:b86d15c6ba29 13545
Vanger 0:b86d15c6ba29 13546 ssl->arrays->preMasterSz = plainLen;
Vanger 0:b86d15c6ba29 13547 ret = MakeMasterSecret(ssl);
Vanger 0:b86d15c6ba29 13548 }
Vanger 0:b86d15c6ba29 13549 break;
Vanger 0:b86d15c6ba29 13550 #endif /* HAVE_NTRU */
Vanger 0:b86d15c6ba29 13551 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 13552 case ecc_diffie_hellman_kea:
Vanger 0:b86d15c6ba29 13553 {
Vanger 0:b86d15c6ba29 13554 if ((*inOutIdx - begin) + OPAQUE8_LEN > size)
Vanger 0:b86d15c6ba29 13555 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13556
Vanger 0:b86d15c6ba29 13557 length = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 13558
Vanger 0:b86d15c6ba29 13559 if ((*inOutIdx - begin) + length > size)
Vanger 0:b86d15c6ba29 13560 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13561
Vanger 0:b86d15c6ba29 13562 if (ssl->peerEccKeyPresent) { /* don't leak on reuse */
Vanger 0:b86d15c6ba29 13563 ecc_free(ssl->peerEccKey);
Vanger 0:b86d15c6ba29 13564 ssl->peerEccKeyPresent = 0;
Vanger 0:b86d15c6ba29 13565 ecc_init(ssl->peerEccKey);
Vanger 0:b86d15c6ba29 13566 }
Vanger 0:b86d15c6ba29 13567
Vanger 0:b86d15c6ba29 13568 if (ecc_import_x963(input + *inOutIdx, length, ssl->peerEccKey))
Vanger 0:b86d15c6ba29 13569 return ECC_PEERKEY_ERROR;
Vanger 0:b86d15c6ba29 13570
Vanger 0:b86d15c6ba29 13571 *inOutIdx += length;
Vanger 0:b86d15c6ba29 13572 ssl->peerEccKeyPresent = 1;
Vanger 0:b86d15c6ba29 13573
Vanger 0:b86d15c6ba29 13574 length = sizeof(ssl->arrays->preMasterSecret);
Vanger 0:b86d15c6ba29 13575
Vanger 0:b86d15c6ba29 13576 if (ssl->specs.static_ecdh) {
Vanger 0:b86d15c6ba29 13577 ecc_key staticKey;
Vanger 0:b86d15c6ba29 13578 word32 i = 0;
Vanger 0:b86d15c6ba29 13579
Vanger 0:b86d15c6ba29 13580 ecc_init(&staticKey);
Vanger 0:b86d15c6ba29 13581 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
Vanger 0:b86d15c6ba29 13582 &staticKey, ssl->buffers.key.length);
Vanger 0:b86d15c6ba29 13583
Vanger 0:b86d15c6ba29 13584 if (ret == 0)
Vanger 0:b86d15c6ba29 13585 ret = ecc_shared_secret(&staticKey, ssl->peerEccKey,
Vanger 0:b86d15c6ba29 13586 ssl->arrays->preMasterSecret, &length);
Vanger 0:b86d15c6ba29 13587
Vanger 0:b86d15c6ba29 13588 ecc_free(&staticKey);
Vanger 0:b86d15c6ba29 13589 }
Vanger 0:b86d15c6ba29 13590 else {
Vanger 0:b86d15c6ba29 13591 if (ssl->eccTempKeyPresent == 0) {
Vanger 0:b86d15c6ba29 13592 CYASSL_MSG("Ecc ephemeral key not made correctly");
Vanger 0:b86d15c6ba29 13593 ret = ECC_MAKEKEY_ERROR;
Vanger 0:b86d15c6ba29 13594 } else {
Vanger 0:b86d15c6ba29 13595 ret = ecc_shared_secret(ssl->eccTempKey,ssl->peerEccKey,
Vanger 0:b86d15c6ba29 13596 ssl->arrays->preMasterSecret, &length);
Vanger 0:b86d15c6ba29 13597 }
Vanger 0:b86d15c6ba29 13598 }
Vanger 0:b86d15c6ba29 13599
Vanger 0:b86d15c6ba29 13600 if (ret != 0)
Vanger 0:b86d15c6ba29 13601 return ECC_SHARED_ERROR;
Vanger 0:b86d15c6ba29 13602
Vanger 0:b86d15c6ba29 13603 ssl->arrays->preMasterSz = length;
Vanger 0:b86d15c6ba29 13604 ret = MakeMasterSecret(ssl);
Vanger 0:b86d15c6ba29 13605 }
Vanger 0:b86d15c6ba29 13606 break;
Vanger 0:b86d15c6ba29 13607 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 13608 #ifndef NO_DH
Vanger 0:b86d15c6ba29 13609 case diffie_hellman_kea:
Vanger 0:b86d15c6ba29 13610 {
Vanger 0:b86d15c6ba29 13611 word16 clientPubSz;
Vanger 0:b86d15c6ba29 13612 DhKey dhKey;
Vanger 0:b86d15c6ba29 13613
Vanger 0:b86d15c6ba29 13614 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 13615 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13616
Vanger 0:b86d15c6ba29 13617 ato16(input + *inOutIdx, &clientPubSz);
Vanger 0:b86d15c6ba29 13618 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 13619
Vanger 0:b86d15c6ba29 13620 if ((*inOutIdx - begin) + clientPubSz > size)
Vanger 0:b86d15c6ba29 13621 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13622
Vanger 0:b86d15c6ba29 13623 InitDhKey(&dhKey);
Vanger 0:b86d15c6ba29 13624 ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
Vanger 0:b86d15c6ba29 13625 ssl->buffers.serverDH_P.length,
Vanger 0:b86d15c6ba29 13626 ssl->buffers.serverDH_G.buffer,
Vanger 0:b86d15c6ba29 13627 ssl->buffers.serverDH_G.length);
Vanger 0:b86d15c6ba29 13628 if (ret == 0)
Vanger 0:b86d15c6ba29 13629 ret = DhAgree(&dhKey, ssl->arrays->preMasterSecret,
Vanger 0:b86d15c6ba29 13630 &ssl->arrays->preMasterSz,
Vanger 0:b86d15c6ba29 13631 ssl->buffers.serverDH_Priv.buffer,
Vanger 0:b86d15c6ba29 13632 ssl->buffers.serverDH_Priv.length,
Vanger 0:b86d15c6ba29 13633 input + *inOutIdx, clientPubSz);
Vanger 0:b86d15c6ba29 13634 FreeDhKey(&dhKey);
Vanger 0:b86d15c6ba29 13635
Vanger 0:b86d15c6ba29 13636 *inOutIdx += clientPubSz;
Vanger 0:b86d15c6ba29 13637
Vanger 0:b86d15c6ba29 13638 if (ret == 0)
Vanger 0:b86d15c6ba29 13639 ret = MakeMasterSecret(ssl);
Vanger 0:b86d15c6ba29 13640 }
Vanger 0:b86d15c6ba29 13641 break;
Vanger 0:b86d15c6ba29 13642 #endif /* NO_DH */
Vanger 0:b86d15c6ba29 13643 #if !defined(NO_DH) && !defined(NO_PSK)
Vanger 0:b86d15c6ba29 13644 case dhe_psk_kea:
Vanger 0:b86d15c6ba29 13645 {
Vanger 0:b86d15c6ba29 13646 byte* pms = ssl->arrays->preMasterSecret;
Vanger 0:b86d15c6ba29 13647 word16 clientSz;
Vanger 0:b86d15c6ba29 13648 DhKey dhKey;
Vanger 0:b86d15c6ba29 13649
Vanger 0:b86d15c6ba29 13650 /* Read in the PSK hint */
Vanger 0:b86d15c6ba29 13651 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 13652 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13653
Vanger 0:b86d15c6ba29 13654 ato16(input + *inOutIdx, &clientSz);
Vanger 0:b86d15c6ba29 13655 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 13656 if (clientSz > MAX_PSK_ID_LEN)
Vanger 0:b86d15c6ba29 13657 return CLIENT_ID_ERROR;
Vanger 0:b86d15c6ba29 13658
Vanger 0:b86d15c6ba29 13659 if ((*inOutIdx - begin) + clientSz > size)
Vanger 0:b86d15c6ba29 13660 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13661
Vanger 0:b86d15c6ba29 13662 XMEMCPY(ssl->arrays->client_identity,
Vanger 0:b86d15c6ba29 13663 input + *inOutIdx, clientSz);
Vanger 0:b86d15c6ba29 13664 *inOutIdx += clientSz;
Vanger 0:b86d15c6ba29 13665 ssl->arrays->client_identity[min(clientSz, MAX_PSK_ID_LEN-1)] =
Vanger 0:b86d15c6ba29 13666 0;
Vanger 0:b86d15c6ba29 13667
Vanger 0:b86d15c6ba29 13668 /* Read in the DHE business */
Vanger 0:b86d15c6ba29 13669 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
Vanger 0:b86d15c6ba29 13670 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13671
Vanger 0:b86d15c6ba29 13672 ato16(input + *inOutIdx, &clientSz);
Vanger 0:b86d15c6ba29 13673 *inOutIdx += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 13674
Vanger 0:b86d15c6ba29 13675 if ((*inOutIdx - begin) + clientSz > size)
Vanger 0:b86d15c6ba29 13676 return BUFFER_ERROR;
Vanger 0:b86d15c6ba29 13677
Vanger 0:b86d15c6ba29 13678 InitDhKey(&dhKey);
Vanger 0:b86d15c6ba29 13679 ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
Vanger 0:b86d15c6ba29 13680 ssl->buffers.serverDH_P.length,
Vanger 0:b86d15c6ba29 13681 ssl->buffers.serverDH_G.buffer,
Vanger 0:b86d15c6ba29 13682 ssl->buffers.serverDH_G.length);
Vanger 0:b86d15c6ba29 13683 if (ret == 0)
Vanger 0:b86d15c6ba29 13684 ret = DhAgree(&dhKey, pms + OPAQUE16_LEN,
Vanger 0:b86d15c6ba29 13685 &ssl->arrays->preMasterSz,
Vanger 0:b86d15c6ba29 13686 ssl->buffers.serverDH_Priv.buffer,
Vanger 0:b86d15c6ba29 13687 ssl->buffers.serverDH_Priv.length,
Vanger 0:b86d15c6ba29 13688 input + *inOutIdx, clientSz);
Vanger 0:b86d15c6ba29 13689 FreeDhKey(&dhKey);
Vanger 0:b86d15c6ba29 13690
Vanger 0:b86d15c6ba29 13691 *inOutIdx += clientSz;
Vanger 0:b86d15c6ba29 13692 c16toa((word16)ssl->arrays->preMasterSz, pms);
Vanger 0:b86d15c6ba29 13693 ssl->arrays->preMasterSz += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 13694 pms += ssl->arrays->preMasterSz;
Vanger 0:b86d15c6ba29 13695
Vanger 0:b86d15c6ba29 13696 /* Use the PSK hint to look up the PSK and add it to the
Vanger 0:b86d15c6ba29 13697 * preMasterSecret here. */
Vanger 0:b86d15c6ba29 13698 ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
Vanger 0:b86d15c6ba29 13699 ssl->arrays->client_identity, ssl->arrays->psk_key,
Vanger 0:b86d15c6ba29 13700 MAX_PSK_KEY_LEN);
Vanger 0:b86d15c6ba29 13701
Vanger 0:b86d15c6ba29 13702 if (ssl->arrays->psk_keySz == 0 ||
Vanger 0:b86d15c6ba29 13703 ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
Vanger 0:b86d15c6ba29 13704 return PSK_KEY_ERROR;
Vanger 0:b86d15c6ba29 13705
Vanger 0:b86d15c6ba29 13706 c16toa((word16) ssl->arrays->psk_keySz, pms);
Vanger 0:b86d15c6ba29 13707 pms += OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 13708
Vanger 0:b86d15c6ba29 13709 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
Vanger 0:b86d15c6ba29 13710 ssl->arrays->preMasterSz +=
Vanger 0:b86d15c6ba29 13711 ssl->arrays->psk_keySz + OPAQUE16_LEN;
Vanger 0:b86d15c6ba29 13712 if (ret == 0)
Vanger 0:b86d15c6ba29 13713 ret = MakeMasterSecret(ssl);
Vanger 0:b86d15c6ba29 13714
Vanger 0:b86d15c6ba29 13715 /* No further need for PSK */
Vanger 0:b86d15c6ba29 13716 XMEMSET(ssl->arrays->psk_key, 0, ssl->arrays->psk_keySz);
Vanger 0:b86d15c6ba29 13717 ssl->arrays->psk_keySz = 0;
Vanger 0:b86d15c6ba29 13718 }
Vanger 0:b86d15c6ba29 13719 break;
Vanger 0:b86d15c6ba29 13720 #endif /* !NO_DH && !NO_PSK */
Vanger 0:b86d15c6ba29 13721 default:
Vanger 0:b86d15c6ba29 13722 {
Vanger 0:b86d15c6ba29 13723 CYASSL_MSG("Bad kea type");
Vanger 0:b86d15c6ba29 13724 ret = BAD_KEA_TYPE_E;
Vanger 0:b86d15c6ba29 13725 }
Vanger 0:b86d15c6ba29 13726 break;
Vanger 0:b86d15c6ba29 13727 }
Vanger 0:b86d15c6ba29 13728
Vanger 0:b86d15c6ba29 13729 /* No further need for PMS */
Vanger 0:b86d15c6ba29 13730 XMEMSET(ssl->arrays->preMasterSecret, 0, ssl->arrays->preMasterSz);
Vanger 0:b86d15c6ba29 13731 ssl->arrays->preMasterSz = 0;
Vanger 0:b86d15c6ba29 13732
Vanger 0:b86d15c6ba29 13733 if (ret == 0) {
Vanger 0:b86d15c6ba29 13734 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
Vanger 0:b86d15c6ba29 13735 #ifndef NO_CERTS
Vanger 0:b86d15c6ba29 13736 if (ssl->options.verifyPeer)
Vanger 0:b86d15c6ba29 13737 ret = BuildCertHashes(ssl, &ssl->certHashes);
Vanger 0:b86d15c6ba29 13738 #endif
Vanger 0:b86d15c6ba29 13739 }
Vanger 0:b86d15c6ba29 13740
Vanger 0:b86d15c6ba29 13741 return ret;
Vanger 0:b86d15c6ba29 13742 }
Vanger 0:b86d15c6ba29 13743
Vanger 0:b86d15c6ba29 13744 #endif /* NO_CYASSL_SERVER */