forked from wolfSSL/wolfssl
callbacks for setting and getting peer ip/port/family
This commit is contained in:
141
src/internal.c
141
src/internal.c
@ -1001,8 +1001,10 @@ static int dtls_export_load(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
|
||||
static int ExportPeerInfo(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
{
|
||||
int idx = 0;
|
||||
word16 fam = 0;
|
||||
int idx = 0;
|
||||
int ipSz = DTLS_EXPORT_IP; /* start as max size */
|
||||
int fam = 0;
|
||||
word16 port = 0;
|
||||
char ip[DTLS_EXPORT_IP];
|
||||
|
||||
if (ver != 1) {
|
||||
@ -1010,57 +1012,29 @@ static int ExportPeerInfo(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (exp == NULL || len < sizeof(ip) + 3 * DTLS_EXPORT_LEN) {
|
||||
if (ssl == NULL || exp == NULL || len < sizeof(ip) + 3 * DTLS_EXPORT_LEN) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
fam = ((SOCKADDR_S*)ssl->buffers.dtlsCtx.peer.sa)->ss_family;
|
||||
|
||||
c16toa(fam, exp + idx); idx += DTLS_EXPORT_LEN;
|
||||
|
||||
switch (fam) {
|
||||
case WOLFSSL_IP4:
|
||||
if (XINET_NTOP(fam,
|
||||
&(((SOCKADDR_IN*)ssl->buffers.dtlsCtx.peer.sa)->sin_addr),
|
||||
ip, sizeof(ip)) == NULL) {
|
||||
WOLFSSL_MSG("XINET_NTOP error");
|
||||
return SOCKET_ERROR_E;
|
||||
}
|
||||
break;
|
||||
|
||||
case WOLFSSL_IP6:
|
||||
if (XINET_NTOP(fam,
|
||||
&(((SOCKADDR_IN6*)ssl->buffers.dtlsCtx.peer.sa)->sin6_addr),
|
||||
ip, sizeof(ip)) == NULL) {
|
||||
WOLFSSL_MSG("XINET_NTOP error");
|
||||
return SOCKET_ERROR_E;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Unknown family type");
|
||||
return SOCKET_ERROR_E;
|
||||
if (ssl->ctx->CBGetPeer == NULL) {
|
||||
WOLFSSL_MSG("No get peer call back set");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
ip[sizeof(ip)-1] = '\0'; /* make sure has terminator */
|
||||
c16toa((word16)XSTRLEN(ip), exp + idx);
|
||||
idx += DTLS_EXPORT_LEN;
|
||||
XMEMCPY(exp + idx, ip, XSTRLEN(ip));
|
||||
idx += (word16)XSTRLEN(ip);
|
||||
|
||||
switch (fam) {
|
||||
case WOLFSSL_IP4:
|
||||
c16toa(XNTOHS(((SOCKADDR_IN*)ssl->buffers.dtlsCtx.peer.sa)->sin_port),
|
||||
exp + idx);
|
||||
break;
|
||||
case WOLFSSL_IP6:
|
||||
c16toa(XNTOHS(((SOCKADDR_IN6*)ssl->buffers.dtlsCtx.peer.sa)->sin6_port),
|
||||
exp + idx);
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Unknown address family");
|
||||
return SOCKET_ERROR_E;
|
||||
if (ssl->ctx->CBGetPeer(ssl, ip, &ipSz, &port, &fam) != SSL_SUCCESS) {
|
||||
WOLFSSL_MSG("Get peer callback error");
|
||||
return SOCKET_ERROR_E;
|
||||
}
|
||||
idx += DTLS_EXPORT_LEN;
|
||||
|
||||
/* check that ipSz/fam is not negative or too large since user can set cb */
|
||||
if (ipSz < 0 || ipSz > DTLS_EXPORT_IP || fam < 0) {
|
||||
WOLFSSL_MSG("Bad ipSz or fam returned from get peer callback");
|
||||
return SOCKET_ERROR_E;
|
||||
}
|
||||
|
||||
c16toa((word16)fam, exp + idx); idx += DTLS_EXPORT_LEN;
|
||||
c16toa((word16)ipSz, exp + idx); idx += DTLS_EXPORT_LEN;
|
||||
XMEMCPY(exp + idx, ip, ipSz); idx += ipSz;
|
||||
c16toa(port, exp + idx); idx += DTLS_EXPORT_LEN;
|
||||
|
||||
return idx;
|
||||
}
|
||||
@ -1068,75 +1042,48 @@ static int ExportPeerInfo(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
||||
|
||||
static int ImportPeerInfo(WOLFSSL* ssl, byte* buf, word32 len, byte ver)
|
||||
{
|
||||
int ret;
|
||||
word16 idx = 0;
|
||||
word16 value;
|
||||
word16 ipSz;
|
||||
word16 fam;
|
||||
word16 port;
|
||||
char ip[DTLS_EXPORT_IP];
|
||||
SOCKADDR_S addr;
|
||||
|
||||
if (ver != 1) {
|
||||
WOLFSSL_MSG("Export version not supported");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (buf == NULL || len < 3 * DTLS_EXPORT_LEN) {
|
||||
if (ssl == NULL || buf == NULL || len < 3 * DTLS_EXPORT_LEN) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* import sin family */
|
||||
ato16(buf + idx, &value); idx += DTLS_EXPORT_LEN;
|
||||
addr.ss_family = value;
|
||||
ato16(buf + idx, &fam); idx += DTLS_EXPORT_LEN;
|
||||
|
||||
/* import ip address idx, and value or unsigned but cast for enum */
|
||||
ato16(buf + idx, &value); idx += DTLS_EXPORT_LEN;
|
||||
if (value > sizeof(ip) || (word16)(idx + value + DTLS_EXPORT_LEN) > len) {
|
||||
/* import ip address idx, and ipSz are unsigned but cast for enum */
|
||||
ato16(buf + idx, &ipSz); idx += DTLS_EXPORT_LEN;
|
||||
if (ipSz > sizeof(ip) || (word16)(idx + ipSz + DTLS_EXPORT_LEN) > len) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
XMEMSET(ip, 0, sizeof(ip));
|
||||
XMEMCPY(ip, buf + idx, value); idx += value;
|
||||
ip[value] = '\0';
|
||||
ato16(buf + idx, &value); idx += DTLS_EXPORT_LEN;
|
||||
switch (addr.ss_family) {
|
||||
case WOLFSSL_IP4:
|
||||
if (XINET_PTON(addr.ss_family, ip,
|
||||
&(((SOCKADDR_IN*)&addr)->sin_addr)) <= 0) {
|
||||
WOLFSSL_MSG("XINET_PTON error");
|
||||
return SOCKET_ERROR_E;
|
||||
}
|
||||
((SOCKADDR_IN*)&addr)->sin_port = XHTONS(value);
|
||||
XMEMCPY(ip, buf + idx, ipSz); idx += ipSz;
|
||||
ip[ipSz] = '\0';
|
||||
ato16(buf + idx, &port); idx += DTLS_EXPORT_LEN;
|
||||
|
||||
/* peer sa is free'd in SSL_ResourceFree */
|
||||
if ((ret = wolfSSL_dtls_set_peer(ssl, (SOCKADDR_IN*)&addr,
|
||||
sizeof(SOCKADDR_IN)))!= SSL_SUCCESS) {
|
||||
WOLFSSL_MSG("Import DTLS peer info error");
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
case WOLFSSL_IP6:
|
||||
if (XINET_PTON(addr.ss_family, ip,
|
||||
&(((SOCKADDR_IN6*)&addr)->sin6_addr)) <= 0) {
|
||||
WOLFSSL_MSG("XINET_PTON error");
|
||||
return SOCKET_ERROR_E;
|
||||
}
|
||||
((SOCKADDR_IN6*)&addr)->sin6_port = XHTONS(value);
|
||||
|
||||
/* peer sa is free'd in SSL_ResourceFree */
|
||||
if ((ret = wolfSSL_dtls_set_peer(ssl, (SOCKADDR_IN6*)&addr,
|
||||
sizeof(SOCKADDR_IN6)))!= SSL_SUCCESS) {
|
||||
WOLFSSL_MSG("Import DTLS peer info error");
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Unknown address family");
|
||||
return BUFFER_E;
|
||||
/* sanity check for a function to call, then use it to import peer info */
|
||||
if (ssl->ctx->CBSetPeer == NULL) {
|
||||
WOLFSSL_MSG("No set peer function");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
if (ssl->ctx->CBSetPeer(ssl, ip, ipSz, port, fam) != SSL_SUCCESS) {
|
||||
WOLFSSL_MSG("Error setting peer info");
|
||||
return SOCKET_ERROR_E;
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
/* WOLFSSL_LOCAL function that serializes the current WOLFSSL session
|
||||
* buf is used to hold the serialized WOLFSSL struct and sz is the size of buf
|
||||
* passed in.
|
||||
@ -1454,6 +1401,10 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method)
|
||||
ctx->CBIORecv = EmbedReceiveFrom;
|
||||
ctx->CBIOSend = EmbedSendTo;
|
||||
}
|
||||
#ifdef WOLFSSL_SESSION_EXPORT
|
||||
ctx->CBGetPeer = EmbedGetPeer;
|
||||
ctx->CBSetPeer = EmbedSetPeer;
|
||||
#endif
|
||||
#endif
|
||||
#endif /* WOLFSSL_USER_IO */
|
||||
|
||||
|
150
src/io.c
150
src/io.c
@ -550,6 +550,142 @@ int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx)
|
||||
return sz;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SESSION_EXPORT
|
||||
#ifndef XINET_NTOP
|
||||
#define XINET_NTOP(a,b,c,d) inet_ntop((a),(b),(c),(d))
|
||||
#endif
|
||||
#ifndef XINET_PTON
|
||||
#define XINET_PTON(a,b,c) inet_pton((a),(b),(c))
|
||||
#endif
|
||||
#ifndef XHTONS
|
||||
#define XHTONS(a) htons((a))
|
||||
#endif
|
||||
#ifndef XNTOHS
|
||||
#define XNTOHS(a) ntohs((a))
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_IP4
|
||||
#define WOLFSSL_IP4 AF_INET
|
||||
#endif
|
||||
#ifndef WOLFSSL_IP6
|
||||
#define WOLFSSL_IP6 AF_INET6
|
||||
#endif
|
||||
|
||||
typedef struct sockaddr_storage SOCKADDR_S;
|
||||
typedef struct sockaddr_in SOCKADDR_IN;
|
||||
typedef struct sockaddr_in6 SOCKADDR_IN6;
|
||||
|
||||
/* get the peer information in human readable form (ip, port, family)
|
||||
* default function assumes BSD sockets
|
||||
* can be overriden with wolfSSL_CTX_SetIOGetPeer
|
||||
*/
|
||||
int EmbedGetPeer(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))
|
||||
!= SSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* extract family, ip, and port */
|
||||
*fam = ((SOCKADDR_S*)&peer)->ss_family;
|
||||
switch (*fam) {
|
||||
case WOLFSSL_IP4:
|
||||
if (XINET_NTOP(*fam, &(((SOCKADDR_IN*)&peer)->sin_addr),
|
||||
ip, *ipSz) == NULL) {
|
||||
WOLFSSL_MSG("XINET_NTOP error");
|
||||
return SOCKET_ERROR_E;
|
||||
}
|
||||
*port = XNTOHS(((SOCKADDR_IN*)&peer)->sin_port);
|
||||
break;
|
||||
|
||||
case WOLFSSL_IP6:
|
||||
if (XINET_NTOP(*fam, &(((SOCKADDR_IN6*)&peer)->sin6_addr),
|
||||
ip, *ipSz) == NULL) {
|
||||
WOLFSSL_MSG("XINET_NTOP error");
|
||||
return SOCKET_ERROR_E;
|
||||
}
|
||||
*port = XNTOHS(((SOCKADDR_IN6*)&peer)->sin6_port);
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Unknown family type");
|
||||
return SOCKET_ERROR_E;
|
||||
}
|
||||
ip[*ipSz - 1] = '\0'; /* make sure has terminator */
|
||||
*ipSz = (word16)XSTRLEN(ip);
|
||||
|
||||
return SSL_SUCCESS;
|
||||
}
|
||||
|
||||
/* set the peer information in human readable form (ip, port, family)
|
||||
* default function assumes BSD sockets
|
||||
* can be overriden with wolfSSL_CTX_SetIOSetPeer
|
||||
*/
|
||||
int EmbedSetPeer(WOLFSSL* ssl, char* ip, int ipSz,
|
||||
unsigned short port, int fam)
|
||||
{
|
||||
int ret;
|
||||
SOCKADDR_S addr;
|
||||
|
||||
/* sanity checks on arguments */
|
||||
if (ssl == NULL || ip == NULL || ipSz < 0 || ipSz > DTLS_EXPORT_IP) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
addr.ss_family = fam;
|
||||
switch (addr.ss_family) {
|
||||
case WOLFSSL_IP4:
|
||||
if (XINET_PTON(addr.ss_family, ip,
|
||||
&(((SOCKADDR_IN*)&addr)->sin_addr)) <= 0) {
|
||||
WOLFSSL_MSG("XINET_PTON error");
|
||||
return SOCKET_ERROR_E;
|
||||
}
|
||||
((SOCKADDR_IN*)&addr)->sin_port = XHTONS(port);
|
||||
|
||||
/* peer sa is free'd in SSL_ResourceFree */
|
||||
if ((ret = wolfSSL_dtls_set_peer(ssl, (SOCKADDR_IN*)&addr,
|
||||
sizeof(SOCKADDR_IN)))!= SSL_SUCCESS) {
|
||||
WOLFSSL_MSG("Import DTLS peer info error");
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
case WOLFSSL_IP6:
|
||||
if (XINET_PTON(addr.ss_family, ip,
|
||||
&(((SOCKADDR_IN6*)&addr)->sin6_addr)) <= 0) {
|
||||
WOLFSSL_MSG("XINET_PTON error");
|
||||
return SOCKET_ERROR_E;
|
||||
}
|
||||
((SOCKADDR_IN6*)&addr)->sin6_port = XHTONS(port);
|
||||
|
||||
/* peer sa is free'd in SSL_ResourceFree */
|
||||
if ((ret = wolfSSL_dtls_set_peer(ssl, (SOCKADDR_IN6*)&addr,
|
||||
sizeof(SOCKADDR_IN6)))!= SSL_SUCCESS) {
|
||||
WOLFSSL_MSG("Import DTLS peer info error");
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Unknown address family");
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
return SSL_SUCCESS;
|
||||
}
|
||||
#endif /* WOLFSSL_SESSION_EXPORT */
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
|
||||
#ifdef HAVE_OCSP
|
||||
@ -1066,6 +1202,20 @@ WOLFSSL_API void* wolfSSL_GetCookieCtx(WOLFSSL* ssl)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SESSION_EXPORT
|
||||
|
||||
WOLFSSL_API void wolfSSL_CTX_SetIOGetPeer(WOLFSSL_CTX* ctx, CallbackGetPeer cb)
|
||||
{
|
||||
ctx->CBGetPeer = cb;
|
||||
}
|
||||
|
||||
|
||||
WOLFSSL_API void wolfSSL_CTX_SetIOSetPeer(WOLFSSL_CTX* ctx, CallbackSetPeer cb)
|
||||
{
|
||||
ctx->CBSetPeer = cb;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_SESSION_EXPORT */
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
|
||||
|
||||
|
@ -1960,7 +1960,11 @@ struct WOLFSSL_CTX {
|
||||
#ifdef WOLFSSL_DTLS
|
||||
CallbackGenCookie CBIOCookie; /* gen cookie callback */
|
||||
wc_dtls_export dtls_export; /* export function for DTLS session */
|
||||
#ifdef WOLFSSL_SESSION_EXPORT
|
||||
CallbackGetPeer CBGetPeer;
|
||||
CallbackSetPeer CBSetPeer;
|
||||
#endif
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
VerifyCallback verifyCallback; /* cert verification callback */
|
||||
word32 timeout; /* session timeout */
|
||||
#ifdef HAVE_ECC
|
||||
|
@ -31,37 +31,6 @@
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/version.h>
|
||||
|
||||
#ifdef WOLFSSL_SESSION_EXPORT
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifndef XINET_NTOP
|
||||
#define XINET_NTOP(a,b,c,d) inet_ntop((a),(b),(c),(d))
|
||||
#endif
|
||||
#ifndef XINET_PTON
|
||||
#define XINET_PTON(a,b,c) inet_pton((a),(b),(c))
|
||||
#endif
|
||||
#ifndef XHTONS
|
||||
#define XHTONS(a) htons((a))
|
||||
#endif
|
||||
#ifndef XNTOHS
|
||||
#define XNTOHS(a) ntohs((a))
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_IP4
|
||||
#define WOLFSSL_IP4 AF_INET
|
||||
#endif
|
||||
#ifndef WOLFSSL_IP6
|
||||
#define WOLFSSL_IP6 AF_INET6
|
||||
#endif
|
||||
|
||||
typedef struct sockaddr_storage SOCKADDR_S;
|
||||
typedef struct sockaddr_in SOCKADDR_IN;
|
||||
typedef struct sockaddr_in6 SOCKADDR_IN6;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NO_FILESYSTEM
|
||||
#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
|
||||
#if MQX_USE_IO_OLD
|
||||
@ -1097,7 +1066,6 @@ WOLFSSL_API void* wolfSSL_GetIOWriteCtx(WOLFSSL* ssl);
|
||||
WOLFSSL_API void wolfSSL_SetIOReadFlags( WOLFSSL* ssl, int flags);
|
||||
WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags);
|
||||
|
||||
|
||||
#ifndef WOLFSSL_USER_IO
|
||||
/* default IO callbacks */
|
||||
WOLFSSL_API int EmbedReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx);
|
||||
@ -1114,6 +1082,22 @@ WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags);
|
||||
WOLFSSL_API int EmbedSendTo(WOLFSSL* ssl, char* buf, int sz, void* ctx);
|
||||
WOLFSSL_API int EmbedGenerateCookie(WOLFSSL* ssl, unsigned char* buf,
|
||||
int sz, void*);
|
||||
#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);
|
||||
|
||||
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 /* WOLFSSL_DTLS */
|
||||
#endif /* WOLFSSL_USER_IO */
|
||||
|
||||
|
Reference in New Issue
Block a user