Merge pull request #2810 from SparkiDev/tls13_mut_auth

Allow mutual authentication to be required for TLS server side
This commit is contained in:
toddouska
2020-03-04 16:21:03 -08:00
committed by GitHub
7 changed files with 114 additions and 13 deletions

View File

@@ -614,23 +614,24 @@ static const char* server_usage_msg[][49] = {
#ifdef HAVE_SESSION_TICKET
"-T Do not generate session ticket\n", /* 44 */
#endif
"-F Send alert if no mutual authentication\n", /* 45 */
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
"-Q Request certificate from client post-handshake\n", /* 45 */
"-Q Request certificate from client post-handshake\n", /* 46 */
#endif
#ifdef WOLFSSL_SEND_HRR_COOKIE
"-J Server sends Cookie Extension containing state\n", /* 46 */
"-J Server sends Cookie Extension containing state\n", /* 47 */
#endif
#endif /* WOLFSSL_TLS13 */
#ifdef WOLFSSL_EARLY_DATA
"-0 Early data read from client (0-RTT handshake)\n", /* 47 */
"-0 Early data read from client (0-RTT handshake)\n", /* 48 */
#endif
#ifdef WOLFSSL_MULTICAST
"-3 <grpid> Multicast, grpid < 256\n", /* 48 */
"-3 <grpid> Multicast, grpid < 256\n", /* 49 */
#endif
"-1 <num> Display a result by specified language."
"\n 0: English, 1: Japanese\n", /* 49 */
"\n 0: English, 1: Japanese\n", /* 50 */
#ifdef HAVE_TRUSTED_CA
"-5 Use Trusted CA Key Indication\n", /* 52 */
"-5 Use Trusted CA Key Indication\n", /* 53 */
#endif
#ifdef HAVE_CURVE448
"-8 Pre-generate Key share using Curve448 only\n", /* 55 */
@@ -734,25 +735,26 @@ static const char* server_usage_msg[][49] = {
#ifdef HAVE_SESSION_TICKET
"-T セッションチケットを生成しない\n", /* 44 */
#endif
"-F Send alert if no mutual authentication\n", /* 45 */
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
"-Q クライアントのポストハンドシェイクから"
"証明書を要求する\n", /* 45 */
"証明書を要求する\n", /* 46 */
#endif
#ifdef WOLFSSL_SEND_HRR_COOKIE
"-J サーバーの状態を含むTLS Cookie 拡張を送信する\n", /* 46 */
"-J サーバーの状態を含むTLS Cookie 拡張を送信する\n", /* 47 */
#endif
#endif /* WOLFSSL_TLS13 */
#ifdef WOLFSSL_EARLY_DATA
"-0 クライアントからの Early Data 読み取り"
"0-RTTハンドシェイク\n", /* 47 */
"0-RTTハンドシェイク\n", /* 48 */
#endif
#ifdef WOLFSSL_MULTICAST
"-3 <grpid> マルチキャスト, grpid < 256\n", /* 48 */
"-3 <grpid> マルチキャスト, grpid < 256\n", /* 49 */
#endif
"-1 <num> 指定された言語で結果を表示します。"
"\n 0: 英語、 1: 日本語\n", /* 49 */
"\n 0: 英語、 1: 日本語\n", /* 50 */
#ifdef HAVE_TRUSTED_CA
"-5 信頼できる認証局の鍵表示を使用する\n", /* 52 */
"-5 信頼できる認証局の鍵表示を使用する\n", /* 53 */
#endif
#ifdef HAVE_CURVE448
"-8 Pre-generate Key share using Curve448 only\n", /* 55 */
@@ -852,6 +854,7 @@ static void Usage(void)
#ifdef HAVE_SESSION_TICKET
printf("%s", msg[++msgId]); /* -T */
#endif
printf("%s", msg[++msgId]); /* -F */
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
printf("%s", msg[++msgId]); /* -Q */
#endif
@@ -986,6 +989,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
int noPskDheKe = 0;
#endif
int updateKeysIVs = 0;
int mutualAuth = 0;
int postHandAuth = 0;
#ifdef WOLFSSL_EARLY_DATA
int earlyData = 0;
@@ -1071,6 +1075,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
(void)crlFlags;
(void)readySignal;
(void)updateKeysIVs;
(void)mutualAuth;
(void)postHandAuth;
(void)mcastID;
(void)loadCertKeyIntoSSLObj;
@@ -1087,7 +1092,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
/* Not Used: h, z, F, T, V, W, X */
while ((ch = mygetopt(argc, argv, "?:"
"abc:defgijk:l:mnop:q:rstuv:wxy"
"A:B:C:D:E:GH:IJKL:MNO:PQR:S:TUVYZ:"
"A:B:C:D:E:FGH:IJKL:MNO:PQR:S:TUVYZ:"
"01:23:4:58")) != -1) {
switch (ch) {
case '?' :
@@ -1402,6 +1407,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#endif
break;
case 'F' :
mutualAuth = 1;
break;
case 'Q' :
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
postHandAuth = 1;
@@ -1745,6 +1754,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
}
#endif
}
#ifndef NO_CERTS
if (mutualAuth)
wolfSSL_CTX_mutual_auth(ctx, 1);
#endif
#ifdef HAVE_ECC

View File

@@ -111,6 +111,22 @@ if [ $RESULT -eq 0 ]; then
fi
echo ""
# TLS 1.3 mutual auth required but client doesn't send certificates.
echo -e "\n\nTLS v1.3 mutual auth fail"
port=0
./examples/server/server -v 4 -F -R $ready_file -p $port &
server_pid=$!
create_port
./examples/client/client -v 4 -x -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -eq 0 ]; then
echo -e "\n\nIssue with requiring mutual authentication"
do_cleanup
exit 1
fi
echo ""
./examples/client/client -v 3 2>&1 | grep -- 'Bad SSL version'
if [ $? -ne 0 ]; then

View File

@@ -5667,6 +5667,7 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
ssl->options.haveEMS = ctx->haveEMS;
#endif
ssl->options.useClientOrder = ctx->useClientOrder;
ssl->options.mutualAuth = ctx->mutualAuth;
#ifdef WOLFSSL_TLS13
#ifdef HAVE_SESSION_TICKET
@@ -9829,6 +9830,17 @@ static void DoCertFatalAlert(WOLFSSL* ssl, int ret)
alertWhy = certificate_revoked;
}
#endif
else if (ret == NO_PEER_CERT) {
#ifdef WOLFSSL_TLS13
if (ssl->options.tls1_3) {
alertWhy = certificate_required;
}
else
#endif
{
alertWhy = handshake_failure;
}
}
/* send fatal alert and mark connection closed */
SendAlert(ssl, alert_fatal, alertWhy); /* try to send */
@@ -10600,6 +10612,12 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
args->count = args->totalCerts;
args->certIdx = 0; /* select peer cert (first one) */
if (args->count == 0 && ssl->options.mutualAuth &&
ssl->options.side == WOLFSSL_SERVER_END) {
ret = NO_PEER_CERT;
DoCertFatalAlert(ssl, ret);
}
args->dCertInit = 0;
#ifndef WOLFSSL_SMALL_CERT_VERIFY
args->dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,

