[openssl] master update

Richard Levitte levitte at openssl.org
Sun Mar 15 18:43:34 UTC 2020


The branch master has been updated
       via  fda127beb2b3c029741573b0dd931295b3446fd2 (commit)
       via  2292c8e17f0b870b48bb7a5f8ed8c37dfb36580f (commit)
       via  aba9bca31cc2507671e25f7ca8e642fce5e38671 (commit)
       via  123c2fef14b80f26f5a8504ccf7b819c2975a6fa (commit)
       via  70a7dd6f96c28a1a3059bf3d175bfb24449202ae (commit)
       via  a5ce329eb496eb7ae17d6198dac51c2ab417550e (commit)
      from  edd3b7a309f8767fc7d8a5c4f7d350b53e144c1b (commit)


- Log -----------------------------------------------------------------
commit fda127beb2b3c029741573b0dd931295b3446fd2
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Mar 10 23:10:29 2020 +0100

    TEST: Adapt all applicable tests to the new distinguishing ID
    
    Fixes #11293
    
    Reviewed-by: Paul Yang <kaishen.yy at antfin.com>
    (Merged from https://github.com/openssl/openssl/pull/11302)

commit 2292c8e17f0b870b48bb7a5f8ed8c37dfb36580f
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Mar 10 23:08:59 2020 +0100

    APPS: Remove all traces of special SM2 treatment.
    
    SM2 IDs are now passed entirely as '-pkeyopt', '-sigopt' or '-vfyopt'
    values, just like any other valid option.
    
    Fixes #11293
    
    Reviewed-by: Paul Yang <kaishen.yy at antfin.com>
    (Merged from https://github.com/openssl/openssl/pull/11302)

commit aba9bca31cc2507671e25f7ca8e642fce5e38671
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Mar 10 23:05:09 2020 +0100

    APPS: Add ctrl_str()-like functionality for X509 and X509_REQ
    
    This should really be part of libcrypto, but since this looks like
    added legacy support, it's preferable to keep it in apps for now.
    
    This allows to build functions that add user given verification
    options to X509 and X509_REQ structures.
    
    Fixes #11293
    
    Reviewed-by: Paul Yang <kaishen.yy at antfin.com>
    (Merged from https://github.com/openssl/openssl/pull/11302)

commit 123c2fef14b80f26f5a8504ccf7b819c2975a6fa
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Mar 10 23:00:45 2020 +0100

    SM2: Make the EVP_PKEY_METHOD ctrl_str function listen to distid
    
    Because we start using Distinguished ID, we also define the key name
    "distid", possibly prefixed with "hex", but keep "sm2_id" and
    "sm2_hex_id" for compatibility with GmSSL.
    
    Fixes #11293
    
    Reviewed-by: Paul Yang <kaishen.yy at antfin.com>
    (Merged from https://github.com/openssl/openssl/pull/11302)

commit 70a7dd6f96c28a1a3059bf3d175bfb24449202ae
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Mar 10 22:50:22 2020 +0100

    X509: Rename X509_set0_sm2_id() and friends
    
    - X509_set0_sm2_id() -> X509_set0_distinguishing_id()
    - X509_get0_sm2_id() -> X509_get0_distinguishing_id()
    - X509_REQ_set0_sm2_id -> X509_REQ_set0_distinguishing_id()
    - X509_REQ_get0_sm2_id -> X509_REQ_get0_distinguishing_id()
    
    The reason for this rename is that the SM2 ID isn't really a unique
    SM2 data item, but rather a re-use of the Distinguished that is
    defined in ISO/IEC 15946-3 as well as in FIPS 196, with no special
    attribution toward any algorithm in particular.
    
    Fixes #11293
    
    Reviewed-by: Paul Yang <kaishen.yy at antfin.com>
    (Merged from https://github.com/openssl/openssl/pull/11302)

commit a5ce329eb496eb7ae17d6198dac51c2ab417550e
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Mar 10 22:07:10 2020 +0100

    EVP: Don't call digest_custom() quite so early
    
    A huge problem with calling digest_custom() already in the
    initialization of DigestSign, DigestVerify etc, is that it force all
    callers to know that certain controls must be performed before Init
    and the rest after.  This has lead to quite interesting hacks in our
    own openssl app, where the SM2 ID had to get special treatment instead
    of just being another sign option or verification option among others.
    
    This change moves the call of digest_custom() to the Update and Final
    functions, to be done exactly once, subject to a flag that's set in
    the Init function.  Seeing to the process of data, through these
    operations, this makes no difference at all.  Seeing to making it
    possible to perform all controls after the Init call, this makes a
    huge difference.
    
    Fixes #11293
    
    Reviewed-by: Paul Yang <kaishen.yy at antfin.com>
    (Merged from https://github.com/openssl/openssl/pull/11302)

-----------------------------------------------------------------------

Summary of changes:
 apps/ca.c                                | 110 +++++-----------
 apps/include/apps.h                      |   5 +
 apps/lib/app_x509.c                      | 134 +++++++++++++++++++
 apps/lib/build.info                      |   2 +-
 apps/pkeyutl.c                           |  16 ---
 apps/req.c                               | 212 ++++++++++++++-----------------
 apps/verify.c                            |  83 ++++--------
 apps/x509.c                              |  29 +++--
 crypto/evp/m_sigver.c                    |  27 +++-
 crypto/sm2/sm2_pmeth.c                   |  10 +-
 crypto/x509/x_all.c                      |  10 +-
 crypto/x509/x_req.c                      |  18 ++-
 crypto/x509/x_x509.c                     |  24 ++--
 doc/man1/openssl-ca.pod.in               |  30 ++---
 doc/man1/openssl-pkeyutl.pod.in          |  12 +-
 doc/man1/openssl-req.pod.in              |  34 ++---
 doc/man1/openssl-verify.pod.in           |  22 +---
 doc/man1/openssl-x509.pod.in             |   8 +-
 doc/man3/X509_get0_distinguishing_id.pod |  71 +++++++++++
 doc/man3/X509_get0_sm2_id.pod            |  55 --------
 include/crypto/evp.h                     |   2 +
 include/crypto/x509.h                    |  12 +-
 include/openssl/x509.h                   |  10 +-
 test/ecdsatest.c                         |  45 ++-----
 test/recipes/20-test_pkeyutl.t           |   4 +-
 test/recipes/25-test_req.t               |   8 +-
 test/recipes/25-test_verify.t            |   6 +-
 test/recipes/80-test_ca.t                |   4 +-
 test/verify_extra_test.c                 |  32 ++---
 util/libcrypto.num                       |   8 +-
 30 files changed, 539 insertions(+), 504 deletions(-)
 create mode 100644 apps/lib/app_x509.c
 create mode 100644 doc/man3/X509_get0_distinguishing_id.pod
 delete mode 100644 doc/man3/X509_get0_sm2_id.pod

diff --git a/apps/ca.c b/apps/ca.c
index e3e2fd2e7e..192e602028 100644
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -89,17 +89,20 @@ typedef enum {
 static char *lookup_conf(const CONF *conf, const char *group, const char *tag);
 
 static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
-                   const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+                   const EVP_MD *dgst,
+                   STACK_OF(OPENSSL_STRING) *sigopts,
+                   STACK_OF(OPENSSL_STRING) *vfyopts,
                    STACK_OF(CONF_VALUE) *policy, CA_DB *db,
                    BIGNUM *serial, const char *subj, unsigned long chtype,
                    int multirdn, int email_dn, const char *startdate,
                    const char *enddate,
                    long days, int batch, const char *ext_sect, CONF *conf,
                    int verbose, unsigned long certopt, unsigned long nameopt,
-                   int default_op, int ext_copy, int selfsign,
-                   unsigned char *sm2_id, size_t sm2idlen);
+                   int default_op, int ext_copy, int selfsign);
 static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
-                        const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+                        const EVP_MD *dgst,
+                        STACK_OF(OPENSSL_STRING) *sigopts,
+                        STACK_OF(OPENSSL_STRING) *vfyopts,
                         STACK_OF(CONF_VALUE) *policy, CA_DB *db,
                         BIGNUM *serial, const char *subj, unsigned long chtype,
                         int multirdn, int email_dn, const char *startdate,
@@ -142,13 +145,13 @@ typedef enum OPTION_choice {
     OPT_ENGINE, OPT_VERBOSE, OPT_CONFIG, OPT_NAME, OPT_SUBJ, OPT_UTF8,
     OPT_CREATE_SERIAL, OPT_MULTIVALUE_RDN, OPT_STARTDATE, OPT_ENDDATE,
     OPT_DAYS, OPT_MD, OPT_POLICY, OPT_KEYFILE, OPT_KEYFORM, OPT_PASSIN,
-    OPT_KEY, OPT_CERT, OPT_SELFSIGN, OPT_IN, OPT_OUT, OPT_OUTDIR,
+    OPT_KEY, OPT_CERT, OPT_SELFSIGN, OPT_IN, OPT_OUT, OPT_OUTDIR, OPT_VFYOPT,
     OPT_SIGOPT, OPT_NOTEXT, OPT_BATCH, OPT_PRESERVEDN, OPT_NOEMAILDN,
     OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC,
     OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID,
     OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS,
     OPT_RAND_SERIAL,
-    OPT_R_ENUM, OPT_SM2ID, OPT_SM2HEXID, OPT_PROV_ENUM,
+    OPT_R_ENUM, OPT_PROV_ENUM,
     /* Do not change the order here; see related case statements below */
     OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, OPT_CRL_CA_COMPROMISE
 } OPTION_CHOICE;
@@ -197,12 +200,6 @@ const OPTIONS ca_options[] = {
      "Extension section (override value in config file)"},
     {"extfile", OPT_EXTFILE, '<',
      "Configuration file with X509v3 extensions to add"},
-#ifndef OPENSSL_NO_SM2
-    {"sm2-id", OPT_SM2ID, 's',
-     "Specify an ID string to verify an SM2 certificate request"},
-    {"sm2-hex-id", OPT_SM2HEXID, 's',
-     "Specify a hex ID string to verify an SM2 certificate request"},
-#endif
     {"preserveDN", OPT_PRESERVEDN, '-', "Don't re-order the DN"},
     {"noemailDN", OPT_NOEMAILDN, '-', "Don't add the EMAIL field to the DN"},
 
@@ -216,6 +213,7 @@ const OPTIONS ca_options[] = {
     {"selfsign", OPT_SELFSIGN, '-',
      "Sign a cert with the key associated with it"},
     {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
+    {"vfyopt", OPT_SIGOPT, 's', "Verification parameter in n:v form"},
 
     OPT_SECTION("Revocation"),
     {"gencrl", OPT_GENCRL, '-', "Generate a new CRL"},
@@ -257,7 +255,7 @@ int ca_main(int argc, char **argv)
     CA_DB *db = NULL;
     DB_ATTR db_attr;
     STACK_OF(CONF_VALUE) *attribs = NULL;
-    STACK_OF(OPENSSL_STRING) *sigopts = NULL;
+    STACK_OF(OPENSSL_STRING) *sigopts = NULL, *vfyopts = NULL;
     STACK_OF(X509) *cert_sk = NULL;
     X509_CRL *crl = NULL;
     const EVP_MD *dgst = NULL;
@@ -286,9 +284,6 @@ int ca_main(int argc, char **argv)
     REVINFO_TYPE rev_type = REV_NONE;
     X509_REVOKED *r = NULL;
     OPTION_CHOICE o;
-    unsigned char *sm2_id = NULL;
-    size_t sm2_idlen = 0;
-    int sm2_free = 0;
 
     prog = opt_init(argc, argv, ca_options);
     while ((o = opt_next()) != OPT_EOF) {
@@ -385,6 +380,12 @@ opthelp:
             if (sigopts == NULL || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
                 goto end;
             break;
+        case OPT_VFYOPT:
+            if (vfyopts == NULL)
+                vfyopts = sk_OPENSSL_STRING_new_null();
+            if (vfyopts == NULL || !sk_OPENSSL_STRING_push(vfyopts, opt_arg()))
+                goto end;
+            break;
         case OPT_NOTEXT:
             notext = 1;
             break;
@@ -456,30 +457,6 @@ opthelp:
         case OPT_ENGINE:
             e = setup_engine(opt_arg(), 0);
             break;
-        case OPT_SM2ID:
-            /* we assume the input is not a hex string */
-            if (sm2_id != NULL) {
-                BIO_printf(bio_err,
-                           "Use one of the options 'sm2-hex-id' or 'sm2-id'\n");
-                goto end;
-            }
-            sm2_id = (unsigned char *)opt_arg();
-            sm2_idlen = strlen((const char *)sm2_id);
-            break;
-        case OPT_SM2HEXID:
-            /* try to parse the input as hex string first */
-            if (sm2_id != NULL) {
-                BIO_printf(bio_err,
-                           "Use one of the options 'sm2-hex-id' or 'sm2-id'\n");
-                goto end;
-            }
-            sm2_free = 1;
-            sm2_id = OPENSSL_hexstr2buf(opt_arg(), (long *)&sm2_idlen);
-            if (sm2_id == NULL) {
-                BIO_printf(bio_err, "Invalid hex string input\n");
-                goto end;
-            }
-            break;
         }
     }
 end_of_options:
@@ -944,8 +921,8 @@ end_of_options:
         }
         if (ss_cert_file != NULL) {
             total++;
-            j = certify_cert(&x, ss_cert_file, pkey, x509, dgst, sigopts,
-                             attribs,
+            j = certify_cert(&x, ss_cert_file, pkey, x509, dgst,
+                             sigopts, vfyopts, attribs,
                              db, serial, subj, chtype, multirdn, email_dn,
                              startdate, enddate, days, batch, extensions,
                              conf, verbose, certopt, get_nameopt(), default_op,
@@ -965,11 +942,11 @@ end_of_options:
         }
         if (infile != NULL) {
             total++;
-            j = certify(&x, infile, pkey, x509p, dgst, sigopts, attribs, db,
+            j = certify(&x, infile, pkey, x509p, dgst, sigopts, vfyopts,
+                        attribs, db,
                         serial, subj, chtype, multirdn, email_dn, startdate,
                         enddate, days, batch, extensions, conf, verbose,
-                        certopt, get_nameopt(), default_op, ext_copy, selfsign,
-                        sm2_id, sm2_idlen);
+                        certopt, get_nameopt(), default_op, ext_copy, selfsign);
             if (j < 0)
                 goto end;
             if (j > 0) {
@@ -985,11 +962,11 @@ end_of_options:
         }
         for (i = 0; i < argc; i++) {
             total++;
-            j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, attribs, db,
+            j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, vfyopts,
+                        attribs, db,
                         serial, subj, chtype, multirdn, email_dn, startdate,
                         enddate, days, batch, extensions, conf, verbose,
-                        certopt, get_nameopt(), default_op, ext_copy, selfsign,
-                        sm2_id, sm2_idlen);
+                        certopt, get_nameopt(), default_op, ext_copy, selfsign);
             if (j < 0)
                 goto end;
             if (j > 0) {
@@ -1287,8 +1264,6 @@ end_of_options:
     ret = 0;
 
  end:
-    if (sm2_free)
-        OPENSSL_free(sm2_id);
     if (ret)
         ERR_print_errors(bio_err);
     BIO_free_all(Sout);
@@ -1302,6 +1277,7 @@ end_of_options:
     BN_free(crlnumber);
     free_index(db);
     sk_OPENSSL_STRING_free(sigopts);
+    sk_OPENSSL_STRING_free(vfyopts);
     EVP_PKEY_free(pkey);
     X509_free(x509);
     X509_CRL_free(crl);
@@ -1320,15 +1296,16 @@ static char *lookup_conf(const CONF *conf, const char *section, const char *tag)
 }
 
 static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
-                   const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+                   const EVP_MD *dgst,
+                   STACK_OF(OPENSSL_STRING) *sigopts,
+                   STACK_OF(OPENSSL_STRING) *vfyopts,
                    STACK_OF(CONF_VALUE) *policy, CA_DB *db,
                    BIGNUM *serial, const char *subj, unsigned long chtype,
                    int multirdn, int email_dn, const char *startdate,
                    const char *enddate,
                    long days, int batch, const char *ext_sect, CONF *lconf,
                    int verbose, unsigned long certopt, unsigned long nameopt,
-                   int default_op, int ext_copy, int selfsign,
-                   unsigned char *sm2id, size_t sm2idlen)
+                   int default_op, int ext_copy, int selfsign)
 {
     X509_REQ *req = NULL;
     BIO *in = NULL;
@@ -1360,26 +1337,7 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
         BIO_printf(bio_err, "error unpacking public key\n");
         goto end;
     }
-    if (sm2id != NULL) {
-#ifndef OPENSSL_NO_SM2
-        ASN1_OCTET_STRING *v;
-
-        v = ASN1_OCTET_STRING_new();
-        if (v == NULL) {
-            BIO_printf(bio_err, "error: SM2 ID allocation failed\n");
-            goto end;
-        }
-
-        if (!ASN1_OCTET_STRING_set(v, sm2id, sm2idlen)) {
-            BIO_printf(bio_err, "error: setting SM2 ID failed\n");
-            ASN1_OCTET_STRING_free(v);
-            goto end;
-        }
-
-        X509_REQ_set0_sm2_id(req, v);
-#endif
-    }
-    i = X509_REQ_verify(req, pktmp);
+    i = do_X509_REQ_verify(req, pktmp, vfyopts);
     pktmp = NULL;
     if (i < 0) {
         ok = 0;
@@ -1409,7 +1367,9 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
 }
 
 static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
-                        const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+                        const EVP_MD *dgst,
+                        STACK_OF(OPENSSL_STRING) *sigopts,
+                        STACK_OF(OPENSSL_STRING) *vfyopts,
                         STACK_OF(CONF_VALUE) *policy, CA_DB *db,
                         BIGNUM *serial, const char *subj, unsigned long chtype,
                         int multirdn, int email_dn, const char *startdate,
@@ -1433,7 +1393,7 @@ static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x
         BIO_printf(bio_err, "error unpacking public key\n");
         goto end;
     }
-    i = X509_verify(req, pktmp);
+    i = do_X509_verify(req, pktmp, vfyopts);
     if (i < 0) {
         ok = 0;
         BIO_printf(bio_err, "Signature verification problems....\n");
diff --git a/apps/include/apps.h b/apps/include/apps.h
index 78be647619..de068d9670 100644
--- a/apps/include/apps.h
+++ b/apps/include/apps.h
@@ -197,12 +197,17 @@ X509_NAME *parse_name(const char *str, long chtype, int multirdn);
 void policies_print(X509_STORE_CTX *ctx);
 int bio_to_mem(unsigned char **out, int maxlen, BIO *in);
 int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value);
+int x509_ctrl_string(X509 *x, const char *value);
+int x509_req_ctrl_string(X509_REQ *x, const char *value);
 int init_gen_str(EVP_PKEY_CTX **pctx,
                  const char *algname, ENGINE *e, int do_param);
 int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
                  STACK_OF(OPENSSL_STRING) *sigopts);
+int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts);
 int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
                      STACK_OF(OPENSSL_STRING) *sigopts);
+int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey,
+                       STACK_OF(OPENSSL_STRING) *vfyopts);
 int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
                      STACK_OF(OPENSSL_STRING) *sigopts);
 
