]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/WolfSSL/src/ssl.c
Update WolfSSL library to the latest version.
[freertos] / FreeRTOS-Plus / Source / WolfSSL / src / ssl.c
1 /* ssl.c
2  *
3  * Copyright (C) 2006-2015 wolfSSL Inc.
4  *
5  * This file is part of wolfSSL. (formerly known as CyaSSL)
6  *
7  * wolfSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * wolfSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26 #include <wolfssl/wolfcrypt/settings.h>
27
28 #ifdef HAVE_ERRNO_H
29     #include <errno.h>
30 #endif
31
32 #include <wolfssl/internal.h>
33 #include <wolfssl/error-ssl.h>
34 #include <wolfssl/wolfcrypt/coding.h>
35
36 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
37     #include <wolfssl/openssl/evp.h>
38 #endif
39
40 #ifdef OPENSSL_EXTRA
41     /* openssl headers begin */
42     #include <wolfssl/openssl/hmac.h>
43     #include <wolfssl/openssl/crypto.h>
44     #include <wolfssl/openssl/des.h>
45     #include <wolfssl/openssl/bn.h>
46     #include <wolfssl/openssl/dh.h>
47     #include <wolfssl/openssl/rsa.h>
48     #include <wolfssl/openssl/pem.h>
49     /* openssl headers end, wolfssl internal headers next */
50     #include <wolfssl/wolfcrypt/hmac.h>
51     #include <wolfssl/wolfcrypt/random.h>
52     #include <wolfssl/wolfcrypt/des3.h>
53     #include <wolfssl/wolfcrypt/md4.h>
54     #include <wolfssl/wolfcrypt/md5.h>
55     #include <wolfssl/wolfcrypt/arc4.h>
56     #ifdef WOLFSSL_SHA512
57         #include <wolfssl/wolfcrypt/sha512.h>
58     #endif
59 #endif
60
61 #ifndef NO_FILESYSTEM
62     #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR) \
63             && !defined(EBSNET)
64         #include <dirent.h>
65         #include <sys/stat.h>
66     #endif
67     #ifdef EBSNET
68         #include "vfapi.h"
69         #include "vfile.h"
70     #endif
71 #endif /* NO_FILESYSTEM */
72
73 #ifndef TRUE
74     #define TRUE  1
75 #endif
76 #ifndef FALSE
77     #define FALSE 0
78 #endif
79
80 #ifndef WOLFSSL_HAVE_MIN
81 #define WOLFSSL_HAVE_MIN
82
83     static INLINE word32 min(word32 a, word32 b)
84     {
85         return a > b ? b : a;
86     }
87
88 #endif /* WOLFSSSL_HAVE_MIN */
89
90 #ifndef WOLFSSL_HAVE_MAX
91 #define WOLFSSL_HAVE_MAX
92
93 #ifdef WOLFSSL_DTLS
94     static INLINE word32 max(word32 a, word32 b)
95     {
96         return a > b ? a : b;
97     }
98 #endif /* WOLFSSL_DTLS */
99
100 #endif /* WOLFSSL_HAVE_MAX */
101
102
103 #ifndef WOLFSSL_LEANPSK
104 char* mystrnstr(const char* s1, const char* s2, unsigned int n)
105 {
106     unsigned int s2_len = (unsigned int)XSTRLEN(s2);
107
108     if (s2_len == 0)
109         return (char*)s1;
110
111     while (n >= s2_len && s1[0]) {
112         if (s1[0] == s2[0])
113             if (XMEMCMP(s1, s2, s2_len) == 0)
114                 return (char*)s1;
115         s1++;
116         n--;
117     }
118
119     return NULL;
120 }
121 #endif
122
123
124 /* prevent multiple mutex initializations */
125 static volatile int initRefCount = 0;
126 static wolfSSL_Mutex count_mutex;   /* init ref count mutex */
127
128
129 WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method)
130 {
131     WOLFSSL_CTX* ctx = NULL;
132
133     WOLFSSL_ENTER("WOLFSSL_CTX_new");
134
135     if (initRefCount == 0)
136         wolfSSL_Init(); /* user no longer forced to call Init themselves */
137
138     if (method == NULL)
139         return ctx;
140
141     ctx = (WOLFSSL_CTX*) XMALLOC(sizeof(WOLFSSL_CTX), 0, DYNAMIC_TYPE_CTX);
142     if (ctx) {
143         if (InitSSL_Ctx(ctx, method) < 0) {
144             WOLFSSL_MSG("Init CTX failed");
145             wolfSSL_CTX_free(ctx);
146             ctx = NULL;
147         }
148     }
149     else {
150         WOLFSSL_MSG("Alloc CTX failed, method freed");
151         XFREE(method, NULL, DYNAMIC_TYPE_METHOD);
152     }
153
154     WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
155     return ctx;
156 }
157
158
159 void wolfSSL_CTX_free(WOLFSSL_CTX* ctx)
160 {
161     WOLFSSL_ENTER("SSL_CTX_free");
162     if (ctx)
163         FreeSSL_Ctx(ctx);
164     WOLFSSL_LEAVE("SSL_CTX_free", 0);
165 }
166
167
168 WOLFSSL* wolfSSL_new(WOLFSSL_CTX* ctx)
169 {
170     WOLFSSL* ssl = NULL;
171     int ret = 0;
172
173     (void)ret;
174     WOLFSSL_ENTER("SSL_new");
175
176     if (ctx == NULL)
177         return ssl;
178
179     ssl = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ctx->heap,DYNAMIC_TYPE_SSL);
180     if (ssl)
181         if ( (ret = InitSSL(ssl, ctx)) < 0) {
182             FreeSSL(ssl);
183             ssl = 0;
184         }
185
186     WOLFSSL_LEAVE("SSL_new", ret);
187     return ssl;
188 }
189
190
191 void wolfSSL_free(WOLFSSL* ssl)
192 {
193     WOLFSSL_ENTER("SSL_free");
194     if (ssl)
195         FreeSSL(ssl);
196     WOLFSSL_LEAVE("SSL_free", 0);
197 }
198
199 #ifdef HAVE_POLY1305
200 /* set if to use old poly 1 for yes 0 to use new poly */
201 int wolfSSL_use_old_poly(WOLFSSL* ssl, int value)
202 {
203     WOLFSSL_ENTER("SSL_use_old_poly");
204     ssl->options.oldPoly = value;
205     WOLFSSL_LEAVE("SSL_use_old_poly", 0);
206     return 0;
207 }
208 #endif
209
210 int wolfSSL_set_fd(WOLFSSL* ssl, int fd)
211 {
212     WOLFSSL_ENTER("SSL_set_fd");
213     ssl->rfd = fd;      /* not used directly to allow IO callbacks */
214     ssl->wfd = fd;
215
216     ssl->IOCB_ReadCtx  = &ssl->rfd;
217     ssl->IOCB_WriteCtx = &ssl->wfd;
218
219     #ifdef WOLFSSL_DTLS
220         if (ssl->options.dtls) {
221             ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
222             ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
223             ssl->buffers.dtlsCtx.fd = fd;
224         }
225     #endif
226
227     WOLFSSL_LEAVE("SSL_set_fd", SSL_SUCCESS);
228     return SSL_SUCCESS;
229 }
230
231
232 /**
233   * Get the name of cipher at priotity level passed in.
234   */
235 char* wolfSSL_get_cipher_list(int priority)
236 {
237     const char* const* ciphers = GetCipherNames();
238
239     if (priority >= GetCipherNamesSize() || priority < 0) {
240         return 0;
241     }
242
243     return (char*)ciphers[priority];
244 }
245
246
247 int wolfSSL_get_ciphers(char* buf, int len)
248 {
249     const char* const* ciphers = GetCipherNames();
250     int  totalInc = 0;
251     int  step     = 0;
252     char delim    = ':';
253     int  size     = GetCipherNamesSize();
254     int  i;
255
256     if (buf == NULL || len <= 0)
257         return BAD_FUNC_ARG;
258
259     /* Add each member to the buffer delimitted by a : */
260     for (i = 0; i < size; i++) {
261         step = (int)(XSTRLEN(ciphers[i]) + 1);  /* delimiter */
262         totalInc += step;
263
264         /* Check to make sure buf is large enough and will not overflow */
265         if (totalInc < len) {
266             XSTRNCPY(buf, ciphers[i], XSTRLEN(ciphers[i]));
267             buf += XSTRLEN(ciphers[i]);
268
269             if (i < size - 1)
270                 *buf++ = delim;
271         }
272         else
273             return BUFFER_E;
274     }
275     return SSL_SUCCESS;
276 }
277
278
279 int wolfSSL_get_fd(const WOLFSSL* ssl)
280 {
281     WOLFSSL_ENTER("SSL_get_fd");
282     WOLFSSL_LEAVE("SSL_get_fd", ssl->rfd);
283     return ssl->rfd;
284 }
285
286
287 int wolfSSL_get_using_nonblock(WOLFSSL* ssl)
288 {
289     WOLFSSL_ENTER("wolfSSL_get_using_nonblock");
290     WOLFSSL_LEAVE("wolfSSL_get_using_nonblock", ssl->options.usingNonblock);
291     return ssl->options.usingNonblock;
292 }
293
294
295 int wolfSSL_dtls(WOLFSSL* ssl)
296 {
297     return ssl->options.dtls;
298 }
299
300
301 #ifndef WOLFSSL_LEANPSK
302 void wolfSSL_set_using_nonblock(WOLFSSL* ssl, int nonblock)
303 {
304     WOLFSSL_ENTER("wolfSSL_set_using_nonblock");
305     ssl->options.usingNonblock = (nonblock != 0);
306 }
307
308
309 int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
310 {
311 #ifdef WOLFSSL_DTLS
312     void* sa = (void*)XMALLOC(peerSz, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
313     if (sa != NULL) {
314         if (ssl->buffers.dtlsCtx.peer.sa != NULL)
315             XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
316         XMEMCPY(sa, peer, peerSz);
317         ssl->buffers.dtlsCtx.peer.sa = sa;
318         ssl->buffers.dtlsCtx.peer.sz = peerSz;
319         return SSL_SUCCESS;
320     }
321     return SSL_FAILURE;
322 #else
323     (void)ssl;
324     (void)peer;
325     (void)peerSz;
326     return SSL_NOT_IMPLEMENTED;
327 #endif
328 }
329
330 int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
331 {
332 #ifdef WOLFSSL_DTLS
333     if (peer != NULL && peerSz != NULL
334             && *peerSz >= ssl->buffers.dtlsCtx.peer.sz) {
335         *peerSz = ssl->buffers.dtlsCtx.peer.sz;
336         XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
337         return SSL_SUCCESS;
338     }
339     return SSL_FAILURE;
340 #else
341     (void)ssl;
342     (void)peer;
343     (void)peerSz;
344     return SSL_NOT_IMPLEMENTED;
345 #endif
346 }
347 #endif /* WOLFSSL_LEANPSK */
348
349
350 /* return underlyig connect or accept, SSL_SUCCESS on ok */
351 int wolfSSL_negotiate(WOLFSSL* ssl)
352 {
353     int err = SSL_FATAL_ERROR;
354
355     WOLFSSL_ENTER("wolfSSL_negotiate");
356 #ifndef NO_WOLFSSL_SERVER
357     if (ssl->options.side == WOLFSSL_SERVER_END)
358         err = wolfSSL_accept(ssl);
359 #endif
360
361 #ifndef NO_WOLFSSL_CLIENT
362     if (ssl->options.side == WOLFSSL_CLIENT_END)
363         err = wolfSSL_connect(ssl);
364 #endif
365
366     WOLFSSL_LEAVE("wolfSSL_negotiate", err);
367
368     return err;
369 }
370
371
372 #ifndef WOLFSSL_LEANPSK
373 /* object size based on build */
374 int wolfSSL_GetObjectSize(void)
375 {
376 #ifdef SHOW_SIZES
377     printf("sizeof suites           = %lu\n", sizeof(Suites));
378     printf("sizeof ciphers(2)       = %lu\n", sizeof(Ciphers));
379 #ifndef NO_RC4
380     printf("    sizeof arc4         = %lu\n", sizeof(Arc4));
381 #endif
382     printf("    sizeof aes          = %lu\n", sizeof(Aes));
383 #ifndef NO_DES3
384     printf("    sizeof des3         = %lu\n", sizeof(Des3));
385 #endif
386 #ifndef NO_RABBIT
387     printf("    sizeof rabbit       = %lu\n", sizeof(Rabbit));
388 #endif
389 #ifdef HAVE_CHACHA
390     printf("    sizeof chacha       = %lu\n", sizeof(Chacha));
391 #endif
392     printf("sizeof cipher specs     = %lu\n", sizeof(CipherSpecs));
393     printf("sizeof keys             = %lu\n", sizeof(Keys));
394     printf("sizeof Hashes(2)        = %lu\n", sizeof(Hashes));
395 #ifndef NO_MD5
396     printf("    sizeof MD5          = %lu\n", sizeof(Md5));
397 #endif
398 #ifndef NO_SHA
399     printf("    sizeof SHA          = %lu\n", sizeof(Sha));
400 #endif
401 #ifndef NO_SHA256
402     printf("    sizeof SHA256       = %lu\n", sizeof(Sha256));
403 #endif
404 #ifdef WOLFSSL_SHA384
405     printf("    sizeof SHA384       = %lu\n", sizeof(Sha384));
406 #endif
407 #ifdef WOLFSSL_SHA384
408     printf("    sizeof SHA512       = %lu\n", sizeof(Sha512));
409 #endif
410     printf("sizeof Buffers          = %lu\n", sizeof(Buffers));
411     printf("sizeof Options          = %lu\n", sizeof(Options));
412     printf("sizeof Arrays           = %lu\n", sizeof(Arrays));
413 #ifndef NO_RSA
414     printf("sizeof RsaKey           = %lu\n", sizeof(RsaKey));
415 #endif
416 #ifdef HAVE_ECC
417     printf("sizeof ecc_key          = %lu\n", sizeof(ecc_key));
418 #endif
419     printf("sizeof WOLFSSL_CIPHER    = %lu\n", sizeof(WOLFSSL_CIPHER));
420     printf("sizeof WOLFSSL_SESSION   = %lu\n", sizeof(WOLFSSL_SESSION));
421     printf("sizeof WOLFSSL           = %lu\n", sizeof(WOLFSSL));
422     printf("sizeof WOLFSSL_CTX       = %lu\n", sizeof(WOLFSSL_CTX));
423 #endif
424
425     return sizeof(WOLFSSL);
426 }
427 #endif
428
429
430 #ifndef NO_DH
431 /* server Diffie-Hellman parameters, SSL_SUCCESS on ok */
432 int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
433                     const unsigned char* g, int gSz)
434 {
435     byte havePSK = 0;
436     byte haveRSA = 1;
437
438     WOLFSSL_ENTER("wolfSSL_SetTmpDH");
439     if (ssl == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
440
441     if (pSz < ssl->options.minDhKeySz)
442         return DH_KEY_SIZE_E;
443
444     if (ssl->options.side != WOLFSSL_SERVER_END)
445         return SIDE_ERROR;
446
447     if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH)
448         XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
449     if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH)
450         XFREE(ssl->buffers.serverDH_G.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
451
452     ssl->buffers.weOwnDH = 1;  /* SSL owns now */
453     ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->ctx->heap,
454                                                     DYNAMIC_TYPE_DH);
455     if (ssl->buffers.serverDH_P.buffer == NULL)
456         return MEMORY_E;
457
458     ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, ssl->ctx->heap,
459                                                     DYNAMIC_TYPE_DH);
460     if (ssl->buffers.serverDH_G.buffer == NULL) {
461         XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
462         return MEMORY_E;
463     }
464
465     ssl->buffers.serverDH_P.length = pSz;
466     ssl->buffers.serverDH_G.length = gSz;
467
468     XMEMCPY(ssl->buffers.serverDH_P.buffer, p, pSz);
469     XMEMCPY(ssl->buffers.serverDH_G.buffer, g, gSz);
470
471     ssl->options.haveDH = 1;
472     #ifndef NO_PSK
473         havePSK = ssl->options.havePSK;
474     #endif
475     #ifdef NO_RSA
476         haveRSA = 0;
477     #endif
478     InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH,
479                ssl->options.haveNTRU, ssl->options.haveECDSAsig,
480                ssl->options.haveStaticECC, ssl->options.side);
481
482     WOLFSSL_LEAVE("wolfSSL_SetTmpDH", 0);
483     return SSL_SUCCESS;
484 }
485
486 /* server ctx Diffie-Hellman parameters, SSL_SUCCESS on ok */
487 int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
488                          const unsigned char* g, int gSz)
489 {
490     WOLFSSL_ENTER("wolfSSL_CTX_SetTmpDH");
491     if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
492
493     if (pSz < ctx->minDhKeySz)
494         return DH_KEY_SIZE_E;
495
496     XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
497     XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
498
499     ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap,DYNAMIC_TYPE_DH);
500     if (ctx->serverDH_P.buffer == NULL)
501        return MEMORY_E;
502
503     ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap,DYNAMIC_TYPE_DH);
504     if (ctx->serverDH_G.buffer == NULL) {
505         XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
506         return MEMORY_E;
507     }
508
509     ctx->serverDH_P.length = pSz;
510     ctx->serverDH_G.length = gSz;
511
512     XMEMCPY(ctx->serverDH_P.buffer, p, pSz);
513     XMEMCPY(ctx->serverDH_G.buffer, g, gSz);
514
515     ctx->haveDH = 1;
516
517     WOLFSSL_LEAVE("wolfSSL_CTX_SetTmpDH", 0);
518     return SSL_SUCCESS;
519 }
520
521 #endif /* !NO_DH */
522
523
524 int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
525 {
526     int ret;
527
528     WOLFSSL_ENTER("SSL_write()");
529
530     if (ssl == NULL || data == NULL || sz < 0)
531         return BAD_FUNC_ARG;
532
533 #ifdef HAVE_ERRNO_H
534     errno = 0;
535 #endif
536
537     ret = SendData(ssl, data, sz);
538
539     WOLFSSL_LEAVE("SSL_write()", ret);
540
541     if (ret < 0)
542         return SSL_FATAL_ERROR;
543     else
544         return ret;
545 }
546
547
548 static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
549 {
550     int ret;
551
552     WOLFSSL_ENTER("wolfSSL_read_internal()");
553
554     if (ssl == NULL || data == NULL || sz < 0)
555         return BAD_FUNC_ARG;
556
557 #ifdef HAVE_ERRNO_H
558         errno = 0;
559 #endif
560 #ifdef WOLFSSL_DTLS
561     if (ssl->options.dtls)
562         ssl->dtls_expected_rx = max(sz + 100, MAX_MTU);
563 #endif
564
565 #ifdef HAVE_MAX_FRAGMENT
566     ret = ReceiveData(ssl, (byte*)data,
567                      min(sz, min(ssl->max_fragment, OUTPUT_RECORD_SIZE)), peek);
568 #else
569     ret = ReceiveData(ssl, (byte*)data, min(sz, OUTPUT_RECORD_SIZE), peek);
570 #endif
571
572     WOLFSSL_LEAVE("wolfSSL_read_internal()", ret);
573
574     if (ret < 0)
575         return SSL_FATAL_ERROR;
576     else
577         return ret;
578 }
579
580
581 int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz)
582 {
583     WOLFSSL_ENTER("wolfSSL_peek()");
584
585     return wolfSSL_read_internal(ssl, data, sz, TRUE);
586 }
587
588
589 int wolfSSL_read(WOLFSSL* ssl, void* data, int sz)
590 {
591     WOLFSSL_ENTER("wolfSSL_read()");
592
593     return wolfSSL_read_internal(ssl, data, sz, FALSE);
594 }
595
596
597 #ifdef HAVE_CAVIUM
598
599 /* let's use cavium, SSL_SUCCESS on ok */
600 int wolfSSL_UseCavium(WOLFSSL* ssl, int devId)
601 {
602     if (ssl == NULL)
603         return BAD_FUNC_ARG;
604
605     ssl->devId = devId;
606
607     return SSL_SUCCESS;
608 }
609
610
611 /* let's use cavium, SSL_SUCCESS on ok */
612 int wolfSSL_CTX_UseCavium(WOLFSSL_CTX* ctx, int devId)
613 {
614     if (ctx == NULL)
615         return BAD_FUNC_ARG;
616
617     ctx->devId = devId;
618
619     return SSL_SUCCESS;
620 }
621
622
623 #endif /* HAVE_CAVIUM */
624
625 #ifdef HAVE_SNI
626
627 int wolfSSL_UseSNI(WOLFSSL* ssl, byte type, const void* data, word16 size)
628 {
629     if (ssl == NULL)
630         return BAD_FUNC_ARG;
631
632     return TLSX_UseSNI(&ssl->extensions, type, data, size);
633 }
634
635 int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, const void* data, word16 size)
636 {
637     if (ctx == NULL)
638         return BAD_FUNC_ARG;
639
640     return TLSX_UseSNI(&ctx->extensions, type, data, size);
641 }
642
643 #ifndef NO_WOLFSSL_SERVER
644
645 void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options)
646 {
647     if (ssl && ssl->extensions)
648         TLSX_SNI_SetOptions(ssl->extensions, type, options);
649 }
650
651 void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options)
652 {
653     if (ctx && ctx->extensions)
654         TLSX_SNI_SetOptions(ctx->extensions, type, options);
655 }
656
657 byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type)
658 {
659     return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type);
660 }
661
662 word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data)
663 {
664     if (data)
665         *data = NULL;
666
667     if (ssl && ssl->extensions)
668         return TLSX_SNI_GetRequest(ssl->extensions, type, data);
669
670     return 0;
671 }
672
673 int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, byte type,
674                                                      byte* sni, word32* inOutSz)
675 {
676     if (clientHello && helloSz > 0 && sni && inOutSz && *inOutSz > 0)
677         return TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
678
679     return BAD_FUNC_ARG;
680 }
681
682 #endif /* NO_WOLFSSL_SERVER */
683
684 #endif /* HAVE_SNI */
685
686
687 #ifdef HAVE_MAX_FRAGMENT
688 #ifndef NO_WOLFSSL_CLIENT
689 int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl)
690 {
691     if (ssl == NULL)
692         return BAD_FUNC_ARG;
693
694     return TLSX_UseMaxFragment(&ssl->extensions, mfl);
695 }
696
697 int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl)
698 {
699     if (ctx == NULL)
700         return BAD_FUNC_ARG;
701
702     return TLSX_UseMaxFragment(&ctx->extensions, mfl);
703 }
704 #endif /* NO_WOLFSSL_CLIENT */
705 #endif /* HAVE_MAX_FRAGMENT */
706
707 #ifdef HAVE_TRUNCATED_HMAC
708 #ifndef NO_WOLFSSL_CLIENT
709 int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl)
710 {
711     if (ssl == NULL)
712         return BAD_FUNC_ARG;
713
714     return TLSX_UseTruncatedHMAC(&ssl->extensions);
715 }
716
717 int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
718 {
719     if (ctx == NULL)
720         return BAD_FUNC_ARG;
721
722     return TLSX_UseTruncatedHMAC(&ctx->extensions);
723 }
724 #endif /* NO_WOLFSSL_CLIENT */
725 #endif /* HAVE_TRUNCATED_HMAC */
726
727 /* Elliptic Curves */
728 #ifdef HAVE_SUPPORTED_CURVES
729 #ifndef NO_WOLFSSL_CLIENT
730
731 int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
732 {
733     if (ssl == NULL)
734         return BAD_FUNC_ARG;
735
736     switch (name) {
737         case WOLFSSL_ECC_SECP160R1:
738         case WOLFSSL_ECC_SECP192R1:
739         case WOLFSSL_ECC_SECP224R1:
740         case WOLFSSL_ECC_SECP256R1:
741         case WOLFSSL_ECC_SECP384R1:
742         case WOLFSSL_ECC_SECP521R1:
743             break;
744
745         default:
746             return BAD_FUNC_ARG;
747     }
748
749     return TLSX_UseSupportedCurve(&ssl->extensions, name);
750 }
751
752 int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
753 {
754     if (ctx == NULL)
755         return BAD_FUNC_ARG;
756
757     switch (name) {
758         case WOLFSSL_ECC_SECP160R1:
759         case WOLFSSL_ECC_SECP192R1:
760         case WOLFSSL_ECC_SECP224R1:
761         case WOLFSSL_ECC_SECP256R1:
762         case WOLFSSL_ECC_SECP384R1:
763         case WOLFSSL_ECC_SECP521R1:
764             break;
765
766         default:
767             return BAD_FUNC_ARG;
768     }
769
770     return TLSX_UseSupportedCurve(&ctx->extensions, name);
771 }
772
773 #endif /* NO_WOLFSSL_CLIENT */
774 #endif /* HAVE_SUPPORTED_CURVES */
775
776 /* Secure Renegotiation */
777 #ifdef HAVE_SECURE_RENEGOTIATION
778
779 /* user is forcing ability to use secure renegotiation, we discourage it */
780 int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl)
781 {
782     int ret = BAD_FUNC_ARG;
783
784     if (ssl)
785         ret = TLSX_UseSecureRenegotiation(&ssl->extensions);
786
787     if (ret == SSL_SUCCESS) {
788         TLSX* extension = TLSX_Find(ssl->extensions, SECURE_RENEGOTIATION);
789         
790         if (extension)
791             ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
792     }
793
794     return ret;
795 }
796
797
798 /* do a secure renegotiation handshake, user forced, we discourage */
799 int wolfSSL_Rehandshake(WOLFSSL* ssl)
800 {
801     int ret;
802
803     if (ssl == NULL)
804         return BAD_FUNC_ARG;
805
806     if (ssl->secure_renegotiation == NULL) {
807         WOLFSSL_MSG("Secure Renegotiation not forced on by user");
808         return SECURE_RENEGOTIATION_E;
809     }
810
811     if (ssl->secure_renegotiation->enabled == 0) {
812         WOLFSSL_MSG("Secure Renegotiation not enabled at extension level");
813         return SECURE_RENEGOTIATION_E;
814     }
815
816     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
817         WOLFSSL_MSG("Can't renegotiate until previous handshake complete");
818         return SECURE_RENEGOTIATION_E;
819     }
820
821 #ifndef NO_FORCE_SCR_SAME_SUITE
822     /* force same suite */
823     if (ssl->suites) {
824         ssl->suites->suiteSz = SUITE_LEN;
825         ssl->suites->suites[0] = ssl->options.cipherSuite0;
826         ssl->suites->suites[1] = ssl->options.cipherSuite;
827     }
828 #endif
829
830     /* reset handshake states */
831     ssl->options.serverState = NULL_STATE;
832     ssl->options.clientState = NULL_STATE;
833     ssl->options.connectState  = CONNECT_BEGIN;
834     ssl->options.acceptState   = ACCEPT_BEGIN;
835     ssl->options.handShakeState = NULL_STATE;
836     ssl->options.processReply  = 0;  /* TODO, move states in internal.h */
837
838     XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
839
840     ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
841
842 #ifndef NO_OLD_TLS
843 #ifndef NO_MD5
844     wc_InitMd5(&ssl->hsHashes->hashMd5);
845 #endif
846 #ifndef NO_SHA
847     ret = wc_InitSha(&ssl->hsHashes->hashSha);
848     if (ret !=0)
849         return ret;
850 #endif
851 #endif /* NO_OLD_TLS */
852 #ifndef NO_SHA256
853     ret = wc_InitSha256(&ssl->hsHashes->hashSha256);
854     if (ret !=0)
855         return ret;
856 #endif
857 #ifdef WOLFSSL_SHA384
858     ret = wc_InitSha384(&ssl->hsHashes->hashSha384);
859     if (ret !=0)
860         return ret;
861 #endif
862 #ifdef WOLFSSL_SHA512
863     ret = wc_InitSha512(&ssl->hsHashes->hashSha512);
864     if (ret !=0)
865         return ret;
866 #endif
867
868     ret = wolfSSL_negotiate(ssl);
869     return ret;
870 }
871
872 #endif /* HAVE_SECURE_RENEGOTIATION */
873
874 /* Session Ticket */
875 #if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SESSION_TICKET)
876 /* SSL_SUCCESS on ok */
877 int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
878 {
879     if (ctx == NULL)
880         return BAD_FUNC_ARG;
881
882     ctx->ticketEncCb = cb;
883
884     return SSL_SUCCESS;
885 }
886
887 /* set hint interval, SSL_SUCCESS on ok */
888 int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
889 {
890     if (ctx == NULL)
891         return BAD_FUNC_ARG;
892
893     ctx->ticketHint = hint;
894
895     return SSL_SUCCESS;
896 }
897
898 /* set user context, SSL_SUCCESS on ok */
899 int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void* userCtx)
900 {
901     if (ctx == NULL)
902         return BAD_FUNC_ARG;
903
904     ctx->ticketEncCtx = userCtx;
905
906     return SSL_SUCCESS;
907 }
908
909 #endif /* !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET) */
910
911 /* Session Ticket */
912 #if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET)
913 int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
914 {
915     if (ssl == NULL)
916         return BAD_FUNC_ARG;
917
918     return TLSX_UseSessionTicket(&ssl->extensions, NULL);
919 }
920
921 int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx)
922 {
923     if (ctx == NULL)
924         return BAD_FUNC_ARG;
925
926     return TLSX_UseSessionTicket(&ctx->extensions, NULL);
927 }
928
929 WOLFSSL_API int wolfSSL_get_SessionTicket(WOLFSSL* ssl, byte* buf, word32* bufSz)
930 {
931     if (ssl == NULL || buf == NULL || bufSz == NULL || *bufSz == 0)
932         return BAD_FUNC_ARG;
933
934     if (ssl->session.ticketLen <= *bufSz) {
935         XMEMCPY(buf, ssl->session.ticket, ssl->session.ticketLen);
936         *bufSz = ssl->session.ticketLen;
937     }
938     else
939         *bufSz = 0;
940
941     return SSL_SUCCESS;
942 }
943
944 WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL* ssl, byte* buf, word32 bufSz)
945 {
946     if (ssl == NULL || (buf == NULL && bufSz > 0))
947         return BAD_FUNC_ARG;
948
949     if (bufSz > 0)
950         XMEMCPY(ssl->session.ticket, buf, bufSz);
951     ssl->session.ticketLen = (word16)bufSz;
952
953     return SSL_SUCCESS;
954 }
955
956
957 WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
958                                             CallbackSessionTicket cb, void* ctx)
959 {
960     if (ssl == NULL)
961         return BAD_FUNC_ARG;
962
963     ssl->session_ticket_cb = cb;
964     ssl->session_ticket_ctx = ctx;
965
966     return SSL_SUCCESS;
967 }
968 #endif
969
970 #ifndef WOLFSSL_LEANPSK
971
972 int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags)
973 {
974     int ret;
975     int oldFlags;
976
977     WOLFSSL_ENTER("wolfSSL_send()");
978
979     if (ssl == NULL || data == NULL || sz < 0)
980         return BAD_FUNC_ARG;
981
982     oldFlags = ssl->wflags;
983
984     ssl->wflags = flags;
985     ret = wolfSSL_write(ssl, data, sz);
986     ssl->wflags = oldFlags;
987
988     WOLFSSL_LEAVE("wolfSSL_send()", ret);
989
990     return ret;
991 }
992
993
994 int wolfSSL_recv(WOLFSSL* ssl, void* data, int sz, int flags)
995 {
996     int ret;
997     int oldFlags;
998
999     WOLFSSL_ENTER("wolfSSL_recv()");
1000
1001     if (ssl == NULL || data == NULL || sz < 0)
1002         return BAD_FUNC_ARG;
1003
1004     oldFlags = ssl->rflags;
1005
1006     ssl->rflags = flags;
1007     ret = wolfSSL_read(ssl, data, sz);
1008     ssl->rflags = oldFlags;
1009
1010     WOLFSSL_LEAVE("wolfSSL_recv()", ret);
1011
1012     return ret;
1013 }
1014 #endif
1015
1016
1017 /* SSL_SUCCESS on ok */
1018 int wolfSSL_shutdown(WOLFSSL* ssl)
1019 {
1020     int  ret = SSL_FATAL_ERROR;
1021     byte tmp;
1022     WOLFSSL_ENTER("SSL_shutdown()");
1023
1024     if (ssl == NULL)
1025         return SSL_FATAL_ERROR;
1026
1027     if (ssl->options.quietShutdown) {
1028         WOLFSSL_MSG("quiet shutdown, no close notify sent");
1029         return SSL_SUCCESS;
1030     }
1031
1032     /* try to send close notify, not an error if can't */
1033     if (!ssl->options.isClosed && !ssl->options.connReset &&
1034                                   !ssl->options.sentNotify) {
1035         ssl->error = SendAlert(ssl, alert_warning, close_notify);
1036         if (ssl->error < 0) {
1037             WOLFSSL_ERROR(ssl->error);
1038             return SSL_FATAL_ERROR;
1039         }
1040         ssl->options.sentNotify = 1;  /* don't send close_notify twice */
1041         if (ssl->options.closeNotify)
1042             ret = SSL_SUCCESS;
1043         else
1044             ret = SSL_SHUTDOWN_NOT_DONE;
1045
1046         WOLFSSL_LEAVE("SSL_shutdown()", ret);
1047         return ret;
1048     }
1049
1050     /* call wolfSSL_shutdown again for bidirectional shudown */
1051     if (ssl->options.sentNotify && !ssl->options.closeNotify) {
1052         ret = wolfSSL_read(ssl, &tmp, 0);
1053         if (ret < 0) {
1054             WOLFSSL_ERROR(ssl->error);
1055             ret = SSL_FATAL_ERROR;
1056         } else if (ssl->options.closeNotify) {
1057             ssl->error = SSL_ERROR_SYSCALL;   /* simulate OpenSSL behavior */
1058             ret = SSL_SUCCESS;
1059         }
1060     }
1061
1062     WOLFSSL_LEAVE("SSL_shutdown()", ret);
1063
1064     return ret;
1065 }
1066
1067
1068 int wolfSSL_get_error(WOLFSSL* ssl, int ret)
1069 {
1070     WOLFSSL_ENTER("SSL_get_error");
1071
1072     if (ret > 0)
1073         return SSL_ERROR_NONE;
1074     if (ssl == NULL)
1075         return BAD_FUNC_ARG;
1076
1077     WOLFSSL_LEAVE("SSL_get_error", ssl->error);
1078
1079     /* make sure converted types are handled in SetErrorString() too */
1080     if (ssl->error == WANT_READ)
1081         return SSL_ERROR_WANT_READ;         /* convert to OpenSSL type */
1082     else if (ssl->error == WANT_WRITE)
1083         return SSL_ERROR_WANT_WRITE;        /* convert to OpenSSL type */
1084     else if (ssl->error == ZERO_RETURN)
1085         return SSL_ERROR_ZERO_RETURN;       /* convert to OpenSSL type */
1086     return ssl->error;
1087 }
1088
1089
1090 /* retrive alert history, SSL_SUCCESS on ok */
1091 int wolfSSL_get_alert_history(WOLFSSL* ssl, WOLFSSL_ALERT_HISTORY *h)
1092 {
1093     if (ssl && h) {
1094         *h = ssl->alert_history;
1095     }
1096     return SSL_SUCCESS;
1097 }
1098
1099
1100 /* return TRUE if current error is want read */
1101 int wolfSSL_want_read(WOLFSSL* ssl)
1102 {
1103     WOLFSSL_ENTER("SSL_want_read");
1104     if (ssl->error == WANT_READ)
1105         return 1;
1106
1107     return 0;
1108 }
1109
1110
1111 /* return TRUE if current error is want write */
1112 int wolfSSL_want_write(WOLFSSL* ssl)
1113 {
1114     WOLFSSL_ENTER("SSL_want_write");
1115     if (ssl->error == WANT_WRITE)
1116         return 1;
1117
1118     return 0;
1119 }
1120
1121
1122 char* wolfSSL_ERR_error_string(unsigned long errNumber, char* data)
1123 {
1124     static const char* msg = "Please supply a buffer for error string";
1125
1126     WOLFSSL_ENTER("ERR_error_string");
1127     if (data) {
1128         SetErrorString((int)errNumber, data);
1129         return data;
1130     }
1131
1132     return (char*)msg;
1133 }
1134
1135
1136 void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
1137 {
1138     WOLFSSL_ENTER("wolfSSL_ERR_error_string_n");
1139     if (len >= WOLFSSL_MAX_ERROR_SZ)
1140         wolfSSL_ERR_error_string(e, buf);
1141     else {
1142         char tmp[WOLFSSL_MAX_ERROR_SZ];
1143
1144         WOLFSSL_MSG("Error buffer too short, truncating");
1145         if (len) {
1146             wolfSSL_ERR_error_string(e, tmp);
1147             XMEMCPY(buf, tmp, len-1);
1148             buf[len-1] = '\0';
1149         }
1150     }
1151 }
1152
1153
1154 /* don't free temporary arrays at end of handshake */
1155 void wolfSSL_KeepArrays(WOLFSSL* ssl)
1156 {
1157     if (ssl)
1158         ssl->options.saveArrays = 1;
1159 }
1160
1161
1162 /* user doesn't need temporary arrays anymore, Free */
1163 void wolfSSL_FreeArrays(WOLFSSL* ssl)
1164 {
1165     if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
1166         ssl->options.saveArrays = 0;
1167         FreeArrays(ssl, 1);
1168     }
1169 }
1170
1171
1172 const byte* wolfSSL_GetMacSecret(WOLFSSL* ssl, int verify)
1173 {
1174     if (ssl == NULL)
1175         return NULL;
1176
1177     if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
1178          (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
1179         return ssl->keys.client_write_MAC_secret;
1180     else
1181         return ssl->keys.server_write_MAC_secret;
1182 }
1183
1184
1185 #ifdef ATOMIC_USER
1186
1187 void  wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX* ctx, CallbackMacEncrypt cb)
1188 {
1189     if (ctx)
1190         ctx->MacEncryptCb = cb;
1191 }
1192
1193
1194 void  wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx)
1195 {
1196     if (ssl)
1197         ssl->MacEncryptCtx = ctx;
1198 }
1199
1200
1201 void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl)
1202 {
1203     if (ssl)
1204         return ssl->MacEncryptCtx;
1205
1206     return NULL;
1207 }
1208
1209
1210 void  wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX* ctx, CallbackDecryptVerify cb)
1211 {
1212     if (ctx)
1213         ctx->DecryptVerifyCb = cb;
1214 }
1215
1216
1217 void  wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx)
1218 {
1219     if (ssl)
1220         ssl->DecryptVerifyCtx = ctx;
1221 }
1222
1223
1224 void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl)
1225 {
1226     if (ssl)
1227         return ssl->DecryptVerifyCtx;
1228
1229     return NULL;
1230 }
1231
1232
1233 const byte* wolfSSL_GetClientWriteKey(WOLFSSL* ssl)
1234 {
1235     if (ssl)
1236         return ssl->keys.client_write_key;
1237
1238     return NULL;
1239 }
1240
1241
1242 const byte* wolfSSL_GetClientWriteIV(WOLFSSL* ssl)
1243 {
1244     if (ssl)
1245         return ssl->keys.client_write_IV;
1246
1247     return NULL;
1248 }
1249
1250
1251 const byte* wolfSSL_GetServerWriteKey(WOLFSSL* ssl)
1252 {
1253     if (ssl)
1254         return ssl->keys.server_write_key;
1255
1256     return NULL;
1257 }
1258
1259
1260 const byte* wolfSSL_GetServerWriteIV(WOLFSSL* ssl)
1261 {
1262     if (ssl)
1263         return ssl->keys.server_write_IV;
1264
1265     return NULL;
1266 }
1267
1268
1269 int wolfSSL_GetKeySize(WOLFSSL* ssl)
1270 {
1271     if (ssl)
1272         return ssl->specs.key_size;
1273
1274     return BAD_FUNC_ARG;
1275 }
1276
1277
1278 int wolfSSL_GetIVSize(WOLFSSL* ssl)
1279 {
1280     if (ssl)
1281         return ssl->specs.iv_size;
1282
1283     return BAD_FUNC_ARG;
1284 }
1285
1286
1287 int wolfSSL_GetBulkCipher(WOLFSSL* ssl)
1288 {
1289     if (ssl)
1290         return ssl->specs.bulk_cipher_algorithm;
1291
1292     return BAD_FUNC_ARG;
1293 }
1294
1295
1296 int wolfSSL_GetCipherType(WOLFSSL* ssl)
1297 {
1298     if (ssl == NULL)
1299         return BAD_FUNC_ARG;
1300
1301     if (ssl->specs.cipher_type == block)
1302         return WOLFSSL_BLOCK_TYPE;
1303     if (ssl->specs.cipher_type == stream)
1304         return WOLFSSL_STREAM_TYPE;
1305     if (ssl->specs.cipher_type == aead)
1306         return WOLFSSL_AEAD_TYPE;
1307
1308     return -1;
1309 }
1310
1311
1312 int wolfSSL_GetCipherBlockSize(WOLFSSL* ssl)
1313 {
1314     if (ssl == NULL)
1315         return BAD_FUNC_ARG;
1316
1317     return ssl->specs.block_size;
1318 }
1319
1320
1321 int wolfSSL_GetAeadMacSize(WOLFSSL* ssl)
1322 {
1323     if (ssl == NULL)
1324         return BAD_FUNC_ARG;
1325
1326     return ssl->specs.aead_mac_size;
1327 }
1328
1329
1330 int wolfSSL_IsTLSv1_1(WOLFSSL* ssl)
1331 {
1332     if (ssl == NULL)
1333         return BAD_FUNC_ARG;
1334
1335     if (ssl->options.tls1_1)
1336         return 1;
1337
1338     return 0;
1339 }
1340
1341
1342 int wolfSSL_GetSide(WOLFSSL* ssl)
1343 {
1344     if (ssl)
1345         return ssl->options.side;
1346
1347     return BAD_FUNC_ARG;
1348 }
1349
1350
1351 int wolfSSL_GetHmacSize(WOLFSSL* ssl)
1352 {
1353     /* AEAD ciphers don't have HMAC keys */
1354     if (ssl)
1355         return (ssl->specs.cipher_type != aead) ? ssl->specs.hash_size : 0;
1356
1357     return BAD_FUNC_ARG;
1358 }
1359
1360 #endif /* ATOMIC_USER */
1361
1362 #ifndef NO_CERTS
1363
1364 WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void)
1365 {
1366     WOLFSSL_CERT_MANAGER* cm = NULL;
1367
1368     WOLFSSL_ENTER("wolfSSL_CertManagerNew");
1369
1370     cm = (WOLFSSL_CERT_MANAGER*) XMALLOC(sizeof(WOLFSSL_CERT_MANAGER), 0,
1371                                         DYNAMIC_TYPE_CERT_MANAGER);
1372     if (cm) {
1373         XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER));
1374
1375         if (InitMutex(&cm->caLock) != 0) {
1376             WOLFSSL_MSG("Bad mutex init");
1377             wolfSSL_CertManagerFree(cm);
1378             return NULL;
1379         }
1380     }
1381
1382     return cm;
1383 }
1384
1385
1386 void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
1387 {
1388     WOLFSSL_ENTER("wolfSSL_CertManagerFree");
1389
1390     if (cm) {
1391         #ifdef HAVE_CRL
1392             if (cm->crl)
1393                 FreeCRL(cm->crl, 1);
1394         #endif
1395         #ifdef HAVE_OCSP
1396             if (cm->ocsp)
1397                 FreeOCSP(cm->ocsp, 1);
1398         #endif
1399         FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
1400         FreeMutex(&cm->caLock);
1401         XFREE(cm, NULL, DYNAMIC_TYPE_CERT_MANAGER);
1402     }
1403
1404 }
1405
1406
1407 /* Unload the CA signer list */
1408 int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
1409 {
1410     WOLFSSL_ENTER("wolfSSL_CertManagerUnloadCAs");
1411
1412     if (cm == NULL)
1413         return BAD_FUNC_ARG;
1414
1415     if (LockMutex(&cm->caLock) != 0)
1416         return BAD_MUTEX_E;
1417
1418     FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
1419
1420     UnLockMutex(&cm->caLock);
1421
1422
1423     return SSL_SUCCESS;
1424 }
1425
1426
1427 /* Return bytes written to buff or < 0 for error */
1428 int wolfSSL_CertPemToDer(const unsigned char* pem, int pemSz,
1429                         unsigned char* buff, int buffSz,
1430                         int type)
1431 {
1432     int            eccKey = 0;
1433     int            ret;
1434     buffer         der;
1435 #ifdef WOLFSSL_SMALL_STACK
1436     EncryptedInfo* info = NULL;
1437 #else
1438     EncryptedInfo  info[1];
1439 #endif
1440
1441     WOLFSSL_ENTER("wolfSSL_CertPemToDer");
1442
1443     if (pem == NULL || buff == NULL || buffSz <= 0) {
1444         WOLFSSL_MSG("Bad pem der args");
1445         return BAD_FUNC_ARG;
1446     }
1447
1448     if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) {
1449         WOLFSSL_MSG("Bad cert type");
1450         return BAD_FUNC_ARG;
1451     }
1452
1453 #ifdef WOLFSSL_SMALL_STACK
1454     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
1455                                                        DYNAMIC_TYPE_TMP_BUFFER);
1456     if (info == NULL)
1457         return MEMORY_E;
1458 #endif
1459
1460     info->set      = 0;
1461     info->ctx      = NULL;
1462     info->consumed = 0;
1463     der.buffer     = NULL;
1464
1465     ret = PemToDer(pem, pemSz, type, &der, NULL, info, &eccKey);
1466
1467 #ifdef WOLFSSL_SMALL_STACK
1468     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1469 #endif
1470
1471     if (ret < 0) {
1472         WOLFSSL_MSG("Bad Pem To Der");
1473     }
1474     else {
1475         if (der.length <= (word32)buffSz) {
1476             XMEMCPY(buff, der.buffer, der.length);
1477             ret = der.length;
1478         }
1479         else {
1480             WOLFSSL_MSG("Bad der length");
1481             ret = BAD_FUNC_ARG;
1482         }
1483     }
1484
1485     XFREE(der.buffer, NULL, DYNAMIC_TYPE_KEY);
1486
1487     return ret;
1488 }
1489
1490
1491 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
1492
1493 /* our KeyPemToDer password callback, password in userData */
1494 static INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
1495 {
1496     (void)rw;
1497
1498     if (userdata == NULL)
1499         return 0;
1500
1501     XSTRNCPY(passwd, (char*)userdata, sz);
1502     return min((word32)sz, (word32)XSTRLEN((char*)userdata));
1503 }
1504
1505 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
1506
1507
1508 /* Return bytes written to buff or < 0 for error */
1509 int wolfSSL_KeyPemToDer(const unsigned char* pem, int pemSz, unsigned char* buff,
1510                        int buffSz, const char* pass)
1511 {
1512     int            eccKey = 0;
1513     int            ret;
1514     buffer         der;
1515 #ifdef WOLFSSL_SMALL_STACK
1516     EncryptedInfo* info = NULL;
1517 #else
1518     EncryptedInfo  info[1];
1519 #endif
1520
1521     (void)pass;
1522
1523     WOLFSSL_ENTER("wolfSSL_KeyPemToDer");
1524
1525     if (pem == NULL || buff == NULL || buffSz <= 0) {
1526         WOLFSSL_MSG("Bad pem der args");
1527         return BAD_FUNC_ARG;
1528     }
1529
1530 #ifdef WOLFSSL_SMALL_STACK
1531     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
1532                                                        DYNAMIC_TYPE_TMP_BUFFER);
1533     if (info == NULL)
1534         return MEMORY_E;
1535 #endif
1536
1537     info->set      = 0;
1538     info->ctx      = NULL;
1539     info->consumed = 0;
1540     der.buffer     = NULL;
1541
1542 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
1543     if (pass) {
1544         info->ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
1545         if (info->ctx == NULL) {
1546         #ifdef WOLFSSL_SMALL_STACK
1547             XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1548         #endif
1549             return MEMORY_E;
1550         }
1551
1552         wolfSSL_CTX_set_default_passwd_cb(info->ctx, OurPasswordCb);
1553         wolfSSL_CTX_set_default_passwd_cb_userdata(info->ctx, (void*)pass);
1554     }
1555 #endif
1556
1557     ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, &eccKey);
1558
1559     if (info->ctx)
1560         wolfSSL_CTX_free(info->ctx);
1561
1562 #ifdef WOLFSSL_SMALL_STACK
1563     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1564 #endif
1565
1566     if (ret < 0) {
1567         WOLFSSL_MSG("Bad Pem To Der");
1568     }
1569     else {
1570         if (der.length <= (word32)buffSz) {
1571             XMEMCPY(buff, der.buffer, der.length);
1572             ret = der.length;
1573         }
1574         else {
1575             WOLFSSL_MSG("Bad der length");
1576             ret = BAD_FUNC_ARG;
1577         }
1578     }
1579
1580     XFREE(der.buffer, NULL, DYNAMIC_TYPE_KEY);
1581
1582     return ret;
1583 }
1584
1585
1586 #endif /* !NO_CERTS */
1587
1588
1589
1590 #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
1591
1592 void wolfSSL_ERR_print_errors_fp(FILE* fp, int err)
1593 {
1594     char data[WOLFSSL_MAX_ERROR_SZ + 1];
1595
1596     WOLFSSL_ENTER("wolfSSL_ERR_print_errors_fp");
1597     SetErrorString(err, data);
1598     fprintf(fp, "%s", data);
1599 }
1600
1601 #endif
1602
1603
1604 int wolfSSL_pending(WOLFSSL* ssl)
1605 {
1606     WOLFSSL_ENTER("SSL_pending");
1607     return ssl->buffers.clearOutputBuffer.length;
1608 }
1609
1610
1611 #ifndef WOLFSSL_LEANPSK
1612 /* trun on handshake group messages for context */
1613 int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx)
1614 {
1615     if (ctx == NULL)
1616        return BAD_FUNC_ARG;
1617
1618     ctx->groupMessages = 1;
1619
1620     return SSL_SUCCESS;
1621 }
1622 #endif
1623
1624
1625 #ifndef NO_WOLFSSL_CLIENT
1626 /* connect enough to get peer cert chain */
1627 int wolfSSL_connect_cert(WOLFSSL* ssl)
1628 {
1629     int  ret;
1630
1631     if (ssl == NULL)
1632         return SSL_FAILURE;
1633
1634     ssl->options.certOnly = 1;
1635     ret = wolfSSL_connect(ssl);
1636     ssl->options.certOnly   = 0;
1637
1638     return ret;
1639 }
1640 #endif
1641
1642
1643 #ifndef WOLFSSL_LEANPSK
1644 /* trun on handshake group messages for ssl object */
1645 int wolfSSL_set_group_messages(WOLFSSL* ssl)
1646 {
1647     if (ssl == NULL)
1648        return BAD_FUNC_ARG;
1649
1650     ssl->options.groupMessages = 1;
1651
1652     return SSL_SUCCESS;
1653 }
1654
1655
1656 /* make minVersion the internal equivilant SSL version */
1657 static int SetMinVersionHelper(byte* minVersion, int version)
1658 {
1659     switch (version) {
1660 #ifndef NO_OLD_TLS
1661         case WOLFSSL_SSLV3:
1662             *minVersion = SSLv3_MINOR;
1663             break;
1664 #endif
1665
1666 #ifndef NO_TLS
1667     #ifndef NO_OLD_TLS
1668         case WOLFSSL_TLSV1:
1669             *minVersion = TLSv1_MINOR;
1670             break;
1671
1672         case WOLFSSL_TLSV1_1:
1673             *minVersion = TLSv1_1_MINOR;
1674             break;
1675     #endif
1676         case WOLFSSL_TLSV1_2:
1677             *minVersion = TLSv1_2_MINOR;
1678             break;
1679 #endif
1680
1681         default:
1682             WOLFSSL_MSG("Bad function argument");
1683             return BAD_FUNC_ARG;
1684     }
1685
1686     return SSL_SUCCESS;
1687 }
1688
1689
1690 /* Set minimum downgrade version allowed, SSL_SUCCESS on ok */
1691 int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version)
1692 {
1693     WOLFSSL_ENTER("wolfSSL_CTX_SetMinVersion");
1694
1695     if (ctx == NULL) {
1696         WOLFSSL_MSG("Bad function argument");
1697         return BAD_FUNC_ARG;
1698     }
1699
1700     return SetMinVersionHelper(&ctx->minDowngrade, version);
1701 }
1702
1703
1704 /* Set minimum downgrade version allowed, SSL_SUCCESS on ok */
1705 int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version)
1706 {
1707     WOLFSSL_ENTER("wolfSSL_SetMinVersion");
1708
1709     if (ssl == NULL) {
1710         WOLFSSL_MSG("Bad function argument");
1711         return BAD_FUNC_ARG;
1712     }
1713
1714     return SetMinVersionHelper(&ssl->options.minDowngrade, version);
1715 }
1716
1717
1718 int wolfSSL_SetVersion(WOLFSSL* ssl, int version)
1719 {
1720     byte haveRSA = 1;
1721     byte havePSK = 0;
1722
1723     WOLFSSL_ENTER("wolfSSL_SetVersion");
1724
1725     if (ssl == NULL) {
1726         WOLFSSL_MSG("Bad function argument");
1727         return BAD_FUNC_ARG;
1728     }
1729
1730     switch (version) {
1731 #ifndef NO_OLD_TLS
1732         case WOLFSSL_SSLV3:
1733             ssl->version = MakeSSLv3();
1734             break;
1735 #endif
1736
1737 #ifndef NO_TLS
1738     #ifndef NO_OLD_TLS
1739         case WOLFSSL_TLSV1:
1740             ssl->version = MakeTLSv1();
1741             break;
1742
1743         case WOLFSSL_TLSV1_1:
1744             ssl->version = MakeTLSv1_1();
1745             break;
1746     #endif
1747         case WOLFSSL_TLSV1_2:
1748             ssl->version = MakeTLSv1_2();
1749             break;
1750 #endif
1751
1752         default:
1753             WOLFSSL_MSG("Bad function argument");
1754             return BAD_FUNC_ARG;
1755     }
1756
1757     #ifdef NO_RSA
1758         haveRSA = 0;
1759     #endif
1760     #ifndef NO_PSK
1761         havePSK = ssl->options.havePSK;
1762     #endif
1763
1764     InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH,
1765                 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
1766                 ssl->options.haveStaticECC, ssl->options.side);
1767
1768     return SSL_SUCCESS;
1769 }
1770 #endif /* !leanpsk */
1771
1772
1773 #if !defined(NO_CERTS) || !defined(NO_SESSION_CACHE)
1774
1775 /* Make a work from the front of random hash */
1776 static INLINE word32 MakeWordFromHash(const byte* hashID)
1777 {
1778     return (hashID[0] << 24) | (hashID[1] << 16) | (hashID[2] <<  8) |
1779             hashID[3];
1780 }
1781
1782 #endif /* !NO_CERTS || !NO_SESSION_CACHE */
1783
1784
1785 #ifndef NO_CERTS
1786
1787 /* hash is the SHA digest of name, just use first 32 bits as hash */
1788 static INLINE word32 HashSigner(const byte* hash)
1789 {
1790     return MakeWordFromHash(hash) % CA_TABLE_SIZE;
1791 }
1792
1793
1794 /* does CA already exist on signer list */
1795 int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash)
1796 {
1797     Signer* signers;
1798     int     ret = 0;
1799     word32  row = HashSigner(hash);
1800
1801     if (LockMutex(&cm->caLock) != 0)
1802         return  ret;
1803     signers = cm->caTable[row];
1804     while (signers) {
1805         byte* subjectHash;
1806         #ifndef NO_SKID
1807             subjectHash = signers->subjectKeyIdHash;
1808         #else
1809             subjectHash = signers->subjectNameHash;
1810         #endif
1811         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
1812             ret = 1;
1813             break;
1814         }
1815         signers = signers->next;
1816     }
1817     UnLockMutex(&cm->caLock);
1818
1819     return ret;
1820 }
1821
1822
1823 /* return CA if found, otherwise NULL */
1824 Signer* GetCA(void* vp, byte* hash)
1825 {
1826     WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
1827     Signer* ret = NULL;
1828     Signer* signers;
1829     word32  row = HashSigner(hash);
1830
1831     if (cm == NULL)
1832         return NULL;
1833
1834     if (LockMutex(&cm->caLock) != 0)
1835         return ret;
1836
1837     signers = cm->caTable[row];
1838     while (signers) {
1839         byte* subjectHash;
1840         #ifndef NO_SKID
1841             subjectHash = signers->subjectKeyIdHash;
1842         #else
1843             subjectHash = signers->subjectNameHash;
1844         #endif
1845         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
1846             ret = signers;
1847             break;
1848         }
1849         signers = signers->next;
1850     }
1851     UnLockMutex(&cm->caLock);
1852
1853     return ret;
1854 }
1855
1856
1857 #ifndef NO_SKID
1858 /* return CA if found, otherwise NULL. Walk through hash table. */
1859 Signer* GetCAByName(void* vp, byte* hash)
1860 {
1861     WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
1862     Signer* ret = NULL;
1863     Signer* signers;
1864     word32  row;
1865
1866     if (cm == NULL)
1867         return NULL;
1868
1869     if (LockMutex(&cm->caLock) != 0)
1870         return ret;
1871
1872     for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
1873         signers = cm->caTable[row];
1874         while (signers && ret == NULL) {
1875             if (XMEMCMP(hash,
1876                            signers->subjectNameHash, SIGNER_DIGEST_SIZE) == 0) {
1877                 ret = signers;
1878             }
1879             signers = signers->next;
1880         }
1881     }
1882     UnLockMutex(&cm->caLock);
1883
1884     return ret;
1885 }
1886 #endif
1887
1888
1889 /* owns der, internal now uses too */
1890 /* type flag ids from user or from chain received during verify
1891    don't allow chain ones to be added w/o isCA extension */
1892 int AddCA(WOLFSSL_CERT_MANAGER* cm, buffer der, int type, int verify)
1893 {
1894     int         ret;
1895     Signer*     signer = 0;
1896     word32      row;
1897     byte*       subjectHash;
1898 #ifdef WOLFSSL_SMALL_STACK
1899     DecodedCert* cert = NULL;
1900 #else
1901     DecodedCert  cert[1];
1902 #endif
1903
1904     WOLFSSL_MSG("Adding a CA");
1905
1906 #ifdef WOLFSSL_SMALL_STACK
1907     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
1908                                                        DYNAMIC_TYPE_TMP_BUFFER);
1909     if (cert == NULL)
1910         return MEMORY_E;
1911 #endif
1912
1913     InitDecodedCert(cert, der.buffer, der.length, cm->heap);
1914     ret = ParseCert(cert, CA_TYPE, verify, cm);
1915     WOLFSSL_MSG("    Parsed new CA");
1916
1917 #ifndef NO_SKID
1918     subjectHash = cert->extSubjKeyId;
1919 #else
1920     subjectHash = cert->subjectHash;
1921 #endif
1922
1923     if (ret == 0 && cert->isCA == 0 && type != WOLFSSL_USER_CA) {
1924         WOLFSSL_MSG("    Can't add as CA if not actually one");
1925         ret = NOT_CA_ERROR;
1926     }
1927 #ifndef ALLOW_INVALID_CERTSIGN
1928     else if (ret == 0 && cert->isCA == 1 && type != WOLFSSL_USER_CA &&
1929                               (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) == 0) {
1930         /* Intermediate CA certs are required to have the keyCertSign
1931         * extension set. User loaded root certs are not. */
1932         WOLFSSL_MSG("    Doesn't have key usage certificate signing");
1933         ret = NOT_CA_ERROR;
1934     }
1935 #endif
1936     else if (ret == 0 && AlreadySigner(cm, subjectHash)) {
1937         WOLFSSL_MSG("    Already have this CA, not adding again");
1938         (void)ret;
1939     }
1940     else if (ret == 0) {
1941         /* take over signer parts */
1942         signer = MakeSigner(cm->heap);
1943         if (!signer)
1944             ret = MEMORY_ERROR;
1945         else {
1946             signer->keyOID         = cert->keyOID;
1947             signer->publicKey      = cert->publicKey;
1948             signer->pubKeySize     = cert->pubKeySize;
1949             signer->nameLen        = cert->subjectCNLen;
1950             signer->name           = cert->subjectCN;
1951         #ifndef IGNORE_NAME_CONSTRAINTS
1952             signer->permittedNames = cert->permittedNames;
1953             signer->excludedNames  = cert->excludedNames;
1954         #endif
1955         #ifndef NO_SKID
1956             XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
1957                                                             SIGNER_DIGEST_SIZE);
1958         #endif
1959             XMEMCPY(signer->subjectNameHash, cert->subjectHash,
1960                                                             SIGNER_DIGEST_SIZE);
1961             signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
1962                                                     : 0xFFFF;
1963             signer->next    = NULL; /* If Key Usage not set, all uses valid. */
1964             cert->publicKey = 0;    /* in case lock fails don't free here.   */
1965             cert->subjectCN = 0;
1966         #ifndef IGNORE_NAME_CONSTRAINTS
1967             cert->permittedNames = NULL;
1968             cert->excludedNames = NULL;
1969         #endif
1970
1971         #ifndef NO_SKID
1972             row = HashSigner(signer->subjectKeyIdHash);
1973         #else
1974             row = HashSigner(signer->subjectNameHash);
1975         #endif
1976
1977             if (LockMutex(&cm->caLock) == 0) {
1978                 signer->next = cm->caTable[row];
1979                 cm->caTable[row] = signer;   /* takes ownership */
1980                 UnLockMutex(&cm->caLock);
1981                 if (cm->caCacheCallback)
1982                     cm->caCacheCallback(der.buffer, (int)der.length, type);
1983             }
1984             else {
1985                 WOLFSSL_MSG("    CA Mutex Lock failed");
1986                 ret = BAD_MUTEX_E;
1987                 FreeSigner(signer, cm->heap);
1988             }
1989         }
1990     }
1991
1992     WOLFSSL_MSG("    Freeing Parsed CA");
1993     FreeDecodedCert(cert);
1994 #ifdef WOLFSSL_SMALL_STACK
1995     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1996 #endif
1997     WOLFSSL_MSG("    Freeing der CA");
1998     XFREE(der.buffer, cm->heap, DYNAMIC_TYPE_CA);
1999     WOLFSSL_MSG("        OK Freeing der CA");
2000
2001     WOLFSSL_LEAVE("AddCA", ret);
2002
2003     return ret == 0 ? SSL_SUCCESS : ret;
2004 }
2005
2006 #endif /* !NO_CERTS */
2007
2008
2009 #ifndef NO_SESSION_CACHE
2010
2011     /* basic config gives a cache with 33 sessions, adequate for clients and
2012        embedded servers
2013
2014        MEDIUM_SESSION_CACHE allows 1055 sessions, adequate for servers that
2015        aren't under heavy load, basically allows 200 new sessions per minute
2016
2017        BIG_SESSION_CACHE yields 20,027 sessions
2018
2019        HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
2020        allows over 13,000 new sessions per minute or over 200 new sessions per
2021        second
2022
2023        SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients
2024        or systems where the default of nearly 3kB is too much RAM, this define
2025        uses less than 500 bytes RAM
2026
2027        default SESSION_CACHE stores 33 sessions (no XXX_SESSION_CACHE defined)
2028     */
2029     #ifdef HUGE_SESSION_CACHE
2030         #define SESSIONS_PER_ROW 11
2031         #define SESSION_ROWS 5981
2032     #elif defined(BIG_SESSION_CACHE)
2033         #define SESSIONS_PER_ROW 7
2034         #define SESSION_ROWS 2861
2035     #elif defined(MEDIUM_SESSION_CACHE)
2036         #define SESSIONS_PER_ROW 5
2037         #define SESSION_ROWS 211
2038     #elif defined(SMALL_SESSION_CACHE)
2039         #define SESSIONS_PER_ROW 2
2040         #define SESSION_ROWS 3
2041     #else
2042         #define SESSIONS_PER_ROW 3
2043         #define SESSION_ROWS 11
2044     #endif
2045
2046     typedef struct SessionRow {
2047         int nextIdx;                           /* where to place next one   */
2048         int totalCount;                        /* sessions ever on this row */
2049         WOLFSSL_SESSION Sessions[SESSIONS_PER_ROW];
2050     } SessionRow;
2051
2052     static SessionRow SessionCache[SESSION_ROWS];
2053
2054     #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
2055         static word32 PeakSessions;
2056     #endif
2057
2058     static wolfSSL_Mutex session_mutex;   /* SessionCache mutex */
2059
2060     #ifndef NO_CLIENT_CACHE
2061
2062         typedef struct ClientSession {
2063             word16 serverRow;            /* SessionCache Row id */
2064             word16 serverIdx;            /* SessionCache Idx (column) */
2065         } ClientSession;
2066
2067         typedef struct ClientRow {
2068             int nextIdx;                /* where to place next one   */
2069             int totalCount;             /* sessions ever on this row */
2070             ClientSession Clients[SESSIONS_PER_ROW];
2071         } ClientRow;
2072
2073         static ClientRow ClientCache[SESSION_ROWS];  /* Client Cache */
2074                                                      /* uses session mutex */
2075     #endif  /* NO_CLIENT_CACHE */
2076
2077 #endif /* NO_SESSION_CACHE */
2078
2079
2080 int wolfSSL_Init(void)
2081 {
2082     int ret = SSL_SUCCESS;
2083
2084     WOLFSSL_ENTER("wolfSSL_Init");
2085
2086     if (initRefCount == 0) {
2087 #ifndef NO_SESSION_CACHE
2088         if (InitMutex(&session_mutex) != 0)
2089             ret = BAD_MUTEX_E;
2090 #endif
2091         if (InitMutex(&count_mutex) != 0)
2092             ret = BAD_MUTEX_E;
2093     }
2094     if (ret == SSL_SUCCESS) {
2095         if (LockMutex(&count_mutex) != 0) {
2096             WOLFSSL_MSG("Bad Lock Mutex count");
2097             return BAD_MUTEX_E;
2098         }
2099         initRefCount++;
2100         UnLockMutex(&count_mutex);
2101     }
2102
2103     return ret;
2104 }
2105
2106
2107 #ifndef NO_CERTS
2108
2109 static const char* BEGIN_CERT         = "-----BEGIN CERTIFICATE-----";
2110 static const char* END_CERT           = "-----END CERTIFICATE-----";
2111 static const char* BEGIN_CERT_REQ     = "-----BEGIN CERTIFICATE REQUEST-----";
2112 static const char* END_CERT_REQ       = "-----END CERTIFICATE REQUEST-----";
2113 static const char* BEGIN_DH_PARAM     = "-----BEGIN DH PARAMETERS-----";
2114 static const char* END_DH_PARAM       = "-----END DH PARAMETERS-----";
2115 static const char* BEGIN_X509_CRL     = "-----BEGIN X509 CRL-----";
2116 static const char* END_X509_CRL       = "-----END X509 CRL-----";
2117 static const char* BEGIN_RSA_PRIV     = "-----BEGIN RSA PRIVATE KEY-----";
2118 static const char* END_RSA_PRIV       = "-----END RSA PRIVATE KEY-----";
2119 static const char* BEGIN_PRIV_KEY     = "-----BEGIN PRIVATE KEY-----";
2120 static const char* END_PRIV_KEY       = "-----END PRIVATE KEY-----";
2121 static const char* BEGIN_ENC_PRIV_KEY = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
2122 static const char* END_ENC_PRIV_KEY   = "-----END ENCRYPTED PRIVATE KEY-----";
2123 static const char* BEGIN_EC_PRIV      = "-----BEGIN EC PRIVATE KEY-----";
2124 static const char* END_EC_PRIV        = "-----END EC PRIVATE KEY-----";
2125 static const char* BEGIN_DSA_PRIV     = "-----BEGIN DSA PRIVATE KEY-----";
2126 static const char* END_DSA_PRIV       = "-----END DSA PRIVATE KEY-----";
2127
2128 /* Remove PEM header/footer, convert to ASN1, store any encrypted data
2129    info->consumed tracks of PEM bytes consumed in case multiple parts */
2130 int PemToDer(const unsigned char* buff, long longSz, int type,
2131                   buffer* der, void* heap, EncryptedInfo* info, int* eccKey)
2132 {
2133     const char* header      = NULL;
2134     const char* footer      = NULL;
2135     char*       headerEnd;
2136     char*       footerEnd;
2137     char*       consumedEnd;
2138     char*       bufferEnd   = (char*)(buff + longSz);
2139     long        neededSz;
2140     int         ret         = 0;
2141     int         dynamicType = 0;
2142     int         sz          = (int)longSz;
2143
2144     switch (type) {
2145         case CA_TYPE:       /* same as below */
2146         case CERT_TYPE:     header= BEGIN_CERT;     footer= END_CERT;     break;
2147         case CRL_TYPE:      header= BEGIN_X509_CRL; footer= END_X509_CRL; break;
2148         case DH_PARAM_TYPE: header= BEGIN_DH_PARAM; footer= END_DH_PARAM; break;
2149         case CERTREQ_TYPE:  header= BEGIN_CERT_REQ; footer= END_CERT_REQ; break;
2150         default:            header= BEGIN_RSA_PRIV; footer= END_RSA_PRIV; break;
2151     }
2152     
2153     switch (type) {
2154         case CA_TYPE:   dynamicType = DYNAMIC_TYPE_CA;   break;
2155         case CERT_TYPE: dynamicType = DYNAMIC_TYPE_CERT; break;
2156         case CRL_TYPE:  dynamicType = DYNAMIC_TYPE_CRL;  break;
2157         default:        dynamicType = DYNAMIC_TYPE_KEY;  break;
2158     }
2159
2160     /* find header */
2161     for (;;) {
2162         headerEnd = XSTRNSTR((char*)buff, header, sz);
2163         
2164         if (headerEnd || type != PRIVATEKEY_TYPE) {
2165             break;
2166         } else if (header == BEGIN_RSA_PRIV) {
2167                    header =  BEGIN_PRIV_KEY;       footer = END_PRIV_KEY;
2168         } else if (header == BEGIN_PRIV_KEY) {
2169                    header =  BEGIN_ENC_PRIV_KEY;   footer = END_ENC_PRIV_KEY;
2170         } else if (header == BEGIN_ENC_PRIV_KEY) {
2171                    header =  BEGIN_EC_PRIV;        footer = END_EC_PRIV;
2172         } else if (header == BEGIN_EC_PRIV) {
2173                    header =  BEGIN_DSA_PRIV;       footer = END_DSA_PRIV;
2174         } else
2175             break;
2176     }
2177
2178     if (!headerEnd) {
2179         WOLFSSL_MSG("Couldn't find PEM header");
2180         return SSL_NO_PEM_HEADER;
2181     }
2182
2183     headerEnd += XSTRLEN(header);
2184
2185     /* eat end of line */
2186     if (headerEnd[0] == '\n')
2187         headerEnd++;
2188     else if (headerEnd[1] == '\n')
2189         headerEnd += 2;
2190     else
2191         return SSL_BAD_FILE;
2192
2193     if (type == PRIVATEKEY_TYPE) {
2194         if (eccKey)
2195             *eccKey = header == BEGIN_EC_PRIV;      
2196     }
2197
2198 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
2199     {
2200         /* remove encrypted header if there */
2201         char encHeader[] = "Proc-Type";
2202         char* line = XSTRNSTR(headerEnd, encHeader, PEM_LINE_LEN);
2203         if (line) {
2204             char* newline;
2205             char* finish;
2206             char* start  = XSTRNSTR(line, "DES", PEM_LINE_LEN);
2207
2208             if (!start)
2209                 start = XSTRNSTR(line, "AES", PEM_LINE_LEN);
2210
2211             if (!start) return SSL_BAD_FILE;
2212             if (!info)  return SSL_BAD_FILE;
2213
2214             finish = XSTRNSTR(start, ",", PEM_LINE_LEN);
2215
2216             if (start && finish && (start < finish)) {
2217                 newline = XSTRNSTR(finish, "\r", PEM_LINE_LEN);
2218
2219                 XMEMCPY(info->name, start, finish - start);
2220                 info->name[finish - start] = 0;
2221                 XMEMCPY(info->iv, finish + 1, sizeof(info->iv));
2222
2223                 if (!newline) newline = XSTRNSTR(finish, "\n", PEM_LINE_LEN);
2224                 if (newline && (newline > finish)) {
2225                     info->ivSz = (word32)(newline - (finish + 1));
2226                     info->set = 1;
2227                 }
2228                 else
2229                     return SSL_BAD_FILE;
2230             }
2231             else
2232                 return SSL_BAD_FILE;
2233
2234             /* eat blank line */
2235             while (*newline == '\r' || *newline == '\n')
2236                 newline++;
2237             headerEnd = newline;
2238         }
2239     }
2240 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
2241
2242     /* find footer */
2243     footerEnd = XSTRNSTR((char*)buff, footer, sz);
2244     if (!footerEnd)
2245         return SSL_BAD_FILE;
2246
2247     consumedEnd = footerEnd + XSTRLEN(footer);
2248
2249     if (consumedEnd < bufferEnd) {  /* handle no end of line on last line */
2250         /* eat end of line */
2251         if (consumedEnd[0] == '\n')
2252             consumedEnd++;
2253         else if (consumedEnd[1] == '\n')
2254             consumedEnd += 2;
2255         else
2256             return SSL_BAD_FILE;
2257     }
2258
2259     if (info)
2260         info->consumed = (long)(consumedEnd - (char*)buff);
2261
2262     /* set up der buffer */
2263     neededSz = (long)(footerEnd - headerEnd);
2264     if (neededSz > sz || neededSz < 0)
2265         return SSL_BAD_FILE;
2266
2267     der->buffer = (byte*)XMALLOC(neededSz, heap, dynamicType);
2268     if (!der->buffer)
2269         return MEMORY_ERROR;
2270
2271     der->length = (word32)neededSz;
2272
2273     if (Base64_Decode((byte*)headerEnd, (word32)neededSz, der->buffer,
2274                                                               &der->length) < 0)
2275         return SSL_BAD_FILE;
2276
2277     if (header == BEGIN_PRIV_KEY) {
2278         /* pkcs8 key, convert and adjust length */
2279         if ((ret = ToTraditional(der->buffer, der->length)) < 0)
2280             return ret;
2281
2282         der->length = ret;
2283         return 0;
2284     }
2285
2286 #if (defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)) && !defined(NO_PWDBASED)
2287     if (header == BEGIN_ENC_PRIV_KEY) {
2288         int   passwordSz;
2289     #ifdef WOLFSSL_SMALL_STACK
2290         char* password = NULL;
2291     #else
2292         char  password[80];
2293     #endif
2294
2295         if (!info || !info->ctx || !info->ctx->passwd_cb)
2296             return SSL_BAD_FILE;  /* no callback error */
2297
2298     #ifdef WOLFSSL_SMALL_STACK
2299         password = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2300         if (password == NULL)
2301             return MEMORY_E;
2302     #endif
2303         passwordSz = info->ctx->passwd_cb(password, sizeof(password), 0,
2304                                                            info->ctx->userdata);
2305         /* convert and adjust length */
2306         ret = ToTraditionalEnc(der->buffer, der->length, password, passwordSz);
2307
2308     #ifdef WOLFSSL_SMALL_STACK
2309         XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2310     #endif
2311
2312         if (ret < 0)
2313             return ret;
2314
2315         der->length = ret;
2316         return 0;
2317     }
2318 #endif
2319
2320     return 0;
2321 }
2322
2323
2324 /* process the buffer buff, legnth sz, into ctx of format and type
2325    used tracks bytes consumed, userChain specifies a user cert chain
2326    to pass during the handshake */
2327 static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
2328                          long sz, int format, int type, WOLFSSL* ssl,
2329                          long* used, int userChain)
2330 {
2331     buffer        der;        /* holds DER or RAW (for NTRU) */
2332     int           ret;
2333     int           dynamicType = 0;
2334     int           eccKey = 0;
2335     int           rsaKey = 0;
2336     void*         heap = ctx ? ctx->heap : NULL;
2337 #ifdef WOLFSSL_SMALL_STACK
2338     EncryptedInfo* info = NULL;
2339 #else
2340     EncryptedInfo  info[1];
2341 #endif
2342
2343     (void)dynamicType;
2344     (void)rsaKey;
2345
2346     if (used)
2347         *used = sz;     /* used bytes default to sz, PEM chain may shorten*/
2348
2349     if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM
2350                                     && format != SSL_FILETYPE_RAW)
2351         return SSL_BAD_FILETYPE;
2352
2353     if (ctx == NULL && ssl == NULL)
2354         return BAD_FUNC_ARG;
2355
2356     if (type == CA_TYPE)
2357         dynamicType = DYNAMIC_TYPE_CA;
2358     else if (type == CERT_TYPE)
2359         dynamicType = DYNAMIC_TYPE_CERT;
2360     else
2361         dynamicType = DYNAMIC_TYPE_KEY;
2362
2363 #ifdef WOLFSSL_SMALL_STACK
2364     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
2365                                                        DYNAMIC_TYPE_TMP_BUFFER);
2366     if (info == NULL)
2367         return MEMORY_E;
2368 #endif
2369
2370     info->set      = 0;
2371     info->ctx      = ctx;
2372     info->consumed = 0;
2373     der.buffer     = 0;
2374
2375     if (format == SSL_FILETYPE_PEM) {
2376         ret = PemToDer(buff, sz, type, &der, heap, info, &eccKey);
2377         if (ret < 0) {
2378         #ifdef WOLFSSL_SMALL_STACK
2379             XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2380         #endif
2381             XFREE(der.buffer, heap, dynamicType);
2382             return ret;
2383         }
2384
2385         if (used)
2386             *used = info->consumed;
2387
2388         /* we may have a user cert chain, try to consume */
2389         if (userChain && type == CERT_TYPE && info->consumed < sz) {
2390         #ifdef WOLFSSL_SMALL_STACK
2391             byte   staticBuffer[1];                 /* force heap usage */
2392         #else
2393             byte   staticBuffer[FILE_BUFFER_SIZE];  /* tmp chain buffer */
2394         #endif
2395             byte*  chainBuffer = staticBuffer;
2396             byte*  shrinked    = NULL;   /* shrinked to size chainBuffer
2397                                           * or staticBuffer */
2398             int    dynamicBuffer = 0;
2399             word32 bufferSz = sizeof(staticBuffer);
2400             long   consumed = info->consumed;
2401             word32 idx = 0;
2402             int    gotOne = 0;
2403
2404             if ( (sz - consumed) > (int)bufferSz) {
2405                 WOLFSSL_MSG("Growing Tmp Chain Buffer");
2406                 bufferSz = (word32)(sz - consumed);
2407                            /* will shrink to actual size */
2408                 chainBuffer = (byte*)XMALLOC(bufferSz, heap, DYNAMIC_TYPE_FILE);
2409                 if (chainBuffer == NULL) {
2410                 #ifdef WOLFSSL_SMALL_STACK
2411                     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2412                 #endif
2413                     XFREE(der.buffer, heap, dynamicType);
2414                     return MEMORY_E;
2415                 }
2416                 dynamicBuffer = 1;
2417             }
2418
2419             WOLFSSL_MSG("Processing Cert Chain");
2420             while (consumed < sz) {
2421                 buffer part;
2422                 info->consumed = 0;
2423                 part.buffer = 0;
2424
2425                 ret = PemToDer(buff + consumed, sz - consumed, type, &part,
2426                                                            heap, info, &eccKey);
2427                 if (ret == 0) {
2428                     gotOne = 1;
2429                     if ( (idx + part.length) > bufferSz) {
2430                         WOLFSSL_MSG("   Cert Chain bigger than buffer");
2431                         ret = BUFFER_E;
2432                     }
2433                     else {
2434                         c32to24(part.length, &chainBuffer[idx]);
2435                         idx += CERT_HEADER_SZ;
2436                         XMEMCPY(&chainBuffer[idx], part.buffer,part.length);
2437                         idx += part.length;
2438                         consumed  += info->consumed;
2439                         if (used)
2440                             *used += info->consumed;
2441                     }
2442                 }
2443
2444                 XFREE(part.buffer, heap, dynamicType);
2445
2446                 if (ret == SSL_NO_PEM_HEADER && gotOne) {
2447                     WOLFSSL_MSG("We got one good PEM so stuff at end ok");
2448                     break;
2449                 }
2450
2451                 if (ret < 0) {
2452                     WOLFSSL_MSG("   Error in Cert in Chain");
2453                     if (dynamicBuffer)
2454                         XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
2455                 #ifdef WOLFSSL_SMALL_STACK
2456                     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2457                 #endif
2458                     XFREE(der.buffer, heap, dynamicType);
2459                     return ret;
2460                 }
2461                 WOLFSSL_MSG("   Consumed another Cert in Chain");
2462             }
2463             WOLFSSL_MSG("Finished Processing Cert Chain");
2464
2465             /* only retain actual size used */
2466             shrinked = (byte*)XMALLOC(idx, heap, dynamicType);
2467             if (shrinked) {
2468                 if (ssl) {
2469                     if (ssl->buffers.certChain.buffer &&
2470                                                   ssl->buffers.weOwnCertChain) {
2471                         XFREE(ssl->buffers.certChain.buffer, heap,
2472                               dynamicType);
2473                     }
2474                     ssl->buffers.certChain.buffer = shrinked;
2475                     ssl->buffers.certChain.length = idx;
2476                     XMEMCPY(ssl->buffers.certChain.buffer, chainBuffer,idx);
2477                     ssl->buffers.weOwnCertChain = 1;
2478                 } else if (ctx) {
2479                     if (ctx->certChain.buffer)
2480                         XFREE(ctx->certChain.buffer, heap, dynamicType);
2481                     ctx->certChain.buffer = shrinked;
2482                     ctx->certChain.length = idx;
2483                     XMEMCPY(ctx->certChain.buffer, chainBuffer, idx);
2484                 }
2485             }
2486
2487             if (dynamicBuffer)
2488                 XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
2489
2490             if (shrinked == NULL) {
2491             #ifdef WOLFSSL_SMALL_STACK
2492                 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2493             #endif
2494                 XFREE(der.buffer, heap, dynamicType);
2495                 return MEMORY_E;
2496             }
2497         }
2498     }
2499     else {  /* ASN1 (DER) or RAW (NTRU) */
2500         der.buffer = (byte*) XMALLOC(sz, heap, dynamicType);
2501         if (!der.buffer) {
2502         #ifdef WOLFSSL_SMALL_STACK
2503             XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2504         #endif
2505             return MEMORY_ERROR;
2506         }
2507
2508         XMEMCPY(der.buffer, buff, sz);
2509         der.length = (word32)sz;
2510     }
2511
2512 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
2513     if (info->set) {
2514         /* decrypt */
2515         int   passwordSz;
2516 #ifdef WOLFSSL_SMALL_STACK
2517         char* password = NULL;
2518         byte* key      = NULL;
2519         byte* iv       = NULL;
2520 #else
2521         char  password[80];
2522         byte  key[AES_256_KEY_SIZE];
2523         #ifndef NO_MD5
2524         byte  iv[AES_IV_SIZE];
2525         #endif
2526 #endif
2527
2528     #ifdef WOLFSSL_SMALL_STACK
2529         password = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2530         key      = (byte*)XMALLOC(AES_256_KEY_SIZE, NULL,
2531                                                    DYNAMIC_TYPE_TMP_BUFFER);
2532         iv       = (byte*)XMALLOC(AES_IV_SIZE, NULL, 
2533                                                    DYNAMIC_TYPE_TMP_BUFFER);
2534
2535         if (password == NULL || key == NULL || iv == NULL) {
2536             XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2537             XFREE(key,      NULL, DYNAMIC_TYPE_TMP_BUFFER);
2538             XFREE(iv,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
2539             ret = MEMORY_E;
2540         }
2541         else
2542     #endif
2543         if (!ctx || !ctx->passwd_cb) {
2544             ret = NO_PASSWORD;
2545         }
2546         else {
2547             passwordSz = ctx->passwd_cb(password, sizeof(password), 0,
2548                                                              ctx->userdata);
2549
2550             /* use file's salt for key derivation, hex decode first */
2551             if (Base16_Decode(info->iv, info->ivSz, info->iv, &info->ivSz)
2552                                                                          != 0) {
2553                 ret = ASN_INPUT_E;
2554             }
2555 #ifndef NO_MD5
2556             else if ((ret = EVP_BytesToKey(info->name, "MD5", info->iv,
2557                            (byte*)password, passwordSz, 1, key, iv)) <= 0) {
2558                 /* empty */
2559             }
2560 #endif
2561 #ifndef NO_DES3
2562             else if (XSTRNCMP(info->name, "DES-CBC", 7) == 0) {
2563                 ret = wc_Des_CbcDecryptWithKey(der.buffer, der.buffer, der.length,
2564                                                                  key, info->iv);
2565             }
2566             else if (XSTRNCMP(info->name, "DES-EDE3-CBC", 13) == 0) {
2567                 ret = wc_Des3_CbcDecryptWithKey(der.buffer, der.buffer, der.length,
2568                                                                  key, info->iv);
2569             }
2570 #endif
2571 #ifndef NO_AES
2572             else if (XSTRNCMP(info->name, "AES-128-CBC", 13) == 0) {
2573                 ret = wc_AesCbcDecryptWithKey(der.buffer, der.buffer, der.length,
2574                                                key, AES_128_KEY_SIZE, info->iv);
2575             }
2576             else if (XSTRNCMP(info->name, "AES-192-CBC", 13) == 0) {
2577                 ret = wc_AesCbcDecryptWithKey(der.buffer, der.buffer, der.length,
2578                                                key, AES_192_KEY_SIZE, info->iv);
2579             }
2580             else if (XSTRNCMP(info->name, "AES-256-CBC", 13) == 0) {
2581                 ret = wc_AesCbcDecryptWithKey(der.buffer, der.buffer, der.length,
2582                                                key, AES_256_KEY_SIZE, info->iv);
2583             }
2584 #endif
2585             else {
2586                 ret = SSL_BAD_FILE;
2587             }
2588         }
2589
2590     #ifdef WOLFSSL_SMALL_STACK
2591         XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2592         XFREE(key,      NULL, DYNAMIC_TYPE_TMP_BUFFER);
2593         XFREE(iv,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
2594     #endif
2595
2596         if (ret != 0) {
2597         #ifdef WOLFSSL_SMALL_STACK
2598             XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2599         #endif
2600             XFREE(der.buffer, heap, dynamicType);
2601             return ret;
2602         }
2603     }
2604 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
2605
2606 #ifdef WOLFSSL_SMALL_STACK
2607     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2608 #endif
2609
2610     if (type == CA_TYPE) {
2611         if (ctx == NULL) {
2612             WOLFSSL_MSG("Need context for CA load");
2613             XFREE(der.buffer, heap, dynamicType);
2614             return BAD_FUNC_ARG;
2615         }
2616         return AddCA(ctx->cm, der, WOLFSSL_USER_CA, ctx->verifyPeer);
2617                                                       /* takes der over */
2618     }
2619     else if (type == CERT_TYPE) {
2620         if (ssl) {
2621             if (ssl->buffers.weOwnCert && ssl->buffers.certificate.buffer)
2622                 XFREE(ssl->buffers.certificate.buffer, heap, dynamicType);
2623             ssl->buffers.certificate = der;
2624             ssl->buffers.weOwnCert = 1;
2625         }
2626         else if (ctx) {
2627             if (ctx->certificate.buffer)
2628                 XFREE(ctx->certificate.buffer, heap, dynamicType);
2629             ctx->certificate = der;     /* takes der over */
2630         }
2631     }
2632     else if (type == PRIVATEKEY_TYPE) {
2633         if (ssl) {
2634             if (ssl->buffers.weOwnKey && ssl->buffers.key.buffer)
2635                 XFREE(ssl->buffers.key.buffer, heap, dynamicType);
2636             ssl->buffers.key = der;
2637             ssl->buffers.weOwnKey = 1;
2638         }
2639         else if (ctx) {
2640             if (ctx->privateKey.buffer)
2641                 XFREE(ctx->privateKey.buffer, heap, dynamicType);
2642             ctx->privateKey = der;      /* takes der over */
2643         }
2644     }
2645     else {
2646         XFREE(der.buffer, heap, dynamicType);
2647         return SSL_BAD_CERTTYPE;
2648     }
2649
2650     if (type == PRIVATEKEY_TYPE && format != SSL_FILETYPE_RAW) {
2651     #ifndef NO_RSA
2652         if (!eccKey) {
2653             /* make sure RSA key can be used */
2654             word32 idx = 0;
2655         #ifdef WOLFSSL_SMALL_STACK
2656             RsaKey* key = NULL;
2657         #else
2658             RsaKey  key[1];
2659         #endif
2660
2661         #ifdef WOLFSSL_SMALL_STACK
2662             key = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL,
2663                                                        DYNAMIC_TYPE_TMP_BUFFER);
2664             if (key == NULL)
2665                 return MEMORY_E;
2666         #endif
2667
2668             ret = wc_InitRsaKey(key, 0);
2669             if (ret == 0) {
2670                 if (wc_RsaPrivateKeyDecode(der.buffer, &idx, key, der.length) !=
2671                                                                             0) {
2672                 #ifdef HAVE_ECC
2673                     /* could have DER ECC (or pkcs8 ecc), no easy way to tell */
2674                     eccKey = 1;  /* so try it out */
2675                 #endif
2676                     if (!eccKey)
2677                         ret = SSL_BAD_FILE;
2678                 } else {
2679                     rsaKey = 1;
2680                     (void)rsaKey;  /* for no ecc builds */
2681                 }
2682             }
2683
2684             wc_FreeRsaKey(key);
2685
2686         #ifdef WOLFSSL_SMALL_STACK
2687             XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2688         #endif
2689
2690             if (ret != 0)
2691                 return ret;
2692         }
2693     #endif
2694     #ifdef HAVE_ECC
2695         if (!rsaKey) {
2696             /* make sure ECC key can be used */
2697             word32  idx = 0;
2698             ecc_key key;
2699
2700             wc_ecc_init(&key);
2701             if (wc_EccPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) {
2702                 wc_ecc_free(&key);
2703                 return SSL_BAD_FILE;
2704             }
2705             wc_ecc_free(&key);
2706             eccKey = 1;
2707             if (ctx)
2708                 ctx->haveStaticECC = 1;
2709             if (ssl)
2710                 ssl->options.haveStaticECC = 1;
2711         }
2712     #endif /* HAVE_ECC */
2713     }
2714     else if (type == CERT_TYPE) {
2715     #ifdef WOLFSSL_SMALL_STACK
2716         DecodedCert* cert = NULL;
2717     #else
2718         DecodedCert  cert[1];
2719     #endif
2720
2721     #ifdef WOLFSSL_SMALL_STACK
2722         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
2723                                                        DYNAMIC_TYPE_TMP_BUFFER);
2724         if (cert == NULL)
2725             return MEMORY_E;
2726     #endif
2727
2728         WOLFSSL_MSG("Checking cert signature type");
2729         InitDecodedCert(cert, der.buffer, der.length, heap);
2730
2731         if (DecodeToKey(cert, 0) < 0) {
2732             WOLFSSL_MSG("Decode to key failed");
2733         #ifdef WOLFSSL_SMALL_STACK
2734             XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2735         #endif
2736             return SSL_BAD_FILE;
2737         }
2738         switch (cert->signatureOID) {
2739             case CTC_SHAwECDSA:
2740             case CTC_SHA256wECDSA:
2741             case CTC_SHA384wECDSA:
2742             case CTC_SHA512wECDSA:
2743                 WOLFSSL_MSG("ECDSA cert signature");
2744                 if (ctx)
2745                     ctx->haveECDSAsig = 1;
2746                 if (ssl)
2747                     ssl->options.haveECDSAsig = 1;
2748                 break;
2749             default:
2750                 WOLFSSL_MSG("Not ECDSA cert signature");
2751                 break;
2752         }
2753
2754     #ifdef HAVE_ECC
2755         if (ctx)
2756             ctx->pkCurveOID = cert->pkCurveOID;
2757         if (ssl)
2758             ssl->pkCurveOID = cert->pkCurveOID;
2759     #endif
2760
2761         FreeDecodedCert(cert);
2762     #ifdef WOLFSSL_SMALL_STACK
2763         XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2764     #endif
2765     }
2766
2767     return SSL_SUCCESS;
2768 }
2769
2770
2771 /* CA PEM file for verification, may have multiple/chain certs to process */
2772 static int ProcessChainBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
2773                             long sz, int format, int type, WOLFSSL* ssl)
2774 {
2775     long used   = 0;
2776     int  ret    = 0;
2777     int  gotOne = 0;
2778
2779     WOLFSSL_MSG("Processing CA PEM file");
2780     while (used < sz) {
2781         long consumed = 0;
2782
2783         ret = ProcessBuffer(ctx, buff + used, sz - used, format, type, ssl,
2784                             &consumed, 0);
2785
2786         if (ret == SSL_NO_PEM_HEADER && gotOne) {
2787             WOLFSSL_MSG("We got one good PEM file so stuff at end ok");
2788             ret = SSL_SUCCESS;
2789             break;
2790         }
2791
2792         if (ret < 0)
2793             break;
2794
2795         WOLFSSL_MSG("   Processed a CA");
2796         gotOne = 1;
2797         used += consumed;
2798     }
2799
2800     return ret;
2801 }
2802
2803
2804 /* Verify the ceritficate, SSL_SUCCESS for ok, < 0 for error */
2805 int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
2806                                    long sz, int format)
2807 {
2808     int ret = 0;
2809     buffer der;
2810 #ifdef WOLFSSL_SMALL_STACK
2811     DecodedCert* cert = NULL;
2812 #else
2813     DecodedCert  cert[1];
2814 #endif
2815
2816     WOLFSSL_ENTER("wolfSSL_CertManagerVerifyBuffer");
2817
2818 #ifdef WOLFSSL_SMALL_STACK
2819     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
2820                                                        DYNAMIC_TYPE_TMP_BUFFER);
2821     if (cert == NULL)
2822         return MEMORY_E;
2823 #endif
2824
2825     der.buffer = NULL;
2826     der.length = 0;
2827
2828     if (format == SSL_FILETYPE_PEM) {
2829         int eccKey = 0; /* not used */
2830     #ifdef WOLFSSL_SMALL_STACK
2831         EncryptedInfo* info = NULL;
2832     #else
2833         EncryptedInfo  info[1];
2834     #endif
2835
2836     #ifdef WOLFSSL_SMALL_STACK
2837         info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
2838                                                        DYNAMIC_TYPE_TMP_BUFFER);
2839         if (info == NULL) {
2840             XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2841             return MEMORY_E;
2842         }
2843     #endif
2844
2845         info->set      = 0;
2846         info->ctx      = NULL;
2847         info->consumed = 0;
2848
2849         ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, info, &eccKey);
2850
2851         if (ret == 0)
2852             InitDecodedCert(cert, der.buffer, der.length, cm->heap);
2853
2854     #ifdef WOLFSSL_SMALL_STACK
2855         XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2856     #endif
2857     }
2858     else
2859         InitDecodedCert(cert, (byte*)buff, (word32)sz, cm->heap);
2860
2861     if (ret == 0)
2862         ret = ParseCertRelative(cert, CERT_TYPE, 1, cm);
2863
2864 #ifdef HAVE_CRL
2865     if (ret == 0 && cm->crlEnabled)
2866         ret = CheckCertCRL(cm->crl, cert);
2867 #endif
2868
2869     FreeDecodedCert(cert);
2870
2871     XFREE(der.buffer, cm->heap, DYNAMIC_TYPE_CERT);
2872 #ifdef WOLFSSL_SMALL_STACK
2873     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2874 #endif
2875
2876     return ret == 0 ? SSL_SUCCESS : ret;
2877 }
2878
2879
2880 /* turn on OCSP if off and compiled in, set options */
2881 int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, int options)
2882 {
2883     int ret = SSL_SUCCESS;
2884
2885     (void)options;
2886
2887     WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSP");
2888     if (cm == NULL)
2889         return BAD_FUNC_ARG;
2890
2891     #ifdef HAVE_OCSP
2892         if (cm->ocsp == NULL) {
2893             cm->ocsp = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), cm->heap,
2894                                                              DYNAMIC_TYPE_OCSP);
2895             if (cm->ocsp == NULL)
2896                 return MEMORY_E;
2897
2898             if (InitOCSP(cm->ocsp, cm) != 0) {
2899                 WOLFSSL_MSG("Init OCSP failed");
2900                 FreeOCSP(cm->ocsp, 1);
2901                 cm->ocsp = NULL;
2902                 return SSL_FAILURE;
2903             }
2904         }
2905         cm->ocspEnabled = 1;
2906         if (options & WOLFSSL_OCSP_URL_OVERRIDE)
2907             cm->ocspUseOverrideURL = 1;
2908         if (options & WOLFSSL_OCSP_NO_NONCE)
2909             cm->ocspSendNonce = 0;
2910         else
2911             cm->ocspSendNonce = 1;
2912         if (options & WOLFSSL_OCSP_CHECKALL)
2913             cm->ocspCheckAll = 1;
2914         #ifndef WOLFSSL_USER_IO
2915             cm->ocspIOCb = EmbedOcspLookup;
2916             cm->ocspRespFreeCb = EmbedOcspRespFree;
2917         #endif /* WOLFSSL_USER_IO */
2918     #else
2919         ret = NOT_COMPILED_IN;
2920     #endif
2921
2922     return ret;
2923 }
2924
2925
2926 int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm)
2927 {
2928     WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSP");
2929     if (cm == NULL)
2930         return BAD_FUNC_ARG;
2931
2932     cm->ocspEnabled = 0;
2933
2934     return SSL_SUCCESS;
2935 }
2936
2937
2938 #ifdef HAVE_OCSP
2939
2940
2941 /* check CRL if enabled, SSL_SUCCESS  */
2942 int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
2943 {
2944     int ret;
2945 #ifdef WOLFSSL_SMALL_STACK
2946     DecodedCert* cert = NULL;
2947 #else
2948     DecodedCert  cert[1];
2949 #endif
2950
2951     WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSP");
2952
2953     if (cm == NULL)
2954         return BAD_FUNC_ARG;
2955
2956     if (cm->ocspEnabled == 0)
2957         return SSL_SUCCESS;
2958
2959 #ifdef WOLFSSL_SMALL_STACK
2960     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
2961                                                        DYNAMIC_TYPE_TMP_BUFFER);
2962     if (cert == NULL)
2963         return MEMORY_E;
2964 #endif
2965
2966     InitDecodedCert(cert, der, sz, NULL);
2967
2968     if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, cm)) != 0) {
2969         WOLFSSL_MSG("ParseCert failed");
2970     }
2971     else if ((ret = CheckCertOCSP(cm->ocsp, cert)) != 0) {
2972         WOLFSSL_MSG("CheckCertOCSP failed");
2973     }
2974
2975     FreeDecodedCert(cert);
2976 #ifdef WOLFSSL_SMALL_STACK
2977     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2978 #endif
2979
2980     return ret == 0 ? SSL_SUCCESS : ret;
2981 }
2982
2983
2984 int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER* cm,
2985                                                                 const char* url)
2986 {
2987     WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSPOverrideURL");
2988     if (cm == NULL)
2989         return BAD_FUNC_ARG;
2990
2991     XFREE(cm->ocspOverrideURL, cm->heap, 0);
2992     if (url != NULL) {
2993         int urlSz = (int)XSTRLEN(url) + 1;
2994         cm->ocspOverrideURL = (char*)XMALLOC(urlSz, cm->heap, 0);
2995         if (cm->ocspOverrideURL != NULL) {
2996             XMEMCPY(cm->ocspOverrideURL, url, urlSz);
2997         }
2998         else
2999             return MEMORY_E;
3000     }
3001     else
3002         cm->ocspOverrideURL = NULL;
3003
3004     return SSL_SUCCESS;
3005 }
3006
3007
3008 int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER* cm,
3009                         CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
3010 {
3011     WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSP_Cb");
3012     if (cm == NULL)
3013         return BAD_FUNC_ARG;
3014
3015     cm->ocspIOCb = ioCb;
3016     cm->ocspRespFreeCb = respFreeCb;
3017     cm->ocspIOCtx = ioCbCtx;
3018
3019     return SSL_SUCCESS;
3020 }
3021
3022
3023 int wolfSSL_EnableOCSP(WOLFSSL* ssl, int options)
3024 {
3025     WOLFSSL_ENTER("wolfSSL_EnableOCSP");
3026     if (ssl)
3027         return wolfSSL_CertManagerEnableOCSP(ssl->ctx->cm, options);
3028     else
3029         return BAD_FUNC_ARG;
3030 }
3031
3032
3033 int wolfSSL_DisableOCSP(WOLFSSL* ssl)
3034 {
3035     WOLFSSL_ENTER("wolfSSL_DisableOCSP");
3036     if (ssl)
3037         return wolfSSL_CertManagerDisableOCSP(ssl->ctx->cm);
3038     else
3039         return BAD_FUNC_ARG;
3040 }
3041
3042
3043 int wolfSSL_SetOCSP_OverrideURL(WOLFSSL* ssl, const char* url)
3044 {
3045     WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
3046     if (ssl)
3047         return wolfSSL_CertManagerSetOCSPOverrideURL(ssl->ctx->cm, url);
3048     else
3049         return BAD_FUNC_ARG;
3050 }
3051
3052
3053 int wolfSSL_SetOCSP_Cb(WOLFSSL* ssl,
3054                         CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
3055 {
3056     WOLFSSL_ENTER("wolfSSL_SetOCSP_Cb");
3057     if (ssl)
3058         return wolfSSL_CertManagerSetOCSP_Cb(ssl->ctx->cm,
3059                                                      ioCb, respFreeCb, ioCbCtx);
3060     else
3061         return BAD_FUNC_ARG;
3062 }
3063
3064
3065 int wolfSSL_CTX_EnableOCSP(WOLFSSL_CTX* ctx, int options)
3066 {
3067     WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSP");
3068     if (ctx)
3069         return wolfSSL_CertManagerEnableOCSP(ctx->cm, options);
3070     else
3071         return BAD_FUNC_ARG;
3072 }
3073
3074
3075 int wolfSSL_CTX_DisableOCSP(WOLFSSL_CTX* ctx)
3076 {
3077     WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSP");
3078     if (ctx)
3079         return wolfSSL_CertManagerDisableOCSP(ctx->cm);
3080     else
3081         return BAD_FUNC_ARG;
3082 }
3083
3084
3085 int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX* ctx, const char* url)
3086 {
3087     WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
3088     if (ctx)
3089         return wolfSSL_CertManagerSetOCSPOverrideURL(ctx->cm, url);
3090     else
3091         return BAD_FUNC_ARG;
3092 }
3093
3094
3095 int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX* ctx,
3096                         CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
3097 {
3098     WOLFSSL_ENTER("wolfSSL_CTX_SetOCSP_Cb");
3099     if (ctx)
3100         return wolfSSL_CertManagerSetOCSP_Cb(ctx->cm, ioCb, respFreeCb, ioCbCtx);
3101     else
3102         return BAD_FUNC_ARG;
3103 }
3104
3105
3106 #endif /* HAVE_OCSP */
3107
3108
3109 #ifndef NO_FILESYSTEM
3110
3111     #if defined(WOLFSSL_MDK_ARM)
3112         extern FILE * wolfSSL_fopen(const char *name, const char *mode) ;
3113         #define XFOPEN     wolfSSL_fopen
3114     #else
3115         #define XFOPEN     fopen
3116     #endif
3117
3118 /* process a file with name fname into ctx of format and type
3119    userChain specifies a user certificate chain to pass during handshake */
3120 int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type,
3121                 WOLFSSL* ssl, int userChain, WOLFSSL_CRL* crl)
3122 {
3123 #ifdef WOLFSSL_SMALL_STACK
3124     byte   staticBuffer[1]; /* force heap usage */
3125 #else
3126     byte   staticBuffer[FILE_BUFFER_SIZE];
3127 #endif
3128     byte*  myBuffer = staticBuffer;
3129     int    dynamic = 0;
3130     int    ret;
3131     long   sz = 0;
3132     XFILE  file;
3133     void*  heapHint = ctx ? ctx->heap : NULL;
3134
3135     (void)crl;
3136     (void)heapHint;
3137
3138     if (fname == NULL) return SSL_BAD_FILE;
3139
3140     file = XFOPEN(fname, "rb");
3141     if (file == XBADFILE) return SSL_BAD_FILE;
3142     XFSEEK(file, 0, XSEEK_END);
3143     sz = XFTELL(file);
3144     XREWIND(file);
3145
3146     if (sz > (long)sizeof(staticBuffer)) {
3147         WOLFSSL_MSG("Getting dynamic buffer");
3148         myBuffer = (byte*)XMALLOC(sz, heapHint, DYNAMIC_TYPE_FILE);
3149         if (myBuffer == NULL) {
3150             XFCLOSE(file);
3151             return SSL_BAD_FILE;
3152         }
3153         dynamic = 1;
3154     }
3155     else if (sz < 0) {
3156         XFCLOSE(file);
3157         return SSL_BAD_FILE;
3158     }
3159
3160     if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
3161         ret = SSL_BAD_FILE;
3162     else {
3163         if (type == CA_TYPE && format == SSL_FILETYPE_PEM)
3164             ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl);
3165 #ifdef HAVE_CRL
3166         else if (type == CRL_TYPE)
3167             ret = BufferLoadCRL(crl, myBuffer, sz, format);
3168 #endif
3169         else
3170             ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL,
3171                                 userChain);
3172     }
3173
3174     XFCLOSE(file);
3175     if (dynamic)
3176         XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
3177
3178     return ret;
3179 }
3180
3181
3182 /* loads file then loads each file in path, no c_rehash */
3183 int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
3184                                      const char* path)
3185 {
3186     int ret = SSL_SUCCESS;
3187
3188     WOLFSSL_ENTER("wolfSSL_CTX_load_verify_locations");
3189     (void)path;
3190
3191     if (ctx == NULL || (file == NULL && path == NULL) )
3192         return SSL_FAILURE;
3193
3194     if (file)
3195         ret = ProcessFile(ctx, file, SSL_FILETYPE_PEM, CA_TYPE, NULL, 0, NULL);
3196
3197     if (ret == SSL_SUCCESS && path) {
3198         /* try to load each regular file in path */
3199     #ifdef USE_WINDOWS_API
3200         WIN32_FIND_DATAA FindFileData;
3201         HANDLE hFind;
3202     #ifdef WOLFSSL_SMALL_STACK
3203         char*  name = NULL;
3204     #else
3205         char   name[MAX_FILENAME_SZ];
3206     #endif
3207
3208     #ifdef WOLFSSL_SMALL_STACK
3209         name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3210         if (name == NULL)
3211             return MEMORY_E;
3212     #endif
3213
3214         XMEMSET(name, 0, MAX_FILENAME_SZ);
3215         XSTRNCPY(name, path, MAX_FILENAME_SZ - 4);
3216         XSTRNCAT(name, "\\*", 3);
3217
3218         hFind = FindFirstFileA(name, &FindFileData);
3219         if (hFind == INVALID_HANDLE_VALUE) {
3220             WOLFSSL_MSG("FindFirstFile for path verify locations failed");
3221         #ifdef WOLFSSL_SMALL_STACK
3222             XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3223         #endif
3224             return BAD_PATH_ERROR;
3225         }
3226
3227         do {
3228             if (FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
3229                 XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 3);
3230                 XSTRNCAT(name, "\\", 2);
3231                 XSTRNCAT(name, FindFileData.cFileName, MAX_FILENAME_SZ/2);
3232
3233                 ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0,
3234                                                                           NULL);
3235             }
3236         } while (ret == SSL_SUCCESS && FindNextFileA(hFind, &FindFileData));
3237
3238     #ifdef WOLFSSL_SMALL_STACK
3239         XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3240     #endif
3241
3242         FindClose(hFind);
3243     #elif !defined(NO_WOLFSSL_DIR)
3244         struct dirent* entry;
3245         DIR*   dir = opendir(path);
3246     #ifdef WOLFSSL_SMALL_STACK
3247         char*  name = NULL;
3248     #else
3249         char   name[MAX_FILENAME_SZ];
3250     #endif
3251
3252         if (dir == NULL) {
3253             WOLFSSL_MSG("opendir path verify locations failed");
3254             return BAD_PATH_ERROR;
3255         }
3256
3257     #ifdef WOLFSSL_SMALL_STACK
3258         name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3259         if (name == NULL)
3260             return MEMORY_E;
3261     #endif
3262
3263         while ( ret == SSL_SUCCESS && (entry = readdir(dir)) != NULL) {
3264             struct stat s;
3265
3266             XMEMSET(name, 0, MAX_FILENAME_SZ);
3267             XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
3268             XSTRNCAT(name, "/", 1);
3269             XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
3270
3271             if (stat(name, &s) != 0) {
3272                 WOLFSSL_MSG("stat on name failed");
3273                 ret = BAD_PATH_ERROR;
3274             } else if (s.st_mode & S_IFREG)
3275                 ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0,
3276                                                                           NULL);
3277         }
3278
3279     #ifdef WOLFSSL_SMALL_STACK
3280         XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3281     #endif
3282
3283         closedir(dir);
3284     #endif
3285     }
3286
3287     return ret;
3288 }
3289
3290
3291 /* Verify the ceritficate, SSL_SUCCESS for ok, < 0 for error */
3292 int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* fname,
3293                              int format)
3294 {
3295     int    ret = SSL_FATAL_ERROR;
3296 #ifdef WOLFSSL_SMALL_STACK
3297     byte   staticBuffer[1]; /* force heap usage */
3298 #else
3299     byte   staticBuffer[FILE_BUFFER_SIZE];
3300 #endif
3301     byte*  myBuffer = staticBuffer;
3302     int    dynamic = 0;
3303     long   sz = 0;
3304     XFILE  file = XFOPEN(fname, "rb");
3305
3306     WOLFSSL_ENTER("wolfSSL_CertManagerVerify");
3307
3308     if (file == XBADFILE) return SSL_BAD_FILE;
3309     XFSEEK(file, 0, XSEEK_END);
3310     sz = XFTELL(file);
3311     XREWIND(file);
3312
3313     if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
3314         WOLFSSL_MSG("CertManagerVerify file bad size");
3315         XFCLOSE(file);
3316         return SSL_BAD_FILE;
3317     }
3318
3319     if (sz > (long)sizeof(staticBuffer)) {
3320         WOLFSSL_MSG("Getting dynamic buffer");
3321         myBuffer = (byte*) XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE);
3322         if (myBuffer == NULL) {
3323             XFCLOSE(file);
3324             return SSL_BAD_FILE;
3325         }
3326         dynamic = 1;
3327     }
3328
3329     if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
3330         ret = SSL_BAD_FILE;
3331     else
3332         ret = wolfSSL_CertManagerVerifyBuffer(cm, myBuffer, sz, format);
3333
3334     XFCLOSE(file);
3335     if (dynamic)
3336         XFREE(myBuffer, cm->heap, DYNAMIC_TYPE_FILE);
3337
3338     return ret;
3339 }
3340
3341
3342 static INLINE WOLFSSL_METHOD* cm_pick_method(void)
3343 {
3344     #ifndef NO_WOLFSSL_CLIENT
3345         #ifdef NO_OLD_TLS
3346             return wolfTLSv1_2_client_method();
3347         #else
3348             return wolfSSLv3_client_method();
3349         #endif      
3350     #elif !defined(NO_WOLFSSL_SERVER)
3351         #ifdef NO_OLD_TLS
3352             return wolfTLSv1_2_server_method();
3353         #else
3354             return wolfSSLv3_server_method();
3355         #endif
3356     #else
3357         return NULL;
3358     #endif
3359 }
3360
3361
3362 /* like load verify locations, 1 for success, < 0 for error */
3363 int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* file,
3364                              const char* path)
3365 {
3366     int ret = SSL_FATAL_ERROR;
3367     WOLFSSL_CTX* tmp;
3368
3369     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCA");
3370
3371     if (cm == NULL) {
3372         WOLFSSL_MSG("No CertManager error");
3373         return ret;
3374     }
3375     tmp = wolfSSL_CTX_new(cm_pick_method());
3376
3377     if (tmp == NULL) {
3378         WOLFSSL_MSG("CTX new failed");
3379         return ret;
3380     }
3381
3382     /* for tmp use */
3383     wolfSSL_CertManagerFree(tmp->cm);
3384     tmp->cm = cm;
3385
3386     ret = wolfSSL_CTX_load_verify_locations(tmp, file, path);
3387
3388     /* don't loose our good one */
3389     tmp->cm = NULL;
3390     wolfSSL_CTX_free(tmp);
3391
3392     return ret;
3393 }
3394
3395
3396
3397 /* turn on CRL if off and compiled in, set options */
3398 int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, int options)
3399 {
3400     int ret = SSL_SUCCESS;
3401
3402     (void)options;
3403
3404     WOLFSSL_ENTER("wolfSSL_CertManagerEnableCRL");
3405     if (cm == NULL)
3406         return BAD_FUNC_ARG;
3407
3408     #ifdef HAVE_CRL
3409         if (cm->crl == NULL) {
3410             cm->crl = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), cm->heap,
3411                                            DYNAMIC_TYPE_CRL);
3412             if (cm->crl == NULL)
3413                 return MEMORY_E;
3414
3415             if (InitCRL(cm->crl, cm) != 0) {
3416                 WOLFSSL_MSG("Init CRL failed");
3417                 FreeCRL(cm->crl, 1);
3418                 cm->crl = NULL;
3419                 return SSL_FAILURE;
3420             }
3421         }
3422         cm->crlEnabled = 1;
3423         if (options & WOLFSSL_CRL_CHECKALL)
3424             cm->crlCheckAll = 1;
3425     #else
3426         ret = NOT_COMPILED_IN;
3427     #endif
3428
3429     return ret;
3430 }
3431
3432
3433 int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER* cm)
3434 {
3435     WOLFSSL_ENTER("wolfSSL_CertManagerDisableCRL");
3436     if (cm == NULL)
3437         return BAD_FUNC_ARG;
3438
3439     cm->crlEnabled = 0;
3440
3441     return SSL_SUCCESS;
3442 }
3443
3444
3445 int wolfSSL_CTX_check_private_key(WOLFSSL_CTX* ctx)
3446 {
3447     /* TODO: check private against public for RSA match */
3448     (void)ctx;
3449     WOLFSSL_ENTER("SSL_CTX_check_private_key");
3450     return SSL_SUCCESS;
3451 }
3452
3453
3454 #ifdef HAVE_CRL
3455
3456
3457 /* check CRL if enabled, SSL_SUCCESS  */
3458 int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
3459 {
3460     int ret = 0;
3461 #ifdef WOLFSSL_SMALL_STACK
3462     DecodedCert* cert = NULL;
3463 #else
3464     DecodedCert  cert[1];
3465 #endif
3466
3467     WOLFSSL_ENTER("wolfSSL_CertManagerCheckCRL");
3468
3469     if (cm == NULL)
3470         return BAD_FUNC_ARG;
3471
3472     if (cm->crlEnabled == 0)
3473         return SSL_SUCCESS;
3474
3475 #ifdef WOLFSSL_SMALL_STACK
3476     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
3477                                                        DYNAMIC_TYPE_TMP_BUFFER);
3478     if (cert == NULL)
3479         return MEMORY_E;
3480 #endif
3481
3482     InitDecodedCert(cert, der, sz, NULL);
3483
3484     if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, cm)) != 0) {
3485         WOLFSSL_MSG("ParseCert failed");
3486     }
3487     else if ((ret = CheckCertCRL(cm->crl, cert)) != 0) {
3488         WOLFSSL_MSG("CheckCertCRL failed");
3489     }
3490
3491     FreeDecodedCert(cert);
3492 #ifdef WOLFSSL_SMALL_STACK
3493     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3494 #endif
3495
3496     return ret == 0 ? SSL_SUCCESS : ret;
3497 }
3498
3499
3500 int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, CbMissingCRL cb)
3501 {
3502     WOLFSSL_ENTER("wolfSSL_CertManagerSetCRL_Cb");
3503     if (cm == NULL)
3504         return BAD_FUNC_ARG;
3505
3506     cm->cbMissingCRL = cb;
3507
3508     return SSL_SUCCESS;
3509 }
3510
3511
3512 int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER* cm, const char* path,
3513                               int type, int monitor)
3514 {
3515     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRL");
3516     if (cm == NULL)
3517         return BAD_FUNC_ARG;
3518
3519     if (cm->crl == NULL) {
3520         if (wolfSSL_CertManagerEnableCRL(cm, 0) != SSL_SUCCESS) {
3521             WOLFSSL_MSG("Enable CRL failed");
3522             return SSL_FATAL_ERROR;
3523         }
3524     }
3525
3526     return LoadCRL(cm->crl, path, type, monitor);
3527 }
3528
3529
3530 int wolfSSL_EnableCRL(WOLFSSL* ssl, int options)
3531 {
3532     WOLFSSL_ENTER("wolfSSL_EnableCRL");
3533     if (ssl)
3534         return wolfSSL_CertManagerEnableCRL(ssl->ctx->cm, options);
3535     else
3536         return BAD_FUNC_ARG;
3537 }
3538
3539
3540 int wolfSSL_DisableCRL(WOLFSSL* ssl)
3541 {
3542     WOLFSSL_ENTER("wolfSSL_DisableCRL");
3543     if (ssl)
3544         return wolfSSL_CertManagerDisableCRL(ssl->ctx->cm);
3545     else
3546         return BAD_FUNC_ARG;
3547 }
3548
3549
3550 int wolfSSL_LoadCRL(WOLFSSL* ssl, const char* path, int type, int monitor)
3551 {
3552     WOLFSSL_ENTER("wolfSSL_LoadCRL");
3553     if (ssl)
3554         return wolfSSL_CertManagerLoadCRL(ssl->ctx->cm, path, type, monitor);
3555     else
3556         return BAD_FUNC_ARG;
3557 }
3558
3559
3560 int wolfSSL_SetCRL_Cb(WOLFSSL* ssl, CbMissingCRL cb)
3561 {
3562     WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
3563     if (ssl)
3564         return wolfSSL_CertManagerSetCRL_Cb(ssl->ctx->cm, cb);
3565     else
3566         return BAD_FUNC_ARG;
3567 }
3568
3569
3570 int wolfSSL_CTX_EnableCRL(WOLFSSL_CTX* ctx, int options)
3571 {
3572     WOLFSSL_ENTER("wolfSSL_CTX_EnableCRL");
3573     if (ctx)
3574         return wolfSSL_CertManagerEnableCRL(ctx->cm, options);
3575     else
3576         return BAD_FUNC_ARG;
3577 }
3578
3579
3580 int wolfSSL_CTX_DisableCRL(WOLFSSL_CTX* ctx)
3581 {
3582     WOLFSSL_ENTER("wolfSSL_CTX_DisableCRL");
3583     if (ctx)
3584         return wolfSSL_CertManagerDisableCRL(ctx->cm);
3585     else
3586         return BAD_FUNC_ARG;
3587 }
3588
3589
3590 int wolfSSL_CTX_LoadCRL(WOLFSSL_CTX* ctx, const char* path, int type, int monitor)
3591 {
3592     WOLFSSL_ENTER("wolfSSL_CTX_LoadCRL");
3593     if (ctx)
3594         return wolfSSL_CertManagerLoadCRL(ctx->cm, path, type, monitor);
3595     else
3596         return BAD_FUNC_ARG;
3597 }
3598
3599
3600 int wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX* ctx, CbMissingCRL cb)
3601 {
3602     WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_Cb");
3603     if (ctx)
3604         return wolfSSL_CertManagerSetCRL_Cb(ctx->cm, cb);
3605     else
3606         return BAD_FUNC_ARG;
3607 }
3608
3609
3610 #endif /* HAVE_CRL */
3611
3612
3613 #ifdef WOLFSSL_DER_LOAD
3614
3615 /* Add format parameter to allow DER load of CA files */
3616 int wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
3617                                          int format)
3618 {
3619     WOLFSSL_ENTER("wolfSSL_CTX_der_load_verify_locations");
3620     if (ctx == NULL || file == NULL)
3621         return SSL_FAILURE;
3622
3623     if (ProcessFile(ctx, file, format, CA_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
3624         return SSL_SUCCESS;
3625
3626     return SSL_FAILURE;
3627 }
3628
3629 #endif /* WOLFSSL_DER_LOAD */
3630
3631
3632 #ifdef WOLFSSL_CERT_GEN
3633
3634 /* load pem cert from file into der buffer, return der size or error */
3635 int wolfSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
3636 {
3637 #ifdef WOLFSSL_SMALL_STACK
3638     EncryptedInfo* info = NULL;
3639     byte   staticBuffer[1]; /* force XMALLOC */
3640 #else
3641     EncryptedInfo info[1];
3642     byte   staticBuffer[FILE_BUFFER_SIZE];
3643 #endif
3644     byte*  fileBuf = staticBuffer;
3645     int    dynamic = 0;
3646     int    ret     = 0;
3647     int    ecc     = 0;
3648     long   sz      = 0;
3649     XFILE  file    = XFOPEN(fileName, "rb");
3650     buffer converted;
3651
3652     WOLFSSL_ENTER("wolfSSL_PemCertToDer");
3653
3654     if (file == XBADFILE)
3655         ret = SSL_BAD_FILE;
3656     else {
3657         XFSEEK(file, 0, XSEEK_END);
3658         sz = XFTELL(file);
3659         XREWIND(file);
3660
3661         if (sz < 0) {
3662             ret = SSL_BAD_FILE;
3663         }
3664         else if (sz > (long)sizeof(staticBuffer)) {
3665             fileBuf = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
3666             if (fileBuf == NULL)
3667                 ret = MEMORY_E;
3668             else
3669                 dynamic = 1;
3670         }
3671
3672         converted.buffer = 0;
3673
3674         if (ret == 0) {
3675             if ( (ret = (int)XFREAD(fileBuf, sz, 1, file)) < 0)
3676                 ret = SSL_BAD_FILE;
3677             else {
3678             #ifdef WOLFSSL_SMALL_STACK
3679                 info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
3680                                                        DYNAMIC_TYPE_TMP_BUFFER);
3681                 if (info == NULL)
3682                     ret = MEMORY_E;
3683                 else
3684             #endif
3685                 {
3686                     ret = PemToDer(fileBuf, sz, CA_TYPE, &converted, 0, info,
3687                                                                           &ecc);
3688                 #ifdef WOLFSSL_SMALL_STACK
3689                     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3690                 #endif
3691                 }
3692             }
3693
3694             if (ret == 0) {
3695                 if (converted.length < (word32)derSz) {
3696                     XMEMCPY(derBuf, converted.buffer, converted.length);
3697                     ret = converted.length;
3698                 }
3699                 else
3700                     ret = BUFFER_E;
3701             }
3702
3703             XFREE(converted.buffer, 0, DYNAMIC_TYPE_CA);
3704         }
3705
3706         XFCLOSE(file);
3707         if (dynamic)
3708             XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE);
3709     }
3710
3711     return ret;
3712 }
3713
3714 #endif /* WOLFSSL_CERT_GEN */
3715
3716
3717 int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
3718                                     int format)
3719 {
3720     WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_file");
3721     if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
3722         return SSL_SUCCESS;
3723
3724     return SSL_FAILURE;
3725 }
3726
3727
3728 int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX* ctx, const char* file,int format)
3729 {
3730     WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_file");
3731     if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL)
3732                     == SSL_SUCCESS)
3733         return SSL_SUCCESS;
3734
3735     return SSL_FAILURE;
3736 }
3737
3738
3739 /* get cert chaining depth using ssl struct */
3740 long wolfSSL_get_verify_depth(WOLFSSL* ssl)
3741 {
3742     if(ssl == NULL) {
3743         return BAD_FUNC_ARG;
3744     }
3745     return MAX_CHAIN_DEPTH;
3746 }
3747
3748
3749 /* get cert chaining depth using ctx struct */
3750 long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx)
3751 {
3752     if(ctx == NULL) {
3753         return BAD_FUNC_ARG;
3754     }
3755     return MAX_CHAIN_DEPTH;
3756 }
3757
3758
3759 int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX* ctx, const char* file)
3760 {
3761    /* procces up to MAX_CHAIN_DEPTH plus subject cert */
3762    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file");
3763    if (ProcessFile(ctx, file, SSL_FILETYPE_PEM,CERT_TYPE,NULL,1, NULL)
3764                    == SSL_SUCCESS)
3765        return SSL_SUCCESS;
3766
3767    return SSL_FAILURE;
3768 }
3769
3770
3771 #ifndef NO_DH
3772
3773 /* server wrapper for ctx or ssl Diffie-Hellman parameters */
3774 static int wolfSSL_SetTmpDH_buffer_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
3775                                   const unsigned char* buf, long sz, int format)
3776 {
3777     buffer der;
3778     int    ret      = 0;
3779     int    weOwnDer = 0;
3780     word32 pSz = MAX_DH_SIZE;
3781     word32 gSz = MAX_DH_SIZE;
3782 #ifdef WOLFSSL_SMALL_STACK
3783     byte*  p = NULL;
3784     byte*  g = NULL;
3785 #else
3786     byte   p[MAX_DH_SIZE];
3787     byte   g[MAX_DH_SIZE];
3788 #endif
3789
3790     der.buffer = (byte*)buf;
3791     der.length = (word32)sz;
3792
3793 #ifdef WOLFSSL_SMALL_STACK
3794     p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3795     g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3796
3797     if (p == NULL || g == NULL) {
3798         XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3799         XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3800         return MEMORY_E;
3801     }
3802 #endif
3803
3804     if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM)
3805         ret = SSL_BAD_FILETYPE;
3806     else {
3807         if (format == SSL_FILETYPE_PEM) {
3808             der.buffer = NULL;
3809             ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap, NULL,NULL);
3810             weOwnDer = 1;
3811         }
3812         
3813         if (ret == 0) {
3814             if (wc_DhParamsLoad(der.buffer, der.length, p, &pSz, g, &gSz) < 0)
3815                 ret = SSL_BAD_FILETYPE;
3816             else if (ssl)
3817                 ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
3818             else
3819                 ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
3820         }
3821     }
3822
3823     if (weOwnDer)
3824         XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
3825
3826 #ifdef WOLFSSL_SMALL_STACK
3827     XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3828     XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3829 #endif
3830
3831     return ret;
3832 }
3833
3834
3835 /* server Diffie-Hellman parameters, SSL_SUCCESS on ok */
3836 int wolfSSL_SetTmpDH_buffer(WOLFSSL* ssl, const unsigned char* buf, long sz,
3837                            int format)
3838 {
3839     return wolfSSL_SetTmpDH_buffer_wrapper(ssl->ctx, ssl, buf, sz, format);
3840 }
3841
3842
3843 /* server ctx Diffie-Hellman parameters, SSL_SUCCESS on ok */
3844 int wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX* ctx, const unsigned char* buf,
3845                                long sz, int format)
3846 {
3847     return wolfSSL_SetTmpDH_buffer_wrapper(ctx, NULL, buf, sz, format);
3848 }
3849
3850
3851 /* server Diffie-Hellman parameters */
3852 static int wolfSSL_SetTmpDH_file_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
3853                                         const char* fname, int format)
3854 {
3855 #ifdef WOLFSSL_SMALL_STACK
3856     byte   staticBuffer[1]; /* force heap usage */
3857 #else
3858     byte   staticBuffer[FILE_BUFFER_SIZE];
3859 #endif
3860     byte*  myBuffer = staticBuffer;
3861     int    dynamic = 0;
3862     int    ret;
3863     long   sz = 0;
3864     XFILE  file = XFOPEN(fname, "rb");
3865
3866     if (file == XBADFILE) return SSL_BAD_FILE;
3867     XFSEEK(file, 0, XSEEK_END);
3868     sz = XFTELL(file);
3869     XREWIND(file);
3870
3871     if (sz > (long)sizeof(staticBuffer)) {
3872         WOLFSSL_MSG("Getting dynamic buffer");
3873         myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
3874         if (myBuffer == NULL) {
3875             XFCLOSE(file);
3876             return SSL_BAD_FILE;
3877         }
3878         dynamic = 1;
3879     }
3880     else if (sz < 0) {
3881         XFCLOSE(file);
3882         return SSL_BAD_FILE;
3883     }
3884
3885     if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
3886         ret = SSL_BAD_FILE;
3887     else {
3888         if (ssl)
3889             ret = wolfSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format);
3890         else
3891             ret = wolfSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format);
3892     }
3893
3894     XFCLOSE(file);
3895     if (dynamic)
3896         XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
3897
3898     return ret;
3899 }
3900
3901 /* server Diffie-Hellman parameters */
3902 int wolfSSL_SetTmpDH_file(WOLFSSL* ssl, const char* fname, int format)
3903 {
3904     return wolfSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format);
3905 }
3906
3907
3908 /* server Diffie-Hellman parameters */
3909 int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format)
3910 {
3911     return wolfSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format);
3912 }
3913
3914
3915 int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz)
3916 {
3917     if (ctx == NULL || keySz > 16000 || keySz % 8 != 0)
3918         return BAD_FUNC_ARG;
3919
3920     ctx->minDhKeySz = keySz / 8;
3921     return SSL_SUCCESS;
3922 }
3923
3924
3925 int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz)
3926 {
3927     if (ssl == NULL || keySz > 16000 || keySz % 8 != 0)
3928         return BAD_FUNC_ARG;
3929
3930     ssl->options.minDhKeySz = keySz / 8;
3931     return SSL_SUCCESS;
3932 }
3933
3934
3935 int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl)
3936 {
3937     if (ssl == NULL)
3938         return BAD_FUNC_ARG;
3939
3940     return (ssl->options.dhKeySz * 8);
3941 }
3942
3943
3944 #endif /* NO_DH */
3945
3946
3947 #ifdef OPENSSL_EXTRA
3948 /* put SSL type in extra for now, not very common */
3949
3950 int wolfSSL_use_certificate_file(WOLFSSL* ssl, const char* file, int format)
3951 {
3952     WOLFSSL_ENTER("wolfSSL_use_certificate_file");
3953     if (ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 0, NULL)
3954                     == SSL_SUCCESS)
3955         return SSL_SUCCESS;
3956
3957     return SSL_FAILURE;
3958 }
3959
3960
3961 int wolfSSL_use_PrivateKey_file(WOLFSSL* ssl, const char* file, int format)
3962 {
3963     WOLFSSL_ENTER("wolfSSL_use_PrivateKey_file");
3964     if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0, NULL)
3965                                                                  == SSL_SUCCESS)
3966         return SSL_SUCCESS;
3967
3968     return SSL_FAILURE;
3969 }
3970
3971
3972 int wolfSSL_use_certificate_chain_file(WOLFSSL* ssl, const char* file)
3973 {
3974    /* procces up to MAX_CHAIN_DEPTH plus subject cert */
3975    WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file");
3976    if (ProcessFile(ssl->ctx, file, SSL_FILETYPE_PEM, CERT_TYPE, ssl, 1, NULL)
3977                                                                  == SSL_SUCCESS)
3978        return SSL_SUCCESS;
3979
3980    return SSL_FAILURE;
3981 }
3982
3983
3984
3985 #ifdef HAVE_ECC
3986
3987 /* Set Temp CTX EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
3988 int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX* ctx, word16 sz)
3989 {
3990     if (ctx == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
3991         return BAD_FUNC_ARG;
3992
3993     ctx->eccTempKeySz = sz;
3994
3995     return SSL_SUCCESS;
3996 }
3997
3998
3999 /* Set Temp SSL EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
4000 int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL* ssl, word16 sz)
4001 {
4002     if (ssl == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
4003         return BAD_FUNC_ARG;
4004
4005     ssl->eccTempKeySz = sz;
4006
4007     return SSL_SUCCESS;
4008 }
4009
4010 #endif /* HAVE_ECC */
4011
4012
4013
4014
4015 int wolfSSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX* ctx,const char* file,
4016                                    int format)
4017 {
4018     WOLFSSL_ENTER("SSL_CTX_use_RSAPrivateKey_file");
4019
4020     return wolfSSL_CTX_use_PrivateKey_file(ctx, file, format);
4021 }
4022
4023
4024 int wolfSSL_use_RSAPrivateKey_file(WOLFSSL* ssl, const char* file, int format)
4025 {
4026     WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_file");
4027
4028     return wolfSSL_use_PrivateKey_file(ssl, file, format);
4029 }
4030
4031 #endif /* OPENSSL_EXTRA */
4032
4033 #ifdef HAVE_NTRU
4034
4035 int wolfSSL_CTX_use_NTRUPrivateKey_file(WOLFSSL_CTX* ctx, const char* file)
4036 {
4037     WOLFSSL_ENTER("wolfSSL_CTX_use_NTRUPrivateKey_file");
4038     if (ctx == NULL)
4039         return SSL_FAILURE;
4040
4041     if (ProcessFile(ctx, file, SSL_FILETYPE_RAW, PRIVATEKEY_TYPE, NULL, 0, NULL)
4042                          == SSL_SUCCESS) {
4043         ctx->haveNTRU = 1;
4044         return SSL_SUCCESS;
4045     }
4046
4047     return SSL_FAILURE;
4048 }
4049
4050 #endif /* HAVE_NTRU */
4051
4052
4053 #endif /* NO_FILESYSTEM */
4054
4055
4056 void wolfSSL_CTX_set_verify(WOLFSSL_CTX* ctx, int mode, VerifyCallback vc)
4057 {
4058     WOLFSSL_ENTER("wolfSSL_CTX_set_verify");
4059     if (mode & SSL_VERIFY_PEER) {
4060         ctx->verifyPeer = 1;
4061         ctx->verifyNone = 0;  /* in case perviously set */
4062     }
4063
4064     if (mode == SSL_VERIFY_NONE) {
4065         ctx->verifyNone = 1;
4066         ctx->verifyPeer = 0;  /* in case previously set */
4067     }
4068
4069     if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
4070         ctx->failNoCert = 1;
4071
4072     ctx->verifyCallback = vc;
4073 }
4074
4075
4076 void wolfSSL_set_verify(WOLFSSL* ssl, int mode, VerifyCallback vc)
4077 {
4078     WOLFSSL_ENTER("wolfSSL_set_verify");
4079     if (mode & SSL_VERIFY_PEER) {
4080         ssl->options.verifyPeer = 1;
4081         ssl->options.verifyNone = 0;  /* in case perviously set */
4082     }
4083
4084     if (mode == SSL_VERIFY_NONE) {
4085         ssl->options.verifyNone = 1;
4086         ssl->options.verifyPeer = 0;  /* in case previously set */
4087     }
4088
4089     if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
4090         ssl->options.failNoCert = 1;
4091
4092     ssl->verifyCallback = vc;
4093 }
4094
4095
4096 /* store user ctx for verify callback */
4097 void wolfSSL_SetCertCbCtx(WOLFSSL* ssl, void* ctx)
4098 {
4099     WOLFSSL_ENTER("wolfSSL_SetCertCbCtx");
4100     if (ssl)
4101         ssl->verifyCbCtx = ctx;
4102 }
4103
4104
4105 /* store context CA Cache addition callback */
4106 void wolfSSL_CTX_SetCACb(WOLFSSL_CTX* ctx, CallbackCACache cb)
4107 {
4108     if (ctx && ctx->cm)
4109         ctx->cm->caCacheCallback = cb;
4110 }
4111
4112
4113 #if defined(PERSIST_CERT_CACHE)
4114
4115 #if !defined(NO_FILESYSTEM)
4116
4117 /* Persist cert cache to file */
4118 int wolfSSL_CTX_save_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
4119 {
4120     WOLFSSL_ENTER("wolfSSL_CTX_save_cert_cache");
4121
4122     if (ctx == NULL || fname == NULL)
4123         return BAD_FUNC_ARG;
4124
4125     return CM_SaveCertCache(ctx->cm, fname);
4126 }
4127
4128
4129 /* Persist cert cache from file */
4130 int wolfSSL_CTX_restore_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
4131 {
4132     WOLFSSL_ENTER("wolfSSL_CTX_restore_cert_cache");
4133
4134     if (ctx == NULL || fname == NULL)
4135         return BAD_FUNC_ARG;
4136
4137     return CM_RestoreCertCache(ctx->cm, fname);
4138 }
4139
4140 #endif /* NO_FILESYSTEM */
4141
4142 /* Persist cert cache to memory */
4143 int wolfSSL_CTX_memsave_cert_cache(WOLFSSL_CTX* ctx, void* mem, int sz, int* used)
4144 {
4145     WOLFSSL_ENTER("wolfSSL_CTX_memsave_cert_cache");
4146
4147     if (ctx == NULL || mem == NULL || used == NULL || sz <= 0)
4148         return BAD_FUNC_ARG;
4149
4150     return CM_MemSaveCertCache(ctx->cm, mem, sz, used);
4151 }
4152
4153
4154 /* Restore cert cache from memory */
4155 int wolfSSL_CTX_memrestore_cert_cache(WOLFSSL_CTX* ctx, const void* mem, int sz)
4156 {
4157     WOLFSSL_ENTER("wolfSSL_CTX_memrestore_cert_cache");
4158
4159     if (ctx == NULL || mem == NULL || sz <= 0)
4160         return BAD_FUNC_ARG;
4161
4162     return CM_MemRestoreCertCache(ctx->cm, mem, sz);
4163 }
4164
4165
4166 /* get how big the the cert cache save buffer needs to be */
4167 int wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX* ctx)
4168 {
4169     WOLFSSL_ENTER("wolfSSL_CTX_get_cert_cache_memsize");
4170
4171     if (ctx == NULL)
4172         return BAD_FUNC_ARG;
4173
4174     return CM_GetCertCacheMemSize(ctx->cm);
4175 }
4176
4177 #endif /* PERSISTE_CERT_CACHE */
4178 #endif /* !NO_CERTS */
4179
4180
4181 #ifndef NO_SESSION_CACHE
4182
4183 WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl)
4184 {
4185     WOLFSSL_ENTER("SSL_get_session");
4186     if (ssl)
4187         return GetSession(ssl, 0);
4188
4189     return NULL;
4190 }
4191
4192
4193 int wolfSSL_set_session(WOLFSSL* ssl, WOLFSSL_SESSION* session)
4194 {
4195     WOLFSSL_ENTER("SSL_set_session");
4196     if (session)
4197         return SetSession(ssl, session);
4198
4199     return SSL_FAILURE;
4200 }
4201
4202
4203 #ifndef NO_CLIENT_CACHE
4204
4205 /* Associate client session with serverID, find existing or store for saving
4206    if newSession flag on, don't reuse existing session
4207    SSL_SUCCESS on ok */
4208 int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
4209 {
4210     WOLFSSL_SESSION* session = NULL;
4211
4212     WOLFSSL_ENTER("wolfSSL_SetServerID");
4213
4214     if (ssl == NULL || id == NULL || len <= 0)
4215         return BAD_FUNC_ARG;
4216
4217     if (newSession == 0) {
4218         session = GetSessionClient(ssl, id, len);
4219         if (session) {
4220             if (SetSession(ssl, session) != SSL_SUCCESS) {
4221                 WOLFSSL_MSG("SetSession failed");
4222                 session = NULL;
4223             }
4224         }
4225     }
4226
4227     if (session == NULL) {
4228         WOLFSSL_MSG("Valid ServerID not cached already");
4229
4230         ssl->session.idLen = (word16)min(SERVER_ID_LEN, (word32)len);
4231         XMEMCPY(ssl->session.serverID, id, ssl->session.idLen);
4232     }
4233
4234     return SSL_SUCCESS;
4235 }
4236
4237 #endif /* NO_CLIENT_CACHE */
4238
4239 #if defined(PERSIST_SESSION_CACHE)
4240
4241 /* for persistance, if changes to layout need to increment and modify
4242    save_session_cache() and restore_session_cache and memory versions too */
4243 #define WOLFSSL_CACHE_VERSION 2
4244
4245 /* Session Cache Header information */
4246 typedef struct {
4247     int version;     /* cache layout version id */
4248     int rows;        /* session rows */
4249     int columns;     /* session columns */
4250     int sessionSz;   /* sizeof WOLFSSL_SESSION */
4251 } cache_header_t;
4252
4253 /* current persistence layout is:
4254
4255    1) cache_header_t
4256    2) SessionCache
4257    3) ClientCache
4258
4259    update WOLFSSL_CACHE_VERSION if change layout for the following
4260    PERSISTENT_SESSION_CACHE functions
4261 */
4262
4263
4264 /* get how big the the session cache save buffer needs to be */
4265 int wolfSSL_get_session_cache_memsize(void)
4266 {
4267     int sz  = (int)(sizeof(SessionCache) + sizeof(cache_header_t));
4268
4269     #ifndef NO_CLIENT_CACHE
4270         sz += (int)(sizeof(ClientCache));
4271     #endif
4272
4273     return sz;
4274 }
4275
4276
4277 /* Persist session cache to memory */
4278 int wolfSSL_memsave_session_cache(void* mem, int sz)
4279 {
4280     int i;
4281     cache_header_t cache_header;
4282     SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
4283 #ifndef NO_CLIENT_CACHE
4284     ClientRow*     clRow;
4285 #endif
4286
4287     WOLFSSL_ENTER("wolfSSL_memsave_session_cache");
4288
4289     if (sz < wolfSSL_get_session_cache_memsize()) {
4290         WOLFSSL_MSG("Memory buffer too small");
4291         return BUFFER_E;
4292     }
4293
4294     cache_header.version   = WOLFSSL_CACHE_VERSION;
4295     cache_header.rows      = SESSION_ROWS;
4296     cache_header.columns   = SESSIONS_PER_ROW;
4297     cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
4298     XMEMCPY(mem, &cache_header, sizeof(cache_header));
4299
4300     if (LockMutex(&session_mutex) != 0) {
4301         WOLFSSL_MSG("Session cache mutex lock failed");
4302         return BAD_MUTEX_E;
4303     }
4304
4305     for (i = 0; i < cache_header.rows; ++i)
4306         XMEMCPY(row++, SessionCache + i, sizeof(SessionRow));
4307
4308 #ifndef NO_CLIENT_CACHE
4309     clRow = (ClientRow*)row;
4310     for (i = 0; i < cache_header.rows; ++i)
4311         XMEMCPY(clRow++, ClientCache + i, sizeof(ClientRow));
4312 #endif
4313
4314     UnLockMutex(&session_mutex);
4315
4316     WOLFSSL_LEAVE("wolfSSL_memsave_session_cache", SSL_SUCCESS);
4317
4318     return SSL_SUCCESS;
4319 }
4320
4321
4322 /* Restore the persistant session cache from memory */
4323 int wolfSSL_memrestore_session_cache(const void* mem, int sz)
4324 {
4325     int    i;
4326     cache_header_t cache_header;
4327     SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
4328 #ifndef NO_CLIENT_CACHE
4329     ClientRow*     clRow;
4330 #endif
4331
4332     WOLFSSL_ENTER("wolfSSL_memrestore_session_cache");
4333
4334     if (sz < wolfSSL_get_session_cache_memsize()) {
4335         WOLFSSL_MSG("Memory buffer too small");
4336         return BUFFER_E;
4337     }
4338
4339     XMEMCPY(&cache_header, mem, sizeof(cache_header));
4340     if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
4341         cache_header.rows      != SESSION_ROWS ||
4342         cache_header.columns   != SESSIONS_PER_ROW ||
4343         cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
4344
4345         WOLFSSL_MSG("Session cache header match failed");
4346         return CACHE_MATCH_ERROR;
4347     }
4348
4349     if (LockMutex(&session_mutex) != 0) {
4350         WOLFSSL_MSG("Session cache mutex lock failed");
4351         return BAD_MUTEX_E;
4352     }
4353
4354     for (i = 0; i < cache_header.rows; ++i)
4355         XMEMCPY(SessionCache + i, row++, sizeof(SessionRow));
4356
4357 #ifndef NO_CLIENT_CACHE
4358     clRow = (ClientRow*)row;
4359     for (i = 0; i < cache_header.rows; ++i)
4360         XMEMCPY(ClientCache + i, clRow++, sizeof(ClientRow));
4361 #endif
4362
4363     UnLockMutex(&session_mutex);
4364
4365     WOLFSSL_LEAVE("wolfSSL_memrestore_session_cache", SSL_SUCCESS);
4366
4367     return SSL_SUCCESS;
4368 }
4369
4370 #if !defined(NO_FILESYSTEM)
4371
4372 /* Persist session cache to file */
4373 /* doesn't use memsave because of additional memory use */
4374 int wolfSSL_save_session_cache(const char *fname)
4375 {
4376     XFILE  file;
4377     int    ret;
4378     int    rc = SSL_SUCCESS;
4379     int    i;
4380     cache_header_t cache_header;
4381
4382     WOLFSSL_ENTER("wolfSSL_save_session_cache");
4383
4384     file = XFOPEN(fname, "w+b");
4385     if (file == XBADFILE) {
4386         WOLFSSL_MSG("Couldn't open session cache save file");
4387         return SSL_BAD_FILE;
4388     }
4389     cache_header.version   = WOLFSSL_CACHE_VERSION;
4390     cache_header.rows      = SESSION_ROWS;
4391     cache_header.columns   = SESSIONS_PER_ROW;
4392     cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
4393
4394     /* cache header */
4395     ret = (int)XFWRITE(&cache_header, sizeof cache_header, 1, file);
4396     if (ret != 1) {
4397         WOLFSSL_MSG("Session cache header file write failed");
4398         XFCLOSE(file);
4399         return FWRITE_ERROR;
4400     }
4401
4402     if (LockMutex(&session_mutex) != 0) {
4403         WOLFSSL_MSG("Session cache mutex lock failed");
4404         XFCLOSE(file);
4405         return BAD_MUTEX_E;
4406     }
4407
4408     /* session cache */
4409     for (i = 0; i < cache_header.rows; ++i) {
4410         ret = (int)XFWRITE(SessionCache + i, sizeof(SessionRow), 1, file);
4411         if (ret != 1) {
4412             WOLFSSL_MSG("Session cache member file write failed");
4413             rc = FWRITE_ERROR;
4414             break;
4415         }
4416     }
4417
4418 #ifndef NO_CLIENT_CACHE
4419     /* client cache */
4420     for (i = 0; i < cache_header.rows; ++i) {
4421         ret = (int)XFWRITE(ClientCache + i, sizeof(ClientRow), 1, file);
4422         if (ret != 1) {
4423             WOLFSSL_MSG("Client cache member file write failed");
4424             rc = FWRITE_ERROR;
4425             break;
4426         }
4427     }
4428 #endif /* NO_CLIENT_CACHE */
4429
4430     UnLockMutex(&session_mutex);
4431
4432     XFCLOSE(file);
4433     WOLFSSL_LEAVE("wolfSSL_save_session_cache", rc);
4434
4435     return rc;
4436 }
4437
4438
4439 /* Restore the persistant session cache from file */
4440 /* doesn't use memstore because of additional memory use */
4441 int wolfSSL_restore_session_cache(const char *fname)
4442 {
4443     XFILE  file;
4444     int    rc = SSL_SUCCESS;
4445     int    ret;
4446     int    i;
4447     cache_header_t cache_header;
4448
4449     WOLFSSL_ENTER("wolfSSL_restore_session_cache");
4450
4451     file = XFOPEN(fname, "rb");
4452     if (file == XBADFILE) {
4453         WOLFSSL_MSG("Couldn't open session cache save file");
4454         return SSL_BAD_FILE;
4455     }
4456     /* cache header */
4457     ret = (int)XFREAD(&cache_header, sizeof cache_header, 1, file);
4458     if (ret != 1) {
4459         WOLFSSL_MSG("Session cache header file read failed");
4460         XFCLOSE(file);
4461         return FREAD_ERROR;
4462     }
4463     if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
4464         cache_header.rows      != SESSION_ROWS ||
4465         cache_header.columns   != SESSIONS_PER_ROW ||
4466         cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
4467
4468         WOLFSSL_MSG("Session cache header match failed");
4469         XFCLOSE(file);
4470         return CACHE_MATCH_ERROR;
4471     }
4472
4473     if (LockMutex(&session_mutex) != 0) {
4474         WOLFSSL_MSG("Session cache mutex lock failed");
4475         XFCLOSE(file);
4476         return BAD_MUTEX_E;
4477     }
4478
4479     /* session cache */
4480     for (i = 0; i < cache_header.rows; ++i) {
4481         ret = (int)XFREAD(SessionCache + i, sizeof(SessionRow), 1, file);
4482         if (ret != 1) {
4483             WOLFSSL_MSG("Session cache member file read failed");
4484             XMEMSET(SessionCache, 0, sizeof SessionCache);
4485             rc = FREAD_ERROR;
4486             break;
4487         }
4488     }
4489
4490 #ifndef NO_CLIENT_CACHE
4491     /* client cache */
4492     for (i = 0; i < cache_header.rows; ++i) {
4493         ret = (int)XFREAD(ClientCache + i, sizeof(ClientRow), 1, file);
4494         if (ret != 1) {
4495             WOLFSSL_MSG("Client cache member file read failed");
4496             XMEMSET(ClientCache, 0, sizeof ClientCache);
4497             rc = FREAD_ERROR;
4498             break;
4499         }
4500     }
4501
4502 #endif /* NO_CLIENT_CACHE */
4503
4504     UnLockMutex(&session_mutex);
4505
4506     XFCLOSE(file);
4507     WOLFSSL_LEAVE("wolfSSL_restore_session_cache", rc);
4508
4509     return rc;
4510 }
4511
4512 #endif /* !NO_FILESYSTEM */
4513 #endif /* PERSIST_SESSION_CACHE */
4514 #endif /* NO_SESSION_CACHE */
4515
4516
4517 void wolfSSL_load_error_strings(void)   /* compatibility only */
4518 {}
4519
4520
4521 int wolfSSL_library_init(void)
4522 {
4523     WOLFSSL_ENTER("SSL_library_init");
4524     if (wolfSSL_Init() == SSL_SUCCESS)
4525         return SSL_SUCCESS;
4526     else
4527         return SSL_FATAL_ERROR;
4528 }
4529
4530
4531 #ifdef HAVE_SECRET_CALLBACK
4532
4533 int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx)
4534 {
4535     WOLFSSL_ENTER("wolfSSL_set_session_secret_cb");
4536     if (ssl == NULL)
4537         return SSL_FATAL_ERROR;
4538
4539     ssl->sessionSecretCb = cb;
4540     ssl->sessionSecretCtx = ctx;
4541     /* If using a pre-set key, assume session resumption. */
4542     ssl->session.sessionIDSz = 0;
4543     ssl->options.resuming = 1;
4544
4545     return SSL_SUCCESS;
4546 }
4547
4548 #endif
4549
4550
4551 #ifndef NO_SESSION_CACHE
4552
4553 /* on by default if built in but allow user to turn off */
4554 long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX* ctx, long mode)
4555 {
4556     WOLFSSL_ENTER("SSL_CTX_set_session_cache_mode");
4557     if (mode == SSL_SESS_CACHE_OFF)
4558         ctx->sessionCacheOff = 1;
4559
4560     if (mode == SSL_SESS_CACHE_NO_AUTO_CLEAR)
4561         ctx->sessionCacheFlushOff = 1;
4562
4563     return SSL_SUCCESS;
4564 }
4565
4566 #endif /* NO_SESSION_CACHE */
4567
4568
4569 #if !defined(NO_CERTS)
4570 #if defined(PERSIST_CERT_CACHE)
4571
4572
4573 #define WOLFSSL_CACHE_CERT_VERSION 1
4574
4575 typedef struct {
4576     int version;                 /* cache cert layout version id */
4577     int rows;                    /* hash table rows, CA_TABLE_SIZE */
4578     int columns[CA_TABLE_SIZE];  /* columns per row on list */
4579     int signerSz;                /* sizeof Signer object */
4580 } CertCacheHeader;
4581
4582 /* current cert persistance layout is:
4583
4584    1) CertCacheHeader
4585    2) caTable
4586
4587    update WOLFSSL_CERT_CACHE_VERSION if change layout for the following
4588    PERSIST_CERT_CACHE functions
4589 */
4590
4591
4592 /* Return memory needed to persist this signer, have lock */
4593 static INLINE int GetSignerMemory(Signer* signer)
4594 {
4595     int sz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID)
4596            + sizeof(signer->nameLen)    + sizeof(signer->subjectNameHash);
4597
4598 #if !defined(NO_SKID)
4599         sz += (int)sizeof(signer->subjectKeyIdHash);
4600 #endif
4601
4602     /* add dynamic bytes needed */
4603     sz += signer->pubKeySize;
4604     sz += signer->nameLen;
4605
4606     return sz;
4607 }
4608
4609
4610 /* Return memory needed to persist this row, have lock */
4611 static INLINE int GetCertCacheRowMemory(Signer* row)
4612 {
4613     int sz = 0;
4614
4615     while (row) {
4616         sz += GetSignerMemory(row);
4617         row = row->next;
4618     }
4619
4620     return sz;
4621 }
4622
4623
4624 /* get the size of persist cert cache, have lock */
4625 static INLINE int GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
4626 {
4627     int sz;
4628     int i;
4629
4630     sz = sizeof(CertCacheHeader);
4631
4632     for (i = 0; i < CA_TABLE_SIZE; i++)
4633         sz += GetCertCacheRowMemory(cm->caTable[i]);
4634
4635     return sz;
4636 }
4637
4638
4639 /* Store cert cache header columns with number of items per list, have lock */
4640 static INLINE void SetCertHeaderColumns(WOLFSSL_CERT_MANAGER* cm, int* columns)
4641 {
4642     int     i;
4643     Signer* row;
4644
4645     for (i = 0; i < CA_TABLE_SIZE; i++) {
4646         int count = 0;
4647         row = cm->caTable[i];
4648
4649         while (row) {
4650             ++count;
4651             row = row->next;
4652         }
4653         columns[i] = count;
4654     }
4655 }
4656
4657
4658 /* Restore whole cert row from memory, have lock, return bytes consumed,
4659    < 0 on error, have lock */
4660 static INLINE int RestoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current,
4661                                  int row, int listSz, const byte* end)
4662 {
4663     int idx = 0;
4664
4665     if (listSz < 0) {
4666         WOLFSSL_MSG("Row header corrupted, negative value");
4667         return PARSE_ERROR;
4668     }
4669
4670     while (listSz) {
4671         Signer* signer;
4672         byte*   start = current + idx;  /* for end checks on this signer */
4673         int     minSz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) +
4674                       sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
4675         #ifndef NO_SKID
4676                 minSz += (int)sizeof(signer->subjectKeyIdHash);
4677         #endif
4678
4679         if (start + minSz > end) {
4680             WOLFSSL_MSG("Would overread restore buffer");
4681             return BUFFER_E;
4682         }
4683         signer = MakeSigner(cm->heap);
4684         if (signer == NULL)
4685             return MEMORY_E;
4686
4687         /* pubKeySize */
4688         XMEMCPY(&signer->pubKeySize, current + idx, sizeof(signer->pubKeySize));
4689         idx += (int)sizeof(signer->pubKeySize);
4690
4691         /* keyOID */
4692         XMEMCPY(&signer->keyOID, current + idx, sizeof(signer->keyOID));
4693         idx += (int)sizeof(signer->keyOID);
4694
4695         /* pulicKey */
4696         if (start + minSz + signer->pubKeySize > end) {
4697             WOLFSSL_MSG("Would overread restore buffer");
4698             FreeSigner(signer, cm->heap);
4699             return BUFFER_E;
4700         }
4701         signer->publicKey = (byte*)XMALLOC(signer->pubKeySize, cm->heap,
4702                                            DYNAMIC_TYPE_KEY);
4703         if (signer->publicKey == NULL) {
4704             FreeSigner(signer, cm->heap);
4705             return MEMORY_E;
4706         }
4707
4708         XMEMCPY(signer->publicKey, current + idx, signer->pubKeySize);
4709         idx += signer->pubKeySize;
4710
4711         /* nameLen */
4712         XMEMCPY(&signer->nameLen, current + idx, sizeof(signer->nameLen));
4713         idx += (int)sizeof(signer->nameLen);
4714
4715         /* name */
4716         if (start + minSz + signer->pubKeySize + signer->nameLen > end) {
4717             WOLFSSL_MSG("Would overread restore buffer");
4718             FreeSigner(signer, cm->heap);
4719             return BUFFER_E;
4720         }
4721         signer->name = (char*)XMALLOC(signer->nameLen, cm->heap,
4722                                       DYNAMIC_TYPE_SUBJECT_CN);
4723         if (signer->name == NULL) {
4724             FreeSigner(signer, cm->heap);
4725             return MEMORY_E;
4726         }
4727
4728         XMEMCPY(signer->name, current + idx, signer->nameLen);
4729         idx += signer->nameLen;
4730
4731         /* subjectNameHash */
4732         XMEMCPY(signer->subjectNameHash, current + idx, SIGNER_DIGEST_SIZE);
4733         idx += SIGNER_DIGEST_SIZE;
4734
4735         #ifndef NO_SKID
4736             /* subjectKeyIdHash */
4737             XMEMCPY(signer->subjectKeyIdHash, current + idx,SIGNER_DIGEST_SIZE);
4738             idx += SIGNER_DIGEST_SIZE;
4739         #endif
4740
4741         signer->next = cm->caTable[row];
4742         cm->caTable[row] = signer;
4743
4744         --listSz;
4745     }
4746
4747     return idx;
4748 }
4749
4750
4751 /* Store whole cert row into memory, have lock, return bytes added */
4752 static INLINE int StoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current, int row)
4753 {
4754     int     added  = 0;
4755     Signer* list   = cm->caTable[row];
4756
4757     while (list) {
4758         XMEMCPY(current + added, &list->pubKeySize, sizeof(list->pubKeySize));
4759         added += (int)sizeof(list->pubKeySize);
4760
4761         XMEMCPY(current + added, &list->keyOID,     sizeof(list->keyOID));
4762         added += (int)sizeof(list->keyOID);
4763
4764         XMEMCPY(current + added, list->publicKey, list->pubKeySize);
4765         added += list->pubKeySize;
4766
4767         XMEMCPY(current + added, &list->nameLen, sizeof(list->nameLen));
4768         added += (int)sizeof(list->nameLen);
4769
4770         XMEMCPY(current + added, list->name, list->nameLen);
4771         added += list->nameLen;
4772
4773         XMEMCPY(current + added, list->subjectNameHash, SIGNER_DIGEST_SIZE);
4774         added += SIGNER_DIGEST_SIZE;
4775
4776         #ifndef NO_SKID
4777             XMEMCPY(current + added, list->subjectKeyIdHash,SIGNER_DIGEST_SIZE);
4778             added += SIGNER_DIGEST_SIZE;
4779         #endif
4780
4781         list = list->next;
4782     }
4783
4784     return added;
4785 }
4786
4787
4788 /* Persist cert cache to memory, have lock */
4789 static INLINE int DoMemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, void* mem, int sz)
4790 {
4791     int realSz;
4792     int ret = SSL_SUCCESS;
4793     int i;
4794
4795     WOLFSSL_ENTER("DoMemSaveCertCache");
4796
4797     realSz = GetCertCacheMemSize(cm);
4798     if (realSz > sz) {
4799         WOLFSSL_MSG("Mem output buffer too small");
4800         ret = BUFFER_E;
4801     }
4802     else {
4803         byte*           current;
4804         CertCacheHeader hdr;
4805
4806         hdr.version  = WOLFSSL_CACHE_CERT_VERSION;
4807         hdr.rows     = CA_TABLE_SIZE;
4808         SetCertHeaderColumns(cm, hdr.columns);
4809         hdr.signerSz = (int)sizeof(Signer);
4810
4811         XMEMCPY(mem, &hdr, sizeof(CertCacheHeader));
4812         current = (byte*)mem + sizeof(CertCacheHeader);
4813
4814         for (i = 0; i < CA_TABLE_SIZE; ++i)
4815             current += StoreCertRow(cm, current, i);
4816     }
4817
4818     return ret;
4819 }
4820
4821
4822 #if !defined(NO_FILESYSTEM)
4823
4824 /* Persist cert cache to file */
4825 int CM_SaveCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
4826 {
4827     XFILE file;
4828     int   rc = SSL_SUCCESS;
4829     int   memSz;
4830     byte* mem;
4831
4832     WOLFSSL_ENTER("CM_SaveCertCache");
4833
4834     file = XFOPEN(fname, "w+b");
4835     if (file == XBADFILE) {
4836        WOLFSSL_MSG("Couldn't open cert cache save file");
4837        return SSL_BAD_FILE;
4838     }
4839
4840     if (LockMutex(&cm->caLock) != 0) {
4841         WOLFSSL_MSG("LockMutex on caLock failed");
4842         XFCLOSE(file);
4843         return BAD_MUTEX_E;
4844     }
4845
4846     memSz = GetCertCacheMemSize(cm);
4847     mem   = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
4848     if (mem == NULL) {
4849         WOLFSSL_MSG("Alloc for tmp buffer failed");
4850         rc = MEMORY_E;
4851     } else {
4852         rc = DoMemSaveCertCache(cm, mem, memSz);
4853         if (rc == SSL_SUCCESS) {
4854             int ret = (int)XFWRITE(mem, memSz, 1, file);
4855             if (ret != 1) {
4856                 WOLFSSL_MSG("Cert cache file write failed");
4857                 rc = FWRITE_ERROR;
4858             }
4859         }
4860         XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
4861     }
4862
4863     UnLockMutex(&cm->caLock);
4864     XFCLOSE(file);
4865
4866     return rc;
4867 }
4868
4869
4870 /* Restore cert cache from file */
4871 int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
4872 {
4873     XFILE file;
4874     int   rc = SSL_SUCCESS;
4875     int   ret;
4876     int   memSz;
4877     byte* mem;
4878
4879     WOLFSSL_ENTER("CM_RestoreCertCache");
4880
4881     file = XFOPEN(fname, "rb");
4882     if (file == XBADFILE) {
4883        WOLFSSL_MSG("Couldn't open cert cache save file");
4884        return SSL_BAD_FILE;
4885     }
4886
4887     XFSEEK(file, 0, XSEEK_END);
4888     memSz = (int)XFTELL(file);
4889     XREWIND(file);
4890
4891     if (memSz <= 0) {
4892         WOLFSSL_MSG("Bad file size");
4893         XFCLOSE(file);
4894         return SSL_BAD_FILE;
4895     }
4896
4897     mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
4898     if (mem == NULL) {
4899         WOLFSSL_MSG("Alloc for tmp buffer failed");
4900         XFCLOSE(file);
4901         return MEMORY_E;
4902     }
4903
4904     ret = (int)XFREAD(mem, memSz, 1, file);
4905     if (ret != 1) {
4906         WOLFSSL_MSG("Cert file read error");
4907         rc = FREAD_ERROR;
4908     } else {
4909         rc = CM_MemRestoreCertCache(cm, mem, memSz);
4910         if (rc != SSL_SUCCESS) {
4911             WOLFSSL_MSG("Mem restore cert cache failed");
4912         }
4913     }
4914
4915     XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
4916     XFCLOSE(file);
4917
4918     return rc;
4919 }
4920
4921 #endif /* NO_FILESYSTEM */
4922
4923
4924 /* Persist cert cache to memory */
4925 int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, void* mem, int sz, int* used)
4926 {
4927     int ret = SSL_SUCCESS;
4928
4929     WOLFSSL_ENTER("CM_MemSaveCertCache");
4930
4931     if (LockMutex(&cm->caLock) != 0) {
4932         WOLFSSL_MSG("LockMutex on caLock failed");
4933         return BAD_MUTEX_E;
4934     }
4935
4936     ret = DoMemSaveCertCache(cm, mem, sz);
4937     if (ret == SSL_SUCCESS)
4938         *used  = GetCertCacheMemSize(cm);
4939
4940     UnLockMutex(&cm->caLock);
4941
4942     return ret;
4943 }
4944
4945
4946 /* Restore cert cache from memory */
4947 int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const void* mem, int sz)
4948 {
4949     int ret = SSL_SUCCESS;
4950     int i;
4951     CertCacheHeader* hdr = (CertCacheHeader*)mem;
4952     byte*            current = (byte*)mem + sizeof(CertCacheHeader);
4953     byte*            end     = (byte*)mem + sz;  /* don't go over */
4954
4955     WOLFSSL_ENTER("CM_MemRestoreCertCache");
4956
4957     if (current > end) {
4958         WOLFSSL_MSG("Cert Cache Memory buffer too small");
4959         return BUFFER_E;
4960     }
4961
4962     if (hdr->version  != WOLFSSL_CACHE_CERT_VERSION ||
4963         hdr->rows     != CA_TABLE_SIZE ||
4964         hdr->signerSz != (int)sizeof(Signer)) {
4965
4966         WOLFSSL_MSG("Cert Cache Memory header mismatch");
4967         return CACHE_MATCH_ERROR;
4968     }
4969
4970     if (LockMutex(&cm->caLock) != 0) {
4971         WOLFSSL_MSG("LockMutex on caLock failed");
4972         return BAD_MUTEX_E;
4973     }
4974
4975     FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
4976
4977     for (i = 0; i < CA_TABLE_SIZE; ++i) {
4978         int added = RestoreCertRow(cm, current, i, hdr->columns[i], end);
4979         if (added < 0) {
4980             WOLFSSL_MSG("RestoreCertRow error");
4981             ret = added;
4982             break;
4983         }
4984         current += added;
4985     }
4986
4987     UnLockMutex(&cm->caLock);
4988
4989     return ret;
4990 }
4991
4992
4993 /* get how big the the cert cache save buffer needs to be */
4994 int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
4995 {
4996     int sz;
4997
4998     WOLFSSL_ENTER("CM_GetCertCacheMemSize");
4999
5000     if (LockMutex(&cm->caLock) != 0) {
5001         WOLFSSL_MSG("LockMutex on caLock failed");
5002         return BAD_MUTEX_E;
5003     }
5004
5005     sz = GetCertCacheMemSize(cm);
5006
5007     UnLockMutex(&cm->caLock);
5008
5009     return sz;
5010 }
5011
5012 #endif /* PERSIST_CERT_CACHE */
5013 #endif /* NO_CERTS */
5014
5015
5016 int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX* ctx, const char* list)
5017 {
5018     WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list");
5019
5020     /* alloc/init on demand only */
5021     if (ctx->suites == NULL) {
5022         ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap,
5023                                        DYNAMIC_TYPE_SUITES);
5024         if (ctx->suites == NULL) {
5025             WOLFSSL_MSG("Memory alloc for Suites failed");
5026             return SSL_FAILURE;
5027         }
5028         XMEMSET(ctx->suites, 0, sizeof(Suites));
5029     }
5030
5031     return (SetCipherList(ctx->suites, list)) ? SSL_SUCCESS : SSL_FAILURE;
5032 }
5033
5034
5035 int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list)
5036 {
5037     WOLFSSL_ENTER("wolfSSL_set_cipher_list");
5038     return (SetCipherList(ssl->suites, list)) ? SSL_SUCCESS : SSL_FAILURE;
5039 }
5040
5041
5042 #ifndef WOLFSSL_LEANPSK
5043 #ifdef WOLFSSL_DTLS
5044
5045 int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl)
5046 {
5047     (void)ssl;
5048
5049     return ssl->dtls_timeout;
5050 }
5051
5052
5053 /* user may need to alter init dtls recv timeout, SSL_SUCCESS on ok */
5054 int wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int timeout)
5055 {
5056     if (ssl == NULL || timeout < 0)
5057         return BAD_FUNC_ARG;
5058
5059     if (timeout > ssl->dtls_timeout_max) {
5060         WOLFSSL_MSG("Can't set dtls timeout init greater than dtls timeout max");
5061         return BAD_FUNC_ARG;
5062     }
5063
5064     ssl->dtls_timeout_init = timeout;
5065     ssl->dtls_timeout = timeout;
5066
5067     return SSL_SUCCESS;
5068 }
5069
5070
5071 /* user may need to alter max dtls recv timeout, SSL_SUCCESS on ok */
5072 int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int timeout)
5073 {
5074     if (ssl == NULL || timeout < 0)
5075         return BAD_FUNC_ARG;
5076
5077     if (timeout < ssl->dtls_timeout_init) {
5078         WOLFSSL_MSG("Can't set dtls timeout max less than dtls timeout init");
5079         return BAD_FUNC_ARG;
5080     }
5081
5082     ssl->dtls_timeout_max = timeout;
5083
5084     return SSL_SUCCESS;
5085 }
5086
5087
5088 int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
5089 {
5090     int result = SSL_SUCCESS;
5091
5092     DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
5093     ssl->dtls_msg_list = NULL;
5094     if (DtlsPoolTimeout(ssl) < 0 || DtlsPoolSend(ssl) < 0) {
5095         result = SSL_FATAL_ERROR;
5096     }
5097     return result;
5098 }
5099
5100 #endif /* DTLS */
5101 #endif /* LEANPSK */
5102
5103
5104 /* client only parts */
5105 #ifndef NO_WOLFSSL_CLIENT
5106
5107     #ifndef NO_OLD_TLS
5108     WOLFSSL_METHOD* wolfSSLv3_client_method(void)
5109     {
5110         WOLFSSL_METHOD* method =
5111                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
5112                                                        DYNAMIC_TYPE_METHOD);
5113         WOLFSSL_ENTER("SSLv3_client_method");
5114         if (method)
5115             InitSSL_Method(method, MakeSSLv3());
5116         return method;
5117     }
5118     #endif
5119
5120     #ifdef WOLFSSL_DTLS
5121
5122         #ifndef NO_OLD_TLS
5123         WOLFSSL_METHOD* wolfDTLSv1_client_method(void)
5124         {
5125             WOLFSSL_METHOD* method =
5126                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
5127                                                        DYNAMIC_TYPE_METHOD);
5128             WOLFSSL_ENTER("DTLSv1_client_method");
5129             if (method)
5130                 InitSSL_Method(method, MakeDTLSv1());
5131             return method;
5132         }
5133         #endif  /* NO_OLD_TLS */
5134
5135         WOLFSSL_METHOD* wolfDTLSv1_2_client_method(void)
5136         {
5137             WOLFSSL_METHOD* method =
5138                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
5139                                                        DYNAMIC_TYPE_METHOD);
5140             WOLFSSL_ENTER("DTLSv1_2_client_method");
5141             if (method)
5142                 InitSSL_Method(method, MakeDTLSv1_2());
5143             return method;
5144         }
5145     #endif
5146
5147
5148     /* please see note at top of README if you get an error from connect */
5149     int wolfSSL_connect(WOLFSSL* ssl)
5150     {
5151         int neededState;
5152
5153         WOLFSSL_ENTER("SSL_connect()");
5154
5155         #ifdef HAVE_ERRNO_H
5156             errno = 0;
5157         #endif
5158
5159         if (ssl->options.side != WOLFSSL_CLIENT_END) {
5160             WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
5161             return SSL_FATAL_ERROR;
5162         }
5163
5164         #ifdef WOLFSSL_DTLS
5165             if (ssl->version.major == DTLS_MAJOR) {
5166                 ssl->options.dtls   = 1;
5167                 ssl->options.tls    = 1;
5168                 ssl->options.tls1_1 = 1;
5169
5170                 if (DtlsPoolInit(ssl) != 0) {
5171                     ssl->error = MEMORY_ERROR;
5172                     WOLFSSL_ERROR(ssl->error);
5173                     return SSL_FATAL_ERROR;
5174                 }
5175             }
5176         #endif
5177
5178         if (ssl->buffers.outputBuffer.length > 0) {
5179             if ( (ssl->error = SendBuffered(ssl)) == 0) {
5180                 ssl->options.connectState++;
5181                 WOLFSSL_MSG("connect state: Advanced from buffered send");
5182             }
5183             else {
5184                 WOLFSSL_ERROR(ssl->error);
5185                 return SSL_FATAL_ERROR;
5186             }
5187         }
5188
5189         switch (ssl->options.connectState) {
5190
5191         case CONNECT_BEGIN :
5192             /* always send client hello first */
5193             if ( (ssl->error = SendClientHello(ssl)) != 0) {
5194                 WOLFSSL_ERROR(ssl->error);
5195                 return SSL_FATAL_ERROR;
5196             }
5197             ssl->options.connectState = CLIENT_HELLO_SENT;
5198             WOLFSSL_MSG("connect state: CLIENT_HELLO_SENT");
5199
5200         case CLIENT_HELLO_SENT :
5201             neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
5202                                           SERVER_HELLODONE_COMPLETE;
5203             #ifdef WOLFSSL_DTLS
5204                 /* In DTLS, when resuming, we can go straight to FINISHED,
5205                  * or do a cookie exchange and then skip to FINISHED, assume
5206                  * we need the cookie exchange first. */
5207                 if (ssl->options.dtls)
5208                     neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
5209             #endif
5210             /* get response */
5211             while (ssl->options.serverState < neededState) {
5212                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
5213                     WOLFSSL_ERROR(ssl->error);
5214                     return SSL_FATAL_ERROR;
5215                 }
5216                 /* if resumption failed, reset needed state */
5217                 else if (neededState == SERVER_FINISHED_COMPLETE)
5218                     if (!ssl->options.resuming) {
5219                         if (!ssl->options.dtls)
5220                             neededState = SERVER_HELLODONE_COMPLETE;
5221                         else
5222                             neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
5223                     }
5224             }
5225
5226             ssl->options.connectState = HELLO_AGAIN;
5227             WOLFSSL_MSG("connect state: HELLO_AGAIN");
5228
5229         case HELLO_AGAIN :
5230             if (ssl->options.certOnly)
5231                 return SSL_SUCCESS;
5232
5233             #ifdef WOLFSSL_DTLS
5234                 if (ssl->options.dtls) {
5235                     /* re-init hashes, exclude first hello and verify request */
5236 #ifndef NO_OLD_TLS
5237                     wc_InitMd5(&ssl->hsHashes->hashMd5);
5238                     if ( (ssl->error = wc_InitSha(&ssl->hsHashes->hashSha))
5239                                                                          != 0) {
5240                         WOLFSSL_ERROR(ssl->error);
5241                         return SSL_FATAL_ERROR;
5242                     }
5243 #endif
5244                     if (IsAtLeastTLSv1_2(ssl)) {
5245                         #ifndef NO_SHA256
5246                             if ( (ssl->error = wc_InitSha256(
5247                                             &ssl->hsHashes->hashSha256)) != 0) {
5248                                 WOLFSSL_ERROR(ssl->error);
5249                                 return SSL_FATAL_ERROR;
5250                             }
5251                         #endif
5252                         #ifdef WOLFSSL_SHA384
5253                             if ( (ssl->error = wc_InitSha384(
5254                                             &ssl->hsHashes->hashSha384)) != 0) {
5255                                 WOLFSSL_ERROR(ssl->error);
5256                                 return SSL_FATAL_ERROR;
5257                             }
5258                         #endif
5259                         #ifdef WOLFSSL_SHA512
5260                             if ( (ssl->error = wc_InitSha512(
5261                                             &ssl->hsHashes->hashSha512)) != 0) {
5262                                 WOLFSSL_ERROR(ssl->error);
5263                                 return SSL_FATAL_ERROR;
5264                             }
5265                         #endif
5266                     }
5267                     if ( (ssl->error = SendClientHello(ssl)) != 0) {
5268                         WOLFSSL_ERROR(ssl->error);
5269                         return SSL_FATAL_ERROR;
5270                     }
5271                 }
5272             #endif
5273
5274             ssl->options.connectState = HELLO_AGAIN_REPLY;
5275             WOLFSSL_MSG("connect state: HELLO_AGAIN_REPLY");
5276
5277         case HELLO_AGAIN_REPLY :
5278             #ifdef WOLFSSL_DTLS
5279                 if (ssl->options.dtls) {
5280                     neededState = ssl->options.resuming ?
5281                            SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
5282
5283                     /* get response */
5284                     while (ssl->options.serverState < neededState) {
5285                         if ( (ssl->error = ProcessReply(ssl)) < 0) {
5286                                 WOLFSSL_ERROR(ssl->error);
5287                                 return SSL_FATAL_ERROR;
5288                         }
5289                         /* if resumption failed, reset needed state */
5290                         else if (neededState == SERVER_FINISHED_COMPLETE)
5291                             if (!ssl->options.resuming)
5292                                 neededState = SERVER_HELLODONE_COMPLETE;
5293                     }
5294                 }
5295             #endif
5296
5297             ssl->options.connectState = FIRST_REPLY_DONE;
5298             WOLFSSL_MSG("connect state: FIRST_REPLY_DONE");
5299
5300         case FIRST_REPLY_DONE :
5301             #ifndef NO_CERTS
5302                 if (ssl->options.sendVerify) {
5303                     if ( (ssl->error = SendCertificate(ssl)) != 0) {
5304                         WOLFSSL_ERROR(ssl->error);
5305                         return SSL_FATAL_ERROR;
5306                     }
5307                     WOLFSSL_MSG("sent: certificate");
5308                 }
5309
5310             #endif
5311             ssl->options.connectState = FIRST_REPLY_FIRST;
5312             WOLFSSL_MSG("connect state: FIRST_REPLY_FIRST");
5313
5314         case FIRST_REPLY_FIRST :
5315             if (!ssl->options.resuming) {
5316                 if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
5317                     WOLFSSL_ERROR(ssl->error);
5318                     return SSL_FATAL_ERROR;
5319                 }
5320                 WOLFSSL_MSG("sent: client key exchange");
5321             }
5322
5323             ssl->options.connectState = FIRST_REPLY_SECOND;
5324             WOLFSSL_MSG("connect state: FIRST_REPLY_SECOND");
5325
5326         case FIRST_REPLY_SECOND :
5327             #ifndef NO_CERTS
5328                 if (ssl->options.sendVerify) {
5329                     if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
5330                         WOLFSSL_ERROR(ssl->error);
5331                         return SSL_FATAL_ERROR;
5332                     }
5333                     WOLFSSL_MSG("sent: certificate verify");
5334                 }
5335             #endif
5336             ssl->options.connectState = FIRST_REPLY_THIRD;
5337             WOLFSSL_MSG("connect state: FIRST_REPLY_THIRD");
5338
5339         case FIRST_REPLY_THIRD :
5340             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
5341                 WOLFSSL_ERROR(ssl->error);
5342                 return SSL_FATAL_ERROR;
5343             }
5344             WOLFSSL_MSG("sent: change cipher spec");
5345             ssl->options.connectState = FIRST_REPLY_FOURTH;
5346             WOLFSSL_MSG("connect state: FIRST_REPLY_FOURTH");
5347
5348         case FIRST_REPLY_FOURTH :
5349             if ( (ssl->error = SendFinished(ssl)) != 0) {
5350                 WOLFSSL_ERROR(ssl->error);
5351                 return SSL_FATAL_ERROR;
5352             }
5353             WOLFSSL_MSG("sent: finished");
5354             ssl->options.connectState = FINISHED_DONE;
5355             WOLFSSL_MSG("connect state: FINISHED_DONE");
5356
5357         case FINISHED_DONE :
5358             /* get response */
5359             while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
5360                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
5361                     WOLFSSL_ERROR(ssl->error);
5362                     return SSL_FATAL_ERROR;
5363                 }
5364
5365             ssl->options.connectState = SECOND_REPLY_DONE;
5366             WOLFSSL_MSG("connect state: SECOND_REPLY_DONE");
5367
5368         case SECOND_REPLY_DONE:
5369 #ifndef NO_HANDSHAKE_DONE_CB
5370             if (ssl->hsDoneCb) {
5371                 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
5372                 if (cbret < 0) {
5373                     ssl->error = cbret;
5374                     WOLFSSL_MSG("HandShake Done Cb don't continue error");
5375                     return SSL_FATAL_ERROR;
5376                 }
5377             }
5378 #endif /* NO_HANDSHAKE_DONE_CB */
5379             FreeHandshakeResources(ssl);
5380             WOLFSSL_LEAVE("SSL_connect()", SSL_SUCCESS);
5381             return SSL_SUCCESS;
5382
5383         default:
5384             WOLFSSL_MSG("Unknown connect state ERROR");
5385             return SSL_FATAL_ERROR; /* unknown connect state */
5386         }
5387     }
5388
5389 #endif /* NO_WOLFSSL_CLIENT */
5390
5391
5392 /* server only parts */
5393 #ifndef NO_WOLFSSL_SERVER
5394
5395     #ifndef NO_OLD_TLS
5396     WOLFSSL_METHOD* wolfSSLv3_server_method(void)
5397     {
5398         WOLFSSL_METHOD* method =
5399                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
5400                                                        DYNAMIC_TYPE_METHOD);
5401         WOLFSSL_ENTER("SSLv3_server_method");
5402         if (method) {
5403             InitSSL_Method(method, MakeSSLv3());
5404             method->side = WOLFSSL_SERVER_END;
5405         }
5406         return method;
5407     }
5408     #endif
5409
5410
5411     #ifdef WOLFSSL_DTLS
5412
5413         #ifndef NO_OLD_TLS
5414         WOLFSSL_METHOD* wolfDTLSv1_server_method(void)
5415         {
5416             WOLFSSL_METHOD* method =
5417                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
5418                                                         0, DYNAMIC_TYPE_METHOD);
5419             WOLFSSL_ENTER("DTLSv1_server_method");
5420             if (method) {
5421                 InitSSL_Method(method, MakeDTLSv1());
5422                 method->side = WOLFSSL_SERVER_END;
5423             }
5424             return method;
5425         }
5426         #endif /* NO_OLD_TLS */
5427
5428         WOLFSSL_METHOD* wolfDTLSv1_2_server_method(void)
5429         {
5430             WOLFSSL_METHOD* method =
5431                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
5432                                                         0, DYNAMIC_TYPE_METHOD);
5433             WOLFSSL_ENTER("DTLSv1_2_server_method");
5434             if (method) {
5435                 InitSSL_Method(method, MakeDTLSv1_2());
5436                 method->side = WOLFSSL_SERVER_END;
5437             }
5438             return method;
5439         }
5440     #endif
5441
5442
5443     int wolfSSL_accept(WOLFSSL* ssl)
5444     {
5445         byte havePSK = 0;
5446         byte haveAnon = 0;
5447         WOLFSSL_ENTER("SSL_accept()");
5448
5449         #ifdef HAVE_ERRNO_H
5450             errno = 0;
5451         #endif
5452
5453         #ifndef NO_PSK
5454             havePSK = ssl->options.havePSK;
5455         #endif
5456         (void)havePSK;
5457
5458         #ifdef HAVE_ANON
5459             haveAnon = ssl->options.haveAnon;
5460         #endif
5461         (void)haveAnon;
5462
5463         if (ssl->options.side != WOLFSSL_SERVER_END) {
5464             WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
5465             return SSL_FATAL_ERROR;
5466         }
5467
5468         #ifndef NO_CERTS
5469             /* in case used set_accept_state after init */
5470             if (!havePSK && !haveAnon &&
5471                             (ssl->buffers.certificate.buffer == NULL ||
5472                              ssl->buffers.key.buffer == NULL)) {
5473                 WOLFSSL_MSG("accept error: don't have server cert and key");
5474                 ssl->error = NO_PRIVATE_KEY;
5475                 WOLFSSL_ERROR(ssl->error);
5476                 return SSL_FATAL_ERROR;
5477             }
5478         #endif
5479
5480         #ifdef WOLFSSL_DTLS
5481             if (ssl->version.major == DTLS_MAJOR) {
5482                 ssl->options.dtls   = 1;
5483                 ssl->options.tls    = 1;
5484                 ssl->options.tls1_1 = 1;
5485
5486                 if (DtlsPoolInit(ssl) != 0) {
5487                     ssl->error = MEMORY_ERROR;
5488                     WOLFSSL_ERROR(ssl->error);
5489                     return SSL_FATAL_ERROR;
5490                 }
5491             }
5492         #endif
5493
5494         if (ssl->buffers.outputBuffer.length > 0) {
5495             if ( (ssl->error = SendBuffered(ssl)) == 0) {
5496                 ssl->options.acceptState++;
5497                 WOLFSSL_MSG("accept state: Advanced from buffered send");
5498             }
5499             else {
5500                 WOLFSSL_ERROR(ssl->error);
5501                 return SSL_FATAL_ERROR;
5502             }
5503         }
5504
5505         switch (ssl->options.acceptState) {
5506
5507         case ACCEPT_BEGIN :
5508             /* get response */
5509             while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
5510                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
5511                     WOLFSSL_ERROR(ssl->error);
5512                     return SSL_FATAL_ERROR;
5513                 }
5514             ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
5515             WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
5516
5517         case ACCEPT_CLIENT_HELLO_DONE :
5518             #ifdef WOLFSSL_DTLS
5519                 if (ssl->options.dtls)
5520                     if ( (ssl->error = SendHelloVerifyRequest(ssl)) != 0) {
5521                         WOLFSSL_ERROR(ssl->error);
5522                         return SSL_FATAL_ERROR;
5523                     }
5524             #endif
5525             ssl->options.acceptState = HELLO_VERIFY_SENT;
5526             WOLFSSL_MSG("accept state HELLO_VERIFY_SENT");
5527
5528         case HELLO_VERIFY_SENT:
5529             #ifdef WOLFSSL_DTLS
5530                 if (ssl->options.dtls) {
5531                     ssl->options.clientState = NULL_STATE;  /* get again */
5532                     /* reset messages received */
5533                     XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
5534                     /* re-init hashes, exclude first hello and verify request */
5535 #ifndef NO_OLD_TLS
5536                     wc_InitMd5(&ssl->hsHashes->hashMd5);
5537                     if ( (ssl->error = wc_InitSha(&ssl->hsHashes->hashSha))
5538                                                                          != 0) {
5539                         WOLFSSL_ERROR(ssl->error);
5540                         return SSL_FATAL_ERROR;
5541                     }
5542 #endif
5543                     if (IsAtLeastTLSv1_2(ssl)) {
5544                         #ifndef NO_SHA256
5545                             if ( (ssl->error = wc_InitSha256(
5546                                             &ssl->hsHashes->hashSha256)) != 0) {
5547                                WOLFSSL_ERROR(ssl->error);
5548                                return SSL_FATAL_ERROR;
5549                             }
5550                         #endif
5551                         #ifdef WOLFSSL_SHA384
5552                             if ( (ssl->error = wc_InitSha384(
5553                                             &ssl->hsHashes->hashSha384)) != 0) {
5554                                WOLFSSL_ERROR(ssl->error);
5555                                return SSL_FATAL_ERROR;
5556                             }
5557                         #endif
5558                         #ifdef WOLFSSL_SHA512
5559                             if ( (ssl->error = wc_InitSha512(
5560                                             &ssl->hsHashes->hashSha512)) != 0) {
5561                                WOLFSSL_ERROR(ssl->error);
5562                                return SSL_FATAL_ERROR;
5563                             }
5564                         #endif
5565                     }
5566
5567                     while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
5568                         if ( (ssl->error = ProcessReply(ssl)) < 0) {
5569                             WOLFSSL_ERROR(ssl->error);
5570                             return SSL_FATAL_ERROR;
5571                         }
5572                 }
5573             #endif
5574             ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
5575             WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
5576
5577         case ACCEPT_FIRST_REPLY_DONE :
5578             if ( (ssl->error = SendServerHello(ssl)) != 0) {
5579                 WOLFSSL_ERROR(ssl->error);
5580                 return SSL_FATAL_ERROR;
5581             }
5582             ssl->options.acceptState = SERVER_HELLO_SENT;
5583             WOLFSSL_MSG("accept state SERVER_HELLO_SENT");
5584
5585         case SERVER_HELLO_SENT :
5586             #ifndef NO_CERTS
5587                 if (!ssl->options.resuming)
5588                     if ( (ssl->error = SendCertificate(ssl)) != 0) {
5589                         WOLFSSL_ERROR(ssl->error);
5590                         return SSL_FATAL_ERROR;
5591                     }
5592             #endif
5593             ssl->options.acceptState = CERT_SENT;
5594             WOLFSSL_MSG("accept state CERT_SENT");
5595
5596         case CERT_SENT :
5597             if (!ssl->options.resuming)
5598                 if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
5599                     WOLFSSL_ERROR(ssl->error);
5600                     return SSL_FATAL_ERROR;
5601                 }
5602             ssl->options.acceptState = KEY_EXCHANGE_SENT;
5603             WOLFSSL_MSG("accept state KEY_EXCHANGE_SENT");
5604
5605         case KEY_EXCHANGE_SENT :
5606             #ifndef NO_CERTS
5607                 if (!ssl->options.resuming)
5608                     if (ssl->options.verifyPeer)
5609                         if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
5610                             WOLFSSL_ERROR(ssl->error);
5611                             return SSL_FATAL_ERROR;
5612                         }
5613             #endif
5614             ssl->options.acceptState = CERT_REQ_SENT;
5615             WOLFSSL_MSG("accept state CERT_REQ_SENT");
5616
5617         case CERT_REQ_SENT :
5618             if (!ssl->options.resuming)
5619                 if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
5620                     WOLFSSL_ERROR(ssl->error);
5621                     return SSL_FATAL_ERROR;
5622                 }
5623             ssl->options.acceptState = SERVER_HELLO_DONE;
5624             WOLFSSL_MSG("accept state SERVER_HELLO_DONE");
5625
5626         case SERVER_HELLO_DONE :
5627             if (!ssl->options.resuming) {
5628                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
5629                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
5630                         WOLFSSL_ERROR(ssl->error);
5631                         return SSL_FATAL_ERROR;
5632                     }
5633             }
5634             ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
5635             WOLFSSL_MSG("accept state  ACCEPT_SECOND_REPLY_DONE");
5636
5637         case ACCEPT_SECOND_REPLY_DONE :
5638 #ifdef HAVE_SESSION_TICKET
5639             if (ssl->options.createTicket) {
5640                 if ( (ssl->error = SendTicket(ssl)) != 0) {
5641                     WOLFSSL_ERROR(ssl->error);
5642                     return SSL_FATAL_ERROR;
5643                 }
5644             }
5645 #endif /* HAVE_SESSION_TICKET */
5646             ssl->options.acceptState = TICKET_SENT;
5647             WOLFSSL_MSG("accept state  TICKET_SENT");
5648
5649         case TICKET_SENT:
5650             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
5651                 WOLFSSL_ERROR(ssl->error);
5652                 return SSL_FATAL_ERROR;
5653             }
5654             ssl->options.acceptState = CHANGE_CIPHER_SENT;
5655             WOLFSSL_MSG("accept state  CHANGE_CIPHER_SENT");
5656
5657         case CHANGE_CIPHER_SENT :
5658             if ( (ssl->error = SendFinished(ssl)) != 0) {
5659                 WOLFSSL_ERROR(ssl->error);
5660                 return SSL_FATAL_ERROR;
5661             }
5662
5663             ssl->options.acceptState = ACCEPT_FINISHED_DONE;
5664             WOLFSSL_MSG("accept state ACCEPT_FINISHED_DONE");
5665
5666         case ACCEPT_FINISHED_DONE :
5667             if (ssl->options.resuming)
5668                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
5669                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
5670                         WOLFSSL_ERROR(ssl->error);
5671                         return SSL_FATAL_ERROR;
5672                     }
5673
5674             ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
5675             WOLFSSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
5676
5677         case ACCEPT_THIRD_REPLY_DONE :
5678 #ifndef NO_HANDSHAKE_DONE_CB
5679             if (ssl->hsDoneCb) {
5680                 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
5681                 if (cbret < 0) {
5682                     ssl->error = cbret;
5683                     WOLFSSL_MSG("HandShake Done Cb don't continue error");
5684                     return SSL_FATAL_ERROR;
5685                 }
5686             }
5687 #endif /* NO_HANDSHAKE_DONE_CB */
5688             FreeHandshakeResources(ssl);
5689             WOLFSSL_LEAVE("SSL_accept()", SSL_SUCCESS);
5690             return SSL_SUCCESS;
5691
5692         default :
5693             WOLFSSL_MSG("Unknown accept state ERROR");
5694             return SSL_FATAL_ERROR;
5695         }
5696     }
5697
5698 #endif /* NO_WOLFSSL_SERVER */
5699
5700
5701 #ifndef NO_HANDSHAKE_DONE_CB
5702
5703 int wolfSSL_SetHsDoneCb(WOLFSSL* ssl, HandShakeDoneCb cb, void* user_ctx)
5704 {
5705     WOLFSSL_ENTER("wolfSSL_SetHsDoneCb");
5706
5707     if (ssl == NULL)
5708         return BAD_FUNC_ARG;
5709
5710     ssl->hsDoneCb  = cb;
5711     ssl->hsDoneCtx = user_ctx;
5712
5713
5714     return SSL_SUCCESS;
5715 }
5716
5717 #endif /* NO_HANDSHAKE_DONE_CB */
5718
5719
5720 int wolfSSL_Cleanup(void)
5721 {
5722     int ret = SSL_SUCCESS;
5723     int release = 0;
5724
5725     WOLFSSL_ENTER("wolfSSL_Cleanup");
5726
5727     if (initRefCount == 0)
5728         return ret;  /* possibly no init yet, but not failure either way */
5729
5730     if (LockMutex(&count_mutex) != 0) {
5731         WOLFSSL_MSG("Bad Lock Mutex count");
5732         return BAD_MUTEX_E;
5733     }
5734
5735     release = initRefCount-- == 1;
5736     if (initRefCount < 0)
5737         initRefCount = 0;
5738
5739     UnLockMutex(&count_mutex);
5740
5741     if (!release)
5742         return ret;
5743
5744 #ifndef NO_SESSION_CACHE
5745     if (FreeMutex(&session_mutex) != 0)
5746         ret = BAD_MUTEX_E;
5747 #endif
5748     if (FreeMutex(&count_mutex) != 0)
5749         ret = BAD_MUTEX_E;
5750
5751 #if defined(HAVE_ECC) && defined(FP_ECC)
5752     wc_ecc_fp_free();
5753 #endif
5754
5755     return ret;
5756 }
5757
5758
5759 #ifndef NO_SESSION_CACHE
5760
5761
5762 /* some session IDs aren't random afterall, let's make them random */
5763 static INLINE word32 HashSession(const byte* sessionID, word32 len, int* error)
5764 {
5765     byte digest[MAX_DIGEST_SIZE];
5766
5767 #ifndef NO_MD5
5768     *error =  wc_Md5Hash(sessionID, len, digest);
5769 #elif !defined(NO_SHA)
5770     *error =  wc_ShaHash(sessionID, len, digest);
5771 #elif !defined(NO_SHA256)
5772     *error =  wc_Sha256Hash(sessionID, len, digest);
5773 #else
5774     #error "We need a digest to hash the session IDs"
5775 #endif
5776
5777     return *error == 0 ? MakeWordFromHash(digest) : 0; /* 0 on failure */
5778 }
5779
5780
5781 void wolfSSL_flush_sessions(WOLFSSL_CTX* ctx, long tm)
5782 {
5783     /* static table now, no flusing needed */
5784     (void)ctx;
5785     (void)tm;
5786 }
5787
5788
5789 /* set ssl session timeout in seconds */
5790 int wolfSSL_set_timeout(WOLFSSL* ssl, unsigned int to)
5791 {
5792     if (ssl == NULL)
5793         return BAD_FUNC_ARG;
5794
5795     ssl->timeout = to;
5796
5797     return SSL_SUCCESS;
5798 }
5799
5800
5801 /* set ctx session timeout in seconds */
5802 int wolfSSL_CTX_set_timeout(WOLFSSL_CTX* ctx, unsigned int to)
5803 {
5804     if (ctx == NULL)
5805         return BAD_FUNC_ARG;
5806
5807     ctx->timeout = to;
5808
5809     return SSL_SUCCESS;
5810 }
5811
5812
5813 #ifndef NO_CLIENT_CACHE
5814
5815 /* Get Session from Client cache based on id/len, return NULL on failure */
5816 WOLFSSL_SESSION* GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
5817 {
5818     WOLFSSL_SESSION* ret = NULL;
5819     word32          row;
5820     int             idx;
5821     int             count;
5822     int             error = 0;
5823
5824     WOLFSSL_ENTER("GetSessionClient");
5825
5826     if (ssl->options.side == WOLFSSL_SERVER_END)
5827         return NULL;
5828
5829     len = min(SERVER_ID_LEN, (word32)len);
5830     row = HashSession(id, len, &error) % SESSION_ROWS;
5831     if (error != 0) {
5832         WOLFSSL_MSG("Hash session failed");
5833         return NULL;
5834     }
5835
5836     if (LockMutex(&session_mutex) != 0) {
5837         WOLFSSL_MSG("Lock session mutex failed");
5838         return NULL;
5839     }
5840
5841     /* start from most recently used */
5842     count = min((word32)ClientCache[row].totalCount, SESSIONS_PER_ROW);
5843     idx = ClientCache[row].nextIdx - 1;
5844     if (idx < 0)
5845         idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
5846
5847     for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
5848         WOLFSSL_SESSION* current;
5849         ClientSession   clSess;
5850
5851         if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
5852             WOLFSSL_MSG("Bad idx");
5853             break;
5854         }
5855
5856         clSess = ClientCache[row].Clients[idx];
5857
5858         current = &SessionCache[clSess.serverRow].Sessions[clSess.serverIdx];
5859         if (XMEMCMP(current->serverID, id, len) == 0) {
5860             WOLFSSL_MSG("Found a serverid match for client");
5861             if (LowResTimer() < (current->bornOn + current->timeout)) {
5862                 WOLFSSL_MSG("Session valid");
5863                 ret = current;
5864                 break;
5865             } else {
5866                 WOLFSSL_MSG("Session timed out");  /* could have more for id */
5867             }
5868         } else {
5869             WOLFSSL_MSG("ServerID not a match from client table");
5870         }
5871     }
5872
5873     UnLockMutex(&session_mutex);
5874
5875     return ret;
5876 }
5877
5878 #endif /* NO_CLIENT_CACHE */
5879
5880
5881 WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret)
5882 {
5883     WOLFSSL_SESSION* ret = 0;
5884     const byte*  id = NULL;
5885     word32       row;
5886     int          idx;
5887     int          count;
5888     int          error = 0;
5889
5890     if (ssl->options.sessionCacheOff)
5891         return NULL;
5892
5893     if (ssl->options.haveSessionId == 0)
5894         return NULL;
5895
5896 #ifdef HAVE_SESSION_TICKET
5897     if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
5898         return NULL;
5899 #endif
5900
5901     if (ssl->arrays)
5902         id = ssl->arrays->sessionID;
5903     else
5904         id = ssl->session.sessionID;
5905
5906     row = HashSession(id, ID_LEN, &error) % SESSION_ROWS;
5907     if (error != 0) {
5908         WOLFSSL_MSG("Hash session failed");
5909         return NULL;
5910     }
5911
5912     if (LockMutex(&session_mutex) != 0)
5913         return 0;
5914
5915     /* start from most recently used */
5916     count = min((word32)SessionCache[row].totalCount, SESSIONS_PER_ROW);
5917     idx = SessionCache[row].nextIdx - 1;
5918     if (idx < 0)
5919         idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
5920
5921     for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
5922         WOLFSSL_SESSION* current;
5923
5924         if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
5925             WOLFSSL_MSG("Bad idx");
5926             break;
5927         }
5928
5929         current = &SessionCache[row].Sessions[idx];
5930         if (XMEMCMP(current->sessionID, id, ID_LEN) == 0) {
5931             WOLFSSL_MSG("Found a session match");
5932             if (LowResTimer() < (current->bornOn + current->timeout)) {
5933                 WOLFSSL_MSG("Session valid");
5934                 ret = current;
5935                 if (masterSecret)
5936                     XMEMCPY(masterSecret, current->masterSecret, SECRET_LEN);
5937             } else {
5938                 WOLFSSL_MSG("Session timed out");
5939             }
5940             break;  /* no more sessionIDs whether valid or not that match */
5941         } else {
5942             WOLFSSL_MSG("SessionID not a match at this idx");
5943         }
5944     }
5945
5946     UnLockMutex(&session_mutex);
5947
5948     return ret;
5949 }
5950
5951
5952 int SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
5953 {
5954     if (ssl->options.sessionCacheOff)
5955         return SSL_FAILURE;
5956
5957     if (LowResTimer() < (session->bornOn + session->timeout)) {
5958         ssl->session  = *session;
5959         ssl->options.resuming = 1;
5960
5961 #ifdef SESSION_CERTS
5962         ssl->version              = session->version;
5963         ssl->options.cipherSuite0 = session->cipherSuite0;
5964         ssl->options.cipherSuite  = session->cipherSuite;
5965 #endif
5966
5967         return SSL_SUCCESS;
5968     }
5969     return SSL_FAILURE;  /* session timed out */
5970 }
5971
5972
5973 #ifdef WOLFSSL_SESSION_STATS
5974 static int get_locked_session_stats(word32* active, word32* total,
5975                                     word32* peak);
5976 #endif
5977
5978 int AddSession(WOLFSSL* ssl)
5979 {
5980     word32 row, idx;
5981     int    error = 0;
5982
5983     if (ssl->options.sessionCacheOff)
5984         return 0;
5985
5986     if (ssl->options.haveSessionId == 0)
5987         return 0;
5988
5989 #ifdef HAVE_SESSION_TICKET
5990     if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
5991         return 0;
5992 #endif
5993
5994     row = HashSession(ssl->arrays->sessionID, ID_LEN, &error) % SESSION_ROWS;
5995     if (error != 0) {
5996         WOLFSSL_MSG("Hash session failed");
5997         return error;
5998     }
5999
6000     if (LockMutex(&session_mutex) != 0)
6001         return BAD_MUTEX_E;
6002
6003     idx = SessionCache[row].nextIdx++;
6004 #ifdef SESSION_INDEX
6005     ssl->sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx;
6006 #endif
6007
6008     XMEMCPY(SessionCache[row].Sessions[idx].masterSecret,
6009            ssl->arrays->masterSecret, SECRET_LEN);
6010     XMEMCPY(SessionCache[row].Sessions[idx].sessionID, ssl->arrays->sessionID,
6011            ID_LEN);
6012     SessionCache[row].Sessions[idx].sessionIDSz = ssl->arrays->sessionIDSz;
6013
6014     SessionCache[row].Sessions[idx].timeout = ssl->timeout;
6015     SessionCache[row].Sessions[idx].bornOn  = LowResTimer();
6016
6017 #ifdef HAVE_SESSION_TICKET
6018     SessionCache[row].Sessions[idx].ticketLen     = ssl->session.ticketLen;
6019     XMEMCPY(SessionCache[row].Sessions[idx].ticket,
6020                                    ssl->session.ticket, ssl->session.ticketLen);
6021 #endif
6022
6023 #ifdef SESSION_CERTS
6024     SessionCache[row].Sessions[idx].chain.count = ssl->session.chain.count;
6025     XMEMCPY(SessionCache[row].Sessions[idx].chain.certs,
6026            ssl->session.chain.certs, sizeof(x509_buffer) * MAX_CHAIN_DEPTH);
6027
6028     SessionCache[row].Sessions[idx].version      = ssl->version;
6029     SessionCache[row].Sessions[idx].cipherSuite0 = ssl->options.cipherSuite0;
6030     SessionCache[row].Sessions[idx].cipherSuite  = ssl->options.cipherSuite;
6031 #endif /* SESSION_CERTS */
6032
6033     SessionCache[row].totalCount++;
6034     if (SessionCache[row].nextIdx == SESSIONS_PER_ROW)
6035         SessionCache[row].nextIdx = 0;
6036
6037 #ifndef NO_CLIENT_CACHE
6038     if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->session.idLen) {
6039         word32 clientRow, clientIdx;
6040
6041         WOLFSSL_MSG("Adding client cache entry");
6042
6043         SessionCache[row].Sessions[idx].idLen = ssl->session.idLen;
6044         XMEMCPY(SessionCache[row].Sessions[idx].serverID, ssl->session.serverID,
6045                 ssl->session.idLen);
6046
6047         clientRow = HashSession(ssl->session.serverID, ssl->session.idLen,
6048                                 &error) % SESSION_ROWS;
6049         if (error != 0) {
6050             WOLFSSL_MSG("Hash session failed");
6051         } else {
6052             clientIdx = ClientCache[clientRow].nextIdx++;
6053
6054             ClientCache[clientRow].Clients[clientIdx].serverRow = (word16)row;
6055             ClientCache[clientRow].Clients[clientIdx].serverIdx = (word16)idx;
6056
6057             ClientCache[clientRow].totalCount++;
6058             if (ClientCache[clientRow].nextIdx == SESSIONS_PER_ROW)
6059                 ClientCache[clientRow].nextIdx = 0;
6060         }
6061     }
6062     else
6063         SessionCache[row].Sessions[idx].idLen = 0;
6064 #endif /* NO_CLIENT_CACHE */
6065
6066 #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
6067     if (error == 0) {
6068         word32 active = 0;
6069
6070         error = get_locked_session_stats(&active, NULL, NULL);
6071         if (error == SSL_SUCCESS) {
6072             error = 0;  /* back to this function ok */
6073
6074             if (active > PeakSessions)
6075                 PeakSessions = active;
6076         }
6077     }
6078 #endif /* defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS) */
6079
6080     if (UnLockMutex(&session_mutex) != 0)
6081         return BAD_MUTEX_E;
6082
6083     return error;
6084 }
6085
6086
6087 #ifdef SESSION_INDEX
6088
6089 int wolfSSL_GetSessionIndex(WOLFSSL* ssl)
6090 {
6091     WOLFSSL_ENTER("wolfSSL_GetSessionIndex");
6092     WOLFSSL_LEAVE("wolfSSL_GetSessionIndex", ssl->sessionIndex);
6093     return ssl->sessionIndex;
6094 }
6095
6096
6097 int wolfSSL_GetSessionAtIndex(int idx, WOLFSSL_SESSION* session)
6098 {
6099     int row, col, result = SSL_FAILURE;
6100
6101     WOLFSSL_ENTER("wolfSSL_GetSessionAtIndex");
6102
6103     row = idx >> SESSIDX_ROW_SHIFT;
6104     col = idx & SESSIDX_IDX_MASK;
6105
6106     if (LockMutex(&session_mutex) != 0) {
6107         return BAD_MUTEX_E;
6108     }
6109
6110     if (row < SESSION_ROWS &&
6111         col < (int)min(SessionCache[row].totalCount, SESSIONS_PER_ROW)) {
6112         XMEMCPY(session,
6113                  &SessionCache[row].Sessions[col], sizeof(WOLFSSL_SESSION));
6114         result = SSL_SUCCESS;
6115     }
6116
6117     if (UnLockMutex(&session_mutex) != 0)
6118         result = BAD_MUTEX_E;
6119
6120     WOLFSSL_LEAVE("wolfSSL_GetSessionAtIndex", result);
6121     return result;
6122 }
6123
6124 #endif /* SESSION_INDEX */
6125
6126 #if defined(SESSION_INDEX) && defined(SESSION_CERTS)
6127
6128 WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session)
6129 {
6130     WOLFSSL_X509_CHAIN* chain = NULL;
6131
6132     WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
6133     if (session)
6134         chain = &session->chain;
6135
6136     WOLFSSL_LEAVE("wolfSSL_SESSION_get_peer_chain", chain ? 1 : 0);
6137     return chain;
6138 }
6139
6140 #endif /* SESSION_INDEX && SESSION_CERTS */
6141
6142
6143 #ifdef WOLFSSL_SESSION_STATS
6144
6145 /* requires session_mutex lock held, SSL_SUCCESS on ok */
6146 static int get_locked_session_stats(word32* active, word32* total, word32* peak)
6147 {
6148     int result = SSL_SUCCESS;
6149     int i;
6150     int count;
6151     int idx;
6152     word32 now   = 0;
6153     word32 seen  = 0;
6154     word32 ticks = LowResTimer();
6155
6156     (void)peak;
6157
6158     WOLFSSL_ENTER("get_locked_session_stats");
6159
6160     for (i = 0; i < SESSION_ROWS; i++) {
6161         seen += SessionCache[i].totalCount;
6162
6163         if (active == NULL)
6164             continue;  /* no need to calculate what we can't set */
6165
6166         count = min((word32)SessionCache[i].totalCount, SESSIONS_PER_ROW);
6167         idx   = SessionCache[i].nextIdx - 1;
6168         if (idx < 0)
6169             idx = SESSIONS_PER_ROW - 1; /* if back to front previous was end */
6170
6171         for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
6172             if (idx >= SESSIONS_PER_ROW || idx < 0) {  /* sanity check */
6173                 WOLFSSL_MSG("Bad idx");
6174                 break;
6175             }
6176
6177             /* if not expried then good */
6178             if (ticks < (SessionCache[i].Sessions[idx].bornOn +
6179                          SessionCache[i].Sessions[idx].timeout) ) {
6180                 now++;
6181             }
6182         }
6183     }
6184
6185     if (active)
6186         *active = now;
6187
6188     if (total)
6189         *total = seen;
6190
6191 #ifdef WOLFSSL_PEAK_SESSIONS
6192     if (peak)
6193         *peak = PeakSessions;
6194 #endif
6195
6196     WOLFSSL_LEAVE("get_locked_session_stats", result);
6197
6198     return result;
6199 }
6200
6201
6202 /* return SSL_SUCCESS on ok */
6203 int wolfSSL_get_session_stats(word32* active, word32* total, word32* peak,
6204                               word32* maxSessions)
6205 {
6206     int result = SSL_SUCCESS;
6207
6208     WOLFSSL_ENTER("wolfSSL_get_session_stats");
6209
6210     if (maxSessions) {
6211         *maxSessions = SESSIONS_PER_ROW * SESSION_ROWS;
6212
6213         if (active == NULL && total == NULL && peak == NULL)
6214             return result;  /* we're done */
6215     }
6216
6217     /* user must provide at least one query value */
6218     if (active == NULL && total == NULL && peak == NULL)
6219         return BAD_FUNC_ARG;
6220
6221     if (LockMutex(&session_mutex) != 0) {
6222         return BAD_MUTEX_E;
6223     }
6224
6225     result = get_locked_session_stats(active, total, peak);
6226
6227     if (UnLockMutex(&session_mutex) != 0)
6228         result = BAD_MUTEX_E;
6229
6230     WOLFSSL_LEAVE("wolfSSL_get_session_stats", result);
6231
6232     return result;
6233 }
6234
6235 #endif /* WOLFSSL_SESSION_STATS */
6236
6237
6238     #ifdef PRINT_SESSION_STATS
6239
6240     /* SSL_SUCCESS on ok */
6241     int wolfSSL_PrintSessionStats(void)
6242     {
6243         word32 totalSessionsSeen = 0;
6244         word32 totalSessionsNow = 0;
6245         word32 peak = 0;
6246         word32 maxSessions = 0;
6247         int    i;
6248         int    ret;
6249         double E;               /* expected freq */
6250         double chiSquare = 0;
6251
6252         ret = wolfSSL_get_session_stats(&totalSessionsNow, &totalSessionsSeen,
6253                                         &peak, &maxSessions);
6254         if (ret != SSL_SUCCESS)
6255             return ret;
6256         printf("Total Sessions Seen = %d\n", totalSessionsSeen);
6257         printf("Total Sessions Now  = %d\n", totalSessionsNow);
6258 #ifdef WOLFSSL_PEAK_SESSIONS
6259         printf("Peak  Sessions      = %d\n", peak);
6260 #endif
6261         printf("Max   Sessions      = %d\n", maxSessions);
6262
6263         E = (double)totalSessionsSeen / SESSION_ROWS;
6264
6265         for (i = 0; i < SESSION_ROWS; i++) {
6266             double diff = SessionCache[i].totalCount - E;
6267             diff *= diff;                /* square    */
6268             diff /= E;                   /* normalize */
6269
6270             chiSquare += diff;
6271         }
6272         printf("  chi-square = %5.1f, d.f. = %d\n", chiSquare,
6273                                                      SESSION_ROWS - 1);
6274         #if (SESSION_ROWS == 11)
6275             printf(" .05 p value =  18.3, chi-square should be less\n");
6276         #elif (SESSION_ROWS == 211)
6277             printf(".05 p value  = 244.8, chi-square should be less\n");
6278         #elif (SESSION_ROWS == 5981)
6279             printf(".05 p value  = 6161.0, chi-square should be less\n");
6280         #elif (SESSION_ROWS == 3)
6281             printf(".05 p value  =   6.0, chi-square should be less\n");
6282         #elif (SESSION_ROWS == 2861)
6283             printf(".05 p value  = 2985.5, chi-square should be less\n");
6284         #endif
6285         printf("\n");
6286
6287         return ret;
6288     }
6289
6290     #endif /* SESSION_STATS */
6291
6292 #else  /* NO_SESSION_CACHE */
6293
6294 /* No session cache version */
6295 WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret)
6296 {
6297     (void)ssl;
6298     (void)masterSecret;
6299
6300     return NULL;
6301 }
6302
6303 #endif /* NO_SESSION_CACHE */
6304
6305
6306 /* call before SSL_connect, if verifying will add name check to
6307    date check and signature check */
6308 int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
6309 {
6310     WOLFSSL_ENTER("wolfSSL_check_domain_name");
6311     if (ssl->buffers.domainName.buffer)
6312         XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
6313
6314     ssl->buffers.domainName.length = (word32)XSTRLEN(dn) + 1;
6315     ssl->buffers.domainName.buffer = (byte*) XMALLOC(
6316                 ssl->buffers.domainName.length, ssl->heap, DYNAMIC_TYPE_DOMAIN);
6317
6318     if (ssl->buffers.domainName.buffer) {
6319         XSTRNCPY((char*)ssl->buffers.domainName.buffer, dn,
6320                 ssl->buffers.domainName.length);
6321         return SSL_SUCCESS;
6322     }
6323     else {
6324         ssl->error = MEMORY_ERROR;
6325         return SSL_FAILURE;
6326     }
6327 }
6328
6329
6330 /* turn on wolfSSL zlib compression
6331    returns SSL_SUCCESS for success, else error (not built in)
6332 */
6333 int wolfSSL_set_compression(WOLFSSL* ssl)
6334 {
6335     WOLFSSL_ENTER("wolfSSL_set_compression");
6336     (void)ssl;
6337 #ifdef HAVE_LIBZ
6338     ssl->options.usingCompression = 1;
6339     return SSL_SUCCESS;
6340 #else
6341     return NOT_COMPILED_IN;
6342 #endif
6343 }
6344
6345
6346 #ifndef USE_WINDOWS_API
6347     #ifndef NO_WRITEV
6348
6349         /* simulate writev semantics, doesn't actually do block at a time though
6350            because of SSL_write behavior and because front adds may be small */
6351         int wolfSSL_writev(WOLFSSL* ssl, const struct iovec* iov, int iovcnt)
6352         {
6353         #ifdef WOLFSSL_SMALL_STACK
6354             byte   staticBuffer[1]; /* force heap usage */
6355         #else
6356             byte   staticBuffer[FILE_BUFFER_SIZE];
6357         #endif
6358             byte* myBuffer  = staticBuffer;
6359             int   dynamic   = 0;
6360             int   sending   = 0;
6361             int   idx       = 0;
6362             int   i;
6363             int   ret;
6364
6365             WOLFSSL_ENTER("wolfSSL_writev");
6366
6367             for (i = 0; i < iovcnt; i++)
6368                 sending += (int)iov[i].iov_len;
6369
6370             if (sending > (int)sizeof(staticBuffer)) {
6371                 myBuffer = (byte*)XMALLOC(sending, ssl->heap,
6372                                                            DYNAMIC_TYPE_WRITEV);
6373                 if (!myBuffer)
6374                     return MEMORY_ERROR;
6375
6376                 dynamic = 1;
6377             }
6378
6379             for (i = 0; i < iovcnt; i++) {
6380                 XMEMCPY(&myBuffer[idx], iov[i].iov_base, iov[i].iov_len);
6381                 idx += (int)iov[i].iov_len;
6382             }
6383
6384             ret = wolfSSL_write(ssl, myBuffer, sending);
6385
6386             if (dynamic)
6387                 XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
6388
6389             return ret;
6390         }
6391     #endif
6392 #endif
6393
6394
6395 #ifdef WOLFSSL_CALLBACKS
6396
6397     typedef struct itimerval Itimerval;
6398
6399     /* don't keep calling simple functions while setting up timer and singals
6400        if no inlining these are the next best */
6401
6402     #define AddTimes(a, b, c)                       \
6403         do {                                        \
6404             c.tv_sec  = a.tv_sec  + b.tv_sec;       \
6405             c.tv_usec = a.tv_usec + b.tv_usec;      \
6406             if (c.tv_usec >=  1000000) {            \
6407                 c.tv_sec++;                         \
6408                 c.tv_usec -= 1000000;               \
6409             }                                       \
6410         } while (0)
6411
6412
6413     #define SubtractTimes(a, b, c)                  \
6414         do {                                        \
6415             c.tv_sec  = a.tv_sec  - b.tv_sec;       \
6416             c.tv_usec = a.tv_usec - b.tv_usec;      \
6417             if (c.tv_usec < 0) {                    \
6418                 c.tv_sec--;                         \
6419                 c.tv_usec += 1000000;               \
6420             }                                       \
6421         } while (0)
6422
6423     #define CmpTimes(a, b, cmp)                     \
6424         ((a.tv_sec  ==  b.tv_sec) ?                 \
6425             (a.tv_usec cmp b.tv_usec) :             \
6426             (a.tv_sec  cmp b.tv_sec))               \
6427
6428
6429     /* do nothing handler */
6430     static void myHandler(int signo)
6431     {
6432         (void)signo;
6433         return;
6434     }
6435
6436
6437     static int wolfSSL_ex_wrapper(WOLFSSL* ssl, HandShakeCallBack hsCb,
6438                                  TimeoutCallBack toCb, Timeval timeout)
6439     {
6440         int       ret        = SSL_FATAL_ERROR;
6441         int       oldTimerOn = 0;   /* was timer already on */
6442         Timeval   startTime;
6443         Timeval   endTime;
6444         Timeval   totalTime;
6445         Itimerval myTimeout;
6446         Itimerval oldTimeout; /* if old timer adjust from total time to reset */
6447         struct sigaction act, oact;
6448
6449         #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
6450
6451         if (hsCb) {
6452             ssl->hsInfoOn = 1;
6453             InitHandShakeInfo(&ssl->handShakeInfo);
6454         }
6455         if (toCb) {
6456             ssl->toInfoOn = 1;
6457             InitTimeoutInfo(&ssl->timeoutInfo);
6458
6459             if (gettimeofday(&startTime, 0) < 0)
6460                 ERR_OUT(GETTIME_ERROR);
6461
6462             /* use setitimer to simulate getitimer, init 0 myTimeout */
6463             myTimeout.it_interval.tv_sec  = 0;
6464             myTimeout.it_interval.tv_usec = 0;
6465             myTimeout.it_value.tv_sec     = 0;
6466             myTimeout.it_value.tv_usec    = 0;
6467             if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
6468                 ERR_OUT(SETITIMER_ERROR);
6469
6470             if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
6471                 oldTimerOn = 1;
6472
6473                 /* is old timer going to expire before ours */
6474                 if (CmpTimes(oldTimeout.it_value, timeout, <)) {
6475                     timeout.tv_sec  = oldTimeout.it_value.tv_sec;
6476                     timeout.tv_usec = oldTimeout.it_value.tv_usec;
6477                 }
6478             }
6479             myTimeout.it_value.tv_sec  = timeout.tv_sec;
6480             myTimeout.it_value.tv_usec = timeout.tv_usec;
6481
6482             /* set up signal handler, don't restart socket send/recv */
6483             act.sa_handler = myHandler;
6484             sigemptyset(&act.sa_mask);
6485             act.sa_flags = 0;
6486 #ifdef SA_INTERRUPT
6487             act.sa_flags |= SA_INTERRUPT;
6488 #endif
6489             if (sigaction(SIGALRM, &act, &oact) < 0)
6490                 ERR_OUT(SIGACT_ERROR);
6491
6492             if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
6493                 ERR_OUT(SETITIMER_ERROR);
6494         }
6495
6496         /* do main work */
6497 #ifndef NO_WOLFSSL_CLIENT
6498         if (ssl->options.side == WOLFSSL_CLIENT_END)
6499             ret = wolfSSL_connect(ssl);
6500 #endif
6501 #ifndef NO_WOLFSSL_SERVER
6502         if (ssl->options.side == WOLFSSL_SERVER_END)
6503             ret = wolfSSL_accept(ssl);
6504 #endif
6505
6506         /* do callbacks */
6507         if (toCb) {
6508             if (oldTimerOn) {
6509                 gettimeofday(&endTime, 0);
6510                 SubtractTimes(endTime, startTime, totalTime);
6511                 /* adjust old timer for elapsed time */
6512                 if (CmpTimes(totalTime, oldTimeout.it_value, <))
6513                     SubtractTimes(oldTimeout.it_value, totalTime,
6514                                   oldTimeout.it_value);
6515                 else {
6516                     /* reset value to interval, may be off */
6517                     oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
6518                     oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
6519                 }
6520                 /* keep iter the same whether there or not */
6521             }
6522             /* restore old handler */
6523             if (sigaction(SIGALRM, &oact, 0) < 0)
6524                 ret = SIGACT_ERROR;    /* more pressing error, stomp */
6525             else
6526                 /* use old settings which may turn off (expired or not there) */
6527                 if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
6528                     ret = SETITIMER_ERROR;
6529
6530             /* if we had a timeout call callback */
6531             if (ssl->timeoutInfo.timeoutName[0]) {
6532                 ssl->timeoutInfo.timeoutValue.tv_sec  = timeout.tv_sec;
6533                 ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
6534                 (toCb)(&ssl->timeoutInfo);
6535             }
6536             /* clean up */
6537             FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
6538             ssl->toInfoOn = 0;
6539         }
6540         if (hsCb) {
6541             FinishHandShakeInfo(&ssl->handShakeInfo, ssl);
6542             (hsCb)(&ssl->handShakeInfo);
6543             ssl->hsInfoOn = 0;
6544         }
6545         return ret;
6546     }
6547
6548
6549 #ifndef NO_WOLFSSL_CLIENT
6550
6551     int wolfSSL_connect_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
6552                           TimeoutCallBack toCb, Timeval timeout)
6553     {
6554         WOLFSSL_ENTER("wolfSSL_connect_ex");
6555         return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
6556     }
6557
6558 #endif
6559
6560
6561 #ifndef NO_WOLFSSL_SERVER
6562
6563     int wolfSSL_accept_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
6564                          TimeoutCallBack toCb,Timeval timeout)
6565     {
6566         WOLFSSL_ENTER("wolfSSL_accept_ex");
6567         return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
6568     }
6569
6570 #endif
6571
6572 #endif /* WOLFSSL_CALLBACKS */
6573
6574
6575 #ifndef NO_PSK
6576
6577     void wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX* ctx,
6578                                          psk_client_callback cb)
6579     {
6580         WOLFSSL_ENTER("SSL_CTX_set_psk_client_callback");
6581         ctx->havePSK = 1;
6582         ctx->client_psk_cb = cb;
6583     }
6584
6585
6586     void wolfSSL_set_psk_client_callback(WOLFSSL* ssl, psk_client_callback cb)
6587     {
6588         byte haveRSA = 1;
6589
6590         WOLFSSL_ENTER("SSL_set_psk_client_callback");
6591         ssl->options.havePSK = 1;
6592         ssl->options.client_psk_cb = cb;
6593
6594         #ifdef NO_RSA
6595             haveRSA = 0;
6596         #endif
6597         InitSuites(ssl->suites, ssl->version, haveRSA, TRUE,
6598                    ssl->options.haveDH, ssl->options.haveNTRU,
6599                    ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
6600                    ssl->options.side);
6601     }
6602
6603
6604     void wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX* ctx,
6605                                          psk_server_callback cb)
6606     {
6607         WOLFSSL_ENTER("SSL_CTX_set_psk_server_callback");
6608         ctx->havePSK = 1;
6609         ctx->server_psk_cb = cb;
6610     }
6611
6612
6613     void wolfSSL_set_psk_server_callback(WOLFSSL* ssl, psk_server_callback cb)
6614     {
6615         byte haveRSA = 1;
6616
6617         WOLFSSL_ENTER("SSL_set_psk_server_callback");
6618         ssl->options.havePSK = 1;
6619         ssl->options.server_psk_cb = cb;
6620
6621         #ifdef NO_RSA
6622             haveRSA = 0;
6623         #endif
6624         InitSuites(ssl->suites, ssl->version, haveRSA, TRUE,
6625                    ssl->options.haveDH, ssl->options.haveNTRU,
6626                    ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
6627                    ssl->options.side);
6628     }
6629
6630
6631     const char* wolfSSL_get_psk_identity_hint(const WOLFSSL* ssl)
6632     {
6633         WOLFSSL_ENTER("SSL_get_psk_identity_hint");
6634
6635         if (ssl == NULL || ssl->arrays == NULL)
6636             return NULL;
6637
6638         return ssl->arrays->server_hint;
6639     }
6640
6641
6642     const char* wolfSSL_get_psk_identity(const WOLFSSL* ssl)
6643     {
6644         WOLFSSL_ENTER("SSL_get_psk_identity");
6645
6646         if (ssl == NULL || ssl->arrays == NULL)
6647             return NULL;
6648
6649         return ssl->arrays->client_identity;
6650     }
6651
6652
6653     int wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX* ctx, const char* hint)
6654     {
6655         WOLFSSL_ENTER("SSL_CTX_use_psk_identity_hint");
6656         if (hint == 0)
6657             ctx->server_hint[0] = 0;
6658         else {
6659             XSTRNCPY(ctx->server_hint, hint, MAX_PSK_ID_LEN);
6660             ctx->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
6661         }
6662         return SSL_SUCCESS;
6663     }
6664
6665
6666     int wolfSSL_use_psk_identity_hint(WOLFSSL* ssl, const char* hint)
6667     {
6668         WOLFSSL_ENTER("SSL_use_psk_identity_hint");
6669
6670         if (ssl == NULL || ssl->arrays == NULL)
6671             return SSL_FAILURE;
6672
6673         if (hint == 0)
6674             ssl->arrays->server_hint[0] = 0;
6675         else {
6676             XSTRNCPY(ssl->arrays->server_hint, hint, MAX_PSK_ID_LEN);
6677             ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
6678         }
6679         return SSL_SUCCESS;
6680     }
6681
6682 #endif /* NO_PSK */
6683
6684
6685 #ifdef HAVE_ANON
6686
6687     int wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX* ctx)
6688     {
6689         WOLFSSL_ENTER("wolfSSL_CTX_allow_anon_cipher");
6690
6691         if (ctx == NULL)
6692             return SSL_FAILURE;
6693
6694         ctx->haveAnon = 1;
6695
6696         return SSL_SUCCESS;
6697     }
6698
6699 #endif /* HAVE_ANON */
6700
6701
6702 #ifndef NO_CERTS
6703 /* used to be defined on NO_FILESYSTEM only, but are generally useful */
6704
6705     /* wolfSSL extension allows DER files to be loaded from buffers as well */
6706     int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX* ctx, const unsigned char* in,
6707                                       long sz, int format)
6708     {
6709         WOLFSSL_ENTER("wolfSSL_CTX_load_verify_buffer");
6710         if (format == SSL_FILETYPE_PEM)
6711             return ProcessChainBuffer(ctx, in, sz, format, CA_TYPE, NULL);
6712         else
6713             return ProcessBuffer(ctx, in, sz, format, CA_TYPE, NULL,NULL,0);
6714     }
6715
6716
6717     int wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX* ctx,
6718                                  const unsigned char* in, long sz, int format)
6719     {
6720         WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_buffer");
6721         return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 0);
6722     }
6723
6724
6725     int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX* ctx,
6726                                  const unsigned char* in, long sz, int format)
6727     {
6728         WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_buffer");
6729         return ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL,NULL,0);
6730     }
6731
6732
6733     int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
6734                                  const unsigned char* in, long sz)
6735     {
6736         WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_buffer");
6737         return ProcessBuffer(ctx, in, sz, SSL_FILETYPE_PEM, CERT_TYPE, NULL,
6738                              NULL, 1);
6739     }
6740
6741     int wolfSSL_use_certificate_buffer(WOLFSSL* ssl,
6742                                  const unsigned char* in, long sz, int format)
6743     {
6744         WOLFSSL_ENTER("wolfSSL_use_certificate_buffer");
6745         return ProcessBuffer(ssl->ctx, in, sz, format,CERT_TYPE,ssl,NULL,0);
6746     }
6747
6748
6749     int wolfSSL_use_PrivateKey_buffer(WOLFSSL* ssl,
6750                                  const unsigned char* in, long sz, int format)
6751     {
6752         WOLFSSL_ENTER("wolfSSL_use_PrivateKey_buffer");
6753         return ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE,
6754                              ssl, NULL, 0);
6755     }
6756
6757
6758     int wolfSSL_use_certificate_chain_buffer(WOLFSSL* ssl,
6759                                  const unsigned char* in, long sz)
6760     {
6761         WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer");
6762         return ProcessBuffer(ssl->ctx, in, sz, SSL_FILETYPE_PEM, CERT_TYPE,
6763                              ssl, NULL, 1);
6764     }
6765
6766
6767     /* unload any certs or keys that SSL owns, leave CTX as is
6768        SSL_SUCCESS on ok */
6769     int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl)
6770     {
6771         if (ssl == NULL) {
6772             WOLFSSL_MSG("Null function arg");
6773             return BAD_FUNC_ARG;
6774         }
6775
6776         if (ssl->buffers.weOwnCert) {
6777             WOLFSSL_MSG("Unloading cert");
6778             XFREE(ssl->buffers.certificate.buffer, ssl->heap,DYNAMIC_TYPE_CERT);
6779             ssl->buffers.weOwnCert = 0;
6780             ssl->buffers.certificate.length = 0;
6781             ssl->buffers.certificate.buffer = NULL;
6782         }
6783
6784         if (ssl->buffers.weOwnCertChain) {
6785             WOLFSSL_MSG("Unloading cert chain");
6786             XFREE(ssl->buffers.certChain.buffer, ssl->heap,DYNAMIC_TYPE_CERT);
6787             ssl->buffers.weOwnCertChain = 0;
6788             ssl->buffers.certChain.length = 0;
6789             ssl->buffers.certChain.buffer = NULL;
6790         }
6791
6792         if (ssl->buffers.weOwnKey) {
6793             WOLFSSL_MSG("Unloading key");
6794             XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
6795             ssl->buffers.weOwnKey = 0;
6796             ssl->buffers.key.length = 0;
6797             ssl->buffers.key.buffer = NULL;
6798         }
6799
6800         return SSL_SUCCESS;
6801     }
6802
6803
6804     int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx)
6805     {
6806         WOLFSSL_ENTER("wolfSSL_CTX_UnloadCAs");
6807
6808         if (ctx == NULL)
6809             return BAD_FUNC_ARG;
6810
6811         return wolfSSL_CertManagerUnloadCAs(ctx->cm);
6812     }
6813
6814 /* old NO_FILESYSTEM end */
6815 #endif /* !NO_CERTS */
6816
6817
6818 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
6819
6820
6821     int wolfSSL_add_all_algorithms(void)
6822     {
6823         WOLFSSL_ENTER("wolfSSL_add_all_algorithms");
6824         wolfSSL_Init();
6825         return SSL_SUCCESS;
6826     }
6827
6828
6829     long wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX* ctx, long sz)
6830     {
6831         /* cache size fixed at compile time in wolfSSL */
6832         (void)ctx;
6833         (void)sz;
6834         return 0;
6835     }
6836
6837
6838     void wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX* ctx, int mode)
6839     {
6840         WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
6841         if (mode)
6842             ctx->quietShutdown = 1;
6843     }
6844
6845
6846     void wolfSSL_set_quiet_shutdown(WOLFSSL* ssl, int mode)
6847     {
6848         WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
6849         if (mode)
6850             ssl->options.quietShutdown = 1;
6851     }
6852
6853
6854     void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr)
6855     {
6856         WOLFSSL_ENTER("SSL_set_bio");
6857         wolfSSL_set_rfd(ssl, rd->fd);
6858         wolfSSL_set_wfd(ssl, wr->fd);
6859
6860         ssl->biord = rd;
6861         ssl->biowr = wr;
6862     }
6863
6864
6865     void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX* ctx,
6866                                        STACK_OF(WOLFSSL_X509_NAME)* names)
6867     {
6868         (void)ctx;
6869         (void)names;
6870     }
6871
6872
6873     STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char* fname)
6874     {
6875         (void)fname;
6876         return 0;
6877     }
6878
6879
6880     int wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX* ctx)
6881     {
6882         /* TODO:, not needed in goahead */
6883         (void)ctx;
6884         return SSL_NOT_IMPLEMENTED;
6885     }
6886
6887
6888     /* keyblock size in bytes or -1 */
6889     int wolfSSL_get_keyblock_size(WOLFSSL* ssl)
6890     {
6891         if (ssl == NULL)
6892             return SSL_FATAL_ERROR;
6893
6894         return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
6895                     ssl->specs.hash_size);
6896     }
6897
6898
6899     /* store keys returns SSL_SUCCESS or -1 on error */
6900     int wolfSSL_get_keys(WOLFSSL* ssl, unsigned char** ms, unsigned int* msLen,
6901                                      unsigned char** sr, unsigned int* srLen,
6902                                      unsigned char** cr, unsigned int* crLen)
6903     {
6904         if (ssl == NULL || ssl->arrays == NULL)
6905             return SSL_FATAL_ERROR;
6906
6907         *ms = ssl->arrays->masterSecret;
6908         *sr = ssl->arrays->serverRandom;
6909         *cr = ssl->arrays->clientRandom;
6910
6911         *msLen = SECRET_LEN;
6912         *srLen = RAN_LEN;
6913         *crLen = RAN_LEN;
6914
6915         return SSL_SUCCESS;
6916     }
6917
6918
6919     void wolfSSL_set_accept_state(WOLFSSL* ssl)
6920     {
6921         byte haveRSA = 1;
6922         byte havePSK = 0;
6923
6924         WOLFSSL_ENTER("SSL_set_accept_state");
6925         ssl->options.side = WOLFSSL_SERVER_END;
6926         /* reset suites in case user switched */
6927
6928         #ifdef NO_RSA
6929             haveRSA = 0;
6930         #endif
6931         #ifndef NO_PSK
6932             havePSK = ssl->options.havePSK;
6933         #endif
6934         InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
6935                    ssl->options.haveDH, ssl->options.haveNTRU,
6936                    ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
6937                    ssl->options.side);
6938     }
6939 #endif
6940
6941     /* return true if connection established */
6942     int wolfSSL_is_init_finished(WOLFSSL* ssl)
6943     {
6944         if (ssl == NULL)
6945             return 0;
6946
6947         if (ssl->options.handShakeState == HANDSHAKE_DONE)
6948             return 1;
6949
6950         return 0;
6951     }
6952
6953 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
6954     void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX* ctx,
6955                                       WOLFSSL_RSA*(*f)(WOLFSSL*, int, int))
6956     {
6957         /* wolfSSL verifies all these internally */
6958         (void)ctx;
6959         (void)f;
6960     }
6961
6962
6963     void wolfSSL_set_shutdown(WOLFSSL* ssl, int opt)
6964     {
6965         (void)ssl;
6966         (void)opt;
6967     }
6968
6969
6970     long wolfSSL_CTX_set_options(WOLFSSL_CTX* ctx, long opt)
6971     {
6972         /* goahead calls with 0, do nothing */
6973         WOLFSSL_ENTER("SSL_CTX_set_options");
6974         (void)ctx;
6975         return opt;
6976     }
6977
6978
6979     int wolfSSL_set_rfd(WOLFSSL* ssl, int rfd)
6980     {
6981         WOLFSSL_ENTER("SSL_set_rfd");
6982         ssl->rfd = rfd;      /* not used directly to allow IO callbacks */
6983
6984         ssl->IOCB_ReadCtx  = &ssl->rfd;
6985
6986         return SSL_SUCCESS;
6987     }
6988
6989
6990     int wolfSSL_set_wfd(WOLFSSL* ssl, int wfd)
6991     {
6992         WOLFSSL_ENTER("SSL_set_wfd");
6993         ssl->wfd = wfd;      /* not used directly to allow IO callbacks */
6994
6995         ssl->IOCB_WriteCtx  = &ssl->wfd;
6996
6997         return SSL_SUCCESS;
6998     }
6999
7000
7001     WOLFSSL_RSA* wolfSSL_RSA_generate_key(int len, unsigned long bits,
7002                                           void(*f)(int, int, void*), void* data)
7003     {
7004         /* no tmp key needed, actual generation not supported */
7005         WOLFSSL_ENTER("RSA_generate_key");
7006         (void)len;
7007         (void)bits;
7008         (void)f;
7009         (void)data;
7010         return NULL;
7011     }
7012
7013
7014
7015     WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get_current_cert(
7016                                                      WOLFSSL_X509_STORE_CTX* ctx)
7017     {
7018         (void)ctx;
7019         return 0;
7020     }
7021
7022
7023     int wolfSSL_X509_STORE_CTX_get_error(WOLFSSL_X509_STORE_CTX* ctx)
7024     {
7025         if (ctx != NULL)
7026             return ctx->error;
7027         return 0;
7028     }
7029
7030
7031     int wolfSSL_X509_STORE_CTX_get_error_depth(WOLFSSL_X509_STORE_CTX* ctx)
7032     {
7033         (void)ctx;
7034         return 0;
7035     }
7036
7037
7038     WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_buffer(void)
7039     {
7040         static WOLFSSL_BIO_METHOD meth;
7041
7042         WOLFSSL_ENTER("BIO_f_buffer");
7043         meth.type = BIO_BUFFER;
7044
7045         return &meth;
7046     }
7047
7048
7049     long wolfSSL_BIO_set_write_buffer_size(WOLFSSL_BIO* bio, long size)
7050     {
7051         /* wolfSSL has internal buffer, compatibility only */
7052         WOLFSSL_ENTER("BIO_set_write_buffer_size");
7053         (void)bio;
7054         return size;
7055     }
7056
7057
7058     WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_ssl(void)
7059     {
7060         static WOLFSSL_BIO_METHOD meth;
7061
7062         WOLFSSL_ENTER("BIO_f_ssl");
7063         meth.type = BIO_SSL;
7064
7065         return &meth;
7066     }
7067
7068
7069     WOLFSSL_BIO* wolfSSL_BIO_new_socket(int sfd, int closeF)
7070     {
7071         WOLFSSL_BIO* bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0,
7072                                                 DYNAMIC_TYPE_OPENSSL);
7073
7074         WOLFSSL_ENTER("BIO_new_socket");
7075         if (bio) {
7076             bio->type  = BIO_SOCKET;
7077             bio->close = (byte)closeF;
7078             bio->eof   = 0;
7079             bio->ssl   = 0;
7080             bio->fd    = sfd;
7081             bio->prev  = 0;
7082             bio->next  = 0;
7083             bio->mem   = NULL;
7084             bio->memLen = 0;
7085         }
7086         return bio;
7087     }
7088
7089
7090     int wolfSSL_BIO_eof(WOLFSSL_BIO* b)
7091     {
7092         WOLFSSL_ENTER("BIO_eof");
7093         if (b->eof)
7094             return 1;
7095
7096         return 0;
7097     }
7098
7099
7100     long wolfSSL_BIO_set_ssl(WOLFSSL_BIO* b, WOLFSSL* ssl, int closeF)
7101     {
7102         WOLFSSL_ENTER("BIO_set_ssl");
7103         b->ssl   = ssl;
7104         b->close = (byte)closeF;
7105     /* add to ssl for bio free if SSL_free called before/instead of free_all? */
7106
7107         return 0;
7108     }
7109
7110
7111     WOLFSSL_BIO* wolfSSL_BIO_new(WOLFSSL_BIO_METHOD* method)
7112     {
7113         WOLFSSL_BIO* bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0,
7114                                                 DYNAMIC_TYPE_OPENSSL);
7115         WOLFSSL_ENTER("BIO_new");
7116         if (bio) {
7117             bio->type   = method->type;
7118             bio->close  = 0;
7119             bio->eof    = 0;
7120             bio->ssl    = NULL;
7121             bio->mem    = NULL;
7122             bio->memLen = 0;
7123             bio->fd     = 0;
7124             bio->prev   = NULL;
7125             bio->next   = NULL;
7126         }
7127         return bio;
7128     }
7129
7130
7131     int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, const byte** p)
7132     {
7133         if (bio == NULL || p == NULL)
7134             return SSL_FATAL_ERROR;
7135
7136         *p = bio->mem;
7137
7138         return bio->memLen;
7139     }
7140
7141
7142     WOLFSSL_BIO* wolfSSL_BIO_new_mem_buf(void* buf, int len)
7143     {
7144         WOLFSSL_BIO* bio = NULL;
7145         if (buf == NULL)
7146             return bio;
7147
7148         bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
7149         if (bio == NULL)
7150             return bio;
7151
7152         bio->memLen = len;
7153         bio->mem    = (byte*)XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL);
7154         if (bio->mem == NULL) {
7155             XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
7156             return NULL;
7157         }
7158
7159         XMEMCPY(bio->mem, buf, len);
7160
7161         return bio;
7162     }
7163
7164
7165 #ifdef USE_WINDOWS_API
7166     #define CloseSocket(s) closesocket(s)
7167 #elif defined(WOLFSSL_MDK_ARM)
7168     #define CloseSocket(s) closesocket(s)
7169     extern int closesocket(int) ;
7170 #else
7171     #define CloseSocket(s) close(s)
7172 #endif
7173
7174     int wolfSSL_BIO_free(WOLFSSL_BIO* bio)
7175     {
7176         /* unchain?, doesn't matter in goahead since from free all */
7177         WOLFSSL_ENTER("BIO_free");
7178         if (bio) {
7179             if (bio->close) {
7180                 if (bio->ssl)
7181                     wolfSSL_free(bio->ssl);
7182                 if (bio->fd)
7183                     CloseSocket(bio->fd);
7184             }
7185             if (bio->mem)
7186                 XFREE(bio->mem, 0, DYNAMIC_TYPE_OPENSSL);
7187             XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
7188         }
7189         return 0;
7190     }
7191
7192
7193     int wolfSSL_BIO_free_all(WOLFSSL_BIO* bio)
7194     {
7195         WOLFSSL_ENTER("BIO_free_all");
7196         while (bio) {
7197             WOLFSSL_BIO* next = bio->next;
7198             wolfSSL_BIO_free(bio);
7199             bio = next;
7200         }
7201         return 0;
7202     }
7203
7204
7205     int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
7206     {
7207         int  ret;
7208         WOLFSSL* ssl = 0;
7209         WOLFSSL_BIO* front = bio;
7210
7211         WOLFSSL_ENTER("BIO_read");
7212         /* already got eof, again is error */
7213         if (front->eof)
7214             return SSL_FATAL_ERROR;
7215
7216         while(bio && ((ssl = bio->ssl) == 0) )
7217             bio = bio->next;
7218
7219         if (ssl == 0) return BAD_FUNC_ARG;
7220
7221         ret = wolfSSL_read(ssl, buf, len);
7222         if (ret == 0)
7223             front->eof = 1;
7224         else if (ret < 0) {
7225             int err = wolfSSL_get_error(ssl, 0);
7226             if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
7227                 front->eof = 1;
7228         }
7229         return ret;
7230     }
7231
7232
7233     int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
7234     {
7235         int  ret;
7236         WOLFSSL* ssl = 0;
7237         WOLFSSL_BIO* front = bio;
7238
7239         WOLFSSL_ENTER("BIO_write");
7240         /* already got eof, again is error */
7241         if (front->eof)
7242             return SSL_FATAL_ERROR;
7243
7244         while(bio && ((ssl = bio->ssl) == 0) )
7245             bio = bio->next;
7246
7247         if (ssl == 0) return BAD_FUNC_ARG;
7248
7249         ret = wolfSSL_write(ssl, data, len);
7250         if (ret == 0)
7251             front->eof = 1;
7252         else if (ret < 0) {
7253             int err = wolfSSL_get_error(ssl, 0);
7254             if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
7255                 front->eof = 1;
7256         }
7257
7258         return ret;
7259     }
7260
7261
7262     WOLFSSL_BIO* wolfSSL_BIO_push(WOLFSSL_BIO* top, WOLFSSL_BIO* append)
7263     {
7264         WOLFSSL_ENTER("BIO_push");
7265         top->next    = append;
7266         append->prev = top;
7267
7268         return top;
7269     }
7270
7271
7272     int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
7273     {
7274         /* for wolfSSL no flushing needed */
7275         WOLFSSL_ENTER("BIO_flush");
7276         (void)bio;
7277         return 1;
7278     }
7279
7280
7281 #endif /* OPENSSL_EXTRA || GOAHEAD_WS */
7282
7283
7284 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
7285
7286     void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX* ctx,
7287                                                    void* userdata)
7288     {
7289         WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb_userdata");
7290         ctx->userdata = userdata;
7291     }
7292
7293
7294     void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX* ctx, pem_password_cb cb)
7295     {
7296         WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb");
7297         ctx->passwd_cb = cb;
7298     }
7299
7300     int wolfSSL_num_locks(void)
7301     {
7302         return 0;
7303     }
7304
7305     void wolfSSL_set_locking_callback(void (*f)(int, int, const char*, int))
7306     {
7307         (void)f;
7308     }
7309
7310     void wolfSSL_set_id_callback(unsigned long (*f)(void))
7311     {
7312         (void)f;
7313     }
7314
7315     unsigned long wolfSSL_ERR_get_error(void)
7316     {
7317         /* TODO: */
7318         return 0;
7319     }
7320
7321 #ifndef NO_MD5
7322
7323     int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER* type,
7324                        const WOLFSSL_EVP_MD* md, const byte* salt,
7325                        const byte* data, int sz, int count, byte* key, byte* iv)
7326     {
7327         int  keyLen = 0;
7328         int  ivLen  = 0;
7329         int  j;
7330         int  keyLeft;
7331         int  ivLeft;
7332         int  keyOutput = 0;
7333         byte digest[MD5_DIGEST_SIZE];
7334     #ifdef WOLFSSL_SMALL_STACK
7335         Md5* md5 = NULL;
7336     #else
7337         Md5  md5[1];
7338     #endif
7339
7340     #ifdef WOLFSSL_SMALL_STACK
7341         md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
7342         if (md5 == NULL)
7343             return 0;
7344     #endif
7345
7346         WOLFSSL_ENTER("EVP_BytesToKey");
7347         wc_InitMd5(md5);
7348
7349         /* only support MD5 for now */
7350         if (XSTRNCMP(md, "MD5", 3) != 0) return 0;
7351
7352         /* only support CBC DES and AES for now */
7353         if (XSTRNCMP(type, "DES-CBC", 7) == 0) {
7354             keyLen = DES_KEY_SIZE;
7355             ivLen  = DES_IV_SIZE;
7356         }
7357         else if (XSTRNCMP(type, "DES-EDE3-CBC", 12) == 0) {
7358             keyLen = DES3_KEY_SIZE;
7359             ivLen  = DES_IV_SIZE;
7360         }
7361         else if (XSTRNCMP(type, "AES-128-CBC", 11) == 0) {
7362             keyLen = AES_128_KEY_SIZE;
7363             ivLen  = AES_IV_SIZE;
7364         }
7365         else if (XSTRNCMP(type, "AES-192-CBC", 11) == 0) {
7366             keyLen = AES_192_KEY_SIZE;
7367             ivLen  = AES_IV_SIZE;
7368         }
7369         else if (XSTRNCMP(type, "AES-256-CBC", 11) == 0) {
7370             keyLen = AES_256_KEY_SIZE;
7371             ivLen  = AES_IV_SIZE;
7372         }
7373         else {
7374         #ifdef WOLFSSL_SMALL_STACK
7375             XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7376         #endif
7377             return 0;
7378         }
7379
7380         keyLeft   = keyLen;
7381         ivLeft    = ivLen;
7382
7383         while (keyOutput < (keyLen + ivLen)) {
7384             int digestLeft = MD5_DIGEST_SIZE;
7385             /* D_(i - 1) */
7386             if (keyOutput)                      /* first time D_0 is empty */
7387                 wc_Md5Update(md5, digest, MD5_DIGEST_SIZE);
7388             /* data */
7389             wc_Md5Update(md5, data, sz);
7390             /* salt */
7391             if (salt)
7392                 wc_Md5Update(md5, salt, EVP_SALT_SIZE);
7393             wc_Md5Final(md5, digest);
7394             /* count */
7395             for (j = 1; j < count; j++) {
7396                 wc_Md5Update(md5, digest, MD5_DIGEST_SIZE);
7397                 wc_Md5Final(md5, digest);
7398             }
7399
7400             if (keyLeft) {
7401                 int store = min(keyLeft, MD5_DIGEST_SIZE);
7402                 XMEMCPY(&key[keyLen - keyLeft], digest, store);
7403
7404                 keyOutput  += store;
7405                 keyLeft    -= store;
7406                 digestLeft -= store;
7407             }
7408
7409             if (ivLeft && digestLeft) {
7410                 int store = min(ivLeft, digestLeft);
7411                 XMEMCPY(&iv[ivLen - ivLeft], &digest[MD5_DIGEST_SIZE -
7412                                                     digestLeft], store);
7413                 keyOutput += store;
7414                 ivLeft    -= store;
7415             }
7416         }
7417
7418     #ifdef WOLFSSL_SMALL_STACK
7419         XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7420     #endif
7421
7422         return keyOutput == (keyLen + ivLen) ? keyOutput : 0;
7423     }
7424
7425 #endif /* NO_MD5 */
7426
7427 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
7428
7429
7430 #ifdef OPENSSL_EXTRA
7431
7432     unsigned long wolfSSLeay(void)
7433     {
7434         return SSLEAY_VERSION_NUMBER;
7435     }
7436
7437
7438     const char* wolfSSLeay_version(int type)
7439     {
7440         static const char* version = "SSLeay wolfSSL compatibility";
7441         (void)type;
7442         return version;
7443     }
7444
7445
7446 #ifndef NO_MD5
7447     void wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5)
7448     {
7449         typedef char md5_test[sizeof(MD5_CTX) >= sizeof(Md5) ? 1 : -1];
7450         (void)sizeof(md5_test);
7451
7452         WOLFSSL_ENTER("MD5_Init");
7453         wc_InitMd5((Md5*)md5);
7454     }
7455
7456
7457     void wolfSSL_MD5_Update(WOLFSSL_MD5_CTX* md5, const void* input,
7458                            unsigned long sz)
7459     {
7460         WOLFSSL_ENTER("wolfSSL_MD5_Update");
7461         wc_Md5Update((Md5*)md5, (const byte*)input, (word32)sz);
7462     }
7463
7464
7465     void wolfSSL_MD5_Final(byte* input, WOLFSSL_MD5_CTX* md5)
7466     {
7467         WOLFSSL_ENTER("MD5_Final");
7468         wc_Md5Final((Md5*)md5, input);
7469     }
7470 #endif /* NO_MD5 */
7471
7472
7473 #ifndef NO_SHA
7474     void wolfSSL_SHA_Init(WOLFSSL_SHA_CTX* sha)
7475     {
7476         typedef char sha_test[sizeof(SHA_CTX) >= sizeof(Sha) ? 1 : -1];
7477         (void)sizeof(sha_test);
7478
7479         WOLFSSL_ENTER("SHA_Init");
7480         wc_InitSha((Sha*)sha);  /* OpenSSL compat, no ret */
7481     }
7482
7483
7484     void wolfSSL_SHA_Update(WOLFSSL_SHA_CTX* sha, const void* input,
7485                            unsigned long sz)
7486     {
7487         WOLFSSL_ENTER("SHA_Update");
7488         wc_ShaUpdate((Sha*)sha, (const byte*)input, (word32)sz);
7489     }
7490
7491
7492     void wolfSSL_SHA_Final(byte* input, WOLFSSL_SHA_CTX* sha)
7493     {
7494         WOLFSSL_ENTER("SHA_Final");
7495         wc_ShaFinal((Sha*)sha, input);
7496     }
7497
7498
7499     void wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX* sha)
7500     {
7501         WOLFSSL_ENTER("SHA1_Init");
7502         SHA_Init(sha);
7503     }
7504
7505
7506     void wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX* sha, const void* input,
7507                             unsigned long sz)
7508     {
7509         WOLFSSL_ENTER("SHA1_Update");
7510         SHA_Update(sha, input, sz);
7511     }
7512
7513
7514     void wolfSSL_SHA1_Final(byte* input, WOLFSSL_SHA_CTX* sha)
7515     {
7516         WOLFSSL_ENTER("SHA1_Final");
7517         SHA_Final(input, sha);
7518     }
7519 #endif /* NO_SHA */
7520
7521
7522     void wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX* sha256)
7523     {
7524         typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(Sha256) ? 1 : -1];
7525         (void)sizeof(sha_test);
7526
7527         WOLFSSL_ENTER("SHA256_Init");
7528         wc_InitSha256((Sha256*)sha256);  /* OpenSSL compat, no error */
7529     }
7530
7531
7532     void wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX* sha, const void* input,
7533                               unsigned long sz)
7534     {
7535         WOLFSSL_ENTER("SHA256_Update");
7536         wc_Sha256Update((Sha256*)sha, (const byte*)input, (word32)sz);
7537         /* OpenSSL compat, no error */
7538     }
7539
7540
7541     void wolfSSL_SHA256_Final(byte* input, WOLFSSL_SHA256_CTX* sha)
7542     {
7543         WOLFSSL_ENTER("SHA256_Final");
7544         wc_Sha256Final((Sha256*)sha, input);
7545         /* OpenSSL compat, no error */
7546     }
7547
7548
7549     #ifdef WOLFSSL_SHA384
7550
7551     void wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX* sha)
7552     {
7553         typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(Sha384) ? 1 : -1];
7554         (void)sizeof(sha_test);
7555
7556         WOLFSSL_ENTER("SHA384_Init");
7557         wc_InitSha384((Sha384*)sha);   /* OpenSSL compat, no error */
7558     }
7559
7560
7561     void wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX* sha, const void* input,
7562                            unsigned long sz)
7563     {
7564         WOLFSSL_ENTER("SHA384_Update");
7565         wc_Sha384Update((Sha384*)sha, (const byte*)input, (word32)sz);
7566         /* OpenSSL compat, no error */
7567     }
7568
7569
7570     void wolfSSL_SHA384_Final(byte* input, WOLFSSL_SHA384_CTX* sha)
7571     {
7572         WOLFSSL_ENTER("SHA384_Final");
7573         wc_Sha384Final((Sha384*)sha, input);
7574         /* OpenSSL compat, no error */
7575     }
7576
7577     #endif /* WOLFSSL_SHA384 */
7578
7579
7580    #ifdef WOLFSSL_SHA512
7581
7582     void wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha)
7583     {
7584         typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(Sha512) ? 1 : -1];
7585         (void)sizeof(sha_test);
7586
7587         WOLFSSL_ENTER("SHA512_Init");
7588         wc_InitSha512((Sha512*)sha);  /* OpenSSL compat, no error */
7589     }
7590
7591
7592     void wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX* sha, const void* input,
7593                            unsigned long sz)
7594     {
7595         WOLFSSL_ENTER("SHA512_Update");
7596         wc_Sha512Update((Sha512*)sha, (const byte*)input, (word32)sz);
7597         /* OpenSSL compat, no error */
7598     }
7599
7600
7601     void wolfSSL_SHA512_Final(byte* input, WOLFSSL_SHA512_CTX* sha)
7602     {
7603         WOLFSSL_ENTER("SHA512_Final");
7604         wc_Sha512Final((Sha512*)sha, input);
7605         /* OpenSSL compat, no error */
7606     }
7607
7608     #endif /* WOLFSSL_SHA512 */
7609
7610
7611     #ifndef NO_MD5
7612
7613     const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void)
7614     {
7615         static const char* type = "MD5";
7616         WOLFSSL_ENTER("EVP_md5");
7617         return type;
7618     }
7619
7620     #endif /* NO_MD5 */
7621
7622
7623 #ifndef NO_SHA
7624     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void)
7625     {
7626         static const char* type = "SHA";
7627         WOLFSSL_ENTER("EVP_sha1");
7628         return type;
7629     }
7630 #endif /* NO_SHA */
7631
7632
7633     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void)
7634     {
7635         static const char* type = "SHA256";
7636         WOLFSSL_ENTER("EVP_sha256");
7637         return type;
7638     }
7639
7640     #ifdef WOLFSSL_SHA384
7641
7642     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void)
7643     {
7644         static const char* type = "SHA384";
7645         WOLFSSL_ENTER("EVP_sha384");
7646         return type;
7647     }
7648
7649     #endif /* WOLFSSL_SHA384 */
7650
7651     #ifdef WOLFSSL_SHA512
7652
7653     const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void)
7654     {
7655         static const char* type = "SHA512";
7656         WOLFSSL_ENTER("EVP_sha512");
7657         return type;
7658     }
7659
7660     #endif /* WOLFSSL_SHA512 */
7661
7662
7663     void wolfSSL_EVP_MD_CTX_init(WOLFSSL_EVP_MD_CTX* ctx)
7664     {
7665         WOLFSSL_ENTER("EVP_CIPHER_MD_CTX_init");
7666         (void)ctx;
7667         /* do nothing */
7668     }
7669
7670
7671     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void)
7672     {
7673         static const char* type = "AES128-CBC";
7674         WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cbc");
7675         return type;
7676     }
7677
7678
7679     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void)
7680     {
7681         static const char* type = "AES192-CBC";
7682         WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cbc");
7683         return type;
7684     }
7685
7686
7687     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void)
7688     {
7689         static const char* type = "AES256-CBC";
7690         WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cbc");
7691         return type;
7692     }
7693
7694
7695     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void)
7696     {
7697         static const char* type = "AES128-CTR";
7698         WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ctr");
7699         return type;
7700     }
7701
7702
7703     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void)
7704     {
7705         static const char* type = "AES192-CTR";
7706         WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ctr");
7707         return type;
7708     }
7709
7710
7711     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void)
7712     {
7713         static const char* type = "AES256-CTR";
7714         WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ctr");
7715         return type;
7716     }
7717
7718
7719     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void)
7720     {
7721         static const char* type = "DES-CBC";
7722         WOLFSSL_ENTER("wolfSSL_EVP_des_cbc");
7723         return type;
7724     }
7725
7726
7727     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void)
7728     {
7729         static const char* type = "DES-EDE3-CBC";
7730         WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_cbc");
7731         return type;
7732     }
7733
7734
7735     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc4(void)
7736     {
7737         static const char* type = "ARC4";
7738         WOLFSSL_ENTER("wolfSSL_EVP_rc4");
7739         return type;
7740     }
7741
7742
7743     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void)
7744     {
7745         static const char* type = "NULL";
7746         WOLFSSL_ENTER("wolfSSL_EVP_enc_null");
7747         return type;
7748     }
7749
7750
7751     int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx)
7752     {
7753         WOLFSSL_ENTER("EVP_MD_CTX_cleanup");
7754         (void)ctx;
7755         return 0;
7756     }
7757
7758
7759
7760     void wolfSSL_EVP_CIPHER_CTX_init(WOLFSSL_EVP_CIPHER_CTX* ctx)
7761     {
7762         WOLFSSL_ENTER("EVP_CIPHER_CTX_init");
7763         if (ctx) {
7764             ctx->cipherType = 0xff;   /* no init */
7765             ctx->keyLen     = 0;
7766             ctx->enc        = 1;      /* start in encrypt mode */
7767         }
7768     }
7769
7770
7771     /* SSL_SUCCESS on ok */
7772     int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx)
7773     {
7774         WOLFSSL_ENTER("EVP_CIPHER_CTX_cleanup");
7775         if (ctx) {
7776             ctx->cipherType = 0xff;  /* no more init */
7777             ctx->keyLen     = 0;
7778         }
7779
7780         return SSL_SUCCESS;
7781     }
7782
7783
7784     /* SSL_SUCCESS on ok */
7785     int  wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
7786                                const WOLFSSL_EVP_CIPHER* type, byte* key,
7787                                byte* iv, int enc)
7788     {
7789 #if defined(NO_AES) && defined(NO_DES3)
7790         (void)iv;
7791         (void)enc;
7792 #else
7793         int ret = 0;
7794 #endif
7795
7796         WOLFSSL_ENTER("wolfSSL_EVP_CipherInit");
7797         if (ctx == NULL) {
7798             WOLFSSL_MSG("no ctx");
7799             return 0;   /* failure */
7800         }
7801
7802         if (type == NULL && ctx->cipherType == 0xff) {
7803             WOLFSSL_MSG("no type set");
7804             return 0;   /* failure */
7805         }
7806
7807 #ifndef NO_AES
7808         if (ctx->cipherType == AES_128_CBC_TYPE || (type &&
7809                                        XSTRNCMP(type, "AES128-CBC", 10) == 0)) {
7810             WOLFSSL_MSG("AES-128-CBC");
7811             ctx->cipherType = AES_128_CBC_TYPE;
7812             ctx->keyLen     = 16;
7813             if (enc == 0 || enc == 1)
7814                 ctx->enc = enc ? 1 : 0;
7815             if (key) {
7816                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
7817                                 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
7818                 if (ret != 0)
7819                     return ret;
7820             }
7821             if (iv && key == NULL) {
7822                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
7823                 if (ret != 0)
7824                     return ret;
7825             }
7826         }
7827         else if (ctx->cipherType == AES_192_CBC_TYPE || (type &&
7828                                        XSTRNCMP(type, "AES192-CBC", 10) == 0)) {
7829             WOLFSSL_MSG("AES-192-CBC");
7830             ctx->cipherType = AES_192_CBC_TYPE;
7831             ctx->keyLen     = 24;
7832             if (enc == 0 || enc == 1)
7833                 ctx->enc = enc ? 1 : 0;
7834             if (key) {
7835                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
7836                                 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
7837                 if (ret != 0)
7838                     return ret;
7839             }
7840             if (iv && key == NULL) {
7841                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
7842                 if (ret != 0)
7843                     return ret;
7844             }
7845         }
7846         else if (ctx->cipherType == AES_256_CBC_TYPE || (type &&
7847                                        XSTRNCMP(type, "AES256-CBC", 10) == 0)) {
7848             WOLFSSL_MSG("AES-256-CBC");
7849             ctx->cipherType = AES_256_CBC_TYPE;
7850             ctx->keyLen     = 32;
7851             if (enc == 0 || enc == 1)
7852                 ctx->enc = enc ? 1 : 0;
7853             if (key) {
7854                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
7855                                 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
7856                 if (ret != 0)
7857                     return ret;
7858             }
7859             if (iv && key == NULL) {
7860                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
7861                 if (ret != 0)
7862                     return ret;
7863             }
7864         }
7865 #ifdef WOLFSSL_AES_COUNTER
7866         else if (ctx->cipherType == AES_128_CTR_TYPE || (type &&
7867                                        XSTRNCMP(type, "AES128-CTR", 10) == 0)) {
7868             WOLFSSL_MSG("AES-128-CTR");
7869             ctx->cipherType = AES_128_CTR_TYPE;
7870             ctx->keyLen     = 16;
7871             if (enc == 0 || enc == 1)
7872                 ctx->enc = enc ? 1 : 0;
7873             if (key) {
7874                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
7875                                 AES_ENCRYPTION);
7876                 if (ret != 0)
7877                     return ret;
7878             }
7879             if (iv && key == NULL) {
7880                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
7881                 if (ret != 0)
7882                     return ret;
7883             }
7884         }
7885         else if (ctx->cipherType == AES_192_CTR_TYPE || (type &&
7886                                        XSTRNCMP(type, "AES192-CTR", 10) == 0)) {
7887             WOLFSSL_MSG("AES-192-CTR");
7888             ctx->cipherType = AES_192_CTR_TYPE;
7889             ctx->keyLen     = 24;
7890             if (enc == 0 || enc == 1)
7891                 ctx->enc = enc ? 1 : 0;
7892             if (key) {
7893                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
7894                                 AES_ENCRYPTION);
7895                 if (ret != 0)
7896                     return ret;
7897             }
7898             if (iv && key == NULL) {
7899                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
7900                 if (ret != 0)
7901                     return ret;
7902             }
7903         }
7904         else if (ctx->cipherType == AES_256_CTR_TYPE || (type &&
7905                                        XSTRNCMP(type, "AES256-CTR", 10) == 0)) {
7906             WOLFSSL_MSG("AES-256-CTR");
7907             ctx->cipherType = AES_256_CTR_TYPE;
7908             ctx->keyLen     = 32;
7909             if (enc == 0 || enc == 1)
7910                 ctx->enc = enc ? 1 : 0;
7911             if (key) {
7912                 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
7913                                 AES_ENCRYPTION);
7914                 if (ret != 0)
7915                     return ret;
7916             }
7917             if (iv && key == NULL) {
7918                 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
7919                 if (ret != 0)
7920                     return ret;
7921             }
7922         }
7923 #endif /* WOLFSSL_AES_CTR */
7924 #endif /* NO_AES */
7925
7926 #ifndef NO_DES3
7927         else if (ctx->cipherType == DES_CBC_TYPE || (type &&
7928                                        XSTRNCMP(type, "DES-CBC", 7) == 0)) {
7929             WOLFSSL_MSG("DES-CBC");
7930             ctx->cipherType = DES_CBC_TYPE;
7931             ctx->keyLen     = 8;
7932             if (enc == 0 || enc == 1)
7933                 ctx->enc = enc ? 1 : 0;
7934             if (key) {
7935                 ret = wc_Des_SetKey(&ctx->cipher.des, key, iv,
7936                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
7937                 if (ret != 0)
7938                     return ret;
7939             }
7940
7941             if (iv && key == NULL)
7942                 wc_Des_SetIV(&ctx->cipher.des, iv);
7943         }
7944         else if (ctx->cipherType == DES_EDE3_CBC_TYPE || (type &&
7945                                      XSTRNCMP(type, "DES-EDE3-CBC", 11) == 0)) {
7946             WOLFSSL_MSG("DES-EDE3-CBC");
7947             ctx->cipherType = DES_EDE3_CBC_TYPE;
7948             ctx->keyLen     = 24;
7949             if (enc == 0 || enc == 1)
7950                 ctx->enc = enc ? 1 : 0;
7951             if (key) {
7952                 ret = wc_Des3_SetKey(&ctx->cipher.des3, key, iv,
7953                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
7954                 if (ret != 0)
7955                     return ret;
7956             }
7957
7958             if (iv && key == NULL) {
7959                 ret = wc_Des3_SetIV(&ctx->cipher.des3, iv);
7960                 if (ret != 0)
7961                     return ret;
7962             }
7963         }
7964 #endif /* NO_DES3 */
7965 #ifndef NO_RC4
7966         else if (ctx->cipherType == ARC4_TYPE || (type &&
7967                                      XSTRNCMP(type, "ARC4", 4) == 0)) {
7968             WOLFSSL_MSG("ARC4");
7969             ctx->cipherType = ARC4_TYPE;
7970             if (ctx->keyLen == 0)  /* user may have already set */
7971                 ctx->keyLen = 16;  /* default to 128 */
7972             if (key)
7973                 wc_Arc4SetKey(&ctx->cipher.arc4, key, ctx->keyLen);
7974         }
7975 #endif /* NO_RC4 */
7976         else if (ctx->cipherType == NULL_CIPHER_TYPE || (type &&
7977                                      XSTRNCMP(type, "NULL", 4) == 0)) {
7978             WOLFSSL_MSG("NULL cipher");
7979             ctx->cipherType = NULL_CIPHER_TYPE;
7980             ctx->keyLen = 0;
7981         }
7982         else
7983             return 0;   /* failure */
7984
7985
7986         return SSL_SUCCESS;
7987     }
7988
7989
7990     /* SSL_SUCCESS on ok */
7991     int wolfSSL_EVP_CIPHER_CTX_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx)
7992     {
7993         WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_key_length");
7994         if (ctx)
7995             return ctx->keyLen;
7996
7997         return 0;   /* failure */
7998     }
7999
8000
8001     /* SSL_SUCCESS on ok */
8002     int wolfSSL_EVP_CIPHER_CTX_set_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx,
8003                                              int keylen)
8004     {
8005         WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_set_key_length");
8006         if (ctx)
8007             ctx->keyLen = keylen;
8008         else
8009             return 0;  /* failure */
8010
8011         return SSL_SUCCESS;
8012     }
8013
8014
8015     /* SSL_SUCCESS on ok */
8016     int wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* dst, byte* src,
8017                           word32 len)
8018     {
8019         int ret = 0;
8020         WOLFSSL_ENTER("wolfSSL_EVP_Cipher");
8021
8022         if (ctx == NULL || dst == NULL || src == NULL) {
8023             WOLFSSL_MSG("Bad function argument");
8024             return 0;  /* failure */
8025         }
8026
8027         if (ctx->cipherType == 0xff) {
8028             WOLFSSL_MSG("no init");
8029             return 0;  /* failure */
8030         }
8031
8032         switch (ctx->cipherType) {
8033
8034 #ifndef NO_AES
8035             case AES_128_CBC_TYPE :
8036             case AES_192_CBC_TYPE :
8037             case AES_256_CBC_TYPE :
8038                 WOLFSSL_MSG("AES CBC");
8039                 if (ctx->enc)
8040                     ret = wc_AesCbcEncrypt(&ctx->cipher.aes, dst, src, len);
8041                 else
8042                     ret = wc_AesCbcDecrypt(&ctx->cipher.aes, dst, src, len);
8043                 break;
8044
8045 #ifdef WOLFSSL_AES_COUNTER
8046             case AES_128_CTR_TYPE :
8047             case AES_192_CTR_TYPE :
8048             case AES_256_CTR_TYPE :
8049                     WOLFSSL_MSG("AES CTR");
8050                     wc_AesCtrEncrypt(&ctx->cipher.aes, dst, src, len);
8051                 break;
8052 #endif
8053 #endif /* NO_AES */
8054
8055 #ifndef NO_DES3
8056             case DES_CBC_TYPE :
8057                 if (ctx->enc)
8058                     wc_Des_CbcEncrypt(&ctx->cipher.des, dst, src, len);
8059                 else
8060                     wc_Des_CbcDecrypt(&ctx->cipher.des, dst, src, len);
8061                 break;
8062
8063             case DES_EDE3_CBC_TYPE :
8064                 if (ctx->enc)
8065                     ret = wc_Des3_CbcEncrypt(&ctx->cipher.des3, dst, src, len);
8066                 else
8067                     ret = wc_Des3_CbcDecrypt(&ctx->cipher.des3, dst, src, len);
8068                 break;
8069 #endif
8070
8071 #ifndef NO_RC4
8072             case ARC4_TYPE :
8073                 wc_Arc4Process(&ctx->cipher.arc4, dst, src, len);
8074                 break;
8075 #endif
8076
8077             case NULL_CIPHER_TYPE :
8078                 XMEMCPY(dst, src, len);
8079                 break;
8080
8081             default: {
8082                 WOLFSSL_MSG("bad type");
8083                 return 0;  /* failure */
8084             }
8085         }
8086
8087         if (ret != 0) {
8088             WOLFSSL_MSG("wolfSSL_EVP_Cipher failure");
8089             return 0;  /* failuer */
8090         }
8091
8092         WOLFSSL_MSG("wolfSSL_EVP_Cipher success");
8093         return SSL_SUCCESS;  /* success */
8094     }
8095
8096
8097     /* store for external read of iv, SSL_SUCCESS on success */
8098     int  wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
8099     {
8100         WOLFSSL_ENTER("wolfSSL_StoreExternalIV");
8101
8102         if (ctx == NULL) {
8103             WOLFSSL_MSG("Bad function argument");
8104             return SSL_FATAL_ERROR;
8105         }
8106
8107         switch (ctx->cipherType) {
8108
8109 #ifndef NO_AES
8110             case AES_128_CBC_TYPE :
8111             case AES_192_CBC_TYPE :
8112             case AES_256_CBC_TYPE :
8113                 WOLFSSL_MSG("AES CBC");
8114                 memcpy(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
8115                 break;
8116
8117 #ifdef WOLFSSL_AES_COUNTER
8118             case AES_128_CTR_TYPE :
8119             case AES_192_CTR_TYPE :
8120             case AES_256_CTR_TYPE :
8121                 WOLFSSL_MSG("AES CTR");
8122                 memcpy(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
8123                 break;
8124 #endif /* WOLFSSL_AES_COUNTER */
8125
8126 #endif /* NO_AES */
8127
8128 #ifndef NO_DES3
8129             case DES_CBC_TYPE :
8130                 WOLFSSL_MSG("DES CBC");
8131                 memcpy(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
8132                 break;
8133
8134             case DES_EDE3_CBC_TYPE :
8135                 WOLFSSL_MSG("DES EDE3 CBC");
8136                 memcpy(ctx->iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
8137                 break;
8138 #endif
8139
8140             case ARC4_TYPE :
8141                 WOLFSSL_MSG("ARC4");
8142                 break;
8143
8144             case NULL_CIPHER_TYPE :
8145                 WOLFSSL_MSG("NULL");
8146                 break;
8147
8148             default: {
8149                 WOLFSSL_MSG("bad type");
8150                 return SSL_FATAL_ERROR;
8151             }
8152         }
8153         return SSL_SUCCESS;
8154     }
8155
8156
8157     /* set internal IV from external, SSL_SUCCESS on success */
8158     int  wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
8159     {
8160
8161         WOLFSSL_ENTER("wolfSSL_SetInternalIV");
8162
8163         if (ctx == NULL) {
8164             WOLFSSL_MSG("Bad function argument");
8165             return SSL_FATAL_ERROR;
8166         }
8167
8168         switch (ctx->cipherType) {
8169
8170 #ifndef NO_AES
8171             case AES_128_CBC_TYPE :
8172             case AES_192_CBC_TYPE :
8173             case AES_256_CBC_TYPE :
8174                 WOLFSSL_MSG("AES CBC");
8175                 memcpy(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
8176                 break;
8177
8178 #ifdef WOLFSSL_AES_COUNTER
8179             case AES_128_CTR_TYPE :
8180             case AES_192_CTR_TYPE :
8181             case AES_256_CTR_TYPE :
8182                 WOLFSSL_MSG("AES CTR");
8183                 memcpy(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
8184                 break;
8185 #endif
8186
8187 #endif /* NO_AES */
8188
8189 #ifndef NO_DES3
8190             case DES_CBC_TYPE :
8191                 WOLFSSL_MSG("DES CBC");
8192                 memcpy(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
8193                 break;
8194
8195             case DES_EDE3_CBC_TYPE :
8196                 WOLFSSL_MSG("DES EDE3 CBC");
8197                 memcpy(&ctx->cipher.des3.reg, ctx->iv, DES_BLOCK_SIZE);
8198                 break;
8199 #endif
8200
8201             case ARC4_TYPE :
8202                 WOLFSSL_MSG("ARC4");
8203                 break;
8204
8205             case NULL_CIPHER_TYPE :
8206                 WOLFSSL_MSG("NULL");
8207                 break;
8208
8209             default: {
8210                 WOLFSSL_MSG("bad type");
8211                 return SSL_FATAL_ERROR;
8212             }
8213         }
8214         return SSL_SUCCESS;
8215     }
8216
8217
8218     /* SSL_SUCCESS on ok */
8219     int wolfSSL_EVP_DigestInit(WOLFSSL_EVP_MD_CTX* ctx, const WOLFSSL_EVP_MD* type)
8220     {
8221         WOLFSSL_ENTER("EVP_DigestInit");
8222         if (XSTRNCMP(type, "SHA256", 6) == 0) {
8223              ctx->macType = SHA256;
8224              wolfSSL_SHA256_Init((SHA256_CTX*)&ctx->hash);
8225         }
8226     #ifdef WOLFSSL_SHA384
8227         else if (XSTRNCMP(type, "SHA384", 6) == 0) {
8228              ctx->macType = SHA384;
8229              wolfSSL_SHA384_Init((SHA384_CTX*)&ctx->hash);
8230         }
8231     #endif
8232     #ifdef WOLFSSL_SHA512
8233         else if (XSTRNCMP(type, "SHA512", 6) == 0) {
8234              ctx->macType = SHA512;
8235              wolfSSL_SHA512_Init((SHA512_CTX*)&ctx->hash);
8236         }
8237     #endif
8238     #ifndef NO_MD5
8239         else if (XSTRNCMP(type, "MD5", 3) == 0) {
8240             ctx->macType = MD5;
8241             wolfSSL_MD5_Init((MD5_CTX*)&ctx->hash);
8242         }
8243     #endif
8244     #ifndef NO_SHA
8245         /* has to be last since would pick or 256, 384, or 512 too */
8246         else if (XSTRNCMP(type, "SHA", 3) == 0) {
8247              ctx->macType = SHA;
8248              wolfSSL_SHA_Init((SHA_CTX*)&ctx->hash);
8249         }
8250     #endif /* NO_SHA */
8251         else
8252              return BAD_FUNC_ARG;
8253
8254         return SSL_SUCCESS;
8255     }
8256
8257
8258     /* SSL_SUCCESS on ok */
8259     int wolfSSL_EVP_DigestUpdate(WOLFSSL_EVP_MD_CTX* ctx, const void* data,
8260                                 unsigned long sz)
8261     {
8262         WOLFSSL_ENTER("EVP_DigestUpdate");
8263
8264         switch (ctx->macType) {
8265 #ifndef NO_MD5
8266             case MD5:
8267                 wolfSSL_MD5_Update((MD5_CTX*)&ctx->hash, data,
8268                                   (unsigned long)sz);
8269                 break;
8270 #endif
8271 #ifndef NO_SHA
8272             case SHA:
8273                 wolfSSL_SHA_Update((SHA_CTX*)&ctx->hash, data,
8274                                   (unsigned long)sz);
8275                 break;
8276 #endif
8277 #ifndef NO_SHA256
8278             case SHA256:
8279                 wolfSSL_SHA256_Update((SHA256_CTX*)&ctx->hash, data,
8280                                      (unsigned long)sz);
8281                 break;
8282 #endif
8283 #ifdef WOLFSSL_SHA384
8284             case SHA384:
8285                 wolfSSL_SHA384_Update((SHA384_CTX*)&ctx->hash, data,
8286                                      (unsigned long)sz);
8287                 break;
8288 #endif
8289 #ifdef WOLFSSL_SHA512
8290             case SHA512:
8291                 wolfSSL_SHA512_Update((SHA512_CTX*)&ctx->hash, data,
8292                                      (unsigned long)sz);
8293                 break;
8294 #endif
8295             default:
8296                 return BAD_FUNC_ARG;
8297         }
8298
8299         return SSL_SUCCESS;
8300     }
8301
8302
8303     /* SSL_SUCCESS on ok */
8304     int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md,
8305                                unsigned int* s)
8306     {
8307         WOLFSSL_ENTER("EVP_DigestFinal");
8308         switch (ctx->macType) {
8309 #ifndef NO_MD5
8310             case MD5:
8311                 wolfSSL_MD5_Final(md, (MD5_CTX*)&ctx->hash);
8312                 if (s) *s = MD5_DIGEST_SIZE;
8313                 break;
8314 #endif
8315 #ifndef NO_SHA
8316             case SHA:
8317                 wolfSSL_SHA_Final(md, (SHA_CTX*)&ctx->hash);
8318                 if (s) *s = SHA_DIGEST_SIZE;
8319                 break;
8320 #endif
8321 #ifndef NO_SHA256
8322             case SHA256:
8323                 wolfSSL_SHA256_Final(md, (SHA256_CTX*)&ctx->hash);
8324                 if (s) *s = SHA256_DIGEST_SIZE;
8325                 break;
8326 #endif
8327 #ifdef WOLFSSL_SHA384
8328             case SHA384:
8329                 wolfSSL_SHA384_Final(md, (SHA384_CTX*)&ctx->hash);
8330                 if (s) *s = SHA384_DIGEST_SIZE;
8331                 break;
8332 #endif
8333 #ifdef WOLFSSL_SHA512
8334             case SHA512:
8335                 wolfSSL_SHA512_Final(md, (SHA512_CTX*)&ctx->hash);
8336                 if (s) *s = SHA512_DIGEST_SIZE;
8337                 break;
8338 #endif
8339             default:
8340                 return BAD_FUNC_ARG;
8341         }
8342
8343         return SSL_SUCCESS;
8344     }
8345
8346
8347     /* SSL_SUCCESS on ok */
8348     int wolfSSL_EVP_DigestFinal_ex(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md,
8349                                   unsigned int* s)
8350     {
8351         WOLFSSL_ENTER("EVP_DigestFinal_ex");
8352         return EVP_DigestFinal(ctx, md, s);
8353     }
8354
8355
8356     unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, const void* key,
8357                                int key_len, const unsigned char* d, int n,
8358                                unsigned char* md, unsigned int* md_len)
8359     {
8360         int type;
8361         unsigned char* ret = NULL;
8362 #ifdef WOLFSSL_SMALL_STACK
8363         Hmac* hmac = NULL;
8364 #else
8365         Hmac  hmac[1];
8366 #endif
8367
8368         WOLFSSL_ENTER("HMAC");
8369         if (!md)
8370             return NULL;  /* no static buffer support */
8371
8372         if (XSTRNCMP(evp_md, "MD5", 3) == 0)
8373             type = MD5;
8374         else if (XSTRNCMP(evp_md, "SHA", 3) == 0)
8375             type = SHA;
8376         else
8377             return NULL;
8378
8379     #ifdef WOLFSSL_SMALL_STACK
8380         hmac = (Hmac*)XMALLOC(sizeof(Hmac), NULL, DYNAMIC_TYPE_TMP_BUFFER);
8381         if (hmac == NULL)
8382             return NULL;
8383     #endif
8384
8385         if (wc_HmacSetKey(hmac, type, (const byte*)key, key_len) == 0)
8386             if (wc_HmacUpdate(hmac, d, n) == 0)
8387                 if (wc_HmacFinal(hmac, md) == 0) {
8388                     if (md_len)
8389                         *md_len = (type == MD5) ? (int)MD5_DIGEST_SIZE
8390                                                 : (int)SHA_DIGEST_SIZE;
8391                     ret = md;
8392                 }
8393
8394     #ifdef WOLFSSL_SMALL_STACK
8395         XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8396     #endif
8397
8398         return ret;
8399     }
8400
8401     void wolfSSL_ERR_clear_error(void)
8402     {
8403         /* TODO: */
8404     }
8405
8406
8407     int wolfSSL_RAND_status(void)
8408     {
8409         return SSL_SUCCESS;  /* wolfCrypt provides enough seed internally */
8410     }
8411
8412
8413
8414     void wolfSSL_RAND_add(const void* add, int len, double entropy)
8415     {
8416         (void)add;
8417         (void)len;
8418         (void)entropy;
8419
8420         /* wolfSSL seeds/adds internally, use explicit RNG if you want
8421            to take control */
8422     }
8423
8424
8425 #ifndef NO_DES3
8426     /* SSL_SUCCESS on ok */
8427     int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key,
8428                              WOLFSSL_DES_key_schedule* schedule)
8429     {
8430         WOLFSSL_ENTER("DES_key_sched");
8431         XMEMCPY(schedule, key, sizeof(const_DES_cblock));
8432         return SSL_SUCCESS;
8433     }
8434
8435
8436     void wolfSSL_DES_cbc_encrypt(const unsigned char* input,
8437                      unsigned char* output, long length,
8438                      WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec,
8439                      int enc)
8440     {
8441         Des myDes;
8442
8443         WOLFSSL_ENTER("DES_cbc_encrypt");
8444
8445         /* OpenSSL compat, no ret */
8446         wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
8447
8448         if (enc)
8449             wc_Des_CbcEncrypt(&myDes, output, input, (word32)length);
8450         else
8451             wc_Des_CbcDecrypt(&myDes, output, input, (word32)length);
8452     }
8453
8454
8455     /* correctly sets ivec for next call */
8456     void wolfSSL_DES_ncbc_encrypt(const unsigned char* input,
8457                      unsigned char* output, long length,
8458                      WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec,
8459                      int enc)
8460     {
8461         Des myDes;
8462
8463         WOLFSSL_ENTER("DES_ncbc_encrypt");
8464
8465         /* OpenSSL compat, no ret */
8466         wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
8467
8468         if (enc)
8469             wc_Des_CbcEncrypt(&myDes, output, input, (word32)length);
8470         else
8471             wc_Des_CbcDecrypt(&myDes, output, input, (word32)length);
8472
8473         XMEMCPY(ivec, output + length - sizeof(DES_cblock), sizeof(DES_cblock));
8474     }
8475
8476 #endif /* NO_DES3 */
8477
8478
8479     void wolfSSL_ERR_free_strings(void)
8480     {
8481         /* handled internally */
8482     }
8483
8484
8485     void wolfSSL_ERR_remove_state(unsigned long state)
8486     {
8487         /* TODO: GetErrors().Remove(); */
8488         (void)state;
8489     }
8490
8491
8492     void wolfSSL_EVP_cleanup(void)
8493     {
8494         /* nothing to do here */
8495     }
8496
8497
8498     void wolfSSL_cleanup_all_ex_data(void)
8499     {
8500         /* nothing to do here */
8501     }
8502
8503
8504     int wolfSSL_clear(WOLFSSL* ssl)
8505     {
8506         (void)ssl;
8507         /* TODO: GetErrors().Remove(); */
8508         return SSL_SUCCESS;
8509     }
8510
8511
8512     long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t)
8513     {
8514         word32 tmptime;
8515         if (!ses || t < 0)
8516             return BAD_FUNC_ARG;
8517
8518         tmptime = t & 0xFFFFFFFF;
8519
8520         ses->timeout = tmptime;
8521
8522         return SSL_SUCCESS;
8523     }
8524
8525
8526     long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode)
8527     {
8528         /* SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
8529
8530         WOLFSSL_ENTER("SSL_CTX_set_mode");
8531         if (mode == SSL_MODE_ENABLE_PARTIAL_WRITE)
8532             ctx->partialWrite = 1;
8533
8534         return mode;
8535     }
8536
8537
8538     long wolfSSL_SSL_get_mode(WOLFSSL* ssl)
8539     {
8540         /* TODO: */
8541         (void)ssl;
8542         return 0;
8543     }
8544
8545
8546     long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx)
8547     {
8548         /* TODO: */
8549         (void)ctx;
8550         return 0;
8551     }
8552
8553
8554     void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m)
8555     {
8556         /* TODO: maybe? */
8557         (void)ctx;
8558         (void)m;
8559     }
8560
8561
8562     int wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX* ctx,
8563                                        const unsigned char* sid_ctx,
8564                                        unsigned int sid_ctx_len)
8565     {
8566         /* No application specific context needed for wolfSSL */
8567         (void)ctx;
8568         (void)sid_ctx;
8569         (void)sid_ctx_len;
8570         return SSL_SUCCESS;
8571     }
8572
8573
8574     long wolfSSL_CTX_sess_get_cache_size(WOLFSSL_CTX* ctx)
8575     {
8576         /* TODO: maybe? */
8577         (void)ctx;
8578         return (~0);
8579     }
8580
8581     unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line,
8582                                           const char** data, int *flags)
8583     {
8584         /* Not implemented */
8585         (void)file;
8586         (void)line;
8587         (void)data;
8588         (void)flags;
8589         return 0;
8590     }
8591
8592 #endif /* OPENSSL_EXTRA */
8593
8594
8595 #if defined(KEEP_PEER_CERT)
8596
8597     WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl)
8598     {
8599         WOLFSSL_ENTER("SSL_get_peer_certificate");
8600         if (ssl->peerCert.issuer.sz)
8601             return &ssl->peerCert;
8602         else
8603             return 0;
8604     }
8605
8606 #endif /* KEEP_PEER_CERT */
8607
8608
8609 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
8610
8611     void wolfSSL_FreeX509(WOLFSSL_X509* x509)
8612     {
8613         WOLFSSL_ENTER("wolfSSL_FreeX509");
8614         FreeX509(x509);
8615     }
8616
8617
8618     /* return the next, if any, altname from the peer cert */
8619     char* wolfSSL_X509_get_next_altname(WOLFSSL_X509* cert)
8620     {
8621         char* ret = NULL;
8622         WOLFSSL_ENTER("wolfSSL_X509_get_next_altname");
8623
8624         /* don't have any to work with */
8625         if (cert == NULL || cert->altNames == NULL)
8626             return NULL;
8627
8628         /* already went through them */
8629         if (cert->altNamesNext == NULL)
8630             return NULL;
8631
8632         ret = cert->altNamesNext->name;
8633         cert->altNamesNext = cert->altNamesNext->next;
8634
8635         return ret;
8636     }
8637
8638
8639     WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509* cert)
8640     {
8641         WOLFSSL_ENTER("X509_get_issuer_name");
8642         return &cert->issuer;
8643     }
8644
8645
8646     WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
8647     {
8648         WOLFSSL_ENTER("X509_get_subject_name");
8649         return &cert->subject;
8650     }
8651
8652
8653     int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509)
8654     {
8655         int isCA = 0;
8656
8657         WOLFSSL_ENTER("wolfSSL_X509_get_isCA");
8658
8659         if (x509 != NULL)
8660             isCA = x509->isCa;
8661
8662         WOLFSSL_LEAVE("wolfSSL_X509_get_isCA", isCA);
8663
8664         return isCA;
8665     }
8666
8667
8668 #ifdef OPENSSL_EXTRA
8669     int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509* x509, int nid)
8670     {
8671         int isSet = 0;
8672
8673         WOLFSSL_ENTER("wolfSSL_X509_ext_isSet_by_NID");
8674
8675         if (x509 != NULL) {
8676             switch (nid) {
8677                 case BASIC_CA_OID: isSet = x509->basicConstSet; break;
8678                 case ALT_NAMES_OID: isSet = x509->subjAltNameSet; break;
8679                 case AUTH_KEY_OID: isSet = x509->authKeyIdSet; break;
8680                 case SUBJ_KEY_OID: isSet = x509->subjKeyIdSet; break;
8681                 case KEY_USAGE_OID: isSet = x509->keyUsageSet; break;
8682                 #ifdef WOLFSSL_SEP
8683                     case CERT_POLICY_OID: isSet = x509->certPolicySet; break;
8684                 #endif /* WOLFSSL_SEP */
8685             }
8686         }
8687
8688         WOLFSSL_LEAVE("wolfSSL_X509_ext_isSet_by_NID", isSet);
8689
8690         return isSet;
8691     }
8692
8693
8694     int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509* x509, int nid)
8695     {
8696         int crit = 0;
8697
8698         WOLFSSL_ENTER("wolfSSL_X509_ext_get_critical_by_NID");
8699
8700         if (x509 != NULL) {
8701             switch (nid) {
8702                 case BASIC_CA_OID: crit = x509->basicConstCrit; break;
8703                 case ALT_NAMES_OID: crit = x509->subjAltNameCrit; break;
8704                 case AUTH_KEY_OID: crit = x509->authKeyIdCrit; break;
8705                 case SUBJ_KEY_OID: crit = x509->subjKeyIdCrit; break;
8706                 case KEY_USAGE_OID: crit = x509->keyUsageCrit; break;
8707                 #ifdef WOLFSSL_SEP
8708                     case CERT_POLICY_OID: crit = x509->certPolicyCrit; break;
8709                 #endif /* WOLFSSL_SEP */
8710             }
8711         }
8712
8713         WOLFSSL_LEAVE("wolfSSL_X509_ext_get_critical_by_NID", crit);
8714
8715         return crit;
8716     }
8717
8718
8719     int wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509* x509)
8720     {
8721         int isSet = 0;
8722
8723         WOLFSSL_ENTER("wolfSSL_X509_get_isSet_pathLength");
8724
8725         if (x509 != NULL)
8726             isSet = x509->basicConstPlSet;
8727
8728         WOLFSSL_LEAVE("wolfSSL_X509_get_isSet_pathLength", isSet);
8729
8730         return isSet;
8731     }
8732
8733
8734     word32 wolfSSL_X509_get_pathLength(WOLFSSL_X509* x509)
8735     {
8736         word32 pathLength = 0;
8737
8738         WOLFSSL_ENTER("wolfSSL_X509_get_pathLength");
8739
8740         if (x509 != NULL)
8741             pathLength = x509->pathLength;
8742
8743         WOLFSSL_LEAVE("wolfSSL_X509_get_pathLength", pathLength);
8744
8745         return pathLength;
8746     }
8747
8748
8749     unsigned int wolfSSL_X509_get_keyUsage(WOLFSSL_X509* x509)
8750     {
8751         word16 usage = 0;
8752
8753         WOLFSSL_ENTER("wolfSSL_X509_get_keyUsage");
8754
8755         if (x509 != NULL)
8756             usage = x509->keyUsage;
8757
8758         WOLFSSL_LEAVE("wolfSSL_X509_get_keyUsage", usage);
8759
8760         return usage;
8761     }
8762
8763
8764     byte* wolfSSL_X509_get_authorityKeyID(
8765                                       WOLFSSL_X509* x509, byte* dst, int* dstLen)
8766     {
8767         byte *id = NULL;
8768         int copySz = 0;
8769
8770         WOLFSSL_ENTER("wolfSSL_X509_get_authorityKeyID");
8771
8772         if (x509 != NULL) {
8773             if (x509->authKeyIdSet) {
8774                 copySz = min(dstLen != NULL ? *dstLen : 0,
8775                                                         (int)x509->authKeyIdSz);
8776                 id = x509->authKeyId;
8777             }
8778
8779             if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
8780                 XMEMCPY(dst, id, copySz);
8781                 id = dst;
8782                 *dstLen = copySz;
8783             }
8784         }
8785
8786         WOLFSSL_LEAVE("wolfSSL_X509_get_authorityKeyID", copySz);
8787
8788         return id;
8789     }
8790
8791
8792     byte* wolfSSL_X509_get_subjectKeyID(
8793                                       WOLFSSL_X509* x509, byte* dst, int* dstLen)
8794     {
8795         byte *id = NULL;
8796         int copySz = 0;
8797
8798         WOLFSSL_ENTER("wolfSSL_X509_get_subjectKeyID");
8799
8800         if (x509 != NULL) {
8801             if (x509->subjKeyIdSet) {
8802                 copySz = min(dstLen != NULL ? *dstLen : 0,
8803                                                         (int)x509->subjKeyIdSz);
8804                 id = x509->subjKeyId;
8805             }
8806
8807             if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
8808                 XMEMCPY(dst, id, copySz);
8809                 id = dst;
8810                 *dstLen = copySz;
8811             }
8812         }
8813
8814         WOLFSSL_LEAVE("wolfSSL_X509_get_subjectKeyID", copySz);
8815
8816         return id;
8817     }
8818
8819
8820     int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME* name)
8821     {
8822         int count = 0;
8823
8824         WOLFSSL_ENTER("wolfSSL_X509_NAME_entry_count");
8825
8826         if (name != NULL)
8827             count = name->fullName.entryCount;
8828
8829         WOLFSSL_LEAVE("wolfSSL_X509_NAME_entry_count", count);
8830         return count;
8831     }
8832
8833
8834     int wolfSSL_X509_NAME_get_text_by_NID(WOLFSSL_X509_NAME* name,
8835                                                     int nid, char* buf, int len)
8836     {
8837         char *text = NULL;
8838         int textSz = 0;
8839
8840         WOLFSSL_ENTER("wolfSSL_X509_NAME_get_text_by_NID");
8841
8842         switch (nid) {
8843             case ASN_COMMON_NAME:
8844                 text = name->fullName.fullName + name->fullName.cnIdx;
8845                 textSz = name->fullName.cnLen;
8846                 break;
8847             case ASN_SUR_NAME:
8848                 text = name->fullName.fullName + name->fullName.snIdx;
8849                 textSz = name->fullName.snLen;
8850                 break;
8851             case ASN_SERIAL_NUMBER:
8852                 text = name->fullName.fullName + name->fullName.serialIdx;
8853                 textSz = name->fullName.serialLen;
8854                 break;
8855             case ASN_COUNTRY_NAME:
8856                 text = name->fullName.fullName + name->fullName.cIdx;
8857                 textSz = name->fullName.cLen;
8858                 break;
8859             case ASN_LOCALITY_NAME:
8860                 text = name->fullName.fullName + name->fullName.lIdx;
8861                 textSz = name->fullName.lLen;
8862                 break;
8863             case ASN_STATE_NAME:
8864                 text = name->fullName.fullName + name->fullName.stIdx;
8865                 textSz = name->fullName.stLen;
8866                 break;
8867             case ASN_ORG_NAME:
8868                 text = name->fullName.fullName + name->fullName.oIdx;
8869                 textSz = name->fullName.oLen;
8870                 break;
8871             case ASN_ORGUNIT_NAME:
8872                 text = name->fullName.fullName + name->fullName.ouIdx;
8873                 textSz = name->fullName.ouLen;
8874                 break;
8875             default:
8876                 break;
8877         }
8878
8879         if (buf != NULL && text != NULL) {
8880             textSz = min(textSz, len);
8881             XMEMCPY(buf, text, textSz);
8882             buf[textSz] = '\0';
8883         }
8884
8885         WOLFSSL_LEAVE("wolfSSL_X509_NAME_get_text_by_NID", textSz);
8886         return textSz;
8887     }
8888 #endif
8889
8890
8891     /* copy name into in buffer, at most sz bytes, if buffer is null will
8892        malloc buffer, call responsible for freeing                     */
8893     char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
8894     {
8895         int copySz = min(sz, name->sz);
8896
8897         WOLFSSL_ENTER("wolfSSL_X509_NAME_oneline");
8898         if (!name->sz) return in;
8899
8900         if (!in) {
8901             in = (char*)XMALLOC(name->sz, 0, DYNAMIC_TYPE_OPENSSL);
8902             if (!in ) return in;
8903             copySz = name->sz;
8904         }
8905
8906         if (copySz == 0)
8907             return in;
8908
8909         XMEMCPY(in, name->name, copySz - 1);
8910         in[copySz - 1] = 0;
8911
8912         return in;
8913     }
8914
8915
8916     int wolfSSL_X509_get_signature_type(WOLFSSL_X509* x509)
8917     {
8918         int type = 0;
8919
8920         WOLFSSL_ENTER("wolfSSL_X509_get_signature_type");
8921
8922         if (x509 != NULL)
8923             type = x509->sigOID;
8924
8925         return type;
8926     }
8927
8928
8929     int wolfSSL_X509_get_signature(WOLFSSL_X509* x509,
8930                                                  unsigned char* buf, int* bufSz)
8931     {
8932         WOLFSSL_ENTER("wolfSSL_X509_get_signature");
8933         if (x509 == NULL || bufSz == NULL || *bufSz < (int)x509->sig.length)
8934             return SSL_FATAL_ERROR;
8935
8936         if (buf != NULL)
8937             XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
8938         *bufSz = x509->sig.length;
8939
8940         return SSL_SUCCESS;
8941     }
8942
8943
8944     /* write X509 serial number in unsigned binary to buffer
8945        buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
8946        return SSL_SUCCESS on success */
8947     int wolfSSL_X509_get_serial_number(WOLFSSL_X509* x509, byte* in, int* inOutSz)
8948     {
8949         WOLFSSL_ENTER("wolfSSL_X509_get_serial_number");
8950         if (x509 == NULL || in == NULL ||
8951                                    inOutSz == NULL || *inOutSz < x509->serialSz)
8952             return BAD_FUNC_ARG;
8953
8954         XMEMCPY(in, x509->serial, x509->serialSz);
8955         *inOutSz = x509->serialSz;
8956
8957         return SSL_SUCCESS;
8958     }
8959
8960
8961     const byte* wolfSSL_X509_get_der(WOLFSSL_X509* x509, int* outSz)
8962     {
8963         WOLFSSL_ENTER("wolfSSL_X509_get_der");
8964
8965         if (x509 == NULL || outSz == NULL)
8966             return NULL;
8967
8968         *outSz = (int)x509->derCert.length;
8969         return x509->derCert.buffer;
8970     }
8971
8972
8973     int wolfSSL_X509_version(WOLFSSL_X509* x509)
8974     {
8975         WOLFSSL_ENTER("wolfSSL_X509_version");
8976
8977         if (x509 == NULL)
8978             return 0;
8979
8980         return x509->version;
8981     }
8982
8983
8984     const byte* wolfSSL_X509_notBefore(WOLFSSL_X509* x509)
8985     {
8986         WOLFSSL_ENTER("wolfSSL_X509_notBefore");
8987
8988         if (x509 == NULL)
8989             return NULL;
8990
8991         return x509->notBefore;
8992     }
8993
8994
8995     const byte* wolfSSL_X509_notAfter(WOLFSSL_X509* x509)
8996     {
8997         WOLFSSL_ENTER("wolfSSL_X509_notAfter");
8998
8999         if (x509 == NULL)
9000             return NULL;
9001
9002         return x509->notAfter;
9003     }
9004
9005
9006 #ifdef WOLFSSL_SEP
9007
9008 /* copy oid into in buffer, at most *inOutSz bytes, if buffer is null will
9009    malloc buffer, call responsible for freeing. Actual size returned in
9010    *inOutSz. Requires inOutSz be non-null */
9011 byte* wolfSSL_X509_get_device_type(WOLFSSL_X509* x509, byte* in, int *inOutSz)
9012 {
9013     int copySz;
9014
9015     WOLFSSL_ENTER("wolfSSL_X509_get_dev_type");
9016     if (inOutSz == NULL) return NULL;
9017     if (!x509->deviceTypeSz) return in;
9018
9019     copySz = min(*inOutSz, x509->deviceTypeSz);
9020
9021     if (!in) {
9022         in = (byte*)XMALLOC(x509->deviceTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
9023         if (!in) return in;
9024         copySz = x509->deviceTypeSz;
9025     }
9026
9027     XMEMCPY(in, x509->deviceType, copySz);
9028     *inOutSz = copySz;
9029
9030     return in;
9031 }
9032
9033
9034 byte* wolfSSL_X509_get_hw_type(WOLFSSL_X509* x509, byte* in, int* inOutSz)
9035 {
9036     int copySz;
9037
9038     WOLFSSL_ENTER("wolfSSL_X509_get_hw_type");
9039     if (inOutSz == NULL) return NULL;
9040     if (!x509->hwTypeSz) return in;
9041
9042     copySz = min(*inOutSz, x509->hwTypeSz);
9043
9044     if (!in) {
9045         in = (byte*)XMALLOC(x509->hwTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
9046         if (!in) return in;
9047         copySz = x509->hwTypeSz;
9048     }
9049
9050     XMEMCPY(in, x509->hwType, copySz);
9051     *inOutSz = copySz;
9052
9053     return in;
9054 }
9055
9056
9057 byte* wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509* x509,byte* in,int* inOutSz)
9058 {
9059     int copySz;
9060
9061     WOLFSSL_ENTER("wolfSSL_X509_get_hw_serial_number");
9062     if (inOutSz == NULL) return NULL;
9063     if (!x509->hwTypeSz) return in;
9064
9065     copySz = min(*inOutSz, x509->hwSerialNumSz);
9066
9067     if (!in) {
9068         in = (byte*)XMALLOC(x509->hwSerialNumSz, 0, DYNAMIC_TYPE_OPENSSL);
9069         if (!in) return in;
9070         copySz = x509->hwSerialNumSz;
9071     }
9072
9073     XMEMCPY(in, x509->hwSerialNum, copySz);
9074     *inOutSz = copySz;
9075
9076     return in;
9077 }
9078
9079 #endif /* WOLFSSL_SEP */
9080
9081
9082 WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
9083 {
9084     WOLFSSL_X509 *newX509 = NULL;
9085
9086     WOLFSSL_ENTER("wolfSSL_X509_d2i");
9087
9088     if (in != NULL && len != 0) {
9089     #ifdef WOLFSSL_SMALL_STACK
9090         DecodedCert* cert = NULL;
9091     #else
9092         DecodedCert  cert[1];
9093     #endif
9094
9095     #ifdef WOLFSSL_SMALL_STACK
9096         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
9097                                                        DYNAMIC_TYPE_TMP_BUFFER);
9098         if (cert == NULL)
9099             return NULL;
9100     #endif
9101
9102         InitDecodedCert(cert, (byte*)in, len, NULL);
9103         if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
9104             newX509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509),
9105                                                        NULL, DYNAMIC_TYPE_X509);
9106             if (newX509 != NULL) {
9107                 InitX509(newX509, 1);
9108                 if (CopyDecodedToX509(newX509, cert) != 0) {
9109                     XFREE(newX509, NULL, DYNAMIC_TYPE_X509);
9110                     newX509 = NULL;
9111                 }
9112             }
9113         }
9114         FreeDecodedCert(cert);
9115     #ifdef WOLFSSL_SMALL_STACK
9116         XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9117     #endif
9118     }
9119
9120     if (x509 != NULL)
9121         *x509 = newX509;
9122
9123     return newX509;
9124 }
9125
9126
9127 #ifndef NO_FILESYSTEM
9128
9129 #ifndef NO_STDIO_FILESYSTEM
9130
9131 WOLFSSL_X509* wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file)
9132 {
9133     WOLFSSL_X509* newX509 = NULL;
9134
9135     WOLFSSL_ENTER("wolfSSL_X509_d2i_fp");
9136
9137     if (file != XBADFILE) {
9138         byte* fileBuffer = NULL;
9139         long sz = 0;
9140
9141         XFSEEK(file, 0, XSEEK_END);
9142         sz = XFTELL(file);
9143         XREWIND(file);
9144
9145         if (sz < 0) {
9146             WOLFSSL_MSG("Bad tell on FILE");
9147             return NULL;
9148         }
9149
9150         fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
9151         if (fileBuffer != NULL) {
9152             int ret = (int)XFREAD(fileBuffer, sz, 1, file);
9153             if (ret > 0) {
9154                 newX509 = wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
9155             }
9156             XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
9157         }
9158     }
9159
9160     if (x509 != NULL)
9161         *x509 = newX509;
9162
9163     return newX509;
9164 }
9165
9166 #endif /* NO_STDIO_FILESYSTEM */
9167
9168 WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format)
9169 {
9170 #ifdef WOLFSSL_SMALL_STACK
9171     byte  staticBuffer[1]; /* force heap usage */
9172 #else
9173     byte  staticBuffer[FILE_BUFFER_SIZE];
9174 #endif
9175     byte* fileBuffer = staticBuffer;
9176     int   dynamic = 0;
9177     int   ret;
9178     long  sz = 0;
9179     XFILE file;
9180
9181     WOLFSSL_X509* x509 = NULL;
9182     buffer der;
9183
9184     WOLFSSL_ENTER("wolfSSL_X509_load_certificate");
9185
9186     /* Check the inputs */
9187     if ((fname == NULL) ||
9188         (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM))
9189         return NULL;
9190
9191     file = XFOPEN(fname, "rb");
9192     if (file == XBADFILE)
9193         return NULL;
9194
9195     XFSEEK(file, 0, XSEEK_END);
9196     sz = XFTELL(file);
9197     XREWIND(file);
9198
9199     if (sz > (long)sizeof(staticBuffer)) {
9200         fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
9201         if (fileBuffer == NULL) {
9202             XFCLOSE(file);
9203             return NULL;
9204         }
9205         dynamic = 1;
9206     }
9207     else if (sz < 0) {
9208         XFCLOSE(file);
9209         return NULL;
9210     }
9211
9212     ret = (int)XFREAD(fileBuffer, sz, 1, file);
9213     if (ret < 0) {
9214         XFCLOSE(file);
9215         if (dynamic)
9216             XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
9217         return NULL;
9218     }
9219
9220     XFCLOSE(file);
9221
9222     der.buffer = NULL;
9223     der.length = 0;
9224
9225     if (format == SSL_FILETYPE_PEM) {
9226         int ecc = 0;
9227     #ifdef WOLFSSL_SMALL_STACK
9228         EncryptedInfo* info = NULL;
9229     #else
9230         EncryptedInfo  info[1];
9231     #endif
9232
9233     #ifdef WOLFSSL_SMALL_STACK
9234         info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
9235                                                        DYNAMIC_TYPE_TMP_BUFFER);
9236         if (info == NULL) {
9237             if (dynamic)
9238                 XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
9239
9240             return NULL;
9241         }
9242     #endif
9243
9244         info->set = 0;
9245         info->ctx = NULL;
9246         info->consumed = 0;
9247
9248         if (PemToDer(fileBuffer, sz, CERT_TYPE, &der, NULL, info, &ecc) != 0)
9249         {
9250             /* Only time this should fail, and leave `der` with a buffer
9251                is when the Base64 Decode fails. Release `der.buffer` in
9252                that case. */
9253             if (der.buffer != NULL) {
9254                 XFREE(der.buffer, NULL, DYNAMIC_TYPE_CERT);
9255                 der.buffer = NULL;
9256             }
9257         }
9258
9259     #ifdef WOLFSSL_SMALL_STACK
9260         XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9261     #endif
9262     }
9263     else {
9264         der.buffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_CERT);
9265         if (der.buffer != NULL) {
9266             XMEMCPY(der.buffer, fileBuffer, sz);
9267             der.length = (word32)sz;
9268         }
9269     }
9270
9271     if (dynamic)
9272         XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
9273
9274     /* At this point we want `der` to have the certificate in DER format */
9275     /* ready to be decoded. */
9276     if (der.buffer != NULL) {
9277     #ifdef WOLFSSL_SMALL_STACK
9278         DecodedCert* cert = NULL;
9279     #else
9280         DecodedCert  cert[1];
9281     #endif
9282
9283     #ifdef WOLFSSL_SMALL_STACK
9284         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
9285                                                        DYNAMIC_TYPE_TMP_BUFFER);
9286         if (cert != NULL)
9287     #endif
9288         {
9289             InitDecodedCert(cert, der.buffer, der.length, NULL);
9290             if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
9291                 x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
9292                                                              DYNAMIC_TYPE_X509);
9293                 if (x509 != NULL) {
9294                     InitX509(x509, 1);
9295                     if (CopyDecodedToX509(x509, cert) != 0) {
9296                         XFREE(x509, NULL, DYNAMIC_TYPE_X509);
9297                         x509 = NULL;
9298                     }
9299                 }
9300             }
9301
9302             FreeDecodedCert(cert);
9303         #ifdef WOLFSSL_SMALL_STACK
9304             XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9305         #endif
9306         }
9307
9308         XFREE(der.buffer, NULL, DYNAMIC_TYPE_CERT);
9309     }
9310
9311     return x509;
9312 }
9313
9314 #endif /* NO_FILESYSTEM */
9315
9316 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
9317
9318
9319 #ifdef OPENSSL_EXTRA
9320 int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data)
9321 {
9322 #ifdef FORTRESS
9323     if (ssl != NULL && idx < MAX_EX_DATA)
9324     {
9325         ssl->ex_data[idx] = data;
9326         return SSL_SUCCESS;
9327     }
9328 #else
9329     (void)ssl;
9330     (void)idx;
9331     (void)data;
9332 #endif
9333     return SSL_FAILURE;
9334 }
9335
9336
9337 int wolfSSL_set_session_id_context(WOLFSSL* ssl, const unsigned char* id,
9338                                unsigned int len)
9339 {
9340     (void)ssl;
9341     (void)id;
9342     (void)len;
9343     return 0;
9344 }
9345
9346
9347 void wolfSSL_set_connect_state(WOLFSSL* ssl)
9348 {
9349     (void)ssl;
9350     /* client by default */
9351 }
9352 #endif
9353
9354 int wolfSSL_get_shutdown(const WOLFSSL* ssl)
9355 {
9356     return (ssl->options.isClosed  ||
9357             ssl->options.connReset ||
9358             ssl->options.sentNotify);
9359 }
9360
9361
9362 int wolfSSL_session_reused(WOLFSSL* ssl)
9363 {
9364     return ssl->options.resuming;
9365 }
9366
9367 #ifdef OPENSSL_EXTRA
9368 void wolfSSL_SESSION_free(WOLFSSL_SESSION* session)
9369 {
9370     (void)session;
9371 }
9372 #endif
9373
9374 const char* wolfSSL_get_version(WOLFSSL* ssl)
9375 {
9376     WOLFSSL_ENTER("SSL_get_version");
9377     if (ssl->version.major == SSLv3_MAJOR) {
9378         switch (ssl->version.minor) {
9379             case SSLv3_MINOR :
9380                 return "SSLv3";
9381             case TLSv1_MINOR :
9382                 return "TLSv1";
9383             case TLSv1_1_MINOR :
9384                 return "TLSv1.1";
9385             case TLSv1_2_MINOR :
9386                 return "TLSv1.2";
9387             default:
9388                 return "unknown";
9389         }
9390     }
9391     else if (ssl->version.major == DTLS_MAJOR) {
9392         switch (ssl->version.minor) {
9393             case DTLS_MINOR :
9394                 return "DTLS";
9395             case DTLSv1_2_MINOR :
9396                 return "DTLSv1.2";
9397             default:
9398                 return "unknown";
9399         }
9400     }
9401     return "unknown";
9402 }
9403
9404
9405 /* current library version */
9406 const char* wolfSSL_lib_version(void)
9407 {
9408     return LIBWOLFSSL_VERSION_STRING;
9409 }
9410
9411
9412 /* current library version in hex */
9413 word32 wolfSSL_lib_version_hex(void)
9414 {
9415     return LIBWOLFSSL_VERSION_HEX;
9416 }
9417
9418
9419 int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl)
9420 {
9421     WOLFSSL_ENTER("SSL_get_current_cipher_suite");
9422     if (ssl)
9423         return (ssl->options.cipherSuite0 << 8) | ssl->options.cipherSuite;
9424     return 0;
9425 }
9426
9427 WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL* ssl)
9428 {
9429     WOLFSSL_ENTER("SSL_get_current_cipher");
9430     if (ssl)
9431         return &ssl->cipher;
9432     else
9433         return NULL;
9434 }
9435
9436
9437 const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher)
9438 {
9439     (void)cipher;
9440
9441     WOLFSSL_ENTER("SSL_CIPHER_get_name");
9442 #ifndef NO_ERROR_STRINGS
9443     if (cipher) {
9444 #if defined(HAVE_CHACHA)
9445         if (cipher->ssl->options.cipherSuite0 == CHACHA_BYTE) {
9446         /* ChaCha suites */
9447         switch (cipher->ssl->options.cipherSuite) {
9448 #ifdef HAVE_CHACHA
9449 #ifndef NO_RSA
9450             case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
9451                 return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
9452
9453             case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
9454                 return "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
9455 #endif
9456             case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
9457                 return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
9458 #endif
9459             }
9460         }
9461 #endif
9462
9463 #if defined(HAVE_ECC) || defined(HAVE_AESCCM)
9464         /* Awkwardly, the ECC cipher suites use the ECC_BYTE as expected,
9465          * but the AES-CCM cipher suites also use it, even the ones that
9466          * aren't ECC. */
9467         if (cipher->ssl->options.cipherSuite0 == ECC_BYTE) {
9468         /* ECC suites */
9469         switch (cipher->ssl->options.cipherSuite) {
9470 #ifdef HAVE_ECC
9471 #ifndef NO_RSA
9472             case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
9473                 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
9474 #endif
9475             case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
9476                 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
9477 #ifndef NO_RSA
9478             case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
9479                 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
9480 #endif
9481             case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
9482                 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
9483 #ifndef NO_RSA
9484             case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
9485                 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
9486 #endif
9487             case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
9488                 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
9489 #ifndef NO_RSA
9490             case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
9491                 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
9492 #endif
9493             case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
9494                 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
9495 #ifndef NO_SHA
9496 #ifndef NO_RSA
9497             case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
9498                 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
9499             case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
9500                 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
9501 #endif
9502             case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
9503                 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
9504             case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
9505                 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
9506 #ifndef NO_RC4
9507     #ifndef NO_RSA
9508             case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
9509                 return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
9510     #endif
9511             case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
9512                 return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
9513 #endif
9514 #ifndef NO_DES3
9515     #ifndef NO_RSA
9516             case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
9517                 return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
9518     #endif
9519             case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
9520                 return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
9521 #endif
9522
9523 #ifndef NO_RSA
9524             case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
9525                 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
9526             case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
9527                 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
9528 #endif
9529             case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
9530                 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
9531             case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
9532                 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
9533 #ifndef NO_RC4
9534     #ifndef NO_RSA
9535             case TLS_ECDH_RSA_WITH_RC4_128_SHA :
9536                 return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
9537     #endif
9538             case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
9539                 return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
9540 #endif
9541 #ifndef NO_DES3
9542     #ifndef NO_RSA
9543             case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
9544                 return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
9545     #endif
9546             case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
9547                 return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
9548 #endif
9549 #endif /* NO_SHA */
9550
9551 #ifdef HAVE_AESGCM
9552 #ifndef NO_RSA
9553             case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
9554                 return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
9555             case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
9556                 return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
9557 #endif
9558             case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
9559                 return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
9560             case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
9561                 return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
9562 #ifndef NO_RSA
9563             case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
9564                 return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
9565             case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
9566                 return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
9567 #endif
9568             case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
9569                 return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
9570             case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
9571                 return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
9572 #endif
9573 #endif /* HAVE_ECC */
9574
9575 #ifdef HAVE_AESCCM
9576 #ifndef NO_RSA
9577             case TLS_RSA_WITH_AES_128_CCM_8 :
9578                 return "TLS_RSA_WITH_AES_128_CCM_8";
9579             case TLS_RSA_WITH_AES_256_CCM_8 :
9580                 return "TLS_RSA_WITH_AES_256_CCM_8";
9581 #endif
9582 #ifndef NO_PSK
9583             case TLS_PSK_WITH_AES_128_CCM_8 :
9584                 return "TLS_PSK_WITH_AES_128_CCM_8";
9585             case TLS_PSK_WITH_AES_256_CCM_8 :
9586                 return "TLS_PSK_WITH_AES_256_CCM_8";
9587             case TLS_PSK_WITH_AES_128_CCM :
9588                 return "TLS_PSK_WITH_AES_128_CCM";
9589             case TLS_PSK_WITH_AES_256_CCM :
9590                 return "TLS_PSK_WITH_AES_256_CCM";
9591             case TLS_DHE_PSK_WITH_AES_128_CCM :
9592                 return "TLS_DHE_PSK_WITH_AES_128_CCM";
9593             case TLS_DHE_PSK_WITH_AES_256_CCM :
9594                 return "TLS_DHE_PSK_WITH_AES_256_CCM";
9595 #endif
9596 #ifdef HAVE_ECC
9597             case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
9598                 return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8";
9599             case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
9600                 return "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8";
9601 #endif
9602 #endif
9603
9604             default:
9605                 return "NONE";
9606         }
9607         }
9608 #endif  /* ECC */
9609         if (cipher->ssl->options.cipherSuite0 != ECC_BYTE &&
9610             cipher->ssl->options.cipherSuite0 != CHACHA_BYTE) {
9611
9612             /* normal suites */
9613         switch (cipher->ssl->options.cipherSuite) {
9614 #ifndef NO_RSA
9615 #ifndef NO_RC4
9616     #ifndef NO_SHA
9617             case SSL_RSA_WITH_RC4_128_SHA :
9618                 return "SSL_RSA_WITH_RC4_128_SHA";
9619     #endif
9620     #ifndef NO_MD5
9621             case SSL_RSA_WITH_RC4_128_MD5 :
9622                 return "SSL_RSA_WITH_RC4_128_MD5";
9623     #endif
9624 #endif
9625 #ifndef NO_SHA
9626     #ifndef NO_DES3
9627             case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
9628                 return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
9629     #endif
9630             case TLS_RSA_WITH_AES_128_CBC_SHA :
9631                 return "TLS_RSA_WITH_AES_128_CBC_SHA";
9632             case TLS_RSA_WITH_AES_256_CBC_SHA :
9633                 return "TLS_RSA_WITH_AES_256_CBC_SHA";
9634 #endif
9635             case TLS_RSA_WITH_AES_128_CBC_SHA256 :
9636                 return "TLS_RSA_WITH_AES_128_CBC_SHA256";
9637             case TLS_RSA_WITH_AES_256_CBC_SHA256 :
9638                 return "TLS_RSA_WITH_AES_256_CBC_SHA256";
9639     #ifdef HAVE_BLAKE2
9640             case TLS_RSA_WITH_AES_128_CBC_B2B256:
9641                 return "TLS_RSA_WITH_AES_128_CBC_B2B256";
9642             case TLS_RSA_WITH_AES_256_CBC_B2B256:
9643                 return "TLS_RSA_WITH_AES_256_CBC_B2B256";
9644     #endif
9645 #ifndef NO_SHA
9646             case TLS_RSA_WITH_NULL_SHA :
9647                 return "TLS_RSA_WITH_NULL_SHA";
9648 #endif
9649             case TLS_RSA_WITH_NULL_SHA256 :
9650                 return "TLS_RSA_WITH_NULL_SHA256";
9651 #endif /* NO_RSA */
9652 #ifndef NO_PSK
9653 #ifndef NO_SHA
9654             case TLS_PSK_WITH_AES_128_CBC_SHA :
9655                 return "TLS_PSK_WITH_AES_128_CBC_SHA";
9656             case TLS_PSK_WITH_AES_256_CBC_SHA :
9657                 return "TLS_PSK_WITH_AES_256_CBC_SHA";
9658 #endif
9659 #ifndef NO_SHA256
9660             case TLS_PSK_WITH_AES_128_CBC_SHA256 :
9661                 return "TLS_PSK_WITH_AES_128_CBC_SHA256";
9662             case TLS_PSK_WITH_NULL_SHA256 :
9663                 return "TLS_PSK_WITH_NULL_SHA256";
9664             case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 :
9665                 return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
9666             case TLS_DHE_PSK_WITH_NULL_SHA256 :
9667                 return "TLS_DHE_PSK_WITH_NULL_SHA256";
9668     #ifdef HAVE_AESGCM
9669             case TLS_PSK_WITH_AES_128_GCM_SHA256 :
9670                 return "TLS_PSK_WITH_AES_128_GCM_SHA256";
9671             case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 :
9672                 return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
9673     #endif
9674 #endif
9675 #ifdef WOLFSSL_SHA384
9676             case TLS_PSK_WITH_AES_256_CBC_SHA384 :
9677                 return "TLS_PSK_WITH_AES_256_CBC_SHA384";
9678             case TLS_PSK_WITH_NULL_SHA384 :
9679                 return "TLS_PSK_WITH_NULL_SHA384";
9680             case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 :
9681                 return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
9682             case TLS_DHE_PSK_WITH_NULL_SHA384 :
9683                 return "TLS_DHE_PSK_WITH_NULL_SHA384";
9684     #ifdef HAVE_AESGCM
9685             case TLS_PSK_WITH_AES_256_GCM_SHA384 :
9686                 return "TLS_PSK_WITH_AES_256_GCM_SHA384";
9687             case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 :
9688                 return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
9689     #endif
9690 #endif
9691 #ifndef NO_SHA
9692             case TLS_PSK_WITH_NULL_SHA :
9693                 return "TLS_PSK_WITH_NULL_SHA";
9694 #endif
9695 #endif /* NO_PSK */
9696 #ifndef NO_RSA
9697             case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
9698                 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
9699             case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
9700                 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
9701 #ifndef NO_SHA
9702             case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
9703                 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
9704             case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
9705                 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
9706 #endif
9707 #ifndef NO_HC128
9708     #ifndef NO_MD5
9709             case TLS_RSA_WITH_HC_128_MD5 :
9710                 return "TLS_RSA_WITH_HC_128_MD5";
9711     #endif
9712     #ifndef NO_SHA
9713             case TLS_RSA_WITH_HC_128_SHA :
9714                 return "TLS_RSA_WITH_HC_128_SHA";
9715     #endif
9716     #ifdef HAVE_BLAKE2
9717             case TLS_RSA_WITH_HC_128_B2B256:
9718                 return "TLS_RSA_WITH_HC_128_B2B256";
9719     #endif
9720 #endif /* NO_HC128 */
9721 #ifndef NO_SHA
9722     #ifndef NO_RABBIT
9723             case TLS_RSA_WITH_RABBIT_SHA :
9724                 return "TLS_RSA_WITH_RABBIT_SHA";
9725     #endif
9726     #ifdef HAVE_NTRU
9727         #ifndef NO_RC4
9728             case TLS_NTRU_RSA_WITH_RC4_128_SHA :
9729                 return "TLS_NTRU_RSA_WITH_RC4_128_SHA";
9730         #endif
9731         #ifndef NO_DES3
9732             case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
9733                 return "TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA";
9734         #endif
9735             case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
9736                 return "TLS_NTRU_RSA_WITH_AES_128_CBC_SHA";
9737             case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
9738                 return "TLS_NTRU_RSA_WITH_AES_256_CBC_SHA";
9739     #endif /* HAVE_NTRU */
9740 #endif /* NO_SHA */
9741             case TLS_RSA_WITH_AES_128_GCM_SHA256 :
9742                 return "TLS_RSA_WITH_AES_128_GCM_SHA256";
9743             case TLS_RSA_WITH_AES_256_GCM_SHA384 :
9744                 return "TLS_RSA_WITH_AES_256_GCM_SHA384";
9745             case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
9746                 return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
9747             case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
9748                 return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
9749 #ifndef NO_SHA
9750             case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
9751                 return "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA";
9752             case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
9753                 return "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA";
9754 #endif
9755             case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
9756                 return "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256";
9757             case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
9758                 return "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256";
9759 #ifndef NO_SHA
9760             case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
9761                 return "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA";
9762             case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
9763                 return "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA";
9764 #endif
9765             case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
9766                 return "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256";
9767             case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
9768                 return "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256";
9769 #endif /* NO_RSA */
9770 #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
9771             case TLS_DH_anon_WITH_AES_128_CBC_SHA :
9772                 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
9773 #endif
9774             default:
9775                 return "NONE";
9776         }  /* switch */
9777         }  /* normal / ECC */
9778     }
9779 #endif /* NO_ERROR_STRINGS */
9780     return "NONE";
9781 }
9782
9783
9784 const char* wolfSSL_get_cipher(WOLFSSL* ssl)
9785 {
9786     WOLFSSL_ENTER("wolfSSL_get_cipher");
9787     return wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl));
9788 }
9789
9790 #ifdef OPENSSL_EXTRA
9791
9792
9793
9794 char* wolfSSL_CIPHER_description(WOLFSSL_CIPHER* cipher, char* in, int len)
9795 {
9796     (void)cipher;
9797     (void)in;
9798     (void)len;
9799     return 0;
9800 }
9801
9802
9803 WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl)  /* what's ref count */
9804 {
9805     (void)ssl;
9806     return 0;
9807 }
9808
9809
9810 void wolfSSL_X509_free(WOLFSSL_X509* buf)
9811 {
9812     FreeX509(buf);
9813 }
9814
9815
9816 /* was do nothing */
9817 /*
9818 void OPENSSL_free(void* buf)
9819 {
9820     (void)buf;
9821 }
9822 */
9823
9824
9825 int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, char** path,
9826                    int* ssl)
9827 {
9828     (void)url;
9829     (void)host;
9830     (void)port;
9831     (void)path;
9832     (void)ssl;
9833     return 0;
9834 }
9835
9836
9837 WOLFSSL_METHOD* wolfSSLv2_client_method(void)
9838 {
9839     return 0;
9840 }
9841
9842
9843 WOLFSSL_METHOD* wolfSSLv2_server_method(void)
9844 {
9845     return 0;
9846 }
9847
9848
9849 #ifndef NO_MD4
9850
9851 void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX* md4)
9852 {
9853     /* make sure we have a big enough buffer */
9854     typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1];
9855     (void) sizeof(ok);
9856
9857     WOLFSSL_ENTER("MD4_Init");
9858     wc_InitMd4((Md4*)md4);
9859 }
9860
9861
9862 void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX* md4, const void* data,
9863                        unsigned long len)
9864 {
9865     WOLFSSL_ENTER("MD4_Update");
9866     wc_Md4Update((Md4*)md4, (const byte*)data, (word32)len);
9867 }
9868
9869
9870 void wolfSSL_MD4_Final(unsigned char* digest, WOLFSSL_MD4_CTX* md4)
9871 {
9872     WOLFSSL_ENTER("MD4_Final");
9873     wc_Md4Final((Md4*)md4, digest);
9874 }
9875
9876 #endif /* NO_MD4 */
9877
9878
9879 WOLFSSL_BIO* wolfSSL_BIO_pop(WOLFSSL_BIO* top)
9880 {
9881     (void)top;
9882     return 0;
9883 }
9884
9885
9886 int wolfSSL_BIO_pending(WOLFSSL_BIO* bio)
9887 {
9888     (void)bio;
9889     return 0;
9890 }
9891
9892
9893
9894 WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_mem(void)
9895 {
9896     static WOLFSSL_BIO_METHOD meth;
9897
9898     WOLFSSL_ENTER("BIO_s_mem");
9899     meth.type = BIO_MEMORY;
9900
9901     return &meth;
9902 }
9903
9904
9905 WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_base64(void)
9906 {
9907     return 0;
9908 }
9909
9910
9911 void wolfSSL_BIO_set_flags(WOLFSSL_BIO* bio, int flags)
9912 {
9913     (void)bio;
9914     (void)flags;
9915 }
9916
9917
9918
9919 void wolfSSL_RAND_screen(void)
9920 {
9921
9922 }
9923
9924
9925 const char* wolfSSL_RAND_file_name(char* fname, unsigned long len)
9926 {
9927     (void)fname;
9928     (void)len;
9929     return 0;
9930 }
9931
9932
9933 int wolfSSL_RAND_write_file(const char* fname)
9934 {
9935     (void)fname;
9936     return 0;
9937 }
9938
9939
9940 int wolfSSL_RAND_load_file(const char* fname, long len)
9941 {
9942     (void)fname;
9943     /* wolfCrypt provides enough entropy internally or will report error */
9944     if (len == -1)
9945         return 1024;
9946     else
9947         return (int)len;
9948 }
9949
9950
9951 int wolfSSL_RAND_egd(const char* path)
9952 {
9953     (void)path;
9954     return 0;
9955 }
9956
9957
9958
9959 WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void)
9960 {
9961     return 0;
9962 }
9963
9964
9965 WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void)
9966 {
9967     return 0;
9968 }
9969
9970
9971 int wolfSSL_COMP_add_compression_method(int method, void* data)
9972 {
9973     (void)method;
9974     (void)data;
9975     return 0;
9976 }
9977
9978
9979
9980 int wolfSSL_get_ex_new_index(long idx, void* data, void* cb1, void* cb2,
9981                          void* cb3)
9982 {
9983     (void)idx;
9984     (void)data;
9985     (void)cb1;
9986     (void)cb2;
9987     (void)cb3;
9988     return 0;
9989 }
9990
9991
9992 void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f)(
9993                                                           const char*, int))
9994 {
9995     (void)f;
9996 }
9997
9998
9999 void wolfSSL_set_dynlock_lock_callback(
10000              void (*f)(int, WOLFSSL_dynlock_value*, const char*, int))
10001 {
10002     (void)f;
10003 }
10004
10005
10006 void wolfSSL_set_dynlock_destroy_callback(
10007                   void (*f)(WOLFSSL_dynlock_value*, const char*, int))
10008 {
10009     (void)f;
10010 }
10011
10012
10013
10014 const char* wolfSSL_X509_verify_cert_error_string(long err)
10015 {
10016     (void)err;
10017     return 0;
10018 }
10019
10020
10021
10022 int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup, const char* dir,
10023                                long len)
10024 {
10025     (void)lookup;
10026     (void)dir;
10027     (void)len;
10028     return 0;
10029 }
10030
10031
10032 int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
10033                                  const char* file, long len)
10034 {
10035     (void)lookup;
10036     (void)file;
10037     (void)len;
10038     return 0;
10039 }
10040
10041
10042 WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void)
10043 {
10044     return 0;
10045 }
10046
10047
10048 WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void)
10049 {
10050     return 0;
10051 }
10052
10053
10054
10055 WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
10056                                                WOLFSSL_X509_LOOKUP_METHOD* m)
10057 {
10058     (void)store;
10059     (void)m;
10060     return 0;
10061 }
10062
10063
10064 int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509)
10065 {
10066     int result = SSL_FATAL_ERROR;
10067
10068     WOLFSSL_ENTER("wolfSSL_X509_STORE_add_cert");
10069     if (store != NULL && store->cm != NULL && x509 != NULL) {
10070         buffer derCert;
10071         derCert.buffer = (byte*)XMALLOC(x509->derCert.length,
10072                                                    NULL, DYNAMIC_TYPE_CERT);
10073         if (derCert.buffer != NULL) {
10074             derCert.length = x509->derCert.length;
10075                 /* AddCA() frees the buffer. */
10076             XMEMCPY(derCert.buffer,
10077                                 x509->derCert.buffer, x509->derCert.length);
10078             result = AddCA(store->cm, derCert, WOLFSSL_USER_CA, 1);
10079             if (result != SSL_SUCCESS) result = SSL_FATAL_ERROR;
10080         }
10081     }
10082
10083     WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_cert", result);
10084     return result;
10085 }
10086
10087
10088 WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void)
10089 {
10090     WOLFSSL_X509_STORE* store = NULL;
10091
10092     store = (WOLFSSL_X509_STORE*)XMALLOC(sizeof(WOLFSSL_X509_STORE), NULL, 0);
10093     if (store != NULL) {
10094         store->cm = wolfSSL_CertManagerNew();
10095         if (store->cm == NULL) {
10096             XFREE(store, NULL, 0);
10097             store = NULL;
10098         }
10099     }
10100
10101     return store;
10102 }
10103
10104
10105 void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store)
10106 {
10107     if (store != NULL) {
10108         if (store->cm != NULL)
10109         wolfSSL_CertManagerFree(store->cm);
10110         XFREE(store, NULL, 0);
10111     }
10112 }
10113
10114
10115 int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE* store)
10116 {
10117     (void)store;
10118     return SSL_SUCCESS;
10119 }
10120
10121
10122 int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX* ctx, int idx,
10123                             WOLFSSL_X509_NAME* name, WOLFSSL_X509_OBJECT* obj)
10124 {
10125     (void)ctx;
10126     (void)idx;
10127     (void)name;
10128     (void)obj;
10129     return 0;
10130 }
10131
10132
10133 WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new(void)
10134 {
10135     WOLFSSL_X509_STORE_CTX* ctx = (WOLFSSL_X509_STORE_CTX*)XMALLOC(
10136                                     sizeof(WOLFSSL_X509_STORE_CTX), NULL, 0);
10137
10138     if (ctx != NULL)
10139         wolfSSL_X509_STORE_CTX_init(ctx, NULL, NULL, NULL);
10140
10141     return ctx;
10142 }
10143
10144
10145 int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
10146      WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509, STACK_OF(WOLFSSL_X509)* sk)
10147 {
10148     (void)sk;
10149     if (ctx != NULL) {
10150         ctx->store = store;
10151         ctx->current_cert = x509;
10152         ctx->domain = NULL;
10153         ctx->ex_data = NULL;
10154         ctx->userCtx = NULL;
10155         ctx->error = 0;
10156         ctx->error_depth = 0;
10157         ctx->discardSessionCerts = 0;
10158         return SSL_SUCCESS;
10159     }
10160     return SSL_FATAL_ERROR;
10161 }
10162
10163
10164 void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx)
10165 {
10166     if (ctx != NULL) {
10167         if (ctx->store != NULL)
10168             wolfSSL_X509_STORE_free(ctx->store);
10169         if (ctx->current_cert != NULL)
10170             wolfSSL_FreeX509(ctx->current_cert);
10171         XFREE(ctx, NULL, 0);
10172     }
10173 }
10174
10175
10176 void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX* ctx)
10177 {
10178     (void)ctx;
10179 }
10180
10181
10182 int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
10183 {
10184     if (ctx != NULL && ctx->store != NULL && ctx->store->cm != NULL
10185                                              && ctx->current_cert != NULL) {
10186         return wolfSSL_CertManagerVerifyBuffer(ctx->store->cm,
10187                     ctx->current_cert->derCert.buffer,
10188                     ctx->current_cert->derCert.length,
10189                     SSL_FILETYPE_ASN1);
10190     }
10191     return SSL_FATAL_ERROR;
10192 }
10193
10194
10195 WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl)
10196 {
10197     (void)crl;
10198     return 0;
10199 }
10200
10201
10202 WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
10203 {
10204     (void)crl;
10205     return 0;
10206 }
10207
10208
10209
10210 WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
10211 {
10212     WOLFSSL_EVP_PKEY* key = NULL;
10213     if (x509 != NULL) {
10214         key = (WOLFSSL_EVP_PKEY*)XMALLOC(
10215                     sizeof(WOLFSSL_EVP_PKEY), NULL, DYNAMIC_TYPE_PUBLIC_KEY);
10216         if (key != NULL) {
10217             key->type = x509->pubKeyOID;
10218             key->save_type = 0;
10219             key->pkey.ptr = (char*)XMALLOC(
10220                         x509->pubKey.length, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
10221             if (key->pkey.ptr == NULL) {
10222                 XFREE(key, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
10223                 return NULL;
10224             }
10225             XMEMCPY(key->pkey.ptr,
10226                                   x509->pubKey.buffer, x509->pubKey.length);
10227             key->pkey_sz = x509->pubKey.length;
10228             #ifdef HAVE_ECC
10229                 key->pkey_curve = (int)x509->pkCurveOID;
10230             #endif /* HAVE_ECC */
10231         }
10232     }
10233     return key;
10234 }
10235
10236
10237 int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
10238 {
10239     (void)crl;
10240     (void)key;
10241     return 0;
10242 }
10243
10244
10245 void wolfSSL_X509_STORE_CTX_set_error(WOLFSSL_X509_STORE_CTX* ctx, int err)
10246 {
10247     (void)ctx;
10248     (void)err;
10249 }
10250
10251
10252 void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj)
10253 {
10254     (void)obj;
10255 }
10256
10257
10258 void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key)
10259 {
10260     if (key != NULL) {
10261         if (key->pkey.ptr != NULL)
10262             XFREE(key->pkey.ptr, NULL, 0);
10263         XFREE(key, NULL, 0);
10264     }
10265 }
10266
10267
10268 int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME* asnTime)
10269 {
10270     (void)asnTime;
10271     return 0;
10272 }
10273
10274
10275 int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED* revoked)
10276 {
10277     (void)revoked;
10278     return 0;
10279 }
10280
10281
10282
10283 WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL* crl)
10284 {
10285     (void)crl;
10286     return 0;
10287 }
10288
10289
10290 WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(
10291                                     WOLFSSL_X509_REVOKED* revoked, int value)
10292 {
10293     (void)revoked;
10294     (void)value;
10295     return 0;
10296 }
10297
10298
10299
10300 WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
10301 {
10302     (void)x509;
10303     return 0;
10304 }
10305
10306
10307 int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime)
10308 {
10309     (void)bio;
10310     (void)asnTime;
10311     return 0;
10312 }
10313
10314
10315
10316 int wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER* a,
10317                             const WOLFSSL_ASN1_INTEGER* b)
10318 {
10319     (void)a;
10320     (void)b;
10321     return 0;
10322 }
10323
10324
10325 long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER* i)
10326 {
10327     (void)i;
10328     return 0;
10329 }
10330
10331
10332
10333 void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx)
10334 {
10335 #ifdef FORTRESS
10336     if (ctx != NULL && idx == 0)
10337         return ctx->ex_data;
10338 #else
10339     (void)ctx;
10340     (void)idx;
10341 #endif
10342     return 0;
10343 }
10344
10345
10346 int wolfSSL_get_ex_data_X509_STORE_CTX_idx(void)
10347 {
10348     return 0;
10349 }
10350
10351
10352 void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx)
10353 {
10354 #ifdef FORTRESS
10355     if (ssl != NULL && idx < MAX_EX_DATA)
10356         return ssl->ex_data[idx];
10357 #else
10358     (void)ssl;
10359     (void)idx;
10360 #endif
10361     return 0;
10362 }
10363
10364
10365 void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX* ctx, void (*f)(void))
10366 {
10367     (void)ctx;
10368     (void)f;
10369 }
10370
10371
10372 unsigned long wolfSSL_ERR_peek_error(void)
10373 {
10374     return 0;
10375 }
10376
10377
10378 int wolfSSL_ERR_GET_REASON(int err)
10379 {
10380     (void)err;
10381     return 0;
10382 }
10383
10384
10385 char* wolfSSL_alert_type_string_long(int alertID)
10386 {
10387     (void)alertID;
10388     return 0;
10389 }
10390
10391
10392 char* wolfSSL_alert_desc_string_long(int alertID)
10393 {
10394     (void)alertID;
10395     return 0;
10396 }
10397
10398
10399 char* wolfSSL_state_string_long(WOLFSSL* ssl)
10400 {
10401     (void)ssl;
10402     return 0;
10403 }
10404
10405
10406 int wolfSSL_PEM_def_callback(char* name, int num, int w, void* key)
10407 {
10408     (void)name;
10409     (void)num;
10410     (void)w;
10411     (void)key;
10412     return 0;
10413 }
10414
10415
10416 long wolfSSL_CTX_sess_accept(WOLFSSL_CTX* ctx)
10417 {
10418     (void)ctx;
10419     return 0;
10420 }
10421
10422
10423 long wolfSSL_CTX_sess_connect(WOLFSSL_CTX* ctx)
10424 {
10425     (void)ctx;
10426     return 0;
10427 }
10428
10429
10430 long wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX* ctx)
10431 {
10432     (void)ctx;
10433     return 0;
10434 }
10435
10436
10437 long wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX* ctx)
10438 {
10439     (void)ctx;
10440     return 0;
10441 }
10442
10443
10444 long wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX* ctx)
10445 {
10446     (void)ctx;
10447     return 0;
10448 }
10449
10450
10451 long wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX* ctx)
10452 {
10453     (void)ctx;
10454     return 0;
10455 }
10456
10457
10458 long wolfSSL_CTX_sess_hits(WOLFSSL_CTX* ctx)
10459 {
10460     (void)ctx;
10461     return 0;
10462 }
10463
10464
10465 long wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX* ctx)
10466 {
10467     (void)ctx;
10468     return 0;
10469 }
10470
10471
10472 long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX* ctx)
10473 {
10474     (void)ctx;
10475     return 0;
10476 }
10477
10478
10479 long wolfSSL_CTX_sess_misses(WOLFSSL_CTX* ctx)
10480 {
10481     (void)ctx;
10482     return 0;
10483 }
10484
10485
10486 long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX* ctx)
10487 {
10488     (void)ctx;
10489     return 0;
10490 }
10491
10492
10493 long wolfSSL_CTX_sess_number(WOLFSSL_CTX* ctx)
10494 {
10495     (void)ctx;
10496     return 0;
10497 }
10498
10499 #ifndef NO_DES3
10500
10501 void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock* myDes,
10502                                                WOLFSSL_DES_key_schedule* key)
10503 {
10504     (void)myDes;
10505     (void)key;
10506 }
10507
10508
10509 void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* myDes)
10510 {
10511     (void)myDes;
10512 }
10513
10514
10515 void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* desa,
10516              WOLFSSL_DES_cblock* desb, WOLFSSL_DES_key_schedule* key, int len)
10517 {
10518     (void)desa;
10519     (void)desb;
10520     (void)key;
10521     (void)len;
10522 }
10523
10524 #endif /* NO_DES3 */
10525
10526 int wolfSSL_BIO_printf(WOLFSSL_BIO* bio, const char* format, ...)
10527 {
10528     (void)bio;
10529     (void)format;
10530     return 0;
10531 }
10532
10533
10534 int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a)
10535 {
10536     (void)bio;
10537     (void)a;
10538     return 0;
10539 }
10540
10541
10542 int  wolfSSL_sk_num(WOLFSSL_X509_REVOKED* rev)
10543 {
10544     (void)rev;
10545     return 0;
10546 }
10547
10548
10549 void* wolfSSL_sk_value(WOLFSSL_X509_REVOKED* rev, int i)
10550 {
10551     (void)rev;
10552     (void)i;
10553     return 0;
10554 }
10555
10556
10557 /* stunnel 4.28 needs */
10558 void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int d)
10559 {
10560     (void)ctx;
10561     (void)d;
10562     return 0;
10563 }
10564
10565
10566 int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int d, void* p)
10567 {
10568     (void)ctx;
10569     (void)d;
10570     (void)p;
10571     return SSL_SUCCESS;
10572 }
10573
10574
10575 void wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX* ctx,
10576                     WOLFSSL_SESSION*(*f)(WOLFSSL*, unsigned char*, int, int*))
10577 {
10578     (void)ctx;
10579     (void)f;
10580 }
10581
10582
10583 void wolfSSL_CTX_sess_set_new_cb(WOLFSSL_CTX* ctx,
10584                              int (*f)(WOLFSSL*, WOLFSSL_SESSION*))
10585 {
10586     (void)ctx;
10587     (void)f;
10588 }
10589
10590
10591 void wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX* ctx, void (*f)(WOLFSSL_CTX*,
10592                                                         WOLFSSL_SESSION*))
10593 {
10594     (void)ctx;
10595     (void)f;
10596 }
10597
10598
10599 int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
10600 {
10601     (void)sess;
10602     (void)p;
10603     return sizeof(WOLFSSL_SESSION);
10604 }
10605
10606
10607 WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
10608                                 const unsigned char** p, long i)
10609 {
10610     (void)p;
10611     (void)i;
10612     if (sess)
10613         return *sess;
10614     return NULL;
10615 }
10616
10617
10618 long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION* sess)
10619 {
10620     WOLFSSL_ENTER("wolfSSL_SESSION_get_timeout");
10621     return sess->timeout;
10622 }
10623
10624
10625 long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION* sess)
10626 {
10627     WOLFSSL_ENTER("wolfSSL_SESSION_get_time");
10628     return sess->bornOn;
10629 }
10630
10631
10632 int wolfSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b,
10633                                 void* c)
10634 {
10635     (void)idx;
10636     (void)arg;
10637     (void)a;
10638     (void)b;
10639     (void)c;
10640     return 0;
10641 }
10642
10643 #endif /* OPENSSL_EXTRA */
10644
10645
10646 #ifdef KEEP_PEER_CERT
10647 char*  wolfSSL_X509_get_subjectCN(WOLFSSL_X509* x509)
10648 {
10649     if (x509 == NULL)
10650         return NULL;
10651
10652     return x509->subjectCN;
10653 }
10654 #endif /* KEEP_PEER_CERT */
10655
10656 #ifdef OPENSSL_EXTRA
10657
10658 #ifdef FORTRESS
10659 int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname)
10660 {
10661     int ret = SSL_FATAL_ERROR;
10662
10663     WOLFSSL_ENTER("wolfSSL_cmp_peer_cert_to_file");
10664     if (ssl != NULL && fname != NULL)
10665     {
10666     #ifdef WOLFSSL_SMALL_STACK
10667         EncryptedInfo* info = NULL;
10668         byte           staticBuffer[1]; /* force heap usage */
10669     #else
10670         EncryptedInfo  info[1];
10671         byte           staticBuffer[FILE_BUFFER_SIZE];
10672     #endif
10673         byte*          myBuffer  = staticBuffer;
10674         int            dynamic   = 0;
10675         XFILE          file      = XBADFILE;
10676         long           sz        = 0;
10677         int            eccKey    = 0;
10678         WOLFSSL_CTX*    ctx       = ssl->ctx;
10679         WOLFSSL_X509*   peer_cert = &ssl->peerCert;
10680         buffer         fileDer;
10681
10682         file = XFOPEN(fname, "rb");
10683         if (file == XBADFILE)
10684             return SSL_BAD_FILE;
10685
10686         XFSEEK(file, 0, XSEEK_END);
10687         sz = XFTELL(file);
10688         XREWIND(file);
10689
10690         if (sz > (long)sizeof(staticBuffer)) {
10691             WOLFSSL_MSG("Getting dynamic buffer");
10692             myBuffer = (byte*)XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
10693             dynamic = 1;
10694         }
10695
10696     #ifdef WOLFSSL_SMALL_STACK
10697         info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
10698                                                    DYNAMIC_TYPE_TMP_BUFFER);
10699         if (info == NULL)
10700             ret = MEMORY_E;
10701         else
10702     #endif
10703         {
10704             info->set = 0;
10705             info->ctx = ctx;
10706             info->consumed = 0;
10707             fileDer.buffer = 0;
10708
10709             if ((myBuffer != NULL) &&
10710                 (sz > 0) &&
10711                 (XFREAD(myBuffer, sz, 1, file) > 0) &&
10712                 (PemToDer(myBuffer, sz, CERT_TYPE,
10713                           &fileDer, ctx->heap, info, &eccKey) == 0) &&
10714                 (fileDer.length != 0) &&
10715                 (fileDer.length == peer_cert->derCert.length) &&
10716                 (XMEMCMP(peer_cert->derCert.buffer, fileDer.buffer,
10717                                                     fileDer.length) == 0))
10718             {
10719                 ret = 0;
10720             }
10721
10722         #ifdef WOLFSSL_SMALL_STACK
10723             XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10724         #endif
10725         }
10726
10727         XFREE(fileDer.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
10728         if (dynamic)
10729             XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
10730
10731         XFCLOSE(file);
10732     }
10733
10734     return ret;
10735 }
10736 #endif
10737
10738
10739 static RNG globalRNG;
10740 static int initGlobalRNG = 0;
10741
10742 /* SSL_SUCCESS on ok */
10743 int wolfSSL_RAND_seed(const void* seed, int len)
10744 {
10745
10746     WOLFSSL_MSG("wolfSSL_RAND_seed");
10747
10748     (void)seed;
10749     (void)len;
10750
10751     if (initGlobalRNG == 0) {
10752         if (wc_InitRng(&globalRNG) < 0) {
10753             WOLFSSL_MSG("wolfSSL Init Global RNG failed");
10754             return 0;
10755         }
10756         initGlobalRNG = 1;
10757     }
10758
10759     return SSL_SUCCESS;
10760 }
10761
10762
10763 /* SSL_SUCCESS on ok */
10764 int wolfSSL_RAND_bytes(unsigned char* buf, int num)
10765 {
10766     int    ret = 0;
10767     int    initTmpRng = 0;
10768     RNG*   rng = NULL;
10769 #ifdef WOLFSSL_SMALL_STACK
10770     RNG*   tmpRNG = NULL;
10771 #else
10772     RNG    tmpRNG[1];
10773 #endif
10774
10775     WOLFSSL_ENTER("RAND_bytes");
10776
10777 #ifdef WOLFSSL_SMALL_STACK
10778     tmpRNG = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
10779     if (tmpRNG == NULL)
10780         return ret;
10781 #endif
10782
10783     if (wc_InitRng(tmpRNG) == 0) {
10784         rng = tmpRNG;
10785         initTmpRng = 1;
10786     }
10787     else if (initGlobalRNG)
10788         rng = &globalRNG;
10789
10790     if (rng) {
10791         if (wc_RNG_GenerateBlock(rng, buf, num) != 0)
10792             WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
10793         else
10794             ret = SSL_SUCCESS;
10795     }
10796
10797     if (initTmpRng)
10798         wc_FreeRng(tmpRNG);
10799
10800 #ifdef WOLFSSL_SMALL_STACK
10801     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10802 #endif
10803
10804     return ret;
10805 }
10806
10807 WOLFSSL_BN_CTX* wolfSSL_BN_CTX_new(void)
10808 {
10809     static int ctx;  /* wolfcrypt doesn't now need ctx */
10810
10811     WOLFSSL_MSG("wolfSSL_BN_CTX_new");
10812
10813     return (WOLFSSL_BN_CTX*)&ctx;
10814 }
10815
10816 void wolfSSL_BN_CTX_init(WOLFSSL_BN_CTX* ctx)
10817 {
10818     (void)ctx;
10819     WOLFSSL_MSG("wolfSSL_BN_CTX_init");
10820 }
10821
10822
10823 void wolfSSL_BN_CTX_free(WOLFSSL_BN_CTX* ctx)
10824 {
10825     (void)ctx;
10826     WOLFSSL_MSG("wolfSSL_BN_CTX_free");
10827
10828     /* do free since static ctx that does nothing */
10829 }
10830
10831
10832 static void InitwolfSSL_BigNum(WOLFSSL_BIGNUM* bn)
10833 {
10834     WOLFSSL_MSG("InitwolfSSL_BigNum");
10835     if (bn) {
10836         bn->neg      = 0;
10837         bn->internal = NULL;
10838     }
10839 }
10840
10841
10842 WOLFSSL_BIGNUM* wolfSSL_BN_new(void)
10843 {
10844     WOLFSSL_BIGNUM* external;
10845     mp_int*        mpi;
10846
10847     WOLFSSL_MSG("wolfSSL_BN_new");
10848
10849     mpi = (mp_int*) XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10850     if (mpi == NULL) {
10851         WOLFSSL_MSG("wolfSSL_BN_new malloc mpi failure");
10852         return NULL;
10853     }
10854
10855     external = (WOLFSSL_BIGNUM*) XMALLOC(sizeof(WOLFSSL_BIGNUM), NULL,
10856                                         DYNAMIC_TYPE_BIGINT);
10857     if (external == NULL) {
10858         WOLFSSL_MSG("wolfSSL_BN_new malloc WOLFSSL_BIGNUM failure");
10859         XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
10860         return NULL;
10861     }
10862
10863     InitwolfSSL_BigNum(external);
10864     external->internal = mpi;
10865     if (mp_init(mpi) != MP_OKAY) {
10866         wolfSSL_BN_free(external);
10867         return NULL;
10868     }
10869
10870     return external;
10871 }
10872
10873
10874 void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn)
10875 {
10876     WOLFSSL_MSG("wolfSSL_BN_free");
10877     if (bn) {
10878         if (bn->internal) {
10879             mp_clear((mp_int*)bn->internal);
10880             XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT);
10881             bn->internal = NULL;
10882         }
10883         XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT);
10884     }
10885 }
10886
10887
10888 void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM* bn)
10889 {
10890     WOLFSSL_MSG("wolfSSL_BN_clear_free");
10891
10892     wolfSSL_BN_free(bn);
10893 }
10894
10895
10896 /* SSL_SUCCESS on ok */
10897 int wolfSSL_BN_sub(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
10898                   const WOLFSSL_BIGNUM* b)
10899 {
10900     WOLFSSL_MSG("wolfSSL_BN_sub");
10901
10902     if (r == NULL || a == NULL || b == NULL)
10903         return 0;
10904
10905     if (mp_sub((mp_int*)a->internal,(mp_int*)b->internal,
10906                (mp_int*)r->internal) == MP_OKAY)
10907         return SSL_SUCCESS;
10908
10909     WOLFSSL_MSG("wolfSSL_BN_sub mp_sub failed");
10910     return 0;
10911 }
10912
10913
10914 /* SSL_SUCCESS on ok */
10915 int wolfSSL_BN_mod(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
10916                   const WOLFSSL_BIGNUM* b, const WOLFSSL_BN_CTX* c)
10917 {
10918     (void)c;
10919     WOLFSSL_MSG("wolfSSL_BN_mod");
10920
10921     if (r == NULL || a == NULL || b == NULL)
10922         return 0;
10923
10924     if (mp_mod((mp_int*)a->internal,(mp_int*)b->internal,
10925                (mp_int*)r->internal) == MP_OKAY)
10926         return SSL_SUCCESS;
10927
10928     WOLFSSL_MSG("wolfSSL_BN_mod mp_mod failed");
10929     return 0;
10930 }
10931
10932
10933 const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void)
10934 {
10935     static WOLFSSL_BIGNUM* bn_one = NULL;
10936
10937     WOLFSSL_MSG("wolfSSL_BN_value_one");
10938
10939     if (bn_one == NULL) {
10940         bn_one = wolfSSL_BN_new();
10941         if (bn_one)
10942             mp_set_int((mp_int*)bn_one->internal, 1);
10943     }
10944
10945     return bn_one;
10946 }
10947
10948
10949 int wolfSSL_BN_num_bytes(const WOLFSSL_BIGNUM* bn)
10950 {
10951     WOLFSSL_MSG("wolfSSL_BN_num_bytes");
10952
10953     if (bn == NULL || bn->internal == NULL)
10954         return 0;
10955
10956     return mp_unsigned_bin_size((mp_int*)bn->internal);
10957 }
10958
10959
10960 int wolfSSL_BN_num_bits(const WOLFSSL_BIGNUM* bn)
10961 {
10962     WOLFSSL_MSG("wolfSSL_BN_num_bits");
10963
10964     if (bn == NULL || bn->internal == NULL)
10965         return 0;
10966
10967     return mp_count_bits((mp_int*)bn->internal);
10968 }
10969
10970
10971 int wolfSSL_BN_is_zero(const WOLFSSL_BIGNUM* bn)
10972 {
10973     WOLFSSL_MSG("wolfSSL_BN_is_zero");
10974
10975     if (bn == NULL || bn->internal == NULL)
10976         return 0;
10977
10978     return mp_iszero((mp_int*)bn->internal);
10979 }
10980
10981
10982 int wolfSSL_BN_is_one(const WOLFSSL_BIGNUM* bn)
10983 {
10984     WOLFSSL_MSG("wolfSSL_BN_is_one");
10985
10986     if (bn == NULL || bn->internal == NULL)
10987         return 0;
10988
10989     if (mp_cmp_d((mp_int*)bn->internal, 1) == 0)
10990         return 1;
10991
10992     return 0;
10993 }
10994
10995
10996 int wolfSSL_BN_is_odd(const WOLFSSL_BIGNUM* bn)
10997 {
10998     WOLFSSL_MSG("wolfSSL_BN_is_odd");
10999
11000     if (bn == NULL || bn->internal == NULL)
11001         return 0;
11002
11003     return mp_isodd((mp_int*)bn->internal);
11004 }
11005
11006
11007 int wolfSSL_BN_cmp(const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b)
11008 {
11009     WOLFSSL_MSG("wolfSSL_BN_cmp");
11010
11011     if (a == NULL || a->internal == NULL || b == NULL || b->internal ==NULL)
11012         return 0;
11013
11014     return mp_cmp((mp_int*)a->internal, (mp_int*)b->internal);
11015 }
11016
11017
11018 int wolfSSL_BN_bn2bin(const WOLFSSL_BIGNUM* bn, unsigned char* r)
11019 {
11020     WOLFSSL_MSG("wolfSSL_BN_bn2bin");
11021
11022     if (bn == NULL || bn->internal == NULL) {
11023         WOLFSSL_MSG("NULL bn error");
11024         return SSL_FATAL_ERROR;
11025     }
11026
11027     if (r == NULL)
11028         return mp_unsigned_bin_size((mp_int*)bn->internal);
11029
11030     if (mp_to_unsigned_bin((mp_int*)bn->internal, r) != MP_OKAY) {
11031         WOLFSSL_MSG("mp_to_unsigned_bin error");
11032         return SSL_FATAL_ERROR;
11033     }
11034
11035     return mp_unsigned_bin_size((mp_int*)bn->internal);
11036 }
11037
11038
11039 WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char* str, int len,
11040                             WOLFSSL_BIGNUM* ret)
11041 {
11042     WOLFSSL_MSG("wolfSSL_BN_bin2bn");
11043
11044     if (ret && ret->internal) {
11045         if (mp_read_unsigned_bin((mp_int*)ret->internal, str, len) != 0) {
11046             WOLFSSL_MSG("mp_read_unsigned_bin failure");
11047             return NULL;
11048         }
11049     }
11050     else {
11051         WOLFSSL_MSG("wolfSSL_BN_bin2bn wants return bignum");
11052     }
11053
11054     return ret;
11055 }
11056
11057
11058 int wolfSSL_mask_bits(WOLFSSL_BIGNUM* bn, int n)
11059 {
11060     (void)bn;
11061     (void)n;
11062     WOLFSSL_MSG("wolfSSL_BN_mask_bits");
11063
11064     return SSL_FATAL_ERROR;
11065 }
11066
11067
11068 /* SSL_SUCCESS on ok */
11069 int wolfSSL_BN_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
11070 {
11071     int           ret    = 0;
11072     int           len    = bits / 8;
11073     int           initTmpRng = 0;
11074     RNG*          rng    = NULL;
11075 #ifdef WOLFSSL_SMALL_STACK
11076     RNG*          tmpRNG = NULL;
11077     byte*         buff   = NULL;
11078 #else
11079     RNG           tmpRNG[1];
11080     byte          buff[1024];
11081 #endif
11082
11083     (void)top;
11084     (void)bottom;
11085     WOLFSSL_MSG("wolfSSL_BN_rand");
11086
11087     if (bits % 8)
11088         len++;
11089
11090 #ifdef WOLFSSL_SMALL_STACK
11091     buff   = (byte*)XMALLOC(1024,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
11092     tmpRNG = (RNG*) XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
11093     if (buff == NULL || tmpRNG == NULL) {
11094         XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
11095         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11096         return ret;
11097     }
11098 #endif
11099
11100     if (bn == NULL || bn->internal == NULL)
11101         WOLFSSL_MSG("Bad function arguments");
11102     else if (wc_InitRng(tmpRNG) == 0) {
11103         rng = tmpRNG;
11104         initTmpRng = 1;
11105     }
11106     else if (initGlobalRNG)
11107         rng = &globalRNG;
11108
11109     if (rng) {
11110         if (wc_RNG_GenerateBlock(rng, buff, len) != 0)
11111             WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
11112         else {
11113             buff[0]     |= 0x80 | 0x40;
11114             buff[len-1] |= 0x01;
11115
11116             if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY)
11117                 WOLFSSL_MSG("mp read bin failed");
11118             else
11119                 ret = SSL_SUCCESS;
11120         }
11121     }
11122
11123     if (initTmpRng)
11124         wc_FreeRng(tmpRNG);
11125
11126 #ifdef WOLFSSL_SMALL_STACK
11127     XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
11128     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11129 #endif
11130
11131     return ret;
11132 }
11133
11134
11135 int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM* bn, int n)
11136 {
11137     (void)bn;
11138     (void)n;
11139
11140     WOLFSSL_MSG("wolfSSL_BN_is_bit_set");
11141
11142     return 0;
11143 }
11144
11145
11146 /* SSL_SUCCESS on ok */
11147 int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str)
11148 {
11149     int     ret     = 0;
11150     word32  decSz   = 1024;
11151 #ifdef WOLFSSL_SMALL_STACK
11152     byte*   decoded = NULL;
11153 #else
11154     byte    decoded[1024];
11155 #endif
11156
11157     WOLFSSL_MSG("wolfSSL_BN_hex2bn");
11158
11159 #ifdef WOLFSSL_SMALL_STACK
11160     decoded = (byte*)XMALLOC(decSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11161     if (decoded == NULL)
11162         return ret;
11163 #endif
11164
11165     if (str == NULL)
11166         WOLFSSL_MSG("Bad function argument");
11167     else if (Base16_Decode((byte*)str, (int)XSTRLEN(str), decoded, &decSz) < 0)
11168         WOLFSSL_MSG("Bad Base16_Decode error");
11169     else if (bn == NULL)
11170         ret = decSz;
11171     else {
11172         if (*bn == NULL)
11173             *bn = wolfSSL_BN_new();
11174
11175         if (*bn == NULL)
11176             WOLFSSL_MSG("BN new failed");
11177         else if (wolfSSL_BN_bin2bn(decoded, decSz, *bn) == NULL)
11178             WOLFSSL_MSG("Bad bin2bn error");
11179         else
11180             ret = SSL_SUCCESS;
11181     }
11182
11183 #ifdef WOLFSSL_SMALL_STACK
11184     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11185 #endif
11186
11187     return ret;
11188 }
11189
11190
11191 WOLFSSL_BIGNUM* wolfSSL_BN_dup(const WOLFSSL_BIGNUM* bn)
11192 {
11193     WOLFSSL_BIGNUM* ret;
11194
11195     WOLFSSL_MSG("wolfSSL_BN_dup");
11196
11197     if (bn == NULL || bn->internal == NULL) {
11198         WOLFSSL_MSG("bn NULL error");
11199         return NULL;
11200     }
11201
11202     ret = wolfSSL_BN_new();
11203     if (ret == NULL) {
11204         WOLFSSL_MSG("bn new error");
11205         return NULL;
11206     }
11207
11208     if (mp_copy((mp_int*)bn->internal, (mp_int*)ret->internal) != MP_OKAY) {
11209         WOLFSSL_MSG("mp_copy error");
11210         wolfSSL_BN_free(ret);
11211         return NULL;
11212     }
11213
11214     return ret;
11215 }
11216
11217
11218 WOLFSSL_BIGNUM* wolfSSL_BN_copy(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* bn)
11219 {
11220     (void)r;
11221     (void)bn;
11222
11223     WOLFSSL_MSG("wolfSSL_BN_copy");
11224
11225     return NULL;
11226 }
11227
11228
11229 int wolfSSL_BN_set_word(WOLFSSL_BIGNUM* bn, unsigned long w)
11230 {
11231     (void)bn;
11232     (void)w;
11233
11234     WOLFSSL_MSG("wolfSSL_BN_set_word");
11235
11236     return SSL_FATAL_ERROR;
11237 }
11238
11239
11240 int wolfSSL_BN_dec2bn(WOLFSSL_BIGNUM** bn, const char* str)
11241 {
11242     (void)bn;
11243     (void)str;
11244
11245     WOLFSSL_MSG("wolfSSL_BN_dec2bn");
11246
11247     return SSL_FATAL_ERROR;
11248 }
11249
11250
11251 char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM* bn)
11252 {
11253     (void)bn;
11254
11255     WOLFSSL_MSG("wolfSSL_BN_bn2dec");
11256
11257     return NULL;
11258 }
11259
11260
11261 #ifndef NO_DH
11262
11263 static void InitwolfSSL_DH(WOLFSSL_DH* dh)
11264 {
11265     if (dh) {
11266         dh->p        = NULL;
11267         dh->g        = NULL;
11268         dh->pub_key  = NULL;
11269         dh->priv_key = NULL;
11270         dh->internal = NULL;
11271         dh->inSet    = 0;
11272         dh->exSet    = 0;
11273     }
11274 }
11275
11276
11277 WOLFSSL_DH* wolfSSL_DH_new(void)
11278 {
11279     WOLFSSL_DH* external;
11280     DhKey*     key;
11281
11282     WOLFSSL_MSG("wolfSSL_DH_new");
11283
11284     key = (DhKey*) XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
11285     if (key == NULL) {
11286         WOLFSSL_MSG("wolfSSL_DH_new malloc DhKey failure");
11287         return NULL;
11288     }
11289
11290     external = (WOLFSSL_DH*) XMALLOC(sizeof(WOLFSSL_DH), NULL,
11291                                     DYNAMIC_TYPE_DH);
11292     if (external == NULL) {
11293         WOLFSSL_MSG("wolfSSL_DH_new malloc WOLFSSL_DH failure");
11294         XFREE(key, NULL, DYNAMIC_TYPE_DH);
11295         return NULL;
11296     }
11297
11298     InitwolfSSL_DH(external);
11299     wc_InitDhKey(key);
11300     external->internal = key;
11301
11302     return external;
11303 }
11304
11305
11306 void wolfSSL_DH_free(WOLFSSL_DH* dh)
11307 {
11308     WOLFSSL_MSG("wolfSSL_DH_free");
11309
11310     if (dh) {
11311         if (dh->internal) {
11312             wc_FreeDhKey((DhKey*)dh->internal);
11313             XFREE(dh->internal, NULL, DYNAMIC_TYPE_DH);
11314             dh->internal = NULL;
11315         }
11316         wolfSSL_BN_free(dh->priv_key);
11317         wolfSSL_BN_free(dh->pub_key);
11318         wolfSSL_BN_free(dh->g);
11319         wolfSSL_BN_free(dh->p);
11320         InitwolfSSL_DH(dh);  /* set back to NULLs for safety */
11321
11322         XFREE(dh, NULL, DYNAMIC_TYPE_DH);
11323     }
11324 }
11325
11326
11327 static int SetDhInternal(WOLFSSL_DH* dh)
11328 {
11329     int            ret = SSL_FATAL_ERROR;
11330     int            pSz = 1024;
11331     int            gSz = 1024;
11332 #ifdef WOLFSSL_SMALL_STACK
11333     unsigned char* p   = NULL;
11334     unsigned char* g   = NULL;
11335 #else
11336     unsigned char  p[1024];
11337     unsigned char  g[1024];
11338 #endif
11339
11340     WOLFSSL_ENTER("SetDhInternal");
11341
11342     if (dh == NULL || dh->p == NULL || dh->g == NULL)
11343         WOLFSSL_MSG("Bad function arguments");
11344     else if (wolfSSL_BN_bn2bin(dh->p, NULL) > pSz)
11345         WOLFSSL_MSG("Bad p internal size");
11346     else if (wolfSSL_BN_bn2bin(dh->g, NULL) > gSz)
11347         WOLFSSL_MSG("Bad g internal size");
11348     else {
11349     #ifdef WOLFSSL_SMALL_STACK
11350         p = (unsigned char*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11351         g = (unsigned char*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11352
11353         if (p == NULL || g == NULL) {
11354             XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11355             XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11356             return ret;
11357         }
11358     #endif
11359
11360         pSz = wolfSSL_BN_bn2bin(dh->p, p);
11361         gSz = wolfSSL_BN_bn2bin(dh->g, g);
11362
11363         if (pSz <= 0 || gSz <= 0)
11364             WOLFSSL_MSG("Bad BN2bin set");
11365         else if (wc_DhSetKey((DhKey*)dh->internal, p, pSz, g, gSz) < 0)
11366             WOLFSSL_MSG("Bad DH SetKey");
11367         else {
11368             dh->inSet = 1;
11369             ret = 0;
11370         }
11371
11372     #ifdef WOLFSSL_SMALL_STACK
11373         XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11374         XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11375     #endif
11376     }
11377
11378
11379     return ret;
11380 }
11381
11382
11383 int wolfSSL_DH_size(WOLFSSL_DH* dh)
11384 {
11385     WOLFSSL_MSG("wolfSSL_DH_size");
11386
11387     if (dh == NULL)
11388         return 0;
11389
11390     return wolfSSL_BN_num_bytes(dh->p);
11391 }
11392
11393
11394 /* return SSL_SUCCESS on ok, else 0 */
11395 int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
11396 {
11397     int            ret    = 0;
11398     word32         pubSz  = 768;
11399     word32         privSz = 768;
11400     int            initTmpRng = 0;
11401     RNG*           rng    = NULL;
11402 #ifdef WOLFSSL_SMALL_STACK
11403     unsigned char* pub    = NULL;
11404     unsigned char* priv   = NULL;
11405     RNG*           tmpRNG = NULL;
11406 #else
11407     unsigned char  pub [768];
11408     unsigned char  priv[768];
11409     RNG            tmpRNG[1];
11410 #endif
11411
11412     WOLFSSL_MSG("wolfSSL_DH_generate_key");
11413
11414 #ifdef WOLFSSL_SMALL_STACK
11415     tmpRNG = (RNG*)XMALLOC(sizeof(RNG),      NULL, DYNAMIC_TYPE_TMP_BUFFER);
11416     pub    = (unsigned char*)XMALLOC(pubSz,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
11417     priv   = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11418
11419     if (tmpRNG == NULL || pub == NULL || priv == NULL) {
11420         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11421         XFREE(pub,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
11422         XFREE(priv,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
11423         return ret;
11424     }
11425 #endif
11426
11427     if (dh == NULL || dh->p == NULL || dh->g == NULL)
11428         WOLFSSL_MSG("Bad function arguments");
11429     else if (dh->inSet == 0 && SetDhInternal(dh) < 0)
11430             WOLFSSL_MSG("Bad DH set internal");
11431     else if (wc_InitRng(tmpRNG) == 0) {
11432         rng = tmpRNG;
11433         initTmpRng = 1;
11434     }
11435     else {
11436         WOLFSSL_MSG("Bad RNG Init, trying global");
11437         if (initGlobalRNG == 0)
11438             WOLFSSL_MSG("Global RNG no Init");
11439         else
11440             rng = &globalRNG;
11441     }
11442
11443     if (rng) {
11444        if (wc_DhGenerateKeyPair((DhKey*)dh->internal, rng, priv, &privSz,
11445                                                                pub, &pubSz) < 0)
11446             WOLFSSL_MSG("Bad wc_DhGenerateKeyPair");
11447        else {
11448             if (dh->pub_key)
11449                 wolfSSL_BN_free(dh->pub_key);
11450    
11451             dh->pub_key = wolfSSL_BN_new();
11452             if (dh->pub_key == NULL) {
11453                 WOLFSSL_MSG("Bad DH new pub");
11454             }
11455             if (dh->priv_key)
11456                 wolfSSL_BN_free(dh->priv_key);
11457
11458             dh->priv_key = wolfSSL_BN_new();
11459
11460             if (dh->priv_key == NULL) {
11461                 WOLFSSL_MSG("Bad DH new priv");
11462             }
11463
11464             if (dh->pub_key && dh->priv_key) {
11465                if (wolfSSL_BN_bin2bn(pub, pubSz, dh->pub_key) == NULL)
11466                    WOLFSSL_MSG("Bad DH bn2bin error pub");
11467                else if (wolfSSL_BN_bin2bn(priv, privSz, dh->priv_key) == NULL)
11468                    WOLFSSL_MSG("Bad DH bn2bin error priv");
11469                else
11470                    ret = SSL_SUCCESS;
11471             }
11472         }
11473     }
11474
11475     if (initTmpRng)
11476         wc_FreeRng(tmpRNG);
11477
11478 #ifdef WOLFSSL_SMALL_STACK
11479     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11480     XFREE(pub,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
11481     XFREE(priv,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
11482 #endif
11483
11484     return ret;
11485 }
11486
11487
11488 /* return key size on ok, 0 otherwise */
11489 int wolfSSL_DH_compute_key(unsigned char* key, WOLFSSL_BIGNUM* otherPub,
11490                           WOLFSSL_DH* dh)
11491 {
11492     int            ret    = 0;
11493     word32         keySz  = 0;
11494     word32         pubSz  = 1024;
11495     word32         privSz = 1024;
11496 #ifdef WOLFSSL_SMALL_STACK
11497     unsigned char* pub    = NULL;
11498     unsigned char* priv   = NULL;
11499 #else
11500     unsigned char  pub [1024];
11501     unsigned char  priv[1024];
11502 #endif
11503
11504     WOLFSSL_MSG("wolfSSL_DH_compute_key");
11505
11506 #ifdef WOLFSSL_SMALL_STACK
11507     pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11508     if (pub == NULL)
11509         return ret;
11510
11511     priv = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11512     if (priv == NULL) {
11513         XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11514         return 0;
11515     }
11516 #endif
11517
11518     if (dh == NULL || dh->priv_key == NULL || otherPub == NULL)
11519         WOLFSSL_MSG("Bad function arguments");
11520     else if ((keySz = (word32)DH_size(dh)) == 0)
11521         WOLFSSL_MSG("Bad DH_size");
11522     else if (wolfSSL_BN_bn2bin(dh->priv_key, NULL) > (int)privSz)
11523         WOLFSSL_MSG("Bad priv internal size");
11524     else if (wolfSSL_BN_bn2bin(otherPub, NULL) > (int)pubSz)
11525         WOLFSSL_MSG("Bad otherPub size");
11526     else {
11527         privSz = wolfSSL_BN_bn2bin(dh->priv_key, priv);
11528         pubSz  = wolfSSL_BN_bn2bin(otherPub, pub);
11529
11530         if (privSz <= 0 || pubSz <= 0)
11531             WOLFSSL_MSG("Bad BN2bin set");
11532         else if (wc_DhAgree((DhKey*)dh->internal, key, &keySz, priv, privSz, pub,
11533                                                                      pubSz) < 0)
11534             WOLFSSL_MSG("wc_DhAgree failed");
11535         else
11536             ret = (int)keySz;
11537     }
11538
11539 #ifdef WOLFSSL_SMALL_STACK
11540     XFREE(pub,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
11541     XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11542 #endif
11543
11544     return ret;
11545 }
11546 #endif /* NO_DH */
11547
11548
11549 #ifndef NO_DSA
11550 static void InitwolfSSL_DSA(WOLFSSL_DSA* dsa)
11551 {
11552     if (dsa) {
11553         dsa->p        = NULL;
11554         dsa->q        = NULL;
11555         dsa->g        = NULL;
11556         dsa->pub_key  = NULL;
11557         dsa->priv_key = NULL;
11558         dsa->internal = NULL;
11559         dsa->inSet    = 0;
11560         dsa->exSet    = 0;
11561     }
11562 }
11563
11564
11565 WOLFSSL_DSA* wolfSSL_DSA_new(void)
11566 {
11567     WOLFSSL_DSA* external;
11568     DsaKey*     key;
11569
11570     WOLFSSL_MSG("wolfSSL_DSA_new");
11571
11572     key = (DsaKey*) XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
11573     if (key == NULL) {
11574         WOLFSSL_MSG("wolfSSL_DSA_new malloc DsaKey failure");
11575         return NULL;
11576     }
11577
11578     external = (WOLFSSL_DSA*) XMALLOC(sizeof(WOLFSSL_DSA), NULL,
11579                                     DYNAMIC_TYPE_DSA);
11580     if (external == NULL) {
11581         WOLFSSL_MSG("wolfSSL_DSA_new malloc WOLFSSL_DSA failure");
11582         XFREE(key, NULL, DYNAMIC_TYPE_DSA);
11583         return NULL;
11584     }
11585
11586     InitwolfSSL_DSA(external);
11587     InitDsaKey(key);
11588     external->internal = key;
11589
11590     return external;
11591 }
11592
11593
11594 void wolfSSL_DSA_free(WOLFSSL_DSA* dsa)
11595 {
11596     WOLFSSL_MSG("wolfSSL_DSA_free");
11597
11598     if (dsa) {
11599         if (dsa->internal) {
11600             FreeDsaKey((DsaKey*)dsa->internal);
11601             XFREE(dsa->internal, NULL, DYNAMIC_TYPE_DSA);
11602             dsa->internal = NULL;
11603         }
11604         wolfSSL_BN_free(dsa->priv_key);
11605         wolfSSL_BN_free(dsa->pub_key);
11606         wolfSSL_BN_free(dsa->g);
11607         wolfSSL_BN_free(dsa->q);
11608         wolfSSL_BN_free(dsa->p);
11609         InitwolfSSL_DSA(dsa);  /* set back to NULLs for safety */
11610
11611         XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
11612     }
11613 }
11614
11615
11616 int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa)
11617 {
11618     (void)dsa;
11619
11620     WOLFSSL_MSG("wolfSSL_DSA_generate_key");
11621
11622     return 0;  /* key gen not needed by server */
11623 }
11624
11625
11626 int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits,
11627                unsigned char* seed, int seedLen, int* counterRet,
11628                unsigned long* hRet, void* cb)
11629 {
11630     (void)dsa;
11631     (void)bits;
11632     (void)seed;
11633     (void)seedLen;
11634     (void)counterRet;
11635     (void)hRet;
11636     (void)cb;
11637
11638     WOLFSSL_MSG("wolfSSL_DSA_generate_parameters_ex");
11639
11640     return 0;  /* key gen not needed by server */
11641 }
11642 #endif /* NO_DSA */
11643
11644 #ifndef NO_RSA
11645 static void InitwolfSSL_Rsa(WOLFSSL_RSA* rsa)
11646 {
11647     if (rsa) {
11648         rsa->n        = NULL;
11649         rsa->e        = NULL;
11650         rsa->d        = NULL;
11651         rsa->p        = NULL;
11652         rsa->q        = NULL;
11653         rsa->dmp1     = NULL;
11654         rsa->dmq1     = NULL;
11655         rsa->iqmp     = NULL;
11656         rsa->internal = NULL;
11657         rsa->inSet    = 0;
11658         rsa->exSet    = 0;
11659     }
11660 }
11661
11662
11663 WOLFSSL_RSA* wolfSSL_RSA_new(void)
11664 {
11665     WOLFSSL_RSA* external;
11666     RsaKey*     key;
11667
11668     WOLFSSL_MSG("wolfSSL_RSA_new");
11669
11670     key = (RsaKey*) XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
11671     if (key == NULL) {
11672         WOLFSSL_MSG("wolfSSL_RSA_new malloc RsaKey failure");
11673         return NULL;
11674     }
11675
11676     external = (WOLFSSL_RSA*) XMALLOC(sizeof(WOLFSSL_RSA), NULL,
11677                                      DYNAMIC_TYPE_RSA);
11678     if (external == NULL) {
11679         WOLFSSL_MSG("wolfSSL_RSA_new malloc WOLFSSL_RSA failure");
11680         XFREE(key, NULL, DYNAMIC_TYPE_RSA);
11681         return NULL;
11682     }
11683
11684     InitwolfSSL_Rsa(external);
11685     if (wc_InitRsaKey(key, NULL) != 0) {
11686         WOLFSSL_MSG("InitRsaKey WOLFSSL_RSA failure");
11687         XFREE(external, NULL, DYNAMIC_TYPE_RSA);
11688         XFREE(key, NULL, DYNAMIC_TYPE_RSA);
11689         return NULL;
11690     }
11691     external->internal = key;
11692
11693     return external;
11694 }
11695
11696
11697 void wolfSSL_RSA_free(WOLFSSL_RSA* rsa)
11698 {
11699     WOLFSSL_MSG("wolfSSL_RSA_free");
11700
11701     if (rsa) {
11702         if (rsa->internal) {
11703             wc_FreeRsaKey((RsaKey*)rsa->internal);
11704             XFREE(rsa->internal, NULL, DYNAMIC_TYPE_RSA);
11705             rsa->internal = NULL;
11706         }
11707         wolfSSL_BN_free(rsa->iqmp);
11708         wolfSSL_BN_free(rsa->dmq1);
11709         wolfSSL_BN_free(rsa->dmp1);
11710         wolfSSL_BN_free(rsa->q);
11711         wolfSSL_BN_free(rsa->p);
11712         wolfSSL_BN_free(rsa->d);
11713         wolfSSL_BN_free(rsa->e);
11714         wolfSSL_BN_free(rsa->n);
11715         InitwolfSSL_Rsa(rsa);  /* set back to NULLs for safety */
11716
11717         XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
11718     }
11719 }
11720 #endif /* NO_RSA */
11721
11722
11723 #if !defined(NO_RSA) || !defined(NO_DSA)
11724 static int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi)
11725 {
11726     WOLFSSL_MSG("Entering SetIndividualExternal");
11727
11728     if (mpi == NULL) {
11729         WOLFSSL_MSG("mpi NULL error");
11730         return SSL_FATAL_ERROR;
11731     }
11732
11733     if (*bn == NULL) {
11734         *bn = wolfSSL_BN_new();
11735         if (*bn == NULL) {
11736             WOLFSSL_MSG("SetIndividualExternal alloc failed");
11737             return SSL_FATAL_ERROR;
11738         }
11739     }
11740
11741     if (mp_copy(mpi, (mp_int*)((*bn)->internal)) != MP_OKAY) {
11742         WOLFSSL_MSG("mp_copy error");
11743         return SSL_FATAL_ERROR;
11744     }
11745
11746     return 0;
11747 }
11748 #endif /* !NO_RSA && !NO_DSA */
11749
11750
11751 #ifndef NO_DSA
11752 static int SetDsaExternal(WOLFSSL_DSA* dsa)
11753 {
11754     DsaKey* key;
11755     WOLFSSL_MSG("Entering SetDsaExternal");
11756
11757     if (dsa == NULL || dsa->internal == NULL) {
11758         WOLFSSL_MSG("dsa key NULL error");
11759         return SSL_FATAL_ERROR;
11760     }
11761
11762     key = (DsaKey*)dsa->internal;
11763
11764     if (SetIndividualExternal(&dsa->p, &key->p) < 0) {
11765         WOLFSSL_MSG("dsa p key error");
11766         return SSL_FATAL_ERROR;
11767     }
11768
11769     if (SetIndividualExternal(&dsa->q, &key->q) < 0) {
11770         WOLFSSL_MSG("dsa q key error");
11771         return SSL_FATAL_ERROR;
11772     }
11773
11774     if (SetIndividualExternal(&dsa->g, &key->g) < 0) {
11775         WOLFSSL_MSG("dsa g key error");
11776         return SSL_FATAL_ERROR;
11777     }
11778
11779     if (SetIndividualExternal(&dsa->pub_key, &key->y) < 0) {
11780         WOLFSSL_MSG("dsa y key error");
11781         return SSL_FATAL_ERROR;
11782     }
11783
11784     if (SetIndividualExternal(&dsa->priv_key, &key->x) < 0) {
11785         WOLFSSL_MSG("dsa x key error");
11786         return SSL_FATAL_ERROR;
11787     }
11788
11789     dsa->exSet = 1;
11790
11791     return 0;
11792 }
11793 #endif /* NO_DSA */
11794
11795
11796 #ifndef NO_RSA
11797 static int SetRsaExternal(WOLFSSL_RSA* rsa)
11798 {
11799     RsaKey* key;
11800     WOLFSSL_MSG("Entering SetRsaExternal");
11801
11802     if (rsa == NULL || rsa->internal == NULL) {
11803         WOLFSSL_MSG("rsa key NULL error");
11804         return SSL_FATAL_ERROR;
11805     }
11806
11807     key = (RsaKey*)rsa->internal;
11808
11809     if (SetIndividualExternal(&rsa->n, &key->n) < 0) {
11810         WOLFSSL_MSG("rsa n key error");
11811         return SSL_FATAL_ERROR;
11812     }
11813
11814     if (SetIndividualExternal(&rsa->e, &key->e) < 0) {
11815         WOLFSSL_MSG("rsa e key error");
11816         return SSL_FATAL_ERROR;
11817     }
11818
11819     if (SetIndividualExternal(&rsa->d, &key->d) < 0) {
11820         WOLFSSL_MSG("rsa d key error");
11821         return SSL_FATAL_ERROR;
11822     }
11823
11824     if (SetIndividualExternal(&rsa->p, &key->p) < 0) {
11825         WOLFSSL_MSG("rsa p key error");
11826         return SSL_FATAL_ERROR;
11827     }
11828
11829     if (SetIndividualExternal(&rsa->q, &key->q) < 0) {
11830         WOLFSSL_MSG("rsa q key error");
11831         return SSL_FATAL_ERROR;
11832     }
11833
11834     if (SetIndividualExternal(&rsa->dmp1, &key->dP) < 0) {
11835         WOLFSSL_MSG("rsa dP key error");
11836         return SSL_FATAL_ERROR;
11837     }
11838
11839     if (SetIndividualExternal(&rsa->dmq1, &key->dQ) < 0) {
11840         WOLFSSL_MSG("rsa dQ key error");
11841         return SSL_FATAL_ERROR;
11842     }
11843
11844     if (SetIndividualExternal(&rsa->iqmp, &key->u) < 0) {
11845         WOLFSSL_MSG("rsa u key error");
11846         return SSL_FATAL_ERROR;
11847     }
11848
11849     rsa->exSet = 1;
11850
11851     return 0;
11852 }
11853
11854
11855 /* SSL_SUCCESS on ok */
11856 int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* bn,
11857                                void* cb)
11858 {
11859     int ret = SSL_FATAL_ERROR;
11860
11861     WOLFSSL_MSG("wolfSSL_RSA_generate_key_ex");
11862
11863     (void)rsa;
11864     (void)bits;
11865     (void)cb;
11866     (void)bn;
11867
11868 #ifdef WOLFSSL_KEY_GEN
11869     {
11870     #ifdef WOLFSSL_SMALL_STACK
11871         RNG* rng = NULL;
11872     #else
11873         RNG  rng[1];
11874     #endif
11875
11876     #ifdef WOLFSSL_SMALL_STACK
11877         rng = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
11878         if (rng == NULL)
11879             return SSL_FATAL_ERROR;
11880     #endif
11881
11882         if (wc_InitRng(rng) < 0)
11883             WOLFSSL_MSG("RNG init failed");
11884         else if (wc_MakeRsaKey((RsaKey*)rsa->internal, bits, 65537, rng) < 0)
11885             WOLFSSL_MSG("wc_MakeRsaKey failed");
11886         else if (SetRsaExternal(rsa) < 0)
11887             WOLFSSL_MSG("SetRsaExternal failed");
11888         else {
11889             rsa->inSet = 1;
11890             ret = SSL_SUCCESS;
11891         }
11892
11893         wc_FreeRng(rng);
11894     #ifdef WOLFSSL_SMALL_STACK
11895         XFREE(rng, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11896     #endif
11897     }
11898 #else
11899     WOLFSSL_MSG("No Key Gen built in");
11900 #endif
11901     return ret;
11902 }
11903
11904
11905 /* SSL_SUCCESS on ok */
11906 int wolfSSL_RSA_blinding_on(WOLFSSL_RSA* rsa, WOLFSSL_BN_CTX* bn)
11907 {
11908     (void)rsa;
11909     (void)bn;
11910
11911     WOLFSSL_MSG("wolfSSL_RSA_blinding_on");
11912
11913     return SSL_SUCCESS;  /* on by default */
11914 }
11915
11916
11917 int wolfSSL_RSA_public_encrypt(int len, unsigned char* fr,
11918                             unsigned char* to, WOLFSSL_RSA* rsa, int padding)
11919 {
11920     (void)len;
11921     (void)fr;
11922     (void)to;
11923     (void)rsa;
11924     (void)padding;
11925
11926     WOLFSSL_MSG("wolfSSL_RSA_public_encrypt");
11927
11928     return SSL_FATAL_ERROR;
11929 }
11930
11931
11932 int wolfSSL_RSA_private_decrypt(int len, unsigned char* fr,
11933                             unsigned char* to, WOLFSSL_RSA* rsa, int padding)
11934 {
11935     (void)len;
11936     (void)fr;
11937     (void)to;
11938     (void)rsa;
11939     (void)padding;
11940
11941     WOLFSSL_MSG("wolfSSL_RSA_private_decrypt");
11942
11943     return SSL_FATAL_ERROR;
11944 }
11945
11946
11947 int wolfSSL_RSA_size(const WOLFSSL_RSA* rsa)
11948 {
11949     WOLFSSL_MSG("wolfSSL_RSA_size");
11950
11951     if (rsa == NULL)
11952         return 0;
11953
11954     return wolfSSL_BN_num_bytes(rsa->n);
11955 }
11956 #endif /* NO_RSA */
11957
11958
11959 #ifndef NO_DSA
11960 /* return SSL_SUCCESS on success, < 0 otherwise */
11961 int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
11962                        WOLFSSL_DSA* dsa)
11963 {
11964     int    ret = SSL_FATAL_ERROR;
11965     int    initTmpRng = 0;
11966     RNG*   rng = NULL;
11967 #ifdef WOLFSSL_SMALL_STACK
11968     RNG*   tmpRNG = NULL;
11969 #else
11970     RNG    tmpRNG[1];
11971 #endif
11972
11973     WOLFSSL_MSG("wolfSSL_DSA_do_sign");
11974
11975     if (d == NULL || sigRet == NULL || dsa == NULL)
11976         WOLFSSL_MSG("Bad function arguments");
11977     else if (dsa->inSet == 0)
11978         WOLFSSL_MSG("No DSA internal set");
11979     else {
11980     #ifdef WOLFSSL_SMALL_STACK
11981         tmpRNG = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
11982         if (tmpRNG == NULL)
11983             return SSL_FATAL_ERROR;
11984     #endif
11985
11986         if (wc_InitRng(tmpRNG) == 0) {
11987             rng = tmpRNG;
11988             initTmpRng = 1;
11989         }
11990         else {
11991             WOLFSSL_MSG("Bad RNG Init, trying global");
11992             if (initGlobalRNG == 0)
11993                 WOLFSSL_MSG("Global RNG no Init");
11994             else
11995                 rng = &globalRNG;
11996         }
11997
11998         if (rng) {
11999             if (DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0)
12000                 WOLFSSL_MSG("DsaSign failed");
12001             else
12002                 ret = SSL_SUCCESS;
12003         }
12004
12005         if (initTmpRng)
12006             wc_FreeRng(tmpRNG);
12007     #ifdef WOLFSSL_SMALL_STACK
12008         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12009     #endif
12010     }
12011
12012     return ret;
12013 }
12014 #endif /* NO_DSA */
12015
12016
12017 #ifndef NO_RSA
12018 /* return SSL_SUCCES on ok, 0 otherwise */
12019 int wolfSSL_RSA_sign(int type, const unsigned char* m,
12020                            unsigned int mLen, unsigned char* sigRet,
12021                            unsigned int* sigLen, WOLFSSL_RSA* rsa)
12022 {
12023     word32 outLen;    
12024     word32 signSz;
12025     int    initTmpRng = 0;
12026     RNG*   rng        = NULL;
12027     int    ret        = 0;
12028 #ifdef WOLFSSL_SMALL_STACK
12029     RNG*   tmpRNG     = NULL;
12030     byte*  encodedSig = NULL;
12031 #else
12032     RNG    tmpRNG[1];
12033     byte   encodedSig[MAX_ENCODED_SIG_SZ];
12034 #endif
12035
12036     WOLFSSL_MSG("wolfSSL_RSA_sign");
12037
12038     if (m == NULL || sigRet == NULL || sigLen == NULL || rsa == NULL)
12039         WOLFSSL_MSG("Bad function arguments");
12040     else if (rsa->inSet == 0)
12041         WOLFSSL_MSG("No RSA internal set");
12042     else if (type != NID_md5 && type != NID_sha1)
12043         WOLFSSL_MSG("Bad md type");
12044     else {
12045         outLen = (word32)wolfSSL_BN_num_bytes(rsa->n);
12046
12047     #ifdef WOLFSSL_SMALL_STACK
12048         tmpRNG = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
12049         if (tmpRNG == NULL)
12050             return 0;
12051
12052         encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
12053                                                        DYNAMIC_TYPE_TMP_BUFFER);
12054         if (encodedSig == NULL) {
12055             XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12056             return 0;
12057         }
12058     #endif
12059
12060         if (outLen == 0)
12061             WOLFSSL_MSG("Bad RSA size");
12062         else if (wc_InitRng(tmpRNG) == 0) {
12063             rng = tmpRNG;
12064             initTmpRng = 1;
12065         }
12066         else {
12067             WOLFSSL_MSG("Bad RNG Init, trying global");
12068
12069             if (initGlobalRNG == 0)
12070                 WOLFSSL_MSG("Global RNG no Init");
12071             else
12072                 rng = &globalRNG;
12073         }
12074     }
12075
12076     if (rng) {
12077         type = (type == NID_md5) ? MD5h : SHAh;
12078
12079         signSz = wc_EncodeSignature(encodedSig, m, mLen, type);
12080         if (signSz == 0) {
12081             WOLFSSL_MSG("Bad Encode Signature");
12082         }
12083         else {
12084             *sigLen = wc_RsaSSL_Sign(encodedSig, signSz, sigRet, outLen,
12085                                   (RsaKey*)rsa->internal, rng);
12086             if (*sigLen <= 0)
12087                 WOLFSSL_MSG("Bad Rsa Sign");
12088             else
12089                 ret = SSL_SUCCESS;
12090         }
12091
12092     }
12093
12094     if (initTmpRng)
12095         wc_FreeRng(tmpRNG);
12096
12097 #ifdef WOLFSSL_SMALL_STACK
12098     XFREE(tmpRNG,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
12099     XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12100 #endif
12101
12102     WOLFSSL_MSG("wolfSSL_RSA_sign success");
12103     return ret;
12104 }
12105
12106
12107 int wolfSSL_RSA_public_decrypt(int flen, unsigned char* from,
12108                           unsigned char* to, WOLFSSL_RSA* rsa, int padding)
12109 {
12110     (void)flen;
12111     (void)from;
12112     (void)to;
12113     (void)rsa;
12114     (void)padding;
12115
12116     WOLFSSL_MSG("wolfSSL_RSA_public_decrypt");
12117
12118     return SSL_FATAL_ERROR;
12119 }
12120
12121
12122 /* generate p-1 and q-1, SSL_SUCCESS on ok */
12123 int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
12124 {
12125     int    err;
12126     mp_int tmp;
12127
12128     WOLFSSL_MSG("wolfSSL_RsaGenAdd");
12129
12130     if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->d == NULL ||
12131                        rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
12132         WOLFSSL_MSG("rsa no init error");
12133         return SSL_FATAL_ERROR;
12134     }
12135
12136     if (mp_init(&tmp) != MP_OKAY) {
12137         WOLFSSL_MSG("mp_init error");
12138         return SSL_FATAL_ERROR;
12139     }
12140
12141     err = mp_sub_d((mp_int*)rsa->p->internal, 1, &tmp);
12142     if (err != MP_OKAY) {
12143         WOLFSSL_MSG("mp_sub_d error");
12144     }
12145     else
12146         err = mp_mod((mp_int*)rsa->d->internal, &tmp,
12147                      (mp_int*)rsa->dmp1->internal);
12148
12149     if (err != MP_OKAY) {
12150         WOLFSSL_MSG("mp_mod error");
12151     }
12152     else
12153         err = mp_sub_d((mp_int*)rsa->q->internal, 1, &tmp);
12154     if (err != MP_OKAY) {
12155         WOLFSSL_MSG("mp_sub_d error");
12156     }
12157     else
12158         err = mp_mod((mp_int*)rsa->d->internal, &tmp,
12159                      (mp_int*)rsa->dmq1->internal);
12160
12161     mp_clear(&tmp);
12162
12163     if (err == MP_OKAY)
12164         return SSL_SUCCESS;
12165     else
12166         return SSL_FATAL_ERROR;
12167 }
12168 #endif /* NO_RSA */
12169
12170
12171 void wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen,
12172                   const EVP_MD* type)
12173 {
12174     WOLFSSL_MSG("wolfSSL_HMAC_Init");
12175
12176     if (ctx == NULL) {
12177         WOLFSSL_MSG("no ctx on init");
12178         return;
12179     }
12180
12181     if (type) {
12182         WOLFSSL_MSG("init has type");
12183
12184         if (XSTRNCMP(type, "MD5", 3) == 0) {
12185             WOLFSSL_MSG("md5 hmac");
12186             ctx->type = MD5;
12187         }
12188         else if (XSTRNCMP(type, "SHA256", 6) == 0) {
12189             WOLFSSL_MSG("sha256 hmac");
12190             ctx->type = SHA256;
12191         }
12192
12193         /* has to be last since would pick or 256, 384, or 512 too */
12194         else if (XSTRNCMP(type, "SHA", 3) == 0) {
12195             WOLFSSL_MSG("sha hmac");
12196             ctx->type = SHA;
12197         }
12198         else {
12199             WOLFSSL_MSG("bad init type");
12200         }
12201     }
12202
12203     if (key && keylen) {
12204         WOLFSSL_MSG("keying hmac");
12205         wc_HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key, (word32)keylen);
12206         /* OpenSSL compat, no error */
12207     }
12208 }
12209
12210
12211 void wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, const unsigned char* data,
12212                     int len)
12213 {
12214     WOLFSSL_MSG("wolfSSL_HMAC_Update");
12215
12216     if (ctx && data) {
12217         WOLFSSL_MSG("updating hmac");
12218         wc_HmacUpdate(&ctx->hmac, data, (word32)len);
12219         /* OpenSSL compat, no error */
12220     }
12221 }
12222
12223
12224 void wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash,
12225                    unsigned int* len)
12226 {
12227     WOLFSSL_MSG("wolfSSL_HMAC_Final");
12228
12229     if (ctx && hash) {
12230         WOLFSSL_MSG("final hmac");
12231         wc_HmacFinal(&ctx->hmac, hash);
12232         /* OpenSSL compat, no error */
12233
12234         if (len) {
12235             WOLFSSL_MSG("setting output len");
12236             switch (ctx->type) {
12237                 case MD5:
12238                     *len = MD5_DIGEST_SIZE;
12239                     break;
12240
12241                 case SHA:
12242                     *len = SHA_DIGEST_SIZE;
12243                     break;
12244
12245                 case SHA256:
12246                     *len = SHA256_DIGEST_SIZE;
12247                     break;
12248
12249                 default:
12250                     WOLFSSL_MSG("bad hmac type");
12251             }
12252         }
12253     }
12254 }
12255
12256
12257 void wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx)
12258 {
12259     (void)ctx;
12260
12261     WOLFSSL_MSG("wolfSSL_HMAC_cleanup");
12262 }
12263
12264
12265 const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id)
12266 {
12267     WOLFSSL_MSG("wolfSSL_get_digestbynid");
12268
12269     switch(id) {
12270 #ifndef NO_MD5
12271         case NID_md5:
12272             return wolfSSL_EVP_md5();
12273 #endif
12274 #ifndef NO_SHA
12275         case NID_sha1:
12276             return wolfSSL_EVP_sha1();
12277 #endif
12278         default:
12279             WOLFSSL_MSG("Bad digest id value");
12280     }
12281
12282     return NULL;
12283 }
12284
12285
12286 WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY* key)
12287 {
12288     (void)key;
12289     WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_RSA");
12290
12291     return NULL;
12292 }
12293
12294
12295 WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY* key)
12296 {
12297     (void)key;
12298     WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_DSA");
12299
12300     return NULL;
12301 }
12302
12303
12304 void* wolfSSL_EVP_X_STATE(const WOLFSSL_EVP_CIPHER_CTX* ctx)
12305 {
12306     WOLFSSL_MSG("wolfSSL_EVP_X_STATE");
12307
12308     if (ctx) {
12309         switch (ctx->cipherType) {
12310             case ARC4_TYPE:
12311                 WOLFSSL_MSG("returning arc4 state");
12312                 return (void*)&ctx->cipher.arc4.x;
12313
12314             default:
12315                 WOLFSSL_MSG("bad x state type");
12316                 return 0;
12317         }
12318     }
12319
12320     return NULL;
12321 }
12322
12323
12324 int wolfSSL_EVP_X_STATE_LEN(const WOLFSSL_EVP_CIPHER_CTX* ctx)
12325 {
12326     WOLFSSL_MSG("wolfSSL_EVP_X_STATE_LEN");
12327
12328     if (ctx) {
12329         switch (ctx->cipherType) {
12330             case ARC4_TYPE:
12331                 WOLFSSL_MSG("returning arc4 state size");
12332                 return sizeof(Arc4);
12333
12334             default:
12335                 WOLFSSL_MSG("bad x state type");
12336                 return 0;
12337         }
12338     }
12339
12340     return 0;
12341 }
12342
12343
12344 #ifndef NO_DES3
12345
12346 void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
12347                             unsigned char* iv, int len)
12348 {
12349     (void)len;
12350
12351     WOLFSSL_MSG("wolfSSL_3des_iv");
12352
12353     if (ctx == NULL || iv == NULL) {
12354         WOLFSSL_MSG("Bad function argument");
12355         return;
12356     }
12357
12358     if (doset)
12359         wc_Des3_SetIV(&ctx->cipher.des3, iv);  /* OpenSSL compat, no ret */
12360     else
12361         memcpy(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
12362 }
12363
12364 #endif /* NO_DES3 */
12365
12366
12367 #ifndef NO_AES
12368
12369 void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
12370                       unsigned char* iv, int len)
12371 {
12372     (void)len;
12373
12374     WOLFSSL_MSG("wolfSSL_aes_ctr_iv");
12375
12376     if (ctx == NULL || iv == NULL) {
12377         WOLFSSL_MSG("Bad function argument");
12378         return;
12379     }
12380
12381     if (doset)
12382         wc_AesSetIV(&ctx->cipher.aes, iv);  /* OpenSSL compat, no ret */
12383     else
12384         memcpy(iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
12385 }
12386
12387 #endif /* NO_AES */
12388
12389
12390 const WOLFSSL_EVP_MD* wolfSSL_EVP_ripemd160(void)
12391 {
12392     WOLFSSL_MSG("wolfSSL_ripemd160");
12393
12394     return NULL;
12395 }
12396
12397
12398 int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* type)
12399 {
12400     WOLFSSL_MSG("wolfSSL_EVP_MD_size");
12401
12402     if (type == NULL) {
12403         WOLFSSL_MSG("No md type arg");
12404         return BAD_FUNC_ARG;
12405     }
12406
12407     if (XSTRNCMP(type, "SHA256", 6) == 0) {
12408         return SHA256_DIGEST_SIZE;
12409     }
12410 #ifndef NO_MD5
12411     else if (XSTRNCMP(type, "MD5", 3) == 0) {
12412         return MD5_DIGEST_SIZE;
12413     }
12414 #endif
12415 #ifdef WOLFSSL_SHA384
12416     else if (XSTRNCMP(type, "SHA384", 6) == 0) {
12417         return SHA384_DIGEST_SIZE;
12418     }
12419 #endif
12420 #ifdef WOLFSSL_SHA512
12421     else if (XSTRNCMP(type, "SHA512", 6) == 0) {
12422         return SHA512_DIGEST_SIZE;
12423     }
12424 #endif
12425 #ifndef NO_SHA
12426     /* has to be last since would pick or 256, 384, or 512 too */
12427     else if (XSTRNCMP(type, "SHA", 3) == 0) {
12428         return SHA_DIGEST_SIZE;
12429     }
12430 #endif
12431
12432     return BAD_FUNC_ARG;
12433 }
12434
12435
12436 int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx)
12437 {
12438     WOLFSSL_MSG("wolfSSL_EVP_CIPHER_CTX_iv_length");
12439
12440     switch (ctx->cipherType) {
12441
12442         case AES_128_CBC_TYPE :
12443         case AES_192_CBC_TYPE :
12444         case AES_256_CBC_TYPE :
12445             WOLFSSL_MSG("AES CBC");
12446             return AES_BLOCK_SIZE;
12447
12448 #ifdef WOLFSSL_AES_COUNTER
12449         case AES_128_CTR_TYPE :
12450         case AES_192_CTR_TYPE :
12451         case AES_256_CTR_TYPE :
12452             WOLFSSL_MSG("AES CTR");
12453             return AES_BLOCK_SIZE;
12454 #endif
12455
12456         case DES_CBC_TYPE :
12457             WOLFSSL_MSG("DES CBC");
12458             return DES_BLOCK_SIZE;
12459
12460         case DES_EDE3_CBC_TYPE :
12461             WOLFSSL_MSG("DES EDE3 CBC");
12462             return DES_BLOCK_SIZE;
12463
12464         case ARC4_TYPE :
12465             WOLFSSL_MSG("ARC4");
12466             return 0;
12467
12468         case NULL_CIPHER_TYPE :
12469             WOLFSSL_MSG("NULL");
12470             return 0;
12471
12472         default: {
12473             WOLFSSL_MSG("bad type");
12474         }
12475     }
12476     return 0;
12477 }
12478
12479
12480 void wolfSSL_OPENSSL_free(void* p)
12481 {
12482     WOLFSSL_MSG("wolfSSL_OPENSSL_free");
12483
12484     XFREE(p, NULL, 0);
12485 }
12486
12487
12488 int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, RSA* rsa,
12489                                   const EVP_CIPHER* cipher,
12490                                   unsigned char* passwd, int len,
12491                                   pem_password_cb cb, void* arg)
12492 {
12493     (void)bio;
12494     (void)rsa;
12495     (void)cipher;
12496     (void)passwd;
12497     (void)len;
12498     (void)cb;
12499     (void)arg;
12500
12501     WOLFSSL_MSG("wolfSSL_PEM_write_bio_RSAPrivateKey");
12502
12503     return SSL_FATAL_ERROR;
12504 }
12505
12506
12507
12508 int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, DSA* rsa,
12509                                   const EVP_CIPHER* cipher,
12510                                   unsigned char* passwd, int len,
12511                                   pem_password_cb cb, void* arg)
12512 {
12513     (void)bio;
12514     (void)rsa;
12515     (void)cipher;
12516     (void)passwd;
12517     (void)len;
12518     (void)cb;
12519     (void)arg;
12520
12521     WOLFSSL_MSG("wolfSSL_PEM_write_bio_DSAPrivateKey");
12522
12523     return SSL_FATAL_ERROR;
12524 }
12525
12526
12527
12528 WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
12529                     WOLFSSL_EVP_PKEY** key, pem_password_cb cb, void* arg)
12530 {
12531     (void)bio;
12532     (void)key;
12533     (void)cb;
12534     (void)arg;
12535
12536     WOLFSSL_MSG("wolfSSL_PEM_read_bio_PrivateKey");
12537
12538     return NULL;
12539 }
12540
12541
12542
12543 #ifndef NO_RSA
12544 /* Load RSA from Der, SSL_SUCCESS on success < 0 on error */
12545 int wolfSSL_RSA_LoadDer(WOLFSSL_RSA* rsa, const unsigned char* der,  int derSz)
12546 {
12547     word32 idx = 0;
12548     int    ret;
12549
12550     WOLFSSL_ENTER("wolfSSL_RSA_LoadDer");
12551
12552     if (rsa == NULL || rsa->internal == NULL || der == NULL || derSz <= 0) {
12553         WOLFSSL_MSG("Bad function arguments");
12554         return BAD_FUNC_ARG;
12555     }
12556
12557     ret = wc_RsaPrivateKeyDecode(der, &idx, (RsaKey*)rsa->internal, derSz);
12558     if (ret < 0) {
12559         WOLFSSL_MSG("RsaPrivateKeyDecode failed");
12560         return ret;
12561     }
12562
12563     if (SetRsaExternal(rsa) < 0) {
12564         WOLFSSL_MSG("SetRsaExternal failed");
12565         return SSL_FATAL_ERROR;
12566     }
12567
12568     rsa->inSet = 1;
12569
12570     return SSL_SUCCESS;
12571 }
12572 #endif /* NO_RSA */
12573
12574
12575 #ifndef NO_DSA
12576 /* Load DSA from Der, SSL_SUCCESS on success < 0 on error */
12577 int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* der,  int derSz)
12578 {
12579     word32 idx = 0;
12580     int    ret;
12581
12582     WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
12583
12584     if (dsa == NULL || dsa->internal == NULL || der == NULL || derSz <= 0) {
12585         WOLFSSL_MSG("Bad function arguments");
12586         return BAD_FUNC_ARG;
12587     }
12588
12589     ret = DsaPrivateKeyDecode(der, &idx, (DsaKey*)dsa->internal, derSz);
12590     if (ret < 0) {
12591         WOLFSSL_MSG("DsaPrivateKeyDecode failed");
12592         return ret;
12593     }
12594
12595     if (SetDsaExternal(dsa) < 0) {
12596         WOLFSSL_MSG("SetDsaExternal failed");
12597         return SSL_FATAL_ERROR;
12598     }
12599
12600     dsa->inSet = 1;
12601
12602     return SSL_SUCCESS;
12603 }
12604 #endif /* NO_DSA */
12605
12606
12607
12608
12609 #endif /* OPENSSL_EXTRA */
12610
12611
12612 #ifdef SESSION_CERTS
12613
12614
12615 /* Get peer's certificate chain */
12616 WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl)
12617 {
12618     WOLFSSL_ENTER("wolfSSL_get_peer_chain");
12619     if (ssl)
12620         return &ssl->session.chain;
12621
12622     return 0;
12623 }
12624
12625
12626 /* Get peer's certificate chain total count */
12627 int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain)
12628 {
12629     WOLFSSL_ENTER("wolfSSL_get_chain_count");
12630     if (chain)
12631         return chain->count;
12632
12633     return 0;
12634 }
12635
12636
12637 /* Get peer's ASN.1 DER ceritifcate at index (idx) length in bytes */
12638 int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx)
12639 {
12640     WOLFSSL_ENTER("wolfSSL_get_chain_length");
12641     if (chain)
12642         return chain->certs[idx].length;
12643
12644     return 0;
12645 }
12646
12647
12648 /* Get peer's ASN.1 DER ceritifcate at index (idx) */
12649 byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx)
12650 {
12651     WOLFSSL_ENTER("wolfSSL_get_chain_cert");
12652     if (chain)
12653         return chain->certs[idx].buffer;
12654
12655     return 0;
12656 }
12657
12658
12659 /* Get peer's wolfSSL X509 ceritifcate at index (idx) */
12660 WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx)
12661 {
12662     int          ret;
12663     WOLFSSL_X509* x509 = NULL;
12664 #ifdef WOLFSSL_SMALL_STACK
12665     DecodedCert* cert = NULL;
12666 #else
12667     DecodedCert  cert[1];
12668 #endif
12669
12670     WOLFSSL_ENTER("wolfSSL_get_chain_X509");
12671     if (chain != NULL) {
12672     #ifdef WOLFSSL_SMALL_STACK
12673         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
12674                                                        DYNAMIC_TYPE_TMP_BUFFER);
12675         if (cert != NULL)
12676     #endif
12677         {
12678             InitDecodedCert(cert, chain->certs[idx].buffer,
12679                                   chain->certs[idx].length, NULL);
12680
12681             if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) != 0)
12682                 WOLFSSL_MSG("Failed to parse cert");
12683             else {
12684                 x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
12685                                                              DYNAMIC_TYPE_X509);
12686                 if (x509 == NULL) {
12687                     WOLFSSL_MSG("Failed alloc X509");
12688                 }
12689                 else {
12690                     InitX509(x509, 1);
12691
12692                     if ((ret = CopyDecodedToX509(x509, cert)) != 0) {
12693                         WOLFSSL_MSG("Failed to copy decoded");
12694                         XFREE(x509, NULL, DYNAMIC_TYPE_X509);
12695                         x509 = NULL;
12696                     }
12697                 }
12698             }
12699
12700             FreeDecodedCert(cert);
12701         #ifdef WOLFSSL_SMALL_STACK
12702             XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12703         #endif
12704         }
12705     }
12706
12707     return x509;
12708 }
12709
12710
12711 /* Get peer's PEM ceritifcate at index (idx), output to buffer if inLen big
12712    enough else return error (-1), output length is in *outLen
12713    SSL_SUCCESS on ok */
12714 int  wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
12715                                unsigned char* buf, int inLen, int* outLen)
12716 {
12717     const char header[] = "-----BEGIN CERTIFICATE-----\n";
12718     const char footer[] = "-----END CERTIFICATE-----\n";
12719
12720     int headerLen = sizeof(header) - 1;
12721     int footerLen = sizeof(footer) - 1;
12722     int i;
12723     int err;
12724
12725     WOLFSSL_ENTER("wolfSSL_get_chain_cert_pem");
12726     if (!chain || !outLen || !buf)
12727         return BAD_FUNC_ARG;
12728
12729     /* don't even try if inLen too short */
12730     if (inLen < headerLen + footerLen + chain->certs[idx].length)
12731         return BAD_FUNC_ARG;
12732
12733     /* header */
12734     XMEMCPY(buf, header, headerLen);
12735     i = headerLen;
12736
12737     /* body */
12738     *outLen = inLen;  /* input to Base64_Encode */
12739     if ( (err = Base64_Encode(chain->certs[idx].buffer,
12740                        chain->certs[idx].length, buf + i, (word32*)outLen)) < 0)
12741         return err;
12742     i += *outLen;
12743
12744     /* footer */
12745     if ( (i + footerLen) > inLen)
12746         return BAD_FUNC_ARG;
12747     XMEMCPY(buf + i, footer, footerLen);
12748     *outLen += headerLen + footerLen;
12749
12750     return SSL_SUCCESS;
12751 }
12752
12753
12754 /* get session ID */
12755 const byte* wolfSSL_get_sessionID(const WOLFSSL_SESSION* session)
12756 {
12757     WOLFSSL_ENTER("wolfSSL_get_sessionID");
12758     if (session)
12759         return session->sessionID;
12760
12761     return NULL;
12762 }
12763
12764
12765 #endif /* SESSION_CERTS */
12766
12767 #ifdef HAVE_FUZZER
12768 void wolfSSL_SetFuzzerCb(WOLFSSL* ssl, CallbackFuzzer cbf, void* fCtx)
12769 {
12770     if (ssl) {
12771         ssl->fuzzerCb  = cbf;
12772         ssl->fuzzerCtx = fCtx;
12773     }
12774 }
12775 #endif
12776
12777 #ifndef NO_CERTS
12778 #ifdef  HAVE_PK_CALLBACKS
12779
12780 #ifdef HAVE_ECC
12781
12782 void  wolfSSL_CTX_SetEccSignCb(WOLFSSL_CTX* ctx, CallbackEccSign cb)
12783 {
12784     if (ctx)
12785         ctx->EccSignCb = cb;
12786 }
12787
12788
12789 void  wolfSSL_SetEccSignCtx(WOLFSSL* ssl, void *ctx)
12790 {
12791     if (ssl)
12792         ssl->EccSignCtx = ctx;
12793 }
12794
12795
12796 void* wolfSSL_GetEccSignCtx(WOLFSSL* ssl)
12797 {
12798     if (ssl)
12799         return ssl->EccSignCtx;
12800
12801     return NULL;
12802 }
12803
12804
12805 void  wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX* ctx, CallbackEccVerify cb)
12806 {
12807     if (ctx)
12808         ctx->EccVerifyCb = cb;
12809 }
12810
12811
12812 void  wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx)
12813 {
12814     if (ssl)
12815         ssl->EccVerifyCtx = ctx;
12816 }
12817
12818
12819 void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl)
12820 {
12821     if (ssl)
12822         return ssl->EccVerifyCtx;
12823
12824     return NULL;
12825 }
12826
12827 #endif /* HAVE_ECC */
12828
12829 #ifndef NO_RSA
12830
12831 void  wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX* ctx, CallbackRsaSign cb)
12832 {
12833     if (ctx)
12834         ctx->RsaSignCb = cb;
12835 }
12836
12837
12838 void  wolfSSL_SetRsaSignCtx(WOLFSSL* ssl, void *ctx)
12839 {
12840     if (ssl)
12841         ssl->RsaSignCtx = ctx;
12842 }
12843
12844
12845 void* wolfSSL_GetRsaSignCtx(WOLFSSL* ssl)
12846 {
12847     if (ssl)
12848         return ssl->RsaSignCtx;
12849
12850     return NULL;
12851 }
12852
12853
12854 void  wolfSSL_CTX_SetRsaVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
12855 {
12856     if (ctx)
12857         ctx->RsaVerifyCb = cb;
12858 }
12859
12860
12861 void  wolfSSL_SetRsaVerifyCtx(WOLFSSL* ssl, void *ctx)
12862 {
12863     if (ssl)
12864         ssl->RsaVerifyCtx = ctx;
12865 }
12866
12867
12868 void* wolfSSL_GetRsaVerifyCtx(WOLFSSL* ssl)
12869 {
12870     if (ssl)
12871         return ssl->RsaVerifyCtx;
12872
12873     return NULL;
12874 }
12875
12876 void  wolfSSL_CTX_SetRsaEncCb(WOLFSSL_CTX* ctx, CallbackRsaEnc cb)
12877 {
12878     if (ctx)
12879         ctx->RsaEncCb = cb;
12880 }
12881
12882
12883 void  wolfSSL_SetRsaEncCtx(WOLFSSL* ssl, void *ctx)
12884 {
12885     if (ssl)
12886         ssl->RsaEncCtx = ctx;
12887 }
12888
12889
12890 void* wolfSSL_GetRsaEncCtx(WOLFSSL* ssl)
12891 {
12892     if (ssl)
12893         return ssl->RsaEncCtx;
12894
12895     return NULL;
12896 }
12897
12898 void  wolfSSL_CTX_SetRsaDecCb(WOLFSSL_CTX* ctx, CallbackRsaDec cb)
12899 {
12900     if (ctx)
12901         ctx->RsaDecCb = cb;
12902 }
12903
12904
12905 void  wolfSSL_SetRsaDecCtx(WOLFSSL* ssl, void *ctx)
12906 {
12907     if (ssl)
12908         ssl->RsaDecCtx = ctx;
12909 }
12910
12911
12912 void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
12913 {
12914     if (ssl)
12915         return ssl->RsaDecCtx;
12916
12917     return NULL;
12918 }
12919
12920
12921 #endif /* NO_RSA */
12922
12923 #endif /* HAVE_PK_CALLBACKS */
12924 #endif /* NO_CERTS */
12925
12926
12927 #ifdef WOLFSSL_HAVE_WOLFSCEP
12928     /* Used by autoconf to see if wolfSCEP is available */
12929     void wolfSSL_wolfSCEP(void) {}
12930 #endif
12931
12932
12933 #ifdef WOLFSSL_HAVE_CERT_SERVICE
12934     /* Used by autoconf to see if cert service is available */
12935     void wolfSSL_cert_service(void) {}
12936 #endif
12937