View File

@@ -956,6 +956,47 @@ int wolfSSL_dtls(WOLFSSL* ssl)
return dtlsOpt;
}
#if !defined(NO_CERTS)
/* Set whether mutual authentication is required for connections.
* Server side only.
*
* ctx The SSL/TLS CTX object.
* req 1 to indicate required and 0 when not.
* returns BAD_FUNC_ARG when ctx is NULL, SIDE_ERROR when not a server and
* 0 on success.
*/
int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req)
{
if (ctx == NULL)
return BAD_FUNC_ARG;
if (ctx->method->side == WOLFSSL_CLIENT_END)
return SIDE_ERROR;
ctx->mutualAuth = (byte)req;
return 0;
}
/* Set whether mutual authentication is required for the connection.
* Server side only.
*
* ssl The SSL/TLS object.
* req 1 to indicate required and 0 when not.
* returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3,
* SIDE_ERROR when not a client and 0 on success.
*/
int wolfSSL_mutual_auth(WOLFSSL* ssl, int req)
{
if (ssl == NULL)
return BAD_FUNC_ARG;
if (ssl->options.side == WOLFSSL_SERVER_END)
return SIDE_ERROR;
ssl->options.mutualAuth = (word16)req;
return 0;
}
#endif /* NO_CERTS */
#ifndef WOLFSSL_LEANPSK
int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)

View File

@@ -169,3 +169,11 @@
-v 3
-l ECDHE-ECDSA-AES128-GCM-SHA256
-H verifyFail
# server send alert on no mutual authentication
-v 3
-F
# client send alert on no mutual authentication
-v 3
-x

View File

@@ -2659,6 +2659,7 @@ struct WOLFSSL_CTX {
byte noTicketTls13:1; /* Server won't create new Ticket */
byte noPskDheKe:1; /* Don't use (EC)DHE with PSK */
#endif
byte mutualAuth:1; /* Mutual authentication required */
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
byte postHandshakeAuth:1; /* Post-handshake auth supported. */
#endif
@@ -3411,6 +3412,7 @@ typedef struct Options {
#endif
word16 keepResources:1; /* Keep resources after handshake */
word16 useClientOrder:1; /* Use client's cipher order */
word16 mutualAuth:1; /* Mutual authentication is rquired */
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
word16 postHandshakeAuth:1;/* Client send post_handshake_auth
* extension */

View File

@@ -627,6 +627,7 @@ enum AlertDescription {
unrecognized_name = 112, /**< RFC 6066, section 3 */
bad_certificate_status_response = 113, /**< RFC 6066, section 8 */
unknown_psk_identity = 115, /**< RFC 4279, section 2 */
certificate_required = 116, /**< RFC 8446, section 8.2 */
no_application_protocol = 120
};
@@ -858,6 +859,8 @@ WOLFSSL_ABI WOLFSSL_API int wolfSSL_write(WOLFSSL*, const void*, int);
WOLFSSL_ABI WOLFSSL_API int wolfSSL_read(WOLFSSL*, void*, int);
WOLFSSL_API int wolfSSL_peek(WOLFSSL*, void*, int);
WOLFSSL_API int wolfSSL_accept(WOLFSSL*);
WOLFSSL_API int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req);
WOLFSSL_API int wolfSSL_mutual_auth(WOLFSSL* ssl, int req);
#ifdef WOLFSSL_TLS13
WOLFSSL_API int wolfSSL_send_hrr_cookie(WOLFSSL* ssl,
const unsigned char* secret, unsigned int secretSz);