diff --git a/apps/lib/app_x509.c b/apps/lib/app_x509.c
new file mode 100644
index 0000000000..89c5960fa6
--- /dev/null
+++ b/apps/lib/app_x509.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (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 "apps.h"
+
+/*
+ * X509_ctrl_str() is sorely lacking in libcrypto, but is still needed to
+ * allow the application to process verification options in a manner similar
+ * to signature or other options that pass through EVP_PKEY_CTX_ctrl_str(),
+ * for uniformity.
+ *
+ * As soon as more stuff is added, the code will need serious rework.  For
+ * the moment, it only handles the FIPS 196 / SM2 distinguishing ID.
+ */
+#ifdef EVP_PKEY_CTRL_SET1_ID
+static ASN1_OCTET_STRING *mk_octet_string(void *value, size_t value_n)
+{
+    ASN1_OCTET_STRING *v = ASN1_OCTET_STRING_new();
+
+    if (v == NULL) {
+        BIO_printf(bio_err, "error: allocation failed\n");
+    } else if (!ASN1_OCTET_STRING_set(v, value, value_n)) {
+        ASN1_OCTET_STRING_free(v);
+        v = NULL;
+    }
+    return v;
+}
+#endif
+
+static int x509_ctrl(void *object, int cmd, void *value, size_t value_n)
+{
+    switch (cmd) {
+#ifdef EVP_PKEY_CTRL_SET1_ID
+    case EVP_PKEY_CTRL_SET1_ID:
+        {
+            ASN1_OCTET_STRING *v = mk_octet_string(value, value_n);
+
+            if (v == NULL) {
+                BIO_printf(bio_err,
+                           "error: setting distinguishing ID in certificate failed\n");
+                return 0;
+            }
+
+            X509_set0_distinguishing_id(object, v);
+            return 1;
+        }
+#endif
+    default:
+        break;
+    }
+    return -2;     /* typical EVP_PKEY return for "unsupported" */
+}
+
+static int x509_req_ctrl(void *object, int cmd, void *value, size_t value_n)
+{
+    switch (cmd) {
+#ifdef EVP_PKEY_CTRL_SET1_ID
+    case EVP_PKEY_CTRL_SET1_ID:
+        {
+            ASN1_OCTET_STRING *v = mk_octet_string(value, value_n);
+
+            if (v == NULL) {
+                BIO_printf(bio_err,
+                           "error: setting distinguishing ID in certificate signing request failed\n");
+                return 0;
+            }
+
+            X509_REQ_set0_distinguishing_id(object, v);
+            return 1;
+        }
+#endif
+    default:
+        break;
+    }
+    return -2;     /* typical EVP_PKEY return for "unsupported" */
+}
+
+static int do_x509_ctrl_string(int (*ctrl)(void *object, int cmd,
+                                           void *value, size_t value_n),
+                               void *object, const char *value)
+{
+    int rv = 0;
+    char *stmp, *vtmp = NULL;
+    size_t vtmp_len = 0;
+    int cmd = 0; /* Will get command values that make sense somehow */
+
+    stmp = OPENSSL_strdup(value);
+    if (stmp == NULL)
+        return -1;
+    vtmp = strchr(stmp, ':');
+    if (vtmp != NULL) {
+        *vtmp = 0;
+        vtmp++;
+        vtmp_len = strlen(vtmp);
+    }
+
+    if (strcmp(stmp, "distid") == 0) {
+#ifdef EVP_PKEY_CTRL_SET1_ID
+        cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */
+#endif
+    } else if (strcmp(stmp, "hexdistid") == 0) {
+        long hexid_len = 0;
+        void *hexid = OPENSSL_hexstr2buf((const char *)vtmp, &hexid_len);
+
+        OPENSSL_free(stmp);
+        stmp = vtmp = hexid;
+        vtmp_len = (size_t)hexid_len;
+#ifdef EVP_PKEY_CTRL_SET1_ID
+        cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */
+#endif
+    }
+
+    rv = ctrl(object, cmd, vtmp, vtmp_len);
+
+    OPENSSL_free(stmp);
+    return rv;
+}
+
+int x509_ctrl_string(X509 *x, const char *value)
+{
+    return do_x509_ctrl_string(x509_ctrl, x, value);
+}
+
+int x509_req_ctrl_string(X509_REQ *x, const char *value)
+{
+    return do_x509_ctrl_string(x509_req_ctrl, x, value);
+}
diff --git a/apps/lib/build.info b/apps/lib/build.info
index a7be58b101..129ffce933 100644
--- a/apps/lib/build.info
+++ b/apps/lib/build.info
@@ -9,7 +9,7 @@ ENDIF
 
 # Source for libapps
 $LIBAPPSSRC=apps.c apps_ui.c opt.c fmt.c s_cb.c s_socket.c app_rand.c \
-        columns.c app_params.c names.c app_provider.c
+        columns.c app_params.c names.c app_provider.c app_x509.c
 
 IF[{- !$disabled{apps} -}]
   LIBS{noinst}=../libapps.a
diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c
index 7f11b168f5..7dc558b13a 100644
--- a/apps/pkeyutl.c
+++ b/apps/pkeyutl.c
@@ -550,22 +550,6 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
         if (pkey == NULL)
             goto end;
 
-#ifndef OPENSSL_NO_EC
-        /* SM2 needs a special treatment */
-        if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
-            EC_KEY *eckey = NULL;
-            const EC_GROUP *group = NULL;
-            int nid;
-
-            if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL
-                    || (group = EC_KEY_get0_group(eckey)) == NULL
-                    || (nid = EC_GROUP_get_curve_name(group)) == 0)
-                goto end;
-            if (nid == NID_sm2
-                    && !EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2))
-                goto end;
-        }
-#endif
         *pkeysize = EVP_PKEY_size(pkey);
         ctx = EVP_PKEY_CTX_new(pkey, impl);
         if (ppkey != NULL)
