mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-26 23:23:40 +08:00
Update tests and tools
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
190
src/asn1.c
190
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
15
src/pem.c
15
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();
|
||||
|
||||
582
src/pkcs8.c
582
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 <gmssl/digest.h>
|
||||
#include <gmssl/sm4.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/x509_alg.h>
|
||||
|
||||
/*
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
377
src/sm2_asn1.c
377
src/sm2_asn1.c
@@ -51,6 +51,10 @@
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/asn1.h>
|
||||
#include <gmssl/pem.h>
|
||||
#include <gmssl/sm4.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/pbkdf2.h>
|
||||
#include <gmssl/pkcs8.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -54,41 +54,42 @@
|
||||
#include <gmssl/asn1.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
144
src/x509_cer.c
144
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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
150
src/x509_oid.c
150
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;
|
||||
|
||||
511
src/x509_prn.c
511
src/x509_prn.c
@@ -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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <gmssl/sm2.h>
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/asn1.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
159
tests/aestest.c
159
tests/aestest.c
@@ -55,50 +55,6 @@
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
690
tests/asn1test.c
690
tests/asn1test.c
@@ -53,22 +53,6 @@
|
||||
#include <gmssl/asn1.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
567
tests/cmstest.c
567
tests/cmstest.c
@@ -56,572 +56,7 @@
|
||||
#include <gmssl/sm4.h>
|
||||
#include <gmssl/cms.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -91,9 +91,5 @@ int main(void)
|
||||
gf128_print("H = ", H);
|
||||
gf128_print("C * H = ", T);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/asn1.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// test_asn1_oid();
|
||||
|
||||
test_asn1_object_identifier();
|
||||
return 1;
|
||||
}
|
||||
@@ -52,7 +52,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/hex.h>
|
||||
#include <gmssl/pbkdf2.h>
|
||||
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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 <stdlib.h>
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/sm2.h>
|
||||
#include <gmssl/asn1.h>
|
||||
#include <gmssl/pkcs8.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/sm2.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
136
tests/sm2test.c
136
tests/sm2test.c
@@ -49,6 +49,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/error.h>
|
||||
#include <gmssl/sm2.h>
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/sm4.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
# 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;
|
||||
}
|
||||
|
||||
@@ -50,80 +50,94 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/x509_alg.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
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;
|
||||
186
tests/x509_crltest.c
Normal file
186
tests/x509_crltest.c
Normal file
@@ -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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/x509_alg.h>
|
||||
#include <gmssl/x509_oid.h>
|
||||
#include <gmssl/x509_crl.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
334
tests/x509_exttest.c
Normal file
334
tests/x509_exttest.c
Normal file
@@ -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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/x509_alg.h>
|
||||
#include <gmssl/x509_oid.h>
|
||||
#include <gmssl/x509_str.h>
|
||||
#include <gmssl/x509_ext.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
322
tests/x509_oidtest.c
Normal file
322
tests/x509_oidtest.c
Normal file
@@ -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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/x509_oid.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
253
tests/x509_reqtest.c
Normal file
253
tests/x509_reqtest.c
Normal file
@@ -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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/x509_alg.h>
|
||||
#include <gmssl/x509_oid.h>
|
||||
#include <gmssl/x509_req.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -49,64 +49,66 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/sm4.h>
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/x509_str.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
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;
|
||||
}
|
||||
531
tests/x509test.c
531
tests/x509test.c
@@ -50,282 +50,397 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/x509_alg.h>
|
||||
#include <gmssl/x509_oid.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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 <stdio.h>
|
||||
|
||||
146
tools/certgen.c
146
tools/certgen.c
@@ -84,11 +84,11 @@ void print_usage(const char *prog)
|
||||
printf("\n");
|
||||
printf("Options:\n");
|
||||
printf(" -C <str> country name\n");
|
||||
printf(" -ST <str> state of province name\n");
|
||||
printf(" -L <str> locality name\n");
|
||||
printf(" -O <str> orgnization name\n");
|
||||
printf(" -OU <str> orgnizational unit name\n");
|
||||
printf(" -CN <str> common name\n");
|
||||
printf(" -L <str> locality name\n");
|
||||
printf(" -ST <str> state of province name\n");
|
||||
printf(" -days <num> validity days\n");
|
||||
printf(" -key <file> 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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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 <file> PKCS #10 certificate request file\n");
|
||||
printf(" -cacert <file> 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;
|
||||
|
||||
@@ -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 <stdlib.h>
|
||||
#include <gmssl/pem.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/x509_req.h>
|
||||
#include <gmssl/pkcs8.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
@@ -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;
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/pem.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/x509_req.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user