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_LEN_E = -389, /* Session Ticket too large */
SESSION_TICKET_EXPECT_E = -390, /* Session Ticket missing */ SESSION_TICKET_EXPECT_E = -390, /* Session Ticket missing */
SCR_DIFFERENT_CERT_E = -391, /* SCR Different cert error */ SCR_DIFFERENT_CERT_E = -391, /* SCR Different cert error */
SESSION_SECRET_CB_E = -392, /* Session secret Cb fcn failure */
/* add strings to SetErrorString !!!!! */ /* add strings to SetErrorString !!!!! */

View File

@@ -2098,6 +2098,10 @@ struct CYASSL {
void* RsaDecCtx; /* Rsa Private Decrypt Callback Context */ void* RsaDecCtx; /* Rsa Private Decrypt Callback Context */
#endif /* NO_RSA */ #endif /* NO_RSA */
#endif /* HAVE_PK_CALLBACKS */ #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 int CyaSSL_library_init(void);
CYASSL_API long CyaSSL_CTX_set_session_cache_mode(CYASSL_CTX*, long); 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 */ /* session cache persistence */
CYASSL_API int CyaSSL_save_session_cache(const char*); CYASSL_API int CyaSSL_save_session_cache(const char*);
CYASSL_API int CyaSSL_restore_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->eccDsaKey);
ecc_init(ssl->eccTempKey); ecc_init(ssl->eccTempKey);
#endif #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 */ /* make sure server has DH parms, and add PSK if there, add NTRU too */
if (ssl->options.side == CYASSL_SERVER_END) 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: case SCR_DIFFERENT_CERT_E:
return "Peer sent different cert during SCR"; return "Peer sent different cert during SCR";
case SESSION_SECRET_CB_E:
return "Session Secret Callback Error";
default : default :
return "unknown error number"; return "unknown error number";
} }
@@ -9140,16 +9147,22 @@ static void PickHashSigAlgo(CYASSL* ssl,
static INLINE int DSH_CheckSessionId(CYASSL* ssl) static INLINE int DSH_CheckSessionId(CYASSL* ssl)
{ {
int ret; int ret = 0;
#ifndef HAVE_SESSION_TICKET #ifdef HAVE_SECRET_CALLBACK
ret = (ssl->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID, /* If a session secret callback exists, we are using that
ssl->session.sessionID, ID_LEN) == 0); * key instead of the saved session key. */
#else ret = ret || (ssl->sessionSecretCb != NULL);
ret = (!ssl->expect_session_ticket && ssl->session.ticketLen > 0) || #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->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID,
ssl->session.sessionID, ID_LEN) == 0); ssl->session.sessionID, ID_LEN) == 0);
#endif
return ret; return ret;
} }
@@ -9303,6 +9316,16 @@ static void PickHashSigAlgo(CYASSL* ssl,
*inOutIdx += ssl->keys.padSz; *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 (ssl->options.resuming) {
if (DSH_CheckSessionId(ssl)) { if (DSH_CheckSessionId(ssl)) {
if (SetCipherSpecs(ssl) == 0) { 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 #ifndef NO_SESSION_CACHE
/* on by default if built in but allow user to turn off */ /* on by default if built in but allow user to turn off */