update base64 WOLFSSL_BIO encoding and checking session context ID

This commit is contained in:
Jacob Barthelmeh 2017-03-29 15:50:14 -06:00
parent b5ab505d1e
commit 32bf163633
5 changed files with 219 additions and 18 deletions

View File

@ -134,6 +134,7 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
{ {
int ret = 0; int ret = 0;
WOLFSSL_BIO* front = bio; WOLFSSL_BIO* front = bio;
int sz = 0;
WOLFSSL_ENTER("wolfSSL_BIO_read"); WOLFSSL_ENTER("wolfSSL_BIO_read");
@ -144,8 +145,8 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
while (bio != NULL && ret >= 0) { while (bio != NULL && ret >= 0) {
/* formating data */ /* formating data */
if (bio->type == WOLFSSL_BIO_BASE64 && ret > 0) { if (bio->type == WOLFSSL_BIO_BASE64 && ret > 0 && sz > 0) {
ret = wolfSSL_BIO_BASE64_read(bio, buf, len); ret = wolfSSL_BIO_BASE64_read(bio, buf, sz);
} }
/* write BIOs */ /* write BIOs */
@ -172,6 +173,10 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
break; /* at front of list so be done */ break; /* at front of list so be done */
} }
if (ret > 0) {
sz = ret; /* adjust size for formating */
}
/* previous WOLFSSL_BIO in list working towards head of list */ /* previous WOLFSSL_BIO in list working towards head of list */
bio = bio->prev; bio = bio->prev;
} }
@ -183,33 +188,47 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
static int wolfSSL_BIO_BASE64_write(WOLFSSL_BIO* bio, const void* data, static int wolfSSL_BIO_BASE64_write(WOLFSSL_BIO* bio, const void* data,
word32 inLen, byte* out, word32* outLen) word32 inLen, byte* out, word32* outLen)
{ {
byte* tmp = NULL;
int ret = 0;
WOLFSSL_ENTER("wolfSSL_BIO_BASE64_write"); WOLFSSL_ENTER("wolfSSL_BIO_BASE64_write");
#if defined(WOLFSSL_BASE64_ENCODE) #if defined(WOLFSSL_BASE64_ENCODE)
tmp = (byte*)XMALLOC(*outLen, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (tmp == NULL) {
return SSL_FATAL_ERROR;
}
if ((bio->flags & WOLFSSL_BIO_FLAG_BASE64_NO_NL) == if ((bio->flags & WOLFSSL_BIO_FLAG_BASE64_NO_NL) ==
WOLFSSL_BIO_FLAG_BASE64_NO_NL) { WOLFSSL_BIO_FLAG_BASE64_NO_NL) {
if (Base64_Encode_NoNl((const byte*)data, inLen, if (Base64_Encode_NoNl((const byte*)data, inLen,
out, outLen) < 0) { tmp, outLen) < 0) {
return SSL_FATAL_ERROR; ret = SSL_FATAL_ERROR;
} }
} }
else { else {
if (Base64_Encode((const byte*)data, inLen, if (Base64_Encode((const byte*)data, inLen,
out, outLen) < 0) { tmp, outLen) < 0) {
return SSL_FATAL_ERROR; ret = SSL_FATAL_ERROR;
} }
} }
return (int)*outLen; if (ret != SSL_FATAL_ERROR) {
ret = (int)*outLen;
XMEMCPY(out, tmp, *outLen);
}
XFREE(tmp, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
#else #else
(void)bio; (void)bio;
(void)data; (void)data;
(void)inLen; (void)inLen;
(void)out; (void)out;
(void)outLen; (void)outLen;
(void)tmp;
WOLFSSL_MSG("BASE64 encoding not compiled in"); WOLFSSL_MSG("BASE64 encoding not compiled in");
return 0;
#endif #endif
return ret;
} }
@ -362,6 +381,10 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
WOLFSSL_MSG("Memory error"); WOLFSSL_MSG("Memory error");
ret = SSL_FATAL_ERROR; ret = SSL_FATAL_ERROR;
} }
/* since frmt already existed then data should point to knew
formated buffer */
data = frmt;
len = frmtSz;
frmtSz = sz; frmtSz = sz;
} }
#endif /* defined(WOLFSSL_BASE64_ENCODE) */ #endif /* defined(WOLFSSL_BASE64_ENCODE) */