diff --git a/apps/req.c b/apps/req.c
index 5186017282..a8db866523 100644
--- a/apps/req.c
+++ b/apps/req.c
@@ -87,11 +87,11 @@ typedef enum OPTION_choice {
     OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_KEYGEN_ENGINE, OPT_KEY,
     OPT_PUBKEY, OPT_NEW, OPT_CONFIG, OPT_KEYFORM, OPT_IN, OPT_OUT,
     OPT_KEYOUT, OPT_PASSIN, OPT_PASSOUT, OPT_NEWKEY,
-    OPT_PKEYOPT, OPT_SIGOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS,
+    OPT_PKEYOPT, OPT_SIGOPT, OPT_VFYOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS,
     OPT_VERIFY, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8,
     OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT, OPT_X509,
     OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, OPT_ADDEXT, OPT_EXTENSIONS,
-    OPT_REQEXTS, OPT_PRECERT, OPT_MD, OPT_SM2ID, OPT_SM2HEXID,
+    OPT_REQEXTS, OPT_PRECERT, OPT_MD,
     OPT_SECTION,
     OPT_R_ENUM, OPT_PROV_ENUM
 } OPTION_CHOICE;
@@ -143,13 +143,8 @@ const OPTIONS req_options[] = {
     {"newkey", OPT_NEWKEY, 's', "Specify as type:bits"},
     {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"},
     {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
+    {"vfyopt", OPT_VFYOPT, 's', "Verification parameter in n:v form"},
     {"", OPT_MD, '-', "Any supported digest"},
-#ifndef OPENSSL_NO_SM2
-    {"sm2-id", OPT_SM2ID, 's',
-     "Specify an ID string to verify an SM2 certificate request"},
-    {"sm2-hex-id", OPT_SM2HEXID, 's',
-     "Specify a hex ID string to verify an SM2 certificate request"},
-#endif
 
     OPT_SECTION("Output"),
     {"out", OPT_OUT, '>', "Output file"},
@@ -237,7 +232,7 @@ int req_main(int argc, char **argv)
     ENGINE *e = NULL, *gen_eng = NULL;
     EVP_PKEY *pkey = NULL;
     EVP_PKEY_CTX *genctx = NULL;
-    STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL;
+    STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL, *vfyopts = NULL;
     LHASH_OF(OPENSSL_STRING) *addexts = NULL;
     X509 *x509ss = NULL;
     X509_REQ *req = NULL;
@@ -260,9 +255,6 @@ int req_main(int argc, char **argv)
     int nodes = 0, newhdr = 0, subject = 0, pubkey = 0, precert = 0;
     long newkey = -1;
     unsigned long chtype = MBSTRING_ASC, reqflag = 0;
-    unsigned char *sm2_id = NULL;
-    size_t sm2_idlen = 0;
-    int sm2_free = 0;
 
 #ifndef OPENSSL_NO_DES
     cipher = EVP_des_ede3_cbc();
@@ -359,6 +351,12 @@ int req_main(int argc, char **argv)
             if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
                 goto opthelp;
             break;
+        case OPT_VFYOPT:
+            if (!vfyopts)
+                vfyopts = sk_OPENSSL_STRING_new_null();
+            if (!vfyopts || !sk_OPENSSL_STRING_push(vfyopts, opt_arg()))
+                goto opthelp;
+            break;
         case OPT_BATCH:
             batch = 1;
             break;
@@ -446,29 +444,6 @@ int req_main(int argc, char **argv)
                 goto opthelp;
             digest = md_alg;
             break;
-        case OPT_SM2ID:
-            if (sm2_id != NULL) {
-                BIO_printf(bio_err,
-                           "Use one of the options 'sm2-hex-id' or 'sm2-id'\n");
-                goto end;
-            }
-            sm2_id = (unsigned char *)opt_arg();
-            sm2_idlen = strlen((const char *)sm2_id);
-            break;
-        case OPT_SM2HEXID:
-            if (sm2_id != NULL) {
-                BIO_printf(bio_err,
-                           "Use one of the options 'sm2-hex-id' or 'sm2-id'\n");
-                goto end;
-            }
-            /* try to parse the input as hex string first */
-            sm2_free = 1;
-            sm2_id = OPENSSL_hexstr2buf(opt_arg(), (long *)&sm2_idlen);
-            if (sm2_id == NULL) {
-                BIO_printf(bio_err, "Invalid hex string input\n");
-                goto end;
-            }
-            break;
         }
     }
     argc = opt_num_rest();
@@ -901,27 +876,7 @@ int req_main(int argc, char **argv)
                 goto end;
         }
 
-        if (sm2_id != NULL) {
-#ifndef OPENSSL_NO_SM2
-            ASN1_OCTET_STRING *v;
-
-            v = ASN1_OCTET_STRING_new();
-            if (v == NULL) {
-                BIO_printf(bio_err, "error: SM2 ID allocation failed\n");
-                goto end;
-            }
-
-            if (!ASN1_OCTET_STRING_set(v, sm2_id, sm2_idlen)) {
-                BIO_printf(bio_err, "error: setting SM2 ID failed\n");
-                ASN1_OCTET_STRING_free(v);
-                goto end;
-            }
-
-            X509_REQ_set0_sm2_id(req, v);
-#endif
-        }
-
-        i = X509_REQ_verify(req, tpubkey);
+        i = do_X509_REQ_verify(req, tpubkey, vfyopts);
 
         if (i < 0) {
             goto end;
@@ -1029,8 +984,6 @@ int req_main(int argc, char **argv)
     }
     ret = 0;
  end:
-    if (sm2_free)
-        OPENSSL_free(sm2_id);
     if (ret) {
         ERR_print_errors(bio_err);
     }
@@ -1043,6 +996,7 @@ int req_main(int argc, char **argv)
     EVP_PKEY_CTX_free(genctx);
     sk_OPENSSL_STRING_free(pkeyopts);
     sk_OPENSSL_STRING_free(sigopts);
+    sk_OPENSSL_STRING_free(vfyopts);
     lh_OPENSSL_STRING_doall(addexts, exts_cleanup);
     lh_OPENSSL_STRING_free(addexts);
 #ifndef OPENSSL_NO_ENGINE
@@ -1685,71 +1639,82 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx)
     return 1;
 }
 
-static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
-                        const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
+static int do_pkey_ctx_init(EVP_PKEY_CTX *pkctx, STACK_OF(OPENSSL_STRING) *opts)
 {
-    EVP_PKEY_CTX *pkctx = NULL;
-    EVP_PKEY_CTX *pctx = NULL;
-    int i, def_nid, ret = 0;
+    int i;
 
-    if (ctx == NULL)
-        goto err;
-    if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) {
-        pctx = EVP_PKEY_CTX_new(pkey, NULL);
-        if (pctx == NULL) {
-            BIO_printf(bio_err, "memory allocation failure.\n");
-            goto err;
-        }
-        /* set SM2 ID from sig options before calling the real init routine */
-        for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
-            char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
-            if (pkey_ctrl_string(pctx, sigopt) <= 0) {
-                BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt);
-                ERR_print_errors(bio_err);
-                goto err;
-            }
+    if (opts == NULL)
+        return 1;
+
+    for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
+        char *opt = sk_OPENSSL_STRING_value(opts, i);
+        if (pkey_ctrl_string(pkctx, opt) <= 0) {
+            BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
+            ERR_print_errors(bio_err);
+            return 0;
         }
-        EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
     }
-    /*
-     * EVP_PKEY_get_default_digest_nid() returns 2 if the digest is mandatory
-     * for this algorithm.
-     */
-    if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) == 2
-            && def_nid == NID_undef) {
-        /* The signing algorithm requires there to be no digest */
-        md = NULL;
+
+    return 1;
+}
+
+static int do_x509_init(X509 *x, STACK_OF(OPENSSL_STRING) *opts)
+{
+    int i;
+
+    if (opts == NULL)
+        return 1;
+
+    for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
+        char *opt = sk_OPENSSL_STRING_value(opts, i);
+        if (x509_ctrl_string(x, opt) <= 0) {
+            BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
+            ERR_print_errors(bio_err);
+            return 0;
+        }
     }
-    if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
-        goto err;
-    for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
-        char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
-        if (pkey_ctrl_string(pkctx, sigopt) <= 0) {
-            BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt);
+
+    return 1;
+}
+
+static int do_x509_req_init(X509_REQ *x, STACK_OF(OPENSSL_STRING) *opts)
+{
+    int i;
+
+    if (opts == NULL)
+        return 1;
+
+    for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
+        char *opt = sk_OPENSSL_STRING_value(opts, i);
+        if (x509_req_ctrl_string(x, opt) <= 0) {
+            BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
             ERR_print_errors(bio_err);
-            goto err;
+            return 0;
         }
     }
 
-    ret = 1;
- err:
-    if (!ret)
-        EVP_PKEY_CTX_free(pctx);
-    return ret;
+    return 1;
 }
 
