cyassl re-port with cellular comms, PSK test

Dependencies:   VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src

Committer:
ashleymills
Date:
Fri Apr 26 16:59:36 2013 +0000
Revision:
1:b211d97b0068
Parent:
0:e979170e02e7
nothing

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:e979170e02e7 1 /* internal.c
ashleymills 0:e979170e02e7 2 *
ashleymills 0:e979170e02e7 3 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
ashleymills 0:e979170e02e7 4 *
ashleymills 0:e979170e02e7 5 * This file is part of CyaSSL.
ashleymills 0:e979170e02e7 6 *
ashleymills 0:e979170e02e7 7 * CyaSSL is free software; you can redistribute it and/or modify
ashleymills 0:e979170e02e7 8 * it under the terms of the GNU General Public License as published by
ashleymills 0:e979170e02e7 9 * the Free Software Foundation; either version 2 of the License, or
ashleymills 0:e979170e02e7 10 * (at your option) any later version.
ashleymills 0:e979170e02e7 11 *
ashleymills 0:e979170e02e7 12 * CyaSSL is distributed in the hope that it will be useful,
ashleymills 0:e979170e02e7 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ashleymills 0:e979170e02e7 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ashleymills 0:e979170e02e7 15 * GNU General Public License for more details.
ashleymills 0:e979170e02e7 16 *
ashleymills 0:e979170e02e7 17 * You should have received a copy of the GNU General Public License
ashleymills 0:e979170e02e7 18 * along with this program; if not, write to the Free Software
ashleymills 0:e979170e02e7 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
ashleymills 0:e979170e02e7 20 */
ashleymills 0:e979170e02e7 21
ashleymills 0:e979170e02e7 22
ashleymills 0:e979170e02e7 23 #ifdef HAVE_CONFIG_H
ashleymills 0:e979170e02e7 24 #include <config.h>
ashleymills 0:e979170e02e7 25 #endif
ashleymills 0:e979170e02e7 26
ashleymills 0:e979170e02e7 27 #include <cyassl/internal.h>
ashleymills 0:e979170e02e7 28 #include <cyassl/error.h>
ashleymills 0:e979170e02e7 29 #include <cyassl/ctaocrypt/asn.h>
ashleymills 0:e979170e02e7 30
ashleymills 0:e979170e02e7 31 #ifdef HAVE_LIBZ
ashleymills 0:e979170e02e7 32 #include "zlib.h"
ashleymills 0:e979170e02e7 33 #endif
ashleymills 0:e979170e02e7 34
ashleymills 0:e979170e02e7 35 #ifdef HAVE_NTRU
ashleymills 0:e979170e02e7 36 #include "crypto_ntru.h"
ashleymills 0:e979170e02e7 37 #endif
ashleymills 0:e979170e02e7 38
ashleymills 0:e979170e02e7 39 #if defined(DEBUG_CYASSL) || defined(SHOW_SECRETS)
ashleymills 0:e979170e02e7 40 #ifdef FREESCALE_MQX
ashleymills 0:e979170e02e7 41 #include <fio.h>
ashleymills 0:e979170e02e7 42 #else
ashleymills 0:e979170e02e7 43 #include <stdio.h>
ashleymills 0:e979170e02e7 44 #endif
ashleymills 0:e979170e02e7 45 #endif
ashleymills 0:e979170e02e7 46
ashleymills 0:e979170e02e7 47 #ifdef __sun
ashleymills 0:e979170e02e7 48 #include <sys/filio.h>
ashleymills 0:e979170e02e7 49 #endif
ashleymills 0:e979170e02e7 50
ashleymills 0:e979170e02e7 51 #ifndef TRUE
ashleymills 0:e979170e02e7 52 #define TRUE 1
ashleymills 0:e979170e02e7 53 #endif
ashleymills 0:e979170e02e7 54 #ifndef FALSE
ashleymills 0:e979170e02e7 55 #define FALSE 0
ashleymills 0:e979170e02e7 56 #endif
ashleymills 0:e979170e02e7 57
ashleymills 0:e979170e02e7 58
ashleymills 0:e979170e02e7 59 #if defined(OPENSSL_EXTRA) && defined(NO_DH)
ashleymills 0:e979170e02e7 60 #error OPENSSL_EXTRA needs DH, please remove NO_DH
ashleymills 0:e979170e02e7 61 #endif
ashleymills 0:e979170e02e7 62
ashleymills 0:e979170e02e7 63
ashleymills 0:e979170e02e7 64 #ifndef NO_CYASSL_CLIENT
ashleymills 0:e979170e02e7 65 static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input, word32*);
ashleymills 0:e979170e02e7 66 static int DoServerHello(CYASSL* ssl, const byte* input, word32*, word32);
ashleymills 0:e979170e02e7 67 static int DoServerKeyExchange(CYASSL* ssl, const byte* input, word32*);
ashleymills 0:e979170e02e7 68 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 69 static int DoCertificateRequest(CYASSL* ssl, const byte* input,word32*);
ashleymills 0:e979170e02e7 70 #endif
ashleymills 0:e979170e02e7 71 #endif
ashleymills 0:e979170e02e7 72
ashleymills 0:e979170e02e7 73
ashleymills 0:e979170e02e7 74 #ifndef NO_CYASSL_SERVER
ashleymills 0:e979170e02e7 75 static int DoClientHello(CYASSL* ssl, const byte* input, word32*, word32,
ashleymills 0:e979170e02e7 76 word32);
ashleymills 0:e979170e02e7 77 static int DoClientKeyExchange(CYASSL* ssl, byte* input, word32*, word32);
ashleymills 0:e979170e02e7 78 #if !defined(NO_RSA) || defined(HAVE_ECC)
ashleymills 0:e979170e02e7 79 static int DoCertificateVerify(CYASSL* ssl, byte*, word32*, word32);
ashleymills 0:e979170e02e7 80 #endif
ashleymills 0:e979170e02e7 81 #endif
ashleymills 0:e979170e02e7 82
ashleymills 0:e979170e02e7 83 typedef enum {
ashleymills 0:e979170e02e7 84 doProcessInit = 0,
ashleymills 0:e979170e02e7 85 #ifndef NO_CYASSL_SERVER
ashleymills 0:e979170e02e7 86 runProcessOldClientHello,
ashleymills 0:e979170e02e7 87 #endif
ashleymills 0:e979170e02e7 88 getRecordLayerHeader,
ashleymills 0:e979170e02e7 89 getData,
ashleymills 0:e979170e02e7 90 runProcessingOneMessage
ashleymills 0:e979170e02e7 91 } processReply;
ashleymills 0:e979170e02e7 92
ashleymills 0:e979170e02e7 93 #ifndef NO_MD5
ashleymills 0:e979170e02e7 94 static void Hmac(CYASSL* ssl, byte* digest, const byte* buffer, word32 sz,
ashleymills 0:e979170e02e7 95 int content, int verify);
ashleymills 0:e979170e02e7 96
ashleymills 0:e979170e02e7 97 static void BuildCertHashes(CYASSL* ssl, Hashes* hashes);
ashleymills 0:e979170e02e7 98 #endif
ashleymills 0:e979170e02e7 99
ashleymills 0:e979170e02e7 100
ashleymills 0:e979170e02e7 101 #ifndef min
ashleymills 0:e979170e02e7 102
ashleymills 0:e979170e02e7 103 static INLINE word32 min(word32 a, word32 b)
ashleymills 0:e979170e02e7 104 {
ashleymills 0:e979170e02e7 105 return a > b ? b : a;
ashleymills 0:e979170e02e7 106 }
ashleymills 0:e979170e02e7 107
ashleymills 0:e979170e02e7 108 #endif /* min */
ashleymills 0:e979170e02e7 109
ashleymills 0:e979170e02e7 110
ashleymills 0:e979170e02e7 111 int IsTLS(const CYASSL* ssl)
ashleymills 0:e979170e02e7 112 {
ashleymills 0:e979170e02e7 113 if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_MINOR)
ashleymills 0:e979170e02e7 114 return 1;
ashleymills 0:e979170e02e7 115
ashleymills 0:e979170e02e7 116 return 0;
ashleymills 0:e979170e02e7 117 }
ashleymills 0:e979170e02e7 118
ashleymills 0:e979170e02e7 119
ashleymills 0:e979170e02e7 120 int IsAtLeastTLSv1_2(const CYASSL* ssl)
ashleymills 0:e979170e02e7 121 {
ashleymills 0:e979170e02e7 122 if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_2_MINOR)
ashleymills 0:e979170e02e7 123 return 1;
ashleymills 0:e979170e02e7 124
ashleymills 0:e979170e02e7 125 return 0;
ashleymills 0:e979170e02e7 126 }
ashleymills 0:e979170e02e7 127
ashleymills 0:e979170e02e7 128
ashleymills 0:e979170e02e7 129 #ifdef HAVE_NTRU
ashleymills 0:e979170e02e7 130
ashleymills 0:e979170e02e7 131 static byte GetEntropy(ENTROPY_CMD cmd, byte* out)
ashleymills 0:e979170e02e7 132 {
ashleymills 0:e979170e02e7 133 /* TODO: add locking? */
ashleymills 0:e979170e02e7 134 static RNG rng;
ashleymills 0:e979170e02e7 135
ashleymills 0:e979170e02e7 136 if (cmd == INIT) {
ashleymills 0:e979170e02e7 137 int ret = InitRng(&rng);
ashleymills 0:e979170e02e7 138 if (ret == 0)
ashleymills 0:e979170e02e7 139 return 1;
ashleymills 0:e979170e02e7 140 else
ashleymills 0:e979170e02e7 141 return 0;
ashleymills 0:e979170e02e7 142 }
ashleymills 0:e979170e02e7 143
ashleymills 0:e979170e02e7 144 if (out == NULL)
ashleymills 0:e979170e02e7 145 return 0;
ashleymills 0:e979170e02e7 146
ashleymills 0:e979170e02e7 147 if (cmd == GET_BYTE_OF_ENTROPY) {
ashleymills 0:e979170e02e7 148 RNG_GenerateBlock(&rng, out, 1);
ashleymills 0:e979170e02e7 149 return 1;
ashleymills 0:e979170e02e7 150 }
ashleymills 0:e979170e02e7 151
ashleymills 0:e979170e02e7 152 if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) {
ashleymills 0:e979170e02e7 153 *out = 1;
ashleymills 0:e979170e02e7 154 return 1;
ashleymills 0:e979170e02e7 155 }
ashleymills 0:e979170e02e7 156
ashleymills 0:e979170e02e7 157 return 0;
ashleymills 0:e979170e02e7 158 }
ashleymills 0:e979170e02e7 159
ashleymills 0:e979170e02e7 160 #endif /* HAVE_NTRU */
ashleymills 0:e979170e02e7 161
ashleymills 0:e979170e02e7 162 /* used by ssl.c too */
ashleymills 0:e979170e02e7 163 void c32to24(word32 in, word24 out)
ashleymills 0:e979170e02e7 164 {
ashleymills 0:e979170e02e7 165 out[0] = (in >> 16) & 0xff;
ashleymills 0:e979170e02e7 166 out[1] = (in >> 8) & 0xff;
ashleymills 0:e979170e02e7 167 out[2] = in & 0xff;
ashleymills 0:e979170e02e7 168 }
ashleymills 0:e979170e02e7 169
ashleymills 0:e979170e02e7 170
ashleymills 0:e979170e02e7 171 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 172
ashleymills 0:e979170e02e7 173 static INLINE void c32to48(word32 in, byte out[6])
ashleymills 0:e979170e02e7 174 {
ashleymills 0:e979170e02e7 175 out[0] = 0;
ashleymills 0:e979170e02e7 176 out[1] = 0;
ashleymills 0:e979170e02e7 177 out[2] = (in >> 24) & 0xff;
ashleymills 0:e979170e02e7 178 out[3] = (in >> 16) & 0xff;
ashleymills 0:e979170e02e7 179 out[4] = (in >> 8) & 0xff;
ashleymills 0:e979170e02e7 180 out[5] = in & 0xff;
ashleymills 0:e979170e02e7 181 }
ashleymills 0:e979170e02e7 182
ashleymills 0:e979170e02e7 183 #endif /* CYASSL_DTLS */
ashleymills 0:e979170e02e7 184
ashleymills 0:e979170e02e7 185
ashleymills 0:e979170e02e7 186 /* convert 16 bit integer to opaque */
ashleymills 0:e979170e02e7 187 static INLINE void c16toa(word16 u16, byte* c)
ashleymills 0:e979170e02e7 188 {
ashleymills 0:e979170e02e7 189 c[0] = (u16 >> 8) & 0xff;
ashleymills 0:e979170e02e7 190 c[1] = u16 & 0xff;
ashleymills 0:e979170e02e7 191 }
ashleymills 0:e979170e02e7 192
ashleymills 0:e979170e02e7 193
ashleymills 0:e979170e02e7 194 /* convert 32 bit integer to opaque */
ashleymills 0:e979170e02e7 195 static INLINE void c32toa(word32 u32, byte* c)
ashleymills 0:e979170e02e7 196 {
ashleymills 0:e979170e02e7 197 c[0] = (u32 >> 24) & 0xff;
ashleymills 0:e979170e02e7 198 c[1] = (u32 >> 16) & 0xff;
ashleymills 0:e979170e02e7 199 c[2] = (u32 >> 8) & 0xff;
ashleymills 0:e979170e02e7 200 c[3] = u32 & 0xff;
ashleymills 0:e979170e02e7 201 }
ashleymills 0:e979170e02e7 202
ashleymills 0:e979170e02e7 203
ashleymills 0:e979170e02e7 204 /* convert a 24 bit integer into a 32 bit one */
ashleymills 0:e979170e02e7 205 static INLINE void c24to32(const word24 u24, word32* u32)
ashleymills 0:e979170e02e7 206 {
ashleymills 0:e979170e02e7 207 *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
ashleymills 0:e979170e02e7 208 }
ashleymills 0:e979170e02e7 209
ashleymills 0:e979170e02e7 210
ashleymills 0:e979170e02e7 211 /* convert opaque to 16 bit integer */
ashleymills 0:e979170e02e7 212 static INLINE void ato16(const byte* c, word16* u16)
ashleymills 0:e979170e02e7 213 {
ashleymills 0:e979170e02e7 214 *u16 = (c[0] << 8) | (c[1]);
ashleymills 0:e979170e02e7 215 }
ashleymills 0:e979170e02e7 216
ashleymills 0:e979170e02e7 217
ashleymills 0:e979170e02e7 218 /* convert opaque to 32 bit integer */
ashleymills 0:e979170e02e7 219 static INLINE void ato32(const byte* c, word32* u32)
ashleymills 0:e979170e02e7 220 {
ashleymills 0:e979170e02e7 221 *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
ashleymills 0:e979170e02e7 222 }
ashleymills 0:e979170e02e7 223
ashleymills 0:e979170e02e7 224
ashleymills 0:e979170e02e7 225 #ifdef HAVE_LIBZ
ashleymills 0:e979170e02e7 226
ashleymills 0:e979170e02e7 227 /* alloc user allocs to work with zlib */
ashleymills 0:e979170e02e7 228 static void* myAlloc(void* opaque, unsigned int item, unsigned int size)
ashleymills 0:e979170e02e7 229 {
ashleymills 0:e979170e02e7 230 (void)opaque;
ashleymills 0:e979170e02e7 231 return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
ashleymills 0:e979170e02e7 232 }
ashleymills 0:e979170e02e7 233
ashleymills 0:e979170e02e7 234
ashleymills 0:e979170e02e7 235 static void myFree(void* opaque, void* memory)
ashleymills 0:e979170e02e7 236 {
ashleymills 0:e979170e02e7 237 (void)opaque;
ashleymills 0:e979170e02e7 238 XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ);
ashleymills 0:e979170e02e7 239 }
ashleymills 0:e979170e02e7 240
ashleymills 0:e979170e02e7 241
ashleymills 0:e979170e02e7 242 /* init zlib comp/decomp streams, 0 on success */
ashleymills 0:e979170e02e7 243 static int InitStreams(CYASSL* ssl)
ashleymills 0:e979170e02e7 244 {
ashleymills 0:e979170e02e7 245 ssl->c_stream.zalloc = (alloc_func)myAlloc;
ashleymills 0:e979170e02e7 246 ssl->c_stream.zfree = (free_func)myFree;
ashleymills 0:e979170e02e7 247 ssl->c_stream.opaque = (voidpf)ssl->heap;
ashleymills 0:e979170e02e7 248
ashleymills 0:e979170e02e7 249 if (deflateInit(&ssl->c_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
ashleymills 0:e979170e02e7 250 return ZLIB_INIT_ERROR;
ashleymills 0:e979170e02e7 251
ashleymills 0:e979170e02e7 252 ssl->didStreamInit = 1;
ashleymills 0:e979170e02e7 253
ashleymills 0:e979170e02e7 254 ssl->d_stream.zalloc = (alloc_func)myAlloc;
ashleymills 0:e979170e02e7 255 ssl->d_stream.zfree = (free_func)myFree;
ashleymills 0:e979170e02e7 256 ssl->d_stream.opaque = (voidpf)ssl->heap;
ashleymills 0:e979170e02e7 257
ashleymills 0:e979170e02e7 258 if (inflateInit(&ssl->d_stream) != Z_OK) return ZLIB_INIT_ERROR;
ashleymills 0:e979170e02e7 259
ashleymills 0:e979170e02e7 260 return 0;
ashleymills 0:e979170e02e7 261 }
ashleymills 0:e979170e02e7 262
ashleymills 0:e979170e02e7 263
ashleymills 0:e979170e02e7 264 static void FreeStreams(CYASSL* ssl)
ashleymills 0:e979170e02e7 265 {
ashleymills 0:e979170e02e7 266 if (ssl->didStreamInit) {
ashleymills 0:e979170e02e7 267 deflateEnd(&ssl->c_stream);
ashleymills 0:e979170e02e7 268 inflateEnd(&ssl->d_stream);
ashleymills 0:e979170e02e7 269 }
ashleymills 0:e979170e02e7 270 }
ashleymills 0:e979170e02e7 271
ashleymills 0:e979170e02e7 272
ashleymills 0:e979170e02e7 273 /* compress in to out, return out size or error */
ashleymills 0:e979170e02e7 274 static int Compress(CYASSL* ssl, byte* in, int inSz, byte* out, int outSz)
ashleymills 0:e979170e02e7 275 {
ashleymills 0:e979170e02e7 276 int err;
ashleymills 0:e979170e02e7 277 int currTotal = (int)ssl->c_stream.total_out;
ashleymills 0:e979170e02e7 278
ashleymills 0:e979170e02e7 279 ssl->c_stream.next_in = in;
ashleymills 0:e979170e02e7 280 ssl->c_stream.avail_in = inSz;
ashleymills 0:e979170e02e7 281 ssl->c_stream.next_out = out;
ashleymills 0:e979170e02e7 282 ssl->c_stream.avail_out = outSz;
ashleymills 0:e979170e02e7 283
ashleymills 0:e979170e02e7 284 err = deflate(&ssl->c_stream, Z_SYNC_FLUSH);
ashleymills 0:e979170e02e7 285 if (err != Z_OK && err != Z_STREAM_END) return ZLIB_COMPRESS_ERROR;
ashleymills 0:e979170e02e7 286
ashleymills 0:e979170e02e7 287 return (int)ssl->c_stream.total_out - currTotal;
ashleymills 0:e979170e02e7 288 }
ashleymills 0:e979170e02e7 289
ashleymills 0:e979170e02e7 290
ashleymills 0:e979170e02e7 291 /* decompress in to out, returnn out size or error */
ashleymills 0:e979170e02e7 292 static int DeCompress(CYASSL* ssl, byte* in, int inSz, byte* out, int outSz)
ashleymills 0:e979170e02e7 293 {
ashleymills 0:e979170e02e7 294 int err;
ashleymills 0:e979170e02e7 295 int currTotal = (int)ssl->d_stream.total_out;
ashleymills 0:e979170e02e7 296
ashleymills 0:e979170e02e7 297 ssl->d_stream.next_in = in;
ashleymills 0:e979170e02e7 298 ssl->d_stream.avail_in = inSz;
ashleymills 0:e979170e02e7 299 ssl->d_stream.next_out = out;
ashleymills 0:e979170e02e7 300 ssl->d_stream.avail_out = outSz;
ashleymills 0:e979170e02e7 301
ashleymills 0:e979170e02e7 302 err = inflate(&ssl->d_stream, Z_SYNC_FLUSH);
ashleymills 0:e979170e02e7 303 if (err != Z_OK && err != Z_STREAM_END) return ZLIB_DECOMPRESS_ERROR;
ashleymills 0:e979170e02e7 304
ashleymills 0:e979170e02e7 305 return (int)ssl->d_stream.total_out - currTotal;
ashleymills 0:e979170e02e7 306 }
ashleymills 0:e979170e02e7 307
ashleymills 0:e979170e02e7 308 #endif /* HAVE_LIBZ */
ashleymills 0:e979170e02e7 309
ashleymills 0:e979170e02e7 310
ashleymills 0:e979170e02e7 311 void InitSSL_Method(CYASSL_METHOD* method, ProtocolVersion pv)
ashleymills 0:e979170e02e7 312 {
ashleymills 0:e979170e02e7 313 method->version = pv;
ashleymills 0:e979170e02e7 314 method->side = CLIENT_END;
ashleymills 0:e979170e02e7 315 method->downgrade = 0;
ashleymills 0:e979170e02e7 316 }
ashleymills 0:e979170e02e7 317
ashleymills 0:e979170e02e7 318
ashleymills 0:e979170e02e7 319 /* Initialze SSL context, return 0 on success */
ashleymills 0:e979170e02e7 320 int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
ashleymills 0:e979170e02e7 321 {
ashleymills 0:e979170e02e7 322 ctx->method = method;
ashleymills 0:e979170e02e7 323 ctx->refCount = 1; /* so either CTX_free or SSL_free can release */
ashleymills 0:e979170e02e7 324 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 325 ctx->certificate.buffer = 0;
ashleymills 0:e979170e02e7 326 ctx->certChain.buffer = 0;
ashleymills 0:e979170e02e7 327 ctx->privateKey.buffer = 0;
ashleymills 0:e979170e02e7 328 ctx->serverDH_P.buffer = 0;
ashleymills 0:e979170e02e7 329 ctx->serverDH_G.buffer = 0;
ashleymills 0:e979170e02e7 330 #endif
ashleymills 0:e979170e02e7 331 ctx->haveDH = 0;
ashleymills 0:e979170e02e7 332 ctx->haveNTRU = 0; /* start off */
ashleymills 0:e979170e02e7 333 ctx->haveECDSAsig = 0; /* start off */
ashleymills 0:e979170e02e7 334 ctx->haveStaticECC = 0; /* start off */
ashleymills 0:e979170e02e7 335 ctx->heap = ctx; /* defaults to self */
ashleymills 0:e979170e02e7 336 #ifndef NO_PSK
ashleymills 0:e979170e02e7 337 ctx->havePSK = 0;
ashleymills 0:e979170e02e7 338 ctx->server_hint[0] = 0;
ashleymills 0:e979170e02e7 339 ctx->client_psk_cb = 0;
ashleymills 0:e979170e02e7 340 ctx->server_psk_cb = 0;
ashleymills 0:e979170e02e7 341 #endif /* NO_PSK */
ashleymills 0:e979170e02e7 342 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 343 ctx->eccTempKeySz = ECDHE_SIZE;
ashleymills 0:e979170e02e7 344 #endif
ashleymills 0:e979170e02e7 345
ashleymills 0:e979170e02e7 346 #ifdef OPENSSL_EXTRA
ashleymills 0:e979170e02e7 347 ctx->passwd_cb = 0;
ashleymills 0:e979170e02e7 348 ctx->userdata = 0;
ashleymills 0:e979170e02e7 349 #endif /* OPENSSL_EXTRA */
ashleymills 0:e979170e02e7 350
ashleymills 0:e979170e02e7 351 ctx->timeout = DEFAULT_TIMEOUT;
ashleymills 0:e979170e02e7 352 #undef CYASSL_USER_IO
ashleymills 0:e979170e02e7 353 #ifndef CYASSL_USER_IO
ashleymills 0:e979170e02e7 354 CYASSL_MSG("using embedded cbio");
ashleymills 0:e979170e02e7 355 ctx->CBIORecv = EmbedReceive;
ashleymills 0:e979170e02e7 356 ctx->CBIOSend = EmbedSend;
ashleymills 0:e979170e02e7 357 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 358 if (method->version.major == DTLS_MAJOR
ashleymills 0:e979170e02e7 359 && method->version.minor == DTLS_MINOR) {
ashleymills 0:e979170e02e7 360 ctx->CBIORecv = EmbedReceiveFrom;
ashleymills 0:e979170e02e7 361 ctx->CBIOSend = EmbedSendTo;
ashleymills 0:e979170e02e7 362 }
ashleymills 0:e979170e02e7 363 #endif
ashleymills 0:e979170e02e7 364 #else
ashleymills 0:e979170e02e7 365 CYASSL_MSG("oh boy");
ashleymills 0:e979170e02e7 366 /* user will set */
ashleymills 0:e979170e02e7 367 ctx->CBIORecv = NULL;
ashleymills 0:e979170e02e7 368 ctx->CBIOSend = NULL;
ashleymills 0:e979170e02e7 369 #endif
ashleymills 0:e979170e02e7 370 ctx->partialWrite = 0;
ashleymills 0:e979170e02e7 371 ctx->verifyCallback = 0;
ashleymills 0:e979170e02e7 372
ashleymills 0:e979170e02e7 373 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 374 ctx->cm = CyaSSL_CertManagerNew();
ashleymills 0:e979170e02e7 375 #endif
ashleymills 0:e979170e02e7 376 #ifdef HAVE_NTRU
ashleymills 0:e979170e02e7 377 if (method->side == CLIENT_END)
ashleymills 0:e979170e02e7 378 ctx->haveNTRU = 1; /* always on cliet side */
ashleymills 0:e979170e02e7 379 /* server can turn on by loading key */
ashleymills 0:e979170e02e7 380 #endif
ashleymills 0:e979170e02e7 381 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 382 if (method->side == CLIENT_END) {
ashleymills 0:e979170e02e7 383 ctx->haveECDSAsig = 1; /* always on cliet side */
ashleymills 0:e979170e02e7 384 ctx->haveStaticECC = 1; /* server can turn on by loading key */
ashleymills 0:e979170e02e7 385 }
ashleymills 0:e979170e02e7 386 #endif
ashleymills 0:e979170e02e7 387 ctx->suites.setSuites = 0; /* user hasn't set yet */
ashleymills 0:e979170e02e7 388 /* remove DH later if server didn't set, add psk later */
ashleymills 0:e979170e02e7 389 InitSuites(&ctx->suites, method->version, TRUE, FALSE, TRUE, ctx->haveNTRU,
ashleymills 0:e979170e02e7 390 ctx->haveECDSAsig, ctx->haveStaticECC, method->side);
ashleymills 0:e979170e02e7 391 ctx->verifyPeer = 0;
ashleymills 0:e979170e02e7 392 ctx->verifyNone = 0;
ashleymills 0:e979170e02e7 393 ctx->failNoCert = 0;
ashleymills 0:e979170e02e7 394 ctx->sessionCacheOff = 0; /* initially on */
ashleymills 0:e979170e02e7 395 ctx->sessionCacheFlushOff = 0; /* initially on */
ashleymills 0:e979170e02e7 396 ctx->sendVerify = 0;
ashleymills 0:e979170e02e7 397 ctx->quietShutdown = 0;
ashleymills 0:e979170e02e7 398 ctx->groupMessages = 0;
ashleymills 0:e979170e02e7 399 #ifdef HAVE_OCSP
ashleymills 0:e979170e02e7 400 CyaSSL_OCSP_Init(&ctx->ocsp);
ashleymills 0:e979170e02e7 401 #endif
ashleymills 0:e979170e02e7 402 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 403 ctx->devId = NO_CAVIUM_DEVICE;
ashleymills 0:e979170e02e7 404 #endif
ashleymills 0:e979170e02e7 405
ashleymills 0:e979170e02e7 406 if (InitMutex(&ctx->countMutex) < 0) {
ashleymills 0:e979170e02e7 407 CYASSL_MSG("Mutex error on CTX init");
ashleymills 0:e979170e02e7 408 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 409 }
ashleymills 0:e979170e02e7 410 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 411 if (ctx->cm == NULL) {
ashleymills 0:e979170e02e7 412 CYASSL_MSG("Bad Cert Manager New");
ashleymills 0:e979170e02e7 413 return BAD_CERT_MANAGER_ERROR;
ashleymills 0:e979170e02e7 414 }
ashleymills 0:e979170e02e7 415 #endif
ashleymills 0:e979170e02e7 416 return 0;
ashleymills 0:e979170e02e7 417 }
ashleymills 0:e979170e02e7 418
ashleymills 0:e979170e02e7 419
ashleymills 0:e979170e02e7 420 /* In case contexts are held in array and don't want to free actual ctx */
ashleymills 0:e979170e02e7 421 void SSL_CtxResourceFree(CYASSL_CTX* ctx)
ashleymills 0:e979170e02e7 422 {
ashleymills 0:e979170e02e7 423 XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
ashleymills 0:e979170e02e7 424
ashleymills 0:e979170e02e7 425 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 426 XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
ashleymills 0:e979170e02e7 427 XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
ashleymills 0:e979170e02e7 428 XFREE(ctx->privateKey.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
ashleymills 0:e979170e02e7 429 XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
ashleymills 0:e979170e02e7 430 XFREE(ctx->certChain.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
ashleymills 0:e979170e02e7 431 CyaSSL_CertManagerFree(ctx->cm);
ashleymills 0:e979170e02e7 432 #endif
ashleymills 0:e979170e02e7 433 #ifdef HAVE_OCSP
ashleymills 0:e979170e02e7 434 CyaSSL_OCSP_Cleanup(&ctx->ocsp);
ashleymills 0:e979170e02e7 435 #endif
ashleymills 0:e979170e02e7 436 }
ashleymills 0:e979170e02e7 437
ashleymills 0:e979170e02e7 438
ashleymills 0:e979170e02e7 439 void FreeSSL_Ctx(CYASSL_CTX* ctx)
ashleymills 0:e979170e02e7 440 {
ashleymills 0:e979170e02e7 441 int doFree = 0;
ashleymills 0:e979170e02e7 442
ashleymills 0:e979170e02e7 443 if (LockMutex(&ctx->countMutex) != 0) {
ashleymills 0:e979170e02e7 444 CYASSL_MSG("Couldn't lock count mutex");
ashleymills 0:e979170e02e7 445 return;
ashleymills 0:e979170e02e7 446 }
ashleymills 0:e979170e02e7 447 ctx->refCount--;
ashleymills 0:e979170e02e7 448 if (ctx->refCount == 0)
ashleymills 0:e979170e02e7 449 doFree = 1;
ashleymills 0:e979170e02e7 450 UnLockMutex(&ctx->countMutex);
ashleymills 0:e979170e02e7 451
ashleymills 0:e979170e02e7 452 if (doFree) {
ashleymills 0:e979170e02e7 453 CYASSL_MSG("CTX ref count down to 0, doing full free");
ashleymills 0:e979170e02e7 454 SSL_CtxResourceFree(ctx);
ashleymills 0:e979170e02e7 455 XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
ashleymills 0:e979170e02e7 456 }
ashleymills 0:e979170e02e7 457 else {
ashleymills 0:e979170e02e7 458 (void)ctx;
ashleymills 0:e979170e02e7 459 CYASSL_MSG("CTX ref count not 0 yet, no free");
ashleymills 0:e979170e02e7 460 }
ashleymills 0:e979170e02e7 461 }
ashleymills 0:e979170e02e7 462
ashleymills 0:e979170e02e7 463
ashleymills 0:e979170e02e7 464 /* Set cipher pointers to null */
ashleymills 0:e979170e02e7 465 void InitCiphers(CYASSL* ssl)
ashleymills 0:e979170e02e7 466 {
ashleymills 0:e979170e02e7 467 #ifdef BUILD_ARC4
ashleymills 0:e979170e02e7 468 ssl->encrypt.arc4 = NULL;
ashleymills 0:e979170e02e7 469 ssl->decrypt.arc4 = NULL;
ashleymills 0:e979170e02e7 470 #endif
ashleymills 0:e979170e02e7 471 #ifdef BUILD_DES3
ashleymills 0:e979170e02e7 472 ssl->encrypt.des3 = NULL;
ashleymills 0:e979170e02e7 473 ssl->decrypt.des3 = NULL;
ashleymills 0:e979170e02e7 474 #endif
ashleymills 0:e979170e02e7 475 #ifdef BUILD_AES
ashleymills 0:e979170e02e7 476 ssl->encrypt.aes = NULL;
ashleymills 0:e979170e02e7 477 ssl->decrypt.aes = NULL;
ashleymills 0:e979170e02e7 478 #endif
ashleymills 0:e979170e02e7 479 #ifdef HAVE_CAMELLIA
ashleymills 0:e979170e02e7 480 ssl->encrypt.cam = NULL;
ashleymills 0:e979170e02e7 481 ssl->decrypt.cam = NULL;
ashleymills 0:e979170e02e7 482 #endif
ashleymills 0:e979170e02e7 483 #ifdef HAVE_HC128
ashleymills 0:e979170e02e7 484 ssl->encrypt.hc128 = NULL;
ashleymills 0:e979170e02e7 485 ssl->decrypt.hc128 = NULL;
ashleymills 0:e979170e02e7 486 #endif
ashleymills 0:e979170e02e7 487 #ifdef BUILD_RABBIT
ashleymills 0:e979170e02e7 488 ssl->encrypt.rabbit = NULL;
ashleymills 0:e979170e02e7 489 ssl->decrypt.rabbit = NULL;
ashleymills 0:e979170e02e7 490 #endif
ashleymills 0:e979170e02e7 491 ssl->encrypt.setup = 0;
ashleymills 0:e979170e02e7 492 ssl->decrypt.setup = 0;
ashleymills 0:e979170e02e7 493 }
ashleymills 0:e979170e02e7 494
ashleymills 0:e979170e02e7 495
ashleymills 0:e979170e02e7 496 /* Free ciphers */
ashleymills 0:e979170e02e7 497 void FreeCiphers(CYASSL* ssl)
ashleymills 0:e979170e02e7 498 {
ashleymills 0:e979170e02e7 499 (void)ssl;
ashleymills 0:e979170e02e7 500 #ifdef BUILD_ARC4
ashleymills 0:e979170e02e7 501 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 502 if (ssl->devId != NO_CAVIUM_DEVICE) {
ashleymills 0:e979170e02e7 503 Arc4FreeCavium(ssl->encrypt.arc4);
ashleymills 0:e979170e02e7 504 Arc4FreeCavium(ssl->decrypt.arc4);
ashleymills 0:e979170e02e7 505 }
ashleymills 0:e979170e02e7 506 #endif
ashleymills 0:e979170e02e7 507 XFREE(ssl->encrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:e979170e02e7 508 XFREE(ssl->decrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:e979170e02e7 509 #endif
ashleymills 0:e979170e02e7 510 #ifdef BUILD_DES3
ashleymills 0:e979170e02e7 511 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 512 if (ssl->devId != NO_CAVIUM_DEVICE) {
ashleymills 0:e979170e02e7 513 Des3_FreeCavium(ssl->encrypt.des3);
ashleymills 0:e979170e02e7 514 Des3_FreeCavium(ssl->decrypt.des3);
ashleymills 0:e979170e02e7 515 }
ashleymills 0:e979170e02e7 516 #endif
ashleymills 0:e979170e02e7 517 XFREE(ssl->encrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:e979170e02e7 518 XFREE(ssl->decrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:e979170e02e7 519 #endif
ashleymills 0:e979170e02e7 520 #ifdef BUILD_AES
ashleymills 0:e979170e02e7 521 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 522 if (ssl->devId != NO_CAVIUM_DEVICE) {
ashleymills 0:e979170e02e7 523 AesFreeCavium(ssl->encrypt.aes);
ashleymills 0:e979170e02e7 524 AesFreeCavium(ssl->decrypt.aes);
ashleymills 0:e979170e02e7 525 }
ashleymills 0:e979170e02e7 526 #endif
ashleymills 0:e979170e02e7 527 XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:e979170e02e7 528 XFREE(ssl->decrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:e979170e02e7 529 #endif
ashleymills 0:e979170e02e7 530 #ifdef BUILD_CAMELLIA
ashleymills 0:e979170e02e7 531 XFREE(ssl->encrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:e979170e02e7 532 XFREE(ssl->decrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:e979170e02e7 533 #endif
ashleymills 0:e979170e02e7 534 #ifdef HAVE_HC128
ashleymills 0:e979170e02e7 535 XFREE(ssl->encrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:e979170e02e7 536 XFREE(ssl->decrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:e979170e02e7 537 #endif
ashleymills 0:e979170e02e7 538 #ifdef BUILD_RABBIT
ashleymills 0:e979170e02e7 539 XFREE(ssl->encrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:e979170e02e7 540 XFREE(ssl->decrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
ashleymills 0:e979170e02e7 541 #endif
ashleymills 0:e979170e02e7 542 }
ashleymills 0:e979170e02e7 543
ashleymills 0:e979170e02e7 544
ashleymills 0:e979170e02e7 545 void InitCipherSpecs(CipherSpecs* cs)
ashleymills 0:e979170e02e7 546 {
ashleymills 0:e979170e02e7 547 cs->bulk_cipher_algorithm = INVALID_BYTE;
ashleymills 0:e979170e02e7 548 cs->cipher_type = INVALID_BYTE;
ashleymills 0:e979170e02e7 549 cs->mac_algorithm = INVALID_BYTE;
ashleymills 0:e979170e02e7 550 cs->kea = INVALID_BYTE;
ashleymills 0:e979170e02e7 551 cs->sig_algo = INVALID_BYTE;
ashleymills 0:e979170e02e7 552
ashleymills 0:e979170e02e7 553 cs->hash_size = 0;
ashleymills 0:e979170e02e7 554 cs->static_ecdh = 0;
ashleymills 0:e979170e02e7 555 cs->key_size = 0;
ashleymills 0:e979170e02e7 556 cs->iv_size = 0;
ashleymills 0:e979170e02e7 557 cs->block_size = 0;
ashleymills 0:e979170e02e7 558 }
ashleymills 0:e979170e02e7 559
ashleymills 0:e979170e02e7 560
ashleymills 0:e979170e02e7 561 void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK,
ashleymills 0:e979170e02e7 562 byte haveDH, byte haveNTRU, byte haveECDSAsig,
ashleymills 0:e979170e02e7 563 byte haveStaticECC, int side)
ashleymills 0:e979170e02e7 564 {
ashleymills 0:e979170e02e7 565 word16 idx = 0;
ashleymills 0:e979170e02e7 566 int tls = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR;
ashleymills 0:e979170e02e7 567 int tls1_2 = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_2_MINOR;
ashleymills 0:e979170e02e7 568 int haveRSAsig = 1;
ashleymills 0:e979170e02e7 569
ashleymills 0:e979170e02e7 570 (void)tls; /* shut up compiler */
ashleymills 0:e979170e02e7 571 (void)tls1_2;
ashleymills 0:e979170e02e7 572 (void)haveDH;
ashleymills 0:e979170e02e7 573 (void)havePSK;
ashleymills 0:e979170e02e7 574 (void)haveNTRU;
ashleymills 0:e979170e02e7 575 (void)haveStaticECC;
ashleymills 0:e979170e02e7 576
ashleymills 0:e979170e02e7 577 if (suites == NULL) {
ashleymills 0:e979170e02e7 578 CYASSL_MSG("InitSuites pointer error");
ashleymills 0:e979170e02e7 579 return;
ashleymills 0:e979170e02e7 580 }
ashleymills 0:e979170e02e7 581
ashleymills 0:e979170e02e7 582 if (suites->setSuites)
ashleymills 0:e979170e02e7 583 return; /* trust user settings, don't override */
ashleymills 0:e979170e02e7 584
ashleymills 0:e979170e02e7 585 if (side == SERVER_END && haveStaticECC)
ashleymills 0:e979170e02e7 586 haveRSA = 0; /* can't do RSA with ECDSA key */
ashleymills 0:e979170e02e7 587
ashleymills 0:e979170e02e7 588 if (side == SERVER_END && haveECDSAsig) {
ashleymills 0:e979170e02e7 589 haveRSAsig = 0; /* can't have RSA sig if signed by ECDSA */
ashleymills 0:e979170e02e7 590 (void)haveRSAsig; /* non ecc builds won't read */
ashleymills 0:e979170e02e7 591 }
ashleymills 0:e979170e02e7 592
ashleymills 0:e979170e02e7 593 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 594 if (pv.major == DTLS_MAJOR && pv.minor == DTLS_MINOR)
ashleymills 0:e979170e02e7 595 tls = 1;
ashleymills 0:e979170e02e7 596 #endif
ashleymills 0:e979170e02e7 597
ashleymills 0:e979170e02e7 598 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 599 if (tls && haveNTRU && haveRSA) {
ashleymills 0:e979170e02e7 600 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 601 suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_256_CBC_SHA;
ashleymills 0:e979170e02e7 602 }
ashleymills 0:e979170e02e7 603 #endif
ashleymills 0:e979170e02e7 604
ashleymills 0:e979170e02e7 605 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 606 if (tls && haveNTRU && haveRSA) {
ashleymills 0:e979170e02e7 607 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 608 suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_128_CBC_SHA;
ashleymills 0:e979170e02e7 609 }
ashleymills 0:e979170e02e7 610 #endif
ashleymills 0:e979170e02e7 611
ashleymills 0:e979170e02e7 612 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 613 if (tls && haveNTRU && haveRSA) {
ashleymills 0:e979170e02e7 614 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 615 suites->suites[idx++] = TLS_NTRU_RSA_WITH_RC4_128_SHA;
ashleymills 0:e979170e02e7 616 }
ashleymills 0:e979170e02e7 617 #endif
ashleymills 0:e979170e02e7 618
ashleymills 0:e979170e02e7 619 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 620 if (tls && haveNTRU && haveRSA) {
ashleymills 0:e979170e02e7 621 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 622 suites->suites[idx++] = TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA;
ashleymills 0:e979170e02e7 623 }
ashleymills 0:e979170e02e7 624 #endif
ashleymills 0:e979170e02e7 625
ashleymills 0:e979170e02e7 626 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 627 if (tls1_2 && haveStaticECC) {
ashleymills 0:e979170e02e7 628 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 629 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
ashleymills 0:e979170e02e7 630 }
ashleymills 0:e979170e02e7 631 #endif
ashleymills 0:e979170e02e7 632
ashleymills 0:e979170e02e7 633 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 634 if (tls && haveStaticECC) {
ashleymills 0:e979170e02e7 635 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 636 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA;
ashleymills 0:e979170e02e7 637 }
ashleymills 0:e979170e02e7 638 #endif
ashleymills 0:e979170e02e7 639
ashleymills 0:e979170e02e7 640 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 641 if (tls1_2 && haveECDSAsig && haveStaticECC) {
ashleymills 0:e979170e02e7 642 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 643 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
ashleymills 0:e979170e02e7 644 }
ashleymills 0:e979170e02e7 645 #endif
ashleymills 0:e979170e02e7 646
ashleymills 0:e979170e02e7 647 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 648 if (tls && haveECDSAsig && haveStaticECC) {
ashleymills 0:e979170e02e7 649 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 650 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA;
ashleymills 0:e979170e02e7 651 }
ashleymills 0:e979170e02e7 652 #endif
ashleymills 0:e979170e02e7 653
ashleymills 0:e979170e02e7 654 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 655 if (tls1_2 && haveStaticECC) {
ashleymills 0:e979170e02e7 656 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 657 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
ashleymills 0:e979170e02e7 658 }
ashleymills 0:e979170e02e7 659 #endif
ashleymills 0:e979170e02e7 660
ashleymills 0:e979170e02e7 661 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 662 if (tls && haveStaticECC) {
ashleymills 0:e979170e02e7 663 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 664 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA;
ashleymills 0:e979170e02e7 665 }
ashleymills 0:e979170e02e7 666 #endif
ashleymills 0:e979170e02e7 667
ashleymills 0:e979170e02e7 668 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 669 if (tls1_2 && haveECDSAsig && haveStaticECC) {
ashleymills 0:e979170e02e7 670 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 671 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
ashleymills 0:e979170e02e7 672 }
ashleymills 0:e979170e02e7 673 #endif
ashleymills 0:e979170e02e7 674
ashleymills 0:e979170e02e7 675 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 676 if (tls && haveECDSAsig && haveStaticECC) {
ashleymills 0:e979170e02e7 677 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 678 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA;
ashleymills 0:e979170e02e7 679 }
ashleymills 0:e979170e02e7 680 #endif
ashleymills 0:e979170e02e7 681
ashleymills 0:e979170e02e7 682 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 683 if (tls && haveStaticECC) {
ashleymills 0:e979170e02e7 684 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 685 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA;
ashleymills 0:e979170e02e7 686 }
ashleymills 0:e979170e02e7 687 #endif
ashleymills 0:e979170e02e7 688
ashleymills 0:e979170e02e7 689 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 690 if (tls && haveECDSAsig && haveStaticECC) {
ashleymills 0:e979170e02e7 691 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 692 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA;
ashleymills 0:e979170e02e7 693 }
ashleymills 0:e979170e02e7 694 #endif
ashleymills 0:e979170e02e7 695
ashleymills 0:e979170e02e7 696 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 697 if (tls && haveStaticECC) {
ashleymills 0:e979170e02e7 698 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 699 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA;
ashleymills 0:e979170e02e7 700 }
ashleymills 0:e979170e02e7 701 #endif
ashleymills 0:e979170e02e7 702
ashleymills 0:e979170e02e7 703 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 704 if (tls && haveECDSAsig && haveStaticECC) {
ashleymills 0:e979170e02e7 705 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 706 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA;
ashleymills 0:e979170e02e7 707 }
ashleymills 0:e979170e02e7 708 #endif
ashleymills 0:e979170e02e7 709
ashleymills 0:e979170e02e7 710 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 711 if (tls1_2 && haveRSA) {
ashleymills 0:e979170e02e7 712 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 713 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
ashleymills 0:e979170e02e7 714 }
ashleymills 0:e979170e02e7 715 #endif
ashleymills 0:e979170e02e7 716
ashleymills 0:e979170e02e7 717 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 718 if (tls && haveRSA) {
ashleymills 0:e979170e02e7 719 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 720 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
ashleymills 0:e979170e02e7 721 }
ashleymills 0:e979170e02e7 722 #endif
ashleymills 0:e979170e02e7 723
ashleymills 0:e979170e02e7 724 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 725 if (tls1_2 && haveRSAsig && haveStaticECC) {
ashleymills 0:e979170e02e7 726 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 727 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
ashleymills 0:e979170e02e7 728 }
ashleymills 0:e979170e02e7 729 #endif
ashleymills 0:e979170e02e7 730
ashleymills 0:e979170e02e7 731 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 732 if (tls && haveRSAsig && haveStaticECC) {
ashleymills 0:e979170e02e7 733 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 734 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA;
ashleymills 0:e979170e02e7 735 }
ashleymills 0:e979170e02e7 736 #endif
ashleymills 0:e979170e02e7 737
ashleymills 0:e979170e02e7 738 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 739 if (tls1_2 && haveRSA) {
ashleymills 0:e979170e02e7 740 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 741 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
ashleymills 0:e979170e02e7 742 }
ashleymills 0:e979170e02e7 743 #endif
ashleymills 0:e979170e02e7 744
ashleymills 0:e979170e02e7 745 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 746 if (tls && haveRSA) {
ashleymills 0:e979170e02e7 747 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 748 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA;
ashleymills 0:e979170e02e7 749 }
ashleymills 0:e979170e02e7 750 #endif
ashleymills 0:e979170e02e7 751
ashleymills 0:e979170e02e7 752 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 753 if (tls1_2 && haveRSAsig && haveStaticECC) {
ashleymills 0:e979170e02e7 754 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 755 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
ashleymills 0:e979170e02e7 756 }
ashleymills 0:e979170e02e7 757 #endif
ashleymills 0:e979170e02e7 758
ashleymills 0:e979170e02e7 759 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 760 if (tls && haveRSAsig && haveStaticECC) {
ashleymills 0:e979170e02e7 761 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 762 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA;
ashleymills 0:e979170e02e7 763 }
ashleymills 0:e979170e02e7 764 #endif
ashleymills 0:e979170e02e7 765
ashleymills 0:e979170e02e7 766 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 767 if (tls && haveRSA) {
ashleymills 0:e979170e02e7 768 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 769 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_RC4_128_SHA;
ashleymills 0:e979170e02e7 770 }
ashleymills 0:e979170e02e7 771 #endif
ashleymills 0:e979170e02e7 772
ashleymills 0:e979170e02e7 773 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 774 if (tls && haveRSAsig && haveStaticECC) {
ashleymills 0:e979170e02e7 775 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 776 suites->suites[idx++] = TLS_ECDH_RSA_WITH_RC4_128_SHA;
ashleymills 0:e979170e02e7 777 }
ashleymills 0:e979170e02e7 778 #endif
ashleymills 0:e979170e02e7 779
ashleymills 0:e979170e02e7 780 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 781 if (tls && haveRSA) {
ashleymills 0:e979170e02e7 782 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 783 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA;
ashleymills 0:e979170e02e7 784 }
ashleymills 0:e979170e02e7 785 #endif
ashleymills 0:e979170e02e7 786
ashleymills 0:e979170e02e7 787 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 788 if (tls && haveRSAsig && haveStaticECC) {
ashleymills 0:e979170e02e7 789 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 790 suites->suites[idx++] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA;
ashleymills 0:e979170e02e7 791 }
ashleymills 0:e979170e02e7 792 #endif
ashleymills 0:e979170e02e7 793
ashleymills 0:e979170e02e7 794 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 795 if (tls1_2 && haveDH && haveRSA) {
ashleymills 0:e979170e02e7 796 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 797 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
ashleymills 0:e979170e02e7 798 }
ashleymills 0:e979170e02e7 799 #endif
ashleymills 0:e979170e02e7 800
ashleymills 0:e979170e02e7 801 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_SHA256
ashleymills 0:e979170e02e7 802 if (tls1_2 && haveECDSAsig && haveDH) {
ashleymills 0:e979170e02e7 803 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 804 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_SHA256;
ashleymills 0:e979170e02e7 805 }
ashleymills 0:e979170e02e7 806 #endif
ashleymills 0:e979170e02e7 807
ashleymills 0:e979170e02e7 808 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8_SHA384
ashleymills 0:e979170e02e7 809 if (tls1_2 && haveECDSAsig && haveDH) {
ashleymills 0:e979170e02e7 810 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 811 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8_SHA384;
ashleymills 0:e979170e02e7 812 }
ashleymills 0:e979170e02e7 813 #endif
ashleymills 0:e979170e02e7 814
ashleymills 0:e979170e02e7 815 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8_SHA256
ashleymills 0:e979170e02e7 816 if (tls1_2 && haveRSA) {
ashleymills 0:e979170e02e7 817 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 818 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CCM_8_SHA256;
ashleymills 0:e979170e02e7 819 }
ashleymills 0:e979170e02e7 820 #endif
ashleymills 0:e979170e02e7 821
ashleymills 0:e979170e02e7 822 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8_SHA384
ashleymills 0:e979170e02e7 823 if (tls1_2 && haveRSA) {
ashleymills 0:e979170e02e7 824 suites->suites[idx++] = ECC_BYTE;
ashleymills 0:e979170e02e7 825 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CCM_8_SHA384;
ashleymills 0:e979170e02e7 826 }
ashleymills 0:e979170e02e7 827 #endif
ashleymills 0:e979170e02e7 828
ashleymills 0:e979170e02e7 829 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
ashleymills 0:e979170e02e7 830 if (tls1_2 && haveDH && haveRSA) {
ashleymills 0:e979170e02e7 831 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 832 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
ashleymills 0:e979170e02e7 833 }
ashleymills 0:e979170e02e7 834 #endif
ashleymills 0:e979170e02e7 835
ashleymills 0:e979170e02e7 836 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 837 if (tls1_2 && haveDH && haveRSA) {
ashleymills 0:e979170e02e7 838 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 839 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
ashleymills 0:e979170e02e7 840 }
ashleymills 0:e979170e02e7 841 #endif
ashleymills 0:e979170e02e7 842
ashleymills 0:e979170e02e7 843 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:e979170e02e7 844 if (tls1_2 && haveDH && haveRSA) {
ashleymills 0:e979170e02e7 845 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 846 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
ashleymills 0:e979170e02e7 847 }
ashleymills 0:e979170e02e7 848 #endif
ashleymills 0:e979170e02e7 849
ashleymills 0:e979170e02e7 850 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 851 if (tls && haveDH && haveRSA) {
ashleymills 0:e979170e02e7 852 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 853 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
ashleymills 0:e979170e02e7 854 }
ashleymills 0:e979170e02e7 855 #endif
ashleymills 0:e979170e02e7 856
ashleymills 0:e979170e02e7 857 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 858 if (tls && haveDH && haveRSA) {
ashleymills 0:e979170e02e7 859 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 860 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
ashleymills 0:e979170e02e7 861 }
ashleymills 0:e979170e02e7 862 #endif
ashleymills 0:e979170e02e7 863
ashleymills 0:e979170e02e7 864 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 865 if (tls1_2 && haveRSA) {
ashleymills 0:e979170e02e7 866 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 867 suites->suites[idx++] = TLS_RSA_WITH_AES_256_GCM_SHA384;
ashleymills 0:e979170e02e7 868 }
ashleymills 0:e979170e02e7 869 #endif
ashleymills 0:e979170e02e7 870
ashleymills 0:e979170e02e7 871 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
ashleymills 0:e979170e02e7 872 if (tls1_2 && haveRSA) {
ashleymills 0:e979170e02e7 873 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 874 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
ashleymills 0:e979170e02e7 875 }
ashleymills 0:e979170e02e7 876 #endif
ashleymills 0:e979170e02e7 877
ashleymills 0:e979170e02e7 878 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 879 if (tls1_2 && haveRSA) {
ashleymills 0:e979170e02e7 880 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 881 suites->suites[idx++] = TLS_RSA_WITH_AES_128_GCM_SHA256;
ashleymills 0:e979170e02e7 882 }
ashleymills 0:e979170e02e7 883 #endif
ashleymills 0:e979170e02e7 884
ashleymills 0:e979170e02e7 885 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:e979170e02e7 886 if (tls1_2 && haveRSA) {
ashleymills 0:e979170e02e7 887 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 888 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
ashleymills 0:e979170e02e7 889 }
ashleymills 0:e979170e02e7 890 #endif
ashleymills 0:e979170e02e7 891
ashleymills 0:e979170e02e7 892 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 893 if (tls && haveRSA) {
ashleymills 0:e979170e02e7 894 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 895 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA;
ashleymills 0:e979170e02e7 896 }
ashleymills 0:e979170e02e7 897 #endif
ashleymills 0:e979170e02e7 898
ashleymills 0:e979170e02e7 899 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 900 if (tls && haveRSA) {
ashleymills 0:e979170e02e7 901 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 902 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA;
ashleymills 0:e979170e02e7 903 }
ashleymills 0:e979170e02e7 904 #endif
ashleymills 0:e979170e02e7 905
ashleymills 0:e979170e02e7 906 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
ashleymills 0:e979170e02e7 907 if (tls && haveRSA) {
ashleymills 0:e979170e02e7 908 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 909 suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA;
ashleymills 0:e979170e02e7 910 }
ashleymills 0:e979170e02e7 911 #endif
ashleymills 0:e979170e02e7 912
ashleymills 0:e979170e02e7 913 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
ashleymills 0:e979170e02e7 914 if (tls && haveRSA) {
ashleymills 0:e979170e02e7 915 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 916 suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA256;
ashleymills 0:e979170e02e7 917 }
ashleymills 0:e979170e02e7 918 #endif
ashleymills 0:e979170e02e7 919
ashleymills 0:e979170e02e7 920 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 921 if (tls && havePSK) {
ashleymills 0:e979170e02e7 922 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 923 suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA;
ashleymills 0:e979170e02e7 924 }
ashleymills 0:e979170e02e7 925 #endif
ashleymills 0:e979170e02e7 926
ashleymills 0:e979170e02e7 927 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
ashleymills 0:e979170e02e7 928 if (tls && havePSK) {
ashleymills 0:e979170e02e7 929 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 930 suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA256;
ashleymills 0:e979170e02e7 931 }
ashleymills 0:e979170e02e7 932 #endif
ashleymills 0:e979170e02e7 933
ashleymills 0:e979170e02e7 934 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 935 if (tls && havePSK) {
ashleymills 0:e979170e02e7 936 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 937 suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA;
ashleymills 0:e979170e02e7 938 }
ashleymills 0:e979170e02e7 939 #endif
ashleymills 0:e979170e02e7 940
ashleymills 0:e979170e02e7 941 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
ashleymills 0:e979170e02e7 942 if (tls & havePSK) {
ashleymills 0:e979170e02e7 943 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 944 suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA256;
ashleymills 0:e979170e02e7 945 }
ashleymills 0:e979170e02e7 946 #endif
ashleymills 0:e979170e02e7 947
ashleymills 0:e979170e02e7 948 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
ashleymills 0:e979170e02e7 949 if (tls & havePSK) {
ashleymills 0:e979170e02e7 950 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 951 suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA;
ashleymills 0:e979170e02e7 952 }
ashleymills 0:e979170e02e7 953 #endif
ashleymills 0:e979170e02e7 954
ashleymills 0:e979170e02e7 955 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 956 if (haveRSA ) {
ashleymills 0:e979170e02e7 957 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 958 suites->suites[idx++] = SSL_RSA_WITH_RC4_128_SHA;
ashleymills 0:e979170e02e7 959 }
ashleymills 0:e979170e02e7 960 #endif
ashleymills 0:e979170e02e7 961
ashleymills 0:e979170e02e7 962 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
ashleymills 0:e979170e02e7 963 if (haveRSA ) {
ashleymills 0:e979170e02e7 964 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 965 suites->suites[idx++] = SSL_RSA_WITH_RC4_128_MD5;
ashleymills 0:e979170e02e7 966 }
ashleymills 0:e979170e02e7 967 #endif
ashleymills 0:e979170e02e7 968
ashleymills 0:e979170e02e7 969 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 970 if (haveRSA ) {
ashleymills 0:e979170e02e7 971 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 972 suites->suites[idx++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
ashleymills 0:e979170e02e7 973 }
ashleymills 0:e979170e02e7 974 #endif
ashleymills 0:e979170e02e7 975
ashleymills 0:e979170e02e7 976 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
ashleymills 0:e979170e02e7 977 if (tls && haveRSA) {
ashleymills 0:e979170e02e7 978 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 979 suites->suites[idx++] = TLS_RSA_WITH_HC_128_CBC_MD5;
ashleymills 0:e979170e02e7 980 }
ashleymills 0:e979170e02e7 981 #endif
ashleymills 0:e979170e02e7 982
ashleymills 0:e979170e02e7 983 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
ashleymills 0:e979170e02e7 984 if (tls && haveRSA) {
ashleymills 0:e979170e02e7 985 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 986 suites->suites[idx++] = TLS_RSA_WITH_HC_128_CBC_SHA;
ashleymills 0:e979170e02e7 987 }
ashleymills 0:e979170e02e7 988 #endif
ashleymills 0:e979170e02e7 989
ashleymills 0:e979170e02e7 990 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
ashleymills 0:e979170e02e7 991 if (tls && haveRSA) {
ashleymills 0:e979170e02e7 992 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 993 suites->suites[idx++] = TLS_RSA_WITH_RABBIT_CBC_SHA;
ashleymills 0:e979170e02e7 994 }
ashleymills 0:e979170e02e7 995 #endif
ashleymills 0:e979170e02e7 996
ashleymills 0:e979170e02e7 997 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
ashleymills 0:e979170e02e7 998 if (tls && haveRSA) {
ashleymills 0:e979170e02e7 999 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 1000 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA;
ashleymills 0:e979170e02e7 1001 }
ashleymills 0:e979170e02e7 1002 #endif
ashleymills 0:e979170e02e7 1003
ashleymills 0:e979170e02e7 1004 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
ashleymills 0:e979170e02e7 1005 if (tls && haveDH && haveRSA) {
ashleymills 0:e979170e02e7 1006 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 1007 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA;
ashleymills 0:e979170e02e7 1008 }
ashleymills 0:e979170e02e7 1009 #endif
ashleymills 0:e979170e02e7 1010
ashleymills 0:e979170e02e7 1011 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
ashleymills 0:e979170e02e7 1012 if (tls && haveRSA) {
ashleymills 0:e979170e02e7 1013 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 1014 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA;
ashleymills 0:e979170e02e7 1015 }
ashleymills 0:e979170e02e7 1016 #endif
ashleymills 0:e979170e02e7 1017
ashleymills 0:e979170e02e7 1018 #ifdef BUILD_TLS_DHE_WITH_RSA_CAMELLIA_256_CBC_SHA
ashleymills 0:e979170e02e7 1019 if (tls && haveDH && haveRSA) {
ashleymills 0:e979170e02e7 1020 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 1021 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA;
ashleymills 0:e979170e02e7 1022 }
ashleymills 0:e979170e02e7 1023 #endif
ashleymills 0:e979170e02e7 1024
ashleymills 0:e979170e02e7 1025 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
ashleymills 0:e979170e02e7 1026 if (tls && haveRSA) {
ashleymills 0:e979170e02e7 1027 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 1028 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256;
ashleymills 0:e979170e02e7 1029 }
ashleymills 0:e979170e02e7 1030 #endif
ashleymills 0:e979170e02e7 1031
ashleymills 0:e979170e02e7 1032 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
ashleymills 0:e979170e02e7 1033 if (tls && haveDH && haveRSA) {
ashleymills 0:e979170e02e7 1034 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 1035 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256;
ashleymills 0:e979170e02e7 1036 }
ashleymills 0:e979170e02e7 1037 #endif
ashleymills 0:e979170e02e7 1038
ashleymills 0:e979170e02e7 1039 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
ashleymills 0:e979170e02e7 1040 if (tls && haveRSA) {
ashleymills 0:e979170e02e7 1041 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 1042 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256;
ashleymills 0:e979170e02e7 1043 }
ashleymills 0:e979170e02e7 1044 #endif
ashleymills 0:e979170e02e7 1045
ashleymills 0:e979170e02e7 1046 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
ashleymills 0:e979170e02e7 1047 if (tls && haveDH && haveRSA) {
ashleymills 0:e979170e02e7 1048 suites->suites[idx++] = 0;
ashleymills 0:e979170e02e7 1049 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256;
ashleymills 0:e979170e02e7 1050 }
ashleymills 0:e979170e02e7 1051 #endif
ashleymills 0:e979170e02e7 1052
ashleymills 0:e979170e02e7 1053 suites->suiteSz = idx;
ashleymills 0:e979170e02e7 1054 }
ashleymills 0:e979170e02e7 1055
ashleymills 0:e979170e02e7 1056
ashleymills 0:e979170e02e7 1057 /* init everything to 0, NULL, default values before calling anything that may
ashleymills 0:e979170e02e7 1058 fail so that desctructor has a "good" state to cleanup */
ashleymills 0:e979170e02e7 1059 int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
ashleymills 0:e979170e02e7 1060 {
ashleymills 0:e979170e02e7 1061 int ret;
ashleymills 0:e979170e02e7 1062 byte haveRSA = 0;
ashleymills 0:e979170e02e7 1063 byte havePSK = 0;
ashleymills 0:e979170e02e7 1064
ashleymills 0:e979170e02e7 1065 ssl->ctx = ctx; /* only for passing to calls, options could change */
ashleymills 0:e979170e02e7 1066 ssl->version = ctx->method->version;
ashleymills 0:e979170e02e7 1067 ssl->suites = NULL;
ashleymills 0:e979170e02e7 1068
ashleymills 0:e979170e02e7 1069 #ifdef HAVE_LIBZ
ashleymills 0:e979170e02e7 1070 ssl->didStreamInit = 0;
ashleymills 0:e979170e02e7 1071 #endif
ashleymills 0:e979170e02e7 1072 #ifndef NO_RSA
ashleymills 0:e979170e02e7 1073 haveRSA = 1;
ashleymills 0:e979170e02e7 1074 #endif
ashleymills 0:e979170e02e7 1075
ashleymills 0:e979170e02e7 1076 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 1077 ssl->buffers.certificate.buffer = 0;
ashleymills 0:e979170e02e7 1078 ssl->buffers.key.buffer = 0;
ashleymills 0:e979170e02e7 1079 ssl->buffers.certChain.buffer = 0;
ashleymills 0:e979170e02e7 1080 #endif
ashleymills 0:e979170e02e7 1081 ssl->buffers.inputBuffer.length = 0;
ashleymills 0:e979170e02e7 1082 ssl->buffers.inputBuffer.idx = 0;
ashleymills 0:e979170e02e7 1083 ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
ashleymills 0:e979170e02e7 1084 ssl->buffers.inputBuffer.bufferSize = STATIC_BUFFER_LEN;
ashleymills 0:e979170e02e7 1085 ssl->buffers.inputBuffer.dynamicFlag = 0;
ashleymills 0:e979170e02e7 1086 ssl->buffers.outputBuffer.length = 0;
ashleymills 0:e979170e02e7 1087 ssl->buffers.outputBuffer.idx = 0;
ashleymills 0:e979170e02e7 1088 ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
ashleymills 0:e979170e02e7 1089 ssl->buffers.outputBuffer.bufferSize = STATIC_BUFFER_LEN;
ashleymills 0:e979170e02e7 1090 ssl->buffers.outputBuffer.dynamicFlag = 0;
ashleymills 0:e979170e02e7 1091 ssl->buffers.domainName.buffer = 0;
ashleymills 0:e979170e02e7 1092 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 1093 ssl->buffers.serverDH_P.buffer = 0;
ashleymills 0:e979170e02e7 1094 ssl->buffers.serverDH_G.buffer = 0;
ashleymills 0:e979170e02e7 1095 ssl->buffers.serverDH_Pub.buffer = 0;
ashleymills 0:e979170e02e7 1096 ssl->buffers.serverDH_Priv.buffer = 0;
ashleymills 0:e979170e02e7 1097 #endif
ashleymills 0:e979170e02e7 1098 ssl->buffers.clearOutputBuffer.buffer = 0;
ashleymills 0:e979170e02e7 1099 ssl->buffers.clearOutputBuffer.length = 0;
ashleymills 0:e979170e02e7 1100 ssl->buffers.prevSent = 0;
ashleymills 0:e979170e02e7 1101 ssl->buffers.plainSz = 0;
ashleymills 0:e979170e02e7 1102
ashleymills 0:e979170e02e7 1103 #ifdef OPENSSL_EXTRA
ashleymills 0:e979170e02e7 1104 ssl->peerCert.derCert.buffer = NULL;
ashleymills 0:e979170e02e7 1105 ssl->peerCert.altNames = NULL;
ashleymills 0:e979170e02e7 1106 ssl->peerCert.altNamesNext = NULL;
ashleymills 0:e979170e02e7 1107 #endif
ashleymills 0:e979170e02e7 1108
ashleymills 0:e979170e02e7 1109 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 1110 ssl->eccTempKeySz = ctx->eccTempKeySz;
ashleymills 0:e979170e02e7 1111 ssl->peerEccKeyPresent = 0;
ashleymills 0:e979170e02e7 1112 ssl->peerEccDsaKeyPresent = 0;
ashleymills 0:e979170e02e7 1113 ssl->eccDsaKeyPresent = 0;
ashleymills 0:e979170e02e7 1114 ssl->eccTempKeyPresent = 0;
ashleymills 0:e979170e02e7 1115 ssl->peerEccKey = NULL;
ashleymills 0:e979170e02e7 1116 ssl->peerEccDsaKey = NULL;
ashleymills 0:e979170e02e7 1117 ssl->eccDsaKey = NULL;
ashleymills 0:e979170e02e7 1118 ssl->eccTempKey = NULL;
ashleymills 0:e979170e02e7 1119 #endif
ashleymills 0:e979170e02e7 1120
ashleymills 0:e979170e02e7 1121 ssl->timeout = ctx->timeout;
ashleymills 0:e979170e02e7 1122 ssl->rfd = -1; /* set to invalid descriptor */
ashleymills 0:e979170e02e7 1123 ssl->wfd = -1;
ashleymills 0:e979170e02e7 1124 ssl->rflags = 0; /* no user flags yet */
ashleymills 0:e979170e02e7 1125 ssl->wflags = 0; /* no user flags yet */
ashleymills 0:e979170e02e7 1126 ssl->biord = 0;
ashleymills 0:e979170e02e7 1127 ssl->biowr = 0;
ashleymills 0:e979170e02e7 1128
ashleymills 0:e979170e02e7 1129 ssl->IOCB_ReadCtx = &ssl->rfd; /* prevent invalid pointer access if not */
ashleymills 0:e979170e02e7 1130 ssl->IOCB_WriteCtx = &ssl->wfd; /* correctly set */
ashleymills 0:e979170e02e7 1131
ashleymills 0:e979170e02e7 1132 #ifndef NO_MD5
ashleymills 0:e979170e02e7 1133 InitMd5(&ssl->hashMd5);
ashleymills 0:e979170e02e7 1134 #endif
ashleymills 0:e979170e02e7 1135 InitSha(&ssl->hashSha);
ashleymills 0:e979170e02e7 1136 #ifndef NO_SHA256
ashleymills 0:e979170e02e7 1137 InitSha256(&ssl->hashSha256);
ashleymills 0:e979170e02e7 1138 #endif
ashleymills 0:e979170e02e7 1139 #ifdef CYASSL_SHA384
ashleymills 0:e979170e02e7 1140 InitSha384(&ssl->hashSha384);
ashleymills 0:e979170e02e7 1141 #endif
ashleymills 0:e979170e02e7 1142 #ifndef NO_RSA
ashleymills 0:e979170e02e7 1143 ssl->peerRsaKey = NULL;
ashleymills 0:e979170e02e7 1144 ssl->peerRsaKeyPresent = 0;
ashleymills 0:e979170e02e7 1145 #endif
ashleymills 0:e979170e02e7 1146 ssl->verifyCallback = ctx->verifyCallback;
ashleymills 0:e979170e02e7 1147 ssl->options.side = ctx->method->side;
ashleymills 0:e979170e02e7 1148 ssl->options.downgrade = ctx->method->downgrade;
ashleymills 0:e979170e02e7 1149 ssl->error = 0;
ashleymills 0:e979170e02e7 1150 ssl->options.connReset = 0;
ashleymills 0:e979170e02e7 1151 ssl->options.isClosed = 0;
ashleymills 0:e979170e02e7 1152 ssl->options.closeNotify = 0;
ashleymills 0:e979170e02e7 1153 ssl->options.sentNotify = 0;
ashleymills 0:e979170e02e7 1154 ssl->options.usingCompression = 0;
ashleymills 0:e979170e02e7 1155 if (ssl->options.side == SERVER_END)
ashleymills 0:e979170e02e7 1156 ssl->options.haveDH = ctx->haveDH;
ashleymills 0:e979170e02e7 1157 else
ashleymills 0:e979170e02e7 1158 ssl->options.haveDH = 0;
ashleymills 0:e979170e02e7 1159 ssl->options.haveNTRU = ctx->haveNTRU;
ashleymills 0:e979170e02e7 1160 ssl->options.haveECDSAsig = ctx->haveECDSAsig;
ashleymills 0:e979170e02e7 1161 ssl->options.haveStaticECC = ctx->haveStaticECC;
ashleymills 0:e979170e02e7 1162 ssl->options.havePeerCert = 0;
ashleymills 0:e979170e02e7 1163 ssl->options.usingPSK_cipher = 0;
ashleymills 0:e979170e02e7 1164 ssl->options.sendAlertState = 0;
ashleymills 0:e979170e02e7 1165 #ifndef NO_PSK
ashleymills 0:e979170e02e7 1166 havePSK = ctx->havePSK;
ashleymills 0:e979170e02e7 1167 ssl->options.havePSK = ctx->havePSK;
ashleymills 0:e979170e02e7 1168 ssl->options.client_psk_cb = ctx->client_psk_cb;
ashleymills 0:e979170e02e7 1169 ssl->options.server_psk_cb = ctx->server_psk_cb;
ashleymills 0:e979170e02e7 1170 #endif /* NO_PSK */
ashleymills 0:e979170e02e7 1171
ashleymills 0:e979170e02e7 1172 ssl->options.serverState = NULL_STATE;
ashleymills 0:e979170e02e7 1173 ssl->options.clientState = NULL_STATE;
ashleymills 0:e979170e02e7 1174 ssl->options.connectState = CONNECT_BEGIN;
ashleymills 0:e979170e02e7 1175 ssl->options.acceptState = ACCEPT_BEGIN;
ashleymills 0:e979170e02e7 1176 ssl->options.handShakeState = NULL_STATE;
ashleymills 0:e979170e02e7 1177 ssl->options.processReply = doProcessInit;
ashleymills 0:e979170e02e7 1178
ashleymills 0:e979170e02e7 1179 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 1180 ssl->keys.dtls_sequence_number = 0;
ashleymills 0:e979170e02e7 1181 ssl->keys.dtls_peer_sequence_number = 0;
ashleymills 0:e979170e02e7 1182 ssl->keys.dtls_expected_peer_sequence_number = 0;
ashleymills 0:e979170e02e7 1183 ssl->keys.dtls_handshake_number = 0;
ashleymills 0:e979170e02e7 1184 ssl->keys.dtls_expected_peer_handshake_number = 0;
ashleymills 0:e979170e02e7 1185 ssl->keys.dtls_epoch = 0;
ashleymills 0:e979170e02e7 1186 ssl->keys.dtls_peer_epoch = 0;
ashleymills 0:e979170e02e7 1187 ssl->keys.dtls_expected_peer_epoch = 0;
ashleymills 0:e979170e02e7 1188 ssl->dtls_timeout = DTLS_DEFAULT_TIMEOUT;
ashleymills 0:e979170e02e7 1189 ssl->dtls_pool = NULL;
ashleymills 0:e979170e02e7 1190 #endif
ashleymills 0:e979170e02e7 1191 ssl->keys.encryptionOn = 0; /* initially off */
ashleymills 0:e979170e02e7 1192 ssl->keys.decryptedCur = 0; /* initially off */
ashleymills 0:e979170e02e7 1193 ssl->options.sessionCacheOff = ctx->sessionCacheOff;
ashleymills 0:e979170e02e7 1194 ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
ashleymills 0:e979170e02e7 1195
ashleymills 0:e979170e02e7 1196 ssl->options.verifyPeer = ctx->verifyPeer;
ashleymills 0:e979170e02e7 1197 ssl->options.verifyNone = ctx->verifyNone;
ashleymills 0:e979170e02e7 1198 ssl->options.failNoCert = ctx->failNoCert;
ashleymills 0:e979170e02e7 1199 ssl->options.sendVerify = ctx->sendVerify;
ashleymills 0:e979170e02e7 1200
ashleymills 0:e979170e02e7 1201 ssl->options.resuming = 0;
ashleymills 0:e979170e02e7 1202 ssl->options.haveSessionId = 0;
ashleymills 0:e979170e02e7 1203 #ifndef NO_OLD_TLS
ashleymills 0:e979170e02e7 1204 ssl->hmac = Hmac; /* default to SSLv3 */
ashleymills 0:e979170e02e7 1205 #else
ashleymills 0:e979170e02e7 1206 ssl->hmac = TLS_hmac;
ashleymills 0:e979170e02e7 1207 #endif
ashleymills 0:e979170e02e7 1208 ssl->heap = ctx->heap; /* defaults to self */
ashleymills 0:e979170e02e7 1209 ssl->options.tls = 0;
ashleymills 0:e979170e02e7 1210 ssl->options.tls1_1 = 0;
ashleymills 0:e979170e02e7 1211 if (ssl->version.major == DTLS_MAJOR && ssl->version.minor == DTLS_MINOR)
ashleymills 0:e979170e02e7 1212 ssl->options.dtls = 1;
ashleymills 0:e979170e02e7 1213 else
ashleymills 0:e979170e02e7 1214 ssl->options.dtls = 0;
ashleymills 0:e979170e02e7 1215 ssl->options.partialWrite = ctx->partialWrite;
ashleymills 0:e979170e02e7 1216 ssl->options.quietShutdown = ctx->quietShutdown;
ashleymills 0:e979170e02e7 1217 ssl->options.certOnly = 0;
ashleymills 0:e979170e02e7 1218 ssl->options.groupMessages = ctx->groupMessages;
ashleymills 0:e979170e02e7 1219 ssl->options.usingNonblock = 0;
ashleymills 0:e979170e02e7 1220 ssl->options.saveArrays = 0;
ashleymills 0:e979170e02e7 1221
ashleymills 0:e979170e02e7 1222 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 1223 /* ctx still owns certificate, certChain, key, dh, and cm */
ashleymills 0:e979170e02e7 1224 ssl->buffers.certificate = ctx->certificate;
ashleymills 0:e979170e02e7 1225 ssl->buffers.certChain = ctx->certChain;
ashleymills 0:e979170e02e7 1226 ssl->buffers.key = ctx->privateKey;
ashleymills 0:e979170e02e7 1227 if (ssl->options.side == SERVER_END) {
ashleymills 0:e979170e02e7 1228 ssl->buffers.serverDH_P = ctx->serverDH_P;
ashleymills 0:e979170e02e7 1229 ssl->buffers.serverDH_G = ctx->serverDH_G;
ashleymills 0:e979170e02e7 1230 }
ashleymills 0:e979170e02e7 1231 #endif
ashleymills 0:e979170e02e7 1232 ssl->buffers.weOwnCert = 0;
ashleymills 0:e979170e02e7 1233 ssl->buffers.weOwnKey = 0;
ashleymills 0:e979170e02e7 1234 ssl->buffers.weOwnDH = 0;
ashleymills 0:e979170e02e7 1235
ashleymills 0:e979170e02e7 1236 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 1237 ssl->buffers.dtlsHandshake.length = 0;
ashleymills 0:e979170e02e7 1238 ssl->buffers.dtlsHandshake.buffer = NULL;
ashleymills 0:e979170e02e7 1239 ssl->buffers.dtlsType = 0;
ashleymills 0:e979170e02e7 1240 ssl->buffers.dtlsCtx.fd = -1;
ashleymills 0:e979170e02e7 1241 ssl->buffers.dtlsCtx.peer.sa = NULL;
ashleymills 0:e979170e02e7 1242 ssl->buffers.dtlsCtx.peer.sz = 0;
ashleymills 0:e979170e02e7 1243 #endif
ashleymills 0:e979170e02e7 1244
ashleymills 0:e979170e02e7 1245 #ifdef OPENSSL_EXTRA
ashleymills 0:e979170e02e7 1246 ssl->peerCert.issuer.sz = 0;
ashleymills 0:e979170e02e7 1247 ssl->peerCert.subject.sz = 0;
ashleymills 0:e979170e02e7 1248 #endif
ashleymills 0:e979170e02e7 1249
ashleymills 0:e979170e02e7 1250 #ifdef SESSION_CERTS
ashleymills 0:e979170e02e7 1251 ssl->session.chain.count = 0;
ashleymills 0:e979170e02e7 1252 #endif
ashleymills 0:e979170e02e7 1253
ashleymills 0:e979170e02e7 1254 ssl->cipher.ssl = ssl;
ashleymills 0:e979170e02e7 1255
ashleymills 0:e979170e02e7 1256 #ifdef FORTRESS
ashleymills 0:e979170e02e7 1257 ssl->ex_data[0] = 0;
ashleymills 0:e979170e02e7 1258 ssl->ex_data[1] = 0;
ashleymills 0:e979170e02e7 1259 ssl->ex_data[2] = 0;
ashleymills 0:e979170e02e7 1260 #endif
ashleymills 0:e979170e02e7 1261
ashleymills 0:e979170e02e7 1262 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 1263 ssl->hsInfoOn = 0;
ashleymills 0:e979170e02e7 1264 ssl->toInfoOn = 0;
ashleymills 0:e979170e02e7 1265 #endif
ashleymills 0:e979170e02e7 1266
ashleymills 0:e979170e02e7 1267 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 1268 ssl->devId = ctx->devId;
ashleymills 0:e979170e02e7 1269 #endif
ashleymills 0:e979170e02e7 1270
ashleymills 0:e979170e02e7 1271 ssl->rng = NULL;
ashleymills 0:e979170e02e7 1272 ssl->arrays = NULL;
ashleymills 0:e979170e02e7 1273 InitCiphers(ssl);
ashleymills 0:e979170e02e7 1274 /* all done with init, now can return errors, call other stuff */
ashleymills 0:e979170e02e7 1275
ashleymills 0:e979170e02e7 1276 /* increment CTX reference count */
ashleymills 0:e979170e02e7 1277 if (LockMutex(&ctx->countMutex) != 0) {
ashleymills 0:e979170e02e7 1278 CYASSL_MSG("Couldn't lock CTX count mutex");
ashleymills 0:e979170e02e7 1279 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 1280 }
ashleymills 0:e979170e02e7 1281 ctx->refCount++;
ashleymills 0:e979170e02e7 1282 UnLockMutex(&ctx->countMutex);
ashleymills 0:e979170e02e7 1283
ashleymills 0:e979170e02e7 1284 /* arrays */
ashleymills 0:e979170e02e7 1285 ssl->arrays = (Arrays*)XMALLOC(sizeof(Arrays), ssl->heap,
ashleymills 0:e979170e02e7 1286 DYNAMIC_TYPE_ARRAYS);
ashleymills 0:e979170e02e7 1287 if (ssl->arrays == NULL) {
ashleymills 0:e979170e02e7 1288 CYASSL_MSG("Arrays Memory error");
ashleymills 0:e979170e02e7 1289 return MEMORY_E;
ashleymills 0:e979170e02e7 1290 }
ashleymills 0:e979170e02e7 1291
ashleymills 0:e979170e02e7 1292 #ifndef NO_PSK
ashleymills 0:e979170e02e7 1293 ssl->arrays->client_identity[0] = 0;
ashleymills 0:e979170e02e7 1294 if (ctx->server_hint[0]) { /* set in CTX */
ashleymills 0:e979170e02e7 1295 XSTRNCPY(ssl->arrays->server_hint, ctx->server_hint, MAX_PSK_ID_LEN);
ashleymills 0:e979170e02e7 1296 ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
ashleymills 0:e979170e02e7 1297 }
ashleymills 0:e979170e02e7 1298 else
ashleymills 0:e979170e02e7 1299 ssl->arrays->server_hint[0] = 0;
ashleymills 0:e979170e02e7 1300 #endif /* NO_PSK */
ashleymills 0:e979170e02e7 1301
ashleymills 0:e979170e02e7 1302 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 1303 ssl->arrays->cookieSz = 0;
ashleymills 0:e979170e02e7 1304 #endif
ashleymills 0:e979170e02e7 1305
ashleymills 0:e979170e02e7 1306 /* RNG */
ashleymills 0:e979170e02e7 1307 ssl->rng = (RNG*)XMALLOC(sizeof(RNG), ssl->heap, DYNAMIC_TYPE_RNG);
ashleymills 0:e979170e02e7 1308 if (ssl->rng == NULL) {
ashleymills 0:e979170e02e7 1309 CYASSL_MSG("RNG Memory error");
ashleymills 0:e979170e02e7 1310 return MEMORY_E;
ashleymills 0:e979170e02e7 1311 }
ashleymills 0:e979170e02e7 1312
ashleymills 0:e979170e02e7 1313 if ( (ret = InitRng(ssl->rng)) != 0)
ashleymills 0:e979170e02e7 1314 return ret;
ashleymills 0:e979170e02e7 1315
ashleymills 0:e979170e02e7 1316 /* suites */
ashleymills 0:e979170e02e7 1317 ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
ashleymills 0:e979170e02e7 1318 DYNAMIC_TYPE_SUITES);
ashleymills 0:e979170e02e7 1319 if (ssl->suites == NULL) {
ashleymills 0:e979170e02e7 1320 CYASSL_MSG("Suites Memory error");
ashleymills 0:e979170e02e7 1321 return MEMORY_E;
ashleymills 0:e979170e02e7 1322 }
ashleymills 0:e979170e02e7 1323 *ssl->suites = ctx->suites;
ashleymills 0:e979170e02e7 1324
ashleymills 0:e979170e02e7 1325 /* peer key */
ashleymills 0:e979170e02e7 1326 #ifndef NO_RSA
ashleymills 0:e979170e02e7 1327 ssl->peerRsaKey = (RsaKey*)XMALLOC(sizeof(RsaKey), ssl->heap,
ashleymills 0:e979170e02e7 1328 DYNAMIC_TYPE_RSA);
ashleymills 0:e979170e02e7 1329 if (ssl->peerRsaKey == NULL) {
ashleymills 0:e979170e02e7 1330 CYASSL_MSG("PeerRsaKey Memory error");
ashleymills 0:e979170e02e7 1331 return MEMORY_E;
ashleymills 0:e979170e02e7 1332 }
ashleymills 0:e979170e02e7 1333 InitRsaKey(ssl->peerRsaKey, ctx->heap);
ashleymills 0:e979170e02e7 1334 #endif
ashleymills 0:e979170e02e7 1335 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 1336 /* make sure server has cert and key unless using PSK */
ashleymills 0:e979170e02e7 1337 if (ssl->options.side == SERVER_END && !havePSK)
ashleymills 0:e979170e02e7 1338 if (!ssl->buffers.certificate.buffer || !ssl->buffers.key.buffer) {
ashleymills 0:e979170e02e7 1339 CYASSL_MSG("Server missing certificate and/or private key");
ashleymills 0:e979170e02e7 1340 return NO_PRIVATE_KEY;
ashleymills 0:e979170e02e7 1341 }
ashleymills 0:e979170e02e7 1342 #endif
ashleymills 0:e979170e02e7 1343 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 1344 ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ashleymills 0:e979170e02e7 1345 ctx->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:e979170e02e7 1346 if (ssl->peerEccKey == NULL) {
ashleymills 0:e979170e02e7 1347 CYASSL_MSG("PeerEccKey Memory error");
ashleymills 0:e979170e02e7 1348 return MEMORY_E;
ashleymills 0:e979170e02e7 1349 }
ashleymills 0:e979170e02e7 1350 ssl->peerEccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ashleymills 0:e979170e02e7 1351 ctx->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:e979170e02e7 1352 if (ssl->peerEccDsaKey == NULL) {
ashleymills 0:e979170e02e7 1353 CYASSL_MSG("PeerEccDsaKey Memory error");
ashleymills 0:e979170e02e7 1354 return MEMORY_E;
ashleymills 0:e979170e02e7 1355 }
ashleymills 0:e979170e02e7 1356 ssl->eccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ashleymills 0:e979170e02e7 1357 ctx->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:e979170e02e7 1358 if (ssl->eccDsaKey == NULL) {
ashleymills 0:e979170e02e7 1359 CYASSL_MSG("EccDsaKey Memory error");
ashleymills 0:e979170e02e7 1360 return MEMORY_E;
ashleymills 0:e979170e02e7 1361 }
ashleymills 0:e979170e02e7 1362 ssl->eccTempKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ashleymills 0:e979170e02e7 1363 ctx->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:e979170e02e7 1364 if (ssl->eccTempKey == NULL) {
ashleymills 0:e979170e02e7 1365 CYASSL_MSG("EccTempKey Memory error");
ashleymills 0:e979170e02e7 1366 return MEMORY_E;
ashleymills 0:e979170e02e7 1367 }
ashleymills 0:e979170e02e7 1368 ecc_init(ssl->peerEccKey);
ashleymills 0:e979170e02e7 1369 ecc_init(ssl->peerEccDsaKey);
ashleymills 0:e979170e02e7 1370 ecc_init(ssl->eccDsaKey);
ashleymills 0:e979170e02e7 1371 ecc_init(ssl->eccTempKey);
ashleymills 0:e979170e02e7 1372 #endif
ashleymills 0:e979170e02e7 1373
ashleymills 0:e979170e02e7 1374 /* make sure server has DH parms, and add PSK if there, add NTRU too */
ashleymills 0:e979170e02e7 1375 if (ssl->options.side == SERVER_END)
ashleymills 0:e979170e02e7 1376 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
ashleymills 0:e979170e02e7 1377 ssl->options.haveDH, ssl->options.haveNTRU,
ashleymills 0:e979170e02e7 1378 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
ashleymills 0:e979170e02e7 1379 ssl->options.side);
ashleymills 0:e979170e02e7 1380 else
ashleymills 0:e979170e02e7 1381 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, TRUE,
ashleymills 0:e979170e02e7 1382 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
ashleymills 0:e979170e02e7 1383 ssl->options.haveStaticECC, ssl->options.side);
ashleymills 0:e979170e02e7 1384
ashleymills 0:e979170e02e7 1385 return 0;
ashleymills 0:e979170e02e7 1386 }
ashleymills 0:e979170e02e7 1387
ashleymills 0:e979170e02e7 1388
ashleymills 0:e979170e02e7 1389 /* free use of temporary arrays */
ashleymills 0:e979170e02e7 1390 void FreeArrays(CYASSL* ssl, int keep)
ashleymills 0:e979170e02e7 1391 {
ashleymills 0:e979170e02e7 1392 if (ssl->arrays && keep) {
ashleymills 0:e979170e02e7 1393 /* keeps session id for user retrieval */
ashleymills 0:e979170e02e7 1394 XMEMCPY(ssl->session.sessionID, ssl->arrays->sessionID, ID_LEN);
ashleymills 0:e979170e02e7 1395 }
ashleymills 0:e979170e02e7 1396 XFREE(ssl->arrays, ssl->heap, DYNAMIC_TYPE_ARRAYS);
ashleymills 0:e979170e02e7 1397 ssl->arrays = NULL;
ashleymills 0:e979170e02e7 1398 }
ashleymills 0:e979170e02e7 1399
ashleymills 0:e979170e02e7 1400
ashleymills 0:e979170e02e7 1401 /* In case holding SSL object in array and don't want to free actual ssl */
ashleymills 0:e979170e02e7 1402 void SSL_ResourceFree(CYASSL* ssl)
ashleymills 0:e979170e02e7 1403 {
ashleymills 0:e979170e02e7 1404 FreeCiphers(ssl);
ashleymills 0:e979170e02e7 1405 FreeArrays(ssl, 0);
ashleymills 0:e979170e02e7 1406 XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
ashleymills 0:e979170e02e7 1407 XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
ashleymills 0:e979170e02e7 1408 XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
ashleymills 0:e979170e02e7 1409
ashleymills 0:e979170e02e7 1410 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 1411 XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
ashleymills 0:e979170e02e7 1412 XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH);
ashleymills 0:e979170e02e7 1413 /* parameters (p,g) may be owned by ctx */
ashleymills 0:e979170e02e7 1414 if (ssl->buffers.weOwnDH || ssl->options.side == CLIENT_END) {
ashleymills 0:e979170e02e7 1415 XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
ashleymills 0:e979170e02e7 1416 XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
ashleymills 0:e979170e02e7 1417 }
ashleymills 0:e979170e02e7 1418
ashleymills 0:e979170e02e7 1419 /* CYASSL_CTX always owns certChain */
ashleymills 0:e979170e02e7 1420 if (ssl->buffers.weOwnCert)
ashleymills 0:e979170e02e7 1421 XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
ashleymills 0:e979170e02e7 1422 if (ssl->buffers.weOwnKey)
ashleymills 0:e979170e02e7 1423 XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
ashleymills 0:e979170e02e7 1424 #endif
ashleymills 0:e979170e02e7 1425 #ifndef NO_RSA
ashleymills 0:e979170e02e7 1426 if (ssl->peerRsaKey) {
ashleymills 0:e979170e02e7 1427 FreeRsaKey(ssl->peerRsaKey);
ashleymills 0:e979170e02e7 1428 XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
ashleymills 0:e979170e02e7 1429 }
ashleymills 0:e979170e02e7 1430 #endif
ashleymills 0:e979170e02e7 1431 if (ssl->buffers.inputBuffer.dynamicFlag)
ashleymills 0:e979170e02e7 1432 ShrinkInputBuffer(ssl, FORCED_FREE);
ashleymills 0:e979170e02e7 1433 if (ssl->buffers.outputBuffer.dynamicFlag)
ashleymills 0:e979170e02e7 1434 ShrinkOutputBuffer(ssl);
ashleymills 0:e979170e02e7 1435 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 1436 if (ssl->buffers.dtlsHandshake.buffer != NULL)
ashleymills 0:e979170e02e7 1437 XFREE(ssl->buffers.dtlsHandshake.buffer, ssl->heap, DYNAMIC_TYPE_NONE);
ashleymills 0:e979170e02e7 1438 if (ssl->dtls_pool != NULL) {
ashleymills 0:e979170e02e7 1439 DtlsPoolReset(ssl);
ashleymills 0:e979170e02e7 1440 XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_NONE);
ashleymills 0:e979170e02e7 1441 }
ashleymills 0:e979170e02e7 1442 XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
ashleymills 0:e979170e02e7 1443 ssl->buffers.dtlsCtx.peer.sa = NULL;
ashleymills 0:e979170e02e7 1444 #endif
ashleymills 0:e979170e02e7 1445 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
ashleymills 0:e979170e02e7 1446 XFREE(ssl->peerCert.derCert.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
ashleymills 0:e979170e02e7 1447 if (ssl->peerCert.altNames)
ashleymills 0:e979170e02e7 1448 FreeAltNames(ssl->peerCert.altNames, ssl->heap);
ashleymills 0:e979170e02e7 1449 CyaSSL_BIO_free(ssl->biord);
ashleymills 0:e979170e02e7 1450 if (ssl->biord != ssl->biowr) /* in case same as write */
ashleymills 0:e979170e02e7 1451 CyaSSL_BIO_free(ssl->biowr);
ashleymills 0:e979170e02e7 1452 #endif
ashleymills 0:e979170e02e7 1453 #ifdef HAVE_LIBZ
ashleymills 0:e979170e02e7 1454 FreeStreams(ssl);
ashleymills 0:e979170e02e7 1455 #endif
ashleymills 0:e979170e02e7 1456 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 1457 if (ssl->peerEccKey) {
ashleymills 0:e979170e02e7 1458 if (ssl->peerEccKeyPresent)
ashleymills 0:e979170e02e7 1459 ecc_free(ssl->peerEccKey);
ashleymills 0:e979170e02e7 1460 XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:e979170e02e7 1461 }
ashleymills 0:e979170e02e7 1462 if (ssl->peerEccDsaKey) {
ashleymills 0:e979170e02e7 1463 if (ssl->peerEccDsaKeyPresent)
ashleymills 0:e979170e02e7 1464 ecc_free(ssl->peerEccDsaKey);
ashleymills 0:e979170e02e7 1465 XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:e979170e02e7 1466 }
ashleymills 0:e979170e02e7 1467 if (ssl->eccTempKey) {
ashleymills 0:e979170e02e7 1468 if (ssl->eccTempKeyPresent)
ashleymills 0:e979170e02e7 1469 ecc_free(ssl->eccTempKey);
ashleymills 0:e979170e02e7 1470 XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:e979170e02e7 1471 }
ashleymills 0:e979170e02e7 1472 if (ssl->eccDsaKey) {
ashleymills 0:e979170e02e7 1473 if (ssl->eccDsaKeyPresent)
ashleymills 0:e979170e02e7 1474 ecc_free(ssl->eccDsaKey);
ashleymills 0:e979170e02e7 1475 XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:e979170e02e7 1476 }
ashleymills 0:e979170e02e7 1477 #endif
ashleymills 0:e979170e02e7 1478 }
ashleymills 0:e979170e02e7 1479
ashleymills 0:e979170e02e7 1480
ashleymills 0:e979170e02e7 1481 /* Free any handshake resources no longer needed */
ashleymills 0:e979170e02e7 1482 void FreeHandshakeResources(CYASSL* ssl)
ashleymills 0:e979170e02e7 1483 {
ashleymills 0:e979170e02e7 1484 /* input buffer */
ashleymills 0:e979170e02e7 1485 if (ssl->buffers.inputBuffer.dynamicFlag)
ashleymills 0:e979170e02e7 1486 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
ashleymills 0:e979170e02e7 1487
ashleymills 0:e979170e02e7 1488 /* suites */
ashleymills 0:e979170e02e7 1489 XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
ashleymills 0:e979170e02e7 1490 ssl->suites = NULL;
ashleymills 0:e979170e02e7 1491
ashleymills 0:e979170e02e7 1492 /* RNG */
ashleymills 0:e979170e02e7 1493 if (ssl->specs.cipher_type == stream || ssl->options.tls1_1 == 0) {
ashleymills 0:e979170e02e7 1494 XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
ashleymills 0:e979170e02e7 1495 ssl->rng = NULL;
ashleymills 0:e979170e02e7 1496 }
ashleymills 0:e979170e02e7 1497
ashleymills 0:e979170e02e7 1498 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 1499 /* DTLS_POOL */
ashleymills 0:e979170e02e7 1500 if (ssl->options.dtls && ssl->dtls_pool != NULL) {
ashleymills 0:e979170e02e7 1501 DtlsPoolReset(ssl);
ashleymills 0:e979170e02e7 1502 XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
ashleymills 0:e979170e02e7 1503 ssl->dtls_pool = NULL;
ashleymills 0:e979170e02e7 1504 }
ashleymills 0:e979170e02e7 1505 #endif
ashleymills 0:e979170e02e7 1506
ashleymills 0:e979170e02e7 1507 /* arrays */
ashleymills 0:e979170e02e7 1508 if (ssl->options.saveArrays)
ashleymills 0:e979170e02e7 1509 FreeArrays(ssl, 1);
ashleymills 0:e979170e02e7 1510
ashleymills 0:e979170e02e7 1511 #ifndef NO_RSA
ashleymills 0:e979170e02e7 1512 /* peerRsaKey */
ashleymills 0:e979170e02e7 1513 if (ssl->peerRsaKey) {
ashleymills 0:e979170e02e7 1514 FreeRsaKey(ssl->peerRsaKey);
ashleymills 0:e979170e02e7 1515 XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
ashleymills 0:e979170e02e7 1516 ssl->peerRsaKey = NULL;
ashleymills 0:e979170e02e7 1517 }
ashleymills 0:e979170e02e7 1518 #endif
ashleymills 0:e979170e02e7 1519
ashleymills 0:e979170e02e7 1520 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 1521 if (ssl->peerEccKey)
ashleymills 0:e979170e02e7 1522 {
ashleymills 0:e979170e02e7 1523 if (ssl->peerEccKeyPresent) {
ashleymills 0:e979170e02e7 1524 ecc_free(ssl->peerEccKey);
ashleymills 0:e979170e02e7 1525 ssl->peerEccKeyPresent = 0;
ashleymills 0:e979170e02e7 1526 }
ashleymills 0:e979170e02e7 1527 XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:e979170e02e7 1528 ssl->peerEccKey = NULL;
ashleymills 0:e979170e02e7 1529 }
ashleymills 0:e979170e02e7 1530 if (ssl->peerEccDsaKey)
ashleymills 0:e979170e02e7 1531 {
ashleymills 0:e979170e02e7 1532 if (ssl->peerEccDsaKeyPresent) {
ashleymills 0:e979170e02e7 1533 ecc_free(ssl->peerEccDsaKey);
ashleymills 0:e979170e02e7 1534 ssl->peerEccDsaKeyPresent = 0;
ashleymills 0:e979170e02e7 1535 }
ashleymills 0:e979170e02e7 1536 XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:e979170e02e7 1537 ssl->peerEccDsaKey = NULL;
ashleymills 0:e979170e02e7 1538 }
ashleymills 0:e979170e02e7 1539 if (ssl->eccTempKey)
ashleymills 0:e979170e02e7 1540 {
ashleymills 0:e979170e02e7 1541 if (ssl->eccTempKeyPresent) {
ashleymills 0:e979170e02e7 1542 ecc_free(ssl->eccTempKey);
ashleymills 0:e979170e02e7 1543 ssl->eccTempKeyPresent = 0;
ashleymills 0:e979170e02e7 1544 }
ashleymills 0:e979170e02e7 1545 XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:e979170e02e7 1546 ssl->eccTempKey = NULL;
ashleymills 0:e979170e02e7 1547 }
ashleymills 0:e979170e02e7 1548 if (ssl->eccDsaKey)
ashleymills 0:e979170e02e7 1549 {
ashleymills 0:e979170e02e7 1550 if (ssl->eccDsaKeyPresent) {
ashleymills 0:e979170e02e7 1551 ecc_free(ssl->eccDsaKey);
ashleymills 0:e979170e02e7 1552 ssl->eccDsaKeyPresent = 0;
ashleymills 0:e979170e02e7 1553 }
ashleymills 0:e979170e02e7 1554 XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
ashleymills 0:e979170e02e7 1555 ssl->eccDsaKey = NULL;
ashleymills 0:e979170e02e7 1556 }
ashleymills 0:e979170e02e7 1557 #endif
ashleymills 0:e979170e02e7 1558 }
ashleymills 0:e979170e02e7 1559
ashleymills 0:e979170e02e7 1560
ashleymills 0:e979170e02e7 1561 void FreeSSL(CYASSL* ssl)
ashleymills 0:e979170e02e7 1562 {
ashleymills 0:e979170e02e7 1563 FreeSSL_Ctx(ssl->ctx); /* will decrement and free underyling CTX if 0 */
ashleymills 0:e979170e02e7 1564 SSL_ResourceFree(ssl);
ashleymills 0:e979170e02e7 1565 XFREE(ssl, ssl->heap, DYNAMIC_TYPE_SSL);
ashleymills 0:e979170e02e7 1566 }
ashleymills 0:e979170e02e7 1567
ashleymills 0:e979170e02e7 1568
ashleymills 0:e979170e02e7 1569 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 1570
ashleymills 0:e979170e02e7 1571 int DtlsPoolInit(CYASSL* ssl)
ashleymills 0:e979170e02e7 1572 {
ashleymills 0:e979170e02e7 1573 if (ssl->dtls_pool == NULL) {
ashleymills 0:e979170e02e7 1574 DtlsPool *pool = (DtlsPool*)XMALLOC(sizeof(DtlsPool),
ashleymills 0:e979170e02e7 1575 ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
ashleymills 0:e979170e02e7 1576 if (pool == NULL) {
ashleymills 0:e979170e02e7 1577 CYASSL_MSG("DTLS Buffer Pool Memory error");
ashleymills 0:e979170e02e7 1578 return MEMORY_E;
ashleymills 0:e979170e02e7 1579 }
ashleymills 0:e979170e02e7 1580 else {
ashleymills 0:e979170e02e7 1581 int i;
ashleymills 0:e979170e02e7 1582
ashleymills 0:e979170e02e7 1583 for (i = 0; i < DTLS_POOL_SZ; i++) {
ashleymills 0:e979170e02e7 1584 pool->buf[i].length = 0;
ashleymills 0:e979170e02e7 1585 pool->buf[i].buffer = NULL;
ashleymills 0:e979170e02e7 1586 }
ashleymills 0:e979170e02e7 1587 pool->used = 0;
ashleymills 0:e979170e02e7 1588 ssl->dtls_pool = pool;
ashleymills 0:e979170e02e7 1589 }
ashleymills 0:e979170e02e7 1590 }
ashleymills 0:e979170e02e7 1591 return 0;
ashleymills 0:e979170e02e7 1592 }
ashleymills 0:e979170e02e7 1593
ashleymills 0:e979170e02e7 1594
ashleymills 0:e979170e02e7 1595 int DtlsPoolSave(CYASSL* ssl, const byte *src, int sz)
ashleymills 0:e979170e02e7 1596 {
ashleymills 0:e979170e02e7 1597 DtlsPool *pool = ssl->dtls_pool;
ashleymills 0:e979170e02e7 1598 if (pool != NULL && pool->used < DTLS_POOL_SZ) {
ashleymills 0:e979170e02e7 1599 buffer *pBuf = &pool->buf[pool->used];
ashleymills 0:e979170e02e7 1600 pBuf->buffer = (byte*)XMALLOC(sz, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
ashleymills 0:e979170e02e7 1601 if (pBuf->buffer == NULL) {
ashleymills 0:e979170e02e7 1602 CYASSL_MSG("DTLS Buffer Memory error");
ashleymills 0:e979170e02e7 1603 return MEMORY_ERROR;
ashleymills 0:e979170e02e7 1604 }
ashleymills 0:e979170e02e7 1605 XMEMCPY(pBuf->buffer, src, sz);
ashleymills 0:e979170e02e7 1606 pBuf->length = (word32)sz;
ashleymills 0:e979170e02e7 1607 pool->used++;
ashleymills 0:e979170e02e7 1608 }
ashleymills 0:e979170e02e7 1609 return 0;
ashleymills 0:e979170e02e7 1610 }
ashleymills 0:e979170e02e7 1611
ashleymills 0:e979170e02e7 1612
ashleymills 0:e979170e02e7 1613 void DtlsPoolReset(CYASSL* ssl)
ashleymills 0:e979170e02e7 1614 {
ashleymills 0:e979170e02e7 1615 DtlsPool *pool = ssl->dtls_pool;
ashleymills 0:e979170e02e7 1616 if (pool != NULL) {
ashleymills 0:e979170e02e7 1617 buffer *pBuf;
ashleymills 0:e979170e02e7 1618 int i, used;
ashleymills 0:e979170e02e7 1619
ashleymills 0:e979170e02e7 1620 used = pool->used;
ashleymills 0:e979170e02e7 1621 for (i = 0, pBuf = &pool->buf[0]; i < used; i++, pBuf++) {
ashleymills 0:e979170e02e7 1622 XFREE(pBuf->buffer, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
ashleymills 0:e979170e02e7 1623 pBuf->buffer = NULL;
ashleymills 0:e979170e02e7 1624 pBuf->length = 0;
ashleymills 0:e979170e02e7 1625 }
ashleymills 0:e979170e02e7 1626 pool->used = 0;
ashleymills 0:e979170e02e7 1627 }
ashleymills 0:e979170e02e7 1628 ssl->dtls_timeout = DTLS_DEFAULT_TIMEOUT;
ashleymills 0:e979170e02e7 1629 }
ashleymills 0:e979170e02e7 1630
ashleymills 0:e979170e02e7 1631
ashleymills 0:e979170e02e7 1632 int DtlsPoolTimeout(CYASSL* ssl)
ashleymills 0:e979170e02e7 1633 {
ashleymills 0:e979170e02e7 1634 int result = -1;
ashleymills 0:e979170e02e7 1635 if (ssl->dtls_timeout < 64) {
ashleymills 0:e979170e02e7 1636 ssl->dtls_timeout *= 2;
ashleymills 0:e979170e02e7 1637 result = 0;
ashleymills 0:e979170e02e7 1638 }
ashleymills 0:e979170e02e7 1639 return result;
ashleymills 0:e979170e02e7 1640 }
ashleymills 0:e979170e02e7 1641
ashleymills 0:e979170e02e7 1642
ashleymills 0:e979170e02e7 1643 int DtlsPoolSend(CYASSL* ssl)
ashleymills 0:e979170e02e7 1644 {
ashleymills 0:e979170e02e7 1645 DtlsPool *pool = ssl->dtls_pool;
ashleymills 0:e979170e02e7 1646
ashleymills 0:e979170e02e7 1647 if (pool != NULL && pool->used > 0) {
ashleymills 0:e979170e02e7 1648 int i;
ashleymills 0:e979170e02e7 1649 for (i = 0; i < pool->used; i++) {
ashleymills 0:e979170e02e7 1650 int sendResult;
ashleymills 0:e979170e02e7 1651 buffer* buf = &pool->buf[i];
ashleymills 0:e979170e02e7 1652 DtlsRecordLayerHeader* dtls = (DtlsRecordLayerHeader*)buf->buffer;
ashleymills 0:e979170e02e7 1653
ashleymills 0:e979170e02e7 1654 if (dtls->type == change_cipher_spec) {
ashleymills 0:e979170e02e7 1655 ssl->keys.dtls_epoch++;
ashleymills 0:e979170e02e7 1656 ssl->keys.dtls_sequence_number = 0;
ashleymills 0:e979170e02e7 1657 }
ashleymills 0:e979170e02e7 1658 c16toa(ssl->keys.dtls_epoch, dtls->epoch);
ashleymills 0:e979170e02e7 1659 c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number);
ashleymills 0:e979170e02e7 1660
ashleymills 0:e979170e02e7 1661 XMEMCPY(ssl->buffers.outputBuffer.buffer, buf->buffer, buf->length);
ashleymills 0:e979170e02e7 1662 ssl->buffers.outputBuffer.idx = 0;
ashleymills 0:e979170e02e7 1663 ssl->buffers.outputBuffer.length = buf->length;
ashleymills 0:e979170e02e7 1664
ashleymills 0:e979170e02e7 1665 sendResult = SendBuffered(ssl);
ashleymills 0:e979170e02e7 1666 if (sendResult < 0) {
ashleymills 0:e979170e02e7 1667 return sendResult;
ashleymills 0:e979170e02e7 1668 }
ashleymills 0:e979170e02e7 1669 }
ashleymills 0:e979170e02e7 1670 }
ashleymills 0:e979170e02e7 1671 return 0;
ashleymills 0:e979170e02e7 1672 }
ashleymills 0:e979170e02e7 1673
ashleymills 0:e979170e02e7 1674 #endif
ashleymills 0:e979170e02e7 1675
ashleymills 0:e979170e02e7 1676 #ifndef NO_OLD_TLS
ashleymills 0:e979170e02e7 1677
ashleymills 0:e979170e02e7 1678 ProtocolVersion MakeSSLv3(void)
ashleymills 0:e979170e02e7 1679 {
ashleymills 0:e979170e02e7 1680 ProtocolVersion pv;
ashleymills 0:e979170e02e7 1681 pv.major = SSLv3_MAJOR;
ashleymills 0:e979170e02e7 1682 pv.minor = SSLv3_MINOR;
ashleymills 0:e979170e02e7 1683
ashleymills 0:e979170e02e7 1684 return pv;
ashleymills 0:e979170e02e7 1685 }
ashleymills 0:e979170e02e7 1686
ashleymills 0:e979170e02e7 1687 #endif /* NO_OLD_TLS */
ashleymills 0:e979170e02e7 1688
ashleymills 0:e979170e02e7 1689
ashleymills 0:e979170e02e7 1690 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 1691
ashleymills 0:e979170e02e7 1692 ProtocolVersion MakeDTLSv1(void)
ashleymills 0:e979170e02e7 1693 {
ashleymills 0:e979170e02e7 1694 ProtocolVersion pv;
ashleymills 0:e979170e02e7 1695 pv.major = DTLS_MAJOR;
ashleymills 0:e979170e02e7 1696 pv.minor = DTLS_MINOR;
ashleymills 0:e979170e02e7 1697
ashleymills 0:e979170e02e7 1698 return pv;
ashleymills 0:e979170e02e7 1699 }
ashleymills 0:e979170e02e7 1700
ashleymills 0:e979170e02e7 1701 #endif /* CYASSL_DTLS */
ashleymills 0:e979170e02e7 1702
ashleymills 0:e979170e02e7 1703
ashleymills 0:e979170e02e7 1704
ashleymills 0:e979170e02e7 1705
ashleymills 0:e979170e02e7 1706 #ifdef USE_WINDOWS_API
ashleymills 0:e979170e02e7 1707
ashleymills 0:e979170e02e7 1708 timer_d Timer(void)
ashleymills 0:e979170e02e7 1709 {
ashleymills 0:e979170e02e7 1710 static int init = 0;
ashleymills 0:e979170e02e7 1711 static LARGE_INTEGER freq;
ashleymills 0:e979170e02e7 1712 LARGE_INTEGER count;
ashleymills 0:e979170e02e7 1713
ashleymills 0:e979170e02e7 1714 if (!init) {
ashleymills 0:e979170e02e7 1715 QueryPerformanceFrequency(&freq);
ashleymills 0:e979170e02e7 1716 init = 1;
ashleymills 0:e979170e02e7 1717 }
ashleymills 0:e979170e02e7 1718
ashleymills 0:e979170e02e7 1719 QueryPerformanceCounter(&count);
ashleymills 0:e979170e02e7 1720
ashleymills 0:e979170e02e7 1721 return (double)count.QuadPart / freq.QuadPart;
ashleymills 0:e979170e02e7 1722 }
ashleymills 0:e979170e02e7 1723
ashleymills 0:e979170e02e7 1724
ashleymills 0:e979170e02e7 1725 word32 LowResTimer(void)
ashleymills 0:e979170e02e7 1726 {
ashleymills 0:e979170e02e7 1727 return (word32)Timer();
ashleymills 0:e979170e02e7 1728 }
ashleymills 0:e979170e02e7 1729
ashleymills 0:e979170e02e7 1730
ashleymills 0:e979170e02e7 1731 #elif defined(THREADX)
ashleymills 0:e979170e02e7 1732
ashleymills 0:e979170e02e7 1733 #include "rtptime.h"
ashleymills 0:e979170e02e7 1734
ashleymills 0:e979170e02e7 1735 word32 LowResTimer(void)
ashleymills 0:e979170e02e7 1736 {
ashleymills 0:e979170e02e7 1737 return (word32)rtp_get_system_sec();
ashleymills 0:e979170e02e7 1738 }
ashleymills 0:e979170e02e7 1739
ashleymills 0:e979170e02e7 1740
ashleymills 0:e979170e02e7 1741 #elif defined(MICRIUM)
ashleymills 0:e979170e02e7 1742
ashleymills 0:e979170e02e7 1743 word32 LowResTimer(void)
ashleymills 0:e979170e02e7 1744 {
ashleymills 0:e979170e02e7 1745 NET_SECURE_OS_TICK clk;
ashleymills 0:e979170e02e7 1746
ashleymills 0:e979170e02e7 1747 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
ashleymills 0:e979170e02e7 1748 clk = NetSecure_OS_TimeGet();
ashleymills 0:e979170e02e7 1749 #endif
ashleymills 0:e979170e02e7 1750 return (word32)clk;
ashleymills 0:e979170e02e7 1751 }
ashleymills 0:e979170e02e7 1752
ashleymills 0:e979170e02e7 1753 #elif defined(USER_TICKS)
ashleymills 0:e979170e02e7 1754
ashleymills 0:e979170e02e7 1755 word32 LowResTimer(void)
ashleymills 0:e979170e02e7 1756 {
ashleymills 0:e979170e02e7 1757 /*
ashleymills 0:e979170e02e7 1758 write your own clock tick function if don't want time(0)
ashleymills 0:e979170e02e7 1759 needs second accuracy but doesn't have to correlated to EPOCH
ashleymills 0:e979170e02e7 1760 */
ashleymills 0:e979170e02e7 1761 }
ashleymills 0:e979170e02e7 1762
ashleymills 0:e979170e02e7 1763 #else /* !USE_WINDOWS_API && !THREADX && !MICRIUM && !USER_TICKS */
ashleymills 0:e979170e02e7 1764
ashleymills 0:e979170e02e7 1765 #include <time.h>
ashleymills 0:e979170e02e7 1766
ashleymills 0:e979170e02e7 1767 word32 LowResTimer(void)
ashleymills 0:e979170e02e7 1768 {
ashleymills 0:e979170e02e7 1769 return (word32)time(0);
ashleymills 0:e979170e02e7 1770 }
ashleymills 0:e979170e02e7 1771
ashleymills 0:e979170e02e7 1772
ashleymills 0:e979170e02e7 1773 #endif /* USE_WINDOWS_API */
ashleymills 0:e979170e02e7 1774
ashleymills 0:e979170e02e7 1775
ashleymills 0:e979170e02e7 1776 /* add output to md5 and sha handshake hashes, exclude record header */
ashleymills 0:e979170e02e7 1777 static void HashOutput(CYASSL* ssl, const byte* output, int sz, int ivSz)
ashleymills 0:e979170e02e7 1778 {
ashleymills 0:e979170e02e7 1779 const byte* adj = output + RECORD_HEADER_SZ + ivSz;
ashleymills 0:e979170e02e7 1780 sz -= RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 1781
ashleymills 0:e979170e02e7 1782 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 1783 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 1784 adj += DTLS_RECORD_EXTRA;
ashleymills 0:e979170e02e7 1785 sz -= DTLS_RECORD_EXTRA;
ashleymills 0:e979170e02e7 1786 }
ashleymills 0:e979170e02e7 1787 #endif
ashleymills 0:e979170e02e7 1788
ashleymills 0:e979170e02e7 1789 ShaUpdate(&ssl->hashSha, adj, sz);
ashleymills 0:e979170e02e7 1790 #ifndef NO_MD5
ashleymills 0:e979170e02e7 1791 Md5Update(&ssl->hashMd5, adj, sz);
ashleymills 0:e979170e02e7 1792 #endif
ashleymills 0:e979170e02e7 1793
ashleymills 0:e979170e02e7 1794 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:e979170e02e7 1795 #ifndef NO_SHA256
ashleymills 0:e979170e02e7 1796 Sha256Update(&ssl->hashSha256, adj, sz);
ashleymills 0:e979170e02e7 1797 #endif
ashleymills 0:e979170e02e7 1798 #ifdef CYASSL_SHA384
ashleymills 0:e979170e02e7 1799 Sha384Update(&ssl->hashSha384, adj, sz);
ashleymills 0:e979170e02e7 1800 #endif
ashleymills 0:e979170e02e7 1801 }
ashleymills 0:e979170e02e7 1802 }
ashleymills 0:e979170e02e7 1803
ashleymills 0:e979170e02e7 1804
ashleymills 0:e979170e02e7 1805 /* add input to md5 and sha handshake hashes, include handshake header */
ashleymills 0:e979170e02e7 1806 static void HashInput(CYASSL* ssl, const byte* input, int sz)
ashleymills 0:e979170e02e7 1807 {
ashleymills 0:e979170e02e7 1808 const byte* adj = input - HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 1809 sz += HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 1810
ashleymills 0:e979170e02e7 1811 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 1812 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 1813 adj -= DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 1814 sz += DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 1815 }
ashleymills 0:e979170e02e7 1816 #endif
ashleymills 0:e979170e02e7 1817
ashleymills 0:e979170e02e7 1818 ShaUpdate(&ssl->hashSha, adj, sz);
ashleymills 0:e979170e02e7 1819 #ifndef NO_MD5
ashleymills 0:e979170e02e7 1820 Md5Update(&ssl->hashMd5, adj, sz);
ashleymills 0:e979170e02e7 1821 #endif
ashleymills 0:e979170e02e7 1822
ashleymills 0:e979170e02e7 1823 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:e979170e02e7 1824 #ifndef NO_SHA256
ashleymills 0:e979170e02e7 1825 Sha256Update(&ssl->hashSha256, adj, sz);
ashleymills 0:e979170e02e7 1826 #endif
ashleymills 0:e979170e02e7 1827 #ifdef CYASSL_SHA384
ashleymills 0:e979170e02e7 1828 Sha384Update(&ssl->hashSha384, adj, sz);
ashleymills 0:e979170e02e7 1829 #endif
ashleymills 0:e979170e02e7 1830 }
ashleymills 0:e979170e02e7 1831 }
ashleymills 0:e979170e02e7 1832
ashleymills 0:e979170e02e7 1833
ashleymills 0:e979170e02e7 1834 /* add record layer header for message */
ashleymills 0:e979170e02e7 1835 static void AddRecordHeader(byte* output, word32 length, byte type, CYASSL* ssl)
ashleymills 0:e979170e02e7 1836 {
ashleymills 0:e979170e02e7 1837 RecordLayerHeader* rl;
ashleymills 0:e979170e02e7 1838
ashleymills 0:e979170e02e7 1839 /* record layer header */
ashleymills 0:e979170e02e7 1840 rl = (RecordLayerHeader*)output;
ashleymills 0:e979170e02e7 1841 rl->type = type;
ashleymills 0:e979170e02e7 1842 rl->pvMajor = ssl->version.major; /* type and version same in each */
ashleymills 0:e979170e02e7 1843 rl->pvMinor = ssl->version.minor;
ashleymills 0:e979170e02e7 1844
ashleymills 0:e979170e02e7 1845 if (!ssl->options.dtls)
ashleymills 0:e979170e02e7 1846 c16toa((word16)length, rl->length);
ashleymills 0:e979170e02e7 1847 else {
ashleymills 0:e979170e02e7 1848 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 1849 DtlsRecordLayerHeader* dtls;
ashleymills 0:e979170e02e7 1850
ashleymills 0:e979170e02e7 1851 /* dtls record layer header extensions */
ashleymills 0:e979170e02e7 1852 dtls = (DtlsRecordLayerHeader*)output;
ashleymills 0:e979170e02e7 1853 c16toa(ssl->keys.dtls_epoch, dtls->epoch);
ashleymills 0:e979170e02e7 1854 c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number);
ashleymills 0:e979170e02e7 1855 c16toa((word16)length, dtls->length);
ashleymills 0:e979170e02e7 1856 #endif
ashleymills 0:e979170e02e7 1857 }
ashleymills 0:e979170e02e7 1858 }
ashleymills 0:e979170e02e7 1859
ashleymills 0:e979170e02e7 1860
ashleymills 0:e979170e02e7 1861 /* add handshake header for message */
ashleymills 0:e979170e02e7 1862 static void AddHandShakeHeader(byte* output, word32 length, byte type,
ashleymills 0:e979170e02e7 1863 CYASSL* ssl)
ashleymills 0:e979170e02e7 1864 {
ashleymills 0:e979170e02e7 1865 HandShakeHeader* hs;
ashleymills 0:e979170e02e7 1866 (void)ssl;
ashleymills 0:e979170e02e7 1867
ashleymills 0:e979170e02e7 1868 /* handshake header */
ashleymills 0:e979170e02e7 1869 hs = (HandShakeHeader*)output;
ashleymills 0:e979170e02e7 1870 hs->type = type;
ashleymills 0:e979170e02e7 1871 c32to24(length, hs->length); /* type and length same for each */
ashleymills 0:e979170e02e7 1872 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 1873 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 1874 DtlsHandShakeHeader* dtls;
ashleymills 0:e979170e02e7 1875
ashleymills 0:e979170e02e7 1876 /* dtls handshake header extensions */
ashleymills 0:e979170e02e7 1877 dtls = (DtlsHandShakeHeader*)output;
ashleymills 0:e979170e02e7 1878 c16toa(ssl->keys.dtls_handshake_number++, dtls->message_seq);
ashleymills 0:e979170e02e7 1879 c32to24(0, dtls->fragment_offset);
ashleymills 0:e979170e02e7 1880 c32to24(length, dtls->fragment_length);
ashleymills 0:e979170e02e7 1881 }
ashleymills 0:e979170e02e7 1882 #endif
ashleymills 0:e979170e02e7 1883 }
ashleymills 0:e979170e02e7 1884
ashleymills 0:e979170e02e7 1885
ashleymills 0:e979170e02e7 1886 /* add both headers for handshake message */
ashleymills 0:e979170e02e7 1887 static void AddHeaders(byte* output, word32 length, byte type, CYASSL* ssl)
ashleymills 0:e979170e02e7 1888 {
ashleymills 0:e979170e02e7 1889 if (!ssl->options.dtls) {
ashleymills 0:e979170e02e7 1890 AddRecordHeader(output, length + HANDSHAKE_HEADER_SZ, handshake, ssl);
ashleymills 0:e979170e02e7 1891 AddHandShakeHeader(output + RECORD_HEADER_SZ, length, type, ssl);
ashleymills 0:e979170e02e7 1892 }
ashleymills 0:e979170e02e7 1893 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 1894 else {
ashleymills 0:e979170e02e7 1895 AddRecordHeader(output, length+DTLS_HANDSHAKE_HEADER_SZ, handshake,ssl);
ashleymills 0:e979170e02e7 1896 AddHandShakeHeader(output + DTLS_RECORD_HEADER_SZ, length, type, ssl);
ashleymills 0:e979170e02e7 1897 }
ashleymills 0:e979170e02e7 1898 #endif
ashleymills 0:e979170e02e7 1899 }
ashleymills 0:e979170e02e7 1900
ashleymills 0:e979170e02e7 1901
ashleymills 0:e979170e02e7 1902 /* return bytes received, -1 on error */
ashleymills 0:e979170e02e7 1903 static int Receive(CYASSL* ssl, byte* buf, word32 sz)
ashleymills 0:e979170e02e7 1904 {
ashleymills 0:e979170e02e7 1905 int recvd;
ashleymills 0:e979170e02e7 1906
ashleymills 0:e979170e02e7 1907 retry:
ashleymills 0:e979170e02e7 1908 recvd = ssl->ctx->CBIORecv(ssl, (char *)buf, (int)sz, ssl->IOCB_ReadCtx);
ashleymills 0:e979170e02e7 1909 if (recvd < 0)
ashleymills 0:e979170e02e7 1910 switch (recvd) {
ashleymills 0:e979170e02e7 1911 case IO_ERR_GENERAL: /* general/unknown error */
ashleymills 0:e979170e02e7 1912 return -1;
ashleymills 0:e979170e02e7 1913
ashleymills 0:e979170e02e7 1914 case IO_ERR_WANT_READ: /* want read, would block */
ashleymills 0:e979170e02e7 1915 return WANT_READ;
ashleymills 0:e979170e02e7 1916
ashleymills 0:e979170e02e7 1917 case IO_ERR_CONN_RST: /* connection reset */
ashleymills 0:e979170e02e7 1918 #ifdef USE_WINDOWS_API
ashleymills 0:e979170e02e7 1919 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 1920 goto retry;
ashleymills 0:e979170e02e7 1921 }
ashleymills 0:e979170e02e7 1922 #endif
ashleymills 0:e979170e02e7 1923 ssl->options.connReset = 1;
ashleymills 0:e979170e02e7 1924 return -1;
ashleymills 0:e979170e02e7 1925
ashleymills 0:e979170e02e7 1926 case IO_ERR_ISR: /* interrupt */
ashleymills 0:e979170e02e7 1927 /* see if we got our timeout */
ashleymills 0:e979170e02e7 1928 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 1929 if (ssl->toInfoOn) {
ashleymills 0:e979170e02e7 1930 struct itimerval timeout;
ashleymills 0:e979170e02e7 1931 getitimer(ITIMER_REAL, &timeout);
ashleymills 0:e979170e02e7 1932 if (timeout.it_value.tv_sec == 0 &&
ashleymills 0:e979170e02e7 1933 timeout.it_value.tv_usec == 0) {
ashleymills 0:e979170e02e7 1934 XSTRNCPY(ssl->timeoutInfo.timeoutName,
ashleymills 0:e979170e02e7 1935 "recv() timeout", MAX_TIMEOUT_NAME_SZ);
ashleymills 0:e979170e02e7 1936 CYASSL_MSG("Got our timeout");
ashleymills 0:e979170e02e7 1937 return WANT_READ;
ashleymills 0:e979170e02e7 1938 }
ashleymills 0:e979170e02e7 1939 }
ashleymills 0:e979170e02e7 1940 #endif
ashleymills 0:e979170e02e7 1941 goto retry;
ashleymills 0:e979170e02e7 1942
ashleymills 0:e979170e02e7 1943 case IO_ERR_CONN_CLOSE: /* peer closed connection */
ashleymills 0:e979170e02e7 1944 ssl->options.isClosed = 1;
ashleymills 0:e979170e02e7 1945 return -1;
ashleymills 0:e979170e02e7 1946
ashleymills 0:e979170e02e7 1947 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 1948 case IO_ERR_TIMEOUT:
ashleymills 0:e979170e02e7 1949 if (DtlsPoolTimeout(ssl) == 0 && DtlsPoolSend(ssl) == 0)
ashleymills 0:e979170e02e7 1950 goto retry;
ashleymills 0:e979170e02e7 1951 else
ashleymills 0:e979170e02e7 1952 return -1;
ashleymills 0:e979170e02e7 1953 #endif
ashleymills 0:e979170e02e7 1954
ashleymills 0:e979170e02e7 1955 default:
ashleymills 0:e979170e02e7 1956 return recvd;
ashleymills 0:e979170e02e7 1957 }
ashleymills 0:e979170e02e7 1958
ashleymills 0:e979170e02e7 1959 return recvd;
ashleymills 0:e979170e02e7 1960 }
ashleymills 0:e979170e02e7 1961
ashleymills 0:e979170e02e7 1962
ashleymills 0:e979170e02e7 1963 /* Switch dynamic output buffer back to static, buffer is assumed clear */
ashleymills 0:e979170e02e7 1964 void ShrinkOutputBuffer(CYASSL* ssl)
ashleymills 0:e979170e02e7 1965 {
ashleymills 0:e979170e02e7 1966 CYASSL_MSG("Shrinking output buffer\n");
ashleymills 0:e979170e02e7 1967 XFREE(ssl->buffers.outputBuffer.buffer, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
ashleymills 0:e979170e02e7 1968 ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
ashleymills 0:e979170e02e7 1969 ssl->buffers.outputBuffer.bufferSize = STATIC_BUFFER_LEN;
ashleymills 0:e979170e02e7 1970 ssl->buffers.outputBuffer.dynamicFlag = 0;
ashleymills 0:e979170e02e7 1971 }
ashleymills 0:e979170e02e7 1972
ashleymills 0:e979170e02e7 1973
ashleymills 0:e979170e02e7 1974 /* Switch dynamic input buffer back to static, keep any remaining input */
ashleymills 0:e979170e02e7 1975 /* forced free means cleaning up */
ashleymills 0:e979170e02e7 1976 void ShrinkInputBuffer(CYASSL* ssl, int forcedFree)
ashleymills 0:e979170e02e7 1977 {
ashleymills 0:e979170e02e7 1978 int usedLength = ssl->buffers.inputBuffer.length -
ashleymills 0:e979170e02e7 1979 ssl->buffers.inputBuffer.idx;
ashleymills 0:e979170e02e7 1980 if (!forcedFree && usedLength > STATIC_BUFFER_LEN)
ashleymills 0:e979170e02e7 1981 return;
ashleymills 0:e979170e02e7 1982
ashleymills 0:e979170e02e7 1983 CYASSL_MSG("Shrinking input buffer\n");
ashleymills 0:e979170e02e7 1984
ashleymills 0:e979170e02e7 1985 if (!forcedFree && usedLength)
ashleymills 0:e979170e02e7 1986 XMEMCPY(ssl->buffers.inputBuffer.staticBuffer,
ashleymills 0:e979170e02e7 1987 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
ashleymills 0:e979170e02e7 1988 usedLength);
ashleymills 0:e979170e02e7 1989
ashleymills 0:e979170e02e7 1990 XFREE(ssl->buffers.inputBuffer.buffer, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
ashleymills 0:e979170e02e7 1991 ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
ashleymills 0:e979170e02e7 1992 ssl->buffers.inputBuffer.bufferSize = STATIC_BUFFER_LEN;
ashleymills 0:e979170e02e7 1993 ssl->buffers.inputBuffer.dynamicFlag = 0;
ashleymills 0:e979170e02e7 1994 ssl->buffers.inputBuffer.idx = 0;
ashleymills 0:e979170e02e7 1995 ssl->buffers.inputBuffer.length = usedLength;
ashleymills 0:e979170e02e7 1996 }
ashleymills 0:e979170e02e7 1997
ashleymills 0:e979170e02e7 1998
ashleymills 0:e979170e02e7 1999 int SendBuffered(CYASSL* ssl)
ashleymills 0:e979170e02e7 2000 {
ashleymills 0:e979170e02e7 2001
ashleymills 0:e979170e02e7 2002 CYASSL_MSG("sending buffered");
ashleymills 0:e979170e02e7 2003 while (ssl->buffers.outputBuffer.length > 0) {
ashleymills 0:e979170e02e7 2004 CYASSL_MSG("really sending: ");
ashleymills 0:e979170e02e7 2005
ashleymills 0:e979170e02e7 2006 int sent = ssl->ctx->CBIOSend(ssl,
ashleymills 0:e979170e02e7 2007 (char*)ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 2008 ssl->buffers.outputBuffer.idx,
ashleymills 0:e979170e02e7 2009 (int)ssl->buffers.outputBuffer.length,
ashleymills 0:e979170e02e7 2010 ssl->IOCB_WriteCtx);
ashleymills 0:e979170e02e7 2011 CYASSL_MSG("donka");
ashleymills 0:e979170e02e7 2012 if (sent < 0) {
ashleymills 0:e979170e02e7 2013 switch (sent) {
ashleymills 0:e979170e02e7 2014
ashleymills 0:e979170e02e7 2015 case IO_ERR_WANT_WRITE: /* would block */
ashleymills 0:e979170e02e7 2016 return WANT_WRITE;
ashleymills 0:e979170e02e7 2017
ashleymills 0:e979170e02e7 2018 case IO_ERR_CONN_RST: /* connection reset */
ashleymills 0:e979170e02e7 2019 ssl->options.connReset = 1;
ashleymills 0:e979170e02e7 2020 break;
ashleymills 0:e979170e02e7 2021
ashleymills 0:e979170e02e7 2022 case IO_ERR_ISR: /* interrupt */
ashleymills 0:e979170e02e7 2023 /* see if we got our timeout */
ashleymills 0:e979170e02e7 2024 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 2025 if (ssl->toInfoOn) {
ashleymills 0:e979170e02e7 2026 struct itimerval timeout;
ashleymills 0:e979170e02e7 2027 getitimer(ITIMER_REAL, &timeout);
ashleymills 0:e979170e02e7 2028 if (timeout.it_value.tv_sec == 0 &&
ashleymills 0:e979170e02e7 2029 timeout.it_value.tv_usec == 0) {
ashleymills 0:e979170e02e7 2030 XSTRNCPY(ssl->timeoutInfo.timeoutName,
ashleymills 0:e979170e02e7 2031 "send() timeout", MAX_TIMEOUT_NAME_SZ);
ashleymills 0:e979170e02e7 2032 CYASSL_MSG("Got our timeout");
ashleymills 0:e979170e02e7 2033 return WANT_WRITE;
ashleymills 0:e979170e02e7 2034 }
ashleymills 0:e979170e02e7 2035 }
ashleymills 0:e979170e02e7 2036 #endif
ashleymills 0:e979170e02e7 2037 continue;
ashleymills 0:e979170e02e7 2038
ashleymills 0:e979170e02e7 2039 case IO_ERR_CONN_CLOSE: /* epipe / conn closed, same as reset */
ashleymills 0:e979170e02e7 2040 ssl->options.connReset = 1;
ashleymills 0:e979170e02e7 2041 break;
ashleymills 0:e979170e02e7 2042
ashleymills 0:e979170e02e7 2043 default:
ashleymills 0:e979170e02e7 2044 return SOCKET_ERROR_E;
ashleymills 0:e979170e02e7 2045 }
ashleymills 0:e979170e02e7 2046
ashleymills 0:e979170e02e7 2047 return SOCKET_ERROR_E;
ashleymills 0:e979170e02e7 2048 }
ashleymills 0:e979170e02e7 2049
ashleymills 0:e979170e02e7 2050 ssl->buffers.outputBuffer.idx += sent;
ashleymills 0:e979170e02e7 2051 ssl->buffers.outputBuffer.length -= sent;
ashleymills 0:e979170e02e7 2052 }
ashleymills 0:e979170e02e7 2053
ashleymills 0:e979170e02e7 2054 ssl->buffers.outputBuffer.idx = 0;
ashleymills 0:e979170e02e7 2055
ashleymills 0:e979170e02e7 2056 if (ssl->buffers.outputBuffer.dynamicFlag)
ashleymills 0:e979170e02e7 2057 ShrinkOutputBuffer(ssl);
ashleymills 0:e979170e02e7 2058
ashleymills 0:e979170e02e7 2059 return 0;
ashleymills 0:e979170e02e7 2060 }
ashleymills 0:e979170e02e7 2061
ashleymills 0:e979170e02e7 2062
ashleymills 0:e979170e02e7 2063 /* Grow the output buffer */
ashleymills 0:e979170e02e7 2064 static INLINE int GrowOutputBuffer(CYASSL* ssl, int size)
ashleymills 0:e979170e02e7 2065 {
ashleymills 0:e979170e02e7 2066 byte* tmp = (byte*) XMALLOC(size + ssl->buffers.outputBuffer.length,
ashleymills 0:e979170e02e7 2067 ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
ashleymills 0:e979170e02e7 2068 CYASSL_MSG("growing output buffer");
ashleymills 0:e979170e02e7 2069
ashleymills 0:e979170e02e7 2070 if (!tmp) {
ashleymills 0:e979170e02e7 2071 CYASSL_MSG("Memory allocation failed");
ashleymills 0:e979170e02e7 2072 return MEMORY_E;
ashleymills 0:e979170e02e7 2073 }
ashleymills 0:e979170e02e7 2074
ashleymills 0:e979170e02e7 2075
ashleymills 0:e979170e02e7 2076 if (ssl->buffers.outputBuffer.length)
ashleymills 0:e979170e02e7 2077 XMEMCPY(tmp, ssl->buffers.outputBuffer.buffer,
ashleymills 0:e979170e02e7 2078 ssl->buffers.outputBuffer.length);
ashleymills 0:e979170e02e7 2079
ashleymills 0:e979170e02e7 2080 if (ssl->buffers.outputBuffer.dynamicFlag)
ashleymills 0:e979170e02e7 2081 XFREE(ssl->buffers.outputBuffer.buffer, ssl->heap,
ashleymills 0:e979170e02e7 2082 DYNAMIC_TYPE_OUT_BUFFER);
ashleymills 0:e979170e02e7 2083 ssl->buffers.outputBuffer.dynamicFlag = 1;
ashleymills 0:e979170e02e7 2084 ssl->buffers.outputBuffer.buffer = tmp;
ashleymills 0:e979170e02e7 2085 ssl->buffers.outputBuffer.bufferSize = size +
ashleymills 0:e979170e02e7 2086 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 2087
ashleymills 0:e979170e02e7 2088 return 0;
ashleymills 0:e979170e02e7 2089 }
ashleymills 0:e979170e02e7 2090
ashleymills 0:e979170e02e7 2091
ashleymills 0:e979170e02e7 2092 /* Grow the input buffer, should only be to read cert or big app data */
ashleymills 0:e979170e02e7 2093 int GrowInputBuffer(CYASSL* ssl, int size, int usedLength)
ashleymills 0:e979170e02e7 2094 {
ashleymills 0:e979170e02e7 2095 byte* tmp = (byte*) XMALLOC(size + usedLength, ssl->heap,
ashleymills 0:e979170e02e7 2096 DYNAMIC_TYPE_IN_BUFFER);
ashleymills 0:e979170e02e7 2097 CYASSL_MSG("growing input buffer\n");
ashleymills 0:e979170e02e7 2098
ashleymills 0:e979170e02e7 2099 if (!tmp) return MEMORY_E;
ashleymills 0:e979170e02e7 2100
ashleymills 0:e979170e02e7 2101 if (usedLength)
ashleymills 0:e979170e02e7 2102 XMEMCPY(tmp, ssl->buffers.inputBuffer.buffer +
ashleymills 0:e979170e02e7 2103 ssl->buffers.inputBuffer.idx, usedLength);
ashleymills 0:e979170e02e7 2104
ashleymills 0:e979170e02e7 2105 if (ssl->buffers.inputBuffer.dynamicFlag)
ashleymills 0:e979170e02e7 2106 XFREE(ssl->buffers.inputBuffer.buffer,ssl->heap,DYNAMIC_TYPE_IN_BUFFER);
ashleymills 0:e979170e02e7 2107
ashleymills 0:e979170e02e7 2108 ssl->buffers.inputBuffer.dynamicFlag = 1;
ashleymills 0:e979170e02e7 2109 ssl->buffers.inputBuffer.buffer = tmp;
ashleymills 0:e979170e02e7 2110 ssl->buffers.inputBuffer.bufferSize = size + usedLength;
ashleymills 0:e979170e02e7 2111 ssl->buffers.inputBuffer.idx = 0;
ashleymills 0:e979170e02e7 2112 ssl->buffers.inputBuffer.length = usedLength;
ashleymills 0:e979170e02e7 2113
ashleymills 0:e979170e02e7 2114 return 0;
ashleymills 0:e979170e02e7 2115 }
ashleymills 0:e979170e02e7 2116
ashleymills 0:e979170e02e7 2117
ashleymills 0:e979170e02e7 2118 /* check avalaible size into output buffer, make room if needed */
ashleymills 0:e979170e02e7 2119 int CheckAvalaibleSize(CYASSL *ssl, int size)
ashleymills 0:e979170e02e7 2120 {
ashleymills 0:e979170e02e7 2121 if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length
ashleymills 0:e979170e02e7 2122 < (word32)size) {
ashleymills 0:e979170e02e7 2123 if (GrowOutputBuffer(ssl, size) < 0)
ashleymills 0:e979170e02e7 2124 return MEMORY_E;
ashleymills 0:e979170e02e7 2125 }
ashleymills 0:e979170e02e7 2126
ashleymills 0:e979170e02e7 2127 return 0;
ashleymills 0:e979170e02e7 2128 }
ashleymills 0:e979170e02e7 2129
ashleymills 0:e979170e02e7 2130
ashleymills 0:e979170e02e7 2131 /* do all verify and sanity checks on record header */
ashleymills 0:e979170e02e7 2132 static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
ashleymills 0:e979170e02e7 2133 RecordLayerHeader* rh, word16 *size)
ashleymills 0:e979170e02e7 2134 {
ashleymills 0:e979170e02e7 2135 if (!ssl->options.dtls) {
ashleymills 0:e979170e02e7 2136 XMEMCPY(rh, input + *inOutIdx, RECORD_HEADER_SZ);
ashleymills 0:e979170e02e7 2137 *inOutIdx += RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 2138 ato16(rh->length, size);
ashleymills 0:e979170e02e7 2139 }
ashleymills 0:e979170e02e7 2140 else {
ashleymills 0:e979170e02e7 2141 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 2142 /* type and version in same sport */
ashleymills 0:e979170e02e7 2143 XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
ashleymills 0:e979170e02e7 2144 *inOutIdx += ENUM_LEN + VERSION_SZ;
ashleymills 0:e979170e02e7 2145 ato16(input + *inOutIdx, &ssl->keys.dtls_peer_epoch);
ashleymills 0:e979170e02e7 2146 *inOutIdx += 4; /* advance past epoch, skip first 2 seq bytes for now */
ashleymills 0:e979170e02e7 2147 ato32(input + *inOutIdx, &ssl->keys.dtls_peer_sequence_number);
ashleymills 0:e979170e02e7 2148 *inOutIdx += 4; /* advance past rest of seq */
ashleymills 0:e979170e02e7 2149 ato16(input + *inOutIdx, size);
ashleymills 0:e979170e02e7 2150 *inOutIdx += LENGTH_SZ;
ashleymills 0:e979170e02e7 2151 #endif
ashleymills 0:e979170e02e7 2152 }
ashleymills 0:e979170e02e7 2153
ashleymills 0:e979170e02e7 2154 /* catch version mismatch */
ashleymills 0:e979170e02e7 2155 if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor){
ashleymills 0:e979170e02e7 2156 if (ssl->options.side == SERVER_END &&
ashleymills 0:e979170e02e7 2157 ssl->options.acceptState == ACCEPT_BEGIN)
ashleymills 0:e979170e02e7 2158 CYASSL_MSG("Client attempting to connect with different version");
ashleymills 0:e979170e02e7 2159 else if (ssl->options.side == CLIENT_END && ssl->options.downgrade &&
ashleymills 0:e979170e02e7 2160 ssl->options.connectState < FIRST_REPLY_DONE)
ashleymills 0:e979170e02e7 2161 CYASSL_MSG("Server attempting to accept with different version");
ashleymills 0:e979170e02e7 2162 else {
ashleymills 0:e979170e02e7 2163 CYASSL_MSG("SSL version error");
ashleymills 0:e979170e02e7 2164 return VERSION_ERROR; /* only use requested version */
ashleymills 0:e979170e02e7 2165 }
ashleymills 0:e979170e02e7 2166 }
ashleymills 0:e979170e02e7 2167
ashleymills 0:e979170e02e7 2168 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 2169 /* If DTLS, check the sequence number against expected. If out of
ashleymills 0:e979170e02e7 2170 * order, drop the record. Allows newer records in and resets the
ashleymills 0:e979170e02e7 2171 * expected to the next record. */
ashleymills 0:e979170e02e7 2172 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 2173 if ((ssl->keys.dtls_expected_peer_epoch ==
ashleymills 0:e979170e02e7 2174 ssl->keys.dtls_peer_epoch) &&
ashleymills 0:e979170e02e7 2175 (ssl->keys.dtls_peer_sequence_number >=
ashleymills 0:e979170e02e7 2176 ssl->keys.dtls_expected_peer_sequence_number)) {
ashleymills 0:e979170e02e7 2177 ssl->keys.dtls_expected_peer_sequence_number =
ashleymills 0:e979170e02e7 2178 ssl->keys.dtls_peer_sequence_number + 1;
ashleymills 0:e979170e02e7 2179 }
ashleymills 0:e979170e02e7 2180 else {
ashleymills 0:e979170e02e7 2181 return SEQUENCE_ERROR;
ashleymills 0:e979170e02e7 2182 }
ashleymills 0:e979170e02e7 2183 }
ashleymills 0:e979170e02e7 2184 #endif
ashleymills 0:e979170e02e7 2185
ashleymills 0:e979170e02e7 2186 /* record layer length check */
ashleymills 0:e979170e02e7 2187 if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
ashleymills 0:e979170e02e7 2188 return LENGTH_ERROR;
ashleymills 0:e979170e02e7 2189
ashleymills 0:e979170e02e7 2190 /* verify record type here as well */
ashleymills 0:e979170e02e7 2191 switch ((enum ContentType)rh->type) {
ashleymills 0:e979170e02e7 2192 case handshake:
ashleymills 0:e979170e02e7 2193 case change_cipher_spec:
ashleymills 0:e979170e02e7 2194 case application_data:
ashleymills 0:e979170e02e7 2195 case alert:
ashleymills 0:e979170e02e7 2196 break;
ashleymills 0:e979170e02e7 2197 case no_type:
ashleymills 0:e979170e02e7 2198 default:
ashleymills 0:e979170e02e7 2199 CYASSL_MSG("Unknown Record Type");
ashleymills 0:e979170e02e7 2200 return UNKNOWN_RECORD_TYPE;
ashleymills 0:e979170e02e7 2201 }
ashleymills 0:e979170e02e7 2202
ashleymills 0:e979170e02e7 2203 /* haven't decrypted this record yet */
ashleymills 0:e979170e02e7 2204 ssl->keys.decryptedCur = 0;
ashleymills 0:e979170e02e7 2205
ashleymills 0:e979170e02e7 2206 return 0;
ashleymills 0:e979170e02e7 2207 }
ashleymills 0:e979170e02e7 2208
ashleymills 0:e979170e02e7 2209
ashleymills 0:e979170e02e7 2210 static int GetHandShakeHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
ashleymills 0:e979170e02e7 2211 byte *type, word32 *size)
ashleymills 0:e979170e02e7 2212 {
ashleymills 0:e979170e02e7 2213 const byte *ptr = input + *inOutIdx;
ashleymills 0:e979170e02e7 2214 (void)ssl;
ashleymills 0:e979170e02e7 2215 *inOutIdx += HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 2216
ashleymills 0:e979170e02e7 2217 *type = ptr[0];
ashleymills 0:e979170e02e7 2218 c24to32(&ptr[1], size);
ashleymills 0:e979170e02e7 2219
ashleymills 0:e979170e02e7 2220 return 0;
ashleymills 0:e979170e02e7 2221 }
ashleymills 0:e979170e02e7 2222
ashleymills 0:e979170e02e7 2223
ashleymills 0:e979170e02e7 2224 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 2225 static int GetDtlsHandShakeHeader(CYASSL* ssl, const byte* input,
ashleymills 0:e979170e02e7 2226 word32* inOutIdx, byte *type, word32 *size,
ashleymills 0:e979170e02e7 2227 word32 *fragOffset, word32 *fragSz)
ashleymills 0:e979170e02e7 2228 {
ashleymills 0:e979170e02e7 2229 word32 idx = *inOutIdx;
ashleymills 0:e979170e02e7 2230
ashleymills 0:e979170e02e7 2231 *inOutIdx += HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 2232
ashleymills 0:e979170e02e7 2233 *type = input[idx++];
ashleymills 0:e979170e02e7 2234 c24to32(input + idx, size);
ashleymills 0:e979170e02e7 2235 idx += BYTE3_LEN;
ashleymills 0:e979170e02e7 2236
ashleymills 0:e979170e02e7 2237 ato16(input + idx, &ssl->keys.dtls_peer_handshake_number);
ashleymills 0:e979170e02e7 2238 idx += DTLS_HANDSHAKE_SEQ_SZ;
ashleymills 0:e979170e02e7 2239
ashleymills 0:e979170e02e7 2240 c24to32(input + idx, fragOffset);
ashleymills 0:e979170e02e7 2241 idx += DTLS_HANDSHAKE_FRAG_SZ;
ashleymills 0:e979170e02e7 2242 c24to32(input + idx, fragSz);
ashleymills 0:e979170e02e7 2243 idx += DTLS_HANDSHAKE_FRAG_SZ;
ashleymills 0:e979170e02e7 2244
ashleymills 0:e979170e02e7 2245 return 0;
ashleymills 0:e979170e02e7 2246 }
ashleymills 0:e979170e02e7 2247 #endif
ashleymills 0:e979170e02e7 2248
ashleymills 0:e979170e02e7 2249
ashleymills 0:e979170e02e7 2250 #ifndef NO_MD5
ashleymills 0:e979170e02e7 2251 /* fill with MD5 pad size since biggest required */
ashleymills 0:e979170e02e7 2252 static const byte PAD1[PAD_MD5] =
ashleymills 0:e979170e02e7 2253 { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
ashleymills 0:e979170e02e7 2254 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
ashleymills 0:e979170e02e7 2255 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
ashleymills 0:e979170e02e7 2256 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
ashleymills 0:e979170e02e7 2257 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
ashleymills 0:e979170e02e7 2258 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
ashleymills 0:e979170e02e7 2259 };
ashleymills 0:e979170e02e7 2260 static const byte PAD2[PAD_MD5] =
ashleymills 0:e979170e02e7 2261 { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
ashleymills 0:e979170e02e7 2262 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
ashleymills 0:e979170e02e7 2263 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
ashleymills 0:e979170e02e7 2264 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
ashleymills 0:e979170e02e7 2265 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
ashleymills 0:e979170e02e7 2266 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
ashleymills 0:e979170e02e7 2267 };
ashleymills 0:e979170e02e7 2268
ashleymills 0:e979170e02e7 2269 /* calculate MD5 hash for finished */
ashleymills 0:e979170e02e7 2270 static void BuildMD5(CYASSL* ssl, Hashes* hashes, const byte* sender)
ashleymills 0:e979170e02e7 2271 {
ashleymills 0:e979170e02e7 2272 byte md5_result[MD5_DIGEST_SIZE];
ashleymills 0:e979170e02e7 2273
ashleymills 0:e979170e02e7 2274 /* make md5 inner */
ashleymills 0:e979170e02e7 2275 Md5Update(&ssl->hashMd5, sender, SIZEOF_SENDER);
ashleymills 0:e979170e02e7 2276 Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:e979170e02e7 2277 Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
ashleymills 0:e979170e02e7 2278 Md5Final(&ssl->hashMd5, md5_result);
ashleymills 0:e979170e02e7 2279
ashleymills 0:e979170e02e7 2280 /* make md5 outer */
ashleymills 0:e979170e02e7 2281 Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:e979170e02e7 2282 Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
ashleymills 0:e979170e02e7 2283 Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
ashleymills 0:e979170e02e7 2284
ashleymills 0:e979170e02e7 2285 Md5Final(&ssl->hashMd5, hashes->md5);
ashleymills 0:e979170e02e7 2286 }
ashleymills 0:e979170e02e7 2287
ashleymills 0:e979170e02e7 2288
ashleymills 0:e979170e02e7 2289 /* calculate SHA hash for finished */
ashleymills 0:e979170e02e7 2290 static void BuildSHA(CYASSL* ssl, Hashes* hashes, const byte* sender)
ashleymills 0:e979170e02e7 2291 {
ashleymills 0:e979170e02e7 2292 byte sha_result[SHA_DIGEST_SIZE];
ashleymills 0:e979170e02e7 2293
ashleymills 0:e979170e02e7 2294 /* make sha inner */
ashleymills 0:e979170e02e7 2295 ShaUpdate(&ssl->hashSha, sender, SIZEOF_SENDER);
ashleymills 0:e979170e02e7 2296 ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:e979170e02e7 2297 ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
ashleymills 0:e979170e02e7 2298 ShaFinal(&ssl->hashSha, sha_result);
ashleymills 0:e979170e02e7 2299
ashleymills 0:e979170e02e7 2300 /* make sha outer */
ashleymills 0:e979170e02e7 2301 ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:e979170e02e7 2302 ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
ashleymills 0:e979170e02e7 2303 ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
ashleymills 0:e979170e02e7 2304
ashleymills 0:e979170e02e7 2305 ShaFinal(&ssl->hashSha, hashes->sha);
ashleymills 0:e979170e02e7 2306 }
ashleymills 0:e979170e02e7 2307 #endif
ashleymills 0:e979170e02e7 2308
ashleymills 0:e979170e02e7 2309
ashleymills 0:e979170e02e7 2310 static void BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
ashleymills 0:e979170e02e7 2311 {
ashleymills 0:e979170e02e7 2312 /* store current states, building requires get_digest which resets state */
ashleymills 0:e979170e02e7 2313 #ifndef NO_MD5
ashleymills 0:e979170e02e7 2314 Md5 md5 = ssl->hashMd5;
ashleymills 0:e979170e02e7 2315 #endif
ashleymills 0:e979170e02e7 2316 Sha sha = ssl->hashSha;
ashleymills 0:e979170e02e7 2317 #ifndef NO_SHA256
ashleymills 0:e979170e02e7 2318 Sha256 sha256;
ashleymills 0:e979170e02e7 2319 #endif
ashleymills 0:e979170e02e7 2320 #ifdef CYASSL_SHA384
ashleymills 0:e979170e02e7 2321 Sha384 sha384;
ashleymills 0:e979170e02e7 2322 #endif
ashleymills 0:e979170e02e7 2323
ashleymills 0:e979170e02e7 2324 #ifndef NO_SHA256
ashleymills 0:e979170e02e7 2325 InitSha256(&sha256);
ashleymills 0:e979170e02e7 2326 if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:e979170e02e7 2327 sha256 = ssl->hashSha256;
ashleymills 0:e979170e02e7 2328 #endif
ashleymills 0:e979170e02e7 2329 #ifdef CYASSL_SHA384
ashleymills 0:e979170e02e7 2330 InitSha384(&sha384);
ashleymills 0:e979170e02e7 2331 if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:e979170e02e7 2332 sha384 = ssl->hashSha384;
ashleymills 0:e979170e02e7 2333 #endif
ashleymills 0:e979170e02e7 2334
ashleymills 0:e979170e02e7 2335 if (ssl->options.tls)
ashleymills 0:e979170e02e7 2336 BuildTlsFinished(ssl, hashes, sender);
ashleymills 0:e979170e02e7 2337 #ifndef NO_MD5
ashleymills 0:e979170e02e7 2338 else {
ashleymills 0:e979170e02e7 2339 BuildMD5(ssl, hashes, sender);
ashleymills 0:e979170e02e7 2340 BuildSHA(ssl, hashes, sender);
ashleymills 0:e979170e02e7 2341 }
ashleymills 0:e979170e02e7 2342 #endif
ashleymills 0:e979170e02e7 2343
ashleymills 0:e979170e02e7 2344 /* restore */
ashleymills 0:e979170e02e7 2345 #ifndef NO_MD5
ashleymills 0:e979170e02e7 2346 ssl->hashMd5 = md5;
ashleymills 0:e979170e02e7 2347 #endif
ashleymills 0:e979170e02e7 2348 ssl->hashSha = sha;
ashleymills 0:e979170e02e7 2349 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:e979170e02e7 2350 #ifndef NO_SHA256
ashleymills 0:e979170e02e7 2351 ssl->hashSha256 = sha256;
ashleymills 0:e979170e02e7 2352 #endif
ashleymills 0:e979170e02e7 2353 #ifdef CYASSL_SHA384
ashleymills 0:e979170e02e7 2354 ssl->hashSha384 = sha384;
ashleymills 0:e979170e02e7 2355 #endif
ashleymills 0:e979170e02e7 2356 }
ashleymills 0:e979170e02e7 2357 }
ashleymills 0:e979170e02e7 2358
ashleymills 0:e979170e02e7 2359
ashleymills 0:e979170e02e7 2360 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 2361
ashleymills 0:e979170e02e7 2362 static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
ashleymills 0:e979170e02e7 2363 {
ashleymills 0:e979170e02e7 2364 word32 listSz, i = *inOutIdx;
ashleymills 0:e979170e02e7 2365 int ret = 0;
ashleymills 0:e979170e02e7 2366 int anyError = 0;
ashleymills 0:e979170e02e7 2367 int totalCerts = 0; /* number of certs in certs buffer */
ashleymills 0:e979170e02e7 2368 int count;
ashleymills 0:e979170e02e7 2369 char domain[ASN_NAME_MAX];
ashleymills 0:e979170e02e7 2370 buffer certs[MAX_CHAIN_DEPTH];
ashleymills 0:e979170e02e7 2371
ashleymills 0:e979170e02e7 2372 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 2373 if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 2374 if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo);
ashleymills 0:e979170e02e7 2375 #endif
ashleymills 0:e979170e02e7 2376 c24to32(&input[i], &listSz);
ashleymills 0:e979170e02e7 2377 i += CERT_HEADER_SZ;
ashleymills 0:e979170e02e7 2378
ashleymills 0:e979170e02e7 2379 CYASSL_MSG("Loading peer's cert chain");
ashleymills 0:e979170e02e7 2380 /* first put cert chain into buffer so can verify top down
ashleymills 0:e979170e02e7 2381 we're sent bottom up */
ashleymills 0:e979170e02e7 2382 while (listSz) {
ashleymills 0:e979170e02e7 2383 /* cert size */
ashleymills 0:e979170e02e7 2384 word32 certSz;
ashleymills 0:e979170e02e7 2385
ashleymills 0:e979170e02e7 2386 if (totalCerts >= MAX_CHAIN_DEPTH)
ashleymills 0:e979170e02e7 2387 return MAX_CHAIN_ERROR;
ashleymills 0:e979170e02e7 2388
ashleymills 0:e979170e02e7 2389 c24to32(&input[i], &certSz);
ashleymills 0:e979170e02e7 2390 i += CERT_HEADER_SZ;
ashleymills 0:e979170e02e7 2391
ashleymills 0:e979170e02e7 2392 if (listSz > MAX_RECORD_SIZE || certSz > MAX_RECORD_SIZE)
ashleymills 0:e979170e02e7 2393 return BUFFER_E;
ashleymills 0:e979170e02e7 2394
ashleymills 0:e979170e02e7 2395 certs[totalCerts].length = certSz;
ashleymills 0:e979170e02e7 2396 certs[totalCerts].buffer = input + i;
ashleymills 0:e979170e02e7 2397
ashleymills 0:e979170e02e7 2398 #ifdef SESSION_CERTS
ashleymills 0:e979170e02e7 2399 if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
ashleymills 0:e979170e02e7 2400 certSz < MAX_X509_SIZE) {
ashleymills 0:e979170e02e7 2401 ssl->session.chain.certs[ssl->session.chain.count].length = certSz;
ashleymills 0:e979170e02e7 2402 XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer,
ashleymills 0:e979170e02e7 2403 input + i, certSz);
ashleymills 0:e979170e02e7 2404 ssl->session.chain.count++;
ashleymills 0:e979170e02e7 2405 } else {
ashleymills 0:e979170e02e7 2406 CYASSL_MSG("Couldn't store chain cert for session");
ashleymills 0:e979170e02e7 2407 }
ashleymills 0:e979170e02e7 2408 #endif
ashleymills 0:e979170e02e7 2409
ashleymills 0:e979170e02e7 2410 i += certSz;
ashleymills 0:e979170e02e7 2411 listSz -= certSz + CERT_HEADER_SZ;
ashleymills 0:e979170e02e7 2412
ashleymills 0:e979170e02e7 2413 totalCerts++;
ashleymills 0:e979170e02e7 2414 CYASSL_MSG(" Put another cert into chain");
ashleymills 0:e979170e02e7 2415 }
ashleymills 0:e979170e02e7 2416
ashleymills 0:e979170e02e7 2417 count = totalCerts;
ashleymills 0:e979170e02e7 2418
ashleymills 0:e979170e02e7 2419 /* verify up to peer's first */
ashleymills 0:e979170e02e7 2420 while (count > 1) {
ashleymills 0:e979170e02e7 2421 buffer myCert = certs[count - 1];
ashleymills 0:e979170e02e7 2422 DecodedCert dCert;
ashleymills 0:e979170e02e7 2423
ashleymills 0:e979170e02e7 2424 InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
ashleymills 0:e979170e02e7 2425 ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
ashleymills 0:e979170e02e7 2426 ssl->ctx->cm);
ashleymills 0:e979170e02e7 2427 if (ret == 0 && dCert.isCA == 0) {
ashleymills 0:e979170e02e7 2428 CYASSL_MSG("Chain cert is not a CA, not adding as one");
ashleymills 0:e979170e02e7 2429 }
ashleymills 0:e979170e02e7 2430 else if (ret == 0 && ssl->options.verifyNone) {
ashleymills 0:e979170e02e7 2431 CYASSL_MSG("Chain cert not verified by option, not adding as CA");
ashleymills 0:e979170e02e7 2432 }
ashleymills 0:e979170e02e7 2433 else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, dCert.subjectHash)) {
ashleymills 0:e979170e02e7 2434 buffer add;
ashleymills 0:e979170e02e7 2435 add.length = myCert.length;
ashleymills 0:e979170e02e7 2436 add.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
ashleymills 0:e979170e02e7 2437 DYNAMIC_TYPE_CA);
ashleymills 0:e979170e02e7 2438 CYASSL_MSG("Adding CA from chain");
ashleymills 0:e979170e02e7 2439
ashleymills 0:e979170e02e7 2440 if (add.buffer == NULL)
ashleymills 0:e979170e02e7 2441 return MEMORY_E;
ashleymills 0:e979170e02e7 2442 XMEMCPY(add.buffer, myCert.buffer, myCert.length);
ashleymills 0:e979170e02e7 2443
ashleymills 0:e979170e02e7 2444 ret = AddCA(ssl->ctx->cm, add, CYASSL_CHAIN_CA,
ashleymills 0:e979170e02e7 2445 ssl->ctx->verifyPeer);
ashleymills 0:e979170e02e7 2446 if (ret == 1) ret = 0; /* SSL_SUCCESS for external */
ashleymills 0:e979170e02e7 2447 }
ashleymills 0:e979170e02e7 2448 else if (ret != 0) {
ashleymills 0:e979170e02e7 2449 CYASSL_MSG("Failed to verify CA from chain");
ashleymills 0:e979170e02e7 2450 }
ashleymills 0:e979170e02e7 2451 else {
ashleymills 0:e979170e02e7 2452 CYASSL_MSG("Verified CA from chain and already had it");
ashleymills 0:e979170e02e7 2453 }
ashleymills 0:e979170e02e7 2454
ashleymills 0:e979170e02e7 2455 #ifdef HAVE_CRL
ashleymills 0:e979170e02e7 2456 if (ret == 0 && ssl->ctx->cm->crlEnabled && ssl->ctx->cm->crlCheckAll) {
ashleymills 0:e979170e02e7 2457 CYASSL_MSG("Doing Non Leaf CRL check");
ashleymills 0:e979170e02e7 2458 ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert);
ashleymills 0:e979170e02e7 2459
ashleymills 0:e979170e02e7 2460 if (ret != 0) {
ashleymills 0:e979170e02e7 2461 CYASSL_MSG("\tCRL check not ok");
ashleymills 0:e979170e02e7 2462 }
ashleymills 0:e979170e02e7 2463 }
ashleymills 0:e979170e02e7 2464 #endif /* HAVE_CRL */
ashleymills 0:e979170e02e7 2465
ashleymills 0:e979170e02e7 2466 if (ret != 0 && anyError == 0)
ashleymills 0:e979170e02e7 2467 anyError = ret; /* save error from last time */
ashleymills 0:e979170e02e7 2468
ashleymills 0:e979170e02e7 2469 FreeDecodedCert(&dCert);
ashleymills 0:e979170e02e7 2470 count--;
ashleymills 0:e979170e02e7 2471 }
ashleymills 0:e979170e02e7 2472
ashleymills 0:e979170e02e7 2473 /* peer's, may not have one if blank client cert sent by TLSv1.2 */
ashleymills 0:e979170e02e7 2474 if (count) {
ashleymills 0:e979170e02e7 2475 buffer myCert = certs[0];
ashleymills 0:e979170e02e7 2476 DecodedCert dCert;
ashleymills 0:e979170e02e7 2477 int fatal = 0;
ashleymills 0:e979170e02e7 2478
ashleymills 0:e979170e02e7 2479 CYASSL_MSG("Veriying Peer's cert");
ashleymills 0:e979170e02e7 2480
ashleymills 0:e979170e02e7 2481 InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
ashleymills 0:e979170e02e7 2482 ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
ashleymills 0:e979170e02e7 2483 ssl->ctx->cm);
ashleymills 0:e979170e02e7 2484 if (ret == 0) {
ashleymills 0:e979170e02e7 2485 CYASSL_MSG("Verified Peer's cert");
ashleymills 0:e979170e02e7 2486 fatal = 0;
ashleymills 0:e979170e02e7 2487 }
ashleymills 0:e979170e02e7 2488 else if (ret == ASN_PARSE_E) {
ashleymills 0:e979170e02e7 2489 CYASSL_MSG("Got Peer cert ASN PARSE ERROR, fatal");
ashleymills 0:e979170e02e7 2490 fatal = 1;
ashleymills 0:e979170e02e7 2491 }
ashleymills 0:e979170e02e7 2492 else {
ashleymills 0:e979170e02e7 2493 CYASSL_MSG("Failed to verify Peer's cert");
ashleymills 0:e979170e02e7 2494 if (ssl->verifyCallback) {
ashleymills 0:e979170e02e7 2495 CYASSL_MSG("\tCallback override available, will continue");
ashleymills 0:e979170e02e7 2496 fatal = 0;
ashleymills 0:e979170e02e7 2497 }
ashleymills 0:e979170e02e7 2498 else {
ashleymills 0:e979170e02e7 2499 CYASSL_MSG("\tNo callback override available, fatal");
ashleymills 0:e979170e02e7 2500 fatal = 1;
ashleymills 0:e979170e02e7 2501 }
ashleymills 0:e979170e02e7 2502 }
ashleymills 0:e979170e02e7 2503
ashleymills 0:e979170e02e7 2504 #ifdef HAVE_OCSP
ashleymills 0:e979170e02e7 2505 if (fatal == 0) {
ashleymills 0:e979170e02e7 2506 ret = CyaSSL_OCSP_Lookup_Cert(&ssl->ctx->ocsp, &dCert);
ashleymills 0:e979170e02e7 2507 if (ret != 0) {
ashleymills 0:e979170e02e7 2508 CYASSL_MSG("\tOCSP Lookup not ok");
ashleymills 0:e979170e02e7 2509 fatal = 0;
ashleymills 0:e979170e02e7 2510 }
ashleymills 0:e979170e02e7 2511 }
ashleymills 0:e979170e02e7 2512 #endif
ashleymills 0:e979170e02e7 2513
ashleymills 0:e979170e02e7 2514 #ifdef HAVE_CRL
ashleymills 0:e979170e02e7 2515 if (fatal == 0 && ssl->ctx->cm->crlEnabled) {
ashleymills 0:e979170e02e7 2516 int doCrlLookup = 1;
ashleymills 0:e979170e02e7 2517
ashleymills 0:e979170e02e7 2518 #ifdef HAVE_OCSP
ashleymills 0:e979170e02e7 2519 if (ssl->ctx->ocsp.enabled) {
ashleymills 0:e979170e02e7 2520 doCrlLookup = (ret == OCSP_CERT_UNKNOWN);
ashleymills 0:e979170e02e7 2521 }
ashleymills 0:e979170e02e7 2522 #endif /* HAVE_OCSP */
ashleymills 0:e979170e02e7 2523
ashleymills 0:e979170e02e7 2524 if (doCrlLookup) {
ashleymills 0:e979170e02e7 2525 CYASSL_MSG("Doing Leaf CRL check");
ashleymills 0:e979170e02e7 2526 ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert);
ashleymills 0:e979170e02e7 2527
ashleymills 0:e979170e02e7 2528 if (ret != 0) {
ashleymills 0:e979170e02e7 2529 CYASSL_MSG("\tCRL check not ok");
ashleymills 0:e979170e02e7 2530 fatal = 0;
ashleymills 0:e979170e02e7 2531 }
ashleymills 0:e979170e02e7 2532 }
ashleymills 0:e979170e02e7 2533 }
ashleymills 0:e979170e02e7 2534
ashleymills 0:e979170e02e7 2535 #endif /* HAVE_CRL */
ashleymills 0:e979170e02e7 2536
ashleymills 0:e979170e02e7 2537 #ifdef OPENSSL_EXTRA
ashleymills 0:e979170e02e7 2538 /* set X509 format for peer cert even if fatal */
ashleymills 0:e979170e02e7 2539 XSTRNCPY(ssl->peerCert.issuer.name, dCert.issuer, ASN_NAME_MAX);
ashleymills 0:e979170e02e7 2540 ssl->peerCert.issuer.name[ASN_NAME_MAX - 1] = '\0';
ashleymills 0:e979170e02e7 2541 ssl->peerCert.issuer.sz = (int)XSTRLEN(ssl->peerCert.issuer.name) + 1;
ashleymills 0:e979170e02e7 2542
ashleymills 0:e979170e02e7 2543 XSTRNCPY(ssl->peerCert.subject.name, dCert.subject, ASN_NAME_MAX);
ashleymills 0:e979170e02e7 2544 ssl->peerCert.subject.name[ASN_NAME_MAX - 1] = '\0';
ashleymills 0:e979170e02e7 2545 ssl->peerCert.subject.sz = (int)XSTRLEN(ssl->peerCert.subject.name) + 1;
ashleymills 0:e979170e02e7 2546
ashleymills 0:e979170e02e7 2547 XMEMCPY(ssl->peerCert.serial, dCert.serial, EXTERNAL_SERIAL_SIZE);
ashleymills 0:e979170e02e7 2548 ssl->peerCert.serialSz = dCert.serialSz;
ashleymills 0:e979170e02e7 2549 if (dCert.subjectCNLen < ASN_NAME_MAX) {
ashleymills 0:e979170e02e7 2550 XMEMCPY(ssl->peerCert.subjectCN,dCert.subjectCN,dCert.subjectCNLen);
ashleymills 0:e979170e02e7 2551 ssl->peerCert.subjectCN[dCert.subjectCNLen] = '\0';
ashleymills 0:e979170e02e7 2552 }
ashleymills 0:e979170e02e7 2553 else
ashleymills 0:e979170e02e7 2554 ssl->peerCert.subjectCN[0] = '\0';
ashleymills 0:e979170e02e7 2555
ashleymills 0:e979170e02e7 2556 /* store cert for potential retrieval */
ashleymills 0:e979170e02e7 2557 ssl->peerCert.derCert.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
ashleymills 0:e979170e02e7 2558 DYNAMIC_TYPE_CERT);
ashleymills 0:e979170e02e7 2559 if (ssl->peerCert.derCert.buffer == NULL) {
ashleymills 0:e979170e02e7 2560 ret = MEMORY_E;
ashleymills 0:e979170e02e7 2561 fatal = 1;
ashleymills 0:e979170e02e7 2562 }
ashleymills 0:e979170e02e7 2563 else {
ashleymills 0:e979170e02e7 2564 XMEMCPY(ssl->peerCert.derCert.buffer, myCert.buffer, myCert.length);
ashleymills 0:e979170e02e7 2565 ssl->peerCert.derCert.length = myCert.length;
ashleymills 0:e979170e02e7 2566 }
ashleymills 0:e979170e02e7 2567
ashleymills 0:e979170e02e7 2568 ssl->peerCert.altNames = dCert.altNames;
ashleymills 0:e979170e02e7 2569 dCert.altNames = NULL; /* takes ownership */
ashleymills 0:e979170e02e7 2570 ssl->peerCert.altNamesNext = ssl->peerCert.altNames; /* index hint */
ashleymills 0:e979170e02e7 2571 #endif
ashleymills 0:e979170e02e7 2572
ashleymills 0:e979170e02e7 2573 if (fatal) {
ashleymills 0:e979170e02e7 2574 FreeDecodedCert(&dCert);
ashleymills 0:e979170e02e7 2575 ssl->error = ret;
ashleymills 0:e979170e02e7 2576 return ret;
ashleymills 0:e979170e02e7 2577 }
ashleymills 0:e979170e02e7 2578 ssl->options.havePeerCert = 1;
ashleymills 0:e979170e02e7 2579
ashleymills 0:e979170e02e7 2580 /* store for callback use */
ashleymills 0:e979170e02e7 2581 if (dCert.subjectCNLen < ASN_NAME_MAX) {
ashleymills 0:e979170e02e7 2582 XMEMCPY(domain, dCert.subjectCN, dCert.subjectCNLen);
ashleymills 0:e979170e02e7 2583 domain[dCert.subjectCNLen] = '\0';
ashleymills 0:e979170e02e7 2584 }
ashleymills 0:e979170e02e7 2585 else
ashleymills 0:e979170e02e7 2586 domain[0] = '\0';
ashleymills 0:e979170e02e7 2587
ashleymills 0:e979170e02e7 2588 if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer)
ashleymills 0:e979170e02e7 2589 if (XSTRNCMP((char*)ssl->buffers.domainName.buffer,
ashleymills 0:e979170e02e7 2590 dCert.subjectCN,
ashleymills 0:e979170e02e7 2591 ssl->buffers.domainName.length - 1) != 0) {
ashleymills 0:e979170e02e7 2592 ret = DOMAIN_NAME_MISMATCH; /* try to get peer key still */
ashleymills 0:e979170e02e7 2593 }
ashleymills 0:e979170e02e7 2594
ashleymills 0:e979170e02e7 2595 /* decode peer key */
ashleymills 0:e979170e02e7 2596 switch (dCert.keyOID) {
ashleymills 0:e979170e02e7 2597 #ifndef NO_RSA
ashleymills 0:e979170e02e7 2598 case RSAk:
ashleymills 0:e979170e02e7 2599 {
ashleymills 0:e979170e02e7 2600 word32 idx = 0;
ashleymills 0:e979170e02e7 2601 if (RsaPublicKeyDecode(dCert.publicKey, &idx,
ashleymills 0:e979170e02e7 2602 ssl->peerRsaKey, dCert.pubKeySize) != 0) {
ashleymills 0:e979170e02e7 2603 ret = PEER_KEY_ERROR;
ashleymills 0:e979170e02e7 2604 }
ashleymills 0:e979170e02e7 2605 else
ashleymills 0:e979170e02e7 2606 ssl->peerRsaKeyPresent = 1;
ashleymills 0:e979170e02e7 2607 }
ashleymills 0:e979170e02e7 2608 break;
ashleymills 0:e979170e02e7 2609 #endif /* NO_RSA */
ashleymills 0:e979170e02e7 2610 #ifdef HAVE_NTRU
ashleymills 0:e979170e02e7 2611 case NTRUk:
ashleymills 0:e979170e02e7 2612 {
ashleymills 0:e979170e02e7 2613 if (dCert.pubKeySize > sizeof(ssl->peerNtruKey)) {
ashleymills 0:e979170e02e7 2614 ret = PEER_KEY_ERROR;
ashleymills 0:e979170e02e7 2615 }
ashleymills 0:e979170e02e7 2616 else {
ashleymills 0:e979170e02e7 2617 XMEMCPY(ssl->peerNtruKey, dCert.publicKey, dCert.pubKeySize);
ashleymills 0:e979170e02e7 2618 ssl->peerNtruKeyLen = (word16)dCert.pubKeySize;
ashleymills 0:e979170e02e7 2619 ssl->peerNtruKeyPresent = 1;
ashleymills 0:e979170e02e7 2620 }
ashleymills 0:e979170e02e7 2621 }
ashleymills 0:e979170e02e7 2622 break;
ashleymills 0:e979170e02e7 2623 #endif /* HAVE_NTRU */
ashleymills 0:e979170e02e7 2624 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 2625 case ECDSAk:
ashleymills 0:e979170e02e7 2626 {
ashleymills 0:e979170e02e7 2627 if (ecc_import_x963(dCert.publicKey, dCert.pubKeySize,
ashleymills 0:e979170e02e7 2628 ssl->peerEccDsaKey) != 0) {
ashleymills 0:e979170e02e7 2629 ret = PEER_KEY_ERROR;
ashleymills 0:e979170e02e7 2630 }
ashleymills 0:e979170e02e7 2631 else
ashleymills 0:e979170e02e7 2632 ssl->peerEccDsaKeyPresent = 1;
ashleymills 0:e979170e02e7 2633 }
ashleymills 0:e979170e02e7 2634 break;
ashleymills 0:e979170e02e7 2635 #endif /* HAVE_ECC */
ashleymills 0:e979170e02e7 2636 default:
ashleymills 0:e979170e02e7 2637 break;
ashleymills 0:e979170e02e7 2638 }
ashleymills 0:e979170e02e7 2639
ashleymills 0:e979170e02e7 2640 FreeDecodedCert(&dCert);
ashleymills 0:e979170e02e7 2641 }
ashleymills 0:e979170e02e7 2642
ashleymills 0:e979170e02e7 2643 if (anyError != 0 && ret == 0)
ashleymills 0:e979170e02e7 2644 ret = anyError;
ashleymills 0:e979170e02e7 2645
ashleymills 0:e979170e02e7 2646 if (ret == 0 && ssl->options.side == CLIENT_END)
ashleymills 0:e979170e02e7 2647 ssl->options.serverState = SERVER_CERT_COMPLETE;
ashleymills 0:e979170e02e7 2648
ashleymills 0:e979170e02e7 2649 if (ret != 0) {
ashleymills 0:e979170e02e7 2650 if (!ssl->options.verifyNone) {
ashleymills 0:e979170e02e7 2651 int why = bad_certificate;
ashleymills 0:e979170e02e7 2652 if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E)
ashleymills 0:e979170e02e7 2653 why = certificate_expired;
ashleymills 0:e979170e02e7 2654 if (ssl->verifyCallback) {
ashleymills 0:e979170e02e7 2655 int ok;
ashleymills 0:e979170e02e7 2656 CYASSL_X509_STORE_CTX store;
ashleymills 0:e979170e02e7 2657
ashleymills 0:e979170e02e7 2658 store.error = ret;
ashleymills 0:e979170e02e7 2659 store.error_depth = totalCerts;
ashleymills 0:e979170e02e7 2660 store.domain = domain;
ashleymills 0:e979170e02e7 2661 #ifdef OPENSSL_EXTRA
ashleymills 0:e979170e02e7 2662 store.current_cert = &ssl->peerCert;
ashleymills 0:e979170e02e7 2663 #else
ashleymills 0:e979170e02e7 2664 store.current_cert = NULL;
ashleymills 0:e979170e02e7 2665 #endif
ashleymills 0:e979170e02e7 2666 #ifdef FORTRESS
ashleymills 0:e979170e02e7 2667 store.ex_data = ssl;
ashleymills 0:e979170e02e7 2668 #endif
ashleymills 0:e979170e02e7 2669 ok = ssl->verifyCallback(0, &store);
ashleymills 0:e979170e02e7 2670 if (ok) {
ashleymills 0:e979170e02e7 2671 CYASSL_MSG("Verify callback overriding error!");
ashleymills 0:e979170e02e7 2672 ret = 0;
ashleymills 0:e979170e02e7 2673 }
ashleymills 0:e979170e02e7 2674 }
ashleymills 0:e979170e02e7 2675 if (ret != 0) {
ashleymills 0:e979170e02e7 2676 SendAlert(ssl, alert_fatal, why); /* try to send */
ashleymills 0:e979170e02e7 2677 ssl->options.isClosed = 1;
ashleymills 0:e979170e02e7 2678 }
ashleymills 0:e979170e02e7 2679 }
ashleymills 0:e979170e02e7 2680 ssl->error = ret;
ashleymills 0:e979170e02e7 2681 }
ashleymills 0:e979170e02e7 2682 #ifdef FORTRESS
ashleymills 0:e979170e02e7 2683 else {
ashleymills 0:e979170e02e7 2684 if (ssl->verifyCallback) {
ashleymills 0:e979170e02e7 2685 int ok;
ashleymills 0:e979170e02e7 2686 CYASSL_X509_STORE_CTX store;
ashleymills 0:e979170e02e7 2687
ashleymills 0:e979170e02e7 2688 store.error = ret;
ashleymills 0:e979170e02e7 2689 store.error_depth = totalCerts;
ashleymills 0:e979170e02e7 2690 store.domain = domain;
ashleymills 0:e979170e02e7 2691 store.current_cert = &ssl->peerCert;
ashleymills 0:e979170e02e7 2692 store.ex_data = ssl;
ashleymills 0:e979170e02e7 2693
ashleymills 0:e979170e02e7 2694 ok = ssl->verifyCallback(1, &store);
ashleymills 0:e979170e02e7 2695 if (!ok) {
ashleymills 0:e979170e02e7 2696 CYASSL_MSG("Verify callback overriding valid certificate!");
ashleymills 0:e979170e02e7 2697 ret = -1;
ashleymills 0:e979170e02e7 2698 SendAlert(ssl, alert_fatal, bad_certificate);
ashleymills 0:e979170e02e7 2699 ssl->options.isClosed = 1;
ashleymills 0:e979170e02e7 2700 }
ashleymills 0:e979170e02e7 2701 }
ashleymills 0:e979170e02e7 2702 }
ashleymills 0:e979170e02e7 2703 #endif
ashleymills 0:e979170e02e7 2704
ashleymills 0:e979170e02e7 2705 *inOutIdx = i;
ashleymills 0:e979170e02e7 2706 return ret;
ashleymills 0:e979170e02e7 2707 }
ashleymills 0:e979170e02e7 2708
ashleymills 0:e979170e02e7 2709 #endif /* !NO_CERTS */
ashleymills 0:e979170e02e7 2710
ashleymills 0:e979170e02e7 2711
ashleymills 0:e979170e02e7 2712 static int DoHelloRequest(CYASSL* ssl, const byte* input, word32* inOutIdx)
ashleymills 0:e979170e02e7 2713 {
ashleymills 0:e979170e02e7 2714 if (ssl->keys.encryptionOn) {
ashleymills 0:e979170e02e7 2715 const byte* mac;
ashleymills 0:e979170e02e7 2716 int padSz = ssl->keys.encryptSz - HANDSHAKE_HEADER_SZ -
ashleymills 0:e979170e02e7 2717 ssl->specs.hash_size;
ashleymills 0:e979170e02e7 2718 byte verify[SHA256_DIGEST_SIZE];
ashleymills 0:e979170e02e7 2719
ashleymills 0:e979170e02e7 2720 ssl->hmac(ssl, verify, input + *inOutIdx - HANDSHAKE_HEADER_SZ,
ashleymills 0:e979170e02e7 2721 HANDSHAKE_HEADER_SZ, handshake, 1);
ashleymills 0:e979170e02e7 2722 /* read mac and fill */
ashleymills 0:e979170e02e7 2723 mac = input + *inOutIdx;
ashleymills 0:e979170e02e7 2724 *inOutIdx += ssl->specs.hash_size;
ashleymills 0:e979170e02e7 2725
ashleymills 0:e979170e02e7 2726 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
ashleymills 0:e979170e02e7 2727 padSz -= ssl->specs.block_size;
ashleymills 0:e979170e02e7 2728
ashleymills 0:e979170e02e7 2729 *inOutIdx += padSz;
ashleymills 0:e979170e02e7 2730
ashleymills 0:e979170e02e7 2731 /* verify */
ashleymills 0:e979170e02e7 2732 if (XMEMCMP(mac, verify, ssl->specs.hash_size) != 0) {
ashleymills 0:e979170e02e7 2733 CYASSL_MSG(" hello_request verify mac error");
ashleymills 0:e979170e02e7 2734 return VERIFY_MAC_ERROR;
ashleymills 0:e979170e02e7 2735 }
ashleymills 0:e979170e02e7 2736 }
ashleymills 0:e979170e02e7 2737
ashleymills 0:e979170e02e7 2738 if (ssl->options.side == SERVER_END) {
ashleymills 0:e979170e02e7 2739 SendAlert(ssl, alert_fatal, unexpected_message); /* try */
ashleymills 0:e979170e02e7 2740 return FATAL_ERROR;
ashleymills 0:e979170e02e7 2741 }
ashleymills 0:e979170e02e7 2742 else
ashleymills 0:e979170e02e7 2743 return SendAlert(ssl, alert_warning, no_renegotiation);
ashleymills 0:e979170e02e7 2744 }
ashleymills 0:e979170e02e7 2745
ashleymills 0:e979170e02e7 2746
ashleymills 0:e979170e02e7 2747 int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, int sniff)
ashleymills 0:e979170e02e7 2748 {
ashleymills 0:e979170e02e7 2749 byte verifyMAC[SHA256_DIGEST_SIZE];
ashleymills 0:e979170e02e7 2750 int finishedSz = ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ;
ashleymills 0:e979170e02e7 2751 int headerSz = HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 2752 word32 macSz = finishedSz + HANDSHAKE_HEADER_SZ,
ashleymills 0:e979170e02e7 2753 idx = *inOutIdx,
ashleymills 0:e979170e02e7 2754 padSz = ssl->keys.encryptSz - HANDSHAKE_HEADER_SZ - finishedSz -
ashleymills 0:e979170e02e7 2755 ssl->specs.hash_size;
ashleymills 0:e979170e02e7 2756 const byte* mac;
ashleymills 0:e979170e02e7 2757
ashleymills 0:e979170e02e7 2758 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 2759 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 2760 headerSz += DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 2761 macSz += DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 2762 padSz -= DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 2763 }
ashleymills 0:e979170e02e7 2764 #endif
ashleymills 0:e979170e02e7 2765
ashleymills 0:e979170e02e7 2766 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 2767 if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 2768 if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
ashleymills 0:e979170e02e7 2769 #endif
ashleymills 0:e979170e02e7 2770 if (sniff == NO_SNIFF) {
ashleymills 0:e979170e02e7 2771 if (XMEMCMP(input + idx, &ssl->verifyHashes, finishedSz) != 0) {
ashleymills 0:e979170e02e7 2772 CYASSL_MSG("Verify finished error on hashes");
ashleymills 0:e979170e02e7 2773 return VERIFY_FINISHED_ERROR;
ashleymills 0:e979170e02e7 2774 }
ashleymills 0:e979170e02e7 2775 }
ashleymills 0:e979170e02e7 2776
ashleymills 0:e979170e02e7 2777 if (ssl->specs.cipher_type != aead) {
ashleymills 0:e979170e02e7 2778 ssl->hmac(ssl, verifyMAC, input + idx - headerSz, macSz,
ashleymills 0:e979170e02e7 2779 handshake, 1);
ashleymills 0:e979170e02e7 2780 idx += finishedSz;
ashleymills 0:e979170e02e7 2781
ashleymills 0:e979170e02e7 2782 /* read mac and fill */
ashleymills 0:e979170e02e7 2783 mac = input + idx;
ashleymills 0:e979170e02e7 2784 idx += ssl->specs.hash_size;
ashleymills 0:e979170e02e7 2785
ashleymills 0:e979170e02e7 2786 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
ashleymills 0:e979170e02e7 2787 padSz -= ssl->specs.block_size;
ashleymills 0:e979170e02e7 2788
ashleymills 0:e979170e02e7 2789 idx += padSz;
ashleymills 0:e979170e02e7 2790
ashleymills 0:e979170e02e7 2791 /* verify mac */
ashleymills 0:e979170e02e7 2792 if (XMEMCMP(mac, verifyMAC, ssl->specs.hash_size) != 0) {
ashleymills 0:e979170e02e7 2793 CYASSL_MSG("Verify finished error on mac");
ashleymills 0:e979170e02e7 2794 return VERIFY_MAC_ERROR;
ashleymills 0:e979170e02e7 2795 }
ashleymills 0:e979170e02e7 2796 }
ashleymills 0:e979170e02e7 2797 else {
ashleymills 0:e979170e02e7 2798 idx += (finishedSz + AEAD_AUTH_TAG_SZ);
ashleymills 0:e979170e02e7 2799 }
ashleymills 0:e979170e02e7 2800
ashleymills 0:e979170e02e7 2801 if (ssl->options.side == CLIENT_END) {
ashleymills 0:e979170e02e7 2802 ssl->options.serverState = SERVER_FINISHED_COMPLETE;
ashleymills 0:e979170e02e7 2803 if (!ssl->options.resuming)
ashleymills 0:e979170e02e7 2804 ssl->options.handShakeState = HANDSHAKE_DONE;
ashleymills 0:e979170e02e7 2805 }
ashleymills 0:e979170e02e7 2806 else {
ashleymills 0:e979170e02e7 2807 ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
ashleymills 0:e979170e02e7 2808 if (ssl->options.resuming)
ashleymills 0:e979170e02e7 2809 ssl->options.handShakeState = HANDSHAKE_DONE;
ashleymills 0:e979170e02e7 2810 }
ashleymills 0:e979170e02e7 2811
ashleymills 0:e979170e02e7 2812 *inOutIdx = idx;
ashleymills 0:e979170e02e7 2813 return 0;
ashleymills 0:e979170e02e7 2814 }
ashleymills 0:e979170e02e7 2815
ashleymills 0:e979170e02e7 2816
ashleymills 0:e979170e02e7 2817 static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
ashleymills 0:e979170e02e7 2818 byte type, word32 size, word32 totalSz)
ashleymills 0:e979170e02e7 2819 {
ashleymills 0:e979170e02e7 2820 int ret = 0;
ashleymills 0:e979170e02e7 2821 (void)totalSz;
ashleymills 0:e979170e02e7 2822
ashleymills 0:e979170e02e7 2823 CYASSL_ENTER("DoHandShakeMsgType");
ashleymills 0:e979170e02e7 2824
ashleymills 0:e979170e02e7 2825 HashInput(ssl, input + *inOutIdx, size);
ashleymills 0:e979170e02e7 2826 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 2827 /* add name later, add on record and handshake header part back on */
ashleymills 0:e979170e02e7 2828 if (ssl->toInfoOn) {
ashleymills 0:e979170e02e7 2829 int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 2830 AddPacketInfo(0, &ssl->timeoutInfo, input + *inOutIdx - add,
ashleymills 0:e979170e02e7 2831 size + add, ssl->heap);
ashleymills 0:e979170e02e7 2832 AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
ashleymills 0:e979170e02e7 2833 }
ashleymills 0:e979170e02e7 2834 #endif
ashleymills 0:e979170e02e7 2835
ashleymills 0:e979170e02e7 2836 if (ssl->options.handShakeState == HANDSHAKE_DONE && type != hello_request){
ashleymills 0:e979170e02e7 2837 CYASSL_MSG("HandShake message after handshake complete");
ashleymills 0:e979170e02e7 2838 SendAlert(ssl, alert_fatal, unexpected_message);
ashleymills 0:e979170e02e7 2839 return OUT_OF_ORDER_E;
ashleymills 0:e979170e02e7 2840 }
ashleymills 0:e979170e02e7 2841
ashleymills 0:e979170e02e7 2842 if (ssl->options.side == CLIENT_END && ssl->options.dtls == 0 &&
ashleymills 0:e979170e02e7 2843 ssl->options.serverState == NULL_STATE && type != server_hello) {
ashleymills 0:e979170e02e7 2844 CYASSL_MSG("First server message not server hello");
ashleymills 0:e979170e02e7 2845 SendAlert(ssl, alert_fatal, unexpected_message);
ashleymills 0:e979170e02e7 2846 return OUT_OF_ORDER_E;
ashleymills 0:e979170e02e7 2847 }
ashleymills 0:e979170e02e7 2848
ashleymills 0:e979170e02e7 2849 if (ssl->options.side == CLIENT_END && ssl->options.dtls &&
ashleymills 0:e979170e02e7 2850 type == server_hello_done &&
ashleymills 0:e979170e02e7 2851 ssl->options.serverState < SERVER_HELLO_COMPLETE) {
ashleymills 0:e979170e02e7 2852 CYASSL_MSG("Server hello done received before server hello in DTLS");
ashleymills 0:e979170e02e7 2853 SendAlert(ssl, alert_fatal, unexpected_message);
ashleymills 0:e979170e02e7 2854 return OUT_OF_ORDER_E;
ashleymills 0:e979170e02e7 2855 }
ashleymills 0:e979170e02e7 2856
ashleymills 0:e979170e02e7 2857 if (ssl->options.side == SERVER_END &&
ashleymills 0:e979170e02e7 2858 ssl->options.clientState == NULL_STATE && type != client_hello) {
ashleymills 0:e979170e02e7 2859 CYASSL_MSG("First client message not client hello");
ashleymills 0:e979170e02e7 2860 SendAlert(ssl, alert_fatal, unexpected_message);
ashleymills 0:e979170e02e7 2861 return OUT_OF_ORDER_E;
ashleymills 0:e979170e02e7 2862 }
ashleymills 0:e979170e02e7 2863
ashleymills 0:e979170e02e7 2864
ashleymills 0:e979170e02e7 2865 switch (type) {
ashleymills 0:e979170e02e7 2866
ashleymills 0:e979170e02e7 2867 case hello_request:
ashleymills 0:e979170e02e7 2868 CYASSL_MSG("processing hello request");
ashleymills 0:e979170e02e7 2869 ret = DoHelloRequest(ssl, input, inOutIdx);
ashleymills 0:e979170e02e7 2870 break;
ashleymills 0:e979170e02e7 2871
ashleymills 0:e979170e02e7 2872 #ifndef NO_CYASSL_CLIENT
ashleymills 0:e979170e02e7 2873 case hello_verify_request:
ashleymills 0:e979170e02e7 2874 CYASSL_MSG("processing hello verify request");
ashleymills 0:e979170e02e7 2875 ret = DoHelloVerifyRequest(ssl, input,inOutIdx);
ashleymills 0:e979170e02e7 2876 break;
ashleymills 0:e979170e02e7 2877
ashleymills 0:e979170e02e7 2878 case server_hello:
ashleymills 0:e979170e02e7 2879 CYASSL_MSG("processing server hello");
ashleymills 0:e979170e02e7 2880 ret = DoServerHello(ssl, input, inOutIdx, size);
ashleymills 0:e979170e02e7 2881 break;
ashleymills 0:e979170e02e7 2882
ashleymills 0:e979170e02e7 2883 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 2884 case certificate_request:
ashleymills 0:e979170e02e7 2885 CYASSL_MSG("processing certificate request");
ashleymills 0:e979170e02e7 2886 ret = DoCertificateRequest(ssl, input, inOutIdx);
ashleymills 0:e979170e02e7 2887 break;
ashleymills 0:e979170e02e7 2888 #endif
ashleymills 0:e979170e02e7 2889
ashleymills 0:e979170e02e7 2890 case server_key_exchange:
ashleymills 0:e979170e02e7 2891 CYASSL_MSG("processing server key exchange");
ashleymills 0:e979170e02e7 2892 ret = DoServerKeyExchange(ssl, input, inOutIdx);
ashleymills 0:e979170e02e7 2893 break;
ashleymills 0:e979170e02e7 2894 #endif
ashleymills 0:e979170e02e7 2895
ashleymills 0:e979170e02e7 2896 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 2897 case certificate:
ashleymills 0:e979170e02e7 2898 CYASSL_MSG("processing certificate");
ashleymills 0:e979170e02e7 2899 ret = DoCertificate(ssl, input, inOutIdx);
ashleymills 0:e979170e02e7 2900 break;
ashleymills 0:e979170e02e7 2901 #endif
ashleymills 0:e979170e02e7 2902
ashleymills 0:e979170e02e7 2903 case server_hello_done:
ashleymills 0:e979170e02e7 2904 CYASSL_MSG("processing server hello done");
ashleymills 0:e979170e02e7 2905 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 2906 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 2907 AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 2908 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 2909 AddLateName("ServerHelloDone", &ssl->timeoutInfo);
ashleymills 0:e979170e02e7 2910 #endif
ashleymills 0:e979170e02e7 2911 ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
ashleymills 0:e979170e02e7 2912 break;
ashleymills 0:e979170e02e7 2913
ashleymills 0:e979170e02e7 2914 case finished:
ashleymills 0:e979170e02e7 2915 CYASSL_MSG("processing finished");
ashleymills 0:e979170e02e7 2916 ret = DoFinished(ssl, input, inOutIdx, NO_SNIFF);
ashleymills 0:e979170e02e7 2917 break;
ashleymills 0:e979170e02e7 2918
ashleymills 0:e979170e02e7 2919 #ifndef NO_CYASSL_SERVER
ashleymills 0:e979170e02e7 2920 case client_hello:
ashleymills 0:e979170e02e7 2921 CYASSL_MSG("processing client hello");
ashleymills 0:e979170e02e7 2922 ret = DoClientHello(ssl, input, inOutIdx, totalSz, size);
ashleymills 0:e979170e02e7 2923 break;
ashleymills 0:e979170e02e7 2924
ashleymills 0:e979170e02e7 2925 case client_key_exchange:
ashleymills 0:e979170e02e7 2926 CYASSL_MSG("processing client key exchange");
ashleymills 0:e979170e02e7 2927 ret = DoClientKeyExchange(ssl, input, inOutIdx, totalSz);
ashleymills 0:e979170e02e7 2928 break;
ashleymills 0:e979170e02e7 2929
ashleymills 0:e979170e02e7 2930 #if !defined(NO_RSA) || defined(HAVE_ECC)
ashleymills 0:e979170e02e7 2931 case certificate_verify:
ashleymills 0:e979170e02e7 2932 CYASSL_MSG("processing certificate verify");
ashleymills 0:e979170e02e7 2933 ret = DoCertificateVerify(ssl, input, inOutIdx, totalSz);
ashleymills 0:e979170e02e7 2934 break;
ashleymills 0:e979170e02e7 2935 #endif /* !NO_RSA || HAVE_ECC */
ashleymills 0:e979170e02e7 2936
ashleymills 0:e979170e02e7 2937 #endif /* !NO_CYASSL_SERVER */
ashleymills 0:e979170e02e7 2938
ashleymills 0:e979170e02e7 2939 default:
ashleymills 0:e979170e02e7 2940 CYASSL_MSG("Unknown handshake message type");
ashleymills 0:e979170e02e7 2941 ret = UNKNOWN_HANDSHAKE_TYPE;
ashleymills 0:e979170e02e7 2942 }
ashleymills 0:e979170e02e7 2943
ashleymills 0:e979170e02e7 2944 CYASSL_LEAVE("DoHandShakeMsgType()", ret);
ashleymills 0:e979170e02e7 2945 return ret;
ashleymills 0:e979170e02e7 2946 }
ashleymills 0:e979170e02e7 2947
ashleymills 0:e979170e02e7 2948
ashleymills 0:e979170e02e7 2949 static int DoHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
ashleymills 0:e979170e02e7 2950 word32 totalSz)
ashleymills 0:e979170e02e7 2951 {
ashleymills 0:e979170e02e7 2952 byte type;
ashleymills 0:e979170e02e7 2953 word32 size;
ashleymills 0:e979170e02e7 2954 int ret = 0;
ashleymills 0:e979170e02e7 2955
ashleymills 0:e979170e02e7 2956 CYASSL_ENTER("DoHandShakeMsg()");
ashleymills 0:e979170e02e7 2957
ashleymills 0:e979170e02e7 2958 if (GetHandShakeHeader(ssl, input, inOutIdx, &type, &size) != 0)
ashleymills 0:e979170e02e7 2959 return PARSE_ERROR;
ashleymills 0:e979170e02e7 2960
ashleymills 0:e979170e02e7 2961 if (*inOutIdx + size > totalSz)
ashleymills 0:e979170e02e7 2962 return INCOMPLETE_DATA;
ashleymills 0:e979170e02e7 2963
ashleymills 0:e979170e02e7 2964 ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
ashleymills 0:e979170e02e7 2965
ashleymills 0:e979170e02e7 2966 CYASSL_LEAVE("DoHandShakeMsg()", ret);
ashleymills 0:e979170e02e7 2967 return ret;
ashleymills 0:e979170e02e7 2968 }
ashleymills 0:e979170e02e7 2969
ashleymills 0:e979170e02e7 2970
ashleymills 0:e979170e02e7 2971 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 2972 static int DoDtlsHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
ashleymills 0:e979170e02e7 2973 word32 totalSz)
ashleymills 0:e979170e02e7 2974 {
ashleymills 0:e979170e02e7 2975 byte type;
ashleymills 0:e979170e02e7 2976 word32 size;
ashleymills 0:e979170e02e7 2977 word32 fragOffset, fragSz;
ashleymills 0:e979170e02e7 2978 int ret = 0;
ashleymills 0:e979170e02e7 2979
ashleymills 0:e979170e02e7 2980 CYASSL_ENTER("DoDtlsHandShakeMsg()");
ashleymills 0:e979170e02e7 2981 if (GetDtlsHandShakeHeader(ssl, input, inOutIdx, &type,
ashleymills 0:e979170e02e7 2982 &size, &fragOffset, &fragSz) != 0)
ashleymills 0:e979170e02e7 2983 return PARSE_ERROR;
ashleymills 0:e979170e02e7 2984
ashleymills 0:e979170e02e7 2985 if (*inOutIdx + fragSz > totalSz)
ashleymills 0:e979170e02e7 2986 return INCOMPLETE_DATA;
ashleymills 0:e979170e02e7 2987
ashleymills 0:e979170e02e7 2988 if (fragSz < size) {
ashleymills 0:e979170e02e7 2989 /* message is fragmented, knit back together */
ashleymills 0:e979170e02e7 2990 byte* buf = ssl->buffers.dtlsHandshake.buffer;
ashleymills 0:e979170e02e7 2991 if (ssl->buffers.dtlsHandshake.length == 0) {
ashleymills 0:e979170e02e7 2992 /* Need to add a header back into the data. The Hash is calculated
ashleymills 0:e979170e02e7 2993 * as if this were a single message, not several fragments. */
ashleymills 0:e979170e02e7 2994 buf = (byte*)XMALLOC(size + DTLS_HANDSHAKE_HEADER_SZ,
ashleymills 0:e979170e02e7 2995 ssl->heap, DYNAMIC_TYPE_NONE);
ashleymills 0:e979170e02e7 2996 if (buf == NULL)
ashleymills 0:e979170e02e7 2997 return MEMORY_ERROR;
ashleymills 0:e979170e02e7 2998
ashleymills 0:e979170e02e7 2999 ssl->buffers.dtlsHandshake.length = size;
ashleymills 0:e979170e02e7 3000 ssl->buffers.dtlsHandshake.buffer = buf;
ashleymills 0:e979170e02e7 3001 ssl->buffers.dtlsUsed = 0;
ashleymills 0:e979170e02e7 3002 ssl->buffers.dtlsType = type;
ashleymills 0:e979170e02e7 3003
ashleymills 0:e979170e02e7 3004 /* Construct a new header for the reassembled message as if it
ashleymills 0:e979170e02e7 3005 * were originally sent as one fragment for the hashing later. */
ashleymills 0:e979170e02e7 3006 XMEMCPY(buf,
ashleymills 0:e979170e02e7 3007 input + *inOutIdx - DTLS_HANDSHAKE_HEADER_SZ,
ashleymills 0:e979170e02e7 3008 DTLS_HANDSHAKE_HEADER_SZ - DTLS_HANDSHAKE_FRAG_SZ);
ashleymills 0:e979170e02e7 3009 XMEMCPY(buf + DTLS_HANDSHAKE_HEADER_SZ - DTLS_HANDSHAKE_FRAG_SZ,
ashleymills 0:e979170e02e7 3010 input + *inOutIdx - DTLS_HANDSHAKE_HEADER_SZ + ENUM_LEN,
ashleymills 0:e979170e02e7 3011 DTLS_HANDSHAKE_FRAG_SZ);
ashleymills 0:e979170e02e7 3012 }
ashleymills 0:e979170e02e7 3013 /* readjust the buf pointer past the header */
ashleymills 0:e979170e02e7 3014 buf += DTLS_HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 3015
ashleymills 0:e979170e02e7 3016 XMEMCPY(buf + fragOffset, input + *inOutIdx, fragSz);
ashleymills 0:e979170e02e7 3017 ssl->buffers.dtlsUsed += fragSz;
ashleymills 0:e979170e02e7 3018 *inOutIdx += fragSz;
ashleymills 0:e979170e02e7 3019
ashleymills 0:e979170e02e7 3020 if (ssl->buffers.dtlsUsed != size) {
ashleymills 0:e979170e02e7 3021 CYASSL_LEAVE("DoDtlsHandShakeMsg()", 0);
ashleymills 0:e979170e02e7 3022 return 0;
ashleymills 0:e979170e02e7 3023 }
ashleymills 0:e979170e02e7 3024 else {
ashleymills 0:e979170e02e7 3025 if (ssl->keys.dtls_peer_handshake_number ==
ashleymills 0:e979170e02e7 3026 ssl->keys.dtls_expected_peer_handshake_number) {
ashleymills 0:e979170e02e7 3027 word32 idx = 0;
ashleymills 0:e979170e02e7 3028 totalSz = size;
ashleymills 0:e979170e02e7 3029 ssl->keys.dtls_expected_peer_handshake_number++;
ashleymills 0:e979170e02e7 3030 ret = DoHandShakeMsgType(ssl, buf, &idx, type, size, totalSz);
ashleymills 0:e979170e02e7 3031 }
ashleymills 0:e979170e02e7 3032 else {
ashleymills 0:e979170e02e7 3033 *inOutIdx += size;
ashleymills 0:e979170e02e7 3034 ret = 0;
ashleymills 0:e979170e02e7 3035 }
ashleymills 0:e979170e02e7 3036 }
ashleymills 0:e979170e02e7 3037 }
ashleymills 0:e979170e02e7 3038 else {
ashleymills 0:e979170e02e7 3039 if (ssl->keys.dtls_peer_handshake_number ==
ashleymills 0:e979170e02e7 3040 ssl->keys.dtls_expected_peer_handshake_number) {
ashleymills 0:e979170e02e7 3041 ssl->keys.dtls_expected_peer_handshake_number++;
ashleymills 0:e979170e02e7 3042 ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
ashleymills 0:e979170e02e7 3043 }
ashleymills 0:e979170e02e7 3044 else {
ashleymills 0:e979170e02e7 3045 *inOutIdx += size;
ashleymills 0:e979170e02e7 3046 ret = 0;
ashleymills 0:e979170e02e7 3047 }
ashleymills 0:e979170e02e7 3048 }
ashleymills 0:e979170e02e7 3049
ashleymills 0:e979170e02e7 3050 if (ssl->buffers.dtlsHandshake.buffer != NULL) {
ashleymills 0:e979170e02e7 3051 XFREE(ssl->buffers.dtlsHandshake.buffer, ssl->heap, DYNAMIC_TYPE_NONE);
ashleymills 0:e979170e02e7 3052 ssl->buffers.dtlsHandshake.length = 0;
ashleymills 0:e979170e02e7 3053 ssl->buffers.dtlsHandshake.buffer = NULL;
ashleymills 0:e979170e02e7 3054 ssl->buffers.dtlsUsed = 0;
ashleymills 0:e979170e02e7 3055 ssl->buffers.dtlsType = 0;
ashleymills 0:e979170e02e7 3056 }
ashleymills 0:e979170e02e7 3057
ashleymills 0:e979170e02e7 3058 CYASSL_LEAVE("DoDtlsHandShakeMsg()", ret);
ashleymills 0:e979170e02e7 3059 return ret;
ashleymills 0:e979170e02e7 3060 }
ashleymills 0:e979170e02e7 3061 #endif
ashleymills 0:e979170e02e7 3062
ashleymills 0:e979170e02e7 3063
ashleymills 0:e979170e02e7 3064 static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
ashleymills 0:e979170e02e7 3065 {
ashleymills 0:e979170e02e7 3066 if (verify)
ashleymills 0:e979170e02e7 3067 return ssl->keys.peer_sequence_number++;
ashleymills 0:e979170e02e7 3068 else
ashleymills 0:e979170e02e7 3069 return ssl->keys.sequence_number++;
ashleymills 0:e979170e02e7 3070 }
ashleymills 0:e979170e02e7 3071
ashleymills 0:e979170e02e7 3072
ashleymills 0:e979170e02e7 3073 #ifdef HAVE_AEAD
ashleymills 0:e979170e02e7 3074 static INLINE void AeadIncrementExpIV(CYASSL* ssl)
ashleymills 0:e979170e02e7 3075 {
ashleymills 0:e979170e02e7 3076 int i;
ashleymills 0:e979170e02e7 3077 for (i = AEAD_EXP_IV_SZ-1; i >= 0; i--) {
ashleymills 0:e979170e02e7 3078 if (++ssl->keys.aead_exp_IV[i]) return;
ashleymills 0:e979170e02e7 3079 }
ashleymills 0:e979170e02e7 3080 }
ashleymills 0:e979170e02e7 3081 #endif
ashleymills 0:e979170e02e7 3082
ashleymills 0:e979170e02e7 3083
ashleymills 0:e979170e02e7 3084 static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz)
ashleymills 0:e979170e02e7 3085 {
ashleymills 0:e979170e02e7 3086 (void)out;
ashleymills 0:e979170e02e7 3087 (void)input;
ashleymills 0:e979170e02e7 3088 (void)sz;
ashleymills 0:e979170e02e7 3089
ashleymills 0:e979170e02e7 3090 if (ssl->encrypt.setup == 0) {
ashleymills 0:e979170e02e7 3091 CYASSL_MSG("Encrypt ciphers not setup");
ashleymills 0:e979170e02e7 3092 return ENCRYPT_ERROR;
ashleymills 0:e979170e02e7 3093 }
ashleymills 0:e979170e02e7 3094
ashleymills 0:e979170e02e7 3095 switch (ssl->specs.bulk_cipher_algorithm) {
ashleymills 0:e979170e02e7 3096 #ifdef BUILD_ARC4
ashleymills 0:e979170e02e7 3097 case rc4:
ashleymills 0:e979170e02e7 3098 Arc4Process(ssl->encrypt.arc4, out, input, sz);
ashleymills 0:e979170e02e7 3099 break;
ashleymills 0:e979170e02e7 3100 #endif
ashleymills 0:e979170e02e7 3101
ashleymills 0:e979170e02e7 3102 #ifdef BUILD_DES3
ashleymills 0:e979170e02e7 3103 case triple_des:
ashleymills 0:e979170e02e7 3104 Des3_CbcEncrypt(ssl->encrypt.des3, out, input, sz);
ashleymills 0:e979170e02e7 3105 break;
ashleymills 0:e979170e02e7 3106 #endif
ashleymills 0:e979170e02e7 3107
ashleymills 0:e979170e02e7 3108 #ifdef BUILD_AES
ashleymills 0:e979170e02e7 3109 case aes:
ashleymills 0:e979170e02e7 3110 #ifdef CYASSL_AESNI
ashleymills 0:e979170e02e7 3111 if ((word)input % 16) {
ashleymills 0:e979170e02e7 3112 byte* tmp = (byte*)XMALLOC(sz, ssl->heap,
ashleymills 0:e979170e02e7 3113 DYNAMIC_TYPE_TMP_BUFFER);
ashleymills 0:e979170e02e7 3114 if (tmp == NULL) return MEMORY_E;
ashleymills 0:e979170e02e7 3115 XMEMCPY(tmp, input, sz);
ashleymills 0:e979170e02e7 3116 AesCbcEncrypt(ssl->encrypt.aes, tmp, tmp, sz);
ashleymills 0:e979170e02e7 3117 XMEMCPY(out, tmp, sz);
ashleymills 0:e979170e02e7 3118 XFREE(tmp, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
ashleymills 0:e979170e02e7 3119 break;
ashleymills 0:e979170e02e7 3120 }
ashleymills 0:e979170e02e7 3121 #endif
ashleymills 0:e979170e02e7 3122 AesCbcEncrypt(ssl->encrypt.aes, out, input, sz);
ashleymills 0:e979170e02e7 3123 break;
ashleymills 0:e979170e02e7 3124 #endif
ashleymills 0:e979170e02e7 3125
ashleymills 0:e979170e02e7 3126 #ifdef BUILD_AESGCM
ashleymills 0:e979170e02e7 3127 case aes_gcm:
ashleymills 0:e979170e02e7 3128 {
ashleymills 0:e979170e02e7 3129 byte additional[AES_BLOCK_SIZE];
ashleymills 0:e979170e02e7 3130 byte nonce[AEAD_NONCE_SZ];
ashleymills 0:e979170e02e7 3131
ashleymills 0:e979170e02e7 3132 XMEMSET(additional, 0, AES_BLOCK_SIZE);
ashleymills 0:e979170e02e7 3133
ashleymills 0:e979170e02e7 3134 /* sequence number field is 64-bits, we only use 32-bits */
ashleymills 0:e979170e02e7 3135 c32toa(GetSEQIncrement(ssl, 0),
ashleymills 0:e979170e02e7 3136 additional + AEAD_SEQ_OFFSET);
ashleymills 0:e979170e02e7 3137
ashleymills 0:e979170e02e7 3138 /* Store the type, version. Unfortunately, they are in
ashleymills 0:e979170e02e7 3139 * the input buffer ahead of the plaintext. */
ashleymills 0:e979170e02e7 3140 XMEMCPY(additional + AEAD_TYPE_OFFSET, input - 5, 3);
ashleymills 0:e979170e02e7 3141
ashleymills 0:e979170e02e7 3142 /* Store the length of the plain text minus the explicit
ashleymills 0:e979170e02e7 3143 * IV length minus the authentication tag size. */
ashleymills 0:e979170e02e7 3144 c16toa(sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
ashleymills 0:e979170e02e7 3145 additional + AEAD_LEN_OFFSET);
ashleymills 0:e979170e02e7 3146 XMEMCPY(nonce,
ashleymills 0:e979170e02e7 3147 ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ);
ashleymills 0:e979170e02e7 3148 XMEMCPY(nonce + AEAD_IMP_IV_SZ,
ashleymills 0:e979170e02e7 3149 ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
ashleymills 0:e979170e02e7 3150 AesGcmEncrypt(ssl->encrypt.aes,
ashleymills 0:e979170e02e7 3151 out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ,
ashleymills 0:e979170e02e7 3152 sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
ashleymills 0:e979170e02e7 3153 nonce, AEAD_NONCE_SZ,
ashleymills 0:e979170e02e7 3154 out + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ,
ashleymills 0:e979170e02e7 3155 additional, AEAD_AUTH_DATA_SZ);
ashleymills 0:e979170e02e7 3156 AeadIncrementExpIV(ssl);
ashleymills 0:e979170e02e7 3157 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
ashleymills 0:e979170e02e7 3158 }
ashleymills 0:e979170e02e7 3159 break;
ashleymills 0:e979170e02e7 3160 #endif
ashleymills 0:e979170e02e7 3161
ashleymills 0:e979170e02e7 3162 #ifdef HAVE_AESCCM
ashleymills 0:e979170e02e7 3163 case aes_ccm:
ashleymills 0:e979170e02e7 3164 {
ashleymills 0:e979170e02e7 3165 byte additional[AES_BLOCK_SIZE];
ashleymills 0:e979170e02e7 3166 byte nonce[AEAD_NONCE_SZ];
ashleymills 0:e979170e02e7 3167
ashleymills 0:e979170e02e7 3168 XMEMSET(additional, 0, AES_BLOCK_SIZE);
ashleymills 0:e979170e02e7 3169
ashleymills 0:e979170e02e7 3170 /* sequence number field is 64-bits, we only use 32-bits */
ashleymills 0:e979170e02e7 3171 c32toa(GetSEQIncrement(ssl, 0),
ashleymills 0:e979170e02e7 3172 additional + AEAD_SEQ_OFFSET);
ashleymills 0:e979170e02e7 3173
ashleymills 0:e979170e02e7 3174 /* Store the type, version. Unfortunately, they are in
ashleymills 0:e979170e02e7 3175 * the input buffer ahead of the plaintext. */
ashleymills 0:e979170e02e7 3176 XMEMCPY(additional + AEAD_TYPE_OFFSET, input - 5, 3);
ashleymills 0:e979170e02e7 3177
ashleymills 0:e979170e02e7 3178 /* Store the length of the plain text minus the explicit
ashleymills 0:e979170e02e7 3179 * IV length minus the authentication tag size. */
ashleymills 0:e979170e02e7 3180 c16toa(sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
ashleymills 0:e979170e02e7 3181 additional + AEAD_LEN_OFFSET);
ashleymills 0:e979170e02e7 3182 XMEMCPY(nonce,
ashleymills 0:e979170e02e7 3183 ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ);
ashleymills 0:e979170e02e7 3184 XMEMCPY(nonce + AEAD_IMP_IV_SZ,
ashleymills 0:e979170e02e7 3185 ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
ashleymills 0:e979170e02e7 3186 AesCcmEncrypt(ssl->encrypt.aes,
ashleymills 0:e979170e02e7 3187 out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ,
ashleymills 0:e979170e02e7 3188 sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
ashleymills 0:e979170e02e7 3189 nonce, AEAD_NONCE_SZ,
ashleymills 0:e979170e02e7 3190 out + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ,
ashleymills 0:e979170e02e7 3191 additional, AEAD_AUTH_DATA_SZ);
ashleymills 0:e979170e02e7 3192 AeadIncrementExpIV(ssl);
ashleymills 0:e979170e02e7 3193 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
ashleymills 0:e979170e02e7 3194 }
ashleymills 0:e979170e02e7 3195 break;
ashleymills 0:e979170e02e7 3196 #endif
ashleymills 0:e979170e02e7 3197
ashleymills 0:e979170e02e7 3198 #ifdef HAVE_CAMELLIA
ashleymills 0:e979170e02e7 3199 case camellia:
ashleymills 0:e979170e02e7 3200 CamelliaCbcEncrypt(ssl->encrypt.cam, out, input, sz);
ashleymills 0:e979170e02e7 3201 break;
ashleymills 0:e979170e02e7 3202 #endif
ashleymills 0:e979170e02e7 3203
ashleymills 0:e979170e02e7 3204 #ifdef HAVE_HC128
ashleymills 0:e979170e02e7 3205 case hc128:
ashleymills 0:e979170e02e7 3206 #ifdef XSTREAM_ALIGNMENT
ashleymills 0:e979170e02e7 3207 if ((word)input % 4) {
ashleymills 0:e979170e02e7 3208 byte* tmp = (byte*)XMALLOC(sz, ssl->heap,
ashleymills 0:e979170e02e7 3209 DYNAMIC_TYPE_TMP_BUFFER);
ashleymills 0:e979170e02e7 3210 if (tmp == NULL) return MEMORY_E;
ashleymills 0:e979170e02e7 3211 XMEMCPY(tmp, input, sz);
ashleymills 0:e979170e02e7 3212 Hc128_Process(ssl->encrypt.hc128, tmp, tmp, sz);
ashleymills 0:e979170e02e7 3213 XMEMCPY(out, tmp, sz);
ashleymills 0:e979170e02e7 3214 XFREE(tmp, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
ashleymills 0:e979170e02e7 3215 break;
ashleymills 0:e979170e02e7 3216 }
ashleymills 0:e979170e02e7 3217 #endif
ashleymills 0:e979170e02e7 3218 Hc128_Process(ssl->encrypt.hc128, out, input, sz);
ashleymills 0:e979170e02e7 3219 break;
ashleymills 0:e979170e02e7 3220 #endif
ashleymills 0:e979170e02e7 3221
ashleymills 0:e979170e02e7 3222 #ifdef BUILD_RABBIT
ashleymills 0:e979170e02e7 3223 case rabbit:
ashleymills 0:e979170e02e7 3224 #ifdef XSTREAM_ALIGNMENT
ashleymills 0:e979170e02e7 3225 if ((word)input % 4) {
ashleymills 0:e979170e02e7 3226 byte* tmp = (byte*)XMALLOC(sz, ssl->heap,
ashleymills 0:e979170e02e7 3227 DYNAMIC_TYPE_TMP_BUFFER);
ashleymills 0:e979170e02e7 3228 if (tmp == NULL) return MEMORY_E;
ashleymills 0:e979170e02e7 3229 XMEMCPY(tmp, input, sz);
ashleymills 0:e979170e02e7 3230 RabbitProcess(ssl->encrypt.rabbit, tmp, tmp, sz);
ashleymills 0:e979170e02e7 3231 XMEMCPY(out, tmp, sz);
ashleymills 0:e979170e02e7 3232 XFREE(tmp, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
ashleymills 0:e979170e02e7 3233 break;
ashleymills 0:e979170e02e7 3234 }
ashleymills 0:e979170e02e7 3235 #endif
ashleymills 0:e979170e02e7 3236 RabbitProcess(ssl->encrypt.rabbit, out, input, sz);
ashleymills 0:e979170e02e7 3237 break;
ashleymills 0:e979170e02e7 3238 #endif
ashleymills 0:e979170e02e7 3239
ashleymills 0:e979170e02e7 3240 #ifdef HAVE_NULL_CIPHER
ashleymills 0:e979170e02e7 3241 case cipher_null:
ashleymills 0:e979170e02e7 3242 if (input != out) {
ashleymills 0:e979170e02e7 3243 XMEMMOVE(out, input, sz);
ashleymills 0:e979170e02e7 3244 }
ashleymills 0:e979170e02e7 3245 break;
ashleymills 0:e979170e02e7 3246 #endif
ashleymills 0:e979170e02e7 3247
ashleymills 0:e979170e02e7 3248 default:
ashleymills 0:e979170e02e7 3249 CYASSL_MSG("CyaSSL Encrypt programming error");
ashleymills 0:e979170e02e7 3250 return ENCRYPT_ERROR;
ashleymills 0:e979170e02e7 3251 }
ashleymills 0:e979170e02e7 3252
ashleymills 0:e979170e02e7 3253 return 0;
ashleymills 0:e979170e02e7 3254 }
ashleymills 0:e979170e02e7 3255
ashleymills 0:e979170e02e7 3256
ashleymills 0:e979170e02e7 3257 static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input,
ashleymills 0:e979170e02e7 3258 word32 sz)
ashleymills 0:e979170e02e7 3259 {
ashleymills 0:e979170e02e7 3260 (void)plain;
ashleymills 0:e979170e02e7 3261 (void)input;
ashleymills 0:e979170e02e7 3262 (void)sz;
ashleymills 0:e979170e02e7 3263
ashleymills 0:e979170e02e7 3264 if (ssl->decrypt.setup == 0) {
ashleymills 0:e979170e02e7 3265 CYASSL_MSG("Decrypt ciphers not setup");
ashleymills 0:e979170e02e7 3266 return DECRYPT_ERROR;
ashleymills 0:e979170e02e7 3267 }
ashleymills 0:e979170e02e7 3268
ashleymills 0:e979170e02e7 3269 switch (ssl->specs.bulk_cipher_algorithm) {
ashleymills 0:e979170e02e7 3270 #ifdef BUILD_ARC4
ashleymills 0:e979170e02e7 3271 case rc4:
ashleymills 0:e979170e02e7 3272 Arc4Process(ssl->decrypt.arc4, plain, input, sz);
ashleymills 0:e979170e02e7 3273 break;
ashleymills 0:e979170e02e7 3274 #endif
ashleymills 0:e979170e02e7 3275
ashleymills 0:e979170e02e7 3276 #ifdef BUILD_DES3
ashleymills 0:e979170e02e7 3277 case triple_des:
ashleymills 0:e979170e02e7 3278 Des3_CbcDecrypt(ssl->decrypt.des3, plain, input, sz);
ashleymills 0:e979170e02e7 3279 break;
ashleymills 0:e979170e02e7 3280 #endif
ashleymills 0:e979170e02e7 3281
ashleymills 0:e979170e02e7 3282 #ifdef BUILD_AES
ashleymills 0:e979170e02e7 3283 case aes:
ashleymills 0:e979170e02e7 3284 AesCbcDecrypt(ssl->decrypt.aes, plain, input, sz);
ashleymills 0:e979170e02e7 3285 break;
ashleymills 0:e979170e02e7 3286 #endif
ashleymills 0:e979170e02e7 3287
ashleymills 0:e979170e02e7 3288 #ifdef BUILD_AESGCM
ashleymills 0:e979170e02e7 3289 case aes_gcm:
ashleymills 0:e979170e02e7 3290 {
ashleymills 0:e979170e02e7 3291 byte additional[AES_BLOCK_SIZE];
ashleymills 0:e979170e02e7 3292 byte nonce[AEAD_NONCE_SZ];
ashleymills 0:e979170e02e7 3293
ashleymills 0:e979170e02e7 3294 XMEMSET(additional, 0, AES_BLOCK_SIZE);
ashleymills 0:e979170e02e7 3295
ashleymills 0:e979170e02e7 3296 /* sequence number field is 64-bits, we only use 32-bits */
ashleymills 0:e979170e02e7 3297 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
ashleymills 0:e979170e02e7 3298
ashleymills 0:e979170e02e7 3299 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
ashleymills 0:e979170e02e7 3300 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
ashleymills 0:e979170e02e7 3301 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
ashleymills 0:e979170e02e7 3302
ashleymills 0:e979170e02e7 3303 c16toa(sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
ashleymills 0:e979170e02e7 3304 additional + AEAD_LEN_OFFSET);
ashleymills 0:e979170e02e7 3305 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
ashleymills 0:e979170e02e7 3306 XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
ashleymills 0:e979170e02e7 3307 if (AesGcmDecrypt(ssl->decrypt.aes,
ashleymills 0:e979170e02e7 3308 plain + AEAD_EXP_IV_SZ,
ashleymills 0:e979170e02e7 3309 input + AEAD_EXP_IV_SZ,
ashleymills 0:e979170e02e7 3310 sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
ashleymills 0:e979170e02e7 3311 nonce, AEAD_NONCE_SZ,
ashleymills 0:e979170e02e7 3312 input + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ,
ashleymills 0:e979170e02e7 3313 additional, AEAD_AUTH_DATA_SZ) < 0) {
ashleymills 0:e979170e02e7 3314 SendAlert(ssl, alert_fatal, bad_record_mac);
ashleymills 0:e979170e02e7 3315 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
ashleymills 0:e979170e02e7 3316 return VERIFY_MAC_ERROR;
ashleymills 0:e979170e02e7 3317 }
ashleymills 0:e979170e02e7 3318 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
ashleymills 0:e979170e02e7 3319 break;
ashleymills 0:e979170e02e7 3320 }
ashleymills 0:e979170e02e7 3321 #endif
ashleymills 0:e979170e02e7 3322
ashleymills 0:e979170e02e7 3323 #ifdef HAVE_AESCCM
ashleymills 0:e979170e02e7 3324 case aes_ccm:
ashleymills 0:e979170e02e7 3325 {
ashleymills 0:e979170e02e7 3326 byte additional[AES_BLOCK_SIZE];
ashleymills 0:e979170e02e7 3327 byte nonce[AEAD_NONCE_SZ];
ashleymills 0:e979170e02e7 3328
ashleymills 0:e979170e02e7 3329 XMEMSET(additional, 0, AES_BLOCK_SIZE);
ashleymills 0:e979170e02e7 3330
ashleymills 0:e979170e02e7 3331 /* sequence number field is 64-bits, we only use 32-bits */
ashleymills 0:e979170e02e7 3332 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
ashleymills 0:e979170e02e7 3333
ashleymills 0:e979170e02e7 3334 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
ashleymills 0:e979170e02e7 3335 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
ashleymills 0:e979170e02e7 3336 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
ashleymills 0:e979170e02e7 3337
ashleymills 0:e979170e02e7 3338 c16toa(sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
ashleymills 0:e979170e02e7 3339 additional + AEAD_LEN_OFFSET);
ashleymills 0:e979170e02e7 3340 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
ashleymills 0:e979170e02e7 3341 XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
ashleymills 0:e979170e02e7 3342 if (AesCcmDecrypt(ssl->decrypt.aes,
ashleymills 0:e979170e02e7 3343 plain + AEAD_EXP_IV_SZ,
ashleymills 0:e979170e02e7 3344 input + AEAD_EXP_IV_SZ,
ashleymills 0:e979170e02e7 3345 sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
ashleymills 0:e979170e02e7 3346 nonce, AEAD_NONCE_SZ,
ashleymills 0:e979170e02e7 3347 input + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ,
ashleymills 0:e979170e02e7 3348 additional, AEAD_AUTH_DATA_SZ) < 0) {
ashleymills 0:e979170e02e7 3349 SendAlert(ssl, alert_fatal, bad_record_mac);
ashleymills 0:e979170e02e7 3350 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
ashleymills 0:e979170e02e7 3351 return VERIFY_MAC_ERROR;
ashleymills 0:e979170e02e7 3352 }
ashleymills 0:e979170e02e7 3353 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
ashleymills 0:e979170e02e7 3354 break;
ashleymills 0:e979170e02e7 3355 }
ashleymills 0:e979170e02e7 3356 #endif
ashleymills 0:e979170e02e7 3357
ashleymills 0:e979170e02e7 3358 #ifdef HAVE_CAMELLIA
ashleymills 0:e979170e02e7 3359 case camellia:
ashleymills 0:e979170e02e7 3360 CamelliaCbcDecrypt(ssl->decrypt.cam, plain, input, sz);
ashleymills 0:e979170e02e7 3361 break;
ashleymills 0:e979170e02e7 3362 #endif
ashleymills 0:e979170e02e7 3363
ashleymills 0:e979170e02e7 3364 #ifdef HAVE_HC128
ashleymills 0:e979170e02e7 3365 case hc128:
ashleymills 0:e979170e02e7 3366 Hc128_Process(ssl->decrypt.hc128, plain, input, sz);
ashleymills 0:e979170e02e7 3367 break;
ashleymills 0:e979170e02e7 3368 #endif
ashleymills 0:e979170e02e7 3369
ashleymills 0:e979170e02e7 3370 #ifdef BUILD_RABBIT
ashleymills 0:e979170e02e7 3371 case rabbit:
ashleymills 0:e979170e02e7 3372 RabbitProcess(ssl->decrypt.rabbit, plain, input, sz);
ashleymills 0:e979170e02e7 3373 break;
ashleymills 0:e979170e02e7 3374 #endif
ashleymills 0:e979170e02e7 3375
ashleymills 0:e979170e02e7 3376 #ifdef HAVE_NULL_CIPHER
ashleymills 0:e979170e02e7 3377 case cipher_null:
ashleymills 0:e979170e02e7 3378 if (input != plain) {
ashleymills 0:e979170e02e7 3379 XMEMMOVE(plain, input, sz);
ashleymills 0:e979170e02e7 3380 }
ashleymills 0:e979170e02e7 3381 break;
ashleymills 0:e979170e02e7 3382 #endif
ashleymills 0:e979170e02e7 3383
ashleymills 0:e979170e02e7 3384 default:
ashleymills 0:e979170e02e7 3385 CYASSL_MSG("CyaSSL Decrypt programming error");
ashleymills 0:e979170e02e7 3386 return DECRYPT_ERROR;
ashleymills 0:e979170e02e7 3387 }
ashleymills 0:e979170e02e7 3388 return 0;
ashleymills 0:e979170e02e7 3389 }
ashleymills 0:e979170e02e7 3390
ashleymills 0:e979170e02e7 3391
ashleymills 0:e979170e02e7 3392 /* check cipher text size for sanity */
ashleymills 0:e979170e02e7 3393 static int SanityCheckCipherText(CYASSL* ssl, word32 encryptSz)
ashleymills 0:e979170e02e7 3394 {
ashleymills 0:e979170e02e7 3395 word32 minLength = 0;
ashleymills 0:e979170e02e7 3396
ashleymills 0:e979170e02e7 3397 if (ssl->specs.cipher_type == block) {
ashleymills 0:e979170e02e7 3398 if (encryptSz % ssl->specs.block_size) {
ashleymills 0:e979170e02e7 3399 CYASSL_MSG("Block ciphertext not block size");
ashleymills 0:e979170e02e7 3400 return SANITY_CIPHER_E;
ashleymills 0:e979170e02e7 3401 }
ashleymills 0:e979170e02e7 3402 minLength = ssl->specs.hash_size + 1; /* pad byte */
ashleymills 0:e979170e02e7 3403 if (ssl->specs.block_size > minLength)
ashleymills 0:e979170e02e7 3404 minLength = ssl->specs.block_size;
ashleymills 0:e979170e02e7 3405
ashleymills 0:e979170e02e7 3406 if (ssl->options.tls1_1)
ashleymills 0:e979170e02e7 3407 minLength += ssl->specs.block_size; /* explicit IV */
ashleymills 0:e979170e02e7 3408 }
ashleymills 0:e979170e02e7 3409 else if (ssl->specs.cipher_type == stream) {
ashleymills 0:e979170e02e7 3410 minLength = ssl->specs.hash_size;
ashleymills 0:e979170e02e7 3411 }
ashleymills 0:e979170e02e7 3412 else if (ssl->specs.cipher_type == aead) {
ashleymills 0:e979170e02e7 3413 minLength = ssl->specs.block_size; /* explicit IV + implicit IV + CTR*/
ashleymills 0:e979170e02e7 3414 }
ashleymills 0:e979170e02e7 3415
ashleymills 0:e979170e02e7 3416 if (encryptSz < minLength) {
ashleymills 0:e979170e02e7 3417 CYASSL_MSG("Ciphertext not minimum size");
ashleymills 0:e979170e02e7 3418 return SANITY_CIPHER_E;
ashleymills 0:e979170e02e7 3419 }
ashleymills 0:e979170e02e7 3420
ashleymills 0:e979170e02e7 3421 return 0;
ashleymills 0:e979170e02e7 3422 }
ashleymills 0:e979170e02e7 3423
ashleymills 0:e979170e02e7 3424
ashleymills 0:e979170e02e7 3425 /* decrypt input message in place */
ashleymills 0:e979170e02e7 3426 static int DecryptMessage(CYASSL* ssl, byte* input, word32 sz, word32* idx)
ashleymills 0:e979170e02e7 3427 {
ashleymills 0:e979170e02e7 3428 int decryptResult;
ashleymills 0:e979170e02e7 3429 int sanityResult = SanityCheckCipherText(ssl, sz);
ashleymills 0:e979170e02e7 3430
ashleymills 0:e979170e02e7 3431 if (sanityResult != 0)
ashleymills 0:e979170e02e7 3432 return sanityResult;
ashleymills 0:e979170e02e7 3433
ashleymills 0:e979170e02e7 3434 decryptResult = Decrypt(ssl, input, input, sz);
ashleymills 0:e979170e02e7 3435
ashleymills 0:e979170e02e7 3436 if (decryptResult == 0)
ashleymills 0:e979170e02e7 3437 {
ashleymills 0:e979170e02e7 3438 ssl->keys.encryptSz = sz;
ashleymills 0:e979170e02e7 3439 ssl->keys.decryptedCur = 1;
ashleymills 0:e979170e02e7 3440
ashleymills 0:e979170e02e7 3441 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
ashleymills 0:e979170e02e7 3442 *idx += ssl->specs.block_size; /* go past TLSv1.1 IV */
ashleymills 0:e979170e02e7 3443 if (ssl->specs.cipher_type == aead)
ashleymills 0:e979170e02e7 3444 *idx += AEAD_EXP_IV_SZ;
ashleymills 0:e979170e02e7 3445 }
ashleymills 0:e979170e02e7 3446
ashleymills 0:e979170e02e7 3447 return decryptResult;
ashleymills 0:e979170e02e7 3448 }
ashleymills 0:e979170e02e7 3449
ashleymills 0:e979170e02e7 3450
ashleymills 0:e979170e02e7 3451 #ifndef NO_MD5
ashleymills 0:e979170e02e7 3452
ashleymills 0:e979170e02e7 3453 static INLINE void Md5Rounds(int rounds, const byte* data, int sz)
ashleymills 0:e979170e02e7 3454 {
ashleymills 0:e979170e02e7 3455 Md5 md5;
ashleymills 0:e979170e02e7 3456 int i;
ashleymills 0:e979170e02e7 3457
ashleymills 0:e979170e02e7 3458 InitMd5(&md5);
ashleymills 0:e979170e02e7 3459
ashleymills 0:e979170e02e7 3460 for (i = 0; i < rounds; i++)
ashleymills 0:e979170e02e7 3461 Md5Update(&md5, data, sz);
ashleymills 0:e979170e02e7 3462 }
ashleymills 0:e979170e02e7 3463
ashleymills 0:e979170e02e7 3464 #endif
ashleymills 0:e979170e02e7 3465
ashleymills 0:e979170e02e7 3466
ashleymills 0:e979170e02e7 3467 static INLINE void ShaRounds(int rounds, const byte* data, int sz)
ashleymills 0:e979170e02e7 3468 {
ashleymills 0:e979170e02e7 3469 Sha sha;
ashleymills 0:e979170e02e7 3470 int i;
ashleymills 0:e979170e02e7 3471
ashleymills 0:e979170e02e7 3472 InitSha(&sha);
ashleymills 0:e979170e02e7 3473
ashleymills 0:e979170e02e7 3474 for (i = 0; i < rounds; i++)
ashleymills 0:e979170e02e7 3475 ShaUpdate(&sha, data, sz);
ashleymills 0:e979170e02e7 3476 }
ashleymills 0:e979170e02e7 3477
ashleymills 0:e979170e02e7 3478
ashleymills 0:e979170e02e7 3479 #ifndef NO_SHA256
ashleymills 0:e979170e02e7 3480
ashleymills 0:e979170e02e7 3481 static INLINE void Sha256Rounds(int rounds, const byte* data, int sz)
ashleymills 0:e979170e02e7 3482 {
ashleymills 0:e979170e02e7 3483 Sha256 sha256;
ashleymills 0:e979170e02e7 3484 int i;
ashleymills 0:e979170e02e7 3485
ashleymills 0:e979170e02e7 3486 InitSha256(&sha256);
ashleymills 0:e979170e02e7 3487
ashleymills 0:e979170e02e7 3488 for (i = 0; i < rounds; i++)
ashleymills 0:e979170e02e7 3489 Sha256Update(&sha256, data, sz);
ashleymills 0:e979170e02e7 3490 }
ashleymills 0:e979170e02e7 3491
ashleymills 0:e979170e02e7 3492 #endif
ashleymills 0:e979170e02e7 3493
ashleymills 0:e979170e02e7 3494
ashleymills 0:e979170e02e7 3495 #ifdef CYASSL_SHA384
ashleymills 0:e979170e02e7 3496
ashleymills 0:e979170e02e7 3497 static INLINE void Sha384Rounds(int rounds, const byte* data, int sz)
ashleymills 0:e979170e02e7 3498 {
ashleymills 0:e979170e02e7 3499 Sha384 sha384;
ashleymills 0:e979170e02e7 3500 int i;
ashleymills 0:e979170e02e7 3501
ashleymills 0:e979170e02e7 3502 InitSha384(&sha384);
ashleymills 0:e979170e02e7 3503
ashleymills 0:e979170e02e7 3504 for (i = 0; i < rounds; i++)
ashleymills 0:e979170e02e7 3505 Sha384Update(&sha384, data, sz);
ashleymills 0:e979170e02e7 3506 }
ashleymills 0:e979170e02e7 3507
ashleymills 0:e979170e02e7 3508 #endif
ashleymills 0:e979170e02e7 3509
ashleymills 0:e979170e02e7 3510
ashleymills 0:e979170e02e7 3511 #ifdef CYASSL_SHA512
ashleymills 0:e979170e02e7 3512
ashleymills 0:e979170e02e7 3513 static INLINE void Sha512Rounds(int rounds, const byte* data, int sz)
ashleymills 0:e979170e02e7 3514 {
ashleymills 0:e979170e02e7 3515 Sha512 sha512;
ashleymills 0:e979170e02e7 3516 int i;
ashleymills 0:e979170e02e7 3517
ashleymills 0:e979170e02e7 3518 InitSha512(&sha512);
ashleymills 0:e979170e02e7 3519
ashleymills 0:e979170e02e7 3520 for (i = 0; i < rounds; i++)
ashleymills 0:e979170e02e7 3521 Sha512Update(&sha512, data, sz);
ashleymills 0:e979170e02e7 3522 }
ashleymills 0:e979170e02e7 3523
ashleymills 0:e979170e02e7 3524 #endif
ashleymills 0:e979170e02e7 3525
ashleymills 0:e979170e02e7 3526
ashleymills 0:e979170e02e7 3527 #ifdef CYASSL_RIPEMD
ashleymills 0:e979170e02e7 3528
ashleymills 0:e979170e02e7 3529 static INLINE void RmdRounds(int rounds, const byte* data, int sz)
ashleymills 0:e979170e02e7 3530 {
ashleymills 0:e979170e02e7 3531 RipeMd ripemd;
ashleymills 0:e979170e02e7 3532 int i;
ashleymills 0:e979170e02e7 3533
ashleymills 0:e979170e02e7 3534 InitRipeMd(&ripemd);
ashleymills 0:e979170e02e7 3535
ashleymills 0:e979170e02e7 3536 for (i = 0; i < rounds; i++)
ashleymills 0:e979170e02e7 3537 RipeMdUpdate(&ripemd, data, sz);
ashleymills 0:e979170e02e7 3538 }
ashleymills 0:e979170e02e7 3539
ashleymills 0:e979170e02e7 3540 #endif
ashleymills 0:e979170e02e7 3541
ashleymills 0:e979170e02e7 3542
ashleymills 0:e979170e02e7 3543 static INLINE void DoRounds(int type, int rounds, const byte* data, int sz)
ashleymills 0:e979170e02e7 3544 {
ashleymills 0:e979170e02e7 3545 switch (type) {
ashleymills 0:e979170e02e7 3546
ashleymills 0:e979170e02e7 3547 case no_mac :
ashleymills 0:e979170e02e7 3548 break;
ashleymills 0:e979170e02e7 3549
ashleymills 0:e979170e02e7 3550 #ifndef NO_MD5
ashleymills 0:e979170e02e7 3551 case md5_mac :
ashleymills 0:e979170e02e7 3552 Md5Rounds(rounds, data, sz);
ashleymills 0:e979170e02e7 3553 break;
ashleymills 0:e979170e02e7 3554 #endif
ashleymills 0:e979170e02e7 3555
ashleymills 0:e979170e02e7 3556 case sha_mac :
ashleymills 0:e979170e02e7 3557 ShaRounds(rounds, data, sz);
ashleymills 0:e979170e02e7 3558 break;
ashleymills 0:e979170e02e7 3559
ashleymills 0:e979170e02e7 3560 #ifndef NO_SHA256
ashleymills 0:e979170e02e7 3561 case sha256_mac :
ashleymills 0:e979170e02e7 3562 Sha256Rounds(rounds, data, sz);
ashleymills 0:e979170e02e7 3563 break;
ashleymills 0:e979170e02e7 3564 #endif
ashleymills 0:e979170e02e7 3565
ashleymills 0:e979170e02e7 3566 #ifdef CYASSL_SHA384
ashleymills 0:e979170e02e7 3567 case sha384_mac :
ashleymills 0:e979170e02e7 3568 Sha384Rounds(rounds, data, sz);
ashleymills 0:e979170e02e7 3569 break;
ashleymills 0:e979170e02e7 3570 #endif
ashleymills 0:e979170e02e7 3571
ashleymills 0:e979170e02e7 3572 #ifdef CYASSL_SHA512
ashleymills 0:e979170e02e7 3573 case sha512_mac :
ashleymills 0:e979170e02e7 3574 Sha512Rounds(rounds, data, sz);
ashleymills 0:e979170e02e7 3575 break;
ashleymills 0:e979170e02e7 3576 #endif
ashleymills 0:e979170e02e7 3577
ashleymills 0:e979170e02e7 3578 #ifdef CYASSL_RIPEMD
ashleymills 0:e979170e02e7 3579 case rmd_mac :
ashleymills 0:e979170e02e7 3580 RmdRounds(rounds, data, sz);
ashleymills 0:e979170e02e7 3581 break;
ashleymills 0:e979170e02e7 3582 #endif
ashleymills 0:e979170e02e7 3583
ashleymills 0:e979170e02e7 3584 default:
ashleymills 0:e979170e02e7 3585 CYASSL_MSG("Bad round type");
ashleymills 0:e979170e02e7 3586 break;
ashleymills 0:e979170e02e7 3587 }
ashleymills 0:e979170e02e7 3588 }
ashleymills 0:e979170e02e7 3589
ashleymills 0:e979170e02e7 3590
ashleymills 0:e979170e02e7 3591 /* do number of compression rounds on dummy data */
ashleymills 0:e979170e02e7 3592 static INLINE void CompressRounds(CYASSL* ssl, int rounds, const byte* dummy)
ashleymills 0:e979170e02e7 3593 {
ashleymills 0:e979170e02e7 3594 if (rounds)
ashleymills 0:e979170e02e7 3595 DoRounds(ssl->specs.mac_algorithm, rounds, dummy, COMPRESS_LOWER);
ashleymills 0:e979170e02e7 3596 }
ashleymills 0:e979170e02e7 3597
ashleymills 0:e979170e02e7 3598
ashleymills 0:e979170e02e7 3599 /* check all length bytes for equality, return 0 on success */
ashleymills 0:e979170e02e7 3600 static int ConstantCompare(const byte* a, const byte* b, int length)
ashleymills 0:e979170e02e7 3601 {
ashleymills 0:e979170e02e7 3602 int i;
ashleymills 0:e979170e02e7 3603 int good = 0;
ashleymills 0:e979170e02e7 3604 int bad = 0;
ashleymills 0:e979170e02e7 3605
ashleymills 0:e979170e02e7 3606 for (i = 0; i < length; i++) {
ashleymills 0:e979170e02e7 3607 if (a[i] == b[i])
ashleymills 0:e979170e02e7 3608 good++;
ashleymills 0:e979170e02e7 3609 else
ashleymills 0:e979170e02e7 3610 bad++;
ashleymills 0:e979170e02e7 3611 }
ashleymills 0:e979170e02e7 3612
ashleymills 0:e979170e02e7 3613 if (good == length)
ashleymills 0:e979170e02e7 3614 return 0;
ashleymills 0:e979170e02e7 3615 else
ashleymills 0:e979170e02e7 3616 return 0 - bad; /* compare failed */
ashleymills 0:e979170e02e7 3617 }
ashleymills 0:e979170e02e7 3618
ashleymills 0:e979170e02e7 3619
ashleymills 0:e979170e02e7 3620 /* check all length bytes for the pad value, return 0 on success */
ashleymills 0:e979170e02e7 3621 static int PadCheck(const byte* input, byte pad, int length)
ashleymills 0:e979170e02e7 3622 {
ashleymills 0:e979170e02e7 3623 int i;
ashleymills 0:e979170e02e7 3624 int good = 0;
ashleymills 0:e979170e02e7 3625 int bad = 0;
ashleymills 0:e979170e02e7 3626
ashleymills 0:e979170e02e7 3627 for (i = 0; i < length; i++) {
ashleymills 0:e979170e02e7 3628 if (input[i] == pad)
ashleymills 0:e979170e02e7 3629 good++;
ashleymills 0:e979170e02e7 3630 else
ashleymills 0:e979170e02e7 3631 bad++;
ashleymills 0:e979170e02e7 3632 }
ashleymills 0:e979170e02e7 3633
ashleymills 0:e979170e02e7 3634 if (good == length)
ashleymills 0:e979170e02e7 3635 return 0;
ashleymills 0:e979170e02e7 3636 else
ashleymills 0:e979170e02e7 3637 return 0 - bad; /* pad check failed */
ashleymills 0:e979170e02e7 3638 }
ashleymills 0:e979170e02e7 3639
ashleymills 0:e979170e02e7 3640
ashleymills 0:e979170e02e7 3641 /* get compression extra rounds */
ashleymills 0:e979170e02e7 3642 static INLINE int GetRounds(int pLen, int padLen, int t)
ashleymills 0:e979170e02e7 3643 {
ashleymills 0:e979170e02e7 3644 int roundL1 = 1; /* round up flags */
ashleymills 0:e979170e02e7 3645 int roundL2 = 1;
ashleymills 0:e979170e02e7 3646
ashleymills 0:e979170e02e7 3647 int L1 = COMPRESS_CONSTANT + pLen - t;
ashleymills 0:e979170e02e7 3648 int L2 = COMPRESS_CONSTANT + pLen - padLen - 1 - t;
ashleymills 0:e979170e02e7 3649
ashleymills 0:e979170e02e7 3650 L1 -= COMPRESS_UPPER;
ashleymills 0:e979170e02e7 3651 L2 -= COMPRESS_UPPER;
ashleymills 0:e979170e02e7 3652
ashleymills 0:e979170e02e7 3653 if ( (L1 % COMPRESS_LOWER) == 0)
ashleymills 0:e979170e02e7 3654 roundL1 = 0;
ashleymills 0:e979170e02e7 3655 if ( (L2 % COMPRESS_LOWER) == 0)
ashleymills 0:e979170e02e7 3656 roundL2 = 0;
ashleymills 0:e979170e02e7 3657
ashleymills 0:e979170e02e7 3658 L1 /= COMPRESS_LOWER;
ashleymills 0:e979170e02e7 3659 L2 /= COMPRESS_LOWER;
ashleymills 0:e979170e02e7 3660
ashleymills 0:e979170e02e7 3661 L1 += roundL1;
ashleymills 0:e979170e02e7 3662 L2 += roundL2;
ashleymills 0:e979170e02e7 3663
ashleymills 0:e979170e02e7 3664 return L1 - L2;
ashleymills 0:e979170e02e7 3665 }
ashleymills 0:e979170e02e7 3666
ashleymills 0:e979170e02e7 3667
ashleymills 0:e979170e02e7 3668 /* timing resistant pad/verify check, return 0 on success */
ashleymills 0:e979170e02e7 3669 static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t,
ashleymills 0:e979170e02e7 3670 int pLen)
ashleymills 0:e979170e02e7 3671 {
ashleymills 0:e979170e02e7 3672 byte verify[SHA256_DIGEST_SIZE];
ashleymills 0:e979170e02e7 3673 byte dummy[MAX_PAD_SIZE];
ashleymills 0:e979170e02e7 3674
ashleymills 0:e979170e02e7 3675 XMEMSET(dummy, 1, sizeof(dummy));
ashleymills 0:e979170e02e7 3676
ashleymills 0:e979170e02e7 3677 if ( (t + padLen + 1) > pLen) {
ashleymills 0:e979170e02e7 3678 CYASSL_MSG("Plain Len not long enough for pad/mac");
ashleymills 0:e979170e02e7 3679 PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE);
ashleymills 0:e979170e02e7 3680 ssl->hmac(ssl, verify, input, pLen - t, application_data, 1);
ashleymills 0:e979170e02e7 3681 ConstantCompare(verify, input + pLen - t, t);
ashleymills 0:e979170e02e7 3682
ashleymills 0:e979170e02e7 3683 return VERIFY_MAC_ERROR;
ashleymills 0:e979170e02e7 3684 }
ashleymills 0:e979170e02e7 3685
ashleymills 0:e979170e02e7 3686 if (PadCheck(input + pLen - (padLen + 1), (byte)padLen, padLen + 1) != 0) {
ashleymills 0:e979170e02e7 3687 CYASSL_MSG("PadCheck failed");
ashleymills 0:e979170e02e7 3688 PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
ashleymills 0:e979170e02e7 3689 ssl->hmac(ssl, verify, input, pLen - t, application_data, 1);
ashleymills 0:e979170e02e7 3690 ConstantCompare(verify, input + pLen - t, t);
ashleymills 0:e979170e02e7 3691
ashleymills 0:e979170e02e7 3692 return VERIFY_MAC_ERROR;
ashleymills 0:e979170e02e7 3693 }
ashleymills 0:e979170e02e7 3694
ashleymills 0:e979170e02e7 3695 PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
ashleymills 0:e979170e02e7 3696 ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, application_data, 1);
ashleymills 0:e979170e02e7 3697
ashleymills 0:e979170e02e7 3698 CompressRounds(ssl, GetRounds(pLen, padLen, t), dummy);
ashleymills 0:e979170e02e7 3699
ashleymills 0:e979170e02e7 3700 if (ConstantCompare(verify, input + (pLen - padLen - 1 - t), t) != 0) {
ashleymills 0:e979170e02e7 3701 CYASSL_MSG("Verify MAC compare failed");
ashleymills 0:e979170e02e7 3702 return VERIFY_MAC_ERROR;
ashleymills 0:e979170e02e7 3703 }
ashleymills 0:e979170e02e7 3704
ashleymills 0:e979170e02e7 3705 return 0;
ashleymills 0:e979170e02e7 3706 }
ashleymills 0:e979170e02e7 3707
ashleymills 0:e979170e02e7 3708
ashleymills 0:e979170e02e7 3709 int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx)
ashleymills 0:e979170e02e7 3710 {
ashleymills 0:e979170e02e7 3711 word32 msgSz = ssl->keys.encryptSz;
ashleymills 0:e979170e02e7 3712 word32 pad = 0,
ashleymills 0:e979170e02e7 3713 padByte = 0,
ashleymills 0:e979170e02e7 3714 idx = *inOutIdx,
ashleymills 0:e979170e02e7 3715 digestSz = ssl->specs.hash_size;
ashleymills 0:e979170e02e7 3716 int dataSz, ret;
ashleymills 0:e979170e02e7 3717 int ivExtra = 0;
ashleymills 0:e979170e02e7 3718 byte* rawData = input + idx; /* keep current for hmac */
ashleymills 0:e979170e02e7 3719 #ifdef HAVE_LIBZ
ashleymills 0:e979170e02e7 3720 byte decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
ashleymills 0:e979170e02e7 3721 #endif
ashleymills 0:e979170e02e7 3722 byte verify[SHA256_DIGEST_SIZE];
ashleymills 0:e979170e02e7 3723
ashleymills 0:e979170e02e7 3724 if (ssl->options.handShakeState != HANDSHAKE_DONE) {
ashleymills 0:e979170e02e7 3725 CYASSL_MSG("Received App data before handshake complete");
ashleymills 0:e979170e02e7 3726 SendAlert(ssl, alert_fatal, unexpected_message);
ashleymills 0:e979170e02e7 3727 return OUT_OF_ORDER_E;
ashleymills 0:e979170e02e7 3728 }
ashleymills 0:e979170e02e7 3729
ashleymills 0:e979170e02e7 3730 if (ssl->specs.cipher_type == block) {
ashleymills 0:e979170e02e7 3731 if (ssl->options.tls1_1)
ashleymills 0:e979170e02e7 3732 ivExtra = ssl->specs.block_size;
ashleymills 0:e979170e02e7 3733 pad = *(input + idx + msgSz - ivExtra - 1);
ashleymills 0:e979170e02e7 3734 padByte = 1;
ashleymills 0:e979170e02e7 3735
ashleymills 0:e979170e02e7 3736 if (ssl->options.tls) {
ashleymills 0:e979170e02e7 3737 ret = TimingPadVerify(ssl, input + idx, pad, digestSz,
ashleymills 0:e979170e02e7 3738 msgSz - ivExtra);
ashleymills 0:e979170e02e7 3739 if (ret != 0)
ashleymills 0:e979170e02e7 3740 return ret;
ashleymills 0:e979170e02e7 3741 }
ashleymills 0:e979170e02e7 3742 else { /* sslv3, some implementations have bad padding */
ashleymills 0:e979170e02e7 3743 ssl->hmac(ssl, verify, rawData, msgSz - digestSz - pad - 1,
ashleymills 0:e979170e02e7 3744 application_data, 1);
ashleymills 0:e979170e02e7 3745 if (ConstantCompare(verify, rawData + msgSz - digestSz - pad - 1,
ashleymills 0:e979170e02e7 3746 digestSz) != 0)
ashleymills 0:e979170e02e7 3747 return VERIFY_MAC_ERROR;
ashleymills 0:e979170e02e7 3748 }
ashleymills 0:e979170e02e7 3749 }
ashleymills 0:e979170e02e7 3750 else if (ssl->specs.cipher_type == stream) {
ashleymills 0:e979170e02e7 3751 ssl->hmac(ssl, verify, rawData, msgSz - digestSz, application_data, 1);
ashleymills 0:e979170e02e7 3752 if (ConstantCompare(verify, rawData + msgSz - digestSz, digestSz) != 0){
ashleymills 0:e979170e02e7 3753 return VERIFY_MAC_ERROR;
ashleymills 0:e979170e02e7 3754 }
ashleymills 0:e979170e02e7 3755 }
ashleymills 0:e979170e02e7 3756 else if (ssl->specs.cipher_type == aead) {
ashleymills 0:e979170e02e7 3757 ivExtra = AEAD_EXP_IV_SZ;
ashleymills 0:e979170e02e7 3758 digestSz = AEAD_AUTH_TAG_SZ;
ashleymills 0:e979170e02e7 3759 }
ashleymills 0:e979170e02e7 3760
ashleymills 0:e979170e02e7 3761 dataSz = msgSz - ivExtra - digestSz - pad - padByte;
ashleymills 0:e979170e02e7 3762 if (dataSz < 0) {
ashleymills 0:e979170e02e7 3763 CYASSL_MSG("App data buffer error, malicious input?");
ashleymills 0:e979170e02e7 3764 return BUFFER_ERROR;
ashleymills 0:e979170e02e7 3765 }
ashleymills 0:e979170e02e7 3766
ashleymills 0:e979170e02e7 3767 /* read data */
ashleymills 0:e979170e02e7 3768 if (dataSz) {
ashleymills 0:e979170e02e7 3769 int rawSz = dataSz; /* keep raw size for idx adjustment */
ashleymills 0:e979170e02e7 3770
ashleymills 0:e979170e02e7 3771 #ifdef HAVE_LIBZ
ashleymills 0:e979170e02e7 3772 if (ssl->options.usingCompression) {
ashleymills 0:e979170e02e7 3773 dataSz = DeCompress(ssl, rawData, dataSz, decomp, sizeof(decomp));
ashleymills 0:e979170e02e7 3774 if (dataSz < 0) return dataSz;
ashleymills 0:e979170e02e7 3775 }
ashleymills 0:e979170e02e7 3776 #endif
ashleymills 0:e979170e02e7 3777 idx += rawSz;
ashleymills 0:e979170e02e7 3778
ashleymills 0:e979170e02e7 3779 ssl->buffers.clearOutputBuffer.buffer = rawData;
ashleymills 0:e979170e02e7 3780 ssl->buffers.clearOutputBuffer.length = dataSz;
ashleymills 0:e979170e02e7 3781 }
ashleymills 0:e979170e02e7 3782
ashleymills 0:e979170e02e7 3783 idx += digestSz;
ashleymills 0:e979170e02e7 3784 idx += pad;
ashleymills 0:e979170e02e7 3785 if (padByte)
ashleymills 0:e979170e02e7 3786 idx++;
ashleymills 0:e979170e02e7 3787
ashleymills 0:e979170e02e7 3788 #ifdef HAVE_LIBZ
ashleymills 0:e979170e02e7 3789 /* decompress could be bigger, overwrite after verify */
ashleymills 0:e979170e02e7 3790 if (ssl->options.usingCompression)
ashleymills 0:e979170e02e7 3791 XMEMMOVE(rawData, decomp, dataSz);
ashleymills 0:e979170e02e7 3792 #endif
ashleymills 0:e979170e02e7 3793
ashleymills 0:e979170e02e7 3794 *inOutIdx = idx;
ashleymills 0:e979170e02e7 3795 return 0;
ashleymills 0:e979170e02e7 3796 }
ashleymills 0:e979170e02e7 3797
ashleymills 0:e979170e02e7 3798
ashleymills 0:e979170e02e7 3799 /* process alert, return level */
ashleymills 0:e979170e02e7 3800 static int DoAlert(CYASSL* ssl, byte* input, word32* inOutIdx, int* type)
ashleymills 0:e979170e02e7 3801 {
ashleymills 0:e979170e02e7 3802 byte level;
ashleymills 0:e979170e02e7 3803
ashleymills 0:e979170e02e7 3804 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 3805 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 3806 AddPacketName("Alert", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 3807 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 3808 /* add record header back on to info + 2 byte level, data */
ashleymills 0:e979170e02e7 3809 AddPacketInfo("Alert", &ssl->timeoutInfo, input + *inOutIdx -
ashleymills 0:e979170e02e7 3810 RECORD_HEADER_SZ, 2 + RECORD_HEADER_SZ, ssl->heap);
ashleymills 0:e979170e02e7 3811 #endif
ashleymills 0:e979170e02e7 3812 level = input[(*inOutIdx)++];
ashleymills 0:e979170e02e7 3813 *type = (int)input[(*inOutIdx)++];
ashleymills 0:e979170e02e7 3814
ashleymills 0:e979170e02e7 3815 CYASSL_MSG("Got alert");
ashleymills 0:e979170e02e7 3816 if (*type == close_notify) {
ashleymills 0:e979170e02e7 3817 CYASSL_MSG(" close notify");
ashleymills 0:e979170e02e7 3818 ssl->options.closeNotify = 1;
ashleymills 0:e979170e02e7 3819 }
ashleymills 0:e979170e02e7 3820 CYASSL_ERROR(*type);
ashleymills 0:e979170e02e7 3821
ashleymills 0:e979170e02e7 3822 if (ssl->keys.encryptionOn) {
ashleymills 0:e979170e02e7 3823 if (ssl->specs.cipher_type != aead) {
ashleymills 0:e979170e02e7 3824 int aSz = ALERT_SIZE;
ashleymills 0:e979170e02e7 3825 const byte* mac;
ashleymills 0:e979170e02e7 3826 byte verify[SHA256_DIGEST_SIZE];
ashleymills 0:e979170e02e7 3827 int padSz = ssl->keys.encryptSz - aSz - ssl->specs.hash_size;
ashleymills 0:e979170e02e7 3828
ashleymills 0:e979170e02e7 3829 ssl->hmac(ssl, verify, input + *inOutIdx - aSz, aSz, alert, 1);
ashleymills 0:e979170e02e7 3830
ashleymills 0:e979170e02e7 3831 /* read mac and fill */
ashleymills 0:e979170e02e7 3832 mac = input + *inOutIdx;
ashleymills 0:e979170e02e7 3833 *inOutIdx += (ssl->specs.hash_size + padSz);
ashleymills 0:e979170e02e7 3834
ashleymills 0:e979170e02e7 3835 /* verify */
ashleymills 0:e979170e02e7 3836 if (XMEMCMP(mac, verify, ssl->specs.hash_size) != 0) {
ashleymills 0:e979170e02e7 3837 CYASSL_MSG(" alert verify mac error");
ashleymills 0:e979170e02e7 3838 return VERIFY_MAC_ERROR;
ashleymills 0:e979170e02e7 3839 }
ashleymills 0:e979170e02e7 3840 }
ashleymills 0:e979170e02e7 3841 else {
ashleymills 0:e979170e02e7 3842 *inOutIdx += AEAD_AUTH_TAG_SZ;
ashleymills 0:e979170e02e7 3843 }
ashleymills 0:e979170e02e7 3844 }
ashleymills 0:e979170e02e7 3845
ashleymills 0:e979170e02e7 3846 return level;
ashleymills 0:e979170e02e7 3847 }
ashleymills 0:e979170e02e7 3848
ashleymills 0:e979170e02e7 3849 static int GetInputData(CYASSL *ssl, word32 size)
ashleymills 0:e979170e02e7 3850 {
ashleymills 0:e979170e02e7 3851 int in;
ashleymills 0:e979170e02e7 3852 int inSz;
ashleymills 0:e979170e02e7 3853 int maxLength;
ashleymills 0:e979170e02e7 3854 int usedLength;
ashleymills 0:e979170e02e7 3855
ashleymills 0:e979170e02e7 3856
ashleymills 0:e979170e02e7 3857 /* check max input length */
ashleymills 0:e979170e02e7 3858 usedLength = ssl->buffers.inputBuffer.length - ssl->buffers.inputBuffer.idx;
ashleymills 0:e979170e02e7 3859 maxLength = ssl->buffers.inputBuffer.bufferSize - usedLength;
ashleymills 0:e979170e02e7 3860 inSz = (int)(size - usedLength); /* from last partial read */
ashleymills 0:e979170e02e7 3861
ashleymills 0:e979170e02e7 3862 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 3863 if (ssl->options.dtls)
ashleymills 0:e979170e02e7 3864 inSz = MAX_MTU; /* read ahead up to MTU */
ashleymills 0:e979170e02e7 3865 #endif
ashleymills 0:e979170e02e7 3866
ashleymills 0:e979170e02e7 3867 if (inSz > maxLength) {
ashleymills 0:e979170e02e7 3868 if (GrowInputBuffer(ssl, size, usedLength) < 0)
ashleymills 0:e979170e02e7 3869 return MEMORY_E;
ashleymills 0:e979170e02e7 3870 }
ashleymills 0:e979170e02e7 3871
ashleymills 0:e979170e02e7 3872 if (inSz <= 0)
ashleymills 0:e979170e02e7 3873 return BUFFER_ERROR;
ashleymills 0:e979170e02e7 3874
ashleymills 0:e979170e02e7 3875 /* Put buffer data at start if not there */
ashleymills 0:e979170e02e7 3876 if (usedLength > 0 && ssl->buffers.inputBuffer.idx != 0)
ashleymills 0:e979170e02e7 3877 XMEMMOVE(ssl->buffers.inputBuffer.buffer,
ashleymills 0:e979170e02e7 3878 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
ashleymills 0:e979170e02e7 3879 usedLength);
ashleymills 0:e979170e02e7 3880
ashleymills 0:e979170e02e7 3881 /* remove processed data */
ashleymills 0:e979170e02e7 3882 ssl->buffers.inputBuffer.idx = 0;
ashleymills 0:e979170e02e7 3883 ssl->buffers.inputBuffer.length = usedLength;
ashleymills 0:e979170e02e7 3884
ashleymills 0:e979170e02e7 3885 /* read data from network */
ashleymills 0:e979170e02e7 3886 do {
ashleymills 0:e979170e02e7 3887 in = Receive(ssl,
ashleymills 0:e979170e02e7 3888 ssl->buffers.inputBuffer.buffer +
ashleymills 0:e979170e02e7 3889 ssl->buffers.inputBuffer.length,
ashleymills 0:e979170e02e7 3890 inSz);
ashleymills 0:e979170e02e7 3891 if (in == -1)
ashleymills 0:e979170e02e7 3892 return SOCKET_ERROR_E;
ashleymills 0:e979170e02e7 3893
ashleymills 0:e979170e02e7 3894 if (in == WANT_READ)
ashleymills 0:e979170e02e7 3895 return WANT_READ;
ashleymills 0:e979170e02e7 3896
ashleymills 0:e979170e02e7 3897 if (in > inSz)
ashleymills 0:e979170e02e7 3898 return RECV_OVERFLOW_E;
ashleymills 0:e979170e02e7 3899
ashleymills 0:e979170e02e7 3900 ssl->buffers.inputBuffer.length += in;
ashleymills 0:e979170e02e7 3901 inSz -= in;
ashleymills 0:e979170e02e7 3902
ashleymills 0:e979170e02e7 3903 } while (ssl->buffers.inputBuffer.length < size);
ashleymills 0:e979170e02e7 3904
ashleymills 0:e979170e02e7 3905 return 0;
ashleymills 0:e979170e02e7 3906 }
ashleymills 0:e979170e02e7 3907
ashleymills 0:e979170e02e7 3908 /* process input requests, return 0 is done, 1 is call again to complete, and
ashleymills 0:e979170e02e7 3909 negative number is error */
ashleymills 0:e979170e02e7 3910 int ProcessReply(CYASSL* ssl)
ashleymills 0:e979170e02e7 3911 {
ashleymills 0:e979170e02e7 3912 int ret = 0, type, readSz;
ashleymills 0:e979170e02e7 3913 word32 startIdx = 0;
ashleymills 0:e979170e02e7 3914 #ifndef NO_CYASSL_SERVER
ashleymills 0:e979170e02e7 3915 byte b0, b1;
ashleymills 0:e979170e02e7 3916 #endif
ashleymills 0:e979170e02e7 3917 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 3918 int used;
ashleymills 0:e979170e02e7 3919 #endif
ashleymills 0:e979170e02e7 3920
ashleymills 0:e979170e02e7 3921 for (;;) {
ashleymills 0:e979170e02e7 3922 switch ((processReply)ssl->options.processReply) {
ashleymills 0:e979170e02e7 3923
ashleymills 0:e979170e02e7 3924 /* in the CYASSL_SERVER case, get the first byte for detecting
ashleymills 0:e979170e02e7 3925 * old client hello */
ashleymills 0:e979170e02e7 3926 case doProcessInit:
ashleymills 0:e979170e02e7 3927
ashleymills 0:e979170e02e7 3928 readSz = RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 3929
ashleymills 0:e979170e02e7 3930 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 3931 if (ssl->options.dtls)
ashleymills 0:e979170e02e7 3932 readSz = DTLS_RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 3933 #endif
ashleymills 0:e979170e02e7 3934
ashleymills 0:e979170e02e7 3935 /* get header or return error */
ashleymills 0:e979170e02e7 3936 if (!ssl->options.dtls) {
ashleymills 0:e979170e02e7 3937 if ((ret = GetInputData(ssl, readSz)) < 0)
ashleymills 0:e979170e02e7 3938 return ret;
ashleymills 0:e979170e02e7 3939 } else {
ashleymills 0:e979170e02e7 3940 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 3941 /* read ahead may already have header */
ashleymills 0:e979170e02e7 3942 used = ssl->buffers.inputBuffer.length -
ashleymills 0:e979170e02e7 3943 ssl->buffers.inputBuffer.idx;
ashleymills 0:e979170e02e7 3944 if (used < readSz)
ashleymills 0:e979170e02e7 3945 if ((ret = GetInputData(ssl, readSz)) < 0)
ashleymills 0:e979170e02e7 3946 return ret;
ashleymills 0:e979170e02e7 3947 #endif
ashleymills 0:e979170e02e7 3948 }
ashleymills 0:e979170e02e7 3949
ashleymills 0:e979170e02e7 3950 #ifndef NO_CYASSL_SERVER
ashleymills 0:e979170e02e7 3951
ashleymills 0:e979170e02e7 3952 /* see if sending SSLv2 client hello */
ashleymills 0:e979170e02e7 3953 if ( ssl->options.side == SERVER_END &&
ashleymills 0:e979170e02e7 3954 ssl->options.clientState == NULL_STATE &&
ashleymills 0:e979170e02e7 3955 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx]
ashleymills 0:e979170e02e7 3956 != handshake) {
ashleymills 0:e979170e02e7 3957 ssl->options.processReply = runProcessOldClientHello;
ashleymills 0:e979170e02e7 3958
ashleymills 0:e979170e02e7 3959 /* how many bytes need ProcessOldClientHello */
ashleymills 0:e979170e02e7 3960 b0 =
ashleymills 0:e979170e02e7 3961 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
ashleymills 0:e979170e02e7 3962 b1 =
ashleymills 0:e979170e02e7 3963 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
ashleymills 0:e979170e02e7 3964 ssl->curSize = ((b0 & 0x7f) << 8) | b1;
ashleymills 0:e979170e02e7 3965 }
ashleymills 0:e979170e02e7 3966 else {
ashleymills 0:e979170e02e7 3967 ssl->options.processReply = getRecordLayerHeader;
ashleymills 0:e979170e02e7 3968 continue;
ashleymills 0:e979170e02e7 3969 }
ashleymills 0:e979170e02e7 3970
ashleymills 0:e979170e02e7 3971 /* in the CYASSL_SERVER case, run the old client hello */
ashleymills 0:e979170e02e7 3972 case runProcessOldClientHello:
ashleymills 0:e979170e02e7 3973
ashleymills 0:e979170e02e7 3974 /* get sz bytes or return error */
ashleymills 0:e979170e02e7 3975 if (!ssl->options.dtls) {
ashleymills 0:e979170e02e7 3976 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
ashleymills 0:e979170e02e7 3977 return ret;
ashleymills 0:e979170e02e7 3978 } else {
ashleymills 0:e979170e02e7 3979 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 3980 /* read ahead may already have */
ashleymills 0:e979170e02e7 3981 used = ssl->buffers.inputBuffer.length -
ashleymills 0:e979170e02e7 3982 ssl->buffers.inputBuffer.idx;
ashleymills 0:e979170e02e7 3983 if (used < ssl->curSize)
ashleymills 0:e979170e02e7 3984 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
ashleymills 0:e979170e02e7 3985 return ret;
ashleymills 0:e979170e02e7 3986 #endif /* CYASSL_DTLS */
ashleymills 0:e979170e02e7 3987 }
ashleymills 0:e979170e02e7 3988
ashleymills 0:e979170e02e7 3989 ret = ProcessOldClientHello(ssl, ssl->buffers.inputBuffer.buffer,
ashleymills 0:e979170e02e7 3990 &ssl->buffers.inputBuffer.idx,
ashleymills 0:e979170e02e7 3991 ssl->buffers.inputBuffer.length -
ashleymills 0:e979170e02e7 3992 ssl->buffers.inputBuffer.idx,
ashleymills 0:e979170e02e7 3993 ssl->curSize);
ashleymills 0:e979170e02e7 3994 if (ret < 0)
ashleymills 0:e979170e02e7 3995 return ret;
ashleymills 0:e979170e02e7 3996
ashleymills 0:e979170e02e7 3997 else if (ssl->buffers.inputBuffer.idx ==
ashleymills 0:e979170e02e7 3998 ssl->buffers.inputBuffer.length) {
ashleymills 0:e979170e02e7 3999 ssl->options.processReply = doProcessInit;
ashleymills 0:e979170e02e7 4000 return 0;
ashleymills 0:e979170e02e7 4001 }
ashleymills 0:e979170e02e7 4002
ashleymills 0:e979170e02e7 4003 #endif /* NO_CYASSL_SERVER */
ashleymills 0:e979170e02e7 4004
ashleymills 0:e979170e02e7 4005 /* get the record layer header */
ashleymills 0:e979170e02e7 4006 case getRecordLayerHeader:
ashleymills 0:e979170e02e7 4007
ashleymills 0:e979170e02e7 4008 ret = GetRecordHeader(ssl, ssl->buffers.inputBuffer.buffer,
ashleymills 0:e979170e02e7 4009 &ssl->buffers.inputBuffer.idx,
ashleymills 0:e979170e02e7 4010 &ssl->curRL, &ssl->curSize);
ashleymills 0:e979170e02e7 4011 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4012 if (ssl->options.dtls && ret == SEQUENCE_ERROR) {
ashleymills 0:e979170e02e7 4013 /* This message is out of order. Forget it ever happened. */
ashleymills 0:e979170e02e7 4014 ssl->options.processReply = doProcessInit;
ashleymills 0:e979170e02e7 4015 ssl->buffers.inputBuffer.length = 0;
ashleymills 0:e979170e02e7 4016 ssl->buffers.inputBuffer.idx = 0;
ashleymills 0:e979170e02e7 4017 continue;
ashleymills 0:e979170e02e7 4018 }
ashleymills 0:e979170e02e7 4019 #endif
ashleymills 0:e979170e02e7 4020 if (ret != 0)
ashleymills 0:e979170e02e7 4021 return ret;
ashleymills 0:e979170e02e7 4022
ashleymills 0:e979170e02e7 4023 ssl->options.processReply = getData;
ashleymills 0:e979170e02e7 4024
ashleymills 0:e979170e02e7 4025 /* retrieve record layer data */
ashleymills 0:e979170e02e7 4026 case getData:
ashleymills 0:e979170e02e7 4027
ashleymills 0:e979170e02e7 4028 /* get sz bytes or return error */
ashleymills 0:e979170e02e7 4029 if (!ssl->options.dtls) {
ashleymills 0:e979170e02e7 4030 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
ashleymills 0:e979170e02e7 4031 return ret;
ashleymills 0:e979170e02e7 4032 } else {
ashleymills 0:e979170e02e7 4033 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4034 /* read ahead may already have */
ashleymills 0:e979170e02e7 4035 used = ssl->buffers.inputBuffer.length -
ashleymills 0:e979170e02e7 4036 ssl->buffers.inputBuffer.idx;
ashleymills 0:e979170e02e7 4037 if (used < ssl->curSize)
ashleymills 0:e979170e02e7 4038 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
ashleymills 0:e979170e02e7 4039 return ret;
ashleymills 0:e979170e02e7 4040 #endif
ashleymills 0:e979170e02e7 4041 }
ashleymills 0:e979170e02e7 4042
ashleymills 0:e979170e02e7 4043 ssl->options.processReply = runProcessingOneMessage;
ashleymills 0:e979170e02e7 4044 startIdx = ssl->buffers.inputBuffer.idx; /* in case > 1 msg per */
ashleymills 0:e979170e02e7 4045
ashleymills 0:e979170e02e7 4046 /* the record layer is here */
ashleymills 0:e979170e02e7 4047 case runProcessingOneMessage:
ashleymills 0:e979170e02e7 4048
ashleymills 0:e979170e02e7 4049 if (ssl->keys.encryptionOn && ssl->keys.decryptedCur == 0)
ashleymills 0:e979170e02e7 4050 if (DecryptMessage(ssl, ssl->buffers.inputBuffer.buffer +
ashleymills 0:e979170e02e7 4051 ssl->buffers.inputBuffer.idx,
ashleymills 0:e979170e02e7 4052 ssl->curSize,
ashleymills 0:e979170e02e7 4053 &ssl->buffers.inputBuffer.idx) < 0)
ashleymills 0:e979170e02e7 4054 return DECRYPT_ERROR;
ashleymills 0:e979170e02e7 4055
ashleymills 0:e979170e02e7 4056 CYASSL_MSG("received record layer msg");
ashleymills 0:e979170e02e7 4057
ashleymills 0:e979170e02e7 4058 switch (ssl->curRL.type) {
ashleymills 0:e979170e02e7 4059 case handshake :
ashleymills 0:e979170e02e7 4060 /* debugging in DoHandShakeMsg */
ashleymills 0:e979170e02e7 4061 if (!ssl->options.dtls) {
ashleymills 0:e979170e02e7 4062 ret = DoHandShakeMsg(ssl,
ashleymills 0:e979170e02e7 4063 ssl->buffers.inputBuffer.buffer,
ashleymills 0:e979170e02e7 4064 &ssl->buffers.inputBuffer.idx,
ashleymills 0:e979170e02e7 4065 ssl->buffers.inputBuffer.length);
ashleymills 0:e979170e02e7 4066 }
ashleymills 0:e979170e02e7 4067 else {
ashleymills 0:e979170e02e7 4068 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4069 ret = DoDtlsHandShakeMsg(ssl,
ashleymills 0:e979170e02e7 4070 ssl->buffers.inputBuffer.buffer,
ashleymills 0:e979170e02e7 4071 &ssl->buffers.inputBuffer.idx,
ashleymills 0:e979170e02e7 4072 ssl->buffers.inputBuffer.length);
ashleymills 0:e979170e02e7 4073 #endif
ashleymills 0:e979170e02e7 4074 }
ashleymills 0:e979170e02e7 4075 if (ret != 0)
ashleymills 0:e979170e02e7 4076 return ret;
ashleymills 0:e979170e02e7 4077 break;
ashleymills 0:e979170e02e7 4078
ashleymills 0:e979170e02e7 4079 case change_cipher_spec:
ashleymills 0:e979170e02e7 4080 CYASSL_MSG("got CHANGE CIPHER SPEC");
ashleymills 0:e979170e02e7 4081 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 4082 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 4083 AddPacketName("ChangeCipher", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 4084 /* add record header back on info */
ashleymills 0:e979170e02e7 4085 if (ssl->toInfoOn) {
ashleymills 0:e979170e02e7 4086 AddPacketInfo("ChangeCipher", &ssl->timeoutInfo,
ashleymills 0:e979170e02e7 4087 ssl->buffers.inputBuffer.buffer +
ashleymills 0:e979170e02e7 4088 ssl->buffers.inputBuffer.idx - RECORD_HEADER_SZ,
ashleymills 0:e979170e02e7 4089 1 + RECORD_HEADER_SZ, ssl->heap);
ashleymills 0:e979170e02e7 4090 AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
ashleymills 0:e979170e02e7 4091 }
ashleymills 0:e979170e02e7 4092 #endif
ashleymills 0:e979170e02e7 4093
ashleymills 0:e979170e02e7 4094 if (ssl->curSize != 1) {
ashleymills 0:e979170e02e7 4095 CYASSL_MSG("Malicious or corrupted ChangeCipher msg");
ashleymills 0:e979170e02e7 4096 return LENGTH_ERROR;
ashleymills 0:e979170e02e7 4097 }
ashleymills 0:e979170e02e7 4098 ssl->buffers.inputBuffer.idx++;
ashleymills 0:e979170e02e7 4099 ssl->keys.encryptionOn = 1;
ashleymills 0:e979170e02e7 4100
ashleymills 0:e979170e02e7 4101 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4102 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 4103 DtlsPoolReset(ssl);
ashleymills 0:e979170e02e7 4104 ssl->keys.dtls_expected_peer_epoch++;
ashleymills 0:e979170e02e7 4105 ssl->keys.dtls_expected_peer_sequence_number = 0;
ashleymills 0:e979170e02e7 4106 }
ashleymills 0:e979170e02e7 4107 #endif
ashleymills 0:e979170e02e7 4108
ashleymills 0:e979170e02e7 4109 #ifdef HAVE_LIBZ
ashleymills 0:e979170e02e7 4110 if (ssl->options.usingCompression)
ashleymills 0:e979170e02e7 4111 if ( (ret = InitStreams(ssl)) != 0)
ashleymills 0:e979170e02e7 4112 return ret;
ashleymills 0:e979170e02e7 4113 #endif
ashleymills 0:e979170e02e7 4114 if (ssl->options.resuming && ssl->options.side ==
ashleymills 0:e979170e02e7 4115 CLIENT_END)
ashleymills 0:e979170e02e7 4116 BuildFinished(ssl, &ssl->verifyHashes, server);
ashleymills 0:e979170e02e7 4117 else if (!ssl->options.resuming && ssl->options.side ==
ashleymills 0:e979170e02e7 4118 SERVER_END)
ashleymills 0:e979170e02e7 4119 BuildFinished(ssl, &ssl->verifyHashes, client);
ashleymills 0:e979170e02e7 4120 break;
ashleymills 0:e979170e02e7 4121
ashleymills 0:e979170e02e7 4122 case application_data:
ashleymills 0:e979170e02e7 4123 CYASSL_MSG("got app DATA");
ashleymills 0:e979170e02e7 4124 if ((ret = DoApplicationData(ssl,
ashleymills 0:e979170e02e7 4125 ssl->buffers.inputBuffer.buffer,
ashleymills 0:e979170e02e7 4126 &ssl->buffers.inputBuffer.idx))
ashleymills 0:e979170e02e7 4127 != 0) {
ashleymills 0:e979170e02e7 4128 CYASSL_ERROR(ret);
ashleymills 0:e979170e02e7 4129 return ret;
ashleymills 0:e979170e02e7 4130 }
ashleymills 0:e979170e02e7 4131 break;
ashleymills 0:e979170e02e7 4132
ashleymills 0:e979170e02e7 4133 case alert:
ashleymills 0:e979170e02e7 4134 CYASSL_MSG("got ALERT!");
ashleymills 0:e979170e02e7 4135 if (DoAlert(ssl, ssl->buffers.inputBuffer.buffer,
ashleymills 0:e979170e02e7 4136 &ssl->buffers.inputBuffer.idx, &type) == alert_fatal)
ashleymills 0:e979170e02e7 4137 return FATAL_ERROR;
ashleymills 0:e979170e02e7 4138
ashleymills 0:e979170e02e7 4139 /* catch warnings that are handled as errors */
ashleymills 0:e979170e02e7 4140 if (type == close_notify)
ashleymills 0:e979170e02e7 4141 return ssl->error = ZERO_RETURN;
ashleymills 0:e979170e02e7 4142
ashleymills 0:e979170e02e7 4143 if (type == decrypt_error)
ashleymills 0:e979170e02e7 4144 return FATAL_ERROR;
ashleymills 0:e979170e02e7 4145 break;
ashleymills 0:e979170e02e7 4146
ashleymills 0:e979170e02e7 4147 default:
ashleymills 0:e979170e02e7 4148 CYASSL_ERROR(UNKNOWN_RECORD_TYPE);
ashleymills 0:e979170e02e7 4149 return UNKNOWN_RECORD_TYPE;
ashleymills 0:e979170e02e7 4150 }
ashleymills 0:e979170e02e7 4151
ashleymills 0:e979170e02e7 4152 ssl->options.processReply = doProcessInit;
ashleymills 0:e979170e02e7 4153
ashleymills 0:e979170e02e7 4154 /* input exhausted? */
ashleymills 0:e979170e02e7 4155 if (ssl->buffers.inputBuffer.idx == ssl->buffers.inputBuffer.length)
ashleymills 0:e979170e02e7 4156 return 0;
ashleymills 0:e979170e02e7 4157 /* more messages per record */
ashleymills 0:e979170e02e7 4158 else if ((ssl->buffers.inputBuffer.idx - startIdx) < ssl->curSize) {
ashleymills 0:e979170e02e7 4159 CYASSL_MSG("More messages in record");
ashleymills 0:e979170e02e7 4160 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4161 /* read-ahead but dtls doesn't bundle messages per record */
ashleymills 0:e979170e02e7 4162 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 4163 ssl->options.processReply = doProcessInit;
ashleymills 0:e979170e02e7 4164 continue;
ashleymills 0:e979170e02e7 4165 }
ashleymills 0:e979170e02e7 4166 #endif
ashleymills 0:e979170e02e7 4167 ssl->options.processReply = runProcessingOneMessage;
ashleymills 0:e979170e02e7 4168 continue;
ashleymills 0:e979170e02e7 4169 }
ashleymills 0:e979170e02e7 4170 /* more records */
ashleymills 0:e979170e02e7 4171 else {
ashleymills 0:e979170e02e7 4172 CYASSL_MSG("More records in input");
ashleymills 0:e979170e02e7 4173 ssl->options.processReply = doProcessInit;
ashleymills 0:e979170e02e7 4174 continue;
ashleymills 0:e979170e02e7 4175 }
ashleymills 0:e979170e02e7 4176 default:
ashleymills 0:e979170e02e7 4177 CYASSL_MSG("Bad process input state, programming error");
ashleymills 0:e979170e02e7 4178 return INPUT_CASE_ERROR;
ashleymills 0:e979170e02e7 4179 }
ashleymills 0:e979170e02e7 4180 }
ashleymills 0:e979170e02e7 4181 }
ashleymills 0:e979170e02e7 4182
ashleymills 0:e979170e02e7 4183
ashleymills 0:e979170e02e7 4184 int SendChangeCipher(CYASSL* ssl)
ashleymills 0:e979170e02e7 4185 {
ashleymills 0:e979170e02e7 4186 byte *output;
ashleymills 0:e979170e02e7 4187 int sendSz = RECORD_HEADER_SZ + ENUM_LEN;
ashleymills 0:e979170e02e7 4188 int idx = RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 4189 int ret;
ashleymills 0:e979170e02e7 4190
ashleymills 0:e979170e02e7 4191 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4192 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 4193 sendSz += DTLS_RECORD_EXTRA;
ashleymills 0:e979170e02e7 4194 idx += DTLS_RECORD_EXTRA;
ashleymills 0:e979170e02e7 4195 }
ashleymills 0:e979170e02e7 4196 #endif
ashleymills 0:e979170e02e7 4197
ashleymills 0:e979170e02e7 4198 /* check for avalaible size */
ashleymills 0:e979170e02e7 4199 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
ashleymills 0:e979170e02e7 4200 return ret;
ashleymills 0:e979170e02e7 4201
ashleymills 0:e979170e02e7 4202 /* get ouput buffer */
ashleymills 0:e979170e02e7 4203 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 4204 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 4205
ashleymills 0:e979170e02e7 4206 AddRecordHeader(output, 1, change_cipher_spec, ssl);
ashleymills 0:e979170e02e7 4207
ashleymills 0:e979170e02e7 4208 output[idx] = 1; /* turn it on */
ashleymills 0:e979170e02e7 4209
ashleymills 0:e979170e02e7 4210 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4211 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 4212 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:e979170e02e7 4213 return ret;
ashleymills 0:e979170e02e7 4214 }
ashleymills 0:e979170e02e7 4215 #endif
ashleymills 0:e979170e02e7 4216 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 4217 if (ssl->hsInfoOn) AddPacketName("ChangeCipher", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 4218 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 4219 AddPacketInfo("ChangeCipher", &ssl->timeoutInfo, output, sendSz,
ashleymills 0:e979170e02e7 4220 ssl->heap);
ashleymills 0:e979170e02e7 4221 #endif
ashleymills 0:e979170e02e7 4222 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:e979170e02e7 4223
ashleymills 0:e979170e02e7 4224 if (ssl->options.groupMessages)
ashleymills 0:e979170e02e7 4225 return 0;
ashleymills 0:e979170e02e7 4226 else
ashleymills 0:e979170e02e7 4227 return SendBuffered(ssl);
ashleymills 0:e979170e02e7 4228 }
ashleymills 0:e979170e02e7 4229
ashleymills 0:e979170e02e7 4230
ashleymills 0:e979170e02e7 4231 static INLINE const byte* GetMacSecret(CYASSL* ssl, int verify)
ashleymills 0:e979170e02e7 4232 {
ashleymills 0:e979170e02e7 4233 if ( (ssl->options.side == CLIENT_END && !verify) ||
ashleymills 0:e979170e02e7 4234 (ssl->options.side == SERVER_END && verify) )
ashleymills 0:e979170e02e7 4235 return ssl->keys.client_write_MAC_secret;
ashleymills 0:e979170e02e7 4236 else
ashleymills 0:e979170e02e7 4237 return ssl->keys.server_write_MAC_secret;
ashleymills 0:e979170e02e7 4238 }
ashleymills 0:e979170e02e7 4239
ashleymills 0:e979170e02e7 4240 #ifndef NO_OLD_TLS
ashleymills 0:e979170e02e7 4241 static void Hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
ashleymills 0:e979170e02e7 4242 int content, int verify)
ashleymills 0:e979170e02e7 4243 {
ashleymills 0:e979170e02e7 4244 byte result[SHA256_DIGEST_SIZE]; /* max possible sizes */
ashleymills 0:e979170e02e7 4245 word32 digestSz = ssl->specs.hash_size; /* actual sizes */
ashleymills 0:e979170e02e7 4246 word32 padSz = ssl->specs.pad_size;
ashleymills 0:e979170e02e7 4247
ashleymills 0:e979170e02e7 4248 Md5 md5;
ashleymills 0:e979170e02e7 4249 Sha sha;
ashleymills 0:e979170e02e7 4250
ashleymills 0:e979170e02e7 4251 /* data */
ashleymills 0:e979170e02e7 4252 byte seq[SEQ_SZ];
ashleymills 0:e979170e02e7 4253 byte conLen[ENUM_LEN + LENGTH_SZ]; /* content & length */
ashleymills 0:e979170e02e7 4254 const byte* macSecret = GetMacSecret(ssl, verify);
ashleymills 0:e979170e02e7 4255
ashleymills 0:e979170e02e7 4256 XMEMSET(seq, 0, SEQ_SZ);
ashleymills 0:e979170e02e7 4257 conLen[0] = (byte)content;
ashleymills 0:e979170e02e7 4258 c16toa((word16)sz, &conLen[ENUM_LEN]);
ashleymills 0:e979170e02e7 4259 c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]);
ashleymills 0:e979170e02e7 4260
ashleymills 0:e979170e02e7 4261 if (ssl->specs.mac_algorithm == md5_mac) {
ashleymills 0:e979170e02e7 4262 InitMd5(&md5);
ashleymills 0:e979170e02e7 4263 /* inner */
ashleymills 0:e979170e02e7 4264 Md5Update(&md5, macSecret, digestSz);
ashleymills 0:e979170e02e7 4265 Md5Update(&md5, PAD1, padSz);
ashleymills 0:e979170e02e7 4266 Md5Update(&md5, seq, SEQ_SZ);
ashleymills 0:e979170e02e7 4267 Md5Update(&md5, conLen, sizeof(conLen));
ashleymills 0:e979170e02e7 4268 /* in buffer */
ashleymills 0:e979170e02e7 4269 Md5Update(&md5, in, sz);
ashleymills 0:e979170e02e7 4270 Md5Final(&md5, result);
ashleymills 0:e979170e02e7 4271 /* outer */
ashleymills 0:e979170e02e7 4272 Md5Update(&md5, macSecret, digestSz);
ashleymills 0:e979170e02e7 4273 Md5Update(&md5, PAD2, padSz);
ashleymills 0:e979170e02e7 4274 Md5Update(&md5, result, digestSz);
ashleymills 0:e979170e02e7 4275 Md5Final(&md5, digest);
ashleymills 0:e979170e02e7 4276 }
ashleymills 0:e979170e02e7 4277 else {
ashleymills 0:e979170e02e7 4278 InitSha(&sha);
ashleymills 0:e979170e02e7 4279 /* inner */
ashleymills 0:e979170e02e7 4280 ShaUpdate(&sha, macSecret, digestSz);
ashleymills 0:e979170e02e7 4281 ShaUpdate(&sha, PAD1, padSz);
ashleymills 0:e979170e02e7 4282 ShaUpdate(&sha, seq, SEQ_SZ);
ashleymills 0:e979170e02e7 4283 ShaUpdate(&sha, conLen, sizeof(conLen));
ashleymills 0:e979170e02e7 4284 /* in buffer */
ashleymills 0:e979170e02e7 4285 ShaUpdate(&sha, in, sz);
ashleymills 0:e979170e02e7 4286 ShaFinal(&sha, result);
ashleymills 0:e979170e02e7 4287 /* outer */
ashleymills 0:e979170e02e7 4288 ShaUpdate(&sha, macSecret, digestSz);
ashleymills 0:e979170e02e7 4289 ShaUpdate(&sha, PAD2, padSz);
ashleymills 0:e979170e02e7 4290 ShaUpdate(&sha, result, digestSz);
ashleymills 0:e979170e02e7 4291 ShaFinal(&sha, digest);
ashleymills 0:e979170e02e7 4292 }
ashleymills 0:e979170e02e7 4293 }
ashleymills 0:e979170e02e7 4294
ashleymills 0:e979170e02e7 4295
ashleymills 0:e979170e02e7 4296 static void BuildMD5_CertVerify(CYASSL* ssl, byte* digest)
ashleymills 0:e979170e02e7 4297 {
ashleymills 0:e979170e02e7 4298 byte md5_result[MD5_DIGEST_SIZE];
ashleymills 0:e979170e02e7 4299
ashleymills 0:e979170e02e7 4300 /* make md5 inner */
ashleymills 0:e979170e02e7 4301 Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:e979170e02e7 4302 Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
ashleymills 0:e979170e02e7 4303 Md5Final(&ssl->hashMd5, md5_result);
ashleymills 0:e979170e02e7 4304
ashleymills 0:e979170e02e7 4305 /* make md5 outer */
ashleymills 0:e979170e02e7 4306 Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:e979170e02e7 4307 Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
ashleymills 0:e979170e02e7 4308 Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
ashleymills 0:e979170e02e7 4309
ashleymills 0:e979170e02e7 4310 Md5Final(&ssl->hashMd5, digest);
ashleymills 0:e979170e02e7 4311 }
ashleymills 0:e979170e02e7 4312
ashleymills 0:e979170e02e7 4313
ashleymills 0:e979170e02e7 4314 static void BuildSHA_CertVerify(CYASSL* ssl, byte* digest)
ashleymills 0:e979170e02e7 4315 {
ashleymills 0:e979170e02e7 4316 byte sha_result[SHA_DIGEST_SIZE];
ashleymills 0:e979170e02e7 4317
ashleymills 0:e979170e02e7 4318 /* make sha inner */
ashleymills 0:e979170e02e7 4319 ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:e979170e02e7 4320 ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
ashleymills 0:e979170e02e7 4321 ShaFinal(&ssl->hashSha, sha_result);
ashleymills 0:e979170e02e7 4322
ashleymills 0:e979170e02e7 4323 /* make sha outer */
ashleymills 0:e979170e02e7 4324 ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
ashleymills 0:e979170e02e7 4325 ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
ashleymills 0:e979170e02e7 4326 ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
ashleymills 0:e979170e02e7 4327
ashleymills 0:e979170e02e7 4328 ShaFinal(&ssl->hashSha, digest);
ashleymills 0:e979170e02e7 4329 }
ashleymills 0:e979170e02e7 4330
ashleymills 0:e979170e02e7 4331
ashleymills 0:e979170e02e7 4332 static void BuildCertHashes(CYASSL* ssl, Hashes* hashes)
ashleymills 0:e979170e02e7 4333 {
ashleymills 0:e979170e02e7 4334 /* store current states, building requires get_digest which resets state */
ashleymills 0:e979170e02e7 4335 Md5 md5 = ssl->hashMd5;
ashleymills 0:e979170e02e7 4336 Sha sha = ssl->hashSha;
ashleymills 0:e979170e02e7 4337 #ifndef NO_SHA256 /* for possible future changes */
ashleymills 0:e979170e02e7 4338 Sha256 sha256;
ashleymills 0:e979170e02e7 4339 InitSha256(&sha256);
ashleymills 0:e979170e02e7 4340 if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:e979170e02e7 4341 sha256 = ssl->hashSha256;
ashleymills 0:e979170e02e7 4342 #endif
ashleymills 0:e979170e02e7 4343
ashleymills 0:e979170e02e7 4344 if (ssl->options.tls) {
ashleymills 0:e979170e02e7 4345 Md5Final(&ssl->hashMd5, hashes->md5);
ashleymills 0:e979170e02e7 4346 ShaFinal(&ssl->hashSha, hashes->sha);
ashleymills 0:e979170e02e7 4347 }
ashleymills 0:e979170e02e7 4348 else {
ashleymills 0:e979170e02e7 4349 BuildMD5_CertVerify(ssl, hashes->md5);
ashleymills 0:e979170e02e7 4350 BuildSHA_CertVerify(ssl, hashes->sha);
ashleymills 0:e979170e02e7 4351 }
ashleymills 0:e979170e02e7 4352
ashleymills 0:e979170e02e7 4353 /* restore */
ashleymills 0:e979170e02e7 4354 ssl->hashMd5 = md5;
ashleymills 0:e979170e02e7 4355 ssl->hashSha = sha;
ashleymills 0:e979170e02e7 4356 #ifndef NO_SHA256
ashleymills 0:e979170e02e7 4357 if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:e979170e02e7 4358 ssl->hashSha256 = sha256;
ashleymills 0:e979170e02e7 4359 #endif
ashleymills 0:e979170e02e7 4360 }
ashleymills 0:e979170e02e7 4361 #endif
ashleymills 0:e979170e02e7 4362
ashleymills 0:e979170e02e7 4363 /* Build SSL Message, encrypted */
ashleymills 0:e979170e02e7 4364 static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz,
ashleymills 0:e979170e02e7 4365 int type)
ashleymills 0:e979170e02e7 4366 {
ashleymills 0:e979170e02e7 4367 word32 digestSz = ssl->specs.hash_size;
ashleymills 0:e979170e02e7 4368 word32 sz = RECORD_HEADER_SZ + inSz + digestSz;
ashleymills 0:e979170e02e7 4369 word32 pad = 0, i;
ashleymills 0:e979170e02e7 4370 word32 idx = RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 4371 word32 ivSz = 0; /* TLSv1.1 IV */
ashleymills 0:e979170e02e7 4372 word32 headerSz = RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 4373 word16 size;
ashleymills 0:e979170e02e7 4374 byte iv[AES_BLOCK_SIZE]; /* max size */
ashleymills 0:e979170e02e7 4375 int ret = 0;
ashleymills 0:e979170e02e7 4376
ashleymills 0:e979170e02e7 4377 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4378 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 4379 sz += DTLS_RECORD_EXTRA;
ashleymills 0:e979170e02e7 4380 idx += DTLS_RECORD_EXTRA;
ashleymills 0:e979170e02e7 4381 headerSz += DTLS_RECORD_EXTRA;
ashleymills 0:e979170e02e7 4382 }
ashleymills 0:e979170e02e7 4383 #endif
ashleymills 0:e979170e02e7 4384
ashleymills 0:e979170e02e7 4385 if (ssl->specs.cipher_type == block) {
ashleymills 0:e979170e02e7 4386 word32 blockSz = ssl->specs.block_size;
ashleymills 0:e979170e02e7 4387 if (ssl->options.tls1_1) {
ashleymills 0:e979170e02e7 4388 ivSz = blockSz;
ashleymills 0:e979170e02e7 4389 sz += ivSz;
ashleymills 0:e979170e02e7 4390 RNG_GenerateBlock(ssl->rng, iv, ivSz);
ashleymills 0:e979170e02e7 4391 }
ashleymills 0:e979170e02e7 4392 sz += 1; /* pad byte */
ashleymills 0:e979170e02e7 4393 pad = (sz - headerSz) % blockSz;
ashleymills 0:e979170e02e7 4394 pad = blockSz - pad;
ashleymills 0:e979170e02e7 4395 sz += pad;
ashleymills 0:e979170e02e7 4396 }
ashleymills 0:e979170e02e7 4397
ashleymills 0:e979170e02e7 4398 #ifdef HAVE_AEAD
ashleymills 0:e979170e02e7 4399 if (ssl->specs.cipher_type == aead) {
ashleymills 0:e979170e02e7 4400 ivSz = AEAD_EXP_IV_SZ;
ashleymills 0:e979170e02e7 4401 sz += (ivSz + 16 - digestSz);
ashleymills 0:e979170e02e7 4402 XMEMCPY(iv, ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
ashleymills 0:e979170e02e7 4403 }
ashleymills 0:e979170e02e7 4404 #endif
ashleymills 0:e979170e02e7 4405 size = (word16)(sz - headerSz); /* include mac and digest */
ashleymills 0:e979170e02e7 4406 AddRecordHeader(output, size, (byte)type, ssl);
ashleymills 0:e979170e02e7 4407
ashleymills 0:e979170e02e7 4408 /* write to output */
ashleymills 0:e979170e02e7 4409 if (ivSz) {
ashleymills 0:e979170e02e7 4410 XMEMCPY(output + idx, iv, min(ivSz, sizeof(iv)));
ashleymills 0:e979170e02e7 4411 idx += ivSz;
ashleymills 0:e979170e02e7 4412 }
ashleymills 0:e979170e02e7 4413 XMEMCPY(output + idx, input, inSz);
ashleymills 0:e979170e02e7 4414 idx += inSz;
ashleymills 0:e979170e02e7 4415
ashleymills 0:e979170e02e7 4416 if (type == handshake) {
ashleymills 0:e979170e02e7 4417 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4418 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 4419 if ((ret = DtlsPoolSave(ssl, output, headerSz+inSz)) != 0)
ashleymills 0:e979170e02e7 4420 return ret;
ashleymills 0:e979170e02e7 4421 }
ashleymills 0:e979170e02e7 4422 #endif
ashleymills 0:e979170e02e7 4423 HashOutput(ssl, output, headerSz + inSz, ivSz);
ashleymills 0:e979170e02e7 4424 }
ashleymills 0:e979170e02e7 4425 if (ssl->specs.cipher_type != aead) {
ashleymills 0:e979170e02e7 4426 ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz, type, 0);
ashleymills 0:e979170e02e7 4427 idx += digestSz;
ashleymills 0:e979170e02e7 4428 }
ashleymills 0:e979170e02e7 4429
ashleymills 0:e979170e02e7 4430 if (ssl->specs.cipher_type == block)
ashleymills 0:e979170e02e7 4431 for (i = 0; i <= pad; i++)
ashleymills 0:e979170e02e7 4432 output[idx++] = (byte)pad; /* pad byte gets pad value too */
ashleymills 0:e979170e02e7 4433
ashleymills 0:e979170e02e7 4434 if ( (ret = Encrypt(ssl, output + headerSz, output + headerSz, size)) != 0)
ashleymills 0:e979170e02e7 4435 return ret;
ashleymills 0:e979170e02e7 4436
ashleymills 0:e979170e02e7 4437 return sz;
ashleymills 0:e979170e02e7 4438 }
ashleymills 0:e979170e02e7 4439
ashleymills 0:e979170e02e7 4440
ashleymills 0:e979170e02e7 4441 int SendFinished(CYASSL* ssl)
ashleymills 0:e979170e02e7 4442 {
ashleymills 0:e979170e02e7 4443 int sendSz,
ashleymills 0:e979170e02e7 4444 finishedSz = ssl->options.tls ? TLS_FINISHED_SZ :
ashleymills 0:e979170e02e7 4445 FINISHED_SZ;
ashleymills 0:e979170e02e7 4446 byte input[FINISHED_SZ + DTLS_HANDSHAKE_HEADER_SZ]; /* max */
ashleymills 0:e979170e02e7 4447 byte *output;
ashleymills 0:e979170e02e7 4448 Hashes* hashes;
ashleymills 0:e979170e02e7 4449 int ret;
ashleymills 0:e979170e02e7 4450 int headerSz = HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 4451
ashleymills 0:e979170e02e7 4452
ashleymills 0:e979170e02e7 4453 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4454 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 4455 headerSz += DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 4456 ssl->keys.dtls_epoch++;
ashleymills 0:e979170e02e7 4457 ssl->keys.dtls_sequence_number = 0; /* reset after epoch change */
ashleymills 0:e979170e02e7 4458 }
ashleymills 0:e979170e02e7 4459 #endif
ashleymills 0:e979170e02e7 4460
ashleymills 0:e979170e02e7 4461 /* check for avalaible size */
ashleymills 0:e979170e02e7 4462 if ((ret = CheckAvalaibleSize(ssl, sizeof(input) + MAX_MSG_EXTRA)) != 0)
ashleymills 0:e979170e02e7 4463 return ret;
ashleymills 0:e979170e02e7 4464
ashleymills 0:e979170e02e7 4465 /* get ouput buffer */
ashleymills 0:e979170e02e7 4466 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 4467 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 4468
ashleymills 0:e979170e02e7 4469 AddHandShakeHeader(input, finishedSz, finished, ssl);
ashleymills 0:e979170e02e7 4470
ashleymills 0:e979170e02e7 4471 /* make finished hashes */
ashleymills 0:e979170e02e7 4472 hashes = (Hashes*)&input[headerSz];
ashleymills 0:e979170e02e7 4473 BuildFinished(ssl, hashes, ssl->options.side == CLIENT_END ? client :
ashleymills 0:e979170e02e7 4474 server);
ashleymills 0:e979170e02e7 4475
ashleymills 0:e979170e02e7 4476 if ( (sendSz = BuildMessage(ssl, output, input, headerSz +
ashleymills 0:e979170e02e7 4477 finishedSz, handshake)) < 0)
ashleymills 0:e979170e02e7 4478 return BUILD_MSG_ERROR;
ashleymills 0:e979170e02e7 4479
ashleymills 0:e979170e02e7 4480 if (!ssl->options.resuming) {
ashleymills 0:e979170e02e7 4481 #ifndef NO_SESSION_CACHE
ashleymills 0:e979170e02e7 4482 AddSession(ssl); /* just try */
ashleymills 0:e979170e02e7 4483 #endif
ashleymills 0:e979170e02e7 4484 if (ssl->options.side == CLIENT_END)
ashleymills 0:e979170e02e7 4485 BuildFinished(ssl, &ssl->verifyHashes, server);
ashleymills 0:e979170e02e7 4486 else
ashleymills 0:e979170e02e7 4487 ssl->options.handShakeState = HANDSHAKE_DONE;
ashleymills 0:e979170e02e7 4488 }
ashleymills 0:e979170e02e7 4489 else {
ashleymills 0:e979170e02e7 4490 if (ssl->options.side == CLIENT_END)
ashleymills 0:e979170e02e7 4491 ssl->options.handShakeState = HANDSHAKE_DONE;
ashleymills 0:e979170e02e7 4492 else
ashleymills 0:e979170e02e7 4493 BuildFinished(ssl, &ssl->verifyHashes, client);
ashleymills 0:e979170e02e7 4494 }
ashleymills 0:e979170e02e7 4495 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4496 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 4497 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:e979170e02e7 4498 return ret;
ashleymills 0:e979170e02e7 4499 }
ashleymills 0:e979170e02e7 4500 #endif
ashleymills 0:e979170e02e7 4501
ashleymills 0:e979170e02e7 4502 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 4503 if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 4504 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 4505 AddPacketInfo("Finished", &ssl->timeoutInfo, output, sendSz,
ashleymills 0:e979170e02e7 4506 ssl->heap);
ashleymills 0:e979170e02e7 4507 #endif
ashleymills 0:e979170e02e7 4508
ashleymills 0:e979170e02e7 4509 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:e979170e02e7 4510
ashleymills 0:e979170e02e7 4511 return SendBuffered(ssl);
ashleymills 0:e979170e02e7 4512 }
ashleymills 0:e979170e02e7 4513
ashleymills 0:e979170e02e7 4514 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 4515 int SendCertificate(CYASSL* ssl)
ashleymills 0:e979170e02e7 4516 {
ashleymills 0:e979170e02e7 4517 int sendSz, length, ret = 0;
ashleymills 0:e979170e02e7 4518 word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 4519 word32 certSz, listSz;
ashleymills 0:e979170e02e7 4520 byte* output = 0;
ashleymills 0:e979170e02e7 4521
ashleymills 0:e979170e02e7 4522 if (ssl->options.usingPSK_cipher) return 0; /* not needed */
ashleymills 0:e979170e02e7 4523
ashleymills 0:e979170e02e7 4524 if (ssl->options.sendVerify == SEND_BLANK_CERT) {
ashleymills 0:e979170e02e7 4525 certSz = 0;
ashleymills 0:e979170e02e7 4526 length = CERT_HEADER_SZ;
ashleymills 0:e979170e02e7 4527 listSz = 0;
ashleymills 0:e979170e02e7 4528 }
ashleymills 0:e979170e02e7 4529 else {
ashleymills 0:e979170e02e7 4530 certSz = ssl->buffers.certificate.length;
ashleymills 0:e979170e02e7 4531 /* list + cert size */
ashleymills 0:e979170e02e7 4532 length = certSz + 2 * CERT_HEADER_SZ;
ashleymills 0:e979170e02e7 4533 listSz = certSz + CERT_HEADER_SZ;
ashleymills 0:e979170e02e7 4534
ashleymills 0:e979170e02e7 4535 /* may need to send rest of chain, already has leading size(s) */
ashleymills 0:e979170e02e7 4536 if (ssl->buffers.certChain.buffer) {
ashleymills 0:e979170e02e7 4537 length += ssl->buffers.certChain.length;
ashleymills 0:e979170e02e7 4538 listSz += ssl->buffers.certChain.length;
ashleymills 0:e979170e02e7 4539 }
ashleymills 0:e979170e02e7 4540 }
ashleymills 0:e979170e02e7 4541 sendSz = length + RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 4542
ashleymills 0:e979170e02e7 4543 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4544 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 4545 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 4546 i += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 4547 }
ashleymills 0:e979170e02e7 4548 #endif
ashleymills 0:e979170e02e7 4549
ashleymills 0:e979170e02e7 4550 /* check for avalaible size */
ashleymills 0:e979170e02e7 4551 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
ashleymills 0:e979170e02e7 4552 return ret;
ashleymills 0:e979170e02e7 4553
ashleymills 0:e979170e02e7 4554 /* get ouput buffer */
ashleymills 0:e979170e02e7 4555 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 4556 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 4557
ashleymills 0:e979170e02e7 4558 AddHeaders(output, length, certificate, ssl);
ashleymills 0:e979170e02e7 4559
ashleymills 0:e979170e02e7 4560 /* list total */
ashleymills 0:e979170e02e7 4561 c32to24(listSz, output + i);
ashleymills 0:e979170e02e7 4562 i += CERT_HEADER_SZ;
ashleymills 0:e979170e02e7 4563
ashleymills 0:e979170e02e7 4564 /* member */
ashleymills 0:e979170e02e7 4565 if (certSz) {
ashleymills 0:e979170e02e7 4566 c32to24(certSz, output + i);
ashleymills 0:e979170e02e7 4567 i += CERT_HEADER_SZ;
ashleymills 0:e979170e02e7 4568 XMEMCPY(output + i, ssl->buffers.certificate.buffer, certSz);
ashleymills 0:e979170e02e7 4569 i += certSz;
ashleymills 0:e979170e02e7 4570
ashleymills 0:e979170e02e7 4571 /* send rest of chain? */
ashleymills 0:e979170e02e7 4572 if (ssl->buffers.certChain.buffer) {
ashleymills 0:e979170e02e7 4573 XMEMCPY(output + i, ssl->buffers.certChain.buffer,
ashleymills 0:e979170e02e7 4574 ssl->buffers.certChain.length);
ashleymills 0:e979170e02e7 4575 /* if add more to output adjust i
ashleymills 0:e979170e02e7 4576 i += ssl->buffers.certChain.length; */
ashleymills 0:e979170e02e7 4577 }
ashleymills 0:e979170e02e7 4578 }
ashleymills 0:e979170e02e7 4579 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4580 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 4581 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:e979170e02e7 4582 return ret;
ashleymills 0:e979170e02e7 4583 }
ashleymills 0:e979170e02e7 4584 #endif
ashleymills 0:e979170e02e7 4585 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:e979170e02e7 4586 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 4587 if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 4588 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 4589 AddPacketInfo("Certificate", &ssl->timeoutInfo, output, sendSz,
ashleymills 0:e979170e02e7 4590 ssl->heap);
ashleymills 0:e979170e02e7 4591 #endif
ashleymills 0:e979170e02e7 4592
ashleymills 0:e979170e02e7 4593 if (ssl->options.side == SERVER_END)
ashleymills 0:e979170e02e7 4594 ssl->options.serverState = SERVER_CERT_COMPLETE;
ashleymills 0:e979170e02e7 4595
ashleymills 0:e979170e02e7 4596 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:e979170e02e7 4597 if (ssl->options.groupMessages)
ashleymills 0:e979170e02e7 4598 return 0;
ashleymills 0:e979170e02e7 4599 else
ashleymills 0:e979170e02e7 4600 return SendBuffered(ssl);
ashleymills 0:e979170e02e7 4601 }
ashleymills 0:e979170e02e7 4602
ashleymills 0:e979170e02e7 4603
ashleymills 0:e979170e02e7 4604 int SendCertificateRequest(CYASSL* ssl)
ashleymills 0:e979170e02e7 4605 {
ashleymills 0:e979170e02e7 4606 byte *output;
ashleymills 0:e979170e02e7 4607 int ret;
ashleymills 0:e979170e02e7 4608 int sendSz;
ashleymills 0:e979170e02e7 4609 word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 4610
ashleymills 0:e979170e02e7 4611 int typeTotal = 1; /* only rsa for now */
ashleymills 0:e979170e02e7 4612 int reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ; /* add auth later */
ashleymills 0:e979170e02e7 4613
ashleymills 0:e979170e02e7 4614 if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:e979170e02e7 4615 reqSz += LENGTH_SZ + HASH_SIG_SIZE;
ashleymills 0:e979170e02e7 4616
ashleymills 0:e979170e02e7 4617 if (ssl->options.usingPSK_cipher) return 0; /* not needed */
ashleymills 0:e979170e02e7 4618
ashleymills 0:e979170e02e7 4619 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
ashleymills 0:e979170e02e7 4620
ashleymills 0:e979170e02e7 4621 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4622 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 4623 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 4624 i += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 4625 }
ashleymills 0:e979170e02e7 4626 #endif
ashleymills 0:e979170e02e7 4627 /* check for avalaible size */
ashleymills 0:e979170e02e7 4628 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
ashleymills 0:e979170e02e7 4629 return ret;
ashleymills 0:e979170e02e7 4630
ashleymills 0:e979170e02e7 4631 /* get ouput buffer */
ashleymills 0:e979170e02e7 4632 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 4633 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 4634
ashleymills 0:e979170e02e7 4635 AddHeaders(output, reqSz, certificate_request, ssl);
ashleymills 0:e979170e02e7 4636
ashleymills 0:e979170e02e7 4637 /* write to output */
ashleymills 0:e979170e02e7 4638 output[i++] = (byte)typeTotal; /* # of types */
ashleymills 0:e979170e02e7 4639 output[i++] = rsa_sign;
ashleymills 0:e979170e02e7 4640
ashleymills 0:e979170e02e7 4641 /* supported hash/sig */
ashleymills 0:e979170e02e7 4642 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:e979170e02e7 4643 c16toa(HASH_SIG_SIZE, &output[i]);
ashleymills 0:e979170e02e7 4644 i += LENGTH_SZ;
ashleymills 0:e979170e02e7 4645
ashleymills 0:e979170e02e7 4646 output[i++] = sha_mac; /* hash */
ashleymills 0:e979170e02e7 4647 output[i++] = rsa_sa_algo; /* sig */
ashleymills 0:e979170e02e7 4648 }
ashleymills 0:e979170e02e7 4649
ashleymills 0:e979170e02e7 4650 c16toa(0, &output[i]); /* auth's */
ashleymills 0:e979170e02e7 4651 /* if add more to output, adjust i
ashleymills 0:e979170e02e7 4652 i += REQ_HEADER_SZ; */
ashleymills 0:e979170e02e7 4653
ashleymills 0:e979170e02e7 4654 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4655 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 4656 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:e979170e02e7 4657 return ret;
ashleymills 0:e979170e02e7 4658 }
ashleymills 0:e979170e02e7 4659 #endif
ashleymills 0:e979170e02e7 4660 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:e979170e02e7 4661
ashleymills 0:e979170e02e7 4662 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 4663 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 4664 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 4665 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 4666 AddPacketInfo("CertificateRequest", &ssl->timeoutInfo, output,
ashleymills 0:e979170e02e7 4667 sendSz, ssl->heap);
ashleymills 0:e979170e02e7 4668 #endif
ashleymills 0:e979170e02e7 4669 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:e979170e02e7 4670 if (ssl->options.groupMessages)
ashleymills 0:e979170e02e7 4671 return 0;
ashleymills 0:e979170e02e7 4672 else
ashleymills 0:e979170e02e7 4673 return SendBuffered(ssl);
ashleymills 0:e979170e02e7 4674 }
ashleymills 0:e979170e02e7 4675 #endif /* !NO_CERTS */
ashleymills 0:e979170e02e7 4676
ashleymills 0:e979170e02e7 4677
ashleymills 0:e979170e02e7 4678 int SendData(CYASSL* ssl, const void* data, int sz)
ashleymills 0:e979170e02e7 4679 {
ashleymills 0:e979170e02e7 4680 int sent = 0, /* plainText size */
ashleymills 0:e979170e02e7 4681 sendSz,
ashleymills 0:e979170e02e7 4682 ret;
ashleymills 0:e979170e02e7 4683
ashleymills 0:e979170e02e7 4684 if (ssl->error == WANT_WRITE)
ashleymills 0:e979170e02e7 4685 ssl->error = 0;
ashleymills 0:e979170e02e7 4686
ashleymills 0:e979170e02e7 4687 if (ssl->options.handShakeState != HANDSHAKE_DONE) {
ashleymills 0:e979170e02e7 4688 int err;
ashleymills 0:e979170e02e7 4689 CYASSL_MSG("handshake not complete, trying to finish");
ashleymills 0:e979170e02e7 4690 if ( (err = CyaSSL_negotiate(ssl)) != 0)
ashleymills 0:e979170e02e7 4691 return err;
ashleymills 0:e979170e02e7 4692 }
ashleymills 0:e979170e02e7 4693
ashleymills 0:e979170e02e7 4694 /* last time system socket output buffer was full, try again to send */
ashleymills 0:e979170e02e7 4695 if (ssl->buffers.outputBuffer.length > 0) {
ashleymills 0:e979170e02e7 4696 CYASSL_MSG("output buffer was full, trying to send again");
ashleymills 0:e979170e02e7 4697 if ( (ssl->error = SendBuffered(ssl)) < 0) {
ashleymills 0:e979170e02e7 4698 CYASSL_ERROR(ssl->error);
ashleymills 0:e979170e02e7 4699 if (ssl->error == SOCKET_ERROR_E && ssl->options.connReset)
ashleymills 0:e979170e02e7 4700 return 0; /* peer reset */
ashleymills 0:e979170e02e7 4701 return ssl->error;
ashleymills 0:e979170e02e7 4702 }
ashleymills 0:e979170e02e7 4703 else {
ashleymills 0:e979170e02e7 4704 /* advance sent to previous sent + plain size just sent */
ashleymills 0:e979170e02e7 4705 sent = ssl->buffers.prevSent + ssl->buffers.plainSz;
ashleymills 0:e979170e02e7 4706 CYASSL_MSG("sent write buffered data");
ashleymills 0:e979170e02e7 4707 }
ashleymills 0:e979170e02e7 4708 }
ashleymills 0:e979170e02e7 4709
ashleymills 0:e979170e02e7 4710 for (;;) {
ashleymills 0:e979170e02e7 4711 int len = min(sz - sent, OUTPUT_RECORD_SIZE);
ashleymills 0:e979170e02e7 4712 byte* out;
ashleymills 0:e979170e02e7 4713 byte* sendBuffer = (byte*)data + sent; /* may switch on comp */
ashleymills 0:e979170e02e7 4714 int buffSz = len; /* may switch on comp */
ashleymills 0:e979170e02e7 4715 #ifdef HAVE_LIBZ
ashleymills 0:e979170e02e7 4716 byte comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
ashleymills 0:e979170e02e7 4717 #endif
ashleymills 0:e979170e02e7 4718
ashleymills 0:e979170e02e7 4719 if (sent == sz) break;
ashleymills 0:e979170e02e7 4720
ashleymills 0:e979170e02e7 4721 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4722 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 4723 len = min(len, MAX_UDP_SIZE);
ashleymills 0:e979170e02e7 4724 buffSz = len;
ashleymills 0:e979170e02e7 4725 }
ashleymills 0:e979170e02e7 4726 #endif
ashleymills 0:e979170e02e7 4727
ashleymills 0:e979170e02e7 4728 /* check for avalaible size */
ashleymills 0:e979170e02e7 4729 if ((ret = CheckAvalaibleSize(ssl, len + COMP_EXTRA +
ashleymills 0:e979170e02e7 4730 MAX_MSG_EXTRA)) != 0)
ashleymills 0:e979170e02e7 4731 return ret;
ashleymills 0:e979170e02e7 4732
ashleymills 0:e979170e02e7 4733 /* get ouput buffer */
ashleymills 0:e979170e02e7 4734 out = ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 4735 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 4736
ashleymills 0:e979170e02e7 4737 #ifdef HAVE_LIBZ
ashleymills 0:e979170e02e7 4738 if (ssl->options.usingCompression) {
ashleymills 0:e979170e02e7 4739 buffSz = Compress(ssl, sendBuffer, buffSz, comp, sizeof(comp));
ashleymills 0:e979170e02e7 4740 if (buffSz < 0) {
ashleymills 0:e979170e02e7 4741 return buffSz;
ashleymills 0:e979170e02e7 4742 }
ashleymills 0:e979170e02e7 4743 sendBuffer = comp;
ashleymills 0:e979170e02e7 4744 }
ashleymills 0:e979170e02e7 4745 #endif
ashleymills 0:e979170e02e7 4746 sendSz = BuildMessage(ssl, out, sendBuffer, buffSz,
ashleymills 0:e979170e02e7 4747 application_data);
ashleymills 0:e979170e02e7 4748
ashleymills 0:e979170e02e7 4749 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:e979170e02e7 4750
ashleymills 0:e979170e02e7 4751 if ( (ret = SendBuffered(ssl)) < 0) {
ashleymills 0:e979170e02e7 4752 CYASSL_ERROR(ret);
ashleymills 0:e979170e02e7 4753 /* store for next call if WANT_WRITE or user embedSend() that
ashleymills 0:e979170e02e7 4754 doesn't present like WANT_WRITE */
ashleymills 0:e979170e02e7 4755 ssl->buffers.plainSz = len;
ashleymills 0:e979170e02e7 4756 ssl->buffers.prevSent = sent;
ashleymills 0:e979170e02e7 4757 if (ret == SOCKET_ERROR_E && ssl->options.connReset)
ashleymills 0:e979170e02e7 4758 return 0; /* peer reset */
ashleymills 0:e979170e02e7 4759 return ssl->error = ret;
ashleymills 0:e979170e02e7 4760 }
ashleymills 0:e979170e02e7 4761
ashleymills 0:e979170e02e7 4762 sent += len;
ashleymills 0:e979170e02e7 4763
ashleymills 0:e979170e02e7 4764 /* only one message per attempt */
ashleymills 0:e979170e02e7 4765 if (ssl->options.partialWrite == 1) {
ashleymills 0:e979170e02e7 4766 CYASSL_MSG("Paritial Write on, only sending one record");
ashleymills 0:e979170e02e7 4767 break;
ashleymills 0:e979170e02e7 4768 }
ashleymills 0:e979170e02e7 4769 }
ashleymills 0:e979170e02e7 4770
ashleymills 0:e979170e02e7 4771 return sent;
ashleymills 0:e979170e02e7 4772 }
ashleymills 0:e979170e02e7 4773
ashleymills 0:e979170e02e7 4774 /* process input data */
ashleymills 0:e979170e02e7 4775 int ReceiveData(CYASSL* ssl, byte* output, int sz, int peek)
ashleymills 0:e979170e02e7 4776 {
ashleymills 0:e979170e02e7 4777 int size;
ashleymills 0:e979170e02e7 4778
ashleymills 0:e979170e02e7 4779 CYASSL_ENTER("ReceiveData()");
ashleymills 0:e979170e02e7 4780
ashleymills 0:e979170e02e7 4781 if (ssl->error == WANT_READ)
ashleymills 0:e979170e02e7 4782 ssl->error = 0;
ashleymills 0:e979170e02e7 4783
ashleymills 0:e979170e02e7 4784 if (ssl->options.handShakeState != HANDSHAKE_DONE) {
ashleymills 0:e979170e02e7 4785 int err;
ashleymills 0:e979170e02e7 4786 CYASSL_MSG("Handshake not complete, trying to finish");
ashleymills 0:e979170e02e7 4787 if ( (err = CyaSSL_negotiate(ssl)) != 0)
ashleymills 0:e979170e02e7 4788 return err;
ashleymills 0:e979170e02e7 4789 }
ashleymills 0:e979170e02e7 4790
ashleymills 0:e979170e02e7 4791 while (ssl->buffers.clearOutputBuffer.length == 0)
ashleymills 0:e979170e02e7 4792 if ( (ssl->error = ProcessReply(ssl)) < 0) {
ashleymills 0:e979170e02e7 4793 CYASSL_ERROR(ssl->error);
ashleymills 0:e979170e02e7 4794 if (ssl->error == ZERO_RETURN) {
ashleymills 0:e979170e02e7 4795 CYASSL_MSG("Zero return, no more data coming");
ashleymills 0:e979170e02e7 4796 ssl->options.isClosed = 1;
ashleymills 0:e979170e02e7 4797 return 0; /* no more data coming */
ashleymills 0:e979170e02e7 4798 }
ashleymills 0:e979170e02e7 4799 if (ssl->error == SOCKET_ERROR_E) {
ashleymills 0:e979170e02e7 4800 if (ssl->options.connReset || ssl->options.isClosed) {
ashleymills 0:e979170e02e7 4801 CYASSL_MSG("Peer reset or closed, connection done");
ashleymills 0:e979170e02e7 4802 return 0; /* peer reset or closed */
ashleymills 0:e979170e02e7 4803 }
ashleymills 0:e979170e02e7 4804 }
ashleymills 0:e979170e02e7 4805 return ssl->error;
ashleymills 0:e979170e02e7 4806 }
ashleymills 0:e979170e02e7 4807
ashleymills 0:e979170e02e7 4808 if (sz < (int)ssl->buffers.clearOutputBuffer.length)
ashleymills 0:e979170e02e7 4809 size = sz;
ashleymills 0:e979170e02e7 4810 else
ashleymills 0:e979170e02e7 4811 size = ssl->buffers.clearOutputBuffer.length;
ashleymills 0:e979170e02e7 4812
ashleymills 0:e979170e02e7 4813 XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size);
ashleymills 0:e979170e02e7 4814
ashleymills 0:e979170e02e7 4815 if (peek == 0) {
ashleymills 0:e979170e02e7 4816 ssl->buffers.clearOutputBuffer.length -= size;
ashleymills 0:e979170e02e7 4817 ssl->buffers.clearOutputBuffer.buffer += size;
ashleymills 0:e979170e02e7 4818 }
ashleymills 0:e979170e02e7 4819
ashleymills 0:e979170e02e7 4820 if (ssl->buffers.clearOutputBuffer.length == 0 &&
ashleymills 0:e979170e02e7 4821 ssl->buffers.inputBuffer.dynamicFlag)
ashleymills 0:e979170e02e7 4822 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
ashleymills 0:e979170e02e7 4823
ashleymills 0:e979170e02e7 4824 CYASSL_LEAVE("ReceiveData()", size);
ashleymills 0:e979170e02e7 4825 return size;
ashleymills 0:e979170e02e7 4826 }
ashleymills 0:e979170e02e7 4827
ashleymills 0:e979170e02e7 4828
ashleymills 0:e979170e02e7 4829 /* send alert message */
ashleymills 0:e979170e02e7 4830 int SendAlert(CYASSL* ssl, int severity, int type)
ashleymills 0:e979170e02e7 4831 {
ashleymills 0:e979170e02e7 4832 byte input[ALERT_SIZE];
ashleymills 0:e979170e02e7 4833 byte *output;
ashleymills 0:e979170e02e7 4834 int sendSz;
ashleymills 0:e979170e02e7 4835 int ret;
ashleymills 0:e979170e02e7 4836
ashleymills 0:e979170e02e7 4837 /* if sendalert is called again for nonbloking */
ashleymills 0:e979170e02e7 4838 if (ssl->options.sendAlertState != 0) {
ashleymills 0:e979170e02e7 4839 ret = SendBuffered(ssl);
ashleymills 0:e979170e02e7 4840 if (ret == 0)
ashleymills 0:e979170e02e7 4841 ssl->options.sendAlertState = 0;
ashleymills 0:e979170e02e7 4842 return ret;
ashleymills 0:e979170e02e7 4843 }
ashleymills 0:e979170e02e7 4844
ashleymills 0:e979170e02e7 4845 /* check for avalaible size */
ashleymills 0:e979170e02e7 4846 if ((ret = CheckAvalaibleSize(ssl, ALERT_SIZE + MAX_MSG_EXTRA)) != 0)
ashleymills 0:e979170e02e7 4847 return ret;
ashleymills 0:e979170e02e7 4848
ashleymills 0:e979170e02e7 4849 /* get ouput buffer */
ashleymills 0:e979170e02e7 4850 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 4851 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 4852
ashleymills 0:e979170e02e7 4853 input[0] = (byte)severity;
ashleymills 0:e979170e02e7 4854 input[1] = (byte)type;
ashleymills 0:e979170e02e7 4855
ashleymills 0:e979170e02e7 4856 /* only send encrypted alert if handshake actually complete, otherwise
ashleymills 0:e979170e02e7 4857 other side may not be able to handle it */
ashleymills 0:e979170e02e7 4858 if (ssl->keys.encryptionOn && ssl->options.handShakeState == HANDSHAKE_DONE)
ashleymills 0:e979170e02e7 4859 sendSz = BuildMessage(ssl, output, input, ALERT_SIZE, alert);
ashleymills 0:e979170e02e7 4860 else {
ashleymills 0:e979170e02e7 4861
ashleymills 0:e979170e02e7 4862 AddRecordHeader(output, ALERT_SIZE, alert, ssl);
ashleymills 0:e979170e02e7 4863 output += RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 4864 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4865 output += DTLS_RECORD_EXTRA;
ashleymills 0:e979170e02e7 4866 #endif
ashleymills 0:e979170e02e7 4867 XMEMCPY(output, input, ALERT_SIZE);
ashleymills 0:e979170e02e7 4868
ashleymills 0:e979170e02e7 4869 sendSz = RECORD_HEADER_SZ + ALERT_SIZE;
ashleymills 0:e979170e02e7 4870 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 4871 sendSz += DTLS_RECORD_EXTRA;
ashleymills 0:e979170e02e7 4872 #endif
ashleymills 0:e979170e02e7 4873 }
ashleymills 0:e979170e02e7 4874
ashleymills 0:e979170e02e7 4875 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 4876 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 4877 AddPacketName("Alert", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 4878 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 4879 AddPacketInfo("Alert", &ssl->timeoutInfo, output, sendSz,ssl->heap);
ashleymills 0:e979170e02e7 4880 #endif
ashleymills 0:e979170e02e7 4881
ashleymills 0:e979170e02e7 4882 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:e979170e02e7 4883 ssl->options.sendAlertState = 1;
ashleymills 0:e979170e02e7 4884
ashleymills 0:e979170e02e7 4885 return SendBuffered(ssl);
ashleymills 0:e979170e02e7 4886 }
ashleymills 0:e979170e02e7 4887
ashleymills 0:e979170e02e7 4888
ashleymills 0:e979170e02e7 4889
ashleymills 0:e979170e02e7 4890 void SetErrorString(int error, char* str)
ashleymills 0:e979170e02e7 4891 {
ashleymills 0:e979170e02e7 4892 const int max = MAX_ERROR_SZ; /* shorthand */
ashleymills 0:e979170e02e7 4893
ashleymills 0:e979170e02e7 4894 #ifdef NO_ERROR_STRINGS
ashleymills 0:e979170e02e7 4895
ashleymills 0:e979170e02e7 4896 (void)error;
ashleymills 0:e979170e02e7 4897 XSTRNCPY(str, "no support for error strings built in", max);
ashleymills 0:e979170e02e7 4898
ashleymills 0:e979170e02e7 4899 #else
ashleymills 0:e979170e02e7 4900
ashleymills 0:e979170e02e7 4901 /* pass to CTaoCrypt */
ashleymills 0:e979170e02e7 4902 if (error < MAX_CODE_E && error > MIN_CODE_E) {
ashleymills 0:e979170e02e7 4903 CTaoCryptErrorString(error, str);
ashleymills 0:e979170e02e7 4904 return;
ashleymills 0:e979170e02e7 4905 }
ashleymills 0:e979170e02e7 4906
ashleymills 0:e979170e02e7 4907 switch (error) {
ashleymills 0:e979170e02e7 4908
ashleymills 0:e979170e02e7 4909 case UNSUPPORTED_SUITE :
ashleymills 0:e979170e02e7 4910 XSTRNCPY(str, "unsupported cipher suite", max);
ashleymills 0:e979170e02e7 4911 break;
ashleymills 0:e979170e02e7 4912
ashleymills 0:e979170e02e7 4913 case INPUT_CASE_ERROR :
ashleymills 0:e979170e02e7 4914 XSTRNCPY(str, "input state error", max);
ashleymills 0:e979170e02e7 4915 break;
ashleymills 0:e979170e02e7 4916
ashleymills 0:e979170e02e7 4917 case PREFIX_ERROR :
ashleymills 0:e979170e02e7 4918 XSTRNCPY(str, "bad index to key rounds", max);
ashleymills 0:e979170e02e7 4919 break;
ashleymills 0:e979170e02e7 4920
ashleymills 0:e979170e02e7 4921 case MEMORY_ERROR :
ashleymills 0:e979170e02e7 4922 XSTRNCPY(str, "out of memory", max);
ashleymills 0:e979170e02e7 4923 break;
ashleymills 0:e979170e02e7 4924
ashleymills 0:e979170e02e7 4925 case VERIFY_FINISHED_ERROR :
ashleymills 0:e979170e02e7 4926 XSTRNCPY(str, "verify problem on finished", max);
ashleymills 0:e979170e02e7 4927 break;
ashleymills 0:e979170e02e7 4928
ashleymills 0:e979170e02e7 4929 case VERIFY_MAC_ERROR :
ashleymills 0:e979170e02e7 4930 XSTRNCPY(str, "verify mac problem", max);
ashleymills 0:e979170e02e7 4931 break;
ashleymills 0:e979170e02e7 4932
ashleymills 0:e979170e02e7 4933 case PARSE_ERROR :
ashleymills 0:e979170e02e7 4934 XSTRNCPY(str, "parse error on header", max);
ashleymills 0:e979170e02e7 4935 break;
ashleymills 0:e979170e02e7 4936
ashleymills 0:e979170e02e7 4937 case SIDE_ERROR :
ashleymills 0:e979170e02e7 4938 XSTRNCPY(str, "wrong client/server type", max);
ashleymills 0:e979170e02e7 4939 break;
ashleymills 0:e979170e02e7 4940
ashleymills 0:e979170e02e7 4941 case NO_PEER_CERT :
ashleymills 0:e979170e02e7 4942 XSTRNCPY(str, "peer didn't send cert", max);
ashleymills 0:e979170e02e7 4943 break;
ashleymills 0:e979170e02e7 4944
ashleymills 0:e979170e02e7 4945 case UNKNOWN_HANDSHAKE_TYPE :
ashleymills 0:e979170e02e7 4946 XSTRNCPY(str, "weird handshake type", max);
ashleymills 0:e979170e02e7 4947 break;
ashleymills 0:e979170e02e7 4948
ashleymills 0:e979170e02e7 4949 case SOCKET_ERROR_E :
ashleymills 0:e979170e02e7 4950 XSTRNCPY(str, "error state on socket", max);
ashleymills 0:e979170e02e7 4951 break;
ashleymills 0:e979170e02e7 4952
ashleymills 0:e979170e02e7 4953 case SOCKET_NODATA :
ashleymills 0:e979170e02e7 4954 XSTRNCPY(str, "expected data, not there", max);
ashleymills 0:e979170e02e7 4955 break;
ashleymills 0:e979170e02e7 4956
ashleymills 0:e979170e02e7 4957 case INCOMPLETE_DATA :
ashleymills 0:e979170e02e7 4958 XSTRNCPY(str, "don't have enough data to complete task", max);
ashleymills 0:e979170e02e7 4959 break;
ashleymills 0:e979170e02e7 4960
ashleymills 0:e979170e02e7 4961 case UNKNOWN_RECORD_TYPE :
ashleymills 0:e979170e02e7 4962 XSTRNCPY(str, "unknown type in record hdr", max);
ashleymills 0:e979170e02e7 4963 break;
ashleymills 0:e979170e02e7 4964
ashleymills 0:e979170e02e7 4965 case DECRYPT_ERROR :
ashleymills 0:e979170e02e7 4966 XSTRNCPY(str, "error during decryption", max);
ashleymills 0:e979170e02e7 4967 break;
ashleymills 0:e979170e02e7 4968
ashleymills 0:e979170e02e7 4969 case FATAL_ERROR :
ashleymills 0:e979170e02e7 4970 XSTRNCPY(str, "revcd alert fatal error", max);
ashleymills 0:e979170e02e7 4971 break;
ashleymills 0:e979170e02e7 4972
ashleymills 0:e979170e02e7 4973 case ENCRYPT_ERROR :
ashleymills 0:e979170e02e7 4974 XSTRNCPY(str, "error during encryption", max);
ashleymills 0:e979170e02e7 4975 break;
ashleymills 0:e979170e02e7 4976
ashleymills 0:e979170e02e7 4977 case FREAD_ERROR :
ashleymills 0:e979170e02e7 4978 XSTRNCPY(str, "fread problem", max);
ashleymills 0:e979170e02e7 4979 break;
ashleymills 0:e979170e02e7 4980
ashleymills 0:e979170e02e7 4981 case NO_PEER_KEY :
ashleymills 0:e979170e02e7 4982 XSTRNCPY(str, "need peer's key", max);
ashleymills 0:e979170e02e7 4983 break;
ashleymills 0:e979170e02e7 4984
ashleymills 0:e979170e02e7 4985 case NO_PRIVATE_KEY :
ashleymills 0:e979170e02e7 4986 XSTRNCPY(str, "need the private key", max);
ashleymills 0:e979170e02e7 4987 break;
ashleymills 0:e979170e02e7 4988
ashleymills 0:e979170e02e7 4989 case NO_DH_PARAMS :
ashleymills 0:e979170e02e7 4990 XSTRNCPY(str, "server missing DH params", max);
ashleymills 0:e979170e02e7 4991 break;
ashleymills 0:e979170e02e7 4992
ashleymills 0:e979170e02e7 4993 case RSA_PRIVATE_ERROR :
ashleymills 0:e979170e02e7 4994 XSTRNCPY(str, "error during rsa priv op", max);
ashleymills 0:e979170e02e7 4995 break;
ashleymills 0:e979170e02e7 4996
ashleymills 0:e979170e02e7 4997 case MATCH_SUITE_ERROR :
ashleymills 0:e979170e02e7 4998 XSTRNCPY(str, "can't match cipher suite", max);
ashleymills 0:e979170e02e7 4999 break;
ashleymills 0:e979170e02e7 5000
ashleymills 0:e979170e02e7 5001 case BUILD_MSG_ERROR :
ashleymills 0:e979170e02e7 5002 XSTRNCPY(str, "build message failure", max);
ashleymills 0:e979170e02e7 5003 break;
ashleymills 0:e979170e02e7 5004
ashleymills 0:e979170e02e7 5005 case BAD_HELLO :
ashleymills 0:e979170e02e7 5006 XSTRNCPY(str, "client hello malformed", max);
ashleymills 0:e979170e02e7 5007 break;
ashleymills 0:e979170e02e7 5008
ashleymills 0:e979170e02e7 5009 case DOMAIN_NAME_MISMATCH :
ashleymills 0:e979170e02e7 5010 XSTRNCPY(str, "peer subject name mismatch", max);
ashleymills 0:e979170e02e7 5011 break;
ashleymills 0:e979170e02e7 5012
ashleymills 0:e979170e02e7 5013 case WANT_READ :
ashleymills 0:e979170e02e7 5014 case SSL_ERROR_WANT_READ :
ashleymills 0:e979170e02e7 5015 XSTRNCPY(str, "non-blocking socket wants data to be read", max);
ashleymills 0:e979170e02e7 5016 break;
ashleymills 0:e979170e02e7 5017
ashleymills 0:e979170e02e7 5018 case NOT_READY_ERROR :
ashleymills 0:e979170e02e7 5019 XSTRNCPY(str, "handshake layer not ready yet, complete first", max);
ashleymills 0:e979170e02e7 5020 break;
ashleymills 0:e979170e02e7 5021
ashleymills 0:e979170e02e7 5022 case PMS_VERSION_ERROR :
ashleymills 0:e979170e02e7 5023 XSTRNCPY(str, "premaster secret version mismatch error", max);
ashleymills 0:e979170e02e7 5024 break;
ashleymills 0:e979170e02e7 5025
ashleymills 0:e979170e02e7 5026 case VERSION_ERROR :
ashleymills 0:e979170e02e7 5027 XSTRNCPY(str, "record layer version error", max);
ashleymills 0:e979170e02e7 5028 break;
ashleymills 0:e979170e02e7 5029
ashleymills 0:e979170e02e7 5030 case WANT_WRITE :
ashleymills 0:e979170e02e7 5031 case SSL_ERROR_WANT_WRITE :
ashleymills 0:e979170e02e7 5032 XSTRNCPY(str, "non-blocking socket write buffer full", max);
ashleymills 0:e979170e02e7 5033 break;
ashleymills 0:e979170e02e7 5034
ashleymills 0:e979170e02e7 5035 case BUFFER_ERROR :
ashleymills 0:e979170e02e7 5036 XSTRNCPY(str, "malformed buffer input error", max);
ashleymills 0:e979170e02e7 5037 break;
ashleymills 0:e979170e02e7 5038
ashleymills 0:e979170e02e7 5039 case VERIFY_CERT_ERROR :
ashleymills 0:e979170e02e7 5040 XSTRNCPY(str, "verify problem on certificate", max);
ashleymills 0:e979170e02e7 5041 break;
ashleymills 0:e979170e02e7 5042
ashleymills 0:e979170e02e7 5043 case VERIFY_SIGN_ERROR :
ashleymills 0:e979170e02e7 5044 XSTRNCPY(str, "verify problem based on signature", max);
ashleymills 0:e979170e02e7 5045 break;
ashleymills 0:e979170e02e7 5046
ashleymills 0:e979170e02e7 5047 case CLIENT_ID_ERROR :
ashleymills 0:e979170e02e7 5048 XSTRNCPY(str, "psk client identity error", max);
ashleymills 0:e979170e02e7 5049 break;
ashleymills 0:e979170e02e7 5050
ashleymills 0:e979170e02e7 5051 case SERVER_HINT_ERROR:
ashleymills 0:e979170e02e7 5052 XSTRNCPY(str, "psk server hint error", max);
ashleymills 0:e979170e02e7 5053 break;
ashleymills 0:e979170e02e7 5054
ashleymills 0:e979170e02e7 5055 case PSK_KEY_ERROR:
ashleymills 0:e979170e02e7 5056 XSTRNCPY(str, "psk key callback error", max);
ashleymills 0:e979170e02e7 5057 break;
ashleymills 0:e979170e02e7 5058
ashleymills 0:e979170e02e7 5059 case NTRU_KEY_ERROR:
ashleymills 0:e979170e02e7 5060 XSTRNCPY(str, "NTRU key error", max);
ashleymills 0:e979170e02e7 5061 break;
ashleymills 0:e979170e02e7 5062
ashleymills 0:e979170e02e7 5063 case NTRU_DRBG_ERROR:
ashleymills 0:e979170e02e7 5064 XSTRNCPY(str, "NTRU drbg error", max);
ashleymills 0:e979170e02e7 5065 break;
ashleymills 0:e979170e02e7 5066
ashleymills 0:e979170e02e7 5067 case NTRU_ENCRYPT_ERROR:
ashleymills 0:e979170e02e7 5068 XSTRNCPY(str, "NTRU encrypt error", max);
ashleymills 0:e979170e02e7 5069 break;
ashleymills 0:e979170e02e7 5070
ashleymills 0:e979170e02e7 5071 case NTRU_DECRYPT_ERROR:
ashleymills 0:e979170e02e7 5072 XSTRNCPY(str, "NTRU decrypt error", max);
ashleymills 0:e979170e02e7 5073 break;
ashleymills 0:e979170e02e7 5074
ashleymills 0:e979170e02e7 5075 case ZLIB_INIT_ERROR:
ashleymills 0:e979170e02e7 5076 XSTRNCPY(str, "zlib init error", max);
ashleymills 0:e979170e02e7 5077 break;
ashleymills 0:e979170e02e7 5078
ashleymills 0:e979170e02e7 5079 case ZLIB_COMPRESS_ERROR:
ashleymills 0:e979170e02e7 5080 XSTRNCPY(str, "zlib compress error", max);
ashleymills 0:e979170e02e7 5081 break;
ashleymills 0:e979170e02e7 5082
ashleymills 0:e979170e02e7 5083 case ZLIB_DECOMPRESS_ERROR:
ashleymills 0:e979170e02e7 5084 XSTRNCPY(str, "zlib decompress error", max);
ashleymills 0:e979170e02e7 5085 break;
ashleymills 0:e979170e02e7 5086
ashleymills 0:e979170e02e7 5087 case GETTIME_ERROR:
ashleymills 0:e979170e02e7 5088 XSTRNCPY(str, "gettimeofday() error", max);
ashleymills 0:e979170e02e7 5089 break;
ashleymills 0:e979170e02e7 5090
ashleymills 0:e979170e02e7 5091 case GETITIMER_ERROR:
ashleymills 0:e979170e02e7 5092 XSTRNCPY(str, "getitimer() error", max);
ashleymills 0:e979170e02e7 5093 break;
ashleymills 0:e979170e02e7 5094
ashleymills 0:e979170e02e7 5095 case SIGACT_ERROR:
ashleymills 0:e979170e02e7 5096 XSTRNCPY(str, "sigaction() error", max);
ashleymills 0:e979170e02e7 5097 break;
ashleymills 0:e979170e02e7 5098
ashleymills 0:e979170e02e7 5099 case SETITIMER_ERROR:
ashleymills 0:e979170e02e7 5100 XSTRNCPY(str, "setitimer() error", max);
ashleymills 0:e979170e02e7 5101 break;
ashleymills 0:e979170e02e7 5102
ashleymills 0:e979170e02e7 5103 case LENGTH_ERROR:
ashleymills 0:e979170e02e7 5104 XSTRNCPY(str, "record layer length error", max);
ashleymills 0:e979170e02e7 5105 break;
ashleymills 0:e979170e02e7 5106
ashleymills 0:e979170e02e7 5107 case PEER_KEY_ERROR:
ashleymills 0:e979170e02e7 5108 XSTRNCPY(str, "cant decode peer key", max);
ashleymills 0:e979170e02e7 5109 break;
ashleymills 0:e979170e02e7 5110
ashleymills 0:e979170e02e7 5111 case ZERO_RETURN:
ashleymills 0:e979170e02e7 5112 case SSL_ERROR_ZERO_RETURN:
ashleymills 0:e979170e02e7 5113 XSTRNCPY(str, "peer sent close notify alert", max);
ashleymills 0:e979170e02e7 5114 break;
ashleymills 0:e979170e02e7 5115
ashleymills 0:e979170e02e7 5116 case ECC_CURVETYPE_ERROR:
ashleymills 0:e979170e02e7 5117 XSTRNCPY(str, "Bad ECC Curve Type or unsupported", max);
ashleymills 0:e979170e02e7 5118 break;
ashleymills 0:e979170e02e7 5119
ashleymills 0:e979170e02e7 5120 case ECC_CURVE_ERROR:
ashleymills 0:e979170e02e7 5121 XSTRNCPY(str, "Bad ECC Curve or unsupported", max);
ashleymills 0:e979170e02e7 5122 break;
ashleymills 0:e979170e02e7 5123
ashleymills 0:e979170e02e7 5124 case ECC_PEERKEY_ERROR:
ashleymills 0:e979170e02e7 5125 XSTRNCPY(str, "Bad ECC Peer Key", max);
ashleymills 0:e979170e02e7 5126 break;
ashleymills 0:e979170e02e7 5127
ashleymills 0:e979170e02e7 5128 case ECC_MAKEKEY_ERROR:
ashleymills 0:e979170e02e7 5129 XSTRNCPY(str, "ECC Make Key failure", max);
ashleymills 0:e979170e02e7 5130 break;
ashleymills 0:e979170e02e7 5131
ashleymills 0:e979170e02e7 5132 case ECC_EXPORT_ERROR:
ashleymills 0:e979170e02e7 5133 XSTRNCPY(str, "ECC Export Key failure", max);
ashleymills 0:e979170e02e7 5134 break;
ashleymills 0:e979170e02e7 5135
ashleymills 0:e979170e02e7 5136 case ECC_SHARED_ERROR:
ashleymills 0:e979170e02e7 5137 XSTRNCPY(str, "ECC DHE shared failure", max);
ashleymills 0:e979170e02e7 5138 break;
ashleymills 0:e979170e02e7 5139
ashleymills 0:e979170e02e7 5140 case BAD_MUTEX_ERROR:
ashleymills 0:e979170e02e7 5141 XSTRNCPY(str, "Bad mutex, operation failed", max);
ashleymills 0:e979170e02e7 5142 break;
ashleymills 0:e979170e02e7 5143
ashleymills 0:e979170e02e7 5144 case NOT_CA_ERROR:
ashleymills 0:e979170e02e7 5145 XSTRNCPY(str, "Not a CA by basic constraint error", max);
ashleymills 0:e979170e02e7 5146 break;
ashleymills 0:e979170e02e7 5147
ashleymills 0:e979170e02e7 5148 case BAD_PATH_ERROR:
ashleymills 0:e979170e02e7 5149 XSTRNCPY(str, "Bad path for opendir error", max);
ashleymills 0:e979170e02e7 5150 break;
ashleymills 0:e979170e02e7 5151
ashleymills 0:e979170e02e7 5152 case BAD_CERT_MANAGER_ERROR:
ashleymills 0:e979170e02e7 5153 XSTRNCPY(str, "Bad Cert Manager error", max);
ashleymills 0:e979170e02e7 5154 break;
ashleymills 0:e979170e02e7 5155
ashleymills 0:e979170e02e7 5156 case OCSP_CERT_REVOKED:
ashleymills 0:e979170e02e7 5157 XSTRNCPY(str, "OCSP Cert revoked", max);
ashleymills 0:e979170e02e7 5158 break;
ashleymills 0:e979170e02e7 5159
ashleymills 0:e979170e02e7 5160 case CRL_CERT_REVOKED:
ashleymills 0:e979170e02e7 5161 XSTRNCPY(str, "CRL Cert revoked", max);
ashleymills 0:e979170e02e7 5162 break;
ashleymills 0:e979170e02e7 5163
ashleymills 0:e979170e02e7 5164 case CRL_MISSING:
ashleymills 0:e979170e02e7 5165 XSTRNCPY(str, "CRL missing, not loaded", max);
ashleymills 0:e979170e02e7 5166 break;
ashleymills 0:e979170e02e7 5167
ashleymills 0:e979170e02e7 5168 case MONITOR_RUNNING_E:
ashleymills 0:e979170e02e7 5169 XSTRNCPY(str, "CRL monitor already running", max);
ashleymills 0:e979170e02e7 5170 break;
ashleymills 0:e979170e02e7 5171
ashleymills 0:e979170e02e7 5172 case THREAD_CREATE_E:
ashleymills 0:e979170e02e7 5173 XSTRNCPY(str, "Thread creation problem", max);
ashleymills 0:e979170e02e7 5174 break;
ashleymills 0:e979170e02e7 5175
ashleymills 0:e979170e02e7 5176 case OCSP_NEED_URL:
ashleymills 0:e979170e02e7 5177 XSTRNCPY(str, "OCSP need URL", max);
ashleymills 0:e979170e02e7 5178 break;
ashleymills 0:e979170e02e7 5179
ashleymills 0:e979170e02e7 5180 case OCSP_CERT_UNKNOWN:
ashleymills 0:e979170e02e7 5181 XSTRNCPY(str, "OCSP Cert unknown", max);
ashleymills 0:e979170e02e7 5182 break;
ashleymills 0:e979170e02e7 5183
ashleymills 0:e979170e02e7 5184 case OCSP_LOOKUP_FAIL:
ashleymills 0:e979170e02e7 5185 XSTRNCPY(str, "OCSP Responder lookup fail", max);
ashleymills 0:e979170e02e7 5186 break;
ashleymills 0:e979170e02e7 5187
ashleymills 0:e979170e02e7 5188 case MAX_CHAIN_ERROR:
ashleymills 0:e979170e02e7 5189 XSTRNCPY(str, "Maximum Chain Depth Exceeded", max);
ashleymills 0:e979170e02e7 5190 break;
ashleymills 0:e979170e02e7 5191
ashleymills 0:e979170e02e7 5192 case COOKIE_ERROR:
ashleymills 0:e979170e02e7 5193 XSTRNCPY(str, "DTLS Cookie Error", max);
ashleymills 0:e979170e02e7 5194 break;
ashleymills 0:e979170e02e7 5195
ashleymills 0:e979170e02e7 5196 case SEQUENCE_ERROR:
ashleymills 0:e979170e02e7 5197 XSTRNCPY(str, "DTLS Sequence Error", max);
ashleymills 0:e979170e02e7 5198 break;
ashleymills 0:e979170e02e7 5199
ashleymills 0:e979170e02e7 5200 case SUITES_ERROR:
ashleymills 0:e979170e02e7 5201 XSTRNCPY(str, "Suites Pointer Error", max);
ashleymills 0:e979170e02e7 5202 break;
ashleymills 0:e979170e02e7 5203
ashleymills 0:e979170e02e7 5204 case SSL_NO_PEM_HEADER:
ashleymills 0:e979170e02e7 5205 XSTRNCPY(str, "No PEM Header Error", max);
ashleymills 0:e979170e02e7 5206 break;
ashleymills 0:e979170e02e7 5207
ashleymills 0:e979170e02e7 5208 case OUT_OF_ORDER_E:
ashleymills 0:e979170e02e7 5209 XSTRNCPY(str, "Out of order message, fatal", max);
ashleymills 0:e979170e02e7 5210 break;
ashleymills 0:e979170e02e7 5211
ashleymills 0:e979170e02e7 5212 case BAD_KEA_TYPE_E:
ashleymills 0:e979170e02e7 5213 XSTRNCPY(str, "Bad KEA type found", max);
ashleymills 0:e979170e02e7 5214 break;
ashleymills 0:e979170e02e7 5215
ashleymills 0:e979170e02e7 5216 case SANITY_CIPHER_E:
ashleymills 0:e979170e02e7 5217 XSTRNCPY(str, "Sanity check on ciphertext failed", max);
ashleymills 0:e979170e02e7 5218 break;
ashleymills 0:e979170e02e7 5219
ashleymills 0:e979170e02e7 5220 case RECV_OVERFLOW_E:
ashleymills 0:e979170e02e7 5221 XSTRNCPY(str, "Receive callback returned more than requested", max);
ashleymills 0:e979170e02e7 5222 break;
ashleymills 0:e979170e02e7 5223
ashleymills 0:e979170e02e7 5224 default :
ashleymills 0:e979170e02e7 5225 XSTRNCPY(str, "unknown error number", max);
ashleymills 0:e979170e02e7 5226 }
ashleymills 0:e979170e02e7 5227
ashleymills 0:e979170e02e7 5228 #endif /* NO_ERROR_STRINGS */
ashleymills 0:e979170e02e7 5229 }
ashleymills 0:e979170e02e7 5230
ashleymills 0:e979170e02e7 5231
ashleymills 0:e979170e02e7 5232
ashleymills 0:e979170e02e7 5233 /* be sure to add to cipher_name_idx too !!!! */
ashleymills 0:e979170e02e7 5234 const char* const cipher_names[] =
ashleymills 0:e979170e02e7 5235 {
ashleymills 0:e979170e02e7 5236 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 5237 "RC4-SHA",
ashleymills 0:e979170e02e7 5238 #endif
ashleymills 0:e979170e02e7 5239
ashleymills 0:e979170e02e7 5240 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
ashleymills 0:e979170e02e7 5241 "RC4-MD5",
ashleymills 0:e979170e02e7 5242 #endif
ashleymills 0:e979170e02e7 5243
ashleymills 0:e979170e02e7 5244 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 5245 "DES-CBC3-SHA",
ashleymills 0:e979170e02e7 5246 #endif
ashleymills 0:e979170e02e7 5247
ashleymills 0:e979170e02e7 5248 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5249 "AES128-SHA",
ashleymills 0:e979170e02e7 5250 #endif
ashleymills 0:e979170e02e7 5251
ashleymills 0:e979170e02e7 5252 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5253 "AES256-SHA",
ashleymills 0:e979170e02e7 5254 #endif
ashleymills 0:e979170e02e7 5255
ashleymills 0:e979170e02e7 5256 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
ashleymills 0:e979170e02e7 5257 "NULL-SHA",
ashleymills 0:e979170e02e7 5258 #endif
ashleymills 0:e979170e02e7 5259
ashleymills 0:e979170e02e7 5260 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
ashleymills 0:e979170e02e7 5261 "NULL-SHA256",
ashleymills 0:e979170e02e7 5262 #endif
ashleymills 0:e979170e02e7 5263
ashleymills 0:e979170e02e7 5264 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5265 "DHE-RSA-AES128-SHA",
ashleymills 0:e979170e02e7 5266 #endif
ashleymills 0:e979170e02e7 5267
ashleymills 0:e979170e02e7 5268 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5269 "DHE-RSA-AES256-SHA",
ashleymills 0:e979170e02e7 5270 #endif
ashleymills 0:e979170e02e7 5271
ashleymills 0:e979170e02e7 5272 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
ashleymills 0:e979170e02e7 5273 "PSK-AES128-CBC-SHA256",
ashleymills 0:e979170e02e7 5274 #endif
ashleymills 0:e979170e02e7 5275
ashleymills 0:e979170e02e7 5276 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5277 "PSK-AES128-CBC-SHA",
ashleymills 0:e979170e02e7 5278 #endif
ashleymills 0:e979170e02e7 5279
ashleymills 0:e979170e02e7 5280 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5281 "PSK-AES256-CBC-SHA",
ashleymills 0:e979170e02e7 5282 #endif
ashleymills 0:e979170e02e7 5283
ashleymills 0:e979170e02e7 5284 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
ashleymills 0:e979170e02e7 5285 "PSK-NULL-SHA256",
ashleymills 0:e979170e02e7 5286 #endif
ashleymills 0:e979170e02e7 5287
ashleymills 0:e979170e02e7 5288 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
ashleymills 0:e979170e02e7 5289 "PSK-NULL-SHA",
ashleymills 0:e979170e02e7 5290 #endif
ashleymills 0:e979170e02e7 5291
ashleymills 0:e979170e02e7 5292 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
ashleymills 0:e979170e02e7 5293 "HC128-MD5",
ashleymills 0:e979170e02e7 5294 #endif
ashleymills 0:e979170e02e7 5295
ashleymills 0:e979170e02e7 5296 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
ashleymills 0:e979170e02e7 5297 "HC128-SHA",
ashleymills 0:e979170e02e7 5298 #endif
ashleymills 0:e979170e02e7 5299
ashleymills 0:e979170e02e7 5300 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
ashleymills 0:e979170e02e7 5301 "RABBIT-SHA",
ashleymills 0:e979170e02e7 5302 #endif
ashleymills 0:e979170e02e7 5303
ashleymills 0:e979170e02e7 5304 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 5305 "NTRU-RC4-SHA",
ashleymills 0:e979170e02e7 5306 #endif
ashleymills 0:e979170e02e7 5307
ashleymills 0:e979170e02e7 5308 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 5309 "NTRU-DES-CBC3-SHA",
ashleymills 0:e979170e02e7 5310 #endif
ashleymills 0:e979170e02e7 5311
ashleymills 0:e979170e02e7 5312 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5313 "NTRU-AES128-SHA",
ashleymills 0:e979170e02e7 5314 #endif
ashleymills 0:e979170e02e7 5315
ashleymills 0:e979170e02e7 5316 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5317 "NTRU-AES256-SHA",
ashleymills 0:e979170e02e7 5318 #endif
ashleymills 0:e979170e02e7 5319
ashleymills 0:e979170e02e7 5320 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8_SHA256
ashleymills 0:e979170e02e7 5321 "AES128-CCM-8-SHA256",
ashleymills 0:e979170e02e7 5322 #endif
ashleymills 0:e979170e02e7 5323
ashleymills 0:e979170e02e7 5324 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8_SHA384
ashleymills 0:e979170e02e7 5325 "AES256-CCM-8-SHA384",
ashleymills 0:e979170e02e7 5326 #endif
ashleymills 0:e979170e02e7 5327
ashleymills 0:e979170e02e7 5328 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_SHA256
ashleymills 0:e979170e02e7 5329 "ECDHE-ECDSA-AES128-CCM-8-SHA256",
ashleymills 0:e979170e02e7 5330 #endif
ashleymills 0:e979170e02e7 5331
ashleymills 0:e979170e02e7 5332 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8_SHA384
ashleymills 0:e979170e02e7 5333 "ECDHE-ECDSA-AES256-CCM-8-SHA384",
ashleymills 0:e979170e02e7 5334 #endif
ashleymills 0:e979170e02e7 5335
ashleymills 0:e979170e02e7 5336 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5337 "ECDHE-RSA-AES128-SHA",
ashleymills 0:e979170e02e7 5338 #endif
ashleymills 0:e979170e02e7 5339
ashleymills 0:e979170e02e7 5340 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5341 "ECDHE-RSA-AES256-SHA",
ashleymills 0:e979170e02e7 5342 #endif
ashleymills 0:e979170e02e7 5343
ashleymills 0:e979170e02e7 5344 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5345 "ECDHE-ECDSA-AES128-SHA",
ashleymills 0:e979170e02e7 5346 #endif
ashleymills 0:e979170e02e7 5347
ashleymills 0:e979170e02e7 5348 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5349 "ECDHE-ECDSA-AES256-SHA",
ashleymills 0:e979170e02e7 5350 #endif
ashleymills 0:e979170e02e7 5351
ashleymills 0:e979170e02e7 5352 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 5353 "ECDHE-RSA-RC4-SHA",
ashleymills 0:e979170e02e7 5354 #endif
ashleymills 0:e979170e02e7 5355
ashleymills 0:e979170e02e7 5356 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 5357 "ECDHE-RSA-DES-CBC3-SHA",
ashleymills 0:e979170e02e7 5358 #endif
ashleymills 0:e979170e02e7 5359
ashleymills 0:e979170e02e7 5360 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 5361 "ECDHE-ECDSA-RC4-SHA",
ashleymills 0:e979170e02e7 5362 #endif
ashleymills 0:e979170e02e7 5363
ashleymills 0:e979170e02e7 5364 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 5365 "ECDHE-ECDSA-DES-CBC3-SHA",
ashleymills 0:e979170e02e7 5366 #endif
ashleymills 0:e979170e02e7 5367
ashleymills 0:e979170e02e7 5368 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:e979170e02e7 5369 "AES128-SHA256",
ashleymills 0:e979170e02e7 5370 #endif
ashleymills 0:e979170e02e7 5371
ashleymills 0:e979170e02e7 5372 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
ashleymills 0:e979170e02e7 5373 "AES256-SHA256",
ashleymills 0:e979170e02e7 5374 #endif
ashleymills 0:e979170e02e7 5375
ashleymills 0:e979170e02e7 5376 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:e979170e02e7 5377 "DHE-RSA-AES128-SHA256",
ashleymills 0:e979170e02e7 5378 #endif
ashleymills 0:e979170e02e7 5379
ashleymills 0:e979170e02e7 5380 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
ashleymills 0:e979170e02e7 5381 "DHE-RSA-AES256-SHA256",
ashleymills 0:e979170e02e7 5382 #endif
ashleymills 0:e979170e02e7 5383
ashleymills 0:e979170e02e7 5384 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5385 "ECDH-RSA-AES128-SHA",
ashleymills 0:e979170e02e7 5386 #endif
ashleymills 0:e979170e02e7 5387
ashleymills 0:e979170e02e7 5388 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5389 "ECDH-RSA-AES256-SHA",
ashleymills 0:e979170e02e7 5390 #endif
ashleymills 0:e979170e02e7 5391
ashleymills 0:e979170e02e7 5392 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5393 "ECDH-ECDSA-AES128-SHA",
ashleymills 0:e979170e02e7 5394 #endif
ashleymills 0:e979170e02e7 5395
ashleymills 0:e979170e02e7 5396 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5397 "ECDH-ECDSA-AES256-SHA",
ashleymills 0:e979170e02e7 5398 #endif
ashleymills 0:e979170e02e7 5399
ashleymills 0:e979170e02e7 5400 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 5401 "ECDH-RSA-RC4-SHA",
ashleymills 0:e979170e02e7 5402 #endif
ashleymills 0:e979170e02e7 5403
ashleymills 0:e979170e02e7 5404 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 5405 "ECDH-RSA-DES-CBC3-SHA",
ashleymills 0:e979170e02e7 5406 #endif
ashleymills 0:e979170e02e7 5407
ashleymills 0:e979170e02e7 5408 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 5409 "ECDH-ECDSA-RC4-SHA",
ashleymills 0:e979170e02e7 5410 #endif
ashleymills 0:e979170e02e7 5411
ashleymills 0:e979170e02e7 5412 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 5413 "ECDH-ECDSA-DES-CBC3-SHA",
ashleymills 0:e979170e02e7 5414 #endif
ashleymills 0:e979170e02e7 5415
ashleymills 0:e979170e02e7 5416 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 5417 "AES128-GCM-SHA256",
ashleymills 0:e979170e02e7 5418 #endif
ashleymills 0:e979170e02e7 5419
ashleymills 0:e979170e02e7 5420 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 5421 "AES256-GCM-SHA384",
ashleymills 0:e979170e02e7 5422 #endif
ashleymills 0:e979170e02e7 5423
ashleymills 0:e979170e02e7 5424 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 5425 "DHE-RSA-AES128-GCM-SHA256",
ashleymills 0:e979170e02e7 5426 #endif
ashleymills 0:e979170e02e7 5427
ashleymills 0:e979170e02e7 5428 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 5429 "DHE-RSA-AES256-GCM-SHA384",
ashleymills 0:e979170e02e7 5430 #endif
ashleymills 0:e979170e02e7 5431
ashleymills 0:e979170e02e7 5432 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 5433 "ECDHE-RSA-AES128-GCM-SHA256",
ashleymills 0:e979170e02e7 5434 #endif
ashleymills 0:e979170e02e7 5435
ashleymills 0:e979170e02e7 5436 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 5437 "ECDHE-RSA-AES256-GCM-SHA384",
ashleymills 0:e979170e02e7 5438 #endif
ashleymills 0:e979170e02e7 5439
ashleymills 0:e979170e02e7 5440 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 5441 "ECDHE-ECDSA-AES128-GCM-SHA256",
ashleymills 0:e979170e02e7 5442 #endif
ashleymills 0:e979170e02e7 5443
ashleymills 0:e979170e02e7 5444 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 5445 "ECDHE-ECDSA-AES256-GCM-SHA384",
ashleymills 0:e979170e02e7 5446 #endif
ashleymills 0:e979170e02e7 5447
ashleymills 0:e979170e02e7 5448 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 5449 "ECDH-RSA-AES128-GCM-SHA256",
ashleymills 0:e979170e02e7 5450 #endif
ashleymills 0:e979170e02e7 5451
ashleymills 0:e979170e02e7 5452 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 5453 "ECDH-RSA-AES256-GCM-SHA384",
ashleymills 0:e979170e02e7 5454 #endif
ashleymills 0:e979170e02e7 5455
ashleymills 0:e979170e02e7 5456 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 5457 "ECDH-ECDSA-AES128-GCM-SHA256",
ashleymills 0:e979170e02e7 5458 #endif
ashleymills 0:e979170e02e7 5459
ashleymills 0:e979170e02e7 5460 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 5461 "ECDH-ECDSA-AES256-GCM-SHA384",
ashleymills 0:e979170e02e7 5462 #endif
ashleymills 0:e979170e02e7 5463
ashleymills 0:e979170e02e7 5464 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
ashleymills 0:e979170e02e7 5465 "CAMELLIA128-SHA",
ashleymills 0:e979170e02e7 5466 #endif
ashleymills 0:e979170e02e7 5467
ashleymills 0:e979170e02e7 5468 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
ashleymills 0:e979170e02e7 5469 "DHE-RSA-CAMELLIA128-SHA",
ashleymills 0:e979170e02e7 5470 #endif
ashleymills 0:e979170e02e7 5471
ashleymills 0:e979170e02e7 5472 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
ashleymills 0:e979170e02e7 5473 "CAMELLIA256-SHA",
ashleymills 0:e979170e02e7 5474 #endif
ashleymills 0:e979170e02e7 5475
ashleymills 0:e979170e02e7 5476 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
ashleymills 0:e979170e02e7 5477 "DHE-RSA-CAMELLIA256-SHA",
ashleymills 0:e979170e02e7 5478 #endif
ashleymills 0:e979170e02e7 5479
ashleymills 0:e979170e02e7 5480 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
ashleymills 0:e979170e02e7 5481 "CAMELLIA128-SHA256",
ashleymills 0:e979170e02e7 5482 #endif
ashleymills 0:e979170e02e7 5483
ashleymills 0:e979170e02e7 5484 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
ashleymills 0:e979170e02e7 5485 "DHE-RSA-CAMELLIA128-SHA256",
ashleymills 0:e979170e02e7 5486 #endif
ashleymills 0:e979170e02e7 5487
ashleymills 0:e979170e02e7 5488 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
ashleymills 0:e979170e02e7 5489 "CAMELLIA256-SHA256",
ashleymills 0:e979170e02e7 5490 #endif
ashleymills 0:e979170e02e7 5491
ashleymills 0:e979170e02e7 5492 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
ashleymills 0:e979170e02e7 5493 "DHE-RSA-CAMELLIA256-SHA256"
ashleymills 0:e979170e02e7 5494 #endif
ashleymills 0:e979170e02e7 5495
ashleymills 0:e979170e02e7 5496 };
ashleymills 0:e979170e02e7 5497
ashleymills 0:e979170e02e7 5498
ashleymills 0:e979170e02e7 5499
ashleymills 0:e979170e02e7 5500 /* cipher suite number that matches above name table */
ashleymills 0:e979170e02e7 5501 int cipher_name_idx[] =
ashleymills 0:e979170e02e7 5502 {
ashleymills 0:e979170e02e7 5503
ashleymills 0:e979170e02e7 5504 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 5505 SSL_RSA_WITH_RC4_128_SHA,
ashleymills 0:e979170e02e7 5506 #endif
ashleymills 0:e979170e02e7 5507
ashleymills 0:e979170e02e7 5508 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
ashleymills 0:e979170e02e7 5509 SSL_RSA_WITH_RC4_128_MD5,
ashleymills 0:e979170e02e7 5510 #endif
ashleymills 0:e979170e02e7 5511
ashleymills 0:e979170e02e7 5512 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 5513 SSL_RSA_WITH_3DES_EDE_CBC_SHA,
ashleymills 0:e979170e02e7 5514 #endif
ashleymills 0:e979170e02e7 5515
ashleymills 0:e979170e02e7 5516 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5517 TLS_RSA_WITH_AES_128_CBC_SHA,
ashleymills 0:e979170e02e7 5518 #endif
ashleymills 0:e979170e02e7 5519
ashleymills 0:e979170e02e7 5520 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5521 TLS_RSA_WITH_AES_256_CBC_SHA,
ashleymills 0:e979170e02e7 5522 #endif
ashleymills 0:e979170e02e7 5523
ashleymills 0:e979170e02e7 5524 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
ashleymills 0:e979170e02e7 5525 TLS_RSA_WITH_NULL_SHA,
ashleymills 0:e979170e02e7 5526 #endif
ashleymills 0:e979170e02e7 5527
ashleymills 0:e979170e02e7 5528 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
ashleymills 0:e979170e02e7 5529 TLS_RSA_WITH_NULL_SHA256,
ashleymills 0:e979170e02e7 5530 #endif
ashleymills 0:e979170e02e7 5531
ashleymills 0:e979170e02e7 5532 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5533 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
ashleymills 0:e979170e02e7 5534 #endif
ashleymills 0:e979170e02e7 5535
ashleymills 0:e979170e02e7 5536 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5537 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
ashleymills 0:e979170e02e7 5538 #endif
ashleymills 0:e979170e02e7 5539
ashleymills 0:e979170e02e7 5540 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
ashleymills 0:e979170e02e7 5541 TLS_PSK_WITH_AES_128_CBC_SHA256,
ashleymills 0:e979170e02e7 5542 #endif
ashleymills 0:e979170e02e7 5543
ashleymills 0:e979170e02e7 5544 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5545 TLS_PSK_WITH_AES_128_CBC_SHA,
ashleymills 0:e979170e02e7 5546 #endif
ashleymills 0:e979170e02e7 5547
ashleymills 0:e979170e02e7 5548 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5549 TLS_PSK_WITH_AES_256_CBC_SHA,
ashleymills 0:e979170e02e7 5550 #endif
ashleymills 0:e979170e02e7 5551
ashleymills 0:e979170e02e7 5552 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
ashleymills 0:e979170e02e7 5553 TLS_PSK_WITH_NULL_SHA256,
ashleymills 0:e979170e02e7 5554 #endif
ashleymills 0:e979170e02e7 5555
ashleymills 0:e979170e02e7 5556 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
ashleymills 0:e979170e02e7 5557 TLS_PSK_WITH_NULL_SHA,
ashleymills 0:e979170e02e7 5558 #endif
ashleymills 0:e979170e02e7 5559
ashleymills 0:e979170e02e7 5560 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
ashleymills 0:e979170e02e7 5561 TLS_RSA_WITH_HC_128_CBC_MD5,
ashleymills 0:e979170e02e7 5562 #endif
ashleymills 0:e979170e02e7 5563
ashleymills 0:e979170e02e7 5564 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
ashleymills 0:e979170e02e7 5565 TLS_RSA_WITH_HC_128_CBC_SHA,
ashleymills 0:e979170e02e7 5566 #endif
ashleymills 0:e979170e02e7 5567
ashleymills 0:e979170e02e7 5568 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
ashleymills 0:e979170e02e7 5569 TLS_RSA_WITH_RABBIT_CBC_SHA,
ashleymills 0:e979170e02e7 5570 #endif
ashleymills 0:e979170e02e7 5571
ashleymills 0:e979170e02e7 5572 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 5573 TLS_NTRU_RSA_WITH_RC4_128_SHA,
ashleymills 0:e979170e02e7 5574 #endif
ashleymills 0:e979170e02e7 5575
ashleymills 0:e979170e02e7 5576 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 5577 TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA,
ashleymills 0:e979170e02e7 5578 #endif
ashleymills 0:e979170e02e7 5579
ashleymills 0:e979170e02e7 5580 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5581 TLS_NTRU_RSA_WITH_AES_128_CBC_SHA,
ashleymills 0:e979170e02e7 5582 #endif
ashleymills 0:e979170e02e7 5583
ashleymills 0:e979170e02e7 5584 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5585 TLS_NTRU_RSA_WITH_AES_256_CBC_SHA,
ashleymills 0:e979170e02e7 5586 #endif
ashleymills 0:e979170e02e7 5587
ashleymills 0:e979170e02e7 5588 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8_SHA256
ashleymills 0:e979170e02e7 5589 TLS_RSA_WITH_AES_128_CCM_8_SHA256,
ashleymills 0:e979170e02e7 5590 #endif
ashleymills 0:e979170e02e7 5591
ashleymills 0:e979170e02e7 5592 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8_SHA384
ashleymills 0:e979170e02e7 5593 TLS_RSA_WITH_AES_256_CCM_8_SHA384,
ashleymills 0:e979170e02e7 5594 #endif
ashleymills 0:e979170e02e7 5595
ashleymills 0:e979170e02e7 5596 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_SHA256
ashleymills 0:e979170e02e7 5597 TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_SHA256,
ashleymills 0:e979170e02e7 5598 #endif
ashleymills 0:e979170e02e7 5599
ashleymills 0:e979170e02e7 5600 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8_SHA384
ashleymills 0:e979170e02e7 5601 TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8_SHA384,
ashleymills 0:e979170e02e7 5602 #endif
ashleymills 0:e979170e02e7 5603
ashleymills 0:e979170e02e7 5604 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5605 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
ashleymills 0:e979170e02e7 5606 #endif
ashleymills 0:e979170e02e7 5607
ashleymills 0:e979170e02e7 5608 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5609 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
ashleymills 0:e979170e02e7 5610 #endif
ashleymills 0:e979170e02e7 5611
ashleymills 0:e979170e02e7 5612 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5613 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
ashleymills 0:e979170e02e7 5614 #endif
ashleymills 0:e979170e02e7 5615
ashleymills 0:e979170e02e7 5616 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5617 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
ashleymills 0:e979170e02e7 5618 #endif
ashleymills 0:e979170e02e7 5619
ashleymills 0:e979170e02e7 5620 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 5621 TLS_ECDHE_RSA_WITH_RC4_128_SHA,
ashleymills 0:e979170e02e7 5622 #endif
ashleymills 0:e979170e02e7 5623
ashleymills 0:e979170e02e7 5624 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 5625 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
ashleymills 0:e979170e02e7 5626 #endif
ashleymills 0:e979170e02e7 5627
ashleymills 0:e979170e02e7 5628 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 5629 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
ashleymills 0:e979170e02e7 5630 #endif
ashleymills 0:e979170e02e7 5631
ashleymills 0:e979170e02e7 5632 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 5633 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
ashleymills 0:e979170e02e7 5634 #endif
ashleymills 0:e979170e02e7 5635
ashleymills 0:e979170e02e7 5636 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:e979170e02e7 5637 TLS_RSA_WITH_AES_128_CBC_SHA256,
ashleymills 0:e979170e02e7 5638 #endif
ashleymills 0:e979170e02e7 5639
ashleymills 0:e979170e02e7 5640 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
ashleymills 0:e979170e02e7 5641 TLS_RSA_WITH_AES_256_CBC_SHA256,
ashleymills 0:e979170e02e7 5642 #endif
ashleymills 0:e979170e02e7 5643
ashleymills 0:e979170e02e7 5644 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
ashleymills 0:e979170e02e7 5645 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
ashleymills 0:e979170e02e7 5646 #endif
ashleymills 0:e979170e02e7 5647
ashleymills 0:e979170e02e7 5648 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
ashleymills 0:e979170e02e7 5649 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
ashleymills 0:e979170e02e7 5650 #endif
ashleymills 0:e979170e02e7 5651
ashleymills 0:e979170e02e7 5652 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5653 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
ashleymills 0:e979170e02e7 5654 #endif
ashleymills 0:e979170e02e7 5655
ashleymills 0:e979170e02e7 5656 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5657 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
ashleymills 0:e979170e02e7 5658 #endif
ashleymills 0:e979170e02e7 5659
ashleymills 0:e979170e02e7 5660 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
ashleymills 0:e979170e02e7 5661 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
ashleymills 0:e979170e02e7 5662 #endif
ashleymills 0:e979170e02e7 5663
ashleymills 0:e979170e02e7 5664 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
ashleymills 0:e979170e02e7 5665 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
ashleymills 0:e979170e02e7 5666 #endif
ashleymills 0:e979170e02e7 5667
ashleymills 0:e979170e02e7 5668 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 5669 TLS_ECDH_RSA_WITH_RC4_128_SHA,
ashleymills 0:e979170e02e7 5670 #endif
ashleymills 0:e979170e02e7 5671
ashleymills 0:e979170e02e7 5672 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 5673 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
ashleymills 0:e979170e02e7 5674 #endif
ashleymills 0:e979170e02e7 5675
ashleymills 0:e979170e02e7 5676 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
ashleymills 0:e979170e02e7 5677 TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
ashleymills 0:e979170e02e7 5678 #endif
ashleymills 0:e979170e02e7 5679
ashleymills 0:e979170e02e7 5680 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
ashleymills 0:e979170e02e7 5681 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
ashleymills 0:e979170e02e7 5682 #endif
ashleymills 0:e979170e02e7 5683
ashleymills 0:e979170e02e7 5684 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 5685 TLS_RSA_WITH_AES_128_GCM_SHA256,
ashleymills 0:e979170e02e7 5686 #endif
ashleymills 0:e979170e02e7 5687
ashleymills 0:e979170e02e7 5688 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 5689 TLS_RSA_WITH_AES_256_GCM_SHA384,
ashleymills 0:e979170e02e7 5690 #endif
ashleymills 0:e979170e02e7 5691
ashleymills 0:e979170e02e7 5692 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 5693 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
ashleymills 0:e979170e02e7 5694 #endif
ashleymills 0:e979170e02e7 5695
ashleymills 0:e979170e02e7 5696 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 5697 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
ashleymills 0:e979170e02e7 5698 #endif
ashleymills 0:e979170e02e7 5699
ashleymills 0:e979170e02e7 5700 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 5701 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
ashleymills 0:e979170e02e7 5702 #endif
ashleymills 0:e979170e02e7 5703
ashleymills 0:e979170e02e7 5704 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 5705 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
ashleymills 0:e979170e02e7 5706 #endif
ashleymills 0:e979170e02e7 5707
ashleymills 0:e979170e02e7 5708 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 5709 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
ashleymills 0:e979170e02e7 5710 #endif
ashleymills 0:e979170e02e7 5711
ashleymills 0:e979170e02e7 5712 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 5713 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
ashleymills 0:e979170e02e7 5714 #endif
ashleymills 0:e979170e02e7 5715
ashleymills 0:e979170e02e7 5716 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 5717 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
ashleymills 0:e979170e02e7 5718 #endif
ashleymills 0:e979170e02e7 5719
ashleymills 0:e979170e02e7 5720 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 5721 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
ashleymills 0:e979170e02e7 5722 #endif
ashleymills 0:e979170e02e7 5723
ashleymills 0:e979170e02e7 5724 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
ashleymills 0:e979170e02e7 5725 TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
ashleymills 0:e979170e02e7 5726 #endif
ashleymills 0:e979170e02e7 5727
ashleymills 0:e979170e02e7 5728 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
ashleymills 0:e979170e02e7 5729 TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
ashleymills 0:e979170e02e7 5730 #endif
ashleymills 0:e979170e02e7 5731
ashleymills 0:e979170e02e7 5732 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
ashleymills 0:e979170e02e7 5733 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
ashleymills 0:e979170e02e7 5734 #endif
ashleymills 0:e979170e02e7 5735
ashleymills 0:e979170e02e7 5736 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
ashleymills 0:e979170e02e7 5737 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
ashleymills 0:e979170e02e7 5738 #endif
ashleymills 0:e979170e02e7 5739
ashleymills 0:e979170e02e7 5740 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
ashleymills 0:e979170e02e7 5741 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
ashleymills 0:e979170e02e7 5742 #endif
ashleymills 0:e979170e02e7 5743
ashleymills 0:e979170e02e7 5744 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
ashleymills 0:e979170e02e7 5745 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
ashleymills 0:e979170e02e7 5746 #endif
ashleymills 0:e979170e02e7 5747
ashleymills 0:e979170e02e7 5748 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
ashleymills 0:e979170e02e7 5749 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
ashleymills 0:e979170e02e7 5750 #endif
ashleymills 0:e979170e02e7 5751
ashleymills 0:e979170e02e7 5752 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
ashleymills 0:e979170e02e7 5753 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
ashleymills 0:e979170e02e7 5754 #endif
ashleymills 0:e979170e02e7 5755
ashleymills 0:e979170e02e7 5756 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
ashleymills 0:e979170e02e7 5757 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
ashleymills 0:e979170e02e7 5758 #endif
ashleymills 0:e979170e02e7 5759
ashleymills 0:e979170e02e7 5760 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
ashleymills 0:e979170e02e7 5761 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
ashleymills 0:e979170e02e7 5762 #endif
ashleymills 0:e979170e02e7 5763
ashleymills 0:e979170e02e7 5764 };
ashleymills 0:e979170e02e7 5765
ashleymills 0:e979170e02e7 5766
ashleymills 0:e979170e02e7 5767 /* return true if set, else false */
ashleymills 0:e979170e02e7 5768 /* only supports full name from cipher_name[] delimited by : */
ashleymills 0:e979170e02e7 5769 int SetCipherList(Suites* s, const char* list)
ashleymills 0:e979170e02e7 5770 {
ashleymills 0:e979170e02e7 5771 int ret = 0, i;
ashleymills 0:e979170e02e7 5772 char name[MAX_SUITE_NAME];
ashleymills 0:e979170e02e7 5773
ashleymills 0:e979170e02e7 5774 char needle[] = ":";
ashleymills 0:e979170e02e7 5775 char* haystack = (char*)list;
ashleymills 0:e979170e02e7 5776 char* prev;
ashleymills 0:e979170e02e7 5777
ashleymills 0:e979170e02e7 5778 const int suiteSz = sizeof(cipher_names) / sizeof(cipher_names[0]);
ashleymills 0:e979170e02e7 5779 int idx = 0;
ashleymills 0:e979170e02e7 5780
ashleymills 0:e979170e02e7 5781 if (s == NULL) {
ashleymills 0:e979170e02e7 5782 CYASSL_MSG("SetCipherList suite pointer error");
ashleymills 0:e979170e02e7 5783 return 0;
ashleymills 0:e979170e02e7 5784 }
ashleymills 0:e979170e02e7 5785
ashleymills 0:e979170e02e7 5786 if (!list)
ashleymills 0:e979170e02e7 5787 return 0;
ashleymills 0:e979170e02e7 5788
ashleymills 0:e979170e02e7 5789 if (*list == 0) return 1; /* CyaSSL default */
ashleymills 0:e979170e02e7 5790
ashleymills 0:e979170e02e7 5791 if (XSTRNCMP(haystack, "ALL", 3) == 0) return 1; /* CyaSSL defualt */
ashleymills 0:e979170e02e7 5792
ashleymills 0:e979170e02e7 5793 for(;;) {
ashleymills 0:e979170e02e7 5794 word32 len;
ashleymills 0:e979170e02e7 5795 prev = haystack;
ashleymills 0:e979170e02e7 5796 haystack = XSTRSTR(haystack, needle);
ashleymills 0:e979170e02e7 5797
ashleymills 0:e979170e02e7 5798 if (!haystack) /* last cipher */
ashleymills 0:e979170e02e7 5799 len = min(sizeof(name), (word32)XSTRLEN(prev));
ashleymills 0:e979170e02e7 5800 else
ashleymills 0:e979170e02e7 5801 len = min(sizeof(name), (word32)(haystack - prev));
ashleymills 0:e979170e02e7 5802
ashleymills 0:e979170e02e7 5803 XSTRNCPY(name, prev, len);
ashleymills 0:e979170e02e7 5804 name[(len == sizeof(name)) ? len - 1 : len] = 0;
ashleymills 0:e979170e02e7 5805
ashleymills 0:e979170e02e7 5806 for (i = 0; i < suiteSz; i++)
ashleymills 0:e979170e02e7 5807 if (XSTRNCMP(name, cipher_names[i], sizeof(name)) == 0) {
ashleymills 0:e979170e02e7 5808 if (XSTRSTR(name, "EC") || XSTRSTR(name, "CCM"))
ashleymills 0:e979170e02e7 5809 s->suites[idx++] = ECC_BYTE; /* ECC suite */
ashleymills 0:e979170e02e7 5810 else
ashleymills 0:e979170e02e7 5811 s->suites[idx++] = 0x00; /* normal */
ashleymills 0:e979170e02e7 5812 s->suites[idx++] = (byte)cipher_name_idx[i];
ashleymills 0:e979170e02e7 5813
ashleymills 0:e979170e02e7 5814 if (!ret) ret = 1; /* found at least one */
ashleymills 0:e979170e02e7 5815 break;
ashleymills 0:e979170e02e7 5816 }
ashleymills 0:e979170e02e7 5817 if (!haystack) break;
ashleymills 0:e979170e02e7 5818 haystack++;
ashleymills 0:e979170e02e7 5819 }
ashleymills 0:e979170e02e7 5820
ashleymills 0:e979170e02e7 5821 if (ret) {
ashleymills 0:e979170e02e7 5822 s->setSuites = 1;
ashleymills 0:e979170e02e7 5823 s->suiteSz = (word16)idx;
ashleymills 0:e979170e02e7 5824 }
ashleymills 0:e979170e02e7 5825
ashleymills 0:e979170e02e7 5826 return ret;
ashleymills 0:e979170e02e7 5827 }
ashleymills 0:e979170e02e7 5828
ashleymills 0:e979170e02e7 5829
ashleymills 0:e979170e02e7 5830 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 5831
ashleymills 0:e979170e02e7 5832 /* Initialisze HandShakeInfo */
ashleymills 0:e979170e02e7 5833 void InitHandShakeInfo(HandShakeInfo* info)
ashleymills 0:e979170e02e7 5834 {
ashleymills 0:e979170e02e7 5835 int i;
ashleymills 0:e979170e02e7 5836
ashleymills 0:e979170e02e7 5837 info->cipherName[0] = 0;
ashleymills 0:e979170e02e7 5838 for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
ashleymills 0:e979170e02e7 5839 info->packetNames[i][0] = 0;
ashleymills 0:e979170e02e7 5840 info->numberPackets = 0;
ashleymills 0:e979170e02e7 5841 info->negotiationError = 0;
ashleymills 0:e979170e02e7 5842 }
ashleymills 0:e979170e02e7 5843
ashleymills 0:e979170e02e7 5844 /* Set Final HandShakeInfo parameters */
ashleymills 0:e979170e02e7 5845 void FinishHandShakeInfo(HandShakeInfo* info, const CYASSL* ssl)
ashleymills 0:e979170e02e7 5846 {
ashleymills 0:e979170e02e7 5847 int i;
ashleymills 0:e979170e02e7 5848 int sz = sizeof(cipher_name_idx)/sizeof(int);
ashleymills 0:e979170e02e7 5849
ashleymills 0:e979170e02e7 5850 for (i = 0; i < sz; i++)
ashleymills 0:e979170e02e7 5851 if (ssl->options.cipherSuite == (byte)cipher_name_idx[i]) {
ashleymills 0:e979170e02e7 5852 if (ssl->options.cipherSuite0 == ECC_BYTE)
ashleymills 0:e979170e02e7 5853 continue; /* ECC suites at end */
ashleymills 0:e979170e02e7 5854 XSTRNCPY(info->cipherName, cipher_names[i], MAX_CIPHERNAME_SZ);
ashleymills 0:e979170e02e7 5855 break;
ashleymills 0:e979170e02e7 5856 }
ashleymills 0:e979170e02e7 5857
ashleymills 0:e979170e02e7 5858 /* error max and min are negative numbers */
ashleymills 0:e979170e02e7 5859 if (ssl->error <= MIN_PARAM_ERR && ssl->error >= MAX_PARAM_ERR)
ashleymills 0:e979170e02e7 5860 info->negotiationError = ssl->error;
ashleymills 0:e979170e02e7 5861 }
ashleymills 0:e979170e02e7 5862
ashleymills 0:e979170e02e7 5863
ashleymills 0:e979170e02e7 5864 /* Add name to info packet names, increase packet name count */
ashleymills 0:e979170e02e7 5865 void AddPacketName(const char* name, HandShakeInfo* info)
ashleymills 0:e979170e02e7 5866 {
ashleymills 0:e979170e02e7 5867 if (info->numberPackets < MAX_PACKETS_HANDSHAKE) {
ashleymills 0:e979170e02e7 5868 XSTRNCPY(info->packetNames[info->numberPackets++], name,
ashleymills 0:e979170e02e7 5869 MAX_PACKETNAME_SZ);
ashleymills 0:e979170e02e7 5870 }
ashleymills 0:e979170e02e7 5871 }
ashleymills 0:e979170e02e7 5872
ashleymills 0:e979170e02e7 5873
ashleymills 0:e979170e02e7 5874 /* Initialisze TimeoutInfo */
ashleymills 0:e979170e02e7 5875 void InitTimeoutInfo(TimeoutInfo* info)
ashleymills 0:e979170e02e7 5876 {
ashleymills 0:e979170e02e7 5877 int i;
ashleymills 0:e979170e02e7 5878
ashleymills 0:e979170e02e7 5879 info->timeoutName[0] = 0;
ashleymills 0:e979170e02e7 5880 info->flags = 0;
ashleymills 0:e979170e02e7 5881
ashleymills 0:e979170e02e7 5882 for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++) {
ashleymills 0:e979170e02e7 5883 info->packets[i].packetName[0] = 0;
ashleymills 0:e979170e02e7 5884 info->packets[i].timestamp.tv_sec = 0;
ashleymills 0:e979170e02e7 5885 info->packets[i].timestamp.tv_usec = 0;
ashleymills 0:e979170e02e7 5886 info->packets[i].bufferValue = 0;
ashleymills 0:e979170e02e7 5887 info->packets[i].valueSz = 0;
ashleymills 0:e979170e02e7 5888 }
ashleymills 0:e979170e02e7 5889 info->numberPackets = 0;
ashleymills 0:e979170e02e7 5890 info->timeoutValue.tv_sec = 0;
ashleymills 0:e979170e02e7 5891 info->timeoutValue.tv_usec = 0;
ashleymills 0:e979170e02e7 5892 }
ashleymills 0:e979170e02e7 5893
ashleymills 0:e979170e02e7 5894
ashleymills 0:e979170e02e7 5895 /* Free TimeoutInfo */
ashleymills 0:e979170e02e7 5896 void FreeTimeoutInfo(TimeoutInfo* info, void* heap)
ashleymills 0:e979170e02e7 5897 {
ashleymills 0:e979170e02e7 5898 int i;
ashleymills 0:e979170e02e7 5899 for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
ashleymills 0:e979170e02e7 5900 if (info->packets[i].bufferValue) {
ashleymills 0:e979170e02e7 5901 XFREE(info->packets[i].bufferValue, heap, DYNAMIC_TYPE_INFO);
ashleymills 0:e979170e02e7 5902 info->packets[i].bufferValue = 0;
ashleymills 0:e979170e02e7 5903 }
ashleymills 0:e979170e02e7 5904
ashleymills 0:e979170e02e7 5905 }
ashleymills 0:e979170e02e7 5906
ashleymills 0:e979170e02e7 5907
ashleymills 0:e979170e02e7 5908 /* Add PacketInfo to TimeoutInfo */
ashleymills 0:e979170e02e7 5909 void AddPacketInfo(const char* name, TimeoutInfo* info, const byte* data,
ashleymills 0:e979170e02e7 5910 int sz, void* heap)
ashleymills 0:e979170e02e7 5911 {
ashleymills 0:e979170e02e7 5912 if (info->numberPackets < (MAX_PACKETS_HANDSHAKE - 1)) {
ashleymills 0:e979170e02e7 5913 Timeval currTime;
ashleymills 0:e979170e02e7 5914
ashleymills 0:e979170e02e7 5915 /* may add name after */
ashleymills 0:e979170e02e7 5916 if (name)
ashleymills 0:e979170e02e7 5917 XSTRNCPY(info->packets[info->numberPackets].packetName, name,
ashleymills 0:e979170e02e7 5918 MAX_PACKETNAME_SZ);
ashleymills 0:e979170e02e7 5919
ashleymills 0:e979170e02e7 5920 /* add data, put in buffer if bigger than static buffer */
ashleymills 0:e979170e02e7 5921 info->packets[info->numberPackets].valueSz = sz;
ashleymills 0:e979170e02e7 5922 if (sz < MAX_VALUE_SZ)
ashleymills 0:e979170e02e7 5923 XMEMCPY(info->packets[info->numberPackets].value, data, sz);
ashleymills 0:e979170e02e7 5924 else {
ashleymills 0:e979170e02e7 5925 info->packets[info->numberPackets].bufferValue =
ashleymills 0:e979170e02e7 5926 XMALLOC(sz, heap, DYNAMIC_TYPE_INFO);
ashleymills 0:e979170e02e7 5927 if (!info->packets[info->numberPackets].bufferValue)
ashleymills 0:e979170e02e7 5928 /* let next alloc catch, just don't fill, not fatal here */
ashleymills 0:e979170e02e7 5929 info->packets[info->numberPackets].valueSz = 0;
ashleymills 0:e979170e02e7 5930 else
ashleymills 0:e979170e02e7 5931 XMEMCPY(info->packets[info->numberPackets].bufferValue,
ashleymills 0:e979170e02e7 5932 data, sz);
ashleymills 0:e979170e02e7 5933 }
ashleymills 0:e979170e02e7 5934 gettimeofday(&currTime, 0);
ashleymills 0:e979170e02e7 5935 info->packets[info->numberPackets].timestamp.tv_sec =
ashleymills 0:e979170e02e7 5936 currTime.tv_sec;
ashleymills 0:e979170e02e7 5937 info->packets[info->numberPackets].timestamp.tv_usec =
ashleymills 0:e979170e02e7 5938 currTime.tv_usec;
ashleymills 0:e979170e02e7 5939 info->numberPackets++;
ashleymills 0:e979170e02e7 5940 }
ashleymills 0:e979170e02e7 5941 }
ashleymills 0:e979170e02e7 5942
ashleymills 0:e979170e02e7 5943
ashleymills 0:e979170e02e7 5944 /* Add packet name to previsouly added packet info */
ashleymills 0:e979170e02e7 5945 void AddLateName(const char* name, TimeoutInfo* info)
ashleymills 0:e979170e02e7 5946 {
ashleymills 0:e979170e02e7 5947 /* make sure we have a valid previous one */
ashleymills 0:e979170e02e7 5948 if (info->numberPackets > 0 && info->numberPackets <
ashleymills 0:e979170e02e7 5949 MAX_PACKETS_HANDSHAKE) {
ashleymills 0:e979170e02e7 5950 XSTRNCPY(info->packets[info->numberPackets - 1].packetName, name,
ashleymills 0:e979170e02e7 5951 MAX_PACKETNAME_SZ);
ashleymills 0:e979170e02e7 5952 }
ashleymills 0:e979170e02e7 5953 }
ashleymills 0:e979170e02e7 5954
ashleymills 0:e979170e02e7 5955 /* Add record header to previsouly added packet info */
ashleymills 0:e979170e02e7 5956 void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info)
ashleymills 0:e979170e02e7 5957 {
ashleymills 0:e979170e02e7 5958 /* make sure we have a valid previous one */
ashleymills 0:e979170e02e7 5959 if (info->numberPackets > 0 && info->numberPackets <
ashleymills 0:e979170e02e7 5960 MAX_PACKETS_HANDSHAKE) {
ashleymills 0:e979170e02e7 5961 if (info->packets[info->numberPackets - 1].bufferValue)
ashleymills 0:e979170e02e7 5962 XMEMCPY(info->packets[info->numberPackets - 1].bufferValue, rl,
ashleymills 0:e979170e02e7 5963 RECORD_HEADER_SZ);
ashleymills 0:e979170e02e7 5964 else
ashleymills 0:e979170e02e7 5965 XMEMCPY(info->packets[info->numberPackets - 1].value, rl,
ashleymills 0:e979170e02e7 5966 RECORD_HEADER_SZ);
ashleymills 0:e979170e02e7 5967 }
ashleymills 0:e979170e02e7 5968 }
ashleymills 0:e979170e02e7 5969
ashleymills 0:e979170e02e7 5970 #endif /* CYASSL_CALLBACKS */
ashleymills 0:e979170e02e7 5971
ashleymills 0:e979170e02e7 5972
ashleymills 0:e979170e02e7 5973
ashleymills 0:e979170e02e7 5974 /* client only parts */
ashleymills 0:e979170e02e7 5975 #ifndef NO_CYASSL_CLIENT
ashleymills 0:e979170e02e7 5976
ashleymills 0:e979170e02e7 5977 int SendClientHello(CYASSL* ssl)
ashleymills 0:e979170e02e7 5978 {
ashleymills 0:e979170e02e7 5979 byte *output;
ashleymills 0:e979170e02e7 5980 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 5981 int sendSz;
ashleymills 0:e979170e02e7 5982 int idSz = ssl->options.resuming ? ID_LEN : 0;
ashleymills 0:e979170e02e7 5983 int ret;
ashleymills 0:e979170e02e7 5984
ashleymills 0:e979170e02e7 5985 if (ssl->suites == NULL) {
ashleymills 0:e979170e02e7 5986 CYASSL_MSG("Bad suites pointer in SendClientHello");
ashleymills 0:e979170e02e7 5987 return SUITES_ERROR;
ashleymills 0:e979170e02e7 5988 }
ashleymills 0:e979170e02e7 5989
ashleymills 0:e979170e02e7 5990 length = VERSION_SZ + RAN_LEN
ashleymills 0:e979170e02e7 5991 + idSz + ENUM_LEN
ashleymills 0:e979170e02e7 5992 + ssl->suites->suiteSz + SUITE_LEN
ashleymills 0:e979170e02e7 5993 + COMP_LEN + ENUM_LEN;
ashleymills 0:e979170e02e7 5994
ashleymills 0:e979170e02e7 5995 if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:e979170e02e7 5996 length += HELLO_EXT_SZ;
ashleymills 0:e979170e02e7 5997
ashleymills 0:e979170e02e7 5998 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 5999
ashleymills 0:e979170e02e7 6000 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 6001 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 6002 length += ENUM_LEN; /* cookie */
ashleymills 0:e979170e02e7 6003 if (ssl->arrays->cookieSz != 0) length += ssl->arrays->cookieSz;
ashleymills 0:e979170e02e7 6004 sendSz = length + DTLS_HANDSHAKE_HEADER_SZ + DTLS_RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 6005 idx += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
ashleymills 0:e979170e02e7 6006 }
ashleymills 0:e979170e02e7 6007 #endif
ashleymills 0:e979170e02e7 6008
ashleymills 0:e979170e02e7 6009 /* check for avalaible size */
ashleymills 0:e979170e02e7 6010 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
ashleymills 0:e979170e02e7 6011 return ret;
ashleymills 0:e979170e02e7 6012
ashleymills 0:e979170e02e7 6013
ashleymills 0:e979170e02e7 6014 /* get ouput buffer */
ashleymills 0:e979170e02e7 6015 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 6016 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 6017
ashleymills 0:e979170e02e7 6018 AddHeaders(output, length, client_hello, ssl);
ashleymills 0:e979170e02e7 6019
ashleymills 0:e979170e02e7 6020 /* client hello, first version */
ashleymills 0:e979170e02e7 6021 output[idx++] = ssl->version.major;
ashleymills 0:e979170e02e7 6022 output[idx++] = ssl->version.minor;
ashleymills 0:e979170e02e7 6023 ssl->chVersion = ssl->version; /* store in case changed */
ashleymills 0:e979170e02e7 6024
ashleymills 0:e979170e02e7 6025 /* then random */
ashleymills 0:e979170e02e7 6026 if (ssl->options.connectState == CONNECT_BEGIN) {
ashleymills 0:e979170e02e7 6027 RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN);
ashleymills 0:e979170e02e7 6028
ashleymills 0:e979170e02e7 6029 /* store random */
ashleymills 0:e979170e02e7 6030 XMEMCPY(ssl->arrays->clientRandom, output + idx, RAN_LEN);
ashleymills 0:e979170e02e7 6031 } else {
ashleymills 0:e979170e02e7 6032 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 6033 /* send same random on hello again */
ashleymills 0:e979170e02e7 6034 XMEMCPY(output + idx, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:e979170e02e7 6035 #endif
ashleymills 0:e979170e02e7 6036 }
ashleymills 0:e979170e02e7 6037 idx += RAN_LEN;
ashleymills 0:e979170e02e7 6038
ashleymills 0:e979170e02e7 6039 /* then session id */
ashleymills 0:e979170e02e7 6040 output[idx++] = (byte)idSz;
ashleymills 0:e979170e02e7 6041 if (idSz) {
ashleymills 0:e979170e02e7 6042 XMEMCPY(output + idx, ssl->session.sessionID, ID_LEN);
ashleymills 0:e979170e02e7 6043 idx += ID_LEN;
ashleymills 0:e979170e02e7 6044 }
ashleymills 0:e979170e02e7 6045
ashleymills 0:e979170e02e7 6046 /* then DTLS cookie */
ashleymills 0:e979170e02e7 6047 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 6048 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 6049 byte cookieSz = ssl->arrays->cookieSz;
ashleymills 0:e979170e02e7 6050
ashleymills 0:e979170e02e7 6051 output[idx++] = cookieSz;
ashleymills 0:e979170e02e7 6052 if (cookieSz) {
ashleymills 0:e979170e02e7 6053 XMEMCPY(&output[idx], ssl->arrays->cookie, cookieSz);
ashleymills 0:e979170e02e7 6054 idx += cookieSz;
ashleymills 0:e979170e02e7 6055 }
ashleymills 0:e979170e02e7 6056 }
ashleymills 0:e979170e02e7 6057 #endif
ashleymills 0:e979170e02e7 6058 /* then cipher suites */
ashleymills 0:e979170e02e7 6059 c16toa(ssl->suites->suiteSz, output + idx);
ashleymills 0:e979170e02e7 6060 idx += 2;
ashleymills 0:e979170e02e7 6061 XMEMCPY(output + idx, &ssl->suites->suites, ssl->suites->suiteSz);
ashleymills 0:e979170e02e7 6062 idx += ssl->suites->suiteSz;
ashleymills 0:e979170e02e7 6063
ashleymills 0:e979170e02e7 6064 /* last, compression */
ashleymills 0:e979170e02e7 6065 output[idx++] = COMP_LEN;
ashleymills 0:e979170e02e7 6066 if (ssl->options.usingCompression)
ashleymills 0:e979170e02e7 6067 output[idx++] = ZLIB_COMPRESSION;
ashleymills 0:e979170e02e7 6068 else
ashleymills 0:e979170e02e7 6069 output[idx++] = NO_COMPRESSION;
ashleymills 0:e979170e02e7 6070
ashleymills 0:e979170e02e7 6071 if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:e979170e02e7 6072 {
ashleymills 0:e979170e02e7 6073 /* add in the extensions length */
ashleymills 0:e979170e02e7 6074 c16toa(HELLO_EXT_LEN, output + idx);
ashleymills 0:e979170e02e7 6075 idx += 2;
ashleymills 0:e979170e02e7 6076
ashleymills 0:e979170e02e7 6077 c16toa(HELLO_EXT_SIG_ALGO, output + idx);
ashleymills 0:e979170e02e7 6078 idx += 2;
ashleymills 0:e979170e02e7 6079 c16toa(HELLO_EXT_SIGALGO_SZ, output + idx);
ashleymills 0:e979170e02e7 6080 idx += 2;
ashleymills 0:e979170e02e7 6081 /* This is a lazy list setup. Eventually, we'll need to support
ashleymills 0:e979170e02e7 6082 * using other hash types or even other extensions. */
ashleymills 0:e979170e02e7 6083 c16toa(HELLO_EXT_SIGALGO_LEN, output + idx);
ashleymills 0:e979170e02e7 6084 idx += 2;
ashleymills 0:e979170e02e7 6085 output[idx++] = sha_mac;
ashleymills 0:e979170e02e7 6086 output[idx++] = rsa_sa_algo;
ashleymills 0:e979170e02e7 6087 output[idx++] = sha_mac;
ashleymills 0:e979170e02e7 6088 output[idx++] = dsa_sa_algo;
ashleymills 0:e979170e02e7 6089 output[idx++] = sha_mac;
ashleymills 0:e979170e02e7 6090 output[idx++] = ecc_dsa_sa_algo;
ashleymills 0:e979170e02e7 6091 }
ashleymills 0:e979170e02e7 6092
ashleymills 0:e979170e02e7 6093 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 6094 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 6095 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:e979170e02e7 6096 return ret;
ashleymills 0:e979170e02e7 6097 }
ashleymills 0:e979170e02e7 6098 #endif
ashleymills 0:e979170e02e7 6099 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:e979170e02e7 6100
ashleymills 0:e979170e02e7 6101 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
ashleymills 0:e979170e02e7 6102
ashleymills 0:e979170e02e7 6103 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 6104 if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 6105 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 6106 AddPacketInfo("ClientHello", &ssl->timeoutInfo, output, sendSz,
ashleymills 0:e979170e02e7 6107 ssl->heap);
ashleymills 0:e979170e02e7 6108 #endif
ashleymills 0:e979170e02e7 6109
ashleymills 0:e979170e02e7 6110 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:e979170e02e7 6111
ashleymills 0:e979170e02e7 6112 return SendBuffered(ssl);
ashleymills 0:e979170e02e7 6113 }
ashleymills 0:e979170e02e7 6114
ashleymills 0:e979170e02e7 6115
ashleymills 0:e979170e02e7 6116 static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input,
ashleymills 0:e979170e02e7 6117 word32* inOutIdx)
ashleymills 0:e979170e02e7 6118 {
ashleymills 0:e979170e02e7 6119 ProtocolVersion pv;
ashleymills 0:e979170e02e7 6120 byte cookieSz;
ashleymills 0:e979170e02e7 6121
ashleymills 0:e979170e02e7 6122 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 6123 if (ssl->hsInfoOn) AddPacketName("HelloVerifyRequest",
ashleymills 0:e979170e02e7 6124 &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 6125 if (ssl->toInfoOn) AddLateName("HelloVerifyRequest", &ssl->timeoutInfo);
ashleymills 0:e979170e02e7 6126 #endif
ashleymills 0:e979170e02e7 6127 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 6128 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 6129 DtlsPoolReset(ssl);
ashleymills 0:e979170e02e7 6130 }
ashleymills 0:e979170e02e7 6131 #endif
ashleymills 0:e979170e02e7 6132 XMEMCPY(&pv, input + *inOutIdx, sizeof(pv));
ashleymills 0:e979170e02e7 6133 *inOutIdx += (word32)sizeof(pv);
ashleymills 0:e979170e02e7 6134
ashleymills 0:e979170e02e7 6135 cookieSz = input[(*inOutIdx)++];
ashleymills 0:e979170e02e7 6136
ashleymills 0:e979170e02e7 6137 if (cookieSz) {
ashleymills 0:e979170e02e7 6138 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 6139 if (cookieSz <= MAX_COOKIE_LEN) {
ashleymills 0:e979170e02e7 6140 XMEMCPY(ssl->arrays->cookie, input + *inOutIdx, cookieSz);
ashleymills 0:e979170e02e7 6141 ssl->arrays->cookieSz = cookieSz;
ashleymills 0:e979170e02e7 6142 }
ashleymills 0:e979170e02e7 6143 #endif
ashleymills 0:e979170e02e7 6144 *inOutIdx += cookieSz;
ashleymills 0:e979170e02e7 6145 }
ashleymills 0:e979170e02e7 6146
ashleymills 0:e979170e02e7 6147 ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
ashleymills 0:e979170e02e7 6148 return 0;
ashleymills 0:e979170e02e7 6149 }
ashleymills 0:e979170e02e7 6150
ashleymills 0:e979170e02e7 6151
ashleymills 0:e979170e02e7 6152 static int DoServerHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
ashleymills 0:e979170e02e7 6153 word32 helloSz)
ashleymills 0:e979170e02e7 6154 {
ashleymills 0:e979170e02e7 6155 byte b;
ashleymills 0:e979170e02e7 6156 byte compression;
ashleymills 0:e979170e02e7 6157 ProtocolVersion pv;
ashleymills 0:e979170e02e7 6158 word32 i = *inOutIdx;
ashleymills 0:e979170e02e7 6159 word32 begin = i;
ashleymills 0:e979170e02e7 6160
ashleymills 0:e979170e02e7 6161 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 6162 if (ssl->hsInfoOn) AddPacketName("ServerHello", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 6163 if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
ashleymills 0:e979170e02e7 6164 #endif
ashleymills 0:e979170e02e7 6165 XMEMCPY(&pv, input + i, sizeof(pv));
ashleymills 0:e979170e02e7 6166 i += (word32)sizeof(pv);
ashleymills 0:e979170e02e7 6167 if (pv.minor > ssl->version.minor) {
ashleymills 0:e979170e02e7 6168 CYASSL_MSG("Server using higher version, fatal error");
ashleymills 0:e979170e02e7 6169 return VERSION_ERROR;
ashleymills 0:e979170e02e7 6170 }
ashleymills 0:e979170e02e7 6171 else if (pv.minor < ssl->version.minor) {
ashleymills 0:e979170e02e7 6172 CYASSL_MSG("server using lower version");
ashleymills 0:e979170e02e7 6173 if (!ssl->options.downgrade) {
ashleymills 0:e979170e02e7 6174 CYASSL_MSG(" no downgrade allowed, fatal error");
ashleymills 0:e979170e02e7 6175 return VERSION_ERROR;
ashleymills 0:e979170e02e7 6176 }
ashleymills 0:e979170e02e7 6177 else if (pv.minor == SSLv3_MINOR) {
ashleymills 0:e979170e02e7 6178 /* turn off tls */
ashleymills 0:e979170e02e7 6179 CYASSL_MSG(" downgrading to SSLv3");
ashleymills 0:e979170e02e7 6180 ssl->options.tls = 0;
ashleymills 0:e979170e02e7 6181 ssl->options.tls1_1 = 0;
ashleymills 0:e979170e02e7 6182 ssl->version.minor = SSLv3_MINOR;
ashleymills 0:e979170e02e7 6183 }
ashleymills 0:e979170e02e7 6184 else if (pv.minor == TLSv1_MINOR) {
ashleymills 0:e979170e02e7 6185 /* turn off tls 1.1+ */
ashleymills 0:e979170e02e7 6186 CYASSL_MSG(" downgrading to TLSv1");
ashleymills 0:e979170e02e7 6187 ssl->options.tls1_1 = 0;
ashleymills 0:e979170e02e7 6188 ssl->version.minor = TLSv1_MINOR;
ashleymills 0:e979170e02e7 6189 }
ashleymills 0:e979170e02e7 6190 else if (pv.minor == TLSv1_1_MINOR) {
ashleymills 0:e979170e02e7 6191 CYASSL_MSG(" downgrading to TLSv1.1");
ashleymills 0:e979170e02e7 6192 ssl->version.minor = TLSv1_1_MINOR;
ashleymills 0:e979170e02e7 6193 }
ashleymills 0:e979170e02e7 6194 }
ashleymills 0:e979170e02e7 6195 XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN);
ashleymills 0:e979170e02e7 6196 i += RAN_LEN;
ashleymills 0:e979170e02e7 6197 b = input[i++];
ashleymills 0:e979170e02e7 6198 if (b) {
ashleymills 0:e979170e02e7 6199 XMEMCPY(ssl->arrays->sessionID, input + i, min(b, ID_LEN));
ashleymills 0:e979170e02e7 6200 i += b;
ashleymills 0:e979170e02e7 6201 ssl->options.haveSessionId = 1;
ashleymills 0:e979170e02e7 6202 }
ashleymills 0:e979170e02e7 6203 ssl->options.cipherSuite0 = input[i++];
ashleymills 0:e979170e02e7 6204 ssl->options.cipherSuite = input[i++];
ashleymills 0:e979170e02e7 6205 compression = input[i++];
ashleymills 0:e979170e02e7 6206
ashleymills 0:e979170e02e7 6207 if (compression != ZLIB_COMPRESSION && ssl->options.usingCompression) {
ashleymills 0:e979170e02e7 6208 CYASSL_MSG("Server refused compression, turning off");
ashleymills 0:e979170e02e7 6209 ssl->options.usingCompression = 0; /* turn off if server refused */
ashleymills 0:e979170e02e7 6210 }
ashleymills 0:e979170e02e7 6211
ashleymills 0:e979170e02e7 6212 *inOutIdx = i;
ashleymills 0:e979170e02e7 6213 if ( (i - begin) < helloSz)
ashleymills 0:e979170e02e7 6214 *inOutIdx = begin + helloSz; /* skip extensions */
ashleymills 0:e979170e02e7 6215
ashleymills 0:e979170e02e7 6216 ssl->options.serverState = SERVER_HELLO_COMPLETE;
ashleymills 0:e979170e02e7 6217
ashleymills 0:e979170e02e7 6218 *inOutIdx = i;
ashleymills 0:e979170e02e7 6219
ashleymills 0:e979170e02e7 6220 if (ssl->options.resuming) {
ashleymills 0:e979170e02e7 6221 if (ssl->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID,
ashleymills 0:e979170e02e7 6222 ssl->session.sessionID, ID_LEN) == 0) {
ashleymills 0:e979170e02e7 6223 if (SetCipherSpecs(ssl) == 0) {
ashleymills 0:e979170e02e7 6224 int ret;
ashleymills 0:e979170e02e7 6225 XMEMCPY(ssl->arrays->masterSecret,
ashleymills 0:e979170e02e7 6226 ssl->session.masterSecret, SECRET_LEN);
ashleymills 0:e979170e02e7 6227 #ifndef NO_OLD_TLS
ashleymills 0:e979170e02e7 6228 if (ssl->options.tls)
ashleymills 0:e979170e02e7 6229 ret = DeriveTlsKeys(ssl);
ashleymills 0:e979170e02e7 6230 else
ashleymills 0:e979170e02e7 6231 ret = DeriveKeys(ssl);
ashleymills 0:e979170e02e7 6232 #else
ashleymills 0:e979170e02e7 6233 ret = DeriveTlsKeys(ssl);
ashleymills 0:e979170e02e7 6234 #endif
ashleymills 0:e979170e02e7 6235 ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
ashleymills 0:e979170e02e7 6236 return ret;
ashleymills 0:e979170e02e7 6237 }
ashleymills 0:e979170e02e7 6238 else {
ashleymills 0:e979170e02e7 6239 CYASSL_MSG("Unsupported cipher suite, DoServerHello");
ashleymills 0:e979170e02e7 6240 return UNSUPPORTED_SUITE;
ashleymills 0:e979170e02e7 6241 }
ashleymills 0:e979170e02e7 6242 }
ashleymills 0:e979170e02e7 6243 else {
ashleymills 0:e979170e02e7 6244 CYASSL_MSG("Server denied resumption attempt");
ashleymills 0:e979170e02e7 6245 ssl->options.resuming = 0; /* server denied resumption try */
ashleymills 0:e979170e02e7 6246 }
ashleymills 0:e979170e02e7 6247 }
ashleymills 0:e979170e02e7 6248 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 6249 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 6250 DtlsPoolReset(ssl);
ashleymills 0:e979170e02e7 6251 }
ashleymills 0:e979170e02e7 6252 #endif
ashleymills 0:e979170e02e7 6253 return SetCipherSpecs(ssl);
ashleymills 0:e979170e02e7 6254 }
ashleymills 0:e979170e02e7 6255
ashleymills 0:e979170e02e7 6256
ashleymills 0:e979170e02e7 6257 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 6258 /* just read in and ignore for now TODO: */
ashleymills 0:e979170e02e7 6259 static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32*
ashleymills 0:e979170e02e7 6260 inOutIdx)
ashleymills 0:e979170e02e7 6261 {
ashleymills 0:e979170e02e7 6262 word16 len;
ashleymills 0:e979170e02e7 6263
ashleymills 0:e979170e02e7 6264 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 6265 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 6266 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 6267 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 6268 AddLateName("CertificateRequest", &ssl->timeoutInfo);
ashleymills 0:e979170e02e7 6269 #endif
ashleymills 0:e979170e02e7 6270 len = input[(*inOutIdx)++];
ashleymills 0:e979170e02e7 6271
ashleymills 0:e979170e02e7 6272 /* types, read in here */
ashleymills 0:e979170e02e7 6273 *inOutIdx += len;
ashleymills 0:e979170e02e7 6274 ato16(&input[*inOutIdx], &len);
ashleymills 0:e979170e02e7 6275 *inOutIdx += LENGTH_SZ;
ashleymills 0:e979170e02e7 6276
ashleymills 0:e979170e02e7 6277 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:e979170e02e7 6278 /* hash sig format */
ashleymills 0:e979170e02e7 6279 *inOutIdx += len;
ashleymills 0:e979170e02e7 6280 ato16(&input[*inOutIdx], &len);
ashleymills 0:e979170e02e7 6281 *inOutIdx += LENGTH_SZ;
ashleymills 0:e979170e02e7 6282 }
ashleymills 0:e979170e02e7 6283
ashleymills 0:e979170e02e7 6284 /* authorities */
ashleymills 0:e979170e02e7 6285 while (len) {
ashleymills 0:e979170e02e7 6286 word16 dnSz;
ashleymills 0:e979170e02e7 6287
ashleymills 0:e979170e02e7 6288 ato16(&input[*inOutIdx], &dnSz);
ashleymills 0:e979170e02e7 6289 *inOutIdx += (REQUEST_HEADER + dnSz);
ashleymills 0:e979170e02e7 6290 len -= dnSz + REQUEST_HEADER;
ashleymills 0:e979170e02e7 6291 }
ashleymills 0:e979170e02e7 6292
ashleymills 0:e979170e02e7 6293 /* don't send client cert or cert verify if user hasn't provided
ashleymills 0:e979170e02e7 6294 cert and private key */
ashleymills 0:e979170e02e7 6295 if (ssl->buffers.certificate.buffer && ssl->buffers.key.buffer)
ashleymills 0:e979170e02e7 6296 ssl->options.sendVerify = SEND_CERT;
ashleymills 0:e979170e02e7 6297 else if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:e979170e02e7 6298 ssl->options.sendVerify = SEND_BLANK_CERT;
ashleymills 0:e979170e02e7 6299
ashleymills 0:e979170e02e7 6300 return 0;
ashleymills 0:e979170e02e7 6301 }
ashleymills 0:e979170e02e7 6302 #endif /* !NO_CERTS */
ashleymills 0:e979170e02e7 6303
ashleymills 0:e979170e02e7 6304
ashleymills 0:e979170e02e7 6305 static int DoServerKeyExchange(CYASSL* ssl, const byte* input,
ashleymills 0:e979170e02e7 6306 word32* inOutIdx)
ashleymills 0:e979170e02e7 6307 {
ashleymills 0:e979170e02e7 6308 #if defined(OPENSSL_EXTRA) || defined(HAVE_ECC)
ashleymills 0:e979170e02e7 6309 word16 length = 0;
ashleymills 0:e979170e02e7 6310 word16 sigLen = 0;
ashleymills 0:e979170e02e7 6311 word16 verifySz = (word16)*inOutIdx; /* keep start idx */
ashleymills 0:e979170e02e7 6312 byte* signature = 0;
ashleymills 0:e979170e02e7 6313 #endif
ashleymills 0:e979170e02e7 6314
ashleymills 0:e979170e02e7 6315 (void)ssl;
ashleymills 0:e979170e02e7 6316 (void)input;
ashleymills 0:e979170e02e7 6317 (void)inOutIdx;
ashleymills 0:e979170e02e7 6318
ashleymills 0:e979170e02e7 6319 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 6320 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 6321 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 6322 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 6323 AddLateName("ServerKeyExchange", &ssl->timeoutInfo);
ashleymills 0:e979170e02e7 6324 #endif
ashleymills 0:e979170e02e7 6325
ashleymills 0:e979170e02e7 6326 #ifndef NO_PSK
ashleymills 0:e979170e02e7 6327 if (ssl->specs.kea == psk_kea) {
ashleymills 0:e979170e02e7 6328 word16 pskLen = 0;
ashleymills 0:e979170e02e7 6329 ato16(&input[*inOutIdx], &pskLen);
ashleymills 0:e979170e02e7 6330 *inOutIdx += LENGTH_SZ;
ashleymills 0:e979170e02e7 6331 XMEMCPY(ssl->arrays->server_hint, &input[*inOutIdx],
ashleymills 0:e979170e02e7 6332 min(pskLen, MAX_PSK_ID_LEN));
ashleymills 0:e979170e02e7 6333 if (pskLen < MAX_PSK_ID_LEN)
ashleymills 0:e979170e02e7 6334 ssl->arrays->server_hint[pskLen] = 0;
ashleymills 0:e979170e02e7 6335 else
ashleymills 0:e979170e02e7 6336 ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = 0;
ashleymills 0:e979170e02e7 6337 *inOutIdx += pskLen;
ashleymills 0:e979170e02e7 6338
ashleymills 0:e979170e02e7 6339 return 0;
ashleymills 0:e979170e02e7 6340 }
ashleymills 0:e979170e02e7 6341 #endif
ashleymills 0:e979170e02e7 6342 #ifdef OPENSSL_EXTRA
ashleymills 0:e979170e02e7 6343 if (ssl->specs.kea == diffie_hellman_kea)
ashleymills 0:e979170e02e7 6344 {
ashleymills 0:e979170e02e7 6345 /* p */
ashleymills 0:e979170e02e7 6346 ato16(&input[*inOutIdx], &length);
ashleymills 0:e979170e02e7 6347 *inOutIdx += LENGTH_SZ;
ashleymills 0:e979170e02e7 6348
ashleymills 0:e979170e02e7 6349 ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
ashleymills 0:e979170e02e7 6350 DYNAMIC_TYPE_DH);
ashleymills 0:e979170e02e7 6351 if (ssl->buffers.serverDH_P.buffer)
ashleymills 0:e979170e02e7 6352 ssl->buffers.serverDH_P.length = length;
ashleymills 0:e979170e02e7 6353 else
ashleymills 0:e979170e02e7 6354 return MEMORY_ERROR;
ashleymills 0:e979170e02e7 6355 XMEMCPY(ssl->buffers.serverDH_P.buffer, &input[*inOutIdx], length);
ashleymills 0:e979170e02e7 6356 *inOutIdx += length;
ashleymills 0:e979170e02e7 6357
ashleymills 0:e979170e02e7 6358 /* g */
ashleymills 0:e979170e02e7 6359 ato16(&input[*inOutIdx], &length);
ashleymills 0:e979170e02e7 6360 *inOutIdx += LENGTH_SZ;
ashleymills 0:e979170e02e7 6361
ashleymills 0:e979170e02e7 6362 ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
ashleymills 0:e979170e02e7 6363 DYNAMIC_TYPE_DH);
ashleymills 0:e979170e02e7 6364 if (ssl->buffers.serverDH_G.buffer)
ashleymills 0:e979170e02e7 6365 ssl->buffers.serverDH_G.length = length;
ashleymills 0:e979170e02e7 6366 else
ashleymills 0:e979170e02e7 6367 return MEMORY_ERROR;
ashleymills 0:e979170e02e7 6368 XMEMCPY(ssl->buffers.serverDH_G.buffer, &input[*inOutIdx], length);
ashleymills 0:e979170e02e7 6369 *inOutIdx += length;
ashleymills 0:e979170e02e7 6370
ashleymills 0:e979170e02e7 6371 /* pub */
ashleymills 0:e979170e02e7 6372 ato16(&input[*inOutIdx], &length);
ashleymills 0:e979170e02e7 6373 *inOutIdx += LENGTH_SZ;
ashleymills 0:e979170e02e7 6374
ashleymills 0:e979170e02e7 6375 ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap,
ashleymills 0:e979170e02e7 6376 DYNAMIC_TYPE_DH);
ashleymills 0:e979170e02e7 6377 if (ssl->buffers.serverDH_Pub.buffer)
ashleymills 0:e979170e02e7 6378 ssl->buffers.serverDH_Pub.length = length;
ashleymills 0:e979170e02e7 6379 else
ashleymills 0:e979170e02e7 6380 return MEMORY_ERROR;
ashleymills 0:e979170e02e7 6381 XMEMCPY(ssl->buffers.serverDH_Pub.buffer, &input[*inOutIdx], length);
ashleymills 0:e979170e02e7 6382 *inOutIdx += length;
ashleymills 0:e979170e02e7 6383 } /* dh_kea */
ashleymills 0:e979170e02e7 6384 #endif /* OPENSSL_EXTRA */
ashleymills 0:e979170e02e7 6385
ashleymills 0:e979170e02e7 6386 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 6387 if (ssl->specs.kea == ecc_diffie_hellman_kea)
ashleymills 0:e979170e02e7 6388 {
ashleymills 0:e979170e02e7 6389 byte b = input[*inOutIdx];
ashleymills 0:e979170e02e7 6390 *inOutIdx += 1;
ashleymills 0:e979170e02e7 6391
ashleymills 0:e979170e02e7 6392 if (b != named_curve)
ashleymills 0:e979170e02e7 6393 return ECC_CURVETYPE_ERROR;
ashleymills 0:e979170e02e7 6394
ashleymills 0:e979170e02e7 6395 *inOutIdx += 1; /* curve type, eat leading 0 */
ashleymills 0:e979170e02e7 6396 b = input[*inOutIdx];
ashleymills 0:e979170e02e7 6397 *inOutIdx += 1;
ashleymills 0:e979170e02e7 6398
ashleymills 0:e979170e02e7 6399 if (b != secp256r1 && b != secp384r1 && b != secp521r1 && b !=
ashleymills 0:e979170e02e7 6400 secp160r1 && b != secp192r1 && b != secp224r1)
ashleymills 0:e979170e02e7 6401 return ECC_CURVE_ERROR;
ashleymills 0:e979170e02e7 6402
ashleymills 0:e979170e02e7 6403 length = input[*inOutIdx];
ashleymills 0:e979170e02e7 6404 *inOutIdx += 1;
ashleymills 0:e979170e02e7 6405
ashleymills 0:e979170e02e7 6406 if (ecc_import_x963(&input[*inOutIdx], length, ssl->peerEccKey) != 0)
ashleymills 0:e979170e02e7 6407 return ECC_PEERKEY_ERROR;
ashleymills 0:e979170e02e7 6408
ashleymills 0:e979170e02e7 6409 *inOutIdx += length;
ashleymills 0:e979170e02e7 6410 ssl->peerEccKeyPresent = 1;
ashleymills 0:e979170e02e7 6411 }
ashleymills 0:e979170e02e7 6412 #endif /* HAVE_ECC */
ashleymills 0:e979170e02e7 6413
ashleymills 0:e979170e02e7 6414 #if defined(OPENSSL_EXTRA) || defined(HAVE_ECC)
ashleymills 0:e979170e02e7 6415 {
ashleymills 0:e979170e02e7 6416 Md5 md5;
ashleymills 0:e979170e02e7 6417 Sha sha;
ashleymills 0:e979170e02e7 6418 byte hash[FINISHED_SZ];
ashleymills 0:e979170e02e7 6419 byte messageVerify[MAX_DH_SZ];
ashleymills 0:e979170e02e7 6420
ashleymills 0:e979170e02e7 6421 /* adjust from start idx */
ashleymills 0:e979170e02e7 6422 verifySz = (word16)(*inOutIdx - verifySz);
ashleymills 0:e979170e02e7 6423
ashleymills 0:e979170e02e7 6424 /* save message for hash verify */
ashleymills 0:e979170e02e7 6425 if (verifySz > sizeof(messageVerify))
ashleymills 0:e979170e02e7 6426 return BUFFER_ERROR;
ashleymills 0:e979170e02e7 6427 XMEMCPY(messageVerify, &input[*inOutIdx - verifySz], verifySz);
ashleymills 0:e979170e02e7 6428
ashleymills 0:e979170e02e7 6429 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:e979170e02e7 6430 /* just advance for now TODO: validate hash algo params */
ashleymills 0:e979170e02e7 6431 *inOutIdx += LENGTH_SZ;
ashleymills 0:e979170e02e7 6432 }
ashleymills 0:e979170e02e7 6433
ashleymills 0:e979170e02e7 6434 /* signature */
ashleymills 0:e979170e02e7 6435 ato16(&input[*inOutIdx], &length);
ashleymills 0:e979170e02e7 6436 *inOutIdx += LENGTH_SZ;
ashleymills 0:e979170e02e7 6437
ashleymills 0:e979170e02e7 6438 signature = (byte*)&input[*inOutIdx];
ashleymills 0:e979170e02e7 6439 *inOutIdx += length;
ashleymills 0:e979170e02e7 6440 sigLen = length;
ashleymills 0:e979170e02e7 6441
ashleymills 0:e979170e02e7 6442 /* verify signature */
ashleymills 0:e979170e02e7 6443
ashleymills 0:e979170e02e7 6444 /* md5 */
ashleymills 0:e979170e02e7 6445 InitMd5(&md5);
ashleymills 0:e979170e02e7 6446 Md5Update(&md5, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:e979170e02e7 6447 Md5Update(&md5, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:e979170e02e7 6448 Md5Update(&md5, messageVerify, verifySz);
ashleymills 0:e979170e02e7 6449 Md5Final(&md5, hash);
ashleymills 0:e979170e02e7 6450
ashleymills 0:e979170e02e7 6451 /* sha */
ashleymills 0:e979170e02e7 6452 InitSha(&sha);
ashleymills 0:e979170e02e7 6453 ShaUpdate(&sha, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:e979170e02e7 6454 ShaUpdate(&sha, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:e979170e02e7 6455 ShaUpdate(&sha, messageVerify, verifySz);
ashleymills 0:e979170e02e7 6456 ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
ashleymills 0:e979170e02e7 6457
ashleymills 0:e979170e02e7 6458 /* rsa */
ashleymills 0:e979170e02e7 6459 if (ssl->specs.sig_algo == rsa_sa_algo)
ashleymills 0:e979170e02e7 6460 {
ashleymills 0:e979170e02e7 6461 int ret;
ashleymills 0:e979170e02e7 6462 byte* out;
ashleymills 0:e979170e02e7 6463
ashleymills 0:e979170e02e7 6464 if (!ssl->peerRsaKeyPresent)
ashleymills 0:e979170e02e7 6465 return NO_PEER_KEY;
ashleymills 0:e979170e02e7 6466
ashleymills 0:e979170e02e7 6467 ret = RsaSSL_VerifyInline(signature, sigLen,&out, ssl->peerRsaKey);
ashleymills 0:e979170e02e7 6468
ashleymills 0:e979170e02e7 6469 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:e979170e02e7 6470 byte encodedSig[MAX_ENCODED_SIG_SZ];
ashleymills 0:e979170e02e7 6471 word32 encSigSz;
ashleymills 0:e979170e02e7 6472 byte* digest;
ashleymills 0:e979170e02e7 6473 int typeH;
ashleymills 0:e979170e02e7 6474 int digestSz;
ashleymills 0:e979170e02e7 6475
ashleymills 0:e979170e02e7 6476 /* sha1 for now */
ashleymills 0:e979170e02e7 6477 digest = &hash[MD5_DIGEST_SIZE];
ashleymills 0:e979170e02e7 6478 typeH = SHAh;
ashleymills 0:e979170e02e7 6479 digestSz = SHA_DIGEST_SIZE;
ashleymills 0:e979170e02e7 6480
ashleymills 0:e979170e02e7 6481 encSigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
ashleymills 0:e979170e02e7 6482
ashleymills 0:e979170e02e7 6483 if (encSigSz != (word32)ret || XMEMCMP(out, encodedSig,
ashleymills 0:e979170e02e7 6484 min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0)
ashleymills 0:e979170e02e7 6485 return VERIFY_SIGN_ERROR;
ashleymills 0:e979170e02e7 6486 }
ashleymills 0:e979170e02e7 6487 else {
ashleymills 0:e979170e02e7 6488 if (ret != sizeof(hash) || XMEMCMP(out, hash,sizeof(hash)) != 0)
ashleymills 0:e979170e02e7 6489 return VERIFY_SIGN_ERROR;
ashleymills 0:e979170e02e7 6490 }
ashleymills 0:e979170e02e7 6491 }
ashleymills 0:e979170e02e7 6492 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 6493 /* ecdsa */
ashleymills 0:e979170e02e7 6494 else if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
ashleymills 0:e979170e02e7 6495 int verify = 0, ret;
ashleymills 0:e979170e02e7 6496 if (!ssl->peerEccDsaKeyPresent)
ashleymills 0:e979170e02e7 6497 return NO_PEER_KEY;
ashleymills 0:e979170e02e7 6498
ashleymills 0:e979170e02e7 6499 ret = ecc_verify_hash(signature, sigLen, &hash[MD5_DIGEST_SIZE],
ashleymills 0:e979170e02e7 6500 SHA_DIGEST_SIZE, &verify, ssl->peerEccDsaKey);
ashleymills 0:e979170e02e7 6501 if (ret != 0 || verify == 0)
ashleymills 0:e979170e02e7 6502 return VERIFY_SIGN_ERROR;
ashleymills 0:e979170e02e7 6503 }
ashleymills 0:e979170e02e7 6504 #endif /* HAVE_ECC */
ashleymills 0:e979170e02e7 6505 else
ashleymills 0:e979170e02e7 6506 return ALGO_ID_E;
ashleymills 0:e979170e02e7 6507
ashleymills 0:e979170e02e7 6508 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
ashleymills 0:e979170e02e7 6509
ashleymills 0:e979170e02e7 6510 return 0;
ashleymills 0:e979170e02e7 6511
ashleymills 0:e979170e02e7 6512 }
ashleymills 0:e979170e02e7 6513 #else /* HAVE_OPENSSL or HAVE_ECC */
ashleymills 0:e979170e02e7 6514 return NOT_COMPILED_IN; /* not supported by build */
ashleymills 0:e979170e02e7 6515 #endif /* HAVE_OPENSSL or HAVE_ECC */
ashleymills 0:e979170e02e7 6516 }
ashleymills 0:e979170e02e7 6517
ashleymills 0:e979170e02e7 6518
ashleymills 0:e979170e02e7 6519 int SendClientKeyExchange(CYASSL* ssl)
ashleymills 0:e979170e02e7 6520 {
ashleymills 0:e979170e02e7 6521 byte encSecret[MAX_ENCRYPT_SZ];
ashleymills 0:e979170e02e7 6522 word32 encSz = 0;
ashleymills 0:e979170e02e7 6523 word32 idx = 0;
ashleymills 0:e979170e02e7 6524 int ret = 0;
ashleymills 0:e979170e02e7 6525
ashleymills 0:e979170e02e7 6526 switch (ssl->specs.kea) {
ashleymills 0:e979170e02e7 6527 #ifndef NO_RSA
ashleymills 0:e979170e02e7 6528 case rsa_kea:
ashleymills 0:e979170e02e7 6529 RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret,
ashleymills 0:e979170e02e7 6530 SECRET_LEN);
ashleymills 0:e979170e02e7 6531 ssl->arrays->preMasterSecret[0] = ssl->chVersion.major;
ashleymills 0:e979170e02e7 6532 ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor;
ashleymills 0:e979170e02e7 6533 ssl->arrays->preMasterSz = SECRET_LEN;
ashleymills 0:e979170e02e7 6534
ashleymills 0:e979170e02e7 6535 if (ssl->peerRsaKeyPresent == 0)
ashleymills 0:e979170e02e7 6536 return NO_PEER_KEY;
ashleymills 0:e979170e02e7 6537
ashleymills 0:e979170e02e7 6538 ret = RsaPublicEncrypt(ssl->arrays->preMasterSecret, SECRET_LEN,
ashleymills 0:e979170e02e7 6539 encSecret, sizeof(encSecret), ssl->peerRsaKey,
ashleymills 0:e979170e02e7 6540 ssl->rng);
ashleymills 0:e979170e02e7 6541 if (ret > 0) {
ashleymills 0:e979170e02e7 6542 encSz = ret;
ashleymills 0:e979170e02e7 6543 ret = 0; /* set success to 0 */
ashleymills 0:e979170e02e7 6544 }
ashleymills 0:e979170e02e7 6545 break;
ashleymills 0:e979170e02e7 6546 #endif
ashleymills 0:e979170e02e7 6547 #ifdef OPENSSL_EXTRA
ashleymills 0:e979170e02e7 6548 case diffie_hellman_kea:
ashleymills 0:e979170e02e7 6549 {
ashleymills 0:e979170e02e7 6550 buffer serverP = ssl->buffers.serverDH_P;
ashleymills 0:e979170e02e7 6551 buffer serverG = ssl->buffers.serverDH_G;
ashleymills 0:e979170e02e7 6552 buffer serverPub = ssl->buffers.serverDH_Pub;
ashleymills 0:e979170e02e7 6553 byte priv[ENCRYPT_LEN];
ashleymills 0:e979170e02e7 6554 word32 privSz = 0;
ashleymills 0:e979170e02e7 6555 DhKey key;
ashleymills 0:e979170e02e7 6556
ashleymills 0:e979170e02e7 6557 if (serverP.buffer == 0 || serverG.buffer == 0 ||
ashleymills 0:e979170e02e7 6558 serverPub.buffer == 0)
ashleymills 0:e979170e02e7 6559 return NO_PEER_KEY;
ashleymills 0:e979170e02e7 6560
ashleymills 0:e979170e02e7 6561 InitDhKey(&key);
ashleymills 0:e979170e02e7 6562 ret = DhSetKey(&key, serverP.buffer, serverP.length,
ashleymills 0:e979170e02e7 6563 serverG.buffer, serverG.length);
ashleymills 0:e979170e02e7 6564 if (ret == 0)
ashleymills 0:e979170e02e7 6565 /* for DH, encSecret is Yc, agree is pre-master */
ashleymills 0:e979170e02e7 6566 ret = DhGenerateKeyPair(&key, ssl->rng, priv, &privSz,
ashleymills 0:e979170e02e7 6567 encSecret, &encSz);
ashleymills 0:e979170e02e7 6568 if (ret == 0)
ashleymills 0:e979170e02e7 6569 ret = DhAgree(&key, ssl->arrays->preMasterSecret,
ashleymills 0:e979170e02e7 6570 &ssl->arrays->preMasterSz, priv, privSz,
ashleymills 0:e979170e02e7 6571 serverPub.buffer, serverPub.length);
ashleymills 0:e979170e02e7 6572 FreeDhKey(&key);
ashleymills 0:e979170e02e7 6573 }
ashleymills 0:e979170e02e7 6574 break;
ashleymills 0:e979170e02e7 6575 #endif /* OPENSSL_EXTRA */
ashleymills 0:e979170e02e7 6576 #ifndef NO_PSK
ashleymills 0:e979170e02e7 6577 case psk_kea:
ashleymills 0:e979170e02e7 6578 {
ashleymills 0:e979170e02e7 6579 byte* pms = ssl->arrays->preMasterSecret;
ashleymills 0:e979170e02e7 6580
ashleymills 0:e979170e02e7 6581 ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
ashleymills 0:e979170e02e7 6582 ssl->arrays->server_hint, ssl->arrays->client_identity,
ashleymills 0:e979170e02e7 6583 MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
ashleymills 0:e979170e02e7 6584 if (ssl->arrays->psk_keySz == 0 ||
ashleymills 0:e979170e02e7 6585 ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
ashleymills 0:e979170e02e7 6586 return PSK_KEY_ERROR;
ashleymills 0:e979170e02e7 6587 encSz = (word32)XSTRLEN(ssl->arrays->client_identity);
ashleymills 0:e979170e02e7 6588 if (encSz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR;
ashleymills 0:e979170e02e7 6589 XMEMCPY(encSecret, ssl->arrays->client_identity, encSz);
ashleymills 0:e979170e02e7 6590
ashleymills 0:e979170e02e7 6591 /* make psk pre master secret */
ashleymills 0:e979170e02e7 6592 /* length of key + length 0s + length of key + key */
ashleymills 0:e979170e02e7 6593 c16toa((word16)ssl->arrays->psk_keySz, pms);
ashleymills 0:e979170e02e7 6594 pms += 2;
ashleymills 0:e979170e02e7 6595 XMEMSET(pms, 0, ssl->arrays->psk_keySz);
ashleymills 0:e979170e02e7 6596 pms += ssl->arrays->psk_keySz;
ashleymills 0:e979170e02e7 6597 c16toa((word16)ssl->arrays->psk_keySz, pms);
ashleymills 0:e979170e02e7 6598 pms += 2;
ashleymills 0:e979170e02e7 6599 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
ashleymills 0:e979170e02e7 6600 ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
ashleymills 0:e979170e02e7 6601 }
ashleymills 0:e979170e02e7 6602 break;
ashleymills 0:e979170e02e7 6603 #endif /* NO_PSK */
ashleymills 0:e979170e02e7 6604 #ifdef HAVE_NTRU
ashleymills 0:e979170e02e7 6605 case ntru_kea:
ashleymills 0:e979170e02e7 6606 {
ashleymills 0:e979170e02e7 6607 word32 rc;
ashleymills 0:e979170e02e7 6608 word16 cipherLen = sizeof(encSecret);
ashleymills 0:e979170e02e7 6609 DRBG_HANDLE drbg;
ashleymills 0:e979170e02e7 6610 static uint8_t const cyasslStr[] = {
ashleymills 0:e979170e02e7 6611 'C', 'y', 'a', 'S', 'S', 'L', ' ', 'N', 'T', 'R', 'U'
ashleymills 0:e979170e02e7 6612 };
ashleymills 0:e979170e02e7 6613
ashleymills 0:e979170e02e7 6614 RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret,
ashleymills 0:e979170e02e7 6615 SECRET_LEN);
ashleymills 0:e979170e02e7 6616 ssl->arrays->preMasterSz = SECRET_LEN;
ashleymills 0:e979170e02e7 6617
ashleymills 0:e979170e02e7 6618 if (ssl->peerNtruKeyPresent == 0)
ashleymills 0:e979170e02e7 6619 return NO_PEER_KEY;
ashleymills 0:e979170e02e7 6620
ashleymills 0:e979170e02e7 6621 rc = crypto_drbg_instantiate(MAX_NTRU_BITS, cyasslStr,
ashleymills 0:e979170e02e7 6622 sizeof(cyasslStr), GetEntropy,
ashleymills 0:e979170e02e7 6623 &drbg);
ashleymills 0:e979170e02e7 6624 if (rc != DRBG_OK)
ashleymills 0:e979170e02e7 6625 return NTRU_DRBG_ERROR;
ashleymills 0:e979170e02e7 6626
ashleymills 0:e979170e02e7 6627 rc = crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen,
ashleymills 0:e979170e02e7 6628 ssl->peerNtruKey,
ashleymills 0:e979170e02e7 6629 ssl->arrays->preMasterSz,
ashleymills 0:e979170e02e7 6630 ssl->arrays->preMasterSecret,
ashleymills 0:e979170e02e7 6631 &cipherLen, encSecret);
ashleymills 0:e979170e02e7 6632 crypto_drbg_uninstantiate(drbg);
ashleymills 0:e979170e02e7 6633 if (rc != NTRU_OK)
ashleymills 0:e979170e02e7 6634 return NTRU_ENCRYPT_ERROR;
ashleymills 0:e979170e02e7 6635
ashleymills 0:e979170e02e7 6636 encSz = cipherLen;
ashleymills 0:e979170e02e7 6637 ret = 0;
ashleymills 0:e979170e02e7 6638 }
ashleymills 0:e979170e02e7 6639 break;
ashleymills 0:e979170e02e7 6640 #endif /* HAVE_NTRU */
ashleymills 0:e979170e02e7 6641 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 6642 case ecc_diffie_hellman_kea:
ashleymills 0:e979170e02e7 6643 {
ashleymills 0:e979170e02e7 6644 ecc_key myKey;
ashleymills 0:e979170e02e7 6645 ecc_key* peerKey = &myKey;
ashleymills 0:e979170e02e7 6646 word32 size = sizeof(encSecret);
ashleymills 0:e979170e02e7 6647
ashleymills 0:e979170e02e7 6648 if (ssl->specs.static_ecdh) {
ashleymills 0:e979170e02e7 6649 /* TODO: EccDsa is really fixed Ecc change naming */
ashleymills 0:e979170e02e7 6650 if (!ssl->peerEccDsaKeyPresent || !ssl->peerEccDsaKey->dp)
ashleymills 0:e979170e02e7 6651 return NO_PEER_KEY;
ashleymills 0:e979170e02e7 6652 peerKey = ssl->peerEccDsaKey;
ashleymills 0:e979170e02e7 6653 }
ashleymills 0:e979170e02e7 6654 else {
ashleymills 0:e979170e02e7 6655 if (!ssl->peerEccKeyPresent || !ssl->peerEccKey->dp)
ashleymills 0:e979170e02e7 6656 return NO_PEER_KEY;
ashleymills 0:e979170e02e7 6657 peerKey = ssl->peerEccKey;
ashleymills 0:e979170e02e7 6658 }
ashleymills 0:e979170e02e7 6659
ashleymills 0:e979170e02e7 6660 ecc_init(&myKey);
ashleymills 0:e979170e02e7 6661 ret = ecc_make_key(ssl->rng, peerKey->dp->size, &myKey);
ashleymills 0:e979170e02e7 6662 if (ret != 0)
ashleymills 0:e979170e02e7 6663 return ECC_MAKEKEY_ERROR;
ashleymills 0:e979170e02e7 6664
ashleymills 0:e979170e02e7 6665 /* precede export with 1 byte length */
ashleymills 0:e979170e02e7 6666 ret = ecc_export_x963(&myKey, encSecret + 1, &size);
ashleymills 0:e979170e02e7 6667 encSecret[0] = (byte)size;
ashleymills 0:e979170e02e7 6668 encSz = size + 1;
ashleymills 0:e979170e02e7 6669
ashleymills 0:e979170e02e7 6670 if (ret != 0)
ashleymills 0:e979170e02e7 6671 ret = ECC_EXPORT_ERROR;
ashleymills 0:e979170e02e7 6672 else {
ashleymills 0:e979170e02e7 6673 size = sizeof(ssl->arrays->preMasterSecret);
ashleymills 0:e979170e02e7 6674 ret = ecc_shared_secret(&myKey, peerKey,
ashleymills 0:e979170e02e7 6675 ssl->arrays->preMasterSecret, &size);
ashleymills 0:e979170e02e7 6676 if (ret != 0)
ashleymills 0:e979170e02e7 6677 ret = ECC_SHARED_ERROR;
ashleymills 0:e979170e02e7 6678 }
ashleymills 0:e979170e02e7 6679
ashleymills 0:e979170e02e7 6680 ssl->arrays->preMasterSz = size;
ashleymills 0:e979170e02e7 6681 ecc_free(&myKey);
ashleymills 0:e979170e02e7 6682 }
ashleymills 0:e979170e02e7 6683 break;
ashleymills 0:e979170e02e7 6684 #endif /* HAVE_ECC */
ashleymills 0:e979170e02e7 6685 default:
ashleymills 0:e979170e02e7 6686 return ALGO_ID_E; /* unsupported kea */
ashleymills 0:e979170e02e7 6687 }
ashleymills 0:e979170e02e7 6688
ashleymills 0:e979170e02e7 6689 if (ret == 0) {
ashleymills 0:e979170e02e7 6690 byte *output;
ashleymills 0:e979170e02e7 6691 int sendSz;
ashleymills 0:e979170e02e7 6692 word32 tlsSz = 0;
ashleymills 0:e979170e02e7 6693
ashleymills 0:e979170e02e7 6694 if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea)
ashleymills 0:e979170e02e7 6695 tlsSz = 2;
ashleymills 0:e979170e02e7 6696
ashleymills 0:e979170e02e7 6697 if (ssl->specs.kea == ecc_diffie_hellman_kea) /* always off */
ashleymills 0:e979170e02e7 6698 tlsSz = 0;
ashleymills 0:e979170e02e7 6699
ashleymills 0:e979170e02e7 6700 sendSz = encSz + tlsSz + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 6701 idx = HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 6702
ashleymills 0:e979170e02e7 6703 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 6704 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 6705 sendSz += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
ashleymills 0:e979170e02e7 6706 idx += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
ashleymills 0:e979170e02e7 6707 }
ashleymills 0:e979170e02e7 6708 #endif
ashleymills 0:e979170e02e7 6709
ashleymills 0:e979170e02e7 6710 /* check for avalaible size */
ashleymills 0:e979170e02e7 6711 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
ashleymills 0:e979170e02e7 6712 return ret;
ashleymills 0:e979170e02e7 6713
ashleymills 0:e979170e02e7 6714 /* get ouput buffer */
ashleymills 0:e979170e02e7 6715 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 6716 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 6717
ashleymills 0:e979170e02e7 6718 AddHeaders(output, encSz + tlsSz, client_key_exchange, ssl);
ashleymills 0:e979170e02e7 6719
ashleymills 0:e979170e02e7 6720 if (tlsSz) {
ashleymills 0:e979170e02e7 6721 c16toa((word16)encSz, &output[idx]);
ashleymills 0:e979170e02e7 6722 idx += 2;
ashleymills 0:e979170e02e7 6723 }
ashleymills 0:e979170e02e7 6724 XMEMCPY(output + idx, encSecret, encSz);
ashleymills 0:e979170e02e7 6725 /* if add more to output, adjust idx
ashleymills 0:e979170e02e7 6726 idx += encSz; */
ashleymills 0:e979170e02e7 6727 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 6728 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 6729 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:e979170e02e7 6730 return ret;
ashleymills 0:e979170e02e7 6731 }
ashleymills 0:e979170e02e7 6732 #endif
ashleymills 0:e979170e02e7 6733 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:e979170e02e7 6734
ashleymills 0:e979170e02e7 6735 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 6736 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 6737 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 6738 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 6739 AddPacketInfo("ClientKeyExchange", &ssl->timeoutInfo,
ashleymills 0:e979170e02e7 6740 output, sendSz, ssl->heap);
ashleymills 0:e979170e02e7 6741 #endif
ashleymills 0:e979170e02e7 6742
ashleymills 0:e979170e02e7 6743 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:e979170e02e7 6744
ashleymills 0:e979170e02e7 6745 if (ssl->options.groupMessages)
ashleymills 0:e979170e02e7 6746 ret = 0;
ashleymills 0:e979170e02e7 6747 else
ashleymills 0:e979170e02e7 6748 ret = SendBuffered(ssl);
ashleymills 0:e979170e02e7 6749 }
ashleymills 0:e979170e02e7 6750
ashleymills 0:e979170e02e7 6751 if (ret == 0 || ret == WANT_WRITE) {
ashleymills 0:e979170e02e7 6752 int tmpRet = MakeMasterSecret(ssl);
ashleymills 0:e979170e02e7 6753 if (tmpRet != 0)
ashleymills 0:e979170e02e7 6754 ret = tmpRet; /* save WANT_WRITE unless more serious */
ashleymills 0:e979170e02e7 6755 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
ashleymills 0:e979170e02e7 6756 }
ashleymills 0:e979170e02e7 6757
ashleymills 0:e979170e02e7 6758 return ret;
ashleymills 0:e979170e02e7 6759 }
ashleymills 0:e979170e02e7 6760
ashleymills 0:e979170e02e7 6761 #ifndef NO_RSA
ashleymills 0:e979170e02e7 6762 int SendCertificateVerify(CYASSL* ssl)
ashleymills 0:e979170e02e7 6763 {
ashleymills 0:e979170e02e7 6764 byte *output;
ashleymills 0:e979170e02e7 6765 int sendSz = 0, length, ret;
ashleymills 0:e979170e02e7 6766 word32 idx = 0;
ashleymills 0:e979170e02e7 6767 word32 sigOutSz = 0;
ashleymills 0:e979170e02e7 6768 RsaKey key;
ashleymills 0:e979170e02e7 6769 int usingEcc = 0;
ashleymills 0:e979170e02e7 6770 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 6771 ecc_key eccKey;
ashleymills 0:e979170e02e7 6772 #endif
ashleymills 0:e979170e02e7 6773
ashleymills 0:e979170e02e7 6774 if (ssl->options.sendVerify == SEND_BLANK_CERT)
ashleymills 0:e979170e02e7 6775 return 0; /* sent blank cert, can't verify */
ashleymills 0:e979170e02e7 6776
ashleymills 0:e979170e02e7 6777 /* check for avalaible size */
ashleymills 0:e979170e02e7 6778 if ((ret = CheckAvalaibleSize(ssl, MAX_CERT_VERIFY_SZ)) != 0)
ashleymills 0:e979170e02e7 6779 return ret;
ashleymills 0:e979170e02e7 6780
ashleymills 0:e979170e02e7 6781 /* get ouput buffer */
ashleymills 0:e979170e02e7 6782 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 6783 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 6784
ashleymills 0:e979170e02e7 6785 BuildCertHashes(ssl, &ssl->certHashes);
ashleymills 0:e979170e02e7 6786
ashleymills 0:e979170e02e7 6787 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 6788 ecc_init(&eccKey);
ashleymills 0:e979170e02e7 6789 #endif
ashleymills 0:e979170e02e7 6790 InitRsaKey(&key, ssl->heap);
ashleymills 0:e979170e02e7 6791 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
ashleymills 0:e979170e02e7 6792 ssl->buffers.key.length);
ashleymills 0:e979170e02e7 6793 if (ret == 0)
ashleymills 0:e979170e02e7 6794 sigOutSz = RsaEncryptSize(&key);
ashleymills 0:e979170e02e7 6795 else {
ashleymills 0:e979170e02e7 6796 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 6797 CYASSL_MSG("Trying ECC client cert, RSA didn't work");
ashleymills 0:e979170e02e7 6798
ashleymills 0:e979170e02e7 6799 idx = 0;
ashleymills 0:e979170e02e7 6800 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &eccKey,
ashleymills 0:e979170e02e7 6801 ssl->buffers.key.length);
ashleymills 0:e979170e02e7 6802 if (ret == 0) {
ashleymills 0:e979170e02e7 6803 CYASSL_MSG("Using ECC client cert");
ashleymills 0:e979170e02e7 6804 usingEcc = 1;
ashleymills 0:e979170e02e7 6805 sigOutSz = ecc_sig_size(&eccKey);
ashleymills 0:e979170e02e7 6806 }
ashleymills 0:e979170e02e7 6807 else {
ashleymills 0:e979170e02e7 6808 CYASSL_MSG("Bad client cert type");
ashleymills 0:e979170e02e7 6809 }
ashleymills 0:e979170e02e7 6810 #endif
ashleymills 0:e979170e02e7 6811 }
ashleymills 0:e979170e02e7 6812 if (ret == 0) {
ashleymills 0:e979170e02e7 6813 byte* verify = (byte*)&output[RECORD_HEADER_SZ +
ashleymills 0:e979170e02e7 6814 HANDSHAKE_HEADER_SZ];
ashleymills 0:e979170e02e7 6815 byte* signBuffer = ssl->certHashes.md5;
ashleymills 0:e979170e02e7 6816 word32 signSz = sizeof(Hashes);
ashleymills 0:e979170e02e7 6817 byte encodedSig[MAX_ENCODED_SIG_SZ];
ashleymills 0:e979170e02e7 6818 word32 extraSz = 0; /* tls 1.2 hash/sig */
ashleymills 0:e979170e02e7 6819
ashleymills 0:e979170e02e7 6820 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 6821 if (ssl->options.dtls)
ashleymills 0:e979170e02e7 6822 verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 6823 #endif
ashleymills 0:e979170e02e7 6824 length = sigOutSz;
ashleymills 0:e979170e02e7 6825 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:e979170e02e7 6826 verify[0] = sha_mac;
ashleymills 0:e979170e02e7 6827 verify[1] = usingEcc ? ecc_dsa_sa_algo : rsa_sa_algo;
ashleymills 0:e979170e02e7 6828 extraSz = HASH_SIG_SIZE;
ashleymills 0:e979170e02e7 6829 }
ashleymills 0:e979170e02e7 6830 c16toa((word16)length, verify + extraSz); /* prepend verify header*/
ashleymills 0:e979170e02e7 6831
ashleymills 0:e979170e02e7 6832 if (usingEcc) {
ashleymills 0:e979170e02e7 6833 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 6834 word32 localSz = sigOutSz;
ashleymills 0:e979170e02e7 6835 ret = ecc_sign_hash(signBuffer + MD5_DIGEST_SIZE,
ashleymills 0:e979170e02e7 6836 SHA_DIGEST_SIZE, verify + extraSz + VERIFY_HEADER,
ashleymills 0:e979170e02e7 6837 &localSz, ssl->rng, &eccKey);
ashleymills 0:e979170e02e7 6838 #endif
ashleymills 0:e979170e02e7 6839 }
ashleymills 0:e979170e02e7 6840 else {
ashleymills 0:e979170e02e7 6841 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:e979170e02e7 6842 byte* digest;
ashleymills 0:e979170e02e7 6843 int typeH;
ashleymills 0:e979170e02e7 6844 int digestSz;
ashleymills 0:e979170e02e7 6845
ashleymills 0:e979170e02e7 6846 /* sha1 for now */
ashleymills 0:e979170e02e7 6847 digest = ssl->certHashes.sha;
ashleymills 0:e979170e02e7 6848 typeH = SHAh;
ashleymills 0:e979170e02e7 6849 digestSz = SHA_DIGEST_SIZE;
ashleymills 0:e979170e02e7 6850
ashleymills 0:e979170e02e7 6851 signSz = EncodeSignature(encodedSig, digest,digestSz,typeH);
ashleymills 0:e979170e02e7 6852 signBuffer = encodedSig;
ashleymills 0:e979170e02e7 6853 }
ashleymills 0:e979170e02e7 6854
ashleymills 0:e979170e02e7 6855 ret = RsaSSL_Sign(signBuffer, signSz, verify + extraSz +
ashleymills 0:e979170e02e7 6856 VERIFY_HEADER, ENCRYPT_LEN, &key, ssl->rng);
ashleymills 0:e979170e02e7 6857
ashleymills 0:e979170e02e7 6858 if (ret > 0)
ashleymills 0:e979170e02e7 6859 ret = 0; /* RSA reset */
ashleymills 0:e979170e02e7 6860 }
ashleymills 0:e979170e02e7 6861
ashleymills 0:e979170e02e7 6862 if (ret == 0) {
ashleymills 0:e979170e02e7 6863 AddHeaders(output, length + extraSz + VERIFY_HEADER,
ashleymills 0:e979170e02e7 6864 certificate_verify, ssl);
ashleymills 0:e979170e02e7 6865
ashleymills 0:e979170e02e7 6866 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + length +
ashleymills 0:e979170e02e7 6867 extraSz + VERIFY_HEADER;
ashleymills 0:e979170e02e7 6868 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 6869 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 6870 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 6871 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:e979170e02e7 6872 return ret;
ashleymills 0:e979170e02e7 6873 }
ashleymills 0:e979170e02e7 6874 #endif
ashleymills 0:e979170e02e7 6875 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:e979170e02e7 6876 }
ashleymills 0:e979170e02e7 6877 }
ashleymills 0:e979170e02e7 6878
ashleymills 0:e979170e02e7 6879 FreeRsaKey(&key);
ashleymills 0:e979170e02e7 6880 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 6881 ecc_free(&eccKey);
ashleymills 0:e979170e02e7 6882 #endif
ashleymills 0:e979170e02e7 6883
ashleymills 0:e979170e02e7 6884 if (ret == 0) {
ashleymills 0:e979170e02e7 6885 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 6886 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 6887 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 6888 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 6889 AddPacketInfo("CertificateVerify", &ssl->timeoutInfo,
ashleymills 0:e979170e02e7 6890 output, sendSz, ssl->heap);
ashleymills 0:e979170e02e7 6891 #endif
ashleymills 0:e979170e02e7 6892 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:e979170e02e7 6893 if (ssl->options.groupMessages)
ashleymills 0:e979170e02e7 6894 return 0;
ashleymills 0:e979170e02e7 6895 else
ashleymills 0:e979170e02e7 6896 return SendBuffered(ssl);
ashleymills 0:e979170e02e7 6897 }
ashleymills 0:e979170e02e7 6898 else
ashleymills 0:e979170e02e7 6899 return ret;
ashleymills 0:e979170e02e7 6900 }
ashleymills 0:e979170e02e7 6901 #endif /* NO_RSA */
ashleymills 0:e979170e02e7 6902
ashleymills 0:e979170e02e7 6903
ashleymills 0:e979170e02e7 6904 #endif /* NO_CYASSL_CLIENT */
ashleymills 0:e979170e02e7 6905
ashleymills 0:e979170e02e7 6906
ashleymills 0:e979170e02e7 6907 #ifndef NO_CYASSL_SERVER
ashleymills 0:e979170e02e7 6908
ashleymills 0:e979170e02e7 6909 int SendServerHello(CYASSL* ssl)
ashleymills 0:e979170e02e7 6910 {
ashleymills 0:e979170e02e7 6911 byte *output;
ashleymills 0:e979170e02e7 6912 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 6913 int sendSz;
ashleymills 0:e979170e02e7 6914 int ret;
ashleymills 0:e979170e02e7 6915
ashleymills 0:e979170e02e7 6916 length = VERSION_SZ + RAN_LEN
ashleymills 0:e979170e02e7 6917 + ID_LEN + ENUM_LEN
ashleymills 0:e979170e02e7 6918 + SUITE_LEN
ashleymills 0:e979170e02e7 6919 + ENUM_LEN;
ashleymills 0:e979170e02e7 6920
ashleymills 0:e979170e02e7 6921 /* check for avalaible size */
ashleymills 0:e979170e02e7 6922 if ((ret = CheckAvalaibleSize(ssl, MAX_HELLO_SZ)) != 0)
ashleymills 0:e979170e02e7 6923 return ret;
ashleymills 0:e979170e02e7 6924
ashleymills 0:e979170e02e7 6925 /* get ouput buffer */
ashleymills 0:e979170e02e7 6926 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 6927 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 6928
ashleymills 0:e979170e02e7 6929 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 6930 AddHeaders(output, length, server_hello, ssl);
ashleymills 0:e979170e02e7 6931
ashleymills 0:e979170e02e7 6932 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 6933 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 6934 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 6935 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 6936 }
ashleymills 0:e979170e02e7 6937 #endif
ashleymills 0:e979170e02e7 6938 /* now write to output */
ashleymills 0:e979170e02e7 6939 /* first version */
ashleymills 0:e979170e02e7 6940 output[idx++] = ssl->version.major;
ashleymills 0:e979170e02e7 6941 output[idx++] = ssl->version.minor;
ashleymills 0:e979170e02e7 6942
ashleymills 0:e979170e02e7 6943 /* then random */
ashleymills 0:e979170e02e7 6944 if (!ssl->options.resuming)
ashleymills 0:e979170e02e7 6945 RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:e979170e02e7 6946 XMEMCPY(output + idx, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:e979170e02e7 6947 idx += RAN_LEN;
ashleymills 0:e979170e02e7 6948
ashleymills 0:e979170e02e7 6949 #ifdef SHOW_SECRETS
ashleymills 0:e979170e02e7 6950 {
ashleymills 0:e979170e02e7 6951 int j;
ashleymills 0:e979170e02e7 6952 printf("server random: ");
ashleymills 0:e979170e02e7 6953 for (j = 0; j < RAN_LEN; j++)
ashleymills 0:e979170e02e7 6954 printf("%02x", ssl->arrays->serverRandom[j]);
ashleymills 0:e979170e02e7 6955 printf("\n");
ashleymills 0:e979170e02e7 6956 }
ashleymills 0:e979170e02e7 6957 #endif
ashleymills 0:e979170e02e7 6958 /* then session id */
ashleymills 0:e979170e02e7 6959 output[idx++] = ID_LEN;
ashleymills 0:e979170e02e7 6960 if (!ssl->options.resuming)
ashleymills 0:e979170e02e7 6961 RNG_GenerateBlock(ssl->rng, ssl->arrays->sessionID, ID_LEN);
ashleymills 0:e979170e02e7 6962 XMEMCPY(output + idx, ssl->arrays->sessionID, ID_LEN);
ashleymills 0:e979170e02e7 6963 idx += ID_LEN;
ashleymills 0:e979170e02e7 6964
ashleymills 0:e979170e02e7 6965 /* then cipher suite */
ashleymills 0:e979170e02e7 6966 output[idx++] = ssl->options.cipherSuite0;
ashleymills 0:e979170e02e7 6967 output[idx++] = ssl->options.cipherSuite;
ashleymills 0:e979170e02e7 6968
ashleymills 0:e979170e02e7 6969 /* last, compression */
ashleymills 0:e979170e02e7 6970 if (ssl->options.usingCompression)
ashleymills 0:e979170e02e7 6971 output[idx++] = ZLIB_COMPRESSION;
ashleymills 0:e979170e02e7 6972 else
ashleymills 0:e979170e02e7 6973 output[idx++] = NO_COMPRESSION;
ashleymills 0:e979170e02e7 6974
ashleymills 0:e979170e02e7 6975 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:e979170e02e7 6976 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 6977 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 6978 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:e979170e02e7 6979 return ret;
ashleymills 0:e979170e02e7 6980 }
ashleymills 0:e979170e02e7 6981 #endif
ashleymills 0:e979170e02e7 6982 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:e979170e02e7 6983
ashleymills 0:e979170e02e7 6984 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 6985 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 6986 AddPacketName("ServerHello", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 6987 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 6988 AddPacketInfo("ServerHello", &ssl->timeoutInfo, output, sendSz,
ashleymills 0:e979170e02e7 6989 ssl->heap);
ashleymills 0:e979170e02e7 6990 #endif
ashleymills 0:e979170e02e7 6991
ashleymills 0:e979170e02e7 6992 ssl->options.serverState = SERVER_HELLO_COMPLETE;
ashleymills 0:e979170e02e7 6993
ashleymills 0:e979170e02e7 6994 if (ssl->options.groupMessages)
ashleymills 0:e979170e02e7 6995 return 0;
ashleymills 0:e979170e02e7 6996 else
ashleymills 0:e979170e02e7 6997 return SendBuffered(ssl);
ashleymills 0:e979170e02e7 6998 }
ashleymills 0:e979170e02e7 6999
ashleymills 0:e979170e02e7 7000
ashleymills 0:e979170e02e7 7001 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 7002
ashleymills 0:e979170e02e7 7003 static byte SetCurveId(int size)
ashleymills 0:e979170e02e7 7004 {
ashleymills 0:e979170e02e7 7005 switch(size) {
ashleymills 0:e979170e02e7 7006 case 20:
ashleymills 0:e979170e02e7 7007 return secp160r1;
ashleymills 0:e979170e02e7 7008 break;
ashleymills 0:e979170e02e7 7009 case 24:
ashleymills 0:e979170e02e7 7010 return secp192r1;
ashleymills 0:e979170e02e7 7011 break;
ashleymills 0:e979170e02e7 7012 case 28:
ashleymills 0:e979170e02e7 7013 return secp224r1;
ashleymills 0:e979170e02e7 7014 break;
ashleymills 0:e979170e02e7 7015 case 32:
ashleymills 0:e979170e02e7 7016 return secp256r1;
ashleymills 0:e979170e02e7 7017 break;
ashleymills 0:e979170e02e7 7018 case 48:
ashleymills 0:e979170e02e7 7019 return secp384r1;
ashleymills 0:e979170e02e7 7020 break;
ashleymills 0:e979170e02e7 7021 case 66:
ashleymills 0:e979170e02e7 7022 return secp521r1;
ashleymills 0:e979170e02e7 7023 break;
ashleymills 0:e979170e02e7 7024 default:
ashleymills 0:e979170e02e7 7025 return 0;
ashleymills 0:e979170e02e7 7026 }
ashleymills 0:e979170e02e7 7027 }
ashleymills 0:e979170e02e7 7028
ashleymills 0:e979170e02e7 7029 #endif /* HAVE_ECC */
ashleymills 0:e979170e02e7 7030
ashleymills 0:e979170e02e7 7031
ashleymills 0:e979170e02e7 7032 int SendServerKeyExchange(CYASSL* ssl)
ashleymills 0:e979170e02e7 7033 {
ashleymills 0:e979170e02e7 7034 int ret = 0;
ashleymills 0:e979170e02e7 7035 (void)ssl;
ashleymills 0:e979170e02e7 7036
ashleymills 0:e979170e02e7 7037 #ifndef NO_PSK
ashleymills 0:e979170e02e7 7038 if (ssl->specs.kea == psk_kea)
ashleymills 0:e979170e02e7 7039 {
ashleymills 0:e979170e02e7 7040 byte *output;
ashleymills 0:e979170e02e7 7041 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 7042 int sendSz;
ashleymills 0:e979170e02e7 7043 if (ssl->arrays->server_hint[0] == 0) return 0; /* don't send */
ashleymills 0:e979170e02e7 7044
ashleymills 0:e979170e02e7 7045 /* include size part */
ashleymills 0:e979170e02e7 7046 length = (word32)XSTRLEN(ssl->arrays->server_hint);
ashleymills 0:e979170e02e7 7047 if (length > MAX_PSK_ID_LEN) return SERVER_HINT_ERROR;
ashleymills 0:e979170e02e7 7048 length += HINT_LEN_SZ;
ashleymills 0:e979170e02e7 7049 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 7050
ashleymills 0:e979170e02e7 7051 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 7052 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 7053 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 7054 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 7055 }
ashleymills 0:e979170e02e7 7056 #endif
ashleymills 0:e979170e02e7 7057 /* check for avalaible size */
ashleymills 0:e979170e02e7 7058 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
ashleymills 0:e979170e02e7 7059 return ret;
ashleymills 0:e979170e02e7 7060
ashleymills 0:e979170e02e7 7061 /* get ouput buffer */
ashleymills 0:e979170e02e7 7062 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 7063 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 7064
ashleymills 0:e979170e02e7 7065 AddHeaders(output, length, server_key_exchange, ssl);
ashleymills 0:e979170e02e7 7066
ashleymills 0:e979170e02e7 7067 /* key data */
ashleymills 0:e979170e02e7 7068 c16toa((word16)(length - HINT_LEN_SZ), output + idx);
ashleymills 0:e979170e02e7 7069 idx += HINT_LEN_SZ;
ashleymills 0:e979170e02e7 7070 XMEMCPY(output + idx, ssl->arrays->server_hint,length -HINT_LEN_SZ);
ashleymills 0:e979170e02e7 7071
ashleymills 0:e979170e02e7 7072 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:e979170e02e7 7073
ashleymills 0:e979170e02e7 7074 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 7075 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 7076 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 7077 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 7078 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
ashleymills 0:e979170e02e7 7079 output, sendSz, ssl->heap);
ashleymills 0:e979170e02e7 7080 #endif
ashleymills 0:e979170e02e7 7081
ashleymills 0:e979170e02e7 7082 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:e979170e02e7 7083 if (ssl->options.groupMessages)
ashleymills 0:e979170e02e7 7084 ret = 0;
ashleymills 0:e979170e02e7 7085 else
ashleymills 0:e979170e02e7 7086 ret = SendBuffered(ssl);
ashleymills 0:e979170e02e7 7087 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
ashleymills 0:e979170e02e7 7088 }
ashleymills 0:e979170e02e7 7089 #endif /*NO_PSK */
ashleymills 0:e979170e02e7 7090
ashleymills 0:e979170e02e7 7091 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 7092 if (ssl->specs.kea == ecc_diffie_hellman_kea)
ashleymills 0:e979170e02e7 7093 {
ashleymills 0:e979170e02e7 7094 byte *output;
ashleymills 0:e979170e02e7 7095 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 7096 int sendSz;
ashleymills 0:e979170e02e7 7097 byte exportBuf[MAX_EXPORT_ECC_SZ];
ashleymills 0:e979170e02e7 7098 word32 expSz = sizeof(exportBuf);
ashleymills 0:e979170e02e7 7099 word32 sigSz;
ashleymills 0:e979170e02e7 7100 word32 preSigSz, preSigIdx;
ashleymills 0:e979170e02e7 7101 RsaKey rsaKey;
ashleymills 0:e979170e02e7 7102 ecc_key dsaKey;
ashleymills 0:e979170e02e7 7103
ashleymills 0:e979170e02e7 7104 if (ssl->specs.static_ecdh) {
ashleymills 0:e979170e02e7 7105 CYASSL_MSG("Using Static ECDH, not sending ServerKeyExchagne");
ashleymills 0:e979170e02e7 7106 return 0;
ashleymills 0:e979170e02e7 7107 }
ashleymills 0:e979170e02e7 7108
ashleymills 0:e979170e02e7 7109 /* curve type, named curve, length(1) */
ashleymills 0:e979170e02e7 7110 length = ENUM_LEN + CURVE_LEN + ENUM_LEN;
ashleymills 0:e979170e02e7 7111 /* pub key size */
ashleymills 0:e979170e02e7 7112 CYASSL_MSG("Using ephemeral ECDH");
ashleymills 0:e979170e02e7 7113 if (ecc_export_x963(ssl->eccTempKey, exportBuf, &expSz) != 0)
ashleymills 0:e979170e02e7 7114 return ECC_EXPORT_ERROR;
ashleymills 0:e979170e02e7 7115 length += expSz;
ashleymills 0:e979170e02e7 7116
ashleymills 0:e979170e02e7 7117 preSigSz = length;
ashleymills 0:e979170e02e7 7118 preSigIdx = idx;
ashleymills 0:e979170e02e7 7119
ashleymills 0:e979170e02e7 7120 InitRsaKey(&rsaKey, ssl->heap);
ashleymills 0:e979170e02e7 7121 ecc_init(&dsaKey);
ashleymills 0:e979170e02e7 7122
ashleymills 0:e979170e02e7 7123 /* sig length */
ashleymills 0:e979170e02e7 7124 length += LENGTH_SZ;
ashleymills 0:e979170e02e7 7125
ashleymills 0:e979170e02e7 7126 if (!ssl->buffers.key.buffer) {
ashleymills 0:e979170e02e7 7127 FreeRsaKey(&rsaKey);
ashleymills 0:e979170e02e7 7128 ecc_free(&dsaKey);
ashleymills 0:e979170e02e7 7129 return NO_PRIVATE_KEY;
ashleymills 0:e979170e02e7 7130 }
ashleymills 0:e979170e02e7 7131
ashleymills 0:e979170e02e7 7132 if (ssl->specs.sig_algo == rsa_sa_algo) {
ashleymills 0:e979170e02e7 7133 /* rsa sig size */
ashleymills 0:e979170e02e7 7134 word32 i = 0;
ashleymills 0:e979170e02e7 7135 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i,
ashleymills 0:e979170e02e7 7136 &rsaKey, ssl->buffers.key.length);
ashleymills 0:e979170e02e7 7137 if (ret != 0) return ret;
ashleymills 0:e979170e02e7 7138 sigSz = RsaEncryptSize(&rsaKey);
ashleymills 0:e979170e02e7 7139 }
ashleymills 0:e979170e02e7 7140 else if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
ashleymills 0:e979170e02e7 7141 /* ecdsa sig size */
ashleymills 0:e979170e02e7 7142 word32 i = 0;
ashleymills 0:e979170e02e7 7143 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
ashleymills 0:e979170e02e7 7144 &dsaKey, ssl->buffers.key.length);
ashleymills 0:e979170e02e7 7145 if (ret != 0) return ret;
ashleymills 0:e979170e02e7 7146 sigSz = ecc_sig_size(&dsaKey);
ashleymills 0:e979170e02e7 7147 }
ashleymills 0:e979170e02e7 7148 else {
ashleymills 0:e979170e02e7 7149 FreeRsaKey(&rsaKey);
ashleymills 0:e979170e02e7 7150 ecc_free(&dsaKey);
ashleymills 0:e979170e02e7 7151 return ALGO_ID_E; /* unsupported type */
ashleymills 0:e979170e02e7 7152 }
ashleymills 0:e979170e02e7 7153 length += sigSz;
ashleymills 0:e979170e02e7 7154
ashleymills 0:e979170e02e7 7155 if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:e979170e02e7 7156 length += HASH_SIG_SIZE;
ashleymills 0:e979170e02e7 7157
ashleymills 0:e979170e02e7 7158 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 7159
ashleymills 0:e979170e02e7 7160 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 7161 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 7162 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 7163 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 7164 preSigIdx = idx;
ashleymills 0:e979170e02e7 7165 }
ashleymills 0:e979170e02e7 7166 #endif
ashleymills 0:e979170e02e7 7167 /* check for avalaible size */
ashleymills 0:e979170e02e7 7168 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0) {
ashleymills 0:e979170e02e7 7169 FreeRsaKey(&rsaKey);
ashleymills 0:e979170e02e7 7170 ecc_free(&dsaKey);
ashleymills 0:e979170e02e7 7171 return ret;
ashleymills 0:e979170e02e7 7172 }
ashleymills 0:e979170e02e7 7173
ashleymills 0:e979170e02e7 7174 /* get ouput buffer */
ashleymills 0:e979170e02e7 7175 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 7176 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 7177
ashleymills 0:e979170e02e7 7178 AddHeaders(output, length, server_key_exchange, ssl);
ashleymills 0:e979170e02e7 7179
ashleymills 0:e979170e02e7 7180 /* key exchange data */
ashleymills 0:e979170e02e7 7181 output[idx++] = named_curve;
ashleymills 0:e979170e02e7 7182 output[idx++] = 0x00; /* leading zero */
ashleymills 0:e979170e02e7 7183 output[idx++] = SetCurveId(ecc_size(ssl->eccTempKey));
ashleymills 0:e979170e02e7 7184 output[idx++] = (byte)expSz;
ashleymills 0:e979170e02e7 7185 XMEMCPY(output + idx, exportBuf, expSz);
ashleymills 0:e979170e02e7 7186 idx += expSz;
ashleymills 0:e979170e02e7 7187 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:e979170e02e7 7188 output[idx++] = sha_mac;
ashleymills 0:e979170e02e7 7189 output[idx++] = ssl->specs.sig_algo;
ashleymills 0:e979170e02e7 7190 }
ashleymills 0:e979170e02e7 7191 c16toa((word16)sigSz, output + idx);
ashleymills 0:e979170e02e7 7192 idx += LENGTH_SZ;
ashleymills 0:e979170e02e7 7193
ashleymills 0:e979170e02e7 7194 /* do signature */
ashleymills 0:e979170e02e7 7195 {
ashleymills 0:e979170e02e7 7196 Md5 md5;
ashleymills 0:e979170e02e7 7197 Sha sha;
ashleymills 0:e979170e02e7 7198 byte hash[FINISHED_SZ];
ashleymills 0:e979170e02e7 7199
ashleymills 0:e979170e02e7 7200 /* md5 */
ashleymills 0:e979170e02e7 7201 InitMd5(&md5);
ashleymills 0:e979170e02e7 7202 Md5Update(&md5, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:e979170e02e7 7203 Md5Update(&md5, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:e979170e02e7 7204 Md5Update(&md5, output + preSigIdx, preSigSz);
ashleymills 0:e979170e02e7 7205 Md5Final(&md5, hash);
ashleymills 0:e979170e02e7 7206
ashleymills 0:e979170e02e7 7207 /* sha */
ashleymills 0:e979170e02e7 7208 InitSha(&sha);
ashleymills 0:e979170e02e7 7209 ShaUpdate(&sha, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:e979170e02e7 7210 ShaUpdate(&sha, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:e979170e02e7 7211 ShaUpdate(&sha, output + preSigIdx, preSigSz);
ashleymills 0:e979170e02e7 7212 ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
ashleymills 0:e979170e02e7 7213
ashleymills 0:e979170e02e7 7214 if (ssl->specs.sig_algo == rsa_sa_algo) {
ashleymills 0:e979170e02e7 7215 byte* signBuffer = hash;
ashleymills 0:e979170e02e7 7216 word32 signSz = sizeof(hash);
ashleymills 0:e979170e02e7 7217 byte encodedSig[MAX_ENCODED_SIG_SZ];
ashleymills 0:e979170e02e7 7218 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:e979170e02e7 7219 byte* digest;
ashleymills 0:e979170e02e7 7220 int hType;
ashleymills 0:e979170e02e7 7221 int digestSz;
ashleymills 0:e979170e02e7 7222
ashleymills 0:e979170e02e7 7223 /* sha1 for now */
ashleymills 0:e979170e02e7 7224 digest = &hash[MD5_DIGEST_SIZE];
ashleymills 0:e979170e02e7 7225 hType = SHAh;
ashleymills 0:e979170e02e7 7226 digestSz = SHA_DIGEST_SIZE;
ashleymills 0:e979170e02e7 7227
ashleymills 0:e979170e02e7 7228 signSz = EncodeSignature(encodedSig, digest, digestSz,
ashleymills 0:e979170e02e7 7229 hType);
ashleymills 0:e979170e02e7 7230 signBuffer = encodedSig;
ashleymills 0:e979170e02e7 7231 }
ashleymills 0:e979170e02e7 7232 ret = RsaSSL_Sign(signBuffer, signSz, output + idx, sigSz,
ashleymills 0:e979170e02e7 7233 &rsaKey, ssl->rng);
ashleymills 0:e979170e02e7 7234 FreeRsaKey(&rsaKey);
ashleymills 0:e979170e02e7 7235 ecc_free(&dsaKey);
ashleymills 0:e979170e02e7 7236 if (ret > 0)
ashleymills 0:e979170e02e7 7237 ret = 0; /* reset on success */
ashleymills 0:e979170e02e7 7238 else
ashleymills 0:e979170e02e7 7239 return ret;
ashleymills 0:e979170e02e7 7240 }
ashleymills 0:e979170e02e7 7241 else if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
ashleymills 0:e979170e02e7 7242 word32 sz = sigSz;
ashleymills 0:e979170e02e7 7243
ashleymills 0:e979170e02e7 7244 ret = ecc_sign_hash(&hash[MD5_DIGEST_SIZE], SHA_DIGEST_SIZE,
ashleymills 0:e979170e02e7 7245 output + idx, &sz, ssl->rng, &dsaKey);
ashleymills 0:e979170e02e7 7246 FreeRsaKey(&rsaKey);
ashleymills 0:e979170e02e7 7247 ecc_free(&dsaKey);
ashleymills 0:e979170e02e7 7248 if (ret < 0) return ret;
ashleymills 0:e979170e02e7 7249 }
ashleymills 0:e979170e02e7 7250 }
ashleymills 0:e979170e02e7 7251
ashleymills 0:e979170e02e7 7252 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:e979170e02e7 7253
ashleymills 0:e979170e02e7 7254 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 7255 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 7256 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 7257 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 7258 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
ashleymills 0:e979170e02e7 7259 output, sendSz, ssl->heap);
ashleymills 0:e979170e02e7 7260 #endif
ashleymills 0:e979170e02e7 7261
ashleymills 0:e979170e02e7 7262 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:e979170e02e7 7263 if (ssl->options.groupMessages)
ashleymills 0:e979170e02e7 7264 ret = 0;
ashleymills 0:e979170e02e7 7265 else
ashleymills 0:e979170e02e7 7266 ret = SendBuffered(ssl);
ashleymills 0:e979170e02e7 7267 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
ashleymills 0:e979170e02e7 7268 }
ashleymills 0:e979170e02e7 7269 #endif /* HAVE_ECC */
ashleymills 0:e979170e02e7 7270
ashleymills 0:e979170e02e7 7271 #ifdef OPENSSL_EXTRA
ashleymills 0:e979170e02e7 7272 if (ssl->specs.kea == diffie_hellman_kea) {
ashleymills 0:e979170e02e7 7273 byte *output;
ashleymills 0:e979170e02e7 7274 word32 length = 0, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 7275 int sendSz;
ashleymills 0:e979170e02e7 7276 word32 sigSz = 0, i = 0;
ashleymills 0:e979170e02e7 7277 word32 preSigSz = 0, preSigIdx = 0;
ashleymills 0:e979170e02e7 7278 RsaKey rsaKey;
ashleymills 0:e979170e02e7 7279 DhKey dhKey;
ashleymills 0:e979170e02e7 7280
ashleymills 0:e979170e02e7 7281 if (ssl->buffers.serverDH_P.buffer == NULL ||
ashleymills 0:e979170e02e7 7282 ssl->buffers.serverDH_G.buffer == NULL)
ashleymills 0:e979170e02e7 7283 return NO_DH_PARAMS;
ashleymills 0:e979170e02e7 7284
ashleymills 0:e979170e02e7 7285 if (ssl->buffers.serverDH_Pub.buffer == NULL) {
ashleymills 0:e979170e02e7 7286 ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
ashleymills 0:e979170e02e7 7287 ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
ashleymills 0:e979170e02e7 7288 DYNAMIC_TYPE_DH);
ashleymills 0:e979170e02e7 7289 if (ssl->buffers.serverDH_Pub.buffer == NULL)
ashleymills 0:e979170e02e7 7290 return MEMORY_E;
ashleymills 0:e979170e02e7 7291 }
ashleymills 0:e979170e02e7 7292
ashleymills 0:e979170e02e7 7293 if (ssl->buffers.serverDH_Priv.buffer == NULL) {
ashleymills 0:e979170e02e7 7294 ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
ashleymills 0:e979170e02e7 7295 ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
ashleymills 0:e979170e02e7 7296 DYNAMIC_TYPE_DH);
ashleymills 0:e979170e02e7 7297 if (ssl->buffers.serverDH_Priv.buffer == NULL)
ashleymills 0:e979170e02e7 7298 return MEMORY_E;
ashleymills 0:e979170e02e7 7299 }
ashleymills 0:e979170e02e7 7300
ashleymills 0:e979170e02e7 7301 InitDhKey(&dhKey);
ashleymills 0:e979170e02e7 7302 ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
ashleymills 0:e979170e02e7 7303 ssl->buffers.serverDH_P.length,
ashleymills 0:e979170e02e7 7304 ssl->buffers.serverDH_G.buffer,
ashleymills 0:e979170e02e7 7305 ssl->buffers.serverDH_G.length);
ashleymills 0:e979170e02e7 7306 if (ret == 0)
ashleymills 0:e979170e02e7 7307 ret = DhGenerateKeyPair(&dhKey, ssl->rng,
ashleymills 0:e979170e02e7 7308 ssl->buffers.serverDH_Priv.buffer,
ashleymills 0:e979170e02e7 7309 &ssl->buffers.serverDH_Priv.length,
ashleymills 0:e979170e02e7 7310 ssl->buffers.serverDH_Pub.buffer,
ashleymills 0:e979170e02e7 7311 &ssl->buffers.serverDH_Pub.length);
ashleymills 0:e979170e02e7 7312 FreeDhKey(&dhKey);
ashleymills 0:e979170e02e7 7313
ashleymills 0:e979170e02e7 7314 if (ret == 0) {
ashleymills 0:e979170e02e7 7315 length = LENGTH_SZ * 3; /* p, g, pub */
ashleymills 0:e979170e02e7 7316 length += ssl->buffers.serverDH_P.length +
ashleymills 0:e979170e02e7 7317 ssl->buffers.serverDH_G.length +
ashleymills 0:e979170e02e7 7318 ssl->buffers.serverDH_Pub.length;
ashleymills 0:e979170e02e7 7319
ashleymills 0:e979170e02e7 7320 preSigIdx = idx;
ashleymills 0:e979170e02e7 7321 preSigSz = length;
ashleymills 0:e979170e02e7 7322
ashleymills 0:e979170e02e7 7323 /* sig length */
ashleymills 0:e979170e02e7 7324 length += LENGTH_SZ;
ashleymills 0:e979170e02e7 7325
ashleymills 0:e979170e02e7 7326 if (!ssl->buffers.key.buffer)
ashleymills 0:e979170e02e7 7327 return NO_PRIVATE_KEY;
ashleymills 0:e979170e02e7 7328
ashleymills 0:e979170e02e7 7329 InitRsaKey(&rsaKey, ssl->heap);
ashleymills 0:e979170e02e7 7330 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i, &rsaKey,
ashleymills 0:e979170e02e7 7331 ssl->buffers.key.length);
ashleymills 0:e979170e02e7 7332 if (ret == 0) {
ashleymills 0:e979170e02e7 7333 sigSz = RsaEncryptSize(&rsaKey);
ashleymills 0:e979170e02e7 7334 length += sigSz;
ashleymills 0:e979170e02e7 7335 }
ashleymills 0:e979170e02e7 7336 }
ashleymills 0:e979170e02e7 7337 if (ret != 0) {
ashleymills 0:e979170e02e7 7338 FreeRsaKey(&rsaKey);
ashleymills 0:e979170e02e7 7339 return ret;
ashleymills 0:e979170e02e7 7340 }
ashleymills 0:e979170e02e7 7341
ashleymills 0:e979170e02e7 7342 if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:e979170e02e7 7343 length += HASH_SIG_SIZE;
ashleymills 0:e979170e02e7 7344
ashleymills 0:e979170e02e7 7345 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
ashleymills 0:e979170e02e7 7346
ashleymills 0:e979170e02e7 7347 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 7348 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 7349 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 7350 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 7351 preSigIdx = idx;
ashleymills 0:e979170e02e7 7352 }
ashleymills 0:e979170e02e7 7353 #endif
ashleymills 0:e979170e02e7 7354 /* check for avalaible size */
ashleymills 0:e979170e02e7 7355 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0) {
ashleymills 0:e979170e02e7 7356 FreeRsaKey(&rsaKey);
ashleymills 0:e979170e02e7 7357 return ret;
ashleymills 0:e979170e02e7 7358 }
ashleymills 0:e979170e02e7 7359
ashleymills 0:e979170e02e7 7360 /* get ouput buffer */
ashleymills 0:e979170e02e7 7361 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 7362 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 7363
ashleymills 0:e979170e02e7 7364 AddHeaders(output, length, server_key_exchange, ssl);
ashleymills 0:e979170e02e7 7365
ashleymills 0:e979170e02e7 7366 /* add p, g, pub */
ashleymills 0:e979170e02e7 7367 c16toa((word16)ssl->buffers.serverDH_P.length, output + idx);
ashleymills 0:e979170e02e7 7368 idx += LENGTH_SZ;
ashleymills 0:e979170e02e7 7369 XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer,
ashleymills 0:e979170e02e7 7370 ssl->buffers.serverDH_P.length);
ashleymills 0:e979170e02e7 7371 idx += ssl->buffers.serverDH_P.length;
ashleymills 0:e979170e02e7 7372
ashleymills 0:e979170e02e7 7373 /* g */
ashleymills 0:e979170e02e7 7374 c16toa((word16)ssl->buffers.serverDH_G.length, output + idx);
ashleymills 0:e979170e02e7 7375 idx += LENGTH_SZ;
ashleymills 0:e979170e02e7 7376 XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer,
ashleymills 0:e979170e02e7 7377 ssl->buffers.serverDH_G.length);
ashleymills 0:e979170e02e7 7378 idx += ssl->buffers.serverDH_G.length;
ashleymills 0:e979170e02e7 7379
ashleymills 0:e979170e02e7 7380 /* pub */
ashleymills 0:e979170e02e7 7381 c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx);
ashleymills 0:e979170e02e7 7382 idx += LENGTH_SZ;
ashleymills 0:e979170e02e7 7383 XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer,
ashleymills 0:e979170e02e7 7384 ssl->buffers.serverDH_Pub.length);
ashleymills 0:e979170e02e7 7385 idx += ssl->buffers.serverDH_Pub.length;
ashleymills 0:e979170e02e7 7386
ashleymills 0:e979170e02e7 7387 /* Add signature */
ashleymills 0:e979170e02e7 7388 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:e979170e02e7 7389 output[idx++] = sha_mac;
ashleymills 0:e979170e02e7 7390 output[idx++] = ssl->specs.sig_algo;
ashleymills 0:e979170e02e7 7391 }
ashleymills 0:e979170e02e7 7392 /* size */
ashleymills 0:e979170e02e7 7393 c16toa((word16)sigSz, output + idx);
ashleymills 0:e979170e02e7 7394 idx += LENGTH_SZ;
ashleymills 0:e979170e02e7 7395
ashleymills 0:e979170e02e7 7396 /* do signature */
ashleymills 0:e979170e02e7 7397 {
ashleymills 0:e979170e02e7 7398 Md5 md5;
ashleymills 0:e979170e02e7 7399 Sha sha;
ashleymills 0:e979170e02e7 7400 byte hash[FINISHED_SZ];
ashleymills 0:e979170e02e7 7401
ashleymills 0:e979170e02e7 7402 /* md5 */
ashleymills 0:e979170e02e7 7403 InitMd5(&md5);
ashleymills 0:e979170e02e7 7404 Md5Update(&md5, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:e979170e02e7 7405 Md5Update(&md5, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:e979170e02e7 7406 Md5Update(&md5, output + preSigIdx, preSigSz);
ashleymills 0:e979170e02e7 7407 Md5Final(&md5, hash);
ashleymills 0:e979170e02e7 7408
ashleymills 0:e979170e02e7 7409 /* sha */
ashleymills 0:e979170e02e7 7410 InitSha(&sha);
ashleymills 0:e979170e02e7 7411 ShaUpdate(&sha, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:e979170e02e7 7412 ShaUpdate(&sha, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:e979170e02e7 7413 ShaUpdate(&sha, output + preSigIdx, preSigSz);
ashleymills 0:e979170e02e7 7414 ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
ashleymills 0:e979170e02e7 7415
ashleymills 0:e979170e02e7 7416 if (ssl->specs.sig_algo == rsa_sa_algo) {
ashleymills 0:e979170e02e7 7417 byte* signBuffer = hash;
ashleymills 0:e979170e02e7 7418 word32 signSz = sizeof(hash);
ashleymills 0:e979170e02e7 7419 byte encodedSig[MAX_ENCODED_SIG_SZ];
ashleymills 0:e979170e02e7 7420 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:e979170e02e7 7421 byte* digest;
ashleymills 0:e979170e02e7 7422 int typeH;
ashleymills 0:e979170e02e7 7423 int digestSz;
ashleymills 0:e979170e02e7 7424
ashleymills 0:e979170e02e7 7425 /* sha1 for now */
ashleymills 0:e979170e02e7 7426 digest = &hash[MD5_DIGEST_SIZE];
ashleymills 0:e979170e02e7 7427 typeH = SHAh;
ashleymills 0:e979170e02e7 7428 digestSz = SHA_DIGEST_SIZE;
ashleymills 0:e979170e02e7 7429
ashleymills 0:e979170e02e7 7430 signSz = EncodeSignature(encodedSig, digest, digestSz,
ashleymills 0:e979170e02e7 7431 typeH);
ashleymills 0:e979170e02e7 7432 signBuffer = encodedSig;
ashleymills 0:e979170e02e7 7433 }
ashleymills 0:e979170e02e7 7434 ret = RsaSSL_Sign(signBuffer, signSz, output + idx, sigSz,
ashleymills 0:e979170e02e7 7435 &rsaKey, ssl->rng);
ashleymills 0:e979170e02e7 7436 FreeRsaKey(&rsaKey);
ashleymills 0:e979170e02e7 7437 if (ret <= 0)
ashleymills 0:e979170e02e7 7438 return ret;
ashleymills 0:e979170e02e7 7439 }
ashleymills 0:e979170e02e7 7440 }
ashleymills 0:e979170e02e7 7441
ashleymills 0:e979170e02e7 7442 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 7443 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 7444 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:e979170e02e7 7445 return ret;
ashleymills 0:e979170e02e7 7446 }
ashleymills 0:e979170e02e7 7447 #endif
ashleymills 0:e979170e02e7 7448 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:e979170e02e7 7449
ashleymills 0:e979170e02e7 7450 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 7451 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 7452 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 7453 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 7454 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
ashleymills 0:e979170e02e7 7455 output, sendSz, ssl->heap);
ashleymills 0:e979170e02e7 7456 #endif
ashleymills 0:e979170e02e7 7457
ashleymills 0:e979170e02e7 7458 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:e979170e02e7 7459 if (ssl->options.groupMessages)
ashleymills 0:e979170e02e7 7460 ret = 0;
ashleymills 0:e979170e02e7 7461 else
ashleymills 0:e979170e02e7 7462 ret = SendBuffered(ssl);
ashleymills 0:e979170e02e7 7463 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
ashleymills 0:e979170e02e7 7464 }
ashleymills 0:e979170e02e7 7465 #endif /* OPENSSL_EXTRA */
ashleymills 0:e979170e02e7 7466
ashleymills 0:e979170e02e7 7467 return ret;
ashleymills 0:e979170e02e7 7468 }
ashleymills 0:e979170e02e7 7469
ashleymills 0:e979170e02e7 7470
ashleymills 0:e979170e02e7 7471 /* cipher requirements */
ashleymills 0:e979170e02e7 7472 enum {
ashleymills 0:e979170e02e7 7473 REQUIRES_RSA,
ashleymills 0:e979170e02e7 7474 REQUIRES_DHE,
ashleymills 0:e979170e02e7 7475 REQUIRES_ECC_DSA,
ashleymills 0:e979170e02e7 7476 REQUIRES_ECC_STATIC,
ashleymills 0:e979170e02e7 7477 REQUIRES_PSK,
ashleymills 0:e979170e02e7 7478 REQUIRES_NTRU,
ashleymills 0:e979170e02e7 7479 REQUIRES_RSA_SIG
ashleymills 0:e979170e02e7 7480 };
ashleymills 0:e979170e02e7 7481
ashleymills 0:e979170e02e7 7482
ashleymills 0:e979170e02e7 7483
ashleymills 0:e979170e02e7 7484 /* Does this cipher suite (first, second) have the requirement
ashleymills 0:e979170e02e7 7485 an ephemeral key exchange will still require the key for signing
ashleymills 0:e979170e02e7 7486 the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */
ashleymills 0:e979170e02e7 7487 static int CipherRequires(byte first, byte second, int requirement)
ashleymills 0:e979170e02e7 7488 {
ashleymills 0:e979170e02e7 7489 /* ECC extensions */
ashleymills 0:e979170e02e7 7490 if (first == ECC_BYTE) {
ashleymills 0:e979170e02e7 7491
ashleymills 0:e979170e02e7 7492 switch (second) {
ashleymills 0:e979170e02e7 7493
ashleymills 0:e979170e02e7 7494 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
ashleymills 0:e979170e02e7 7495 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7496 return 1;
ashleymills 0:e979170e02e7 7497 break;
ashleymills 0:e979170e02e7 7498
ashleymills 0:e979170e02e7 7499 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
ashleymills 0:e979170e02e7 7500 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:e979170e02e7 7501 return 1;
ashleymills 0:e979170e02e7 7502 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:e979170e02e7 7503 return 1;
ashleymills 0:e979170e02e7 7504 break;
ashleymills 0:e979170e02e7 7505
ashleymills 0:e979170e02e7 7506 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
ashleymills 0:e979170e02e7 7507 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7508 return 1;
ashleymills 0:e979170e02e7 7509 break;
ashleymills 0:e979170e02e7 7510
ashleymills 0:e979170e02e7 7511 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
ashleymills 0:e979170e02e7 7512 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:e979170e02e7 7513 return 1;
ashleymills 0:e979170e02e7 7514 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:e979170e02e7 7515 return 1;
ashleymills 0:e979170e02e7 7516 break;
ashleymills 0:e979170e02e7 7517
ashleymills 0:e979170e02e7 7518 case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
ashleymills 0:e979170e02e7 7519 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7520 return 1;
ashleymills 0:e979170e02e7 7521 break;
ashleymills 0:e979170e02e7 7522
ashleymills 0:e979170e02e7 7523 case TLS_ECDH_RSA_WITH_RC4_128_SHA :
ashleymills 0:e979170e02e7 7524 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:e979170e02e7 7525 return 1;
ashleymills 0:e979170e02e7 7526 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:e979170e02e7 7527 return 1;
ashleymills 0:e979170e02e7 7528 break;
ashleymills 0:e979170e02e7 7529
ashleymills 0:e979170e02e7 7530 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
ashleymills 0:e979170e02e7 7531 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:e979170e02e7 7532 return 1;
ashleymills 0:e979170e02e7 7533 break;
ashleymills 0:e979170e02e7 7534
ashleymills 0:e979170e02e7 7535 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
ashleymills 0:e979170e02e7 7536 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:e979170e02e7 7537 return 1;
ashleymills 0:e979170e02e7 7538 break;
ashleymills 0:e979170e02e7 7539
ashleymills 0:e979170e02e7 7540 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
ashleymills 0:e979170e02e7 7541 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:e979170e02e7 7542 return 1;
ashleymills 0:e979170e02e7 7543 break;
ashleymills 0:e979170e02e7 7544
ashleymills 0:e979170e02e7 7545 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
ashleymills 0:e979170e02e7 7546 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:e979170e02e7 7547 return 1;
ashleymills 0:e979170e02e7 7548 break;
ashleymills 0:e979170e02e7 7549
ashleymills 0:e979170e02e7 7550 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
ashleymills 0:e979170e02e7 7551 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7552 return 1;
ashleymills 0:e979170e02e7 7553 break;
ashleymills 0:e979170e02e7 7554
ashleymills 0:e979170e02e7 7555 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
ashleymills 0:e979170e02e7 7556 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:e979170e02e7 7557 return 1;
ashleymills 0:e979170e02e7 7558 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:e979170e02e7 7559 return 1;
ashleymills 0:e979170e02e7 7560 break;
ashleymills 0:e979170e02e7 7561
ashleymills 0:e979170e02e7 7562 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
ashleymills 0:e979170e02e7 7563 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:e979170e02e7 7564 return 1;
ashleymills 0:e979170e02e7 7565 break;
ashleymills 0:e979170e02e7 7566
ashleymills 0:e979170e02e7 7567 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
ashleymills 0:e979170e02e7 7568 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:e979170e02e7 7569 return 1;
ashleymills 0:e979170e02e7 7570 break;
ashleymills 0:e979170e02e7 7571
ashleymills 0:e979170e02e7 7572 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
ashleymills 0:e979170e02e7 7573 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:e979170e02e7 7574 return 1;
ashleymills 0:e979170e02e7 7575 break;
ashleymills 0:e979170e02e7 7576
ashleymills 0:e979170e02e7 7577 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
ashleymills 0:e979170e02e7 7578 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:e979170e02e7 7579 return 1;
ashleymills 0:e979170e02e7 7580 break;
ashleymills 0:e979170e02e7 7581
ashleymills 0:e979170e02e7 7582 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
ashleymills 0:e979170e02e7 7583 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:e979170e02e7 7584 return 1;
ashleymills 0:e979170e02e7 7585 break;
ashleymills 0:e979170e02e7 7586
ashleymills 0:e979170e02e7 7587 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
ashleymills 0:e979170e02e7 7588 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:e979170e02e7 7589 return 1;
ashleymills 0:e979170e02e7 7590 break;
ashleymills 0:e979170e02e7 7591
ashleymills 0:e979170e02e7 7592 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
ashleymills 0:e979170e02e7 7593 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:e979170e02e7 7594 return 1;
ashleymills 0:e979170e02e7 7595 break;
ashleymills 0:e979170e02e7 7596
ashleymills 0:e979170e02e7 7597 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
ashleymills 0:e979170e02e7 7598 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:e979170e02e7 7599 return 1;
ashleymills 0:e979170e02e7 7600 break;
ashleymills 0:e979170e02e7 7601
ashleymills 0:e979170e02e7 7602 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
ashleymills 0:e979170e02e7 7603 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7604 return 1;
ashleymills 0:e979170e02e7 7605 break;
ashleymills 0:e979170e02e7 7606
ashleymills 0:e979170e02e7 7607 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
ashleymills 0:e979170e02e7 7608 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7609 return 1;
ashleymills 0:e979170e02e7 7610 break;
ashleymills 0:e979170e02e7 7611
ashleymills 0:e979170e02e7 7612 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
ashleymills 0:e979170e02e7 7613 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:e979170e02e7 7614 return 1;
ashleymills 0:e979170e02e7 7615 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:e979170e02e7 7616 return 1;
ashleymills 0:e979170e02e7 7617 break;
ashleymills 0:e979170e02e7 7618
ashleymills 0:e979170e02e7 7619 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
ashleymills 0:e979170e02e7 7620 if (requirement == REQUIRES_ECC_STATIC)
ashleymills 0:e979170e02e7 7621 return 1;
ashleymills 0:e979170e02e7 7622 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:e979170e02e7 7623 return 1;
ashleymills 0:e979170e02e7 7624 break;
ashleymills 0:e979170e02e7 7625
ashleymills 0:e979170e02e7 7626 case TLS_RSA_WITH_AES_128_CCM_8_SHA256 :
ashleymills 0:e979170e02e7 7627 case TLS_RSA_WITH_AES_256_CCM_8_SHA384 :
ashleymills 0:e979170e02e7 7628 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7629 return 1;
ashleymills 0:e979170e02e7 7630 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:e979170e02e7 7631 return 1;
ashleymills 0:e979170e02e7 7632 break;
ashleymills 0:e979170e02e7 7633
ashleymills 0:e979170e02e7 7634 case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_SHA256 :
ashleymills 0:e979170e02e7 7635 case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8_SHA384 :
ashleymills 0:e979170e02e7 7636 if (requirement == REQUIRES_ECC_DSA)
ashleymills 0:e979170e02e7 7637 return 1;
ashleymills 0:e979170e02e7 7638 break;
ashleymills 0:e979170e02e7 7639
ashleymills 0:e979170e02e7 7640 default:
ashleymills 0:e979170e02e7 7641 CYASSL_MSG("Unsupported cipher suite, CipherRequires ECC");
ashleymills 0:e979170e02e7 7642 return 0;
ashleymills 0:e979170e02e7 7643 } /* switch */
ashleymills 0:e979170e02e7 7644 } /* if */
ashleymills 0:e979170e02e7 7645 if (first != ECC_BYTE) { /* normal suites */
ashleymills 0:e979170e02e7 7646 switch (second) {
ashleymills 0:e979170e02e7 7647
ashleymills 0:e979170e02e7 7648 case SSL_RSA_WITH_RC4_128_SHA :
ashleymills 0:e979170e02e7 7649 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7650 return 1;
ashleymills 0:e979170e02e7 7651 break;
ashleymills 0:e979170e02e7 7652
ashleymills 0:e979170e02e7 7653 case TLS_NTRU_RSA_WITH_RC4_128_SHA :
ashleymills 0:e979170e02e7 7654 if (requirement == REQUIRES_NTRU)
ashleymills 0:e979170e02e7 7655 return 1;
ashleymills 0:e979170e02e7 7656 break;
ashleymills 0:e979170e02e7 7657
ashleymills 0:e979170e02e7 7658 case SSL_RSA_WITH_RC4_128_MD5 :
ashleymills 0:e979170e02e7 7659 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7660 return 1;
ashleymills 0:e979170e02e7 7661 break;
ashleymills 0:e979170e02e7 7662
ashleymills 0:e979170e02e7 7663 case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
ashleymills 0:e979170e02e7 7664 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7665 return 1;
ashleymills 0:e979170e02e7 7666 break;
ashleymills 0:e979170e02e7 7667
ashleymills 0:e979170e02e7 7668 case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
ashleymills 0:e979170e02e7 7669 if (requirement == REQUIRES_NTRU)
ashleymills 0:e979170e02e7 7670 return 1;
ashleymills 0:e979170e02e7 7671 break;
ashleymills 0:e979170e02e7 7672
ashleymills 0:e979170e02e7 7673 case TLS_RSA_WITH_AES_128_CBC_SHA :
ashleymills 0:e979170e02e7 7674 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7675 return 1;
ashleymills 0:e979170e02e7 7676 break;
ashleymills 0:e979170e02e7 7677
ashleymills 0:e979170e02e7 7678 case TLS_RSA_WITH_AES_128_CBC_SHA256 :
ashleymills 0:e979170e02e7 7679 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7680 return 1;
ashleymills 0:e979170e02e7 7681 break;
ashleymills 0:e979170e02e7 7682
ashleymills 0:e979170e02e7 7683 case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
ashleymills 0:e979170e02e7 7684 if (requirement == REQUIRES_NTRU)
ashleymills 0:e979170e02e7 7685 return 1;
ashleymills 0:e979170e02e7 7686 break;
ashleymills 0:e979170e02e7 7687
ashleymills 0:e979170e02e7 7688 case TLS_RSA_WITH_AES_256_CBC_SHA :
ashleymills 0:e979170e02e7 7689 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7690 return 1;
ashleymills 0:e979170e02e7 7691 break;
ashleymills 0:e979170e02e7 7692
ashleymills 0:e979170e02e7 7693 case TLS_RSA_WITH_AES_256_CBC_SHA256 :
ashleymills 0:e979170e02e7 7694 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7695 return 1;
ashleymills 0:e979170e02e7 7696 break;
ashleymills 0:e979170e02e7 7697
ashleymills 0:e979170e02e7 7698 case TLS_RSA_WITH_NULL_SHA :
ashleymills 0:e979170e02e7 7699 case TLS_RSA_WITH_NULL_SHA256 :
ashleymills 0:e979170e02e7 7700 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7701 return 1;
ashleymills 0:e979170e02e7 7702 break;
ashleymills 0:e979170e02e7 7703
ashleymills 0:e979170e02e7 7704 case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
ashleymills 0:e979170e02e7 7705 if (requirement == REQUIRES_NTRU)
ashleymills 0:e979170e02e7 7706 return 1;
ashleymills 0:e979170e02e7 7707 break;
ashleymills 0:e979170e02e7 7708
ashleymills 0:e979170e02e7 7709 case TLS_PSK_WITH_AES_128_CBC_SHA256 :
ashleymills 0:e979170e02e7 7710 if (requirement == REQUIRES_PSK)
ashleymills 0:e979170e02e7 7711 return 1;
ashleymills 0:e979170e02e7 7712 break;
ashleymills 0:e979170e02e7 7713
ashleymills 0:e979170e02e7 7714 case TLS_PSK_WITH_AES_128_CBC_SHA :
ashleymills 0:e979170e02e7 7715 if (requirement == REQUIRES_PSK)
ashleymills 0:e979170e02e7 7716 return 1;
ashleymills 0:e979170e02e7 7717 break;
ashleymills 0:e979170e02e7 7718
ashleymills 0:e979170e02e7 7719 case TLS_PSK_WITH_AES_256_CBC_SHA :
ashleymills 0:e979170e02e7 7720 if (requirement == REQUIRES_PSK)
ashleymills 0:e979170e02e7 7721 return 1;
ashleymills 0:e979170e02e7 7722 break;
ashleymills 0:e979170e02e7 7723
ashleymills 0:e979170e02e7 7724 case TLS_PSK_WITH_NULL_SHA256 :
ashleymills 0:e979170e02e7 7725 if (requirement == REQUIRES_PSK)
ashleymills 0:e979170e02e7 7726 return 1;
ashleymills 0:e979170e02e7 7727 break;
ashleymills 0:e979170e02e7 7728
ashleymills 0:e979170e02e7 7729 case TLS_PSK_WITH_NULL_SHA :
ashleymills 0:e979170e02e7 7730 if (requirement == REQUIRES_PSK)
ashleymills 0:e979170e02e7 7731 return 1;
ashleymills 0:e979170e02e7 7732 break;
ashleymills 0:e979170e02e7 7733
ashleymills 0:e979170e02e7 7734 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
ashleymills 0:e979170e02e7 7735 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7736 return 1;
ashleymills 0:e979170e02e7 7737 if (requirement == REQUIRES_DHE)
ashleymills 0:e979170e02e7 7738 return 1;
ashleymills 0:e979170e02e7 7739 break;
ashleymills 0:e979170e02e7 7740
ashleymills 0:e979170e02e7 7741 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
ashleymills 0:e979170e02e7 7742 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7743 return 1;
ashleymills 0:e979170e02e7 7744 if (requirement == REQUIRES_DHE)
ashleymills 0:e979170e02e7 7745 return 1;
ashleymills 0:e979170e02e7 7746 break;
ashleymills 0:e979170e02e7 7747
ashleymills 0:e979170e02e7 7748 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
ashleymills 0:e979170e02e7 7749 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7750 return 1;
ashleymills 0:e979170e02e7 7751 if (requirement == REQUIRES_DHE)
ashleymills 0:e979170e02e7 7752 return 1;
ashleymills 0:e979170e02e7 7753 break;
ashleymills 0:e979170e02e7 7754
ashleymills 0:e979170e02e7 7755 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
ashleymills 0:e979170e02e7 7756 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7757 return 1;
ashleymills 0:e979170e02e7 7758 if (requirement == REQUIRES_DHE)
ashleymills 0:e979170e02e7 7759 return 1;
ashleymills 0:e979170e02e7 7760 break;
ashleymills 0:e979170e02e7 7761
ashleymills 0:e979170e02e7 7762 case TLS_RSA_WITH_HC_128_CBC_MD5 :
ashleymills 0:e979170e02e7 7763 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7764 return 1;
ashleymills 0:e979170e02e7 7765 break;
ashleymills 0:e979170e02e7 7766
ashleymills 0:e979170e02e7 7767 case TLS_RSA_WITH_HC_128_CBC_SHA :
ashleymills 0:e979170e02e7 7768 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7769 return 1;
ashleymills 0:e979170e02e7 7770 break;
ashleymills 0:e979170e02e7 7771
ashleymills 0:e979170e02e7 7772 case TLS_RSA_WITH_RABBIT_CBC_SHA :
ashleymills 0:e979170e02e7 7773 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7774 return 1;
ashleymills 0:e979170e02e7 7775 break;
ashleymills 0:e979170e02e7 7776
ashleymills 0:e979170e02e7 7777 case TLS_RSA_WITH_AES_128_GCM_SHA256 :
ashleymills 0:e979170e02e7 7778 case TLS_RSA_WITH_AES_256_GCM_SHA384 :
ashleymills 0:e979170e02e7 7779 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7780 return 1;
ashleymills 0:e979170e02e7 7781 break;
ashleymills 0:e979170e02e7 7782
ashleymills 0:e979170e02e7 7783 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
ashleymills 0:e979170e02e7 7784 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
ashleymills 0:e979170e02e7 7785 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7786 return 1;
ashleymills 0:e979170e02e7 7787 if (requirement == REQUIRES_DHE)
ashleymills 0:e979170e02e7 7788 return 1;
ashleymills 0:e979170e02e7 7789 break;
ashleymills 0:e979170e02e7 7790
ashleymills 0:e979170e02e7 7791 case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
ashleymills 0:e979170e02e7 7792 case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
ashleymills 0:e979170e02e7 7793 case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
ashleymills 0:e979170e02e7 7794 case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
ashleymills 0:e979170e02e7 7795 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7796 return 1;
ashleymills 0:e979170e02e7 7797 break;
ashleymills 0:e979170e02e7 7798
ashleymills 0:e979170e02e7 7799 case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
ashleymills 0:e979170e02e7 7800 case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
ashleymills 0:e979170e02e7 7801 case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
ashleymills 0:e979170e02e7 7802 case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
ashleymills 0:e979170e02e7 7803 if (requirement == REQUIRES_RSA)
ashleymills 0:e979170e02e7 7804 return 1;
ashleymills 0:e979170e02e7 7805 if (requirement == REQUIRES_RSA_SIG)
ashleymills 0:e979170e02e7 7806 return 1;
ashleymills 0:e979170e02e7 7807 if (requirement == REQUIRES_DHE)
ashleymills 0:e979170e02e7 7808 return 1;
ashleymills 0:e979170e02e7 7809 break;
ashleymills 0:e979170e02e7 7810
ashleymills 0:e979170e02e7 7811 default:
ashleymills 0:e979170e02e7 7812 CYASSL_MSG("Unsupported cipher suite, CipherRequires");
ashleymills 0:e979170e02e7 7813 return 0;
ashleymills 0:e979170e02e7 7814 } /* switch */
ashleymills 0:e979170e02e7 7815 } /* if ECC / Normal suites else */
ashleymills 0:e979170e02e7 7816
ashleymills 0:e979170e02e7 7817 return 0;
ashleymills 0:e979170e02e7 7818 }
ashleymills 0:e979170e02e7 7819
ashleymills 0:e979170e02e7 7820
ashleymills 0:e979170e02e7 7821
ashleymills 0:e979170e02e7 7822
ashleymills 0:e979170e02e7 7823
ashleymills 0:e979170e02e7 7824 /* Make sure cert/key are valid for this suite, true on success */
ashleymills 0:e979170e02e7 7825 static int VerifySuite(CYASSL* ssl, word16 idx)
ashleymills 0:e979170e02e7 7826 {
ashleymills 0:e979170e02e7 7827 int haveRSA = !ssl->options.haveStaticECC;
ashleymills 0:e979170e02e7 7828 int havePSK = 0;
ashleymills 0:e979170e02e7 7829 byte first;
ashleymills 0:e979170e02e7 7830 byte second;
ashleymills 0:e979170e02e7 7831
ashleymills 0:e979170e02e7 7832 CYASSL_ENTER("VerifySuite");
ashleymills 0:e979170e02e7 7833
ashleymills 0:e979170e02e7 7834 if (ssl->suites == NULL) {
ashleymills 0:e979170e02e7 7835 CYASSL_MSG("Suites pointer error");
ashleymills 0:e979170e02e7 7836 return 0;
ashleymills 0:e979170e02e7 7837 }
ashleymills 0:e979170e02e7 7838
ashleymills 0:e979170e02e7 7839 first = ssl->suites->suites[idx];
ashleymills 0:e979170e02e7 7840 second = ssl->suites->suites[idx+1];
ashleymills 0:e979170e02e7 7841
ashleymills 0:e979170e02e7 7842 #ifndef NO_PSK
ashleymills 0:e979170e02e7 7843 havePSK = ssl->options.havePSK;
ashleymills 0:e979170e02e7 7844 #endif
ashleymills 0:e979170e02e7 7845
ashleymills 0:e979170e02e7 7846 if (ssl->options.haveNTRU)
ashleymills 0:e979170e02e7 7847 haveRSA = 0;
ashleymills 0:e979170e02e7 7848
ashleymills 0:e979170e02e7 7849 if (CipherRequires(first, second, REQUIRES_RSA)) {
ashleymills 0:e979170e02e7 7850 CYASSL_MSG("Requires RSA");
ashleymills 0:e979170e02e7 7851 if (haveRSA == 0) {
ashleymills 0:e979170e02e7 7852 CYASSL_MSG("Don't have RSA");
ashleymills 0:e979170e02e7 7853 return 0;
ashleymills 0:e979170e02e7 7854 }
ashleymills 0:e979170e02e7 7855 }
ashleymills 0:e979170e02e7 7856
ashleymills 0:e979170e02e7 7857 if (CipherRequires(first, second, REQUIRES_DHE)) {
ashleymills 0:e979170e02e7 7858 CYASSL_MSG("Requires DHE");
ashleymills 0:e979170e02e7 7859 if (ssl->options.haveDH == 0) {
ashleymills 0:e979170e02e7 7860 CYASSL_MSG("Don't have DHE");
ashleymills 0:e979170e02e7 7861 return 0;
ashleymills 0:e979170e02e7 7862 }
ashleymills 0:e979170e02e7 7863 }
ashleymills 0:e979170e02e7 7864
ashleymills 0:e979170e02e7 7865 if (CipherRequires(first, second, REQUIRES_ECC_DSA)) {
ashleymills 0:e979170e02e7 7866 CYASSL_MSG("Requires ECCDSA");
ashleymills 0:e979170e02e7 7867 if (ssl->options.haveECDSAsig == 0) {
ashleymills 0:e979170e02e7 7868 CYASSL_MSG("Don't have ECCDSA");
ashleymills 0:e979170e02e7 7869 return 0;
ashleymills 0:e979170e02e7 7870 }
ashleymills 0:e979170e02e7 7871 }
ashleymills 0:e979170e02e7 7872
ashleymills 0:e979170e02e7 7873 if (CipherRequires(first, second, REQUIRES_ECC_STATIC)) {
ashleymills 0:e979170e02e7 7874 CYASSL_MSG("Requires static ECC");
ashleymills 0:e979170e02e7 7875 if (ssl->options.haveStaticECC == 0) {
ashleymills 0:e979170e02e7 7876 CYASSL_MSG("Don't have static ECC");
ashleymills 0:e979170e02e7 7877 return 0;
ashleymills 0:e979170e02e7 7878 }
ashleymills 0:e979170e02e7 7879 }
ashleymills 0:e979170e02e7 7880
ashleymills 0:e979170e02e7 7881 if (CipherRequires(first, second, REQUIRES_PSK)) {
ashleymills 0:e979170e02e7 7882 CYASSL_MSG("Requires PSK");
ashleymills 0:e979170e02e7 7883 if (havePSK == 0) {
ashleymills 0:e979170e02e7 7884 CYASSL_MSG("Don't have PSK");
ashleymills 0:e979170e02e7 7885 return 0;
ashleymills 0:e979170e02e7 7886 }
ashleymills 0:e979170e02e7 7887 }
ashleymills 0:e979170e02e7 7888
ashleymills 0:e979170e02e7 7889 if (CipherRequires(first, second, REQUIRES_NTRU)) {
ashleymills 0:e979170e02e7 7890 CYASSL_MSG("Requires NTRU");
ashleymills 0:e979170e02e7 7891 if (ssl->options.haveNTRU == 0) {
ashleymills 0:e979170e02e7 7892 CYASSL_MSG("Don't have NTRU");
ashleymills 0:e979170e02e7 7893 return 0;
ashleymills 0:e979170e02e7 7894 }
ashleymills 0:e979170e02e7 7895 }
ashleymills 0:e979170e02e7 7896
ashleymills 0:e979170e02e7 7897 if (CipherRequires(first, second, REQUIRES_RSA_SIG)) {
ashleymills 0:e979170e02e7 7898 CYASSL_MSG("Requires RSA Signature");
ashleymills 0:e979170e02e7 7899 if (ssl->options.side == SERVER_END && ssl->options.haveECDSAsig == 1) {
ashleymills 0:e979170e02e7 7900 CYASSL_MSG("Don't have RSA Signature");
ashleymills 0:e979170e02e7 7901 return 0;
ashleymills 0:e979170e02e7 7902 }
ashleymills 0:e979170e02e7 7903 }
ashleymills 0:e979170e02e7 7904
ashleymills 0:e979170e02e7 7905 /* ECCDHE is always supported if ECC on */
ashleymills 0:e979170e02e7 7906
ashleymills 0:e979170e02e7 7907 return 1;
ashleymills 0:e979170e02e7 7908 }
ashleymills 0:e979170e02e7 7909
ashleymills 0:e979170e02e7 7910
ashleymills 0:e979170e02e7 7911 static int MatchSuite(CYASSL* ssl, Suites* peerSuites)
ashleymills 0:e979170e02e7 7912 {
ashleymills 0:e979170e02e7 7913 word16 i, j;
ashleymills 0:e979170e02e7 7914
ashleymills 0:e979170e02e7 7915 CYASSL_ENTER("MatchSuite");
ashleymills 0:e979170e02e7 7916
ashleymills 0:e979170e02e7 7917 /* & 0x1 equivalent % 2 */
ashleymills 0:e979170e02e7 7918 if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1)
ashleymills 0:e979170e02e7 7919 return MATCH_SUITE_ERROR;
ashleymills 0:e979170e02e7 7920
ashleymills 0:e979170e02e7 7921 if (ssl->suites == NULL)
ashleymills 0:e979170e02e7 7922 return SUITES_ERROR;
ashleymills 0:e979170e02e7 7923
ashleymills 0:e979170e02e7 7924 /* start with best, if a match we are good */
ashleymills 0:e979170e02e7 7925 for (i = 0; i < ssl->suites->suiteSz; i += 2)
ashleymills 0:e979170e02e7 7926 for (j = 0; j < peerSuites->suiteSz; j += 2)
ashleymills 0:e979170e02e7 7927 if (ssl->suites->suites[i] == peerSuites->suites[j] &&
ashleymills 0:e979170e02e7 7928 ssl->suites->suites[i+1] == peerSuites->suites[j+1] ) {
ashleymills 0:e979170e02e7 7929
ashleymills 0:e979170e02e7 7930 if (VerifySuite(ssl, i)) {
ashleymills 0:e979170e02e7 7931 CYASSL_MSG("Verified suite validity");
ashleymills 0:e979170e02e7 7932 ssl->options.cipherSuite0 = ssl->suites->suites[i];
ashleymills 0:e979170e02e7 7933 ssl->options.cipherSuite = ssl->suites->suites[i+1];
ashleymills 0:e979170e02e7 7934 return SetCipherSpecs(ssl);
ashleymills 0:e979170e02e7 7935 }
ashleymills 0:e979170e02e7 7936 else {
ashleymills 0:e979170e02e7 7937 CYASSL_MSG("Could not verify suite validity, continue");
ashleymills 0:e979170e02e7 7938 }
ashleymills 0:e979170e02e7 7939 }
ashleymills 0:e979170e02e7 7940
ashleymills 0:e979170e02e7 7941 return MATCH_SUITE_ERROR;
ashleymills 0:e979170e02e7 7942 }
ashleymills 0:e979170e02e7 7943
ashleymills 0:e979170e02e7 7944
ashleymills 0:e979170e02e7 7945 /* process old style client hello, deprecate? */
ashleymills 0:e979170e02e7 7946 int ProcessOldClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
ashleymills 0:e979170e02e7 7947 word32 inSz, word16 sz)
ashleymills 0:e979170e02e7 7948 {
ashleymills 0:e979170e02e7 7949 word32 idx = *inOutIdx;
ashleymills 0:e979170e02e7 7950 word16 sessionSz;
ashleymills 0:e979170e02e7 7951 word16 randomSz;
ashleymills 0:e979170e02e7 7952 word16 i, j;
ashleymills 0:e979170e02e7 7953 ProtocolVersion pv;
ashleymills 0:e979170e02e7 7954 Suites clSuites;
ashleymills 0:e979170e02e7 7955
ashleymills 0:e979170e02e7 7956 (void)inSz;
ashleymills 0:e979170e02e7 7957 CYASSL_MSG("Got old format client hello");
ashleymills 0:e979170e02e7 7958 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 7959 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 7960 AddPacketName("ClientHello", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 7961 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 7962 AddLateName("ClientHello", &ssl->timeoutInfo);
ashleymills 0:e979170e02e7 7963 #endif
ashleymills 0:e979170e02e7 7964
ashleymills 0:e979170e02e7 7965 /* manually hash input since different format */
ashleymills 0:e979170e02e7 7966 #ifndef NO_MD5
ashleymills 0:e979170e02e7 7967 Md5Update(&ssl->hashMd5, input + idx, sz);
ashleymills 0:e979170e02e7 7968 #endif
ashleymills 0:e979170e02e7 7969 ShaUpdate(&ssl->hashSha, input + idx, sz);
ashleymills 0:e979170e02e7 7970 #ifndef NO_SHA256
ashleymills 0:e979170e02e7 7971 if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:e979170e02e7 7972 Sha256Update(&ssl->hashSha256, input + idx, sz);
ashleymills 0:e979170e02e7 7973 #endif
ashleymills 0:e979170e02e7 7974
ashleymills 0:e979170e02e7 7975 /* does this value mean client_hello? */
ashleymills 0:e979170e02e7 7976 idx++;
ashleymills 0:e979170e02e7 7977
ashleymills 0:e979170e02e7 7978 /* version */
ashleymills 0:e979170e02e7 7979 pv.major = input[idx++];
ashleymills 0:e979170e02e7 7980 pv.minor = input[idx++];
ashleymills 0:e979170e02e7 7981 ssl->chVersion = pv; /* store */
ashleymills 0:e979170e02e7 7982
ashleymills 0:e979170e02e7 7983 if (ssl->version.minor > pv.minor) {
ashleymills 0:e979170e02e7 7984 byte haveRSA = 0;
ashleymills 0:e979170e02e7 7985 byte havePSK = 0;
ashleymills 0:e979170e02e7 7986 if (!ssl->options.downgrade) {
ashleymills 0:e979170e02e7 7987 CYASSL_MSG("Client trying to connect with lesser version");
ashleymills 0:e979170e02e7 7988 return VERSION_ERROR;
ashleymills 0:e979170e02e7 7989 }
ashleymills 0:e979170e02e7 7990 if (pv.minor == SSLv3_MINOR) {
ashleymills 0:e979170e02e7 7991 /* turn off tls */
ashleymills 0:e979170e02e7 7992 CYASSL_MSG(" downgrading to SSLv3");
ashleymills 0:e979170e02e7 7993 ssl->options.tls = 0;
ashleymills 0:e979170e02e7 7994 ssl->options.tls1_1 = 0;
ashleymills 0:e979170e02e7 7995 ssl->version.minor = SSLv3_MINOR;
ashleymills 0:e979170e02e7 7996 }
ashleymills 0:e979170e02e7 7997 else if (pv.minor == TLSv1_MINOR) {
ashleymills 0:e979170e02e7 7998 CYASSL_MSG(" downgrading to TLSv1");
ashleymills 0:e979170e02e7 7999 /* turn off tls 1.1+ */
ashleymills 0:e979170e02e7 8000 ssl->options.tls1_1 = 0;
ashleymills 0:e979170e02e7 8001 ssl->version.minor = TLSv1_MINOR;
ashleymills 0:e979170e02e7 8002 }
ashleymills 0:e979170e02e7 8003 else if (pv.minor == TLSv1_1_MINOR) {
ashleymills 0:e979170e02e7 8004 CYASSL_MSG(" downgrading to TLSv1.1");
ashleymills 0:e979170e02e7 8005 ssl->version.minor = TLSv1_1_MINOR;
ashleymills 0:e979170e02e7 8006 }
ashleymills 0:e979170e02e7 8007 #ifndef NO_RSA
ashleymills 0:e979170e02e7 8008 haveRSA = 1;
ashleymills 0:e979170e02e7 8009 #endif
ashleymills 0:e979170e02e7 8010 #ifndef NO_PSK
ashleymills 0:e979170e02e7 8011 havePSK = ssl->options.havePSK;
ashleymills 0:e979170e02e7 8012 #endif
ashleymills 0:e979170e02e7 8013
ashleymills 0:e979170e02e7 8014 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
ashleymills 0:e979170e02e7 8015 ssl->options.haveDH, ssl->options.haveNTRU,
ashleymills 0:e979170e02e7 8016 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
ashleymills 0:e979170e02e7 8017 ssl->options.side);
ashleymills 0:e979170e02e7 8018 }
ashleymills 0:e979170e02e7 8019
ashleymills 0:e979170e02e7 8020 /* suite size */
ashleymills 0:e979170e02e7 8021 ato16(&input[idx], &clSuites.suiteSz);
ashleymills 0:e979170e02e7 8022 idx += 2;
ashleymills 0:e979170e02e7 8023
ashleymills 0:e979170e02e7 8024 if (clSuites.suiteSz > MAX_SUITE_SZ)
ashleymills 0:e979170e02e7 8025 return BUFFER_ERROR;
ashleymills 0:e979170e02e7 8026
ashleymills 0:e979170e02e7 8027 /* session size */
ashleymills 0:e979170e02e7 8028 ato16(&input[idx], &sessionSz);
ashleymills 0:e979170e02e7 8029 idx += 2;
ashleymills 0:e979170e02e7 8030
ashleymills 0:e979170e02e7 8031 if (sessionSz > ID_LEN)
ashleymills 0:e979170e02e7 8032 return BUFFER_ERROR;
ashleymills 0:e979170e02e7 8033
ashleymills 0:e979170e02e7 8034 /* random size */
ashleymills 0:e979170e02e7 8035 ato16(&input[idx], &randomSz);
ashleymills 0:e979170e02e7 8036 idx += 2;
ashleymills 0:e979170e02e7 8037
ashleymills 0:e979170e02e7 8038 if (randomSz > RAN_LEN)
ashleymills 0:e979170e02e7 8039 return BUFFER_ERROR;
ashleymills 0:e979170e02e7 8040
ashleymills 0:e979170e02e7 8041 /* suites */
ashleymills 0:e979170e02e7 8042 for (i = 0, j = 0; i < clSuites.suiteSz; i += 3) {
ashleymills 0:e979170e02e7 8043 byte first = input[idx++];
ashleymills 0:e979170e02e7 8044 if (!first) { /* implicit: skip sslv2 type */
ashleymills 0:e979170e02e7 8045 XMEMCPY(&clSuites.suites[j], &input[idx], 2);
ashleymills 0:e979170e02e7 8046 j += 2;
ashleymills 0:e979170e02e7 8047 }
ashleymills 0:e979170e02e7 8048 idx += 2;
ashleymills 0:e979170e02e7 8049 }
ashleymills 0:e979170e02e7 8050 clSuites.suiteSz = j;
ashleymills 0:e979170e02e7 8051
ashleymills 0:e979170e02e7 8052 /* session id */
ashleymills 0:e979170e02e7 8053 if (sessionSz) {
ashleymills 0:e979170e02e7 8054 XMEMCPY(ssl->arrays->sessionID, input + idx, sessionSz);
ashleymills 0:e979170e02e7 8055 idx += sessionSz;
ashleymills 0:e979170e02e7 8056 ssl->options.resuming = 1;
ashleymills 0:e979170e02e7 8057 }
ashleymills 0:e979170e02e7 8058
ashleymills 0:e979170e02e7 8059 /* random */
ashleymills 0:e979170e02e7 8060 if (randomSz < RAN_LEN)
ashleymills 0:e979170e02e7 8061 XMEMSET(ssl->arrays->clientRandom, 0, RAN_LEN - randomSz);
ashleymills 0:e979170e02e7 8062 XMEMCPY(&ssl->arrays->clientRandom[RAN_LEN - randomSz], input + idx,
ashleymills 0:e979170e02e7 8063 randomSz);
ashleymills 0:e979170e02e7 8064 idx += randomSz;
ashleymills 0:e979170e02e7 8065
ashleymills 0:e979170e02e7 8066 if (ssl->options.usingCompression)
ashleymills 0:e979170e02e7 8067 ssl->options.usingCompression = 0; /* turn off */
ashleymills 0:e979170e02e7 8068
ashleymills 0:e979170e02e7 8069 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
ashleymills 0:e979170e02e7 8070 *inOutIdx = idx;
ashleymills 0:e979170e02e7 8071
ashleymills 0:e979170e02e7 8072 ssl->options.haveSessionId = 1;
ashleymills 0:e979170e02e7 8073 /* DoClientHello uses same resume code */
ashleymills 0:e979170e02e7 8074 if (ssl->options.resuming) { /* let's try */
ashleymills 0:e979170e02e7 8075 int ret;
ashleymills 0:e979170e02e7 8076 CYASSL_SESSION* session = GetSession(ssl,ssl->arrays->masterSecret);
ashleymills 0:e979170e02e7 8077 if (!session) {
ashleymills 0:e979170e02e7 8078 CYASSL_MSG("Session lookup for resume failed");
ashleymills 0:e979170e02e7 8079 ssl->options.resuming = 0;
ashleymills 0:e979170e02e7 8080 } else {
ashleymills 0:e979170e02e7 8081 if (MatchSuite(ssl, &clSuites) < 0) {
ashleymills 0:e979170e02e7 8082 CYASSL_MSG("Unsupported cipher suite, OldClientHello");
ashleymills 0:e979170e02e7 8083 return UNSUPPORTED_SUITE;
ashleymills 0:e979170e02e7 8084 }
ashleymills 0:e979170e02e7 8085
ashleymills 0:e979170e02e7 8086 RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:e979170e02e7 8087 #ifndef NO_OLD_TLS
ashleymills 0:e979170e02e7 8088 if (ssl->options.tls)
ashleymills 0:e979170e02e7 8089 ret = DeriveTlsKeys(ssl);
ashleymills 0:e979170e02e7 8090 else
ashleymills 0:e979170e02e7 8091 ret = DeriveKeys(ssl);
ashleymills 0:e979170e02e7 8092 #else
ashleymills 0:e979170e02e7 8093 ret = DeriveTlsKeys(ssl);
ashleymills 0:e979170e02e7 8094 #endif
ashleymills 0:e979170e02e7 8095 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
ashleymills 0:e979170e02e7 8096
ashleymills 0:e979170e02e7 8097 return ret;
ashleymills 0:e979170e02e7 8098 }
ashleymills 0:e979170e02e7 8099 }
ashleymills 0:e979170e02e7 8100
ashleymills 0:e979170e02e7 8101 return MatchSuite(ssl, &clSuites);
ashleymills 0:e979170e02e7 8102 }
ashleymills 0:e979170e02e7 8103
ashleymills 0:e979170e02e7 8104
ashleymills 0:e979170e02e7 8105 static int DoClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
ashleymills 0:e979170e02e7 8106 word32 totalSz, word32 helloSz)
ashleymills 0:e979170e02e7 8107 {
ashleymills 0:e979170e02e7 8108 byte b;
ashleymills 0:e979170e02e7 8109 ProtocolVersion pv;
ashleymills 0:e979170e02e7 8110 Suites clSuites;
ashleymills 0:e979170e02e7 8111 word32 i = *inOutIdx;
ashleymills 0:e979170e02e7 8112 word32 begin = i;
ashleymills 0:e979170e02e7 8113
ashleymills 0:e979170e02e7 8114 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 8115 if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 8116 if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
ashleymills 0:e979170e02e7 8117 #endif
ashleymills 0:e979170e02e7 8118 /* make sure can read up to session */
ashleymills 0:e979170e02e7 8119 if (i + sizeof(pv) + RAN_LEN + ENUM_LEN > totalSz)
ashleymills 0:e979170e02e7 8120 return INCOMPLETE_DATA;
ashleymills 0:e979170e02e7 8121
ashleymills 0:e979170e02e7 8122 XMEMCPY(&pv, input + i, sizeof(pv));
ashleymills 0:e979170e02e7 8123 ssl->chVersion = pv; /* store */
ashleymills 0:e979170e02e7 8124 i += (word32)sizeof(pv);
ashleymills 0:e979170e02e7 8125 if (ssl->version.minor > pv.minor) {
ashleymills 0:e979170e02e7 8126 byte haveRSA = 0;
ashleymills 0:e979170e02e7 8127 byte havePSK = 0;
ashleymills 0:e979170e02e7 8128 if (!ssl->options.downgrade) {
ashleymills 0:e979170e02e7 8129 CYASSL_MSG("Client trying to connect with lesser version");
ashleymills 0:e979170e02e7 8130 return VERSION_ERROR;
ashleymills 0:e979170e02e7 8131 }
ashleymills 0:e979170e02e7 8132 if (pv.minor == SSLv3_MINOR) {
ashleymills 0:e979170e02e7 8133 /* turn off tls */
ashleymills 0:e979170e02e7 8134 CYASSL_MSG(" downgrading to SSLv3");
ashleymills 0:e979170e02e7 8135 ssl->options.tls = 0;
ashleymills 0:e979170e02e7 8136 ssl->options.tls1_1 = 0;
ashleymills 0:e979170e02e7 8137 ssl->version.minor = SSLv3_MINOR;
ashleymills 0:e979170e02e7 8138 }
ashleymills 0:e979170e02e7 8139 else if (pv.minor == TLSv1_MINOR) {
ashleymills 0:e979170e02e7 8140 /* turn off tls 1.1+ */
ashleymills 0:e979170e02e7 8141 CYASSL_MSG(" downgrading to TLSv1");
ashleymills 0:e979170e02e7 8142 ssl->options.tls1_1 = 0;
ashleymills 0:e979170e02e7 8143 ssl->version.minor = TLSv1_MINOR;
ashleymills 0:e979170e02e7 8144 }
ashleymills 0:e979170e02e7 8145 else if (pv.minor == TLSv1_1_MINOR) {
ashleymills 0:e979170e02e7 8146 CYASSL_MSG(" downgrading to TLSv1.1");
ashleymills 0:e979170e02e7 8147 ssl->version.minor = TLSv1_1_MINOR;
ashleymills 0:e979170e02e7 8148 }
ashleymills 0:e979170e02e7 8149 #ifndef NO_RSA
ashleymills 0:e979170e02e7 8150 haveRSA = 1;
ashleymills 0:e979170e02e7 8151 #endif
ashleymills 0:e979170e02e7 8152 #ifndef NO_PSK
ashleymills 0:e979170e02e7 8153 havePSK = ssl->options.havePSK;
ashleymills 0:e979170e02e7 8154 #endif
ashleymills 0:e979170e02e7 8155 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
ashleymills 0:e979170e02e7 8156 ssl->options.haveDH, ssl->options.haveNTRU,
ashleymills 0:e979170e02e7 8157 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
ashleymills 0:e979170e02e7 8158 ssl->options.side);
ashleymills 0:e979170e02e7 8159 }
ashleymills 0:e979170e02e7 8160 /* random */
ashleymills 0:e979170e02e7 8161 XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
ashleymills 0:e979170e02e7 8162 i += RAN_LEN;
ashleymills 0:e979170e02e7 8163
ashleymills 0:e979170e02e7 8164 #ifdef SHOW_SECRETS
ashleymills 0:e979170e02e7 8165 {
ashleymills 0:e979170e02e7 8166 int j;
ashleymills 0:e979170e02e7 8167 printf("client random: ");
ashleymills 0:e979170e02e7 8168 for (j = 0; j < RAN_LEN; j++)
ashleymills 0:e979170e02e7 8169 printf("%02x", ssl->arrays->clientRandom[j]);
ashleymills 0:e979170e02e7 8170 printf("\n");
ashleymills 0:e979170e02e7 8171 }
ashleymills 0:e979170e02e7 8172 #endif
ashleymills 0:e979170e02e7 8173 /* session id */
ashleymills 0:e979170e02e7 8174 b = input[i++];
ashleymills 0:e979170e02e7 8175 if (b) {
ashleymills 0:e979170e02e7 8176 if (i + ID_LEN > totalSz)
ashleymills 0:e979170e02e7 8177 return INCOMPLETE_DATA;
ashleymills 0:e979170e02e7 8178 XMEMCPY(ssl->arrays->sessionID, input + i, ID_LEN);
ashleymills 0:e979170e02e7 8179 i += b;
ashleymills 0:e979170e02e7 8180 ssl->options.resuming= 1; /* client wants to resume */
ashleymills 0:e979170e02e7 8181 CYASSL_MSG("Client wants to resume session");
ashleymills 0:e979170e02e7 8182 }
ashleymills 0:e979170e02e7 8183
ashleymills 0:e979170e02e7 8184 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 8185 /* cookie */
ashleymills 0:e979170e02e7 8186 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 8187 b = input[i++];
ashleymills 0:e979170e02e7 8188 if (b) {
ashleymills 0:e979170e02e7 8189 byte cookie[MAX_COOKIE_LEN];
ashleymills 0:e979170e02e7 8190
ashleymills 0:e979170e02e7 8191 if (b > MAX_COOKIE_LEN)
ashleymills 0:e979170e02e7 8192 return BUFFER_ERROR;
ashleymills 0:e979170e02e7 8193 if (i + b > totalSz)
ashleymills 0:e979170e02e7 8194 return INCOMPLETE_DATA;
ashleymills 0:e979170e02e7 8195 if ((EmbedGenerateCookie(cookie, COOKIE_SZ, ssl)
ashleymills 0:e979170e02e7 8196 != COOKIE_SZ)
ashleymills 0:e979170e02e7 8197 || (b != COOKIE_SZ)
ashleymills 0:e979170e02e7 8198 || (XMEMCMP(cookie, input + i, b) != 0)) {
ashleymills 0:e979170e02e7 8199 return COOKIE_ERROR;
ashleymills 0:e979170e02e7 8200 }
ashleymills 0:e979170e02e7 8201 i += b;
ashleymills 0:e979170e02e7 8202 }
ashleymills 0:e979170e02e7 8203 }
ashleymills 0:e979170e02e7 8204 #endif
ashleymills 0:e979170e02e7 8205
ashleymills 0:e979170e02e7 8206 if (i + LENGTH_SZ > totalSz)
ashleymills 0:e979170e02e7 8207 return INCOMPLETE_DATA;
ashleymills 0:e979170e02e7 8208 /* suites */
ashleymills 0:e979170e02e7 8209 ato16(&input[i], &clSuites.suiteSz);
ashleymills 0:e979170e02e7 8210 i += 2;
ashleymills 0:e979170e02e7 8211
ashleymills 0:e979170e02e7 8212 /* suites and comp len */
ashleymills 0:e979170e02e7 8213 if (i + clSuites.suiteSz + ENUM_LEN > totalSz)
ashleymills 0:e979170e02e7 8214 return INCOMPLETE_DATA;
ashleymills 0:e979170e02e7 8215 if (clSuites.suiteSz > MAX_SUITE_SZ)
ashleymills 0:e979170e02e7 8216 return BUFFER_ERROR;
ashleymills 0:e979170e02e7 8217 XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
ashleymills 0:e979170e02e7 8218 i += clSuites.suiteSz;
ashleymills 0:e979170e02e7 8219
ashleymills 0:e979170e02e7 8220 b = input[i++]; /* comp len */
ashleymills 0:e979170e02e7 8221 if (i + b > totalSz)
ashleymills 0:e979170e02e7 8222 return INCOMPLETE_DATA;
ashleymills 0:e979170e02e7 8223
ashleymills 0:e979170e02e7 8224 if (ssl->options.usingCompression) {
ashleymills 0:e979170e02e7 8225 int match = 0;
ashleymills 0:e979170e02e7 8226 while (b--) {
ashleymills 0:e979170e02e7 8227 byte comp = input[i++];
ashleymills 0:e979170e02e7 8228 if (comp == ZLIB_COMPRESSION)
ashleymills 0:e979170e02e7 8229 match = 1;
ashleymills 0:e979170e02e7 8230 }
ashleymills 0:e979170e02e7 8231 if (!match) {
ashleymills 0:e979170e02e7 8232 CYASSL_MSG("Not matching compression, turning off");
ashleymills 0:e979170e02e7 8233 ssl->options.usingCompression = 0; /* turn off */
ashleymills 0:e979170e02e7 8234 }
ashleymills 0:e979170e02e7 8235 }
ashleymills 0:e979170e02e7 8236 else
ashleymills 0:e979170e02e7 8237 i += b; /* ignore, since we're not on */
ashleymills 0:e979170e02e7 8238
ashleymills 0:e979170e02e7 8239 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
ashleymills 0:e979170e02e7 8240
ashleymills 0:e979170e02e7 8241 *inOutIdx = i;
ashleymills 0:e979170e02e7 8242 if ( (i - begin) < helloSz)
ashleymills 0:e979170e02e7 8243 *inOutIdx = begin + helloSz; /* skip extensions */
ashleymills 0:e979170e02e7 8244
ashleymills 0:e979170e02e7 8245 ssl->options.haveSessionId = 1;
ashleymills 0:e979170e02e7 8246 /* ProcessOld uses same resume code */
ashleymills 0:e979170e02e7 8247 if (ssl->options.resuming) { /* let's try */
ashleymills 0:e979170e02e7 8248 int ret;
ashleymills 0:e979170e02e7 8249 CYASSL_SESSION* session = GetSession(ssl,ssl->arrays->masterSecret);
ashleymills 0:e979170e02e7 8250 if (!session) {
ashleymills 0:e979170e02e7 8251 CYASSL_MSG("Session lookup for resume failed");
ashleymills 0:e979170e02e7 8252 ssl->options.resuming = 0;
ashleymills 0:e979170e02e7 8253 } else {
ashleymills 0:e979170e02e7 8254 if (MatchSuite(ssl, &clSuites) < 0) {
ashleymills 0:e979170e02e7 8255 CYASSL_MSG("Unsupported cipher suite, ClientHello");
ashleymills 0:e979170e02e7 8256 return UNSUPPORTED_SUITE;
ashleymills 0:e979170e02e7 8257 }
ashleymills 0:e979170e02e7 8258
ashleymills 0:e979170e02e7 8259 RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:e979170e02e7 8260 #ifndef NO_OLD_TLS
ashleymills 0:e979170e02e7 8261 if (ssl->options.tls)
ashleymills 0:e979170e02e7 8262 ret = DeriveTlsKeys(ssl);
ashleymills 0:e979170e02e7 8263 else
ashleymills 0:e979170e02e7 8264 ret = DeriveKeys(ssl);
ashleymills 0:e979170e02e7 8265 #else
ashleymills 0:e979170e02e7 8266 ret = DeriveTlsKeys(ssl);
ashleymills 0:e979170e02e7 8267 #endif
ashleymills 0:e979170e02e7 8268 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
ashleymills 0:e979170e02e7 8269
ashleymills 0:e979170e02e7 8270 return ret;
ashleymills 0:e979170e02e7 8271 }
ashleymills 0:e979170e02e7 8272 }
ashleymills 0:e979170e02e7 8273 return MatchSuite(ssl, &clSuites);
ashleymills 0:e979170e02e7 8274 }
ashleymills 0:e979170e02e7 8275
ashleymills 0:e979170e02e7 8276 #if !defined(NO_RSA) || defined(HAVE_ECC)
ashleymills 0:e979170e02e7 8277 static int DoCertificateVerify(CYASSL* ssl, byte* input, word32* inOutsz,
ashleymills 0:e979170e02e7 8278 word32 totalSz)
ashleymills 0:e979170e02e7 8279 {
ashleymills 0:e979170e02e7 8280 word16 sz = 0;
ashleymills 0:e979170e02e7 8281 word32 i = *inOutsz;
ashleymills 0:e979170e02e7 8282 int ret = VERIFY_CERT_ERROR; /* start in error state */
ashleymills 0:e979170e02e7 8283 byte* sig;
ashleymills 0:e979170e02e7 8284 byte* out;
ashleymills 0:e979170e02e7 8285 int outLen;
ashleymills 0:e979170e02e7 8286
ashleymills 0:e979170e02e7 8287 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 8288 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 8289 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 8290 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 8291 AddLateName("CertificateVerify", &ssl->timeoutInfo);
ashleymills 0:e979170e02e7 8292 #endif
ashleymills 0:e979170e02e7 8293 if ( (i + VERIFY_HEADER) > totalSz)
ashleymills 0:e979170e02e7 8294 return INCOMPLETE_DATA;
ashleymills 0:e979170e02e7 8295
ashleymills 0:e979170e02e7 8296 if (IsAtLeastTLSv1_2(ssl))
ashleymills 0:e979170e02e7 8297 i += HASH_SIG_SIZE;
ashleymills 0:e979170e02e7 8298 ato16(&input[i], &sz);
ashleymills 0:e979170e02e7 8299 i += VERIFY_HEADER;
ashleymills 0:e979170e02e7 8300
ashleymills 0:e979170e02e7 8301 if ( (i + sz) > totalSz)
ashleymills 0:e979170e02e7 8302 return INCOMPLETE_DATA;
ashleymills 0:e979170e02e7 8303
ashleymills 0:e979170e02e7 8304 if (sz > ENCRYPT_LEN)
ashleymills 0:e979170e02e7 8305 return BUFFER_ERROR;
ashleymills 0:e979170e02e7 8306
ashleymills 0:e979170e02e7 8307 sig = &input[i];
ashleymills 0:e979170e02e7 8308 *inOutsz = i + sz;
ashleymills 0:e979170e02e7 8309
ashleymills 0:e979170e02e7 8310 /* RSA */
ashleymills 0:e979170e02e7 8311 #ifndef NO_RSA
ashleymills 0:e979170e02e7 8312 if (ssl->peerRsaKeyPresent != 0) {
ashleymills 0:e979170e02e7 8313 CYASSL_MSG("Doing RSA peer cert verify");
ashleymills 0:e979170e02e7 8314
ashleymills 0:e979170e02e7 8315 outLen = RsaSSL_VerifyInline(sig, sz, &out, ssl->peerRsaKey);
ashleymills 0:e979170e02e7 8316
ashleymills 0:e979170e02e7 8317 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:e979170e02e7 8318 byte encodedSig[MAX_ENCODED_SIG_SZ];
ashleymills 0:e979170e02e7 8319 word32 sigSz;
ashleymills 0:e979170e02e7 8320 byte* digest;
ashleymills 0:e979170e02e7 8321 int typeH;
ashleymills 0:e979170e02e7 8322 int digestSz;
ashleymills 0:e979170e02e7 8323
ashleymills 0:e979170e02e7 8324 /* sha1 for now */
ashleymills 0:e979170e02e7 8325 digest = ssl->certHashes.sha;
ashleymills 0:e979170e02e7 8326 typeH = SHAh;
ashleymills 0:e979170e02e7 8327 digestSz = SHA_DIGEST_SIZE;
ashleymills 0:e979170e02e7 8328
ashleymills 0:e979170e02e7 8329 sigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
ashleymills 0:e979170e02e7 8330
ashleymills 0:e979170e02e7 8331 if (outLen == (int)sigSz && XMEMCMP(out, encodedSig,
ashleymills 0:e979170e02e7 8332 min(sigSz, MAX_ENCODED_SIG_SZ)) == 0)
ashleymills 0:e979170e02e7 8333 ret = 0; /* verified */
ashleymills 0:e979170e02e7 8334 }
ashleymills 0:e979170e02e7 8335 else {
ashleymills 0:e979170e02e7 8336 if (outLen == sizeof(ssl->certHashes) && XMEMCMP(out,
ashleymills 0:e979170e02e7 8337 &ssl->certHashes, sizeof(ssl->certHashes)) == 0)
ashleymills 0:e979170e02e7 8338 ret = 0; /* verified */
ashleymills 0:e979170e02e7 8339 }
ashleymills 0:e979170e02e7 8340 }
ashleymills 0:e979170e02e7 8341 #endif
ashleymills 0:e979170e02e7 8342 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 8343 if (ssl->peerEccDsaKeyPresent) {
ashleymills 0:e979170e02e7 8344 int verify = 0;
ashleymills 0:e979170e02e7 8345 int err = -1;
ashleymills 0:e979170e02e7 8346
ashleymills 0:e979170e02e7 8347 CYASSL_MSG("Doing ECC peer cert verify");
ashleymills 0:e979170e02e7 8348
ashleymills 0:e979170e02e7 8349 err = ecc_verify_hash(sig, sz, ssl->certHashes.sha, SHA_DIGEST_SIZE,
ashleymills 0:e979170e02e7 8350 &verify, ssl->peerEccDsaKey);
ashleymills 0:e979170e02e7 8351
ashleymills 0:e979170e02e7 8352 if (err == 0 && verify == 1)
ashleymills 0:e979170e02e7 8353 ret = 0; /* verified */
ashleymills 0:e979170e02e7 8354 }
ashleymills 0:e979170e02e7 8355 #endif
ashleymills 0:e979170e02e7 8356 return ret;
ashleymills 0:e979170e02e7 8357 }
ashleymills 0:e979170e02e7 8358 #endif /* !NO_RSA || HAVE_ECC */
ashleymills 0:e979170e02e7 8359
ashleymills 0:e979170e02e7 8360 int SendServerHelloDone(CYASSL* ssl)
ashleymills 0:e979170e02e7 8361 {
ashleymills 0:e979170e02e7 8362 byte *output;
ashleymills 0:e979170e02e7 8363 int sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 8364 int ret;
ashleymills 0:e979170e02e7 8365
ashleymills 0:e979170e02e7 8366 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 8367 if (ssl->options.dtls)
ashleymills 0:e979170e02e7 8368 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
ashleymills 0:e979170e02e7 8369 #endif
ashleymills 0:e979170e02e7 8370 /* check for avalaible size */
ashleymills 0:e979170e02e7 8371 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
ashleymills 0:e979170e02e7 8372 return ret;
ashleymills 0:e979170e02e7 8373
ashleymills 0:e979170e02e7 8374 /* get ouput buffer */
ashleymills 0:e979170e02e7 8375 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 8376 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 8377
ashleymills 0:e979170e02e7 8378 AddHeaders(output, 0, server_hello_done, ssl);
ashleymills 0:e979170e02e7 8379
ashleymills 0:e979170e02e7 8380 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 8381 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 8382 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
ashleymills 0:e979170e02e7 8383 return 0;
ashleymills 0:e979170e02e7 8384 }
ashleymills 0:e979170e02e7 8385 #endif
ashleymills 0:e979170e02e7 8386 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:e979170e02e7 8387 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 8388 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 8389 AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 8390 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 8391 AddPacketInfo("ServerHelloDone", &ssl->timeoutInfo, output, sendSz,
ashleymills 0:e979170e02e7 8392 ssl->heap);
ashleymills 0:e979170e02e7 8393 #endif
ashleymills 0:e979170e02e7 8394 ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
ashleymills 0:e979170e02e7 8395
ashleymills 0:e979170e02e7 8396 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:e979170e02e7 8397
ashleymills 0:e979170e02e7 8398 return SendBuffered(ssl);
ashleymills 0:e979170e02e7 8399 }
ashleymills 0:e979170e02e7 8400
ashleymills 0:e979170e02e7 8401 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 8402 int SendHelloVerifyRequest(CYASSL* ssl)
ashleymills 0:e979170e02e7 8403 {
ashleymills 0:e979170e02e7 8404 byte* output;
ashleymills 0:e979170e02e7 8405 byte cookieSz = COOKIE_SZ;
ashleymills 0:e979170e02e7 8406 int length = VERSION_SZ + ENUM_LEN + cookieSz;
ashleymills 0:e979170e02e7 8407 int idx = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
ashleymills 0:e979170e02e7 8408 int sendSz = length + idx;
ashleymills 0:e979170e02e7 8409 int ret;
ashleymills 0:e979170e02e7 8410
ashleymills 0:e979170e02e7 8411 /* check for avalaible size */
ashleymills 0:e979170e02e7 8412 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
ashleymills 0:e979170e02e7 8413 return ret;
ashleymills 0:e979170e02e7 8414
ashleymills 0:e979170e02e7 8415 /* get ouput buffer */
ashleymills 0:e979170e02e7 8416 output = ssl->buffers.outputBuffer.buffer +
ashleymills 0:e979170e02e7 8417 ssl->buffers.outputBuffer.length;
ashleymills 0:e979170e02e7 8418
ashleymills 0:e979170e02e7 8419 AddHeaders(output, length, hello_verify_request, ssl);
ashleymills 0:e979170e02e7 8420
ashleymills 0:e979170e02e7 8421 output[idx++] = ssl->chVersion.major;
ashleymills 0:e979170e02e7 8422 output[idx++] = ssl->chVersion.minor;
ashleymills 0:e979170e02e7 8423
ashleymills 0:e979170e02e7 8424 output[idx++] = cookieSz;
ashleymills 0:e979170e02e7 8425 if ((ret = EmbedGenerateCookie(output + idx, cookieSz, ssl)) < 0)
ashleymills 0:e979170e02e7 8426 return ret;
ashleymills 0:e979170e02e7 8427
ashleymills 0:e979170e02e7 8428 HashOutput(ssl, output, sendSz, 0);
ashleymills 0:e979170e02e7 8429 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 8430 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 8431 AddPacketName("HelloVerifyRequest", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 8432 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 8433 AddPacketInfo("HelloVerifyRequest", &ssl->timeoutInfo, output,
ashleymills 0:e979170e02e7 8434 sendSz, ssl->heap);
ashleymills 0:e979170e02e7 8435 #endif
ashleymills 0:e979170e02e7 8436 ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
ashleymills 0:e979170e02e7 8437
ashleymills 0:e979170e02e7 8438 ssl->buffers.outputBuffer.length += sendSz;
ashleymills 0:e979170e02e7 8439
ashleymills 0:e979170e02e7 8440 return SendBuffered(ssl);
ashleymills 0:e979170e02e7 8441 }
ashleymills 0:e979170e02e7 8442 #endif
ashleymills 0:e979170e02e7 8443
ashleymills 0:e979170e02e7 8444 static int DoClientKeyExchange(CYASSL* ssl, byte* input,
ashleymills 0:e979170e02e7 8445 word32* inOutIdx, word32 totalSz)
ashleymills 0:e979170e02e7 8446 {
ashleymills 0:e979170e02e7 8447 int ret = 0;
ashleymills 0:e979170e02e7 8448 word32 length = 0;
ashleymills 0:e979170e02e7 8449 byte* out = NULL;
ashleymills 0:e979170e02e7 8450
ashleymills 0:e979170e02e7 8451 (void)length; /* shut up compiler warnings */
ashleymills 0:e979170e02e7 8452 (void)out;
ashleymills 0:e979170e02e7 8453 (void)input;
ashleymills 0:e979170e02e7 8454 (void)inOutIdx;
ashleymills 0:e979170e02e7 8455 (void)totalSz;
ashleymills 0:e979170e02e7 8456
ashleymills 0:e979170e02e7 8457 if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
ashleymills 0:e979170e02e7 8458 CYASSL_MSG("Client sending keyexchange at wrong time");
ashleymills 0:e979170e02e7 8459 SendAlert(ssl, alert_fatal, unexpected_message);
ashleymills 0:e979170e02e7 8460 return OUT_OF_ORDER_E;
ashleymills 0:e979170e02e7 8461 }
ashleymills 0:e979170e02e7 8462
ashleymills 0:e979170e02e7 8463 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 8464 if (ssl->options.verifyPeer && ssl->options.failNoCert)
ashleymills 0:e979170e02e7 8465 if (!ssl->options.havePeerCert) {
ashleymills 0:e979170e02e7 8466 CYASSL_MSG("client didn't present peer cert");
ashleymills 0:e979170e02e7 8467 return NO_PEER_CERT;
ashleymills 0:e979170e02e7 8468 }
ashleymills 0:e979170e02e7 8469 #endif
ashleymills 0:e979170e02e7 8470
ashleymills 0:e979170e02e7 8471 #ifdef CYASSL_CALLBACKS
ashleymills 0:e979170e02e7 8472 if (ssl->hsInfoOn)
ashleymills 0:e979170e02e7 8473 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
ashleymills 0:e979170e02e7 8474 if (ssl->toInfoOn)
ashleymills 0:e979170e02e7 8475 AddLateName("ClientKeyExchange", &ssl->timeoutInfo);
ashleymills 0:e979170e02e7 8476 #endif
ashleymills 0:e979170e02e7 8477
ashleymills 0:e979170e02e7 8478 switch (ssl->specs.kea) {
ashleymills 0:e979170e02e7 8479 #ifndef NO_RSA
ashleymills 0:e979170e02e7 8480 case rsa_kea:
ashleymills 0:e979170e02e7 8481 {
ashleymills 0:e979170e02e7 8482 word32 idx = 0;
ashleymills 0:e979170e02e7 8483 RsaKey key;
ashleymills 0:e979170e02e7 8484 byte* tmp = 0;
ashleymills 0:e979170e02e7 8485
ashleymills 0:e979170e02e7 8486 InitRsaKey(&key, ssl->heap);
ashleymills 0:e979170e02e7 8487
ashleymills 0:e979170e02e7 8488 if (ssl->buffers.key.buffer)
ashleymills 0:e979170e02e7 8489 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx,
ashleymills 0:e979170e02e7 8490 &key, ssl->buffers.key.length);
ashleymills 0:e979170e02e7 8491 else
ashleymills 0:e979170e02e7 8492 return NO_PRIVATE_KEY;
ashleymills 0:e979170e02e7 8493
ashleymills 0:e979170e02e7 8494 if (ret == 0) {
ashleymills 0:e979170e02e7 8495 length = RsaEncryptSize(&key);
ashleymills 0:e979170e02e7 8496 ssl->arrays->preMasterSz = SECRET_LEN;
ashleymills 0:e979170e02e7 8497
ashleymills 0:e979170e02e7 8498 if (ssl->options.tls) {
ashleymills 0:e979170e02e7 8499 word16 check;
ashleymills 0:e979170e02e7 8500 ato16(input + *inOutIdx, &check);
ashleymills 0:e979170e02e7 8501 if ((word32)check != length) {
ashleymills 0:e979170e02e7 8502 CYASSL_MSG("RSA explicit size doesn't match");
ashleymills 0:e979170e02e7 8503 FreeRsaKey(&key);
ashleymills 0:e979170e02e7 8504 return RSA_PRIVATE_ERROR;
ashleymills 0:e979170e02e7 8505 }
ashleymills 0:e979170e02e7 8506 (*inOutIdx) += 2;
ashleymills 0:e979170e02e7 8507 }
ashleymills 0:e979170e02e7 8508 tmp = input + *inOutIdx;
ashleymills 0:e979170e02e7 8509 *inOutIdx += length;
ashleymills 0:e979170e02e7 8510
ashleymills 0:e979170e02e7 8511 if (*inOutIdx > totalSz) {
ashleymills 0:e979170e02e7 8512 CYASSL_MSG("RSA message too big");
ashleymills 0:e979170e02e7 8513 FreeRsaKey(&key);
ashleymills 0:e979170e02e7 8514 return INCOMPLETE_DATA;
ashleymills 0:e979170e02e7 8515 }
ashleymills 0:e979170e02e7 8516
ashleymills 0:e979170e02e7 8517 if (RsaPrivateDecryptInline(tmp, length, &out, &key) ==
ashleymills 0:e979170e02e7 8518 SECRET_LEN) {
ashleymills 0:e979170e02e7 8519 XMEMCPY(ssl->arrays->preMasterSecret, out, SECRET_LEN);
ashleymills 0:e979170e02e7 8520 if (ssl->arrays->preMasterSecret[0] !=
ashleymills 0:e979170e02e7 8521 ssl->chVersion.major
ashleymills 0:e979170e02e7 8522 || ssl->arrays->preMasterSecret[1] !=
ashleymills 0:e979170e02e7 8523 ssl->chVersion.minor)
ashleymills 0:e979170e02e7 8524 ret = PMS_VERSION_ERROR;
ashleymills 0:e979170e02e7 8525 else
ashleymills 0:e979170e02e7 8526 ret = MakeMasterSecret(ssl);
ashleymills 0:e979170e02e7 8527 }
ashleymills 0:e979170e02e7 8528 else
ashleymills 0:e979170e02e7 8529 ret = RSA_PRIVATE_ERROR;
ashleymills 0:e979170e02e7 8530 }
ashleymills 0:e979170e02e7 8531
ashleymills 0:e979170e02e7 8532 FreeRsaKey(&key);
ashleymills 0:e979170e02e7 8533 }
ashleymills 0:e979170e02e7 8534 break;
ashleymills 0:e979170e02e7 8535 #endif
ashleymills 0:e979170e02e7 8536 #ifndef NO_PSK
ashleymills 0:e979170e02e7 8537 case psk_kea:
ashleymills 0:e979170e02e7 8538 {
ashleymills 0:e979170e02e7 8539 byte* pms = ssl->arrays->preMasterSecret;
ashleymills 0:e979170e02e7 8540 word16 ci_sz;
ashleymills 0:e979170e02e7 8541
ashleymills 0:e979170e02e7 8542 ato16(&input[*inOutIdx], &ci_sz);
ashleymills 0:e979170e02e7 8543 *inOutIdx += LENGTH_SZ;
ashleymills 0:e979170e02e7 8544 if (ci_sz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR;
ashleymills 0:e979170e02e7 8545
ashleymills 0:e979170e02e7 8546 XMEMCPY(ssl->arrays->client_identity, &input[*inOutIdx], ci_sz);
ashleymills 0:e979170e02e7 8547 *inOutIdx += ci_sz;
ashleymills 0:e979170e02e7 8548 ssl->arrays->client_identity[ci_sz] = 0;
ashleymills 0:e979170e02e7 8549
ashleymills 0:e979170e02e7 8550 ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
ashleymills 0:e979170e02e7 8551 ssl->arrays->client_identity, ssl->arrays->psk_key,
ashleymills 0:e979170e02e7 8552 MAX_PSK_KEY_LEN);
ashleymills 0:e979170e02e7 8553 if (ssl->arrays->psk_keySz == 0 ||
ashleymills 0:e979170e02e7 8554 ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
ashleymills 0:e979170e02e7 8555 return PSK_KEY_ERROR;
ashleymills 0:e979170e02e7 8556
ashleymills 0:e979170e02e7 8557 /* make psk pre master secret */
ashleymills 0:e979170e02e7 8558 /* length of key + length 0s + length of key + key */
ashleymills 0:e979170e02e7 8559 c16toa((word16)ssl->arrays->psk_keySz, pms);
ashleymills 0:e979170e02e7 8560 pms += 2;
ashleymills 0:e979170e02e7 8561 XMEMSET(pms, 0, ssl->arrays->psk_keySz);
ashleymills 0:e979170e02e7 8562 pms += ssl->arrays->psk_keySz;
ashleymills 0:e979170e02e7 8563 c16toa((word16)ssl->arrays->psk_keySz, pms);
ashleymills 0:e979170e02e7 8564 pms += 2;
ashleymills 0:e979170e02e7 8565 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
ashleymills 0:e979170e02e7 8566 ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
ashleymills 0:e979170e02e7 8567
ashleymills 0:e979170e02e7 8568 ret = MakeMasterSecret(ssl);
ashleymills 0:e979170e02e7 8569 }
ashleymills 0:e979170e02e7 8570 break;
ashleymills 0:e979170e02e7 8571 #endif /* NO_PSK */
ashleymills 0:e979170e02e7 8572 #ifdef HAVE_NTRU
ashleymills 0:e979170e02e7 8573 case ntru_kea:
ashleymills 0:e979170e02e7 8574 {
ashleymills 0:e979170e02e7 8575 word32 rc;
ashleymills 0:e979170e02e7 8576 word16 cipherLen;
ashleymills 0:e979170e02e7 8577 word16 plainLen = sizeof(ssl->arrays->preMasterSecret);
ashleymills 0:e979170e02e7 8578 byte* tmp;
ashleymills 0:e979170e02e7 8579
ashleymills 0:e979170e02e7 8580 if (!ssl->buffers.key.buffer)
ashleymills 0:e979170e02e7 8581 return NO_PRIVATE_KEY;
ashleymills 0:e979170e02e7 8582
ashleymills 0:e979170e02e7 8583 ato16(&input[*inOutIdx], &cipherLen);
ashleymills 0:e979170e02e7 8584 *inOutIdx += LENGTH_SZ;
ashleymills 0:e979170e02e7 8585 if (cipherLen > MAX_NTRU_ENCRYPT_SZ)
ashleymills 0:e979170e02e7 8586 return NTRU_KEY_ERROR;
ashleymills 0:e979170e02e7 8587
ashleymills 0:e979170e02e7 8588 tmp = input + *inOutIdx;
ashleymills 0:e979170e02e7 8589 rc = crypto_ntru_decrypt((word16)ssl->buffers.key.length,
ashleymills 0:e979170e02e7 8590 ssl->buffers.key.buffer, cipherLen, tmp, &plainLen,
ashleymills 0:e979170e02e7 8591 ssl->arrays->preMasterSecret);
ashleymills 0:e979170e02e7 8592
ashleymills 0:e979170e02e7 8593 if (rc != NTRU_OK || plainLen != SECRET_LEN)
ashleymills 0:e979170e02e7 8594 return NTRU_DECRYPT_ERROR;
ashleymills 0:e979170e02e7 8595 *inOutIdx += cipherLen;
ashleymills 0:e979170e02e7 8596
ashleymills 0:e979170e02e7 8597 ssl->arrays->preMasterSz = plainLen;
ashleymills 0:e979170e02e7 8598 ret = MakeMasterSecret(ssl);
ashleymills 0:e979170e02e7 8599 }
ashleymills 0:e979170e02e7 8600 break;
ashleymills 0:e979170e02e7 8601 #endif /* HAVE_NTRU */
ashleymills 0:e979170e02e7 8602 #ifdef HAVE_ECC
ashleymills 0:e979170e02e7 8603 case ecc_diffie_hellman_kea:
ashleymills 0:e979170e02e7 8604 {
ashleymills 0:e979170e02e7 8605 word32 size;
ashleymills 0:e979170e02e7 8606 word32 bLength = input[*inOutIdx]; /* one byte length */
ashleymills 0:e979170e02e7 8607 *inOutIdx += 1;
ashleymills 0:e979170e02e7 8608
ashleymills 0:e979170e02e7 8609 ret = ecc_import_x963(&input[*inOutIdx],
ashleymills 0:e979170e02e7 8610 bLength, ssl->peerEccKey);
ashleymills 0:e979170e02e7 8611 if (ret != 0)
ashleymills 0:e979170e02e7 8612 return ECC_PEERKEY_ERROR;
ashleymills 0:e979170e02e7 8613 *inOutIdx += bLength;
ashleymills 0:e979170e02e7 8614 ssl->peerEccKeyPresent = 1;
ashleymills 0:e979170e02e7 8615
ashleymills 0:e979170e02e7 8616 size = sizeof(ssl->arrays->preMasterSecret);
ashleymills 0:e979170e02e7 8617 if (ssl->specs.static_ecdh) {
ashleymills 0:e979170e02e7 8618 ecc_key staticKey;
ashleymills 0:e979170e02e7 8619 word32 i = 0;
ashleymills 0:e979170e02e7 8620
ashleymills 0:e979170e02e7 8621 ecc_init(&staticKey);
ashleymills 0:e979170e02e7 8622 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
ashleymills 0:e979170e02e7 8623 &staticKey, ssl->buffers.key.length);
ashleymills 0:e979170e02e7 8624 if (ret == 0)
ashleymills 0:e979170e02e7 8625 ret = ecc_shared_secret(&staticKey, ssl->peerEccKey,
ashleymills 0:e979170e02e7 8626 ssl->arrays->preMasterSecret, &size);
ashleymills 0:e979170e02e7 8627 ecc_free(&staticKey);
ashleymills 0:e979170e02e7 8628 }
ashleymills 0:e979170e02e7 8629 else
ashleymills 0:e979170e02e7 8630 ret = ecc_shared_secret(ssl->eccTempKey, ssl->peerEccKey,
ashleymills 0:e979170e02e7 8631 ssl->arrays->preMasterSecret, &size);
ashleymills 0:e979170e02e7 8632 if (ret != 0)
ashleymills 0:e979170e02e7 8633 return ECC_SHARED_ERROR;
ashleymills 0:e979170e02e7 8634 ssl->arrays->preMasterSz = size;
ashleymills 0:e979170e02e7 8635 ret = MakeMasterSecret(ssl);
ashleymills 0:e979170e02e7 8636 }
ashleymills 0:e979170e02e7 8637 break;
ashleymills 0:e979170e02e7 8638 #endif /* HAVE_ECC */
ashleymills 0:e979170e02e7 8639 #ifdef OPENSSL_EXTRA
ashleymills 0:e979170e02e7 8640 case diffie_hellman_kea:
ashleymills 0:e979170e02e7 8641 {
ashleymills 0:e979170e02e7 8642 byte* clientPub;
ashleymills 0:e979170e02e7 8643 word16 clientPubSz;
ashleymills 0:e979170e02e7 8644 DhKey dhKey;
ashleymills 0:e979170e02e7 8645
ashleymills 0:e979170e02e7 8646 ato16(&input[*inOutIdx], &clientPubSz);
ashleymills 0:e979170e02e7 8647 *inOutIdx += LENGTH_SZ;
ashleymills 0:e979170e02e7 8648
ashleymills 0:e979170e02e7 8649 clientPub = &input[*inOutIdx];
ashleymills 0:e979170e02e7 8650 *inOutIdx += clientPubSz;
ashleymills 0:e979170e02e7 8651
ashleymills 0:e979170e02e7 8652 InitDhKey(&dhKey);
ashleymills 0:e979170e02e7 8653 ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
ashleymills 0:e979170e02e7 8654 ssl->buffers.serverDH_P.length,
ashleymills 0:e979170e02e7 8655 ssl->buffers.serverDH_G.buffer,
ashleymills 0:e979170e02e7 8656 ssl->buffers.serverDH_G.length);
ashleymills 0:e979170e02e7 8657 if (ret == 0)
ashleymills 0:e979170e02e7 8658 ret = DhAgree(&dhKey, ssl->arrays->preMasterSecret,
ashleymills 0:e979170e02e7 8659 &ssl->arrays->preMasterSz,
ashleymills 0:e979170e02e7 8660 ssl->buffers.serverDH_Priv.buffer,
ashleymills 0:e979170e02e7 8661 ssl->buffers.serverDH_Priv.length,
ashleymills 0:e979170e02e7 8662 clientPub, clientPubSz);
ashleymills 0:e979170e02e7 8663 FreeDhKey(&dhKey);
ashleymills 0:e979170e02e7 8664 if (ret == 0)
ashleymills 0:e979170e02e7 8665 ret = MakeMasterSecret(ssl);
ashleymills 0:e979170e02e7 8666 }
ashleymills 0:e979170e02e7 8667 break;
ashleymills 0:e979170e02e7 8668 #endif /* OPENSSL_EXTRA */
ashleymills 0:e979170e02e7 8669 default:
ashleymills 0:e979170e02e7 8670 {
ashleymills 0:e979170e02e7 8671 CYASSL_MSG("Bad kea type");
ashleymills 0:e979170e02e7 8672 ret = BAD_KEA_TYPE_E;
ashleymills 0:e979170e02e7 8673 }
ashleymills 0:e979170e02e7 8674 break;
ashleymills 0:e979170e02e7 8675 }
ashleymills 0:e979170e02e7 8676
ashleymills 0:e979170e02e7 8677 if (ret == 0) {
ashleymills 0:e979170e02e7 8678 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
ashleymills 0:e979170e02e7 8679 #ifndef NO_CERTS
ashleymills 0:e979170e02e7 8680 if (ssl->options.verifyPeer)
ashleymills 0:e979170e02e7 8681 BuildCertHashes(ssl, &ssl->certHashes);
ashleymills 0:e979170e02e7 8682 #endif
ashleymills 0:e979170e02e7 8683 }
ashleymills 0:e979170e02e7 8684
ashleymills 0:e979170e02e7 8685 return ret;
ashleymills 0:e979170e02e7 8686 }
ashleymills 0:e979170e02e7 8687
ashleymills 0:e979170e02e7 8688 #endif /* NO_CYASSL_SERVER */
ashleymills 0:e979170e02e7 8689
ashleymills 0:e979170e02e7 8690
ashleymills 0:e979170e02e7 8691 #ifdef SINGLE_THREADED
ashleymills 0:e979170e02e7 8692
ashleymills 0:e979170e02e7 8693 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8694 {
ashleymills 0:e979170e02e7 8695 (void)m;
ashleymills 0:e979170e02e7 8696 return 0;
ashleymills 0:e979170e02e7 8697 }
ashleymills 0:e979170e02e7 8698
ashleymills 0:e979170e02e7 8699
ashleymills 0:e979170e02e7 8700 int FreeMutex(CyaSSL_Mutex *m)
ashleymills 0:e979170e02e7 8701 {
ashleymills 0:e979170e02e7 8702 (void)m;
ashleymills 0:e979170e02e7 8703 return 0;
ashleymills 0:e979170e02e7 8704 }
ashleymills 0:e979170e02e7 8705
ashleymills 0:e979170e02e7 8706
ashleymills 0:e979170e02e7 8707 int LockMutex(CyaSSL_Mutex *m)
ashleymills 0:e979170e02e7 8708 {
ashleymills 0:e979170e02e7 8709 (void)m;
ashleymills 0:e979170e02e7 8710 return 0;
ashleymills 0:e979170e02e7 8711 }
ashleymills 0:e979170e02e7 8712
ashleymills 0:e979170e02e7 8713
ashleymills 0:e979170e02e7 8714 int UnLockMutex(CyaSSL_Mutex *m)
ashleymills 0:e979170e02e7 8715 {
ashleymills 0:e979170e02e7 8716 (void)m;
ashleymills 0:e979170e02e7 8717 return 0;
ashleymills 0:e979170e02e7 8718 }
ashleymills 0:e979170e02e7 8719
ashleymills 0:e979170e02e7 8720 #else /* MULTI_THREAD */
ashleymills 0:e979170e02e7 8721
ashleymills 0:e979170e02e7 8722 #if defined(FREERTOS)
ashleymills 0:e979170e02e7 8723
ashleymills 0:e979170e02e7 8724 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8725 {
ashleymills 0:e979170e02e7 8726 int iReturn;
ashleymills 0:e979170e02e7 8727
ashleymills 0:e979170e02e7 8728 *m = ( CyaSSL_Mutex ) xSemaphoreCreateMutex();
ashleymills 0:e979170e02e7 8729 if( *m != NULL )
ashleymills 0:e979170e02e7 8730 iReturn = 0;
ashleymills 0:e979170e02e7 8731 else
ashleymills 0:e979170e02e7 8732 iReturn = BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8733
ashleymills 0:e979170e02e7 8734 return iReturn;
ashleymills 0:e979170e02e7 8735 }
ashleymills 0:e979170e02e7 8736
ashleymills 0:e979170e02e7 8737 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8738 {
ashleymills 0:e979170e02e7 8739 vSemaphoreDelete( *m );
ashleymills 0:e979170e02e7 8740 return 0;
ashleymills 0:e979170e02e7 8741 }
ashleymills 0:e979170e02e7 8742
ashleymills 0:e979170e02e7 8743 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8744 {
ashleymills 0:e979170e02e7 8745 /* Assume an infinite block, or should there be zero block? */
ashleymills 0:e979170e02e7 8746 xSemaphoreTake( *m, portMAX_DELAY );
ashleymills 0:e979170e02e7 8747 return 0;
ashleymills 0:e979170e02e7 8748 }
ashleymills 0:e979170e02e7 8749
ashleymills 0:e979170e02e7 8750 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8751 {
ashleymills 0:e979170e02e7 8752 xSemaphoreGive( *m );
ashleymills 0:e979170e02e7 8753 return 0;
ashleymills 0:e979170e02e7 8754 }
ashleymills 0:e979170e02e7 8755
ashleymills 0:e979170e02e7 8756 #elif defined(CYASSL_SAFERTOS)
ashleymills 0:e979170e02e7 8757
ashleymills 0:e979170e02e7 8758 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8759 {
ashleymills 0:e979170e02e7 8760 vSemaphoreCreateBinary(m->mutexBuffer, m->mutex);
ashleymills 0:e979170e02e7 8761 if (m->mutex == NULL)
ashleymills 0:e979170e02e7 8762 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8763
ashleymills 0:e979170e02e7 8764 return 0;
ashleymills 0:e979170e02e7 8765 }
ashleymills 0:e979170e02e7 8766
ashleymills 0:e979170e02e7 8767 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8768 {
ashleymills 0:e979170e02e7 8769 (void)m;
ashleymills 0:e979170e02e7 8770 return 0;
ashleymills 0:e979170e02e7 8771 }
ashleymills 0:e979170e02e7 8772
ashleymills 0:e979170e02e7 8773 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8774 {
ashleymills 0:e979170e02e7 8775 /* Assume an infinite block */
ashleymills 0:e979170e02e7 8776 xSemaphoreTake(m->mutex, portMAX_DELAY);
ashleymills 0:e979170e02e7 8777 return 0;
ashleymills 0:e979170e02e7 8778 }
ashleymills 0:e979170e02e7 8779
ashleymills 0:e979170e02e7 8780 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8781 {
ashleymills 0:e979170e02e7 8782 xSemaphoreGive(m->mutex);
ashleymills 0:e979170e02e7 8783 return 0;
ashleymills 0:e979170e02e7 8784 }
ashleymills 0:e979170e02e7 8785
ashleymills 0:e979170e02e7 8786
ashleymills 0:e979170e02e7 8787 #elif defined(USE_WINDOWS_API)
ashleymills 0:e979170e02e7 8788
ashleymills 0:e979170e02e7 8789 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8790 {
ashleymills 0:e979170e02e7 8791 InitializeCriticalSection(m);
ashleymills 0:e979170e02e7 8792 return 0;
ashleymills 0:e979170e02e7 8793 }
ashleymills 0:e979170e02e7 8794
ashleymills 0:e979170e02e7 8795
ashleymills 0:e979170e02e7 8796 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8797 {
ashleymills 0:e979170e02e7 8798 DeleteCriticalSection(m);
ashleymills 0:e979170e02e7 8799 return 0;
ashleymills 0:e979170e02e7 8800 }
ashleymills 0:e979170e02e7 8801
ashleymills 0:e979170e02e7 8802
ashleymills 0:e979170e02e7 8803 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8804 {
ashleymills 0:e979170e02e7 8805 EnterCriticalSection(m);
ashleymills 0:e979170e02e7 8806 return 0;
ashleymills 0:e979170e02e7 8807 }
ashleymills 0:e979170e02e7 8808
ashleymills 0:e979170e02e7 8809
ashleymills 0:e979170e02e7 8810 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8811 {
ashleymills 0:e979170e02e7 8812 LeaveCriticalSection(m);
ashleymills 0:e979170e02e7 8813 return 0;
ashleymills 0:e979170e02e7 8814 }
ashleymills 0:e979170e02e7 8815
ashleymills 0:e979170e02e7 8816 #elif defined(CYASSL_PTHREADS)
ashleymills 0:e979170e02e7 8817
ashleymills 0:e979170e02e7 8818 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8819 {
ashleymills 0:e979170e02e7 8820 if (pthread_mutex_init(m, 0) == 0)
ashleymills 0:e979170e02e7 8821 return 0;
ashleymills 0:e979170e02e7 8822 else
ashleymills 0:e979170e02e7 8823 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8824 }
ashleymills 0:e979170e02e7 8825
ashleymills 0:e979170e02e7 8826
ashleymills 0:e979170e02e7 8827 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8828 {
ashleymills 0:e979170e02e7 8829 if (pthread_mutex_destroy(m) == 0)
ashleymills 0:e979170e02e7 8830 return 0;
ashleymills 0:e979170e02e7 8831 else
ashleymills 0:e979170e02e7 8832 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8833 }
ashleymills 0:e979170e02e7 8834
ashleymills 0:e979170e02e7 8835
ashleymills 0:e979170e02e7 8836 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8837 {
ashleymills 0:e979170e02e7 8838 if (pthread_mutex_lock(m) == 0)
ashleymills 0:e979170e02e7 8839 return 0;
ashleymills 0:e979170e02e7 8840 else
ashleymills 0:e979170e02e7 8841 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8842 }
ashleymills 0:e979170e02e7 8843
ashleymills 0:e979170e02e7 8844
ashleymills 0:e979170e02e7 8845 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8846 {
ashleymills 0:e979170e02e7 8847 if (pthread_mutex_unlock(m) == 0)
ashleymills 0:e979170e02e7 8848 return 0;
ashleymills 0:e979170e02e7 8849 else
ashleymills 0:e979170e02e7 8850 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8851 }
ashleymills 0:e979170e02e7 8852
ashleymills 0:e979170e02e7 8853 #elif defined(THREADX)
ashleymills 0:e979170e02e7 8854
ashleymills 0:e979170e02e7 8855 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8856 {
ashleymills 0:e979170e02e7 8857 if (tx_mutex_create(m, "CyaSSL Mutex", TX_NO_INHERIT) == 0)
ashleymills 0:e979170e02e7 8858 return 0;
ashleymills 0:e979170e02e7 8859 else
ashleymills 0:e979170e02e7 8860 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8861 }
ashleymills 0:e979170e02e7 8862
ashleymills 0:e979170e02e7 8863
ashleymills 0:e979170e02e7 8864 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8865 {
ashleymills 0:e979170e02e7 8866 if (tx_mutex_delete(m) == 0)
ashleymills 0:e979170e02e7 8867 return 0;
ashleymills 0:e979170e02e7 8868 else
ashleymills 0:e979170e02e7 8869 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8870 }
ashleymills 0:e979170e02e7 8871
ashleymills 0:e979170e02e7 8872
ashleymills 0:e979170e02e7 8873 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8874 {
ashleymills 0:e979170e02e7 8875 if (tx_mutex_get(m, TX_WAIT_FOREVER) == 0)
ashleymills 0:e979170e02e7 8876 return 0;
ashleymills 0:e979170e02e7 8877 else
ashleymills 0:e979170e02e7 8878 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8879 }
ashleymills 0:e979170e02e7 8880
ashleymills 0:e979170e02e7 8881
ashleymills 0:e979170e02e7 8882 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8883 {
ashleymills 0:e979170e02e7 8884 if (tx_mutex_put(m) == 0)
ashleymills 0:e979170e02e7 8885 return 0;
ashleymills 0:e979170e02e7 8886 else
ashleymills 0:e979170e02e7 8887 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8888 }
ashleymills 0:e979170e02e7 8889
ashleymills 0:e979170e02e7 8890 #elif defined(MICRIUM)
ashleymills 0:e979170e02e7 8891
ashleymills 0:e979170e02e7 8892 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8893 {
ashleymills 0:e979170e02e7 8894 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
ashleymills 0:e979170e02e7 8895 if (NetSecure_OS_MutexCreate(m) == 0)
ashleymills 0:e979170e02e7 8896 return 0;
ashleymills 0:e979170e02e7 8897 else
ashleymills 0:e979170e02e7 8898 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8899 #else
ashleymills 0:e979170e02e7 8900 return 0;
ashleymills 0:e979170e02e7 8901 #endif
ashleymills 0:e979170e02e7 8902 }
ashleymills 0:e979170e02e7 8903
ashleymills 0:e979170e02e7 8904
ashleymills 0:e979170e02e7 8905 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8906 {
ashleymills 0:e979170e02e7 8907 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
ashleymills 0:e979170e02e7 8908 if (NetSecure_OS_FreeMutex(m) == 0)
ashleymills 0:e979170e02e7 8909 return 0;
ashleymills 0:e979170e02e7 8910 else
ashleymills 0:e979170e02e7 8911 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8912 #else
ashleymills 0:e979170e02e7 8913 return 0;
ashleymills 0:e979170e02e7 8914 #endif
ashleymills 0:e979170e02e7 8915 }
ashleymills 0:e979170e02e7 8916
ashleymills 0:e979170e02e7 8917
ashleymills 0:e979170e02e7 8918 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8919 {
ashleymills 0:e979170e02e7 8920 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
ashleymills 0:e979170e02e7 8921 if (NetSecure_OS_LockMutex(m) == 0)
ashleymills 0:e979170e02e7 8922 return 0;
ashleymills 0:e979170e02e7 8923 else
ashleymills 0:e979170e02e7 8924 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8925 #else
ashleymills 0:e979170e02e7 8926 return 0;
ashleymills 0:e979170e02e7 8927 #endif
ashleymills 0:e979170e02e7 8928 }
ashleymills 0:e979170e02e7 8929
ashleymills 0:e979170e02e7 8930
ashleymills 0:e979170e02e7 8931 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8932 {
ashleymills 0:e979170e02e7 8933 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
ashleymills 0:e979170e02e7 8934 if (NetSecure_OS_UnLockMutex(m) == 0)
ashleymills 0:e979170e02e7 8935 return 0;
ashleymills 0:e979170e02e7 8936 else
ashleymills 0:e979170e02e7 8937 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8938 #else
ashleymills 0:e979170e02e7 8939 return 0;
ashleymills 0:e979170e02e7 8940 #endif
ashleymills 0:e979170e02e7 8941
ashleymills 0:e979170e02e7 8942 }
ashleymills 0:e979170e02e7 8943
ashleymills 0:e979170e02e7 8944 #elif defined(EBSNET)
ashleymills 0:e979170e02e7 8945
ashleymills 0:e979170e02e7 8946 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8947 {
ashleymills 0:e979170e02e7 8948 if (rtp_sig_mutex_alloc(m, "CyaSSL Mutex") == -1)
ashleymills 0:e979170e02e7 8949 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8950 else
ashleymills 0:e979170e02e7 8951 return 0;
ashleymills 0:e979170e02e7 8952 }
ashleymills 0:e979170e02e7 8953
ashleymills 0:e979170e02e7 8954 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8955 {
ashleymills 0:e979170e02e7 8956 rtp_sig_mutex_free(*m);
ashleymills 0:e979170e02e7 8957 return 0;
ashleymills 0:e979170e02e7 8958 }
ashleymills 0:e979170e02e7 8959
ashleymills 0:e979170e02e7 8960 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8961 {
ashleymills 0:e979170e02e7 8962 if (rtp_sig_mutex_claim_timed(*m, RTIP_INF) == 0)
ashleymills 0:e979170e02e7 8963 return 0;
ashleymills 0:e979170e02e7 8964 else
ashleymills 0:e979170e02e7 8965 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8966 }
ashleymills 0:e979170e02e7 8967
ashleymills 0:e979170e02e7 8968 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8969 {
ashleymills 0:e979170e02e7 8970 rtp_sig_mutex_release(*m);
ashleymills 0:e979170e02e7 8971 return 0;
ashleymills 0:e979170e02e7 8972 }
ashleymills 0:e979170e02e7 8973
ashleymills 0:e979170e02e7 8974 #elif defined(FREESCALE_MQX)
ashleymills 0:e979170e02e7 8975
ashleymills 0:e979170e02e7 8976 int InitMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8977 {
ashleymills 0:e979170e02e7 8978 if (_mutex_init(m, NULL) == MQX_EOK)
ashleymills 0:e979170e02e7 8979 return 0;
ashleymills 0:e979170e02e7 8980 else
ashleymills 0:e979170e02e7 8981 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8982 }
ashleymills 0:e979170e02e7 8983
ashleymills 0:e979170e02e7 8984 int FreeMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8985 {
ashleymills 0:e979170e02e7 8986 if (_mutex_destroy(m) == MQX_EOK)
ashleymills 0:e979170e02e7 8987 return 0;
ashleymills 0:e979170e02e7 8988 else
ashleymills 0:e979170e02e7 8989 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8990 }
ashleymills 0:e979170e02e7 8991
ashleymills 0:e979170e02e7 8992 int LockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 8993 {
ashleymills 0:e979170e02e7 8994 if (_mutex_lock(m) == MQX_EOK)
ashleymills 0:e979170e02e7 8995 return 0;
ashleymills 0:e979170e02e7 8996 else
ashleymills 0:e979170e02e7 8997 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 8998 }
ashleymills 0:e979170e02e7 8999
ashleymills 0:e979170e02e7 9000 int UnLockMutex(CyaSSL_Mutex* m)
ashleymills 0:e979170e02e7 9001 {
ashleymills 0:e979170e02e7 9002 if (_mutex_unlock(m) == MQX_EOK)
ashleymills 0:e979170e02e7 9003 return 0;
ashleymills 0:e979170e02e7 9004 else
ashleymills 0:e979170e02e7 9005 return BAD_MUTEX_ERROR;
ashleymills 0:e979170e02e7 9006 }
ashleymills 0:e979170e02e7 9007
ashleymills 0:e979170e02e7 9008 #endif /* USE_WINDOWS_API */
ashleymills 0:e979170e02e7 9009 #endif /* SINGLE_THREADED */