View File

@ -4355,6 +4355,12 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
ssl->alert_history.last_tx.code = -1; ssl->alert_history.last_tx.code = -1;
ssl->alert_history.last_tx.level = -1; ssl->alert_history.last_tx.level = -1;
#ifdef OPENSSL_EXTRA
/* copy over application session context ID */
ssl->sessionCtxSz = ctx->sessionCtxSz;
XMEMCPY(ssl->sessionCtx, ctx->sessionCtx, ctx->sessionCtxSz);
#endif
InitCiphers(ssl); InitCiphers(ssl);
InitCipherSpecs(&ssl->specs); InitCipherSpecs(&ssl->specs);

View File

@ -10143,6 +10143,17 @@ int SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
if (ssl->options.sessionCacheOff) if (ssl->options.sessionCacheOff)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
#ifdef OPENSSL_EXTRA
/* check for application context id */
if (ssl->sessionCtxSz > 0) {
if (XMEMCMP(ssl->sessionCtx, session->sessionCtx, ssl->sessionCtxSz)) {
/* context id did not match! */
WOLFSSL_MSG("Session context did not match");
return SSL_FAILURE;
}
}
#endif /* OPENSSL_EXTRA */
if (LowResTimer() < (session->bornOn + session->timeout)) { if (LowResTimer() < (session->bornOn + session->timeout)) {
int ret = GetDeepCopySession(ssl, session); int ret = GetDeepCopySession(ssl, session);
if (ret == WOLFSSL_SUCCESS) { if (ret == WOLFSSL_SUCCESS) {
@ -10251,6 +10262,14 @@ int AddSession(WOLFSSL* ssl)
XMEMCPY(session->sessionID, ssl->arrays->sessionID, ID_LEN); XMEMCPY(session->sessionID, ssl->arrays->sessionID, ID_LEN);
session->sessionIDSz = ssl->arrays->sessionIDSz; session->sessionIDSz = ssl->arrays->sessionIDSz;
#ifdef OPENSSL_EXTRA
/* If using compatibilty layer then check for and copy over session context
* id. */
if (ssl->sessionCtxSz > 0 && ssl->sessionCtxSz < ID_LEN) {
XMEMCPY(session->sessionCtx, ssl->sessionCtx, ssl->sessionCtxSz);
}
#endif
session->timeout = ssl->timeout; session->timeout = ssl->timeout;
session->bornOn = LowResTimer(); session->bornOn = LowResTimer();
@ -14292,8 +14311,16 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
#endif #endif
/* @TODO storing app session context id, now needs to tie in with InitSSL_CTX /* Storing app session context id, this value is inherited by WOLFSSL
* and with handshake. */ * objects created from WOLFSSL_CTX. Any session that is imported with a
* different session context id will be rejected.
*
* ctx structure to set context in
* sid_ctx value of context to set
* sid_ctx_len length of sid_ctx buffer
*
* Returns SSL_SUCCESS in success case and SSL_FAILURE when failing
*/
int wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX* ctx, int wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX* ctx,
const unsigned char* sid_ctx, const unsigned char* sid_ctx,
unsigned int sid_ctx_len) unsigned int sid_ctx_len)
@ -14305,6 +14332,8 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
return SSL_FAILURE; return SSL_FAILURE;
} }
XMEMCPY(ctx->sessionCtx, sid_ctx, sid_ctx_len); XMEMCPY(ctx->sessionCtx, sid_ctx, sid_ctx_len);
ctx->sessionCtxSz = sid_ctx_len;
return SSL_SUCCESS; return SSL_SUCCESS;
} }
@ -19805,6 +19834,10 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
#endif #endif
unsigned char *data; unsigned char *data;
if (sess == NULL) {
return BAD_FUNC_ARG;
}
/* bornOn | timeout | sessionID len | sessionID | masterSecret | haveEMS */ /* bornOn | timeout | sessionID len | sessionID | masterSecret | haveEMS */
size += OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN + sess->sessionIDSz + size += OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN + sess->sessionIDSz +
SECRET_LEN + OPAQUE8_LEN; SECRET_LEN + OPAQUE8_LEN;
@ -19824,6 +19857,10 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
/* ticket len | ticket */ /* ticket len | ticket */
size += OPAQUE16_LEN + sess->ticketLen; size += OPAQUE16_LEN + sess->ticketLen;
#endif #endif
#ifdef OPENSSL_EXTRA
/* session context ID len | session context ID */
size += OPAQUE8_LEN + sess->sessionCtxSz;
#endif
if (p != NULL) { if (p != NULL) {
if (*p == NULL) if (*p == NULL)
@ -19862,6 +19899,11 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
c16toa(sess->ticketLen, data + idx); idx += OPAQUE16_LEN; c16toa(sess->ticketLen, data + idx); idx += OPAQUE16_LEN;
XMEMCPY(data + idx, sess->ticket, sess->ticketLen); XMEMCPY(data + idx, sess->ticket, sess->ticketLen);
idx += sess->ticketLen; idx += sess->ticketLen;
#endif
#ifdef OPENSSL_EXTRA
data[idx++] = sess->sessionCtxSz;
XMEMCPY(data + idx, sess->sessionCtx, sess->sessionCtxSz);
idx += sess->sessionCtxSz;
#endif #endif
} }
#endif #endif
@ -20008,6 +20050,21 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
goto end; goto end;
} }
XMEMCPY(s->ticket, data + idx, s->ticketLen); idx += s->ticketLen; XMEMCPY(s->ticket, data + idx, s->ticketLen); idx += s->ticketLen;
#endif
#ifdef OPENSSL_EXTRA
/* byte for length of session context ID */
if (i - idx < OPAQUE8_LEN) {
ret = BUFFER_ERROR;
goto end;
}
s->sessionCtxSz = data[idx++];
/* app session context ID */
if (i - idx < s->sessionCtxSz) {
ret = BUFFER_ERROR;
goto end;
}
XMEMCPY(s->sessionCtx, data + idx, s->sessionCtxSz); idx += s->sessionCtxSz;
#endif #endif
(void)idx; (void)idx;

