From 431a0cbea9c31582168a73d4e5ce634d59bab3c2 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 15 Dec 2016 11:43:15 -0800 Subject: [PATCH] Multicast 1. Since multicast's only cipher suite uses null cipher automatically enable it. 2. Add options to example client and server to start testing multicast API. (Uses TLS over TCP.) 3. Updates to use the forced secrets set by API. --- configure.ac | 6 ++++++ examples/client/client.c | 42 +++++++++++++++++++++++++++++++++++++++- examples/server/server.c | 40 +++++++++++++++++++++++++++++++++++++- src/internal.c | 21 ++++++++++++++++++++ src/ssl.c | 7 ++++++- wolfssl/internal.h | 9 +++++++-- 6 files changed, 120 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 2881d80f0..6cc2e2e10 100644 --- a/configure.ac +++ b/configure.ac @@ -3564,6 +3564,12 @@ AS_IF([(test "x$ENABLED_DTLS" = "xno") && \ [AM_CFLAGS="-DWOLFSSL_DTLS $AM_CFLAGS" ENABLED_DTLS=yes]) +# Multicast requires the null cipher +AS_IF([test "x$ENABLED_NULL_CIPHER" = "xno" && \ + test "x$ENABLED_MCAST" = "xyes"], + [AM_CFLAGS="-DHAVE_NULL_CIPHER $AM_CFLAGS" + ENABLED_NULL_CIPHER=yes]) + ################################################################################ # OPTIMIZE FLAGS diff --git a/examples/client/client.c b/examples/client/client.c index 52f1ab828..42816bdbe 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -752,8 +752,12 @@ static void Usage(void) #ifdef WOLFSSL_EARLY_DATA printf("-0 Early data sent to server (0-RTT handshake)\n"); #endif +#ifdef WOLFSSL_MULTICAST + printf("-3 Multicast, grpid < 256\n"); +#endif } + THREAD_RETURN WOLFSSL_THREAD client_test(void* args) { SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID; @@ -793,6 +797,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) int doDTLS = 0; int dtlsUDP = 0; int dtlsSCTP = 0; + int doMcast = 0; int matchName = 0; int doPeerCheck = 1; int nonBlocking = 0; @@ -856,6 +861,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifdef WOLFSSL_EARLY_DATA int earlyData = 0; #endif + byte mcastID = 0; #ifdef HAVE_OCSP int useOcsp = 0; @@ -897,6 +903,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) (void)updateKeysIVs; (void)useX25519; (void)helloRetry; + (void)mcastID; StackTrap(); @@ -905,7 +912,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) while ((ch = mygetopt(argc, argv, "?" "ab:c:defgh:ijk:l:mnop:q:rstuv:wxyz" "A:B:CDE:F:GHIJKL:M:NO:PQRS:TUVW:XYZ:" - "0")) != -1) { + "03:")) != -1) { switch (ch) { case '?' : Usage(); @@ -1175,6 +1182,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif break; +<<<<<<< HEAD case 'J' : #ifdef WOLFSSL_TLS13 helloRetry = 1; @@ -1231,6 +1239,13 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif break; + case '3' : + #ifdef WOLFSSL_MULTICAST + doMcast = 1; + mcastID = (byte)(atoi(myoptarg) & 0xFF); + #endif + break; + default: Usage(); exit(MY_EX_USAGE); @@ -1660,6 +1675,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) wolfSSL_CTX_allow_post_handshake_auth(ctx); #endif + if (doMcast) { +#ifdef WOLFSSL_MULTICAST + wolfSSL_CTX_mcast_set_member_id(ctx, mcastID); + if (wolfSSL_CTX_set_cipher_list(ctx, "WDM-NULL-SHA256") != SSL_SUCCESS) + err_sys("Couldn't set multicast cipher list."); +#endif + } + ssl = wolfSSL_new(ctx); if (ssl == NULL) { wolfSSL_CTX_free(ctx); @@ -1705,6 +1728,23 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif + if (doMcast) { +#ifdef WOLFSSL_MULTICAST + byte pms[512]; + byte cr[32]; + byte sr[32]; + const byte suite[2] = {0, 0xfe}; /* WDM_WITH_NULL_SHA256 */ + + XMEMSET(pms, 0x23, sizeof(pms)); + XMEMSET(cr, 0xA5, sizeof(cr)); + XMEMSET(sr, 0x5A, sizeof(sr)); + + if (wolfSSL_set_secret(ssl, 1, pms, sizeof(pms), cr, sr, suite) + != SSL_SUCCESS) + err_sys("unable to set mcast secret"); +#endif + } + #ifdef HAVE_SESSION_TICKET wolfSSL_set_SessionTicket_cb(ssl, sessionTicketCB, (void*)"initial session"); #endif diff --git a/examples/server/server.c b/examples/server/server.c index 2c85e4c4c..60ee22007 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -416,6 +416,9 @@ static void Usage(void) #ifdef WOLFSSL_EARLY_DATA printf("-0 Early data read from client (0-RTT handshake)\n"); #endif +#ifdef WOLFSSL_MULTICAST + printf("-3 Multicast, grpid < 256\n"); +#endif } THREAD_RETURN CYASSL_THREAD server_test(void* args) @@ -445,6 +448,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) int doDTLS = 0; int dtlsUDP = 0; int dtlsSCTP = 0; + int doMcast = 0; int needDH = 0; int useNtruKey = 0; int nonBlocking = 0; @@ -510,6 +514,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #ifdef WOLFSSL_SEND_HRR_COOKIE int hrrCookie = 0; #endif + byte mcastID = 0; #ifdef WOLFSSL_STATIC_MEMORY #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \ @@ -546,6 +551,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) (void)crlFlags; (void)readySignal; (void)updateKeysIVs; + (void)mcastID; #ifdef CYASSL_TIRTOS fdOpenSession(Task_self()); @@ -558,7 +564,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) while ((ch = mygetopt(argc, argv, "?" "abc:defgijk:l:nop:q:rsuv:wx" "A:B:C:D:E:GHIJKL:NO:PQR:S:UYZ:" - "0")) != -1) { + "03:")) != -1) { switch (ch) { case '?' : Usage(); @@ -795,6 +801,13 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #endif break; + case '3' : + #ifdef WOLFSSL_MULTICAST + doMcast = 1; + mcastID = (byte)(atoi(myoptarg) & 0xFF); + #endif + break; + default: Usage(); exit(MY_EX_USAGE); @@ -1119,6 +1132,14 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) } #endif + if (doMcast) { +#ifdef WOLFSSL_MULTICAST + wolfSSL_CTX_mcast_set_member_id(ctx, mcastID); + if (wolfSSL_CTX_set_cipher_list(ctx, "WDM-NULL-SHA256") != SSL_SUCCESS) + err_sys("Couldn't set multicast cipher list."); +#endif + } + ssl = SSL_new(ctx); if (ssl == NULL) err_sys_ex(runWithErrors, "unable to get SSL"); @@ -1143,6 +1164,23 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) } #endif + if (doMcast) { +#ifdef WOLFSSL_MULTICAST + byte pms[512]; + byte cr[32]; + byte sr[32]; + const byte suite[2] = {0, 0xfe}; /* WDM_WITH_NULL_SHA256 */ + + XMEMSET(pms, 0x23, sizeof(pms)); + XMEMSET(cr, 0xA5, sizeof(cr)); + XMEMSET(sr, 0x5A, sizeof(sr)); + + if (wolfSSL_set_secret(ssl, 1, pms, sizeof(pms), cr, sr, suite) + != SSL_SUCCESS) + err_sys("unable to set mcast secret"); +#endif + } + #ifndef NO_HANDSHAKE_DONE_CB wolfSSL_SetHsDoneCb(ssl, myHsDoneCb, NULL); #endif diff --git a/src/internal.c b/src/internal.c index 161243dbc..3608df49c 100755 --- a/src/internal.c +++ b/src/internal.c @@ -4281,6 +4281,23 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #ifdef HAVE_SESSION_TICKET ssl->session.ticket = ssl->session.staticTicket; #endif + +#ifdef WOLFSSL_MULTICAST + if (ctx->haveMcast) { + ssl->options.haveMcast = 1; + ssl->options.mcastID = ctx->mcastID; + + /* Force the state to look like handshake has completed. */ + /* Keying material is supplied externally. */ + ssl->options.serverState = SERVER_FINISHED_COMPLETE; + ssl->options.clientState = CLIENT_FINISHED_COMPLETE; + ssl->options.connectState = SECOND_REPLY_DONE; + ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE; + ssl->options.handShakeState = HANDSHAKE_DONE; + ssl->options.handShakeDone = 1; + } +#endif + return 0; } @@ -7060,6 +7077,10 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) return 1; break; #endif +#ifdef WOLFSSL_MULTICAST + case WDM_WITH_NULL_SHA256 : + break; +#endif default: WOLFSSL_MSG("Unsupported cipher suite, CipherRequires"); diff --git a/src/ssl.c b/src/ssl.c index 69f23104d..402d3ce72 100755 --- a/src/ssl.c +++ b/src/ssl.c @@ -856,8 +856,8 @@ int wolfSSL_CTX_mcast_set_member_id(WOLFSSL_CTX* ctx, byte id) ret = BAD_FUNC_ARG; if (ret == 0) { - /* check if side == MASTER. only work for client */ ctx->haveEMS = 0; + ctx->haveMcast = 1; ctx->mcastID = id; } @@ -900,6 +900,11 @@ int wolfSSL_set_secret(WOLFSSL* ssl, unsigned short epoch, if (ret == 0) ret = MakeTlsMasterSecret(ssl); + if (ret == 0) { + ssl->keys.encryptionOn = 1; + ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE); + } + if (ret == 0) ret = SSL_SUCCESS; else { diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 554551e80..5482ad724 100755 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2241,6 +2241,7 @@ struct WOLFSSL_CTX { byte postHandshakeAuth:1; /* Post-handshake auth supported. */ #endif #ifdef WOLFSSL_MULTICAST + byte haveMcast; /* multicast requested */ byte mcastID; /* multicast group ID */ #endif #if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS) @@ -2824,6 +2825,7 @@ typedef struct Options { word16 saveArrays:1; /* save array Memory for user get keys or psk */ word16 weOwnRng:1; /* will be true unless CTX owns */ + word16 haveEMS:1; /* using extended master secret */ #ifdef HAVE_POLY1305 word16 oldPoly:1; /* set when to use old rfc way of poly*/ #endif @@ -2843,9 +2845,9 @@ typedef struct Options { #ifdef WOLFSSL_SCTP word16 dtlsSctp:1; /* DTLS-over-SCTP mode */ #endif -#ifdef WOLFSSL_MULTICAST - word16 dtlsMcast:1; /* using multicast ? */ #endif +#ifdef WOLFSSL_MULTICAST + word16 haveMcast:1; /* using multicast ? */ #endif word16 haveEMS:1; /* using extended master secret */ #if defined(HAVE_TLS_EXTENSIONS) && defined(HAVE_SUPPORTED_CURVES) @@ -2874,6 +2876,9 @@ typedef struct Options { byte acceptState; /* nonblocking resume */ byte asyncState; /* sub-state for enum asyncState */ byte buildMsgState; /* sub-state for enum buildMsgState */ +#ifdef WOLFSSL_MULTICAST + byte mcastID; /* Multicast group ID */ +#endif #ifndef NO_DH word16 minDhKeySz; /* minimum DH key size */ word16 dhKeySz; /* actual DH key size */