Add X509_KEY to support different public key algos

This commit is contained in:
Zhi Guan
2026-01-16 17:25:17 +08:00
parent d7f93bf379
commit 47639a9e23
37 changed files with 1539 additions and 364 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2025 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.
@@ -44,7 +44,7 @@ const char *asn1_tag_name(int tag)
}
switch (tag) {
case ASN1_TAG_END_OF_CONTENTS: return "End-of-contents";
//case ASN1_TAG_END_OF_CONTENTS: return "End-of-contents";
case ASN1_TAG_BOOLEAN: return "BOOLEAN";
case ASN1_TAG_INTEGER: return "INTEGER";
case ASN1_TAG_BIT_STRING: return "BIT STRING";

View File

@@ -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.
@@ -739,7 +739,7 @@ err:
}
int cms_signer_info_sign_to_der(
const SM3_CTX *sm3_ctx, const SM2_KEY *sign_key,
const SM3_CTX *sm3_ctx, const X509_KEY *sign_key,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial_number, size_t serial_number_len,
const uint8_t *authed_attrs, size_t authed_attrs_len,
@@ -755,7 +755,15 @@ int cms_signer_info_sign_to_der(
sm3_update(&ctx, authed_attrs, authed_attrs_len);
sm3_finish(&ctx, dgst);
if (sm2_sign_fixlen(sign_key, dgst, siglen, sig) != 1) {
// 显然我们没有这个功能了!
// 这是个严重的问题啊,这个签名是有问题的!这里签名的是 dgst啊
// 没想到会出现如此严重的问题!
if (sign_key->algor != OID_ec_public_key
|| sign_key->algor_param != OID_sm2) {
error_print();
return -1;
}
if (sm2_sign_fixlen(&sign_key->u.sm2_key, dgst, siglen, sig) != 1) {
error_print();
return -1;
}
@@ -784,7 +792,7 @@ int cms_signer_info_verify_from_der(
int signature_algor;
const uint8_t *sig;
size_t siglen;
SM2_KEY public_key;
X509_KEY public_key;
SM3_CTX sm3_ctx = *ctx;
uint8_t dgst[32];
@@ -807,11 +815,16 @@ int cms_signer_info_verify_from_der(
error_print();
return -1;
}
if (public_key.algor != OID_ec_public_key
|| public_key.algor_param != OID_sm2) {
error_print();
return -1;
}
sm3_update(&sm3_ctx, *authed_attrs, *authed_attrs_len);
sm3_finish(&sm3_ctx, dgst);
if (sm2_verify(&public_key, dgst, sig, siglen) != 1) {
if (sm2_verify(&public_key.u.sm2_key, dgst, sig, siglen) != 1) {
error_print();
return -1;
}
@@ -820,7 +833,7 @@ int cms_signer_info_verify_from_der(
int cms_signer_infos_add_signer_info(
uint8_t *d, size_t *dlen, size_t maxlen,
const SM3_CTX *sm3_ctx, const SM2_KEY *sign_key,
const SM3_CTX *sm3_ctx, const X509_KEY *sign_key,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial_number, size_t serial_number_len,
const uint8_t *authed_attrs, size_t authed_attrs_len,
@@ -1297,7 +1310,7 @@ err:
}
int cms_recipient_info_encrypt_to_der(
const SM2_KEY *public_key,
const X509_KEY *public_key,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial_number, size_t serial_number_len,
const uint8_t *in, size_t inlen,
@@ -1308,12 +1321,17 @@ int cms_recipient_info_encrypt_to_der(
size_t enced_key_len;
int fixed_outlen = 1;
if (public_key->algor != OID_ec_public_key
|| public_key->algor_param != OID_sm2) {
error_print();
return -1;
}
if (pke_algor != OID_sm2encrypt) {
error_print();
return -1;
}
if (sm2_encrypt_fixlen(public_key, in, inlen, SM2_ciphertext_typical_point_size,
if (sm2_encrypt_fixlen(&public_key->u.sm2_key, in, inlen, SM2_ciphertext_typical_point_size,
enced_key, &enced_key_len) != 1) {
error_print();
return -1;
@@ -1329,7 +1347,7 @@ int cms_recipient_info_encrypt_to_der(
}
int cms_recipient_info_decrypt_from_der(
const SM2_KEY *sm2_key,
const X509_KEY *x509_key,
const uint8_t *rcpt_issuer, size_t rcpt_issuer_len,
const uint8_t *rcpt_serial, size_t rcpt_serial_len,
uint8_t *out, size_t *outlen, size_t maxlen,
@@ -1366,7 +1384,13 @@ int cms_recipient_info_decrypt_from_der(
error_print();
return -1;
}
if (sm2_decrypt(sm2_key, enced_key, enced_key_len, outbuf, outlen) != 1) {
if (x509_key->algor != OID_ec_public_key
|| x509_key->algor_param != OID_sm2) {
error_print();
return -1;
}
if (sm2_decrypt(&x509_key->u.sm2_key, enced_key, enced_key_len, outbuf, outlen) != 1) {
error_print();
return -1;
}
@@ -1380,7 +1404,7 @@ int cms_recipient_info_decrypt_from_der(
int cms_recipient_infos_add_recipient_info(
uint8_t *d, size_t *dlen, size_t maxlen,
const SM2_KEY *public_key,
const X509_KEY *public_key,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial, size_t serial_len,
const uint8_t *in, size_t inlen)
@@ -1521,7 +1545,7 @@ int cms_enveloped_data_encrypt_to_der(
while (rcpt_certs_len) {
const uint8_t *cert;
size_t certlen;
SM2_KEY public_key;
X509_KEY public_key;
const uint8_t *issuer;
size_t issuer_len;
const uint8_t *serial;
@@ -1534,6 +1558,11 @@ int cms_enveloped_data_encrypt_to_der(
error_print();
return -1;
}
if (public_key.algor != OID_ec_public_key
|| public_key.algor_param != OID_sm2) {
error_print();
return -1;
}
if (cms_recipient_info_encrypt_to_der(&public_key,
issuer, issuer_len, serial, serial_len,
key, keylen, NULL, &len) != 1
@@ -1570,7 +1599,7 @@ int cms_enveloped_data_encrypt_to_der(
}
int cms_enveloped_data_decrypt_from_der(
const SM2_KEY *sm2_key,
const X509_KEY *x509_key,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial, size_t serial_len,
int *content_type, uint8_t *content, size_t *content_len,
@@ -1601,7 +1630,7 @@ int cms_enveloped_data_decrypt_from_der(
while (rcpt_infos_len) {
if ((ret = cms_recipient_info_decrypt_from_der(
sm2_key,
x509_key,
issuer, issuer_len,
serial, serial_len,
key, &keylen, sizeof(key),
@@ -1768,13 +1797,21 @@ int cms_signed_and_enveloped_data_encipher_to_der(
while (rcpt_certs_len) {
const uint8_t *cert;
size_t certlen;
SM2_KEY public_key;
X509_KEY public_key;
if (asn1_any_from_der(&cert, &certlen, &rcpt_certs, &rcpt_certs_len) != 1
|| x509_cert_get_issuer_and_serial_number(cert, certlen,
&issuer, &issuer_len, &serial, &serial_len) != 1
|| x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1
|| cms_recipient_info_encrypt_to_der(&public_key,
|| x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) {
error_print();
return -1;
}
if (public_key.algor != OID_ec_public_key
|| public_key.algor_param != OID_sm2) {
error_print();
return -1;
}
if (cms_recipient_info_encrypt_to_der(&public_key,
issuer, issuer_len, serial, serial_len,
key, keylen, NULL, &len) != 1
|| asn1_length_le(len, sizeof(rcpt_infos)) != 1
@@ -1843,7 +1880,7 @@ int cms_signed_and_enveloped_data_encipher_to_der(
}
int cms_signed_and_enveloped_data_decipher_from_der(
const SM2_KEY *rcpt_key,
const X509_KEY *rcpt_key,
const uint8_t *rcpt_issuer, size_t rcpt_issuer_len,
const uint8_t *rcpt_serial, size_t rcpt_serial_len,
int *content_type, uint8_t *content, size_t *content_len,
@@ -1961,19 +1998,19 @@ int cms_signed_and_enveloped_data_decipher_from_der(
int cms_key_agreement_info_to_der(
int version,
const SM2_KEY *temp_public_key_r,
const X509_KEY *temp_public_key_r,
const uint8_t *user_cert, size_t user_cert_len,
const uint8_t *user_id, size_t user_id_len,
uint8_t **out, size_t *outlen)
{
size_t len = 0;
if (asn1_int_to_der(version, NULL, &len) != 1
|| sm2_public_key_info_to_der(temp_public_key_r, NULL, &len) != 1
|| x509_public_key_info_to_der(temp_public_key_r, NULL, &len) != 1
|| x509_cert_to_der(user_cert, user_cert_len, NULL, &len) != 1
|| asn1_octet_string_to_der(user_id, user_id_len, NULL, &len) != 1
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| asn1_int_to_der(version, out, outlen) != 1
|| sm2_public_key_info_to_der(temp_public_key_r, out, outlen) != 1
|| x509_public_key_info_to_der(temp_public_key_r, out, outlen) != 1
|| x509_cert_to_der(user_cert, user_cert_len, out, outlen) != 1
|| asn1_octet_string_to_der(user_id, user_id_len, out, outlen) != 1) {
error_print();
@@ -1984,7 +2021,7 @@ int cms_key_agreement_info_to_der(
int cms_key_agreement_info_from_der(
int *version,
SM2_KEY *temp_public_key_r,
X509_KEY *temp_public_key_r,
const uint8_t **user_cert, size_t *user_cert_len,
const uint8_t **user_id, size_t *user_id_len,
const uint8_t **in, size_t *inlen)
@@ -1998,7 +2035,7 @@ int cms_key_agreement_info_from_der(
return ret;
}
if (asn1_int_from_der(version, &d, &dlen) != 1
|| sm2_public_key_info_from_der(temp_public_key_r, &d, &dlen) != 1
|| x509_public_key_info_from_der(temp_public_key_r, &d, &dlen) != 1
|| x509_cert_from_der(user_cert, user_cert_len, &d, &dlen) != 1
|| asn1_octet_string_from_der(user_id, user_id_len, &d, &dlen) != 1
|| asn1_length_is_zero(dlen) != 1) {
@@ -2252,7 +2289,7 @@ int cms_envelop(
}
int cms_deenvelop(const uint8_t *cms, size_t cmslen,
const SM2_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len,
const X509_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len,
int *content_type, uint8_t *content, size_t *content_len,
const uint8_t **rcpt_infos, size_t *rcpt_infos_len,
const uint8_t **shared_info1, size_t *shared_info1_len,
@@ -2265,7 +2302,7 @@ int cms_deenvelop(const uint8_t *cms, size_t cmslen,
size_t issuer_len;
const uint8_t *serial;
size_t serial_len;
SM2_KEY public_key;
X509_KEY public_key;
if (cms_content_info_from_der(&cms_type, &cms_content, &cms_content_len, &cms, &cmslen) != 1
|| asn1_check(cms_type == OID_cms_enveloped_data) != 1
@@ -2282,7 +2319,7 @@ int cms_deenvelop(const uint8_t *cms, size_t cmslen,
error_print();
return -1;
}
if (memcmp(&public_key, rcpt_key, sizeof(SM2_POINT)) != 0) {
if (memcmp(&public_key.u.sm2_key, rcpt_key, sizeof(SM2_POINT)) != 0) {
error_print();
return -1;
}
@@ -2351,7 +2388,7 @@ int cms_sign_and_envelop(uint8_t *cms, size_t *cmslen,
}
int cms_deenvelop_and_verify(const uint8_t *cms, size_t cmslen,
const SM2_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len,
const X509_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len,
const uint8_t *extra_certs, size_t extra_certs_len,
const uint8_t *extra_crls, size_t extra_crls_len,
int *content_type, uint8_t *content, size_t *content_len,
@@ -2366,7 +2403,7 @@ int cms_deenvelop_and_verify(const uint8_t *cms, size_t cmslen,
size_t rcpt_issuer_len;
const uint8_t *rcpt_serial;
size_t rcpt_serial_len;
SM2_KEY public_key;
X509_KEY public_key;
int cms_type;
const uint8_t *cms_content;
size_t cms_content_len;
@@ -2387,7 +2424,7 @@ int cms_deenvelop_and_verify(const uint8_t *cms, size_t cmslen,
error_print();
return -1;
}
if (memcmp(&public_key, rcpt_key, sizeof(SM2_POINT)) != 0) {
if (memcmp(&public_key.u.sm2_key, rcpt_key, sizeof(SM2_POINT)) != 0) {
error_print();
return -1;
}
@@ -2415,7 +2452,7 @@ int cms_deenvelop_and_verify(const uint8_t *cms, size_t cmslen,
int cms_set_key_agreement_info(
uint8_t *cms, size_t *cmslen,
const SM2_KEY *temp_public_key_r,
const X509_KEY *temp_public_key_r,
const uint8_t *user_cert, size_t user_cert_len,
const uint8_t *user_id, size_t user_id_len)
{

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2024 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.
@@ -145,8 +145,8 @@ int tlcp_do_connect(TLS_CONNECT *conn)
const uint8_t *exts;
size_t exts_len;
SM2_KEY server_sign_key;
SM2_KEY server_enc_key;
X509_KEY server_sign_key;
X509_KEY server_enc_key;
SM2_VERIFY_CTX verify_ctx;
SM2_SIGN_CTX sign_ctx;
const uint8_t *sig;
@@ -292,9 +292,17 @@ int tlcp_do_connect(TLS_CONNECT *conn)
tls_send_alert(conn, TLS_alert_bad_certificate);
goto end;
}
if (server_sign_key.algor != OID_ec_public_key
|| server_sign_key.algor_param != OID_sm2
|| server_enc_key.algor != OID_ec_public_key
|| server_enc_key.algor_param != OID_sm2) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
goto end;
}
p = server_enc_cert_lenbuf; len = 0;
tls_uint24_to_bytes((uint24_t)server_enc_cert_len, &p, &len);
if (sm2_verify_init(&verify_ctx, &server_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1
if (sm2_verify_init(&verify_ctx, &server_sign_key.u.sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1
|| sm2_verify_update(&verify_ctx, client_random, 32) != 1
|| sm2_verify_update(&verify_ctx, server_random, 32) != 1
|| sm2_verify_update(&verify_ctx, server_enc_cert_lenbuf, 3) != 1
@@ -411,7 +419,7 @@ int tlcp_do_connect(TLS_CONNECT *conn)
// send ClientKeyExchange
tls_trace("send ClientKeyExchange\n");
if (sm2_encrypt(&server_enc_key, pre_master_secret, 48,
if (sm2_encrypt(&server_enc_key.u.sm2_key, pre_master_secret, 48,
enced_pre_master_secret, &enced_pre_master_secret_len) != 1
|| tls_record_set_handshake_client_key_exchange_pke(record, &recordlen,
enced_pre_master_secret, enced_pre_master_secret_len) != 1) {
@@ -604,7 +612,7 @@ int tlcp_do_accept(TLS_CONNECT *conn)
size_t siglen;
// ClientCertificate, CertificateVerify
SM2_KEY client_sign_key;
X509_KEY client_sign_key;
SM2_VERIFY_CTX verify_ctx;
const uint8_t *sig;
const int verify_depth = 5;
@@ -853,9 +861,15 @@ int tlcp_do_accept(TLS_CONNECT *conn)
tls_send_alert(conn, TLS_alert_bad_certificate);
goto end;
}
if (client_sign_key.algor != OID_ec_public_key
|| client_sign_key.algor_param != OID_sm2) {
tls_send_alert(conn, TLS_alert_bad_certificate);
error_print();
goto end;
}
sm3_finish(&cert_verify_sm3_ctx, cert_verify_hash);
if (sm2_verify_init(&verify_ctx, &client_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1
if (sm2_verify_init(&verify_ctx, &client_sign_key.u.sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1
|| sm2_verify_update(&verify_ctx, cert_verify_hash, SM3_DIGEST_SIZE) != 1
|| sm2_verify_finish(&verify_ctx, sig, siglen) != 1) {
error_print();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2024 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.
@@ -2143,7 +2143,7 @@ int tls_ctx_set_certificate_and_key(TLS_CTX *ctx, const char *chainfile,
SM2_KEY key;
const uint8_t *cert;
size_t certlen;
SM2_KEY public_key;
X509_KEY public_key;
if (!ctx || !chainfile || !keyfile || !keypass) {
error_print();
@@ -2175,7 +2175,12 @@ int tls_ctx_set_certificate_and_key(TLS_CTX *ctx, const char *chainfile,
error_print();
return -1;
}
if (sm2_public_key_equ(&key, &public_key) != 1) {
if (public_key.algor != OID_ec_public_key
|| public_key.algor_param != OID_sm2) {
error_print();
return -1;
}
if (sm2_public_key_equ(&key, &public_key.u.sm2_key) != 1) {
error_print();
return -1;
}
@@ -2206,7 +2211,7 @@ int tls_ctx_set_tlcp_server_certificate_and_keys(TLS_CTX *ctx, const char *chain
const uint8_t *cert;
size_t certlen;
SM2_KEY public_key;
X509_KEY public_key;
if (!ctx || !chainfile || !signkeyfile || !signkeypass || !kenckeyfile || !kenckeypass) {
error_print();
@@ -2235,8 +2240,16 @@ int tls_ctx_set_tlcp_server_certificate_and_keys(TLS_CTX *ctx, const char *chain
goto end;
}
if (x509_certs_get_cert_by_index(certs, certslen, 0, &cert, &certlen) != 1
|| x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1
|| sm2_public_key_equ(&signkey, &public_key) != 1) {
|| x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) {
error_print();
return -1;
}
if (public_key.algor != OID_ec_public_key
|| public_key.algor_param != OID_sm2) {
error_print();
return -1;
}
if (sm2_public_key_equ(&signkey, &public_key.u.sm2_key) != 1) {
error_print();
goto end;
}
@@ -2250,8 +2263,16 @@ int tls_ctx_set_tlcp_server_certificate_and_keys(TLS_CTX *ctx, const char *chain
goto end;
}
if (x509_certs_get_cert_by_index(certs, certslen, 1, &cert, &certlen) != 1
|| x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1
|| sm2_public_key_equ(&kenckey, &public_key) != 1) {
|| x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) {
error_print();
return -1;
}
if (public_key.algor != OID_ec_public_key
|| public_key.algor_param != OID_sm2) {
error_print();
return -1;
}
if (sm2_public_key_equ(&kenckey, &public_key.u.sm2_key) != 1) {
error_print();
goto end;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2024 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.
@@ -202,7 +202,7 @@ int tls12_do_connect(TLS_CONNECT *conn)
int signature_algor = -1;
SM2_KEY server_sign_key;
X509_KEY server_sign_key;
SM2_SIGN_CTX sign_ctx;
const uint8_t *sig;
size_t siglen;
@@ -380,7 +380,13 @@ int tls12_do_connect(TLS_CONNECT *conn)
tls_send_alert(conn, TLS_alert_bad_certificate);
goto end;
}
if (tls_verify_server_ecdh_params(&server_sign_key, // 这应该是签名公钥
if (server_sign_key.algor != OID_ec_public_key
|| server_sign_key.algor_param != OID_sm2) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
goto end;
}
if (tls_verify_server_ecdh_params(&server_sign_key.u.sm2_key, // 这应该是签名公钥
client_random, server_random, curve, &server_ecdhe_public, sig, siglen) != 1) {
error_print();
tls_send_alert(conn, TLS_alert_internal_error);
@@ -687,7 +693,7 @@ int tls12_do_accept(TLS_CONNECT *conn)
// ClientCertificate, CertificateVerify
TLS_CLIENT_VERIFY_CTX client_verify_ctx;
SM2_KEY client_sign_key;
X509_KEY client_sign_key;
const uint8_t *sig;
const int verify_depth = 5;
int verify_result;
@@ -933,7 +939,13 @@ int tls12_do_accept(TLS_CONNECT *conn)
tls_send_alert(conn, TLS_alert_bad_certificate);
goto end;
}
if (tls_client_verify_finish(&client_verify_ctx, sig, siglen, &client_sign_key) != 1) {
if (client_sign_key.algor != OID_ec_public_key
|| client_sign_key.algor_param != OID_sm2) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
goto end;
}
if (tls_client_verify_finish(&client_verify_ctx, sig, siglen, &client_sign_key.u.sm2_key) != 1) {
error_print();
tls_send_alert(conn, TLS_alert_decrypt_error);
goto end;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2024 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.
@@ -510,7 +510,7 @@ int tls13_sign_certificate_verify(int tls_mode,
}
int tls13_verify_certificate_verify(int tls_mode,
const SM2_KEY *public_key, const char *signer_id, size_t signer_id_len,
const X509_KEY *public_key, const char *signer_id, size_t signer_id_len,
const DIGEST_CTX *tbs_dgst_ctx, const uint8_t *sig, size_t siglen)
{
int ret;
@@ -541,7 +541,13 @@ int tls13_verify_certificate_verify(int tls_mode,
dgst_ctx = *tbs_dgst_ctx;
digest_finish(&dgst_ctx, dgst, &dgstlen);
sm2_verify_init(&verify_ctx, public_key, signer_id, signer_id_len);
// FIXME: use x509_verify_init/update/finish
if (public_key->algor != OID_ec_public_key
|| public_key->algor_param != OID_sm2) {
error_print();
return -1;
}
sm2_verify_init(&verify_ctx, &public_key->u.sm2_key, signer_id, signer_id_len);
sm2_verify_update(&verify_ctx, prefix, 64);
sm2_verify_update(&verify_ctx, context_str_and_zero, context_str_and_zero_len);
sm2_verify_update(&verify_ctx, dgst, dgstlen);
@@ -1497,7 +1503,7 @@ int tls13_do_connect(TLS_CONNECT *conn)
SM2_KEY client_ecdhe;
SM2_Z256_POINT server_ecdhe_public;
SM2_KEY server_sign_key;
X509_KEY server_sign_key;
const DIGEST *digest = DIGEST_sm3();
DIGEST_CTX dgst_ctx; // secret generation过程中需要ClientHello等数据输入的
@@ -1729,6 +1735,12 @@ int tls13_do_connect(TLS_CONNECT *conn)
tls_send_alert(conn, TLS_alert_unexpected_message);
goto end;
}
if (server_sign_key.algor != OID_ec_public_key
|| server_sign_key.algor_param != OID_sm2) {
error_print();
tls_send_alert(conn, TLS_alert_unexpected_message);
goto end;
}
digest_update(&dgst_ctx, record + 5, recordlen - 5);
tls_seq_num_incr(conn->server_seq_num);
@@ -1975,7 +1987,7 @@ int tls13_do_accept(TLS_CONNECT *conn)
SM2_KEY server_ecdhe;
SM2_Z256_POINT client_ecdhe_public;
SM2_KEY client_sign_key;
X509_KEY client_sign_key;
const BLOCK_CIPHER *cipher = NULL;
const DIGEST *digest = NULL;
DIGEST_CTX dgst_ctx;
@@ -2285,9 +2297,16 @@ int tls13_do_accept(TLS_CONNECT *conn)
}
if (x509_cert_get_subject_public_key(cert, certlen, &client_sign_key) != 1) {
error_print();
tls_send_alert(conn, TLS_alert_unexpected_message);
tls_send_alert(conn, TLS_alert_bad_certificate);
goto end;
}
if (client_sign_key.algor != OID_ec_public_key
|| client_sign_key.algor_param != OID_sm2) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
goto end;
}
digest_update(&dgst_ctx, record + 5, recordlen - 5);
tls_seq_num_incr(conn->client_seq_num);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2025 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.
@@ -363,7 +363,7 @@ static const ASN1_OID_INFO x509_sign_algors[] = {
{ OID_rsasign_with_sha256, "sha256WithRSAEncryption", oid_rsasign_with_sha256, sizeof(oid_rsasign_with_sha256)/sizeof(int), 1 },
{ OID_rsasign_with_sha384, "sha384WithRSAEncryption", oid_rsasign_with_sha384, sizeof(oid_rsasign_with_sha384)/sizeof(int), 1 },
{ OID_rsasign_with_sha512, "sha512WithRSAEncryption", oid_rsasign_with_sha512, sizeof(oid_rsasign_with_sha512)/sizeof(int), 1 },
#ifdef ENABLE_LMS_HSS
#ifdef ENABLE_LMS
{ OID_hss_lms_hashsig, "hss-lms-hashsig", oid_hss_lms_hashsig, sizeof(oid_hss_lms_hashsig)/sizeof(int), 1 },
#endif
#ifdef ENABLE_XMSS
@@ -587,7 +587,7 @@ static uint32_t oid_ec_public_key[] = { oid_x9_62,2,1 };
static const ASN1_OID_INFO x509_public_key_algors[] = {
{ OID_ec_public_key, "ecPublicKey", oid_ec_public_key, sizeof(oid_ec_public_key)/sizeof(int), 0, "X9.62 ecPublicKey" },
{ OID_rsa_encryption, "rsaEncryption", oid_rsa_encryption, sizeof(oid_rsa_encryption)/sizeof(int), 0, "RSAEncryption" },
#ifdef ENABLE_LMS_HSS
#ifdef ENABLE_LMS
{ OID_hss_lms_hashsig, "hss-lms-hashsig", oid_hss_lms_hashsig, sizeof(oid_hss_lms_hashsig)/sizeof(int), 0, "HSS/LMS HashSig" },
#endif
#ifdef ENABLE_XMSS
@@ -644,7 +644,7 @@ int x509_public_key_algor_to_der(int oid, int curve_or_null, uint8_t **out, size
return -1;
}
break;
#ifdef ENABLE_LMS_HSS
#ifdef ENABLE_LMS
// TODO: rsa, hss/lms, xmss/xmss^mt OID encoding is similar, reduce code size
case OID_hss_lms_hashsig:
if (asn1_object_identifier_to_der(oid_hss_lms_hashsig, sizeof(oid_hss_lms_hashsig)/sizeof(int), NULL, &len) != 1
@@ -713,7 +713,7 @@ int x509_public_key_algor_from_der(int *oid , int *curve_or_null, const uint8_t
}
break;
case OID_rsa_encryption:
#ifdef ENABLE_LMS_HSS
#ifdef ENABLE_LMS
case OID_hss_lms_hashsig:
#endif
#ifdef ENABLE_XMSS
@@ -750,7 +750,7 @@ int x509_public_key_algor_print(FILE *fp, int fmt, int ind, const char *label, c
format_print(fp, fmt, ind, "namedCurve: %s\n", ec_named_curve_name(val));
break;
case OID_rsa_encryption:
#ifdef ENABLE_LMS_HSS
#ifdef ENABLE_LMS
case OID_hss_lms_hashsig:
#endif
#ifdef ENABLE_XMSS

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2023 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.
@@ -983,7 +983,7 @@ int x509_tbs_cert_to_der(
const uint8_t *issuer, size_t issuer_len,
time_t not_before, time_t not_after,
const uint8_t *subject, size_t subject_len,
const SM2_KEY *subject_public_key,
const X509_KEY *subject_public_key,
const uint8_t *issuer_unique_id, size_t issuer_unique_id_len,
const uint8_t *subject_unique_id, size_t subject_unique_id_len,
const uint8_t *exts, size_t exts_len,
@@ -1024,7 +1024,7 @@ int x509_tbs_cert_from_der(
const uint8_t **issuer, size_t *issuer_len,
time_t *not_before, time_t *not_after,
const uint8_t **subject, size_t *subject_len,
SM2_KEY *subject_public_key,
X509_KEY *subject_public_key,
const uint8_t **issuer_unique_id, size_t *issuer_unique_id_len,
const uint8_t **subject_unique_id, size_t *subject_unique_id_len,
const uint8_t **exts, size_t *exts_len,
@@ -1098,18 +1098,27 @@ int x509_cert_sign_to_der(
const uint8_t *issuer, size_t issuer_len,
time_t not_before, time_t not_after,
const uint8_t *subject, size_t subject_len,
const SM2_KEY *subject_public_key,
const X509_KEY *subject_public_key,
const uint8_t *issuer_unique_id, size_t issuer_unique_id_len,
const uint8_t *subject_unique_id, size_t subject_unique_id_len,
const uint8_t *exts, size_t exts_len,
const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len,
X509_KEY *sign_key, const char *signer_id, size_t signer_id_len,
uint8_t **out, size_t *outlen)
{
size_t len = 0;
uint8_t *tbs = NULL;
int sig_alg = OID_sm2sign_with_sm3;
uint8_t sig[SM2_MAX_SIGNATURE_SIZE];
size_t siglen = SM2_signature_typical_size;
int sig_alg;
uint8_t sig[X509_SIGNATURE_MAX_SIZE];
size_t siglen;
if (x509_key_get_sign_algor(sign_key, &sig_alg) != 1) {
error_print();
return -1;
}
if (x509_key_get_signature_size(sign_key, &siglen) != 1) {
error_print();
return -1;
}
if (x509_tbs_cert_to_der(
version,
@@ -1150,10 +1159,10 @@ int x509_cert_sign_to_der(
}
if (out && *out) {
SM2_SIGN_CTX sign_ctx;
if (sm2_sign_init(&sign_ctx, sign_key, signer_id, signer_id_len) != 1
|| sm2_sign_update(&sign_ctx, tbs, *out - tbs) != 1
|| sm2_sign_finish_fixlen(&sign_ctx, siglen, sig) != 1) {
X509_SIGN_CTX sign_ctx;
if (x509_sign_init(&sign_ctx, sign_key, signer_id, signer_id_len) != 1
|| x509_sign_update(&sign_ctx, tbs, *out - tbs) != 1
|| x509_sign_finish(&sign_ctx, sig, &siglen) != 1) {
gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx));
error_print();
return -1;
@@ -1197,27 +1206,34 @@ int x509_signed_from_der(const uint8_t **tbs, size_t *tbslen,
}
int x509_signed_verify(const uint8_t *a, size_t alen,
const SM2_KEY *pub_key, const char *signer_id, size_t signer_id_len)
const X509_KEY *key, const char *signer_id, size_t signer_id_len)
{
const uint8_t *tbs;
size_t tbslen;
int sig_alg;
const uint8_t *sig;
size_t siglen;
SM2_VERIFY_CTX verify_ctx;
int key_sig_alg;
X509_SIGN_CTX verify_ctx;
if (x509_key_get_sign_algor(key, &key_sig_alg) != 1) {
error_print();
return -1;
}
if (x509_signed_from_der(&tbs, &tbslen, &sig_alg, &sig, &siglen, &a, &alen) != 1
|| asn1_length_is_zero(alen) != 1) {
error_print();
return -1;
}
if (sig_alg != OID_sm2sign_with_sm3) {
if (sig_alg != key_sig_alg) {
error_print();
return -1;
}
if (sm2_verify_init(&verify_ctx, pub_key, signer_id, signer_id_len) != 1
|| sm2_verify_update(&verify_ctx, tbs, tbslen) != 1
|| sm2_verify_finish(&verify_ctx, sig, siglen) != 1) {
if (x509_verify_init(&verify_ctx, key, signer_id, signer_id_len, sig, siglen) != 1
|| x509_verify_update(&verify_ctx, tbs, tbslen) != 1
|| x509_verify_finish(&verify_ctx) != 1) {
error_print();
return -1;
}
@@ -1229,7 +1245,7 @@ int x509_signed_verify_by_ca_cert(const uint8_t *a, size_t alen,
const char *signer_id, size_t signer_id_len)
{
int ret;
SM2_KEY public_key;
X509_KEY public_key;
if (x509_cert_get_subject_public_key(cacert, cacertlen, &public_key) != 1
|| (ret = x509_signed_verify(a, alen, &public_key, signer_id, signer_id_len)) < 0) {
@@ -1387,7 +1403,7 @@ int x509_cert_get_details(const uint8_t *a, size_t alen,
const uint8_t **issuer, size_t *issuer_len,
time_t *not_before, time_t *not_after,
const uint8_t **subject, size_t *subject_len,
SM2_KEY *subject_public_key,
X509_KEY *subject_public_key,
const uint8_t **issuer_unique_id, size_t *issuer_unique_id_len,
const uint8_t **subject_unique_id, size_t *subject_unique_id_len,
const uint8_t **extensions, size_t *extensions_len,
@@ -1407,7 +1423,7 @@ int x509_cert_get_details(const uint8_t *a, size_t alen,
const uint8_t *issuer; size_t issuer_len;
time_t not_before; time_t not_after;
const uint8_t *subject; size_t subject_len;
SM2_KEY subject_public_key;
X509_KEY subject_public_key;
const uint8_t *issuer_unique_id; size_t issuer_unique_id_len;
const uint8_t *subject_unique_id; size_t subject_unique_id_len;
const uint8_t *exts; size_t exts_len;
@@ -1475,7 +1491,7 @@ int x509_cert_get_issuer_and_serial_number(const uint8_t *a, size_t alen,
NULL, NULL); // signature
}
int x509_cert_get_subject_public_key(const uint8_t *a, size_t alen, SM2_KEY *public_key)
int x509_cert_get_subject_public_key(const uint8_t *a, size_t alen, X509_KEY *public_key)
{
return x509_cert_get_details(a, alen,
NULL, // version

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2023 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.
@@ -17,6 +17,7 @@
#include <gmssl/x509_crl.h>
#include <gmssl/x509_alg.h>
#include <gmssl/x509_ext.h>
#include <gmssl/x509_key.h>
#include <gmssl/pem.h>
#include <gmssl/mem.h>
#include <gmssl/http.h>
@@ -1046,7 +1047,7 @@ int x509_crl_exts_add_authority_key_identifier(
}
int x509_crl_exts_add_default_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen,
const SM2_KEY *public_key)
const X509_KEY *public_key)
{
int ret;
if ((ret = x509_exts_add_default_authority_key_identifier(exts, extslen, maxlen, public_key)) != 1) {
@@ -1422,15 +1423,24 @@ int x509_crl_sign_to_der(
time_t this_update, time_t next_update,
const uint8_t *revoked_certs, size_t revoked_certs_len,
const uint8_t *crl_exts, size_t crl_exts_len,
const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len,
X509_KEY *sign_key, const char *signer_id, size_t signer_id_len,
uint8_t **out, size_t *outlen)
{
int key_sig_alg;
size_t len = 0;
uint8_t *tbs = NULL;
uint8_t sig[SM2_MAX_SIGNATURE_SIZE];
size_t siglen = SM2_signature_typical_size;
uint8_t sig[X509_SIGNATURE_MAX_SIZE];
size_t siglen;
if (sig_alg != OID_sm2sign_with_sm3) {
if (x509_key_get_sign_algor(sign_key, &key_sig_alg) != 1) {
error_print();
return -1;
}
if (sig_alg != key_sig_alg) {
error_print();
return -1;
}
if (x509_key_get_signature_size(sign_key, &siglen) != 1) {
error_print();
return -1;
}
@@ -1454,10 +1464,10 @@ int x509_crl_sign_to_der(
return -1;
}
if (out && *out) {
SM2_SIGN_CTX sign_ctx;
if (sm2_sign_init(&sign_ctx, sign_key, signer_id, signer_id_len) != 1
|| sm2_sign_update(&sign_ctx, tbs, *out - tbs) != 1
|| sm2_sign_finish_fixlen(&sign_ctx, siglen, sig) != 1) {
X509_SIGN_CTX sign_ctx;
if (x509_sign_init(&sign_ctx, sign_key, signer_id, signer_id_len) != 1
|| x509_sign_update(&sign_ctx, tbs, *out - tbs) != 1
|| x509_sign_finish(&sign_ctx, sig, &siglen) != 1) {
gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx));
error_print();
return -1;

View File

@@ -19,6 +19,7 @@
#include <gmssl/asn1.h>
#include <gmssl/x509.h>
#include <gmssl/x509_ext.h>
#include <gmssl/x509_key.h>
#include <gmssl/error.h>
@@ -348,7 +349,7 @@ int x509_exts_add_authority_key_identifier(uint8_t *exts, size_t *extslen, size_
}
int x509_exts_add_default_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen,
const SM2_KEY *public_key)
const X509_KEY *public_key)
{
uint8_t id[32];
int critical = -1;
@@ -357,7 +358,7 @@ int x509_exts_add_default_authority_key_identifier(uint8_t *exts, size_t *extsle
return 0;
}
if (sm2_public_key_digest(public_key, id) != 1) {
if (x509_public_key_digest(public_key, id) != 1) {
error_print();
return -1;
}
@@ -399,7 +400,7 @@ int x509_exts_add_subject_key_identifier(uint8_t *exts, size_t *extslen, size_t
}
int x509_exts_add_subject_key_identifier_ex(uint8_t *exts, size_t *extslen, size_t maxlen,
int critical, const SM2_KEY *subject_key)
int critical, const X509_KEY *subject_key)
{
uint8_t id[32];
@@ -407,7 +408,7 @@ int x509_exts_add_subject_key_identifier_ex(uint8_t *exts, size_t *extslen, size
return 0;
}
if (sm2_public_key_digest(subject_key, id) != 1) {
if (x509_public_key_digest(subject_key, id) != 1) {
error_print();
return -1;
}

737
src/x509_key.c Normal file
View File

@@ -0,0 +1,737 @@
/*
* 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.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/ec.h>
#include <gmssl/oid.h>
#include <gmssl/asn1.h>
#include <gmssl/sm2.h>
#include <gmssl/mem.h>
#include <gmssl/error.h>
#include <gmssl/x509_alg.h>
#include <gmssl/x509_cer.h>
#include <gmssl/x509_key.h>
// currently the lms_type(s) of SHA-256 and SM3 are smaller than 4-bit
// so we encode the lms_types into 4-bit array and int value
// TODO: if max lms_type > 15, this function must be change!
int x509_algor_param_from_lms_types(int *algor_param, const int *lms_types, size_t num)
{
if (!algor_param || !lms_types || !num) {
error_print();
return -1;
}
if (num > HSS_MAX_LEVELS) {
error_print();
return -1;
}
*algor_param = 0;
while (num--) {
if (lms_types[num] < 0 || lms_types[num] > 15) {
error_print();
return -1;
}
*algor_param <<= 4;
*algor_param |= lms_types[num] & 0x0f;
}
return 1;
}
int x509_algor_param_to_lms_types(int algor_param, int lms_types[5], size_t *num)
{
if (!lms_types || !num) {
error_print();
return -1;
}
for (*num = 0; *num < 5; (*num)++) {
if (!algor_param) {
break;
}
lms_types[*num] = algor_param & 0x0f;
if (!lms_type_name(lms_types[*num])) {
error_print();
return -1;
}
algor_param >>= 4;
}
return 1;
}
int x509_key_generate(X509_KEY *key, int algor, int algor_param)
{
if (!key) {
error_print();
return -1;
}
memset(key, 0, sizeof(X509_KEY));
switch (algor) {
case OID_ec_public_key:
if (algor_param != OID_sm2) {
error_print();
return -1;
}
if (sm2_key_generate(&key->u.sm2_key) != 1) {
error_print();
return -1;
}
break;
case OID_lms_hashsig:
if (!lms_type_name(algor_param)) {
error_print();
return -1;
}
if (lms_key_generate(&key->u.lms_key, algor_param) != 1) {
error_print();
return -1;
}
break;
case OID_hss_lms_hashsig:
{
int lms_types[5];
size_t num;
if (x509_algor_param_to_lms_types(algor_param, lms_types, &num) != 1) {
error_print();
return -1;
}
if (hss_key_generate(&key->u.hss_key, lms_types, num) != 1) {
error_print();
return -1;
}
}
break;
case OID_xmss_hashsig:
if (!xmss_type_name((uint32_t)algor_param)) {
error_print();
return -1;
}
if (xmss_key_generate(&key->u.xmss_key, (uint32_t)algor_param) != 1) {
error_print();
return -1;
}
break;
case OID_xmssmt_hashsig:
if (!xmssmt_type_name((uint32_t)algor_param)) {
error_print();
return -1;
}
if (xmssmt_key_generate(&key->u.xmssmt_key, (uint32_t)algor_param) != 1) {
error_print();
return -1;
}
break;
case OID_sphincs_hashsig:
if (algor_param != OID_undef) {
error_print();
return -1;
}
if (sphincs_key_generate(&key->u.sphincs_key) != 1) {
error_print();
return -1;
}
break;
default:
error_print();
return -1;
}
key->algor = algor;
key->algor_param = algor_param;
return 1;
}
int x509_public_key_print(FILE *fp, int fmt, int ind, const char *label, const X509_KEY *key)
{
switch (key->algor) {
case OID_ec_public_key:
if (sm2_public_key_print(fp, fmt, ind, label, &key->u.sm2_key) != 1) {
error_print();
return -1;
}
break;
case OID_lms_hashsig:
if (lms_public_key_print(fp, fmt, ind, label, &key->u.lms_key.public_key) != 1) {
error_print();
return -1;
}
break;
case OID_hss_lms_hashsig:
if (hss_public_key_print(fp, fmt, ind, label, &key->u.hss_key) != 1) {
error_print();
return -1;
}
break;
case OID_xmss_hashsig:
if (xmss_public_key_print(fp, fmt, ind, label, &key->u.xmss_key) != 1) {
error_print();
return -1;
}
break;
case OID_xmssmt_hashsig:
if (xmssmt_public_key_print(fp, fmt, ind, label, &key->u.xmssmt_key) != 1) {
error_print();
return -1;
}
break;
case OID_sphincs_hashsig:
if (sphincs_public_key_print(fp, fmt, ind, label, &key->u.sphincs_key) != 1) {
error_print();
return -1;
}
break;
default:
error_print();
return -1;
}
return 1;
}
int x509_key_set_sm2_key(X509_KEY *x509_key, SM2_KEY *sm2_key)
{
memset(x509_key, 0, sizeof(X509_KEY));
x509_key->algor = OID_ec_public_key;
x509_key->algor_param = OID_sm2;
x509_key->u.sm2_key = *sm2_key;
return 1;
}
int x509_key_set_lms_key(X509_KEY *x509_key, LMS_KEY *lms_key)
{
memset(x509_key, 0, sizeof(X509_KEY));
x509_key->algor = OID_lms_hashsig;
x509_key->algor_param = OID_undef;
x509_key->u.lms_key = *lms_key;
return -1;
}
int x509_key_set_hss_key(X509_KEY *x509_key, HSS_KEY *hss_key)
{
memset(x509_key, 0, sizeof(X509_KEY));
x509_key->algor = OID_hss_lms_hashsig;
x509_key->algor_param = OID_undef;
x509_key->u.hss_key = *hss_key;
return 1;
}
int x509_key_set_xmss_key(X509_KEY *x509_key, XMSS_KEY *xmss_key)
{
memset(x509_key, 0, sizeof(X509_KEY));
x509_key->algor = OID_xmss_hashsig;
x509_key->algor_param = OID_undef;
x509_key->u.xmss_key = *xmss_key;
return 1;
}
int x509_key_set_xmssmt_key(X509_KEY *x509_key, XMSSMT_KEY *xmssmt_key)
{
memset(x509_key, 0, sizeof(X509_KEY));
x509_key->algor = OID_xmssmt_hashsig;
x509_key->algor_param = OID_undef;
x509_key->u.xmssmt_key = *xmssmt_key;
return 1;
}
int x509_key_set_sphincs_key(X509_KEY *x509_key, SPHINCS_KEY *sphincs_key)
{
memset(x509_key, 0, sizeof(X509_KEY));
x509_key->algor = OID_sphincs_hashsig;
x509_key->algor_param = OID_undef;
x509_key->u.sphincs_key = *sphincs_key;
return 1;
}
int x509_key_get_sign_algor(const X509_KEY *key, int *algor)
{
if (!key || !algor) {
error_print();
return -1;
}
switch (key->algor) {
case OID_lms_hashsig:
case OID_hss_lms_hashsig:
case OID_xmss_hashsig:
case OID_xmssmt_hashsig:
case OID_sphincs_hashsig:
*algor = key->algor;
break;
case OID_ec_public_key:
*algor = OID_sm2sign_with_sm3;
break;
default:
fprintf(stderr, "key->algor = %d\n", key->algor);
error_print();
return -1;
}
return 1;
}
int x509_public_key_digest(const X509_KEY *key, uint8_t dgst[32])
{
SM3_CTX ctx;
uint8_t bits[X509_PUBLIC_KEY_MAX_SIZE];
uint8_t *p = bits;
size_t len = 0;
switch (key->algor) {
case OID_ec_public_key:
if (sm2_z256_point_to_uncompressed_octets(&key->u.sm2_key.public_key, bits) != 1) {
error_print();
return -1;
}
len = 65;
break;
case OID_hss_lms_hashsig:
if (hss_public_key_to_bytes(&key->u.hss_key, &p, &len) != 1) {
error_print();
return -1;
}
break;
case OID_xmss_hashsig:
if (xmss_public_key_to_bytes(&key->u.xmss_key, &p, &len) != 1) {
error_print();
return -1;
}
break;
case OID_xmssmt_hashsig:
if (xmssmt_public_key_to_bytes(&key->u.xmssmt_key, &p, &len) != 1) {
error_print();
return -1;
}
break;
default:
error_print();
return -1;
}
sm3_init(&ctx);
sm3_update(&ctx, bits, len);
sm3_finish(&ctx, dgst);
return 1;
}
int x509_key_get_signature_size(const X509_KEY *key, size_t *siglen)
{
switch (key->algor) {
case OID_hss_lms_hashsig:
if (hss_key_get_signature_size(&key->u.hss_key, siglen) != 1) {
error_print();
return -1;
}
break;
case OID_xmss_hashsig:
if (xmss_key_get_signature_size(&key->u.xmss_key, siglen) != 1) {
error_print();
return -1;
}
break;
case OID_xmssmt_hashsig:
if (xmssmt_key_get_signature_size(&key->u.xmssmt_key, siglen) != 1) {
error_print();
return -1;
}
break;
case OID_ec_public_key:
*siglen = SM2_signature_typical_size;
break;
default:
error_print();
return -1;
}
return 1;
}
int x509_sign_init(X509_SIGN_CTX *ctx, X509_KEY *key, const char *signer_id, size_t signer_idlen)
{
if (!ctx || !key) {
error_print();
return -1;
}
switch (key->algor) {
case OID_hss_lms_hashsig:
if (hss_sign_init(&ctx->u.hss_sign_ctx, &key->u.hss_key) != 1) {
error_print();
return -1;
}
ctx->sign_algor = key->algor;
break;
case OID_xmss_hashsig:
if (xmss_sign_init(&ctx->u.xmss_sign_ctx, &key->u.xmss_key) != 1) {
error_print();
return -1;
}
ctx->sign_algor = key->algor;
break;
case OID_xmssmt_hashsig:
if (xmssmt_sign_init(&ctx->u.xmssmt_sign_ctx, &key->u.xmssmt_key) != 1) {
error_print();
return -1;
}
ctx->sign_algor = key->algor;
break;
case OID_ec_public_key:
if (sm2_sign_init(&ctx->u.sm2_sign_ctx, &key->u.sm2_key, signer_id, signer_idlen) != 1) {
error_print();
return -1;
}
ctx->sign_algor = OID_sm2sign_with_sm3;
break;
default:
error_print();
return -1;
}
return 1;
}
int x509_sign_update(X509_SIGN_CTX *ctx, const uint8_t *data, size_t datalen)
{
switch (ctx->sign_algor) {
case OID_hss_lms_hashsig:
if (hss_sign_update(&ctx->u.hss_sign_ctx, data, datalen) != 1) {
error_print();
return -1;
}
break;
case OID_xmss_hashsig:
if (xmss_sign_update(&ctx->u.xmss_sign_ctx, data, datalen) != 1) {
error_print();
return -1;
}
break;
case OID_xmssmt_hashsig:
if (xmssmt_sign_update(&ctx->u.xmssmt_sign_ctx, data, datalen) != 1) {
error_print();
return -1;
}
break;
case OID_sm2sign_with_sm3:
if (sm2_sign_update(&ctx->u.sm2_sign_ctx, data, datalen) != 1) {
error_print();
return -1;
}
break;
default:
error_print();
return -1;
}
return 1;
}
int x509_sign_finish(X509_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen)
{
if (!ctx || !sig || !siglen) {
error_print();
return -1;
}
switch (ctx->sign_algor) {
case OID_hss_lms_hashsig:
if (hss_sign_finish(&ctx->u.hss_sign_ctx, sig, siglen) != 1) {
error_print();
return -1;
}
break;
case OID_xmss_hashsig:
if (xmss_sign_finish(&ctx->u.xmss_sign_ctx, sig, siglen) != 1) {
error_print();
return -1;
}
break;
case OID_xmssmt_hashsig:
if (xmssmt_sign_finish(&ctx->u.xmssmt_sign_ctx, sig, siglen) != 1) {
error_print();
return -1;
}
break;
case OID_sm2sign_with_sm3:
*siglen = SM2_signature_typical_size;
if (sm2_sign_finish_fixlen(&ctx->u.sm2_sign_ctx, *siglen, sig) != 1) {
error_print();
return -1;
}
break;
default:
error_print();
return -1;
}
return 1;
}
int x509_verify_init(X509_SIGN_CTX *ctx, const X509_KEY *key, const char *signer_id, size_t signer_idlen,
const uint8_t *sig, size_t siglen)
{
if (!ctx || !key || !sig || !siglen) {
error_print();
return -1;
}
switch (key->algor) {
case OID_hss_lms_hashsig:
if (hss_verify_init(&ctx->u.hss_sign_ctx, &key->u.hss_key, sig, siglen) != 1) {
error_print();
return -1;
}
ctx->sign_algor = key->algor;
break;
case OID_xmss_hashsig:
if (xmss_verify_init(&ctx->u.xmss_sign_ctx, &key->u.xmss_key, sig, siglen) != 1) {
error_print();
return -1;
}
ctx->sign_algor = key->algor;
break;
case OID_xmssmt_hashsig:
if (xmssmt_verify_init(&ctx->u.xmssmt_sign_ctx, &key->u.xmssmt_key, sig, siglen) != 1) {
error_print();
return -1;
}
ctx->sign_algor = key->algor;
break;
case OID_ec_public_key:
if (sm2_verify_init(&ctx->u.sm2_verify_ctx, &key->u.sm2_key, signer_id, signer_idlen) != 1) {
error_print();
return -1;
}
ctx->sign_algor = OID_sm2sign_with_sm3;
if (siglen > sizeof(ctx->sig)) {
error_print();
return -1;
}
memcpy(ctx->sig, sig, siglen);
ctx->siglen = siglen;
break;
default:
error_print();
return -1;
}
return 1;
}
int x509_verify_update(X509_SIGN_CTX *ctx, const uint8_t *data, size_t datalen)
{
switch (ctx->sign_algor) {
case OID_hss_lms_hashsig:
if (hss_verify_update(&ctx->u.hss_sign_ctx, data, datalen) != 1) {
error_print();
return -1;
}
break;
case OID_xmss_hashsig:
if (xmss_verify_update(&ctx->u.xmss_sign_ctx, data, datalen) != 1) {
error_print();
return -1;
}
break;
case OID_xmssmt_hashsig:
if (xmssmt_verify_update(&ctx->u.xmssmt_sign_ctx, data, datalen) != 1) {
error_print();
return -1;
}
break;
case OID_sm2sign_with_sm3:
if (sm2_verify_update(&ctx->u.sm2_verify_ctx, data, datalen) != 1) {
error_print();
return -1;
}
break;
default:
error_print();
return -1;
}
return 1;
}
int x509_verify_finish(X509_SIGN_CTX *ctx)
{
int ret;
switch (ctx->sign_algor) {
case OID_hss_lms_hashsig:
if ((ret = hss_verify_finish(&ctx->u.hss_sign_ctx)) < 0) {
error_print();
return -1;
}
break;
case OID_xmss_hashsig:
if ((ret = xmss_verify_finish(&ctx->u.xmss_sign_ctx)) < 0) {
error_print();
return -1;
}
break;
case OID_xmssmt_hashsig:
if ((ret = xmssmt_verify_finish(&ctx->u.xmssmt_sign_ctx)) < 0) {
error_print();
return -1;
}
break;
case OID_sm2sign_with_sm3:
if ((ret = sm2_verify_update(&ctx->u.sm2_verify_ctx, ctx->sig, ctx->siglen)) < 0) {
error_print();
return -1;
}
break;
default:
error_print();
return -1;
}
return 1;
}
int x509_public_key_info_to_der(const X509_KEY *x509_key, uint8_t **out, size_t *outlen)
{
uint8_t keybuf[300];
uint8_t *p = keybuf;
size_t keylen = 0;
size_t len = 0;
if (!x509_key || !outlen) {
error_print();
return -1;
}
switch (x509_key->algor) {
case OID_hss_lms_hashsig:
if (hss_public_key_to_bytes(&x509_key->u.hss_key, &p, &keylen) != 1) {
error_print();
return -1;
}
break;
case OID_xmss_hashsig:
if (xmss_public_key_to_bytes(&x509_key->u.xmss_key, &p, &keylen) != 1) {
error_print();
return -1;
}
break;
case OID_xmssmt_hashsig:
if (xmssmt_public_key_to_bytes(&x509_key->u.xmssmt_key, &p, &keylen) != 1) {
error_print();
return -1;
}
break;
case OID_ec_public_key:
sm2_z256_point_to_uncompressed_octets(&x509_key->u.sm2_key.public_key, p);
keylen = 65;
break;
default:
error_print();
}
// 这几个函数需要合并到一起
if (x509_public_key_algor_to_der(x509_key->algor, x509_key->algor_param, NULL, &len) != 1) {
error_print();
return -1;
}
if (asn1_bit_octets_to_der(keybuf, keylen, NULL, &len) != 1) {
error_print();
return -1;
}
if (asn1_sequence_header_to_der(len, out, outlen) != 1) {
error_print();
return -1;
}
if (x509_public_key_algor_to_der(x509_key->algor, x509_key->algor_param, out, outlen) != 1
|| asn1_bit_octets_to_der(keybuf, keylen, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_public_key_info_from_der(X509_KEY *x509_key, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *d;
size_t dlen;
int algor;
int algor_param;
const uint8_t *pub;
size_t publen;
if (!x509_key || !in || !(*in) || !inlen) {
error_print();
return -1;
}
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (x509_public_key_algor_from_der(&algor, &algor_param, &d, &dlen) != 1
|| asn1_bit_octets_from_der(&pub, &publen, &d, &dlen) != 1
|| asn1_length_is_zero(dlen) != 1) {
error_print();
return -1;
}
memset(x509_key, 0, sizeof(X509_KEY));
switch (algor) {
case OID_ec_public_key:
if (algor_param != OID_sm2) {
error_print();
return -1;
}
if (sm2_z256_point_from_octets(&x509_key->u.sm2_key.public_key, pub, publen) != 1) {
error_print();
return -1;
}
publen = 0;
break;
case OID_hss_lms_hashsig:
if (hss_public_key_from_bytes(&x509_key->u.hss_key, &pub, &publen) != 1) {
error_print();
return -1;
}
break;
case OID_xmss_hashsig:
if (xmss_public_key_from_bytes(&x509_key->u.xmss_key, &pub, &publen) != 1) {
error_print();
return -1;
}
break;
case OID_xmssmt_hashsig:
if (xmssmt_public_key_from_bytes(&x509_key->u.xmssmt_key, &pub, &publen) != 1) {
error_print();
return -1;
}
break;
case OID_sphincs_hashsig:
if (sphincs_public_key_from_bytes(&x509_key->u.sphincs_key, &pub, &publen) != 1) {
error_print();
return -1;
}
break;
default:
error_print();
return -1;
}
x509_key->algor = algor;
x509_key->algor_param = algor_param;
if (publen) {
error_print();
return -1;
}
return 1;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2024 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.
@@ -24,12 +24,13 @@
#include <gmssl/x509_req.h>
#include <gmssl/x509_ext.h>
#include <gmssl/x509_alg.h>
#include <gmssl/x509_key.h>
int x509_request_info_to_der(
int version,
const uint8_t *subject, size_t subject_len,
const SM2_KEY *subject_public_key,
const X509_KEY *subject_public_key,
const uint8_t *attrs, size_t attrs_len,
uint8_t **out, size_t *outlen)
{
@@ -56,7 +57,7 @@ int x509_request_info_to_der(
int x509_request_info_from_der(
int *version,
const uint8_t **subject, size_t *subject_len,
SM2_KEY *subject_public_key,
X509_KEY *subject_public_key,
const uint8_t **attrs, size_t *attrs_len,
const uint8_t **in, size_t *inlen)
{
@@ -110,7 +111,7 @@ err:
static int x509_request_from_der(
int *version,
const uint8_t **subject, size_t *subject_len,
SM2_KEY *subject_public_key,
X509_KEY *subject_public_key,
const uint8_t **attrs, size_t *attrs_len,
int *signature_algor,
const uint8_t **sig, size_t *siglen,
@@ -159,17 +160,26 @@ err:
int x509_req_sign_to_der(
int version,
const uint8_t *subject, size_t subject_len,
const SM2_KEY *subject_public_key,
const X509_KEY *subject_public_key,
const uint8_t *attrs, size_t attrs_len,
int signature_algor,
const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len,
X509_KEY *sign_key, const char *signer_id, size_t signer_id_len,
uint8_t **out, size_t *outlen)
{
size_t len = 0;
uint8_t *tbs = NULL;
int sig_alg = OID_sm2sign_with_sm3;
uint8_t sig[SM2_MAX_SIGNATURE_SIZE];
size_t siglen = SM2_signature_typical_size;
int sig_alg;
uint8_t sig[X509_SIGNATURE_MAX_SIZE];
size_t siglen;
if (x509_key_get_sign_algor(sign_key, &sig_alg) != 1) {
error_print();
return -1;
}
if (x509_key_get_signature_size(sign_key, &siglen) != 1) {
error_print();
return -1;
}
if (x509_request_info_to_der(version, subject, subject_len, subject_public_key,
attrs, attrs_len, NULL, &len) != 1
@@ -188,10 +198,10 @@ int x509_req_sign_to_der(
return -1;
}
if (out && *out) {
SM2_SIGN_CTX sign_ctx;
if (sm2_sign_init(&sign_ctx, sign_key, signer_id, signer_id_len) != 1
|| sm2_sign_update(&sign_ctx, tbs, *out - tbs) != 1
|| sm2_sign_finish_fixlen(&sign_ctx, siglen, sig) != 1) {
X509_SIGN_CTX sign_ctx;
if (x509_sign_init(&sign_ctx, sign_key, signer_id, signer_id_len) != 1
|| x509_sign_update(&sign_ctx, tbs, *out - tbs) != 1
|| x509_sign_finish(&sign_ctx, sig, &siglen) != 1) {
gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx));
error_print();
return -1;
@@ -208,7 +218,7 @@ int x509_req_sign_to_der(
int x509_req_verify(const uint8_t *a, size_t alen, const char *signer_id, size_t signer_id_len)
{
SM2_KEY public_key;
X509_KEY public_key;
if (x509_req_get_details(a, alen,
NULL, NULL, NULL, &public_key, NULL, NULL, NULL, NULL, NULL) != 1) {
@@ -225,7 +235,7 @@ int x509_req_verify(const uint8_t *a, size_t alen, const char *signer_id, size_t
int x509_req_get_details(const uint8_t *a, size_t alen,
int *version,
const uint8_t **subject, size_t *subject_len,
SM2_KEY *subject_public_key,
X509_KEY *subject_public_key,
const uint8_t **attributes, size_t *attributes_len,
int *signature_algor,
const uint8_t **signature, size_t *signature_len)
@@ -233,7 +243,7 @@ int x509_req_get_details(const uint8_t *a, size_t alen,
int ver;
const uint8_t *subj;
size_t subj_len;
SM2_KEY pub_key;
X509_KEY pub_key;
const uint8_t *attrs;
size_t attrs_len;
int sig_alg;