View File

@ -15546,13 +15546,13 @@ static void test_wolfSSL_BIO_gets(void)
static void test_wolfSSL_BIO_write(void) static void test_wolfSSL_BIO_write(void)
{ {
#if defined(OPENSSL_EXTRA) #if defined(OPENSSL_EXTRA) && defined(WOLFSSL_BASE64_ENCODE)
BIO* bio; BIO* bio;
BIO* bio64; BIO* bio64;
BIO* ptr; BIO* ptr;
int sz; int sz;
char msg[] = "conversion test"; char msg[] = "conversion test";
char out[25]; char out[40];
char expected[] = "Y29udmVyc2lvbiB0ZXN0AA==\n"; char expected[] = "Y29udmVyc2lvbiB0ZXN0AA==\n";
printf(testingFmt, "BIO_write()"); printf(testingFmt, "BIO_write()");
@ -15569,6 +15569,13 @@ static void test_wolfSSL_BIO_write(void)
AssertIntEQ((sz = BIO_read(ptr, out, sz)), 25); AssertIntEQ((sz = BIO_read(ptr, out, sz)), 25);
AssertIntEQ(XMEMCMP(out, expected, sz), 0); AssertIntEQ(XMEMCMP(out, expected, sz), 0);
/* write then read should return the same message */
AssertIntEQ(BIO_write(bio, msg, sizeof(msg)), 25);
sz = sizeof(out);
XMEMSET(out, 0, sz);
AssertIntEQ(BIO_read(bio, out, sz), 16);
AssertIntEQ(XMEMCMP(out, msg, sizeof(msg)), 0);
/* now try encoding with no line ending */ /* now try encoding with no line ending */
BIO_set_flags(bio64, BIO_FLAG_BASE64_NO_NL); BIO_set_flags(bio64, BIO_FLAG_BASE64_NO_NL);
AssertIntEQ(BIO_write(bio, msg, sizeof(msg)), 24); AssertIntEQ(BIO_write(bio, msg, sizeof(msg)), 24);
@ -15582,11 +15589,11 @@ static void test_wolfSSL_BIO_write(void)
/* test with more than one bio64 in list */ /* test with more than one bio64 in list */
AssertNotNull(bio64 = BIO_new(BIO_f_base64())); AssertNotNull(bio64 = BIO_new(BIO_f_base64()));
AssertNotNull(bio = BIO_push(bio64, BIO_new(BIO_f_base64()))); AssertNotNull(bio = BIO_push(BIO_new(BIO_f_base64()), bio64));
AssertNotNull(bio = BIO_push(bio, BIO_new(BIO_s_mem()))); AssertNotNull(BIO_push(bio64, BIO_new(BIO_s_mem())));
/* now should convert to base64(x2) when stored and then decode with read */ /* now should convert to base64(x2) when stored and then decode with read */
AssertIntEQ(BIO_write(bio, msg, sizeof(msg)), 25); AssertIntEQ(BIO_write(bio, msg, sizeof(msg)), 37);
BIO_flush(bio); BIO_flush(bio);
sz = sizeof(out); sz = sizeof(out);
XMEMSET(out, 0, sz); XMEMSET(out, 0, sz);
@ -15600,10 +15607,110 @@ static void test_wolfSSL_BIO_write(void)
static void test_wolfSSL_SESSION(void) static void test_wolfSSL_SESSION(void)
{ {
#if defined(OPENSSL_EXTRA) #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
printf(testingFmt, "no_op_functions()"); !defined(NO_RSA) && defined(HAVE_EXT_CACHE) && \
defined(HAVE_IO_TESTS_DEPENDENCIES)
WOLFSSL* ssl;
WOLFSSL_CTX* ctx;
WOLFSSL_SESSION* sess;
const unsigned char context[] = "user app context";
unsigned char* sessDer = NULL;
unsigned char* ptr = NULL;
unsigned int contextSz = (unsigned int)sizeof(context);
int ret, err, sockfd, sz;
tcp_ready ready;
func_args server_args;
THREAD_TYPE serverThread;
printf(testingFmt, "wolfSSL_SESSION()");
AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
AssertTrue(wolfSSL_CTX_use_certificate_file(ctx, cliCertFile, SSL_FILETYPE_PEM));
AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile, SSL_FILETYPE_PEM));
AssertIntEQ(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0), SSL_SUCCESS);
wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
XMEMSET(&server_args, 0, sizeof(func_args));
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
StartTCP();
InitTcpReady(&ready);
#if defined(USE_WINDOWS_API)
/* use RNG to get random port if using windows */
ready.port = GetRandomPort();
#endif
server_args.signal = &ready;
start_thread(test_server_nofail, &server_args, &serverThread);
wait_tcp_ready(&server_args);
/* client connection */
ssl = wolfSSL_new(ctx);
tcp_connect(&sockfd, wolfSSLIP, ready.port, 0, 0, ssl);
AssertIntEQ(wolfSSL_set_fd(ssl, sockfd), SSL_SUCCESS);
do {
#ifdef WOLFSSL_ASYNC_CRYPT
if (err == WC_PENDING_E) {
ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
if (ret < 0) { break; } else if (ret == 0) { continue; }
}
#endif
err = 0; /* Reset error */
ret = wolfSSL_connect(ssl);
if (ret != SSL_SUCCESS) {
err = wolfSSL_get_error(ssl, 0);
}
} while (ret != SSL_SUCCESS && err == WC_PENDING_E);
AssertIntEQ(ret, SSL_SUCCESS);
sess = wolfSSL_get_session(ssl);
wolfSSL_shutdown(ssl);
wolfSSL_free(ssl);
join_thread(serverThread);
FreeTcpReady(&ready);
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
/* get session from DER and update the timeout */
AssertIntEQ(wolfSSL_i2d_SSL_SESSION(NULL, &sessDer), BAD_FUNC_ARG);
AssertIntGT((sz = wolfSSL_i2d_SSL_SESSION(sess, &sessDer)), 0);
wolfSSL_SESSION_free(sess);
ptr = sessDer;
AssertNull(sess = wolfSSL_d2i_SSL_SESSION(NULL, NULL, sz));
AssertNotNull(sess = wolfSSL_d2i_SSL_SESSION(NULL,
(const unsigned char**)&ptr, sz));
XFREE(sessDer, NULL, DYNAMIC_TYPE_OPENSSL);
AssertIntGT(wolfSSL_SESSION_get_time(sess), 0);
AssertIntEQ(wolfSSL_SSL_SESSION_set_timeout(sess, 500), SSL_SUCCESS);
/* successful set session test */
AssertNotNull(ssl = wolfSSL_new(ctx));
AssertIntEQ(wolfSSL_set_session(ssl, sess), SSL_SUCCESS);
wolfSSL_free(ssl);
/* fail case with miss match session context IDs (use compatibility API) */
AssertIntEQ(SSL_CTX_set_session_id_context(NULL, context, contextSz),
SSL_FAILURE);
AssertIntEQ(SSL_CTX_set_session_id_context(ctx, context, contextSz),
SSL_SUCCESS);
AssertNotNull(ssl = wolfSSL_new(ctx));
AssertIntEQ(wolfSSL_set_session(ssl, sess), SSL_FAILURE);
wolfSSL_free(ssl);
wolfSSL_SESSION_free(sess);
wolfSSL_CTX_free(ctx);
printf(resultFmt, passed); printf(resultFmt, passed);
#endif #endif
} }