-static void do_sign_cleanup(EVP_MD_CTX *ctx, EVP_PKEY *pkey)
+static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
+                        const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
 {
+    EVP_PKEY_CTX *pkctx = NULL;
+    int def_nid;
+
+    if (ctx == NULL)
+        return 0;
     /*
-     * With SM2, do_sign_init() attached an EVP_PKEY_CTX to the EVP_MD_CTX,
-     * and we have to free it explicitly.
+     * EVP_PKEY_get_default_digest_nid() returns 2 if the digest is mandatory
+     * for this algorithm.
      */
-    if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) {
-        EVP_PKEY_CTX *pctx = EVP_MD_CTX_pkey_ctx(ctx);
-
-        EVP_MD_CTX_set_pkey_ctx(ctx, NULL);
-        EVP_PKEY_CTX_free(pctx);
+    if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) == 2
+            && def_nid == NID_undef) {
+        /* The signing algorithm requires there to be no digest */
+        md = NULL;
     }
+    return EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey)
+        && do_pkey_ctx_init(pkctx, sigopts);
 }
 
 int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
@@ -1758,10 +1723,8 @@ int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
     int rv = 0;
     EVP_MD_CTX *mctx = EVP_MD_CTX_new();
 
-    if (do_sign_init(mctx, pkey, md, sigopts) > 0) {
+    if (do_sign_init(mctx, pkey, md, sigopts) > 0)
         rv = (X509_sign_ctx(x, mctx) > 0);
-        do_sign_cleanup(mctx, pkey);
-    }
     EVP_MD_CTX_free(mctx);
     return rv;
 }
@@ -1772,24 +1735,39 @@ int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
     int rv = 0;
     EVP_MD_CTX *mctx = EVP_MD_CTX_new();
 
-    if (do_sign_init(mctx, pkey, md, sigopts) > 0) {
+    if (do_sign_init(mctx, pkey, md, sigopts) > 0)
         rv = (X509_REQ_sign_ctx(x, mctx) > 0);
-        do_sign_cleanup(mctx, pkey);
-    }
     EVP_MD_CTX_free(mctx);
     return rv;
 }
 
+int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts)
+{
+    int rv = 0;
+
+    if (do_x509_init(x, vfyopts) > 0)
+        rv = (X509_verify(x, pkey) > 0);
+    return rv;
+}
+
+int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey,
+                       STACK_OF(OPENSSL_STRING) *vfyopts)
+{
+    int rv = 0;
+
+    if (do_x509_req_init(x, vfyopts) > 0)
+        rv = (X509_REQ_verify(x, pkey) > 0);
+    return rv;
+}
+
 int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
                      STACK_OF(OPENSSL_STRING) *sigopts)
 {
     int rv = 0;
     EVP_MD_CTX *mctx = EVP_MD_CTX_new();
 
-    if (do_sign_init(mctx, pkey, md, sigopts) > 0) {
+    if (do_sign_init(mctx, pkey, md, sigopts) > 0)
         rv = (X509_CRL_sign_ctx(x, mctx) > 0);
-        do_sign_cleanup(mctx, pkey);
-    }
     EVP_MD_CTX_free(mctx);
     return rv;
 }
diff --git a/apps/verify.c b/apps/verify.c
index 82ca35e971..f626009f55 100644
--- a/apps/verify.c
+++ b/apps/verify.c
@@ -22,7 +22,7 @@ static int cb(int ok, X509_STORE_CTX *ctx);
 static int check(X509_STORE *ctx, const char *file,
                  STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
                  STACK_OF(X509_CRL) *crls, int show_chain,
-                 unsigned char *sm2id, size_t sm2idlen);
+                 STACK_OF(OPENSSL_STRING) *opts);
 static int v_verbose = 0, vflags = 0;
 
 typedef enum OPTION_choice {
@@ -30,8 +30,8 @@ typedef enum OPTION_choice {
     OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_CASTORE,
     OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE,
     OPT_UNTRUSTED, OPT_TRUSTED, OPT_CRLFILE, OPT_CRL_DOWNLOAD, OPT_SHOW_CHAIN,
-    OPT_V_ENUM, OPT_NAMEOPT,
-    OPT_VERBOSE, OPT_SM2ID, OPT_SM2HEXID,
+    OPT_V_ENUM, OPT_NAMEOPT, OPT_VFYOPT,
+    OPT_VERBOSE,
     OPT_PROV_ENUM
 } OPTION_CHOICE;
 
@@ -67,12 +67,7 @@ const OPTIONS verify_options[] = {
         "Display information about the certificate chain"},
 
     OPT_V_OPTIONS,
-#ifndef OPENSSL_NO_SM2
-    {"sm2-id", OPT_SM2ID, 's',
-     "Specify an ID string to verify an SM2 certificate"},
-    {"sm2-hex-id", OPT_SM2HEXID, 's',
-     "Specify a hex ID string to verify an SM2 certificate"},
-#endif
+    {"vfyopt", OPT_VFYOPT, 's', "Verification parameter in n:v form"},
 
     OPT_PROV_OPTIONS,
 
@@ -86,15 +81,13 @@ int verify_main(int argc, char **argv)
     ENGINE *e = NULL;
     STACK_OF(X509) *untrusted = NULL, *trusted = NULL;
     STACK_OF(X509_CRL) *crls = NULL;
+    STACK_OF(OPENSSL_STRING) *vfyopts = NULL;
     X509_STORE *store = NULL;
     X509_VERIFY_PARAM *vpm = NULL;
     const char *prog, *CApath = NULL, *CAfile = NULL, *CAstore = NULL;
     int noCApath = 0, noCAfile = 0, noCAstore = 0;
     int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1;
     OPTION_CHOICE o;
-    unsigned char *sm2_id = NULL;
-    size_t sm2_idlen = 0;
-    int sm2_free = 0;
 
     if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
         goto end;
@@ -104,6 +97,7 @@ int verify_main(int argc, char **argv)
         switch (o) {
         case OPT_EOF:
         case OPT_ERR:
+ opthelp:
             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
             goto end;
         case OPT_HELP:
@@ -186,32 +180,15 @@ int verify_main(int argc, char **argv)
             if (!set_nameopt(opt_arg()))
                 goto end;
             break;
+        case OPT_VFYOPT:
+            if (!vfyopts)
+                vfyopts = sk_OPENSSL_STRING_new_null();
+            if (!vfyopts || !sk_OPENSSL_STRING_push(vfyopts, opt_arg()))
+                goto opthelp;
+            break;
         case OPT_VERBOSE:
             v_verbose = 1;
             break;
-        case OPT_SM2ID:
-            if (sm2_id != NULL) {
-                BIO_printf(bio_err,
-                           "Use one of the options 'sm2-hex-id' or 'sm2-id' \n");
-                goto end;
-            }
-            sm2_id = (unsigned char *)opt_arg();
-            sm2_idlen = strlen((const char *)sm2_id);
-            break;
-        case OPT_SM2HEXID:
-            if (sm2_id != NULL) {
-                BIO_printf(bio_err,
-                           "Use one of the options 'sm2-hex-id' or 'sm2-id' \n");
-                goto end;
-            }
-            /* try to parse the input as hex string first */
-            sm2_free = 1;
-            sm2_id = OPENSSL_hexstr2buf(opt_arg(), (long *)&sm2_idlen);
-            if (sm2_id == NULL) {
-                BIO_printf(bio_err, "Invalid hex string input\n");
-                goto end;
-            }
-            break;
         case OPT_PROV_CASES:
             if (!opt_provider(o))
                 goto end;
@@ -244,23 +221,22 @@ int verify_main(int argc, char **argv)
     ret = 0;
     if (argc < 1) {
         if (check(store, NULL, untrusted, trusted, crls, show_chain,
-                  sm2_id, sm2_idlen) != 1)
+                  vfyopts) != 1)
             ret = -1;
     } else {
         for (i = 0; i < argc; i++)
-            if (check(store, argv[i], untrusted, trusted, crls,
-                      show_chain, sm2_id, sm2_idlen) != 1)
+            if (check(store, argv[i], untrusted, trusted, crls, show_chain,
+                      vfyopts) != 1)
                 ret = -1;
     }
 
  end:
-    if (sm2_free)
-        OPENSSL_free(sm2_id);
     X509_VERIFY_PARAM_free(vpm);
     X509_STORE_free(store);
     sk_X509_pop_free(untrusted, X509_free);
     sk_X509_pop_free(trusted, X509_free);
     sk_X509_CRL_pop_free(crls, X509_CRL_free);
+    sk_OPENSSL_STRING_free(vfyopts);
     release_engine(e);
     return (ret < 0 ? 2 : ret);
 }
