mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 19:24:42 +02:00
initial extended master secret support
This commit is contained in:
16
configure.ac
16
configure.ac
@@ -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"
|
||||
|
@@ -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");
|
||||
|
23
src/ssl.c
23
src/ssl.c
@@ -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
144
src/tls.c
@@ -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");
|
||||
|
||||
|
@@ -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 */
|
||||
|
@@ -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);
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user