initial extended master secret support

This commit is contained in:
Chris Conlon
2016-09-01 15:12:54 -06:00
parent 5bf8806655
commit e4f527a332
7 changed files with 217 additions and 11 deletions

View File

@@ -1957,6 +1957,18 @@ then
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SESSION_TICKET"
fi
# Extended Master Secret Extension
AC_ARG_ENABLE([extended-master],
[AS_HELP_STRING([--enable-extended-master],[Enable Extended Master Secret (default: disabled)])],
[ ENABLED_EXTENDED_MASTER=$enableval ],
[ ENABLED_EXTENDED_MASTER=no ]
)
if test "x$ENABLED_EXTENDED_MASTER" = "xyes"
then
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_EXTENDED_MASTER"
fi
# TLS Extensions
AC_ARG_ENABLE([tlsx],
[ --enable-tlsx Enable all TLS Extensions (default: disabled)],
@@ -1971,7 +1983,8 @@ then
ENABLED_TRUNCATED_HMAC=yes
ENABLED_SUPPORTED_CURVES=yes
ENABLED_ALPN=yes
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SNI -DHAVE_MAX_FRAGMENT -DHAVE_TRUNCATED_HMAC -DHAVE_SUPPORTED_CURVES -DHAVE_ALPN"
ENABLED_EXTENDED_MASTER=yes
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SNI -DHAVE_MAX_FRAGMENT -DHAVE_TRUNCATED_HMAC -DHAVE_SUPPORTED_CURVES -DHAVE_ALPN -DHAVE_EXTENDED_MASTER"
fi
# PKCS7
@@ -3199,6 +3212,7 @@ echo " * Maximum Fragment Length: $ENABLED_MAX_FRAGMENT"
echo " * Truncated HMAC: $ENABLED_TRUNCATED_HMAC"
echo " * Supported Elliptic Curves: $ENABLED_SUPPORTED_CURVES"
echo " * Session Ticket: $ENABLED_SESSION_TICKET"
echo " * Extended Master Secret: $ENABLED_EXTENDED_MASTER"
echo " * Renegotiation Indication: $ENABLED_RENEGOTIATION_INDICATION"
echo " * Secure Renegotiation: $ENABLED_SECURE_RENEGOTIATION"
echo " * All TLS Extensions: $ENABLED_TLSX"

View File

@@ -11432,6 +11432,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
case CTX_INIT_MUTEX_E:
return "Initialize ctx mutex error";
case EXT_MASTER_SECRET_NEEDED_E:
return "Extended Master Secret must be enabled to resume EMS session";
default :
return "unknown error number";
}
@@ -18185,6 +18188,17 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
WOLFSSL_MSG("Session lookup for resume failed");
ssl->options.resuming = 0;
}
else if (session->haveEMS != ssl->options.haveEMS) {
/* RFC 7627, 5.3, server-side */
/* if old sess didn't have EMS, but new does, full handshake */
if (!session->haveEMS && ssl->options.haveEMS) {
ssl->options.resuming = 0;
}
/* if old sess used EMS, but new doesn't, MUST abort */
else if (session->haveEMS && !ssl->options.haveEMS) {
return EXT_MASTER_SECRET_NEEDED_E;
}
}
else {
if (MatchSuite(ssl, &clSuites) < 0) {
WOLFSSL_MSG("Unsupported cipher suite, ClientHello");

View File

@@ -1749,6 +1749,28 @@ WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
}
#endif
#ifdef HAVE_EXTENDED_MASTER
#ifndef NO_WOLFSSL_CLIENT
int wolfSSL_UseExtendedMasterSecret(WOLFSSL* ssl)
{
if (ssl == NULL)
return BAD_FUNC_ARG;
return TLSX_UseExtendedMasterSecret(&ssl->extensions, ssl->heap);
}
int wolfSSL_CTX_UseExtendedMasterSecret(WOLFSSL_CTX* ctx)
{
if (ctx == NULL)
return BAD_FUNC_ARG;
return TLSX_UseExtendedMasterSecret(&ctx->extensions, ctx->heap);
}
#endif /* NO_WOLFSSL_CLIENT */
#endif /* HAVE_EXTENDED_MASTER */
#ifndef WOLFSSL_LEANPSK
int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags)
@@ -7847,6 +7869,7 @@ int AddSession(WOLFSSL* ssl)
XMEMCPY(SessionCache[row].Sessions[idx].masterSecret,
ssl->arrays->masterSecret, SECRET_LEN);
SessionCache[row].Sessions[idx].haveEMS = ssl->options.haveEMS;
XMEMCPY(SessionCache[row].Sessions[idx].sessionID, ssl->arrays->sessionID,
ID_LEN);
SessionCache[row].Sessions[idx].sessionIDSz = ssl->arrays->sessionIDSz;

