Projects
home:Eustace:branches:Eulaceura:Factory
compat-openssl11
_service:obs_scm:Feature-Support-TLCP-protocol....
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:Feature-Support-TLCP-protocol.patch of Package compat-openssl11
From 897ef4d611facba29cde86fac6d161984d524da4 Mon Sep 17 00:00:00 2001 From: s_c_c <shichuchao@huawei.com> Date: Mon, 27 Jun 2022 10:28:38 +0800 Subject: [PATCH] Support TLCP protocol TLCP_method(), TLCP_server_method(), TLCP_client_method() are the GM version-specific methods for TLCP protocol. Valid TLCP ciphersuite names are ECDHE-SM4-CBC-SM3 and ECC-SM4-CBC-SM3. Additionally enable-tlcp(argument to Configure) was required. --- Configure | 7 +- apps/s_client.c | 60 +- crypto/dh/dh_err.c | 8 +- crypto/dsa/dsa_err.c | 8 +- crypto/err/openssl.txt | 34 +- crypto/evp/evp_err.c | 6 +- crypto/evp/p_lib.c | 18 + crypto/rsa/rsa_err.c | 23 +- crypto/sm2/build.info | 2 +- crypto/sm2/sm2_err.c | 4 +- crypto/sm2/sm2_kep.c | 254 ++++++ crypto/sm2/sm2_pmeth.c | 4 + doc/man1/s_client.pod | 9 + doc/man3/EVP_PKEY_set1_RSA.pod | 9 +- doc/man3/SSL_CTX_new.pod | 19 +- doc/man3/SSL_CTX_set_options.pod | 4 +- doc/man3/SSL_CTX_use_certificate.pod | 56 +- doc/man7/ssl.pod | 40 + include/crypto/sm2.h | 1 + include/crypto/sm2err.h | 12 +- include/openssl/dherr.h | 15 +- include/openssl/dsaerr.h | 18 +- include/openssl/evp.h | 4 + include/openssl/evperr.h | 17 +- include/openssl/rsaerr.h | 32 +- include/openssl/sm2.h | 20 + include/openssl/ssl.h | 71 ++ include/openssl/sslerr.h | 33 +- include/openssl/tls1.h | 20 + include/openssl/x509.h | 4 + include/openssl/x509err.h | 4 +- ssl/methods.c | 36 + ssl/record/ssl3_record.c | 4 + ssl/s3_lib.c | 126 +++ ssl/ssl_asn1.c | 3 +- ssl/ssl_cert.c | 18 + ssl/ssl_cert_table.h | 6 +- ssl/ssl_ciph.c | 46 +- ssl/ssl_err.c | 54 +- ssl/ssl_lib.c | 81 +- ssl/ssl_local.h | 69 +- ssl/ssl_rsa.c | 541 +++++++++++++ ssl/ssl_sess.c | 3 + ssl/ssl_stat.c | 28 + ssl/statem/extensions.c | 6 +- ssl/statem/extensions_clnt.c | 3 + ssl/statem/extensions_srvr.c | 6 +- ssl/statem/statem.c | 4 + ssl/statem/statem_clnt.c | 434 ++++++++++ ssl/statem/statem_lib.c | 182 ++++- ssl/statem/statem_srvr.c | 445 ++++++++++- ssl/t1_enc.c | 84 ++ ssl/t1_lib.c | 130 ++- test/build.info | 6 +- test/ciphername_test.c | 3 + test/recipes/85-test_tlcp.t | 34 + .../85-test_tlcp_data/ecdsa-client-cert.pem | 12 + .../85-test_tlcp_data/ecdsa-client-key.pem | 5 + .../85-test_tlcp_data/ecdsa-root-cert.pem | 14 + .../85-test_tlcp_data/ecdsa-server-cert.pem | 12 + .../85-test_tlcp_data/ecdsa-server-key.pem | 5 + .../85-test_tlcp_data/sm2-client-enc-cert.pem | 12 + .../85-test_tlcp_data/sm2-client-enc-key.pem | 5 + .../85-test_tlcp_data/sm2-client-sig-cert.pem | 12 + .../85-test_tlcp_data/sm2-client-sig-key.pem | 5 + .../85-test_tlcp_data/sm2-root-cert.pem | 14 + .../85-test_tlcp_data/sm2-server-enc-cert.pem | 12 + .../85-test_tlcp_data/sm2-server-enc-key.pem | 5 + .../85-test_tlcp_data/sm2-server-sig-cert.pem | 12 + .../85-test_tlcp_data/sm2-server-sig-key.pem | 5 + test/sm2_internal_test.c | 111 +++ test/tlcptest.c | 746 ++++++++++++++++++ util/libcrypto.num | 2 + util/libssl.num | 17 + 74 files changed, 4065 insertions(+), 109 deletions(-) create mode 100644 crypto/sm2/sm2_kep.c create mode 100644 include/openssl/sm2.h create mode 100644 test/recipes/85-test_tlcp.t create mode 100644 test/recipes/85-test_tlcp_data/ecdsa-client-cert.pem create mode 100644 test/recipes/85-test_tlcp_data/ecdsa-client-key.pem create mode 100644 test/recipes/85-test_tlcp_data/ecdsa-root-cert.pem create mode 100644 test/recipes/85-test_tlcp_data/ecdsa-server-cert.pem create mode 100644 test/recipes/85-test_tlcp_data/ecdsa-server-key.pem create mode 100644 test/recipes/85-test_tlcp_data/sm2-client-enc-cert.pem create mode 100644 test/recipes/85-test_tlcp_data/sm2-client-enc-key.pem create mode 100644 test/recipes/85-test_tlcp_data/sm2-client-sig-cert.pem create mode 100644 test/recipes/85-test_tlcp_data/sm2-client-sig-key.pem create mode 100644 test/recipes/85-test_tlcp_data/sm2-root-cert.pem create mode 100644 test/recipes/85-test_tlcp_data/sm2-server-enc-cert.pem create mode 100644 test/recipes/85-test_tlcp_data/sm2-server-enc-key.pem create mode 100644 test/recipes/85-test_tlcp_data/sm2-server-sig-cert.pem create mode 100644 test/recipes/85-test_tlcp_data/sm2-server-sig-key.pem create mode 100644 test/tlcptest.c diff --git a/Configure b/Configure index 4236e6c..a41c897 100755 --- a/Configure +++ b/Configure @@ -425,6 +425,7 @@ my @disablables = ( "stdio", "tests", "threads", + "tlcp", "tls", "ts", "ubsan", @@ -469,6 +470,7 @@ our %disabled = ( # "what" => "comment" "ssl-trace" => "default", "ssl3" => "default", "ssl3-method" => "default", + "tlcp" => "default", "ubsan" => "default", "unit-test" => "default", "weak-ssl-ciphers" => "default", @@ -512,8 +514,9 @@ my @disable_cascades = ( "apps" => [ "tests" ], "tests" => [ "external-tests" ], "comp" => [ "zlib" ], - "ec" => [ "tls1_3", "sm2" ], - "sm3" => [ "sm2" ], + "ec" => [ "tls1_3", "sm2", "tlcp" ], + "sm3" => [ "sm2", "tlcp" ], + "sm2" => [ "tlcp" ], sub { !$disabled{"unit-test"} } => [ "heartbeats" ], sub { !$disabled{"msan"} } => [ "asm" ], diff --git a/apps/s_client.c b/apps/s_client.c index 121cd14..a41f98a 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -578,6 +578,7 @@ typedef enum OPTION_choice { OPT_SRPUSER, OPT_SRPPASS, OPT_SRP_STRENGTH, OPT_SRP_LATEUSER, OPT_SRP_MOREGROUPS, #endif + OPT_TLCP, OPT_DCERT, OPT_DKEY, OPT_DPASS, OPT_SSL3, OPT_SSL_CONFIG, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS, @@ -738,6 +739,12 @@ const OPTIONS s_client_options[] = { #ifndef OPENSSL_NO_TLS1_3 {"tls1_3", OPT_TLS1_3, '-', "Just use TLSv1.3"}, #endif +#ifndef OPENSSL_NO_TCLP + {"tlcp", OPT_TLCP, '-', "Just use TLCP"}, + {"dcert", OPT_DCERT, '<', "Encryption certificate file to use (usually for TLCP)"}, + {"dkey", OPT_DKEY, '<', "Encryption private key file to use (usually for TLCP)"}, + {"dpass", OPT_DPASS, 's', "Encryption private key file pass phrase source"}, +#endif #ifndef OPENSSL_NO_DTLS {"dtls", OPT_DTLS, '-', "Use any version of DTLS"}, {"timeout", OPT_TIMEOUT, '-', @@ -836,7 +843,7 @@ static const OPT_PAIR services[] = { #define IS_PROT_FLAG(o) \ (o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \ - || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2) + || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2 || o == OPT_TLCP) /* Free |*dest| and optionally set it to a copy of |source|. */ static void freeandcopy(char **dest, const char *source) @@ -982,6 +989,10 @@ int s_client_main(int argc, char **argv) #ifndef OPENSSL_NO_SCTP int sctp_label_bug = 0; #endif + char *s_dcert_file = NULL, *s_dkey_file = NULL; + char *dpassarg = NULL, *dpass = NULL; + X509 *s_dcert = NULL; + EVP_PKEY *s_dkey = NULL; FD_ZERO(&readfds); FD_ZERO(&writefds); @@ -1318,6 +1329,14 @@ int s_client_main(int argc, char **argv) socket_type = SOCK_STREAM; #ifndef OPENSSL_NO_DTLS isdtls = 0; +#endif + break; + case OPT_TLCP: + min_version = TLCP_VERSION; + max_version = TLCP_VERSION; + socket_type = SOCK_STREAM; +#ifndef OPENSSL_NO_DTLS + isdtls = 0; #endif break; case OPT_DTLS: @@ -1381,6 +1400,15 @@ int s_client_main(int argc, char **argv) case OPT_KEY: key_file = opt_arg(); break; + case OPT_DCERT: + s_dcert_file = opt_arg(); + break; + case OPT_DPASS: + dpassarg = opt_arg(); + break; + case OPT_DKEY: + s_dkey_file = opt_arg(); + break; case OPT_RECONNECT: reconnect = 5; break; @@ -1650,7 +1678,7 @@ int s_client_main(int argc, char **argv) next_proto.data = NULL; #endif - if (!app_passwd(passarg, NULL, &pass, NULL)) { + if (!app_passwd(passarg, dpassarg, &pass, &dpass)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } @@ -1681,6 +1709,26 @@ int s_client_main(int argc, char **argv) goto end; } + if (s_dcert_file != NULL) { + if (s_dkey_file == NULL) + s_dkey_file = s_dcert_file; + + s_dkey = load_key(s_dkey_file, key_format, 0, dpass, e, + "Encrypt certificate private key file"); + if (s_dkey == NULL) { + ERR_print_errors(bio_err); + goto end; + } + + s_dcert = load_cert(s_dcert_file, key_format, + "Encrypt server certificate file"); + + if (s_dcert == NULL) { + ERR_print_errors(bio_err); + goto end; + } + } + if (crl_file != NULL) { X509_CRL *crl; crl = load_crl(crl_file, crl_format); @@ -1932,6 +1980,11 @@ int s_client_main(int argc, char **argv) if (!set_cert_key_stuff(ctx, cert, key, chain, build_chain)) goto end; + + if (s_dcert != NULL) { + if (!set_cert_key_stuff(ctx, s_dcert, s_dkey, chain, build_chain)) + goto end; + } if (!noservername) { tlsextcbp.biodebug = bio_err; @@ -3146,6 +3199,9 @@ int s_client_main(int argc, char **argv) EVP_PKEY_free(key); sk_X509_pop_free(chain, X509_free); OPENSSL_free(pass); + X509_free(s_dcert); + EVP_PKEY_free(s_dkey); + OPENSSL_free(dpass); #ifndef OPENSSL_NO_SRP OPENSSL_free(srp_arg.srppassin); #endif diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c index 9778138..c7ac6ae 100644 --- a/crypto/dh/dh_err.c +++ b/crypto/dh/dh_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -26,8 +26,8 @@ static const ERR_STRING_DATA DH_str_functs[] = { {ERR_PACK(ERR_LIB_DH, DH_F_DH_CMS_SET_SHARED_INFO, 0), "dh_cms_set_shared_info"}, {ERR_PACK(ERR_LIB_DH, DH_F_DH_COMPUTE_KEY, 0), "DH_compute_key"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_GENERATE_KEY, 0), "DH_generate_key"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_GENERATE_PARAMETERS_EX, 0), "DH_generate_parameters_ex"}, + {ERR_PACK(ERR_LIB_DH, DH_F_DH_GENERATE_PARAMETERS_EX, 0), + "DH_generate_parameters_ex"}, {ERR_PACK(ERR_LIB_DH, DH_F_DH_METH_DUP, 0), "DH_meth_dup"}, {ERR_PACK(ERR_LIB_DH, DH_F_DH_METH_NEW, 0), "DH_meth_new"}, {ERR_PACK(ERR_LIB_DH, DH_F_DH_METH_SET1_NAME, 0), "DH_meth_set1_name"}, @@ -78,11 +78,11 @@ static const ERR_STRING_DATA DH_str_reasons[] = { {ERR_PACK(ERR_LIB_DH, 0, DH_R_KEY_SIZE_TOO_SMALL), "key size too small"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_MISSING_PUBKEY), "missing pubkey"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_MODULUS_TOO_LARGE), "modulus too large"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_NON_FIPS_METHOD), "non fips method"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_NOT_SUITABLE_GENERATOR), "not suitable generator"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_NO_PARAMETERS_SET), "no parameters set"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_NO_PRIVATE_VALUE), "no private value"}, - {ERR_PACK(ERR_LIB_DH, 0, DH_R_NON_FIPS_METHOD), "non FIPS method"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_PEER_KEY_ERROR), "peer key error"}, diff --git a/crypto/dsa/dsa_err.c b/crypto/dsa/dsa_err.c index d85d221..26210c5 100644 --- a/crypto/dsa/dsa_err.c +++ b/crypto/dsa/dsa_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -24,7 +24,8 @@ static const ERR_STRING_DATA DSA_str_functs[] = { {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_DO_SIGN, 0), "DSA_do_sign"}, {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_DO_VERIFY, 0), "DSA_do_verify"}, {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_GENERATE_KEY, 0), "DSA_generate_key"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_GENERATE_PARAMETERS_EX, 0), "DSA_generate_parameters_ex"}, + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_GENERATE_PARAMETERS_EX, 0), + "DSA_generate_parameters_ex"}, {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_METH_DUP, 0), "DSA_meth_dup"}, {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_METH_NEW, 0), "DSA_meth_new"}, {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_METH_SET1_NAME, 0), "DSA_meth_set1_name"}, @@ -60,8 +61,9 @@ static const ERR_STRING_DATA DSA_str_reasons[] = { {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MISSING_PRIVATE_KEY), "missing private key"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MODULUS_TOO_LARGE), "modulus too large"}, + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_NON_FIPS_DSA_METHOD), + "non fips dsa method"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_NO_PARAMETERS_SET), "no parameters set"}, - {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_NON_FIPS_DSA_METHOD), "non FIPS DSA method"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_Q_NOT_PRIME), "q not prime"}, diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index b93cace..3ea4c02 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -1,4 +1,4 @@ -# Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the OpenSSL license (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -1102,6 +1102,7 @@ SM2_F_PKEY_SM2_CTRL_STR:110:pkey_sm2_ctrl_str SM2_F_PKEY_SM2_DIGEST_CUSTOM:114:pkey_sm2_digest_custom SM2_F_PKEY_SM2_INIT:111:pkey_sm2_init SM2_F_PKEY_SM2_SIGN:112:pkey_sm2_sign +SM2_F_SM2_COMPUTE_KEY:116:SM2_compute_key SM2_F_SM2_COMPUTE_MSG_HASH:100:sm2_compute_msg_hash SM2_F_SM2_COMPUTE_USERID_DIGEST:101:sm2_compute_userid_digest SM2_F_SM2_COMPUTE_Z_DIGEST:113:sm2_compute_z_digest @@ -1184,7 +1185,7 @@ SSL_F_OSSL_STATEM_SERVER_CONSTRUCT_MESSAGE:431:* SSL_F_OSSL_STATEM_SERVER_POST_PROCESS_MESSAGE:601:\ ossl_statem_server_post_process_message SSL_F_OSSL_STATEM_SERVER_POST_WORK:602:ossl_statem_server_post_work -SSL_F_OSSL_STATEM_SERVER_PRE_WORK:640: +SSL_F_OSSL_STATEM_SERVER_PRE_WORK:640:ossl_statem_server_pre_work SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE:603:ossl_statem_server_process_message SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION:418:ossl_statem_server_read_transition SSL_F_OSSL_STATEM_SERVER_WRITE_TRANSITION:604:\ @@ -1270,6 +1271,10 @@ SSL_F_SSL_CTX_SET_TLSEXT_MAX_FRAGMENT_LENGTH:551:\ SSL_F_SSL_CTX_USE_CERTIFICATE:171:SSL_CTX_use_certificate SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1:172:SSL_CTX_use_certificate_ASN1 SSL_F_SSL_CTX_USE_CERTIFICATE_FILE:173:SSL_CTX_use_certificate_file +SSL_F_SSL_CTX_USE_GM_CERTIFICATE:641:SSL_CTX_use_gm_certificate +SSL_F_SSL_CTX_USE_GM_CERTIFICATE_ASN1:642:SSL_CTX_use_gm_certificate_ASN1 +SSL_F_SSL_CTX_USE_GM_PRIVATEKEY:643:SSL_CTX_use_gm_PrivateKey +SSL_F_SSL_CTX_USE_GM_PRIVATEKEY_ASN1:644:SSL_CTX_use_gm_PrivateKey_ASN1 SSL_F_SSL_CTX_USE_PRIVATEKEY:174:SSL_CTX_use_PrivateKey SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1:175:SSL_CTX_use_PrivateKey_ASN1 SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE:176:SSL_CTX_use_PrivateKey_file @@ -1296,7 +1301,9 @@ SSL_F_SSL_GET_SIGN_PKEY:183:* SSL_F_SSL_HANDSHAKE_HASH:560:ssl_handshake_hash SSL_F_SSL_INIT_WBIO_BUFFER:184:ssl_init_wbio_buffer SSL_F_SSL_KEY_UPDATE:515:SSL_key_update +SSL_F_SSL_LOAD_CERT_FILE:645:ssl_load_cert_file SSL_F_SSL_LOAD_CLIENT_CA_FILE:185:SSL_load_client_CA_file +SSL_F_SSL_LOAD_PKEY_FILE:646:ssl_load_pkey_file SSL_F_SSL_LOG_MASTER_SECRET:498:* SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE:499:ssl_log_rsa_client_key_exchange SSL_F_SSL_MODULE_INIT:392:ssl_module_init @@ -1330,11 +1337,14 @@ SSL_F_SSL_SET_CERT_AND_KEY:621:ssl_set_cert_and_key SSL_F_SSL_SET_CIPHER_LIST:271:SSL_set_cipher_list SSL_F_SSL_SET_CT_VALIDATION_CALLBACK:399:SSL_set_ct_validation_callback SSL_F_SSL_SET_FD:192:SSL_set_fd +SSL_F_SSL_SET_GM_CERT_AND_KEY:647:ssl_set_gm_cert_and_key SSL_F_SSL_SET_PKEY:193:ssl_set_pkey SSL_F_SSL_SET_RFD:194:SSL_set_rfd SSL_F_SSL_SET_SESSION:195:SSL_set_session SSL_F_SSL_SET_SESSION_ID_CONTEXT:218:SSL_set_session_id_context SSL_F_SSL_SET_SESSION_TICKET_EXT:294:SSL_set_session_ticket_ext +SSL_F_SSL_SET_SIGN_ENC_CERT:648:ssl_set_sign_enc_cert +SSL_F_SSL_SET_SIGN_ENC_PKEY:649:ssl_set_sign_enc_pkey SSL_F_SSL_SET_TLSEXT_MAX_FRAGMENT_LENGTH:550:SSL_set_tlsext_max_fragment_length SSL_F_SSL_SET_WFD:196:SSL_set_wfd SSL_F_SSL_SHUTDOWN:224:SSL_shutdown @@ -1345,6 +1355,10 @@ SSL_F_SSL_UNDEFINED_VOID_FUNCTION:244:ssl_undefined_void_function SSL_F_SSL_USE_CERTIFICATE:198:SSL_use_certificate SSL_F_SSL_USE_CERTIFICATE_ASN1:199:SSL_use_certificate_ASN1 SSL_F_SSL_USE_CERTIFICATE_FILE:200:SSL_use_certificate_file +SSL_F_SSL_USE_GM_CERTIFICATE:650:SSL_use_gm_certificate +SSL_F_SSL_USE_GM_CERTIFICATE_ASN1:651:SSL_use_gm_certificate_ASN1 +SSL_F_SSL_USE_GM_PRIVATEKEY:652:SSL_use_gm_PrivateKey +SSL_F_SSL_USE_GM_PRIVATEKEY_ASN1:653:SSL_use_gm_PrivateKey_ASN1 SSL_F_SSL_USE_PRIVATEKEY:201:SSL_use_PrivateKey SSL_F_SSL_USE_PRIVATEKEY_ASN1:202:SSL_use_PrivateKey_ASN1 SSL_F_SSL_USE_PRIVATEKEY_FILE:203:SSL_use_PrivateKey_file @@ -1361,6 +1375,20 @@ SSL_F_SSL_WRITE_EARLY_FINISH:527:* SSL_F_SSL_WRITE_EX:433:SSL_write_ex SSL_F_SSL_WRITE_INTERNAL:524:ssl_write_internal SSL_F_STATE_MACHINE:353:state_machine +SSL_F_TLCP_CHOOSE_SIGALG:662:tlcp_choose_sigalg +SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE:663:tlcp_construct_cke_sm2dhe +SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC:658:tlcp_construct_cke_sm2ecc +SSL_F_TLCP_CONSTRUCT_CLIENT_KEY_EXCHANGE:654:tlcp_construct_client_key_exchange +SSL_F_TLCP_CONSTRUCT_SERVER_KEY_EXCHANGE:655:tlcp_construct_server_key_exchange +SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE:664:tlcp_construct_ske_sm2dhe +SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC:659:tlcp_construct_ske_sm2ecc +SSL_F_TLCP_DERIVE:665:tlcp_derive +SSL_F_TLCP_PROCESS_CKE_SM2DHE:666:tlcp_process_cke_sm2dhe +SSL_F_TLCP_PROCESS_CKE_SM2ECC:660:tlcp_process_cke_sm2ecc +SSL_F_TLCP_PROCESS_CLIENT_KEY_EXCHANGE:656:tlcp_process_client_key_exchange +SSL_F_TLCP_PROCESS_KEY_EXCHANGE:657:tlcp_process_key_exchange +SSL_F_TLCP_PROCESS_SKE_SM2DHE:667:tlcp_process_ske_sm2dhe +SSL_F_TLCP_PROCESS_SKE_SM2ECC:661:tlcp_process_ske_sm2ecc SSL_F_TLS12_CHECK_PEER_SIGALG:333:tls12_check_peer_sigalg SSL_F_TLS12_COPY_SIGALGS:533:tls12_copy_sigalgs SSL_F_TLS13_CHANGE_CIPHER_STATE:440:tls13_change_cipher_state @@ -1769,7 +1797,7 @@ X509_F_X509_STORE_NEW:158:X509_STORE_new X509_F_X509_TO_X509_REQ:126:X509_to_X509_REQ X509_F_X509_TRUST_ADD:133:X509_TRUST_add X509_F_X509_TRUST_SET:141:X509_TRUST_set -X509_F_X509_VERIFY:161:X509_verify +X509_F_X509_VERIFY:166:X509_verify X509_F_X509_VERIFY_CERT:127:X509_verify_cert X509_F_X509_VERIFY_PARAM_NEW:159:X509_VERIFY_PARAM_new X509_F_X509_VERIFY_SM2:162:x509_verify_sm2 diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index daf7fdc..e3c9e05 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -187,7 +187,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { "different key types"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_PARAMETERS), "different parameters"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DISABLED_FOR_FIPS), "disabled for FIPS"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DISABLED_FOR_FIPS), "disabled for fips"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ERROR_LOADING_SECTION), "error loading section"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ERROR_SETTING_FIPS_MODE), @@ -279,8 +279,6 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { "wrap mode not allowed"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRONG_FINAL_BLOCK_LENGTH), "wrong final block length"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE), - "xts data unit is too large"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_XTS_DUPLICATED_KEYS), "xts duplicated keys"}, {0, NULL} diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 1f36cb2..9e25ae1 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -459,6 +459,24 @@ const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len) } #endif +# ifndef OPENSSL_NO_SM2 +int EVP_PKEY_is_sm2(EVP_PKEY *pkey) +{ + EC_KEY *eckey; + const EC_GROUP *group; + if (pkey == NULL) { + return 0; + } + if (EVP_PKEY_id(pkey) == EVP_PKEY_EC + && (eckey = EVP_PKEY_get0_EC_KEY(pkey)) != NULL + && (group = EC_KEY_get0_group(eckey)) != NULL + && EC_GROUP_get_curve_name(group) == NID_sm2) { + return 1; + } + return EVP_PKEY_id(pkey) == EVP_PKEY_SM2; +} +# endif + #ifndef OPENSSL_NO_RSA int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) { diff --git a/crypto/rsa/rsa_err.c b/crypto/rsa/rsa_err.c index cf43265..888fd07 100644 --- a/crypto/rsa/rsa_err.c +++ b/crypto/rsa/rsa_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -34,7 +34,8 @@ static const ERR_STRING_DATA RSA_str_functs[] = { {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CHECK_KEY_EX, 0), "RSA_check_key_ex"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CMS_DECRYPT, 0), "rsa_cms_decrypt"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CMS_VERIFY, 0), "rsa_cms_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_GENERATE_KEY_EX, 0), "RSA_generate_key_ex"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_GENERATE_KEY_EX, 0), + "RSA_generate_key_ex"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_GENERATE_MULTI_PRIME_KEY, 0), "RSA_generate_multi_prime_key"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_ITEM_VERIFY, 0), "rsa_item_verify"}, @@ -93,16 +94,21 @@ static const ERR_STRING_DATA RSA_str_functs[] = { {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PARAM_DECODE, 0), "rsa_param_decode"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRINT, 0), "RSA_print"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRINT_FP, 0), "RSA_print_fp"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIVATE_DECRYPT, 0), + "RSA_private_decrypt"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIVATE_ENCRYPT, 0), + "RSA_private_encrypt"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIV_DECODE, 0), "rsa_priv_decode"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIV_ENCODE, 0), "rsa_priv_encode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIVATE_DECRYPT, 0), "RSA_private_decrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIVATE_ENCRYPT, 0), "RSA_private_encrypt"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PSS_GET_PARAM, 0), "rsa_pss_get_param"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PSS_TO_CTX, 0), "rsa_pss_to_ctx"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PUB_DECODE, 0), "rsa_pub_decode"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PUBLIC_DECRYPT, 0), "RSA_public_decrypt"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PUBLIC_ENCRYPT, 0), "RSA_public_encrypt"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PUB_DECODE, 0), "rsa_pub_decode"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SETUP_BLINDING, 0), "RSA_setup_blinding"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SET_DEFAULT_METHOD, 0), + "RSA_set_default_method"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SET_METHOD, 0), "RSA_set_method"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SIGN, 0), "RSA_sign"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SIGN_ASN1_OCTET_STRING, 0), "RSA_sign_ASN1_OCTET_STRING"}, @@ -111,8 +117,6 @@ static const ERR_STRING_DATA RSA_str_functs[] = { "RSA_verify_ASN1_OCTET_STRING"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, 0), "RSA_verify_PKCS1_PSS_mgf1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SET_DEFAULT_METHOD, 0), "RSA_set_default_method"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SET_METHOD, 0), "RSA_set_method"}, {ERR_PACK(ERR_LIB_RSA, RSA_F_SETUP_TBUF, 0), "setup_tbuf"}, {0, NULL} }; @@ -193,8 +197,9 @@ static const ERR_STRING_DATA RSA_str_reasons[] = { {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D), "mp exponent not congruent to d"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_R_NOT_PRIME), "mp r not prime"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NON_FIPS_RSA_METHOD), + "non fips rsa method"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NO_PUBLIC_EXPONENT), "no public exponent"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NON_FIPS_RSA_METHOD), "non FIPS rsa method"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NULL_BEFORE_BLOCK_MISSING), "null before block missing"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES), @@ -204,7 +209,7 @@ static const ERR_STRING_DATA RSA_str_reasons[] = { {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OAEP_DECODING_ERROR), "oaep decoding error"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE), - "operation not allowed in FIPS mode"}, + "operation not allowed in fips mode"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), "operation not supported for this keytype"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PADDING_CHECK_FAILED), diff --git a/crypto/sm2/build.info b/crypto/sm2/build.info index be76d96..adaf5f3 100644 --- a/crypto/sm2/build.info +++ b/crypto/sm2/build.info @@ -1,5 +1,5 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - sm2_sign.c sm2_crypt.c sm2_err.c sm2_pmeth.c + sm2_sign.c sm2_crypt.c sm2_err.c sm2_pmeth.c sm2_kep.c diff --git a/crypto/sm2/sm2_err.c b/crypto/sm2/sm2_err.c index e5973e9..f5f75cb 100644 --- a/crypto/sm2/sm2_err.c +++ b/crypto/sm2/sm2_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -21,6 +21,7 @@ static const ERR_STRING_DATA SM2_str_functs[] = { "pkey_sm2_digest_custom"}, {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_INIT, 0), "pkey_sm2_init"}, {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_SIGN, 0), "pkey_sm2_sign"}, + {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_KEY, 0), "SM2_compute_key"}, {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_MSG_HASH, 0), "sm2_compute_msg_hash"}, {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_USERID_DIGEST, 0), @@ -51,6 +52,7 @@ static const ERR_STRING_DATA SM2_str_reasons[] = { {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_ENCODING), "invalid encoding"}, {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_FIELD), "invalid field"}, {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NO_PARAMETERS_SET), "no parameters set"}, + {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NO_PRIVATE_VALUE), "no private value"}, {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_USER_ID_TOO_LARGE), "user id too large"}, {0, NULL} }; diff --git a/crypto/sm2/sm2_kep.c b/crypto/sm2/sm2_kep.c new file mode 100644 index 0000000..a7bd681 --- /dev/null +++ b/crypto/sm2/sm2_kep.c @@ -0,0 +1,254 @@ +/* + * Copyright 2019 The BabaSSL Project Authors. All Rights Reserved. + */ + +#include "internal/cryptlib.h" +#include <openssl/ec.h> +#include <openssl/evp.h> +#include <openssl/bn.h> +#include "crypto/sm2.h" +#include "crypto/ec.h" /* ecdh_KDF_X9_63() */ +#include "crypto/sm2err.h" + + +#ifndef OPENSSL_NO_SM2 +int SM2_compute_key(void *out, size_t outlen, int server, + const char *peer_uid, int peer_uid_len, + const char *self_uid, int self_uid_len, + const EC_KEY *peer_ecdhe_key, const EC_KEY *self_ecdhe_key, + const EC_KEY *peer_pub_key, const EC_KEY *self_eckey, + const EVP_MD *md) +{ + BN_CTX *ctx = NULL; + EC_POINT *UorV = NULL; + const EC_POINT *Rs, *Rp; + BIGNUM *Xs = NULL, *Xp = NULL, *h = NULL, *t = NULL, *two_power_w = NULL, *order = NULL; + const BIGNUM *priv_key, *r; + const EC_GROUP *group; + int w; + int ret = -1; + size_t buflen, len; + unsigned char *buf = NULL; + size_t elemet_len, idx; + + if (outlen > INT_MAX) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (peer_pub_key == NULL || self_eckey == NULL) { + SM2err(SM2_F_SM2_COMPUTE_KEY, SM2_R_NO_PRIVATE_VALUE); + goto err; + } + + priv_key = EC_KEY_get0_private_key(self_eckey); + if (priv_key == NULL) { + SM2err(SM2_F_SM2_COMPUTE_KEY, SM2_R_NO_PRIVATE_VALUE); + goto err; + } + + if (peer_ecdhe_key == NULL || self_ecdhe_key == NULL) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + + Rs = EC_KEY_get0_public_key(self_ecdhe_key); + Rp = EC_KEY_get0_public_key(peer_ecdhe_key); + r = EC_KEY_get0_private_key(self_ecdhe_key); + + if (Rs == NULL || Rp == NULL || r == NULL) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + BN_CTX_start(ctx); + Xs = BN_CTX_get(ctx); + Xp = BN_CTX_get(ctx); + h = BN_CTX_get(ctx); + t = BN_CTX_get(ctx); + two_power_w = BN_CTX_get(ctx); + order = BN_CTX_get(ctx); + + if (order == NULL) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + group = EC_KEY_get0_group(self_eckey); + + if (!EC_GROUP_get_order(group, order, ctx) + || !EC_GROUP_get_cofactor(group, h, ctx)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + w = (BN_num_bits(order) + 1) / 2 - 1; + if (!BN_lshift(two_power_w, BN_value_one(), w)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); + goto err; + } + + /*Third: Caculate -- X = 2 ^ w + (x & (2 ^ w - 1)) = 2 ^ w + (x mod 2 ^ w)*/ + UorV = EC_POINT_new(group); + if (UorV == NULL) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + /*Test peer public key On curve*/ + if (!EC_POINT_is_on_curve(group, Rp, ctx)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); + goto err; + } + + /*Get x*/ + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) + == NID_X9_62_prime_field) { + if (!EC_POINT_get_affine_coordinates_GFp(group, Rs, Xs, NULL, ctx)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); + goto err; + } + + if (!EC_POINT_get_affine_coordinates_GFp(group, Rp, Xp, NULL, ctx)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); + goto err; + } + } + + /*x mod 2 ^ w*/ + /*Caculate Self x*/ + if (!BN_nnmod(Xs, Xs, two_power_w, ctx)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); + goto err; + } + + if (!BN_add(Xs, Xs, two_power_w)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); + goto err; + } + + /*Caculate Peer x*/ + if (!BN_nnmod(Xp, Xp, two_power_w, ctx)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); + goto err; + } + + if (!BN_add(Xp, Xp, two_power_w)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); + goto err; + } + + /*Forth: Caculate t*/ + if (!BN_mod_mul(t, Xs, r, order, ctx)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); + goto err; + } + + if (!BN_mod_add(t, t, priv_key, order, ctx)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); + goto err; + } + + /*Fifth: Caculate V or U*/ + if (!BN_mul(t, t, h, ctx)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); + goto err; + } + + /* [x]R */ + if (!EC_POINT_mul(group, UorV, NULL, Rp, Xp, ctx)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); + goto err; + } + + /* P + [x]R */ + if (!EC_POINT_add(group, UorV, UorV, + EC_KEY_get0_public_key(peer_pub_key), ctx)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); + goto err; + } + + if (!EC_POINT_mul(group, UorV, NULL, UorV, t, ctx)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); + goto err; + } + + if (EC_POINT_is_at_infinity(group, UorV)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); + goto err; + } + + /*Sixth: Caculate Key -- Need Xuorv, Yuorv, Zc, Zs, klen*/ + + elemet_len = (size_t)((EC_GROUP_get_degree(group) + 7) / 8); + buflen = elemet_len * 2 + 32 * 2 + 1; /*add 1 byte tag*/ + buf = (unsigned char *)OPENSSL_zalloc(buflen + 10); + if (buf == NULL) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + /*1 : Get public key for UorV, Notice: the first byte is a tag, not a valid char*/ + idx = EC_POINT_point2oct(group, UorV, 4, buf, buflen, ctx); + if (!idx) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); + goto err; + } + + len = EVP_MD_size(md); + + /* Z_A || Z_B, server is initiator(Z_A), client is responder(Z_B) */ + if (server) { + if (!sm2_compute_z_digest((uint8_t *)(buf + idx), md, + (const uint8_t *)self_uid, + self_uid_len, self_eckey)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); + goto err; + } + + idx += len; + } + + if (!sm2_compute_z_digest((uint8_t *)(buf + idx), md, + (const uint8_t *)peer_uid, peer_uid_len, + peer_pub_key)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); + goto err; + } + idx += len; + + if (!server) { + if (!sm2_compute_z_digest((uint8_t *)(buf + idx), md, + (const uint8_t *)self_uid, + self_uid_len, self_eckey)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); + goto err; + } + idx += len; + } + + if (!ecdh_KDF_X9_63(out, outlen, (const unsigned char *)(buf + 1), idx - 1, + NULL, 0, md)) { + SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = outlen; + + err: + EC_POINT_free(UorV); + OPENSSL_free(buf); + if (ctx != NULL) + BN_CTX_end(ctx); + BN_CTX_free(ctx); + + return ret; +} + +#endif diff --git a/crypto/sm2/sm2_pmeth.c b/crypto/sm2/sm2_pmeth.c index 9551d70..1998812 100644 --- a/crypto/sm2/sm2_pmeth.c +++ b/crypto/sm2/sm2_pmeth.c @@ -287,6 +287,10 @@ static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) const EVP_MD *md = EVP_MD_CTX_md(mctx); int mdlen = EVP_MD_size(md); + if (!smctx->id_set) + (void)pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID, SM2_DEFAULT_USERID_LEN + , (void *)SM2_DEFAULT_USERID); + if (!smctx->id_set) { /* * An ID value must be set. The specifications are not clear whether a diff --git a/doc/man1/s_client.pod b/doc/man1/s_client.pod index f1a2c4a..8fa82a1 100644 --- a/doc/man1/s_client.pod +++ b/doc/man1/s_client.pod @@ -20,8 +20,10 @@ B<openssl> B<s_client> [B<-verify depth>] [B<-verify_return_error>] [B<-cert filename>] +[B<-dcert filename>] [B<-certform DER|PEM>] [B<-key filename>] +[B<-dkey filename>] [B<-keyform DER|PEM>] [B<-cert_chain filename>] [B<-build_chain>] @@ -32,6 +34,7 @@ B<openssl> B<s_client> [B<-xcertform PEM|DER>] [B<-xkeyform PEM|DER>] [B<-pass arg>] +[B<-dpass arg>] [B<-CApath directory>] [B<-CAfile filename>] [B<-chainCApath directory>] @@ -91,6 +94,7 @@ B<openssl> B<s_client> [B<-tls1_1>] [B<-tls1_2>] [B<-tls1_3>] +[B<-tlcp>] [B<-no_ssl3>] [B<-no_tls1>] [B<-no_tls1_1>] @@ -214,6 +218,11 @@ ClientHello message. Cannot be used in conjunction with the B<-servername> or The certificate to use, if one is requested by the server. The default is not to use a certificate. +=item B<-dcert infile>, B<-dkey infile>, B<-dpass val> + +Specify an encryption certificate, private key and passphrase +respectively, usually for TLCP. + =item B<-certform format> The certificate format to use: DER or PEM. PEM is the default. diff --git a/doc/man3/EVP_PKEY_set1_RSA.pod b/doc/man3/EVP_PKEY_set1_RSA.pod index d571e58..f9ee16d 100644 --- a/doc/man3/EVP_PKEY_set1_RSA.pod +++ b/doc/man3/EVP_PKEY_set1_RSA.pod @@ -9,7 +9,7 @@ EVP_PKEY_assign_RSA, EVP_PKEY_assign_DSA, EVP_PKEY_assign_DH, EVP_PKEY_assign_EC_KEY, EVP_PKEY_assign_POLY1305, EVP_PKEY_assign_SIPHASH, EVP_PKEY_get0_hmac, EVP_PKEY_get0_poly1305, EVP_PKEY_get0_siphash, EVP_PKEY_type, EVP_PKEY_id, EVP_PKEY_base_id, EVP_PKEY_set_alias_type, -EVP_PKEY_set1_engine, EVP_PKEY_get0_engine - EVP_PKEY assignment functions +EVP_PKEY_is_sm2, EVP_PKEY_set1_engine, EVP_PKEY_get0_engine - EVP_PKEY assignment functions =head1 SYNOPSIS @@ -45,6 +45,8 @@ EVP_PKEY_set1_engine, EVP_PKEY_get0_engine - EVP_PKEY assignment functions int EVP_PKEY_type(int type); int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type); + int EVP_PKEY_is_sm2(EVP_PKEY *pkey); + ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey); int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *engine); @@ -93,6 +95,9 @@ EVP_PKEY_set_alias_type() allows modifying a EVP_PKEY to use a different set of algorithms than the default. This is currently used to support SM2 keys, which use an identical encoding to ECDSA. +EVP_PKEY_is_sm2() can be used to determine whether the B<pkey> is +SM2 curve. + =head1 NOTES In accordance with the OpenSSL naming convention the key obtained @@ -134,6 +139,8 @@ EVP_PKEY_set1_engine() returns 1 for success and 0 for failure. EVP_PKEY_set_alias_type() returns 1 for success and 0 for error. +EVP_PKEY_is_sm2() returns 1 for success and 0 for error. + =head1 EXAMPLES After loading an ECC key, it is possible to convert it to using SM2 diff --git a/doc/man3/SSL_CTX_new.pod b/doc/man3/SSL_CTX_new.pod index a6c036c..23f93f6 100644 --- a/doc/man3/SSL_CTX_new.pod +++ b/doc/man3/SSL_CTX_new.pod @@ -9,7 +9,8 @@ TLSv1_1_method, TLSv1_1_server_method, TLSv1_1_client_method, TLS_method, TLS_server_method, TLS_client_method, SSLv23_method, SSLv23_server_method, SSLv23_client_method, DTLS_method, DTLS_server_method, DTLS_client_method, DTLSv1_method, DTLSv1_server_method, DTLSv1_client_method, -DTLSv1_2_method, DTLSv1_2_server_method, DTLSv1_2_client_method +DTLSv1_2_method, DTLSv1_2_server_method, DTLSv1_2_client_method, +TLCP_method, TLCP_server_method, TLCP_client_method, - create a new SSL_CTX object as framework for TLS/SSL or DTLS enabled functions @@ -68,6 +69,12 @@ functions const SSL_METHOD *DTLSv1_2_client_method(void); #endif + #ifndef OPENSSL_NO_TLCP + const SSL_METHOD *TLCP_method(void); + const SSL_METHOD *TLCP_server_method(void); + const SSL_METHOD *TLCP_client_method(void); + #endif + =head1 DESCRIPTION SSL_CTX_new() creates a new B<SSL_CTX> object as framework to @@ -93,6 +100,8 @@ These are the general-purpose I<version-flexible> SSL/TLS methods. The actual protocol version used will be negotiated to the highest version mutually supported by the client and the server. The supported protocols are SSLv3, TLSv1, TLSv1.1, TLSv1.2 and TLSv1.3. +TLS_method() and TLS_server_method() can aslo support TLCP protocol +by using TLCP_client_method(). Applications should use these methods, and avoid the version-specific methods described below, which are deprecated. @@ -141,6 +150,12 @@ These methods are deprecated. These are the version-specific methods for DTLSv1. These methods are deprecated. +=item TLCP_method(), TLCP_server_method(), TLCP_client_method() + +These are the GM version-specific methods for TLCP protocol. +Valid TLCP ciphersuite names are ECDHE-SM4-CBC-SM3 and ECC-SM4-CBC-SM3. +B<enable-tlcp>(argument to Configure) was required. + =back SSL_CTX_new() initializes the list of ciphers, the session cache setting, the @@ -162,7 +177,7 @@ allow newer protocols like TLS 1.0, TLS 1.1, TLS 1.2 or TLS 1.3. The list of protocols available can also be limited using the B<SSL_OP_NO_SSLv3>, B<SSL_OP_NO_TLSv1>, B<SSL_OP_NO_TLSv1_1>, -B<SSL_OP_NO_TLSv1_3>, B<SSL_OP_NO_TLSv1_2> and B<SSL_OP_NO_TLSv1_3> +B<SSL_OP_NO_TLSv1_3>, B<SSL_OP_NO_TLSv1_2>, B<SSL_OP_NO_TLSv1_3> and B<SSL_OP_NO_TLCP> options of the L<SSL_CTX_set_options(3)> or L<SSL_set_options(3)> functions, but this approach is not recommended. Clients should avoid creating "holes" in the set of diff --git a/doc/man3/SSL_CTX_set_options.pod b/doc/man3/SSL_CTX_set_options.pod index 969e036..304e966 100644 --- a/doc/man3/SSL_CTX_set_options.pod +++ b/doc/man3/SSL_CTX_set_options.pod @@ -114,11 +114,11 @@ preferences. When not set, the SSL server will always follow the clients preferences. When set, the SSL/TLS server will choose following its own preferences. -=item SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1, SSL_OP_NO_TLSv1_1, +=item SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1, SSL_OP_NO_TLSv1_1, SSL_OP_NO_TLCP SSL_OP_NO_TLSv1_2, SSL_OP_NO_TLSv1_3, SSL_OP_NO_DTLSv1, SSL_OP_NO_DTLSv1_2 These options turn off the SSLv3, TLSv1, TLSv1.1, TLSv1.2 or TLSv1.3 protocol -versions with TLS or the DTLSv1, DTLSv1.2 versions with DTLS, +versions with TLS or the DTLSv1, DTLSv1.2 versions with DTLS, TLCP respectively. As of OpenSSL 1.1.0, these options are deprecated, use L<SSL_CTX_set_min_proto_version(3)> and diff --git a/doc/man3/SSL_CTX_use_certificate.pod b/doc/man3/SSL_CTX_use_certificate.pod index b065d8f..7a717e7 100644 --- a/doc/man3/SSL_CTX_use_certificate.pod +++ b/doc/man3/SSL_CTX_use_certificate.pod @@ -12,7 +12,12 @@ SSL_CTX_use_RSAPrivateKey_ASN1, SSL_CTX_use_RSAPrivateKey_file, SSL_use_PrivateKey_file, SSL_use_PrivateKey_ASN1, SSL_use_PrivateKey, SSL_use_RSAPrivateKey, SSL_use_RSAPrivateKey_ASN1, SSL_use_RSAPrivateKey_file, SSL_CTX_check_private_key, SSL_check_private_key, -SSL_CTX_use_cert_and_key, SSL_use_cert_and_key +SSL_CTX_use_cert_and_key, SSL_use_cert_and_key, +SSL_CTX_use_gm_certificate, SSL_CTX_use_gm_certificate_ASN1, SSL_CTX_use_gm_certificate_file, +SSL_use_gm_certificate, SSL_use_gm_certificate_ASN1, SSL_use_gm_certificate_file, +SSL_CTX_use_gm_PrivateKey, SSL_CTX_use_gm_PrivateKey_ASN1, SSL_CTX_use_gm_PrivateKey_file, +SSL_use_gm_PrivateKey, SSL_use_gm_PrivateKey_ASN1, SSL_use_gm_PrivateKey_file, +SSL_CTX_use_gm_cert_and_key, SSL_use_gm_cert_and_key - load certificate and key data =head1 SYNOPSIS @@ -26,6 +31,13 @@ SSL_CTX_use_cert_and_key, SSL_use_cert_and_key int SSL_use_certificate_ASN1(SSL *ssl, unsigned char *d, int len); int SSL_use_certificate_file(SSL *ssl, const char *file, int type); + int SSL_CTX_use_gm_certificate(SSL_CTX *ctx, X509 *x, int usage); + int SSL_CTX_use_gm_certificate_ASN1(SSL_CTX *ctx, int len, unsigned char *d, int usage); + int SSL_CTX_use_gm_certificate_file(SSL_CTX *ctx, const char *file, int type, int usage); + int SSL_use_gm_certificate(SSL *ssl, X509 *x, int usage); + int SSL_use_gm_certificate_ASN1(SSL *ssl, unsigned char *d, int len, int usage); + int SSL_use_gm_certificate_file(SSL *ssl, const char *file, int type, int usage); + int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); int SSL_use_certificate_chain_file(SSL *ssl, const char *file); @@ -43,12 +55,23 @@ SSL_CTX_use_cert_and_key, SSL_use_cert_and_key int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len); int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); + int SSL_CTX_use_gm_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey, int usage); + int SSL_CTX_use_gm_PrivateKey_ASN1(int pk, SSL_CTX *ctx, unsigned char *d, + long len, int usage); + int SSL_CTX_use_gm_PrivateKey_file(SSL_CTX *ctx, const char *file, int type, int usage); + int SSL_use_gm_PrivateKey(SSL *ssl, EVP_PKEY *pkey, int usage); + int SSL_use_gm_PrivateKey_ASN1(int pk, SSL *ssl, unsigned char *d, long len, int usage); + int SSL_use_gm_PrivateKey_file(SSL *ssl, const char *file, int type, int usage); + int SSL_CTX_check_private_key(const SSL_CTX *ctx); int SSL_check_private_key(const SSL *ssl); int SSL_CTX_use_cert_and_key(SSL_CTX *ctx, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override); int SSL_use_cert_and_key(SSL *ssl, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override); + int SSL_CTX_use_gm_cert_and_key(SSL_CTX *ctx, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override, int usage); + int SSL_use_gm_cert_and_key(SSL *ssl, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override, int usage); + =head1 DESCRIPTION These functions load the certificates and private keys into the SSL_CTX @@ -81,6 +104,21 @@ SSL_use_certificate_file() loads the certificate from B<file> into B<ssl>. See the NOTES section on why SSL_CTX_use_certificate_chain_file() should be preferred. +SSL_CTX_use_gm_certificate() loads the certificate B<x> into B<ctx> +and specify B<usage>. SSL_use_gm_certificate() loads B<x> into B<ssl> +and specify B<usage>. The B<usage> should be SSL_USAGE_SIG or SSL_USAGE_ENC. + +SSL_CTX_use_gm_certificate_ASN1() loads the ASN1 encoded certificate from +the memory location B<d> (with length B<len>) into B<ctx> and specify B<usage>, +SSL_use_gm_certificate_ASN1() loads the ASN1 encoded certificate into B<ssl> +and specify B<usage>. + +SSL_CTX_use_gm_certificate_file() loads the first certificate stored in B<file> +into B<ctx> and specify B<usage>. The formatting B<type> of the certificate must +be specified from the known types SSL_FILETYPE_PEM, SSL_FILETYPE_ASN1. +SSL_use_gm_certificate_file() loads the certificate from B<file> into B<ssl> +and specify B<usage>. + SSL_CTX_use_certificate_chain_file() loads a certificate chain from B<file> into B<ctx>. The certificates must be in PEM format and must be sorted starting with the subject's certificate (actual client or server @@ -127,6 +165,22 @@ B<file> to B<ctx>. SSL_use_PrivateKey_file() adds the first private key found in B<file> to B<ssl>; SSL_use_RSAPrivateKey_file() adds the first private RSA key found to B<ssl>. +SSL_CTX_use_gm_PrivateKey() adds B<pkey> as private key to B<ctx> and +specify B<usage>. SSL_CTX_use_gm_PrivateKey_ASN1() adds the private key of +type B<pk> stored at memory location B<d> (length B<len>) to B<ctx> and +specify B<usage>. SSL_CTX_use_gm_PrivateKey_file() adds the first private +key found in B<file> to B<ctx>. The formatting B<type> of the private key +must be specified from the known types SSL_FILETYPE_PEM, SSL_FILETYPE_ASN1. + +SSL_use_PrivateKey() adds B<pkey> as private key to B<ssl> and sprcify B<usage>. +SSL_use_gm_PrivateKey_ASN1() adds the private key to B<ssl> and sprcify B<usage>. +SSL_use_gm_PrivateKey_file() adds the first private key found in B<file> to B<ssl> +and sprcify B<usage>. + +SSL_CTX_use_gm_cert_and_key() and SSL_use_gm_cert_and_key() assign the X.509 +certificate B<x>, private key B<key>, and certificate B<chain> onto the +corresponding B<ssl> or B<ctx> and specify B<usage>. + SSL_CTX_check_private_key() checks the consistency of a private key with the corresponding certificate loaded into B<ctx>. If more than one key/certificate pair (RSA/DSA) is installed, the last item installed will diff --git a/doc/man7/ssl.pod b/doc/man7/ssl.pod index d439860..8d7293a 100644 --- a/doc/man7/ssl.pod +++ b/doc/man7/ssl.pod @@ -183,6 +183,18 @@ Constructor for the SSLv3 SSL_METHOD structure for clients. Constructor for the SSLv3 SSL_METHOD structure for servers. +=item const SSL_METHOD *B<TLCP_method>(void); + +Constructor for the TLCP SSL_METHOD structure for clients, servers or both. + +=item const SSL_METHOD *B<TLCP_client_method>(void); + +Constructor for the TLCP SSL_METHOD structure for clients. + +=item const SSL_METHOD *B<TLCP_server_method>(void); + +Constructor for the TLCP SSL_METHOD structure for servers. + =back =head2 Dealing with Ciphers @@ -393,6 +405,12 @@ Use the file path to locate trusted CA certificates. =item int B<SSL_CTX_use_RSAPrivateKey_file>(SSL_CTX *ctx, const char *file, int type); +=item int B<SSL_CTX_use_gm_PrivateKey>(SSL_CTX *ctx, EVP_PKEY *pkey, int usage); + +=item int B<SSL_CTX_use_gm_PrivateKey_ASN1>(int type, SSL_CTX *ctx, unsigned char *d, long len, int usage); + +=item int B<SSL_CTX_use_gm_PrivateKey_file>(SSL_CTX *ctx, const char *file, int type, int usage); + =item int B<SSL_CTX_use_certificate>(SSL_CTX *ctx, X509 *x); =item int B<SSL_CTX_use_certificate_ASN1>(SSL_CTX *ctx, int len, unsigned char *d); @@ -401,6 +419,14 @@ Use the file path to locate trusted CA certificates. =item int B<SSL_CTX_use_cert_and_key>(SSL_CTX *ctx, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override); +=item int B<SSL_CTX_use_gm_certificate>(SSL_CTX *ctx, X509 *x, int usage); + +=item int B<SSL_CTX_use_gm_certificate_ASN1>(SSL_CTX *ctx, int len, unsigned char *d, int usage); + +=item int B<SSL_CTX_use_gm_certificate_file>(SSL_CTX *ctx, const char *file, int type, int usage); + +=item int B<SSL_CTX_use_gm_cert_and_key>(SSL_CTX *ctx, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override, int usage); + =item X509 *B<SSL_CTX_get0_certificate>(const SSL_CTX *ctx); =item EVP_PKEY *B<SSL_CTX_get0_privatekey>(const SSL_CTX *ctx); @@ -704,6 +730,12 @@ Returns the current handshake state. =item int B<SSL_use_RSAPrivateKey_file>(SSL *ssl, const char *file, int type); +=item int B<SSL_use_gm_PrivateKey>(SSL *ssl, EVP_PKEY *pkey, int usage); + +=item int B<SSL_use_gm_PrivateKey_ASN1>(int type, SSL *ssl, unsigned char *d, long len, int usage); + +=item int B<SSL_use_gm_PrivateKey_file>(SSL *ssl, const char *file, int type, int usage); + =item int B<SSL_use_certificate>(SSL *ssl, X509 *x); =item int B<SSL_use_certificate_ASN1>(SSL *ssl, int len, unsigned char *d); @@ -712,6 +744,14 @@ Returns the current handshake state. =item int B<SSL_use_cert_and_key>(SSL *ssl, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override); +=item int B<SSL_use_gm_certificate>(SSL *ssl, X509 *x, int usage); + +=item int B<SSL_use_gm_certificate_ASN1>(SSL *ssl, int len, unsigned char *d, int usage); + +=item int B<SSL_use_gm_certificate_file>(SSL *ssl, const char *file, int type, int usage); + +=item int B<SSL_use_gm_cert_and_key>(SSL *ssl, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override, int usage); + =item int B<SSL_version>(const SSL *ssl); =item int B<SSL_want>(const SSL *ssl); diff --git a/include/crypto/sm2.h b/include/crypto/sm2.h index a7f5548..720bdd4 100644 --- a/include/crypto/sm2.h +++ b/include/crypto/sm2.h @@ -19,6 +19,7 @@ /* The default user id as specified in GM/T 0009-2012 */ # define SM2_DEFAULT_USERID "1234567812345678" +# define SM2_DEFAULT_USERID_LEN 16 int sm2_compute_z_digest(uint8_t *out, const EVP_MD *digest, diff --git a/include/crypto/sm2err.h b/include/crypto/sm2err.h index d1c0ee2..251c4f9 100644 --- a/include/crypto/sm2err.h +++ b/include/crypto/sm2err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,12 +8,10 @@ * https://www.openssl.org/source/license.html */ -#ifndef OSSL_CRYPTO_SM2ERR_H -# define OSSL_CRYPTO_SM2ERR_H +#ifndef HEADER_SM2ERR_H +# define HEADER_SM2ERR_H -# ifndef HEADER_SYMHACKS_H -# include <openssl/symhacks.h> -# endif +# include <openssl/symhacks.h> # include <openssl/opensslconf.h> @@ -33,6 +31,7 @@ int ERR_load_SM2_strings(void); # define SM2_F_PKEY_SM2_DIGEST_CUSTOM 114 # define SM2_F_PKEY_SM2_INIT 111 # define SM2_F_PKEY_SM2_SIGN 112 +# define SM2_F_SM2_COMPUTE_KEY 116 # define SM2_F_SM2_COMPUTE_MSG_HASH 100 # define SM2_F_SM2_COMPUTE_USERID_DIGEST 101 # define SM2_F_SM2_COMPUTE_Z_DIGEST 113 @@ -59,6 +58,7 @@ int ERR_load_SM2_strings(void); # define SM2_R_INVALID_ENCODING 104 # define SM2_R_INVALID_FIELD 105 # define SM2_R_NO_PARAMETERS_SET 109 +# define SM2_R_NO_PRIVATE_VALUE 113 # define SM2_R_USER_ID_TOO_LARGE 106 # endif diff --git a/include/openssl/dherr.h b/include/openssl/dherr.h index b2d62eb..e7fdb21 100644 --- a/include/openssl/dherr.h +++ b/include/openssl/dherr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,9 +11,7 @@ #ifndef HEADER_DHERR_H # define HEADER_DHERR_H -# ifndef HEADER_SYMHACKS_H -# include <openssl/symhacks.h> -# endif +# include <openssl/symhacks.h> # include <openssl/opensslconf.h> @@ -36,9 +34,8 @@ int ERR_load_DH_strings(void); # define DH_F_DH_CMS_DECRYPT 114 # define DH_F_DH_CMS_SET_PEERKEY 115 # define DH_F_DH_CMS_SET_SHARED_INFO 116 -# define DH_F_DH_COMPUTE_KEY 203 -# define DH_F_DH_GENERATE_KEY 202 -# define DH_F_DH_GENERATE_PARAMETERS_EX 201 +# define DH_F_DH_COMPUTE_KEY 126 +# define DH_F_DH_GENERATE_PARAMETERS_EX 127 # define DH_F_DH_METH_DUP 117 # define DH_F_DH_METH_NEW 118 # define DH_F_DH_METH_SET1_NAME 119 @@ -76,14 +73,14 @@ int ERR_load_DH_strings(void); # define DH_R_INVALID_PARAMETER_NID 114 # define DH_R_INVALID_PUBKEY 102 # define DH_R_KDF_PARAMETER_ERROR 112 -# define DH_R_KEY_SIZE_TOO_SMALL 201 # define DH_R_KEYS_NOT_SET 108 +# define DH_R_KEY_SIZE_TOO_SMALL 126 # define DH_R_MISSING_PUBKEY 125 # define DH_R_MODULUS_TOO_LARGE 103 +# define DH_R_NON_FIPS_METHOD 127 # define DH_R_NOT_SUITABLE_GENERATOR 120 # define DH_R_NO_PARAMETERS_SET 107 # define DH_R_NO_PRIVATE_VALUE 100 -# define DH_R_NON_FIPS_METHOD 202 # define DH_R_PARAMETER_ENCODING_ERROR 105 # define DH_R_PEER_KEY_ERROR 111 # define DH_R_SHARED_INFO_ERROR 113 diff --git a/include/openssl/dsaerr.h b/include/openssl/dsaerr.h index 19f650a..83f1b68 100644 --- a/include/openssl/dsaerr.h +++ b/include/openssl/dsaerr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,9 +11,7 @@ #ifndef HEADER_DSAERR_H # define HEADER_DSAERR_H -# ifndef HEADER_SYMHACKS_H -# include <openssl/symhacks.h> -# endif +# include <openssl/symhacks.h> # include <openssl/opensslconf.h> @@ -29,13 +27,13 @@ int ERR_load_DSA_strings(void); */ # define DSA_F_DSAPARAMS_PRINT 100 # define DSA_F_DSAPARAMS_PRINT_FP 101 -# define DSA_F_DSA_BUILTIN_KEYGEN 202 +# define DSA_F_DSA_BUILTIN_KEYGEN 108 # define DSA_F_DSA_BUILTIN_PARAMGEN 125 # define DSA_F_DSA_BUILTIN_PARAMGEN2 126 -# define DSA_F_DSA_GENERATE_KEY 201 -# define DSA_F_DSA_GENERATE_PARAMETERS_EX 200 # define DSA_F_DSA_DO_SIGN 112 # define DSA_F_DSA_DO_VERIFY 113 +# define DSA_F_DSA_GENERATE_KEY 109 +# define DSA_F_DSA_GENERATE_PARAMETERS_EX 110 # define DSA_F_DSA_METH_DUP 127 # define DSA_F_DSA_METH_NEW 128 # define DSA_F_DSA_METH_SET1_NAME 129 @@ -63,13 +61,13 @@ int ERR_load_DSA_strings(void); # define DSA_R_DECODE_ERROR 104 # define DSA_R_INVALID_DIGEST_TYPE 106 # define DSA_R_INVALID_PARAMETERS 112 -# define DSA_R_KEY_SIZE_INVALID 201 -# define DSA_R_KEY_SIZE_TOO_SMALL 202 +# define DSA_R_KEY_SIZE_INVALID 114 +# define DSA_R_KEY_SIZE_TOO_SMALL 115 # define DSA_R_MISSING_PARAMETERS 101 # define DSA_R_MISSING_PRIVATE_KEY 111 # define DSA_R_MODULUS_TOO_LARGE 103 +# define DSA_R_NON_FIPS_DSA_METHOD 116 # define DSA_R_NO_PARAMETERS_SET 107 -# define DSA_R_NON_FIPS_DSA_METHOD 200 # define DSA_R_PARAMETER_ENCODING_ERROR 105 # define DSA_R_Q_NOT_PRIME 113 # define DSA_R_SEED_LEN_SMALL 110 diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 0f7fbd1..3116c1b 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1011,6 +1011,10 @@ const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len); const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len); # endif +# ifndef OPENSSL_NO_SM2 +int EVP_PKEY_is_sm2(EVP_PKEY *pkey); +# endif + # ifndef OPENSSL_NO_RSA struct rsa_st; int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h index bfa2e68..da604ca 100644 --- a/include/openssl/evperr.h +++ b/include/openssl/evperr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -22,15 +22,15 @@ int ERR_load_EVP_strings(void); * EVP function codes. */ # define EVP_F_AESNI_INIT_KEY 165 -# define EVP_F_AESNI_XTS_INIT_KEY 233 +# define EVP_F_AESNI_XTS_INIT_KEY 207 # define EVP_F_AES_GCM_CTRL 196 # define EVP_F_AES_INIT_KEY 133 # define EVP_F_AES_OCB_CIPHER 169 # define EVP_F_AES_T4_INIT_KEY 178 -# define EVP_F_AES_T4_XTS_INIT_KEY 234 +# define EVP_F_AES_T4_XTS_INIT_KEY 208 # define EVP_F_AES_WRAP_CIPHER 170 -# define EVP_F_AES_XTS_CIPHER 229 -# define EVP_F_AES_XTS_INIT_KEY 235 +# define EVP_F_AES_XTS_CIPHER 210 +# define EVP_F_AES_XTS_INIT_KEY 209 # define EVP_F_ALG_MODULE_INIT 177 # define EVP_F_ARIA_CCM_INIT_KEY 175 # define EVP_F_ARIA_GCM_CTRL 197 @@ -141,9 +141,9 @@ int ERR_load_EVP_strings(void); # define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 # define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 # define EVP_R_DECODE_ERROR 114 -# define EVP_R_DISABLED_FOR_FIPS 200 # define EVP_R_DIFFERENT_KEY_TYPES 101 # define EVP_R_DIFFERENT_PARAMETERS 153 +# define EVP_R_DISABLED_FOR_FIPS 185 # define EVP_R_ERROR_LOADING_SECTION 165 # define EVP_R_ERROR_SETTING_FIPS_MODE 166 # define EVP_R_EXPECTING_AN_HMAC_KEY 174 @@ -186,7 +186,7 @@ int ERR_load_EVP_strings(void); # define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 # define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 # define EVP_R_PUBLIC_KEY_NOT_RSA 106 -# define EVP_R_TOO_LARGE 201 +# define EVP_R_TOO_LARGE 186 # define EVP_R_UNKNOWN_CIPHER 160 # define EVP_R_UNKNOWN_DIGEST 161 # define EVP_R_UNKNOWN_OPTION 169 @@ -202,7 +202,6 @@ int ERR_load_EVP_strings(void); # define EVP_R_UNSUPPORTED_SALT_TYPE 126 # define EVP_R_WRAP_MODE_NOT_ALLOWED 170 # define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 -# define EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE 191 -# define EVP_R_XTS_DUPLICATED_KEYS 192 +# define EVP_R_XTS_DUPLICATED_KEYS 183 #endif diff --git a/include/openssl/rsaerr.h b/include/openssl/rsaerr.h index a8bcfdf..6bbd265 100644 --- a/include/openssl/rsaerr.h +++ b/include/openssl/rsaerr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,9 +11,7 @@ #ifndef HEADER_RSAERR_H # define HEADER_RSAERR_H -# ifndef HEADER_SYMHACKS_H -# include <openssl/symhacks.h> -# endif +# include <openssl/symhacks.h> # ifdef __cplusplus extern "C" @@ -25,7 +23,7 @@ int ERR_load_RSA_strings(void); */ # define RSA_F_CHECK_PADDING_MD 140 # define RSA_F_ENCODE_PKCS1 146 -# define RSA_F_FIPS_RSA_BUILTIN_KEYGEN 206 +# define RSA_F_FIPS_RSA_BUILTIN_KEYGEN 168 # define RSA_F_INT_RSA_VERIFY 145 # define RSA_F_OLD_RSA_PRIV_DECODE 147 # define RSA_F_PKEY_PSS_INIT 165 @@ -40,8 +38,8 @@ int ERR_load_RSA_strings(void); # define RSA_F_RSA_CHECK_KEY_EX 160 # define RSA_F_RSA_CMS_DECRYPT 159 # define RSA_F_RSA_CMS_VERIFY 158 -# define RSA_F_RSA_GENERATE_KEY_EX 204 -# define RSA_F_RSA_GENERATE_MULTI_PRIME_KEY 207 +# define RSA_F_RSA_GENERATE_KEY_EX 169 +# define RSA_F_RSA_GENERATE_MULTI_PRIME_KEY 170 # define RSA_F_RSA_ITEM_VERIFY 148 # define RSA_F_RSA_METH_DUP 161 # define RSA_F_RSA_METH_NEW 162 @@ -77,18 +75,18 @@ int ERR_load_RSA_strings(void); # define RSA_F_RSA_PARAM_DECODE 164 # define RSA_F_RSA_PRINT 115 # define RSA_F_RSA_PRINT_FP 116 +# define RSA_F_RSA_PRIVATE_DECRYPT 171 +# define RSA_F_RSA_PRIVATE_ENCRYPT 172 # define RSA_F_RSA_PRIV_DECODE 150 # define RSA_F_RSA_PRIV_ENCODE 138 -# define RSA_F_RSA_PRIVATE_DECRYPT 200 -# define RSA_F_RSA_PRIVATE_ENCRYPT 201 # define RSA_F_RSA_PSS_GET_PARAM 151 # define RSA_F_RSA_PSS_TO_CTX 155 +# define RSA_F_RSA_PUBLIC_DECRYPT 173 +# define RSA_F_RSA_PUBLIC_ENCRYPT 174 # define RSA_F_RSA_PUB_DECODE 139 -# define RSA_F_RSA_PUBLIC_DECRYPT 202 -# define RSA_F_RSA_PUBLIC_ENCRYPT 203 # define RSA_F_RSA_SETUP_BLINDING 136 -# define RSA_F_RSA_SET_DEFAULT_METHOD 205 -# define RSA_F_RSA_SET_METHOD 204 +# define RSA_F_RSA_SET_DEFAULT_METHOD 175 +# define RSA_F_RSA_SET_METHOD 176 # define RSA_F_RSA_SIGN 117 # define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 # define RSA_F_RSA_VERIFY 119 @@ -139,19 +137,19 @@ int ERR_load_RSA_strings(void); # define RSA_R_KEY_PRIME_NUM_INVALID 165 # define RSA_R_KEY_SIZE_TOO_SMALL 120 # define RSA_R_LAST_OCTET_INVALID 134 -# define RSA_R_MISSING_PRIVATE_KEY 179 # define RSA_R_MGF1_DIGEST_NOT_ALLOWED 152 +# define RSA_R_MISSING_PRIVATE_KEY 179 # define RSA_R_MODULUS_TOO_LARGE 105 # define RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R 168 # define RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D 169 # define RSA_R_MP_R_NOT_PRIME 170 +# define RSA_R_NON_FIPS_RSA_METHOD 171 # define RSA_R_NO_PUBLIC_EXPONENT 140 -# define RSA_R_NON_FIPS_RSA_METHOD 200 # define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 # define RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES 172 # define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 # define RSA_R_OAEP_DECODING_ERROR 121 -# define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 201 +# define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 173 # define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 # define RSA_R_PADDING_CHECK_FAILED 114 # define RSA_R_PKCS_DECODING_ERROR 159 @@ -171,7 +169,7 @@ int ERR_load_RSA_strings(void); # define RSA_R_UNSUPPORTED_LABEL_SOURCE 163 # define RSA_R_UNSUPPORTED_MASK_ALGORITHM 153 # define RSA_R_UNSUPPORTED_MASK_PARAMETER 154 -# define RSA_R_UNSUPPORTED_PARAMETERS 202 +# define RSA_R_UNSUPPORTED_PARAMETERS 174 # define RSA_R_UNSUPPORTED_SIGNATURE_TYPE 155 # define RSA_R_VALUE_MISSING 147 # define RSA_R_WRONG_SIGNATURE_LENGTH 119 diff --git a/include/openssl/sm2.h b/include/openssl/sm2.h new file mode 100644 index 0000000..505ebfc --- /dev/null +++ b/include/openssl/sm2.h @@ -0,0 +1,20 @@ +#ifndef HEADER_SM2_H +# define HEADER_SM2_H + +#include "ossl_typ.h" + +# ifdef __cplusplus +extern "C" { +# endif + +int SM2_compute_key(void *out, size_t outlen, + int server, const char *peer_uid, int peer_uid_len, + const char *self_uid, int self_uid_len, + const EC_KEY *peer_ecdhe_key, const EC_KEY *self_ecdhe_key, + const EC_KEY *peer_pub_key, const EC_KEY *self_eckey, + const EVP_MD *md); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index fd0c5a9..a6acbc4 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -300,6 +300,11 @@ typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx); * Reserved value (until OpenSSL 1.2.0) 0x00000001U * Reserved value (until OpenSSL 1.2.0) 0x00000002U */ +#ifndef OPENSSL_NO_TLCP +/* Use reserved value for the position of enc cert, default is placed at the end */ +# define SSL_OP_ENCCERT_SECOND_POSITION 0x00000002U +#endif + /* Allow initial connection to servers that don't support RI */ # define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004U @@ -383,8 +388,15 @@ typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx); # define SSL_OP_NO_DTLSv1 0x04000000U # define SSL_OP_NO_DTLSv1_2 0x08000000U +#ifndef OPENSSL_NO_TLCP +/* Use reserved value for TCLP(GB/T 38636-2020) */ +# define SSL_OP_NO_TLCP 0x00000001U +# define SSL_OP_NO_SSL_MASK (SSL_OP_NO_TLCP|SSL_OP_NO_SSLv3|\ + SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2|SSL_OP_NO_TLSv1_3) +#else # define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv3|\ SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2|SSL_OP_NO_TLSv1_3) +#endif # define SSL_OP_NO_DTLS_MASK (SSL_OP_NO_DTLSv1|SSL_OP_NO_DTLSv1_2) /* Disallow all renegotiation */ @@ -1041,6 +1053,11 @@ typedef enum { TLS_ST_SR_END_OF_EARLY_DATA } OSSL_HANDSHAKE_STATE; +#ifndef OPENSSL_NO_TLCP +# define SSL_USAGE_SIG 0 +# define SSL_USAGE_ENC 1 +#endif + /* * Most of the following state values are no longer used and are defined to be * the closest equivalent value in the current state machine code. Not all @@ -1177,6 +1194,19 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) /* fatal */ # define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK # define SSL_AD_NO_APPLICATION_PROTOCOL TLS1_AD_NO_APPLICATION_PROTOCOL + +/* These alert types are for TLCP */ +# define SSL_AD_UNSUPPORTED_SITE2SITE TLCP_AD_UNSUPPORTED_SITE2SITE +/* fatal */ +# define SSL_AD_NO_AREA TLCP_AD_NO_AREA +# define SSL_AD_UNSUPPORTED_AREATYPE TLCP_AD_UNSUPPORTED_AREATYPE +# define SSL_AD_BAD_IBCPARAM TLCP_AD_BAD_IBCPARAM +/* fatal */ +# define SSL_AD_UNSUPPORTED_IBCPARAM TLCP_AD_UNSUPPORTED_IBCPARAM +/* fatal */ +# define SSL_AD_IDENTITY_NEED TLCP_AD_IDENTITY_NEED +/* fatal */ + # define SSL_ERROR_NONE 0 # define SSL_ERROR_SSL 1 # define SSL_ERROR_WANT_READ 2 @@ -1560,9 +1590,20 @@ __owur int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); __owur int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len); # endif +# ifndef OPENSSL_NO_TLCP +__owur int SSL_use_gm_PrivateKey(SSL *ssl, EVP_PKEY *pkey, int usage); +__owur int SSL_use_gm_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d, + long len, int usage); +# endif __owur int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); __owur int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d, long len); +# ifndef OPENSSL_NO_TLCP +__owur int SSL_use_gm_certificate(SSL *ssl, X509 *x, int usage); +__owur int SSL_use_gm_certificate_ASN1(SSL *ssl, const unsigned char *d, int len, int usage); +__owur int SSL_use_gm_cert_and_key(SSL *ssl, X509 *x509, EVP_PKEY *privatekey, + STACK_OF(X509) *chain, int override, int usage); +# endif __owur int SSL_use_certificate(SSL *ssl, X509 *x); __owur int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); __owur int SSL_use_cert_and_key(SSL *ssl, X509 *x509, EVP_PKEY *privatekey, @@ -1585,6 +1626,11 @@ __owur int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); __owur int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); #endif +#ifndef OPENSSL_NO_TLCP +__owur int SSL_use_gm_PrivateKey_file(SSL *ssl, const char *file, int type, int usage); +__owur int SSL_use_gm_certificate_file(SSL *ssl, const char *file, int type, int usage); +#endif + __owur int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type); __owur int SSL_use_certificate_file(SSL *ssl, const char *file, int type); @@ -1592,6 +1638,13 @@ __owur int SSL_use_certificate_file(SSL *ssl, const char *file, int type); __owur int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); #endif + +#ifndef OPENSSL_NO_TLCP +__owur int SSL_CTX_use_gm_PrivateKey_file(SSL_CTX *ctx, const char *file, + int type, int usage); +__owur int SSL_CTX_use_gm_certificate_file(SSL_CTX *ctx, const char *file, + int type, int usage); +#endif __owur int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); __owur int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, @@ -1695,6 +1748,18 @@ __owur int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); __owur int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); # endif + +# ifndef OPENSSL_NO_TLCP +__owur int SSL_CTX_use_gm_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey, int usage); +__owur int SSL_CTX_use_gm_PrivateKey_ASN1(int pk, SSL_CTX *ctx, + const unsigned char *d, long len, int usage); +__owur int SSL_CTX_use_gm_certificate(SSL_CTX *ctx, X509 *x, int usage); +__owur int SSL_CTX_use_gm_certificate_ASN1(SSL_CTX *ctx, int len, + const unsigned char *d, int usage); +__owur int SSL_CTX_use_gm_cert_and_key(SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, + STACK_OF(X509) *chain, int override, int usage); +# endif + __owur int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); __owur int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len); @@ -1873,6 +1938,12 @@ __owur const SSL_METHOD *TLS_method(void); __owur const SSL_METHOD *TLS_server_method(void); __owur const SSL_METHOD *TLS_client_method(void); +#ifndef OPENSSL_NO_TLCP +__owur const SSL_METHOD *TLCP_method(void); +__owur const SSL_METHOD *TLCP_server_method(void); +__owur const SSL_METHOD *TLCP_client_method(void); +#endif + # ifndef OPENSSL_NO_TLS1_METHOD DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_method(void)) /* TLSv1.0 */ DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_server_method(void)) diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h index 701d61c..aa5f56a 100644 --- a/include/openssl/sslerr.h +++ b/include/openssl/sslerr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,9 +11,7 @@ #ifndef HEADER_SSLERR_H # define HEADER_SSLERR_H -# ifndef HEADER_SYMHACKS_H -# include <openssl/symhacks.h> -# endif +# include <openssl/symhacks.h> # ifdef __cplusplus extern "C" @@ -171,6 +169,10 @@ int ERR_load_SSL_strings(void); # define SSL_F_SSL_CTX_USE_CERTIFICATE 171 # define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172 # define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 173 +# define SSL_F_SSL_CTX_USE_GM_CERTIFICATE 641 +# define SSL_F_SSL_CTX_USE_GM_CERTIFICATE_ASN1 642 +# define SSL_F_SSL_CTX_USE_GM_PRIVATEKEY 643 +# define SSL_F_SSL_CTX_USE_GM_PRIVATEKEY_ASN1 644 # define SSL_F_SSL_CTX_USE_PRIVATEKEY 174 # define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1 175 # define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE 176 @@ -197,7 +199,9 @@ int ERR_load_SSL_strings(void); # define SSL_F_SSL_HANDSHAKE_HASH 560 # define SSL_F_SSL_INIT_WBIO_BUFFER 184 # define SSL_F_SSL_KEY_UPDATE 515 +# define SSL_F_SSL_LOAD_CERT_FILE 645 # define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 +# define SSL_F_SSL_LOAD_PKEY_FILE 646 # define SSL_F_SSL_LOG_MASTER_SECRET 498 # define SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE 499 # define SSL_F_SSL_MODULE_INIT 392 @@ -231,11 +235,14 @@ int ERR_load_SSL_strings(void); # define SSL_F_SSL_SET_CIPHER_LIST 271 # define SSL_F_SSL_SET_CT_VALIDATION_CALLBACK 399 # define SSL_F_SSL_SET_FD 192 +# define SSL_F_SSL_SET_GM_CERT_AND_KEY 647 # define SSL_F_SSL_SET_PKEY 193 # define SSL_F_SSL_SET_RFD 194 # define SSL_F_SSL_SET_SESSION 195 # define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 # define SSL_F_SSL_SET_SESSION_TICKET_EXT 294 +# define SSL_F_SSL_SET_SIGN_ENC_CERT 648 +# define SSL_F_SSL_SET_SIGN_ENC_PKEY 649 # define SSL_F_SSL_SET_TLSEXT_MAX_FRAGMENT_LENGTH 550 # define SSL_F_SSL_SET_WFD 196 # define SSL_F_SSL_SHUTDOWN 224 @@ -246,6 +253,10 @@ int ERR_load_SSL_strings(void); # define SSL_F_SSL_USE_CERTIFICATE 198 # define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 # define SSL_F_SSL_USE_CERTIFICATE_FILE 200 +# define SSL_F_SSL_USE_GM_CERTIFICATE 650 +# define SSL_F_SSL_USE_GM_CERTIFICATE_ASN1 651 +# define SSL_F_SSL_USE_GM_PRIVATEKEY 652 +# define SSL_F_SSL_USE_GM_PRIVATEKEY_ASN1 653 # define SSL_F_SSL_USE_PRIVATEKEY 201 # define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 # define SSL_F_SSL_USE_PRIVATEKEY_FILE 203 @@ -262,6 +273,20 @@ int ERR_load_SSL_strings(void); # define SSL_F_SSL_WRITE_EX 433 # define SSL_F_SSL_WRITE_INTERNAL 524 # define SSL_F_STATE_MACHINE 353 +# define SSL_F_TLCP_CHOOSE_SIGALG 662 +# define SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE 663 +# define SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC 658 +# define SSL_F_TLCP_CONSTRUCT_CLIENT_KEY_EXCHANGE 654 +# define SSL_F_TLCP_CONSTRUCT_SERVER_KEY_EXCHANGE 655 +# define SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE 664 +# define SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC 659 +# define SSL_F_TLCP_DERIVE 665 +# define SSL_F_TLCP_PROCESS_CKE_SM2DHE 666 +# define SSL_F_TLCP_PROCESS_CKE_SM2ECC 660 +# define SSL_F_TLCP_PROCESS_CLIENT_KEY_EXCHANGE 656 +# define SSL_F_TLCP_PROCESS_KEY_EXCHANGE 657 +# define SSL_F_TLCP_PROCESS_SKE_SM2DHE 667 +# define SSL_F_TLCP_PROCESS_SKE_SM2ECC 661 # define SSL_F_TLS12_CHECK_PEER_SIGALG 333 # define SSL_F_TLS12_COPY_SIGALGS 533 # define SSL_F_TLS13_CHANGE_CIPHER_STATE 440 diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h index 76d9fda..f05382a 100644 --- a/include/openssl/tls1.h +++ b/include/openssl/tls1.h @@ -24,6 +24,7 @@ extern "C" { # define OPENSSL_TLS_SECURITY_LEVEL 1 # endif +# define TLCP_VERSION 0x0101 # define TLS1_VERSION 0x0301 # define TLS1_1_VERSION 0x0302 # define TLS1_2_VERSION 0x0303 @@ -33,6 +34,9 @@ extern "C" { /* Special value for method supporting multiple versions */ # define TLS_ANY_VERSION 0x10000 +# define TLCP_VERSION_MAJOR 0x01 +# define TLCP_VERSION_MINOR 0x01 + # define TLS1_VERSION_MAJOR 0x03 # define TLS1_VERSION_MINOR 0x01 @@ -73,6 +77,14 @@ extern "C" { # define TLS1_AD_UNKNOWN_PSK_IDENTITY 115/* fatal */ # define TLS1_AD_NO_APPLICATION_PROTOCOL 120 /* fatal */ +/* TLCP(GB/T 38636-2020) alerts */ +# define TLCP_AD_UNSUPPORTED_SITE2SITE 200 /* fatal */ +# define TLCP_AD_NO_AREA 201 +# define TLCP_AD_UNSUPPORTED_AREATYPE 202 +# define TLCP_AD_BAD_IBCPARAM 203 /* fatal */ +# define TLCP_AD_UNSUPPORTED_IBCPARAM 204 /* fatal */ +# define TLCP_AD_IDENTITY_NEED 205 /* fatal */ + /* ExtensionType values from RFC3546 / RFC4366 / RFC6066 */ # define TLSEXT_TYPE_server_name 0 # define TLSEXT_TYPE_max_fragment_length 1 @@ -641,6 +653,10 @@ __owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain) # define TLS1_CK_RSA_PSK_WITH_ARIA_128_GCM_SHA256 0x0300C06E # define TLS1_CK_RSA_PSK_WITH_ARIA_256_GCM_SHA384 0x0300C06F +/* some TLCP ciphersuites from GB/T 38636-2020 */ +# define TLCP_CK_ECDHE_SM2_WITH_SM4_CBC_SM3 0x0300E011 +# define TLCP_CK_ECC_SM2_WITH_SM4_CBC_SM3 0x0300E013 + /* a bundle of RFC standard cipher names, generated from ssl3_ciphers[] */ # define TLS1_RFC_RSA_WITH_AES_128_SHA "TLS_RSA_WITH_AES_128_CBC_SHA" # define TLS1_RFC_DHE_DSS_WITH_AES_128_SHA "TLS_DHE_DSS_WITH_AES_128_CBC_SHA" @@ -1127,6 +1143,10 @@ __owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain) # define TLS1_TXT_RSA_PSK_WITH_ARIA_128_GCM_SHA256 "RSA-PSK-ARIA128-GCM-SHA256" # define TLS1_TXT_RSA_PSK_WITH_ARIA_256_GCM_SHA384 "RSA-PSK-ARIA256-GCM-SHA384" +/* some TLCP ciphersuites from GB/T 38636-2020 */ +# define TLCP_TXT_ECDHE_SM2_WITH_SM4_CBC_SM3 "ECDHE-SM4-CBC-SM3" +# define TLCP_TXT_ECC_SM2_WITH_SM4_CBC_SM3 "ECC-SM4-CBC-SM3" + # define TLS_CT_RSA_SIGN 1 # define TLS_CT_DSS_SIGN 2 # define TLS_CT_RSA_FIXED_DH 3 diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 42e9eee..f6e82f1 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -55,6 +55,10 @@ extern "C" { # define X509v3_KU_ENCIPHER_ONLY 0x0001 # define X509v3_KU_DECIPHER_ONLY 0x8000 # define X509v3_KU_UNDEF 0xffff +/* For TLCP sm2 certificates */ +# define X509v3_KU_SM2_SIGN (X509v3_KU_DIGITAL_SIGNATURE | X509v3_KU_NON_REPUDIATION) +# define X509v3_KU_SM2_ENC_ENCIPHERMENT (X509v3_KU_KEY_ENCIPHERMENT | X509v3_KU_DATA_ENCIPHERMENT) +# define X509v3_KU_SM2_ENC_CIPHER_ONLY (X509v3_KU_ENCIPHER_ONLY | X509v3_KU_DECIPHER_ONLY) struct X509_algor_st { ASN1_OBJECT *algorithm; diff --git a/include/openssl/x509err.h b/include/openssl/x509err.h index 0a84ef0..1e51e04 100644 --- a/include/openssl/x509err.h +++ b/include/openssl/x509err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -84,7 +84,7 @@ int ERR_load_X509_strings(void); # define X509_F_X509_TO_X509_REQ 126 # define X509_F_X509_TRUST_ADD 133 # define X509_F_X509_TRUST_SET 141 -# define X509_F_X509_VERIFY 161 +# define X509_F_X509_VERIFY 166 # define X509_F_X509_VERIFY_CERT 127 # define X509_F_X509_VERIFY_PARAM_NEW 159 # define X509_F_X509_VERIFY_SM2 162 diff --git a/ssl/methods.c b/ssl/methods.c index c5e8898..2a6cd73 100644 --- a/ssl/methods.c +++ b/ssl/methods.c @@ -109,6 +109,25 @@ IMPLEMENT_tls_meth_func(TLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1, IMPLEMENT_ssl3_meth_func(sslv3_client_method, ssl_undefined_function, ossl_statem_connect) #endif +/*- + * TLCP methods + */ +#ifndef OPENSSL_NO_TLCP +IMPLEMENT_tls_meth_func(TLCP_VERSION, 0, SSL_OP_NO_TLCP, + tlcp_method, + ossl_statem_accept, + ossl_statem_connect, TLCP_enc_data) + +IMPLEMENT_tls_meth_func(TLCP_VERSION, 0, SSL_OP_NO_TLCP, + tlcp_server_method, + ossl_statem_accept, + ssl_undefined_function, TLCP_enc_data) + +IMPLEMENT_tls_meth_func(TLCP_VERSION, 0, SSL_OP_NO_TLCP, + tlcp_client_method, + ssl_undefined_function, + ossl_statem_connect, TLCP_enc_data) +#endif /*- * DTLS methods */ @@ -207,6 +226,23 @@ const SSL_METHOD *TLSv1_1_client_method(void) } # endif +# ifndef OPENSSL_NO_TLCP +const SSL_METHOD *TLCP_method(void) +{ + return tlcp_method(); +} + +const SSL_METHOD *TLCP_server_method(void) +{ + return tlcp_server_method(); +} + +const SSL_METHOD *TLCP_client_method(void) +{ + return tlcp_client_method(); +} +# endif + # ifndef OPENSSL_NO_TLS1_METHOD const SSL_METHOD *TLSv1_method(void) { diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c index f158544..af825b1 100644 --- a/ssl/record/ssl3_record.c +++ b/ssl/record/ssl3_record.c @@ -309,7 +309,11 @@ int ssl3_get_record(SSL *s) return -1; } +#ifndef OPENSSL_NO_TLCP + if ((version >> 8) != SSL3_VERSION_MAJOR && (version != TLCP_VERSION)) { +#else if ((version >> 8) != SSL3_VERSION_MAJOR) { +#endif if (RECORD_LAYER_is_first_record(&s->rlayer)) { /* Go back to start of packet, look at the five bytes * that we have. */ diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 918cab0..5ecd953 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -15,6 +15,8 @@ #include "ssl_local.h" #include <openssl/md5.h> #include <openssl/dh.h> +#include "include/crypto/sm2.h" +#include <openssl/sm2.h> #include <openssl/rand.h> #include "internal/cryptlib.h" @@ -2667,6 +2669,43 @@ static SSL_CIPHER ssl3_ciphers[] = { }, #endif /* OPENSSL_NO_GOST */ +#ifndef OPENSSL_NO_TLCP + { + 1, + TLCP_TXT_ECDHE_SM2_WITH_SM4_CBC_SM3, + NULL, + TLCP_CK_ECDHE_SM2_WITH_SM4_CBC_SM3, + SSL_kSM2DHE, + SSL_aSM2, + SSL_SM4CBC, + SSL_SM3, + TLCP_VERSION, + TLS1_2_VERSION, + 0, 0, + SSL_HIGH, + SSL_HANDSHAKE_MAC_SM3 | TLS1_PRF_SM3, + 128, + 128, + }, + { + 1, + TLCP_TXT_ECC_SM2_WITH_SM4_CBC_SM3, + NULL, + TLCP_CK_ECC_SM2_WITH_SM4_CBC_SM3, + SSL_kSM2ECC, + SSL_aSM2, + SSL_SM4CBC, + SSL_SM3, + TLCP_VERSION, + TLS1_2_VERSION, + 0, 0, + SSL_HIGH, + SSL_HANDSHAKE_MAC_SM3 | TLS1_PRF_SM3, + 128, + 128, + }, +#endif /* OPENSSL_NO_TLCP */ + #ifndef OPENSSL_NO_IDEA { 1, @@ -4313,6 +4352,20 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, ret = tmp; continue; } +#ifndef OPENSSL_NO_TLCP + /* Prefer ECC-SM4-CBC-SM3 while enabling TLCP */ + if (!(s->options & SSL_OP_NO_TLCP)) { + const SSL_CIPHER *tmp = sk_SSL_CIPHER_value(allow, ii); + + if (tmp->id == TLCP_CK_ECC_SM2_WITH_SM4_CBC_SM3) { + ret = tmp; + break; + } + if (ret == NULL) + ret = tmp; + continue; + } +#endif ret = sk_SSL_CIPHER_value(allow, ii); break; } @@ -4856,3 +4909,76 @@ EVP_PKEY *ssl_dh_to_pkey(DH *dh) return ret; } #endif + +#ifndef OPENSSL_NO_TLCP +int tlcp_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey) +{ + unsigned char *pms; + int pmslen = SSL_MAX_MASTER_KEY_LENGTH; + EC_KEY *tmp_peer_pub_key, *tmp_self_priv_key; + EC_KEY *self_priv_key, *peer_pub_key; + X509 *peer_enc_cert; + int ret; + + if ((tmp_self_priv_key = EVP_PKEY_get0_EC_KEY(privkey)) == NULL + || (tmp_peer_pub_key = EVP_PKEY_get0_EC_KEY(pubkey)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_DERIVE, + ERR_R_INTERNAL_ERROR); + return 0; + } + + if (s->cert->pkeys[SSL_PKEY_SM2_ENC].privatekey == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_DERIVE, + ERR_R_INTERNAL_ERROR); + return 0; + } + + if ((self_priv_key = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_SM2_ENC].privatekey)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_DERIVE, + ERR_R_EC_LIB); + return 0; + } + + peer_enc_cert = ssl_get_sm2_enc_cert(s, s->session->peer_chain); + if (peer_enc_cert == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_DERIVE, + ERR_R_INTERNAL_ERROR); + return 0; + } + + if ((peer_pub_key = EVP_PKEY_get0_EC_KEY(X509_get0_pubkey(peer_enc_cert))) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_DERIVE, + ERR_R_INTERNAL_ERROR); + return 0; + } + + pms = OPENSSL_malloc(pmslen); + if (pms == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_DERIVE, + ERR_R_MALLOC_FAILURE); + return 0; + } + + if (SM2_compute_key(pms, pmslen, s->server, + SM2_DEFAULT_USERID, SM2_DEFAULT_USERID_LEN, + SM2_DEFAULT_USERID, SM2_DEFAULT_USERID_LEN, + tmp_peer_pub_key, tmp_self_priv_key, + peer_pub_key, self_priv_key, + EVP_sm3()) != pmslen) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_DERIVE, + ERR_R_INTERNAL_ERROR); + OPENSSL_free(pms); + return 0; + } + + if (s->server) { + ret = ssl_generate_master_secret(s, pms, (size_t)pmslen, 1); + } else { + s->s3->tmp.pms = pms; + s->s3->tmp.pmslen = pmslen; + ret = 1; + } + + return ret; +} +#endif diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c index 9264364..beb3c3b 100644 --- a/ssl/ssl_asn1.c +++ b/ssl/ssl_asn1.c @@ -265,7 +265,8 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, if ((as->ssl_version >> 8) != SSL3_VERSION_MAJOR && (as->ssl_version >> 8) != DTLS1_VERSION_MAJOR - && as->ssl_version != DTLS1_BAD_VER) { + && as->ssl_version != DTLS1_BAD_VER + && as->ssl_version != TLCP_VERSION) { SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_UNSUPPORTED_SSL_VERSION); goto err; } diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index e7feda8..73d76a5 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -937,18 +937,31 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, return 0; /* Level 3: forward secure ciphersuites only */ if (level >= 3 && c->min_tls != TLS1_3_VERSION && +#ifndef OPENSSL_NO_TLCP + !(c->algorithm_mkey & (SSL_kEDH | SSL_kEECDH | SSL_kSM2DHE))) +#else !(c->algorithm_mkey & (SSL_kEDH | SSL_kEECDH))) +#endif return 0; break; } case SSL_SECOP_VERSION: if (!SSL_IS_DTLS(s)) { +#ifndef OPENSSL_NO_TLCP + /* SSLv3 not allowed at level 2 */ + if (nid <= SSL3_VERSION && nid != TLCP_VERSION && level >= 2) + return 0; + /* TLS v1.1 and above only for level 3 */ + if (nid <= TLS1_VERSION && nid != TLCP_VERSION && level >= 3) + return 0; +#else /* SSLv3 not allowed at level 2 */ if (nid <= SSL3_VERSION && level >= 2) return 0; /* TLS v1.1 and above only for level 3 */ if (nid <= TLS1_VERSION && level >= 3) return 0; +#endif /* TLS v1.2 only for level 4 and above */ if (nid <= TLS1_1_VERSION && level >= 4) return 0; @@ -1003,6 +1016,11 @@ const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx) { int nid = EVP_PKEY_id(pk); size_t tmpidx; +#ifndef OPENSSL_NO_TLCP + if (EVP_PKEY_is_sm2((EVP_PKEY *)pk)) { + nid = NID_sm2; + } +#endif if (nid == NID_undef) return NULL; diff --git a/ssl/ssl_cert_table.h b/ssl/ssl_cert_table.h index 0c47241..1e1864f 100644 --- a/ssl/ssl_cert_table.h +++ b/ssl/ssl_cert_table.h @@ -19,5 +19,9 @@ static const SSL_CERT_LOOKUP ssl_cert_info [] = { {NID_id_GostR3410_2012_256, SSL_aGOST12}, /* SSL_PKEY_GOST12_256 */ {NID_id_GostR3410_2012_512, SSL_aGOST12}, /* SSL_PKEY_GOST12_512 */ {EVP_PKEY_ED25519, SSL_aECDSA}, /* SSL_PKEY_ED25519 */ - {EVP_PKEY_ED448, SSL_aECDSA} /* SSL_PKEY_ED448 */ + {EVP_PKEY_ED448, SSL_aECDSA}, /* SSL_PKEY_ED448 */ +#ifndef OPENSSL_NO_TLCP + {EVP_PKEY_SM2, SSL_aSM2}, /* SSL_PKEY_SM2_SIGN */ + {EVP_PKEY_SM2, SSL_aSM2} /* SSL_PKEY_SM2_ENC */ +#endif }; diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index b8eba0c..b0d50b5 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -43,7 +43,12 @@ #define SSL_ENC_CHACHA_IDX 19 #define SSL_ENC_ARIA128GCM_IDX 20 #define SSL_ENC_ARIA256GCM_IDX 21 +#ifndef OPENSSL_NO_TLCP +#define SSL_ENC_SM4CBC_IDX 22 +#define SSL_ENC_NUM_IDX 23 +#else #define SSL_ENC_NUM_IDX 22 +#endif /* NB: make sure indices in these tables match values above */ @@ -76,6 +81,9 @@ static const ssl_cipher_table ssl_cipher_table_cipher[SSL_ENC_NUM_IDX] = { {SSL_CHACHA20POLY1305, NID_chacha20_poly1305}, /* SSL_ENC_CHACHA_IDX 19 */ {SSL_ARIA128GCM, NID_aria_128_gcm}, /* SSL_ENC_ARIA128GCM_IDX 20 */ {SSL_ARIA256GCM, NID_aria_256_gcm}, /* SSL_ENC_ARIA256GCM_IDX 21 */ +#ifndef OPENSSL_NO_TLCP + {SSL_SM4CBC, NID_sm4_cbc}, /* SSL_ENC_SM4CBC_IDX 22*/ +#endif }; static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]; @@ -110,11 +118,17 @@ static const ssl_cipher_table ssl_cipher_table_mac[SSL_MD_NUM_IDX] = { {SSL_GOST12_512, NID_id_GostR3411_2012_512}, /* SSL_MD_GOST12_512_IDX 8 */ {0, NID_md5_sha1}, /* SSL_MD_MD5_SHA1_IDX 9 */ {0, NID_sha224}, /* SSL_MD_SHA224_IDX 10 */ - {0, NID_sha512} /* SSL_MD_SHA512_IDX 11 */ + {0, NID_sha512}, /* SSL_MD_SHA512_IDX 11 */ +#ifndef OPENSSL_NO_TLCP + {SSL_SM3, NID_sm3} /* SSL_MD_SM3_IDX 12 */ +#endif }; static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +#ifndef OPENSSL_NO_TLCP + NULL +#endif }; /* *INDENT-OFF* */ @@ -172,7 +186,10 @@ static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = { /* GOST2012_512 */ EVP_PKEY_HMAC, /* MD5/SHA1, SHA224, SHA512 */ - NID_undef, NID_undef, NID_undef + NID_undef, NID_undef, NID_undef, +#ifndef OPENSSL_NO_TLCP + EVP_PKEY_HMAC +#endif }; static size_t ssl_mac_secret_size[SSL_MD_NUM_IDX]; @@ -1696,6 +1713,14 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_kANY: kx = "any"; break; +#ifndef OPENSSL_NO_TLCP + case SSL_kSM2ECC: + kx = "SM2ECC"; + break; + case SSL_kSM2DHE: + kx = "SM2DHE"; + break; +#endif default: kx = "unknown"; } @@ -1729,6 +1754,11 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_aANY: au = "any"; break; +#ifndef OPENSSL_NO_TLCP + case SSL_aSM2: + au = "SM2"; + break; +#endif default: au = "unknown"; break; @@ -1799,6 +1829,11 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_CHACHA20POLY1305: enc = "CHACHA20/POLY1305(256)"; break; +#ifndef OPENSSL_NO_TLCP + case SSL_SM4CBC: + enc = "SM4CBC"; + break; +#endif default: enc = "unknown"; break; @@ -1831,6 +1866,11 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_GOST12_512: mac = "GOST2012"; break; +#ifndef OPENSSL_NO_TLCP + case SSL_SM3: + mac = "SM3"; + break; +#endif default: mac = "unknown"; break; diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 324f2cc..5a7c42a 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -113,6 +113,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = { "ossl_statem_server_post_process_message"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_POST_WORK, 0), "ossl_statem_server_post_work"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_PRE_WORK, 0), + "ossl_statem_server_pre_work"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE, 0), "ossl_statem_server_process_message"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION, 0), @@ -244,6 +246,14 @@ static const ERR_STRING_DATA SSL_str_functs[] = { "SSL_CTX_use_certificate_ASN1"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, 0), "SSL_CTX_use_certificate_file"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_GM_CERTIFICATE, 0), + "SSL_CTX_use_gm_certificate"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_GM_CERTIFICATE_ASN1, 0), + "SSL_CTX_use_gm_certificate_ASN1"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_GM_PRIVATEKEY, 0), + "SSL_CTX_use_gm_PrivateKey"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_GM_PRIVATEKEY_ASN1, 0), + "SSL_CTX_use_gm_PrivateKey_ASN1"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_PRIVATEKEY, 0), "SSL_CTX_use_PrivateKey"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, 0), @@ -285,8 +295,10 @@ static const ERR_STRING_DATA SSL_str_functs[] = { {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_INIT_WBIO_BUFFER, 0), "ssl_init_wbio_buffer"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_KEY_UPDATE, 0), "SSL_key_update"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_LOAD_CERT_FILE, 0), "ssl_load_cert_file"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_LOAD_CLIENT_CA_FILE, 0), "SSL_load_client_CA_file"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_LOAD_PKEY_FILE, 0), "ssl_load_pkey_file"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_LOG_MASTER_SECRET, 0), ""}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE, 0), "ssl_log_rsa_client_key_exchange"}, @@ -331,6 +343,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = { {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_CT_VALIDATION_CALLBACK, 0), "SSL_set_ct_validation_callback"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_FD, 0), "SSL_set_fd"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_GM_CERT_AND_KEY, 0), + "ssl_set_gm_cert_and_key"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_PKEY, 0), "ssl_set_pkey"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_RFD, 0), "SSL_set_rfd"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_SESSION, 0), "SSL_set_session"}, @@ -338,6 +352,10 @@ static const ERR_STRING_DATA SSL_str_functs[] = { "SSL_set_session_id_context"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_SESSION_TICKET_EXT, 0), "SSL_set_session_ticket_ext"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_SIGN_ENC_CERT, 0), + "ssl_set_sign_enc_cert"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_SIGN_ENC_PKEY, 0), + "ssl_set_sign_enc_pkey"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_TLSEXT_MAX_FRAGMENT_LENGTH, 0), "SSL_set_tlsext_max_fragment_length"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_WFD, 0), "SSL_set_wfd"}, @@ -355,6 +373,14 @@ static const ERR_STRING_DATA SSL_str_functs[] = { "SSL_use_certificate_ASN1"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_CERTIFICATE_FILE, 0), "SSL_use_certificate_file"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_GM_CERTIFICATE, 0), + "SSL_use_gm_certificate"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_GM_CERTIFICATE_ASN1, 0), + "SSL_use_gm_certificate_ASN1"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_GM_PRIVATEKEY, 0), + "SSL_use_gm_PrivateKey"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_GM_PRIVATEKEY_ASN1, 0), + "SSL_use_gm_PrivateKey_ASN1"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_PRIVATEKEY, 0), "SSL_use_PrivateKey"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_PRIVATEKEY_ASN1, 0), "SSL_use_PrivateKey_ASN1"}, @@ -380,6 +406,32 @@ static const ERR_STRING_DATA SSL_str_functs[] = { {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_WRITE_EX, 0), "SSL_write_ex"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_WRITE_INTERNAL, 0), "ssl_write_internal"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_STATE_MACHINE, 0), "state_machine"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_CHOOSE_SIGALG, 0), "tlcp_choose_sigalg"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE, 0), + "tlcp_construct_cke_sm2dhe"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, 0), + "tlcp_construct_cke_sm2ecc"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_CONSTRUCT_CLIENT_KEY_EXCHANGE, 0), + "tlcp_construct_client_key_exchange"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_CONSTRUCT_SERVER_KEY_EXCHANGE, 0), + "tlcp_construct_server_key_exchange"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, 0), + "tlcp_construct_ske_sm2dhe"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, 0), + "tlcp_construct_ske_sm2ecc"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_DERIVE, 0), "tlcp_derive"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_PROCESS_CKE_SM2DHE, 0), + "tlcp_process_cke_sm2dhe"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_PROCESS_CKE_SM2ECC, 0), + "tlcp_process_cke_sm2ecc"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_PROCESS_CLIENT_KEY_EXCHANGE, 0), + "tlcp_process_client_key_exchange"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_PROCESS_KEY_EXCHANGE, 0), + "tlcp_process_key_exchange"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_PROCESS_SKE_SM2DHE, 0), + "tlcp_process_ske_sm2dhe"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_PROCESS_SKE_SM2ECC, 0), + "tlcp_process_ske_sm2ecc"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS12_CHECK_PEER_SIGALG, 0), "tls12_check_peer_sigalg"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS12_COPY_SIGALGS, 0), "tls12_copy_sigalgs"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 78c4f99..27e5ed2 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -560,8 +560,14 @@ static int ssl_check_allowed_versions(int min_version, int max_version) #ifdef OPENSSL_NO_TLS1_3 || (min_version <= TLS1_3_VERSION && TLS1_3_VERSION <= max_version) #endif - ) + ) { +#ifndef OPENSSL_NO_TLCP + if (min_version == TLCP_VERSION || max_version == TLCP_VERSION) { + return 1; + } +#endif return 0; + } } return 1; } @@ -3365,6 +3371,9 @@ void ssl_set_masks(SSL *s) unsigned long mask_k, mask_a; #ifndef OPENSSL_NO_EC int have_ecc_cert, ecdsa_ok; +#endif +#ifndef OPENSSL_NO_TLCP + int tlcp_sm2_sign, tlcp_sm2_enc; #endif if (c == NULL) return; @@ -3380,14 +3389,23 @@ void ssl_set_masks(SSL *s) dsa_sign = pvalid[SSL_PKEY_DSA_SIGN] & CERT_PKEY_VALID; #ifndef OPENSSL_NO_EC have_ecc_cert = pvalid[SSL_PKEY_ECC] & CERT_PKEY_VALID; +#endif +#ifndef OPENSSL_NO_TLCP + tlcp_sm2_sign = ssl_has_cert(s, SSL_PKEY_SM2_SIGN); + tlcp_sm2_enc = ssl_has_cert(s, SSL_PKEY_SM2_ENC); #endif mask_k = 0; mask_a = 0; #ifdef CIPHER_DEBUG +#ifndef OPENSSL_NO_TLCP + fprintf(stderr, "dht=%d re=%d rs=%d ds=%d tss=%d tse=%d\n", + dh_tmp, rsa_enc, rsa_sign, dsa_sign, tlcp_sm2_sign, tlcp_sm2_enc); +#else fprintf(stderr, "dht=%d re=%d rs=%d ds=%d\n", dh_tmp, rsa_enc, rsa_sign, dsa_sign); #endif +#endif #ifndef OPENSSL_NO_GOST if (ssl_has_cert(s, SSL_PKEY_GOST12_512)) { @@ -3457,6 +3475,14 @@ void ssl_set_masks(SSL *s) mask_k |= SSL_kECDHE; #endif +#ifndef OPENSSL_NO_TLCP + if (tlcp_sm2_sign) + mask_a |= SSL_aSM2; + + if (tlcp_sm2_enc) + mask_k |= SSL_kSM2ECC | SSL_kSM2DHE; +#endif + #ifndef OPENSSL_NO_PSK mask_k |= SSL_kPSK; mask_a |= SSL_aPSK; @@ -3786,6 +3812,11 @@ const char *ssl_protocol_to_string(int version) case TLS1_VERSION: return "TLSv1"; +#ifndef OPENSSL_NO_TLCP + case TLCP_VERSION: + return "TLCP"; +#endif + case SSL3_VERSION: return "SSLv3"; @@ -5700,3 +5731,51 @@ void SSL_set_allow_early_data_cb(SSL *s, s->allow_early_data_cb = cb; s->allow_early_data_cb_data = arg; } + +#ifndef OPENSSL_NO_TLCP +int ssl_is_sm2_cert(X509 *x) +{ + return x && EVP_PKEY_is_sm2(X509_get0_pubkey(x)); +} + +int ssl_is_sm2_sign_usage(X509 *x) +{ + return x && (X509_get_extension_flags(x) & EXFLAG_KUSAGE) && + (X509_get_key_usage(x) & X509v3_KU_SM2_SIGN); +} + +int ssl_is_sm2_enc_usage(X509 *x) +{ + return x && (X509_get_extension_flags(x) & EXFLAG_KUSAGE) && + ((X509_get_key_usage(x) & X509v3_KU_SM2_ENC_ENCIPHERMENT) || + ((X509_get_key_usage(x) & X509v3_KU_SM2_ENC_CIPHER_ONLY) && + (X509_get_key_usage(x) & X509v3_KU_KEY_AGREEMENT)) + ); +} + +X509 *ssl_get_sm2_enc_cert(SSL *s, STACK_OF(X509) *chain) +{ + X509 *x; + int i; + + for (i = sk_X509_num(chain) - 1; i >= 0 ; --i) { + x = sk_X509_value(chain, i); + if (ssl_is_sm2_cert(x) && ssl_is_sm2_enc_usage(x)) { + return x; + } + } + return NULL; +} + +int ssl_get_sm2_cert_id(X509 *x, size_t *id) +{ + if (ssl_is_sm2_sign_usage(x) && !ssl_is_sm2_enc_usage(x)) { + *id = SSL_PKEY_SM2_SIGN; + return 1; + } else if (!ssl_is_sm2_sign_usage(x) && ssl_is_sm2_enc_usage(x)) { + *id = SSL_PKEY_SM2_ENC; + return 1; + } + return 0; +} +#endif \ No newline at end of file diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index a33cb9a..8135248 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -177,6 +177,13 @@ # define SSL_kECDHEPSK 0x00000080U # define SSL_kDHEPSK 0x00000100U +#ifndef OPENSSL_NO_TLCP +/* TLCP ECC*/ +# define SSL_kSM2ECC 0x00000800U +/* TLCP ECDHE */ +# define SSL_kSM2DHE 0x00001000U +#endif + /* all PSK */ # define SSL_PSK (SSL_kPSK | SSL_kRSAPSK | SSL_kECDHEPSK | SSL_kDHEPSK) @@ -203,9 +210,21 @@ # define SSL_aGOST12 0x00000080U /* Any appropriate signature auth (for TLS 1.3 ciphersuites) */ # define SSL_aANY 0x00000000U + +#ifndef OPENSSL_NO_TLCP +/* SM2 auth */ +# define SSL_aSM2 0x00000100U +#endif + +#ifndef OPENSSL_NO_TLCP +/* All bits requiring a certificate */ +#define SSL_aCERT \ + (SSL_aRSA | SSL_aDSS | SSL_aECDSA | SSL_aGOST01 | SSL_aGOST12 | SSL_aSM2) +#else /* All bits requiring a certificate */ #define SSL_aCERT \ (SSL_aRSA | SSL_aDSS | SSL_aECDSA | SSL_aGOST01 | SSL_aGOST12) +#endif /* Bits for algorithm_enc (symmetric encryption) */ # define SSL_DES 0x00000001U @@ -231,6 +250,10 @@ # define SSL_ARIA128GCM 0x00100000U # define SSL_ARIA256GCM 0x00200000U +#ifndef OPENSSL_NO_TLCP +# define SSL_SM4CBC 0x00800000U +#endif + # define SSL_AESGCM (SSL_AES128GCM | SSL_AES256GCM) # define SSL_AESCCM (SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8) # define SSL_AES (SSL_AES128|SSL_AES256|SSL_AESGCM|SSL_AESCCM) @@ -253,6 +276,10 @@ # define SSL_GOST89MAC12 0x00000100U # define SSL_GOST12_512 0x00000200U +#ifndef OPENSSL_NO_TLCP +# define SSL_SM3 0x00000400U +#endif + /* * When adding new digest in the ssl_ciph.c and increment SSL_MD_NUM_IDX make * sure to update this constant too @@ -270,8 +297,12 @@ # define SSL_MD_MD5_SHA1_IDX 9 # define SSL_MD_SHA224_IDX 10 # define SSL_MD_SHA512_IDX 11 +#ifndef OPENSSL_NO_TLCP +# define SSL_MD_SM3_IDX 12 +# define SSL_MAX_DIGEST 13 +#else # define SSL_MAX_DIGEST 12 - +#endif /* Bits for algorithm2 (handshake digests and other extra flags) */ /* Bits 0-7 are handshake MAC */ @@ -283,6 +314,9 @@ # define SSL_HANDSHAKE_MAC_GOST12_256 SSL_MD_GOST12_256_IDX # define SSL_HANDSHAKE_MAC_GOST12_512 SSL_MD_GOST12_512_IDX # define SSL_HANDSHAKE_MAC_DEFAULT SSL_HANDSHAKE_MAC_MD5_SHA1 +#ifndef OPENSSL_NO_TLCP +# define SSL_HANDSHAKE_MAC_SM3 SSL_MD_SM3_IDX +#endif /* Bits 8-15 bits are PRF */ # define TLS1_PRF_DGST_SHIFT 8 @@ -293,6 +327,9 @@ # define TLS1_PRF_GOST12_256 (SSL_MD_GOST12_256_IDX << TLS1_PRF_DGST_SHIFT) # define TLS1_PRF_GOST12_512 (SSL_MD_GOST12_512_IDX << TLS1_PRF_DGST_SHIFT) # define TLS1_PRF (SSL_MD_MD5_SHA1_IDX << TLS1_PRF_DGST_SHIFT) +#ifndef OPENSSL_NO_TLCP +# define TLS1_PRF_SM3 (SSL_MD_SM3_IDX << TLS1_PRF_DGST_SHIFT) +#endif /* * Stream MAC for GOST ciphersuites from cryptopro draft (currently this also @@ -318,6 +355,8 @@ /* Check if an SSL structure is using DTLS */ # define SSL_IS_DTLS(s) (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) +# define SSL_IS_TLCP(s) (s->version == TLCP_VERSION) + /* Check if we are using TLSv1.3 */ # define SSL_IS_TLS13(s) (!SSL_IS_DTLS(s) \ && (s)->method->version >= TLS1_3_VERSION \ @@ -383,7 +422,13 @@ # define SSL_PKEY_GOST12_512 6 # define SSL_PKEY_ED25519 7 # define SSL_PKEY_ED448 8 +#ifndef OPENSSL_NO_TLCP +# define SSL_PKEY_SM2_SIGN 9 +# define SSL_PKEY_SM2_ENC 10 +# define SSL_PKEY_NUM 11 +#else # define SSL_PKEY_NUM 9 +#endif /*- * SSL_kRSA <- RSA_ENC @@ -2027,6 +2072,9 @@ typedef enum downgrade_en { #define TLSEXT_SIGALG_ecdsa_secp521r1_sha512 0x0603 #define TLSEXT_SIGALG_ecdsa_sha224 0x0303 #define TLSEXT_SIGALG_ecdsa_sha1 0x0203 +#ifndef OPENSSL_NO_TLCP +#define TLSEXT_SIGALG_sm2dsa_sm3 0x0708 +#endif #define TLSEXT_SIGALG_rsa_pss_rsae_sha256 0x0804 #define TLSEXT_SIGALG_rsa_pss_rsae_sha384 0x0805 #define TLSEXT_SIGALG_rsa_pss_rsae_sha512 0x0806 @@ -2096,6 +2144,18 @@ __owur const SSL_METHOD *dtls_bad_ver_client_method(void); __owur const SSL_METHOD *dtlsv1_2_method(void); __owur const SSL_METHOD *dtlsv1_2_server_method(void); __owur const SSL_METHOD *dtlsv1_2_client_method(void); +# ifndef OPENSSL_NO_TLCP +__owur const SSL_METHOD *tlcp_method(void); +__owur const SSL_METHOD *tlcp_server_method(void); +__owur const SSL_METHOD *tlcp_client_method(void); + +/* TLCP helper functions */ +__owur int ssl_is_sm2_cert(X509 *x); +__owur int ssl_is_sm2_sign_usage(X509 *x); +__owur int ssl_is_sm2_enc_usage(X509 *x); +__owur X509 *ssl_get_sm2_enc_cert(SSL *s, STACK_OF(X509) *chain); +__owur int ssl_get_sm2_cert_id(X509 *x, size_t *id); +# endif extern const SSL3_ENC_METHOD TLSv1_enc_data; extern const SSL3_ENC_METHOD TLSv1_1_enc_data; @@ -2104,6 +2164,9 @@ extern const SSL3_ENC_METHOD TLSv1_3_enc_data; extern const SSL3_ENC_METHOD SSLv3_enc_data; extern const SSL3_ENC_METHOD DTLSv1_enc_data; extern const SSL3_ENC_METHOD DTLSv1_2_enc_data; +# ifndef OPENSSL_NO_TLCP +extern const SSL3_ENC_METHOD TLCP_enc_data; +# endif /* * Flags for SSL methods @@ -2331,6 +2394,7 @@ __owur int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, __owur EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm); __owur int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int genmaster); +__owur int tlcp_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey); __owur EVP_PKEY *ssl_dh_to_pkey(DH *dh); __owur unsigned int ssl_get_max_send_fragment(const SSL *ssl); __owur unsigned int ssl_get_split_send_fragment(const SSL *ssl); @@ -2502,6 +2566,9 @@ __owur int tls13_export_keying_material_early(SSL *s, unsigned char *out, __owur int tls1_alert_code(int code); __owur int tls13_alert_code(int code); __owur int ssl3_alert_code(int code); +# ifndef OPENSSL_NO_TLCP +__owur int tlcp_alert_code(int code); +# endif # ifndef OPENSSL_NO_EC __owur int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s); diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c index 6457c0c..5a495ec 100644 --- a/ssl/ssl_rsa.c +++ b/ssl/ssl_rsa.c @@ -19,6 +19,15 @@ static int ssl_set_cert(CERT *c, X509 *x509); static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); +#ifndef OPENSSL_NO_TLCP +#include <openssl/x509v3.h> + +static int ssl_set_sign_enc_pkey(CERT *c, EVP_PKEY *pkey, size_t id); +static int ssl_set_sign_enc_cert(CERT *c, X509 *x, size_t id); +static int ssl_load_pkey_file(SSL *ssl, SSL_CTX *ctx, const char *file, int type, EVP_PKEY **pkey); +static int ssl_load_cert_file(SSL *ssl, SSL_CTX *ctx, const char *file, int type, X509 **x); +#endif + #define SYNTHV1CONTEXT (SSL_EXT_TLS1_2_AND_BELOW_ONLY \ | SSL_EXT_CLIENT_HELLO \ | SSL_EXT_TLS1_2_SERVER_HELLO \ @@ -97,6 +106,99 @@ int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) return ret; } +#ifndef OPENSSL_NO_TLCP +static int ssl_load_cert_file(SSL *ssl, SSL_CTX *ctx, const char *file, int type, X509 **x) +{ + int j; + BIO *in; + int ret = 0; + *x = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + SSLerr(SSL_F_SSL_LOAD_CERT_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_LOAD_CERT_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + *x = d2i_X509_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + pem_password_cb *cb = (ssl != NULL) ? ssl->default_passwd_callback : + ctx->default_passwd_callback; + void *userdata = (ssl != NULL) ? ssl->default_passwd_callback_userdata : + ctx->default_passwd_callback_userdata; + *x = PEM_read_bio_X509(in, NULL, cb, userdata); + } else { + SSLerr(SSL_F_SSL_LOAD_CERT_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (*x == NULL) { + SSLerr(SSL_F_SSL_LOAD_CERT_FILE, j); + goto end; + } + ret = 1; +end: + BIO_free(in); + return ret; +} + +int SSL_use_gm_certificate(SSL *ssl, X509 *x, int usage) +{ + int rv; + if (x == NULL) { + SSLerr(SSL_F_SSL_USE_GM_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + rv = ssl_security_cert(ssl, NULL, x, 0, 1); + if (rv != 1) { + SSLerr(SSL_F_SSL_USE_GM_CERTIFICATE, rv); + return 0; + } + if (usage == SSL_USAGE_SIG) { + return ssl_set_sign_enc_cert(ssl->cert, x, SSL_PKEY_SM2_SIGN); + } else if (usage == SSL_USAGE_ENC) { + return ssl_set_sign_enc_cert(ssl->cert, x, SSL_PKEY_SM2_ENC); + } + SSLerr(SSL_F_SSL_USE_GM_CERTIFICATE, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; +} + +int SSL_use_gm_certificate_ASN1(SSL *ssl, const unsigned char *d, int len, int usage) +{ + X509 *x; + int ret; + + x = d2i_X509(NULL, &d, (long)len); + if (x == NULL) { + SSLerr(SSL_F_SSL_USE_GM_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); + return 0; + } + + ret = SSL_use_gm_certificate(ssl, x, usage); + X509_free(x); + return ret; +} + +int SSL_use_gm_certificate_file(SSL *ssl, const char *file, int type, int usage) +{ + int ret; + X509 *x = NULL; + ret = ssl_load_cert_file(ssl, NULL, file, type, &x); + if (ret == 1) { + ret = SSL_use_gm_certificate(ssl, x, usage); + } + X509_free(x); + return ret; +} +#endif + #ifndef OPENSSL_NO_RSA int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) { @@ -162,6 +264,50 @@ static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) return 1; } +#ifndef OPENSSL_NO_TLCP +int ssl_set_sign_enc_pkey(CERT *c, EVP_PKEY *pkey, size_t id) +{ + if (id != SSL_PKEY_SM2_SIGN && id != SSL_PKEY_SM2_ENC) { + SSLerr(SSL_F_SSL_SET_SIGN_ENC_PKEY, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + if (EVP_PKEY_is_sm2(pkey) == 0) { + SSLerr(SSL_F_SSL_SET_SIGN_ENC_PKEY, SSL_R_UNKNOWN_PKEY_TYPE); + return 0; + } + + if (c->pkeys[id].x509 != NULL) { + EVP_PKEY *pktmp; + pktmp = X509_get0_pubkey(c->pkeys[id].x509); + if (pktmp == NULL) { + SSLerr(SSL_F_SSL_SET_SIGN_ENC_PKEY, ERR_R_MALLOC_FAILURE); + return 0; + } + /* + * The return code from EVP_PKEY_copy_parameters is deliberately + * ignored. Some EVP_PKEY types cannot do this. + */ + EVP_PKEY_copy_parameters(pktmp, pkey); + ERR_clear_error(); + + if (!X509_check_private_key(c->pkeys[id].x509, pkey)) { + X509_free(c->pkeys[id].x509); + c->pkeys[id].x509 = NULL; + return 0; + } + } + + EVP_PKEY_free(c->pkeys[id].privatekey); + EVP_PKEY_up_ref(pkey); + c->pkeys[id].privatekey = pkey; + if (id != SSL_PKEY_SM2_ENC) { + c->key = &(c->pkeys[id]); + } + return 1; +} +#endif + #ifndef OPENSSL_NO_RSA int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) { @@ -228,6 +374,17 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); return 0; } +#ifndef OPENSSL_NO_TLCP + if (EVP_PKEY_is_sm2(pkey)) { + if (X509_check_private_key(ssl->cert->pkeys[SSL_PKEY_SM2_SIGN].x509, pkey)) { + return ssl_set_sign_enc_pkey(ssl->cert, pkey, SSL_PKEY_SM2_SIGN); + } else if (X509_check_private_key(ssl->cert->pkeys[SSL_PKEY_SM2_ENC].x509, pkey)) { + return ssl_set_sign_enc_pkey(ssl->cert, pkey, SSL_PKEY_SM2_ENC); + } + SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } +#endif ret = ssl_set_pkey(ssl->cert, pkey); return ret; } @@ -289,6 +446,94 @@ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, return ret; } +#ifndef OPENSSL_NO_TLCP +static int ssl_load_pkey_file(SSL *ssl, SSL_CTX *ctx, const char *file, int type, EVP_PKEY **pkey) +{ + int j, ret = 0; + BIO *in; + *pkey = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + SSLerr(SSL_F_SSL_LOAD_PKEY_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_LOAD_PKEY_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + pem_password_cb *cb = (ssl != NULL) ? ssl->default_passwd_callback : + ctx->default_passwd_callback; + void *userdata = (ssl != NULL) ? ssl->default_passwd_callback_userdata : + ctx->default_passwd_callback_userdata; + *pkey = PEM_read_bio_PrivateKey(in, NULL, cb, userdata); + } else if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + *pkey = d2i_PrivateKey_bio(in, NULL); + } else { + SSLerr(SSL_F_SSL_LOAD_PKEY_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (*pkey == NULL) { + SSLerr(SSL_F_SSL_LOAD_PKEY_FILE, j); + goto end; + } + ret = 1; +end: + BIO_free(in); + return ret; +} + +int SSL_use_gm_PrivateKey(SSL *ssl, EVP_PKEY *pkey, int usage) +{ + if (pkey == NULL) { + SSLerr(SSL_F_SSL_USE_GM_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (usage == SSL_USAGE_SIG) { + return ssl_set_sign_enc_pkey(ssl->cert, pkey, SSL_PKEY_SM2_SIGN); + } else if (usage == SSL_USAGE_ENC) { + return ssl_set_sign_enc_pkey(ssl->cert, pkey, SSL_PKEY_SM2_ENC); + } + SSLerr(SSL_F_SSL_USE_GM_PRIVATEKEY, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; +} + +int SSL_use_gm_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, + long len, int usage) +{ + int ret; + const unsigned char *p; + EVP_PKEY *pkey; + + p = d; + if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { + SSLerr(SSL_F_SSL_USE_GM_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + return 0; + } + + ret = SSL_use_gm_PrivateKey(ssl, pkey, usage); + EVP_PKEY_free(pkey); + return ret; +} + +int SSL_use_gm_PrivateKey_file(SSL *ssl, const char *file, int type, int usage) +{ + int ret; + EVP_PKEY *pkey = NULL; + + ret = ssl_load_pkey_file(ssl, NULL, file, type, &pkey); + if (ret == 1) { + ret = SSL_use_gm_PrivateKey(ssl, pkey, usage); + } + EVP_PKEY_free(pkey); + return ret; +} +#endif + int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) { int rv; @@ -319,6 +564,12 @@ static int ssl_set_cert(CERT *c, X509 *x) SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return 0; } +#ifndef OPENSSL_NO_TLCP + if (i == SSL_PKEY_SM2_SIGN && !ssl_get_sm2_cert_id(x, &i)) { + SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return 0; + } +#endif #ifndef OPENSSL_NO_EC if (i == SSL_PKEY_ECC && !EC_KEY_can_sign(EVP_PKEY_get0_EC_KEY(pkey))) { SSLerr(SSL_F_SSL_SET_CERT, SSL_R_ECC_CERT_NOT_FOR_SIGNING); @@ -349,7 +600,13 @@ static int ssl_set_cert(CERT *c, X509 *x) X509_free(c->pkeys[i].x509); X509_up_ref(x); c->pkeys[i].x509 = x; +#ifndef OPENSSL_NO_TLCP + if (i != SSL_PKEY_SM2_ENC) { + c->key = &(c->pkeys[i]); + } +#else c->key = &(c->pkeys[i]); +#endif return 1; } @@ -411,6 +668,109 @@ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) return ret; } +#ifndef OPENSSL_NO_TLCP +static int ssl_set_sign_enc_cert(CERT *c, X509 *x, size_t id) +{ + EVP_PKEY *pkey; + + pkey = X509_get0_pubkey(x); + if (pkey == NULL) { + SSLerr(SSL_F_SSL_SET_SIGN_ENC_CERT, SSL_R_X509_LIB); + return 0; + } + + if (ssl_is_sm2_cert(x) == 0 || + (id == SSL_PKEY_SM2_ENC && !ssl_is_sm2_enc_usage(x)) || + (id == SSL_PKEY_SM2_SIGN && !ssl_is_sm2_sign_usage(x))) { + SSLerr(SSL_F_SSL_SET_SIGN_ENC_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return 0; + } + + if (id == SSL_PKEY_SM2_SIGN && !EC_KEY_can_sign(EVP_PKEY_get0_EC_KEY(pkey))) { + SSLerr(SSL_F_SSL_SET_SIGN_ENC_CERT, SSL_R_ECC_CERT_NOT_FOR_SIGNING); + return 0; + } + + if (c->pkeys[id].privatekey != NULL) { + /* + * The return code from EVP_PKEY_copy_parameters is deliberately + * ignored. Some EVP_PKEY types cannot do this. + */ + EVP_PKEY_copy_parameters(pkey, c->pkeys[id].privatekey); + ERR_clear_error(); + + if (!X509_check_private_key(x, c->pkeys[id].privatekey)) { + /* + * don't fail for a cert/key mismatch, just free current private + * key (when switching to a different cert & key, first this + * function should be used, then ssl_set_pkey + */ + EVP_PKEY_free(c->pkeys[id].privatekey); + c->pkeys[id].privatekey = NULL; + /* clear error queue */ + ERR_clear_error(); + } + } + + X509_free(c->pkeys[id].x509); + X509_up_ref(x); + c->pkeys[id].x509 = x; + if (id != SSL_PKEY_SM2_ENC) { + c->key = &(c->pkeys[id]); + } + return 1; +} + +int SSL_CTX_use_gm_certificate(SSL_CTX *ctx, X509 *x, int usage) +{ + int rv; + if (x == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_GM_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + rv = ssl_security_cert(NULL, ctx, x, 0, 1); + if (rv != 1) { + SSLerr(SSL_F_SSL_CTX_USE_GM_CERTIFICATE, rv); + return 0; + } + if (usage == SSL_USAGE_SIG) { + return ssl_set_sign_enc_cert(ctx->cert, x, SSL_PKEY_SM2_SIGN); + } else if (usage == SSL_USAGE_ENC) { + return ssl_set_sign_enc_cert(ctx->cert, x, SSL_PKEY_SM2_ENC); + } + SSLerr(SSL_F_SSL_CTX_USE_GM_CERTIFICATE, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; +} + +int SSL_CTX_use_gm_certificate_file(SSL_CTX *ctx, const char *file, int type, int usage) +{ + int ret; + X509 *x = NULL; + ret = ssl_load_cert_file(NULL, ctx, file, type, &x); + if (ret == 1) { + ret = SSL_CTX_use_gm_certificate(ctx, x, usage); + } + X509_free(x); + return ret; +} + +int SSL_CTX_use_gm_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d, int usage) +{ + X509 *x; + int ret; + + x = d2i_X509(NULL, &d, (long)len); + if (x == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_GM_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); + return 0; + } + + ret = SSL_CTX_use_gm_certificate(ctx, x, usage); + X509_free(x); + return ret; +} +#endif + #ifndef OPENSSL_NO_RSA int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) { @@ -502,6 +862,17 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); return 0; } +#ifndef OPENSSL_NO_TLCP + if (EVP_PKEY_is_sm2(pkey)) { + if (X509_check_private_key(ctx->cert->pkeys[SSL_PKEY_SM2_SIGN].x509, pkey)) { + return ssl_set_sign_enc_pkey(ctx->cert, pkey, SSL_PKEY_SM2_SIGN); + } else if (X509_check_private_key(ctx->cert->pkeys[SSL_PKEY_SM2_ENC].x509, pkey)) { + return ssl_set_sign_enc_pkey(ctx->cert, pkey, SSL_PKEY_SM2_ENC); + } + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } +#endif return ssl_set_pkey(ctx->cert, pkey); } @@ -562,6 +933,54 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, return ret; } +#ifndef OPENSSL_NO_TLCP +int SSL_CTX_use_gm_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey, int usage) +{ + if (pkey == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_GM_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (usage == SSL_USAGE_SIG) { + return ssl_set_sign_enc_pkey(ctx->cert, pkey, SSL_PKEY_SM2_SIGN); + } else if (usage == SSL_USAGE_ENC) { + return ssl_set_sign_enc_pkey(ctx->cert, pkey, SSL_PKEY_SM2_ENC); + } + SSLerr(SSL_F_SSL_CTX_USE_GM_PRIVATEKEY, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; +} + +int SSL_CTX_use_gm_PrivateKey_file(SSL_CTX *ctx, const char *file, int type, int usage) +{ + int ret; + EVP_PKEY *pkey = NULL; + + ret = ssl_load_pkey_file(NULL, ctx, file, type, &pkey); + if (ret == 1) { + ret = SSL_CTX_use_gm_PrivateKey(ctx, pkey, usage); + } + EVP_PKEY_free(pkey); + return ret; +} + +int SSL_CTX_use_gm_PrivateKey_ASN1(int type, SSL_CTX *ctx, + const unsigned char *d, long len, int usage) +{ + int ret; + const unsigned char *p; + EVP_PKEY *pkey; + + p = d; + if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_GM_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + return 0; + } + + ret = SSL_CTX_use_gm_PrivateKey(ctx, pkey, usage); + EVP_PKEY_free(pkey); + return ret; +} +#endif + /* * Read a file that contains our certificate in "PEM" format, possibly * followed by a sequence of CA certificates that should be sent to the peer @@ -1073,6 +1492,12 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); goto out; } +#ifndef OPENSSL_NO_TLCP + if (i == SSL_PKEY_SM2_SIGN && !ssl_get_sm2_cert_id(x509, &i)) { + SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return 0; + } +#endif if (!override && (c->pkeys[i].x509 != NULL || c->pkeys[i].privatekey != NULL @@ -1101,7 +1526,13 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr EVP_PKEY_up_ref(privatekey); c->pkeys[i].privatekey = privatekey; +#ifndef OPENSSL_NO_TLCP + if (i != SSL_PKEY_SM2_ENC) { + c->key = &(c->pkeys[i]); + } +#else c->key = &(c->pkeys[i]); +#endif ret = 1; out: @@ -1120,3 +1551,113 @@ int SSL_CTX_use_cert_and_key(SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, { return ssl_set_cert_and_key(NULL, ctx, x509, privatekey, chain, override); } + +#ifndef OPENSSL_NO_TLCP +static int ssl_set_gm_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, + STACK_OF(X509) *chain, int override, int usage) +{ + int ret = 0; + size_t id; + int j; + int rv; + CERT *c = ssl != NULL ? ssl->cert : ctx->cert; + STACK_OF(X509) *dup_chain = NULL; + EVP_PKEY *pubkey = NULL; + + /* Do all security checks before anything else */ + rv = ssl_security_cert(ssl, ctx, x509, 0, 1); + if (rv != 1) { + SSLerr(SSL_F_SSL_SET_GM_CERT_AND_KEY, rv); + goto out; + } + for (j = 0; j < sk_X509_num(chain); j++) { + rv = ssl_security_cert(ssl, ctx, sk_X509_value(chain, j), 0, 0); + if (rv != 1) { + SSLerr(SSL_F_SSL_SET_GM_CERT_AND_KEY, rv); + goto out; + } + } + + pubkey = X509_get_pubkey(x509); /* bumps reference */ + if (pubkey == NULL) + goto out; + if (privatekey == NULL) { + privatekey = pubkey; + } else { + /* For RSA, which has no parameters, missing returns 0 */ + if (EVP_PKEY_missing_parameters(privatekey)) { + if (EVP_PKEY_missing_parameters(pubkey)) { + /* nobody has parameters? - error */ + SSLerr(SSL_F_SSL_SET_GM_CERT_AND_KEY, SSL_R_MISSING_PARAMETERS); + goto out; + } else { + /* copy to privatekey from pubkey */ + EVP_PKEY_copy_parameters(privatekey, pubkey); + } + } else if (EVP_PKEY_missing_parameters(pubkey)) { + /* copy to pubkey from privatekey */ + EVP_PKEY_copy_parameters(pubkey, privatekey); + } /* else both have parameters */ + + /* check that key <-> cert match */ + if (EVP_PKEY_cmp(pubkey, privatekey) != 1) { + SSLerr(SSL_F_SSL_SET_GM_CERT_AND_KEY, SSL_R_PRIVATE_KEY_MISMATCH); + goto out; + } + } + if (usage == SSL_USAGE_SIG) { + id = SSL_PKEY_SM2_SIGN; + } else if (usage == SSL_USAGE_ENC) { + id = SSL_PKEY_SM2_ENC; + } else { + SSLerr(SSL_F_SSL_SET_GM_CERT_AND_KEY, ERR_R_PASSED_INVALID_ARGUMENT); + goto out; + } + + if (!override && (c->pkeys[id].x509 != NULL + || c->pkeys[id].privatekey != NULL + || c->pkeys[id].chain != NULL)) { + /* No override, and something already there */ + SSLerr(SSL_F_SSL_SET_GM_CERT_AND_KEY, SSL_R_NOT_REPLACING_CERTIFICATE); + goto out; + } + + if (chain != NULL) { + dup_chain = X509_chain_up_ref(chain); + if (dup_chain == NULL) { + SSLerr(SSL_F_SSL_SET_GM_CERT_AND_KEY, ERR_R_MALLOC_FAILURE); + goto out; + } + } + + sk_X509_pop_free(c->pkeys[id].chain, X509_free); + c->pkeys[id].chain = dup_chain; + + X509_free(c->pkeys[id].x509); + X509_up_ref(x509); + c->pkeys[id].x509 = x509; + + EVP_PKEY_free(c->pkeys[id].privatekey); + EVP_PKEY_up_ref(privatekey); + c->pkeys[id].privatekey = privatekey; + if (id != SSL_PKEY_SM2_ENC) { + c->key = &(c->pkeys[id]); + } + ret = 1; + out: + EVP_PKEY_free(pubkey); + return ret; +} + +int SSL_use_gm_cert_and_key(SSL *ssl, X509 *x509, EVP_PKEY *privatekey, + STACK_OF(X509) *chain, int override, int usage) +{ + return ssl_set_gm_cert_and_key(ssl, NULL, x509, privatekey, chain, override, usage); +} + +int SSL_CTX_use_gm_cert_and_key(SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, + STACK_OF(X509) *chain, int override, int usage) +{ + return ssl_set_gm_cert_and_key(NULL, ctx, x509, privatekey, chain, override, usage); +} +#endif \ No newline at end of file diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index cda6b7c..fb354e6 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -283,6 +283,9 @@ int ssl_generate_session_id(SSL *s, SSL_SESSION *ss) GEN_SESSION_CB cb = def_generate_session_id; switch (s->version) { +#ifndef OPENSSL_NO_TLCP + case TLCP_VERSION: +#endif case SSL3_VERSION: case TLS1_VERSION: case TLS1_1_VERSION: diff --git a/ssl/ssl_stat.c b/ssl/ssl_stat.c index ca51c03..1750bdb 100644 --- a/ssl/ssl_stat.c +++ b/ssl/ssl_stat.c @@ -312,6 +312,20 @@ const char *SSL_alert_desc_string(int value) return "BH"; case TLS1_AD_UNKNOWN_PSK_IDENTITY: return "UP"; +#ifndef OPENSSL_NO_TLCP + case TLCP_AD_UNSUPPORTED_SITE2SITE: + return "U2"; + case TLCP_AD_NO_AREA: + return "NA"; + case TLCP_AD_UNSUPPORTED_AREATYPE: + return "AT"; + case TLCP_AD_BAD_IBCPARAM: + return "BI"; + case TLCP_AD_UNSUPPORTED_IBCPARAM: + return "UI"; + case TLCP_AD_IDENTITY_NEED: + return "IN"; +#endif default: return "UK"; } @@ -382,6 +396,20 @@ const char *SSL_alert_desc_string_long(int value) return "unknown PSK identity"; case TLS1_AD_NO_APPLICATION_PROTOCOL: return "no application protocol"; +#ifndef OPENSSL_NO_TLCP + case TLCP_AD_UNSUPPORTED_SITE2SITE: + return "unsupported site2site"; + case TLCP_AD_NO_AREA: + return "no area"; + case TLCP_AD_UNSUPPORTED_AREATYPE: + return "unsupported areatype"; + case TLCP_AD_BAD_IBCPARAM: + return "bad ibcparam"; + case TLCP_AD_UNSUPPORTED_IBCPARAM: + return "unsupported ibcparam"; + case TLCP_AD_IDENTITY_NEED: + return "identity need"; +#endif default: return "unknown"; } diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 0f39275..a03b6cd 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -1056,7 +1056,11 @@ static int final_ec_pt_formats(SSL *s, unsigned int context, int sent) && s->ext.ecpointformats_len > 0 && s->ext.peer_ecpointformats != NULL && s->ext.peer_ecpointformats_len > 0 - && ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA))) { + && ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA) +#ifndef OPENSSL_NO_TLCP + || (alg_k & SSL_kSM2DHE) || (alg_a & SSL_aSM2) +#endif + )) { /* we are using an ECC cipher */ size_t i; unsigned char *list = s->ext.peer_ecpointformats; diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 9d38ac2..23ca93e 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -132,6 +132,9 @@ static int use_ecc(SSL *s) alg_a = c->algorithm_auth; if ((alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) || (alg_a & SSL_aECDSA) +#ifndef OPENSSL_NO_TLCP + || (alg_k & SSL_kSM2DHE) || (alg_a & SSL_aSM2) +#endif || c->min_tls >= TLS1_3_VERSION) { ret = 1; break; diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 04f64f8..7c5e3bf 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -1386,7 +1386,11 @@ EXT_RETURN tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, { unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; - int using_ecc = ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA)) + int using_ecc = ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA) +#ifndef OPENSSL_NO_TLCP + || (alg_k & SSL_kSM2DHE) || (alg_a & SSL_aSM2) +#endif + ) && (s->ext.peer_ecpointformats != NULL); const unsigned char *plist; size_t plistlen; diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c index 20f5bd5..d1fc2cc 100644 --- a/ssl/statem/statem.c +++ b/ssl/statem/statem.c @@ -361,7 +361,11 @@ static int state_machine(SSL *s, int server) goto end; } } else { +#ifndef OPENSSL_NO_TLCP + if ((s->version >> 8) != SSL3_VERSION_MAJOR && s->version != TLCP_VERSION) { +#else if ((s->version >> 8) != SSL3_VERSION_MAJOR) { +#endif SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, ERR_R_INTERNAL_ERROR); goto end; diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index d1a3969..052a733 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -61,6 +61,10 @@ static int key_exchange_expected(SSL *s) { long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; +#ifndef OPENSSL_NO_TLCP + if (SSL_IS_TLCP(s)) + return 1; +#endif /* * Can't skip server key exchange if this is an ephemeral * ciphersuite or for SRP @@ -2252,8 +2256,277 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) #endif } +#ifndef OPENSSL_NO_TLCP +static int tlcp_process_ske_sm2ecc(SSL *s, PACKET *pkt) +{ + EVP_MD_CTX *md_ctx = NULL; + EVP_PKEY_CTX *pctx = NULL; + unsigned char *encbuf = NULL; + unsigned char *tbs = NULL; + + PACKET signature; + X509 *peer_sign_cert; + X509 *peer_enc_cert; + EVP_PKEY *peer_sign_pkey; + const EVP_MD *md; + unsigned char *tmp; + int rv, ebuflen, tbslen; + + rv = 0; + peer_sign_cert = s->session->peer; + peer_enc_cert = ssl_get_sm2_enc_cert(s, s->session->peer_chain); + if (peer_sign_cert == NULL || peer_enc_cert == NULL + || !ssl_is_sm2_cert(peer_sign_cert) + || !ssl_is_sm2_sign_usage(peer_sign_cert)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_SKE_SM2ECC, ERR_R_INTERNAL_ERROR); + goto err; + } + + peer_sign_pkey = X509_get0_pubkey(peer_sign_cert); + if (!EVP_PKEY_set_alias_type(peer_sign_pkey, EVP_PKEY_SM2)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, + ERR_R_INTERNAL_ERROR); + goto err; + } + /* Get the signature algorithm according to the peer sign key */ + if (SSL_USE_SIGALGS(s)) { + unsigned int sigalg; + + if (!PACKET_get_net_2(pkt, &sigalg)) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, + SSL_R_LENGTH_TOO_SHORT); + goto err; + } + if (tls12_check_peer_sigalg(s, sigalg, peer_sign_pkey) <=0) { + /* SSLfatal() already called */ + goto err; + } + } else if (!tls1_set_peer_legacy_sigalg(s, peer_sign_pkey)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, + ERR_R_INTERNAL_ERROR); + goto err; + } + if (!tls1_lookup_md(s->s3->tmp.peer_sigalg, &md) + || EVP_PKEY_size(peer_sign_pkey) < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!PACKET_get_length_prefixed_2(pkt, &signature) + || PACKET_remaining(pkt) != 0 + || PACKET_remaining(&signature) > EVP_PKEY_size(peer_sign_pkey)) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, + SSL_R_LENGTH_MISMATCH); + goto err; + } + + ebuflen = i2d_X509(peer_enc_cert, NULL); + if (ebuflen < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, + ERR_R_BUF_LIB); + goto err; + } + + md_ctx = EVP_MD_CTX_new(); + encbuf = OPENSSL_malloc(ebuflen + 3); + if (md_ctx == NULL || encbuf == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, + ERR_R_MALLOC_FAILURE); + goto err; + } + /* Encode the DER encoding of an X509 structure, reserve 3 bytes for length */ + tmp = encbuf; + l2n3(ebuflen, tmp); + ebuflen = i2d_X509(peer_enc_cert, &tmp); + if (ebuflen < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, + ERR_R_BUF_LIB); + goto err; + } + ebuflen += 3; + + if (EVP_DigestVerifyInit(md_ctx, &pctx, md, NULL, peer_sign_pkey) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, + ERR_R_EVP_LIB); + goto err; + } + + tbslen = construct_key_exchange_tbs(s, &tbs, encbuf, ebuflen); + if (tbslen == 0) { + goto err; + } + + rv = EVP_DigestVerify(md_ctx, PACKET_data(&signature), + PACKET_remaining(&signature), tbs, tbslen); + if (rv <= 0) { + SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, + SSL_R_BAD_SIGNATURE); + } +err: + OPENSSL_free(encbuf); + OPENSSL_free(tbs); + EVP_MD_CTX_free(md_ctx); + return rv; +} + +static int tlcp_process_ske_sm2dhe(SSL *s, PACKET *pkt) +{ + unsigned char *ecparams; + int ecparams_len; + PACKET pt_encoded; + PACKET signature; + EVP_PKEY *pkey; + EVP_PKEY_CTX *pctx; + EVP_PKEY_CTX *verify_ctx; + EVP_MD_CTX *md_ctx = NULL; + char *id = "1234567812345678"; + int ret = 0; + int max_sig_len; + + if(!PACKET_get_bytes(pkt, (const unsigned char**)&ecparams, 3) + || !PACKET_get_length_prefixed_1(pkt, &pt_encoded) + || !PACKET_get_length_prefixed_2(pkt, &signature) + ) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_SKE_SM2DHE, SSL_R_LENGTH_TOO_SHORT); + return 0; + } + + if (PACKET_remaining(pkt) != 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_SKE_SM2DHE, SSL_R_LENGTH_TOO_LONG); + return 0; + } + + // generate tmp pkey s->s3->peer_tmp with peer pub key + if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (EVP_PKEY_paramgen_init(pctx) <= 0 + || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_sm2) <= 0 + || EVP_PKEY_paramgen(pctx, &s->s3->peer_tmp) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_EVP_LIB); + goto end; + } + + if (s->s3->peer_tmp == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_INTERNAL_ERROR); + goto end; + } + + if (!EVP_PKEY_set1_tls_encodedpoint(s->s3->peer_tmp, + PACKET_data(&pt_encoded), PACKET_remaining(&pt_encoded))) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_SKE_SM2DHE, SSL_R_BAD_ECPOINT); + goto end; + } + + // verify the msg using peer sign cert's pubkey + if ((pkey = X509_get0_pubkey(s->session->peer)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_INTERNAL_ERROR); + goto end; + } + + max_sig_len = EVP_PKEY_size(pkey); + if (PACKET_remaining(&signature) > max_sig_len) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_SKE_SM2DHE, SSL_R_LENGTH_TOO_LONG); + goto end; + } + + if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_EVP_LIB); + goto end; + } + + if ((md_ctx = EVP_MD_CTX_new()) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_MALLOC_FAILURE); + goto end; + } + + if (EVP_DigestVerifyInit(md_ctx, &verify_ctx, EVP_sm3(), NULL, pkey) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_EVP_LIB); + goto end; + } + + if (EVP_PKEY_CTX_set1_id(verify_ctx, id, strlen(id)) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_EVP_LIB); + goto end; + } + + ecparams_len = PACKET_data(&pt_encoded) + PACKET_remaining(&pt_encoded) - ecparams; + if (EVP_DigestVerifyUpdate(md_ctx, s->s3->client_random, SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestVerifyUpdate(md_ctx, s->s3->server_random, SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestVerifyUpdate(md_ctx, ecparams, ecparams_len) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_EVP_LIB); + goto end; + } + + if (EVP_DigestVerifyFinal(md_ctx, + PACKET_data(&signature), PACKET_remaining(&signature)) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_SKE_SM2DHE, SSL_R_BAD_SIGNATURE); + goto end; + } + + ret = 1; + +end: + EVP_PKEY_CTX_free(pctx); + EVP_MD_CTX_free(md_ctx); + + return ret; +} + +static MSG_PROCESS_RETURN tlcp_process_key_exchange(SSL *s, PACKET *pkt) +{ + unsigned long alg_k; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + if (alg_k & SSL_kSM2ECC) { + if (!tlcp_process_ske_sm2ecc(s, pkt)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + } else if (alg_k & SSL_kSM2DHE) { + if (!tlcp_process_ske_sm2dhe(s, pkt)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + } else { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + + return MSG_PROCESS_CONTINUE_READING; +err: + return MSG_PROCESS_ERROR; +} +#endif + MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) { +#ifndef OPENSSL_NO_TLCP + if (SSL_IS_TLCP(s)) + return tlcp_process_key_exchange(s, pkt); +#endif long alg_k; EVP_PKEY *pkey = NULL; EVP_MD_CTX *md_ctx = NULL; @@ -3315,8 +3588,169 @@ static int tls_construct_cke_srp(SSL *s, WPACKET *pkt) #endif } +#ifndef OPENSSL_NO_TLCP +static int tlcp_construct_cke_sm2ecc(SSL *s, WPACKET *pkt) +{ + unsigned char *encdata = NULL; + EVP_PKEY_CTX *pctx = NULL; + unsigned char *pms = NULL; + size_t pmslen = 0; + + X509 *peer_enc_cert; + EVP_PKEY *peer_enc_pkey; + size_t enclen; + + peer_enc_cert = ssl_get_sm2_enc_cert(s, s->session->peer_chain); + peer_enc_pkey = X509_get0_pubkey(peer_enc_cert); + if (peer_enc_cert == NULL || peer_enc_pkey == NULL + || !EVP_PKEY_set_alias_type(peer_enc_pkey, EVP_PKEY_SM2)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, ERR_R_INTERNAL_ERROR); + goto err; + } + + pmslen = SSL_MAX_MASTER_KEY_LENGTH; + pms = OPENSSL_malloc(pmslen); + if (pms == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, + ERR_R_MALLOC_FAILURE); + goto err; + } + + pms[0] = s->client_version >> 8; + pms[1] = s->client_version & 0xff; + if (RAND_bytes(pms + 2, (int)(pmslen - 2)) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!WPACKET_start_sub_packet_u16(pkt)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, + ERR_R_INTERNAL_ERROR); + goto err; + } + /* Encrypt premaster secret { client_version, random[46] }*/ + pctx = EVP_PKEY_CTX_new(peer_enc_pkey, NULL); + if (pctx == NULL || EVP_PKEY_encrypt_init(pctx) <= 0 + || EVP_PKEY_encrypt(pctx, NULL, &enclen, pms, pmslen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, + ERR_R_EVP_LIB); + goto err; + } + if (!WPACKET_reserve_bytes(pkt, enclen, &encdata) + || EVP_PKEY_encrypt(pctx, encdata, &enclen, pms, pmslen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, + ERR_R_EVP_LIB); + goto err; + } + pkt->written += enclen; + pkt->curr += enclen; + EVP_PKEY_CTX_free(pctx); + pctx = NULL; + + if (!WPACKET_close(pkt)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, + ERR_R_INTERNAL_ERROR); + goto err; + } + + s->s3->tmp.pms = pms; + s->s3->tmp.pmslen = pmslen; + + return 1; +err: + OPENSSL_clear_free(pms, pmslen); + EVP_PKEY_CTX_free(pctx); + return 0; +} + +static int tlcp_construct_cke_sm2dhe(SSL *s, WPACKET *pkt) +{ + EVP_PKEY *skey, *ckey; + unsigned char * pt_encoded = NULL; + int pt_encoded_len; + int ret = 0; + + if ((skey = s->s3->peer_tmp) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (!WPACKET_put_bytes_u8(pkt, NAMED_CURVE_TYPE) + || !WPACKET_put_bytes_u8(pkt, 0) + || !WPACKET_put_bytes_u8(pkt, 41)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE, ERR_R_INTERNAL_ERROR); + return 0; + } + + if ((ckey = ssl_generate_pkey(skey)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE, ERR_R_INTERNAL_ERROR); + return 0; + } + + if ((pt_encoded_len = EVP_PKEY_get1_tls_encodedpoint(ckey, &pt_encoded)) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE, ERR_R_EC_LIB); + goto end; + } + + if (!WPACKET_sub_memcpy_u8(pkt, pt_encoded, pt_encoded_len)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE, ERR_R_INTERNAL_ERROR); + goto end; + } + + if (!tlcp_derive(s, ckey, skey)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE, ERR_R_INTERNAL_ERROR); + goto end; + } + + ret = 1; + +end: + EVP_PKEY_free(ckey); + if (pt_encoded) { + OPENSSL_free(pt_encoded); + } + + return ret; +} + +static int tlcp_construct_client_key_exchange(SSL *s, WPACKET *pkt) +{ + unsigned long alg_k; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + if (alg_k & SSL_kSM2ECC) { + if (!tlcp_construct_cke_sm2ecc(s, pkt)) + goto err; + } else if (alg_k & SSL_kSM2DHE) { + if (!tlcp_construct_cke_sm2dhe(s, pkt)) + goto err; + } else { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + + return 1; +err: + return 0; +} +#endif + int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt) { +#ifndef OPENSSL_NO_TLCP + if (SSL_IS_TLCP(s)) + return tlcp_construct_client_key_exchange(s, pkt); +#endif unsigned long alg_k; alg_k = s->s3->tmp.new_cipher->algorithm_mkey; diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 695caab..777a474 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -227,6 +227,29 @@ static int get_cert_verify_tbs_data(SSL *s, unsigned char *tls13tbs, return 1; } +#ifndef OPENSSL_NO_TLCP +static int get_tbs_hash_data(void *hdata, size_t hdatalen, unsigned char *out, size_t *outlen) +{ + EVP_MD_CTX *md_ctx; + int rv = 0; + + md_ctx = EVP_MD_CTX_new(); + if (md_ctx == NULL) + goto err; + + // TLCP is only used SM3 + if (!EVP_DigestInit(md_ctx, EVP_sm3()) + || !EVP_DigestUpdate(md_ctx, (const void *)hdata, hdatalen) + || !EVP_DigestFinal(md_ctx, out, (unsigned int *)outlen)) { + goto err; + } + rv = 1; +err: + EVP_MD_CTX_free(md_ctx); + return rv; +} +#endif + int tls_construct_cert_verify(SSL *s, WPACKET *pkt) { EVP_PKEY *pkey = NULL; @@ -238,6 +261,9 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) unsigned char *sig = NULL; unsigned char tls13tbs[TLS13_TBS_PREAMBLE_SIZE + EVP_MAX_MD_SIZE]; const SIGALG_LOOKUP *lu = s->s3->tmp.sigalg; +#ifndef OPENSSL_NO_TLCP + unsigned char out[EVP_MAX_MD_SIZE] = {0}; +#endif if (lu == NULL || s->s3->tmp.cert == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, @@ -251,6 +277,15 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) ERR_R_INTERNAL_ERROR); goto err; } +#ifndef OPENSSL_NO_TLCP + if (SSL_IS_TLCP(s) && EVP_PKEY_is_sm2(pkey)) { + if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, + ERR_R_INTERNAL_ERROR); + goto err; + } + } +#endif mctx = EVP_MD_CTX_new(); if (mctx == NULL) { @@ -264,7 +299,17 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) /* SSLfatal() already called */ goto err; } - +#ifndef OPENSSL_NO_TLCP + if (SSL_IS_TLCP(s)) { + if (!get_tbs_hash_data(hdata, hdatalen, out, &hdatalen)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, + ERR_R_INTERNAL_ERROR); + goto err; + } + /* Use new hash data for sign */ + hdata = out; + } +#endif if (SSL_USE_SIGALGS(s) && !WPACKET_put_bytes_u16(pkt, lu->sigalg)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_INTERNAL_ERROR); @@ -359,6 +404,9 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) unsigned char tls13tbs[TLS13_TBS_PREAMBLE_SIZE + EVP_MAX_MD_SIZE]; EVP_MD_CTX *mctx = EVP_MD_CTX_new(); EVP_PKEY_CTX *pctx = NULL; +#ifndef OPENSSL_NO_TLCP + unsigned char out[EVP_MAX_MD_SIZE] = {0}; +#endif if (mctx == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, @@ -373,6 +421,15 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) ERR_R_INTERNAL_ERROR); goto err; } +#ifndef OPENSSL_NO_TLCP + if (SSL_IS_TLCP(s) && EVP_PKEY_is_sm2(pkey)) { + if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, + ERR_R_INTERNAL_ERROR); + goto err; + } + } +#endif if (ssl_cert_lookup_by_pkey(pkey, NULL) == NULL) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_CERT_VERIFY, @@ -448,6 +505,17 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) /* SSLfatal() already called */ goto err; } +#ifndef OPENSSL_NO_TLCP + if (SSL_IS_TLCP(s)) { + if (!get_tbs_hash_data(hdata, hdatalen, out, &hdatalen)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, + ERR_R_INTERNAL_ERROR); + goto err; + } + /* Use new hash data for verify */ + hdata = out; + } +#endif #ifdef SSL_DEBUG fprintf(stderr, "Using client verify alg %s\n", @@ -907,6 +975,60 @@ static int ssl_add_cert_to_wpacket(SSL *s, WPACKET *pkt, X509 *x, int chain) return 1; } +#ifndef OPENSSL_NO_TLCP +static int ssl_add_sm2_cert_for_tlcp(SSL *s, STACK_OF(X509) *chain, WPACKET *pkt, X509 *sign_cert) +{ + CERT_PKEY *enc_cpk; + X509 *x; + int i = 0; + int idx = 0; + int count; + X509 *enc_cert; + + enc_cpk = &s->cert->pkeys[SSL_PKEY_SM2_ENC]; + // server must have enc cert + if (s->server && (enc_cpk == NULL || enc_cpk->x509 == NULL)) + return 0; + + enc_cert = enc_cpk->x509; + + if (sign_cert != NULL) { + if (!ssl_add_cert_to_wpacket(s, pkt, sign_cert, idx++)) { + return 0; + } + } else { + if (!ssl_add_cert_to_wpacket(s, pkt, sk_X509_value(chain, i++), idx++)) { + return 0; + } + } + + // enc cert put the second position + if (enc_cert != NULL && (s->options & SSL_OP_ENCCERT_SECOND_POSITION)) { + if (!ssl_add_cert_to_wpacket(s, pkt, enc_cert, idx++)) { + return 0; + } + enc_cert = NULL; + } + + count = sk_X509_num(chain); + for (; i < count; i++) { + x = sk_X509_value(chain, i); + if (!ssl_add_cert_to_wpacket(s, pkt, x, idx++)) { + return 0; + } + } + + // enc cert in the last position + if (enc_cert) { + if (!ssl_add_cert_to_wpacket(s, pkt, enc_cpk->x509, idx++)) { + return 0; + } + } + + return 1; +} +#endif + /* Add certificate chain to provided WPACKET */ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) { @@ -972,6 +1094,14 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_ADD_CERT_CHAIN, i); return 0; } +#ifndef OPENSSL_NO_TLCP + if (SSL_IS_TLCP(s)) { + if (!ssl_add_sm2_cert_for_tlcp(s, chain, pkt, NULL)) { + X509_STORE_CTX_free(xs_ctx); + return 0; + } + } else { +#endif chain_count = sk_X509_num(chain); for (i = 0; i < chain_count; i++) { x = sk_X509_value(chain, i); @@ -982,6 +1112,9 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) return 0; } } +#ifndef OPENSSL_NO_TLCP + } +#endif X509_STORE_CTX_free(xs_ctx); } else { i = ssl_security_cert_chain(s, extra_certs, x, 0); @@ -989,6 +1122,11 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_ADD_CERT_CHAIN, i); return 0; } +#ifndef OPENSSL_NO_TLCP + if (SSL_IS_TLCP(s)) { + return ssl_add_sm2_cert_for_tlcp(s, extra_certs, pkt, x); + } else { +#endif if (!ssl_add_cert_to_wpacket(s, pkt, x, 0)) { /* SSLfatal() already called */ return 0; @@ -1000,6 +1138,9 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) return 0; } } +#ifndef OPENSSL_NO_TLCP + } +#endif } return 1; } @@ -1444,6 +1585,9 @@ static const version_info tls_version_table[] = { #else {TLS1_VERSION, NULL, NULL}, #endif +#ifndef OPENSSL_NO_TLCP + {TLCP_VERSION, tlcp_client_method, tlcp_server_method}, +#endif #ifndef OPENSSL_NO_SSL3 {SSL3_VERSION, sslv3_client_method, sslv3_server_method}, #else @@ -1596,7 +1740,10 @@ int ssl_version_supported(const SSL *s, int version, const SSL_METHOD **meth) } for (vent = table; - vent->version != 0 && version_cmp(s, version, vent->version) <= 0; +#ifndef OPENSSL_NO_TLCP + ((version == SSL3_VERSION) && (vent->version == TLCP_VERSION)) || +#endif + (vent->version != 0 && version_cmp(s, version, vent->version) <= 0); ++vent) { if (vent->cmeth != NULL && version_cmp(s, version, vent->version) == 0 @@ -1675,8 +1822,11 @@ int ssl_set_version_bound(int method_version, int version, int *bound) *bound = version; return 1; } - +#ifndef OPENSSL_NO_TLCP + valid_tls = version >= TLCP_VERSION && version <= TLS_MAX_VERSION; +#else valid_tls = version >= SSL3_VERSION && version <= TLS_MAX_VERSION; +#endif valid_dtls = DTLS_VERSION_LE(version, DTLS_MAX_VERSION) && DTLS_VERSION_GE(version, DTLS1_BAD_VER); @@ -1868,6 +2018,9 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) const SSL_METHOD *method; if (vent->smeth == NULL || +#ifndef OPENSSL_NO_TLCP + ((client_version != TLCP_VERSION) && (vent->version == TLCP_VERSION)) || +#endif version_cmp(s, client_version, vent->version) < 0) continue; method = vent->smeth(); @@ -2097,6 +2250,11 @@ int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version, * A table entry with a NULL client method is still a hole in the * "version capability" vector. */ +#ifndef OPENSSL_NO_TLCP + if (vent->version == TLCP_VERSION) { + continue; + } +#endif if (vent->cmeth == NULL) { hole = 1; tmp_real_max = 0; @@ -2120,7 +2278,23 @@ int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version, hole = 0; } } - +#ifndef OPENSSL_NO_TLCP + if (version == 0 && s->method->version == TLS_ANY_VERSION) { + /* + * enable tlcp condition (when only sslv3 version, dont choose tlcp): + * 1. version is TLS_ANY_VERSION, and all tls/ssl protocol disabled + * 2. max version > sslv3 or max version == tlcp_version + * 3. s->options not set SSL_OP_NO_TLCP + */ + if ((s->max_proto_version > SSL3_VERSION + || s->max_proto_version == TLCP_VERSION + || s->max_proto_version == 0) + && (s->options & SSL_OP_NO_TLCP) == 0) { + *min_version = *max_version = TLCP_VERSION; + return 0; + } + } +#endif *max_version = version; /* Fail if everything is disabled */ diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index d701c46..ef13eec 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -325,6 +325,11 @@ static int send_server_key_exchange(SSL *s) { unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; +#ifndef OPENSSL_NO_TLCP + /* TLCP: send ServerKeyExchange */ + if (SSL_IS_TLCP(s)) + return 1; +#endif /* * only send a ServerKeyExchange if DH or fortezza but we have a * sign only certificate PSK: may send PSK identity hints For @@ -2356,7 +2361,17 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) } } #endif - +#ifndef OPENSSL_NO_TLCP + /* + * As described by TLCP, when using ecdhe algorithm, + * client is required to send a certificate, + * so we set VEERFY_PEER mode. + */ + if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSM2DHE) { + SSL_set_verify(s, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT + | SSL_VERIFY_CLIENT_ONCE, NULL); + } +#endif return WORK_FINISHED_STOP; err: return WORK_ERROR; @@ -2485,8 +2500,270 @@ int tls_construct_server_done(SSL *s, WPACKET *pkt) return 1; } +#ifndef OPENSSL_NO_TLCP +static int tlcp_construct_ske_sm2ecc(SSL *s, WPACKET *pkt) +{ + EVP_MD_CTX *md_ctx = NULL; + EVP_PKEY_CTX *pctx = NULL; + unsigned char *encbuf = NULL; + unsigned char *tbs = NULL; + + const SIGALG_LOOKUP *lu; + EVP_PKEY *sign_pkey; + X509 *enc_cert; + const EVP_MD *md; + unsigned char *sigbytes1, *sigbytes2, *tmp; + size_t siglen, tbslen; + int rv, ebuflen; + + rv = 0; + lu = s->s3->tmp.sigalg; + sign_pkey = s->cert->pkeys[SSL_PKEY_SM2_SIGN].privatekey; + enc_cert = s->cert->pkeys[SSL_PKEY_SM2_ENC].x509; + + if (lu == NULL || sign_pkey == NULL || enc_cert == NULL + || !tls1_lookup_md(lu, &md)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!EVP_PKEY_is_sm2(sign_pkey) + || !EVP_PKEY_set_alias_type(sign_pkey, EVP_PKEY_SM2)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, + ERR_R_INTERNAL_ERROR); + goto err; + } + + /* send signature algorithm */ + if (SSL_USE_SIGALGS(s) && !WPACKET_put_bytes_u16(pkt, lu->sigalg)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, + ERR_R_INTERNAL_ERROR); + goto err; + } + + ebuflen = i2d_X509(enc_cert, NULL); + if (ebuflen < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, + ERR_R_BUF_LIB); + goto err; + } + + md_ctx = EVP_MD_CTX_new(); + encbuf = OPENSSL_malloc(ebuflen + 3); + if (md_ctx == NULL || encbuf == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, + ERR_R_MALLOC_FAILURE); + goto err; + } + /* Encode the DER encoding of an X509 structure, reserve 3 bytes for length */ + tmp = encbuf; + l2n3(ebuflen, tmp); + ebuflen = i2d_X509(enc_cert, &tmp); + if (ebuflen < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, + ERR_R_BUF_LIB); + goto err; + } + ebuflen += 3; + + siglen = EVP_PKEY_size(sign_pkey); + if (!WPACKET_sub_reserve_bytes_u16(pkt, siglen, &sigbytes1) + || EVP_DigestSignInit(md_ctx, &pctx, md, NULL, sign_pkey) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, + ERR_R_INTERNAL_ERROR); + goto err; + } + /* + * As described by TLCP, client_random, server_random and encryption + * certificate are signed. + */ + tbslen = construct_key_exchange_tbs(s, &tbs, encbuf, ebuflen); + if (tbslen == 0) { + goto err; + } + + rv = EVP_DigestSign(md_ctx, sigbytes1, &siglen, tbs, tbslen); + + if (rv <= 0 || !WPACKET_sub_allocate_bytes_u16(pkt, siglen, &sigbytes2) + || sigbytes1 != sigbytes2) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, + ERR_R_INTERNAL_ERROR); + goto err; + } +err: + OPENSSL_free(encbuf); + OPENSSL_free(tbs); + EVP_MD_CTX_free(md_ctx); + return rv; +} + +static int tlcp_construct_ske_sm2dhe(SSL *s, WPACKET *pkt) +{ + EVP_PKEY_CTX *ctx; + EVP_PKEY *pkey; + EVP_MD_CTX *md_ctx = NULL; + unsigned char *pt; + int ptLen; + char *id = "1234567812345678"; + unsigned char *ecparam; + size_t ecparam_len = 0; + int ret = 0; + size_t siglen; + unsigned char *sig; + + ecparam = WPACKET_get_curr(pkt); + + // ECParam: NameCurved, curvedtype {NameCurved(3), curveid(41, rfc8898 defined, but this msg is ignored) + if (!WPACKET_put_bytes_u8(pkt, NAMED_CURVE_TYPE) + || !WPACKET_put_bytes_u8(pkt, 0) + || !WPACKET_put_bytes_u8(pkt, 41)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, + ERR_R_INTERNAL_ERROR); + return 0; + } + + pkey = s->cert->pkeys[SSL_PKEY_SM2_SIGN].privatekey; + if (pkey == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, + ERR_R_INTERNAL_ERROR); + return 0; + } + + if (s->s3->tmp.pkey != NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, + ERR_R_INTERNAL_ERROR); + return 0; + } + s->s3->tmp.pkey = ssl_generate_pkey_group(s, 41); + if (s->s3->tmp.pkey == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, + ERR_R_INTERNAL_ERROR); + return 0; + } + + ptLen = EVP_PKEY_get1_tls_encodedpoint(s->s3->tmp.pkey, &pt); + if (ptLen == 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, + ERR_R_EC_LIB); + return 0; + } + + if (!WPACKET_sub_memcpy_u8(pkt, pt, ptLen)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, + ERR_R_INTERNAL_ERROR); + OPENSSL_free(pt); + return 0; + } + OPENSSL_free(pt); + ecparam_len = WPACKET_get_curr(pkt) - ecparam; + + if (!EVP_PKEY_is_sm2(pkey) || !EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, + ERR_R_EC_LIB); + goto err; + } + + md_ctx = EVP_MD_CTX_new(); + if (md_ctx == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, + ERR_R_MALLOC_FAILURE); + return 0; + } + + if (EVP_DigestSignInit(md_ctx, &ctx, EVP_sm3(), NULL, pkey) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (EVP_PKEY_CTX_set1_id(ctx, id, strlen(id)) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, + ERR_R_EC_LIB); + return 0; + } + + if (EVP_DigestSignUpdate(md_ctx, s->s3->client_random, SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestSignUpdate(md_ctx, s->s3->server_random, SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestSignUpdate(md_ctx, ecparam, ecparam_len) <= 0 + ) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, + ERR_R_EVP_LIB); + goto err; + } + + if ((siglen = EVP_PKEY_size(pkey)) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!WPACKET_sub_reserve_bytes_u16(pkt, siglen, &sig)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (EVP_DigestSignFinal(md_ctx, sig, &siglen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, + SSL_R_SIGNATURE_ALGORITHMS_ERROR); + goto err; + } + + unsigned char* sig2 = NULL; + if (!WPACKET_sub_allocate_bytes_u16(pkt, siglen, &sig2) || sig != sig2) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = 1; + +err: + EVP_MD_CTX_free(md_ctx); + if (!ret && s->s3->tmp.pkey) { + EVP_PKEY_free(s->s3->tmp.pkey); + s->s3->tmp.pkey = NULL; + } + + return ret; +} + +static int tlcp_construct_server_key_exchange(SSL *s, WPACKET *pkt) +{ + unsigned long alg_k; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + if (alg_k & SSL_kSM2ECC) { + if (!tlcp_construct_ske_sm2ecc(s, pkt)) + goto err; + } else if (alg_k & SSL_kSM2DHE) { + if (!tlcp_construct_ske_sm2dhe(s, pkt)) + goto err; + } else { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + + return 1; +err: + return 0; +} +#endif + int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) { +#ifndef OPENSSL_NO_TLCP + if (SSL_IS_TLCP(s)) + return tlcp_construct_server_key_exchange(s, pkt); +#endif #ifndef OPENSSL_NO_DH EVP_PKEY *pkdh = NULL; #endif @@ -3455,8 +3732,174 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt) #endif } +#ifndef OPENSSL_NO_TLCP +static int tlcp_process_cke_sm2ecc(SSL *s, PACKET *pkt) +{ + EVP_PKEY_CTX *pctx = NULL; + int ret = 0; + + unsigned char premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; + EVP_PKEY *enc_prv_pkey; + PACKET enc_premaster; + size_t decrypt_len; + + enc_prv_pkey = s->cert->pkeys[SSL_PKEY_SM2_ENC].privatekey; + if (enc_prv_pkey == NULL || !EVP_PKEY_is_sm2(enc_prv_pkey) + || !EVP_PKEY_set_alias_type(enc_prv_pkey, EVP_PKEY_SM2)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2ECC, + SSL_R_NO_PRIVATE_KEY_ASSIGNED); + return 0; + } + + if (!PACKET_get_length_prefixed_2(pkt, &enc_premaster) + || PACKET_remaining(pkt) != 0) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2ECC, + SSL_R_LENGTH_MISMATCH); + return 0; + } + + pctx = EVP_PKEY_CTX_new(enc_prv_pkey, NULL); + if (pctx == NULL || EVP_PKEY_decrypt_init(pctx) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2ECC, + ERR_R_EVP_LIB); + goto err; + } + + /* Decrypt premaster secret { client_version, random[46] }*/ + decrypt_len = sizeof(premaster_secret); + if (EVP_PKEY_decrypt(pctx, premaster_secret, &decrypt_len, + PACKET_data(&enc_premaster), PACKET_remaining(&enc_premaster)) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2ECC, + ERR_R_EVP_LIB); + goto err; + } + if (decrypt_len != SSL_MAX_MASTER_KEY_LENGTH) { + SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2ECC, + SSL_R_DECRYPTION_FAILED); + goto err; + } + + /* Check client version */ + if (constant_time_eq_8(premaster_secret[0], (unsigned)(s->client_version >> 8)) == 0 || + constant_time_eq_8(premaster_secret[1], (unsigned)(s->client_version & 0xff)) == 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2ECC, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!ssl_generate_master_secret(s, premaster_secret, + sizeof(premaster_secret), 0)) { + /* SSLfatal() already called */ + goto err; + } + + ret = 1; + err: + OPENSSL_cleanse(premaster_secret, sizeof(premaster_secret)); + EVP_PKEY_CTX_free(pctx); + return ret; +} + +static int tlcp_process_cke_sm2dhe(SSL *s, PACKET *pkt) +{ + int ret = 0; + const unsigned char *ecparams; + PACKET pt_encoded; + EVP_PKEY *skey; + EVP_PKEY *ckey = NULL; + + if ((skey = s->s3->tmp.pkey) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, + ERR_R_INTERNAL_ERROR); + return 0; + } + + if (!PACKET_get_bytes(pkt, &ecparams, 3)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, + SSL_R_LENGTH_TOO_SHORT); + goto end; + } + + if (!PACKET_get_length_prefixed_1(pkt, &pt_encoded)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, + SSL_R_LENGTH_TOO_SHORT); + goto end; + } + + if (PACKET_remaining(pkt) != 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, + SSL_R_LENGTH_TOO_LONG); + goto end; + } + + if ((ckey = EVP_PKEY_new()) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, + ERR_R_MALLOC_FAILURE); + goto end; + } + + if (EVP_PKEY_copy_parameters(ckey, skey) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, + ERR_R_INTERNAL_ERROR); + goto end; + } + + if (EVP_PKEY_set1_tls_encodedpoint(ckey, + PACKET_data(&pt_encoded), PACKET_remaining(&pt_encoded)) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, + ERR_R_EC_LIB); + goto end; + } + + if (!tlcp_derive(s, skey, ckey)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, + ERR_R_INTERNAL_ERROR); + goto end; + } + + ret = 1; + +end: + EVP_PKEY_free(ckey); + EVP_PKEY_free(skey); + s->s3->tmp.pkey = NULL; + + return ret; +} + +static MSG_PROCESS_RETURN tlcp_process_client_key_exchange(SSL *s, PACKET *pkt) +{ + unsigned long alg_k; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + if (alg_k & SSL_kSM2ECC) { + if (!tlcp_process_cke_sm2ecc(s, pkt)) { + goto err; + } + } else if (alg_k & SSL_kSM2DHE) { + if (!tlcp_process_cke_sm2dhe(s, pkt)) { + goto err; + } + } else { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLCP_PROCESS_CLIENT_KEY_EXCHANGE, + SSL_R_UNKNOWN_CIPHER_TYPE); + goto err; + } + + return MSG_PROCESS_CONTINUE_PROCESSING; +err: + return MSG_PROCESS_ERROR; +} +#endif + MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) { +#ifndef OPENSSL_NO_TLCP + if (SSL_IS_TLCP(s)) + return tlcp_process_client_key_exchange(s, pkt); +#endif unsigned long alg_k; alg_k = s->s3->tmp.new_cipher->algorithm_mkey; diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index c85c0b0..e86a663 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -676,3 +676,87 @@ int tls1_alert_code(int code) return -1; } } + +#ifndef OPENSSL_NO_TLCP +int tlcp_alert_code(int code) +{ + switch (code) { + case SSL_AD_CLOSE_NOTIFY: + return (SSL3_AD_CLOSE_NOTIFY); + case SSL_AD_UNEXPECTED_MESSAGE: + return (SSL3_AD_UNEXPECTED_MESSAGE); + case SSL_AD_BAD_RECORD_MAC: + return (SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_DECRYPTION_FAILED: + return (TLS1_AD_DECRYPTION_FAILED); + case SSL_AD_RECORD_OVERFLOW: + return (TLS1_AD_RECORD_OVERFLOW); + case SSL_AD_DECOMPRESSION_FAILURE: + return (SSL3_AD_DECOMPRESSION_FAILURE); + case SSL_AD_HANDSHAKE_FAILURE: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_BAD_CERTIFICATE: + return (SSL3_AD_BAD_CERTIFICATE); + case SSL_AD_UNSUPPORTED_CERTIFICATE: + return (SSL3_AD_UNSUPPORTED_CERTIFICATE); + case SSL_AD_CERTIFICATE_REVOKED: + return (SSL3_AD_CERTIFICATE_REVOKED); + case SSL_AD_CERTIFICATE_EXPIRED: + return (SSL3_AD_CERTIFICATE_EXPIRED); + case SSL_AD_CERTIFICATE_UNKNOWN: + return (SSL3_AD_CERTIFICATE_UNKNOWN); + case SSL_AD_ILLEGAL_PARAMETER: + return (SSL3_AD_ILLEGAL_PARAMETER); + case SSL_AD_UNKNOWN_CA: + return (TLS1_AD_UNKNOWN_CA); + case SSL_AD_ACCESS_DENIED: + return (TLS1_AD_ACCESS_DENIED); + case SSL_AD_DECODE_ERROR: + return (TLS1_AD_DECODE_ERROR); + case SSL_AD_DECRYPT_ERROR: + return (TLS1_AD_DECRYPT_ERROR); + case SSL_AD_EXPORT_RESTRICTION: + return (TLS1_AD_EXPORT_RESTRICTION); + case SSL_AD_PROTOCOL_VERSION: + return (TLS1_AD_PROTOCOL_VERSION); + case SSL_AD_INSUFFICIENT_SECURITY: + return (TLS1_AD_INSUFFICIENT_SECURITY); + case SSL_AD_INTERNAL_ERROR: + return (TLS1_AD_INTERNAL_ERROR); + case SSL_AD_USER_CANCELLED: + return (TLS1_AD_USER_CANCELLED); + case SSL_AD_NO_RENEGOTIATION: + return (TLS1_AD_NO_RENEGOTIATION); + case SSL_AD_UNSUPPORTED_EXTENSION: + return (TLS1_AD_UNSUPPORTED_EXTENSION); + case SSL_AD_CERTIFICATE_UNOBTAINABLE: + return (TLS1_AD_CERTIFICATE_UNOBTAINABLE); + case SSL_AD_UNRECOGNIZED_NAME: + return (TLS1_AD_UNRECOGNIZED_NAME); + case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + return (TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE); + case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: + return (TLS1_AD_BAD_CERTIFICATE_HASH_VALUE); + case SSL_AD_INAPPROPRIATE_FALLBACK: + return (TLS1_AD_INAPPROPRIATE_FALLBACK); + case SSL_AD_NO_APPLICATION_PROTOCOL: + return (TLS1_AD_NO_APPLICATION_PROTOCOL); + case SSL_AD_CERTIFICATE_REQUIRED: + return (SSL_AD_HANDSHAKE_FAILURE); + case SSL_AD_UNSUPPORTED_SITE2SITE: + return (TLCP_AD_UNSUPPORTED_SITE2SITE); + case SSL_AD_NO_AREA: + return (TLCP_AD_NO_AREA); + case SSL_AD_UNSUPPORTED_AREATYPE: + return (TLCP_AD_UNSUPPORTED_AREATYPE); + case SSL_AD_BAD_IBCPARAM: + return (TLCP_AD_BAD_IBCPARAM); + case SSL_AD_UNSUPPORTED_IBCPARAM: + return (TLCP_AD_UNSUPPORTED_IBCPARAM); + case SSL_AD_IDENTITY_NEED: + return (TLCP_AD_IDENTITY_NEED); + default: + return (-1); + } +} +#endif \ No newline at end of file diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 841feec..8b4a61b 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -93,6 +93,25 @@ SSL3_ENC_METHOD const TLSv1_3_enc_data = { ssl3_handshake_write }; +#ifndef OPENSSL_NO_TLCP +SSL3_ENC_METHOD const TLCP_enc_data = { + tls1_enc, + tls1_mac, + tls1_setup_key_block, + tls1_generate_master_secret, + tls1_change_cipher_state, + tls1_final_finish_mac, + TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, + tlcp_alert_code, + tls1_export_keying_material, + SSL_ENC_FLAG_EXPLICIT_IV, + ssl3_set_handshake_header, + tls_close_construct_packet, + ssl3_handshake_write +}; +#endif + long tls1_default_timeout(void) { /* @@ -169,6 +188,9 @@ static const TLS_GROUP_INFO nid_list[] = { {NID_brainpoolP512r1, 256, TLS_CURVE_PRIME}, /* brainpool512r1 (28) */ {EVP_PKEY_X25519, 128, TLS_CURVE_CUSTOM}, /* X25519 (29) */ {EVP_PKEY_X448, 224, TLS_CURVE_CUSTOM}, /* X448 (30) */ +#ifndef OPENSSL_NO_TLCP + [40] = {EVP_PKEY_SM2, 128, TLS_CURVE_PRIME} /* sm2 (41) */ +#endif }; static const unsigned char ecformats_default[] = { @@ -184,6 +206,9 @@ static const uint16_t eccurves_default[] = { 30, /* X448 (30) */ 25, /* secp521r1 (25) */ 24, /* secp384r1 (24) */ +#ifndef OPENSSL_NO_TLCP + 41, /* sm2 (41) */ +#endif }; static const uint16_t suiteb_curves[] = { @@ -260,6 +285,12 @@ int tls_curve_allowed(SSL *s, uint16_t curve, int op) # endif if (FIPS_mode() && !(cinfo->flags & TLS_CURVE_FIPS)) return 0; +#ifndef OPENSSL_NO_TLCP + // SM2 is only allowed in TLCP + if (s->version != TLCP_VERSION && cinfo->nid == NID_sm2) { + return 0; + } +#endif ctmp[0] = curve >> 8; ctmp[1] = curve & 0xff; return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)ctmp); @@ -547,6 +578,10 @@ void tls1_get_formatlist(SSL *s, const unsigned char **pformats, /* For Suite B we don't support char2 fields */ if (tls1_suiteb(s)) *num_formats = sizeof(ecformats_default) - 1; +#ifndef OPENSSL_NO_TLCP + else if (SSL_IS_TLCP(s)) // TLCP version only support uncompressed + *num_formats = sizeof(ecformats_default) - 2; +#endif else *num_formats = sizeof(ecformats_default); } @@ -639,6 +674,9 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) /* Default sigalg schemes */ static const uint16_t tls12_sigalgs[] = { #ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_TLCP + TLSEXT_SIGALG_sm2dsa_sm3, +#endif TLSEXT_SIGALG_ecdsa_secp256r1_sha256, TLSEXT_SIGALG_ecdsa_secp384r1_sha384, TLSEXT_SIGALG_ecdsa_secp521r1_sha512, @@ -687,6 +725,11 @@ static const uint16_t suiteb_sigalgs[] = { static const SIGALG_LOOKUP sigalg_lookup_tbl[] = { #ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_TLCP + {"sm2dsa_sm3", TLSEXT_SIGALG_sm2dsa_sm3, + NID_sm3, SSL_MD_SM3_IDX, EVP_PKEY_SM2, SSL_PKEY_SM2_SIGN, + NID_SM2_with_SM3, NID_sm2}, +#endif {"ecdsa_secp256r1_sha256", TLSEXT_SIGALG_ecdsa_secp256r1_sha256, NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, NID_ecdsa_with_SHA256, NID_X9_62_prime256v1}, @@ -796,6 +839,10 @@ static const uint16_t tls_default_sigalg[] = { TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, /* SSL_PKEY_GOST12_512 */ 0, /* SSL_PKEY_ED25519 */ 0, /* SSL_PKEY_ED448 */ +#ifndef OPENSSL_NO_TLCP + TLSEXT_SIGALG_sm2dsa_sm3, /* SSL_PKEY_SM2_SIGN */ + 0, /* SSL_PKEY_SM2_ENC */ +#endif }; /* Lookup TLS signature algorithm */ @@ -983,7 +1030,7 @@ int tls_check_sigalg_curve(const SSL *s, int curve) if (lu == NULL) continue; - if (lu->sig == EVP_PKEY_EC + if ((lu->sig == EVP_PKEY_EC || lu->sig == EVP_PKEY_SM2) && lu->curve != NID_undef && curve == lu->curve) return 1; @@ -1055,6 +1102,9 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) if (lu == NULL || (SSL_IS_TLS13(s) && (lu->hash == NID_sha1 || lu->hash == NID_sha224)) || (pkeyid != lu->sig +#ifndef OPENSSL_NO_TCLP + && (lu->sig != EVP_PKEY_SM2) +#endif && (lu->sig != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA))) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); @@ -1199,6 +1249,13 @@ int ssl_set_client_disabled(SSL *s) s->s3->tmp.mask_a |= SSL_aSRP; s->s3->tmp.mask_k |= SSL_kSRP; } +#endif +#ifndef OPENSSL_NO_TLCP + /* TLCP ciphersuites will be disabled while using other protocols */ + if (s->version != TLCP_VERSION) { + s->s3->tmp.mask_a |= SSL_aSM2; + s->s3->tmp.mask_k |= SSL_kSM2ECC | SSL_kSM2DHE; + } #endif return 1; } @@ -1319,7 +1376,11 @@ SSL_TICKET_STATUS tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello, * (e.g. TLSv1.3) behave as if no ticket present to permit stateful * resumption. */ +#ifndef OPENSSL_NO_TLCP + if ((s->version <= SSL3_VERSION && s->version != TLCP_VERSION) || !tls_use_ticket(s)) +#else if (s->version <= SSL3_VERSION || !tls_use_ticket(s)) +#endif return SSL_TICKET_NONE; ticketext = &hello->pre_proc_exts[TLSEXT_IDX_session_ticket]; @@ -1597,6 +1658,13 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) unsigned char sigalgstr[2]; int secbits; +#ifndef OPENSSL_NO_TLCP + // SM2 is only allowed in TLCP + if (s->version != TLCP_VERSION && lu != NULL && lu->sig == EVP_PKEY_SM2) { + return 0; + } +#endif + /* See if sigalgs is recognised and if hash is enabled */ if (!tls1_lookup_md(lu, NULL)) return 0; @@ -2430,6 +2498,10 @@ void tls1_set_cert_validity(SSL *s) tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST12_512); tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ED25519); tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ED448); +#ifndef OPENSSL_NO_TLCP + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_SM2_ENC); + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_SM2_SIGN); +#endif } /* User level utility function to check a chain is suitable */ @@ -2734,6 +2806,55 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey) return lu; } +#ifndef OPENSSL_NO_TLCP +int tlcp_choose_sigalg(SSL *s, int fatalerrs) +{ + int sig_idx; + const SIGALG_LOOKUP *lu = NULL; + + // sever must used sm2dsa cert for signature + if (s->server) { + s->cert->key = &(s->cert->pkeys[SSL_PKEY_SM2_SIGN]); + } + + sig_idx = s->cert->key - s->cert->pkeys; + + // check cert is existed + if (!ssl_has_cert(s, sig_idx)) { + if (!fatalerrs) + return 1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CHOOSE_SIGALG, + ERR_R_INTERNAL_ERROR); + return 0; + } + + // only support sm2dsa cert now + switch(sig_idx) { + case SSL_PKEY_ECC: + if (!EVP_PKEY_is_sm2(s->cert->key->privatekey)) + break; + case SSL_PKEY_SM2_SIGN: + lu = tls1_lookup_sigalg(TLSEXT_SIGALG_sm2dsa_sm3); + break; + default: + lu = NULL; + } + + if (lu == NULL) { + if (!fatalerrs) + return 1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CHOOSE_SIGALG, + ERR_R_INTERNAL_ERROR); + return 0; + } + + s->s3->tmp.cert = &s->cert->pkeys[sig_idx]; + s->cert->key = s->s3->tmp.cert; + s->s3->tmp.sigalg = lu; + return 1; +} +#endif + /* * Choose an appropriate signature algorithm based on available certificates * Sets chosen certificate and signature algorithm. @@ -2753,6 +2874,12 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) s->s3->tmp.cert = NULL; s->s3->tmp.sigalg = NULL; +#ifndef OPENSSL_NO_TLCP + if (SSL_IS_TLCP(s)) { + return tlcp_choose_sigalg(s, fatalerrs); + } +#endif + if (SSL_IS_TLS13(s)) { lu = find_sig_alg(s, NULL, NULL); if (lu == NULL) { @@ -2766,6 +2893,7 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) /* If ciphersuite doesn't require a cert nothing to do */ if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aCERT)) return 1; + if (!s->server && !ssl_has_cert(s, s->cert->key - s->cert->pkeys)) return 1; diff --git a/test/build.info b/test/build.info index 726bd22..db16a1f 100644 --- a/test/build.info +++ b/test/build.info @@ -51,7 +51,7 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN recordlentest drbgtest drbg_cavs_test sslbuffertest \ time_offset_test pemtest ssl_cert_table_internal_test ciphername_test \ servername_test ocspapitest rsa_mp_test fatalerrtest tls13ccstest \ - sysdefaulttest errtest ssl_ctx_test gosttest + sysdefaulttest errtest ssl_ctx_test gosttest tlcptest SOURCE[versions]=versions.c INCLUDE[versions]=../include @@ -320,6 +320,10 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN INCLUDE[dtlstest]=../include DEPEND[dtlstest]=../libcrypto ../libssl libtestutil.a + SOURCE[tlcptest]=tlcptest.c ssltestlib.c + INCLUDE[tlcptest]=.. ../include + DEPEND[tlcptest]=../libcrypto ../libssl libtestutil.a + SOURCE[sslcorrupttest]=sslcorrupttest.c ssltestlib.c INCLUDE[sslcorrupttest]=../include DEPEND[sslcorrupttest]=../libcrypto ../libssl libtestutil.a diff --git a/test/ciphername_test.c b/test/ciphername_test.c index 303e28f..5c9edf4 100644 --- a/test/ciphername_test.c +++ b/test/ciphername_test.c @@ -434,6 +434,9 @@ static int test_cipher_name(void) if ((id == 0xFF85) || (id == 0xFF87)) /* skip GOST2012-GOST8912-GOST891 and GOST2012-NULL-GOST12 */ continue; + if ((id == 0xE011) || (id == 0xE013)) + /* skip ECDHE_SM2_WITH_SM4_CBC_SM3 and ECC_SM2_WITH_SM4_CBC_SM3 */ + continue; p = SSL_CIPHER_standard_name(c); q = get_std_name_by_id(id); if (!TEST_ptr(p)) { diff --git a/test/recipes/85-test_tlcp.t b/test/recipes/85-test_tlcp.t new file mode 100644 index 0000000..eb87123 --- /dev/null +++ b/test/recipes/85-test_tlcp.t @@ -0,0 +1,34 @@ +#! /usr/bin/env perl +# Copyright 2022 Huawei Technologies Co., Ltd. All Rights Reserved. +# +# Licensed under the OpenSSL license (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use OpenSSL::Test::Utils; +use OpenSSL::Test qw/:DEFAULT data_file/; + +setup("test_tlcp"); + +plan skip_all => "TLCP is not supported by this OpenSSL build" + if disabled("tlcp"); + +plan tests => 1; + +ok(run(test(["tlcptest", + data_file("sm2-root-cert.pem"), # 0 + data_file("sm2-server-sig-cert.pem"), # 1 + data_file("sm2-server-sig-key.pem"), # 2 + data_file("sm2-server-enc-cert.pem"), # 3 + data_file("sm2-server-enc-key.pem"), # 4 + data_file("sm2-client-sig-cert.pem"), # 5 + data_file("sm2-client-sig-key.pem"), # 6 + data_file("sm2-client-enc-cert.pem"), # 7 + data_file("sm2-client-enc-key.pem"), # 8 + data_file("ecdsa-root-cert.pem"), # 9 + data_file("ecdsa-server-cert.pem"), # 10 + data_file("ecdsa-server-key.pem"), # 11 + data_file("ecdsa-client-cert.pem"), # 12 + data_file("ecdsa-client-key.pem") # 13 + ]))); \ No newline at end of file diff --git a/test/recipes/85-test_tlcp_data/ecdsa-client-cert.pem b/test/recipes/85-test_tlcp_data/ecdsa-client-cert.pem new file mode 100644 index 0000000..4f41232 --- /dev/null +++ b/test/recipes/85-test_tlcp_data/ecdsa-client-cert.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB2zCCAYGgAwIBAgIUIxUR+f5s2IPkP5kd86umC0jtOy0wCgYIKoZIzj0EAwIw +YDELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz +dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxGDAWBgNVBAMMD1Rlc3QgQ0EgKEVDRFNB +KTAeFw0yMjA1MTkwOTI3MTVaFw0yNjA2MjcwOTI3MTVaMF8xCzAJBgNVBAYTAkNO +MRIwEAYDVQQIDAlHdWFuZ2RvbmcxETAPBgNVBAoMCFRlc3QgT3JnMRAwDgYDVQQL +DAdUZXN0IE9VMRcwFQYDVQQDDA5jbGllbnQgKEVDRFNBKTBZMBMGByqGSM49AgEG +CCqGSM49AwEHA0IABJg2jl8qqQkLHwcqKC+gu8SWpDNHl8x2xSlsNkS8hm2edlsJ +5QHfMPw7b138CmEE2FEtMqCtpRtsQnb5JRcxfTajGjAYMAkGA1UdEwQCMAAwCwYD +VR0PBAQDAgbAMAoGCCqGSM49BAMCA0gAMEUCICBPe4rSKQdIWdB3u8EZ9+AR6Slu +wsqdPm8p2mE409x4AiEAx513RsVDYohfejrvJmEL9ELIHmqTHjX+WjTjfMR/qrY= +-----END CERTIFICATE----- diff --git a/test/recipes/85-test_tlcp_data/ecdsa-client-key.pem b/test/recipes/85-test_tlcp_data/ecdsa-client-key.pem new file mode 100644 index 0000000..8a356ba --- /dev/null +++ b/test/recipes/85-test_tlcp_data/ecdsa-client-key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgj/hA8kscmW1VDMMn +jWDNu/JrGrZ5Xr1kH0Q61zpRhIShRANCAASYNo5fKqkJCx8HKigvoLvElqQzR5fM +dsUpbDZEvIZtnnZbCeUB3zD8O29d/AphBNhRLTKgraUbbEJ2+SUXMX02 +-----END PRIVATE KEY----- diff --git a/test/recipes/85-test_tlcp_data/ecdsa-root-cert.pem b/test/recipes/85-test_tlcp_data/ecdsa-root-cert.pem new file mode 100644 index 0000000..80d8c06 --- /dev/null +++ b/test/recipes/85-test_tlcp_data/ecdsa-root-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICHzCCAcWgAwIBAgIUcxkoWsrQfKvdPzNFeZt9sUACCv8wCgYIKoZIzj0EAwIw +YDELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz +dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxGDAWBgNVBAMMD1Rlc3QgQ0EgKEVDRFNB +KTAeFw0yMjA1MTkwOTI3MTVaFw0yNjA2MjcwOTI3MTVaMGAxCzAJBgNVBAYTAkNO +MRIwEAYDVQQIDAlHdWFuZ2RvbmcxETAPBgNVBAoMCFRlc3QgT3JnMRAwDgYDVQQL +DAdUZXN0IE9VMRgwFgYDVQQDDA9UZXN0IENBIChFQ0RTQSkwWTATBgcqhkjOPQIB +BggqhkjOPQMBBwNCAAQb8M+p/ywfaaLb6y5jP/6essKMw+HBYIzluA8JpAyuSEag +hiiIegi/fJA9tONUKGGQrE92gFIjsyrGvwPnYqF1o10wWzAdBgNVHQ4EFgQU+BnE +9UFgm03egYusuG7wtBeF12kwHwYDVR0jBBgwFoAU+BnE9UFgm03egYusuG7wtBeF +12kwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwCgYIKoZIzj0EAwIDSAAwRQIh +AO3LVs9OBinihB4W22ju3zoqfXTtHGdF0d9nbHbZEYqdAiAum1ZhMbtyWo/3YLDR +2DqMuw5al5FbOlCIwrMbqcL+qQ== +-----END CERTIFICATE----- diff --git a/test/recipes/85-test_tlcp_data/ecdsa-server-cert.pem b/test/recipes/85-test_tlcp_data/ecdsa-server-cert.pem new file mode 100644 index 0000000..7e0d8d7 --- /dev/null +++ b/test/recipes/85-test_tlcp_data/ecdsa-server-cert.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB2zCCAYGgAwIBAgIUIxUR+f5s2IPkP5kd86umC0jtOywwCgYIKoZIzj0EAwIw +YDELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz +dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxGDAWBgNVBAMMD1Rlc3QgQ0EgKEVDRFNB +KTAeFw0yMjA1MTkwOTI3MTVaFw0yNjA2MjcwOTI3MTVaMF8xCzAJBgNVBAYTAkNO +MRIwEAYDVQQIDAlHdWFuZ2RvbmcxETAPBgNVBAoMCFRlc3QgT3JnMRAwDgYDVQQL +DAdUZXN0IE9VMRcwFQYDVQQDDA5zZXJ2ZXIgKEVDRFNBKTBZMBMGByqGSM49AgEG +CCqGSM49AwEHA0IABAAmT2rADtfh1M/AW6n3cgLm2kEq/StWWcFDQ/AmTz54nFMp +9AHt7xAqnizKl2UcdzUcDbhyBeNwjZ+80Eavvx2jGjAYMAkGA1UdEwQCMAAwCwYD +VR0PBAQDAgbAMAoGCCqGSM49BAMCA0gAMEUCIQC70m1KUdKAsLI8zq78azjV2r/Z +Oc6vwXfAqLKgF7EhtQIgYvh0XrMU9ETKKbfHORqJK+BD9DmFnAkxNpc9KVmN/D8= +-----END CERTIFICATE----- diff --git a/test/recipes/85-test_tlcp_data/ecdsa-server-key.pem b/test/recipes/85-test_tlcp_data/ecdsa-server-key.pem new file mode 100644 index 0000000..9d9af8d --- /dev/null +++ b/test/recipes/85-test_tlcp_data/ecdsa-server-key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgqMLQcziYtVwg+30u +MvCIb3bYAfxAazvxQ8I69Jtml9uhRANCAAQAJk9qwA7X4dTPwFup93IC5tpBKv0r +VlnBQ0PwJk8+eJxTKfQB7e8QKp4sypdlHHc1HA24cgXjcI2fvNBGr78d +-----END PRIVATE KEY----- diff --git a/test/recipes/85-test_tlcp_data/sm2-client-enc-cert.pem b/test/recipes/85-test_tlcp_data/sm2-client-enc-cert.pem new file mode 100644 index 0000000..4a3e3f0 --- /dev/null +++ b/test/recipes/85-test_tlcp_data/sm2-client-enc-cert.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB2DCCAYCgAwIBAgIUMsQnTMiHshN4IOMc/ydgCOWB3WQwCgYIKoEcz1UBg3Uw +XjELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz +dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxFjAUBgNVBAMMDVRlc3QgQ0EgKFNNMikw +HhcNMjIwNTE5MDkyNzEwWhcNMjYwNjI3MDkyNzEwWjBgMQswCQYDVQQGEwJDTjES +MBAGA1UECAwJR3Vhbmdkb25nMREwDwYDVQQKDAhUZXN0IE9yZzEQMA4GA1UECwwH +VGVzdCBPVTEYMBYGA1UEAwwPY2xpZW50IGVuYyhTTTIpMFkwEwYHKoZIzj0CAQYI +KoEcz1UBgi0DQgAEsjxuZnSYi2M2iL4vUqHFdegJqxALkFxq+XiA/C8vQSMOCDaz +8ZH1XrCwU3kMShiQyNM8AkjufKgCOGSB3B58qKMaMBgwCQYDVR0TBAIwADALBgNV +HQ8EBAMCAzgwCgYIKoEcz1UBg3UDRgAwQwIgcwaVeJ3pa/WUuR28r9+tGRg2EIEO +IOlzRUlo6mwqcDACHxugAc0CFsB1dUWLOJuwJtpYsEmNpNHwLzxa16cfW3w= +-----END CERTIFICATE----- diff --git a/test/recipes/85-test_tlcp_data/sm2-client-enc-key.pem b/test/recipes/85-test_tlcp_data/sm2-client-enc-key.pem new file mode 100644 index 0000000..7a03991 --- /dev/null +++ b/test/recipes/85-test_tlcp_data/sm2-client-enc-key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQg5xwdNhYtjBcZ5YEd +VNu5609rYpePHUZUlQvlAJIqMB2hRANCAASyPG5mdJiLYzaIvi9SocV16AmrEAuQ +XGr5eID8Ly9BIw4INrPxkfVesLBTeQxKGJDI0zwCSO58qAI4ZIHcHnyo +-----END PRIVATE KEY----- diff --git a/test/recipes/85-test_tlcp_data/sm2-client-sig-cert.pem b/test/recipes/85-test_tlcp_data/sm2-client-sig-cert.pem new file mode 100644 index 0000000..ce539a6 --- /dev/null +++ b/test/recipes/85-test_tlcp_data/sm2-client-sig-cert.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB3DCCAYKgAwIBAgIUMsQnTMiHshN4IOMc/ydgCOWB3WMwCgYIKoEcz1UBg3Uw +XjELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz +dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxFjAUBgNVBAMMDVRlc3QgQ0EgKFNNMikw +HhcNMjIwNTE5MDkyNzEwWhcNMjYwNjI3MDkyNzEwWjBiMQswCQYDVQQGEwJDTjES +MBAGA1UECAwJR3Vhbmdkb25nMREwDwYDVQQKDAhUZXN0IE9yZzEQMA4GA1UECwwH +VGVzdCBPVTEaMBgGA1UEAwwRY2xpZW50IHNpZ24gKFNNMikwWTATBgcqhkjOPQIB +BggqgRzPVQGCLQNCAAQDr0xTp4anFz8UHoMWyAWq/yYpiXdysF1dvciTvgET7CAA +PydlOnKQw2K1NguwiecT4/XCpZMmbvhthMcCsyywoxowGDAJBgNVHRMEAjAAMAsG +A1UdDwQEAwIGwDAKBggqgRzPVQGDdQNIADBFAiEA1pxw3tMJ6epz6r/wonHMWBE/ +3MBbRIsOq9xxhOhqhyECIBR0V+O51j3gsuDwSqSU81rYLXPaE0RGuhbdWOHi4bII +-----END CERTIFICATE----- diff --git a/test/recipes/85-test_tlcp_data/sm2-client-sig-key.pem b/test/recipes/85-test_tlcp_data/sm2-client-sig-key.pem new file mode 100644 index 0000000..d2c537d --- /dev/null +++ b/test/recipes/85-test_tlcp_data/sm2-client-sig-key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQg0x2USJzgAonYJeiQ +VkBw/u6/uo6B9M88YVL3A1OmorKhRANCAAQDr0xTp4anFz8UHoMWyAWq/yYpiXdy +sF1dvciTvgET7CAAPydlOnKQw2K1NguwiecT4/XCpZMmbvhthMcCsyyw +-----END PRIVATE KEY----- diff --git a/test/recipes/85-test_tlcp_data/sm2-root-cert.pem b/test/recipes/85-test_tlcp_data/sm2-root-cert.pem new file mode 100644 index 0000000..a20df8c --- /dev/null +++ b/test/recipes/85-test_tlcp_data/sm2-root-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICGjCCAcGgAwIBAgIUV3TWPlV09Vqm5/FpSqR7ryeGrfEwCgYIKoEcz1UBg3Uw +XjELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz +dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxFjAUBgNVBAMMDVRlc3QgQ0EgKFNNMikw +HhcNMjIwNTE5MDkyNzEwWhcNMjYwNjI3MDkyNzEwWjBeMQswCQYDVQQGEwJDTjES +MBAGA1UECAwJR3Vhbmdkb25nMREwDwYDVQQKDAhUZXN0IE9yZzEQMA4GA1UECwwH +VGVzdCBPVTEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTBZMBMGByqGSM49AgEGCCqB +HM9VAYItA0IABHsTJfkk1NiaYrPidOIQHCGWBs77fKEhXoG1uONGTfHEDhhhA3EX +QZBL9cVO//farVmKF9ipYR9GA4pk0wHtGEKjXTBbMB0GA1UdDgQWBBQ9YT+D7/Cv +3KqG4b9YxuWOSbMRRzAfBgNVHSMEGDAWgBQ9YT+D7/Cv3KqG4b9YxuWOSbMRRzAM +BgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAKBggqgRzPVQGDdQNHADBEAiAOJ4al +v3c1AHBohqZQkAAZsY9+LSH/3/e3C4Q4jQsDUQIgUDJFXbXSUrsMoKFmkvHONmz+ +9zGXND9ctJ1Dineo9dI= +-----END CERTIFICATE----- diff --git a/test/recipes/85-test_tlcp_data/sm2-server-enc-cert.pem b/test/recipes/85-test_tlcp_data/sm2-server-enc-cert.pem new file mode 100644 index 0000000..c7a5ef2 --- /dev/null +++ b/test/recipes/85-test_tlcp_data/sm2-server-enc-cert.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB2jCCAYGgAwIBAgIUMsQnTMiHshN4IOMc/ydgCOWB3WIwCgYIKoEcz1UBg3Uw +XjELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz +dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxFjAUBgNVBAMMDVRlc3QgQ0EgKFNNMikw +HhcNMjIwNTE5MDkyNzEwWhcNMjYwNjI3MDkyNzEwWjBhMQswCQYDVQQGEwJDTjES +MBAGA1UECAwJR3Vhbmdkb25nMREwDwYDVQQKDAhUZXN0IE9yZzEQMA4GA1UECwwH +VGVzdCBPVTEZMBcGA1UEAwwQc2VydmVyIGVuYyAoU00yKTBZMBMGByqGSM49AgEG +CCqBHM9VAYItA0IABCWsJ/Vs/68DYkqIgoTdE8zoOA86UMHLASZriw+AF0lbmiOD +dngO7RvDd55OOAmFK6sY7d+vzsIeMNQus4YLkc2jGjAYMAkGA1UdEwQCMAAwCwYD +VR0PBAQDAgM4MAoGCCqBHM9VAYN1A0cAMEQCICZgP6OiaVyAbYTX5yJpiwusEvDU +bMB/+hpnNA0ors3zAiB4EkZEBWZkd0su+umAXpO44IYaDvUumPSaGZLBbg7m1w== +-----END CERTIFICATE----- diff --git a/test/recipes/85-test_tlcp_data/sm2-server-enc-key.pem b/test/recipes/85-test_tlcp_data/sm2-server-enc-key.pem new file mode 100644 index 0000000..ae509ec --- /dev/null +++ b/test/recipes/85-test_tlcp_data/sm2-server-enc-key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgE32DrOaCm3ai/cPZ +/9nnxJoCH171qVL7ignjIrMBGdGhRANCAAQlrCf1bP+vA2JKiIKE3RPM6DgPOlDB +ywEma4sPgBdJW5ojg3Z4Du0bw3eeTjgJhSurGO3fr87CHjDULrOGC5HN +-----END PRIVATE KEY----- diff --git a/test/recipes/85-test_tlcp_data/sm2-server-sig-cert.pem b/test/recipes/85-test_tlcp_data/sm2-server-sig-cert.pem new file mode 100644 index 0000000..8238bad --- /dev/null +++ b/test/recipes/85-test_tlcp_data/sm2-server-sig-cert.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB2zCCAYKgAwIBAgIUMsQnTMiHshN4IOMc/ydgCOWB3WEwCgYIKoEcz1UBg3Uw +XjELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz +dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxFjAUBgNVBAMMDVRlc3QgQ0EgKFNNMikw +HhcNMjIwNTE5MDkyNzEwWhcNMjYwNjI3MDkyNzEwWjBiMQswCQYDVQQGEwJDTjES +MBAGA1UECAwJR3Vhbmdkb25nMREwDwYDVQQKDAhUZXN0IE9yZzEQMA4GA1UECwwH +VGVzdCBPVTEaMBgGA1UEAwwRc2VydmVyIHNpZ24gKFNNMikwWTATBgcqhkjOPQIB +BggqgRzPVQGCLQNCAAQgP2f+HnNb6BWCGscITDpf53BwVvpj3gxrlHz05Po3i2IA +qyL5yL2VE+bqTrxCFpQOHupjW3f5Bkihv7IUW/zMoxowGDAJBgNVHRMEAjAAMAsG +A1UdDwQEAwIGwDAKBggqgRzPVQGDdQNHADBEAiA63GVhHaDzcVJ9DMLK/53wQZvg +HR+tj4MCBtb6F9hL9QIgbojf0R49GnO6VYHHUx0fe+4+2DfAcMdVIutOmbpRc60= +-----END CERTIFICATE----- diff --git a/test/recipes/85-test_tlcp_data/sm2-server-sig-key.pem b/test/recipes/85-test_tlcp_data/sm2-server-sig-key.pem new file mode 100644 index 0000000..f7fa712 --- /dev/null +++ b/test/recipes/85-test_tlcp_data/sm2-server-sig-key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgr9nuyaNIE7aSQw/I +sc7JhizpuCPUNKBF9zZy1on8BHShRANCAAQgP2f+HnNb6BWCGscITDpf53BwVvpj +3gxrlHz05Po3i2IAqyL5yL2VE+bqTrxCFpQOHupjW3f5Bkihv7IUW/zM +-----END PRIVATE KEY----- diff --git a/test/sm2_internal_test.c b/test/sm2_internal_test.c index 4951cd3..0ab84b2 100644 --- a/test/sm2_internal_test.c +++ b/test/sm2_internal_test.c @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -17,6 +18,7 @@ #include <openssl/crypto.h> #include <openssl/err.h> #include <openssl/rand.h> +#include <openssl/sm2.h> #include "testutil.h" #ifndef OPENSSL_NO_SM2 @@ -404,6 +406,114 @@ static int sm2_sig_test(void) return testresult; } +static EC_KEY* create_EC_key(EC_GROUP *group, const char *prv_hex, const char *x_hex, const char *y_hex) +{ + BIGNUM *prv = NULL; + BIGNUM *x = NULL; + BIGNUM *y = NULL; + EC_KEY *key = NULL; + + if (!TEST_true(BN_hex2bn(&prv, prv_hex)) + || !TEST_true(BN_hex2bn(&x, x_hex)) + || !TEST_true(BN_hex2bn(&y, y_hex))) + goto err; + + if (!TEST_ptr(key = EC_KEY_new()) + || !TEST_true(EC_KEY_set_group(key, group)) + || !TEST_true(EC_KEY_set_private_key(key, prv)) + || !TEST_true(EC_KEY_set_public_key_affine_coordinates(key, x, y))) { + EC_KEY_free(key); + key = NULL; + } + +err: + BN_free(prv); + BN_free(x); + BN_free(y); + + return key; +} + +static int sm2_key_exchange_test(void) +{ + const char *userA = "ALICE123@YAHOO.COM"; + const char *userB = "BILL456@YAHOO.COM"; + const char *privA_hex = "6FCBA2EF9AE0AB902BC3BDE3FF915D44BA4CC78F88E2F8E7F8996D3B8CCEEDEE"; + const char *pubA_x_hex = "3099093BF3C137D8FCBBCDF4A2AE50F3B0F216C3122D79425FE03A45DBFE1655"; + const char *pubA_y_hex = "3DF79E8DAC1CF0ECBAA2F2B49D51A4B387F2EFAF482339086A27A8E05BAED98B"; + const char *privB_hex = "5E35D7D3F3C54DBAC72E61819E730B019A84208CA3A35E4C2E353DFCCB2A3B53"; + const char *pubB_x_hex = "245493D446C38D8CC0F118374690E7DF633A8A4BFB3329B5ECE604B2B4F37F43"; + const char *pubB_y_hex = "53C0869F4B9E17773DE68FEC45E14904E0DEA45BF6CECF9918C85EA047C60A4C"; + const char *ra = "83A2C9C8B96E5AF70BD480B472409A9A327257F1EBB73F5B073354B248668563"; + const char *x1 = "6CB5633816F4DD560B1DEC458310CBCC6856C09505324A6D23150C408F162BF0"; + const char *y1 = "0D6FCF62F1036C0A1B6DACCF57399223A65F7D7BF2D9637E5BBBEB857961BF1A"; + const char *rb = "33FE21940342161C55619C4A0C060293D543C80AF19748CE176D83477DE71C80"; + const char *x2 = "1799B2A2C778295300D9A2325C686129B8F2B5337B3DCF4514E8BBC19D900EE5"; + const char *y2 = "54C9288C82733EFDF7808AE7F27D0E732F7C73A7D9AC98B7D8740A91D0DB3CF4"; + + EC_KEY *keyA = NULL; + EC_KEY *keyB = NULL; + EC_KEY *keyRa = NULL; + EC_KEY *keyRb = NULL; + + unsigned char Ka[16]; + unsigned char Kb[16]; + unsigned char K[] = {0x55, 0xB0, 0xAC, 0x62, 0xA6, 0xB9, 0x27, 0xBA, 0x23, 0x70, 0x38, 0x32, 0xC8, 0x53, 0xDE, 0xD4}; + + int ret = 0; + + EC_GROUP *test_group = + create_EC_group + ("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3", + "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498", + "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A", + "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D", + "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2", + "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7", + "1"); + + if (!TEST_ptr(keyA = create_EC_key(test_group, privA_hex, pubA_x_hex, pubA_y_hex)) + || !TEST_ptr(keyB = create_EC_key(test_group, privB_hex, pubB_x_hex, pubB_y_hex))) + goto done; + + if (!TEST_ptr(keyRa = create_EC_key(test_group, ra, x1, y1)) + || !TEST_ptr(keyRb = create_EC_key(test_group, rb, x2, y2))) + goto done; + + ret = SM2_compute_key(Ka, sizeof(Ka), 1, + userB, strlen(userB), userA, strlen(userA), + keyRb, keyRa, + keyB, keyA, + EVP_sm3()); + if (!TEST_int_eq(ret, sizeof(Ka))) { + ret = 0; + goto done; + } + + ret = SM2_compute_key(Kb, sizeof(Kb), 0, + userA, strlen(userA), userB, strlen(userB), + keyRa, keyRb, + keyA, keyB, + EVP_sm3()); + if (!TEST_int_eq(ret, sizeof(Kb))) { + ret = 0; + goto done; + } + + if (!TEST_mem_eq(Ka, sizeof(Ka), K, sizeof(K)) + || !TEST_mem_eq(Kb, sizeof(Kb), K, sizeof(K))) + ret = 0; + +done: + EC_KEY_free(keyA); + EC_KEY_free(keyB); + EC_KEY_free(keyRa); + EC_KEY_free(keyRb); + EC_GROUP_free(test_group); + + return ret; +} + #endif int setup_tests(void) @@ -413,6 +523,7 @@ int setup_tests(void) #else ADD_TEST(sm2_crypt_test); ADD_TEST(sm2_sig_test); + ADD_TEST(sm2_key_exchange_test); #endif return 1; } diff --git a/test/tlcptest.c b/test/tlcptest.c new file mode 100644 index 0000000..7ebf1a2 --- /dev/null +++ b/test/tlcptest.c @@ -0,0 +1,746 @@ +/* + * Copyright 2022 Huawei Technologies Co., Ltd. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <string.h> +#include <openssl/bio.h> +#include <openssl/crypto.h> +#include <openssl/ssl.h> +#include <openssl/err.h> + +#include "internal/nelem.h" +#include "ssltestlib.h" +#include "testutil.h" + +#ifndef OPENSSL_NO_TLCP + +typedef enum { + IDX_SM2_ROOT_CERT = 0, + IDX_SM2_SERVER_SIG_CERT, + IDX_SM2_SERVER_SIG_KEY, + IDX_SM2_SERVER_ENC_CERT, + IDX_SM2_SERVER_ENC_KEY, + IDX_SM2_CLIENT_SIG_CERT, + IDX_SM2_CLIENT_SIG_KEY, + IDX_SM2_CLIENT_ENC_CERT, + IDX_SM2_CLIENT_ENC_KEY, + IDX_ECDSA_ROOT_CERT, + IDX_ECDSA_SERVER_CERT, + IDX_ECDSA_SERVER_KEY, + IDX_ECDSA_CLIENT_CERT, + IDX_ECDSA_CLIENT_KEY, + IDX_MAX +} TEST_FILES_IDX; + +#define OPTION_IS_CA 0x00000001U +#define OPTION_IS_CERT 0x00000002U +#define OPTION_IS_KEY 0x00000004U +#define OPTION_USE_NEWAPI 0x00000008U +#define OPTION_USE_EXTRA 0x00000010U +#define OPTION_IS_SIG 0x00000020U +#define OPTION_IS_ENC 0x00000040U + +typedef struct { + TEST_FILES_IDX idx; + int flag; +} LOAD_OPTION; + +typedef struct { + const char *method_name; + const char *sid_ctx; + int verify_mode; + int ssl_options; + int set_version; + LOAD_OPTION load_options[IDX_MAX]; +} SSL_CTX_OPTION; +typedef struct { + const char *case_name; + SSL_CTX_OPTION server; + SSL_CTX_OPTION client; + const char *ciphersuite; + const char *expected_version; + const char *expected_cipher; + int regenotiate; + int reuse_session; +} TLCP_TEST_CASE; + +static const TLCP_TEST_CASE tlcp_test_cases[] = { + { "test_ecc_and_cert_position", + { + "TLS_server", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + { + "TLCP_client", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + "ECC-SM4-CBC-SM3", + "TLCP", + "ECC-SM4-CBC-SM3", + 0, 0 + }, + { "test_extra_cert", + { + "TLS_server", NULL, SSL_VERIFY_NONE, 0, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA | OPTION_USE_EXTRA}, + {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + { + "TLCP_client", NULL, SSL_VERIFY_NONE, 0, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA | OPTION_USE_EXTRA}, + {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + "ECC-SM4-CBC-SM3", + "TLCP", + "ECC-SM4-CBC-SM3", + 0, 0 + }, + { "test_ssl_op_no", + { + "TLS_server", NULL, SSL_VERIFY_PEER, SSL_OP_NO_TLSv1_3 | SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1 | SSL_OP_NO_SSLv3, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + { + "TLS_client", NULL, SSL_VERIFY_PEER, SSL_OP_NO_TLSv1_3 | SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1 | SSL_OP_NO_SSLv3, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + "ECC-SM4-CBC-SM3", + "TLCP", + "ECC-SM4-CBC-SM3", + 0, 0 + }, + { "test_set_version_bound", + { + "TLCP_server", NULL, SSL_VERIFY_PEER, 0, TLCP_VERSION, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + { + "TLS_client", NULL, SSL_VERIFY_PEER, 0, TLCP_VERSION, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + NULL, + "TLCP", + "ECC-SM4-CBC-SM3", + 0, 0 + }, + { "test_use_old_api_and_other_certs", + { + "TLS_server", NULL, SSL_VERIFY_PEER, 0, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_SERVER_SIG_CERT, OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_SERVER_SIG_KEY, OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_SERVER_ENC_CERT, OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_SERVER_ENC_KEY, OPTION_IS_ENC | OPTION_IS_KEY }, + {IDX_ECDSA_ROOT_CERT, OPTION_IS_CA}, + {IDX_ECDSA_SERVER_CERT, OPTION_IS_CERT}, + {IDX_ECDSA_SERVER_KEY, OPTION_IS_KEY} + } + }, + { + "TLCP_client", NULL, SSL_VERIFY_PEER, 0, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_CLIENT_SIG_CERT, OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_SIG_KEY, OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_CLIENT_ENC_CERT, OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_ENC_KEY, OPTION_IS_ENC | OPTION_IS_KEY }, + {IDX_ECDSA_ROOT_CERT, OPTION_IS_CA}, + {IDX_ECDSA_CLIENT_CERT, OPTION_IS_CERT}, + {IDX_ECDSA_CLIENT_KEY, OPTION_IS_KEY} + } + }, + NULL, + "TLCP", + "ECC-SM4-CBC-SM3", + 0, 0 + }, + { "test_sm2dhe_and_cert_position", + { + "TLS_server", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + { + "TLCP_client", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + "ECDHE-SM4-CBC-SM3", + "TLCP", + "ECDHE-SM4-CBC-SM3", + 0, 0 + }, + { "test_ecc_regenotiate", + { + "TLS_server", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + { + "TLCP_client", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + "ECC-SM4-CBC-SM3", + "TLCP", + "ECC-SM4-CBC-SM3", + 1, 0 + }, + { "test_sm2dhe_regenotiate", + { + "TLS_server", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + { + "TLCP_client", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + "ECDHE-SM4-CBC-SM3", + "TLCP", + "ECDHE-SM4-CBC-SM3", + 1, 0 + }, + { "test_ecc_reused_sessionid", + { + "TLS_server", "TEST", SSL_VERIFY_PEER, SSL_OP_NO_TICKET | SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + { + "TLCP_client", NULL, SSL_VERIFY_PEER, SSL_OP_NO_TICKET | SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + "ECC-SM4-CBC-SM3", + "TLCP", + "ECC-SM4-CBC-SM3", + 0, 1 + }, + { "test_sm2dhe_reused_sessionid", + { + "TLS_server", "TEST", SSL_VERIFY_PEER, SSL_OP_NO_TICKET | SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + { + "TLCP_client", NULL, SSL_VERIFY_PEER, SSL_OP_NO_TICKET | SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + "ECDHE-SM4-CBC-SM3", + "TLCP", + "ECDHE-SM4-CBC-SM3", + 0, 1 + }, + { "test_ecc_reused_ticket", + { + "TLS_server", NULL, SSL_VERIFY_NONE, SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + { + "TLCP_client", NULL, SSL_VERIFY_NONE, SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + "ECC-SM4-CBC-SM3", + "TLCP", + "ECC-SM4-CBC-SM3", + 0, 1 + }, + { "test_sm2dhe_reused_ticket", + { + "TLS_server", NULL, SSL_VERIFY_NONE, SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + { + "TLCP_client", NULL, SSL_VERIFY_NONE, SSL_OP_ENCCERT_SECOND_POSITION, 0, + { + {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, + {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, + {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, + {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } + } + }, + "ECDHE-SM4-CBC-SM3", + "TLCP", + "ECDHE-SM4-CBC-SM3", + 0, 1 + }, +}; + +static const char *test_files[IDX_MAX]; + +static X509 *PEM_file_to_X509(const char *file) +{ + BIO *in; + X509 *x = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL || BIO_read_filename(in, file) <= 0) + goto err; + + x = PEM_read_bio_X509(in, NULL, NULL, NULL); +err: + BIO_free(in); + return x; +} + +static EVP_PKEY *PEM_file_to_PrivateKey(const char *file) +{ + BIO *in; + EVP_PKEY *pkey = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL || BIO_read_filename(in, file) <= 0) + goto err; + + pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL); +err: + BIO_free(in); + return pkey; +} + +static int use_extra_cert_file(SSL_CTX *ctx, const char *file) +{ + X509 *x; + + x = PEM_file_to_X509(file); + + if (x == NULL) + return 0; + + if (!SSL_CTX_add_extra_chain_cert(ctx, x)) { + X509_free(x); + return 0; + } + return 1; +} + +static int load_test_file_by_option(SSL_CTX *ctx, LOAD_OPTION opt) +{ + int usage = -1; + if (opt.idx >= IDX_MAX) + return 0; + + if (opt.flag & OPTION_IS_CA) { + return (opt.flag & OPTION_USE_EXTRA) + ? use_extra_cert_file(ctx, test_files[opt.idx]) + : SSL_CTX_load_verify_locations(ctx, test_files[opt.idx], NULL); + } + + if (opt.flag & OPTION_IS_SIG) { + usage = SSL_USAGE_SIG; + } else if (opt.flag & OPTION_IS_ENC) { + usage = SSL_USAGE_ENC; + } + + if (opt.flag & OPTION_IS_CERT) { + return (opt.flag & OPTION_USE_NEWAPI) + ? SSL_CTX_use_gm_certificate_file(ctx, test_files[opt.idx], SSL_FILETYPE_PEM, usage) + : SSL_CTX_use_certificate_file(ctx, test_files[opt.idx], SSL_FILETYPE_PEM); + } else if (opt.flag & OPTION_IS_KEY){ + return (opt.flag & OPTION_USE_NEWAPI) + ? SSL_CTX_use_gm_PrivateKey_file(ctx, test_files[opt.idx], SSL_FILETYPE_PEM, usage) + : SSL_CTX_use_PrivateKey_file(ctx, test_files[opt.idx], SSL_FILETYPE_PEM); + } + return 1; +} + +static int load_test_files(SSL_CTX *ctx, LOAD_OPTION *opt, size_t optlen) +{ + int i; + for (i = 0; i < optlen; ++i) { + if (!load_test_file_by_option(ctx, opt[i])) { + return 0; + } + } + return 1; +} + +static SSL_CTX *SSL_CTX_create_by_option(const SSL_CTX_OPTION *opt) +{ + SSL_CTX *ctx = NULL; + if (opt == NULL) + return NULL; + + if (strcmp(opt->method_name, "TLS_server") == 0) { + ctx = SSL_CTX_new(TLS_server_method()); + } else if (strcmp(opt->method_name, "TLS_client") == 0) { + ctx = SSL_CTX_new(TLS_client_method()); + } else if (strcmp(opt->method_name, "TLCP_server") == 0) { + ctx = SSL_CTX_new(TLCP_server_method()); + } else if (strcmp(opt->method_name, "TLCP_client") == 0) { + ctx = SSL_CTX_new(TLCP_client_method()); + } + if (ctx == NULL) + return NULL; + + SSL_CTX_set_verify(ctx, opt->verify_mode, NULL); + SSL_CTX_set_options(ctx, opt->ssl_options); + SSL_CTX_set_min_proto_version(ctx, opt->set_version); + SSL_CTX_set_max_proto_version(ctx, opt->set_version); + + if (opt->sid_ctx + && SSL_CTX_set_session_id_context(ctx, (unsigned char*)opt->sid_ctx, strlen(opt->sid_ctx)) != 1) { + SSL_CTX_free(ctx); + return NULL; + } + + if (!load_test_files(ctx, (LOAD_OPTION *)opt->load_options, OSSL_NELEM(opt->load_options))) { + SSL_CTX_free(ctx); + return NULL; + } + return ctx; +} + +static int test_tlcp_regenotiate(SSL *server_ssl, SSL *client_ssl) +{ + SSL_SESSION *sess_pre; + SSL_SESSION *sess_post; + + if (!TEST_ptr(sess_pre = SSL_get0_session(server_ssl))) + return 0; + + if (!TEST_int_eq(SSL_renegotiate(client_ssl), 1) + || !TEST_int_eq(SSL_renegotiate_pending(client_ssl), 1)) + return 0; + + for (int i = 0; i < 3; i++) { + unsigned char buf; + size_t readbytes; + int ret = SSL_read_ex(client_ssl, &buf, sizeof(buf), &readbytes); + if ((ret > 0 && !TEST_ulong_eq(readbytes, 0)) + || (ret <= 0 && !TEST_int_eq(SSL_get_error(client_ssl, 0), SSL_ERROR_WANT_READ))) { + return 0; + } + + ret = SSL_read_ex(server_ssl, &buf, sizeof(buf), &readbytes); + if ((ret > 0 && !TEST_ulong_eq(readbytes, 0)) + || (ret <= 0 && SSL_get_error(server_ssl, 0) != SSL_ERROR_WANT_READ)) { + if (!strcmp("ECDHE-SM4-CBC-SM3", SSL_CIPHER_get_name(SSL_get_current_cipher(client_ssl)))) + return 1; + return 0; + } + } + + if (!TEST_false(SSL_renegotiate_pending(client_ssl)) + || !TEST_int_eq(SSL_session_reused(client_ssl), 0) + || !TEST_int_eq(SSL_session_reused(server_ssl), 0) + || !TEST_ptr(sess_post = SSL_get0_session(server_ssl)) + || !TEST_ptr_ne(sess_pre, sess_post)) + return 0; + + return 1; +} + +static int test_tlcp_reuse_session(SSL **p_server_ssl, SSL **p_client_ssl) +{ + int ret = 0; + SSL *server_ssl = *p_server_ssl; + SSL *client_ssl = *p_client_ssl; + SSL_CTX *server_ctx; + SSL_CTX *client_ctx; + SSL_SESSION *sess_pre; + SSL_SESSION *sess_post; + SSL_SESSION *sess; + const unsigned char *sess_pre_id; + unsigned int sess_pre_id_len; + const unsigned char *sess_post_id; + unsigned int sess_post_id_len; + const char *ciph_name = SSL_CIPHER_get_name(SSL_get_current_cipher(client_ssl)); + + if (!TEST_ptr(server_ctx = SSL_get_SSL_CTX(server_ssl)) + || !TEST_ptr(client_ctx = SSL_get_SSL_CTX(client_ssl))) + return 0; + + if (!TEST_ptr(sess_pre = SSL_get0_session(server_ssl))) + return 0; + + if (!TEST_ptr(sess = SSL_get1_session(client_ssl))) + return 0; + + shutdown_ssl_connection(server_ssl, client_ssl); + *p_server_ssl = NULL; + *p_client_ssl = NULL; + + if (!TEST_int_eq(create_ssl_objects(server_ctx, client_ctx, p_server_ssl, p_client_ssl, NULL, NULL), 1)) + goto out; + + server_ssl = *p_server_ssl; + client_ssl = *p_client_ssl; + + if (!TEST_int_eq(SSL_set_session(client_ssl, sess), 1)) + goto out; + + if (!TEST_int_eq(create_ssl_connection(server_ssl, client_ssl, SSL_ERROR_NONE), 1)) + goto out; + + if (!TEST_int_eq(SSL_session_reused(client_ssl), 1) + || !TEST_int_eq(SSL_session_reused(server_ssl), 1)) + goto out; + + if (!TEST_ptr(sess_post = SSL_get0_session(server_ssl)) + || !TEST_str_eq(ciph_name, SSL_CIPHER_get_name(SSL_get_current_cipher(client_ssl)))) + goto out; + + if ((SSL_get_options(client_ssl) & SSL_OP_NO_TICKET) && (SSL_get_options(server_ssl) & SSL_OP_NO_TICKET) + && !TEST_ptr_eq(sess_pre, sess_post)) + goto out; + + sess_post_id = SSL_SESSION_get_id(sess_post, &sess_post_id_len); + sess_pre_id = SSL_SESSION_get_id(sess, &sess_pre_id_len); + + if (!TEST_mem_eq(sess_pre_id, sess_pre_id_len, sess_post_id, sess_post_id_len)) + goto out; + + ret = 1; + +out: + SSL_SESSION_free(sess); + + return ret; +} + +static int test_tlcp_ciphersuites(int idx) +{ + int result = 0; + SSL_CTX *server_ctx = NULL; + SSL_CTX *client_ctx = NULL; + SSL *server_ssl = NULL; + SSL *client_ssl = NULL; + const TLCP_TEST_CASE *case_ptr; + + case_ptr = &tlcp_test_cases[idx]; + if (!TEST_ptr(server_ctx = SSL_CTX_create_by_option(&case_ptr->server)) + || !TEST_ptr(client_ctx = SSL_CTX_create_by_option(&case_ptr->client))) + goto err; + + if (case_ptr->ciphersuite != NULL && + !TEST_int_eq(SSL_CTX_set_cipher_list(client_ctx, case_ptr->ciphersuite), 1)) + goto err; + + if (!TEST_int_eq(create_ssl_objects(server_ctx, client_ctx + , &server_ssl, &client_ssl, NULL, NULL), 1)) + goto err; + + if (!TEST_int_eq(create_ssl_connection(server_ssl, client_ssl, SSL_ERROR_NONE), 1)) + goto err; + + if (case_ptr->expected_version != NULL && + !TEST_str_eq(SSL_get_version(client_ssl), case_ptr->expected_version)) + goto err; + + if (case_ptr->expected_cipher && + !TEST_str_eq(SSL_get_cipher(client_ssl), case_ptr->expected_cipher)) + goto err; + + if (case_ptr->regenotiate + && !TEST_int_eq(test_tlcp_regenotiate(server_ssl, client_ssl), 1)) + goto err; + + if (case_ptr->reuse_session + && !TEST_int_eq(test_tlcp_reuse_session(&server_ssl, &client_ssl), 1)) + goto err; + + result = 1; +err: + if (server_ssl != NULL) + SSL_shutdown(server_ssl); + if (client_ssl != NULL) + SSL_shutdown(client_ssl); + SSL_free(server_ssl); + SSL_free(client_ssl); + SSL_CTX_free(server_ctx); + SSL_CTX_free(client_ctx); + return result; +} + +static int test_use_certs_and_keys(void) +{ + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + X509 *x = NULL; + EVP_PKEY *pkey = NULL; + int result = 0; + + ctx = SSL_CTX_new(TLCP_method()); + if (ctx == NULL) + goto err; + + ssl = SSL_new(ctx); + if (ssl == NULL) + goto err; + + if (!TEST_int_ne(SSL_use_gm_certificate_file(ssl, test_files[IDX_ECDSA_SERVER_CERT], + SSL_FILETYPE_PEM, SSL_USAGE_SIG), 1) + || !TEST_int_ne(SSL_use_gm_PrivateKey_file(ssl, test_files[IDX_ECDSA_CLIENT_KEY], + SSL_FILETYPE_PEM, SSL_USAGE_SIG), 1)) { + goto err; + } + + if (!TEST_int_eq(SSL_use_certificate_file(ssl, test_files[IDX_SM2_SERVER_SIG_CERT], + SSL_FILETYPE_PEM), 1) + || !TEST_int_eq(SSL_use_gm_PrivateKey_file(ssl, test_files[IDX_SM2_SERVER_SIG_KEY], + SSL_FILETYPE_PEM, SSL_USAGE_SIG), 1) + || !TEST_int_eq(SSL_use_gm_certificate_file(ssl, test_files[IDX_SM2_SERVER_ENC_CERT], + SSL_FILETYPE_PEM, SSL_USAGE_ENC), 1) + || !TEST_int_eq(SSL_use_PrivateKey_file(ssl, test_files[IDX_SM2_SERVER_ENC_KEY], + SSL_FILETYPE_PEM), 1)){ + goto err; + } + + if (!TEST_ptr(x = PEM_file_to_X509(test_files[IDX_SM2_CLIENT_SIG_CERT])) + || !TEST_ptr(pkey = PEM_file_to_PrivateKey(test_files[IDX_SM2_CLIENT_SIG_KEY])) + || !TEST_int_eq(SSL_use_gm_cert_and_key(ssl, x, pkey, NULL, 1, SSL_USAGE_SIG), 1)) { + goto err; + } + result = 1; +err: + X509_free(x); + + EVP_PKEY_free(pkey); + SSL_free(ssl); + SSL_CTX_free(ctx); + return result; +} + +#endif + +int setup_tests(void) +{ +#ifndef OPENSSL_NO_TLCP + int argc; + + for (argc = 0; argc < IDX_MAX; ++argc) { + if (!TEST_ptr(test_files[argc] = test_get_argument(argc))) { + return 0; + } + } + + ADD_ALL_TESTS(test_tlcp_ciphersuites, OSSL_NELEM(tlcp_test_cases)); + ADD_TEST(test_use_certs_and_keys); +#endif + return 1; +} diff --git a/util/libcrypto.num b/util/libcrypto.num index 81a6388..95bccf9 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4630,3 +4630,5 @@ X509_set0_sm2_id 6383 1_1_1m EXIST::FUNCTION:SM2 X509_get0_sm2_id 6384 1_1_1m EXIST::FUNCTION:SM2 X509_REQ_get0_sm2_id 6385 1_1_1m EXIST::FUNCTION:SM2 X509_REQ_set0_sm2_id 6386 1_1_1m EXIST::FUNCTION:SM2 +EVP_PKEY_is_sm2 6387 1_1_1m EXIST::FUNCTION:SM2 +SM2_compute_key 6388 1_1_1m EXIST::FUNCTION: diff --git a/util/libssl.num b/util/libssl.num index 297522c..f120bed 100644 --- a/util/libssl.num +++ b/util/libssl.num @@ -498,3 +498,20 @@ SSL_CTX_get_recv_max_early_data 498 1_1_1 EXIST::FUNCTION: SSL_CTX_set_recv_max_early_data 499 1_1_1 EXIST::FUNCTION: SSL_CTX_set_post_handshake_auth 500 1_1_1 EXIST::FUNCTION: SSL_get_signature_type_nid 501 1_1_1a EXIST::FUNCTION: +SSL_use_gm_PrivateKey 502 1_1_1m EXIST::FUNCTION:TLCP +SSL_CTX_use_gm_certificate_file 503 1_1_1m EXIST::FUNCTION:TLCP +SSL_CTX_use_gm_certificate 504 1_1_1m EXIST::FUNCTION:TLCP +SSL_use_gm_certificate_file 505 1_1_1m EXIST::FUNCTION:TLCP +SSL_CTX_use_gm_certificate_ASN1 506 1_1_1m EXIST::FUNCTION:TLCP +SSL_use_gm_PrivateKey_file 507 1_1_1m EXIST::FUNCTION:TLCP +TLCP_method 508 1_1_1m EXIST::FUNCTION:TLCP +SSL_CTX_use_gm_PrivateKey_file 509 1_1_1m EXIST::FUNCTION:TLCP +SSL_use_gm_PrivateKey_ASN1 510 1_1_1m EXIST::FUNCTION:TLCP +TLCP_client_method 511 1_1_1m EXIST::FUNCTION:TLCP +SSL_CTX_use_gm_cert_and_key 512 1_1_1m EXIST::FUNCTION:TLCP +SSL_CTX_use_gm_PrivateKey 513 1_1_1m EXIST::FUNCTION:TLCP +TLCP_server_method 514 1_1_1m EXIST::FUNCTION:TLCP +SSL_use_gm_cert_and_key 515 1_1_1m EXIST::FUNCTION:TLCP +SSL_use_gm_certificate 516 1_1_1m EXIST::FUNCTION:TLCP +SSL_use_gm_certificate_ASN1 517 1_1_1m EXIST::FUNCTION:TLCP +SSL_CTX_use_gm_PrivateKey_ASN1 518 1_1_1m EXIST::FUNCTION:TLCP -- 2.20.1 (Apple Git-117)
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2