fork of cyassl-lib

Dependents:   TLS_cyassl TLS_cyassl

Committer:
feb11
Date:
Mon Sep 16 09:53:35 2013 +0000
Revision:
4:f377303c41be
Parent:
0:714293de3836
changed settings

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:714293de3836 1 /* internal.c
ashleymills 0:714293de3836 2 *
ashleymills 0:714293de3836 3 * Copyright (C) 2006-2013 wolfSSL Inc.
ashleymills 0:714293de3836 4 *
ashleymills 0:714293de3836 5 * This file is part of CyaSSL.
ashleymills 0:714293de3836 6 *
ashleymills 0:714293de3836 7 * CyaSSL is free software; you can redistribute it and/or modify
ashleymills 0:714293de3836 8 * it under the terms of the GNU General Public License as published by
ashleymills 0:714293de3836 9 * the Free Software Foundation; either version 2 of the License, or
ashleymills 0:714293de3836 10 * (at your option) any later version.
ashleymills 0:714293de3836 11 *
ashleymills 0:714293de3836 12 * CyaSSL is distributed in the hope that it will be useful,
ashleymills 0:714293de3836 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ashleymills 0:714293de3836 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ashleymills 0:714293de3836 15 * GNU General Public License for more details.
ashleymills 0:714293de3836 16 *
ashleymills 0:714293de3836 17 * You should have received a copy of the GNU General Public License
ashleymills 0:714293de3836 18 * along with this program; if not, write to the Free Software
ashleymills 0:714293de3836 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
ashleymills 0:714293de3836 20 */
ashleymills 0:714293de3836 21
ashleymills 0:714293de3836 22
ashleymills 0:714293de3836 23 #ifdef HAVE_CONFIG_H
ashleymills 0:714293de3836 24 #include <config.h>
ashleymills 0:714293de3836 25 #endif
ashleymills 0:714293de3836 26
ashleymills 0:714293de3836 27 #include <cyassl/ctaocrypt/settings.h>
ashleymills 0:714293de3836 28
ashleymills 0:714293de3836 29 #include <cyassl/internal.h>
ashleymills 0:714293de3836 30 #include <cyassl/ctaoerror.h>
ashleymills 0:714293de3836 31 #include <cyassl/ctaocrypt/asn.h>
ashleymills 0:714293de3836 32
ashleymills 0:714293de3836 33 #ifdef HAVE_LIBZ
ashleymills 0:714293de3836 34 #include "zlib.h"
ashleymills 0:714293de3836 35 #endif
ashleymills 0:714293de3836 36
ashleymills 0:714293de3836 37 #ifdef HAVE_NTRU
ashleymills 0:714293de3836 38 #include "crypto_ntru.h"
ashleymills 0:714293de3836 39 #endif
ashleymills 0:714293de3836 40
ashleymills 0:714293de3836 41 #if defined(DEBUG_CYASSL) || defined(SHOW_SECRETS)
ashleymills 0:714293de3836 42 #ifdef FREESCALE_MQX
ashleymills 0:714293de3836 43 #include <fio.h>
ashleymills 0:714293de3836 44 #else
ashleymills 0:714293de3836 45 #include <stdio.h>
ashleymills 0:714293de3836 46 #endif
ashleymills 0:714293de3836 47 #endif
ashleymills 0:714293de3836 48
ashleymills 0:714293de3836 49 #ifdef __sun
ashleymills 0:714293de3836 50 #include <sys/filio.h>
ashleymills 0:714293de3836 51 #endif
ashleymills 0:714293de3836 52
ashleymills 0:714293de3836 53 #ifndef TRUE
ashleymills 0:714293de3836 54 #define TRUE 1
ashleymills 0:714293de3836 55 #endif
ashleymills 0:714293de3836 56 #ifndef FALSE
ashleymills 0:714293de3836 57 #define FALSE 0
ashleymills 0:714293de3836 58 #endif
ashleymills 0:714293de3836 59
ashleymills 0:714293de3836 60
ashleymills 0:714293de3836 61 #if defined(OPENSSL_EXTRA) && defined(NO_DH)
ashleymills 0:714293de3836 62 #error OPENSSL_EXTRA needs DH, please remove NO_DH
ashleymills 0:714293de3836 63 #endif
ashleymills 0:714293de3836 64
ashleymills 0:714293de3836 65 #if defined(CYASSL_CALLBACKS) && !defined(LARGE_STATIC_BUFFERS)
ashleymills 0:714293de3836 66 #error \
ashleymills 0:714293de3836 67 CYASSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
ashleymills 0:714293de3836 68 #endif
ashleymills 0:714293de3836 69
ashleymills 0:714293de3836 70
ashleymills 0:714293de3836 71 #ifndef NO_CYASSL_CLIENT
ashleymills 0:714293de3836 72 static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input, word32*);
ashleymills 0:714293de3836 73 static int DoServerHello(CYASSL* ssl, const byte* input, word32*, word32);
ashleymills 0:714293de3836 74 static int DoServerKeyExchange(CYASSL* ssl, const byte* input, word32*);
ashleymills 0:714293de3836 75 #ifndef NO_CERTS
ashleymills 0:714293de3836 76 static int DoCertificateRequest(CYASSL* ssl, const byte* input,word32*);
ashleymills 0:714293de3836 77 #endif
ashleymills 0:714293de3836 78 #endif
ashleymills 0:714293de3836 79
ashleymills 0:714293de3836 80
ashleymills 0:714293de3836 81 #ifndef NO_CYASSL_SERVER
ashleymills 0:714293de3836 82 static int DoClientHello(CYASSL* ssl, const byte* input, word32*, word32,
ashleymills 0:714293de3836 83 word32);
ashleymills 0:714293de3836 84 static int DoClientKeyExchange(CYASSL* ssl, byte* input, word32*, word32);
ashleymills 0:714293de3836 85 #if !defined(NO_RSA) || defined(HAVE_ECC)
ashleymills 0:714293de3836 86 static int DoCertificateVerify(CYASSL* ssl, byte*, word32*, word32);
ashleymills 0:714293de3836 87 #endif
ashleymills 0:714293de3836 88 #endif
ashleymills 0:714293de3836 89
ashleymills 0:714293de3836 90 typedef enum {
ashleymills 0:714293de3836 91 doProcessInit = 0,
ashleymills 0:714293de3836 92 #ifndef NO_CYASSL_SERVER
ashleymills 0:714293de3836 93 runProcessOldClientHello,
ashleymills 0:714293de3836 94 #endif
ashleymills 0:714293de3836 95 getRecordLayerHeader,
ashleymills 0:714293de3836 96 getData,
ashleymills 0:714293de3836 97 runProcessingOneMessage
ashleymills 0:714293de3836 98 } processReply;
ashleymills 0:714293de3836 99
ashleymills 0:714293de3836 100 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 101 static void Hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
ashleymills 0:714293de3836 102 int content, int verify);
ashleymills 0:714293de3836 103
ashleymills 0:714293de3836 104 #endif
ashleymills 0:714293de3836 105
ashleymills 0:714293de3836 106 #ifndef NO_CERTS
ashleymills 0:714293de3836 107 static void BuildCertHashes(CYASSL* ssl, Hashes* hashes);
ashleymills 0:714293de3836 108 #endif
ashleymills 0:714293de3836 109
ashleymills 0:714293de3836 110 static void PickHashSigAlgo(CYASSL* ssl,
ashleymills 0:714293de3836 111 const byte* hashSigAlgo, word32 hashSigAlgoSz);
ashleymills 0:714293de3836 112
ashleymills 0:714293de3836 113 #ifndef min
ashleymills 0:714293de3836 114
ashleymills 0:714293de3836 115 static INLINE word32 min(word32 a, word32 b)
ashleymills 0:714293de3836 116 {
ashleymills 0:714293de3836 117 return a > b ? b : a;
ashleymills 0:714293de3836 118 }
ashleymills 0:714293de3836 119
ashleymills 0:714293de3836 120 #endif /* min */
ashleymills 0:714293de3836 121
ashleymills 0:714293de3836 122
ashleymills 0:714293de3836 123 int IsTLS(const CYASSL* ssl)
ashleymills 0:714293de3836 124 {
ashleymills 0:714293de3836 125 if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_MINOR)
ashleymills 0:714293de3836 126 return 1;
ashleymills 0:714293de3836 127
ashleymills 0:714293de3836 128 return 0;
ashleymills 0:714293de3836 129 }
ashleymills 0:714293de3836 130
ashleymills 0:714293de3836 131
ashleymills 0:714293de3836 132 int IsAtLeastTLSv1_2(const CYASSL* ssl)
ashleymills 0:714293de3836 133 {
ashleymills 0:714293de3836 134 if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_2_MINOR)
ashleymills 0:714293de3836 135 return 1;
ashleymills 0:714293de3836 136 if (ssl->version.major == DTLS_MAJOR && ssl->version.minor <= DTLSv1_2_MINOR)
ashleymills 0:714293de3836 137 return 1;
ashleymills 0:714293de3836 138
ashleymills 0:714293de3836 139 return 0;
ashleymills 0:714293de3836 140 }
ashleymills 0:714293de3836 141
ashleymills 0:714293de3836 142
ashleymills 0:714293de3836 143 #ifdef HAVE_NTRU
ashleymills 0:714293de3836 144
ashleymills 0:714293de3836 145 static byte GetEntropy(ENTROPY_CMD cmd, byte* out)
ashleymills 0:714293de3836 146 {
ashleymills 0:714293de3836 147 /* TODO: add locking? */
ashleymills 0:714293de3836 148 static RNG rng;
ashleymills 0:714293de3836 149
ashleymills 0:714293de3836 150 if (cmd == INIT) {
ashleymills 0:714293de3836 151 int ret = InitRng(&rng);
ashleymills 0:714293de3836 152 if (ret == 0)
ashleymills 0:714293de3836 153 return 1;
ashleymills 0:714293de3836 154 else
ashleymills 0:714293de3836 155 return 0;
ashleymills 0:714293de3836 156 }
ashleymills 0:714293de3836 157
ashleymills 0:714293de3836 158 if (out == NULL)
ashleymills 0:714293de3836 159 return 0;
ashleymills 0:714293de3836 160
ashleymills 0:714293de3836 161 if (cmd == GET_BYTE_OF_ENTROPY) {
ashleymills 0:714293de3836 162 RNG_GenerateBlock(&rng, out, 1);
ashleymills 0:714293de3836 163 return 1;
ashleymills 0:714293de3836 164 }
ashleymills 0:714293de3836 165
ashleymills 0:714293de3836 166 if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) {
ashleymills 0:714293de3836 167 *out = 1;
ashleymills 0:714293de3836 168 return 1;
ashleymills 0:714293de3836 169 }
ashleymills 0:714293de3836 170
ashleymills 0:714293de3836 171 return 0;
ashleymills 0:714293de3836 172 }
ashleymills 0:714293de3836 173
ashleymills 0:714293de3836 174 #endif /* HAVE_NTRU */
ashleymills 0:714293de3836 175
ashleymills 0:714293de3836 176 /* used by ssl.c too */
ashleymills 0:714293de3836 177 void c32to24(word32 in, word24 out)
ashleymills 0:714293de3836 178 {
ashleymills 0:714293de3836 179 out[0] = (in >> 16) & 0xff;
ashleymills 0:714293de3836 180 out[1] = (in >> 8) & 0xff;
ashleymills 0:714293de3836 181 out[2] = in & 0xff;
ashleymills 0:714293de3836 182 }
ashleymills 0:714293de3836 183
ashleymills 0:714293de3836 184
ashleymills 0:714293de3836 185 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 186
ashleymills 0:714293de3836 187 static INLINE void c32to48(word32 in, byte out[6])
ashleymills 0:714293de3836 188 {
ashleymills 0:714293de3836 189 out[0] = 0;
ashleymills 0:714293de3836 190 out[1] = 0;
ashleymills 0:714293de3836 191 out[2] = (in >> 24) & 0xff;
ashleymills 0:714293de3836 192 out[3] = (in >> 16) & 0xff;
ashleymills 0:714293de3836 193 out[4] = (in >> 8) & 0xff;
ashleymills 0:714293de3836 194 out[5] = in & 0xff;
ashleymills 0:714293de3836 195 }
ashleymills 0:714293de3836 196
ashleymills 0:714293de3836 197 #endif /* CYASSL_DTLS */
ashleymills 0:714293de3836 198
ashleymills 0:714293de3836 199
ashleymills 0:714293de3836 200 /* convert 16 bit integer to opaque */
ashleymills 0:714293de3836 201 static INLINE void c16toa(word16 u16, byte* c)
ashleymills 0:714293de3836 202 {
ashleymills 0:714293de3836 203 c[0] = (u16 >> 8) & 0xff;
ashleymills 0:714293de3836 204 c[1] = u16 & 0xff;
ashleymills 0:714293de3836 205 }
ashleymills 0:714293de3836 206
ashleymills 0:714293de3836 207
ashleymills 0:714293de3836 208 /* convert 32 bit integer to opaque */
ashleymills 0:714293de3836 209 static INLINE void c32toa(word32 u32, byte* c)
ashleymills 0:714293de3836 210 {
ashleymills 0:714293de3836 211 c[0] = (u32 >> 24) & 0xff;
ashleymills 0:714293de3836 212 c[1] = (u32 >> 16) & 0xff;
ashleymills 0:714293de3836 213 c[2] = (u32 >> 8) & 0xff;
ashleymills 0:714293de3836 214 c[3] = u32 & 0xff;
ashleymills 0:714293de3836 215 }
ashleymills 0:714293de3836 216
ashleymills 0:714293de3836 217
ashleymills 0:714293de3836 218 /* convert a 24 bit integer into a 32 bit one */
ashleymills 0:714293de3836 219 static INLINE void c24to32(const word24 u24, word32* u32)
ashleymills 0:714293de3836 220 {
ashleymills 0:714293de3836 221 *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
ashleymills 0:714293de3836 222 }
ashleymills 0:714293de3836 223
ashleymills 0:714293de3836 224
ashleymills 0:714293de3836 225 /* convert opaque to 16 bit integer */
ashleymills 0:714293de3836 226 static INLINE void ato16(const byte* c, word16* u16)
ashleymills 0:714293de3836 227 {
ashleymills 0:714293de3836 228 *u16 = (c[0] << 8) | (c[1]);
ashleymills 0:714293de3836 229 }
ashleymills 0:714293de3836 230
ashleymills 0:714293de3836 231
ashleymills 0:714293de3836 232 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 233
ashleymills 0:714293de3836 234 /* convert opaque to 32 bit integer */
ashleymills 0:714293de3836 235 static INLINE void ato32(const byte* c, word32* u32)
ashleymills 0:714293de3836 236 {
ashleymills 0:714293de3836 237 *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
ashleymills 0:714293de3836 238 }
ashleymills 0:714293de3836 239
ashleymills 0:714293de3836 240 #endif /* CYASSL_DTLS */
ashleymills 0:714293de3836 241
ashleymills 0:714293de3836 242
ashleymills 0:714293de3836 243 #ifdef HAVE_LIBZ
ashleymills 0:714293de3836 244
ashleymills 0:714293de3836 245 /* alloc user allocs to work with zlib */
ashleymills 0:714293de3836 246 static void* myAlloc(void* opaque, unsigned int item, unsigned int size)
ashleymills 0:714293de3836 247 {
ashleymills 0:714293de3836 248 (void)opaque;
ashleymills 0:714293de3836 249 return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
ashleymills 0:714293de3836 250 }
ashleymills 0:714293de3836 251
ashleymills 0:714293de3836 252
ashleymills 0:714293de3836 253 static void myFree(void* opaque, void* memory)
ashleymills 0:714293de3836 254 {
ashleymills 0:714293de3836 255 (void)opaque;
ashleymills 0:714293de3836 256 XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ);
ashleymills 0:714293de3836 257 }
ashleymills 0:714293de3836 258
ashleymills 0:714293de3836 259
ashleymills 0:714293de3836 260 /* init zlib comp/decomp streams, 0 on success */
ashleymills 0:714293de3836 261 static int InitStreams(CYASSL* ssl)
ashleymills 0:714293de3836 262 {
ashleymills 0:714293de3836 263 ssl->c_stream.zalloc = (alloc_func)myAlloc;
ashleymills 0:714293de3836 264 ssl->c_stream.zfree = (free_func)myFree;
ashleymills 0:714293de3836 265 ssl->c_stream.opaque = (voidpf)ssl->heap;
ashleymills 0:714293de3836 266
ashleymills 0:714293de3836 267 if (deflateInit(&ssl->c_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
ashleymills 0:714293de3836 268 return ZLIB_INIT_ERROR;
ashleymills 0:714293de3836 269
ashleymills 0:714293de3836 270 ssl->didStreamInit = 1;
ashleymills 0:714293de3836 271
ashleymills 0:714293de3836 272 ssl->d_stream.zalloc = (alloc_func)myAlloc;
ashleymills 0:714293de3836 273 ssl->d_stream.zfree = (free_func)myFree;
ashleymills 0:714293de3836 274 ssl->d_stream.opaque = (voidpf)ssl->heap;
ashleymills 0:714293de3836 275
ashleymills 0:714293de3836 276 if (inflateInit(&ssl->d_stream) != Z_OK) return ZLIB_INIT_ERROR;
ashleymills 0:714293de3836 277
ashleymills 0:714293de3836 278 return 0;
ashleymills 0:714293de3836 279 }
ashleymills 0:714293de3836 280
ashleymills 0:714293de3836 281
ashleymills 0:714293de3836 282 static void FreeStreams(CYASSL* ssl)
ashleymills 0:714293de3836 283 {
ashleymills 0:714293de3836 284 if (ssl->didStreamInit) {
ashleymills 0:714293de3836 285 deflateEnd(&ssl->c_stream);
ashleymills 0:714293de3836 286 inflateEnd(&ssl->d_stream);
ashleymills 0:714293de3836 287 }
ashleymills 0:714293de3836 288 }
ashleymills 0:714293de3836 289
ashleymills 0:714293de3836 290
ashleymills 0:714293de3836 291 /* compress in to out, return out size or error */
ashleymills 0:714293de3836 292 static int myCompress(CYASSL* ssl, byte* in, int inSz, byte* out, int outSz)
ashleymills 0:714293de3836 293 {
ashleymills 0:714293de3836 294 int err;
ashleymills 0:714293de3836 295 int currTotal = (int)ssl->c_stream.total_out;
ashleymills 0:714293de3836 296
ashleymills 0:714293de3836 297 ssl->c_stream.next_in = in;
ashleymills 0:714293de3836 298 ssl->c_stream.avail_in = inSz;
ashleymills 0:714293de3836 299 ssl->c_stream.next_out = out;
ashleymills 0:714293de3836 300 ssl->c_stream.avail_out = outSz;
ashleymills 0:714293de3836 301
ashleymills 0:714293de3836 302 err = deflate(&ssl->c_stream, Z_SYNC_FLUSH);
ashleymills 0:714293de3836 303 if (err != Z_OK && err != Z_STREAM_END) return ZLIB_COMPRESS_ERROR;
ashleymills 0:714293de3836 304
ashleymills 0:714293de3836 305 return (int)ssl->c_stream.total_out - currTotal;
ashleymills 0:714293de3836 306 }
ashleymills 0:714293de3836 307
ashleymills 0:714293de3836 308
ashleymills 0:714293de3836 309 /* decompress in to out, returnn out size or error */
ashleymills 0:714293de3836 310 static int myDeCompress(CYASSL* ssl, byte* in,int inSz, byte* out,int outSz)
ashleymills 0:714293de3836 311 {
ashleymills 0:714293de3836 312 int err;
ashleymills 0:714293de3836 313 int currTotal = (int)ssl->d_stream.total_out;
ashleymills 0:714293de3836 314
ashleymills 0:714293de3836 315 ssl->d_stream.next_in = in;
ashleymills 0:714293de3836 316 ssl->d_stream.avail_in = inSz;
ashleymills 0:714293de3836 317 ssl->d_stream.next_out = out;
ashleymills 0:714293de3836 318 ssl->d_stream.avail_out = outSz;
ashleymills 0:714293de3836 319
ashleymills 0:714293de3836 320 err = inflate(&ssl->d_stream, Z_SYNC_FLUSH);
ashleymills 0:714293de3836 321 if (err != Z_OK && err != Z_STREAM_END) return ZLIB_DECOMPRESS_ERROR;
ashleymills 0:714293de3836 322
ashleymills 0:714293de3836 323 return (int)ssl->d_stream.total_out - currTotal;
ashleymills 0:714293de3836 324 }
ashleymills 0:714293de3836 325
ashleymills 0:714293de3836 326 #endif /* HAVE_LIBZ */
ashleymills 0:714293de3836 327
ashleymills 0:714293de3836 328
ashleymills 0:714293de3836 329 void InitSSL_Method(CYASSL_METHOD* method, ProtocolVersion pv)
ashleymills 0:714293de3836 330 {
ashleymills 0:714293de3836 331 method->version = pv;
ashleymills 0:714293de3836 332 method->side = CLIENT_END;
ashleymills 0:714293de3836 333 method->downgrade = 0;
ashleymills 0:714293de3836 334 }
ashleymills 0:714293de3836 335
ashleymills 0:714293de3836 336
ashleymills 0:714293de3836 337 /* Initialze SSL context, return 0 on success */
ashleymills 0:714293de3836 338 int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
ashleymills 0:714293de3836 339 {
ashleymills 0:714293de3836 340 ctx->method = method;
ashleymills 0:714293de3836 341 ctx->refCount = 1; /* so either CTX_free or SSL_free can release */
ashleymills 0:714293de3836 342 #ifndef NO_CERTS
ashleymills 0:714293de3836 343 ctx->certificate.buffer = 0;
ashleymills 0:714293de3836 344 ctx->certChain.buffer = 0;
ashleymills 0:714293de3836 345 ctx->privateKey.buffer = 0;
ashleymills 0:714293de3836 346 ctx->serverDH_P.buffer = 0;
ashleymills 0:714293de3836 347 ctx->serverDH_G.buffer = 0;
ashleymills 0:714293de3836 348 #endif
ashleymills 0:714293de3836 349 ctx->haveDH = 0;
ashleymills 0:714293de3836 350 ctx->haveNTRU = 0; /* start off */
ashleymills 0:714293de3836 351 ctx->haveECDSAsig = 0; /* start off */
ashleymills 0:714293de3836 352 ctx->haveStaticECC = 0; /* start off */
ashleymills 0:714293de3836 353 ctx->heap = ctx; /* defaults to self */
ashleymills 0:714293de3836 354 #ifndef NO_PSK
ashleymills 0:714293de3836 355 ctx->havePSK = 0;
ashleymills 0:714293de3836 356 ctx->server_hint[0] = 0;
ashleymills 0:714293de3836 357 ctx->client_psk_cb = 0;
ashleymills 0:714293de3836 358 ctx->server_psk_cb = 0;
ashleymills 0:714293de3836 359 #endif /* NO_PSK */
ashleymills 0:714293de3836 360 #ifdef HAVE_ECC
ashleymills 0:714293de3836 361 ctx->eccTempKeySz = ECDHE_SIZE;
ashleymills 0:714293de3836 362 #endif
ashleymills 0:714293de3836 363
ashleymills 0:714293de3836 364 #ifdef OPENSSL_EXTRA
ashleymills 0:714293de3836 365 ctx->passwd_cb = 0;
ashleymills 0:714293de3836 366 ctx->userdata = 0;
ashleymills 0:714293de3836 367 #endif /* OPENSSL_EXTRA */
ashleymills 0:714293de3836 368
ashleymills 0:714293de3836 369 ctx->timeout = DEFAULT_TIMEOUT;
ashleymills 0:714293de3836 370
ashleymills 0:714293de3836 371 #ifndef CYASSL_USER_IO
ashleymills 0:714293de3836 372 ctx->CBIORecv = EmbedReceive;
ashleymills 0:714293de3836 373 ctx->CBIOSend = EmbedSend;
ashleymills 0:714293de3836 374 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 375 if (method->version.major == DTLS_MAJOR) {
ashleymills 0:714293de3836 376 ctx->CBIORecv = EmbedReceiveFrom;
ashleymills 0:714293de3836 377 ctx->CBIOSend = EmbedSendTo;
ashleymills 0:714293de3836 378 ctx->CBIOCookie = EmbedGenerateCookie;
ashleymills 0:714293de3836 379 }
ashleymills 0:714293de3836 380 #endif
ashleymills 0:714293de3836 381 #else
ashleymills 0:714293de3836 382 /* user will set */
ashleymills 0:714293de3836 383 ctx->CBIORecv = NULL;
ashleymills 0:714293de3836 384 ctx->CBIOSend = NULL;
ashleymills 0:714293de3836 385 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 386 ctx->CBIOCookie = NULL;
ashleymills 0:714293de3836 387 #endif
ashleymills 0:714293de3836 388 #endif
ashleymills 0:714293de3836 389 ctx->partialWrite = 0;
ashleymills 0:714293de3836 390 ctx->verifyCallback = 0;
ashleymills 0:714293de3836 391
ashleymills 0:714293de3836 392 #ifndef NO_CERTS
ashleymills 0:714293de3836 393 ctx->cm = CyaSSL_CertManagerNew();
ashleymills 0:714293de3836 394 #endif
ashleymills 0:714293de3836 395 #ifdef HAVE_NTRU
ashleymills 0:714293de3836 396 if (method->side == CLIENT_END)
ashleymills 0:714293de3836 397 ctx->haveNTRU = 1; /* always on cliet side */
ashleymills 0:714293de3836 398 /* server can turn on by loading key */
ashleymills 0:714293de3836 399 #endif
ashleymills 0:714293de3836 400 #ifdef HAVE_ECC
ashleymills 0:714293de3836 401 if (method->side == CLIENT_END) {
ashleymills 0:714293de3836 402 ctx->haveECDSAsig = 1; /* always on cliet side */
ashleymills 0:714293de3836 403 ctx->haveStaticECC = 1; /* server can turn on by loading key */
ashleymills 0:714293de3836 404 }
ashleymills 0:714293de3836 405 #endif
ashleymills 0:714293de3836 406 ctx->suites.setSuites = 0; /* user hasn't set yet */
ashleymills 0:714293de3836 407 /* remove DH later if server didn't set, add psk later */
ashleymills 0:714293de3836 408 InitSuites(&ctx->suites, method->version, TRUE, FALSE, TRUE, ctx->haveNTRU,
ashleymills 0:714293de3836 409 ctx->haveECDSAsig, ctx->haveStaticECC, method->side);
ashleymills 0:714293de3836 410 ctx->verifyPeer = 0;
ashleymills 0:714293de3836 411 ctx->verifyNone = 0;
ashleymills 0:714293de3836 412 ctx->failNoCert = 0;
ashleymills 0:714293de3836 413 ctx->sessionCacheOff = 0; /* initially on */
ashleymills 0:714293de3836 414 ctx->sessionCacheFlushOff = 0; /* initially on */
ashleymills 0:714293de3836 415 ctx->sendVerify = 0;
ashleymills 0:714293de3836 416 ctx->quietShutdown = 0;
ashleymills 0:714293de3836 417 ctx->groupMessages = 0;
ashleymills 0:714293de3836 418 #ifdef HAVE_OCSP
ashleymills 0:714293de3836 419 CyaSSL_OCSP_Init(&ctx->ocsp);
ashleymills 0:714293de3836 420 #endif
ashleymills 0:714293de3836 421 #ifdef HAVE_CAVIUM
ashleymills 0:714293de3836 422 ctx->devId = NO_CAVIUM_DEVICE;
ashleymills 0:714293de3836 423 #endif
ashleymills 0:714293de3836 424 #ifdef HAVE_TLS_EXTENSIONS
ashleymills 0:714293de3836 425 ctx->extensions = NULL;
ashleymills 0:714293de3836 426 #endif
ashleymills 0:714293de3836 427
ashleymills 0:714293de3836 428 if (InitMutex(&ctx->countMutex) < 0) {
ashleymills 0:714293de3836 429 CYASSL_MSG("Mutex error on CTX init");
ashleymills 0:714293de3836 430 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 431 }
ashleymills 0:714293de3836 432 #ifndef NO_CERTS
ashleymills 0:714293de3836 433 if (ctx->cm == NULL) {
ashleymills 0:714293de3836 434 CYASSL_MSG("Bad Cert Manager New");
ashleymills 0:714293de3836 435 return BAD_CERT_MANAGER_ERROR;
ashleymills 0:714293de3836 436 }
ashleymills 0:714293de3836 437 #endif
ashleymills 0:714293de3836 438 return 0;
ashleymills 0:714293de3836 439 }
ashleymills 0:714293de3836 440
ashleymills 0:714293de3836 441
ashleymills 0:714293de3836 442 /* In case contexts are held in array and don't want to free actual ctx */
ashleymills 0:714293de3836 443 void SSL_CtxResourceFree(CYASSL_CTX* ctx)
ashleymills 0:714293de3836 444 {
ashleymills 0:714293de3836 445 XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
ashleymills 0:714293de3836 446
ashleymills 0:714293de3836 447 #ifndef NO_CERTS
ashleymills 0:714293de3836 448 XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
ashleymills 0:714293de3836 449 XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
ashleymills 0:714293de3836 450 XFREE(ctx->privateKey.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
ashleymills 0:714293de3836 451 XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
ashleymills 0:714293de3836 452 XFREE(ctx->certChain.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
ashleymills 0:714293de3836 453 CyaSSL_CertManagerFree(ctx->cm);
ashleymills 0:714293de3836 454 #endif
ashleymills 0:714293de3836 455 #ifdef HAVE_OCSP
ashleymills 0:714293de3836 456 CyaSSL_OCSP_Cleanup(&ctx->ocsp);
ashleymills 0:714293de3836 457 #endif
ashleymills 0:714293de3836 458 #ifdef HAVE_TLS_EXTENSIONS
ashleymills 0:714293de3836 459 TLSX_FreeAll(ctx->extensions);
ashleymills 0:714293de3836 460 #endif
ashleymills 0:714293de3836 461 }
ashleymills 0:714293de3836 462
ashleymills 0:714293de3836 463
ashleymills 0:714293de3836 464 void FreeSSL_Ctx(CYASSL_CTX* ctx)
ashleymills 0:714293de3836 465 {
ashleymills 0:714293de3836 466 int doFree = 0;
ashleymills 0:714293de3836 467
ashleymills 0:714293de3836 468 if (LockMutex(&ctx->countMutex) != 0) {
ashleymills 0:714293de3836 469 CYASSL_MSG("Couldn't lock count mutex");
ashleymills 0:714293de3836 470 return;
ashleymills 0:714293de3836 471 }
ashleymills 0:714293de3836 472 ctx->refCount--;
ashleymills 0:714293de3836 473 if (ctx->refCount == 0)
ashleymills 0:714293de3836 474 doFree = 1;
ashleymills 0:714293de3836 475 UnLockMutex(&ctx->countMutex);
ashleymills 0:714293de3836 476
ashleymills 0:714293de3836 477 if (doFree) {
ashleymills 0:714293de3836 478 CYASSL_MSG("CTX ref count down to 0, doing full free");
ashleymills 0:714293de3836 479 SSL_CtxResourceFree(ctx);
ashleymills 0:714293de3836 480 FreeMutex(&ctx->countMutex);
ashleymills 0:714293de3836 481 XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
ashleymills 0:714293de3836 482 }
ashleymills 0:714293de3836 483 else {
ashleymills 0:714293de3836 484 (void)ctx;
ashleymills 0:714293de3836 485 CYASSL_MSG("CTX ref count not 0 yet, no free");
ashleymills 0:714293de3836 486 }
ashleymills 0:714293de3836 487 }
ashleymills 0:714293de3836 488
ashleymills 0:714293de3836 489
ashleymills 0:714293de3836 490 /* Set cipher pointers to null */
ashleymills 0:714293de3836 491 void InitCiphers(CYASSL* ssl)
ashleymills 0:714293de3836 492 {
ashleymills 0:714293de3836 493 #ifdef BUILD_ARC4
ashleymills 0:714293de3836 494 ssl->encrypt.arc4 = NULL;
ashleymills 0:714293de3836 495 ssl->decrypt.arc4 = NULL;
ashleymills 0:714293de3836 496 #endif
ashleymills 0:714293de3836 497 #ifdef BUILD_DES3
ashleymills 0:714293de3836 498 ssl->encrypt.des3 = NULL;
ashleymills 0:714293de3836 499 ssl->decrypt.des3 = NULL;
ashleymills 0:714293de3836 500 #endif
ashleymills 0:714293de3836 501 #ifdef BUILD_AES
ashleymills 0:714293de3836 502 ssl->encrypt.aes = NULL;
ashleymills 0:714293de3836 503 ssl->decrypt.aes = NULL;
ashleymills 0:714293de3836 504 #endif
ashleymills 0:714293de3836 505 #ifdef HAVE_CAMELLIA
ashleymills 0:714293de3836 506 ssl->encrypt.cam = NULL;
ashleymills 0:714293de3836 507 ssl->decrypt.cam = NULL;
ashleymills 0:714293de3836 508 #endif
ashleymills 0:714293de3836 509 #ifdef HAVE_HC128
ashleymills 0:714293de3836 510 ssl->encrypt.hc128 = NULL;
ashleymills 0:714293de3836 511 ssl->decrypt.hc128 = NULL;
ashleymills 0:714293de3836 512 #endif
ashleymills 0:714293de3836 513 #ifdef BUILD_RABBIT
ashleymills 0:714293de3836 514 ssl->encrypt.rabbit = NULL;
ashleymills 0:714293de3836 515 ssl->decrypt.rabbit = NULL;
ashleymills 0:714293de3836 516 #endif
ashleymills 0:714293de3836 517 ssl->encrypt.setup = 0;
ashleymills 0:714293de3836 518 ssl->decrypt.setup = 0;
ashleymills 0:714293de3836 519 }
ashleymills 0:714293de3836 520
ashleymills 0:714293de3836 521
ashleymills 0:714293de3836 522 /* Free ciphers */
ashleymills 0:714293de3836 523 void FreeCiphers(CYASSL* ssl)
ashleymills 0:714293de3836 524 {
ashleymills 0:714293de3836 525 (void)ssl;
ashleymills 0:714293de3836 526 #ifdef BUILD_ARC4
ashleymills 0:714293de3836 527 #ifdef HAVE_CAVIUM
ashleymills 0:714293de3836 528 if (ssl->devId != NO_CAVIUM_DEVICE) {
ashleymills 0:714293de3836 529 Arc4FreeCavium(ssl->encrypt.arc4);
ashleymills 0:714293de3836 530 Arc4FreeCavium(ssl->decrypt.arc4);
ashleymills 0:714293de3836 531 }
ashleymills 0:714293de3836 532 #endif
ashleymills 0:714293de3836 533 XFREE(ssl->encrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:714293de3836 534 XFREE(ssl->decrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:714293de3836 535 #endif
ashleymills 0:714293de3836 536 #ifdef BUILD_DES3
ashleymills 0:714293de3836 537 #ifdef HAVE_CAVIUM
ashleymills 0:714293de3836 538 if (ssl->devId != NO_CAVIUM_DEVICE) {
ashleymills 0:714293de3836 539 Des3_FreeCavium(ssl->encrypt.des3);
ashleymills 0:714293de3836 540 Des3_FreeCavium(ssl->decrypt.des3);
ashleymills 0:714293de3836 541 }
ashleymills 0:714293de3836 542 #endif
ashleymills 0:714293de3836 543 XFREE(ssl->encrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:714293de3836 544 XFREE(ssl->decrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:714293de3836 545 #endif
ashleymills 0:714293de3836 546 #ifdef BUILD_AES
ashleymills 0:714293de3836 547 #ifdef HAVE_CAVIUM
ashleymills 0:714293de3836 548 if (ssl->devId != NO_CAVIUM_DEVICE) {
ashleymills 0:714293de3836 549 AesFreeCavium(ssl->encrypt.aes);
ashleymills 0:714293de3836 550 AesFreeCavium(ssl->decrypt.aes);
ashleymills 0:714293de3836 551 }
ashleymills 0:714293de3836 552 #endif
ashleymills 0:714293de3836 553 XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:714293de3836 554 XFREE(ssl->decrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:714293de3836 555 #endif
ashleymills 0:714293de3836 556 #ifdef BUILD_CAMELLIA
ashleymills 0:714293de3836 557 XFREE(ssl->encrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:714293de3836 558 XFREE(ssl->decrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:714293de3836 559 #endif
ashleymills 0:714293de3836 560 #ifdef HAVE_HC128
ashleymills 0:714293de3836 561 XFREE(ssl->encrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:714293de3836 562 XFREE(ssl->decrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:714293de3836 563 #endif
ashleymills 0:714293de3836 564 #ifdef BUILD_RABBIT
ashleymills 0:714293de3836 565 XFREE(ssl->encrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:714293de3836 566 XFREE(ssl->decrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:714293de3836 567 #endif
ashleymills 0:714293de3836 568 }
ashleymills 0:714293de3836 569
ashleymills 0:714293de3836 570
ashleymills 0:714293de3836 571 void InitCipherSpecs(CipherSpecs* cs)
ashleymills 0:714293de3836 572 {
ashleymills 0:714293de3836 573 cs->bulk_cipher_algorithm = INVALID_BYTE;
ashleymills 0:714293de3836 574 cs->cipher_type = INVALID_BYTE;
ashleymills 0:714293de3836 575 cs->mac_algorithm = INVALID_BYTE;
ashleymills 0:714293de3836 576 cs->kea = INVALID_BYTE;
ashleymills 0:714293de3836 577 cs->sig_algo = INVALID_BYTE;
ashleymills 0:714293de3836 578
ashleymills 0:714293de3836 579 cs->hash_size = 0;
ashleymills 0:714293de3836 580 cs->static_ecdh = 0;
ashleymills 0:714293de3836 581 cs->key_size = 0;
ashleymills 0:714293de3836 582 cs->iv_size = 0;
ashleymills 0:714293de3836 583 cs->block_size = 0;
ashleymills 0:714293de3836 584 }
ashleymills 0:714293de3836 585
ashleymills 0:714293de3836 586
ashleymills 0:714293de3836 587 void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK,
ashleymills 0:714293de3836 588 byte haveDH, byte haveNTRU, byte haveECDSAsig,
ashleymills 0:714293de3836 589 byte haveStaticECC, int side)
ashleymills 0:714293de3836 590 {
ashleymills 0:714293de3836 591 word16 idx = 0;
ashleymills 0:714293de3836 592 int tls = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR;
ashleymills 0:714293de3836 593 int tls1_2 = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_2_MINOR;
ashleymills 0:714293de3836 594 int haveRSAsig = 1;
ashleymills 0:714293de3836 595
ashleymills 0:714293de3836 596 (void)tls; /* shut up compiler */
ashleymills 0:714293de3836 597 (void)tls1_2;
ashleymills 0:714293de3836 598 (void)haveDH;
ashleymills 0:714293de3836 599 (void)havePSK;
ashleymills 0:714293de3836 600 (void)haveNTRU;
ashleymills 0:714293de3836 601 (void)haveStaticECC;
ashleymills 0:714293de3836 602
ashleymills 0:714293de3836 603 if (suites == NULL) {
ashleymills 0:714293de3836 604 CYASSL_MSG("InitSuites pointer error");
ashleymills 0:714293de3836 605 return;
ashleymills 0:714293de3836 606 }
ashleymills 0:714293de3836 607
ashleymills 0:714293de3836 608 if (suites->setSuites)
ashleymills 0:714293de3836 609 return; /* trust user settings, don't override */
ashleymills 0:714293de3836 610
ashleymills 0:714293de3836 611 if (side == SERVER_END && haveStaticECC)
ashleymills 0:714293de3836 612 haveRSA = 0; /* can't do RSA with ECDSA key */
ashleymills 0:714293de3836 613
ashleymills 0:714293de3836 614 if (side == SERVER_END && haveECDSAsig) {
ashleymills 0:714293de3836 615 haveRSAsig = 0; /* can't have RSA sig if signed by ECDSA */
ashleymills 0:714293de3836 616 (void)haveRSAsig; /* non ecc builds won't read */
ashleymills 0:714293de3836 617 }
ashleymills 0:714293de3836 618
ashleymills 0:714293de3836 619 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 620 if (pv.major == DTLS_MAJOR) {
ashleymills 0:714293de3836 621 tls = 1;
ashleymills 0:714293de3836 622 tls1_2 = pv.minor <= DTLSv1_2_MINOR;
ashleymills 0:714293de3836 623 }
ashleymills 0:714293de3836 624 #endif
ashleymills 0:714293de3836 625
ashleymills 0:714293de3836 626 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 627 if (tls && haveNTRU && haveRSA) {
ashleymills 0:714293de3836 628 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 629 suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_256_CBC_SHA;
ashleymills 0:714293de3836 630 }
ashleymills 0:714293de3836 631 #endif
ashleymills 0:714293de3836 632
ashleymills 0:714293de3836 633 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 634 if (tls && haveNTRU && haveRSA) {
ashleymills 0:714293de3836 635 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 636 suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_128_CBC_SHA;
ashleymills 0:714293de3836 637 }
ashleymills 0:714293de3836 638 #endif
ashleymills 0:714293de3836 639
ashleymills 0:714293de3836 640 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 641 if (tls && haveNTRU && haveRSA) {
ashleymills 0:714293de3836 642 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 643 suites->suites[idx++] = TLS_NTRU_RSA_WITH_RC4_128_SHA;
ashleymills 0:714293de3836 644 }
ashleymills 0:714293de3836 645 #endif
ashleymills 0:714293de3836 646
ashleymills 0:714293de3836 647 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 648 if (tls && haveNTRU && haveRSA) {
ashleymills 0:714293de3836 649 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 650 suites->suites[idx++] = TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA;
ashleymills 0:714293de3836 651 }
ashleymills 0:714293de3836 652 #endif
ashleymills 0:714293de3836 653
ashleymills 0:714293de3836 654 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 655 if (tls1_2 && haveRSAsig) {
ashleymills 0:714293de3836 656 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 657 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256;
ashleymills 0:714293de3836 658 }
ashleymills 0:714293de3836 659 #endif
ashleymills 0:714293de3836 660
ashleymills 0:714293de3836 661 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 662 if (tls1_2 && haveECDSAsig) {
ashleymills 0:714293de3836 663 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 664 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
ashleymills 0:714293de3836 665 }
ashleymills 0:714293de3836 666 #endif
ashleymills 0:714293de3836 667
ashleymills 0:714293de3836 668 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 669 if (tls1_2 && haveRSAsig && haveStaticECC) {
ashleymills 0:714293de3836 670 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 671 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256;
ashleymills 0:714293de3836 672 }
ashleymills 0:714293de3836 673 #endif
ashleymills 0:714293de3836 674
ashleymills 0:714293de3836 675 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 676 if (tls1_2 && haveECDSAsig && haveStaticECC) {
ashleymills 0:714293de3836 677 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 678 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256;
ashleymills 0:714293de3836 679 }
ashleymills 0:714293de3836 680 #endif
ashleymills 0:714293de3836 681
ashleymills 0:714293de3836 682 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
ashleymills 0:714293de3836 683 if (tls1_2 && haveRSAsig) {
ashleymills 0:714293de3836 684 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 685 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384;
ashleymills 0:714293de3836 686 }
ashleymills 0:714293de3836 687 #endif
ashleymills 0:714293de3836 688
ashleymills 0:714293de3836 689 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
ashleymills 0:714293de3836 690 if (tls1_2 && haveECDSAsig) {
ashleymills 0:714293de3836 691 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 692 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384;
ashleymills 0:714293de3836 693 }
ashleymills 0:714293de3836 694 #endif
ashleymills 0:714293de3836 695
ashleymills 0:714293de3836 696 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
ashleymills 0:714293de3836 697 if (tls1_2 && haveRSAsig && haveStaticECC) {
ashleymills 0:714293de3836 698 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 699 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384;
ashleymills 0:714293de3836 700 }
ashleymills 0:714293de3836 701 #endif
ashleymills 0:714293de3836 702
ashleymills 0:714293de3836 703 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
ashleymills 0:714293de3836 704 if (tls1_2 && haveECDSAsig && haveStaticECC) {
ashleymills 0:714293de3836 705 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 706 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384;
ashleymills 0:714293de3836 707 }
ashleymills 0:714293de3836 708 #endif
ashleymills 0:714293de3836 709
ashleymills 0:714293de3836 710 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 711 if (tls1_2 && haveECDSAsig) {
ashleymills 0:714293de3836 712 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 713 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
ashleymills 0:714293de3836 714 }
ashleymills 0:714293de3836 715 #endif
ashleymills 0:714293de3836 716
ashleymills 0:714293de3836 717 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 718 if (tls && haveECDSAsig) {
ashleymills 0:714293de3836 719 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 720 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA;
ashleymills 0:714293de3836 721 }
ashleymills 0:714293de3836 722 #endif
ashleymills 0:714293de3836 723
ashleymills 0:714293de3836 724 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 725 if (tls1_2 && haveECDSAsig && haveStaticECC) {
ashleymills 0:714293de3836 726 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 727 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
ashleymills 0:714293de3836 728 }
ashleymills 0:714293de3836 729 #endif
ashleymills 0:714293de3836 730
ashleymills 0:714293de3836 731 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 732 if (tls && haveECDSAsig && haveStaticECC) {
ashleymills 0:714293de3836 733 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 734 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA;
ashleymills 0:714293de3836 735 }
ashleymills 0:714293de3836 736 #endif
ashleymills 0:714293de3836 737
ashleymills 0:714293de3836 738 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 739 if (tls1_2 && haveECDSAsig) {
ashleymills 0:714293de3836 740 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 741 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
ashleymills 0:714293de3836 742 }
ashleymills 0:714293de3836 743 #endif
ashleymills 0:714293de3836 744
ashleymills 0:714293de3836 745 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 746 if (tls && haveECDSAsig) {
ashleymills 0:714293de3836 747 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 748 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA;
ashleymills 0:714293de3836 749 }
ashleymills 0:714293de3836 750 #endif
ashleymills 0:714293de3836 751
ashleymills 0:714293de3836 752 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 753 if (tls1_2 && haveECDSAsig && haveStaticECC) {
ashleymills 0:714293de3836 754 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 755 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
ashleymills 0:714293de3836 756 }
ashleymills 0:714293de3836 757 #endif
ashleymills 0:714293de3836 758
ashleymills 0:714293de3836 759 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 760 if (tls && haveECDSAsig && haveStaticECC) {
ashleymills 0:714293de3836 761 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 762 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA;
ashleymills 0:714293de3836 763 }
ashleymills 0:714293de3836 764 #endif
ashleymills 0:714293de3836 765
ashleymills 0:714293de3836 766 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 767 if (tls && haveECDSAsig) {
ashleymills 0:714293de3836 768 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 769 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA;
ashleymills 0:714293de3836 770 }
ashleymills 0:714293de3836 771 #endif
ashleymills 0:714293de3836 772
ashleymills 0:714293de3836 773 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 774 if (tls && haveECDSAsig && haveStaticECC) {
ashleymills 0:714293de3836 775 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 776 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA;
ashleymills 0:714293de3836 777 }
ashleymills 0:714293de3836 778 #endif
ashleymills 0:714293de3836 779
ashleymills 0:714293de3836 780 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 781 if (tls && haveECDSAsig) {
ashleymills 0:714293de3836 782 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 783 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA;
ashleymills 0:714293de3836 784 }
ashleymills 0:714293de3836 785 #endif
ashleymills 0:714293de3836 786
ashleymills 0:714293de3836 787 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 788 if (tls && haveECDSAsig && haveStaticECC) {
ashleymills 0:714293de3836 789 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 790 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA;
ashleymills 0:714293de3836 791 }
ashleymills 0:714293de3836 792 #endif
ashleymills 0:714293de3836 793
ashleymills 0:714293de3836 794 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 795 if (tls1_2 && haveRSA) {
ashleymills 0:714293de3836 796 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 797 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
ashleymills 0:714293de3836 798 }
ashleymills 0:714293de3836 799 #endif
ashleymills 0:714293de3836 800
ashleymills 0:714293de3836 801 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 802 if (tls && haveRSA) {
ashleymills 0:714293de3836 803 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 804 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
ashleymills 0:714293de3836 805 }
ashleymills 0:714293de3836 806 #endif
ashleymills 0:714293de3836 807
ashleymills 0:714293de3836 808 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 809 if (tls1_2 && haveRSAsig && haveStaticECC) {
ashleymills 0:714293de3836 810 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 811 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
ashleymills 0:714293de3836 812 }
ashleymills 0:714293de3836 813 #endif
ashleymills 0:714293de3836 814
ashleymills 0:714293de3836 815 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 816 if (tls && haveRSAsig && haveStaticECC) {
ashleymills 0:714293de3836 817 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 818 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA;
ashleymills 0:714293de3836 819 }
ashleymills 0:714293de3836 820 #endif
ashleymills 0:714293de3836 821
ashleymills 0:714293de3836 822 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 823 if (tls1_2 && haveRSA) {
ashleymills 0:714293de3836 824 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 825 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
ashleymills 0:714293de3836 826 }
ashleymills 0:714293de3836 827 #endif
ashleymills 0:714293de3836 828
ashleymills 0:714293de3836 829 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 830 if (tls && haveRSA) {
ashleymills 0:714293de3836 831 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 832 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA;
ashleymills 0:714293de3836 833 }
ashleymills 0:714293de3836 834 #endif
ashleymills 0:714293de3836 835
ashleymills 0:714293de3836 836 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 837 if (tls1_2 && haveRSAsig && haveStaticECC) {
ashleymills 0:714293de3836 838 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 839 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
ashleymills 0:714293de3836 840 }
ashleymills 0:714293de3836 841 #endif
ashleymills 0:714293de3836 842
ashleymills 0:714293de3836 843 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 844 if (tls && haveRSAsig && haveStaticECC) {
ashleymills 0:714293de3836 845 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 846 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA;
ashleymills 0:714293de3836 847 }
ashleymills 0:714293de3836 848 #endif
ashleymills 0:714293de3836 849
ashleymills 0:714293de3836 850 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 851 if (tls && haveRSA) {
ashleymills 0:714293de3836 852 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 853 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_RC4_128_SHA;
ashleymills 0:714293de3836 854 }
ashleymills 0:714293de3836 855 #endif
ashleymills 0:714293de3836 856
ashleymills 0:714293de3836 857 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 858 if (tls && haveRSAsig && haveStaticECC) {
ashleymills 0:714293de3836 859 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 860 suites->suites[idx++] = TLS_ECDH_RSA_WITH_RC4_128_SHA;
ashleymills 0:714293de3836 861 }
ashleymills 0:714293de3836 862 #endif
ashleymills 0:714293de3836 863
ashleymills 0:714293de3836 864 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 865 if (tls && haveRSA) {
ashleymills 0:714293de3836 866 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 867 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA;
ashleymills 0:714293de3836 868 }
ashleymills 0:714293de3836 869 #endif
ashleymills 0:714293de3836 870
ashleymills 0:714293de3836 871 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 872 if (tls && haveRSAsig && haveStaticECC) {
ashleymills 0:714293de3836 873 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 874 suites->suites[idx++] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA;
ashleymills 0:714293de3836 875 }
ashleymills 0:714293de3836 876 #endif
ashleymills 0:714293de3836 877
ashleymills 0:714293de3836 878 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 879 if (tls1_2 && haveDH && haveRSA) {
ashleymills 0:714293de3836 880 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 881 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
ashleymills 0:714293de3836 882 }
ashleymills 0:714293de3836 883 #endif
ashleymills 0:714293de3836 884
ashleymills 0:714293de3836 885 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
ashleymills 0:714293de3836 886 if (tls1_2 && haveECDSAsig) {
ashleymills 0:714293de3836 887 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 888 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
ashleymills 0:714293de3836 889 }
ashleymills 0:714293de3836 890 #endif
ashleymills 0:714293de3836 891
ashleymills 0:714293de3836 892 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
ashleymills 0:714293de3836 893 if (tls1_2 && haveECDSAsig) {
ashleymills 0:714293de3836 894 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 895 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8;
ashleymills 0:714293de3836 896 }
ashleymills 0:714293de3836 897 #endif
ashleymills 0:714293de3836 898
ashleymills 0:714293de3836 899 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
ashleymills 0:714293de3836 900 if (tls1_2 && haveRSA) {
ashleymills 0:714293de3836 901 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 902 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CCM_8;
ashleymills 0:714293de3836 903 }
ashleymills 0:714293de3836 904 #endif
ashleymills 0:714293de3836 905
ashleymills 0:714293de3836 906 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
ashleymills 0:714293de3836 907 if (tls1_2 && haveRSA) {
ashleymills 0:714293de3836 908 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 909 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CCM_8;
ashleymills 0:714293de3836 910 }
ashleymills 0:714293de3836 911 #endif
ashleymills 0:714293de3836 912
ashleymills 0:714293de3836 913 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
ashleymills 0:714293de3836 914 if (tls1_2 && haveDH && haveRSA) {
ashleymills 0:714293de3836 915 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 916 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
ashleymills 0:714293de3836 917 }
ashleymills 0:714293de3836 918 #endif
ashleymills 0:714293de3836 919
ashleymills 0:714293de3836 920 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 921 if (tls1_2 && haveDH && haveRSA) {
ashleymills 0:714293de3836 922 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 923 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
ashleymills 0:714293de3836 924 }
ashleymills 0:714293de3836 925 #endif
ashleymills 0:714293de3836 926
ashleymills 0:714293de3836 927 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 928 if (tls1_2 && haveDH && haveRSA) {
ashleymills 0:714293de3836 929 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 930 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
ashleymills 0:714293de3836 931 }
ashleymills 0:714293de3836 932 #endif
ashleymills 0:714293de3836 933
ashleymills 0:714293de3836 934 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 935 if (tls && haveDH && haveRSA) {
ashleymills 0:714293de3836 936 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 937 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
ashleymills 0:714293de3836 938 }
ashleymills 0:714293de3836 939 #endif
ashleymills 0:714293de3836 940
ashleymills 0:714293de3836 941 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 942 if (tls && haveDH && haveRSA) {
ashleymills 0:714293de3836 943 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 944 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
ashleymills 0:714293de3836 945 }
ashleymills 0:714293de3836 946 #endif
ashleymills 0:714293de3836 947
ashleymills 0:714293de3836 948 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 949 if (tls1_2 && haveRSA) {
ashleymills 0:714293de3836 950 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 951 suites->suites[idx++] = TLS_RSA_WITH_AES_256_GCM_SHA384;
ashleymills 0:714293de3836 952 }
ashleymills 0:714293de3836 953 #endif
ashleymills 0:714293de3836 954
ashleymills 0:714293de3836 955 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
ashleymills 0:714293de3836 956 if (tls1_2 && haveRSA) {
ashleymills 0:714293de3836 957 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 958 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
ashleymills 0:714293de3836 959 }
ashleymills 0:714293de3836 960 #endif
ashleymills 0:714293de3836 961
ashleymills 0:714293de3836 962 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 963 if (tls1_2 && haveRSA) {
ashleymills 0:714293de3836 964 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 965 suites->suites[idx++] = TLS_RSA_WITH_AES_128_GCM_SHA256;
ashleymills 0:714293de3836 966 }
ashleymills 0:714293de3836 967 #endif
ashleymills 0:714293de3836 968
ashleymills 0:714293de3836 969 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 970 if (tls1_2 && haveRSA) {
ashleymills 0:714293de3836 971 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 972 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
ashleymills 0:714293de3836 973 }
ashleymills 0:714293de3836 974 #endif
ashleymills 0:714293de3836 975
ashleymills 0:714293de3836 976 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 977 if (tls && haveRSA) {
ashleymills 0:714293de3836 978 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 979 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA;
ashleymills 0:714293de3836 980 }
ashleymills 0:714293de3836 981 #endif
ashleymills 0:714293de3836 982
ashleymills 0:714293de3836 983 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 984 if (tls && haveRSA) {
ashleymills 0:714293de3836 985 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 986 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA;
ashleymills 0:714293de3836 987 }
ashleymills 0:714293de3836 988 #endif
ashleymills 0:714293de3836 989
ashleymills 0:714293de3836 990 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
ashleymills 0:714293de3836 991 if (tls && haveRSA) {
ashleymills 0:714293de3836 992 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 993 suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA;
ashleymills 0:714293de3836 994 }
ashleymills 0:714293de3836 995 #endif
ashleymills 0:714293de3836 996
ashleymills 0:714293de3836 997 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
ashleymills 0:714293de3836 998 if (tls && haveRSA) {
ashleymills 0:714293de3836 999 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1000 suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA256;
ashleymills 0:714293de3836 1001 }
ashleymills 0:714293de3836 1002 #endif
ashleymills 0:714293de3836 1003
ashleymills 0:714293de3836 1004 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 1005 if (tls && havePSK) {
ashleymills 0:714293de3836 1006 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1007 suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA;
ashleymills 0:714293de3836 1008 }
ashleymills 0:714293de3836 1009 #endif
ashleymills 0:714293de3836 1010
ashleymills 0:714293de3836 1011 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 1012 if (tls && havePSK) {
ashleymills 0:714293de3836 1013 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1014 suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA256;
ashleymills 0:714293de3836 1015 }
ashleymills 0:714293de3836 1016 #endif
ashleymills 0:714293de3836 1017
ashleymills 0:714293de3836 1018 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 1019 if (tls && havePSK) {
ashleymills 0:714293de3836 1020 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1021 suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA;
ashleymills 0:714293de3836 1022 }
ashleymills 0:714293de3836 1023 #endif
ashleymills 0:714293de3836 1024
ashleymills 0:714293de3836 1025 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
ashleymills 0:714293de3836 1026 if (tls && havePSK) {
ashleymills 0:714293de3836 1027 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 1028 suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM_8;
ashleymills 0:714293de3836 1029 }
ashleymills 0:714293de3836 1030 #endif
ashleymills 0:714293de3836 1031
ashleymills 0:714293de3836 1032 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
ashleymills 0:714293de3836 1033 if (tls && havePSK) {
ashleymills 0:714293de3836 1034 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:714293de3836 1035 suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM_8;
ashleymills 0:714293de3836 1036 }
ashleymills 0:714293de3836 1037 #endif
ashleymills 0:714293de3836 1038
ashleymills 0:714293de3836 1039 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
ashleymills 0:714293de3836 1040 if (tls && havePSK) {
ashleymills 0:714293de3836 1041 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1042 suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA256;
ashleymills 0:714293de3836 1043 }
ashleymills 0:714293de3836 1044 #endif
ashleymills 0:714293de3836 1045
ashleymills 0:714293de3836 1046 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
ashleymills 0:714293de3836 1047 if (tls && havePSK) {
ashleymills 0:714293de3836 1048 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1049 suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA;
ashleymills 0:714293de3836 1050 }
ashleymills 0:714293de3836 1051 #endif
ashleymills 0:714293de3836 1052
ashleymills 0:714293de3836 1053 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 1054 if (haveRSA ) {
ashleymills 0:714293de3836 1055 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1056 suites->suites[idx++] = SSL_RSA_WITH_RC4_128_SHA;
ashleymills 0:714293de3836 1057 }
ashleymills 0:714293de3836 1058 #endif
ashleymills 0:714293de3836 1059
ashleymills 0:714293de3836 1060 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
ashleymills 0:714293de3836 1061 if (haveRSA ) {
ashleymills 0:714293de3836 1062 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1063 suites->suites[idx++] = SSL_RSA_WITH_RC4_128_MD5;
ashleymills 0:714293de3836 1064 }
ashleymills 0:714293de3836 1065 #endif
ashleymills 0:714293de3836 1066
ashleymills 0:714293de3836 1067 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 1068 if (haveRSA ) {
ashleymills 0:714293de3836 1069 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1070 suites->suites[idx++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
ashleymills 0:714293de3836 1071 }
ashleymills 0:714293de3836 1072 #endif
ashleymills 0:714293de3836 1073
ashleymills 0:714293de3836 1074 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
ashleymills 0:714293de3836 1075 if (tls && haveRSA) {
ashleymills 0:714293de3836 1076 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1077 suites->suites[idx++] = TLS_RSA_WITH_HC_128_CBC_MD5;
ashleymills 0:714293de3836 1078 }
ashleymills 0:714293de3836 1079 #endif
ashleymills 0:714293de3836 1080
ashleymills 0:714293de3836 1081 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
ashleymills 0:714293de3836 1082 if (tls && haveRSA) {
ashleymills 0:714293de3836 1083 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1084 suites->suites[idx++] = TLS_RSA_WITH_HC_128_CBC_SHA;
ashleymills 0:714293de3836 1085 }
ashleymills 0:714293de3836 1086 #endif
ashleymills 0:714293de3836 1087
ashleymills 0:714293de3836 1088 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
ashleymills 0:714293de3836 1089 if (tls && haveRSA) {
ashleymills 0:714293de3836 1090 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1091 suites->suites[idx++] = TLS_RSA_WITH_RABBIT_CBC_SHA;
ashleymills 0:714293de3836 1092 }
ashleymills 0:714293de3836 1093 #endif
ashleymills 0:714293de3836 1094
ashleymills 0:714293de3836 1095 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
ashleymills 0:714293de3836 1096 if (tls && haveRSA) {
ashleymills 0:714293de3836 1097 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1098 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA;
ashleymills 0:714293de3836 1099 }
ashleymills 0:714293de3836 1100 #endif
ashleymills 0:714293de3836 1101
ashleymills 0:714293de3836 1102 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
ashleymills 0:714293de3836 1103 if (tls && haveDH && haveRSA) {
ashleymills 0:714293de3836 1104 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1105 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA;
ashleymills 0:714293de3836 1106 }
ashleymills 0:714293de3836 1107 #endif
ashleymills 0:714293de3836 1108
ashleymills 0:714293de3836 1109 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
ashleymills 0:714293de3836 1110 if (tls && haveRSA) {
ashleymills 0:714293de3836 1111 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1112 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA;
ashleymills 0:714293de3836 1113 }
ashleymills 0:714293de3836 1114 #endif
ashleymills 0:714293de3836 1115
ashleymills 0:714293de3836 1116 #ifdef BUILD_TLS_DHE_WITH_RSA_CAMELLIA_256_CBC_SHA
ashleymills 0:714293de3836 1117 if (tls && haveDH && haveRSA) {
ashleymills 0:714293de3836 1118 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1119 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA;
ashleymills 0:714293de3836 1120 }
ashleymills 0:714293de3836 1121 #endif
ashleymills 0:714293de3836 1122
ashleymills 0:714293de3836 1123 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
ashleymills 0:714293de3836 1124 if (tls && haveRSA) {
ashleymills 0:714293de3836 1125 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1126 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256;
ashleymills 0:714293de3836 1127 }
ashleymills 0:714293de3836 1128 #endif
ashleymills 0:714293de3836 1129
ashleymills 0:714293de3836 1130 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
ashleymills 0:714293de3836 1131 if (tls && haveDH && haveRSA) {
ashleymills 0:714293de3836 1132 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1133 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256;
ashleymills 0:714293de3836 1134 }
ashleymills 0:714293de3836 1135 #endif
ashleymills 0:714293de3836 1136
ashleymills 0:714293de3836 1137 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
ashleymills 0:714293de3836 1138 if (tls && haveRSA) {
ashleymills 0:714293de3836 1139 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1140 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256;
ashleymills 0:714293de3836 1141 }
ashleymills 0:714293de3836 1142 #endif
ashleymills 0:714293de3836 1143
ashleymills 0:714293de3836 1144 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
ashleymills 0:714293de3836 1145 if (tls && haveDH && haveRSA) {
ashleymills 0:714293de3836 1146 suites->suites[idx++] = 0;
ashleymills 0:714293de3836 1147 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256;
ashleymills 0:714293de3836 1148 }
ashleymills 0:714293de3836 1149 #endif
ashleymills 0:714293de3836 1150
ashleymills 0:714293de3836 1151 suites->suiteSz = idx;
ashleymills 0:714293de3836 1152
ashleymills 0:714293de3836 1153 {
ashleymills 0:714293de3836 1154 idx = 0;
ashleymills 0:714293de3836 1155
ashleymills 0:714293de3836 1156 if (haveECDSAsig) {
ashleymills 0:714293de3836 1157 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 1158 suites->hashSigAlgo[idx++] = sha384_mac;
ashleymills 0:714293de3836 1159 suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
ashleymills 0:714293de3836 1160 #endif
ashleymills 0:714293de3836 1161 #ifndef NO_SHA256
ashleymills 0:714293de3836 1162 suites->hashSigAlgo[idx++] = sha256_mac;
ashleymills 0:714293de3836 1163 suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
ashleymills 0:714293de3836 1164 #endif
ashleymills 0:714293de3836 1165 #ifndef NO_SHA
ashleymills 0:714293de3836 1166 suites->hashSigAlgo[idx++] = sha_mac;
ashleymills 0:714293de3836 1167 suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
ashleymills 0:714293de3836 1168 #endif
ashleymills 0:714293de3836 1169 }
ashleymills 0:714293de3836 1170
ashleymills 0:714293de3836 1171 if (haveRSAsig) {
ashleymills 0:714293de3836 1172 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 1173 suites->hashSigAlgo[idx++] = sha384_mac;
ashleymills 0:714293de3836 1174 suites->hashSigAlgo[idx++] = rsa_sa_algo;
ashleymills 0:714293de3836 1175 #endif
ashleymills 0:714293de3836 1176 #ifndef NO_SHA256
ashleymills 0:714293de3836 1177 suites->hashSigAlgo[idx++] = sha256_mac;
ashleymills 0:714293de3836 1178 suites->hashSigAlgo[idx++] = rsa_sa_algo;
ashleymills 0:714293de3836 1179 #endif
ashleymills 0:714293de3836 1180 #ifndef NO_SHA
ashleymills 0:714293de3836 1181 suites->hashSigAlgo[idx++] = sha_mac;
ashleymills 0:714293de3836 1182 suites->hashSigAlgo[idx++] = rsa_sa_algo;
ashleymills 0:714293de3836 1183 #endif
ashleymills 0:714293de3836 1184 }
ashleymills 0:714293de3836 1185
ashleymills 0:714293de3836 1186 suites->hashSigAlgoSz = idx;
ashleymills 0:714293de3836 1187 }
ashleymills 0:714293de3836 1188 }
ashleymills 0:714293de3836 1189
ashleymills 0:714293de3836 1190
ashleymills 0:714293de3836 1191 #ifndef NO_CERTS
ashleymills 0:714293de3836 1192
ashleymills 0:714293de3836 1193 /* Initialize CyaSSL X509 type */
ashleymills 0:714293de3836 1194 void InitX509(CYASSL_X509* x509, int dynamicFlag)
ashleymills 0:714293de3836 1195 {
ashleymills 0:714293de3836 1196 x509->derCert.buffer = NULL;
ashleymills 0:714293de3836 1197 x509->altNames = NULL;
ashleymills 0:714293de3836 1198 x509->altNamesNext = NULL;
ashleymills 0:714293de3836 1199 x509->dynamicMemory = (byte)dynamicFlag;
ashleymills 0:714293de3836 1200 }
ashleymills 0:714293de3836 1201
ashleymills 0:714293de3836 1202
ashleymills 0:714293de3836 1203 /* Free CyaSSL X509 type */
ashleymills 0:714293de3836 1204 void FreeX509(CYASSL_X509* x509)
ashleymills 0:714293de3836 1205 {
ashleymills 0:714293de3836 1206 if (x509 == NULL)
ashleymills 0:714293de3836 1207 return;
ashleymills 0:714293de3836 1208
ashleymills 0:714293de3836 1209 XFREE(x509->derCert.buffer, NULL, DYNAMIC_TYPE_CERT);
ashleymills 0:714293de3836 1210 if (x509->altNames)
ashleymills 0:714293de3836 1211 FreeAltNames(x509->altNames, NULL);
ashleymills 0:714293de3836 1212 if (x509->dynamicMemory)
ashleymills 0:714293de3836 1213 XFREE(x509, NULL, DYNAMIC_TYPE_X509);
ashleymills 0:714293de3836 1214 }
ashleymills 0:714293de3836 1215
ashleymills 0:714293de3836 1216 #endif /* NO_CERTS */
ashleymills 0:714293de3836 1217
ashleymills 0:714293de3836 1218
ashleymills 0:714293de3836 1219 /* init everything to 0, NULL, default values before calling anything that may
ashleymills 0:714293de3836 1220 fail so that desctructor has a "good" state to cleanup */
ashleymills 0:714293de3836 1221 int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
ashleymills 0:714293de3836 1222 {
ashleymills 0:714293de3836 1223 int ret;
ashleymills 0:714293de3836 1224 byte haveRSA = 0;
ashleymills 0:714293de3836 1225 byte havePSK = 0;
ashleymills 0:714293de3836 1226
ashleymills 0:714293de3836 1227 ssl->ctx = ctx; /* only for passing to calls, options could change */
ashleymills 0:714293de3836 1228 ssl->version = ctx->method->version;
ashleymills 0:714293de3836 1229 ssl->suites = NULL;
ashleymills 0:714293de3836 1230
ashleymills 0:714293de3836 1231 #ifdef HAVE_LIBZ
ashleymills 0:714293de3836 1232 ssl->didStreamInit = 0;
ashleymills 0:714293de3836 1233 #endif
ashleymills 0:714293de3836 1234 #ifndef NO_RSA
ashleymills 0:714293de3836 1235 haveRSA = 1;
ashleymills 0:714293de3836 1236 #endif
ashleymills 0:714293de3836 1237
ashleymills 0:714293de3836 1238 #ifndef NO_CERTS
ashleymills 0:714293de3836 1239 ssl->buffers.certificate.buffer = 0;
ashleymills 0:714293de3836 1240 ssl->buffers.key.buffer = 0;
ashleymills 0:714293de3836 1241 ssl->buffers.certChain.buffer = 0;
ashleymills 0:714293de3836 1242 #endif
ashleymills 0:714293de3836 1243 ssl->buffers.inputBuffer.length = 0;
ashleymills 0:714293de3836 1244 ssl->buffers.inputBuffer.idx = 0;
ashleymills 0:714293de3836 1245 ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
ashleymills 0:714293de3836 1246 ssl->buffers.inputBuffer.bufferSize = STATIC_BUFFER_LEN;
ashleymills 0:714293de3836 1247 ssl->buffers.inputBuffer.dynamicFlag = 0;
ashleymills 0:714293de3836 1248 ssl->buffers.inputBuffer.offset = 0;
ashleymills 0:714293de3836 1249 ssl->buffers.outputBuffer.length = 0;
ashleymills 0:714293de3836 1250 ssl->buffers.outputBuffer.idx = 0;
ashleymills 0:714293de3836 1251 ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
ashleymills 0:714293de3836 1252 ssl->buffers.outputBuffer.bufferSize = STATIC_BUFFER_LEN;
ashleymills 0:714293de3836 1253 ssl->buffers.outputBuffer.dynamicFlag = 0;
ashleymills 0:714293de3836 1254 ssl->buffers.outputBuffer.offset = 0;
ashleymills 0:714293de3836 1255 ssl->buffers.domainName.buffer = 0;
ashleymills 0:714293de3836 1256 #ifndef NO_CERTS
ashleymills 0:714293de3836 1257 ssl->buffers.serverDH_P.buffer = 0;
ashleymills 0:714293de3836 1258 ssl->buffers.serverDH_G.buffer = 0;
ashleymills 0:714293de3836 1259 ssl->buffers.serverDH_Pub.buffer = 0;
ashleymills 0:714293de3836 1260 ssl->buffers.serverDH_Priv.buffer = 0;
ashleymills 0:714293de3836 1261 #endif
ashleymills 0:714293de3836 1262 ssl->buffers.clearOutputBuffer.buffer = 0;
ashleymills 0:714293de3836 1263 ssl->buffers.clearOutputBuffer.length = 0;
ashleymills 0:714293de3836 1264 ssl->buffers.prevSent = 0;
ashleymills 0:714293de3836 1265 ssl->buffers.plainSz = 0;
ashleymills 0:714293de3836 1266
ashleymills 0:714293de3836 1267 #ifdef KEEP_PEER_CERT
ashleymills 0:714293de3836 1268 InitX509(&ssl->peerCert, 0);
ashleymills 0:714293de3836 1269 #endif
ashleymills 0:714293de3836 1270
ashleymills 0:714293de3836 1271 #ifdef HAVE_ECC
ashleymills 0:714293de3836 1272 ssl->eccTempKeySz = ctx->eccTempKeySz;
ashleymills 0:714293de3836 1273 ssl->peerEccKeyPresent = 0;
ashleymills 0:714293de3836 1274 ssl->peerEccDsaKeyPresent = 0;
ashleymills 0:714293de3836 1275 ssl->eccDsaKeyPresent = 0;
ashleymills 0:714293de3836 1276 ssl->eccTempKeyPresent = 0;
ashleymills 0:714293de3836 1277 ssl->peerEccKey = NULL;
ashleymills 0:714293de3836 1278 ssl->peerEccDsaKey = NULL;
ashleymills 0:714293de3836 1279 ssl->eccDsaKey = NULL;
ashleymills 0:714293de3836 1280 ssl->eccTempKey = NULL;
ashleymills 0:714293de3836 1281 #endif
ashleymills 0:714293de3836 1282
ashleymills 0:714293de3836 1283 ssl->timeout = ctx->timeout;
ashleymills 0:714293de3836 1284 ssl->rfd = -1; /* set to invalid descriptor */
ashleymills 0:714293de3836 1285 ssl->wfd = -1;
ashleymills 0:714293de3836 1286 ssl->rflags = 0; /* no user flags yet */
ashleymills 0:714293de3836 1287 ssl->wflags = 0; /* no user flags yet */
ashleymills 0:714293de3836 1288 ssl->biord = 0;
ashleymills 0:714293de3836 1289 ssl->biowr = 0;
ashleymills 0:714293de3836 1290
ashleymills 0:714293de3836 1291 ssl->IOCB_ReadCtx = &ssl->rfd; /* prevent invalid pointer access if not */
ashleymills 0:714293de3836 1292 ssl->IOCB_WriteCtx = &ssl->wfd; /* correctly set */
ashleymills 0:714293de3836 1293 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 1294 ssl->IOCB_CookieCtx = NULL; /* we don't use for default cb */
ashleymills 0:714293de3836 1295 ssl->dtls_expected_rx = MAX_MTU;
ashleymills 0:714293de3836 1296 #endif
ashleymills 0:714293de3836 1297
ashleymills 0:714293de3836 1298 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 1299 #ifndef NO_MD5
ashleymills 0:714293de3836 1300 InitMd5(&ssl->hashMd5);
ashleymills 0:714293de3836 1301 #endif
ashleymills 0:714293de3836 1302 #ifndef NO_SHA
ashleymills 0:714293de3836 1303 InitSha(&ssl->hashSha);
ashleymills 0:714293de3836 1304 #endif
ashleymills 0:714293de3836 1305 #endif
ashleymills 0:714293de3836 1306 #ifndef NO_SHA256
ashleymills 0:714293de3836 1307 InitSha256(&ssl->hashSha256);
ashleymills 0:714293de3836 1308 #endif
ashleymills 0:714293de3836 1309 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 1310 InitSha384(&ssl->hashSha384);
ashleymills 0:714293de3836 1311 #endif
ashleymills 0:714293de3836 1312 #ifndef NO_RSA
ashleymills 0:714293de3836 1313 ssl->peerRsaKey = NULL;
ashleymills 0:714293de3836 1314 ssl->peerRsaKeyPresent = 0;
ashleymills 0:714293de3836 1315 #endif
ashleymills 0:714293de3836 1316 ssl->verifyCallback = ctx->verifyCallback;
ashleymills 0:714293de3836 1317 ssl->verifyCbCtx = NULL;
ashleymills 0:714293de3836 1318 ssl->options.side = ctx->method->side;
ashleymills 0:714293de3836 1319 ssl->options.downgrade = ctx->method->downgrade;
ashleymills 0:714293de3836 1320 ssl->error = 0;
ashleymills 0:714293de3836 1321 ssl->options.connReset = 0;
ashleymills 0:714293de3836 1322 ssl->options.isClosed = 0;
ashleymills 0:714293de3836 1323 ssl->options.closeNotify = 0;
ashleymills 0:714293de3836 1324 ssl->options.sentNotify = 0;
ashleymills 0:714293de3836 1325 ssl->options.usingCompression = 0;
ashleymills 0:714293de3836 1326 if (ssl->options.side == SERVER_END)
ashleymills 0:714293de3836 1327 ssl->options.haveDH = ctx->haveDH;
ashleymills 0:714293de3836 1328 else
ashleymills 0:714293de3836 1329 ssl->options.haveDH = 0;
ashleymills 0:714293de3836 1330 ssl->options.haveNTRU = ctx->haveNTRU;
ashleymills 0:714293de3836 1331 ssl->options.haveECDSAsig = ctx->haveECDSAsig;
ashleymills 0:714293de3836 1332 ssl->options.haveStaticECC = ctx->haveStaticECC;
ashleymills 0:714293de3836 1333 ssl->options.havePeerCert = 0;
ashleymills 0:714293de3836 1334 ssl->options.havePeerVerify = 0;
ashleymills 0:714293de3836 1335 ssl->options.usingPSK_cipher = 0;
ashleymills 0:714293de3836 1336 ssl->options.sendAlertState = 0;
ashleymills 0:714293de3836 1337 #ifndef NO_PSK
ashleymills 0:714293de3836 1338 havePSK = ctx->havePSK;
ashleymills 0:714293de3836 1339 ssl->options.havePSK = ctx->havePSK;
ashleymills 0:714293de3836 1340 ssl->options.client_psk_cb = ctx->client_psk_cb;
ashleymills 0:714293de3836 1341 ssl->options.server_psk_cb = ctx->server_psk_cb;
ashleymills 0:714293de3836 1342 #endif /* NO_PSK */
ashleymills 0:714293de3836 1343
ashleymills 0:714293de3836 1344 ssl->options.serverState = NULL_STATE;
ashleymills 0:714293de3836 1345 ssl->options.clientState = NULL_STATE;
ashleymills 0:714293de3836 1346 ssl->options.connectState = CONNECT_BEGIN;
ashleymills 0:714293de3836 1347 ssl->options.acceptState = ACCEPT_BEGIN;
ashleymills 0:714293de3836 1348 ssl->options.handShakeState = NULL_STATE;
ashleymills 0:714293de3836 1349 ssl->options.processReply = doProcessInit;
ashleymills 0:714293de3836 1350
ashleymills 0:714293de3836 1351 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 1352 ssl->keys.dtls_sequence_number = 0;
ashleymills 0:714293de3836 1353 ssl->keys.dtls_peer_sequence_number = 0;
ashleymills 0:714293de3836 1354 ssl->keys.dtls_expected_peer_sequence_number = 0;
ashleymills 0:714293de3836 1355 ssl->keys.dtls_handshake_number = 0;
ashleymills 0:714293de3836 1356 ssl->keys.dtls_expected_peer_handshake_number = 0;
ashleymills 0:714293de3836 1357 ssl->keys.dtls_epoch = 0;
ashleymills 0:714293de3836 1358 ssl->keys.dtls_peer_epoch = 0;
ashleymills 0:714293de3836 1359 ssl->keys.dtls_expected_peer_epoch = 0;
ashleymills 0:714293de3836 1360 ssl->dtls_timeout_init = DTLS_TIMEOUT_INIT;
ashleymills 0:714293de3836 1361 ssl->dtls_timeout_max = DTLS_TIMEOUT_MAX;
ashleymills 0:714293de3836 1362 ssl->dtls_timeout = ssl->dtls_timeout_init;
ashleymills 0:714293de3836 1363 ssl->dtls_pool = NULL;
ashleymills 0:714293de3836 1364 ssl->dtls_msg_list = NULL;
ashleymills 0:714293de3836 1365 #endif
ashleymills 0:714293de3836 1366 ssl->keys.encryptSz = 0;
ashleymills 0:714293de3836 1367 ssl->keys.encryptionOn = 0; /* initially off */
ashleymills 0:714293de3836 1368 ssl->keys.decryptedCur = 0; /* initially off */
ashleymills 0:714293de3836 1369 ssl->options.sessionCacheOff = ctx->sessionCacheOff;
ashleymills 0:714293de3836 1370 ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
ashleymills 0:714293de3836 1371
ashleymills 0:714293de3836 1372 ssl->options.verifyPeer = ctx->verifyPeer;
ashleymills 0:714293de3836 1373 ssl->options.verifyNone = ctx->verifyNone;
ashleymills 0:714293de3836 1374 ssl->options.failNoCert = ctx->failNoCert;
ashleymills 0:714293de3836 1375 ssl->options.sendVerify = ctx->sendVerify;
ashleymills 0:714293de3836 1376
ashleymills 0:714293de3836 1377 ssl->options.resuming = 0;
ashleymills 0:714293de3836 1378 ssl->options.haveSessionId = 0;
ashleymills 0:714293de3836 1379 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 1380 ssl->hmac = Hmac; /* default to SSLv3 */
ashleymills 0:714293de3836 1381 #else
ashleymills 0:714293de3836 1382 ssl->hmac = TLS_hmac;
ashleymills 0:714293de3836 1383 #endif
ashleymills 0:714293de3836 1384 ssl->heap = ctx->heap; /* defaults to self */
ashleymills 0:714293de3836 1385 ssl->options.tls = 0;
ashleymills 0:714293de3836 1386 ssl->options.tls1_1 = 0;
ashleymills 0:714293de3836 1387 ssl->options.dtls = ssl->version.major == DTLS_MAJOR;
ashleymills 0:714293de3836 1388 ssl->options.partialWrite = ctx->partialWrite;
ashleymills 0:714293de3836 1389 ssl->options.quietShutdown = ctx->quietShutdown;
ashleymills 0:714293de3836 1390 ssl->options.certOnly = 0;
ashleymills 0:714293de3836 1391 ssl->options.groupMessages = ctx->groupMessages;
ashleymills 0:714293de3836 1392 ssl->options.usingNonblock = 0;
ashleymills 0:714293de3836 1393 ssl->options.saveArrays = 0;
ashleymills 0:714293de3836 1394
ashleymills 0:714293de3836 1395 #ifndef NO_CERTS
ashleymills 0:714293de3836 1396 /* ctx still owns certificate, certChain, key, dh, and cm */
ashleymills 0:714293de3836 1397 ssl->buffers.certificate = ctx->certificate;
ashleymills 0:714293de3836 1398 ssl->buffers.certChain = ctx->certChain;
ashleymills 0:714293de3836 1399 ssl->buffers.key = ctx->privateKey;
ashleymills 0:714293de3836 1400 if (ssl->options.side == SERVER_END) {
ashleymills 0:714293de3836 1401 ssl->buffers.serverDH_P = ctx->serverDH_P;
ashleymills 0:714293de3836 1402 ssl->buffers.serverDH_G = ctx->serverDH_G;
ashleymills 0:714293de3836 1403 }
ashleymills 0:714293de3836 1404 #endif
ashleymills 0:714293de3836 1405 ssl->buffers.weOwnCert = 0;
ashleymills 0:714293de3836 1406 ssl->buffers.weOwnKey = 0;
ashleymills 0:714293de3836 1407 ssl->buffers.weOwnDH = 0;
ashleymills 0:714293de3836 1408
ashleymills 0:714293de3836 1409 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 1410 ssl->buffers.dtlsCtx.fd = -1;
ashleymills 0:714293de3836 1411 ssl->buffers.dtlsCtx.peer.sa = NULL;
ashleymills 0:714293de3836 1412 ssl->buffers.dtlsCtx.peer.sz = 0;
ashleymills 0:714293de3836 1413 #endif
ashleymills 0:714293de3836 1414
ashleymills 0:714293de3836 1415 #ifdef KEEP_PEER_CERT
ashleymills 0:714293de3836 1416 ssl->peerCert.issuer.sz = 0;
ashleymills 0:714293de3836 1417 ssl->peerCert.subject.sz = 0;
ashleymills 0:714293de3836 1418 #endif
ashleymills 0:714293de3836 1419
ashleymills 0:714293de3836 1420 #ifdef SESSION_CERTS
ashleymills 0:714293de3836 1421 ssl->session.chain.count = 0;
ashleymills 0:714293de3836 1422 #endif
ashleymills 0:714293de3836 1423
ashleymills 0:714293de3836 1424 #ifndef NO_CLIENT_CACHE
ashleymills 0:714293de3836 1425 ssl->session.idLen = 0;
ashleymills 0:714293de3836 1426 #endif
ashleymills 0:714293de3836 1427
ashleymills 0:714293de3836 1428 ssl->cipher.ssl = ssl;
ashleymills 0:714293de3836 1429
ashleymills 0:714293de3836 1430 #ifdef FORTRESS
ashleymills 0:714293de3836 1431 ssl->ex_data[0] = 0;
ashleymills 0:714293de3836 1432 ssl->ex_data[1] = 0;
ashleymills 0:714293de3836 1433 ssl->ex_data[2] = 0;
ashleymills 0:714293de3836 1434 #endif
ashleymills 0:714293de3836 1435
ashleymills 0:714293de3836 1436 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 1437 ssl->hsInfoOn = 0;
ashleymills 0:714293de3836 1438 ssl->toInfoOn = 0;
ashleymills 0:714293de3836 1439 #endif
ashleymills 0:714293de3836 1440
ashleymills 0:714293de3836 1441 #ifdef HAVE_CAVIUM
ashleymills 0:714293de3836 1442 ssl->devId = ctx->devId;
ashleymills 0:714293de3836 1443 #endif
ashleymills 0:714293de3836 1444
ashleymills 0:714293de3836 1445 #ifdef HAVE_TLS_EXTENSIONS
ashleymills 0:714293de3836 1446 ssl->extensions = NULL;
ashleymills 0:714293de3836 1447 #endif
ashleymills 0:714293de3836 1448
ashleymills 0:714293de3836 1449 ssl->rng = NULL;
ashleymills 0:714293de3836 1450 ssl->arrays = NULL;
ashleymills 0:714293de3836 1451
ashleymills 0:714293de3836 1452 /* default alert state (none) */
ashleymills 0:714293de3836 1453 ssl->alert_history.last_rx.code = -1;
ashleymills 0:714293de3836 1454 ssl->alert_history.last_rx.level = -1;
ashleymills 0:714293de3836 1455 ssl->alert_history.last_tx.code = -1;
ashleymills 0:714293de3836 1456 ssl->alert_history.last_tx.level = -1;
ashleymills 0:714293de3836 1457
ashleymills 0:714293de3836 1458 InitCiphers(ssl);
ashleymills 0:714293de3836 1459 InitCipherSpecs(&ssl->specs);
ashleymills 0:714293de3836 1460 /* all done with init, now can return errors, call other stuff */
ashleymills 0:714293de3836 1461
ashleymills 0:714293de3836 1462 /* increment CTX reference count */
ashleymills 0:714293de3836 1463 if (LockMutex(&ctx->countMutex) != 0) {
ashleymills 0:714293de3836 1464 CYASSL_MSG("Couldn't lock CTX count mutex");
ashleymills 0:714293de3836 1465 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 1466 }
ashleymills 0:714293de3836 1467 ctx->refCount++;
ashleymills 0:714293de3836 1468 UnLockMutex(&ctx->countMutex);
ashleymills 0:714293de3836 1469
ashleymills 0:714293de3836 1470 /* arrays */
ashleymills 0:714293de3836 1471 ssl->arrays = (Arrays*)XMALLOC(sizeof(Arrays), ssl->heap,
ashleymills 0:714293de3836 1472 DYNAMIC_TYPE_ARRAYS);
ashleymills 0:714293de3836 1473 if (ssl->arrays == NULL) {
ashleymills 0:714293de3836 1474 CYASSL_MSG("Arrays Memory error");
ashleymills 0:714293de3836 1475 return MEMORY_E;
ashleymills 0:714293de3836 1476 }
ashleymills 0:714293de3836 1477
ashleymills 0:714293de3836 1478 #ifndef NO_PSK
ashleymills 0:714293de3836 1479 ssl->arrays->client_identity[0] = 0;
ashleymills 0:714293de3836 1480 if (ctx->server_hint[0]) { /* set in CTX */
ashleymills 0:714293de3836 1481 XSTRNCPY(ssl->arrays->server_hint, ctx->server_hint, MAX_PSK_ID_LEN);
ashleymills 0:714293de3836 1482 ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
ashleymills 0:714293de3836 1483 }
ashleymills 0:714293de3836 1484 else
ashleymills 0:714293de3836 1485 ssl->arrays->server_hint[0] = 0;
ashleymills 0:714293de3836 1486 #endif /* NO_PSK */
ashleymills 0:714293de3836 1487
ashleymills 0:714293de3836 1488 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 1489 ssl->arrays->cookieSz = 0;
ashleymills 0:714293de3836 1490 #endif
ashleymills 0:714293de3836 1491
ashleymills 0:714293de3836 1492 /* RNG */
ashleymills 0:714293de3836 1493 ssl->rng = (RNG*)XMALLOC(sizeof(RNG), ssl->heap, DYNAMIC_TYPE_RNG);
ashleymills 0:714293de3836 1494 if (ssl->rng == NULL) {
ashleymills 0:714293de3836 1495 CYASSL_MSG("RNG Memory error");
ashleymills 0:714293de3836 1496 return MEMORY_E;
ashleymills 0:714293de3836 1497 }
ashleymills 0:714293de3836 1498
ashleymills 0:714293de3836 1499 if ( (ret = InitRng(ssl->rng)) != 0) {
ashleymills 0:714293de3836 1500 CYASSL_MSG("RNG Init error");
ashleymills 0:714293de3836 1501 return ret;
ashleymills 0:714293de3836 1502 }
ashleymills 0:714293de3836 1503
ashleymills 0:714293de3836 1504 /* suites */
ashleymills 0:714293de3836 1505 ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
ashleymills 0:714293de3836 1506 DYNAMIC_TYPE_SUITES);
ashleymills 0:714293de3836 1507 if (ssl->suites == NULL) {
ashleymills 0:714293de3836 1508 CYASSL_MSG("Suites Memory error");
ashleymills 0:714293de3836 1509 return MEMORY_E;
ashleymills 0:714293de3836 1510 }
ashleymills 0:714293de3836 1511 *ssl->suites = ctx->suites;
ashleymills 0:714293de3836 1512
ashleymills 0:714293de3836 1513 /* peer key */
ashleymills 0:714293de3836 1514 #ifndef NO_RSA
ashleymills 0:714293de3836 1515 ssl->peerRsaKey = (RsaKey*)XMALLOC(sizeof(RsaKey), ssl->heap,
ashleymills 0:714293de3836 1516 DYNAMIC_TYPE_RSA);
ashleymills 0:714293de3836 1517 if (ssl->peerRsaKey == NULL) {
ashleymills 0:714293de3836 1518 CYASSL_MSG("PeerRsaKey Memory error");
ashleymills 0:714293de3836 1519 return MEMORY_E;
ashleymills 0:714293de3836 1520 }
ashleymills 0:714293de3836 1521 InitRsaKey(ssl->peerRsaKey, ctx->heap);
ashleymills 0:714293de3836 1522 #endif
ashleymills 0:714293de3836 1523 #ifndef NO_CERTS
ashleymills 0:714293de3836 1524 /* make sure server has cert and key unless using PSK */
ashleymills 0:714293de3836 1525 if (ssl->options.side == SERVER_END && !havePSK)
ashleymills 0:714293de3836 1526 if (!ssl->buffers.certificate.buffer || !ssl->buffers.key.buffer) {
ashleymills 0:714293de3836 1527 CYASSL_MSG("Server missing certificate and/or private key");
ashleymills 0:714293de3836 1528 return NO_PRIVATE_KEY;
ashleymills 0:714293de3836 1529 }
ashleymills 0:714293de3836 1530 #endif
ashleymills 0:714293de3836 1531 #ifdef HAVE_ECC
ashleymills 0:714293de3836 1532 ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ashleymills 0:714293de3836 1533 ctx->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:714293de3836 1534 if (ssl->peerEccKey == NULL) {
ashleymills 0:714293de3836 1535 CYASSL_MSG("PeerEccKey Memory error");
ashleymills 0:714293de3836 1536 return MEMORY_E;
ashleymills 0:714293de3836 1537 }
ashleymills 0:714293de3836 1538 ssl->peerEccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ashleymills 0:714293de3836 1539 ctx->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:714293de3836 1540 if (ssl->peerEccDsaKey == NULL) {
ashleymills 0:714293de3836 1541 CYASSL_MSG("PeerEccDsaKey Memory error");
ashleymills 0:714293de3836 1542 return MEMORY_E;
ashleymills 0:714293de3836 1543 }
ashleymills 0:714293de3836 1544 ssl->eccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ashleymills 0:714293de3836 1545 ctx->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:714293de3836 1546 if (ssl->eccDsaKey == NULL) {
ashleymills 0:714293de3836 1547 CYASSL_MSG("EccDsaKey Memory error");
ashleymills 0:714293de3836 1548 return MEMORY_E;
ashleymills 0:714293de3836 1549 }
ashleymills 0:714293de3836 1550 ssl->eccTempKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ashleymills 0:714293de3836 1551 ctx->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:714293de3836 1552 if (ssl->eccTempKey == NULL) {
ashleymills 0:714293de3836 1553 CYASSL_MSG("EccTempKey Memory error");
ashleymills 0:714293de3836 1554 return MEMORY_E;
ashleymills 0:714293de3836 1555 }
ashleymills 0:714293de3836 1556 ecc_init(ssl->peerEccKey);
ashleymills 0:714293de3836 1557 ecc_init(ssl->peerEccDsaKey);
ashleymills 0:714293de3836 1558 ecc_init(ssl->eccDsaKey);
ashleymills 0:714293de3836 1559 ecc_init(ssl->eccTempKey);
ashleymills 0:714293de3836 1560 #endif
ashleymills 0:714293de3836 1561
ashleymills 0:714293de3836 1562 /* make sure server has DH parms, and add PSK if there, add NTRU too */
ashleymills 0:714293de3836 1563 if (ssl->options.side == SERVER_END)
ashleymills 0:714293de3836 1564 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
ashleymills 0:714293de3836 1565 ssl->options.haveDH, ssl->options.haveNTRU,
ashleymills 0:714293de3836 1566 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
ashleymills 0:714293de3836 1567 ssl->options.side);
ashleymills 0:714293de3836 1568 else
ashleymills 0:714293de3836 1569 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, TRUE,
ashleymills 0:714293de3836 1570 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
ashleymills 0:714293de3836 1571 ssl->options.haveStaticECC, ssl->options.side);
ashleymills 0:714293de3836 1572
ashleymills 0:714293de3836 1573 return 0;
ashleymills 0:714293de3836 1574 }
ashleymills 0:714293de3836 1575
ashleymills 0:714293de3836 1576
ashleymills 0:714293de3836 1577 /* free use of temporary arrays */
ashleymills 0:714293de3836 1578 void FreeArrays(CYASSL* ssl, int keep)
ashleymills 0:714293de3836 1579 {
ashleymills 0:714293de3836 1580 if (ssl->arrays && keep) {
ashleymills 0:714293de3836 1581 /* keeps session id for user retrieval */
ashleymills 0:714293de3836 1582 XMEMCPY(ssl->session.sessionID, ssl->arrays->sessionID, ID_LEN);
ashleymills 0:714293de3836 1583 }
ashleymills 0:714293de3836 1584 XFREE(ssl->arrays, ssl->heap, DYNAMIC_TYPE_ARRAYS);
ashleymills 0:714293de3836 1585 ssl->arrays = NULL;
ashleymills 0:714293de3836 1586 }
ashleymills 0:714293de3836 1587
ashleymills 0:714293de3836 1588
ashleymills 0:714293de3836 1589 /* In case holding SSL object in array and don't want to free actual ssl */
ashleymills 0:714293de3836 1590 void SSL_ResourceFree(CYASSL* ssl)
ashleymills 0:714293de3836 1591 {
ashleymills 0:714293de3836 1592 FreeCiphers(ssl);
ashleymills 0:714293de3836 1593 FreeArrays(ssl, 0);
ashleymills 0:714293de3836 1594 XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
ashleymills 0:714293de3836 1595 XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
ashleymills 0:714293de3836 1596 XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
ashleymills 0:714293de3836 1597
ashleymills 0:714293de3836 1598 #ifndef NO_CERTS
ashleymills 0:714293de3836 1599 XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
ashleymills 0:714293de3836 1600 XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH);
ashleymills 0:714293de3836 1601 /* parameters (p,g) may be owned by ctx */
ashleymills 0:714293de3836 1602 if (ssl->buffers.weOwnDH || ssl->options.side == CLIENT_END) {
ashleymills 0:714293de3836 1603 XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
ashleymills 0:714293de3836 1604 XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
ashleymills 0:714293de3836 1605 }
ashleymills 0:714293de3836 1606
ashleymills 0:714293de3836 1607 /* CYASSL_CTX always owns certChain */
ashleymills 0:714293de3836 1608 if (ssl->buffers.weOwnCert)
ashleymills 0:714293de3836 1609 XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
ashleymills 0:714293de3836 1610 if (ssl->buffers.weOwnKey)
ashleymills 0:714293de3836 1611 XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
ashleymills 0:714293de3836 1612 #endif
ashleymills 0:714293de3836 1613 #ifndef NO_RSA
ashleymills 0:714293de3836 1614 if (ssl->peerRsaKey) {
ashleymills 0:714293de3836 1615 FreeRsaKey(ssl->peerRsaKey);
ashleymills 0:714293de3836 1616 XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
ashleymills 0:714293de3836 1617 }
ashleymills 0:714293de3836 1618 #endif
ashleymills 0:714293de3836 1619 if (ssl->buffers.inputBuffer.dynamicFlag)
ashleymills 0:714293de3836 1620 ShrinkInputBuffer(ssl, FORCED_FREE);
ashleymills 0:714293de3836 1621 if (ssl->buffers.outputBuffer.dynamicFlag)
ashleymills 0:714293de3836 1622 ShrinkOutputBuffer(ssl);
ashleymills 0:714293de3836 1623 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 1624 if (ssl->dtls_pool != NULL) {
ashleymills 0:714293de3836 1625 DtlsPoolReset(ssl);
ashleymills 0:714293de3836 1626 XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_NONE);
ashleymills 0:714293de3836 1627 }
ashleymills 0:714293de3836 1628 if (ssl->dtls_msg_list != NULL) {
ashleymills 0:714293de3836 1629 DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
ashleymills 0:714293de3836 1630 ssl->dtls_msg_list = NULL;
ashleymills 0:714293de3836 1631 }
ashleymills 0:714293de3836 1632 XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
ashleymills 0:714293de3836 1633 ssl->buffers.dtlsCtx.peer.sa = NULL;
ashleymills 0:714293de3836 1634 #endif
ashleymills 0:714293de3836 1635 #if defined(KEEP_PEER_CERT) || defined(GOAHEAD_WS)
ashleymills 0:714293de3836 1636 FreeX509(&ssl->peerCert);
ashleymills 0:714293de3836 1637 #endif
ashleymills 0:714293de3836 1638 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
ashleymills 0:714293de3836 1639 CyaSSL_BIO_free(ssl->biord);
ashleymills 0:714293de3836 1640 if (ssl->biord != ssl->biowr) /* in case same as write */
ashleymills 0:714293de3836 1641 CyaSSL_BIO_free(ssl->biowr);
ashleymills 0:714293de3836 1642 #endif
ashleymills 0:714293de3836 1643 #ifdef HAVE_LIBZ
ashleymills 0:714293de3836 1644 FreeStreams(ssl);
ashleymills 0:714293de3836 1645 #endif
ashleymills 0:714293de3836 1646 #ifdef HAVE_ECC
ashleymills 0:714293de3836 1647 if (ssl->peerEccKey) {
ashleymills 0:714293de3836 1648 if (ssl->peerEccKeyPresent)
ashleymills 0:714293de3836 1649 ecc_free(ssl->peerEccKey);
ashleymills 0:714293de3836 1650 XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:714293de3836 1651 }
ashleymills 0:714293de3836 1652 if (ssl->peerEccDsaKey) {
ashleymills 0:714293de3836 1653 if (ssl->peerEccDsaKeyPresent)
ashleymills 0:714293de3836 1654 ecc_free(ssl->peerEccDsaKey);
ashleymills 0:714293de3836 1655 XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:714293de3836 1656 }
ashleymills 0:714293de3836 1657 if (ssl->eccTempKey) {
ashleymills 0:714293de3836 1658 if (ssl->eccTempKeyPresent)
ashleymills 0:714293de3836 1659 ecc_free(ssl->eccTempKey);
ashleymills 0:714293de3836 1660 XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:714293de3836 1661 }
ashleymills 0:714293de3836 1662 if (ssl->eccDsaKey) {
ashleymills 0:714293de3836 1663 if (ssl->eccDsaKeyPresent)
ashleymills 0:714293de3836 1664 ecc_free(ssl->eccDsaKey);
ashleymills 0:714293de3836 1665 XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:714293de3836 1666 }
ashleymills 0:714293de3836 1667 #endif
ashleymills 0:714293de3836 1668 #ifdef HAVE_TLS_EXTENSIONS
ashleymills 0:714293de3836 1669 TLSX_FreeAll(ssl->extensions);
ashleymills 0:714293de3836 1670 #endif
ashleymills 0:714293de3836 1671 }
ashleymills 0:714293de3836 1672
ashleymills 0:714293de3836 1673
ashleymills 0:714293de3836 1674 /* Free any handshake resources no longer needed */
ashleymills 0:714293de3836 1675 void FreeHandshakeResources(CYASSL* ssl)
ashleymills 0:714293de3836 1676 {
ashleymills 0:714293de3836 1677 /* input buffer */
ashleymills 0:714293de3836 1678 if (ssl->buffers.inputBuffer.dynamicFlag)
ashleymills 0:714293de3836 1679 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
ashleymills 0:714293de3836 1680
ashleymills 0:714293de3836 1681 /* suites */
ashleymills 0:714293de3836 1682 XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
ashleymills 0:714293de3836 1683 ssl->suites = NULL;
ashleymills 0:714293de3836 1684
ashleymills 0:714293de3836 1685 /* RNG */
ashleymills 0:714293de3836 1686 if (ssl->specs.cipher_type == stream || ssl->options.tls1_1 == 0) {
ashleymills 0:714293de3836 1687 XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
ashleymills 0:714293de3836 1688 ssl->rng = NULL;
ashleymills 0:714293de3836 1689 }
ashleymills 0:714293de3836 1690
ashleymills 0:714293de3836 1691 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 1692 /* DTLS_POOL */
ashleymills 0:714293de3836 1693 if (ssl->options.dtls && ssl->dtls_pool != NULL) {
ashleymills 0:714293de3836 1694 DtlsPoolReset(ssl);
ashleymills 0:714293de3836 1695 XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
ashleymills 0:714293de3836 1696 ssl->dtls_pool = NULL;
ashleymills 0:714293de3836 1697 }
ashleymills 0:714293de3836 1698 #endif
ashleymills 0:714293de3836 1699
ashleymills 0:714293de3836 1700 /* arrays */
ashleymills 0:714293de3836 1701 if (ssl->options.saveArrays)
ashleymills 0:714293de3836 1702 FreeArrays(ssl, 1);
ashleymills 0:714293de3836 1703
ashleymills 0:714293de3836 1704 #ifndef NO_RSA
ashleymills 0:714293de3836 1705 /* peerRsaKey */
ashleymills 0:714293de3836 1706 if (ssl->peerRsaKey) {
ashleymills 0:714293de3836 1707 FreeRsaKey(ssl->peerRsaKey);
ashleymills 0:714293de3836 1708 XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
ashleymills 0:714293de3836 1709 ssl->peerRsaKey = NULL;
ashleymills 0:714293de3836 1710 }
ashleymills 0:714293de3836 1711 #endif
ashleymills 0:714293de3836 1712
ashleymills 0:714293de3836 1713 #ifdef HAVE_ECC
ashleymills 0:714293de3836 1714 if (ssl->peerEccKey)
ashleymills 0:714293de3836 1715 {
ashleymills 0:714293de3836 1716 if (ssl->peerEccKeyPresent) {
ashleymills 0:714293de3836 1717 ecc_free(ssl->peerEccKey);
ashleymills 0:714293de3836 1718 ssl->peerEccKeyPresent = 0;
ashleymills 0:714293de3836 1719 }
ashleymills 0:714293de3836 1720 XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:714293de3836 1721 ssl->peerEccKey = NULL;
ashleymills 0:714293de3836 1722 }
ashleymills 0:714293de3836 1723 if (ssl->peerEccDsaKey)
ashleymills 0:714293de3836 1724 {
ashleymills 0:714293de3836 1725 if (ssl->peerEccDsaKeyPresent) {
ashleymills 0:714293de3836 1726 ecc_free(ssl->peerEccDsaKey);
ashleymills 0:714293de3836 1727 ssl->peerEccDsaKeyPresent = 0;
ashleymills 0:714293de3836 1728 }
ashleymills 0:714293de3836 1729 XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:714293de3836 1730 ssl->peerEccDsaKey = NULL;
ashleymills 0:714293de3836 1731 }
ashleymills 0:714293de3836 1732 if (ssl->eccTempKey)
ashleymills 0:714293de3836 1733 {
ashleymills 0:714293de3836 1734 if (ssl->eccTempKeyPresent) {
ashleymills 0:714293de3836 1735 ecc_free(ssl->eccTempKey);
ashleymills 0:714293de3836 1736 ssl->eccTempKeyPresent = 0;
ashleymills 0:714293de3836 1737 }
ashleymills 0:714293de3836 1738 XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:714293de3836 1739 ssl->eccTempKey = NULL;
ashleymills 0:714293de3836 1740 }
ashleymills 0:714293de3836 1741 if (ssl->eccDsaKey)
ashleymills 0:714293de3836 1742 {
ashleymills 0:714293de3836 1743 if (ssl->eccDsaKeyPresent) {
ashleymills 0:714293de3836 1744 ecc_free(ssl->eccDsaKey);
ashleymills 0:714293de3836 1745 ssl->eccDsaKeyPresent = 0;
ashleymills 0:714293de3836 1746 }
ashleymills 0:714293de3836 1747 XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:714293de3836 1748 ssl->eccDsaKey = NULL;
ashleymills 0:714293de3836 1749 }
ashleymills 0:714293de3836 1750 #endif
ashleymills 0:714293de3836 1751 }
ashleymills 0:714293de3836 1752
ashleymills 0:714293de3836 1753
ashleymills 0:714293de3836 1754 void FreeSSL(CYASSL* ssl)
ashleymills 0:714293de3836 1755 {
ashleymills 0:714293de3836 1756 FreeSSL_Ctx(ssl->ctx); /* will decrement and free underyling CTX if 0 */
ashleymills 0:714293de3836 1757 SSL_ResourceFree(ssl);
ashleymills 0:714293de3836 1758 XFREE(ssl, ssl->heap, DYNAMIC_TYPE_SSL);
ashleymills 0:714293de3836 1759 }
ashleymills 0:714293de3836 1760
ashleymills 0:714293de3836 1761
ashleymills 0:714293de3836 1762 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 1763
ashleymills 0:714293de3836 1764 int DtlsPoolInit(CYASSL* ssl)
ashleymills 0:714293de3836 1765 {
ashleymills 0:714293de3836 1766 if (ssl->dtls_pool == NULL) {
ashleymills 0:714293de3836 1767 DtlsPool *pool = (DtlsPool*)XMALLOC(sizeof(DtlsPool),
ashleymills 0:714293de3836 1768 ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
ashleymills 0:714293de3836 1769 if (pool == NULL) {
ashleymills 0:714293de3836 1770 CYASSL_MSG("DTLS Buffer Pool Memory error");
ashleymills 0:714293de3836 1771 return MEMORY_E;
ashleymills 0:714293de3836 1772 }
ashleymills 0:714293de3836 1773 else {
ashleymills 0:714293de3836 1774 int i;
ashleymills 0:714293de3836 1775
ashleymills 0:714293de3836 1776 for (i = 0; i < DTLS_POOL_SZ; i++) {
ashleymills 0:714293de3836 1777 pool->buf[i].length = 0;
ashleymills 0:714293de3836 1778 pool->buf[i].buffer = NULL;
ashleymills 0:714293de3836 1779 }
ashleymills 0:714293de3836 1780 pool->used = 0;
ashleymills 0:714293de3836 1781 ssl->dtls_pool = pool;
ashleymills 0:714293de3836 1782 }
ashleymills 0:714293de3836 1783 }
ashleymills 0:714293de3836 1784 return 0;
ashleymills 0:714293de3836 1785 }
ashleymills 0:714293de3836 1786
ashleymills 0:714293de3836 1787
ashleymills 0:714293de3836 1788 int DtlsPoolSave(CYASSL* ssl, const byte *src, int sz)
ashleymills 0:714293de3836 1789 {
ashleymills 0:714293de3836 1790 DtlsPool *pool = ssl->dtls_pool;
ashleymills 0:714293de3836 1791 if (pool != NULL && pool->used < DTLS_POOL_SZ) {
ashleymills 0:714293de3836 1792 buffer *pBuf = &pool->buf[pool->used];
ashleymills 0:714293de3836 1793 pBuf->buffer = (byte*)XMALLOC(sz, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
ashleymills 0:714293de3836 1794 if (pBuf->buffer == NULL) {
ashleymills 0:714293de3836 1795 CYASSL_MSG("DTLS Buffer Memory error");
ashleymills 0:714293de3836 1796 return MEMORY_ERROR;
ashleymills 0:714293de3836 1797 }
ashleymills 0:714293de3836 1798 XMEMCPY(pBuf->buffer, src, sz);
ashleymills 0:714293de3836 1799 pBuf->length = (word32)sz;
ashleymills 0:714293de3836 1800 pool->used++;
ashleymills 0:714293de3836 1801 }
ashleymills 0:714293de3836 1802 return 0;
ashleymills 0:714293de3836 1803 }
ashleymills 0:714293de3836 1804
ashleymills 0:714293de3836 1805
ashleymills 0:714293de3836 1806 void DtlsPoolReset(CYASSL* ssl)
ashleymills 0:714293de3836 1807 {
ashleymills 0:714293de3836 1808 DtlsPool *pool = ssl->dtls_pool;
ashleymills 0:714293de3836 1809 if (pool != NULL) {
ashleymills 0:714293de3836 1810 buffer *pBuf;
ashleymills 0:714293de3836 1811 int i, used;
ashleymills 0:714293de3836 1812
ashleymills 0:714293de3836 1813 used = pool->used;
ashleymills 0:714293de3836 1814 for (i = 0, pBuf = &pool->buf[0]; i < used; i++, pBuf++) {
ashleymills 0:714293de3836 1815 XFREE(pBuf->buffer, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
ashleymills 0:714293de3836 1816 pBuf->buffer = NULL;
ashleymills 0:714293de3836 1817 pBuf->length = 0;
ashleymills 0:714293de3836 1818 }
ashleymills 0:714293de3836 1819 pool->used = 0;
ashleymills 0:714293de3836 1820 }
ashleymills 0:714293de3836 1821 ssl->dtls_timeout = ssl->dtls_timeout_init;
ashleymills 0:714293de3836 1822 }
ashleymills 0:714293de3836 1823
ashleymills 0:714293de3836 1824
ashleymills 0:714293de3836 1825 int DtlsPoolTimeout(CYASSL* ssl)
ashleymills 0:714293de3836 1826 {
ashleymills 0:714293de3836 1827 int result = -1;
ashleymills 0:714293de3836 1828 if (ssl->dtls_timeout < ssl->dtls_timeout_max) {
ashleymills 0:714293de3836 1829 ssl->dtls_timeout *= DTLS_TIMEOUT_MULTIPLIER;
ashleymills 0:714293de3836 1830 result = 0;
ashleymills 0:714293de3836 1831 }
ashleymills 0:714293de3836 1832 return result;
ashleymills 0:714293de3836 1833 }
ashleymills 0:714293de3836 1834
ashleymills 0:714293de3836 1835
ashleymills 0:714293de3836 1836 int DtlsPoolSend(CYASSL* ssl)
ashleymills 0:714293de3836 1837 {
ashleymills 0:714293de3836 1838 int ret;
ashleymills 0:714293de3836 1839 DtlsPool *pool = ssl->dtls_pool;
ashleymills 0:714293de3836 1840
ashleymills 0:714293de3836 1841 if (pool != NULL && pool->used > 0) {
ashleymills 0:714293de3836 1842 int i;
ashleymills 0:714293de3836 1843 for (i = 0; i < pool->used; i++) {
ashleymills 0:714293de3836 1844 int sendResult;
ashleymills 0:714293de3836 1845 buffer* buf = &pool->buf[i];
ashleymills 0:714293de3836 1846
ashleymills 0:714293de3836 1847 DtlsRecordLayerHeader* dtls = (DtlsRecordLayerHeader*)buf->buffer;
ashleymills 0:714293de3836 1848
ashleymills 0:714293de3836 1849 word16 message_epoch;
ashleymills 0:714293de3836 1850 ato16(dtls->epoch, &message_epoch);
ashleymills 0:714293de3836 1851 if (message_epoch == ssl->keys.dtls_epoch) {
ashleymills 0:714293de3836 1852 /* Increment record sequence number on retransmitted handshake
ashleymills 0:714293de3836 1853 * messages */
ashleymills 0:714293de3836 1854 c32to48(ssl->keys.dtls_sequence_number, dtls->sequence_number);
ashleymills 0:714293de3836 1855 ssl->keys.dtls_sequence_number++;
ashleymills 0:714293de3836 1856 }
ashleymills 0:714293de3836 1857 else {
ashleymills 0:714293de3836 1858 /* The Finished message is sent with the next epoch, keep its
ashleymills 0:714293de3836 1859 * sequence number */
ashleymills 0:714293de3836 1860 }
ashleymills 0:714293de3836 1861
ashleymills 0:714293de3836 1862 if ((ret = CheckAvailableSize(ssl, buf->length)) != 0)
ashleymills 0:714293de3836 1863 return ret;
ashleymills 0:714293de3836 1864
ashleymills 0:714293de3836 1865 XMEMCPY(ssl->buffers.outputBuffer.buffer, buf->buffer, buf->length);
ashleymills 0:714293de3836 1866 ssl->buffers.outputBuffer.idx = 0;
ashleymills 0:714293de3836 1867 ssl->buffers.outputBuffer.length = buf->length;
ashleymills 0:714293de3836 1868
ashleymills 0:714293de3836 1869 sendResult = SendBuffered(ssl);
ashleymills 0:714293de3836 1870 if (sendResult < 0) {
ashleymills 0:714293de3836 1871 return sendResult;
ashleymills 0:714293de3836 1872 }
ashleymills 0:714293de3836 1873 }
ashleymills 0:714293de3836 1874 }
ashleymills 0:714293de3836 1875 return 0;
ashleymills 0:714293de3836 1876 }
ashleymills 0:714293de3836 1877
ashleymills 0:714293de3836 1878
ashleymills 0:714293de3836 1879 /* functions for managing DTLS datagram reordering */
ashleymills 0:714293de3836 1880
ashleymills 0:714293de3836 1881 /* Need to allocate space for the handshake message header. The hashing
ashleymills 0:714293de3836 1882 * routines assume the message pointer is still within the buffer that
ashleymills 0:714293de3836 1883 * has the headers, and will include those headers in the hash. The store
ashleymills 0:714293de3836 1884 * routines need to take that into account as well. New will allocate
ashleymills 0:714293de3836 1885 * extra space for the headers. */
ashleymills 0:714293de3836 1886 DtlsMsg* DtlsMsgNew(word32 sz, void* heap)
ashleymills 0:714293de3836 1887 {
ashleymills 0:714293de3836 1888 DtlsMsg* msg = NULL;
ashleymills 0:714293de3836 1889
ashleymills 0:714293de3836 1890 msg = (DtlsMsg*)XMALLOC(sizeof(DtlsMsg), heap, DYNAMIC_TYPE_DTLS_MSG);
ashleymills 0:714293de3836 1891
ashleymills 0:714293de3836 1892 if (msg != NULL) {
ashleymills 0:714293de3836 1893 msg->buf = (byte*)XMALLOC(sz + DTLS_HANDSHAKE_HEADER_SZ,
ashleymills 0:714293de3836 1894 heap, DYNAMIC_TYPE_NONE);
ashleymills 0:714293de3836 1895 if (msg->buf != NULL) {
ashleymills 0:714293de3836 1896 msg->next = NULL;
ashleymills 0:714293de3836 1897 msg->seq = 0;
ashleymills 0:714293de3836 1898 msg->sz = sz;
ashleymills 0:714293de3836 1899 msg->fragSz = 0;
ashleymills 0:714293de3836 1900 msg->msg = msg->buf + DTLS_HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 1901 }
ashleymills 0:714293de3836 1902 else {
ashleymills 0:714293de3836 1903 XFREE(msg, heap, DYNAMIC_TYPE_DTLS_MSG);
ashleymills 0:714293de3836 1904 msg = NULL;
ashleymills 0:714293de3836 1905 }
ashleymills 0:714293de3836 1906 }
ashleymills 0:714293de3836 1907
ashleymills 0:714293de3836 1908 return msg;
ashleymills 0:714293de3836 1909 }
ashleymills 0:714293de3836 1910
ashleymills 0:714293de3836 1911 void DtlsMsgDelete(DtlsMsg* item, void* heap)
ashleymills 0:714293de3836 1912 {
ashleymills 0:714293de3836 1913 (void)heap;
ashleymills 0:714293de3836 1914
ashleymills 0:714293de3836 1915 if (item != NULL) {
ashleymills 0:714293de3836 1916 if (item->buf != NULL)
ashleymills 0:714293de3836 1917 XFREE(item->buf, heap, DYNAMIC_TYPE_NONE);
ashleymills 0:714293de3836 1918 XFREE(item, heap, DYNAMIC_TYPE_DTLS_MSG);
ashleymills 0:714293de3836 1919 }
ashleymills 0:714293de3836 1920 }
ashleymills 0:714293de3836 1921
ashleymills 0:714293de3836 1922
ashleymills 0:714293de3836 1923 void DtlsMsgListDelete(DtlsMsg* head, void* heap)
ashleymills 0:714293de3836 1924 {
ashleymills 0:714293de3836 1925 DtlsMsg* next;
ashleymills 0:714293de3836 1926 while (head) {
ashleymills 0:714293de3836 1927 next = head->next;
ashleymills 0:714293de3836 1928 DtlsMsgDelete(head, heap);
ashleymills 0:714293de3836 1929 head = next;
ashleymills 0:714293de3836 1930 }
ashleymills 0:714293de3836 1931 }
ashleymills 0:714293de3836 1932
ashleymills 0:714293de3836 1933
ashleymills 0:714293de3836 1934 void DtlsMsgSet(DtlsMsg* msg, word32 seq, const byte* data, byte type,
ashleymills 0:714293de3836 1935 word32 fragOffset, word32 fragSz)
ashleymills 0:714293de3836 1936 {
ashleymills 0:714293de3836 1937 if (msg != NULL && data != NULL && msg->fragSz <= msg->sz) {
ashleymills 0:714293de3836 1938 msg->seq = seq;
ashleymills 0:714293de3836 1939 msg->type = type;
ashleymills 0:714293de3836 1940 msg->fragSz += fragSz;
ashleymills 0:714293de3836 1941 /* If fragOffset is zero, this is either a full message that is out
ashleymills 0:714293de3836 1942 * of order, or the first fragment of a fragmented message. Copy the
ashleymills 0:714293de3836 1943 * handshake message header as well as the message data. */
ashleymills 0:714293de3836 1944 if (fragOffset == 0)
ashleymills 0:714293de3836 1945 XMEMCPY(msg->buf, data - DTLS_HANDSHAKE_HEADER_SZ,
ashleymills 0:714293de3836 1946 fragSz + DTLS_HANDSHAKE_HEADER_SZ);
ashleymills 0:714293de3836 1947 else {
ashleymills 0:714293de3836 1948 /* If fragOffet is non-zero, this is an additional fragment that
ashleymills 0:714293de3836 1949 * needs to be copied to its location in the message buffer. Also
ashleymills 0:714293de3836 1950 * copy the total size of the message over the fragment size. The
ashleymills 0:714293de3836 1951 * hash routines look at a defragmented message if it had actually
ashleymills 0:714293de3836 1952 * come across as a single handshake message. */
ashleymills 0:714293de3836 1953 XMEMCPY(msg->msg + fragOffset, data, fragSz);
ashleymills 0:714293de3836 1954 c32to24(msg->sz, msg->msg - DTLS_HANDSHAKE_FRAG_SZ);
ashleymills 0:714293de3836 1955 }
ashleymills 0:714293de3836 1956 }
ashleymills 0:714293de3836 1957 }
ashleymills 0:714293de3836 1958
ashleymills 0:714293de3836 1959
ashleymills 0:714293de3836 1960 DtlsMsg* DtlsMsgFind(DtlsMsg* head, word32 seq)
ashleymills 0:714293de3836 1961 {
ashleymills 0:714293de3836 1962 while (head != NULL && head->seq != seq) {
ashleymills 0:714293de3836 1963 head = head->next;
ashleymills 0:714293de3836 1964 }
ashleymills 0:714293de3836 1965 return head;
ashleymills 0:714293de3836 1966 }
ashleymills 0:714293de3836 1967
ashleymills 0:714293de3836 1968
ashleymills 0:714293de3836 1969 DtlsMsg* DtlsMsgStore(DtlsMsg* head, word32 seq, const byte* data,
ashleymills 0:714293de3836 1970 word32 dataSz, byte type, word32 fragOffset, word32 fragSz, void* heap)
ashleymills 0:714293de3836 1971 {
ashleymills 0:714293de3836 1972
ashleymills 0:714293de3836 1973 /* See if seq exists in the list. If it isn't in the list, make
ashleymills 0:714293de3836 1974 * a new item of size dataSz, copy fragSz bytes from data to msg->msg
ashleymills 0:714293de3836 1975 * starting at offset fragOffset, and add fragSz to msg->fragSz. If
ashleymills 0:714293de3836 1976 * the seq is in the list and it isn't full, copy fragSz bytes from
ashleymills 0:714293de3836 1977 * data to msg->msg starting at offset fragOffset, and add fragSz to
ashleymills 0:714293de3836 1978 * msg->fragSz. The new item should be inserted into the list in its
ashleymills 0:714293de3836 1979 * proper position.
ashleymills 0:714293de3836 1980 *
ashleymills 0:714293de3836 1981 * 1. Find seq in list, or where seq should go in list. If seq not in
ashleymills 0:714293de3836 1982 * list, create new item and insert into list. Either case, keep
ashleymills 0:714293de3836 1983 * pointer to item.
ashleymills 0:714293de3836 1984 * 2. If msg->fragSz + fragSz < sz, copy data to msg->msg at offset
ashleymills 0:714293de3836 1985 * fragOffset. Add fragSz to msg->fragSz.
ashleymills 0:714293de3836 1986 */
ashleymills 0:714293de3836 1987
ashleymills 0:714293de3836 1988 if (head != NULL) {
ashleymills 0:714293de3836 1989 DtlsMsg* cur = DtlsMsgFind(head, seq);
ashleymills 0:714293de3836 1990 if (cur == NULL) {
ashleymills 0:714293de3836 1991 cur = DtlsMsgNew(dataSz, heap);
ashleymills 0:714293de3836 1992 DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz);
ashleymills 0:714293de3836 1993 head = DtlsMsgInsert(head, cur);
ashleymills 0:714293de3836 1994 }
ashleymills 0:714293de3836 1995 else {
ashleymills 0:714293de3836 1996 DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz);
ashleymills 0:714293de3836 1997 }
ashleymills 0:714293de3836 1998 }
ashleymills 0:714293de3836 1999 else {
ashleymills 0:714293de3836 2000 head = DtlsMsgNew(dataSz, heap);
ashleymills 0:714293de3836 2001 DtlsMsgSet(head, seq, data, type, fragOffset, fragSz);
ashleymills 0:714293de3836 2002 }
ashleymills 0:714293de3836 2003
ashleymills 0:714293de3836 2004 return head;
ashleymills 0:714293de3836 2005 }
ashleymills 0:714293de3836 2006
ashleymills 0:714293de3836 2007
ashleymills 0:714293de3836 2008 /* DtlsMsgInsert() is an in-order insert. */
ashleymills 0:714293de3836 2009 DtlsMsg* DtlsMsgInsert(DtlsMsg* head, DtlsMsg* item)
ashleymills 0:714293de3836 2010 {
ashleymills 0:714293de3836 2011 if (head == NULL || item->seq < head->seq) {
ashleymills 0:714293de3836 2012 item->next = head;
ashleymills 0:714293de3836 2013 head = item;
ashleymills 0:714293de3836 2014 }
ashleymills 0:714293de3836 2015 else if (head->next == NULL) {
ashleymills 0:714293de3836 2016 head->next = item;
ashleymills 0:714293de3836 2017 }
ashleymills 0:714293de3836 2018 else {
ashleymills 0:714293de3836 2019 DtlsMsg* cur = head->next;
ashleymills 0:714293de3836 2020 DtlsMsg* prev = head;
ashleymills 0:714293de3836 2021 while (cur) {
ashleymills 0:714293de3836 2022 if (item->seq < cur->seq) {
ashleymills 0:714293de3836 2023 item->next = cur;
ashleymills 0:714293de3836 2024 prev->next = item;
ashleymills 0:714293de3836 2025 break;
ashleymills 0:714293de3836 2026 }
ashleymills 0:714293de3836 2027 prev = cur;
ashleymills 0:714293de3836 2028 cur = cur->next;
ashleymills 0:714293de3836 2029 }
ashleymills 0:714293de3836 2030 if (cur == NULL) {
ashleymills 0:714293de3836 2031 prev->next = item;
ashleymills 0:714293de3836 2032 }
ashleymills 0:714293de3836 2033 }
ashleymills 0:714293de3836 2034
ashleymills 0:714293de3836 2035 return head;
ashleymills 0:714293de3836 2036 }
ashleymills 0:714293de3836 2037
ashleymills 0:714293de3836 2038 #endif /* CYASSL_DTLS */
ashleymills 0:714293de3836 2039
ashleymills 0:714293de3836 2040 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 2041
ashleymills 0:714293de3836 2042 ProtocolVersion MakeSSLv3(void)
ashleymills 0:714293de3836 2043 {
ashleymills 0:714293de3836 2044 ProtocolVersion pv;
ashleymills 0:714293de3836 2045 pv.major = SSLv3_MAJOR;
ashleymills 0:714293de3836 2046 pv.minor = SSLv3_MINOR;
ashleymills 0:714293de3836 2047
ashleymills 0:714293de3836 2048 return pv;
ashleymills 0:714293de3836 2049 }
ashleymills 0:714293de3836 2050
ashleymills 0:714293de3836 2051 #endif /* NO_OLD_TLS */
ashleymills 0:714293de3836 2052
ashleymills 0:714293de3836 2053
ashleymills 0:714293de3836 2054 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 2055
ashleymills 0:714293de3836 2056 ProtocolVersion MakeDTLSv1(void)
ashleymills 0:714293de3836 2057 {
ashleymills 0:714293de3836 2058 ProtocolVersion pv;
ashleymills 0:714293de3836 2059 pv.major = DTLS_MAJOR;
ashleymills 0:714293de3836 2060 pv.minor = DTLS_MINOR;
ashleymills 0:714293de3836 2061
ashleymills 0:714293de3836 2062 return pv;
ashleymills 0:714293de3836 2063 }
ashleymills 0:714293de3836 2064
ashleymills 0:714293de3836 2065 ProtocolVersion MakeDTLSv1_2(void)
ashleymills 0:714293de3836 2066 {
ashleymills 0:714293de3836 2067 ProtocolVersion pv;
ashleymills 0:714293de3836 2068 pv.major = DTLS_MAJOR;
ashleymills 0:714293de3836 2069 pv.minor = DTLSv1_2_MINOR;
ashleymills 0:714293de3836 2070
ashleymills 0:714293de3836 2071 return pv;
ashleymills 0:714293de3836 2072 }
ashleymills 0:714293de3836 2073
ashleymills 0:714293de3836 2074 #endif /* CYASSL_DTLS */
ashleymills 0:714293de3836 2075
ashleymills 0:714293de3836 2076
ashleymills 0:714293de3836 2077
ashleymills 0:714293de3836 2078
ashleymills 0:714293de3836 2079 #ifdef USE_WINDOWS_API
ashleymills 0:714293de3836 2080
ashleymills 0:714293de3836 2081 word32 LowResTimer(void)
ashleymills 0:714293de3836 2082 {
ashleymills 0:714293de3836 2083 static int init = 0;
ashleymills 0:714293de3836 2084 static LARGE_INTEGER freq;
ashleymills 0:714293de3836 2085 LARGE_INTEGER count;
ashleymills 0:714293de3836 2086
ashleymills 0:714293de3836 2087 if (!init) {
ashleymills 0:714293de3836 2088 QueryPerformanceFrequency(&freq);
ashleymills 0:714293de3836 2089 init = 1;
ashleymills 0:714293de3836 2090 }
ashleymills 0:714293de3836 2091
ashleymills 0:714293de3836 2092 QueryPerformanceCounter(&count);
ashleymills 0:714293de3836 2093
ashleymills 0:714293de3836 2094 return (word32)(count.QuadPart / freq.QuadPart);
ashleymills 0:714293de3836 2095 }
ashleymills 0:714293de3836 2096
ashleymills 0:714293de3836 2097 #elif defined(HAVE_RTP_SYS)
ashleymills 0:714293de3836 2098
ashleymills 0:714293de3836 2099 #include "rtptime.h"
ashleymills 0:714293de3836 2100
ashleymills 0:714293de3836 2101 word32 LowResTimer(void)
ashleymills 0:714293de3836 2102 {
ashleymills 0:714293de3836 2103 return (word32)rtp_get_system_sec();
ashleymills 0:714293de3836 2104 }
ashleymills 0:714293de3836 2105
ashleymills 0:714293de3836 2106
ashleymills 0:714293de3836 2107 #elif defined(MICRIUM)
ashleymills 0:714293de3836 2108
ashleymills 0:714293de3836 2109 word32 LowResTimer(void)
ashleymills 0:714293de3836 2110 {
ashleymills 0:714293de3836 2111 NET_SECURE_OS_TICK clk;
ashleymills 0:714293de3836 2112
ashleymills 0:714293de3836 2113 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
ashleymills 0:714293de3836 2114 clk = NetSecure_OS_TimeGet();
ashleymills 0:714293de3836 2115 #endif
ashleymills 0:714293de3836 2116 return (word32)clk;
ashleymills 0:714293de3836 2117 }
ashleymills 0:714293de3836 2118
ashleymills 0:714293de3836 2119
ashleymills 0:714293de3836 2120 #elif defined(MICROCHIP_TCPIP_V5)
ashleymills 0:714293de3836 2121
ashleymills 0:714293de3836 2122 word32 LowResTimer(void)
ashleymills 0:714293de3836 2123 {
ashleymills 0:714293de3836 2124 return (word32) TickGet();
ashleymills 0:714293de3836 2125 }
ashleymills 0:714293de3836 2126
ashleymills 0:714293de3836 2127
ashleymills 0:714293de3836 2128 #elif defined(MICROCHIP_TCPIP)
ashleymills 0:714293de3836 2129
ashleymills 0:714293de3836 2130 word32 LowResTimer(void)
ashleymills 0:714293de3836 2131 {
ashleymills 0:714293de3836 2132 return (word32) SYS_TICK_Get();
ashleymills 0:714293de3836 2133 }
ashleymills 0:714293de3836 2134
ashleymills 0:714293de3836 2135
ashleymills 0:714293de3836 2136 #elif defined(USER_TICKS)
ashleymills 0:714293de3836 2137 #if 0
ashleymills 0:714293de3836 2138 word32 LowResTimer(void)
ashleymills 0:714293de3836 2139 {
ashleymills 0:714293de3836 2140 /*
ashleymills 0:714293de3836 2141 write your own clock tick function if don't want time(0)
ashleymills 0:714293de3836 2142 needs second accuracy but doesn't have to correlated to EPOCH
ashleymills 0:714293de3836 2143 */
ashleymills 0:714293de3836 2144 }
ashleymills 0:714293de3836 2145 #endif
ashleymills 0:714293de3836 2146 #else /* !USE_WINDOWS_API && !HAVE_RTP_SYS && !MICRIUM && !USER_TICKS */
ashleymills 0:714293de3836 2147
ashleymills 0:714293de3836 2148 #include <time.h>
ashleymills 0:714293de3836 2149
ashleymills 0:714293de3836 2150 word32 LowResTimer(void)
ashleymills 0:714293de3836 2151 {
ashleymills 0:714293de3836 2152 return (word32)time(0);
ashleymills 0:714293de3836 2153 }
ashleymills 0:714293de3836 2154
ashleymills 0:714293de3836 2155
ashleymills 0:714293de3836 2156 #endif /* USE_WINDOWS_API */
ashleymills 0:714293de3836 2157
ashleymills 0:714293de3836 2158
ashleymills 0:714293de3836 2159 /* add output to md5 and sha handshake hashes, exclude record header */
ashleymills 0:714293de3836 2160 static void HashOutput(CYASSL* ssl, const byte* output, int sz, int ivSz)
ashleymills 0:714293de3836 2161 {
ashleymills 0:714293de3836 2162 const byte* adj = output + RECORD_HEADER_SZ + ivSz;
ashleymills 0:714293de3836 2163 sz -= RECORD_HEADER_SZ;
ashleymills 0:714293de3836 2164
ashleymills 0:714293de3836 2165 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 2166 if (ssl->options.dtls) {
ashleymills 0:714293de3836 2167 adj += DTLS_RECORD_EXTRA;
ashleymills 0:714293de3836 2168 sz -= DTLS_RECORD_EXTRA;
ashleymills 0:714293de3836 2169 }
ashleymills 0:714293de3836 2170 #endif
ashleymills 0:714293de3836 2171 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 2172 #ifndef NO_SHA
ashleymills 0:714293de3836 2173 ShaUpdate(&ssl->hashSha, adj, sz);
ashleymills 0:714293de3836 2174 #endif
ashleymills 0:714293de3836 2175 #ifndef NO_MD5
ashleymills 0:714293de3836 2176 Md5Update(&ssl->hashMd5, adj, sz);
ashleymills 0:714293de3836 2177 #endif
ashleymills 0:714293de3836 2178 #endif
ashleymills 0:714293de3836 2179
ashleymills 0:714293de3836 2180 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 2181 #ifndef NO_SHA256
ashleymills 0:714293de3836 2182 Sha256Update(&ssl->hashSha256, adj, sz);
ashleymills 0:714293de3836 2183 #endif
ashleymills 0:714293de3836 2184 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 2185 Sha384Update(&ssl->hashSha384, adj, sz);
ashleymills 0:714293de3836 2186 #endif
ashleymills 0:714293de3836 2187 }
ashleymills 0:714293de3836 2188 }
ashleymills 0:714293de3836 2189
ashleymills 0:714293de3836 2190
ashleymills 0:714293de3836 2191 /* add input to md5 and sha handshake hashes, include handshake header */
ashleymills 0:714293de3836 2192 static void HashInput(CYASSL* ssl, const byte* input, int sz)
ashleymills 0:714293de3836 2193 {
ashleymills 0:714293de3836 2194 const byte* adj = input - HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 2195 sz += HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 2196
ashleymills 0:714293de3836 2197 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 2198 if (ssl->options.dtls) {
ashleymills 0:714293de3836 2199 adj -= DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 2200 sz += DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 2201 }
ashleymills 0:714293de3836 2202 #endif
ashleymills 0:714293de3836 2203
ashleymills 0:714293de3836 2204 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 2205 #ifndef NO_SHA
ashleymills 0:714293de3836 2206 ShaUpdate(&ssl->hashSha, adj, sz);
ashleymills 0:714293de3836 2207 #endif
ashleymills 0:714293de3836 2208 #ifndef NO_MD5
ashleymills 0:714293de3836 2209 Md5Update(&ssl->hashMd5, adj, sz);
ashleymills 0:714293de3836 2210 #endif
ashleymills 0:714293de3836 2211 #endif
ashleymills 0:714293de3836 2212
ashleymills 0:714293de3836 2213 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 2214 #ifndef NO_SHA256
ashleymills 0:714293de3836 2215 Sha256Update(&ssl->hashSha256, adj, sz);
ashleymills 0:714293de3836 2216 #endif
ashleymills 0:714293de3836 2217 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 2218 Sha384Update(&ssl->hashSha384, adj, sz);
ashleymills 0:714293de3836 2219 #endif
ashleymills 0:714293de3836 2220 }
ashleymills 0:714293de3836 2221 }
ashleymills 0:714293de3836 2222
ashleymills 0:714293de3836 2223
ashleymills 0:714293de3836 2224 /* add record layer header for message */
ashleymills 0:714293de3836 2225 static void AddRecordHeader(byte* output, word32 length, byte type, CYASSL* ssl)
ashleymills 0:714293de3836 2226 {
ashleymills 0:714293de3836 2227 RecordLayerHeader* rl;
ashleymills 0:714293de3836 2228
ashleymills 0:714293de3836 2229 /* record layer header */
ashleymills 0:714293de3836 2230 rl = (RecordLayerHeader*)output;
ashleymills 0:714293de3836 2231 rl->type = type;
ashleymills 0:714293de3836 2232 rl->pvMajor = ssl->version.major; /* type and version same in each */
ashleymills 0:714293de3836 2233 rl->pvMinor = ssl->version.minor;
ashleymills 0:714293de3836 2234
ashleymills 0:714293de3836 2235 if (!ssl->options.dtls)
ashleymills 0:714293de3836 2236 c16toa((word16)length, rl->length);
ashleymills 0:714293de3836 2237 else {
ashleymills 0:714293de3836 2238 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 2239 DtlsRecordLayerHeader* dtls;
ashleymills 0:714293de3836 2240
ashleymills 0:714293de3836 2241 /* dtls record layer header extensions */
ashleymills 0:714293de3836 2242 dtls = (DtlsRecordLayerHeader*)output;
ashleymills 0:714293de3836 2243 c16toa(ssl->keys.dtls_epoch, dtls->epoch);
ashleymills 0:714293de3836 2244 c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number);
ashleymills 0:714293de3836 2245 c16toa((word16)length, dtls->length);
ashleymills 0:714293de3836 2246 #endif
ashleymills 0:714293de3836 2247 }
ashleymills 0:714293de3836 2248 }
ashleymills 0:714293de3836 2249
ashleymills 0:714293de3836 2250
ashleymills 0:714293de3836 2251 /* add handshake header for message */
ashleymills 0:714293de3836 2252 static void AddHandShakeHeader(byte* output, word32 length, byte type,
ashleymills 0:714293de3836 2253 CYASSL* ssl)
ashleymills 0:714293de3836 2254 {
ashleymills 0:714293de3836 2255 HandShakeHeader* hs;
ashleymills 0:714293de3836 2256 (void)ssl;
ashleymills 0:714293de3836 2257
ashleymills 0:714293de3836 2258 /* handshake header */
ashleymills 0:714293de3836 2259 hs = (HandShakeHeader*)output;
ashleymills 0:714293de3836 2260 hs->type = type;
ashleymills 0:714293de3836 2261 c32to24(length, hs->length); /* type and length same for each */
ashleymills 0:714293de3836 2262 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 2263 if (ssl->options.dtls) {
ashleymills 0:714293de3836 2264 DtlsHandShakeHeader* dtls;
ashleymills 0:714293de3836 2265
ashleymills 0:714293de3836 2266 /* dtls handshake header extensions */
ashleymills 0:714293de3836 2267 dtls = (DtlsHandShakeHeader*)output;
ashleymills 0:714293de3836 2268 c16toa(ssl->keys.dtls_handshake_number++, dtls->message_seq);
ashleymills 0:714293de3836 2269 c32to24(0, dtls->fragment_offset);
ashleymills 0:714293de3836 2270 c32to24(length, dtls->fragment_length);
ashleymills 0:714293de3836 2271 }
ashleymills 0:714293de3836 2272 #endif
ashleymills 0:714293de3836 2273 }
ashleymills 0:714293de3836 2274
ashleymills 0:714293de3836 2275
ashleymills 0:714293de3836 2276 /* add both headers for handshake message */
ashleymills 0:714293de3836 2277 static void AddHeaders(byte* output, word32 length, byte type, CYASSL* ssl)
ashleymills 0:714293de3836 2278 {
ashleymills 0:714293de3836 2279 if (!ssl->options.dtls) {
ashleymills 0:714293de3836 2280 AddRecordHeader(output, length + HANDSHAKE_HEADER_SZ, handshake, ssl);
ashleymills 0:714293de3836 2281 AddHandShakeHeader(output + RECORD_HEADER_SZ, length, type, ssl);
ashleymills 0:714293de3836 2282 }
ashleymills 0:714293de3836 2283 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 2284 else {
ashleymills 0:714293de3836 2285 AddRecordHeader(output, length+DTLS_HANDSHAKE_HEADER_SZ, handshake,ssl);
ashleymills 0:714293de3836 2286 AddHandShakeHeader(output + DTLS_RECORD_HEADER_SZ, length, type, ssl);
ashleymills 0:714293de3836 2287 }
ashleymills 0:714293de3836 2288 #endif
ashleymills 0:714293de3836 2289 }
ashleymills 0:714293de3836 2290
ashleymills 0:714293de3836 2291
ashleymills 0:714293de3836 2292 /* return bytes received, -1 on error */
ashleymills 0:714293de3836 2293 static int Receive(CYASSL* ssl, byte* buf, word32 sz)
ashleymills 0:714293de3836 2294 {
ashleymills 0:714293de3836 2295 int recvd;
ashleymills 0:714293de3836 2296
ashleymills 0:714293de3836 2297 if (ssl->ctx->CBIORecv == NULL) {
ashleymills 0:714293de3836 2298 CYASSL_MSG("Your IO Recv callback is null, please set");
ashleymills 0:714293de3836 2299 return -1;
ashleymills 0:714293de3836 2300 }
ashleymills 0:714293de3836 2301
ashleymills 0:714293de3836 2302 retry:
ashleymills 0:714293de3836 2303 recvd = ssl->ctx->CBIORecv(ssl, (char *)buf, (int)sz, ssl->IOCB_ReadCtx);
ashleymills 0:714293de3836 2304 if (recvd < 0)
ashleymills 0:714293de3836 2305 switch (recvd) {
ashleymills 0:714293de3836 2306 case CYASSL_CBIO_ERR_GENERAL: /* general/unknown error */
ashleymills 0:714293de3836 2307 return -1;
ashleymills 0:714293de3836 2308
ashleymills 0:714293de3836 2309 case CYASSL_CBIO_ERR_WANT_READ: /* want read, would block */
ashleymills 0:714293de3836 2310 return WANT_READ;
ashleymills 0:714293de3836 2311
ashleymills 0:714293de3836 2312 case CYASSL_CBIO_ERR_CONN_RST: /* connection reset */
ashleymills 0:714293de3836 2313 #ifdef USE_WINDOWS_API
ashleymills 0:714293de3836 2314 if (ssl->options.dtls) {
ashleymills 0:714293de3836 2315 goto retry;
ashleymills 0:714293de3836 2316 }
ashleymills 0:714293de3836 2317 #endif
ashleymills 0:714293de3836 2318 ssl->options.connReset = 1;
ashleymills 0:714293de3836 2319 return -1;
ashleymills 0:714293de3836 2320
ashleymills 0:714293de3836 2321 case CYASSL_CBIO_ERR_ISR: /* interrupt */
ashleymills 0:714293de3836 2322 /* see if we got our timeout */
ashleymills 0:714293de3836 2323 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 2324 if (ssl->toInfoOn) {
ashleymills 0:714293de3836 2325 struct itimerval timeout;
ashleymills 0:714293de3836 2326 getitimer(ITIMER_REAL, &timeout);
ashleymills 0:714293de3836 2327 if (timeout.it_value.tv_sec == 0 &&
ashleymills 0:714293de3836 2328 timeout.it_value.tv_usec == 0) {
ashleymills 0:714293de3836 2329 XSTRNCPY(ssl->timeoutInfo.timeoutName,
ashleymills 0:714293de3836 2330 "recv() timeout", MAX_TIMEOUT_NAME_SZ);
ashleymills 0:714293de3836 2331 CYASSL_MSG("Got our timeout");
ashleymills 0:714293de3836 2332 return WANT_READ;
ashleymills 0:714293de3836 2333 }
ashleymills 0:714293de3836 2334 }
ashleymills 0:714293de3836 2335 #endif
ashleymills 0:714293de3836 2336 goto retry;
ashleymills 0:714293de3836 2337
ashleymills 0:714293de3836 2338 case CYASSL_CBIO_ERR_CONN_CLOSE: /* peer closed connection */
ashleymills 0:714293de3836 2339 ssl->options.isClosed = 1;
ashleymills 0:714293de3836 2340 return -1;
ashleymills 0:714293de3836 2341
ashleymills 0:714293de3836 2342 case CYASSL_CBIO_ERR_TIMEOUT:
ashleymills 0:714293de3836 2343 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 2344 if (DtlsPoolTimeout(ssl) == 0 && DtlsPoolSend(ssl) == 0)
ashleymills 0:714293de3836 2345 goto retry;
ashleymills 0:714293de3836 2346 else
ashleymills 0:714293de3836 2347 #endif
ashleymills 0:714293de3836 2348 return -1;
ashleymills 0:714293de3836 2349
ashleymills 0:714293de3836 2350 default:
ashleymills 0:714293de3836 2351 return recvd;
ashleymills 0:714293de3836 2352 }
ashleymills 0:714293de3836 2353
ashleymills 0:714293de3836 2354 return recvd;
ashleymills 0:714293de3836 2355 }
ashleymills 0:714293de3836 2356
ashleymills 0:714293de3836 2357
ashleymills 0:714293de3836 2358 /* Switch dynamic output buffer back to static, buffer is assumed clear */
ashleymills 0:714293de3836 2359 void ShrinkOutputBuffer(CYASSL* ssl)
ashleymills 0:714293de3836 2360 {
ashleymills 0:714293de3836 2361 CYASSL_MSG("Shrinking output buffer\n");
ashleymills 0:714293de3836 2362 XFREE(ssl->buffers.outputBuffer.buffer - ssl->buffers.outputBuffer.offset,
ashleymills 0:714293de3836 2363 ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
ashleymills 0:714293de3836 2364 ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
ashleymills 0:714293de3836 2365 ssl->buffers.outputBuffer.bufferSize = STATIC_BUFFER_LEN;
ashleymills 0:714293de3836 2366 ssl->buffers.outputBuffer.dynamicFlag = 0;
ashleymills 0:714293de3836 2367 ssl->buffers.outputBuffer.offset = 0;
ashleymills 0:714293de3836 2368 }
ashleymills 0:714293de3836 2369
ashleymills 0:714293de3836 2370
ashleymills 0:714293de3836 2371 /* Switch dynamic input buffer back to static, keep any remaining input */
ashleymills 0:714293de3836 2372 /* forced free means cleaning up */
ashleymills 0:714293de3836 2373 void ShrinkInputBuffer(CYASSL* ssl, int forcedFree)
ashleymills 0:714293de3836 2374 {
ashleymills 0:714293de3836 2375 int usedLength = ssl->buffers.inputBuffer.length -
ashleymills 0:714293de3836 2376 ssl->buffers.inputBuffer.idx;
ashleymills 0:714293de3836 2377 if (!forcedFree && usedLength > STATIC_BUFFER_LEN)
ashleymills 0:714293de3836 2378 return;
ashleymills 0:714293de3836 2379
ashleymills 0:714293de3836 2380 CYASSL_MSG("Shrinking input buffer\n");
ashleymills 0:714293de3836 2381
ashleymills 0:714293de3836 2382 if (!forcedFree && usedLength)
ashleymills 0:714293de3836 2383 XMEMCPY(ssl->buffers.inputBuffer.staticBuffer,
ashleymills 0:714293de3836 2384 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
ashleymills 0:714293de3836 2385 usedLength);
ashleymills 0:714293de3836 2386
ashleymills 0:714293de3836 2387 XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
ashleymills 0:714293de3836 2388 ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
ashleymills 0:714293de3836 2389 ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
ashleymills 0:714293de3836 2390 ssl->buffers.inputBuffer.bufferSize = STATIC_BUFFER_LEN;
ashleymills 0:714293de3836 2391 ssl->buffers.inputBuffer.dynamicFlag = 0;
ashleymills 0:714293de3836 2392 ssl->buffers.inputBuffer.offset = 0;
ashleymills 0:714293de3836 2393 ssl->buffers.inputBuffer.idx = 0;
ashleymills 0:714293de3836 2394 ssl->buffers.inputBuffer.length = usedLength;
ashleymills 0:714293de3836 2395 }
ashleymills 0:714293de3836 2396
ashleymills 0:714293de3836 2397
ashleymills 0:714293de3836 2398 int SendBuffered(CYASSL* ssl)
ashleymills 0:714293de3836 2399 {
ashleymills 0:714293de3836 2400 if (ssl->ctx->CBIOSend == NULL) {
ashleymills 0:714293de3836 2401 CYASSL_MSG("Your IO Send callback is null, please set");
ashleymills 0:714293de3836 2402 return SOCKET_ERROR_E;
ashleymills 0:714293de3836 2403 }
ashleymills 0:714293de3836 2404
ashleymills 0:714293de3836 2405 while (ssl->buffers.outputBuffer.length > 0) {
ashleymills 0:714293de3836 2406 int sent = ssl->ctx->CBIOSend(ssl,
ashleymills 0:714293de3836 2407 (char*)ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 2408 ssl->buffers.outputBuffer.idx,
ashleymills 0:714293de3836 2409 (int)ssl->buffers.outputBuffer.length,
ashleymills 0:714293de3836 2410 ssl->IOCB_WriteCtx);
ashleymills 0:714293de3836 2411 if (sent < 0) {
ashleymills 0:714293de3836 2412 switch (sent) {
ashleymills 0:714293de3836 2413
ashleymills 0:714293de3836 2414 case CYASSL_CBIO_ERR_WANT_WRITE: /* would block */
ashleymills 0:714293de3836 2415 return WANT_WRITE;
ashleymills 0:714293de3836 2416
ashleymills 0:714293de3836 2417 case CYASSL_CBIO_ERR_CONN_RST: /* connection reset */
ashleymills 0:714293de3836 2418 ssl->options.connReset = 1;
ashleymills 0:714293de3836 2419 break;
ashleymills 0:714293de3836 2420
ashleymills 0:714293de3836 2421 case CYASSL_CBIO_ERR_ISR: /* interrupt */
ashleymills 0:714293de3836 2422 /* see if we got our timeout */
ashleymills 0:714293de3836 2423 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 2424 if (ssl->toInfoOn) {
ashleymills 0:714293de3836 2425 struct itimerval timeout;
ashleymills 0:714293de3836 2426 getitimer(ITIMER_REAL, &timeout);
ashleymills 0:714293de3836 2427 if (timeout.it_value.tv_sec == 0 &&
ashleymills 0:714293de3836 2428 timeout.it_value.tv_usec == 0) {
ashleymills 0:714293de3836 2429 XSTRNCPY(ssl->timeoutInfo.timeoutName,
ashleymills 0:714293de3836 2430 "send() timeout", MAX_TIMEOUT_NAME_SZ);
ashleymills 0:714293de3836 2431 CYASSL_MSG("Got our timeout");
ashleymills 0:714293de3836 2432 return WANT_WRITE;
ashleymills 0:714293de3836 2433 }
ashleymills 0:714293de3836 2434 }
ashleymills 0:714293de3836 2435 #endif
ashleymills 0:714293de3836 2436 continue;
ashleymills 0:714293de3836 2437
ashleymills 0:714293de3836 2438 case CYASSL_CBIO_ERR_CONN_CLOSE: /* epipe / conn closed */
ashleymills 0:714293de3836 2439 ssl->options.connReset = 1; /* treat same as reset */
ashleymills 0:714293de3836 2440 break;
ashleymills 0:714293de3836 2441
ashleymills 0:714293de3836 2442 default:
ashleymills 0:714293de3836 2443 return SOCKET_ERROR_E;
ashleymills 0:714293de3836 2444 }
ashleymills 0:714293de3836 2445
ashleymills 0:714293de3836 2446 return SOCKET_ERROR_E;
ashleymills 0:714293de3836 2447 }
ashleymills 0:714293de3836 2448
ashleymills 0:714293de3836 2449 ssl->buffers.outputBuffer.idx += sent;
ashleymills 0:714293de3836 2450 ssl->buffers.outputBuffer.length -= sent;
ashleymills 0:714293de3836 2451 }
ashleymills 0:714293de3836 2452
ashleymills 0:714293de3836 2453 ssl->buffers.outputBuffer.idx = 0;
ashleymills 0:714293de3836 2454
ashleymills 0:714293de3836 2455 if (ssl->buffers.outputBuffer.dynamicFlag)
ashleymills 0:714293de3836 2456 ShrinkOutputBuffer(ssl);
ashleymills 0:714293de3836 2457
ashleymills 0:714293de3836 2458 return 0;
ashleymills 0:714293de3836 2459 }
ashleymills 0:714293de3836 2460
ashleymills 0:714293de3836 2461
ashleymills 0:714293de3836 2462 /* Grow the output buffer */
ashleymills 0:714293de3836 2463 static INLINE int GrowOutputBuffer(CYASSL* ssl, int size)
ashleymills 0:714293de3836 2464 {
ashleymills 0:714293de3836 2465 byte* tmp;
ashleymills 0:714293de3836 2466 byte hdrSz = ssl->options.dtls ? DTLS_RECORD_HEADER_SZ :
ashleymills 0:714293de3836 2467 RECORD_HEADER_SZ;
ashleymills 0:714293de3836 2468 byte align = CYASSL_GENERAL_ALIGNMENT;
ashleymills 0:714293de3836 2469 /* the encrypted data will be offset from the front of the buffer by
ashleymills 0:714293de3836 2470 the header, if the user wants encrypted alignment they need
ashleymills 0:714293de3836 2471 to define their alignment requirement */
ashleymills 0:714293de3836 2472
ashleymills 0:714293de3836 2473 if (align) {
ashleymills 0:714293de3836 2474 while (align < hdrSz)
ashleymills 0:714293de3836 2475 align *= 2;
ashleymills 0:714293de3836 2476 }
ashleymills 0:714293de3836 2477
ashleymills 0:714293de3836 2478 tmp = (byte*) XMALLOC(size + ssl->buffers.outputBuffer.length + align,
ashleymills 0:714293de3836 2479 ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
ashleymills 0:714293de3836 2480 CYASSL_MSG("growing output buffer\n");
ashleymills 0:714293de3836 2481
ashleymills 0:714293de3836 2482 if (!tmp) return MEMORY_E;
ashleymills 0:714293de3836 2483 if (align)
ashleymills 0:714293de3836 2484 tmp += align - hdrSz;
ashleymills 0:714293de3836 2485
ashleymills 0:714293de3836 2486 if (ssl->buffers.outputBuffer.length)
ashleymills 0:714293de3836 2487 XMEMCPY(tmp, ssl->buffers.outputBuffer.buffer,
ashleymills 0:714293de3836 2488 ssl->buffers.outputBuffer.length);
ashleymills 0:714293de3836 2489
ashleymills 0:714293de3836 2490 if (ssl->buffers.outputBuffer.dynamicFlag)
ashleymills 0:714293de3836 2491 XFREE(ssl->buffers.outputBuffer.buffer -
ashleymills 0:714293de3836 2492 ssl->buffers.outputBuffer.offset, ssl->heap,
ashleymills 0:714293de3836 2493 DYNAMIC_TYPE_OUT_BUFFER);
ashleymills 0:714293de3836 2494 ssl->buffers.outputBuffer.dynamicFlag = 1;
ashleymills 0:714293de3836 2495 if (align)
ashleymills 0:714293de3836 2496 ssl->buffers.outputBuffer.offset = align - hdrSz;
ashleymills 0:714293de3836 2497 else
ashleymills 0:714293de3836 2498 ssl->buffers.outputBuffer.offset = 0;
ashleymills 0:714293de3836 2499 ssl->buffers.outputBuffer.buffer = tmp;
ashleymills 0:714293de3836 2500 ssl->buffers.outputBuffer.bufferSize = size +
ashleymills 0:714293de3836 2501 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 2502 return 0;
ashleymills 0:714293de3836 2503 }
ashleymills 0:714293de3836 2504
ashleymills 0:714293de3836 2505
ashleymills 0:714293de3836 2506 /* Grow the input buffer, should only be to read cert or big app data */
ashleymills 0:714293de3836 2507 int GrowInputBuffer(CYASSL* ssl, int size, int usedLength)
ashleymills 0:714293de3836 2508 {
ashleymills 0:714293de3836 2509 byte* tmp;
ashleymills 0:714293de3836 2510 byte hdrSz = DTLS_RECORD_HEADER_SZ;
ashleymills 0:714293de3836 2511 byte align = ssl->options.dtls ? CYASSL_GENERAL_ALIGNMENT : 0;
ashleymills 0:714293de3836 2512 /* the encrypted data will be offset from the front of the buffer by
ashleymills 0:714293de3836 2513 the dtls record header, if the user wants encrypted alignment they need
ashleymills 0:714293de3836 2514 to define their alignment requirement. in tls we read record header
ashleymills 0:714293de3836 2515 to get size of record and put actual data back at front, so don't need */
ashleymills 0:714293de3836 2516
ashleymills 0:714293de3836 2517 if (align) {
ashleymills 0:714293de3836 2518 while (align < hdrSz)
ashleymills 0:714293de3836 2519 align *= 2;
ashleymills 0:714293de3836 2520 }
ashleymills 0:714293de3836 2521 tmp = (byte*) XMALLOC(size + usedLength + align, ssl->heap,
ashleymills 0:714293de3836 2522 DYNAMIC_TYPE_IN_BUFFER);
ashleymills 0:714293de3836 2523 CYASSL_MSG("growing input buffer\n");
ashleymills 0:714293de3836 2524
ashleymills 0:714293de3836 2525 if (!tmp) return MEMORY_E;
ashleymills 0:714293de3836 2526 if (align)
ashleymills 0:714293de3836 2527 tmp += align - hdrSz;
ashleymills 0:714293de3836 2528
ashleymills 0:714293de3836 2529 if (usedLength)
ashleymills 0:714293de3836 2530 XMEMCPY(tmp, ssl->buffers.inputBuffer.buffer +
ashleymills 0:714293de3836 2531 ssl->buffers.inputBuffer.idx, usedLength);
ashleymills 0:714293de3836 2532
ashleymills 0:714293de3836 2533 if (ssl->buffers.inputBuffer.dynamicFlag)
ashleymills 0:714293de3836 2534 XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
ashleymills 0:714293de3836 2535 ssl->heap,DYNAMIC_TYPE_IN_BUFFER);
ashleymills 0:714293de3836 2536
ashleymills 0:714293de3836 2537 ssl->buffers.inputBuffer.dynamicFlag = 1;
ashleymills 0:714293de3836 2538 if (align)
ashleymills 0:714293de3836 2539 ssl->buffers.inputBuffer.offset = align - hdrSz;
ashleymills 0:714293de3836 2540 else
ashleymills 0:714293de3836 2541 ssl->buffers.inputBuffer.offset = 0;
ashleymills 0:714293de3836 2542 ssl->buffers.inputBuffer.buffer = tmp;
ashleymills 0:714293de3836 2543 ssl->buffers.inputBuffer.bufferSize = size + usedLength;
ashleymills 0:714293de3836 2544 ssl->buffers.inputBuffer.idx = 0;
ashleymills 0:714293de3836 2545 ssl->buffers.inputBuffer.length = usedLength;
ashleymills 0:714293de3836 2546
ashleymills 0:714293de3836 2547 return 0;
ashleymills 0:714293de3836 2548 }
ashleymills 0:714293de3836 2549
ashleymills 0:714293de3836 2550
ashleymills 0:714293de3836 2551 /* check available size into output buffer, make room if needed */
ashleymills 0:714293de3836 2552 int CheckAvailableSize(CYASSL *ssl, int size)
ashleymills 0:714293de3836 2553 {
ashleymills 0:714293de3836 2554 if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length
ashleymills 0:714293de3836 2555 < (word32)size) {
ashleymills 0:714293de3836 2556 if (GrowOutputBuffer(ssl, size) < 0)
ashleymills 0:714293de3836 2557 return MEMORY_E;
ashleymills 0:714293de3836 2558 }
ashleymills 0:714293de3836 2559
ashleymills 0:714293de3836 2560 return 0;
ashleymills 0:714293de3836 2561 }
ashleymills 0:714293de3836 2562
ashleymills 0:714293de3836 2563
ashleymills 0:714293de3836 2564 /* do all verify and sanity checks on record header */
ashleymills 0:714293de3836 2565 static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
ashleymills 0:714293de3836 2566 RecordLayerHeader* rh, word16 *size)
ashleymills 0:714293de3836 2567 {
ashleymills 0:714293de3836 2568 if (!ssl->options.dtls) {
ashleymills 0:714293de3836 2569 XMEMCPY(rh, input + *inOutIdx, RECORD_HEADER_SZ);
ashleymills 0:714293de3836 2570 *inOutIdx += RECORD_HEADER_SZ;
ashleymills 0:714293de3836 2571 ato16(rh->length, size);
ashleymills 0:714293de3836 2572 }
ashleymills 0:714293de3836 2573 else {
ashleymills 0:714293de3836 2574 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 2575 /* type and version in same sport */
ashleymills 0:714293de3836 2576 XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
ashleymills 0:714293de3836 2577 *inOutIdx += ENUM_LEN + VERSION_SZ;
ashleymills 0:714293de3836 2578 ato16(input + *inOutIdx, &ssl->keys.dtls_peer_epoch);
ashleymills 0:714293de3836 2579 *inOutIdx += 4; /* advance past epoch, skip first 2 seq bytes for now */
ashleymills 0:714293de3836 2580 ato32(input + *inOutIdx, &ssl->keys.dtls_peer_sequence_number);
ashleymills 0:714293de3836 2581 *inOutIdx += 4; /* advance past rest of seq */
ashleymills 0:714293de3836 2582 ato16(input + *inOutIdx, size);
ashleymills 0:714293de3836 2583 *inOutIdx += LENGTH_SZ;
ashleymills 0:714293de3836 2584 #endif
ashleymills 0:714293de3836 2585 }
ashleymills 0:714293de3836 2586
ashleymills 0:714293de3836 2587 /* catch version mismatch */
ashleymills 0:714293de3836 2588 if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor){
ashleymills 0:714293de3836 2589 if (ssl->options.side == SERVER_END &&
ashleymills 0:714293de3836 2590 ssl->options.acceptState == ACCEPT_BEGIN)
ashleymills 0:714293de3836 2591 CYASSL_MSG("Client attempting to connect with different version");
ashleymills 0:714293de3836 2592 else if (ssl->options.side == CLIENT_END && ssl->options.downgrade &&
ashleymills 0:714293de3836 2593 ssl->options.connectState < FIRST_REPLY_DONE)
ashleymills 0:714293de3836 2594 CYASSL_MSG("Server attempting to accept with different version");
ashleymills 0:714293de3836 2595 else {
ashleymills 0:714293de3836 2596 CYASSL_MSG("SSL version error");
ashleymills 0:714293de3836 2597 return VERSION_ERROR; /* only use requested version */
ashleymills 0:714293de3836 2598 }
ashleymills 0:714293de3836 2599 }
ashleymills 0:714293de3836 2600 #if 0
ashleymills 0:714293de3836 2601 /* Instead of this, check the datagram against the sliding window of
ashleymills 0:714293de3836 2602 * received datagram goodness. */
ashleymills 0:714293de3836 2603 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 2604 /* If DTLS, check the sequence number against expected. If out of
ashleymills 0:714293de3836 2605 * order, drop the record. Allows newer records in and resets the
ashleymills 0:714293de3836 2606 * expected to the next record. */
ashleymills 0:714293de3836 2607 if (ssl->options.dtls) {
ashleymills 0:714293de3836 2608 if ((ssl->keys.dtls_expected_peer_epoch ==
ashleymills 0:714293de3836 2609 ssl->keys.dtls_peer_epoch) &&
ashleymills 0:714293de3836 2610 (ssl->keys.dtls_peer_sequence_number >=
ashleymills 0:714293de3836 2611 ssl->keys.dtls_expected_peer_sequence_number)) {
ashleymills 0:714293de3836 2612 ssl->keys.dtls_expected_peer_sequence_number =
ashleymills 0:714293de3836 2613 ssl->keys.dtls_peer_sequence_number + 1;
ashleymills 0:714293de3836 2614 }
ashleymills 0:714293de3836 2615 else {
ashleymills 0:714293de3836 2616 return SEQUENCE_ERROR;
ashleymills 0:714293de3836 2617 }
ashleymills 0:714293de3836 2618 }
ashleymills 0:714293de3836 2619 #endif
ashleymills 0:714293de3836 2620 #endif
ashleymills 0:714293de3836 2621 /* record layer length check */
ashleymills 0:714293de3836 2622 if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
ashleymills 0:714293de3836 2623 return LENGTH_ERROR;
ashleymills 0:714293de3836 2624
ashleymills 0:714293de3836 2625 /* verify record type here as well */
ashleymills 0:714293de3836 2626 switch ((enum ContentType)rh->type) {
ashleymills 0:714293de3836 2627 case handshake:
ashleymills 0:714293de3836 2628 case change_cipher_spec:
ashleymills 0:714293de3836 2629 case application_data:
ashleymills 0:714293de3836 2630 case alert:
ashleymills 0:714293de3836 2631 break;
ashleymills 0:714293de3836 2632 case no_type:
ashleymills 0:714293de3836 2633 default:
ashleymills 0:714293de3836 2634 CYASSL_MSG("Unknown Record Type");
ashleymills 0:714293de3836 2635 return UNKNOWN_RECORD_TYPE;
ashleymills 0:714293de3836 2636 }
ashleymills 0:714293de3836 2637
ashleymills 0:714293de3836 2638 /* haven't decrypted this record yet */
ashleymills 0:714293de3836 2639 ssl->keys.decryptedCur = 0;
ashleymills 0:714293de3836 2640
ashleymills 0:714293de3836 2641 return 0;
ashleymills 0:714293de3836 2642 }
ashleymills 0:714293de3836 2643
ashleymills 0:714293de3836 2644
ashleymills 0:714293de3836 2645 static int GetHandShakeHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
ashleymills 0:714293de3836 2646 byte *type, word32 *size)
ashleymills 0:714293de3836 2647 {
ashleymills 0:714293de3836 2648 const byte *ptr = input + *inOutIdx;
ashleymills 0:714293de3836 2649 (void)ssl;
ashleymills 0:714293de3836 2650 *inOutIdx += HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 2651
ashleymills 0:714293de3836 2652 *type = ptr[0];
ashleymills 0:714293de3836 2653 c24to32(&ptr[1], size);
ashleymills 0:714293de3836 2654
ashleymills 0:714293de3836 2655 return 0;
ashleymills 0:714293de3836 2656 }
ashleymills 0:714293de3836 2657
ashleymills 0:714293de3836 2658
ashleymills 0:714293de3836 2659 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 2660 static int GetDtlsHandShakeHeader(CYASSL* ssl, const byte* input,
ashleymills 0:714293de3836 2661 word32* inOutIdx, byte *type, word32 *size,
ashleymills 0:714293de3836 2662 word32 *fragOffset, word32 *fragSz)
ashleymills 0:714293de3836 2663 {
ashleymills 0:714293de3836 2664 word32 idx = *inOutIdx;
ashleymills 0:714293de3836 2665
ashleymills 0:714293de3836 2666 *inOutIdx += HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 2667
ashleymills 0:714293de3836 2668 *type = input[idx++];
ashleymills 0:714293de3836 2669 c24to32(input + idx, size);
ashleymills 0:714293de3836 2670 idx += BYTE3_LEN;
ashleymills 0:714293de3836 2671
ashleymills 0:714293de3836 2672 ato16(input + idx, &ssl->keys.dtls_peer_handshake_number);
ashleymills 0:714293de3836 2673 idx += DTLS_HANDSHAKE_SEQ_SZ;
ashleymills 0:714293de3836 2674
ashleymills 0:714293de3836 2675 c24to32(input + idx, fragOffset);
ashleymills 0:714293de3836 2676 idx += DTLS_HANDSHAKE_FRAG_SZ;
ashleymills 0:714293de3836 2677 c24to32(input + idx, fragSz);
ashleymills 0:714293de3836 2678
ashleymills 0:714293de3836 2679 return 0;
ashleymills 0:714293de3836 2680 }
ashleymills 0:714293de3836 2681 #endif
ashleymills 0:714293de3836 2682
ashleymills 0:714293de3836 2683
ashleymills 0:714293de3836 2684 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 2685 /* fill with MD5 pad size since biggest required */
ashleymills 0:714293de3836 2686 static const byte PAD1[PAD_MD5] =
ashleymills 0:714293de3836 2687 { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
ashleymills 0:714293de3836 2688 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
ashleymills 0:714293de3836 2689 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
ashleymills 0:714293de3836 2690 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
ashleymills 0:714293de3836 2691 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
ashleymills 0:714293de3836 2692 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
ashleymills 0:714293de3836 2693 };
ashleymills 0:714293de3836 2694 static const byte PAD2[PAD_MD5] =
ashleymills 0:714293de3836 2695 { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
ashleymills 0:714293de3836 2696 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
ashleymills 0:714293de3836 2697 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
ashleymills 0:714293de3836 2698 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
ashleymills 0:714293de3836 2699 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
ashleymills 0:714293de3836 2700 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
ashleymills 0:714293de3836 2701 };
ashleymills 0:714293de3836 2702
ashleymills 0:714293de3836 2703 /* calculate MD5 hash for finished */
ashleymills 0:714293de3836 2704 static void BuildMD5(CYASSL* ssl, Hashes* hashes, const byte* sender)
ashleymills 0:714293de3836 2705 {
ashleymills 0:714293de3836 2706 byte md5_result[MD5_DIGEST_SIZE];
ashleymills 0:714293de3836 2707
ashleymills 0:714293de3836 2708 /* make md5 inner */
ashleymills 0:714293de3836 2709 Md5Update(&ssl->hashMd5, sender, SIZEOF_SENDER);
ashleymills 0:714293de3836 2710 Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:714293de3836 2711 Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
ashleymills 0:714293de3836 2712 Md5Final(&ssl->hashMd5, md5_result);
ashleymills 0:714293de3836 2713
ashleymills 0:714293de3836 2714 /* make md5 outer */
ashleymills 0:714293de3836 2715 Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:714293de3836 2716 Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
ashleymills 0:714293de3836 2717 Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
ashleymills 0:714293de3836 2718
ashleymills 0:714293de3836 2719 Md5Final(&ssl->hashMd5, hashes->md5);
ashleymills 0:714293de3836 2720 }
ashleymills 0:714293de3836 2721
ashleymills 0:714293de3836 2722
ashleymills 0:714293de3836 2723 /* calculate SHA hash for finished */
ashleymills 0:714293de3836 2724 static void BuildSHA(CYASSL* ssl, Hashes* hashes, const byte* sender)
ashleymills 0:714293de3836 2725 {
ashleymills 0:714293de3836 2726 byte sha_result[SHA_DIGEST_SIZE];
ashleymills 0:714293de3836 2727
ashleymills 0:714293de3836 2728 /* make sha inner */
ashleymills 0:714293de3836 2729 ShaUpdate(&ssl->hashSha, sender, SIZEOF_SENDER);
ashleymills 0:714293de3836 2730 ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:714293de3836 2731 ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
ashleymills 0:714293de3836 2732 ShaFinal(&ssl->hashSha, sha_result);
ashleymills 0:714293de3836 2733
ashleymills 0:714293de3836 2734 /* make sha outer */
ashleymills 0:714293de3836 2735 ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:714293de3836 2736 ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
ashleymills 0:714293de3836 2737 ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
ashleymills 0:714293de3836 2738
ashleymills 0:714293de3836 2739 ShaFinal(&ssl->hashSha, hashes->sha);
ashleymills 0:714293de3836 2740 }
ashleymills 0:714293de3836 2741 #endif
ashleymills 0:714293de3836 2742
ashleymills 0:714293de3836 2743
ashleymills 0:714293de3836 2744 static void BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
ashleymills 0:714293de3836 2745 {
ashleymills 0:714293de3836 2746 /* store current states, building requires get_digest which resets state */
ashleymills 0:714293de3836 2747 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 2748 #ifndef NO_MD5
ashleymills 0:714293de3836 2749 Md5 md5 = ssl->hashMd5;
ashleymills 0:714293de3836 2750 #endif
ashleymills 0:714293de3836 2751 #ifndef NO_SHA
ashleymills 0:714293de3836 2752 Sha sha = ssl->hashSha;
ashleymills 0:714293de3836 2753 #endif
ashleymills 0:714293de3836 2754 #endif
ashleymills 0:714293de3836 2755 #ifndef NO_SHA256
ashleymills 0:714293de3836 2756 Sha256 sha256 = ssl->hashSha256;
ashleymills 0:714293de3836 2757 #endif
ashleymills 0:714293de3836 2758 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 2759 Sha384 sha384 = ssl->hashSha384;
ashleymills 0:714293de3836 2760 #endif
ashleymills 0:714293de3836 2761
ashleymills 0:714293de3836 2762 #ifndef NO_TLS
ashleymills 0:714293de3836 2763 if (ssl->options.tls) {
ashleymills 0:714293de3836 2764 BuildTlsFinished(ssl, hashes, sender);
ashleymills 0:714293de3836 2765 }
ashleymills 0:714293de3836 2766 #endif
ashleymills 0:714293de3836 2767 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 2768 if (!ssl->options.tls) {
ashleymills 0:714293de3836 2769 BuildMD5(ssl, hashes, sender);
ashleymills 0:714293de3836 2770 BuildSHA(ssl, hashes, sender);
ashleymills 0:714293de3836 2771 }
ashleymills 0:714293de3836 2772 #endif
ashleymills 0:714293de3836 2773
ashleymills 0:714293de3836 2774 /* restore */
ashleymills 0:714293de3836 2775 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 2776 #ifndef NO_MD5
ashleymills 0:714293de3836 2777 ssl->hashMd5 = md5;
ashleymills 0:714293de3836 2778 #endif
ashleymills 0:714293de3836 2779 #ifndef NO_SHA
ashleymills 0:714293de3836 2780 ssl->hashSha = sha;
ashleymills 0:714293de3836 2781 #endif
ashleymills 0:714293de3836 2782 #endif
ashleymills 0:714293de3836 2783 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 2784 #ifndef NO_SHA256
ashleymills 0:714293de3836 2785 ssl->hashSha256 = sha256;
ashleymills 0:714293de3836 2786 #endif
ashleymills 0:714293de3836 2787 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 2788 ssl->hashSha384 = sha384;
ashleymills 0:714293de3836 2789 #endif
ashleymills 0:714293de3836 2790 }
ashleymills 0:714293de3836 2791 }
ashleymills 0:714293de3836 2792
ashleymills 0:714293de3836 2793
ashleymills 0:714293de3836 2794 #ifndef NO_CERTS
ashleymills 0:714293de3836 2795
ashleymills 0:714293de3836 2796
ashleymills 0:714293de3836 2797 /* Match names with wildcards, each wildcard can represent a single name
ashleymills 0:714293de3836 2798 component or fragment but not mulitple names, i.e.,
ashleymills 0:714293de3836 2799 *.z.com matches y.z.com but not x.y.z.com
ashleymills 0:714293de3836 2800
ashleymills 0:714293de3836 2801 return 1 on success */
ashleymills 0:714293de3836 2802 static int MatchDomainName(const char* pattern, int len, const char* str)
ashleymills 0:714293de3836 2803 {
ashleymills 0:714293de3836 2804 char p, s;
ashleymills 0:714293de3836 2805
ashleymills 0:714293de3836 2806 if (pattern == NULL || str == NULL || len <= 0)
ashleymills 0:714293de3836 2807 return 0;
ashleymills 0:714293de3836 2808
ashleymills 0:714293de3836 2809 while (len > 0 && (p = (char)(*pattern++))) {
ashleymills 0:714293de3836 2810 if (p == '*') {
ashleymills 0:714293de3836 2811 while (--len > 0 && (p = (char)(*pattern++)) == '*')
ashleymills 0:714293de3836 2812 ;
ashleymills 0:714293de3836 2813
ashleymills 0:714293de3836 2814 if (len == 0)
ashleymills 0:714293de3836 2815 p = '\0';
ashleymills 0:714293de3836 2816
ashleymills 0:714293de3836 2817 while ( (s = (char)(*str)) != '\0') {
ashleymills 0:714293de3836 2818 if (s == p)
ashleymills 0:714293de3836 2819 break;
ashleymills 0:714293de3836 2820 if (s == '.')
ashleymills 0:714293de3836 2821 return 0;
ashleymills 0:714293de3836 2822 str++;
ashleymills 0:714293de3836 2823 }
ashleymills 0:714293de3836 2824 }
ashleymills 0:714293de3836 2825 else {
ashleymills 0:714293de3836 2826 if (p != (char)(*str))
ashleymills 0:714293de3836 2827 return 0;
ashleymills 0:714293de3836 2828 }
ashleymills 0:714293de3836 2829
ashleymills 0:714293de3836 2830 if (*str != '\0')
ashleymills 0:714293de3836 2831 str++;
ashleymills 0:714293de3836 2832
ashleymills 0:714293de3836 2833 if (len > 0)
ashleymills 0:714293de3836 2834 len--;
ashleymills 0:714293de3836 2835 }
ashleymills 0:714293de3836 2836
ashleymills 0:714293de3836 2837 return *str == '\0';
ashleymills 0:714293de3836 2838 }
ashleymills 0:714293de3836 2839
ashleymills 0:714293de3836 2840
ashleymills 0:714293de3836 2841 /* try to find an altName match to domain, return 1 on success */
ashleymills 0:714293de3836 2842 static int CheckAltNames(DecodedCert* dCert, char* domain)
ashleymills 0:714293de3836 2843 {
ashleymills 0:714293de3836 2844 int match = 0;
ashleymills 0:714293de3836 2845 DNS_entry* altName = NULL;
ashleymills 0:714293de3836 2846
ashleymills 0:714293de3836 2847 CYASSL_MSG("Checking AltNames");
ashleymills 0:714293de3836 2848
ashleymills 0:714293de3836 2849 if (dCert)
ashleymills 0:714293de3836 2850 altName = dCert->altNames;
ashleymills 0:714293de3836 2851
ashleymills 0:714293de3836 2852 while (altName) {
ashleymills 0:714293de3836 2853 CYASSL_MSG(" individual AltName check");
ashleymills 0:714293de3836 2854
ashleymills 0:714293de3836 2855 if (MatchDomainName(altName->name,(int)XSTRLEN(altName->name), domain)){
ashleymills 0:714293de3836 2856 match = 1;
ashleymills 0:714293de3836 2857 break;
ashleymills 0:714293de3836 2858 }
ashleymills 0:714293de3836 2859
ashleymills 0:714293de3836 2860 altName = altName->next;
ashleymills 0:714293de3836 2861 }
ashleymills 0:714293de3836 2862
ashleymills 0:714293de3836 2863 return match;
ashleymills 0:714293de3836 2864 }
ashleymills 0:714293de3836 2865
ashleymills 0:714293de3836 2866
ashleymills 0:714293de3836 2867 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
ashleymills 0:714293de3836 2868
ashleymills 0:714293de3836 2869 /* Copy parts X509 needs from Decoded cert, 0 on success */
ashleymills 0:714293de3836 2870 int CopyDecodedToX509(CYASSL_X509* x509, DecodedCert* dCert)
ashleymills 0:714293de3836 2871 {
ashleymills 0:714293de3836 2872 int ret = 0;
ashleymills 0:714293de3836 2873
ashleymills 0:714293de3836 2874 if (x509 == NULL || dCert == NULL)
ashleymills 0:714293de3836 2875 return BAD_FUNC_ARG;
ashleymills 0:714293de3836 2876
ashleymills 0:714293de3836 2877 XSTRNCPY(x509->issuer.name, dCert->issuer, ASN_NAME_MAX);
ashleymills 0:714293de3836 2878 x509->issuer.name[ASN_NAME_MAX - 1] = '\0';
ashleymills 0:714293de3836 2879 x509->issuer.sz = (int)XSTRLEN(x509->issuer.name) + 1;
ashleymills 0:714293de3836 2880
ashleymills 0:714293de3836 2881 XSTRNCPY(x509->subject.name, dCert->subject, ASN_NAME_MAX);
ashleymills 0:714293de3836 2882 x509->subject.name[ASN_NAME_MAX - 1] = '\0';
ashleymills 0:714293de3836 2883 x509->subject.sz = (int)XSTRLEN(x509->subject.name) + 1;
ashleymills 0:714293de3836 2884
ashleymills 0:714293de3836 2885 XMEMCPY(x509->serial, dCert->serial, EXTERNAL_SERIAL_SIZE);
ashleymills 0:714293de3836 2886 x509->serialSz = dCert->serialSz;
ashleymills 0:714293de3836 2887 if (dCert->subjectCNLen < ASN_NAME_MAX) {
ashleymills 0:714293de3836 2888 XMEMCPY(x509->subjectCN, dCert->subjectCN, dCert->subjectCNLen);
ashleymills 0:714293de3836 2889 x509->subjectCN[dCert->subjectCNLen] = '\0';
ashleymills 0:714293de3836 2890 }
ashleymills 0:714293de3836 2891 else
ashleymills 0:714293de3836 2892 x509->subjectCN[0] = '\0';
ashleymills 0:714293de3836 2893
ashleymills 0:714293de3836 2894 /* store cert for potential retrieval */
ashleymills 0:714293de3836 2895 x509->derCert.buffer = (byte*)XMALLOC(dCert->maxIdx, NULL,
ashleymills 0:714293de3836 2896 DYNAMIC_TYPE_CERT);
ashleymills 0:714293de3836 2897 if (x509->derCert.buffer == NULL) {
ashleymills 0:714293de3836 2898 ret = MEMORY_E;
ashleymills 0:714293de3836 2899 }
ashleymills 0:714293de3836 2900 else {
ashleymills 0:714293de3836 2901 XMEMCPY(x509->derCert.buffer, dCert->source, dCert->maxIdx);
ashleymills 0:714293de3836 2902 x509->derCert.length = dCert->maxIdx;
ashleymills 0:714293de3836 2903 }
ashleymills 0:714293de3836 2904
ashleymills 0:714293de3836 2905 x509->altNames = dCert->altNames;
ashleymills 0:714293de3836 2906 dCert->altNames = NULL; /* takes ownership */
ashleymills 0:714293de3836 2907 x509->altNamesNext = x509->altNames; /* index hint */
ashleymills 0:714293de3836 2908
ashleymills 0:714293de3836 2909 return ret;
ashleymills 0:714293de3836 2910 }
ashleymills 0:714293de3836 2911
ashleymills 0:714293de3836 2912 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
ashleymills 0:714293de3836 2913
ashleymills 0:714293de3836 2914
ashleymills 0:714293de3836 2915 static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
ashleymills 0:714293de3836 2916 {
ashleymills 0:714293de3836 2917 word32 listSz, i = *inOutIdx;
ashleymills 0:714293de3836 2918 int ret = 0;
ashleymills 0:714293de3836 2919 int anyError = 0;
ashleymills 0:714293de3836 2920 int totalCerts = 0; /* number of certs in certs buffer */
ashleymills 0:714293de3836 2921 int count;
ashleymills 0:714293de3836 2922 char domain[ASN_NAME_MAX];
ashleymills 0:714293de3836 2923 buffer certs[MAX_CHAIN_DEPTH];
ashleymills 0:714293de3836 2924
ashleymills 0:714293de3836 2925 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 2926 if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
ashleymills 0:714293de3836 2927 if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo);
ashleymills 0:714293de3836 2928 #endif
ashleymills 0:714293de3836 2929 c24to32(&input[i], &listSz);
ashleymills 0:714293de3836 2930 i += CERT_HEADER_SZ;
ashleymills 0:714293de3836 2931
ashleymills 0:714293de3836 2932 CYASSL_MSG("Loading peer's cert chain");
ashleymills 0:714293de3836 2933 /* first put cert chain into buffer so can verify top down
ashleymills 0:714293de3836 2934 we're sent bottom up */
ashleymills 0:714293de3836 2935 while (listSz) {
ashleymills 0:714293de3836 2936 /* cert size */
ashleymills 0:714293de3836 2937 word32 certSz;
ashleymills 0:714293de3836 2938
ashleymills 0:714293de3836 2939 if (totalCerts >= MAX_CHAIN_DEPTH)
ashleymills 0:714293de3836 2940 return MAX_CHAIN_ERROR;
ashleymills 0:714293de3836 2941
ashleymills 0:714293de3836 2942 c24to32(&input[i], &certSz);
ashleymills 0:714293de3836 2943 i += CERT_HEADER_SZ;
ashleymills 0:714293de3836 2944
ashleymills 0:714293de3836 2945 if (listSz > MAX_RECORD_SIZE || certSz > MAX_RECORD_SIZE)
ashleymills 0:714293de3836 2946 return BUFFER_E;
ashleymills 0:714293de3836 2947
ashleymills 0:714293de3836 2948 certs[totalCerts].length = certSz;
ashleymills 0:714293de3836 2949 certs[totalCerts].buffer = input + i;
ashleymills 0:714293de3836 2950
ashleymills 0:714293de3836 2951 #ifdef SESSION_CERTS
ashleymills 0:714293de3836 2952 if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
ashleymills 0:714293de3836 2953 certSz < MAX_X509_SIZE) {
ashleymills 0:714293de3836 2954 ssl->session.chain.certs[ssl->session.chain.count].length = certSz;
ashleymills 0:714293de3836 2955 XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer,
ashleymills 0:714293de3836 2956 input + i, certSz);
ashleymills 0:714293de3836 2957 ssl->session.chain.count++;
ashleymills 0:714293de3836 2958 } else {
ashleymills 0:714293de3836 2959 CYASSL_MSG("Couldn't store chain cert for session");
ashleymills 0:714293de3836 2960 }
ashleymills 0:714293de3836 2961 #endif
ashleymills 0:714293de3836 2962
ashleymills 0:714293de3836 2963 i += certSz;
ashleymills 0:714293de3836 2964 listSz -= certSz + CERT_HEADER_SZ;
ashleymills 0:714293de3836 2965
ashleymills 0:714293de3836 2966 totalCerts++;
ashleymills 0:714293de3836 2967 CYASSL_MSG(" Put another cert into chain");
ashleymills 0:714293de3836 2968 }
ashleymills 0:714293de3836 2969
ashleymills 0:714293de3836 2970 count = totalCerts;
ashleymills 0:714293de3836 2971
ashleymills 0:714293de3836 2972 /* verify up to peer's first */
ashleymills 0:714293de3836 2973 while (count > 1) {
ashleymills 0:714293de3836 2974 buffer myCert = certs[count - 1];
ashleymills 0:714293de3836 2975 DecodedCert dCert;
ashleymills 0:714293de3836 2976 byte* subjectHash;
ashleymills 0:714293de3836 2977
ashleymills 0:714293de3836 2978 InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
ashleymills 0:714293de3836 2979 ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
ashleymills 0:714293de3836 2980 ssl->ctx->cm);
ashleymills 0:714293de3836 2981 #ifndef NO_SKID
ashleymills 0:714293de3836 2982 subjectHash = dCert.extSubjKeyId;
ashleymills 0:714293de3836 2983 #else
ashleymills 0:714293de3836 2984 subjectHash = dCert.subjectHash;
ashleymills 0:714293de3836 2985 #endif
ashleymills 0:714293de3836 2986
ashleymills 0:714293de3836 2987 if (ret == 0 && dCert.isCA == 0) {
ashleymills 0:714293de3836 2988 CYASSL_MSG("Chain cert is not a CA, not adding as one");
ashleymills 0:714293de3836 2989 }
ashleymills 0:714293de3836 2990 else if (ret == 0 && ssl->options.verifyNone) {
ashleymills 0:714293de3836 2991 CYASSL_MSG("Chain cert not verified by option, not adding as CA");
ashleymills 0:714293de3836 2992 }
ashleymills 0:714293de3836 2993 else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, subjectHash)) {
ashleymills 0:714293de3836 2994 buffer add;
ashleymills 0:714293de3836 2995 add.length = myCert.length;
ashleymills 0:714293de3836 2996 add.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
ashleymills 0:714293de3836 2997 DYNAMIC_TYPE_CA);
ashleymills 0:714293de3836 2998 CYASSL_MSG("Adding CA from chain");
ashleymills 0:714293de3836 2999
ashleymills 0:714293de3836 3000 if (add.buffer == NULL)
ashleymills 0:714293de3836 3001 return MEMORY_E;
ashleymills 0:714293de3836 3002 XMEMCPY(add.buffer, myCert.buffer, myCert.length);
ashleymills 0:714293de3836 3003
ashleymills 0:714293de3836 3004 ret = AddCA(ssl->ctx->cm, add, CYASSL_CHAIN_CA,
ashleymills 0:714293de3836 3005 ssl->ctx->verifyPeer);
ashleymills 0:714293de3836 3006 if (ret == 1) ret = 0; /* SSL_SUCCESS for external */
ashleymills 0:714293de3836 3007 }
ashleymills 0:714293de3836 3008 else if (ret != 0) {
ashleymills 0:714293de3836 3009 CYASSL_MSG("Failed to verify CA from chain");
ashleymills 0:714293de3836 3010 }
ashleymills 0:714293de3836 3011 else {
ashleymills 0:714293de3836 3012 CYASSL_MSG("Verified CA from chain and already had it");
ashleymills 0:714293de3836 3013 }
ashleymills 0:714293de3836 3014
ashleymills 0:714293de3836 3015 #ifdef HAVE_CRL
ashleymills 0:714293de3836 3016 if (ret == 0 && ssl->ctx->cm->crlEnabled && ssl->ctx->cm->crlCheckAll) {
ashleymills 0:714293de3836 3017 CYASSL_MSG("Doing Non Leaf CRL check");
ashleymills 0:714293de3836 3018 ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert);
ashleymills 0:714293de3836 3019
ashleymills 0:714293de3836 3020 if (ret != 0) {
ashleymills 0:714293de3836 3021 CYASSL_MSG("\tCRL check not ok");
ashleymills 0:714293de3836 3022 }
ashleymills 0:714293de3836 3023 }
ashleymills 0:714293de3836 3024 #endif /* HAVE_CRL */
ashleymills 0:714293de3836 3025
ashleymills 0:714293de3836 3026 if (ret != 0 && anyError == 0)
ashleymills 0:714293de3836 3027 anyError = ret; /* save error from last time */
ashleymills 0:714293de3836 3028
ashleymills 0:714293de3836 3029 FreeDecodedCert(&dCert);
ashleymills 0:714293de3836 3030 count--;
ashleymills 0:714293de3836 3031 }
ashleymills 0:714293de3836 3032
ashleymills 0:714293de3836 3033 /* peer's, may not have one if blank client cert sent by TLSv1.2 */
ashleymills 0:714293de3836 3034 if (count) {
ashleymills 0:714293de3836 3035 buffer myCert = certs[0];
ashleymills 0:714293de3836 3036 DecodedCert dCert;
ashleymills 0:714293de3836 3037 int fatal = 0;
ashleymills 0:714293de3836 3038
ashleymills 0:714293de3836 3039 CYASSL_MSG("Verifying Peer's cert");
ashleymills 0:714293de3836 3040
ashleymills 0:714293de3836 3041 InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
ashleymills 0:714293de3836 3042 ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
ashleymills 0:714293de3836 3043 ssl->ctx->cm);
ashleymills 0:714293de3836 3044 if (ret == 0) {
ashleymills 0:714293de3836 3045 CYASSL_MSG("Verified Peer's cert");
ashleymills 0:714293de3836 3046 fatal = 0;
ashleymills 0:714293de3836 3047 }
ashleymills 0:714293de3836 3048 else if (ret == ASN_PARSE_E) {
ashleymills 0:714293de3836 3049 CYASSL_MSG("Got Peer cert ASN PARSE ERROR, fatal");
ashleymills 0:714293de3836 3050 fatal = 1;
ashleymills 0:714293de3836 3051 }
ashleymills 0:714293de3836 3052 else {
ashleymills 0:714293de3836 3053 CYASSL_MSG("Failed to verify Peer's cert");
ashleymills 0:714293de3836 3054 if (ssl->verifyCallback) {
ashleymills 0:714293de3836 3055 CYASSL_MSG("\tCallback override available, will continue");
ashleymills 0:714293de3836 3056 fatal = 0;
ashleymills 0:714293de3836 3057 }
ashleymills 0:714293de3836 3058 else {
ashleymills 0:714293de3836 3059 CYASSL_MSG("\tNo callback override available, fatal");
ashleymills 0:714293de3836 3060 fatal = 1;
ashleymills 0:714293de3836 3061 }
ashleymills 0:714293de3836 3062 }
ashleymills 0:714293de3836 3063
ashleymills 0:714293de3836 3064 #ifdef HAVE_OCSP
ashleymills 0:714293de3836 3065 if (fatal == 0) {
ashleymills 0:714293de3836 3066 ret = CyaSSL_OCSP_Lookup_Cert(&ssl->ctx->ocsp, &dCert);
ashleymills 0:714293de3836 3067 if (ret != 0) {
ashleymills 0:714293de3836 3068 CYASSL_MSG("\tOCSP Lookup not ok");
ashleymills 0:714293de3836 3069 fatal = 0;
ashleymills 0:714293de3836 3070 }
ashleymills 0:714293de3836 3071 }
ashleymills 0:714293de3836 3072 #endif
ashleymills 0:714293de3836 3073
ashleymills 0:714293de3836 3074 #ifdef HAVE_CRL
ashleymills 0:714293de3836 3075 if (fatal == 0 && ssl->ctx->cm->crlEnabled) {
ashleymills 0:714293de3836 3076 int doCrlLookup = 1;
ashleymills 0:714293de3836 3077
ashleymills 0:714293de3836 3078 #ifdef HAVE_OCSP
ashleymills 0:714293de3836 3079 if (ssl->ctx->ocsp.enabled) {
ashleymills 0:714293de3836 3080 doCrlLookup = (ret == OCSP_CERT_UNKNOWN);
ashleymills 0:714293de3836 3081 }
ashleymills 0:714293de3836 3082 #endif /* HAVE_OCSP */
ashleymills 0:714293de3836 3083
ashleymills 0:714293de3836 3084 if (doCrlLookup) {
ashleymills 0:714293de3836 3085 CYASSL_MSG("Doing Leaf CRL check");
ashleymills 0:714293de3836 3086 ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert);
ashleymills 0:714293de3836 3087
ashleymills 0:714293de3836 3088 if (ret != 0) {
ashleymills 0:714293de3836 3089 CYASSL_MSG("\tCRL check not ok");
ashleymills 0:714293de3836 3090 fatal = 0;
ashleymills 0:714293de3836 3091 }
ashleymills 0:714293de3836 3092 }
ashleymills 0:714293de3836 3093 }
ashleymills 0:714293de3836 3094
ashleymills 0:714293de3836 3095 #endif /* HAVE_CRL */
ashleymills 0:714293de3836 3096
ashleymills 0:714293de3836 3097 #ifdef KEEP_PEER_CERT
ashleymills 0:714293de3836 3098 {
ashleymills 0:714293de3836 3099 /* set X509 format for peer cert even if fatal */
ashleymills 0:714293de3836 3100 int copyRet = CopyDecodedToX509(&ssl->peerCert, &dCert);
ashleymills 0:714293de3836 3101 if (copyRet == MEMORY_E)
ashleymills 0:714293de3836 3102 fatal = 1;
ashleymills 0:714293de3836 3103 }
ashleymills 0:714293de3836 3104 #endif
ashleymills 0:714293de3836 3105
ashleymills 0:714293de3836 3106 if (fatal) {
ashleymills 0:714293de3836 3107 FreeDecodedCert(&dCert);
ashleymills 0:714293de3836 3108 ssl->error = ret;
ashleymills 0:714293de3836 3109 return ret;
ashleymills 0:714293de3836 3110 }
ashleymills 0:714293de3836 3111 ssl->options.havePeerCert = 1;
ashleymills 0:714293de3836 3112
ashleymills 0:714293de3836 3113 /* store for callback use */
ashleymills 0:714293de3836 3114 if (dCert.subjectCNLen < ASN_NAME_MAX) {
ashleymills 0:714293de3836 3115 XMEMCPY(domain, dCert.subjectCN, dCert.subjectCNLen);
ashleymills 0:714293de3836 3116 domain[dCert.subjectCNLen] = '\0';
ashleymills 0:714293de3836 3117 }
ashleymills 0:714293de3836 3118 else
ashleymills 0:714293de3836 3119 domain[0] = '\0';
ashleymills 0:714293de3836 3120
ashleymills 0:714293de3836 3121 if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer) {
ashleymills 0:714293de3836 3122 if (MatchDomainName(dCert.subjectCN, dCert.subjectCNLen,
ashleymills 0:714293de3836 3123 (char*)ssl->buffers.domainName.buffer) == 0) {
ashleymills 0:714293de3836 3124 CYASSL_MSG("DomainName match on common name failed");
ashleymills 0:714293de3836 3125 if (CheckAltNames(&dCert,
ashleymills 0:714293de3836 3126 (char*)ssl->buffers.domainName.buffer) == 0 ) {
ashleymills 0:714293de3836 3127 CYASSL_MSG("DomainName match on alt names failed too");
ashleymills 0:714293de3836 3128 ret = DOMAIN_NAME_MISMATCH; /* try to get peer key still */
ashleymills 0:714293de3836 3129 }
ashleymills 0:714293de3836 3130 }
ashleymills 0:714293de3836 3131 }
ashleymills 0:714293de3836 3132
ashleymills 0:714293de3836 3133 /* decode peer key */
ashleymills 0:714293de3836 3134 switch (dCert.keyOID) {
ashleymills 0:714293de3836 3135 #ifndef NO_RSA
ashleymills 0:714293de3836 3136 case RSAk:
ashleymills 0:714293de3836 3137 {
ashleymills 0:714293de3836 3138 word32 idx = 0;
ashleymills 0:714293de3836 3139 if (RsaPublicKeyDecode(dCert.publicKey, &idx,
ashleymills 0:714293de3836 3140 ssl->peerRsaKey, dCert.pubKeySize) != 0) {
ashleymills 0:714293de3836 3141 ret = PEER_KEY_ERROR;
ashleymills 0:714293de3836 3142 }
ashleymills 0:714293de3836 3143 else
ashleymills 0:714293de3836 3144 ssl->peerRsaKeyPresent = 1;
ashleymills 0:714293de3836 3145 }
ashleymills 0:714293de3836 3146 break;
ashleymills 0:714293de3836 3147 #endif /* NO_RSA */
ashleymills 0:714293de3836 3148 #ifdef HAVE_NTRU
ashleymills 0:714293de3836 3149 case NTRUk:
ashleymills 0:714293de3836 3150 {
ashleymills 0:714293de3836 3151 if (dCert.pubKeySize > sizeof(ssl->peerNtruKey)) {
ashleymills 0:714293de3836 3152 ret = PEER_KEY_ERROR;
ashleymills 0:714293de3836 3153 }
ashleymills 0:714293de3836 3154 else {
ashleymills 0:714293de3836 3155 XMEMCPY(ssl->peerNtruKey, dCert.publicKey, dCert.pubKeySize);
ashleymills 0:714293de3836 3156 ssl->peerNtruKeyLen = (word16)dCert.pubKeySize;
ashleymills 0:714293de3836 3157 ssl->peerNtruKeyPresent = 1;
ashleymills 0:714293de3836 3158 }
ashleymills 0:714293de3836 3159 }
ashleymills 0:714293de3836 3160 break;
ashleymills 0:714293de3836 3161 #endif /* HAVE_NTRU */
ashleymills 0:714293de3836 3162 #ifdef HAVE_ECC
ashleymills 0:714293de3836 3163 case ECDSAk:
ashleymills 0:714293de3836 3164 {
ashleymills 0:714293de3836 3165 if (ecc_import_x963(dCert.publicKey, dCert.pubKeySize,
ashleymills 0:714293de3836 3166 ssl->peerEccDsaKey) != 0) {
ashleymills 0:714293de3836 3167 ret = PEER_KEY_ERROR;
ashleymills 0:714293de3836 3168 }
ashleymills 0:714293de3836 3169 else
ashleymills 0:714293de3836 3170 ssl->peerEccDsaKeyPresent = 1;
ashleymills 0:714293de3836 3171 }
ashleymills 0:714293de3836 3172 break;
ashleymills 0:714293de3836 3173 #endif /* HAVE_ECC */
ashleymills 0:714293de3836 3174 default:
ashleymills 0:714293de3836 3175 break;
ashleymills 0:714293de3836 3176 }
ashleymills 0:714293de3836 3177
ashleymills 0:714293de3836 3178 FreeDecodedCert(&dCert);
ashleymills 0:714293de3836 3179 }
ashleymills 0:714293de3836 3180
ashleymills 0:714293de3836 3181 if (anyError != 0 && ret == 0)
ashleymills 0:714293de3836 3182 ret = anyError;
ashleymills 0:714293de3836 3183
ashleymills 0:714293de3836 3184 if (ret == 0 && ssl->options.side == CLIENT_END)
ashleymills 0:714293de3836 3185 ssl->options.serverState = SERVER_CERT_COMPLETE;
ashleymills 0:714293de3836 3186
ashleymills 0:714293de3836 3187 if (ret != 0) {
ashleymills 0:714293de3836 3188 if (!ssl->options.verifyNone) {
ashleymills 0:714293de3836 3189 int why = bad_certificate;
ashleymills 0:714293de3836 3190 if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E)
ashleymills 0:714293de3836 3191 why = certificate_expired;
ashleymills 0:714293de3836 3192 if (ssl->verifyCallback) {
ashleymills 0:714293de3836 3193 int ok;
ashleymills 0:714293de3836 3194 CYASSL_X509_STORE_CTX store;
ashleymills 0:714293de3836 3195
ashleymills 0:714293de3836 3196 store.error = ret;
ashleymills 0:714293de3836 3197 store.error_depth = totalCerts;
ashleymills 0:714293de3836 3198 store.discardSessionCerts = 0;
ashleymills 0:714293de3836 3199 store.domain = domain;
ashleymills 0:714293de3836 3200 store.userCtx = ssl->verifyCbCtx;
ashleymills 0:714293de3836 3201 #ifdef KEEP_PEER_CERT
ashleymills 0:714293de3836 3202 store.current_cert = &ssl->peerCert;
ashleymills 0:714293de3836 3203 #else
ashleymills 0:714293de3836 3204 store.current_cert = NULL;
ashleymills 0:714293de3836 3205 #endif
ashleymills 0:714293de3836 3206 #ifdef FORTRESS
ashleymills 0:714293de3836 3207 store.ex_data = ssl;
ashleymills 0:714293de3836 3208 #endif
ashleymills 0:714293de3836 3209 ok = ssl->verifyCallback(0, &store);
ashleymills 0:714293de3836 3210 if (ok) {
ashleymills 0:714293de3836 3211 CYASSL_MSG("Verify callback overriding error!");
ashleymills 0:714293de3836 3212 ret = 0;
ashleymills 0:714293de3836 3213 }
ashleymills 0:714293de3836 3214 #ifdef SESSION_CERTS
ashleymills 0:714293de3836 3215 if (store.discardSessionCerts) {
ashleymills 0:714293de3836 3216 CYASSL_MSG("Verify callback requested discard sess certs");
ashleymills 0:714293de3836 3217 ssl->session.chain.count = 0;
ashleymills 0:714293de3836 3218 }
ashleymills 0:714293de3836 3219 #endif
ashleymills 0:714293de3836 3220 }
ashleymills 0:714293de3836 3221 if (ret != 0) {
ashleymills 0:714293de3836 3222 SendAlert(ssl, alert_fatal, why); /* try to send */
ashleymills 0:714293de3836 3223 ssl->options.isClosed = 1;
ashleymills 0:714293de3836 3224 }
ashleymills 0:714293de3836 3225 }
ashleymills 0:714293de3836 3226 ssl->error = ret;
ashleymills 0:714293de3836 3227 }
ashleymills 0:714293de3836 3228 #ifdef FORTRESS
ashleymills 0:714293de3836 3229 else {
ashleymills 0:714293de3836 3230 if (ssl->verifyCallback) {
ashleymills 0:714293de3836 3231 int ok;
ashleymills 0:714293de3836 3232 CYASSL_X509_STORE_CTX store;
ashleymills 0:714293de3836 3233
ashleymills 0:714293de3836 3234 store.error = ret;
ashleymills 0:714293de3836 3235 store.error_depth = totalCerts;
ashleymills 0:714293de3836 3236 store.discardSessionCerts = 0;
ashleymills 0:714293de3836 3237 store.domain = domain;
ashleymills 0:714293de3836 3238 store.userCtx = ssl->verifyCbCtx;
ashleymills 0:714293de3836 3239 store.current_cert = &ssl->peerCert;
ashleymills 0:714293de3836 3240 store.ex_data = ssl;
ashleymills 0:714293de3836 3241
ashleymills 0:714293de3836 3242 ok = ssl->verifyCallback(1, &store);
ashleymills 0:714293de3836 3243 if (!ok) {
ashleymills 0:714293de3836 3244 CYASSL_MSG("Verify callback overriding valid certificate!");
ashleymills 0:714293de3836 3245 ret = -1;
ashleymills 0:714293de3836 3246 SendAlert(ssl, alert_fatal, bad_certificate);
ashleymills 0:714293de3836 3247 ssl->options.isClosed = 1;
ashleymills 0:714293de3836 3248 }
ashleymills 0:714293de3836 3249 #ifdef SESSION_CERTS
ashleymills 0:714293de3836 3250 if (store.discardSessionCerts) {
ashleymills 0:714293de3836 3251 CYASSL_MSG("Verify callback requested discard sess certs");
ashleymills 0:714293de3836 3252 ssl->session.chain.count = 0;
ashleymills 0:714293de3836 3253 }
ashleymills 0:714293de3836 3254 #endif
ashleymills 0:714293de3836 3255 }
ashleymills 0:714293de3836 3256 }
ashleymills 0:714293de3836 3257 #endif
ashleymills 0:714293de3836 3258
ashleymills 0:714293de3836 3259 *inOutIdx = i;
ashleymills 0:714293de3836 3260 return ret;
ashleymills 0:714293de3836 3261 }
ashleymills 0:714293de3836 3262
ashleymills 0:714293de3836 3263 #endif /* !NO_CERTS */
ashleymills 0:714293de3836 3264
ashleymills 0:714293de3836 3265
ashleymills 0:714293de3836 3266 static int DoHelloRequest(CYASSL* ssl, const byte* input, word32* inOutIdx)
ashleymills 0:714293de3836 3267 {
ashleymills 0:714293de3836 3268 if (ssl->keys.encryptionOn) {
ashleymills 0:714293de3836 3269 const byte* mac;
ashleymills 0:714293de3836 3270 int padSz = ssl->keys.encryptSz - HANDSHAKE_HEADER_SZ -
ashleymills 0:714293de3836 3271 ssl->specs.hash_size;
ashleymills 0:714293de3836 3272 byte verify[SHA256_DIGEST_SIZE];
ashleymills 0:714293de3836 3273
ashleymills 0:714293de3836 3274 ssl->hmac(ssl, verify, input + *inOutIdx - HANDSHAKE_HEADER_SZ,
ashleymills 0:714293de3836 3275 HANDSHAKE_HEADER_SZ, handshake, 1);
ashleymills 0:714293de3836 3276 /* read mac and fill */
ashleymills 0:714293de3836 3277 mac = input + *inOutIdx;
ashleymills 0:714293de3836 3278 *inOutIdx += ssl->specs.hash_size;
ashleymills 0:714293de3836 3279
ashleymills 0:714293de3836 3280 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
ashleymills 0:714293de3836 3281 padSz -= ssl->specs.block_size;
ashleymills 0:714293de3836 3282
ashleymills 0:714293de3836 3283 *inOutIdx += padSz;
ashleymills 0:714293de3836 3284
ashleymills 0:714293de3836 3285 /* verify */
ashleymills 0:714293de3836 3286 if (XMEMCMP(mac, verify, ssl->specs.hash_size) != 0) {
ashleymills 0:714293de3836 3287 CYASSL_MSG(" hello_request verify mac error");
ashleymills 0:714293de3836 3288 return VERIFY_MAC_ERROR;
ashleymills 0:714293de3836 3289 }
ashleymills 0:714293de3836 3290 }
ashleymills 0:714293de3836 3291
ashleymills 0:714293de3836 3292 if (ssl->options.side == SERVER_END) {
ashleymills 0:714293de3836 3293 SendAlert(ssl, alert_fatal, unexpected_message); /* try */
ashleymills 0:714293de3836 3294 return FATAL_ERROR;
ashleymills 0:714293de3836 3295 }
ashleymills 0:714293de3836 3296 else
ashleymills 0:714293de3836 3297 return SendAlert(ssl, alert_warning, no_renegotiation);
ashleymills 0:714293de3836 3298 }
ashleymills 0:714293de3836 3299
ashleymills 0:714293de3836 3300
ashleymills 0:714293de3836 3301 int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, int sniff)
ashleymills 0:714293de3836 3302 {
ashleymills 0:714293de3836 3303 int finishedSz = ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ;
ashleymills 0:714293de3836 3304 int headerSz = HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 3305 word32 macSz = finishedSz + HANDSHAKE_HEADER_SZ,
ashleymills 0:714293de3836 3306 idx = *inOutIdx,
ashleymills 0:714293de3836 3307 padSz = ssl->keys.encryptSz - HANDSHAKE_HEADER_SZ - finishedSz -
ashleymills 0:714293de3836 3308 ssl->specs.hash_size;
ashleymills 0:714293de3836 3309 const byte* mac;
ashleymills 0:714293de3836 3310
ashleymills 0:714293de3836 3311 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 3312 if (ssl->options.dtls) {
ashleymills 0:714293de3836 3313 headerSz += DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 3314 macSz += DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 3315 padSz -= DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 3316 }
ashleymills 0:714293de3836 3317 #endif
ashleymills 0:714293de3836 3318
ashleymills 0:714293de3836 3319 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 3320 if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
ashleymills 0:714293de3836 3321 if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
ashleymills 0:714293de3836 3322 #endif
ashleymills 0:714293de3836 3323 if (sniff == NO_SNIFF) {
ashleymills 0:714293de3836 3324 if (XMEMCMP(input + idx, &ssl->verifyHashes, finishedSz) != 0) {
ashleymills 0:714293de3836 3325 CYASSL_MSG("Verify finished error on hashes");
ashleymills 0:714293de3836 3326 return VERIFY_FINISHED_ERROR;
ashleymills 0:714293de3836 3327 }
ashleymills 0:714293de3836 3328 }
ashleymills 0:714293de3836 3329
ashleymills 0:714293de3836 3330 if (ssl->specs.cipher_type != aead) {
ashleymills 0:714293de3836 3331 byte verifyMAC[MAX_DIGEST_SIZE];
ashleymills 0:714293de3836 3332 ssl->hmac(ssl, verifyMAC, input + idx - headerSz, macSz,
ashleymills 0:714293de3836 3333 handshake, 1);
ashleymills 0:714293de3836 3334 idx += finishedSz;
ashleymills 0:714293de3836 3335
ashleymills 0:714293de3836 3336 /* read mac and fill */
ashleymills 0:714293de3836 3337 mac = input + idx;
ashleymills 0:714293de3836 3338 idx += ssl->specs.hash_size;
ashleymills 0:714293de3836 3339
ashleymills 0:714293de3836 3340 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
ashleymills 0:714293de3836 3341 padSz -= ssl->specs.block_size;
ashleymills 0:714293de3836 3342
ashleymills 0:714293de3836 3343 idx += padSz;
ashleymills 0:714293de3836 3344
ashleymills 0:714293de3836 3345 /* verify mac */
ashleymills 0:714293de3836 3346 if (XMEMCMP(mac, verifyMAC, ssl->specs.hash_size) != 0) {
ashleymills 0:714293de3836 3347 CYASSL_MSG("Verify finished error on mac");
ashleymills 0:714293de3836 3348 return VERIFY_MAC_ERROR;
ashleymills 0:714293de3836 3349 }
ashleymills 0:714293de3836 3350 }
ashleymills 0:714293de3836 3351 else {
ashleymills 0:714293de3836 3352 idx += (finishedSz + ssl->specs.aead_mac_size);
ashleymills 0:714293de3836 3353 }
ashleymills 0:714293de3836 3354
ashleymills 0:714293de3836 3355 if (ssl->options.side == CLIENT_END) {
ashleymills 0:714293de3836 3356 ssl->options.serverState = SERVER_FINISHED_COMPLETE;
ashleymills 0:714293de3836 3357 if (!ssl->options.resuming) {
ashleymills 0:714293de3836 3358 ssl->options.handShakeState = HANDSHAKE_DONE;
ashleymills 0:714293de3836 3359 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 3360 if (ssl->options.dtls) {
ashleymills 0:714293de3836 3361 /* Other side has received our Finished, go to next epoch */
ashleymills 0:714293de3836 3362 ssl->keys.dtls_epoch++;
ashleymills 0:714293de3836 3363 ssl->keys.dtls_sequence_number = 1;
ashleymills 0:714293de3836 3364 }
ashleymills 0:714293de3836 3365 #endif
ashleymills 0:714293de3836 3366 }
ashleymills 0:714293de3836 3367 }
ashleymills 0:714293de3836 3368 else {
ashleymills 0:714293de3836 3369 ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
ashleymills 0:714293de3836 3370 if (ssl->options.resuming) {
ashleymills 0:714293de3836 3371 ssl->options.handShakeState = HANDSHAKE_DONE;
ashleymills 0:714293de3836 3372 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 3373 if (ssl->options.dtls) {
ashleymills 0:714293de3836 3374 /* Other side has received our Finished, go to next epoch */
ashleymills 0:714293de3836 3375 ssl->keys.dtls_epoch++;
ashleymills 0:714293de3836 3376 ssl->keys.dtls_sequence_number = 1;
ashleymills 0:714293de3836 3377 }
ashleymills 0:714293de3836 3378 #endif
ashleymills 0:714293de3836 3379 }
ashleymills 0:714293de3836 3380 }
ashleymills 0:714293de3836 3381
ashleymills 0:714293de3836 3382 *inOutIdx = idx;
ashleymills 0:714293de3836 3383 return 0;
ashleymills 0:714293de3836 3384 }
ashleymills 0:714293de3836 3385
ashleymills 0:714293de3836 3386
ashleymills 0:714293de3836 3387 static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
ashleymills 0:714293de3836 3388 byte type, word32 size, word32 totalSz)
ashleymills 0:714293de3836 3389 {
ashleymills 0:714293de3836 3390 int ret = 0;
ashleymills 0:714293de3836 3391 (void)totalSz;
ashleymills 0:714293de3836 3392
ashleymills 0:714293de3836 3393 CYASSL_ENTER("DoHandShakeMsgType");
ashleymills 0:714293de3836 3394
ashleymills 0:714293de3836 3395 HashInput(ssl, input + *inOutIdx, size);
ashleymills 0:714293de3836 3396 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 3397 /* add name later, add on record and handshake header part back on */
ashleymills 0:714293de3836 3398 if (ssl->toInfoOn) {
ashleymills 0:714293de3836 3399 int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 3400 AddPacketInfo(0, &ssl->timeoutInfo, input + *inOutIdx - add,
ashleymills 0:714293de3836 3401 size + add, ssl->heap);
ashleymills 0:714293de3836 3402 AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
ashleymills 0:714293de3836 3403 }
ashleymills 0:714293de3836 3404 #endif
ashleymills 0:714293de3836 3405
ashleymills 0:714293de3836 3406 if (ssl->options.handShakeState == HANDSHAKE_DONE && type != hello_request){
ashleymills 0:714293de3836 3407 CYASSL_MSG("HandShake message after handshake complete");
ashleymills 0:714293de3836 3408 SendAlert(ssl, alert_fatal, unexpected_message);
ashleymills 0:714293de3836 3409 return OUT_OF_ORDER_E;
ashleymills 0:714293de3836 3410 }
ashleymills 0:714293de3836 3411
ashleymills 0:714293de3836 3412 if (ssl->options.side == CLIENT_END && ssl->options.dtls == 0 &&
ashleymills 0:714293de3836 3413 ssl->options.serverState == NULL_STATE && type != server_hello) {
ashleymills 0:714293de3836 3414 CYASSL_MSG("First server message not server hello");
ashleymills 0:714293de3836 3415 SendAlert(ssl, alert_fatal, unexpected_message);
ashleymills 0:714293de3836 3416 return OUT_OF_ORDER_E;
ashleymills 0:714293de3836 3417 }
ashleymills 0:714293de3836 3418
ashleymills 0:714293de3836 3419 if (ssl->options.side == CLIENT_END && ssl->options.dtls &&
ashleymills 0:714293de3836 3420 type == server_hello_done &&
ashleymills 0:714293de3836 3421 ssl->options.serverState < SERVER_HELLO_COMPLETE) {
ashleymills 0:714293de3836 3422 CYASSL_MSG("Server hello done received before server hello in DTLS");
ashleymills 0:714293de3836 3423 SendAlert(ssl, alert_fatal, unexpected_message);
ashleymills 0:714293de3836 3424 return OUT_OF_ORDER_E;
ashleymills 0:714293de3836 3425 }
ashleymills 0:714293de3836 3426
ashleymills 0:714293de3836 3427 if (ssl->options.side == SERVER_END &&
ashleymills 0:714293de3836 3428 ssl->options.clientState == NULL_STATE && type != client_hello) {
ashleymills 0:714293de3836 3429 CYASSL_MSG("First client message not client hello");
ashleymills 0:714293de3836 3430 SendAlert(ssl, alert_fatal, unexpected_message);
ashleymills 0:714293de3836 3431 return OUT_OF_ORDER_E;
ashleymills 0:714293de3836 3432 }
ashleymills 0:714293de3836 3433
ashleymills 0:714293de3836 3434
ashleymills 0:714293de3836 3435 switch (type) {
ashleymills 0:714293de3836 3436
ashleymills 0:714293de3836 3437 case hello_request:
ashleymills 0:714293de3836 3438 CYASSL_MSG("processing hello request");
ashleymills 0:714293de3836 3439 ret = DoHelloRequest(ssl, input, inOutIdx);
ashleymills 0:714293de3836 3440 break;
ashleymills 0:714293de3836 3441
ashleymills 0:714293de3836 3442 #ifndef NO_CYASSL_CLIENT
ashleymills 0:714293de3836 3443 case hello_verify_request:
ashleymills 0:714293de3836 3444 CYASSL_MSG("processing hello verify request");
ashleymills 0:714293de3836 3445 ret = DoHelloVerifyRequest(ssl, input,inOutIdx);
ashleymills 0:714293de3836 3446 break;
ashleymills 0:714293de3836 3447
ashleymills 0:714293de3836 3448 case server_hello:
ashleymills 0:714293de3836 3449 CYASSL_MSG("processing server hello");
ashleymills 0:714293de3836 3450 ret = DoServerHello(ssl, input, inOutIdx, size);
ashleymills 0:714293de3836 3451 break;
ashleymills 0:714293de3836 3452
ashleymills 0:714293de3836 3453 #ifndef NO_CERTS
ashleymills 0:714293de3836 3454 case certificate_request:
ashleymills 0:714293de3836 3455 CYASSL_MSG("processing certificate request");
ashleymills 0:714293de3836 3456 ret = DoCertificateRequest(ssl, input, inOutIdx);
ashleymills 0:714293de3836 3457 break;
ashleymills 0:714293de3836 3458 #endif
ashleymills 0:714293de3836 3459
ashleymills 0:714293de3836 3460 case server_key_exchange:
ashleymills 0:714293de3836 3461 CYASSL_MSG("processing server key exchange");
ashleymills 0:714293de3836 3462 ret = DoServerKeyExchange(ssl, input, inOutIdx);
ashleymills 0:714293de3836 3463 break;
ashleymills 0:714293de3836 3464 #endif
ashleymills 0:714293de3836 3465
ashleymills 0:714293de3836 3466 #ifndef NO_CERTS
ashleymills 0:714293de3836 3467 case certificate:
ashleymills 0:714293de3836 3468 CYASSL_MSG("processing certificate");
ashleymills 0:714293de3836 3469 ret = DoCertificate(ssl, input, inOutIdx);
ashleymills 0:714293de3836 3470 break;
ashleymills 0:714293de3836 3471 #endif
ashleymills 0:714293de3836 3472
ashleymills 0:714293de3836 3473 case server_hello_done:
ashleymills 0:714293de3836 3474 CYASSL_MSG("processing server hello done");
ashleymills 0:714293de3836 3475 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 3476 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 3477 AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
ashleymills 0:714293de3836 3478 if (ssl->toInfoOn)
ashleymills 0:714293de3836 3479 AddLateName("ServerHelloDone", &ssl->timeoutInfo);
ashleymills 0:714293de3836 3480 #endif
ashleymills 0:714293de3836 3481 ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
ashleymills 0:714293de3836 3482 break;
ashleymills 0:714293de3836 3483
ashleymills 0:714293de3836 3484 case finished:
ashleymills 0:714293de3836 3485 CYASSL_MSG("processing finished");
ashleymills 0:714293de3836 3486 ret = DoFinished(ssl, input, inOutIdx, NO_SNIFF);
ashleymills 0:714293de3836 3487 break;
ashleymills 0:714293de3836 3488
ashleymills 0:714293de3836 3489 #ifndef NO_CYASSL_SERVER
ashleymills 0:714293de3836 3490 case client_hello:
ashleymills 0:714293de3836 3491 CYASSL_MSG("processing client hello");
ashleymills 0:714293de3836 3492 ret = DoClientHello(ssl, input, inOutIdx, totalSz, size);
ashleymills 0:714293de3836 3493 break;
ashleymills 0:714293de3836 3494
ashleymills 0:714293de3836 3495 case client_key_exchange:
ashleymills 0:714293de3836 3496 CYASSL_MSG("processing client key exchange");
ashleymills 0:714293de3836 3497 ret = DoClientKeyExchange(ssl, input, inOutIdx, totalSz);
ashleymills 0:714293de3836 3498 break;
ashleymills 0:714293de3836 3499
ashleymills 0:714293de3836 3500 #if !defined(NO_RSA) || defined(HAVE_ECC)
ashleymills 0:714293de3836 3501 case certificate_verify:
ashleymills 0:714293de3836 3502 CYASSL_MSG("processing certificate verify");
ashleymills 0:714293de3836 3503 ret = DoCertificateVerify(ssl, input, inOutIdx, totalSz);
ashleymills 0:714293de3836 3504 break;
ashleymills 0:714293de3836 3505 #endif /* !NO_RSA || HAVE_ECC */
ashleymills 0:714293de3836 3506
ashleymills 0:714293de3836 3507 #endif /* !NO_CYASSL_SERVER */
ashleymills 0:714293de3836 3508
ashleymills 0:714293de3836 3509 default:
ashleymills 0:714293de3836 3510 CYASSL_MSG("Unknown handshake message type");
ashleymills 0:714293de3836 3511 ret = UNKNOWN_HANDSHAKE_TYPE;
ashleymills 0:714293de3836 3512 }
ashleymills 0:714293de3836 3513
ashleymills 0:714293de3836 3514 CYASSL_LEAVE("DoHandShakeMsgType()", ret);
ashleymills 0:714293de3836 3515 return ret;
ashleymills 0:714293de3836 3516 }
ashleymills 0:714293de3836 3517
ashleymills 0:714293de3836 3518
ashleymills 0:714293de3836 3519 static int DoHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
ashleymills 0:714293de3836 3520 word32 totalSz)
ashleymills 0:714293de3836 3521 {
ashleymills 0:714293de3836 3522 byte type;
ashleymills 0:714293de3836 3523 word32 size;
ashleymills 0:714293de3836 3524 int ret = 0;
ashleymills 0:714293de3836 3525
ashleymills 0:714293de3836 3526 CYASSL_ENTER("DoHandShakeMsg()");
ashleymills 0:714293de3836 3527
ashleymills 0:714293de3836 3528 if (GetHandShakeHeader(ssl, input, inOutIdx, &type, &size) != 0)
ashleymills 0:714293de3836 3529 return PARSE_ERROR;
ashleymills 0:714293de3836 3530
ashleymills 0:714293de3836 3531 if (*inOutIdx + size > totalSz)
ashleymills 0:714293de3836 3532 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 3533
ashleymills 0:714293de3836 3534 ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
ashleymills 0:714293de3836 3535
ashleymills 0:714293de3836 3536 CYASSL_LEAVE("DoHandShakeMsg()", ret);
ashleymills 0:714293de3836 3537 return ret;
ashleymills 0:714293de3836 3538 }
ashleymills 0:714293de3836 3539
ashleymills 0:714293de3836 3540
ashleymills 0:714293de3836 3541 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 3542 static int DtlsMsgDrain(CYASSL* ssl)
ashleymills 0:714293de3836 3543 {
ashleymills 0:714293de3836 3544 DtlsMsg* item = ssl->dtls_msg_list;
ashleymills 0:714293de3836 3545 int ret = 0;
ashleymills 0:714293de3836 3546 word32 idx = 0;
ashleymills 0:714293de3836 3547
ashleymills 0:714293de3836 3548 /* While there is an item in the store list, and it is the expected
ashleymills 0:714293de3836 3549 * message, and it is complete, and there hasn't been an error in the
ashleymills 0:714293de3836 3550 * last messge... */
ashleymills 0:714293de3836 3551 while (item != NULL &&
ashleymills 0:714293de3836 3552 ssl->keys.dtls_expected_peer_handshake_number == item->seq &&
ashleymills 0:714293de3836 3553 item->fragSz == item->sz &&
ashleymills 0:714293de3836 3554 ret == 0) {
ashleymills 0:714293de3836 3555 ssl->keys.dtls_expected_peer_handshake_number++;
ashleymills 0:714293de3836 3556 ret = DoHandShakeMsgType(ssl, item->msg,
ashleymills 0:714293de3836 3557 &idx, item->type, item->sz, item->sz);
ashleymills 0:714293de3836 3558 ssl->dtls_msg_list = item->next;
ashleymills 0:714293de3836 3559 DtlsMsgDelete(item, ssl->heap);
ashleymills 0:714293de3836 3560 item = ssl->dtls_msg_list;
ashleymills 0:714293de3836 3561 }
ashleymills 0:714293de3836 3562
ashleymills 0:714293de3836 3563 return ret;
ashleymills 0:714293de3836 3564 }
ashleymills 0:714293de3836 3565
ashleymills 0:714293de3836 3566
ashleymills 0:714293de3836 3567 static int DoDtlsHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
ashleymills 0:714293de3836 3568 word32 totalSz)
ashleymills 0:714293de3836 3569 {
ashleymills 0:714293de3836 3570 byte type;
ashleymills 0:714293de3836 3571 word32 size;
ashleymills 0:714293de3836 3572 word32 fragOffset, fragSz;
ashleymills 0:714293de3836 3573 int ret = 0;
ashleymills 0:714293de3836 3574
ashleymills 0:714293de3836 3575 CYASSL_ENTER("DoDtlsHandShakeMsg()");
ashleymills 0:714293de3836 3576 if (GetDtlsHandShakeHeader(ssl, input, inOutIdx, &type,
ashleymills 0:714293de3836 3577 &size, &fragOffset, &fragSz) != 0)
ashleymills 0:714293de3836 3578 return PARSE_ERROR;
ashleymills 0:714293de3836 3579
ashleymills 0:714293de3836 3580 if (*inOutIdx + fragSz > totalSz)
ashleymills 0:714293de3836 3581 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 3582
ashleymills 0:714293de3836 3583 /* Check the handshake sequence number first. If out of order,
ashleymills 0:714293de3836 3584 * add the current message to the list. If the message is in order,
ashleymills 0:714293de3836 3585 * but it is a fragment, add the current message to the list, then
ashleymills 0:714293de3836 3586 * check the head of the list to see if it is complete, if so, pop
ashleymills 0:714293de3836 3587 * it out as the current message. If the message is complete and in
ashleymills 0:714293de3836 3588 * order, process it. Check the head of the list to see if it is in
ashleymills 0:714293de3836 3589 * order, if so, process it. (Repeat until list exhausted.) If the
ashleymills 0:714293de3836 3590 * head is out of order, return for more processing.
ashleymills 0:714293de3836 3591 */
ashleymills 0:714293de3836 3592 if (ssl->keys.dtls_peer_handshake_number >
ashleymills 0:714293de3836 3593 ssl->keys.dtls_expected_peer_handshake_number) {
ashleymills 0:714293de3836 3594 /* Current message is out of order. It will get stored in the list.
ashleymills 0:714293de3836 3595 * Storing also takes care of defragmentation. */
ashleymills 0:714293de3836 3596 ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
ashleymills 0:714293de3836 3597 ssl->keys.dtls_peer_handshake_number, input + *inOutIdx,
ashleymills 0:714293de3836 3598 size, type, fragOffset, fragSz, ssl->heap);
ashleymills 0:714293de3836 3599 *inOutIdx += fragSz;
ashleymills 0:714293de3836 3600 ret = 0;
ashleymills 0:714293de3836 3601 }
ashleymills 0:714293de3836 3602 else if (ssl->keys.dtls_peer_handshake_number <
ashleymills 0:714293de3836 3603 ssl->keys.dtls_expected_peer_handshake_number) {
ashleymills 0:714293de3836 3604 /* Already saw this message and processed it. It can be ignored. */
ashleymills 0:714293de3836 3605 *inOutIdx += fragSz;
ashleymills 0:714293de3836 3606 ret = 0;
ashleymills 0:714293de3836 3607 }
ashleymills 0:714293de3836 3608 else if (fragSz < size) {
ashleymills 0:714293de3836 3609 /* Since this branch is in order, but fragmented, dtls_msg_list will be
ashleymills 0:714293de3836 3610 * pointing to the message with this fragment in it. Check it to see
ashleymills 0:714293de3836 3611 * if it is completed. */
ashleymills 0:714293de3836 3612 ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
ashleymills 0:714293de3836 3613 ssl->keys.dtls_peer_handshake_number, input + *inOutIdx,
ashleymills 0:714293de3836 3614 size, type, fragOffset, fragSz, ssl->heap);
ashleymills 0:714293de3836 3615 *inOutIdx += fragSz;
ashleymills 0:714293de3836 3616 ret = 0;
ashleymills 0:714293de3836 3617 if (ssl->dtls_msg_list->fragSz >= ssl->dtls_msg_list->sz)
ashleymills 0:714293de3836 3618 ret = DtlsMsgDrain(ssl);
ashleymills 0:714293de3836 3619 }
ashleymills 0:714293de3836 3620 else {
ashleymills 0:714293de3836 3621 /* This branch is in order next, and a complete message. */
ashleymills 0:714293de3836 3622 ssl->keys.dtls_expected_peer_handshake_number++;
ashleymills 0:714293de3836 3623 ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
ashleymills 0:714293de3836 3624 if (ret == 0 && ssl->dtls_msg_list != NULL)
ashleymills 0:714293de3836 3625 ret = DtlsMsgDrain(ssl);
ashleymills 0:714293de3836 3626 }
ashleymills 0:714293de3836 3627
ashleymills 0:714293de3836 3628 CYASSL_LEAVE("DoDtlsHandShakeMsg()", ret);
ashleymills 0:714293de3836 3629 return ret;
ashleymills 0:714293de3836 3630 }
ashleymills 0:714293de3836 3631 #endif
ashleymills 0:714293de3836 3632
ashleymills 0:714293de3836 3633
ashleymills 0:714293de3836 3634 static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
ashleymills 0:714293de3836 3635 {
ashleymills 0:714293de3836 3636 if (verify)
ashleymills 0:714293de3836 3637 return ssl->keys.peer_sequence_number++;
ashleymills 0:714293de3836 3638 else
ashleymills 0:714293de3836 3639 return ssl->keys.sequence_number++;
ashleymills 0:714293de3836 3640 }
ashleymills 0:714293de3836 3641
ashleymills 0:714293de3836 3642
ashleymills 0:714293de3836 3643 #ifdef HAVE_AEAD
ashleymills 0:714293de3836 3644 static INLINE void AeadIncrementExpIV(CYASSL* ssl)
ashleymills 0:714293de3836 3645 {
ashleymills 0:714293de3836 3646 int i;
ashleymills 0:714293de3836 3647 for (i = AEAD_EXP_IV_SZ-1; i >= 0; i--) {
ashleymills 0:714293de3836 3648 if (++ssl->keys.aead_exp_IV[i]) return;
ashleymills 0:714293de3836 3649 }
ashleymills 0:714293de3836 3650 }
ashleymills 0:714293de3836 3651 #endif
ashleymills 0:714293de3836 3652
ashleymills 0:714293de3836 3653
ashleymills 0:714293de3836 3654 static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz)
ashleymills 0:714293de3836 3655 {
ashleymills 0:714293de3836 3656 (void)out;
ashleymills 0:714293de3836 3657 (void)input;
ashleymills 0:714293de3836 3658 (void)sz;
ashleymills 0:714293de3836 3659
ashleymills 0:714293de3836 3660 if (ssl->encrypt.setup == 0) {
ashleymills 0:714293de3836 3661 CYASSL_MSG("Encrypt ciphers not setup");
ashleymills 0:714293de3836 3662 return ENCRYPT_ERROR;
ashleymills 0:714293de3836 3663 }
ashleymills 0:714293de3836 3664
ashleymills 0:714293de3836 3665 switch (ssl->specs.bulk_cipher_algorithm) {
ashleymills 0:714293de3836 3666 #ifdef BUILD_ARC4
ashleymills 0:714293de3836 3667 case rc4:
ashleymills 0:714293de3836 3668 Arc4Process(ssl->encrypt.arc4, out, input, sz);
ashleymills 0:714293de3836 3669 break;
ashleymills 0:714293de3836 3670 #endif
ashleymills 0:714293de3836 3671
ashleymills 0:714293de3836 3672 #ifdef BUILD_DES3
ashleymills 0:714293de3836 3673 case triple_des:
ashleymills 0:714293de3836 3674 Des3_CbcEncrypt(ssl->encrypt.des3, out, input, sz);
ashleymills 0:714293de3836 3675 break;
ashleymills 0:714293de3836 3676 #endif
ashleymills 0:714293de3836 3677
ashleymills 0:714293de3836 3678 #ifdef BUILD_AES
ashleymills 0:714293de3836 3679 case aes:
ashleymills 0:714293de3836 3680 return AesCbcEncrypt(ssl->encrypt.aes, out, input, sz);
ashleymills 0:714293de3836 3681 break;
ashleymills 0:714293de3836 3682 #endif
ashleymills 0:714293de3836 3683
ashleymills 0:714293de3836 3684 #ifdef BUILD_AESGCM
ashleymills 0:714293de3836 3685 case aes_gcm:
ashleymills 0:714293de3836 3686 {
ashleymills 0:714293de3836 3687 byte additional[AES_BLOCK_SIZE];
ashleymills 0:714293de3836 3688 byte nonce[AEAD_NONCE_SZ];
ashleymills 0:714293de3836 3689 const byte* additionalSrc = input - 5;
ashleymills 0:714293de3836 3690
ashleymills 0:714293de3836 3691 XMEMSET(additional, 0, AES_BLOCK_SIZE);
ashleymills 0:714293de3836 3692
ashleymills 0:714293de3836 3693 /* sequence number field is 64-bits, we only use 32-bits */
ashleymills 0:714293de3836 3694 c32toa(GetSEQIncrement(ssl, 0),
ashleymills 0:714293de3836 3695 additional + AEAD_SEQ_OFFSET);
ashleymills 0:714293de3836 3696
ashleymills 0:714293de3836 3697 /* Store the type, version. Unfortunately, they are in
ashleymills 0:714293de3836 3698 * the input buffer ahead of the plaintext. */
ashleymills 0:714293de3836 3699 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 3700 if (ssl->options.dtls)
ashleymills 0:714293de3836 3701 additionalSrc -= DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 3702 #endif
ashleymills 0:714293de3836 3703 XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
ashleymills 0:714293de3836 3704
ashleymills 0:714293de3836 3705 /* Store the length of the plain text minus the explicit
ashleymills 0:714293de3836 3706 * IV length minus the authentication tag size. */
ashleymills 0:714293de3836 3707 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
ashleymills 0:714293de3836 3708 additional + AEAD_LEN_OFFSET);
ashleymills 0:714293de3836 3709 XMEMCPY(nonce,
ashleymills 0:714293de3836 3710 ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ);
ashleymills 0:714293de3836 3711 XMEMCPY(nonce + AEAD_IMP_IV_SZ,
ashleymills 0:714293de3836 3712 ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
ashleymills 0:714293de3836 3713 AesGcmEncrypt(ssl->encrypt.aes,
ashleymills 0:714293de3836 3714 out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ,
ashleymills 0:714293de3836 3715 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
ashleymills 0:714293de3836 3716 nonce, AEAD_NONCE_SZ,
ashleymills 0:714293de3836 3717 out + sz - ssl->specs.aead_mac_size,
ashleymills 0:714293de3836 3718 ssl->specs.aead_mac_size, additional,
ashleymills 0:714293de3836 3719 AEAD_AUTH_DATA_SZ);
ashleymills 0:714293de3836 3720 AeadIncrementExpIV(ssl);
ashleymills 0:714293de3836 3721 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
ashleymills 0:714293de3836 3722 }
ashleymills 0:714293de3836 3723 break;
ashleymills 0:714293de3836 3724 #endif
ashleymills 0:714293de3836 3725
ashleymills 0:714293de3836 3726 #ifdef HAVE_AESCCM
ashleymills 0:714293de3836 3727 case aes_ccm:
ashleymills 0:714293de3836 3728 {
ashleymills 0:714293de3836 3729 byte additional[AES_BLOCK_SIZE];
ashleymills 0:714293de3836 3730 byte nonce[AEAD_NONCE_SZ];
ashleymills 0:714293de3836 3731 const byte* additionalSrc = input - 5;
ashleymills 0:714293de3836 3732
ashleymills 0:714293de3836 3733 XMEMSET(additional, 0, AES_BLOCK_SIZE);
ashleymills 0:714293de3836 3734
ashleymills 0:714293de3836 3735 /* sequence number field is 64-bits, we only use 32-bits */
ashleymills 0:714293de3836 3736 c32toa(GetSEQIncrement(ssl, 0),
ashleymills 0:714293de3836 3737 additional + AEAD_SEQ_OFFSET);
ashleymills 0:714293de3836 3738
ashleymills 0:714293de3836 3739 /* Store the type, version. Unfortunately, they are in
ashleymills 0:714293de3836 3740 * the input buffer ahead of the plaintext. */
ashleymills 0:714293de3836 3741 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 3742 if (ssl->options.dtls)
ashleymills 0:714293de3836 3743 additionalSrc -= DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 3744 #endif
ashleymills 0:714293de3836 3745 XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
ashleymills 0:714293de3836 3746
ashleymills 0:714293de3836 3747 /* Store the length of the plain text minus the explicit
ashleymills 0:714293de3836 3748 * IV length minus the authentication tag size. */
ashleymills 0:714293de3836 3749 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
ashleymills 0:714293de3836 3750 additional + AEAD_LEN_OFFSET);
ashleymills 0:714293de3836 3751 XMEMCPY(nonce,
ashleymills 0:714293de3836 3752 ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ);
ashleymills 0:714293de3836 3753 XMEMCPY(nonce + AEAD_IMP_IV_SZ,
ashleymills 0:714293de3836 3754 ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
ashleymills 0:714293de3836 3755 AesCcmEncrypt(ssl->encrypt.aes,
ashleymills 0:714293de3836 3756 out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ,
ashleymills 0:714293de3836 3757 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
ashleymills 0:714293de3836 3758 nonce, AEAD_NONCE_SZ,
ashleymills 0:714293de3836 3759 out + sz - ssl->specs.aead_mac_size,
ashleymills 0:714293de3836 3760 ssl->specs.aead_mac_size,
ashleymills 0:714293de3836 3761 additional, AEAD_AUTH_DATA_SZ);
ashleymills 0:714293de3836 3762 AeadIncrementExpIV(ssl);
ashleymills 0:714293de3836 3763 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
ashleymills 0:714293de3836 3764 }
ashleymills 0:714293de3836 3765 break;
ashleymills 0:714293de3836 3766 #endif
ashleymills 0:714293de3836 3767
ashleymills 0:714293de3836 3768 #ifdef HAVE_CAMELLIA
ashleymills 0:714293de3836 3769 case camellia:
ashleymills 0:714293de3836 3770 CamelliaCbcEncrypt(ssl->encrypt.cam, out, input, sz);
ashleymills 0:714293de3836 3771 break;
ashleymills 0:714293de3836 3772 #endif
ashleymills 0:714293de3836 3773
ashleymills 0:714293de3836 3774 #ifdef HAVE_HC128
ashleymills 0:714293de3836 3775 case hc128:
ashleymills 0:714293de3836 3776 return Hc128_Process(ssl->encrypt.hc128, out, input, sz);
ashleymills 0:714293de3836 3777 break;
ashleymills 0:714293de3836 3778 #endif
ashleymills 0:714293de3836 3779
ashleymills 0:714293de3836 3780 #ifdef BUILD_RABBIT
ashleymills 0:714293de3836 3781 case rabbit:
ashleymills 0:714293de3836 3782 return RabbitProcess(ssl->encrypt.rabbit, out, input, sz);
ashleymills 0:714293de3836 3783 break;
ashleymills 0:714293de3836 3784 #endif
ashleymills 0:714293de3836 3785
ashleymills 0:714293de3836 3786 #ifdef HAVE_NULL_CIPHER
ashleymills 0:714293de3836 3787 case cipher_null:
ashleymills 0:714293de3836 3788 if (input != out) {
ashleymills 0:714293de3836 3789 XMEMMOVE(out, input, sz);
ashleymills 0:714293de3836 3790 }
ashleymills 0:714293de3836 3791 break;
ashleymills 0:714293de3836 3792 #endif
ashleymills 0:714293de3836 3793
ashleymills 0:714293de3836 3794 default:
ashleymills 0:714293de3836 3795 CYASSL_MSG("CyaSSL Encrypt programming error");
ashleymills 0:714293de3836 3796 return ENCRYPT_ERROR;
ashleymills 0:714293de3836 3797 }
ashleymills 0:714293de3836 3798
ashleymills 0:714293de3836 3799 return 0;
ashleymills 0:714293de3836 3800 }
ashleymills 0:714293de3836 3801
ashleymills 0:714293de3836 3802
ashleymills 0:714293de3836 3803 static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input,
ashleymills 0:714293de3836 3804 word32 sz)
ashleymills 0:714293de3836 3805 {
ashleymills 0:714293de3836 3806 (void)plain;
ashleymills 0:714293de3836 3807 (void)input;
ashleymills 0:714293de3836 3808 (void)sz;
ashleymills 0:714293de3836 3809
ashleymills 0:714293de3836 3810 if (ssl->decrypt.setup == 0) {
ashleymills 0:714293de3836 3811 CYASSL_MSG("Decrypt ciphers not setup");
ashleymills 0:714293de3836 3812 return DECRYPT_ERROR;
ashleymills 0:714293de3836 3813 }
ashleymills 0:714293de3836 3814
ashleymills 0:714293de3836 3815 switch (ssl->specs.bulk_cipher_algorithm) {
ashleymills 0:714293de3836 3816 #ifdef BUILD_ARC4
ashleymills 0:714293de3836 3817 case rc4:
ashleymills 0:714293de3836 3818 Arc4Process(ssl->decrypt.arc4, plain, input, sz);
ashleymills 0:714293de3836 3819 break;
ashleymills 0:714293de3836 3820 #endif
ashleymills 0:714293de3836 3821
ashleymills 0:714293de3836 3822 #ifdef BUILD_DES3
ashleymills 0:714293de3836 3823 case triple_des:
ashleymills 0:714293de3836 3824 Des3_CbcDecrypt(ssl->decrypt.des3, plain, input, sz);
ashleymills 0:714293de3836 3825 break;
ashleymills 0:714293de3836 3826 #endif
ashleymills 0:714293de3836 3827
ashleymills 0:714293de3836 3828 #ifdef BUILD_AES
ashleymills 0:714293de3836 3829 case aes:
ashleymills 0:714293de3836 3830 return AesCbcDecrypt(ssl->decrypt.aes, plain, input, sz);
ashleymills 0:714293de3836 3831 break;
ashleymills 0:714293de3836 3832 #endif
ashleymills 0:714293de3836 3833
ashleymills 0:714293de3836 3834 #ifdef BUILD_AESGCM
ashleymills 0:714293de3836 3835 case aes_gcm:
ashleymills 0:714293de3836 3836 {
ashleymills 0:714293de3836 3837 byte additional[AES_BLOCK_SIZE];
ashleymills 0:714293de3836 3838 byte nonce[AEAD_NONCE_SZ];
ashleymills 0:714293de3836 3839
ashleymills 0:714293de3836 3840 XMEMSET(additional, 0, AES_BLOCK_SIZE);
ashleymills 0:714293de3836 3841
ashleymills 0:714293de3836 3842 /* sequence number field is 64-bits, we only use 32-bits */
ashleymills 0:714293de3836 3843 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
ashleymills 0:714293de3836 3844
ashleymills 0:714293de3836 3845 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
ashleymills 0:714293de3836 3846 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
ashleymills 0:714293de3836 3847 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
ashleymills 0:714293de3836 3848
ashleymills 0:714293de3836 3849 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
ashleymills 0:714293de3836 3850 additional + AEAD_LEN_OFFSET);
ashleymills 0:714293de3836 3851 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
ashleymills 0:714293de3836 3852 XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
ashleymills 0:714293de3836 3853 if (AesGcmDecrypt(ssl->decrypt.aes,
ashleymills 0:714293de3836 3854 plain + AEAD_EXP_IV_SZ,
ashleymills 0:714293de3836 3855 input + AEAD_EXP_IV_SZ,
ashleymills 0:714293de3836 3856 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
ashleymills 0:714293de3836 3857 nonce, AEAD_NONCE_SZ,
ashleymills 0:714293de3836 3858 input + sz - ssl->specs.aead_mac_size,
ashleymills 0:714293de3836 3859 ssl->specs.aead_mac_size,
ashleymills 0:714293de3836 3860 additional, AEAD_AUTH_DATA_SZ) < 0) {
ashleymills 0:714293de3836 3861 SendAlert(ssl, alert_fatal, bad_record_mac);
ashleymills 0:714293de3836 3862 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
ashleymills 0:714293de3836 3863 return VERIFY_MAC_ERROR;
ashleymills 0:714293de3836 3864 }
ashleymills 0:714293de3836 3865 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
ashleymills 0:714293de3836 3866 break;
ashleymills 0:714293de3836 3867 }
ashleymills 0:714293de3836 3868 #endif
ashleymills 0:714293de3836 3869
ashleymills 0:714293de3836 3870 #ifdef HAVE_AESCCM
ashleymills 0:714293de3836 3871 case aes_ccm:
ashleymills 0:714293de3836 3872 {
ashleymills 0:714293de3836 3873 byte additional[AES_BLOCK_SIZE];
ashleymills 0:714293de3836 3874 byte nonce[AEAD_NONCE_SZ];
ashleymills 0:714293de3836 3875
ashleymills 0:714293de3836 3876 XMEMSET(additional, 0, AES_BLOCK_SIZE);
ashleymills 0:714293de3836 3877
ashleymills 0:714293de3836 3878 /* sequence number field is 64-bits, we only use 32-bits */
ashleymills 0:714293de3836 3879 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
ashleymills 0:714293de3836 3880
ashleymills 0:714293de3836 3881 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
ashleymills 0:714293de3836 3882 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
ashleymills 0:714293de3836 3883 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
ashleymills 0:714293de3836 3884
ashleymills 0:714293de3836 3885 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
ashleymills 0:714293de3836 3886 additional + AEAD_LEN_OFFSET);
ashleymills 0:714293de3836 3887 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
ashleymills 0:714293de3836 3888 XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
ashleymills 0:714293de3836 3889 if (AesCcmDecrypt(ssl->decrypt.aes,
ashleymills 0:714293de3836 3890 plain + AEAD_EXP_IV_SZ,
ashleymills 0:714293de3836 3891 input + AEAD_EXP_IV_SZ,
ashleymills 0:714293de3836 3892 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
ashleymills 0:714293de3836 3893 nonce, AEAD_NONCE_SZ,
ashleymills 0:714293de3836 3894 input + sz - ssl->specs.aead_mac_size,
ashleymills 0:714293de3836 3895 ssl->specs.aead_mac_size,
ashleymills 0:714293de3836 3896 additional, AEAD_AUTH_DATA_SZ) < 0) {
ashleymills 0:714293de3836 3897 SendAlert(ssl, alert_fatal, bad_record_mac);
ashleymills 0:714293de3836 3898 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
ashleymills 0:714293de3836 3899 return VERIFY_MAC_ERROR;
ashleymills 0:714293de3836 3900 }
ashleymills 0:714293de3836 3901 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
ashleymills 0:714293de3836 3902 break;
ashleymills 0:714293de3836 3903 }
ashleymills 0:714293de3836 3904 #endif
ashleymills 0:714293de3836 3905
ashleymills 0:714293de3836 3906 #ifdef HAVE_CAMELLIA
ashleymills 0:714293de3836 3907 case camellia:
ashleymills 0:714293de3836 3908 CamelliaCbcDecrypt(ssl->decrypt.cam, plain, input, sz);
ashleymills 0:714293de3836 3909 break;
ashleymills 0:714293de3836 3910 #endif
ashleymills 0:714293de3836 3911
ashleymills 0:714293de3836 3912 #ifdef HAVE_HC128
ashleymills 0:714293de3836 3913 case hc128:
ashleymills 0:714293de3836 3914 return Hc128_Process(ssl->decrypt.hc128, plain, input, sz);
ashleymills 0:714293de3836 3915 break;
ashleymills 0:714293de3836 3916 #endif
ashleymills 0:714293de3836 3917
ashleymills 0:714293de3836 3918 #ifdef BUILD_RABBIT
ashleymills 0:714293de3836 3919 case rabbit:
ashleymills 0:714293de3836 3920 return RabbitProcess(ssl->decrypt.rabbit, plain, input, sz);
ashleymills 0:714293de3836 3921 break;
ashleymills 0:714293de3836 3922 #endif
ashleymills 0:714293de3836 3923
ashleymills 0:714293de3836 3924 #ifdef HAVE_NULL_CIPHER
ashleymills 0:714293de3836 3925 case cipher_null:
ashleymills 0:714293de3836 3926 if (input != plain) {
ashleymills 0:714293de3836 3927 XMEMMOVE(plain, input, sz);
ashleymills 0:714293de3836 3928 }
ashleymills 0:714293de3836 3929 break;
ashleymills 0:714293de3836 3930 #endif
ashleymills 0:714293de3836 3931
ashleymills 0:714293de3836 3932 default:
ashleymills 0:714293de3836 3933 CYASSL_MSG("CyaSSL Decrypt programming error");
ashleymills 0:714293de3836 3934 return DECRYPT_ERROR;
ashleymills 0:714293de3836 3935 }
ashleymills 0:714293de3836 3936 return 0;
ashleymills 0:714293de3836 3937 }
ashleymills 0:714293de3836 3938
ashleymills 0:714293de3836 3939
ashleymills 0:714293de3836 3940 /* check cipher text size for sanity */
ashleymills 0:714293de3836 3941 static int SanityCheckCipherText(CYASSL* ssl, word32 encryptSz)
ashleymills 0:714293de3836 3942 {
ashleymills 0:714293de3836 3943 word32 minLength = 0;
ashleymills 0:714293de3836 3944
ashleymills 0:714293de3836 3945 if (ssl->specs.cipher_type == block) {
ashleymills 0:714293de3836 3946 if (encryptSz % ssl->specs.block_size) {
ashleymills 0:714293de3836 3947 CYASSL_MSG("Block ciphertext not block size");
ashleymills 0:714293de3836 3948 return SANITY_CIPHER_E;
ashleymills 0:714293de3836 3949 }
ashleymills 0:714293de3836 3950 minLength = ssl->specs.hash_size + 1; /* pad byte */
ashleymills 0:714293de3836 3951 if (ssl->specs.block_size > minLength)
ashleymills 0:714293de3836 3952 minLength = ssl->specs.block_size;
ashleymills 0:714293de3836 3953
ashleymills 0:714293de3836 3954 if (ssl->options.tls1_1)
ashleymills 0:714293de3836 3955 minLength += ssl->specs.block_size; /* explicit IV */
ashleymills 0:714293de3836 3956 }
ashleymills 0:714293de3836 3957 else if (ssl->specs.cipher_type == stream) {
ashleymills 0:714293de3836 3958 minLength = ssl->specs.hash_size;
ashleymills 0:714293de3836 3959 }
ashleymills 0:714293de3836 3960 else if (ssl->specs.cipher_type == aead) {
ashleymills 0:714293de3836 3961 minLength = ssl->specs.block_size; /* explicit IV + implicit IV + CTR */
ashleymills 0:714293de3836 3962 }
ashleymills 0:714293de3836 3963
ashleymills 0:714293de3836 3964 if (encryptSz < minLength) {
ashleymills 0:714293de3836 3965 CYASSL_MSG("Ciphertext not minimum size");
ashleymills 0:714293de3836 3966 return SANITY_CIPHER_E;
ashleymills 0:714293de3836 3967 }
ashleymills 0:714293de3836 3968
ashleymills 0:714293de3836 3969 return 0;
ashleymills 0:714293de3836 3970 }
ashleymills 0:714293de3836 3971
ashleymills 0:714293de3836 3972
ashleymills 0:714293de3836 3973 /* decrypt input message in place */
ashleymills 0:714293de3836 3974 static int DecryptMessage(CYASSL* ssl, byte* input, word32 sz, word32* idx)
ashleymills 0:714293de3836 3975 {
ashleymills 0:714293de3836 3976 int decryptResult;
ashleymills 0:714293de3836 3977 int sanityResult = SanityCheckCipherText(ssl, sz);
ashleymills 0:714293de3836 3978
ashleymills 0:714293de3836 3979 if (sanityResult != 0)
ashleymills 0:714293de3836 3980 return sanityResult;
ashleymills 0:714293de3836 3981
ashleymills 0:714293de3836 3982 decryptResult = Decrypt(ssl, input, input, sz);
ashleymills 0:714293de3836 3983
ashleymills 0:714293de3836 3984 if (decryptResult == 0)
ashleymills 0:714293de3836 3985 {
ashleymills 0:714293de3836 3986 ssl->keys.encryptSz = sz;
ashleymills 0:714293de3836 3987 ssl->keys.decryptedCur = 1;
ashleymills 0:714293de3836 3988
ashleymills 0:714293de3836 3989 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
ashleymills 0:714293de3836 3990 *idx += ssl->specs.block_size; /* go past TLSv1.1 IV */
ashleymills 0:714293de3836 3991 if (ssl->specs.cipher_type == aead)
ashleymills 0:714293de3836 3992 *idx += AEAD_EXP_IV_SZ;
ashleymills 0:714293de3836 3993 }
ashleymills 0:714293de3836 3994
ashleymills 0:714293de3836 3995 return decryptResult;
ashleymills 0:714293de3836 3996 }
ashleymills 0:714293de3836 3997
ashleymills 0:714293de3836 3998
ashleymills 0:714293de3836 3999 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 4000
ashleymills 0:714293de3836 4001 static INLINE void Md5Rounds(int rounds, const byte* data, int sz)
ashleymills 0:714293de3836 4002 {
ashleymills 0:714293de3836 4003 Md5 md5;
ashleymills 0:714293de3836 4004 int i;
ashleymills 0:714293de3836 4005
ashleymills 0:714293de3836 4006 InitMd5(&md5);
ashleymills 0:714293de3836 4007
ashleymills 0:714293de3836 4008 for (i = 0; i < rounds; i++)
ashleymills 0:714293de3836 4009 Md5Update(&md5, data, sz);
ashleymills 0:714293de3836 4010 }
ashleymills 0:714293de3836 4011
ashleymills 0:714293de3836 4012
ashleymills 0:714293de3836 4013
ashleymills 0:714293de3836 4014 static INLINE void ShaRounds(int rounds, const byte* data, int sz)
ashleymills 0:714293de3836 4015 {
ashleymills 0:714293de3836 4016 Sha sha;
ashleymills 0:714293de3836 4017 int i;
ashleymills 0:714293de3836 4018
ashleymills 0:714293de3836 4019 InitSha(&sha);
ashleymills 0:714293de3836 4020
ashleymills 0:714293de3836 4021 for (i = 0; i < rounds; i++)
ashleymills 0:714293de3836 4022 ShaUpdate(&sha, data, sz);
ashleymills 0:714293de3836 4023 }
ashleymills 0:714293de3836 4024 #endif
ashleymills 0:714293de3836 4025
ashleymills 0:714293de3836 4026
ashleymills 0:714293de3836 4027 #ifndef NO_SHA256
ashleymills 0:714293de3836 4028
ashleymills 0:714293de3836 4029 static INLINE void Sha256Rounds(int rounds, const byte* data, int sz)
ashleymills 0:714293de3836 4030 {
ashleymills 0:714293de3836 4031 Sha256 sha256;
ashleymills 0:714293de3836 4032 int i;
ashleymills 0:714293de3836 4033
ashleymills 0:714293de3836 4034 InitSha256(&sha256);
ashleymills 0:714293de3836 4035
ashleymills 0:714293de3836 4036 for (i = 0; i < rounds; i++)
ashleymills 0:714293de3836 4037 Sha256Update(&sha256, data, sz);
ashleymills 0:714293de3836 4038 }
ashleymills 0:714293de3836 4039
ashleymills 0:714293de3836 4040 #endif
ashleymills 0:714293de3836 4041
ashleymills 0:714293de3836 4042
ashleymills 0:714293de3836 4043 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 4044
ashleymills 0:714293de3836 4045 static INLINE void Sha384Rounds(int rounds, const byte* data, int sz)
ashleymills 0:714293de3836 4046 {
ashleymills 0:714293de3836 4047 Sha384 sha384;
ashleymills 0:714293de3836 4048 int i;
ashleymills 0:714293de3836 4049
ashleymills 0:714293de3836 4050 InitSha384(&sha384);
ashleymills 0:714293de3836 4051
ashleymills 0:714293de3836 4052 for (i = 0; i < rounds; i++)
ashleymills 0:714293de3836 4053 Sha384Update(&sha384, data, sz);
ashleymills 0:714293de3836 4054 }
ashleymills 0:714293de3836 4055
ashleymills 0:714293de3836 4056 #endif
ashleymills 0:714293de3836 4057
ashleymills 0:714293de3836 4058
ashleymills 0:714293de3836 4059 #ifdef CYASSL_SHA512
ashleymills 0:714293de3836 4060
ashleymills 0:714293de3836 4061 static INLINE void Sha512Rounds(int rounds, const byte* data, int sz)
ashleymills 0:714293de3836 4062 {
ashleymills 0:714293de3836 4063 Sha512 sha512;
ashleymills 0:714293de3836 4064 int i;
ashleymills 0:714293de3836 4065
ashleymills 0:714293de3836 4066 InitSha512(&sha512);
ashleymills 0:714293de3836 4067
ashleymills 0:714293de3836 4068 for (i = 0; i < rounds; i++)
ashleymills 0:714293de3836 4069 Sha512Update(&sha512, data, sz);
ashleymills 0:714293de3836 4070 }
ashleymills 0:714293de3836 4071
ashleymills 0:714293de3836 4072 #endif
ashleymills 0:714293de3836 4073
ashleymills 0:714293de3836 4074
ashleymills 0:714293de3836 4075 #ifdef CYASSL_RIPEMD
ashleymills 0:714293de3836 4076
ashleymills 0:714293de3836 4077 static INLINE void RmdRounds(int rounds, const byte* data, int sz)
ashleymills 0:714293de3836 4078 {
ashleymills 0:714293de3836 4079 RipeMd ripemd;
ashleymills 0:714293de3836 4080 int i;
ashleymills 0:714293de3836 4081
ashleymills 0:714293de3836 4082 InitRipeMd(&ripemd);
ashleymills 0:714293de3836 4083
ashleymills 0:714293de3836 4084 for (i = 0; i < rounds; i++)
ashleymills 0:714293de3836 4085 RipeMdUpdate(&ripemd, data, sz);
ashleymills 0:714293de3836 4086 }
ashleymills 0:714293de3836 4087
ashleymills 0:714293de3836 4088 #endif
ashleymills 0:714293de3836 4089
ashleymills 0:714293de3836 4090
ashleymills 0:714293de3836 4091 static INLINE void DoRounds(int type, int rounds, const byte* data, int sz)
ashleymills 0:714293de3836 4092 {
ashleymills 0:714293de3836 4093 switch (type) {
ashleymills 0:714293de3836 4094
ashleymills 0:714293de3836 4095 case no_mac :
ashleymills 0:714293de3836 4096 break;
ashleymills 0:714293de3836 4097
ashleymills 0:714293de3836 4098 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 4099 #ifndef NO_MD5
ashleymills 0:714293de3836 4100 case md5_mac :
ashleymills 0:714293de3836 4101 Md5Rounds(rounds, data, sz);
ashleymills 0:714293de3836 4102 break;
ashleymills 0:714293de3836 4103 #endif
ashleymills 0:714293de3836 4104
ashleymills 0:714293de3836 4105 #ifndef NO_SHA
ashleymills 0:714293de3836 4106 case sha_mac :
ashleymills 0:714293de3836 4107 ShaRounds(rounds, data, sz);
ashleymills 0:714293de3836 4108 break;
ashleymills 0:714293de3836 4109 #endif
ashleymills 0:714293de3836 4110 #endif
ashleymills 0:714293de3836 4111
ashleymills 0:714293de3836 4112 #ifndef NO_SHA256
ashleymills 0:714293de3836 4113 case sha256_mac :
ashleymills 0:714293de3836 4114 Sha256Rounds(rounds, data, sz);
ashleymills 0:714293de3836 4115 break;
ashleymills 0:714293de3836 4116 #endif
ashleymills 0:714293de3836 4117
ashleymills 0:714293de3836 4118 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 4119 case sha384_mac :
ashleymills 0:714293de3836 4120 Sha384Rounds(rounds, data, sz);
ashleymills 0:714293de3836 4121 break;
ashleymills 0:714293de3836 4122 #endif
ashleymills 0:714293de3836 4123
ashleymills 0:714293de3836 4124 #ifdef CYASSL_SHA512
ashleymills 0:714293de3836 4125 case sha512_mac :
ashleymills 0:714293de3836 4126 Sha512Rounds(rounds, data, sz);
ashleymills 0:714293de3836 4127 break;
ashleymills 0:714293de3836 4128 #endif
ashleymills 0:714293de3836 4129
ashleymills 0:714293de3836 4130 #ifdef CYASSL_RIPEMD
ashleymills 0:714293de3836 4131 case rmd_mac :
ashleymills 0:714293de3836 4132 RmdRounds(rounds, data, sz);
ashleymills 0:714293de3836 4133 break;
ashleymills 0:714293de3836 4134 #endif
ashleymills 0:714293de3836 4135
ashleymills 0:714293de3836 4136 default:
ashleymills 0:714293de3836 4137 CYASSL_MSG("Bad round type");
ashleymills 0:714293de3836 4138 break;
ashleymills 0:714293de3836 4139 }
ashleymills 0:714293de3836 4140 }
ashleymills 0:714293de3836 4141
ashleymills 0:714293de3836 4142
ashleymills 0:714293de3836 4143 /* do number of compression rounds on dummy data */
ashleymills 0:714293de3836 4144 static INLINE void CompressRounds(CYASSL* ssl, int rounds, const byte* dummy)
ashleymills 0:714293de3836 4145 {
ashleymills 0:714293de3836 4146 if (rounds)
ashleymills 0:714293de3836 4147 DoRounds(ssl->specs.mac_algorithm, rounds, dummy, COMPRESS_LOWER);
ashleymills 0:714293de3836 4148 }
ashleymills 0:714293de3836 4149
ashleymills 0:714293de3836 4150
ashleymills 0:714293de3836 4151 /* check all length bytes for equality, return 0 on success */
ashleymills 0:714293de3836 4152 static int ConstantCompare(const byte* a, const byte* b, int length)
ashleymills 0:714293de3836 4153 {
ashleymills 0:714293de3836 4154 int i;
ashleymills 0:714293de3836 4155 int good = 0;
ashleymills 0:714293de3836 4156 int bad = 0;
ashleymills 0:714293de3836 4157
ashleymills 0:714293de3836 4158 for (i = 0; i < length; i++) {
ashleymills 0:714293de3836 4159 if (a[i] == b[i])
ashleymills 0:714293de3836 4160 good++;
ashleymills 0:714293de3836 4161 else
ashleymills 0:714293de3836 4162 bad++;
ashleymills 0:714293de3836 4163 }
ashleymills 0:714293de3836 4164
ashleymills 0:714293de3836 4165 if (good == length)
ashleymills 0:714293de3836 4166 return 0;
ashleymills 0:714293de3836 4167 else
ashleymills 0:714293de3836 4168 return 0 - bad; /* compare failed */
ashleymills 0:714293de3836 4169 }
ashleymills 0:714293de3836 4170
ashleymills 0:714293de3836 4171
ashleymills 0:714293de3836 4172 /* check all length bytes for the pad value, return 0 on success */
ashleymills 0:714293de3836 4173 static int PadCheck(const byte* input, byte pad, int length)
ashleymills 0:714293de3836 4174 {
ashleymills 0:714293de3836 4175 int i;
ashleymills 0:714293de3836 4176 int good = 0;
ashleymills 0:714293de3836 4177 int bad = 0;
ashleymills 0:714293de3836 4178
ashleymills 0:714293de3836 4179 for (i = 0; i < length; i++) {
ashleymills 0:714293de3836 4180 if (input[i] == pad)
ashleymills 0:714293de3836 4181 good++;
ashleymills 0:714293de3836 4182 else
ashleymills 0:714293de3836 4183 bad++;
ashleymills 0:714293de3836 4184 }
ashleymills 0:714293de3836 4185
ashleymills 0:714293de3836 4186 if (good == length)
ashleymills 0:714293de3836 4187 return 0;
ashleymills 0:714293de3836 4188 else
ashleymills 0:714293de3836 4189 return 0 - bad; /* pad check failed */
ashleymills 0:714293de3836 4190 }
ashleymills 0:714293de3836 4191
ashleymills 0:714293de3836 4192
ashleymills 0:714293de3836 4193 /* get compression extra rounds */
ashleymills 0:714293de3836 4194 static INLINE int GetRounds(int pLen, int padLen, int t)
ashleymills 0:714293de3836 4195 {
ashleymills 0:714293de3836 4196 int roundL1 = 1; /* round up flags */
ashleymills 0:714293de3836 4197 int roundL2 = 1;
ashleymills 0:714293de3836 4198
ashleymills 0:714293de3836 4199 int L1 = COMPRESS_CONSTANT + pLen - t;
ashleymills 0:714293de3836 4200 int L2 = COMPRESS_CONSTANT + pLen - padLen - 1 - t;
ashleymills 0:714293de3836 4201
ashleymills 0:714293de3836 4202 L1 -= COMPRESS_UPPER;
ashleymills 0:714293de3836 4203 L2 -= COMPRESS_UPPER;
ashleymills 0:714293de3836 4204
ashleymills 0:714293de3836 4205 if ( (L1 % COMPRESS_LOWER) == 0)
ashleymills 0:714293de3836 4206 roundL1 = 0;
ashleymills 0:714293de3836 4207 if ( (L2 % COMPRESS_LOWER) == 0)
ashleymills 0:714293de3836 4208 roundL2 = 0;
ashleymills 0:714293de3836 4209
ashleymills 0:714293de3836 4210 L1 /= COMPRESS_LOWER;
ashleymills 0:714293de3836 4211 L2 /= COMPRESS_LOWER;
ashleymills 0:714293de3836 4212
ashleymills 0:714293de3836 4213 L1 += roundL1;
ashleymills 0:714293de3836 4214 L2 += roundL2;
ashleymills 0:714293de3836 4215
ashleymills 0:714293de3836 4216 return L1 - L2;
ashleymills 0:714293de3836 4217 }
ashleymills 0:714293de3836 4218
ashleymills 0:714293de3836 4219
ashleymills 0:714293de3836 4220 /* timing resistant pad/verify check, return 0 on success */
ashleymills 0:714293de3836 4221 static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t,
ashleymills 0:714293de3836 4222 int pLen)
ashleymills 0:714293de3836 4223 {
ashleymills 0:714293de3836 4224 byte verify[MAX_DIGEST_SIZE];
ashleymills 0:714293de3836 4225 byte dummy[MAX_PAD_SIZE];
ashleymills 0:714293de3836 4226
ashleymills 0:714293de3836 4227 XMEMSET(dummy, 1, sizeof(dummy));
ashleymills 0:714293de3836 4228
ashleymills 0:714293de3836 4229 if ( (t + padLen + 1) > pLen) {
ashleymills 0:714293de3836 4230 CYASSL_MSG("Plain Len not long enough for pad/mac");
ashleymills 0:714293de3836 4231 PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE);
ashleymills 0:714293de3836 4232 ssl->hmac(ssl, verify, input, pLen - t, application_data, 1);
ashleymills 0:714293de3836 4233 ConstantCompare(verify, input + pLen - t, t);
ashleymills 0:714293de3836 4234
ashleymills 0:714293de3836 4235 return VERIFY_MAC_ERROR;
ashleymills 0:714293de3836 4236 }
ashleymills 0:714293de3836 4237
ashleymills 0:714293de3836 4238 if (PadCheck(input + pLen - (padLen + 1), (byte)padLen, padLen + 1) != 0) {
ashleymills 0:714293de3836 4239 CYASSL_MSG("PadCheck failed");
ashleymills 0:714293de3836 4240 PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
ashleymills 0:714293de3836 4241 ssl->hmac(ssl, verify, input, pLen - t, application_data, 1);
ashleymills 0:714293de3836 4242 ConstantCompare(verify, input + pLen - t, t);
ashleymills 0:714293de3836 4243
ashleymills 0:714293de3836 4244 return VERIFY_MAC_ERROR;
ashleymills 0:714293de3836 4245 }
ashleymills 0:714293de3836 4246
ashleymills 0:714293de3836 4247 PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
ashleymills 0:714293de3836 4248 ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, application_data, 1);
ashleymills 0:714293de3836 4249
ashleymills 0:714293de3836 4250 CompressRounds(ssl, GetRounds(pLen, padLen, t), dummy);
ashleymills 0:714293de3836 4251
ashleymills 0:714293de3836 4252 if (ConstantCompare(verify, input + (pLen - padLen - 1 - t), t) != 0) {
ashleymills 0:714293de3836 4253 CYASSL_MSG("Verify MAC compare failed");
ashleymills 0:714293de3836 4254 return VERIFY_MAC_ERROR;
ashleymills 0:714293de3836 4255 }
ashleymills 0:714293de3836 4256
ashleymills 0:714293de3836 4257 return 0;
ashleymills 0:714293de3836 4258 }
ashleymills 0:714293de3836 4259
ashleymills 0:714293de3836 4260
ashleymills 0:714293de3836 4261 int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx)
ashleymills 0:714293de3836 4262 {
ashleymills 0:714293de3836 4263 word32 msgSz = ssl->keys.encryptSz;
ashleymills 0:714293de3836 4264 word32 pad = 0,
ashleymills 0:714293de3836 4265 padByte = 0,
ashleymills 0:714293de3836 4266 idx = *inOutIdx,
ashleymills 0:714293de3836 4267 digestSz = ssl->specs.hash_size;
ashleymills 0:714293de3836 4268 int dataSz, ret;
ashleymills 0:714293de3836 4269 int ivExtra = 0;
ashleymills 0:714293de3836 4270 byte* rawData = input + idx; /* keep current for hmac */
ashleymills 0:714293de3836 4271 #ifdef HAVE_LIBZ
ashleymills 0:714293de3836 4272 byte decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
ashleymills 0:714293de3836 4273 #endif
ashleymills 0:714293de3836 4274 byte verify[MAX_DIGEST_SIZE];
ashleymills 0:714293de3836 4275
ashleymills 0:714293de3836 4276 if (ssl->options.handShakeState != HANDSHAKE_DONE) {
ashleymills 0:714293de3836 4277 CYASSL_MSG("Received App data before handshake complete");
ashleymills 0:714293de3836 4278 SendAlert(ssl, alert_fatal, unexpected_message);
ashleymills 0:714293de3836 4279 return OUT_OF_ORDER_E;
ashleymills 0:714293de3836 4280 }
ashleymills 0:714293de3836 4281
ashleymills 0:714293de3836 4282 if (ssl->specs.cipher_type == block) {
ashleymills 0:714293de3836 4283 if (ssl->options.tls1_1)
ashleymills 0:714293de3836 4284 ivExtra = ssl->specs.block_size;
ashleymills 0:714293de3836 4285 pad = *(input + idx + msgSz - ivExtra - 1);
ashleymills 0:714293de3836 4286 padByte = 1;
ashleymills 0:714293de3836 4287
ashleymills 0:714293de3836 4288 if (ssl->options.tls) {
ashleymills 0:714293de3836 4289 ret = TimingPadVerify(ssl, input + idx, pad, digestSz,
ashleymills 0:714293de3836 4290 msgSz - ivExtra);
ashleymills 0:714293de3836 4291 if (ret != 0)
ashleymills 0:714293de3836 4292 return ret;
ashleymills 0:714293de3836 4293 }
ashleymills 0:714293de3836 4294 else { /* sslv3, some implementations have bad padding */
ashleymills 0:714293de3836 4295 ssl->hmac(ssl, verify, rawData, msgSz - digestSz - pad - 1,
ashleymills 0:714293de3836 4296 application_data, 1);
ashleymills 0:714293de3836 4297 if (ConstantCompare(verify, rawData + msgSz - digestSz - pad - 1,
ashleymills 0:714293de3836 4298 digestSz) != 0)
ashleymills 0:714293de3836 4299 return VERIFY_MAC_ERROR;
ashleymills 0:714293de3836 4300 }
ashleymills 0:714293de3836 4301 }
ashleymills 0:714293de3836 4302 else if (ssl->specs.cipher_type == stream) {
ashleymills 0:714293de3836 4303 ssl->hmac(ssl, verify, rawData, msgSz - digestSz, application_data, 1);
ashleymills 0:714293de3836 4304 if (ConstantCompare(verify, rawData + msgSz - digestSz, digestSz) != 0){
ashleymills 0:714293de3836 4305 return VERIFY_MAC_ERROR;
ashleymills 0:714293de3836 4306 }
ashleymills 0:714293de3836 4307 }
ashleymills 0:714293de3836 4308 else if (ssl->specs.cipher_type == aead) {
ashleymills 0:714293de3836 4309 ivExtra = AEAD_EXP_IV_SZ;
ashleymills 0:714293de3836 4310 digestSz = ssl->specs.aead_mac_size;
ashleymills 0:714293de3836 4311 }
ashleymills 0:714293de3836 4312
ashleymills 0:714293de3836 4313 dataSz = msgSz - ivExtra - digestSz - pad - padByte;
ashleymills 0:714293de3836 4314 if (dataSz < 0) {
ashleymills 0:714293de3836 4315 CYASSL_MSG("App data buffer error, malicious input?");
ashleymills 0:714293de3836 4316 return BUFFER_ERROR;
ashleymills 0:714293de3836 4317 }
ashleymills 0:714293de3836 4318
ashleymills 0:714293de3836 4319 /* read data */
ashleymills 0:714293de3836 4320 if (dataSz) {
ashleymills 0:714293de3836 4321 int rawSz = dataSz; /* keep raw size for idx adjustment */
ashleymills 0:714293de3836 4322
ashleymills 0:714293de3836 4323 #ifdef HAVE_LIBZ
ashleymills 0:714293de3836 4324 if (ssl->options.usingCompression) {
ashleymills 0:714293de3836 4325 dataSz = myDeCompress(ssl, rawData, dataSz, decomp, sizeof(decomp));
ashleymills 0:714293de3836 4326 if (dataSz < 0) return dataSz;
ashleymills 0:714293de3836 4327 }
ashleymills 0:714293de3836 4328 #endif
ashleymills 0:714293de3836 4329 idx += rawSz;
ashleymills 0:714293de3836 4330
ashleymills 0:714293de3836 4331 ssl->buffers.clearOutputBuffer.buffer = rawData;
ashleymills 0:714293de3836 4332 ssl->buffers.clearOutputBuffer.length = dataSz;
ashleymills 0:714293de3836 4333 }
ashleymills 0:714293de3836 4334
ashleymills 0:714293de3836 4335 idx += digestSz;
ashleymills 0:714293de3836 4336 idx += pad;
ashleymills 0:714293de3836 4337 if (padByte)
ashleymills 0:714293de3836 4338 idx++;
ashleymills 0:714293de3836 4339
ashleymills 0:714293de3836 4340 #ifdef HAVE_LIBZ
ashleymills 0:714293de3836 4341 /* decompress could be bigger, overwrite after verify */
ashleymills 0:714293de3836 4342 if (ssl->options.usingCompression)
ashleymills 0:714293de3836 4343 XMEMMOVE(rawData, decomp, dataSz);
ashleymills 0:714293de3836 4344 #endif
ashleymills 0:714293de3836 4345
ashleymills 0:714293de3836 4346 *inOutIdx = idx;
ashleymills 0:714293de3836 4347 return 0;
ashleymills 0:714293de3836 4348 }
ashleymills 0:714293de3836 4349
ashleymills 0:714293de3836 4350
ashleymills 0:714293de3836 4351 /* process alert, return level */
ashleymills 0:714293de3836 4352 static int DoAlert(CYASSL* ssl, byte* input, word32* inOutIdx, int* type)
ashleymills 0:714293de3836 4353 {
ashleymills 0:714293de3836 4354 byte level;
ashleymills 0:714293de3836 4355 byte code;
ashleymills 0:714293de3836 4356
ashleymills 0:714293de3836 4357 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 4358 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 4359 AddPacketName("Alert", &ssl->handShakeInfo);
ashleymills 0:714293de3836 4360 if (ssl->toInfoOn)
ashleymills 0:714293de3836 4361 /* add record header back on to info + 2 byte level, data */
ashleymills 0:714293de3836 4362 AddPacketInfo("Alert", &ssl->timeoutInfo, input + *inOutIdx -
ashleymills 0:714293de3836 4363 RECORD_HEADER_SZ, 2 + RECORD_HEADER_SZ, ssl->heap);
ashleymills 0:714293de3836 4364 #endif
ashleymills 0:714293de3836 4365 level = input[(*inOutIdx)++];
ashleymills 0:714293de3836 4366 code = (int)input[(*inOutIdx)++];
ashleymills 0:714293de3836 4367 ssl->alert_history.last_rx.code = code;
ashleymills 0:714293de3836 4368 ssl->alert_history.last_rx.level = level;
ashleymills 0:714293de3836 4369 *type = code;
ashleymills 0:714293de3836 4370 if (level == alert_fatal) {
ashleymills 0:714293de3836 4371 ssl->options.isClosed = 1; /* Don't send close_notify */
ashleymills 0:714293de3836 4372 }
ashleymills 0:714293de3836 4373
ashleymills 0:714293de3836 4374 CYASSL_MSG("Got alert");
ashleymills 0:714293de3836 4375 if (*type == close_notify) {
ashleymills 0:714293de3836 4376 CYASSL_MSG(" close notify");
ashleymills 0:714293de3836 4377 ssl->options.closeNotify = 1;
ashleymills 0:714293de3836 4378 }
ashleymills 0:714293de3836 4379 CYASSL_ERROR(*type);
ashleymills 0:714293de3836 4380
ashleymills 0:714293de3836 4381 if (ssl->keys.encryptionOn) {
ashleymills 0:714293de3836 4382 if (ssl->specs.cipher_type != aead) {
ashleymills 0:714293de3836 4383 int aSz = ALERT_SIZE;
ashleymills 0:714293de3836 4384 const byte* mac;
ashleymills 0:714293de3836 4385 byte verify[MAX_DIGEST_SIZE];
ashleymills 0:714293de3836 4386 int padSz = ssl->keys.encryptSz - aSz - ssl->specs.hash_size;
ashleymills 0:714293de3836 4387
ashleymills 0:714293de3836 4388 ssl->hmac(ssl, verify, input + *inOutIdx - aSz, aSz, alert, 1);
ashleymills 0:714293de3836 4389
ashleymills 0:714293de3836 4390 /* read mac and fill */
ashleymills 0:714293de3836 4391 mac = input + *inOutIdx;
ashleymills 0:714293de3836 4392 *inOutIdx += (ssl->specs.hash_size + padSz);
ashleymills 0:714293de3836 4393
ashleymills 0:714293de3836 4394 /* verify */
ashleymills 0:714293de3836 4395 if (XMEMCMP(mac, verify, ssl->specs.hash_size) != 0) {
ashleymills 0:714293de3836 4396 CYASSL_MSG(" alert verify mac error");
ashleymills 0:714293de3836 4397 return VERIFY_MAC_ERROR;
ashleymills 0:714293de3836 4398 }
ashleymills 0:714293de3836 4399 }
ashleymills 0:714293de3836 4400 else {
ashleymills 0:714293de3836 4401 *inOutIdx += ssl->specs.aead_mac_size;
ashleymills 0:714293de3836 4402 }
ashleymills 0:714293de3836 4403 }
ashleymills 0:714293de3836 4404
ashleymills 0:714293de3836 4405 return level;
ashleymills 0:714293de3836 4406 }
ashleymills 0:714293de3836 4407
ashleymills 0:714293de3836 4408 static int GetInputData(CYASSL *ssl, word32 size)
ashleymills 0:714293de3836 4409 {
ashleymills 0:714293de3836 4410 int in;
ashleymills 0:714293de3836 4411 int inSz;
ashleymills 0:714293de3836 4412 int maxLength;
ashleymills 0:714293de3836 4413 int usedLength;
ashleymills 0:714293de3836 4414 int dtlsExtra = 0;
ashleymills 0:714293de3836 4415
ashleymills 0:714293de3836 4416
ashleymills 0:714293de3836 4417 /* check max input length */
ashleymills 0:714293de3836 4418 usedLength = ssl->buffers.inputBuffer.length - ssl->buffers.inputBuffer.idx;
ashleymills 0:714293de3836 4419 maxLength = ssl->buffers.inputBuffer.bufferSize - usedLength;
ashleymills 0:714293de3836 4420 inSz = (int)(size - usedLength); /* from last partial read */
ashleymills 0:714293de3836 4421
ashleymills 0:714293de3836 4422 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 4423 if (ssl->options.dtls) {
ashleymills 0:714293de3836 4424 if (size < ssl->dtls_expected_rx)
ashleymills 0:714293de3836 4425 dtlsExtra = (int)(ssl->dtls_expected_rx - size);
ashleymills 0:714293de3836 4426 inSz = ssl->dtls_expected_rx;
ashleymills 0:714293de3836 4427 }
ashleymills 0:714293de3836 4428 #endif
ashleymills 0:714293de3836 4429
ashleymills 0:714293de3836 4430 if (inSz > maxLength) {
ashleymills 0:714293de3836 4431 if (GrowInputBuffer(ssl, size + dtlsExtra, usedLength) < 0)
ashleymills 0:714293de3836 4432 return MEMORY_E;
ashleymills 0:714293de3836 4433 }
ashleymills 0:714293de3836 4434
ashleymills 0:714293de3836 4435 if (inSz <= 0)
ashleymills 0:714293de3836 4436 return BUFFER_ERROR;
ashleymills 0:714293de3836 4437
ashleymills 0:714293de3836 4438 /* Put buffer data at start if not there */
ashleymills 0:714293de3836 4439 if (usedLength > 0 && ssl->buffers.inputBuffer.idx != 0)
ashleymills 0:714293de3836 4440 XMEMMOVE(ssl->buffers.inputBuffer.buffer,
ashleymills 0:714293de3836 4441 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
ashleymills 0:714293de3836 4442 usedLength);
ashleymills 0:714293de3836 4443
ashleymills 0:714293de3836 4444 /* remove processed data */
ashleymills 0:714293de3836 4445 ssl->buffers.inputBuffer.idx = 0;
ashleymills 0:714293de3836 4446 ssl->buffers.inputBuffer.length = usedLength;
ashleymills 0:714293de3836 4447
ashleymills 0:714293de3836 4448 /* read data from network */
ashleymills 0:714293de3836 4449 do {
ashleymills 0:714293de3836 4450 in = Receive(ssl,
ashleymills 0:714293de3836 4451 ssl->buffers.inputBuffer.buffer +
ashleymills 0:714293de3836 4452 ssl->buffers.inputBuffer.length,
ashleymills 0:714293de3836 4453 inSz);
ashleymills 0:714293de3836 4454 if (in == -1)
ashleymills 0:714293de3836 4455 return SOCKET_ERROR_E;
ashleymills 0:714293de3836 4456
ashleymills 0:714293de3836 4457 if (in == WANT_READ)
ashleymills 0:714293de3836 4458 return WANT_READ;
ashleymills 0:714293de3836 4459
ashleymills 0:714293de3836 4460 if (in > inSz)
ashleymills 0:714293de3836 4461 return RECV_OVERFLOW_E;
ashleymills 0:714293de3836 4462
ashleymills 0:714293de3836 4463 ssl->buffers.inputBuffer.length += in;
ashleymills 0:714293de3836 4464 inSz -= in;
ashleymills 0:714293de3836 4465
ashleymills 0:714293de3836 4466 } while (ssl->buffers.inputBuffer.length < size);
ashleymills 0:714293de3836 4467
ashleymills 0:714293de3836 4468 return 0;
ashleymills 0:714293de3836 4469 }
ashleymills 0:714293de3836 4470
ashleymills 0:714293de3836 4471 /* process input requests, return 0 is done, 1 is call again to complete, and
ashleymills 0:714293de3836 4472 negative number is error */
ashleymills 0:714293de3836 4473 int ProcessReply(CYASSL* ssl)
ashleymills 0:714293de3836 4474 {
ashleymills 0:714293de3836 4475 int ret = 0, type, readSz;
ashleymills 0:714293de3836 4476 word32 startIdx = 0;
ashleymills 0:714293de3836 4477 #ifndef NO_CYASSL_SERVER
ashleymills 0:714293de3836 4478 byte b0, b1;
ashleymills 0:714293de3836 4479 #endif
ashleymills 0:714293de3836 4480 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 4481 int used;
ashleymills 0:714293de3836 4482 #endif
ashleymills 0:714293de3836 4483
ashleymills 0:714293de3836 4484 for (;;) {
ashleymills 0:714293de3836 4485 switch ((processReply)ssl->options.processReply) {
ashleymills 0:714293de3836 4486
ashleymills 0:714293de3836 4487 /* in the CYASSL_SERVER case, get the first byte for detecting
ashleymills 0:714293de3836 4488 * old client hello */
ashleymills 0:714293de3836 4489 case doProcessInit:
ashleymills 0:714293de3836 4490
ashleymills 0:714293de3836 4491 readSz = RECORD_HEADER_SZ;
ashleymills 0:714293de3836 4492
ashleymills 0:714293de3836 4493 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 4494 if (ssl->options.dtls)
ashleymills 0:714293de3836 4495 readSz = DTLS_RECORD_HEADER_SZ;
ashleymills 0:714293de3836 4496 #endif
ashleymills 0:714293de3836 4497
ashleymills 0:714293de3836 4498 /* get header or return error */
ashleymills 0:714293de3836 4499 if (!ssl->options.dtls) {
ashleymills 0:714293de3836 4500 if ((ret = GetInputData(ssl, readSz)) < 0)
ashleymills 0:714293de3836 4501 return ret;
ashleymills 0:714293de3836 4502 } else {
ashleymills 0:714293de3836 4503 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 4504 /* read ahead may already have header */
ashleymills 0:714293de3836 4505 used = ssl->buffers.inputBuffer.length -
ashleymills 0:714293de3836 4506 ssl->buffers.inputBuffer.idx;
ashleymills 0:714293de3836 4507 if (used < readSz)
ashleymills 0:714293de3836 4508 if ((ret = GetInputData(ssl, readSz)) < 0)
ashleymills 0:714293de3836 4509 return ret;
ashleymills 0:714293de3836 4510 #endif
ashleymills 0:714293de3836 4511 }
ashleymills 0:714293de3836 4512
ashleymills 0:714293de3836 4513 #ifndef NO_CYASSL_SERVER
ashleymills 0:714293de3836 4514
ashleymills 0:714293de3836 4515 /* see if sending SSLv2 client hello */
ashleymills 0:714293de3836 4516 if ( ssl->options.side == SERVER_END &&
ashleymills 0:714293de3836 4517 ssl->options.clientState == NULL_STATE &&
ashleymills 0:714293de3836 4518 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx]
ashleymills 0:714293de3836 4519 != handshake) {
ashleymills 0:714293de3836 4520 ssl->options.processReply = runProcessOldClientHello;
ashleymills 0:714293de3836 4521
ashleymills 0:714293de3836 4522 /* how many bytes need ProcessOldClientHello */
ashleymills 0:714293de3836 4523 b0 =
ashleymills 0:714293de3836 4524 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
ashleymills 0:714293de3836 4525 b1 =
ashleymills 0:714293de3836 4526 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
ashleymills 0:714293de3836 4527 ssl->curSize = ((b0 & 0x7f) << 8) | b1;
ashleymills 0:714293de3836 4528 }
ashleymills 0:714293de3836 4529 else {
ashleymills 0:714293de3836 4530 ssl->options.processReply = getRecordLayerHeader;
ashleymills 0:714293de3836 4531 continue;
ashleymills 0:714293de3836 4532 }
ashleymills 0:714293de3836 4533
ashleymills 0:714293de3836 4534 /* in the CYASSL_SERVER case, run the old client hello */
ashleymills 0:714293de3836 4535 case runProcessOldClientHello:
ashleymills 0:714293de3836 4536
ashleymills 0:714293de3836 4537 /* get sz bytes or return error */
ashleymills 0:714293de3836 4538 if (!ssl->options.dtls) {
ashleymills 0:714293de3836 4539 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
ashleymills 0:714293de3836 4540 return ret;
ashleymills 0:714293de3836 4541 } else {
ashleymills 0:714293de3836 4542 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 4543 /* read ahead may already have */
ashleymills 0:714293de3836 4544 used = ssl->buffers.inputBuffer.length -
ashleymills 0:714293de3836 4545 ssl->buffers.inputBuffer.idx;
ashleymills 0:714293de3836 4546 if (used < ssl->curSize)
ashleymills 0:714293de3836 4547 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
ashleymills 0:714293de3836 4548 return ret;
ashleymills 0:714293de3836 4549 #endif /* CYASSL_DTLS */
ashleymills 0:714293de3836 4550 }
ashleymills 0:714293de3836 4551
ashleymills 0:714293de3836 4552 ret = ProcessOldClientHello(ssl, ssl->buffers.inputBuffer.buffer,
ashleymills 0:714293de3836 4553 &ssl->buffers.inputBuffer.idx,
ashleymills 0:714293de3836 4554 ssl->buffers.inputBuffer.length -
ashleymills 0:714293de3836 4555 ssl->buffers.inputBuffer.idx,
ashleymills 0:714293de3836 4556 ssl->curSize);
ashleymills 0:714293de3836 4557 if (ret < 0)
ashleymills 0:714293de3836 4558 return ret;
ashleymills 0:714293de3836 4559
ashleymills 0:714293de3836 4560 else if (ssl->buffers.inputBuffer.idx ==
ashleymills 0:714293de3836 4561 ssl->buffers.inputBuffer.length) {
ashleymills 0:714293de3836 4562 ssl->options.processReply = doProcessInit;
ashleymills 0:714293de3836 4563 return 0;
ashleymills 0:714293de3836 4564 }
ashleymills 0:714293de3836 4565
ashleymills 0:714293de3836 4566 #endif /* NO_CYASSL_SERVER */
ashleymills 0:714293de3836 4567
ashleymills 0:714293de3836 4568 /* get the record layer header */
ashleymills 0:714293de3836 4569 case getRecordLayerHeader:
ashleymills 0:714293de3836 4570
ashleymills 0:714293de3836 4571 ret = GetRecordHeader(ssl, ssl->buffers.inputBuffer.buffer,
ashleymills 0:714293de3836 4572 &ssl->buffers.inputBuffer.idx,
ashleymills 0:714293de3836 4573 &ssl->curRL, &ssl->curSize);
ashleymills 0:714293de3836 4574 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 4575 if (ssl->options.dtls && ret == SEQUENCE_ERROR) {
ashleymills 0:714293de3836 4576 /* This message is out of order. If we are handshaking, save
ashleymills 0:714293de3836 4577 *it for later. Otherwise go ahead and process it. */
ashleymills 0:714293de3836 4578 ssl->options.processReply = doProcessInit;
ashleymills 0:714293de3836 4579 ssl->buffers.inputBuffer.length = 0;
ashleymills 0:714293de3836 4580 ssl->buffers.inputBuffer.idx = 0;
ashleymills 0:714293de3836 4581 continue;
ashleymills 0:714293de3836 4582 }
ashleymills 0:714293de3836 4583 #endif
ashleymills 0:714293de3836 4584 if (ret != 0)
ashleymills 0:714293de3836 4585 return ret;
ashleymills 0:714293de3836 4586
ashleymills 0:714293de3836 4587 ssl->options.processReply = getData;
ashleymills 0:714293de3836 4588
ashleymills 0:714293de3836 4589 /* retrieve record layer data */
ashleymills 0:714293de3836 4590 case getData:
ashleymills 0:714293de3836 4591
ashleymills 0:714293de3836 4592 /* get sz bytes or return error */
ashleymills 0:714293de3836 4593 if (!ssl->options.dtls) {
ashleymills 0:714293de3836 4594 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
ashleymills 0:714293de3836 4595 return ret;
ashleymills 0:714293de3836 4596 } else {
ashleymills 0:714293de3836 4597 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 4598 /* read ahead may already have */
ashleymills 0:714293de3836 4599 used = ssl->buffers.inputBuffer.length -
ashleymills 0:714293de3836 4600 ssl->buffers.inputBuffer.idx;
ashleymills 0:714293de3836 4601 if (used < ssl->curSize)
ashleymills 0:714293de3836 4602 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
ashleymills 0:714293de3836 4603 return ret;
ashleymills 0:714293de3836 4604 #endif
ashleymills 0:714293de3836 4605 }
ashleymills 0:714293de3836 4606
ashleymills 0:714293de3836 4607 ssl->options.processReply = runProcessingOneMessage;
ashleymills 0:714293de3836 4608 startIdx = ssl->buffers.inputBuffer.idx; /* in case > 1 msg per */
ashleymills 0:714293de3836 4609
ashleymills 0:714293de3836 4610 /* the record layer is here */
ashleymills 0:714293de3836 4611 case runProcessingOneMessage:
ashleymills 0:714293de3836 4612
ashleymills 0:714293de3836 4613 if (ssl->keys.encryptionOn && ssl->keys.decryptedCur == 0) {
ashleymills 0:714293de3836 4614 ret = DecryptMessage(ssl, ssl->buffers.inputBuffer.buffer +
ashleymills 0:714293de3836 4615 ssl->buffers.inputBuffer.idx,
ashleymills 0:714293de3836 4616 ssl->curSize,
ashleymills 0:714293de3836 4617 &ssl->buffers.inputBuffer.idx);
ashleymills 0:714293de3836 4618 if (ret < 0) {
ashleymills 0:714293de3836 4619 CYASSL_ERROR(ret);
ashleymills 0:714293de3836 4620 return DECRYPT_ERROR;
ashleymills 0:714293de3836 4621 }
ashleymills 0:714293de3836 4622 }
ashleymills 0:714293de3836 4623
ashleymills 0:714293de3836 4624 CYASSL_MSG("received record layer msg");
ashleymills 0:714293de3836 4625
ashleymills 0:714293de3836 4626 switch (ssl->curRL.type) {
ashleymills 0:714293de3836 4627 case handshake :
ashleymills 0:714293de3836 4628 /* debugging in DoHandShakeMsg */
ashleymills 0:714293de3836 4629 if (!ssl->options.dtls) {
ashleymills 0:714293de3836 4630 ret = DoHandShakeMsg(ssl,
ashleymills 0:714293de3836 4631 ssl->buffers.inputBuffer.buffer,
ashleymills 0:714293de3836 4632 &ssl->buffers.inputBuffer.idx,
ashleymills 0:714293de3836 4633 ssl->buffers.inputBuffer.length);
ashleymills 0:714293de3836 4634 }
ashleymills 0:714293de3836 4635 else {
ashleymills 0:714293de3836 4636 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 4637 ret = DoDtlsHandShakeMsg(ssl,
ashleymills 0:714293de3836 4638 ssl->buffers.inputBuffer.buffer,
ashleymills 0:714293de3836 4639 &ssl->buffers.inputBuffer.idx,
ashleymills 0:714293de3836 4640 ssl->buffers.inputBuffer.length);
ashleymills 0:714293de3836 4641 #endif
ashleymills 0:714293de3836 4642 }
ashleymills 0:714293de3836 4643 if (ret != 0)
ashleymills 0:714293de3836 4644 return ret;
ashleymills 0:714293de3836 4645 break;
ashleymills 0:714293de3836 4646
ashleymills 0:714293de3836 4647 case change_cipher_spec:
ashleymills 0:714293de3836 4648 CYASSL_MSG("got CHANGE CIPHER SPEC");
ashleymills 0:714293de3836 4649 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 4650 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 4651 AddPacketName("ChangeCipher", &ssl->handShakeInfo);
ashleymills 0:714293de3836 4652 /* add record header back on info */
ashleymills 0:714293de3836 4653 if (ssl->toInfoOn) {
ashleymills 0:714293de3836 4654 AddPacketInfo("ChangeCipher", &ssl->timeoutInfo,
ashleymills 0:714293de3836 4655 ssl->buffers.inputBuffer.buffer +
ashleymills 0:714293de3836 4656 ssl->buffers.inputBuffer.idx - RECORD_HEADER_SZ,
ashleymills 0:714293de3836 4657 1 + RECORD_HEADER_SZ, ssl->heap);
ashleymills 0:714293de3836 4658 AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
ashleymills 0:714293de3836 4659 }
ashleymills 0:714293de3836 4660 #endif
ashleymills 0:714293de3836 4661
ashleymills 0:714293de3836 4662 if (ssl->curSize != 1) {
ashleymills 0:714293de3836 4663 CYASSL_MSG("Malicious or corrupted ChangeCipher msg");
ashleymills 0:714293de3836 4664 return LENGTH_ERROR;
ashleymills 0:714293de3836 4665 }
ashleymills 0:714293de3836 4666 #ifndef NO_CERTS
ashleymills 0:714293de3836 4667 if (ssl->options.side == SERVER_END &&
ashleymills 0:714293de3836 4668 ssl->options.verifyPeer &&
ashleymills 0:714293de3836 4669 ssl->options.havePeerCert)
ashleymills 0:714293de3836 4670 if (!ssl->options.havePeerVerify) {
ashleymills 0:714293de3836 4671 CYASSL_MSG("client didn't send cert verify");
ashleymills 0:714293de3836 4672 return NO_PEER_VERIFY;
ashleymills 0:714293de3836 4673 }
ashleymills 0:714293de3836 4674 #endif
ashleymills 0:714293de3836 4675
ashleymills 0:714293de3836 4676
ashleymills 0:714293de3836 4677 ssl->buffers.inputBuffer.idx++;
ashleymills 0:714293de3836 4678 ssl->keys.encryptionOn = 1;
ashleymills 0:714293de3836 4679
ashleymills 0:714293de3836 4680 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 4681 if (ssl->options.dtls) {
ashleymills 0:714293de3836 4682 DtlsPoolReset(ssl);
ashleymills 0:714293de3836 4683 ssl->keys.dtls_expected_peer_epoch++;
ashleymills 0:714293de3836 4684 ssl->keys.dtls_expected_peer_sequence_number = 0;
ashleymills 0:714293de3836 4685 }
ashleymills 0:714293de3836 4686 #endif
ashleymills 0:714293de3836 4687
ashleymills 0:714293de3836 4688 #ifdef HAVE_LIBZ
ashleymills 0:714293de3836 4689 if (ssl->options.usingCompression)
ashleymills 0:714293de3836 4690 if ( (ret = InitStreams(ssl)) != 0)
ashleymills 0:714293de3836 4691 return ret;
ashleymills 0:714293de3836 4692 #endif
ashleymills 0:714293de3836 4693 if (ssl->options.resuming && ssl->options.side ==
ashleymills 0:714293de3836 4694 CLIENT_END)
ashleymills 0:714293de3836 4695 BuildFinished(ssl, &ssl->verifyHashes, server);
ashleymills 0:714293de3836 4696 else if (!ssl->options.resuming && ssl->options.side ==
ashleymills 0:714293de3836 4697 SERVER_END)
ashleymills 0:714293de3836 4698 BuildFinished(ssl, &ssl->verifyHashes, client);
ashleymills 0:714293de3836 4699 break;
ashleymills 0:714293de3836 4700
ashleymills 0:714293de3836 4701 case application_data:
ashleymills 0:714293de3836 4702 CYASSL_MSG("got app DATA");
ashleymills 0:714293de3836 4703 if ((ret = DoApplicationData(ssl,
ashleymills 0:714293de3836 4704 ssl->buffers.inputBuffer.buffer,
ashleymills 0:714293de3836 4705 &ssl->buffers.inputBuffer.idx))
ashleymills 0:714293de3836 4706 != 0) {
ashleymills 0:714293de3836 4707 CYASSL_ERROR(ret);
ashleymills 0:714293de3836 4708 return ret;
ashleymills 0:714293de3836 4709 }
ashleymills 0:714293de3836 4710 break;
ashleymills 0:714293de3836 4711
ashleymills 0:714293de3836 4712 case alert:
ashleymills 0:714293de3836 4713 CYASSL_MSG("got ALERT!");
ashleymills 0:714293de3836 4714 if (DoAlert(ssl, ssl->buffers.inputBuffer.buffer,
ashleymills 0:714293de3836 4715 &ssl->buffers.inputBuffer.idx, &type) == alert_fatal)
ashleymills 0:714293de3836 4716 return FATAL_ERROR;
ashleymills 0:714293de3836 4717
ashleymills 0:714293de3836 4718 /* catch warnings that are handled as errors */
ashleymills 0:714293de3836 4719 if (type == close_notify)
ashleymills 0:714293de3836 4720 return ssl->error = ZERO_RETURN;
ashleymills 0:714293de3836 4721
ashleymills 0:714293de3836 4722 if (type == decrypt_error)
ashleymills 0:714293de3836 4723 return FATAL_ERROR;
ashleymills 0:714293de3836 4724 break;
ashleymills 0:714293de3836 4725
ashleymills 0:714293de3836 4726 default:
ashleymills 0:714293de3836 4727 CYASSL_ERROR(UNKNOWN_RECORD_TYPE);
ashleymills 0:714293de3836 4728 return UNKNOWN_RECORD_TYPE;
ashleymills 0:714293de3836 4729 }
ashleymills 0:714293de3836 4730
ashleymills 0:714293de3836 4731 ssl->options.processReply = doProcessInit;
ashleymills 0:714293de3836 4732
ashleymills 0:714293de3836 4733 /* input exhausted? */
ashleymills 0:714293de3836 4734 if (ssl->buffers.inputBuffer.idx == ssl->buffers.inputBuffer.length)
ashleymills 0:714293de3836 4735 return 0;
ashleymills 0:714293de3836 4736 /* more messages per record */
ashleymills 0:714293de3836 4737 else if ((ssl->buffers.inputBuffer.idx - startIdx) < ssl->curSize) {
ashleymills 0:714293de3836 4738 CYASSL_MSG("More messages in record");
ashleymills 0:714293de3836 4739 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 4740 /* read-ahead but dtls doesn't bundle messages per record */
ashleymills 0:714293de3836 4741 if (ssl->options.dtls) {
ashleymills 0:714293de3836 4742 ssl->options.processReply = doProcessInit;
ashleymills 0:714293de3836 4743 continue;
ashleymills 0:714293de3836 4744 }
ashleymills 0:714293de3836 4745 #endif
ashleymills 0:714293de3836 4746 ssl->options.processReply = runProcessingOneMessage;
ashleymills 0:714293de3836 4747 continue;
ashleymills 0:714293de3836 4748 }
ashleymills 0:714293de3836 4749 /* more records */
ashleymills 0:714293de3836 4750 else {
ashleymills 0:714293de3836 4751 CYASSL_MSG("More records in input");
ashleymills 0:714293de3836 4752 ssl->options.processReply = doProcessInit;
ashleymills 0:714293de3836 4753 continue;
ashleymills 0:714293de3836 4754 }
ashleymills 0:714293de3836 4755 default:
ashleymills 0:714293de3836 4756 CYASSL_MSG("Bad process input state, programming error");
ashleymills 0:714293de3836 4757 return INPUT_CASE_ERROR;
ashleymills 0:714293de3836 4758 }
ashleymills 0:714293de3836 4759 }
ashleymills 0:714293de3836 4760 }
ashleymills 0:714293de3836 4761
ashleymills 0:714293de3836 4762
ashleymills 0:714293de3836 4763 int SendChangeCipher(CYASSL* ssl)
ashleymills 0:714293de3836 4764 {
ashleymills 0:714293de3836 4765 byte *output;
ashleymills 0:714293de3836 4766 int sendSz = RECORD_HEADER_SZ + ENUM_LEN;
ashleymills 0:714293de3836 4767 int idx = RECORD_HEADER_SZ;
ashleymills 0:714293de3836 4768 int ret;
ashleymills 0:714293de3836 4769
ashleymills 0:714293de3836 4770 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 4771 if (ssl->options.dtls) {
ashleymills 0:714293de3836 4772 sendSz += DTLS_RECORD_EXTRA;
ashleymills 0:714293de3836 4773 idx += DTLS_RECORD_EXTRA;
ashleymills 0:714293de3836 4774 }
ashleymills 0:714293de3836 4775 #endif
ashleymills 0:714293de3836 4776
ashleymills 0:714293de3836 4777 /* check for avalaible size */
ashleymills 0:714293de3836 4778 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
ashleymills 0:714293de3836 4779 return ret;
ashleymills 0:714293de3836 4780
ashleymills 0:714293de3836 4781 /* get ouput buffer */
ashleymills 0:714293de3836 4782 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 4783 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 4784
ashleymills 0:714293de3836 4785 AddRecordHeader(output, 1, change_cipher_spec, ssl);
ashleymills 0:714293de3836 4786
ashleymills 0:714293de3836 4787 output[idx] = 1; /* turn it on */
ashleymills 0:714293de3836 4788
ashleymills 0:714293de3836 4789 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 4790 if (ssl->options.dtls) {
ashleymills 0:714293de3836 4791 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:714293de3836 4792 return ret;
ashleymills 0:714293de3836 4793 }
ashleymills 0:714293de3836 4794 #endif
ashleymills 0:714293de3836 4795 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 4796 if (ssl->hsInfoOn) AddPacketName("ChangeCipher", &ssl->handShakeInfo);
ashleymills 0:714293de3836 4797 if (ssl->toInfoOn)
ashleymills 0:714293de3836 4798 AddPacketInfo("ChangeCipher", &ssl->timeoutInfo, output, sendSz,
ashleymills 0:714293de3836 4799 ssl->heap);
ashleymills 0:714293de3836 4800 #endif
ashleymills 0:714293de3836 4801 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:714293de3836 4802
ashleymills 0:714293de3836 4803 if (ssl->options.groupMessages)
ashleymills 0:714293de3836 4804 return 0;
ashleymills 0:714293de3836 4805 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 4806 else if (ssl->options.dtls) {
ashleymills 0:714293de3836 4807 /* If using DTLS, force the ChangeCipherSpec message to be in the
ashleymills 0:714293de3836 4808 * same datagram as the finished message. */
ashleymills 0:714293de3836 4809 return 0;
ashleymills 0:714293de3836 4810 }
ashleymills 0:714293de3836 4811 #endif
ashleymills 0:714293de3836 4812 else
ashleymills 0:714293de3836 4813 return SendBuffered(ssl);
ashleymills 0:714293de3836 4814 }
ashleymills 0:714293de3836 4815
ashleymills 0:714293de3836 4816
ashleymills 0:714293de3836 4817 static INLINE const byte* GetMacSecret(CYASSL* ssl, int verify)
ashleymills 0:714293de3836 4818 {
ashleymills 0:714293de3836 4819 if ( (ssl->options.side == CLIENT_END && !verify) ||
ashleymills 0:714293de3836 4820 (ssl->options.side == SERVER_END && verify) )
ashleymills 0:714293de3836 4821 return ssl->keys.client_write_MAC_secret;
ashleymills 0:714293de3836 4822 else
ashleymills 0:714293de3836 4823 return ssl->keys.server_write_MAC_secret;
ashleymills 0:714293de3836 4824 }
ashleymills 0:714293de3836 4825
ashleymills 0:714293de3836 4826 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 4827 static void Hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
ashleymills 0:714293de3836 4828 int content, int verify)
ashleymills 0:714293de3836 4829 {
ashleymills 0:714293de3836 4830 byte result[MAX_DIGEST_SIZE];
ashleymills 0:714293de3836 4831 word32 digestSz = ssl->specs.hash_size; /* actual sizes */
ashleymills 0:714293de3836 4832 word32 padSz = ssl->specs.pad_size;
ashleymills 0:714293de3836 4833
ashleymills 0:714293de3836 4834 Md5 md5;
ashleymills 0:714293de3836 4835 Sha sha;
ashleymills 0:714293de3836 4836
ashleymills 0:714293de3836 4837 /* data */
ashleymills 0:714293de3836 4838 byte seq[SEQ_SZ];
ashleymills 0:714293de3836 4839 byte conLen[ENUM_LEN + LENGTH_SZ]; /* content & length */
ashleymills 0:714293de3836 4840 const byte* macSecret = GetMacSecret(ssl, verify);
ashleymills 0:714293de3836 4841
ashleymills 0:714293de3836 4842 XMEMSET(seq, 0, SEQ_SZ);
ashleymills 0:714293de3836 4843 conLen[0] = (byte)content;
ashleymills 0:714293de3836 4844 c16toa((word16)sz, &conLen[ENUM_LEN]);
ashleymills 0:714293de3836 4845 c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]);
ashleymills 0:714293de3836 4846
ashleymills 0:714293de3836 4847 if (ssl->specs.mac_algorithm == md5_mac) {
ashleymills 0:714293de3836 4848 InitMd5(&md5);
ashleymills 0:714293de3836 4849 /* inner */
ashleymills 0:714293de3836 4850 Md5Update(&md5, macSecret, digestSz);
ashleymills 0:714293de3836 4851 Md5Update(&md5, PAD1, padSz);
ashleymills 0:714293de3836 4852 Md5Update(&md5, seq, SEQ_SZ);
ashleymills 0:714293de3836 4853 Md5Update(&md5, conLen, sizeof(conLen));
ashleymills 0:714293de3836 4854 /* in buffer */
ashleymills 0:714293de3836 4855 Md5Update(&md5, in, sz);
ashleymills 0:714293de3836 4856 Md5Final(&md5, result);
ashleymills 0:714293de3836 4857 /* outer */
ashleymills 0:714293de3836 4858 Md5Update(&md5, macSecret, digestSz);
ashleymills 0:714293de3836 4859 Md5Update(&md5, PAD2, padSz);
ashleymills 0:714293de3836 4860 Md5Update(&md5, result, digestSz);
ashleymills 0:714293de3836 4861 Md5Final(&md5, digest);
ashleymills 0:714293de3836 4862 }
ashleymills 0:714293de3836 4863 else {
ashleymills 0:714293de3836 4864 InitSha(&sha);
ashleymills 0:714293de3836 4865 /* inner */
ashleymills 0:714293de3836 4866 ShaUpdate(&sha, macSecret, digestSz);
ashleymills 0:714293de3836 4867 ShaUpdate(&sha, PAD1, padSz);
ashleymills 0:714293de3836 4868 ShaUpdate(&sha, seq, SEQ_SZ);
ashleymills 0:714293de3836 4869 ShaUpdate(&sha, conLen, sizeof(conLen));
ashleymills 0:714293de3836 4870 /* in buffer */
ashleymills 0:714293de3836 4871 ShaUpdate(&sha, in, sz);
ashleymills 0:714293de3836 4872 ShaFinal(&sha, result);
ashleymills 0:714293de3836 4873 /* outer */
ashleymills 0:714293de3836 4874 ShaUpdate(&sha, macSecret, digestSz);
ashleymills 0:714293de3836 4875 ShaUpdate(&sha, PAD2, padSz);
ashleymills 0:714293de3836 4876 ShaUpdate(&sha, result, digestSz);
ashleymills 0:714293de3836 4877 ShaFinal(&sha, digest);
ashleymills 0:714293de3836 4878 }
ashleymills 0:714293de3836 4879 }
ashleymills 0:714293de3836 4880
ashleymills 0:714293de3836 4881 #ifndef NO_CERTS
ashleymills 0:714293de3836 4882 static void BuildMD5_CertVerify(CYASSL* ssl, byte* digest)
ashleymills 0:714293de3836 4883 {
ashleymills 0:714293de3836 4884 byte md5_result[MD5_DIGEST_SIZE];
ashleymills 0:714293de3836 4885
ashleymills 0:714293de3836 4886 /* make md5 inner */
ashleymills 0:714293de3836 4887 Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:714293de3836 4888 Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
ashleymills 0:714293de3836 4889 Md5Final(&ssl->hashMd5, md5_result);
ashleymills 0:714293de3836 4890
ashleymills 0:714293de3836 4891 /* make md5 outer */
ashleymills 0:714293de3836 4892 Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:714293de3836 4893 Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
ashleymills 0:714293de3836 4894 Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
ashleymills 0:714293de3836 4895
ashleymills 0:714293de3836 4896 Md5Final(&ssl->hashMd5, digest);
ashleymills 0:714293de3836 4897 }
ashleymills 0:714293de3836 4898
ashleymills 0:714293de3836 4899
ashleymills 0:714293de3836 4900 static void BuildSHA_CertVerify(CYASSL* ssl, byte* digest)
ashleymills 0:714293de3836 4901 {
ashleymills 0:714293de3836 4902 byte sha_result[SHA_DIGEST_SIZE];
ashleymills 0:714293de3836 4903
ashleymills 0:714293de3836 4904 /* make sha inner */
ashleymills 0:714293de3836 4905 ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:714293de3836 4906 ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
ashleymills 0:714293de3836 4907 ShaFinal(&ssl->hashSha, sha_result);
ashleymills 0:714293de3836 4908
ashleymills 0:714293de3836 4909 /* make sha outer */
ashleymills 0:714293de3836 4910 ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:714293de3836 4911 ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
ashleymills 0:714293de3836 4912 ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
ashleymills 0:714293de3836 4913
ashleymills 0:714293de3836 4914 ShaFinal(&ssl->hashSha, digest);
ashleymills 0:714293de3836 4915 }
ashleymills 0:714293de3836 4916 #endif /* NO_CERTS */
ashleymills 0:714293de3836 4917 #endif /* NO_OLD_TLS */
ashleymills 0:714293de3836 4918
ashleymills 0:714293de3836 4919
ashleymills 0:714293de3836 4920 #ifndef NO_CERTS
ashleymills 0:714293de3836 4921
ashleymills 0:714293de3836 4922 static void BuildCertHashes(CYASSL* ssl, Hashes* hashes)
ashleymills 0:714293de3836 4923 {
ashleymills 0:714293de3836 4924 /* store current states, building requires get_digest which resets state */
ashleymills 0:714293de3836 4925 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 4926 Md5 md5 = ssl->hashMd5;
ashleymills 0:714293de3836 4927 Sha sha = ssl->hashSha;
ashleymills 0:714293de3836 4928 #endif
ashleymills 0:714293de3836 4929 #ifndef NO_SHA256
ashleymills 0:714293de3836 4930 Sha256 sha256 = ssl->hashSha256;
ashleymills 0:714293de3836 4931 #endif
ashleymills 0:714293de3836 4932 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 4933 Sha384 sha384 = ssl->hashSha384;
ashleymills 0:714293de3836 4934 #endif
ashleymills 0:714293de3836 4935
ashleymills 0:714293de3836 4936 if (ssl->options.tls) {
ashleymills 0:714293de3836 4937 #if ! defined( NO_OLD_TLS )
ashleymills 0:714293de3836 4938 Md5Final(&ssl->hashMd5, hashes->md5);
ashleymills 0:714293de3836 4939 ShaFinal(&ssl->hashSha, hashes->sha);
ashleymills 0:714293de3836 4940 #endif
ashleymills 0:714293de3836 4941 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 4942 #ifndef NO_SHA256
ashleymills 0:714293de3836 4943 Sha256Final(&ssl->hashSha256, hashes->sha256);
ashleymills 0:714293de3836 4944 #endif
ashleymills 0:714293de3836 4945 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 4946 Sha384Final(&ssl->hashSha384, hashes->sha384);
ashleymills 0:714293de3836 4947 #endif
ashleymills 0:714293de3836 4948 }
ashleymills 0:714293de3836 4949 }
ashleymills 0:714293de3836 4950 #if ! defined( NO_OLD_TLS )
ashleymills 0:714293de3836 4951 else {
ashleymills 0:714293de3836 4952 BuildMD5_CertVerify(ssl, hashes->md5);
ashleymills 0:714293de3836 4953 BuildSHA_CertVerify(ssl, hashes->sha);
ashleymills 0:714293de3836 4954 }
ashleymills 0:714293de3836 4955
ashleymills 0:714293de3836 4956 /* restore */
ashleymills 0:714293de3836 4957 ssl->hashMd5 = md5;
ashleymills 0:714293de3836 4958 ssl->hashSha = sha;
ashleymills 0:714293de3836 4959 #endif
ashleymills 0:714293de3836 4960 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 4961 #ifndef NO_SHA256
ashleymills 0:714293de3836 4962 ssl->hashSha256 = sha256;
ashleymills 0:714293de3836 4963 #endif
ashleymills 0:714293de3836 4964 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 4965 ssl->hashSha384 = sha384;
ashleymills 0:714293de3836 4966 #endif
ashleymills 0:714293de3836 4967 }
ashleymills 0:714293de3836 4968 }
ashleymills 0:714293de3836 4969
ashleymills 0:714293de3836 4970 #endif /* CYASSL_LEANPSK */
ashleymills 0:714293de3836 4971
ashleymills 0:714293de3836 4972 /* Build SSL Message, encrypted */
ashleymills 0:714293de3836 4973 static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz,
ashleymills 0:714293de3836 4974 int type)
ashleymills 0:714293de3836 4975 {
ashleymills 0:714293de3836 4976 word32 digestSz = ssl->specs.hash_size;
ashleymills 0:714293de3836 4977 word32 sz = RECORD_HEADER_SZ + inSz + digestSz;
ashleymills 0:714293de3836 4978 word32 pad = 0, i;
ashleymills 0:714293de3836 4979 word32 idx = RECORD_HEADER_SZ;
ashleymills 0:714293de3836 4980 word32 ivSz = 0; /* TLSv1.1 IV */
ashleymills 0:714293de3836 4981 word32 headerSz = RECORD_HEADER_SZ;
ashleymills 0:714293de3836 4982 word16 size;
ashleymills 0:714293de3836 4983 byte iv[AES_BLOCK_SIZE]; /* max size */
ashleymills 0:714293de3836 4984 int ret = 0;
ashleymills 0:714293de3836 4985
ashleymills 0:714293de3836 4986 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 4987 if (ssl->options.dtls) {
ashleymills 0:714293de3836 4988 sz += DTLS_RECORD_EXTRA;
ashleymills 0:714293de3836 4989 idx += DTLS_RECORD_EXTRA;
ashleymills 0:714293de3836 4990 headerSz += DTLS_RECORD_EXTRA;
ashleymills 0:714293de3836 4991 }
ashleymills 0:714293de3836 4992 #endif
ashleymills 0:714293de3836 4993
ashleymills 0:714293de3836 4994 if (ssl->specs.cipher_type == block) {
ashleymills 0:714293de3836 4995 word32 blockSz = ssl->specs.block_size;
ashleymills 0:714293de3836 4996 if (ssl->options.tls1_1) {
ashleymills 0:714293de3836 4997 ivSz = blockSz;
ashleymills 0:714293de3836 4998 sz += ivSz;
ashleymills 0:714293de3836 4999 RNG_GenerateBlock(ssl->rng, iv, ivSz);
ashleymills 0:714293de3836 5000 }
ashleymills 0:714293de3836 5001 sz += 1; /* pad byte */
ashleymills 0:714293de3836 5002 pad = (sz - headerSz) % blockSz;
ashleymills 0:714293de3836 5003 pad = blockSz - pad;
ashleymills 0:714293de3836 5004 sz += pad;
ashleymills 0:714293de3836 5005 }
ashleymills 0:714293de3836 5006
ashleymills 0:714293de3836 5007 #ifdef HAVE_AEAD
ashleymills 0:714293de3836 5008 if (ssl->specs.cipher_type == aead) {
ashleymills 0:714293de3836 5009 ivSz = AEAD_EXP_IV_SZ;
ashleymills 0:714293de3836 5010 sz += (ivSz + ssl->specs.aead_mac_size - digestSz);
ashleymills 0:714293de3836 5011 XMEMCPY(iv, ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
ashleymills 0:714293de3836 5012 }
ashleymills 0:714293de3836 5013 #endif
ashleymills 0:714293de3836 5014 size = (word16)(sz - headerSz); /* include mac and digest */
ashleymills 0:714293de3836 5015 AddRecordHeader(output, size, (byte)type, ssl);
ashleymills 0:714293de3836 5016
ashleymills 0:714293de3836 5017 /* write to output */
ashleymills 0:714293de3836 5018 if (ivSz) {
ashleymills 0:714293de3836 5019 XMEMCPY(output + idx, iv, min(ivSz, sizeof(iv)));
ashleymills 0:714293de3836 5020 idx += ivSz;
ashleymills 0:714293de3836 5021 }
ashleymills 0:714293de3836 5022 XMEMCPY(output + idx, input, inSz);
ashleymills 0:714293de3836 5023 idx += inSz;
ashleymills 0:714293de3836 5024
ashleymills 0:714293de3836 5025 if (type == handshake) {
ashleymills 0:714293de3836 5026 HashOutput(ssl, output, headerSz + inSz, ivSz);
ashleymills 0:714293de3836 5027 }
ashleymills 0:714293de3836 5028
ashleymills 0:714293de3836 5029 if (ssl->specs.cipher_type != aead) {
ashleymills 0:714293de3836 5030 ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz, type, 0);
ashleymills 0:714293de3836 5031 idx += digestSz;
ashleymills 0:714293de3836 5032 }
ashleymills 0:714293de3836 5033
ashleymills 0:714293de3836 5034 if (ssl->specs.cipher_type == block)
ashleymills 0:714293de3836 5035 for (i = 0; i <= pad; i++)
ashleymills 0:714293de3836 5036 output[idx++] = (byte)pad; /* pad byte gets pad value too */
ashleymills 0:714293de3836 5037
ashleymills 0:714293de3836 5038 if ( (ret = Encrypt(ssl, output + headerSz, output + headerSz, size)) != 0)
ashleymills 0:714293de3836 5039 return ret;
ashleymills 0:714293de3836 5040
ashleymills 0:714293de3836 5041 return sz;
ashleymills 0:714293de3836 5042 }
ashleymills 0:714293de3836 5043
ashleymills 0:714293de3836 5044
ashleymills 0:714293de3836 5045 int SendFinished(CYASSL* ssl)
ashleymills 0:714293de3836 5046 {
ashleymills 0:714293de3836 5047 int sendSz,
ashleymills 0:714293de3836 5048 finishedSz = ssl->options.tls ? TLS_FINISHED_SZ :
ashleymills 0:714293de3836 5049 FINISHED_SZ;
ashleymills 0:714293de3836 5050 byte input[FINISHED_SZ + DTLS_HANDSHAKE_HEADER_SZ]; /* max */
ashleymills 0:714293de3836 5051 byte *output;
ashleymills 0:714293de3836 5052 Hashes* hashes;
ashleymills 0:714293de3836 5053 int ret;
ashleymills 0:714293de3836 5054 int headerSz = HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 5055
ashleymills 0:714293de3836 5056 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 5057 word32 sequence_number = ssl->keys.dtls_sequence_number;
ashleymills 0:714293de3836 5058 word16 epoch = ssl->keys.dtls_epoch;
ashleymills 0:714293de3836 5059 #endif
ashleymills 0:714293de3836 5060
ashleymills 0:714293de3836 5061
ashleymills 0:714293de3836 5062 /* check for available size */
ashleymills 0:714293de3836 5063 if ((ret = CheckAvailableSize(ssl, sizeof(input) + MAX_MSG_EXTRA)) != 0)
ashleymills 0:714293de3836 5064 return ret;
ashleymills 0:714293de3836 5065
ashleymills 0:714293de3836 5066 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 5067 if (ssl->options.dtls) {
ashleymills 0:714293de3836 5068 /* Send Finished message with the next epoch, but don't commit that
ashleymills 0:714293de3836 5069 * change until the other end confirms its reception. */
ashleymills 0:714293de3836 5070 headerSz += DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 5071 ssl->keys.dtls_epoch++;
ashleymills 0:714293de3836 5072 ssl->keys.dtls_sequence_number = 0; /* reset after epoch change */
ashleymills 0:714293de3836 5073 }
ashleymills 0:714293de3836 5074 #endif
ashleymills 0:714293de3836 5075
ashleymills 0:714293de3836 5076 /* get ouput buffer */
ashleymills 0:714293de3836 5077 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 5078 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 5079
ashleymills 0:714293de3836 5080 AddHandShakeHeader(input, finishedSz, finished, ssl);
ashleymills 0:714293de3836 5081
ashleymills 0:714293de3836 5082 /* make finished hashes */
ashleymills 0:714293de3836 5083 hashes = (Hashes*)&input[headerSz];
ashleymills 0:714293de3836 5084 BuildFinished(ssl, hashes, ssl->options.side == CLIENT_END ? client :
ashleymills 0:714293de3836 5085 server);
ashleymills 0:714293de3836 5086
ashleymills 0:714293de3836 5087 sendSz = BuildMessage(ssl, output, input, headerSz + finishedSz, handshake);
ashleymills 0:714293de3836 5088
ashleymills 0:714293de3836 5089 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 5090 if (ssl->options.dtls) {
ashleymills 0:714293de3836 5091 ssl->keys.dtls_epoch = epoch;
ashleymills 0:714293de3836 5092 ssl->keys.dtls_sequence_number = sequence_number;
ashleymills 0:714293de3836 5093 }
ashleymills 0:714293de3836 5094 #endif
ashleymills 0:714293de3836 5095
ashleymills 0:714293de3836 5096 if (sendSz < 0)
ashleymills 0:714293de3836 5097 return BUILD_MSG_ERROR;
ashleymills 0:714293de3836 5098
ashleymills 0:714293de3836 5099 if (!ssl->options.resuming) {
ashleymills 0:714293de3836 5100 #ifndef NO_SESSION_CACHE
ashleymills 0:714293de3836 5101 AddSession(ssl); /* just try */
ashleymills 0:714293de3836 5102 #endif
ashleymills 0:714293de3836 5103 if (ssl->options.side == CLIENT_END) {
ashleymills 0:714293de3836 5104 BuildFinished(ssl, &ssl->verifyHashes, server);
ashleymills 0:714293de3836 5105 }
ashleymills 0:714293de3836 5106 else {
ashleymills 0:714293de3836 5107 ssl->options.handShakeState = HANDSHAKE_DONE;
ashleymills 0:714293de3836 5108 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 5109 if (ssl->options.dtls) {
ashleymills 0:714293de3836 5110 /* Other side will soon receive our Finished, go to next
ashleymills 0:714293de3836 5111 * epoch. */
ashleymills 0:714293de3836 5112 ssl->keys.dtls_epoch++;
ashleymills 0:714293de3836 5113 ssl->keys.dtls_sequence_number = 1;
ashleymills 0:714293de3836 5114 }
ashleymills 0:714293de3836 5115 #endif
ashleymills 0:714293de3836 5116 }
ashleymills 0:714293de3836 5117 }
ashleymills 0:714293de3836 5118 else {
ashleymills 0:714293de3836 5119 if (ssl->options.side == CLIENT_END) {
ashleymills 0:714293de3836 5120 ssl->options.handShakeState = HANDSHAKE_DONE;
ashleymills 0:714293de3836 5121 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 5122 if (ssl->options.dtls) {
ashleymills 0:714293de3836 5123 /* Other side will soon receive our Finished, go to next
ashleymills 0:714293de3836 5124 * epoch. */
ashleymills 0:714293de3836 5125 ssl->keys.dtls_epoch++;
ashleymills 0:714293de3836 5126 ssl->keys.dtls_sequence_number = 1;
ashleymills 0:714293de3836 5127 }
ashleymills 0:714293de3836 5128 #endif
ashleymills 0:714293de3836 5129 }
ashleymills 0:714293de3836 5130 else {
ashleymills 0:714293de3836 5131 BuildFinished(ssl, &ssl->verifyHashes, client);
ashleymills 0:714293de3836 5132 }
ashleymills 0:714293de3836 5133 }
ashleymills 0:714293de3836 5134 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 5135 if (ssl->options.dtls) {
ashleymills 0:714293de3836 5136 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:714293de3836 5137 return ret;
ashleymills 0:714293de3836 5138 }
ashleymills 0:714293de3836 5139 #endif
ashleymills 0:714293de3836 5140
ashleymills 0:714293de3836 5141 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 5142 if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
ashleymills 0:714293de3836 5143 if (ssl->toInfoOn)
ashleymills 0:714293de3836 5144 AddPacketInfo("Finished", &ssl->timeoutInfo, output, sendSz,
ashleymills 0:714293de3836 5145 ssl->heap);
ashleymills 0:714293de3836 5146 #endif
ashleymills 0:714293de3836 5147
ashleymills 0:714293de3836 5148 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:714293de3836 5149
ashleymills 0:714293de3836 5150 return SendBuffered(ssl);
ashleymills 0:714293de3836 5151 }
ashleymills 0:714293de3836 5152
ashleymills 0:714293de3836 5153 #ifndef NO_CERTS
ashleymills 0:714293de3836 5154 int SendCertificate(CYASSL* ssl)
ashleymills 0:714293de3836 5155 {
ashleymills 0:714293de3836 5156 int sendSz, length, ret = 0;
ashleymills 0:714293de3836 5157 word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 5158 word32 certSz, listSz;
ashleymills 0:714293de3836 5159 byte* output = 0;
ashleymills 0:714293de3836 5160
ashleymills 0:714293de3836 5161 if (ssl->options.usingPSK_cipher) return 0; /* not needed */
ashleymills 0:714293de3836 5162
ashleymills 0:714293de3836 5163 if (ssl->options.sendVerify == SEND_BLANK_CERT) {
ashleymills 0:714293de3836 5164 certSz = 0;
ashleymills 0:714293de3836 5165 length = CERT_HEADER_SZ;
ashleymills 0:714293de3836 5166 listSz = 0;
ashleymills 0:714293de3836 5167 }
ashleymills 0:714293de3836 5168 else {
ashleymills 0:714293de3836 5169 certSz = ssl->buffers.certificate.length;
ashleymills 0:714293de3836 5170 /* list + cert size */
ashleymills 0:714293de3836 5171 length = certSz + 2 * CERT_HEADER_SZ;
ashleymills 0:714293de3836 5172 listSz = certSz + CERT_HEADER_SZ;
ashleymills 0:714293de3836 5173
ashleymills 0:714293de3836 5174 /* may need to send rest of chain, already has leading size(s) */
ashleymills 0:714293de3836 5175 if (ssl->buffers.certChain.buffer) {
ashleymills 0:714293de3836 5176 length += ssl->buffers.certChain.length;
ashleymills 0:714293de3836 5177 listSz += ssl->buffers.certChain.length;
ashleymills 0:714293de3836 5178 }
ashleymills 0:714293de3836 5179 }
ashleymills 0:714293de3836 5180 sendSz = length + RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 5181
ashleymills 0:714293de3836 5182 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 5183 if (ssl->options.dtls) {
ashleymills 0:714293de3836 5184 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 5185 i += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 5186 }
ashleymills 0:714293de3836 5187 #endif
ashleymills 0:714293de3836 5188
ashleymills 0:714293de3836 5189 /* check for available size */
ashleymills 0:714293de3836 5190 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
ashleymills 0:714293de3836 5191 return ret;
ashleymills 0:714293de3836 5192
ashleymills 0:714293de3836 5193 /* get ouput buffer */
ashleymills 0:714293de3836 5194 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 5195 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 5196
ashleymills 0:714293de3836 5197 AddHeaders(output, length, certificate, ssl);
ashleymills 0:714293de3836 5198
ashleymills 0:714293de3836 5199 /* list total */
ashleymills 0:714293de3836 5200 c32to24(listSz, output + i);
ashleymills 0:714293de3836 5201 i += CERT_HEADER_SZ;
ashleymills 0:714293de3836 5202
ashleymills 0:714293de3836 5203 /* member */
ashleymills 0:714293de3836 5204 if (certSz) {
ashleymills 0:714293de3836 5205 c32to24(certSz, output + i);
ashleymills 0:714293de3836 5206 i += CERT_HEADER_SZ;
ashleymills 0:714293de3836 5207 XMEMCPY(output + i, ssl->buffers.certificate.buffer, certSz);
ashleymills 0:714293de3836 5208 i += certSz;
ashleymills 0:714293de3836 5209
ashleymills 0:714293de3836 5210 /* send rest of chain? */
ashleymills 0:714293de3836 5211 if (ssl->buffers.certChain.buffer) {
ashleymills 0:714293de3836 5212 XMEMCPY(output + i, ssl->buffers.certChain.buffer,
ashleymills 0:714293de3836 5213 ssl->buffers.certChain.length);
ashleymills 0:714293de3836 5214 /* if add more to output adjust i
ashleymills 0:714293de3836 5215 i += ssl->buffers.certChain.length; */
ashleymills 0:714293de3836 5216 }
ashleymills 0:714293de3836 5217 }
ashleymills 0:714293de3836 5218 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 5219 if (ssl->options.dtls) {
ashleymills 0:714293de3836 5220 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:714293de3836 5221 return ret;
ashleymills 0:714293de3836 5222 }
ashleymills 0:714293de3836 5223 #endif
ashleymills 0:714293de3836 5224 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:714293de3836 5225 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 5226 if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
ashleymills 0:714293de3836 5227 if (ssl->toInfoOn)
ashleymills 0:714293de3836 5228 AddPacketInfo("Certificate", &ssl->timeoutInfo, output, sendSz,
ashleymills 0:714293de3836 5229 ssl->heap);
ashleymills 0:714293de3836 5230 #endif
ashleymills 0:714293de3836 5231
ashleymills 0:714293de3836 5232 if (ssl->options.side == SERVER_END)
ashleymills 0:714293de3836 5233 ssl->options.serverState = SERVER_CERT_COMPLETE;
ashleymills 0:714293de3836 5234
ashleymills 0:714293de3836 5235 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:714293de3836 5236 if (ssl->options.groupMessages)
ashleymills 0:714293de3836 5237 return 0;
ashleymills 0:714293de3836 5238 else
ashleymills 0:714293de3836 5239 return SendBuffered(ssl);
ashleymills 0:714293de3836 5240 }
ashleymills 0:714293de3836 5241
ashleymills 0:714293de3836 5242
ashleymills 0:714293de3836 5243 int SendCertificateRequest(CYASSL* ssl)
ashleymills 0:714293de3836 5244 {
ashleymills 0:714293de3836 5245 byte *output;
ashleymills 0:714293de3836 5246 int ret;
ashleymills 0:714293de3836 5247 int sendSz;
ashleymills 0:714293de3836 5248 word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 5249
ashleymills 0:714293de3836 5250 int typeTotal = 1; /* only rsa for now */
ashleymills 0:714293de3836 5251 int reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ; /* add auth later */
ashleymills 0:714293de3836 5252
ashleymills 0:714293de3836 5253 if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:714293de3836 5254 reqSz += LENGTH_SZ + ssl->suites->hashSigAlgoSz;
ashleymills 0:714293de3836 5255
ashleymills 0:714293de3836 5256 if (ssl->options.usingPSK_cipher) return 0; /* not needed */
ashleymills 0:714293de3836 5257
ashleymills 0:714293de3836 5258 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
ashleymills 0:714293de3836 5259
ashleymills 0:714293de3836 5260 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 5261 if (ssl->options.dtls) {
ashleymills 0:714293de3836 5262 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 5263 i += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 5264 }
ashleymills 0:714293de3836 5265 #endif
ashleymills 0:714293de3836 5266 /* check for available size */
ashleymills 0:714293de3836 5267 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
ashleymills 0:714293de3836 5268 return ret;
ashleymills 0:714293de3836 5269
ashleymills 0:714293de3836 5270 /* get ouput buffer */
ashleymills 0:714293de3836 5271 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 5272 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 5273
ashleymills 0:714293de3836 5274 AddHeaders(output, reqSz, certificate_request, ssl);
ashleymills 0:714293de3836 5275
ashleymills 0:714293de3836 5276 /* write to output */
ashleymills 0:714293de3836 5277 output[i++] = (byte)typeTotal; /* # of types */
ashleymills 0:714293de3836 5278 output[i++] = rsa_sign;
ashleymills 0:714293de3836 5279
ashleymills 0:714293de3836 5280 /* supported hash/sig */
ashleymills 0:714293de3836 5281 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 5282 c16toa(ssl->suites->hashSigAlgoSz, &output[i]);
ashleymills 0:714293de3836 5283 i += LENGTH_SZ;
ashleymills 0:714293de3836 5284
ashleymills 0:714293de3836 5285 XMEMCPY(&output[i],
ashleymills 0:714293de3836 5286 ssl->suites->hashSigAlgo, ssl->suites->hashSigAlgoSz);
ashleymills 0:714293de3836 5287 i += ssl->suites->hashSigAlgoSz;
ashleymills 0:714293de3836 5288 }
ashleymills 0:714293de3836 5289
ashleymills 0:714293de3836 5290 c16toa(0, &output[i]); /* auth's */
ashleymills 0:714293de3836 5291 /* if add more to output, adjust i
ashleymills 0:714293de3836 5292 i += REQ_HEADER_SZ; */
ashleymills 0:714293de3836 5293
ashleymills 0:714293de3836 5294 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 5295 if (ssl->options.dtls) {
ashleymills 0:714293de3836 5296 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:714293de3836 5297 return ret;
ashleymills 0:714293de3836 5298 }
ashleymills 0:714293de3836 5299 #endif
ashleymills 0:714293de3836 5300 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:714293de3836 5301
ashleymills 0:714293de3836 5302 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 5303 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 5304 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
ashleymills 0:714293de3836 5305 if (ssl->toInfoOn)
ashleymills 0:714293de3836 5306 AddPacketInfo("CertificateRequest", &ssl->timeoutInfo, output,
ashleymills 0:714293de3836 5307 sendSz, ssl->heap);
ashleymills 0:714293de3836 5308 #endif
ashleymills 0:714293de3836 5309 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:714293de3836 5310 if (ssl->options.groupMessages)
ashleymills 0:714293de3836 5311 return 0;
ashleymills 0:714293de3836 5312 else
ashleymills 0:714293de3836 5313 return SendBuffered(ssl);
ashleymills 0:714293de3836 5314 }
ashleymills 0:714293de3836 5315 #endif /* !NO_CERTS */
ashleymills 0:714293de3836 5316
ashleymills 0:714293de3836 5317
ashleymills 0:714293de3836 5318 int SendData(CYASSL* ssl, const void* data, int sz)
ashleymills 0:714293de3836 5319 {
ashleymills 0:714293de3836 5320 int sent = 0, /* plainText size */
ashleymills 0:714293de3836 5321 sendSz,
ashleymills 0:714293de3836 5322 ret;
ashleymills 0:714293de3836 5323
ashleymills 0:714293de3836 5324 if (ssl->error == WANT_WRITE)
ashleymills 0:714293de3836 5325 ssl->error = 0;
ashleymills 0:714293de3836 5326
ashleymills 0:714293de3836 5327 if (ssl->options.handShakeState != HANDSHAKE_DONE) {
ashleymills 0:714293de3836 5328 int err;
ashleymills 0:714293de3836 5329 CYASSL_MSG("handshake not complete, trying to finish");
ashleymills 0:714293de3836 5330 if ( (err = CyaSSL_negotiate(ssl)) != SSL_SUCCESS)
ashleymills 0:714293de3836 5331 return err;
ashleymills 0:714293de3836 5332 }
ashleymills 0:714293de3836 5333
ashleymills 0:714293de3836 5334 /* last time system socket output buffer was full, try again to send */
ashleymills 0:714293de3836 5335 if (ssl->buffers.outputBuffer.length > 0) {
ashleymills 0:714293de3836 5336 CYASSL_MSG("output buffer was full, trying to send again");
ashleymills 0:714293de3836 5337 if ( (ssl->error = SendBuffered(ssl)) < 0) {
ashleymills 0:714293de3836 5338 CYASSL_ERROR(ssl->error);
ashleymills 0:714293de3836 5339 if (ssl->error == SOCKET_ERROR_E && ssl->options.connReset)
ashleymills 0:714293de3836 5340 return 0; /* peer reset */
ashleymills 0:714293de3836 5341 return ssl->error;
ashleymills 0:714293de3836 5342 }
ashleymills 0:714293de3836 5343 else {
ashleymills 0:714293de3836 5344 /* advance sent to previous sent + plain size just sent */
ashleymills 0:714293de3836 5345 sent = ssl->buffers.prevSent + ssl->buffers.plainSz;
ashleymills 0:714293de3836 5346 CYASSL_MSG("sent write buffered data");
ashleymills 0:714293de3836 5347 }
ashleymills 0:714293de3836 5348 }
ashleymills 0:714293de3836 5349
ashleymills 0:714293de3836 5350 for (;;) {
ashleymills 0:714293de3836 5351 int len = min(sz - sent, OUTPUT_RECORD_SIZE);
ashleymills 0:714293de3836 5352 byte* out;
ashleymills 0:714293de3836 5353 byte* sendBuffer = (byte*)data + sent; /* may switch on comp */
ashleymills 0:714293de3836 5354 int buffSz = len; /* may switch on comp */
ashleymills 0:714293de3836 5355 #ifdef HAVE_LIBZ
ashleymills 0:714293de3836 5356 byte comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
ashleymills 0:714293de3836 5357 #endif
ashleymills 0:714293de3836 5358
ashleymills 0:714293de3836 5359 if (sent == sz) break;
ashleymills 0:714293de3836 5360
ashleymills 0:714293de3836 5361 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 5362 if (ssl->options.dtls) {
ashleymills 0:714293de3836 5363 len = min(len, MAX_UDP_SIZE);
ashleymills 0:714293de3836 5364 buffSz = len;
ashleymills 0:714293de3836 5365 }
ashleymills 0:714293de3836 5366 #endif
ashleymills 0:714293de3836 5367
ashleymills 0:714293de3836 5368 /* check for available size */
ashleymills 0:714293de3836 5369 if ((ret = CheckAvailableSize(ssl, len + COMP_EXTRA +
ashleymills 0:714293de3836 5370 MAX_MSG_EXTRA)) != 0)
ashleymills 0:714293de3836 5371 return ssl->error = ret;
ashleymills 0:714293de3836 5372
ashleymills 0:714293de3836 5373 /* get ouput buffer */
ashleymills 0:714293de3836 5374 out = ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 5375 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 5376
ashleymills 0:714293de3836 5377 #ifdef HAVE_LIBZ
ashleymills 0:714293de3836 5378 if (ssl->options.usingCompression) {
ashleymills 0:714293de3836 5379 buffSz = myCompress(ssl, sendBuffer, buffSz, comp, sizeof(comp));
ashleymills 0:714293de3836 5380 if (buffSz < 0) {
ashleymills 0:714293de3836 5381 return buffSz;
ashleymills 0:714293de3836 5382 }
ashleymills 0:714293de3836 5383 sendBuffer = comp;
ashleymills 0:714293de3836 5384 }
ashleymills 0:714293de3836 5385 #endif
ashleymills 0:714293de3836 5386 sendSz = BuildMessage(ssl, out, sendBuffer, buffSz,
ashleymills 0:714293de3836 5387 application_data);
ashleymills 0:714293de3836 5388
ashleymills 0:714293de3836 5389 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:714293de3836 5390
ashleymills 0:714293de3836 5391 if ( (ret = SendBuffered(ssl)) < 0) {
ashleymills 0:714293de3836 5392 CYASSL_ERROR(ret);
ashleymills 0:714293de3836 5393 /* store for next call if WANT_WRITE or user embedSend() that
ashleymills 0:714293de3836 5394 doesn't present like WANT_WRITE */
ashleymills 0:714293de3836 5395 ssl->buffers.plainSz = len;
ashleymills 0:714293de3836 5396 ssl->buffers.prevSent = sent;
ashleymills 0:714293de3836 5397 if (ret == SOCKET_ERROR_E && ssl->options.connReset)
ashleymills 0:714293de3836 5398 return 0; /* peer reset */
ashleymills 0:714293de3836 5399 return ssl->error = ret;
ashleymills 0:714293de3836 5400 }
ashleymills 0:714293de3836 5401
ashleymills 0:714293de3836 5402 sent += len;
ashleymills 0:714293de3836 5403
ashleymills 0:714293de3836 5404 /* only one message per attempt */
ashleymills 0:714293de3836 5405 if (ssl->options.partialWrite == 1) {
ashleymills 0:714293de3836 5406 CYASSL_MSG("Paritial Write on, only sending one record");
ashleymills 0:714293de3836 5407 break;
ashleymills 0:714293de3836 5408 }
ashleymills 0:714293de3836 5409 }
ashleymills 0:714293de3836 5410
ashleymills 0:714293de3836 5411 return sent;
ashleymills 0:714293de3836 5412 }
ashleymills 0:714293de3836 5413
ashleymills 0:714293de3836 5414 /* process input data */
ashleymills 0:714293de3836 5415 int ReceiveData(CYASSL* ssl, byte* output, int sz, int peek)
ashleymills 0:714293de3836 5416 {
ashleymills 0:714293de3836 5417 int size;
ashleymills 0:714293de3836 5418
ashleymills 0:714293de3836 5419 CYASSL_ENTER("ReceiveData()");
ashleymills 0:714293de3836 5420
ashleymills 0:714293de3836 5421 if (ssl->error == WANT_READ)
ashleymills 0:714293de3836 5422 ssl->error = 0;
ashleymills 0:714293de3836 5423
ashleymills 0:714293de3836 5424 if (ssl->options.handShakeState != HANDSHAKE_DONE) {
ashleymills 0:714293de3836 5425 int err;
ashleymills 0:714293de3836 5426 CYASSL_MSG("Handshake not complete, trying to finish");
ashleymills 0:714293de3836 5427 if ( (err = CyaSSL_negotiate(ssl)) != SSL_SUCCESS)
ashleymills 0:714293de3836 5428 return err;
ashleymills 0:714293de3836 5429 }
ashleymills 0:714293de3836 5430
ashleymills 0:714293de3836 5431 while (ssl->buffers.clearOutputBuffer.length == 0)
ashleymills 0:714293de3836 5432 if ( (ssl->error = ProcessReply(ssl)) < 0) {
ashleymills 0:714293de3836 5433 CYASSL_ERROR(ssl->error);
ashleymills 0:714293de3836 5434 if (ssl->error == ZERO_RETURN) {
ashleymills 0:714293de3836 5435 CYASSL_MSG("Zero return, no more data coming");
ashleymills 0:714293de3836 5436 return 0; /* no more data coming */
ashleymills 0:714293de3836 5437 }
ashleymills 0:714293de3836 5438 if (ssl->error == SOCKET_ERROR_E) {
ashleymills 0:714293de3836 5439 if (ssl->options.connReset || ssl->options.isClosed) {
ashleymills 0:714293de3836 5440 CYASSL_MSG("Peer reset or closed, connection done");
ashleymills 0:714293de3836 5441 return 0; /* peer reset or closed */
ashleymills 0:714293de3836 5442 }
ashleymills 0:714293de3836 5443 }
ashleymills 0:714293de3836 5444 return ssl->error;
ashleymills 0:714293de3836 5445 }
ashleymills 0:714293de3836 5446
ashleymills 0:714293de3836 5447 if (sz < (int)ssl->buffers.clearOutputBuffer.length)
ashleymills 0:714293de3836 5448 size = sz;
ashleymills 0:714293de3836 5449 else
ashleymills 0:714293de3836 5450 size = ssl->buffers.clearOutputBuffer.length;
ashleymills 0:714293de3836 5451
ashleymills 0:714293de3836 5452 XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size);
ashleymills 0:714293de3836 5453
ashleymills 0:714293de3836 5454 if (peek == 0) {
ashleymills 0:714293de3836 5455 ssl->buffers.clearOutputBuffer.length -= size;
ashleymills 0:714293de3836 5456 ssl->buffers.clearOutputBuffer.buffer += size;
ashleymills 0:714293de3836 5457 }
ashleymills 0:714293de3836 5458
ashleymills 0:714293de3836 5459 if (ssl->buffers.clearOutputBuffer.length == 0 &&
ashleymills 0:714293de3836 5460 ssl->buffers.inputBuffer.dynamicFlag)
ashleymills 0:714293de3836 5461 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
ashleymills 0:714293de3836 5462
ashleymills 0:714293de3836 5463 CYASSL_LEAVE("ReceiveData()", size);
ashleymills 0:714293de3836 5464 return size;
ashleymills 0:714293de3836 5465 }
ashleymills 0:714293de3836 5466
ashleymills 0:714293de3836 5467
ashleymills 0:714293de3836 5468 /* send alert message */
ashleymills 0:714293de3836 5469 int SendAlert(CYASSL* ssl, int severity, int type)
ashleymills 0:714293de3836 5470 {
ashleymills 0:714293de3836 5471 byte input[ALERT_SIZE];
ashleymills 0:714293de3836 5472 byte *output;
ashleymills 0:714293de3836 5473 int sendSz;
ashleymills 0:714293de3836 5474 int ret;
ashleymills 0:714293de3836 5475 int dtlsExtra = 0;
ashleymills 0:714293de3836 5476
ashleymills 0:714293de3836 5477 /* if sendalert is called again for nonbloking */
ashleymills 0:714293de3836 5478 if (ssl->options.sendAlertState != 0) {
ashleymills 0:714293de3836 5479 ret = SendBuffered(ssl);
ashleymills 0:714293de3836 5480 if (ret == 0)
ashleymills 0:714293de3836 5481 ssl->options.sendAlertState = 0;
ashleymills 0:714293de3836 5482 return ret;
ashleymills 0:714293de3836 5483 }
ashleymills 0:714293de3836 5484
ashleymills 0:714293de3836 5485 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 5486 if (ssl->options.dtls)
ashleymills 0:714293de3836 5487 dtlsExtra = DTLS_RECORD_EXTRA;
ashleymills 0:714293de3836 5488 #endif
ashleymills 0:714293de3836 5489
ashleymills 0:714293de3836 5490 /* check for available size */
ashleymills 0:714293de3836 5491 if ((ret = CheckAvailableSize(ssl,
ashleymills 0:714293de3836 5492 ALERT_SIZE + MAX_MSG_EXTRA + dtlsExtra)) != 0)
ashleymills 0:714293de3836 5493 return ret;
ashleymills 0:714293de3836 5494
ashleymills 0:714293de3836 5495 /* get ouput buffer */
ashleymills 0:714293de3836 5496 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 5497 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 5498
ashleymills 0:714293de3836 5499 input[0] = (byte)severity;
ashleymills 0:714293de3836 5500 input[1] = (byte)type;
ashleymills 0:714293de3836 5501 ssl->alert_history.last_tx.code = type;
ashleymills 0:714293de3836 5502 ssl->alert_history.last_tx.level = severity;
ashleymills 0:714293de3836 5503 if (severity == alert_fatal) {
ashleymills 0:714293de3836 5504 ssl->options.isClosed = 1; /* Don't send close_notify */
ashleymills 0:714293de3836 5505 }
ashleymills 0:714293de3836 5506
ashleymills 0:714293de3836 5507 /* only send encrypted alert if handshake actually complete, otherwise
ashleymills 0:714293de3836 5508 other side may not be able to handle it */
ashleymills 0:714293de3836 5509 if (ssl->keys.encryptionOn && ssl->options.handShakeState == HANDSHAKE_DONE)
ashleymills 0:714293de3836 5510 sendSz = BuildMessage(ssl, output, input, ALERT_SIZE, alert);
ashleymills 0:714293de3836 5511 else {
ashleymills 0:714293de3836 5512
ashleymills 0:714293de3836 5513 AddRecordHeader(output, ALERT_SIZE, alert, ssl);
ashleymills 0:714293de3836 5514 output += RECORD_HEADER_SZ;
ashleymills 0:714293de3836 5515 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 5516 if (ssl->options.dtls)
ashleymills 0:714293de3836 5517 output += DTLS_RECORD_EXTRA;
ashleymills 0:714293de3836 5518 #endif
ashleymills 0:714293de3836 5519 XMEMCPY(output, input, ALERT_SIZE);
ashleymills 0:714293de3836 5520
ashleymills 0:714293de3836 5521 sendSz = RECORD_HEADER_SZ + ALERT_SIZE;
ashleymills 0:714293de3836 5522 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 5523 if (ssl->options.dtls)
ashleymills 0:714293de3836 5524 sendSz += DTLS_RECORD_EXTRA;
ashleymills 0:714293de3836 5525 #endif
ashleymills 0:714293de3836 5526 }
ashleymills 0:714293de3836 5527
ashleymills 0:714293de3836 5528 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 5529 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 5530 AddPacketName("Alert", &ssl->handShakeInfo);
ashleymills 0:714293de3836 5531 if (ssl->toInfoOn)
ashleymills 0:714293de3836 5532 AddPacketInfo("Alert", &ssl->timeoutInfo, output, sendSz,ssl->heap);
ashleymills 0:714293de3836 5533 #endif
ashleymills 0:714293de3836 5534
ashleymills 0:714293de3836 5535 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:714293de3836 5536 ssl->options.sendAlertState = 1;
ashleymills 0:714293de3836 5537
ashleymills 0:714293de3836 5538 return SendBuffered(ssl);
ashleymills 0:714293de3836 5539 }
ashleymills 0:714293de3836 5540
ashleymills 0:714293de3836 5541
ashleymills 0:714293de3836 5542
ashleymills 0:714293de3836 5543 void SetErrorString(int error, char* str)
ashleymills 0:714293de3836 5544 {
ashleymills 0:714293de3836 5545 const int max = MAX_ERROR_SZ; /* shorthand */
ashleymills 0:714293de3836 5546
ashleymills 0:714293de3836 5547 #ifdef NO_ERROR_STRINGS
ashleymills 0:714293de3836 5548
ashleymills 0:714293de3836 5549 (void)error;
ashleymills 0:714293de3836 5550 XSTRNCPY(str, "no support for error strings built in", max);
ashleymills 0:714293de3836 5551
ashleymills 0:714293de3836 5552 #else
ashleymills 0:714293de3836 5553
ashleymills 0:714293de3836 5554 /* pass to CTaoCrypt */
ashleymills 0:714293de3836 5555 if (error < MAX_CODE_E && error > MIN_CODE_E) {
ashleymills 0:714293de3836 5556 CTaoCryptErrorString(error, str);
ashleymills 0:714293de3836 5557 return;
ashleymills 0:714293de3836 5558 }
ashleymills 0:714293de3836 5559
ashleymills 0:714293de3836 5560 switch (error) {
ashleymills 0:714293de3836 5561
ashleymills 0:714293de3836 5562 case UNSUPPORTED_SUITE :
ashleymills 0:714293de3836 5563 XSTRNCPY(str, "unsupported cipher suite", max);
ashleymills 0:714293de3836 5564 break;
ashleymills 0:714293de3836 5565
ashleymills 0:714293de3836 5566 case INPUT_CASE_ERROR :
ashleymills 0:714293de3836 5567 XSTRNCPY(str, "input state error", max);
ashleymills 0:714293de3836 5568 break;
ashleymills 0:714293de3836 5569
ashleymills 0:714293de3836 5570 case PREFIX_ERROR :
ashleymills 0:714293de3836 5571 XSTRNCPY(str, "bad index to key rounds", max);
ashleymills 0:714293de3836 5572 break;
ashleymills 0:714293de3836 5573
ashleymills 0:714293de3836 5574 case MEMORY_ERROR :
ashleymills 0:714293de3836 5575 XSTRNCPY(str, "out of memory", max);
ashleymills 0:714293de3836 5576 break;
ashleymills 0:714293de3836 5577
ashleymills 0:714293de3836 5578 case VERIFY_FINISHED_ERROR :
ashleymills 0:714293de3836 5579 XSTRNCPY(str, "verify problem on finished", max);
ashleymills 0:714293de3836 5580 break;
ashleymills 0:714293de3836 5581
ashleymills 0:714293de3836 5582 case VERIFY_MAC_ERROR :
ashleymills 0:714293de3836 5583 XSTRNCPY(str, "verify mac problem", max);
ashleymills 0:714293de3836 5584 break;
ashleymills 0:714293de3836 5585
ashleymills 0:714293de3836 5586 case PARSE_ERROR :
ashleymills 0:714293de3836 5587 XSTRNCPY(str, "parse error on header", max);
ashleymills 0:714293de3836 5588 break;
ashleymills 0:714293de3836 5589
ashleymills 0:714293de3836 5590 case SIDE_ERROR :
ashleymills 0:714293de3836 5591 XSTRNCPY(str, "wrong client/server type", max);
ashleymills 0:714293de3836 5592 break;
ashleymills 0:714293de3836 5593
ashleymills 0:714293de3836 5594 case NO_PEER_CERT :
ashleymills 0:714293de3836 5595 XSTRNCPY(str, "peer didn't send cert", max);
ashleymills 0:714293de3836 5596 break;
ashleymills 0:714293de3836 5597
ashleymills 0:714293de3836 5598 case UNKNOWN_HANDSHAKE_TYPE :
ashleymills 0:714293de3836 5599 XSTRNCPY(str, "weird handshake type", max);
ashleymills 0:714293de3836 5600 break;
ashleymills 0:714293de3836 5601
ashleymills 0:714293de3836 5602 case SOCKET_ERROR_E :
ashleymills 0:714293de3836 5603 XSTRNCPY(str, "error state on socket", max);
ashleymills 0:714293de3836 5604 break;
ashleymills 0:714293de3836 5605
ashleymills 0:714293de3836 5606 case SOCKET_NODATA :
ashleymills 0:714293de3836 5607 XSTRNCPY(str, "expected data, not there", max);
ashleymills 0:714293de3836 5608 break;
ashleymills 0:714293de3836 5609
ashleymills 0:714293de3836 5610 case INCOMPLETE_DATA :
ashleymills 0:714293de3836 5611 XSTRNCPY(str, "don't have enough data to complete task", max);
ashleymills 0:714293de3836 5612 break;
ashleymills 0:714293de3836 5613
ashleymills 0:714293de3836 5614 case UNKNOWN_RECORD_TYPE :
ashleymills 0:714293de3836 5615 XSTRNCPY(str, "unknown type in record hdr", max);
ashleymills 0:714293de3836 5616 break;
ashleymills 0:714293de3836 5617
ashleymills 0:714293de3836 5618 case DECRYPT_ERROR :
ashleymills 0:714293de3836 5619 XSTRNCPY(str, "error during decryption", max);
ashleymills 0:714293de3836 5620 break;
ashleymills 0:714293de3836 5621
ashleymills 0:714293de3836 5622 case FATAL_ERROR :
ashleymills 0:714293de3836 5623 XSTRNCPY(str, "revcd alert fatal error", max);
ashleymills 0:714293de3836 5624 break;
ashleymills 0:714293de3836 5625
ashleymills 0:714293de3836 5626 case ENCRYPT_ERROR :
ashleymills 0:714293de3836 5627 XSTRNCPY(str, "error during encryption", max);
ashleymills 0:714293de3836 5628 break;
ashleymills 0:714293de3836 5629
ashleymills 0:714293de3836 5630 case FREAD_ERROR :
ashleymills 0:714293de3836 5631 XSTRNCPY(str, "fread problem", max);
ashleymills 0:714293de3836 5632 break;
ashleymills 0:714293de3836 5633
ashleymills 0:714293de3836 5634 case NO_PEER_KEY :
ashleymills 0:714293de3836 5635 XSTRNCPY(str, "need peer's key", max);
ashleymills 0:714293de3836 5636 break;
ashleymills 0:714293de3836 5637
ashleymills 0:714293de3836 5638 case NO_PRIVATE_KEY :
ashleymills 0:714293de3836 5639 XSTRNCPY(str, "need the private key", max);
ashleymills 0:714293de3836 5640 break;
ashleymills 0:714293de3836 5641
ashleymills 0:714293de3836 5642 case NO_DH_PARAMS :
ashleymills 0:714293de3836 5643 XSTRNCPY(str, "server missing DH params", max);
ashleymills 0:714293de3836 5644 break;
ashleymills 0:714293de3836 5645
ashleymills 0:714293de3836 5646 case RSA_PRIVATE_ERROR :
ashleymills 0:714293de3836 5647 XSTRNCPY(str, "error during rsa priv op", max);
ashleymills 0:714293de3836 5648 break;
ashleymills 0:714293de3836 5649
ashleymills 0:714293de3836 5650 case MATCH_SUITE_ERROR :
ashleymills 0:714293de3836 5651 XSTRNCPY(str, "can't match cipher suite", max);
ashleymills 0:714293de3836 5652 break;
ashleymills 0:714293de3836 5653
ashleymills 0:714293de3836 5654 case BUILD_MSG_ERROR :
ashleymills 0:714293de3836 5655 XSTRNCPY(str, "build message failure", max);
ashleymills 0:714293de3836 5656 break;
ashleymills 0:714293de3836 5657
ashleymills 0:714293de3836 5658 case BAD_HELLO :
ashleymills 0:714293de3836 5659 XSTRNCPY(str, "client hello malformed", max);
ashleymills 0:714293de3836 5660 break;
ashleymills 0:714293de3836 5661
ashleymills 0:714293de3836 5662 case DOMAIN_NAME_MISMATCH :
ashleymills 0:714293de3836 5663 XSTRNCPY(str, "peer subject name mismatch", max);
ashleymills 0:714293de3836 5664 break;
ashleymills 0:714293de3836 5665
ashleymills 0:714293de3836 5666 case WANT_READ :
ashleymills 0:714293de3836 5667 case SSL_ERROR_WANT_READ :
ashleymills 0:714293de3836 5668 XSTRNCPY(str, "non-blocking socket wants data to be read", max);
ashleymills 0:714293de3836 5669 break;
ashleymills 0:714293de3836 5670
ashleymills 0:714293de3836 5671 case NOT_READY_ERROR :
ashleymills 0:714293de3836 5672 XSTRNCPY(str, "handshake layer not ready yet, complete first", max);
ashleymills 0:714293de3836 5673 break;
ashleymills 0:714293de3836 5674
ashleymills 0:714293de3836 5675 case PMS_VERSION_ERROR :
ashleymills 0:714293de3836 5676 XSTRNCPY(str, "premaster secret version mismatch error", max);
ashleymills 0:714293de3836 5677 break;
ashleymills 0:714293de3836 5678
ashleymills 0:714293de3836 5679 case VERSION_ERROR :
ashleymills 0:714293de3836 5680 XSTRNCPY(str, "record layer version error", max);
ashleymills 0:714293de3836 5681 break;
ashleymills 0:714293de3836 5682
ashleymills 0:714293de3836 5683 case WANT_WRITE :
ashleymills 0:714293de3836 5684 case SSL_ERROR_WANT_WRITE :
ashleymills 0:714293de3836 5685 XSTRNCPY(str, "non-blocking socket write buffer full", max);
ashleymills 0:714293de3836 5686 break;
ashleymills 0:714293de3836 5687
ashleymills 0:714293de3836 5688 case BUFFER_ERROR :
ashleymills 0:714293de3836 5689 XSTRNCPY(str, "malformed buffer input error", max);
ashleymills 0:714293de3836 5690 break;
ashleymills 0:714293de3836 5691
ashleymills 0:714293de3836 5692 case VERIFY_CERT_ERROR :
ashleymills 0:714293de3836 5693 XSTRNCPY(str, "verify problem on certificate", max);
ashleymills 0:714293de3836 5694 break;
ashleymills 0:714293de3836 5695
ashleymills 0:714293de3836 5696 case VERIFY_SIGN_ERROR :
ashleymills 0:714293de3836 5697 XSTRNCPY(str, "verify problem based on signature", max);
ashleymills 0:714293de3836 5698 break;
ashleymills 0:714293de3836 5699
ashleymills 0:714293de3836 5700 case CLIENT_ID_ERROR :
ashleymills 0:714293de3836 5701 XSTRNCPY(str, "psk client identity error", max);
ashleymills 0:714293de3836 5702 break;
ashleymills 0:714293de3836 5703
ashleymills 0:714293de3836 5704 case SERVER_HINT_ERROR:
ashleymills 0:714293de3836 5705 XSTRNCPY(str, "psk server hint error", max);
ashleymills 0:714293de3836 5706 break;
ashleymills 0:714293de3836 5707
ashleymills 0:714293de3836 5708 case PSK_KEY_ERROR:
ashleymills 0:714293de3836 5709 XSTRNCPY(str, "psk key callback error", max);
ashleymills 0:714293de3836 5710 break;
ashleymills 0:714293de3836 5711
ashleymills 0:714293de3836 5712 case NTRU_KEY_ERROR:
ashleymills 0:714293de3836 5713 XSTRNCPY(str, "NTRU key error", max);
ashleymills 0:714293de3836 5714 break;
ashleymills 0:714293de3836 5715
ashleymills 0:714293de3836 5716 case NTRU_DRBG_ERROR:
ashleymills 0:714293de3836 5717 XSTRNCPY(str, "NTRU drbg error", max);
ashleymills 0:714293de3836 5718 break;
ashleymills 0:714293de3836 5719
ashleymills 0:714293de3836 5720 case NTRU_ENCRYPT_ERROR:
ashleymills 0:714293de3836 5721 XSTRNCPY(str, "NTRU encrypt error", max);
ashleymills 0:714293de3836 5722 break;
ashleymills 0:714293de3836 5723
ashleymills 0:714293de3836 5724 case NTRU_DECRYPT_ERROR:
ashleymills 0:714293de3836 5725 XSTRNCPY(str, "NTRU decrypt error", max);
ashleymills 0:714293de3836 5726 break;
ashleymills 0:714293de3836 5727
ashleymills 0:714293de3836 5728 case ZLIB_INIT_ERROR:
ashleymills 0:714293de3836 5729 XSTRNCPY(str, "zlib init error", max);
ashleymills 0:714293de3836 5730 break;
ashleymills 0:714293de3836 5731
ashleymills 0:714293de3836 5732 case ZLIB_COMPRESS_ERROR:
ashleymills 0:714293de3836 5733 XSTRNCPY(str, "zlib compress error", max);
ashleymills 0:714293de3836 5734 break;
ashleymills 0:714293de3836 5735
ashleymills 0:714293de3836 5736 case ZLIB_DECOMPRESS_ERROR:
ashleymills 0:714293de3836 5737 XSTRNCPY(str, "zlib decompress error", max);
ashleymills 0:714293de3836 5738 break;
ashleymills 0:714293de3836 5739
ashleymills 0:714293de3836 5740 case GETTIME_ERROR:
ashleymills 0:714293de3836 5741 XSTRNCPY(str, "gettimeofday() error", max);
ashleymills 0:714293de3836 5742 break;
ashleymills 0:714293de3836 5743
ashleymills 0:714293de3836 5744 case GETITIMER_ERROR:
ashleymills 0:714293de3836 5745 XSTRNCPY(str, "getitimer() error", max);
ashleymills 0:714293de3836 5746 break;
ashleymills 0:714293de3836 5747
ashleymills 0:714293de3836 5748 case SIGACT_ERROR:
ashleymills 0:714293de3836 5749 XSTRNCPY(str, "sigaction() error", max);
ashleymills 0:714293de3836 5750 break;
ashleymills 0:714293de3836 5751
ashleymills 0:714293de3836 5752 case SETITIMER_ERROR:
ashleymills 0:714293de3836 5753 XSTRNCPY(str, "setitimer() error", max);
ashleymills 0:714293de3836 5754 break;
ashleymills 0:714293de3836 5755
ashleymills 0:714293de3836 5756 case LENGTH_ERROR:
ashleymills 0:714293de3836 5757 XSTRNCPY(str, "record layer length error", max);
ashleymills 0:714293de3836 5758 break;
ashleymills 0:714293de3836 5759
ashleymills 0:714293de3836 5760 case PEER_KEY_ERROR:
ashleymills 0:714293de3836 5761 XSTRNCPY(str, "cant decode peer key", max);
ashleymills 0:714293de3836 5762 break;
ashleymills 0:714293de3836 5763
ashleymills 0:714293de3836 5764 case ZERO_RETURN:
ashleymills 0:714293de3836 5765 case SSL_ERROR_ZERO_RETURN:
ashleymills 0:714293de3836 5766 XSTRNCPY(str, "peer sent close notify alert", max);
ashleymills 0:714293de3836 5767 break;
ashleymills 0:714293de3836 5768
ashleymills 0:714293de3836 5769 case ECC_CURVETYPE_ERROR:
ashleymills 0:714293de3836 5770 XSTRNCPY(str, "Bad ECC Curve Type or unsupported", max);
ashleymills 0:714293de3836 5771 break;
ashleymills 0:714293de3836 5772
ashleymills 0:714293de3836 5773 case ECC_CURVE_ERROR:
ashleymills 0:714293de3836 5774 XSTRNCPY(str, "Bad ECC Curve or unsupported", max);
ashleymills 0:714293de3836 5775 break;
ashleymills 0:714293de3836 5776
ashleymills 0:714293de3836 5777 case ECC_PEERKEY_ERROR:
ashleymills 0:714293de3836 5778 XSTRNCPY(str, "Bad ECC Peer Key", max);
ashleymills 0:714293de3836 5779 break;
ashleymills 0:714293de3836 5780
ashleymills 0:714293de3836 5781 case ECC_MAKEKEY_ERROR:
ashleymills 0:714293de3836 5782 XSTRNCPY(str, "ECC Make Key failure", max);
ashleymills 0:714293de3836 5783 break;
ashleymills 0:714293de3836 5784
ashleymills 0:714293de3836 5785 case ECC_EXPORT_ERROR:
ashleymills 0:714293de3836 5786 XSTRNCPY(str, "ECC Export Key failure", max);
ashleymills 0:714293de3836 5787 break;
ashleymills 0:714293de3836 5788
ashleymills 0:714293de3836 5789 case ECC_SHARED_ERROR:
ashleymills 0:714293de3836 5790 XSTRNCPY(str, "ECC DHE shared failure", max);
ashleymills 0:714293de3836 5791 break;
ashleymills 0:714293de3836 5792
ashleymills 0:714293de3836 5793 case BAD_MUTEX_ERROR:
ashleymills 0:714293de3836 5794 XSTRNCPY(str, "Bad mutex, operation failed", max);
ashleymills 0:714293de3836 5795 break;
ashleymills 0:714293de3836 5796
ashleymills 0:714293de3836 5797 case NOT_CA_ERROR:
ashleymills 0:714293de3836 5798 XSTRNCPY(str, "Not a CA by basic constraint error", max);
ashleymills 0:714293de3836 5799 break;
ashleymills 0:714293de3836 5800
ashleymills 0:714293de3836 5801 case BAD_PATH_ERROR:
ashleymills 0:714293de3836 5802 XSTRNCPY(str, "Bad path for opendir error", max);
ashleymills 0:714293de3836 5803 break;
ashleymills 0:714293de3836 5804
ashleymills 0:714293de3836 5805 case BAD_CERT_MANAGER_ERROR:
ashleymills 0:714293de3836 5806 XSTRNCPY(str, "Bad Cert Manager error", max);
ashleymills 0:714293de3836 5807 break;
ashleymills 0:714293de3836 5808
ashleymills 0:714293de3836 5809 case OCSP_CERT_REVOKED:
ashleymills 0:714293de3836 5810 XSTRNCPY(str, "OCSP Cert revoked", max);
ashleymills 0:714293de3836 5811 break;
ashleymills 0:714293de3836 5812
ashleymills 0:714293de3836 5813 case CRL_CERT_REVOKED:
ashleymills 0:714293de3836 5814 XSTRNCPY(str, "CRL Cert revoked", max);
ashleymills 0:714293de3836 5815 break;
ashleymills 0:714293de3836 5816
ashleymills 0:714293de3836 5817 case CRL_MISSING:
ashleymills 0:714293de3836 5818 XSTRNCPY(str, "CRL missing, not loaded", max);
ashleymills 0:714293de3836 5819 break;
ashleymills 0:714293de3836 5820
ashleymills 0:714293de3836 5821 case MONITOR_RUNNING_E:
ashleymills 0:714293de3836 5822 XSTRNCPY(str, "CRL monitor already running", max);
ashleymills 0:714293de3836 5823 break;
ashleymills 0:714293de3836 5824
ashleymills 0:714293de3836 5825 case THREAD_CREATE_E:
ashleymills 0:714293de3836 5826 XSTRNCPY(str, "Thread creation problem", max);
ashleymills 0:714293de3836 5827 break;
ashleymills 0:714293de3836 5828
ashleymills 0:714293de3836 5829 case OCSP_NEED_URL:
ashleymills 0:714293de3836 5830 XSTRNCPY(str, "OCSP need URL", max);
ashleymills 0:714293de3836 5831 break;
ashleymills 0:714293de3836 5832
ashleymills 0:714293de3836 5833 case OCSP_CERT_UNKNOWN:
ashleymills 0:714293de3836 5834 XSTRNCPY(str, "OCSP Cert unknown", max);
ashleymills 0:714293de3836 5835 break;
ashleymills 0:714293de3836 5836
ashleymills 0:714293de3836 5837 case OCSP_LOOKUP_FAIL:
ashleymills 0:714293de3836 5838 XSTRNCPY(str, "OCSP Responder lookup fail", max);
ashleymills 0:714293de3836 5839 break;
ashleymills 0:714293de3836 5840
ashleymills 0:714293de3836 5841 case MAX_CHAIN_ERROR:
ashleymills 0:714293de3836 5842 XSTRNCPY(str, "Maximum Chain Depth Exceeded", max);
ashleymills 0:714293de3836 5843 break;
ashleymills 0:714293de3836 5844
ashleymills 0:714293de3836 5845 case COOKIE_ERROR:
ashleymills 0:714293de3836 5846 XSTRNCPY(str, "DTLS Cookie Error", max);
ashleymills 0:714293de3836 5847 break;
ashleymills 0:714293de3836 5848
ashleymills 0:714293de3836 5849 case SEQUENCE_ERROR:
ashleymills 0:714293de3836 5850 XSTRNCPY(str, "DTLS Sequence Error", max);
ashleymills 0:714293de3836 5851 break;
ashleymills 0:714293de3836 5852
ashleymills 0:714293de3836 5853 case SUITES_ERROR:
ashleymills 0:714293de3836 5854 XSTRNCPY(str, "Suites Pointer Error", max);
ashleymills 0:714293de3836 5855 break;
ashleymills 0:714293de3836 5856
ashleymills 0:714293de3836 5857 case SSL_NO_PEM_HEADER:
ashleymills 0:714293de3836 5858 XSTRNCPY(str, "No PEM Header Error", max);
ashleymills 0:714293de3836 5859 break;
ashleymills 0:714293de3836 5860
ashleymills 0:714293de3836 5861 case OUT_OF_ORDER_E:
ashleymills 0:714293de3836 5862 XSTRNCPY(str, "Out of order message, fatal", max);
ashleymills 0:714293de3836 5863 break;
ashleymills 0:714293de3836 5864
ashleymills 0:714293de3836 5865 case BAD_KEA_TYPE_E:
ashleymills 0:714293de3836 5866 XSTRNCPY(str, "Bad KEA type found", max);
ashleymills 0:714293de3836 5867 break;
ashleymills 0:714293de3836 5868
ashleymills 0:714293de3836 5869 case SANITY_CIPHER_E:
ashleymills 0:714293de3836 5870 XSTRNCPY(str, "Sanity check on ciphertext failed", max);
ashleymills 0:714293de3836 5871 break;
ashleymills 0:714293de3836 5872
ashleymills 0:714293de3836 5873 case RECV_OVERFLOW_E:
ashleymills 0:714293de3836 5874 XSTRNCPY(str, "Receive callback returned more than requested", max);
ashleymills 0:714293de3836 5875 break;
ashleymills 0:714293de3836 5876
ashleymills 0:714293de3836 5877 case GEN_COOKIE_E:
ashleymills 0:714293de3836 5878 XSTRNCPY(str, "Generate Cookie Error", max);
ashleymills 0:714293de3836 5879 break;
ashleymills 0:714293de3836 5880
ashleymills 0:714293de3836 5881 case NO_PEER_VERIFY:
ashleymills 0:714293de3836 5882 XSTRNCPY(str, "Need peer certificate verify Error", max);
ashleymills 0:714293de3836 5883 break;
ashleymills 0:714293de3836 5884
ashleymills 0:714293de3836 5885 case FWRITE_ERROR:
ashleymills 0:714293de3836 5886 XSTRNCPY(str, "fwrite Error", max);
ashleymills 0:714293de3836 5887 break;
ashleymills 0:714293de3836 5888
ashleymills 0:714293de3836 5889 case CACHE_MATCH_ERROR:
ashleymills 0:714293de3836 5890 XSTRNCPY(str, "Cache restore header match Error", max);
ashleymills 0:714293de3836 5891 break;
ashleymills 0:714293de3836 5892
ashleymills 0:714293de3836 5893 case UNKNOWN_SNI_HOST_NAME_E:
ashleymills 0:714293de3836 5894 XSTRNCPY(str, "Unrecognized host name Error", max);
ashleymills 0:714293de3836 5895 break;
ashleymills 0:714293de3836 5896
ashleymills 0:714293de3836 5897 default :
ashleymills 0:714293de3836 5898 XSTRNCPY(str, "unknown error number", max);
ashleymills 0:714293de3836 5899 }
ashleymills 0:714293de3836 5900
ashleymills 0:714293de3836 5901 #endif /* NO_ERROR_STRINGS */
ashleymills 0:714293de3836 5902 }
ashleymills 0:714293de3836 5903
ashleymills 0:714293de3836 5904
ashleymills 0:714293de3836 5905
ashleymills 0:714293de3836 5906 /* be sure to add to cipher_name_idx too !!!! */
ashleymills 0:714293de3836 5907 const char* const cipher_names[] =
ashleymills 0:714293de3836 5908 {
ashleymills 0:714293de3836 5909 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 5910 "RC4-SHA",
ashleymills 0:714293de3836 5911 #endif
ashleymills 0:714293de3836 5912
ashleymills 0:714293de3836 5913 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
ashleymills 0:714293de3836 5914 "RC4-MD5",
ashleymills 0:714293de3836 5915 #endif
ashleymills 0:714293de3836 5916
ashleymills 0:714293de3836 5917 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 5918 "DES-CBC3-SHA",
ashleymills 0:714293de3836 5919 #endif
ashleymills 0:714293de3836 5920
ashleymills 0:714293de3836 5921 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 5922 "AES128-SHA",
ashleymills 0:714293de3836 5923 #endif
ashleymills 0:714293de3836 5924
ashleymills 0:714293de3836 5925 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 5926 "AES256-SHA",
ashleymills 0:714293de3836 5927 #endif
ashleymills 0:714293de3836 5928
ashleymills 0:714293de3836 5929 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
ashleymills 0:714293de3836 5930 "NULL-SHA",
ashleymills 0:714293de3836 5931 #endif
ashleymills 0:714293de3836 5932
ashleymills 0:714293de3836 5933 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
ashleymills 0:714293de3836 5934 "NULL-SHA256",
ashleymills 0:714293de3836 5935 #endif
ashleymills 0:714293de3836 5936
ashleymills 0:714293de3836 5937 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 5938 "DHE-RSA-AES128-SHA",
ashleymills 0:714293de3836 5939 #endif
ashleymills 0:714293de3836 5940
ashleymills 0:714293de3836 5941 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 5942 "DHE-RSA-AES256-SHA",
ashleymills 0:714293de3836 5943 #endif
ashleymills 0:714293de3836 5944
ashleymills 0:714293de3836 5945 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 5946 "PSK-AES128-CBC-SHA256",
ashleymills 0:714293de3836 5947 #endif
ashleymills 0:714293de3836 5948
ashleymills 0:714293de3836 5949 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 5950 "PSK-AES128-CBC-SHA",
ashleymills 0:714293de3836 5951 #endif
ashleymills 0:714293de3836 5952
ashleymills 0:714293de3836 5953 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 5954 "PSK-AES256-CBC-SHA",
ashleymills 0:714293de3836 5955 #endif
ashleymills 0:714293de3836 5956
ashleymills 0:714293de3836 5957 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
ashleymills 0:714293de3836 5958 "PSK-AES128-CCM-8",
ashleymills 0:714293de3836 5959 #endif
ashleymills 0:714293de3836 5960
ashleymills 0:714293de3836 5961 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
ashleymills 0:714293de3836 5962 "PSK-AES256-CCM-8",
ashleymills 0:714293de3836 5963 #endif
ashleymills 0:714293de3836 5964
ashleymills 0:714293de3836 5965 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
ashleymills 0:714293de3836 5966 "PSK-NULL-SHA256",
ashleymills 0:714293de3836 5967 #endif
ashleymills 0:714293de3836 5968
ashleymills 0:714293de3836 5969 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
ashleymills 0:714293de3836 5970 "PSK-NULL-SHA",
ashleymills 0:714293de3836 5971 #endif
ashleymills 0:714293de3836 5972
ashleymills 0:714293de3836 5973 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
ashleymills 0:714293de3836 5974 "HC128-MD5",
ashleymills 0:714293de3836 5975 #endif
ashleymills 0:714293de3836 5976
ashleymills 0:714293de3836 5977 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
ashleymills 0:714293de3836 5978 "HC128-SHA",
ashleymills 0:714293de3836 5979 #endif
ashleymills 0:714293de3836 5980
ashleymills 0:714293de3836 5981 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
ashleymills 0:714293de3836 5982 "RABBIT-SHA",
ashleymills 0:714293de3836 5983 #endif
ashleymills 0:714293de3836 5984
ashleymills 0:714293de3836 5985 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 5986 "NTRU-RC4-SHA",
ashleymills 0:714293de3836 5987 #endif
ashleymills 0:714293de3836 5988
ashleymills 0:714293de3836 5989 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 5990 "NTRU-DES-CBC3-SHA",
ashleymills 0:714293de3836 5991 #endif
ashleymills 0:714293de3836 5992
ashleymills 0:714293de3836 5993 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 5994 "NTRU-AES128-SHA",
ashleymills 0:714293de3836 5995 #endif
ashleymills 0:714293de3836 5996
ashleymills 0:714293de3836 5997 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 5998 "NTRU-AES256-SHA",
ashleymills 0:714293de3836 5999 #endif
ashleymills 0:714293de3836 6000
ashleymills 0:714293de3836 6001 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
ashleymills 0:714293de3836 6002 "AES128-CCM-8",
ashleymills 0:714293de3836 6003 #endif
ashleymills 0:714293de3836 6004
ashleymills 0:714293de3836 6005 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
ashleymills 0:714293de3836 6006 "AES256-CCM-8",
ashleymills 0:714293de3836 6007 #endif
ashleymills 0:714293de3836 6008
ashleymills 0:714293de3836 6009 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
ashleymills 0:714293de3836 6010 "ECDHE-ECDSA-AES128-CCM-8",
ashleymills 0:714293de3836 6011 #endif
ashleymills 0:714293de3836 6012
ashleymills 0:714293de3836 6013 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
ashleymills 0:714293de3836 6014 "ECDHE-ECDSA-AES256-CCM-8",
ashleymills 0:714293de3836 6015 #endif
ashleymills 0:714293de3836 6016
ashleymills 0:714293de3836 6017 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 6018 "ECDHE-RSA-AES128-SHA",
ashleymills 0:714293de3836 6019 #endif
ashleymills 0:714293de3836 6020
ashleymills 0:714293de3836 6021 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 6022 "ECDHE-RSA-AES256-SHA",
ashleymills 0:714293de3836 6023 #endif
ashleymills 0:714293de3836 6024
ashleymills 0:714293de3836 6025 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 6026 "ECDHE-ECDSA-AES128-SHA",
ashleymills 0:714293de3836 6027 #endif
ashleymills 0:714293de3836 6028
ashleymills 0:714293de3836 6029 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 6030 "ECDHE-ECDSA-AES256-SHA",
ashleymills 0:714293de3836 6031 #endif
ashleymills 0:714293de3836 6032
ashleymills 0:714293de3836 6033 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 6034 "ECDHE-RSA-RC4-SHA",
ashleymills 0:714293de3836 6035 #endif
ashleymills 0:714293de3836 6036
ashleymills 0:714293de3836 6037 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 6038 "ECDHE-RSA-DES-CBC3-SHA",
ashleymills 0:714293de3836 6039 #endif
ashleymills 0:714293de3836 6040
ashleymills 0:714293de3836 6041 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 6042 "ECDHE-ECDSA-RC4-SHA",
ashleymills 0:714293de3836 6043 #endif
ashleymills 0:714293de3836 6044
ashleymills 0:714293de3836 6045 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 6046 "ECDHE-ECDSA-DES-CBC3-SHA",
ashleymills 0:714293de3836 6047 #endif
ashleymills 0:714293de3836 6048
ashleymills 0:714293de3836 6049 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 6050 "AES128-SHA256",
ashleymills 0:714293de3836 6051 #endif
ashleymills 0:714293de3836 6052
ashleymills 0:714293de3836 6053 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
ashleymills 0:714293de3836 6054 "AES256-SHA256",
ashleymills 0:714293de3836 6055 #endif
ashleymills 0:714293de3836 6056
ashleymills 0:714293de3836 6057 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 6058 "DHE-RSA-AES128-SHA256",
ashleymills 0:714293de3836 6059 #endif
ashleymills 0:714293de3836 6060
ashleymills 0:714293de3836 6061 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
ashleymills 0:714293de3836 6062 "DHE-RSA-AES256-SHA256",
ashleymills 0:714293de3836 6063 #endif
ashleymills 0:714293de3836 6064
ashleymills 0:714293de3836 6065 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 6066 "ECDH-RSA-AES128-SHA",
ashleymills 0:714293de3836 6067 #endif
ashleymills 0:714293de3836 6068
ashleymills 0:714293de3836 6069 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 6070 "ECDH-RSA-AES256-SHA",
ashleymills 0:714293de3836 6071 #endif
ashleymills 0:714293de3836 6072
ashleymills 0:714293de3836 6073 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 6074 "ECDH-ECDSA-AES128-SHA",
ashleymills 0:714293de3836 6075 #endif
ashleymills 0:714293de3836 6076
ashleymills 0:714293de3836 6077 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 6078 "ECDH-ECDSA-AES256-SHA",
ashleymills 0:714293de3836 6079 #endif
ashleymills 0:714293de3836 6080
ashleymills 0:714293de3836 6081 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 6082 "ECDH-RSA-RC4-SHA",
ashleymills 0:714293de3836 6083 #endif
ashleymills 0:714293de3836 6084
ashleymills 0:714293de3836 6085 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 6086 "ECDH-RSA-DES-CBC3-SHA",
ashleymills 0:714293de3836 6087 #endif
ashleymills 0:714293de3836 6088
ashleymills 0:714293de3836 6089 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 6090 "ECDH-ECDSA-RC4-SHA",
ashleymills 0:714293de3836 6091 #endif
ashleymills 0:714293de3836 6092
ashleymills 0:714293de3836 6093 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 6094 "ECDH-ECDSA-DES-CBC3-SHA",
ashleymills 0:714293de3836 6095 #endif
ashleymills 0:714293de3836 6096
ashleymills 0:714293de3836 6097 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 6098 "AES128-GCM-SHA256",
ashleymills 0:714293de3836 6099 #endif
ashleymills 0:714293de3836 6100
ashleymills 0:714293de3836 6101 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 6102 "AES256-GCM-SHA384",
ashleymills 0:714293de3836 6103 #endif
ashleymills 0:714293de3836 6104
ashleymills 0:714293de3836 6105 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 6106 "DHE-RSA-AES128-GCM-SHA256",
ashleymills 0:714293de3836 6107 #endif
ashleymills 0:714293de3836 6108
ashleymills 0:714293de3836 6109 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 6110 "DHE-RSA-AES256-GCM-SHA384",
ashleymills 0:714293de3836 6111 #endif
ashleymills 0:714293de3836 6112
ashleymills 0:714293de3836 6113 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 6114 "ECDHE-RSA-AES128-GCM-SHA256",
ashleymills 0:714293de3836 6115 #endif
ashleymills 0:714293de3836 6116
ashleymills 0:714293de3836 6117 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 6118 "ECDHE-RSA-AES256-GCM-SHA384",
ashleymills 0:714293de3836 6119 #endif
ashleymills 0:714293de3836 6120
ashleymills 0:714293de3836 6121 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 6122 "ECDHE-ECDSA-AES128-GCM-SHA256",
ashleymills 0:714293de3836 6123 #endif
ashleymills 0:714293de3836 6124
ashleymills 0:714293de3836 6125 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 6126 "ECDHE-ECDSA-AES256-GCM-SHA384",
ashleymills 0:714293de3836 6127 #endif
ashleymills 0:714293de3836 6128
ashleymills 0:714293de3836 6129 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 6130 "ECDH-RSA-AES128-GCM-SHA256",
ashleymills 0:714293de3836 6131 #endif
ashleymills 0:714293de3836 6132
ashleymills 0:714293de3836 6133 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 6134 "ECDH-RSA-AES256-GCM-SHA384",
ashleymills 0:714293de3836 6135 #endif
ashleymills 0:714293de3836 6136
ashleymills 0:714293de3836 6137 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 6138 "ECDH-ECDSA-AES128-GCM-SHA256",
ashleymills 0:714293de3836 6139 #endif
ashleymills 0:714293de3836 6140
ashleymills 0:714293de3836 6141 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 6142 "ECDH-ECDSA-AES256-GCM-SHA384",
ashleymills 0:714293de3836 6143 #endif
ashleymills 0:714293de3836 6144
ashleymills 0:714293de3836 6145 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
ashleymills 0:714293de3836 6146 "CAMELLIA128-SHA",
ashleymills 0:714293de3836 6147 #endif
ashleymills 0:714293de3836 6148
ashleymills 0:714293de3836 6149 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
ashleymills 0:714293de3836 6150 "DHE-RSA-CAMELLIA128-SHA",
ashleymills 0:714293de3836 6151 #endif
ashleymills 0:714293de3836 6152
ashleymills 0:714293de3836 6153 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
ashleymills 0:714293de3836 6154 "CAMELLIA256-SHA",
ashleymills 0:714293de3836 6155 #endif
ashleymills 0:714293de3836 6156
ashleymills 0:714293de3836 6157 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
ashleymills 0:714293de3836 6158 "DHE-RSA-CAMELLIA256-SHA",
ashleymills 0:714293de3836 6159 #endif
ashleymills 0:714293de3836 6160
ashleymills 0:714293de3836 6161 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
ashleymills 0:714293de3836 6162 "CAMELLIA128-SHA256",
ashleymills 0:714293de3836 6163 #endif
ashleymills 0:714293de3836 6164
ashleymills 0:714293de3836 6165 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
ashleymills 0:714293de3836 6166 "DHE-RSA-CAMELLIA128-SHA256",
ashleymills 0:714293de3836 6167 #endif
ashleymills 0:714293de3836 6168
ashleymills 0:714293de3836 6169 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
ashleymills 0:714293de3836 6170 "CAMELLIA256-SHA256",
ashleymills 0:714293de3836 6171 #endif
ashleymills 0:714293de3836 6172
ashleymills 0:714293de3836 6173 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
ashleymills 0:714293de3836 6174 "DHE-RSA-CAMELLIA256-SHA256",
ashleymills 0:714293de3836 6175 #endif
ashleymills 0:714293de3836 6176
ashleymills 0:714293de3836 6177 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 6178 "ECDHE-RSA-AES128-SHA256",
ashleymills 0:714293de3836 6179 #endif
ashleymills 0:714293de3836 6180
ashleymills 0:714293de3836 6181 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 6182 "ECDHE-ECDSA-AES128-SHA256",
ashleymills 0:714293de3836 6183 #endif
ashleymills 0:714293de3836 6184
ashleymills 0:714293de3836 6185 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 6186 "ECDH-RSA-AES128-SHA256",
ashleymills 0:714293de3836 6187 #endif
ashleymills 0:714293de3836 6188
ashleymills 0:714293de3836 6189 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 6190 "ECDH-ECDSA-AES128-SHA256",
ashleymills 0:714293de3836 6191 #endif
ashleymills 0:714293de3836 6192
ashleymills 0:714293de3836 6193 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
ashleymills 0:714293de3836 6194 "ECDHE-RSA-AES256-SHA384",
ashleymills 0:714293de3836 6195 #endif
ashleymills 0:714293de3836 6196
ashleymills 0:714293de3836 6197 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
ashleymills 0:714293de3836 6198 "ECDHE-ECDSA-AES256-SHA384",
ashleymills 0:714293de3836 6199 #endif
ashleymills 0:714293de3836 6200
ashleymills 0:714293de3836 6201 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
ashleymills 0:714293de3836 6202 "ECDH-RSA-AES256-SHA384",
ashleymills 0:714293de3836 6203 #endif
ashleymills 0:714293de3836 6204
ashleymills 0:714293de3836 6205 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
ashleymills 0:714293de3836 6206 "ECDH-ECDSA-AES256-SHA384",
ashleymills 0:714293de3836 6207 #endif
ashleymills 0:714293de3836 6208
ashleymills 0:714293de3836 6209 };
ashleymills 0:714293de3836 6210
ashleymills 0:714293de3836 6211
ashleymills 0:714293de3836 6212
ashleymills 0:714293de3836 6213 /* cipher suite number that matches above name table */
ashleymills 0:714293de3836 6214 int cipher_name_idx[] =
ashleymills 0:714293de3836 6215 {
ashleymills 0:714293de3836 6216
ashleymills 0:714293de3836 6217 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 6218 SSL_RSA_WITH_RC4_128_SHA,
ashleymills 0:714293de3836 6219 #endif
ashleymills 0:714293de3836 6220
ashleymills 0:714293de3836 6221 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
ashleymills 0:714293de3836 6222 SSL_RSA_WITH_RC4_128_MD5,
ashleymills 0:714293de3836 6223 #endif
ashleymills 0:714293de3836 6224
ashleymills 0:714293de3836 6225 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 6226 SSL_RSA_WITH_3DES_EDE_CBC_SHA,
ashleymills 0:714293de3836 6227 #endif
ashleymills 0:714293de3836 6228
ashleymills 0:714293de3836 6229 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 6230 TLS_RSA_WITH_AES_128_CBC_SHA,
ashleymills 0:714293de3836 6231 #endif
ashleymills 0:714293de3836 6232
ashleymills 0:714293de3836 6233 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 6234 TLS_RSA_WITH_AES_256_CBC_SHA,
ashleymills 0:714293de3836 6235 #endif
ashleymills 0:714293de3836 6236
ashleymills 0:714293de3836 6237 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
ashleymills 0:714293de3836 6238 TLS_RSA_WITH_NULL_SHA,
ashleymills 0:714293de3836 6239 #endif
ashleymills 0:714293de3836 6240
ashleymills 0:714293de3836 6241 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
ashleymills 0:714293de3836 6242 TLS_RSA_WITH_NULL_SHA256,
ashleymills 0:714293de3836 6243 #endif
ashleymills 0:714293de3836 6244
ashleymills 0:714293de3836 6245 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 6246 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
ashleymills 0:714293de3836 6247 #endif
ashleymills 0:714293de3836 6248
ashleymills 0:714293de3836 6249 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 6250 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
ashleymills 0:714293de3836 6251 #endif
ashleymills 0:714293de3836 6252
ashleymills 0:714293de3836 6253 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 6254 TLS_PSK_WITH_AES_128_CBC_SHA256,
ashleymills 0:714293de3836 6255 #endif
ashleymills 0:714293de3836 6256
ashleymills 0:714293de3836 6257 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 6258 TLS_PSK_WITH_AES_128_CBC_SHA,
ashleymills 0:714293de3836 6259 #endif
ashleymills 0:714293de3836 6260
ashleymills 0:714293de3836 6261 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 6262 TLS_PSK_WITH_AES_256_CBC_SHA,
ashleymills 0:714293de3836 6263 #endif
ashleymills 0:714293de3836 6264
ashleymills 0:714293de3836 6265 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
ashleymills 0:714293de3836 6266 TLS_PSK_WITH_AES_128_CCM_8,
ashleymills 0:714293de3836 6267 #endif
ashleymills 0:714293de3836 6268
ashleymills 0:714293de3836 6269 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
ashleymills 0:714293de3836 6270 TLS_PSK_WITH_AES_256_CCM_8,
ashleymills 0:714293de3836 6271 #endif
ashleymills 0:714293de3836 6272
ashleymills 0:714293de3836 6273 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
ashleymills 0:714293de3836 6274 TLS_PSK_WITH_NULL_SHA256,
ashleymills 0:714293de3836 6275 #endif
ashleymills 0:714293de3836 6276
ashleymills 0:714293de3836 6277 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
ashleymills 0:714293de3836 6278 TLS_PSK_WITH_NULL_SHA,
ashleymills 0:714293de3836 6279 #endif
ashleymills 0:714293de3836 6280
ashleymills 0:714293de3836 6281 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
ashleymills 0:714293de3836 6282 TLS_RSA_WITH_HC_128_CBC_MD5,
ashleymills 0:714293de3836 6283 #endif
ashleymills 0:714293de3836 6284
ashleymills 0:714293de3836 6285 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
ashleymills 0:714293de3836 6286 TLS_RSA_WITH_HC_128_CBC_SHA,
ashleymills 0:714293de3836 6287 #endif
ashleymills 0:714293de3836 6288
ashleymills 0:714293de3836 6289 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
ashleymills 0:714293de3836 6290 TLS_RSA_WITH_RABBIT_CBC_SHA,
ashleymills 0:714293de3836 6291 #endif
ashleymills 0:714293de3836 6292
ashleymills 0:714293de3836 6293 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 6294 TLS_NTRU_RSA_WITH_RC4_128_SHA,
ashleymills 0:714293de3836 6295 #endif
ashleymills 0:714293de3836 6296
ashleymills 0:714293de3836 6297 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 6298 TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA,
ashleymills 0:714293de3836 6299 #endif
ashleymills 0:714293de3836 6300
ashleymills 0:714293de3836 6301 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 6302 TLS_NTRU_RSA_WITH_AES_128_CBC_SHA,
ashleymills 0:714293de3836 6303 #endif
ashleymills 0:714293de3836 6304
ashleymills 0:714293de3836 6305 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 6306 TLS_NTRU_RSA_WITH_AES_256_CBC_SHA,
ashleymills 0:714293de3836 6307 #endif
ashleymills 0:714293de3836 6308
ashleymills 0:714293de3836 6309 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
ashleymills 0:714293de3836 6310 TLS_RSA_WITH_AES_128_CCM_8,
ashleymills 0:714293de3836 6311 #endif
ashleymills 0:714293de3836 6312
ashleymills 0:714293de3836 6313 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
ashleymills 0:714293de3836 6314 TLS_RSA_WITH_AES_256_CCM_8,
ashleymills 0:714293de3836 6315 #endif
ashleymills 0:714293de3836 6316
ashleymills 0:714293de3836 6317 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
ashleymills 0:714293de3836 6318 TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
ashleymills 0:714293de3836 6319 #endif
ashleymills 0:714293de3836 6320
ashleymills 0:714293de3836 6321 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
ashleymills 0:714293de3836 6322 TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
ashleymills 0:714293de3836 6323 #endif
ashleymills 0:714293de3836 6324
ashleymills 0:714293de3836 6325 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 6326 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
ashleymills 0:714293de3836 6327 #endif
ashleymills 0:714293de3836 6328
ashleymills 0:714293de3836 6329 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 6330 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
ashleymills 0:714293de3836 6331 #endif
ashleymills 0:714293de3836 6332
ashleymills 0:714293de3836 6333 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 6334 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
ashleymills 0:714293de3836 6335 #endif
ashleymills 0:714293de3836 6336
ashleymills 0:714293de3836 6337 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 6338 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
ashleymills 0:714293de3836 6339 #endif
ashleymills 0:714293de3836 6340
ashleymills 0:714293de3836 6341 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 6342 TLS_ECDHE_RSA_WITH_RC4_128_SHA,
ashleymills 0:714293de3836 6343 #endif
ashleymills 0:714293de3836 6344
ashleymills 0:714293de3836 6345 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 6346 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
ashleymills 0:714293de3836 6347 #endif
ashleymills 0:714293de3836 6348
ashleymills 0:714293de3836 6349 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 6350 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
ashleymills 0:714293de3836 6351 #endif
ashleymills 0:714293de3836 6352
ashleymills 0:714293de3836 6353 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 6354 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
ashleymills 0:714293de3836 6355 #endif
ashleymills 0:714293de3836 6356
ashleymills 0:714293de3836 6357 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 6358 TLS_RSA_WITH_AES_128_CBC_SHA256,
ashleymills 0:714293de3836 6359 #endif
ashleymills 0:714293de3836 6360
ashleymills 0:714293de3836 6361 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
ashleymills 0:714293de3836 6362 TLS_RSA_WITH_AES_256_CBC_SHA256,
ashleymills 0:714293de3836 6363 #endif
ashleymills 0:714293de3836 6364
ashleymills 0:714293de3836 6365 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 6366 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
ashleymills 0:714293de3836 6367 #endif
ashleymills 0:714293de3836 6368
ashleymills 0:714293de3836 6369 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
ashleymills 0:714293de3836 6370 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
ashleymills 0:714293de3836 6371 #endif
ashleymills 0:714293de3836 6372
ashleymills 0:714293de3836 6373 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 6374 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
ashleymills 0:714293de3836 6375 #endif
ashleymills 0:714293de3836 6376
ashleymills 0:714293de3836 6377 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 6378 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
ashleymills 0:714293de3836 6379 #endif
ashleymills 0:714293de3836 6380
ashleymills 0:714293de3836 6381 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
ashleymills 0:714293de3836 6382 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
ashleymills 0:714293de3836 6383 #endif
ashleymills 0:714293de3836 6384
ashleymills 0:714293de3836 6385 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
ashleymills 0:714293de3836 6386 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
ashleymills 0:714293de3836 6387 #endif
ashleymills 0:714293de3836 6388
ashleymills 0:714293de3836 6389 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 6390 TLS_ECDH_RSA_WITH_RC4_128_SHA,
ashleymills 0:714293de3836 6391 #endif
ashleymills 0:714293de3836 6392
ashleymills 0:714293de3836 6393 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 6394 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
ashleymills 0:714293de3836 6395 #endif
ashleymills 0:714293de3836 6396
ashleymills 0:714293de3836 6397 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
ashleymills 0:714293de3836 6398 TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
ashleymills 0:714293de3836 6399 #endif
ashleymills 0:714293de3836 6400
ashleymills 0:714293de3836 6401 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:714293de3836 6402 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
ashleymills 0:714293de3836 6403 #endif
ashleymills 0:714293de3836 6404
ashleymills 0:714293de3836 6405 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 6406 TLS_RSA_WITH_AES_128_GCM_SHA256,
ashleymills 0:714293de3836 6407 #endif
ashleymills 0:714293de3836 6408
ashleymills 0:714293de3836 6409 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 6410 TLS_RSA_WITH_AES_256_GCM_SHA384,
ashleymills 0:714293de3836 6411 #endif
ashleymills 0:714293de3836 6412
ashleymills 0:714293de3836 6413 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 6414 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
ashleymills 0:714293de3836 6415 #endif
ashleymills 0:714293de3836 6416
ashleymills 0:714293de3836 6417 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 6418 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
ashleymills 0:714293de3836 6419 #endif
ashleymills 0:714293de3836 6420
ashleymills 0:714293de3836 6421 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 6422 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
ashleymills 0:714293de3836 6423 #endif
ashleymills 0:714293de3836 6424
ashleymills 0:714293de3836 6425 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 6426 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
ashleymills 0:714293de3836 6427 #endif
ashleymills 0:714293de3836 6428
ashleymills 0:714293de3836 6429 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 6430 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
ashleymills 0:714293de3836 6431 #endif
ashleymills 0:714293de3836 6432
ashleymills 0:714293de3836 6433 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 6434 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
ashleymills 0:714293de3836 6435 #endif
ashleymills 0:714293de3836 6436
ashleymills 0:714293de3836 6437 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 6438 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
ashleymills 0:714293de3836 6439 #endif
ashleymills 0:714293de3836 6440
ashleymills 0:714293de3836 6441 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 6442 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
ashleymills 0:714293de3836 6443 #endif
ashleymills 0:714293de3836 6444
ashleymills 0:714293de3836 6445 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
ashleymills 0:714293de3836 6446 TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
ashleymills 0:714293de3836 6447 #endif
ashleymills 0:714293de3836 6448
ashleymills 0:714293de3836 6449 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
ashleymills 0:714293de3836 6450 TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
ashleymills 0:714293de3836 6451 #endif
ashleymills 0:714293de3836 6452
ashleymills 0:714293de3836 6453 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
ashleymills 0:714293de3836 6454 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
ashleymills 0:714293de3836 6455 #endif
ashleymills 0:714293de3836 6456
ashleymills 0:714293de3836 6457 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
ashleymills 0:714293de3836 6458 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
ashleymills 0:714293de3836 6459 #endif
ashleymills 0:714293de3836 6460
ashleymills 0:714293de3836 6461 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
ashleymills 0:714293de3836 6462 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
ashleymills 0:714293de3836 6463 #endif
ashleymills 0:714293de3836 6464
ashleymills 0:714293de3836 6465 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
ashleymills 0:714293de3836 6466 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
ashleymills 0:714293de3836 6467 #endif
ashleymills 0:714293de3836 6468
ashleymills 0:714293de3836 6469 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
ashleymills 0:714293de3836 6470 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
ashleymills 0:714293de3836 6471 #endif
ashleymills 0:714293de3836 6472
ashleymills 0:714293de3836 6473 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
ashleymills 0:714293de3836 6474 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
ashleymills 0:714293de3836 6475 #endif
ashleymills 0:714293de3836 6476
ashleymills 0:714293de3836 6477 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
ashleymills 0:714293de3836 6478 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
ashleymills 0:714293de3836 6479 #endif
ashleymills 0:714293de3836 6480
ashleymills 0:714293de3836 6481 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
ashleymills 0:714293de3836 6482 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
ashleymills 0:714293de3836 6483 #endif
ashleymills 0:714293de3836 6484
ashleymills 0:714293de3836 6485 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 6486 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
ashleymills 0:714293de3836 6487 #endif
ashleymills 0:714293de3836 6488
ashleymills 0:714293de3836 6489 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 6490 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
ashleymills 0:714293de3836 6491 #endif
ashleymills 0:714293de3836 6492
ashleymills 0:714293de3836 6493 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 6494 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
ashleymills 0:714293de3836 6495 #endif
ashleymills 0:714293de3836 6496
ashleymills 0:714293de3836 6497 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
ashleymills 0:714293de3836 6498 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
ashleymills 0:714293de3836 6499 #endif
ashleymills 0:714293de3836 6500
ashleymills 0:714293de3836 6501 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
ashleymills 0:714293de3836 6502 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
ashleymills 0:714293de3836 6503 #endif
ashleymills 0:714293de3836 6504
ashleymills 0:714293de3836 6505 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
ashleymills 0:714293de3836 6506 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
ashleymills 0:714293de3836 6507 #endif
ashleymills 0:714293de3836 6508
ashleymills 0:714293de3836 6509 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
ashleymills 0:714293de3836 6510 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
ashleymills 0:714293de3836 6511 #endif
ashleymills 0:714293de3836 6512
ashleymills 0:714293de3836 6513 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
ashleymills 0:714293de3836 6514 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
ashleymills 0:714293de3836 6515 #endif
ashleymills 0:714293de3836 6516 };
ashleymills 0:714293de3836 6517
ashleymills 0:714293de3836 6518
ashleymills 0:714293de3836 6519 /* return true if set, else false */
ashleymills 0:714293de3836 6520 /* only supports full name from cipher_name[] delimited by : */
ashleymills 0:714293de3836 6521 int SetCipherList(Suites* s, const char* list)
ashleymills 0:714293de3836 6522 {
ashleymills 0:714293de3836 6523 int ret = 0, i;
ashleymills 0:714293de3836 6524 char name[MAX_SUITE_NAME];
ashleymills 0:714293de3836 6525
ashleymills 0:714293de3836 6526 char needle[] = ":";
ashleymills 0:714293de3836 6527 char* haystack = (char*)list;
ashleymills 0:714293de3836 6528 char* prev;
ashleymills 0:714293de3836 6529
ashleymills 0:714293de3836 6530 const int suiteSz = sizeof(cipher_names) / sizeof(cipher_names[0]);
ashleymills 0:714293de3836 6531 int idx = 0;
ashleymills 0:714293de3836 6532 int haveRSA = 0, haveECDSA = 0;
ashleymills 0:714293de3836 6533
ashleymills 0:714293de3836 6534 if (s == NULL) {
ashleymills 0:714293de3836 6535 CYASSL_MSG("SetCipherList suite pointer error");
ashleymills 0:714293de3836 6536 return 0;
ashleymills 0:714293de3836 6537 }
ashleymills 0:714293de3836 6538
ashleymills 0:714293de3836 6539 if (!list)
ashleymills 0:714293de3836 6540 return 0;
ashleymills 0:714293de3836 6541
ashleymills 0:714293de3836 6542 if (*list == 0) return 1; /* CyaSSL default */
ashleymills 0:714293de3836 6543
ashleymills 0:714293de3836 6544 if (XSTRNCMP(haystack, "ALL", 3) == 0) return 1; /* CyaSSL defualt */
ashleymills 0:714293de3836 6545
ashleymills 0:714293de3836 6546 for(;;) {
ashleymills 0:714293de3836 6547 word32 len;
ashleymills 0:714293de3836 6548 prev = haystack;
ashleymills 0:714293de3836 6549 haystack = XSTRSTR(haystack, needle);
ashleymills 0:714293de3836 6550
ashleymills 0:714293de3836 6551 if (!haystack) /* last cipher */
ashleymills 0:714293de3836 6552 len = min(sizeof(name), (word32)XSTRLEN(prev));
ashleymills 0:714293de3836 6553 else
ashleymills 0:714293de3836 6554 len = min(sizeof(name), (word32)(haystack - prev));
ashleymills 0:714293de3836 6555
ashleymills 0:714293de3836 6556 XSTRNCPY(name, prev, len);
ashleymills 0:714293de3836 6557 name[(len == sizeof(name)) ? len - 1 : len] = 0;
ashleymills 0:714293de3836 6558
ashleymills 0:714293de3836 6559 for (i = 0; i < suiteSz; i++)
ashleymills 0:714293de3836 6560 if (XSTRNCMP(name, cipher_names[i], sizeof(name)) == 0) {
ashleymills 0:714293de3836 6561 if (XSTRSTR(name, "EC") || XSTRSTR(name, "CCM"))
ashleymills 0:714293de3836 6562 s->suites[idx++] = ECC_BYTE; /* ECC suite */
ashleymills 0:714293de3836 6563 else
ashleymills 0:714293de3836 6564 s->suites[idx++] = 0x00; /* normal */
ashleymills 0:714293de3836 6565 s->suites[idx++] = (byte)cipher_name_idx[i];
ashleymills 0:714293de3836 6566
ashleymills 0:714293de3836 6567 /* The suites are either ECDSA, RSA, or PSK. The RSA suites
ashleymills 0:714293de3836 6568 * don't necessarily have RSA in the name. */
ashleymills 0:714293de3836 6569 if ((haveECDSA == 0) && XSTRSTR(name, "ECDSA")) {
ashleymills 0:714293de3836 6570 haveECDSA = 1;
ashleymills 0:714293de3836 6571 }
ashleymills 0:714293de3836 6572 else if ((haveRSA == 0) && (XSTRSTR(name, "PSK") == NULL)) {
ashleymills 0:714293de3836 6573 haveRSA = 1;
ashleymills 0:714293de3836 6574 }
ashleymills 0:714293de3836 6575
ashleymills 0:714293de3836 6576 if (!ret) ret = 1; /* found at least one */
ashleymills 0:714293de3836 6577 break;
ashleymills 0:714293de3836 6578 }
ashleymills 0:714293de3836 6579 if (!haystack) break;
ashleymills 0:714293de3836 6580 haystack++;
ashleymills 0:714293de3836 6581 }
ashleymills 0:714293de3836 6582
ashleymills 0:714293de3836 6583 if (ret) {
ashleymills 0:714293de3836 6584 s->setSuites = 1;
ashleymills 0:714293de3836 6585 s->suiteSz = (word16)idx;
ashleymills 0:714293de3836 6586
ashleymills 0:714293de3836 6587 idx = 0;
ashleymills 0:714293de3836 6588
ashleymills 0:714293de3836 6589 if (haveECDSA) {
ashleymills 0:714293de3836 6590 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 6591 s->hashSigAlgo[idx++] = sha384_mac;
ashleymills 0:714293de3836 6592 s->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
ashleymills 0:714293de3836 6593 #endif
ashleymills 0:714293de3836 6594 #ifndef NO_SHA256
ashleymills 0:714293de3836 6595 s->hashSigAlgo[idx++] = sha256_mac;
ashleymills 0:714293de3836 6596 s->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
ashleymills 0:714293de3836 6597 #endif
ashleymills 0:714293de3836 6598 s->hashSigAlgo[idx++] = sha_mac;
ashleymills 0:714293de3836 6599 s->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
ashleymills 0:714293de3836 6600 }
ashleymills 0:714293de3836 6601
ashleymills 0:714293de3836 6602 if (haveRSA) {
ashleymills 0:714293de3836 6603 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 6604 s->hashSigAlgo[idx++] = sha384_mac;
ashleymills 0:714293de3836 6605 s->hashSigAlgo[idx++] = rsa_sa_algo;
ashleymills 0:714293de3836 6606 #endif
ashleymills 0:714293de3836 6607 #ifndef NO_SHA256
ashleymills 0:714293de3836 6608 s->hashSigAlgo[idx++] = sha256_mac;
ashleymills 0:714293de3836 6609 s->hashSigAlgo[idx++] = rsa_sa_algo;
ashleymills 0:714293de3836 6610 #endif
ashleymills 0:714293de3836 6611 s->hashSigAlgo[idx++] = sha_mac;
ashleymills 0:714293de3836 6612 s->hashSigAlgo[idx++] = rsa_sa_algo;
ashleymills 0:714293de3836 6613 }
ashleymills 0:714293de3836 6614
ashleymills 0:714293de3836 6615 s->hashSigAlgoSz = (word16)idx;
ashleymills 0:714293de3836 6616 }
ashleymills 0:714293de3836 6617
ashleymills 0:714293de3836 6618 return ret;
ashleymills 0:714293de3836 6619 }
ashleymills 0:714293de3836 6620
ashleymills 0:714293de3836 6621
ashleymills 0:714293de3836 6622 static void PickHashSigAlgo(CYASSL* ssl,
ashleymills 0:714293de3836 6623 const byte* hashSigAlgo, word32 hashSigAlgoSz)
ashleymills 0:714293de3836 6624 {
ashleymills 0:714293de3836 6625 word32 i;
ashleymills 0:714293de3836 6626
ashleymills 0:714293de3836 6627 ssl->suites->sigAlgo = ssl->specs.sig_algo;
ashleymills 0:714293de3836 6628 ssl->suites->hashAlgo = sha_mac;
ashleymills 0:714293de3836 6629
ashleymills 0:714293de3836 6630 for (i = 0; i < hashSigAlgoSz; i += 2) {
ashleymills 0:714293de3836 6631 if (hashSigAlgo[i+1] == ssl->specs.sig_algo) {
ashleymills 0:714293de3836 6632 if (hashSigAlgo[i] == sha_mac) {
ashleymills 0:714293de3836 6633 break;
ashleymills 0:714293de3836 6634 }
ashleymills 0:714293de3836 6635 #ifndef NO_SHA256
ashleymills 0:714293de3836 6636 else if (hashSigAlgo[i] == sha256_mac) {
ashleymills 0:714293de3836 6637 ssl->suites->hashAlgo = sha256_mac;
ashleymills 0:714293de3836 6638 break;
ashleymills 0:714293de3836 6639 }
ashleymills 0:714293de3836 6640 #endif
ashleymills 0:714293de3836 6641 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 6642 else if (hashSigAlgo[i] == sha384_mac) {
ashleymills 0:714293de3836 6643 ssl->suites->hashAlgo = sha384_mac;
ashleymills 0:714293de3836 6644 break;
ashleymills 0:714293de3836 6645 }
ashleymills 0:714293de3836 6646 #endif
ashleymills 0:714293de3836 6647 }
ashleymills 0:714293de3836 6648 }
ashleymills 0:714293de3836 6649 }
ashleymills 0:714293de3836 6650
ashleymills 0:714293de3836 6651
ashleymills 0:714293de3836 6652 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 6653
ashleymills 0:714293de3836 6654 /* Initialisze HandShakeInfo */
ashleymills 0:714293de3836 6655 void InitHandShakeInfo(HandShakeInfo* info)
ashleymills 0:714293de3836 6656 {
ashleymills 0:714293de3836 6657 int i;
ashleymills 0:714293de3836 6658
ashleymills 0:714293de3836 6659 info->cipherName[0] = 0;
ashleymills 0:714293de3836 6660 for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
ashleymills 0:714293de3836 6661 info->packetNames[i][0] = 0;
ashleymills 0:714293de3836 6662 info->numberPackets = 0;
ashleymills 0:714293de3836 6663 info->negotiationError = 0;
ashleymills 0:714293de3836 6664 }
ashleymills 0:714293de3836 6665
ashleymills 0:714293de3836 6666 /* Set Final HandShakeInfo parameters */
ashleymills 0:714293de3836 6667 void FinishHandShakeInfo(HandShakeInfo* info, const CYASSL* ssl)
ashleymills 0:714293de3836 6668 {
ashleymills 0:714293de3836 6669 int i;
ashleymills 0:714293de3836 6670 int sz = sizeof(cipher_name_idx)/sizeof(int);
ashleymills 0:714293de3836 6671
ashleymills 0:714293de3836 6672 for (i = 0; i < sz; i++)
ashleymills 0:714293de3836 6673 if (ssl->options.cipherSuite == (byte)cipher_name_idx[i]) {
ashleymills 0:714293de3836 6674 if (ssl->options.cipherSuite0 == ECC_BYTE)
ashleymills 0:714293de3836 6675 continue; /* ECC suites at end */
ashleymills 0:714293de3836 6676 XSTRNCPY(info->cipherName, cipher_names[i], MAX_CIPHERNAME_SZ);
ashleymills 0:714293de3836 6677 break;
ashleymills 0:714293de3836 6678 }
ashleymills 0:714293de3836 6679
ashleymills 0:714293de3836 6680 /* error max and min are negative numbers */
ashleymills 0:714293de3836 6681 if (ssl->error <= MIN_PARAM_ERR && ssl->error >= MAX_PARAM_ERR)
ashleymills 0:714293de3836 6682 info->negotiationError = ssl->error;
ashleymills 0:714293de3836 6683 }
ashleymills 0:714293de3836 6684
ashleymills 0:714293de3836 6685
ashleymills 0:714293de3836 6686 /* Add name to info packet names, increase packet name count */
ashleymills 0:714293de3836 6687 void AddPacketName(const char* name, HandShakeInfo* info)
ashleymills 0:714293de3836 6688 {
ashleymills 0:714293de3836 6689 if (info->numberPackets < MAX_PACKETS_HANDSHAKE) {
ashleymills 0:714293de3836 6690 XSTRNCPY(info->packetNames[info->numberPackets++], name,
ashleymills 0:714293de3836 6691 MAX_PACKETNAME_SZ);
ashleymills 0:714293de3836 6692 }
ashleymills 0:714293de3836 6693 }
ashleymills 0:714293de3836 6694
ashleymills 0:714293de3836 6695
ashleymills 0:714293de3836 6696 /* Initialisze TimeoutInfo */
ashleymills 0:714293de3836 6697 void InitTimeoutInfo(TimeoutInfo* info)
ashleymills 0:714293de3836 6698 {
ashleymills 0:714293de3836 6699 int i;
ashleymills 0:714293de3836 6700
ashleymills 0:714293de3836 6701 info->timeoutName[0] = 0;
ashleymills 0:714293de3836 6702 info->flags = 0;
ashleymills 0:714293de3836 6703
ashleymills 0:714293de3836 6704 for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++) {
ashleymills 0:714293de3836 6705 info->packets[i].packetName[0] = 0;
ashleymills 0:714293de3836 6706 info->packets[i].timestamp.tv_sec = 0;
ashleymills 0:714293de3836 6707 info->packets[i].timestamp.tv_usec = 0;
ashleymills 0:714293de3836 6708 info->packets[i].bufferValue = 0;
ashleymills 0:714293de3836 6709 info->packets[i].valueSz = 0;
ashleymills 0:714293de3836 6710 }
ashleymills 0:714293de3836 6711 info->numberPackets = 0;
ashleymills 0:714293de3836 6712 info->timeoutValue.tv_sec = 0;
ashleymills 0:714293de3836 6713 info->timeoutValue.tv_usec = 0;
ashleymills 0:714293de3836 6714 }
ashleymills 0:714293de3836 6715
ashleymills 0:714293de3836 6716
ashleymills 0:714293de3836 6717 /* Free TimeoutInfo */
ashleymills 0:714293de3836 6718 void FreeTimeoutInfo(TimeoutInfo* info, void* heap)
ashleymills 0:714293de3836 6719 {
ashleymills 0:714293de3836 6720 int i;
ashleymills 0:714293de3836 6721 (void)heap;
ashleymills 0:714293de3836 6722 for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
ashleymills 0:714293de3836 6723 if (info->packets[i].bufferValue) {
ashleymills 0:714293de3836 6724 XFREE(info->packets[i].bufferValue, heap, DYNAMIC_TYPE_INFO);
ashleymills 0:714293de3836 6725 info->packets[i].bufferValue = 0;
ashleymills 0:714293de3836 6726 }
ashleymills 0:714293de3836 6727
ashleymills 0:714293de3836 6728 }
ashleymills 0:714293de3836 6729
ashleymills 0:714293de3836 6730
ashleymills 0:714293de3836 6731 /* Add PacketInfo to TimeoutInfo */
ashleymills 0:714293de3836 6732 void AddPacketInfo(const char* name, TimeoutInfo* info, const byte* data,
ashleymills 0:714293de3836 6733 int sz, void* heap)
ashleymills 0:714293de3836 6734 {
ashleymills 0:714293de3836 6735 if (info->numberPackets < (MAX_PACKETS_HANDSHAKE - 1)) {
ashleymills 0:714293de3836 6736 Timeval currTime;
ashleymills 0:714293de3836 6737
ashleymills 0:714293de3836 6738 /* may add name after */
ashleymills 0:714293de3836 6739 if (name)
ashleymills 0:714293de3836 6740 XSTRNCPY(info->packets[info->numberPackets].packetName, name,
ashleymills 0:714293de3836 6741 MAX_PACKETNAME_SZ);
ashleymills 0:714293de3836 6742
ashleymills 0:714293de3836 6743 /* add data, put in buffer if bigger than static buffer */
ashleymills 0:714293de3836 6744 info->packets[info->numberPackets].valueSz = sz;
ashleymills 0:714293de3836 6745 if (sz < MAX_VALUE_SZ)
ashleymills 0:714293de3836 6746 XMEMCPY(info->packets[info->numberPackets].value, data, sz);
ashleymills 0:714293de3836 6747 else {
ashleymills 0:714293de3836 6748 info->packets[info->numberPackets].bufferValue =
ashleymills 0:714293de3836 6749 XMALLOC(sz, heap, DYNAMIC_TYPE_INFO);
ashleymills 0:714293de3836 6750 if (!info->packets[info->numberPackets].bufferValue)
ashleymills 0:714293de3836 6751 /* let next alloc catch, just don't fill, not fatal here */
ashleymills 0:714293de3836 6752 info->packets[info->numberPackets].valueSz = 0;
ashleymills 0:714293de3836 6753 else
ashleymills 0:714293de3836 6754 XMEMCPY(info->packets[info->numberPackets].bufferValue,
ashleymills 0:714293de3836 6755 data, sz);
ashleymills 0:714293de3836 6756 }
ashleymills 0:714293de3836 6757 gettimeofday(&currTime, 0);
ashleymills 0:714293de3836 6758 info->packets[info->numberPackets].timestamp.tv_sec =
ashleymills 0:714293de3836 6759 currTime.tv_sec;
ashleymills 0:714293de3836 6760 info->packets[info->numberPackets].timestamp.tv_usec =
ashleymills 0:714293de3836 6761 currTime.tv_usec;
ashleymills 0:714293de3836 6762 info->numberPackets++;
ashleymills 0:714293de3836 6763 }
ashleymills 0:714293de3836 6764 }
ashleymills 0:714293de3836 6765
ashleymills 0:714293de3836 6766
ashleymills 0:714293de3836 6767 /* Add packet name to previsouly added packet info */
ashleymills 0:714293de3836 6768 void AddLateName(const char* name, TimeoutInfo* info)
ashleymills 0:714293de3836 6769 {
ashleymills 0:714293de3836 6770 /* make sure we have a valid previous one */
ashleymills 0:714293de3836 6771 if (info->numberPackets > 0 && info->numberPackets <
ashleymills 0:714293de3836 6772 MAX_PACKETS_HANDSHAKE) {
ashleymills 0:714293de3836 6773 XSTRNCPY(info->packets[info->numberPackets - 1].packetName, name,
ashleymills 0:714293de3836 6774 MAX_PACKETNAME_SZ);
ashleymills 0:714293de3836 6775 }
ashleymills 0:714293de3836 6776 }
ashleymills 0:714293de3836 6777
ashleymills 0:714293de3836 6778 /* Add record header to previsouly added packet info */
ashleymills 0:714293de3836 6779 void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info)
ashleymills 0:714293de3836 6780 {
ashleymills 0:714293de3836 6781 /* make sure we have a valid previous one */
ashleymills 0:714293de3836 6782 if (info->numberPackets > 0 && info->numberPackets <
ashleymills 0:714293de3836 6783 MAX_PACKETS_HANDSHAKE) {
ashleymills 0:714293de3836 6784 if (info->packets[info->numberPackets - 1].bufferValue)
ashleymills 0:714293de3836 6785 XMEMCPY(info->packets[info->numberPackets - 1].bufferValue, rl,
ashleymills 0:714293de3836 6786 RECORD_HEADER_SZ);
ashleymills 0:714293de3836 6787 else
ashleymills 0:714293de3836 6788 XMEMCPY(info->packets[info->numberPackets - 1].value, rl,
ashleymills 0:714293de3836 6789 RECORD_HEADER_SZ);
ashleymills 0:714293de3836 6790 }
ashleymills 0:714293de3836 6791 }
ashleymills 0:714293de3836 6792
ashleymills 0:714293de3836 6793 #endif /* CYASSL_CALLBACKS */
ashleymills 0:714293de3836 6794
ashleymills 0:714293de3836 6795
ashleymills 0:714293de3836 6796
ashleymills 0:714293de3836 6797 /* client only parts */
ashleymills 0:714293de3836 6798 #ifndef NO_CYASSL_CLIENT
ashleymills 0:714293de3836 6799
ashleymills 0:714293de3836 6800 int SendClientHello(CYASSL* ssl)
ashleymills 0:714293de3836 6801 {
ashleymills 0:714293de3836 6802 byte *output;
ashleymills 0:714293de3836 6803 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 6804 int sendSz;
ashleymills 0:714293de3836 6805 int idSz = ssl->options.resuming ? ID_LEN : 0;
ashleymills 0:714293de3836 6806 int ret;
ashleymills 0:714293de3836 6807
ashleymills 0:714293de3836 6808 if (ssl->suites == NULL) {
ashleymills 0:714293de3836 6809 CYASSL_MSG("Bad suites pointer in SendClientHello");
ashleymills 0:714293de3836 6810 return SUITES_ERROR;
ashleymills 0:714293de3836 6811 }
ashleymills 0:714293de3836 6812
ashleymills 0:714293de3836 6813 length = VERSION_SZ + RAN_LEN
ashleymills 0:714293de3836 6814 + idSz + ENUM_LEN
ashleymills 0:714293de3836 6815 + ssl->suites->suiteSz + SUITE_LEN
ashleymills 0:714293de3836 6816 + COMP_LEN + ENUM_LEN;
ashleymills 0:714293de3836 6817
ashleymills 0:714293de3836 6818 #ifdef HAVE_TLS_EXTENSIONS
ashleymills 0:714293de3836 6819 length += TLSX_GetRequestSize(ssl);
ashleymills 0:714293de3836 6820 #else
ashleymills 0:714293de3836 6821 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) {
ashleymills 0:714293de3836 6822 length += ssl->suites->hashSigAlgoSz + HELLO_EXT_SZ;
ashleymills 0:714293de3836 6823 }
ashleymills 0:714293de3836 6824 #endif
ashleymills 0:714293de3836 6825 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
ashleymills 0:714293de3836 6826
ashleymills 0:714293de3836 6827 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 6828 if (ssl->options.dtls) {
ashleymills 0:714293de3836 6829 length += ENUM_LEN; /* cookie */
ashleymills 0:714293de3836 6830 if (ssl->arrays->cookieSz != 0) length += ssl->arrays->cookieSz;
ashleymills 0:714293de3836 6831 sendSz = length + DTLS_HANDSHAKE_HEADER_SZ + DTLS_RECORD_HEADER_SZ;
ashleymills 0:714293de3836 6832 idx += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
ashleymills 0:714293de3836 6833 }
ashleymills 0:714293de3836 6834 #endif
ashleymills 0:714293de3836 6835
ashleymills 0:714293de3836 6836 /* check for available size */
ashleymills 0:714293de3836 6837 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
ashleymills 0:714293de3836 6838 return ret;
ashleymills 0:714293de3836 6839
ashleymills 0:714293de3836 6840 /* get ouput buffer */
ashleymills 0:714293de3836 6841 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 6842 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 6843
ashleymills 0:714293de3836 6844 AddHeaders(output, length, client_hello, ssl);
ashleymills 0:714293de3836 6845
ashleymills 0:714293de3836 6846 /* client hello, first version */
ashleymills 0:714293de3836 6847 output[idx++] = ssl->version.major;
ashleymills 0:714293de3836 6848 output[idx++] = ssl->version.minor;
ashleymills 0:714293de3836 6849 ssl->chVersion = ssl->version; /* store in case changed */
ashleymills 0:714293de3836 6850
ashleymills 0:714293de3836 6851 /* then random */
ashleymills 0:714293de3836 6852 if (ssl->options.connectState == CONNECT_BEGIN) {
ashleymills 0:714293de3836 6853 RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN);
ashleymills 0:714293de3836 6854
ashleymills 0:714293de3836 6855 /* store random */
ashleymills 0:714293de3836 6856 XMEMCPY(ssl->arrays->clientRandom, output + idx, RAN_LEN);
ashleymills 0:714293de3836 6857 } else {
ashleymills 0:714293de3836 6858 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 6859 /* send same random on hello again */
ashleymills 0:714293de3836 6860 XMEMCPY(output + idx, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 6861 #endif
ashleymills 0:714293de3836 6862 }
ashleymills 0:714293de3836 6863 idx += RAN_LEN;
ashleymills 0:714293de3836 6864
ashleymills 0:714293de3836 6865 /* then session id */
ashleymills 0:714293de3836 6866 output[idx++] = (byte)idSz;
ashleymills 0:714293de3836 6867 if (idSz) {
ashleymills 0:714293de3836 6868 XMEMCPY(output + idx, ssl->session.sessionID, ID_LEN);
ashleymills 0:714293de3836 6869 idx += ID_LEN;
ashleymills 0:714293de3836 6870 }
ashleymills 0:714293de3836 6871
ashleymills 0:714293de3836 6872 /* then DTLS cookie */
ashleymills 0:714293de3836 6873 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 6874 if (ssl->options.dtls) {
ashleymills 0:714293de3836 6875 byte cookieSz = ssl->arrays->cookieSz;
ashleymills 0:714293de3836 6876
ashleymills 0:714293de3836 6877 output[idx++] = cookieSz;
ashleymills 0:714293de3836 6878 if (cookieSz) {
ashleymills 0:714293de3836 6879 XMEMCPY(&output[idx], ssl->arrays->cookie, cookieSz);
ashleymills 0:714293de3836 6880 idx += cookieSz;
ashleymills 0:714293de3836 6881 }
ashleymills 0:714293de3836 6882 }
ashleymills 0:714293de3836 6883 #endif
ashleymills 0:714293de3836 6884 /* then cipher suites */
ashleymills 0:714293de3836 6885 c16toa(ssl->suites->suiteSz, output + idx);
ashleymills 0:714293de3836 6886 idx += 2;
ashleymills 0:714293de3836 6887 XMEMCPY(output + idx, &ssl->suites->suites, ssl->suites->suiteSz);
ashleymills 0:714293de3836 6888 idx += ssl->suites->suiteSz;
ashleymills 0:714293de3836 6889
ashleymills 0:714293de3836 6890 /* last, compression */
ashleymills 0:714293de3836 6891 output[idx++] = COMP_LEN;
ashleymills 0:714293de3836 6892 if (ssl->options.usingCompression)
ashleymills 0:714293de3836 6893 output[idx++] = ZLIB_COMPRESSION;
ashleymills 0:714293de3836 6894 else
ashleymills 0:714293de3836 6895 output[idx++] = NO_COMPRESSION;
ashleymills 0:714293de3836 6896
ashleymills 0:714293de3836 6897 #ifdef HAVE_TLS_EXTENSIONS
ashleymills 0:714293de3836 6898 idx += TLSX_WriteRequest(ssl, output + idx);
ashleymills 0:714293de3836 6899
ashleymills 0:714293de3836 6900 (void)idx; /* suppress analyzer warning, keep idx current */
ashleymills 0:714293de3836 6901 #else
ashleymills 0:714293de3836 6902 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
ashleymills 0:714293de3836 6903 {
ashleymills 0:714293de3836 6904 int i;
ashleymills 0:714293de3836 6905 /* add in the extensions length */
ashleymills 0:714293de3836 6906 c16toa(HELLO_EXT_LEN + ssl->suites->hashSigAlgoSz, output + idx);
ashleymills 0:714293de3836 6907 idx += 2;
ashleymills 0:714293de3836 6908
ashleymills 0:714293de3836 6909 c16toa(HELLO_EXT_SIG_ALGO, output + idx);
ashleymills 0:714293de3836 6910 idx += 2;
ashleymills 0:714293de3836 6911 c16toa(HELLO_EXT_SIGALGO_SZ+ssl->suites->hashSigAlgoSz, output+idx);
ashleymills 0:714293de3836 6912 idx += 2;
ashleymills 0:714293de3836 6913 c16toa(ssl->suites->hashSigAlgoSz, output + idx);
ashleymills 0:714293de3836 6914 idx += 2;
ashleymills 0:714293de3836 6915 for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, idx++) {
ashleymills 0:714293de3836 6916 output[idx] = ssl->suites->hashSigAlgo[i];
ashleymills 0:714293de3836 6917 }
ashleymills 0:714293de3836 6918 }
ashleymills 0:714293de3836 6919 #endif
ashleymills 0:714293de3836 6920
ashleymills 0:714293de3836 6921 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 6922 if (ssl->options.dtls) {
ashleymills 0:714293de3836 6923 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:714293de3836 6924 return ret;
ashleymills 0:714293de3836 6925 }
ashleymills 0:714293de3836 6926 #endif
ashleymills 0:714293de3836 6927 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:714293de3836 6928
ashleymills 0:714293de3836 6929 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
ashleymills 0:714293de3836 6930
ashleymills 0:714293de3836 6931 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 6932 if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
ashleymills 0:714293de3836 6933 if (ssl->toInfoOn)
ashleymills 0:714293de3836 6934 AddPacketInfo("ClientHello", &ssl->timeoutInfo, output, sendSz,
ashleymills 0:714293de3836 6935 ssl->heap);
ashleymills 0:714293de3836 6936 #endif
ashleymills 0:714293de3836 6937
ashleymills 0:714293de3836 6938 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:714293de3836 6939
ashleymills 0:714293de3836 6940 return SendBuffered(ssl);
ashleymills 0:714293de3836 6941 }
ashleymills 0:714293de3836 6942
ashleymills 0:714293de3836 6943
ashleymills 0:714293de3836 6944 static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input,
ashleymills 0:714293de3836 6945 word32* inOutIdx)
ashleymills 0:714293de3836 6946 {
ashleymills 0:714293de3836 6947 ProtocolVersion pv;
ashleymills 0:714293de3836 6948 byte cookieSz;
ashleymills 0:714293de3836 6949
ashleymills 0:714293de3836 6950 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 6951 if (ssl->hsInfoOn) AddPacketName("HelloVerifyRequest",
ashleymills 0:714293de3836 6952 &ssl->handShakeInfo);
ashleymills 0:714293de3836 6953 if (ssl->toInfoOn) AddLateName("HelloVerifyRequest", &ssl->timeoutInfo);
ashleymills 0:714293de3836 6954 #endif
ashleymills 0:714293de3836 6955 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 6956 if (ssl->options.dtls) {
ashleymills 0:714293de3836 6957 DtlsPoolReset(ssl);
ashleymills 0:714293de3836 6958 }
ashleymills 0:714293de3836 6959 #endif
ashleymills 0:714293de3836 6960 XMEMCPY(&pv, input + *inOutIdx, sizeof(pv));
ashleymills 0:714293de3836 6961 *inOutIdx += (word32)sizeof(pv);
ashleymills 0:714293de3836 6962
ashleymills 0:714293de3836 6963 cookieSz = input[(*inOutIdx)++];
ashleymills 0:714293de3836 6964
ashleymills 0:714293de3836 6965 if (cookieSz) {
ashleymills 0:714293de3836 6966 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 6967 if (cookieSz <= MAX_COOKIE_LEN) {
ashleymills 0:714293de3836 6968 XMEMCPY(ssl->arrays->cookie, input + *inOutIdx, cookieSz);
ashleymills 0:714293de3836 6969 ssl->arrays->cookieSz = cookieSz;
ashleymills 0:714293de3836 6970 }
ashleymills 0:714293de3836 6971 #endif
ashleymills 0:714293de3836 6972 *inOutIdx += cookieSz;
ashleymills 0:714293de3836 6973 }
ashleymills 0:714293de3836 6974
ashleymills 0:714293de3836 6975 ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
ashleymills 0:714293de3836 6976 return 0;
ashleymills 0:714293de3836 6977 }
ashleymills 0:714293de3836 6978
ashleymills 0:714293de3836 6979
ashleymills 0:714293de3836 6980 static int DoServerHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
ashleymills 0:714293de3836 6981 word32 helloSz)
ashleymills 0:714293de3836 6982 {
ashleymills 0:714293de3836 6983 byte b;
ashleymills 0:714293de3836 6984 byte compression;
ashleymills 0:714293de3836 6985 ProtocolVersion pv;
ashleymills 0:714293de3836 6986 word32 i = *inOutIdx;
ashleymills 0:714293de3836 6987 word32 begin = i;
ashleymills 0:714293de3836 6988
ashleymills 0:714293de3836 6989 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 6990 if (ssl->hsInfoOn) AddPacketName("ServerHello", &ssl->handShakeInfo);
ashleymills 0:714293de3836 6991 if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
ashleymills 0:714293de3836 6992 #endif
ashleymills 0:714293de3836 6993 XMEMCPY(&pv, input + i, sizeof(pv));
ashleymills 0:714293de3836 6994 i += (word32)sizeof(pv);
ashleymills 0:714293de3836 6995 if (pv.minor > ssl->version.minor) {
ashleymills 0:714293de3836 6996 CYASSL_MSG("Server using higher version, fatal error");
ashleymills 0:714293de3836 6997 return VERSION_ERROR;
ashleymills 0:714293de3836 6998 }
ashleymills 0:714293de3836 6999 else if (pv.minor < ssl->version.minor) {
ashleymills 0:714293de3836 7000 CYASSL_MSG("server using lower version");
ashleymills 0:714293de3836 7001 if (!ssl->options.downgrade) {
ashleymills 0:714293de3836 7002 CYASSL_MSG(" no downgrade allowed, fatal error");
ashleymills 0:714293de3836 7003 return VERSION_ERROR;
ashleymills 0:714293de3836 7004 }
ashleymills 0:714293de3836 7005 else if (pv.minor == SSLv3_MINOR) {
ashleymills 0:714293de3836 7006 /* turn off tls */
ashleymills 0:714293de3836 7007 CYASSL_MSG(" downgrading to SSLv3");
ashleymills 0:714293de3836 7008 ssl->options.tls = 0;
ashleymills 0:714293de3836 7009 ssl->options.tls1_1 = 0;
ashleymills 0:714293de3836 7010 ssl->version.minor = SSLv3_MINOR;
ashleymills 0:714293de3836 7011 }
ashleymills 0:714293de3836 7012 else if (pv.minor == TLSv1_MINOR) {
ashleymills 0:714293de3836 7013 /* turn off tls 1.1+ */
ashleymills 0:714293de3836 7014 CYASSL_MSG(" downgrading to TLSv1");
ashleymills 0:714293de3836 7015 ssl->options.tls1_1 = 0;
ashleymills 0:714293de3836 7016 ssl->version.minor = TLSv1_MINOR;
ashleymills 0:714293de3836 7017 }
ashleymills 0:714293de3836 7018 else if (pv.minor == TLSv1_1_MINOR) {
ashleymills 0:714293de3836 7019 CYASSL_MSG(" downgrading to TLSv1.1");
ashleymills 0:714293de3836 7020 ssl->version.minor = TLSv1_1_MINOR;
ashleymills 0:714293de3836 7021 }
ashleymills 0:714293de3836 7022 }
ashleymills 0:714293de3836 7023 XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN);
ashleymills 0:714293de3836 7024 i += RAN_LEN;
ashleymills 0:714293de3836 7025 b = input[i++];
ashleymills 0:714293de3836 7026 if (b) {
ashleymills 0:714293de3836 7027 XMEMCPY(ssl->arrays->sessionID, input + i, min(b, ID_LEN));
ashleymills 0:714293de3836 7028 i += b;
ashleymills 0:714293de3836 7029 ssl->options.haveSessionId = 1;
ashleymills 0:714293de3836 7030 }
ashleymills 0:714293de3836 7031 ssl->options.cipherSuite0 = input[i++];
ashleymills 0:714293de3836 7032 ssl->options.cipherSuite = input[i++];
ashleymills 0:714293de3836 7033 compression = input[i++];
ashleymills 0:714293de3836 7034
ashleymills 0:714293de3836 7035 if (compression != ZLIB_COMPRESSION && ssl->options.usingCompression) {
ashleymills 0:714293de3836 7036 CYASSL_MSG("Server refused compression, turning off");
ashleymills 0:714293de3836 7037 ssl->options.usingCompression = 0; /* turn off if server refused */
ashleymills 0:714293de3836 7038 }
ashleymills 0:714293de3836 7039
ashleymills 0:714293de3836 7040 *inOutIdx = i;
ashleymills 0:714293de3836 7041 if ( (i - begin) < helloSz) {
ashleymills 0:714293de3836 7042 #ifdef HAVE_TLS_EXTENSIONS
ashleymills 0:714293de3836 7043 if (IsTLS(ssl)) {
ashleymills 0:714293de3836 7044 int ret = 0;
ashleymills 0:714293de3836 7045 word16 totalExtSz;
ashleymills 0:714293de3836 7046 Suites clSuites; /* just for compatibility right now */
ashleymills 0:714293de3836 7047
ashleymills 0:714293de3836 7048 ato16(&input[i], &totalExtSz);
ashleymills 0:714293de3836 7049 i += LENGTH_SZ;
ashleymills 0:714293de3836 7050 if (totalExtSz > helloSz + begin - i)
ashleymills 0:714293de3836 7051 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 7052
ashleymills 0:714293de3836 7053 if ((ret = TLSX_Parse(ssl, (byte *) input + i,
ashleymills 0:714293de3836 7054 totalExtSz, 0, &clSuites)))
ashleymills 0:714293de3836 7055 return ret;
ashleymills 0:714293de3836 7056
ashleymills 0:714293de3836 7057 i += totalExtSz;
ashleymills 0:714293de3836 7058 *inOutIdx = i;
ashleymills 0:714293de3836 7059 }
ashleymills 0:714293de3836 7060 else
ashleymills 0:714293de3836 7061 #endif
ashleymills 0:714293de3836 7062 *inOutIdx = begin + helloSz; /* skip extensions */
ashleymills 0:714293de3836 7063 }
ashleymills 0:714293de3836 7064
ashleymills 0:714293de3836 7065 ssl->options.serverState = SERVER_HELLO_COMPLETE;
ashleymills 0:714293de3836 7066
ashleymills 0:714293de3836 7067 if (ssl->options.resuming) {
ashleymills 0:714293de3836 7068 if (ssl->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID,
ashleymills 0:714293de3836 7069 ssl->session.sessionID, ID_LEN) == 0) {
ashleymills 0:714293de3836 7070 if (SetCipherSpecs(ssl) == 0) {
ashleymills 0:714293de3836 7071 int ret = -1;
ashleymills 0:714293de3836 7072 XMEMCPY(ssl->arrays->masterSecret,
ashleymills 0:714293de3836 7073 ssl->session.masterSecret, SECRET_LEN);
ashleymills 0:714293de3836 7074 #ifdef NO_OLD_TLS
ashleymills 0:714293de3836 7075 ret = DeriveTlsKeys(ssl);
ashleymills 0:714293de3836 7076 #else
ashleymills 0:714293de3836 7077 #ifndef NO_TLS
ashleymills 0:714293de3836 7078 if (ssl->options.tls)
ashleymills 0:714293de3836 7079 ret = DeriveTlsKeys(ssl);
ashleymills 0:714293de3836 7080 #endif
ashleymills 0:714293de3836 7081 if (!ssl->options.tls)
ashleymills 0:714293de3836 7082 ret = DeriveKeys(ssl);
ashleymills 0:714293de3836 7083 #endif
ashleymills 0:714293de3836 7084 ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
ashleymills 0:714293de3836 7085 return ret;
ashleymills 0:714293de3836 7086 }
ashleymills 0:714293de3836 7087 else {
ashleymills 0:714293de3836 7088 CYASSL_MSG("Unsupported cipher suite, DoServerHello");
ashleymills 0:714293de3836 7089 return UNSUPPORTED_SUITE;
ashleymills 0:714293de3836 7090 }
ashleymills 0:714293de3836 7091 }
ashleymills 0:714293de3836 7092 else {
ashleymills 0:714293de3836 7093 CYASSL_MSG("Server denied resumption attempt");
ashleymills 0:714293de3836 7094 ssl->options.resuming = 0; /* server denied resumption try */
ashleymills 0:714293de3836 7095 }
ashleymills 0:714293de3836 7096 }
ashleymills 0:714293de3836 7097 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 7098 if (ssl->options.dtls) {
ashleymills 0:714293de3836 7099 DtlsPoolReset(ssl);
ashleymills 0:714293de3836 7100 }
ashleymills 0:714293de3836 7101 #endif
ashleymills 0:714293de3836 7102 return SetCipherSpecs(ssl);
ashleymills 0:714293de3836 7103 }
ashleymills 0:714293de3836 7104
ashleymills 0:714293de3836 7105
ashleymills 0:714293de3836 7106 #ifndef NO_CERTS
ashleymills 0:714293de3836 7107 /* just read in and ignore for now TODO: */
ashleymills 0:714293de3836 7108 static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32*
ashleymills 0:714293de3836 7109 inOutIdx)
ashleymills 0:714293de3836 7110 {
ashleymills 0:714293de3836 7111 word16 len;
ashleymills 0:714293de3836 7112
ashleymills 0:714293de3836 7113 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 7114 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 7115 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
ashleymills 0:714293de3836 7116 if (ssl->toInfoOn)
ashleymills 0:714293de3836 7117 AddLateName("CertificateRequest", &ssl->timeoutInfo);
ashleymills 0:714293de3836 7118 #endif
ashleymills 0:714293de3836 7119 len = input[(*inOutIdx)++];
ashleymills 0:714293de3836 7120
ashleymills 0:714293de3836 7121 /* types, read in here */
ashleymills 0:714293de3836 7122 *inOutIdx += len;
ashleymills 0:714293de3836 7123
ashleymills 0:714293de3836 7124 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 7125 /* hash sig format */
ashleymills 0:714293de3836 7126 ato16(&input[*inOutIdx], &len);
ashleymills 0:714293de3836 7127 *inOutIdx += LENGTH_SZ;
ashleymills 0:714293de3836 7128 PickHashSigAlgo(ssl, &input[*inOutIdx], len);
ashleymills 0:714293de3836 7129 *inOutIdx += len;
ashleymills 0:714293de3836 7130 }
ashleymills 0:714293de3836 7131
ashleymills 0:714293de3836 7132 /* authorities */
ashleymills 0:714293de3836 7133 ato16(&input[*inOutIdx], &len);
ashleymills 0:714293de3836 7134 *inOutIdx += LENGTH_SZ;
ashleymills 0:714293de3836 7135 while (len) {
ashleymills 0:714293de3836 7136 word16 dnSz;
ashleymills 0:714293de3836 7137
ashleymills 0:714293de3836 7138 ato16(&input[*inOutIdx], &dnSz);
ashleymills 0:714293de3836 7139 *inOutIdx += (REQUEST_HEADER + dnSz);
ashleymills 0:714293de3836 7140 len -= dnSz + REQUEST_HEADER;
ashleymills 0:714293de3836 7141 }
ashleymills 0:714293de3836 7142
ashleymills 0:714293de3836 7143 /* don't send client cert or cert verify if user hasn't provided
ashleymills 0:714293de3836 7144 cert and private key */
ashleymills 0:714293de3836 7145 if (ssl->buffers.certificate.buffer && ssl->buffers.key.buffer)
ashleymills 0:714293de3836 7146 ssl->options.sendVerify = SEND_CERT;
ashleymills 0:714293de3836 7147 else if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:714293de3836 7148 ssl->options.sendVerify = SEND_BLANK_CERT;
ashleymills 0:714293de3836 7149
ashleymills 0:714293de3836 7150 return 0;
ashleymills 0:714293de3836 7151 }
ashleymills 0:714293de3836 7152 #endif /* !NO_CERTS */
ashleymills 0:714293de3836 7153
ashleymills 0:714293de3836 7154
ashleymills 0:714293de3836 7155 static int DoServerKeyExchange(CYASSL* ssl, const byte* input,
ashleymills 0:714293de3836 7156 word32* inOutIdx)
ashleymills 0:714293de3836 7157 {
ashleymills 0:714293de3836 7158 #if defined(OPENSSL_EXTRA) || defined(HAVE_ECC)
ashleymills 0:714293de3836 7159 word16 length = 0;
ashleymills 0:714293de3836 7160 word16 sigLen = 0;
ashleymills 0:714293de3836 7161 word16 verifySz = (word16)*inOutIdx; /* keep start idx */
ashleymills 0:714293de3836 7162 byte* signature = 0;
ashleymills 0:714293de3836 7163 #endif
ashleymills 0:714293de3836 7164
ashleymills 0:714293de3836 7165 (void)ssl;
ashleymills 0:714293de3836 7166 (void)input;
ashleymills 0:714293de3836 7167 (void)inOutIdx;
ashleymills 0:714293de3836 7168
ashleymills 0:714293de3836 7169 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 7170 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 7171 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
ashleymills 0:714293de3836 7172 if (ssl->toInfoOn)
ashleymills 0:714293de3836 7173 AddLateName("ServerKeyExchange", &ssl->timeoutInfo);
ashleymills 0:714293de3836 7174 #endif
ashleymills 0:714293de3836 7175
ashleymills 0:714293de3836 7176 #ifndef NO_PSK
ashleymills 0:714293de3836 7177 if (ssl->specs.kea == psk_kea) {
ashleymills 0:714293de3836 7178 word16 pskLen = 0;
ashleymills 0:714293de3836 7179 ato16(&input[*inOutIdx], &pskLen);
ashleymills 0:714293de3836 7180 *inOutIdx += LENGTH_SZ;
ashleymills 0:714293de3836 7181 XMEMCPY(ssl->arrays->server_hint, &input[*inOutIdx],
ashleymills 0:714293de3836 7182 min(pskLen, MAX_PSK_ID_LEN));
ashleymills 0:714293de3836 7183 if (pskLen < MAX_PSK_ID_LEN)
ashleymills 0:714293de3836 7184 ssl->arrays->server_hint[pskLen] = 0;
ashleymills 0:714293de3836 7185 else
ashleymills 0:714293de3836 7186 ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = 0;
ashleymills 0:714293de3836 7187 *inOutIdx += pskLen;
ashleymills 0:714293de3836 7188
ashleymills 0:714293de3836 7189 return 0;
ashleymills 0:714293de3836 7190 }
ashleymills 0:714293de3836 7191 #endif
ashleymills 0:714293de3836 7192 #ifdef OPENSSL_EXTRA
ashleymills 0:714293de3836 7193 if (ssl->specs.kea == diffie_hellman_kea)
ashleymills 0:714293de3836 7194 {
ashleymills 0:714293de3836 7195 /* p */
ashleymills 0:714293de3836 7196 ato16(&input[*inOutIdx], &length);
ashleymills 0:714293de3836 7197 *inOutIdx += LENGTH_SZ;
ashleymills 0:714293de3836 7198
ashleymills 0:714293de3836 7199 ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
ashleymills 0:714293de3836 7200 DYNAMIC_TYPE_DH);
ashleymills 0:714293de3836 7201 if (ssl->buffers.serverDH_P.buffer)
ashleymills 0:714293de3836 7202 ssl->buffers.serverDH_P.length = length;
ashleymills 0:714293de3836 7203 else
ashleymills 0:714293de3836 7204 return MEMORY_ERROR;
ashleymills 0:714293de3836 7205 XMEMCPY(ssl->buffers.serverDH_P.buffer, &input[*inOutIdx], length);
ashleymills 0:714293de3836 7206 *inOutIdx += length;
ashleymills 0:714293de3836 7207
ashleymills 0:714293de3836 7208 /* g */
ashleymills 0:714293de3836 7209 ato16(&input[*inOutIdx], &length);
ashleymills 0:714293de3836 7210 *inOutIdx += LENGTH_SZ;
ashleymills 0:714293de3836 7211
ashleymills 0:714293de3836 7212 ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
ashleymills 0:714293de3836 7213 DYNAMIC_TYPE_DH);
ashleymills 0:714293de3836 7214 if (ssl->buffers.serverDH_G.buffer)
ashleymills 0:714293de3836 7215 ssl->buffers.serverDH_G.length = length;
ashleymills 0:714293de3836 7216 else
ashleymills 0:714293de3836 7217 return MEMORY_ERROR;
ashleymills 0:714293de3836 7218 XMEMCPY(ssl->buffers.serverDH_G.buffer, &input[*inOutIdx], length);
ashleymills 0:714293de3836 7219 *inOutIdx += length;
ashleymills 0:714293de3836 7220
ashleymills 0:714293de3836 7221 /* pub */
ashleymills 0:714293de3836 7222 ato16(&input[*inOutIdx], &length);
ashleymills 0:714293de3836 7223 *inOutIdx += LENGTH_SZ;
ashleymills 0:714293de3836 7224
ashleymills 0:714293de3836 7225 ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap,
ashleymills 0:714293de3836 7226 DYNAMIC_TYPE_DH);
ashleymills 0:714293de3836 7227 if (ssl->buffers.serverDH_Pub.buffer)
ashleymills 0:714293de3836 7228 ssl->buffers.serverDH_Pub.length = length;
ashleymills 0:714293de3836 7229 else
ashleymills 0:714293de3836 7230 return MEMORY_ERROR;
ashleymills 0:714293de3836 7231 XMEMCPY(ssl->buffers.serverDH_Pub.buffer, &input[*inOutIdx], length);
ashleymills 0:714293de3836 7232 *inOutIdx += length;
ashleymills 0:714293de3836 7233 } /* dh_kea */
ashleymills 0:714293de3836 7234 #endif /* OPENSSL_EXTRA */
ashleymills 0:714293de3836 7235
ashleymills 0:714293de3836 7236 #ifdef HAVE_ECC
ashleymills 0:714293de3836 7237 if (ssl->specs.kea == ecc_diffie_hellman_kea)
ashleymills 0:714293de3836 7238 {
ashleymills 0:714293de3836 7239 byte b = input[*inOutIdx];
ashleymills 0:714293de3836 7240 *inOutIdx += 1;
ashleymills 0:714293de3836 7241
ashleymills 0:714293de3836 7242 if (b != named_curve)
ashleymills 0:714293de3836 7243 return ECC_CURVETYPE_ERROR;
ashleymills 0:714293de3836 7244
ashleymills 0:714293de3836 7245 *inOutIdx += 1; /* curve type, eat leading 0 */
ashleymills 0:714293de3836 7246 b = input[*inOutIdx];
ashleymills 0:714293de3836 7247 *inOutIdx += 1;
ashleymills 0:714293de3836 7248
ashleymills 0:714293de3836 7249 if (b != secp256r1 && b != secp384r1 && b != secp521r1 && b !=
ashleymills 0:714293de3836 7250 secp160r1 && b != secp192r1 && b != secp224r1)
ashleymills 0:714293de3836 7251 return ECC_CURVE_ERROR;
ashleymills 0:714293de3836 7252
ashleymills 0:714293de3836 7253 length = input[*inOutIdx];
ashleymills 0:714293de3836 7254 *inOutIdx += 1;
ashleymills 0:714293de3836 7255
ashleymills 0:714293de3836 7256 if (ecc_import_x963(&input[*inOutIdx], length, ssl->peerEccKey) != 0)
ashleymills 0:714293de3836 7257 return ECC_PEERKEY_ERROR;
ashleymills 0:714293de3836 7258
ashleymills 0:714293de3836 7259 *inOutIdx += length;
ashleymills 0:714293de3836 7260 ssl->peerEccKeyPresent = 1;
ashleymills 0:714293de3836 7261 }
ashleymills 0:714293de3836 7262 #endif /* HAVE_ECC */
ashleymills 0:714293de3836 7263
ashleymills 0:714293de3836 7264 #if defined(OPENSSL_EXTRA) || defined(HAVE_ECC)
ashleymills 0:714293de3836 7265 {
ashleymills 0:714293de3836 7266 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 7267 Md5 md5;
ashleymills 0:714293de3836 7268 Sha sha;
ashleymills 0:714293de3836 7269 #endif
ashleymills 0:714293de3836 7270 byte hash[FINISHED_SZ];
ashleymills 0:714293de3836 7271 #ifndef NO_SHA256
ashleymills 0:714293de3836 7272 Sha256 sha256;
ashleymills 0:714293de3836 7273 byte hash256[SHA256_DIGEST_SIZE];
ashleymills 0:714293de3836 7274 #endif
ashleymills 0:714293de3836 7275 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 7276 Sha384 sha384;
ashleymills 0:714293de3836 7277 byte hash384[SHA384_DIGEST_SIZE];
ashleymills 0:714293de3836 7278 #endif
ashleymills 0:714293de3836 7279 byte messageVerify[MAX_DH_SZ];
ashleymills 0:714293de3836 7280 byte hashAlgo = sha_mac;
ashleymills 0:714293de3836 7281 byte sigAlgo = ssl->specs.sig_algo;
ashleymills 0:714293de3836 7282
ashleymills 0:714293de3836 7283 /* adjust from start idx */
ashleymills 0:714293de3836 7284 verifySz = (word16)(*inOutIdx - verifySz);
ashleymills 0:714293de3836 7285
ashleymills 0:714293de3836 7286 /* save message for hash verify */
ashleymills 0:714293de3836 7287 if (verifySz > sizeof(messageVerify))
ashleymills 0:714293de3836 7288 return BUFFER_ERROR;
ashleymills 0:714293de3836 7289 XMEMCPY(messageVerify, &input[*inOutIdx - verifySz], verifySz);
ashleymills 0:714293de3836 7290
ashleymills 0:714293de3836 7291 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 7292 hashAlgo = input[*inOutIdx];
ashleymills 0:714293de3836 7293 *inOutIdx += 1;
ashleymills 0:714293de3836 7294 sigAlgo = input[*inOutIdx];
ashleymills 0:714293de3836 7295 *inOutIdx += 1;
ashleymills 0:714293de3836 7296 }
ashleymills 0:714293de3836 7297
ashleymills 0:714293de3836 7298 /* signature */
ashleymills 0:714293de3836 7299 ato16(&input[*inOutIdx], &length);
ashleymills 0:714293de3836 7300 *inOutIdx += LENGTH_SZ;
ashleymills 0:714293de3836 7301
ashleymills 0:714293de3836 7302 signature = (byte*)&input[*inOutIdx];
ashleymills 0:714293de3836 7303 *inOutIdx += length;
ashleymills 0:714293de3836 7304 sigLen = length;
ashleymills 0:714293de3836 7305
ashleymills 0:714293de3836 7306 /* verify signature */
ashleymills 0:714293de3836 7307 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 7308 /* md5 */
ashleymills 0:714293de3836 7309 InitMd5(&md5);
ashleymills 0:714293de3836 7310 Md5Update(&md5, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 7311 Md5Update(&md5, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 7312 Md5Update(&md5, messageVerify, verifySz);
ashleymills 0:714293de3836 7313 Md5Final(&md5, hash);
ashleymills 0:714293de3836 7314
ashleymills 0:714293de3836 7315 /* sha */
ashleymills 0:714293de3836 7316 InitSha(&sha);
ashleymills 0:714293de3836 7317 ShaUpdate(&sha, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 7318 ShaUpdate(&sha, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 7319 ShaUpdate(&sha, messageVerify, verifySz);
ashleymills 0:714293de3836 7320 ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
ashleymills 0:714293de3836 7321 #endif
ashleymills 0:714293de3836 7322 #ifndef NO_SHA256
ashleymills 0:714293de3836 7323 InitSha256(&sha256);
ashleymills 0:714293de3836 7324 Sha256Update(&sha256, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 7325 Sha256Update(&sha256, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 7326 Sha256Update(&sha256, messageVerify, verifySz);
ashleymills 0:714293de3836 7327 Sha256Final(&sha256, hash256);
ashleymills 0:714293de3836 7328 #endif
ashleymills 0:714293de3836 7329
ashleymills 0:714293de3836 7330 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 7331 InitSha384(&sha384);
ashleymills 0:714293de3836 7332 Sha384Update(&sha384, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 7333 Sha384Update(&sha384, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 7334 Sha384Update(&sha384, messageVerify, verifySz);
ashleymills 0:714293de3836 7335 Sha384Final(&sha384, hash384);
ashleymills 0:714293de3836 7336 #endif
ashleymills 0:714293de3836 7337 #ifndef NO_RSA
ashleymills 0:714293de3836 7338 /* rsa */
ashleymills 0:714293de3836 7339 if (sigAlgo == rsa_sa_algo)
ashleymills 0:714293de3836 7340 {
ashleymills 0:714293de3836 7341 int ret;
ashleymills 0:714293de3836 7342 byte* out;
ashleymills 0:714293de3836 7343
ashleymills 0:714293de3836 7344 if (!ssl->peerRsaKeyPresent)
ashleymills 0:714293de3836 7345 return NO_PEER_KEY;
ashleymills 0:714293de3836 7346
ashleymills 0:714293de3836 7347 ret = RsaSSL_VerifyInline(signature, sigLen,&out, ssl->peerRsaKey);
ashleymills 0:714293de3836 7348
ashleymills 0:714293de3836 7349 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 7350 byte encodedSig[MAX_ENCODED_SIG_SZ];
ashleymills 0:714293de3836 7351 word32 encSigSz;
ashleymills 0:714293de3836 7352 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 7353 byte* digest = &hash[MD5_DIGEST_SIZE];
ashleymills 0:714293de3836 7354 int typeH = SHAh;
ashleymills 0:714293de3836 7355 int digestSz = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 7356 #else
ashleymills 0:714293de3836 7357 byte* digest = hash256;
ashleymills 0:714293de3836 7358 int typeH = SHA256h;
ashleymills 0:714293de3836 7359 int digestSz = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 7360 #endif
ashleymills 0:714293de3836 7361
ashleymills 0:714293de3836 7362 if (hashAlgo == sha_mac) {
ashleymills 0:714293de3836 7363 #ifndef NO_SHA
ashleymills 0:714293de3836 7364 digest = &hash[MD5_DIGEST_SIZE];
ashleymills 0:714293de3836 7365 typeH = SHAh;
ashleymills 0:714293de3836 7366 digestSz = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 7367 #endif
ashleymills 0:714293de3836 7368 }
ashleymills 0:714293de3836 7369 else if (hashAlgo == sha256_mac) {
ashleymills 0:714293de3836 7370 #ifndef NO_SHA256
ashleymills 0:714293de3836 7371 digest = hash256;
ashleymills 0:714293de3836 7372 typeH = SHA256h;
ashleymills 0:714293de3836 7373 digestSz = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 7374 #endif
ashleymills 0:714293de3836 7375 }
ashleymills 0:714293de3836 7376 else if (hashAlgo == sha384_mac) {
ashleymills 0:714293de3836 7377 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 7378 digest = hash384;
ashleymills 0:714293de3836 7379 typeH = SHA384h;
ashleymills 0:714293de3836 7380 digestSz = SHA384_DIGEST_SIZE;
ashleymills 0:714293de3836 7381 #endif
ashleymills 0:714293de3836 7382 }
ashleymills 0:714293de3836 7383
ashleymills 0:714293de3836 7384 encSigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
ashleymills 0:714293de3836 7385
ashleymills 0:714293de3836 7386 if (encSigSz != (word32)ret || XMEMCMP(out, encodedSig,
ashleymills 0:714293de3836 7387 min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0)
ashleymills 0:714293de3836 7388 return VERIFY_SIGN_ERROR;
ashleymills 0:714293de3836 7389 }
ashleymills 0:714293de3836 7390 else {
ashleymills 0:714293de3836 7391 if (ret != sizeof(hash) || XMEMCMP(out, hash,sizeof(hash)) != 0)
ashleymills 0:714293de3836 7392 return VERIFY_SIGN_ERROR;
ashleymills 0:714293de3836 7393 }
ashleymills 0:714293de3836 7394 } else
ashleymills 0:714293de3836 7395 #endif
ashleymills 0:714293de3836 7396 #ifdef HAVE_ECC
ashleymills 0:714293de3836 7397 /* ecdsa */
ashleymills 0:714293de3836 7398 if (sigAlgo == ecc_dsa_sa_algo) {
ashleymills 0:714293de3836 7399 int verify = 0, ret;
ashleymills 0:714293de3836 7400 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 7401 byte* digest = &hash[MD5_DIGEST_SIZE];
ashleymills 0:714293de3836 7402 word32 digestSz = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 7403 #else
ashleymills 0:714293de3836 7404 byte* digest = hash256;
ashleymills 0:714293de3836 7405 word32 digestSz = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 7406 #endif
ashleymills 0:714293de3836 7407 if (!ssl->peerEccDsaKeyPresent)
ashleymills 0:714293de3836 7408 return NO_PEER_KEY;
ashleymills 0:714293de3836 7409
ashleymills 0:714293de3836 7410 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 7411 if (hashAlgo == sha_mac) {
ashleymills 0:714293de3836 7412 #ifndef NO_SHA
ashleymills 0:714293de3836 7413 digest = &hash[MD5_DIGEST_SIZE];
ashleymills 0:714293de3836 7414 digestSz = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 7415 #endif
ashleymills 0:714293de3836 7416 }
ashleymills 0:714293de3836 7417 else if (hashAlgo == sha256_mac) {
ashleymills 0:714293de3836 7418 #ifndef NO_SHA256
ashleymills 0:714293de3836 7419 digest = hash256;
ashleymills 0:714293de3836 7420 digestSz = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 7421 #endif
ashleymills 0:714293de3836 7422 }
ashleymills 0:714293de3836 7423 else if (hashAlgo == sha384_mac) {
ashleymills 0:714293de3836 7424 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 7425 digest = hash384;
ashleymills 0:714293de3836 7426 digestSz = SHA384_DIGEST_SIZE;
ashleymills 0:714293de3836 7427 #endif
ashleymills 0:714293de3836 7428 }
ashleymills 0:714293de3836 7429 }
ashleymills 0:714293de3836 7430
ashleymills 0:714293de3836 7431 ret = ecc_verify_hash(signature, sigLen, digest, digestSz,
ashleymills 0:714293de3836 7432 &verify, ssl->peerEccDsaKey);
ashleymills 0:714293de3836 7433 if (ret != 0 || verify == 0)
ashleymills 0:714293de3836 7434 return VERIFY_SIGN_ERROR;
ashleymills 0:714293de3836 7435 }
ashleymills 0:714293de3836 7436 else
ashleymills 0:714293de3836 7437 #endif /* HAVE_ECC */
ashleymills 0:714293de3836 7438 return ALGO_ID_E;
ashleymills 0:714293de3836 7439
ashleymills 0:714293de3836 7440 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
ashleymills 0:714293de3836 7441
ashleymills 0:714293de3836 7442 return 0;
ashleymills 0:714293de3836 7443
ashleymills 0:714293de3836 7444 }
ashleymills 0:714293de3836 7445 #else /* HAVE_OPENSSL or HAVE_ECC */
ashleymills 0:714293de3836 7446 return NOT_COMPILED_IN; /* not supported by build */
ashleymills 0:714293de3836 7447 #endif /* HAVE_OPENSSL or HAVE_ECC */
ashleymills 0:714293de3836 7448 }
ashleymills 0:714293de3836 7449
ashleymills 0:714293de3836 7450
ashleymills 0:714293de3836 7451 int SendClientKeyExchange(CYASSL* ssl)
ashleymills 0:714293de3836 7452 {
ashleymills 0:714293de3836 7453 byte encSecret[MAX_ENCRYPT_SZ];
ashleymills 0:714293de3836 7454 word32 encSz = 0;
ashleymills 0:714293de3836 7455 word32 idx = 0;
ashleymills 0:714293de3836 7456 int ret = 0;
ashleymills 0:714293de3836 7457
ashleymills 0:714293de3836 7458 switch (ssl->specs.kea) {
ashleymills 0:714293de3836 7459 #ifndef NO_RSA
ashleymills 0:714293de3836 7460 case rsa_kea:
ashleymills 0:714293de3836 7461 RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret,
ashleymills 0:714293de3836 7462 SECRET_LEN);
ashleymills 0:714293de3836 7463 ssl->arrays->preMasterSecret[0] = ssl->chVersion.major;
ashleymills 0:714293de3836 7464 ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor;
ashleymills 0:714293de3836 7465 ssl->arrays->preMasterSz = SECRET_LEN;
ashleymills 0:714293de3836 7466
ashleymills 0:714293de3836 7467 if (ssl->peerRsaKeyPresent == 0)
ashleymills 0:714293de3836 7468 return NO_PEER_KEY;
ashleymills 0:714293de3836 7469
ashleymills 0:714293de3836 7470 ret = RsaPublicEncrypt(ssl->arrays->preMasterSecret, SECRET_LEN,
ashleymills 0:714293de3836 7471 encSecret, sizeof(encSecret), ssl->peerRsaKey,
ashleymills 0:714293de3836 7472 ssl->rng);
ashleymills 0:714293de3836 7473 if (ret > 0) {
ashleymills 0:714293de3836 7474 encSz = ret;
ashleymills 0:714293de3836 7475 ret = 0; /* set success to 0 */
ashleymills 0:714293de3836 7476 }
ashleymills 0:714293de3836 7477 break;
ashleymills 0:714293de3836 7478 #endif
ashleymills 0:714293de3836 7479 #ifdef OPENSSL_EXTRA
ashleymills 0:714293de3836 7480 case diffie_hellman_kea:
ashleymills 0:714293de3836 7481 {
ashleymills 0:714293de3836 7482 buffer serverP = ssl->buffers.serverDH_P;
ashleymills 0:714293de3836 7483 buffer serverG = ssl->buffers.serverDH_G;
ashleymills 0:714293de3836 7484 buffer serverPub = ssl->buffers.serverDH_Pub;
ashleymills 0:714293de3836 7485 byte priv[ENCRYPT_LEN];
ashleymills 0:714293de3836 7486 word32 privSz = 0;
ashleymills 0:714293de3836 7487 DhKey key;
ashleymills 0:714293de3836 7488
ashleymills 0:714293de3836 7489 if (serverP.buffer == 0 || serverG.buffer == 0 ||
ashleymills 0:714293de3836 7490 serverPub.buffer == 0)
ashleymills 0:714293de3836 7491 return NO_PEER_KEY;
ashleymills 0:714293de3836 7492
ashleymills 0:714293de3836 7493 InitDhKey(&key);
ashleymills 0:714293de3836 7494 ret = DhSetKey(&key, serverP.buffer, serverP.length,
ashleymills 0:714293de3836 7495 serverG.buffer, serverG.length);
ashleymills 0:714293de3836 7496 if (ret == 0)
ashleymills 0:714293de3836 7497 /* for DH, encSecret is Yc, agree is pre-master */
ashleymills 0:714293de3836 7498 ret = DhGenerateKeyPair(&key, ssl->rng, priv, &privSz,
ashleymills 0:714293de3836 7499 encSecret, &encSz);
ashleymills 0:714293de3836 7500 if (ret == 0)
ashleymills 0:714293de3836 7501 ret = DhAgree(&key, ssl->arrays->preMasterSecret,
ashleymills 0:714293de3836 7502 &ssl->arrays->preMasterSz, priv, privSz,
ashleymills 0:714293de3836 7503 serverPub.buffer, serverPub.length);
ashleymills 0:714293de3836 7504 FreeDhKey(&key);
ashleymills 0:714293de3836 7505 }
ashleymills 0:714293de3836 7506 break;
ashleymills 0:714293de3836 7507 #endif /* OPENSSL_EXTRA */
ashleymills 0:714293de3836 7508 #ifndef NO_PSK
ashleymills 0:714293de3836 7509 case psk_kea:
ashleymills 0:714293de3836 7510 {
ashleymills 0:714293de3836 7511 byte* pms = ssl->arrays->preMasterSecret;
ashleymills 0:714293de3836 7512
ashleymills 0:714293de3836 7513 ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
ashleymills 0:714293de3836 7514 ssl->arrays->server_hint, ssl->arrays->client_identity,
ashleymills 0:714293de3836 7515 MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
ashleymills 0:714293de3836 7516 if (ssl->arrays->psk_keySz == 0 ||
ashleymills 0:714293de3836 7517 ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
ashleymills 0:714293de3836 7518 return PSK_KEY_ERROR;
ashleymills 0:714293de3836 7519 encSz = (word32)XSTRLEN(ssl->arrays->client_identity);
ashleymills 0:714293de3836 7520 if (encSz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR;
ashleymills 0:714293de3836 7521 XMEMCPY(encSecret, ssl->arrays->client_identity, encSz);
ashleymills 0:714293de3836 7522
ashleymills 0:714293de3836 7523 /* make psk pre master secret */
ashleymills 0:714293de3836 7524 /* length of key + length 0s + length of key + key */
ashleymills 0:714293de3836 7525 c16toa((word16)ssl->arrays->psk_keySz, pms);
ashleymills 0:714293de3836 7526 pms += 2;
ashleymills 0:714293de3836 7527 XMEMSET(pms, 0, ssl->arrays->psk_keySz);
ashleymills 0:714293de3836 7528 pms += ssl->arrays->psk_keySz;
ashleymills 0:714293de3836 7529 c16toa((word16)ssl->arrays->psk_keySz, pms);
ashleymills 0:714293de3836 7530 pms += 2;
ashleymills 0:714293de3836 7531 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
ashleymills 0:714293de3836 7532 ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
ashleymills 0:714293de3836 7533 XMEMSET(ssl->arrays->psk_key, 0, ssl->arrays->psk_keySz);
ashleymills 0:714293de3836 7534 ssl->arrays->psk_keySz = 0; /* No further need */
ashleymills 0:714293de3836 7535 }
ashleymills 0:714293de3836 7536 break;
ashleymills 0:714293de3836 7537 #endif /* NO_PSK */
ashleymills 0:714293de3836 7538 #ifdef HAVE_NTRU
ashleymills 0:714293de3836 7539 case ntru_kea:
ashleymills 0:714293de3836 7540 {
ashleymills 0:714293de3836 7541 word32 rc;
ashleymills 0:714293de3836 7542 word16 cipherLen = sizeof(encSecret);
ashleymills 0:714293de3836 7543 DRBG_HANDLE drbg;
ashleymills 0:714293de3836 7544 static uint8_t const cyasslStr[] = {
ashleymills 0:714293de3836 7545 'C', 'y', 'a', 'S', 'S', 'L', ' ', 'N', 'T', 'R', 'U'
ashleymills 0:714293de3836 7546 };
ashleymills 0:714293de3836 7547
ashleymills 0:714293de3836 7548 RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret,
ashleymills 0:714293de3836 7549 SECRET_LEN);
ashleymills 0:714293de3836 7550 ssl->arrays->preMasterSz = SECRET_LEN;
ashleymills 0:714293de3836 7551
ashleymills 0:714293de3836 7552 if (ssl->peerNtruKeyPresent == 0)
ashleymills 0:714293de3836 7553 return NO_PEER_KEY;
ashleymills 0:714293de3836 7554
ashleymills 0:714293de3836 7555 rc = crypto_drbg_instantiate(MAX_NTRU_BITS, cyasslStr,
ashleymills 0:714293de3836 7556 sizeof(cyasslStr), GetEntropy,
ashleymills 0:714293de3836 7557 &drbg);
ashleymills 0:714293de3836 7558 if (rc != DRBG_OK)
ashleymills 0:714293de3836 7559 return NTRU_DRBG_ERROR;
ashleymills 0:714293de3836 7560
ashleymills 0:714293de3836 7561 rc = crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen,
ashleymills 0:714293de3836 7562 ssl->peerNtruKey,
ashleymills 0:714293de3836 7563 ssl->arrays->preMasterSz,
ashleymills 0:714293de3836 7564 ssl->arrays->preMasterSecret,
ashleymills 0:714293de3836 7565 &cipherLen, encSecret);
ashleymills 0:714293de3836 7566 crypto_drbg_uninstantiate(drbg);
ashleymills 0:714293de3836 7567 if (rc != NTRU_OK)
ashleymills 0:714293de3836 7568 return NTRU_ENCRYPT_ERROR;
ashleymills 0:714293de3836 7569
ashleymills 0:714293de3836 7570 encSz = cipherLen;
ashleymills 0:714293de3836 7571 ret = 0;
ashleymills 0:714293de3836 7572 }
ashleymills 0:714293de3836 7573 break;
ashleymills 0:714293de3836 7574 #endif /* HAVE_NTRU */
ashleymills 0:714293de3836 7575 #ifdef HAVE_ECC
ashleymills 0:714293de3836 7576 case ecc_diffie_hellman_kea:
ashleymills 0:714293de3836 7577 {
ashleymills 0:714293de3836 7578 ecc_key myKey;
ashleymills 0:714293de3836 7579 ecc_key* peerKey = &myKey;
ashleymills 0:714293de3836 7580 word32 size = sizeof(encSecret);
ashleymills 0:714293de3836 7581
ashleymills 0:714293de3836 7582 if (ssl->specs.static_ecdh) {
ashleymills 0:714293de3836 7583 /* TODO: EccDsa is really fixed Ecc change naming */
ashleymills 0:714293de3836 7584 if (!ssl->peerEccDsaKeyPresent || !ssl->peerEccDsaKey->dp)
ashleymills 0:714293de3836 7585 return NO_PEER_KEY;
ashleymills 0:714293de3836 7586 peerKey = ssl->peerEccDsaKey;
ashleymills 0:714293de3836 7587 }
ashleymills 0:714293de3836 7588 else {
ashleymills 0:714293de3836 7589 if (!ssl->peerEccKeyPresent || !ssl->peerEccKey->dp)
ashleymills 0:714293de3836 7590 return NO_PEER_KEY;
ashleymills 0:714293de3836 7591 peerKey = ssl->peerEccKey;
ashleymills 0:714293de3836 7592 }
ashleymills 0:714293de3836 7593
ashleymills 0:714293de3836 7594 ecc_init(&myKey);
ashleymills 0:714293de3836 7595 ret = ecc_make_key(ssl->rng, peerKey->dp->size, &myKey);
ashleymills 0:714293de3836 7596 if (ret != 0)
ashleymills 0:714293de3836 7597 return ECC_MAKEKEY_ERROR;
ashleymills 0:714293de3836 7598
ashleymills 0:714293de3836 7599 /* precede export with 1 byte length */
ashleymills 0:714293de3836 7600 ret = ecc_export_x963(&myKey, encSecret + 1, &size);
ashleymills 0:714293de3836 7601 encSecret[0] = (byte)size;
ashleymills 0:714293de3836 7602 encSz = size + 1;
ashleymills 0:714293de3836 7603
ashleymills 0:714293de3836 7604 if (ret != 0)
ashleymills 0:714293de3836 7605 ret = ECC_EXPORT_ERROR;
ashleymills 0:714293de3836 7606 else {
ashleymills 0:714293de3836 7607 size = sizeof(ssl->arrays->preMasterSecret);
ashleymills 0:714293de3836 7608 ret = ecc_shared_secret(&myKey, peerKey,
ashleymills 0:714293de3836 7609 ssl->arrays->preMasterSecret, &size);
ashleymills 0:714293de3836 7610 if (ret != 0)
ashleymills 0:714293de3836 7611 ret = ECC_SHARED_ERROR;
ashleymills 0:714293de3836 7612 }
ashleymills 0:714293de3836 7613
ashleymills 0:714293de3836 7614 ssl->arrays->preMasterSz = size;
ashleymills 0:714293de3836 7615 ecc_free(&myKey);
ashleymills 0:714293de3836 7616 }
ashleymills 0:714293de3836 7617 break;
ashleymills 0:714293de3836 7618 #endif /* HAVE_ECC */
ashleymills 0:714293de3836 7619 default:
ashleymills 0:714293de3836 7620 return ALGO_ID_E; /* unsupported kea */
ashleymills 0:714293de3836 7621 }
ashleymills 0:714293de3836 7622
ashleymills 0:714293de3836 7623 if (ret == 0) {
ashleymills 0:714293de3836 7624 byte *output;
ashleymills 0:714293de3836 7625 int sendSz;
ashleymills 0:714293de3836 7626 word32 tlsSz = 0;
ashleymills 0:714293de3836 7627
ashleymills 0:714293de3836 7628 if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea)
ashleymills 0:714293de3836 7629 tlsSz = 2;
ashleymills 0:714293de3836 7630
ashleymills 0:714293de3836 7631 if (ssl->specs.kea == ecc_diffie_hellman_kea) /* always off */
ashleymills 0:714293de3836 7632 tlsSz = 0;
ashleymills 0:714293de3836 7633
ashleymills 0:714293de3836 7634 sendSz = encSz + tlsSz + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
ashleymills 0:714293de3836 7635 idx = HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
ashleymills 0:714293de3836 7636
ashleymills 0:714293de3836 7637 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 7638 if (ssl->options.dtls) {
ashleymills 0:714293de3836 7639 sendSz += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
ashleymills 0:714293de3836 7640 idx += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
ashleymills 0:714293de3836 7641 }
ashleymills 0:714293de3836 7642 #endif
ashleymills 0:714293de3836 7643
ashleymills 0:714293de3836 7644 /* check for available size */
ashleymills 0:714293de3836 7645 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
ashleymills 0:714293de3836 7646 return ret;
ashleymills 0:714293de3836 7647
ashleymills 0:714293de3836 7648 /* get ouput buffer */
ashleymills 0:714293de3836 7649 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 7650 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 7651
ashleymills 0:714293de3836 7652 AddHeaders(output, encSz + tlsSz, client_key_exchange, ssl);
ashleymills 0:714293de3836 7653
ashleymills 0:714293de3836 7654 if (tlsSz) {
ashleymills 0:714293de3836 7655 c16toa((word16)encSz, &output[idx]);
ashleymills 0:714293de3836 7656 idx += 2;
ashleymills 0:714293de3836 7657 }
ashleymills 0:714293de3836 7658 XMEMCPY(output + idx, encSecret, encSz);
ashleymills 0:714293de3836 7659 /* if add more to output, adjust idx
ashleymills 0:714293de3836 7660 idx += encSz; */
ashleymills 0:714293de3836 7661 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 7662 if (ssl->options.dtls) {
ashleymills 0:714293de3836 7663 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:714293de3836 7664 return ret;
ashleymills 0:714293de3836 7665 }
ashleymills 0:714293de3836 7666 #endif
ashleymills 0:714293de3836 7667 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:714293de3836 7668
ashleymills 0:714293de3836 7669 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 7670 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 7671 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
ashleymills 0:714293de3836 7672 if (ssl->toInfoOn)
ashleymills 0:714293de3836 7673 AddPacketInfo("ClientKeyExchange", &ssl->timeoutInfo,
ashleymills 0:714293de3836 7674 output, sendSz, ssl->heap);
ashleymills 0:714293de3836 7675 #endif
ashleymills 0:714293de3836 7676
ashleymills 0:714293de3836 7677 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:714293de3836 7678
ashleymills 0:714293de3836 7679 if (ssl->options.groupMessages)
ashleymills 0:714293de3836 7680 ret = 0;
ashleymills 0:714293de3836 7681 else
ashleymills 0:714293de3836 7682 ret = SendBuffered(ssl);
ashleymills 0:714293de3836 7683 }
ashleymills 0:714293de3836 7684
ashleymills 0:714293de3836 7685 if (ret == 0 || ret == WANT_WRITE) {
ashleymills 0:714293de3836 7686 int tmpRet = MakeMasterSecret(ssl);
ashleymills 0:714293de3836 7687 if (tmpRet != 0)
ashleymills 0:714293de3836 7688 ret = tmpRet; /* save WANT_WRITE unless more serious */
ashleymills 0:714293de3836 7689 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
ashleymills 0:714293de3836 7690 }
ashleymills 0:714293de3836 7691 /* No further need for PMS */
ashleymills 0:714293de3836 7692 XMEMSET(ssl->arrays->preMasterSecret, 0, ssl->arrays->preMasterSz);
ashleymills 0:714293de3836 7693 ssl->arrays->preMasterSz = 0;
ashleymills 0:714293de3836 7694
ashleymills 0:714293de3836 7695 return ret;
ashleymills 0:714293de3836 7696 }
ashleymills 0:714293de3836 7697
ashleymills 0:714293de3836 7698 #ifndef NO_CERTS
ashleymills 0:714293de3836 7699 int SendCertificateVerify(CYASSL* ssl)
ashleymills 0:714293de3836 7700 {
ashleymills 0:714293de3836 7701 byte *output;
ashleymills 0:714293de3836 7702 int sendSz = 0, length, ret;
ashleymills 0:714293de3836 7703 word32 idx = 0;
ashleymills 0:714293de3836 7704 word32 sigOutSz = 0;
ashleymills 0:714293de3836 7705 #ifndef NO_RSA
ashleymills 0:714293de3836 7706 RsaKey key;
ashleymills 0:714293de3836 7707 #endif
ashleymills 0:714293de3836 7708 int usingEcc = 0;
ashleymills 0:714293de3836 7709 #ifdef HAVE_ECC
ashleymills 0:714293de3836 7710 ecc_key eccKey;
ashleymills 0:714293de3836 7711 #endif
ashleymills 0:714293de3836 7712
ashleymills 0:714293de3836 7713 (void)idx;
ashleymills 0:714293de3836 7714
ashleymills 0:714293de3836 7715 if (ssl->options.sendVerify == SEND_BLANK_CERT)
ashleymills 0:714293de3836 7716 return 0; /* sent blank cert, can't verify */
ashleymills 0:714293de3836 7717
ashleymills 0:714293de3836 7718 /* check for available size */
ashleymills 0:714293de3836 7719 if ((ret = CheckAvailableSize(ssl, MAX_CERT_VERIFY_SZ)) != 0)
ashleymills 0:714293de3836 7720 return ret;
ashleymills 0:714293de3836 7721
ashleymills 0:714293de3836 7722 /* get ouput buffer */
ashleymills 0:714293de3836 7723 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 7724 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 7725
ashleymills 0:714293de3836 7726 BuildCertHashes(ssl, &ssl->certHashes);
ashleymills 0:714293de3836 7727
ashleymills 0:714293de3836 7728 #ifdef HAVE_ECC
ashleymills 0:714293de3836 7729 ecc_init(&eccKey);
ashleymills 0:714293de3836 7730 #endif
ashleymills 0:714293de3836 7731 #ifndef NO_RSA
ashleymills 0:714293de3836 7732 InitRsaKey(&key, ssl->heap);
ashleymills 0:714293de3836 7733 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
ashleymills 0:714293de3836 7734 ssl->buffers.key.length);
ashleymills 0:714293de3836 7735 if (ret == 0)
ashleymills 0:714293de3836 7736 sigOutSz = RsaEncryptSize(&key);
ashleymills 0:714293de3836 7737 else
ashleymills 0:714293de3836 7738 #endif
ashleymills 0:714293de3836 7739 {
ashleymills 0:714293de3836 7740 #ifdef HAVE_ECC
ashleymills 0:714293de3836 7741 CYASSL_MSG("Trying ECC client cert, RSA didn't work");
ashleymills 0:714293de3836 7742
ashleymills 0:714293de3836 7743 idx = 0;
ashleymills 0:714293de3836 7744 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &eccKey,
ashleymills 0:714293de3836 7745 ssl->buffers.key.length);
ashleymills 0:714293de3836 7746 if (ret == 0) {
ashleymills 0:714293de3836 7747 CYASSL_MSG("Using ECC client cert");
ashleymills 0:714293de3836 7748 usingEcc = 1;
ashleymills 0:714293de3836 7749 sigOutSz = MAX_ENCODED_SIG_SZ;
ashleymills 0:714293de3836 7750 }
ashleymills 0:714293de3836 7751 else {
ashleymills 0:714293de3836 7752 CYASSL_MSG("Bad client cert type");
ashleymills 0:714293de3836 7753 }
ashleymills 0:714293de3836 7754 #endif
ashleymills 0:714293de3836 7755 }
ashleymills 0:714293de3836 7756 if (ret == 0) {
ashleymills 0:714293de3836 7757 byte* verify = (byte*)&output[RECORD_HEADER_SZ +
ashleymills 0:714293de3836 7758 HANDSHAKE_HEADER_SZ];
ashleymills 0:714293de3836 7759 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 7760 byte* signBuffer = ssl->certHashes.md5;
ashleymills 0:714293de3836 7761 #else
ashleymills 0:714293de3836 7762 byte* signBuffer = NULL;
ashleymills 0:714293de3836 7763 #endif
ashleymills 0:714293de3836 7764 word32 signSz = FINISHED_SZ;
ashleymills 0:714293de3836 7765 byte encodedSig[MAX_ENCODED_SIG_SZ];
ashleymills 0:714293de3836 7766 word32 extraSz = 0; /* tls 1.2 hash/sig */
ashleymills 0:714293de3836 7767
ashleymills 0:714293de3836 7768 (void)encodedSig;
ashleymills 0:714293de3836 7769 (void)signSz;
ashleymills 0:714293de3836 7770 (void)signBuffer;
ashleymills 0:714293de3836 7771
ashleymills 0:714293de3836 7772 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 7773 if (ssl->options.dtls)
ashleymills 0:714293de3836 7774 verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 7775 #endif
ashleymills 0:714293de3836 7776 length = sigOutSz;
ashleymills 0:714293de3836 7777 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 7778 verify[0] = ssl->suites->hashAlgo;
ashleymills 0:714293de3836 7779 verify[1] = usingEcc ? ecc_dsa_sa_algo : rsa_sa_algo;
ashleymills 0:714293de3836 7780 extraSz = HASH_SIG_SIZE;
ashleymills 0:714293de3836 7781 }
ashleymills 0:714293de3836 7782
ashleymills 0:714293de3836 7783 if (usingEcc) {
ashleymills 0:714293de3836 7784 #ifdef HAVE_ECC
ashleymills 0:714293de3836 7785 word32 localSz = MAX_ENCODED_SIG_SZ;
ashleymills 0:714293de3836 7786 word32 digestSz;
ashleymills 0:714293de3836 7787 byte* digest;
ashleymills 0:714293de3836 7788 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 7789 /* old tls default */
ashleymills 0:714293de3836 7790 digestSz = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 7791 digest = ssl->certHashes.sha;
ashleymills 0:714293de3836 7792 #else
ashleymills 0:714293de3836 7793 /* new tls default */
ashleymills 0:714293de3836 7794 digestSz = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 7795 digest = ssl->certHashes.sha256;
ashleymills 0:714293de3836 7796 #endif
ashleymills 0:714293de3836 7797
ashleymills 0:714293de3836 7798 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 7799 if (ssl->suites->hashAlgo == sha_mac) {
ashleymills 0:714293de3836 7800 #ifndef NO_SHA
ashleymills 0:714293de3836 7801 digest = ssl->certHashes.sha;
ashleymills 0:714293de3836 7802 digestSz = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 7803 #endif
ashleymills 0:714293de3836 7804 }
ashleymills 0:714293de3836 7805 else if (ssl->suites->hashAlgo == sha256_mac) {
ashleymills 0:714293de3836 7806 #ifndef NO_SHA256
ashleymills 0:714293de3836 7807 digest = ssl->certHashes.sha256;
ashleymills 0:714293de3836 7808 digestSz = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 7809 #endif
ashleymills 0:714293de3836 7810 }
ashleymills 0:714293de3836 7811 else if (ssl->suites->hashAlgo == sha384_mac) {
ashleymills 0:714293de3836 7812 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 7813 digest = ssl->certHashes.sha384;
ashleymills 0:714293de3836 7814 digestSz = SHA384_DIGEST_SIZE;
ashleymills 0:714293de3836 7815 #endif
ashleymills 0:714293de3836 7816 }
ashleymills 0:714293de3836 7817 }
ashleymills 0:714293de3836 7818
ashleymills 0:714293de3836 7819 ret = ecc_sign_hash(digest, digestSz, encodedSig,
ashleymills 0:714293de3836 7820 &localSz, ssl->rng, &eccKey);
ashleymills 0:714293de3836 7821 if (ret == 0) {
ashleymills 0:714293de3836 7822 length = localSz;
ashleymills 0:714293de3836 7823 c16toa((word16)length, verify + extraSz); /* prepend hdr */
ashleymills 0:714293de3836 7824 XMEMCPY(verify + extraSz + VERIFY_HEADER,encodedSig,length);
ashleymills 0:714293de3836 7825 }
ashleymills 0:714293de3836 7826 #endif
ashleymills 0:714293de3836 7827 }
ashleymills 0:714293de3836 7828 #ifndef NO_RSA
ashleymills 0:714293de3836 7829 else {
ashleymills 0:714293de3836 7830 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 7831 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 7832 byte* digest = ssl->certHashes.sha;
ashleymills 0:714293de3836 7833 int digestSz = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 7834 int typeH = SHAh;
ashleymills 0:714293de3836 7835 #else
ashleymills 0:714293de3836 7836 byte* digest = ssl->certHashes.sha256;
ashleymills 0:714293de3836 7837 int digestSz = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 7838 int typeH = SHA256h;
ashleymills 0:714293de3836 7839 #endif
ashleymills 0:714293de3836 7840
ashleymills 0:714293de3836 7841 if (ssl->suites->hashAlgo == sha_mac) {
ashleymills 0:714293de3836 7842 #ifndef NO_SHA
ashleymills 0:714293de3836 7843 digest = ssl->certHashes.sha;
ashleymills 0:714293de3836 7844 typeH = SHAh;
ashleymills 0:714293de3836 7845 digestSz = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 7846 #endif
ashleymills 0:714293de3836 7847 }
ashleymills 0:714293de3836 7848 else if (ssl->suites->hashAlgo == sha256_mac) {
ashleymills 0:714293de3836 7849 #ifndef NO_SHA256
ashleymills 0:714293de3836 7850 digest = ssl->certHashes.sha256;
ashleymills 0:714293de3836 7851 typeH = SHA256h;
ashleymills 0:714293de3836 7852 digestSz = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 7853 #endif
ashleymills 0:714293de3836 7854 }
ashleymills 0:714293de3836 7855 else if (ssl->suites->hashAlgo == sha384_mac) {
ashleymills 0:714293de3836 7856 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 7857 digest = ssl->certHashes.sha384;
ashleymills 0:714293de3836 7858 typeH = SHA384h;
ashleymills 0:714293de3836 7859 digestSz = SHA384_DIGEST_SIZE;
ashleymills 0:714293de3836 7860 #endif
ashleymills 0:714293de3836 7861 }
ashleymills 0:714293de3836 7862
ashleymills 0:714293de3836 7863 signSz = EncodeSignature(encodedSig, digest,digestSz,typeH);
ashleymills 0:714293de3836 7864 signBuffer = encodedSig;
ashleymills 0:714293de3836 7865 }
ashleymills 0:714293de3836 7866
ashleymills 0:714293de3836 7867 c16toa((word16)length, verify + extraSz); /* prepend hdr */
ashleymills 0:714293de3836 7868 ret = RsaSSL_Sign(signBuffer, signSz, verify + extraSz +
ashleymills 0:714293de3836 7869 VERIFY_HEADER, ENCRYPT_LEN, &key, ssl->rng);
ashleymills 0:714293de3836 7870
ashleymills 0:714293de3836 7871 if (ret > 0)
ashleymills 0:714293de3836 7872 ret = 0; /* RSA reset */
ashleymills 0:714293de3836 7873 }
ashleymills 0:714293de3836 7874 #endif
ashleymills 0:714293de3836 7875 if (ret == 0) {
ashleymills 0:714293de3836 7876 AddHeaders(output, length + extraSz + VERIFY_HEADER,
ashleymills 0:714293de3836 7877 certificate_verify, ssl);
ashleymills 0:714293de3836 7878
ashleymills 0:714293de3836 7879 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + length +
ashleymills 0:714293de3836 7880 extraSz + VERIFY_HEADER;
ashleymills 0:714293de3836 7881 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 7882 if (ssl->options.dtls) {
ashleymills 0:714293de3836 7883 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 7884 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:714293de3836 7885 return ret;
ashleymills 0:714293de3836 7886 }
ashleymills 0:714293de3836 7887 #endif
ashleymills 0:714293de3836 7888 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:714293de3836 7889 }
ashleymills 0:714293de3836 7890 }
ashleymills 0:714293de3836 7891 #ifndef NO_RSA
ashleymills 0:714293de3836 7892 FreeRsaKey(&key);
ashleymills 0:714293de3836 7893 #endif
ashleymills 0:714293de3836 7894 #ifdef HAVE_ECC
ashleymills 0:714293de3836 7895 ecc_free(&eccKey);
ashleymills 0:714293de3836 7896 #endif
ashleymills 0:714293de3836 7897
ashleymills 0:714293de3836 7898 if (ret == 0) {
ashleymills 0:714293de3836 7899 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 7900 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 7901 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
ashleymills 0:714293de3836 7902 if (ssl->toInfoOn)
ashleymills 0:714293de3836 7903 AddPacketInfo("CertificateVerify", &ssl->timeoutInfo,
ashleymills 0:714293de3836 7904 output, sendSz, ssl->heap);
ashleymills 0:714293de3836 7905 #endif
ashleymills 0:714293de3836 7906 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:714293de3836 7907 if (ssl->options.groupMessages)
ashleymills 0:714293de3836 7908 return 0;
ashleymills 0:714293de3836 7909 else
ashleymills 0:714293de3836 7910 return SendBuffered(ssl);
ashleymills 0:714293de3836 7911 }
ashleymills 0:714293de3836 7912 else
ashleymills 0:714293de3836 7913 return ret;
ashleymills 0:714293de3836 7914 }
ashleymills 0:714293de3836 7915 #endif /* NO_CERTS */
ashleymills 0:714293de3836 7916
ashleymills 0:714293de3836 7917
ashleymills 0:714293de3836 7918 #endif /* NO_CYASSL_CLIENT */
ashleymills 0:714293de3836 7919
ashleymills 0:714293de3836 7920
ashleymills 0:714293de3836 7921 #ifndef NO_CYASSL_SERVER
ashleymills 0:714293de3836 7922
ashleymills 0:714293de3836 7923 int SendServerHello(CYASSL* ssl)
ashleymills 0:714293de3836 7924 {
ashleymills 0:714293de3836 7925 byte *output;
ashleymills 0:714293de3836 7926 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 7927 int sendSz;
ashleymills 0:714293de3836 7928 int ret;
ashleymills 0:714293de3836 7929
ashleymills 0:714293de3836 7930 length = VERSION_SZ + RAN_LEN
ashleymills 0:714293de3836 7931 + ID_LEN + ENUM_LEN
ashleymills 0:714293de3836 7932 + SUITE_LEN
ashleymills 0:714293de3836 7933 + ENUM_LEN;
ashleymills 0:714293de3836 7934
ashleymills 0:714293de3836 7935 #ifdef HAVE_TLS_EXTENSIONS
ashleymills 0:714293de3836 7936 length += TLSX_GetResponseSize(ssl);
ashleymills 0:714293de3836 7937 #endif
ashleymills 0:714293de3836 7938
ashleymills 0:714293de3836 7939 /* check for avalaible size */
ashleymills 0:714293de3836 7940 if ((ret = CheckAvailableSize(ssl, MAX_HELLO_SZ)) != 0)
ashleymills 0:714293de3836 7941 return ret;
ashleymills 0:714293de3836 7942
ashleymills 0:714293de3836 7943 /* get ouput buffer */
ashleymills 0:714293de3836 7944 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 7945 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 7946
ashleymills 0:714293de3836 7947 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
ashleymills 0:714293de3836 7948 AddHeaders(output, length, server_hello, ssl);
ashleymills 0:714293de3836 7949
ashleymills 0:714293de3836 7950 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 7951 if (ssl->options.dtls) {
ashleymills 0:714293de3836 7952 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 7953 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 7954 }
ashleymills 0:714293de3836 7955 #endif
ashleymills 0:714293de3836 7956 /* now write to output */
ashleymills 0:714293de3836 7957 /* first version */
ashleymills 0:714293de3836 7958 output[idx++] = ssl->version.major;
ashleymills 0:714293de3836 7959 output[idx++] = ssl->version.minor;
ashleymills 0:714293de3836 7960
ashleymills 0:714293de3836 7961 /* then random */
ashleymills 0:714293de3836 7962 if (!ssl->options.resuming)
ashleymills 0:714293de3836 7963 RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 7964 XMEMCPY(output + idx, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 7965 idx += RAN_LEN;
ashleymills 0:714293de3836 7966
ashleymills 0:714293de3836 7967 #ifdef SHOW_SECRETS
ashleymills 0:714293de3836 7968 {
ashleymills 0:714293de3836 7969 int j;
ashleymills 0:714293de3836 7970 printf("server random: ");
ashleymills 0:714293de3836 7971 for (j = 0; j < RAN_LEN; j++)
ashleymills 0:714293de3836 7972 printf("%02x", ssl->arrays->serverRandom[j]);
ashleymills 0:714293de3836 7973 printf("\n");
ashleymills 0:714293de3836 7974 }
ashleymills 0:714293de3836 7975 #endif
ashleymills 0:714293de3836 7976 /* then session id */
ashleymills 0:714293de3836 7977 output[idx++] = ID_LEN;
ashleymills 0:714293de3836 7978 if (!ssl->options.resuming)
ashleymills 0:714293de3836 7979 RNG_GenerateBlock(ssl->rng, ssl->arrays->sessionID, ID_LEN);
ashleymills 0:714293de3836 7980 XMEMCPY(output + idx, ssl->arrays->sessionID, ID_LEN);
ashleymills 0:714293de3836 7981 idx += ID_LEN;
ashleymills 0:714293de3836 7982
ashleymills 0:714293de3836 7983 /* then cipher suite */
ashleymills 0:714293de3836 7984 output[idx++] = ssl->options.cipherSuite0;
ashleymills 0:714293de3836 7985 output[idx++] = ssl->options.cipherSuite;
ashleymills 0:714293de3836 7986
ashleymills 0:714293de3836 7987 /* then compression */
ashleymills 0:714293de3836 7988 if (ssl->options.usingCompression)
ashleymills 0:714293de3836 7989 output[idx++] = ZLIB_COMPRESSION;
ashleymills 0:714293de3836 7990 else
ashleymills 0:714293de3836 7991 output[idx++] = NO_COMPRESSION;
ashleymills 0:714293de3836 7992
ashleymills 0:714293de3836 7993 /* last, extensions */
ashleymills 0:714293de3836 7994 #ifdef HAVE_TLS_EXTENSIONS
ashleymills 0:714293de3836 7995 if (IsTLS(ssl))
ashleymills 0:714293de3836 7996 TLSX_WriteResponse(ssl, output + idx);
ashleymills 0:714293de3836 7997 #endif
ashleymills 0:714293de3836 7998
ashleymills 0:714293de3836 7999 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:714293de3836 8000 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 8001 if (ssl->options.dtls) {
ashleymills 0:714293de3836 8002 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:714293de3836 8003 return ret;
ashleymills 0:714293de3836 8004 }
ashleymills 0:714293de3836 8005 #endif
ashleymills 0:714293de3836 8006 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:714293de3836 8007
ashleymills 0:714293de3836 8008 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 8009 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 8010 AddPacketName("ServerHello", &ssl->handShakeInfo);
ashleymills 0:714293de3836 8011 if (ssl->toInfoOn)
ashleymills 0:714293de3836 8012 AddPacketInfo("ServerHello", &ssl->timeoutInfo, output, sendSz,
ashleymills 0:714293de3836 8013 ssl->heap);
ashleymills 0:714293de3836 8014 #endif
ashleymills 0:714293de3836 8015
ashleymills 0:714293de3836 8016 ssl->options.serverState = SERVER_HELLO_COMPLETE;
ashleymills 0:714293de3836 8017
ashleymills 0:714293de3836 8018 if (ssl->options.groupMessages)
ashleymills 0:714293de3836 8019 return 0;
ashleymills 0:714293de3836 8020 else
ashleymills 0:714293de3836 8021 return SendBuffered(ssl);
ashleymills 0:714293de3836 8022 }
ashleymills 0:714293de3836 8023
ashleymills 0:714293de3836 8024
ashleymills 0:714293de3836 8025 #ifdef HAVE_ECC
ashleymills 0:714293de3836 8026
ashleymills 0:714293de3836 8027 static byte SetCurveId(int size)
ashleymills 0:714293de3836 8028 {
ashleymills 0:714293de3836 8029 switch(size) {
ashleymills 0:714293de3836 8030 case 20:
ashleymills 0:714293de3836 8031 return secp160r1;
ashleymills 0:714293de3836 8032 break;
ashleymills 0:714293de3836 8033 case 24:
ashleymills 0:714293de3836 8034 return secp192r1;
ashleymills 0:714293de3836 8035 break;
ashleymills 0:714293de3836 8036 case 28:
ashleymills 0:714293de3836 8037 return secp224r1;
ashleymills 0:714293de3836 8038 break;
ashleymills 0:714293de3836 8039 case 32:
ashleymills 0:714293de3836 8040 return secp256r1;
ashleymills 0:714293de3836 8041 break;
ashleymills 0:714293de3836 8042 case 48:
ashleymills 0:714293de3836 8043 return secp384r1;
ashleymills 0:714293de3836 8044 break;
ashleymills 0:714293de3836 8045 case 66:
ashleymills 0:714293de3836 8046 return secp521r1;
ashleymills 0:714293de3836 8047 break;
ashleymills 0:714293de3836 8048 default:
ashleymills 0:714293de3836 8049 return 0;
ashleymills 0:714293de3836 8050 }
ashleymills 0:714293de3836 8051 }
ashleymills 0:714293de3836 8052
ashleymills 0:714293de3836 8053 #endif /* HAVE_ECC */
ashleymills 0:714293de3836 8054
ashleymills 0:714293de3836 8055
ashleymills 0:714293de3836 8056 int SendServerKeyExchange(CYASSL* ssl)
ashleymills 0:714293de3836 8057 {
ashleymills 0:714293de3836 8058 int ret = 0;
ashleymills 0:714293de3836 8059 (void)ssl;
ashleymills 0:714293de3836 8060
ashleymills 0:714293de3836 8061 #ifndef NO_PSK
ashleymills 0:714293de3836 8062 if (ssl->specs.kea == psk_kea)
ashleymills 0:714293de3836 8063 {
ashleymills 0:714293de3836 8064 byte *output;
ashleymills 0:714293de3836 8065 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 8066 int sendSz;
ashleymills 0:714293de3836 8067 if (ssl->arrays->server_hint[0] == 0) return 0; /* don't send */
ashleymills 0:714293de3836 8068
ashleymills 0:714293de3836 8069 /* include size part */
ashleymills 0:714293de3836 8070 length = (word32)XSTRLEN(ssl->arrays->server_hint);
ashleymills 0:714293de3836 8071 if (length > MAX_PSK_ID_LEN) return SERVER_HINT_ERROR;
ashleymills 0:714293de3836 8072 length += HINT_LEN_SZ;
ashleymills 0:714293de3836 8073 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
ashleymills 0:714293de3836 8074
ashleymills 0:714293de3836 8075 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 8076 if (ssl->options.dtls) {
ashleymills 0:714293de3836 8077 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 8078 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 8079 }
ashleymills 0:714293de3836 8080 #endif
ashleymills 0:714293de3836 8081 /* check for available size */
ashleymills 0:714293de3836 8082 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
ashleymills 0:714293de3836 8083 return ret;
ashleymills 0:714293de3836 8084
ashleymills 0:714293de3836 8085 /* get ouput buffer */
ashleymills 0:714293de3836 8086 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 8087 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 8088
ashleymills 0:714293de3836 8089 AddHeaders(output, length, server_key_exchange, ssl);
ashleymills 0:714293de3836 8090
ashleymills 0:714293de3836 8091 /* key data */
ashleymills 0:714293de3836 8092 c16toa((word16)(length - HINT_LEN_SZ), output + idx);
ashleymills 0:714293de3836 8093 idx += HINT_LEN_SZ;
ashleymills 0:714293de3836 8094 XMEMCPY(output + idx, ssl->arrays->server_hint,length -HINT_LEN_SZ);
ashleymills 0:714293de3836 8095
ashleymills 0:714293de3836 8096 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:714293de3836 8097
ashleymills 0:714293de3836 8098 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 8099 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 8100 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
ashleymills 0:714293de3836 8101 if (ssl->toInfoOn)
ashleymills 0:714293de3836 8102 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
ashleymills 0:714293de3836 8103 output, sendSz, ssl->heap);
ashleymills 0:714293de3836 8104 #endif
ashleymills 0:714293de3836 8105
ashleymills 0:714293de3836 8106 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:714293de3836 8107 if (ssl->options.groupMessages)
ashleymills 0:714293de3836 8108 ret = 0;
ashleymills 0:714293de3836 8109 else
ashleymills 0:714293de3836 8110 ret = SendBuffered(ssl);
ashleymills 0:714293de3836 8111 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
ashleymills 0:714293de3836 8112 }
ashleymills 0:714293de3836 8113 #endif /*NO_PSK */
ashleymills 0:714293de3836 8114
ashleymills 0:714293de3836 8115 #ifdef HAVE_ECC
ashleymills 0:714293de3836 8116 if (ssl->specs.kea == ecc_diffie_hellman_kea)
ashleymills 0:714293de3836 8117 {
ashleymills 0:714293de3836 8118 byte *output;
ashleymills 0:714293de3836 8119 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 8120 int sendSz;
ashleymills 0:714293de3836 8121 byte exportBuf[MAX_EXPORT_ECC_SZ];
ashleymills 0:714293de3836 8122 word32 expSz = sizeof(exportBuf);
ashleymills 0:714293de3836 8123 word32 sigSz;
ashleymills 0:714293de3836 8124 word32 preSigSz, preSigIdx;
ashleymills 0:714293de3836 8125 #ifndef NO_RSA
ashleymills 0:714293de3836 8126 RsaKey rsaKey;
ashleymills 0:714293de3836 8127 #endif
ashleymills 0:714293de3836 8128 ecc_key dsaKey;
ashleymills 0:714293de3836 8129
ashleymills 0:714293de3836 8130 if (ssl->specs.static_ecdh) {
ashleymills 0:714293de3836 8131 CYASSL_MSG("Using Static ECDH, not sending ServerKeyExchagne");
ashleymills 0:714293de3836 8132 return 0;
ashleymills 0:714293de3836 8133 }
ashleymills 0:714293de3836 8134
ashleymills 0:714293de3836 8135 /* curve type, named curve, length(1) */
ashleymills 0:714293de3836 8136 length = ENUM_LEN + CURVE_LEN + ENUM_LEN;
ashleymills 0:714293de3836 8137 /* pub key size */
ashleymills 0:714293de3836 8138 CYASSL_MSG("Using ephemeral ECDH");
ashleymills 0:714293de3836 8139 if (ecc_export_x963(ssl->eccTempKey, exportBuf, &expSz) != 0)
ashleymills 0:714293de3836 8140 return ECC_EXPORT_ERROR;
ashleymills 0:714293de3836 8141 length += expSz;
ashleymills 0:714293de3836 8142
ashleymills 0:714293de3836 8143 preSigSz = length;
ashleymills 0:714293de3836 8144 preSigIdx = idx;
ashleymills 0:714293de3836 8145
ashleymills 0:714293de3836 8146 #ifndef NO_RSA
ashleymills 0:714293de3836 8147 InitRsaKey(&rsaKey, ssl->heap);
ashleymills 0:714293de3836 8148 #endif
ashleymills 0:714293de3836 8149 ecc_init(&dsaKey);
ashleymills 0:714293de3836 8150
ashleymills 0:714293de3836 8151 /* sig length */
ashleymills 0:714293de3836 8152 length += LENGTH_SZ;
ashleymills 0:714293de3836 8153
ashleymills 0:714293de3836 8154 if (!ssl->buffers.key.buffer) {
ashleymills 0:714293de3836 8155 #ifndef NO_RSA
ashleymills 0:714293de3836 8156 FreeRsaKey(&rsaKey);
ashleymills 0:714293de3836 8157 #endif
ashleymills 0:714293de3836 8158 ecc_free(&dsaKey);
ashleymills 0:714293de3836 8159 return NO_PRIVATE_KEY;
ashleymills 0:714293de3836 8160 }
ashleymills 0:714293de3836 8161
ashleymills 0:714293de3836 8162 #ifndef NO_RSA
ashleymills 0:714293de3836 8163 if (ssl->specs.sig_algo == rsa_sa_algo) {
ashleymills 0:714293de3836 8164 /* rsa sig size */
ashleymills 0:714293de3836 8165 word32 i = 0;
ashleymills 0:714293de3836 8166 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i,
ashleymills 0:714293de3836 8167 &rsaKey, ssl->buffers.key.length);
ashleymills 0:714293de3836 8168 if (ret != 0) return ret;
ashleymills 0:714293de3836 8169 sigSz = RsaEncryptSize(&rsaKey);
ashleymills 0:714293de3836 8170 } else
ashleymills 0:714293de3836 8171 #endif
ashleymills 0:714293de3836 8172 if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
ashleymills 0:714293de3836 8173 /* ecdsa sig size */
ashleymills 0:714293de3836 8174 word32 i = 0;
ashleymills 0:714293de3836 8175 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
ashleymills 0:714293de3836 8176 &dsaKey, ssl->buffers.key.length);
ashleymills 0:714293de3836 8177 if (ret != 0) return ret;
ashleymills 0:714293de3836 8178 sigSz = ecc_sig_size(&dsaKey) + 2; /* worst case estimate */
ashleymills 0:714293de3836 8179 }
ashleymills 0:714293de3836 8180 else {
ashleymills 0:714293de3836 8181 #ifndef NO_RSA
ashleymills 0:714293de3836 8182 FreeRsaKey(&rsaKey);
ashleymills 0:714293de3836 8183 #endif
ashleymills 0:714293de3836 8184 ecc_free(&dsaKey);
ashleymills 0:714293de3836 8185 return ALGO_ID_E; /* unsupported type */
ashleymills 0:714293de3836 8186 }
ashleymills 0:714293de3836 8187 length += sigSz;
ashleymills 0:714293de3836 8188
ashleymills 0:714293de3836 8189 if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:714293de3836 8190 length += HASH_SIG_SIZE;
ashleymills 0:714293de3836 8191
ashleymills 0:714293de3836 8192 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
ashleymills 0:714293de3836 8193
ashleymills 0:714293de3836 8194 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 8195 if (ssl->options.dtls) {
ashleymills 0:714293de3836 8196 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 8197 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 8198 preSigIdx = idx;
ashleymills 0:714293de3836 8199 }
ashleymills 0:714293de3836 8200 #endif
ashleymills 0:714293de3836 8201 /* check for available size */
ashleymills 0:714293de3836 8202 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
ashleymills 0:714293de3836 8203 #ifndef NO_RSA
ashleymills 0:714293de3836 8204 FreeRsaKey(&rsaKey);
ashleymills 0:714293de3836 8205 #endif
ashleymills 0:714293de3836 8206 ecc_free(&dsaKey);
ashleymills 0:714293de3836 8207 return ret;
ashleymills 0:714293de3836 8208 }
ashleymills 0:714293de3836 8209
ashleymills 0:714293de3836 8210 /* get ouput buffer */
ashleymills 0:714293de3836 8211 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 8212 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 8213
ashleymills 0:714293de3836 8214 /* record and message headers will be added below, when we're sure
ashleymills 0:714293de3836 8215 of the sig length */
ashleymills 0:714293de3836 8216
ashleymills 0:714293de3836 8217 /* key exchange data */
ashleymills 0:714293de3836 8218 output[idx++] = named_curve;
ashleymills 0:714293de3836 8219 output[idx++] = 0x00; /* leading zero */
ashleymills 0:714293de3836 8220 output[idx++] = SetCurveId(ecc_size(ssl->eccTempKey));
ashleymills 0:714293de3836 8221 output[idx++] = (byte)expSz;
ashleymills 0:714293de3836 8222 XMEMCPY(output + idx, exportBuf, expSz);
ashleymills 0:714293de3836 8223 idx += expSz;
ashleymills 0:714293de3836 8224 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 8225 output[idx++] = ssl->suites->hashAlgo;
ashleymills 0:714293de3836 8226 output[idx++] = ssl->suites->sigAlgo;
ashleymills 0:714293de3836 8227 }
ashleymills 0:714293de3836 8228
ashleymills 0:714293de3836 8229 /* Signtaure length will be written later, when we're sure what it
ashleymills 0:714293de3836 8230 is */
ashleymills 0:714293de3836 8231
ashleymills 0:714293de3836 8232 /* do signature */
ashleymills 0:714293de3836 8233 {
ashleymills 0:714293de3836 8234 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 8235 Md5 md5;
ashleymills 0:714293de3836 8236 Sha sha;
ashleymills 0:714293de3836 8237 #endif
ashleymills 0:714293de3836 8238 byte hash[FINISHED_SZ];
ashleymills 0:714293de3836 8239 #ifndef NO_SHA256
ashleymills 0:714293de3836 8240 Sha256 sha256;
ashleymills 0:714293de3836 8241 byte hash256[SHA256_DIGEST_SIZE];
ashleymills 0:714293de3836 8242 #endif
ashleymills 0:714293de3836 8243 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 8244 Sha384 sha384;
ashleymills 0:714293de3836 8245 byte hash384[SHA384_DIGEST_SIZE];
ashleymills 0:714293de3836 8246 #endif
ashleymills 0:714293de3836 8247
ashleymills 0:714293de3836 8248 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 8249 /* md5 */
ashleymills 0:714293de3836 8250 InitMd5(&md5);
ashleymills 0:714293de3836 8251 Md5Update(&md5, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 8252 Md5Update(&md5, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 8253 Md5Update(&md5, output + preSigIdx, preSigSz);
ashleymills 0:714293de3836 8254 Md5Final(&md5, hash);
ashleymills 0:714293de3836 8255
ashleymills 0:714293de3836 8256 /* sha */
ashleymills 0:714293de3836 8257 InitSha(&sha);
ashleymills 0:714293de3836 8258 ShaUpdate(&sha, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 8259 ShaUpdate(&sha, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 8260 ShaUpdate(&sha, output + preSigIdx, preSigSz);
ashleymills 0:714293de3836 8261 ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
ashleymills 0:714293de3836 8262 #endif
ashleymills 0:714293de3836 8263
ashleymills 0:714293de3836 8264 #ifndef NO_SHA256
ashleymills 0:714293de3836 8265 InitSha256(&sha256);
ashleymills 0:714293de3836 8266 Sha256Update(&sha256, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 8267 Sha256Update(&sha256, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 8268 Sha256Update(&sha256, output + preSigIdx, preSigSz);
ashleymills 0:714293de3836 8269 Sha256Final(&sha256, hash256);
ashleymills 0:714293de3836 8270 #endif
ashleymills 0:714293de3836 8271
ashleymills 0:714293de3836 8272 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 8273 InitSha384(&sha384);
ashleymills 0:714293de3836 8274 Sha384Update(&sha384, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 8275 Sha384Update(&sha384, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 8276 Sha384Update(&sha384, output + preSigIdx, preSigSz);
ashleymills 0:714293de3836 8277 Sha384Final(&sha384, hash384);
ashleymills 0:714293de3836 8278 #endif
ashleymills 0:714293de3836 8279 #ifndef NO_RSA
ashleymills 0:714293de3836 8280 if (ssl->suites->sigAlgo == rsa_sa_algo) {
ashleymills 0:714293de3836 8281 byte* signBuffer = hash;
ashleymills 0:714293de3836 8282 word32 signSz = sizeof(hash);
ashleymills 0:714293de3836 8283 byte encodedSig[MAX_ENCODED_SIG_SZ];
ashleymills 0:714293de3836 8284 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 8285 byte* digest = &hash[MD5_DIGEST_SIZE];
ashleymills 0:714293de3836 8286 int typeH = SHAh;
ashleymills 0:714293de3836 8287 int digestSz = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 8288
ashleymills 0:714293de3836 8289 if (ssl->suites->hashAlgo == sha256_mac) {
ashleymills 0:714293de3836 8290 #ifndef NO_SHA256
ashleymills 0:714293de3836 8291 digest = hash256;
ashleymills 0:714293de3836 8292 typeH = SHA256h;
ashleymills 0:714293de3836 8293 digestSz = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 8294 #endif
ashleymills 0:714293de3836 8295 }
ashleymills 0:714293de3836 8296 else if (ssl->suites->hashAlgo == sha384_mac) {
ashleymills 0:714293de3836 8297 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 8298 digest = hash384;
ashleymills 0:714293de3836 8299 typeH = SHA384h;
ashleymills 0:714293de3836 8300 digestSz = SHA384_DIGEST_SIZE;
ashleymills 0:714293de3836 8301 #endif
ashleymills 0:714293de3836 8302 }
ashleymills 0:714293de3836 8303
ashleymills 0:714293de3836 8304 signSz = EncodeSignature(encodedSig, digest, digestSz,
ashleymills 0:714293de3836 8305 typeH);
ashleymills 0:714293de3836 8306 signBuffer = encodedSig;
ashleymills 0:714293de3836 8307 }
ashleymills 0:714293de3836 8308 /* write sig size here */
ashleymills 0:714293de3836 8309 c16toa((word16)sigSz, output + idx);
ashleymills 0:714293de3836 8310 idx += LENGTH_SZ;
ashleymills 0:714293de3836 8311
ashleymills 0:714293de3836 8312 ret = RsaSSL_Sign(signBuffer, signSz, output + idx, sigSz,
ashleymills 0:714293de3836 8313 &rsaKey, ssl->rng);
ashleymills 0:714293de3836 8314 FreeRsaKey(&rsaKey);
ashleymills 0:714293de3836 8315 ecc_free(&dsaKey);
ashleymills 0:714293de3836 8316 if (ret > 0)
ashleymills 0:714293de3836 8317 ret = 0; /* reset on success */
ashleymills 0:714293de3836 8318 else
ashleymills 0:714293de3836 8319 return ret;
ashleymills 0:714293de3836 8320 } else
ashleymills 0:714293de3836 8321 #endif
ashleymills 0:714293de3836 8322 if (ssl->suites->sigAlgo == ecc_dsa_sa_algo) {
ashleymills 0:714293de3836 8323 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 8324 byte* digest = &hash[MD5_DIGEST_SIZE];
ashleymills 0:714293de3836 8325 word32 digestSz = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 8326 #else
ashleymills 0:714293de3836 8327 byte* digest = hash256;
ashleymills 0:714293de3836 8328 word32 digestSz = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 8329 #endif
ashleymills 0:714293de3836 8330 word32 sz = sigSz;
ashleymills 0:714293de3836 8331
ashleymills 0:714293de3836 8332 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 8333 if (ssl->suites->hashAlgo == sha_mac) {
ashleymills 0:714293de3836 8334 #ifndef NO_SHA
ashleymills 0:714293de3836 8335 digest = &hash[MD5_DIGEST_SIZE];
ashleymills 0:714293de3836 8336 digestSz = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 8337 #endif
ashleymills 0:714293de3836 8338 }
ashleymills 0:714293de3836 8339 else if (ssl->suites->hashAlgo == sha256_mac) {
ashleymills 0:714293de3836 8340 #ifndef NO_SHA256
ashleymills 0:714293de3836 8341 digest = hash256;
ashleymills 0:714293de3836 8342 digestSz = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 8343 #endif
ashleymills 0:714293de3836 8344 }
ashleymills 0:714293de3836 8345 else if (ssl->suites->hashAlgo == sha384_mac) {
ashleymills 0:714293de3836 8346 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 8347 digest = hash384;
ashleymills 0:714293de3836 8348 digestSz = SHA384_DIGEST_SIZE;
ashleymills 0:714293de3836 8349 #endif
ashleymills 0:714293de3836 8350 }
ashleymills 0:714293de3836 8351 }
ashleymills 0:714293de3836 8352
ashleymills 0:714293de3836 8353 ret = ecc_sign_hash(digest, digestSz,
ashleymills 0:714293de3836 8354 output + LENGTH_SZ + idx, &sz, ssl->rng, &dsaKey);
ashleymills 0:714293de3836 8355 #ifndef NO_RSA
ashleymills 0:714293de3836 8356 FreeRsaKey(&rsaKey);
ashleymills 0:714293de3836 8357 #endif
ashleymills 0:714293de3836 8358 ecc_free(&dsaKey);
ashleymills 0:714293de3836 8359 if (ret < 0) return ret;
ashleymills 0:714293de3836 8360
ashleymills 0:714293de3836 8361 /* Now that we know the real sig size, write it. */
ashleymills 0:714293de3836 8362 c16toa((word16)sz, output + idx);
ashleymills 0:714293de3836 8363
ashleymills 0:714293de3836 8364 /* And adjust length and sendSz from estimates */
ashleymills 0:714293de3836 8365 length += sz - sigSz;
ashleymills 0:714293de3836 8366 sendSz += sz - sigSz;
ashleymills 0:714293de3836 8367 }
ashleymills 0:714293de3836 8368 }
ashleymills 0:714293de3836 8369
ashleymills 0:714293de3836 8370 AddHeaders(output, length, server_key_exchange, ssl);
ashleymills 0:714293de3836 8371 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:714293de3836 8372
ashleymills 0:714293de3836 8373 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 8374 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 8375 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
ashleymills 0:714293de3836 8376 if (ssl->toInfoOn)
ashleymills 0:714293de3836 8377 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
ashleymills 0:714293de3836 8378 output, sendSz, ssl->heap);
ashleymills 0:714293de3836 8379 #endif
ashleymills 0:714293de3836 8380
ashleymills 0:714293de3836 8381 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:714293de3836 8382 if (ssl->options.groupMessages)
ashleymills 0:714293de3836 8383 ret = 0;
ashleymills 0:714293de3836 8384 else
ashleymills 0:714293de3836 8385 ret = SendBuffered(ssl);
ashleymills 0:714293de3836 8386 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
ashleymills 0:714293de3836 8387 }
ashleymills 0:714293de3836 8388 #endif /* HAVE_ECC */
ashleymills 0:714293de3836 8389
ashleymills 0:714293de3836 8390 #ifdef OPENSSL_EXTRA
ashleymills 0:714293de3836 8391 if (ssl->specs.kea == diffie_hellman_kea) {
ashleymills 0:714293de3836 8392 byte *output;
ashleymills 0:714293de3836 8393 word32 length = 0, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 8394 int sendSz;
ashleymills 0:714293de3836 8395 word32 sigSz = 0, i = 0;
ashleymills 0:714293de3836 8396 word32 preSigSz = 0, preSigIdx = 0;
ashleymills 0:714293de3836 8397 RsaKey rsaKey;
ashleymills 0:714293de3836 8398 DhKey dhKey;
ashleymills 0:714293de3836 8399
ashleymills 0:714293de3836 8400 if (ssl->buffers.serverDH_P.buffer == NULL ||
ashleymills 0:714293de3836 8401 ssl->buffers.serverDH_G.buffer == NULL)
ashleymills 0:714293de3836 8402 return NO_DH_PARAMS;
ashleymills 0:714293de3836 8403
ashleymills 0:714293de3836 8404 if (ssl->buffers.serverDH_Pub.buffer == NULL) {
ashleymills 0:714293de3836 8405 ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
ashleymills 0:714293de3836 8406 ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
ashleymills 0:714293de3836 8407 DYNAMIC_TYPE_DH);
ashleymills 0:714293de3836 8408 if (ssl->buffers.serverDH_Pub.buffer == NULL)
ashleymills 0:714293de3836 8409 return MEMORY_E;
ashleymills 0:714293de3836 8410 }
ashleymills 0:714293de3836 8411
ashleymills 0:714293de3836 8412 if (ssl->buffers.serverDH_Priv.buffer == NULL) {
ashleymills 0:714293de3836 8413 ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
ashleymills 0:714293de3836 8414 ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
ashleymills 0:714293de3836 8415 DYNAMIC_TYPE_DH);
ashleymills 0:714293de3836 8416 if (ssl->buffers.serverDH_Priv.buffer == NULL)
ashleymills 0:714293de3836 8417 return MEMORY_E;
ashleymills 0:714293de3836 8418 }
ashleymills 0:714293de3836 8419
ashleymills 0:714293de3836 8420 InitDhKey(&dhKey);
ashleymills 0:714293de3836 8421 ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
ashleymills 0:714293de3836 8422 ssl->buffers.serverDH_P.length,
ashleymills 0:714293de3836 8423 ssl->buffers.serverDH_G.buffer,
ashleymills 0:714293de3836 8424 ssl->buffers.serverDH_G.length);
ashleymills 0:714293de3836 8425 if (ret == 0)
ashleymills 0:714293de3836 8426 ret = DhGenerateKeyPair(&dhKey, ssl->rng,
ashleymills 0:714293de3836 8427 ssl->buffers.serverDH_Priv.buffer,
ashleymills 0:714293de3836 8428 &ssl->buffers.serverDH_Priv.length,
ashleymills 0:714293de3836 8429 ssl->buffers.serverDH_Pub.buffer,
ashleymills 0:714293de3836 8430 &ssl->buffers.serverDH_Pub.length);
ashleymills 0:714293de3836 8431 FreeDhKey(&dhKey);
ashleymills 0:714293de3836 8432
ashleymills 0:714293de3836 8433 InitRsaKey(&rsaKey, ssl->heap);
ashleymills 0:714293de3836 8434 if (ret == 0) {
ashleymills 0:714293de3836 8435 length = LENGTH_SZ * 3; /* p, g, pub */
ashleymills 0:714293de3836 8436 length += ssl->buffers.serverDH_P.length +
ashleymills 0:714293de3836 8437 ssl->buffers.serverDH_G.length +
ashleymills 0:714293de3836 8438 ssl->buffers.serverDH_Pub.length;
ashleymills 0:714293de3836 8439
ashleymills 0:714293de3836 8440 preSigIdx = idx;
ashleymills 0:714293de3836 8441 preSigSz = length;
ashleymills 0:714293de3836 8442
ashleymills 0:714293de3836 8443 /* sig length */
ashleymills 0:714293de3836 8444 length += LENGTH_SZ;
ashleymills 0:714293de3836 8445
ashleymills 0:714293de3836 8446 if (!ssl->buffers.key.buffer)
ashleymills 0:714293de3836 8447 return NO_PRIVATE_KEY;
ashleymills 0:714293de3836 8448
ashleymills 0:714293de3836 8449 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i, &rsaKey,
ashleymills 0:714293de3836 8450 ssl->buffers.key.length);
ashleymills 0:714293de3836 8451 if (ret == 0) {
ashleymills 0:714293de3836 8452 sigSz = RsaEncryptSize(&rsaKey);
ashleymills 0:714293de3836 8453 length += sigSz;
ashleymills 0:714293de3836 8454 }
ashleymills 0:714293de3836 8455 }
ashleymills 0:714293de3836 8456 if (ret != 0) {
ashleymills 0:714293de3836 8457 FreeRsaKey(&rsaKey);
ashleymills 0:714293de3836 8458 return ret;
ashleymills 0:714293de3836 8459 }
ashleymills 0:714293de3836 8460
ashleymills 0:714293de3836 8461 if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:714293de3836 8462 length += HASH_SIG_SIZE;
ashleymills 0:714293de3836 8463
ashleymills 0:714293de3836 8464 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
ashleymills 0:714293de3836 8465
ashleymills 0:714293de3836 8466 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 8467 if (ssl->options.dtls) {
ashleymills 0:714293de3836 8468 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 8469 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 8470 preSigIdx = idx;
ashleymills 0:714293de3836 8471 }
ashleymills 0:714293de3836 8472 #endif
ashleymills 0:714293de3836 8473 /* check for available size */
ashleymills 0:714293de3836 8474 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
ashleymills 0:714293de3836 8475 FreeRsaKey(&rsaKey);
ashleymills 0:714293de3836 8476 return ret;
ashleymills 0:714293de3836 8477 }
ashleymills 0:714293de3836 8478
ashleymills 0:714293de3836 8479 /* get ouput buffer */
ashleymills 0:714293de3836 8480 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 8481 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 8482
ashleymills 0:714293de3836 8483 AddHeaders(output, length, server_key_exchange, ssl);
ashleymills 0:714293de3836 8484
ashleymills 0:714293de3836 8485 /* add p, g, pub */
ashleymills 0:714293de3836 8486 c16toa((word16)ssl->buffers.serverDH_P.length, output + idx);
ashleymills 0:714293de3836 8487 idx += LENGTH_SZ;
ashleymills 0:714293de3836 8488 XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer,
ashleymills 0:714293de3836 8489 ssl->buffers.serverDH_P.length);
ashleymills 0:714293de3836 8490 idx += ssl->buffers.serverDH_P.length;
ashleymills 0:714293de3836 8491
ashleymills 0:714293de3836 8492 /* g */
ashleymills 0:714293de3836 8493 c16toa((word16)ssl->buffers.serverDH_G.length, output + idx);
ashleymills 0:714293de3836 8494 idx += LENGTH_SZ;
ashleymills 0:714293de3836 8495 XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer,
ashleymills 0:714293de3836 8496 ssl->buffers.serverDH_G.length);
ashleymills 0:714293de3836 8497 idx += ssl->buffers.serverDH_G.length;
ashleymills 0:714293de3836 8498
ashleymills 0:714293de3836 8499 /* pub */
ashleymills 0:714293de3836 8500 c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx);
ashleymills 0:714293de3836 8501 idx += LENGTH_SZ;
ashleymills 0:714293de3836 8502 XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer,
ashleymills 0:714293de3836 8503 ssl->buffers.serverDH_Pub.length);
ashleymills 0:714293de3836 8504 idx += ssl->buffers.serverDH_Pub.length;
ashleymills 0:714293de3836 8505
ashleymills 0:714293de3836 8506 /* Add signature */
ashleymills 0:714293de3836 8507 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 8508 output[idx++] = ssl->suites->hashAlgo;
ashleymills 0:714293de3836 8509 output[idx++] = ssl->suites->sigAlgo;
ashleymills 0:714293de3836 8510 }
ashleymills 0:714293de3836 8511 /* size */
ashleymills 0:714293de3836 8512 c16toa((word16)sigSz, output + idx);
ashleymills 0:714293de3836 8513 idx += LENGTH_SZ;
ashleymills 0:714293de3836 8514
ashleymills 0:714293de3836 8515 /* do signature */
ashleymills 0:714293de3836 8516 {
ashleymills 0:714293de3836 8517 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 8518 Md5 md5;
ashleymills 0:714293de3836 8519 Sha sha;
ashleymills 0:714293de3836 8520 #endif
ashleymills 0:714293de3836 8521 byte hash[FINISHED_SZ];
ashleymills 0:714293de3836 8522 #ifndef NO_SHA256
ashleymills 0:714293de3836 8523 Sha256 sha256;
ashleymills 0:714293de3836 8524 byte hash256[SHA256_DIGEST_SIZE];
ashleymills 0:714293de3836 8525 #endif
ashleymills 0:714293de3836 8526 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 8527 Sha384 sha384;
ashleymills 0:714293de3836 8528 byte hash384[SHA384_DIGEST_SIZE];
ashleymills 0:714293de3836 8529 #endif
ashleymills 0:714293de3836 8530
ashleymills 0:714293de3836 8531 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 8532 /* md5 */
ashleymills 0:714293de3836 8533 InitMd5(&md5);
ashleymills 0:714293de3836 8534 Md5Update(&md5, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 8535 Md5Update(&md5, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 8536 Md5Update(&md5, output + preSigIdx, preSigSz);
ashleymills 0:714293de3836 8537 Md5Final(&md5, hash);
ashleymills 0:714293de3836 8538
ashleymills 0:714293de3836 8539 /* sha */
ashleymills 0:714293de3836 8540 InitSha(&sha);
ashleymills 0:714293de3836 8541 ShaUpdate(&sha, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 8542 ShaUpdate(&sha, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 8543 ShaUpdate(&sha, output + preSigIdx, preSigSz);
ashleymills 0:714293de3836 8544 ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
ashleymills 0:714293de3836 8545 #endif
ashleymills 0:714293de3836 8546
ashleymills 0:714293de3836 8547 #ifndef NO_SHA256
ashleymills 0:714293de3836 8548 InitSha256(&sha256);
ashleymills 0:714293de3836 8549 Sha256Update(&sha256, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 8550 Sha256Update(&sha256, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 8551 Sha256Update(&sha256, output + preSigIdx, preSigSz);
ashleymills 0:714293de3836 8552 Sha256Final(&sha256, hash256);
ashleymills 0:714293de3836 8553 #endif
ashleymills 0:714293de3836 8554
ashleymills 0:714293de3836 8555 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 8556 InitSha384(&sha384);
ashleymills 0:714293de3836 8557 Sha384Update(&sha384, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:714293de3836 8558 Sha384Update(&sha384, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 8559 Sha384Update(&sha384, output + preSigIdx, preSigSz);
ashleymills 0:714293de3836 8560 Sha384Final(&sha384, hash384);
ashleymills 0:714293de3836 8561 #endif
ashleymills 0:714293de3836 8562 #ifndef NO_RSA
ashleymills 0:714293de3836 8563 if (ssl->suites->sigAlgo == rsa_sa_algo) {
ashleymills 0:714293de3836 8564 byte* signBuffer = hash;
ashleymills 0:714293de3836 8565 word32 signSz = sizeof(hash);
ashleymills 0:714293de3836 8566 byte encodedSig[MAX_ENCODED_SIG_SZ];
ashleymills 0:714293de3836 8567 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 8568 byte* digest = &hash[MD5_DIGEST_SIZE];
ashleymills 0:714293de3836 8569 int typeH = SHAh;
ashleymills 0:714293de3836 8570 int digestSz = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 8571
ashleymills 0:714293de3836 8572 if (ssl->suites->hashAlgo == sha256_mac) {
ashleymills 0:714293de3836 8573 #ifndef NO_SHA256
ashleymills 0:714293de3836 8574 digest = hash256;
ashleymills 0:714293de3836 8575 typeH = SHA256h;
ashleymills 0:714293de3836 8576 digestSz = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 8577 #endif
ashleymills 0:714293de3836 8578 }
ashleymills 0:714293de3836 8579 else if (ssl->suites->hashAlgo == sha384_mac) {
ashleymills 0:714293de3836 8580 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 8581 digest = hash384;
ashleymills 0:714293de3836 8582 typeH = SHA384h;
ashleymills 0:714293de3836 8583 digestSz = SHA384_DIGEST_SIZE;
ashleymills 0:714293de3836 8584 #endif
ashleymills 0:714293de3836 8585 }
ashleymills 0:714293de3836 8586
ashleymills 0:714293de3836 8587 signSz = EncodeSignature(encodedSig, digest, digestSz,
ashleymills 0:714293de3836 8588 typeH);
ashleymills 0:714293de3836 8589 signBuffer = encodedSig;
ashleymills 0:714293de3836 8590 }
ashleymills 0:714293de3836 8591 ret = RsaSSL_Sign(signBuffer, signSz, output + idx, sigSz,
ashleymills 0:714293de3836 8592 &rsaKey, ssl->rng);
ashleymills 0:714293de3836 8593 FreeRsaKey(&rsaKey);
ashleymills 0:714293de3836 8594 if (ret <= 0)
ashleymills 0:714293de3836 8595 return ret;
ashleymills 0:714293de3836 8596 }
ashleymills 0:714293de3836 8597 #endif
ashleymills 0:714293de3836 8598 }
ashleymills 0:714293de3836 8599
ashleymills 0:714293de3836 8600 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 8601 if (ssl->options.dtls) {
ashleymills 0:714293de3836 8602 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:714293de3836 8603 return ret;
ashleymills 0:714293de3836 8604 }
ashleymills 0:714293de3836 8605 #endif
ashleymills 0:714293de3836 8606 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:714293de3836 8607
ashleymills 0:714293de3836 8608 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 8609 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 8610 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
ashleymills 0:714293de3836 8611 if (ssl->toInfoOn)
ashleymills 0:714293de3836 8612 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
ashleymills 0:714293de3836 8613 output, sendSz, ssl->heap);
ashleymills 0:714293de3836 8614 #endif
ashleymills 0:714293de3836 8615
ashleymills 0:714293de3836 8616 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:714293de3836 8617 if (ssl->options.groupMessages)
ashleymills 0:714293de3836 8618 ret = 0;
ashleymills 0:714293de3836 8619 else
ashleymills 0:714293de3836 8620 ret = SendBuffered(ssl);
ashleymills 0:714293de3836 8621 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
ashleymills 0:714293de3836 8622 }
ashleymills 0:714293de3836 8623 #endif /* OPENSSL_EXTRA */
ashleymills 0:714293de3836 8624
ashleymills 0:714293de3836 8625 return ret;
ashleymills 0:714293de3836 8626 }
ashleymills 0:714293de3836 8627
ashleymills 0:714293de3836 8628
ashleymills 0:714293de3836 8629 /* cipher requirements */
ashleymills 0:714293de3836 8630 enum {
ashleymills 0:714293de3836 8631 REQUIRES_RSA,
ashleymills 0:714293de3836 8632 REQUIRES_DHE,
ashleymills 0:714293de3836 8633 REQUIRES_ECC_DSA,
ashleymills 0:714293de3836 8634 REQUIRES_ECC_STATIC,
ashleymills 0:714293de3836 8635 REQUIRES_PSK,
ashleymills 0:714293de3836 8636 REQUIRES_NTRU,
ashleymills 0:714293de3836 8637 REQUIRES_RSA_SIG
ashleymills 0:714293de3836 8638 };
ashleymills 0:714293de3836 8639
ashleymills 0:714293de3836 8640
ashleymills 0:714293de3836 8641
ashleymills 0:714293de3836 8642 /* Does this cipher suite (first, second) have the requirement
ashleymills 0:714293de3836 8643 an ephemeral key exchange will still require the key for signing
ashleymills 0:714293de3836 8644 the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */
ashleymills 0:714293de3836 8645 static int CipherRequires(byte first, byte second, int requirement)
ashleymills 0:714293de3836 8646 {
ashleymills 0:714293de3836 8647 /* ECC extensions */
ashleymills 0:714293de3836 8648 if (first == ECC_BYTE) {
ashleymills 0:714293de3836 8649
ashleymills 0:714293de3836 8650 switch (second) {
ashleymills 0:714293de3836 8651
ashleymills 0:714293de3836 8652 #ifndef NO_RSA
ashleymills 0:714293de3836 8653 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
ashleymills 0:714293de3836 8654 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8655 return 1;
ashleymills 0:714293de3836 8656 break;
ashleymills 0:714293de3836 8657
ashleymills 0:714293de3836 8658 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
ashleymills 0:714293de3836 8659 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:714293de3836 8660 return 1;
ashleymills 0:714293de3836 8661 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:714293de3836 8662 return 1;
ashleymills 0:714293de3836 8663 break;
ashleymills 0:714293de3836 8664
ashleymills 0:714293de3836 8665 #ifndef NO_3DES
ashleymills 0:714293de3836 8666 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
ashleymills 0:714293de3836 8667 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8668 return 1;
ashleymills 0:714293de3836 8669 break;
ashleymills 0:714293de3836 8670
ashleymills 0:714293de3836 8671 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
ashleymills 0:714293de3836 8672 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:714293de3836 8673 return 1;
ashleymills 0:714293de3836 8674 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:714293de3836 8675 return 1;
ashleymills 0:714293de3836 8676 break;
ashleymills 0:714293de3836 8677 #endif
ashleymills 0:714293de3836 8678
ashleymills 0:714293de3836 8679 #ifndef NO_RC4
ashleymills 0:714293de3836 8680 case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
ashleymills 0:714293de3836 8681 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8682 return 1;
ashleymills 0:714293de3836 8683 break;
ashleymills 0:714293de3836 8684
ashleymills 0:714293de3836 8685 case TLS_ECDH_RSA_WITH_RC4_128_SHA :
ashleymills 0:714293de3836 8686 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:714293de3836 8687 return 1;
ashleymills 0:714293de3836 8688 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:714293de3836 8689 return 1;
ashleymills 0:714293de3836 8690 break;
ashleymills 0:714293de3836 8691 #endif
ashleymills 0:714293de3836 8692 #endif /* NO_RSA */
ashleymills 0:714293de3836 8693
ashleymills 0:714293de3836 8694 #ifndef NO_3DES
ashleymills 0:714293de3836 8695 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
ashleymills 0:714293de3836 8696 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:714293de3836 8697 return 1;
ashleymills 0:714293de3836 8698 break;
ashleymills 0:714293de3836 8699
ashleymills 0:714293de3836 8700 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
ashleymills 0:714293de3836 8701 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:714293de3836 8702 return 1;
ashleymills 0:714293de3836 8703 break;
ashleymills 0:714293de3836 8704 #endif
ashleymills 0:714293de3836 8705 #ifndef NO_RC4
ashleymills 0:714293de3836 8706 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
ashleymills 0:714293de3836 8707 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:714293de3836 8708 return 1;
ashleymills 0:714293de3836 8709 break;
ashleymills 0:714293de3836 8710
ashleymills 0:714293de3836 8711 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
ashleymills 0:714293de3836 8712 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:714293de3836 8713 return 1;
ashleymills 0:714293de3836 8714 break;
ashleymills 0:714293de3836 8715 #endif
ashleymills 0:714293de3836 8716 #ifndef NO_RSA
ashleymills 0:714293de3836 8717 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
ashleymills 0:714293de3836 8718 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8719 return 1;
ashleymills 0:714293de3836 8720 break;
ashleymills 0:714293de3836 8721
ashleymills 0:714293de3836 8722 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
ashleymills 0:714293de3836 8723 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:714293de3836 8724 return 1;
ashleymills 0:714293de3836 8725 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:714293de3836 8726 return 1;
ashleymills 0:714293de3836 8727 break;
ashleymills 0:714293de3836 8728 #endif
ashleymills 0:714293de3836 8729
ashleymills 0:714293de3836 8730 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
ashleymills 0:714293de3836 8731 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:714293de3836 8732 return 1;
ashleymills 0:714293de3836 8733 break;
ashleymills 0:714293de3836 8734
ashleymills 0:714293de3836 8735 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
ashleymills 0:714293de3836 8736 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:714293de3836 8737 return 1;
ashleymills 0:714293de3836 8738 break;
ashleymills 0:714293de3836 8739
ashleymills 0:714293de3836 8740 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
ashleymills 0:714293de3836 8741 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:714293de3836 8742 return 1;
ashleymills 0:714293de3836 8743 break;
ashleymills 0:714293de3836 8744
ashleymills 0:714293de3836 8745 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
ashleymills 0:714293de3836 8746 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:714293de3836 8747 return 1;
ashleymills 0:714293de3836 8748 break;
ashleymills 0:714293de3836 8749
ashleymills 0:714293de3836 8750 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
ashleymills 0:714293de3836 8751 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:714293de3836 8752 return 1;
ashleymills 0:714293de3836 8753 break;
ashleymills 0:714293de3836 8754
ashleymills 0:714293de3836 8755 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
ashleymills 0:714293de3836 8756 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:714293de3836 8757 return 1;
ashleymills 0:714293de3836 8758 break;
ashleymills 0:714293de3836 8759
ashleymills 0:714293de3836 8760 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
ashleymills 0:714293de3836 8761 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:714293de3836 8762 return 1;
ashleymills 0:714293de3836 8763 break;
ashleymills 0:714293de3836 8764
ashleymills 0:714293de3836 8765 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
ashleymills 0:714293de3836 8766 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:714293de3836 8767 return 1;
ashleymills 0:714293de3836 8768 break;
ashleymills 0:714293de3836 8769
ashleymills 0:714293de3836 8770 #ifndef NO_RSA
ashleymills 0:714293de3836 8771 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
ashleymills 0:714293de3836 8772 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8773 return 1;
ashleymills 0:714293de3836 8774 break;
ashleymills 0:714293de3836 8775
ashleymills 0:714293de3836 8776 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
ashleymills 0:714293de3836 8777 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8778 return 1;
ashleymills 0:714293de3836 8779 break;
ashleymills 0:714293de3836 8780
ashleymills 0:714293de3836 8781 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
ashleymills 0:714293de3836 8782 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:714293de3836 8783 return 1;
ashleymills 0:714293de3836 8784 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:714293de3836 8785 return 1;
ashleymills 0:714293de3836 8786 break;
ashleymills 0:714293de3836 8787
ashleymills 0:714293de3836 8788 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
ashleymills 0:714293de3836 8789 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:714293de3836 8790 return 1;
ashleymills 0:714293de3836 8791 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:714293de3836 8792 return 1;
ashleymills 0:714293de3836 8793 break;
ashleymills 0:714293de3836 8794
ashleymills 0:714293de3836 8795 case TLS_RSA_WITH_AES_128_CCM_8 :
ashleymills 0:714293de3836 8796 case TLS_RSA_WITH_AES_256_CCM_8 :
ashleymills 0:714293de3836 8797 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8798 return 1;
ashleymills 0:714293de3836 8799 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:714293de3836 8800 return 1;
ashleymills 0:714293de3836 8801 break;
ashleymills 0:714293de3836 8802
ashleymills 0:714293de3836 8803 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
ashleymills 0:714293de3836 8804 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
ashleymills 0:714293de3836 8805 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8806 return 1;
ashleymills 0:714293de3836 8807 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:714293de3836 8808 return 1;
ashleymills 0:714293de3836 8809 break;
ashleymills 0:714293de3836 8810
ashleymills 0:714293de3836 8811 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
ashleymills 0:714293de3836 8812 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
ashleymills 0:714293de3836 8813 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:714293de3836 8814 return 1;
ashleymills 0:714293de3836 8815 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:714293de3836 8816 return 1;
ashleymills 0:714293de3836 8817 break;
ashleymills 0:714293de3836 8818 #endif
ashleymills 0:714293de3836 8819
ashleymills 0:714293de3836 8820 case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 :
ashleymills 0:714293de3836 8821 case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
ashleymills 0:714293de3836 8822 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:714293de3836 8823 return 1;
ashleymills 0:714293de3836 8824 break;
ashleymills 0:714293de3836 8825
ashleymills 0:714293de3836 8826 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
ashleymills 0:714293de3836 8827 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
ashleymills 0:714293de3836 8828 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:714293de3836 8829 return 1;
ashleymills 0:714293de3836 8830 break;
ashleymills 0:714293de3836 8831
ashleymills 0:714293de3836 8832 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
ashleymills 0:714293de3836 8833 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
ashleymills 0:714293de3836 8834 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:714293de3836 8835 return 1;
ashleymills 0:714293de3836 8836 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:714293de3836 8837 return 1;
ashleymills 0:714293de3836 8838 break;
ashleymills 0:714293de3836 8839
ashleymills 0:714293de3836 8840 default:
ashleymills 0:714293de3836 8841 CYASSL_MSG("Unsupported cipher suite, CipherRequires ECC");
ashleymills 0:714293de3836 8842 return 0;
ashleymills 0:714293de3836 8843 } /* switch */
ashleymills 0:714293de3836 8844 } /* if */
ashleymills 0:714293de3836 8845 if (first != ECC_BYTE) { /* normal suites */
ashleymills 0:714293de3836 8846 switch (second) {
ashleymills 0:714293de3836 8847
ashleymills 0:714293de3836 8848 #ifndef NO_RSA
ashleymills 0:714293de3836 8849 case SSL_RSA_WITH_RC4_128_SHA :
ashleymills 0:714293de3836 8850 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8851 return 1;
ashleymills 0:714293de3836 8852 break;
ashleymills 0:714293de3836 8853
ashleymills 0:714293de3836 8854 case TLS_NTRU_RSA_WITH_RC4_128_SHA :
ashleymills 0:714293de3836 8855 if (requirement == REQUIRES_NTRU)
ashleymills 0:714293de3836 8856 return 1;
ashleymills 0:714293de3836 8857 break;
ashleymills 0:714293de3836 8858
ashleymills 0:714293de3836 8859 case SSL_RSA_WITH_RC4_128_MD5 :
ashleymills 0:714293de3836 8860 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8861 return 1;
ashleymills 0:714293de3836 8862 break;
ashleymills 0:714293de3836 8863
ashleymills 0:714293de3836 8864 case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
ashleymills 0:714293de3836 8865 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8866 return 1;
ashleymills 0:714293de3836 8867 break;
ashleymills 0:714293de3836 8868
ashleymills 0:714293de3836 8869 case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
ashleymills 0:714293de3836 8870 if (requirement == REQUIRES_NTRU)
ashleymills 0:714293de3836 8871 return 1;
ashleymills 0:714293de3836 8872 break;
ashleymills 0:714293de3836 8873
ashleymills 0:714293de3836 8874 case TLS_RSA_WITH_AES_128_CBC_SHA :
ashleymills 0:714293de3836 8875 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8876 return 1;
ashleymills 0:714293de3836 8877 break;
ashleymills 0:714293de3836 8878
ashleymills 0:714293de3836 8879 case TLS_RSA_WITH_AES_128_CBC_SHA256 :
ashleymills 0:714293de3836 8880 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8881 return 1;
ashleymills 0:714293de3836 8882 break;
ashleymills 0:714293de3836 8883
ashleymills 0:714293de3836 8884 case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
ashleymills 0:714293de3836 8885 if (requirement == REQUIRES_NTRU)
ashleymills 0:714293de3836 8886 return 1;
ashleymills 0:714293de3836 8887 break;
ashleymills 0:714293de3836 8888
ashleymills 0:714293de3836 8889 case TLS_RSA_WITH_AES_256_CBC_SHA :
ashleymills 0:714293de3836 8890 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8891 return 1;
ashleymills 0:714293de3836 8892 break;
ashleymills 0:714293de3836 8893
ashleymills 0:714293de3836 8894 case TLS_RSA_WITH_AES_256_CBC_SHA256 :
ashleymills 0:714293de3836 8895 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8896 return 1;
ashleymills 0:714293de3836 8897 break;
ashleymills 0:714293de3836 8898
ashleymills 0:714293de3836 8899 case TLS_RSA_WITH_NULL_SHA :
ashleymills 0:714293de3836 8900 case TLS_RSA_WITH_NULL_SHA256 :
ashleymills 0:714293de3836 8901 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8902 return 1;
ashleymills 0:714293de3836 8903 break;
ashleymills 0:714293de3836 8904
ashleymills 0:714293de3836 8905 case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
ashleymills 0:714293de3836 8906 if (requirement == REQUIRES_NTRU)
ashleymills 0:714293de3836 8907 return 1;
ashleymills 0:714293de3836 8908 break;
ashleymills 0:714293de3836 8909 #endif
ashleymills 0:714293de3836 8910
ashleymills 0:714293de3836 8911 case TLS_PSK_WITH_AES_128_CBC_SHA256 :
ashleymills 0:714293de3836 8912 if (requirement == REQUIRES_PSK)
ashleymills 0:714293de3836 8913 return 1;
ashleymills 0:714293de3836 8914 break;
ashleymills 0:714293de3836 8915
ashleymills 0:714293de3836 8916 case TLS_PSK_WITH_AES_128_CBC_SHA :
ashleymills 0:714293de3836 8917 if (requirement == REQUIRES_PSK)
ashleymills 0:714293de3836 8918 return 1;
ashleymills 0:714293de3836 8919 break;
ashleymills 0:714293de3836 8920
ashleymills 0:714293de3836 8921 case TLS_PSK_WITH_AES_256_CBC_SHA :
ashleymills 0:714293de3836 8922 if (requirement == REQUIRES_PSK)
ashleymills 0:714293de3836 8923 return 1;
ashleymills 0:714293de3836 8924 break;
ashleymills 0:714293de3836 8925
ashleymills 0:714293de3836 8926 case TLS_PSK_WITH_NULL_SHA256 :
ashleymills 0:714293de3836 8927 if (requirement == REQUIRES_PSK)
ashleymills 0:714293de3836 8928 return 1;
ashleymills 0:714293de3836 8929 break;
ashleymills 0:714293de3836 8930
ashleymills 0:714293de3836 8931 case TLS_PSK_WITH_NULL_SHA :
ashleymills 0:714293de3836 8932 if (requirement == REQUIRES_PSK)
ashleymills 0:714293de3836 8933 return 1;
ashleymills 0:714293de3836 8934 break;
ashleymills 0:714293de3836 8935
ashleymills 0:714293de3836 8936 #ifndef NO_RSA
ashleymills 0:714293de3836 8937 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
ashleymills 0:714293de3836 8938 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8939 return 1;
ashleymills 0:714293de3836 8940 if (requirement == REQUIRES_DHE)
ashleymills 0:714293de3836 8941 return 1;
ashleymills 0:714293de3836 8942 break;
ashleymills 0:714293de3836 8943
ashleymills 0:714293de3836 8944 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
ashleymills 0:714293de3836 8945 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8946 return 1;
ashleymills 0:714293de3836 8947 if (requirement == REQUIRES_DHE)
ashleymills 0:714293de3836 8948 return 1;
ashleymills 0:714293de3836 8949 break;
ashleymills 0:714293de3836 8950
ashleymills 0:714293de3836 8951 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
ashleymills 0:714293de3836 8952 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8953 return 1;
ashleymills 0:714293de3836 8954 if (requirement == REQUIRES_DHE)
ashleymills 0:714293de3836 8955 return 1;
ashleymills 0:714293de3836 8956 break;
ashleymills 0:714293de3836 8957
ashleymills 0:714293de3836 8958 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
ashleymills 0:714293de3836 8959 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8960 return 1;
ashleymills 0:714293de3836 8961 if (requirement == REQUIRES_DHE)
ashleymills 0:714293de3836 8962 return 1;
ashleymills 0:714293de3836 8963 break;
ashleymills 0:714293de3836 8964
ashleymills 0:714293de3836 8965 case TLS_RSA_WITH_HC_128_CBC_MD5 :
ashleymills 0:714293de3836 8966 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8967 return 1;
ashleymills 0:714293de3836 8968 break;
ashleymills 0:714293de3836 8969
ashleymills 0:714293de3836 8970 case TLS_RSA_WITH_HC_128_CBC_SHA :
ashleymills 0:714293de3836 8971 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8972 return 1;
ashleymills 0:714293de3836 8973 break;
ashleymills 0:714293de3836 8974
ashleymills 0:714293de3836 8975 case TLS_RSA_WITH_RABBIT_CBC_SHA :
ashleymills 0:714293de3836 8976 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8977 return 1;
ashleymills 0:714293de3836 8978 break;
ashleymills 0:714293de3836 8979
ashleymills 0:714293de3836 8980 case TLS_RSA_WITH_AES_128_GCM_SHA256 :
ashleymills 0:714293de3836 8981 case TLS_RSA_WITH_AES_256_GCM_SHA384 :
ashleymills 0:714293de3836 8982 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8983 return 1;
ashleymills 0:714293de3836 8984 break;
ashleymills 0:714293de3836 8985
ashleymills 0:714293de3836 8986 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
ashleymills 0:714293de3836 8987 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
ashleymills 0:714293de3836 8988 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8989 return 1;
ashleymills 0:714293de3836 8990 if (requirement == REQUIRES_DHE)
ashleymills 0:714293de3836 8991 return 1;
ashleymills 0:714293de3836 8992 break;
ashleymills 0:714293de3836 8993
ashleymills 0:714293de3836 8994 case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
ashleymills 0:714293de3836 8995 case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
ashleymills 0:714293de3836 8996 case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
ashleymills 0:714293de3836 8997 case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
ashleymills 0:714293de3836 8998 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 8999 return 1;
ashleymills 0:714293de3836 9000 break;
ashleymills 0:714293de3836 9001
ashleymills 0:714293de3836 9002 case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
ashleymills 0:714293de3836 9003 case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
ashleymills 0:714293de3836 9004 case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
ashleymills 0:714293de3836 9005 case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
ashleymills 0:714293de3836 9006 if (requirement == REQUIRES_RSA)
ashleymills 0:714293de3836 9007 return 1;
ashleymills 0:714293de3836 9008 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:714293de3836 9009 return 1;
ashleymills 0:714293de3836 9010 if (requirement == REQUIRES_DHE)
ashleymills 0:714293de3836 9011 return 1;
ashleymills 0:714293de3836 9012 break;
ashleymills 0:714293de3836 9013 #endif
ashleymills 0:714293de3836 9014
ashleymills 0:714293de3836 9015 default:
ashleymills 0:714293de3836 9016 CYASSL_MSG("Unsupported cipher suite, CipherRequires");
ashleymills 0:714293de3836 9017 return 0;
ashleymills 0:714293de3836 9018 } /* switch */
ashleymills 0:714293de3836 9019 } /* if ECC / Normal suites else */
ashleymills 0:714293de3836 9020
ashleymills 0:714293de3836 9021 return 0;
ashleymills 0:714293de3836 9022 }
ashleymills 0:714293de3836 9023
ashleymills 0:714293de3836 9024
ashleymills 0:714293de3836 9025
ashleymills 0:714293de3836 9026
ashleymills 0:714293de3836 9027
ashleymills 0:714293de3836 9028 /* Make sure cert/key are valid for this suite, true on success */
ashleymills 0:714293de3836 9029 static int VerifySuite(CYASSL* ssl, word16 idx)
ashleymills 0:714293de3836 9030 {
ashleymills 0:714293de3836 9031 int haveRSA = !ssl->options.haveStaticECC;
ashleymills 0:714293de3836 9032 int havePSK = 0;
ashleymills 0:714293de3836 9033 byte first;
ashleymills 0:714293de3836 9034 byte second;
ashleymills 0:714293de3836 9035
ashleymills 0:714293de3836 9036 CYASSL_ENTER("VerifySuite");
ashleymills 0:714293de3836 9037
ashleymills 0:714293de3836 9038 if (ssl->suites == NULL) {
ashleymills 0:714293de3836 9039 CYASSL_MSG("Suites pointer error");
ashleymills 0:714293de3836 9040 return 0;
ashleymills 0:714293de3836 9041 }
ashleymills 0:714293de3836 9042
ashleymills 0:714293de3836 9043 first = ssl->suites->suites[idx];
ashleymills 0:714293de3836 9044 second = ssl->suites->suites[idx+1];
ashleymills 0:714293de3836 9045
ashleymills 0:714293de3836 9046 #ifndef NO_PSK
ashleymills 0:714293de3836 9047 havePSK = ssl->options.havePSK;
ashleymills 0:714293de3836 9048 #endif
ashleymills 0:714293de3836 9049
ashleymills 0:714293de3836 9050 if (ssl->options.haveNTRU)
ashleymills 0:714293de3836 9051 haveRSA = 0;
ashleymills 0:714293de3836 9052
ashleymills 0:714293de3836 9053 if (CipherRequires(first, second, REQUIRES_RSA)) {
ashleymills 0:714293de3836 9054 CYASSL_MSG("Requires RSA");
ashleymills 0:714293de3836 9055 if (haveRSA == 0) {
ashleymills 0:714293de3836 9056 CYASSL_MSG("Don't have RSA");
ashleymills 0:714293de3836 9057 return 0;
ashleymills 0:714293de3836 9058 }
ashleymills 0:714293de3836 9059 }
ashleymills 0:714293de3836 9060
ashleymills 0:714293de3836 9061 if (CipherRequires(first, second, REQUIRES_DHE)) {
ashleymills 0:714293de3836 9062 CYASSL_MSG("Requires DHE");
ashleymills 0:714293de3836 9063 if (ssl->options.haveDH == 0) {
ashleymills 0:714293de3836 9064 CYASSL_MSG("Don't have DHE");
ashleymills 0:714293de3836 9065 return 0;
ashleymills 0:714293de3836 9066 }
ashleymills 0:714293de3836 9067 }
ashleymills 0:714293de3836 9068
ashleymills 0:714293de3836 9069 if (CipherRequires(first, second, REQUIRES_ECC_DSA)) {
ashleymills 0:714293de3836 9070 CYASSL_MSG("Requires ECCDSA");
ashleymills 0:714293de3836 9071 if (ssl->options.haveECDSAsig == 0) {
ashleymills 0:714293de3836 9072 CYASSL_MSG("Don't have ECCDSA");
ashleymills 0:714293de3836 9073 return 0;
ashleymills 0:714293de3836 9074 }
ashleymills 0:714293de3836 9075 }
ashleymills 0:714293de3836 9076
ashleymills 0:714293de3836 9077 if (CipherRequires(first, second, REQUIRES_ECC_STATIC)) {
ashleymills 0:714293de3836 9078 CYASSL_MSG("Requires static ECC");
ashleymills 0:714293de3836 9079 if (ssl->options.haveStaticECC == 0) {
ashleymills 0:714293de3836 9080 CYASSL_MSG("Don't have static ECC");
ashleymills 0:714293de3836 9081 return 0;
ashleymills 0:714293de3836 9082 }
ashleymills 0:714293de3836 9083 }
ashleymills 0:714293de3836 9084
ashleymills 0:714293de3836 9085 if (CipherRequires(first, second, REQUIRES_PSK)) {
ashleymills 0:714293de3836 9086 CYASSL_MSG("Requires PSK");
ashleymills 0:714293de3836 9087 if (havePSK == 0) {
ashleymills 0:714293de3836 9088 CYASSL_MSG("Don't have PSK");
ashleymills 0:714293de3836 9089 return 0;
ashleymills 0:714293de3836 9090 }
ashleymills 0:714293de3836 9091 }
ashleymills 0:714293de3836 9092
ashleymills 0:714293de3836 9093 if (CipherRequires(first, second, REQUIRES_NTRU)) {
ashleymills 0:714293de3836 9094 CYASSL_MSG("Requires NTRU");
ashleymills 0:714293de3836 9095 if (ssl->options.haveNTRU == 0) {
ashleymills 0:714293de3836 9096 CYASSL_MSG("Don't have NTRU");
ashleymills 0:714293de3836 9097 return 0;
ashleymills 0:714293de3836 9098 }
ashleymills 0:714293de3836 9099 }
ashleymills 0:714293de3836 9100
ashleymills 0:714293de3836 9101 if (CipherRequires(first, second, REQUIRES_RSA_SIG)) {
ashleymills 0:714293de3836 9102 CYASSL_MSG("Requires RSA Signature");
ashleymills 0:714293de3836 9103 if (ssl->options.side == SERVER_END && ssl->options.haveECDSAsig == 1) {
ashleymills 0:714293de3836 9104 CYASSL_MSG("Don't have RSA Signature");
ashleymills 0:714293de3836 9105 return 0;
ashleymills 0:714293de3836 9106 }
ashleymills 0:714293de3836 9107 }
ashleymills 0:714293de3836 9108
ashleymills 0:714293de3836 9109 /* ECCDHE is always supported if ECC on */
ashleymills 0:714293de3836 9110
ashleymills 0:714293de3836 9111 return 1;
ashleymills 0:714293de3836 9112 }
ashleymills 0:714293de3836 9113
ashleymills 0:714293de3836 9114
ashleymills 0:714293de3836 9115 static int MatchSuite(CYASSL* ssl, Suites* peerSuites)
ashleymills 0:714293de3836 9116 {
ashleymills 0:714293de3836 9117 word16 i, j;
ashleymills 0:714293de3836 9118
ashleymills 0:714293de3836 9119 CYASSL_ENTER("MatchSuite");
ashleymills 0:714293de3836 9120
ashleymills 0:714293de3836 9121 /* & 0x1 equivalent % 2 */
ashleymills 0:714293de3836 9122 if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1)
ashleymills 0:714293de3836 9123 return MATCH_SUITE_ERROR;
ashleymills 0:714293de3836 9124
ashleymills 0:714293de3836 9125 if (ssl->suites == NULL)
ashleymills 0:714293de3836 9126 return SUITES_ERROR;
ashleymills 0:714293de3836 9127 /* start with best, if a match we are good */
ashleymills 0:714293de3836 9128 for (i = 0; i < ssl->suites->suiteSz; i += 2)
ashleymills 0:714293de3836 9129 for (j = 0; j < peerSuites->suiteSz; j += 2)
ashleymills 0:714293de3836 9130 if (ssl->suites->suites[i] == peerSuites->suites[j] &&
ashleymills 0:714293de3836 9131 ssl->suites->suites[i+1] == peerSuites->suites[j+1] ) {
ashleymills 0:714293de3836 9132
ashleymills 0:714293de3836 9133 if (VerifySuite(ssl, i)) {
ashleymills 0:714293de3836 9134 int result;
ashleymills 0:714293de3836 9135 CYASSL_MSG("Verified suite validity");
ashleymills 0:714293de3836 9136 ssl->options.cipherSuite0 = ssl->suites->suites[i];
ashleymills 0:714293de3836 9137 ssl->options.cipherSuite = ssl->suites->suites[i+1];
ashleymills 0:714293de3836 9138 result = SetCipherSpecs(ssl);
ashleymills 0:714293de3836 9139 if (result == 0)
ashleymills 0:714293de3836 9140 PickHashSigAlgo(ssl, peerSuites->hashSigAlgo,
ashleymills 0:714293de3836 9141 peerSuites->hashSigAlgoSz);
ashleymills 0:714293de3836 9142 return result;
ashleymills 0:714293de3836 9143 }
ashleymills 0:714293de3836 9144 else {
ashleymills 0:714293de3836 9145 CYASSL_MSG("Could not verify suite validity, continue");
ashleymills 0:714293de3836 9146 }
ashleymills 0:714293de3836 9147 }
ashleymills 0:714293de3836 9148
ashleymills 0:714293de3836 9149 return MATCH_SUITE_ERROR;
ashleymills 0:714293de3836 9150 }
ashleymills 0:714293de3836 9151
ashleymills 0:714293de3836 9152
ashleymills 0:714293de3836 9153 /* process old style client hello, deprecate? */
ashleymills 0:714293de3836 9154 int ProcessOldClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
ashleymills 0:714293de3836 9155 word32 inSz, word16 sz)
ashleymills 0:714293de3836 9156 {
ashleymills 0:714293de3836 9157 word32 idx = *inOutIdx;
ashleymills 0:714293de3836 9158 word16 sessionSz;
ashleymills 0:714293de3836 9159 word16 randomSz;
ashleymills 0:714293de3836 9160 word16 i, j;
ashleymills 0:714293de3836 9161 ProtocolVersion pv;
ashleymills 0:714293de3836 9162 Suites clSuites;
ashleymills 0:714293de3836 9163
ashleymills 0:714293de3836 9164 (void)inSz;
ashleymills 0:714293de3836 9165 CYASSL_MSG("Got old format client hello");
ashleymills 0:714293de3836 9166 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 9167 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 9168 AddPacketName("ClientHello", &ssl->handShakeInfo);
ashleymills 0:714293de3836 9169 if (ssl->toInfoOn)
ashleymills 0:714293de3836 9170 AddLateName("ClientHello", &ssl->timeoutInfo);
ashleymills 0:714293de3836 9171 #endif
ashleymills 0:714293de3836 9172
ashleymills 0:714293de3836 9173 /* manually hash input since different format */
ashleymills 0:714293de3836 9174 #ifndef NO_OLD_TLS
ashleymills 0:714293de3836 9175 #ifndef NO_MD5
ashleymills 0:714293de3836 9176 Md5Update(&ssl->hashMd5, input + idx, sz);
ashleymills 0:714293de3836 9177 #endif
ashleymills 0:714293de3836 9178 #ifndef NO_SHA
ashleymills 0:714293de3836 9179 ShaUpdate(&ssl->hashSha, input + idx, sz);
ashleymills 0:714293de3836 9180 #endif
ashleymills 0:714293de3836 9181 #endif
ashleymills 0:714293de3836 9182 #ifndef NO_SHA256
ashleymills 0:714293de3836 9183 if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:714293de3836 9184 Sha256Update(&ssl->hashSha256, input + idx, sz);
ashleymills 0:714293de3836 9185 #endif
ashleymills 0:714293de3836 9186
ashleymills 0:714293de3836 9187 /* does this value mean client_hello? */
ashleymills 0:714293de3836 9188 idx++;
ashleymills 0:714293de3836 9189
ashleymills 0:714293de3836 9190 /* version */
ashleymills 0:714293de3836 9191 pv.major = input[idx++];
ashleymills 0:714293de3836 9192 pv.minor = input[idx++];
ashleymills 0:714293de3836 9193 ssl->chVersion = pv; /* store */
ashleymills 0:714293de3836 9194
ashleymills 0:714293de3836 9195 if (ssl->version.minor > pv.minor) {
ashleymills 0:714293de3836 9196 byte haveRSA = 0;
ashleymills 0:714293de3836 9197 byte havePSK = 0;
ashleymills 0:714293de3836 9198 if (!ssl->options.downgrade) {
ashleymills 0:714293de3836 9199 CYASSL_MSG("Client trying to connect with lesser version");
ashleymills 0:714293de3836 9200 return VERSION_ERROR;
ashleymills 0:714293de3836 9201 }
ashleymills 0:714293de3836 9202 if (pv.minor == SSLv3_MINOR) {
ashleymills 0:714293de3836 9203 /* turn off tls */
ashleymills 0:714293de3836 9204 CYASSL_MSG(" downgrading to SSLv3");
ashleymills 0:714293de3836 9205 ssl->options.tls = 0;
ashleymills 0:714293de3836 9206 ssl->options.tls1_1 = 0;
ashleymills 0:714293de3836 9207 ssl->version.minor = SSLv3_MINOR;
ashleymills 0:714293de3836 9208 }
ashleymills 0:714293de3836 9209 else if (pv.minor == TLSv1_MINOR) {
ashleymills 0:714293de3836 9210 CYASSL_MSG(" downgrading to TLSv1");
ashleymills 0:714293de3836 9211 /* turn off tls 1.1+ */
ashleymills 0:714293de3836 9212 ssl->options.tls1_1 = 0;
ashleymills 0:714293de3836 9213 ssl->version.minor = TLSv1_MINOR;
ashleymills 0:714293de3836 9214 }
ashleymills 0:714293de3836 9215 else if (pv.minor == TLSv1_1_MINOR) {
ashleymills 0:714293de3836 9216 CYASSL_MSG(" downgrading to TLSv1.1");
ashleymills 0:714293de3836 9217 ssl->version.minor = TLSv1_1_MINOR;
ashleymills 0:714293de3836 9218 }
ashleymills 0:714293de3836 9219 #ifndef NO_RSA
ashleymills 0:714293de3836 9220 haveRSA = 1;
ashleymills 0:714293de3836 9221 #endif
ashleymills 0:714293de3836 9222 #ifndef NO_PSK
ashleymills 0:714293de3836 9223 havePSK = ssl->options.havePSK;
ashleymills 0:714293de3836 9224 #endif
ashleymills 0:714293de3836 9225
ashleymills 0:714293de3836 9226 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
ashleymills 0:714293de3836 9227 ssl->options.haveDH, ssl->options.haveNTRU,
ashleymills 0:714293de3836 9228 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
ashleymills 0:714293de3836 9229 ssl->options.side);
ashleymills 0:714293de3836 9230 }
ashleymills 0:714293de3836 9231
ashleymills 0:714293de3836 9232 /* suite size */
ashleymills 0:714293de3836 9233 ato16(&input[idx], &clSuites.suiteSz);
ashleymills 0:714293de3836 9234 idx += 2;
ashleymills 0:714293de3836 9235
ashleymills 0:714293de3836 9236 if (clSuites.suiteSz > MAX_SUITE_SZ)
ashleymills 0:714293de3836 9237 return BUFFER_ERROR;
ashleymills 0:714293de3836 9238
ashleymills 0:714293de3836 9239 /* session size */
ashleymills 0:714293de3836 9240 ato16(&input[idx], &sessionSz);
ashleymills 0:714293de3836 9241 idx += 2;
ashleymills 0:714293de3836 9242
ashleymills 0:714293de3836 9243 if (sessionSz > ID_LEN)
ashleymills 0:714293de3836 9244 return BUFFER_ERROR;
ashleymills 0:714293de3836 9245
ashleymills 0:714293de3836 9246 /* random size */
ashleymills 0:714293de3836 9247 ato16(&input[idx], &randomSz);
ashleymills 0:714293de3836 9248 idx += 2;
ashleymills 0:714293de3836 9249
ashleymills 0:714293de3836 9250 if (randomSz > RAN_LEN)
ashleymills 0:714293de3836 9251 return BUFFER_ERROR;
ashleymills 0:714293de3836 9252
ashleymills 0:714293de3836 9253 /* suites */
ashleymills 0:714293de3836 9254 for (i = 0, j = 0; i < clSuites.suiteSz; i += 3) {
ashleymills 0:714293de3836 9255 byte first = input[idx++];
ashleymills 0:714293de3836 9256 if (!first) { /* implicit: skip sslv2 type */
ashleymills 0:714293de3836 9257 XMEMCPY(&clSuites.suites[j], &input[idx], 2);
ashleymills 0:714293de3836 9258 j += 2;
ashleymills 0:714293de3836 9259 }
ashleymills 0:714293de3836 9260 idx += 2;
ashleymills 0:714293de3836 9261 }
ashleymills 0:714293de3836 9262 clSuites.suiteSz = j;
ashleymills 0:714293de3836 9263
ashleymills 0:714293de3836 9264 /* session id */
ashleymills 0:714293de3836 9265 if (sessionSz) {
ashleymills 0:714293de3836 9266 XMEMCPY(ssl->arrays->sessionID, input + idx, sessionSz);
ashleymills 0:714293de3836 9267 idx += sessionSz;
ashleymills 0:714293de3836 9268 ssl->options.resuming = 1;
ashleymills 0:714293de3836 9269 }
ashleymills 0:714293de3836 9270
ashleymills 0:714293de3836 9271 /* random */
ashleymills 0:714293de3836 9272 if (randomSz < RAN_LEN)
ashleymills 0:714293de3836 9273 XMEMSET(ssl->arrays->clientRandom, 0, RAN_LEN - randomSz);
ashleymills 0:714293de3836 9274 XMEMCPY(&ssl->arrays->clientRandom[RAN_LEN - randomSz], input + idx,
ashleymills 0:714293de3836 9275 randomSz);
ashleymills 0:714293de3836 9276 idx += randomSz;
ashleymills 0:714293de3836 9277
ashleymills 0:714293de3836 9278 if (ssl->options.usingCompression)
ashleymills 0:714293de3836 9279 ssl->options.usingCompression = 0; /* turn off */
ashleymills 0:714293de3836 9280
ashleymills 0:714293de3836 9281 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
ashleymills 0:714293de3836 9282 *inOutIdx = idx;
ashleymills 0:714293de3836 9283
ashleymills 0:714293de3836 9284 ssl->options.haveSessionId = 1;
ashleymills 0:714293de3836 9285 /* DoClientHello uses same resume code */
ashleymills 0:714293de3836 9286 if (ssl->options.resuming) { /* let's try */
ashleymills 0:714293de3836 9287 int ret = -1;
ashleymills 0:714293de3836 9288 CYASSL_SESSION* session = GetSession(ssl,ssl->arrays->masterSecret);
ashleymills 0:714293de3836 9289 if (!session) {
ashleymills 0:714293de3836 9290 CYASSL_MSG("Session lookup for resume failed");
ashleymills 0:714293de3836 9291 ssl->options.resuming = 0;
ashleymills 0:714293de3836 9292 } else {
ashleymills 0:714293de3836 9293 if (MatchSuite(ssl, &clSuites) < 0) {
ashleymills 0:714293de3836 9294 CYASSL_MSG("Unsupported cipher suite, OldClientHello");
ashleymills 0:714293de3836 9295 return UNSUPPORTED_SUITE;
ashleymills 0:714293de3836 9296 }
ashleymills 0:714293de3836 9297 #ifdef SESSION_CERTS
ashleymills 0:714293de3836 9298 ssl->session = *session; /* restore session certs. */
ashleymills 0:714293de3836 9299 #endif
ashleymills 0:714293de3836 9300 RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 9301 #ifdef NO_OLD_TLS
ashleymills 0:714293de3836 9302 ret = DeriveTlsKeys(ssl);
ashleymills 0:714293de3836 9303 #else
ashleymills 0:714293de3836 9304 #ifndef NO_TLS
ashleymills 0:714293de3836 9305 if (ssl->options.tls)
ashleymills 0:714293de3836 9306 ret = DeriveTlsKeys(ssl);
ashleymills 0:714293de3836 9307 #endif
ashleymills 0:714293de3836 9308 if (!ssl->options.tls)
ashleymills 0:714293de3836 9309 ret = DeriveKeys(ssl);
ashleymills 0:714293de3836 9310 #endif
ashleymills 0:714293de3836 9311 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
ashleymills 0:714293de3836 9312
ashleymills 0:714293de3836 9313 return ret;
ashleymills 0:714293de3836 9314 }
ashleymills 0:714293de3836 9315 }
ashleymills 0:714293de3836 9316
ashleymills 0:714293de3836 9317 return MatchSuite(ssl, &clSuites);
ashleymills 0:714293de3836 9318 }
ashleymills 0:714293de3836 9319
ashleymills 0:714293de3836 9320
ashleymills 0:714293de3836 9321 static int DoClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
ashleymills 0:714293de3836 9322 word32 totalSz, word32 helloSz)
ashleymills 0:714293de3836 9323 {
ashleymills 0:714293de3836 9324 byte b;
ashleymills 0:714293de3836 9325 ProtocolVersion pv;
ashleymills 0:714293de3836 9326 Suites clSuites;
ashleymills 0:714293de3836 9327 word32 i = *inOutIdx;
ashleymills 0:714293de3836 9328 word32 begin = i;
ashleymills 0:714293de3836 9329
ashleymills 0:714293de3836 9330 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 9331 if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
ashleymills 0:714293de3836 9332 if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
ashleymills 0:714293de3836 9333 #endif
ashleymills 0:714293de3836 9334 /* make sure can read up to session */
ashleymills 0:714293de3836 9335 if (i + sizeof(pv) + RAN_LEN + ENUM_LEN > totalSz)
ashleymills 0:714293de3836 9336 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 9337
ashleymills 0:714293de3836 9338 XMEMCPY(&pv, input + i, sizeof(pv));
ashleymills 0:714293de3836 9339 ssl->chVersion = pv; /* store */
ashleymills 0:714293de3836 9340 i += (word32)sizeof(pv);
ashleymills 0:714293de3836 9341 if (ssl->version.minor > pv.minor) {
ashleymills 0:714293de3836 9342 byte haveRSA = 0;
ashleymills 0:714293de3836 9343 byte havePSK = 0;
ashleymills 0:714293de3836 9344 if (!ssl->options.downgrade) {
ashleymills 0:714293de3836 9345 CYASSL_MSG("Client trying to connect with lesser version");
ashleymills 0:714293de3836 9346 return VERSION_ERROR;
ashleymills 0:714293de3836 9347 }
ashleymills 0:714293de3836 9348 if (pv.minor == SSLv3_MINOR) {
ashleymills 0:714293de3836 9349 /* turn off tls */
ashleymills 0:714293de3836 9350 CYASSL_MSG(" downgrading to SSLv3");
ashleymills 0:714293de3836 9351 ssl->options.tls = 0;
ashleymills 0:714293de3836 9352 ssl->options.tls1_1 = 0;
ashleymills 0:714293de3836 9353 ssl->version.minor = SSLv3_MINOR;
ashleymills 0:714293de3836 9354 }
ashleymills 0:714293de3836 9355 else if (pv.minor == TLSv1_MINOR) {
ashleymills 0:714293de3836 9356 /* turn off tls 1.1+ */
ashleymills 0:714293de3836 9357 CYASSL_MSG(" downgrading to TLSv1");
ashleymills 0:714293de3836 9358 ssl->options.tls1_1 = 0;
ashleymills 0:714293de3836 9359 ssl->version.minor = TLSv1_MINOR;
ashleymills 0:714293de3836 9360 }
ashleymills 0:714293de3836 9361 else if (pv.minor == TLSv1_1_MINOR) {
ashleymills 0:714293de3836 9362 CYASSL_MSG(" downgrading to TLSv1.1");
ashleymills 0:714293de3836 9363 ssl->version.minor = TLSv1_1_MINOR;
ashleymills 0:714293de3836 9364 }
ashleymills 0:714293de3836 9365 #ifndef NO_RSA
ashleymills 0:714293de3836 9366 haveRSA = 1;
ashleymills 0:714293de3836 9367 #endif
ashleymills 0:714293de3836 9368 #ifndef NO_PSK
ashleymills 0:714293de3836 9369 havePSK = ssl->options.havePSK;
ashleymills 0:714293de3836 9370 #endif
ashleymills 0:714293de3836 9371 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
ashleymills 0:714293de3836 9372 ssl->options.haveDH, ssl->options.haveNTRU,
ashleymills 0:714293de3836 9373 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
ashleymills 0:714293de3836 9374 ssl->options.side);
ashleymills 0:714293de3836 9375 }
ashleymills 0:714293de3836 9376 /* random */
ashleymills 0:714293de3836 9377 XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
ashleymills 0:714293de3836 9378 i += RAN_LEN;
ashleymills 0:714293de3836 9379
ashleymills 0:714293de3836 9380 #ifdef SHOW_SECRETS
ashleymills 0:714293de3836 9381 {
ashleymills 0:714293de3836 9382 int j;
ashleymills 0:714293de3836 9383 printf("client random: ");
ashleymills 0:714293de3836 9384 for (j = 0; j < RAN_LEN; j++)
ashleymills 0:714293de3836 9385 printf("%02x", ssl->arrays->clientRandom[j]);
ashleymills 0:714293de3836 9386 printf("\n");
ashleymills 0:714293de3836 9387 }
ashleymills 0:714293de3836 9388 #endif
ashleymills 0:714293de3836 9389 /* session id */
ashleymills 0:714293de3836 9390 b = input[i++];
ashleymills 0:714293de3836 9391 if (b) {
ashleymills 0:714293de3836 9392 if (i + ID_LEN > totalSz)
ashleymills 0:714293de3836 9393 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 9394 XMEMCPY(ssl->arrays->sessionID, input + i, ID_LEN);
ashleymills 0:714293de3836 9395 i += b;
ashleymills 0:714293de3836 9396 ssl->options.resuming= 1; /* client wants to resume */
ashleymills 0:714293de3836 9397 CYASSL_MSG("Client wants to resume session");
ashleymills 0:714293de3836 9398 }
ashleymills 0:714293de3836 9399
ashleymills 0:714293de3836 9400 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 9401 /* cookie */
ashleymills 0:714293de3836 9402 if (ssl->options.dtls) {
ashleymills 0:714293de3836 9403 b = input[i++];
ashleymills 0:714293de3836 9404 if (b) {
ashleymills 0:714293de3836 9405 byte cookie[MAX_COOKIE_LEN];
ashleymills 0:714293de3836 9406
ashleymills 0:714293de3836 9407 if (b > MAX_COOKIE_LEN)
ashleymills 0:714293de3836 9408 return BUFFER_ERROR;
ashleymills 0:714293de3836 9409 if (i + b > totalSz)
ashleymills 0:714293de3836 9410 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 9411 if (ssl->ctx->CBIOCookie == NULL) {
ashleymills 0:714293de3836 9412 CYASSL_MSG("Your Cookie callback is null, please set");
ashleymills 0:714293de3836 9413 return COOKIE_ERROR;
ashleymills 0:714293de3836 9414 }
ashleymills 0:714293de3836 9415 if ((ssl->ctx->CBIOCookie(ssl, cookie, COOKIE_SZ,
ashleymills 0:714293de3836 9416 ssl->IOCB_CookieCtx) != COOKIE_SZ)
ashleymills 0:714293de3836 9417 || (b != COOKIE_SZ)
ashleymills 0:714293de3836 9418 || (XMEMCMP(cookie, input + i, b) != 0)) {
ashleymills 0:714293de3836 9419 return COOKIE_ERROR;
ashleymills 0:714293de3836 9420 }
ashleymills 0:714293de3836 9421 i += b;
ashleymills 0:714293de3836 9422 }
ashleymills 0:714293de3836 9423 }
ashleymills 0:714293de3836 9424 #endif
ashleymills 0:714293de3836 9425
ashleymills 0:714293de3836 9426 if (i + LENGTH_SZ > totalSz)
ashleymills 0:714293de3836 9427 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 9428 /* suites */
ashleymills 0:714293de3836 9429 ato16(&input[i], &clSuites.suiteSz);
ashleymills 0:714293de3836 9430 i += 2;
ashleymills 0:714293de3836 9431
ashleymills 0:714293de3836 9432 /* suites and comp len */
ashleymills 0:714293de3836 9433 if (i + clSuites.suiteSz + ENUM_LEN > totalSz)
ashleymills 0:714293de3836 9434 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 9435 if (clSuites.suiteSz > MAX_SUITE_SZ)
ashleymills 0:714293de3836 9436 return BUFFER_ERROR;
ashleymills 0:714293de3836 9437 XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
ashleymills 0:714293de3836 9438 i += clSuites.suiteSz;
ashleymills 0:714293de3836 9439 clSuites.hashSigAlgoSz = 0;
ashleymills 0:714293de3836 9440
ashleymills 0:714293de3836 9441 b = input[i++]; /* comp len */
ashleymills 0:714293de3836 9442 if (i + b > totalSz)
ashleymills 0:714293de3836 9443 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 9444
ashleymills 0:714293de3836 9445 if (ssl->options.usingCompression) {
ashleymills 0:714293de3836 9446 int match = 0;
ashleymills 0:714293de3836 9447 while (b--) {
ashleymills 0:714293de3836 9448 byte comp = input[i++];
ashleymills 0:714293de3836 9449 if (comp == ZLIB_COMPRESSION)
ashleymills 0:714293de3836 9450 match = 1;
ashleymills 0:714293de3836 9451 }
ashleymills 0:714293de3836 9452 if (!match) {
ashleymills 0:714293de3836 9453 CYASSL_MSG("Not matching compression, turning off");
ashleymills 0:714293de3836 9454 ssl->options.usingCompression = 0; /* turn off */
ashleymills 0:714293de3836 9455 }
ashleymills 0:714293de3836 9456 }
ashleymills 0:714293de3836 9457 else
ashleymills 0:714293de3836 9458 i += b; /* ignore, since we're not on */
ashleymills 0:714293de3836 9459
ashleymills 0:714293de3836 9460 *inOutIdx = i;
ashleymills 0:714293de3836 9461 if ( (i - begin) < helloSz) {
ashleymills 0:714293de3836 9462 #ifdef HAVE_TLS_EXTENSIONS
ashleymills 0:714293de3836 9463 if (IsTLS(ssl)) {
ashleymills 0:714293de3836 9464 int ret = 0;
ashleymills 0:714293de3836 9465 #else
ashleymills 0:714293de3836 9466 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 9467 #endif
ashleymills 0:714293de3836 9468 /* Process the hello extension. Skip unsupported. */
ashleymills 0:714293de3836 9469 word16 totalExtSz;
ashleymills 0:714293de3836 9470
ashleymills 0:714293de3836 9471 ato16(&input[i], &totalExtSz);
ashleymills 0:714293de3836 9472 i += LENGTH_SZ;
ashleymills 0:714293de3836 9473 if (totalExtSz > helloSz + begin - i)
ashleymills 0:714293de3836 9474 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 9475
ashleymills 0:714293de3836 9476 #ifdef HAVE_TLS_EXTENSIONS
ashleymills 0:714293de3836 9477 if ((ret = TLSX_Parse(ssl, (byte *) input + i,
ashleymills 0:714293de3836 9478 totalExtSz, 1, &clSuites)))
ashleymills 0:714293de3836 9479 return ret;
ashleymills 0:714293de3836 9480
ashleymills 0:714293de3836 9481 i += totalExtSz;
ashleymills 0:714293de3836 9482 #else
ashleymills 0:714293de3836 9483 while (totalExtSz) {
ashleymills 0:714293de3836 9484 word16 extId, extSz;
ashleymills 0:714293de3836 9485
ashleymills 0:714293de3836 9486 ato16(&input[i], &extId);
ashleymills 0:714293de3836 9487 i += LENGTH_SZ;
ashleymills 0:714293de3836 9488 ato16(&input[i], &extSz);
ashleymills 0:714293de3836 9489 i += EXT_ID_SZ;
ashleymills 0:714293de3836 9490 if (extSz > totalExtSz - LENGTH_SZ - EXT_ID_SZ)
ashleymills 0:714293de3836 9491 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 9492
ashleymills 0:714293de3836 9493 if (extId == HELLO_EXT_SIG_ALGO) {
ashleymills 0:714293de3836 9494 ato16(&input[i], &clSuites.hashSigAlgoSz);
ashleymills 0:714293de3836 9495 i += LENGTH_SZ;
ashleymills 0:714293de3836 9496 if (clSuites.hashSigAlgoSz > extSz - LENGTH_SZ)
ashleymills 0:714293de3836 9497 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 9498
ashleymills 0:714293de3836 9499 XMEMCPY(clSuites.hashSigAlgo, &input[i],
ashleymills 0:714293de3836 9500 min(clSuites.hashSigAlgoSz, HELLO_EXT_SIGALGO_MAX));
ashleymills 0:714293de3836 9501 i += clSuites.hashSigAlgoSz;
ashleymills 0:714293de3836 9502 }
ashleymills 0:714293de3836 9503 else
ashleymills 0:714293de3836 9504 i += extSz;
ashleymills 0:714293de3836 9505
ashleymills 0:714293de3836 9506 totalExtSz -= LENGTH_SZ + EXT_ID_SZ + extSz;
ashleymills 0:714293de3836 9507 }
ashleymills 0:714293de3836 9508 #endif
ashleymills 0:714293de3836 9509 *inOutIdx = i;
ashleymills 0:714293de3836 9510 }
ashleymills 0:714293de3836 9511 else
ashleymills 0:714293de3836 9512 *inOutIdx = begin + helloSz; /* skip extensions */
ashleymills 0:714293de3836 9513 }
ashleymills 0:714293de3836 9514
ashleymills 0:714293de3836 9515 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
ashleymills 0:714293de3836 9516
ashleymills 0:714293de3836 9517 ssl->options.haveSessionId = 1;
ashleymills 0:714293de3836 9518 /* ProcessOld uses same resume code */
ashleymills 0:714293de3836 9519 if (ssl->options.resuming && (!ssl->options.dtls ||
ashleymills 0:714293de3836 9520 ssl->options.acceptState == HELLO_VERIFY_SENT)) { /* let's try */
ashleymills 0:714293de3836 9521 int ret = -1;
ashleymills 0:714293de3836 9522 CYASSL_SESSION* session = GetSession(ssl,ssl->arrays->masterSecret);
ashleymills 0:714293de3836 9523 if (!session) {
ashleymills 0:714293de3836 9524 CYASSL_MSG("Session lookup for resume failed");
ashleymills 0:714293de3836 9525 ssl->options.resuming = 0;
ashleymills 0:714293de3836 9526 } else {
ashleymills 0:714293de3836 9527 if (MatchSuite(ssl, &clSuites) < 0) {
ashleymills 0:714293de3836 9528 CYASSL_MSG("Unsupported cipher suite, ClientHello");
ashleymills 0:714293de3836 9529 return UNSUPPORTED_SUITE;
ashleymills 0:714293de3836 9530 }
ashleymills 0:714293de3836 9531 #ifdef SESSION_CERTS
ashleymills 0:714293de3836 9532 ssl->session = *session; /* restore session certs. */
ashleymills 0:714293de3836 9533 #endif
ashleymills 0:714293de3836 9534 RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:714293de3836 9535 #ifdef NO_OLD_TLS
ashleymills 0:714293de3836 9536 ret = DeriveTlsKeys(ssl);
ashleymills 0:714293de3836 9537 #else
ashleymills 0:714293de3836 9538 #ifndef NO_TLS
ashleymills 0:714293de3836 9539 if (ssl->options.tls)
ashleymills 0:714293de3836 9540 ret = DeriveTlsKeys(ssl);
ashleymills 0:714293de3836 9541 #endif
ashleymills 0:714293de3836 9542 if (!ssl->options.tls)
ashleymills 0:714293de3836 9543 ret = DeriveKeys(ssl);
ashleymills 0:714293de3836 9544 #endif
ashleymills 0:714293de3836 9545 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
ashleymills 0:714293de3836 9546
ashleymills 0:714293de3836 9547 return ret;
ashleymills 0:714293de3836 9548 }
ashleymills 0:714293de3836 9549 }
ashleymills 0:714293de3836 9550 return MatchSuite(ssl, &clSuites);
ashleymills 0:714293de3836 9551 }
ashleymills 0:714293de3836 9552
ashleymills 0:714293de3836 9553 #if !defined(NO_RSA) || defined(HAVE_ECC)
ashleymills 0:714293de3836 9554 static int DoCertificateVerify(CYASSL* ssl, byte* input, word32* inOutsz,
ashleymills 0:714293de3836 9555 word32 totalSz)
ashleymills 0:714293de3836 9556 {
ashleymills 0:714293de3836 9557 word16 sz = 0;
ashleymills 0:714293de3836 9558 word32 i = *inOutsz;
ashleymills 0:714293de3836 9559 int ret = VERIFY_CERT_ERROR; /* start in error state */
ashleymills 0:714293de3836 9560 byte* sig;
ashleymills 0:714293de3836 9561 byte hashAlgo = sha_mac;
ashleymills 0:714293de3836 9562 byte sigAlgo = anonymous_sa_algo;
ashleymills 0:714293de3836 9563
ashleymills 0:714293de3836 9564 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 9565 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 9566 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
ashleymills 0:714293de3836 9567 if (ssl->toInfoOn)
ashleymills 0:714293de3836 9568 AddLateName("CertificateVerify", &ssl->timeoutInfo);
ashleymills 0:714293de3836 9569 #endif
ashleymills 0:714293de3836 9570 if ( (i + VERIFY_HEADER) > totalSz)
ashleymills 0:714293de3836 9571 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 9572
ashleymills 0:714293de3836 9573 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 9574 hashAlgo = input[i++];
ashleymills 0:714293de3836 9575 sigAlgo = input[i++];
ashleymills 0:714293de3836 9576 }
ashleymills 0:714293de3836 9577 ato16(&input[i], &sz);
ashleymills 0:714293de3836 9578 i += VERIFY_HEADER;
ashleymills 0:714293de3836 9579
ashleymills 0:714293de3836 9580 if ( (i + sz) > totalSz)
ashleymills 0:714293de3836 9581 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 9582
ashleymills 0:714293de3836 9583 if (sz > ENCRYPT_LEN)
ashleymills 0:714293de3836 9584 return BUFFER_ERROR;
ashleymills 0:714293de3836 9585
ashleymills 0:714293de3836 9586 sig = &input[i];
ashleymills 0:714293de3836 9587 *inOutsz = i + sz;
ashleymills 0:714293de3836 9588
ashleymills 0:714293de3836 9589 /* RSA */
ashleymills 0:714293de3836 9590 #ifndef NO_RSA
ashleymills 0:714293de3836 9591 if (ssl->peerRsaKeyPresent != 0) {
ashleymills 0:714293de3836 9592 byte* out;
ashleymills 0:714293de3836 9593 int outLen;
ashleymills 0:714293de3836 9594
ashleymills 0:714293de3836 9595 CYASSL_MSG("Doing RSA peer cert verify");
ashleymills 0:714293de3836 9596
ashleymills 0:714293de3836 9597 outLen = RsaSSL_VerifyInline(sig, sz, &out, ssl->peerRsaKey);
ashleymills 0:714293de3836 9598
ashleymills 0:714293de3836 9599 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 9600 byte encodedSig[MAX_ENCODED_SIG_SZ];
ashleymills 0:714293de3836 9601 word32 sigSz;
ashleymills 0:714293de3836 9602 byte* digest = ssl->certHashes.sha;
ashleymills 0:714293de3836 9603 int typeH = SHAh;
ashleymills 0:714293de3836 9604 int digestSz = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 9605
ashleymills 0:714293de3836 9606 if (sigAlgo != rsa_sa_algo) {
ashleymills 0:714293de3836 9607 CYASSL_MSG("Oops, peer sent RSA key but not in verify");
ashleymills 0:714293de3836 9608 }
ashleymills 0:714293de3836 9609
ashleymills 0:714293de3836 9610 if (hashAlgo == sha256_mac) {
ashleymills 0:714293de3836 9611 #ifndef NO_SHA256
ashleymills 0:714293de3836 9612 digest = ssl->certHashes.sha256;
ashleymills 0:714293de3836 9613 typeH = SHA256h;
ashleymills 0:714293de3836 9614 digestSz = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 9615 #endif
ashleymills 0:714293de3836 9616 }
ashleymills 0:714293de3836 9617 else if (hashAlgo == sha384_mac) {
ashleymills 0:714293de3836 9618 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 9619 digest = ssl->certHashes.sha384;
ashleymills 0:714293de3836 9620 typeH = SHA384h;
ashleymills 0:714293de3836 9621 digestSz = SHA384_DIGEST_SIZE;
ashleymills 0:714293de3836 9622 #endif
ashleymills 0:714293de3836 9623 }
ashleymills 0:714293de3836 9624
ashleymills 0:714293de3836 9625 sigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
ashleymills 0:714293de3836 9626
ashleymills 0:714293de3836 9627 if (outLen == (int)sigSz && XMEMCMP(out, encodedSig,
ashleymills 0:714293de3836 9628 min(sigSz, MAX_ENCODED_SIG_SZ)) == 0)
ashleymills 0:714293de3836 9629 ret = 0; /* verified */
ashleymills 0:714293de3836 9630 }
ashleymills 0:714293de3836 9631 else {
ashleymills 0:714293de3836 9632 if (outLen == FINISHED_SZ && XMEMCMP(out,
ashleymills 0:714293de3836 9633 &ssl->certHashes, FINISHED_SZ) == 0)
ashleymills 0:714293de3836 9634 ret = 0; /* verified */
ashleymills 0:714293de3836 9635 }
ashleymills 0:714293de3836 9636 }
ashleymills 0:714293de3836 9637 #endif
ashleymills 0:714293de3836 9638 #ifdef HAVE_ECC
ashleymills 0:714293de3836 9639 if (ssl->peerEccDsaKeyPresent) {
ashleymills 0:714293de3836 9640 int verify = 0;
ashleymills 0:714293de3836 9641 int err = -1;
ashleymills 0:714293de3836 9642 byte* digest = ssl->certHashes.sha;
ashleymills 0:714293de3836 9643 word32 digestSz = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 9644
ashleymills 0:714293de3836 9645 CYASSL_MSG("Doing ECC peer cert verify");
ashleymills 0:714293de3836 9646
ashleymills 0:714293de3836 9647 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:714293de3836 9648 if (sigAlgo != ecc_dsa_sa_algo) {
ashleymills 0:714293de3836 9649 CYASSL_MSG("Oops, peer sent ECC key but not in verify");
ashleymills 0:714293de3836 9650 }
ashleymills 0:714293de3836 9651 if (hashAlgo == sha256_mac) {
ashleymills 0:714293de3836 9652 #ifndef NO_SHA256
ashleymills 0:714293de3836 9653 digest = ssl->certHashes.sha256;
ashleymills 0:714293de3836 9654 digestSz = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 9655 #endif
ashleymills 0:714293de3836 9656 }
ashleymills 0:714293de3836 9657 else if (hashAlgo == sha384_mac) {
ashleymills 0:714293de3836 9658 #ifdef CYASSL_SHA384
ashleymills 0:714293de3836 9659 digest = ssl->certHashes.sha384;
ashleymills 0:714293de3836 9660 digestSz = SHA384_DIGEST_SIZE;
ashleymills 0:714293de3836 9661 #endif
ashleymills 0:714293de3836 9662 }
ashleymills 0:714293de3836 9663 }
ashleymills 0:714293de3836 9664 err = ecc_verify_hash(sig, sz, digest, digestSz,
ashleymills 0:714293de3836 9665 &verify, ssl->peerEccDsaKey);
ashleymills 0:714293de3836 9666
ashleymills 0:714293de3836 9667 if (err == 0 && verify == 1)
ashleymills 0:714293de3836 9668 ret = 0; /* verified */
ashleymills 0:714293de3836 9669 }
ashleymills 0:714293de3836 9670 #endif
ashleymills 0:714293de3836 9671 if (ret == 0)
ashleymills 0:714293de3836 9672 ssl->options.havePeerVerify = 1;
ashleymills 0:714293de3836 9673
ashleymills 0:714293de3836 9674 return ret;
ashleymills 0:714293de3836 9675 }
ashleymills 0:714293de3836 9676 #endif /* !NO_RSA || HAVE_ECC */
ashleymills 0:714293de3836 9677
ashleymills 0:714293de3836 9678 int SendServerHelloDone(CYASSL* ssl)
ashleymills 0:714293de3836 9679 {
ashleymills 0:714293de3836 9680 byte *output;
ashleymills 0:714293de3836 9681 int sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 9682 int ret;
ashleymills 0:714293de3836 9683
ashleymills 0:714293de3836 9684 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 9685 if (ssl->options.dtls)
ashleymills 0:714293de3836 9686 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:714293de3836 9687 #endif
ashleymills 0:714293de3836 9688 /* check for available size */
ashleymills 0:714293de3836 9689 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
ashleymills 0:714293de3836 9690 return ret;
ashleymills 0:714293de3836 9691
ashleymills 0:714293de3836 9692 /* get ouput buffer */
ashleymills 0:714293de3836 9693 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 9694 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 9695
ashleymills 0:714293de3836 9696 AddHeaders(output, 0, server_hello_done, ssl);
ashleymills 0:714293de3836 9697
ashleymills 0:714293de3836 9698 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 9699 if (ssl->options.dtls) {
ashleymills 0:714293de3836 9700 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:714293de3836 9701 return 0;
ashleymills 0:714293de3836 9702 }
ashleymills 0:714293de3836 9703 #endif
ashleymills 0:714293de3836 9704 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:714293de3836 9705 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 9706 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 9707 AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
ashleymills 0:714293de3836 9708 if (ssl->toInfoOn)
ashleymills 0:714293de3836 9709 AddPacketInfo("ServerHelloDone", &ssl->timeoutInfo, output, sendSz,
ashleymills 0:714293de3836 9710 ssl->heap);
ashleymills 0:714293de3836 9711 #endif
ashleymills 0:714293de3836 9712 ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
ashleymills 0:714293de3836 9713
ashleymills 0:714293de3836 9714 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:714293de3836 9715
ashleymills 0:714293de3836 9716 return SendBuffered(ssl);
ashleymills 0:714293de3836 9717 }
ashleymills 0:714293de3836 9718
ashleymills 0:714293de3836 9719 #ifdef CYASSL_DTLS
ashleymills 0:714293de3836 9720 int SendHelloVerifyRequest(CYASSL* ssl)
ashleymills 0:714293de3836 9721 {
ashleymills 0:714293de3836 9722 byte* output;
ashleymills 0:714293de3836 9723 byte cookieSz = COOKIE_SZ;
ashleymills 0:714293de3836 9724 int length = VERSION_SZ + ENUM_LEN + cookieSz;
ashleymills 0:714293de3836 9725 int idx = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
ashleymills 0:714293de3836 9726 int sendSz = length + idx;
ashleymills 0:714293de3836 9727 int ret;
ashleymills 0:714293de3836 9728
ashleymills 0:714293de3836 9729 /* check for available size */
ashleymills 0:714293de3836 9730 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
ashleymills 0:714293de3836 9731 return ret;
ashleymills 0:714293de3836 9732
ashleymills 0:714293de3836 9733 /* get ouput buffer */
ashleymills 0:714293de3836 9734 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:714293de3836 9735 ssl->buffers.outputBuffer.length;
ashleymills 0:714293de3836 9736
ashleymills 0:714293de3836 9737 AddHeaders(output, length, hello_verify_request, ssl);
ashleymills 0:714293de3836 9738
ashleymills 0:714293de3836 9739 output[idx++] = ssl->chVersion.major;
ashleymills 0:714293de3836 9740 output[idx++] = ssl->chVersion.minor;
ashleymills 0:714293de3836 9741
ashleymills 0:714293de3836 9742 output[idx++] = cookieSz;
ashleymills 0:714293de3836 9743 if (ssl->ctx->CBIOCookie == NULL) {
ashleymills 0:714293de3836 9744 CYASSL_MSG("Your Cookie callback is null, please set");
ashleymills 0:714293de3836 9745 return COOKIE_ERROR;
ashleymills 0:714293de3836 9746 }
ashleymills 0:714293de3836 9747 if ((ret = ssl->ctx->CBIOCookie(ssl, output + idx, cookieSz,
ashleymills 0:714293de3836 9748 ssl->IOCB_CookieCtx)) < 0)
ashleymills 0:714293de3836 9749 return ret;
ashleymills 0:714293de3836 9750
ashleymills 0:714293de3836 9751 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:714293de3836 9752 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 9753 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 9754 AddPacketName("HelloVerifyRequest", &ssl->handShakeInfo);
ashleymills 0:714293de3836 9755 if (ssl->toInfoOn)
ashleymills 0:714293de3836 9756 AddPacketInfo("HelloVerifyRequest", &ssl->timeoutInfo, output,
ashleymills 0:714293de3836 9757 sendSz, ssl->heap);
ashleymills 0:714293de3836 9758 #endif
ashleymills 0:714293de3836 9759 ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
ashleymills 0:714293de3836 9760
ashleymills 0:714293de3836 9761 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:714293de3836 9762
ashleymills 0:714293de3836 9763 return SendBuffered(ssl);
ashleymills 0:714293de3836 9764 }
ashleymills 0:714293de3836 9765 #endif
ashleymills 0:714293de3836 9766
ashleymills 0:714293de3836 9767 static int DoClientKeyExchange(CYASSL* ssl, byte* input,
ashleymills 0:714293de3836 9768 word32* inOutIdx, word32 totalSz)
ashleymills 0:714293de3836 9769 {
ashleymills 0:714293de3836 9770 int ret = 0;
ashleymills 0:714293de3836 9771 word32 length = 0;
ashleymills 0:714293de3836 9772 byte* out = NULL;
ashleymills 0:714293de3836 9773
ashleymills 0:714293de3836 9774 (void)length; /* shut up compiler warnings */
ashleymills 0:714293de3836 9775 (void)out;
ashleymills 0:714293de3836 9776 (void)input;
ashleymills 0:714293de3836 9777 (void)inOutIdx;
ashleymills 0:714293de3836 9778 (void)totalSz;
ashleymills 0:714293de3836 9779
ashleymills 0:714293de3836 9780 if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
ashleymills 0:714293de3836 9781 CYASSL_MSG("Client sending keyexchange at wrong time");
ashleymills 0:714293de3836 9782 SendAlert(ssl, alert_fatal, unexpected_message);
ashleymills 0:714293de3836 9783 return OUT_OF_ORDER_E;
ashleymills 0:714293de3836 9784 }
ashleymills 0:714293de3836 9785
ashleymills 0:714293de3836 9786 #ifndef NO_CERTS
ashleymills 0:714293de3836 9787 if (ssl->options.verifyPeer && ssl->options.failNoCert)
ashleymills 0:714293de3836 9788 if (!ssl->options.havePeerCert) {
ashleymills 0:714293de3836 9789 CYASSL_MSG("client didn't present peer cert");
ashleymills 0:714293de3836 9790 return NO_PEER_CERT;
ashleymills 0:714293de3836 9791 }
ashleymills 0:714293de3836 9792 #endif
ashleymills 0:714293de3836 9793
ashleymills 0:714293de3836 9794 #ifdef CYASSL_CALLBACKS
ashleymills 0:714293de3836 9795 if (ssl->hsInfoOn)
ashleymills 0:714293de3836 9796 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
ashleymills 0:714293de3836 9797 if (ssl->toInfoOn)
ashleymills 0:714293de3836 9798 AddLateName("ClientKeyExchange", &ssl->timeoutInfo);
ashleymills 0:714293de3836 9799 #endif
ashleymills 0:714293de3836 9800
ashleymills 0:714293de3836 9801 switch (ssl->specs.kea) {
ashleymills 0:714293de3836 9802 #ifndef NO_RSA
ashleymills 0:714293de3836 9803 case rsa_kea:
ashleymills 0:714293de3836 9804 {
ashleymills 0:714293de3836 9805 word32 idx = 0;
ashleymills 0:714293de3836 9806 RsaKey key;
ashleymills 0:714293de3836 9807 byte* tmp = 0;
ashleymills 0:714293de3836 9808
ashleymills 0:714293de3836 9809 InitRsaKey(&key, ssl->heap);
ashleymills 0:714293de3836 9810
ashleymills 0:714293de3836 9811 if (ssl->buffers.key.buffer)
ashleymills 0:714293de3836 9812 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx,
ashleymills 0:714293de3836 9813 &key, ssl->buffers.key.length);
ashleymills 0:714293de3836 9814 else
ashleymills 0:714293de3836 9815 return NO_PRIVATE_KEY;
ashleymills 0:714293de3836 9816
ashleymills 0:714293de3836 9817 if (ret == 0) {
ashleymills 0:714293de3836 9818 length = RsaEncryptSize(&key);
ashleymills 0:714293de3836 9819 ssl->arrays->preMasterSz = SECRET_LEN;
ashleymills 0:714293de3836 9820
ashleymills 0:714293de3836 9821 if (ssl->options.tls) {
ashleymills 0:714293de3836 9822 word16 check;
ashleymills 0:714293de3836 9823 ato16(input + *inOutIdx, &check);
ashleymills 0:714293de3836 9824 if ((word32)check != length) {
ashleymills 0:714293de3836 9825 CYASSL_MSG("RSA explicit size doesn't match");
ashleymills 0:714293de3836 9826 FreeRsaKey(&key);
ashleymills 0:714293de3836 9827 return RSA_PRIVATE_ERROR;
ashleymills 0:714293de3836 9828 }
ashleymills 0:714293de3836 9829 (*inOutIdx) += 2;
ashleymills 0:714293de3836 9830 }
ashleymills 0:714293de3836 9831 tmp = input + *inOutIdx;
ashleymills 0:714293de3836 9832 *inOutIdx += length;
ashleymills 0:714293de3836 9833
ashleymills 0:714293de3836 9834 if (*inOutIdx > totalSz) {
ashleymills 0:714293de3836 9835 CYASSL_MSG("RSA message too big");
ashleymills 0:714293de3836 9836 FreeRsaKey(&key);
ashleymills 0:714293de3836 9837 return INCOMPLETE_DATA;
ashleymills 0:714293de3836 9838 }
ashleymills 0:714293de3836 9839
ashleymills 0:714293de3836 9840 if (RsaPrivateDecryptInline(tmp, length, &out, &key) ==
ashleymills 0:714293de3836 9841 SECRET_LEN) {
ashleymills 0:714293de3836 9842 XMEMCPY(ssl->arrays->preMasterSecret, out, SECRET_LEN);
ashleymills 0:714293de3836 9843 if (ssl->arrays->preMasterSecret[0] !=
ashleymills 0:714293de3836 9844 ssl->chVersion.major
ashleymills 0:714293de3836 9845 || ssl->arrays->preMasterSecret[1] !=
ashleymills 0:714293de3836 9846 ssl->chVersion.minor)
ashleymills 0:714293de3836 9847 ret = PMS_VERSION_ERROR;
ashleymills 0:714293de3836 9848 else
ashleymills 0:714293de3836 9849 ret = MakeMasterSecret(ssl);
ashleymills 0:714293de3836 9850 }
ashleymills 0:714293de3836 9851 else
ashleymills 0:714293de3836 9852 ret = RSA_PRIVATE_ERROR;
ashleymills 0:714293de3836 9853 }
ashleymills 0:714293de3836 9854
ashleymills 0:714293de3836 9855 FreeRsaKey(&key);
ashleymills 0:714293de3836 9856 }
ashleymills 0:714293de3836 9857 break;
ashleymills 0:714293de3836 9858 #endif
ashleymills 0:714293de3836 9859 #ifndef NO_PSK
ashleymills 0:714293de3836 9860 case psk_kea:
ashleymills 0:714293de3836 9861 {
ashleymills 0:714293de3836 9862 byte* pms = ssl->arrays->preMasterSecret;
ashleymills 0:714293de3836 9863 word16 ci_sz;
ashleymills 0:714293de3836 9864
ashleymills 0:714293de3836 9865 ato16(&input[*inOutIdx], &ci_sz);
ashleymills 0:714293de3836 9866 *inOutIdx += LENGTH_SZ;
ashleymills 0:714293de3836 9867 if (ci_sz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR;
ashleymills 0:714293de3836 9868
ashleymills 0:714293de3836 9869 XMEMCPY(ssl->arrays->client_identity, &input[*inOutIdx], ci_sz);
ashleymills 0:714293de3836 9870 *inOutIdx += ci_sz;
ashleymills 0:714293de3836 9871 if (ci_sz < MAX_PSK_ID_LEN)
ashleymills 0:714293de3836 9872 ssl->arrays->client_identity[ci_sz] = 0;
ashleymills 0:714293de3836 9873 else
ashleymills 0:714293de3836 9874 ssl->arrays->client_identity[MAX_PSK_ID_LEN-1] = 0;
ashleymills 0:714293de3836 9875
ashleymills 0:714293de3836 9876 ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
ashleymills 0:714293de3836 9877 ssl->arrays->client_identity, ssl->arrays->psk_key,
ashleymills 0:714293de3836 9878 MAX_PSK_KEY_LEN);
ashleymills 0:714293de3836 9879 if (ssl->arrays->psk_keySz == 0 ||
ashleymills 0:714293de3836 9880 ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
ashleymills 0:714293de3836 9881 return PSK_KEY_ERROR;
ashleymills 0:714293de3836 9882
ashleymills 0:714293de3836 9883 /* make psk pre master secret */
ashleymills 0:714293de3836 9884 /* length of key + length 0s + length of key + key */
ashleymills 0:714293de3836 9885 c16toa((word16)ssl->arrays->psk_keySz, pms);
ashleymills 0:714293de3836 9886 pms += 2;
ashleymills 0:714293de3836 9887 XMEMSET(pms, 0, ssl->arrays->psk_keySz);
ashleymills 0:714293de3836 9888 pms += ssl->arrays->psk_keySz;
ashleymills 0:714293de3836 9889 c16toa((word16)ssl->arrays->psk_keySz, pms);
ashleymills 0:714293de3836 9890 pms += 2;
ashleymills 0:714293de3836 9891 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
ashleymills 0:714293de3836 9892 ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
ashleymills 0:714293de3836 9893
ashleymills 0:714293de3836 9894 ret = MakeMasterSecret(ssl);
ashleymills 0:714293de3836 9895 /* No further need for PSK */
ashleymills 0:714293de3836 9896 XMEMSET(ssl->arrays->psk_key, 0, ssl->arrays->psk_keySz);
ashleymills 0:714293de3836 9897 ssl->arrays->psk_keySz = 0;
ashleymills 0:714293de3836 9898 }
ashleymills 0:714293de3836 9899 break;
ashleymills 0:714293de3836 9900 #endif /* NO_PSK */
ashleymills 0:714293de3836 9901 #ifdef HAVE_NTRU
ashleymills 0:714293de3836 9902 case ntru_kea:
ashleymills 0:714293de3836 9903 {
ashleymills 0:714293de3836 9904 word32 rc;
ashleymills 0:714293de3836 9905 word16 cipherLen;
ashleymills 0:714293de3836 9906 word16 plainLen = sizeof(ssl->arrays->preMasterSecret);
ashleymills 0:714293de3836 9907 byte* tmp;
ashleymills 0:714293de3836 9908
ashleymills 0:714293de3836 9909 if (!ssl->buffers.key.buffer)
ashleymills 0:714293de3836 9910 return NO_PRIVATE_KEY;
ashleymills 0:714293de3836 9911
ashleymills 0:714293de3836 9912 ato16(&input[*inOutIdx], &cipherLen);
ashleymills 0:714293de3836 9913 *inOutIdx += LENGTH_SZ;
ashleymills 0:714293de3836 9914 if (cipherLen > MAX_NTRU_ENCRYPT_SZ)
ashleymills 0:714293de3836 9915 return NTRU_KEY_ERROR;
ashleymills 0:714293de3836 9916
ashleymills 0:714293de3836 9917 tmp = input + *inOutIdx;
ashleymills 0:714293de3836 9918 rc = crypto_ntru_decrypt((word16)ssl->buffers.key.length,
ashleymills 0:714293de3836 9919 ssl->buffers.key.buffer, cipherLen, tmp, &plainLen,
ashleymills 0:714293de3836 9920 ssl->arrays->preMasterSecret);
ashleymills 0:714293de3836 9921
ashleymills 0:714293de3836 9922 if (rc != NTRU_OK || plainLen != SECRET_LEN)
ashleymills 0:714293de3836 9923 return NTRU_DECRYPT_ERROR;
ashleymills 0:714293de3836 9924 *inOutIdx += cipherLen;
ashleymills 0:714293de3836 9925
ashleymills 0:714293de3836 9926 ssl->arrays->preMasterSz = plainLen;
ashleymills 0:714293de3836 9927 ret = MakeMasterSecret(ssl);
ashleymills 0:714293de3836 9928 }
ashleymills 0:714293de3836 9929 break;
ashleymills 0:714293de3836 9930 #endif /* HAVE_NTRU */
ashleymills 0:714293de3836 9931 #ifdef HAVE_ECC
ashleymills 0:714293de3836 9932 case ecc_diffie_hellman_kea:
ashleymills 0:714293de3836 9933 {
ashleymills 0:714293de3836 9934 word32 size;
ashleymills 0:714293de3836 9935 word32 bLength = input[*inOutIdx]; /* one byte length */
ashleymills 0:714293de3836 9936 *inOutIdx += 1;
ashleymills 0:714293de3836 9937
ashleymills 0:714293de3836 9938 ret = ecc_import_x963(&input[*inOutIdx],
ashleymills 0:714293de3836 9939 bLength, ssl->peerEccKey);
ashleymills 0:714293de3836 9940 if (ret != 0)
ashleymills 0:714293de3836 9941 return ECC_PEERKEY_ERROR;
ashleymills 0:714293de3836 9942 *inOutIdx += bLength;
ashleymills 0:714293de3836 9943 ssl->peerEccKeyPresent = 1;
ashleymills 0:714293de3836 9944
ashleymills 0:714293de3836 9945 size = sizeof(ssl->arrays->preMasterSecret);
ashleymills 0:714293de3836 9946 if (ssl->specs.static_ecdh) {
ashleymills 0:714293de3836 9947 ecc_key staticKey;
ashleymills 0:714293de3836 9948 word32 i = 0;
ashleymills 0:714293de3836 9949
ashleymills 0:714293de3836 9950 ecc_init(&staticKey);
ashleymills 0:714293de3836 9951 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
ashleymills 0:714293de3836 9952 &staticKey, ssl->buffers.key.length);
ashleymills 0:714293de3836 9953 if (ret == 0)
ashleymills 0:714293de3836 9954 ret = ecc_shared_secret(&staticKey, ssl->peerEccKey,
ashleymills 0:714293de3836 9955 ssl->arrays->preMasterSecret, &size);
ashleymills 0:714293de3836 9956 ecc_free(&staticKey);
ashleymills 0:714293de3836 9957 }
ashleymills 0:714293de3836 9958 else
ashleymills 0:714293de3836 9959 ret = ecc_shared_secret(ssl->eccTempKey, ssl->peerEccKey,
ashleymills 0:714293de3836 9960 ssl->arrays->preMasterSecret, &size);
ashleymills 0:714293de3836 9961 if (ret != 0)
ashleymills 0:714293de3836 9962 return ECC_SHARED_ERROR;
ashleymills 0:714293de3836 9963 ssl->arrays->preMasterSz = size;
ashleymills 0:714293de3836 9964 ret = MakeMasterSecret(ssl);
ashleymills 0:714293de3836 9965 }
ashleymills 0:714293de3836 9966 break;
ashleymills 0:714293de3836 9967 #endif /* HAVE_ECC */
ashleymills 0:714293de3836 9968 #ifdef OPENSSL_EXTRA
ashleymills 0:714293de3836 9969 case diffie_hellman_kea:
ashleymills 0:714293de3836 9970 {
ashleymills 0:714293de3836 9971 byte* clientPub;
ashleymills 0:714293de3836 9972 word16 clientPubSz;
ashleymills 0:714293de3836 9973 DhKey dhKey;
ashleymills 0:714293de3836 9974
ashleymills 0:714293de3836 9975 ato16(&input[*inOutIdx], &clientPubSz);
ashleymills 0:714293de3836 9976 *inOutIdx += LENGTH_SZ;
ashleymills 0:714293de3836 9977
ashleymills 0:714293de3836 9978 clientPub = &input[*inOutIdx];
ashleymills 0:714293de3836 9979 *inOutIdx += clientPubSz;
ashleymills 0:714293de3836 9980
ashleymills 0:714293de3836 9981 InitDhKey(&dhKey);
ashleymills 0:714293de3836 9982 ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
ashleymills 0:714293de3836 9983 ssl->buffers.serverDH_P.length,
ashleymills 0:714293de3836 9984 ssl->buffers.serverDH_G.buffer,
ashleymills 0:714293de3836 9985 ssl->buffers.serverDH_G.length);
ashleymills 0:714293de3836 9986 if (ret == 0)
ashleymills 0:714293de3836 9987 ret = DhAgree(&dhKey, ssl->arrays->preMasterSecret,
ashleymills 0:714293de3836 9988 &ssl->arrays->preMasterSz,
ashleymills 0:714293de3836 9989 ssl->buffers.serverDH_Priv.buffer,
ashleymills 0:714293de3836 9990 ssl->buffers.serverDH_Priv.length,
ashleymills 0:714293de3836 9991 clientPub, clientPubSz);
ashleymills 0:714293de3836 9992 FreeDhKey(&dhKey);
ashleymills 0:714293de3836 9993 if (ret == 0)
ashleymills 0:714293de3836 9994 ret = MakeMasterSecret(ssl);
ashleymills 0:714293de3836 9995 }
ashleymills 0:714293de3836 9996 break;
ashleymills 0:714293de3836 9997 #endif /* OPENSSL_EXTRA */
ashleymills 0:714293de3836 9998 default:
ashleymills 0:714293de3836 9999 {
ashleymills 0:714293de3836 10000 CYASSL_MSG("Bad kea type");
ashleymills 0:714293de3836 10001 ret = BAD_KEA_TYPE_E;
ashleymills 0:714293de3836 10002 }
ashleymills 0:714293de3836 10003 break;
ashleymills 0:714293de3836 10004 }
ashleymills 0:714293de3836 10005 /* No further need for PMS */
ashleymills 0:714293de3836 10006 XMEMSET(ssl->arrays->preMasterSecret, 0, ssl->arrays->preMasterSz);
ashleymills 0:714293de3836 10007 ssl->arrays->preMasterSz = 0;
ashleymills 0:714293de3836 10008
ashleymills 0:714293de3836 10009 if (ret == 0) {
ashleymills 0:714293de3836 10010 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
ashleymills 0:714293de3836 10011 #ifndef NO_CERTS
ashleymills 0:714293de3836 10012 if (ssl->options.verifyPeer)
ashleymills 0:714293de3836 10013 BuildCertHashes(ssl, &ssl->certHashes);
ashleymills 0:714293de3836 10014 #endif
ashleymills 0:714293de3836 10015 }
ashleymills 0:714293de3836 10016
ashleymills 0:714293de3836 10017 return ret;
ashleymills 0:714293de3836 10018 }
ashleymills 0:714293de3836 10019
ashleymills 0:714293de3836 10020 #endif /* NO_CYASSL_SERVER */
ashleymills 0:714293de3836 10021
ashleymills 0:714293de3836 10022
ashleymills 0:714293de3836 10023 #ifdef SINGLE_THREADED
ashleymills 0:714293de3836 10024
ashleymills 0:714293de3836 10025 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10026 {
ashleymills 0:714293de3836 10027 (void)m;
ashleymills 0:714293de3836 10028 return 0;
ashleymills 0:714293de3836 10029 }
ashleymills 0:714293de3836 10030
ashleymills 0:714293de3836 10031
ashleymills 0:714293de3836 10032 int FreeMutex(CyaSSL_Mutex *m)
ashleymills 0:714293de3836 10033 {
ashleymills 0:714293de3836 10034 (void)m;
ashleymills 0:714293de3836 10035 return 0;
ashleymills 0:714293de3836 10036 }
ashleymills 0:714293de3836 10037
ashleymills 0:714293de3836 10038
ashleymills 0:714293de3836 10039 int LockMutex(CyaSSL_Mutex *m)
ashleymills 0:714293de3836 10040 {
ashleymills 0:714293de3836 10041 (void)m;
ashleymills 0:714293de3836 10042 return 0;
ashleymills 0:714293de3836 10043 }
ashleymills 0:714293de3836 10044
ashleymills 0:714293de3836 10045
ashleymills 0:714293de3836 10046 int UnLockMutex(CyaSSL_Mutex *m)
ashleymills 0:714293de3836 10047 {
ashleymills 0:714293de3836 10048 (void)m;
ashleymills 0:714293de3836 10049 return 0;
ashleymills 0:714293de3836 10050 }
ashleymills 0:714293de3836 10051
ashleymills 0:714293de3836 10052 #else /* MULTI_THREAD */
ashleymills 0:714293de3836 10053
ashleymills 0:714293de3836 10054 #if defined(FREERTOS)
ashleymills 0:714293de3836 10055
ashleymills 0:714293de3836 10056 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10057 {
ashleymills 0:714293de3836 10058 int iReturn;
ashleymills 0:714293de3836 10059
ashleymills 0:714293de3836 10060 *m = ( CyaSSL_Mutex ) xSemaphoreCreateMutex();
ashleymills 0:714293de3836 10061 if( *m != NULL )
ashleymills 0:714293de3836 10062 iReturn = 0;
ashleymills 0:714293de3836 10063 else
ashleymills 0:714293de3836 10064 iReturn = BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10065
ashleymills 0:714293de3836 10066 return iReturn;
ashleymills 0:714293de3836 10067 }
ashleymills 0:714293de3836 10068
ashleymills 0:714293de3836 10069 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10070 {
ashleymills 0:714293de3836 10071 vSemaphoreDelete( *m );
ashleymills 0:714293de3836 10072 return 0;
ashleymills 0:714293de3836 10073 }
ashleymills 0:714293de3836 10074
ashleymills 0:714293de3836 10075 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10076 {
ashleymills 0:714293de3836 10077 /* Assume an infinite block, or should there be zero block? */
ashleymills 0:714293de3836 10078 xSemaphoreTake( *m, portMAX_DELAY );
ashleymills 0:714293de3836 10079 return 0;
ashleymills 0:714293de3836 10080 }
ashleymills 0:714293de3836 10081
ashleymills 0:714293de3836 10082 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10083 {
ashleymills 0:714293de3836 10084 xSemaphoreGive( *m );
ashleymills 0:714293de3836 10085 return 0;
ashleymills 0:714293de3836 10086 }
ashleymills 0:714293de3836 10087
ashleymills 0:714293de3836 10088 #elif defined(CYASSL_SAFERTOS)
ashleymills 0:714293de3836 10089
ashleymills 0:714293de3836 10090 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10091 {
ashleymills 0:714293de3836 10092 vSemaphoreCreateBinary(m->mutexBuffer, m->mutex);
ashleymills 0:714293de3836 10093 if (m->mutex == NULL)
ashleymills 0:714293de3836 10094 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10095
ashleymills 0:714293de3836 10096 return 0;
ashleymills 0:714293de3836 10097 }
ashleymills 0:714293de3836 10098
ashleymills 0:714293de3836 10099 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10100 {
ashleymills 0:714293de3836 10101 (void)m;
ashleymills 0:714293de3836 10102 return 0;
ashleymills 0:714293de3836 10103 }
ashleymills 0:714293de3836 10104
ashleymills 0:714293de3836 10105 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10106 {
ashleymills 0:714293de3836 10107 /* Assume an infinite block */
ashleymills 0:714293de3836 10108 xSemaphoreTake(m->mutex, portMAX_DELAY);
ashleymills 0:714293de3836 10109 return 0;
ashleymills 0:714293de3836 10110 }
ashleymills 0:714293de3836 10111
ashleymills 0:714293de3836 10112 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10113 {
ashleymills 0:714293de3836 10114 xSemaphoreGive(m->mutex);
ashleymills 0:714293de3836 10115 return 0;
ashleymills 0:714293de3836 10116 }
ashleymills 0:714293de3836 10117
ashleymills 0:714293de3836 10118
ashleymills 0:714293de3836 10119 #elif defined(USE_WINDOWS_API)
ashleymills 0:714293de3836 10120
ashleymills 0:714293de3836 10121 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10122 {
ashleymills 0:714293de3836 10123 InitializeCriticalSection(m);
ashleymills 0:714293de3836 10124 return 0;
ashleymills 0:714293de3836 10125 }
ashleymills 0:714293de3836 10126
ashleymills 0:714293de3836 10127
ashleymills 0:714293de3836 10128 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10129 {
ashleymills 0:714293de3836 10130 DeleteCriticalSection(m);
ashleymills 0:714293de3836 10131 return 0;
ashleymills 0:714293de3836 10132 }
ashleymills 0:714293de3836 10133
ashleymills 0:714293de3836 10134
ashleymills 0:714293de3836 10135 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10136 {
ashleymills 0:714293de3836 10137 EnterCriticalSection(m);
ashleymills 0:714293de3836 10138 return 0;
ashleymills 0:714293de3836 10139 }
ashleymills 0:714293de3836 10140
ashleymills 0:714293de3836 10141
ashleymills 0:714293de3836 10142 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10143 {
ashleymills 0:714293de3836 10144 LeaveCriticalSection(m);
ashleymills 0:714293de3836 10145 return 0;
ashleymills 0:714293de3836 10146 }
ashleymills 0:714293de3836 10147
ashleymills 0:714293de3836 10148 #elif defined(CYASSL_PTHREADS)
ashleymills 0:714293de3836 10149
ashleymills 0:714293de3836 10150 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10151 {
ashleymills 0:714293de3836 10152 if (pthread_mutex_init(m, 0) == 0)
ashleymills 0:714293de3836 10153 return 0;
ashleymills 0:714293de3836 10154 else
ashleymills 0:714293de3836 10155 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10156 }
ashleymills 0:714293de3836 10157
ashleymills 0:714293de3836 10158
ashleymills 0:714293de3836 10159 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10160 {
ashleymills 0:714293de3836 10161 if (pthread_mutex_destroy(m) == 0)
ashleymills 0:714293de3836 10162 return 0;
ashleymills 0:714293de3836 10163 else
ashleymills 0:714293de3836 10164 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10165 }
ashleymills 0:714293de3836 10166
ashleymills 0:714293de3836 10167
ashleymills 0:714293de3836 10168 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10169 {
ashleymills 0:714293de3836 10170 if (pthread_mutex_lock(m) == 0)
ashleymills 0:714293de3836 10171 return 0;
ashleymills 0:714293de3836 10172 else
ashleymills 0:714293de3836 10173 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10174 }
ashleymills 0:714293de3836 10175
ashleymills 0:714293de3836 10176
ashleymills 0:714293de3836 10177 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10178 {
ashleymills 0:714293de3836 10179 if (pthread_mutex_unlock(m) == 0)
ashleymills 0:714293de3836 10180 return 0;
ashleymills 0:714293de3836 10181 else
ashleymills 0:714293de3836 10182 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10183 }
ashleymills 0:714293de3836 10184
ashleymills 0:714293de3836 10185 #elif defined(THREADX)
ashleymills 0:714293de3836 10186
ashleymills 0:714293de3836 10187 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10188 {
ashleymills 0:714293de3836 10189 if (tx_mutex_create(m, "CyaSSL Mutex", TX_NO_INHERIT) == 0)
ashleymills 0:714293de3836 10190 return 0;
ashleymills 0:714293de3836 10191 else
ashleymills 0:714293de3836 10192 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10193 }
ashleymills 0:714293de3836 10194
ashleymills 0:714293de3836 10195
ashleymills 0:714293de3836 10196 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10197 {
ashleymills 0:714293de3836 10198 if (tx_mutex_delete(m) == 0)
ashleymills 0:714293de3836 10199 return 0;
ashleymills 0:714293de3836 10200 else
ashleymills 0:714293de3836 10201 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10202 }
ashleymills 0:714293de3836 10203
ashleymills 0:714293de3836 10204
ashleymills 0:714293de3836 10205 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10206 {
ashleymills 0:714293de3836 10207 if (tx_mutex_get(m, TX_WAIT_FOREVER) == 0)
ashleymills 0:714293de3836 10208 return 0;
ashleymills 0:714293de3836 10209 else
ashleymills 0:714293de3836 10210 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10211 }
ashleymills 0:714293de3836 10212
ashleymills 0:714293de3836 10213
ashleymills 0:714293de3836 10214 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10215 {
ashleymills 0:714293de3836 10216 if (tx_mutex_put(m) == 0)
ashleymills 0:714293de3836 10217 return 0;
ashleymills 0:714293de3836 10218 else
ashleymills 0:714293de3836 10219 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10220 }
ashleymills 0:714293de3836 10221
ashleymills 0:714293de3836 10222 #elif defined(MICRIUM)
ashleymills 0:714293de3836 10223
ashleymills 0:714293de3836 10224 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10225 {
ashleymills 0:714293de3836 10226 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
ashleymills 0:714293de3836 10227 if (NetSecure_OS_MutexCreate(m) == 0)
ashleymills 0:714293de3836 10228 return 0;
ashleymills 0:714293de3836 10229 else
ashleymills 0:714293de3836 10230 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10231 #else
ashleymills 0:714293de3836 10232 return 0;
ashleymills 0:714293de3836 10233 #endif
ashleymills 0:714293de3836 10234 }
ashleymills 0:714293de3836 10235
ashleymills 0:714293de3836 10236
ashleymills 0:714293de3836 10237 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10238 {
ashleymills 0:714293de3836 10239 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
ashleymills 0:714293de3836 10240 if (NetSecure_OS_FreeMutex(m) == 0)
ashleymills 0:714293de3836 10241 return 0;
ashleymills 0:714293de3836 10242 else
ashleymills 0:714293de3836 10243 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10244 #else
ashleymills 0:714293de3836 10245 return 0;
ashleymills 0:714293de3836 10246 #endif
ashleymills 0:714293de3836 10247 }
ashleymills 0:714293de3836 10248
ashleymills 0:714293de3836 10249
ashleymills 0:714293de3836 10250 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10251 {
ashleymills 0:714293de3836 10252 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
ashleymills 0:714293de3836 10253 if (NetSecure_OS_LockMutex(m) == 0)
ashleymills 0:714293de3836 10254 return 0;
ashleymills 0:714293de3836 10255 else
ashleymills 0:714293de3836 10256 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10257 #else
ashleymills 0:714293de3836 10258 return 0;
ashleymills 0:714293de3836 10259 #endif
ashleymills 0:714293de3836 10260 }
ashleymills 0:714293de3836 10261
ashleymills 0:714293de3836 10262
ashleymills 0:714293de3836 10263 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10264 {
ashleymills 0:714293de3836 10265 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
ashleymills 0:714293de3836 10266 if (NetSecure_OS_UnLockMutex(m) == 0)
ashleymills 0:714293de3836 10267 return 0;
ashleymills 0:714293de3836 10268 else
ashleymills 0:714293de3836 10269 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10270 #else
ashleymills 0:714293de3836 10271 return 0;
ashleymills 0:714293de3836 10272 #endif
ashleymills 0:714293de3836 10273
ashleymills 0:714293de3836 10274 }
ashleymills 0:714293de3836 10275
ashleymills 0:714293de3836 10276 #elif defined(EBSNET)
ashleymills 0:714293de3836 10277
ashleymills 0:714293de3836 10278 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10279 {
ashleymills 0:714293de3836 10280 if (rtp_sig_mutex_alloc(m, "CyaSSL Mutex") == -1)
ashleymills 0:714293de3836 10281 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10282 else
ashleymills 0:714293de3836 10283 return 0;
ashleymills 0:714293de3836 10284 }
ashleymills 0:714293de3836 10285
ashleymills 0:714293de3836 10286 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10287 {
ashleymills 0:714293de3836 10288 rtp_sig_mutex_free(*m);
ashleymills 0:714293de3836 10289 return 0;
ashleymills 0:714293de3836 10290 }
ashleymills 0:714293de3836 10291
ashleymills 0:714293de3836 10292 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10293 {
ashleymills 0:714293de3836 10294 if (rtp_sig_mutex_claim_timed(*m, RTIP_INF) == 0)
ashleymills 0:714293de3836 10295 return 0;
ashleymills 0:714293de3836 10296 else
ashleymills 0:714293de3836 10297 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10298 }
ashleymills 0:714293de3836 10299
ashleymills 0:714293de3836 10300 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10301 {
ashleymills 0:714293de3836 10302 rtp_sig_mutex_release(*m);
ashleymills 0:714293de3836 10303 return 0;
ashleymills 0:714293de3836 10304 }
ashleymills 0:714293de3836 10305
ashleymills 0:714293de3836 10306 #elif defined(FREESCALE_MQX)
ashleymills 0:714293de3836 10307
ashleymills 0:714293de3836 10308 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10309 {
ashleymills 0:714293de3836 10310 if (_mutex_init(m, NULL) == MQX_EOK)
ashleymills 0:714293de3836 10311 return 0;
ashleymills 0:714293de3836 10312 else
ashleymills 0:714293de3836 10313 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10314 }
ashleymills 0:714293de3836 10315
ashleymills 0:714293de3836 10316 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10317 {
ashleymills 0:714293de3836 10318 if (_mutex_destroy(m) == MQX_EOK)
ashleymills 0:714293de3836 10319 return 0;
ashleymills 0:714293de3836 10320 else
ashleymills 0:714293de3836 10321 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10322 }
ashleymills 0:714293de3836 10323
ashleymills 0:714293de3836 10324 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10325 {
ashleymills 0:714293de3836 10326 if (_mutex_lock(m) == MQX_EOK)
ashleymills 0:714293de3836 10327 return 0;
ashleymills 0:714293de3836 10328 else
ashleymills 0:714293de3836 10329 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10330 }
ashleymills 0:714293de3836 10331
ashleymills 0:714293de3836 10332 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10333 {
ashleymills 0:714293de3836 10334 if (_mutex_unlock(m) == MQX_EOK)
ashleymills 0:714293de3836 10335 return 0;
ashleymills 0:714293de3836 10336 else
ashleymills 0:714293de3836 10337 return BAD_MUTEX_ERROR;
ashleymills 0:714293de3836 10338 }
ashleymills 0:714293de3836 10339
ashleymills 0:714293de3836 10340 #elif defined(CYASSL_MDK_ARM)
ashleymills 0:714293de3836 10341
ashleymills 0:714293de3836 10342 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10343 {
ashleymills 0:714293de3836 10344 os_mut_init (m);
ashleymills 0:714293de3836 10345 return 0;
ashleymills 0:714293de3836 10346 }
ashleymills 0:714293de3836 10347
ashleymills 0:714293de3836 10348 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10349 {
ashleymills 0:714293de3836 10350 return(0) ;
ashleymills 0:714293de3836 10351 }
ashleymills 0:714293de3836 10352
ashleymills 0:714293de3836 10353 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10354 {
ashleymills 0:714293de3836 10355 os_mut_wait (m, 0xffff);
ashleymills 0:714293de3836 10356 return(0) ;
ashleymills 0:714293de3836 10357 }
ashleymills 0:714293de3836 10358
ashleymills 0:714293de3836 10359 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:714293de3836 10360 {
ashleymills 0:714293de3836 10361 os_mut_release (m);
ashleymills 0:714293de3836 10362 return 0;
ashleymills 0:714293de3836 10363 }
ashleymills 0:714293de3836 10364 #endif /* USE_WINDOWS_API */
ashleymills 0:714293de3836 10365 #endif /* SINGLE_THREADED */