144
src/tls.c
View File

@@ -341,21 +341,23 @@ static int PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen,
#endif
int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
int BuildTlsHandshakeHash(WOLFSSL* ssl, byte* hash, word32* hashLen)
{
const byte* side;
byte handshake_hash[HSHASH_SZ];
word32 hashSz = FINISHED_SZ;
word32 hashSz = FINISHED_SZ;
if (ssl == NULL || hash == NULL || hashLen == NULL || *hashLen < HSHASH_SZ)
return BAD_FUNC_ARG;
#ifndef NO_OLD_TLS
wc_Md5GetHash(&ssl->hsHashes->hashMd5, handshake_hash);
wc_ShaGetHash(&ssl->hsHashes->hashSha, &handshake_hash[MD5_DIGEST_SIZE]);
wc_Md5GetHash(&ssl->hsHashes->hashMd5, hash);
wc_ShaGetHash(&ssl->hsHashes->hashSha, &hash[MD5_DIGEST_SIZE]);
#endif
if (IsAtLeastTLSv1_2(ssl)) {
#ifndef NO_SHA256
if (ssl->specs.mac_algorithm <= sha256_mac || ssl->specs.mac_algorithm == blake2b_mac) {
int ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256,handshake_hash);
if (ssl->specs.mac_algorithm <= sha256_mac ||
ssl->specs.mac_algorithm == blake2b_mac) {
int ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash);
if (ret != 0)
return ret;
@@ -365,7 +367,7 @@ int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
#endif
#ifdef WOLFSSL_SHA384
if (ssl->specs.mac_algorithm == sha384_mac) {
int ret = wc_Sha384Final(&ssl->hsHashes->hashSha384,handshake_hash);
int ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash);
if (ret != 0)
return ret;
@@ -375,6 +377,23 @@ int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
#endif
}
*hashLen = hashSz;
return 0;
}
int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
{
int ret;
const byte* side;
byte handshake_hash[HSHASH_SZ];
word32 hashSz = HSHASH_SZ;
ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz);
if (ret < 0)
return ret;
if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0)
side = tls_client;
else
@@ -420,6 +439,10 @@ ProtocolVersion MakeTLSv1_2(void)
}
#ifdef HAVE_EXTENDED_MASTER
static const byte ext_master_label[EXT_MASTER_LABEL_SZ + 1] =
"extended master secret";
#endif
static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret";
static const byte key_label [KEY_LABEL_SZ + 1] = "key expansion";
@@ -490,10 +513,41 @@ int wolfSSL_MakeTlsMasterSecret(byte* ms, word32 msLen,
}
#ifdef HAVE_EXTENDED_MASTER
/* External facing wrapper so user can call as well, 0 on success */
int wolfSSL_MakeTlsExtendedMasterSecret(byte* ms, word32 msLen,
const byte* pms, word32 pmsLen,
const byte* sHash, word32 sHashLen,
int tls1_2, int hash_type)
{
return PRF(ms, msLen, pms, pmsLen, ext_master_label, EXT_MASTER_LABEL_SZ,
sHash, sHashLen, tls1_2, hash_type);
}
#endif /* HAVE_EXTENDED_MASTER */
int MakeTlsMasterSecret(WOLFSSL* ssl)
{
int ret;
int ret;
#ifdef HAVE_EXTENDED_MASTER
byte handshake_hash[HSHASH_SZ];
word32 hashSz = HSHASH_SZ;
if (ssl->options.haveEMS) {
ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz);
if (ret < 0)
return ret;
ret = wolfSSL_MakeTlsExtendedMasterSecret(
ssl->arrays->masterSecret, SECRET_LEN,
ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
handshake_hash, hashSz,
IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
} else
#endif
ret = wolfSSL_MakeTlsMasterSecret(ssl->arrays->masterSecret, SECRET_LEN,
ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
ssl->arrays->clientRandom, ssl->arrays->serverRandom,
@@ -3888,6 +3942,58 @@ int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz,
#endif /* HAVE_QSH */
/******************************************************************************/
/* TLS Extended Master Secret */
/******************************************************************************/
#ifdef HAVE_EXTENDED_MASTER
static int TLSX_EMS_Parse(WOLFSSL* ssl, byte* input, word16 length,
byte isRequest)
{
(void)isRequest;
if (length != 0 || input == NULL)
return BUFFER_ERROR;
#ifndef NO_WOLFSSL_SERVER
if (isRequest) {
int r = TLSX_UseExtendedMasterSecret(&ssl->extensions, ssl->heap);
if (r != SSL_SUCCESS)
return r; /* throw error */
TLSX_SetResponse(ssl, TLSX_EXTENDED_MASTER_SECRET);
}
#endif
ssl->options.haveEMS = 1;
return 0;
}
int TLSX_UseExtendedMasterSecret(TLSX** extensions, void* heap)
{
int ret = 0;
if (extensions == NULL)
return BAD_FUNC_ARG;
if ((ret = TLSX_Push(extensions, TLSX_EXTENDED_MASTER_SECRET, NULL,
heap)) != 0)
return ret;
return SSL_SUCCESS;
}
#define EMS_PARSE TLSX_EMS_Parse
#else
#define EMS_PARSE(a, b, c, d) 0
#endif /* HAVE_EXTENDED_MASTER */
/******************************************************************************/
/* TLS Extensions Framework */
/******************************************************************************/
@@ -3937,6 +4043,10 @@ void TLSX_FreeAll(TLSX* list, void* heap)
CSR2_FREE_ALL(extension->data, heap);
break;
case TLSX_EXTENDED_MASTER_SECRET:
/* Nothing to do. */
break;
case TLSX_RENEGOTIATION_INFO:
SCR_FREE_ALL(extension->data, heap);
break;
@@ -4014,6 +4124,10 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest)
length += CSR2_GET_SIZE(extension->data, isRequest);
break;
case TLSX_EXTENDED_MASTER_SECRET:
/* always empty. */
break;
case TLSX_RENEGOTIATION_INFO:
length += SCR_GET_SIZE(extension->data, isRequest);
break;
@@ -4093,6 +4207,10 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
isRequest);
break;
case TLSX_EXTENDED_MASTER_SECRET:
/* always empty. */
break;
case TLSX_RENEGOTIATION_INFO:
offset += SCR_WRITE(extension->data, output + offset,
isRequest);
@@ -4606,6 +4724,12 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest,
ret = CSR2_PARSE(ssl, input + offset, size, isRequest);
break;
case TLSX_EXTENDED_MASTER_SECRET:
WOLFSSL_MSG("Extended Master Secret extension received");
ret = EMS_PARSE(ssl, input + offset, size, isRequest);
break;
case TLSX_RENEGOTIATION_INFO:
WOLFSSL_MSG("Secure Renegotiation extension received");