@@ -268,7 +244,7 @@ int verify_main(int argc, char **argv)
 static int check(X509_STORE *ctx, const char *file,
                  STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
                  STACK_OF(X509_CRL) *crls, int show_chain,
-                 unsigned char *sm2id, size_t sm2idlen)
+                 STACK_OF(OPENSSL_STRING) *opts)
 {
     X509 *x = NULL;
     int i = 0, ret = 0;
@@ -280,24 +256,15 @@ static int check(X509_STORE *ctx, const char *file,
     if (x == NULL)
         goto end;
 
-    if (sm2id != NULL) {
-#ifndef OPENSSL_NO_SM2
-        ASN1_OCTET_STRING *v;
-
-        v = ASN1_OCTET_STRING_new();
-        if (v == NULL) {
-            BIO_printf(bio_err, "error: SM2 ID allocation failed\n");
-            goto end;
-        }
-
-        if (!ASN1_OCTET_STRING_set(v, sm2id, sm2idlen)) {
-            BIO_printf(bio_err, "error: setting SM2 ID failed\n");
-            ASN1_OCTET_STRING_free(v);
-            goto end;
+    if (opts != NULL) {
+        for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
+            char *opt = sk_OPENSSL_STRING_value(opts, i);
+            if (x509_ctrl_string(x, opt) <= 0) {
+                BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
+                ERR_print_errors(bio_err);
+                return 0;
+            }
         }
-
-        X509_set0_sm2_id(x, v);
-#endif
     }
 
     csc = X509_STORE_CTX_new();
diff --git a/apps/x509.c b/apps/x509.c
index 3176cf528c..e2a68828e3 100644
--- a/apps/x509.c
+++ b/apps/x509.c
@@ -33,7 +33,9 @@
 #define DEF_DAYS        30
 
 static int callb(int ok, X509_STORE_CTX *ctx);
-static int sign(X509 *x, EVP_PKEY *pkey, EVP_PKEY *fkey, int days, int clrext,
+static int sign(X509 *x, EVP_PKEY *pkey, EVP_PKEY *fkey,
+                STACK_OF(OPENSSL_STRING) *sigopts,
+                int days, int clrext,
                 const EVP_MD *digest, CONF *conf, const char *section,
                 int preserve_dates);
 static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *digest,
@@ -48,7 +50,7 @@ static int print_x509v3_exts(BIO *bio, X509 *x, const char *exts);
 typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
     OPT_INFORM, OPT_OUTFORM, OPT_KEYFORM, OPT_REQ, OPT_CAFORM,
-    OPT_CAKEYFORM, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE,
+    OPT_CAKEYFORM, OPT_VFYOPT, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE,
     OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_SIGNKEY, OPT_CA, OPT_CAKEY,
     OPT_CASERIAL, OPT_SET_SERIAL, OPT_NEW, OPT_FORCE_PUBKEY, OPT_SUBJ,
     OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_NAMEOPT,
@@ -80,6 +82,7 @@ const OPTIONS x509_options[] = {
     {"out", OPT_OUT, '>', "Output file - default stdout"},
     {"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"},
     {"req", OPT_REQ, '-', "Input is a certificate request, sign and output"},
+    {"vfyopt", OPT_VFYOPT, 's', "Verification parameter in n:v form"},
 
     OPT_SECTION("Output"),
     {"serial", OPT_SERIAL, '-', "Print serial number value"},
@@ -174,7 +177,7 @@ int x509_main(int argc, char **argv)
     const unsigned long chtype = MBSTRING_ASC;
     const int multirdn = 0;
     STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
-    STACK_OF(OPENSSL_STRING) *sigopts = NULL;
+    STACK_OF(OPENSSL_STRING) *sigopts = NULL, *vfyopts = NULL;
     X509 *x = NULL, *xca = NULL;
     X509_REQ *req = NULL, *rq = NULL;
     X509_STORE *ctx = NULL;
@@ -256,6 +259,12 @@ int x509_main(int argc, char **argv)
             if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
                 goto opthelp;
             break;
+        case OPT_VFYOPT:
+            if (!vfyopts)
+                vfyopts = sk_OPENSSL_STRING_new_null();
+            if (!vfyopts || !sk_OPENSSL_STRING_push(vfyopts, opt_arg()))
+                goto opthelp;
+            break;
         case OPT_DAYS:
             if (preserve_dates)
                 goto opthelp;
@@ -576,7 +585,7 @@ int x509_main(int argc, char **argv)
             BIO_printf(bio_err, "error unpacking public key\n");
             goto end;
         }
-        i = X509_REQ_verify(req, pkey);
+        i = do_X509_REQ_verify(req, pkey, vfyopts);
         if (i < 0) {
             BIO_printf(bio_err, "Request self-signature verification error\n");
             ERR_print_errors(bio_err);
@@ -848,8 +857,8 @@ int x509_main(int argc, char **argv)
                         goto end;
                 }
 
-                if (!sign(x, Upkey, fkey, days, clrext, digest, extconf,
-                          extsect, preserve_dates))
+                if (!sign(x, Upkey, fkey, sigopts, days, clrext, digest,
+                          extconf, extsect, preserve_dates))
                     goto end;
             } else if (CA_flag == i) {
                 BIO_printf(bio_err, "Getting CA Private Key\n");
@@ -949,6 +958,7 @@ int x509_main(int argc, char **argv)
     EVP_PKEY_free(CApkey);
     EVP_PKEY_free(fkey);
     sk_OPENSSL_STRING_free(sigopts);
+    sk_OPENSSL_STRING_free(vfyopts);
     X509_REQ_free(rq);
     ASN1_INTEGER_free(sno);
     sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
@@ -1106,11 +1116,12 @@ static int callb(int ok, X509_STORE_CTX *ctx)
 }
 
 /* self-issue; self-sign unless a forced public key (fkey) is given */
-static int sign(X509 *x, EVP_PKEY *pkey, EVP_PKEY *fkey, int days, int clrext,
+static int sign(X509 *x, EVP_PKEY *pkey, EVP_PKEY *fkey,
+                STACK_OF(OPENSSL_STRING) *sigopts,
+                int days, int clrext,
                 const EVP_MD *digest, CONF *conf, const char *section,
                 int preserve_dates)
 {
-
     if (!X509_set_issuer_name(x, X509_get_subject_name(x)))
         goto err;
     if (!preserve_dates && !set_cert_times(x, NULL, NULL, days))
@@ -1129,7 +1140,7 @@ static int sign(X509 *x, EVP_PKEY *pkey, EVP_PKEY *fkey, int days, int clrext,
         if (!X509V3_EXT_add_nconf(conf, &ctx, section, x))
             goto err;
     }
-    if (!X509_sign(x, pkey, digest))
+    if (!do_X509_sign(x, pkey, digest, sigopts))
         goto err;
     return 1;
  err:
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
index 4b2cb4eb35..1948f234ca 100644
--- a/crypto/evp/m_sigver.c
+++ b/crypto/evp/m_sigver.c
@@ -250,8 +250,9 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
      * This indicates the current algorithm requires
      * special treatment before hashing the tbs-message.
      */
+    ctx->pctx->flag_call_digest_custom = 0;
     if (ctx->pctx->pmeth->digest_custom != NULL)
-        return ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx);
+        ctx->pctx->flag_call_digest_custom = 1;
 
     return 1;
 }
@@ -301,6 +302,12 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
                                                       data, dsize);
 
  legacy:
+    /* do_sigver_init() checked that |digest_custom| is non-NULL */
+    if (pctx->flag_call_digest_custom
+        && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx))
+        return 0;
+    pctx->flag_call_digest_custom = 0;
+
     return EVP_DigestUpdate(ctx, data, dsize);
 }
 
@@ -323,6 +330,12 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
                                                         data, dsize);
 
  legacy:
+    /* do_sigver_init() checked that |digest_custom| is non-NULL */
+    if (pctx->flag_call_digest_custom
+        && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx))
+        return 0;
+    pctx->flag_call_digest_custom = 0;
+
     return EVP_DigestUpdate(ctx, data, dsize);
 }
 
@@ -348,6 +361,12 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
         return 0;
     }
 
+    /* do_sigver_init() checked that |digest_custom| is non-NULL */
+    if (pctx->flag_call_digest_custom
+        && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx))
+        return 0;
+    pctx->flag_call_digest_custom = 0;
+
     if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) {
         if (sigret == NULL)
             return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
@@ -458,6 +477,12 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
         return 0;
     }
 
+    /* do_sigver_init() checked that |digest_custom| is non-NULL */
+    if (pctx->flag_call_digest_custom
+        && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx))
+        return 0;
+    pctx->flag_call_digest_custom = 0;
+
     if (pctx->pmeth->verifyctx != NULL)
         vctx = 1;
     else
diff --git a/crypto/sm2/sm2_pmeth.c b/crypto/sm2/sm2_pmeth.c
index c3ba9280c5..9830fb8234 100644
--- a/crypto/sm2/sm2_pmeth.c
+++ b/crypto/sm2/sm2_pmeth.c
@@ -26,7 +26,7 @@
 typedef struct {
     /* message digest */
     const EVP_MD *md;
-    /* Distinguishing Identifier, ISO/IEC 15946-3 */
+    /* Distinguishing Identifier, ISO/IEC 15946-3, FIPS 196 */
     uint8_t *id;
     size_t id_len;
     /* id_set indicates if the 'id' field is set (1) or not (0) */
@@ -247,14 +247,10 @@ static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx,
         else
             return -2;
         return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc);
-    } else if (strcmp(type, "sm2_id") == 0) {
+    } else if (strcmp(type, "distid") == 0) {
         return pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID,
                              (int)strlen(value), (void *)value);
-    } else if (strcmp(type, "sm2_hex_id") == 0) {
-        /*
-         * TODO(3.0): reconsider the name "sm2_hex_id", OR change
-         * OSSL_PARAM_allocate_from_text() to handle infix "_hex_"
-         */
+    } else if (strcmp(type, "hexdistid") == 0) {
         hex_id = OPENSSL_hexstr2buf((const char *)value, &hex_len);
         if (hex_id == NULL) {
             SM2err(SM2_F_PKEY_SM2_CTRL_STR, ERR_R_PASSED_INVALID_ARGUMENT);
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c
index 2d7387b9e0..ca9d3dbc98 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -71,10 +71,7 @@ int X509_verify(X509 *a, EVP_PKEY *r)
     if (X509_ALGOR_cmp(&a->sig_alg, &a->cert_info.signature))
         return 0;
 
-#ifndef OPENSSL_NO_SM2
-    id = a->sm2_id;
-#endif
-
+    id = a->distinguishing_id;
     if ((ctx = make_id_ctx(r, id)) != NULL) {
         rv = ASN1_item_verify_ctx(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg,
                                   &a->signature, &a->cert_info, ctx);
@@ -89,10 +86,7 @@ int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
     EVP_MD_CTX *ctx = NULL;
     ASN1_OCTET_STRING *id = NULL;
 
-#ifndef OPENSSL_NO_SM2
-    id = a->sm2_id;
-#endif
-
+    id = a->distinguishing_id;
     if ((ctx = make_id_ctx(r, id)) != NULL) {
         rv = ASN1_item_verify_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), &a->sig_alg,
                                   a->signature, &a->req_info, ctx);
diff --git a/crypto/x509/x_req.c b/crypto/x509/x_req.c
index e9cc9ba41c..d8a89011e8 100644
--- a/crypto/x509/x_req.c
+++ b/crypto/x509/x_req.c
@@ -53,14 +53,14 @@ static int req_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
 
     switch (operation) {
     case ASN1_OP_D2I_PRE:
-        ASN1_OCTET_STRING_free(ret->sm2_id);
+        ASN1_OCTET_STRING_free(ret->distinguishing_id);
         /* fall thru */
     case ASN1_OP_NEW_POST:
-        ret->sm2_id = NULL;
+        ret->distinguishing_id = NULL;
         break;
 
     case ASN1_OP_FREE_POST:
-        ASN1_OCTET_STRING_free(ret->sm2_id);
+        ASN1_OCTET_STRING_free(ret->distinguishing_id);
         break;
     }
 #endif
@@ -90,15 +90,13 @@ IMPLEMENT_ASN1_FUNCTIONS(X509_REQ)
 
 IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ)
 
-#ifndef OPENSSL_NO_SM2
-void X509_REQ_set0_sm2_id(X509_REQ *x, ASN1_OCTET_STRING *sm2_id)
+void X509_REQ_set0_distinguishing_id(X509_REQ *x, ASN1_OCTET_STRING *d_id)
 {
-    ASN1_OCTET_STRING_free(x->sm2_id);
-    x->sm2_id = sm2_id;
+    ASN1_OCTET_STRING_free(x->distinguishing_id);
+    x->distinguishing_id = d_id;
 }
 
-ASN1_OCTET_STRING *X509_REQ_get0_sm2_id(X509_REQ *x)
+ASN1_OCTET_STRING *X509_REQ_get0_distinguishing_id(X509_REQ *x)
 {
-    return x->sm2_id;
+    return x->distinguishing_id;
 }
-#endif
diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c
index 7b41ce0777..e3caf8d44a 100644
--- a/crypto/x509/x_x509.c
+++ b/crypto/x509/x_x509.c
@@ -53,9 +53,7 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
         sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
         ASIdentifiers_free(ret->rfc3779_asid);
 #endif
-#ifndef OPENSSL_NO_SM2
-        ASN1_OCTET_STRING_free(ret->sm2_id);
-#endif
+        ASN1_OCTET_STRING_free(ret->distinguishing_id);
 
         /* fall thru */
 
@@ -76,9 +74,7 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
         ret->rfc3779_addr = NULL;
         ret->rfc3779_asid = NULL;
 #endif
-#ifndef OPENSSL_NO_SM2
-        ret->sm2_id = NULL;
-#endif
+        ret->distinguishing_id = NULL;
         ret->aux = NULL;
         ret->crldp = NULL;
         if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data))
@@ -98,9 +94,7 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
         sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
         ASIdentifiers_free(ret->rfc3779_asid);
 #endif
-#ifndef OPENSSL_NO_SM2
-        ASN1_OCTET_STRING_free(ret->sm2_id);
-#endif
+        ASN1_OCTET_STRING_free(ret->distinguishing_id);
         break;
 
     }
@@ -254,15 +248,13 @@ int X509_get_signature_nid(const X509 *x)
     return OBJ_obj2nid(x->sig_alg.algorithm);
 }
 
-#ifndef OPENSSL_NO_SM2
-void X509_set0_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id)
+void X509_set0_distinguishing_id(X509 *x, ASN1_OCTET_STRING *d_id)
 {
-    ASN1_OCTET_STRING_free(x->sm2_id);
-    x->sm2_id = sm2_id;
+    ASN1_OCTET_STRING_free(x->distinguishing_id);
+    x->distinguishing_id = d_id;
 }
 
-ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x)
+ASN1_OCTET_STRING *X509_get0_distinguishing_id(X509 *x)
 {
-    return x->sm2_id;
+    return x->distinguishing_id;
 }
-#endif
diff --git a/doc/man1/openssl-ca.pod.in b/doc/man1/openssl-ca.pod.in
index 5192b25fa5..e07295cffc 100644
--- a/doc/man1/openssl-ca.pod.in
+++ b/doc/man1/openssl-ca.pod.in
@@ -53,17 +53,16 @@ B<openssl> B<ca>
 [B<-subj> I<arg>]
 [B<-utf8>]
 [B<-sigopt> I<nm>:I<v>]
+[B<-vfyopt> I<nm>:I<v>]
 [B<-create_serial>]
 [B<-rand_serial>]
 [B<-multivalue-rdn>]
-[B<-sm2-id> I<string>]
-[B<-sm2-hex-id> I<hex-string>]
 {- $OpenSSL::safe::opt_r_synopsis -}
 {- $OpenSSL::safe::opt_engine_synopsis -}
 {- $OpenSSL::safe::opt_provider_synopsis -}
 [I<certreq>...]
 
-=for openssl ifdef engine sm2-id sm2-hex-id
+=for openssl ifdef engine
 
 =head1 DESCRIPTION
 
@@ -147,9 +146,18 @@ See L<openssl(1)/Format Options> for details.
 
 =item B<-sigopt> I<nm>:I<v>
 
-Pass options to the signature algorithm during sign or verify operations.
+Pass options to the signature algorithm during sign operations.
 Names and values of these options are algorithm-specific.
 
+=item B<-vfyopt> I<nm>:I<v>
+
+Pass options to the signature algorithm during verify operations.
+Names and values of these options are algorithm-specific.
+
+This often needs to be given while signing too, because the input
+certificate signature request is verified against its own public key,
+and that verification may need its own set of options.
+
 =item B<-key> I<password>
 
 =for openssl foreign manual ps(1)
@@ -297,16 +305,6 @@ C</DC=org/DC=OpenSSL/DC=users/UID=123456+CN=John Doe>
 
 If B<-multi-rdn> is not used then the UID value is C<123456+CN=John Doe>.
 
-=item B<-sm2-id> I<string>
-
-Specify the ID string to use when verifying an SM2 certificate. The ID string is
-required by the SM2 signature algorithm for signing and verification.
-
-=item B<-sm2-hex-id> I<hex-string>
-
-Specify a binary ID string to use when signing or verifying using an SM2
-certificate. The argument for this option is string of hexadecimal digits.
-
 {- $OpenSSL::safe::opt_r_item -}
 
 {- $OpenSSL::safe::opt_engine_item -}
@@ -617,7 +615,9 @@ Sign a certificate request:
 
 Sign an SM2 certificate request:
 
- openssl ca -in sm2.csr -out sm2.crt -md sm3 -sigopt "sm2_id:1234567812345678" -sm2-id "1234567812345678"
+ openssl ca -in sm2.csr -out sm2.crt -md sm3 \
+         -sigopt "distid:1234567812345678" \
+         -vfyopt "distid:1234567812345678"
 
 Sign a certificate request, using CA extensions:
 
diff --git a/doc/man1/openssl-pkeyutl.pod.in b/doc/man1/openssl-pkeyutl.pod.in
index 583ea68734..8f9060a239 100644
--- a/doc/man1/openssl-pkeyutl.pod.in
+++ b/doc/man1/openssl-pkeyutl.pod.in
@@ -321,18 +321,18 @@ must be known for this to work. If the size of the file cannot be determined
 =head1 SM2
 
 The SM2 algorithm supports sign, verify, encrypt and decrypt operations. For
-the sign and verify operations, SM2 requires an ID string to be passed in. The
-following B<-pkeyopt> value is supported:
+the sign and verify operations, SM2 requires an Distinguishing ID string to
+be passed in. The following B<-pkeyopt> value is supported:
 
 =over 4
 
-=item B<sm2_id:>I<string>
+=item B<distid:>I<string>
 
 This sets the ID string used in SM2 sign or verify operations. While verifying
 an SM2 signature, the ID string must be the same one used when signing the data.
 Otherwise the verification will fail.
 
-=item B<sm2_hex_id:>I<hex_string>
+=item B<hexdistid:>I<hex_string>
 
 This sets the ID string used in SM2 sign or verify operations. While verifying
 an SM2 signature, the ID string must be the same one used when signing the data.
@@ -382,12 +382,12 @@ Derive using the same algorithm, but read key from environment variable MYPASS:
 Sign some data using an L<SM2(7)> private key and a specific ID:
 
  openssl pkeyutl -sign -in file -inkey sm2.key -out sig -rawin -digest sm3 \
-    -pkeyopt sm2_id:someid
+    -pkeyopt distid:someid
 
 Verify some data using an L<SM2(7)> certificate and a specific ID:
 
  openssl pkeyutl -verify -certin -in file -inkey sm2.cert -sigfile sig \
-    -rawin -digest sm3 -pkeyopt sm2_id:someid
+    -rawin -digest sm3 -pkeyopt distid:someid
 
 =head1 SEE ALSO
 
diff --git a/doc/man1/openssl-req.pod.in b/doc/man1/openssl-req.pod.in
index ca3416e799..c8abeb368d 100644
--- a/doc/man1/openssl-req.pod.in
+++ b/doc/man1/openssl-req.pod.in
@@ -45,16 +45,15 @@ B<openssl> B<req>
 [B<-subject>]
 [B<-subj> I<arg>]
 [B<-sigopt> I<nm>:I<v>]
+[B<-vfyopt> I<nm>:I<v>]
 [B<-batch>]
 [B<-verbose>]
-[B<-sm2-id> I<string>]
-[B<-sm2-hex-id> I<hex-string>]
 {- $OpenSSL::safe::opt_name_synopsis -}
 {- $OpenSSL::safe::opt_r_synopsis -}
 {- $OpenSSL::safe::opt_engine_synopsis -}
 {- $OpenSSL::safe::opt_provider_synopsis -}
 
-=for openssl ifdef engine keygen_engine sm2-id sm2-hex-id
+=for openssl ifdef engine keygen_engine
 
 =head1 DESCRIPTION
 
@@ -85,9 +84,22 @@ options (B<-new> and B<-newkey>) are not specified.
 
 =item B<-sigopt> I<nm>:I<v>
 
-Pass options to the signature algorithm during sign or verify operations.
+Pass options to the signature algorithm during sign operations.
 Names and values of these options are algorithm-specific.
 
+=item B<-vfyopt> I<nm>:I<v>
+
+Pass options to the signature algorithm during verify operations.
+Names and values of these options are algorithm-specific.
+
+=begin comment
+
+Maybe it would be preferable to only have -opts instead of -sigopt and
+-vfyopt?  They are both present here to be compatible with L<openssl-ca(1)>,
+which supports both options for good reasons.
+
+=end comment
+
 =item B<-passin> I<arg>, B<-passout> I<arg>
 
 The password source for the input and output file.
@@ -313,16 +325,6 @@ Print extra details about the operations being performed.
 Specifies an engine (by its unique I<id> string) which would be used
 for key generation operations.
 
-=item B<-sm2-id>
-
-Specify the ID string to use when verifying an SM2 certificate request. The ID
-string is required by the SM2 signature algorithm for signing and verification.
-
-=item B<-sm2-hex-id>
-
-Specify a binary ID string to use when verifying an SM2 certificate request. The
-argument for this option is string of hexadecimal digits.
-
 {- $OpenSSL::safe::opt_name_item -}
 
 {- $OpenSSL::safe::opt_r_item -}
@@ -531,11 +533,11 @@ Generate a self signed root certificate:
 Create an SM2 private key and then generate a certificate request from it:
 
  openssl ecparam -genkey -name SM2 -out sm2.key
- openssl req -new -key sm2.key -out sm2.csr -sm3 -sigopt "sm2_id:1234567812345678"
+ openssl req -new -key sm2.key -out sm2.csr -sm3 -sigopt "distid:1234567812345678"
 
 Examine and verify an SM2 certificate request:
 
- openssl req -verify -in sm2.csr -sm3 -sm2-id 1234567812345678
+ openssl req -verify -in sm2.csr -sm3 -vfyopt "distid:1234567812345678"
 
 Example of a file pointed to by the B<oid_file> option:
 
diff --git a/doc/man1/openssl-verify.pod.in b/doc/man1/openssl-verify.pod.in
index 7a15e73721..821f88dae9 100644
--- a/doc/man1/openssl-verify.pod.in
+++ b/doc/man1/openssl-verify.pod.in
@@ -12,11 +12,10 @@ B<openssl> B<verify>
 [B<-CRLfile> I<file>]
 [B<-crl_download>]
 [B<-show_chain>]
-[B<-sm2-id> I<hexstring>]
-[B<-sm2-hex-id> I<hexstring>]
 [B<-verbose>]
 [B<-trusted> I<file>]
 [B<-untrusted> I<file>]
+[B<-vfyopt> I<nm>:I<v>]
 {- $OpenSSL::safe::opt_name_synopsis -}
 {- $OpenSSL::safe::opt_trust_synopsis -}
 {- $OpenSSL::safe::opt_engine_synopsis -}
@@ -25,7 +24,7 @@ B<openssl> B<verify>
 [B<-->]
 [I<certificate> ...]
 
-=for openssl ifdef engine sm2-id sm2-hex-id
+=for openssl ifdef engine
 
 =head1 DESCRIPTION
 
@@ -59,16 +58,6 @@ Display information about the certificate chain that has been built (if
 successful). Certificates in the chain that came from the untrusted list will be
 flagged as "untrusted".
 
-=item B<-sm2-id> I<hexstring>
-
-Specify the ID string to use when verifying an SM2 certificate. The ID string is
-required by the SM2 signature algorithm for signing and verification.
-
-=item B<-sm2-hex-id> I<hexstring>
-
-Specify a binary ID string to use when signing or verifying using an SM2
-certificate. The argument for this option is string of hexadecimal digits.
-
 =item B<-verbose>
 
 Print extra information about the operations being performed.
@@ -81,6 +70,11 @@ A file of trusted certificates.
 
 A file of untrusted certificates.
 
+=item B<-vfyopt> I<nm>:I<v>
+
+Pass options to the signature algorithm during verify operations.
+Names and values of these options are algorithm-specific.
+
 {- $OpenSSL::safe::opt_name_item -}
 
 {- $OpenSSL::safe::opt_engine_item -}
@@ -159,8 +153,6 @@ L<ossl_store-file(7)>
 
 The B<-show_chain> option was added in OpenSSL 1.1.0.
 
-The B<-sm2-id> and B<-sm2-hex-id> options were added in OpenSSL 3.0.
-
 =head1 COPYRIGHT
 
 Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
diff --git a/doc/man1/openssl-x509.pod.in b/doc/man1/openssl-x509.pod.in
index 98b4e71231..568a2053fc 100644
--- a/doc/man1/openssl-x509.pod.in
+++ b/doc/man1/openssl-x509.pod.in
@@ -71,6 +71,7 @@ B<openssl> B<x509>
 [B<-extfile> I<filename>]
 [B<-extensions> I<section>]
 [B<-sigopt> I<nm>:I<v>]
+[B<-vfyopt> I<nm>:I<v>]
 [B<-preserve_dates>]
 {- $OpenSSL::safe::opt_name_synopsis -}
 {- $OpenSSL::safe::opt_r_synopsis -}
