]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/CyaSSL/src/ssl.c
Prepare for V7.2.0 release.
[freertos] / FreeRTOS-Plus / CyaSSL / src / ssl.c
1 /* ssl.c
2  *
3  * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL 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  * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26 #ifdef HAVE_ERRNO_H 
27     #include <errno.h>
28 #endif
29
30 #define TRUE  1
31 #define FALSE 0
32
33 #include <cyassl/ssl.h>
34 #include <cyassl/internal.h>
35 #include <cyassl/error.h>
36 #include <cyassl/ctaocrypt/coding.h>
37
38 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
39     #include <cyassl/openssl/evp.h>
40 #endif
41
42 #ifdef OPENSSL_EXTRA
43     /* openssl headers begin */
44     #include <cyassl/openssl/hmac.h>
45     #include <cyassl/openssl/crypto.h>
46     #include <cyassl/openssl/des.h>
47     #include <cyassl/openssl/bn.h>
48     #include <cyassl/openssl/dh.h>
49     #include <cyassl/openssl/rsa.h>
50     #include <cyassl/openssl/pem.h>
51     /* openssl headers end, cyassl internal headers next */
52     #include <cyassl/ctaocrypt/hmac.h>
53     #include <cyassl/ctaocrypt/random.h>
54     #include <cyassl/ctaocrypt/des3.h>
55     #include <cyassl/ctaocrypt/md4.h>
56     #include <cyassl/ctaocrypt/md5.h>
57     #include <cyassl/ctaocrypt/arc4.h>
58     #ifdef CYASSL_SHA512
59         #include <cyassl/ctaocrypt/sha512.h>
60     #endif
61 #endif
62
63 #ifndef NO_FILESYSTEM
64     #if !defined(USE_WINDOWS_API) && !defined(NO_CYASSL_DIR)
65         #include <dirent.h>
66     #endif
67 #endif /* NO_FILESYSTEM */
68
69
70 #ifndef min
71
72     static INLINE word32 min(word32 a, word32 b)
73     {
74         return a > b ? b : a;
75     }
76
77 #endif /* min */
78
79
80 char* mystrnstr(const char* s1, const char* s2, unsigned int n)
81 {
82     unsigned int s2_len = XSTRLEN(s2);
83
84     if (s2_len == 0)
85         return (char*)s1;
86
87     while (n >= s2_len && s1[0]) {
88         if (s1[0] == s2[0])
89             if (XMEMCMP(s1, s2, s2_len) == 0)
90                 return (char*)s1;
91         s1++;
92         n--;
93     }
94
95     return NULL;
96 }
97
98
99 CYASSL_CTX* CyaSSL_CTX_new(CYASSL_METHOD* method)
100 {
101     CYASSL_CTX* ctx = NULL;
102
103     CYASSL_ENTER("CYASSL_CTX_new");
104
105     if (method == NULL)
106         return ctx;
107
108     ctx = (CYASSL_CTX*) XMALLOC(sizeof(CYASSL_CTX), 0, DYNAMIC_TYPE_CTX);
109     if (ctx) {
110         if (InitSSL_Ctx(ctx, method) < 0) {
111             CYASSL_MSG("Init CTX failed");
112             CyaSSL_CTX_free(ctx);
113             ctx = NULL;
114         }
115     }
116
117     CYASSL_LEAVE("CYASSL_CTX_new", 0);
118     return ctx;
119 }
120
121
122 void CyaSSL_CTX_free(CYASSL_CTX* ctx)
123 {
124     CYASSL_ENTER("SSL_CTX_free");
125     if (ctx)
126         FreeSSL_Ctx(ctx);
127     CYASSL_LEAVE("SSL_CTX_free", 0);
128 }
129
130
131 CYASSL* CyaSSL_new(CYASSL_CTX* ctx)
132 {
133     CYASSL* ssl = NULL;
134
135     CYASSL_ENTER("SSL_new");
136
137     if (ctx == NULL)
138         return ssl;
139
140     ssl = (CYASSL*) XMALLOC(sizeof(CYASSL), ctx->heap,DYNAMIC_TYPE_SSL);
141     if (ssl)
142         if (InitSSL(ssl, ctx) < 0) {
143             FreeSSL(ssl);
144             ssl = 0;
145         }
146
147     CYASSL_LEAVE("SSL_new", 0);
148     return ssl;
149 }
150
151
152 void CyaSSL_free(CYASSL* ssl)
153 {
154     CYASSL_ENTER("SSL_free");
155     if (ssl)
156         FreeSSL(ssl);
157     CYASSL_LEAVE("SSL_free", 0);
158 }
159
160
161 int CyaSSL_set_fd(CYASSL* ssl, int fd)
162 {
163     CYASSL_ENTER("SSL_set_fd");
164     ssl->rfd = fd;      /* not used directly to allow IO callbacks */
165     ssl->wfd = fd;
166
167     ssl->IOCB_ReadCtx  = &ssl->rfd;
168     ssl->IOCB_WriteCtx = &ssl->wfd;
169
170     CYASSL_LEAVE("SSL_set_fd", SSL_SUCCESS);
171     return SSL_SUCCESS;
172 }
173
174
175 int CyaSSL_get_fd(const CYASSL* ssl)
176 {
177     CYASSL_ENTER("SSL_get_fd");
178     CYASSL_LEAVE("SSL_get_fd", ssl->rfd);
179     return ssl->rfd;
180 }
181
182
183 int CyaSSL_negotiate(CYASSL* ssl)
184 {
185     int err = SSL_FATAL_ERROR;
186
187     CYASSL_ENTER("CyaSSL_negotiate");
188 #ifndef NO_CYASSL_SERVER
189     if (ssl->options.side == SERVER_END)
190         err = CyaSSL_accept(ssl);
191 #endif
192
193 #ifndef NO_CYASSL_CLIENT
194     if (ssl->options.side == CLIENT_END)
195         err = CyaSSL_connect(ssl);
196 #endif
197
198     CYASSL_LEAVE("CyaSSL_negotiate", err);
199
200     if (err == SSL_SUCCESS)
201         return 0;
202     else
203         return err;
204 }
205
206
207 /* server Diffie-Hellman parameters */
208 int CyaSSL_SetTmpDH(CYASSL* ssl, const unsigned char* p, int pSz,
209                     const unsigned char* g, int gSz)
210 {
211     byte havePSK = 0;
212
213     CYASSL_ENTER("CyaSSL_SetTmpDH");
214     if (ssl == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
215
216     if (ssl->options.side != SERVER_END)
217         return SIDE_ERROR;
218
219     if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH)
220         XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
221     if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH)
222         XFREE(ssl->buffers.serverDH_G.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
223
224     ssl->buffers.weOwnDH = 1;  /* SSL owns now */
225     ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->ctx->heap,
226                                                     DYNAMIC_TYPE_DH);
227     if (ssl->buffers.serverDH_P.buffer == NULL)
228         return MEMORY_E;
229
230     ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, ssl->ctx->heap,
231                                                     DYNAMIC_TYPE_DH);
232     if (ssl->buffers.serverDH_G.buffer == NULL) {
233         XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
234         return MEMORY_E;
235     }
236
237     ssl->buffers.serverDH_P.length = pSz;
238     ssl->buffers.serverDH_G.length = gSz;
239
240     XMEMCPY(ssl->buffers.serverDH_P.buffer, p, pSz);
241     XMEMCPY(ssl->buffers.serverDH_G.buffer, g, gSz);
242
243     ssl->options.haveDH = 1;
244     #ifndef NO_PSK
245         havePSK = ssl->options.havePSK;
246     #endif
247     InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH,
248                havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig,
249                ssl->options.haveStaticECC, ssl->options.side);
250
251     CYASSL_LEAVE("CyaSSL_SetTmpDH", 0);
252     return 0;
253 }
254
255
256 int CyaSSL_write(CYASSL* ssl, const void* data, int sz)
257 {
258     int ret;
259
260     CYASSL_ENTER("SSL_write()");
261
262 #ifdef HAVE_ERRNO_H 
263     errno = 0;
264 #endif
265
266     ret = SendData(ssl, data, sz);
267
268     CYASSL_LEAVE("SSL_write()", ret);
269
270     if (ret < 0)
271         return SSL_FATAL_ERROR;
272     else
273         return ret;
274 }
275
276
277 int CyaSSL_read(CYASSL* ssl, void* data, int sz)
278 {
279     int ret; 
280
281     CYASSL_ENTER("SSL_read()");
282
283 #ifdef HAVE_ERRNO_H 
284         errno = 0;
285 #endif
286
287     ret = ReceiveData(ssl, (byte*)data, min(sz, OUTPUT_RECORD_SIZE));
288
289     CYASSL_LEAVE("SSL_read()", ret);
290
291     if (ret < 0)
292         return SSL_FATAL_ERROR;
293     else
294         return ret;
295 }
296
297
298 int CyaSSL_shutdown(CYASSL* ssl)
299 {
300     CYASSL_ENTER("SSL_shutdown()");
301
302     if (ssl->options.quietShutdown) {
303         CYASSL_MSG("quiet shutdown, no close notify sent"); 
304         return 0;
305     }
306
307     /* try to send close notify, not an error if can't */
308     if (!ssl->options.isClosed && !ssl->options.connReset &&
309                                   !ssl->options.sentNotify) {
310         ssl->error = SendAlert(ssl, alert_warning, close_notify);
311         if (ssl->error < 0) {
312             CYASSL_ERROR(ssl->error);
313             return SSL_FATAL_ERROR;
314         }
315         ssl->options.sentNotify = 1;  /* don't send close_notify twice */
316     }
317
318     CYASSL_LEAVE("SSL_shutdown()", ssl->error);
319
320     ssl->error = SSL_ERROR_SYSCALL;   /* simulate OpenSSL behavior */
321
322     return 0;
323 }
324
325
326 int CyaSSL_get_error(CYASSL* ssl, int ret)
327 {
328     CYASSL_ENTER("SSL_get_error");
329     CYASSL_LEAVE("SSL_get_error", ssl->error);
330     if (ret > 0)
331         return SSL_ERROR_NONE;
332
333     if (ssl->error == WANT_READ)
334         return SSL_ERROR_WANT_READ;         /* convert to OpenSSL type */
335     else if (ssl->error == WANT_WRITE)
336         return SSL_ERROR_WANT_WRITE;        /* convert to OpenSSL type */
337     else if (ssl->error == ZERO_RETURN) 
338         return SSL_ERROR_ZERO_RETURN;       /* convert to OpenSSL type */
339     return ssl->error;
340 }
341
342
343 int CyaSSL_want_read(CYASSL* ssl)
344 {
345     CYASSL_ENTER("SSL_want_read");
346     if (ssl->error == WANT_READ)
347         return 1;
348
349     return 0;
350 }
351
352
353 int CyaSSL_want_write(CYASSL* ssl)
354 {
355     CYASSL_ENTER("SSL_want_write");
356     if (ssl->error == WANT_WRITE)
357         return 1;
358
359     return 0;
360 }
361
362
363 char* CyaSSL_ERR_error_string(unsigned long errNumber, char* data)
364 {
365     static const char* msg = "Please supply a buffer for error string";
366
367     CYASSL_ENTER("ERR_error_string");
368     if (data) {
369         SetErrorString(errNumber, data);
370         return data;
371     }
372
373     return (char*)msg;
374 }
375
376
377 void CyaSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
378 {
379     CYASSL_ENTER("CyaSSL_ERR_error_string_n");
380     if (len) CyaSSL_ERR_error_string(e, buf);
381 }
382
383
384 CYASSL_CERT_MANAGER* CyaSSL_CertManagerNew(void)
385 {
386     CYASSL_CERT_MANAGER* cm = NULL;
387
388     CYASSL_ENTER("CyaSSL_CertManagerNew");
389
390     cm = (CYASSL_CERT_MANAGER*) XMALLOC(sizeof(CYASSL_CERT_MANAGER), 0,
391                                         DYNAMIC_TYPE_CERT_MANAGER);
392     if (cm) {
393         cm->caList          = NULL;
394         cm->heap            = NULL;
395         cm->caCacheCallback = NULL;
396         cm->crl             = NULL;
397         cm->crlEnabled      = 0;
398         cm->crlCheckAll     = 0;
399         cm->cbMissingCRL    = NULL;
400
401         if (InitMutex(&cm->caLock) != 0) {
402             CYASSL_MSG("Bad mutex init");
403             CyaSSL_CertManagerFree(cm);
404             return NULL;
405         }
406     }
407
408     return cm;
409 }
410
411
412 void CyaSSL_CertManagerFree(CYASSL_CERT_MANAGER* cm)
413 {
414     CYASSL_ENTER("CyaSSL_CertManagerFree");
415
416     if (cm) {
417         #ifdef HAVE_CRL
418             if (cm->crl) 
419                 FreeCRL(cm->crl);
420         #endif
421         FreeSigners(cm->caList, NULL);
422         FreeMutex(&cm->caLock);
423         XFREE(cm, NULL, DYNAMIC_TYPE_CERT_MANAGER);
424     }
425
426 }
427
428
429
430
431 #ifndef NO_FILESYSTEM
432
433 void CyaSSL_ERR_print_errors_fp(FILE* fp, int err)
434 {
435     char data[MAX_ERROR_SZ + 1];
436
437     CYASSL_ENTER("CyaSSL_ERR_print_errors_fp");
438     SetErrorString(err, data);
439     fprintf(fp, "%s", data);
440 }
441
442 #endif
443
444
445 int CyaSSL_pending(CYASSL* ssl)
446 {
447     CYASSL_ENTER("SSL_pending");
448     return ssl->buffers.clearOutputBuffer.length;
449 }
450
451
452 /* trun on handshake group messages for context */
453 int CyaSSL_CTX_set_group_messages(CYASSL_CTX* ctx)
454 {
455     if (ctx == NULL)
456        return BAD_FUNC_ARG;
457
458     ctx->groupMessages = 1;
459
460     return SSL_SUCCESS;
461 }
462
463
464 #ifndef NO_CYASSL_CLIENT
465 /* connect enough to get peer cert chain */
466 int CyaSSL_connect_cert(CYASSL* ssl)
467 {
468     int  ret;
469
470     if (ssl == NULL)
471         return SSL_FAILURE;
472
473     ssl->options.certOnly = 1;
474     ret = CyaSSL_connect(ssl);
475     ssl->options.certOnly   = 0;
476
477     return ret;
478 }
479 #endif
480
481
482 /* trun on handshake group messages for ssl object */
483 int CyaSSL_set_group_messages(CYASSL* ssl)
484 {
485     if (ssl == NULL)
486        return BAD_FUNC_ARG;
487
488     ssl->options.groupMessages = 1;
489
490     return SSL_SUCCESS;
491 }
492
493
494 int CyaSSL_SetVersion(CYASSL* ssl, int version)
495 {
496     byte havePSK = 0;
497
498     CYASSL_ENTER("CyaSSL_SetVersion");
499
500     if (ssl == NULL) {
501         CYASSL_MSG("Bad function argument");
502         return BAD_FUNC_ARG;
503     }
504
505     switch (version) {
506         case CYASSL_SSLV3:
507             ssl->version = MakeSSLv3();
508             break;
509
510 #ifndef NO_TLS
511         case CYASSL_TLSV1:
512             ssl->version = MakeTLSv1();
513             break;
514
515         case CYASSL_TLSV1_1:
516             ssl->version = MakeTLSv1_1();
517             break;
518
519         case CYASSL_TLSV1_2:
520             ssl->version = MakeTLSv1_2();
521             break;
522 #endif
523
524         default:
525             CYASSL_MSG("Bad function argument");
526             return BAD_FUNC_ARG;
527     }
528
529     #ifndef NO_PSK
530         havePSK = ssl->options.havePSK;
531     #endif
532
533     InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK,
534                 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
535                 ssl->options.haveStaticECC, ssl->options.side);
536
537     return SSL_SUCCESS;
538 }
539
540
541 /* does CA already exist on signer list */
542 int AlreadySigner(CYASSL_CERT_MANAGER* cm, byte* hash)
543 {
544     Signer* signers;
545     int     ret = 0;
546
547     if (LockMutex(&cm->caLock) != 0)
548         return  ret;
549     signers = cm->caList;
550     while (signers) {
551         if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
552             ret = 1;
553             break;
554         }
555         signers = signers->next;
556     }
557     UnLockMutex(&cm->caLock);
558
559     return ret;
560 }
561
562
563 /* return CA if found, otherwise NULL */
564 Signer* GetCA(void* vp, byte* hash)
565 {
566     CYASSL_CERT_MANAGER* cm = (CYASSL_CERT_MANAGER*)vp;
567     Signer* ret = NULL;
568     Signer* signers;
569
570     if (cm == NULL)
571         return NULL;
572
573     signers = cm->caList;
574
575     if (LockMutex(&cm->caLock) != 0)
576         return ret;
577     while (signers) {
578         if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
579             ret = signers;
580             break;
581         }
582         signers = signers->next;
583     }
584     UnLockMutex(&cm->caLock);
585
586     return ret;
587 }
588
589
590 /* owns der, internal now uses too */
591 /* type flag ids from user or from chain received during verify
592    don't allow chain ones to be added w/o isCA extension */
593 int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify)
594 {
595     int         ret;
596     DecodedCert cert;
597     Signer*     signer = 0;
598
599     CYASSL_MSG("Adding a CA");
600     InitDecodedCert(&cert, der.buffer, der.length, cm->heap);
601     ret = ParseCert(&cert, CA_TYPE, verify, cm);
602     CYASSL_MSG("    Parsed new CA");
603
604     if (ret == 0 && cert.isCA == 0 && type != CYASSL_USER_CA) {
605         CYASSL_MSG("    Can't add as CA if not actually one");
606         ret = NOT_CA_ERROR;
607     }
608     else if (ret == 0 && AlreadySigner(cm, cert.subjectHash)) {
609         CYASSL_MSG("    Already have this CA, not adding again");
610         (void)ret;
611     } 
612     else if (ret == 0) {
613         /* take over signer parts */
614         signer = MakeSigner(cm->heap);
615         if (!signer)
616             ret = MEMORY_ERROR;
617         else {
618             signer->keyOID     = cert.keyOID;
619             signer->publicKey  = cert.publicKey;
620             signer->pubKeySize = cert.pubKeySize;
621             signer->name = cert.subjectCN;
622             XMEMCPY(signer->hash, cert.subjectHash, SHA_DIGEST_SIZE);
623             signer->next = NULL;   /* in case lock fails */
624
625             cert.publicKey = 0;  /* don't free here */
626             cert.subjectCN = 0;
627
628             if (LockMutex(&cm->caLock) == 0) {
629                 signer->next = cm->caList;
630                 cm->caList  = signer;   /* takes ownership */
631                 UnLockMutex(&cm->caLock);
632                 if (cm->caCacheCallback)
633                     cm->caCacheCallback(der.buffer, (int)der.length, type);
634             }
635             else {
636                 CYASSL_MSG("    CA Mutex Lock failed");
637                 ret = BAD_MUTEX_ERROR;
638                 FreeSigners(signer, cm->heap);
639             }
640         }
641     }
642
643     CYASSL_MSG("    Freeing Parsed CA");
644     FreeDecodedCert(&cert);
645     CYASSL_MSG("    Freeing der CA");
646     XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_CA);
647     CYASSL_MSG("        OK Freeing der CA");
648
649     CYASSL_LEAVE("AddCA", ret);
650     if (ret == 0) return SSL_SUCCESS;
651     return ret;
652 }
653
654
655 #ifndef NO_SESSION_CACHE
656
657     /* basic config gives a cache with 33 sessions, adequate for clients and
658        embedded servers
659
660        MEDIUM_SESSION_CACHE allows 1055 sessions, adequate for servers that
661        aren't under heavy load, basically allows 200 new sessions per minute
662
663        BIG_SESSION_CACHE yields 20,0027 sessions
664
665        HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
666        allows over 13,000 new sessions per minute or over 200 new sessions per
667        second
668
669        SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients
670        or systems where the default of nearly 3kB is too much RAM, this define
671        uses less than 500 bytes RAM
672     */
673     #ifdef HUGE_SESSION_CACHE
674         #define SESSIONS_PER_ROW 11
675         #define SESSION_ROWS 5981
676     #elif defined(BIG_SESSION_CACHE)
677         #define SESSIONS_PER_ROW 7
678         #define SESSION_ROWS 2861
679     #elif defined(MEDIUM_SESSION_CACHE)
680         #define SESSIONS_PER_ROW 5
681         #define SESSION_ROWS 211
682     #elif defined(SMALL_SESSION_CACHE)
683         #define SESSIONS_PER_ROW 2
684         #define SESSION_ROWS 3 
685     #else
686         #define SESSIONS_PER_ROW 3
687         #define SESSION_ROWS 11
688     #endif
689
690     typedef struct SessionRow {
691         int nextIdx;                           /* where to place next one   */
692         int totalCount;                        /* sessions ever on this row */
693         CYASSL_SESSION Sessions[SESSIONS_PER_ROW];
694     } SessionRow;
695
696     static SessionRow SessionCache[SESSION_ROWS];
697
698     static CyaSSL_Mutex session_mutex;   /* SessionCache mutex */
699
700 #endif /* NO_SESSION_CACHE */
701
702
703     /* Remove PEM header/footer, convert to ASN1, store any encrypted data 
704        info->consumed tracks of PEM bytes consumed in case multiple parts */
705     int PemToDer(const unsigned char* buff, long sz, int type,
706                       buffer* der, void* heap, EncryptedInfo* info, int* eccKey)
707     {
708         char  header[PEM_LINE_LEN];
709         char  footer[PEM_LINE_LEN];
710         char* headerEnd;
711         char* footerEnd;
712         char* consumedEnd;
713         long  neededSz;
714         int   pkcs8    = 0;
715         int   pkcs8Enc = 0;
716         int   dynamicType = 0;
717
718         (void)heap;
719         (void)dynamicType;
720         (void)pkcs8Enc;
721
722         if (type == CERT_TYPE || type == CA_TYPE)  {
723             XSTRNCPY(header, "-----BEGIN CERTIFICATE-----", sizeof(header));
724             XSTRNCPY(footer, "-----END CERTIFICATE-----", sizeof(footer));
725             dynamicType = (type == CA_TYPE) ? DYNAMIC_TYPE_CA :
726                                               DYNAMIC_TYPE_CERT;
727         } else if (type == DH_PARAM_TYPE) {
728             XSTRNCPY(header, "-----BEGIN DH PARAMETERS-----", sizeof(header));
729             XSTRNCPY(footer, "-----END DH PARAMETERS-----", sizeof(footer));
730             dynamicType = DYNAMIC_TYPE_KEY;
731         } else if (type == CRL_TYPE) {
732             XSTRNCPY(header, "-----BEGIN X509 CRL-----", sizeof(header));
733             XSTRNCPY(footer, "-----END X509 CRL-----", sizeof(footer));
734             dynamicType = DYNAMIC_TYPE_CRL;
735         } else {
736             XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----", sizeof(header));
737             XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----", sizeof(footer));
738             dynamicType = DYNAMIC_TYPE_KEY;
739         }
740
741         /* find header */
742         headerEnd = XSTRNSTR((char*)buff, header, sz);
743         if (!headerEnd && type == PRIVATEKEY_TYPE) {  /* may be pkcs8 */
744             XSTRNCPY(header, "-----BEGIN PRIVATE KEY-----", sizeof(header));
745             XSTRNCPY(footer, "-----END PRIVATE KEY-----", sizeof(footer));
746         
747             headerEnd = XSTRNSTR((char*)buff, header, sz);
748             if (headerEnd)
749                 pkcs8 = 1;
750             else {
751                 XSTRNCPY(header, "-----BEGIN ENCRYPTED PRIVATE KEY-----",
752                         sizeof(header));
753                 XSTRNCPY(footer, "-----END ENCRYPTED PRIVATE KEY-----",
754                         sizeof(footer));
755
756                 headerEnd = XSTRNSTR((char*)buff, header, sz);
757                 if (headerEnd)
758                     pkcs8Enc = 1;
759             }
760         }
761         if (!headerEnd && type == PRIVATEKEY_TYPE) {  /* may be ecc */
762             XSTRNCPY(header, "-----BEGIN EC PRIVATE KEY-----", sizeof(header));
763             XSTRNCPY(footer, "-----END EC PRIVATE KEY-----", sizeof(footer));
764         
765             headerEnd = XSTRNSTR((char*)buff, header, sz);
766             if (headerEnd)
767                 *eccKey = 1;
768         }
769         if (!headerEnd && type == PRIVATEKEY_TYPE) {  /* may be dsa */
770             XSTRNCPY(header, "-----BEGIN DSA PRIVATE KEY-----", sizeof(header));
771             XSTRNCPY(footer, "-----END DSA PRIVATE KEY-----", sizeof(footer));
772         
773             headerEnd = XSTRNSTR((char*)buff, header, sz);
774         }
775         if (!headerEnd)
776             return SSL_BAD_FILE;
777         headerEnd += XSTRLEN(header);
778
779         /* get next line */
780         if (headerEnd[0] == '\n')
781             headerEnd++;
782         else if (headerEnd[1] == '\n')
783             headerEnd += 2;
784         else
785             return SSL_BAD_FILE;
786
787 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
788     {
789         /* remove encrypted header if there */
790         char encHeader[] = "Proc-Type";
791         char* line = XSTRNSTR((char*)buff, encHeader, PEM_LINE_LEN);
792         if (line) {
793             char* newline;
794             char* finish;
795             char* start  = XSTRNSTR(line, "DES", PEM_LINE_LEN);
796     
797             if (!start)
798                 start = XSTRNSTR(line, "AES", PEM_LINE_LEN);
799             
800             if (!start) return SSL_BAD_FILE;
801             if (!info)  return SSL_BAD_FILE;
802             
803             finish = XSTRNSTR(start, ",", PEM_LINE_LEN);
804
805             if (start && finish && (start < finish)) {
806                 newline = XSTRNSTR(finish, "\r", PEM_LINE_LEN);
807
808                 XMEMCPY(info->name, start, finish - start);
809                 info->name[finish - start] = 0;
810                 XMEMCPY(info->iv, finish + 1, sizeof(info->iv));
811
812                 if (!newline) newline = XSTRNSTR(finish, "\n", PEM_LINE_LEN);
813                 if (newline && (newline > finish)) {
814                     info->ivSz = (word32)(newline - (finish + 1));
815                     info->set = 1;
816                 }
817                 else
818                     return SSL_BAD_FILE;
819             }
820             else
821                 return SSL_BAD_FILE;
822
823             /* eat blank line */
824             while (*newline == '\r' || *newline == '\n')
825                 newline++;
826             headerEnd = newline;
827         }
828     }
829 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
830
831         /* find footer */
832         footerEnd = XSTRNSTR((char*)buff, footer, sz);
833         if (!footerEnd) return SSL_BAD_FILE;
834
835         consumedEnd = footerEnd + XSTRLEN(footer);
836
837         /* get next line */
838         if (consumedEnd[0] == '\n')
839             consumedEnd++;
840         else if (consumedEnd[1] == '\n')
841             consumedEnd += 2;
842         else
843             return SSL_BAD_FILE;
844
845         if (info)
846             info->consumed = (long)(consumedEnd - (char*)buff);
847
848         /* set up der buffer */
849         neededSz = (long)(footerEnd - headerEnd);
850         if (neededSz > sz || neededSz < 0) return SSL_BAD_FILE;
851         der->buffer = (byte*) XMALLOC(neededSz, heap, dynamicType);
852         if (!der->buffer) return MEMORY_ERROR;
853         der->length = neededSz;
854
855         if (Base64_Decode((byte*)headerEnd, neededSz, der->buffer,
856                           &der->length) < 0)
857             return SSL_BAD_FILE;
858
859         if (pkcs8)
860             return ToTraditional(der->buffer, der->length);
861
862 #ifdef OPENSSL_EXTRA
863          if (pkcs8Enc) {
864             int  passwordSz;
865             char password[80];
866
867             if (!info->ctx || !info->ctx->passwd_cb)
868                 return SSL_BAD_FILE;  /* no callback error */
869             passwordSz = info->ctx->passwd_cb(password, sizeof(password), 0,
870                                               info->ctx->userdata);
871             return ToTraditionalEnc(der->buffer, der->length, password,
872                                     passwordSz);
873          }
874 #endif
875
876         return 0;
877     }
878
879
880     /* process the buffer buff, legnth sz, into ctx of format and type
881        used tracks bytes consumed, userChain specifies a user cert chain
882        to pass during the handshake */
883     static int ProcessBuffer(CYASSL_CTX* ctx, const unsigned char* buff,
884                              long sz, int format, int type, CYASSL* ssl,
885                              long* used, int userChain)
886     {
887         EncryptedInfo info;
888         buffer        der;        /* holds DER or RAW (for NTRU) */
889         int           dynamicType = 0;
890         int           eccKey = 0;
891
892         info.set      = 0;
893         info.ctx      = ctx;
894         info.consumed = 0;
895         der.buffer    = 0;
896
897         (void)dynamicType;
898
899         if (used)
900             *used = sz;     /* used bytes default to sz, PEM chain may shorten*/
901
902         if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM 
903                                         && format != SSL_FILETYPE_RAW)
904             return SSL_BAD_FILETYPE;
905
906         if (type == CA_TYPE)
907             dynamicType = DYNAMIC_TYPE_CA;
908         else if (type == CERT_TYPE)
909             dynamicType = DYNAMIC_TYPE_CERT;
910         else
911             dynamicType = DYNAMIC_TYPE_KEY;
912
913         if (format == SSL_FILETYPE_PEM) {
914             int ret = PemToDer(buff, sz, type, &der, ctx->heap, &info, &eccKey);
915             if (ret < 0) {
916                 XFREE(der.buffer, ctx->heap, dynamicType);
917                 return ret;
918             }
919             if (used)
920                 *used = info.consumed;
921             /* we may have a user cert chain, try to consume */
922             if (userChain && type == CERT_TYPE && info.consumed < sz) {
923                 byte   staticBuffer[FILE_BUFFER_SIZE];  /* tmp chain buffer */
924                 byte*  chainBuffer = staticBuffer;
925                 int    dynamicBuffer = 0;
926                 word32 bufferSz = sizeof(staticBuffer);
927                 long   consumed = info.consumed;
928                 word32 idx = 0;
929
930                 if ( (sz - consumed) > (int)bufferSz) {
931                     CYASSL_MSG("Growing Tmp Chain Buffer");
932                     bufferSz = sz - consumed;  /* will shrink to actual size */
933                     chainBuffer = (byte*)XMALLOC(bufferSz, ctx->heap,
934                                                  DYNAMIC_FILE_TYPE);
935                     if (chainBuffer == NULL) {
936                         XFREE(der.buffer, ctx->heap, dynamicType);
937                         return MEMORY_E;
938                     }
939                     dynamicBuffer = 1;
940                 }
941
942                 CYASSL_MSG("Processing Cert Chain");
943                 while (consumed < sz) {
944                     long   left;
945                     buffer part;
946                     info.consumed = 0;
947                     part.buffer = 0;
948
949                     ret = PemToDer(buff + consumed, sz - consumed, type, &part,
950                                    ctx->heap, &info, &eccKey);
951                     if (ret == 0) {
952                         if ( (idx + part.length) > bufferSz) {
953                             CYASSL_MSG("   Cert Chain bigger than buffer");
954                             ret = BUFFER_E;
955                         }
956                         else {
957                             c32to24(part.length, &chainBuffer[idx]);
958                             idx += CERT_HEADER_SZ;
959                             XMEMCPY(&chainBuffer[idx], part.buffer,part.length);
960                             idx += part.length;
961                             consumed  += info.consumed;
962                             if (used)
963                                 *used += info.consumed;
964                         }
965                     }
966
967                     XFREE(part.buffer, ctx->heap, dynamicType);
968                     if (ret < 0) {
969                         CYASSL_MSG("   Error in Cert in Chain");
970                         XFREE(der.buffer, ctx->heap, dynamicType);
971                         return ret;
972                     }
973                     CYASSL_MSG("   Consumed another Cert in Chain");
974
975                     left = sz - consumed;
976                     if (left > 0 && left < CERT_MIN_SIZE) {
977                         CYASSL_MSG("   Non Cert at end of file");
978                         break;
979                     }
980                 }
981                 CYASSL_MSG("Finished Processing Cert Chain");
982                 ctx->certChain.buffer = (byte*)XMALLOC(idx, ctx->heap,
983                                                        dynamicType);
984                 if (ctx->certChain.buffer) {
985                     ctx->certChain.length = idx;
986                     XMEMCPY(ctx->certChain.buffer, chainBuffer, idx);
987                 }
988                 if (dynamicBuffer)
989                     XFREE(chainBuffer, ctx->heap, DYNAMIC_FILE_TYPE);
990                 if (ctx->certChain.buffer == NULL) {
991                     XFREE(der.buffer, ctx->heap, dynamicType);
992                     return MEMORY_E;
993                 }
994             }
995         }
996         else {  /* ASN1 (DER) or RAW (NTRU) */
997             der.buffer = (byte*) XMALLOC(sz, ctx->heap, dynamicType);
998             if (!der.buffer) return MEMORY_ERROR;
999             XMEMCPY(der.buffer, buff, sz);
1000             der.length = sz;
1001         }
1002
1003 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
1004         if (info.set) {
1005             /* decrypt */
1006             char password[80];
1007             int  passwordSz;
1008             int  ret;
1009
1010             byte key[AES_256_KEY_SIZE];
1011             byte  iv[AES_IV_SIZE];
1012
1013             if (!ctx->passwd_cb) {
1014                 XFREE(der.buffer, ctx->heap, dynamicType);
1015                 return NO_PASSWORD;
1016             }
1017
1018             /* use file's salt for key derivation, hex decode first */
1019             if (Base16_Decode(info.iv, info.ivSz, info.iv, &info.ivSz) != 0) {
1020                 XFREE(der.buffer, ctx->heap, dynamicType);
1021                 return ASN_INPUT_E;
1022             }
1023
1024             passwordSz = ctx->passwd_cb(password, sizeof(password), 0,
1025                                     ctx->userdata);
1026             if ( (ret = EVP_BytesToKey(info.name, "MD5", info.iv,
1027                             (byte*)password, passwordSz, 1, key, iv)) <= 0) {
1028                 XFREE(der.buffer, ctx->heap, dynamicType);
1029                 return ret;
1030             }
1031
1032             if (XSTRNCMP(info.name, "DES-CBC", 7) == 0) {
1033                 Des enc;
1034                 Des_SetKey(&enc, key, info.iv, DES_DECRYPTION);
1035                 Des_CbcDecrypt(&enc, der.buffer, der.buffer, der.length);
1036             }
1037             else if (XSTRNCMP(info.name, "DES-EDE3-CBC", 13) == 0) {
1038                 Des3 enc;
1039                 Des3_SetKey(&enc, key, info.iv, DES_DECRYPTION);
1040                 Des3_CbcDecrypt(&enc, der.buffer, der.buffer, der.length);
1041             }
1042             else if (XSTRNCMP(info.name, "AES-128-CBC", 13) == 0) {
1043                 Aes enc;
1044                 AesSetKey(&enc, key, AES_128_KEY_SIZE, info.iv, AES_DECRYPTION);
1045                 AesCbcDecrypt(&enc, der.buffer, der.buffer, der.length);
1046             }
1047             else if (XSTRNCMP(info.name, "AES-192-CBC", 13) == 0) {
1048                 Aes enc;
1049                 AesSetKey(&enc, key, AES_192_KEY_SIZE, info.iv, AES_DECRYPTION);
1050                 AesCbcDecrypt(&enc, der.buffer, der.buffer, der.length);
1051             }
1052             else if (XSTRNCMP(info.name, "AES-256-CBC", 13) == 0) {
1053                 Aes enc;
1054                 AesSetKey(&enc, key, AES_256_KEY_SIZE, info.iv, AES_DECRYPTION);
1055                 AesCbcDecrypt(&enc, der.buffer, der.buffer, der.length);
1056             }
1057             else { 
1058                 XFREE(der.buffer, ctx->heap, dynamicType);
1059                 return SSL_BAD_FILE;
1060             }
1061         }
1062 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
1063
1064         if (type == CA_TYPE)
1065             return AddCA(ctx->cm, der, CYASSL_USER_CA, ctx->verifyPeer);
1066                                                           /* takes der over */
1067         else if (type == CERT_TYPE) {
1068             if (ssl) {
1069                 if (ssl->buffers.weOwnCert && ssl->buffers.certificate.buffer)
1070                     XFREE(ssl->buffers.certificate.buffer, ctx->heap,
1071                           dynamicType);
1072                 ssl->buffers.certificate = der;
1073                 ssl->buffers.weOwnCert = 1;
1074             }
1075             else {
1076                 if (ctx->certificate.buffer)
1077                     XFREE(ctx->certificate.buffer, ctx->heap, dynamicType);
1078                 ctx->certificate = der;     /* takes der over */
1079             }
1080         }
1081         else if (type == PRIVATEKEY_TYPE) {
1082             if (ssl) {
1083                 if (ssl->buffers.weOwnKey && ssl->buffers.key.buffer)
1084                     XFREE(ssl->buffers.key.buffer, ctx->heap, dynamicType);
1085                 ssl->buffers.key = der;
1086                 ssl->buffers.weOwnKey = 1;
1087             }
1088             else {
1089                 if (ctx->privateKey.buffer)
1090                     XFREE(ctx->privateKey.buffer, ctx->heap, dynamicType);
1091                 ctx->privateKey = der;      /* takes der over */
1092             }
1093         }
1094         else {
1095             XFREE(der.buffer, ctx->heap, dynamicType);
1096             return SSL_BAD_CERTTYPE;
1097         }
1098
1099         if (type == PRIVATEKEY_TYPE && format != SSL_FILETYPE_RAW) {
1100             if (!eccKey) { 
1101                 /* make sure RSA key can be used */
1102                 RsaKey key;
1103                 word32 idx = 0;
1104         
1105                 InitRsaKey(&key, 0);
1106                 if (RsaPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) {
1107 #ifdef HAVE_ECC  
1108                     /* could have DER ECC (or pkcs8 ecc), no easy way to tell */
1109                     eccKey = 1;  /* so try it out */
1110 #endif
1111                     if (!eccKey) {
1112                         FreeRsaKey(&key);
1113                         return SSL_BAD_FILE;
1114                     }
1115                 }
1116                 FreeRsaKey(&key);
1117             }
1118 #ifdef HAVE_ECC  
1119             if (eccKey ) {
1120                 /* make sure ECC key can be used */
1121                 word32  idx = 0;
1122                 ecc_key key;
1123
1124                 ecc_init(&key);
1125                 if (EccPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) {
1126                     ecc_free(&key);
1127                     return SSL_BAD_FILE;
1128                 }
1129                 ecc_free(&key);
1130                 ctx->haveStaticECC = 1;
1131                 if (ssl)
1132                     ssl->options.haveStaticECC = 1;
1133             }
1134 #endif /* HAVE_ECC */
1135         }
1136         else if (type == CERT_TYPE) {
1137             int         ret;
1138             DecodedCert cert;
1139
1140             CYASSL_MSG("Checking cert signature type");
1141             InitDecodedCert(&cert, der.buffer, der.length, ctx->heap);
1142
1143             if ((ret = DecodeToKey(&cert, 0)) < 0) {
1144                 CYASSL_MSG("Decode to key failed");
1145                 return SSL_BAD_FILE; 
1146             }            
1147             switch (cert.signatureOID) {
1148                 case CTC_SHAwECDSA:
1149                 case CTC_SHA256wECDSA:
1150                 case CTC_SHA384wECDSA:
1151                 case CTC_SHA512wECDSA:
1152                     CYASSL_MSG("ECDSA cert signature");
1153                     ctx->haveECDSAsig = 1;
1154                     if (ssl)
1155                         ssl->options.haveECDSAsig = 1;
1156                     break;
1157                 default:
1158                     CYASSL_MSG("Not ECDSA cert signature");
1159                     break;
1160             }
1161
1162             FreeDecodedCert(&cert);
1163         }
1164
1165         return SSL_SUCCESS;
1166     }
1167
1168
1169
1170
1171 /* CA PEM file for verification, may have multiple/chain certs to process */
1172 static int ProcessChainBuffer(CYASSL_CTX* ctx, const unsigned char* buff,
1173                             long sz, int format, int type, CYASSL* ssl)
1174 {
1175     long used = 0;
1176     int  ret  = 0;
1177
1178     CYASSL_MSG("Processing CA PEM file");
1179     while (used < sz) {
1180         long consumed = 0;
1181         long left;
1182
1183         ret = ProcessBuffer(ctx, buff + used, sz - used, format, type, ssl,
1184                             &consumed, 0);
1185         if (ret < 0)
1186             break;
1187
1188         CYASSL_MSG("   Processed a CA");
1189         used += consumed;
1190
1191         left = sz - used;
1192         if (left > 0 && left < CERT_MIN_SIZE) { /* non cert stuff at eof */
1193             CYASSL_MSG("   Non CA cert at eof");
1194             break;
1195         }
1196     }
1197     return ret;
1198 }
1199
1200
1201 #ifndef NO_FILESYSTEM
1202
1203 #ifndef MICRIUM
1204     #define XFILE      FILE
1205     #define XFOPEN     fopen 
1206     #define XFSEEK     fseek
1207     #define XFTELL     ftell
1208     #define XREWIND    rewind
1209     #define XFREAD     fread
1210     #define XFCLOSE    fclose
1211     #define XSEEK_END  SEEK_END
1212 #else
1213     #include <fs.h>
1214     #define XFILE      FS_FILE
1215     #define XFOPEN     fs_fopen 
1216     #define XFSEEK     fs_fseek
1217     #define XFTELL     fs_ftell
1218     #define XREWIND    fs_rewind
1219     #define XFREAD     fs_fread
1220     #define XFCLOSE    fs_fclose
1221     #define XSEEK_END  FS_SEEK_END
1222 #endif
1223
1224
1225 /* process a file with name fname into ctx of format and type
1226    userChain specifies a user certificate chain to pass during handshake */
1227 int ProcessFile(CYASSL_CTX* ctx, const char* fname, int format, int type,
1228                 CYASSL* ssl, int userChain, CYASSL_CRL* crl)
1229 {
1230     byte   staticBuffer[FILE_BUFFER_SIZE];
1231     byte*  myBuffer = staticBuffer;
1232     int    dynamic = 0;
1233     int    ret;
1234     long   sz = 0;
1235     XFILE* file = XFOPEN(fname, "rb"); 
1236
1237     (void)crl;
1238
1239     if (!file) return SSL_BAD_FILE;
1240     XFSEEK(file, 0, XSEEK_END);
1241     sz = XFTELL(file);
1242     XREWIND(file);
1243
1244     if (sz > (long)sizeof(staticBuffer)) {
1245         CYASSL_MSG("Getting dynamic buffer");
1246         myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
1247         if (myBuffer == NULL) {
1248             XFCLOSE(file);
1249             return SSL_BAD_FILE;
1250         }
1251         dynamic = 1;
1252     }
1253
1254     if ( (ret = XFREAD(myBuffer, sz, 1, file)) < 0)
1255         ret = SSL_BAD_FILE;
1256     else {
1257         if (type == CA_TYPE && format == SSL_FILETYPE_PEM) 
1258             ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl);
1259 #ifdef HAVE_CRL
1260         else if (type == CRL_TYPE)
1261             ret = BufferLoadCRL(crl, myBuffer, sz, format);
1262 #endif
1263         else
1264             ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL,
1265                                 userChain);
1266     }
1267
1268     XFCLOSE(file);
1269     if (dynamic) XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
1270
1271     return ret;
1272 }
1273
1274
1275 /* loads file then loads each file in path, no c_rehash */
1276 int CyaSSL_CTX_load_verify_locations(CYASSL_CTX* ctx, const char* file,
1277                                      const char* path)
1278 {
1279     int ret = SSL_SUCCESS;
1280
1281     CYASSL_ENTER("CyaSSL_CTX_load_verify_locations");
1282     (void)path;
1283
1284     if (ctx == NULL || (file == NULL && path == NULL) )
1285         return SSL_FAILURE;
1286
1287     if (file)
1288         ret = ProcessFile(ctx, file, SSL_FILETYPE_PEM, CA_TYPE, NULL, 0, NULL);
1289
1290     if (ret == SSL_SUCCESS && path) {
1291         /* try to load each regular file in path */
1292     #ifdef USE_WINDOWS_API 
1293         WIN32_FIND_DATAA FindFileData;
1294         HANDLE hFind;
1295         char   name[MAX_FILENAME_SZ];
1296
1297         XMEMSET(name, 0, sizeof(name));
1298         XSTRNCPY(name, path, MAX_FILENAME_SZ - 4);
1299         XSTRNCAT(name, "\\*", 3);
1300
1301         hFind = FindFirstFileA(name, &FindFileData);
1302         if (hFind == INVALID_HANDLE_VALUE) {
1303             CYASSL_MSG("FindFirstFile for path verify locations failed");
1304             return BAD_PATH_ERROR;
1305         }
1306
1307         do {
1308             if (FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
1309                 XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 3);
1310                 XSTRNCAT(name, "\\", 2);
1311                 XSTRNCAT(name, FindFileData.cFileName, MAX_FILENAME_SZ/2);
1312
1313                 ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0,
1314                                   NULL);
1315             }
1316         } while (ret == SSL_SUCCESS && FindNextFileA(hFind, &FindFileData));
1317
1318         FindClose(hFind);
1319     #elif !defined(NO_CYASSL_DIR)
1320         struct dirent* entry;
1321         DIR*   dir = opendir(path);
1322
1323         if (dir == NULL) {
1324             CYASSL_MSG("opendir path verify locations failed");
1325             return BAD_PATH_ERROR;
1326         }
1327         while ( ret == SSL_SUCCESS && (entry = readdir(dir)) != NULL) {
1328             if (entry->d_type & DT_REG) {
1329                 char name[MAX_FILENAME_SZ];
1330
1331                 XMEMSET(name, 0, sizeof(name));
1332                 XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
1333                 XSTRNCAT(name, "/", 1);
1334                 XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
1335                 
1336                 ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0,
1337                                   NULL);
1338             }
1339         }
1340         closedir(dir);
1341     #endif
1342     }
1343
1344     return ret;
1345 }
1346
1347
1348 /* Verify the ceritficate, 1 for success, < 0 for error */
1349 int CyaSSL_CertManagerVerifyBuffer(CYASSL_CERT_MANAGER* cm, const byte* buff,
1350                                    int sz, int format)
1351 {
1352     int ret = 0;
1353     int eccKey = 0;  /* not used */
1354
1355     DecodedCert cert;
1356     buffer      der;
1357
1358     CYASSL_ENTER("CyaSSL_CertManagerVerifyBuffer");
1359
1360     der.buffer = NULL;
1361
1362     if (format == SSL_FILETYPE_PEM) { 
1363         EncryptedInfo info;
1364             
1365         info.set      = 0;
1366         info.ctx      = NULL;
1367         info.consumed = 0;
1368         ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, &info, &eccKey);
1369         InitDecodedCert(&cert, der.buffer, der.length, cm->heap);
1370     }
1371     else
1372         InitDecodedCert(&cert, (byte*)buff, sz, cm->heap);
1373
1374     if (ret == 0)
1375         ret = ParseCertRelative(&cert, CERT_TYPE, 1, cm);
1376 #ifdef HAVE_CRL
1377     if (ret == 0 && cm->crlEnabled)
1378         ret = CheckCertCRL(cm->crl, &cert);
1379 #endif
1380
1381     FreeDecodedCert(&cert);
1382     XFREE(der.buffer, cm->heap, DYNAMIC_TYPE_CERT);
1383
1384     return ret;
1385 }
1386
1387
1388 /* Verify the ceritficate, 1 for success, < 0 for error */
1389 int CyaSSL_CertManagerVerify(CYASSL_CERT_MANAGER* cm, const char* fname,
1390                              int format)
1391 {
1392     int    ret = SSL_FATAL_ERROR;
1393     byte   staticBuffer[FILE_BUFFER_SIZE];
1394     byte*  myBuffer = staticBuffer;
1395     int    dynamic = 0;
1396     long   sz = 0;
1397     XFILE* file = XFOPEN(fname, "rb"); 
1398
1399     CYASSL_ENTER("CyaSSL_CertManagerVerify");
1400
1401     if (!file) return SSL_BAD_FILE;
1402     XFSEEK(file, 0, XSEEK_END);
1403     sz = XFTELL(file);
1404     XREWIND(file);
1405
1406     if (sz > (long)sizeof(staticBuffer)) {
1407         CYASSL_MSG("Getting dynamic buffer");
1408         myBuffer = (byte*) XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE);
1409         if (myBuffer == NULL) {
1410             XFCLOSE(file);
1411             return SSL_BAD_FILE;
1412         }
1413         dynamic = 1;
1414     }
1415
1416     if ( (ret = XFREAD(myBuffer, sz, 1, file)) < 0)
1417         ret = SSL_BAD_FILE;
1418     else 
1419         ret = CyaSSL_CertManagerVerifyBuffer(cm, myBuffer, sz, format);
1420
1421     XFCLOSE(file);
1422     if (dynamic) XFREE(myBuffer, cm->heap, DYNAMIC_TYPE_FILE);
1423
1424     if (ret == 0)
1425         return SSL_SUCCESS;
1426     return ret;
1427 }
1428
1429
1430 /* like load verify locations, 1 for success, < 0 for error */
1431 int CyaSSL_CertManagerLoadCA(CYASSL_CERT_MANAGER* cm, const char* file,
1432                              const char* path)
1433 {
1434     int ret = SSL_FATAL_ERROR;
1435     CYASSL_CTX* tmp;
1436
1437     CYASSL_ENTER("CyaSSL_CertManagerLoadCA");
1438
1439     if (cm == NULL) {
1440         CYASSL_MSG("No CertManager error");
1441         return ret;
1442     }
1443     tmp = CyaSSL_CTX_new(CyaSSLv3_client_method());
1444
1445     if (tmp == NULL) {
1446         CYASSL_MSG("CTX new failed");
1447         return ret;
1448     }
1449
1450     /* for tmp use */
1451     CyaSSL_CertManagerFree(tmp->cm);
1452     tmp->cm = cm;
1453
1454     ret = CyaSSL_CTX_load_verify_locations(tmp, file, path);
1455
1456     /* don't loose our good one */
1457     tmp->cm = NULL;
1458     CyaSSL_CTX_free(tmp);
1459
1460     return ret;
1461 }
1462
1463
1464
1465 /* turn on CRL if off and compiled in, set options */
1466 int CyaSSL_CertManagerEnableCRL(CYASSL_CERT_MANAGER* cm, int options)
1467 {
1468     int ret = SSL_SUCCESS;
1469
1470     (void)options;
1471
1472     CYASSL_ENTER("CyaSSL_CertManagerEnableCRL");
1473     if (cm == NULL)
1474         return BAD_FUNC_ARG;
1475
1476     #ifdef HAVE_CRL
1477         if (cm->crl == NULL) {
1478             cm->crl = (CYASSL_CRL*)XMALLOC(sizeof(CYASSL_CRL), cm->heap,
1479                                            DYNAMIC_TYPE_CRL);
1480             if (cm->crl == NULL)
1481                 return MEMORY_E;
1482
1483             if (InitCRL(cm->crl, cm) != 0) {
1484                 CYASSL_MSG("Init CRL failed");
1485                 FreeCRL(cm->crl);
1486                 cm->crl = NULL;
1487                 return SSL_FAILURE;
1488             }
1489         }
1490         cm->crlEnabled = 1;
1491         if (options & CYASSL_CRL_CHECKALL)
1492             cm->crlCheckAll = 1;
1493     #else
1494         ret = NOT_COMPILED_IN;
1495     #endif
1496
1497     return ret;
1498 }
1499
1500
1501 int CyaSSL_CertManagerDisableCRL(CYASSL_CERT_MANAGER* cm)
1502 {
1503     CYASSL_ENTER("CyaSSL_CertManagerDisableCRL");
1504     if (cm == NULL)
1505         return BAD_FUNC_ARG;
1506
1507     cm->crlEnabled = 0;
1508
1509     return SSL_SUCCESS;
1510 }
1511
1512
1513 int CyaSSL_CTX_check_private_key(CYASSL_CTX* ctx)
1514 {
1515     /* TODO: check private against public for RSA match */
1516     (void)ctx; 
1517     CYASSL_ENTER("SSL_CTX_check_private_key");
1518     return SSL_SUCCESS;
1519 }
1520
1521
1522 #ifdef HAVE_CRL
1523
1524
1525 /* check CRL if enabled, SSL_SUCCESS  */
1526 int CyaSSL_CertManagerCheckCRL(CYASSL_CERT_MANAGER* cm, byte* der, int sz)
1527 {
1528     int         ret;
1529     DecodedCert cert;
1530
1531     CYASSL_ENTER("CyaSSL_CertManagerCheckCRL");
1532
1533     if (cm == NULL)
1534         return BAD_FUNC_ARG;
1535
1536     if (cm->crlEnabled == 0)
1537         return SSL_SUCCESS;
1538
1539     InitDecodedCert(&cert, der, sz, NULL);
1540
1541     ret = ParseCertRelative(&cert, CERT_TYPE, NO_VERIFY, cm);
1542     if (ret != 0) {
1543         CYASSL_MSG("ParseCert failed");
1544         return ret;
1545     }
1546     else {
1547         ret = CheckCertCRL(cm->crl, &cert);
1548         if (ret != 0) {
1549             CYASSL_MSG("CheckCertCRL failed");
1550         }
1551     }
1552
1553     FreeDecodedCert(&cert);
1554
1555     if (ret == 0)
1556         return SSL_SUCCESS;  /* convert */
1557
1558     return ret;
1559 }
1560
1561
1562 int CyaSSL_CertManagerSetCRL_Cb(CYASSL_CERT_MANAGER* cm, CbMissingCRL cb)
1563 {
1564     CYASSL_ENTER("CyaSSL_CertManagerSetCRL_Cb");
1565     if (cm == NULL)
1566         return BAD_FUNC_ARG;
1567
1568     cm->cbMissingCRL = cb;
1569
1570     return SSL_SUCCESS;
1571 }
1572
1573
1574 int CyaSSL_CertManagerLoadCRL(CYASSL_CERT_MANAGER* cm, const char* path,
1575                               int type, int monitor)
1576 {
1577     CYASSL_ENTER("CyaSSL_CertManagerLoadCRL");
1578     if (cm == NULL)
1579         return BAD_FUNC_ARG;
1580
1581     if (cm->crl == NULL) {
1582         if (CyaSSL_CertManagerEnableCRL(cm, 0) != SSL_SUCCESS) {
1583             CYASSL_MSG("Enable CRL failed");
1584             return -1;
1585         }
1586     }
1587
1588     return LoadCRL(cm->crl, path, type, monitor);
1589 }
1590
1591
1592 int CyaSSL_EnableCRL(CYASSL* ssl, int options)
1593 {
1594     CYASSL_ENTER("CyaSSL_EnableCRL");
1595     if (ssl)
1596         return CyaSSL_CertManagerEnableCRL(ssl->ctx->cm, options);
1597     else
1598         return BAD_FUNC_ARG;
1599 }
1600
1601
1602 int CyaSSL_DisableCRL(CYASSL* ssl)
1603 {
1604     CYASSL_ENTER("CyaSSL_DisableCRL");
1605     if (ssl)
1606         return CyaSSL_CertManagerDisableCRL(ssl->ctx->cm);
1607     else
1608         return BAD_FUNC_ARG;
1609 }
1610
1611
1612 int CyaSSL_LoadCRL(CYASSL* ssl, const char* path, int type, int monitor)
1613 {
1614     CYASSL_ENTER("CyaSSL_LoadCRL");
1615     if (ssl)
1616         return CyaSSL_CertManagerLoadCRL(ssl->ctx->cm, path, type, monitor);
1617     else
1618         return BAD_FUNC_ARG;
1619 }
1620
1621
1622 int CyaSSL_SetCRL_Cb(CYASSL* ssl, CbMissingCRL cb)
1623 {
1624     CYASSL_ENTER("CyaSSL_SetCRL_Cb");
1625     if (ssl)
1626         return CyaSSL_CertManagerSetCRL_Cb(ssl->ctx->cm, cb);
1627     else
1628         return BAD_FUNC_ARG;
1629 }
1630
1631
1632 int CyaSSL_CTX_EnableCRL(CYASSL_CTX* ctx, int options)
1633 {
1634     CYASSL_ENTER("CyaSSL_CTX_EnableCRL");
1635     if (ctx)
1636         return CyaSSL_CertManagerEnableCRL(ctx->cm, options);
1637     else
1638         return BAD_FUNC_ARG;
1639 }
1640
1641
1642 int CyaSSL_CTX_DisableCRL(CYASSL_CTX* ctx)
1643 {
1644     CYASSL_ENTER("CyaSSL_CTX_DisableCRL");
1645     if (ctx)
1646         return CyaSSL_CertManagerDisableCRL(ctx->cm);
1647     else
1648         return BAD_FUNC_ARG;
1649 }
1650
1651
1652 int CyaSSL_CTX_LoadCRL(CYASSL_CTX* ctx, const char* path, int type, int monitor)
1653 {
1654     CYASSL_ENTER("CyaSSL_CTX_LoadCRL");
1655     if (ctx)
1656         return CyaSSL_CertManagerLoadCRL(ctx->cm, path, type, monitor);
1657     else
1658         return BAD_FUNC_ARG;
1659 }
1660
1661
1662 int CyaSSL_CTX_SetCRL_Cb(CYASSL_CTX* ctx, CbMissingCRL cb)
1663 {
1664     CYASSL_ENTER("CyaSSL_CTX_SetCRL_Cb");
1665     if (ctx)
1666         return CyaSSL_CertManagerSetCRL_Cb(ctx->cm, cb);
1667     else
1668         return BAD_FUNC_ARG;
1669 }
1670
1671
1672 #endif /* HAVE_CRL */
1673
1674
1675 #ifdef CYASSL_DER_LOAD
1676
1677 /* Add format parameter to allow DER load of CA files */
1678 int CyaSSL_CTX_der_load_verify_locations(CYASSL_CTX* ctx, const char* file,
1679                                          int format)
1680 {
1681     CYASSL_ENTER("CyaSSL_CTX_der_load_verify_locations");
1682     if (ctx == NULL || file == NULL)
1683         return SSL_FAILURE;
1684
1685     if (ProcessFile(ctx, file, format, CA_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
1686         return SSL_SUCCESS;
1687
1688     return SSL_FAILURE;
1689 }
1690
1691 #endif /* CYASSL_DER_LOAD */
1692
1693
1694 #ifdef CYASSL_CERT_GEN
1695
1696 /* load pem cert from file into der buffer, return der size or error */
1697 int CyaSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz) 
1698 {
1699     byte   staticBuffer[FILE_BUFFER_SIZE];
1700     byte*  fileBuf = staticBuffer;
1701     int    dynamic = 0;
1702     int    ret;
1703     int    ecc = 0;
1704     long   sz = 0;
1705     XFILE* file = XFOPEN(fileName, "rb"); 
1706     EncryptedInfo info;
1707     buffer        converted;
1708
1709     CYASSL_ENTER("CyaSSL_PemCertToDer");
1710     converted.buffer = 0;
1711
1712     if (!file) return SSL_BAD_FILE;
1713     XFSEEK(file, 0, XSEEK_END);
1714     sz = XFTELL(file);
1715     XREWIND(file);
1716
1717     if (sz > (long)sizeof(staticBuffer)) {
1718         fileBuf = (byte*) XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
1719         if (fileBuf == NULL) {
1720             XFCLOSE(file);
1721             return SSL_BAD_FILE;
1722         }
1723         dynamic = 1;
1724     }
1725
1726     if ( (ret = XFREAD(fileBuf, sz, 1, file)) < 0)
1727         ret = SSL_BAD_FILE;
1728     else
1729         ret = PemToDer(fileBuf, sz, CA_TYPE, &converted, 0, &info, &ecc);
1730
1731     if (ret == 0) {
1732         if (converted.length < (word32)derSz) {
1733             XMEMCPY(derBuf, converted.buffer, converted.length);
1734             ret = converted.length;
1735         }
1736         else
1737             ret = BUFFER_E;
1738     }       
1739
1740     XFREE(converted.buffer, 0, DYNAMIC_TYPE_CA); 
1741     if (dynamic)
1742         XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE); 
1743     XFCLOSE(file);
1744
1745     return ret;
1746 }
1747
1748 #endif /* CYASSL_CERT_GEN */
1749
1750
1751 int CyaSSL_CTX_use_certificate_file(CYASSL_CTX* ctx, const char* file,
1752                                     int format)
1753 {
1754     CYASSL_ENTER("CyaSSL_CTX_use_certificate_file");
1755     if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
1756         return SSL_SUCCESS;
1757
1758     return SSL_FAILURE;
1759 }
1760
1761
1762 int CyaSSL_CTX_use_PrivateKey_file(CYASSL_CTX* ctx, const char* file,int format)
1763 {
1764     CYASSL_ENTER("CyaSSL_CTX_use_PrivateKey_file");
1765     if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL)
1766                     == SSL_SUCCESS)
1767         return SSL_SUCCESS;
1768
1769     return SSL_FAILURE;
1770 }
1771
1772
1773 int CyaSSL_CTX_use_certificate_chain_file(CYASSL_CTX* ctx, const char* file)
1774 {
1775    /* procces up to MAX_CHAIN_DEPTH plus subject cert */
1776    CYASSL_ENTER("CyaSSL_CTX_use_certificate_chain_file");
1777    if (ProcessFile(ctx, file, SSL_FILETYPE_PEM,CERT_TYPE,NULL,1, NULL)
1778                    == SSL_SUCCESS)
1779        return SSL_SUCCESS;
1780
1781    return SSL_FAILURE;
1782 }
1783
1784
1785 #ifdef OPENSSL_EXTRA
1786 /* put SSL type in extra for now, not very common */
1787
1788 int CyaSSL_use_certificate_file(CYASSL* ssl, const char* file, int format)
1789 {
1790     CYASSL_ENTER("CyaSSL_use_certificate_file");
1791     if (ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 0, NULL)
1792                     == SSL_SUCCESS)
1793         return SSL_SUCCESS;
1794
1795     return SSL_FAILURE;
1796 }
1797
1798
1799 int CyaSSL_use_PrivateKey_file(CYASSL* ssl, const char* file, int format)
1800 {
1801     CYASSL_ENTER("CyaSSL_use_PrivateKey_file");
1802     if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0, NULL)
1803                                                                  == SSL_SUCCESS)
1804         return SSL_SUCCESS;
1805
1806     return SSL_FAILURE;
1807 }
1808
1809
1810 int CyaSSL_use_certificate_chain_file(CYASSL* ssl, const char* file)
1811 {
1812    /* procces up to MAX_CHAIN_DEPTH plus subject cert */
1813    CYASSL_ENTER("CyaSSL_use_certificate_chain_file");
1814    if (ProcessFile(ssl->ctx, file, SSL_FILETYPE_PEM, CERT_TYPE, ssl, 1, NULL)
1815                                                                  == SSL_SUCCESS)
1816        return SSL_SUCCESS;
1817
1818    return SSL_FAILURE;
1819 }
1820
1821
1822 /* server wrapper for ctx or ssl Diffie-Hellman parameters */
1823 static int CyaSSL_SetTmpDH_buffer_wrapper(CYASSL_CTX* ctx, CYASSL* ssl,
1824                                   const unsigned char* buf, long sz, int format)
1825 {
1826     buffer der;
1827     int    ret;
1828     int    weOwnDer = 0;
1829     byte   p[MAX_DH_SIZE];
1830     byte   g[MAX_DH_SIZE];
1831     word32 pSz = sizeof(p);
1832     word32 gSz = sizeof(g);
1833
1834     der.buffer = (byte*)buf;
1835     der.length = sz;
1836
1837     if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM)
1838         return SSL_BAD_FILETYPE;
1839
1840     if (format == SSL_FILETYPE_PEM) {
1841         der.buffer = NULL;
1842         ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap, NULL,NULL);
1843         if (ret < 0) {
1844             XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
1845             return ret;
1846         }
1847         weOwnDer = 1;
1848     }
1849
1850     if (DhParamsLoad(der.buffer, der.length, p, &pSz, g, &gSz) < 0)
1851         ret = SSL_BAD_FILETYPE;
1852     else {
1853         if (ssl)
1854             ret = CyaSSL_SetTmpDH(ssl, p, pSz, g, gSz);
1855         else
1856             ret = CyaSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
1857     }
1858
1859     if (weOwnDer)
1860         XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
1861
1862     return ret;
1863 }
1864
1865 /* server Diffie-Hellman parameters */
1866 int CyaSSL_SetTmpDH_buffer(CYASSL* ssl, const unsigned char* buf, long sz,
1867                            int format)
1868 {
1869     return CyaSSL_SetTmpDH_buffer_wrapper(ssl->ctx, ssl, buf, sz, format);
1870 }
1871
1872
1873 /* server ctx Diffie-Hellman parameters */
1874 int CyaSSL_CTX_SetTmpDH_buffer(CYASSL_CTX* ctx, const unsigned char* buf,
1875                                long sz, int format)
1876 {
1877     return CyaSSL_SetTmpDH_buffer_wrapper(ctx, NULL, buf, sz, format);
1878 }
1879
1880
1881 #ifdef HAVE_ECC
1882
1883 /* Set Temp CTX EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
1884 int CyaSSL_CTX_SetTmpEC_DHE_Sz(CYASSL_CTX* ctx, word16 sz)
1885 {
1886     if (ctx == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
1887         return BAD_FUNC_ARG;
1888
1889     ctx->eccTempKeySz = sz;
1890
1891     return SSL_SUCCESS;
1892 }
1893
1894
1895 /* Set Temp SSL EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
1896 int CyaSSL_SetTmpEC_DHE_Sz(CYASSL* ssl, word16 sz)
1897 {
1898     if (ssl == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
1899         return BAD_FUNC_ARG;
1900
1901     ssl->eccTempKeySz = sz;
1902
1903     return SSL_SUCCESS;
1904 }
1905
1906 #endif /* HAVE_ECC */
1907
1908
1909 #if !defined(NO_FILESYSTEM)
1910
1911 /* server Diffie-Hellman parameters */
1912 static int CyaSSL_SetTmpDH_file_wrapper(CYASSL_CTX* ctx, CYASSL* ssl,
1913                                         const char* fname, int format)
1914 {
1915     byte   staticBuffer[FILE_BUFFER_SIZE];
1916     byte*  myBuffer = staticBuffer;
1917     int    dynamic = 0;
1918     int    ret;
1919     long   sz = 0;
1920     XFILE* file = XFOPEN(fname, "rb"); 
1921
1922     if (!file) return SSL_BAD_FILE;
1923     XFSEEK(file, 0, XSEEK_END);
1924     sz = XFTELL(file);
1925     XREWIND(file);
1926
1927     if (sz > (long)sizeof(staticBuffer)) {
1928         CYASSL_MSG("Getting dynamic buffer");
1929         myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
1930         if (myBuffer == NULL) {
1931             XFCLOSE(file);
1932             return SSL_BAD_FILE;
1933         }
1934         dynamic = 1;
1935     }
1936
1937     if ( (ret = XFREAD(myBuffer, sz, 1, file)) < 0)
1938         ret = SSL_BAD_FILE;
1939     else {
1940         if (ssl)
1941             ret = CyaSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format);
1942         else
1943             ret = CyaSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format);
1944     }
1945
1946     XFCLOSE(file);
1947     if (dynamic) XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
1948
1949     return ret;
1950 }
1951
1952 /* server Diffie-Hellman parameters */
1953 int CyaSSL_SetTmpDH_file(CYASSL* ssl, const char* fname, int format)
1954 {
1955     return CyaSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format);
1956 }
1957
1958
1959 /* server Diffie-Hellman parameters */
1960 int CyaSSL_CTX_SetTmpDH_file(CYASSL_CTX* ctx, const char* fname, int format)
1961 {
1962     return CyaSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format);
1963 }
1964
1965
1966 #endif /* !NO_FILESYSTEM */
1967 #endif /* OPENSSL_EXTRA */
1968
1969 #ifdef HAVE_NTRU
1970
1971 int CyaSSL_CTX_use_NTRUPrivateKey_file(CYASSL_CTX* ctx, const char* file)
1972 {
1973     CYASSL_ENTER("CyaSSL_CTX_use_NTRUPrivateKey_file");
1974     if (ProcessFile(ctx, file, SSL_FILETYPE_RAW, PRIVATEKEY_TYPE, NULL, 0, NULL)
1975                          == SSL_SUCCESS) {
1976         ctx->haveNTRU = 1;
1977         return SSL_SUCCESS;
1978     }
1979
1980     return SSL_FAILURE;
1981 }
1982
1983 #endif /* HAVE_NTRU */
1984
1985
1986
1987 #ifdef OPENSSL_EXTRA
1988
1989     int CyaSSL_CTX_use_RSAPrivateKey_file(CYASSL_CTX* ctx,const char* file,
1990                                        int format)
1991     {
1992         CYASSL_ENTER("SSL_CTX_use_RSAPrivateKey_file");
1993         if (ProcessFile(ctx, file,format,PRIVATEKEY_TYPE,NULL,0, NULL)
1994                         == SSL_SUCCESS)
1995             return SSL_SUCCESS;
1996
1997         return SSL_FAILURE;
1998     }
1999
2000     int CyaSSL_use_RSAPrivateKey_file(CYASSL* ssl, const char* file, int format)
2001     {
2002         CYASSL_ENTER("CyaSSL_use_RSAPrivateKey_file");
2003         if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0, NULL)
2004                                                                  == SSL_SUCCESS)
2005             return SSL_SUCCESS;
2006
2007         return SSL_FAILURE;
2008     }
2009
2010 #endif /* OPENSSL_EXTRA */
2011
2012 #endif /* NO_FILESYSTEM */
2013
2014
2015 void CyaSSL_CTX_set_verify(CYASSL_CTX* ctx, int mode, VerifyCallback vc)
2016 {
2017     CYASSL_ENTER("CyaSSL_CTX_set_verify");
2018     if (mode & SSL_VERIFY_PEER) {
2019         ctx->verifyPeer = 1;
2020         ctx->verifyNone = 0;  /* in case perviously set */
2021     }
2022
2023     if (mode == SSL_VERIFY_NONE) {
2024         ctx->verifyNone = 1;
2025         ctx->verifyPeer = 0;  /* in case previously set */
2026     }
2027
2028     if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
2029         ctx->failNoCert = 1;
2030
2031     ctx->verifyCallback = vc;
2032 }
2033
2034
2035 void CyaSSL_set_verify(CYASSL* ssl, int mode, VerifyCallback vc)
2036 {
2037     CYASSL_ENTER("CyaSSL_set_verify");
2038     if (mode & SSL_VERIFY_PEER) {
2039         ssl->options.verifyPeer = 1;
2040         ssl->options.verifyNone = 0;  /* in case perviously set */
2041     }
2042
2043     if (mode == SSL_VERIFY_NONE) {
2044         ssl->options.verifyNone = 1;
2045         ssl->options.verifyPeer = 0;  /* in case previously set */
2046     }
2047
2048     if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
2049         ssl->options.failNoCert = 1;
2050
2051     ssl->verifyCallback = vc;
2052 }
2053
2054
2055 /* store context CA Cache addition callback */
2056 void CyaSSL_CTX_SetCACb(CYASSL_CTX* ctx, CallbackCACache cb)
2057 {
2058     if (ctx && ctx->cm)
2059         ctx->cm->caCacheCallback = cb;
2060 }
2061
2062
2063 #ifndef NO_SESSION_CACHE
2064
2065 CYASSL_SESSION* CyaSSL_get_session(CYASSL* ssl)
2066 {
2067     CYASSL_ENTER("SSL_get_session");
2068     if (ssl)
2069         return GetSession(ssl, 0);
2070
2071     return NULL;
2072 }
2073
2074
2075 int CyaSSL_set_session(CYASSL* ssl, CYASSL_SESSION* session)
2076 {
2077     CYASSL_ENTER("SSL_set_session");
2078     if (session)
2079         return SetSession(ssl, session);
2080
2081     return SSL_FAILURE;
2082 }
2083
2084 #endif /* NO_SESSION_CACHE */
2085
2086
2087 void CyaSSL_load_error_strings(void)   /* compatibility only */
2088 {}
2089
2090
2091 int CyaSSL_library_init(void)
2092 {
2093     CYASSL_ENTER("SSL_library_init");
2094     if (CyaSSL_Init() == 0)
2095         return SSL_SUCCESS;
2096     else
2097         return SSL_FATAL_ERROR;
2098 }
2099
2100
2101 #ifndef NO_SESSION_CACHE
2102
2103 /* on by default if built in but allow user to turn off */
2104 long CyaSSL_CTX_set_session_cache_mode(CYASSL_CTX* ctx, long mode)
2105 {
2106     CYASSL_ENTER("SSL_CTX_set_session_cache_mode");
2107     if (mode == SSL_SESS_CACHE_OFF)
2108         ctx->sessionCacheOff = 1;
2109
2110     if (mode == SSL_SESS_CACHE_NO_AUTO_CLEAR)
2111         ctx->sessionCacheFlushOff = 1;
2112
2113     return SSL_SUCCESS;
2114 }
2115
2116 #endif /* NO_SESSION_CACHE */
2117
2118
2119 int CyaSSL_CTX_set_cipher_list(CYASSL_CTX* ctx, const char* list)
2120 {
2121     CYASSL_ENTER("CyaSSL_CTX_set_cipher_list");
2122     if (SetCipherList(&ctx->suites, list))
2123         return SSL_SUCCESS;
2124     else
2125         return SSL_FAILURE;
2126 }
2127
2128
2129 int CyaSSL_set_cipher_list(CYASSL* ssl, const char* list)
2130 {
2131     CYASSL_ENTER("CyaSSL_set_cipher_list");
2132     if (SetCipherList(&ssl->suites, list)) {
2133         byte havePSK = 0;
2134
2135         #ifndef NO_PSK
2136             havePSK = ssl->options.havePSK;
2137         #endif
2138
2139         InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK,
2140                    ssl->options.haveNTRU, ssl->options.haveECDSAsig,
2141                    ssl->options.haveStaticECC, ssl->options.side);
2142
2143         return SSL_SUCCESS;
2144     }
2145     else
2146         return SSL_FAILURE;
2147 }
2148
2149
2150 /* client only parts */
2151 #ifndef NO_CYASSL_CLIENT
2152
2153     CYASSL_METHOD* CyaSSLv3_client_method(void)
2154     {
2155         CYASSL_METHOD* method =
2156                               (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
2157                                                        DYNAMIC_TYPE_METHOD);
2158         CYASSL_ENTER("SSLv3_client_method");
2159         if (method)
2160             InitSSL_Method(method, MakeSSLv3());
2161         return method;
2162     }
2163
2164     #ifdef CYASSL_DTLS
2165         CYASSL_METHOD* CyaDTLSv1_client_method(void)
2166         {
2167             CYASSL_METHOD* method =
2168                               (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
2169                                                        DYNAMIC_TYPE_METHOD);
2170             CYASSL_ENTER("DTLSv1_client_method");
2171             if (method)
2172                 InitSSL_Method(method, MakeDTLSv1());
2173             return method;
2174         }
2175     #endif
2176
2177
2178     /* please see note at top of README if you get an error from connect */
2179     int CyaSSL_connect(CYASSL* ssl)
2180     {
2181         int neededState;
2182
2183         CYASSL_ENTER("SSL_connect()");
2184
2185         #ifdef HAVE_ERRNO_H 
2186             errno = 0;
2187         #endif
2188
2189         if (ssl->options.side != CLIENT_END) {
2190             CYASSL_ERROR(ssl->error = SIDE_ERROR);
2191             return SSL_FATAL_ERROR;
2192         }
2193
2194         #ifdef CYASSL_DTLS
2195             if (ssl->version.major == DTLS_MAJOR && 
2196                                       ssl->version.minor == DTLS_MINOR) {
2197                 ssl->options.dtls   = 1;
2198                 ssl->options.tls    = 1;
2199                 ssl->options.tls1_1 = 1;
2200             }
2201         #endif
2202
2203         if (ssl->buffers.outputBuffer.length > 0) {
2204             if ( (ssl->error = SendBuffered(ssl)) == 0) {
2205                 ssl->options.connectState++;
2206                 CYASSL_MSG("connect state: Advanced from buffered send");
2207             }
2208             else {
2209                 CYASSL_ERROR(ssl->error);
2210                 return SSL_FATAL_ERROR;
2211             }
2212         }
2213
2214         switch (ssl->options.connectState) {
2215
2216         case CONNECT_BEGIN :
2217             /* always send client hello first */
2218             if ( (ssl->error = SendClientHello(ssl)) != 0) {
2219                 CYASSL_ERROR(ssl->error);
2220                 return SSL_FATAL_ERROR;
2221             }
2222             ssl->options.connectState = CLIENT_HELLO_SENT;
2223             CYASSL_MSG("connect state: CLIENT_HELLO_SENT");
2224
2225         case CLIENT_HELLO_SENT :
2226             neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
2227                                           SERVER_HELLODONE_COMPLETE;
2228             #ifdef CYASSL_DTLS
2229                 if (ssl->options.dtls && !ssl->options.resuming)
2230                     neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
2231             #endif
2232             /* get response */
2233             while (ssl->options.serverState < neededState) {
2234                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
2235                     CYASSL_ERROR(ssl->error);
2236                     return SSL_FATAL_ERROR;
2237                 }
2238                 /* if resumption failed, reset needed state */
2239                 else if (neededState == SERVER_FINISHED_COMPLETE)
2240                     if (!ssl->options.resuming) {
2241                         if (!ssl->options.dtls)
2242                             neededState = SERVER_HELLODONE_COMPLETE;
2243                         else
2244                             neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
2245                     }
2246             }
2247
2248             ssl->options.connectState = HELLO_AGAIN;
2249             CYASSL_MSG("connect state: HELLO_AGAIN");
2250
2251         case HELLO_AGAIN :
2252             if (ssl->options.certOnly)
2253                 return SSL_SUCCESS;
2254
2255             #ifdef CYASSL_DTLS
2256                 if (ssl->options.dtls && !ssl->options.resuming) {
2257                     /* re-init hashes, exclude first hello and verify request */
2258                     InitMd5(&ssl->hashMd5);
2259                     InitSha(&ssl->hashSha);
2260                     #ifndef NO_SHA256
2261                         if (IsAtLeastTLSv1_2(ssl))
2262                             InitSha256(&ssl->hashSha256);
2263                     #endif
2264                     if ( (ssl->error = SendClientHello(ssl)) != 0) {
2265                         CYASSL_ERROR(ssl->error);
2266                         return SSL_FATAL_ERROR;
2267                     }
2268                 }
2269             #endif
2270
2271             ssl->options.connectState = HELLO_AGAIN_REPLY;
2272             CYASSL_MSG("connect state: HELLO_AGAIN_REPLY");
2273
2274         case HELLO_AGAIN_REPLY :
2275             #ifdef CYASSL_DTLS
2276                 if (ssl->options.dtls) {
2277                     neededState = ssl->options.resuming ?
2278                            SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
2279             
2280                     /* get response */
2281                     while (ssl->options.serverState < neededState) {
2282                         if ( (ssl->error = ProcessReply(ssl)) < 0) {
2283                                 CYASSL_ERROR(ssl->error);
2284                                 return SSL_FATAL_ERROR;
2285                         }
2286                         /* if resumption failed, reset needed state */
2287                         else if (neededState == SERVER_FINISHED_COMPLETE)
2288                             if (!ssl->options.resuming)
2289                                 neededState = SERVER_HELLODONE_COMPLETE;
2290                     }
2291                 }
2292             #endif
2293
2294             ssl->options.connectState = FIRST_REPLY_DONE;
2295             CYASSL_MSG("connect state: FIRST_REPLY_DONE");
2296
2297         case FIRST_REPLY_DONE :
2298             if (ssl->options.sendVerify)
2299                 if ( (ssl->error = SendCertificate(ssl)) != 0) {
2300                     CYASSL_ERROR(ssl->error);
2301                     return SSL_FATAL_ERROR;
2302                 }
2303
2304             ssl->options.connectState = FIRST_REPLY_FIRST;
2305             CYASSL_MSG("connect state: FIRST_REPLY_FIRST");
2306
2307         case FIRST_REPLY_FIRST :
2308             if (!ssl->options.resuming)
2309                 if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
2310                     CYASSL_ERROR(ssl->error);
2311                     return SSL_FATAL_ERROR;
2312                 }
2313
2314             ssl->options.connectState = FIRST_REPLY_SECOND;
2315             CYASSL_MSG("connect state: FIRST_REPLY_SECOND");
2316
2317         case FIRST_REPLY_SECOND :
2318             if (ssl->options.sendVerify)
2319                 if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
2320                     CYASSL_ERROR(ssl->error);
2321                     return SSL_FATAL_ERROR;
2322             }
2323             ssl->options.connectState = FIRST_REPLY_THIRD;
2324             CYASSL_MSG("connect state: FIRST_REPLY_THIRD");
2325
2326         case FIRST_REPLY_THIRD :
2327             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
2328                 CYASSL_ERROR(ssl->error);
2329                 return SSL_FATAL_ERROR;
2330             }
2331             ssl->options.connectState = FIRST_REPLY_FOURTH;
2332             CYASSL_MSG("connect state: FIRST_REPLY_FOURTH");
2333
2334         case FIRST_REPLY_FOURTH :
2335             if ( (ssl->error = SendFinished(ssl)) != 0) {
2336                 CYASSL_ERROR(ssl->error);
2337                 return SSL_FATAL_ERROR;
2338             }
2339
2340             ssl->options.connectState = FINISHED_DONE;
2341             CYASSL_MSG("connect state: FINISHED_DONE");
2342
2343         case FINISHED_DONE :
2344             /* get response */
2345             while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
2346                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
2347                     CYASSL_ERROR(ssl->error);
2348                     return SSL_FATAL_ERROR;
2349                 }
2350           
2351             ssl->options.connectState = SECOND_REPLY_DONE;
2352             CYASSL_MSG("connect state: SECOND_REPLY_DONE");
2353
2354         case SECOND_REPLY_DONE:
2355             if (ssl->buffers.inputBuffer.dynamicFlag)
2356                 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
2357             CYASSL_LEAVE("SSL_connect()", SSL_SUCCESS);
2358             return SSL_SUCCESS;
2359
2360         default:
2361             CYASSL_MSG("Unknown connect state ERROR");
2362             return SSL_FATAL_ERROR; /* unknown connect state */
2363         }
2364     }
2365
2366 #endif /* NO_CYASSL_CLIENT */
2367
2368
2369 /* server only parts */
2370 #ifndef NO_CYASSL_SERVER
2371
2372     CYASSL_METHOD* CyaSSLv3_server_method(void)
2373     {
2374         CYASSL_METHOD* method =
2375                               (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
2376                                                        DYNAMIC_TYPE_METHOD);
2377         CYASSL_ENTER("SSLv3_server_method");
2378         if (method) {
2379             InitSSL_Method(method, MakeSSLv3());
2380             method->side = SERVER_END;
2381         }
2382         return method;
2383     }
2384
2385
2386     #ifdef CYASSL_DTLS
2387         CYASSL_METHOD* CyaDTLSv1_server_method(void)
2388         {
2389             CYASSL_METHOD* method =
2390                               (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
2391                                                        DYNAMIC_TYPE_METHOD);
2392             CYASSL_ENTER("DTLSv1_server_method");
2393             if (method) {
2394                 InitSSL_Method(method, MakeDTLSv1());
2395                 method->side = SERVER_END;
2396             }
2397             return method;
2398         }
2399     #endif
2400
2401
2402     int CyaSSL_accept(CYASSL* ssl)
2403     {
2404         byte havePSK = 0;
2405         CYASSL_ENTER("SSL_accept()");
2406
2407         #ifdef HAVE_ERRNO_H 
2408             errno = 0;
2409         #endif
2410
2411         #ifndef NO_PSK
2412             havePSK = ssl->options.havePSK;
2413         #endif
2414
2415         if (ssl->options.side != SERVER_END) {
2416             CYASSL_ERROR(ssl->error = SIDE_ERROR);
2417             return SSL_FATAL_ERROR;
2418         }
2419
2420         /* in case used set_accept_state after init */
2421         if (!havePSK && (ssl->buffers.certificate.buffer == NULL ||
2422                          ssl->buffers.key.buffer == NULL)) {
2423             CYASSL_MSG("accept error: don't have server cert and key");
2424             ssl->error = NO_PRIVATE_KEY;
2425             CYASSL_ERROR(ssl->error);
2426             return SSL_FATAL_ERROR;
2427         }
2428
2429         #ifdef HAVE_ECC
2430             /* in case used set_accept_state after init */
2431             if (ssl->eccTempKeyPresent == 0) {
2432                 if (ecc_make_key(&ssl->rng, ssl->eccTempKeySz,
2433                                  &ssl->eccTempKey) != 0) {
2434                     ssl->error = ECC_MAKEKEY_ERROR;
2435                     CYASSL_ERROR(ssl->error);
2436                     return SSL_FATAL_ERROR; 
2437                 } 
2438                 ssl->eccTempKeyPresent = 1;
2439             }
2440         #endif
2441
2442         #ifdef CYASSL_DTLS
2443             if (ssl->version.major == DTLS_MAJOR &&
2444                                       ssl->version.minor == DTLS_MINOR) {
2445                 ssl->options.dtls   = 1;
2446                 ssl->options.tls    = 1;
2447                 ssl->options.tls1_1 = 1;
2448             }
2449         #endif
2450
2451         if (ssl->buffers.outputBuffer.length > 0) {
2452             if ( (ssl->error = SendBuffered(ssl)) == 0) {
2453                 ssl->options.acceptState++;
2454                 CYASSL_MSG("accept state: Advanced from buffered send");
2455             }
2456             else {
2457                 CYASSL_ERROR(ssl->error);
2458                 return SSL_FATAL_ERROR;
2459             }
2460         }
2461
2462         switch (ssl->options.acceptState) {
2463     
2464         case ACCEPT_BEGIN :
2465             /* get response */
2466             while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
2467                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
2468                     CYASSL_ERROR(ssl->error);
2469                     return SSL_FATAL_ERROR;
2470                 }
2471             ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
2472             CYASSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
2473
2474         case ACCEPT_CLIENT_HELLO_DONE :
2475             #ifdef CYASSL_DTLS
2476                 if (ssl->options.dtls && !ssl->options.resuming)
2477                     if ( (ssl->error = SendHelloVerifyRequest(ssl)) != 0) {
2478                         CYASSL_ERROR(ssl->error);
2479                         return SSL_FATAL_ERROR;
2480                     }
2481             #endif
2482             ssl->options.acceptState = HELLO_VERIFY_SENT;
2483             CYASSL_MSG("accept state HELLO_VERIFY_SENT");
2484
2485         case HELLO_VERIFY_SENT:
2486             #ifdef CYASSL_DTLS
2487                 if (ssl->options.dtls && !ssl->options.resuming) {
2488                     ssl->options.clientState = NULL_STATE;  /* get again */
2489                     /* re-init hashes, exclude first hello and verify request */
2490                     InitMd5(&ssl->hashMd5);
2491                     InitSha(&ssl->hashSha);
2492                     #ifndef NO_SHA256
2493                         if (IsAtLeastTLSv1_2(ssl))
2494                             InitSha256(&ssl->hashSha256);
2495                     #endif
2496
2497                     while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
2498                         if ( (ssl->error = ProcessReply(ssl)) < 0) {
2499                             CYASSL_ERROR(ssl->error);
2500                             return SSL_FATAL_ERROR;
2501                         }
2502                 }
2503             #endif
2504             ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
2505             CYASSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
2506
2507         case ACCEPT_FIRST_REPLY_DONE :
2508             if ( (ssl->error = SendServerHello(ssl)) != 0) {
2509                 CYASSL_ERROR(ssl->error);
2510                 return SSL_FATAL_ERROR;
2511             }
2512             ssl->options.acceptState = SERVER_HELLO_SENT;
2513             CYASSL_MSG("accept state SERVER_HELLO_SENT");
2514
2515         case SERVER_HELLO_SENT :
2516             if (!ssl->options.resuming) 
2517                 if ( (ssl->error = SendCertificate(ssl)) != 0) {
2518                     CYASSL_ERROR(ssl->error);
2519                     return SSL_FATAL_ERROR;
2520                 }
2521             ssl->options.acceptState = CERT_SENT;
2522             CYASSL_MSG("accept state CERT_SENT");
2523
2524         case CERT_SENT :
2525             if (!ssl->options.resuming) 
2526                 if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
2527                     CYASSL_ERROR(ssl->error);
2528                     return SSL_FATAL_ERROR;
2529                 }
2530             ssl->options.acceptState = KEY_EXCHANGE_SENT;
2531             CYASSL_MSG("accept state KEY_EXCHANGE_SENT");
2532
2533         case KEY_EXCHANGE_SENT :
2534             if (!ssl->options.resuming) 
2535                 if (ssl->options.verifyPeer)
2536                     if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
2537                         CYASSL_ERROR(ssl->error);
2538                         return SSL_FATAL_ERROR;
2539                     }
2540             ssl->options.acceptState = CERT_REQ_SENT;
2541             CYASSL_MSG("accept state CERT_REQ_SENT");
2542
2543         case CERT_REQ_SENT :
2544             if (!ssl->options.resuming) 
2545                 if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
2546                     CYASSL_ERROR(ssl->error);
2547                     return SSL_FATAL_ERROR;
2548                 }
2549             ssl->options.acceptState = SERVER_HELLO_DONE;
2550             CYASSL_MSG("accept state SERVER_HELLO_DONE");
2551
2552         case SERVER_HELLO_DONE :
2553             if (!ssl->options.resuming) {
2554                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
2555                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
2556                         CYASSL_ERROR(ssl->error);
2557                         return SSL_FATAL_ERROR;
2558                     }
2559             }
2560             ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
2561             CYASSL_MSG("accept state  ACCEPT_SECOND_REPLY_DONE");
2562           
2563         case ACCEPT_SECOND_REPLY_DONE : 
2564             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
2565                 CYASSL_ERROR(ssl->error);
2566                 return SSL_FATAL_ERROR;
2567             }
2568             ssl->options.acceptState = CHANGE_CIPHER_SENT;
2569             CYASSL_MSG("accept state  CHANGE_CIPHER_SENT");
2570
2571         case CHANGE_CIPHER_SENT : 
2572             if ( (ssl->error = SendFinished(ssl)) != 0) {
2573                 CYASSL_ERROR(ssl->error);
2574                 return SSL_FATAL_ERROR;
2575             }
2576
2577             ssl->options.acceptState = ACCEPT_FINISHED_DONE;
2578             CYASSL_MSG("accept state ACCEPT_FINISHED_DONE");
2579
2580         case ACCEPT_FINISHED_DONE :
2581             if (ssl->options.resuming)
2582                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
2583                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
2584                         CYASSL_ERROR(ssl->error);
2585                         return SSL_FATAL_ERROR;
2586                     }
2587
2588             ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
2589             CYASSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
2590
2591         case ACCEPT_THIRD_REPLY_DONE :
2592             if (ssl->buffers.inputBuffer.dynamicFlag)
2593                 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
2594             CYASSL_LEAVE("SSL_accept()", SSL_SUCCESS);
2595             return SSL_SUCCESS;
2596
2597         default :
2598             CYASSL_MSG("Unknown accept state ERROR");
2599             return SSL_FATAL_ERROR;
2600         }
2601     }
2602
2603 #endif /* NO_CYASSL_SERVER */
2604
2605 /* prevent multiple mutex initializations */
2606 static volatile int initRefCount = 0;
2607 static CyaSSL_Mutex count_mutex;   /* init ref count mutex */
2608
2609 int CyaSSL_Init(void)
2610 {
2611     int ret = 0;
2612
2613     CYASSL_ENTER("CyaSSL_Init");
2614
2615     if (initRefCount == 0) {
2616 #ifndef NO_SESSION_CACHE
2617         if (InitMutex(&session_mutex) != 0)
2618             ret = BAD_MUTEX_ERROR;
2619 #endif
2620         if (InitMutex(&count_mutex) != 0)
2621             ret = BAD_MUTEX_ERROR;
2622     }
2623     if (ret == 0) {
2624         LockMutex(&count_mutex);
2625         initRefCount++;
2626         UnLockMutex(&count_mutex);
2627     }
2628
2629     return ret;
2630 }
2631
2632
2633 int CyaSSL_Cleanup(void)
2634 {
2635     int ret = 0;
2636     int release = 0;
2637
2638     CYASSL_ENTER("CyaSSL_Cleanup");
2639
2640     LockMutex(&count_mutex);
2641
2642     release = initRefCount-- == 1;
2643     if (initRefCount < 0)
2644         initRefCount = 0;
2645
2646     UnLockMutex(&count_mutex);
2647
2648     if (!release)
2649         return ret;
2650
2651 #ifndef NO_SESSION_CACHE
2652     if (FreeMutex(&session_mutex) != 0)
2653         ret = BAD_MUTEX_ERROR;
2654 #endif
2655     if (FreeMutex(&count_mutex) != 0)
2656         ret = BAD_MUTEX_ERROR;
2657
2658     return ret;
2659 }
2660
2661
2662 #ifndef NO_SESSION_CACHE
2663
2664
2665 static INLINE word32 HashSession(const byte* sessionID)
2666 {
2667     /* id is random, just make 32 bit number from first 4 bytes for now */
2668     return (sessionID[0] << 24) | (sessionID[1] << 16) | (sessionID[2] <<  8) |
2669             sessionID[3];
2670 }
2671
2672
2673 void CyaSSL_flush_sessions(CYASSL_CTX* ctx, long tm)
2674 {
2675     /* static table now, no flusing needed */
2676     (void)ctx;
2677     (void)tm;
2678 }
2679
2680
2681 /* set ssl session timeout in seconds */
2682 int CyaSSL_set_timeout(CYASSL* ssl, unsigned int to)
2683 {
2684     if (ssl == NULL)
2685         return BAD_FUNC_ARG;
2686
2687     ssl->timeout = to;
2688
2689     return SSL_SUCCESS;
2690 }
2691
2692
2693 /* set ctx session timeout in seconds */
2694 int CyaSSL_CTX_set_timeout(CYASSL_CTX* ctx, unsigned int to)
2695 {
2696     if (ctx == NULL)
2697         return BAD_FUNC_ARG;
2698
2699     ctx->timeout = to;
2700
2701     return SSL_SUCCESS;
2702 }
2703
2704
2705 CYASSL_SESSION* GetSession(CYASSL* ssl, byte* masterSecret)
2706 {
2707     CYASSL_SESSION* ret = 0;
2708     const byte*  id = ssl->arrays.sessionID;
2709     word32       row;
2710     int          idx;
2711     
2712     if (ssl->options.sessionCacheOff)
2713         return NULL;
2714
2715     if (ssl->options.haveSessionId == 0)
2716         return NULL;
2717
2718     row = HashSession(id) % SESSION_ROWS;
2719
2720     if (LockMutex(&session_mutex) != 0)
2721         return 0;
2722    
2723     if (SessionCache[row].totalCount >= SESSIONS_PER_ROW)
2724         idx = SESSIONS_PER_ROW - 1;
2725     else
2726         idx = SessionCache[row].nextIdx - 1;
2727
2728     for (; idx >= 0; idx--) {
2729         CYASSL_SESSION* current;
2730         
2731         if (idx >= SESSIONS_PER_ROW)    /* server could have restarted, idx  */
2732             break;                      /* would be word32(-1) and seg fault */
2733         
2734         current = &SessionCache[row].Sessions[idx];
2735         if (XMEMCMP(current->sessionID, id, ID_LEN) == 0) {
2736             if (LowResTimer() < (current->bornOn + current->timeout)) {
2737                 ret = current;
2738                 if (masterSecret)
2739                     XMEMCPY(masterSecret, current->masterSecret, SECRET_LEN);
2740             }
2741             break;
2742         }   
2743     }
2744
2745     UnLockMutex(&session_mutex);
2746     
2747     return ret;
2748 }
2749
2750
2751 int SetSession(CYASSL* ssl, CYASSL_SESSION* session)
2752 {
2753     if (ssl->options.sessionCacheOff)
2754         return SSL_FAILURE;
2755
2756     if (LowResTimer() < (session->bornOn + session->timeout)) {
2757         ssl->session  = *session;
2758         ssl->options.resuming = 1;
2759
2760 #ifdef SESSION_CERTS
2761         ssl->version              = session->version;
2762         ssl->options.cipherSuite0 = session->cipherSuite0;
2763         ssl->options.cipherSuite  = session->cipherSuite;
2764 #endif
2765
2766         return SSL_SUCCESS;
2767     }
2768     return SSL_FAILURE;  /* session timed out */
2769 }
2770
2771
2772 int AddSession(CYASSL* ssl)
2773 {
2774     word32 row, idx;
2775
2776     if (ssl->options.sessionCacheOff)
2777         return 0;
2778
2779     if (ssl->options.haveSessionId == 0)
2780         return 0;
2781
2782     row = HashSession(ssl->arrays.sessionID) % SESSION_ROWS;
2783
2784     if (LockMutex(&session_mutex) != 0)
2785         return BAD_MUTEX_ERROR;
2786
2787     idx = SessionCache[row].nextIdx++;
2788
2789     XMEMCPY(SessionCache[row].Sessions[idx].masterSecret,
2790            ssl->arrays.masterSecret, SECRET_LEN);
2791     XMEMCPY(SessionCache[row].Sessions[idx].sessionID, ssl->arrays.sessionID,
2792            ID_LEN);
2793
2794     SessionCache[row].Sessions[idx].timeout = ssl->timeout;
2795     SessionCache[row].Sessions[idx].bornOn  = LowResTimer();
2796
2797 #ifdef SESSION_CERTS
2798     SessionCache[row].Sessions[idx].chain.count = ssl->session.chain.count;
2799     XMEMCPY(SessionCache[row].Sessions[idx].chain.certs,
2800            ssl->session.chain.certs, sizeof(x509_buffer) * MAX_CHAIN_DEPTH);
2801
2802     SessionCache[row].Sessions[idx].version      = ssl->version;
2803     SessionCache[row].Sessions[idx].cipherSuite0 = ssl->options.cipherSuite0;
2804     SessionCache[row].Sessions[idx].cipherSuite  = ssl->options.cipherSuite;
2805 #endif
2806
2807     SessionCache[row].totalCount++;
2808     if (SessionCache[row].nextIdx == SESSIONS_PER_ROW)
2809         SessionCache[row].nextIdx = 0;
2810
2811     if (UnLockMutex(&session_mutex) != 0)
2812         return BAD_MUTEX_ERROR;
2813
2814     return 0;
2815 }
2816
2817
2818     #ifdef SESSION_STATS
2819
2820     CYASSL_API
2821     void PrintSessionStats(void)
2822     {
2823         word32 totalSessionsSeen = 0;
2824         word32 totalSessionsNow = 0;
2825         word32 rowNow;
2826         int    i;
2827         double E;               /* expected freq */
2828         double chiSquare = 0;
2829         
2830         for (i = 0; i < SESSION_ROWS; i++) {
2831             totalSessionsSeen += SessionCache[i].totalCount;
2832
2833             if (SessionCache[i].totalCount >= SESSIONS_PER_ROW)
2834                 rowNow = SESSIONS_PER_ROW;
2835             else if (SessionCache[i].nextIdx == 0)
2836                 rowNow = 0;
2837             else
2838                 rowNow = SessionCache[i].nextIdx;
2839         
2840             totalSessionsNow += rowNow;
2841         }
2842
2843         printf("Total Sessions Seen = %d\n", totalSessionsSeen);
2844         printf("Total Sessions Now  = %d\n", totalSessionsNow);
2845
2846         E = (double)totalSessionsSeen / SESSION_ROWS;
2847
2848         for (i = 0; i < SESSION_ROWS; i++) {
2849             double diff = SessionCache[i].totalCount - E;
2850             diff *= diff;                /* square    */
2851             diff /= E;                   /* normalize */
2852
2853             chiSquare += diff;
2854         }
2855         printf("  chi-square = %5.1f, d.f. = %d\n", chiSquare,
2856                                                      SESSION_ROWS - 1);
2857         if (SESSION_ROWS == 11)
2858             printf(" .05 p value =  18.3, chi-square should be less\n");
2859         else if (SESSION_ROWS == 211)
2860             printf(".05 p value  = 244.8, chi-square should be less\n");
2861         else if (SESSION_ROWS == 5981)
2862             printf(".05 p value  = 6161.0, chi-square should be less\n");
2863         else if (SESSION_ROWS == 3)
2864             printf(".05 p value  =   6.0, chi-square should be less\n");
2865         else if (SESSION_ROWS == 2861)
2866             printf(".05 p value  = 2985.5, chi-square should be less\n");
2867         printf("\n");
2868     }
2869
2870     #endif /* SESSION_STATS */
2871
2872 #else  /* NO_SESSION_CACHE */
2873
2874 /* No session cache version */
2875 CYASSL_SESSION* GetSession(CYASSL* ssl, byte* masterSecret)
2876 {
2877     return NULL;  
2878 }
2879
2880 #endif /* NO_SESSION_CACHE */
2881
2882
2883 /* call before SSL_connect, if verifying will add name check to
2884    date check and signature check */
2885 int CyaSSL_check_domain_name(CYASSL* ssl, const char* dn)
2886 {
2887     CYASSL_ENTER("CyaSSL_check_domain_name");
2888     if (ssl->buffers.domainName.buffer)
2889         XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
2890
2891     ssl->buffers.domainName.length = (word32)XSTRLEN(dn) + 1;
2892     ssl->buffers.domainName.buffer = (byte*) XMALLOC(
2893                 ssl->buffers.domainName.length, ssl->heap, DYNAMIC_TYPE_DOMAIN);
2894
2895     if (ssl->buffers.domainName.buffer) {
2896         XSTRNCPY((char*)ssl->buffers.domainName.buffer, dn,
2897                 ssl->buffers.domainName.length);
2898         return SSL_SUCCESS;
2899     }
2900     else {
2901         ssl->error = MEMORY_ERROR;
2902         return SSL_FAILURE;
2903     }
2904 }
2905
2906
2907 /* turn on CyaSSL zlib compression
2908    returns 0 for success, else error (not built in)
2909 */
2910 int CyaSSL_set_compression(CYASSL* ssl)
2911 {
2912     CYASSL_ENTER("CyaSSL_set_compression");
2913     (void)ssl;
2914 #ifdef HAVE_LIBZ
2915     ssl->options.usingCompression = 1;
2916     return 0;
2917 #else
2918     return NOT_COMPILED_IN;
2919 #endif
2920 }
2921
2922
2923 #ifndef USE_WINDOWS_API 
2924     #ifndef NO_WRITEV
2925
2926         /* simulate writev semantics, doesn't actually do block at a time though
2927            because of SSL_write behavior and because front adds may be small */
2928         int CyaSSL_writev(CYASSL* ssl, const struct iovec* iov, int iovcnt)
2929         {
2930             byte  tmp[OUTPUT_RECORD_SIZE];
2931             byte* myBuffer    = tmp;
2932             int   send      = 0;
2933             int   newBuffer = 0;
2934             int   idx       = 0;
2935             int   i;
2936             int   ret;
2937
2938             CYASSL_ENTER("CyaSSL_writev");
2939
2940             for (i = 0; i < iovcnt; i++)
2941                 send += iov[i].iov_len;
2942
2943             if (send > (int)sizeof(tmp)) {
2944                 byte* tmp2 = (byte*) XMALLOC(send, ssl->heap,
2945                                              DYNAMIC_TYPE_WRITEV);
2946                 if (!tmp2)
2947                     return MEMORY_ERROR;
2948                 myBuffer = tmp2;
2949                 newBuffer = 1;
2950             }
2951
2952             for (i = 0; i < iovcnt; i++) {
2953                 XMEMCPY(&myBuffer[idx], iov[i].iov_base, iov[i].iov_len);
2954                 idx += iov[i].iov_len;
2955             }
2956
2957             ret = CyaSSL_write(ssl, myBuffer, send);
2958
2959             if (newBuffer) XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
2960
2961             return ret;
2962         }
2963     #endif
2964 #endif
2965
2966
2967 #ifdef CYASSL_CALLBACKS
2968
2969     typedef struct itimerval Itimerval;
2970
2971     /* don't keep calling simple functions while setting up timer and singals
2972        if no inlining these are the next best */
2973
2974     #define AddTimes(a, b, c)                       \
2975         do {                                        \
2976             c.tv_sec  = a.tv_sec  + b.tv_sec;       \
2977             c.tv_usec = a.tv_usec + b.tv_usec;      \
2978             if (c.tv_sec >=  1000000) {             \
2979                 c.tv_sec++;                         \
2980                 c.tv_usec -= 1000000;               \
2981             }                                       \
2982         } while (0)
2983
2984
2985     #define SubtractTimes(a, b, c)                  \
2986         do {                                        \
2987             c.tv_sec  = a.tv_sec  - b.tv_sec;       \
2988             c.tv_usec = a.tv_usec - b.tv_usec;      \
2989             if (c.tv_sec < 0) {                     \
2990                 c.tv_sec--;                         \
2991                 c.tv_usec += 1000000;               \
2992             }                                       \
2993         } while (0)
2994
2995     #define CmpTimes(a, b, cmp)                     \
2996         ((a.tv_sec  ==  b.tv_sec) ?                 \
2997             (a.tv_usec cmp b.tv_usec) :             \
2998             (a.tv_sec  cmp b.tv_sec))               \
2999
3000
3001     /* do nothing handler */
3002     static void myHandler(int signo)
3003     {
3004         return;
3005     }
3006
3007
3008     static int CyaSSL_ex_wrapper(CYASSL* ssl, HandShakeCallBack hsCb,
3009                                  TimeoutCallBack toCb, Timeval timeout)
3010     {
3011         int       ret        = SSL_FATAL_ERROR;
3012         int       oldTimerOn = 0;   /* was timer already on */
3013         Timeval   startTime;
3014         Timeval   endTime;
3015         Timeval   totalTime;
3016         Itimerval myTimeout;
3017         Itimerval oldTimeout; /* if old timer adjust from total time to reset */
3018         struct sigaction act, oact;
3019        
3020         #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
3021
3022         if (hsCb) {
3023             ssl->hsInfoOn = 1;
3024             InitHandShakeInfo(&ssl->handShakeInfo);
3025         }
3026         if (toCb) {
3027             ssl->toInfoOn = 1;
3028             InitTimeoutInfo(&ssl->timeoutInfo);
3029             
3030             if (gettimeofday(&startTime, 0) < 0)
3031                 ERR_OUT(GETTIME_ERROR);
3032
3033             /* use setitimer to simulate getitimer, init 0 myTimeout */
3034             myTimeout.it_interval.tv_sec  = 0;
3035             myTimeout.it_interval.tv_usec = 0;
3036             myTimeout.it_value.tv_sec     = 0;
3037             myTimeout.it_value.tv_usec    = 0;
3038             if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
3039                 ERR_OUT(SETITIMER_ERROR);
3040
3041             if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
3042                 oldTimerOn = 1;
3043                 
3044                 /* is old timer going to expire before ours */
3045                 if (CmpTimes(oldTimeout.it_value, timeout, <)) { 
3046                     timeout.tv_sec  = oldTimeout.it_value.tv_sec;
3047                     timeout.tv_usec = oldTimeout.it_value.tv_usec;
3048                 }       
3049             }
3050             myTimeout.it_value.tv_sec  = timeout.tv_sec;
3051             myTimeout.it_value.tv_usec = timeout.tv_usec;
3052             
3053             /* set up signal handler, don't restart socket send/recv */
3054             act.sa_handler = myHandler;
3055             sigemptyset(&act.sa_mask);
3056             act.sa_flags = 0;
3057 #ifdef SA_INTERRUPT
3058             act.sa_flags |= SA_INTERRUPT;
3059 #endif
3060             if (sigaction(SIGALRM, &act, &oact) < 0)
3061                 ERR_OUT(SIGACT_ERROR);
3062
3063             if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
3064                 ERR_OUT(SETITIMER_ERROR);
3065         }
3066
3067         /* do main work */
3068 #ifndef NO_CYASSL_CLIENT
3069         if (ssl->options.side == CLIENT_END)
3070             ret = CyaSSL_connect(ssl);
3071 #endif
3072 #ifndef NO_CYASSL_SERVER
3073         if (ssl->options.side == SERVER_END)
3074             ret = CyaSSL_accept(ssl);
3075 #endif
3076        
3077         /* do callbacks */ 
3078         if (toCb) {
3079             if (oldTimerOn) {
3080                 gettimeofday(&endTime, 0);
3081                 SubtractTimes(endTime, startTime, totalTime);
3082                 /* adjust old timer for elapsed time */
3083                 if (CmpTimes(totalTime, oldTimeout.it_value, <))
3084                     SubtractTimes(oldTimeout.it_value, totalTime,
3085                                   oldTimeout.it_value);
3086                 else {
3087                     /* reset value to interval, may be off */
3088                     oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
3089                     oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
3090                 }
3091                 /* keep iter the same whether there or not */
3092             }
3093             /* restore old handler */
3094             if (sigaction(SIGALRM, &oact, 0) < 0)
3095                 ret = SIGACT_ERROR;    /* more pressing error, stomp */
3096             else
3097                 /* use old settings which may turn off (expired or not there) */
3098                 if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
3099                     ret = SETITIMER_ERROR;
3100             
3101             /* if we had a timeout call callback */
3102             if (ssl->timeoutInfo.timeoutName[0]) {
3103                 ssl->timeoutInfo.timeoutValue.tv_sec  = timeout.tv_sec;
3104                 ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
3105                 (toCb)(&ssl->timeoutInfo);
3106             }
3107             /* clean up */
3108             FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
3109             ssl->toInfoOn = 0;
3110         }
3111         if (hsCb) {
3112             FinishHandShakeInfo(&ssl->handShakeInfo, ssl);
3113             (hsCb)(&ssl->handShakeInfo);
3114             ssl->hsInfoOn = 0;
3115         }
3116         return ret;
3117     }
3118
3119
3120 #ifndef NO_CYASSL_CLIENT
3121
3122     int CyaSSL_connect_ex(CYASSL* ssl, HandShakeCallBack hsCb,
3123                           TimeoutCallBack toCb, Timeval timeout)
3124     {
3125         CYASSL_ENTER("CyaSSL_connect_ex");
3126         return CyaSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
3127     }
3128
3129 #endif
3130
3131
3132 #ifndef NO_CYASSL_SERVER
3133
3134     int CyaSSL_accept_ex(CYASSL* ssl, HandShakeCallBack hsCb,
3135                          TimeoutCallBack toCb,Timeval timeout)
3136     {
3137         CYASSL_ENTER("CyaSSL_accept_ex");
3138         return CyaSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
3139     }
3140
3141 #endif
3142
3143 #endif /* CYASSL_CALLBACKS */
3144
3145
3146 #ifndef NO_PSK
3147
3148     void CyaSSL_CTX_set_psk_client_callback(CYASSL_CTX* ctx,
3149                                          psk_client_callback cb)
3150     {
3151         CYASSL_ENTER("SSL_CTX_set_psk_client_callback");
3152         ctx->havePSK = 1;
3153         ctx->client_psk_cb = cb;
3154     }
3155
3156
3157     void CyaSSL_set_psk_client_callback(CYASSL* ssl, psk_client_callback cb)
3158     {
3159         CYASSL_ENTER("SSL_set_psk_client_callback");
3160         ssl->options.havePSK = 1;
3161         ssl->options.client_psk_cb = cb;
3162
3163         InitSuites(&ssl->suites, ssl->version,TRUE,TRUE, ssl->options.haveNTRU,
3164                    ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
3165                    ssl->options.side);
3166     }
3167
3168
3169     void CyaSSL_CTX_set_psk_server_callback(CYASSL_CTX* ctx,
3170                                          psk_server_callback cb)
3171     {
3172         CYASSL_ENTER("SSL_CTX_set_psk_server_callback");
3173         ctx->havePSK = 1;
3174         ctx->server_psk_cb = cb;
3175     }
3176
3177
3178     void CyaSSL_set_psk_server_callback(CYASSL* ssl, psk_server_callback cb)
3179     {
3180         CYASSL_ENTER("SSL_set_psk_server_callback");
3181         ssl->options.havePSK = 1;
3182         ssl->options.server_psk_cb = cb;
3183
3184         InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, TRUE,
3185                    ssl->options.haveNTRU, ssl->options.haveECDSAsig,
3186                    ssl->options.haveStaticECC, ssl->options.side);
3187     }
3188
3189
3190     const char* CyaSSL_get_psk_identity_hint(const CYASSL* ssl)
3191     {
3192         CYASSL_ENTER("SSL_get_psk_identity_hint");
3193         return ssl->arrays.server_hint;
3194     }
3195
3196
3197     const char* CyaSSL_get_psk_identity(const CYASSL* ssl)
3198     {
3199         CYASSL_ENTER("SSL_get_psk_identity");
3200         return ssl->arrays.client_identity;
3201     }
3202
3203
3204     int CyaSSL_CTX_use_psk_identity_hint(CYASSL_CTX* ctx, const char* hint)
3205     {
3206         CYASSL_ENTER("SSL_CTX_use_psk_identity_hint");
3207         if (hint == 0)
3208             ctx->server_hint[0] = 0;
3209         else {
3210             XSTRNCPY(ctx->server_hint, hint, MAX_PSK_ID_LEN);
3211             ctx->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
3212         }
3213         return SSL_SUCCESS;
3214     }
3215
3216
3217     int CyaSSL_use_psk_identity_hint(CYASSL* ssl, const char* hint)
3218     {
3219         CYASSL_ENTER("SSL_use_psk_identity_hint");
3220         if (hint == 0)
3221             ssl->arrays.server_hint[0] = 0;
3222         else {
3223             XSTRNCPY(ssl->arrays.server_hint, hint, MAX_PSK_ID_LEN);
3224             ssl->arrays.server_hint[MAX_PSK_ID_LEN - 1] = '\0';
3225         }
3226         return SSL_SUCCESS;
3227     }
3228
3229 #endif /* NO_PSK */
3230
3231
3232 /* used to be defined on NO_FILESYSTEM only, but are generally useful */
3233
3234     /* CyaSSL extension allows DER files to be loaded from buffers as well */
3235     int CyaSSL_CTX_load_verify_buffer(CYASSL_CTX* ctx, const unsigned char* in,
3236                                       long sz, int format)
3237     {
3238         CYASSL_ENTER("CyaSSL_CTX_load_verify_buffer");
3239         if (format == SSL_FILETYPE_PEM)
3240             return ProcessChainBuffer(ctx, in, sz, format, CA_TYPE, NULL);
3241         else
3242             return ProcessBuffer(ctx, in, sz, format, CA_TYPE, NULL,NULL,0);
3243     }
3244
3245
3246     int CyaSSL_CTX_use_certificate_buffer(CYASSL_CTX* ctx,
3247                                  const unsigned char* in, long sz, int format)
3248     {
3249         CYASSL_ENTER("CyaSSL_CTX_use_certificate_buffer");
3250         return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 0);
3251     }
3252
3253
3254     int CyaSSL_CTX_use_PrivateKey_buffer(CYASSL_CTX* ctx,
3255                                  const unsigned char* in, long sz, int format)
3256     {
3257         CYASSL_ENTER("CyaSSL_CTX_use_PrivateKey_buffer");
3258         return ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL,NULL,0);
3259     }
3260
3261
3262     int CyaSSL_CTX_use_certificate_chain_buffer(CYASSL_CTX* ctx,
3263                                  const unsigned char* in, long sz)
3264     {
3265         CYASSL_ENTER("CyaSSL_CTX_use_certificate_chain_buffer");
3266         return ProcessBuffer(ctx, in, sz, SSL_FILETYPE_PEM, CERT_TYPE, NULL,
3267                              NULL, 1);
3268     }
3269
3270     int CyaSSL_use_certificate_buffer(CYASSL* ssl,
3271                                  const unsigned char* in, long sz, int format)
3272     {
3273         CYASSL_ENTER("CyaSSL_use_certificate_buffer");
3274         return ProcessBuffer(ssl->ctx, in, sz, format,CERT_TYPE,ssl,NULL,0);
3275     }
3276
3277
3278     int CyaSSL_use_PrivateKey_buffer(CYASSL* ssl,
3279                                  const unsigned char* in, long sz, int format)
3280     {
3281         CYASSL_ENTER("CyaSSL_use_PrivateKey_buffer");
3282         return ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE, 
3283                              ssl, NULL, 0);
3284     }
3285
3286
3287     int CyaSSL_use_certificate_chain_buffer(CYASSL* ssl,
3288                                  const unsigned char* in, long sz)
3289     {
3290         CYASSL_ENTER("CyaSSL_use_certificate_chain_buffer");
3291         return ProcessBuffer(ssl->ctx, in, sz, SSL_FILETYPE_PEM, CERT_TYPE,
3292                              ssl, NULL, 1);
3293     }
3294
3295 /* old NO_FILESYSTEM end */
3296
3297
3298 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
3299
3300
3301     int CyaSSL_add_all_algorithms(void)
3302     {
3303         CYASSL_ENTER("CyaSSL_add_all_algorithms");
3304         CyaSSL_Init();
3305         return SSL_SUCCESS;
3306     }
3307
3308
3309     long CyaSSL_CTX_sess_set_cache_size(CYASSL_CTX* ctx, long sz)
3310     {
3311         /* cache size fixed at compile time in CyaSSL */
3312         (void)ctx;
3313         (void)sz;
3314         return 0;
3315     }
3316
3317
3318     void CyaSSL_CTX_set_quiet_shutdown(CYASSL_CTX* ctx, int mode)
3319     {
3320         CYASSL_ENTER("CyaSSL_CTX_set_quiet_shutdown");
3321         if (mode)
3322             ctx->quietShutdown = 1;
3323     }
3324
3325
3326     void CyaSSL_set_quiet_shutdown(CYASSL* ssl, int mode)
3327     {
3328         CYASSL_ENTER("CyaSSL_CTX_set_quiet_shutdown");
3329         if (mode)
3330             ssl->options.quietShutdown = 1;
3331     }
3332
3333
3334     void CyaSSL_set_bio(CYASSL* ssl, CYASSL_BIO* rd, CYASSL_BIO* wr)
3335     {
3336         CYASSL_ENTER("SSL_set_bio");
3337         CyaSSL_set_rfd(ssl, rd->fd);
3338         CyaSSL_set_wfd(ssl, wr->fd);
3339
3340         ssl->biord = rd;
3341         ssl->biowr = wr;
3342     }
3343
3344
3345     void CyaSSL_CTX_set_client_CA_list(CYASSL_CTX* ctx,
3346                                        STACK_OF(CYASSL_X509_NAME)* names)
3347     {
3348         (void)ctx; 
3349         (void)names; 
3350     }
3351
3352
3353     STACK_OF(CYASSL_X509_NAME)* CyaSSL_load_client_CA_file(const char* fname)
3354     {
3355         (void)fname;
3356         return 0;
3357     }
3358
3359
3360     int CyaSSL_CTX_set_default_verify_paths(CYASSL_CTX* ctx)
3361     {
3362         /* TODO:, not needed in goahead */
3363         (void)ctx; 
3364         return SSL_NOT_IMPLEMENTED;
3365     }
3366
3367
3368     /* keyblock size in bytes or -1 */
3369     int CyaSSL_get_keyblock_size(CYASSL* ssl)
3370     {
3371         if (ssl == NULL)
3372             return -1;
3373
3374         return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
3375                     ssl->specs.hash_size);
3376     }
3377
3378
3379     /* store keys returns 0 or -1 on error */
3380     int CyaSSL_get_keys(CYASSL* ssl, unsigned char** ms, unsigned int* msLen,
3381                                      unsigned char** sr, unsigned int* srLen,
3382                                      unsigned char** cr, unsigned int* crLen)
3383     {
3384         if (ssl == NULL)
3385             return -1;
3386
3387         *ms = ssl->arrays.masterSecret;
3388         *sr = ssl->arrays.serverRandom;
3389         *cr = ssl->arrays.clientRandom;
3390
3391         *msLen = SECRET_LEN;
3392         *srLen = RAN_LEN;
3393         *crLen = RAN_LEN;
3394     
3395         return 0;
3396     }
3397
3398
3399     void CyaSSL_set_accept_state(CYASSL* ssl)
3400     {
3401         byte havePSK = 0;
3402
3403         CYASSL_ENTER("SSL_set_accept_state");
3404         ssl->options.side = SERVER_END;
3405         /* reset suites in case user switched */
3406 #ifndef NO_PSK
3407         havePSK = ssl->options.havePSK;
3408 #endif
3409         InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK,
3410                    ssl->options.haveNTRU, ssl->options.haveECDSAsig,
3411                    ssl->options.haveStaticECC, ssl->options.side);
3412     }
3413
3414    
3415     /* return true if connection established */
3416     int CyaSSL_is_init_finished(CYASSL* ssl)
3417     {
3418         if (ssl == NULL)
3419             return 0;
3420
3421         if (ssl->options.handShakeState == HANDSHAKE_DONE)
3422             return 1;
3423
3424         return 0;
3425     }
3426
3427
3428     void CyaSSL_CTX_set_tmp_rsa_callback(CYASSL_CTX* ctx,
3429                                       CYASSL_RSA*(*f)(CYASSL*, int, int))
3430     {
3431         /* CyaSSL verifies all these internally */   
3432         (void)ctx; 
3433         (void)f; 
3434     }
3435
3436
3437     void CyaSSL_set_shutdown(CYASSL* ssl, int opt)
3438     {
3439         (void)ssl; 
3440         (void)opt; 
3441     }
3442
3443
3444     long CyaSSL_CTX_set_options(CYASSL_CTX* ctx, long opt)
3445     {
3446         /* goahead calls with 0, do nothing */ 
3447         CYASSL_ENTER("SSL_CTX_set_options");
3448         (void)ctx; 
3449         return opt;
3450     }
3451
3452
3453     int CyaSSL_set_rfd(CYASSL* ssl, int rfd)
3454     {
3455         CYASSL_ENTER("SSL_set_rfd");
3456         ssl->rfd = rfd;      /* not used directly to allow IO callbacks */
3457
3458         ssl->IOCB_ReadCtx  = &ssl->rfd;
3459
3460         return SSL_SUCCESS;
3461     }
3462
3463
3464     int CyaSSL_set_wfd(CYASSL* ssl, int wfd)
3465     {
3466         CYASSL_ENTER("SSL_set_wfd");
3467         ssl->wfd = wfd;      /* not used directly to allow IO callbacks */
3468
3469         ssl->IOCB_WriteCtx  = &ssl->wfd;
3470
3471         return SSL_SUCCESS;
3472     }
3473
3474
3475     CYASSL_RSA* CyaSSL_RSA_generate_key(int len, unsigned long bits,
3476                                           void(*f)(int, int, void*), void* data)
3477     {
3478         /* no tmp key needed, actual generation not supported */
3479         CYASSL_ENTER("RSA_generate_key");
3480         (void)len; 
3481         (void)bits; 
3482         (void)f; 
3483         (void)data; 
3484         return NULL;
3485     }
3486
3487
3488     /* return the next, if any, altname from the peer cert */
3489     char* CyaSSL_X509_get_next_altname(CYASSL_X509* cert)
3490     {
3491         char* ret = NULL;
3492         CYASSL_ENTER("CyaSSL_X509_get_next_altname");
3493
3494         /* don't have any to work with */
3495         if (cert == NULL || cert->altNames == NULL)
3496             return NULL;
3497
3498         /* already went through them */
3499         if (cert->altNamesNext == NULL)
3500             return NULL;
3501
3502         ret = cert->altNamesNext->name;
3503         cert->altNamesNext = cert->altNamesNext->next;
3504
3505         return ret;
3506     }
3507
3508
3509     CYASSL_X509_NAME* CyaSSL_X509_get_issuer_name(CYASSL_X509* cert)
3510     {
3511         CYASSL_ENTER("X509_get_issuer_name");
3512         return &cert->issuer;
3513     }
3514
3515
3516     CYASSL_X509_NAME* CyaSSL_X509_get_subject_name(CYASSL_X509* cert)
3517     {
3518         CYASSL_ENTER("X509_get_subject_name");
3519         return &cert->subject;
3520     }
3521
3522
3523     /* copy name into in buffer, at most sz bytes, if buffer is null will
3524        malloc buffer, call responsible for freeing                     */
3525     char* CyaSSL_X509_NAME_oneline(CYASSL_X509_NAME* name, char* in, int sz)
3526     {
3527         int copySz = min(sz, name->sz);
3528
3529         CYASSL_ENTER("CyaSSL_X509_NAME_oneline");
3530         if (!name->sz) return in;
3531
3532         if (!in) {
3533             in = (char*)XMALLOC(name->sz, 0, DYNAMIC_TYPE_OPENSSL);
3534             if (!in ) return in;
3535             copySz = name->sz;
3536         }
3537
3538         if (copySz == 0)
3539             return in;
3540
3541         XMEMCPY(in, name->name, copySz - 1);
3542         in[copySz - 1] = 0;
3543
3544         return in;
3545     }
3546
3547
3548     CYASSL_X509* CyaSSL_X509_STORE_CTX_get_current_cert(
3549                                                      CYASSL_X509_STORE_CTX* ctx)
3550     {
3551         (void)ctx; 
3552         return 0;
3553     }
3554
3555
3556     int CyaSSL_X509_STORE_CTX_get_error(CYASSL_X509_STORE_CTX* ctx)
3557     {
3558         (void)ctx; 
3559         return 0;
3560     }
3561
3562
3563     int CyaSSL_X509_STORE_CTX_get_error_depth(CYASSL_X509_STORE_CTX* ctx)
3564     {
3565         (void)ctx; 
3566         return 0;
3567     }
3568
3569
3570     CYASSL_BIO_METHOD* CyaSSL_BIO_f_buffer(void)
3571     {
3572         static CYASSL_BIO_METHOD meth;
3573
3574         CYASSL_ENTER("BIO_f_buffer");
3575         meth.type = BIO_BUFFER;
3576
3577         return &meth;
3578     }
3579
3580
3581     long CyaSSL_BIO_set_write_buffer_size(CYASSL_BIO* bio, long size)
3582     {
3583         /* CyaSSL has internal buffer, compatibility only */
3584         CYASSL_ENTER("BIO_set_write_buffer_size");
3585         (void)bio; 
3586         return size; 
3587     }
3588
3589
3590     CYASSL_BIO_METHOD* CyaSSL_BIO_f_ssl(void)
3591     {
3592         static CYASSL_BIO_METHOD meth;
3593
3594         CYASSL_ENTER("BIO_f_ssl");
3595         meth.type = BIO_SSL;
3596
3597         return &meth;
3598     }
3599
3600
3601     CYASSL_BIO* CyaSSL_BIO_new_socket(int sfd, int closeF)
3602     {
3603         CYASSL_BIO* bio = (CYASSL_BIO*) XMALLOC(sizeof(CYASSL_BIO), 0,
3604                                                 DYNAMIC_TYPE_OPENSSL);
3605
3606         CYASSL_ENTER("BIO_new_socket");
3607         if (bio) { 
3608             bio->type  = BIO_SOCKET;
3609             bio->close = (byte)closeF;
3610             bio->eof   = 0;
3611             bio->ssl   = 0;
3612             bio->fd    = sfd;
3613             bio->prev  = 0;
3614             bio->next  = 0;
3615         }
3616         return bio; 
3617     }
3618
3619
3620     int CyaSSL_BIO_eof(CYASSL_BIO* b)
3621     {
3622         CYASSL_ENTER("BIO_eof");
3623         if (b->eof)
3624             return 1;
3625
3626         return 0;        
3627     }
3628
3629
3630     long CyaSSL_BIO_set_ssl(CYASSL_BIO* b, CYASSL* ssl, int closeF)
3631     {
3632         CYASSL_ENTER("BIO_set_ssl");
3633         b->ssl   = ssl;
3634         b->close = (byte)closeF;
3635     /* add to ssl for bio free if SSL_free called before/instead of free_all? */
3636
3637         return 0;
3638     }
3639
3640
3641     CYASSL_BIO* CyaSSL_BIO_new(CYASSL_BIO_METHOD* method)
3642     {
3643         CYASSL_BIO* bio = (CYASSL_BIO*) XMALLOC(sizeof(CYASSL_BIO), 0,
3644                                                 DYNAMIC_TYPE_OPENSSL);
3645         CYASSL_ENTER("BIO_new");
3646         if (bio) {
3647             bio->type   = method->type;
3648             bio->close  = 0;
3649             bio->eof    = 0;
3650             bio->ssl    = NULL;
3651             bio->mem    = NULL;
3652             bio->memLen = 0;
3653             bio->fd     = 0;
3654             bio->prev   = NULL;
3655             bio->next   = NULL;
3656         }
3657         return bio;
3658     }
3659
3660
3661     int CyaSSL_BIO_get_mem_data(CYASSL_BIO* bio, const byte** p)
3662     {
3663         if (bio == NULL || p == NULL)
3664             return -1;
3665
3666         *p = bio->mem;
3667
3668         return bio->memLen;
3669     }
3670
3671
3672     CYASSL_BIO* CyaSSL_BIO_new_mem_buf(void* buf, int len)
3673     {
3674         CYASSL_BIO* bio = NULL;
3675         if (buf == NULL)
3676             return bio;
3677
3678         bio = CyaSSL_BIO_new(CyaSSL_BIO_s_mem());
3679         if (bio == NULL)
3680             return bio;
3681
3682         bio->memLen = len;
3683         bio->mem    = (byte*)XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL);
3684         if (bio->mem == NULL) {
3685             XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
3686             return NULL;
3687         }
3688
3689         XMEMCPY(bio->mem, buf, len);
3690
3691         return bio;
3692     }
3693
3694
3695 #ifdef USE_WINDOWS_API 
3696     #define CloseSocket(s) closesocket(s)
3697 #else
3698     #define CloseSocket(s) close(s)
3699 #endif
3700
3701     int CyaSSL_BIO_free(CYASSL_BIO* bio)
3702     {
3703         /* unchain?, doesn't matter in goahead since from free all */
3704         CYASSL_ENTER("BIO_free");
3705         if (bio) {
3706             if (bio->close) {
3707                 if (bio->ssl)
3708                     CyaSSL_free(bio->ssl);
3709                 if (bio->fd)
3710                     CloseSocket(bio->fd);
3711             }
3712             if (bio->mem)
3713                 XFREE(bio->mem, 0, DYNAMIC_TYPE_OPENSSL);
3714             XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
3715         }
3716         return 0;
3717     }
3718
3719
3720     int CyaSSL_BIO_free_all(CYASSL_BIO* bio)
3721     {
3722         CYASSL_ENTER("BIO_free_all");
3723         while (bio) {
3724             CYASSL_BIO* next = bio->next;
3725             CyaSSL_BIO_free(bio);
3726             bio = next;
3727         }
3728         return 0;
3729     }
3730
3731
3732     int CyaSSL_BIO_read(CYASSL_BIO* bio, void* buf, int len)
3733     {
3734         int  ret;
3735         CYASSL* ssl = 0;
3736         CYASSL_BIO* front = bio;
3737
3738         CYASSL_ENTER("BIO_read");
3739         /* already got eof, again is error */
3740         if (front->eof)
3741             return SSL_FATAL_ERROR;
3742
3743         while(bio && ((ssl = bio->ssl) == 0) )
3744             bio = bio->next;
3745
3746         if (ssl == 0) return BAD_FUNC_ARG;
3747
3748         ret = CyaSSL_read(ssl, buf, len);
3749         if (ret == 0)
3750             front->eof = 1;
3751         else if (ret < 0) {
3752             int err = CyaSSL_get_error(ssl, 0);
3753             if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
3754                 front->eof = 1;
3755         }
3756         return ret;
3757     }
3758
3759
3760     int CyaSSL_BIO_write(CYASSL_BIO* bio, const void* data, int len)
3761     {
3762         int  ret;
3763         CYASSL* ssl = 0;
3764         CYASSL_BIO* front = bio;
3765
3766         CYASSL_ENTER("BIO_write");
3767         /* already got eof, again is error */
3768         if (front->eof)
3769             return SSL_FATAL_ERROR;
3770
3771         while(bio && ((ssl = bio->ssl) == 0) )
3772             bio = bio->next;
3773
3774         if (ssl == 0) return BAD_FUNC_ARG;
3775
3776         ret = CyaSSL_write(ssl, data, len);
3777         if (ret == 0)
3778             front->eof = 1;
3779         else if (ret < 0) {
3780             int err = CyaSSL_get_error(ssl, 0);
3781             if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
3782                 front->eof = 1;
3783         }
3784
3785         return ret;
3786     }
3787
3788
3789     CYASSL_BIO* CyaSSL_BIO_push(CYASSL_BIO* top, CYASSL_BIO* append)
3790     {
3791         CYASSL_ENTER("BIO_push");
3792         top->next    = append;
3793         append->prev = top;
3794
3795         return top;
3796     }
3797
3798
3799     int CyaSSL_BIO_flush(CYASSL_BIO* bio)
3800     {
3801         /* for CyaSSL no flushing needed */
3802         CYASSL_ENTER("BIO_flush");
3803         (void)bio; 
3804         return 1;
3805     }
3806
3807
3808 #endif /* OPENSSL_EXTRA || GOAHEAD_WS */
3809
3810
3811 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
3812
3813     void CyaSSL_CTX_set_default_passwd_cb_userdata(CYASSL_CTX* ctx,
3814                                                    void* userdata)
3815     {
3816         CYASSL_ENTER("SSL_CTX_set_default_passwd_cb_userdata");
3817         ctx->userdata = userdata;
3818     }
3819
3820
3821     void CyaSSL_CTX_set_default_passwd_cb(CYASSL_CTX* ctx, pem_password_cb cb)
3822     {
3823         CYASSL_ENTER("SSL_CTX_set_default_passwd_cb");
3824         ctx->passwd_cb = cb;
3825     }
3826
3827     int CyaSSL_num_locks(void)
3828     {
3829         return 0;
3830     }
3831
3832     void CyaSSL_set_locking_callback(void (*f)(int, int, const char*, int))
3833     {
3834         (void)f; 
3835     }
3836
3837     void CyaSSL_set_id_callback(unsigned long (*f)(void))
3838     {
3839         (void)f; 
3840     }
3841
3842     unsigned long CyaSSL_ERR_get_error(void)
3843     {
3844         /* TODO: */
3845         return 0;
3846     }
3847
3848     int CyaSSL_EVP_BytesToKey(const CYASSL_EVP_CIPHER* type,
3849                        const CYASSL_EVP_MD* md, const byte* salt,
3850                        const byte* data, int sz, int count, byte* key, byte* iv)
3851     {
3852         int keyLen = 0;
3853         int ivLen  = 0;
3854
3855         Md5    myMD;
3856         byte   digest[MD5_DIGEST_SIZE];
3857
3858         int j;
3859         int keyLeft;
3860         int ivLeft;
3861         int keyOutput = 0;
3862
3863         CYASSL_ENTER("EVP_BytesToKey");
3864         InitMd5(&myMD);
3865
3866         /* only support MD5 for now */
3867         if (XSTRNCMP(md, "MD5", 3)) return 0;
3868
3869         /* only support CBC DES and AES for now */
3870         if (XSTRNCMP(type, "DES-CBC", 7) == 0) {
3871             keyLen = DES_KEY_SIZE;
3872             ivLen  = DES_IV_SIZE;
3873         }
3874         else if (XSTRNCMP(type, "DES-EDE3-CBC", 12) == 0) {
3875             keyLen = DES3_KEY_SIZE;
3876             ivLen  = DES_IV_SIZE;
3877         }
3878         else if (XSTRNCMP(type, "AES-128-CBC", 11) == 0) {
3879             keyLen = AES_128_KEY_SIZE;
3880             ivLen  = AES_IV_SIZE;
3881         }
3882         else if (XSTRNCMP(type, "AES-192-CBC", 11) == 0) {
3883             keyLen = AES_192_KEY_SIZE;
3884             ivLen  = AES_IV_SIZE;
3885         }
3886         else if (XSTRNCMP(type, "AES-256-CBC", 11) == 0) {
3887             keyLen = AES_256_KEY_SIZE;
3888             ivLen  = AES_IV_SIZE;
3889         }
3890         else
3891             return 0;
3892
3893         keyLeft   = keyLen;
3894         ivLeft    = ivLen;
3895
3896         while (keyOutput < (keyLen + ivLen)) {
3897             int digestLeft = MD5_DIGEST_SIZE;
3898             /* D_(i - 1) */
3899             if (keyOutput)                      /* first time D_0 is empty */
3900                 Md5Update(&myMD, digest, MD5_DIGEST_SIZE);
3901             /* data */
3902             Md5Update(&myMD, data, sz);
3903             /* salt */
3904             if (salt)
3905                 Md5Update(&myMD, salt, EVP_SALT_SIZE);
3906             Md5Final(&myMD, digest);
3907             /* count */
3908             for (j = 1; j < count; j++) {
3909                 Md5Update(&myMD, digest, MD5_DIGEST_SIZE);
3910                 Md5Final(&myMD, digest);
3911             }
3912
3913             if (keyLeft) {
3914                 int store = min(keyLeft, MD5_DIGEST_SIZE);
3915                 XMEMCPY(&key[keyLen - keyLeft], digest, store);
3916
3917                 keyOutput  += store;
3918                 keyLeft    -= store;
3919                 digestLeft -= store;
3920             }
3921
3922             if (ivLeft && digestLeft) {
3923                 int store = min(ivLeft, digestLeft);
3924                 XMEMCPY(&iv[ivLen - ivLeft], &digest[MD5_DIGEST_SIZE -
3925                                                     digestLeft], store);
3926                 keyOutput += store;
3927                 ivLeft    -= store;
3928             }
3929         }
3930         if (keyOutput != (keyLen + ivLen))
3931             return 0;
3932         return keyOutput;
3933     }
3934
3935 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
3936
3937
3938 #ifdef OPENSSL_EXTRA
3939
3940     unsigned long CyaSSLeay(void)
3941     {
3942         return SSLEAY_VERSION_NUMBER;
3943     }
3944
3945
3946     const char* CyaSSLeay_version(int type)
3947     {
3948         static const char* version = "SSLeay CyaSSL compatibility";
3949         (void)type; 
3950         return version;
3951     }
3952
3953
3954     void CyaSSL_MD5_Init(CYASSL_MD5_CTX* md5)
3955     {
3956         typedef char md5_test[sizeof(MD5_CTX) >= sizeof(Md5) ? 1 : -1];
3957         (void)sizeof(md5_test);
3958
3959         CYASSL_ENTER("MD5_Init");
3960         InitMd5((Md5*)md5);
3961     }
3962
3963
3964     void CyaSSL_MD5_Update(CYASSL_MD5_CTX* md5, const void* input,
3965                            unsigned long sz)
3966     {
3967         CYASSL_ENTER("CyaSSL_MD5_Update");
3968         Md5Update((Md5*)md5, (const byte*)input, sz);
3969     }
3970
3971
3972     void CyaSSL_MD5_Final(byte* input, CYASSL_MD5_CTX* md5)
3973     {
3974         CYASSL_ENTER("MD5_Final");
3975         Md5Final((Md5*)md5, input);
3976     }
3977
3978
3979     void CyaSSL_SHA_Init(CYASSL_SHA_CTX* sha)
3980     {
3981         typedef char sha_test[sizeof(SHA_CTX) >= sizeof(Sha) ? 1 : -1];
3982         (void)sizeof(sha_test);
3983
3984         CYASSL_ENTER("SHA_Init");
3985         InitSha((Sha*)sha);
3986     }
3987
3988
3989     void CyaSSL_SHA_Update(CYASSL_SHA_CTX* sha, const void* input,
3990                            unsigned long sz)
3991     {
3992         CYASSL_ENTER("SHA_Update");
3993         ShaUpdate((Sha*)sha, (const byte*)input, sz);
3994     }
3995
3996
3997     void CyaSSL_SHA_Final(byte* input, CYASSL_SHA_CTX* sha)
3998     {
3999         CYASSL_ENTER("SHA_Final");
4000         ShaFinal((Sha*)sha, input);
4001     }
4002
4003
4004     void CyaSSL_SHA1_Init(CYASSL_SHA_CTX* sha)
4005     {
4006         CYASSL_ENTER("SHA1_Init");
4007         SHA_Init(sha);
4008     }
4009
4010
4011     void CyaSSL_SHA1_Update(CYASSL_SHA_CTX* sha, const void* input,
4012                             unsigned long sz)
4013     {
4014         CYASSL_ENTER("SHA1_Update");
4015         SHA_Update(sha, input, sz);
4016     }
4017
4018
4019     void CyaSSL_SHA1_Final(byte* input, CYASSL_SHA_CTX* sha)
4020     {
4021         CYASSL_ENTER("SHA1_Final");
4022         SHA_Final(input, sha);
4023     }
4024
4025
4026     void CyaSSL_SHA256_Init(CYASSL_SHA256_CTX* sha256)
4027     {
4028         typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(Sha256) ? 1 : -1];
4029         (void)sizeof(sha_test);
4030
4031         CYASSL_ENTER("SHA256_Init");
4032         InitSha256((Sha256*)sha256);
4033     }
4034
4035
4036     void CyaSSL_SHA256_Update(CYASSL_SHA256_CTX* sha, const void* input,
4037                               unsigned long sz)
4038     {
4039         CYASSL_ENTER("SHA256_Update");
4040         Sha256Update((Sha256*)sha, (const byte*)input, sz);
4041     }
4042
4043
4044     void CyaSSL_SHA256_Final(byte* input, CYASSL_SHA256_CTX* sha)
4045     {
4046         CYASSL_ENTER("SHA256_Final");
4047         Sha256Final((Sha256*)sha, input);
4048     }
4049
4050
4051     #ifdef CYASSL_SHA384
4052
4053     void CyaSSL_SHA384_Init(CYASSL_SHA384_CTX* sha)
4054     {
4055         typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(Sha384) ? 1 : -1];
4056         (void)sizeof(sha_test);
4057
4058         CYASSL_ENTER("SHA384_Init");
4059         InitSha384((Sha384*)sha);
4060     }
4061
4062
4063     void CyaSSL_SHA384_Update(CYASSL_SHA384_CTX* sha, const void* input,
4064                            unsigned long sz)
4065     {
4066         CYASSL_ENTER("SHA384_Update");
4067         Sha384Update((Sha384*)sha, (const byte*)input, sz);
4068     }
4069
4070
4071     void CyaSSL_SHA384_Final(byte* input, CYASSL_SHA384_CTX* sha)
4072     {
4073         CYASSL_ENTER("SHA384_Final");
4074         Sha384Final((Sha384*)sha, input);
4075     }
4076
4077     #endif /* CYASSL_SHA384 */
4078
4079
4080    #ifdef CYASSL_SHA512
4081
4082     void CyaSSL_SHA512_Init(CYASSL_SHA512_CTX* sha)
4083     {
4084         typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(Sha512) ? 1 : -1];
4085         (void)sizeof(sha_test);
4086
4087         CYASSL_ENTER("SHA512_Init");
4088         InitSha512((Sha512*)sha);
4089     }
4090
4091
4092     void CyaSSL_SHA512_Update(CYASSL_SHA512_CTX* sha, const void* input,
4093                            unsigned long sz)
4094     {
4095         CYASSL_ENTER("SHA512_Update");
4096         Sha512Update((Sha512*)sha, (const byte*)input, sz);
4097     }
4098
4099
4100     void CyaSSL_SHA512_Final(byte* input, CYASSL_SHA512_CTX* sha)
4101     {
4102         CYASSL_ENTER("SHA512_Final");
4103         Sha512Final((Sha512*)sha, input);
4104     }
4105
4106     #endif /* CYASSL_SHA512 */
4107
4108
4109     const CYASSL_EVP_MD* CyaSSL_EVP_md5(void)
4110     {
4111         static const char* type = "MD5";
4112         CYASSL_ENTER("EVP_md5");
4113         return type;
4114     }
4115
4116
4117     const CYASSL_EVP_MD* CyaSSL_EVP_sha1(void)
4118     {
4119         static const char* type = "SHA";
4120         CYASSL_ENTER("EVP_sha1");
4121         return type;
4122     }
4123
4124
4125     const CYASSL_EVP_MD* CyaSSL_EVP_sha256(void)
4126     {
4127         static const char* type = "SHA256";
4128         CYASSL_ENTER("EVP_sha256");
4129         return type;
4130     }
4131
4132     #ifdef CYASSL_SHA384
4133
4134     const CYASSL_EVP_MD* CyaSSL_EVP_sha384(void)
4135     {
4136         static const char* type = "SHA384";
4137         CYASSL_ENTER("EVP_sha384");
4138         return type;
4139     }
4140
4141     #endif /* CYASSL_SHA384 */
4142
4143     #ifdef CYASSL_SHA512
4144
4145     const CYASSL_EVP_MD* CyaSSL_EVP_sha512(void)
4146     {
4147         static const char* type = "SHA512";
4148         CYASSL_ENTER("EVP_sha512");
4149         return type;
4150     }
4151
4152     #endif /* CYASSL_SHA512 */
4153
4154
4155     void CyaSSL_EVP_MD_CTX_init(CYASSL_EVP_MD_CTX* ctx)
4156     {
4157         CYASSL_ENTER("EVP_CIPHER_MD_CTX_init");
4158         (void)ctx; 
4159         /* do nothing */ 
4160     }
4161
4162
4163     const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_128_cbc(void)
4164     {
4165         static const char* type = "AES128-CBC";
4166         CYASSL_ENTER("CyaSSL_EVP_aes_128_cbc");
4167         return type;
4168     }
4169
4170
4171     const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_192_cbc(void)
4172     {
4173         static const char* type = "AES192-CBC";
4174         CYASSL_ENTER("CyaSSL_EVP_aes_192_cbc");
4175         return type;
4176     }
4177
4178
4179     const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_256_cbc(void)
4180     {
4181         static const char* type = "AES256-CBC";
4182         CYASSL_ENTER("CyaSSL_EVP_aes_256_cbc");
4183         return type;
4184     }
4185
4186
4187     const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_128_ctr(void)
4188     {
4189         static const char* type = "AES128-CTR";
4190         CYASSL_ENTER("CyaSSL_EVP_aes_128_ctr");
4191         return type;
4192     }
4193
4194
4195     const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_192_ctr(void)
4196     {
4197         static const char* type = "AES192-CTR";
4198         CYASSL_ENTER("CyaSSL_EVP_aes_192_ctr");
4199         return type;
4200     }
4201
4202
4203     const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_256_ctr(void)
4204     {
4205         static const char* type = "AES256-CTR";
4206         CYASSL_ENTER("CyaSSL_EVP_aes_256_ctr");
4207         return type;
4208     }
4209
4210
4211     const CYASSL_EVP_CIPHER* CyaSSL_EVP_des_cbc(void)
4212     {
4213         static const char* type = "DES-CBC";
4214         CYASSL_ENTER("CyaSSL_EVP_des_cbc");
4215         return type;
4216     }
4217
4218
4219     const CYASSL_EVP_CIPHER* CyaSSL_EVP_des_ede3_cbc(void)
4220     {
4221         static const char* type = "DES-EDE3-CBC";
4222         CYASSL_ENTER("CyaSSL_EVP_des_ede3_cbc");
4223         return type;
4224     }
4225
4226
4227     const CYASSL_EVP_CIPHER* CyaSSL_EVP_rc4(void)
4228     {
4229         static const char* type = "ARC4";
4230         CYASSL_ENTER("CyaSSL_EVP_rc4");
4231         return type;
4232     }
4233
4234
4235     const CYASSL_EVP_CIPHER* CyaSSL_EVP_enc_null(void)
4236     {
4237         static const char* type = "NULL";
4238         CYASSL_ENTER("CyaSSL_EVP_enc_null");
4239         return type;
4240     }
4241
4242
4243     int CyaSSL_EVP_MD_CTX_cleanup(CYASSL_EVP_MD_CTX* ctx)
4244     {
4245         CYASSL_ENTER("EVP_MD_CTX_cleanup");
4246         (void)ctx; 
4247         return 0;
4248     }
4249
4250
4251
4252     void CyaSSL_EVP_CIPHER_CTX_init(CYASSL_EVP_CIPHER_CTX* ctx)
4253     {
4254         CYASSL_ENTER("EVP_CIPHER_CTX_init");
4255         if (ctx) {
4256             ctx->cipherType = 0xff;   /* no init */
4257             ctx->keyLen     = 0;
4258             ctx->enc        = 1;      /* start in encrypt mode */
4259         }
4260     }
4261
4262
4263     int CyaSSL_EVP_CIPHER_CTX_cleanup(CYASSL_EVP_CIPHER_CTX* ctx)
4264     {
4265         CYASSL_ENTER("EVP_CIPHER_CTX_cleanup");
4266         if (ctx) {
4267             ctx->cipherType = 0xff;  /* no more init */
4268             ctx->keyLen     = 0;
4269         }
4270
4271         return 1;  /* success */
4272     }    
4273
4274     int  CyaSSL_EVP_CipherInit(CYASSL_EVP_CIPHER_CTX* ctx,
4275                                const CYASSL_EVP_CIPHER* type, byte* key,
4276                                byte* iv, int enc)
4277     {
4278         CYASSL_ENTER("CyaSSL_EVP_CipherInit");
4279         if (ctx == NULL) {
4280             CYASSL_MSG("no ctx");
4281             return 0;   /* failure */
4282         }
4283
4284         if (type == NULL && ctx->cipherType == 0xff) {
4285             CYASSL_MSG("no type set");
4286             return 0;   /* failure */
4287         }
4288
4289         if (ctx->cipherType == AES_128_CBC_TYPE || (type &&
4290                                        XSTRNCMP(type, "AES128-CBC", 10) == 0)) {
4291             CYASSL_MSG("AES-128-CBC");
4292             ctx->cipherType = AES_128_CBC_TYPE;
4293             ctx->keyLen     = 16;
4294             if (enc == 0 || enc == 1)
4295                 ctx->enc = enc ? 1 : 0;
4296             if (key)
4297                 AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
4298                           ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
4299             if (iv && key == NULL)
4300                 AesSetIV(&ctx->cipher.aes, iv);
4301         }
4302         else if (ctx->cipherType == AES_192_CBC_TYPE || (type &&
4303                                        XSTRNCMP(type, "AES192-CBC", 10) == 0)) {
4304             CYASSL_MSG("AES-192-CBC");
4305             ctx->cipherType = AES_192_CBC_TYPE;
4306             ctx->keyLen     = 24;
4307             if (enc == 0 || enc == 1)
4308                 ctx->enc = enc ? 1 : 0;
4309             if (key)
4310                 AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
4311                           ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
4312             if (iv && key == NULL)
4313                 AesSetIV(&ctx->cipher.aes, iv);
4314         }
4315         else if (ctx->cipherType == AES_256_CBC_TYPE || (type &&
4316                                        XSTRNCMP(type, "AES256-CBC", 10) == 0)) {
4317             CYASSL_MSG("AES-256-CBC");
4318             ctx->cipherType = AES_256_CBC_TYPE;
4319             ctx->keyLen     = 32;
4320             if (enc == 0 || enc == 1)
4321                 ctx->enc = enc ? 1 : 0;
4322             if (key)
4323                 AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
4324                           ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
4325             if (iv && key == NULL)
4326                 AesSetIV(&ctx->cipher.aes, iv);
4327         }
4328 #ifdef CYASSL_AES_COUNTER
4329         else if (ctx->cipherType == AES_128_CTR_TYPE || (type &&
4330                                        XSTRNCMP(type, "AES128-CTR", 10) == 0)) {
4331             CYASSL_MSG("AES-128-CTR");
4332             ctx->cipherType = AES_128_CTR_TYPE;
4333             ctx->keyLen     = 16;
4334             if (enc == 0 || enc == 1)
4335                 ctx->enc = enc ? 1 : 0;
4336             if (key)
4337                 AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
4338                           AES_ENCRYPTION);
4339             if (iv && key == NULL)
4340                 AesSetIV(&ctx->cipher.aes, iv);
4341         }
4342         else if (ctx->cipherType == AES_192_CTR_TYPE || (type &&
4343                                        XSTRNCMP(type, "AES192-CTR", 10) == 0)) {
4344             CYASSL_MSG("AES-192-CTR");
4345             ctx->cipherType = AES_192_CTR_TYPE;
4346             ctx->keyLen     = 24;
4347             if (enc == 0 || enc == 1)
4348                 ctx->enc = enc ? 1 : 0;
4349             if (key)
4350                 AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
4351                           AES_ENCRYPTION);
4352             if (iv && key == NULL)
4353                 AesSetIV(&ctx->cipher.aes, iv);
4354         }
4355         else if (ctx->cipherType == AES_256_CTR_TYPE || (type &&
4356                                        XSTRNCMP(type, "AES256-CTR", 10) == 0)) {
4357             CYASSL_MSG("AES-256-CTR");
4358             ctx->cipherType = AES_256_CTR_TYPE;
4359             ctx->keyLen     = 32;
4360             if (enc == 0 || enc == 1)
4361                 ctx->enc = enc ? 1 : 0;
4362             if (key)
4363                 AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
4364                           AES_ENCRYPTION);
4365             if (iv && key == NULL)
4366                 AesSetIV(&ctx->cipher.aes, iv);
4367         }
4368 #endif /* CYASSL_AES_CTR */
4369         else if (ctx->cipherType == DES_CBC_TYPE || (type &&
4370                                        XSTRNCMP(type, "DES-CBC", 7) == 0)) {
4371             CYASSL_MSG("DES-CBC");
4372             ctx->cipherType = DES_CBC_TYPE;
4373             ctx->keyLen     = 8;
4374             if (enc == 0 || enc == 1)
4375                 ctx->enc = enc ? 1 : 0;
4376             if (key)
4377                 Des_SetKey(&ctx->cipher.des, key, iv,
4378                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
4379             if (iv && key == NULL)
4380                 Des_SetIV(&ctx->cipher.des, iv);
4381         }
4382         else if (ctx->cipherType == DES_EDE3_CBC_TYPE || (type &&
4383                                      XSTRNCMP(type, "DES-EDE3-CBC", 11) == 0)) {
4384             CYASSL_MSG("DES-EDE3-CBC");
4385             ctx->cipherType = DES_EDE3_CBC_TYPE;
4386             ctx->keyLen     = 24;
4387             if (enc == 0 || enc == 1)
4388                 ctx->enc = enc ? 1 : 0;
4389             if (key)
4390                 Des3_SetKey(&ctx->cipher.des3, key, iv,
4391                           ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
4392             if (iv && key == NULL)
4393                 Des3_SetIV(&ctx->cipher.des3, iv);
4394         }
4395         else if (ctx->cipherType == ARC4_TYPE || (type &&
4396                                      XSTRNCMP(type, "ARC4", 4) == 0)) {
4397             CYASSL_MSG("ARC4");
4398             ctx->cipherType = ARC4_TYPE;
4399             if (ctx->keyLen == 0)  /* user may have already set */
4400                 ctx->keyLen = 16;  /* default to 128 */
4401             if (key)
4402                 Arc4SetKey(&ctx->cipher.arc4, key, ctx->keyLen); 
4403         }
4404         else if (ctx->cipherType == NULL_CIPHER_TYPE || (type &&
4405                                      XSTRNCMP(type, "NULL", 4) == 0)) {
4406             CYASSL_MSG("NULL cipher");
4407             ctx->cipherType = NULL_CIPHER_TYPE;
4408             ctx->keyLen = 0; 
4409         }
4410         else
4411             return 0;   /* failure */
4412
4413
4414         return 1;   /* success */
4415     }
4416
4417
4418     int CyaSSL_EVP_CIPHER_CTX_key_length(CYASSL_EVP_CIPHER_CTX* ctx)
4419     {
4420         CYASSL_ENTER("CyaSSL_EVP_CIPHER_CTX_key_length");
4421         if (ctx)
4422             return ctx->keyLen;
4423
4424         return 0;   /* failure */
4425     }
4426
4427
4428     int CyaSSL_EVP_CIPHER_CTX_set_key_length(CYASSL_EVP_CIPHER_CTX* ctx,
4429                                              int keylen)
4430     {
4431         CYASSL_ENTER("CyaSSL_EVP_CIPHER_CTX_set_key_length");
4432         if (ctx)
4433             ctx->keyLen = keylen;
4434         else
4435             return 0;  /* failure */
4436
4437         return 1;  /* success */
4438     }
4439
4440
4441     int CyaSSL_EVP_Cipher(CYASSL_EVP_CIPHER_CTX* ctx, byte* dst, byte* src,
4442                           word32 len)
4443     {
4444         CYASSL_ENTER("CyaSSL_EVP_Cipher");
4445
4446         if (ctx == NULL || dst == NULL || src == NULL) {
4447             CYASSL_MSG("Bad function argument");
4448             return 0;  /* failure */
4449         }
4450
4451         if (ctx->cipherType == 0xff) { 
4452             CYASSL_MSG("no init");
4453             return 0;  /* failure */
4454         }
4455
4456         switch (ctx->cipherType) {
4457
4458             case AES_128_CBC_TYPE :
4459             case AES_192_CBC_TYPE :
4460             case AES_256_CBC_TYPE :
4461                 CYASSL_MSG("AES CBC");
4462                 if (ctx->enc)
4463                     AesCbcEncrypt(&ctx->cipher.aes, dst, src, len);
4464                 else
4465                     AesCbcDecrypt(&ctx->cipher.aes, dst, src, len);
4466                 break;
4467
4468 #ifdef CYASSL_AES_COUNTER
4469             case AES_128_CTR_TYPE :
4470             case AES_192_CTR_TYPE :
4471             case AES_256_CTR_TYPE :
4472                     CYASSL_MSG("AES CTR");
4473                     AesCtrEncrypt(&ctx->cipher.aes, dst, src, len);
4474                 break;
4475 #endif
4476
4477             case DES_CBC_TYPE :
4478                 if (ctx->enc)
4479                     Des_CbcEncrypt(&ctx->cipher.des, dst, src, len);
4480                 else
4481                     Des_CbcDecrypt(&ctx->cipher.des, dst, src, len);
4482                 break;
4483                 
4484             case DES_EDE3_CBC_TYPE :
4485                 if (ctx->enc)
4486                     Des3_CbcEncrypt(&ctx->cipher.des3, dst, src, len);
4487                 else
4488                     Des3_CbcDecrypt(&ctx->cipher.des3, dst, src, len);
4489                 break;
4490
4491             case ARC4_TYPE :
4492                 Arc4Process(&ctx->cipher.arc4, dst, src, len);
4493                 break;
4494
4495             case NULL_CIPHER_TYPE :
4496                 XMEMCPY(dst, src, len);
4497                 break;
4498
4499             default: {
4500                 CYASSL_MSG("bad type");
4501                 return 0;  /* failure */
4502             }
4503         }    
4504
4505         CYASSL_MSG("CyaSSL_EVP_Cipher success");
4506         return 1;  /* success */ 
4507     }
4508
4509
4510     /* store for external read of iv, 0 on success */
4511     int  CyaSSL_StoreExternalIV(CYASSL_EVP_CIPHER_CTX* ctx)
4512     {
4513         CYASSL_ENTER("CyaSSL_StoreExternalIV");
4514
4515         if (ctx == NULL) {
4516             CYASSL_MSG("Bad function argument");
4517             return -1;
4518         }
4519     
4520         switch (ctx->cipherType) {
4521
4522             case AES_128_CBC_TYPE :
4523             case AES_192_CBC_TYPE :
4524             case AES_256_CBC_TYPE :
4525                 CYASSL_MSG("AES CBC");
4526                 memcpy(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
4527                 break;
4528
4529 #ifdef CYASSL_AES_COUNTER
4530             case AES_128_CTR_TYPE :
4531             case AES_192_CTR_TYPE :
4532             case AES_256_CTR_TYPE :
4533                 CYASSL_MSG("AES CTR");
4534                 memcpy(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
4535                 break;
4536 #endif
4537
4538             case DES_CBC_TYPE :
4539                 CYASSL_MSG("DES CBC");
4540                 memcpy(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
4541                 break;
4542                 
4543             case DES_EDE3_CBC_TYPE :
4544                 CYASSL_MSG("DES EDE3 CBC");
4545                 memcpy(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
4546                 break;
4547
4548             case ARC4_TYPE :
4549                 CYASSL_MSG("ARC4");
4550                 break;
4551
4552             case NULL_CIPHER_TYPE :
4553                 CYASSL_MSG("NULL");
4554                 break;
4555
4556             default: {
4557                 CYASSL_MSG("bad type");
4558                 return -1;  /* failure */
4559             }
4560         }    
4561         return 0;  /* success */
4562     }
4563
4564
4565     /* set internal IV from external, 0 on success */
4566     int  CyaSSL_SetInternalIV(CYASSL_EVP_CIPHER_CTX* ctx)
4567     {
4568
4569         CYASSL_ENTER("CyaSSL_SetInternalIV");
4570
4571         if (ctx == NULL) {
4572             CYASSL_MSG("Bad function argument");
4573             return -1;
4574         }
4575     
4576         switch (ctx->cipherType) {
4577
4578             case AES_128_CBC_TYPE :
4579             case AES_192_CBC_TYPE :
4580             case AES_256_CBC_TYPE :
4581                 CYASSL_MSG("AES CBC");
4582                 memcpy(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
4583                 break;
4584
4585 #ifdef CYASSL_AES_COUNTER
4586             case AES_128_CTR_TYPE :
4587             case AES_192_CTR_TYPE :
4588             case AES_256_CTR_TYPE :
4589                 CYASSL_MSG("AES CTR");
4590                 memcpy(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
4591                 break;
4592 #endif
4593
4594             case DES_CBC_TYPE :
4595                 CYASSL_MSG("DES CBC");
4596                 memcpy(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
4597                 break;
4598                 
4599             case DES_EDE3_CBC_TYPE :
4600                 CYASSL_MSG("DES EDE3 CBC");
4601                 memcpy(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
4602                 break;
4603
4604             case ARC4_TYPE :
4605                 CYASSL_MSG("ARC4");
4606                 break;
4607
4608             case NULL_CIPHER_TYPE :
4609                 CYASSL_MSG("NULL");
4610                 break;
4611
4612             default: {
4613                 CYASSL_MSG("bad type");
4614                 return -1;  /* failure */
4615             }
4616         }    
4617         return 0;  /* success */
4618     }
4619
4620
4621     int CyaSSL_EVP_DigestInit(CYASSL_EVP_MD_CTX* ctx, const CYASSL_EVP_MD* type)
4622     {
4623         CYASSL_ENTER("EVP_DigestInit");
4624         if (XSTRNCMP(type, "MD5", 3) == 0) {
4625              ctx->macType = MD5;
4626              CyaSSL_MD5_Init((MD5_CTX*)&ctx->hash);
4627         }
4628         else if (XSTRNCMP(type, "SHA256", 6) == 0) {
4629              ctx->macType = SHA256;
4630              CyaSSL_SHA256_Init((SHA256_CTX*)&ctx->hash);
4631         }
4632     #ifdef CYASSL_SHA384
4633         else if (XSTRNCMP(type, "SHA384", 6) == 0) {
4634              ctx->macType = SHA384;
4635              CyaSSL_SHA384_Init((SHA384_CTX*)&ctx->hash);
4636         }
4637     #endif
4638     #ifdef CYASSL_SHA512
4639         else if (XSTRNCMP(type, "SHA512", 6) == 0) {
4640              ctx->macType = SHA512;
4641              CyaSSL_SHA512_Init((SHA512_CTX*)&ctx->hash);
4642         }
4643     #endif
4644         /* has to be last since would pick or 256, 384, or 512 too */
4645         else if (XSTRNCMP(type, "SHA", 3) == 0) {
4646              ctx->macType = SHA;
4647              CyaSSL_SHA_Init((SHA_CTX*)&ctx->hash);
4648         }    
4649         else
4650              return BAD_FUNC_ARG;
4651
4652         return 0;
4653     }
4654
4655
4656     int CyaSSL_EVP_DigestUpdate(CYASSL_EVP_MD_CTX* ctx, const void* data,
4657                                 unsigned long sz)
4658     {
4659         CYASSL_ENTER("EVP_DigestUpdate");
4660         if (ctx->macType == MD5) 
4661             CyaSSL_MD5_Update((MD5_CTX*)&ctx->hash, data, (unsigned long)sz);
4662         else if (ctx->macType == SHA) 
4663             CyaSSL_SHA_Update((SHA_CTX*)&ctx->hash, data, (unsigned long)sz);
4664         else if (ctx->macType == SHA256) 
4665             CyaSSL_SHA256_Update((SHA256_CTX*)&ctx->hash, data,
4666                                  (unsigned long)sz);
4667     #ifdef CYASSL_SHA384
4668         else if (ctx->macType == SHA384) 
4669             CyaSSL_SHA384_Update((SHA384_CTX*)&ctx->hash, data,
4670                                  (unsigned long)sz);
4671     #endif
4672     #ifdef CYASSL_SHA512
4673         else if (ctx->macType == SHA512) 
4674             CyaSSL_SHA512_Update((SHA512_CTX*)&ctx->hash, data,
4675                                  (unsigned long)sz);
4676     #endif
4677         else
4678             return BAD_FUNC_ARG;
4679
4680         return 0;
4681     }
4682
4683
4684     int CyaSSL_EVP_DigestFinal(CYASSL_EVP_MD_CTX* ctx, unsigned char* md,
4685                                unsigned int* s)
4686     {
4687         CYASSL_ENTER("EVP_DigestFinal");
4688         if (ctx->macType == MD5) {
4689             CyaSSL_MD5_Final(md, (MD5_CTX*)&ctx->hash);
4690             if (s) *s = MD5_DIGEST_SIZE;
4691         }
4692         else if (ctx->macType == SHA) {
4693             CyaSSL_SHA_Final(md, (SHA_CTX*)&ctx->hash);
4694             if (s) *s = SHA_DIGEST_SIZE;
4695         }
4696         else if (ctx->macType == SHA256) {
4697             CyaSSL_SHA256_Final(md, (SHA256_CTX*)&ctx->hash);
4698             if (s) *s = SHA256_DIGEST_SIZE;
4699         }
4700     #ifdef CYASSL_SHA384
4701         else if (ctx->macType == SHA384) {
4702             CyaSSL_SHA384_Final(md, (SHA384_CTX*)&ctx->hash);
4703             if (s) *s = SHA384_DIGEST_SIZE;
4704         }
4705     #endif
4706     #ifdef CYASSL_SHA512
4707         else if (ctx->macType == SHA512) {
4708             CyaSSL_SHA512_Final(md, (SHA512_CTX*)&ctx->hash);
4709             if (s) *s = SHA512_DIGEST_SIZE;
4710         }
4711     #endif
4712         else
4713             return BAD_FUNC_ARG;
4714
4715         return 0;
4716     }
4717
4718
4719     int CyaSSL_EVP_DigestFinal_ex(CYASSL_EVP_MD_CTX* ctx, unsigned char* md,
4720                                   unsigned int* s)
4721     {
4722         CYASSL_ENTER("EVP_DigestFinal_ex");
4723         return EVP_DigestFinal(ctx, md, s);
4724     }
4725
4726
4727     unsigned char* CyaSSL_HMAC(const CYASSL_EVP_MD* evp_md, const void* key,
4728                                int key_len, const unsigned char* d, int n,
4729                                unsigned char* md, unsigned int* md_len)
4730     {
4731         Hmac hmac;
4732
4733         CYASSL_ENTER("HMAC");
4734         if (!md) return 0;  /* no static buffer support */
4735
4736         if (XSTRNCMP(evp_md, "MD5", 3) == 0) {
4737             HmacSetKey(&hmac, MD5, (const byte*)key, key_len);
4738             if (md_len) *md_len = MD5_DIGEST_SIZE;
4739         }
4740         else if (XSTRNCMP(evp_md, "SHA", 3) == 0) {
4741             HmacSetKey(&hmac, SHA, (const byte*)key, key_len);    
4742             if (md_len) *md_len = SHA_DIGEST_SIZE;
4743         }
4744         else
4745             return 0;
4746
4747         HmacUpdate(&hmac, d, n);
4748         HmacFinal(&hmac, md);
4749     
4750         return md;
4751     }
4752
4753     void CyaSSL_ERR_clear_error(void)
4754     {
4755         /* TODO: */
4756     }
4757
4758
4759     int CyaSSL_RAND_status(void)
4760     {
4761         return 1;  /* CTaoCrypt provides enough seed internally */
4762     }
4763
4764
4765
4766     void CyaSSL_RAND_add(const void* add, int len, double entropy)
4767     {
4768         (void)add;
4769         (void)len;
4770         (void)entropy;
4771
4772         /* CyaSSL seeds/adds internally, use explicit RNG if you want
4773            to take control */
4774     }
4775
4776
4777     int CyaSSL_DES_key_sched(CYASSL_const_DES_cblock* key,
4778                              CYASSL_DES_key_schedule* schedule)
4779     {
4780         CYASSL_ENTER("DES_key_sched");
4781         XMEMCPY(schedule, key, sizeof(const_DES_cblock));
4782         return 0;
4783     }
4784
4785
4786     void CyaSSL_DES_cbc_encrypt(const unsigned char* input,
4787                      unsigned char* output, long length,
4788                      CYASSL_DES_key_schedule* schedule, CYASSL_DES_cblock* ivec,
4789                      int enc)
4790     {
4791         Des myDes;
4792         CYASSL_ENTER("DES_cbc_encrypt");
4793         Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
4794
4795         if (enc)
4796             Des_CbcEncrypt(&myDes, output, input, length);
4797         else
4798             Des_CbcDecrypt(&myDes, output, input, length);
4799     }
4800
4801
4802     /* correctly sets ivec for next call */
4803     void CyaSSL_DES_ncbc_encrypt(const unsigned char* input,
4804                      unsigned char* output, long length,
4805                      CYASSL_DES_key_schedule* schedule, CYASSL_DES_cblock* ivec,
4806                      int enc)
4807     {
4808         Des myDes;
4809         CYASSL_ENTER("DES_ncbc_encrypt");
4810         Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
4811
4812         if (enc)
4813             Des_CbcEncrypt(&myDes, output, input, length);
4814         else
4815             Des_CbcDecrypt(&myDes, output, input, length);
4816
4817         XMEMCPY(ivec, output + length - sizeof(DES_cblock), sizeof(DES_cblock));
4818     }
4819
4820
4821     void CyaSSL_ERR_free_strings(void)
4822     {
4823         /* handled internally */
4824     }
4825
4826
4827     void CyaSSL_ERR_remove_state(unsigned long state)
4828     {
4829         /* TODO: GetErrors().Remove(); */
4830         (void)state; 
4831     }
4832
4833
4834     void CyaSSL_EVP_cleanup(void)
4835     {
4836         /* nothing to do here */
4837     }
4838
4839
4840     void CyaSSL_cleanup_all_ex_data(void)
4841     {
4842         /* nothing to do here */
4843     }
4844
4845
4846     long CyaSSL_CTX_set_mode(CYASSL_CTX* ctx, long mode)
4847     {
4848         /* SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is CyaSSL default mode */
4849
4850         CYASSL_ENTER("SSL_CTX_set_mode");
4851         if (mode == SSL_MODE_ENABLE_PARTIAL_WRITE)
4852             ctx->partialWrite = 1;
4853
4854         return mode;
4855     }
4856
4857
4858     long CyaSSL_CTX_get_mode(CYASSL_CTX* ctx)
4859     {
4860         /* TODO: */
4861         (void)ctx; 
4862         return 0;
4863     }
4864
4865
4866     void CyaSSL_CTX_set_default_read_ahead(CYASSL_CTX* ctx, int m)
4867     {
4868         /* TODO: maybe? */
4869         (void)ctx; 
4870         (void)m; 
4871     }
4872
4873
4874     int CyaSSL_CTX_set_session_id_context(CYASSL_CTX* ctx,
4875                                        const unsigned char* sid_ctx,
4876                                        unsigned int sid_ctx_len)
4877     {
4878         /* No application specific context needed for cyaSSL */
4879         (void)ctx; 
4880         (void)sid_ctx; 
4881         (void)sid_ctx_len; 
4882         return SSL_SUCCESS;
4883     }
4884
4885
4886     long CyaSSL_CTX_sess_get_cache_size(CYASSL_CTX* ctx)
4887     {
4888         /* TODO: maybe? */
4889         (void)ctx; 
4890         return (~0);
4891     }
4892
4893     unsigned long CyaSSL_ERR_get_error_line_data(const char** file, int* line,
4894                                           const char** data, int *flags)
4895     {
4896         /* Not implemented */
4897         (void)file; 
4898         (void)line; 
4899         (void)data; 
4900         (void)flags; 
4901         return 0;
4902     }
4903
4904
4905     CYASSL_X509* CyaSSL_get_peer_certificate(CYASSL* ssl)
4906     {
4907         CYASSL_ENTER("SSL_get_peer_certificate");
4908         if (ssl->peerCert.issuer.sz)
4909             return &ssl->peerCert;
4910         else
4911             return 0;
4912     }
4913
4914
4915
4916     int CyaSSL_set_ex_data(CYASSL* ssl, int idx, void* data)
4917     {
4918 #ifdef FORTRESS
4919         if (ssl != NULL && idx < MAX_EX_DATA)
4920         {
4921             ssl->ex_data[idx] = data;
4922             return SSL_SUCCESS;
4923         }
4924 #else
4925         (void)ssl;
4926         (void)idx;
4927         (void)data;
4928 #endif
4929         return SSL_FAILURE;
4930     }
4931
4932
4933     int CyaSSL_get_shutdown(const CYASSL* ssl)
4934     {
4935         (void)ssl;
4936         return 0;
4937     }
4938
4939
4940     int CyaSSL_set_session_id_context(CYASSL* ssl, const unsigned char* id,
4941                                    unsigned int len)
4942     {
4943         (void)ssl;
4944         (void)id;
4945         (void)len;
4946         return 0;
4947     }
4948
4949
4950     void CyaSSL_set_connect_state(CYASSL* ssl)
4951     {
4952         (void)ssl;
4953         /* client by default */ 
4954     }
4955
4956
4957     int CyaSSL_session_reused(CYASSL* ssl)
4958     {
4959         return ssl->options.resuming;
4960     }
4961
4962
4963     void CyaSSL_SESSION_free(CYASSL_SESSION* session)
4964     {
4965         (void)session;
4966     }
4967
4968
4969     const char* CyaSSL_get_version(CYASSL* ssl)
4970     {
4971         CYASSL_ENTER("SSL_get_version");
4972         if (ssl->version.major == SSLv3_MAJOR) {
4973             switch (ssl->version.minor) {
4974                 case SSLv3_MINOR :
4975                     return "SSLv3";
4976                 case TLSv1_MINOR :
4977                     return "TLSv1";
4978                 case TLSv1_1_MINOR :
4979                     return "TLSv1.1";
4980                 case TLSv1_2_MINOR :
4981                     return "TLSv1.2";
4982                 default:
4983                     return "unknown";
4984             }
4985         }
4986         else if (ssl->version.major == DTLS_MAJOR)
4987             return "DTLS";
4988         return "unknown";
4989     }
4990
4991
4992     CYASSL_CIPHER* CyaSSL_get_current_cipher(CYASSL* ssl)
4993     {
4994         CYASSL_ENTER("SSL_get_current_cipher");
4995         if (ssl)
4996             return &ssl->cipher;
4997         else
4998             return NULL;
4999     }
5000
5001
5002     const char* CyaSSL_CIPHER_get_name(const CYASSL_CIPHER* cipher)
5003     {
5004         CYASSL_ENTER("SSL_CIPHER_get_name");
5005         if (cipher) {
5006 #ifdef HAVE_ECC
5007             if (cipher->ssl->options.cipherSuite0 == ECC_BYTE) {
5008             /* ECC suites */
5009             switch (cipher->ssl->options.cipherSuite) {
5010                 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
5011                     return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
5012                 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
5013                     return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
5014                 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
5015                     return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
5016                 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
5017                     return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
5018                 case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
5019                     return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
5020                 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
5021                     return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
5022                 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
5023                     return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
5024                 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
5025                     return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
5026
5027                 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
5028                     return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
5029                 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
5030                     return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
5031                 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
5032                     return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
5033                 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
5034                     return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
5035                 case TLS_ECDH_RSA_WITH_RC4_128_SHA :
5036                     return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
5037                 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
5038                     return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
5039                 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
5040                     return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
5041                 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
5042                     return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
5043
5044                 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
5045                     return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
5046                 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
5047                     return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
5048                 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
5049                     return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
5050                 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
5051                     return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
5052                 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
5053                     return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
5054                 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
5055                     return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
5056                 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
5057                     return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
5058                 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
5059                     return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
5060
5061                 default:
5062                     return "NONE";
5063             }
5064             }
5065 #endif
5066             if (cipher->ssl->options.cipherSuite0 != ECC_BYTE) {
5067             /* normal suites */
5068             switch (cipher->ssl->options.cipherSuite) {
5069                 case SSL_RSA_WITH_RC4_128_SHA :
5070                     return "SSL_RSA_WITH_RC4_128_SHA";
5071                 case SSL_RSA_WITH_RC4_128_MD5 :
5072                     return "SSL_RSA_WITH_RC4_128_MD5";
5073                 case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
5074                     return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
5075                 case TLS_RSA_WITH_AES_128_CBC_SHA :
5076                     return "TLS_RSA_WITH_AES_128_CBC_SHA";
5077                 case TLS_RSA_WITH_AES_256_CBC_SHA :
5078                     return "TLS_RSA_WITH_AES_256_CBC_SHA";
5079                 case TLS_RSA_WITH_AES_128_CBC_SHA256 :
5080                     return "TLS_RSA_WITH_AES_128_CBC_SHA256";
5081                 case TLS_RSA_WITH_AES_256_CBC_SHA256 :
5082                     return "TLS_RSA_WITH_AES_256_CBC_SHA256";
5083                 case TLS_PSK_WITH_AES_128_CBC_SHA :
5084                     return "TLS_PSK_WITH_AES_128_CBC_SHA";
5085                 case TLS_PSK_WITH_AES_256_CBC_SHA :
5086                     return "TLS_PSK_WITH_AES_256_CBC_SHA";
5087                 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
5088                     return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
5089                 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
5090                     return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
5091                 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
5092                     return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
5093                 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
5094                     return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
5095                 case TLS_RSA_WITH_HC_128_CBC_MD5 :
5096                     return "TLS_RSA_WITH_HC_128_CBC_MD5";
5097                 case TLS_RSA_WITH_HC_128_CBC_SHA :
5098                     return "TLS_RSA_WITH_HC_128_CBC_SHA";
5099                 case TLS_RSA_WITH_RABBIT_CBC_SHA :
5100                     return "TLS_RSA_WITH_RABBIT_CBC_SHA";
5101                 case TLS_NTRU_RSA_WITH_RC4_128_SHA :
5102                     return "TLS_NTRU_RSA_WITH_RC4_128_SHA";
5103                 case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
5104                     return "TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA";
5105                 case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
5106                     return "TLS_NTRU_RSA_WITH_AES_128_CBC_SHA";
5107                 case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
5108                     return "TLS_NTRU_RSA_WITH_AES_256_CBC_SHA";
5109                 case TLS_RSA_WITH_AES_128_GCM_SHA256 :
5110                     return "TLS_RSA_WITH_AES_128_GCM_SHA256";
5111                 case TLS_RSA_WITH_AES_256_GCM_SHA384 :
5112                     return "TLS_RSA_WITH_AES_256_GCM_SHA384";
5113                 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
5114                     return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
5115                 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
5116                     return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
5117                 default:
5118                     return "NONE";
5119             }  /* switch */
5120             }  /* normal / ECC */
5121         }
5122
5123         return "NONE";
5124     }
5125
5126
5127     const char* CyaSSL_get_cipher(CYASSL* ssl)
5128     {
5129         CYASSL_ENTER("CyaSSL_get_cipher");
5130         return CyaSSL_CIPHER_get_name(CyaSSL_get_current_cipher(ssl));
5131     }
5132
5133
5134     /* server ctx Diffie-Hellman parameters */
5135     int CyaSSL_CTX_SetTmpDH(CYASSL_CTX* ctx, const unsigned char* p, int pSz,
5136                             const unsigned char* g, int gSz)
5137     {
5138         CYASSL_ENTER("CyaSSL_CTX_SetTmpDH");
5139         if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
5140
5141         XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
5142         XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
5143
5144         ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap,DYNAMIC_TYPE_DH);
5145         if (ctx->serverDH_P.buffer == NULL)
5146             return MEMORY_E;
5147
5148         ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap,DYNAMIC_TYPE_DH);
5149         if (ctx->serverDH_G.buffer == NULL) {
5150             XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
5151             return MEMORY_E;
5152         }
5153
5154         ctx->serverDH_P.length = pSz;
5155         ctx->serverDH_G.length = gSz;
5156
5157         XMEMCPY(ctx->serverDH_P.buffer, p, pSz);
5158         XMEMCPY(ctx->serverDH_G.buffer, g, gSz);
5159
5160         ctx->haveDH = 1;
5161
5162         CYASSL_LEAVE("CyaSSL_CTX_SetTmpDH", 0);
5163         return 0;
5164     }
5165
5166
5167     char* CyaSSL_CIPHER_description(CYASSL_CIPHER* cipher, char* in, int len)
5168     {
5169         (void)cipher;
5170         (void)in;
5171         (void)len;
5172         return 0;
5173     }
5174
5175
5176     CYASSL_SESSION* CyaSSL_get1_session(CYASSL* ssl)  /* what's ref count */
5177     {
5178         (void)ssl;
5179         return 0;
5180     }
5181
5182
5183     void CyaSSL_X509_free(CYASSL_X509* buf)
5184     {
5185         (void)buf;
5186     }
5187
5188
5189     /* was do nothing */
5190     /*
5191     void OPENSSL_free(void* buf)
5192     {
5193         (void)buf;
5194     }
5195     */
5196
5197
5198     int CyaSSL_OCSP_parse_url(char* url, char** host, char** port, char** path,
5199                        int* ssl)
5200     {
5201         (void)url;
5202         (void)host;
5203         (void)port;
5204         (void)path;
5205         (void)ssl;
5206         return 0;
5207     }
5208
5209
5210     CYASSL_METHOD* CyaSSLv2_client_method(void)
5211     {
5212         return 0;
5213     }
5214
5215
5216     CYASSL_METHOD* CyaSSLv2_server_method(void)
5217     {
5218         return 0;
5219     }
5220
5221
5222 #ifndef NO_MD4
5223
5224     void CyaSSL_MD4_Init(CYASSL_MD4_CTX* md4)
5225     {
5226         /* make sure we have a big enough buffer */
5227         typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1];
5228         (void) sizeof(ok);
5229  
5230         CYASSL_ENTER("MD4_Init");
5231         InitMd4((Md4*)md4);    
5232     }
5233
5234
5235     void CyaSSL_MD4_Update(CYASSL_MD4_CTX* md4, const void* data,
5236                            unsigned long len)
5237     {
5238         CYASSL_ENTER("MD4_Update");
5239         Md4Update((Md4*)md4, (const byte*)data, (word32)len); 
5240     }
5241
5242
5243     void CyaSSL_MD4_Final(unsigned char* digest, CYASSL_MD4_CTX* md4)
5244     {
5245         CYASSL_ENTER("MD4_Final");
5246         Md4Final((Md4*)md4, digest); 
5247     }
5248
5249 #endif /* NO_MD4 */
5250
5251
5252     CYASSL_BIO* CyaSSL_BIO_pop(CYASSL_BIO* top)
5253     {
5254         (void)top;
5255         return 0;
5256     }
5257
5258
5259     int CyaSSL_BIO_pending(CYASSL_BIO* bio)
5260     {
5261         (void)bio;
5262         return 0;
5263     }
5264
5265
5266
5267     CYASSL_BIO_METHOD* CyaSSL_BIO_s_mem(void)
5268     {
5269         static CYASSL_BIO_METHOD meth;
5270
5271         CYASSL_ENTER("BIO_s_mem");
5272         meth.type = BIO_MEMORY;
5273
5274         return &meth;
5275     }
5276
5277
5278     CYASSL_BIO_METHOD* CyaSSL_BIO_f_base64(void)
5279     {
5280         return 0;
5281     }
5282
5283
5284     void CyaSSL_BIO_set_flags(CYASSL_BIO* bio, int flags)
5285     {
5286         (void)bio;
5287         (void)flags;
5288     }
5289
5290
5291
5292     void CyaSSL_RAND_screen(void)
5293     {
5294     
5295     }
5296
5297
5298     const char* CyaSSL_RAND_file_name(char* fname, unsigned long len)
5299     {
5300         (void)fname;
5301         (void)len;
5302         return 0;
5303     }
5304
5305
5306     int CyaSSL_RAND_write_file(const char* fname)
5307     {
5308         (void)fname;
5309         return 0;
5310     }
5311
5312
5313     int CyaSSL_RAND_load_file(const char* fname, long len)
5314     {
5315         (void)fname;
5316         /* CTaoCrypt provides enough entropy internally or will report error */
5317         if (len == -1)
5318             return 1024;
5319         else
5320             return (int)len;
5321     }
5322
5323
5324     int CyaSSL_RAND_egd(const char* path)
5325     {
5326         (void)path;
5327         return 0;
5328     }
5329
5330
5331
5332     CYASSL_COMP_METHOD* CyaSSL_COMP_zlib(void)
5333     {
5334         return 0;
5335     }
5336
5337
5338     CYASSL_COMP_METHOD* CyaSSL_COMP_rle(void)
5339     {
5340         return 0;
5341     }
5342
5343
5344     int CyaSSL_COMP_add_compression_method(int method, void* data)
5345     {
5346         (void)method;
5347         (void)data;
5348         return 0;
5349     }
5350
5351
5352
5353     int CyaSSL_get_ex_new_index(long idx, void* data, void* cb1, void* cb2,
5354                              void* cb3)
5355     {
5356         (void)idx;
5357         (void)data;
5358         (void)cb1;
5359         (void)cb2;
5360         (void)cb3;
5361         return 0;
5362     }
5363
5364
5365     void CyaSSL_set_dynlock_create_callback(CYASSL_dynlock_value* (*f)(
5366                                                               const char*, int))
5367     {
5368         (void)f;
5369     }
5370
5371
5372     void CyaSSL_set_dynlock_lock_callback(
5373                  void (*f)(int, CYASSL_dynlock_value*, const char*, int))
5374     {
5375         (void)f;
5376     }
5377
5378
5379     void CyaSSL_set_dynlock_destroy_callback(
5380                       void (*f)(CYASSL_dynlock_value*, const char*, int))
5381     {
5382         (void)f;
5383     }
5384
5385
5386
5387     const char* CyaSSL_X509_verify_cert_error_string(long err)
5388     {
5389         (void)err;
5390         return 0;
5391     }
5392
5393
5394
5395     int CyaSSL_X509_LOOKUP_add_dir(CYASSL_X509_LOOKUP* lookup, const char* dir,
5396                                    long len)
5397     {
5398         (void)lookup;
5399         (void)dir;
5400         (void)len;
5401         return 0;
5402     }
5403
5404
5405     int CyaSSL_X509_LOOKUP_load_file(CYASSL_X509_LOOKUP* lookup,
5406                                      const char* file, long len)
5407     {
5408         (void)lookup;
5409         (void)file;
5410         (void)len;
5411         return 0;
5412     }
5413
5414
5415     CYASSL_X509_LOOKUP_METHOD* CyaSSL_X509_LOOKUP_hash_dir(void)
5416     {
5417         return 0;
5418     }
5419
5420
5421     CYASSL_X509_LOOKUP_METHOD* CyaSSL_X509_LOOKUP_file(void)
5422     {
5423         return 0;
5424     }
5425
5426
5427
5428     CYASSL_X509_LOOKUP* CyaSSL_X509_STORE_add_lookup(CYASSL_X509_STORE* store,
5429                                                    CYASSL_X509_LOOKUP_METHOD* m)
5430     {
5431         (void)store;
5432         (void)m;
5433         return 0;
5434     }
5435
5436
5437     CYASSL_X509_STORE* CyaSSL_X509_STORE_new(void)
5438     {
5439         return 0;
5440     }
5441
5442
5443     int CyaSSL_X509_STORE_get_by_subject(CYASSL_X509_STORE_CTX* ctx, int idx,
5444                                 CYASSL_X509_NAME* name, CYASSL_X509_OBJECT* obj)
5445     {
5446         (void)ctx;
5447         (void)idx;
5448         (void)name;
5449         (void)obj;
5450         return 0;
5451     }
5452
5453
5454     int CyaSSL_X509_STORE_CTX_init(CYASSL_X509_STORE_CTX* ctx,
5455          CYASSL_X509_STORE* store, CYASSL_X509* x509, STACK_OF(CYASSL_X509)* sk)
5456     {
5457         (void)ctx;
5458         (void)store;
5459         (void)x509;
5460         (void)sk;
5461         return 0;
5462     }
5463
5464
5465     void CyaSSL_X509_STORE_CTX_cleanup(CYASSL_X509_STORE_CTX* ctx)
5466     {
5467         (void)ctx;
5468     }
5469
5470
5471
5472     CYASSL_ASN1_TIME* CyaSSL_X509_CRL_get_lastUpdate(CYASSL_X509_CRL* crl)
5473     {
5474         (void)crl;
5475         return 0;
5476     }
5477
5478
5479     CYASSL_ASN1_TIME* CyaSSL_X509_CRL_get_nextUpdate(CYASSL_X509_CRL* crl)
5480     {
5481         (void)crl;
5482         return 0;
5483     }
5484
5485
5486
5487     CYASSL_EVP_PKEY* CyaSSL_X509_get_pubkey(CYASSL_X509* x509)
5488     {
5489         (void)x509;
5490         return 0;
5491     }
5492
5493
5494     int CyaSSL_X509_CRL_verify(CYASSL_X509_CRL* crl, CYASSL_EVP_PKEY* key)
5495     {
5496         (void)crl;
5497         (void)key;
5498         return 0;
5499     }
5500
5501
5502     void CyaSSL_X509_STORE_CTX_set_error(CYASSL_X509_STORE_CTX* ctx, int err)
5503     {
5504         (void)ctx;
5505         (void)err;
5506     }
5507
5508
5509     void CyaSSL_X509_OBJECT_free_contents(CYASSL_X509_OBJECT* obj)
5510     {
5511         (void)obj;
5512     }
5513
5514
5515     void CyaSSL_EVP_PKEY_free(CYASSL_EVP_PKEY* key)
5516     {
5517         (void)key;
5518     }
5519
5520
5521     int CyaSSL_X509_cmp_current_time(const CYASSL_ASN1_TIME* asnTime)
5522     {
5523         (void)asnTime;
5524         return 0;
5525     }
5526
5527
5528     int CyaSSL_sk_X509_REVOKED_num(CYASSL_X509_REVOKED* revoked)
5529     {
5530         (void)revoked;
5531         return 0;
5532     }
5533
5534
5535
5536     CYASSL_X509_REVOKED* CyaSSL_X509_CRL_get_REVOKED(CYASSL_X509_CRL* crl)
5537     {
5538         (void)crl;
5539         return 0;
5540     }
5541
5542
5543     CYASSL_X509_REVOKED* CyaSSL_sk_X509_REVOKED_value(
5544                                         CYASSL_X509_REVOKED* revoked, int value)
5545     {
5546         (void)revoked;
5547         (void)value;
5548         return 0;
5549     }
5550
5551
5552
5553     CYASSL_ASN1_INTEGER* CyaSSL_X509_get_serialNumber(CYASSL_X509* x509)
5554     {
5555         (void)x509;
5556         return 0;
5557     }
5558
5559
5560     int CyaSSL_ASN1_TIME_print(CYASSL_BIO* bio, const CYASSL_ASN1_TIME* asnTime)
5561     {
5562         (void)bio;
5563         (void)asnTime;
5564         return 0;
5565     }
5566
5567
5568
5569     int CyaSSL_ASN1_INTEGER_cmp(const CYASSL_ASN1_INTEGER* a,
5570                                 const CYASSL_ASN1_INTEGER* b)
5571     {
5572         (void)a;
5573         (void)b;
5574         return 0;
5575     }
5576
5577
5578     long CyaSSL_ASN1_INTEGER_get(const CYASSL_ASN1_INTEGER* i)
5579     {
5580         (void)i;
5581         return 0;
5582     }
5583
5584
5585
5586     void* CyaSSL_X509_STORE_CTX_get_ex_data(CYASSL_X509_STORE_CTX* ctx, int idx)
5587     {
5588 #ifdef FORTRESS
5589         if (ctx != NULL && idx == 0)
5590             return ctx->ex_data;
5591 #else
5592         (void)ctx;
5593         (void)idx;
5594 #endif
5595         return 0;
5596     }
5597
5598
5599     int CyaSSL_get_ex_data_X509_STORE_CTX_idx(void)
5600     {
5601         return 0;
5602     }
5603
5604
5605     void* CyaSSL_get_ex_data(const CYASSL* ssl, int idx)
5606     {
5607 #ifdef FORTRESS
5608         if (ssl != NULL && idx < MAX_EX_DATA)
5609             return ssl->ex_data[idx];
5610 #else
5611         (void)ssl;
5612         (void)idx;
5613 #endif
5614         return 0;
5615     }
5616
5617
5618     void CyaSSL_CTX_set_info_callback(CYASSL_CTX* ctx, void (*f)(void))
5619     {
5620         (void)ctx;
5621         (void)f;
5622     }
5623
5624
5625     unsigned long CyaSSL_ERR_peek_error(void)
5626     {
5627         return 0;
5628     }
5629
5630
5631     int CyaSSL_ERR_GET_REASON(int err)
5632     {
5633         (void)err;
5634         return 0;
5635     }
5636
5637
5638     char* CyaSSL_alert_type_string_long(int alertID)
5639     {
5640         (void)alertID;
5641         return 0;
5642     }
5643
5644
5645     char* CyaSSL_alert_desc_string_long(int alertID)
5646     {
5647         (void)alertID;
5648         return 0;
5649     }
5650
5651
5652     char* CyaSSL_state_string_long(CYASSL* ssl)
5653     {
5654         (void)ssl;
5655         return 0;
5656     }
5657
5658
5659     int CyaSSL_PEM_def_callback(char* name, int num, int w, void* key)
5660     {
5661         (void)name;
5662         (void)num;
5663         (void)w;
5664         (void)key;
5665         return 0;
5666     }
5667     
5668
5669     long CyaSSL_CTX_sess_accept(CYASSL_CTX* ctx)
5670     {
5671         (void)ctx;
5672         return 0;
5673     }
5674
5675
5676     long CyaSSL_CTX_sess_connect(CYASSL_CTX* ctx)
5677     {
5678         (void)ctx;
5679         return 0;
5680     }
5681
5682
5683     long CyaSSL_CTX_sess_accept_good(CYASSL_CTX* ctx)
5684     {
5685         (void)ctx;
5686         return 0;
5687     }
5688
5689
5690     long CyaSSL_CTX_sess_connect_good(CYASSL_CTX* ctx)
5691     {
5692         (void)ctx;
5693         return 0;
5694     }
5695
5696
5697     long CyaSSL_CTX_sess_accept_renegotiate(CYASSL_CTX* ctx)
5698     {
5699         (void)ctx;
5700         return 0;
5701     }
5702
5703
5704     long CyaSSL_CTX_sess_connect_renegotiate(CYASSL_CTX* ctx)
5705     {
5706         (void)ctx;
5707         return 0;
5708     }
5709
5710
5711     long CyaSSL_CTX_sess_hits(CYASSL_CTX* ctx)
5712     {
5713         (void)ctx;
5714         return 0;
5715     }
5716
5717
5718     long CyaSSL_CTX_sess_cb_hits(CYASSL_CTX* ctx)
5719     {
5720         (void)ctx;
5721         return 0;
5722     }
5723
5724
5725     long CyaSSL_CTX_sess_cache_full(CYASSL_CTX* ctx)
5726     {
5727         (void)ctx;
5728         return 0;
5729     }
5730
5731
5732     long CyaSSL_CTX_sess_misses(CYASSL_CTX* ctx)
5733     {
5734         (void)ctx;
5735         return 0;
5736     }
5737
5738
5739     long CyaSSL_CTX_sess_timeouts(CYASSL_CTX* ctx)
5740     {
5741         (void)ctx;
5742         return 0;
5743     }
5744
5745
5746     long CyaSSL_CTX_sess_number(CYASSL_CTX* ctx)
5747     {
5748         (void)ctx;
5749         return 0;
5750     }
5751
5752
5753     void CyaSSL_DES_set_key_unchecked(CYASSL_const_DES_cblock* myDes,
5754                                                    CYASSL_DES_key_schedule* key)
5755     {
5756         (void)myDes;
5757         (void)key;
5758     }
5759
5760
5761     void CyaSSL_DES_set_odd_parity(CYASSL_DES_cblock* myDes)
5762     {
5763         (void)myDes;
5764     }
5765
5766     
5767     void CyaSSL_DES_ecb_encrypt(CYASSL_DES_cblock* desa,
5768                  CYASSL_DES_cblock* desb, CYASSL_DES_key_schedule* key, int len)
5769     {
5770         (void)desa;
5771         (void)desb;
5772         (void)key;
5773         (void)len;
5774     }
5775
5776     int CyaSSL_BIO_printf(CYASSL_BIO* bio, const char* format, ...)
5777     {
5778         (void)bio;
5779         (void)format;
5780         return 0;
5781     }
5782
5783
5784     int CyaSSL_ASN1_UTCTIME_print(CYASSL_BIO* bio, const CYASSL_ASN1_UTCTIME* a)
5785     {
5786         (void)bio;
5787         (void)a;
5788         return 0;
5789     }
5790     
5791
5792     int  CyaSSL_sk_num(CYASSL_X509_REVOKED* rev)
5793     {
5794         (void)rev;
5795         return 0;
5796     }
5797
5798
5799     void* CyaSSL_sk_value(CYASSL_X509_REVOKED* rev, int i)
5800     {
5801         (void)rev;
5802         (void)i;
5803         return 0;
5804     }
5805
5806
5807     /* stunnel 4.28 needs */
5808     void* CyaSSL_CTX_get_ex_data(const CYASSL_CTX* ctx, int d)
5809     {
5810         (void)ctx;
5811         (void)d;
5812         return 0;
5813     }
5814
5815
5816     int CyaSSL_CTX_set_ex_data(CYASSL_CTX* ctx, int d, void* p)
5817     {
5818         (void)ctx;
5819         (void)d;
5820         (void)p;
5821         return SSL_SUCCESS;
5822     }
5823
5824
5825     void CyaSSL_CTX_sess_set_get_cb(CYASSL_CTX* ctx,
5826                         CYASSL_SESSION*(*f)(CYASSL*, unsigned char*, int, int*))
5827     {
5828         (void)ctx;
5829         (void)f;
5830     }
5831
5832
5833     void CyaSSL_CTX_sess_set_new_cb(CYASSL_CTX* ctx,
5834                                  int (*f)(CYASSL*, CYASSL_SESSION*))
5835     {
5836         (void)ctx;
5837         (void)f;
5838     }
5839
5840
5841     void CyaSSL_CTX_sess_set_remove_cb(CYASSL_CTX* ctx, void (*f)(CYASSL_CTX*,
5842                                                             CYASSL_SESSION*))
5843     {
5844         (void)ctx;
5845         (void)f;
5846     }
5847
5848
5849     int CyaSSL_i2d_SSL_SESSION(CYASSL_SESSION* sess, unsigned char** p)
5850     {
5851         (void)sess;
5852         (void)p;
5853         return sizeof(CYASSL_SESSION);
5854     }
5855
5856
5857     CYASSL_SESSION* CyaSSL_d2i_SSL_SESSION(CYASSL_SESSION** sess,
5858                                     const unsigned char** p, long i)
5859     {
5860         (void)p;
5861         (void)i;
5862         if (sess)
5863             return *sess;
5864         return NULL;
5865     }
5866
5867
5868     long CyaSSL_SESSION_get_timeout(const CYASSL_SESSION* sess)
5869     {
5870         CYASSL_ENTER("CyaSSL_SESSION_get_timeout");
5871         return sess->timeout;
5872     }
5873
5874
5875     long CyaSSL_SESSION_get_time(const CYASSL_SESSION* sess)
5876     {
5877         CYASSL_ENTER("CyaSSL_SESSION_get_time");
5878         return sess->bornOn;
5879     }
5880
5881
5882     int CyaSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b,
5883                                     void* c)
5884     {
5885         (void)idx;
5886         (void)arg;
5887         (void)a;
5888         (void)b;
5889         (void)c;
5890         return 0; 
5891     }
5892
5893     /* write X509 serial number in unsigned binary to buffer 
5894        buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
5895        return 0 on success */
5896     int CyaSSL_X509_get_serial_number(CYASSL_X509* x509, byte* in, int* inOutSz)
5897     {
5898         CYASSL_ENTER("CyaSSL_X509_get_serial_number");
5899         if (x509 == NULL || in == NULL || *inOutSz < x509->serialSz)
5900             return BAD_FUNC_ARG;
5901
5902         XMEMCPY(in, x509->serial, x509->serialSz);
5903         *inOutSz = x509->serialSz;
5904
5905         return 0;
5906     }
5907
5908
5909     const byte* CyaSSL_X509_get_der(CYASSL_X509* x509, int* outSz)
5910     { 
5911         CYASSL_ENTER("CyaSSL_X509_get_der");
5912         
5913         if (x509 == NULL || outSz == NULL)
5914             return NULL;
5915
5916         *outSz = (int)x509->derCert.length;
5917         return x509->derCert.buffer;
5918     }  
5919
5920
5921     char*  CyaSSL_X509_get_subjectCN(CYASSL_X509* x509)
5922     {
5923         if (x509 == NULL)
5924             return NULL;
5925
5926         return x509->subjectCN;
5927     }
5928
5929
5930 #ifdef FORTRESS
5931     int CyaSSL_cmp_peer_cert_to_file(CYASSL* ssl, const char *fname)
5932     {
5933         int ret = -1;
5934
5935         CYASSL_ENTER("CyaSSL_cmp_peer_cert_to_file");
5936         if (ssl != NULL && fname != NULL)
5937         {
5938             XFILE*        file = NULL;
5939             int           sz = 0;
5940             byte          staticBuffer[FILE_BUFFER_SIZE];
5941             byte*         myBuffer = staticBuffer;
5942             CYASSL_CTX*   ctx = ssl->ctx;
5943             EncryptedInfo info;
5944             buffer        fileDer;
5945             int           eccKey = 0;
5946             CYASSL_X509*  peer_cert = &ssl->peerCert;
5947
5948             info.set = 0;
5949             info.ctx = ctx;
5950             info.consumed = 0;
5951             fileDer.buffer = 0;
5952
5953             file = XFOPEN(fname, "rb"); 
5954             if (!file) return SSL_BAD_FILE;
5955             XFSEEK(file, 0, XSEEK_END);
5956             sz = XFTELL(file);
5957             XREWIND(file);
5958             if (sz > (long)sizeof(staticBuffer)) {
5959                 CYASSL_MSG("Getting dynamic buffer");
5960                 myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
5961             }
5962             
5963             if ((myBuffer != NULL) &&
5964                 (XFREAD(myBuffer, sz, 1, file) > 0) &&
5965                 (PemToDer(myBuffer, sz, CERT_TYPE,
5966                                 &fileDer, ctx->heap, &info, &eccKey) == 0) &&
5967                 (fileDer.length != 0) &&
5968                 (fileDer.length == peer_cert->derCert.length) &&
5969                 (XMEMCMP(peer_cert->derCert.buffer, fileDer.buffer,
5970                                                     fileDer.length) == 0))
5971             {
5972                 ret = 0;
5973             }
5974
5975             XFCLOSE(file);
5976             if (fileDer.buffer)
5977                 XFREE(fileDer.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
5978             if (myBuffer && (myBuffer != staticBuffer))
5979                 XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
5980         }
5981
5982         return ret;
5983     }
5984 #else
5985     int CyaSSL_cmp_peer_cert_to_file(CYASSL* ssl, const char *fname)
5986     {
5987         (void)ssl;
5988         (void)fname;
5989         return -1;
5990     }
5991 #endif
5992
5993
5994 static RNG globalRNG;
5995 static int initGlobalRNG = 0;
5996
5997     int CyaSSL_RAND_seed(const void* seed, int len)
5998     {
5999
6000         CYASSL_MSG("CyaSSL_RAND_seed");
6001
6002         (void)seed;
6003         (void)len;
6004
6005         if (initGlobalRNG == 0) {
6006             if (InitRng(&globalRNG) < 0) {
6007                 CYASSL_MSG("CyaSSL Init Global RNG failed");
6008             }
6009             initGlobalRNG = 1;
6010         }
6011
6012         return 0;
6013     }
6014
6015
6016     int CyaSSL_RAND_bytes(unsigned char* buf, int num)
6017     {
6018         RNG    tmpRNG;
6019         RNG*   rng = &tmpRNG; 
6020
6021         CYASSL_ENTER("RAND_bytes");
6022         if (InitRng(&tmpRNG) != 0) {
6023             CYASSL_MSG("Bad RNG Init, trying global");
6024             if (initGlobalRNG == 0) {
6025                 CYASSL_MSG("Global RNG no Init");
6026                 return 0; 
6027             }
6028             rng = &globalRNG;
6029         }
6030
6031         RNG_GenerateBlock(rng, buf, num);
6032
6033         return 1;
6034     }
6035
6036     CYASSL_BN_CTX* CyaSSL_BN_CTX_new(void)
6037     {
6038         static int ctx;  /* ctaocrypt doesn't now need ctx */
6039
6040         CYASSL_MSG("CyaSSL_BN_CTX_new");
6041
6042         return (CYASSL_BN_CTX*)&ctx;
6043     }
6044
6045     void CyaSSL_BN_CTX_init(CYASSL_BN_CTX* ctx)
6046     {
6047         (void)ctx;
6048         CYASSL_MSG("CyaSSL_BN_CTX_init");
6049     }
6050
6051
6052     void CyaSSL_BN_CTX_free(CYASSL_BN_CTX* ctx)
6053     {
6054         (void)ctx;
6055         CYASSL_MSG("CyaSSL_BN_CTX_free");
6056
6057         /* do free since static ctx that does nothing */
6058     }
6059
6060
6061     static void InitCyaSSL_BigNum(CYASSL_BIGNUM* bn)
6062     { 
6063         CYASSL_MSG("InitCyaSSL_BigNum");
6064         if (bn) {
6065             bn->neg      = 0;
6066             bn->internal = NULL;
6067         }
6068     }
6069
6070
6071     CYASSL_BIGNUM* CyaSSL_BN_new(void)
6072     {
6073         CYASSL_BIGNUM* external;
6074         mp_int*        mpi;
6075
6076         CYASSL_MSG("CyaSSL_BN_new");
6077
6078         mpi = (mp_int*) XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
6079         if (mpi == NULL) {
6080             CYASSL_MSG("CyaSSL_BN_new malloc mpi failure");
6081             return NULL;
6082         }
6083
6084         external = (CYASSL_BIGNUM*) XMALLOC(sizeof(CYASSL_BIGNUM), NULL,
6085                                             DYNAMIC_TYPE_BIGINT);
6086         if (external == NULL) {
6087             CYASSL_MSG("CyaSSL_BN_new malloc CYASSL_BIGNUM failure");
6088             XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
6089             return NULL;
6090         }
6091
6092         InitCyaSSL_BigNum(external);
6093         mp_init(mpi);
6094         external->internal = mpi;
6095
6096         return external;
6097     }
6098
6099
6100     void CyaSSL_BN_free(CYASSL_BIGNUM* bn)
6101     {
6102         CYASSL_MSG("CyaSSL_BN_free");
6103         if (bn) {
6104             if (bn->internal) {
6105                 mp_clear((mp_int*)bn->internal);
6106                 XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT);
6107                 bn->internal = NULL;
6108             }
6109             XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT);
6110         }
6111     }
6112
6113
6114     void CyaSSL_BN_clear_free(CYASSL_BIGNUM* bn)
6115     {
6116         CYASSL_MSG("CyaSSL_BN_clear_free");
6117
6118         CyaSSL_BN_free(bn);
6119     }
6120
6121
6122     int CyaSSL_BN_sub(CYASSL_BIGNUM* r, const CYASSL_BIGNUM* a,
6123                       const CYASSL_BIGNUM* b)
6124     {
6125         CYASSL_MSG("CyaSSL_BN_sub");
6126
6127         if (r == NULL || a == NULL || b == NULL)
6128             return 0;
6129
6130         if (mp_sub((mp_int*)a->internal,(mp_int*)b->internal,
6131                    (mp_int*)r->internal) == MP_OKAY)
6132             return 1;
6133
6134         CYASSL_MSG("CyaSSL_BN_sub mp_sub failed");
6135         return 0;
6136     }
6137
6138
6139     int CyaSSL_BN_mod(CYASSL_BIGNUM* r, const CYASSL_BIGNUM* a,
6140                           const CYASSL_BIGNUM* b, const CYASSL_BN_CTX* c)
6141     {
6142         (void)c;
6143         CYASSL_MSG("CyaSSL_BN_mod");
6144
6145         if (r == NULL || a == NULL || b == NULL)
6146             return 0;
6147
6148         if (mp_mod((mp_int*)a->internal,(mp_int*)b->internal,
6149                    (mp_int*)r->internal) == MP_OKAY)
6150             return 1;
6151
6152         CYASSL_MSG("CyaSSL_BN_mod mp_mod failed");
6153         return 0;
6154     }
6155
6156
6157     const CYASSL_BIGNUM* CyaSSL_BN_value_one(void)
6158     {
6159         static CYASSL_BIGNUM* bn_one = NULL;
6160
6161         CYASSL_MSG("CyaSSL_BN_value_one");
6162
6163         if (bn_one == NULL) {
6164             bn_one = CyaSSL_BN_new();
6165             if (bn_one)
6166                 mp_set_int((mp_int*)bn_one->internal, 1);
6167         }
6168
6169         return bn_one;
6170     }
6171
6172
6173     int CyaSSL_BN_num_bytes(const CYASSL_BIGNUM* bn)
6174     {
6175         CYASSL_MSG("CyaSSL_BN_num_bytes");
6176
6177         if (bn == NULL || bn->internal == NULL)
6178             return 0;
6179
6180         return mp_unsigned_bin_size((mp_int*)bn->internal);
6181     }
6182
6183
6184     int CyaSSL_BN_num_bits(const CYASSL_BIGNUM* bn)
6185     {
6186         CYASSL_MSG("CyaSSL_BN_num_bits");
6187
6188         if (bn == NULL || bn->internal == NULL)
6189             return 0;
6190
6191         return mp_count_bits((mp_int*)bn->internal);
6192     }
6193
6194
6195     int CyaSSL_BN_is_zero(const CYASSL_BIGNUM* bn)
6196     {
6197         CYASSL_MSG("CyaSSL_BN_is_zero");
6198
6199         if (bn == NULL || bn->internal == NULL)
6200             return 0;
6201
6202         return mp_iszero((mp_int*)bn->internal);
6203     }
6204
6205
6206     int CyaSSL_BN_is_one(const CYASSL_BIGNUM* bn)
6207     {
6208         CYASSL_MSG("CyaSSL_BN_is_one");
6209
6210         if (bn == NULL || bn->internal == NULL)
6211             return 0;
6212
6213         if (mp_cmp_d((mp_int*)bn->internal, 1) == 0)
6214             return 1;
6215
6216         return 0;
6217     }
6218
6219
6220     int CyaSSL_BN_is_odd(const CYASSL_BIGNUM* bn)
6221     {
6222         CYASSL_MSG("CyaSSL_BN_is_odd");
6223
6224         if (bn == NULL || bn->internal == NULL)
6225             return 0;
6226
6227         return mp_isodd((mp_int*)bn->internal);
6228     }
6229
6230
6231     int CyaSSL_BN_cmp(const CYASSL_BIGNUM* a, const CYASSL_BIGNUM* b)
6232     {
6233         CYASSL_MSG("CyaSSL_BN_cmp");
6234
6235         if (a == NULL || a->internal == NULL || b == NULL || b->internal ==NULL)
6236             return 0;
6237
6238         return mp_cmp((mp_int*)a->internal, (mp_int*)b->internal);
6239     }
6240
6241
6242     int CyaSSL_BN_bn2bin(const CYASSL_BIGNUM* bn, unsigned char* r)
6243     {
6244         CYASSL_MSG("CyaSSL_BN_bn2bin");
6245
6246         if (bn == NULL || bn->internal == NULL) {
6247             CYASSL_MSG("NULL bn error");
6248             return -1;
6249         }
6250
6251         if (r == NULL)
6252             return mp_unsigned_bin_size((mp_int*)bn->internal);
6253
6254         if (mp_to_unsigned_bin((mp_int*)bn->internal, r) != MP_OKAY) {
6255             CYASSL_MSG("mp_to_unsigned_bin error");
6256             return -1;
6257         }
6258
6259         return mp_unsigned_bin_size((mp_int*)bn->internal);
6260     }
6261
6262
6263     CYASSL_BIGNUM* CyaSSL_BN_bin2bn(const unsigned char* str, int len,
6264                                     CYASSL_BIGNUM* ret)
6265     {
6266         CYASSL_MSG("CyaSSL_BN_bin2bn");
6267
6268         if (ret && ret->internal) {
6269             if (mp_read_unsigned_bin((mp_int*)ret->internal, str, len) != 0) {
6270                 CYASSL_MSG("mp_read_unsigned_bin failure");
6271                 return NULL;
6272             } 
6273         }
6274         else {
6275             CYASSL_MSG("CyaSSL_BN_bin2bn wants return bignum");
6276         }
6277
6278         return ret;
6279     }
6280
6281
6282     int CyaSSL_mask_bits(CYASSL_BIGNUM* bn, int n)
6283     {
6284         (void)bn;
6285         (void)n;
6286         CYASSL_MSG("CyaSSL_BN_mask_bits");
6287
6288         return -1;
6289     }
6290
6291
6292     int CyaSSL_BN_rand(CYASSL_BIGNUM* bn, int bits, int top, int bottom)
6293     {
6294         byte          buff[1024];
6295         RNG           tmpRNG;
6296         RNG*          rng = &tmpRNG; 
6297         int           ret;
6298         int           len = bits/8;
6299
6300         (void)top;
6301         (void)bottom;
6302         CYASSL_MSG("CyaSSL_BN_rand");
6303
6304         if (bn == NULL || bn->internal == NULL) {
6305             CYASSL_MSG("Bad function arguments");
6306             return 0; 
6307         }
6308
6309         if (bits % 8)
6310             len++;
6311
6312         if ( (ret = InitRng(&tmpRNG)) != 0) {
6313             CYASSL_MSG("Bad RNG Init, trying global");
6314             if (initGlobalRNG == 0) {
6315                 CYASSL_MSG("Global RNG no Init");
6316                 return 0; 
6317             }
6318             rng = &globalRNG;
6319         }
6320
6321         RNG_GenerateBlock(rng, buff, len);
6322         buff[0]     |= 0x80 | 0x40;
6323         buff[len-1] |= 0x01;
6324
6325         if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY) {
6326             CYASSL_MSG("mp read bin failed");
6327             return 0;
6328         }
6329                 
6330         return 1;
6331     }
6332
6333
6334     int CyaSSL_BN_is_bit_set(const CYASSL_BIGNUM* bn, int n)
6335     {
6336         (void)bn;
6337         (void)n;
6338
6339         CYASSL_MSG("CyaSSL_BN_is_bit_set");
6340
6341         return 0;
6342     }
6343
6344
6345     int CyaSSL_BN_hex2bn(CYASSL_BIGNUM** bn, const char* str)
6346     {
6347         byte    decoded[1024];
6348         word32  decSz = sizeof(decoded);
6349
6350         CYASSL_MSG("CyaSSL_BN_hex2bn");
6351
6352         if (str == NULL) {
6353             CYASSL_MSG("Bad function argument");
6354             return 0;
6355         }
6356
6357         if (Base16_Decode((byte*)str, strlen(str), decoded, &decSz) < 0) {
6358             CYASSL_MSG("Bad Base16_Decode error");
6359             return 0;
6360         }
6361
6362         if (bn == NULL)
6363             return decSz;
6364
6365         if (*bn == NULL) {
6366             *bn = CyaSSL_BN_new();
6367             if (*bn == NULL) {
6368                 CYASSL_MSG("BN new failed");
6369                 return 0;
6370             }
6371         }
6372
6373         if (CyaSSL_BN_bin2bn(decoded, decSz, *bn) == NULL) {
6374             CYASSL_MSG("Bad bin2bn error");
6375             return 0;
6376         }
6377
6378         return 1;  /* success */
6379     }
6380
6381
6382     CYASSL_BIGNUM* CyaSSL_BN_dup(const CYASSL_BIGNUM* bn)
6383     {
6384         CYASSL_BIGNUM* ret;
6385
6386         CYASSL_MSG("CyaSSL_BN_dup");
6387
6388         if (bn == NULL || bn->internal == NULL) {
6389             CYASSL_MSG("bn NULL error");
6390             return NULL;
6391         }
6392
6393         ret = CyaSSL_BN_new();
6394         if (ret == NULL) {
6395             CYASSL_MSG("bn new error");
6396             return NULL;
6397         }
6398
6399         if (mp_copy((mp_int*)bn->internal, (mp_int*)ret->internal) != MP_OKAY) {
6400             CYASSL_MSG("mp_copy error");
6401             CyaSSL_BN_free(ret);
6402             return NULL;
6403         }
6404
6405         return ret;
6406     }
6407
6408
6409     CYASSL_BIGNUM* CyaSSL_BN_copy(CYASSL_BIGNUM* r, const CYASSL_BIGNUM* bn)
6410     {
6411         (void)r;
6412         (void)bn;
6413
6414         CYASSL_MSG("CyaSSL_BN_copy");
6415
6416         return NULL;
6417     }
6418
6419
6420     int CyaSSL_BN_set_word(CYASSL_BIGNUM* bn, unsigned long w)
6421     {
6422         (void)bn;
6423         (void)w;
6424
6425         CYASSL_MSG("CyaSSL_BN_set_word");
6426
6427         return -1;
6428     }
6429
6430
6431     int CyaSSL_BN_dec2bn(CYASSL_BIGNUM** bn, const char* str)
6432     {
6433         (void)bn;
6434         (void)str;
6435
6436         CYASSL_MSG("CyaSSL_BN_dec2bn");
6437
6438         return -1;
6439     }
6440
6441
6442     char* CyaSSL_BN_bn2dec(const CYASSL_BIGNUM* bn)
6443     {
6444         (void)bn;
6445
6446         CYASSL_MSG("CyaSSL_BN_bn2dec");
6447
6448         return NULL;
6449     }
6450
6451
6452     static void InitCyaSSL_DH(CYASSL_DH* dh)
6453     {
6454         if (dh) {
6455             dh->p        = NULL;
6456             dh->g        = NULL;
6457             dh->pub_key  = NULL;
6458             dh->priv_key = NULL;
6459             dh->internal = NULL;
6460             dh->inSet    = 0;
6461             dh->exSet    = 0;
6462         }
6463     }
6464
6465
6466     CYASSL_DH* CyaSSL_DH_new(void)
6467     {
6468         CYASSL_DH* external;
6469         DhKey*     key;
6470
6471         CYASSL_MSG("CyaSSL_DH_new");
6472
6473         key = (DhKey*) XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
6474         if (key == NULL) {
6475             CYASSL_MSG("CyaSSL_DH_new malloc DhKey failure");
6476             return NULL;
6477         }
6478
6479         external = (CYASSL_DH*) XMALLOC(sizeof(CYASSL_DH), NULL,
6480                                         DYNAMIC_TYPE_DH);
6481         if (external == NULL) {
6482             CYASSL_MSG("CyaSSL_DH_new malloc CYASSL_DH failure");
6483             XFREE(key, NULL, DYNAMIC_TYPE_DH);
6484             return NULL;
6485         }
6486
6487         InitCyaSSL_DH(external);
6488         InitDhKey(key);
6489         external->internal = key;
6490
6491         return external;
6492     }
6493
6494
6495     void CyaSSL_DH_free(CYASSL_DH* dh)
6496     {
6497         CYASSL_MSG("CyaSSL_DH_free");
6498
6499         if (dh) {
6500             if (dh->internal) {
6501                 FreeDhKey((DhKey*)dh->internal);
6502                 XFREE(dh->internal, NULL, DYNAMIC_TYPE_DH);
6503                 dh->internal = NULL;
6504             }
6505             CyaSSL_BN_free(dh->priv_key);
6506             CyaSSL_BN_free(dh->pub_key);
6507             CyaSSL_BN_free(dh->g);
6508             CyaSSL_BN_free(dh->p);
6509             InitCyaSSL_DH(dh);  /* set back to NULLs for safety */
6510
6511             XFREE(dh, NULL, DYNAMIC_TYPE_DH);
6512         }
6513     }
6514
6515
6516     static int SetDhInternal(CYASSL_DH* dh) 
6517     {
6518         unsigned char p[1024];
6519         unsigned char g[1024];
6520         int           pSz = sizeof(p);
6521         int           gSz = sizeof(g);
6522
6523         CYASSL_ENTER("SetDhInternal");
6524
6525         if (dh == NULL || dh->p == NULL || dh->g == NULL) {
6526             CYASSL_MSG("Bad function arguments");
6527             return -1;
6528         }
6529
6530         if (CyaSSL_BN_bn2bin(dh->p, NULL) > pSz) {
6531             CYASSL_MSG("Bad p internal size");
6532             return -1;
6533         }
6534
6535         if (CyaSSL_BN_bn2bin(dh->g, NULL) > gSz) {
6536             CYASSL_MSG("Bad g internal size");
6537             return -1;
6538         }
6539
6540         pSz = CyaSSL_BN_bn2bin(dh->p, p);
6541         gSz = CyaSSL_BN_bn2bin(dh->g, g);
6542         
6543         if (pSz <= 0 || gSz <= 0) {
6544             CYASSL_MSG("Bad BN2bin set");
6545             return -1;
6546         }
6547
6548         if (DhSetKey((DhKey*)dh->internal, p, pSz, g, gSz) < 0) {
6549             CYASSL_MSG("Bad DH SetKey");
6550             return -1;
6551         }
6552
6553         dh->inSet = 1;
6554
6555         return 0;
6556     }
6557
6558
6559     int CyaSSL_DH_size(CYASSL_DH* dh)
6560     {
6561         CYASSL_MSG("CyaSSL_DH_size");
6562
6563         if (dh == NULL)
6564             return 0;
6565
6566         return CyaSSL_BN_num_bytes(dh->p);
6567     }
6568
6569
6570     /* return 1 on success else 0 */
6571     int CyaSSL_DH_generate_key(CYASSL_DH* dh)
6572     {
6573         unsigned char pub [1024];
6574         unsigned char priv[1024];
6575         word32        pubSz  = sizeof(pub);
6576         word32        privSz = sizeof(priv);
6577         RNG           tmpRNG;
6578         RNG*          rng = &tmpRNG; 
6579         int           ret;
6580
6581         CYASSL_MSG("CyaSSL_DH_generate_key");
6582
6583         if (dh == NULL || dh->p == NULL || dh->g == NULL) {
6584             CYASSL_MSG("Bad function arguments");
6585             return 0; 
6586         }
6587
6588         if (dh->inSet == 0) {
6589             if (SetDhInternal(dh) < 0) {
6590                 CYASSL_MSG("Bad DH set internal");
6591                 return 0; 
6592             }
6593         }
6594
6595         if ( (ret = InitRng(&tmpRNG)) != 0) {
6596             CYASSL_MSG("Bad RNG Init, trying global");
6597             if (initGlobalRNG == 0) {
6598                 CYASSL_MSG("Global RNG no Init");
6599                 return 0; 
6600             }
6601             rng = &globalRNG;
6602         }
6603
6604         if (DhGenerateKeyPair((DhKey*)dh->internal, rng, priv, &privSz,
6605                                 pub, &pubSz) < 0) {
6606             CYASSL_MSG("Bad DhGenerateKeyPair");
6607             return 0; 
6608         }
6609
6610         if (dh->pub_key)
6611             CyaSSL_BN_free(dh->pub_key);
6612         dh->pub_key = CyaSSL_BN_new();
6613         if (dh->pub_key == NULL) {
6614             CYASSL_MSG("Bad DH new pub");
6615             return 0; 
6616         }
6617
6618         if (dh->priv_key)
6619             CyaSSL_BN_free(dh->priv_key);
6620         dh->priv_key = CyaSSL_BN_new();
6621         if (dh->priv_key == NULL) {
6622             CYASSL_MSG("Bad DH new priv");
6623             return 0; 
6624         }
6625
6626         if (CyaSSL_BN_bin2bn(pub, pubSz, dh->pub_key) == NULL) {
6627             CYASSL_MSG("Bad DH bn2bin error pub");
6628             return 0; 
6629         }
6630
6631         if (CyaSSL_BN_bin2bn(priv, privSz, dh->priv_key) == NULL) {
6632             CYASSL_MSG("Bad DH bn2bin error priv");
6633             return 0; 
6634         }
6635
6636         CYASSL_MSG("CyaSSL_generate_key success");
6637         return 1;
6638     }
6639
6640
6641     /* return 1 on success, 0 otherwise */
6642     int CyaSSL_DH_compute_key(unsigned char* key, CYASSL_BIGNUM* otherPub,
6643                               CYASSL_DH* dh)
6644     {
6645         unsigned char pub [1024];
6646         unsigned char priv[1024];
6647         word32        pubSz  = sizeof(pub);
6648         word32        privSz = sizeof(priv);
6649         word32        keySz;
6650
6651         CYASSL_MSG("CyaSSL_DH_compute_key");
6652
6653         if (dh == NULL || dh->priv_key == NULL || otherPub == NULL) {
6654             CYASSL_MSG("Bad function arguments");
6655             return 0; 
6656         }
6657
6658         keySz = (word32)DH_size(dh);
6659         if (keySz == 0) {
6660             CYASSL_MSG("Bad DH_size");
6661             return 0;
6662         }
6663
6664         if (CyaSSL_BN_bn2bin(dh->priv_key, NULL) > (int)privSz) {
6665             CYASSL_MSG("Bad priv internal size");
6666             return 0;
6667         }
6668
6669         if (CyaSSL_BN_bn2bin(otherPub, NULL) > (int)pubSz) {
6670             CYASSL_MSG("Bad otherPub size");
6671             return 0;
6672         }
6673
6674         privSz = CyaSSL_BN_bn2bin(dh->priv_key, priv);
6675         pubSz  = CyaSSL_BN_bn2bin(otherPub, pub);
6676         
6677         if (privSz <= 0 || pubSz <= 0) {
6678             CYASSL_MSG("Bad BN2bin set");
6679             return 0;
6680         }
6681
6682         if (DhAgree((DhKey*)dh->internal, key, &keySz, priv, privSz, pub,
6683                     pubSz) < 0) {
6684             CYASSL_MSG("DhAgree failed");
6685             return 0;
6686         }
6687
6688         CYASSL_MSG("CyaSSL_compute_key success");
6689         return (int)keySz;
6690     }
6691
6692
6693     static void InitCyaSSL_DSA(CYASSL_DSA* dsa)
6694     {
6695         if (dsa) {
6696             dsa->p        = NULL;
6697             dsa->q        = NULL;
6698             dsa->g        = NULL;
6699             dsa->pub_key  = NULL;
6700             dsa->priv_key = NULL;
6701             dsa->internal = NULL;
6702             dsa->inSet    = 0;
6703             dsa->exSet    = 0;
6704         }
6705     }
6706
6707
6708     CYASSL_DSA* CyaSSL_DSA_new(void)
6709     {
6710         CYASSL_DSA* external;
6711         DsaKey*     key;
6712
6713         CYASSL_MSG("CyaSSL_DSA_new");
6714
6715         key = (DsaKey*) XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
6716         if (key == NULL) {
6717             CYASSL_MSG("CyaSSL_DSA_new malloc DsaKey failure");
6718             return NULL;
6719         }
6720
6721         external = (CYASSL_DSA*) XMALLOC(sizeof(CYASSL_DSA), NULL,
6722                                         DYNAMIC_TYPE_DSA);
6723         if (external == NULL) {
6724             CYASSL_MSG("CyaSSL_DSA_new malloc CYASSL_DSA failure");
6725             XFREE(key, NULL, DYNAMIC_TYPE_DSA);
6726             return NULL;
6727         }
6728
6729         InitCyaSSL_DSA(external);
6730         InitDsaKey(key);
6731         external->internal = key;
6732
6733         return external;
6734     }
6735
6736
6737     void CyaSSL_DSA_free(CYASSL_DSA* dsa)
6738     {
6739         CYASSL_MSG("CyaSSL_DSA_free");
6740
6741         if (dsa) {
6742             if (dsa->internal) {
6743                 FreeDsaKey((DsaKey*)dsa->internal);
6744                 XFREE(dsa->internal, NULL, DYNAMIC_TYPE_DSA);
6745                 dsa->internal = NULL;
6746             }
6747             CyaSSL_BN_free(dsa->priv_key);
6748             CyaSSL_BN_free(dsa->pub_key);
6749             CyaSSL_BN_free(dsa->g);
6750             CyaSSL_BN_free(dsa->q);
6751             CyaSSL_BN_free(dsa->p);
6752             InitCyaSSL_DSA(dsa);  /* set back to NULLs for safety */
6753
6754             XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
6755         }
6756     }
6757
6758
6759     int CyaSSL_DSA_generate_key(CYASSL_DSA* dsa)
6760     {
6761         (void)dsa;
6762
6763         CYASSL_MSG("CyaSSL_DSA_generate_key");
6764
6765         return 0;  /* key gen not needed by server */
6766     }
6767
6768
6769     int CyaSSL_DSA_generate_parameters_ex(CYASSL_DSA* dsa, int bits,
6770                    unsigned char* seed, int seedLen, int* counterRet,
6771                    unsigned long* hRet, void* cb)
6772     {
6773         (void)dsa;
6774         (void)bits;
6775         (void)seed;
6776         (void)seedLen;
6777         (void)counterRet;
6778         (void)hRet;
6779         (void)cb;
6780
6781         CYASSL_MSG("CyaSSL_DSA_generate_parameters_ex");
6782
6783         return 0;  /* key gen not needed by server */
6784     }
6785
6786
6787     static void InitCyaSSL_Rsa(CYASSL_RSA* rsa)
6788     {
6789         if (rsa) {
6790             rsa->n        = NULL;
6791             rsa->e        = NULL;
6792             rsa->d        = NULL;
6793             rsa->p        = NULL;
6794             rsa->q        = NULL;
6795                 rsa->dmp1     = NULL;
6796                 rsa->dmq1     = NULL;
6797                 rsa->iqmp     = NULL;
6798             rsa->internal = NULL;
6799             rsa->inSet    = 0;
6800             rsa->exSet    = 0;
6801         }
6802     }
6803
6804
6805     CYASSL_RSA* CyaSSL_RSA_new(void)
6806     {
6807         CYASSL_RSA* external;
6808         RsaKey*     key;
6809
6810         CYASSL_MSG("CyaSSL_RSA_new");
6811
6812         key = (RsaKey*) XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
6813         if (key == NULL) {
6814             CYASSL_MSG("CyaSSL_RSA_new malloc RsaKey failure");
6815             return NULL;
6816         }
6817
6818         external = (CYASSL_RSA*) XMALLOC(sizeof(CYASSL_RSA), NULL,
6819                                          DYNAMIC_TYPE_RSA);
6820         if (external == NULL) {
6821             CYASSL_MSG("CyaSSL_RSA_new malloc CYASSL_RSA failure");
6822             XFREE(key, NULL, DYNAMIC_TYPE_RSA);
6823             return NULL;
6824         }
6825
6826         InitCyaSSL_Rsa(external);
6827         InitRsaKey(key, NULL);
6828         external->internal = key;
6829
6830         return external;
6831     }
6832
6833
6834     void CyaSSL_RSA_free(CYASSL_RSA* rsa)
6835     {
6836         CYASSL_MSG("CyaSSL_RSA_free");
6837
6838         if (rsa) {
6839             if (rsa->internal) {
6840                 FreeRsaKey((RsaKey*)rsa->internal);
6841                 XFREE(rsa->internal, NULL, DYNAMIC_TYPE_RSA);
6842                 rsa->internal = NULL;
6843             }
6844             CyaSSL_BN_free(rsa->iqmp);
6845             CyaSSL_BN_free(rsa->dmq1);
6846             CyaSSL_BN_free(rsa->dmp1);
6847             CyaSSL_BN_free(rsa->q);
6848             CyaSSL_BN_free(rsa->p);
6849             CyaSSL_BN_free(rsa->d);
6850             CyaSSL_BN_free(rsa->e);
6851             CyaSSL_BN_free(rsa->n);
6852             InitCyaSSL_Rsa(rsa);  /* set back to NULLs for safety */
6853
6854             XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
6855         }
6856     }
6857
6858
6859     static int SetIndividualExternal(CYASSL_BIGNUM** bn, mp_int* mpi)
6860     {
6861         CYASSL_MSG("Entering SetIndividualExternal");
6862
6863         if (mpi == NULL) {
6864             CYASSL_MSG("mpi NULL error");
6865             return -1;
6866         }
6867
6868         if (*bn == NULL) {
6869             *bn = CyaSSL_BN_new();
6870             if (*bn == NULL) {
6871                 CYASSL_MSG("SetIndividualExternal alloc failed");
6872                 return -1;
6873             }
6874         }
6875
6876         if (mp_copy(mpi, (mp_int*)((*bn)->internal)) != MP_OKAY) {
6877             CYASSL_MSG("mp_copy error");
6878             return -1;
6879         }
6880
6881         return 0;
6882     }
6883
6884
6885     static int SetDsaExternal(CYASSL_DSA* dsa)
6886     {
6887         DsaKey* key;
6888         CYASSL_MSG("Entering SetDsaExternal");
6889
6890         if (dsa == NULL || dsa->internal == NULL) {
6891             CYASSL_MSG("dsa key NULL error");
6892             return -1;
6893         }
6894
6895         key = (DsaKey*)dsa->internal;
6896
6897         if (SetIndividualExternal(&dsa->p, &key->p) < 0) {
6898             CYASSL_MSG("dsa p key error");
6899             return -1;
6900         }
6901
6902         if (SetIndividualExternal(&dsa->q, &key->q) < 0) {
6903             CYASSL_MSG("dsa q key error");
6904             return -1;
6905         }
6906
6907         if (SetIndividualExternal(&dsa->g, &key->g) < 0) {
6908             CYASSL_MSG("dsa g key error");
6909             return -1;
6910         }
6911
6912         if (SetIndividualExternal(&dsa->pub_key, &key->y) < 0) {
6913             CYASSL_MSG("dsa y key error");
6914             return -1;
6915         }
6916
6917         if (SetIndividualExternal(&dsa->priv_key, &key->x) < 0) {
6918             CYASSL_MSG("dsa x key error");
6919             return -1;
6920         }
6921
6922         dsa->exSet = 1;
6923
6924         return 0;
6925     }
6926
6927
6928     static int SetRsaExternal(CYASSL_RSA* rsa)
6929     {
6930         RsaKey* key;
6931         CYASSL_MSG("Entering SetRsaExternal");
6932
6933         if (rsa == NULL || rsa->internal == NULL) {
6934             CYASSL_MSG("rsa key NULL error");
6935             return -1;
6936         }
6937
6938         key = (RsaKey*)rsa->internal;
6939
6940         if (SetIndividualExternal(&rsa->n, &key->n) < 0) {
6941             CYASSL_MSG("rsa n key error");
6942             return -1;
6943         }
6944
6945         if (SetIndividualExternal(&rsa->e, &key->e) < 0) {
6946             CYASSL_MSG("rsa e key error");
6947             return -1;
6948         }
6949
6950         if (SetIndividualExternal(&rsa->d, &key->d) < 0) {
6951             CYASSL_MSG("rsa d key error");
6952             return -1;
6953         }
6954
6955         if (SetIndividualExternal(&rsa->p, &key->p) < 0) {
6956             CYASSL_MSG("rsa p key error");
6957             return -1;
6958         }
6959
6960         if (SetIndividualExternal(&rsa->q, &key->q) < 0) {
6961             CYASSL_MSG("rsa q key error");
6962             return -1;
6963         }
6964
6965         if (SetIndividualExternal(&rsa->dmp1, &key->dP) < 0) {
6966             CYASSL_MSG("rsa dP key error");
6967             return -1;
6968         }
6969
6970         if (SetIndividualExternal(&rsa->dmq1, &key->dQ) < 0) {
6971             CYASSL_MSG("rsa dQ key error");
6972             return -1;
6973         }
6974
6975         if (SetIndividualExternal(&rsa->iqmp, &key->u) < 0) {
6976             CYASSL_MSG("rsa u key error");
6977             return -1;
6978         }
6979
6980         rsa->exSet = 1;
6981
6982         return 0;
6983     }
6984
6985
6986     int CyaSSL_RSA_generate_key_ex(CYASSL_RSA* rsa, int bits, CYASSL_BIGNUM* bn,
6987                                    void* cb)
6988     {
6989         RNG rng;
6990
6991         CYASSL_MSG("CyaSSL_RSA_generate_key_ex");
6992
6993         (void)rsa;
6994         (void)bits;
6995         (void)cb;
6996         (void)bn;
6997     
6998         if (InitRng(&rng) < 0) {
6999             CYASSL_MSG("RNG init failed");
7000             return -1;
7001         }
7002
7003 #ifdef CYASSL_KEY_GEN
7004         if (MakeRsaKey((RsaKey*)rsa->internal, bits, 65537, &rng) < 0) {
7005             CYASSL_MSG("MakeRsaKey failed");
7006             return -1;
7007         }
7008
7009         if (SetRsaExternal(rsa) < 0) {
7010             CYASSL_MSG("SetRsaExternal failed");
7011             return -1;
7012         }
7013
7014         rsa->inSet = 1;
7015
7016         return 1;  /* success */
7017 #else
7018         CYASSL_MSG("No Key Gen built in");
7019         return -1;
7020 #endif
7021
7022     }
7023
7024
7025     int CyaSSL_RSA_blinding_on(CYASSL_RSA* rsa, CYASSL_BN_CTX* bn)
7026     {
7027         (void)rsa;
7028         (void)bn;
7029
7030         CYASSL_MSG("CyaSSL_RSA_blinding_on");
7031
7032         return 1;  /* on by default */
7033     }
7034
7035
7036     int CyaSSL_RSA_public_encrypt(int len, unsigned char* fr,
7037                                     unsigned char* to, CYASSL_RSA* rsa, int padding)
7038     {
7039         (void)len;
7040         (void)fr;
7041         (void)to;
7042         (void)rsa;
7043         (void)padding;
7044
7045         CYASSL_MSG("CyaSSL_RSA_public_encrypt");
7046
7047         return -1;
7048     }
7049
7050
7051     int CyaSSL_RSA_private_decrypt(int len, unsigned char* fr,
7052                                     unsigned char* to, CYASSL_RSA* rsa, int padding)
7053     {
7054         (void)len;
7055         (void)fr;
7056         (void)to;
7057         (void)rsa;
7058         (void)padding;
7059
7060         CYASSL_MSG("CyaSSL_RSA_private_decrypt");
7061
7062         return -1;
7063     }
7064
7065
7066     int CyaSSL_RSA_size(const CYASSL_RSA* rsa)
7067     {
7068         CYASSL_MSG("CyaSSL_RSA_size");
7069
7070         if (rsa == NULL)
7071             return 0;
7072
7073         return CyaSSL_BN_num_bytes(rsa->n);
7074     }
7075
7076
7077     /* return 0 on success, < 0 otherwise */
7078     int CyaSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
7079                            CYASSL_DSA* dsa)
7080     {
7081         RNG    tmpRNG;
7082         RNG*   rng = &tmpRNG; 
7083
7084         CYASSL_MSG("CyaSSL_DSA_do_sign");
7085
7086         if (d == NULL || sigRet == NULL || dsa == NULL) {
7087             CYASSL_MSG("Bad function arguments");
7088             return -1;
7089         }
7090
7091         if (dsa->inSet == 0) {
7092             CYASSL_MSG("No DSA internal set");
7093             return -1;
7094         }
7095
7096         if (InitRng(&tmpRNG) != 0) {
7097             CYASSL_MSG("Bad RNG Init, trying global");
7098             if (initGlobalRNG == 0) {
7099                 CYASSL_MSG("Global RNG no Init");
7100                 return -1; 
7101             }
7102             rng = &globalRNG;
7103         }
7104
7105         if (DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0) {
7106             CYASSL_MSG("DsaSign failed");
7107             return -1;
7108         }
7109
7110         return 0;
7111     }
7112
7113
7114     /* return 1 on success, 0 otherwise */
7115     int CyaSSL_RSA_sign(int type, const unsigned char* m,
7116                                unsigned int mLen, unsigned char* sigRet,
7117                                unsigned int* sigLen, CYASSL_RSA* rsa)
7118     {
7119         byte   encodedSig[MAX_ENCODED_SIG_SZ];
7120         word32 outLen;
7121         word32 signSz;
7122         RNG    tmpRNG;
7123         RNG*   rng = &tmpRNG; 
7124
7125         CYASSL_MSG("CyaSSL_RSA_sign");
7126
7127         if (m == NULL || sigRet == NULL || sigLen == NULL || rsa == NULL) {
7128             CYASSL_MSG("Bad function arguments");
7129             return 0;
7130         }
7131
7132         if (rsa->inSet == 0) {
7133             CYASSL_MSG("No RSA internal set");
7134             return 0;
7135         }
7136
7137         outLen = (word32)CyaSSL_BN_num_bytes(rsa->n);
7138         if (outLen == 0) {
7139             CYASSL_MSG("Bad RSA size");
7140             return 0;
7141         }
7142        
7143         if (InitRng(&tmpRNG) != 0) {
7144             CYASSL_MSG("Bad RNG Init, trying global");
7145             if (initGlobalRNG == 0) {
7146                 CYASSL_MSG("Global RNG no Init");
7147                 return 0; 
7148             }
7149             rng = &globalRNG;
7150         }
7151
7152         switch (type) {
7153             case NID_md5:
7154                 type = MD5h;
7155                 break;
7156
7157             case NID_sha1:
7158                 type = SHAh;
7159                 break;
7160
7161             default:
7162                 CYASSL_MSG("Bad md type");
7163                 return 0;
7164         }
7165
7166         signSz = EncodeSignature(encodedSig, m, mLen, type);
7167         if (signSz == 0) {
7168             CYASSL_MSG("Bad Encode Signature");
7169             return 0;
7170         }
7171
7172         *sigLen = RsaSSL_Sign(encodedSig, signSz, sigRet, outLen,
7173                               (RsaKey*)rsa->internal, rng);
7174         if (*sigLen <= 0) {
7175             CYASSL_MSG("Bad Rsa Sign");
7176             return 0;
7177         }
7178
7179         CYASSL_MSG("CyaSSL_RSA_sign success");
7180         return 1;  /* success */
7181     }
7182
7183
7184     int CyaSSL_RSA_public_decrypt(int flen, unsigned char* from,
7185                               unsigned char* to, CYASSL_RSA* rsa, int padding)
7186     {
7187         (void)flen;
7188         (void)from;
7189         (void)to;
7190         (void)rsa;
7191         (void)padding;
7192
7193         CYASSL_MSG("CyaSSL_RSA_public_decrypt");
7194
7195         return -1;
7196     }
7197
7198
7199     /* generate p-1 and q-1 */
7200     int CyaSSL_RSA_GenAdd(CYASSL_RSA* rsa)
7201     {
7202         int    err;
7203         mp_int tmp;
7204
7205         CYASSL_MSG("CyaSSL_RsaGenAdd");
7206
7207         if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->d == NULL ||
7208                            rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
7209             CYASSL_MSG("rsa no init error");
7210             return -1;
7211         }
7212
7213         if (mp_init(&tmp) != MP_OKAY) {
7214             CYASSL_MSG("mp_init error");
7215             return -1;
7216         }
7217
7218         err = mp_sub_d((mp_int*)rsa->p->internal, 1, &tmp);
7219         if (err != MP_OKAY)
7220             CYASSL_MSG("mp_sub_d error");
7221         else
7222             err = mp_mod((mp_int*)rsa->d->internal, &tmp,
7223                          (mp_int*)rsa->dmp1->internal);
7224
7225         if (err != MP_OKAY)
7226             CYASSL_MSG("mp_mod error");
7227         else
7228             err = mp_sub_d((mp_int*)rsa->q->internal, 1, &tmp);
7229         if (err != MP_OKAY)
7230             CYASSL_MSG("mp_sub_d error");
7231         else
7232             err = mp_mod((mp_int*)rsa->d->internal, &tmp,
7233                          (mp_int*)rsa->dmq1->internal);
7234
7235         mp_clear(&tmp);
7236
7237         if (err == MP_OKAY)
7238             return 0;
7239         else
7240             return -1;
7241     }
7242
7243
7244     void CyaSSL_HMAC_Init(CYASSL_HMAC_CTX* ctx, const void* key, int keylen,
7245                       const EVP_MD* type)
7246     {
7247         CYASSL_MSG("CyaSSL_HMAC_Init");
7248
7249         if (ctx == NULL) {
7250             CYASSL_MSG("no ctx on init");
7251             return;
7252         }
7253
7254         if (type) {
7255             CYASSL_MSG("init has type");
7256
7257             if (XSTRNCMP(type, "MD5", 3) == 0) {
7258                 CYASSL_MSG("md5 hmac");
7259                 ctx->type = MD5;
7260             }
7261             else if (XSTRNCMP(type, "SHA256", 6) == 0) {
7262                 CYASSL_MSG("sha256 hmac");
7263                 ctx->type = SHA256;
7264             }
7265             
7266             /* has to be last since would pick or 256, 384, or 512 too */
7267             else if (XSTRNCMP(type, "SHA", 3) == 0) {
7268                 CYASSL_MSG("sha hmac");
7269                 ctx->type = SHA;
7270             }
7271             else {
7272                 CYASSL_MSG("bad init type");
7273             }
7274         }
7275
7276         if (key && keylen) {
7277             CYASSL_MSG("keying hmac");
7278             HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key, (word32)keylen);
7279         }
7280     }
7281
7282
7283     void CyaSSL_HMAC_Update(CYASSL_HMAC_CTX* ctx, const unsigned char* data,
7284                         int len)
7285     {
7286         CYASSL_MSG("CyaSSL_HMAC_Update");
7287
7288         if (ctx && data) {
7289             CYASSL_MSG("updating hmac");
7290             HmacUpdate(&ctx->hmac, data, (word32)len);
7291         }
7292     }
7293
7294
7295     void CyaSSL_HMAC_Final(CYASSL_HMAC_CTX* ctx, unsigned char* hash,
7296                        unsigned int* len)
7297     {
7298         CYASSL_MSG("CyaSSL_HMAC_Final");
7299
7300         if (ctx && hash) {
7301             CYASSL_MSG("final hmac");
7302             HmacFinal(&ctx->hmac, hash);
7303
7304             if (len) {
7305                 CYASSL_MSG("setting output len");
7306                 switch (ctx->type) {
7307                     case MD5:
7308                         *len = MD5_DIGEST_SIZE;
7309                         break;
7310
7311                     case SHA:
7312                         *len = SHA_DIGEST_SIZE;
7313                         break;
7314
7315                     case SHA256:
7316                         *len = SHA256_DIGEST_SIZE;
7317                         break;
7318
7319                     default:
7320                         CYASSL_MSG("bad hmac type");
7321                 }
7322             }
7323         }
7324     }
7325
7326
7327     void CyaSSL_HMAC_cleanup(CYASSL_HMAC_CTX* ctx)
7328     {
7329         (void)ctx;
7330
7331         CYASSL_MSG("CyaSSL_HMAC_cleanup");
7332     }
7333
7334
7335     const CYASSL_EVP_MD* CyaSSL_EVP_get_digestbynid(int id)
7336     {
7337         CYASSL_MSG("CyaSSL_get_digestbynid");
7338
7339         switch(id) {
7340             case NID_md5:
7341                 return CyaSSL_EVP_md5();
7342                 break;
7343
7344             case NID_sha1:
7345                 return CyaSSL_EVP_sha1();
7346                 break;
7347
7348             default:
7349                 CYASSL_MSG("Bad digest id value");
7350         }
7351
7352         return NULL;
7353     }
7354
7355
7356     CYASSL_RSA* CyaSSL_EVP_PKEY_get1_RSA(CYASSL_EVP_PKEY* key)
7357     {
7358         (void)key;
7359         CYASSL_MSG("CyaSSL_EVP_PKEY_get1_RSA");
7360
7361         return NULL;
7362     }
7363
7364
7365     CYASSL_DSA* CyaSSL_EVP_PKEY_get1_DSA(CYASSL_EVP_PKEY* key)
7366     {
7367         (void)key;
7368         CYASSL_MSG("CyaSSL_EVP_PKEY_get1_DSA");
7369
7370         return NULL;
7371     }
7372
7373
7374     void* CyaSSL_EVP_X_STATE(const CYASSL_EVP_CIPHER_CTX* ctx)
7375     {
7376         CYASSL_MSG("CyaSSL_EVP_X_STATE");
7377
7378         if (ctx) {
7379             switch (ctx->cipherType) {
7380                 case ARC4_TYPE:
7381                     CYASSL_MSG("returning arc4 state");
7382                     return (void*)&ctx->cipher.arc4.x;
7383                     break;
7384
7385                 default:
7386                     CYASSL_MSG("bad x state type");
7387                     return 0;
7388             }
7389         }
7390
7391         return NULL;
7392     }
7393
7394
7395     int CyaSSL_EVP_X_STATE_LEN(const CYASSL_EVP_CIPHER_CTX* ctx)
7396     {
7397         CYASSL_MSG("CyaSSL_EVP_X_STATE_LEN");
7398
7399         if (ctx) {
7400             switch (ctx->cipherType) {
7401                 case ARC4_TYPE:
7402                     CYASSL_MSG("returning arc4 state size");
7403                     return sizeof(Arc4);
7404                     break;
7405
7406                 default:
7407                     CYASSL_MSG("bad x state type");
7408                     return 0;
7409             }
7410         }
7411
7412         return 0;
7413     }
7414
7415
7416     void CyaSSL_3des_iv(CYASSL_EVP_CIPHER_CTX* ctx, int doset,
7417                                 unsigned char* iv, int len)
7418     {
7419         (void)len;
7420
7421         CYASSL_MSG("CyaSSL_3des_iv");
7422
7423         if (ctx == NULL || iv == NULL) {
7424             CYASSL_MSG("Bad function argument");
7425             return;
7426         }
7427
7428         if (doset)
7429             Des3_SetIV(&ctx->cipher.des3, iv);
7430         else
7431             memcpy(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
7432     }
7433
7434
7435     void CyaSSL_aes_ctr_iv(CYASSL_EVP_CIPHER_CTX* ctx, int doset,
7436                           unsigned char* iv, int len)
7437     {
7438         (void)len;
7439
7440         CYASSL_MSG("CyaSSL_aes_ctr_iv");
7441
7442         if (ctx == NULL || iv == NULL) {
7443             CYASSL_MSG("Bad function argument");
7444             return;
7445         }
7446
7447         if (doset)
7448             AesSetIV(&ctx->cipher.aes, iv);
7449         else
7450             memcpy(iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
7451     }
7452
7453
7454     const CYASSL_EVP_MD* CyaSSL_EVP_ripemd160(void)
7455     {
7456         CYASSL_MSG("CyaSSL_ripemd160");
7457
7458         return NULL;
7459     }
7460
7461
7462     int CyaSSL_EVP_MD_size(const CYASSL_EVP_MD* type)
7463     {
7464         CYASSL_MSG("CyaSSL_EVP_MD_size");
7465
7466         if (type == NULL) {
7467             CYASSL_MSG("No md type arg");
7468             return BAD_FUNC_ARG;
7469         }
7470
7471         if (XSTRNCMP(type, "MD5", 3) == 0) {
7472             return MD5_DIGEST_SIZE;
7473         }
7474         else if (XSTRNCMP(type, "SHA256", 6) == 0) {
7475             return SHA256_DIGEST_SIZE;
7476         }
7477     #ifdef CYASSL_SHA384
7478         else if (XSTRNCMP(type, "SHA384", 6) == 0) {
7479             return SHA384_DIGEST_SIZE;
7480         }
7481     #endif
7482     #ifdef CYASSL_SHA512
7483         else if (XSTRNCMP(type, "SHA512", 6) == 0) {
7484             return SHA512_DIGEST_SIZE;
7485         }
7486     #endif
7487         /* has to be last since would pick or 256, 384, or 512 too */
7488         else if (XSTRNCMP(type, "SHA", 3) == 0) {
7489             return SHA_DIGEST_SIZE;
7490         }   
7491
7492         return BAD_FUNC_ARG;
7493     }
7494
7495
7496     int CyaSSL_EVP_CIPHER_CTX_iv_length(const CYASSL_EVP_CIPHER_CTX* ctx)
7497     {
7498         CYASSL_MSG("CyaSSL_EVP_CIPHER_CTX_iv_length");
7499
7500         switch (ctx->cipherType) {
7501
7502             case AES_128_CBC_TYPE :
7503             case AES_192_CBC_TYPE :
7504             case AES_256_CBC_TYPE :
7505                 CYASSL_MSG("AES CBC");
7506                 return AES_BLOCK_SIZE;
7507                 break;
7508
7509 #ifdef CYASSL_AES_COUNTER
7510             case AES_128_CTR_TYPE :
7511             case AES_192_CTR_TYPE :
7512             case AES_256_CTR_TYPE :
7513                 CYASSL_MSG("AES CTR");
7514                 return AES_BLOCK_SIZE;
7515                 break;
7516 #endif
7517
7518             case DES_CBC_TYPE :
7519                 CYASSL_MSG("DES CBC");
7520                 return DES_BLOCK_SIZE;
7521                 break;
7522                 
7523             case DES_EDE3_CBC_TYPE :
7524                 CYASSL_MSG("DES EDE3 CBC");
7525                 return DES_BLOCK_SIZE;
7526                 break;
7527
7528             case ARC4_TYPE :
7529                 CYASSL_MSG("ARC4");
7530                 return 0;
7531                 break;
7532
7533             case NULL_CIPHER_TYPE :
7534                 CYASSL_MSG("NULL");
7535                 return 0;
7536                 break;
7537
7538             default: {
7539                 CYASSL_MSG("bad type");
7540             }
7541         }    
7542         return 0;
7543     }
7544
7545
7546     void CyaSSL_OPENSSL_free(void* p)
7547     {
7548         CYASSL_MSG("CyaSSL_OPENSSL_free");
7549
7550         XFREE(p, NULL, 0);
7551     }
7552
7553
7554     int CyaSSL_PEM_write_bio_RSAPrivateKey(CYASSL_BIO* bio, RSA* rsa,
7555                                           const EVP_CIPHER* cipher,
7556                                           unsigned char* passwd, int len,
7557                                           pem_password_cb cb, void* arg)
7558     {
7559         (void)bio;
7560         (void)rsa;
7561         (void)cipher;
7562         (void)passwd;
7563         (void)len;
7564         (void)cb;
7565         (void)arg;
7566
7567         CYASSL_MSG("CyaSSL_PEM_write_bio_RSAPrivateKey");
7568
7569         return -1;
7570     }
7571
7572
7573
7574     int CyaSSL_PEM_write_bio_DSAPrivateKey(CYASSL_BIO* bio, DSA* rsa,
7575                                           const EVP_CIPHER* cipher,
7576                                           unsigned char* passwd, int len,
7577                                           pem_password_cb cb, void* arg)
7578     {
7579         (void)bio;
7580         (void)rsa;
7581         (void)cipher;
7582         (void)passwd;
7583         (void)len;
7584         (void)cb;
7585         (void)arg;
7586
7587         CYASSL_MSG("CyaSSL_PEM_write_bio_DSAPrivateKey");
7588
7589         return -1;
7590     }
7591
7592
7593
7594     CYASSL_EVP_PKEY* CyaSSL_PEM_read_bio_PrivateKey(CYASSL_BIO* bio,
7595                         CYASSL_EVP_PKEY** key, pem_password_cb cb, void* arg)
7596     {
7597         (void)bio;
7598         (void)key;
7599         (void)cb;
7600         (void)arg;
7601
7602         CYASSL_MSG("CyaSSL_PEM_read_bio_PrivateKey");
7603
7604         return NULL;
7605     }
7606
7607
7608
7609 /* Return bytes written to buff or < 0 for error */
7610 int CyaSSL_KeyPemToDer(const unsigned char* pem, int pemSz, unsigned char* buff,
7611                        int buffSz, const char* pass)
7612 {
7613     EncryptedInfo info;
7614     int           eccKey = 0;
7615     int           ret;
7616     buffer        der;
7617
7618     (void)pass;
7619
7620     CYASSL_ENTER("CyaSSL_KeyPemToDer");
7621
7622     if (pem == NULL || buff == NULL || buffSz <= 0) {
7623         CYASSL_MSG("Bad pem der args"); 
7624         return BAD_FUNC_ARG;
7625     }
7626
7627     info.set       = 0;
7628     info.ctx      = NULL;
7629     info.consumed = 0;
7630     der.buffer    = NULL;
7631
7632     ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, &info, &eccKey);
7633     if (ret < 0) {
7634         CYASSL_MSG("Bad Pem To Der"); 
7635     }
7636     else {
7637         if (der.length <= (word32)buffSz) {
7638             XMEMCPY(buff, der.buffer, der.length);
7639             ret = der.length;
7640         }
7641         else {
7642             CYASSL_MSG("Bad der length");
7643             ret = BAD_FUNC_ARG;
7644         }
7645     }
7646
7647     XFREE(der.buffer, NULL, DYANMIC_KEY_TYPE);
7648
7649     return ret;
7650 }
7651
7652
7653 /* Load RSA from Der, 0 on success < 0 on error */
7654 int CyaSSL_RSA_LoadDer(CYASSL_RSA* rsa, const unsigned char* der,  int derSz)
7655 {
7656     word32 idx = 0;
7657     int    ret;
7658
7659     CYASSL_ENTER("CyaSSL_RSA_LoadDer");
7660
7661     if (rsa == NULL || rsa->internal == NULL || der == NULL || derSz <= 0) {
7662         CYASSL_MSG("Bad function arguments");
7663         return BAD_FUNC_ARG;
7664     }
7665
7666     ret = RsaPrivateKeyDecode(der, &idx, (RsaKey*)rsa->internal, derSz);
7667     if (ret < 0) {
7668         CYASSL_MSG("RsaPrivateKeyDecode failed");
7669         return ret;
7670     }
7671
7672     if (SetRsaExternal(rsa) < 0) {
7673         CYASSL_MSG("SetRsaExternal failed");
7674         return -1;
7675     }
7676
7677     rsa->inSet = 1;
7678
7679     return 0;
7680 }
7681
7682
7683 /* Load DSA from Der, 0 on success < 0 on error */
7684 int CyaSSL_DSA_LoadDer(CYASSL_DSA* dsa, const unsigned char* der,  int derSz)
7685 {
7686     word32 idx = 0;
7687     int    ret;
7688
7689     CYASSL_ENTER("CyaSSL_DSA_LoadDer");
7690
7691     if (dsa == NULL || dsa->internal == NULL || der == NULL || derSz <= 0) {
7692         CYASSL_MSG("Bad function arguments");
7693         return BAD_FUNC_ARG;
7694     }
7695
7696     ret = DsaPrivateKeyDecode(der, &idx, (DsaKey*)dsa->internal, derSz);
7697     if (ret < 0) {
7698         CYASSL_MSG("DsaPrivateKeyDecode failed");
7699         return ret;
7700     }
7701
7702     if (SetDsaExternal(dsa) < 0) {
7703         CYASSL_MSG("SetDsaExternal failed");
7704         return -1;
7705     }
7706
7707     dsa->inSet = 1;
7708
7709     return 0;
7710 }
7711
7712
7713
7714
7715
7716 #endif /* OPENSSL_EXTRA */
7717
7718
7719 #ifdef SESSION_CERTS
7720
7721
7722 /* Get peer's certificate chain */
7723 CYASSL_X509_CHAIN* CyaSSL_get_peer_chain(CYASSL* ssl)
7724 {
7725     CYASSL_ENTER("CyaSSL_get_peer_chain");
7726     if (ssl)
7727         return &ssl->session.chain;
7728
7729     return 0;
7730 }
7731
7732
7733 /* Get peer's certificate chain total count */
7734 int CyaSSL_get_chain_count(CYASSL_X509_CHAIN* chain)
7735 {
7736     CYASSL_ENTER("CyaSSL_get_chain_count");
7737     if (chain)
7738         return chain->count;
7739
7740     return 0;
7741 }
7742
7743
7744 /* Get peer's ASN.1 DER ceritifcate at index (idx) length in bytes */
7745 int CyaSSL_get_chain_length(CYASSL_X509_CHAIN* chain, int idx)
7746 {
7747     CYASSL_ENTER("CyaSSL_get_chain_length");
7748     if (chain)
7749         return chain->certs[idx].length;
7750
7751     return 0;
7752 }
7753
7754
7755 /* Get peer's ASN.1 DER ceritifcate at index (idx) */
7756 byte* CyaSSL_get_chain_cert(CYASSL_X509_CHAIN* chain, int idx)
7757 {
7758     CYASSL_ENTER("CyaSSL_get_chain_cert");
7759     if (chain)
7760         return chain->certs[idx].buffer;
7761
7762     return 0;
7763 }
7764
7765
7766 /* Get peer's PEM ceritifcate at index (idx), output to buffer if inLen big
7767    enough else return error (-1), output length is in *outLen */
7768 int  CyaSSL_get_chain_cert_pem(CYASSL_X509_CHAIN* chain, int idx,
7769                                unsigned char* buf, int inLen, int* outLen)
7770 {
7771     const char header[] = "-----BEGIN CERTIFICATE-----\n";
7772     const char footer[] = "-----END CERTIFICATE-----\n";
7773
7774     int headerLen = sizeof(header) - 1;
7775     int footerLen = sizeof(footer) - 1;
7776     int i;
7777     int err;
7778
7779     CYASSL_ENTER("CyaSSL_get_chain_cert_pem");
7780     if (!chain || !outLen || !buf)
7781         return BAD_FUNC_ARG;
7782
7783     /* don't even try if inLen too short */
7784     if (inLen < headerLen + footerLen + chain->certs[idx].length)
7785         return BAD_FUNC_ARG;
7786
7787     /* header */
7788     XMEMCPY(buf, header, headerLen);
7789     i = headerLen;
7790
7791     /* body */
7792     *outLen = inLen;  /* input to Base64_Encode */
7793     if ( (err = Base64_Encode(chain->certs[idx].buffer,
7794                        chain->certs[idx].length, buf + i, (word32*)outLen)) < 0)
7795         return err;
7796     i += *outLen;
7797
7798     /* footer */
7799     if ( (i + footerLen) > inLen)
7800         return BAD_FUNC_ARG;
7801     XMEMCPY(buf + i, footer, footerLen);
7802     *outLen += headerLen + footerLen; 
7803
7804     return 0;
7805 }
7806
7807
7808 /* get session ID */
7809 const byte* CyaSSL_get_sessionID(const CYASSL_SESSION* session)
7810 {
7811     CYASSL_ENTER("CyaSSL_get_sessionID");
7812     if (session)
7813         return session->sessionID;
7814
7815     return NULL;
7816 }
7817
7818
7819 #endif /* SESSION_CERTS */
7820
7821
7822 long CyaSSL_CTX_OCSP_set_options(CYASSL_CTX* ctx, long options)
7823 {
7824     CYASSL_ENTER("CyaSSL_CTX_OCSP_set_options");
7825 #ifdef HAVE_OCSP
7826     if (ctx != NULL) {
7827         ctx->ocsp.enabled = (options & CYASSL_OCSP_ENABLE) != 0;
7828         ctx->ocsp.useOverrideUrl = (options & CYASSL_OCSP_URL_OVERRIDE) != 0;
7829         return 1;
7830     }
7831     return 0;
7832 #else
7833     (void)ctx;
7834     (void)options;
7835     return NOT_COMPILED_IN;
7836 #endif
7837 }
7838
7839
7840 int CyaSSL_CTX_OCSP_set_override_url(CYASSL_CTX* ctx, const char* url)
7841 {
7842     CYASSL_ENTER("CyaSSL_CTX_OCSP_set_override_url");
7843 #ifdef HAVE_OCSP
7844     return CyaSSL_OCSP_set_override_url(&ctx->ocsp, url);
7845 #else
7846     (void)ctx;
7847     (void)url;
7848     return NOT_COMPILED_IN;
7849 #endif
7850 }
7851
7852