Support HSS/XMSS/XMSSMT certificate, CSR, and CRL

LMS and SPHINCS+ do not have official OID, so officially supported by X.509
This commit is contained in:
Zhi Guan
2026-01-18 21:13:58 +08:00
parent e8eb873c47
commit 05ba2f8e54
8 changed files with 263 additions and 129 deletions

View File

@@ -18,19 +18,26 @@
#include <gmssl/pkcs8.h>
#include <gmssl/x509.h>
#include <gmssl/x509_req.h>
#include <gmssl/x509_alg.h>
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;