mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 18:57:27 +02:00
Merge pull request #2379 from JacobBarthelmeh/sessionExport
reduce size of state only save and add option to remove peer info
This commit is contained in:
@ -4284,13 +4284,19 @@ AC_ARG_ENABLE([sessionexport],
|
||||
[ ENABLED_SESSIONEXPORT=no ]
|
||||
)
|
||||
|
||||
if test "$ENABLED_SESSIONEXPORT" = "yes"
|
||||
if test "$ENABLED_SESSIONEXPORT" = "yes" ||
|
||||
test "$ENABLED_SESSIONEXPORT" = "nopeer"
|
||||
then
|
||||
if test "$ENABLED_DTLS" = "no"
|
||||
then
|
||||
AC_MSG_ERROR([Only DTLS supported with session export])
|
||||
fi
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SESSION_EXPORT"
|
||||
|
||||
if test "$ENABLED_SESSIONEXPORT" = "nopeer"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SESSION_EXPORT_NOPEER"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
140
src/internal.c
140
src/internal.c
@ -485,7 +485,8 @@ static int ExportCipherSpecState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
|
||||
|
||||
/* serializes the key struct for exporting */
|
||||
static int ExportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
static int ExportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver,
|
||||
byte small)
|
||||
{
|
||||
word32 idx = 0;
|
||||
byte sz;
|
||||
@ -499,12 +500,12 @@ static int ExportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
|
||||
keys = &(ssl->keys);
|
||||
|
||||
if (DTLS_EXPORT_KEY_SZ > len) {
|
||||
WOLFSSL_MSG("Buffer not large enough for max key struct size");
|
||||
if (DTLS_EXPORT_MIN_KEY_SZ > len) {
|
||||
WOLFSSL_MSG("Buffer not large enough for minimum key struct size");
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
XMEMSET(exp, 0, DTLS_EXPORT_KEY_SZ);
|
||||
XMEMSET(exp, 0, DTLS_EXPORT_MIN_KEY_SZ);
|
||||
|
||||
c32toa(keys->peer_sequence_number_hi, exp + idx); idx += OPAQUE32_LEN;
|
||||
c32toa(keys->peer_sequence_number_lo, exp + idx); idx += OPAQUE32_LEN;
|
||||
@ -535,8 +536,15 @@ static int ExportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
exp[idx++] = keys->encryptionOn;
|
||||
exp[idx++] = keys->decryptedCur;
|
||||
|
||||
/* from here on the buffer needs checked because is variable length that
|
||||
* can be larger than DTLS_EXPORT_MIN_KEY_SZ */
|
||||
{
|
||||
word32 i;
|
||||
if ((OPAQUE16_LEN * 2) + idx +
|
||||
(2 * (WOLFSSL_DTLS_WINDOW_WORDS * OPAQUE32_LEN)) > len) {
|
||||
WOLFSSL_MSG("Buffer not large enough for WOLFSSL_DTLS_WINDOW_WORDS");
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
c16toa(WOLFSSL_DTLS_WINDOW_WORDS, exp + idx); idx += OPAQUE16_LEN;
|
||||
for (i = 0; i < WOLFSSL_DTLS_WINDOW_WORDS; i++) {
|
||||
@ -550,6 +558,11 @@ static int ExportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
}
|
||||
}
|
||||
|
||||
if (idx >= len) {
|
||||
WOLFSSL_MSG("Buffer not large enough for truncated hmac flag");
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
#ifdef HAVE_TRUNCATED_HMAC
|
||||
sz = ssl->truncated_hmac ? TRUNCATED_HMAC_SZ: ssl->specs.hash_size;
|
||||
exp[idx++] = ssl->truncated_hmac;
|
||||
@ -557,31 +570,60 @@ static int ExportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
sz = ssl->specs.hash_size;
|
||||
exp[idx++] = 0; /* no truncated hmac */
|
||||
#endif
|
||||
exp[idx++] = sz;
|
||||
#ifndef WOLFSSL_AEAD_ONLY
|
||||
XMEMCPY(exp + idx, keys->client_write_MAC_secret, sz); idx += sz;
|
||||
XMEMCPY(exp + idx, keys->server_write_MAC_secret, sz); idx += sz;
|
||||
#else
|
||||
XMEMSET(exp + idx, 0, sz); idx += sz;
|
||||
XMEMSET(exp + idx, 0, sz); idx += sz;
|
||||
#endif
|
||||
|
||||
sz = ssl->specs.key_size;
|
||||
exp[idx++] = sz;
|
||||
XMEMCPY(exp + idx, keys->client_write_key, sz); idx += sz;
|
||||
XMEMCPY(exp + idx, keys->server_write_key, sz); idx += sz;
|
||||
sz = (small)? 0: sz;
|
||||
if (idx + (sz * 2) + OPAQUE8_LEN > len) {
|
||||
WOLFSSL_MSG("Buffer not large enough for MAC secret");
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
sz = ssl->specs.iv_size;
|
||||
exp[idx++] = sz;
|
||||
XMEMCPY(exp + idx, keys->client_write_IV, sz); idx += sz;
|
||||
XMEMCPY(exp + idx, keys->server_write_IV, sz); idx += sz;
|
||||
if (sz > 0) {
|
||||
#ifndef WOLFSSL_AEAD_ONLY
|
||||
XMEMCPY(exp + idx, keys->client_write_MAC_secret, sz); idx += sz;
|
||||
XMEMCPY(exp + idx, keys->server_write_MAC_secret, sz); idx += sz;
|
||||
#else
|
||||
XMEMSET(exp + idx, 0, sz); idx += sz;
|
||||
XMEMSET(exp + idx, 0, sz); idx += sz;
|
||||
#endif
|
||||
}
|
||||
|
||||
sz = (small)? 0: ssl->specs.key_size;
|
||||
if (idx + (sz * 2) + OPAQUE8_LEN > len) {
|
||||
WOLFSSL_MSG("Buffer not large enough for write key");
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
exp[idx++] = sz;
|
||||
if (sz > 0) {
|
||||
XMEMCPY(exp + idx, keys->client_write_key, sz); idx += sz;
|
||||
XMEMCPY(exp + idx, keys->server_write_key, sz); idx += sz;
|
||||
}
|
||||
|
||||
sz = (small)? 0: ssl->specs.iv_size;
|
||||
if (idx + (sz * 2) + OPAQUE8_LEN + AEAD_MAX_EXP_SZ > len) {
|
||||
WOLFSSL_MSG("Buffer not large enough for IVs");
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
exp[idx++] = sz;
|
||||
if (sz > 0) {
|
||||
XMEMCPY(exp + idx, keys->client_write_IV, sz); idx += sz;
|
||||
XMEMCPY(exp + idx, keys->server_write_IV, sz); idx += sz;
|
||||
}
|
||||
XMEMCPY(exp + idx, keys->aead_exp_IV, AEAD_MAX_EXP_SZ);
|
||||
idx += AEAD_MAX_EXP_SZ;
|
||||
|
||||
sz = AEAD_MAX_IMP_SZ;
|
||||
sz = (small)? 0: AEAD_MAX_IMP_SZ;
|
||||
if (idx + (sz * 2) + OPAQUE8_LEN > len) {
|
||||
WOLFSSL_MSG("Buffer not large enough for imp IVs");
|
||||
return BUFFER_E;
|
||||
}
|
||||
exp[idx++] = sz;
|
||||
XMEMCPY(exp + idx, keys->aead_enc_imp_IV, sz); idx += sz;
|
||||
XMEMCPY(exp + idx, keys->aead_dec_imp_IV, sz); idx += sz;
|
||||
if (sz > 0) {
|
||||
XMEMCPY(exp + idx, keys->aead_enc_imp_IV, sz); idx += sz;
|
||||
XMEMCPY(exp + idx, keys->aead_dec_imp_IV, sz); idx += sz;
|
||||
}
|
||||
|
||||
/* DTLS_EXPORT_KEY_SZ is max value. idx size can vary */
|
||||
if (idx > DTLS_EXPORT_KEY_SZ) {
|
||||
@ -647,6 +689,7 @@ static int ImportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
|
||||
/* check minimum length -- includes byte used for size indicators */
|
||||
if (len < DTLS_EXPORT_MIN_KEY_SZ) {
|
||||
WOLFSSL_MSG("Buffer not large enough for minimum expected size");
|
||||
return BUFFER_E;
|
||||
}
|
||||
ato32(exp + idx, &keys->peer_sequence_number_hi); idx += OPAQUE32_LEN;
|
||||
@ -722,11 +765,14 @@ static int ImportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
#endif
|
||||
sz = exp[idx++];
|
||||
#ifndef WOLFSSL_AEAD_ONLY
|
||||
if (sz > sizeof(keys->client_write_MAC_secret) || sz + idx > len) {
|
||||
if (sz > sizeof(keys->client_write_MAC_secret) || (sz * 2) + idx > len) {
|
||||
WOLFSSL_MSG("Buffer not large enough for MAC import");
|
||||
return BUFFER_E;
|
||||
}
|
||||
XMEMCPY(keys->client_write_MAC_secret, exp + idx, sz); idx += sz;
|
||||
XMEMCPY(keys->server_write_MAC_secret, exp + idx, sz); idx += sz;
|
||||
if (sz > 0) {
|
||||
XMEMCPY(keys->client_write_MAC_secret, exp + idx, sz); idx += sz;
|
||||
XMEMCPY(keys->server_write_MAC_secret, exp + idx, sz); idx += sz;
|
||||
}
|
||||
#else
|
||||
if (sz + idx > len) {
|
||||
return BUFFER_E;
|
||||
@ -735,27 +781,36 @@ static int ImportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
#endif
|
||||
|
||||
sz = exp[idx++];
|
||||
if (sz > sizeof(keys->client_write_key) || sz + idx > len) {
|
||||
if (sz > sizeof(keys->client_write_key) || (sz * 2) + idx > len) {
|
||||
WOLFSSL_MSG("Buffer not large enough for key import");
|
||||
return BUFFER_E;
|
||||
}
|
||||
XMEMCPY(keys->client_write_key, exp + idx, sz); idx += sz;
|
||||
XMEMCPY(keys->server_write_key, exp + idx, sz); idx += sz;
|
||||
if (sz > 0) {
|
||||
XMEMCPY(keys->client_write_key, exp + idx, sz); idx += sz;
|
||||
XMEMCPY(keys->server_write_key, exp + idx, sz); idx += sz;
|
||||
}
|
||||
|
||||
sz = exp[idx++];
|
||||
if (sz > sizeof(keys->client_write_IV) || sz + idx > len) {
|
||||
if (sz > sizeof(keys->client_write_IV) || (sz * 2) + idx > len) {
|
||||
WOLFSSL_MSG("Buffer not large enough for write IV import");
|
||||
return BUFFER_E;
|
||||
}
|
||||
XMEMCPY(keys->client_write_IV, exp + idx, sz); idx += sz;
|
||||
XMEMCPY(keys->server_write_IV, exp + idx, sz); idx += sz;
|
||||
if (sz > 0) {
|
||||
XMEMCPY(keys->client_write_IV, exp + idx, sz); idx += sz;
|
||||
XMEMCPY(keys->server_write_IV, exp + idx, sz); idx += sz;
|
||||
}
|
||||
XMEMCPY(keys->aead_exp_IV, exp + idx, AEAD_MAX_EXP_SZ);
|
||||
idx += AEAD_MAX_EXP_SZ;
|
||||
|
||||
sz = exp[idx++];
|
||||
if (sz > sizeof(keys->aead_enc_imp_IV) || sz + idx > len) {
|
||||
if (sz > sizeof(keys->aead_enc_imp_IV) || (sz * 2) + idx > len) {
|
||||
WOLFSSL_MSG("Buffer not large enough for imp IV import");
|
||||
return BUFFER_E;
|
||||
}
|
||||
XMEMCPY(keys->aead_enc_imp_IV, exp + idx, sz); idx += sz;
|
||||
XMEMCPY(keys->aead_dec_imp_IV, exp + idx, sz); idx += sz;
|
||||
if (sz > 0) {
|
||||
XMEMCPY(keys->aead_enc_imp_IV, exp + idx, sz); idx += sz;
|
||||
XMEMCPY(keys->aead_dec_imp_IV, exp + idx, sz); idx += sz;
|
||||
}
|
||||
|
||||
WOLFSSL_LEAVE("ImportKeyState", idx);
|
||||
(void)ver;
|
||||
@ -1053,6 +1108,7 @@ static int dtls_export_load(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
return idx;
|
||||
}
|
||||
|
||||
#ifndef WOLFSSL_SESSION_EXPORT_NOPEER
|
||||
static int ExportPeerInfo(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
{
|
||||
int idx = 0;
|
||||
@ -1092,6 +1148,7 @@ static int ExportPeerInfo(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
|
||||
return idx;
|
||||
}
|
||||
#endif /* !WOLFSSL_SESSION_EXPORT_NOPEER */
|
||||
|
||||
|
||||
static int ImportPeerInfo(WOLFSSL* ssl, byte* buf, word32 len, byte ver)
|
||||
@ -1107,6 +1164,11 @@ static int ImportPeerInfo(WOLFSSL* ssl, byte* buf, word32 len, byte ver)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
WOLFSSL_MSG("No peer info sent");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ssl == NULL || buf == NULL || len < 3 * DTLS_EXPORT_LEN) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
@ -1157,7 +1219,7 @@ int wolfSSL_dtls_export_state_internal(WOLFSSL* ssl, byte* buf, word32 sz)
|
||||
|
||||
totalLen += DTLS_EXPORT_LEN * 2; /* 2 protocol bytes and 2 length bytes */
|
||||
/* each of the following have a 2 byte length before data */
|
||||
totalLen += DTLS_EXPORT_LEN + DTLS_EXPORT_KEY_SZ;
|
||||
totalLen += DTLS_EXPORT_LEN + DTLS_EXPORT_MIN_KEY_SZ;
|
||||
if (totalLen > sz) {
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export_state_internal", BUFFER_E);
|
||||
return BUFFER_E;
|
||||
@ -1171,7 +1233,7 @@ int wolfSSL_dtls_export_state_internal(WOLFSSL* ssl, byte* buf, word32 sz)
|
||||
/* export keys struct and dtls state -- variable length stored in ret */
|
||||
idx += DTLS_EXPORT_LEN; /* leave room for length */
|
||||
if ((ret = ExportKeyState(ssl, buf + idx, sz - idx,
|
||||
DTLS_EXPORT_VERSION)) < 0) {
|
||||
DTLS_EXPORT_VERSION, 1)) < 0) {
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export_state_internal", ret);
|
||||
return ret;
|
||||
}
|
||||
@ -1242,7 +1304,7 @@ int wolfSSL_dtls_export_internal(WOLFSSL* ssl, byte* buf, word32 sz)
|
||||
/* export keys struct and dtls state -- variable length stored in ret */
|
||||
idx += DTLS_EXPORT_LEN; /* leave room for length */
|
||||
if ((ret = ExportKeyState(ssl, buf + idx, sz - idx,
|
||||
DTLS_EXPORT_VERSION)) < 0) {
|
||||
DTLS_EXPORT_VERSION, 0)) < 0) {
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", ret);
|
||||
return ret;
|
||||
}
|
||||
@ -1259,11 +1321,15 @@ int wolfSSL_dtls_export_internal(WOLFSSL* ssl, byte* buf, word32 sz)
|
||||
|
||||
/* export of dtls peer information */
|
||||
idx += DTLS_EXPORT_LEN;
|
||||
#ifdef WOLFSSL_SESSION_EXPORT_NOPEER
|
||||
ret = 0; /* not saving peer port/ip information */
|
||||
#else
|
||||
if ((ret = ExportPeerInfo(ssl, buf + idx, sz - idx,
|
||||
DTLS_EXPORT_VERSION)) < 0) {
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
c16toa(ret, buf + idx - DTLS_EXPORT_LEN);
|
||||
idx += ret;
|
||||
|
||||
|
@ -1286,13 +1286,13 @@ enum Misc {
|
||||
DTLS_EXPORT_OPT_SZ_3 = 59, /* amount of bytes used from Options */
|
||||
DTLS_EXPORT_KEY_SZ = 325 + (DTLS_SEQ_SZ * 2),
|
||||
/* max amount of bytes used from Keys */
|
||||
DTLS_EXPORT_MIN_KEY_SZ = 78 + (DTLS_SEQ_SZ * 2),
|
||||
DTLS_EXPORT_MIN_KEY_SZ = 85 + (DTLS_SEQ_SZ * 2),
|
||||
/* min amount of bytes used from Keys */
|
||||
DTLS_EXPORT_SPC_SZ = 16, /* amount of bytes used from CipherSpecs */
|
||||
DTLS_EXPORT_LEN = 2, /* 2 bytes for length and protocol */
|
||||
DTLS_EXPORT_IP = 46, /* max ip size IPv4 mapped IPv6 */
|
||||
MAX_EXPORT_BUFFER = 514, /* max size of buffer for exporting */
|
||||
MAX_EXPORT_STATE_BUFFER = DTLS_EXPORT_KEY_SZ + 3 * DTLS_EXPORT_LEN,
|
||||
MAX_EXPORT_STATE_BUFFER = (DTLS_EXPORT_MIN_KEY_SZ) + (3 * DTLS_EXPORT_LEN),
|
||||
/* max size of buffer for exporting state */
|
||||
FINISHED_LABEL_SZ = 15, /* TLS finished label size */
|
||||
TLS_FINISHED_SZ = 12, /* TLS has a shorter size */
|
||||
|
Reference in New Issue
Block a user