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,
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;
"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"},
{"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"},
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;
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) {
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;
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:
}
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,
}
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) {
}
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) {
ret = 0;
end:
- if (sm2_free)
- OPENSSL_free(sm2_id);
if (ret)
ERR_print_errors(bio_err);
BIO_free_all(Sout);
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);
}
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;
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;
}
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,
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");
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,
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)
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;
{"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"},
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;
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();
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;
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();
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;
}
ret = 0;
end:
- if (sm2_free)
- OPENSSL_free(sm2_id);
if (ret) {
ERR_print_errors(bio_err);
}
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
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;
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.
/* 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,
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;
}
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;
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;
}
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 {
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;
"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,
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;
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:
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;
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);
}
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;
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();
#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,
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,
{"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"},
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;
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;
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);
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");
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);
}
/* 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))
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:
[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
=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)
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 -}
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:
=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.
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
[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
=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.
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 -}
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:
[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 -}
[B<-->]
[I<certificate> ...]
-=for openssl ifdef engine sm2-id sm2-hex-id
+=for openssl ifdef engine
=head1 DESCRIPTION
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.
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 -}
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.
[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 -}
=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>