add wolfSSL_write_dup(), creates write_only WOLFSSL to allow concurrent access

This commit is contained in:
toddouska 2017-03-20 15:08:34 -07:00
parent 52215b3ecf
commit 15423428ed
9 changed files with 400 additions and 75 deletions

View File

@ -476,6 +476,19 @@ then
fi
# Write duplicate WOLFSSL object
AC_ARG_ENABLE([writedup],
[ --enable-writedup Enable write duplication of WOLFSSL objects (default: disabled)],
[ ENABLED_WRITEDUP=$enableval ],
[ ENABLED_WRITEDUP=no ]
)
if test "$ENABLED_WRITEDUP" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DHAVE_WRITE_DUP"
fi
# Atomic User Record Layer
AC_ARG_ENABLE([atomicuser],
[ --enable-atomicuser Enable Atomic User Record Layer (default: disabled)],
@ -3480,6 +3493,7 @@ echo " * Async Crypto: $ENABLED_ASYNCCRYPT"
echo " * Cavium: $ENABLED_CAVIUM"
echo " * ARM ASM: $ENABLED_ARMASM"
echo " * AES Key Wrap: $ENABLED_AESKEYWRAP"
echo " * Write duplicate: $ENABLED_WRITEDUP"
echo ""
echo "---"

View File

@ -241,7 +241,8 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args)
SignalReady(args, port);
while (!shutDown) {
CYASSL* ssl = 0;
CYASSL* ssl = NULL;
CYASSL* write_ssl = NULL; /* may have separate w/ HAVE_WRITE_DUP */
char command[SVR_COMMAND_SIZE+1];
int echoSz = 0;
int clientfd;
@ -308,6 +309,18 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args)
showPeer(ssl);
#endif
#ifdef HAVE_WRITE_DUP
write_ssl = wolfSSL_write_dup(ssl);
if (write_ssl == NULL) {
printf("wolfSSL_write_dup failed\n");
CyaSSL_free(ssl);
CloseSocket(clientfd);
continue;
}
#else
write_ssl = ssl;
#endif
while ( (echoSz = CyaSSL_read(ssl, command, sizeof(command)-1)) > 0) {
if (firstRead == 1) {
@ -354,7 +367,7 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args)
strncpy(&command[echoSz], footer, sizeof(footer));
echoSz += (int)sizeof(footer);
if (CyaSSL_write(ssl, command, echoSz) != echoSz)
if (CyaSSL_write(write_ssl, command, echoSz) != echoSz)
err_sys("SSL_write failed");
break;
}
@ -364,11 +377,14 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args)
fputs(command, fout);
#endif
if (CyaSSL_write(ssl, command, echoSz) != echoSz)
if (CyaSSL_write(write_ssl, command, echoSz) != echoSz)
err_sys("SSL_write failed");
}
#ifndef CYASSL_DTLS
CyaSSL_shutdown(ssl);
#endif
#ifdef HAVE_WRITE_DUP
CyaSSL_free(write_ssl);
#endif
CyaSSL_free(ssl);
CloseSocket(clientfd);

View File

