diff --git a/cyassl/error-ssl.h b/cyassl/error-ssl.h index 625cd8296..7b7befcbd 100644 --- a/cyassl/error-ssl.h +++ b/cyassl/error-ssl.h @@ -119,16 +119,19 @@ enum CyaSSL_ErrorCodes { EXTKEYUSE_AUTH_E = -386, /* ExtKeyUse server|client_auth */ SEND_OOB_READ_E = -387, /* Send Cb out of bounds read */ SECURE_RENEGOTIATION_E = -388, /* Invalid Renegotiation Info */ + 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 */ + /* add strings to SetErrorString !!!!! */ /* begin negotiation parameter errors */ - UNSUPPORTED_SUITE = -390, /* unsupported cipher suite */ - MATCH_SUITE_ERROR = -391, /* can't match cipher suite */ + UNSUPPORTED_SUITE = -500, /* unsupported cipher suite */ + MATCH_SUITE_ERROR = -501, /* can't match cipher suite */ /* end negotiation parameter errors only 10 for now */ /* add strings to SetErrorString !!!!! */ - SESSION_TICKET_LEN_E = -392, /* Session Ticket too large */ - SESSION_TICKET_EXPECT_E = -393 /* Session Ticket missing */ + /* no error stings go down here, add above negotiation errors !!!! */ }; diff --git a/cyassl/internal.h b/cyassl/internal.h index 29bf6dbd1..038e33011 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -1352,6 +1352,7 @@ typedef struct SecureRenegotiation { enum key_cache_state cache_status; /* track key cache state */ byte client_verify_data[TLS_FINISHED_SZ]; /* cached */ byte server_verify_data[TLS_FINISHED_SZ]; /* cached */ + byte subject_hash[SHA_DIGEST_SIZE]; /* peer cert hash */ Keys tmp_keys; /* can't overwrite real keys yet */ } SecureRenegotiation; diff --git a/src/internal.c b/src/internal.c index bcbc04bc6..f091447ce 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4114,6 +4114,29 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, } } +#ifdef HAVE_SECURE_RENEGOTIATION + if (fatal == 0 && ssl->secure_renegotiation + && ssl->secure_renegotiation->enabled) { + + if (ssl->keys.encryptionOn) { + /* compare against previous time */ + if (XMEMCMP(dCert.subjectHash, + ssl->secure_renegotiation->subject_hash, + SHA_DIGEST_SIZE) != 0) { + CYASSL_MSG("Peer sent different cert during scr, fatal"); + fatal = 1; + ret = SCR_DIFFERENT_CERT_E; + } + } + + /* cache peer's hash */ + if (fatal == 0) { + XMEMCPY(ssl->secure_renegotiation->subject_hash, + dCert.subjectHash, SHA_DIGEST_SIZE); + } + } +#endif + #ifdef HAVE_OCSP if (fatal == 0 && ssl->ctx->cm->ocspEnabled) { ret = CheckCertOCSP(ssl->ctx->cm->ocsp, &dCert); @@ -7676,13 +7699,14 @@ const char* CyaSSL_ERR_reason_error_string(unsigned long e) case SECURE_RENEGOTIATION_E: return "Invalid Renegotiation Error"; -#ifdef HAVE_SESSION_TICKET case SESSION_TICKET_LEN_E: return "Session Ticket Too Long Error"; case SESSION_TICKET_EXPECT_E: return "Session Ticket Error"; -#endif + + case SCR_DIFFERENT_CERT_E: + return "Peer sent different cert during SCR"; default : return "unknown error number"; @@ -8754,7 +8778,7 @@ static void PickHashSigAlgo(CYASSL* ssl, } #ifdef HAVE_SESSION_TICKET - if (ssl->session.ticketLen > 0) { + if (ssl->options.resuming && ssl->session.ticketLen > 0) { SessionTicket* ticket; ticket = TLSX_SessionTicket_Create(0,