diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c index 321eb7a8c..d82c02472 100644 --- a/ssl/ssl_conf.c +++ b/ssl/ssl_conf.c @@ -772,6 +772,38 @@ static int cmd_Enable_sign_by_dc(SSL_CONF_CTX *cctx, const char *value) #endif +#ifndef OPENSSL_NO_SSL_TRACE +static void trace_cb(int write_p, int version, int content_type, + const void *buf, size_t msglen, SSL *ssl, void *arg) +{ + BIO *bio = NULL; + if (arg == NULL) { + bio = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT); + if (bio == NULL) + return; + + arg = bio; + } + + SSL_trace(write_p, version, content_type, buf, msglen, ssl, arg); + + BIO_free(bio); +} + +static int cmd_Trace(SSL_CONF_CTX *cctx, const char *value) +{ + if (strcmp(value, "on") == 0) { + if (cctx->ctx) + SSL_CTX_set_msg_callback(cctx->ctx, trace_cb); + + if (cctx->ssl) + SSL_set_msg_callback(cctx->ssl, trace_cb); + } + + return 1; +} +#endif + typedef struct { int (*cmd) (SSL_CONF_CTX *cctx, const char *value); const char *str_file; @@ -885,6 +917,9 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { SSL_CONF_CMD_STRING(Enable_verify_peer_by_dc, "Enable_verify_peer_by_dc", 0), SSL_CONF_CMD_STRING(Enable_sign_by_dc, "Enable_sign_by_dc", 0), #endif +#ifndef OPENSSL_NO_SSL_TRACE + SSL_CONF_CMD_STRING(Trace, "Trace", 0), +#endif }; /* Supported switches: must match order of switches in ssl_conf_cmds */ diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 89ae849ac..c31a2b6bb 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1155,6 +1155,26 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) if (pkeyid == -1) return -1; if (SSL_IS_TLS13(s)) { +#ifndef OPENSSL_NO_SM2 + /* + * RFC 8998 requires that if TLS_SM4_GCM_SM3 or TLS_SM4_CCM_SM3 was + * choosen, the only valid signature algorithm MUST be "sm2sig_sm3". + */ + if (s->enable_sm_tls13_strict == 1) { + const SSL_CIPHER *cipher = s->s3->tmp.new_cipher; + + if (cipher != NULL && (cipher->id == TLS1_3_CK_SM4_GCM_SM3 + || cipher->id == TLS1_3_CK_SM4_CCM_SM3)) { + if (sig != TLSEXT_SIGALG_sm2sig_sm3) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, + SSL_F_TLS12_CHECK_PEER_SIGALG, + SSL_R_WRONG_SIGNATURE_TYPE); + return 0; + } + } + } +#endif + /* Disallow DSA for TLS 1.3 */ if (pkeyid == EVP_PKEY_DSA) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS12_CHECK_PEER_SIGALG, @@ -2860,6 +2880,26 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey) if ((pkey == NULL && !has_usable_cert(s, lu, -1)) || (pkey != NULL && !is_cert_usable(s, lu, x, pkey))) continue; + +#ifndef OPENSSL_NO_SM2 + /* + * RFC 8998 requires that + * if the server chooses TLS_SM4_GCM_SM3 or TLS_SM4_CCM_SM3, + * the only valid signature algorithm present in + * "signature_algorithms" extension MUST be "sm2sig_sm3". + */ + if (SSL_IS_TLS13(s) && s->enable_sm_tls13_strict == 1 && s->server) { + const SSL_CIPHER *cipher = s->s3->tmp.new_cipher; + + if (cipher != NULL && + (cipher->id == TLS1_3_CK_SM4_GCM_SM3 + || cipher->id == TLS1_3_CK_SM4_CCM_SM3)) { + if (lu->sigalg != TLSEXT_SIGALG_sm2sig_sm3) + continue; + } + } +#endif + tmppkey = (pkey != NULL) ? pkey : s->cert->pkeys[lu->sig_idx].privatekey; diff --git a/test/ssl-tests/30-tls13-sm.conf b/test/ssl-tests/30-tls13-sm.conf index 226ca4aed..f12e50b6c 100644 --- a/test/ssl-tests/30-tls13-sm.conf +++ b/test/ssl-tests/30-tls13-sm.conf @@ -1,6 +1,6 @@ # Generated with generate_ssl_tests.pl -num_tests = 22 +num_tests = 24 test-0 = 0-test ciphersuites TLS_SM4_GCM_SM3 test-1 = 1-test series of ciphersuites includes TLS_SM4_GCM_SM3 @@ -24,6 +24,8 @@ test-18 = 18-test client success when enable sm_tls13_strict with SM2 key_share test-19 = 19-test client should fail when enable sm_tls13_strict with ecdsa cert and TLS_SM4_GCM_SM3 cipher test-20 = 20-test client auth fail when enable sm_tls13_strict, CertificateRequest with other signature algorithms except sm2sig_sm3 test-21 = 21-test client auth success when both enable sm_tls13_strict +test-22 = 22-test sm_tls13_strict server with sm2 and rsa certs, client signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3 +test-23 = 23-test sm_tls13_strict client with sm2 and rsa certs, server signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3 # =========================================================== [0-test ciphersuites TLS_SM4_GCM_SM3] @@ -711,3 +713,85 @@ ExpectedHRR = Yes ExpectedResult = Success +# =========================================================== + +[22-test sm_tls13_strict server with sm2 and rsa certs, client signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3] +ssl_conf = 22-test sm_tls13_strict server with sm2 and rsa certs, client signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3-ssl + +[22-test sm_tls13_strict server with sm2 and rsa certs, client signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3-ssl] +server = 22-test sm_tls13_strict server with sm2 and rsa certs, client signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3-server +client = 22-test sm_tls13_strict server with sm2 and rsa certs, client signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3-client + +[22-test sm_tls13_strict server with sm2 and rsa certs, client signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +Ciphersuites = TLS_SM4_GCM_SM3 +Enable_sm_tls13_strict = on +MaxProtocol = TLSv1.3 +MinProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem +RSA.Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +RSA.PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem +SM2.Certificate = ${ENV::TEST_CERTS_DIR}/sm2-leaf.crt +SM2.PrivateKey = ${ENV::TEST_CERTS_DIR}/sm2-leaf.key +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/sm2-root.crt +VerifyMode = Require + +[22-test sm_tls13_strict server with sm2 and rsa certs, client signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3-client] +Certificate = ${ENV::TEST_CERTS_DIR}/sm2-first-crt.pem +CipherString = DEFAULT +Ciphersuites = TLS_SM4_GCM_SM3 +Enable_sm_tls13_strict = on +MaxProtocol = TLSv1.3 +MinProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/sm2-first-key.pem +SignatureAlgorithms = rsa_pss_rsae_sha256:sm2sig_sm3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/sm2-chain-ca.crt +VerifyMode = Peer + +[test-22] +ExpectedCipher = TLS_SM4_GCM_SM3 +ExpectedResult = Success +ExpectedServerCertType = SM2 + + +# =========================================================== + +[23-test sm_tls13_strict client with sm2 and rsa certs, server signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3] +ssl_conf = 23-test sm_tls13_strict client with sm2 and rsa certs, server signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3-ssl + +[23-test sm_tls13_strict client with sm2 and rsa certs, server signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3-ssl] +server = 23-test sm_tls13_strict client with sm2 and rsa certs, server signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3-server +client = 23-test sm_tls13_strict client with sm2 and rsa certs, server signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3-client + +[23-test sm_tls13_strict client with sm2 and rsa certs, server signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3-server] +Certificate = ${ENV::TEST_CERTS_DIR}/sm2-leaf.crt +CipherString = DEFAULT +Ciphersuites = TLS_SM4_GCM_SM3 +Enable_sm_tls13_strict = off +Groups = SM2 +MaxProtocol = TLSv1.3 +MinProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/sm2-leaf.key +SignatureAlgorithms = rsa_pss_rsae_sha256:sm2sig_sm3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/sm2-root.crt +VerifyMode = Require + +[23-test sm_tls13_strict client with sm2 and rsa certs, server signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3-client] +CipherString = DEFAULT +Ciphersuites = TLS_SM4_GCM_SM3 +Enable_sm_tls13_strict = on +MaxProtocol = TLSv1.3 +MinProtocol = TLSv1.3 +RSA.Certificate = ${ENV::TEST_CERTS_DIR}/ee-client-chain.pem +RSA.PrivateKey = ${ENV::TEST_CERTS_DIR}/ee-key.pem +SM2.Certificate = ${ENV::TEST_CERTS_DIR}/sm2-first-crt.pem +SM2.PrivateKey = ${ENV::TEST_CERTS_DIR}/sm2-first-key.pem +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/sm2-chain-ca.crt +VerifyMode = Peer + +[test-23] +ExpectedClientAlert = IllegalParameter +ExpectedResult = ClientFail + + diff --git a/test/ssl-tests/30-tls13-sm.conf.in b/test/ssl-tests/30-tls13-sm.conf.in index d902fd285..af97c69b4 100644 --- a/test/ssl-tests/30-tls13-sm.conf.in +++ b/test/ssl-tests/30-tls13-sm.conf.in @@ -485,4 +485,66 @@ our @tests = ( "ExpectedHRR" => "Yes", }, }, + + { + name => "test sm_tls13_strict server with sm2 and rsa certs, client signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3", + server => { + "MinProtocol" => "TLSv1.3", + "MaxProtocol" => "TLSv1.3", + "Ciphersuites" => "TLS_SM4_GCM_SM3", + "SM2.Certificate" => test_pem("sm2-leaf.crt"), + "SM2.PrivateKey" => test_pem("sm2-leaf.key"), + "RSA.Certificate" => test_pem("servercert.pem"), + "RSA.PrivateKey" => test_pem("serverkey.pem"), + "Enable_sm_tls13_strict" => "on", + "VerifyMode" => "Require", + "VerifyCAFile" => test_pem("sm2-root.crt"), + }, + client => { + "MinProtocol" => "TLSv1.3", + "MaxProtocol" => "TLSv1.3", + "Ciphersuites" => "TLS_SM4_GCM_SM3", + "SignatureAlgorithms" => "rsa_pss_rsae_sha256:sm2sig_sm3", + "Enable_sm_tls13_strict" => "on", + "VerifyCAFile" => test_pem("sm2-chain-ca.crt"), + "Certificate" => test_pem("sm2-first-crt.pem"), + "PrivateKey" => test_pem("sm2-first-key.pem"), + }, + test => { + "ExpectedResult" => "Success", + "ExpectedCipher" => "TLS_SM4_GCM_SM3", + "ExpectedServerCertType" =>, "SM2", + }, + }, + + { + name => "test sm_tls13_strict client with sm2 and rsa certs, server signature_algorithms with rsa_pss_rsae_sha256 and sm2sig_sm3", + server => { + "MinProtocol" => "TLSv1.3", + "MaxProtocol" => "TLSv1.3", + "Ciphersuites" => "TLS_SM4_GCM_SM3", + "SignatureAlgorithms" => "rsa_pss_rsae_sha256:sm2sig_sm3", + "Groups" => "SM2", + "Certificate" => test_pem("sm2-leaf.crt"), + "PrivateKey" => test_pem("sm2-leaf.key"), + "Enable_sm_tls13_strict" => "off", + "VerifyMode" => "Require", + "VerifyCAFile" => test_pem("sm2-root.crt"), + }, + client => { + "MinProtocol" => "TLSv1.3", + "MaxProtocol" => "TLSv1.3", + "Ciphersuites" => "TLS_SM4_GCM_SM3", + "Enable_sm_tls13_strict" => "on", + "SM2.Certificate" => test_pem("sm2-first-crt.pem"), + "SM2.PrivateKey" => test_pem("sm2-first-key.pem"), + "RSA.Certificate" => test_pem("ee-client-chain.pem"), + "RSA.PrivateKey" => test_pem("ee-key.pem"), + "VerifyCAFile" => test_pem("sm2-chain-ca.crt"), + }, + test => { + "ExpectedResult" => "ClientFail", + "ExpectedClientAlert" => "IllegalParameter", + }, + }, ); diff --git a/test/ssl_test_ctx.c b/test/ssl_test_ctx.c index 713b488c6..5aa48cc24 100644 --- a/test/ssl_test_ctx.c +++ b/test/ssl_test_ctx.c @@ -166,6 +166,7 @@ static const test_enum ssl_alerts[] = { {"NoApplicationProtocol", SSL_AD_NO_APPLICATION_PROTOCOL}, {"CertificateRequired", SSL_AD_CERTIFICATE_REQUIRED}, {"CertificateExpired", SSL_AD_CERTIFICATE_EXPIRED}, + {"IllegalParameter", SSL_AD_ILLEGAL_PARAMETER}, }; __owur static int parse_alert(int *alert, const char *value)