diff --git a/examples/client/client.c b/examples/client/client.c index c2e6afc1b..446e29e1c 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -984,6 +984,11 @@ static const char* client_usage_msg[][59] = { #endif "-1 Display a result by specified language.\n" " 0: English, 1: Japanese\n", /* 58 */ +#if !defined(NO_DH) && !defined(HAVE_FIPS) && \ + !defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK) + "-2 Disable DH Prime check\n", /* 59 */ +#endif + "-4 Use resumption for renegotiation\n", /* 60 */ NULL, }, #ifndef NO_MULTIBYTE_PRINT @@ -1135,6 +1140,13 @@ static const char* client_usage_msg[][59] = { #endif "-1 指定された言語で結果を表示します。\n" " 0: 英語、 1: 日本語\n", /* 58 */ +#if !defined(NO_DH) && !defined(HAVE_FIPS) && \ + !defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK) + "-2 DHプライム番号チェックを無効にする\n", /* 59 */ +#endif +#ifdef HAVE_SECURE_RENEGOTIATION + "-4 再交渉に再開を使用\n", /* 60 */ +#endif NULL, }, #endif @@ -1276,14 +1288,17 @@ static void Usage(void) #ifdef WOLFSSL_EARLY_DATA printf("%s", msg[++msgid]); /* -0 */ #endif -#if !defined(NO_DH) && !defined(HAVE_FIPS) && \ - !defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK) - printf("-2 Disable DH Prime check\n"); -#endif #ifdef WOLFSSL_MULTICAST printf("%s", msg[++msgid]); /* -3 */ #endif printf("%s", msg[++msgid]); /* -1 */ +#if !defined(NO_DH) && !defined(HAVE_FIPS) && \ + !defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK) + printf("%s", msg[++msgid]); /* -2 */ +#endif +#ifdef HAVE_SECURE_RENEGOTIATION + printf("%s", msg[++msgid]); /* -4 */ +#endif } THREAD_RETURN WOLFSSL_THREAD client_test(void* args) @@ -1338,6 +1353,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) int err = 0; int scr = 0; /* allow secure renegotiation */ int forceScr = 0; /* force client initiaed scr */ + int resumeScr = 0; /* use resumption for renegotiation */ #ifndef WOLFSSL_NO_CLIENT_AUTH int useClientCert = 1; #else @@ -1451,6 +1467,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) (void)atomicUser; (void)scr; (void)forceScr; + (void)resumeScr; (void)ourKey; (void)ourCert; (void)verifyCert; @@ -1475,7 +1492,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) while ((ch = mygetopt(argc, argv, "?:" "ab:c:defgh:ijk:l:mnop:q:rstuv:wxyz" "A:B:CDE:F:GH:IJKL:M:NO:PQRS:TUVW:XYZ:" - "01:23:")) != -1) { + "01:23:4")) != -1) { switch (ch) { case '?' : if(myoptarg!=NULL) { @@ -1889,6 +1906,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif break; + case '4' : + #ifdef HAVE_SECURE_RENEGOTIATION + scr = 1; + forceScr = 1; + resumeScr = 1; + #endif + break; + default: Usage(); XEXIT_T(MY_EX_USAGE); @@ -2829,18 +2854,35 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (scr && forceScr) { if (nonBlocking) { printf("not doing secure renegotiation on example with" - " nonblocking yet"); + " nonblocking yet\n"); } else { - if (wolfSSL_Rehandshake(ssl) != WOLFSSL_SUCCESS) { - err = wolfSSL_get_error(ssl, 0); - printf("err = %d, %s\n", err, - wolfSSL_ERR_error_string(err, buffer)); - wolfSSL_free(ssl); ssl = NULL; - wolfSSL_CTX_free(ctx); ctx = NULL; - err_sys("wolfSSL_Rehandshake failed"); + if (!resumeScr) { + printf("Beginning secure rengotiation.\n"); + if (wolfSSL_Rehandshake(ssl) != WOLFSSL_SUCCESS) { + err = wolfSSL_get_error(ssl, 0); + printf("err = %d, %s\n", err, + wolfSSL_ERR_error_string(err, buffer)); + wolfSSL_free(ssl); ssl = NULL; + wolfSSL_CTX_free(ctx); ctx = NULL; + err_sys("wolfSSL_Rehandshake failed"); + } + else { + printf("RENEGOTIATION SUCCESSFUL\n"); + } } else { - printf("RENEGOTIATION SUCCESSFUL\n"); + printf("Beginning secure resumption.\n"); + if (wolfSSL_SecureResume(ssl) != WOLFSSL_SUCCESS) { + err = wolfSSL_get_error(ssl, 0); + printf("err = %d, %s\n", err, + wolfSSL_ERR_error_string(err, buffer)); + wolfSSL_free(ssl); ssl = NULL; + wolfSSL_CTX_free(ctx); ctx = NULL; + err_sys("wolfSSL_SecureResume failed"); + } + else { + printf("SECURE RESUMPTION SUCCESSFUL\n"); + } } } } diff --git a/src/internal.c b/src/internal.c index 2adb2f1ea..133ce6f2a 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9593,7 +9593,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* compare against previous time */ if (XMEMCMP(args->dCert->subjectHash, ssl->secure_renegotiation->subject_hash, - WC_SHA_DIGEST_SIZE) != 0) { + KEYID_SIZE) != 0) { WOLFSSL_MSG( "Peer sent different cert during scr, fatal"); args->fatal = 1; @@ -9604,7 +9604,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* cache peer's hash */ if (args->fatal == 0) { XMEMCPY(ssl->secure_renegotiation->subject_hash, - args->dCert->subjectHash, WC_SHA_DIGEST_SIZE); + args->dCert->subjectHash, KEYID_SIZE); } } #endif /* HAVE_SECURE_RENEGOTIATION */ @@ -15818,9 +15818,6 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) case SESSION_TICKET_EXPECT_E: return "Session Ticket Error"; - case SCR_DIFFERENT_CERT_E: - return "Peer sent different cert during SCR"; - case SESSION_SECRET_CB_E: return "Session Secret Callback Error"; @@ -23985,6 +23982,14 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ret = HandleTlsResumption(ssl, bogusID, &clSuites); if (ret != 0) return ret; + + #ifdef HAVE_SECURE_RENEGOTIATION + if (ssl->secure_renegotiation && + ssl->secure_renegotiation->enabled && + IsEncryptionOn(ssl, 0)) + ssl->secure_renegotiation->startScr = 1; + #endif + if (ssl->options.clientState == CLIENT_KEYEXCHANGE_COMPLETE) { WOLFSSL_LEAVE("DoClientHello", ret); WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO); diff --git a/src/ssl.c b/src/ssl.c index abe0790af..c83b31726 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2375,6 +2375,7 @@ int wolfSSL_Rehandshake(WOLFSSL* ssl) #endif /* reset handshake states */ + ssl->options.sendVerify = 0; ssl->options.serverState = NULL_STATE; ssl->options.clientState = NULL_STATE; ssl->options.connectState = CONNECT_BEGIN; @@ -2389,19 +2390,53 @@ int wolfSSL_Rehandshake(WOLFSSL* ssl) #if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SERVER_RENEGOTIATION_INFO) if (ssl->options.side == WOLFSSL_SERVER_END) { ret = SendHelloRequest(ssl); - if (ret != 0) - return ret; + if (ret != 0) { + ssl->error = ret; + return WOLFSSL_FATAL_ERROR; + } } #endif /* NO_WOLFSSL_SERVER && HAVE_SERVER_RENEGOTIATION_INFO */ ret = InitHandshakeHashes(ssl); - if (ret !=0) - return ret; + if (ret != 0) { + ssl->error = ret; + return WOLFSSL_FATAL_ERROR; + } } ret = wolfSSL_negotiate(ssl); return ret; } + +#ifndef NO_WOLFSSL_CLIENT + +/* do a secure resumption handshake, user forced, we discourage */ +int wolfSSL_SecureResume(WOLFSSL* ssl) +{ + WOLFSSL_SESSION* session; + int ret; + + WOLFSSL_ENTER("wolfSSL_SecureResume()"); + + if (ssl == NULL) + return BAD_FUNC_ARG; + + if (ssl->options.side == WOLFSSL_SERVER_END) { + ssl->error = SIDE_ERROR; + return SSL_FATAL_ERROR; + } + + session = wolfSSL_get_session(ssl); + ret = wolfSSL_set_session(ssl, session); + session = NULL; + if (ret == WOLFSSL_SUCCESS) + ret = wolfSSL_Rehandshake(ssl); + + return ret; +} + +#endif /* NO_WOLFSSL_CLIENT */ + #endif /* HAVE_SECURE_RENEGOTIATION */ /* Session Ticket */ diff --git a/tests/test.conf b/tests/test.conf index faad62e6e..eaece3e6e 100644 --- a/tests/test.conf +++ b/tests/test.conf @@ -2378,3 +2378,63 @@ -c ./certs/client-ecc384-cert.pem -k ./certs/client-ecc384-key.pem -A ./certs/ca-ecc384-cert.pem + +# server TLSv1.2 default with secure renegotiation (renegotiation available) +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-M + +# client TLSv1.2 default with secure renegotiation (client initiated) +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-i + +# server TLSv1.2 default with secure renegotiation (renegotiation available) +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-M + +# client TLSv1.2 default with secure renegotiation (client initiated as resume) +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-i -4 + +# server TLSv1.2 default with secure renegotiation (server initiated) +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-m + +# client TLSv1.2 default with secure renegotiation (renegotiation available) +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-R + +# server TLSv1.2 default with secure renegotiation (server initiated) +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-m + +# client TLSv1.2 default with secure renegotiation (renegotiation available as resume) +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-R -4 + +# server TLSv1.2 default with secure renegotiation (server initiated) +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-m + +# client TLSv1.2 default with secure renegotiation (client initiated) +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-i + +# server TLSv1.2 default with secure renegotiation (server initiated) +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-m + +# client TLSv1.2 default with secure renegotiation (client initiated as resume) +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-i -4 diff --git a/wolfssl/error-ssl.h b/wolfssl/error-ssl.h index f1053be3d..c16002762 100644 --- a/wolfssl/error-ssl.h +++ b/wolfssl/error-ssl.h @@ -126,23 +126,19 @@ enum wolfSSL_ErrorCodes { DUPLICATE_MSG_E = -395, /* Duplicate message error */ SNI_UNSUPPORTED = -396, /* SSL 3.0 does not support SNI */ SOCKET_PEER_CLOSED_E = -397, /* Underlying transport closed */ - BAD_TICKET_KEY_CB_SZ = -398, /* Bad session ticket key cb size */ BAD_TICKET_MSG_SZ = -399, /* Bad session ticket msg size */ BAD_TICKET_ENCRYPT = -400, /* Bad user ticket encrypt */ - DH_KEY_SIZE_E = -401, /* DH Key too small */ SNI_ABSENT_ERROR = -402, /* No SNI request. */ RSA_SIGN_FAULT = -403, /* RSA Sign fault */ HANDSHAKE_SIZE_ERROR = -404, /* Handshake message too large */ - UNKNOWN_ALPN_PROTOCOL_NAME_E = -405, /* Unrecognized protocol name Error*/ BAD_CERTIFICATE_STATUS_ERROR = -406, /* Bad certificate status message */ OCSP_INVALID_STATUS = -407, /* Invalid OCSP Status */ OCSP_WANT_READ = -408, /* OCSP callback response WOLFSSL_CBIO_ERR_WANT_READ */ RSA_KEY_SIZE_E = -409, /* RSA key too small */ ECC_KEY_SIZE_E = -410, /* ECC key too small */ - 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 */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index fc54466e1..4be19bae5 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2301,7 +2301,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[WC_SHA_DIGEST_SIZE]; /* peer cert hash */ + byte subject_hash[KEYID_SIZE]; /* peer cert hash */ Keys tmp_keys; /* can't overwrite real keys yet */ } SecureRenegotiation; diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 0fabaebb4..42004e0da 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2433,7 +2433,9 @@ WOLFSSL_API int wolfSSL_NoKeyShares(WOLFSSL* ssl); #ifdef HAVE_SECURE_RENEGOTIATION WOLFSSL_API int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_StartSecureRenegotiation(WOLFSSL* ssl, int resume); WOLFSSL_API int wolfSSL_Rehandshake(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_SecureResume(WOLFSSL* ssl); #endif