@@ -371,7 +372,12 @@ for testing.
 
 =item B<-sigopt> I<nm>:I<v>
 
-Pass options to the signature algorithm during sign or verify operations.
+Pass options to the signature algorithm during sign operations.
+Names and values of these options are algorithm-specific.
+
+=item B<-vfyopt> I<nm>:I<v>
+
+Pass options to the signature algorithm during verify operations.
 Names and values of these options are algorithm-specific.
 
 =item B<-passin> I<arg>
diff --git a/doc/man3/X509_get0_distinguishing_id.pod b/doc/man3/X509_get0_distinguishing_id.pod
new file mode 100644
index 0000000000..2dd06e716d
--- /dev/null
+++ b/doc/man3/X509_get0_distinguishing_id.pod
@@ -0,0 +1,71 @@
+=pod
+
+=head1 NAME
+
+X509_get0_distinguishing_id, X509_set0_distinguishing_id,
+X509_REQ_get0_distinguishing_id, X509_REQ_set0_distinguishing_id
+- get or set the Distinguishing ID for certificate operations
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+ ASN1_OCTET_STRING *X509_get0_distinguishing_id(X509 *x);
+ void X509_set0_distinguishing_id(X509 *x, ASN1_OCTET_STRING *distid);
+ ASN1_OCTET_STRING *X509_REQ_get0_distinguishing_id(X509_REQ *x);
+ void X509_REQ_set0_distinguishing_id(X509_REQ *x, ASN1_OCTET_STRING *distid);
+
+=head1 DESCRIPTION
+
+The Distinguishing ID is defined in FIPS 196 as follows:
+
+=over 4
+
+I<Distinguishing  identifier>: information which unambiguously distinguishes
+an entity in the authentication process.
+
+=back
+
+The SM2 signature algorithm requires a Distinguishing ID value when generating
+and verifying a signature, but the Ddistinguishing ID may also find other uses.
+In the context of SM2, the Distinguishing ID is often referred to as the "SM2
+ID".
+
+For the purpose off verifying a certificate or a certification request, a
+Distinguishing ID may be attached to it, so functions like L<X509_verify(3)>
+or L<X509_REQ_verify(3)> have easy access to that identity for signature
+verification.
+
+X509_get0_distinguishing_id() gets the Distinguishing ID value of a certificate
+B<x> by returning an B<ASN1_OCTET_STRING> object which should not be freed by
+the caller.
+
+X509_set0_distinguishing_id() assigns B<distid> to the certificate B<x>.
+Calling this function transfers the memory management of the value to the X509
+object, and therefore the value that has been passed in should not be freed by
+the caller after this function has been called.
+
+X509_REQ_get0_distinguishing_id() and X509_REQ_set0_distinguishing_id()
+have the same functionality as X509_get0_distinguishing_id() and
+X509_set0_distinguishing_id() except that they deal with  B<X509_REQ>
+objects instead of B<X509>.
+
+=head1 RETURN VALUES
+
+X509_set0_distinguishing_id() and X509_REQ_set0_distinguishing_id() do not
+return a value.
+
+=head1 SEE ALSO
+
+L<X509_verify(3)>, L<SM2(7)>
+
+=head1 COPYRIGHT
+
+Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/X509_get0_sm2_id.pod b/doc/man3/X509_get0_sm2_id.pod
deleted file mode 100644
index d8a85d7f8b..0000000000
--- a/doc/man3/X509_get0_sm2_id.pod
+++ /dev/null
@@ -1,55 +0,0 @@
-=pod
-
-=head1 NAME
-
-X509_get0_sm2_id, X509_set0_sm2_id,
-X509_REQ_get0_sm2_id, X509_REQ_set0_sm2_id
-- get or set SM2 ID for certificate operations
-
-=head1 SYNOPSIS
-
- #include <openssl/x509.h>
-
- ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x);
- void X509_set0_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id);
- ASN1_OCTET_STRING *X509_REQ_get0_sm2_id(X509_REQ *x);
- void X509_REQ_set0_sm2_id(X509_REQ *x, ASN1_OCTET_STRING *sm2_id);
-
-=head1 DESCRIPTION
-
-X509_get0_sm2_id() gets the ID value of an SM2 certificate B<x> by returning an
-B<ASN1_OCTET_STRING> object which should not be freed by the caller.
-
-X509_set0_sm2_id() sets the B<sm2_id> value to an SM2 certificate B<x>. Calling
-this function transfers the memory management of the value to the X509 object,
-and therefore the value that has been passed in should not be freed by the
-caller after this function has been called.
-
-X509_REQ_get0_sm2_id() and X509_REQ_set0_sm2_id() have the same functionality
-as X509_get0_sm2_id() and X509_set0_sm2_id() except that they deal with
-B<X509_REQ> objects instead of B<X509>.
-
-=head1 NOTES
-
-SM2 signature algorithm requires an ID value when generating and verifying a
-signature. The functions described in this manual provide the user with the
-ability to set and retrieve the SM2 ID value.
-
-=head1 RETURN VALUES
-
-X509_set0_sm2_id() and X509_REQ_set0_sm2_id() do not return a value.
-
-=head1 SEE ALSO
-
-L<X509_verify(3)>, L<SM2(7)>
-
-=head1 COPYRIGHT
-
-Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
-
-Licensed under the Apache License 2.0 (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
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
index 744731aefe..c9d3075b82 100644
--- a/include/crypto/evp.h
+++ b/include/crypto/evp.h
@@ -74,6 +74,8 @@ struct evp_pkey_ctx_st {
     EVP_PKEY *peerkey;
     /* Algorithm specific data */
     void *data;
+    /* Indicator if digest_custom needs to be called */
+    unsigned int flag_call_digest_custom:1;
 } /* EVP_PKEY_CTX */ ;
 
 #define EVP_PKEY_FLAG_DYNAMIC   1
diff --git a/include/crypto/x509.h b/include/crypto/x509.h
index 602a72fd27..edd85b6db0 100644
--- a/include/crypto/x509.h
+++ b/include/crypto/x509.h
@@ -71,9 +71,9 @@ struct X509_req_st {
     ASN1_BIT_STRING *signature; /* signature */
     CRYPTO_REF_COUNT references;
     CRYPTO_RWLOCK *lock;
-# ifndef OPENSSL_NO_SM2
-    ASN1_OCTET_STRING *sm2_id;
-# endif
+
+    /* Set on live certificates for authentication purposes */
+    ASN1_OCTET_STRING *distinguishing_id;
 };
 
 struct X509_crl_info_st {
@@ -186,9 +186,9 @@ struct x509_st {
     X509_CERT_AUX *aux;
     CRYPTO_RWLOCK *lock;
     volatile int ex_cached;
-# ifndef OPENSSL_NO_SM2
-    ASN1_OCTET_STRING *sm2_id;
-# endif
+
+    /* Set on live certificates for authentication purposes */
+    ASN1_OCTET_STRING *distinguishing_id;
 } /* X509 */ ;
 
 /*
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 80328cb2eb..82feb75efb 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -581,12 +581,10 @@ void X509_get0_signature(const ASN1_BIT_STRING **psig,
                          const X509_ALGOR **palg, const X509 *x);
 int X509_get_signature_nid(const X509 *x);
 
-# ifndef OPENSSL_NO_SM2
-void X509_set0_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id);
-ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x);
-void X509_REQ_set0_sm2_id(X509_REQ *x, ASN1_OCTET_STRING *sm2_id);
-ASN1_OCTET_STRING *X509_REQ_get0_sm2_id(X509_REQ *x);
-# endif
+void X509_set0_distinguishing_id(X509 *x, ASN1_OCTET_STRING *d_id);
+ASN1_OCTET_STRING *X509_get0_distinguishing_id(X509 *x);
+void X509_REQ_set0_distinguishing_id(X509_REQ *x, ASN1_OCTET_STRING *d_id);
+ASN1_OCTET_STRING *X509_REQ_get0_distinguishing_id(X509_REQ *x);
 
 int X509_trusted(const X509 *x);
 int X509_alias_set1(X509 *x, const unsigned char *name, int len);
diff --git a/test/ecdsatest.c b/test/ecdsatest.c
index 9747fb9042..4e343f0834 100644
--- a/test/ecdsatest.c
+++ b/test/ecdsatest.c
@@ -212,20 +212,9 @@ static int set_sm2_id(EVP_MD_CTX *mctx, EVP_PKEY *pkey)
     static const char sm2_id[] = { 1, 2, 3, 4, 'l', 'e', 't', 't', 'e', 'r' };
     EVP_PKEY_CTX *pctx;
 
-    if (!TEST_ptr(pctx = EVP_PKEY_CTX_new(pkey, NULL))
+    if (!TEST_ptr(pctx = EVP_MD_CTX_pkey_ctx(mctx))
         || !TEST_int_gt(EVP_PKEY_CTX_set1_id(pctx, sm2_id, sizeof(sm2_id)), 0))
         return 0;
-    EVP_MD_CTX_set_pkey_ctx(mctx, pctx);
-    return 1;
-}
-
-static int clean_sm2_id(EVP_MD_CTX *mctx)
-{
-    EVP_PKEY_CTX *pctx;
-
-    if (!TEST_ptr(pctx = EVP_MD_CTX_pkey_ctx(mctx)))
-        return 0;
-    EVP_PKEY_CTX_free(pctx);
     return 1;
 }
 
@@ -283,46 +272,40 @@ static int test_builtin(int n, int as)
     if (!TEST_int_ge(temp, 0)
         || !TEST_ptr(sig = OPENSSL_malloc(sig_len = (size_t)temp))
         /* create a signature */
-        || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
         || !TEST_true(EVP_DigestSignInit(mctx, NULL, NULL, NULL, pkey))
+        || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
         || !TEST_true(EVP_DigestSign(mctx, sig, &sig_len, tbs, sizeof(tbs)))
         || !TEST_int_le(sig_len, ECDSA_size(eckey))
-        || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
         || !TEST_true(EVP_MD_CTX_reset(mctx))
         /* negative test, verify with wrong key, 0 return */
-        || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey_neg))
         || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey_neg))
+        || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey_neg))
         || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 0)
-        || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
         || !TEST_true(EVP_MD_CTX_reset(mctx))
         /* negative test, verify with wrong signature length, -1 return */
-        || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
         || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+        || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
         || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len - 1, tbs, sizeof(tbs)), -1)
-        || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
         || !TEST_true(EVP_MD_CTX_reset(mctx))
         /* positive test, verify with correct key, 1 return */
-        || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
         || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+        || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
         || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1)
-        || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
         || !TEST_true(EVP_MD_CTX_reset(mctx)))
         goto err;
 
     /* muck with the message, test it fails with 0 return */
     tbs[0] ^= 1;
