Added a callback function to set the master secret on the client

This commit is contained in:
John Safranek 2014-10-24 15:26:47 -07:00
parent 6138ce720c
commit bf718a7d51
5 changed files with 62 additions and 8 deletions

View File

@ -122,6 +122,7 @@ enum CyaSSL_ErrorCodes {
SESSION_TICKET_LEN_E = -389, /* Session Ticket too large */
SESSION_TICKET_EXPECT_E = -390, /* Session Ticket missing */
SCR_DIFFERENT_CERT_E = -391, /* SCR Different cert error */
SESSION_SECRET_CB_E = -392, /* Session secret Cb fcn failure */
/* add strings to SetErrorString !!!!! */

View File

@ -2098,6 +2098,10 @@ struct CYASSL {
void* RsaDecCtx; /* Rsa Private Decrypt Callback Context */
#endif /* NO_RSA */
#endif /* HAVE_PK_CALLBACKS */
#ifdef HAVE_SECRET_CALLBACK
SessionSecretCb sessionSecretCb;
void* sessionSecretCtx;
#endif /* HAVE_SECRET_CALLBACK */
};

View File

@ -286,6 +286,12 @@ CYASSL_API void CyaSSL_load_error_strings(void);
CYASSL_API int CyaSSL_library_init(void);
CYASSL_API long CyaSSL_CTX_set_session_cache_mode(CYASSL_CTX*, long);
#ifdef HAVE_SECRET_CALLBACK
typedef int (*SessionSecretCb)(CYASSL* ssl,
void* secret, int* secretSz, void* ctx);
CYASSL_API int CyaSSL_set_session_secret_cb(CYASSL*, SessionSecretCb, void*);
#endif /* HAVE_SECRET_CALLBACK */
/* session cache persistence */
CYASSL_API int CyaSSL_save_session_cache(const char*);
CYASSL_API int CyaSSL_restore_session_cache(const char*);

View File

@ -1899,6 +1899,10 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
ecc_init(ssl->eccDsaKey);
ecc_init(ssl->eccTempKey);
#endif
#ifdef HAVE_SECRET_CALLBACK
ssl->sessionSecretCb = NULL;
ssl->sessionSecretCtx = NULL;
#endif
/* make sure server has DH parms, and add PSK if there, add NTRU too */
if (ssl->options.side == CYASSL_SERVER_END)
@ -7851,6 +7855,9 @@ const char* CyaSSL_ERR_reason_error_string(unsigned long e)
case SCR_DIFFERENT_CERT_E:
return "Peer sent different cert during SCR";
case SESSION_SECRET_CB_E:
return "Session Secret Callback Error";
default :
return "unknown error number";
}
@ -9140,16 +9147,22 @@ static void PickHashSigAlgo(CYASSL* ssl,
static INLINE int DSH_CheckSessionId(CYASSL* ssl)
{
int ret;
int ret = 0;
#ifndef HAVE_SESSION_TICKET
ret = (ssl->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID,
#ifdef HAVE_SECRET_CALLBACK
/* If a session secret callback exists, we are using that
* key instead of the saved session key. */
ret = ret || (ssl->sessionSecretCb != NULL);
#endif
#ifdef HAVE_SESSION_TICKET
ret = ret ||
(!ssl->expect_session_ticket && ssl->session.ticketLen > 0);
#endif
ret = ret ||
(ssl->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID,
ssl->session.sessionID, ID_LEN) == 0);
#else
ret = (!ssl->expect_session_ticket && ssl->session.ticketLen > 0) ||
(ssl->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID,
ssl->session.sessionID, ID_LEN) == 0);
#endif
return ret;
}
@ -9303,6 +9316,16 @@ static void PickHashSigAlgo(CYASSL* ssl,
*inOutIdx += ssl->keys.padSz;
}
#ifdef HAVE_SECRET_CALLBACK
if (ssl->sessionSecretCb != NULL) {
int secretSz = SECRET_LEN, ret;
ret = ssl->sessionSecretCb(ssl, ssl->session.masterSecret,
&secretSz, ssl->sessionSecretCtx);
if (ret != 0 || secretSz != SECRET_LEN)
return SESSION_SECRET_CB_E;
}
#endif /* HAVE_SECRET_CALLBACK */
if (ssl->options.resuming) {
if (DSH_CheckSessionId(ssl)) {
if (SetCipherSpecs(ssl) == 0) {

View File

@ -4310,6 +4310,26 @@ int CyaSSL_library_init(void)
}
#ifdef HAVE_SECRET_CALLBACK
int CyaSSL_set_session_secret_cb(CYASSL* ssl, SessionSecretCb cb, void* ctx)
{
CYASSL_ENTER("CyaSSL_set_session_secret_cb");
if (ssl == NULL)
return SSL_FATAL_ERROR;
ssl->sessionSecretCb = cb;
ssl->sessionSecretCtx = ctx;
/* If using a pre-set key, assume session resumption. */
ssl->session.sessionIDSz = 0;
ssl->options.resuming = 1;
return SSL_SUCCESS;
}
#endif
#ifndef NO_SESSION_CACHE
/* on by default if built in but allow user to turn off */