@ -3187,8 +3187,14 @@ int DhAgree(WOLFSSL* ssl,
/* This function inherits a WOLFSSL_CTX's fields into an SSL object.
It is used during initialization and to switch an ssl's CTX with
wolfSSL_Set_SSL_CTX. Requires ssl->suites alloc and ssl-arrays with PSK
unless writeDup is on.
ssl object to initialize
ctx parent factory
writeDup flag indicating this is a write dup only
SSL_SUCCESS return value on success */
int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
{
byte havePSK = 0;
byte haveAnon = 0;
@ -3196,13 +3202,16 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
byte haveRSA = 0;
(void) haveAnon; /* Squash unused var warnings */
if(!ssl || !ctx || ssl->suites == NULL)
if (!ssl || !ctx)
return BAD_FUNC_ARG;
if (ssl->suites == NULL && !writeDup)
return BAD_FUNC_ARG;
newSSL = ssl->ctx == NULL; /* Assign after null check */
#ifndef NO_PSK
if (ctx->server_hint[0] && ssl->arrays == NULL) {
if (ctx->server_hint[0] && ssl->arrays == NULL && !writeDup) {
return BAD_FUNC_ARG; /* needed for copy below */
}
#endif
@ -3307,41 +3316,45 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
ssl->devId = ctx->devId;
#endif
if (writeDup == 0) {
#ifndef NO_PSK
if (ctx->server_hint[0]) { /* set in CTX */
XSTRNCPY(ssl->arrays->server_hint, ctx->server_hint, MAX_PSK_ID_LEN);
ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
}
if (ctx->server_hint[0]) { /* set in CTX */
XSTRNCPY(ssl->arrays->server_hint, ctx->server_hint,MAX_PSK_ID_LEN);
ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
}
#endif /* NO_PSK */
if (ctx->suites)
*ssl->suites = *ctx->suites;
else
XMEMSET(ssl->suites, 0, sizeof(Suites));
if (ctx->suites)
*ssl->suites = *ctx->suites;
else
XMEMSET(ssl->suites, 0, sizeof(Suites));
/* make sure server has DH parms, and add PSK if there, add NTRU too */
if (ssl->options.side == WOLFSSL_SERVER_END)
InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
/* make sure server has DH parms, and add PSK if there, add NTRU too */
if (ssl->options.side == WOLFSSL_SERVER_END)
InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
ssl->options.haveDH, ssl->options.haveNTRU,
ssl->options.haveECDSAsig, ssl->options.haveECC,
ssl->options.haveStaticECC, ssl->options.side);
else
InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, TRUE,
else
InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, TRUE,
ssl->options.haveNTRU, ssl->options.haveECDSAsig,
ssl->options.haveECC, ssl->options.haveStaticECC,
ssl->options.side);
#if !defined(NO_CERTS) && !defined(WOLFSSL_SESSION_EXPORT)
/* make sure server has cert and key unless using PSK or Anon
* This should be true even if just switching ssl ctx */
if (ssl->options.side == WOLFSSL_SERVER_END && !havePSK && !haveAnon)
if (!ssl->buffers.certificate || !ssl->buffers.certificate->buffer ||
!ssl->buffers.key || !ssl->buffers.key->buffer) {
WOLFSSL_MSG("Server missing certificate and/or private key");
return NO_PRIVATE_KEY;
}
/* make sure server has cert and key unless using PSK or Anon
* This should be true even if just switching ssl ctx */
if (ssl->options.side == WOLFSSL_SERVER_END && !havePSK && !haveAnon)
if (!ssl->buffers.certificate || !ssl->buffers.certificate->buffer
|| !ssl->buffers.key || !ssl->buffers.key->buffer) {
WOLFSSL_MSG("Server missing certificate and/or private key");
return NO_PRIVATE_KEY;
}
#endif
} /* writeDup check */
#ifdef WOLFSSL_SESSION_EXPORT
#ifdef WOLFSSL_DTLS
ssl->dtls_export = ctx->dtls_export; /* export function for session */
@ -3358,8 +3371,13 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
/* init everything to 0, NULL, default values before calling anything that may
fail so that destructor has a "good" state to cleanup
ssl object to initialize
ctx parent factory
writeDup flag indicating this is a write dup only
0 on success */
int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
{
int ret;
@ -3542,30 +3560,65 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
/* all done with init, now can return errors, call other stuff */
/* arrays */
ssl->arrays = (Arrays*)XMALLOC(sizeof(Arrays), ssl->heap,
if (!writeDup) {
/* arrays */
ssl->arrays = (Arrays*)XMALLOC(sizeof(Arrays), ssl->heap,
DYNAMIC_TYPE_ARRAYS);
if (ssl->arrays == NULL) {
WOLFSSL_MSG("Arrays Memory error");
return MEMORY_E;
}
XMEMSET(ssl->arrays, 0, sizeof(Arrays));
if (ssl->arrays == NULL) {
WOLFSSL_MSG("Arrays Memory error");
return MEMORY_E;
}
XMEMSET(ssl->arrays, 0, sizeof(Arrays));
/* suites */
ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
/* suites */
ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
DYNAMIC_TYPE_SUITES);
if (ssl->suites == NULL) {
WOLFSSL_MSG("Suites Memory error");
return MEMORY_E;
if (ssl->suites == NULL) {
WOLFSSL_MSG("Suites Memory error");
return MEMORY_E;
}
}
/* Initialize SSL with the appropriate fields from it's ctx */
/* requires valid arrays and suites */
if((ret = SetSSL_CTX(ssl, ctx)) != SSL_SUCCESS)
/* requires valid arrays and suites unless writeDup ing */
if ((ret = SetSSL_CTX(ssl, ctx, writeDup)) != SSL_SUCCESS)
return ret;
ssl->options.dtls = ssl->version.major == DTLS_MAJOR;
#ifdef SINGLE_THREADED
ssl->rng = ctx->rng; /* CTX may have one, if so use it */
#endif
if (ssl->rng == NULL) {
/* RNG */
ssl->rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ssl->heap,DYNAMIC_TYPE_RNG);
if (ssl->rng == NULL) {
WOLFSSL_MSG("RNG Memory error");
return MEMORY_E;
}
XMEMSET(ssl->rng, 0, sizeof(WC_RNG));
ssl->options.weOwnRng = 1;
/* FIPS RNG API does not accept a heap hint */
#ifndef HAVE_FIPS
if ( (ret = wc_InitRng_ex(ssl->rng, ssl->heap)) != 0) {
WOLFSSL_MSG("RNG Init error");
return ret;
}
#else
if ( (ret = wc_InitRng(ssl->rng)) != 0) {
WOLFSSL_MSG("RNG Init error");
return ret;
}
#endif
}
if (writeDup) {
/* all done */
return 0;
}
/* hsHashes */
ssl->hsHashes = (HS_Hashes*)XMALLOC(sizeof(HS_Hashes), ssl->heap,
DYNAMIC_TYPE_HASHES);
@ -3604,34 +3657,6 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
}
#endif
#ifdef SINGLE_THREADED
ssl->rng = ctx->rng; /* CTX may have one, if so use it */
#endif
if (ssl->rng == NULL) {
/* RNG */
ssl->rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ssl->heap,DYNAMIC_TYPE_RNG);
if (ssl->rng == NULL) {
WOLFSSL_MSG("RNG Memory error");
return MEMORY_E;
}
XMEMSET(ssl->rng, 0, sizeof(WC_RNG));
ssl->options.weOwnRng = 1;
/* FIPS RNG API does not accept a heap hint */
#ifndef HAVE_FIPS
if ( (ret = wc_InitRng_ex(ssl->rng, ssl->heap)) != 0) {
WOLFSSL_MSG("RNG Init error");
return ret;
}
#else
if ( (ret = wc_InitRng(ssl->rng)) != 0) {
WOLFSSL_MSG("RNG Init error");
return ret;
}
#endif
}
#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
if (ssl->options.dtls && ssl->options.side == WOLFSSL_SERVER_END) {
ret = wolfSSL_DTLS_SetCookieSecret(ssl, NULL, 0);
@ -3842,6 +3867,11 @@ void SSL_ResourceFree(WOLFSSL* ssl)
#ifdef HAVE_EXT_CACHE
wolfSSL_SESSION_free(ssl->extSession);
#endif
#ifdef HAVE_WRITE_DUP
if (ssl->dupWrite) {
FreeWriteDup(ssl);
}
#endif
#ifdef WOLFSSL_STATIC_MEMORY
/* check if using fixed io buffers and free them */
@ -11588,6 +11618,26 @@ int SendAlert(WOLFSSL* ssl, int severity, int type)
int outputSz;
int dtlsExtra = 0;
#ifdef HAVE_WRITE_DUP
if (ssl->dupWrite && ssl->dupSide == READ_DUP_SIDE) {
int notifyErr = 0;
WOLFSSL_MSG("Read dup side cannot write alerts, notifying sibling");
if (type == close_notify) {
notifyErr = ZERO_RETURN;
} else if (severity == alert_fatal) {
notifyErr = FATAL_ERROR;
}
if (notifyErr != 0) {
return NotifyWriteSide(ssl, notifyErr);
}
return 0;
}
#endif
/* if sendalert is called again for nonblocking */
if (ssl->options.sendAlertState != 0) {
ret = SendBuffered(ssl);
@ -12024,6 +12074,12 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
case DECODE_E:
return "Decode handshake message error";
case WRITE_DUP_READ_E:
return "Write dup write side can't read error";
case WRITE_DUP_WRITE_E:
return "Write dup read side can't write error";
default :
return "unknown error number";
}

212
src/ssl.c
View File

@ -372,7 +372,7 @@ WOLFSSL* wolfSSL_new(WOLFSSL_CTX* ctx)
ssl = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ctx->heap, DYNAMIC_TYPE_SSL);
if (ssl)
if ( (ret = InitSSL(ssl, ctx)) < 0) {
if ( (ret = InitSSL(ssl, ctx, 0)) < 0) {
FreeSSL(ssl, ctx->heap);
ssl = 0;
}
@ -390,6 +390,162 @@ void wolfSSL_free(WOLFSSL* ssl)
WOLFSSL_LEAVE("SSL_free", 0);
}
#ifdef HAVE_WRITE_DUP
/*
* Release resources around WriteDup object
*
* ssl WOLFSSL object
*
* no return, destruction so make best attempt
*/
void FreeWriteDup(WOLFSSL* ssl)
{
int doFree = 0;
WOLFSSL_ENTER("FreeWriteDup");
if (ssl->dupWrite) {
if (wc_LockMutex(&ssl->dupWrite->dupMutex) == 0) {
ssl->dupWrite->dupCount--;
if (ssl->dupWrite->dupCount == 0) {
doFree = 1;
} else {
WOLFSSL_MSG("WriteDup count not zero, no full free");
}
wc_UnLockMutex(&ssl->dupWrite->dupMutex);
}
}
if (doFree) {
WOLFSSL_MSG("Doing WriteDup full free, count to zero");
wc_FreeMutex(&ssl->dupWrite->dupMutex);
XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
}
}
/*
* duplicate existing ssl members into dup needed for writing
*
* dup write only WOLFSSL
* ssl exisiting WOLFSSL
*
* 0 on success
*/
static int DupSSL(WOLFSSL* dup, WOLFSSL* ssl)
{
/* shared dupWrite setup */
ssl->dupWrite = (WriteDup*)XMALLOC(sizeof(WriteDup), ssl->heap,
DYNAMIC_TYPE_WRITEDUP);
if (ssl->dupWrite == NULL) {
return MEMORY_E;
}
XMEMSET(ssl->dupWrite, 0, sizeof(WriteDup));
if (wc_InitMutex(&ssl->dupWrite->dupMutex) != 0) {
XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
ssl->dupWrite = NULL;
return BAD_MUTEX_E;
}
ssl->dupWrite->dupCount = 2; /* both sides have a count to start */
dup->dupWrite = ssl->dupWrite ; /* each side uses */
/* copy write parts over to dup writer */
XMEMCPY(&dup->specs, &ssl->specs, sizeof(CipherSpecs));
XMEMCPY(&dup->options, &ssl->options, sizeof(Options));
XMEMCPY(&dup->keys, &ssl->keys, sizeof(Keys));
XMEMCPY(&dup->encrypt, &ssl->encrypt, sizeof(Ciphers));
/* dup side now owns encrypt/write ciphers */
XMEMSET(&ssl->encrypt, 0, sizeof(Ciphers));
dup->IOCB_WriteCtx = ssl->IOCB_WriteCtx;
dup->wfd = ssl->wfd;
dup->wflags = ssl->wflags;
dup->hmac = ssl->hmac;
#ifdef HAVE_TRUNCATED_HMAC
dup->truncated_hmac = ssl->truncated_hmac;
#endif
/* unique side dup setup */
dup->dupSide = WRITE_DUP_SIDE;
ssl->dupSide = READ_DUP_SIDE;
return 0;
}
/*
* duplicate a WOLFSSL object post handshake for writing only
* turn exisitng object into read only. Allows concurrent access from two
* different threads.
*
* ssl exisiting WOLFSSL object
*
* return dup'd WOLFSSL object on success
*/
WOLFSSL* wolfSSL_write_dup(WOLFSSL* ssl)
{
WOLFSSL* dup = NULL;
int ret = 0;
(void)ret;
WOLFSSL_ENTER("wolfSSL_write_dup");
if (ssl == NULL) {
return ssl;
}
if (ssl->options.handShakeDone == 0) {
WOLFSSL_MSG("wolfSSL_write_dup called before handshake complete");
return NULL;
}
dup = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ssl->ctx->heap, DYNAMIC_TYPE_SSL);
if (dup) {
if ( (ret = InitSSL(dup, ssl->ctx, 1)) < 0) {
FreeSSL(dup, ssl->ctx->heap);
dup = NULL;
} else if ( (ret = DupSSL(dup, ssl) < 0)) {
FreeSSL(dup, ssl->ctx->heap);
dup = NULL;
}
}
WOLFSSL_LEAVE("wolfSSL_write_dup", ret);
return dup;
}
/*
* Notify write dup side of fatal error or close notify
*
* ssl WOLFSSL object
* err Notify err
*
* 0 on success
*/
int NotifyWriteSide(WOLFSSL* ssl, int err)
{
int ret;
WOLFSSL_ENTER("NotifyWriteSide");
ret = wc_LockMutex(&ssl->dupWrite->dupMutex);
if (ret == 0) {
ssl->dupWrite->dupErr = err;
ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
}
return ret;
}
#endif /* HAVE_WRITE_DUP */
#ifdef HAVE_POLY1305
/* set if to use old poly 1 for yes 0 to use new poly */
int wolfSSL_use_old_poly(WOLFSSL* ssl, int value)
@ -1114,6 +1270,36 @@ int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
if (ssl == NULL || data == NULL || sz < 0)
return BAD_FUNC_ARG;
#ifdef HAVE_WRITE_DUP
{ /* local variable scope */
int dupErr = 0; /* local copy */
ret = 0;
if (ssl->dupWrite && ssl->dupSide == READ_DUP_SIDE) {
WOLFSSL_MSG("Read dup side cannot write");
return WRITE_DUP_WRITE_E;
}
if (ssl->dupWrite) {
if (wc_LockMutex(&ssl->dupWrite->dupMutex) != 0) {
return BAD_MUTEX_E;
}
dupErr = ssl->dupWrite->dupErr;
ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
}
if (ret != 0) {
ssl->error = ret; /* high priority fatal error */
return SSL_FATAL_ERROR;
}
if (dupErr != 0) {
WOLFSSL_MSG("Write dup error from other side");
ssl->error = dupErr;
return SSL_FATAL_ERROR;
}
}
#endif
#ifdef HAVE_ERRNO_H
errno = 0;
#endif
@ -1138,6 +1324,13 @@ static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
if (ssl == NULL || data == NULL || sz < 0)
return BAD_FUNC_ARG;
#ifdef HAVE_WRITE_DUP
if (ssl->dupWrite && ssl->dupSide == WRITE_DUP_SIDE) {
WOLFSSL_MSG("Write dup side cannot read");
return WRITE_DUP_READ_E;
}
#endif
#ifdef HAVE_ERRNO_H
errno = 0;
#endif
@ -1158,6 +1351,21 @@ static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
#endif
ret = ReceiveData(ssl, (byte*)data, sz, peek);
#ifdef HAVE_WRITE_DUP
if (ssl->dupWrite) {
if (ssl->error != 0 && ssl->error != WANT_READ &&
ssl->error != WC_PENDING_E) {
int notifyErr;
WOLFSSL_MSG("Notifying write side of fatal read error");
notifyErr = NotifyWriteSide(ssl, ssl->error);
if (notifyErr < 0) {
ret = ssl->error = notifyErr;
}
}
}
#endif
WOLFSSL_LEAVE("wolfSSL_read_internal()", ret);
if (ret < 0)
@ -22603,7 +22811,7 @@ const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type)
WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
{
if (ssl && ctx && SetSSL_CTX(ssl, ctx) == SSL_SUCCESS)
if (ssl && ctx && SetSSL_CTX(ssl, ctx, 0) == SSL_SUCCESS)
return ssl->ctx;
return NULL;
}