View File

@ -2682,6 +2682,10 @@ struct WOLFSSL_SESSION {
word16 idLen; /* serverID length */ word16 idLen; /* serverID length */
byte serverID[SERVER_ID_LEN]; /* for easier client lookup */ byte serverID[SERVER_ID_LEN]; /* for easier client lookup */
#endif #endif
#ifdef OPENSSL_EXTRA
byte sessionCtxSz; /* sessionCtx length */
byte sessionCtx[ID_LEN]; /* app specific context id */
#endif
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
byte namedGroup; byte namedGroup;
@ -2694,6 +2698,8 @@ struct WOLFSSL_SESSION {
#ifdef WOLFSSL_EARLY_DATA #ifdef WOLFSSL_EARLY_DATA
word32 maxEarlyDataSz; word32 maxEarlyDataSz;
#endif #endif
#endif
#ifdef HAVE_SESSION_TICKET
byte* ticket; byte* ticket;
word16 ticketLen; word16 ticketLen;
byte staticTicket[SESSION_TICKET_LEN]; byte staticTicket[SESSION_TICKET_LEN];
@ -3319,8 +3325,10 @@ struct WOLFSSL {
CallbackInfoState* CBIS; /* used to get info about SSL state */ CallbackInfoState* CBIS; /* used to get info about SSL state */
WOLFSSL_BIO* biord; /* socket bio read to free/close */ WOLFSSL_BIO* biord; /* socket bio read to free/close */
WOLFSSL_BIO* biowr; /* socket bio write to free/close */ WOLFSSL_BIO* biowr; /* socket bio write to free/close */
byte sessionCtx[ID_LEN]; /* app session context ID */
unsigned long peerVerifyRet; unsigned long peerVerifyRet;
byte readAhead; byte readAhead;
byte sessionCtxSz; /* size of sessionCtx stored */
#ifdef HAVE_PK_CALLBACKS #ifdef HAVE_PK_CALLBACKS
void* loggingCtx; /* logging callback argument */ void* loggingCtx; /* logging callback argument */
#endif #endif