summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/ca.c110
-rw-r--r--apps/include/apps.h1
-rw-r--r--apps/pkeyutl.c16
-rw-r--r--apps/req.c183
-rw-r--r--apps/verify.c83
-rw-r--r--apps/x509.c29
-rw-r--r--doc/man1/openssl-ca.pod.in30
-rw-r--r--doc/man1/openssl-pkeyutl.pod.in12
-rw-r--r--doc/man1/openssl-req.pod.in34
-rw-r--r--doc/man1/openssl-verify.pod.in22
-rw-r--r--doc/man1/openssl-x509.pod.in8
11 files changed, 200 insertions, 328 deletions
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 ccafaef5f1..de068d9670 100644
--- a/apps/include/apps.h
+++ b/apps/include/apps.h
@@ -203,6 +203,7 @@ 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,
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 d1c93a68f7..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,6 +1639,44 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx)
return 1;
}
+static int do_pkey_ctx_init(EVP_PKEY_CTX *pkctx, 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 (pkey_ctrl_string(pkctx, opt) <= 0) {
+ BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
+ ERR_print_errors(bio_err);
+ return 0;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ return 1;
+}
+
static int do_x509_req_init(X509_REQ *x, STACK_OF(OPENSSL_STRING) *opts)
{
int i;
@@ -1708,28 +1700,10 @@ 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;
- EVP_PKEY_CTX *pctx = NULL;
- int i, def_nid, ret = 0;
+ int def_nid;
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;
- }
- }
- EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
- }
+ return 0;
/*
* EVP_PKEY_get_default_digest_nid() returns 2 if the digest is mandatory
* for this algorithm.
@@ -1739,36 +1713,8 @@ static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
/* The signing algorithm requires there to be no digest */
md = NULL;
}
- 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);
- ERR_print_errors(bio_err);
- goto err;
- }
- }
-
- ret = 1;
- err:
- if (!ret)
- EVP_PKEY_CTX_free(pctx);
- return ret;
-}
-
-static void do_sign_cleanup(EVP_MD_CTX *ctx, EVP_PKEY *pkey)
-{
- /*
- * With SM2, do_sign_init() attached an EVP_PKEY_CTX to the EVP_MD_CTX,
- * and we have to free it explicitly.
- */
- 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);
- }
+ 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,
@@ -1777,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;
}
@@ -1791,14 +1735,21 @@ 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)
{
@@ -1815,10 +1766,8 @@ int do_X509_CRL_sign(X509_CRL *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_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/doc/man1/openssl-ca.pod.in b/do