diff options
-rw-r--r-- | apps/ca.c | 110 | ||||
-rw-r--r-- | apps/include/apps.h | 1 | ||||
-rw-r--r-- | apps/pkeyutl.c | 16 | ||||
-rw-r--r-- | apps/req.c | 183 | ||||
-rw-r--r-- | apps/verify.c | 83 | ||||
-rw-r--r-- | apps/x509.c | 29 | ||||
-rw-r--r-- | doc/man1/openssl-ca.pod.in | 30 | ||||
-rw-r--r-- | doc/man1/openssl-pkeyutl.pod.in | 12 | ||||
-rw-r--r-- | doc/man1/openssl-req.pod.in | 34 | ||||
-rw-r--r-- | doc/man1/openssl-verify.pod.in | 22 | ||||
-rw-r--r-- | doc/man1/openssl-x509.pod.in | 8 |
11 files changed, 200 insertions, 328 deletions
@@ -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 |