View File

@@ -149,6 +149,7 @@ enum wolfSSL_ErrorCodes {
DTLS_EXPORT_VER_E = -411, /* export version error */
INPUT_SIZE_E = -412, /* input size too big error */
CTX_INIT_MUTEX_E = -413, /* initialize ctx mutex error */
EXT_MASTER_SECRET_NEEDED_E = -414, /* need EMS enabled to resume */
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */
/* begin negotiation parameter errors */

View File

@@ -963,6 +963,7 @@ enum Misc {
MAX_EXPORT_BUFFER = 500, /* max size of buffer for exporting */
FINISHED_LABEL_SZ = 15, /* TLS finished label size */
TLS_FINISHED_SZ = 12, /* TLS has a shorter size */
EXT_MASTER_LABEL_SZ = 22, /* TLS extended master secret label sz */
MASTER_LABEL_SZ = 13, /* TLS master secret label sz */
KEY_LABEL_SZ = 13, /* TLS key block expansion sz */
MAX_PRF_HALF = 256, /* Maximum half secret len */
@@ -1644,6 +1645,7 @@ typedef enum {
TLSX_SUPPORTED_GROUPS = 0x000a, /* a.k.a. Supported Curves */
TLSX_APPLICATION_LAYER_PROTOCOL = 0x0010, /* a.k.a. ALPN */
TLSX_STATUS_REQUEST_V2 = 0x0011, /* a.k.a. OCSP stapling v2 */
TLSX_EXTENDED_MASTER_SECRET = 0x0017,
TLSX_QUANTUM_SAFE_HYBRID = 0x0018, /* a.k.a. QSH */
TLSX_SESSION_TICKET = 0x0023,
TLSX_RENEGOTIATION_INFO = 0xff01
@@ -1897,6 +1899,14 @@ WOLFSSL_LOCAL int TLSX_ValidateQSHScheme(TLSX** extensions, word16 name);
#endif /* HAVE_QSH */
/* TLS Extended Master Secret, RFC 7627 */
#ifdef HAVE_EXTENDED_MASTER
WOLFSSL_LOCAL int TLSX_UseExtendedMasterSecret(TLSX** extensions, void* heap);
#endif
/* wolfSSL context type */
struct WOLFSSL_CTX {
WOLFSSL_METHOD* method;
@@ -2225,6 +2235,7 @@ struct WOLFSSL_SESSION {
byte sessionID[ID_LEN]; /* id for protocol */
byte sessionIDSz;
byte masterSecret[SECRET_LEN]; /* stored secret */
word16 haveEMS; /* ext master secret flag */
#ifdef SESSION_CERTS
WOLFSSL_X509_CHAIN chain; /* peer cert chain, static */
ProtocolVersion version; /* which version was used */
@@ -2409,6 +2420,7 @@ typedef struct Options {
word16 dtlsSctp:1; /* DTLS-over-SCTP mode */
#endif
#endif
word16 haveEMS:1; /* using extended master secret */
/* need full byte values for this section */
byte processReply; /* nonblocking resume */
@@ -3028,6 +3040,8 @@ WOLFSSL_LOCAL int VerifyClientSuite(WOLFSSL* ssl);
WOLFSSL_LOCAL Signer* GetCAByName(void* cm, byte* hash);
#endif
#endif /* !NO_CERTS */
WOLFSSL_LOCAL int BuildTlsHandshakeHash(WOLFSSL* ssl, byte* hash,
word32* hashLen);
WOLFSSL_LOCAL int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes,
const byte* sender);
WOLFSSL_LOCAL void FreeArrays(WOLFSSL* ssl, int keep);

View File

@@ -1704,6 +1704,16 @@ WOLFSSL_API int wolfSSL_UseSupportedQSH(WOLFSSL* ssl, unsigned short name);
#endif
#endif
/* TLS Extended Master Secret Extension */
#ifdef HAVE_EXTENDED_MASTER
#ifndef NO_WOLFSSL_CLIENT
WOLFSSL_API int wolfSSL_UseExtendedMasterSecret(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_CTX_UseExtendedMasterSecret(WOLFSSL_CTX* ctx);
#endif /* NO_WOLFSSL_CLIENT */
#endif /* HAVE_EXTENDED_MASTER */
#define WOLFSSL_CRL_MONITOR 0x01 /* monitor this dir flag */
#define WOLFSSL_CRL_START_MON 0x02 /* start monitoring flag */
@@ -1725,6 +1735,12 @@ int wolfSSL_MakeTlsMasterSecret(unsigned char* ms, unsigned int msLen,
const unsigned char* cr, const unsigned char* sr,
int tls1_2, int hash_type);
WOLFSSL_API
int wolfSSL_MakeTlsExtendedMasterSecret(unsigned char* ms, unsigned int msLen,
const unsigned char* pms, unsigned int pmsLen,
const unsigned char* sHash, unsigned int sHashLen,
int tls1_2, int hash_type);
WOLFSSL_API
int wolfSSL_DeriveTlsKeys(unsigned char* key_data, unsigned int keyLen,
const unsigned char* ms, unsigned int msLen,