3 * Copyright (C) 2006-2015 wolfSSL Inc.
5 * This file is part of wolfSSL. (formerly known as CyaSSL)
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26 #include <wolfssl/wolfcrypt/settings.h>
32 #include <wolfssl/internal.h>
33 #include <wolfssl/error-ssl.h>
34 #include <wolfssl/wolfcrypt/coding.h>
36 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
37 #include <wolfssl/openssl/evp.h>
41 /* openssl headers begin */
42 #include <wolfssl/openssl/hmac.h>
43 #include <wolfssl/openssl/crypto.h>
44 #include <wolfssl/openssl/des.h>
45 #include <wolfssl/openssl/bn.h>
46 #include <wolfssl/openssl/dh.h>
47 #include <wolfssl/openssl/rsa.h>
48 #include <wolfssl/openssl/pem.h>
49 /* openssl headers end, wolfssl internal headers next */
50 #include <wolfssl/wolfcrypt/hmac.h>
51 #include <wolfssl/wolfcrypt/random.h>
52 #include <wolfssl/wolfcrypt/des3.h>
53 #include <wolfssl/wolfcrypt/md4.h>
54 #include <wolfssl/wolfcrypt/md5.h>
55 #include <wolfssl/wolfcrypt/arc4.h>
57 #include <wolfssl/wolfcrypt/sha512.h>
62 #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR) \
71 #endif /* NO_FILESYSTEM */
80 #ifndef WOLFSSL_HAVE_MIN
81 #define WOLFSSL_HAVE_MIN
83 static INLINE word32 min(word32 a, word32 b)
88 #endif /* WOLFSSSL_HAVE_MIN */
90 #ifndef WOLFSSL_HAVE_MAX
91 #define WOLFSSL_HAVE_MAX
94 static INLINE word32 max(word32 a, word32 b)
98 #endif /* WOLFSSL_DTLS */
100 #endif /* WOLFSSL_HAVE_MAX */
103 #ifndef WOLFSSL_LEANPSK
104 char* mystrnstr(const char* s1, const char* s2, unsigned int n)
106 unsigned int s2_len = (unsigned int)XSTRLEN(s2);
111 while (n >= s2_len && s1[0]) {
113 if (XMEMCMP(s1, s2, s2_len) == 0)
124 /* prevent multiple mutex initializations */
125 static volatile int initRefCount = 0;
126 static wolfSSL_Mutex count_mutex; /* init ref count mutex */
129 WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method)
131 WOLFSSL_CTX* ctx = NULL;
133 WOLFSSL_ENTER("WOLFSSL_CTX_new");
135 if (initRefCount == 0)
136 wolfSSL_Init(); /* user no longer forced to call Init themselves */
141 ctx = (WOLFSSL_CTX*) XMALLOC(sizeof(WOLFSSL_CTX), 0, DYNAMIC_TYPE_CTX);
143 if (InitSSL_Ctx(ctx, method) < 0) {
144 WOLFSSL_MSG("Init CTX failed");
145 wolfSSL_CTX_free(ctx);
150 WOLFSSL_MSG("Alloc CTX failed, method freed");
151 XFREE(method, NULL, DYNAMIC_TYPE_METHOD);
154 WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
159 void wolfSSL_CTX_free(WOLFSSL_CTX* ctx)
161 WOLFSSL_ENTER("SSL_CTX_free");
164 WOLFSSL_LEAVE("SSL_CTX_free", 0);
168 WOLFSSL* wolfSSL_new(WOLFSSL_CTX* ctx)
174 WOLFSSL_ENTER("SSL_new");
179 ssl = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ctx->heap,DYNAMIC_TYPE_SSL);
181 if ( (ret = InitSSL(ssl, ctx)) < 0) {
186 WOLFSSL_LEAVE("SSL_new", ret);
191 void wolfSSL_free(WOLFSSL* ssl)
193 WOLFSSL_ENTER("SSL_free");
196 WOLFSSL_LEAVE("SSL_free", 0);
200 /* set if to use old poly 1 for yes 0 to use new poly */
201 int wolfSSL_use_old_poly(WOLFSSL* ssl, int value)
203 WOLFSSL_ENTER("SSL_use_old_poly");
204 ssl->options.oldPoly = value;
205 WOLFSSL_LEAVE("SSL_use_old_poly", 0);
210 int wolfSSL_set_fd(WOLFSSL* ssl, int fd)
212 WOLFSSL_ENTER("SSL_set_fd");
213 ssl->rfd = fd; /* not used directly to allow IO callbacks */
216 ssl->IOCB_ReadCtx = &ssl->rfd;
217 ssl->IOCB_WriteCtx = &ssl->wfd;
220 if (ssl->options.dtls) {
221 ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
222 ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
223 ssl->buffers.dtlsCtx.fd = fd;
227 WOLFSSL_LEAVE("SSL_set_fd", SSL_SUCCESS);
233 * Get the name of cipher at priotity level passed in.
235 char* wolfSSL_get_cipher_list(int priority)
237 const char* const* ciphers = GetCipherNames();
239 if (priority >= GetCipherNamesSize() || priority < 0) {
243 return (char*)ciphers[priority];
247 int wolfSSL_get_ciphers(char* buf, int len)
249 const char* const* ciphers = GetCipherNames();
253 int size = GetCipherNamesSize();
256 if (buf == NULL || len <= 0)
259 /* Add each member to the buffer delimitted by a : */
260 for (i = 0; i < size; i++) {
261 step = (int)(XSTRLEN(ciphers[i]) + 1); /* delimiter */
264 /* Check to make sure buf is large enough and will not overflow */
265 if (totalInc < len) {
266 XSTRNCPY(buf, ciphers[i], XSTRLEN(ciphers[i]));
267 buf += XSTRLEN(ciphers[i]);
279 int wolfSSL_get_fd(const WOLFSSL* ssl)
281 WOLFSSL_ENTER("SSL_get_fd");
282 WOLFSSL_LEAVE("SSL_get_fd", ssl->rfd);
287 int wolfSSL_get_using_nonblock(WOLFSSL* ssl)
289 WOLFSSL_ENTER("wolfSSL_get_using_nonblock");
290 WOLFSSL_LEAVE("wolfSSL_get_using_nonblock", ssl->options.usingNonblock);
291 return ssl->options.usingNonblock;
295 int wolfSSL_dtls(WOLFSSL* ssl)
297 return ssl->options.dtls;
301 #ifndef WOLFSSL_LEANPSK
302 void wolfSSL_set_using_nonblock(WOLFSSL* ssl, int nonblock)
304 WOLFSSL_ENTER("wolfSSL_set_using_nonblock");
305 ssl->options.usingNonblock = (nonblock != 0);
309 int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
312 void* sa = (void*)XMALLOC(peerSz, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
314 if (ssl->buffers.dtlsCtx.peer.sa != NULL)
315 XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
316 XMEMCPY(sa, peer, peerSz);
317 ssl->buffers.dtlsCtx.peer.sa = sa;
318 ssl->buffers.dtlsCtx.peer.sz = peerSz;
326 return SSL_NOT_IMPLEMENTED;
330 int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
333 if (peer != NULL && peerSz != NULL
334 && *peerSz >= ssl->buffers.dtlsCtx.peer.sz) {
335 *peerSz = ssl->buffers.dtlsCtx.peer.sz;
336 XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
344 return SSL_NOT_IMPLEMENTED;
347 #endif /* WOLFSSL_LEANPSK */
350 /* return underlyig connect or accept, SSL_SUCCESS on ok */
351 int wolfSSL_negotiate(WOLFSSL* ssl)
353 int err = SSL_FATAL_ERROR;
355 WOLFSSL_ENTER("wolfSSL_negotiate");
356 #ifndef NO_WOLFSSL_SERVER
357 if (ssl->options.side == WOLFSSL_SERVER_END)
358 err = wolfSSL_accept(ssl);
361 #ifndef NO_WOLFSSL_CLIENT
362 if (ssl->options.side == WOLFSSL_CLIENT_END)
363 err = wolfSSL_connect(ssl);
366 WOLFSSL_LEAVE("wolfSSL_negotiate", err);
372 #ifndef WOLFSSL_LEANPSK
373 /* object size based on build */
374 int wolfSSL_GetObjectSize(void)
377 printf("sizeof suites = %lu\n", sizeof(Suites));
378 printf("sizeof ciphers(2) = %lu\n", sizeof(Ciphers));
380 printf(" sizeof arc4 = %lu\n", sizeof(Arc4));
382 printf(" sizeof aes = %lu\n", sizeof(Aes));
384 printf(" sizeof des3 = %lu\n", sizeof(Des3));
387 printf(" sizeof rabbit = %lu\n", sizeof(Rabbit));
390 printf(" sizeof chacha = %lu\n", sizeof(Chacha));
392 printf("sizeof cipher specs = %lu\n", sizeof(CipherSpecs));
393 printf("sizeof keys = %lu\n", sizeof(Keys));
394 printf("sizeof Hashes(2) = %lu\n", sizeof(Hashes));
396 printf(" sizeof MD5 = %lu\n", sizeof(Md5));
399 printf(" sizeof SHA = %lu\n", sizeof(Sha));
402 printf(" sizeof SHA256 = %lu\n", sizeof(Sha256));
404 #ifdef WOLFSSL_SHA384
405 printf(" sizeof SHA384 = %lu\n", sizeof(Sha384));
407 #ifdef WOLFSSL_SHA384
408 printf(" sizeof SHA512 = %lu\n", sizeof(Sha512));
410 printf("sizeof Buffers = %lu\n", sizeof(Buffers));
411 printf("sizeof Options = %lu\n", sizeof(Options));
412 printf("sizeof Arrays = %lu\n", sizeof(Arrays));
414 printf("sizeof RsaKey = %lu\n", sizeof(RsaKey));
417 printf("sizeof ecc_key = %lu\n", sizeof(ecc_key));
419 printf("sizeof WOLFSSL_CIPHER = %lu\n", sizeof(WOLFSSL_CIPHER));
420 printf("sizeof WOLFSSL_SESSION = %lu\n", sizeof(WOLFSSL_SESSION));
421 printf("sizeof WOLFSSL = %lu\n", sizeof(WOLFSSL));
422 printf("sizeof WOLFSSL_CTX = %lu\n", sizeof(WOLFSSL_CTX));
425 return sizeof(WOLFSSL);
431 /* server Diffie-Hellman parameters, SSL_SUCCESS on ok */
432 int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
433 const unsigned char* g, int gSz)
438 WOLFSSL_ENTER("wolfSSL_SetTmpDH");
439 if (ssl == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
441 if (pSz < ssl->options.minDhKeySz)
442 return DH_KEY_SIZE_E;
444 if (ssl->options.side != WOLFSSL_SERVER_END)
447 if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH)
448 XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
449 if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH)
450 XFREE(ssl->buffers.serverDH_G.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
452 ssl->buffers.weOwnDH = 1; /* SSL owns now */
453 ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->ctx->heap,
455 if (ssl->buffers.serverDH_P.buffer == NULL)
458 ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, ssl->ctx->heap,
460 if (ssl->buffers.serverDH_G.buffer == NULL) {
461 XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
465 ssl->buffers.serverDH_P.length = pSz;
466 ssl->buffers.serverDH_G.length = gSz;
468 XMEMCPY(ssl->buffers.serverDH_P.buffer, p, pSz);
469 XMEMCPY(ssl->buffers.serverDH_G.buffer, g, gSz);
471 ssl->options.haveDH = 1;
473 havePSK = ssl->options.havePSK;
478 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH,
479 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
480 ssl->options.haveStaticECC, ssl->options.side);
482 WOLFSSL_LEAVE("wolfSSL_SetTmpDH", 0);
486 /* server ctx Diffie-Hellman parameters, SSL_SUCCESS on ok */
487 int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
488 const unsigned char* g, int gSz)
490 WOLFSSL_ENTER("wolfSSL_CTX_SetTmpDH");
491 if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
493 if (pSz < ctx->minDhKeySz)
494 return DH_KEY_SIZE_E;
496 XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
497 XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
499 ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap,DYNAMIC_TYPE_DH);
500 if (ctx->serverDH_P.buffer == NULL)
503 ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap,DYNAMIC_TYPE_DH);
504 if (ctx->serverDH_G.buffer == NULL) {
505 XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
509 ctx->serverDH_P.length = pSz;
510 ctx->serverDH_G.length = gSz;
512 XMEMCPY(ctx->serverDH_P.buffer, p, pSz);
513 XMEMCPY(ctx->serverDH_G.buffer, g, gSz);
517 WOLFSSL_LEAVE("wolfSSL_CTX_SetTmpDH", 0);
524 int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
528 WOLFSSL_ENTER("SSL_write()");
530 if (ssl == NULL || data == NULL || sz < 0)
537 ret = SendData(ssl, data, sz);
539 WOLFSSL_LEAVE("SSL_write()", ret);
542 return SSL_FATAL_ERROR;
548 static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
552 WOLFSSL_ENTER("wolfSSL_read_internal()");
554 if (ssl == NULL || data == NULL || sz < 0)
561 if (ssl->options.dtls)
562 ssl->dtls_expected_rx = max(sz + 100, MAX_MTU);
565 #ifdef HAVE_MAX_FRAGMENT
566 ret = ReceiveData(ssl, (byte*)data,
567 min(sz, min(ssl->max_fragment, OUTPUT_RECORD_SIZE)), peek);
569 ret = ReceiveData(ssl, (byte*)data, min(sz, OUTPUT_RECORD_SIZE), peek);
572 WOLFSSL_LEAVE("wolfSSL_read_internal()", ret);
575 return SSL_FATAL_ERROR;
581 int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz)
583 WOLFSSL_ENTER("wolfSSL_peek()");
585 return wolfSSL_read_internal(ssl, data, sz, TRUE);
589 int wolfSSL_read(WOLFSSL* ssl, void* data, int sz)
591 WOLFSSL_ENTER("wolfSSL_read()");
593 return wolfSSL_read_internal(ssl, data, sz, FALSE);
599 /* let's use cavium, SSL_SUCCESS on ok */
600 int wolfSSL_UseCavium(WOLFSSL* ssl, int devId)
611 /* let's use cavium, SSL_SUCCESS on ok */
612 int wolfSSL_CTX_UseCavium(WOLFSSL_CTX* ctx, int devId)
623 #endif /* HAVE_CAVIUM */
627 int wolfSSL_UseSNI(WOLFSSL* ssl, byte type, const void* data, word16 size)
632 return TLSX_UseSNI(&ssl->extensions, type, data, size);
635 int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, const void* data, word16 size)
640 return TLSX_UseSNI(&ctx->extensions, type, data, size);
643 #ifndef NO_WOLFSSL_SERVER
645 void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options)
647 if (ssl && ssl->extensions)
648 TLSX_SNI_SetOptions(ssl->extensions, type, options);
651 void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options)
653 if (ctx && ctx->extensions)
654 TLSX_SNI_SetOptions(ctx->extensions, type, options);
657 byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type)
659 return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type);
662 word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data)
667 if (ssl && ssl->extensions)
668 return TLSX_SNI_GetRequest(ssl->extensions, type, data);
673 int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, byte type,
674 byte* sni, word32* inOutSz)
676 if (clientHello && helloSz > 0 && sni && inOutSz && *inOutSz > 0)
677 return TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
682 #endif /* NO_WOLFSSL_SERVER */
684 #endif /* HAVE_SNI */
687 #ifdef HAVE_MAX_FRAGMENT
688 #ifndef NO_WOLFSSL_CLIENT
689 int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl)
694 return TLSX_UseMaxFragment(&ssl->extensions, mfl);
697 int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl)
702 return TLSX_UseMaxFragment(&ctx->extensions, mfl);
704 #endif /* NO_WOLFSSL_CLIENT */
705 #endif /* HAVE_MAX_FRAGMENT */
707 #ifdef HAVE_TRUNCATED_HMAC
708 #ifndef NO_WOLFSSL_CLIENT
709 int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl)
714 return TLSX_UseTruncatedHMAC(&ssl->extensions);
717 int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
722 return TLSX_UseTruncatedHMAC(&ctx->extensions);
724 #endif /* NO_WOLFSSL_CLIENT */
725 #endif /* HAVE_TRUNCATED_HMAC */
727 /* Elliptic Curves */
728 #ifdef HAVE_SUPPORTED_CURVES
729 #ifndef NO_WOLFSSL_CLIENT
731 int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
737 case WOLFSSL_ECC_SECP160R1:
738 case WOLFSSL_ECC_SECP192R1:
739 case WOLFSSL_ECC_SECP224R1:
740 case WOLFSSL_ECC_SECP256R1:
741 case WOLFSSL_ECC_SECP384R1:
742 case WOLFSSL_ECC_SECP521R1:
749 return TLSX_UseSupportedCurve(&ssl->extensions, name);
752 int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
758 case WOLFSSL_ECC_SECP160R1:
759 case WOLFSSL_ECC_SECP192R1:
760 case WOLFSSL_ECC_SECP224R1:
761 case WOLFSSL_ECC_SECP256R1:
762 case WOLFSSL_ECC_SECP384R1:
763 case WOLFSSL_ECC_SECP521R1:
770 return TLSX_UseSupportedCurve(&ctx->extensions, name);
773 #endif /* NO_WOLFSSL_CLIENT */
774 #endif /* HAVE_SUPPORTED_CURVES */
776 /* Secure Renegotiation */
777 #ifdef HAVE_SECURE_RENEGOTIATION
779 /* user is forcing ability to use secure renegotiation, we discourage it */
780 int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl)
782 int ret = BAD_FUNC_ARG;
785 ret = TLSX_UseSecureRenegotiation(&ssl->extensions);
787 if (ret == SSL_SUCCESS) {
788 TLSX* extension = TLSX_Find(ssl->extensions, SECURE_RENEGOTIATION);
791 ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
798 /* do a secure renegotiation handshake, user forced, we discourage */
799 int wolfSSL_Rehandshake(WOLFSSL* ssl)
806 if (ssl->secure_renegotiation == NULL) {
807 WOLFSSL_MSG("Secure Renegotiation not forced on by user");
808 return SECURE_RENEGOTIATION_E;
811 if (ssl->secure_renegotiation->enabled == 0) {
812 WOLFSSL_MSG("Secure Renegotiation not enabled at extension level");
813 return SECURE_RENEGOTIATION_E;
816 if (ssl->options.handShakeState != HANDSHAKE_DONE) {
817 WOLFSSL_MSG("Can't renegotiate until previous handshake complete");
818 return SECURE_RENEGOTIATION_E;
821 #ifndef NO_FORCE_SCR_SAME_SUITE
822 /* force same suite */
824 ssl->suites->suiteSz = SUITE_LEN;
825 ssl->suites->suites[0] = ssl->options.cipherSuite0;
826 ssl->suites->suites[1] = ssl->options.cipherSuite;
830 /* reset handshake states */
831 ssl->options.serverState = NULL_STATE;
832 ssl->options.clientState = NULL_STATE;
833 ssl->options.connectState = CONNECT_BEGIN;
834 ssl->options.acceptState = ACCEPT_BEGIN;
835 ssl->options.handShakeState = NULL_STATE;
836 ssl->options.processReply = 0; /* TODO, move states in internal.h */
838 XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
840 ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
844 wc_InitMd5(&ssl->hsHashes->hashMd5);
847 ret = wc_InitSha(&ssl->hsHashes->hashSha);
851 #endif /* NO_OLD_TLS */
853 ret = wc_InitSha256(&ssl->hsHashes->hashSha256);
857 #ifdef WOLFSSL_SHA384
858 ret = wc_InitSha384(&ssl->hsHashes->hashSha384);
862 #ifdef WOLFSSL_SHA512
863 ret = wc_InitSha512(&ssl->hsHashes->hashSha512);
868 ret = wolfSSL_negotiate(ssl);
872 #endif /* HAVE_SECURE_RENEGOTIATION */
875 #if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SESSION_TICKET)
876 /* SSL_SUCCESS on ok */
877 int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
882 ctx->ticketEncCb = cb;
887 /* set hint interval, SSL_SUCCESS on ok */
888 int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
893 ctx->ticketHint = hint;
898 /* set user context, SSL_SUCCESS on ok */
899 int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void* userCtx)
904 ctx->ticketEncCtx = userCtx;
909 #endif /* !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET) */
912 #if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET)
913 int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
918 return TLSX_UseSessionTicket(&ssl->extensions, NULL);
921 int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx)
926 return TLSX_UseSessionTicket(&ctx->extensions, NULL);
929 WOLFSSL_API int wolfSSL_get_SessionTicket(WOLFSSL* ssl, byte* buf, word32* bufSz)
931 if (ssl == NULL || buf == NULL || bufSz == NULL || *bufSz == 0)
934 if (ssl->session.ticketLen <= *bufSz) {
935 XMEMCPY(buf, ssl->session.ticket, ssl->session.ticketLen);
936 *bufSz = ssl->session.ticketLen;
944 WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL* ssl, byte* buf, word32 bufSz)
946 if (ssl == NULL || (buf == NULL && bufSz > 0))
950 XMEMCPY(ssl->session.ticket, buf, bufSz);
951 ssl->session.ticketLen = (word16)bufSz;
957 WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
958 CallbackSessionTicket cb, void* ctx)
963 ssl->session_ticket_cb = cb;
964 ssl->session_ticket_ctx = ctx;
970 #ifndef WOLFSSL_LEANPSK
972 int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags)
977 WOLFSSL_ENTER("wolfSSL_send()");
979 if (ssl == NULL || data == NULL || sz < 0)
982 oldFlags = ssl->wflags;
985 ret = wolfSSL_write(ssl, data, sz);
986 ssl->wflags = oldFlags;
988 WOLFSSL_LEAVE("wolfSSL_send()", ret);
994 int wolfSSL_recv(WOLFSSL* ssl, void* data, int sz, int flags)
999 WOLFSSL_ENTER("wolfSSL_recv()");
1001 if (ssl == NULL || data == NULL || sz < 0)
1002 return BAD_FUNC_ARG;
1004 oldFlags = ssl->rflags;
1006 ssl->rflags = flags;
1007 ret = wolfSSL_read(ssl, data, sz);
1008 ssl->rflags = oldFlags;
1010 WOLFSSL_LEAVE("wolfSSL_recv()", ret);
1017 /* SSL_SUCCESS on ok */
1018 int wolfSSL_shutdown(WOLFSSL* ssl)
1020 int ret = SSL_FATAL_ERROR;
1022 WOLFSSL_ENTER("SSL_shutdown()");
1025 return SSL_FATAL_ERROR;
1027 if (ssl->options.quietShutdown) {
1028 WOLFSSL_MSG("quiet shutdown, no close notify sent");
1032 /* try to send close notify, not an error if can't */
1033 if (!ssl->options.isClosed && !ssl->options.connReset &&
1034 !ssl->options.sentNotify) {
1035 ssl->error = SendAlert(ssl, alert_warning, close_notify);
1036 if (ssl->error < 0) {
1037 WOLFSSL_ERROR(ssl->error);
1038 return SSL_FATAL_ERROR;
1040 ssl->options.sentNotify = 1; /* don't send close_notify twice */
1041 if (ssl->options.closeNotify)
1044 ret = SSL_SHUTDOWN_NOT_DONE;
1046 WOLFSSL_LEAVE("SSL_shutdown()", ret);
1050 /* call wolfSSL_shutdown again for bidirectional shudown */
1051 if (ssl->options.sentNotify && !ssl->options.closeNotify) {
1052 ret = wolfSSL_read(ssl, &tmp, 0);
1054 WOLFSSL_ERROR(ssl->error);
1055 ret = SSL_FATAL_ERROR;
1056 } else if (ssl->options.closeNotify) {
1057 ssl->error = SSL_ERROR_SYSCALL; /* simulate OpenSSL behavior */
1062 WOLFSSL_LEAVE("SSL_shutdown()", ret);
1068 int wolfSSL_get_error(WOLFSSL* ssl, int ret)
1070 WOLFSSL_ENTER("SSL_get_error");
1073 return SSL_ERROR_NONE;
1075 return BAD_FUNC_ARG;
1077 WOLFSSL_LEAVE("SSL_get_error", ssl->error);
1079 /* make sure converted types are handled in SetErrorString() too */
1080 if (ssl->error == WANT_READ)
1081 return SSL_ERROR_WANT_READ; /* convert to OpenSSL type */
1082 else if (ssl->error == WANT_WRITE)
1083 return SSL_ERROR_WANT_WRITE; /* convert to OpenSSL type */
1084 else if (ssl->error == ZERO_RETURN)
1085 return SSL_ERROR_ZERO_RETURN; /* convert to OpenSSL type */
1090 /* retrive alert history, SSL_SUCCESS on ok */
1091 int wolfSSL_get_alert_history(WOLFSSL* ssl, WOLFSSL_ALERT_HISTORY *h)
1094 *h = ssl->alert_history;
1100 /* return TRUE if current error is want read */
1101 int wolfSSL_want_read(WOLFSSL* ssl)
1103 WOLFSSL_ENTER("SSL_want_read");
1104 if (ssl->error == WANT_READ)
1111 /* return TRUE if current error is want write */
1112 int wolfSSL_want_write(WOLFSSL* ssl)
1114 WOLFSSL_ENTER("SSL_want_write");
1115 if (ssl->error == WANT_WRITE)
1122 char* wolfSSL_ERR_error_string(unsigned long errNumber, char* data)
1124 static const char* msg = "Please supply a buffer for error string";
1126 WOLFSSL_ENTER("ERR_error_string");
1128 SetErrorString((int)errNumber, data);
1136 void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
1138 WOLFSSL_ENTER("wolfSSL_ERR_error_string_n");
1139 if (len >= WOLFSSL_MAX_ERROR_SZ)
1140 wolfSSL_ERR_error_string(e, buf);
1142 char tmp[WOLFSSL_MAX_ERROR_SZ];
1144 WOLFSSL_MSG("Error buffer too short, truncating");
1146 wolfSSL_ERR_error_string(e, tmp);
1147 XMEMCPY(buf, tmp, len-1);
1154 /* don't free temporary arrays at end of handshake */
1155 void wolfSSL_KeepArrays(WOLFSSL* ssl)
1158 ssl->options.saveArrays = 1;
1162 /* user doesn't need temporary arrays anymore, Free */
1163 void wolfSSL_FreeArrays(WOLFSSL* ssl)
1165 if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
1166 ssl->options.saveArrays = 0;
1172 const byte* wolfSSL_GetMacSecret(WOLFSSL* ssl, int verify)
1177 if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
1178 (ssl->options.side == WOLFSSL_SERVER_END && verify) )
1179 return ssl->keys.client_write_MAC_secret;
1181 return ssl->keys.server_write_MAC_secret;
1187 void wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX* ctx, CallbackMacEncrypt cb)
1190 ctx->MacEncryptCb = cb;
1194 void wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx)
1197 ssl->MacEncryptCtx = ctx;
1201 void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl)
1204 return ssl->MacEncryptCtx;
1210 void wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX* ctx, CallbackDecryptVerify cb)
1213 ctx->DecryptVerifyCb = cb;
1217 void wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx)
1220 ssl->DecryptVerifyCtx = ctx;
1224 void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl)
1227 return ssl->DecryptVerifyCtx;
1233 const byte* wolfSSL_GetClientWriteKey(WOLFSSL* ssl)
1236 return ssl->keys.client_write_key;
1242 const byte* wolfSSL_GetClientWriteIV(WOLFSSL* ssl)
1245 return ssl->keys.client_write_IV;
1251 const byte* wolfSSL_GetServerWriteKey(WOLFSSL* ssl)
1254 return ssl->keys.server_write_key;
1260 const byte* wolfSSL_GetServerWriteIV(WOLFSSL* ssl)
1263 return ssl->keys.server_write_IV;
1269 int wolfSSL_GetKeySize(WOLFSSL* ssl)
1272 return ssl->specs.key_size;
1274 return BAD_FUNC_ARG;
1278 int wolfSSL_GetIVSize(WOLFSSL* ssl)
1281 return ssl->specs.iv_size;
1283 return BAD_FUNC_ARG;
1287 int wolfSSL_GetBulkCipher(WOLFSSL* ssl)
1290 return ssl->specs.bulk_cipher_algorithm;
1292 return BAD_FUNC_ARG;
1296 int wolfSSL_GetCipherType(WOLFSSL* ssl)
1299 return BAD_FUNC_ARG;
1301 if (ssl->specs.cipher_type == block)
1302 return WOLFSSL_BLOCK_TYPE;
1303 if (ssl->specs.cipher_type == stream)
1304 return WOLFSSL_STREAM_TYPE;
1305 if (ssl->specs.cipher_type == aead)
1306 return WOLFSSL_AEAD_TYPE;
1312 int wolfSSL_GetCipherBlockSize(WOLFSSL* ssl)
1315 return BAD_FUNC_ARG;
1317 return ssl->specs.block_size;
1321 int wolfSSL_GetAeadMacSize(WOLFSSL* ssl)
1324 return BAD_FUNC_ARG;
1326 return ssl->specs.aead_mac_size;
1330 int wolfSSL_IsTLSv1_1(WOLFSSL* ssl)
1333 return BAD_FUNC_ARG;
1335 if (ssl->options.tls1_1)
1342 int wolfSSL_GetSide(WOLFSSL* ssl)
1345 return ssl->options.side;
1347 return BAD_FUNC_ARG;
1351 int wolfSSL_GetHmacSize(WOLFSSL* ssl)
1353 /* AEAD ciphers don't have HMAC keys */
1355 return (ssl->specs.cipher_type != aead) ? ssl->specs.hash_size : 0;
1357 return BAD_FUNC_ARG;
1360 #endif /* ATOMIC_USER */
1364 WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void)
1366 WOLFSSL_CERT_MANAGER* cm = NULL;
1368 WOLFSSL_ENTER("wolfSSL_CertManagerNew");
1370 cm = (WOLFSSL_CERT_MANAGER*) XMALLOC(sizeof(WOLFSSL_CERT_MANAGER), 0,
1371 DYNAMIC_TYPE_CERT_MANAGER);
1373 XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER));
1375 if (InitMutex(&cm->caLock) != 0) {
1376 WOLFSSL_MSG("Bad mutex init");
1377 wolfSSL_CertManagerFree(cm);
1386 void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
1388 WOLFSSL_ENTER("wolfSSL_CertManagerFree");
1393 FreeCRL(cm->crl, 1);
1397 FreeOCSP(cm->ocsp, 1);
1399 FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
1400 FreeMutex(&cm->caLock);
1401 XFREE(cm, NULL, DYNAMIC_TYPE_CERT_MANAGER);
1407 /* Unload the CA signer list */
1408 int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
1410 WOLFSSL_ENTER("wolfSSL_CertManagerUnloadCAs");
1413 return BAD_FUNC_ARG;
1415 if (LockMutex(&cm->caLock) != 0)
1418 FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
1420 UnLockMutex(&cm->caLock);
1427 /* Return bytes written to buff or < 0 for error */
1428 int wolfSSL_CertPemToDer(const unsigned char* pem, int pemSz,
1429 unsigned char* buff, int buffSz,
1435 #ifdef WOLFSSL_SMALL_STACK
1436 EncryptedInfo* info = NULL;
1438 EncryptedInfo info[1];
1441 WOLFSSL_ENTER("wolfSSL_CertPemToDer");
1443 if (pem == NULL || buff == NULL || buffSz <= 0) {
1444 WOLFSSL_MSG("Bad pem der args");
1445 return BAD_FUNC_ARG;
1448 if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) {
1449 WOLFSSL_MSG("Bad cert type");
1450 return BAD_FUNC_ARG;
1453 #ifdef WOLFSSL_SMALL_STACK
1454 info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
1455 DYNAMIC_TYPE_TMP_BUFFER);
1465 ret = PemToDer(pem, pemSz, type, &der, NULL, info, &eccKey);
1467 #ifdef WOLFSSL_SMALL_STACK
1468 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1472 WOLFSSL_MSG("Bad Pem To Der");
1475 if (der.length <= (word32)buffSz) {
1476 XMEMCPY(buff, der.buffer, der.length);
1480 WOLFSSL_MSG("Bad der length");
1485 XFREE(der.buffer, NULL, DYNAMIC_TYPE_KEY);
1491 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
1493 /* our KeyPemToDer password callback, password in userData */
1494 static INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
1498 if (userdata == NULL)
1501 XSTRNCPY(passwd, (char*)userdata, sz);
1502 return min((word32)sz, (word32)XSTRLEN((char*)userdata));
1505 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
1508 /* Return bytes written to buff or < 0 for error */
1509 int wolfSSL_KeyPemToDer(const unsigned char* pem, int pemSz, unsigned char* buff,
1510 int buffSz, const char* pass)
1515 #ifdef WOLFSSL_SMALL_STACK
1516 EncryptedInfo* info = NULL;
1518 EncryptedInfo info[1];
1523 WOLFSSL_ENTER("wolfSSL_KeyPemToDer");
1525 if (pem == NULL || buff == NULL || buffSz <= 0) {
1526 WOLFSSL_MSG("Bad pem der args");
1527 return BAD_FUNC_ARG;
1530 #ifdef WOLFSSL_SMALL_STACK
1531 info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
1532 DYNAMIC_TYPE_TMP_BUFFER);
1542 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
1544 info->ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
1545 if (info->ctx == NULL) {
1546 #ifdef WOLFSSL_SMALL_STACK
1547 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1552 wolfSSL_CTX_set_default_passwd_cb(info->ctx, OurPasswordCb);
1553 wolfSSL_CTX_set_default_passwd_cb_userdata(info->ctx, (void*)pass);
1557 ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, &eccKey);
1560 wolfSSL_CTX_free(info->ctx);
1562 #ifdef WOLFSSL_SMALL_STACK
1563 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1567 WOLFSSL_MSG("Bad Pem To Der");
1570 if (der.length <= (word32)buffSz) {
1571 XMEMCPY(buff, der.buffer, der.length);
1575 WOLFSSL_MSG("Bad der length");
1580 XFREE(der.buffer, NULL, DYNAMIC_TYPE_KEY);
1586 #endif /* !NO_CERTS */
1590 #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
1592 void wolfSSL_ERR_print_errors_fp(FILE* fp, int err)
1594 char data[WOLFSSL_MAX_ERROR_SZ + 1];
1596 WOLFSSL_ENTER("wolfSSL_ERR_print_errors_fp");
1597 SetErrorString(err, data);
1598 fprintf(fp, "%s", data);
1604 int wolfSSL_pending(WOLFSSL* ssl)
1606 WOLFSSL_ENTER("SSL_pending");
1607 return ssl->buffers.clearOutputBuffer.length;
1611 #ifndef WOLFSSL_LEANPSK
1612 /* trun on handshake group messages for context */
1613 int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx)
1616 return BAD_FUNC_ARG;
1618 ctx->groupMessages = 1;
1625 #ifndef NO_WOLFSSL_CLIENT
1626 /* connect enough to get peer cert chain */
1627 int wolfSSL_connect_cert(WOLFSSL* ssl)
1634 ssl->options.certOnly = 1;
1635 ret = wolfSSL_connect(ssl);
1636 ssl->options.certOnly = 0;
1643 #ifndef WOLFSSL_LEANPSK
1644 /* trun on handshake group messages for ssl object */
1645 int wolfSSL_set_group_messages(WOLFSSL* ssl)
1648 return BAD_FUNC_ARG;
1650 ssl->options.groupMessages = 1;
1656 /* make minVersion the internal equivilant SSL version */
1657 static int SetMinVersionHelper(byte* minVersion, int version)
1662 *minVersion = SSLv3_MINOR;
1669 *minVersion = TLSv1_MINOR;
1672 case WOLFSSL_TLSV1_1:
1673 *minVersion = TLSv1_1_MINOR;
1676 case WOLFSSL_TLSV1_2:
1677 *minVersion = TLSv1_2_MINOR;
1682 WOLFSSL_MSG("Bad function argument");
1683 return BAD_FUNC_ARG;
1690 /* Set minimum downgrade version allowed, SSL_SUCCESS on ok */
1691 int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version)
1693 WOLFSSL_ENTER("wolfSSL_CTX_SetMinVersion");
1696 WOLFSSL_MSG("Bad function argument");
1697 return BAD_FUNC_ARG;
1700 return SetMinVersionHelper(&ctx->minDowngrade, version);
1704 /* Set minimum downgrade version allowed, SSL_SUCCESS on ok */
1705 int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version)
1707 WOLFSSL_ENTER("wolfSSL_SetMinVersion");
1710 WOLFSSL_MSG("Bad function argument");
1711 return BAD_FUNC_ARG;
1714 return SetMinVersionHelper(&ssl->options.minDowngrade, version);
1718 int wolfSSL_SetVersion(WOLFSSL* ssl, int version)
1723 WOLFSSL_ENTER("wolfSSL_SetVersion");
1726 WOLFSSL_MSG("Bad function argument");
1727 return BAD_FUNC_ARG;
1733 ssl->version = MakeSSLv3();
1740 ssl->version = MakeTLSv1();
1743 case WOLFSSL_TLSV1_1:
1744 ssl->version = MakeTLSv1_1();
1747 case WOLFSSL_TLSV1_2:
1748 ssl->version = MakeTLSv1_2();
1753 WOLFSSL_MSG("Bad function argument");
1754 return BAD_FUNC_ARG;
1761 havePSK = ssl->options.havePSK;
1764 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH,
1765 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
1766 ssl->options.haveStaticECC, ssl->options.side);
1770 #endif /* !leanpsk */
1773 #if !defined(NO_CERTS) || !defined(NO_SESSION_CACHE)
1775 /* Make a work from the front of random hash */
1776 static INLINE word32 MakeWordFromHash(const byte* hashID)
1778 return (hashID[0] << 24) | (hashID[1] << 16) | (hashID[2] << 8) |
1782 #endif /* !NO_CERTS || !NO_SESSION_CACHE */
1787 /* hash is the SHA digest of name, just use first 32 bits as hash */
1788 static INLINE word32 HashSigner(const byte* hash)
1790 return MakeWordFromHash(hash) % CA_TABLE_SIZE;
1794 /* does CA already exist on signer list */
1795 int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash)
1799 word32 row = HashSigner(hash);
1801 if (LockMutex(&cm->caLock) != 0)
1803 signers = cm->caTable[row];
1807 subjectHash = signers->subjectKeyIdHash;
1809 subjectHash = signers->subjectNameHash;
1811 if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
1815 signers = signers->next;
1817 UnLockMutex(&cm->caLock);
1823 /* return CA if found, otherwise NULL */
1824 Signer* GetCA(void* vp, byte* hash)
1826 WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
1829 word32 row = HashSigner(hash);
1834 if (LockMutex(&cm->caLock) != 0)
1837 signers = cm->caTable[row];
1841 subjectHash = signers->subjectKeyIdHash;
1843 subjectHash = signers->subjectNameHash;
1845 if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
1849 signers = signers->next;
1851 UnLockMutex(&cm->caLock);
1858 /* return CA if found, otherwise NULL. Walk through hash table. */
1859 Signer* GetCAByName(void* vp, byte* hash)
1861 WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
1869 if (LockMutex(&cm->caLock) != 0)
1872 for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
1873 signers = cm->caTable[row];
1874 while (signers && ret == NULL) {
1876 signers->subjectNameHash, SIGNER_DIGEST_SIZE) == 0) {
1879 signers = signers->next;
1882 UnLockMutex(&cm->caLock);
1889 /* owns der, internal now uses too */
1890 /* type flag ids from user or from chain received during verify
1891 don't allow chain ones to be added w/o isCA extension */
1892 int AddCA(WOLFSSL_CERT_MANAGER* cm, buffer der, int type, int verify)
1898 #ifdef WOLFSSL_SMALL_STACK
1899 DecodedCert* cert = NULL;
1901 DecodedCert cert[1];
1904 WOLFSSL_MSG("Adding a CA");
1906 #ifdef WOLFSSL_SMALL_STACK
1907 cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
1908 DYNAMIC_TYPE_TMP_BUFFER);
1913 InitDecodedCert(cert, der.buffer, der.length, cm->heap);
1914 ret = ParseCert(cert, CA_TYPE, verify, cm);
1915 WOLFSSL_MSG(" Parsed new CA");
1918 subjectHash = cert->extSubjKeyId;
1920 subjectHash = cert->subjectHash;
1923 if (ret == 0 && cert->isCA == 0 && type != WOLFSSL_USER_CA) {
1924 WOLFSSL_MSG(" Can't add as CA if not actually one");
1927 #ifndef ALLOW_INVALID_CERTSIGN
1928 else if (ret == 0 && cert->isCA == 1 && type != WOLFSSL_USER_CA &&
1929 (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) == 0) {
1930 /* Intermediate CA certs are required to have the keyCertSign
1931 * extension set. User loaded root certs are not. */
1932 WOLFSSL_MSG(" Doesn't have key usage certificate signing");
1936 else if (ret == 0 && AlreadySigner(cm, subjectHash)) {
1937 WOLFSSL_MSG(" Already have this CA, not adding again");
1940 else if (ret == 0) {
1941 /* take over signer parts */
1942 signer = MakeSigner(cm->heap);
1946 signer->keyOID = cert->keyOID;
1947 signer->publicKey = cert->publicKey;
1948 signer->pubKeySize = cert->pubKeySize;
1949 signer->nameLen = cert->subjectCNLen;
1950 signer->name = cert->subjectCN;
1951 #ifndef IGNORE_NAME_CONSTRAINTS
1952 signer->permittedNames = cert->permittedNames;
1953 signer->excludedNames = cert->excludedNames;
1956 XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
1957 SIGNER_DIGEST_SIZE);
1959 XMEMCPY(signer->subjectNameHash, cert->subjectHash,
1960 SIGNER_DIGEST_SIZE);
1961 signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
1963 signer->next = NULL; /* If Key Usage not set, all uses valid. */
1964 cert->publicKey = 0; /* in case lock fails don't free here. */
1965 cert->subjectCN = 0;
1966 #ifndef IGNORE_NAME_CONSTRAINTS
1967 cert->permittedNames = NULL;
1968 cert->excludedNames = NULL;
1972 row = HashSigner(signer->subjectKeyIdHash);
1974 row = HashSigner(signer->subjectNameHash);
1977 if (LockMutex(&cm->caLock) == 0) {
1978 signer->next = cm->caTable[row];
1979 cm->caTable[row] = signer; /* takes ownership */
1980 UnLockMutex(&cm->caLock);
1981 if (cm->caCacheCallback)
1982 cm->caCacheCallback(der.buffer, (int)der.length, type);
1985 WOLFSSL_MSG(" CA Mutex Lock failed");
1987 FreeSigner(signer, cm->heap);
1992 WOLFSSL_MSG(" Freeing Parsed CA");
1993 FreeDecodedCert(cert);
1994 #ifdef WOLFSSL_SMALL_STACK
1995 XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1997 WOLFSSL_MSG(" Freeing der CA");
1998 XFREE(der.buffer, cm->heap, DYNAMIC_TYPE_CA);
1999 WOLFSSL_MSG(" OK Freeing der CA");
2001 WOLFSSL_LEAVE("AddCA", ret);
2003 return ret == 0 ? SSL_SUCCESS : ret;
2006 #endif /* !NO_CERTS */
2009 #ifndef NO_SESSION_CACHE
2011 /* basic config gives a cache with 33 sessions, adequate for clients and
2014 MEDIUM_SESSION_CACHE allows 1055 sessions, adequate for servers that
2015 aren't under heavy load, basically allows 200 new sessions per minute
2017 BIG_SESSION_CACHE yields 20,027 sessions
2019 HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
2020 allows over 13,000 new sessions per minute or over 200 new sessions per
2023 SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients
2024 or systems where the default of nearly 3kB is too much RAM, this define
2025 uses less than 500 bytes RAM
2027 default SESSION_CACHE stores 33 sessions (no XXX_SESSION_CACHE defined)
2029 #ifdef HUGE_SESSION_CACHE
2030 #define SESSIONS_PER_ROW 11
2031 #define SESSION_ROWS 5981
2032 #elif defined(BIG_SESSION_CACHE)
2033 #define SESSIONS_PER_ROW 7
2034 #define SESSION_ROWS 2861
2035 #elif defined(MEDIUM_SESSION_CACHE)
2036 #define SESSIONS_PER_ROW 5
2037 #define SESSION_ROWS 211
2038 #elif defined(SMALL_SESSION_CACHE)
2039 #define SESSIONS_PER_ROW 2
2040 #define SESSION_ROWS 3
2042 #define SESSIONS_PER_ROW 3
2043 #define SESSION_ROWS 11
2046 typedef struct SessionRow {
2047 int nextIdx; /* where to place next one */
2048 int totalCount; /* sessions ever on this row */
2049 WOLFSSL_SESSION Sessions[SESSIONS_PER_ROW];
2052 static SessionRow SessionCache[SESSION_ROWS];
2054 #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
2055 static word32 PeakSessions;
2058 static wolfSSL_Mutex session_mutex; /* SessionCache mutex */
2060 #ifndef NO_CLIENT_CACHE
2062 typedef struct ClientSession {
2063 word16 serverRow; /* SessionCache Row id */
2064 word16 serverIdx; /* SessionCache Idx (column) */
2067 typedef struct ClientRow {
2068 int nextIdx; /* where to place next one */
2069 int totalCount; /* sessions ever on this row */
2070 ClientSession Clients[SESSIONS_PER_ROW];
2073 static ClientRow ClientCache[SESSION_ROWS]; /* Client Cache */
2074 /* uses session mutex */
2075 #endif /* NO_CLIENT_CACHE */
2077 #endif /* NO_SESSION_CACHE */
2080 int wolfSSL_Init(void)
2082 int ret = SSL_SUCCESS;
2084 WOLFSSL_ENTER("wolfSSL_Init");
2086 if (initRefCount == 0) {
2087 #ifndef NO_SESSION_CACHE
2088 if (InitMutex(&session_mutex) != 0)
2091 if (InitMutex(&count_mutex) != 0)
2094 if (ret == SSL_SUCCESS) {
2095 if (LockMutex(&count_mutex) != 0) {
2096 WOLFSSL_MSG("Bad Lock Mutex count");
2100 UnLockMutex(&count_mutex);
2109 static const char* BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
2110 static const char* END_CERT = "-----END CERTIFICATE-----";
2111 static const char* BEGIN_CERT_REQ = "-----BEGIN CERTIFICATE REQUEST-----";
2112 static const char* END_CERT_REQ = "-----END CERTIFICATE REQUEST-----";
2113 static const char* BEGIN_DH_PARAM = "-----BEGIN DH PARAMETERS-----";
2114 static const char* END_DH_PARAM = "-----END DH PARAMETERS-----";
2115 static const char* BEGIN_X509_CRL = "-----BEGIN X509 CRL-----";
2116 static const char* END_X509_CRL = "-----END X509 CRL-----";
2117 static const char* BEGIN_RSA_PRIV = "-----BEGIN RSA PRIVATE KEY-----";
2118 static const char* END_RSA_PRIV = "-----END RSA PRIVATE KEY-----";
2119 static const char* BEGIN_PRIV_KEY = "-----BEGIN PRIVATE KEY-----";
2120 static const char* END_PRIV_KEY = "-----END PRIVATE KEY-----";
2121 static const char* BEGIN_ENC_PRIV_KEY = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
2122 static const char* END_ENC_PRIV_KEY = "-----END ENCRYPTED PRIVATE KEY-----";
2123 static const char* BEGIN_EC_PRIV = "-----BEGIN EC PRIVATE KEY-----";
2124 static const char* END_EC_PRIV = "-----END EC PRIVATE KEY-----";
2125 static const char* BEGIN_DSA_PRIV = "-----BEGIN DSA PRIVATE KEY-----";
2126 static const char* END_DSA_PRIV = "-----END DSA PRIVATE KEY-----";
2128 /* Remove PEM header/footer, convert to ASN1, store any encrypted data
2129 info->consumed tracks of PEM bytes consumed in case multiple parts */
2130 int PemToDer(const unsigned char* buff, long longSz, int type,
2131 buffer* der, void* heap, EncryptedInfo* info, int* eccKey)
2133 const char* header = NULL;
2134 const char* footer = NULL;
2138 char* bufferEnd = (char*)(buff + longSz);
2141 int dynamicType = 0;
2142 int sz = (int)longSz;
2145 case CA_TYPE: /* same as below */
2146 case CERT_TYPE: header= BEGIN_CERT; footer= END_CERT; break;
2147 case CRL_TYPE: header= BEGIN_X509_CRL; footer= END_X509_CRL; break;
2148 case DH_PARAM_TYPE: header= BEGIN_DH_PARAM; footer= END_DH_PARAM; break;
2149 case CERTREQ_TYPE: header= BEGIN_CERT_REQ; footer= END_CERT_REQ; break;
2150 default: header= BEGIN_RSA_PRIV; footer= END_RSA_PRIV; break;
2154 case CA_TYPE: dynamicType = DYNAMIC_TYPE_CA; break;
2155 case CERT_TYPE: dynamicType = DYNAMIC_TYPE_CERT; break;
2156 case CRL_TYPE: dynamicType = DYNAMIC_TYPE_CRL; break;
2157 default: dynamicType = DYNAMIC_TYPE_KEY; break;
2162 headerEnd = XSTRNSTR((char*)buff, header, sz);
2164 if (headerEnd || type != PRIVATEKEY_TYPE) {
2166 } else if (header == BEGIN_RSA_PRIV) {
2167 header = BEGIN_PRIV_KEY; footer = END_PRIV_KEY;
2168 } else if (header == BEGIN_PRIV_KEY) {
2169 header = BEGIN_ENC_PRIV_KEY; footer = END_ENC_PRIV_KEY;
2170 } else if (header == BEGIN_ENC_PRIV_KEY) {
2171 header = BEGIN_EC_PRIV; footer = END_EC_PRIV;
2172 } else if (header == BEGIN_EC_PRIV) {
2173 header = BEGIN_DSA_PRIV; footer = END_DSA_PRIV;
2179 WOLFSSL_MSG("Couldn't find PEM header");
2180 return SSL_NO_PEM_HEADER;
2183 headerEnd += XSTRLEN(header);
2185 /* eat end of line */
2186 if (headerEnd[0] == '\n')
2188 else if (headerEnd[1] == '\n')
2191 return SSL_BAD_FILE;
2193 if (type == PRIVATEKEY_TYPE) {
2195 *eccKey = header == BEGIN_EC_PRIV;
2198 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
2200 /* remove encrypted header if there */
2201 char encHeader[] = "Proc-Type";
2202 char* line = XSTRNSTR(headerEnd, encHeader, PEM_LINE_LEN);
2206 char* start = XSTRNSTR(line, "DES", PEM_LINE_LEN);
2209 start = XSTRNSTR(line, "AES", PEM_LINE_LEN);
2211 if (!start) return SSL_BAD_FILE;
2212 if (!info) return SSL_BAD_FILE;
2214 finish = XSTRNSTR(start, ",", PEM_LINE_LEN);
2216 if (start && finish && (start < finish)) {
2217 newline = XSTRNSTR(finish, "\r", PEM_LINE_LEN);
2219 XMEMCPY(info->name, start, finish - start);
2220 info->name[finish - start] = 0;
2221 XMEMCPY(info->iv, finish + 1, sizeof(info->iv));
2223 if (!newline) newline = XSTRNSTR(finish, "\n", PEM_LINE_LEN);
2224 if (newline && (newline > finish)) {
2225 info->ivSz = (word32)(newline - (finish + 1));
2229 return SSL_BAD_FILE;
2232 return SSL_BAD_FILE;
2234 /* eat blank line */
2235 while (*newline == '\r' || *newline == '\n')
2237 headerEnd = newline;
2240 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
2243 footerEnd = XSTRNSTR((char*)buff, footer, sz);
2245 return SSL_BAD_FILE;
2247 consumedEnd = footerEnd + XSTRLEN(footer);
2249 if (consumedEnd < bufferEnd) { /* handle no end of line on last line */
2250 /* eat end of line */
2251 if (consumedEnd[0] == '\n')
2253 else if (consumedEnd[1] == '\n')
2256 return SSL_BAD_FILE;
2260 info->consumed = (long)(consumedEnd - (char*)buff);
2262 /* set up der buffer */
2263 neededSz = (long)(footerEnd - headerEnd);
2264 if (neededSz > sz || neededSz < 0)
2265 return SSL_BAD_FILE;
2267 der->buffer = (byte*)XMALLOC(neededSz, heap, dynamicType);
2269 return MEMORY_ERROR;
2271 der->length = (word32)neededSz;
2273 if (Base64_Decode((byte*)headerEnd, (word32)neededSz, der->buffer,
2275 return SSL_BAD_FILE;
2277 if (header == BEGIN_PRIV_KEY) {
2278 /* pkcs8 key, convert and adjust length */
2279 if ((ret = ToTraditional(der->buffer, der->length)) < 0)
2286 #if (defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)) && !defined(NO_PWDBASED)
2287 if (header == BEGIN_ENC_PRIV_KEY) {
2289 #ifdef WOLFSSL_SMALL_STACK
2290 char* password = NULL;
2295 if (!info || !info->ctx || !info->ctx->passwd_cb)
2296 return SSL_BAD_FILE; /* no callback error */
2298 #ifdef WOLFSSL_SMALL_STACK
2299 password = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2300 if (password == NULL)
2303 passwordSz = info->ctx->passwd_cb(password, sizeof(password), 0,
2304 info->ctx->userdata);
2305 /* convert and adjust length */
2306 ret = ToTraditionalEnc(der->buffer, der->length, password, passwordSz);
2308 #ifdef WOLFSSL_SMALL_STACK
2309 XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2324 /* process the buffer buff, legnth sz, into ctx of format and type
2325 used tracks bytes consumed, userChain specifies a user cert chain
2326 to pass during the handshake */
2327 static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
2328 long sz, int format, int type, WOLFSSL* ssl,
2329 long* used, int userChain)
2331 buffer der; /* holds DER or RAW (for NTRU) */
2333 int dynamicType = 0;
2336 void* heap = ctx ? ctx->heap : NULL;
2337 #ifdef WOLFSSL_SMALL_STACK
2338 EncryptedInfo* info = NULL;
2340 EncryptedInfo info[1];
2347 *used = sz; /* used bytes default to sz, PEM chain may shorten*/
2349 if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM
2350 && format != SSL_FILETYPE_RAW)
2351 return SSL_BAD_FILETYPE;
2353 if (ctx == NULL && ssl == NULL)
2354 return BAD_FUNC_ARG;
2356 if (type == CA_TYPE)
2357 dynamicType = DYNAMIC_TYPE_CA;
2358 else if (type == CERT_TYPE)
2359 dynamicType = DYNAMIC_TYPE_CERT;
2361 dynamicType = DYNAMIC_TYPE_KEY;
2363 #ifdef WOLFSSL_SMALL_STACK
2364 info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
2365 DYNAMIC_TYPE_TMP_BUFFER);
2375 if (format == SSL_FILETYPE_PEM) {
2376 ret = PemToDer(buff, sz, type, &der, heap, info, &eccKey);
2378 #ifdef WOLFSSL_SMALL_STACK
2379 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2381 XFREE(der.buffer, heap, dynamicType);
2386 *used = info->consumed;
2388 /* we may have a user cert chain, try to consume */
2389 if (userChain && type == CERT_TYPE && info->consumed < sz) {
2390 #ifdef WOLFSSL_SMALL_STACK
2391 byte staticBuffer[1]; /* force heap usage */
2393 byte staticBuffer[FILE_BUFFER_SIZE]; /* tmp chain buffer */
2395 byte* chainBuffer = staticBuffer;
2396 byte* shrinked = NULL; /* shrinked to size chainBuffer
2397 * or staticBuffer */
2398 int dynamicBuffer = 0;
2399 word32 bufferSz = sizeof(staticBuffer);
2400 long consumed = info->consumed;
2404 if ( (sz - consumed) > (int)bufferSz) {
2405 WOLFSSL_MSG("Growing Tmp Chain Buffer");
2406 bufferSz = (word32)(sz - consumed);
2407 /* will shrink to actual size */
2408 chainBuffer = (byte*)XMALLOC(bufferSz, heap, DYNAMIC_TYPE_FILE);
2409 if (chainBuffer == NULL) {
2410 #ifdef WOLFSSL_SMALL_STACK
2411 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2413 XFREE(der.buffer, heap, dynamicType);
2419 WOLFSSL_MSG("Processing Cert Chain");
2420 while (consumed < sz) {
2425 ret = PemToDer(buff + consumed, sz - consumed, type, &part,
2426 heap, info, &eccKey);
2429 if ( (idx + part.length) > bufferSz) {
2430 WOLFSSL_MSG(" Cert Chain bigger than buffer");
2434 c32to24(part.length, &chainBuffer[idx]);
2435 idx += CERT_HEADER_SZ;
2436 XMEMCPY(&chainBuffer[idx], part.buffer,part.length);
2438 consumed += info->consumed;
2440 *used += info->consumed;
2444 XFREE(part.buffer, heap, dynamicType);
2446 if (ret == SSL_NO_PEM_HEADER && gotOne) {
2447 WOLFSSL_MSG("We got one good PEM so stuff at end ok");
2452 WOLFSSL_MSG(" Error in Cert in Chain");
2454 XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
2455 #ifdef WOLFSSL_SMALL_STACK
2456 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2458 XFREE(der.buffer, heap, dynamicType);
2461 WOLFSSL_MSG(" Consumed another Cert in Chain");
2463 WOLFSSL_MSG("Finished Processing Cert Chain");
2465 /* only retain actual size used */
2466 shrinked = (byte*)XMALLOC(idx, heap, dynamicType);
2469 if (ssl->buffers.certChain.buffer &&
2470 ssl->buffers.weOwnCertChain) {
2471 XFREE(ssl->buffers.certChain.buffer, heap,
2474 ssl->buffers.certChain.buffer = shrinked;
2475 ssl->buffers.certChain.length = idx;
2476 XMEMCPY(ssl->buffers.certChain.buffer, chainBuffer,idx);
2477 ssl->buffers.weOwnCertChain = 1;
2479 if (ctx->certChain.buffer)
2480 XFREE(ctx->certChain.buffer, heap, dynamicType);
2481 ctx->certChain.buffer = shrinked;
2482 ctx->certChain.length = idx;
2483 XMEMCPY(ctx->certChain.buffer, chainBuffer, idx);
2488 XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
2490 if (shrinked == NULL) {
2491 #ifdef WOLFSSL_SMALL_STACK
2492 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2494 XFREE(der.buffer, heap, dynamicType);
2499 else { /* ASN1 (DER) or RAW (NTRU) */
2500 der.buffer = (byte*) XMALLOC(sz, heap, dynamicType);
2502 #ifdef WOLFSSL_SMALL_STACK
2503 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2505 return MEMORY_ERROR;
2508 XMEMCPY(der.buffer, buff, sz);
2509 der.length = (word32)sz;
2512 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
2516 #ifdef WOLFSSL_SMALL_STACK
2517 char* password = NULL;
2522 byte key[AES_256_KEY_SIZE];
2524 byte iv[AES_IV_SIZE];
2528 #ifdef WOLFSSL_SMALL_STACK
2529 password = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2530 key = (byte*)XMALLOC(AES_256_KEY_SIZE, NULL,
2531 DYNAMIC_TYPE_TMP_BUFFER);
2532 iv = (byte*)XMALLOC(AES_IV_SIZE, NULL,
2533 DYNAMIC_TYPE_TMP_BUFFER);
2535 if (password == NULL || key == NULL || iv == NULL) {
2536 XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2537 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2538 XFREE(iv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2543 if (!ctx || !ctx->passwd_cb) {
2547 passwordSz = ctx->passwd_cb(password, sizeof(password), 0,
2550 /* use file's salt for key derivation, hex decode first */
2551 if (Base16_Decode(info->iv, info->ivSz, info->iv, &info->ivSz)
2556 else if ((ret = EVP_BytesToKey(info->name, "MD5", info->iv,
2557 (byte*)password, passwordSz, 1, key, iv)) <= 0) {
2562 else if (XSTRNCMP(info->name, "DES-CBC", 7) == 0) {
2563 ret = wc_Des_CbcDecryptWithKey(der.buffer, der.buffer, der.length,
2566 else if (XSTRNCMP(info->name, "DES-EDE3-CBC", 13) == 0) {
2567 ret = wc_Des3_CbcDecryptWithKey(der.buffer, der.buffer, der.length,
2572 else if (XSTRNCMP(info->name, "AES-128-CBC", 13) == 0) {
2573 ret = wc_AesCbcDecryptWithKey(der.buffer, der.buffer, der.length,
2574 key, AES_128_KEY_SIZE, info->iv);
2576 else if (XSTRNCMP(info->name, "AES-192-CBC", 13) == 0) {
2577 ret = wc_AesCbcDecryptWithKey(der.buffer, der.buffer, der.length,
2578 key, AES_192_KEY_SIZE, info->iv);
2580 else if (XSTRNCMP(info->name, "AES-256-CBC", 13) == 0) {
2581 ret = wc_AesCbcDecryptWithKey(der.buffer, der.buffer, der.length,
2582 key, AES_256_KEY_SIZE, info->iv);
2590 #ifdef WOLFSSL_SMALL_STACK
2591 XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2592 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2593 XFREE(iv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2597 #ifdef WOLFSSL_SMALL_STACK
2598 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2600 XFREE(der.buffer, heap, dynamicType);
2604 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
2606 #ifdef WOLFSSL_SMALL_STACK
2607 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2610 if (type == CA_TYPE) {
2612 WOLFSSL_MSG("Need context for CA load");
2613 XFREE(der.buffer, heap, dynamicType);
2614 return BAD_FUNC_ARG;
2616 return AddCA(ctx->cm, der, WOLFSSL_USER_CA, ctx->verifyPeer);
2617 /* takes der over */
2619 else if (type == CERT_TYPE) {
2621 if (ssl->buffers.weOwnCert && ssl->buffers.certificate.buffer)
2622 XFREE(ssl->buffers.certificate.buffer, heap, dynamicType);
2623 ssl->buffers.certificate = der;
2624 ssl->buffers.weOwnCert = 1;
2627 if (ctx->certificate.buffer)
2628 XFREE(ctx->certificate.buffer, heap, dynamicType);
2629 ctx->certificate = der; /* takes der over */
2632 else if (type == PRIVATEKEY_TYPE) {
2634 if (ssl->buffers.weOwnKey && ssl->buffers.key.buffer)
2635 XFREE(ssl->buffers.key.buffer, heap, dynamicType);
2636 ssl->buffers.key = der;
2637 ssl->buffers.weOwnKey = 1;
2640 if (ctx->privateKey.buffer)
2641 XFREE(ctx->privateKey.buffer, heap, dynamicType);
2642 ctx->privateKey = der; /* takes der over */
2646 XFREE(der.buffer, heap, dynamicType);
2647 return SSL_BAD_CERTTYPE;
2650 if (type == PRIVATEKEY_TYPE && format != SSL_FILETYPE_RAW) {
2653 /* make sure RSA key can be used */
2655 #ifdef WOLFSSL_SMALL_STACK
2661 #ifdef WOLFSSL_SMALL_STACK
2662 key = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL,
2663 DYNAMIC_TYPE_TMP_BUFFER);
2668 ret = wc_InitRsaKey(key, 0);
2670 if (wc_RsaPrivateKeyDecode(der.buffer, &idx, key, der.length) !=
2673 /* could have DER ECC (or pkcs8 ecc), no easy way to tell */
2674 eccKey = 1; /* so try it out */
2680 (void)rsaKey; /* for no ecc builds */
2686 #ifdef WOLFSSL_SMALL_STACK
2687 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2696 /* make sure ECC key can be used */
2701 if (wc_EccPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) {
2703 return SSL_BAD_FILE;
2708 ctx->haveStaticECC = 1;
2710 ssl->options.haveStaticECC = 1;
2712 #endif /* HAVE_ECC */
2714 else if (type == CERT_TYPE) {
2715 #ifdef WOLFSSL_SMALL_STACK
2716 DecodedCert* cert = NULL;
2718 DecodedCert cert[1];
2721 #ifdef WOLFSSL_SMALL_STACK
2722 cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
2723 DYNAMIC_TYPE_TMP_BUFFER);
2728 WOLFSSL_MSG("Checking cert signature type");
2729 InitDecodedCert(cert, der.buffer, der.length, heap);
2731 if (DecodeToKey(cert, 0) < 0) {
2732 WOLFSSL_MSG("Decode to key failed");
2733 #ifdef WOLFSSL_SMALL_STACK
2734 XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2736 return SSL_BAD_FILE;
2738 switch (cert->signatureOID) {
2740 case CTC_SHA256wECDSA:
2741 case CTC_SHA384wECDSA:
2742 case CTC_SHA512wECDSA:
2743 WOLFSSL_MSG("ECDSA cert signature");
2745 ctx->haveECDSAsig = 1;
2747 ssl->options.haveECDSAsig = 1;
2750 WOLFSSL_MSG("Not ECDSA cert signature");
2756 ctx->pkCurveOID = cert->pkCurveOID;
2758 ssl->pkCurveOID = cert->pkCurveOID;
2761 FreeDecodedCert(cert);
2762 #ifdef WOLFSSL_SMALL_STACK
2763 XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2771 /* CA PEM file for verification, may have multiple/chain certs to process */
2772 static int ProcessChainBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
2773 long sz, int format, int type, WOLFSSL* ssl)
2779 WOLFSSL_MSG("Processing CA PEM file");
2783 ret = ProcessBuffer(ctx, buff + used, sz - used, format, type, ssl,
2786 if (ret == SSL_NO_PEM_HEADER && gotOne) {
2787 WOLFSSL_MSG("We got one good PEM file so stuff at end ok");
2795 WOLFSSL_MSG(" Processed a CA");
2804 /* Verify the ceritficate, SSL_SUCCESS for ok, < 0 for error */
2805 int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
2806 long sz, int format)
2810 #ifdef WOLFSSL_SMALL_STACK
2811 DecodedCert* cert = NULL;
2813 DecodedCert cert[1];
2816 WOLFSSL_ENTER("wolfSSL_CertManagerVerifyBuffer");
2818 #ifdef WOLFSSL_SMALL_STACK
2819 cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
2820 DYNAMIC_TYPE_TMP_BUFFER);
2828 if (format == SSL_FILETYPE_PEM) {
2829 int eccKey = 0; /* not used */
2830 #ifdef WOLFSSL_SMALL_STACK
2831 EncryptedInfo* info = NULL;
2833 EncryptedInfo info[1];
2836 #ifdef WOLFSSL_SMALL_STACK
2837 info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
2838 DYNAMIC_TYPE_TMP_BUFFER);
2840 XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2849 ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, info, &eccKey);
2852 InitDecodedCert(cert, der.buffer, der.length, cm->heap);
2854 #ifdef WOLFSSL_SMALL_STACK
2855 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2859 InitDecodedCert(cert, (byte*)buff, (word32)sz, cm->heap);
2862 ret = ParseCertRelative(cert, CERT_TYPE, 1, cm);
2865 if (ret == 0 && cm->crlEnabled)
2866 ret = CheckCertCRL(cm->crl, cert);
2869 FreeDecodedCert(cert);
2871 XFREE(der.buffer, cm->heap, DYNAMIC_TYPE_CERT);
2872 #ifdef WOLFSSL_SMALL_STACK
2873 XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2876 return ret == 0 ? SSL_SUCCESS : ret;
2880 /* turn on OCSP if off and compiled in, set options */
2881 int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, int options)
2883 int ret = SSL_SUCCESS;
2887 WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSP");
2889 return BAD_FUNC_ARG;
2892 if (cm->ocsp == NULL) {
2893 cm->ocsp = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), cm->heap,
2895 if (cm->ocsp == NULL)
2898 if (InitOCSP(cm->ocsp, cm) != 0) {
2899 WOLFSSL_MSG("Init OCSP failed");
2900 FreeOCSP(cm->ocsp, 1);
2905 cm->ocspEnabled = 1;
2906 if (options & WOLFSSL_OCSP_URL_OVERRIDE)
2907 cm->ocspUseOverrideURL = 1;
2908 if (options & WOLFSSL_OCSP_NO_NONCE)
2909 cm->ocspSendNonce = 0;
2911 cm->ocspSendNonce = 1;
2912 if (options & WOLFSSL_OCSP_CHECKALL)
2913 cm->ocspCheckAll = 1;
2914 #ifndef WOLFSSL_USER_IO
2915 cm->ocspIOCb = EmbedOcspLookup;
2916 cm->ocspRespFreeCb = EmbedOcspRespFree;
2917 #endif /* WOLFSSL_USER_IO */
2919 ret = NOT_COMPILED_IN;
2926 int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm)
2928 WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSP");
2930 return BAD_FUNC_ARG;
2932 cm->ocspEnabled = 0;
2941 /* check CRL if enabled, SSL_SUCCESS */
2942 int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
2945 #ifdef WOLFSSL_SMALL_STACK
2946 DecodedCert* cert = NULL;
2948 DecodedCert cert[1];
2951 WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSP");
2954 return BAD_FUNC_ARG;
2956 if (cm->ocspEnabled == 0)
2959 #ifdef WOLFSSL_SMALL_STACK
2960 cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
2961 DYNAMIC_TYPE_TMP_BUFFER);
2966 InitDecodedCert(cert, der, sz, NULL);
2968 if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, cm)) != 0) {
2969 WOLFSSL_MSG("ParseCert failed");
2971 else if ((ret = CheckCertOCSP(cm->ocsp, cert)) != 0) {
2972 WOLFSSL_MSG("CheckCertOCSP failed");
2975 FreeDecodedCert(cert);
2976 #ifdef WOLFSSL_SMALL_STACK
2977 XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2980 return ret == 0 ? SSL_SUCCESS : ret;
2984 int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER* cm,
2987 WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSPOverrideURL");
2989 return BAD_FUNC_ARG;
2991 XFREE(cm->ocspOverrideURL, cm->heap, 0);
2993 int urlSz = (int)XSTRLEN(url) + 1;
2994 cm->ocspOverrideURL = (char*)XMALLOC(urlSz, cm->heap, 0);
2995 if (cm->ocspOverrideURL != NULL) {
2996 XMEMCPY(cm->ocspOverrideURL, url, urlSz);
3002 cm->ocspOverrideURL = NULL;
3008 int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER* cm,
3009 CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
3011 WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSP_Cb");
3013 return BAD_FUNC_ARG;
3015 cm->ocspIOCb = ioCb;
3016 cm->ocspRespFreeCb = respFreeCb;
3017 cm->ocspIOCtx = ioCbCtx;
3023 int wolfSSL_EnableOCSP(WOLFSSL* ssl, int options)
3025 WOLFSSL_ENTER("wolfSSL_EnableOCSP");
3027 return wolfSSL_CertManagerEnableOCSP(ssl->ctx->cm, options);
3029 return BAD_FUNC_ARG;
3033 int wolfSSL_DisableOCSP(WOLFSSL* ssl)
3035 WOLFSSL_ENTER("wolfSSL_DisableOCSP");
3037 return wolfSSL_CertManagerDisableOCSP(ssl->ctx->cm);
3039 return BAD_FUNC_ARG;
3043 int wolfSSL_SetOCSP_OverrideURL(WOLFSSL* ssl, const char* url)
3045 WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
3047 return wolfSSL_CertManagerSetOCSPOverrideURL(ssl->ctx->cm, url);
3049 return BAD_FUNC_ARG;
3053 int wolfSSL_SetOCSP_Cb(WOLFSSL* ssl,
3054 CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
3056 WOLFSSL_ENTER("wolfSSL_SetOCSP_Cb");
3058 return wolfSSL_CertManagerSetOCSP_Cb(ssl->ctx->cm,
3059 ioCb, respFreeCb, ioCbCtx);
3061 return BAD_FUNC_ARG;
3065 int wolfSSL_CTX_EnableOCSP(WOLFSSL_CTX* ctx, int options)
3067 WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSP");
3069 return wolfSSL_CertManagerEnableOCSP(ctx->cm, options);
3071 return BAD_FUNC_ARG;
3075 int wolfSSL_CTX_DisableOCSP(WOLFSSL_CTX* ctx)
3077 WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSP");
3079 return wolfSSL_CertManagerDisableOCSP(ctx->cm);
3081 return BAD_FUNC_ARG;
3085 int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX* ctx, const char* url)
3087 WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
3089 return wolfSSL_CertManagerSetOCSPOverrideURL(ctx->cm, url);
3091 return BAD_FUNC_ARG;
3095 int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX* ctx,
3096 CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
3098 WOLFSSL_ENTER("wolfSSL_CTX_SetOCSP_Cb");
3100 return wolfSSL_CertManagerSetOCSP_Cb(ctx->cm, ioCb, respFreeCb, ioCbCtx);
3102 return BAD_FUNC_ARG;
3106 #endif /* HAVE_OCSP */
3109 #ifndef NO_FILESYSTEM
3111 #if defined(WOLFSSL_MDK_ARM)
3112 extern FILE * wolfSSL_fopen(const char *name, const char *mode) ;
3113 #define XFOPEN wolfSSL_fopen
3115 #define XFOPEN fopen
3118 /* process a file with name fname into ctx of format and type
3119 userChain specifies a user certificate chain to pass during handshake */
3120 int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type,
3121 WOLFSSL* ssl, int userChain, WOLFSSL_CRL* crl)
3123 #ifdef WOLFSSL_SMALL_STACK
3124 byte staticBuffer[1]; /* force heap usage */
3126 byte staticBuffer[FILE_BUFFER_SIZE];
3128 byte* myBuffer = staticBuffer;
3133 void* heapHint = ctx ? ctx->heap : NULL;
3138 if (fname == NULL) return SSL_BAD_FILE;
3140 file = XFOPEN(fname, "rb");
3141 if (file == XBADFILE) return SSL_BAD_FILE;
3142 XFSEEK(file, 0, XSEEK_END);
3146 if (sz > (long)sizeof(staticBuffer)) {
3147 WOLFSSL_MSG("Getting dynamic buffer");
3148 myBuffer = (byte*)XMALLOC(sz, heapHint, DYNAMIC_TYPE_FILE);
3149 if (myBuffer == NULL) {
3151 return SSL_BAD_FILE;
3157 return SSL_BAD_FILE;
3160 if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
3163 if (type == CA_TYPE && format == SSL_FILETYPE_PEM)
3164 ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl);
3166 else if (type == CRL_TYPE)
3167 ret = BufferLoadCRL(crl, myBuffer, sz, format);
3170 ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL,
3176 XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
3182 /* loads file then loads each file in path, no c_rehash */
3183 int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
3186 int ret = SSL_SUCCESS;
3188 WOLFSSL_ENTER("wolfSSL_CTX_load_verify_locations");
3191 if (ctx == NULL || (file == NULL && path == NULL) )
3195 ret = ProcessFile(ctx, file, SSL_FILETYPE_PEM, CA_TYPE, NULL, 0, NULL);
3197 if (ret == SSL_SUCCESS && path) {
3198 /* try to load each regular file in path */
3199 #ifdef USE_WINDOWS_API
3200 WIN32_FIND_DATAA FindFileData;
3202 #ifdef WOLFSSL_SMALL_STACK
3205 char name[MAX_FILENAME_SZ];
3208 #ifdef WOLFSSL_SMALL_STACK
3209 name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3214 XMEMSET(name, 0, MAX_FILENAME_SZ);
3215 XSTRNCPY(name, path, MAX_FILENAME_SZ - 4);
3216 XSTRNCAT(name, "\\*", 3);
3218 hFind = FindFirstFileA(name, &FindFileData);
3219 if (hFind == INVALID_HANDLE_VALUE) {
3220 WOLFSSL_MSG("FindFirstFile for path verify locations failed");
3221 #ifdef WOLFSSL_SMALL_STACK
3222 XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3224 return BAD_PATH_ERROR;
3228 if (FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
3229 XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 3);
3230 XSTRNCAT(name, "\\", 2);
3231 XSTRNCAT(name, FindFileData.cFileName, MAX_FILENAME_SZ/2);
3233 ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0,
3236 } while (ret == SSL_SUCCESS && FindNextFileA(hFind, &FindFileData));
3238 #ifdef WOLFSSL_SMALL_STACK
3239 XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3243 #elif !defined(NO_WOLFSSL_DIR)
3244 struct dirent* entry;
3245 DIR* dir = opendir(path);
3246 #ifdef WOLFSSL_SMALL_STACK
3249 char name[MAX_FILENAME_SZ];
3253 WOLFSSL_MSG("opendir path verify locations failed");
3254 return BAD_PATH_ERROR;
3257 #ifdef WOLFSSL_SMALL_STACK
3258 name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3263 while ( ret == SSL_SUCCESS && (entry = readdir(dir)) != NULL) {
3266 XMEMSET(name, 0, MAX_FILENAME_SZ);
3267 XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
3268 XSTRNCAT(name, "/", 1);
3269 XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
3271 if (stat(name, &s) != 0) {
3272 WOLFSSL_MSG("stat on name failed");
3273 ret = BAD_PATH_ERROR;
3274 } else if (s.st_mode & S_IFREG)
3275 ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0,
3279 #ifdef WOLFSSL_SMALL_STACK
3280 XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3291 /* Verify the ceritficate, SSL_SUCCESS for ok, < 0 for error */
3292 int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* fname,
3295 int ret = SSL_FATAL_ERROR;
3296 #ifdef WOLFSSL_SMALL_STACK
3297 byte staticBuffer[1]; /* force heap usage */
3299 byte staticBuffer[FILE_BUFFER_SIZE];
3301 byte* myBuffer = staticBuffer;
3304 XFILE file = XFOPEN(fname, "rb");
3306 WOLFSSL_ENTER("wolfSSL_CertManagerVerify");
3308 if (file == XBADFILE) return SSL_BAD_FILE;
3309 XFSEEK(file, 0, XSEEK_END);
3313 if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
3314 WOLFSSL_MSG("CertManagerVerify file bad size");
3316 return SSL_BAD_FILE;
3319 if (sz > (long)sizeof(staticBuffer)) {
3320 WOLFSSL_MSG("Getting dynamic buffer");
3321 myBuffer = (byte*) XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE);
3322 if (myBuffer == NULL) {
3324 return SSL_BAD_FILE;
3329 if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
3332 ret = wolfSSL_CertManagerVerifyBuffer(cm, myBuffer, sz, format);
3336 XFREE(myBuffer, cm->heap, DYNAMIC_TYPE_FILE);
3342 static INLINE WOLFSSL_METHOD* cm_pick_method(void)
3344 #ifndef NO_WOLFSSL_CLIENT
3346 return wolfTLSv1_2_client_method();
3348 return wolfSSLv3_client_method();
3350 #elif !defined(NO_WOLFSSL_SERVER)
3352 return wolfTLSv1_2_server_method();
3354 return wolfSSLv3_server_method();
3362 /* like load verify locations, 1 for success, < 0 for error */
3363 int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* file,
3366 int ret = SSL_FATAL_ERROR;
3369 WOLFSSL_ENTER("wolfSSL_CertManagerLoadCA");
3372 WOLFSSL_MSG("No CertManager error");
3375 tmp = wolfSSL_CTX_new(cm_pick_method());
3378 WOLFSSL_MSG("CTX new failed");
3383 wolfSSL_CertManagerFree(tmp->cm);
3386 ret = wolfSSL_CTX_load_verify_locations(tmp, file, path);
3388 /* don't loose our good one */
3390 wolfSSL_CTX_free(tmp);
3397 /* turn on CRL if off and compiled in, set options */
3398 int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, int options)
3400 int ret = SSL_SUCCESS;
3404 WOLFSSL_ENTER("wolfSSL_CertManagerEnableCRL");
3406 return BAD_FUNC_ARG;
3409 if (cm->crl == NULL) {
3410 cm->crl = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), cm->heap,
3412 if (cm->crl == NULL)
3415 if (InitCRL(cm->crl, cm) != 0) {
3416 WOLFSSL_MSG("Init CRL failed");
3417 FreeCRL(cm->crl, 1);
3423 if (options & WOLFSSL_CRL_CHECKALL)
3424 cm->crlCheckAll = 1;
3426 ret = NOT_COMPILED_IN;
3433 int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER* cm)
3435 WOLFSSL_ENTER("wolfSSL_CertManagerDisableCRL");
3437 return BAD_FUNC_ARG;
3445 int wolfSSL_CTX_check_private_key(WOLFSSL_CTX* ctx)
3447 /* TODO: check private against public for RSA match */
3449 WOLFSSL_ENTER("SSL_CTX_check_private_key");
3457 /* check CRL if enabled, SSL_SUCCESS */
3458 int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
3461 #ifdef WOLFSSL_SMALL_STACK
3462 DecodedCert* cert = NULL;
3464 DecodedCert cert[1];
3467 WOLFSSL_ENTER("wolfSSL_CertManagerCheckCRL");
3470 return BAD_FUNC_ARG;
3472 if (cm->crlEnabled == 0)
3475 #ifdef WOLFSSL_SMALL_STACK
3476 cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
3477 DYNAMIC_TYPE_TMP_BUFFER);
3482 InitDecodedCert(cert, der, sz, NULL);
3484 if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, cm)) != 0) {
3485 WOLFSSL_MSG("ParseCert failed");
3487 else if ((ret = CheckCertCRL(cm->crl, cert)) != 0) {
3488 WOLFSSL_MSG("CheckCertCRL failed");
3491 FreeDecodedCert(cert);
3492 #ifdef WOLFSSL_SMALL_STACK
3493 XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3496 return ret == 0 ? SSL_SUCCESS : ret;
3500 int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, CbMissingCRL cb)
3502 WOLFSSL_ENTER("wolfSSL_CertManagerSetCRL_Cb");
3504 return BAD_FUNC_ARG;
3506 cm->cbMissingCRL = cb;
3512 int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER* cm, const char* path,
3513 int type, int monitor)
3515 WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRL");
3517 return BAD_FUNC_ARG;
3519 if (cm->crl == NULL) {
3520 if (wolfSSL_CertManagerEnableCRL(cm, 0) != SSL_SUCCESS) {
3521 WOLFSSL_MSG("Enable CRL failed");
3522 return SSL_FATAL_ERROR;
3526 return LoadCRL(cm->crl, path, type, monitor);
3530 int wolfSSL_EnableCRL(WOLFSSL* ssl, int options)
3532 WOLFSSL_ENTER("wolfSSL_EnableCRL");
3534 return wolfSSL_CertManagerEnableCRL(ssl->ctx->cm, options);
3536 return BAD_FUNC_ARG;
3540 int wolfSSL_DisableCRL(WOLFSSL* ssl)
3542 WOLFSSL_ENTER("wolfSSL_DisableCRL");
3544 return wolfSSL_CertManagerDisableCRL(ssl->ctx->cm);
3546 return BAD_FUNC_ARG;
3550 int wolfSSL_LoadCRL(WOLFSSL* ssl, const char* path, int type, int monitor)
3552 WOLFSSL_ENTER("wolfSSL_LoadCRL");
3554 return wolfSSL_CertManagerLoadCRL(ssl->ctx->cm, path, type, monitor);
3556 return BAD_FUNC_ARG;
3560 int wolfSSL_SetCRL_Cb(WOLFSSL* ssl, CbMissingCRL cb)
3562 WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
3564 return wolfSSL_CertManagerSetCRL_Cb(ssl->ctx->cm, cb);
3566 return BAD_FUNC_ARG;
3570 int wolfSSL_CTX_EnableCRL(WOLFSSL_CTX* ctx, int options)
3572 WOLFSSL_ENTER("wolfSSL_CTX_EnableCRL");
3574 return wolfSSL_CertManagerEnableCRL(ctx->cm, options);
3576 return BAD_FUNC_ARG;
3580 int wolfSSL_CTX_DisableCRL(WOLFSSL_CTX* ctx)
3582 WOLFSSL_ENTER("wolfSSL_CTX_DisableCRL");
3584 return wolfSSL_CertManagerDisableCRL(ctx->cm);
3586 return BAD_FUNC_ARG;
3590 int wolfSSL_CTX_LoadCRL(WOLFSSL_CTX* ctx, const char* path, int type, int monitor)
3592 WOLFSSL_ENTER("wolfSSL_CTX_LoadCRL");
3594 return wolfSSL_CertManagerLoadCRL(ctx->cm, path, type, monitor);
3596 return BAD_FUNC_ARG;
3600 int wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX* ctx, CbMissingCRL cb)
3602 WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_Cb");
3604 return wolfSSL_CertManagerSetCRL_Cb(ctx->cm, cb);
3606 return BAD_FUNC_ARG;
3610 #endif /* HAVE_CRL */
3613 #ifdef WOLFSSL_DER_LOAD
3615 /* Add format parameter to allow DER load of CA files */
3616 int wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
3619 WOLFSSL_ENTER("wolfSSL_CTX_der_load_verify_locations");
3620 if (ctx == NULL || file == NULL)
3623 if (ProcessFile(ctx, file, format, CA_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
3629 #endif /* WOLFSSL_DER_LOAD */
3632 #ifdef WOLFSSL_CERT_GEN
3634 /* load pem cert from file into der buffer, return der size or error */
3635 int wolfSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
3637 #ifdef WOLFSSL_SMALL_STACK
3638 EncryptedInfo* info = NULL;
3639 byte staticBuffer[1]; /* force XMALLOC */
3641 EncryptedInfo info[1];
3642 byte staticBuffer[FILE_BUFFER_SIZE];
3644 byte* fileBuf = staticBuffer;
3649 XFILE file = XFOPEN(fileName, "rb");
3652 WOLFSSL_ENTER("wolfSSL_PemCertToDer");
3654 if (file == XBADFILE)
3657 XFSEEK(file, 0, XSEEK_END);
3664 else if (sz > (long)sizeof(staticBuffer)) {
3665 fileBuf = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
3666 if (fileBuf == NULL)
3672 converted.buffer = 0;
3675 if ( (ret = (int)XFREAD(fileBuf, sz, 1, file)) < 0)
3678 #ifdef WOLFSSL_SMALL_STACK
3679 info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
3680 DYNAMIC_TYPE_TMP_BUFFER);
3686 ret = PemToDer(fileBuf, sz, CA_TYPE, &converted, 0, info,
3688 #ifdef WOLFSSL_SMALL_STACK
3689 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3695 if (converted.length < (word32)derSz) {
3696 XMEMCPY(derBuf, converted.buffer, converted.length);
3697 ret = converted.length;
3703 XFREE(converted.buffer, 0, DYNAMIC_TYPE_CA);
3708 XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE);
3714 #endif /* WOLFSSL_CERT_GEN */
3717 int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
3720 WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_file");
3721 if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
3728 int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX* ctx, const char* file,int format)
3730 WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_file");
3731 if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL)
3739 /* get cert chaining depth using ssl struct */
3740 long wolfSSL_get_verify_depth(WOLFSSL* ssl)
3743 return BAD_FUNC_ARG;
3745 return MAX_CHAIN_DEPTH;
3749 /* get cert chaining depth using ctx struct */
3750 long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx)
3753 return BAD_FUNC_ARG;
3755 return MAX_CHAIN_DEPTH;
3759 int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX* ctx, const char* file)
3761 /* procces up to MAX_CHAIN_DEPTH plus subject cert */
3762 WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file");
3763 if (ProcessFile(ctx, file, SSL_FILETYPE_PEM,CERT_TYPE,NULL,1, NULL)
3773 /* server wrapper for ctx or ssl Diffie-Hellman parameters */
3774 static int wolfSSL_SetTmpDH_buffer_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
3775 const unsigned char* buf, long sz, int format)
3780 word32 pSz = MAX_DH_SIZE;
3781 word32 gSz = MAX_DH_SIZE;
3782 #ifdef WOLFSSL_SMALL_STACK
3786 byte p[MAX_DH_SIZE];
3787 byte g[MAX_DH_SIZE];
3790 der.buffer = (byte*)buf;
3791 der.length = (word32)sz;
3793 #ifdef WOLFSSL_SMALL_STACK
3794 p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3795 g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3797 if (p == NULL || g == NULL) {
3798 XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3799 XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3804 if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM)
3805 ret = SSL_BAD_FILETYPE;
3807 if (format == SSL_FILETYPE_PEM) {
3809 ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap, NULL,NULL);
3814 if (wc_DhParamsLoad(der.buffer, der.length, p, &pSz, g, &gSz) < 0)
3815 ret = SSL_BAD_FILETYPE;
3817 ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
3819 ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
3824 XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
3826 #ifdef WOLFSSL_SMALL_STACK
3827 XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3828 XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3835 /* server Diffie-Hellman parameters, SSL_SUCCESS on ok */
3836 int wolfSSL_SetTmpDH_buffer(WOLFSSL* ssl, const unsigned char* buf, long sz,
3839 return wolfSSL_SetTmpDH_buffer_wrapper(ssl->ctx, ssl, buf, sz, format);
3843 /* server ctx Diffie-Hellman parameters, SSL_SUCCESS on ok */
3844 int wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX* ctx, const unsigned char* buf,
3845 long sz, int format)
3847 return wolfSSL_SetTmpDH_buffer_wrapper(ctx, NULL, buf, sz, format);
3851 /* server Diffie-Hellman parameters */
3852 static int wolfSSL_SetTmpDH_file_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
3853 const char* fname, int format)
3855 #ifdef WOLFSSL_SMALL_STACK
3856 byte staticBuffer[1]; /* force heap usage */
3858 byte staticBuffer[FILE_BUFFER_SIZE];
3860 byte* myBuffer = staticBuffer;
3864 XFILE file = XFOPEN(fname, "rb");
3866 if (file == XBADFILE) return SSL_BAD_FILE;
3867 XFSEEK(file, 0, XSEEK_END);
3871 if (sz > (long)sizeof(staticBuffer)) {
3872 WOLFSSL_MSG("Getting dynamic buffer");
3873 myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
3874 if (myBuffer == NULL) {
3876 return SSL_BAD_FILE;
3882 return SSL_BAD_FILE;
3885 if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
3889 ret = wolfSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format);
3891 ret = wolfSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format);
3896 XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
3901 /* server Diffie-Hellman parameters */
3902 int wolfSSL_SetTmpDH_file(WOLFSSL* ssl, const char* fname, int format)
3904 return wolfSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format);
3908 /* server Diffie-Hellman parameters */
3909 int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format)
3911 return wolfSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format);
3915 int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz)
3917 if (ctx == NULL || keySz > 16000 || keySz % 8 != 0)
3918 return BAD_FUNC_ARG;
3920 ctx->minDhKeySz = keySz / 8;
3925 int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz)
3927 if (ssl == NULL || keySz > 16000 || keySz % 8 != 0)
3928 return BAD_FUNC_ARG;
3930 ssl->options.minDhKeySz = keySz / 8;
3935 int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl)
3938 return BAD_FUNC_ARG;
3940 return (ssl->options.dhKeySz * 8);
3947 #ifdef OPENSSL_EXTRA
3948 /* put SSL type in extra for now, not very common */
3950 int wolfSSL_use_certificate_file(WOLFSSL* ssl, const char* file, int format)
3952 WOLFSSL_ENTER("wolfSSL_use_certificate_file");
3953 if (ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 0, NULL)
3961 int wolfSSL_use_PrivateKey_file(WOLFSSL* ssl, const char* file, int format)
3963 WOLFSSL_ENTER("wolfSSL_use_PrivateKey_file");
3964 if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0, NULL)
3972 int wolfSSL_use_certificate_chain_file(WOLFSSL* ssl, const char* file)
3974 /* procces up to MAX_CHAIN_DEPTH plus subject cert */
3975 WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file");
3976 if (ProcessFile(ssl->ctx, file, SSL_FILETYPE_PEM, CERT_TYPE, ssl, 1, NULL)
3987 /* Set Temp CTX EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
3988 int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX* ctx, word16 sz)
3990 if (ctx == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
3991 return BAD_FUNC_ARG;
3993 ctx->eccTempKeySz = sz;
3999 /* Set Temp SSL EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
4000 int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL* ssl, word16 sz)
4002 if (ssl == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
4003 return BAD_FUNC_ARG;
4005 ssl->eccTempKeySz = sz;
4010 #endif /* HAVE_ECC */
4015 int wolfSSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX* ctx,const char* file,
4018 WOLFSSL_ENTER("SSL_CTX_use_RSAPrivateKey_file");
4020 return wolfSSL_CTX_use_PrivateKey_file(ctx, file, format);
4024 int wolfSSL_use_RSAPrivateKey_file(WOLFSSL* ssl, const char* file, int format)
4026 WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_file");
4028 return wolfSSL_use_PrivateKey_file(ssl, file, format);
4031 #endif /* OPENSSL_EXTRA */
4035 int wolfSSL_CTX_use_NTRUPrivateKey_file(WOLFSSL_CTX* ctx, const char* file)
4037 WOLFSSL_ENTER("wolfSSL_CTX_use_NTRUPrivateKey_file");
4041 if (ProcessFile(ctx, file, SSL_FILETYPE_RAW, PRIVATEKEY_TYPE, NULL, 0, NULL)
4050 #endif /* HAVE_NTRU */
4053 #endif /* NO_FILESYSTEM */
4056 void wolfSSL_CTX_set_verify(WOLFSSL_CTX* ctx, int mode, VerifyCallback vc)
4058 WOLFSSL_ENTER("wolfSSL_CTX_set_verify");
4059 if (mode & SSL_VERIFY_PEER) {
4060 ctx->verifyPeer = 1;
4061 ctx->verifyNone = 0; /* in case perviously set */
4064 if (mode == SSL_VERIFY_NONE) {
4065 ctx->verifyNone = 1;
4066 ctx->verifyPeer = 0; /* in case previously set */
4069 if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
4070 ctx->failNoCert = 1;
4072 ctx->verifyCallback = vc;
4076 void wolfSSL_set_verify(WOLFSSL* ssl, int mode, VerifyCallback vc)
4078 WOLFSSL_ENTER("wolfSSL_set_verify");
4079 if (mode & SSL_VERIFY_PEER) {
4080 ssl->options.verifyPeer = 1;
4081 ssl->options.verifyNone = 0; /* in case perviously set */
4084 if (mode == SSL_VERIFY_NONE) {
4085 ssl->options.verifyNone = 1;
4086 ssl->options.verifyPeer = 0; /* in case previously set */
4089 if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
4090 ssl->options.failNoCert = 1;
4092 ssl->verifyCallback = vc;
4096 /* store user ctx for verify callback */
4097 void wolfSSL_SetCertCbCtx(WOLFSSL* ssl, void* ctx)
4099 WOLFSSL_ENTER("wolfSSL_SetCertCbCtx");
4101 ssl->verifyCbCtx = ctx;
4105 /* store context CA Cache addition callback */
4106 void wolfSSL_CTX_SetCACb(WOLFSSL_CTX* ctx, CallbackCACache cb)
4109 ctx->cm->caCacheCallback = cb;
4113 #if defined(PERSIST_CERT_CACHE)
4115 #if !defined(NO_FILESYSTEM)
4117 /* Persist cert cache to file */
4118 int wolfSSL_CTX_save_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
4120 WOLFSSL_ENTER("wolfSSL_CTX_save_cert_cache");
4122 if (ctx == NULL || fname == NULL)
4123 return BAD_FUNC_ARG;
4125 return CM_SaveCertCache(ctx->cm, fname);
4129 /* Persist cert cache from file */
4130 int wolfSSL_CTX_restore_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
4132 WOLFSSL_ENTER("wolfSSL_CTX_restore_cert_cache");
4134 if (ctx == NULL || fname == NULL)
4135 return BAD_FUNC_ARG;
4137 return CM_RestoreCertCache(ctx->cm, fname);
4140 #endif /* NO_FILESYSTEM */
4142 /* Persist cert cache to memory */
4143 int wolfSSL_CTX_memsave_cert_cache(WOLFSSL_CTX* ctx, void* mem, int sz, int* used)
4145 WOLFSSL_ENTER("wolfSSL_CTX_memsave_cert_cache");
4147 if (ctx == NULL || mem == NULL || used == NULL || sz <= 0)
4148 return BAD_FUNC_ARG;
4150 return CM_MemSaveCertCache(ctx->cm, mem, sz, used);
4154 /* Restore cert cache from memory */
4155 int wolfSSL_CTX_memrestore_cert_cache(WOLFSSL_CTX* ctx, const void* mem, int sz)
4157 WOLFSSL_ENTER("wolfSSL_CTX_memrestore_cert_cache");
4159 if (ctx == NULL || mem == NULL || sz <= 0)
4160 return BAD_FUNC_ARG;
4162 return CM_MemRestoreCertCache(ctx->cm, mem, sz);
4166 /* get how big the the cert cache save buffer needs to be */
4167 int wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX* ctx)
4169 WOLFSSL_ENTER("wolfSSL_CTX_get_cert_cache_memsize");
4172 return BAD_FUNC_ARG;
4174 return CM_GetCertCacheMemSize(ctx->cm);
4177 #endif /* PERSISTE_CERT_CACHE */
4178 #endif /* !NO_CERTS */
4181 #ifndef NO_SESSION_CACHE
4183 WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl)
4185 WOLFSSL_ENTER("SSL_get_session");
4187 return GetSession(ssl, 0);
4193 int wolfSSL_set_session(WOLFSSL* ssl, WOLFSSL_SESSION* session)
4195 WOLFSSL_ENTER("SSL_set_session");
4197 return SetSession(ssl, session);
4203 #ifndef NO_CLIENT_CACHE
4205 /* Associate client session with serverID, find existing or store for saving
4206 if newSession flag on, don't reuse existing session
4207 SSL_SUCCESS on ok */
4208 int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
4210 WOLFSSL_SESSION* session = NULL;
4212 WOLFSSL_ENTER("wolfSSL_SetServerID");
4214 if (ssl == NULL || id == NULL || len <= 0)
4215 return BAD_FUNC_ARG;
4217 if (newSession == 0) {
4218 session = GetSessionClient(ssl, id, len);
4220 if (SetSession(ssl, session) != SSL_SUCCESS) {
4221 WOLFSSL_MSG("SetSession failed");
4227 if (session == NULL) {
4228 WOLFSSL_MSG("Valid ServerID not cached already");
4230 ssl->session.idLen = (word16)min(SERVER_ID_LEN, (word32)len);
4231 XMEMCPY(ssl->session.serverID, id, ssl->session.idLen);
4237 #endif /* NO_CLIENT_CACHE */
4239 #if defined(PERSIST_SESSION_CACHE)
4241 /* for persistance, if changes to layout need to increment and modify
4242 save_session_cache() and restore_session_cache and memory versions too */
4243 #define WOLFSSL_CACHE_VERSION 2
4245 /* Session Cache Header information */
4247 int version; /* cache layout version id */
4248 int rows; /* session rows */
4249 int columns; /* session columns */
4250 int sessionSz; /* sizeof WOLFSSL_SESSION */
4253 /* current persistence layout is:
4259 update WOLFSSL_CACHE_VERSION if change layout for the following
4260 PERSISTENT_SESSION_CACHE functions
4264 /* get how big the the session cache save buffer needs to be */
4265 int wolfSSL_get_session_cache_memsize(void)
4267 int sz = (int)(sizeof(SessionCache) + sizeof(cache_header_t));
4269 #ifndef NO_CLIENT_CACHE
4270 sz += (int)(sizeof(ClientCache));
4277 /* Persist session cache to memory */
4278 int wolfSSL_memsave_session_cache(void* mem, int sz)
4281 cache_header_t cache_header;
4282 SessionRow* row = (SessionRow*)((byte*)mem + sizeof(cache_header));
4283 #ifndef NO_CLIENT_CACHE
4287 WOLFSSL_ENTER("wolfSSL_memsave_session_cache");
4289 if (sz < wolfSSL_get_session_cache_memsize()) {
4290 WOLFSSL_MSG("Memory buffer too small");
4294 cache_header.version = WOLFSSL_CACHE_VERSION;
4295 cache_header.rows = SESSION_ROWS;
4296 cache_header.columns = SESSIONS_PER_ROW;
4297 cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
4298 XMEMCPY(mem, &cache_header, sizeof(cache_header));
4300 if (LockMutex(&session_mutex) != 0) {
4301 WOLFSSL_MSG("Session cache mutex lock failed");
4305 for (i = 0; i < cache_header.rows; ++i)
4306 XMEMCPY(row++, SessionCache + i, sizeof(SessionRow));
4308 #ifndef NO_CLIENT_CACHE
4309 clRow = (ClientRow*)row;
4310 for (i = 0; i < cache_header.rows; ++i)
4311 XMEMCPY(clRow++, ClientCache + i, sizeof(ClientRow));
4314 UnLockMutex(&session_mutex);
4316 WOLFSSL_LEAVE("wolfSSL_memsave_session_cache", SSL_SUCCESS);
4322 /* Restore the persistant session cache from memory */
4323 int wolfSSL_memrestore_session_cache(const void* mem, int sz)
4326 cache_header_t cache_header;
4327 SessionRow* row = (SessionRow*)((byte*)mem + sizeof(cache_header));
4328 #ifndef NO_CLIENT_CACHE
4332 WOLFSSL_ENTER("wolfSSL_memrestore_session_cache");
4334 if (sz < wolfSSL_get_session_cache_memsize()) {
4335 WOLFSSL_MSG("Memory buffer too small");
4339 XMEMCPY(&cache_header, mem, sizeof(cache_header));
4340 if (cache_header.version != WOLFSSL_CACHE_VERSION ||
4341 cache_header.rows != SESSION_ROWS ||
4342 cache_header.columns != SESSIONS_PER_ROW ||
4343 cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
4345 WOLFSSL_MSG("Session cache header match failed");
4346 return CACHE_MATCH_ERROR;
4349 if (LockMutex(&session_mutex) != 0) {
4350 WOLFSSL_MSG("Session cache mutex lock failed");
4354 for (i = 0; i < cache_header.rows; ++i)
4355 XMEMCPY(SessionCache + i, row++, sizeof(SessionRow));
4357 #ifndef NO_CLIENT_CACHE
4358 clRow = (ClientRow*)row;
4359 for (i = 0; i < cache_header.rows; ++i)
4360 XMEMCPY(ClientCache + i, clRow++, sizeof(ClientRow));
4363 UnLockMutex(&session_mutex);
4365 WOLFSSL_LEAVE("wolfSSL_memrestore_session_cache", SSL_SUCCESS);
4370 #if !defined(NO_FILESYSTEM)
4372 /* Persist session cache to file */
4373 /* doesn't use memsave because of additional memory use */
4374 int wolfSSL_save_session_cache(const char *fname)
4378 int rc = SSL_SUCCESS;
4380 cache_header_t cache_header;
4382 WOLFSSL_ENTER("wolfSSL_save_session_cache");
4384 file = XFOPEN(fname, "w+b");
4385 if (file == XBADFILE) {
4386 WOLFSSL_MSG("Couldn't open session cache save file");
4387 return SSL_BAD_FILE;
4389 cache_header.version = WOLFSSL_CACHE_VERSION;
4390 cache_header.rows = SESSION_ROWS;
4391 cache_header.columns = SESSIONS_PER_ROW;
4392 cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
4395 ret = (int)XFWRITE(&cache_header, sizeof cache_header, 1, file);
4397 WOLFSSL_MSG("Session cache header file write failed");
4399 return FWRITE_ERROR;
4402 if (LockMutex(&session_mutex) != 0) {
4403 WOLFSSL_MSG("Session cache mutex lock failed");
4409 for (i = 0; i < cache_header.rows; ++i) {
4410 ret = (int)XFWRITE(SessionCache + i, sizeof(SessionRow), 1, file);
4412 WOLFSSL_MSG("Session cache member file write failed");
4418 #ifndef NO_CLIENT_CACHE
4420 for (i = 0; i < cache_header.rows; ++i) {
4421 ret = (int)XFWRITE(ClientCache + i, sizeof(ClientRow), 1, file);
4423 WOLFSSL_MSG("Client cache member file write failed");
4428 #endif /* NO_CLIENT_CACHE */
4430 UnLockMutex(&session_mutex);
4433 WOLFSSL_LEAVE("wolfSSL_save_session_cache", rc);
4439 /* Restore the persistant session cache from file */
4440 /* doesn't use memstore because of additional memory use */
4441 int wolfSSL_restore_session_cache(const char *fname)
4444 int rc = SSL_SUCCESS;
4447 cache_header_t cache_header;
4449 WOLFSSL_ENTER("wolfSSL_restore_session_cache");
4451 file = XFOPEN(fname, "rb");
4452 if (file == XBADFILE) {
4453 WOLFSSL_MSG("Couldn't open session cache save file");
4454 return SSL_BAD_FILE;
4457 ret = (int)XFREAD(&cache_header, sizeof cache_header, 1, file);
4459 WOLFSSL_MSG("Session cache header file read failed");
4463 if (cache_header.version != WOLFSSL_CACHE_VERSION ||
4464 cache_header.rows != SESSION_ROWS ||
4465 cache_header.columns != SESSIONS_PER_ROW ||
4466 cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
4468 WOLFSSL_MSG("Session cache header match failed");
4470 return CACHE_MATCH_ERROR;
4473 if (LockMutex(&session_mutex) != 0) {
4474 WOLFSSL_MSG("Session cache mutex lock failed");
4480 for (i = 0; i < cache_header.rows; ++i) {
4481 ret = (int)XFREAD(SessionCache + i, sizeof(SessionRow), 1, file);
4483 WOLFSSL_MSG("Session cache member file read failed");
4484 XMEMSET(SessionCache, 0, sizeof SessionCache);
4490 #ifndef NO_CLIENT_CACHE
4492 for (i = 0; i < cache_header.rows; ++i) {
4493 ret = (int)XFREAD(ClientCache + i, sizeof(ClientRow), 1, file);
4495 WOLFSSL_MSG("Client cache member file read failed");
4496 XMEMSET(ClientCache, 0, sizeof ClientCache);
4502 #endif /* NO_CLIENT_CACHE */
4504 UnLockMutex(&session_mutex);
4507 WOLFSSL_LEAVE("wolfSSL_restore_session_cache", rc);
4512 #endif /* !NO_FILESYSTEM */
4513 #endif /* PERSIST_SESSION_CACHE */
4514 #endif /* NO_SESSION_CACHE */
4517 void wolfSSL_load_error_strings(void) /* compatibility only */
4521 int wolfSSL_library_init(void)
4523 WOLFSSL_ENTER("SSL_library_init");
4524 if (wolfSSL_Init() == SSL_SUCCESS)
4527 return SSL_FATAL_ERROR;
4531 #ifdef HAVE_SECRET_CALLBACK
4533 int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx)
4535 WOLFSSL_ENTER("wolfSSL_set_session_secret_cb");
4537 return SSL_FATAL_ERROR;
4539 ssl->sessionSecretCb = cb;
4540 ssl->sessionSecretCtx = ctx;
4541 /* If using a pre-set key, assume session resumption. */
4542 ssl->session.sessionIDSz = 0;
4543 ssl->options.resuming = 1;
4551 #ifndef NO_SESSION_CACHE
4553 /* on by default if built in but allow user to turn off */
4554 long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX* ctx, long mode)
4556 WOLFSSL_ENTER("SSL_CTX_set_session_cache_mode");
4557 if (mode == SSL_SESS_CACHE_OFF)
4558 ctx->sessionCacheOff = 1;
4560 if (mode == SSL_SESS_CACHE_NO_AUTO_CLEAR)
4561 ctx->sessionCacheFlushOff = 1;
4566 #endif /* NO_SESSION_CACHE */
4569 #if !defined(NO_CERTS)
4570 #if defined(PERSIST_CERT_CACHE)
4573 #define WOLFSSL_CACHE_CERT_VERSION 1
4576 int version; /* cache cert layout version id */
4577 int rows; /* hash table rows, CA_TABLE_SIZE */
4578 int columns[CA_TABLE_SIZE]; /* columns per row on list */
4579 int signerSz; /* sizeof Signer object */
4582 /* current cert persistance layout is:
4587 update WOLFSSL_CERT_CACHE_VERSION if change layout for the following
4588 PERSIST_CERT_CACHE functions
4592 /* Return memory needed to persist this signer, have lock */
4593 static INLINE int GetSignerMemory(Signer* signer)
4595 int sz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID)
4596 + sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
4598 #if !defined(NO_SKID)
4599 sz += (int)sizeof(signer->subjectKeyIdHash);
4602 /* add dynamic bytes needed */
4603 sz += signer->pubKeySize;
4604 sz += signer->nameLen;
4610 /* Return memory needed to persist this row, have lock */
4611 static INLINE int GetCertCacheRowMemory(Signer* row)
4616 sz += GetSignerMemory(row);
4624 /* get the size of persist cert cache, have lock */
4625 static INLINE int GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
4630 sz = sizeof(CertCacheHeader);
4632 for (i = 0; i < CA_TABLE_SIZE; i++)
4633 sz += GetCertCacheRowMemory(cm->caTable[i]);
4639 /* Store cert cache header columns with number of items per list, have lock */
4640 static INLINE void SetCertHeaderColumns(WOLFSSL_CERT_MANAGER* cm, int* columns)
4645 for (i = 0; i < CA_TABLE_SIZE; i++) {
4647 row = cm->caTable[i];
4658 /* Restore whole cert row from memory, have lock, return bytes consumed,
4659 < 0 on error, have lock */
4660 static INLINE int RestoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current,
4661 int row, int listSz, const byte* end)
4666 WOLFSSL_MSG("Row header corrupted, negative value");
4672 byte* start = current + idx; /* for end checks on this signer */
4673 int minSz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) +
4674 sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
4676 minSz += (int)sizeof(signer->subjectKeyIdHash);
4679 if (start + minSz > end) {
4680 WOLFSSL_MSG("Would overread restore buffer");
4683 signer = MakeSigner(cm->heap);
4688 XMEMCPY(&signer->pubKeySize, current + idx, sizeof(signer->pubKeySize));
4689 idx += (int)sizeof(signer->pubKeySize);
4692 XMEMCPY(&signer->keyOID, current + idx, sizeof(signer->keyOID));
4693 idx += (int)sizeof(signer->keyOID);
4696 if (start + minSz + signer->pubKeySize > end) {
4697 WOLFSSL_MSG("Would overread restore buffer");
4698 FreeSigner(signer, cm->heap);
4701 signer->publicKey = (byte*)XMALLOC(signer->pubKeySize, cm->heap,
4703 if (signer->publicKey == NULL) {
4704 FreeSigner(signer, cm->heap);
4708 XMEMCPY(signer->publicKey, current + idx, signer->pubKeySize);
4709 idx += signer->pubKeySize;
4712 XMEMCPY(&signer->nameLen, current + idx, sizeof(signer->nameLen));
4713 idx += (int)sizeof(signer->nameLen);
4716 if (start + minSz + signer->pubKeySize + signer->nameLen > end) {
4717 WOLFSSL_MSG("Would overread restore buffer");
4718 FreeSigner(signer, cm->heap);
4721 signer->name = (char*)XMALLOC(signer->nameLen, cm->heap,
4722 DYNAMIC_TYPE_SUBJECT_CN);
4723 if (signer->name == NULL) {
4724 FreeSigner(signer, cm->heap);
4728 XMEMCPY(signer->name, current + idx, signer->nameLen);
4729 idx += signer->nameLen;
4731 /* subjectNameHash */
4732 XMEMCPY(signer->subjectNameHash, current + idx, SIGNER_DIGEST_SIZE);
4733 idx += SIGNER_DIGEST_SIZE;
4736 /* subjectKeyIdHash */
4737 XMEMCPY(signer->subjectKeyIdHash, current + idx,SIGNER_DIGEST_SIZE);
4738 idx += SIGNER_DIGEST_SIZE;
4741 signer->next = cm->caTable[row];
4742 cm->caTable[row] = signer;
4751 /* Store whole cert row into memory, have lock, return bytes added */
4752 static INLINE int StoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current, int row)
4755 Signer* list = cm->caTable[row];
4758 XMEMCPY(current + added, &list->pubKeySize, sizeof(list->pubKeySize));
4759 added += (int)sizeof(list->pubKeySize);
4761 XMEMCPY(current + added, &list->keyOID, sizeof(list->keyOID));
4762 added += (int)sizeof(list->keyOID);
4764 XMEMCPY(current + added, list->publicKey, list->pubKeySize);
4765 added += list->pubKeySize;
4767 XMEMCPY(current + added, &list->nameLen, sizeof(list->nameLen));
4768 added += (int)sizeof(list->nameLen);
4770 XMEMCPY(current + added, list->name, list->nameLen);
4771 added += list->nameLen;
4773 XMEMCPY(current + added, list->subjectNameHash, SIGNER_DIGEST_SIZE);
4774 added += SIGNER_DIGEST_SIZE;
4777 XMEMCPY(current + added, list->subjectKeyIdHash,SIGNER_DIGEST_SIZE);
4778 added += SIGNER_DIGEST_SIZE;
4788 /* Persist cert cache to memory, have lock */
4789 static INLINE int DoMemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, void* mem, int sz)
4792 int ret = SSL_SUCCESS;
4795 WOLFSSL_ENTER("DoMemSaveCertCache");
4797 realSz = GetCertCacheMemSize(cm);
4799 WOLFSSL_MSG("Mem output buffer too small");
4804 CertCacheHeader hdr;
4806 hdr.version = WOLFSSL_CACHE_CERT_VERSION;
4807 hdr.rows = CA_TABLE_SIZE;
4808 SetCertHeaderColumns(cm, hdr.columns);
4809 hdr.signerSz = (int)sizeof(Signer);
4811 XMEMCPY(mem, &hdr, sizeof(CertCacheHeader));
4812 current = (byte*)mem + sizeof(CertCacheHeader);
4814 for (i = 0; i < CA_TABLE_SIZE; ++i)
4815 current += StoreCertRow(cm, current, i);
4822 #if !defined(NO_FILESYSTEM)
4824 /* Persist cert cache to file */
4825 int CM_SaveCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
4828 int rc = SSL_SUCCESS;
4832 WOLFSSL_ENTER("CM_SaveCertCache");
4834 file = XFOPEN(fname, "w+b");
4835 if (file == XBADFILE) {
4836 WOLFSSL_MSG("Couldn't open cert cache save file");
4837 return SSL_BAD_FILE;
4840 if (LockMutex(&cm->caLock) != 0) {
4841 WOLFSSL_MSG("LockMutex on caLock failed");
4846 memSz = GetCertCacheMemSize(cm);
4847 mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
4849 WOLFSSL_MSG("Alloc for tmp buffer failed");
4852 rc = DoMemSaveCertCache(cm, mem, memSz);
4853 if (rc == SSL_SUCCESS) {
4854 int ret = (int)XFWRITE(mem, memSz, 1, file);
4856 WOLFSSL_MSG("Cert cache file write failed");
4860 XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
4863 UnLockMutex(&cm->caLock);
4870 /* Restore cert cache from file */
4871 int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
4874 int rc = SSL_SUCCESS;
4879 WOLFSSL_ENTER("CM_RestoreCertCache");
4881 file = XFOPEN(fname, "rb");
4882 if (file == XBADFILE) {
4883 WOLFSSL_MSG("Couldn't open cert cache save file");
4884 return SSL_BAD_FILE;
4887 XFSEEK(file, 0, XSEEK_END);
4888 memSz = (int)XFTELL(file);
4892 WOLFSSL_MSG("Bad file size");
4894 return SSL_BAD_FILE;
4897 mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
4899 WOLFSSL_MSG("Alloc for tmp buffer failed");
4904 ret = (int)XFREAD(mem, memSz, 1, file);
4906 WOLFSSL_MSG("Cert file read error");
4909 rc = CM_MemRestoreCertCache(cm, mem, memSz);
4910 if (rc != SSL_SUCCESS) {
4911 WOLFSSL_MSG("Mem restore cert cache failed");
4915 XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
4921 #endif /* NO_FILESYSTEM */
4924 /* Persist cert cache to memory */
4925 int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, void* mem, int sz, int* used)
4927 int ret = SSL_SUCCESS;
4929 WOLFSSL_ENTER("CM_MemSaveCertCache");
4931 if (LockMutex(&cm->caLock) != 0) {
4932 WOLFSSL_MSG("LockMutex on caLock failed");
4936 ret = DoMemSaveCertCache(cm, mem, sz);
4937 if (ret == SSL_SUCCESS)
4938 *used = GetCertCacheMemSize(cm);
4940 UnLockMutex(&cm->caLock);
4946 /* Restore cert cache from memory */
4947 int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const void* mem, int sz)
4949 int ret = SSL_SUCCESS;
4951 CertCacheHeader* hdr = (CertCacheHeader*)mem;
4952 byte* current = (byte*)mem + sizeof(CertCacheHeader);
4953 byte* end = (byte*)mem + sz; /* don't go over */
4955 WOLFSSL_ENTER("CM_MemRestoreCertCache");
4957 if (current > end) {
4958 WOLFSSL_MSG("Cert Cache Memory buffer too small");
4962 if (hdr->version != WOLFSSL_CACHE_CERT_VERSION ||
4963 hdr->rows != CA_TABLE_SIZE ||
4964 hdr->signerSz != (int)sizeof(Signer)) {
4966 WOLFSSL_MSG("Cert Cache Memory header mismatch");
4967 return CACHE_MATCH_ERROR;
4970 if (LockMutex(&cm->caLock) != 0) {
4971 WOLFSSL_MSG("LockMutex on caLock failed");
4975 FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
4977 for (i = 0; i < CA_TABLE_SIZE; ++i) {
4978 int added = RestoreCertRow(cm, current, i, hdr->columns[i], end);
4980 WOLFSSL_MSG("RestoreCertRow error");
4987 UnLockMutex(&cm->caLock);
4993 /* get how big the the cert cache save buffer needs to be */
4994 int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
4998 WOLFSSL_ENTER("CM_GetCertCacheMemSize");
5000 if (LockMutex(&cm->caLock) != 0) {
5001 WOLFSSL_MSG("LockMutex on caLock failed");
5005 sz = GetCertCacheMemSize(cm);
5007 UnLockMutex(&cm->caLock);
5012 #endif /* PERSIST_CERT_CACHE */
5013 #endif /* NO_CERTS */
5016 int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX* ctx, const char* list)
5018 WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list");
5020 /* alloc/init on demand only */
5021 if (ctx->suites == NULL) {
5022 ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap,
5023 DYNAMIC_TYPE_SUITES);
5024 if (ctx->suites == NULL) {
5025 WOLFSSL_MSG("Memory alloc for Suites failed");
5028 XMEMSET(ctx->suites, 0, sizeof(Suites));
5031 return (SetCipherList(ctx->suites, list)) ? SSL_SUCCESS : SSL_FAILURE;
5035 int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list)
5037 WOLFSSL_ENTER("wolfSSL_set_cipher_list");
5038 return (SetCipherList(ssl->suites, list)) ? SSL_SUCCESS : SSL_FAILURE;
5042 #ifndef WOLFSSL_LEANPSK
5045 int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl)
5049 return ssl->dtls_timeout;
5053 /* user may need to alter init dtls recv timeout, SSL_SUCCESS on ok */
5054 int wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int timeout)
5056 if (ssl == NULL || timeout < 0)
5057 return BAD_FUNC_ARG;
5059 if (timeout > ssl->dtls_timeout_max) {
5060 WOLFSSL_MSG("Can't set dtls timeout init greater than dtls timeout max");
5061 return BAD_FUNC_ARG;
5064 ssl->dtls_timeout_init = timeout;
5065 ssl->dtls_timeout = timeout;
5071 /* user may need to alter max dtls recv timeout, SSL_SUCCESS on ok */
5072 int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int timeout)
5074 if (ssl == NULL || timeout < 0)
5075 return BAD_FUNC_ARG;
5077 if (timeout < ssl->dtls_timeout_init) {
5078 WOLFSSL_MSG("Can't set dtls timeout max less than dtls timeout init");
5079 return BAD_FUNC_ARG;
5082 ssl->dtls_timeout_max = timeout;
5088 int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
5090 int result = SSL_SUCCESS;
5092 DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
5093 ssl->dtls_msg_list = NULL;
5094 if (DtlsPoolTimeout(ssl) < 0 || DtlsPoolSend(ssl) < 0) {
5095 result = SSL_FATAL_ERROR;
5101 #endif /* LEANPSK */
5104 /* client only parts */
5105 #ifndef NO_WOLFSSL_CLIENT
5108 WOLFSSL_METHOD* wolfSSLv3_client_method(void)
5110 WOLFSSL_METHOD* method =
5111 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
5112 DYNAMIC_TYPE_METHOD);
5113 WOLFSSL_ENTER("SSLv3_client_method");
5115 InitSSL_Method(method, MakeSSLv3());
5123 WOLFSSL_METHOD* wolfDTLSv1_client_method(void)
5125 WOLFSSL_METHOD* method =
5126 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
5127 DYNAMIC_TYPE_METHOD);
5128 WOLFSSL_ENTER("DTLSv1_client_method");
5130 InitSSL_Method(method, MakeDTLSv1());
5133 #endif /* NO_OLD_TLS */
5135 WOLFSSL_METHOD* wolfDTLSv1_2_client_method(void)
5137 WOLFSSL_METHOD* method =
5138 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
5139 DYNAMIC_TYPE_METHOD);
5140 WOLFSSL_ENTER("DTLSv1_2_client_method");
5142 InitSSL_Method(method, MakeDTLSv1_2());
5148 /* please see note at top of README if you get an error from connect */
5149 int wolfSSL_connect(WOLFSSL* ssl)
5153 WOLFSSL_ENTER("SSL_connect()");
5159 if (ssl->options.side != WOLFSSL_CLIENT_END) {
5160 WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
5161 return SSL_FATAL_ERROR;
5165 if (ssl->version.major == DTLS_MAJOR) {
5166 ssl->options.dtls = 1;
5167 ssl->options.tls = 1;
5168 ssl->options.tls1_1 = 1;
5170 if (DtlsPoolInit(ssl) != 0) {
5171 ssl->error = MEMORY_ERROR;
5172 WOLFSSL_ERROR(ssl->error);
5173 return SSL_FATAL_ERROR;
5178 if (ssl->buffers.outputBuffer.length > 0) {
5179 if ( (ssl->error = SendBuffered(ssl)) == 0) {
5180 ssl->options.connectState++;
5181 WOLFSSL_MSG("connect state: Advanced from buffered send");
5184 WOLFSSL_ERROR(ssl->error);
5185 return SSL_FATAL_ERROR;
5189 switch (ssl->options.connectState) {
5191 case CONNECT_BEGIN :
5192 /* always send client hello first */
5193 if ( (ssl->error = SendClientHello(ssl)) != 0) {
5194 WOLFSSL_ERROR(ssl->error);
5195 return SSL_FATAL_ERROR;
5197 ssl->options.connectState = CLIENT_HELLO_SENT;
5198 WOLFSSL_MSG("connect state: CLIENT_HELLO_SENT");
5200 case CLIENT_HELLO_SENT :
5201 neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
5202 SERVER_HELLODONE_COMPLETE;
5204 /* In DTLS, when resuming, we can go straight to FINISHED,
5205 * or do a cookie exchange and then skip to FINISHED, assume
5206 * we need the cookie exchange first. */
5207 if (ssl->options.dtls)
5208 neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
5211 while (ssl->options.serverState < neededState) {
5212 if ( (ssl->error = ProcessReply(ssl)) < 0) {
5213 WOLFSSL_ERROR(ssl->error);
5214 return SSL_FATAL_ERROR;
5216 /* if resumption failed, reset needed state */
5217 else if (neededState == SERVER_FINISHED_COMPLETE)
5218 if (!ssl->options.resuming) {
5219 if (!ssl->options.dtls)
5220 neededState = SERVER_HELLODONE_COMPLETE;
5222 neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
5226 ssl->options.connectState = HELLO_AGAIN;
5227 WOLFSSL_MSG("connect state: HELLO_AGAIN");
5230 if (ssl->options.certOnly)
5234 if (ssl->options.dtls) {
5235 /* re-init hashes, exclude first hello and verify request */
5237 wc_InitMd5(&ssl->hsHashes->hashMd5);
5238 if ( (ssl->error = wc_InitSha(&ssl->hsHashes->hashSha))
5240 WOLFSSL_ERROR(ssl->error);
5241 return SSL_FATAL_ERROR;
5244 if (IsAtLeastTLSv1_2(ssl)) {
5246 if ( (ssl->error = wc_InitSha256(
5247 &ssl->hsHashes->hashSha256)) != 0) {
5248 WOLFSSL_ERROR(ssl->error);
5249 return SSL_FATAL_ERROR;
5252 #ifdef WOLFSSL_SHA384
5253 if ( (ssl->error = wc_InitSha384(
5254 &ssl->hsHashes->hashSha384)) != 0) {
5255 WOLFSSL_ERROR(ssl->error);
5256 return SSL_FATAL_ERROR;
5259 #ifdef WOLFSSL_SHA512
5260 if ( (ssl->error = wc_InitSha512(
5261 &ssl->hsHashes->hashSha512)) != 0) {
5262 WOLFSSL_ERROR(ssl->error);
5263 return SSL_FATAL_ERROR;
5267 if ( (ssl->error = SendClientHello(ssl)) != 0) {
5268 WOLFSSL_ERROR(ssl->error);
5269 return SSL_FATAL_ERROR;
5274 ssl->options.connectState = HELLO_AGAIN_REPLY;
5275 WOLFSSL_MSG("connect state: HELLO_AGAIN_REPLY");
5277 case HELLO_AGAIN_REPLY :
5279 if (ssl->options.dtls) {
5280 neededState = ssl->options.resuming ?
5281 SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
5284 while (ssl->options.serverState < neededState) {
5285 if ( (ssl->error = ProcessReply(ssl)) < 0) {
5286 WOLFSSL_ERROR(ssl->error);
5287 return SSL_FATAL_ERROR;
5289 /* if resumption failed, reset needed state */
5290 else if (neededState == SERVER_FINISHED_COMPLETE)
5291 if (!ssl->options.resuming)
5292 neededState = SERVER_HELLODONE_COMPLETE;
5297 ssl->options.connectState = FIRST_REPLY_DONE;
5298 WOLFSSL_MSG("connect state: FIRST_REPLY_DONE");
5300 case FIRST_REPLY_DONE :
5302 if (ssl->options.sendVerify) {
5303 if ( (ssl->error = SendCertificate(ssl)) != 0) {
5304 WOLFSSL_ERROR(ssl->error);
5305 return SSL_FATAL_ERROR;
5307 WOLFSSL_MSG("sent: certificate");
5311 ssl->options.connectState = FIRST_REPLY_FIRST;
5312 WOLFSSL_MSG("connect state: FIRST_REPLY_FIRST");
5314 case FIRST_REPLY_FIRST :
5315 if (!ssl->options.resuming) {
5316 if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
5317 WOLFSSL_ERROR(ssl->error);
5318 return SSL_FATAL_ERROR;
5320 WOLFSSL_MSG("sent: client key exchange");
5323 ssl->options.connectState = FIRST_REPLY_SECOND;
5324 WOLFSSL_MSG("connect state: FIRST_REPLY_SECOND");
5326 case FIRST_REPLY_SECOND :
5328 if (ssl->options.sendVerify) {
5329 if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
5330 WOLFSSL_ERROR(ssl->error);
5331 return SSL_FATAL_ERROR;
5333 WOLFSSL_MSG("sent: certificate verify");
5336 ssl->options.connectState = FIRST_REPLY_THIRD;
5337 WOLFSSL_MSG("connect state: FIRST_REPLY_THIRD");
5339 case FIRST_REPLY_THIRD :
5340 if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
5341 WOLFSSL_ERROR(ssl->error);
5342 return SSL_FATAL_ERROR;
5344 WOLFSSL_MSG("sent: change cipher spec");
5345 ssl->options.connectState = FIRST_REPLY_FOURTH;
5346 WOLFSSL_MSG("connect state: FIRST_REPLY_FOURTH");
5348 case FIRST_REPLY_FOURTH :
5349 if ( (ssl->error = SendFinished(ssl)) != 0) {
5350 WOLFSSL_ERROR(ssl->error);
5351 return SSL_FATAL_ERROR;
5353 WOLFSSL_MSG("sent: finished");
5354 ssl->options.connectState = FINISHED_DONE;
5355 WOLFSSL_MSG("connect state: FINISHED_DONE");
5357 case FINISHED_DONE :
5359 while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
5360 if ( (ssl->error = ProcessReply(ssl)) < 0) {
5361 WOLFSSL_ERROR(ssl->error);
5362 return SSL_FATAL_ERROR;
5365 ssl->options.connectState = SECOND_REPLY_DONE;
5366 WOLFSSL_MSG("connect state: SECOND_REPLY_DONE");
5368 case SECOND_REPLY_DONE:
5369 #ifndef NO_HANDSHAKE_DONE_CB
5370 if (ssl->hsDoneCb) {
5371 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
5374 WOLFSSL_MSG("HandShake Done Cb don't continue error");
5375 return SSL_FATAL_ERROR;
5378 #endif /* NO_HANDSHAKE_DONE_CB */
5379 FreeHandshakeResources(ssl);
5380 WOLFSSL_LEAVE("SSL_connect()", SSL_SUCCESS);
5384 WOLFSSL_MSG("Unknown connect state ERROR");
5385 return SSL_FATAL_ERROR; /* unknown connect state */
5389 #endif /* NO_WOLFSSL_CLIENT */
5392 /* server only parts */
5393 #ifndef NO_WOLFSSL_SERVER
5396 WOLFSSL_METHOD* wolfSSLv3_server_method(void)
5398 WOLFSSL_METHOD* method =
5399 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
5400 DYNAMIC_TYPE_METHOD);
5401 WOLFSSL_ENTER("SSLv3_server_method");
5403 InitSSL_Method(method, MakeSSLv3());
5404 method->side = WOLFSSL_SERVER_END;
5414 WOLFSSL_METHOD* wolfDTLSv1_server_method(void)
5416 WOLFSSL_METHOD* method =
5417 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
5418 0, DYNAMIC_TYPE_METHOD);
5419 WOLFSSL_ENTER("DTLSv1_server_method");
5421 InitSSL_Method(method, MakeDTLSv1());
5422 method->side = WOLFSSL_SERVER_END;
5426 #endif /* NO_OLD_TLS */
5428 WOLFSSL_METHOD* wolfDTLSv1_2_server_method(void)
5430 WOLFSSL_METHOD* method =
5431 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
5432 0, DYNAMIC_TYPE_METHOD);
5433 WOLFSSL_ENTER("DTLSv1_2_server_method");
5435 InitSSL_Method(method, MakeDTLSv1_2());
5436 method->side = WOLFSSL_SERVER_END;
5443 int wolfSSL_accept(WOLFSSL* ssl)
5447 WOLFSSL_ENTER("SSL_accept()");
5454 havePSK = ssl->options.havePSK;
5459 haveAnon = ssl->options.haveAnon;
5463 if (ssl->options.side != WOLFSSL_SERVER_END) {
5464 WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
5465 return SSL_FATAL_ERROR;
5469 /* in case used set_accept_state after init */
5470 if (!havePSK && !haveAnon &&
5471 (ssl->buffers.certificate.buffer == NULL ||
5472 ssl->buffers.key.buffer == NULL)) {
5473 WOLFSSL_MSG("accept error: don't have server cert and key");
5474 ssl->error = NO_PRIVATE_KEY;
5475 WOLFSSL_ERROR(ssl->error);
5476 return SSL_FATAL_ERROR;
5481 if (ssl->version.major == DTLS_MAJOR) {
5482 ssl->options.dtls = 1;
5483 ssl->options.tls = 1;
5484 ssl->options.tls1_1 = 1;
5486 if (DtlsPoolInit(ssl) != 0) {
5487 ssl->error = MEMORY_ERROR;
5488 WOLFSSL_ERROR(ssl->error);
5489 return SSL_FATAL_ERROR;
5494 if (ssl->buffers.outputBuffer.length > 0) {
5495 if ( (ssl->error = SendBuffered(ssl)) == 0) {
5496 ssl->options.acceptState++;
5497 WOLFSSL_MSG("accept state: Advanced from buffered send");
5500 WOLFSSL_ERROR(ssl->error);
5501 return SSL_FATAL_ERROR;
5505 switch (ssl->options.acceptState) {
5509 while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
5510 if ( (ssl->error = ProcessReply(ssl)) < 0) {
5511 WOLFSSL_ERROR(ssl->error);
5512 return SSL_FATAL_ERROR;
5514 ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
5515 WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
5517 case ACCEPT_CLIENT_HELLO_DONE :
5519 if (ssl->options.dtls)
5520 if ( (ssl->error = SendHelloVerifyRequest(ssl)) != 0) {
5521 WOLFSSL_ERROR(ssl->error);
5522 return SSL_FATAL_ERROR;
5525 ssl->options.acceptState = HELLO_VERIFY_SENT;
5526 WOLFSSL_MSG("accept state HELLO_VERIFY_SENT");
5528 case HELLO_VERIFY_SENT:
5530 if (ssl->options.dtls) {
5531 ssl->options.clientState = NULL_STATE; /* get again */
5532 /* reset messages received */
5533 XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
5534 /* re-init hashes, exclude first hello and verify request */
5536 wc_InitMd5(&ssl->hsHashes->hashMd5);
5537 if ( (ssl->error = wc_InitSha(&ssl->hsHashes->hashSha))
5539 WOLFSSL_ERROR(ssl->error);
5540 return SSL_FATAL_ERROR;
5543 if (IsAtLeastTLSv1_2(ssl)) {
5545 if ( (ssl->error = wc_InitSha256(
5546 &ssl->hsHashes->hashSha256)) != 0) {
5547 WOLFSSL_ERROR(ssl->error);
5548 return SSL_FATAL_ERROR;
5551 #ifdef WOLFSSL_SHA384
5552 if ( (ssl->error = wc_InitSha384(
5553 &ssl->hsHashes->hashSha384)) != 0) {
5554 WOLFSSL_ERROR(ssl->error);
5555 return SSL_FATAL_ERROR;
5558 #ifdef WOLFSSL_SHA512
5559 if ( (ssl->error = wc_InitSha512(
5560 &ssl->hsHashes->hashSha512)) != 0) {
5561 WOLFSSL_ERROR(ssl->error);
5562 return SSL_FATAL_ERROR;
5567 while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
5568 if ( (ssl->error = ProcessReply(ssl)) < 0) {
5569 WOLFSSL_ERROR(ssl->error);
5570 return SSL_FATAL_ERROR;
5574 ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
5575 WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
5577 case ACCEPT_FIRST_REPLY_DONE :
5578 if ( (ssl->error = SendServerHello(ssl)) != 0) {
5579 WOLFSSL_ERROR(ssl->error);
5580 return SSL_FATAL_ERROR;
5582 ssl->options.acceptState = SERVER_HELLO_SENT;
5583 WOLFSSL_MSG("accept state SERVER_HELLO_SENT");
5585 case SERVER_HELLO_SENT :
5587 if (!ssl->options.resuming)
5588 if ( (ssl->error = SendCertificate(ssl)) != 0) {
5589 WOLFSSL_ERROR(ssl->error);
5590 return SSL_FATAL_ERROR;
5593 ssl->options.acceptState = CERT_SENT;
5594 WOLFSSL_MSG("accept state CERT_SENT");
5597 if (!ssl->options.resuming)
5598 if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
5599 WOLFSSL_ERROR(ssl->error);
5600 return SSL_FATAL_ERROR;
5602 ssl->options.acceptState = KEY_EXCHANGE_SENT;
5603 WOLFSSL_MSG("accept state KEY_EXCHANGE_SENT");
5605 case KEY_EXCHANGE_SENT :
5607 if (!ssl->options.resuming)
5608 if (ssl->options.verifyPeer)
5609 if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
5610 WOLFSSL_ERROR(ssl->error);
5611 return SSL_FATAL_ERROR;
5614 ssl->options.acceptState = CERT_REQ_SENT;
5615 WOLFSSL_MSG("accept state CERT_REQ_SENT");
5617 case CERT_REQ_SENT :
5618 if (!ssl->options.resuming)
5619 if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
5620 WOLFSSL_ERROR(ssl->error);
5621 return SSL_FATAL_ERROR;
5623 ssl->options.acceptState = SERVER_HELLO_DONE;
5624 WOLFSSL_MSG("accept state SERVER_HELLO_DONE");
5626 case SERVER_HELLO_DONE :
5627 if (!ssl->options.resuming) {
5628 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
5629 if ( (ssl->error = ProcessReply(ssl)) < 0) {
5630 WOLFSSL_ERROR(ssl->error);
5631 return SSL_FATAL_ERROR;
5634 ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
5635 WOLFSSL_MSG("accept state ACCEPT_SECOND_REPLY_DONE");
5637 case ACCEPT_SECOND_REPLY_DONE :
5638 #ifdef HAVE_SESSION_TICKET
5639 if (ssl->options.createTicket) {
5640 if ( (ssl->error = SendTicket(ssl)) != 0) {
5641 WOLFSSL_ERROR(ssl->error);
5642 return SSL_FATAL_ERROR;
5645 #endif /* HAVE_SESSION_TICKET */
5646 ssl->options.acceptState = TICKET_SENT;
5647 WOLFSSL_MSG("accept state TICKET_SENT");
5650 if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
5651 WOLFSSL_ERROR(ssl->error);
5652 return SSL_FATAL_ERROR;
5654 ssl->options.acceptState = CHANGE_CIPHER_SENT;
5655 WOLFSSL_MSG("accept state CHANGE_CIPHER_SENT");
5657 case CHANGE_CIPHER_SENT :
5658 if ( (ssl->error = SendFinished(ssl)) != 0) {
5659 WOLFSSL_ERROR(ssl->error);
5660 return SSL_FATAL_ERROR;
5663 ssl->options.acceptState = ACCEPT_FINISHED_DONE;
5664 WOLFSSL_MSG("accept state ACCEPT_FINISHED_DONE");
5666 case ACCEPT_FINISHED_DONE :
5667 if (ssl->options.resuming)
5668 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
5669 if ( (ssl->error = ProcessReply(ssl)) < 0) {
5670 WOLFSSL_ERROR(ssl->error);
5671 return SSL_FATAL_ERROR;
5674 ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
5675 WOLFSSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
5677 case ACCEPT_THIRD_REPLY_DONE :
5678 #ifndef NO_HANDSHAKE_DONE_CB
5679 if (ssl->hsDoneCb) {
5680 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
5683 WOLFSSL_MSG("HandShake Done Cb don't continue error");
5684 return SSL_FATAL_ERROR;
5687 #endif /* NO_HANDSHAKE_DONE_CB */
5688 FreeHandshakeResources(ssl);
5689 WOLFSSL_LEAVE("SSL_accept()", SSL_SUCCESS);
5693 WOLFSSL_MSG("Unknown accept state ERROR");
5694 return SSL_FATAL_ERROR;
5698 #endif /* NO_WOLFSSL_SERVER */
5701 #ifndef NO_HANDSHAKE_DONE_CB
5703 int wolfSSL_SetHsDoneCb(WOLFSSL* ssl, HandShakeDoneCb cb, void* user_ctx)
5705 WOLFSSL_ENTER("wolfSSL_SetHsDoneCb");
5708 return BAD_FUNC_ARG;
5711 ssl->hsDoneCtx = user_ctx;
5717 #endif /* NO_HANDSHAKE_DONE_CB */
5720 int wolfSSL_Cleanup(void)
5722 int ret = SSL_SUCCESS;
5725 WOLFSSL_ENTER("wolfSSL_Cleanup");
5727 if (initRefCount == 0)
5728 return ret; /* possibly no init yet, but not failure either way */
5730 if (LockMutex(&count_mutex) != 0) {
5731 WOLFSSL_MSG("Bad Lock Mutex count");
5735 release = initRefCount-- == 1;
5736 if (initRefCount < 0)
5739 UnLockMutex(&count_mutex);
5744 #ifndef NO_SESSION_CACHE
5745 if (FreeMutex(&session_mutex) != 0)
5748 if (FreeMutex(&count_mutex) != 0)
5751 #if defined(HAVE_ECC) && defined(FP_ECC)
5759 #ifndef NO_SESSION_CACHE
5762 /* some session IDs aren't random afterall, let's make them random */
5763 static INLINE word32 HashSession(const byte* sessionID, word32 len, int* error)
5765 byte digest[MAX_DIGEST_SIZE];
5768 *error = wc_Md5Hash(sessionID, len, digest);
5769 #elif !defined(NO_SHA)
5770 *error = wc_ShaHash(sessionID, len, digest);
5771 #elif !defined(NO_SHA256)
5772 *error = wc_Sha256Hash(sessionID, len, digest);
5774 #error "We need a digest to hash the session IDs"
5777 return *error == 0 ? MakeWordFromHash(digest) : 0; /* 0 on failure */
5781 void wolfSSL_flush_sessions(WOLFSSL_CTX* ctx, long tm)
5783 /* static table now, no flusing needed */
5789 /* set ssl session timeout in seconds */
5790 int wolfSSL_set_timeout(WOLFSSL* ssl, unsigned int to)
5793 return BAD_FUNC_ARG;
5801 /* set ctx session timeout in seconds */
5802 int wolfSSL_CTX_set_timeout(WOLFSSL_CTX* ctx, unsigned int to)
5805 return BAD_FUNC_ARG;
5813 #ifndef NO_CLIENT_CACHE
5815 /* Get Session from Client cache based on id/len, return NULL on failure */
5816 WOLFSSL_SESSION* GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
5818 WOLFSSL_SESSION* ret = NULL;
5824 WOLFSSL_ENTER("GetSessionClient");
5826 if (ssl->options.side == WOLFSSL_SERVER_END)
5829 len = min(SERVER_ID_LEN, (word32)len);
5830 row = HashSession(id, len, &error) % SESSION_ROWS;
5832 WOLFSSL_MSG("Hash session failed");
5836 if (LockMutex(&session_mutex) != 0) {
5837 WOLFSSL_MSG("Lock session mutex failed");
5841 /* start from most recently used */
5842 count = min((word32)ClientCache[row].totalCount, SESSIONS_PER_ROW);
5843 idx = ClientCache[row].nextIdx - 1;
5845 idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
5847 for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
5848 WOLFSSL_SESSION* current;
5849 ClientSession clSess;
5851 if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
5852 WOLFSSL_MSG("Bad idx");
5856 clSess = ClientCache[row].Clients[idx];
5858 current = &SessionCache[clSess.serverRow].Sessions[clSess.serverIdx];
5859 if (XMEMCMP(current->serverID, id, len) == 0) {
5860 WOLFSSL_MSG("Found a serverid match for client");
5861 if (LowResTimer() < (current->bornOn + current->timeout)) {
5862 WOLFSSL_MSG("Session valid");
5866 WOLFSSL_MSG("Session timed out"); /* could have more for id */
5869 WOLFSSL_MSG("ServerID not a match from client table");
5873 UnLockMutex(&session_mutex);
5878 #endif /* NO_CLIENT_CACHE */
5881 WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret)
5883 WOLFSSL_SESSION* ret = 0;
5884 const byte* id = NULL;
5890 if (ssl->options.sessionCacheOff)
5893 if (ssl->options.haveSessionId == 0)
5896 #ifdef HAVE_SESSION_TICKET
5897 if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
5902 id = ssl->arrays->sessionID;
5904 id = ssl->session.sessionID;
5906 row = HashSession(id, ID_LEN, &error) % SESSION_ROWS;
5908 WOLFSSL_MSG("Hash session failed");
5912 if (LockMutex(&session_mutex) != 0)
5915 /* start from most recently used */
5916 count = min((word32)SessionCache[row].totalCount, SESSIONS_PER_ROW);
5917 idx = SessionCache[row].nextIdx - 1;
5919 idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
5921 for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
5922 WOLFSSL_SESSION* current;
5924 if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
5925 WOLFSSL_MSG("Bad idx");
5929 current = &SessionCache[row].Sessions[idx];
5930 if (XMEMCMP(current->sessionID, id, ID_LEN) == 0) {
5931 WOLFSSL_MSG("Found a session match");
5932 if (LowResTimer() < (current->bornOn + current->timeout)) {
5933 WOLFSSL_MSG("Session valid");
5936 XMEMCPY(masterSecret, current->masterSecret, SECRET_LEN);
5938 WOLFSSL_MSG("Session timed out");
5940 break; /* no more sessionIDs whether valid or not that match */
5942 WOLFSSL_MSG("SessionID not a match at this idx");
5946 UnLockMutex(&session_mutex);
5952 int SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
5954 if (ssl->options.sessionCacheOff)
5957 if (LowResTimer() < (session->bornOn + session->timeout)) {
5958 ssl->session = *session;
5959 ssl->options.resuming = 1;
5961 #ifdef SESSION_CERTS
5962 ssl->version = session->version;
5963 ssl->options.cipherSuite0 = session->cipherSuite0;
5964 ssl->options.cipherSuite = session->cipherSuite;
5969 return SSL_FAILURE; /* session timed out */
5973 #ifdef WOLFSSL_SESSION_STATS
5974 static int get_locked_session_stats(word32* active, word32* total,
5978 int AddSession(WOLFSSL* ssl)
5983 if (ssl->options.sessionCacheOff)
5986 if (ssl->options.haveSessionId == 0)
5989 #ifdef HAVE_SESSION_TICKET
5990 if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
5994 row = HashSession(ssl->arrays->sessionID, ID_LEN, &error) % SESSION_ROWS;
5996 WOLFSSL_MSG("Hash session failed");
6000 if (LockMutex(&session_mutex) != 0)
6003 idx = SessionCache[row].nextIdx++;
6004 #ifdef SESSION_INDEX
6005 ssl->sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx;
6008 XMEMCPY(SessionCache[row].Sessions[idx].masterSecret,
6009 ssl->arrays->masterSecret, SECRET_LEN);
6010 XMEMCPY(SessionCache[row].Sessions[idx].sessionID, ssl->arrays->sessionID,
6012 SessionCache[row].Sessions[idx].sessionIDSz = ssl->arrays->sessionIDSz;
6014 SessionCache[row].Sessions[idx].timeout = ssl->timeout;
6015 SessionCache[row].Sessions[idx].bornOn = LowResTimer();
6017 #ifdef HAVE_SESSION_TICKET
6018 SessionCache[row].Sessions[idx].ticketLen = ssl->session.ticketLen;
6019 XMEMCPY(SessionCache[row].Sessions[idx].ticket,
6020 ssl->session.ticket, ssl->session.ticketLen);
6023 #ifdef SESSION_CERTS
6024 SessionCache[row].Sessions[idx].chain.count = ssl->session.chain.count;
6025 XMEMCPY(SessionCache[row].Sessions[idx].chain.certs,
6026 ssl->session.chain.certs, sizeof(x509_buffer) * MAX_CHAIN_DEPTH);
6028 SessionCache[row].Sessions[idx].version = ssl->version;
6029 SessionCache[row].Sessions[idx].cipherSuite0 = ssl->options.cipherSuite0;
6030 SessionCache[row].Sessions[idx].cipherSuite = ssl->options.cipherSuite;
6031 #endif /* SESSION_CERTS */
6033 SessionCache[row].totalCount++;
6034 if (SessionCache[row].nextIdx == SESSIONS_PER_ROW)
6035 SessionCache[row].nextIdx = 0;
6037 #ifndef NO_CLIENT_CACHE
6038 if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->session.idLen) {
6039 word32 clientRow, clientIdx;
6041 WOLFSSL_MSG("Adding client cache entry");
6043 SessionCache[row].Sessions[idx].idLen = ssl->session.idLen;
6044 XMEMCPY(SessionCache[row].Sessions[idx].serverID, ssl->session.serverID,
6045 ssl->session.idLen);
6047 clientRow = HashSession(ssl->session.serverID, ssl->session.idLen,
6048 &error) % SESSION_ROWS;
6050 WOLFSSL_MSG("Hash session failed");
6052 clientIdx = ClientCache[clientRow].nextIdx++;
6054 ClientCache[clientRow].Clients[clientIdx].serverRow = (word16)row;
6055 ClientCache[clientRow].Clients[clientIdx].serverIdx = (word16)idx;
6057 ClientCache[clientRow].totalCount++;
6058 if (ClientCache[clientRow].nextIdx == SESSIONS_PER_ROW)
6059 ClientCache[clientRow].nextIdx = 0;
6063 SessionCache[row].Sessions[idx].idLen = 0;
6064 #endif /* NO_CLIENT_CACHE */
6066 #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
6070 error = get_locked_session_stats(&active, NULL, NULL);
6071 if (error == SSL_SUCCESS) {
6072 error = 0; /* back to this function ok */
6074 if (active > PeakSessions)
6075 PeakSessions = active;
6078 #endif /* defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS) */
6080 if (UnLockMutex(&session_mutex) != 0)
6087 #ifdef SESSION_INDEX
6089 int wolfSSL_GetSessionIndex(WOLFSSL* ssl)
6091 WOLFSSL_ENTER("wolfSSL_GetSessionIndex");
6092 WOLFSSL_LEAVE("wolfSSL_GetSessionIndex", ssl->sessionIndex);
6093 return ssl->sessionIndex;
6097 int wolfSSL_GetSessionAtIndex(int idx, WOLFSSL_SESSION* session)
6099 int row, col, result = SSL_FAILURE;
6101 WOLFSSL_ENTER("wolfSSL_GetSessionAtIndex");
6103 row = idx >> SESSIDX_ROW_SHIFT;
6104 col = idx & SESSIDX_IDX_MASK;
6106 if (LockMutex(&session_mutex) != 0) {
6110 if (row < SESSION_ROWS &&
6111 col < (int)min(SessionCache[row].totalCount, SESSIONS_PER_ROW)) {
6113 &SessionCache[row].Sessions[col], sizeof(WOLFSSL_SESSION));
6114 result = SSL_SUCCESS;
6117 if (UnLockMutex(&session_mutex) != 0)
6118 result = BAD_MUTEX_E;
6120 WOLFSSL_LEAVE("wolfSSL_GetSessionAtIndex", result);
6124 #endif /* SESSION_INDEX */
6126 #if defined(SESSION_INDEX) && defined(SESSION_CERTS)
6128 WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session)
6130 WOLFSSL_X509_CHAIN* chain = NULL;
6132 WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
6134 chain = &session->chain;
6136 WOLFSSL_LEAVE("wolfSSL_SESSION_get_peer_chain", chain ? 1 : 0);
6140 #endif /* SESSION_INDEX && SESSION_CERTS */
6143 #ifdef WOLFSSL_SESSION_STATS
6145 /* requires session_mutex lock held, SSL_SUCCESS on ok */
6146 static int get_locked_session_stats(word32* active, word32* total, word32* peak)
6148 int result = SSL_SUCCESS;
6154 word32 ticks = LowResTimer();
6158 WOLFSSL_ENTER("get_locked_session_stats");
6160 for (i = 0; i < SESSION_ROWS; i++) {
6161 seen += SessionCache[i].totalCount;
6164 continue; /* no need to calculate what we can't set */
6166 count = min((word32)SessionCache[i].totalCount, SESSIONS_PER_ROW);
6167 idx = SessionCache[i].nextIdx - 1;
6169 idx = SESSIONS_PER_ROW - 1; /* if back to front previous was end */
6171 for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
6172 if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
6173 WOLFSSL_MSG("Bad idx");
6177 /* if not expried then good */
6178 if (ticks < (SessionCache[i].Sessions[idx].bornOn +
6179 SessionCache[i].Sessions[idx].timeout) ) {
6191 #ifdef WOLFSSL_PEAK_SESSIONS
6193 *peak = PeakSessions;
6196 WOLFSSL_LEAVE("get_locked_session_stats", result);
6202 /* return SSL_SUCCESS on ok */
6203 int wolfSSL_get_session_stats(word32* active, word32* total, word32* peak,
6204 word32* maxSessions)
6206 int result = SSL_SUCCESS;
6208 WOLFSSL_ENTER("wolfSSL_get_session_stats");
6211 *maxSessions = SESSIONS_PER_ROW * SESSION_ROWS;
6213 if (active == NULL && total == NULL && peak == NULL)
6214 return result; /* we're done */
6217 /* user must provide at least one query value */
6218 if (active == NULL && total == NULL && peak == NULL)
6219 return BAD_FUNC_ARG;
6221 if (LockMutex(&session_mutex) != 0) {
6225 result = get_locked_session_stats(active, total, peak);
6227 if (UnLockMutex(&session_mutex) != 0)
6228 result = BAD_MUTEX_E;
6230 WOLFSSL_LEAVE("wolfSSL_get_session_stats", result);
6235 #endif /* WOLFSSL_SESSION_STATS */
6238 #ifdef PRINT_SESSION_STATS
6240 /* SSL_SUCCESS on ok */
6241 int wolfSSL_PrintSessionStats(void)
6243 word32 totalSessionsSeen = 0;
6244 word32 totalSessionsNow = 0;
6246 word32 maxSessions = 0;
6249 double E; /* expected freq */
6250 double chiSquare = 0;
6252 ret = wolfSSL_get_session_stats(&totalSessionsNow, &totalSessionsSeen,
6253 &peak, &maxSessions);
6254 if (ret != SSL_SUCCESS)
6256 printf("Total Sessions Seen = %d\n", totalSessionsSeen);
6257 printf("Total Sessions Now = %d\n", totalSessionsNow);
6258 #ifdef WOLFSSL_PEAK_SESSIONS
6259 printf("Peak Sessions = %d\n", peak);
6261 printf("Max Sessions = %d\n", maxSessions);
6263 E = (double)totalSessionsSeen / SESSION_ROWS;
6265 for (i = 0; i < SESSION_ROWS; i++) {
6266 double diff = SessionCache[i].totalCount - E;
6267 diff *= diff; /* square */
6268 diff /= E; /* normalize */
6272 printf(" chi-square = %5.1f, d.f. = %d\n", chiSquare,
6274 #if (SESSION_ROWS == 11)
6275 printf(" .05 p value = 18.3, chi-square should be less\n");
6276 #elif (SESSION_ROWS == 211)
6277 printf(".05 p value = 244.8, chi-square should be less\n");
6278 #elif (SESSION_ROWS == 5981)
6279 printf(".05 p value = 6161.0, chi-square should be less\n");
6280 #elif (SESSION_ROWS == 3)
6281 printf(".05 p value = 6.0, chi-square should be less\n");
6282 #elif (SESSION_ROWS == 2861)
6283 printf(".05 p value = 2985.5, chi-square should be less\n");
6290 #endif /* SESSION_STATS */
6292 #else /* NO_SESSION_CACHE */
6294 /* No session cache version */
6295 WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret)
6303 #endif /* NO_SESSION_CACHE */
6306 /* call before SSL_connect, if verifying will add name check to
6307 date check and signature check */
6308 int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
6310 WOLFSSL_ENTER("wolfSSL_check_domain_name");
6311 if (ssl->buffers.domainName.buffer)
6312 XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
6314 ssl->buffers.domainName.length = (word32)XSTRLEN(dn) + 1;
6315 ssl->buffers.domainName.buffer = (byte*) XMALLOC(
6316 ssl->buffers.domainName.length, ssl->heap, DYNAMIC_TYPE_DOMAIN);
6318 if (ssl->buffers.domainName.buffer) {
6319 XSTRNCPY((char*)ssl->buffers.domainName.buffer, dn,
6320 ssl->buffers.domainName.length);
6324 ssl->error = MEMORY_ERROR;
6330 /* turn on wolfSSL zlib compression
6331 returns SSL_SUCCESS for success, else error (not built in)
6333 int wolfSSL_set_compression(WOLFSSL* ssl)
6335 WOLFSSL_ENTER("wolfSSL_set_compression");
6338 ssl->options.usingCompression = 1;
6341 return NOT_COMPILED_IN;
6346 #ifndef USE_WINDOWS_API
6349 /* simulate writev semantics, doesn't actually do block at a time though
6350 because of SSL_write behavior and because front adds may be small */
6351 int wolfSSL_writev(WOLFSSL* ssl, const struct iovec* iov, int iovcnt)
6353 #ifdef WOLFSSL_SMALL_STACK
6354 byte staticBuffer[1]; /* force heap usage */
6356 byte staticBuffer[FILE_BUFFER_SIZE];
6358 byte* myBuffer = staticBuffer;
6365 WOLFSSL_ENTER("wolfSSL_writev");
6367 for (i = 0; i < iovcnt; i++)
6368 sending += (int)iov[i].iov_len;
6370 if (sending > (int)sizeof(staticBuffer)) {
6371 myBuffer = (byte*)XMALLOC(sending, ssl->heap,
6372 DYNAMIC_TYPE_WRITEV);
6374 return MEMORY_ERROR;
6379 for (i = 0; i < iovcnt; i++) {
6380 XMEMCPY(&myBuffer[idx], iov[i].iov_base, iov[i].iov_len);
6381 idx += (int)iov[i].iov_len;
6384 ret = wolfSSL_write(ssl, myBuffer, sending);
6387 XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
6395 #ifdef WOLFSSL_CALLBACKS
6397 typedef struct itimerval Itimerval;
6399 /* don't keep calling simple functions while setting up timer and singals
6400 if no inlining these are the next best */
6402 #define AddTimes(a, b, c) \
6404 c.tv_sec = a.tv_sec + b.tv_sec; \
6405 c.tv_usec = a.tv_usec + b.tv_usec; \
6406 if (c.tv_usec >= 1000000) { \
6408 c.tv_usec -= 1000000; \
6413 #define SubtractTimes(a, b, c) \
6415 c.tv_sec = a.tv_sec - b.tv_sec; \
6416 c.tv_usec = a.tv_usec - b.tv_usec; \
6417 if (c.tv_usec < 0) { \
6419 c.tv_usec += 1000000; \
6423 #define CmpTimes(a, b, cmp) \
6424 ((a.tv_sec == b.tv_sec) ? \
6425 (a.tv_usec cmp b.tv_usec) : \
6426 (a.tv_sec cmp b.tv_sec)) \
6429 /* do nothing handler */
6430 static void myHandler(int signo)
6437 static int wolfSSL_ex_wrapper(WOLFSSL* ssl, HandShakeCallBack hsCb,
6438 TimeoutCallBack toCb, Timeval timeout)
6440 int ret = SSL_FATAL_ERROR;
6441 int oldTimerOn = 0; /* was timer already on */
6445 Itimerval myTimeout;
6446 Itimerval oldTimeout; /* if old timer adjust from total time to reset */
6447 struct sigaction act, oact;
6449 #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
6453 InitHandShakeInfo(&ssl->handShakeInfo);
6457 InitTimeoutInfo(&ssl->timeoutInfo);
6459 if (gettimeofday(&startTime, 0) < 0)
6460 ERR_OUT(GETTIME_ERROR);
6462 /* use setitimer to simulate getitimer, init 0 myTimeout */
6463 myTimeout.it_interval.tv_sec = 0;
6464 myTimeout.it_interval.tv_usec = 0;
6465 myTimeout.it_value.tv_sec = 0;
6466 myTimeout.it_value.tv_usec = 0;
6467 if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
6468 ERR_OUT(SETITIMER_ERROR);
6470 if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
6473 /* is old timer going to expire before ours */
6474 if (CmpTimes(oldTimeout.it_value, timeout, <)) {
6475 timeout.tv_sec = oldTimeout.it_value.tv_sec;
6476 timeout.tv_usec = oldTimeout.it_value.tv_usec;
6479 myTimeout.it_value.tv_sec = timeout.tv_sec;
6480 myTimeout.it_value.tv_usec = timeout.tv_usec;
6482 /* set up signal handler, don't restart socket send/recv */
6483 act.sa_handler = myHandler;
6484 sigemptyset(&act.sa_mask);
6487 act.sa_flags |= SA_INTERRUPT;
6489 if (sigaction(SIGALRM, &act, &oact) < 0)
6490 ERR_OUT(SIGACT_ERROR);
6492 if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
6493 ERR_OUT(SETITIMER_ERROR);
6497 #ifndef NO_WOLFSSL_CLIENT
6498 if (ssl->options.side == WOLFSSL_CLIENT_END)
6499 ret = wolfSSL_connect(ssl);
6501 #ifndef NO_WOLFSSL_SERVER
6502 if (ssl->options.side == WOLFSSL_SERVER_END)
6503 ret = wolfSSL_accept(ssl);
6509 gettimeofday(&endTime, 0);
6510 SubtractTimes(endTime, startTime, totalTime);
6511 /* adjust old timer for elapsed time */
6512 if (CmpTimes(totalTime, oldTimeout.it_value, <))
6513 SubtractTimes(oldTimeout.it_value, totalTime,
6514 oldTimeout.it_value);
6516 /* reset value to interval, may be off */
6517 oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
6518 oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
6520 /* keep iter the same whether there or not */
6522 /* restore old handler */
6523 if (sigaction(SIGALRM, &oact, 0) < 0)
6524 ret = SIGACT_ERROR; /* more pressing error, stomp */
6526 /* use old settings which may turn off (expired or not there) */
6527 if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
6528 ret = SETITIMER_ERROR;
6530 /* if we had a timeout call callback */
6531 if (ssl->timeoutInfo.timeoutName[0]) {
6532 ssl->timeoutInfo.timeoutValue.tv_sec = timeout.tv_sec;
6533 ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
6534 (toCb)(&ssl->timeoutInfo);
6537 FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
6541 FinishHandShakeInfo(&ssl->handShakeInfo, ssl);
6542 (hsCb)(&ssl->handShakeInfo);
6549 #ifndef NO_WOLFSSL_CLIENT
6551 int wolfSSL_connect_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
6552 TimeoutCallBack toCb, Timeval timeout)
6554 WOLFSSL_ENTER("wolfSSL_connect_ex");
6555 return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
6561 #ifndef NO_WOLFSSL_SERVER
6563 int wolfSSL_accept_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
6564 TimeoutCallBack toCb,Timeval timeout)
6566 WOLFSSL_ENTER("wolfSSL_accept_ex");
6567 return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
6572 #endif /* WOLFSSL_CALLBACKS */
6577 void wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX* ctx,
6578 psk_client_callback cb)
6580 WOLFSSL_ENTER("SSL_CTX_set_psk_client_callback");
6582 ctx->client_psk_cb = cb;
6586 void wolfSSL_set_psk_client_callback(WOLFSSL* ssl, psk_client_callback cb)
6590 WOLFSSL_ENTER("SSL_set_psk_client_callback");
6591 ssl->options.havePSK = 1;
6592 ssl->options.client_psk_cb = cb;
6597 InitSuites(ssl->suites, ssl->version, haveRSA, TRUE,
6598 ssl->options.haveDH, ssl->options.haveNTRU,
6599 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
6604 void wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX* ctx,
6605 psk_server_callback cb)
6607 WOLFSSL_ENTER("SSL_CTX_set_psk_server_callback");
6609 ctx->server_psk_cb = cb;
6613 void wolfSSL_set_psk_server_callback(WOLFSSL* ssl, psk_server_callback cb)
6617 WOLFSSL_ENTER("SSL_set_psk_server_callback");
6618 ssl->options.havePSK = 1;
6619 ssl->options.server_psk_cb = cb;
6624 InitSuites(ssl->suites, ssl->version, haveRSA, TRUE,
6625 ssl->options.haveDH, ssl->options.haveNTRU,
6626 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
6631 const char* wolfSSL_get_psk_identity_hint(const WOLFSSL* ssl)
6633 WOLFSSL_ENTER("SSL_get_psk_identity_hint");
6635 if (ssl == NULL || ssl->arrays == NULL)
6638 return ssl->arrays->server_hint;
6642 const char* wolfSSL_get_psk_identity(const WOLFSSL* ssl)
6644 WOLFSSL_ENTER("SSL_get_psk_identity");
6646 if (ssl == NULL || ssl->arrays == NULL)
6649 return ssl->arrays->client_identity;
6653 int wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX* ctx, const char* hint)
6655 WOLFSSL_ENTER("SSL_CTX_use_psk_identity_hint");
6657 ctx->server_hint[0] = 0;
6659 XSTRNCPY(ctx->server_hint, hint, MAX_PSK_ID_LEN);
6660 ctx->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
6666 int wolfSSL_use_psk_identity_hint(WOLFSSL* ssl, const char* hint)
6668 WOLFSSL_ENTER("SSL_use_psk_identity_hint");
6670 if (ssl == NULL || ssl->arrays == NULL)
6674 ssl->arrays->server_hint[0] = 0;
6676 XSTRNCPY(ssl->arrays->server_hint, hint, MAX_PSK_ID_LEN);
6677 ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
6687 int wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX* ctx)
6689 WOLFSSL_ENTER("wolfSSL_CTX_allow_anon_cipher");
6699 #endif /* HAVE_ANON */
6703 /* used to be defined on NO_FILESYSTEM only, but are generally useful */
6705 /* wolfSSL extension allows DER files to be loaded from buffers as well */
6706 int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX* ctx, const unsigned char* in,
6707 long sz, int format)
6709 WOLFSSL_ENTER("wolfSSL_CTX_load_verify_buffer");
6710 if (format == SSL_FILETYPE_PEM)
6711 return ProcessChainBuffer(ctx, in, sz, format, CA_TYPE, NULL);
6713 return ProcessBuffer(ctx, in, sz, format, CA_TYPE, NULL,NULL,0);
6717 int wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX* ctx,
6718 const unsigned char* in, long sz, int format)
6720 WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_buffer");
6721 return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 0);
6725 int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX* ctx,
6726 const unsigned char* in, long sz, int format)
6728 WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_buffer");
6729 return ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL,NULL,0);
6733 int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
6734 const unsigned char* in, long sz)
6736 WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_buffer");
6737 return ProcessBuffer(ctx, in, sz, SSL_FILETYPE_PEM, CERT_TYPE, NULL,
6741 int wolfSSL_use_certificate_buffer(WOLFSSL* ssl,
6742 const unsigned char* in, long sz, int format)
6744 WOLFSSL_ENTER("wolfSSL_use_certificate_buffer");
6745 return ProcessBuffer(ssl->ctx, in, sz, format,CERT_TYPE,ssl,NULL,0);
6749 int wolfSSL_use_PrivateKey_buffer(WOLFSSL* ssl,
6750 const unsigned char* in, long sz, int format)
6752 WOLFSSL_ENTER("wolfSSL_use_PrivateKey_buffer");
6753 return ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE,
6758 int wolfSSL_use_certificate_chain_buffer(WOLFSSL* ssl,
6759 const unsigned char* in, long sz)
6761 WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer");
6762 return ProcessBuffer(ssl->ctx, in, sz, SSL_FILETYPE_PEM, CERT_TYPE,
6767 /* unload any certs or keys that SSL owns, leave CTX as is
6768 SSL_SUCCESS on ok */
6769 int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl)
6772 WOLFSSL_MSG("Null function arg");
6773 return BAD_FUNC_ARG;
6776 if (ssl->buffers.weOwnCert) {
6777 WOLFSSL_MSG("Unloading cert");
6778 XFREE(ssl->buffers.certificate.buffer, ssl->heap,DYNAMIC_TYPE_CERT);
6779 ssl->buffers.weOwnCert = 0;
6780 ssl->buffers.certificate.length = 0;
6781 ssl->buffers.certificate.buffer = NULL;
6784 if (ssl->buffers.weOwnCertChain) {
6785 WOLFSSL_MSG("Unloading cert chain");
6786 XFREE(ssl->buffers.certChain.buffer, ssl->heap,DYNAMIC_TYPE_CERT);
6787 ssl->buffers.weOwnCertChain = 0;
6788 ssl->buffers.certChain.length = 0;
6789 ssl->buffers.certChain.buffer = NULL;
6792 if (ssl->buffers.weOwnKey) {
6793 WOLFSSL_MSG("Unloading key");
6794 XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
6795 ssl->buffers.weOwnKey = 0;
6796 ssl->buffers.key.length = 0;
6797 ssl->buffers.key.buffer = NULL;
6804 int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx)
6806 WOLFSSL_ENTER("wolfSSL_CTX_UnloadCAs");
6809 return BAD_FUNC_ARG;
6811 return wolfSSL_CertManagerUnloadCAs(ctx->cm);
6814 /* old NO_FILESYSTEM end */
6815 #endif /* !NO_CERTS */
6818 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
6821 int wolfSSL_add_all_algorithms(void)
6823 WOLFSSL_ENTER("wolfSSL_add_all_algorithms");
6829 long wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX* ctx, long sz)
6831 /* cache size fixed at compile time in wolfSSL */
6838 void wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX* ctx, int mode)
6840 WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
6842 ctx->quietShutdown = 1;
6846 void wolfSSL_set_quiet_shutdown(WOLFSSL* ssl, int mode)
6848 WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
6850 ssl->options.quietShutdown = 1;
6854 void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr)
6856 WOLFSSL_ENTER("SSL_set_bio");
6857 wolfSSL_set_rfd(ssl, rd->fd);
6858 wolfSSL_set_wfd(ssl, wr->fd);
6865 void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX* ctx,
6866 STACK_OF(WOLFSSL_X509_NAME)* names)
6873 STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char* fname)
6880 int wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX* ctx)
6882 /* TODO:, not needed in goahead */
6884 return SSL_NOT_IMPLEMENTED;
6888 /* keyblock size in bytes or -1 */
6889 int wolfSSL_get_keyblock_size(WOLFSSL* ssl)
6892 return SSL_FATAL_ERROR;
6894 return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
6895 ssl->specs.hash_size);
6899 /* store keys returns SSL_SUCCESS or -1 on error */
6900 int wolfSSL_get_keys(WOLFSSL* ssl, unsigned char** ms, unsigned int* msLen,
6901 unsigned char** sr, unsigned int* srLen,
6902 unsigned char** cr, unsigned int* crLen)
6904 if (ssl == NULL || ssl->arrays == NULL)
6905 return SSL_FATAL_ERROR;
6907 *ms = ssl->arrays->masterSecret;
6908 *sr = ssl->arrays->serverRandom;
6909 *cr = ssl->arrays->clientRandom;
6911 *msLen = SECRET_LEN;
6919 void wolfSSL_set_accept_state(WOLFSSL* ssl)
6924 WOLFSSL_ENTER("SSL_set_accept_state");
6925 ssl->options.side = WOLFSSL_SERVER_END;
6926 /* reset suites in case user switched */
6932 havePSK = ssl->options.havePSK;
6934 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
6935 ssl->options.haveDH, ssl->options.haveNTRU,
6936 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
6941 /* return true if connection established */
6942 int wolfSSL_is_init_finished(WOLFSSL* ssl)
6947 if (ssl->options.handShakeState == HANDSHAKE_DONE)
6953 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
6954 void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX* ctx,
6955 WOLFSSL_RSA*(*f)(WOLFSSL*, int, int))
6957 /* wolfSSL verifies all these internally */
6963 void wolfSSL_set_shutdown(WOLFSSL* ssl, int opt)
6970 long wolfSSL_CTX_set_options(WOLFSSL_CTX* ctx, long opt)
6972 /* goahead calls with 0, do nothing */
6973 WOLFSSL_ENTER("SSL_CTX_set_options");
6979 int wolfSSL_set_rfd(WOLFSSL* ssl, int rfd)
6981 WOLFSSL_ENTER("SSL_set_rfd");
6982 ssl->rfd = rfd; /* not used directly to allow IO callbacks */
6984 ssl->IOCB_ReadCtx = &ssl->rfd;
6990 int wolfSSL_set_wfd(WOLFSSL* ssl, int wfd)
6992 WOLFSSL_ENTER("SSL_set_wfd");
6993 ssl->wfd = wfd; /* not used directly to allow IO callbacks */
6995 ssl->IOCB_WriteCtx = &ssl->wfd;
7001 WOLFSSL_RSA* wolfSSL_RSA_generate_key(int len, unsigned long bits,
7002 void(*f)(int, int, void*), void* data)
7004 /* no tmp key needed, actual generation not supported */
7005 WOLFSSL_ENTER("RSA_generate_key");
7015 WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get_current_cert(
7016 WOLFSSL_X509_STORE_CTX* ctx)
7023 int wolfSSL_X509_STORE_CTX_get_error(WOLFSSL_X509_STORE_CTX* ctx)
7031 int wolfSSL_X509_STORE_CTX_get_error_depth(WOLFSSL_X509_STORE_CTX* ctx)
7038 WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_buffer(void)
7040 static WOLFSSL_BIO_METHOD meth;
7042 WOLFSSL_ENTER("BIO_f_buffer");
7043 meth.type = BIO_BUFFER;
7049 long wolfSSL_BIO_set_write_buffer_size(WOLFSSL_BIO* bio, long size)
7051 /* wolfSSL has internal buffer, compatibility only */
7052 WOLFSSL_ENTER("BIO_set_write_buffer_size");
7058 WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_ssl(void)
7060 static WOLFSSL_BIO_METHOD meth;
7062 WOLFSSL_ENTER("BIO_f_ssl");
7063 meth.type = BIO_SSL;
7069 WOLFSSL_BIO* wolfSSL_BIO_new_socket(int sfd, int closeF)
7071 WOLFSSL_BIO* bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0,
7072 DYNAMIC_TYPE_OPENSSL);
7074 WOLFSSL_ENTER("BIO_new_socket");
7076 bio->type = BIO_SOCKET;
7077 bio->close = (byte)closeF;
7090 int wolfSSL_BIO_eof(WOLFSSL_BIO* b)
7092 WOLFSSL_ENTER("BIO_eof");
7100 long wolfSSL_BIO_set_ssl(WOLFSSL_BIO* b, WOLFSSL* ssl, int closeF)
7102 WOLFSSL_ENTER("BIO_set_ssl");
7104 b->close = (byte)closeF;
7105 /* add to ssl for bio free if SSL_free called before/instead of free_all? */
7111 WOLFSSL_BIO* wolfSSL_BIO_new(WOLFSSL_BIO_METHOD* method)
7113 WOLFSSL_BIO* bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0,
7114 DYNAMIC_TYPE_OPENSSL);
7115 WOLFSSL_ENTER("BIO_new");
7117 bio->type = method->type;
7131 int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, const byte** p)
7133 if (bio == NULL || p == NULL)
7134 return SSL_FATAL_ERROR;
7142 WOLFSSL_BIO* wolfSSL_BIO_new_mem_buf(void* buf, int len)
7144 WOLFSSL_BIO* bio = NULL;
7148 bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
7153 bio->mem = (byte*)XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL);
7154 if (bio->mem == NULL) {
7155 XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
7159 XMEMCPY(bio->mem, buf, len);
7165 #ifdef USE_WINDOWS_API
7166 #define CloseSocket(s) closesocket(s)
7167 #elif defined(WOLFSSL_MDK_ARM)
7168 #define CloseSocket(s) closesocket(s)
7169 extern int closesocket(int) ;
7171 #define CloseSocket(s) close(s)
7174 int wolfSSL_BIO_free(WOLFSSL_BIO* bio)
7176 /* unchain?, doesn't matter in goahead since from free all */
7177 WOLFSSL_ENTER("BIO_free");
7181 wolfSSL_free(bio->ssl);
7183 CloseSocket(bio->fd);
7186 XFREE(bio->mem, 0, DYNAMIC_TYPE_OPENSSL);
7187 XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
7193 int wolfSSL_BIO_free_all(WOLFSSL_BIO* bio)
7195 WOLFSSL_ENTER("BIO_free_all");
7197 WOLFSSL_BIO* next = bio->next;
7198 wolfSSL_BIO_free(bio);
7205 int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
7209 WOLFSSL_BIO* front = bio;
7211 WOLFSSL_ENTER("BIO_read");
7212 /* already got eof, again is error */
7214 return SSL_FATAL_ERROR;
7216 while(bio && ((ssl = bio->ssl) == 0) )
7219 if (ssl == 0) return BAD_FUNC_ARG;
7221 ret = wolfSSL_read(ssl, buf, len);
7225 int err = wolfSSL_get_error(ssl, 0);
7226 if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
7233 int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
7237 WOLFSSL_BIO* front = bio;
7239 WOLFSSL_ENTER("BIO_write");
7240 /* already got eof, again is error */
7242 return SSL_FATAL_ERROR;
7244 while(bio && ((ssl = bio->ssl) == 0) )
7247 if (ssl == 0) return BAD_FUNC_ARG;
7249 ret = wolfSSL_write(ssl, data, len);
7253 int err = wolfSSL_get_error(ssl, 0);
7254 if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
7262 WOLFSSL_BIO* wolfSSL_BIO_push(WOLFSSL_BIO* top, WOLFSSL_BIO* append)
7264 WOLFSSL_ENTER("BIO_push");
7272 int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
7274 /* for wolfSSL no flushing needed */
7275 WOLFSSL_ENTER("BIO_flush");
7281 #endif /* OPENSSL_EXTRA || GOAHEAD_WS */
7284 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
7286 void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX* ctx,
7289 WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb_userdata");
7290 ctx->userdata = userdata;
7294 void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX* ctx, pem_password_cb cb)
7296 WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb");
7297 ctx->passwd_cb = cb;
7300 int wolfSSL_num_locks(void)
7305 void wolfSSL_set_locking_callback(void (*f)(int, int, const char*, int))
7310 void wolfSSL_set_id_callback(unsigned long (*f)(void))
7315 unsigned long wolfSSL_ERR_get_error(void)
7323 int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER* type,
7324 const WOLFSSL_EVP_MD* md, const byte* salt,
7325 const byte* data, int sz, int count, byte* key, byte* iv)
7333 byte digest[MD5_DIGEST_SIZE];
7334 #ifdef WOLFSSL_SMALL_STACK
7340 #ifdef WOLFSSL_SMALL_STACK
7341 md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
7346 WOLFSSL_ENTER("EVP_BytesToKey");
7349 /* only support MD5 for now */
7350 if (XSTRNCMP(md, "MD5", 3) != 0) return 0;
7352 /* only support CBC DES and AES for now */
7353 if (XSTRNCMP(type, "DES-CBC", 7) == 0) {
7354 keyLen = DES_KEY_SIZE;
7355 ivLen = DES_IV_SIZE;
7357 else if (XSTRNCMP(type, "DES-EDE3-CBC", 12) == 0) {
7358 keyLen = DES3_KEY_SIZE;
7359 ivLen = DES_IV_SIZE;
7361 else if (XSTRNCMP(type, "AES-128-CBC", 11) == 0) {
7362 keyLen = AES_128_KEY_SIZE;
7363 ivLen = AES_IV_SIZE;
7365 else if (XSTRNCMP(type, "AES-192-CBC", 11) == 0) {
7366 keyLen = AES_192_KEY_SIZE;
7367 ivLen = AES_IV_SIZE;
7369 else if (XSTRNCMP(type, "AES-256-CBC", 11) == 0) {
7370 keyLen = AES_256_KEY_SIZE;
7371 ivLen = AES_IV_SIZE;
7374 #ifdef WOLFSSL_SMALL_STACK
7375 XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7383 while (keyOutput < (keyLen + ivLen)) {
7384 int digestLeft = MD5_DIGEST_SIZE;
7386 if (keyOutput) /* first time D_0 is empty */
7387 wc_Md5Update(md5, digest, MD5_DIGEST_SIZE);
7389 wc_Md5Update(md5, data, sz);
7392 wc_Md5Update(md5, salt, EVP_SALT_SIZE);
7393 wc_Md5Final(md5, digest);
7395 for (j = 1; j < count; j++) {
7396 wc_Md5Update(md5, digest, MD5_DIGEST_SIZE);
7397 wc_Md5Final(md5, digest);
7401 int store = min(keyLeft, MD5_DIGEST_SIZE);
7402 XMEMCPY(&key[keyLen - keyLeft], digest, store);
7406 digestLeft -= store;
7409 if (ivLeft && digestLeft) {
7410 int store = min(ivLeft, digestLeft);
7411 XMEMCPY(&iv[ivLen - ivLeft], &digest[MD5_DIGEST_SIZE -
7412 digestLeft], store);
7418 #ifdef WOLFSSL_SMALL_STACK
7419 XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7422 return keyOutput == (keyLen + ivLen) ? keyOutput : 0;
7427 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
7430 #ifdef OPENSSL_EXTRA
7432 unsigned long wolfSSLeay(void)
7434 return SSLEAY_VERSION_NUMBER;
7438 const char* wolfSSLeay_version(int type)
7440 static const char* version = "SSLeay wolfSSL compatibility";
7447 void wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5)
7449 typedef char md5_test[sizeof(MD5_CTX) >= sizeof(Md5) ? 1 : -1];
7450 (void)sizeof(md5_test);
7452 WOLFSSL_ENTER("MD5_Init");
7453 wc_InitMd5((Md5*)md5);
7457 void wolfSSL_MD5_Update(WOLFSSL_MD5_CTX* md5, const void* input,
7460 WOLFSSL_ENTER("wolfSSL_MD5_Update");
7461 wc_Md5Update((Md5*)md5, (const byte*)input, (word32)sz);
7465 void wolfSSL_MD5_Final(byte* input, WOLFSSL_MD5_CTX* md5)
7467 WOLFSSL_ENTER("MD5_Final");
7468 wc_Md5Final((Md5*)md5, input);
7474 void wolfSSL_SHA_Init(WOLFSSL_SHA_CTX* sha)
7476 typedef char sha_test[sizeof(SHA_CTX) >= sizeof(Sha) ? 1 : -1];
7477 (void)sizeof(sha_test);
7479 WOLFSSL_ENTER("SHA_Init");
7480 wc_InitSha((Sha*)sha); /* OpenSSL compat, no ret */
7484 void wolfSSL_SHA_Update(WOLFSSL_SHA_CTX* sha, const void* input,
7487 WOLFSSL_ENTER("SHA_Update");
7488 wc_ShaUpdate((Sha*)sha, (const byte*)input, (word32)sz);
7492 void wolfSSL_SHA_Final(byte* input, WOLFSSL_SHA_CTX* sha)
7494 WOLFSSL_ENTER("SHA_Final");
7495 wc_ShaFinal((Sha*)sha, input);
7499 void wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX* sha)
7501 WOLFSSL_ENTER("SHA1_Init");
7506 void wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX* sha, const void* input,
7509 WOLFSSL_ENTER("SHA1_Update");
7510 SHA_Update(sha, input, sz);
7514 void wolfSSL_SHA1_Final(byte* input, WOLFSSL_SHA_CTX* sha)
7516 WOLFSSL_ENTER("SHA1_Final");
7517 SHA_Final(input, sha);
7522 void wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX* sha256)
7524 typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(Sha256) ? 1 : -1];
7525 (void)sizeof(sha_test);
7527 WOLFSSL_ENTER("SHA256_Init");
7528 wc_InitSha256((Sha256*)sha256); /* OpenSSL compat, no error */
7532 void wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX* sha, const void* input,
7535 WOLFSSL_ENTER("SHA256_Update");
7536 wc_Sha256Update((Sha256*)sha, (const byte*)input, (word32)sz);
7537 /* OpenSSL compat, no error */
7541 void wolfSSL_SHA256_Final(byte* input, WOLFSSL_SHA256_CTX* sha)
7543 WOLFSSL_ENTER("SHA256_Final");
7544 wc_Sha256Final((Sha256*)sha, input);
7545 /* OpenSSL compat, no error */
7549 #ifdef WOLFSSL_SHA384
7551 void wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX* sha)
7553 typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(Sha384) ? 1 : -1];
7554 (void)sizeof(sha_test);
7556 WOLFSSL_ENTER("SHA384_Init");
7557 wc_InitSha384((Sha384*)sha); /* OpenSSL compat, no error */
7561 void wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX* sha, const void* input,
7564 WOLFSSL_ENTER("SHA384_Update");
7565 wc_Sha384Update((Sha384*)sha, (const byte*)input, (word32)sz);
7566 /* OpenSSL compat, no error */
7570 void wolfSSL_SHA384_Final(byte* input, WOLFSSL_SHA384_CTX* sha)
7572 WOLFSSL_ENTER("SHA384_Final");
7573 wc_Sha384Final((Sha384*)sha, input);
7574 /* OpenSSL compat, no error */
7577 #endif /* WOLFSSL_SHA384 */
7580 #ifdef WOLFSSL_SHA512
7582 void wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha)
7584 typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(Sha512) ? 1 : -1];
7585 (void)sizeof(sha_test);
7587 WOLFSSL_ENTER("SHA512_Init");
7588 wc_InitSha512((Sha512*)sha); /* OpenSSL compat, no error */
7592 void wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX* sha, const void* input,
7595 WOLFSSL_ENTER("SHA512_Update");
7596 wc_Sha512Update((Sha512*)sha, (const byte*)input, (word32)sz);
7597 /* OpenSSL compat, no error */
7601 void wolfSSL_SHA512_Final(byte* input, WOLFSSL_SHA512_CTX* sha)
7603 WOLFSSL_ENTER("SHA512_Final");
7604 wc_Sha512Final((Sha512*)sha, input);
7605 /* OpenSSL compat, no error */
7608 #endif /* WOLFSSL_SHA512 */
7613 const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void)
7615 static const char* type = "MD5";
7616 WOLFSSL_ENTER("EVP_md5");
7624 const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void)
7626 static const char* type = "SHA";
7627 WOLFSSL_ENTER("EVP_sha1");
7633 const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void)
7635 static const char* type = "SHA256";
7636 WOLFSSL_ENTER("EVP_sha256");
7640 #ifdef WOLFSSL_SHA384
7642 const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void)
7644 static const char* type = "SHA384";
7645 WOLFSSL_ENTER("EVP_sha384");
7649 #endif /* WOLFSSL_SHA384 */
7651 #ifdef WOLFSSL_SHA512
7653 const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void)
7655 static const char* type = "SHA512";
7656 WOLFSSL_ENTER("EVP_sha512");
7660 #endif /* WOLFSSL_SHA512 */
7663 void wolfSSL_EVP_MD_CTX_init(WOLFSSL_EVP_MD_CTX* ctx)
7665 WOLFSSL_ENTER("EVP_CIPHER_MD_CTX_init");
7671 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void)
7673 static const char* type = "AES128-CBC";
7674 WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cbc");
7679 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void)
7681 static const char* type = "AES192-CBC";
7682 WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cbc");
7687 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void)
7689 static const char* type = "AES256-CBC";
7690 WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cbc");
7695 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void)
7697 static const char* type = "AES128-CTR";
7698 WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ctr");
7703 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void)
7705 static const char* type = "AES192-CTR";
7706 WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ctr");
7711 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void)
7713 static const char* type = "AES256-CTR";
7714 WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ctr");
7719 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void)
7721 static const char* type = "DES-CBC";
7722 WOLFSSL_ENTER("wolfSSL_EVP_des_cbc");
7727 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void)
7729 static const char* type = "DES-EDE3-CBC";
7730 WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_cbc");
7735 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc4(void)
7737 static const char* type = "ARC4";
7738 WOLFSSL_ENTER("wolfSSL_EVP_rc4");
7743 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void)
7745 static const char* type = "NULL";
7746 WOLFSSL_ENTER("wolfSSL_EVP_enc_null");
7751 int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx)
7753 WOLFSSL_ENTER("EVP_MD_CTX_cleanup");
7760 void wolfSSL_EVP_CIPHER_CTX_init(WOLFSSL_EVP_CIPHER_CTX* ctx)
7762 WOLFSSL_ENTER("EVP_CIPHER_CTX_init");
7764 ctx->cipherType = 0xff; /* no init */
7766 ctx->enc = 1; /* start in encrypt mode */
7771 /* SSL_SUCCESS on ok */
7772 int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx)
7774 WOLFSSL_ENTER("EVP_CIPHER_CTX_cleanup");
7776 ctx->cipherType = 0xff; /* no more init */
7784 /* SSL_SUCCESS on ok */
7785 int wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
7786 const WOLFSSL_EVP_CIPHER* type, byte* key,
7789 #if defined(NO_AES) && defined(NO_DES3)
7796 WOLFSSL_ENTER("wolfSSL_EVP_CipherInit");
7798 WOLFSSL_MSG("no ctx");
7799 return 0; /* failure */
7802 if (type == NULL && ctx->cipherType == 0xff) {
7803 WOLFSSL_MSG("no type set");
7804 return 0; /* failure */
7808 if (ctx->cipherType == AES_128_CBC_TYPE || (type &&
7809 XSTRNCMP(type, "AES128-CBC", 10) == 0)) {
7810 WOLFSSL_MSG("AES-128-CBC");
7811 ctx->cipherType = AES_128_CBC_TYPE;
7813 if (enc == 0 || enc == 1)
7814 ctx->enc = enc ? 1 : 0;
7816 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
7817 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
7821 if (iv && key == NULL) {
7822 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
7827 else if (ctx->cipherType == AES_192_CBC_TYPE || (type &&
7828 XSTRNCMP(type, "AES192-CBC", 10) == 0)) {
7829 WOLFSSL_MSG("AES-192-CBC");
7830 ctx->cipherType = AES_192_CBC_TYPE;
7832 if (enc == 0 || enc == 1)
7833 ctx->enc = enc ? 1 : 0;
7835 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
7836 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
7840 if (iv && key == NULL) {
7841 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
7846 else if (ctx->cipherType == AES_256_CBC_TYPE || (type &&
7847 XSTRNCMP(type, "AES256-CBC", 10) == 0)) {
7848 WOLFSSL_MSG("AES-256-CBC");
7849 ctx->cipherType = AES_256_CBC_TYPE;
7851 if (enc == 0 || enc == 1)
7852 ctx->enc = enc ? 1 : 0;
7854 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
7855 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
7859 if (iv && key == NULL) {
7860 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
7865 #ifdef WOLFSSL_AES_COUNTER
7866 else if (ctx->cipherType == AES_128_CTR_TYPE || (type &&
7867 XSTRNCMP(type, "AES128-CTR", 10) == 0)) {
7868 WOLFSSL_MSG("AES-128-CTR");
7869 ctx->cipherType = AES_128_CTR_TYPE;
7871 if (enc == 0 || enc == 1)
7872 ctx->enc = enc ? 1 : 0;
7874 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
7879 if (iv && key == NULL) {
7880 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
7885 else if (ctx->cipherType == AES_192_CTR_TYPE || (type &&
7886 XSTRNCMP(type, "AES192-CTR", 10) == 0)) {
7887 WOLFSSL_MSG("AES-192-CTR");
7888 ctx->cipherType = AES_192_CTR_TYPE;
7890 if (enc == 0 || enc == 1)
7891 ctx->enc = enc ? 1 : 0;
7893 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
7898 if (iv && key == NULL) {
7899 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
7904 else if (ctx->cipherType == AES_256_CTR_TYPE || (type &&
7905 XSTRNCMP(type, "AES256-CTR", 10) == 0)) {
7906 WOLFSSL_MSG("AES-256-CTR");
7907 ctx->cipherType = AES_256_CTR_TYPE;
7909 if (enc == 0 || enc == 1)
7910 ctx->enc = enc ? 1 : 0;
7912 ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
7917 if (iv && key == NULL) {
7918 ret = wc_AesSetIV(&ctx->cipher.aes, iv);
7923 #endif /* WOLFSSL_AES_CTR */
7927 else if (ctx->cipherType == DES_CBC_TYPE || (type &&
7928 XSTRNCMP(type, "DES-CBC", 7) == 0)) {
7929 WOLFSSL_MSG("DES-CBC");
7930 ctx->cipherType = DES_CBC_TYPE;
7932 if (enc == 0 || enc == 1)
7933 ctx->enc = enc ? 1 : 0;
7935 ret = wc_Des_SetKey(&ctx->cipher.des, key, iv,
7936 ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
7941 if (iv && key == NULL)
7942 wc_Des_SetIV(&ctx->cipher.des, iv);
7944 else if (ctx->cipherType == DES_EDE3_CBC_TYPE || (type &&
7945 XSTRNCMP(type, "DES-EDE3-CBC", 11) == 0)) {
7946 WOLFSSL_MSG("DES-EDE3-CBC");
7947 ctx->cipherType = DES_EDE3_CBC_TYPE;
7949 if (enc == 0 || enc == 1)
7950 ctx->enc = enc ? 1 : 0;
7952 ret = wc_Des3_SetKey(&ctx->cipher.des3, key, iv,
7953 ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
7958 if (iv && key == NULL) {
7959 ret = wc_Des3_SetIV(&ctx->cipher.des3, iv);
7964 #endif /* NO_DES3 */
7966 else if (ctx->cipherType == ARC4_TYPE || (type &&
7967 XSTRNCMP(type, "ARC4", 4) == 0)) {
7968 WOLFSSL_MSG("ARC4");
7969 ctx->cipherType = ARC4_TYPE;
7970 if (ctx->keyLen == 0) /* user may have already set */
7971 ctx->keyLen = 16; /* default to 128 */
7973 wc_Arc4SetKey(&ctx->cipher.arc4, key, ctx->keyLen);
7976 else if (ctx->cipherType == NULL_CIPHER_TYPE || (type &&
7977 XSTRNCMP(type, "NULL", 4) == 0)) {
7978 WOLFSSL_MSG("NULL cipher");
7979 ctx->cipherType = NULL_CIPHER_TYPE;
7983 return 0; /* failure */
7990 /* SSL_SUCCESS on ok */
7991 int wolfSSL_EVP_CIPHER_CTX_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx)
7993 WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_key_length");
7997 return 0; /* failure */
8001 /* SSL_SUCCESS on ok */
8002 int wolfSSL_EVP_CIPHER_CTX_set_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx,
8005 WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_set_key_length");
8007 ctx->keyLen = keylen;
8009 return 0; /* failure */
8015 /* SSL_SUCCESS on ok */
8016 int wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* dst, byte* src,
8020 WOLFSSL_ENTER("wolfSSL_EVP_Cipher");
8022 if (ctx == NULL || dst == NULL || src == NULL) {
8023 WOLFSSL_MSG("Bad function argument");
8024 return 0; /* failure */
8027 if (ctx->cipherType == 0xff) {
8028 WOLFSSL_MSG("no init");
8029 return 0; /* failure */
8032 switch (ctx->cipherType) {
8035 case AES_128_CBC_TYPE :
8036 case AES_192_CBC_TYPE :
8037 case AES_256_CBC_TYPE :
8038 WOLFSSL_MSG("AES CBC");
8040 ret = wc_AesCbcEncrypt(&ctx->cipher.aes, dst, src, len);
8042 ret = wc_AesCbcDecrypt(&ctx->cipher.aes, dst, src, len);
8045 #ifdef WOLFSSL_AES_COUNTER
8046 case AES_128_CTR_TYPE :
8047 case AES_192_CTR_TYPE :
8048 case AES_256_CTR_TYPE :
8049 WOLFSSL_MSG("AES CTR");
8050 wc_AesCtrEncrypt(&ctx->cipher.aes, dst, src, len);
8058 wc_Des_CbcEncrypt(&ctx->cipher.des, dst, src, len);
8060 wc_Des_CbcDecrypt(&ctx->cipher.des, dst, src, len);
8063 case DES_EDE3_CBC_TYPE :
8065 ret = wc_Des3_CbcEncrypt(&ctx->cipher.des3, dst, src, len);
8067 ret = wc_Des3_CbcDecrypt(&ctx->cipher.des3, dst, src, len);
8073 wc_Arc4Process(&ctx->cipher.arc4, dst, src, len);
8077 case NULL_CIPHER_TYPE :
8078 XMEMCPY(dst, src, len);
8082 WOLFSSL_MSG("bad type");
8083 return 0; /* failure */
8088 WOLFSSL_MSG("wolfSSL_EVP_Cipher failure");
8089 return 0; /* failuer */
8092 WOLFSSL_MSG("wolfSSL_EVP_Cipher success");
8093 return SSL_SUCCESS; /* success */
8097 /* store for external read of iv, SSL_SUCCESS on success */
8098 int wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
8100 WOLFSSL_ENTER("wolfSSL_StoreExternalIV");
8103 WOLFSSL_MSG("Bad function argument");
8104 return SSL_FATAL_ERROR;
8107 switch (ctx->cipherType) {
8110 case AES_128_CBC_TYPE :
8111 case AES_192_CBC_TYPE :
8112 case AES_256_CBC_TYPE :
8113 WOLFSSL_MSG("AES CBC");
8114 memcpy(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
8117 #ifdef WOLFSSL_AES_COUNTER
8118 case AES_128_CTR_TYPE :
8119 case AES_192_CTR_TYPE :
8120 case AES_256_CTR_TYPE :
8121 WOLFSSL_MSG("AES CTR");
8122 memcpy(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
8124 #endif /* WOLFSSL_AES_COUNTER */
8130 WOLFSSL_MSG("DES CBC");
8131 memcpy(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
8134 case DES_EDE3_CBC_TYPE :
8135 WOLFSSL_MSG("DES EDE3 CBC");
8136 memcpy(ctx->iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
8141 WOLFSSL_MSG("ARC4");
8144 case NULL_CIPHER_TYPE :
8145 WOLFSSL_MSG("NULL");
8149 WOLFSSL_MSG("bad type");
8150 return SSL_FATAL_ERROR;
8157 /* set internal IV from external, SSL_SUCCESS on success */
8158 int wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
8161 WOLFSSL_ENTER("wolfSSL_SetInternalIV");
8164 WOLFSSL_MSG("Bad function argument");
8165 return SSL_FATAL_ERROR;
8168 switch (ctx->cipherType) {
8171 case AES_128_CBC_TYPE :
8172 case AES_192_CBC_TYPE :
8173 case AES_256_CBC_TYPE :
8174 WOLFSSL_MSG("AES CBC");
8175 memcpy(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
8178 #ifdef WOLFSSL_AES_COUNTER
8179 case AES_128_CTR_TYPE :
8180 case AES_192_CTR_TYPE :
8181 case AES_256_CTR_TYPE :
8182 WOLFSSL_MSG("AES CTR");
8183 memcpy(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
8191 WOLFSSL_MSG("DES CBC");
8192 memcpy(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
8195 case DES_EDE3_CBC_TYPE :
8196 WOLFSSL_MSG("DES EDE3 CBC");
8197 memcpy(&ctx->cipher.des3.reg, ctx->iv, DES_BLOCK_SIZE);
8202 WOLFSSL_MSG("ARC4");
8205 case NULL_CIPHER_TYPE :
8206 WOLFSSL_MSG("NULL");
8210 WOLFSSL_MSG("bad type");
8211 return SSL_FATAL_ERROR;
8218 /* SSL_SUCCESS on ok */
8219 int wolfSSL_EVP_DigestInit(WOLFSSL_EVP_MD_CTX* ctx, const WOLFSSL_EVP_MD* type)
8221 WOLFSSL_ENTER("EVP_DigestInit");
8222 if (XSTRNCMP(type, "SHA256", 6) == 0) {
8223 ctx->macType = SHA256;
8224 wolfSSL_SHA256_Init((SHA256_CTX*)&ctx->hash);
8226 #ifdef WOLFSSL_SHA384
8227 else if (XSTRNCMP(type, "SHA384", 6) == 0) {
8228 ctx->macType = SHA384;
8229 wolfSSL_SHA384_Init((SHA384_CTX*)&ctx->hash);
8232 #ifdef WOLFSSL_SHA512
8233 else if (XSTRNCMP(type, "SHA512", 6) == 0) {
8234 ctx->macType = SHA512;
8235 wolfSSL_SHA512_Init((SHA512_CTX*)&ctx->hash);
8239 else if (XSTRNCMP(type, "MD5", 3) == 0) {
8241 wolfSSL_MD5_Init((MD5_CTX*)&ctx->hash);
8245 /* has to be last since would pick or 256, 384, or 512 too */
8246 else if (XSTRNCMP(type, "SHA", 3) == 0) {
8248 wolfSSL_SHA_Init((SHA_CTX*)&ctx->hash);
8252 return BAD_FUNC_ARG;
8258 /* SSL_SUCCESS on ok */
8259 int wolfSSL_EVP_DigestUpdate(WOLFSSL_EVP_MD_CTX* ctx, const void* data,
8262 WOLFSSL_ENTER("EVP_DigestUpdate");
8264 switch (ctx->macType) {
8267 wolfSSL_MD5_Update((MD5_CTX*)&ctx->hash, data,
8273 wolfSSL_SHA_Update((SHA_CTX*)&ctx->hash, data,
8279 wolfSSL_SHA256_Update((SHA256_CTX*)&ctx->hash, data,
8283 #ifdef WOLFSSL_SHA384
8285 wolfSSL_SHA384_Update((SHA384_CTX*)&ctx->hash, data,
8289 #ifdef WOLFSSL_SHA512
8291 wolfSSL_SHA512_Update((SHA512_CTX*)&ctx->hash, data,
8296 return BAD_FUNC_ARG;
8303 /* SSL_SUCCESS on ok */
8304 int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md,
8307 WOLFSSL_ENTER("EVP_DigestFinal");
8308 switch (ctx->macType) {
8311 wolfSSL_MD5_Final(md, (MD5_CTX*)&ctx->hash);
8312 if (s) *s = MD5_DIGEST_SIZE;
8317 wolfSSL_SHA_Final(md, (SHA_CTX*)&ctx->hash);
8318 if (s) *s = SHA_DIGEST_SIZE;
8323 wolfSSL_SHA256_Final(md, (SHA256_CTX*)&ctx->hash);
8324 if (s) *s = SHA256_DIGEST_SIZE;
8327 #ifdef WOLFSSL_SHA384
8329 wolfSSL_SHA384_Final(md, (SHA384_CTX*)&ctx->hash);
8330 if (s) *s = SHA384_DIGEST_SIZE;
8333 #ifdef WOLFSSL_SHA512
8335 wolfSSL_SHA512_Final(md, (SHA512_CTX*)&ctx->hash);
8336 if (s) *s = SHA512_DIGEST_SIZE;
8340 return BAD_FUNC_ARG;
8347 /* SSL_SUCCESS on ok */
8348 int wolfSSL_EVP_DigestFinal_ex(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md,
8351 WOLFSSL_ENTER("EVP_DigestFinal_ex");
8352 return EVP_DigestFinal(ctx, md, s);
8356 unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, const void* key,
8357 int key_len, const unsigned char* d, int n,
8358 unsigned char* md, unsigned int* md_len)
8361 unsigned char* ret = NULL;
8362 #ifdef WOLFSSL_SMALL_STACK
8368 WOLFSSL_ENTER("HMAC");
8370 return NULL; /* no static buffer support */
8372 if (XSTRNCMP(evp_md, "MD5", 3) == 0)
8374 else if (XSTRNCMP(evp_md, "SHA", 3) == 0)
8379 #ifdef WOLFSSL_SMALL_STACK
8380 hmac = (Hmac*)XMALLOC(sizeof(Hmac), NULL, DYNAMIC_TYPE_TMP_BUFFER);
8385 if (wc_HmacSetKey(hmac, type, (const byte*)key, key_len) == 0)
8386 if (wc_HmacUpdate(hmac, d, n) == 0)
8387 if (wc_HmacFinal(hmac, md) == 0) {
8389 *md_len = (type == MD5) ? (int)MD5_DIGEST_SIZE
8390 : (int)SHA_DIGEST_SIZE;
8394 #ifdef WOLFSSL_SMALL_STACK
8395 XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8401 void wolfSSL_ERR_clear_error(void)
8407 int wolfSSL_RAND_status(void)
8409 return SSL_SUCCESS; /* wolfCrypt provides enough seed internally */
8414 void wolfSSL_RAND_add(const void* add, int len, double entropy)
8420 /* wolfSSL seeds/adds internally, use explicit RNG if you want
8426 /* SSL_SUCCESS on ok */
8427 int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key,
8428 WOLFSSL_DES_key_schedule* schedule)
8430 WOLFSSL_ENTER("DES_key_sched");
8431 XMEMCPY(schedule, key, sizeof(const_DES_cblock));
8436 void wolfSSL_DES_cbc_encrypt(const unsigned char* input,
8437 unsigned char* output, long length,
8438 WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec,
8443 WOLFSSL_ENTER("DES_cbc_encrypt");
8445 /* OpenSSL compat, no ret */
8446 wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
8449 wc_Des_CbcEncrypt(&myDes, output, input, (word32)length);
8451 wc_Des_CbcDecrypt(&myDes, output, input, (word32)length);
8455 /* correctly sets ivec for next call */
8456 void wolfSSL_DES_ncbc_encrypt(const unsigned char* input,
8457 unsigned char* output, long length,
8458 WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec,
8463 WOLFSSL_ENTER("DES_ncbc_encrypt");
8465 /* OpenSSL compat, no ret */
8466 wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
8469 wc_Des_CbcEncrypt(&myDes, output, input, (word32)length);
8471 wc_Des_CbcDecrypt(&myDes, output, input, (word32)length);
8473 XMEMCPY(ivec, output + length - sizeof(DES_cblock), sizeof(DES_cblock));
8476 #endif /* NO_DES3 */
8479 void wolfSSL_ERR_free_strings(void)
8481 /* handled internally */
8485 void wolfSSL_ERR_remove_state(unsigned long state)
8487 /* TODO: GetErrors().Remove(); */
8492 void wolfSSL_EVP_cleanup(void)
8494 /* nothing to do here */
8498 void wolfSSL_cleanup_all_ex_data(void)
8500 /* nothing to do here */
8504 int wolfSSL_clear(WOLFSSL* ssl)
8507 /* TODO: GetErrors().Remove(); */
8512 long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t)
8516 return BAD_FUNC_ARG;
8518 tmptime = t & 0xFFFFFFFF;
8520 ses->timeout = tmptime;
8526 long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode)
8528 /* SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
8530 WOLFSSL_ENTER("SSL_CTX_set_mode");
8531 if (mode == SSL_MODE_ENABLE_PARTIAL_WRITE)
8532 ctx->partialWrite = 1;
8538 long wolfSSL_SSL_get_mode(WOLFSSL* ssl)
8546 long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx)
8554 void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m)
8562 int wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX* ctx,
8563 const unsigned char* sid_ctx,
8564 unsigned int sid_ctx_len)
8566 /* No application specific context needed for wolfSSL */
8574 long wolfSSL_CTX_sess_get_cache_size(WOLFSSL_CTX* ctx)
8581 unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line,
8582 const char** data, int *flags)
8584 /* Not implemented */
8592 #endif /* OPENSSL_EXTRA */
8595 #if defined(KEEP_PEER_CERT)
8597 WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl)
8599 WOLFSSL_ENTER("SSL_get_peer_certificate");
8600 if (ssl->peerCert.issuer.sz)
8601 return &ssl->peerCert;
8606 #endif /* KEEP_PEER_CERT */
8609 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
8611 void wolfSSL_FreeX509(WOLFSSL_X509* x509)
8613 WOLFSSL_ENTER("wolfSSL_FreeX509");
8618 /* return the next, if any, altname from the peer cert */
8619 char* wolfSSL_X509_get_next_altname(WOLFSSL_X509* cert)
8622 WOLFSSL_ENTER("wolfSSL_X509_get_next_altname");
8624 /* don't have any to work with */
8625 if (cert == NULL || cert->altNames == NULL)
8628 /* already went through them */
8629 if (cert->altNamesNext == NULL)
8632 ret = cert->altNamesNext->name;
8633 cert->altNamesNext = cert->altNamesNext->next;
8639 WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509* cert)
8641 WOLFSSL_ENTER("X509_get_issuer_name");
8642 return &cert->issuer;
8646 WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
8648 WOLFSSL_ENTER("X509_get_subject_name");
8649 return &cert->subject;
8653 int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509)
8657 WOLFSSL_ENTER("wolfSSL_X509_get_isCA");
8662 WOLFSSL_LEAVE("wolfSSL_X509_get_isCA", isCA);
8668 #ifdef OPENSSL_EXTRA
8669 int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509* x509, int nid)
8673 WOLFSSL_ENTER("wolfSSL_X509_ext_isSet_by_NID");
8677 case BASIC_CA_OID: isSet = x509->basicConstSet; break;
8678 case ALT_NAMES_OID: isSet = x509->subjAltNameSet; break;
8679 case AUTH_KEY_OID: isSet = x509->authKeyIdSet; break;
8680 case SUBJ_KEY_OID: isSet = x509->subjKeyIdSet; break;
8681 case KEY_USAGE_OID: isSet = x509->keyUsageSet; break;
8683 case CERT_POLICY_OID: isSet = x509->certPolicySet; break;
8684 #endif /* WOLFSSL_SEP */
8688 WOLFSSL_LEAVE("wolfSSL_X509_ext_isSet_by_NID", isSet);
8694 int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509* x509, int nid)
8698 WOLFSSL_ENTER("wolfSSL_X509_ext_get_critical_by_NID");
8702 case BASIC_CA_OID: crit = x509->basicConstCrit; break;
8703 case ALT_NAMES_OID: crit = x509->subjAltNameCrit; break;
8704 case AUTH_KEY_OID: crit = x509->authKeyIdCrit; break;
8705 case SUBJ_KEY_OID: crit = x509->subjKeyIdCrit; break;
8706 case KEY_USAGE_OID: crit = x509->keyUsageCrit; break;
8708 case CERT_POLICY_OID: crit = x509->certPolicyCrit; break;
8709 #endif /* WOLFSSL_SEP */
8713 WOLFSSL_LEAVE("wolfSSL_X509_ext_get_critical_by_NID", crit);
8719 int wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509* x509)
8723 WOLFSSL_ENTER("wolfSSL_X509_get_isSet_pathLength");
8726 isSet = x509->basicConstPlSet;
8728 WOLFSSL_LEAVE("wolfSSL_X509_get_isSet_pathLength", isSet);
8734 word32 wolfSSL_X509_get_pathLength(WOLFSSL_X509* x509)
8736 word32 pathLength = 0;
8738 WOLFSSL_ENTER("wolfSSL_X509_get_pathLength");
8741 pathLength = x509->pathLength;
8743 WOLFSSL_LEAVE("wolfSSL_X509_get_pathLength", pathLength);
8749 unsigned int wolfSSL_X509_get_keyUsage(WOLFSSL_X509* x509)
8753 WOLFSSL_ENTER("wolfSSL_X509_get_keyUsage");
8756 usage = x509->keyUsage;
8758 WOLFSSL_LEAVE("wolfSSL_X509_get_keyUsage", usage);
8764 byte* wolfSSL_X509_get_authorityKeyID(
8765 WOLFSSL_X509* x509, byte* dst, int* dstLen)
8770 WOLFSSL_ENTER("wolfSSL_X509_get_authorityKeyID");
8773 if (x509->authKeyIdSet) {
8774 copySz = min(dstLen != NULL ? *dstLen : 0,
8775 (int)x509->authKeyIdSz);
8776 id = x509->authKeyId;
8779 if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
8780 XMEMCPY(dst, id, copySz);
8786 WOLFSSL_LEAVE("wolfSSL_X509_get_authorityKeyID", copySz);
8792 byte* wolfSSL_X509_get_subjectKeyID(
8793 WOLFSSL_X509* x509, byte* dst, int* dstLen)
8798 WOLFSSL_ENTER("wolfSSL_X509_get_subjectKeyID");
8801 if (x509->subjKeyIdSet) {
8802 copySz = min(dstLen != NULL ? *dstLen : 0,
8803 (int)x509->subjKeyIdSz);
8804 id = x509->subjKeyId;
8807 if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
8808 XMEMCPY(dst, id, copySz);
8814 WOLFSSL_LEAVE("wolfSSL_X509_get_subjectKeyID", copySz);
8820 int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME* name)
8824 WOLFSSL_ENTER("wolfSSL_X509_NAME_entry_count");
8827 count = name->fullName.entryCount;
8829 WOLFSSL_LEAVE("wolfSSL_X509_NAME_entry_count", count);
8834 int wolfSSL_X509_NAME_get_text_by_NID(WOLFSSL_X509_NAME* name,
8835 int nid, char* buf, int len)
8840 WOLFSSL_ENTER("wolfSSL_X509_NAME_get_text_by_NID");
8843 case ASN_COMMON_NAME:
8844 text = name->fullName.fullName + name->fullName.cnIdx;
8845 textSz = name->fullName.cnLen;
8848 text = name->fullName.fullName + name->fullName.snIdx;
8849 textSz = name->fullName.snLen;
8851 case ASN_SERIAL_NUMBER:
8852 text = name->fullName.fullName + name->fullName.serialIdx;
8853 textSz = name->fullName.serialLen;
8855 case ASN_COUNTRY_NAME:
8856 text = name->fullName.fullName + name->fullName.cIdx;
8857 textSz = name->fullName.cLen;
8859 case ASN_LOCALITY_NAME:
8860 text = name->fullName.fullName + name->fullName.lIdx;
8861 textSz = name->fullName.lLen;
8863 case ASN_STATE_NAME:
8864 text = name->fullName.fullName + name->fullName.stIdx;
8865 textSz = name->fullName.stLen;
8868 text = name->fullName.fullName + name->fullName.oIdx;
8869 textSz = name->fullName.oLen;
8871 case ASN_ORGUNIT_NAME:
8872 text = name->fullName.fullName + name->fullName.ouIdx;
8873 textSz = name->fullName.ouLen;
8879 if (buf != NULL && text != NULL) {
8880 textSz = min(textSz, len);
8881 XMEMCPY(buf, text, textSz);
8885 WOLFSSL_LEAVE("wolfSSL_X509_NAME_get_text_by_NID", textSz);
8891 /* copy name into in buffer, at most sz bytes, if buffer is null will
8892 malloc buffer, call responsible for freeing */
8893 char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
8895 int copySz = min(sz, name->sz);
8897 WOLFSSL_ENTER("wolfSSL_X509_NAME_oneline");
8898 if (!name->sz) return in;
8901 in = (char*)XMALLOC(name->sz, 0, DYNAMIC_TYPE_OPENSSL);
8902 if (!in ) return in;
8909 XMEMCPY(in, name->name, copySz - 1);
8916 int wolfSSL_X509_get_signature_type(WOLFSSL_X509* x509)
8920 WOLFSSL_ENTER("wolfSSL_X509_get_signature_type");
8923 type = x509->sigOID;
8929 int wolfSSL_X509_get_signature(WOLFSSL_X509* x509,
8930 unsigned char* buf, int* bufSz)
8932 WOLFSSL_ENTER("wolfSSL_X509_get_signature");
8933 if (x509 == NULL || bufSz == NULL || *bufSz < (int)x509->sig.length)
8934 return SSL_FATAL_ERROR;
8937 XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
8938 *bufSz = x509->sig.length;
8944 /* write X509 serial number in unsigned binary to buffer
8945 buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
8946 return SSL_SUCCESS on success */
8947 int wolfSSL_X509_get_serial_number(WOLFSSL_X509* x509, byte* in, int* inOutSz)
8949 WOLFSSL_ENTER("wolfSSL_X509_get_serial_number");
8950 if (x509 == NULL || in == NULL ||
8951 inOutSz == NULL || *inOutSz < x509->serialSz)
8952 return BAD_FUNC_ARG;
8954 XMEMCPY(in, x509->serial, x509->serialSz);
8955 *inOutSz = x509->serialSz;
8961 const byte* wolfSSL_X509_get_der(WOLFSSL_X509* x509, int* outSz)
8963 WOLFSSL_ENTER("wolfSSL_X509_get_der");
8965 if (x509 == NULL || outSz == NULL)
8968 *outSz = (int)x509->derCert.length;
8969 return x509->derCert.buffer;
8973 int wolfSSL_X509_version(WOLFSSL_X509* x509)
8975 WOLFSSL_ENTER("wolfSSL_X509_version");
8980 return x509->version;
8984 const byte* wolfSSL_X509_notBefore(WOLFSSL_X509* x509)
8986 WOLFSSL_ENTER("wolfSSL_X509_notBefore");
8991 return x509->notBefore;
8995 const byte* wolfSSL_X509_notAfter(WOLFSSL_X509* x509)
8997 WOLFSSL_ENTER("wolfSSL_X509_notAfter");
9002 return x509->notAfter;
9008 /* copy oid into in buffer, at most *inOutSz bytes, if buffer is null will
9009 malloc buffer, call responsible for freeing. Actual size returned in
9010 *inOutSz. Requires inOutSz be non-null */
9011 byte* wolfSSL_X509_get_device_type(WOLFSSL_X509* x509, byte* in, int *inOutSz)
9015 WOLFSSL_ENTER("wolfSSL_X509_get_dev_type");
9016 if (inOutSz == NULL) return NULL;
9017 if (!x509->deviceTypeSz) return in;
9019 copySz = min(*inOutSz, x509->deviceTypeSz);
9022 in = (byte*)XMALLOC(x509->deviceTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
9024 copySz = x509->deviceTypeSz;
9027 XMEMCPY(in, x509->deviceType, copySz);
9034 byte* wolfSSL_X509_get_hw_type(WOLFSSL_X509* x509, byte* in, int* inOutSz)
9038 WOLFSSL_ENTER("wolfSSL_X509_get_hw_type");
9039 if (inOutSz == NULL) return NULL;
9040 if (!x509->hwTypeSz) return in;
9042 copySz = min(*inOutSz, x509->hwTypeSz);
9045 in = (byte*)XMALLOC(x509->hwTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
9047 copySz = x509->hwTypeSz;
9050 XMEMCPY(in, x509->hwType, copySz);
9057 byte* wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509* x509,byte* in,int* inOutSz)
9061 WOLFSSL_ENTER("wolfSSL_X509_get_hw_serial_number");
9062 if (inOutSz == NULL) return NULL;
9063 if (!x509->hwTypeSz) return in;
9065 copySz = min(*inOutSz, x509->hwSerialNumSz);
9068 in = (byte*)XMALLOC(x509->hwSerialNumSz, 0, DYNAMIC_TYPE_OPENSSL);
9070 copySz = x509->hwSerialNumSz;
9073 XMEMCPY(in, x509->hwSerialNum, copySz);
9079 #endif /* WOLFSSL_SEP */
9082 WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
9084 WOLFSSL_X509 *newX509 = NULL;
9086 WOLFSSL_ENTER("wolfSSL_X509_d2i");
9088 if (in != NULL && len != 0) {
9089 #ifdef WOLFSSL_SMALL_STACK
9090 DecodedCert* cert = NULL;
9092 DecodedCert cert[1];
9095 #ifdef WOLFSSL_SMALL_STACK
9096 cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
9097 DYNAMIC_TYPE_TMP_BUFFER);
9102 InitDecodedCert(cert, (byte*)in, len, NULL);
9103 if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
9104 newX509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509),
9105 NULL, DYNAMIC_TYPE_X509);
9106 if (newX509 != NULL) {
9107 InitX509(newX509, 1);
9108 if (CopyDecodedToX509(newX509, cert) != 0) {
9109 XFREE(newX509, NULL, DYNAMIC_TYPE_X509);
9114 FreeDecodedCert(cert);
9115 #ifdef WOLFSSL_SMALL_STACK
9116 XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9127 #ifndef NO_FILESYSTEM
9129 #ifndef NO_STDIO_FILESYSTEM
9131 WOLFSSL_X509* wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file)
9133 WOLFSSL_X509* newX509 = NULL;
9135 WOLFSSL_ENTER("wolfSSL_X509_d2i_fp");
9137 if (file != XBADFILE) {
9138 byte* fileBuffer = NULL;
9141 XFSEEK(file, 0, XSEEK_END);
9146 WOLFSSL_MSG("Bad tell on FILE");
9150 fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
9151 if (fileBuffer != NULL) {
9152 int ret = (int)XFREAD(fileBuffer, sz, 1, file);
9154 newX509 = wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
9156 XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
9166 #endif /* NO_STDIO_FILESYSTEM */
9168 WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format)
9170 #ifdef WOLFSSL_SMALL_STACK
9171 byte staticBuffer[1]; /* force heap usage */
9173 byte staticBuffer[FILE_BUFFER_SIZE];
9175 byte* fileBuffer = staticBuffer;
9181 WOLFSSL_X509* x509 = NULL;
9184 WOLFSSL_ENTER("wolfSSL_X509_load_certificate");
9186 /* Check the inputs */
9187 if ((fname == NULL) ||
9188 (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM))
9191 file = XFOPEN(fname, "rb");
9192 if (file == XBADFILE)
9195 XFSEEK(file, 0, XSEEK_END);
9199 if (sz > (long)sizeof(staticBuffer)) {
9200 fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
9201 if (fileBuffer == NULL) {
9212 ret = (int)XFREAD(fileBuffer, sz, 1, file);
9216 XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
9225 if (format == SSL_FILETYPE_PEM) {
9227 #ifdef WOLFSSL_SMALL_STACK
9228 EncryptedInfo* info = NULL;
9230 EncryptedInfo info[1];
9233 #ifdef WOLFSSL_SMALL_STACK
9234 info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
9235 DYNAMIC_TYPE_TMP_BUFFER);
9238 XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
9248 if (PemToDer(fileBuffer, sz, CERT_TYPE, &der, NULL, info, &ecc) != 0)
9250 /* Only time this should fail, and leave `der` with a buffer
9251 is when the Base64 Decode fails. Release `der.buffer` in
9253 if (der.buffer != NULL) {
9254 XFREE(der.buffer, NULL, DYNAMIC_TYPE_CERT);
9259 #ifdef WOLFSSL_SMALL_STACK
9260 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9264 der.buffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_CERT);
9265 if (der.buffer != NULL) {
9266 XMEMCPY(der.buffer, fileBuffer, sz);
9267 der.length = (word32)sz;
9272 XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
9274 /* At this point we want `der` to have the certificate in DER format */
9275 /* ready to be decoded. */
9276 if (der.buffer != NULL) {
9277 #ifdef WOLFSSL_SMALL_STACK
9278 DecodedCert* cert = NULL;
9280 DecodedCert cert[1];
9283 #ifdef WOLFSSL_SMALL_STACK
9284 cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
9285 DYNAMIC_TYPE_TMP_BUFFER);
9289 InitDecodedCert(cert, der.buffer, der.length, NULL);
9290 if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
9291 x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
9295 if (CopyDecodedToX509(x509, cert) != 0) {
9296 XFREE(x509, NULL, DYNAMIC_TYPE_X509);
9302 FreeDecodedCert(cert);
9303 #ifdef WOLFSSL_SMALL_STACK
9304 XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9308 XFREE(der.buffer, NULL, DYNAMIC_TYPE_CERT);
9314 #endif /* NO_FILESYSTEM */
9316 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
9319 #ifdef OPENSSL_EXTRA
9320 int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data)
9323 if (ssl != NULL && idx < MAX_EX_DATA)
9325 ssl->ex_data[idx] = data;
9337 int wolfSSL_set_session_id_context(WOLFSSL* ssl, const unsigned char* id,
9347 void wolfSSL_set_connect_state(WOLFSSL* ssl)
9350 /* client by default */
9354 int wolfSSL_get_shutdown(const WOLFSSL* ssl)
9356 return (ssl->options.isClosed ||
9357 ssl->options.connReset ||
9358 ssl->options.sentNotify);
9362 int wolfSSL_session_reused(WOLFSSL* ssl)
9364 return ssl->options.resuming;
9367 #ifdef OPENSSL_EXTRA
9368 void wolfSSL_SESSION_free(WOLFSSL_SESSION* session)
9374 const char* wolfSSL_get_version(WOLFSSL* ssl)
9376 WOLFSSL_ENTER("SSL_get_version");
9377 if (ssl->version.major == SSLv3_MAJOR) {
9378 switch (ssl->version.minor) {
9383 case TLSv1_1_MINOR :
9385 case TLSv1_2_MINOR :
9391 else if (ssl->version.major == DTLS_MAJOR) {
9392 switch (ssl->version.minor) {
9395 case DTLSv1_2_MINOR :
9405 /* current library version */
9406 const char* wolfSSL_lib_version(void)
9408 return LIBWOLFSSL_VERSION_STRING;
9412 /* current library version in hex */
9413 word32 wolfSSL_lib_version_hex(void)
9415 return LIBWOLFSSL_VERSION_HEX;
9419 int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl)
9421 WOLFSSL_ENTER("SSL_get_current_cipher_suite");
9423 return (ssl->options.cipherSuite0 << 8) | ssl->options.cipherSuite;
9427 WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL* ssl)
9429 WOLFSSL_ENTER("SSL_get_current_cipher");
9431 return &ssl->cipher;
9437 const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher)
9441 WOLFSSL_ENTER("SSL_CIPHER_get_name");
9442 #ifndef NO_ERROR_STRINGS
9444 #if defined(HAVE_CHACHA)
9445 if (cipher->ssl->options.cipherSuite0 == CHACHA_BYTE) {
9447 switch (cipher->ssl->options.cipherSuite) {
9450 case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
9451 return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
9453 case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
9454 return "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
9456 case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
9457 return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
9463 #if defined(HAVE_ECC) || defined(HAVE_AESCCM)
9464 /* Awkwardly, the ECC cipher suites use the ECC_BYTE as expected,
9465 * but the AES-CCM cipher suites also use it, even the ones that
9467 if (cipher->ssl->options.cipherSuite0 == ECC_BYTE) {
9469 switch (cipher->ssl->options.cipherSuite) {
9472 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
9473 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
9475 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
9476 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
9478 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
9479 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
9481 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
9482 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
9484 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
9485 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
9487 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
9488 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
9490 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
9491 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
9493 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
9494 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
9497 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
9498 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
9499 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
9500 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
9502 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
9503 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
9504 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
9505 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
9508 case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
9509 return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
9511 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
9512 return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
9516 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
9517 return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
9519 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
9520 return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
9524 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
9525 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
9526 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
9527 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
9529 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
9530 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
9531 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
9532 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
9535 case TLS_ECDH_RSA_WITH_RC4_128_SHA :
9536 return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
9538 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
9539 return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
9543 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
9544 return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
9546 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
9547 return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
9553 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
9554 return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
9555 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
9556 return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
9558 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
9559 return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
9560 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
9561 return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
9563 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
9564 return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
9565 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
9566 return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
9568 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
9569 return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
9570 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
9571 return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
9573 #endif /* HAVE_ECC */
9577 case TLS_RSA_WITH_AES_128_CCM_8 :
9578 return "TLS_RSA_WITH_AES_128_CCM_8";
9579 case TLS_RSA_WITH_AES_256_CCM_8 :
9580 return "TLS_RSA_WITH_AES_256_CCM_8";
9583 case TLS_PSK_WITH_AES_128_CCM_8 :
9584 return "TLS_PSK_WITH_AES_128_CCM_8";
9585 case TLS_PSK_WITH_AES_256_CCM_8 :
9586 return "TLS_PSK_WITH_AES_256_CCM_8";
9587 case TLS_PSK_WITH_AES_128_CCM :
9588 return "TLS_PSK_WITH_AES_128_CCM";
9589 case TLS_PSK_WITH_AES_256_CCM :
9590 return "TLS_PSK_WITH_AES_256_CCM";
9591 case TLS_DHE_PSK_WITH_AES_128_CCM :
9592 return "TLS_DHE_PSK_WITH_AES_128_CCM";
9593 case TLS_DHE_PSK_WITH_AES_256_CCM :
9594 return "TLS_DHE_PSK_WITH_AES_256_CCM";
9597 case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
9598 return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8";
9599 case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
9600 return "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8";
9609 if (cipher->ssl->options.cipherSuite0 != ECC_BYTE &&
9610 cipher->ssl->options.cipherSuite0 != CHACHA_BYTE) {
9613 switch (cipher->ssl->options.cipherSuite) {
9617 case SSL_RSA_WITH_RC4_128_SHA :
9618 return "SSL_RSA_WITH_RC4_128_SHA";
9621 case SSL_RSA_WITH_RC4_128_MD5 :
9622 return "SSL_RSA_WITH_RC4_128_MD5";
9627 case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
9628 return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
9630 case TLS_RSA_WITH_AES_128_CBC_SHA :
9631 return "TLS_RSA_WITH_AES_128_CBC_SHA";
9632 case TLS_RSA_WITH_AES_256_CBC_SHA :
9633 return "TLS_RSA_WITH_AES_256_CBC_SHA";
9635 case TLS_RSA_WITH_AES_128_CBC_SHA256 :
9636 return "TLS_RSA_WITH_AES_128_CBC_SHA256";
9637 case TLS_RSA_WITH_AES_256_CBC_SHA256 :
9638 return "TLS_RSA_WITH_AES_256_CBC_SHA256";
9640 case TLS_RSA_WITH_AES_128_CBC_B2B256:
9641 return "TLS_RSA_WITH_AES_128_CBC_B2B256";
9642 case TLS_RSA_WITH_AES_256_CBC_B2B256:
9643 return "TLS_RSA_WITH_AES_256_CBC_B2B256";
9646 case TLS_RSA_WITH_NULL_SHA :
9647 return "TLS_RSA_WITH_NULL_SHA";
9649 case TLS_RSA_WITH_NULL_SHA256 :
9650 return "TLS_RSA_WITH_NULL_SHA256";
9654 case TLS_PSK_WITH_AES_128_CBC_SHA :
9655 return "TLS_PSK_WITH_AES_128_CBC_SHA";
9656 case TLS_PSK_WITH_AES_256_CBC_SHA :
9657 return "TLS_PSK_WITH_AES_256_CBC_SHA";
9660 case TLS_PSK_WITH_AES_128_CBC_SHA256 :
9661 return "TLS_PSK_WITH_AES_128_CBC_SHA256";
9662 case TLS_PSK_WITH_NULL_SHA256 :
9663 return "TLS_PSK_WITH_NULL_SHA256";
9664 case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 :
9665 return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
9666 case TLS_DHE_PSK_WITH_NULL_SHA256 :
9667 return "TLS_DHE_PSK_WITH_NULL_SHA256";
9669 case TLS_PSK_WITH_AES_128_GCM_SHA256 :
9670 return "TLS_PSK_WITH_AES_128_GCM_SHA256";
9671 case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 :
9672 return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
9675 #ifdef WOLFSSL_SHA384
9676 case TLS_PSK_WITH_AES_256_CBC_SHA384 :
9677 return "TLS_PSK_WITH_AES_256_CBC_SHA384";
9678 case TLS_PSK_WITH_NULL_SHA384 :
9679 return "TLS_PSK_WITH_NULL_SHA384";
9680 case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 :
9681 return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
9682 case TLS_DHE_PSK_WITH_NULL_SHA384 :
9683 return "TLS_DHE_PSK_WITH_NULL_SHA384";
9685 case TLS_PSK_WITH_AES_256_GCM_SHA384 :
9686 return "TLS_PSK_WITH_AES_256_GCM_SHA384";
9687 case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 :
9688 return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
9692 case TLS_PSK_WITH_NULL_SHA :
9693 return "TLS_PSK_WITH_NULL_SHA";
9697 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
9698 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
9699 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
9700 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
9702 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
9703 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
9704 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
9705 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
9709 case TLS_RSA_WITH_HC_128_MD5 :
9710 return "TLS_RSA_WITH_HC_128_MD5";
9713 case TLS_RSA_WITH_HC_128_SHA :
9714 return "TLS_RSA_WITH_HC_128_SHA";
9717 case TLS_RSA_WITH_HC_128_B2B256:
9718 return "TLS_RSA_WITH_HC_128_B2B256";
9720 #endif /* NO_HC128 */
9723 case TLS_RSA_WITH_RABBIT_SHA :
9724 return "TLS_RSA_WITH_RABBIT_SHA";
9728 case TLS_NTRU_RSA_WITH_RC4_128_SHA :
9729 return "TLS_NTRU_RSA_WITH_RC4_128_SHA";
9732 case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
9733 return "TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA";
9735 case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
9736 return "TLS_NTRU_RSA_WITH_AES_128_CBC_SHA";
9737 case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
9738 return "TLS_NTRU_RSA_WITH_AES_256_CBC_SHA";
9739 #endif /* HAVE_NTRU */
9741 case TLS_RSA_WITH_AES_128_GCM_SHA256 :
9742 return "TLS_RSA_WITH_AES_128_GCM_SHA256";
9743 case TLS_RSA_WITH_AES_256_GCM_SHA384 :
9744 return "TLS_RSA_WITH_AES_256_GCM_SHA384";
9745 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
9746 return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
9747 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
9748 return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
9750 case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
9751 return "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA";
9752 case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
9753 return "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA";
9755 case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
9756 return "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256";
9757 case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
9758 return "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256";
9760 case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
9761 return "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA";
9762 case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
9763 return "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA";
9765 case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
9766 return "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256";
9767 case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
9768 return "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256";
9770 #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
9771 case TLS_DH_anon_WITH_AES_128_CBC_SHA :
9772 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
9777 } /* normal / ECC */
9779 #endif /* NO_ERROR_STRINGS */
9784 const char* wolfSSL_get_cipher(WOLFSSL* ssl)
9786 WOLFSSL_ENTER("wolfSSL_get_cipher");
9787 return wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl));
9790 #ifdef OPENSSL_EXTRA
9794 char* wolfSSL_CIPHER_description(WOLFSSL_CIPHER* cipher, char* in, int len)
9803 WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl) /* what's ref count */
9810 void wolfSSL_X509_free(WOLFSSL_X509* buf)
9816 /* was do nothing */
9818 void OPENSSL_free(void* buf)
9825 int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, char** path,
9837 WOLFSSL_METHOD* wolfSSLv2_client_method(void)
9843 WOLFSSL_METHOD* wolfSSLv2_server_method(void)
9851 void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX* md4)
9853 /* make sure we have a big enough buffer */
9854 typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1];
9857 WOLFSSL_ENTER("MD4_Init");
9858 wc_InitMd4((Md4*)md4);
9862 void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX* md4, const void* data,
9865 WOLFSSL_ENTER("MD4_Update");
9866 wc_Md4Update((Md4*)md4, (const byte*)data, (word32)len);
9870 void wolfSSL_MD4_Final(unsigned char* digest, WOLFSSL_MD4_CTX* md4)
9872 WOLFSSL_ENTER("MD4_Final");
9873 wc_Md4Final((Md4*)md4, digest);
9879 WOLFSSL_BIO* wolfSSL_BIO_pop(WOLFSSL_BIO* top)
9886 int wolfSSL_BIO_pending(WOLFSSL_BIO* bio)
9894 WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_mem(void)
9896 static WOLFSSL_BIO_METHOD meth;
9898 WOLFSSL_ENTER("BIO_s_mem");
9899 meth.type = BIO_MEMORY;
9905 WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_base64(void)
9911 void wolfSSL_BIO_set_flags(WOLFSSL_BIO* bio, int flags)
9919 void wolfSSL_RAND_screen(void)
9925 const char* wolfSSL_RAND_file_name(char* fname, unsigned long len)
9933 int wolfSSL_RAND_write_file(const char* fname)
9940 int wolfSSL_RAND_load_file(const char* fname, long len)
9943 /* wolfCrypt provides enough entropy internally or will report error */
9951 int wolfSSL_RAND_egd(const char* path)
9959 WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void)
9965 WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void)
9971 int wolfSSL_COMP_add_compression_method(int method, void* data)
9980 int wolfSSL_get_ex_new_index(long idx, void* data, void* cb1, void* cb2,
9992 void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f)(
9999 void wolfSSL_set_dynlock_lock_callback(
10000 void (*f)(int, WOLFSSL_dynlock_value*, const char*, int))
10006 void wolfSSL_set_dynlock_destroy_callback(
10007 void (*f)(WOLFSSL_dynlock_value*, const char*, int))
10014 const char* wolfSSL_X509_verify_cert_error_string(long err)
10022 int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup, const char* dir,
10032 int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
10033 const char* file, long len)
10042 WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void)
10048 WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void)
10055 WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
10056 WOLFSSL_X509_LOOKUP_METHOD* m)
10064 int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509)
10066 int result = SSL_FATAL_ERROR;
10068 WOLFSSL_ENTER("wolfSSL_X509_STORE_add_cert");
10069 if (store != NULL && store->cm != NULL && x509 != NULL) {
10071 derCert.buffer = (byte*)XMALLOC(x509->derCert.length,
10072 NULL, DYNAMIC_TYPE_CERT);
10073 if (derCert.buffer != NULL) {
10074 derCert.length = x509->derCert.length;
10075 /* AddCA() frees the buffer. */
10076 XMEMCPY(derCert.buffer,
10077 x509->derCert.buffer, x509->derCert.length);
10078 result = AddCA(store->cm, derCert, WOLFSSL_USER_CA, 1);
10079 if (result != SSL_SUCCESS) result = SSL_FATAL_ERROR;
10083 WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_cert", result);
10088 WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void)
10090 WOLFSSL_X509_STORE* store = NULL;
10092 store = (WOLFSSL_X509_STORE*)XMALLOC(sizeof(WOLFSSL_X509_STORE), NULL, 0);
10093 if (store != NULL) {
10094 store->cm = wolfSSL_CertManagerNew();
10095 if (store->cm == NULL) {
10096 XFREE(store, NULL, 0);
10105 void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store)
10107 if (store != NULL) {
10108 if (store->cm != NULL)
10109 wolfSSL_CertManagerFree(store->cm);
10110 XFREE(store, NULL, 0);
10115 int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE* store)
10118 return SSL_SUCCESS;
10122 int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX* ctx, int idx,
10123 WOLFSSL_X509_NAME* name, WOLFSSL_X509_OBJECT* obj)
10133 WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new(void)
10135 WOLFSSL_X509_STORE_CTX* ctx = (WOLFSSL_X509_STORE_CTX*)XMALLOC(
10136 sizeof(WOLFSSL_X509_STORE_CTX), NULL, 0);
10139 wolfSSL_X509_STORE_CTX_init(ctx, NULL, NULL, NULL);
10145 int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
10146 WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509, STACK_OF(WOLFSSL_X509)* sk)
10150 ctx->store = store;
10151 ctx->current_cert = x509;
10152 ctx->domain = NULL;
10153 ctx->ex_data = NULL;
10154 ctx->userCtx = NULL;
10156 ctx->error_depth = 0;
10157 ctx->discardSessionCerts = 0;
10158 return SSL_SUCCESS;
10160 return SSL_FATAL_ERROR;
10164 void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx)
10167 if (ctx->store != NULL)
10168 wolfSSL_X509_STORE_free(ctx->store);
10169 if (ctx->current_cert != NULL)
10170 wolfSSL_FreeX509(ctx->current_cert);
10171 XFREE(ctx, NULL, 0);
10176 void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX* ctx)
10182 int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
10184 if (ctx != NULL && ctx->store != NULL && ctx->store->cm != NULL
10185 && ctx->current_cert != NULL) {
10186 return wolfSSL_CertManagerVerifyBuffer(ctx->store->cm,
10187 ctx->current_cert->derCert.buffer,
10188 ctx->current_cert->derCert.length,
10189 SSL_FILETYPE_ASN1);
10191 return SSL_FATAL_ERROR;
10195 WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl)
10202 WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
10210 WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
10212 WOLFSSL_EVP_PKEY* key = NULL;
10213 if (x509 != NULL) {
10214 key = (WOLFSSL_EVP_PKEY*)XMALLOC(
10215 sizeof(WOLFSSL_EVP_PKEY), NULL, DYNAMIC_TYPE_PUBLIC_KEY);
10217 key->type = x509->pubKeyOID;
10218 key->save_type = 0;
10219 key->pkey.ptr = (char*)XMALLOC(
10220 x509->pubKey.length, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
10221 if (key->pkey.ptr == NULL) {
10222 XFREE(key, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
10225 XMEMCPY(key->pkey.ptr,
10226 x509->pubKey.buffer, x509->pubKey.length);
10227 key->pkey_sz = x509->pubKey.length;
10229 key->pkey_curve = (int)x509->pkCurveOID;
10230 #endif /* HAVE_ECC */
10237 int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
10245 void wolfSSL_X509_STORE_CTX_set_error(WOLFSSL_X509_STORE_CTX* ctx, int err)
10252 void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj)
10258 void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key)
10261 if (key->pkey.ptr != NULL)
10262 XFREE(key->pkey.ptr, NULL, 0);
10263 XFREE(key, NULL, 0);
10268 int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME* asnTime)
10275 int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED* revoked)
10283 WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL* crl)
10290 WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(
10291 WOLFSSL_X509_REVOKED* revoked, int value)
10300 WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
10307 int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime)
10316 int wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER* a,
10317 const WOLFSSL_ASN1_INTEGER* b)
10325 long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER* i)
10333 void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx)
10336 if (ctx != NULL && idx == 0)
10337 return ctx->ex_data;
10346 int wolfSSL_get_ex_data_X509_STORE_CTX_idx(void)
10352 void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx)
10355 if (ssl != NULL && idx < MAX_EX_DATA)
10356 return ssl->ex_data[idx];
10365 void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX* ctx, void (*f)(void))
10372 unsigned long wolfSSL_ERR_peek_error(void)
10378 int wolfSSL_ERR_GET_REASON(int err)
10385 char* wolfSSL_alert_type_string_long(int alertID)
10392 char* wolfSSL_alert_desc_string_long(int alertID)
10399 char* wolfSSL_state_string_long(WOLFSSL* ssl)
10406 int wolfSSL_PEM_def_callback(char* name, int num, int w, void* key)
10416 long wolfSSL_CTX_sess_accept(WOLFSSL_CTX* ctx)
10423 long wolfSSL_CTX_sess_connect(WOLFSSL_CTX* ctx)
10430 long wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX* ctx)
10437 long wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX* ctx)
10444 long wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX* ctx)
10451 long wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX* ctx)
10458 long wolfSSL_CTX_sess_hits(WOLFSSL_CTX* ctx)
10465 long wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX* ctx)
10472 long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX* ctx)
10479 long wolfSSL_CTX_sess_misses(WOLFSSL_CTX* ctx)
10486 long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX* ctx)
10493 long wolfSSL_CTX_sess_number(WOLFSSL_CTX* ctx)
10501 void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock* myDes,
10502 WOLFSSL_DES_key_schedule* key)
10509 void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* myDes)
10515 void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* desa,
10516 WOLFSSL_DES_cblock* desb, WOLFSSL_DES_key_schedule* key, int len)
10524 #endif /* NO_DES3 */
10526 int wolfSSL_BIO_printf(WOLFSSL_BIO* bio, const char* format, ...)
10534 int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a)
10542 int wolfSSL_sk_num(WOLFSSL_X509_REVOKED* rev)
10549 void* wolfSSL_sk_value(WOLFSSL_X509_REVOKED* rev, int i)
10557 /* stunnel 4.28 needs */
10558 void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int d)
10566 int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int d, void* p)
10571 return SSL_SUCCESS;
10575 void wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX* ctx,
10576 WOLFSSL_SESSION*(*f)(WOLFSSL*, unsigned char*, int, int*))
10583 void wolfSSL_CTX_sess_set_new_cb(WOLFSSL_CTX* ctx,
10584 int (*f)(WOLFSSL*, WOLFSSL_SESSION*))
10591 void wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX* ctx, void (*f)(WOLFSSL_CTX*,
10599 int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
10603 return sizeof(WOLFSSL_SESSION);
10607 WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
10608 const unsigned char** p, long i)
10618 long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION* sess)
10620 WOLFSSL_ENTER("wolfSSL_SESSION_get_timeout");
10621 return sess->timeout;
10625 long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION* sess)
10627 WOLFSSL_ENTER("wolfSSL_SESSION_get_time");
10628 return sess->bornOn;
10632 int wolfSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b,
10643 #endif /* OPENSSL_EXTRA */
10646 #ifdef KEEP_PEER_CERT
10647 char* wolfSSL_X509_get_subjectCN(WOLFSSL_X509* x509)
10652 return x509->subjectCN;
10654 #endif /* KEEP_PEER_CERT */
10656 #ifdef OPENSSL_EXTRA
10659 int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname)
10661 int ret = SSL_FATAL_ERROR;
10663 WOLFSSL_ENTER("wolfSSL_cmp_peer_cert_to_file");
10664 if (ssl != NULL && fname != NULL)
10666 #ifdef WOLFSSL_SMALL_STACK
10667 EncryptedInfo* info = NULL;
10668 byte staticBuffer[1]; /* force heap usage */
10670 EncryptedInfo info[1];
10671 byte staticBuffer[FILE_BUFFER_SIZE];
10673 byte* myBuffer = staticBuffer;
10675 XFILE file = XBADFILE;
10678 WOLFSSL_CTX* ctx = ssl->ctx;
10679 WOLFSSL_X509* peer_cert = &ssl->peerCert;
10682 file = XFOPEN(fname, "rb");
10683 if (file == XBADFILE)
10684 return SSL_BAD_FILE;
10686 XFSEEK(file, 0, XSEEK_END);
10690 if (sz > (long)sizeof(staticBuffer)) {
10691 WOLFSSL_MSG("Getting dynamic buffer");
10692 myBuffer = (byte*)XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
10696 #ifdef WOLFSSL_SMALL_STACK
10697 info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
10698 DYNAMIC_TYPE_TMP_BUFFER);
10706 info->consumed = 0;
10707 fileDer.buffer = 0;
10709 if ((myBuffer != NULL) &&
10711 (XFREAD(myBuffer, sz, 1, file) > 0) &&
10712 (PemToDer(myBuffer, sz, CERT_TYPE,
10713 &fileDer, ctx->heap, info, &eccKey) == 0) &&
10714 (fileDer.length != 0) &&
10715 (fileDer.length == peer_cert->derCert.length) &&
10716 (XMEMCMP(peer_cert->derCert.buffer, fileDer.buffer,
10717 fileDer.length) == 0))
10722 #ifdef WOLFSSL_SMALL_STACK
10723 XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10727 XFREE(fileDer.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
10729 XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
10739 static RNG globalRNG;
10740 static int initGlobalRNG = 0;
10742 /* SSL_SUCCESS on ok */
10743 int wolfSSL_RAND_seed(const void* seed, int len)
10746 WOLFSSL_MSG("wolfSSL_RAND_seed");
10751 if (initGlobalRNG == 0) {
10752 if (wc_InitRng(&globalRNG) < 0) {
10753 WOLFSSL_MSG("wolfSSL Init Global RNG failed");
10759 return SSL_SUCCESS;
10763 /* SSL_SUCCESS on ok */
10764 int wolfSSL_RAND_bytes(unsigned char* buf, int num)
10767 int initTmpRng = 0;
10769 #ifdef WOLFSSL_SMALL_STACK
10770 RNG* tmpRNG = NULL;
10775 WOLFSSL_ENTER("RAND_bytes");
10777 #ifdef WOLFSSL_SMALL_STACK
10778 tmpRNG = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
10779 if (tmpRNG == NULL)
10783 if (wc_InitRng(tmpRNG) == 0) {
10787 else if (initGlobalRNG)
10791 if (wc_RNG_GenerateBlock(rng, buf, num) != 0)
10792 WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
10798 wc_FreeRng(tmpRNG);
10800 #ifdef WOLFSSL_SMALL_STACK
10801 XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10807 WOLFSSL_BN_CTX* wolfSSL_BN_CTX_new(void)
10809 static int ctx; /* wolfcrypt doesn't now need ctx */
10811 WOLFSSL_MSG("wolfSSL_BN_CTX_new");
10813 return (WOLFSSL_BN_CTX*)&ctx;
10816 void wolfSSL_BN_CTX_init(WOLFSSL_BN_CTX* ctx)
10819 WOLFSSL_MSG("wolfSSL_BN_CTX_init");
10823 void wolfSSL_BN_CTX_free(WOLFSSL_BN_CTX* ctx)
10826 WOLFSSL_MSG("wolfSSL_BN_CTX_free");
10828 /* do free since static ctx that does nothing */
10832 static void InitwolfSSL_BigNum(WOLFSSL_BIGNUM* bn)
10834 WOLFSSL_MSG("InitwolfSSL_BigNum");
10837 bn->internal = NULL;
10842 WOLFSSL_BIGNUM* wolfSSL_BN_new(void)
10844 WOLFSSL_BIGNUM* external;
10847 WOLFSSL_MSG("wolfSSL_BN_new");
10849 mpi = (mp_int*) XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10851 WOLFSSL_MSG("wolfSSL_BN_new malloc mpi failure");
10855 external = (WOLFSSL_BIGNUM*) XMALLOC(sizeof(WOLFSSL_BIGNUM), NULL,
10856 DYNAMIC_TYPE_BIGINT);
10857 if (external == NULL) {
10858 WOLFSSL_MSG("wolfSSL_BN_new malloc WOLFSSL_BIGNUM failure");
10859 XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
10863 InitwolfSSL_BigNum(external);
10864 external->internal = mpi;
10865 if (mp_init(mpi) != MP_OKAY) {
10866 wolfSSL_BN_free(external);
10874 void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn)
10876 WOLFSSL_MSG("wolfSSL_BN_free");
10878 if (bn->internal) {
10879 mp_clear((mp_int*)bn->internal);
10880 XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT);
10881 bn->internal = NULL;
10883 XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT);
10888 void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM* bn)
10890 WOLFSSL_MSG("wolfSSL_BN_clear_free");
10892 wolfSSL_BN_free(bn);
10896 /* SSL_SUCCESS on ok */
10897 int wolfSSL_BN_sub(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
10898 const WOLFSSL_BIGNUM* b)
10900 WOLFSSL_MSG("wolfSSL_BN_sub");
10902 if (r == NULL || a == NULL || b == NULL)
10905 if (mp_sub((mp_int*)a->internal,(mp_int*)b->internal,
10906 (mp_int*)r->internal) == MP_OKAY)
10907 return SSL_SUCCESS;
10909 WOLFSSL_MSG("wolfSSL_BN_sub mp_sub failed");
10914 /* SSL_SUCCESS on ok */
10915 int wolfSSL_BN_mod(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
10916 const WOLFSSL_BIGNUM* b, const WOLFSSL_BN_CTX* c)
10919 WOLFSSL_MSG("wolfSSL_BN_mod");
10921 if (r == NULL || a == NULL || b == NULL)
10924 if (mp_mod((mp_int*)a->internal,(mp_int*)b->internal,
10925 (mp_int*)r->internal) == MP_OKAY)
10926 return SSL_SUCCESS;
10928 WOLFSSL_MSG("wolfSSL_BN_mod mp_mod failed");
10933 const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void)
10935 static WOLFSSL_BIGNUM* bn_one = NULL;
10937 WOLFSSL_MSG("wolfSSL_BN_value_one");
10939 if (bn_one == NULL) {
10940 bn_one = wolfSSL_BN_new();
10942 mp_set_int((mp_int*)bn_one->internal, 1);
10949 int wolfSSL_BN_num_bytes(const WOLFSSL_BIGNUM* bn)
10951 WOLFSSL_MSG("wolfSSL_BN_num_bytes");
10953 if (bn == NULL || bn->internal == NULL)
10956 return mp_unsigned_bin_size((mp_int*)bn->internal);
10960 int wolfSSL_BN_num_bits(const WOLFSSL_BIGNUM* bn)
10962 WOLFSSL_MSG("wolfSSL_BN_num_bits");
10964 if (bn == NULL || bn->internal == NULL)
10967 return mp_count_bits((mp_int*)bn->internal);
10971 int wolfSSL_BN_is_zero(const WOLFSSL_BIGNUM* bn)
10973 WOLFSSL_MSG("wolfSSL_BN_is_zero");
10975 if (bn == NULL || bn->internal == NULL)
10978 return mp_iszero((mp_int*)bn->internal);
10982 int wolfSSL_BN_is_one(const WOLFSSL_BIGNUM* bn)
10984 WOLFSSL_MSG("wolfSSL_BN_is_one");
10986 if (bn == NULL || bn->internal == NULL)
10989 if (mp_cmp_d((mp_int*)bn->internal, 1) == 0)
10996 int wolfSSL_BN_is_odd(const WOLFSSL_BIGNUM* bn)
10998 WOLFSSL_MSG("wolfSSL_BN_is_odd");
11000 if (bn == NULL || bn->internal == NULL)
11003 return mp_isodd((mp_int*)bn->internal);
11007 int wolfSSL_BN_cmp(const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b)
11009 WOLFSSL_MSG("wolfSSL_BN_cmp");
11011 if (a == NULL || a->internal == NULL || b == NULL || b->internal ==NULL)
11014 return mp_cmp((mp_int*)a->internal, (mp_int*)b->internal);
11018 int wolfSSL_BN_bn2bin(const WOLFSSL_BIGNUM* bn, unsigned char* r)
11020 WOLFSSL_MSG("wolfSSL_BN_bn2bin");
11022 if (bn == NULL || bn->internal == NULL) {
11023 WOLFSSL_MSG("NULL bn error");
11024 return SSL_FATAL_ERROR;
11028 return mp_unsigned_bin_size((mp_int*)bn->internal);
11030 if (mp_to_unsigned_bin((mp_int*)bn->internal, r) != MP_OKAY) {
11031 WOLFSSL_MSG("mp_to_unsigned_bin error");
11032 return SSL_FATAL_ERROR;
11035 return mp_unsigned_bin_size((mp_int*)bn->internal);
11039 WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char* str, int len,
11040 WOLFSSL_BIGNUM* ret)
11042 WOLFSSL_MSG("wolfSSL_BN_bin2bn");
11044 if (ret && ret->internal) {
11045 if (mp_read_unsigned_bin((mp_int*)ret->internal, str, len) != 0) {
11046 WOLFSSL_MSG("mp_read_unsigned_bin failure");
11051 WOLFSSL_MSG("wolfSSL_BN_bin2bn wants return bignum");
11058 int wolfSSL_mask_bits(WOLFSSL_BIGNUM* bn, int n)
11062 WOLFSSL_MSG("wolfSSL_BN_mask_bits");
11064 return SSL_FATAL_ERROR;
11068 /* SSL_SUCCESS on ok */
11069 int wolfSSL_BN_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
11072 int len = bits / 8;
11073 int initTmpRng = 0;
11075 #ifdef WOLFSSL_SMALL_STACK
11076 RNG* tmpRNG = NULL;
11085 WOLFSSL_MSG("wolfSSL_BN_rand");
11090 #ifdef WOLFSSL_SMALL_STACK
11091 buff = (byte*)XMALLOC(1024, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11092 tmpRNG = (RNG*) XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
11093 if (buff == NULL || tmpRNG == NULL) {
11094 XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11095 XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11100 if (bn == NULL || bn->internal == NULL)
11101 WOLFSSL_MSG("Bad function arguments");
11102 else if (wc_InitRng(tmpRNG) == 0) {
11106 else if (initGlobalRNG)
11110 if (wc_RNG_GenerateBlock(rng, buff, len) != 0)
11111 WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
11113 buff[0] |= 0x80 | 0x40;
11114 buff[len-1] |= 0x01;
11116 if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY)
11117 WOLFSSL_MSG("mp read bin failed");
11124 wc_FreeRng(tmpRNG);
11126 #ifdef WOLFSSL_SMALL_STACK
11127 XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11128 XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11135 int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM* bn, int n)
11140 WOLFSSL_MSG("wolfSSL_BN_is_bit_set");
11146 /* SSL_SUCCESS on ok */
11147 int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str)
11150 word32 decSz = 1024;
11151 #ifdef WOLFSSL_SMALL_STACK
11152 byte* decoded = NULL;
11154 byte decoded[1024];
11157 WOLFSSL_MSG("wolfSSL_BN_hex2bn");
11159 #ifdef WOLFSSL_SMALL_STACK
11160 decoded = (byte*)XMALLOC(decSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11161 if (decoded == NULL)
11166 WOLFSSL_MSG("Bad function argument");
11167 else if (Base16_Decode((byte*)str, (int)XSTRLEN(str), decoded, &decSz) < 0)
11168 WOLFSSL_MSG("Bad Base16_Decode error");
11169 else if (bn == NULL)
11173 *bn = wolfSSL_BN_new();
11176 WOLFSSL_MSG("BN new failed");
11177 else if (wolfSSL_BN_bin2bn(decoded, decSz, *bn) == NULL)
11178 WOLFSSL_MSG("Bad bin2bn error");
11183 #ifdef WOLFSSL_SMALL_STACK
11184 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11191 WOLFSSL_BIGNUM* wolfSSL_BN_dup(const WOLFSSL_BIGNUM* bn)
11193 WOLFSSL_BIGNUM* ret;
11195 WOLFSSL_MSG("wolfSSL_BN_dup");
11197 if (bn == NULL || bn->internal == NULL) {
11198 WOLFSSL_MSG("bn NULL error");
11202 ret = wolfSSL_BN_new();
11204 WOLFSSL_MSG("bn new error");
11208 if (mp_copy((mp_int*)bn->internal, (mp_int*)ret->internal) != MP_OKAY) {
11209 WOLFSSL_MSG("mp_copy error");
11210 wolfSSL_BN_free(ret);
11218 WOLFSSL_BIGNUM* wolfSSL_BN_copy(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* bn)
11223 WOLFSSL_MSG("wolfSSL_BN_copy");
11229 int wolfSSL_BN_set_word(WOLFSSL_BIGNUM* bn, unsigned long w)
11234 WOLFSSL_MSG("wolfSSL_BN_set_word");
11236 return SSL_FATAL_ERROR;
11240 int wolfSSL_BN_dec2bn(WOLFSSL_BIGNUM** bn, const char* str)
11245 WOLFSSL_MSG("wolfSSL_BN_dec2bn");
11247 return SSL_FATAL_ERROR;
11251 char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM* bn)
11255 WOLFSSL_MSG("wolfSSL_BN_bn2dec");
11263 static void InitwolfSSL_DH(WOLFSSL_DH* dh)
11268 dh->pub_key = NULL;
11269 dh->priv_key = NULL;
11270 dh->internal = NULL;
11277 WOLFSSL_DH* wolfSSL_DH_new(void)
11279 WOLFSSL_DH* external;
11282 WOLFSSL_MSG("wolfSSL_DH_new");
11284 key = (DhKey*) XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
11286 WOLFSSL_MSG("wolfSSL_DH_new malloc DhKey failure");
11290 external = (WOLFSSL_DH*) XMALLOC(sizeof(WOLFSSL_DH), NULL,
11292 if (external == NULL) {
11293 WOLFSSL_MSG("wolfSSL_DH_new malloc WOLFSSL_DH failure");
11294 XFREE(key, NULL, DYNAMIC_TYPE_DH);
11298 InitwolfSSL_DH(external);
11300 external->internal = key;
11306 void wolfSSL_DH_free(WOLFSSL_DH* dh)
11308 WOLFSSL_MSG("wolfSSL_DH_free");
11311 if (dh->internal) {
11312 wc_FreeDhKey((DhKey*)dh->internal);
11313 XFREE(dh->internal, NULL, DYNAMIC_TYPE_DH);
11314 dh->internal = NULL;
11316 wolfSSL_BN_free(dh->priv_key);
11317 wolfSSL_BN_free(dh->pub_key);
11318 wolfSSL_BN_free(dh->g);
11319 wolfSSL_BN_free(dh->p);
11320 InitwolfSSL_DH(dh); /* set back to NULLs for safety */
11322 XFREE(dh, NULL, DYNAMIC_TYPE_DH);
11327 static int SetDhInternal(WOLFSSL_DH* dh)
11329 int ret = SSL_FATAL_ERROR;
11332 #ifdef WOLFSSL_SMALL_STACK
11333 unsigned char* p = NULL;
11334 unsigned char* g = NULL;
11336 unsigned char p[1024];
11337 unsigned char g[1024];
11340 WOLFSSL_ENTER("SetDhInternal");
11342 if (dh == NULL || dh->p == NULL || dh->g == NULL)
11343 WOLFSSL_MSG("Bad function arguments");
11344 else if (wolfSSL_BN_bn2bin(dh->p, NULL) > pSz)
11345 WOLFSSL_MSG("Bad p internal size");
11346 else if (wolfSSL_BN_bn2bin(dh->g, NULL) > gSz)
11347 WOLFSSL_MSG("Bad g internal size");
11349 #ifdef WOLFSSL_SMALL_STACK
11350 p = (unsigned char*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11351 g = (unsigned char*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11353 if (p == NULL || g == NULL) {
11354 XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11355 XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11360 pSz = wolfSSL_BN_bn2bin(dh->p, p);
11361 gSz = wolfSSL_BN_bn2bin(dh->g, g);
11363 if (pSz <= 0 || gSz <= 0)
11364 WOLFSSL_MSG("Bad BN2bin set");
11365 else if (wc_DhSetKey((DhKey*)dh->internal, p, pSz, g, gSz) < 0)
11366 WOLFSSL_MSG("Bad DH SetKey");
11372 #ifdef WOLFSSL_SMALL_STACK
11373 XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11374 XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11383 int wolfSSL_DH_size(WOLFSSL_DH* dh)
11385 WOLFSSL_MSG("wolfSSL_DH_size");
11390 return wolfSSL_BN_num_bytes(dh->p);
11394 /* return SSL_SUCCESS on ok, else 0 */
11395 int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
11398 word32 pubSz = 768;
11399 word32 privSz = 768;
11400 int initTmpRng = 0;
11402 #ifdef WOLFSSL_SMALL_STACK
11403 unsigned char* pub = NULL;
11404 unsigned char* priv = NULL;
11405 RNG* tmpRNG = NULL;
11407 unsigned char pub [768];
11408 unsigned char priv[768];
11412 WOLFSSL_MSG("wolfSSL_DH_generate_key");
11414 #ifdef WOLFSSL_SMALL_STACK
11415 tmpRNG = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
11416 pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11417 priv = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11419 if (tmpRNG == NULL || pub == NULL || priv == NULL) {
11420 XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11421 XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11422 XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11427 if (dh == NULL || dh->p == NULL || dh->g == NULL)
11428 WOLFSSL_MSG("Bad function arguments");
11429 else if (dh->inSet == 0 && SetDhInternal(dh) < 0)
11430 WOLFSSL_MSG("Bad DH set internal");
11431 else if (wc_InitRng(tmpRNG) == 0) {
11436 WOLFSSL_MSG("Bad RNG Init, trying global");
11437 if (initGlobalRNG == 0)
11438 WOLFSSL_MSG("Global RNG no Init");
11444 if (wc_DhGenerateKeyPair((DhKey*)dh->internal, rng, priv, &privSz,
11446 WOLFSSL_MSG("Bad wc_DhGenerateKeyPair");
11449 wolfSSL_BN_free(dh->pub_key);
11451 dh->pub_key = wolfSSL_BN_new();
11452 if (dh->pub_key == NULL) {
11453 WOLFSSL_MSG("Bad DH new pub");
11456 wolfSSL_BN_free(dh->priv_key);
11458 dh->priv_key = wolfSSL_BN_new();
11460 if (dh->priv_key == NULL) {
11461 WOLFSSL_MSG("Bad DH new priv");
11464 if (dh->pub_key && dh->priv_key) {
11465 if (wolfSSL_BN_bin2bn(pub, pubSz, dh->pub_key) == NULL)
11466 WOLFSSL_MSG("Bad DH bn2bin error pub");
11467 else if (wolfSSL_BN_bin2bn(priv, privSz, dh->priv_key) == NULL)
11468 WOLFSSL_MSG("Bad DH bn2bin error priv");
11476 wc_FreeRng(tmpRNG);
11478 #ifdef WOLFSSL_SMALL_STACK
11479 XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11480 XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11481 XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11488 /* return key size on ok, 0 otherwise */
11489 int wolfSSL_DH_compute_key(unsigned char* key, WOLFSSL_BIGNUM* otherPub,
11494 word32 pubSz = 1024;
11495 word32 privSz = 1024;
11496 #ifdef WOLFSSL_SMALL_STACK
11497 unsigned char* pub = NULL;
11498 unsigned char* priv = NULL;
11500 unsigned char pub [1024];
11501 unsigned char priv[1024];
11504 WOLFSSL_MSG("wolfSSL_DH_compute_key");
11506 #ifdef WOLFSSL_SMALL_STACK
11507 pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11511 priv = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11512 if (priv == NULL) {
11513 XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11518 if (dh == NULL || dh->priv_key == NULL || otherPub == NULL)
11519 WOLFSSL_MSG("Bad function arguments");
11520 else if ((keySz = (word32)DH_size(dh)) == 0)
11521 WOLFSSL_MSG("Bad DH_size");
11522 else if (wolfSSL_BN_bn2bin(dh->priv_key, NULL) > (int)privSz)
11523 WOLFSSL_MSG("Bad priv internal size");
11524 else if (wolfSSL_BN_bn2bin(otherPub, NULL) > (int)pubSz)
11525 WOLFSSL_MSG("Bad otherPub size");
11527 privSz = wolfSSL_BN_bn2bin(dh->priv_key, priv);
11528 pubSz = wolfSSL_BN_bn2bin(otherPub, pub);
11530 if (privSz <= 0 || pubSz <= 0)
11531 WOLFSSL_MSG("Bad BN2bin set");
11532 else if (wc_DhAgree((DhKey*)dh->internal, key, &keySz, priv, privSz, pub,
11534 WOLFSSL_MSG("wc_DhAgree failed");
11539 #ifdef WOLFSSL_SMALL_STACK
11540 XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11541 XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11550 static void InitwolfSSL_DSA(WOLFSSL_DSA* dsa)
11556 dsa->pub_key = NULL;
11557 dsa->priv_key = NULL;
11558 dsa->internal = NULL;
11565 WOLFSSL_DSA* wolfSSL_DSA_new(void)
11567 WOLFSSL_DSA* external;
11570 WOLFSSL_MSG("wolfSSL_DSA_new");
11572 key = (DsaKey*) XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
11574 WOLFSSL_MSG("wolfSSL_DSA_new malloc DsaKey failure");
11578 external = (WOLFSSL_DSA*) XMALLOC(sizeof(WOLFSSL_DSA), NULL,
11580 if (external == NULL) {
11581 WOLFSSL_MSG("wolfSSL_DSA_new malloc WOLFSSL_DSA failure");
11582 XFREE(key, NULL, DYNAMIC_TYPE_DSA);
11586 InitwolfSSL_DSA(external);
11588 external->internal = key;
11594 void wolfSSL_DSA_free(WOLFSSL_DSA* dsa)
11596 WOLFSSL_MSG("wolfSSL_DSA_free");
11599 if (dsa->internal) {
11600 FreeDsaKey((DsaKey*)dsa->internal);
11601 XFREE(dsa->internal, NULL, DYNAMIC_TYPE_DSA);
11602 dsa->internal = NULL;
11604 wolfSSL_BN_free(dsa->priv_key);
11605 wolfSSL_BN_free(dsa->pub_key);
11606 wolfSSL_BN_free(dsa->g);
11607 wolfSSL_BN_free(dsa->q);
11608 wolfSSL_BN_free(dsa->p);
11609 InitwolfSSL_DSA(dsa); /* set back to NULLs for safety */
11611 XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
11616 int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa)
11620 WOLFSSL_MSG("wolfSSL_DSA_generate_key");
11622 return 0; /* key gen not needed by server */
11626 int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits,
11627 unsigned char* seed, int seedLen, int* counterRet,
11628 unsigned long* hRet, void* cb)
11638 WOLFSSL_MSG("wolfSSL_DSA_generate_parameters_ex");
11640 return 0; /* key gen not needed by server */
11642 #endif /* NO_DSA */
11645 static void InitwolfSSL_Rsa(WOLFSSL_RSA* rsa)
11656 rsa->internal = NULL;
11663 WOLFSSL_RSA* wolfSSL_RSA_new(void)
11665 WOLFSSL_RSA* external;
11668 WOLFSSL_MSG("wolfSSL_RSA_new");
11670 key = (RsaKey*) XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
11672 WOLFSSL_MSG("wolfSSL_RSA_new malloc RsaKey failure");
11676 external = (WOLFSSL_RSA*) XMALLOC(sizeof(WOLFSSL_RSA), NULL,
11678 if (external == NULL) {
11679 WOLFSSL_MSG("wolfSSL_RSA_new malloc WOLFSSL_RSA failure");
11680 XFREE(key, NULL, DYNAMIC_TYPE_RSA);
11684 InitwolfSSL_Rsa(external);
11685 if (wc_InitRsaKey(key, NULL) != 0) {
11686 WOLFSSL_MSG("InitRsaKey WOLFSSL_RSA failure");
11687 XFREE(external, NULL, DYNAMIC_TYPE_RSA);
11688 XFREE(key, NULL, DYNAMIC_TYPE_RSA);
11691 external->internal = key;
11697 void wolfSSL_RSA_free(WOLFSSL_RSA* rsa)
11699 WOLFSSL_MSG("wolfSSL_RSA_free");
11702 if (rsa->internal) {
11703 wc_FreeRsaKey((RsaKey*)rsa->internal);
11704 XFREE(rsa->internal, NULL, DYNAMIC_TYPE_RSA);
11705 rsa->internal = NULL;
11707 wolfSSL_BN_free(rsa->iqmp);
11708 wolfSSL_BN_free(rsa->dmq1);
11709 wolfSSL_BN_free(rsa->dmp1);
11710 wolfSSL_BN_free(rsa->q);
11711 wolfSSL_BN_free(rsa->p);
11712 wolfSSL_BN_free(rsa->d);
11713 wolfSSL_BN_free(rsa->e);
11714 wolfSSL_BN_free(rsa->n);
11715 InitwolfSSL_Rsa(rsa); /* set back to NULLs for safety */
11717 XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
11720 #endif /* NO_RSA */
11723 #if !defined(NO_RSA) || !defined(NO_DSA)
11724 static int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi)
11726 WOLFSSL_MSG("Entering SetIndividualExternal");
11729 WOLFSSL_MSG("mpi NULL error");
11730 return SSL_FATAL_ERROR;
11734 *bn = wolfSSL_BN_new();
11736 WOLFSSL_MSG("SetIndividualExternal alloc failed");
11737 return SSL_FATAL_ERROR;
11741 if (mp_copy(mpi, (mp_int*)((*bn)->internal)) != MP_OKAY) {
11742 WOLFSSL_MSG("mp_copy error");
11743 return SSL_FATAL_ERROR;
11748 #endif /* !NO_RSA && !NO_DSA */
11752 static int SetDsaExternal(WOLFSSL_DSA* dsa)
11755 WOLFSSL_MSG("Entering SetDsaExternal");
11757 if (dsa == NULL || dsa->internal == NULL) {
11758 WOLFSSL_MSG("dsa key NULL error");
11759 return SSL_FATAL_ERROR;
11762 key = (DsaKey*)dsa->internal;
11764 if (SetIndividualExternal(&dsa->p, &key->p) < 0) {
11765 WOLFSSL_MSG("dsa p key error");
11766 return SSL_FATAL_ERROR;
11769 if (SetIndividualExternal(&dsa->q, &key->q) < 0) {
11770 WOLFSSL_MSG("dsa q key error");
11771 return SSL_FATAL_ERROR;
11774 if (SetIndividualExternal(&dsa->g, &key->g) < 0) {
11775 WOLFSSL_MSG("dsa g key error");
11776 return SSL_FATAL_ERROR;
11779 if (SetIndividualExternal(&dsa->pub_key, &key->y) < 0) {
11780 WOLFSSL_MSG("dsa y key error");
11781 return SSL_FATAL_ERROR;
11784 if (SetIndividualExternal(&dsa->priv_key, &key->x) < 0) {
11785 WOLFSSL_MSG("dsa x key error");
11786 return SSL_FATAL_ERROR;
11793 #endif /* NO_DSA */
11797 static int SetRsaExternal(WOLFSSL_RSA* rsa)
11800 WOLFSSL_MSG("Entering SetRsaExternal");
11802 if (rsa == NULL || rsa->internal == NULL) {
11803 WOLFSSL_MSG("rsa key NULL error");
11804 return SSL_FATAL_ERROR;
11807 key = (RsaKey*)rsa->internal;
11809 if (SetIndividualExternal(&rsa->n, &key->n) < 0) {
11810 WOLFSSL_MSG("rsa n key error");
11811 return SSL_FATAL_ERROR;
11814 if (SetIndividualExternal(&rsa->e, &key->e) < 0) {
11815 WOLFSSL_MSG("rsa e key error");
11816 return SSL_FATAL_ERROR;
11819 if (SetIndividualExternal(&rsa->d, &key->d) < 0) {
11820 WOLFSSL_MSG("rsa d key error");
11821 return SSL_FATAL_ERROR;
11824 if (SetIndividualExternal(&rsa->p, &key->p) < 0) {
11825 WOLFSSL_MSG("rsa p key error");
11826 return SSL_FATAL_ERROR;
11829 if (SetIndividualExternal(&rsa->q, &key->q) < 0) {
11830 WOLFSSL_MSG("rsa q key error");
11831 return SSL_FATAL_ERROR;
11834 if (SetIndividualExternal(&rsa->dmp1, &key->dP) < 0) {
11835 WOLFSSL_MSG("rsa dP key error");
11836 return SSL_FATAL_ERROR;
11839 if (SetIndividualExternal(&rsa->dmq1, &key->dQ) < 0) {
11840 WOLFSSL_MSG("rsa dQ key error");
11841 return SSL_FATAL_ERROR;
11844 if (SetIndividualExternal(&rsa->iqmp, &key->u) < 0) {
11845 WOLFSSL_MSG("rsa u key error");
11846 return SSL_FATAL_ERROR;
11855 /* SSL_SUCCESS on ok */
11856 int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* bn,
11859 int ret = SSL_FATAL_ERROR;
11861 WOLFSSL_MSG("wolfSSL_RSA_generate_key_ex");
11868 #ifdef WOLFSSL_KEY_GEN
11870 #ifdef WOLFSSL_SMALL_STACK
11876 #ifdef WOLFSSL_SMALL_STACK
11877 rng = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
11879 return SSL_FATAL_ERROR;
11882 if (wc_InitRng(rng) < 0)
11883 WOLFSSL_MSG("RNG init failed");
11884 else if (wc_MakeRsaKey((RsaKey*)rsa->internal, bits, 65537, rng) < 0)
11885 WOLFSSL_MSG("wc_MakeRsaKey failed");
11886 else if (SetRsaExternal(rsa) < 0)
11887 WOLFSSL_MSG("SetRsaExternal failed");
11894 #ifdef WOLFSSL_SMALL_STACK
11895 XFREE(rng, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11899 WOLFSSL_MSG("No Key Gen built in");
11905 /* SSL_SUCCESS on ok */
11906 int wolfSSL_RSA_blinding_on(WOLFSSL_RSA* rsa, WOLFSSL_BN_CTX* bn)
11911 WOLFSSL_MSG("wolfSSL_RSA_blinding_on");
11913 return SSL_SUCCESS; /* on by default */
11917 int wolfSSL_RSA_public_encrypt(int len, unsigned char* fr,
11918 unsigned char* to, WOLFSSL_RSA* rsa, int padding)
11926 WOLFSSL_MSG("wolfSSL_RSA_public_encrypt");
11928 return SSL_FATAL_ERROR;
11932 int wolfSSL_RSA_private_decrypt(int len, unsigned char* fr,
11933 unsigned char* to, WOLFSSL_RSA* rsa, int padding)
11941 WOLFSSL_MSG("wolfSSL_RSA_private_decrypt");
11943 return SSL_FATAL_ERROR;
11947 int wolfSSL_RSA_size(const WOLFSSL_RSA* rsa)
11949 WOLFSSL_MSG("wolfSSL_RSA_size");
11954 return wolfSSL_BN_num_bytes(rsa->n);
11956 #endif /* NO_RSA */
11960 /* return SSL_SUCCESS on success, < 0 otherwise */
11961 int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
11964 int ret = SSL_FATAL_ERROR;
11965 int initTmpRng = 0;
11967 #ifdef WOLFSSL_SMALL_STACK
11968 RNG* tmpRNG = NULL;
11973 WOLFSSL_MSG("wolfSSL_DSA_do_sign");
11975 if (d == NULL || sigRet == NULL || dsa == NULL)
11976 WOLFSSL_MSG("Bad function arguments");
11977 else if (dsa->inSet == 0)
11978 WOLFSSL_MSG("No DSA internal set");
11980 #ifdef WOLFSSL_SMALL_STACK
11981 tmpRNG = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
11982 if (tmpRNG == NULL)
11983 return SSL_FATAL_ERROR;
11986 if (wc_InitRng(tmpRNG) == 0) {
11991 WOLFSSL_MSG("Bad RNG Init, trying global");
11992 if (initGlobalRNG == 0)
11993 WOLFSSL_MSG("Global RNG no Init");
11999 if (DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0)
12000 WOLFSSL_MSG("DsaSign failed");
12006 wc_FreeRng(tmpRNG);
12007 #ifdef WOLFSSL_SMALL_STACK
12008 XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12014 #endif /* NO_DSA */
12018 /* return SSL_SUCCES on ok, 0 otherwise */
12019 int wolfSSL_RSA_sign(int type, const unsigned char* m,
12020 unsigned int mLen, unsigned char* sigRet,
12021 unsigned int* sigLen, WOLFSSL_RSA* rsa)
12025 int initTmpRng = 0;
12028 #ifdef WOLFSSL_SMALL_STACK
12029 RNG* tmpRNG = NULL;
12030 byte* encodedSig = NULL;
12033 byte encodedSig[MAX_ENCODED_SIG_SZ];
12036 WOLFSSL_MSG("wolfSSL_RSA_sign");
12038 if (m == NULL || sigRet == NULL || sigLen == NULL || rsa == NULL)
12039 WOLFSSL_MSG("Bad function arguments");
12040 else if (rsa->inSet == 0)
12041 WOLFSSL_MSG("No RSA internal set");
12042 else if (type != NID_md5 && type != NID_sha1)
12043 WOLFSSL_MSG("Bad md type");
12045 outLen = (word32)wolfSSL_BN_num_bytes(rsa->n);
12047 #ifdef WOLFSSL_SMALL_STACK
12048 tmpRNG = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
12049 if (tmpRNG == NULL)
12052 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
12053 DYNAMIC_TYPE_TMP_BUFFER);
12054 if (encodedSig == NULL) {
12055 XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12061 WOLFSSL_MSG("Bad RSA size");
12062 else if (wc_InitRng(tmpRNG) == 0) {
12067 WOLFSSL_MSG("Bad RNG Init, trying global");
12069 if (initGlobalRNG == 0)
12070 WOLFSSL_MSG("Global RNG no Init");
12077 type = (type == NID_md5) ? MD5h : SHAh;
12079 signSz = wc_EncodeSignature(encodedSig, m, mLen, type);
12081 WOLFSSL_MSG("Bad Encode Signature");
12084 *sigLen = wc_RsaSSL_Sign(encodedSig, signSz, sigRet, outLen,
12085 (RsaKey*)rsa->internal, rng);
12087 WOLFSSL_MSG("Bad Rsa Sign");
12095 wc_FreeRng(tmpRNG);
12097 #ifdef WOLFSSL_SMALL_STACK
12098 XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12099 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12102 WOLFSSL_MSG("wolfSSL_RSA_sign success");
12107 int wolfSSL_RSA_public_decrypt(int flen, unsigned char* from,
12108 unsigned char* to, WOLFSSL_RSA* rsa, int padding)
12116 WOLFSSL_MSG("wolfSSL_RSA_public_decrypt");
12118 return SSL_FATAL_ERROR;
12122 /* generate p-1 and q-1, SSL_SUCCESS on ok */
12123 int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
12128 WOLFSSL_MSG("wolfSSL_RsaGenAdd");
12130 if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->d == NULL ||
12131 rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
12132 WOLFSSL_MSG("rsa no init error");
12133 return SSL_FATAL_ERROR;
12136 if (mp_init(&tmp) != MP_OKAY) {
12137 WOLFSSL_MSG("mp_init error");
12138 return SSL_FATAL_ERROR;
12141 err = mp_sub_d((mp_int*)rsa->p->internal, 1, &tmp);
12142 if (err != MP_OKAY) {
12143 WOLFSSL_MSG("mp_sub_d error");
12146 err = mp_mod((mp_int*)rsa->d->internal, &tmp,
12147 (mp_int*)rsa->dmp1->internal);
12149 if (err != MP_OKAY) {
12150 WOLFSSL_MSG("mp_mod error");
12153 err = mp_sub_d((mp_int*)rsa->q->internal, 1, &tmp);
12154 if (err != MP_OKAY) {
12155 WOLFSSL_MSG("mp_sub_d error");
12158 err = mp_mod((mp_int*)rsa->d->internal, &tmp,
12159 (mp_int*)rsa->dmq1->internal);
12163 if (err == MP_OKAY)
12164 return SSL_SUCCESS;
12166 return SSL_FATAL_ERROR;
12168 #endif /* NO_RSA */
12171 void wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen,
12172 const EVP_MD* type)
12174 WOLFSSL_MSG("wolfSSL_HMAC_Init");
12177 WOLFSSL_MSG("no ctx on init");
12182 WOLFSSL_MSG("init has type");
12184 if (XSTRNCMP(type, "MD5", 3) == 0) {
12185 WOLFSSL_MSG("md5 hmac");
12188 else if (XSTRNCMP(type, "SHA256", 6) == 0) {
12189 WOLFSSL_MSG("sha256 hmac");
12190 ctx->type = SHA256;
12193 /* has to be last since would pick or 256, 384, or 512 too */
12194 else if (XSTRNCMP(type, "SHA", 3) == 0) {
12195 WOLFSSL_MSG("sha hmac");
12199 WOLFSSL_MSG("bad init type");
12203 if (key && keylen) {
12204 WOLFSSL_MSG("keying hmac");
12205 wc_HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key, (word32)keylen);
12206 /* OpenSSL compat, no error */
12211 void wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, const unsigned char* data,
12214 WOLFSSL_MSG("wolfSSL_HMAC_Update");
12217 WOLFSSL_MSG("updating hmac");
12218 wc_HmacUpdate(&ctx->hmac, data, (word32)len);
12219 /* OpenSSL compat, no error */
12224 void wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash,
12227 WOLFSSL_MSG("wolfSSL_HMAC_Final");
12230 WOLFSSL_MSG("final hmac");
12231 wc_HmacFinal(&ctx->hmac, hash);
12232 /* OpenSSL compat, no error */
12235 WOLFSSL_MSG("setting output len");
12236 switch (ctx->type) {
12238 *len = MD5_DIGEST_SIZE;
12242 *len = SHA_DIGEST_SIZE;
12246 *len = SHA256_DIGEST_SIZE;
12250 WOLFSSL_MSG("bad hmac type");
12257 void wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx)
12261 WOLFSSL_MSG("wolfSSL_HMAC_cleanup");
12265 const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id)
12267 WOLFSSL_MSG("wolfSSL_get_digestbynid");
12272 return wolfSSL_EVP_md5();
12276 return wolfSSL_EVP_sha1();
12279 WOLFSSL_MSG("Bad digest id value");
12286 WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY* key)
12289 WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_RSA");
12295 WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY* key)
12298 WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_DSA");
12304 void* wolfSSL_EVP_X_STATE(const WOLFSSL_EVP_CIPHER_CTX* ctx)
12306 WOLFSSL_MSG("wolfSSL_EVP_X_STATE");
12309 switch (ctx->cipherType) {
12311 WOLFSSL_MSG("returning arc4 state");
12312 return (void*)&ctx->cipher.arc4.x;
12315 WOLFSSL_MSG("bad x state type");
12324 int wolfSSL_EVP_X_STATE_LEN(const WOLFSSL_EVP_CIPHER_CTX* ctx)
12326 WOLFSSL_MSG("wolfSSL_EVP_X_STATE_LEN");
12329 switch (ctx->cipherType) {
12331 WOLFSSL_MSG("returning arc4 state size");
12332 return sizeof(Arc4);
12335 WOLFSSL_MSG("bad x state type");
12346 void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
12347 unsigned char* iv, int len)
12351 WOLFSSL_MSG("wolfSSL_3des_iv");
12353 if (ctx == NULL || iv == NULL) {
12354 WOLFSSL_MSG("Bad function argument");
12359 wc_Des3_SetIV(&ctx->cipher.des3, iv); /* OpenSSL compat, no ret */
12361 memcpy(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
12364 #endif /* NO_DES3 */
12369 void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
12370 unsigned char* iv, int len)
12374 WOLFSSL_MSG("wolfSSL_aes_ctr_iv");
12376 if (ctx == NULL || iv == NULL) {
12377 WOLFSSL_MSG("Bad function argument");
12382 wc_AesSetIV(&ctx->cipher.aes, iv); /* OpenSSL compat, no ret */
12384 memcpy(iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
12387 #endif /* NO_AES */
12390 const WOLFSSL_EVP_MD* wolfSSL_EVP_ripemd160(void)
12392 WOLFSSL_MSG("wolfSSL_ripemd160");
12398 int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* type)
12400 WOLFSSL_MSG("wolfSSL_EVP_MD_size");
12402 if (type == NULL) {
12403 WOLFSSL_MSG("No md type arg");
12404 return BAD_FUNC_ARG;
12407 if (XSTRNCMP(type, "SHA256", 6) == 0) {
12408 return SHA256_DIGEST_SIZE;
12411 else if (XSTRNCMP(type, "MD5", 3) == 0) {
12412 return MD5_DIGEST_SIZE;
12415 #ifdef WOLFSSL_SHA384
12416 else if (XSTRNCMP(type, "SHA384", 6) == 0) {
12417 return SHA384_DIGEST_SIZE;
12420 #ifdef WOLFSSL_SHA512
12421 else if (XSTRNCMP(type, "SHA512", 6) == 0) {
12422 return SHA512_DIGEST_SIZE;
12426 /* has to be last since would pick or 256, 384, or 512 too */
12427 else if (XSTRNCMP(type, "SHA", 3) == 0) {
12428 return SHA_DIGEST_SIZE;
12432 return BAD_FUNC_ARG;
12436 int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx)
12438 WOLFSSL_MSG("wolfSSL_EVP_CIPHER_CTX_iv_length");
12440 switch (ctx->cipherType) {
12442 case AES_128_CBC_TYPE :
12443 case AES_192_CBC_TYPE :
12444 case AES_256_CBC_TYPE :
12445 WOLFSSL_MSG("AES CBC");
12446 return AES_BLOCK_SIZE;
12448 #ifdef WOLFSSL_AES_COUNTER
12449 case AES_128_CTR_TYPE :
12450 case AES_192_CTR_TYPE :
12451 case AES_256_CTR_TYPE :
12452 WOLFSSL_MSG("AES CTR");
12453 return AES_BLOCK_SIZE;
12456 case DES_CBC_TYPE :
12457 WOLFSSL_MSG("DES CBC");
12458 return DES_BLOCK_SIZE;
12460 case DES_EDE3_CBC_TYPE :
12461 WOLFSSL_MSG("DES EDE3 CBC");
12462 return DES_BLOCK_SIZE;
12465 WOLFSSL_MSG("ARC4");
12468 case NULL_CIPHER_TYPE :
12469 WOLFSSL_MSG("NULL");
12473 WOLFSSL_MSG("bad type");
12480 void wolfSSL_OPENSSL_free(void* p)
12482 WOLFSSL_MSG("wolfSSL_OPENSSL_free");
12488 int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, RSA* rsa,
12489 const EVP_CIPHER* cipher,
12490 unsigned char* passwd, int len,
12491 pem_password_cb cb, void* arg)
12501 WOLFSSL_MSG("wolfSSL_PEM_write_bio_RSAPrivateKey");
12503 return SSL_FATAL_ERROR;
12508 int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, DSA* rsa,
12509 const EVP_CIPHER* cipher,
12510 unsigned char* passwd, int len,
12511 pem_password_cb cb, void* arg)
12521 WOLFSSL_MSG("wolfSSL_PEM_write_bio_DSAPrivateKey");
12523 return SSL_FATAL_ERROR;
12528 WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
12529 WOLFSSL_EVP_PKEY** key, pem_password_cb cb, void* arg)
12536 WOLFSSL_MSG("wolfSSL_PEM_read_bio_PrivateKey");
12544 /* Load RSA from Der, SSL_SUCCESS on success < 0 on error */
12545 int wolfSSL_RSA_LoadDer(WOLFSSL_RSA* rsa, const unsigned char* der, int derSz)
12550 WOLFSSL_ENTER("wolfSSL_RSA_LoadDer");
12552 if (rsa == NULL || rsa->internal == NULL || der == NULL || derSz <= 0) {
12553 WOLFSSL_MSG("Bad function arguments");
12554 return BAD_FUNC_ARG;
12557 ret = wc_RsaPrivateKeyDecode(der, &idx, (RsaKey*)rsa->internal, derSz);
12559 WOLFSSL_MSG("RsaPrivateKeyDecode failed");
12563 if (SetRsaExternal(rsa) < 0) {
12564 WOLFSSL_MSG("SetRsaExternal failed");
12565 return SSL_FATAL_ERROR;
12570 return SSL_SUCCESS;
12572 #endif /* NO_RSA */
12576 /* Load DSA from Der, SSL_SUCCESS on success < 0 on error */
12577 int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* der, int derSz)
12582 WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
12584 if (dsa == NULL || dsa->internal == NULL || der == NULL || derSz <= 0) {
12585 WOLFSSL_MSG("Bad function arguments");
12586 return BAD_FUNC_ARG;
12589 ret = DsaPrivateKeyDecode(der, &idx, (DsaKey*)dsa->internal, derSz);
12591 WOLFSSL_MSG("DsaPrivateKeyDecode failed");
12595 if (SetDsaExternal(dsa) < 0) {
12596 WOLFSSL_MSG("SetDsaExternal failed");
12597 return SSL_FATAL_ERROR;
12602 return SSL_SUCCESS;
12604 #endif /* NO_DSA */
12609 #endif /* OPENSSL_EXTRA */
12612 #ifdef SESSION_CERTS
12615 /* Get peer's certificate chain */
12616 WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl)
12618 WOLFSSL_ENTER("wolfSSL_get_peer_chain");
12620 return &ssl->session.chain;
12626 /* Get peer's certificate chain total count */
12627 int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain)
12629 WOLFSSL_ENTER("wolfSSL_get_chain_count");
12631 return chain->count;
12637 /* Get peer's ASN.1 DER ceritifcate at index (idx) length in bytes */
12638 int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx)
12640 WOLFSSL_ENTER("wolfSSL_get_chain_length");
12642 return chain->certs[idx].length;
12648 /* Get peer's ASN.1 DER ceritifcate at index (idx) */
12649 byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx)
12651 WOLFSSL_ENTER("wolfSSL_get_chain_cert");
12653 return chain->certs[idx].buffer;
12659 /* Get peer's wolfSSL X509 ceritifcate at index (idx) */
12660 WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx)
12663 WOLFSSL_X509* x509 = NULL;
12664 #ifdef WOLFSSL_SMALL_STACK
12665 DecodedCert* cert = NULL;
12667 DecodedCert cert[1];
12670 WOLFSSL_ENTER("wolfSSL_get_chain_X509");
12671 if (chain != NULL) {
12672 #ifdef WOLFSSL_SMALL_STACK
12673 cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
12674 DYNAMIC_TYPE_TMP_BUFFER);
12678 InitDecodedCert(cert, chain->certs[idx].buffer,
12679 chain->certs[idx].length, NULL);
12681 if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) != 0)
12682 WOLFSSL_MSG("Failed to parse cert");
12684 x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
12685 DYNAMIC_TYPE_X509);
12686 if (x509 == NULL) {
12687 WOLFSSL_MSG("Failed alloc X509");
12692 if ((ret = CopyDecodedToX509(x509, cert)) != 0) {
12693 WOLFSSL_MSG("Failed to copy decoded");
12694 XFREE(x509, NULL, DYNAMIC_TYPE_X509);
12700 FreeDecodedCert(cert);
12701 #ifdef WOLFSSL_SMALL_STACK
12702 XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12711 /* Get peer's PEM ceritifcate at index (idx), output to buffer if inLen big
12712 enough else return error (-1), output length is in *outLen
12713 SSL_SUCCESS on ok */
12714 int wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
12715 unsigned char* buf, int inLen, int* outLen)
12717 const char header[] = "-----BEGIN CERTIFICATE-----\n";
12718 const char footer[] = "-----END CERTIFICATE-----\n";
12720 int headerLen = sizeof(header) - 1;
12721 int footerLen = sizeof(footer) - 1;
12725 WOLFSSL_ENTER("wolfSSL_get_chain_cert_pem");
12726 if (!chain || !outLen || !buf)
12727 return BAD_FUNC_ARG;
12729 /* don't even try if inLen too short */
12730 if (inLen < headerLen + footerLen + chain->certs[idx].length)
12731 return BAD_FUNC_ARG;
12734 XMEMCPY(buf, header, headerLen);
12738 *outLen = inLen; /* input to Base64_Encode */
12739 if ( (err = Base64_Encode(chain->certs[idx].buffer,
12740 chain->certs[idx].length, buf + i, (word32*)outLen)) < 0)
12745 if ( (i + footerLen) > inLen)
12746 return BAD_FUNC_ARG;
12747 XMEMCPY(buf + i, footer, footerLen);
12748 *outLen += headerLen + footerLen;
12750 return SSL_SUCCESS;
12754 /* get session ID */
12755 const byte* wolfSSL_get_sessionID(const WOLFSSL_SESSION* session)
12757 WOLFSSL_ENTER("wolfSSL_get_sessionID");
12759 return session->sessionID;
12765 #endif /* SESSION_CERTS */
12768 void wolfSSL_SetFuzzerCb(WOLFSSL* ssl, CallbackFuzzer cbf, void* fCtx)
12771 ssl->fuzzerCb = cbf;
12772 ssl->fuzzerCtx = fCtx;
12778 #ifdef HAVE_PK_CALLBACKS
12782 void wolfSSL_CTX_SetEccSignCb(WOLFSSL_CTX* ctx, CallbackEccSign cb)
12785 ctx->EccSignCb = cb;
12789 void wolfSSL_SetEccSignCtx(WOLFSSL* ssl, void *ctx)
12792 ssl->EccSignCtx = ctx;
12796 void* wolfSSL_GetEccSignCtx(WOLFSSL* ssl)
12799 return ssl->EccSignCtx;
12805 void wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX* ctx, CallbackEccVerify cb)
12808 ctx->EccVerifyCb = cb;
12812 void wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx)
12815 ssl->EccVerifyCtx = ctx;
12819 void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl)
12822 return ssl->EccVerifyCtx;
12827 #endif /* HAVE_ECC */
12831 void wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX* ctx, CallbackRsaSign cb)
12834 ctx->RsaSignCb = cb;
12838 void wolfSSL_SetRsaSignCtx(WOLFSSL* ssl, void *ctx)
12841 ssl->RsaSignCtx = ctx;
12845 void* wolfSSL_GetRsaSignCtx(WOLFSSL* ssl)
12848 return ssl->RsaSignCtx;
12854 void wolfSSL_CTX_SetRsaVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
12857 ctx->RsaVerifyCb = cb;
12861 void wolfSSL_SetRsaVerifyCtx(WOLFSSL* ssl, void *ctx)
12864 ssl->RsaVerifyCtx = ctx;
12868 void* wolfSSL_GetRsaVerifyCtx(WOLFSSL* ssl)
12871 return ssl->RsaVerifyCtx;
12876 void wolfSSL_CTX_SetRsaEncCb(WOLFSSL_CTX* ctx, CallbackRsaEnc cb)
12879 ctx->RsaEncCb = cb;
12883 void wolfSSL_SetRsaEncCtx(WOLFSSL* ssl, void *ctx)
12886 ssl->RsaEncCtx = ctx;
12890 void* wolfSSL_GetRsaEncCtx(WOLFSSL* ssl)
12893 return ssl->RsaEncCtx;
12898 void wolfSSL_CTX_SetRsaDecCb(WOLFSSL_CTX* ctx, CallbackRsaDec cb)
12901 ctx->RsaDecCb = cb;
12905 void wolfSSL_SetRsaDecCtx(WOLFSSL* ssl, void *ctx)
12908 ssl->RsaDecCtx = ctx;
12912 void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
12915 return ssl->RsaDecCtx;
12921 #endif /* NO_RSA */
12923 #endif /* HAVE_PK_CALLBACKS */
12924 #endif /* NO_CERTS */
12927 #ifdef WOLFSSL_HAVE_WOLFSCEP
12928 /* Used by autoconf to see if wolfSCEP is available */
12929 void wolfSSL_wolfSCEP(void) {}
12933 #ifdef WOLFSSL_HAVE_CERT_SERVICE
12934 /* Used by autoconf to see if cert service is available */
12935 void wolfSSL_cert_service(void) {}