From 05ba2f8e54c35026ce34f23c13b82fba5dc33220 Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Sun, 18 Jan 2026 21:13:58 +0800 Subject: [PATCH] Support HSS/XMSS/XMSSMT certificate, CSR, and CRL LMS and SPHINCS+ do not have official OID, so officially supported by X.509 --- include/gmssl/lms.h | 1 + include/gmssl/x509_key.h | 22 ++--- src/lms.c | 18 +++++ src/x509_key.c | 171 +++++++++++++++++++++++++++------------ tools/certgen.c | 33 +++++--- tools/crlgen.c | 67 ++++++++------- tools/reqgen.c | 37 ++++++--- tools/reqsign.c | 43 +++++----- 8 files changed, 263 insertions(+), 129 deletions(-) diff --git a/include/gmssl/lms.h b/include/gmssl/lms.h index 2c85c6a5..9ee48c69 100644 --- a/include/gmssl/lms.h +++ b/include/gmssl/lms.h @@ -249,6 +249,7 @@ int hss_key_update(HSS_KEY *key); int hss_key_get_signature_size(const HSS_KEY *key, size_t *siglen); void hss_key_cleanup(HSS_KEY *key); +int hss_public_key_equ(const HSS_KEY *key, const HSS_KEY *pub); int hss_public_key_to_bytes(const HSS_KEY *key, uint8_t **out, size_t *outlen); int hss_private_key_to_bytes(const HSS_KEY *key, uint8_t **out, size_t *outlen); int hss_public_key_from_bytes(HSS_KEY *key, const uint8_t **in, size_t *inlen); diff --git a/include/gmssl/x509_key.h b/include/gmssl/x509_key.h index f29a452d..063827e8 100644 --- a/include/gmssl/x509_key.h +++ b/include/gmssl/x509_key.h @@ -54,16 +54,21 @@ typedef struct { } u; } X509_KEY; + +int x509_key_set_sm2_key(X509_KEY *x509_key, const SM2_KEY *sm2_key); +int x509_key_set_lms_key(X509_KEY *x509_key, const LMS_KEY *lms_key); +int x509_key_set_hss_key(X509_KEY *x509_key, const HSS_KEY *hss_key); +int x509_key_set_xmss_key(X509_KEY *x509_key, const XMSS_KEY *xmss_key); +int x509_key_set_xmssmt_key(X509_KEY *x509_key, const XMSSMT_KEY *xmssmt_key); +int x509_key_set_sphincs_key(X509_KEY *x509_key, const SPHINCS_KEY *sphincs_key); + int x509_key_generate(X509_KEY *key, int algor, int algor_param); - -int x509_key_set_sm2_key(X509_KEY *x509_key, SM2_KEY *sm2_key); -int x509_key_set_lms_key(X509_KEY *x509_key, LMS_KEY *lms_key); -int x509_key_set_hss_key(X509_KEY *x509_key, HSS_KEY *hss_key); -int x509_key_set_xmss_key(X509_KEY *x509_key, XMSS_KEY *xmss_key); -int x509_key_set_xmssmt_key(X509_KEY *x509_key, XMSSMT_KEY *xmssmt_key); -int x509_key_set_sphincs_key(X509_KEY *x509_key, SPHINCS_KEY *sphincs_key); - +int x509_private_key_from_file(X509_KEY *key, int algor, const char *pass, FILE *fp); int x509_public_key_digest(const X509_KEY *key, uint8_t dgst[32]); +int x509_public_key_equ(const X509_KEY *key, const X509_KEY *pub); +int x509_public_key_equ(const X509_KEY *key, const X509_KEY *pub); +void x509_key_cleanup(X509_KEY *key); + /* SubjectPublicKeyInfo ::= SEQUENCE { @@ -79,7 +84,6 @@ int x509_public_key_info_from_der(X509_KEY *key, const uint8_t **in, size_t *inl int x509_public_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); int x509_private_key_print(FILE *fp, int fmt, int ind, const char *label, const X509_KEY *key); int x509_public_key_print(FILE *fp, int fmt, int ind, const char *label, const X509_KEY *key); -int x509_private_key_from_file(X509_KEY *key, int algor, const char *pass, FILE *fp); typedef union { diff --git a/src/lms.c b/src/lms.c index 8d279bf5..73065ed3 100644 --- a/src/lms.c +++ b/src/lms.c @@ -1189,6 +1189,24 @@ int hss_public_key_print(FILE *fp, int fmt, int ind, const char *label, const HS return 1; } +int hss_public_key_equ(const HSS_KEY *key, const HSS_KEY *pub) +{ + if (!key || !pub) { + error_print(); + return -1; + } + if (key->levels != pub->levels) { + error_print(); + return -1; + } + if (memcmp(&key->lms_key[0].public_key, + &pub->lms_key[0].public_key, LMS_PUBLIC_KEY_SIZE) != 0) { + error_print(); + return -1; + } + return 1; +} + int hss_public_key_to_bytes(const HSS_KEY *key, uint8_t **out, size_t *outlen) { if (!key || !outlen) { diff --git a/src/x509_key.c b/src/x509_key.c index 85a3d59e..58ca39c9 100644 --- a/src/x509_key.c +++ b/src/x509_key.c @@ -199,69 +199,57 @@ int x509_public_key_print(FILE *fp, int fmt, int ind, const char *label, const X } -int x509_key_set_sm2_key(X509_KEY *x509_key, SM2_KEY *sm2_key) +int x509_key_set_sm2_key(X509_KEY *x509_key, const SM2_KEY *sm2_key) { memset(x509_key, 0, sizeof(X509_KEY)); x509_key->algor = OID_ec_public_key; x509_key->algor_param = OID_sm2; - if (&x509_key->u.sm2_key != sm2_key) { - x509_key->u.sm2_key = *sm2_key; - } + x509_key->u.sm2_key = *sm2_key; return 1; } -int x509_key_set_lms_key(X509_KEY *x509_key, LMS_KEY *lms_key) +int x509_key_set_lms_key(X509_KEY *x509_key, const LMS_KEY *lms_key) { memset(x509_key, 0, sizeof(X509_KEY)); x509_key->algor = OID_lms_hashsig; x509_key->algor_param = OID_undef; - if (&x509_key->u.lms_key != lms_key) { - x509_key->u.lms_key = *lms_key; - } + x509_key->u.lms_key = *lms_key; return 1; } -int x509_key_set_hss_key(X509_KEY *x509_key, HSS_KEY *hss_key) +int x509_key_set_hss_key(X509_KEY *x509_key, const HSS_KEY *hss_key) { memset(x509_key, 0, sizeof(X509_KEY)); x509_key->algor = OID_hss_lms_hashsig; x509_key->algor_param = OID_undef; - if (&x509_key->u.hss_key != hss_key) { - x509_key->u.hss_key = *hss_key; - } + x509_key->u.hss_key = *hss_key; return 1; } -int x509_key_set_xmss_key(X509_KEY *x509_key, XMSS_KEY *xmss_key) +int x509_key_set_xmss_key(X509_KEY *x509_key, const XMSS_KEY *xmss_key) { memset(x509_key, 0, sizeof(X509_KEY)); x509_key->algor = OID_xmss_hashsig; x509_key->algor_param = OID_undef; - if (&x509_key->u.xmss_key != xmss_key) { - x509_key->u.xmss_key = *xmss_key; - } + x509_key->u.xmss_key = *xmss_key; return 1; } -int x509_key_set_xmssmt_key(X509_KEY *x509_key, XMSSMT_KEY *xmssmt_key) +int x509_key_set_xmssmt_key(X509_KEY *x509_key, const XMSSMT_KEY *xmssmt_key) { memset(x509_key, 0, sizeof(X509_KEY)); x509_key->algor = OID_xmssmt_hashsig; x509_key->algor_param = OID_undef; - if (&x509_key->u.xmssmt_key != xmssmt_key) { - x509_key->u.xmssmt_key = *xmssmt_key; - } + x509_key->u.xmssmt_key = *xmssmt_key; return 1; } -int x509_key_set_sphincs_key(X509_KEY *x509_key, SPHINCS_KEY *sphincs_key) +int x509_key_set_sphincs_key(X509_KEY *x509_key, const SPHINCS_KEY *sphincs_key) { memset(x509_key, 0, sizeof(X509_KEY)); x509_key->algor = OID_sphincs_hashsig; x509_key->algor_param = OID_undef; - if (&x509_key->u.sphincs_key != sphincs_key) { - x509_key->u.sphincs_key = *sphincs_key; - } + x509_key->u.sphincs_key = *sphincs_key; return 1; } @@ -336,9 +324,80 @@ int x509_public_key_digest(const X509_KEY *key, uint8_t dgst[32]) return 1; } +int x509_public_key_equ(const X509_KEY *key, const X509_KEY *pub) +{ + if (!key || !pub) { + error_print(); + return -1; + } + if (key->algor != pub->algor) { + error_print(); + return -1; + } + if (key->algor_param != pub->algor_param) { + error_print(); + return -1; + } + switch (key->algor) { + case OID_ec_public_key: + if (sm2_public_key_equ(&key->u.sm2_key, &pub->u.sm2_key) != 1) { + error_print(); + return -1; + } + break; + case OID_lms_hashsig: + if (memcmp(&key->u.lms_key.public_key, + &pub->u.lms_key.public_key, LMS_PUBLIC_KEY_SIZE) != 0) { + error_print(); + return -1; + } + break; + case OID_hss_lms_hashsig: + if (hss_public_key_equ(&key->u.hss_key, &pub->u.hss_key) != 1) { + error_print(); + return -1; + } + break; + case OID_xmss_hashsig: + if (memcmp(&key->u.xmss_key.public_key, + &pub->u.xmss_key.public_key, XMSS_PUBLIC_KEY_SIZE) != 0) { + error_print(); + return -1; + } + break; + case OID_xmssmt_hashsig: + if (memcmp(&key->u.xmssmt_key.public_key, + &pub->u.xmssmt_key.public_key, XMSSMT_PUBLIC_KEY_SIZE) != 0) { + error_print(); + return -1; + } + break; + case OID_sphincs_hashsig: + if (memcmp(&key->u.sphincs_key.public_key, + &pub->u.sphincs_key.public_key, SPHINCS_PUBLIC_KEY_SIZE) != 0) { + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + return 1; +} + int x509_key_get_signature_size(const X509_KEY *key, size_t *siglen) { switch (key->algor) { + case OID_ec_public_key: + *siglen = SM2_signature_typical_size; + break; + case OID_lms_hashsig: + if (lms_key_get_signature_size(&key->u.lms_key, siglen) != 1) { + error_print(); + return -1; + } + break; case OID_hss_lms_hashsig: if (hss_key_get_signature_size(&key->u.hss_key, siglen) != 1) { error_print(); @@ -357,8 +416,8 @@ int x509_key_get_signature_size(const X509_KEY *key, size_t *siglen) return -1; } break; - case OID_ec_public_key: - *siglen = SM2_signature_typical_size; + case OID_sphincs_hashsig: + *siglen = SPHINCS_SIGNATURE_SIZE; break; default: error_print(); @@ -754,6 +813,9 @@ int x509_private_key_from_file(X509_KEY *key, int algor, const char *pass, FILE return -1; } + key->algor = algor; + key->algor_param = OID_undef; + if (algor == OID_ec_public_key) { if (!pass) { error_print(); @@ -763,10 +825,7 @@ int x509_private_key_from_file(X509_KEY *key, int algor, const char *pass, FILE error_print(); return -1; } - if (x509_key_set_sm2_key(key, &key->u.sm2_key) != 1) { - error_print(); - return -1; - } + key->algor_param = OID_sm2; } else if (algor == OID_lms_hashsig) { uint8_t buf[LMS_PRIVATE_KEY_SIZE]; const uint8_t *cp = buf; @@ -784,10 +843,6 @@ int x509_private_key_from_file(X509_KEY *key, int algor, const char *pass, FILE error_print(); return -1; } - if (x509_key_set_lms_key(key, &key->u.lms_key) != 1) { - error_print(); - return -1; - } } else if (algor == OID_hss_lms_hashsig) { uint8_t buf[HSS_PRIVATE_KEY_MAX_SIZE]; const uint8_t *cp = buf; @@ -805,28 +860,16 @@ int x509_private_key_from_file(X509_KEY *key, int algor, const char *pass, FILE error_print(); return -1; } - if (x509_key_set_hss_key(key, &key->u.hss_key) != 1) { - error_print(); - return -1; - } } else if (algor == OID_xmss_hashsig) { if (xmss_private_key_from_file(&key->u.xmss_key, fp) != 1) { error_print(); return -1; } - if (x509_key_set_xmss_key(key, &key->u.xmss_key) != 1) { - error_print(); - return -1; - } } else if (algor == OID_xmssmt_hashsig) { if (xmssmt_private_key_from_file(&key->u.xmssmt_key, fp) != 1) { error_print(); return -1; } - if (x509_key_set_xmssmt_key(key, &key->u.xmssmt_key) != 1) { - error_print(); - return -1; - } } else if (algor == OID_sphincs_hashsig) { uint8_t buf[SPHINCS_PRIVATE_KEY_SIZE]; const uint8_t *cp = buf; @@ -844,10 +887,6 @@ int x509_private_key_from_file(X509_KEY *key, int algor, const char *pass, FILE error_print(); return -1; } - if (x509_key_set_sphincs_key(key, &key->u.sphincs_key) != 1) { - error_print(); - return -1; - } } else { error_print(); return -1; @@ -856,3 +895,35 @@ int x509_private_key_from_file(X509_KEY *key, int algor, const char *pass, FILE return 1; } + +void x509_key_cleanup(X509_KEY *key) +{ + if (key) { + switch (key->algor) { + case OID_ec_public_key: + //sm2_key_cleanup(&key->u.sm2_key); + gmssl_secure_clear(&key->u.sm2_key, sizeof(SM2_KEY)); + break; + case OID_lms_hashsig: + lms_key_cleanup(&key->u.lms_key); + break; + case OID_hss_lms_hashsig: + hss_key_cleanup(&key->u.hss_key); + break; + case OID_xmss_hashsig: + xmss_key_cleanup(&key->u.xmss_key); + break; + case OID_xmssmt_hashsig: + xmssmt_key_cleanup(&key->u.xmssmt_key); + break; + case OID_sphincs_hashsig: + sphincs_key_cleanup(&key->u.sphincs_key); + break; + default: + error_print(); + } + } +} + + + diff --git a/tools/certgen.c b/tools/certgen.c index 2fb11f58..9c3541d0 100644 --- a/tools/certgen.c +++ b/tools/certgen.c @@ -19,13 +19,14 @@ #include #include #include +#include static const char *options = "[-C str] [-ST str] [-L str] [-O str] [-OU str] -CN str" " -serial_len num" " -days num" - " -key pem -pass pass" + " -key pem [-algor str] [-pass pass]" " [-sm2_id str | -sm2_id_hex hex]" " [-gen_authority_key_id]" " [-gen_subject_key_id]" @@ -45,6 +46,7 @@ static char *usage = " -serial_len num Serial number length in bytes\n" " -days num Validity peroid in days\n" " -key file Private key file in PEM format\n" +" -algor str Public key algorithm\n" " -pass pass Password for decrypting private key file\n" " -sm2_id str Signer's ID in SM2 signature algorithm\n" " -sm2_id_hex hex Signer's ID in hex format\n" @@ -154,8 +156,9 @@ int certgen_main(int argc, char **argv) // Private Key FILE *keyfp = NULL; char *pass = NULL; - SM2_KEY sm2_key; X509_KEY x509_key; + int algor = OID_ec_public_key; + int sign_algor = OID_sm2sign_with_sm3; char signer_id[SM2_MAX_ID_LENGTH + 1] = {0}; size_t signer_id_len = 0; @@ -264,6 +267,13 @@ int certgen_main(int argc, char **argv) fprintf(stderr, "%s: open '%s' failure : %s\n", prog, str, strerror(errno)); goto end; } + } else if (!strcmp(*argv, "-algor")) { + if (--argc < 1) goto bad; + str = *(++argv); + if ((algor = x509_public_key_algor_from_name(str)) == OID_undef) { + fprintf(stderr, "%s: invalid algor '%s'\n", prog, str); + goto end; + } } else if (!strcmp(*argv, "-pass")) { if (--argc < 1) goto bad; pass = *(++argv); @@ -390,24 +400,25 @@ bad: printf("usage: gmssl %s %s\n\n", prog, options); goto end; } - if (!pass) { + if (!pass && algor != OID_ec_public_key) { fprintf(stderr, "%s: option `-pass` required\n", prog); printf("usage: gmssl %s %s\n\n", prog, options); goto end; } - if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) { + if (x509_private_key_from_file(&x509_key, algor, pass, keyfp) != 1) { fprintf(stderr, "%s: load private key failed\n", prog); goto end; } + if (x509_key_get_sign_algor(&x509_key, &sign_algor) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } if (!signer_id_len) { strcpy(signer_id, SM2_DEFAULT_ID); signer_id_len = strlen(SM2_DEFAULT_ID); } - if (x509_key_set_sm2_key(&x509_key, &sm2_key) != 1) { - // - goto end; - } + // Serial if (rand_bytes(serial, sizeof(serial)) != 1) { @@ -508,7 +519,7 @@ bad: if (x509_cert_sign_to_der( X509_version_v3, serial, serial_len, - OID_sm2sign_with_sm3, + sign_algor, name, namelen, not_before, not_after, name, namelen, @@ -530,7 +541,7 @@ bad: if (x509_cert_sign_to_der( X509_version_v3, serial, serial_len, - OID_sm2sign_with_sm3, + sign_algor, name, namelen, not_before, not_after, name, namelen, @@ -550,7 +561,7 @@ bad: ret = 0; end: - gmssl_secure_clear(&sm2_key, sizeof(SM2_KEY)); + x509_key_cleanup(&x509_key); if (cert) free(cert); if (keyfp) fclose(keyfp); if (outfile && outfp) fclose(outfp); diff --git a/tools/crlgen.c b/tools/crlgen.c index bd26472e..7f5ac8b1 100644 --- a/tools/crlgen.c +++ b/tools/crlgen.c @@ -24,7 +24,7 @@ static const char *usage = " -in revoked_certs" - " -cacert pem -key pem -pass pass [-sm2_id str | -sm2_id_hex hex]" + " -cacert pem -key pem [-pass pass] [-sm2_id str | -sm2_id_hex hex]" " [-next_update time] " " [-gen_authority_key_id]" " [-crl_num num]" @@ -76,11 +76,13 @@ int crlgen_main(int argc, char **argv) size_t cacert_len = 0; FILE *keyfp = NULL; char *pass = NULL; - SM2_KEY sm2_key; - X509_KEY sign_key; + X509_KEY x509_key; + X509_KEY x509_pub; char signer_id[SM2_MAX_ID_LENGTH + 1] = {0}; size_t signer_id_len = 0; + int sign_algor = OID_undef; + const uint8_t *issuer; size_t issuer_len; time_t this_update = time(NULL); @@ -231,32 +233,44 @@ bad: fprintf(stderr, "usage: gmssl %s %s\n", prog, usage); goto end; } - if (!pass) { - fprintf(stderr, "usage: gmssl %s %s\n", prog, usage); - fprintf(stderr, "%s: `-pass` option required\n", prog); - goto end; - } - if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) { - fprintf(stderr, "%s: load private key failure\n", prog); - goto end; - } - if (!signer_id_len) { - strcpy(signer_id, SM2_DEFAULT_ID); - signer_id_len = strlen(SM2_DEFAULT_ID); - } - if (x509_key_set_sm2_key(&sign_key, &sm2_key) != 1) { - error_print(); - goto end; - } + if (x509_cert_get_subject(cacert, cacert_len, &issuer, &issuer_len) != 1) { fprintf(stderr, "%s: parse CA certificate failure\n", prog); goto end; } + if (x509_cert_get_subject_public_key(cacert, cacert_len, &x509_pub) != 1) { + fprintf(stderr, "%s: parse CA certificate failure\n", prog); + goto end; + } + + if (!pass && x509_pub.algor == OID_ec_public_key) { + fprintf(stderr, "usage: gmssl %s %s\n", prog, usage); + fprintf(stderr, "%s: `-pass` option required\n", prog); + goto end; + } + if (x509_private_key_from_file(&x509_key, x509_pub.algor, pass, keyfp) != 1) { + fprintf(stderr, "%s: load private key failure\n", prog); + goto end; + } + if (x509_public_key_equ(&x509_key, &x509_pub) != 1) { + fprintf(stderr, "%s: certificate and private key not match\n", prog); + goto end; + } + if (x509_key_get_sign_algor(&x509_key, &sign_algor) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + + if (!signer_id_len) { + strcpy(signer_id, SM2_DEFAULT_ID); + signer_id_len = strlen(SM2_DEFAULT_ID); + } + // Extensions if (gen_authority_key_id) { - if (x509_crl_exts_add_default_authority_key_identifier(exts, &extslen, sizeof(exts), &sign_key) != 1) { + if (x509_crl_exts_add_default_authority_key_identifier(exts, &extslen, sizeof(exts), &x509_key) != 1) { fprintf(stderr, "%s: inner error\n", prog); goto end; } @@ -288,12 +302,12 @@ bad: if (x509_crl_sign_to_der( X509_version_v2, - OID_sm2sign_with_sm3, + sign_algor, issuer, issuer_len, this_update, next_update, revoked_certs, revoked_certs_len, extslen ? exts : NULL, extslen, - &sign_key, signer_id, signer_id_len, + &x509_key, signer_id, signer_id_len, NULL, &outlen) != 1) { fprintf(stderr, "%s: inner error\n", prog); goto end; @@ -306,12 +320,12 @@ bad: outlen = 0; if (x509_crl_sign_to_der( X509_version_v2, - OID_sm2sign_with_sm3, + sign_algor, issuer, issuer_len, this_update, next_update, revoked_certs, revoked_certs_len, extslen ? exts : NULL, extslen, - &sign_key, signer_id, signer_id_len, + &x509_key, signer_id, signer_id_len, &out, &outlen) != 1) { fprintf(stderr, "%s: inner error\n", prog); goto end; @@ -323,8 +337,7 @@ bad: ret = 0; end: - gmssl_secure_clear(&sm2_key, sizeof(SM2_KEY)); // FIXME: sm2_clean? - gmssl_secure_clear(&sign_key, sizeof(X509_KEY)); // x509_key_clean? + x509_key_cleanup(&x509_key); if (revoked_certs) free(revoked_certs); if (keyfp) fclose(keyfp); if (cacert) free(cacert); diff --git a/tools/reqgen.c b/tools/reqgen.c index 99a28937..0ac0e4e0 100644 --- a/tools/reqgen.c +++ b/tools/reqgen.c @@ -18,19 +18,26 @@ #include #include #include - +#include static const char *options = "[-C str] [-ST str] [-L str] [-O str] [-OU str] -CN str" - " -key pem -pass pass" + " -key file [-algor str] [-pass pass]" " [-sm2_id str | -sm2_id_hex hex]" " [-out pem]"; static char *usage = "Options\n" "\n" -" -key file Private key file in PEM format\n" +" -key file Private key file in PKCS#8 PEM format or raw binary\n" +" -algor str Public key algorithm, supported algorithms:\n" +" * ecPublicKey\n" +" * lms-hashsig\n" +" * hss-lms-hashsig\n" +" * xmss-hashsig\n" +" * xmssmt-hashsig\n" +" * shpincs-hashsig\n" " -pass pass Password for decrypting private key file\n" " -sm2_id str Signer's ID in SM2 signature algorithm\n" " -sm2_id_hex hex Signer's ID in hex format\n" @@ -79,10 +86,10 @@ int reqgen_main(int argc, char **argv) // Private Key FILE *keyfp = NULL; char *pass = NULL; - SM2_KEY sm2_key; + X509_KEY x509_key; + int algor = OID_ec_public_key; char signer_id[SM2_MAX_ID_LENGTH + 1] = {0}; size_t signer_id_len = 0; - X509_KEY x509_key; // Output char *outfile = NULL; @@ -131,6 +138,13 @@ int reqgen_main(int argc, char **argv) fprintf(stderr, "%s: open '%s' failure : %s\n", prog, str, strerror(errno)); goto end; } + } else if (!strcmp(*argv, "-algor")) { + if (--argc < 1) goto bad; + str = *(++argv); + if ((algor = x509_public_key_algor_from_name(str)) == OID_undef) { + fprintf(stderr, "%s: invalid algor '%s'\n", prog, str); + goto end; + } } else if (!strcmp(*argv, "-pass")) { if (--argc < 1) goto bad; pass = *(++argv); @@ -184,25 +198,22 @@ bad: printf("usage: gmssl %s %s\n\n", prog, options); goto end; } - if (!pass) { + + if (!pass && algor == OID_ec_public_key) { fprintf(stderr, "%s: `-pass` option required\n", prog); printf("usage: gmssl %s %s\n\n", prog, options); goto end; } - if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) { + if (x509_private_key_from_file(&x509_key, algor, pass, keyfp) != 1) { fprintf(stderr, "%s: load private key failed\n", prog); goto end; } + if (!signer_id_len) { strcpy(signer_id, SM2_DEFAULT_ID); signer_id_len = strlen(SM2_DEFAULT_ID); } - if (x509_key_set_sm2_key(&x509_key, &sm2_key) != 1) { - // output error message - //error_print(); - goto end; - } if (x509_name_set(name, &namelen, sizeof(name), country, state, locality, org, org_unit, common_name) != 1) { fprintf(stderr, "%s: set Subject Name error\n", prog); @@ -226,7 +237,7 @@ bad: } ret = 0; end: - gmssl_secure_clear(&sm2_key, sizeof(SM2_KEY)); + x509_key_cleanup(&x509_key); if (keyfp) fclose(keyfp); if (outfile && outfp) fclose(outfp); return ret; diff --git a/tools/reqsign.c b/tools/reqsign.c index fc88b876..9474aadd 100644 --- a/tools/reqsign.c +++ b/tools/reqsign.c @@ -1,5 +1,5 @@ /* - * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2026 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -18,6 +18,9 @@ #include #include #include +#include +#include +#include static const char *options = @@ -25,7 +28,7 @@ static const char *options = " [-req_sm2_id str | -req_sm2_id_hex hex]" " [-serial_len num]" " -days num" - " -cacert pem -key file -pass pass" + " -cacert pem -key file [-pass pass]" " [-sm2_id str | -sm2_id_hex hex]" " [-gen_authority_key_id]" " [-gen_subject_key_id]" @@ -172,15 +175,17 @@ int reqsign_main(int argc, char **argv) size_t cacertlen; FILE *keyfp = NULL; char *pass = NULL; - SM2_KEY sm2_key; X509_KEY x509_key; char signer_id[SM2_MAX_ID_LENGTH + 1] = {0}; size_t signer_id_len = 0; + // Algor + int sign_algor = OID_undef; + // Issuer from CA certificate const uint8_t *issuer; size_t issuer_len; - SM2_KEY sm2_issuer_public_key; + //SM2_KEY sm2_issuer_public_key; X509_KEY issuer_public_key; // Output @@ -429,11 +434,6 @@ bad: printf("usage: gmssl %s %s\n\n", prog, options); goto end; } - if (!pass) { - fprintf(stderr, "%s: '-pass' option required\n", prog); - printf("usage: gmssl %s %s\n\n", prog, options); - goto end; - } if (x509_req_from_pem(req, &reqlen, sizeof(req), infp) != 1) { fprintf(stderr, "%s: parse CSR failure\n", prog); @@ -459,23 +459,28 @@ bad: fprintf(stderr, "%s: parse CA certificate failure\n", prog); goto end; } - if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) { + if (!pass && issuer_public_key.algor == OID_ec_public_key) { + fprintf(stderr, "%s: '-pass' option required\n", prog); + printf("usage: gmssl %s %s\n\n", prog, options); + goto end; + } + + if (x509_private_key_from_file(&x509_key, issuer_public_key.algor, pass, keyfp) != 1) { fprintf(stderr, "%s: load private key failure\n", prog); goto end; } - // 这里可能需要修改一下,x509_key和sm2_key对比 - if (sm2_public_key_equ(&sm2_key, &issuer_public_key.u.sm2_key) != 1) { + if (x509_public_key_equ(&x509_key, &issuer_public_key) != 1) { fprintf(stderr, "%s: private key and CA certificate not match\n", prog); goto end; } + if (x509_key_get_sign_algor(&x509_key, &sign_algor) != 1) { + error_print(); + goto end; + } if (!signer_id_len) { strcpy(signer_id, SM2_DEFAULT_ID); signer_id_len = strlen(SM2_DEFAULT_ID); } - if (x509_key_set_sm2_key(&x509_key, &sm2_key) != 1) { - //fprint - goto end; - } if (rand_bytes(serial, serial_len) != 1) { fprintf(stderr, "%s: random number generator error\n", prog); @@ -569,7 +574,7 @@ bad: if (x509_cert_sign_to_der( X509_version_v3, serial, serial_len, - OID_sm2sign_with_sm3, + sign_algor, issuer, issuer_len, not_before, not_after, subject, subject_len, @@ -591,7 +596,7 @@ bad: if (x509_cert_sign_to_der( X509_version_v3, serial, serial_len, - OID_sm2sign_with_sm3, + sign_algor, issuer, issuer_len, not_before, not_after, subject, subject_len, @@ -611,7 +616,7 @@ bad: } ret = 0; end: - gmssl_secure_clear(&x509_key, sizeof(SM2_KEY)); + x509_key_cleanup(&x509_key); if (cert) free(cert); if (keyfp) fclose(keyfp); if (infile && infp) fclose(infp);