From 22b6cc675a6dcae891dd59d53320816a665ba2c5 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Mon, 24 May 2021 23:04:59 +0700 Subject: [PATCH] add import/export of peer info with tls --- src/internal.c | 72 +++++++++++++++++++++---------------------- src/wolfio.c | 77 ++++++++++++++++++++++++++++++++++++---------- wolfssl/internal.h | 7 +++-- wolfssl/wolfio.h | 28 ++++++++--------- 4 files changed, 114 insertions(+), 70 deletions(-) diff --git a/src/internal.c b/src/internal.c index 4c5af8058..8773a7cd1 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1370,15 +1370,14 @@ static int ImportOptions(WOLFSSL* ssl, const byte* exp, word32 len, byte ver, } -#ifdef WOLFSSL_DTLS #ifndef WOLFSSL_SESSION_EXPORT_NOPEER static int ExportPeerInfo(WOLFSSL* ssl, byte* exp, word32 len, byte ver) { int idx = 0; - int ipSz = DTLS_EXPORT_IP; /* start as max size */ + int ipSz = MAX_EXPORT_IP; /* start as max size */ int fam = 0; word16 port = 0; - char ip[DTLS_EXPORT_IP]; + char ip[MAX_EXPORT_IP]; if (ver != WOLFSSL_EXPORT_VERSION) { WOLFSSL_MSG("Export version not supported"); @@ -1399,7 +1398,7 @@ static int ExportPeerInfo(WOLFSSL* ssl, byte* exp, word32 len, byte ver) } /* check that ipSz/fam is not negative or too large since user can set cb */ - if (ipSz < 0 || ipSz > DTLS_EXPORT_IP || fam < 0) { + if (ipSz < 0 || ipSz > MAX_EXPORT_IP || fam < 0) { WOLFSSL_MSG("Bad ipSz or fam returned from get peer callback"); return SOCKET_ERROR_E; } @@ -1420,7 +1419,7 @@ static int ImportPeerInfo(WOLFSSL* ssl, const byte* buf, word32 len, byte ver) word16 ipSz; word16 fam; word16 port; - char ip[DTLS_EXPORT_IP]; + char ip[MAX_EXPORT_IP]; if (ver != WOLFSSL_EXPORT_VERSION && ver != WOLFSSL_EXPORT_VERSION_3) { WOLFSSL_MSG("Export version not supported"); @@ -1463,6 +1462,7 @@ static int ImportPeerInfo(WOLFSSL* ssl, const byte* buf, word32 len, byte ver) } +#ifdef WOLFSSL_DTLS /* WOLFSSL_LOCAL function that serializes the current WOLFSSL session state only * buf is used to hold the serialized WOLFSSL struct and sz is the size of buf * passed in. @@ -1669,7 +1669,12 @@ int wolfSSL_session_import_internal(WOLFSSL* ssl, const unsigned char* buf, if (ret == 0) { switch (version) { case WOLFSSL_EXPORT_VERSION: - optSz = DTLS_EXPORT_OPT_SZ; + if (!isTLS) { + optSz = DTLS_EXPORT_OPT_SZ; + } + else { + optSz = TLS_EXPORT_OPT_SZ; + } break; case WOLFSSL_EXPORT_VERSION_3: @@ -1758,32 +1763,28 @@ int wolfSSL_session_import_internal(WOLFSSL* ssl, const unsigned char* buf, } /* perform sanity checks and extract DTLS peer info */ - if (!isTLS) { - if (ret == 0 && (WOLFSSL_EXPORT_LEN + idx > sz)) { + if (ret == 0 && (WOLFSSL_EXPORT_LEN + idx > sz)) { + WOLFSSL_MSG("Import DTLS peer info error"); + ret = BUFFER_E; + } + + if (ret == 0) { + ato16(buf + idx, &length); idx += WOLFSSL_EXPORT_LEN; + if (idx + length > sz) { WOLFSSL_MSG("Import DTLS peer info error"); ret = BUFFER_E; } + } - if (ret == 0) { - ato16(buf + idx, &length); idx += WOLFSSL_EXPORT_LEN; - if (idx + length > sz) { - WOLFSSL_MSG("Import DTLS peer info error"); - ret = BUFFER_E; - } + if (ret == 0) { + rc = ImportPeerInfo(ssl, buf + idx, length, version); + if (rc < 0) { + WOLFSSL_MSG("Import Peer Addr error"); + ret = rc; } - - #ifdef WOLFSSL_DTLS - if (ret == 0) { - rc = ImportPeerInfo(ssl, buf + idx, length, version); - if (rc < 0) { - WOLFSSL_MSG("Import Peer Addr error"); - ret = rc; - } - else { - idx += rc; - } + else { + idx += rc; } - #endif } /* make sure is a valid suite used */ @@ -1870,12 +1871,13 @@ int wolfSSL_session_export_internal(WOLFSSL* ssl, byte* buf, word32* sz, buf[idx++] = ((byte)((isTLS)? TLS_EXPORT_PRO : DTLS_EXPORT_PRO) & 0xF0) | ((byte)WOLFSSL_EXPORT_VERSION & 0X0F); - idx += WOLFSSL_EXPORT_LEN; /* leave spot for length */ - c16toa((word16)DTLS_EXPORT_OPT_SZ, buf + idx); + idx += WOLFSSL_EXPORT_LEN; /* leave spot for length of total buffer */ + idx += WOLFSSL_EXPORT_LEN; ret = ExportOptions(ssl, buf + idx, *sz - idx, WOLFSSL_EXPORT_VERSION, isTLS); if (ret >= 0) { + c16toa((word16)ret, buf + idx - WOLFSSL_EXPORT_LEN); idx += ret; ret = 0; } @@ -1904,9 +1906,8 @@ int wolfSSL_session_export_internal(WOLFSSL* ssl, byte* buf, word32* sz, } } - /* export of dtls peer information */ -#ifdef WOLFSSL_DTLS - if (ret == 0 && !isTLS) { + /* export of peer information */ + if (ret == 0) { idx += WOLFSSL_EXPORT_LEN; #ifdef WOLFSSL_SESSION_EXPORT_NOPEER ret = 0; /* not saving peer port/ip information */ @@ -1919,7 +1920,6 @@ int wolfSSL_session_export_internal(WOLFSSL* ssl, byte* buf, word32* sz, ret = 0; } } -#endif if (ret != 0) { /*in a fail case clear the buffer which could contain partial key info*/ @@ -2071,15 +2071,15 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) #else ctx->CBIORecv = EmbedReceive; ctx->CBIOSend = EmbedSend; + #ifdef WOLFSSL_SESSION_EXPORT + ctx->CBGetPeer = EmbedGetPeer; + ctx->CBSetPeer = EmbedSetPeer; + #endif #ifdef WOLFSSL_DTLS if (method->version.major == DTLS_MAJOR) { ctx->CBIORecv = EmbedReceiveFrom; ctx->CBIOSend = EmbedSendTo; } - #ifdef WOLFSSL_SESSION_EXPORT - ctx->CBGetPeer = EmbedGetPeer; - ctx->CBSetPeer = EmbedSetPeer; - #endif #endif #endif /* MICRIUM */ #endif /* WOLFSSL_USER_IO */ diff --git a/src/wolfio.c b/src/wolfio.c index 23afcb812..020c3dc21 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -477,25 +477,18 @@ int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx) return sz; } +#endif /* WOLFSSL_DTLS */ #ifdef WOLFSSL_SESSION_EXPORT - /* get the peer information in human readable form (ip, port, family) - * default function assumes BSD sockets - * can be overridden with wolfSSL_CTX_SetIOGetPeer - */ - int EmbedGetPeer(WOLFSSL* ssl, char* ip, int* ipSz, +#ifdef WOLFSSL_DTLS + static int EmbedGetPeerDTLS(WOLFSSL* ssl, char* ip, int* ipSz, unsigned short* port, int* fam) { SOCKADDR_S peer; word32 peerSz; int ret; - if (ssl == NULL || ip == NULL || ipSz == NULL || - port == NULL || fam == NULL) { - return BAD_FUNC_ARG; - } - /* get peer information stored in ssl struct */ peerSz = sizeof(SOCKADDR_S); if ((ret = wolfSSL_dtls_get_peer(ssl, (void*)&peer, &peerSz)) @@ -536,11 +529,7 @@ int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx) return WOLFSSL_SUCCESS; } - /* set the peer information in human readable form (ip, port, family) - * default function assumes BSD sockets - * can be overridden with wolfSSL_CTX_SetIOSetPeer - */ - int EmbedSetPeer(WOLFSSL* ssl, char* ip, int ipSz, + static int EmbedSetPeerDTLS(WOLFSSL* ssl, char* ip, int ipSz, unsigned short port, int fam) { int ret; @@ -594,8 +583,62 @@ int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx) return WOLFSSL_SUCCESS; } +#endif + + /* get the peer information in human readable form (ip, port, family) + * default function assumes BSD sockets + * can be overridden with wolfSSL_CTX_SetIOGetPeer + */ + int EmbedGetPeer(WOLFSSL* ssl, char* ip, int* ipSz, + unsigned short* port, int* fam) + { + if (ssl == NULL || ip == NULL || ipSz == NULL || + port == NULL || fam == NULL) { + return BAD_FUNC_ARG; + } + + if (ssl->options.dtls) { + #ifdef WOLFSSL_DTLS + return EmbedGetPeerDTLS(ssl, ip, ipSz, port, fam); + #else + return NOT_COMPILED_IN; + #endif + } + else { + *port = wolfSSL_get_fd(ssl); + ip[0] = '\0'; + *ipSz = 0; + *fam = 0; + return WOLFSSL_SUCCESS; + } + } + + /* set the peer information in human readable form (ip, port, family) + * default function assumes BSD sockets + * can be overridden with wolfSSL_CTX_SetIOSetPeer + */ + int EmbedSetPeer(WOLFSSL* ssl, char* ip, int ipSz, + unsigned short port, int fam) + { + /* sanity checks on arguments */ + if (ssl == NULL || ip == NULL || ipSz < 0 || ipSz > MAX_EXPORT_IP) { + return BAD_FUNC_ARG; + } + + if (ssl->options.dtls) { + #ifdef WOLFSSL_DTLS + return EmbedSetPeerDTLS(ssl, ip, ipSz, port, fam); + #else + return NOT_COMPILED_IN; + #endif + } + else { + wolfSSL_set_fd(ssl, port); + (void)fam; + return WOLFSSL_SUCCESS; + } + } #endif /* WOLFSSL_SESSION_EXPORT */ -#endif /* WOLFSSL_DTLS */ #ifdef WOLFSSL_LINUXKM static int linuxkm_send(struct socket *socket, void *buf, int size, @@ -1772,6 +1815,7 @@ void* wolfSSL_GetCookieCtx(WOLFSSL* ssl) return NULL; } +#endif /* WOLFSSL_DTLS */ #ifdef WOLFSSL_SESSION_EXPORT @@ -1789,7 +1833,6 @@ void wolfSSL_CTX_SetIOSetPeer(WOLFSSL_CTX* ctx, CallbackSetPeer cb) } #endif /* WOLFSSL_SESSION_EXPORT */ -#endif /* WOLFSSL_DTLS */ #ifdef HAVE_NETX diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 8d0d73739..55cb14556 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1325,6 +1325,7 @@ enum Misc { DTLS_EXPORT_STATE_PRO = 166,/* wolfSSL protocol for serialized state */ TLS_EXPORT_PRO = 167,/* wolfSSL protocol for serialized TLS */ DTLS_EXPORT_OPT_SZ = 61, /* amount of bytes used from Options */ + TLS_EXPORT_OPT_SZ = 65, /* amount of bytes used from Options */ DTLS_EXPORT_OPT_SZ_3 = 60, /* amount of bytes used from Options */ DTLS_EXPORT_KEY_SZ = 325 + (DTLS_SEQ_SZ * 2), /* max amount of bytes used from Keys */ @@ -1339,7 +1340,7 @@ enum Misc { /* older export versions supported */ WOLFSSL_EXPORT_VERSION_3 = 3, /* wolfSSL version before TLS 1.3 addition */ - DTLS_EXPORT_IP = 46, /* max ip size IPv4 mapped IPv6 */ + MAX_EXPORT_IP = 46, /* max ip size IPv4 mapped IPv6 */ DTLS_MTU_ADDITIONAL_READ_BUFFER = WOLFSSL_DTLS_MTU_ADDITIONAL_READ_BUFFER, /* Additional bytes to read so that * we can work with a peer that has @@ -2852,12 +2853,14 @@ struct WOLFSSL_CTX { CallbackIOSend CBIOSend; #ifdef WOLFSSL_DTLS CallbackGenCookie CBIOCookie; /* gen cookie callback */ +#endif /* WOLFSSL_DTLS */ #ifdef WOLFSSL_SESSION_EXPORT +#ifdef WOLFSSL_DTLS wc_dtls_export dtls_export; /* export function for DTLS session */ +#endif CallbackGetPeer CBGetPeer; CallbackSetPeer CBSetPeer; #endif -#endif /* WOLFSSL_DTLS */ VerifyCallback verifyCallback; /* cert verification callback */ #ifdef OPENSSL_ALL CertVerifyCallback verifyCertCb; diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index a6363f5cf..9e1f76f4a 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -429,12 +429,6 @@ WOLFSSL_API int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx); WOLFSSL_API int EmbedReceiveFromMcast(WOLFSSL* ssl, char* buf, int sz, void*); #endif /* WOLFSSL_MULTICAST */ - #ifdef WOLFSSL_SESSION_EXPORT - WOLFSSL_API int EmbedGetPeer(WOLFSSL* ssl, char* ip, int* ipSz, - unsigned short* port, int* fam); - WOLFSSL_API int EmbedSetPeer(WOLFSSL* ssl, char* ip, int ipSz, - unsigned short port, int fam); - #endif /* WOLFSSL_SESSION_EXPORT */ #endif /* WOLFSSL_DTLS */ #endif /* USE_WOLFSSL_IO */ @@ -593,16 +587,20 @@ WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); WOLFSSL_API void wolfSSL_SetCookieCtx(WOLFSSL* ssl, void *ctx); WOLFSSL_API void* wolfSSL_GetCookieCtx(WOLFSSL* ssl); - #ifdef WOLFSSL_SESSION_EXPORT - typedef int (*CallbackGetPeer)(WOLFSSL* ssl, char* ip, int* ipSz, - unsigned short* port, int* fam); - typedef int (*CallbackSetPeer)(WOLFSSL* ssl, char* ip, int ipSz, - unsigned short port, int fam); - - WOLFSSL_API void wolfSSL_CTX_SetIOGetPeer(WOLFSSL_CTX*, CallbackGetPeer); - WOLFSSL_API void wolfSSL_CTX_SetIOSetPeer(WOLFSSL_CTX*, CallbackSetPeer); - #endif /* WOLFSSL_SESSION_EXPORT */ #endif +#ifdef WOLFSSL_SESSION_EXPORT + typedef int (*CallbackGetPeer)(WOLFSSL* ssl, char* ip, int* ipSz, + unsigned short* port, int* fam); + typedef int (*CallbackSetPeer)(WOLFSSL* ssl, char* ip, int ipSz, + unsigned short port, int fam); + + WOLFSSL_API void wolfSSL_CTX_SetIOGetPeer(WOLFSSL_CTX*, CallbackGetPeer); + WOLFSSL_API void wolfSSL_CTX_SetIOSetPeer(WOLFSSL_CTX*, CallbackSetPeer); + WOLFSSL_API int EmbedGetPeer(WOLFSSL* ssl, char* ip, int* ipSz, + unsigned short* port, int* fam); + WOLFSSL_API int EmbedSetPeer(WOLFSSL* ssl, char* ip, int ipSz, + unsigned short port, int fam); +#endif /* WOLFSSL_SESSION_EXPORT */