View File

@ -153,6 +153,8 @@ enum wolfSSL_ErrorCodes {
DTLS_POOL_SZ_E = -415, /* exceeded DTLS pool size */
DECODE_E = -416, /* decode handshake message error */
HTTP_TIMEOUT = -417, /* HTTP timeout for OCSP or CRL req */
WRITE_DUP_READ_E = -418, /* Write dup write side can't read */
WRITE_DUP_WRITE_E = -419, /* Write dup read side can't write */
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */
/* begin negotiation parameter errors */

View File

@ -2754,6 +2754,22 @@ typedef struct HS_Hashes {
} HS_Hashes;
#ifdef HAVE_WRITE_DUP
#define WRITE_DUP_SIDE 1
#define READ_DUP_SIDE 2
typedef struct WriteDup {
wolfSSL_Mutex dupMutex; /* reference count mutex */
int dupCount; /* reference count */
int dupErr; /* under dupMutex, pass to other side */
} WriteDup;
WOLFSSL_LOCAL void FreeWriteDup(WOLFSSL* ssl);
WOLFSSL_LOCAL int NotifyWriteSide(WOLFSSL* ssl, int err);
#endif /* HAVE_WRITE_DUP */
/* wolfSSL ssl type */
struct WOLFSSL {
WOLFSSL_CTX* ctx;
@ -2766,6 +2782,11 @@ struct WOLFSSL {
void* verifyCbCtx; /* cert verify callback user ctx*/
VerifyCallback verifyCallback; /* cert verification callback */
void* heap; /* for user overrides */
#ifdef HAVE_WRITE_DUP
WriteDup* dupWrite; /* valid pointer indicates ON */
/* side that decrements dupCount to zero frees overall structure */
byte dupSide; /* write side or read side */
#endif
#ifdef WOLFSSL_STATIC_MEMORY
WOLFSSL_HEAP_HINT heap_hint;
#endif
@ -2967,9 +2988,9 @@ struct WOLFSSL {
WOLFSSL_LOCAL
int SetSSL_CTX(WOLFSSL*, WOLFSSL_CTX*);
int SetSSL_CTX(WOLFSSL*, WOLFSSL_CTX*, int);
WOLFSSL_LOCAL
int InitSSL(WOLFSSL*, WOLFSSL_CTX*);
int InitSSL(WOLFSSL*, WOLFSSL_CTX*, int);
WOLFSSL_LOCAL
void FreeSSL(WOLFSSL*, void* heap);
WOLFSSL_API void SSL_ResourceFree(WOLFSSL*); /* Micrium uses */

View File

@ -369,6 +369,7 @@ WOLFSSL_API int wolfSSL_use_RSAPrivateKey_file(WOLFSSL*, const char*, int);
WOLFSSL_API WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD*);
WOLFSSL_API WOLFSSL* wolfSSL_new(WOLFSSL_CTX*);
WOLFSSL_API WOLFSSL* wolfSSL_write_dup(WOLFSSL*);
WOLFSSL_API int wolfSSL_set_fd (WOLFSSL*, int);
WOLFSSL_API int wolfSSL_set_write_fd (WOLFSSL*, int);
WOLFSSL_API int wolfSSL_set_read_fd (WOLFSSL*, int);

View File

@ -1230,6 +1230,12 @@ static char *fgets(char *buff, int sz, FILE *fp)
#endif
#endif
/* write dup cannot be used with secure renegotiation because write dup
* make write side write only and read side read only */
#if defined(HAVE_WRITE_DUP) && defined(HAVE_SECURE_RENEGOTIATION)
#error "WRITE DUP and SECURE RENEGOTIATION cannot both be on"
#endif
#ifdef WOLFSSL_SGX
#define WOLFCRYPT_ONLY /* limitation until IO resolved */
#define SINGLE_THREADED

View File

@ -343,7 +343,8 @@
DYNAMIC_TYPE_MUTEX = 59,
DYNAMIC_TYPE_PKCS7 = 60,
DYNAMIC_TYPE_ASN1 = 61,
DYNAMIC_TYPE_LOG = 62
DYNAMIC_TYPE_LOG = 62,
DYNAMIC_TYPE_WRITEDUP = 63
};
/* max error buffer string size */