Support SM2 certificate signing
SM2 certificate signing request can be created and signed by OpenSSL now, both in library and apps. Documentation and test cases are added. Reviewed-by: Tim Hudson <tjh@openssl.org> Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/9085)
This commit is contained in:
parent
53a11c6da0
commit
bc42bd6298
3
CHANGES
3
CHANGES
@ -9,6 +9,9 @@
|
|||||||
|
|
||||||
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
|
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
|
||||||
|
|
||||||
|
*) Support SM2 signing and verification schemes with X509 certificate.
|
||||||
|
[Paul Yang]
|
||||||
|
|
||||||
*) Use SHA256 as the default digest for TS query in the ts app.
|
*) Use SHA256 as the default digest for TS query in the ts app.
|
||||||
[Tomas Mraz]
|
[Tomas Mraz]
|
||||||
|
|
||||||
|
68
apps/ca.c
68
apps/ca.c
@ -96,7 +96,8 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
|
|||||||
const char *enddate,
|
const char *enddate,
|
||||||
long days, int batch, const char *ext_sect, CONF *conf,
|
long days, int batch, const char *ext_sect, CONF *conf,
|
||||||
int verbose, unsigned long certopt, unsigned long nameopt,
|
int verbose, unsigned long certopt, unsigned long nameopt,
|
||||||
int default_op, int ext_copy, int selfsign);
|
int default_op, int ext_copy, int selfsign,
|
||||||
|
unsigned char *sm2_id, size_t sm2idlen);
|
||||||
static int certify_cert(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(CONF_VALUE) *policy, CA_DB *db,
|
STACK_OF(CONF_VALUE) *policy, CA_DB *db,
|
||||||
@ -147,7 +148,7 @@ typedef enum OPTION_choice {
|
|||||||
OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID,
|
OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID,
|
||||||
OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS,
|
OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS,
|
||||||
OPT_RAND_SERIAL,
|
OPT_RAND_SERIAL,
|
||||||
OPT_R_ENUM,
|
OPT_R_ENUM, OPT_SM2ID, OPT_SM2HEXID,
|
||||||
/* Do not change the order here; see related case statements below */
|
/* Do not change the order here; see related case statements below */
|
||||||
OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, OPT_CRL_CA_COMPROMISE
|
OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, OPT_CRL_CA_COMPROMISE
|
||||||
} OPTION_CHOICE;
|
} OPTION_CHOICE;
|
||||||
@ -217,6 +218,12 @@ const OPTIONS ca_options[] = {
|
|||||||
OPT_R_OPTIONS,
|
OPT_R_OPTIONS,
|
||||||
#ifndef OPENSSL_NO_ENGINE
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
||||||
|
#endif
|
||||||
|
#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
|
#endif
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
@ -262,6 +269,9 @@ int ca_main(int argc, char **argv)
|
|||||||
REVINFO_TYPE rev_type = REV_NONE;
|
REVINFO_TYPE rev_type = REV_NONE;
|
||||||
X509_REVOKED *r = NULL;
|
X509_REVOKED *r = NULL;
|
||||||
OPTION_CHOICE o;
|
OPTION_CHOICE o;
|
||||||
|
unsigned char *sm2_id = NULL;
|
||||||
|
size_t sm2_idlen = 0;
|
||||||
|
int sm2_free = 0;
|
||||||
|
|
||||||
prog = opt_init(argc, argv, ca_options);
|
prog = opt_init(argc, argv, ca_options);
|
||||||
while ((o = opt_next()) != OPT_EOF) {
|
while ((o = opt_next()) != OPT_EOF) {
|
||||||
@ -425,6 +435,30 @@ opthelp:
|
|||||||
case OPT_ENGINE:
|
case OPT_ENGINE:
|
||||||
e = setup_engine(opt_arg(), 0);
|
e = setup_engine(opt_arg(), 0);
|
||||||
break;
|
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:
|
end_of_options:
|
||||||
@ -913,7 +947,8 @@ end_of_options:
|
|||||||
j = certify(&x, infile, pkey, x509p, dgst, sigopts, attribs, db,
|
j = certify(&x, infile, pkey, x509p, dgst, sigopts, attribs, db,
|
||||||
serial, subj, chtype, multirdn, email_dn, startdate,
|
serial, subj, chtype, multirdn, email_dn, startdate,
|
||||||
enddate, days, batch, extensions, conf, verbose,
|
enddate, days, batch, extensions, conf, verbose,
|
||||||
certopt, get_nameopt(), default_op, ext_copy, selfsign);
|
certopt, get_nameopt(), default_op, ext_copy, selfsign,
|
||||||
|
sm2_id, sm2_idlen);
|
||||||
if (j < 0)
|
if (j < 0)
|
||||||
goto end;
|
goto end;
|
||||||
if (j > 0) {
|
if (j > 0) {
|
||||||
@ -932,7 +967,8 @@ end_of_options:
|
|||||||
j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, attribs, db,
|
j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, attribs, db,
|
||||||
serial, subj, chtype, multirdn, email_dn, startdate,
|
serial, subj, chtype, multirdn, email_dn, startdate,
|
||||||
enddate, days, batch, extensions, conf, verbose,
|
enddate, days, batch, extensions, conf, verbose,
|
||||||
certopt, get_nameopt(), default_op, ext_copy, selfsign);
|
certopt, get_nameopt(), default_op, ext_copy, selfsign,
|
||||||
|
sm2_id, sm2_idlen);
|
||||||
if (j < 0)
|
if (j < 0)
|
||||||
goto end;
|
goto end;
|
||||||
if (j > 0) {
|
if (j > 0) {
|
||||||
@ -1230,6 +1266,8 @@ end_of_options:
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
if (sm2_free)
|
||||||
|
OPENSSL_free(sm2_id);
|
||||||
if (ret)
|
if (ret)
|
||||||
ERR_print_errors(bio_err);
|
ERR_print_errors(bio_err);
|
||||||
BIO_free_all(Sout);
|
BIO_free_all(Sout);
|
||||||
@ -1268,7 +1306,8 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
|
|||||||
const char *enddate,
|
const char *enddate,
|
||||||
long days, int batch, const char *ext_sect, CONF *lconf,
|
long days, int batch, const char *ext_sect, CONF *lconf,
|
||||||
int verbose, unsigned long certopt, unsigned long nameopt,
|
int verbose, unsigned long certopt, unsigned long nameopt,
|
||||||
int default_op, int ext_copy, int selfsign)
|
int default_op, int ext_copy, int selfsign,
|
||||||
|
unsigned char *sm2id, size_t sm2idlen)
|
||||||
{
|
{
|
||||||
X509_REQ *req = NULL;
|
X509_REQ *req = NULL;
|
||||||
BIO *in = NULL;
|
BIO *in = NULL;
|
||||||
@ -1300,6 +1339,25 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
|
|||||||
BIO_printf(bio_err, "error unpacking public key\n");
|
BIO_printf(bio_err, "error unpacking public key\n");
|
||||||
goto end;
|
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 = X509_REQ_verify(req, pktmp);
|
||||||
pktmp = NULL;
|
pktmp = NULL;
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
|
149
apps/req.c
149
apps/req.c
@ -90,7 +90,7 @@ typedef enum OPTION_choice {
|
|||||||
OPT_VERIFY, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8,
|
OPT_VERIFY, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8,
|
||||||
OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT, OPT_X509,
|
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_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, OPT_ADDEXT, OPT_EXTENSIONS,
|
||||||
OPT_REQEXTS, OPT_PRECERT, OPT_MD,
|
OPT_REQEXTS, OPT_PRECERT, OPT_MD, OPT_SM2ID, OPT_SM2HEXID,
|
||||||
OPT_R_ENUM
|
OPT_R_ENUM
|
||||||
} OPTION_CHOICE;
|
} OPTION_CHOICE;
|
||||||
|
|
||||||
@ -145,6 +145,12 @@ const OPTIONS req_options[] = {
|
|||||||
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
||||||
{"keygen_engine", OPT_KEYGEN_ENGINE, 's',
|
{"keygen_engine", OPT_KEYGEN_ENGINE, 's',
|
||||||
"Specify engine to be used for key generation operations"},
|
"Specify engine to be used for key generation operations"},
|
||||||
|
#endif
|
||||||
|
#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
|
#endif
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
@ -239,6 +245,9 @@ int req_main(int argc, char **argv)
|
|||||||
int nodes = 0, newhdr = 0, subject = 0, pubkey = 0, precert = 0;
|
int nodes = 0, newhdr = 0, subject = 0, pubkey = 0, precert = 0;
|
||||||
long newkey = -1;
|
long newkey = -1;
|
||||||
unsigned long chtype = MBSTRING_ASC, reqflag = 0;
|
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
|
#ifndef OPENSSL_NO_DES
|
||||||
cipher = EVP_des_ede3_cbc();
|
cipher = EVP_des_ede3_cbc();
|
||||||
@ -414,6 +423,29 @@ int req_main(int argc, char **argv)
|
|||||||
goto opthelp;
|
goto opthelp;
|
||||||
digest = md_alg;
|
digest = md_alg;
|
||||||
break;
|
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();
|
argc = opt_num_rest();
|
||||||
@ -844,6 +876,26 @@ int req_main(int argc, char **argv)
|
|||||||
goto end;
|
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 = X509_REQ_verify(req, tpubkey);
|
||||||
|
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
@ -942,6 +994,8 @@ int req_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
end:
|
end:
|
||||||
|
if (sm2_free)
|
||||||
|
OPENSSL_free(sm2_id);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ERR_print_errors(bio_err);
|
ERR_print_errors(bio_err);
|
||||||
}
|
}
|
||||||
@ -1596,14 +1650,58 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_SM2
|
||||||
|
static int ec_pkey_is_sm2(EVP_PKEY *pkey)
|
||||||
|
{
|
||||||
|
EC_KEY *eckey = NULL;
|
||||||
|
const EC_GROUP *group = NULL;
|
||||||
|
|
||||||
|
if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2)
|
||||||
|
return 1;
|
||||||
|
if (EVP_PKEY_id(pkey) == EVP_PKEY_EC
|
||||||
|
&& (eckey = EVP_PKEY_get0_EC_KEY(pkey)) != NULL
|
||||||
|
&& (group = EC_KEY_get0_group(eckey)) != NULL
|
||||||
|
&& EC_GROUP_get_curve_name(group) == NID_sm2)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int do_sign_init(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)
|
const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
|
||||||
{
|
{
|
||||||
EVP_PKEY_CTX *pkctx = NULL;
|
EVP_PKEY_CTX *pkctx = NULL;
|
||||||
int i, def_nid;
|
#ifndef OPENSSL_NO_SM2
|
||||||
|
EVP_PKEY_CTX *pctx = NULL;
|
||||||
|
#endif
|
||||||
|
int i, def_nid, ret = 0;
|
||||||
|
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
return 0;
|
goto err;
|
||||||
|
#ifndef OPENSSL_NO_SM2
|
||||||
|
if (ec_pkey_is_sm2(pkey)) {
|
||||||
|
/* initialize some SM2-specific code */
|
||||||
|
if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) {
|
||||||
|
BIO_printf(bio_err, "Internal error.\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* EVP_PKEY_get_default_digest_nid() returns 2 if the digest is mandatory
|
* EVP_PKEY_get_default_digest_nid() returns 2 if the digest is mandatory
|
||||||
* for this algorithm.
|
* for this algorithm.
|
||||||
@ -1614,16 +1712,23 @@ static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
|
|||||||
md = NULL;
|
md = NULL;
|
||||||
}
|
}
|
||||||
if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
|
if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
|
||||||
return 0;
|
goto err;
|
||||||
for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
|
for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
|
||||||
char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
|
char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
|
||||||
if (pkey_ctrl_string(pkctx, sigopt) <= 0) {
|
if (pkey_ctrl_string(pkctx, sigopt) <= 0) {
|
||||||
BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt);
|
BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt);
|
||||||
ERR_print_errors(bio_err);
|
ERR_print_errors(bio_err);
|
||||||
return 0;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
|
ret = 1;
|
||||||
|
err:
|
||||||
|
#ifndef OPENSSL_NO_SM2
|
||||||
|
if (!ret)
|
||||||
|
EVP_PKEY_CTX_free(pctx);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
|
int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
|
||||||
@ -1631,10 +1736,20 @@ int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
|
|||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
|
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
|
||||||
|
#ifndef OPENSSL_NO_SM2
|
||||||
|
EVP_PKEY_CTX *pctx = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
rv = do_sign_init(mctx, pkey, md, sigopts);
|
rv = do_sign_init(mctx, pkey, md, sigopts);
|
||||||
if (rv > 0)
|
if (rv > 0)
|
||||||
rv = X509_sign_ctx(x, mctx);
|
rv = X509_sign_ctx(x, mctx);
|
||||||
|
#ifndef OPENSSL_NO_SM2
|
||||||
|
/* only in SM2 case we need to free the pctx explicitly */
|
||||||
|
if (ec_pkey_is_sm2(pkey)) {
|
||||||
|
pctx = EVP_MD_CTX_pkey_ctx(mctx);
|
||||||
|
EVP_PKEY_CTX_free(pctx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
EVP_MD_CTX_free(mctx);
|
EVP_MD_CTX_free(mctx);
|
||||||
return rv > 0 ? 1 : 0;
|
return rv > 0 ? 1 : 0;
|
||||||
}
|
}
|
||||||
@ -1644,9 +1759,20 @@ int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
|
|||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
|
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
|
||||||
|
#ifndef OPENSSL_NO_SM2
|
||||||
|
EVP_PKEY_CTX *pctx = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
rv = do_sign_init(mctx, pkey, md, sigopts);
|
rv = do_sign_init(mctx, pkey, md, sigopts);
|
||||||
if (rv > 0)
|
if (rv > 0)
|
||||||
rv = X509_REQ_sign_ctx(x, mctx);
|
rv = X509_REQ_sign_ctx(x, mctx);
|
||||||
|
#ifndef OPENSSL_NO_SM2
|
||||||
|
/* only in SM2 case we need to free the pctx explicitly */
|
||||||
|
if (ec_pkey_is_sm2(pkey)) {
|
||||||
|
pctx = EVP_MD_CTX_pkey_ctx(mctx);
|
||||||
|
EVP_PKEY_CTX_free(pctx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
EVP_MD_CTX_free(mctx);
|
EVP_MD_CTX_free(mctx);
|
||||||
return rv > 0 ? 1 : 0;
|
return rv > 0 ? 1 : 0;
|
||||||
}
|
}
|
||||||
@ -1656,9 +1782,20 @@ int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
|
|||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
|
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
|
||||||
|
#ifndef OPENSSL_NO_SM2
|
||||||
|
EVP_PKEY_CTX *pctx = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
rv = do_sign_init(mctx, pkey, md, sigopts);
|
rv = do_sign_init(mctx, pkey, md, sigopts);
|
||||||
if (rv > 0)
|
if (rv > 0)
|
||||||
rv = X509_CRL_sign_ctx(x, mctx);
|
rv = X509_CRL_sign_ctx(x, mctx);
|
||||||
|
#ifndef OPENSSL_NO_SM2
|
||||||
|
/* only in SM2 case we need to free the pctx explicitly */
|
||||||
|
if (ec_pkey_is_sm2(pkey)) {
|
||||||
|
pctx = EVP_MD_CTX_pkey_ctx(mctx);
|
||||||
|
EVP_PKEY_CTX_free(pctx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
EVP_MD_CTX_free(mctx);
|
EVP_MD_CTX_free(mctx);
|
||||||
return rv > 0 ? 1 : 0;
|
return rv > 0 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it,
|
|||||||
unsigned char *buf_in = NULL, *buf_out = NULL;
|
unsigned char *buf_in = NULL, *buf_out = NULL;
|
||||||
size_t inl = 0, outl = 0, outll = 0;
|
size_t inl = 0, outl = 0, outll = 0;
|
||||||
int signid, paramtype, buf_len = 0;
|
int signid, paramtype, buf_len = 0;
|
||||||
int rv;
|
int rv, pkey_id;
|
||||||
|
|
||||||
type = EVP_MD_CTX_md(ctx);
|
type = EVP_MD_CTX_md(ctx);
|
||||||
pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx));
|
pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx));
|
||||||
@ -184,9 +184,14 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it,
|
|||||||
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
|
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (!OBJ_find_sigid_by_algs(&signid,
|
|
||||||
EVP_MD_nid(type),
|
pkey_id =
|
||||||
pkey->ameth->pkey_id)) {
|
#ifndef OPENSSL_NO_SM2
|
||||||
|
EVP_PKEY_id(pkey) == NID_sm2 ? NID_sm2 :
|
||||||
|
#endif
|
||||||
|
pkey->ameth->pkey_id;
|
||||||
|
|
||||||
|
if (!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), pkey_id)) {
|
||||||
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
|
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
|
||||||
ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
|
ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -327,7 +327,8 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
|||||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_224 &&
|
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_224 &&
|
||||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_256 &&
|
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_256 &&
|
||||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_384 &&
|
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_384 &&
|
||||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512) {
|
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512 &&
|
||||||
|
EVP_MD_type((const EVP_MD *)p2) != NID_sm3) {
|
||||||
ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
|
ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1832,6 +1832,7 @@ X509_F_BUILD_CHAIN:106:build_chain
|
|||||||
X509_F_BY_FILE_CTRL:101:by_file_ctrl
|
X509_F_BY_FILE_CTRL:101:by_file_ctrl
|
||||||
X509_F_CHECK_NAME_CONSTRAINTS:149:check_name_constraints
|
X509_F_CHECK_NAME_CONSTRAINTS:149:check_name_constraints
|
||||||
X509_F_CHECK_POLICY:145:check_policy
|
X509_F_CHECK_POLICY:145:check_policy
|
||||||
|
X509_F_COMMON_VERIFY_SM2:165:common_verify_sm2
|
||||||
X509_F_DANE_I2D:107:dane_i2d
|
X509_F_DANE_I2D:107:dane_i2d
|
||||||
X509_F_DIR_CTRL:102:dir_ctrl
|
X509_F_DIR_CTRL:102:dir_ctrl
|
||||||
X509_F_GET_CERT_BY_SUBJECT:103:get_cert_by_subject
|
X509_F_GET_CERT_BY_SUBJECT:103:get_cert_by_subject
|
||||||
@ -1875,6 +1876,8 @@ X509_F_X509_REQ_CHECK_PRIVATE_KEY:144:X509_REQ_check_private_key
|
|||||||
X509_F_X509_REQ_PRINT_EX:121:X509_REQ_print_ex
|
X509_F_X509_REQ_PRINT_EX:121:X509_REQ_print_ex
|
||||||
X509_F_X509_REQ_PRINT_FP:122:X509_REQ_print_fp
|
X509_F_X509_REQ_PRINT_FP:122:X509_REQ_print_fp
|
||||||
X509_F_X509_REQ_TO_X509:123:X509_REQ_to_X509
|
X509_F_X509_REQ_TO_X509:123:X509_REQ_to_X509
|
||||||
|
X509_F_X509_REQ_VERIFY:163:X509_REQ_verify
|
||||||
|
X509_F_X509_REQ_VERIFY_SM2:164:x509_req_verify_sm2
|
||||||
X509_F_X509_STORE_ADD_CERT:124:X509_STORE_add_cert
|
X509_F_X509_STORE_ADD_CERT:124:X509_STORE_add_cert
|
||||||
X509_F_X509_STORE_ADD_CRL:125:X509_STORE_add_crl
|
X509_F_X509_STORE_ADD_CRL:125:X509_STORE_add_crl
|
||||||
X509_F_X509_STORE_ADD_LOOKUP:157:X509_STORE_add_lookup
|
X509_F_X509_STORE_ADD_LOOKUP:157:X509_STORE_add_lookup
|
||||||
|
@ -71,6 +71,9 @@ struct X509_req_st {
|
|||||||
ASN1_BIT_STRING *signature; /* signature */
|
ASN1_BIT_STRING *signature; /* signature */
|
||||||
CRYPTO_REF_COUNT references;
|
CRYPTO_REF_COUNT references;
|
||||||
CRYPTO_RWLOCK *lock;
|
CRYPTO_RWLOCK *lock;
|
||||||
|
# ifndef OPENSSL_NO_SM2
|
||||||
|
ASN1_OCTET_STRING *sm2_id;
|
||||||
|
# endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct X509_crl_info_st {
|
struct X509_crl_info_st {
|
||||||
|
@ -20,6 +20,7 @@ static const ERR_STRING_DATA X509_str_functs[] = {
|
|||||||
{ERR_PACK(ERR_LIB_X509, X509_F_CHECK_NAME_CONSTRAINTS, 0),
|
{ERR_PACK(ERR_LIB_X509, X509_F_CHECK_NAME_CONSTRAINTS, 0),
|
||||||
"check_name_constraints"},
|
"check_name_constraints"},
|
||||||
{ERR_PACK(ERR_LIB_X509, X509_F_CHECK_POLICY, 0), "check_policy"},
|
{ERR_PACK(ERR_LIB_X509, X509_F_CHECK_POLICY, 0), "check_policy"},
|
||||||
|
{ERR_PACK(ERR_LIB_X509, X509_F_COMMON_VERIFY_SM2, 0), "common_verify_sm2"},
|
||||||
{ERR_PACK(ERR_LIB_X509, X509_F_DANE_I2D, 0), "dane_i2d"},
|
{ERR_PACK(ERR_LIB_X509, X509_F_DANE_I2D, 0), "dane_i2d"},
|
||||||
{ERR_PACK(ERR_LIB_X509, X509_F_DIR_CTRL, 0), "dir_ctrl"},
|
{ERR_PACK(ERR_LIB_X509, X509_F_DIR_CTRL, 0), "dir_ctrl"},
|
||||||
{ERR_PACK(ERR_LIB_X509, X509_F_GET_CERT_BY_SUBJECT, 0),
|
{ERR_PACK(ERR_LIB_X509, X509_F_GET_CERT_BY_SUBJECT, 0),
|
||||||
@ -86,6 +87,9 @@ static const ERR_STRING_DATA X509_str_functs[] = {
|
|||||||
{ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_PRINT_EX, 0), "X509_REQ_print_ex"},
|
{ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_PRINT_EX, 0), "X509_REQ_print_ex"},
|
||||||
{ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_PRINT_FP, 0), "X509_REQ_print_fp"},
|
{ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_PRINT_FP, 0), "X509_REQ_print_fp"},
|
||||||
{ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_TO_X509, 0), "X509_REQ_to_X509"},
|
{ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_TO_X509, 0), "X509_REQ_to_X509"},
|
||||||
|
{ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_VERIFY, 0), "X509_REQ_verify"},
|
||||||
|
{ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_VERIFY_SM2, 0),
|
||||||
|
"x509_req_verify_sm2"},
|
||||||
{ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_ADD_CERT, 0),
|
{ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_ADD_CERT, 0),
|
||||||
"X509_STORE_add_cert"},
|
"X509_STORE_add_cert"},
|
||||||
{ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_ADD_CRL, 0),
|
{ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_ADD_CRL, 0),
|
||||||
|
@ -24,86 +24,105 @@
|
|||||||
# include "internal/asn1_int.h"
|
# include "internal/asn1_int.h"
|
||||||
# include "internal/evp_int.h"
|
# include "internal/evp_int.h"
|
||||||
|
|
||||||
static int x509_verify_sm2(X509 *x, EVP_PKEY *pkey, int mdnid, int pknid)
|
static int common_verify_sm2(void *data, EVP_PKEY *pkey,
|
||||||
|
int mdnid, int pknid, int req)
|
||||||
{
|
{
|
||||||
|
X509 *x = NULL;
|
||||||
|
X509_REQ *r = NULL;
|
||||||
EVP_MD_CTX *ctx = NULL;
|
EVP_MD_CTX *ctx = NULL;
|
||||||
unsigned char *buf_in = NULL;
|
unsigned char *buf_in = NULL;
|
||||||
int ret = -1, inl = 0;
|
int ret = -1, inl = 0;
|
||||||
size_t inll = 0;
|
size_t inll = 0;
|
||||||
EVP_PKEY_CTX *pctx = NULL;
|
EVP_PKEY_CTX *pctx = NULL;
|
||||||
const EVP_MD *type = EVP_get_digestbynid(mdnid);
|
const EVP_MD *type = EVP_get_digestbynid(mdnid);
|
||||||
|
ASN1_BIT_STRING *signature = NULL;
|
||||||
|
ASN1_OCTET_STRING *sm2_id = NULL;
|
||||||
|
ASN1_VALUE *tbv = NULL;
|
||||||
|
|
||||||
if (type == NULL) {
|
if (type == NULL) {
|
||||||
X509err(X509_F_X509_VERIFY_SM2,
|
X509err(X509_F_COMMON_VERIFY_SM2,
|
||||||
ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
|
ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pkey == NULL) {
|
if (pkey == NULL) {
|
||||||
X509err(X509_F_X509_VERIFY_SM2, ERR_R_PASSED_NULL_PARAMETER);
|
X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_PASSED_NULL_PARAMETER);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x->signature.type == V_ASN1_BIT_STRING && x->signature.flags & 0x7) {
|
if (req == 1) {
|
||||||
X509err(X509_F_X509_VERIFY_SM2, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
|
r = (X509_REQ *)data;
|
||||||
|
signature = r->signature;
|
||||||
|
sm2_id = r->sm2_id;
|
||||||
|
tbv = (ASN1_VALUE *)&r->req_info;
|
||||||
|
} else {
|
||||||
|
x = (X509 *)data;
|
||||||
|
signature = &x->signature;
|
||||||
|
sm2_id = x->sm2_id;
|
||||||
|
tbv = (ASN1_VALUE *)&x->cert_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
|
||||||
|
X509err(X509_F_COMMON_VERIFY_SM2, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = EVP_MD_CTX_new();
|
ctx = EVP_MD_CTX_new();
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
X509err(X509_F_X509_VERIFY_SM2, ERR_R_MALLOC_FAILURE);
|
X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_MALLOC_FAILURE);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check public key OID matches public key type */
|
/* Check public key OID matches public key type */
|
||||||
if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) {
|
if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) {
|
||||||
X509err(X509_F_X509_VERIFY_SM2, ASN1_R_WRONG_PUBLIC_KEY_TYPE);
|
X509err(X509_F_COMMON_VERIFY_SM2, ASN1_R_WRONG_PUBLIC_KEY_TYPE);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) {
|
if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) {
|
||||||
X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB);
|
X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_EVP_LIB);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
pctx = EVP_PKEY_CTX_new(pkey, NULL);
|
pctx = EVP_PKEY_CTX_new(pkey, NULL);
|
||||||
if (pctx == NULL) {
|
if (pctx == NULL) {
|
||||||
X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB);
|
X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_EVP_LIB);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
/* NOTE: we tolerate no actual ID, to provide maximum flexibility */
|
/* NOTE: we tolerate no actual ID, to provide maximum flexibility */
|
||||||
if (x->sm2_id != NULL
|
if (sm2_id != NULL
|
||||||
&& EVP_PKEY_CTX_set1_id(pctx, x->sm2_id->data,
|
&& EVP_PKEY_CTX_set1_id(pctx, sm2_id->data, sm2_id->length) != 1) {
|
||||||
x->sm2_id->length) != 1) {
|
X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_EVP_LIB);
|
||||||
X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB);
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
|
EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
|
||||||
|
|
||||||
if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) {
|
if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) {
|
||||||
X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB);
|
X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_EVP_LIB);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
inl = ASN1_item_i2d((ASN1_VALUE *)&x->cert_info, &buf_in,
|
inl = ASN1_item_i2d(tbv, &buf_in,
|
||||||
|
req == 1 ?
|
||||||
|
ASN1_ITEM_rptr(X509_REQ_INFO) :
|
||||||
ASN1_ITEM_rptr(X509_CINF));
|
ASN1_ITEM_rptr(X509_CINF));
|
||||||
if (inl <= 0) {
|
if (inl <= 0) {
|
||||||
X509err(X509_F_X509_VERIFY_SM2, ERR_R_INTERNAL_ERROR);
|
X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_INTERNAL_ERROR);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (buf_in == NULL) {
|
if (buf_in == NULL) {
|
||||||
X509err(X509_F_X509_VERIFY_SM2, ERR_R_MALLOC_FAILURE);
|
X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_MALLOC_FAILURE);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
inll = inl;
|
inll = inl;
|
||||||
|
|
||||||
ret = EVP_DigestVerify(ctx, x->signature.data,
|
ret = EVP_DigestVerify(ctx, signature->data,
|
||||||
(size_t)x->signature.length, buf_in, inl);
|
(size_t)signature->length, buf_in, inl);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB);
|
X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_EVP_LIB);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
ret = 1;
|
ret = 1;
|
||||||
@ -113,6 +132,18 @@ static int x509_verify_sm2(X509 *x, EVP_PKEY *pkey, int mdnid, int pknid)
|
|||||||
EVP_PKEY_CTX_free(pctx);
|
EVP_PKEY_CTX_free(pctx);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int x509_verify_sm2(X509 *x, EVP_PKEY *pkey, int mdnid, int pknid)
|
||||||
|
{
|
||||||
|
return common_verify_sm2(x, pkey, mdnid, pknid, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int x509_req_verify_sm2(X509_REQ *x, EVP_PKEY *pkey,
|
||||||
|
int mdnid, int pknid)
|
||||||
|
{
|
||||||
|
return common_verify_sm2(x, pkey, mdnid, pknid, 1);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int X509_verify(X509 *a, EVP_PKEY *r)
|
int X509_verify(X509 *a, EVP_PKEY *r)
|
||||||
@ -142,6 +173,20 @@ int X509_verify(X509 *a, EVP_PKEY *r)
|
|||||||
|
|
||||||
int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
|
int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
|
||||||
{
|
{
|
||||||
|
#ifndef OPENSSL_NO_SM2
|
||||||
|
int mdnid, pknid;
|
||||||
|
|
||||||
|
/* Convert signature OID into digest and public key OIDs */
|
||||||
|
if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->sig_alg.algorithm),
|
||||||
|
&mdnid, &pknid)) {
|
||||||
|
X509err(X509_F_X509_REQ_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pknid == NID_sm2)
|
||||||
|
return x509_req_verify_sm2(a, r, mdnid, pknid);
|
||||||
|
#endif
|
||||||
|
|
||||||
return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO),
|
return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO),
|
||||||
&a->sig_alg, a->signature, &a->req_info, r));
|
&a->sig_alg, a->signature, &a->req_info, r));
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,29 @@ static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int req_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||||
|
void *exarg)
|
||||||
|
{
|
||||||
|
#ifndef OPENSSL_NO_SM2
|
||||||
|
X509_REQ *ret = (X509_REQ *)*pval;
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case ASN1_OP_D2I_PRE:
|
||||||
|
ASN1_OCTET_STRING_free(ret->sm2_id);
|
||||||
|
/* fall thru */
|
||||||
|
case ASN1_OP_NEW_POST:
|
||||||
|
ret->sm2_id = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASN1_OP_FREE_POST:
|
||||||
|
ASN1_OCTET_STRING_free(ret->sm2_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = {
|
ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = {
|
||||||
ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
|
ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
|
||||||
ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
|
ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
|
||||||
@ -57,7 +80,7 @@ ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = {
|
|||||||
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO)
|
IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO)
|
||||||
|
|
||||||
ASN1_SEQUENCE_ref(X509_REQ, 0) = {
|
ASN1_SEQUENCE_ref(X509_REQ, req_cb) = {
|
||||||
ASN1_EMBED(X509_REQ, req_info, X509_REQ_INFO),
|
ASN1_EMBED(X509_REQ, req_info, X509_REQ_INFO),
|
||||||
ASN1_EMBED(X509_REQ, sig_alg, X509_ALGOR),
|
ASN1_EMBED(X509_REQ, sig_alg, X509_ALGOR),
|
||||||
ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING)
|
ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING)
|
||||||
@ -66,3 +89,16 @@ ASN1_SEQUENCE_ref(X509_REQ, 0) = {
|
|||||||
IMPLEMENT_ASN1_FUNCTIONS(X509_REQ)
|
IMPLEMENT_ASN1_FUNCTIONS(X509_REQ)
|
||||||
|
|
||||||
IMPLEMENT_ASN1_DUP_FUNCTION(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)
|
||||||
|
{
|
||||||
|
ASN1_OCTET_STRING_free(x->sm2_id);
|
||||||
|
x->sm2_id = sm2_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1_OCTET_STRING *X509_REQ_get0_sm2_id(X509_REQ *x)
|
||||||
|
{
|
||||||
|
return x->sm2_id;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -53,6 +53,9 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
|||||||
sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
|
sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
|
||||||
ASIdentifiers_free(ret->rfc3779_asid);
|
ASIdentifiers_free(ret->rfc3779_asid);
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef OPENSSL_NO_SM2
|
||||||
|
ASN1_OCTET_STRING_free(ret->sm2_id);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* fall thru */
|
/* fall thru */
|
||||||
|
|
||||||
|
@ -57,6 +57,8 @@ B<openssl> B<ca>
|
|||||||
[B<-multivalue-rdn>]
|
[B<-multivalue-rdn>]
|
||||||
[B<-rand file...>]
|
[B<-rand file...>]
|
||||||
[B<-writerand file>]
|
[B<-writerand file>]
|
||||||
|
[B<-sm2-id string>]
|
||||||
|
[B<-sm2-hex-id hex-string>]
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
@ -303,6 +305,16 @@ all others.
|
|||||||
Writes random data to the specified I<file> upon exit.
|
Writes random data to the specified I<file> upon exit.
|
||||||
This can be used with a subsequent B<-rand> flag.
|
This can be used with a subsequent B<-rand> flag.
|
||||||
|
|
||||||
|
=item B<-sm2-id>
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head1 CRL OPTIONS
|
=head1 CRL OPTIONS
|
||||||
@ -600,6 +612,10 @@ Sign a certificate request:
|
|||||||
|
|
||||||
openssl ca -in req.pem -out newcert.pem
|
openssl ca -in req.pem -out newcert.pem
|
||||||
|
|
||||||
|
Sign an SM2 certificate request:
|
||||||
|
|
||||||
|
openssl ca -in sm2.csr -out sm2.crt -md sm3 -sigopt "sm2_id:1234567812345678" -sm2-id "1234567812345678"
|
||||||
|
|
||||||
Sign a certificate request, using CA extensions:
|
Sign a certificate request, using CA extensions:
|
||||||
|
|
||||||
openssl ca -in req.pem -extensions v3_ca -out newcert.pem
|
openssl ca -in req.pem -extensions v3_ca -out newcert.pem
|
||||||
|
@ -50,6 +50,8 @@ B<openssl> B<req>
|
|||||||
[B<-batch>]
|
[B<-batch>]
|
||||||
[B<-verbose>]
|
[B<-verbose>]
|
||||||
[B<-engine id>]
|
[B<-engine id>]
|
||||||
|
[B<-sm2-id string>]
|
||||||
|
[B<-sm2-hex-id hex-string>]
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
@ -339,6 +341,16 @@ for all available algorithms.
|
|||||||
Specifies an engine (by its unique B<id> string) which would be used
|
Specifies an engine (by its unique B<id> string) which would be used
|
||||||
for key generation operations.
|
for key generation operations.
|
||||||
|
|
||||||
|
=item B<-sm2-id>
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head1 CONFIGURATION FILE FORMAT
|
=head1 CONFIGURATION FILE FORMAT
|
||||||
@ -534,6 +546,15 @@ Generate a self signed root certificate:
|
|||||||
|
|
||||||
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out req.pem
|
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out req.pem
|
||||||
|
|
||||||
|
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"
|
||||||
|
|
||||||
|
Examine and verify an SM2 certificate request:
|
||||||
|
|
||||||
|
openssl req -verify -in sm2.csr -sm3 -sm2-id 1234567812345678
|
||||||
|
|
||||||
Example of a file pointed to by the B<oid_file> option:
|
Example of a file pointed to by the B<oid_file> option:
|
||||||
|
|
||||||
1.2.3.4 shortName A longer Name
|
1.2.3.4 shortName A longer Name
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
=head1 NAME
|
=head1 NAME
|
||||||
|
|
||||||
X509_get0_sm2_id, X509_set0_sm2_id - get or set SM2 ID for certificate operations
|
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
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
@ -10,6 +12,8 @@ X509_get0_sm2_id, X509_set0_sm2_id - get or set SM2 ID for certificate operation
|
|||||||
|
|
||||||
ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x);
|
ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x);
|
||||||
void X509_set0_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id);
|
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
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
@ -21,6 +25,10 @@ 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
|
and therefore the value that has been passed in should not be freed by the
|
||||||
caller after this function has been called.
|
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
|
=head1 NOTES
|
||||||
|
|
||||||
SM2 signature algorithm requires an ID value when generating and verifying a
|
SM2 signature algorithm requires an ID value when generating and verifying a
|
||||||
@ -29,7 +37,7 @@ ability to set and retrieve the SM2 ID value.
|
|||||||
|
|
||||||
=head1 RETURN VALUES
|
=head1 RETURN VALUES
|
||||||
|
|
||||||
X509_set0_sm2_id() does not return a value.
|
X509_set0_sm2_id() and X509_REQ_set0_sm2_id() do not return a value.
|
||||||
|
|
||||||
=head1 SEE ALSO
|
=head1 SEE ALSO
|
||||||
|
|
||||||
|
@ -569,6 +569,8 @@ int X509_get_signature_nid(const X509 *x);
|
|||||||
# ifndef OPENSSL_NO_SM2
|
# ifndef OPENSSL_NO_SM2
|
||||||
void X509_set0_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id);
|
void X509_set0_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id);
|
||||||
ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x);
|
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
|
# endif
|
||||||
|
|
||||||
int X509_trusted(const X509 *x);
|
int X509_trusted(const X509 *x);
|
||||||
|
@ -28,6 +28,7 @@ int ERR_load_X509_strings(void);
|
|||||||
# define X509_F_BY_FILE_CTRL 101
|
# define X509_F_BY_FILE_CTRL 101
|
||||||
# define X509_F_CHECK_NAME_CONSTRAINTS 149
|
# define X509_F_CHECK_NAME_CONSTRAINTS 149
|
||||||
# define X509_F_CHECK_POLICY 145
|
# define X509_F_CHECK_POLICY 145
|
||||||
|
# define X509_F_COMMON_VERIFY_SM2 165
|
||||||
# define X509_F_DANE_I2D 107
|
# define X509_F_DANE_I2D 107
|
||||||
# define X509_F_DIR_CTRL 102
|
# define X509_F_DIR_CTRL 102
|
||||||
# define X509_F_GET_CERT_BY_SUBJECT 103
|
# define X509_F_GET_CERT_BY_SUBJECT 103
|
||||||
@ -71,6 +72,8 @@ int ERR_load_X509_strings(void);
|
|||||||
# define X509_F_X509_REQ_PRINT_EX 121
|
# define X509_F_X509_REQ_PRINT_EX 121
|
||||||
# define X509_F_X509_REQ_PRINT_FP 122
|
# define X509_F_X509_REQ_PRINT_FP 122
|
||||||
# define X509_F_X509_REQ_TO_X509 123
|
# define X509_F_X509_REQ_TO_X509 123
|
||||||
|
# define X509_F_X509_REQ_VERIFY 163
|
||||||
|
# define X509_F_X509_REQ_VERIFY_SM2 164
|
||||||
# define X509_F_X509_STORE_ADD_CERT 124
|
# define X509_F_X509_STORE_ADD_CERT 124
|
||||||
# define X509_F_X509_STORE_ADD_CRL 125
|
# define X509_F_X509_STORE_ADD_CRL 125
|
||||||
# define X509_F_X509_STORE_ADD_LOOKUP 157
|
# define X509_F_X509_STORE_ADD_LOOKUP 157
|
||||||
|
9
test/certs/sm2-csr.pem
Normal file
9
test/certs/sm2-csr.pem
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
-----BEGIN CERTIFICATE REQUEST-----
|
||||||
|
MIIBMTCB1wIBADB1MQswCQYDVQQGEwJDTjERMA8GA1UECAwITGlhb25pbmcxETAP
|
||||||
|
BgNVBAcMCFNoZW55YW5nMQwwCgYDVQQKDANUZXQxDDAKBgNVBAsMA1RldDELMAkG
|
||||||
|
A1UEAwwCb28xFzAVBgkqhkiG9w0BCQEWCG9vQG9vLm9vMFkwEwYHKoZIzj0CAQYI
|
||||||
|
KoEcz1UBgi0DQgAE1NjdOpldcjTkuZpdGDNyHAnhK9cB2RZ7jAmFzt7jgEs9OHSg
|
||||||
|
rb3crjz+qGZfqyJ5AyZulQ7gdARzb1H55jvw5qAAMAoGCCqBHM9VAYN1A0kAMEYC
|
||||||
|
IQCacUXA8kyTTDwEm89Yz9qjsbfd8/N32lnzKxuKCcXJwQIhAIpugCbfeWuPxUQO
|
||||||
|
7AvQS3yxBp1yn0FbTT2XVSyYy6To
|
||||||
|
-----END CERTIFICATE REQUEST-----
|
14
test/certs/sm2-root.crt
Normal file
14
test/certs/sm2-root.crt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICJDCCAcqgAwIBAgIJAOlkpDpSrmVbMAoGCCqBHM9VAYN1MGgxCzAJBgNVBAYT
|
||||||
|
AkNOMQswCQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRl
|
||||||
|
c3QgT3JnMRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTAe
|
||||||
|
Fw0xOTAyMTkwNzA1NDhaFw0yMzAzMzAwNzA1NDhaMGgxCzAJBgNVBAYTAkNOMQsw
|
||||||
|
CQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRlc3QgT3Jn
|
||||||
|
MRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTBZMBMGByqG
|
||||||
|
SM49AgEGCCqBHM9VAYItA0IABHRYnqErofBdXPptvvO7+BSVJxcpHuTGnZ+UPrbU
|
||||||
|
5kVEUMaUnNOeMJZl/vRGimZCm/AkReJmRfnb15ESHR+ssp6jXTBbMB0GA1UdDgQW
|
||||||
|
BBTFjcWu/zJgSZ5SKUlU5Vx4/0W5dDAfBgNVHSMEGDAWgBTFjcWu/zJgSZ5SKUlU
|
||||||
|
5Vx4/0W5dDAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAKBggqgRzPVQGDdQNI
|
||||||
|
ADBFAiEAs6byi1nSQtFELOw/2tQIv5AEsZFR5MJ/oB2ztXzs2LYCIEfIw4xlUH6X
|
||||||
|
YFhs4RnIa0K9Ng1ebsGPrifYkudwBIk3
|
||||||
|
-----END CERTIFICATE-----
|
5
test/certs/sm2-root.key
Normal file
5
test/certs/sm2-root.key
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQglktdVbLA5tyXMc+9
|
||||||
|
KV4ikyDaFZNnXqfNAzUVqTlqn8GhRANCAAR0WJ6hK6HwXVz6bb7zu/gUlScXKR7k
|
||||||
|
xp2flD621OZFRFDGlJzTnjCWZf70RopmQpvwJEXiZkX529eREh0frLKe
|
||||||
|
-----END PRIVATE KEY-----
|
@ -15,7 +15,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/;
|
|||||||
|
|
||||||
setup("test_req");
|
setup("test_req");
|
||||||
|
|
||||||
plan tests => 9;
|
plan tests => 10;
|
||||||
|
|
||||||
require_ok(srctop_file('test','recipes','tconversion.pl'));
|
require_ok(srctop_file('test','recipes','tconversion.pl'));
|
||||||
|
|
||||||
@ -58,6 +58,25 @@ subtest "generating certificate requests" => sub {
|
|||||||
"Verifying signature on request");
|
"Verifying signature on request");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
subtest "generating SM2 certificate requests" => sub {
|
||||||
|
plan tests => 2;
|
||||||
|
|
||||||
|
SKIP: {
|
||||||
|
skip "SM2 is not supported by this OpenSSL build", 2
|
||||||
|
if disabled("sm2");
|
||||||
|
ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"),
|
||||||
|
"-new", "-key", srctop_file("test", "certs", "sm2.key"),
|
||||||
|
"-sigopt", "sm2_id:1234567812345678",
|
||||||
|
"-out", "testreq.pem", "-sm3"])),
|
||||||
|
"Generating SM2 certificate request");
|
||||||
|
|
||||||
|
ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"),
|
||||||
|
"-verify", "-in", "testreq.pem", "-noout",
|
||||||
|
"-sm2-id", "1234567812345678", "-sm3"])),
|
||||||
|
"Verifying signature on SM2 certificate request");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
my @openssl_args = ("req", "-config", srctop_file("apps", "openssl.cnf"));
|
my @openssl_args = ("req", "-config", srctop_file("apps", "openssl.cnf"));
|
||||||
|
|
||||||
run_conversion('req conversions',
|
run_conversion('req conversions',
|
||||||
|
@ -16,4 +16,5 @@ plan tests => 1;
|
|||||||
ok(run(test(["verify_extra_test",
|
ok(run(test(["verify_extra_test",
|
||||||
srctop_file("test", "certs", "roots.pem"),
|
srctop_file("test", "certs", "roots.pem"),
|
||||||
srctop_file("test", "certs", "untrusted.pem"),
|
srctop_file("test", "certs", "untrusted.pem"),
|
||||||
srctop_file("test", "certs", "bad.pem")])));
|
srctop_file("test", "certs", "bad.pem"),
|
||||||
|
srctop_file("test", "certs", "sm2-csr.pem")])));
|
||||||
|
@ -23,7 +23,7 @@ my $std_openssl_cnf =
|
|||||||
|
|
||||||
rmtree("demoCA", { safe => 0 });
|
rmtree("demoCA", { safe => 0 });
|
||||||
|
|
||||||
plan tests => 5;
|
plan tests => 6;
|
||||||
SKIP: {
|
SKIP: {
|
||||||
$ENV{OPENSSL_CONFIG} = '-config "'.srctop_file("test", "CAss.cnf").'"';
|
$ENV{OPENSSL_CONFIG} = '-config "'.srctop_file("test", "CAss.cnf").'"';
|
||||||
skip "failed creating CA structure", 4
|
skip "failed creating CA structure", 4
|
||||||
@ -51,9 +51,25 @@ plan tests => 5;
|
|||||||
'creating new pre-certificate');
|
'creating new pre-certificate');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SKIP: {
|
||||||
|
skip "SM2 is not supported by this OpenSSL build", 1
|
||||||
|
if disabled("sm2");
|
||||||
|
|
||||||
|
is(yes(cmdstr(app(["openssl", "ca", "-config",
|
||||||
|
srctop_file("test", "CAss.cnf"),
|
||||||
|
"-in", srctop_file("test", "certs", "sm2-csr.pem"),
|
||||||
|
"-out", "sm2-test.crt",
|
||||||
|
"-sigopt", "sm2_id:1234567812345678",
|
||||||
|
"-sm2-id", "1234567812345678",
|
||||||
|
"-md", "sm3",
|
||||||
|
"-cert", srctop_file("test", "certs", "sm2-root.crt"),
|
||||||
|
"-keyfile", srctop_file("test", "certs", "sm2-root.key")]))),
|
||||||
|
0,
|
||||||
|
"Signing SM2 certificate request");
|
||||||
|
}
|
||||||
|
|
||||||
rmtree("demoCA", { safe => 0 });
|
rmtree("demoCA", { safe => 0 });
|
||||||
unlink "newcert.pem", "newreq.pem", "newkey.pem";
|
unlink "newcert.pem", "newreq.pem", "newkey.pem", "sm2-test.crt";
|
||||||
|
|
||||||
|
|
||||||
sub yes {
|
sub yes {
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
static const char *roots_f;
|
static const char *roots_f;
|
||||||
static const char *untrusted_f;
|
static const char *untrusted_f;
|
||||||
static const char *bad_f;
|
static const char *bad_f;
|
||||||
|
static const char *req_f;
|
||||||
|
|
||||||
static STACK_OF(X509) *load_certs_from_file(const char *filename)
|
static STACK_OF(X509) *load_certs_from_file(const char *filename)
|
||||||
{
|
{
|
||||||
@ -218,19 +219,61 @@ static int test_sm2_id(void)
|
|||||||
BIO_free(bio);
|
BIO_free(bio);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_req_sm2_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";
|
||||||
|
|
||||||
|
bio = BIO_new_file(req_f, "r");
|
||||||
|
if (bio == NULL)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
x = PEM_read_bio_X509_REQ(bio, NULL, 0, NULL);
|
||||||
|
if (x == NULL)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
v = ASN1_OCTET_STRING_new();
|
||||||
|
if (v == NULL)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (!ASN1_OCTET_STRING_set(v, (unsigned char *)sm2id, (int)strlen(sm2id))) {
|
||||||
|
ASN1_OCTET_STRING_free(v);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
X509_REQ_set0_sm2_id(x, v);
|
||||||
|
|
||||||
|
v2 = X509_REQ_get0_sm2_id(x);
|
||||||
|
if (!TEST_ptr(v2)
|
||||||
|
|| !TEST_int_eq(ASN1_OCTET_STRING_cmp(v, v2), 0))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
err:
|
||||||
|
X509_REQ_free(x);
|
||||||
|
BIO_free(bio);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int setup_tests(void)
|
int setup_tests(void)
|
||||||
{
|
{
|
||||||
if (!TEST_ptr(roots_f = test_get_argument(0))
|
if (!TEST_ptr(roots_f = test_get_argument(0))
|
||||||
|| !TEST_ptr(untrusted_f = test_get_argument(1))
|
|| !TEST_ptr(untrusted_f = test_get_argument(1))
|
||||||
|| !TEST_ptr(bad_f = test_get_argument(2)))
|
|| !TEST_ptr(bad_f = test_get_argument(2))
|
||||||
|
|| !TEST_ptr(req_f = test_get_argument(3)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ADD_TEST(test_alt_chains_cert_forgery);
|
ADD_TEST(test_alt_chains_cert_forgery);
|
||||||
ADD_TEST(test_store_ctx);
|
ADD_TEST(test_store_ctx);
|
||||||
#ifndef OPENSSL_NO_SM2
|
#ifndef OPENSSL_NO_SM2
|
||||||
ADD_TEST(test_sm2_id);
|
ADD_TEST(test_sm2_id);
|
||||||
|
ADD_TEST(test_req_sm2_id);
|
||||||
#endif
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -4833,3 +4833,5 @@ BN_CTX_new_ex 4777 3_0_0 EXIST::FUNCTION:
|
|||||||
BN_CTX_secure_new_ex 4778 3_0_0 EXIST::FUNCTION:
|
BN_CTX_secure_new_ex 4778 3_0_0 EXIST::FUNCTION:
|
||||||
OPENSSL_thread_stop_ex 4779 3_0_0 EXIST::FUNCTION:
|
OPENSSL_thread_stop_ex 4779 3_0_0 EXIST::FUNCTION:
|
||||||
OSSL_PARAM_locate_const 4780 3_0_0 EXIST::FUNCTION:
|
OSSL_PARAM_locate_const 4780 3_0_0 EXIST::FUNCTION:
|
||||||
|
X509_REQ_set0_sm2_id 4781 3_0_0 EXIST::FUNCTION:SM2
|
||||||
|
X509_REQ_get0_sm2_id 4782 3_0_0 EXIST::FUNCTION:SM2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user