mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 02:37:28 +02:00
Save pending alerts when using async io
- Don't overwrite ssl->error - Clear the error in ssl->error because the return of SendBuffered is now stored in ret instead
This commit is contained in:
@ -1162,7 +1162,7 @@ static int ExportOptions(WOLFSSL* ssl, byte* exp, word32 len, byte ver,
|
||||
exp[idx++] = options->havePeerVerify;
|
||||
exp[idx++] = options->usingPSK_cipher;
|
||||
exp[idx++] = options->usingAnon_cipher;
|
||||
exp[idx++] = options->sendAlertState;
|
||||
exp[idx++] = 0; /* Historical: options->sendAlertState */
|
||||
exp[idx++] = options->partialWrite;
|
||||
exp[idx++] = options->quietShutdown;
|
||||
exp[idx++] = options->groupMessages;
|
||||
@ -1345,7 +1345,7 @@ static int ImportOptions(WOLFSSL* ssl, const byte* exp, word32 len, byte ver,
|
||||
options->havePeerVerify = exp[idx++];
|
||||
options->usingPSK_cipher = exp[idx++];
|
||||
options->usingAnon_cipher = exp[idx++];
|
||||
options->sendAlertState = exp[idx++];
|
||||
idx++; /* Historical: options->sendAlertState */
|
||||
options->partialWrite = exp[idx++];
|
||||
options->quietShutdown = exp[idx++];
|
||||
options->groupMessages = exp[idx++];
|
||||
@ -17276,6 +17276,10 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = RetrySendAlert(ssl);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
for (;;) {
|
||||
switch (ssl->options.processReply) {
|
||||
|
||||
@ -20289,6 +20293,10 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
|
||||
}
|
||||
}
|
||||
|
||||
ret = RetrySendAlert(ssl);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
for (;;) {
|
||||
byte* out;
|
||||
byte* sendBuffer = (byte*)data + sent; /* may switch on comp */
|
||||
@ -20554,6 +20562,19 @@ startScr:
|
||||
return size;
|
||||
}
|
||||
|
||||
int RetrySendAlert(WOLFSSL* ssl)
|
||||
{
|
||||
int type = ssl->pendingAlert.code;
|
||||
int severity = ssl->pendingAlert.level;
|
||||
|
||||
if (severity == alert_none)
|
||||
return 0;
|
||||
|
||||
ssl->pendingAlert.code = 0;
|
||||
ssl->pendingAlert.level = alert_none;
|
||||
|
||||
return SendAlert(ssl, severity, type);
|
||||
}
|
||||
|
||||
/* send alert message */
|
||||
int SendAlert(WOLFSSL* ssl, int severity, int type)
|
||||
@ -20587,14 +20608,24 @@ int SendAlert(WOLFSSL* ssl, int severity, int type)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* if sendalert is called again for nonblocking */
|
||||
if (ssl->options.sendAlertState != 0) {
|
||||
ret = SendBuffered(ssl);
|
||||
if (ret == 0)
|
||||
ssl->options.sendAlertState = 0;
|
||||
return ret;
|
||||
if (ssl->pendingAlert.level != alert_none) {
|
||||
ret = RetrySendAlert(ssl);
|
||||
if (ret != 0) {
|
||||
if (ssl->pendingAlert.level == alert_none ||
|
||||
(ssl->pendingAlert.level != alert_fatal &&
|
||||
severity == alert_fatal)) {
|
||||
/* Store current alert if pendingAlert if free or if current
|
||||
* is fatal and previous was not */
|
||||
ssl->pendingAlert.code = type;
|
||||
ssl->pendingAlert.level = severity;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ssl->pendingAlert.code = type;
|
||||
ssl->pendingAlert.level = severity;
|
||||
|
||||
#ifdef OPENSSL_EXTRA
|
||||
if (ssl->CBIS != NULL) {
|
||||
ssl->CBIS(ssl, SSL_CB_ALERT, type);
|
||||
@ -20607,16 +20638,8 @@ int SendAlert(WOLFSSL* ssl, int severity, int type)
|
||||
|
||||
/* check for available size */
|
||||
outputSz = ALERT_SIZE + MAX_MSG_EXTRA + dtlsExtra;
|
||||
if ((ret = CheckAvailableSize(ssl, outputSz)) != 0) {
|
||||
/* If CheckAvailableSize returned WANT_WRITE due to a blocking write
|
||||
* then discard pending output and just send the alert. */
|
||||
if (ret != WANT_WRITE || severity != alert_fatal)
|
||||
return ret;
|
||||
ShrinkOutputBuffer(ssl);
|
||||
if ((ret = CheckAvailableSize(ssl, outputSz)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
|
||||
return ret;
|
||||
|
||||
/* Check output buffer */
|
||||
if (ssl->buffers.outputBuffer.buffer == NULL)
|
||||
@ -20670,10 +20693,12 @@ int SendAlert(WOLFSSL* ssl, int severity, int type)
|
||||
#endif
|
||||
|
||||
ssl->buffers.outputBuffer.length += sendSz;
|
||||
ssl->options.sendAlertState = 1;
|
||||
|
||||
ret = SendBuffered(ssl);
|
||||
|
||||
ssl->pendingAlert.code = 0;
|
||||
ssl->pendingAlert.level = alert_none;
|
||||
|
||||
WOLFSSL_LEAVE("SendAlert", ret);
|
||||
|
||||
return ret;
|
||||
|
44
src/ssl.c
44
src/ssl.c
@ -11778,6 +11778,9 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
#if !(defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13))
|
||||
int neededState;
|
||||
#endif
|
||||
int ret = 0;
|
||||
|
||||
(void)ret;
|
||||
|
||||
WOLFSSL_ENTER("SSL_connect()");
|
||||
|
||||
@ -11820,14 +11823,16 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
if ((ssl->ConnectFilter(ssl, ssl->ConnectFilter_arg, &res) ==
|
||||
WOLFSSL_SUCCESS) &&
|
||||
(res == WOLFSSL_NETFILTER_REJECT)) {
|
||||
WOLFSSL_ERROR(ssl->error = SOCKET_FILTERED_E);
|
||||
ssl->error = SOCKET_FILTERED_E;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
|
||||
|
||||
if (ssl->options.side != WOLFSSL_CLIENT_END) {
|
||||
WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
|
||||
ssl->error = SIDE_ERROR;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
@ -11846,7 +11851,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
&& ssl->error != WC_PENDING_E
|
||||
#endif
|
||||
) {
|
||||
if ( (ssl->error = SendBuffered(ssl)) == 0) {
|
||||
if ( (ret = SendBuffered(ssl)) == 0) {
|
||||
/* fragOffset is non-zero when sending fragments. On the last
|
||||
* fragment, fragOffset is zero again, and the state can be
|
||||
* advanced. */
|
||||
@ -11870,11 +11875,19 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
}
|
||||
}
|
||||
else {
|
||||
ssl->error = ret;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ret = RetrySendAlert(ssl);
|
||||
if (ret != 0) {
|
||||
ssl->error = ret;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
switch (ssl->options.connectState) {
|
||||
|
||||
case CONNECT_BEGIN :
|
||||
@ -12117,6 +12130,8 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
FreeAsyncCtx(ssl, 1);
|
||||
#endif
|
||||
|
||||
ssl->error = 0; /* clear the error */
|
||||
|
||||
WOLFSSL_LEAVE("SSL_connect()", WOLFSSL_SUCCESS);
|
||||
return WOLFSSL_SUCCESS;
|
||||
#endif /* !WOLFSSL_NO_TLS12 || !NO_OLD_TLS */
|
||||
@ -12207,6 +12222,9 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
word16 haveAnon = 0;
|
||||
word16 haveMcast = 0;
|
||||
#endif
|
||||
int ret = 0;
|
||||
|
||||
(void)ret;
|
||||
|
||||
if (ssl == NULL)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
@ -12238,7 +12256,8 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
if ((ssl->AcceptFilter(ssl, ssl->AcceptFilter_arg, &res) ==
|
||||
WOLFSSL_SUCCESS) &&
|
||||
(res == WOLFSSL_NETFILTER_REJECT)) {
|
||||
WOLFSSL_ERROR(ssl->error = SOCKET_FILTERED_E);
|
||||
ssl->error = SOCKET_FILTERED_E;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
@ -12264,7 +12283,8 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
(void)haveMcast;
|
||||
|
||||
if (ssl->options.side != WOLFSSL_SERVER_END) {
|
||||
WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
|
||||
ssl->error = SIDE_ERROR;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
@ -12303,7 +12323,8 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
#endif
|
||||
{
|
||||
WOLFSSL_MSG("accept error: server key required");
|
||||
WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY);
|
||||
ssl->error = NO_PRIVATE_KEY;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
@ -12326,7 +12347,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
&& ssl->error != WC_PENDING_E
|
||||
#endif
|
||||
) {
|
||||
if ( (ssl->error = SendBuffered(ssl)) == 0) {
|
||||
if ( (ret = SendBuffered(ssl)) == 0) {
|
||||
/* fragOffset is non-zero when sending fragments. On the last
|
||||
* fragment, fragOffset is zero again, and the state can be
|
||||
* advanced. */
|
||||
@ -12355,11 +12376,19 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
}
|
||||
}
|
||||
else {
|
||||
ssl->error = ret;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ret = RetrySendAlert(ssl);
|
||||
if (ret != 0) {
|
||||
ssl->error = ret;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
switch (ssl->options.acceptState) {
|
||||
|
||||
case ACCEPT_BEGIN :
|
||||
@ -12589,6 +12618,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ssl->error = 0; /* clear the error */
|
||||
|
||||
WOLFSSL_LEAVE("SSL_accept()", WOLFSSL_SUCCESS);
|
||||
return WOLFSSL_SUCCESS;
|
||||
|
45
src/tls13.c
45
src/tls13.c
@ -8689,6 +8689,8 @@ int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
*/
|
||||
int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_connect_TLSv13()");
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
@ -8696,7 +8698,8 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
|
||||
#endif
|
||||
|
||||
if (ssl->options.side != WOLFSSL_CLIENT_END) {
|
||||
WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
|
||||
ssl->error = SIDE_ERROR;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
@ -8706,7 +8709,8 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
|
||||
if ((ssl->ConnectFilter(ssl, ssl->ConnectFilter_arg, &res) ==
|
||||
WOLFSSL_SUCCESS) &&
|
||||
(res == WOLFSSL_NETFILTER_REJECT)) {
|
||||
WOLFSSL_ERROR(ssl->error = SOCKET_FILTERED_E);
|
||||
ssl->error = SOCKET_FILTERED_E;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
@ -8719,7 +8723,7 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
|
||||
&& ssl->error != WC_PENDING_E
|
||||
#endif
|
||||
) {
|
||||
if ((ssl->error = SendBuffered(ssl)) == 0) {
|
||||
if ((ret = SendBuffered(ssl)) == 0) {
|
||||
/* fragOffset is non-zero when sending fragments. On the last
|
||||
* fragment, fragOffset is zero again, and the state can be
|
||||
* advanced. */
|
||||
@ -8743,11 +8747,19 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
ssl->error = ret;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ret = RetrySendAlert(ssl);
|
||||
if (ret != 0) {
|
||||
ssl->error = ret;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
switch (ssl->options.connectState) {
|
||||
|
||||
case CONNECT_BEGIN:
|
||||
@ -8946,6 +8958,8 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
|
||||
FreeAsyncCtx(ssl, 1);
|
||||
#endif
|
||||
|
||||
ssl->error = 0; /* clear the error */
|
||||
|
||||
WOLFSSL_LEAVE("wolfSSL_connect_TLSv13()", WOLFSSL_SUCCESS);
|
||||
return WOLFSSL_SUCCESS;
|
||||
|
||||
@ -9609,6 +9623,7 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
||||
#if !defined(NO_CERTS) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
|
||||
word16 havePSK = 0;
|
||||
#endif
|
||||
int ret = 0;
|
||||
WOLFSSL_ENTER("SSL_accept_TLSv13()");
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
@ -9620,7 +9635,8 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
||||
#endif
|
||||
|
||||
if (ssl->options.side != WOLFSSL_SERVER_END) {
|
||||
WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
|
||||
ssl->error = SIDE_ERROR;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
@ -9630,7 +9646,8 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
||||
if ((ssl->AcceptFilter(ssl, ssl->AcceptFilter_arg, &res) ==
|
||||
WOLFSSL_SUCCESS) &&
|
||||
(res == WOLFSSL_NETFILTER_REJECT)) {
|
||||
WOLFSSL_ERROR(ssl->error = SOCKET_FILTERED_E);
|
||||
ssl->error = SOCKET_FILTERED_E;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
@ -9654,7 +9671,8 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
||||
!ssl->buffers.certificate->buffer) {
|
||||
|
||||
WOLFSSL_MSG("accept error: server cert required");
|
||||
WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY);
|
||||
ssl->error = NO_PRIVATE_KEY;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
@ -9672,7 +9690,8 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
||||
#endif
|
||||
{
|
||||
WOLFSSL_MSG("accept error: server key required");
|
||||
WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY);
|
||||
ssl->error = NO_PRIVATE_KEY;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
@ -9687,7 +9706,7 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
||||
&& ssl->error != WC_PENDING_E
|
||||
#endif
|
||||
) {
|
||||
if ((ssl->error = SendBuffered(ssl)) == 0) {
|
||||
if ((ret = SendBuffered(ssl)) == 0) {
|
||||
/* fragOffset is non-zero when sending fragments. On the last
|
||||
* fragment, fragOffset is zero again, and the state can be
|
||||
* advanced. */
|
||||
@ -9718,11 +9737,19 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
||||
}
|
||||
}
|
||||
else {
|
||||
ssl->error = ret;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ret = RetrySendAlert(ssl);
|
||||
if (ret != 0) {
|
||||
ssl->error = ret;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
switch (ssl->options.acceptState) {
|
||||
|
||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||
@ -9983,6 +10010,8 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
||||
FreeAsyncCtx(ssl, 1);
|
||||
#endif
|
||||
|
||||
ssl->error = 0; /* clear the error */
|
||||
|
||||
WOLFSSL_LEAVE("SSL_accept()", WOLFSSL_SUCCESS);
|
||||
return WOLFSSL_SUCCESS;
|
||||
|
||||
|
@ -3692,7 +3692,6 @@ typedef struct Options {
|
||||
word16 usingPSK_cipher:1; /* are using psk as cipher */
|
||||
word16 usingAnon_cipher:1; /* are we using an anon cipher */
|
||||
word16 noPskDheKe:1; /* Don't use (EC)DHE with PSK */
|
||||
word16 sendAlertState:1; /* nonblocking resume */
|
||||
word16 partialWrite:1; /* only one msg per write call */
|
||||
word16 quietShutdown:1; /* don't send close notify */
|
||||
word16 certOnly:1; /* stop once we get cert */
|
||||
@ -4324,6 +4323,7 @@ struct WOLFSSL {
|
||||
ClientSession* clientSession;
|
||||
#endif
|
||||
WOLFSSL_ALERT_HISTORY alert_history;
|
||||
WOLFSSL_ALERT pendingAlert;
|
||||
int error;
|
||||
int rfd; /* read file descriptor */
|
||||
int wfd; /* write file descriptor */
|
||||
@ -4839,6 +4839,7 @@ WOLFSSL_LOCAL int SendServerKeyExchange(WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL int SendBuffered(WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek);
|
||||
WOLFSSL_LOCAL int SendFinished(WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL int RetrySendAlert(WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL int SendAlert(WOLFSSL* ssl, int severity, int type);
|
||||
WOLFSSL_LOCAL int ProcessReply(WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr);
|
||||
|
@ -769,6 +769,7 @@ enum AlertDescription {
|
||||
|
||||
|
||||
enum AlertLevel {
|
||||
alert_none = 0, /* Used to indicate no alert level is set */
|
||||
alert_warning = 1,
|
||||
alert_fatal = 2
|
||||
};
|
||||
|
Reference in New Issue
Block a user