From 8a0a23f91d518dca68817724029440a2fb233f2a Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Thu, 9 Feb 2023 11:44:27 +0800 Subject: [PATCH] Add SM2 AlgorithmIdentifier option Add option in CMake to support NULL parameters encoding --- CMakeLists.txt | 11 +++++++++++ include/gmssl/error.h | 3 +++ include/gmssl/sm2.h | 29 ++++++++++++++--------------- src/sm2_alg.c | 2 -- src/sm2_recover.c | 7 +++++++ src/x509_alg.c | 38 +++++++++++++++++++++++++++++--------- 6 files changed, 64 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f7d1bad4..7c6332bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,14 +187,25 @@ set(demos demo_zuc ) +# when an option has been enabled, `cmake ..` will not refresh the value +# use `cmake .. -DENABLE_XXX=OFF` to disable the option + +option(ENABLE_SM2_ALGOR_ID_ENCODE_NULL "Enable AlgorithmIdenifier with algorithm sm2sign_with_sm3 encode a NULL object as parameters" OFF) +if (ENABLE_SM2_ALGOR_ID_ENCODE_NULL) + message(STATUS "ENABLE_SM2_ALGOR_ID_ENCODE_NULL") + add_definitions(-DSM2_ALGOR_ID_ENCODE_NULL) +endif() + option(ENABLE_PRIVATE_KEY_EXPORT "Enable export un-encrypted private key" OFF) if (ENABLE_PRIVATE_KEY_EXPORT) + message(STATUS "ENABLE_PRIVATE_KEY_EXPORT") add_definitions(-DENABLE_PRIVATE_KEY_EXPORT) list(APPEND demos demo_sm2_key_export) endif() option(ENABLE_TLS_DEBUG "Enable TLS and TLCP print debug message" OFF) if (ENABLE_TLS_DEBUG) + message(STATUS "ENABLE_TLS_DEBUG") add_definitions(-DTLS_DEBUG) endif() diff --git a/include/gmssl/error.h b/include/gmssl/error.h index c9dc3399..a5902eff 100644 --- a/include/gmssl/error.h +++ b/include/gmssl/error.h @@ -32,6 +32,9 @@ extern "C" { #define DEBUG 1 +#define warning_print() \ + do { if (DEBUG) fprintf(stderr, "%s:%d:%s():\n",__FILE__, __LINE__, __func__); } while (0) + #define error_print() \ do { if (DEBUG) fprintf(stderr, "%s:%d:%s():\n",__FILE__, __LINE__, __func__); } while (0) diff --git a/include/gmssl/sm2.h b/include/gmssl/sm2.h index 7dd75e69..58bc4b66 100644 --- a/include/gmssl/sm2.h +++ b/include/gmssl/sm2.h @@ -135,7 +135,7 @@ typedef struct { } SM2_JACOBIAN_POINT; void sm2_jacobian_point_init(SM2_JACOBIAN_POINT *R); -void sm2_jacobian_point_set_xy(SM2_JACOBIAN_POINT *R, const SM2_BN x, const SM2_BN y); // 应该返回错误 +void sm2_jacobian_point_set_xy(SM2_JACOBIAN_POINT *R, const SM2_BN x, const SM2_BN y); void sm2_jacobian_point_get_xy(const SM2_JACOBIAN_POINT *P, SM2_BN x, SM2_BN y); void sm2_jacobian_point_neg(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P); void sm2_jacobian_point_dbl(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P); @@ -145,17 +145,18 @@ void sm2_jacobian_point_mul(SM2_JACOBIAN_POINT *R, const SM2_BN k, const SM2_JAC void sm2_jacobian_point_to_bytes(const SM2_JACOBIAN_POINT *P, uint8_t out[64]); void sm2_jacobian_point_from_bytes(SM2_JACOBIAN_POINT *P, const uint8_t in[64]); void sm2_jacobian_point_mul_generator(SM2_JACOBIAN_POINT *R, const SM2_BN k); -void sm2_jacobian_point_mul_sum(SM2_JACOBIAN_POINT *R, const SM2_BN t, const SM2_JACOBIAN_POINT *P, const SM2_BN s); // 应该返回错误 -void sm2_jacobian_point_from_hex(SM2_JACOBIAN_POINT *P, const char hex[64 * 2]); // 应该返回错误 +void sm2_jacobian_point_mul_sum(SM2_JACOBIAN_POINT *R, const SM2_BN t, const SM2_JACOBIAN_POINT *P, const SM2_BN s); +void sm2_jacobian_point_from_hex(SM2_JACOBIAN_POINT *P, const char hex[64 * 2]); // for testing only int sm2_jacobian_point_is_at_infinity(const SM2_JACOBIAN_POINT *P); int sm2_jacobian_point_is_on_curve(const SM2_JACOBIAN_POINT *P); -int sm2_jacobian_point_equ_hex(const SM2_JACOBIAN_POINT *P, const char hex[128]); +int sm2_jacobian_point_equ_hex(const SM2_JACOBIAN_POINT *P, const char hex[128]); // for testing only int sm2_jacobian_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_JACOBIAN_POINT *P); #define sm2_jacobian_point_set_infinity(R) sm2_jacobian_point_init(R) #define sm2_jacobian_point_copy(R, P) memcpy((R), (P), sizeof(SM2_JACOBIAN_POINT)) +typedef uint8_t sm2_bn_t[32]; typedef struct { uint8_t x[32]; @@ -166,7 +167,6 @@ void sm2_point_to_compressed_octets(const SM2_POINT *P, uint8_t out[33]); void sm2_point_to_uncompressed_octets(const SM2_POINT *P, uint8_t out[65]); int sm2_point_from_octets(SM2_POINT *P, const uint8_t *in, size_t inlen); - int sm2_point_from_x(SM2_POINT *P, const uint8_t x[32], int y); int sm2_point_from_xy(SM2_POINT *P, const uint8_t x[32], const uint8_t y[32]); int sm2_point_is_on_curve(const SM2_POINT *P); @@ -196,14 +196,14 @@ typedef struct { int sm2_key_generate(SM2_KEY *key); -int sm2_key_set_private_key(SM2_KEY *key, const uint8_t private_key[32]); // 自动生成公钥 -int sm2_key_set_public_key(SM2_KEY *key, const SM2_POINT *public_key); // 自动清空私钥,不要和set_private_key同时用 +int sm2_key_set_private_key(SM2_KEY *key, const uint8_t private_key[32]); // key->public_key will be replaced +int sm2_key_set_public_key(SM2_KEY *key, const SM2_POINT *public_key); // key->private_key will be cleared // FIXME: support octets as input? int sm2_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *key); int sm2_public_key_equ(const SM2_KEY *sm2_key, const SM2_KEY *pub_key); -//int sm2_public_key_copy(SM2_KEY *sm2_key, const SM2_KEY *pub_key); // 这个函数的逻辑不清楚 +//int sm2_public_key_copy(SM2_KEY *sm2_key, const SM2_KEY *pub_key); // do we need this? int sm2_public_key_digest(const SM2_KEY *key, uint8_t dgst[32]); -int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *pub_key); // 和private_key_print参数不一致 +int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *pub_key); /* from RFC 5915 @@ -237,7 +237,7 @@ int sm2_public_key_algor_to_der(uint8_t **out, size_t *outlen); int sm2_public_key_algor_from_der(const uint8_t **in, size_t *inlen); /* -X.509 SubjectPublicKeyInfo from RFC 5280 +SubjectPublicKeyInfo from RFC 5280 SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, @@ -261,10 +261,12 @@ enum { PKCS8_private_key_info_version = 0, }; + int sm2_private_key_info_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen); int sm2_private_key_info_from_der(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, const uint8_t **in, size_t *inlen); int sm2_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp); +// FIXME: #define default buffer size for sm2_private_key_info_from_pem int sm2_private_key_info_from_pem(SM2_KEY *key, FILE *fp); /* @@ -277,6 +279,7 @@ int sm2_private_key_info_encrypt_to_der(const SM2_KEY *key, int sm2_private_key_info_decrypt_from_der(SM2_KEY *key, const uint8_t **attrs, size_t *attrs_len, const char *pass, const uint8_t **in, size_t *inlen); int sm2_private_key_info_encrypt_to_pem(const SM2_KEY *key, const char *pass, FILE *fp); +// FIXME: #define default buffer size int sm2_private_key_info_decrypt_from_pem(SM2_KEY *key, const char *pass, FILE *fp); @@ -285,7 +288,6 @@ typedef struct { uint8_t s[32]; } SM2_SIGNATURE; -int sm2_do_sign_ex(const SM2_KEY *key, int flags, const uint8_t dgst[32], SM2_SIGNATURE *sig); int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig); int sm2_do_sign_fast(const SM2_Fn d, const uint8_t dgst[32], SM2_SIGNATURE *sig); int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig); @@ -349,7 +351,7 @@ typedef struct { int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out); int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, size_t *outlen); -#define SM2_MIN_CIPHERTEXT_SIZE 45 // dependes on SM2_MIN_PLAINTEXT_SIZE +#define SM2_MIN_CIPHERTEXT_SIZE 45 // depends on SM2_MIN_PLAINTEXT_SIZE #define SM2_MAX_CIPHERTEXT_SIZE 366 // depends on SM2_MAX_PLAINTEXT_SIZE int sm2_ciphertext_to_der(const SM2_CIPHERTEXT *c, uint8_t **out, size_t *outlen); int sm2_ciphertext_from_der(SM2_CIPHERTEXT *c, const uint8_t **in, size_t *inlen); @@ -370,9 +372,6 @@ int sm2_do_ecdh(const SM2_KEY *key, const SM2_POINT *peer_public, SM2_POINT *out int sm2_ecdh(const SM2_KEY *key, const uint8_t *peer_public, size_t peer_public_len, SM2_POINT *out); -typedef uint8_t sm2_bn_t[32]; - - #ifdef __cplusplus } #endif diff --git a/src/sm2_alg.c b/src/sm2_alg.c index 49cb75e3..8364a8ab 100644 --- a/src/sm2_alg.c +++ b/src/sm2_alg.c @@ -1081,8 +1081,6 @@ int sm2_jacobian_point_equ_hex(const SM2_JACOBIAN_POINT *P, const char hex[128]) return (sm2_bn_cmp(x, T->X) == 0) && (sm2_bn_cmp(y, T->Y) == 0); } - - int sm2_point_is_on_curve(const SM2_POINT *P) { SM2_JACOBIAN_POINT T; diff --git a/src/sm2_recover.c b/src/sm2_recover.c index e550ce47..291498da 100644 --- a/src/sm2_recover.c +++ b/src/sm2_recover.c @@ -40,6 +40,7 @@ int sm2_signature_to_public_key_points(const SM2_SIGNATURE *sig, const uint8_t d SM2_Fp x1; SM2_Fp y1; + // FIXME: check r, s sm2_bn_from_bytes(r, sig->r); sm2_bn_from_bytes(s, sig->s); @@ -120,6 +121,7 @@ int sm2_signature_conjugate(const SM2_SIGNATURE *sig, SM2_SIGNATURE *new_sig) SM2_Fn r; SM2_Fn s; + // FIXME: check r,s sm2_bn_from_bytes(r, sig->r); sm2_bn_from_bytes(s, sig->s); sm2_fn_neg(r, r); @@ -129,3 +131,8 @@ int sm2_signature_conjugate(const SM2_SIGNATURE *sig, SM2_SIGNATURE *new_sig) return 1; } + +// TODO: Add API to support sig,siglen + + + diff --git a/src/x509_alg.c b/src/x509_alg.c index ff5ae648..2cb217ab 100644 --- a/src/x509_alg.c +++ b/src/x509_alg.c @@ -279,6 +279,17 @@ from RFC 3447 Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 } sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 } +from RFC 3279 Algorithms and Identifiers for the + Internet X.509 Public Key Infrastructure + Certificate and Certificate Revocation List (CRL) Profile + + 2.2.3 ECDSA Signature Algorithm + + When the ecdsa-with-SHA1 algorithm identifier appears as the + algorithm field in an AlgorithmIdentifier, the encoding MUST omit the + parameters field. That is, the AlgorithmIdentifier SHALL be a + SEQUENCE of one component: the OBJECT IDENTIFIER ecdsa-with-SHA1. + from RFC 5754 Using SHA2 Algorithms with Cryptographic Message Syntax @@ -313,16 +324,23 @@ from RFC 5758 Internet X.509 Public Key Infrastructure: SHA384, or ecdsa-with-SHA512. */ + +#ifdef SM2_ALGOR_ID_ENCODE_NULL // from CMakeLists.txt +#define SM2_SIGN_ALGOR_FLAGS 1 +#else +#define SM2_SIGN_ALGOR_FLAGS 0 +#endif + static const ASN1_OID_INFO x509_sign_algors[] = { - { OID_sm2sign_with_sm3, "sm2sign-with-sm3", oid_sm2sign_with_sm3, sizeof(oid_sm2sign_with_sm3)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, + { OID_sm2sign_with_sm3, "sm2sign-with-sm3", oid_sm2sign_with_sm3, sizeof(oid_sm2sign_with_sm3)/sizeof(int), SM2_SIGN_ALGOR_FLAGS }, { OID_rsasign_with_sm3, "rsasign-with-sm3", oid_rsasign_with_sm3, sizeof(oid_rsasign_with_sm3)/sizeof(int), 1 }, - { OID_ecdsa_with_sha1, "ecdsa-with-sha1", oid_ecdsa_with_sha1, sizeof(oid_ecdsa_with_sha1)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, - { OID_ecdsa_with_sha224, "ecdsa-with-sha224", oid_ecdsa_with_sha224, sizeof(oid_ecdsa_with_sha224)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM } , - { OID_ecdsa_with_sha256, "ecdsa-with-sha256", oid_ecdsa_with_sha256, sizeof(oid_ecdsa_with_sha256)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, - { OID_ecdsa_with_sha384, "ecdsa-with-sha384", oid_ecdsa_with_sha384, sizeof(oid_ecdsa_with_sha384)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, - { OID_ecdsa_with_sha512, "ecdsa-with-sha512", oid_ecdsa_with_sha512, sizeof(oid_ecdsa_with_sha512)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, - { OID_rsasign_with_md5, "md5WithRSAEncryption", oid_rsasign_with_md5, sizeof(oid_rsasign_with_md5)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, - { OID_rsasign_with_sha1, "sha1WithRSAEncryption", oid_rsasign_with_sha1, sizeof(oid_rsasign_with_sha1)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, + { OID_ecdsa_with_sha1, "ecdsa-with-sha1", oid_ecdsa_with_sha1, sizeof(oid_ecdsa_with_sha1)/sizeof(int), 0 }, + { OID_ecdsa_with_sha224, "ecdsa-with-sha224", oid_ecdsa_with_sha224, sizeof(oid_ecdsa_with_sha224)/sizeof(int), 0 } , + { OID_ecdsa_with_sha256, "ecdsa-with-sha256", oid_ecdsa_with_sha256, sizeof(oid_ecdsa_with_sha256)/sizeof(int), 0 }, + { OID_ecdsa_with_sha384, "ecdsa-with-sha384", oid_ecdsa_with_sha384, sizeof(oid_ecdsa_with_sha384)/sizeof(int), 0 }, + { OID_ecdsa_with_sha512, "ecdsa-with-sha512", oid_ecdsa_with_sha512, sizeof(oid_ecdsa_with_sha512)/sizeof(int), 0 }, + { OID_rsasign_with_md5, "md5WithRSAEncryption", oid_rsasign_with_md5, sizeof(oid_rsasign_with_md5)/sizeof(int), 0 }, + { OID_rsasign_with_sha1, "sha1WithRSAEncryption", oid_rsasign_with_sha1, sizeof(oid_rsasign_with_sha1)/sizeof(int), 0 }, { OID_rsasign_with_sha224, "sha224WithRSAEncryption", oid_rsasign_with_sha224, sizeof(oid_rsasign_with_sha224)/sizeof(int), 1 }, { 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 }, @@ -388,11 +406,13 @@ int x509_signature_algor_from_der(int *oid, const uint8_t **in, size_t *inlen) return -1; } if (len) { + if (info->flags == 0) { + warning_print(); + } if (asn1_null_from_der(&p, &len) < 0) { error_print(); return -1; } - // FIXME: check info->flags if (len) { error_print(); return -1;