From ea4cc6585c9bd8dbf3b09fa2d5f5030ac63c8fae Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Wed, 16 Mar 2022 15:12:29 +0800 Subject: [PATCH] Update tests and tools --- CMakeLists.txt | 39 +- include/gmssl/asn1.h | 10 +- include/gmssl/oid.h | 29 +- include/gmssl/pkcs8.h | 73 ++- include/gmssl/sm2.h | 13 +- include/gmssl/x509.h | 15 +- include/gmssl/x509_ext.h | 4 +- include/gmssl/x509_req.h | 2 +- src/asn1.c | 190 +++--- src/cms.c | 2 +- src/debug.c | 2 +- src/pem.c | 15 +- src/pkcs8.c | 582 ++++++++--------- src/sm2_asn1.c | 377 +++++++---- src/sm2_prn.c | 31 +- src/x509_cer.c | 144 +++-- src/x509_crl.c | 20 +- src/x509_ext.c | 34 +- src/x509_oid.c | 150 +++-- src/x509_prn.c | 511 --------------- src/x509_req.c | 4 +- src/x509_str.c | 1 + tests/aestest.c | 159 ++--- tests/asn1test.c | 690 +++++++++++---------- tests/base64test.c | 32 +- tests/chacha20test.c | 12 +- tests/cmstest.c | 567 +---------------- tests/gcmtest.c | 9 +- tests/gf128test.c | 4 - tests/oidtest.c | 62 -- tests/pbkdf2test.c | 34 +- tests/pkcs8test.c | 383 ++++++++---- tests/sm2asn1test.c | 180 ------ tests/sm2test.c | 136 +++- tests/sm3test.c | 2 +- tests/sm4test.c | 79 ++- tests/{x509_algortest.c => x509_algtest.c} | 164 +++-- tests/x509_crltest.c | 186 ++++++ tests/x509_exttest.c | 334 ++++++++++ tests/x509_oidtest.c | 322 ++++++++++ tests/x509_reqtest.c | 253 ++++++++ tests/{sm4cbctest.c => x509_strtest.c} | 94 +-- tests/x509test.c | 531 +++++++++------- tests/zuctest.c | 3 +- tools/certgen.c | 146 ++--- tools/certparse.c | 2 +- tools/certverify.c | 93 +-- tools/reqgen.c | 71 +-- tools/reqparse.c | 14 +- tools/sm2decrypt.c | 2 +- tools/sm2keygen.c | 2 +- tools/sm2sign.c | 2 +- 52 files changed, 3600 insertions(+), 3216 deletions(-) delete mode 100644 src/x509_prn.c delete mode 100644 tests/oidtest.c delete mode 100644 tests/sm2asn1test.c rename tests/{x509_algortest.c => x509_algtest.c} (64%) create mode 100644 tests/x509_crltest.c create mode 100644 tests/x509_exttest.c create mode 100644 tests/x509_oidtest.c create mode 100644 tests/x509_reqtest.c rename tests/{sm4cbctest.c => x509_strtest.c} (59%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ad936da..56be0371 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,17 +107,17 @@ target_link_libraries (sm3 LINK_PUBLIC gmssl) add_executable (sm3hmac tools/sm3hmac.c) target_link_libraries (sm3hmac LINK_PUBLIC gmssl) -#add_executable (reqgen tools/reqgen.c) -#target_link_libraries (reqgen LINK_PUBLIC gmssl) -#add_executable (reqparse tools/reqparse.c) -#target_link_libraries (reqparse LINK_PUBLIC gmssl) +add_executable (reqgen tools/reqgen.c) +target_link_libraries (reqgen LINK_PUBLIC gmssl) +add_executable (reqparse tools/reqparse.c) +target_link_libraries (reqparse LINK_PUBLIC gmssl) -#add_executable (certgen tools/certgen.c) -#target_link_libraries (certgen LINK_PUBLIC gmssl) +add_executable (certgen tools/certgen.c) +target_link_libraries (certgen LINK_PUBLIC gmssl) add_executable (certparse tools/certparse.c) target_link_libraries (certparse LINK_PUBLIC gmssl) -#add_executable (certverify tools/certverify.c) -#target_link_libraries (certverify LINK_PUBLIC gmssl) +add_executable (certverify tools/certverify.c) +target_link_libraries (certverify LINK_PUBLIC gmssl) #add_executable (tlcp_client tools/tlcp_client.c) #target_link_libraries (tlcp_client LINK_PUBLIC gmssl) @@ -221,11 +221,20 @@ target_link_libraries (sm3test LINK_PUBLIC gmssl) add_executable(sm4test tests/sm4test.c) target_link_libraries (sm4test LINK_PUBLIC gmssl) -add_executable(sm4cbctest tests/sm4cbctest.c) -target_link_libraries (sm4cbctest LINK_PUBLIC gmssl) - add_executable(x509test tests/x509test.c) target_link_libraries (x509test LINK_PUBLIC gmssl) +add_executable(x509_oidtest tests/x509_oidtest.c) +target_link_libraries (x509_oidtest LINK_PUBLIC gmssl) +add_executable(x509_algtest tests/x509_algtest.c) +target_link_libraries (x509_algtest LINK_PUBLIC gmssl) +add_executable(x509_strtest tests/x509_strtest.c) +target_link_libraries (x509_strtest LINK_PUBLIC gmssl) +add_executable(x509_reqtest tests/x509_reqtest.c) +target_link_libraries (x509_reqtest LINK_PUBLIC gmssl) +add_executable(x509_crltest tests/x509_crltest.c) +target_link_libraries (x509_crltest LINK_PUBLIC gmssl) +add_executable(x509_exttest tests/x509_exttest.c) +target_link_libraries (x509_exttest LINK_PUBLIC gmssl) add_executable(zuctest tests/zuctest.c) target_link_libraries (zuctest LINK_PUBLIC gmssl) @@ -256,13 +265,17 @@ add_test(NAME sha224 COMMAND sha224test) add_test(NAME sha256 COMMAND sha256test) add_test(NAME sha384 COMMAND sha384test) add_test(NAME sha512 COMMAND sha512test) -add_test(NAME sm2asn1 COMMAND sm2asn1test) add_test(NAME sm2 COMMAND sm2test) add_test(NAME sm3 COMMAND sm3test) -add_test(NAME sm4cbc COMMAND sm4cbctest) add_test(NAME sm4 COMMAND sm4test) #add_test(NAME tls COMMAND tlstest) add_test(NAME x509 COMMAND x509test) +add_test(NAME x509_oid COMMAND x509_oidtest) +add_test(NAME x509_alg COMMAND x509_algtest) +add_test(NAME x509_str COMMAND x509_strtest) +add_test(NAME x509_req COMMAND x509_reqtest) +add_test(NAME x509_crl COMMAND x509_crltest) +add_test(NAME x509_ext COMMAND x509_exttest) add_test(NAME zuc COMMAND zuctest) diff --git a/include/gmssl/asn1.h b/include/gmssl/asn1.h index 1aa12f3f..17a17885 100644 --- a/include/gmssl/asn1.h +++ b/include/gmssl/asn1.h @@ -72,6 +72,9 @@ extern "C" { #define ASN1_TAG_EXPLICIT(index) ASN1_TAG_IMPLICIT(ASN1_TAG_CONSTRUCTED|(index)) +#define ASN1_FMT_FULL 0x01 + + enum ASN1_TAG { ASN1_TAG_BOOLEAN = 1, ASN1_TAG_INTEGER = 2, @@ -229,6 +232,9 @@ int asn1_ia5_string_from_der_ex(int tag, const char **d, size_t *dlen, const uin int asn1_string_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen); +#define ASN1_UTC_TIME_LEN (sizeof("YYMMDDHHMMSSZ")-1) +#define ASN1_GENERALIZED_TIME_LEN (sizeof("YYYYMMDDHHMMSSZ")-1) + int asn1_utc_time_to_der_ex(int tag, time_t tv, uint8_t **out, size_t *outlen); int asn1_utc_time_from_der_ex(int tag, time_t *tv, const uint8_t **in, size_t *inlen); #define asn1_utc_time_to_der(tv,out,outlen) asn1_utc_time_to_der_ex(ASN1_TAG_UTCTime,tv,out,outlen) @@ -253,8 +259,8 @@ int asn1_generalized_time_from_der_ex(int tag, time_t *tv, const uint8_t **in, s #define asn1_implicit_set_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen) #define asn1_implicit_set_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen) -#define asn1_implicit_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen) -#define asn1_implicit_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen) +#define asn1_implicit_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen) +#define asn1_implicit_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen) int asn1_header_to_der(int tag, size_t dlen, uint8_t **out, size_t *outlen); #define asn1_implicit_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen) diff --git a/include/gmssl/oid.h b/include/gmssl/oid.h index 476b8948..85963858 100644 --- a/include/gmssl/oid.h +++ b/include/gmssl/oid.h @@ -155,10 +155,19 @@ enum { OID_sha512_224, OID_sha512_256, + + OID_hmac_sha1, + OID_hmac_sha224, + OID_hmac_sha256, + OID_hmac_sha384, + OID_hmac_sha512, + OID_hmac_sha512_224, + OID_hmac_sha512_256, + OID_pbkdf2, // {pkcs-5 12} OID_pbes2, // {pkcs-5 13} - OID_hmacWithSHA1, - OID_hmacWithSHA224, + + OID_sm4_ecb, // 1 2 156 10197 1 104 1 OID_sm4_cbc, // 1 2 156 10197 1 104 2 @@ -209,8 +218,24 @@ enum { #define oid_ce 2,5,29 +#define oid_sm 1,2,156,10197 +#define oid_sm_algors oid_sm,1 + + #define oid_sm2_cms 1,2,156,10197,6,1,4,2 +/* +rsadsi OBJECT IDENTIFIER ::= {iso(1) member-body(2) us(840) 113549} +pkcs OBJECT IDENTIFIER ::= {rsadsi 1} +pkcs-5 OBJECT IDENTIFIER ::= {pkcs 5} +id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12} +id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} +*/ + +#define oid_rsadsi 1,2,840,113549 +#define oid_pkcs oid_rsadsi,1 +#define oid_pkcs5 oid_pkcs,5 + #ifdef __cplusplus } diff --git a/include/gmssl/pkcs8.h b/include/gmssl/pkcs8.h index 167bae3b..fd1becd7 100644 --- a/include/gmssl/pkcs8.h +++ b/include/gmssl/pkcs8.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -63,22 +63,27 @@ extern "C" { #endif -// EncryptedPrivateKeyInfo -int sm2_enced_private_key_info_to_der(const SM2_KEY *key, - const char *pass, uint8_t **out, size_t *outlen); -int sm2_enced_private_key_info_from_der(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, - const char *pass, const uint8_t **in, size_t *inlen); -int sm2_enced_private_key_info_to_pem(const SM2_KEY *key, const char *pass, FILE *fp); -int sm2_enced_private_key_info_from_pem(SM2_KEY *key, const char *pass, FILE *fp); - /* - prf must be OID_hmac_sm3 - cipher must be OID_sm4_cbc +id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12} + +PBKDF2-params ::= SEQUENCE { + salt CHOICE { + specified OCTET STRING, + otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}} + }, + iterationCount INTEGER (1..MAX), + keyLength INTEGER (1..MAX) OPTIONAL, -- 这个参数可以由函数指定 + prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 +} + +prf must be OID_hmac_sm3 +cipher must be OID_sm4_cbc */ int pbkdf2_params_to_der(const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf, uint8_t **out, size_t *outlen); int pbkdf2_params_from_der(const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf, const uint8_t **in, size_t *inlen); +int pbkdf2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); int pbkdf2_algor_to_der( const uint8_t *salt, size_t saltlen, @@ -92,6 +97,23 @@ int pbkdf2_algor_from_der( int *keylen, int *prf, const uint8_t **in, size_t *inlen); +int pbkdf2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + +/* +id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} + +PBES2-params ::= SEQUENCE { + keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, -- id-PBKDF2 + encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}} + +PBES2-Encs: + AES-CBC-Pad [RFC2898] + RC5-CBC-Pad + DES-CBC-Pad legacy + DES-EDE3-CBC-Pad legacy + RC2-CBC-Pad legacy +*/ int pbes2_enc_algor_to_der( int cipher, @@ -101,10 +123,13 @@ int pbes2_enc_algor_from_der( int *cipher, const uint8_t **iv, size_t *ivlen, const uint8_t **in, size_t *inlen); +int pbes2_enc_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + int pbes2_params_to_der( const uint8_t *salt, size_t saltlen, int iter, + int keylen, int prf, int cipher, const uint8_t *iv, size_t ivlen, @@ -112,14 +137,18 @@ int pbes2_params_to_der( int pbes2_params_from_der( const uint8_t **salt, size_t *saltlen, int *iter, + int *keylen, int *prf, int *cipher, const uint8_t **iv, size_t *ivlen, const uint8_t **in, size_t *inlen); +int pbes2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + int pbes2_algor_to_der( const uint8_t *salt, size_t saltlen, int iter, + int keylen, int prf, int cipher, const uint8_t *iv, size_t ivlen, @@ -127,14 +156,34 @@ int pbes2_algor_to_der( int pbes2_algor_from_der( const uint8_t **salt, size_t *saltlen, int *iter, + int *keylen, int *prf, int *cipher, const uint8_t **iv, size_t *ivlen, const uint8_t **in, size_t *inlen); +int pbes2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +from [RFC 5208] + +EncryptedPrivateKeyInfo ::= SEQUENCE { + encryptionAlgorithm EncryptionAlgorithmIdentifier, + encryptedData OCTET STRING } + +encryptionAlgorithm: + id-PBES2 + +PrivateKeyInfo ::= SEQUENCE { + version INTEGER { v1(0) }, + privateKeyAlgorithm AlgorithmIdentifier, + privateKey OCTET STRING, + attributes [0] Attributes OPTIONAL } +*/ int pkcs8_enced_private_key_info_to_der( const uint8_t *salt, size_t saltlen, int iter, + int keylen, int prf, int cipher, const uint8_t *iv, size_t ivlen, @@ -143,11 +192,13 @@ int pkcs8_enced_private_key_info_to_der( int pkcs8_enced_private_key_info_from_der( const uint8_t **salt, size_t *saltlen, int *iter, + int *keylen, int *prf, int *cipher, const uint8_t **iv, size_t *ivlen, const uint8_t **enced, size_t *encedlen, const uint8_t **in, size_t *inlen); +int pkcs8_enced_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); #ifdef __cplusplus diff --git a/include/gmssl/sm2.h b/include/gmssl/sm2.h index cd14c192..92a8859d 100644 --- a/include/gmssl/sm2.h +++ b/include/gmssl/sm2.h @@ -120,7 +120,6 @@ AlgorithmIdentifier ::= { 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 @@ -147,6 +146,18 @@ int sm2_private_key_info_from_der(SM2_KEY *key, const uint8_t **attrs, size_t *a int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp); int sm2_private_key_info_from_pem(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, FILE *fp); +/* +EncryptedPrivateKeyInfo ::= SEQUENCE { + encryptionAlgorithm EncryptionAlgorithmIdentifier, -- id-PBES2 + encryptedData OCTET STRING } +*/ +int sm2_private_key_info_encrypt_to_der(const SM2_KEY *key, + const char *pass, uint8_t **out, size_t *outlen); +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); +int sm2_private_key_info_decrypt_from_pem(SM2_KEY *key, const char *pass, FILE *fp); + typedef struct { uint8_t r[32]; diff --git a/include/gmssl/x509.h b/include/gmssl/x509.h index 3215b9b2..20340089 100644 --- a/include/gmssl/x509.h +++ b/include/gmssl/x509.h @@ -150,6 +150,10 @@ int x509_name_add_organizational_unit_name(uint8_t *d, size_t *dlen, int maxlen, int x509_name_add_common_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen); int x509_name_add_domain_component(uint8_t *d, size_t *dlen, int maxlen, const char *val, size_t vlen); // val: IA5String +int x509_name_set(uint8_t *d, size_t *dlen, size_t maxlen, + const char *country, const char *state, const char *locality, + const char *org, const char *org_unit, const char *common_name); + int x509_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); int x509_name_get_printable(const uint8_t *d, size_t dlen, char *str, size_t maxlen); int x509_name_get_value_by_type(const uint8_t *d, size_t dlen, int oid, int *tag, const uint8_t **val, size_t *vlen); @@ -269,9 +273,12 @@ int x509_cert_sign( 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); -int x509_cert_verify(const uint8_t *a, size_t alen, const SM2_KEY *pub_key, const char *signer_id, size_t signer_id_len); -int x509_cert_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen); + const SM2_KEY *sign_key, + const char *signer_id, size_t signer_id_len); +int x509_cert_verify(const uint8_t *a, size_t alen, const SM2_KEY *pub_key, + const char *signer_id, size_t signer_id_len); +int x509_cert_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen, + const char *signer_id, size_t signer_id_len); int x509_cert_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen); int x509_cert_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen); @@ -279,7 +286,7 @@ int x509_cert_to_pem(const uint8_t *a, size_t alen, FILE *fp); int x509_cert_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp); int x509_cert_from_pem_by_index(uint8_t *a, size_t *alen, size_t maxlen, int index, FILE *fp); int x509_cert_from_pem_by_subject(uint8_t *a, size_t *alen, size_t maxlen, const uint8_t *name, size_t namelen, FILE *fp); -int x509_cert_print(FILE *fp, int fmt, int ind, const uint8_t *a, size_t alen); +int x509_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen); int x509_cert_get_details(const uint8_t *a, size_t alen, int *version, diff --git a/include/gmssl/x509_ext.h b/include/gmssl/x509_ext.h index 3078e88d..9d29d08e 100644 --- a/include/gmssl/x509_ext.h +++ b/include/gmssl/x509_ext.h @@ -459,8 +459,8 @@ ReasonFlags ::= BIT STRING { #define X509_RF_PRIVILEGE_WITHDRAWN (1 << 7) #define X509_RF_AA_COMPROMISE (1 << 8) -int x509_revoke_reasons_to_der(int bits, uint8_t **out, size_t *outlen); -int x509_revoke_reasons_from_der(int *bits, const uint8_t **in, size_t *inlen); +#define x509_revoke_reasons_to_der(bits,out,outlen) asn1_bits_to_der(bits,out,outlen) +#define x509_revoke_reasons_from_der(bits,in,inlen) asn1_bits_from_der(bits,in,inlen) int x509_revoke_reasons_print(FILE *fp, int fmt, int ind, const char *label, int bits); /* diff --git a/include/gmssl/x509_req.h b/include/gmssl/x509_req.h index cb0ac24c..1a408e6c 100644 --- a/include/gmssl/x509_req.h +++ b/include/gmssl/x509_req.h @@ -121,7 +121,7 @@ int x509_req_get_details(const uint8_t *req, size_t reqlen, const uint8_t **attributes, size_t *attributes_len, int *signature_algor, const uint8_t **signature, size_t *signature_len); -int x509_req_print(FILE *fp, int fmt, int ind, const uint8_t *req, size_t reqlen); +int x509_req_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *req, size_t reqlen); int x509_req_to_pem(const uint8_t *req, size_t reqlen, FILE *fp); int x509_req_from_pem(uint8_t *req, size_t *reqlen, size_t maxlen, FILE *fp); diff --git a/src/asn1.c b/src/asn1.c index 256d483f..e02045cb 100644 --- a/src/asn1.c +++ b/src/asn1.c @@ -59,9 +59,6 @@ #include "endian.h" -//FIXME: ENUMERATED 没有支持,在CRLReason中用到 - - /* ## 返回值 @@ -113,7 +110,10 @@ const char *asn1_tag_name(int tag) case ASN1_TAG_EXTERNAL: return "EXTERNAL"; case ASN1_TAG_REAL: return "REAL"; case ASN1_TAG_ENUMERATED: return "ENUMERATED"; + case ASN1_TAG_EMBEDDED: return "EMBEDDED"; case ASN1_TAG_UTF8String: return "UTF8String"; + case ASN1_TAG_RELATIVE_OID: return "RELATIVE_OID"; + case ASN1_TAG_NumericString: return "NumericString"; case ASN1_TAG_PrintableString: return "PrintableString"; case ASN1_TAG_TeletexString: return "TeletexString"; case ASN1_TAG_VideotexString: return "VideotexString"; @@ -128,6 +128,7 @@ const char *asn1_tag_name(int tag) case ASN1_TAG_BMPString: return "BMPString"; case ASN1_TAG_SEQUENCE: return "SEQUENCE"; case ASN1_TAG_SET: return "SET"; + case ASN1_TAG_EXPLICIT: return "EXPLICIT"; } error_print(); @@ -221,11 +222,9 @@ int asn1_data_to_der(const uint8_t *data, size_t datalen, uint8_t **out, size_t int asn1_tag_from_der(int tag, const uint8_t **in, size_t *inlen) { if (*inlen == 0) { - //error_print_msg("inlen = %zu\n", *inlen); return 0; } if (**in != tag) { - //error_print_msg("tag get %d instead of %d\n", **in, tag); return 0; } (*in)++; @@ -276,15 +275,15 @@ int asn1_length_from_der(size_t *plen, const uint8_t **pin, size_t *pinlen) inlen -= nbytes; } - if (inlen < len) { - error_print_msg("inlen = %zu\n", *pinlen); - error_print_msg("length = %zu, left = %zu\n", len, inlen); - return -1; - } - *plen = len; *pin = in; *pinlen = inlen; + + if (inlen < len) { + error_print_msg("inlen = %zu\n", *pinlen); + error_print_msg("length = %zu, left = %zu\n", len, inlen); + return -2; // 特殊错误值用于 test_asn1_length() 的测试 + } return 1; } @@ -476,27 +475,19 @@ int asn1_int_to_der_ex(int tag, int a, uint8_t **out, size_t *outlen) int asn1_bit_string_to_der_ex(int tag, const uint8_t *bits, size_t nbits, uint8_t **out, size_t *outlen) { - int unused = (8 - nbits % 8) % 8; + uint8_t unused = (8 - nbits % 8) % 8; size_t nbytes = (nbits + 7) / 8; - if (!bits || nbits >= INT_MAX || (out && !(*out)) || !outlen) { + if (!bits) { + return 0; + } + if (asn1_tag_to_der(tag, out, outlen) != 1 + || asn1_length_to_der(nbytes + 1, out, outlen) != 1 + || asn1_data_to_der(&unused, 1, out, outlen) != 1 + || asn1_data_to_der(bits, nbytes, out, outlen) != 1) { + error_print(); return -1; } - - if (out) - *(*out)++ = tag; - (*outlen)++; - - asn1_length_to_der(nbytes + 1, out, outlen); - - if (out) { - *(*out)++ = (uint8_t)unused; - memcpy(*out, bits, nbytes); - (*out) += nbytes; - } - *outlen += 1 + nbytes; - - return 1; } @@ -505,22 +496,25 @@ int asn1_bit_octets_to_der_ex(int tag, const uint8_t *octs, size_t nocts, uint8_ return asn1_bit_string_to_der_ex(tag, octs, nocts << 3, out, outlen); } - int asn1_bits_to_der_ex(int tag, int bits, uint8_t **out, size_t *outlen) { size_t nbits = 0; uint8_t buf[4] = {0}; int i = 0; + uint8_t mask = 0x80; if (bits < 0) { return 0; } - while (bits) { - buf[i] = (buf[i] << 1) | (bits & 1); + while (bits > 0) { + if (bits & 1) + buf[i] |= mask; + mask >>= 1; bits >>= 1; nbits++; - if (nbits % 8) { + if (nbits % 8 == 0) { i++; + mask = 0x80; } } if (!nbits) { @@ -643,9 +637,11 @@ int asn1_object_identifier_from_octets(uint32_t *nodes, size_t *nodes_cnt, const while (inlen) { uint32_t val; if (count > 32) { + error_print(); return -1; } if (asn1_oid_node_from_base128(&val, &in, &inlen) < 0) { + error_print(); return -1; } if (nodes) { @@ -706,8 +702,6 @@ const ASN1_OID_INFO *asn1_oid_info_from_oid(const ASN1_OID_INFO *infos, size_t c return NULL; } -// 这个函数可以支持未知的OID,通常只有在print或者解析Extensions时需要调用该函数 -// 注意:函数有特殊返回值 int asn1_oid_info_from_der_ex(const ASN1_OID_INFO **info, uint32_t *nodes, size_t *nodes_cnt, const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen) { @@ -716,6 +710,7 @@ int asn1_oid_info_from_der_ex(const ASN1_OID_INFO **info, uint32_t *nodes, size_ if ((ret = asn1_object_identifier_from_der(nodes, nodes_cnt, in, inlen)) != 1) { if (ret < 0) error_print(); + if (ret == 0) error_print(); return ret; } *info = NULL; @@ -726,7 +721,8 @@ int asn1_oid_info_from_der_ex(const ASN1_OID_INFO **info, uint32_t *nodes, size_ return 1; } } - return 2; // 返回非1的正整数表示OID格式正确但是不在给定列表中 + // 注意,此时虽然返回1,但是*info == NULL,因此调用方应该显式的判断info + return 1; } int asn1_oid_info_from_der(const ASN1_OID_INFO **info, const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen) @@ -777,13 +773,12 @@ int asn1_ia5_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out int asn1_utc_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen) { struct tm tm_val; - char buf[sizeof("YYMMDDHHMMSSZ")]; + char buf[ASN1_UTC_TIME_LEN + 1]; if ((out && !(*out)) || !outlen) { return -1; } - // 注意,这个函数可能在Windows上是没有的! gmtime_r(&a, &tm_val); strftime(buf, sizeof(buf), "%y%m%d%H%M%SZ", &tm_val); @@ -800,10 +795,11 @@ int asn1_utc_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen) return 1; } + int asn1_generalized_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen) { struct tm tm_val; - char buf[sizeof("YYYYMMDDHHMMSSZ")]; + char buf[ASN1_GENERALIZED_TIME_LEN + 1]; if ((out && !(*out)) || !outlen) { error_print(); @@ -812,16 +808,17 @@ int asn1_generalized_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *ou gmtime_r(&a, &tm_val); strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &tm_val); + //printf("%s %d: generalized time : %s\n", __FILE__, __LINE__, buf); if (out) *(*out)++ = tag; (*outlen)++; - asn1_length_to_der(sizeof(buf)-1, out, outlen); + asn1_length_to_der(ASN1_GENERALIZED_TIME_LEN, out, outlen); if (out) { - memcpy(*out, buf, sizeof(buf)-1); - (*out) += sizeof(buf)-1; + memcpy(*out, buf, ASN1_GENERALIZED_TIME_LEN); + (*out) += ASN1_GENERALIZED_TIME_LEN; } - *outlen += sizeof(buf)-1; + *outlen += ASN1_GENERALIZED_TIME_LEN; return 1; } @@ -951,41 +948,45 @@ int asn1_int_from_der_ex(int tag, int *a, const uint8_t **in, size_t *inlen) return 1; } -int asn1_bit_string_from_der_ex(int tag, const uint8_t **bits, size_t *nbits, const uint8_t **pin, size_t *pinlen) +int asn1_bit_string_from_der_ex(int tag, const uint8_t **bits, size_t *nbits, const uint8_t **in, size_t *inlen) { - const uint8_t *in = *pin; - size_t inlen = *pinlen; + int ret; size_t len; int unused_bits; - if (!bits || !nbits || !pin || !(*pin) || !pinlen) { + if ((ret = asn1_tag_from_der(tag, in, inlen)) != 1) { + if (ret < 0) error_print(); + else { + *bits = NULL; + *nbits = 0; + } + return ret; + } + if (asn1_length_from_der(&len, in, inlen) != 1 + || asn1_data_from_der(bits, len, in, inlen) != 1) { + error_print(); + return -1; + } + if (len < 2) { error_print(); return -1; } - // FIXME: 其他函数可能存在类似情况 - *bits = NULL; - *nbits = 0; - if (inlen-- < 1 || *in++ != tag) { - return 0; - } - if (asn1_length_from_der(&len, &in, &inlen) != 1 - || len <= 0) { + unused_bits = **bits; + + if (len < 1) { error_print(); return -1; } - - unused_bits = *in; if (unused_bits > 8 || (len == 1 && unused_bits > 0)) { error_print(); return -1; } - *bits = in + 1; - *nbits = (len - 1) * 8 - unused_bits; - *pin = in + len; - *pinlen = inlen - len; + (*bits)++; + *nbits = (len - 1) << 3; + return 1; } @@ -1051,32 +1052,22 @@ int asn1_null_from_der(const uint8_t **in, size_t *inlen) } int asn1_object_identifier_from_der_ex(int tag, uint32_t *nodes, size_t *nodes_cnt, - const uint8_t **pin, size_t *pinlen) + const uint8_t **in, size_t *inlen) { - const uint8_t *in = *pin; - size_t inlen = *pinlen; + int ret; size_t len; + const uint8_t *p; - if (!nodes || !nodes_cnt || !pin || !(*pin) || !pinlen) { + if ((ret = asn1_tag_from_der(tag, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_length_from_der(&len, in, inlen) != 1 + || asn1_data_from_der(&p, len, in, inlen) != 1 + || asn1_object_identifier_from_octets(nodes, nodes_cnt, p, len) != 1) { error_print(); return -1; } - - if (inlen-- <= 0 || *in++ != tag) { - error_print(); - return 0; - } - if (asn1_length_from_der(&len, &in, &inlen) != 1 - || len <= 0) { - error_print(); - return -1; - } - if (asn1_object_identifier_from_octets(nodes, nodes_cnt, in, len) != 1) { - error_print(); - return -1; - } - *pin = in + len; - *pinlen = inlen - len; return 1; } @@ -1206,8 +1197,6 @@ int asn1_generalized_time_from_der_ex(int tag, time_t *t, const uint8_t **pin, s } memcpy(buf, in, len); - - if (len == sizeof("YYYYMMDDHHMMSSZ")-1) { if (!strptime(buf, "%Y%m%d%H%M%SZ", &tm_val)) { error_print(); @@ -1312,7 +1301,17 @@ int asn1_sequence_of_int_from_der(int *nums, size_t *nums_cnt, const uint8_t **i int asn1_sequence_of_int_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) { - return -1; + int val; + format_print(fp, fmt, ind, "%s: ", label); + while (dlen) { + if (asn1_int_from_der(&val, &d, &dlen) != 1) { + error_print(); + return -1; + } + fprintf(fp, "%d%s", val, dlen ? "," : ""); + } + fprintf(fp, "\n"); + return 1; } @@ -1320,11 +1319,15 @@ int asn1_object_identifier_print(FILE *fp, int format, int indent, const char *l const uint32_t *nodes, size_t nodes_cnt) { size_t i; - format_print(fp, format, indent, "%s: %s (", label, name); - for (i = 0; i < nodes_cnt - 1; i++) { - fprintf(fp, "%d.", (int)nodes[i]); + format_print(fp, format, indent, "%s: %s", label, name); + if (nodes) { + fprintf(fp, " ("); + for (i = 0; i < nodes_cnt - 1; i++) { + fprintf(fp, "%d.", (int)nodes[i]); + } + fprintf(fp, "%d)", nodes[i]); } - fprintf(fp, "%d)\n", nodes[i]); + fprintf(fp, "\n"); return 1; } @@ -1345,10 +1348,8 @@ int asn1_bits_print(FILE *fp, int fmt, int ind, const char *label, const char ** for (i = 0; i < names_cnt; i++) { if (bits & 0x01) - fprintf(fp, "%s", names[i]); + fprintf(fp, "%s%s", names[i], bits >> 1 ? "," : ""); bits >>= 1; - if (bits) - fprintf(fp, ", "); } fprintf(fp, "\n"); if (bits) { @@ -1358,7 +1359,6 @@ int asn1_bits_print(FILE *fp, int fmt, int ind, const char *label, const char ** return 1; } - int asn1_types_get_count(const uint8_t *d, size_t dlen, int tag, size_t *cnt) { error_print(); @@ -1371,11 +1371,3 @@ int asn1_types_get_item_by_index(const uint8_t *d, size_t *dlen, int tag, error_print(); return -1; } - - - - - - - - diff --git a/src/cms.c b/src/cms.c index afc1474a..96baa614 100644 --- a/src/cms.c +++ b/src/cms.c @@ -1975,7 +1975,7 @@ int cms_key_agreement_info_print(FILE *fp, int fmt, int ind, const char *label, if (sm2_public_key_info_from_der(&pub_key, &d, &dlen) != 1) goto err; sm2_public_key_print(fp, fmt, ind, "tempPublicKeyR", &pub_key); if (x509_cert_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_cert_print(fp, fmt, ind, p, len); + x509_cert_print(fp, fmt, ind, "certificate", p, len); if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; format_bytes(fp, fmt, ind, "userID", p, len); if (asn1_length_is_zero(dlen) != 1) goto err; diff --git a/src/debug.c b/src/debug.c index 465520bc..b759396d 100644 --- a/src/debug.c +++ b/src/debug.c @@ -107,7 +107,7 @@ int format_bytes(FILE *fp, int format, int indent, const char *str, const uint8_ for (i = 0; i < indent; i++) { fprintf(fp, " "); } - fprintf(fp, "%s", str); + fprintf(fp, "%s: ", str); if (!datalen) { fprintf(fp, "(null)\n"); return 1; diff --git a/src/pem.c b/src/pem.c index 987bfdf5..f8f11235 100644 --- a/src/pem.c +++ b/src/pem.c @@ -67,7 +67,8 @@ int pem_write(FILE *fp, const char *name, const uint8_t *data, size_t datalen) ret += fprintf(fp, "-----BEGIN %s-----\n", name); ret += fprintf(fp, "%s", (char *)b64); ret += fprintf(fp, "-----END %s-----\n", name); - return ret; + //return ret; + return 1; } int pem_read(FILE *fp, const char *name, uint8_t *data, size_t *datalen, size_t maxlen) @@ -81,11 +82,19 @@ int pem_read(FILE *fp, const char *name, uint8_t *data, size_t *datalen, size_t snprintf(begin_line, sizeof(begin_line), "-----BEGIN %s-----\n", name); snprintf(end_line, sizeof(end_line), "-----END %s-----\n", name); - if (!fgets(line, sizeof(line), fp)) { - //FIXME: feof 判断是不是文件结束了呢 + if (feof(fp)) { return 0; } + if (!fgets(line, sizeof(line), fp)) { + if (feof(fp)) + return 0; + else { + error_print(); + return -1; + } + } + if (strcmp(line, begin_line) != 0) { // FIXME: 这里是不是应该容忍一些错误呢? error_print(); diff --git a/src/pkcs8.c b/src/pkcs8.c index 24aff4d7..7d6162b0 100644 --- a/src/pkcs8.c +++ b/src/pkcs8.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -58,22 +58,69 @@ #include #include #include +#include -/* -PBKDF2-params ::= SEQUENCE { - salt OCTET STRING, - iterationCount INTEGER (1..MAX), - keyLength INTEGER (1..MAX) OPTIONAL, - prf AlgorithmIdentifier DEFAULT algid-hmacWithSHA1 + +static const uint32_t oid_hmac_sm3[] = { oid_sm_algors,401,2 }; +static const size_t oid_hmac_sm3_cnt = sizeof(oid_hmac_sm3)/sizeof(oid_hmac_sm3[0]); + +char *pbkdf2_prf_name(int oid) +{ + switch (oid) { + case OID_hmac_sm3: return "hmac-sm3"; + } + return NULL; } -这里prf的OID一般来说其他地方是用不到的,并且除了sm3-hmac之外,我们都不支持 +int pbkdf2_prf_from_name(const char *name) +{ + if (strcmp(name, "hmac-sm3") == 0) { + return OID_hmac_sm3; + } + return 0; +} -*/ +int pbkdf2_prf_to_der(int oid, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (oid == -1) + return 0; -static const uint32_t oid_hmac_sm3[] = { 1,2 }; -static const size_t oid_hmac_sm3_count = sizeof(oid_hmac_sm3)/sizeof(oid_hmac_sm3[0]); + if (oid != OID_hmac_sm3) { + error_print(); + return -1; + } + if (asn1_object_identifier_to_der(oid_hmac_sm3, oid_hmac_sm3_cnt, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_object_identifier_to_der(oid_hmac_sm3, oid_hmac_sm3_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} +int pbkdf2_prf_from_der(int *oid, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + uint32_t nodes[32]; + size_t nodes_cnt; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + else *oid = -1; + return ret; + } + if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1 + || asn1_object_identifier_equ(nodes, nodes_cnt, oid_hmac_sm3, oid_hmac_sm3_cnt) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + *oid = OID_hmac_sm3; + return 1; +} int pbkdf2_params_to_der( const uint8_t *salt, size_t saltlen, @@ -83,40 +130,15 @@ int pbkdf2_params_to_der( uint8_t **out, size_t *outlen) { size_t len = 0; - size_t prflen = 0; - - switch (prf) { - case OID_hmac_sm3: - break; - /* - case OID_hmacWithSHA1: - case OID_hmacWithSHA224: - case OID_hmacWithSHA256: - case OID_hmacWithSHA384: - case OID_hmacWithSHA512: - case OID_hmacWithSHA512_224: - case OID_hmacWithSHA512_256: - error_print(); - return -1; - */ - default: - error_print(); - return -1; - } - if (asn1_octet_string_to_der(salt, saltlen, NULL, &len) != 1 || asn1_int_to_der(iter, NULL, &len) != 1 || asn1_int_to_der(keylen, NULL, &len) < 0 - || asn1_object_identifier_to_der(oid_hmac_sm3, oid_hmac_sm3_count, NULL, &prflen) != 1 - || asn1_null_to_der(NULL, &prflen) != 1 - || asn1_sequence_to_der(NULL, prflen, NULL, &len) != 1 + || pbkdf2_prf_to_der(prf, NULL, &len) < 0 || asn1_sequence_header_to_der(len, out, outlen) != 1 || asn1_octet_string_to_der(salt, saltlen, out, outlen) != 1 || asn1_int_to_der(iter, out, outlen) != 1 || asn1_int_to_der(keylen, out, outlen) < 0 - || asn1_sequence_header_to_der(prflen, out, outlen) != 1 - || asn1_object_identifier_to_der(oid_hmac_sm3, oid_hmac_sm3_count, out, outlen) != 1 - || asn1_null_to_der(out, outlen) != 1) { + || pbkdf2_prf_to_der(prf, out, outlen) < 0) { error_print(); return -1; } @@ -131,61 +153,53 @@ int pbkdf2_params_from_der( const uint8_t **in, size_t *inlen) { int ret; - const uint8_t *data; - const uint8_t *algo; - size_t datalen; - size_t algolen; + const uint8_t *d; + size_t dlen; - if ((ret = asn1_sequence_from_der(&data, &datalen, in, inlen)) != 1) { + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { if (ret < 0) error_print(); return ret; } - if (asn1_octet_string_from_der(salt, saltlen, &data, &datalen) != 1 - || asn1_int_from_der(iter, &data, &datalen) != 1 - || asn1_int_from_der(keylen, &data, &datalen) < 0 - || asn1_sequence_from_der(&algo, &algolen, &data, &datalen) < 0 - || datalen > 0) { + if (asn1_octet_string_from_der(salt, saltlen, &d, &dlen) != 1 + || asn1_int_from_der(iter, &d, &dlen) != 1 + || asn1_int_from_der(keylen, &d, &dlen) < 0 + || pbkdf2_prf_from_der(prf, &d, &dlen) < 0 + || asn1_check(*saltlen > 0) != 1 + || asn1_check(*iter > 0) != 1 + || asn1_length_is_zero(dlen) != 1) { error_print(); return -1; } - if (*saltlen < 1) { - error_print(); - return -1; - } - if (*iter < 1) { - error_print(); - return -1; - } - if (algo) { - uint32_t nodes[32]; - size_t nodes_count; - - if (asn1_object_identifier_from_der(nodes, &nodes_count, &algo, &algolen) != 1 - || asn1_null_from_der(&algo, &algolen) != 1 - || algolen > 0) { - error_print(); - return -1; - } - if (nodes_count == oid_hmac_sm3_count - && memcmp(nodes, oid_hmac_sm3, sizeof(oid_hmac_sm3)) == 0) { - *prf = OID_hmac_sm3; - } else { - *prf = OID_undef; - error_print(); - return -1; - } - - } else { - //*prf = OID_hmacWithSHA1; - error_print(); - return -1; - } - return 1; } -static const uint32_t oid_pbkdf2[] = { 1, 2, 840, 113549, 1, 5, 12 }; -static const size_t oid_pbkdf2_count = sizeof(oid_pbkdf2)/sizeof(oid_pbkdf2[0]); +int pbkdf2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret; + const uint8_t *p; + size_t len; + int val; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "salt", p, len); + if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "iterationCount: %d\n", val); + if ((ret = asn1_int_from_der(&val, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "keyLength: %d\n", val); + if ((ret = pbkdf2_prf_from_der(&val, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "prf: %s\n", pbkdf2_prf_name(val)); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +static const uint32_t oid_pbkdf2[] = { oid_pkcs5,12 }; +static const size_t oid_pbkdf2_cnt = sizeof(oid_pbkdf2)/sizeof(oid_pbkdf2[0]); int pbkdf2_algor_to_der( const uint8_t *salt, size_t saltlen, @@ -195,11 +209,10 @@ int pbkdf2_algor_to_der( uint8_t **out, size_t *outlen) { size_t len = 0; - - if (asn1_object_identifier_to_der(oid_pbkdf2, oid_pbkdf2_count, NULL, &len) != 1 + if (asn1_object_identifier_to_der(oid_pbkdf2, oid_pbkdf2_cnt, NULL, &len) != 1 || pbkdf2_params_to_der(salt, saltlen, iter, keylen, prf, NULL, &len) != 1 || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(oid_pbkdf2, oid_pbkdf2_count, out, outlen) != 1 + || asn1_object_identifier_to_der(oid_pbkdf2, oid_pbkdf2_cnt, out, outlen) != 1 || pbkdf2_params_to_der(salt, saltlen, iter, keylen, prf, out, outlen) != 1) { error_print(); return -1; @@ -215,104 +228,88 @@ int pbkdf2_algor_from_der( const uint8_t **in, size_t *inlen) { int ret; - const uint8_t *data; - size_t datalen; - int oid; + const uint8_t *d; + size_t dlen; uint32_t nodes[32]; - size_t nodes_count; + size_t nodes_cnt; - if ((ret = asn1_sequence_from_der(&data, &datalen, in, inlen)) != 1) { + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { if (ret < 0) error_print(); return ret; } - - if (asn1_object_identifier_from_der(nodes, &nodes_count, &data, &datalen) != 1 - || pbkdf2_params_from_der(salt, saltlen, iter, keylen, prf, &data, &datalen) != 1 - || datalen > 0) { + if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1 + || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbkdf2, oid_pbkdf2_cnt) != 1 + || pbkdf2_params_from_der(salt, saltlen, iter, keylen, prf, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { error_print(); return -1; } - if (oid != OID_undef || nodes_count != oid_pbkdf2_count - || memcmp(nodes, oid_pbkdf2, sizeof(oid_pbkdf2)) != 0) { - error_print(); - return -1; - } - - // FIXME: 检查keylen return 1; } -static const uint32_t oid_sm4_cbc[] = { 1, 2, 156, 10197, 1, 104, 2 }; -static const size_t oid_sm4_cbc_count = sizeof(oid_sm4_cbc)/sizeof(oid_sm4_cbc[0]); - - -// 这个应该提取到外面,和digest_algor, encryption_algor, sign_algor 之类的放到一起 -int pbes2_enc_algor_to_der(int cipher, const uint8_t *iv, size_t ivlen, uint8_t **out, size_t *outlen) +int pbkdf2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) { - size_t len = 0; + uint32_t nodes[32]; + size_t nodes_cnt; + const uint8_t *p; + size_t len; - if (cipher != OID_sm4_cbc || ivlen != 16) { + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1 + || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbkdf2, oid_pbkdf2_cnt) != 1) { error_print(); return -1; } - if (asn1_object_identifier_to_der(oid_sm4_cbc, oid_sm4_cbc_count, NULL, &len) != 1 - || asn1_octet_string_to_der(iv, ivlen, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(oid_sm4_cbc, oid_sm4_cbc_count, out, outlen) != 1 - || asn1_octet_string_to_der(iv, ivlen, out, outlen) != 1) { + format_print(fp, fmt, ind, "algorithm: %s\n", "pbkdf2"); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + pbkdf2_params_print(fp, fmt, ind, "parameters", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int pbes2_enc_algor_to_der(int oid, const uint8_t *iv, size_t ivlen, uint8_t **out, size_t *outlen) +{ + if (oid != OID_sm4_cbc) { + error_print(); + return -1; + } + if (x509_encryption_algor_to_der(oid, iv, ivlen, out, outlen) != 1) { error_print(); return -1; } return 1; } -int pbes2_enc_algor_from_der(int *cipher, const uint8_t **iv, size_t *ivlen, const uint8_t **in, size_t *inlen) +int pbes2_enc_algor_from_der(int *oid, const uint8_t **iv, size_t *ivlen, const uint8_t **in, size_t *inlen) { int ret; - const uint8_t *data; - size_t datalen; - uint32_t nodes[32]; - size_t nodes_count; - - if ((ret = asn1_sequence_from_der(&data, &datalen, in, inlen)) != 1) { + if ((ret = x509_encryption_algor_from_der(oid, iv, ivlen, in, inlen)) != 1) { if (ret < 0) error_print(); return ret; } - - if (asn1_object_identifier_from_der(nodes, &nodes_count, &data, &datalen) != 1 - || asn1_octet_string_from_der(iv, ivlen, &data, &datalen) != 1 - || asn1_length_is_zero(datalen) != 1) { + if (*oid != OID_sm4_cbc) { error_print(); return -1; } - - if (asn1_object_identifier_equ(nodes, nodes_count, oid_sm4_cbc, oid_sm4_cbc_count) != 1) { - size_t i; - *cipher = OID_undef; - error_print(); - for (i = 0; i < nodes_count; i++) { - fprintf(stderr, " %d", nodes[i]); - } - fprintf(stderr, "\n"); - return -1; - } - *cipher = OID_sm4_cbc; - - // FIXME: 检查ivlen return 1; } +int pbes2_enc_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + return x509_encryption_algor_print(fp, fmt, ind, label, d, dlen); +} + int pbes2_params_to_der( - const uint8_t *salt, size_t saltlen, - int iter, - int prf, - int cipher, - const uint8_t *iv, size_t ivlen, + const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf, + int cipher, const uint8_t *iv, size_t ivlen, uint8_t **out, size_t *outlen) { size_t len = 0; - int keylen = -1; - if (pbkdf2_algor_to_der(salt, saltlen, iter, keylen, prf, NULL, &len) != 1 || pbes2_enc_algor_to_der(cipher, iv, ivlen, NULL, &len) != 1 || asn1_sequence_header_to_der(len, out, outlen) != 1 @@ -325,54 +322,61 @@ int pbes2_params_to_der( } int pbes2_params_from_der( - const uint8_t **salt, size_t *saltlen, - int *iter, - int *prf, - int *cipher, - const uint8_t **iv, size_t *ivlen, + const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf, + int *cipher, const uint8_t **iv, size_t *ivlen, const uint8_t **in, size_t *inlen) { int ret; - const uint8_t *data; - size_t datalen; - int keylen; + const uint8_t *d; + size_t dlen; - if ((ret = asn1_sequence_from_der(&data, &datalen, in, inlen)) != 1) { + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { if (ret < 0) error_print(); return ret; } - if (pbkdf2_algor_from_der(salt, saltlen, iter, &keylen, prf, &data, &datalen) != 1 - || pbes2_enc_algor_from_der(cipher, iv, ivlen, &data, &datalen) != 1 - || datalen > 0) { - error_print(); - return -1; - } - if (keylen >= 0 && keylen != 16) { + if (pbkdf2_algor_from_der(salt, saltlen, iter, keylen, prf, &d, &dlen) != 1 + || pbes2_enc_algor_from_der(cipher, iv, ivlen, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { error_print(); return -1; } return 1; } +int pbes2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; -static const uint32_t oid_pbes2[] = { 1, 2, 840, 113549, 1, 5, 13 }; -static const size_t oid_pbes2_count = sizeof(oid_pbes2)/sizeof(oid_pbes2[0]); + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + pbkdf2_algor_print(fp, fmt, ind, "keyDerivationFunc", p, len); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + pbes2_enc_algor_print(fp, fmt, ind, "encryptionScheme", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + + +static const uint32_t oid_pbes2[] = { oid_pkcs5,13 }; +static const size_t oid_pbes2_cnt = sizeof(oid_pbes2)/sizeof(oid_pbes2[0]); int pbes2_algor_to_der( - const uint8_t *salt, size_t saltlen, - int iter, - int prf, - int cipher, - const uint8_t *iv, size_t ivlen, + const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf, + int cipher, const uint8_t *iv, size_t ivlen, uint8_t **out, size_t *outlen) { size_t len = 0; - - if (asn1_object_identifier_to_der(oid_pbes2, oid_pbes2_count, NULL, &len) != 1 - || pbes2_params_to_der(salt, saltlen, iter, prf, cipher, iv, ivlen, NULL, &len) != 1 + if (asn1_object_identifier_to_der(oid_pbes2, oid_pbes2_cnt, NULL, &len) != 1 + || pbes2_params_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, NULL, &len) != 1 || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(oid_pbes2, oid_pbes2_count, out, outlen) != 1 - || pbes2_params_to_der(salt, saltlen, iter, prf, cipher, iv, ivlen, out, outlen) != 1) { + || asn1_object_identifier_to_der(oid_pbes2, oid_pbes2_cnt, out, outlen) != 1 + || pbes2_params_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, out, outlen) != 1) { error_print(); return -1; } @@ -380,212 +384,110 @@ int pbes2_algor_to_der( } int pbes2_algor_from_der( - const uint8_t **salt, size_t *saltlen, - int *iter, - int *prf, - int *cipher, - const uint8_t **iv, size_t *ivlen, + const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf, + int *cipher, const uint8_t **iv, size_t *ivlen, const uint8_t **in, size_t *inlen) { int ret; - const uint8_t *data; - size_t datalen; + const uint8_t *d; + size_t dlen; int oid; uint32_t nodes[32]; - size_t nodes_count; + size_t nodes_cnt; - if ((ret = asn1_sequence_from_der(&data, &datalen, in, inlen)) != 1) { + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { if (ret < 0) error_print(); return ret; } - - if (asn1_object_identifier_from_der(nodes, &nodes_count, &data, &datalen) != 1 - || pbes2_params_from_der(salt, saltlen, iter, prf, cipher, iv, ivlen, &data, &datalen) != 1 - || datalen > 0) { - error_print(); - return -1; - } - if (nodes_count != oid_pbes2_count - && memcmp(nodes, oid_pbes2, sizeof(oid_pbes2)) != 0) { + if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1 + || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbes2, oid_pbes2_cnt) != 1 + || pbes2_params_from_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { error_print(); return -1; } return 1; } +int pbes2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + uint32_t nodes[32]; + size_t nodes_cnt; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1 + || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbes2, oid_pbes2_cnt) != 1) + goto err; + format_print(fp, fmt, ind, "algorithm: %s\n", "pbes2"); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + pbes2_params_print(fp, fmt, ind, "parameters", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + int pkcs8_enced_private_key_info_to_der( - const uint8_t *salt, size_t saltlen, - int iter, - int prf, - int cipher, - const uint8_t *iv, size_t ivlen, + const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf, + int cipher, const uint8_t *iv, size_t ivlen, const uint8_t *enced, size_t encedlen, uint8_t **out, size_t *outlen) { size_t len = 0; - pbes2_algor_to_der(salt, saltlen, iter, prf, cipher, iv, ivlen, NULL, &len); - asn1_octet_string_to_der(enced, encedlen, NULL, &len); - asn1_sequence_header_to_der(len, out, outlen); - pbes2_algor_to_der(salt, saltlen, iter, prf, cipher, iv, ivlen, out, outlen); - asn1_octet_string_to_der(enced, encedlen, out, outlen); + if (pbes2_algor_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, NULL, &len) != 1 + || asn1_octet_string_to_der(enced, encedlen, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || pbes2_algor_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, out, outlen) != 1 + || asn1_octet_string_to_der(enced, encedlen, out, outlen) != 1) { + error_print(); + return -1; + } return 1; } int pkcs8_enced_private_key_info_from_der( - const uint8_t **salt, size_t *saltlen, - int *iter, - int *prf, - int *cipher, - const uint8_t **iv, size_t *ivlen, + const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf, + int *cipher, const uint8_t **iv, size_t *ivlen, const uint8_t **enced, size_t *encedlen, const uint8_t **in, size_t *inlen) { int ret; - const uint8_t *data; - size_t datalen; + const uint8_t *d; + size_t dlen; - if ((ret = asn1_sequence_from_der(&data, &datalen, in, inlen)) != 1) { + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { if (ret < 0) error_print(); return ret; } - if (pbes2_algor_from_der(salt, saltlen, iter, prf, cipher, iv, ivlen, &data, &datalen) != 1 - || asn1_octet_string_from_der(enced, encedlen, &data, &datalen) != 1 - || datalen > 0) { + if (pbes2_algor_from_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, &d, &dlen) != 1 + || asn1_octet_string_from_der(enced, encedlen, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { error_print(); return -1; } return 1; } -// output PKCS #8 EncryptedPrivateKeyInfo - -int sm2_enced_private_key_info_to_der(const SM2_KEY *sm2, const char *pass, uint8_t **out, size_t *outlen) +int pkcs8_enced_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) { - SM4_KEY sm4_key; - uint8_t salt[16]; - int iter = 65536; - int prf = OID_hmac_sm3; - uint8_t key[16]; - int cipher = OID_sm4_cbc; - uint8_t iv[16]; - uint8_t info[256]; - uint8_t *pinfo = info; - size_t infolen = 0; - uint8_t enced[512]; - size_t encedlen; - - if (rand_bytes(salt, sizeof(salt)) != 1 - || rand_bytes(iv, sizeof(iv)) != 1) { - error_print(); - return -1; - } - - // SM2_KEY to PKCS8 PrivateKeyInfo - if (sm2_private_key_info_to_der(sm2, &pinfo, &infolen) != 1) { - error_print(); - return -1; - } - - // password to encryption key - if (pbkdf2_genkey(DIGEST_sm3(), pass, strlen(pass), salt, sizeof(salt), iter, sizeof(key), key) != 1) { - error_print(); - return -1; - } - - // encrypt PrivateKeyInfo - sm4_set_encrypt_key(&sm4_key, key); - if (sm4_cbc_padding_encrypt(&sm4_key, iv, info, infolen, enced, &encedlen) != 1) { - error_print(); - return -1; - } - - // encode EncryptedPrivateKeyInfo - if (pkcs8_enced_private_key_info_to_der(salt, sizeof(salt), iter, prf, - cipher, iv, sizeof(iv), enced, encedlen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm2_enced_private_key_info_from_der(SM2_KEY *sm2, const uint8_t **attrs, size_t *attrslen, const char *pass, const uint8_t **in, size_t *inlen) -{ - SM4_KEY sm4_key; - const uint8_t *salt; - size_t saltlen; - int iter; - int prf; - int cipher; - const uint8_t *iv; - size_t ivlen; - const uint8_t *enced; - size_t encedlen; - uint8_t key[16]; - uint8_t info[256]; - const uint8_t *pinfo = info; - size_t infolen; - - if (pkcs8_enced_private_key_info_from_der(&salt, &saltlen, &iter, &prf, - &cipher, &iv, &ivlen, &enced, &encedlen, in, inlen) != 1) { - error_print(); - return -1; - } - - if (pbkdf2_genkey(DIGEST_sm3(), pass, strlen(pass), salt, saltlen, iter, sizeof(key), key) != 1) { - error_print(); - return -1; - } - - sm4_set_decrypt_key(&sm4_key, key); - if (sm4_cbc_padding_decrypt(&sm4_key, iv, enced, encedlen, info, &infolen) != 1) { - error_print(); - return -1; - } - if (sm2_private_key_info_from_der(sm2, attrs, attrslen, &pinfo, &infolen) != 1 - || infolen > 0) { - error_print(); - return -1; - } - - return 1; -} - -int sm2_enced_private_key_info_to_pem(const SM2_KEY *key, const char *pass, FILE *fp) -{ - uint8_t buf[1024]; - uint8_t *p = buf; - size_t len = 0; - - if (sm2_enced_private_key_info_to_der(key, pass, &p, &len) != 1) { - error_print(); - return -1; - } - if (pem_write(fp, "ENCRYPTED PRIVATE KEY", buf, len) <= 0) { - error_print(); - return -1; - } - return 1; -} - -// TODO: return attributes -int sm2_enced_private_key_info_from_pem(SM2_KEY *key, const char *pass, FILE *fp) -{ - uint8_t buf[512]; - const uint8_t *cp = buf; + const uint8_t *p; size_t len; - const uint8_t *attrs; - size_t attrslen; - if (pem_read(fp, "ENCRYPTED PRIVATE KEY", buf, &len, sizeof(buf)) != 1) { - error_print(); - return -1; - } + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; - if (sm2_enced_private_key_info_from_der(key, &attrs, &attrslen, pass, &cp, &len) != 1 - || len > 0) { - error_print(); - return -1; - } + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + pbes2_algor_print(fp, fmt, ind, "encryptionAlgorithm", p, len); + if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "encryptedData", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; return 1; +err: + error_print(); + return -1; } - diff --git a/src/sm2_asn1.c b/src/sm2_asn1.c index 30460ace..1f5a7de5 100644 --- a/src/sm2_asn1.c +++ b/src/sm2_asn1.c @@ -51,6 +51,10 @@ #include #include #include +#include +#include +#include +#include #include // sm2 curve 1.2.156.10197.1.301 @@ -71,71 +75,93 @@ 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) { if ((*in == 0x02 || *in == 0x03) && inlen == 33) { - return sm2_point_from_x(P, in + 1, *in); + if (sm2_point_from_x(P, in + 1, *in) != 1) { + error_print(); + return -1; + } } else if (*in == 0x04 && inlen == 65) { - return sm2_point_from_xy(P, in + 1, in + 33); + if (sm2_point_from_xy(P, in + 1, in + 33) != 1) { + error_print(); + return -1; + } } else { error_print(); return -1; } -} - -int sm2_point_to_der(const SM2_POINT *a, uint8_t **out, size_t *outlen) -{ - uint8_t buf[65]; - sm2_point_to_uncompressed_octets(a, buf); - asn1_octet_string_to_der(buf, sizeof(buf), out, outlen); return 1; } -int sm2_point_from_der(SM2_POINT *a, const uint8_t **in, size_t *inlen) +int sm2_point_to_der(const SM2_POINT *P, uint8_t **out, size_t *outlen) { - int ret; - const uint8_t *data; - size_t datalen; - error_print_msg("inlen = %zu\n", *inlen); - - if ((ret = asn1_octet_string_from_der(&data, &datalen, in, inlen)) != 1) { - if (ret < 0) error_print(); - else error_print(); - return ret; - } - if (sm2_point_from_octets(a, data, datalen) != 1) { + uint8_t buf[65]; + if (!P) + return 0; + sm2_point_to_uncompressed_octets(P, buf); + if (asn1_octet_string_to_der(buf, sizeof(buf), out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_octet_string_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (sm2_point_from_octets(P, d, dlen) != 1) { error_print(); return -1; } - error_print_msg("inlen = %zu\n", *inlen); return 1; } int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen) { size_t len = 0; - asn1_integer_to_der(sig->r, 32, NULL, &len); - asn1_integer_to_der(sig->s, 32, NULL, &len); - asn1_sequence_header_to_der(len, out, outlen); - asn1_integer_to_der(sig->r, 32, out, outlen); - asn1_integer_to_der(sig->s, 32, out, outlen); + if (!sig) + return 0; + if (asn1_integer_to_der(sig->r, 32, NULL, &len) != 1 + || asn1_integer_to_der(sig->s, 32, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_integer_to_der(sig->r, 32, out, outlen) != 1 + || asn1_integer_to_der(sig->s, 32, out, outlen) != 1) { + error_print(); + return -1; + } return 1; } int sm2_signature_from_der(SM2_SIGNATURE *sig, const uint8_t **in, size_t *inlen) { - const uint8_t *data, *r, *s; - size_t datalen, rlen, slen; + int ret; + const uint8_t *d; + size_t dlen; + const uint8_t *r; + size_t rlen; + const uint8_t *s; + size_t slen; - if (asn1_sequence_from_der(&data, &datalen, in, inlen) < 0 - || asn1_integer_from_der(&r, &rlen, &data, &datalen) < 0 - || asn1_integer_from_der(&s, &slen, &data, &datalen) < 0 - || datalen > 0) { + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_integer_from_der(&r, &rlen, &d, &dlen) != 1 + || asn1_integer_from_der(&s, &slen, &d, &dlen) != 1 + || asn1_length_le(rlen, 32) != 1 + || asn1_length_le(slen, 32) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); return -1; } - if (rlen != 32 || slen != 32) { - return -2; - } - - memcpy(sig->r, r, 32); - memcpy(sig->s, s, 32); + memset(sig, 0, sizeof(*sig)); + memcpy(sig->r, r, rlen); + memcpy(sig->s, s, slen); return 1; } @@ -148,48 +174,59 @@ int sm2_ciphertext_size(size_t inlen, size_t *outlen) int sm2_ciphertext_to_der(const SM2_CIPHERTEXT *c, uint8_t **out, size_t *outlen) { size_t len = 0; - asn1_integer_to_der(c->point.x, 32, NULL, &len); - asn1_integer_to_der(c->point.y, 32, NULL, &len); - asn1_octet_string_to_der(c->hash, 32, NULL, &len); - asn1_octet_string_to_der(c->ciphertext, c->ciphertext_size, NULL, &len); - asn1_sequence_header_to_der(len, out, outlen); - asn1_integer_to_der(c->point.x, 32, out, outlen); - asn1_integer_to_der(c->point.y, 32, out, outlen); - asn1_octet_string_to_der(c->hash, 32, out, outlen); - asn1_octet_string_to_der(c->ciphertext, c->ciphertext_size, out, outlen); + if (!c) + return 0; + if (asn1_integer_to_der(c->point.x, 32, NULL, &len) != 1 + || asn1_integer_to_der(c->point.y, 32, NULL, &len) != 1 + || asn1_octet_string_to_der(c->hash, 32, NULL, &len) != 1 + || asn1_octet_string_to_der(c->ciphertext, c->ciphertext_size, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_integer_to_der(c->point.x, 32, out, outlen) != 1 + || asn1_integer_to_der(c->point.y, 32, out, outlen) != 1 + || asn1_octet_string_to_der(c->hash, 32, out, outlen) != 1 + || asn1_octet_string_to_der(c->ciphertext, c->ciphertext_size, out, outlen) != 1) { + error_print(); + return -1; + } return 1; } -int sm2_ciphertext_from_der(SM2_CIPHERTEXT *a, const uint8_t **in, size_t *inlen) +int sm2_ciphertext_from_der(SM2_CIPHERTEXT *C, const uint8_t **in, size_t *inlen) { - const uint8_t *data, *x, *y, *hash, *c; + int ret; + const uint8_t *d; + size_t dlen; + const uint8_t *x; + const uint8_t *y; + const uint8_t *hash; + const uint8_t *c; size_t datalen, xlen, ylen, hashlen, clen; - if (asn1_sequence_from_der(&data, &datalen, in, inlen) < 0 - || asn1_integer_from_der(&x, &xlen, &data, &datalen) < 0 - || asn1_integer_from_der(&y, &ylen, &data, &datalen) < 0 - || asn1_octet_string_from_der(&hash, &hashlen, &data, &datalen) < 0 - || asn1_octet_string_from_der(&c, &clen, &data, &datalen) < 0 - || datalen > 0) { + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_integer_from_der(&x, &xlen, &d, &dlen) != 1 + || asn1_integer_from_der(&y, &ylen, &d, &dlen) != 1 + || asn1_octet_string_from_der(&hash, &hashlen, &d, &dlen) != 1 + || asn1_octet_string_from_der(&c, &clen, &d, &dlen) != 1 + || asn1_length_le(xlen, 32) != 1 + || asn1_length_le(ylen, 32) != 1 + || asn1_check(hashlen == 32) != 1 + || asn1_length_le(clen, SM2_MAX_PLAINTEXT_SIZE) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); return -1; } - if (xlen != 32 - || ylen != 32 - || hashlen != 32 - || clen < 1) { - return -1; - } - - memcpy(a->point.x, x, 32); - memcpy(a->point.y, y, 32); - memcpy(a->hash, hash, 32); - memcpy(a->ciphertext, c, clen); - a->ciphertext_size = (uint32_t)clen; + memset(C, 0, sizeof(SM2_CIPHERTEXT)); + memcpy(C->point.x, x, xlen); + memcpy(C->point.y, y, ylen); + memcpy(C->hash, hash, hashlen); + memcpy(C->ciphertext, c, clen); + C->ciphertext_size = (uint32_t)clen; return 1; } - - // TODO: sm2, ecPublicKey 这些公用的OID应该提取到一个地方 static const uint32_t oid_sm2[] = { 1,2,156,10197,1,301 }; static const size_t oid_sm2_count = sizeof(oid_sm2)/sizeof(oid_sm2[0]); @@ -345,54 +382,57 @@ int sm2_public_key_algor_from_der(const uint8_t **in, size_t *inlen) return 1; } - -int sm2_private_key_info_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen) +int sm2_private_key_info_to_der(const SM2_KEY *sm2_key, uint8_t **out, size_t *outlen) { size_t len = 0; uint8_t prikey[512]; uint8_t *p = prikey; size_t prikey_len = 0; - sm2_private_key_to_der(key, &p, &prikey_len); - - asn1_int_to_der(0, NULL, &len); - sm2_public_key_algor_to_der(NULL, &len); - asn1_octet_string_to_der(prikey, prikey_len, NULL, &len); - asn1_sequence_header_to_der(len, out, outlen); - asn1_int_to_der(0, out, outlen); - sm2_public_key_algor_to_der(out, outlen); - asn1_octet_string_to_der(prikey, prikey_len, out, outlen); + if (sm2_private_key_to_der(sm2_key, &p, &prikey_len) != 1) { + error_print(); + return -1; + } + if (asn1_int_to_der(0, NULL, &len) != 1 + || sm2_public_key_algor_to_der(NULL, &len) != 1 + || asn1_octet_string_to_der(prikey, prikey_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(0, out, outlen) != 1 + || sm2_public_key_algor_to_der(out, outlen) != 1 + || asn1_octet_string_to_der(prikey, prikey_len, out, outlen) != 1) { + memset(prikey, 0, sizeof(prikey)); + error_print(); + return -1; + } + memset(prikey, 0, sizeof(prikey)); return 1; } -int sm2_private_key_info_from_der(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, +int sm2_private_key_info_from_der(SM2_KEY *sm2_key, const uint8_t **attrs, size_t *attrslen, const uint8_t **in, size_t *inlen) { int ret; - const uint8_t *data; - size_t datalen; + const uint8_t *d; + size_t dlen; int version; const uint8_t *prikey; size_t prikeylen; - if ((ret = asn1_sequence_from_der(&data, &datalen, in, inlen)) != 1) { + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { if (ret < 0) error_print(); return ret; } - if (asn1_int_from_der(&version, &data, &datalen) != 1 - || sm2_public_key_algor_from_der(&data, &datalen) != 1 - || asn1_octet_string_from_der(&prikey, &prikeylen, &data, &datalen) != 1 - || asn1_implicit_set_from_der(0, attrs, attrslen, &data, &datalen) < 0 - || datalen > 0) { + if (asn1_int_from_der(&version, &d, &dlen) != 1 + || sm2_public_key_algor_from_der(&d, &dlen) != 1 + || asn1_octet_string_from_der(&prikey, &prikeylen, &d, &dlen) != 1 + || asn1_implicit_set_from_der(0, attrs, attrslen, &d, &dlen) < 0 + || asn1_check(version == 0) != 1 + || asn1_length_is_zero(dlen) != 1) { error_print(); return -1; } - if (version != 0) { - error_print(); - return -1; - } - if (sm2_private_key_from_der(key, &prikey, &prikeylen) != 1 - || prikeylen > 0) { + if (sm2_private_key_from_der(sm2_key, &prikey, &prikeylen) != 1 + || asn1_length_is_zero(prikeylen) != 1) { error_print(); return -1; } @@ -405,31 +445,28 @@ int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp) uint8_t *p = buf; size_t len = 0; - if (sm2_private_key_info_to_der(key, &p, &len) != 1) { - error_print(); - return -1; - } - if (pem_write(fp, "PRIVATE KEY", buf, len) <= 0) { + if (sm2_private_key_info_to_der(key, &p, &len) != 1 + || pem_write(fp, "PRIVATE KEY", buf, len) != 1) { + memset(buf, 0, sizeof(buf)); error_print(); return -1; } + memset(buf, 0, sizeof(buf)); return 1; } -int sm2_private_key_info_from_pem(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, FILE *fp) +int sm2_private_key_info_from_pem(SM2_KEY *sm2_key, const uint8_t **attrs, size_t *attrslen, FILE *fp) { uint8_t buf[512]; const uint8_t *cp = buf; size_t len; - if (pem_read(fp, "PRIVATE KEY", buf, &len, sizeof(buf)) != 1) { + if (pem_read(fp, "PRIVATE KEY", buf, &len, sizeof(buf)) != 1 + || sm2_private_key_info_from_der(sm2_key, attrs, attrslen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { error_print(); return -1; } - if (sm2_private_key_info_from_der(key, attrs, attrslen, &cp, &len) != 1 - || len > 0) { - return -1; - } return 1; } @@ -567,3 +604,129 @@ int sm2_public_key_digest(const SM2_KEY *sm2_key, uint8_t dgst[32]) return 1; } +int sm2_private_key_info_encrypt_to_der(const SM2_KEY *sm2_key, const char *pass, + uint8_t **out, size_t *outlen) +{ + int ret = -1; + uint8_t pkey_info[2560]; + uint8_t *p = pkey_info; + size_t pkey_info_len = 0; + uint8_t salt[16]; + int iter = 65536; + uint8_t iv[16]; + uint8_t key[16]; + SM4_KEY sm4_key; + uint8_t enced_pkey_info[5120]; + size_t enced_pkey_info_len; + + if (sm2_private_key_info_to_der(sm2_key, &p, &pkey_info_len) != 1 + || rand_bytes(salt, sizeof(salt)) != 1 + || rand_bytes(iv, sizeof(iv)) != 1 + || pbkdf2_genkey(DIGEST_sm3(), pass, strlen(pass), + salt, sizeof(salt), iter, sizeof(key), key) != 1) { + error_print(); + goto end; + } + sm4_set_encrypt_key(&sm4_key, key); + if (sm4_cbc_padding_encrypt( + &sm4_key, iv, pkey_info, pkey_info_len, + enced_pkey_info, &enced_pkey_info_len) != 1 + || pkcs8_enced_private_key_info_to_der( + salt, sizeof(salt), iter, sizeof(key), OID_hmac_sm3, + OID_sm4_cbc, iv, sizeof(iv), + enced_pkey_info, enced_pkey_info_len, out, outlen) != 1) { + error_print(); + goto end; + } + ret = 1; +end: + memset(pkey_info, 0, sizeof(pkey_info)); + memset(key, 0, sizeof(key)); + memset(&sm4_key, 0, sizeof(sm4_key)); + return ret; +} + +int sm2_private_key_info_decrypt_from_der(SM2_KEY *sm2, + const uint8_t **attrs, size_t *attrs_len, + const char *pass, const uint8_t **in, size_t *inlen) +{ + int ret = -1; + const uint8_t *salt; + size_t saltlen; + int iter; + int keylen; + int prf; + int cipher; + const uint8_t *iv; + size_t ivlen; + uint8_t key[16]; + SM4_KEY sm4_key; + const uint8_t *enced_pkey_info; + size_t enced_pkey_info_len; + uint8_t pkey_info[256]; + const uint8_t *cp = pkey_info; + size_t pkey_info_len; + + if (pkcs8_enced_private_key_info_from_der(&salt, &saltlen, &iter, &keylen, &prf, + &cipher, &iv, &ivlen, &enced_pkey_info, &enced_pkey_info_len, in, inlen) != 1 + || asn1_check(keylen == -1 || keylen == 16) != 1 + || asn1_check(prf == - 1 || prf == OID_hmac_sm3) != 1 + || asn1_check(cipher == OID_sm4_cbc) != 1 + || asn1_check(ivlen == 16) != 1 + || asn1_length_le(enced_pkey_info_len, sizeof(pkey_info)) != 1) { + error_print(); + return -1; + } + if (pbkdf2_genkey(DIGEST_sm3(), pass, strlen(pass), salt, saltlen, iter, sizeof(key), key) != 1) { + error_print(); + goto end; + } + sm4_set_decrypt_key(&sm4_key, key); + if (sm4_cbc_padding_decrypt(&sm4_key, iv, enced_pkey_info, enced_pkey_info_len, + pkey_info, &pkey_info_len) != 1 + || sm2_private_key_info_from_der(sm2, attrs, attrs_len, &cp, &pkey_info_len) != 1 + || asn1_length_is_zero(pkey_info_len) != 1) { + error_print(); + goto end; + } + ret = 1; +end: + memset(&sm4_key, 0, sizeof(sm4_key)); + memset(key, 0, sizeof(key)); + memset(pkey_info, 0, sizeof(pkey_info)); + return ret; +} + +int sm2_private_key_info_encrypt_to_pem(const SM2_KEY *sm2_key, const char *pass, FILE *fp) +{ + uint8_t buf[1024]; + uint8_t *p = buf; + size_t len = 0; + + if (sm2_private_key_info_encrypt_to_der(sm2_key, pass, &p, &len) != 1) { + error_print(); + return -1; + } + if (pem_write(fp, "ENCRYPTED PRIVATE KEY", buf, len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm2_private_key_info_decrypt_from_pem(SM2_KEY *key, const char *pass, FILE *fp) +{ + uint8_t buf[512]; + const uint8_t *cp = buf; + size_t len; + const uint8_t *attrs; + size_t attrs_len; + + if (pem_read(fp, "ENCRYPTED PRIVATE KEY", buf, &len, sizeof(buf)) != 1 + || sm2_private_key_info_decrypt_from_der(key, &attrs, &attrs_len, pass, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} diff --git a/src/sm2_prn.c b/src/sm2_prn.c index c1ec6fcb..3d3ea9df 100644 --- a/src/sm2_prn.c +++ b/src/sm2_prn.c @@ -54,41 +54,42 @@ #include #include -// FIXME: 缺乏打印公钥的函数,有时候SM2_KEY中只有公钥,没有私钥 -int sm2_key_print(FILE *fp, int format, int indent, const char *label, const SM2_KEY *key) + +int sm2_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *key) { - format_print(fp, format, indent, "SM2PrivateKey\n"); - indent += 4; - format_bytes(fp, format, indent, "private_key : ", key->private_key, 32); - sm2_point_print(fp, format, indent + 4, "public_key", &key->public_key); + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + sm2_public_key_print(fp, fmt, ind, "publicKey", key); + format_bytes(fp, fmt, ind, "privateKey", key->private_key, 32); return 1; } int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *pub_key) { - sm2_point_print(fp, fmt, ind + 4, "public_key", &pub_key->public_key); - return 1; + return sm2_point_print(fp, fmt, ind, label, &pub_key->public_key); } -int sm2_point_print(FILE *fp, int format, int indent, const char *label, const SM2_POINT *P) +int sm2_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_POINT *P) { - format_bytes(fp, format, indent, "x : ", P->x, 32); - format_bytes(fp, format, indent, "y : ", P->y, 32); + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + format_bytes(fp, fmt, ind, "x", P->x, 32); + format_bytes(fp, fmt, ind, "y", P->y, 32); return 1; } int sm2_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) { SM2_SIGNATURE sig; + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; if (sm2_signature_from_der(&sig, &a, &alen) != 1 || asn1_length_is_zero(alen) != 1) { error_print(); return -1; } - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - format_bytes(fp, fmt, ind, "r : ", sig.r, 32); - format_bytes(fp, fmt, ind, "s : ", sig.s, 32); + format_bytes(fp, fmt, ind, "r", sig.r, 32); + format_bytes(fp, fmt, ind, "s", sig.s, 32); return 1; } diff --git a/src/x509_cer.c b/src/x509_cer.c index 29fc6636..729a26d0 100644 --- a/src/x509_cer.c +++ b/src/x509_cer.c @@ -101,7 +101,7 @@ int x509_explicit_version_from_der(int index, int *version, const uint8_t **in, if ((ret = asn1_explicit_from_der(index, &d, &dlen, in, inlen)) != 1) { if (ret < 0) error_print(); - else *version = X509_version_v1; + else *version = -1; return ret; } if (asn1_int_from_der(version, &d, &dlen) != 1 @@ -224,9 +224,9 @@ int x509_validity_print(FILE *fp, int fmt, int ind, const char *label, const uin ind += 4; if (x509_time_from_der(&tv, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "notBefore : %s\n", ctime(&tv)); + format_print(fp, fmt, ind, "notBefore: %s", ctime(&tv)); if (x509_time_from_der(&tv, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "notAfter : %s\n", ctime(&tv)); + format_print(fp, fmt, ind, "notAfter: %s", ctime(&tv)); if (asn1_length_is_zero(dlen) != 1) goto err; return 1; err: @@ -278,7 +278,8 @@ int x509_attr_type_and_value_check(int oid, int tag, const uint8_t *val, size_t return 1; } } - return 0; + error_print(); + return -1; } int x509_attr_type_and_value_to_der(int oid, int tag, const uint8_t *val, size_t vlen, @@ -324,14 +325,19 @@ int x509_attr_type_and_value_print(FILE *fp, int fmt, int ind, const char *label const uint8_t *val; size_t vlen; - if (label) { + if (fmt & ASN1_FMT_FULL) { format_print(fp, fmt, ind, "%s\n", label); ind += 4; } if (x509_name_type_from_der(&oid, &d, &dlen) != 1) goto err; - asn1_object_identifier_print(fp, fmt, ind, "type", x509_name_type_name(oid), NULL, 0); + if (fmt & ASN1_FMT_FULL) + asn1_object_identifier_print(fp, fmt, ind, "type", x509_name_type_name(oid), NULL, 0); + if (x509_directory_name_from_der(&tag, &val, &vlen, &d, &dlen) != 1) goto err; - x509_directory_name_print(fp, fmt, ind, "value", tag, val, vlen); + if (fmt & ASN1_FMT_FULL) + x509_directory_name_print(fp, fmt, ind, "value", tag, val, vlen); + else x509_directory_name_print(fp, fmt, ind, x509_name_type_name(oid), tag, val, vlen); + if (asn1_length_is_zero(dlen) != 1) goto err; return 1; err: @@ -387,7 +393,7 @@ int x509_rdn_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t const uint8_t *p; size_t len; - if (label) { + if (fmt & ASN1_FMT_FULL) { format_print(fp, fmt, ind, "%s\n", label); ind += 4; } @@ -398,7 +404,7 @@ int x509_rdn_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t } x509_attr_type_and_value_print(fp, fmt, ind, "AttributeTypeAndValue", p, len); } - format_print(fp, fmt, ind, "\n"); + //format_print(fp, fmt, ind, "\n"); return 1; } @@ -406,19 +412,14 @@ int x509_name_add_rdn(uint8_t *d, size_t *dlen, size_t maxlen, int oid, int tag, const uint8_t *val, size_t vlen, const uint8_t *more, size_t morelen) { - uint8_t *p; size_t len = 0; - - if (x509_rdn_to_der(oid, tag, val, len, NULL, 0, NULL, &len) != 1) { - error_print(); - return -1; + uint8_t *p = d + *dlen; + if (!val && !more) { + return 0; } - if (*dlen + len + morelen > maxlen) { - error_print(); - return -1; - } - if (x509_rdn_to_der(oid, tag, val, len, NULL, 0, &d, dlen) != 1 - || asn1_data_to_der(more, morelen, &d, dlen) < 0) { + if (x509_rdn_to_der(oid, tag, val, vlen, NULL, 0, NULL, &len) != 1 + || asn1_length_le(*dlen + len, maxlen) != 1 + || x509_rdn_to_der(oid, tag, val, vlen, NULL, 0, &p, dlen) != 1) { error_print(); return -1; } @@ -427,44 +428,88 @@ int x509_name_add_rdn(uint8_t *d, size_t *dlen, size_t maxlen, int x509_name_add_country_name(uint8_t *d, size_t *dlen, int maxlen, const char val[2]) { - return x509_name_add_rdn(d, dlen, maxlen, + int ret; + ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_country_name, ASN1_TAG_PrintableString, (uint8_t *)val, 2, NULL, 0); + if (ret < 0) error_print(); + return ret; } int x509_name_add_state_or_province_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen) { - return x509_name_add_rdn(d, dlen, maxlen, OID_at_state_or_province_name, tag, val, vlen, NULL, 0); + int ret; + ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_state_or_province_name, tag, val, vlen, NULL, 0); + if (ret < 0) error_print(); + return ret; } int x509_name_add_locality_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen) { - return x509_name_add_rdn(d, dlen, maxlen, OID_at_locality_name, tag, val, vlen, NULL, 0); + int ret; + ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_locality_name, tag, val, vlen, NULL, 0); + if (ret < 0) error_print(); + return ret; } int x509_name_add_organization_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen) { - return x509_name_add_rdn(d, dlen, maxlen, OID_at_organization_name, tag, val, vlen, NULL, 0); + int ret; + ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_organization_name, tag, val, vlen, NULL, 0); + if (ret < 0) error_print(); + return ret; } int x509_name_add_organizational_unit_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen) { - return x509_name_add_rdn(d, dlen, maxlen, OID_at_organizational_unit_name, tag, val, vlen, NULL, 0); + int ret; + ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_organizational_unit_name, tag, val, vlen, NULL, 0); + if (ret < 0) error_print(); + return ret; } int x509_name_add_common_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen) { - return x509_name_add_rdn(d, dlen, maxlen, OID_at_common_name, tag, val, vlen, NULL, 0); + int ret; + ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_common_name, tag, val, vlen, NULL, 0); + if (ret < 0) error_print(); + return ret; } int x509_name_add_domain_component(uint8_t *d, size_t *dlen, int maxlen, const char *val, size_t vlen) { + int ret; return x509_name_add_rdn(d, dlen, maxlen, OID_domain_component, ASN1_TAG_IA5String, (uint8_t *)val, vlen, NULL, 0); + if (ret < 0) error_print(); + return ret; +} + +static size_t _strlen(const char *s) { return s ? strlen(s) : 0; } + +int x509_name_set(uint8_t *d, size_t *dlen, size_t maxlen, + const char *country, const char *state, const char *locality, + const char *org, const char *org_unit, const char *common_name) +{ + int tag = ASN1_TAG_PrintableString; + if (country && strlen(country) != 2) { + error_print(); + return -1; + } + if (x509_name_add_country_name(d, dlen, maxlen, country) < 0 + || x509_name_add_state_or_province_name(d, dlen, maxlen, tag, (uint8_t *)state, _strlen(state)) < 0 + || x509_name_add_locality_name(d, dlen, maxlen, tag, (uint8_t *)locality, _strlen(locality)) < 0 + || x509_name_add_organization_name(d, dlen, maxlen, tag, (uint8_t *)org, _strlen(org)) < 0 + || x509_name_add_organizational_unit_name(d, dlen, maxlen, tag, (uint8_t *)org_unit, _strlen(org_unit)) < 0 + || x509_name_add_common_name(d, dlen, maxlen, tag, (uint8_t *)common_name, _strlen(common_name)) != 1) { + error_print(); + return -1; + } + return 1; } int x509_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) @@ -515,7 +560,7 @@ int x509_public_key_info_print(FILE *fp, int fmt, int ind, const char *label, co if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; x509_public_key_algor_print(fp, fmt, ind, "algorithm", p, len); if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "subjectPublicKey: ", p, len); + format_bytes(fp, fmt, ind, "subjectPublicKey", p, len); if (asn1_length_is_zero(dlen) != 1) goto err; return 1; err: @@ -649,6 +694,9 @@ err: int x509_explicit_exts_to_der(int index, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) { size_t len = 0; + if (!d) { + return 0; + } if (asn1_sequence_to_der(d, dlen, NULL, &len) != 1 || asn1_explicit_header_to_der(index, len, out, outlen) != 1 || asn1_sequence_to_der(d, dlen, out, outlen) != 1) { @@ -803,17 +851,17 @@ int x509_tbs_cert_print(FILE *fp, int fmt, int ind, const char *label, const uin ind += 4; if ((ret = x509_explicit_version_from_der(0, &val, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "version: %s\n", x509_version_name(val)); + if (ret) format_print(fp, fmt, ind, "version: %s (%d)\n", x509_version_name(val), val); if (asn1_integer_from_der(&p, &len, &d, &dlen) != 1) goto err; format_bytes(fp, fmt, ind, "serialNumber", p, len); if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err; format_print(fp, fmt, ind, "siganture: %s\n", x509_signature_algor_name(val)); if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_name_print(fp, fmt, ind, "issuer", d, dlen); + x509_name_print(fp, fmt, ind, "issuer", p, len); if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; x509_validity_print(fp, fmt, ind, "validity", p, len); if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_name_print(fp, fmt, ind, "subject", d, dlen); + x509_name_print(fp, fmt, ind, "subject", p, len); if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; x509_public_key_info_print(fp, fmt, ind, "subjectPulbicKeyInfo", p, len); if ((ret = asn1_implicit_bit_octets_from_der(1, &p, &len, &d, &dlen)) < 0) goto err; @@ -886,6 +934,7 @@ int x509_certificate_print(FILE *fp, int fmt, int ind, const char *label, const if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err; format_bytes(fp, fmt, ind, "signatureValue", p, len); if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; err: error_print(); return -1; @@ -980,13 +1029,15 @@ int x509_cert_verify(const uint8_t *a, size_t alen, return ret; } -int x509_cert_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen) +int x509_cert_verify_by_ca_cert(const uint8_t *a, size_t alen, + const uint8_t *cacert, size_t cacertlen, + const char *signer_id, size_t signer_id_len) { int ret; SM2_KEY public_key; if (x509_cert_get_subject_public_key(cacert, cacertlen, &public_key) != 1 - || (ret = x509_cert_verify(a, alen, &public_key, NULL, 0)) < 0) { + || (ret = x509_cert_verify(a, alen, &public_key, signer_id, signer_id_len)) < 0) { error_print(); return -1; } @@ -1015,9 +1066,10 @@ int x509_cert_to_pem(const uint8_t *a, size_t alen, FILE *fp) int x509_cert_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp) { - if (pem_read(fp, "CERTIFICATE", a, alen, maxlen) != 1) { - error_print(); - return -1; + int ret; + if ((ret = pem_read(fp, "CERTIFICATE", a, alen, maxlen)) != 1) { + if (ret < 0) error_print(); + return ret; } return 1; } @@ -1054,17 +1106,20 @@ int x509_cert_from_pem_by_subject(uint8_t *a, size_t *alen, size_t maxlen, const return 0; } -int x509_cert_print(FILE *fp, int fmt, int ind, const uint8_t *a, size_t alen) +int x509_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) { const uint8_t *d; size_t dlen; + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1 || asn1_length_is_zero(alen) != 1) { error_print(); return -1; } - x509_certificate_print(fp, fmt, ind, "Certificate", d, dlen); + x509_certificate_print(fp, fmt, ind, label, d, dlen); return 1; } @@ -1082,11 +1137,14 @@ int x509_cert_get_details(const uint8_t *a, size_t alen, int *signature_algor, const uint8_t **signature, size_t *signature_len) { - const uint8_t *d; - size_t dlen; + const uint8_t *tbs; + size_t tbs_len; int sig_alg; const uint8_t *sig; size_t sig_len; + const uint8_t *d; + size_t dlen; + int ver; const uint8_t *serial; size_t serial_len; int inner_sig_alg; @@ -1098,11 +1156,17 @@ int x509_cert_get_details(const uint8_t *a, size_t alen, const uint8_t *subj_uniq_id; size_t subj_uniq_id_len; const uint8_t *exts; size_t exts_len; - if (x509_certificate_from_der(&d, &dlen, &sig_alg, &sig, &sig_len, &a, &alen) != 1 + if (x509_certificate_from_der(&tbs, &tbs_len, &sig_alg, &sig, &sig_len, &a, &alen) != 1 || asn1_length_is_zero(alen) != 1) { error_print(); return -1; } + if (asn1_sequence_from_der(&d, &dlen, &tbs, &tbs_len) != 1 + || asn1_length_is_zero(tbs_len) != 1) { + error_print(); + return -1; + } + if (x509_explicit_version_from_der(0, &ver, &d, &dlen) < 0 || asn1_integer_from_der(&serial, &serial_len, &d, &dlen) != 1 || x509_signature_algor_from_der(&inner_sig_alg, &d, &dlen) != 1 diff --git a/src/x509_crl.c b/src/x509_crl.c index 612464bb..3159a8e0 100644 --- a/src/x509_crl.c +++ b/src/x509_crl.c @@ -146,14 +146,11 @@ int x509_crl_entry_ext_id_from_name(const char *name) int x509_crl_entry_ext_id_to_der(int oid, uint8_t **out, size_t *outlen) { const ASN1_OID_INFO *info; - size_t len = 0; if (!(info = asn1_oid_info_from_oid(x509_crl_entry_exts, x509_crl_entry_exts_count, oid))) { error_print(); return -1; } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { error_print(); return -1; } @@ -163,17 +160,15 @@ int x509_crl_entry_ext_id_to_der(int oid, uint8_t **out, size_t *outlen) int x509_crl_entry_ext_id_from_der(int *oid, const uint8_t **in, size_t *inlen) { int ret; - const uint8_t *p; - size_t len; const ASN1_OID_INFO *info; - *oid = 0; if ((ret = asn1_oid_info_from_der(&info, x509_crl_entry_exts, x509_crl_entry_exts_count, in, inlen)) != 1) { - error_print(); - return -1; + if (ret < 0) error_print(); + else *oid = -1; + return ret; } *oid = info->oid; - return ret; + return 1; } int x509_crl_entry_exts_add_reason(uint8_t *exts, size_t *extslen, size_t maxlen, @@ -278,12 +273,15 @@ int x509_revoked_cert_print(FILE *fp, int fmt, int ind, const char *label, const size_t len; time_t tv; + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + if (asn1_integer_from_der(&p, &len, &d, &dlen) != 1) goto err; format_bytes(fp, fmt, ind, "userCertificate", p, len); if (asn1_generalized_time_from_der(&tv, &d, &dlen) != 1) goto err; format_print(fp, fmt, ind, "revocationDate: %s\n", ctime(&tv)); if ((ret = asn1_sequence_from_der(&p, &len, &d, &dlen)) < 0) goto err; - //if (ret) x509_crl_entry_exts_print(fp, fmt, ind, "crlEntryExtensions", p, len); // 这里需要一个函数能够处理 + if (ret) x509_crl_entry_exts_print(fp, fmt, ind, "crlEntryExtensions", p, len); // 这里需要一个函数能够处理 if (asn1_length_is_zero(dlen) != 1) goto err; return 1; err: diff --git a/src/x509_ext.c b/src/x509_ext.c index 63b101c3..012d5168 100644 --- a/src/x509_ext.c +++ b/src/x509_ext.c @@ -423,6 +423,9 @@ int x509_edi_party_name_print(FILE *fp, int fmt, int ind, const char *label, con size_t len; int tag; + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + if ((ret = x509_explicit_directory_name_from_der(0, &tag, &p, &len, &d, &dlen)) < 0) goto err; if (ret) x509_directory_name_print(fp, fmt, ind, "nameAssigner", tag, p, len); if (x509_explicit_directory_name_from_der(1, &tag, &p, &len, &d, &dlen) != 1) goto err; @@ -443,13 +446,27 @@ int x509_general_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t int x509_general_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) { - int ret, tag; + int ret; + int tag; if ((ret = asn1_any_type_from_der(&tag, d, dlen, in, inlen)) != 1) { if (ret < 0) error_print(); return ret; } - - return -1; + switch (tag) { + case ASN1_TAG_IMPLICIT(0): *choice = 0; break; + case ASN1_TAG_IMPLICIT(1): *choice = 1; break; + case ASN1_TAG_IMPLICIT(2): *choice = 2; break; + case ASN1_TAG_IMPLICIT(3): *choice = 3; break; + case ASN1_TAG_IMPLICIT(4): *choice = 4; break; + case ASN1_TAG_IMPLICIT(5): *choice = 5; break; + case ASN1_TAG_IMPLICIT(6): *choice = 6; break; + case ASN1_TAG_IMPLICIT(7): *choice = 7; break; + case ASN1_TAG_IMPLICIT(8): *choice = 8; break; + default: + error_print(); + return -1; + } + return 1; } int x509_general_name_print(FILE *fp, int fmt, int ind, const char *label, int choice, const uint8_t *d, size_t dlen) @@ -486,8 +503,15 @@ int x509_general_name_print(FILE *fp, int fmt, int ind, const char *label, int c int x509_general_names_add_general_name(uint8_t *gns, size_t *gnslen, size_t maxlen, int choice, const uint8_t *d, size_t dlen) { - error_print(); - return -1; + size_t len = 0; + uint8_t *p = gns + *gnslen; + if (x509_general_name_to_der(choice, d, dlen, NULL, &len) != 1 + || asn1_length_le(*gnslen + len, maxlen) != 1 + || x509_general_name_to_der(choice, d, dlen, &p, gnslen) != 1) { + error_print(); + return -1; + } + return 1; } int x509_general_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) diff --git a/src/x509_oid.c b/src/x509_oid.c index 5d8a3fb8..acdbe03c 100644 --- a/src/x509_oid.c +++ b/src/x509_oid.c @@ -75,24 +75,25 @@ static uint32_t oid_at_country_name[] = { oid_at,6 }; static uint32_t oid_at_serial_number[] = { oid_at,5 }; static uint32_t oid_at_pseudonym[] = { oid_at,65 }; static uint32_t oid_domain_component[] = { 0,9,2342,19200300,100,1,25 }; +static const size_t oid_at_cnt = sizeof(oid_at_name)/sizeof(int); static const ASN1_OID_INFO x509_name_types[] = { - { OID_at_name, "name", oid_at_name, 3 }, - { OID_at_surname, "surname", oid_at_surname, 3 }, - { OID_at_given_name, "givenName", oid_at_given_name, 3 }, - { OID_at_initials, "initials", oid_at_initials, 3 }, - { OID_at_generation_qualifier, "generationQualifier", oid_at_generation_qualifier, 3 }, - { OID_at_common_name, "commonName", oid_at_common_name, 3 }, - { OID_at_locality_name, "localityName", oid_at_locality_name, 3 }, - { OID_at_state_or_province_name, "stateOrProvinceName", oid_at_state_or_province_name, 3 }, - { OID_at_organization_name, "organizationName", oid_at_organization_name, 3 }, - { OID_at_organizational_unit_name, "organizationalUnitName", oid_at_organizational_unit_name, 3 }, - { OID_at_title, "title", oid_at_title, 3 }, - { OID_at_dn_qualifier, "dnQualifier", oid_at_dn_qualifier, 3 }, - { OID_at_country_name, "countryName", oid_at_country_name, 3 }, - { OID_at_serial_number, "serialNumber", oid_at_serial_number, 3 }, - { OID_at_pseudonym, "pseudonym", oid_at_pseudonym, 3 }, - { OID_domain_component, "domainComponent", oid_domain_component, 7 }, + { OID_at_name, "name", oid_at_name, oid_at_cnt }, + { OID_at_surname, "surname", oid_at_surname, oid_at_cnt }, + { OID_at_given_name, "givenName", oid_at_given_name, oid_at_cnt }, + { OID_at_initials, "initials", oid_at_initials, oid_at_cnt }, + { OID_at_generation_qualifier, "generationQualifier", oid_at_generation_qualifier, oid_at_cnt }, + { OID_at_common_name, "commonName", oid_at_common_name, oid_at_cnt }, + { OID_at_locality_name, "localityName", oid_at_locality_name, oid_at_cnt }, + { OID_at_state_or_province_name, "stateOrProvinceName", oid_at_state_or_province_name, oid_at_cnt }, + { OID_at_organization_name, "organizationName", oid_at_organization_name, oid_at_cnt }, + { OID_at_organizational_unit_name, "organizationalUnitName", oid_at_organizational_unit_name, oid_at_cnt }, + { OID_at_title, "title", oid_at_title, oid_at_cnt }, + { OID_at_dn_qualifier, "dnQualifier", oid_at_dn_qualifier, oid_at_cnt }, + { OID_at_country_name, "countryName", oid_at_country_name, oid_at_cnt }, + { OID_at_serial_number, "serialNumber", oid_at_serial_number, oid_at_cnt }, + { OID_at_pseudonym, "pseudonym", oid_at_pseudonym, oid_at_cnt }, + { OID_domain_component, "domainComponent", oid_domain_component, sizeof(oid_domain_component)/sizeof(int) }, }; static const int x509_name_types_count @@ -121,14 +122,11 @@ int x509_name_type_from_name(const char *name) int x509_name_type_to_der(int oid, uint8_t **out, size_t *outlen) { const ASN1_OID_INFO *info; - size_t len = 0; if (!(info = asn1_oid_info_from_oid(x509_name_types, x509_name_types_count, oid))) { error_print(); return -1; } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { error_print(); return -1; } @@ -138,18 +136,11 @@ int x509_name_type_to_der(int oid, uint8_t **out, size_t *outlen) int x509_name_type_from_der(int *oid, const uint8_t **in, size_t *inlen) { int ret; - const uint8_t *d; - size_t dlen; const ASN1_OID_INFO *info; - *oid = 0; - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if ((ret = asn1_oid_info_from_der(&info, x509_name_types, x509_name_types_count, in, inlen)) != 1) { if (ret < 0) error_print(); - return ret; - } - if ((ret = asn1_oid_info_from_der(&info, x509_name_types, x509_name_types_count, &d, &dlen)) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); + else *oid = -1; return ret; } *oid = info->oid; @@ -172,23 +163,24 @@ static uint32_t oid_ce_policy_constraints[] = { oid_ce,36 }; static uint32_t oid_ce_ext_key_usage[] = { oid_ce,37 }; static uint32_t oid_ce_freshest_crl[] = { oid_ce,46 }; static uint32_t oid_ce_inhibit_any_policy[] = { oid_ce,54 }; +static const size_t oid_ce_cnt = sizeof(oid_ce_subject_directory_attributes)/sizeof(int); static const ASN1_OID_INFO x509_ext_ids[] = { - { OID_ce_authority_key_identifier, "AuthorityKeyIdentifier", oid_ce_authority_key_identifier, 4 }, - { OID_ce_subject_key_identifier, "SubjectKeyIdentifier", oid_ce_subject_key_identifier, 4 }, - { OID_ce_key_usage, "KeyUsage", oid_ce_key_usage, 4 }, - { OID_ce_certificate_policies, "CertificatePolicies", oid_ce_certificate_policies, 4 }, - { OID_ce_policy_mappings, "PolicyMappings", oid_ce_policy_mappings, 4 }, - { OID_ce_subject_alt_name, "SubjectAltName", oid_ce_subject_alt_name, 4 }, - { OID_ce_issuer_alt_name, "IssuerAltName", oid_ce_issuer_alt_name, 4 }, - { OID_ce_subject_directory_attributes, "SubjectDirectoryAttributes", oid_ce_subject_directory_attributes, 4 }, - { OID_ce_basic_constraints, "BasicConstraints", oid_ce_basic_constraints, 4 }, - { OID_ce_name_constraints, "NameConstraints", oid_ce_name_constraints, 4 }, - { OID_ce_policy_constraints, "PolicyConstraints", oid_ce_policy_constraints, 4 }, - { OID_ce_ext_key_usage, "ExtKeyUsage", oid_ce_ext_key_usage, 4 }, - { OID_ce_crl_distribution_points, "CRLDistributionPoints", oid_ce_crl_distribution_points, 4 }, - { OID_ce_inhibit_any_policy, "InhibitAnyPolicy", oid_ce_inhibit_any_policy, 4 }, - { OID_ce_freshest_crl, "FreshestCRL", oid_ce_freshest_crl, 4 }, + { OID_ce_authority_key_identifier, "AuthorityKeyIdentifier", oid_ce_authority_key_identifier, oid_ce_cnt }, + { OID_ce_subject_key_identifier, "SubjectKeyIdentifier", oid_ce_subject_key_identifier, oid_ce_cnt }, + { OID_ce_key_usage, "KeyUsage", oid_ce_key_usage, oid_ce_cnt }, + { OID_ce_certificate_policies, "CertificatePolicies", oid_ce_certificate_policies, oid_ce_cnt }, + { OID_ce_policy_mappings, "PolicyMappings", oid_ce_policy_mappings, oid_ce_cnt }, + { OID_ce_subject_alt_name, "SubjectAltName", oid_ce_subject_alt_name, oid_ce_cnt }, + { OID_ce_issuer_alt_name, "IssuerAltName", oid_ce_issuer_alt_name, oid_ce_cnt }, + { OID_ce_subject_directory_attributes, "SubjectDirectoryAttributes", oid_ce_subject_directory_attributes, oid_ce_cnt }, + { OID_ce_basic_constraints, "BasicConstraints", oid_ce_basic_constraints, oid_ce_cnt }, + { OID_ce_name_constraints, "NameConstraints", oid_ce_name_constraints, oid_ce_cnt }, + { OID_ce_policy_constraints, "PolicyConstraints", oid_ce_policy_constraints, oid_ce_cnt }, + { OID_ce_ext_key_usage, "ExtKeyUsage", oid_ce_ext_key_usage, oid_ce_cnt }, + { OID_ce_crl_distribution_points, "CRLDistributionPoints", oid_ce_crl_distribution_points, oid_ce_cnt }, + { OID_ce_inhibit_any_policy, "InhibitAnyPolicy", oid_ce_inhibit_any_policy, oid_ce_cnt }, + { OID_ce_freshest_crl, "FreshestCRL", oid_ce_freshest_crl, oid_ce_cnt }, }; static const int x509_ext_ids_count = @@ -217,35 +209,30 @@ int x509_ext_id_from_name(const char *name) int x509_ext_id_to_der(int oid, uint8_t **out, size_t *outlen) { const ASN1_OID_INFO *info; - size_t len = 0; if (!(info = asn1_oid_info_from_oid(x509_ext_ids, x509_ext_ids_count, oid))) { error_print(); return -1; } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { error_print(); return -1; } return 1; } -// 不同于X509算法,X509扩展的数量比较多,而且很多没有在RFC中,而是由某些大公司给出的, 因此这个函数接口要返回nodes +// 如果要支持未知的ext_id,应该提供一个callback int x509_ext_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen) { int ret; - const uint8_t *p; - size_t len; const ASN1_OID_INFO *info; - *oid = 0; if ((ret = asn1_oid_info_from_der_ex(&info, nodes, nodes_cnt, x509_ext_ids, x509_ext_ids_count, in, inlen)) != 1) { - error_print(); - return -1; + if (ret < 0) error_print(); + else *oid = -1; + return ret; } - *oid = info->oid; - return ret; + *oid = info ? info->oid : 0; + return 1; } @@ -300,6 +287,7 @@ int x509_qualifier_id_from_der(int *oid, const uint8_t **in, size_t *inlen) const ASN1_OID_INFO *info; if ((ret = asn1_oid_info_from_der(&info, x509_qt_ids, x509_qt_ids_count, in, inlen)) != 1) { if (ret < 0) error_print(); + else *oid = -1; return ret; } *oid = info->oid; @@ -307,6 +295,22 @@ int x509_qualifier_id_from_der(int *oid, const uint8_t **in, size_t *inlen) } +int x509_cert_policy_id_from_name(const char *name) +{ + if (strcmp(name, "anyPolicy") == 0) { + return OID_any_policy; + } + return OID_undef; +} + +char *x509_cert_policy_id_name(int oid) +{ + switch (oid) { + case OID_any_policy: return "anyPolicy"; + } + return NULL; +} + static uint32_t oid_any_policy[] = { oid_ce,32,0 }; int x509_cert_policy_id_to_der(int oid, const uint32_t *nodes, size_t nodes_cnt, uint8_t **out, size_t *outlen) @@ -334,9 +338,9 @@ int x509_cert_policy_id_to_der(int oid, const uint32_t *nodes, size_t nodes_cnt, int x509_cert_policy_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen) { int ret; - *oid = OID_undef; if ((ret = asn1_object_identifier_from_der(nodes, nodes_cnt, in, inlen)) != 1) { if (ret < 0) error_print(); + *oid = -1; return ret; } if (*nodes_cnt == sizeof(oid_any_policy)/sizeof(int) @@ -346,23 +350,6 @@ int x509_cert_policy_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, c return 1; } -int x509_cert_policy_id_from_name(const char *name) -{ - if (strcmp(name, "anyPolicy") == 0) { - return OID_any_policy; - } - return OID_undef; -} - -char *x509_cert_policy_id_name(int oid) -{ - switch (oid) { - case OID_any_policy: return "anyPolicy"; - } - return NULL; -} - - #define oid_kp oid_pkix,3 @@ -372,15 +359,16 @@ static uint32_t oid_kp_code_signing[] = { oid_kp,3 }; static uint32_t oid_kp_email_protection[] = { oid_kp,4 }; static uint32_t oid_kp_time_stamping[] = { oid_kp,8 }; static uint32_t oid_kp_ocsp_signing[] = { oid_kp,9 }; +static const size_t oid_kp_cnt = sizeof(oid_kp_server_auth)/sizeof(int); static const ASN1_OID_INFO x509_key_purposes[] = { - { OID_kp_server_auth, "serverAuth", oid_kp_server_auth, 9, 0, "TLS WWW server authentication" }, - { OID_kp_client_auth, "clientAuth", oid_kp_client_auth, 9, 0, "TLS WWW client authentication" }, - { OID_kp_code_signing, "codeSigning", oid_kp_code_signing, 9, 0, "Signing of downloadable executable code" }, - { OID_kp_email_protection, "emailProtection", oid_kp_email_protection, 9, 0, "Email protection" }, - { OID_kp_time_stamping, "timeStamping", oid_kp_time_stamping, 9, 0, "Binding the hash of an object to a time" }, - { OID_kp_ocsp_signing, "OCSPSigning", oid_kp_ocsp_signing, 9, 0, "Signing OCSP responses" }, + { OID_kp_server_auth, "serverAuth", oid_kp_server_auth, oid_kp_cnt, 0, "TLS WWW server authentication" }, + { OID_kp_client_auth, "clientAuth", oid_kp_client_auth, oid_kp_cnt, 0, "TLS WWW client authentication" }, + { OID_kp_code_signing, "codeSigning", oid_kp_code_signing, oid_kp_cnt, 0, "Signing of downloadable executable code" }, + { OID_kp_email_protection, "emailProtection", oid_kp_email_protection, oid_kp_cnt, 0, "Email protection" }, + { OID_kp_time_stamping, "timeStamping", oid_kp_time_stamping, oid_kp_cnt, 0, "Binding the hash of an object to a time" }, + { OID_kp_ocsp_signing, "OCSPSigning", oid_kp_ocsp_signing, oid_kp_cnt, 0, "Signing OCSP responses" }, }; static const int x509_key_purposes_count = @@ -434,9 +422,9 @@ int x509_key_purpose_from_der(int *oid, const uint8_t **in, size_t *inlen) { int ret; const ASN1_OID_INFO *info; - if ((ret = asn1_oid_info_from_der(&info, x509_key_purposes, x509_key_purposes_count, in, inlen)) != 1) { if (ret < 0) error_print(); + else *oid = 0; return ret; } *oid = info->oid; diff --git a/src/x509_prn.c b/src/x509_prn.c deleted file mode 100644 index d518db8f..00000000 --- a/src/x509_prn.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Copyright (c) 2014 - 2020 The GmSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the GmSSL Project. - * (http://gmssl.org/)" - * - * 4. The name "GmSSL Project" must not be used to endorse or promote - * products derived from this software without prior written - * permission. For written permission, please contact - * guanzhi1980@gmail.com. - * - * 5. Products derived from this software may not be called "GmSSL" - * nor may "GmSSL" appear in their names without prior written - * permission of the GmSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the GmSSL Project - * (http://gmssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -int x509_other_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - uint32_t nodes[32]; - size_t nodes_count; - const uint8_t *value; - size_t valuelen; - - format_print(fp, fmt, ind, "%s:\n", label); - ind += 4; - if (asn1_object_identifier_from_der(nodes, &nodes_count, &d, &dlen) != 1 - || asn1_explicit_from_der(0, &value, &valuelen, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - asn1_oid_nodes_print(fp, fmt, ind, "type-id", "unknown", nodes, nodes_count); - format_bytes(fp, fmt, ind, "value: ", value, valuelen); - return 1; -} - -int x509_edi_party_name_print(FILE *fp, int fmt, int ind, const char *label,const uint8_t *d, size_t dlen) -{ - const uint8_t *name_assigner; - const uint8_t *party_name; - size_t name_assigner_len, party_name_len; - - format_print(fp, fmt, ind, "%s:\n", label); - ind += 4; - if (asn1_explicit_from_der(0, &name_assigner, &name_assigner_len, &d, &dlen) < 0 - || asn1_explicit_from_der(1, &party_name, &party_name_len, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (name_assigner) { - if (x509_directory_string_print(fp, fmt, ind, "nameAssigner", - name_assigner, name_assigner_len) != 1) { - error_print(); - return -1; - } - } - if (x509_directory_string_print(fp, fmt, ind, "partyName", party_name, party_name_len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_general_name_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen) -{ - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - switch (tag) { - case ASN1_TAG_IMPLICIT(0): return x509_other_name_print(fp, fmt, ind, "otherName", d, dlen); - case ASN1_TAG_IMPLICIT(1): return asn1_string_print(fp, fmt, ind, "rfc822Name", (char *)d, dlen); - case ASN1_TAG_IMPLICIT(2): return asn1_string_print(fp, fmt, ind, "DNSName", (char *)d, dlen); - case ASN1_TAG_IMPLICIT(3): return format_bytes(fp, fmt, ind, "x400Address", d, dlen); - case ASN1_TAG_IMPLICIT(4): return x509_name_print(fp, fmt, ind, "directoryName", d, dlen); - case ASN1_TAG_IMPLICIT(5): return x509_edi_party_name_print(fp, fmt, ind, "ediPartyName", d, dlen); - case ASN1_TAG_IMPLICIT(6): return asn1_string_print(fp, fmt, ind, "URI", (char *)d, dlen); - case ASN1_TAG_IMPLICIT(7): return format_bytes(fp, fmt, ind, "IPAddress", d, dlen); - case ASN1_TAG_IMPLICIT(8): return asn1_object_identifier_print(fp, fmt, ind, "registeredID", d, dlen); - default: - error_print(); - return -1; - } - return 1; -} - -int x509_general_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - int tag; - const uint8_t *p; - size_t len; - if (asn1_any_type_from_der(&tag, &p, &len, &d, &dlen) != 1 - || x509_general_name_print(fp, fmt, ind, NULL, tag, p, len) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int x509_key_usage_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int usage; - if (asn1_bits_from_der(&usage, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "keyUsage:\n"); - ind += 4; - - if (usage & X509_KU_DIGITAL_SIGNATURE) - format_print(fp, fmt, ind, "DigitalSignature\n"); - if (usage & X509_KU_NON_REPUDIATION) - format_print(fp, fmt, ind, "NonRepudiation\n"); - if (usage & X509_KU_KEY_ENCIPHERMENT) - format_print(fp, fmt, ind, "KeyEncipherment\n"); - if (usage & X509_KU_DATA_ENCIPHERMENT) - format_print(fp, fmt, ind, "DataEncipherment\n"); - if (usage & X509_KU_KEY_AGREEMENT) - format_print(fp, fmt, ind, "KeyAgreement\n"); - if (usage & X509_KU_KEY_CERT_SIGN) - format_print(fp, fmt, ind, "KeyCertSign\n"); - if (usage & X509_KU_CRL_SIGN) - format_print(fp, fmt, ind, "CRLSign\n"); - if (usage & X509_KU_ENCIPHER_ONLY) - format_print(fp, fmt, ind, "EncipherOnly\n"); - if (usage & X509_KU_DECIPHER_ONLY) - format_print(fp, fmt, ind, "DecipherOnly\n"); - - - return 1; -} - -int x509_authority_key_identifier_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *keyid, *issuer, *serial; - size_t keyid_len, issuer_len, serial_len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_implicit_octet_string_from_der(0, &keyid, &keyid_len, &d, &dlen) < 0 - || asn1_implicit_sequence_from_der(1, &issuer, &issuer_len, &d, &dlen) < 0 - || asn1_implicit_integer_from_der(2, &serial, &serial_len, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (keyid) { - format_bytes(fp, fmt, ind, "keyIdentifier : ", keyid, keyid_len); - } - if (issuer) { - x509_general_names_print(fp, fmt, ind, "authorityCertIssuer", issuer, issuer_len); - } - if (serial) { - format_bytes(fp, fmt, ind, "authorityCertSerialNumber", serial, serial_len); - } - return 1; -} - - - -int x509_policy_information_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1) goto err; - - - return 1; -} - -int x509_certificate_policies_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - while (dlen) { - const uint8_t *p; - size_t len; - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - if (x509_policy_information_print(fp, fmt, ind, "PolicyInformation", p, len) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int x509_policy_mapping_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - return 1; -} - -int x509_policy_mappings_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - while (dlen) { - const uint8_t *p; - size_t len; - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1 - || x509_policy_mapping_print(fp, fmt, ind, "PolicyMapping", p, len) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int x509_attribute_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - return 1; -} - -int x509_attributes_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - while (dlen) { - const uint8_t *p; - size_t len; - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1 - || x509_attribute_print(fp, fmt, ind, "Attribute", p, len) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int x509_basic_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret; - int val; - - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - - if ((ret = asn1_boolean_from_der(&val, &d, &dlen)) < 0) goto err; - else if (ret) - format_print(fp, fmt, ind, "cA: %s\n", val ? "true" : "false"); - - if ((ret = asn1_int_from_der(&val, &d, &dlen)) < 0) goto err; - else if (ret) - format_print(fp, fmt, ind, "pathLenConstraint: %d\n", val); - - return 1; -err: - error_print(); - return -1; -} - -int x509_general_subtree_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret; - int val; - const uint8_t *p; - size_t len; - - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - if (asn1_any_type_from_der(&val, &p, &len, &d, &dlen) != 1) goto err; - if (x509_general_name_print(fp, fmt, ind, "base", val, p, len) != 1) goto err; - if ((ret = asn1_implicit_int_from_der(0, &val, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "minimum: %d\n", val); - if ((ret = asn1_implicit_int_from_der(0, &val, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "maximum: %d\n", val); - if (dlen) { - format_bytes(fp, fmt, ind, "", d, dlen); - goto err; - } - return 1; -err: - error_print(); - return -1; -} - -int x509_general_subtrees_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - while (dlen) { - const uint8_t *p; - size_t len; - - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1 - || x509_general_subtree_print(fp, fmt, ind, "GeneralSubtree", p, len) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int x509_name_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret; - const uint8_t *p; - size_t len; - - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - - if ((ret = asn1_sequence_from_der(&p, &len, &d, &dlen)) < 0) goto err; - if (ret) { - x509_general_subtrees_print(fp, fmt, ind, "permittedSubtrees", p, len); - } - - if ((ret = asn1_sequence_from_der(&p, &len, &d, &dlen)) < 0) goto err; - if (ret) { - x509_general_subtrees_print(fp, fmt, ind, "excludedSubtrees", p, len); - } - if (dlen) { - } - - return 1; -err: - error_print(); - return -1; -} - -int x509_policy_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret; - int val; - - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - - if ((ret = asn1_implicit_int_from_der(0, &val, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "requireExplicitPolicy: %d\n", val); - if ((ret = asn1_implicit_int_from_der(0, &val, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "inhibitPolicyMapping: %d\n", val); - if (dlen) { - format_bytes(fp, fmt, ind, "", d, dlen); - goto err; - } - return 1; -err: - error_print(); - return -1; -} - -int x509_ext_key_usage_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - while (dlen) { - int oid; - if (x509_key_purpose_from_der(&oid, &d, &dlen) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "%s\n", x509_key_purpose_name(oid)); - } - return 1; -} - -int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - return -1; -} - -int x509_reason_flags_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - return -1; -} - -int x509_distribution_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret; - int val; - const uint8_t *p; - size_t len; - - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - if ((ret = asn1_explicit_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) { - if (x509_distribution_point_name_print(fp, fmt, ind, "distributionPoint", p, len) != 1) { - error_print(); - return -1; - } - } - - if ((ret = asn1_implicit_bits_from_der(1, &val, &d, &dlen)) < 0) goto err; - if (ret) { - x509_reason_flags_print(fp, fmt, ind, "reasons", p, len); - } - - if ((ret = asn1_implicit_sequence_from_der(2, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) { - x509_general_names_print(fp, fmt, ind, "cRLIssuer", p, len); - } - if (dlen) { - format_bytes(fp, fmt, ind, "", d, dlen); - goto err; - } - return 1; - -err: - error_print(); - return -1; -} - -int x509_crl_distribution_points_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - while (dlen) { - const uint8_t *p; - size_t len; - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - if (x509_distribution_point_print(fp, fmt, ind, "DistributionPoint", p, len) != 1) { - error_print(); - return -1; - } - } - return 1; -} - - -int x509_directory_string_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) -{ - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - return -1; -} diff --git a/src/x509_req.c b/src/x509_req.c index 859b8a7c..74443496 100644 --- a/src/x509_req.c +++ b/src/x509_req.c @@ -350,7 +350,7 @@ int x509_req_get_details(const uint8_t *req, size_t reqlen, return 1; } -int x509_req_print(FILE *fp, int fmt, int ind, const uint8_t *req, size_t reqlen) +int x509_req_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *req, size_t reqlen) { const uint8_t *d; size_t dlen; @@ -360,7 +360,7 @@ int x509_req_print(FILE *fp, int fmt, int ind, const uint8_t *req, size_t reqlen error_print(); return -1; } - x509_request_print(fp, fmt, ind, "CertificationRequest", d, dlen); + x509_request_print(fp, fmt, ind, label, d, dlen); return 1; } diff --git a/src/x509_str.c b/src/x509_str.c index 6b084357..96277d32 100644 --- a/src/x509_str.c +++ b/src/x509_str.c @@ -105,6 +105,7 @@ int x509_directory_name_check_ex(int tag, const uint8_t *d, size_t dlen, size_t return -1; } if (dlen < minlen || dlen > maxlen) { + printf("%s %d: dlen = %zu, minlen = %zu, maxlne = %zu\n", __FILE__, __LINE__, dlen, minlen, maxlen); error_print(); return -1; } diff --git a/tests/aestest.c b/tests/aestest.c index f7ae56c3..426b1399 100644 --- a/tests/aestest.c +++ b/tests/aestest.c @@ -55,50 +55,6 @@ #include -int test_aes_ctr(void) -{ - // NIST SP 800-38A F.5.1 - char *hex_key = "2b7e151628aed2a6abf7158809cf4f3c"; - char *hex_ctr = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; - char *hex_msg = "6bc1bee22e409f96e93d7e117393172a" - "ae2d8a571e03ac9c9eb76fac45af8e51" - "30c81c46a35ce411e5fbc1191a0a52ef" - "f69f2445df4f9b17ad2b417be66c3710"; - char *hex_out = "874d6191b620e3261bef6864990db6ce" - "9806f66b7970fdff8617187bb9fffdff" - "5ae4df3edbd5d35e5b4f09020db03eab" - "1e031dda2fbe03d1792170a0f3009cee"; - - int err = 0; - AES_KEY aes_key; - uint8_t key[32]; - uint8_t ctr[16]; - uint8_t msg[64]; - uint8_t out[64]; - uint8_t buf[64]; - size_t keylen, ctrlen, msglen, outlen, buflen; - - hex_to_bytes(hex_key, strlen(hex_key), key, &keylen); - hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen); - hex_to_bytes(hex_msg, strlen(hex_msg), msg, &msglen); - hex_to_bytes(hex_out, strlen(hex_out), out, &outlen); - - aes_set_encrypt_key(&aes_key, key, keylen); - aes_ctr_encrypt(&aes_key, ctr, msg, msglen, buf); - buflen = msglen; - - format_bytes(stdout, 0, 0, "aes_ctr(msg) = ", buf, buflen); - format_bytes(stdout, 0, 0, " = ", out, outlen); - - hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen); - aes_ctr_encrypt(&aes_key, ctr, buf, buflen, buf); - format_bytes(stdout, 0, 0, "msg = ", msg, msglen); - format_bytes(stdout, 0, 0, " = ", buf, buflen); - - return 1; -} - - int test_aes(void) { int err = 0; @@ -230,7 +186,65 @@ int test_aes(void) printf("ok\n"); } - return 0; + return err; +} + +int test_aes_ctr(void) +{ + int err = 0; + + // NIST SP 800-38A F.5.1 + char *hex_key = "2b7e151628aed2a6abf7158809cf4f3c"; + char *hex_ctr = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; + char *hex_msg = "6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"; + char *hex_out = "874d6191b620e3261bef6864990db6ce" + "9806f66b7970fdff8617187bb9fffdff" + "5ae4df3edbd5d35e5b4f09020db03eab" + "1e031dda2fbe03d1792170a0f3009cee"; + + AES_KEY aes_key; + uint8_t key[32]; + uint8_t ctr[16]; + uint8_t msg[64]; + uint8_t out[64]; + uint8_t buf[64]; + size_t keylen, ctrlen, msglen, outlen, buflen; + + hex_to_bytes(hex_key, strlen(hex_key), key, &keylen); + hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen); + hex_to_bytes(hex_msg, strlen(hex_msg), msg, &msglen); + hex_to_bytes(hex_out, strlen(hex_out), out, &outlen); + + aes_set_encrypt_key(&aes_key, key, keylen); + aes_ctr_encrypt(&aes_key, ctr, msg, msglen, buf); + buflen = msglen; + + printf("aes ctr test 1 "); + if (memcmp(buf, out, outlen) != 0) { + printf("failed\n"); + err++; + format_bytes(stdout, 0, 0, "aes_ctr(msg) = ", buf, buflen); + format_bytes(stdout, 0, 0, " != ", out, outlen); + } else { + printf("ok\n"); + } + + printf("aes ctr test 2 "); + hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen); + aes_ctr_decrypt(&aes_key, ctr, buf, buflen, buf); + if (memcmp(buf, msg, msglen) != 0) { + printf("failed\n"); + format_bytes(stdout, 0, 0, "msg = ", msg, msglen); + format_bytes(stdout, 0, 0, " = ", buf, buflen); + err++; + } else { + printf("ok\n"); + } + + return err; } @@ -340,6 +354,7 @@ struct { int test_aes_gcm(void) { + int err = 0; uint8_t K[32]; uint8_t P[64]; uint8_t A[32]; @@ -354,8 +369,6 @@ int test_aes_gcm(void) uint8_t buf[64]; int i; - printf("%s\n", __FUNCTION__); - for (i = 0; i < sizeof(aes_gcm_tests)/sizeof(aes_gcm_tests[0]); i++) { int ok = 1; @@ -369,43 +382,33 @@ int test_aes_gcm(void) aes_set_encrypt_key(&aes_key, K, Klen); aes_gcm_encrypt(&aes_key, IV, IVlen, A, Alen, P, Plen, out, Tlen, tag); - if (aes_gcm_decrypt(&aes_key, IV, IVlen, A, Alen, out, Plen, tag, Tlen, buf) != 1) { - error_print(); - ok = 0; + printf("aes gcm test %d ", i + 1); + if (aes_gcm_decrypt(&aes_key, IV, IVlen, A, Alen, out, Plen, tag, Tlen, buf) != 1 + || memcmp(buf, P, Plen) != 0) { + printf("failed\n"); + format_print(stdout, 0, 2, "K = %s\n", aes_gcm_tests[i].K); + format_print(stdout, 0, 2, "P = %s\n", aes_gcm_tests[i].P); + format_print(stdout, 0, 2, "A = %s\n", aes_gcm_tests[i].A); + format_print(stdout, 0, 2, "IV = %s\n", aes_gcm_tests[i].IV); + format_print(stdout, 0, 2, "C = %s\n", aes_gcm_tests[i].C); + format_bytes(stdout, 0, 2, " = ", out, Plen); + format_print(stdout, 0, 2, "T = %s\n", aes_gcm_tests[i].T); + format_bytes(stdout, 0, 2, " = ", tag, Tlen); + err++; + } else { + printf("ok\n"); } - if (memcmp(buf, P, Plen) != 0) { - error_print(); - ok = 0; - } - - printf(" test %d %s\n", i + 1, ok ? "ok" : "error"); - - /* - format_print(stdout, 0, 2, "K = %s\n", aes_gcm_tests[i].K); - format_print(stdout, 0, 2, "P = %s\n", aes_gcm_tests[i].P); - format_print(stdout, 0, 2, "A = %s\n", aes_gcm_tests[i].A); - format_print(stdout, 0, 2, "IV = %s\n", aes_gcm_tests[i].IV); - format_print(stdout, 0, 2, "C = %s\n", aes_gcm_tests[i].C); - format_bytes(stdout, 0, 2, " = ", out, Plen); - format_print(stdout, 0, 2, "T = %s\n", aes_gcm_tests[i].T); - format_bytes(stdout, 0, 2, " = ", tag, Tlen); - printf("\n"); - */ } - return 0; + return err; } - - - - - int main(void) { - test_aes(); - test_aes_ctr(); - test_aes_gcm(); - return 0; + int err = 0; + err += test_aes(); + err += test_aes_ctr(); + err += test_aes_gcm(); + return err; } diff --git a/tests/asn1test.c b/tests/asn1test.c index 052f5fce..de0c326a 100644 --- a/tests/asn1test.c +++ b/tests/asn1test.c @@ -53,22 +53,6 @@ #include #include -#define BOOL_1 0 -#define BOOL_2 1 - -#define INT_1 "\x00" -#define INT_2 "\x7f" -#define INT_3 "\x80" -#define INT_4 "\xff\xf0" - -#define BITS_1 "\xff\xf0" -#define BITS_1_LEN 12 - -#define OCTETS_1 "\x12\x34\x45\x56" - - -#if 0 - static void print_buf(const uint8_t *a, size_t len) { size_t i; @@ -110,342 +94,432 @@ static void print_octets(const uint8_t *o, size_t olen) static int test_asn1_tag(void) { - int i = 0; - for (i = 0; i < 32; i++) { - printf("%s\n", asn1_tag_name(i)); + int i; + format_print(stderr, 0, 0, "Tags:\n"); + for (i = 1; i <= 13; i++) { + format_print(stderr, 0, 4, "%s (0x%02x)\n", asn1_tag_name(i), i); } + for (i = 18; i <= 30; i++) { + format_print(stderr, 0, 4, "%s (0x%02x)\n", asn1_tag_name(i), i); + } + printf("%s() ok\n", __FUNCTION__); return 0; } static int test_asn1_length(void) { - int err = 0; - size_t tests[] = {5, 127, 128, 256, 65537, 1<<23, (size_t)1<<31, }; - size_t val; - uint8_t buf[1024] = {0}; + size_t tests[] = { + 0, + 5, + 127, + 128, + 256, + 344, + 65537, + 1<<23, + (size_t)1<<31, + }; + size_t length; + uint8_t buf[256]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - size_t left = ((size_t)1 << 32); size_t i; - int rv; - printf("%s\n", __FUNCTION__); + format_print(stderr, 0, 0, "Length:\n"); for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - printf("%zu ", tests[i]); - } - printf("\n"); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - asn1_length_to_der(tests[i], &p, &len); - print_buf(buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - rv = asn1_length_from_der(&val, &cp, &left); - assert(rv > 0); - if (val != tests[i]) { - error_print_msg("error decoding %zu-th length: get %zu, should be %zu", i, val, tests[i]); - err++; + if (asn1_length_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + int ret; + ret = asn1_length_from_der(&length, &cp, &len); + if (ret != 1 && ret != -2) { + error_print(); + return -1; + } + if (length != tests[i]) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%zd\n", length); + } + if (len != 0) { + error_print(); + return -1; } - printf("\n"); - return err; + printf("%s() ok\n", __FUNCTION__); + return 0; } static int test_asn1_boolean(void) { - int err = 0; int tests[] = {0, 1}; int val; - uint8_t buf[1024] = {0}; + uint8_t buf[128] = {0}; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - size_t left = sizeof(buf); size_t i; - int rv; - printf("%s\n", __FUNCTION__); + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_BOOLEAN)); for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - printf("%d ", tests[i]); - } - printf("\n"); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - asn1_boolean_to_der(tests[i], &p, &len); - print_buf(buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - rv = asn1_boolean_from_der(&val, &cp, &left); - assert(rv > 0); - if (val != tests[i]) { - error_print_msg("error decoding %zu-th: get %d, should be %d", i, val, tests[i]); - err++; + if (asn1_boolean_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_boolean_from_der(&val, &cp, &len) != 1 + || asn1_check(val == tests[i]) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", val ? "true" : "false"); + } + if (len != 0) { + error_print(); + return -1; } - printf("\n"); - return err; + printf("%s() ok\n", __FUNCTION__); + return 0; } -static int test_asn1_integer(void) +static int test_asn1_int(void) { - int err = 0; - int tests[] = {1, 127, 128, 65535, 65537, 1<<23, 1<<30, /* 0, -1 */ }; + int tests[] = { + 0, + 1, + 127, + 128, + 65535, + 65537, + 1<<23, + 1<<30, + }; int val; - uint8_t buf[1024] = {0}; + uint8_t buf[256] = {0}; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - size_t left = sizeof(buf); size_t i; int rv; - printf("%s\n", __FUNCTION__); + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_INTEGER)); for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - printf("%d ", tests[i]); - } - printf("\n"); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - asn1_int_to_der(tests[i], &p, &len); - print_buf(buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - rv = asn1_int_from_der(&val, &cp, &left); - assert(rv > 0); - if (val != tests[i]) { - error_print_msg("error decoding %zu-th: get %d, should be %d", i, val, tests[i]); - err++; + if (asn1_int_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; } + format_bytes(stderr, 0, 4, "", buf, len); + } + // 测试 -1 表示默认不编码 + if (asn1_int_to_der(-1, &p, &len) != 0) { + error_print(); + return -1; } - printf("\n"); - return err; + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_int_from_der(&val, &cp, &len) != 1 + || asn1_check(val == tests[i]) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%d\n", val); + } + if (len != 0) { + error_print(); + return -1; + } + + // 测试返回0时是否对val值做初始化 + if (asn1_int_from_der(&val, &cp, &len) != 0) { + error_print(); + return -1; + } + if (val != -1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 0; } -static int test_asn1_bit_string(void) +static int test_asn1_bits(void) { - int err = 0; - int tests[] = {1, 0xfe, 0xff, 0xffff, 0xfffff }; - int val; - uint8_t buf[1024] = {0}; + int tests[] = { + 0x01, + 0x02, + 0x03, + 0x7f, + 0xfe, + 0xff, + 0xffff, + 0xfffff, + }; + uint8_t der[] = { + 0x03,0x02,0x07,0x80, + 0x03,0x02,0x06,0x40, + 0x03,0x02,0x06,0xC0, + 0x03,0x02,0x01,0xFE, + 0x03,0x02,0x00,0x7F, + 0x03,0x02,0x00,0xFF, + 0x03,0x03,0x00,0xFF,0xFF, + 0x03,0x04,0x04,0xFF,0xFF,0xF0, + }; + int bits; + uint8_t buf[256]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - size_t left = sizeof(buf); size_t i; - int rv; - printf("%s\n", __FUNCTION__); + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_BIT_STRING)); for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - printf("%d ", tests[i]); - } - printf("\n"); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - asn1_bits_to_der(tests[i], &p, &len); - print_buf(buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - rv = asn1_bits_from_der(&val, &cp, &left); - assert(rv > 0); - if (val != tests[i]) { - error_print_msg("error decoding %zu-th: get %d, should be %d", i, val, tests[i]); - err++; + if (asn1_bits_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; } + format_bytes(stderr, 0, 4, "", buf, len); } - - printf("\n"); - return err; + if (sizeof(der) != len + || memcmp(der, buf, len) != 0) { + error_print(); + return -1; + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_bits_from_der(&bits, &cp, &len) != 1 + || asn1_check(bits == tests[i]) != 1) { + error_print(); + return 1; + } + format_print(stderr, 0, 4, "%x\n", bits); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 0; } static int test_asn1_null(void) { - int err = 0; - int tests[6]; - uint8_t buf[1024] = {0}; + uint8_t buf[256] = {0}; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - size_t left = sizeof(buf); size_t i; - int rv; - printf("%s\n", __FUNCTION__); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - printf("null "); + format_print(stderr, 0, 0, "NULL\n"); + for (i = 0; i < 3; i++) { + if (asn1_null_to_der(&p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); } - printf("\n"); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - asn1_null_to_der(&p, &len); - print_buf(buf, len); + for (i = 0; i < 3; i++) { + if (asn1_null_from_der(&cp, &len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", asn1_tag_name(ASN1_TAG_NULL)); } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - rv = asn1_null_from_der(&cp, &left); - assert(rv > 0); + if (asn1_length_is_zero(len) != 1) { + error_print(); + return -1; } - - printf("\n"); - return err; + printf("%s() ok\n", __FUNCTION__); + return 0; } static int test_asn1_object_identifier(void) { int err = 0; - int tests[] = {1, 2, 3, 4, 5, 6}; - int val; - uint32_t nodes[32]; - size_t nodes_count; - uint8_t buf[1024] = {0}; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - size_t left = sizeof(buf); - size_t i; - int rv; + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_OBJECT_IDENTIFIER)); - printf("%s\n", __FUNCTION__); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - printf("%d ", tests[i]); - } - printf("\n"); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - asn1_object_identifier_to_der(tests[i], NULL, 0, &p, &len); - print_buf(buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - rv = asn1_object_identifier_from_der(&val, nodes, &nodes_count, &cp, &left); - assert(rv > 0); - if (val != tests[i]) { - error_print_msg("error decoding %zu-th: get %d, should be %d", i, val, tests[i]); + if (1) { + char *name = "sm2"; + uint32_t oid[] = { 1,2,156,10197,1,301 }; + uint8_t der[] = { 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x82, 0x2D }; + uint32_t nodes[32]; + size_t nodes_cnt; + uint8_t buf[128]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + format_print(stderr, 0 ,4, "%s ", name); + if (asn1_object_identifier_to_der(oid, sizeof(oid)/sizeof(int), &p, &len) != 1 + || asn1_check(len == sizeof(der)) != 1 + || asn1_check(memcmp(buf, der, sizeof(der)) == 0) != 1 + || asn1_object_identifier_from_der(nodes, &nodes_cnt, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1 + || asn1_object_identifier_equ(nodes, nodes_cnt, oid, sizeof(oid)/sizeof(int)) != 1) { + printf("failed\n"); + error_print(); err++; + } else { + printf("ok\n"); } - printf("%s\n", asn1_object_identifier_name(val)); } - printf("\n"); + if (2) { + char *name = "x9.62-ecPublicKey"; + uint32_t oid[] = { 1,2,840,10045,2,1 }; + uint8_t der[] = { 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01 }; + uint8_t buf[128]; + uint32_t nodes[32]; + size_t nodes_cnt; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + format_print(stderr, 0 ,4, "%s ", name); + if (asn1_object_identifier_to_der(oid, sizeof(oid)/sizeof(int), &p, &len) != 1 + || asn1_check(len == sizeof(der)) != 1 + || asn1_check(memcmp(buf, der, sizeof(der)) == 0) != 1 + || asn1_object_identifier_from_der(nodes, &nodes_cnt, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1 + || asn1_object_identifier_equ(nodes, nodes_cnt, oid, sizeof(oid)/sizeof(int)) != 1) { + printf("failed\n"); + error_print(); + err++; + } else { + printf("ok\n"); + } + } + + if (!err) printf("%s() ok\n", __FUNCTION__); return err; } static int test_asn1_printable_string(void) { - int err = 0; - char *tests[] = {"hello", "world", "Just do it!"}; - const char *val; - size_t vallen; - uint32_t nodes[32]; - size_t nodes_count; - uint8_t buf[1024] = {0}; + char *tests[] = { + "hello", + "world", + "Just do it!", + }; + uint8_t buf[256]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - size_t left = sizeof(buf); size_t i; - int rv; - printf("%s\n", __FUNCTION__); + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_PrintableString)); for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - printf("%s\n", tests[i]); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - asn1_printable_string_to_der(tests[i], &p, &len); - print_buf(buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - char str[256] = {0}; - rv = asn1_printable_string_from_der(&val, &vallen, &cp, &left); - assert(rv > 0); - memcpy(str, val, vallen); - - if (strcmp(str, tests[i]) != 0) { - error_print_msg("error decoding %zu-th: get %s, should be %s", i, str, tests[i]); - err++; + if (asn1_printable_string_to_der(tests[i], strlen(tests[i]), &p, &len) != 1) { + error_print(); + return 1; } - printf("%s\n", str); + format_bytes(stderr, 0, 4, "", buf, len); } - - printf("\n"); - return err; + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + const char *d; + size_t dlen; + if (asn1_printable_string_from_der(&d, &dlen, &cp, &len) != 1 + || strlen(tests[i]) != dlen + || memcmp(tests[i], d, dlen) != 0) { + error_print(); + return 1; + } + format_string(stderr, 0, 4, "", (uint8_t *)d, dlen); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 0; } static int test_asn1_utf8_string(void) { - int err = 0; - char *tests[] = {"hello", "world", "Just do it!"}; - const char *val; - size_t vallen; - uint32_t nodes[32]; - size_t nodes_count; - uint8_t buf[1024] = {0}; + char *tests[] = { + "hello", + "world", + "Just do it!", + }; + uint8_t buf[256]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - size_t left = sizeof(buf); size_t i; - int rv; - printf("%s\n", __FUNCTION__); + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_UTF8String)); for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - printf("%s\n", tests[i]); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - asn1_utf8_string_to_der(tests[i], &p, &len); - print_buf(buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - char str[256] = {0}; - rv = asn1_utf8_string_from_der(&val, &vallen, &cp, &left); - assert(rv > 0); - memcpy(str, val, vallen); - - if (strcmp(str, tests[i]) != 0) { - error_print_msg("error decoding %zu-th: get %s, should be %s", i, str, tests[i]); - err++; + if (asn1_utf8_string_to_der(tests[i], strlen(tests[i]), &p, &len) != 1) { + error_print(); + return 1; } - printf("%s\n", str); + format_bytes(stderr, 0, 4, "", buf, len); } - - printf("\n"); - return err; + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + const char *d; + size_t dlen; + if (asn1_utf8_string_from_der(&d, &dlen, &cp, &len) != 1 + || strlen(tests[i]) != dlen + || memcmp(tests[i], d, dlen) != 0) { + error_print(); + return 1; + } + format_string(stderr, 0, 4, "", (uint8_t *)d, dlen); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 0; } static int test_asn1_ia5_string(void) { - int err = 0; - char *tests[] = {"hello", "world", "Just do it!"}; - const char *val; - size_t vallen; - uint32_t nodes[32]; - size_t nodes_count; - uint8_t buf[1024] = {0}; + char *tests[] = { + "hello", + "world", + "Just do it!", + }; + uint8_t buf[256]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - size_t left = sizeof(buf); size_t i; - int rv; - printf("%s\n", __FUNCTION__); + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_IA5String)); for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - printf("%s\n", tests[i]); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - asn1_ia5_string_to_der(tests[i], &p, &len); - print_buf(buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - char str[256] = {0}; - rv = asn1_ia5_string_from_der(&val, &vallen, &cp, &left); - assert(rv > 0); - memcpy(str, val, vallen); - - if (strcmp(str, tests[i]) != 0) { - error_print_msg("error decoding %zu-th: get %s, should be %s", i, str, tests[i]); - err++; + if (asn1_ia5_string_to_der(tests[i], strlen(tests[i]), &p, &len) != 1) { + error_print(); + return 1; } - printf("%s\n", str); + format_bytes(stderr, 0, 4, "", buf, len); } - - printf("\n"); - return err; + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + const char *d; + size_t dlen; + if (asn1_ia5_string_from_der(&d, &dlen, &cp, &len) != 1 + || strlen(tests[i]) != dlen + || memcmp(tests[i], d, dlen) != 0) { + error_print(); + return 1; + } + format_string(stderr, 0, 4, "", (uint8_t *)d, dlen); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 0; } static int test_time(void) @@ -455,7 +529,6 @@ static int test_time(void) time(&tval); printf("%s", ctime(&tval)); - printf("%08x%08x\n", (uint32_t)(tval >> 32), (uint32_t)tval); return 0; @@ -463,110 +536,99 @@ static int test_time(void) static int test_asn1_utc_time(void) { - int err = 0; - time_t tests[] = {0, 0, 1<<30 }; - time_t val; - uint8_t buf[1024] = {0}; + time_t tests[] = { + 0, + 0, + 1<<30, + }; + time_t tv; + uint8_t buf[256]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - size_t left = sizeof(buf); size_t i; - int rv; - time(&tests[0]); + time(&tests[1]); - printf("%s\n", __FUNCTION__); + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_UTCTime)); for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - printf("%s", ctime(&tests[i])); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - asn1_utc_time_to_der(tests[i], &p, &len); - print_buf(buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - rv = asn1_utc_time_from_der(&val, &cp, &left); - assert(rv > 0); - if (val != tests[i]) { - error_print_msg("error decoding %zu-th: get %zu, should be %zu", i, val, tests[i]); - err++; + if (asn1_utc_time_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; } - printf("%s", ctime(&val)); + format_bytes(stderr, 0, 4, "", buf, len); } - - printf("\n"); - return err; + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_utc_time_from_der(&tv, &cp, &len) != 1 + || asn1_check(tv == tests[i]) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s", ctime(&tv)); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 0; } static int test_asn1_generalized_time(void) { - int err = 0; - time_t tests[] = {0, 1<<30}; - time_t val; - uint8_t buf[1024] = {0}; + time_t tests[] = { + 0, + 1<<30, + }; + uint8_t buf[256]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - size_t left = sizeof(buf); size_t i; - int rv; time(&tests[0]); - printf("%s\n", __FUNCTION__); + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_GeneralizedTime)); for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - printf("%s", ctime(&tests[i])); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - asn1_generalized_time_to_der(tests[i], &p, &len); - print_buf(buf, len); - } - - - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - rv = asn1_generalized_time_from_der(&val, &cp, &left); - assert(rv > 0); - if (val != tests[i]) { - error_print_msg("error decoding %zu-th: get %zu, should be %zu", i, val, tests[i]); - err++; + if (asn1_generalized_time_to_der(tests[i], &p, &len) != 1) { + error_print(); + return 1; } - printf("%s", ctime(&val)); + format_bytes(stderr, 0, 4, "", buf, len); } - - printf("\n"); - return err; + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + time_t tv; + if (asn1_generalized_time_from_der(&tv, &cp, &len) != 1 + || asn1_check(tv == tests[i]) != 1) { + error_print(); + return 1; + } + format_print(stderr, 0, 4, "%s", ctime(&tv)); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 0; } - - - - - -#endif - - - - - - - - int main(void) { int err = 0; - //err += test_asn1_tag(); - //err += test_asn1_length(); - //err += test_asn1_boolean(); - //err += test_asn1_integer(); - //err += test_asn1_bit_string(); - //err += test_asn1_null(); - //err += test_asn1_object_identifier(); - //err += test_asn1_printable_string(); - //err += test_asn1_utf8_string(); - //err += test_asn1_ia5_string(); - //err += test_asn1_utc_time(); - //err += test_asn1_generalized_time(); + err += test_asn1_tag(); + err += test_asn1_length(); + err += test_asn1_boolean(); + err += test_asn1_int(); + err += test_asn1_bits(); + err += test_asn1_null(); + err += test_asn1_object_identifier(); + err += test_asn1_printable_string(); + err += test_asn1_utf8_string(); + err += test_asn1_ia5_string(); + err += test_asn1_utc_time(); + err += test_asn1_generalized_time(); return err; } diff --git a/tests/base64test.c b/tests/base64test.c index 97b0c69a..2c5fefe1 100644 --- a/tests/base64test.c +++ b/tests/base64test.c @@ -55,13 +55,14 @@ int test_base64(void) { + int err = 0; + uint8_t bin1[50]; uint8_t bin2[100]; uint8_t bin3[200]; uint8_t buf1[8000] = {0}; uint8_t buf2[8000] = {0}; - int err = 0; BASE64_CTX ctx; uint8_t *p; int len; @@ -78,8 +79,6 @@ int test_base64(void) base64_encode_update(&ctx, bin3, sizeof(bin3), p, &len); p += len; base64_encode_finish(&ctx, p, &len); p += len; len = (int)(p - buf1); - printf("%s\n", buf1); - p = buf2; base64_decode_init(&ctx); @@ -87,24 +86,23 @@ int test_base64(void) base64_decode_finish(&ctx, p, &len); p += len; len = (int)(p - buf2); - printf("len = %d\n", len); - print_der(buf2, len); - printf("\n"); + printf("base64 test "); + if (len != sizeof(bin1) + sizeof(bin2) + sizeof(bin3) + || memcmp(buf2, bin1, sizeof(bin1)) != 0 + || memcmp(buf2 + sizeof(bin1), bin2, sizeof(bin2)) != 0 + || memcmp(buf2 + sizeof(bin1) + sizeof(bin2), bin3, sizeof(bin3)) != 0) { + printf("failed\n"); + err++; + } else { + printf("ok\n"); + } return err; } int main(void) { - test_base64(); - return 0; + int err = 0; + err += test_base64(); + return err; } - - - - - - - - - diff --git a/tests/chacha20test.c b/tests/chacha20test.c index bfb846d3..eb007b87 100644 --- a/tests/chacha20test.c +++ b/tests/chacha20test.c @@ -55,7 +55,8 @@ int main(void) { - int e = 0, i; + int err = 0; + int i; const unsigned char key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, @@ -83,13 +84,14 @@ int main(void) chacha20_init(&state, key, nonce, counter); chacha20_generate_keystream(&state, 1, buf); + printf("chacha20 test "); if (memcmp(buf, testdata, sizeof(testdata)) != 0) { - printf("chacha20 test 1 failed\n"); - return -1; + printf("failed\n"); + err++; } else { - printf("chacha20 test 1 ok\n"); + printf("ok\n"); } - return 0; + return err; } diff --git a/tests/cmstest.c b/tests/cmstest.c index f0269d95..7184a4d0 100644 --- a/tests/cmstest.c +++ b/tests/cmstest.c @@ -56,572 +56,7 @@ #include #include -#if 0 -static int test_cms_data(void) +int main(int argc, char **argv) { - uint8_t data[20]; - uint8_t der[512]; - uint8_t *p = der; - size_t len = 0; - int i; - - memset(data, 'A', sizeof(data)); - if (cms_content_info_to_der(CMS_data, data, sizeof(data), &p, &len) != 1 - || cms_content_info_print(stdout, der, len, 0, 0) != 1) { - error_print(); - return -1; - } - return 0; -} - -static int test_cms_enced_content_info(void) -{ - SM4_KEY sm4_key; - uint8_t key[16] = {0}; - uint8_t iv[16] = {0}; - uint8_t data[] = "Hello!"; - uint8_t buf[512]; - const uint8_t *cp = buf; - uint8_t *p = buf; - size_t len = 0; - int content_type; - uint8_t content[512] = {0}; - const uint8_t *shared_info1; - const uint8_t *shared_info2; - size_t content_len; - size_t shared_info1_len; - size_t shared_info2_len; - - sm4_set_encrypt_key(&sm4_key, key); - if (cms_enced_content_info_encrypt_to_der(&sm4_key, iv, - CMS_data, data, sizeof(data), - NULL, 0, NULL, 0, &p, &len) != 1) { - error_print(); - return -1; - } - - sm4_set_decrypt_key(&sm4_key, key); - if (cms_enced_content_info_decrypt_from_der(&sm4_key, &content_type, content, &content_len, - &shared_info1, &shared_info1_len, - &shared_info2, &shared_info2_len, - &cp, &len) != 1) { - error_print(); - return -1; - } - - printf("ContentType: %s\n", cms_content_type_name(content_type)); - printf("Content: %s\n", (char *)content); - printf("SharedInfo1: %s\n", (char *)shared_info1); - printf("SharedInfo2: %s\n", (char *)shared_info2); - return 0; -} - -static int test_cms_encrypt(void) -{ - uint8_t key[16]; - uint8_t msg[] = "Hello world!"; - uint8_t cbuf[512]; - uint8_t mbuf[512] = {0}; - size_t clen, mlen; - int content_type = 0; - const uint8_t *shared_info1 = NULL; - const uint8_t *shared_info2 = NULL; - size_t shared_info1_len, shared_info2_len; - - printf("%s()\n", __FUNCTION__); - - if (cms_encrypt(key, msg, sizeof(msg), cbuf, &clen) != 1) { - error_print(); - return -1; - } - cms_content_info_print(stdout, cbuf, clen, 0, 0); - - if (cms_decrypt(key, cbuf, clen, &content_type, mbuf, &mlen) != 1) { - error_print(); - return -1; - } - printf(" ContentType : %s\n", cms_content_type_name(content_type)); - printf(" Content: %s\n", mbuf); - return 0; -} - -static int test_cms_key_agreement_info(void) -{ - SM2_KEY sm2_key; - X509_CERTIFICATE cert; - FILE *key_fp = fopen("sign_key.pem", "r"); - FILE *cert_fp = fopen("sign_cert.pem", "r"); - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *id; - size_t idlen; - - if (sm2_private_key_from_pem(&sm2_key, key_fp) != 1) { - error_print(); - return -1; - } - if (x509_certificate_from_pem(&cert, cert_fp) != 1) { - error_print(); - return -1; - } - - if (cms_key_agreement_info_to_der(&sm2_key, &cert, (uint8_t *)"Alice", strlen("Alice"), &p, &len) != 1) { - error_print(); - return -1; - } - cms_key_agreement_info_print(stdout, buf, len, 0, 0); - if (cms_key_agreement_info_from_der(&sm2_key, &cert, &id, &idlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - return 0; -} - -static int test_cms_issuer_and_serial_number(void) -{ - FILE *cert_fp = fopen("sign_cert.pem", "r"); - X509_CERTIFICATE cert; - - X509_NAME issuer; - const X509_NAME *issuer_ptr; - const uint8_t *serial_number; - size_t serial_number_len; - const SM2_KEY *sm2_key; - - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - - if (x509_certificate_from_pem(&cert, cert_fp) != 1) { - error_print(); - return -1; - } - - if (cms_issuer_and_serial_number_from_certificate(&issuer_ptr, - &serial_number, &serial_number_len, &cert) != 1) { - error_print(); - return -1; - } - - if (cms_issuer_and_serial_number_to_der(issuer_ptr, serial_number, serial_number_len, &p, &len) != 1) { - error_print(); - return -1; - } - - if (cms_issuer_and_serial_number_from_der(&issuer, &serial_number, &serial_number_len, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - cms_issuer_and_serial_number_print(stdout, &issuer, serial_number, serial_number_len, 0, 0); - - return 0; -} - -// 从这个测试可以看出,由于CMS类型非常复杂,因此最好能够将其打包称为一个struct,但是要区分指针类型和存储类型 -static int test_cms_recipient_info(void) -{ - FILE *key_fp = fopen("sign_key.pem", "r"); - FILE *cert_fp = fopen("sign_cert.pem", "r"); - X509_CERTIFICATE cert; - - X509_NAME issuer; - SM2_KEY sm2_key; - - const X509_NAME *issuer_ptr; - const uint8_t *serial_number; - size_t serial_number_len; - const SM2_KEY *pub_key; - - uint8_t key[128] = {1,2,3}; - size_t keylen = 16; - - - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - - if (x509_certificate_from_pem(&cert, cert_fp) != 1) { - error_print(); - return -1; - } - if (cms_public_key_from_certificate(&pub_key, &cert) != 1) { - error_print(); - return -1; - } - sm2_key_print(stdout, pub_key, 0, 0); - - if (cms_recipient_info_from_x509_certificate(&pub_key, &issuer_ptr, &serial_number, &serial_number_len, &cert) != 1) { - error_print(); - return -1; - } - - if (cms_recipient_info_encrypt_to_der(pub_key, issuer_ptr, serial_number, serial_number_len, key, keylen, &p, &len) != 1) { - error_print(); - return -1; - } - - int version; - int pke_algor; - const uint8_t *params; - size_t paramslen; - const uint8_t *enced_key; - size_t enced_key_len; - - /* - // 这个函数导致cp, len的长度发生变化 - if (cms_recipient_info_from_der(&version, &issuer, &serial_number, &serial_number_len, - &pke_algor, ¶ms, ¶mslen, - &enced_key, &enced_key_len, - &cp, &len) != 1) { - - error_print(); - return -1; - } - - cms_recipient_info_print(stdout, - version, &issuer, serial_number, serial_number_len, - pke_algor, params, paramslen, - enced_key, enced_key_len, - 0, 0); - */ - - if (sm2_private_key_from_pem(&sm2_key, key_fp) != 1) { - error_print(); - return -1; - } - sm2_key_print(stdout, &sm2_key, 0, 0); - - - if (cms_recipient_info_decrypt_from_der(&sm2_key, &issuer, &serial_number, &serial_number_len, key, &keylen, &cp, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stdout, 0, 0, "decrypted_key : ", key, keylen); - - return 0; - -} - - -static int test_cms_enveloped_data(void) -{ - - FILE *key_fp = fopen("sign_key.pem", "r"); - FILE *cert_fp = fopen("sign_cert.pem", "r"); - X509_CERTIFICATE cert; - - X509_NAME issuer; - SM2_KEY sm2_key; - - const X509_NAME *issuer_ptr; - const uint8_t *serial_number; - size_t serial_number_len; - const SM2_KEY *pub_key; - - uint8_t key[128] = {1,2,3}; - size_t keylen = 16; - - - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - - if (x509_certificate_from_pem(&cert, cert_fp) != 1) { - error_print(); - return -1; - } - - uint8_t data[8]; - - if (cms_enveloped_data_encrypt_to_der(&cert, 1, - CMS_data, data, sizeof(data), - NULL, 0, NULL, 0, &p, &len) != 1) { - error_print(); - return -1; - } - error_print_msg("len = %zu\n", len); - - //cms_enveloped_data_print(stdout, cp, len, 0, 0); - //return 0; - - if (sm2_private_key_from_pem(&sm2_key, key_fp) != 1) { - error_print(); - return -1; - } - int content_type; - uint8_t content[512]; - size_t content_len; - const uint8_t *shared_info1, *shared_info2; - size_t shared_info1_len, shared_info2_len; - - if (cms_enveloped_data_decrypt_from_der( - &sm2_key, &cert, - &content_type, content, &content_len, - &shared_info1, &shared_info1_len, - &shared_info2, &shared_info2_len, - &cp, &len) != 1) { - error_print(); - return -1; - } - - - return 0; -} - - -static int test_cms_signer_info(void) -{ - FILE *key_fp = fopen("sign_key.pem", "r"); - FILE *cert_fp = fopen("sign_cert.pem", "r"); - X509_CERTIFICATE cert; - - X509_NAME issuer; - SM2_KEY sm2_key; - - const X509_NAME *issuer_ptr; - const uint8_t *serial_number; - size_t serial_number_len; - const SM2_KEY *pub_key; - - uint8_t key[128] = {1,2,3}; - size_t keylen = 16; - - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - if (x509_certificate_from_pem(&cert, cert_fp) != 1) { - error_print(); - return -1; - } - - if (cms_issuer_and_serial_number_from_certificate(&issuer_ptr, - &serial_number, &serial_number_len, &cert) != 1) { - error_print(); - return -1; - } - - uint8_t attrs[10]; - - if (cms_signer_info_to_der( - issuer_ptr, - serial_number, serial_number_len, - OID_sm3, - attrs, sizeof(attrs), - attrs, sizeof(attrs), - attrs, sizeof(attrs), - &p, &len) != 1) { - error_print(); - return -1; - } - - const uint8_t *authed_attrs, *unauthed_attrs, *sig; - size_t authed_attrs_len, unauthed_attrs_len, siglen; - int dgst_algor, sign_algor; - - if (cms_signer_info_from_der( - &issuer, - &serial_number, &serial_number_len, - &dgst_algor, - &authed_attrs, &authed_attrs_len, - &sign_algor, - &sig, &siglen, - &unauthed_attrs, &unauthed_attrs_len, - &cp, &len) != 1) { - error_print(); - return -1; - } - - - cms_signer_info_print(stdout, - 1, - &issuer, serial_number, serial_number_len, - dgst_algor, NULL, 0, - authed_attrs, authed_attrs_len, - sign_algor, NULL, 0, - sig, siglen, - unauthed_attrs, unauthed_attrs_len, - 0, 0); - - p = buf; - cp = buf; - len = 0; - - SM3_CTX sm3_ctx; - - // 这里根本没有测试验证过程 - -/* -270 int cms_signer_info_from_der(X509_NAME *issuer, -271 const uint8_t **serial_number, size_t *serial_number_len, -272 int *digest_algor, -273 const uint8_t **authed_attrs, size_t *authed_attrs_len, -274 int *sign_algor, -275 const uint8_t **enced_digest, size_t *enced_digest_len, -276 const uint8_t **unauthed_attrs, size_t *unauthed_attrs_len, -277 const uint8_t **in, size_t *inlen); -*/ - - - - - return 0; -} - -static int test_cms_signed_data(void) -{ - FILE *key_fp = fopen("sign_key.pem", "r"); - FILE *cert_fp = fopen("sign_cert.pem", "r"); - X509_CERTIFICATE cert; - - X509_NAME issuer; - SM2_KEY sm2_key; - - const X509_NAME *issuer_ptr; - const uint8_t *serial_number; - size_t serial_number_len; - const SM2_KEY *pub_key; - - uint8_t key[128] = {1,2,3}; - size_t keylen = 16; - - uint8_t buf[1512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - uint8_t data[10] = {0}; - - - if (x509_certificate_from_pem(&cert, cert_fp) != 1) { - error_print(); - return -1; - } - if (sm2_private_key_from_pem(&sm2_key, key_fp) != 1) { - error_print(); - return -1; - } - - - if (cms_signed_data_sign_to_der(&sm2_key, &cert, 1, - CMS_data, data, sizeof(data), - NULL, 0, - &p, &len) != 1) { - error_print(); - return -1; - } - - cms_signed_data_print(stdout, buf, len, 0, 0); - - // 这个函数有问题,因为from_der返回的0和验证签名返回的0可能产生冲突 - // 还是应该直接提供一个函数,只做verify,不做from_der - - - int content_type; - const uint8_t *dgst_algors, *content, *certs, *crls, *signer_infos; - size_t dgst_algors_len, content_len, certs_len, crls_len, signer_infos_len; - - if (cms_signed_data_from_der( - &dgst_algors, &dgst_algors_len, - &content_type, &content, &content_len, - &certs, &certs_len, - &crls, &crls_len, - &signer_infos, &signer_infos_len, - &cp, &len) != 1) { - error_print(); - return -1; - } - - if (cms_signed_data_verify( - content_type, content, content_len, - certs, certs_len, - signer_infos, signer_infos_len) != 1) { - error_print(); - return -1; - } - - - return 0; - -} - - - -static int test_cms_sign(void) -{ - SM2_KEY sign_key; - X509_CERTIFICATE sign_cert; - uint8_t in[20]; - uint8_t out[1024]; - size_t outlen = 0; - - FILE *key_fp = fopen("sign_key.pem", "r"); - FILE *cert_fp = fopen("sign_cert.pem", "r"); - - if (sm2_private_key_from_pem(&sign_key, key_fp) != 1) { - error_print(); - return -1; - } - if (x509_certificate_from_pem(&sign_cert, cert_fp) != 1) { - error_print(); - return -1; - } - - if (cms_sign(&sign_key, &sign_cert, 1, in, sizeof(in), out, &outlen) != 1) { - error_print(); - return -1; - } - - cms_content_info_print(stdout, out, outlen, 0, 0); - - int content_type; - const uint8_t *content, *certs, *crls, *signer_infos; - size_t content_len, certs_len, crls_len, signer_infos_len; - - if (cms_verify(&content_type, &content, &content_len, - &certs, &certs_len, - &crls, &crls_len, - &signer_infos, &signer_infos_len, - out, outlen) != 1) { - error_print(); - return -1; - } - - - return 1; -} - - - -#endif - - - - - -int main(void) -{ - //test_cms_data(); - //test_cms_enced_content_info(); - //test_cms_encrypt(); - //test_cms_key_agreement_info(); - //test_cms_issuer_and_serial_number(); - //test_cms_recipient_info(); - //test_cms_signer_info(); - //test_cms_signed_data(); - //test_cms_enveloped_data(); - //test_cms_sign(); return 0; } diff --git a/tests/gcmtest.c b/tests/gcmtest.c index 54e74ac1..6fa755ec 100644 --- a/tests/gcmtest.c +++ b/tests/gcmtest.c @@ -148,12 +148,13 @@ int test_ghash(void) format_print(stdout, 0, 2, " = %s\n\n", ghash_tests[i].T); */ } - return 1; + return 0; } -int main(void) +int main(int argc, char **argv) { - test_ghash(); - return 1; + int err = 0; + err += test_ghash(); + return err; } diff --git a/tests/gf128test.c b/tests/gf128test.c index 1a93dc82..cf0301b3 100644 --- a/tests/gf128test.c +++ b/tests/gf128test.c @@ -91,9 +91,5 @@ int main(void) gf128_print("H = ", H); gf128_print("C * H = ", T); - - - - return 0; } diff --git a/tests/oidtest.c b/tests/oidtest.c deleted file mode 100644 index 7b6bdfdc..00000000 --- a/tests/oidtest.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2014 - 2020 The GmSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the GmSSL Project. - * (http://gmssl.org/)" - * - * 4. The name "GmSSL Project" must not be used to endorse or promote - * products derived from this software without prior written - * permission. For written permission, please contact - * guanzhi1980@gmail.com. - * - * 5. Products derived from this software may not be called "GmSSL" - * nor may "GmSSL" appear in their names without prior written - * permission of the GmSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the GmSSL Project - * (http://gmssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include - -int main(void) -{ -// test_asn1_oid(); - - test_asn1_object_identifier(); - return 1; -} diff --git a/tests/pbkdf2test.c b/tests/pbkdf2test.c index 9629575d..48378d01 100644 --- a/tests/pbkdf2test.c +++ b/tests/pbkdf2test.c @@ -52,7 +52,7 @@ #include #include #include - +#include struct { @@ -85,13 +85,15 @@ struct { 20, "4b007901b765489abead49d926f721d065a429c1", }, + /* { "password", "salt", - 16777216, + 16777216, // very slow 20, "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984", }, + */ { "passwordPASSWORDpassword", "saltSALTsaltSALTsaltSALTsaltSALTsalt", @@ -101,7 +103,7 @@ struct { }, }; - +/* void test(void) { HMAC_CTX ctx; @@ -133,8 +135,9 @@ void test(void) } printf("\n"); } +*/ -int main(void) +static int test_pbkdf2_genkey(void) { int i; uint8_t key[64]; @@ -144,17 +147,28 @@ int main(void) for (i = 0; i < sizeof(pbkdf2_hmac_sha1_tests)/sizeof(pbkdf2_hmac_sha1_tests[0]); i++) { hex_to_bytes(pbkdf2_hmac_sha1_tests[i].dk, strlen(pbkdf2_hmac_sha1_tests[i].dk), buf, &len); - pbkdf2_genkey(DIGEST_sha1(), + if (pbkdf2_genkey(DIGEST_sha1(), pbkdf2_hmac_sha1_tests[i].pass, strlen(pbkdf2_hmac_sha1_tests[i].pass), (uint8_t *)pbkdf2_hmac_sha1_tests[i].salt, strlen(pbkdf2_hmac_sha1_tests[i].salt), - pbkdf2_hmac_sha1_tests[i].iter, pbkdf2_hmac_sha1_tests[i].dklen, key); - + pbkdf2_hmac_sha1_tests[i].iter, pbkdf2_hmac_sha1_tests[i].dklen, key) != 1) { + error_print(); + return -1; + } if (memcmp(key, buf, pbkdf2_hmac_sha1_tests[i].dklen) != 0) { - printf("%d failed\n", i); + fprintf(stderr, "test_pbkdf2_genkey test %d failed\n", i); + return -1; } else { - printf("%d ok\n", i); + fprintf(stderr, "test_pbkdf2_genkey test %d ok\n", i); } } - return 1; + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +int main(int argc, char **argv) +{ + int err = 0; + err += test_pbkdf2_genkey(); + return err; } diff --git a/tests/pkcs8test.c b/tests/pkcs8test.c index cf04abea..a3a74894 100644 --- a/tests/pkcs8test.c +++ b/tests/pkcs8test.c @@ -13,7 +13,7 @@ * the documentation and/or other materials provided with the * distribution. * -sm2_enced_private_key_info_from_der * 3. All advertising materials mentioning features or use of this + * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the GmSSL Project. * (http://gmssl.org/)" @@ -51,216 +51,312 @@ sm2_enced_private_key_info_from_der * 3. All advertising materials mentioning fe #include #include #include +#include #include #include static int test_pbkdf2_params(void) { - int err = 0; uint8_t salt[8] = {0}; - const uint8_t *psalt; size_t saltlen; int iter = 65536; - int keylen; + int keylen = 16; int prf = OID_hmac_sm3; + uint8_t buf[128]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - keylen = -1; - if (pbkdf2_params_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1) { - error_print(); - err++; - goto end; - } - if (pbkdf2_params_from_der(&psalt, &saltlen, &iter, &keylen, &prf, &cp, &len) != 1 - || len > 0) { - error_print(); - err++; - goto end; - } + const uint8_t *d; + size_t dlen; + const uint8_t *psalt; - keylen = 16; - if (pbkdf2_params_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1) { + if (pbkdf2_params_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { error_print(); - err++; - goto end; + return -1; } - if (pbkdf2_params_from_der(&psalt, &saltlen, &iter, &keylen, &prf, &cp, &len) != 1 - || len > 0) { + pbkdf2_params_print(stderr, 0, 0, "PBKDF2-params", d, dlen); + + p = buf; + cp = buf; + len = 0; + keylen = -1; + prf = -1; + if (pbkdf2_params_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { error_print(); - err++; - goto end; + return -1; } - printf("%s : ok\n", __func__); -end: - return err; + pbkdf2_params_print(stderr, 0, 0, "PBKDF2-params", d, dlen); + + p = buf; + cp = buf; + len = 0; + keylen = -1; + prf = -1; + if (pbkdf2_params_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1 + || pbkdf2_params_from_der(&psalt, &saltlen, &iter, &keylen, &prf, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 0, "PBKDF2-params\n"); + format_bytes(stderr, 0, 4, "salt", psalt, saltlen); + format_print(stderr, 0, 4, "iterationCount: %d\n", iter); + format_print(stderr, 0, 4, "keyLength: %d\n", keylen); + format_print(stderr, 0, 4, "prf: %d\n", prf); + + printf("%s() ok\n", __FUNCTION__); + return 0; } static int test_pbkdf2_algor(void) { - int err = 0; uint8_t salt[8] = {0}; - const uint8_t *psalt; size_t saltlen; int iter = 65536; - int keylen; + int keylen = 16; int prf = OID_hmac_sm3; + uint8_t buf[128]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - keylen = -1; - if (pbkdf2_algor_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1) { - error_print(); - err++; - goto end; - } - if (pbkdf2_algor_from_der(&psalt, &saltlen, &iter, &keylen, &prf, &cp, &len) != 1 - || len > 0) { - error_print(); - err++; - goto end; - } - printf("%s : ok\n", __func__); -end: - return err; -} + const uint8_t *d; + size_t dlen; + const uint8_t *psalt; + if (pbkdf2_algor_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + pbkdf2_algor_print(stderr, 0, 0, "PBKDF2", d, dlen); + + p = buf; + cp = buf; + len = 0; + if (pbkdf2_algor_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 0, "PBKDF2\n"); + format_bytes(stderr, 0, 4, "salt", psalt, saltlen); + format_print(stderr, 0, 4, "iterationCount: %d\n", iter); + format_print(stderr, 0, 4, "keyLength: %d\n", keylen); + format_print(stderr, 0, 4, "prf: %d\n", prf); + + printf("%s() ok\n", __FUNCTION__); + return 0; +} static int test_pbes2_enc_algor(void) { - int err = 0; int cipher = OID_sm4_cbc; uint8_t iv[16] = {1}; - const uint8_t *piv; - size_t ivlen; + uint8_t buf[128]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - if (pbes2_enc_algor_to_der(OID_sm4_cbc, iv, sizeof(iv), &p, &len) != 1) { + const uint8_t *d; + size_t dlen; + const uint8_t *piv; + size_t ivlen; + + if (pbes2_enc_algor_to_der(cipher, iv, sizeof(iv), &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { error_print(); - err++; - goto end; + return -1; } - if (pbes2_enc_algor_from_der(&cipher, &piv, &ivlen, &cp, &len) != 1 - || len > 0) { + pbes2_enc_algor_print(stderr, 0, 0, "PBES2-Enc", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (pbes2_enc_algor_to_der(cipher, iv, sizeof(iv), &p, &len) != 1 + || pbes2_enc_algor_from_der(&cipher, &piv, &ivlen, &cp, &len) != 1 + || asn1_check(cipher == OID_sm4_cbc) != 1 + || asn1_check(ivlen == sizeof(iv)) != 1 + || asn1_length_is_zero(len) != 1) { error_print(); - err++; - goto end; + return -1; } - printf("%s : ok\n", __func__); -end: - return err; + + printf("%s() ok\n", __FUNCTION__); + return 0; } static int test_pbes2_params(void) { - int err = 0; uint8_t salt[8] = {0}; - const uint8_t *psalt; size_t saltlen; int iter = 65536; + int keylen = -1; int prf = OID_hmac_sm3; int cipher = OID_sm4_cbc; uint8_t iv[16]; - const uint8_t *piv; - size_t ivlen; + uint8_t buf[256]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - if (pbes2_params_to_der(salt, sizeof(salt), iter, prf, cipher, iv, sizeof(iv), &p, &len) != 1) { + const uint8_t *d; + size_t dlen; + const uint8_t *psalt; + const uint8_t *piv; + size_t ivlen; + + if (pbes2_params_to_der(salt, sizeof(salt), iter, keylen, prf, cipher, iv, sizeof(iv), &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { error_print(); - err++; - goto end; + return -1; } - if (pbes2_params_from_der(&psalt, &saltlen, &iter, &prf, &cipher, &piv, &ivlen, &cp, &len) != 1 - || len > 0) { + pbes2_params_print(stderr, 0, 0, "PBES2-params", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (pbes2_params_to_der(salt, sizeof(salt), iter, keylen, prf, cipher, iv, sizeof(iv), &p, &len) != 1 + || pbes2_params_from_der(&psalt, &saltlen, &iter, &keylen, &prf, &cipher, &piv, &ivlen, &cp, &len) != 1 + || asn1_check(saltlen == sizeof(salt)) != 1 + || asn1_check(iter == 65536) != 1 + || asn1_check(keylen == -1) != 1 + || asn1_check(prf == OID_hmac_sm3) != 1 + || asn1_check(cipher == OID_sm4_cbc) != 1 + || asn1_check(ivlen == sizeof(iv)) != 1 + || asn1_length_is_zero(len) != 1) { error_print(); - err++; - goto end; + return -1; } - printf("%s : ok\n", __func__); -end: - return err; + printf("%s() ok\n", __FUNCTION__); + return 0; } static int test_pbes2_algor(void) { - int err = 0; uint8_t salt[8] = {0}; - const uint8_t *psalt; size_t saltlen; int iter = 65536; + int keylen = -1; int prf = OID_hmac_sm3; int cipher = OID_sm4_cbc; uint8_t iv[16]; - const uint8_t *piv; - size_t ivlen; + uint8_t buf[256]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - if (pbes2_algor_to_der(salt, sizeof(salt), iter, prf, cipher, iv, sizeof(iv), &p, &len) != 1) { + const uint8_t *d; + size_t dlen; + const uint8_t *psalt; + const uint8_t *piv; + size_t ivlen; + + if (pbes2_algor_to_der(salt, sizeof(salt), iter, keylen, prf, cipher, iv, sizeof(iv), &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { error_print(); - err++; - goto end; + return -1; } - if (pbes2_algor_from_der(&psalt, &saltlen, &iter, &prf, &cipher, &piv, &ivlen, &cp, &len) != 1 - || len > 0) { + pbes2_algor_print(stderr, 0, 0, "PBES2", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (pbes2_algor_to_der(salt, sizeof(salt), iter, keylen, prf, cipher, iv, sizeof(iv), &p, &len) != 1 + || pbes2_algor_from_der(&psalt, &saltlen, &iter, &keylen, &prf, &cipher, &piv, &ivlen, &cp, &len) != 1 + || asn1_check(saltlen == sizeof(salt)) != 1 + || asn1_check(iter == 65536) != 1 + || asn1_check(keylen == -1) != 1 + || asn1_check(prf == OID_hmac_sm3) != 1 + || asn1_check(cipher == OID_sm4_cbc) != 1 + || asn1_check(ivlen == sizeof(iv)) != 1 + || asn1_length_is_zero(len) != 1) { error_print(); - err++; - goto end; + return -1; } - printf("%s : ok\n", __func__); -end: - return err; + printf("%s() ok\n", __FUNCTION__); + return 0; } static int test_pkcs8_enced_private_key_info(void) { - int err = 0; - uint8_t salt[8] = {0}; - const uint8_t *psalt; - size_t saltlen; + uint8_t salt[8] = { 1,0 }; int iter = 65536; + int keylen = -1; int prf = OID_hmac_sm3; int cipher = OID_sm4_cbc; - uint8_t iv[16]; - const uint8_t *piv; - size_t ivlen; - uint8_t enced[128]; - const uint8_t *penced; - size_t encedlen; + uint8_t iv[16] = { 2,0 }; + uint8_t enced[128] = { 3,0 }; + uint8_t buf[256]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - if (pkcs8_enced_private_key_info_to_der(salt, sizeof(salt), iter, prf, cipher, iv, sizeof(iv), - enced, sizeof(enced), &p, &len) != 1) { + const uint8_t *d; + size_t dlen; + const uint8_t *psalt; + size_t saltlen; + const uint8_t *piv; + size_t ivlen; + const uint8_t *penced; + size_t encedlen; + + if (pkcs8_enced_private_key_info_to_der( + salt, sizeof(salt), iter, keylen, prf, + cipher, iv, sizeof(iv), + enced, sizeof(enced), &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { error_print(); - err++; - goto end; + return -1; } - if (pkcs8_enced_private_key_info_from_der(&psalt, &saltlen, &iter, &prf, &cipher, &piv, &ivlen, - &penced, &encedlen, &cp, &len) != 1 - || len > 0) { + pkcs8_enced_private_key_info_print(stderr, 0, 0, "EncryptedPrivateKeyInfo", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (pkcs8_enced_private_key_info_to_der( + salt, sizeof(salt), iter, keylen, prf, + cipher, iv, sizeof(iv), + enced, sizeof(enced), &p, &len) != 1 + || pkcs8_enced_private_key_info_from_der( + &psalt, &saltlen, &iter, &keylen, &prf, + &cipher, &piv, &ivlen, + &penced, &encedlen, &cp, &len) != 1 + || asn1_check(saltlen == sizeof(salt)) != 1 + || asn1_check(keylen == -1) != 1 + || asn1_check(prf == OID_hmac_sm3) != 1 + || asn1_check(cipher == OID_sm4_cbc) != 1 + || asn1_check(ivlen == sizeof(iv)) != 1 + || asn1_check(encedlen == sizeof(enced)) != 1 + || asn1_length_is_zero(len) != 1) { error_print(); - err++; - goto end; + return -1; } - printf("%s : ok\n", __func__); -end: - return err; + + printf("%s() ok\n", __FUNCTION__); + return 0; } static int test_pkcs8(void) @@ -277,31 +373,69 @@ static int test_pkcs8(void) sm2_key_generate(&sm2_key); memcpy(&sm2_buf, &sm2_key, sizeof(sm2_key)); - //sm2_key_print(stdout, &sm2_key, 0, 0); + sm2_key_print(stderr, 0, 0, "SM2_KEY", &sm2_key); - if (sm2_enced_private_key_info_to_der(&sm2_key, "passowrd", &p, &len) != 1) { + if (sm2_private_key_info_encrypt_to_der(&sm2_key, "password", &p, &len) != 1) { error_print(); - err++; - goto end; + return -1; + } + { + const uint8_t *a = buf; + size_t alen = len; + const uint8_t *d; + size_t dlen; + if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1 + || asn1_length_is_zero(alen) != 1) { + error_print(); + return -1; + } + pkcs8_enced_private_key_info_print(stderr, 0, 0, "test_pkcs8: 392", d, dlen); } memset(&sm2_key, 0, sizeof(sm2_key)); - if (sm2_enced_private_key_info_from_der(&sm2_key, &attrs, &attrslen, "password", &cp, &len) != 1 - || len > 0) { + if (sm2_private_key_info_decrypt_from_der(&sm2_key, &attrs, &attrslen, "password", &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { error_print(); - err++; - goto end; + return -1; } - //sm2_key_print(stdout, &sm2_key, 0, 0); + sm2_key_print(stderr, 0, 0, "SM2_KEY", &sm2_key); - if (memcmp(&sm2_key, &sm2_buf, sizeof(sm2_key)) != 0) { + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_pkcs8_pem(void) +{ + int err = 0; + char *file = "test_pkcs8_pem.pem"; + char *pass = "password"; + SM2_KEY sm2_key; + SM2_KEY sm2_buf; + const uint8_t *attrs; + size_t attrs_len; + FILE *fp; + + sm2_key_generate(&sm2_key); + memcpy(&sm2_buf, &sm2_key, sizeof(sm2_key)); + sm2_key_print(stderr, 0, 0, "SM2_KEY", &sm2_key); + + if (!(fp = fopen(file, "w")) + || sm2_private_key_info_encrypt_to_pem(&sm2_key, pass, fp) != 1) { error_print(); - err++; - goto end; + return -1; } - printf("%s : ok\n", __func__); -end: - return err; + fclose(fp); + + memset(&sm2_key, 0, sizeof(sm2_key)); + if (!(fp = fopen(file, "r")) + || sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, fp) != 1) { + error_print(); + return -1; + } + sm2_key_print(stderr, 0, 0, "SM2_KEY", &sm2_key); + + printf("%s() ok\n", __FUNCTION__); + return 0; } int main(void) @@ -314,5 +448,6 @@ int main(void) err += test_pbes2_algor(); err += test_pkcs8_enced_private_key_info(); err += test_pkcs8(); + err += test_pkcs8_pem(); return err; } diff --git a/tests/sm2asn1test.c b/tests/sm2asn1test.c deleted file mode 100644 index bb630567..00000000 --- a/tests/sm2asn1test.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the GmSSL Project. - * (http://gmssl.org/)" - * - * 4. The name "GmSSL Project" must not be used to endorse or promote - * products derived from this software without prior written - * permission. For written permission, please contact - * guanzhi1980@gmail.com. - * - * 5. Products derived from this software may not be called "GmSSL" - * nor may "GmSSL" appear in their names without prior written - * permission of the GmSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the GmSSL Project - * (http://gmssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include - - -static int test_sm2_point_octets(void) -{ - int err = 0; - SM2_KEY sm2_key; - SM2_POINT point; - uint8_t buf[65]; - int i; - - // compress - for (i = 0; i < 8; i++) { - uint8_t buf[33]; - sm2_key_generate(&sm2_key); - sm2_point_to_compressed_octets(&sm2_key.public_key, buf); - if (sm2_point_from_octets(&point, buf, sizeof(buf)) != 1) { - error_print(); - err++; - break; - } - if (memcmp(&sm2_key.public_key, &point, sizeof(SM2_POINT)) != 0) { - error_print(); - err++; - break; - } - } - - // uncompress - for (i = 0; i < 8; i++) { - uint8_t buf[65]; - sm2_key_generate(&sm2_key); - sm2_point_to_uncompressed_octets(&sm2_key.public_key, buf); - if (sm2_point_from_octets(&point, buf, sizeof(buf)) != 1) { - error_print(); - err++; - break; - } - if (memcmp(&sm2_key.public_key, &point, sizeof(SM2_POINT)) != 0) { - error_print(); - err++; - break; - } - } - - printf("%s : %s\n", __func__, err ? "failed" : "ok"); - return err; -} - -static int test_sm2_private_key(void) -{ - int err = 0; - SM2_KEY sm2_key; - SM2_KEY sm2_tmp; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - - sm2_key_generate(&sm2_key); - - if (sm2_private_key_to_der(&sm2_key, &p, &len) != 1) { - error_print(); - err++; - goto end; - } - if (sm2_private_key_from_der(&sm2_tmp, &cp, &len) != 1 - || len > 0) { - error_print(); - err++; - goto end; - } - if (memcmp(&sm2_tmp, &sm2_key, sizeof(SM2_KEY)) != 0) { - error_print(); - err++; - goto end; - } - - printf("%s : ok\n", __func__); -end: - return err; -} - -static int test_sm2_public_key_info(void) -{ - int err = 0; - SM2_KEY sm2_key; - SM2_KEY sm2_tmp; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - sm2_key_generate(&sm2_key); - - if (sm2_public_key_info_to_der(&sm2_key, &p, &len) != 1) { - error_print(); - err++; - goto end; - } - if (sm2_public_key_info_from_der(&sm2_tmp, &cp, &len) != 1 - || len > 0) { - error_print(); - err++; - goto end; - } - if (memcmp(&sm2_key.public_key, &sm2_tmp.public_key, sizeof(SM2_POINT)) != 0) { - error_print(); - err++; - goto end; - } - printf("%s : ok\n", __func__); -end: - return err; -} - - - -int main(void) -{ - test_sm2_point_octets(); - test_sm2_private_key(); - test_sm2_public_key_info(); - return 0; -} - diff --git a/tests/sm2test.c b/tests/sm2test.c index 33e1abea..22528422 100644 --- a/tests/sm2test.c +++ b/tests/sm2test.c @@ -49,6 +49,7 @@ #include #include #include +#include #include @@ -96,7 +97,7 @@ static int test_sm2_point(void) i = sm2_point_is_on_curve(&P); printf("point_is_on_curve: %d\n", i); - return 1; + return 0; } @@ -119,7 +120,7 @@ static int test_sm2_do_encrypt(void) sm2_do_decrypt(&key, ciphertext, plainbuf, &plainlen); printf("plaintext = %s\n", (char *)plainbuf); - return r; + return 0; } static int test_sm2_sign(void) @@ -149,13 +150,130 @@ static int test_sm2_sign(void) return 0; } +static int test_sm2_point_octets(void) +{ + int err = 0; + SM2_KEY sm2_key; + SM2_POINT point; + uint8_t buf[65]; + int i; + + // compress + for (i = 0; i < 8; i++) { + uint8_t buf[33]; + sm2_key_generate(&sm2_key); + sm2_point_to_compressed_octets(&sm2_key.public_key, buf); + if (sm2_point_from_octets(&point, buf, sizeof(buf)) != 1) { + error_print(); + err++; + break; + } + if (memcmp(&sm2_key.public_key, &point, sizeof(SM2_POINT)) != 0) { + error_print(); + err++; + break; + } + } + + // uncompress + for (i = 0; i < 8; i++) { + uint8_t buf[65]; + sm2_key_generate(&sm2_key); + sm2_point_to_uncompressed_octets(&sm2_key.public_key, buf); + if (sm2_point_from_octets(&point, buf, sizeof(buf)) != 1) { + error_print(); + err++; + break; + } + if (memcmp(&sm2_key.public_key, &point, sizeof(SM2_POINT)) != 0) { + error_print(); + err++; + break; + } + } + + printf("%s : %s\n", __func__, err ? "failed" : "ok"); + return err; +} + +static int test_sm2_private_key(void) +{ + int err = 0; + SM2_KEY sm2_key; + SM2_KEY sm2_tmp; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + sm2_key_generate(&sm2_key); + + if (sm2_private_key_to_der(&sm2_key, &p, &len) != 1) { + error_print(); + err++; + goto end; + } + if (sm2_private_key_from_der(&sm2_tmp, &cp, &len) != 1 + || len > 0) { + error_print(); + err++; + goto end; + } + if (memcmp(&sm2_tmp, &sm2_key, sizeof(SM2_KEY)) != 0) { + error_print(); + err++; + goto end; + } + + printf("%s : ok\n", __func__); +end: + printf("%s : %s\n", __func__, err ? "failed" : "ok"); + return err; +} + +static int test_sm2_public_key_info(void) +{ + int err = 0; + SM2_KEY sm2_key; + SM2_KEY sm2_tmp; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + sm2_key_generate(&sm2_key); + + if (sm2_public_key_info_to_der(&sm2_key, &p, &len) != 1) { + error_print(); + err++; + goto end; + } + if (sm2_public_key_info_from_der(&sm2_tmp, &cp, &len) != 1 + || len > 0) { + error_print(); + err++; + goto end; + } + if (memcmp(&sm2_key.public_key, &sm2_tmp.public_key, sizeof(SM2_POINT)) != 0) { + error_print(); + err++; + goto end; + } + printf("%s : ok\n", __func__); +end: + printf("%s : %s\n", __func__, err ? "failed" : "ok"); + return err; +} + int main(void) { - sm2_selftest(); - - //test_sm2_point(); - //test_sm2_sign(); - test_sm2_do_encrypt(); - - return 0; + int err = 0; + err += sm2_selftest(); + err += test_sm2_point(); + err += test_sm2_sign(); + err += test_sm2_do_encrypt(); + err += test_sm2_point_octets(); + err += test_sm2_private_key(); + err += test_sm2_public_key_info(); + return err; } diff --git a/tests/sm3test.c b/tests/sm3test.c index e5282ac4..a12d8939 100644 --- a/tests/sm3test.c +++ b/tests/sm3test.c @@ -179,7 +179,7 @@ int main(int argc, char **argv) { int err = 0; char *p; - uint8_t testbuf[sizeof(testhex)/2]; + uint8_t testbuf[sizeof(testhex)/2 + 1000]; uint8_t dgstbuf[32]; size_t testbuflen, dgstbuflen; uint8_t dgst[32]; diff --git a/tests/sm4test.c b/tests/sm4test.c index 16567ca8..de0a70d2 100644 --- a/tests/sm4test.c +++ b/tests/sm4test.c @@ -50,6 +50,7 @@ #include #include #include +#include # ifdef SM4_AVX2 void sm4_avx2_ecb_encrypt_blocks(const unsigned char *in, @@ -93,13 +94,15 @@ static int test_ecb(int avx) # endif default: printf("avx shuold be in {2}\n"); - return 0; + error_print(); + return -1; } if (memcmp(out1, out2, sizeof(out1)) != 0) { - return 0; + error_print(); + return -1; } - return 1; + return 0; } static void xor_block(unsigned char *out, const unsigned char *in) @@ -151,13 +154,15 @@ static int test_ctr32(int avx) break; default: printf("avx should be in {0, 2}\n"); - return 0; + error_print(); + return -1; } if (memcmp(out1, out2, sizeof(out1)) != 0) { - return 0; + error_print(); + return -1; } - return 1; + return 0; } @@ -197,7 +202,7 @@ static int test_ede(void) } */ -int main(int argc, char **argv) +int test_sm4(void) { int err = 0; int i; @@ -309,3 +314,63 @@ end: return err; } + + +static int test_sm4_cbc(void) +{ + SM4_KEY sm4_key; + uint8_t key[16] = {0}; + uint8_t iv[16]; + + uint8_t buf1[2] = {0}; + uint8_t buf2[32] = {0}; + uint8_t buf3[47] = {0}; + uint8_t buf4[96] = {0}; + uint8_t buf5[96]; + int i; + + sm4_set_encrypt_key(&sm4_key, key); + sm4_cbc_encrypt(&sm4_key, iv, buf2, 2, buf4); + + for (i = 0; i < 32; i++) { + printf("%02x", buf4[i]); + } + printf("\n"); + return 0; +} + +static int test_sm4_cbc_padding(void) +{ + SM4_KEY enc_key; + SM4_KEY dec_key; + uint8_t key[16] = {0}; + uint8_t iv[16] = {0}; + uint8_t in[64]; + uint8_t out[128]; + uint8_t buf[128]; + size_t len1, len2, i; + + for (i = 0; i < sizeof(in); i++) { + in[i] = i; + } + + sm4_set_encrypt_key(&enc_key, key); + sm4_set_decrypt_key(&dec_key, key); + + sm4_cbc_padding_encrypt(&enc_key, iv, in, 33, out, &len1); + printf("c = (%zu) ", len1); for (i = 0; i < len1; i++) printf("%02x", out[i]); printf("\n"); + + sm4_cbc_padding_decrypt(&dec_key, iv, out, len1, buf, &len2); + printf("m = (%zu) ", len2); for (i = 0; i < len2; i++) printf("%02x", buf[i]); printf("\n"); + + return 0; +} + +int main(void) +{ + int err = 0; + err += test_sm4(); + err += test_sm4_cbc(); + err += test_sm4_cbc_padding(); + return err; +} diff --git a/tests/x509_algortest.c b/tests/x509_algtest.c similarity index 64% rename from tests/x509_algortest.c rename to tests/x509_algtest.c index edcfde93..06a1268f 100644 --- a/tests/x509_algortest.c +++ b/tests/x509_algtest.c @@ -50,80 +50,94 @@ #include #include #include +#include #include +#include #include static int test_x509_digest_algor(void) { - char *names[] = {"sm3", "md5", "sha1", "sha224", "sha256", "sha384", "sha512" }; + char *names[] = { + "sm3", + "md5", + "sha1", + "sha224", + "sha256", + "sha384", + "sha512", + }; uint8_t buf[256]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - int algor; - uint32_t nodes[32]; - size_t nodes_count; - int i, j; + int oid; + int i; - printf("\n%s\n", __FUNCTION__); + format_print(stderr, 0, 0, "DER\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + oid = x509_digest_algor_from_name(names[i]); + if (x509_digest_algor_to_der(oid, &p, &len) != 1) { + error_print(); + return 1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + format_print(stderr, 0, 0, "OID\n"); for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - algor = x509_digest_algor_from_name(names[i]); - if (x509_digest_algor_to_der(algor, &p, &len) != 1) { + if (x509_digest_algor_from_der(&oid, &cp, &len) != 1) { error_print(); - return -1; + return 1; } - } - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - if (x509_digest_algor_from_der(&algor, nodes, &nodes_count, &cp, &len) != 1) { + if (oid != x509_digest_algor_from_name(names[i])) { error_print(); - return -1; + return 1; } - printf(" %s : ", x509_digest_algor_name(algor)); - for (j = 0; j < nodes_count; j++) { - printf("%d ", nodes[j]); - } - printf("\n"); + format_print(stderr, 0, 4, "%s\n", x509_digest_algor_name(oid)); } + printf("%s() ok\n", __FUNCTION__); return 0; } static int test_x509_encryption_algor(void) { - char *names[] = { "sm4-cbc", "aes128-cbc", "aes192-cbc", "aes256-cbc" }; + char *names[] = { + "sm4-cbc", + "aes128-cbc", + "aes192-cbc", + "aes256-cbc", + }; uint8_t iv[16] = {0}; uint8_t buf[256]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - int algor; - uint32_t nodes[32]; - size_t nodes_count; + int oid; const uint8_t *params; size_t paramslen; - int i, j; - - printf("\n%s\n", __FUNCTION__); + int i; + format_print(stderr, 0, 0, "DER\n"); for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - algor = x509_encryption_algor_from_name(names[i]); - if (x509_encryption_algor_to_der(algor, iv, sizeof(iv), &p, &len) != 1) { + oid = x509_encryption_algor_from_name(names[i]); + if (x509_encryption_algor_to_der(oid, iv, sizeof(iv), &p, &len) != 1) { error_print(); - return -1; + return 1; } + format_bytes(stderr, 0, 4, "", buf, len); } + format_print(stderr, 0, 0, "OID\n"); for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - if (x509_encryption_algor_from_der(&algor, nodes, &nodes_count, ¶ms, ¶mslen, &cp, &len) != 1) { + if (x509_encryption_algor_from_der(&oid, ¶ms, ¶mslen, &cp, &len) != 1 + || asn1_check(params != NULL) != 1 + || asn1_check(paramslen == sizeof(iv)) != 1) { error_print(); - return -1; + return 1; } - printf(" %s : ", x509_encryption_algor_name(algor)); - for (j = 0; j < nodes_count; j++) { - printf("%d ", nodes[j]); - } - printf("\n"); + format_print(stderr, 0, 4, "%s\n", x509_encryption_algor_name(oid)); } + printf("%s() ok\n", __FUNCTION__); return 0; } @@ -147,89 +161,67 @@ static int test_x509_signature_algor(void) uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - int algor; - uint32_t nodes[32]; - size_t nodes_count; - int i, j; - - printf("\n%s\n", __FUNCTION__); + int oid; + int i; + format_print(stderr, 0, 0, "DER\n"); for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - algor = x509_signature_algor_from_name(names[i]); - if (x509_signature_algor_to_der(algor, &p, &len) != 1) { + oid = x509_signature_algor_from_name(names[i]); + if (x509_signature_algor_to_der(oid, &p, &len) != 1) { error_print(); - return -1; + return 1; } + format_bytes(stderr, 0, 4, "", buf, len); } + format_print(stderr, 0, 0, "OID\n"); for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - if (x509_signature_algor_from_der(&algor, nodes, &nodes_count, &cp, &len) != 1) { + if (x509_signature_algor_from_der(&oid, &cp, &len) != 1) { error_print(); - return -1; + return 1; } - printf(" %s : ", x509_signature_algor_name(algor)); - for (j = 0; j < nodes_count; j++) { - printf("%d ", nodes[j]); - } - printf("\n"); + format_print(stderr, 0, 4, "%s\n", x509_signature_algor_name(oid)); } + printf("%s() ok\n", __FUNCTION__); return 0; } static int test_x509_public_key_encryption_algor(void) { - char *names[] = {"sm2encrypt", "rsaesOAEP", "rsaEncryption" }; + char *names[] = { + "sm2encrypt", + // "rsaesOAEP", + // "rsaEncryption", + }; uint8_t buf[256]; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; - int algor; - uint32_t nodes[32]; - size_t nodes_count; + int oid; const uint8_t *params; size_t paramslen; - int i, j; - - printf("\n%s\n", __FUNCTION__); + int i; + format_print(stderr, 0, 0, "DER\n"); for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - algor = x509_public_key_encryption_algor_from_name(names[i]); - if (x509_public_key_encryption_algor_to_der(algor, &p, &len) != 1) { + oid = x509_public_key_encryption_algor_from_name(names[i]); + if (x509_public_key_encryption_algor_to_der(oid, &p, &len) != 1) { error_print(); - return -1; + return 1; } + format_bytes(stderr, 0, 4, "", buf, len); } + format_print(stderr, 0, 0, "OID\n"); for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - if (x509_public_key_encryption_algor_from_der(&algor, nodes, &nodes_count, ¶ms, ¶mslen, &cp, &len) != 1) { + if (x509_public_key_encryption_algor_from_der(&oid, ¶ms, ¶mslen, &cp, &len) != 1) { error_print(); - return -1; + return 1; } - printf(" %s : ", x509_public_key_encryption_algor_name(algor)); - for (j = 0; j < nodes_count; j++) { - printf("%d ", nodes[j]); - } - printf("\n"); + format_print(stderr, 0, 4, "%s\n", x509_public_key_encryption_algor_name(oid)); } + printf("%s() ok\n", __FUNCTION__); return 0; } - - - - - - - - - - - - - - - - - - int main(void) { int err = 0; diff --git a/tests/x509_crltest.c b/tests/x509_crltest.c new file mode 100644 index 00000000..1b43e66f --- /dev/null +++ b/tests/x509_crltest.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2014 - 2021 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static int test_x509_crl_reason(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int reason; + int i; + + for (i = 0; i < 11; i++) { + if (x509_crl_reason_to_der(i, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < 11; i++) { + if (x509_crl_reason_from_der(&reason, &cp, &len) != 1 + || asn1_check(reason == i) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s (%d)\n", x509_crl_reason_name(reason), reason); + } + (void)asn1_length_is_zero(len); + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_crl_entry_ext(void) +{ + int exts[] = { + OID_ce_crl_reasons, + OID_ce_invalidity_date, + OID_ce_certificate_issuer, + }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int oid; + int i; + + for (i = 0; i < sizeof(exts)/sizeof(exts[0]); i++) { + if (x509_crl_entry_ext_id_to_der(exts[i], &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(exts)/sizeof(exts[0]); i++) { + if (x509_crl_entry_ext_id_from_der(&oid, &cp, &len) != 1 + || asn1_check(oid == exts[i]) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_crl_entry_ext_id_name(oid)); + } + (void)asn1_length_is_zero(len); + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_crl_entry_exts(void) +{ + uint8_t exts[256]; + size_t extslen = 0; + int reason = X509_cr_key_compromise; + time_t tv; + uint8_t issuer[256]; + size_t issuer_len = 0; + int critical = 1; + + uint8_t buf[512]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + time(&tv); + if (x509_crl_entry_exts_add_reason(exts, &extslen, sizeof(exts), critical, reason) != 1 + || x509_crl_entry_exts_add_invalidity_date(exts, &extslen, sizeof(exts), critical, tv) != 1 + || x509_crl_entry_exts_add_certificate_issuer(exts, &extslen, sizeof(exts), critical, issuer, issuer_len) != 1 + || x509_crl_entry_exts_to_der(exts, extslen, &p, &len) != 1) { + error_print(); + return -1; + } + x509_crl_entry_exts_print(stderr, 0, 0, "CRL Entry Extensions", exts, extslen); + + return 0; +} + +static int test_x509_revoked_cert(void) +{ + uint8_t serial[20] = { 0x01,0x02 }; + time_t revoke_date; + + uint8_t buf[512]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + const uint8_t *d; + size_t dlen; + + time(&revoke_date); + if (x509_revoked_cert_to_der(serial, sizeof(serial), revoke_date, NULL, 0, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_revoked_cert_print(stderr, 0, 0, "RevokedCertificate", d, dlen); + + return 0; +} + + +int main(void) +{ + int err = 0; + err += test_x509_crl_reason(); + err += test_x509_crl_entry_ext(); + //err += test_x509_crl_entry_exts(); + err += test_x509_revoked_cert(); + return err; + } diff --git a/tests/x509_exttest.c b/tests/x509_exttest.c new file mode 100644 index 00000000..8019eb62 --- /dev/null +++ b/tests/x509_exttest.c @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2014 - 2021 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +static int test_x509_other_name(void) +{ + const uint32_t oid[] = { 1,3,5 }; + const uint8_t value[] = { 0x30,0x01,0x00 }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + uint32_t nodes[32]; + size_t nodes_cnt; + const uint8_t *val; + size_t vlen; + + if (x509_other_name_to_der(oid, sizeof(oid)/sizeof(int), value, sizeof(value), &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_other_name_print(stderr, 0, 0, "OtherName", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (x509_other_name_to_der(oid, sizeof(oid)/sizeof(int), value, sizeof(value), &p, &len) != 1 + || x509_other_name_from_der(nodes, &nodes_cnt, &val, &vlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + asn1_object_identifier_print(stderr, 0, 4, "type-id", NULL, nodes, nodes_cnt); + format_bytes(stderr, 0, 4, "value", val, vlen); + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_edi_party_name(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + int assigner_tag; + const uint8_t *assigner; + size_t assigner_len; + int party_name_tag; + const uint8_t *party_name; + size_t party_name_len; + + if (x509_edi_party_name_to_der( + ASN1_TAG_PrintableString, (uint8_t *)"Hello", 5, + ASN1_TAG_PrintableString, (uint8_t *)"World", 5, + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_edi_party_name_print(stderr, 0, 0, "EDIPartyName", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (x509_edi_party_name_to_der( + ASN1_TAG_PrintableString, (uint8_t *)"Hello", 5, + ASN1_TAG_PrintableString, (uint8_t *)"World", 5, + &p, &len) != 1 + || x509_edi_party_name_from_der( + &assigner_tag, &assigner, &assigner_len, + &party_name_tag, &party_name, &party_name_len, + &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_directory_name_print(stderr, 0, 4, "nameAssigner", assigner_tag, assigner, assigner_len); + x509_directory_name_print(stderr, 0, 4, "partyName", party_name_tag, party_name, party_name_len); + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_general_name(void) +{ + + uint8_t gns[512]; + size_t gnslen = 0; + + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + if (x509_general_names_add_general_name(gns, &gnslen, sizeof(gns), X509_gn_rfc822_name, (uint8_t *)"guan@pku.edu.cn", 15) != 1 + || format_bytes(stderr, 0, 0, "", gns, gnslen) > 2 + || x509_general_names_add_general_name(gns, &gnslen, sizeof(gns), X509_gn_dns_name, (uint8_t *)"www.pku.edu.cn", 14) != 1 + || format_bytes(stderr, 0, 0, "", gns, gnslen) > 2 + || x509_general_names_add_general_name(gns, &gnslen, sizeof(gns), X509_gn_uniform_resource_identifier, (uint8_t *)"http://localhost", 14) != 1 + || format_bytes(stderr, 0, 0, "", gns, gnslen) > 2 + || x509_general_names_add_general_name(gns, &gnslen, sizeof(gns), X509_gn_ip_address, (uint8_t *)"10.0.0.1", 8) != 1 + || format_bytes(stderr, 0, 0, "", gns, gnslen) > 2 + || x509_general_names_to_der(gns, gnslen, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_general_names_print(stderr, 0, 0, "GeneralNames", d, dlen); + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_authority_key_identifier(void) +{ + return 0; +} + +static int test_x509_key_usage(void) +{ + int tests[] = { + 0, + 1, + 2, + X509_KU_NON_REPUDIATION|X509_KU_CRL_SIGN, + 7, + 8, + X509_KU_DIGITAL_SIGNATURE|X509_KU_NON_REPUDIATION|X509_KU_DECIPHER_ONLY, + 0x1ff, + // 0x3ff, // this should return error + }; + + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int usage; + int i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (x509_key_usage_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (x509_key_usage_from_der(&usage, &cp, &len) != 1 + || asn1_check(usage == tests[i]) != 1) { + error_print(); + return -1; + } + x509_key_usage_print(stderr, 0, 4, "KeyUsage", usage); + } + (void)asn1_length_is_zero(len); + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_notice_reference(void) +{ + int notice_nums[] = { 1,2,3,4,5 }; + + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + const uint8_t *d; + size_t dlen; + + int org_tag; + const uint8_t *org; + size_t orglen; + int nums[32]; + size_t nums_cnt; + + if (x509_notice_reference_to_der( + ASN1_TAG_IA5String, (uint8_t *)"Hello", 5, + notice_nums, sizeof(notice_nums)/sizeof(notice_nums[0]), + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_notice_reference_print(stderr, 0, 0, "NoticeReference", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (x509_notice_reference_to_der( + ASN1_TAG_IA5String, (uint8_t *)"Hello", 5, + notice_nums, sizeof(notice_nums)/sizeof(notice_nums[0]), + &p, &len) != 1 + || x509_notice_reference_from_der( + &org_tag, &org, &orglen, + nums, &nums_cnt, sizeof(nums)/sizeof(nums[0]), + &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_revoke_reasons(void) +{ + int tests[] = { + 0, + 1, + 2, + X509_RF_SUPERSEDED|X509_RF_PRIVILEGE_WITHDRAWN|X509_RF_AA_COMPROMISE, + 0x1ff, + }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int bits; + int i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (x509_revoke_reasons_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (x509_revoke_reasons_from_der(&bits, &cp, &len) != 1 + || asn1_check(bits == tests[i]) != 1) { + error_print(); + return -1; + } + x509_revoke_reasons_print(stderr, 0, 4, "ReasonFlags", bits); + } + (void)asn1_length_is_zero(len); + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + + + + + +int main(int argc, char **argv) +{ + int err = 0; + err += test_x509_other_name(); + err += test_x509_edi_party_name(); + err += test_x509_general_name(); + err += test_x509_key_usage(); + err += test_x509_notice_reference(); + err += test_x509_revoke_reasons(); + return err; +} diff --git a/tests/x509_oidtest.c b/tests/x509_oidtest.c new file mode 100644 index 00000000..cd9ab870 --- /dev/null +++ b/tests/x509_oidtest.c @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2014 - 2021 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +static int test_x509_name_type() +{ + char *names[] = { + "name", + "surname", + "givenName", + "initials", + "generationQualifier", + "commonName", + "localityName", + "stateOrProvinceName", + "organizationName", + "organizationalUnitName", + "title", + "dnQualifier", + "countryName", + "serialNumber", + "pseudonym", + "domainComponent", + }; + int oid; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int i; + + format_print(stderr, 0, 0, "DER\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + oid = x509_name_type_from_name(names[i]); + if (asn1_check(oid != OID_undef) != 1 + || x509_name_type_to_der(oid, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + + format_print(stderr, 0, 0, "OID\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + if (x509_name_type_from_der(&oid, &cp, &len) != 1) { + error_print(); + return -1; + } + if (oid != x509_name_type_from_name(names[i])) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_name_type_name(oid)); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_ext_id() +{ + char *names[] = { + "AuthorityKeyIdentifier", + "SubjectKeyIdentifier", + "KeyUsage", + "CertificatePolicies", + "PolicyMappings", + "SubjectAltName", + "IssuerAltName", + "SubjectDirectoryAttributes", + "BasicConstraints", + "NameConstraints", + "PolicyConstraints", + "ExtKeyUsage", + "CRLDistributionPoints", + "InhibitAnyPolicy", + "FreshestCRL", + }; + int oid; + uint32_t nodes[32]; + size_t nodes_cnt; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int i; + + format_print(stderr, 0, 0, "DER\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + oid = x509_ext_id_from_name(names[i]); + if (asn1_check(oid != OID_undef) != 1 + || x509_ext_id_to_der(oid, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + + format_print(stderr, 0, 0, "ExtnID\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + if (x509_ext_id_from_der(&oid, nodes, &nodes_cnt, &cp, &len) != 1) { + error_print(); + return -1; + } + if (oid != x509_ext_id_from_name(names[i])) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_ext_id_name(oid)); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_qualifier_id(void) +{ + char *names[] = { + "CPS", + "userNotice", + }; + int oid; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int i; + + format_print(stderr, 0, 0, "DER\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + oid = x509_qualifier_id_from_name(names[i]); + if (asn1_check(oid != OID_undef) != 1 + || x509_qualifier_id_to_der(oid, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + + format_print(stderr, 0, 0, "OID\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + if (x509_qualifier_id_from_der(&oid, &cp, &len) != 1) { + error_print(); + return -1; + } + if (asn1_check(oid == x509_qualifier_id_from_name(names[i])) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_qualifier_id_name(oid)); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_cert_policy_id(void) +{ + char *names[] = { + "anyPolicy", + }; + int oid; + uint32_t nodes[32]; + size_t nodes_cnt; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int i; + + format_print(stderr, 0, 0, "DER\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + oid = x509_cert_policy_id_from_name(names[i]); + if (asn1_check(oid != OID_undef) != 1 + || x509_cert_policy_id_to_der(oid, NULL, 0, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + + format_print(stderr, 0, 0, "OID\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + if (x509_cert_policy_id_from_der(&oid, nodes, &nodes_cnt, &cp, &len) != 1) { + error_print(); + return -1; + } + if (oid != x509_cert_policy_id_from_name(names[i])) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_cert_policy_id_name(oid)); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_key_purpose(void) +{ + char *names[] = { + "serverAuth", + "clientAuth", + "codeSigning", + "emailProtection", + "timeStamping", + "OCSPSigning", + }; + int oid; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int i; + + format_print(stderr, 0, 0, "DER\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + oid = x509_key_purpose_from_name(names[i]); + if (asn1_check(oid != OID_undef) != 1 + || x509_key_purpose_to_der(oid, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + + format_print(stderr, 0, 0, "OID\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + if (x509_key_purpose_from_der(&oid, &cp, &len) != 1) { + error_print(); + return -1; + } + if (oid != x509_key_purpose_from_name(names[i])) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_key_purpose_name(oid)); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +int main(void) +{ + int err = 0; + err += test_x509_name_type(); + err += test_x509_ext_id(); + err += test_x509_qualifier_id(); + err += test_x509_cert_policy_id(); + err += test_x509_key_purpose(); + return err; +} diff --git a/tests/x509_reqtest.c b/tests/x509_reqtest.c new file mode 100644 index 00000000..809494bb --- /dev/null +++ b/tests/x509_reqtest.c @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2014 - 2021 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static int test_x509_request_info(void) +{ + uint8_t subject[256]; + size_t subject_len; + SM2_KEY sm2_key; + + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + int version; + const uint8_t *subj; + size_t subj_len; + SM2_KEY pub_key; + const uint8_t *attrs; + size_t attrs_len; + + if (sm2_key_generate(&sm2_key) != 1 + || x509_name_set(subject, &subject_len, sizeof(subject), "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1 + || x509_request_info_to_der(X509_version_v1, subject, subject_len, &sm2_key, NULL, 0, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_request_info_print(stderr, 0, 0, "CertificationRequestInfo", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (x509_request_info_to_der(X509_version_v1, subject, subject_len, &sm2_key, NULL, 0, &p, &len) != 1 + || x509_request_info_from_der(&version, &subj, &subj_len, &pub_key, &attrs, &attrs_len, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 0, "CertificationRequestInfo\n"); + format_print(stderr, 0, 4, "version: %d\n", version); + x509_name_print(stderr, 0, 4, "subject", subj, subj_len); + sm2_public_key_print(stderr, 0, 4, "publicKey", &pub_key); + format_bytes(stderr, 0, 4, "attributes", attrs, attrs_len); + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_request(void) +{ + uint8_t subject[256]; + size_t subject_len; + SM2_KEY sm2_key; + uint8_t signature[128] = { 0x01, 0x02 }; + + uint8_t buf[512]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + int version; + const uint8_t *subj; + size_t subj_len; + SM2_KEY pub_key; + const uint8_t *attrs; + size_t attrs_len; + int sig_alg; + const uint8_t *sig; + size_t siglen; + + if (sm2_key_generate(&sm2_key) != 1 + || x509_name_set(subject, &subject_len, sizeof(subject), "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1 + || x509_request_to_der(X509_version_v1, subject, subject_len, &sm2_key, NULL, 0, + OID_sm2sign_with_sm3, signature, sizeof(signature), &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_request_print(stderr, 0, 0, "CertificationRequest", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (x509_request_to_der(X509_version_v1, subject, subject_len, &sm2_key, NULL, 0, + OID_sm2sign_with_sm3, signature, sizeof(signature), &p, &len) != 1 + || x509_request_from_der(&version, &subj, &subj_len, &pub_key, &attrs, &attrs_len, + &sig_alg, &sig, &siglen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 0, "CertificationRequest\n"); + format_print(stderr, 0, 4, "version: %d\n", version); + x509_name_print(stderr, 0, 4, "subject", subj, subj_len); + sm2_public_key_print(stderr, 0, 4, "publicKey", &pub_key); + format_bytes(stderr, 0, 4, "attributes", attrs, attrs_len); + format_print(stderr, 0, 4, "signatureAlgor: %s\n", x509_signature_algor_name(sig_alg)); + format_bytes(stderr, 0, 4, "signature", sig, siglen); + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_req(void) +{ + uint8_t subject[256]; + size_t subject_len; + SM2_KEY sm2_key; + + uint8_t req[512]; + size_t reqlen = 0; + + int version; + const uint8_t *subj; + size_t subj_len; + SM2_KEY pub_key; + const uint8_t *attrs; + size_t attrs_len; + + if (sm2_key_generate(&sm2_key) != 1 + || x509_name_set(subject, &subject_len, sizeof(subject), "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1 + || x509_req_sign(req, &reqlen, sizeof(req), + X509_version_v1, subject, subject_len, &sm2_key, NULL, 0, + OID_sm2sign_with_sm3, &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { + error_print(); + return -1; + } + x509_req_print(stderr, 0, 0, "CertificationRequest", req, reqlen); + + + + FILE *fp; + + if ((fp = fopen("req.pem", "w")) == NULL) { + error_print(); + return -1; + } + if (x509_req_to_pem(req, reqlen, fp) != 1) { + error_print(); + return -1; + } + fclose(fp); + x509_req_to_pem(req, reqlen, stderr); + + + memset(req, 0, sizeof(req)); + + if ((fp = fopen("req.pem", "r")) == NULL) { + error_print(); + return -1; + } + if (x509_req_from_pem(req, &reqlen, sizeof(req), fp) != 1) { + error_print(); + return -1; + } + if (x509_req_verify(req, reqlen, &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 0, "x509_req_verify() success\n"); + + + + + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + + + + + + + + + + +int main(void) +{ + int err = 0; + err += test_x509_request_info(); + err += test_x509_request(); + err += test_x509_req(); + return err; +} + diff --git a/tests/sm4cbctest.c b/tests/x509_strtest.c similarity index 59% rename from tests/sm4cbctest.c rename to tests/x509_strtest.c index 9a746864..9c402b44 100644 --- a/tests/sm4cbctest.c +++ b/tests/x509_strtest.c @@ -49,64 +49,66 @@ #include #include #include -#include +#include +#include +#include #include +#include -static int test_sm4_cbc(void) +static int test_x509_directory_name(void) { - SM4_KEY sm4_key; - uint8_t key[16] = {0}; - uint8_t iv[16]; + uint8_t str[] = { 'a', 'b', 'c', 0 }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int tag; + const uint8_t *d; + size_t dlen; - uint8_t buf1[2] = {0}; - uint8_t buf2[32] = {0}; - uint8_t buf3[47] = {0}; - uint8_t buf4[96] = {0}; - uint8_t buf5[96]; - int i; - - sm4_set_encrypt_key(&sm4_key, key); - sm4_cbc_encrypt(&sm4_key, iv, buf2, 2, buf4); - - for (i = 0; i < 32; i++) { - printf("%02x", buf4[i]); + if (x509_directory_name_check_ex(ASN1_TAG_UTF8String, str, 3, 1, 10) != 1 // str,4 will fail + || x509_directory_name_to_der(ASN1_TAG_UTF8String, str, 3, &p, &len) != 1 + || x509_directory_name_from_der(&tag, &d, &dlen, &cp, &len) != 1 + || asn1_check(tag == ASN1_TAG_UTF8String) != 1 + || asn1_check(dlen == 3) != 1 + || asn1_check(memcmp(str, d, dlen) == 0) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return 1; } - printf("\n"); - return 1; + printf("%s() ok\n", __FUNCTION__); + return 0; } -static int test_sm4_cbc_padding(void) +static int test_x509_display_text(void) { - SM4_KEY enc_key; - SM4_KEY dec_key; - uint8_t key[16] = {0}; - uint8_t iv[16] = {0}; - uint8_t in[64]; - uint8_t out[128]; - uint8_t buf[128]; - size_t len1, len2, i; + uint8_t str[] = { 'a', 'b', 'c', 0 }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int tag; + const uint8_t *d; + size_t dlen; - for (i = 0; i < sizeof(in); i++) { - in[i] = i; + if (x509_display_text_check(ASN1_TAG_UTF8String, str, 3) != 1 // str,4 will fail + || x509_display_text_to_der(ASN1_TAG_UTF8String, str, 3, &p, &len) != 1 + || x509_display_text_from_der(&tag, &d, &dlen, &cp, &len) != 1 + || asn1_check(tag == ASN1_TAG_UTF8String) != 1 + || asn1_check(dlen == 3) != 1 + || asn1_check(memcmp(str, d, dlen) == 0) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return 1; } - - sm4_set_encrypt_key(&enc_key, key); - sm4_set_decrypt_key(&dec_key, key); - - sm4_cbc_padding_encrypt(&enc_key, iv, in, 33, out, &len1); - printf("c = (%zu) ", len1); for (i = 0; i < len1; i++) printf("%02x", out[i]); printf("\n"); - - sm4_cbc_padding_decrypt(&dec_key, iv, out, len1, buf, &len2); - printf("m = (%zu) ", len2); for (i = 0; i < len2; i++) printf("%02x", buf[i]); printf("\n"); - - return 1; + printf("%s() ok\n", __FUNCTION__); + return 0; } - - int main(void) { - test_sm4_cbc(); - test_sm4_cbc_padding(); - return 1; + int err = 0; + err += test_x509_directory_name(); + err += test_x509_display_text(); + return err; } diff --git a/tests/x509test.c b/tests/x509test.c index 06b085b3..fa69d082 100644 --- a/tests/x509test.c +++ b/tests/x509test.c @@ -50,282 +50,397 @@ #include #include #include +#include +#include #include #include #include -#if 0 -static int test_x509_validity(void) + +static int test_x509_version(void) { - int err = 0; - X509_VALIDITY validity; - uint8_t buf[64] = {0}; - const uint8_t *cp = buf; + + int tests[] = { + X509_version_v1, + X509_version_v2, + X509_version_v3, + -1, + }; + uint8_t buf[256]; uint8_t *p = buf; + const uint8_t *cp = buf; size_t len = 0; size_t i; - printf("%s\n", __FUNCTION__); - memset(&validity, 0, sizeof(X509_VALIDITY)); + format_print(stderr, 0, 0, "Version\n"); + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (x509_explicit_version_to_der(i, tests[i], &p, &len) < 0) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + int ver; + if (x509_explicit_version_from_der(i, &ver, &cp, &len) < 0 + || asn1_check(ver == tests[i]) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_version_name(ver)); + } + (void)asn1_length_is_zero(len); + printf("%s() ok\n", __FUNCTION__); + return 0; +} - x509_validity_set_days(&validity, time(NULL), 365 * 10); - x509_validity_to_der(&validity, &p, &len); - print_der(buf, len); - printf("\n"); - memset(&validity, 0, sizeof(X509_VALIDITY)); - x509_validity_from_der(&validity, &cp, &len); - x509_validity_print(stdout, &validity, 0, 0); +static int test_x509_validity(void) +{ + time_t not_before, not_before_; + time_t not_after, not_after_; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + size_t i; - printf("\n"); - return err; + time(¬_before); + + format_print(stderr, 0, 0, "Validity\n"); + if (x509_validity_add_days(¬_after, not_before, 365) != 1 + || x509_validity_to_der(not_before, not_after, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + if (x509_validity_from_der(¬_before_, ¬_after_, &cp, &len) != 1 + || asn1_check(not_before == not_before_) != 1 + || asn1_check(not_after == not_after_) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return 1; + } + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_attr_type_and_value(void) +{ + int oid; + int tag; + const uint8_t *d; + size_t dlen; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + format_print(stderr, 0, 0, "AttributeTypeAndValue\n"); + if (x509_attr_type_and_value_to_der(OID_at_locality_name, ASN1_TAG_PrintableString, (uint8_t *)"Haidian", strlen("Haidian"), &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + if (x509_attr_type_and_value_from_der(&oid, &tag, &d, &dlen, &cp, &len) != 1 + || asn1_check(oid == OID_at_locality_name) != 1 + || asn1_check(tag == ASN1_TAG_PrintableString) != 1 + || asn1_check(dlen == strlen("Haidian")) != 1 + || asn1_check(memcmp("Haidian", d, dlen) == 0) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s : %s ", x509_name_type_name(oid), asn1_tag_name(tag)); + format_string(stderr, 0, 0, "", d, dlen); + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_rdn(void) +{ + int oid; + int tag; + const uint8_t *d; + size_t dlen; + const uint8_t *more; + size_t morelen; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + format_print(stderr, 0, 0, "RDN\n"); + if (x509_rdn_to_der(OID_at_locality_name, ASN1_TAG_PrintableString, + (uint8_t *)"Haidian", strlen("Haidian"), NULL, 0, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + if (x509_rdn_from_der(&oid, &tag, &d, &dlen, &more, &morelen, &cp, &len) != 1 + || asn1_check(oid == OID_at_locality_name) != 1 + || asn1_check(tag == ASN1_TAG_PrintableString) != 1 + || asn1_check(dlen == strlen("Haidian")) != 1 + || asn1_check(memcmp("Haidian", d, dlen) == 0) != 1 + || asn1_check(more == NULL) != 1 + || asn1_check(morelen == 0) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s : %s ", x509_name_type_name(oid), asn1_tag_name(tag)); + format_string(stderr, 0, 0, "", d, dlen); + printf("%s() ok\n", __FUNCTION__); + return 0; } static int test_x509_name(void) { int err = 0; - X509_NAME name; + uint8_t name[512]; + size_t namelen = 0; uint8_t buf[1024]; const uint8_t *cp = buf; uint8_t *p = buf; size_t len = 0; - printf("%s\n", __FUNCTION__); - - memset(&name, 0, sizeof(X509_NAME)); - x509_name_add_rdn(&name, OID_at_countryName, ASN1_TAG_PrintableString, "CN"); - x509_name_add_rdn(&name, OID_at_stateOrProvinceName, ASN1_TAG_PrintableString, "Beijing"); - x509_name_add_rdn(&name, OID_at_organizationName, ASN1_TAG_PrintableString, "PKU"); - x509_name_add_rdn(&name, OID_at_organizationalUnitName, ASN1_TAG_PrintableString, "CS"); - x509_name_add_rdn(&name, OID_at_commonName, ASN1_TAG_PrintableString, "infosec"); - - if (x509_name_to_der(&name, &p, &len) != 1) { + if (x509_name_add_country_name(name, &namelen, sizeof(name), "CN") != 1 + || format_bytes(stderr, 0, 4, "", name, namelen) > 2 + || x509_name_add_locality_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"Haidian", strlen("Haidian")) != 1 + || format_bytes(stderr, 0, 4, "", name, namelen) > 2 + || x509_name_add_state_or_province_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"Beijing", strlen("Beijing")) != 1 + || format_bytes(stderr, 0, 4, "", name, namelen) > 2 + || x509_name_add_organization_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"PKU", strlen("PKU")) != 1 + || format_bytes(stderr, 0, 4, "", name, namelen) > 2 + || x509_name_add_organizational_unit_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"CS", strlen("CS")) != 1 + || format_bytes(stderr, 0, 4, "", name, namelen) > 2 + || x509_name_add_common_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"CA", strlen("CA")) != 1 + || format_bytes(stderr, 0, 4, "", name, namelen) > 2 + ) { error_print(); - err++; - goto end; + return 1; } - print_der(buf, len); - printf("\n"); - - if (x509_name_from_der(&name, &cp, &len) != 1 - || len > 0) { - error_print(); - err++; - goto end; - } - x509_name_print(stdout, &name, 0, 0); - -end: - printf("\n"); - return err; -} - -static int test_x509_signature_algor(int oid) -{ - int err = 0; - int tests[] = {OID_sm2sign_with_sm3, OID_rsasign_with_sm3}; - int val; - uint32_t nodes[32]; - size_t nodes_count; - uint8_t buf[128]; - const uint8_t *cp = buf; - uint8_t *p = buf; - size_t len = 0; - size_t i; - - printf("%s\n", __FUNCTION__); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - printf("%s\n", asn1_object_identifier_name(tests[i])); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (x509_signature_algor_to_der(tests[i], &p, &len) != 1) { - error_print(); - err++; - goto end; - } - print_der(buf, len); - printf("\n"); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (x509_signature_algor_from_der(&val, nodes, &nodes_count, &cp, &len) != 1) { - error_print(); - err++; - goto end; - } - if (val != tests[i]) { - error_print(); - err++; - goto end; - } - printf("%s\n", asn1_object_identifier_name(tests[i])); - } - -end: - printf("\n"); - return err; + format_bytes(stdout, 0, 0, "der ", name, namelen); + x509_name_print(stdout, 0, 0, "Name", name, namelen); + return 0; } static int test_x509_public_key_info(void) { int err = 0; - SM2_KEY key; - X509_PUBLIC_KEY_INFO pkey_info; + SM2_KEY sm2_key; + SM2_KEY pub_key; uint8_t buf[256]; const uint8_t *cp = buf; uint8_t *p = buf; size_t len = 0; + const uint8_t *d; + size_t dlen; - printf("%s\n", __FUNCTION__); - sm2_keygen(&key); - x509_public_key_info_set_sm2(&pkey_info, &key); - - if (x509_public_key_info_to_der(&pkey_info, &p, &len) != 1) { + if (sm2_key_generate(&sm2_key) != 1 + || x509_public_key_info_to_der(&sm2_key, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { error_print(); - return -1; + return 1; } - print_der(buf, len); - printf("\n"); - - if (x509_public_key_info_from_der(&pkey_info, &cp, &len) != 1 - || len > 0) { + x509_public_key_info_print(stdout, 0, 0, "PublicKeyInfo", d, dlen); + if (sm2_key_generate(&sm2_key) != 1 + || x509_public_key_info_to_der(&sm2_key, &p, &len) != 1 + || x509_public_key_info_from_der(&pub_key, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { error_print(); - return -1; + return 1; } + sm2_public_key_print(stdout, 0, 8, "ECPublicKey", &pub_key); - x509_public_key_info_print(stdout, &pkey_info, 0, 0); - - printf("\n"); - return err; + printf("%s() ok\n", __FUNCTION__); + return 0; } -static int test_x509_certificate(void) +static int set_x509_name(uint8_t *name, size_t *namelen, size_t maxlen) { - int err = 0; - X509_CERTIFICATE _cert, *cert = &_cert; - int rv; - int version = X509_version_v3; - uint8_t sn[12]; - X509_NAME issuer; - X509_NAME subject; - time_t not_before; + *namelen = 0; + if (x509_name_add_country_name(name, namelen, maxlen, "CN") != 1 + || x509_name_add_locality_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"Haidian", strlen("Haidian")) != 1 + || x509_name_add_state_or_province_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"Beijing", strlen("Beijing")) != 1 + || x509_name_add_organization_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"PKU", strlen("PKU")) != 1 + || x509_name_add_organizational_unit_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"CS", strlen("CS")) != 1 + || x509_name_add_common_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"CA", strlen("CA")) != 1) { + error_print(); + return -1; + } + return 1; +} - SM2_KEY key; - - uint8_t buf[2048] = {0}; +static int test_x509_tbs_cert(void) +{ + uint8_t serial[20] = { 0x01, 0x00 }; + size_t serial_len; + uint8_t issuer[256]; + size_t issuer_len = 0; + time_t not_before, not_after; + uint8_t subject[256]; + size_t subject_len = 0; + SM2_KEY sm2_key; + uint8_t buf[1024] = {0}; uint8_t *p = buf; const uint8_t *cp = buf; size_t len = 0; + const uint8_t *d; + size_t dlen; - printf("%s\n", __FUNCTION__); - - memset(cert, 0, sizeof(X509_CERTIFICATE)); - - rand_bytes(sn, sizeof(sn)); - - memset(&issuer, 0, sizeof(X509_NAME)); - // add_rdn 应该用一个ex来支持长度 - x509_name_add_rdn(&issuer, OID_at_countryName, ASN1_TAG_PrintableString, "CN"); - x509_name_add_rdn(&issuer, OID_at_stateOrProvinceName, ASN1_TAG_PrintableString, "Beijing"); - x509_name_add_rdn(&issuer, OID_at_organizationName, ASN1_TAG_PrintableString, "PKU"); - x509_name_add_rdn(&issuer, OID_at_organizationalUnitName, ASN1_TAG_PrintableString, "CS"); - x509_name_add_rdn(&issuer, OID_at_commonName, ASN1_TAG_PrintableString, "CA"); - - memset(&subject, 0, sizeof(X509_NAME)); - x509_name_add_rdn(&subject, OID_at_countryName, ASN1_TAG_PrintableString, "CN"); - x509_name_add_rdn(&subject, OID_at_stateOrProvinceName, ASN1_TAG_PrintableString, "Beijing"); - x509_name_add_rdn(&subject, OID_at_organizationName, ASN1_TAG_PrintableString, "PKU"); - x509_name_add_rdn(&subject, OID_at_organizationalUnitName, ASN1_TAG_PrintableString, "CS"); - x509_name_add_rdn(&subject, OID_at_commonName, ASN1_TAG_PrintableString, "infosec"); - + set_x509_name(issuer, &issuer_len, sizeof(issuer)); time(¬_before); + x509_validity_add_days(¬_after, not_before, 365); + set_x509_name(subject, &subject_len, sizeof(subject)); + sm2_key_generate(&sm2_key); - rv = x509_certificate_set_version(cert, version); - rv = x509_certificate_set_serial_number(cert, sn, sizeof(sn)); - rv = x509_certificate_set_signature_algor(cert, OID_sm2sign_with_sm3); // 这个不是应该在设置公钥的时候一起设置吗? - rv = x509_certificate_set_issuer(cert, &issuer); - rv = x509_certificate_set_subject(cert, &subject); - rv = x509_certificate_set_validity(cert, not_before, 365); + if (x509_tbs_cert_to_der( + X509_version_v3, + serial, sizeof(serial), + OID_sm2sign_with_sm3, + issuer, issuer_len, + not_before, not_after, + subject, subject_len, + &sm2_key, + NULL, 0, + NULL, 0, + NULL, 0, + &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 0, "tbs_cert", buf, len); + if (asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_tbs_cert_print(stderr, 0, 4, "TBSCertificate", d, dlen); - sm2_keygen(&key); - rv = x509_certificate_set_subject_public_key_info_sm2(cert, &key); + return 0; +} + +static int test_x509_cert_get(const uint8_t *cert, size_t certlen) +{ + const uint8_t *serial; + size_t serial_len; + const uint8_t *issuer; + size_t issuer_len; + const uint8_t *subject; + size_t subject_len; + SM2_KEY public_key; + + if (x509_cert_get_issuer_and_serial_number(cert, certlen, &issuer, &issuer_len, &serial, &serial_len) != 1 + || x509_cert_get_subject(cert, certlen, &subject, &subject_len) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "SerialNumber", serial, serial_len); + x509_name_print(stderr, 0, 4, "Issuer", issuer, issuer_len); + x509_name_print(stderr, 0, 4, "Subject", subject, subject_len); + sm2_public_key_print(stderr, 0, 4, "SubjectPublicKey", &public_key); + return 0; +} + +static int test_x509_cert(void) +{ + uint8_t serial[20] = { 0x01, 0x00 }; + size_t serial_len; + uint8_t issuer[256]; + size_t issuer_len = 0; + time_t not_before, not_after; + uint8_t subject[256]; + size_t subject_len = 0; + SM2_KEY sm2_key; + uint8_t cert[1024] = {0}; + uint8_t *p = cert; + const uint8_t *cp = cert; + size_t certlen = 0; + + set_x509_name(issuer, &issuer_len, sizeof(issuer)); + time(¬_before); + x509_validity_add_days(¬_after, not_before, 365); + set_x509_name(subject, &subject_len, sizeof(subject)); + sm2_key_generate(&sm2_key); + + if (x509_cert_sign( + cert, &certlen, sizeof(cert), + X509_version_v3, + serial, sizeof(serial), + OID_sm2sign_with_sm3, + issuer, issuer_len, + not_before, not_after, + subject, subject_len, + &sm2_key, + NULL, 0, + NULL, 0, + NULL, 0, + &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "cert", cert, certlen); + x509_cert_print(stderr, 0, 4, "Certificate", cert, certlen); + + if (x509_cert_verify(cert, certlen, &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { + error_print(); + return -1; + } + printf("x509_cert_verify() success\n"); + + test_x509_cert_get(cert, certlen); - rv = x509_certificate_generate_subject_key_identifier(cert, 1); + FILE *fp; + + if (!(fp = fopen("cert.pem", "w"))) { + error_print(); + return -1; + } + + x509_cert_to_pem(cert, certlen, fp); + x509_cert_to_pem(cert, certlen, stderr); + fclose(fp); - rv = x509_certificate_sign_sm2(cert, &key); + if (!(fp = fopen("cert.pem", "r"))) { + error_print(); + return -1; + } - rv = x509_certificate_to_der(cert, &p, &len); - print_der(buf, len); - printf("\n"); - - memset(cert, 0, sizeof(X509_CERTIFICATE)); - x509_certificate_from_der(cert, &cp, &len); - - x509_certificate_print(stdout, cert, 0, 0); + memset(cert, 0, sizeof(cert)); + if (x509_cert_from_pem(cert, &certlen, sizeof(cert), fp) != 1) { + error_print(); + return -1; + } + x509_cert_print(stderr, 0, 4, "Certificate", cert, certlen); return 0; } + static int test_x509_cert_request(void) { - int err = 0; - X509_CERT_REQUEST req; - X509_NAME subject; - SM2_KEY keypair; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - printf("%s : \n", __func__); - - memset(&subject, 0, sizeof(X509_NAME)); - x509_name_add_rdn(&subject, OID_at_countryName, ASN1_TAG_PrintableString, "CN"); - x509_name_add_rdn(&subject, OID_at_stateOrProvinceName, ASN1_TAG_PrintableString, "Beijing"); - x509_name_add_rdn(&subject, OID_at_organizationName, ASN1_TAG_PrintableString, "PKU"); - x509_name_add_rdn(&subject, OID_at_organizationalUnitName, ASN1_TAG_PrintableString, "CS"); - x509_name_add_rdn(&subject, OID_at_commonName, ASN1_TAG_PrintableString, "infosec"); - - sm2_keygen(&keypair); - - if (x509_cert_request_set_sm2(&req, &subject, &keypair) != 1 - || x509_cert_request_sign_sm2(&req, &keypair) != 1 - || x509_cert_request_to_der(&req, &p, &len) != 1) { - error_print(); - err++; - goto end; - } - print_der(buf, len); - printf("\n"); - - memset(&req, 0, sizeof(req)); - if (x509_cert_request_from_der(&req, &cp, &len) != 1) { - error_print(); - err++; - goto end; - } - - x509_cert_request_print(stdout, &req, 0, 0); - -end: - return err; + return 0; } -#endif - int main(void) { int err = 0; - //err += test_x509_validity(); - //err += test_x509_signature_algor(OID_sm2sign_with_sm3); - //err += test_x509_signature_algor(OID_rsasign_with_sm3); - //err += test_x509_name(); - //err += test_x509_public_key_info(); - //err += test_x509_certificate(); +// err += test_x509_version(); +// err += test_x509_validity(); +// err += test_x509_attr_type_and_value(); +// err += test_x509_rdn(); +// err += test_x509_name(); +// err += test_x509_public_key_info(); +// err += test_x509_tbs_cert(); + err += test_x509_cert(); //err += test_x509_cert_request(); //test_x509_extensions(); - return 1; + return err; } diff --git a/tests/zuctest.c b/tests/zuctest.c index 7e71721b..7653d637 100644 --- a/tests/zuctest.c +++ b/tests/zuctest.c @@ -1,4 +1,4 @@ -/* ==================================================================== +/* * Copyright (c) 2014 - 2018 The GmSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,7 +44,6 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== */ #include diff --git a/tools/certgen.c b/tools/certgen.c index 89f8164f..cfe9c2eb 100644 --- a/tools/certgen.c +++ b/tools/certgen.c @@ -84,11 +84,11 @@ void print_usage(const char *prog) printf("\n"); printf("Options:\n"); printf(" -C country name\n"); + printf(" -ST state of province name\n"); + printf(" -L locality name\n"); printf(" -O orgnization name\n"); printf(" -OU orgnizational unit name\n"); printf(" -CN common name\n"); - printf(" -L locality name\n"); - printf(" -ST state of province name\n"); printf(" -days validity days\n"); printf(" -key private key file\n"); printf(" -pass pass password\n"); @@ -96,45 +96,30 @@ void print_usage(const char *prog) int main(int argc, char **argv) { - int ret = -1; char *prog = argv[0]; + char *country = NULL; char *state = NULL; + char *locality = NULL; char *org = NULL; char *org_unit = NULL; char *common_name = NULL; - char *keyfile = NULL; int days = 0; - char *outfile = NULL; - + char *keyfile = NULL; FILE *keyfp = NULL; + char *pass = NULL; + char *outfile = NULL; FILE *outfp = stdout; - X509_CERTIFICATE cert; - - char *pass = NULL; - + SM2_KEY sm2_key; uint8_t serial[12]; - X509_NAME name; + uint8_t name[256]; + size_t namelen; time_t not_before; - SM2_KEY sm2_key; // 这个应该是从文件中读取的! + time_t not_after; uint8_t uniq_id[32]; - - uint8_t buf[1024]; - const uint8_t *cp = buf; - uint8_t *p = buf; - size_t len = 0; - - - - int kp[] = { - OID_kp_serverAuth, - OID_kp_clientAuth, - OID_kp_codeSigning, - OID_kp_emailProtection, - OID_kp_timeStamping, - OID_kp_OCSPSigning, - }; + uint8_t cert[1024]; + size_t certlen; argc--; argv++; @@ -216,91 +201,34 @@ int main(int argc, char **argv) } } - if (sm2_enced_private_key_info_from_pem(&sm2_key, pass, keyfp) != 1) { - error_print(); - goto end; - } - - - rand_bytes(serial, sizeof(serial)); - - - - memset(&name, 0, sizeof(name)); - - - - if (country) { - if (x509_name_set_country(&name, country) != 1) { - error_print(); - goto end; - } - } - if (state) { - if (x509_name_set_state_or_province(&name, state) != 1) { - error_print(); - goto end; - } - } - if (org) { - if (x509_name_set_organization(&name, org) != 1) { - error_print(); - goto end; - } - } - if (org_unit) { - if (x509_name_set_organizational_unit(&name, org_unit) != 1) { - error_print(); - goto end; - } - } - if (!common_name) { - error_print(); - goto end; - } else { - if (x509_name_set_common_name(&name, common_name) != 1) { - error_print(); - goto end; - } - } - time(¬_before); - - - memset(&cert, 0, sizeof(cert)); - x509_certificate_set_version(&cert, X509_version_v3); - x509_certificate_set_serial_number(&cert, serial, sizeof(serial)); - x509_certificate_set_signature_algor(&cert, OID_sm2sign_with_sm3); - x509_certificate_set_issuer(&cert, &name); - x509_certificate_set_subject(&cert, &name); - x509_certificate_set_validity(&cert, not_before, days); - x509_certificate_set_subject_public_key_info_sm2(&cert, &sm2_key); - x509_certificate_set_issuer_unique_id_from_public_key(&cert, &sm2_key); - x509_certificate_set_subject_unique_id_from_public_key(&cert, &sm2_key); - - x509_certificate_set_basic_constraints(&cert, ASN1_TRUE, ASN1_TRUE, 6); - - x509_certificate_set_ext_key_usage(&cert, ASN1_TRUE, kp, sizeof(kp)/sizeof(kp[0])); - - x509_certificate_generate_subject_key_identifier(&cert, ASN1_TRUE); - - x509_certificate_set_inhibit_any_policy(&cert, ASN1_TRUE, 20); - - - - x509_certificate_set_policy_constraints(&cert, ASN1_FALSE, 5, 5); - - - - - x509_certificate_sign_sm2(&cert, &sm2_key); - x509_certificate_to_pem(&cert, outfp); - ret = 0; - goto end; + if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1 + || rand_bytes(serial, sizeof(serial)) != 1 + || x509_name_set(name, &namelen, sizeof(name), + country, state, locality, org, org_unit, common_name) != 1 + || x509_validity_add_days(¬_after, not_before, days) != 1 + || x509_cert_sign( + cert, &certlen, sizeof(cert), + X509_version_v3, + serial, sizeof(serial), + OID_sm2sign_with_sm3, + name, namelen, + not_before, not_after, + name, namelen, + &sm2_key, + NULL, 0, + NULL, 0, + NULL, 0, + &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1 + || x509_cert_to_pem(cert, certlen, outfp) != 1) { + error_print(); + return -1; + } + return 0; bad: fprintf(stderr, "%s: commands should not be used together\n", prog); end: - return ret; + return -1; } diff --git a/tools/certparse.c b/tools/certparse.c index 9c260e17..6eb81f5c 100644 --- a/tools/certparse.c +++ b/tools/certparse.c @@ -69,7 +69,7 @@ int main(void) goto end; } fprintf(stdout, "Certificate\n"); - x509_cert_print(stdout, 0, 0, cert, certlen); + x509_cert_print(stdout, 0, 0, "Certificate", cert, certlen); x509_cert_to_pem(cert, certlen, stdout); fprintf(stdout, "\n"); } diff --git a/tools/certverify.c b/tools/certverify.c index e9b9eb9d..cb0bc64d 100644 --- a/tools/certverify.c +++ b/tools/certverify.c @@ -59,66 +59,21 @@ // 比如最基本的是证书中的签名、有效期、各个扩展等 // 外部相关的:证书链、CRL等 - -static int verify_cert(const X509_CERTIFICATE *cert, const X509_CERTIFICATE *cacert) -{ - int ret; - SM2_KEY ca_pubkey; - - if (x509_name_equ(&cert->tbs_certificate.issuer, &cacert->tbs_certificate.subject) != 1) { - error_print(); - return -1; - } - if (x509_certificate_get_public_key(cacert, &ca_pubkey) != 1) { - error_print(); - return -1; - } - if ((ret = x509_certificate_verify(cert, &ca_pubkey)) < 0) { - error_print(); - return -1; - } - return ret; -} - -static int find_cacert(X509_CERTIFICATE *cacert, FILE *fp, const X509_NAME *issuer) -{ - int ret; - for (;;) { - if ((ret = x509_certificate_from_pem(cacert, fp)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_name_equ(&cacert->tbs_certificate.subject, issuer) == 1) { - return 1; - } - } - return 0; -} - - -void print_usage(const char *prog) -{ - printf("Usage: %s command [options] ...\n", prog); - printf("\n"); - printf("Options:\n"); - printf(" -cert PKCS #10 certificate request file\n"); - printf(" -cacert CA certificate file\n"); -} - int main(int argc, char **argv) { - int ret = -1; + int ret = 0; char *prog = argv[0]; char *certfile = NULL; - char *cacertfile = NULL; FILE *certfp = NULL; + + char *cacertfile = NULL; FILE *cacertfp = NULL; - X509_CERTIFICATE cert1; - X509_CERTIFICATE cert2; - X509_CERTIFICATE *cert = &cert1; - X509_CERTIFICATE *cacert = &cert2; - X509_CERTIFICATE *tmpcert; + uint8_t cert[1024]; + size_t certlen; + uint8_t cacert[1024]; + size_t cacertlen; + char *signer_id = SM2_DEFAULT_ID; SM2_KEY ca_pubkey; @@ -126,7 +81,7 @@ int main(int argc, char **argv) argv++; while (argc >= 1) { if (!strcmp(*argv, "-help")) { - print_usage(prog); + printf("Usage: %s [-cert pem] -cacert pem\n", prog); return 0; } else if (!strcmp(*argv, "-cert")) { @@ -144,7 +99,7 @@ int main(int argc, char **argv) return -1; } } else { - print_usage(prog); + printf("Usage: %s [-cert pem] -cacert pem\n", prog); return 0; break; } @@ -154,36 +109,24 @@ int main(int argc, char **argv) } if (!certfp || !cacertfp) { - print_usage(prog); + error_print(); return -1; } - if (x509_certificate_from_pem(cert, certfp) != 1) { - error_print(); - return -1; - } - for (;;) { - if ((ret = x509_certificate_from_pem(cacert, certfp)) != 1) { - if (ret < 0) error_print(); - break; - } - if (verify_cert(cert, cacert) != 1) { - error_print(); - return -1; - } - tmpcert = cacert; - cert = cacert; - cacert = tmpcert; - } - if (find_cacert(cacert, cacertfp, &cert->tbs_certificate.issuer) != 1) { + if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1) { error_print(); return -1; } - if ((ret = verify_cert(cert, cacert)) < 0) { + if (x509_cert_from_pem(cacert, &cacertlen, sizeof(cacert), cacertfp) != 1) { error_print(); return -1; } + if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, signer_id, strlen(signer_id)) != 1) { + error_print(); + return -1; + } + ret = 1; printf("Verification %s\n", ret ? "success" : "failure"); ret = 0; diff --git a/tools/reqgen.c b/tools/reqgen.c index e1761f33..1cce416c 100644 --- a/tools/reqgen.c +++ b/tools/reqgen.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -98,9 +99,12 @@ int main(int argc, char **argv) FILE *keyfp = NULL; FILE *outfp = stdout; - X509_CERT_REQUEST req; + uint8_t req[1024]; + size_t reqlen = 0; + + uint8_t name[256]; + size_t namelen = 0; - X509_NAME name; SM2_KEY sm2_key; // 这个应该是从文件中读取的! @@ -171,7 +175,6 @@ int main(int argc, char **argv) goto bad; } - if (outfile) { if (!(outfp = fopen(outfile, "w"))) { error_print(); @@ -187,57 +190,35 @@ int main(int argc, char **argv) #endif } - if (sm2_enced_private_key_info_from_pem(&sm2_key, pass, keyfp) != 1) { + if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) { error_print(); goto end; } - - memset(&name, 0, sizeof(name)); - - - - if (country) { - if (x509_name_set_country(&name, country) != 1) { - error_print(); - goto end; - } - } - if (state) { - if (x509_name_set_state_or_province(&name, state) != 1) { - error_print(); - goto end; - } - } - if (org) { - if (x509_name_set_organization(&name, org) != 1) { - error_print(); - goto end; - } - } - if (org_unit) { - if (x509_name_set_organizational_unit(&name, org_unit) != 1) { - error_print(); - goto end; - } - } - if (!common_name) { + if (x509_name_set(name, &namelen, sizeof(name), + country, state, NULL, org, org_unit, common_name) != 1) { error_print(); - goto end; - } else { - if (x509_name_set_common_name(&name, common_name) != 1) { - error_print(); - goto end; - } + return -1; } - memset(&req, 0, sizeof(req)); - x509_cert_request_set(&req, &name, &sm2_key); - x509_cert_request_sign(&req, &sm2_key); + if (x509_req_sign(req, &reqlen, sizeof(req), + X509_version_v1, + name, namelen, + &sm2_key, + NULL, 0, + OID_sm2sign_with_sm3, + &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { + error_print(); + return -1; + } - x509_cert_request_to_pem(&req, outfp); + + if (x509_req_to_pem(req, reqlen, outfp) != 1) { + error_print(); + return -1; + } ret = 0; goto end; diff --git a/tools/reqparse.c b/tools/reqparse.c index acc745b3..884a748d 100644 --- a/tools/reqparse.c +++ b/tools/reqparse.c @@ -51,6 +51,7 @@ #include #include #include +#include #include @@ -58,8 +59,9 @@ int main(int argc, char **argv) { char *prog = argv[0]; char *infile = NULL; - X509_CERT_REQUEST req; FILE *infp = stdin; + uint8_t req[1024]; + size_t reqlen; argc--; argv++; @@ -90,16 +92,12 @@ help: } } - int ret = x509_cert_request_from_pem(&req, infp); - if (ret < 0) { + if (x509_req_from_pem(req, &reqlen, sizeof(req), infp) != 1) { error_print(); return -1; } - if (ret == 0) { - error_print(); - return -1; - } - x509_cert_request_print(stdout, &req, 0, 0); + x509_req_print(stdout, 0, 0, "CertificationRequest", req, reqlen); + x509_req_to_pem(req, reqlen, stdout); return 0; bad: diff --git a/tools/sm2decrypt.c b/tools/sm2decrypt.c index 44ab807a..66d6265a 100644 --- a/tools/sm2decrypt.c +++ b/tools/sm2decrypt.c @@ -143,7 +143,7 @@ help: } } - if (sm2_enced_private_key_info_from_pem(&key, pass, keyfp) != 1) { + if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { error_puts("private key decryption failure"); return -1; } diff --git a/tools/sm2keygen.c b/tools/sm2keygen.c index 7e4d956b..a2f383e1 100644 --- a/tools/sm2keygen.c +++ b/tools/sm2keygen.c @@ -134,7 +134,7 @@ help: return -1; } - if (sm2_enced_private_key_info_to_pem(&key, pass, outfp) != 1) { + if (sm2_private_key_info_encrypt_to_pem(&key, pass, outfp) != 1) { memset(&key, 0, sizeof(SM2_KEY)); error_print(); return -1; diff --git a/tools/sm2sign.c b/tools/sm2sign.c index 2fb6f29f..538258b5 100644 --- a/tools/sm2sign.c +++ b/tools/sm2sign.c @@ -151,7 +151,7 @@ help: } } - if (sm2_enced_private_key_info_from_pem(&key, pass, keyfp) != 1) { + if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { error_puts("private key decryption failure"); return -1; }