-    if ((as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
-        || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+    if (!TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+        || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
         || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 0)
-        || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
         || !TEST_true(EVP_MD_CTX_reset(mctx)))
         goto err;
     /* un-muck and test it verifies */
     tbs[0] ^= 1;
-    if ((as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
-        || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+    if (!TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+        || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
         || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1)
-        || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
         || !TEST_true(EVP_MD_CTX_reset(mctx)))
         goto err;
 
@@ -355,18 +338,16 @@ static int test_builtin(int n, int as)
     offset = tbs[0] % sig_len;
     dirt = tbs[1] ? tbs[1] : 1;
     sig[offset] ^= dirt;
-    if ((as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
-        || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+    if (!TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+        || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
         || !TEST_int_ne(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1)
-        || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
         || !TEST_true(EVP_MD_CTX_reset(mctx)))
         goto err;
     /* un-muck and test it verifies */
     sig[offset] ^= dirt;
-    if ((as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
-        || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+    if (!TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+        || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
         || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1)
-        || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
         || !TEST_true(EVP_MD_CTX_reset(mctx)))
         goto err;
 
diff --git a/test/recipes/20-test_pkeyutl.t b/test/recipes/20-test_pkeyutl.t
index f923f7cdc8..2d9aae29cd 100644
--- a/test/recipes/20-test_pkeyutl.t
+++ b/test/recipes/20-test_pkeyutl.t
@@ -29,13 +29,13 @@ SKIP: {
                       '-in', srctop_file('test', 'certs', 'sm2.pem'),
                       '-inkey', srctop_file('test', 'certs', 'sm2.key'),
                       '-out', 'sm2.sig', '-rawin',
-                      '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid']))),
+                      '-digest', 'sm3', '-pkeyopt', 'distid:someid']))),
                       "Sign a piece of data using SM2");
     ok_nofips(run(app(([ 'openssl', 'pkeyutl', '-verify', '-certin',
                       '-in', srctop_file('test', 'certs', 'sm2.pem'),
                       '-inkey', srctop_file('test', 'certs', 'sm2.pem'),
                       '-sigfile', 'sm2.sig', '-rawin',
-                      '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid']))),
+                      '-digest', 'sm3', '-pkeyopt', 'distid:someid']))),
                       "Verify an SM2 signature against a piece of data");
 }
 
diff --git a/test/recipes/25-test_req.t b/test/recipes/25-test_req.t
index 662109c896..0567adf702 100644
--- a/test/recipes/25-test_req.t
+++ b/test/recipes/25-test_req.t
@@ -191,27 +191,27 @@ subtest "generating SM2 certificate requests" => sub {
         ok(run(app(["openssl", "req",
                     "-config", srctop_file("test", "test.cnf"),
                     "-new", "-key", srctop_file("test", "certs", "sm2.key"),
-                    "-sigopt", "sm2_id:1234567812345678",
+                    "-sigopt", "distid:1234567812345678",
                     "-out", "testreq-sm2.pem", "-sm3"])),
            "Generating SM2 certificate request");
 
         ok(run(app(["openssl", "req",
                     "-config", srctop_file("test", "test.cnf"),
                     "-verify", "-in", "testreq-sm2.pem", "-noout",
-                    "-sm2-id", "1234567812345678", "-sm3"])),
+                    "-vfyopt", "distid:1234567812345678", "-sm3"])),
            "Verifying signature on SM2 certificate request");
 
         ok(run(app(["openssl", "req",
                     "-config", srctop_file("test", "test.cnf"),
                     "-new", "-key", srctop_file("test", "certs", "sm2.key"),
-                    "-sigopt", "sm2_hex_id:DEADBEEF",
+                    "-sigopt", "hexdistid:DEADBEEF",
                     "-out", "testreq-sm2.pem", "-sm3"])),
            "Generating SM2 certificate request with hex id");
 
         ok(run(app(["openssl", "req",
                     "-config", srctop_file("test", "test.cnf"),
                     "-verify", "-in", "testreq-sm2.pem", "-noout",
-                    "-sm2-hex-id", "DEADBEEF", "-sm3"])),
+                    "-vfyopt", "hexdistid:DEADBEEF", "-sm3"])),
            "Verifying signature on SM2 certificate request");
     }
 };
diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t
index 219e7e1149..c0de243708 100644
--- a/test/recipes/25-test_verify.t
+++ b/test/recipes/25-test_verify.t
@@ -378,10 +378,8 @@ SKIP: {
     skip "SM2 is not supported by this OpenSSL build", 2
 	      if disabled("sm2");
 
-   # Test '-sm2-id' and '-sm2-hex-id'  option
-   ok_nofips(verify("sm2", "any", ["sm2-ca-cert"], [], "-sm2-id", "1234567812345678"),
+   ok_nofips(verify("sm2", "any", ["sm2-ca-cert"], [], "-vfyopt", "distid:1234567812345678"),
        "SM2 ID test");
-   ok_nofips(verify("sm2", "any", ["sm2-ca-cert"], [], "-sm2-hex-id",
-             "31323334353637383132333435363738"),
+   ok_nofips(verify("sm2", "any", ["sm2-ca-cert"], [], "-vfyopt", "hexdistid:31323334353637383132333435363738"),
        "SM2 hex ID test");
 }
diff --git a/test/recipes/80-test_ca.t b/test/recipes/80-test_ca.t
index c01bc389fa..5b4f59b69b 100644
--- a/test/recipes/80-test_ca.t
+++ b/test/recipes/80-test_ca.t
@@ -59,8 +59,8 @@ SKIP: {
                        srctop_file("test", "CAss.cnf"),
                        "-in", srctop_file("test", "certs", "sm2-csr.pem"),
                        "-out", "sm2-test.crt",
-                       "-sigopt", "sm2_id:1234567812345678",
-                       "-sm2-id", "1234567812345678",
+                       "-sigopt", "distid:1234567812345678",
+                       "-vfyopt", "distid:1234567812345678",
                        "-md", "sm3",
                        "-cert", srctop_file("test", "certs", "sm2-root.crt"),
                        "-keyfile", srctop_file("test", "certs", "sm2-root.key")]))),
diff --git a/test/verify_extra_test.c b/test/verify_extra_test.c
index 91ed31b374..e8fe79b19a 100644
--- a/test/verify_extra_test.c
+++ b/test/verify_extra_test.c
@@ -179,15 +179,13 @@ static int test_store_ctx(void)
 
 OPT_TEST_DECLARE_USAGE("roots.pem untrusted.pem bad.pem\n")
 
-#ifndef OPENSSL_NO_SM2
-static int test_sm2_id(void)
+static int test_distinguishing_id(void)
 {
-    /* we only need an X509 structure, no matter if it's a real SM2 cert */
     X509 *x = NULL;
     BIO *bio = NULL;
     int ret = 0;
     ASN1_OCTET_STRING *v = NULL, *v2 = NULL;
-    char *sm2id = "this is an ID";
+    char *distid = "this is an ID";
 
     bio = BIO_new_file(bad_f, "r");
     if (bio == NULL)
@@ -201,14 +199,15 @@ static int test_sm2_id(void)
     if (v == NULL)
         goto err;
 
-    if (!ASN1_OCTET_STRING_set(v, (unsigned char *)sm2id, (int)strlen(sm2id))) {
+    if (!ASN1_OCTET_STRING_set(v, (unsigned char *)distid,
+                               (int)strlen(distid))) {
         ASN1_OCTET_STRING_free(v);
         goto err;
     }
 
-    X509_set0_sm2_id(x, v);
+    X509_set0_distinguishing_id(x, v);
 
-    v2 = X509_get0_sm2_id(x);
+    v2 = X509_get0_distinguishing_id(x);
     if (!TEST_ptr(v2)
             || !TEST_int_eq(ASN1_OCTET_STRING_cmp(v, v2), 0))
         goto err;
@@ -220,14 +219,13 @@ static int test_sm2_id(void)
     return ret;
 }
 
-static int test_req_sm2_id(void)
+static int test_req_distinguishing_id(void)
 {
-    /* we only need an X509_REQ structure, no matter if it's a real SM2 cert */
     X509_REQ *x = NULL;
     BIO *bio = NULL;
     int ret = 0;
     ASN1_OCTET_STRING *v = NULL, *v2 = NULL;
-    char *sm2id = "this is an ID";
+    char *distid = "this is an ID";
 
     bio = BIO_new_file(req_f, "r");
     if (bio == NULL)
@@ -241,14 +239,15 @@ static int test_req_sm2_id(void)
     if (v == NULL)
         goto err;
 
-    if (!ASN1_OCTET_STRING_set(v, (unsigned char *)sm2id, (int)strlen(sm2id))) {
+    if (!ASN1_OCTET_STRING_set(v, (unsigned char *)distid,
+                               (int)strlen(distid))) {
         ASN1_OCTET_STRING_free(v);
         goto err;
     }
 
-    X509_REQ_set0_sm2_id(x, v);
+    X509_REQ_set0_distinguishing_id(x, v);
 
-    v2 = X509_REQ_get0_sm2_id(x);
+    v2 = X509_REQ_get0_distinguishing_id(x);
     if (!TEST_ptr(v2)
             || !TEST_int_eq(ASN1_OCTET_STRING_cmp(v, v2), 0))
         goto err;
@@ -259,7 +258,6 @@ static int test_req_sm2_id(void)
     BIO_free(bio);
     return ret;
 }
-#endif
 
 int setup_tests(void)
 {
@@ -276,9 +274,7 @@ int setup_tests(void)
 
     ADD_TEST(test_alt_chains_cert_forgery);
     ADD_TEST(test_store_ctx);
-#ifndef OPENSSL_NO_SM2
-    ADD_TEST(test_sm2_id);
-    ADD_TEST(test_req_sm2_id);
-#endif
+    ADD_TEST(test_distinguishing_id);
+    ADD_TEST(test_req_distinguishing_id);
     return 1;
 }
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 30978d2fb0..5f30a779fc 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4604,8 +4604,8 @@ OSSL_PARAM_get_utf8_ptr                 ?	3_0_0	EXIST::FUNCTION:
 OSSL_PARAM_set_utf8_ptr                 ?	3_0_0	EXIST::FUNCTION:
 OSSL_PARAM_get_octet_ptr                ?	3_0_0	EXIST::FUNCTION:
 OSSL_PARAM_set_octet_ptr                ?	3_0_0	EXIST::FUNCTION:
-X509_set0_sm2_id                        ?	3_0_0	EXIST::FUNCTION:SM2
-X509_get0_sm2_id                        ?	3_0_0	EXIST::FUNCTION:SM2
+X509_set0_distinguishing_id             ?	3_0_0	EXIST::FUNCTION:
+X509_get0_distinguishing_id             ?	3_0_0	EXIST::FUNCTION:
 EVP_PKEY_get0_engine                    ?	3_0_0	EXIST::FUNCTION:ENGINE
 EVP_MD_up_ref                           ?	3_0_0	EXIST::FUNCTION:
 EVP_MD_fetch                            ?	3_0_0	EXIST::FUNCTION:
@@ -4650,8 +4650,8 @@ BN_CTX_new_ex                           ?	3_0_0	EXIST::FUNCTION:
 BN_CTX_secure_new_ex                    ?	3_0_0	EXIST::FUNCTION:
 OPENSSL_thread_stop_ex                  ?	3_0_0	EXIST::FUNCTION:
 OSSL_PARAM_locate_const                 ?	3_0_0	EXIST::FUNCTION:
-X509_REQ_set0_sm2_id                    ?	3_0_0	EXIST::FUNCTION:SM2
-X509_REQ_get0_sm2_id                    ?	3_0_0	EXIST::FUNCTION:SM2
+X509_REQ_set0_distinguishing_id         ?	3_0_0	EXIST::FUNCTION:
+X509_REQ_get0_distinguishing_id         ?	3_0_0	EXIST::FUNCTION:
 BN_rand_ex                              ?	3_0_0	EXIST::FUNCTION:
 BN_priv_rand_ex                         ?	3_0_0	EXIST::FUNCTION:
 BN_rand_range_ex                        ?	3_0_0	EXIST::FUNCTION:


More information about the openssl-commits mailing list