diff --git a/include/gmssl/aes.h b/include/gmssl/aes.h index 2c9a2650..8521f5b2 100644 --- a/include/gmssl/aes.h +++ b/include/gmssl/aes.h @@ -53,6 +53,11 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + + #define AES128_KEY_BITS 128 #define AES192_KEY_BITS 192 #define AES256_KEY_BITS 256 @@ -69,40 +74,47 @@ #define AES_MAX_ROUNDS AES256_ROUNDS -#ifdef __cplusplus -extern "C" { -#endif - - typedef struct { uint32_t rk[4 * (AES_MAX_ROUNDS + 1)]; size_t rounds; } AES_KEY; -int aes_set_encrypt_key(AES_KEY *aes_key, const uint8_t *key, size_t keylen); -int aes_set_decrypt_key(AES_KEY *aes_key, const uint8_t *key, size_t keylen); -void aes_encrypt(const AES_KEY *aes_key, const uint8_t in[AES_BLOCK_SIZE], uint8_t out[AES_BLOCK_SIZE]); +int aes_set_encrypt_key(AES_KEY *key, const uint8_t *raw_key, size_t raw_key_len); +int aes_set_decrypt_key(AES_KEY *key, const uint8_t *raw_key, size_t raw_key_len); +void aes_encrypt(const AES_KEY *key, const uint8_t in[AES_BLOCK_SIZE], uint8_t out[AES_BLOCK_SIZE]); +void aes_decrypt(const AES_KEY *key, const uint8_t in[AES_BLOCK_SIZE], uint8_t out[AES_BLOCK_SIZE]); -void aes_decrypt(const AES_KEY *aes_key, const uint8_t in[AES_BLOCK_SIZE], uint8_t out[AES_BLOCK_SIZE]); -void aes_cbc_encrypt(const AES_KEY *key, const uint8_t iv[16], const uint8_t *in, size_t nblocks, uint8_t *out); -void aes_cbc_decrypt(const AES_KEY *key, const uint8_t iv[16], const uint8_t *in, size_t nblocks, uint8_t *out); - -int aes_cbc_padding_encrypt(const AES_KEY *key, const uint8_t iv[16], +void aes_cbc_encrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE], + const uint8_t *in, size_t nblocks, uint8_t *out); +void aes_cbc_decrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE], + const uint8_t *in, size_t nblocks, uint8_t *out); +int aes_cbc_padding_encrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE], + const uint8_t *in, size_t inlen, + uint8_t *out, size_t *outlen); +int aes_cbc_padding_decrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE], const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int aes_cbc_padding_decrypt(const AES_KEY *key, const uint8_t iv[16], - const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen); - -void aes_ctr_encrypt(const AES_KEY *key, uint8_t ctr[16], +void aes_ctr_encrypt(const AES_KEY *key, uint8_t ctr[AES_BLOCK_SIZE], const uint8_t *in, size_t inlen, uint8_t *out); +#define aes_ctr_decrypt(key,ctr,in,inlen,out) aes_ctr_encrypt(key,ctr,in,inlen,out) + + +#define AES_GCM_IV_MIN_SIZE 1 +#define AES_GCM_IV_MAX_SIZE ((uint64_t)(1 << (64-3))) +#define AES_GCM_IV_DEFAULT_BITS 96 +#define AES_GCM_IV_DEFAULT_SIZE 12 + +#define AES_GCM_MIN_AAD_SIZE 0 +#define AES_GCM_MAX_AAD_SIZE ((uint64_t)(1 << (64-3))) + +#define AES_GCM_MIN_PLAINTEXT_SIZE 0 +#define AES_GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3) int aes_gcm_encrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen, const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, - uint8_t *out, const size_t taglen, uint8_t *tag); - + uint8_t *out, size_t taglen, uint8_t *tag); int aes_gcm_decrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen, const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, const uint8_t *tag, size_t taglen, uint8_t *out); diff --git a/include/gmssl/asn1.h b/include/gmssl/asn1.h index f1aa131d..78892bb0 100644 --- a/include/gmssl/asn1.h +++ b/include/gmssl/asn1.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2014 - 2021 The GmSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,15 +46,16 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ +// https://www.obj-sys.com/asn1tutorial/node128.html + + #ifndef GMSSL_ASN1_H #define GMSSL_ASN1_H - #include #include #include - #if __cplusplus extern "C" { #endif @@ -71,8 +72,6 @@ extern "C" { #define ASN1_TAG_EXPLICIT(index) ASN1_TAG_IMPLICIT(ASN1_TAG_CONSTRUCTED|(index)) -// https://www.obj-sys.com/asn1tutorial/node128.html - enum ASN1_TAG { ASN1_TAG_BOOLEAN = 1, ASN1_TAG_INTEGER = 2, @@ -105,172 +104,194 @@ enum ASN1_TAG { ASN1_TAG_EXPLICIT = 0xa0, }; - - -#define ASN1_TRUE 0xff -#define ASN1_FALSE 0x00 - - - -// 用来解析未定义的OID -typedef struct { - int oid; - uint32_t nodes[16]; - size_t nodes_count; -} ASN1_OID_INFO; - const char *asn1_tag_name(int tag); - - - - -// private -void asn1_tag_to_der(int tag, uint8_t **out, size_t *outlen); -void asn1_length_to_der(size_t len, uint8_t **in, size_t *inlen); -void asn1_data_to_der(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen); - +int asn1_tag_to_der(int tag, uint8_t **out, size_t *outlen); int asn1_tag_from_der(int tag, const uint8_t **in, size_t *inlen); -int asn1_length_from_der(size_t *len, const uint8_t **in, size_t *inlen); -int asn1_data_from_der(const uint8_t **data, size_t datalen, const uint8_t **in, size_t *inlen); - - -const char *asn1_object_identifier_name(int oid); -const char *asn1_object_identifier_description(int oid); -int asn1_object_identifier_from_name(int *oid, const char *name); - -int asn1_utf8_string_check(const char *a, size_t alen); -int asn1_printable_string_check(const char *a, size_t alen); -int asn1_ia5_string_check(const char *a, size_t alen); - -int asn1_header_to_der(int tag, size_t len, uint8_t **out, size_t *outlen); -int asn1_type_to_der(int tag, const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen); -int asn1_type_from_der(int tag, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen); - -int asn1_type_copy_from_der(int tag, size_t maxlen, uint8_t *data, size_t *datalen, const uint8_t **in, size_t *inlen); -#define asn1_sequence_copy_from_der(maxl,d,dl,i,il) asn1_type_copy_from_der(ASN1_TAG_SEQUENCE,maxl,d,dl,i,il) -// FIXME: 调整一下参数位置,maxl放在dl前面 - int asn1_any_tag_from_der(int *tag, const uint8_t **in, size_t *inlen); -int asn1_any_type_from_der(int *tag, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen); +int asn1_tag_get(int *tag, const uint8_t **in, size_t *inlen); // 这个函数是看看下一个tag是什么,并不修改in,inlen +int asn1_tag_is_cstring(int tag); +int asn1_length_to_der(size_t len, uint8_t **in, size_t *inlen); +int asn1_length_from_der(size_t *len, const uint8_t **in, size_t *inlen); +int asn1_length_is_zero(size_t len); +int asn1_data_to_der(const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int asn1_data_from_der(const uint8_t **d, size_t dlen, const uint8_t **in, size_t *inlen); -int asn1_any_from_der(const uint8_t **tlv, size_t *tlvlen, const uint8_t **in, size_t *inlen); +int asn1_type_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int asn1_type_from_der(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +int asn1_any_type_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +int asn1_any_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen); +int asn1_any_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen); int asn1_boolean_to_der_ex(int tag, int val, uint8_t **out, size_t *outlen); -int asn1_integer_to_der_ex(int tag, const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen); -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 asn1_bits_to_der_ex(int tag, int bits, uint8_t **out, size_t *outlen); -int asn1_null_to_der(uint8_t **out, size_t *outlen); -int asn1_object_identifier_to_der_ex(int tag, int oid, const uint32_t *nodes, size_t nodes_count, uint8_t **out, size_t *outlen); -int asn1_utf8_string_to_der_ex(int tag, const char *a, uint8_t **out, size_t *outlen); -int asn1_printable_string_to_der_ex(int tag, const char *a, uint8_t **out, size_t *outlen); -int asn1_ia5_string_to_der_ex(int tag, const char *a, uint8_t **out, size_t *outlen); -int asn1_utc_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen); -int asn1_generalized_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen); - int asn1_boolean_from_der_ex(int tag, int *val, const uint8_t **in, size_t *inlen); -int asn1_integer_from_der_ex(int tag, const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen); +#define asn1_boolean_to_der(val,out,outlen) asn1_boolean_to_der_ex(ASN1_TAG_BOOLEAN,val,out,outlen) +#define asn1_boolean_from_der(val,in,inlen) asn1_boolean_from_der_ex(ASN1_TAG_BOOLEAN,val,in,inlen) +#define asn1_implicit_boolean_to_der(idx,val,out,outlen) asn1_boolean_to_der_ex(ASN1_TAG_IMPLICIT(idx),val,out,outlen) +#define asn1_implicit_boolean_from_der(idx,val,in,inlen) asn1_boolean_from_der_ex(ASN1_TAG_IMPLICIT(idx),val,in,inlen) + +int asn1_integer_to_der_ex(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int asn1_integer_from_der_ex(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +#define asn1_integer_to_der(d,dlen,out,outlen) asn1_integer_to_der_ex(ASN1_TAG_INTEGER,d,dlen,out,outlen) +#define asn1_integer_from_der(d,dlen,in,inlen) asn1_integer_from_der_ex(ASN1_TAG_INTEGER,d,dlen,in,inlen) +#define asn1_implicit_integer_to_der(idx,d,dlen,out,outlen) asn1_integer_to_der_ex(ASN1_TAG_IMPLICIT(idx),d,dlen,out,outlen) +#define asn1_implicit_integer_from_der(idx,d,dlen,in,inlen) asn1_integer_from_der_ex(ASN1_TAG_IMPLICIT(idx),d,dlen,in,inlen) + +int asn1_int_to_der_ex(int tag, int a, uint8_t **out, size_t *outlen); int asn1_int_from_der_ex(int tag, int *a, const uint8_t **in, size_t *inlen); -int asn1_bit_string_from_der_ex(int tag, const uint8_t **bits, size_t *nbits, const uint8_t **in, size_t *inlen); +#define asn1_int_to_der(val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_INTEGER,val,out,outlen) +#define asn1_int_from_der(val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_INTEGER,val,in,inlen) +#define asn1_implicit_int_to_der(idx,val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_IMPLICIT(idx),val,out,outlen) +#define asn1_implicit_int_from_der(idx,val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_IMPLICIT(idx),val,in,inlen) + +int asn1_bit_string_to_der_ex(int tag, const uint8_t *d, size_t nbits, uint8_t **out, size_t *outlen); +int asn1_bit_string_from_der_ex(int tag, const uint8_t **d, size_t *nbits, const uint8_t **in, size_t *inlen); +#define asn1_bit_string_to_der(d,nbits,out,outlen) asn1_bit_string_to_der_ex(ASN1_TAG_BIT_STRING,d,nbits,out,outlen) +#define asn1_bit_string_from_der(d,nbits,in,inlen) asn1_bit_string_from_der_ex(ASN1_TAG_BIT_STRING,d,nbits,in,inlen) +#define asn1_implicit_bit_string_to_der(idx,d,nbits,out,outlen) asn1_bit_string_to_der_ex(ASN1_TAG_IMPLICIT(idx),d,nbits,out,outlen) +#define asn1_implicit_bit_string_from_der(idx,d,nbits,in,inlen) asn1_bit_string_from_der_ex(ASN1_TAG_IMPLICIT(idx),d,nbits,in,inlen) + +int asn1_bit_octets_to_der_ex(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int asn1_bit_octets_from_der_ex(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +#define asn1_bit_octets_to_der(d,dlen,out,outlen) asn1_bit_octets_to_der_ex(ASN1_TAG_BIT_STRING,d,dlen,out,outlen) +#define asn1_bit_octets_from_der(d,dlen,in,inlen) asn1_bit_octets_from_der_ex(ASN1_TAG_BIT_STRING,d,dlen,out,outlen) +#define asn1_implicit_bit_octets_to_der(idx,d,dlen,out,outlen) asn1_bit_octets_to_der_ex(ASN1_TAG_IMPLICIT(idx),d,dlen,out,outlen) +#define asn1_implicit_bit_octets_from_der(idx,d,dlen,in,inlen) asn1_bit_octets_from_der_ex(ASN1_TAG_IMPLICIT(idx),d,dlen,out,outlen) + +int asn1_bits_to_der_ex(int tag, int bits, uint8_t **out, size_t *outlen); int asn1_bits_from_der_ex(int tag, int *bits, const uint8_t **in, size_t *inlen); -int asn1_octet_string_from_der_ex(int tag, const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen); +#define asn1_bits_to_der(val,out,outlen) asn1_bits_to_der_ex(ASN1_TAG_BIT_STRING,val,out,outlen) +#define asn1_bits_from_der(val,out,outlen) asn1_bits_from_der_ex(ASN1_TAG_BIT_STRING,val,out,outlen) +#define asn1_implicit_bits_to_der(idx,val,out,outlen) asn1_bits_to_der_ex(ASN1_TAG_IMPLICIT(idx),val,out,outlen) +#define asn1_implicit_bits_from_der(idx,val,out,outlen) asn1_bits_from_der_ex(ASN1_TAG_IMPLICIT(idx),val,out,outlen) +int asn1_bits_print(FILE *fp, int fmt, int ind, const char *label, const char **names, size_t names_cnt, int bits); + +#define asn1_octet_string_to_der_ex(tag,a,alen,d,dlen) asn1_type_to_der(tag,a,alen,d,dlen) +#define asn1_octet_string_from_der_ex(tag,a,alen,d,dlen) asn1_type_from_der(tag,a,alen,d,dlen) +#define asn1_octet_string_to_der(val,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_OCTET_STRING,val,d,dlen,out,outlen) +#define asn1_octet_string_from_der(val,d,dlen,out,outlen) asn1_type_from_der(ASN1_TAG_OCTET_STRING,val,d,dlen,out,outlen) +#define asn1_implicit_octet_string_to_der(idx,val,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_IMPLICIT(idx),val,d,dlen,out,outlen) +#define asn1_implicit_octet_string_from_der(idx,val,d,dlen,out,outlen) asn1_type_from_der(ASN1_TAG_IMPLICIT(idx),val,d,dlen,out,outlen) + +int asn1_null_to_der(uint8_t **out, size_t *outlen); int asn1_null_from_der(const uint8_t **in, size_t *inlen); -int asn1_object_identifier_from_der_ex(int tag, int *oid, uint32_t *nodes, size_t *nodes_count, const uint8_t **in, size_t *inlen); + +#define ASN1_OID_MAX_NODES 32 +int asn1_object_identifier_to_octets(const uint32_t *nodes, size_t nodes_count, uint8_t *out, size_t *outlen); +int asn1_object_identifier_from_octets(uint32_t *nodes, size_t *nodes_count, const uint8_t *in, size_t inlen); + +int asn1_object_identifier_equ(const uint32_t *a, size_t a_count, const uint32_t *b, size_t b_count); +int asn1_object_identifier_to_der_ex(int tag, const uint32_t *nodes, size_t nodes_count, uint8_t **out, size_t *outlen); +int asn1_object_identifier_from_der_ex(int tag, uint32_t *nodes, size_t *nodes_count, const uint8_t **in, size_t *inlen); +#define asn1_object_identifier_to_der(val,d,dlen,out,outlen) asn1_object_identifier_to_der_ex(ASN1_TAG_OBJECT_IDENTIFIER,val,d,dlen,out,outlen) +#define asn1_object_identifier_from_der(val,d,dlen,out,outlen) asn1_object_identifier_from_der_ex(ASN1_TAG_OBJECT_IDENTIFIER,val,d,dlen,out,outlen) +#define asn1_implicit_object_identifier_to_der(idx,val,d,dlen,out,outlen) asn1_object_identifier_to_der_ex(ASN1_TAG_IMPLICIT(idx),val,d,dlen,out,outlen) +#define asn1_implicit_object_identifier_from_der(idx,val,d,dlen,out,outlen) asn1_object_identifier_from_der_ex(ASN1_TAG_IMPLICIT(idx),val,d,dlen,out,outlen) +int asn1_object_identifier_print(FILE *fp, int fmt, int ind, const char *label, const char *name, + const uint32_t *nodes, size_t nodes_count); + +#define asn1_enumerated_to_der_ex(tag,val,out,outlen) asn1_int_to_der_ex(tag,val,out,outlen) +#define asn1_enumerated_from_der_ex(tag,val,out,outlen) asn1_int_from_der_ex(tag,val,out,outlen) +#define asn1_enumerated_to_der(val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_ENUMERATED,val,out,outlen) +#define asn1_enumerated_from_der(val,out,outlen) asn1_int_from_der_ex(ASN1_TAG_ENUMERATED,val,out,outlen) +#define asn1_implicit_enumerated_to_der(idx,val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_IMPLICIT(idx),val,out,outlen) +#define asn1_implicit_enumerated_from_der(idx,val,out,outlen) asn1_int_from_der_ex(ASN1_TAG_IMPLICIT(idx),val,out,outlen) + +int asn1_utf8_string_check(const char *d, size_t dlen); +int asn1_utf8_string_to_der_ex(int tag, const char *a, uint8_t **out, size_t *outlen); int asn1_utf8_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen); +#define asn1_utf8_string_to_der(val,out,outlen) asn1_utf8_string_to_der_ex(ASN1_TAG_UTF8String,val,out,outlen) +#define asn1_utf8_string_from_der(val,d,dlen,out,outlen) asn1_utf8_string_from_der_ex(ASN1_TAG_UTF8String,val,d,dlen,out,outlen) +#define asn1_implicit_utf8_string_to_der(i,val,out,outlen) asn1_utf8_string_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) +#define asn1_implicit_utf8_string_from_der(i,val,out,outlen) asn1_utf8_string_from_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) + +int asn1_printable_string_check(const char *d, size_t dlen); +int asn1_printable_string_to_der_ex(int tag, const char *a, uint8_t **out, size_t *outlen); int asn1_printable_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen); +#define asn1_printable_string_to_der(val,out,outlen) asn1_printable_string_to_der_ex(ASN1_TAG_PrintableString,val,out,outlen) +#define asn1_printable_string_from_der(val,d,dlen,out,outlen) asn1_printable_string_from_der_ex(ASN1_TAG_PrintableString,val,d,dlen,out,outlen) +#define asn1_implicit_printable_string_to_der(i,val,out,outlen) asn1_printable_string_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) +#define asn1_implicit_printable_string_from_der(i,val,out,outlen) asn1_printable_string_from_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) + +int asn1_ia5_string_check(const char *d, size_t dlen); +int asn1_ia5_string_to_der_ex(int tag, const char *a, uint8_t **out, size_t *outlen); int asn1_ia5_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen); +#define asn1_ia5_string_to_der(val,out,outlen) asn1_ia5_string_to_der_ex(ASN1_TAG_IA5String,val,out,outlen) +#define asn1_ia5_string_from_der(val,d,dlen,out,outlen) asn1_ia5_string_from_der_ex(ASN1_TAG_IA5String,val,d,dlen,out,outlen) +#define asn1_implicit_ia5_string_to_der(i,val,out,outlen) asn1_ia5_string_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) +#define asn1_implicit_ia5_string_from_der(i,val,out,outlen) asn1_ia5_string_from_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) + +int asn1_string_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen); + + +int asn1_utc_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen); int asn1_utc_time_from_der_ex(int tag, time_t *t, const uint8_t **in, size_t *inlen); +#define asn1_utc_time_to_der(val,out,outlen) asn1_utc_time_to_der_ex(ASN1_TAG_UTCTime,val,out,outlen) +#define asn1_utc_time_from_der(val,out,outlen) asn1_utc_time_from_der_ex(ASN1_TAG_UTCTime,val,out,outlen) +#define asn1_implicit_utc_time_to_der(i,val,out,outlen) asn1_utc_time_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) +#define asn1_implicit_utc_time_from_der(i,val,out,outlen) asn1_utc_time_from_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) + +int asn1_generalized_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen); int asn1_generalized_time_from_der_ex(int tag, time_t *t, const uint8_t **in, size_t *inlen); +#define asn1_generalized_time_to_der(val,out,outlen) asn1_generalized_time_to_der_ex(ASN1_TAG_GeneralizedTime,val,out,outlen) +#define asn1_generalized_time_from_der(val,out,outlen) asn1_generalized_time_from_der_ex(ASN1_TAG_GeneralizedTime,val,out,outlen) +#define asn1_implicit_generalized_time_to_der(i,val,out,outlen) asn1_generalized_time_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) +#define asn1_implicit_generalized_time_from_der(i,val,out,outlen) asn1_generalized_time_from_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) +#define asn1_sequence_to_der(val,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_SEQUENCE,val,d,dlen,out,outlen) +#define asn1_sequence_from_der(val,d,dlen,out,outlen) asn1_type_from_der(ASN1_TAG_SEQUENCE,val,d,dlen,out,outlen) +#define asn1_implicit_sequence_to_der(i,val,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),val,d,dlen,out,outlen) +#define asn1_implicit_sequence_from_der(i,val,d,dlen,out,outlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),val,d,dlen,out,outlen) -#define asn1_boolean_to_der(a,d,dl) asn1_boolean_to_der_ex(ASN1_TAG_BOOLEAN,a,d,dl) -#define asn1_integer_to_der(a,al,d,dl) asn1_integer_to_der_ex(ASN1_TAG_INTEGER,a,al,d,dl) -#define asn1_int_to_der(a,d,dl) asn1_int_to_der_ex(ASN1_TAG_INTEGER,a,d,dl) -#define asn1_bit_string_to_der(a,al,d,dl) asn1_bit_string_to_der_ex(ASN1_TAG_BIT_STRING,a,al,d,dl) -#define asn1_bits_to_der(a,d,dl) asn1_bits_to_der_ex(ASN1_TAG_BIT_STRING,a,d,dl) -#define asn1_octet_string_to_der(a,al,d,dl) asn1_type_to_der(ASN1_TAG_OCTET_STRING,a,al,d,dl) -#define asn1_object_identifier_to_der(oid,a,al,d,dl) asn1_object_identifier_to_der_ex(ASN1_TAG_OBJECT_IDENTIFIER,oid,a,al,d,dl) -#define asn1_utf8_string_to_der(a,d,dl) asn1_utf8_string_to_der_ex(ASN1_TAG_UTF8String,a,d,dl) -#define asn1_printable_string_to_der(a,d,dl) asn1_printable_string_to_der_ex(ASN1_TAG_PrintableString,a,d,dl) -#define asn1_ia5_string_to_der(a,d,dl) asn1_ia5_string_to_der_ex(ASN1_TAG_IA5String,a,d,dl) -#define asn1_utc_time_to_der(a,d,dl) asn1_utc_time_to_der_ex(ASN1_TAG_UTCTime,a,d,dl) -#define asn1_generalized_time_to_der(a,d,dl) asn1_generalized_time_to_der_ex(ASN1_TAG_GeneralizedTime,a,d,dl) + +#define asn1_set_to_der(val,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_SET,val,d,dlen,out,outlen) +#define asn1_set_from_der(val,d,dlen,out,outlen) asn1_type_from_der(ASN1_TAG_SET,val,d,dlen,out,outlen) +#define asn1_implicit_set_to_der(i,val,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),val,d,dlen,out,outlen) +#define asn1_implicit_set_from_der(i,val,d,dlen,out,outlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),val,d,dlen,out,outlen) + +#define asn1_implicit_to_der(i,val,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),val,d,dlen,out,outlen) +#define asn1_implicit_from_der(i,val,d,dlen,out,outlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),val,d,dlen,out,outlen) + + +int asn1_header_to_der(int tag, size_t len, uint8_t **out, size_t *outlen); #define asn1_sequence_header_to_der(al,d,dl) asn1_header_to_der(ASN1_TAG_SEQUENCE,al,d,dl) +#define asn1_implicit_sequence_header_to_der(i,al,d,dl) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),al,d,dl) + #define asn1_set_header_to_der(al,d,dl) asn1_header_to_der(ASN1_TAG_SET,al,d,dl) +#define asn1_implicit_set_header_to_der(i,al,d,dl) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),al,d,dl) + #define asn1_explicit_header_to_der(i,al,d,dl) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),al,d,dl) -#define asn1_sequence_to_der(a,al,d,dl) asn1_type_to_der(ASN1_TAG_SEQUENCE,a,al,d,dl) -#define asn1_set_to_der(a,al,d,dl) asn1_type_to_der(ASN1_TAG_SET,a,al,d,dl) -#define asn1_explicit_to_der(i,a,al,d,dl) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),a,al,d,dl) -#define asn1_boolean_from_der(a,d,dl) asn1_boolean_from_der_ex(ASN1_TAG_BOOLEAN,a,d,dl) -#define asn1_integer_from_der(a,al,d,dl) asn1_integer_from_der_ex(ASN1_TAG_INTEGER,a,al,d,dl) -#define asn1_int_from_der(a,d,dl) asn1_int_from_der_ex(ASN1_TAG_INTEGER,a,d,dl) -#define asn1_bit_string_from_der(a,al,d,dl) asn1_bit_string_from_der_ex(ASN1_TAG_BIT_STRING,a,al,d,dl) -#define asn1_bits_from_der(a,d,dl) asn1_bits_from_der_ex(ASN1_TAG_BIT_STRING,a,d,dl) -#define asn1_octet_string_from_der(a,al,d,dl) asn1_type_from_der(ASN1_TAG_OCTET_STRING,a,al,d,dl) -#define asn1_object_identifier_from_der(oid,a,al,d,dl) asn1_object_identifier_from_der_ex(ASN1_TAG_OBJECT_IDENTIFIER,oid,a,al,d,dl) -#define asn1_utf8_string_from_der(a,al,d,dl) asn1_utf8_string_from_der_ex(ASN1_TAG_UTF8String,a,al,d,dl) -#define asn1_printable_string_from_der(a,al,d,dl) asn1_printable_string_from_der_ex(ASN1_TAG_PrintableString,a,al,d,dl) -#define asn1_ia5_string_from_der(a,al,d,dl) asn1_ia5_string_from_der_ex(ASN1_TAG_IA5String,a,al,d,dl) -#define asn1_utc_time_from_der(a,d,dl) asn1_utc_time_from_der_ex(ASN1_TAG_UTCTime,a,d,dl) -#define asn1_generalized_time_from_der(a,d,dl) asn1_generalized_time_from_der_ex(ASN1_TAG_GeneralizedTime,a,d,dl) -#define asn1_sequence_from_der(a,al,d,dl) asn1_type_from_der(ASN1_TAG_SEQUENCE,a,al,d,dl) -#define asn1_set_from_der(a,al,d,dl) asn1_type_from_der(ASN1_TAG_SET,a,al,d,dl) -#define asn1_implicit_from_der(i,a,al,d,dl) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),a,al,d,dl) -#define asn1_explicit_from_der(i,a,al,d,dl) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),a,al,d,dl) - -#define asn1_implicit_boolean_to_der(i,a,d,dl) asn1_boolean_to_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_integer_to_der(i,a,al,d,dl) asn1_integer_to_der_ex(ASN1_TAG_IMPLICIT(i),a,al,d,dl) -#define asn1_implicit_int_to_der(i,a,d,dl) asn1_int_to_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_bit_string_to_der(i,a,al,d,dl) asn1_bit_string_to_der_ex(ASN1_TAG_IMPLICIT(i),a,al,d,dl) -#define asn1_implicit_bits_to_der(i,a,d,dl) asn1_bits_to_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_octet_string_to_der(i,a,al,d,dl) asn1_type_to_der(ASN1_TAG_IMPLICIT(i),a,al,d,dl) -#define asn1_implicit_object_identifier_to_der(i,oid,a,al,d,dl) asn1_object_identifier_to_der_ex(ASN1_TAG_IMPLICIT(i),oid,a,al,d,dl) -#define asn1_implicit_utf8_string_to_der(i,a,d,dl) asn1_utf8_string_to_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_printable_string_to_der(i,a,d,dl) asn1_printable_string_to_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_ia5_string_to_der(i,a,d,dl) asn1_ia5_string_to_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_utc_time_to_der(i,a,d,dl) asn1_utc_time_to_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_generalized_time_to_der(i,a,d,dl) asn1_generalized_time_to_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_sequence_header_to_der(i,al,d,dl) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),al,d,dl) -#define asn1_implicit_set_header_to_der(i,al,d,dl) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),al,d,dl) -#define asn1_implicit_sequence_to_der(i,a,al,d,dl) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),a,al,d,dl) -#define asn1_implicit_set_to_der(i,a,al,d,dl) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),a,al,d,dl) - -#define asn1_implicit_boolean_from_der(i,a,d,dl) asn1_boolean_from_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_integer_from_der(i,a,al,d,dl) asn1_integer_from_der_ex(ASN1_TAG_IMPLICIT(i),a,al,d,dl) -#define asn1_implicit_int_from_der(i,a,d,dl) asn1_int_from_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_bit_string_from_der(i,a,al,d,dl) asn1_bit_string_from_der_ex(ASN1_TAG_IMPLICIT(i),a,al,d,dl) -#define asn1_implicit_bits_from_der(i,a,d,dl) asn1_bits_from_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_octet_string_from_der(i,a,al,d,dl) asn1_type_from_der(ASN1_TAG_IMPLICIT(i),a,al,d,dl) -#define asn1_implicit_object_identifier_from_der(i,oid,a,al,d,dl) asn1_object_identifier_from_der_ex(ASN1_TAG_IMPLICIT(i),oid,a,al,d,dl) -#define asn1_implicit_utf8_string_from_der(i,a,d,dl) asn1_utf8_string_from_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_printable_string_from_der(i,a,d,dl) asn1_printable_string_from_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_ia5_string_from_der(i,a,d,dl) asn1_ia5_string_from_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_utc_time_from_der(i,a,d,dl) asn1_utc_time_from_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_generalized_time_from_der(i,a,d,dl) asn1_generalized_time_from_der_ex(ASN1_TAG_IMPLICIT(i),a,d,dl) -#define asn1_implicit_sequence_from_der(i,a,al,d,dl) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),a,al,d,dl) -#define asn1_implicit_set_from_der(i,a,al,d,dl) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),a,al,d,dl) +#define asn1_explicit_to_der(i,val,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),val,d,dlen,out,outlen) +#define asn1_explicit_from_der(i,val,d,dlen,out,outlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),val,d,dlen,out,outlen) -int asn1_cstring_to_der(int tag, const char *a, uint8_t **out, size_t *outlen); -int asn1_cstring_from_der(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen); - +int asn1_types_get_count(const uint8_t *d, size_t dlen, int tag, int *count); +int asn1_types_get_type_by_index(const uint8_t *d, size_t *dlen, int tag, const uint8_t **val, size_t *vlen); +int asn1_sequence_of_integer_to_der(const int *nums, size_t nums_cnt, uint8_t **out, size_t *outlen); +int asn1_sequence_of_integer_from_der(int *nums, size_t *nums_cnt, const uint8_t **in, size_t *inlen); +int asn1_sequence_of_integer_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); typedef struct { - size_t datalen; - uint8_t data[1]; -} ASN1_SEQUENCE_OF; + int oid; + char *name; + uint32_t *nodes; + size_t nodes_count; + int flags; + char *description; +} ASN1_OID_INFO; -int asn1_sequence_of_get_next_item(const ASN1_SEQUENCE_OF *a, const uint8_t **next, const uint8_t **data, size_t *datalen); -int asn1_sequence_of_get_count(const ASN1_SEQUENCE_OF *a, size_t *count); +const ASN1_OID_INFO *asn1_oid_info_from_name(const ASN1_OID_INFO *infos, size_t count, const char *name); +const ASN1_OID_INFO *asn1_oid_info_from_oid(const ASN1_OID_INFO *infos, size_t count, int oid); +int asn1_oid_info_from_der_ex(const ASN1_OID_INFO **info, uint32_t *nodes, size_t *nodes_count, + const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen); +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); int asn1_check(int expr); -int asn1_length_is_zero(size_t len); - #if __cplusplus diff --git a/include/gmssl/block_cipher.h b/include/gmssl/block_cipher.h index a357b9c8..8d4e1516 100644 --- a/include/gmssl/block_cipher.h +++ b/include/gmssl/block_cipher.h @@ -64,6 +64,11 @@ extern "C" { #endif +#define BLOCK_CIPHER_BLOCK_SIZE 16 +#define BLOCK_CIPHER_MIN_KEY_SIZE 16 +#define BLOCK_CIPHER_MAX_KEY_SIZE 32 + + typedef struct BLOCK_CIPHER BLOCK_CIPHER; typedef struct BLOCK_CIPHER_KEY BLOCK_CIPHER_KEY; @@ -81,6 +86,7 @@ typedef void (*block_cipher_encrypt_func)(const BLOCK_CIPHER_KEY *key, const uin typedef void (*block_cipher_decrypt_func)(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out); struct BLOCK_CIPHER { + int oid; size_t key_size; size_t block_size; block_cipher_set_encrypt_key_func set_encrypt_key; @@ -89,15 +95,16 @@ struct BLOCK_CIPHER { block_cipher_decrypt_func decrypt; }; +const BLOCK_CIPHER *BLOCK_CIPHER_sm4(void); +const BLOCK_CIPHER *BLOCK_CIPHER_aes128(void); + +const BLOCK_CIPHER *block_cipher_from_name(const char *name); +const char *block_cipher_name(const BLOCK_CIPHER *cipher); int block_cipher_set_encrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key); int block_cipher_set_decrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key); int block_cipher_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out); int block_cipher_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out); -const BLOCK_CIPHER *BLOCK_CIPHER_sm4(void); -const BLOCK_CIPHER *BLOCK_CIPHER_aes128(void); - - #ifdef __cplusplus } diff --git a/include/gmssl/chacha20.h b/include/gmssl/chacha20.h index 24ebba81..e7805bfa 100644 --- a/include/gmssl/chacha20.h +++ b/include/gmssl/chacha20.h @@ -81,14 +81,12 @@ typedef struct { } CHACHA20_STATE; -void chacha20_set_key(CHACHA20_STATE *state, +void chacha20_init(CHACHA20_STATE *state, const uint8_t key[CHACHA20_KEY_SIZE], - const uint8_t nonce[CHACHA20_NONCE_SIZE], - uint32_t counter); + const uint8_t nonce[CHACHA20_NONCE_SIZE], uint32_t counter); void chacha20_generate_keystream(CHACHA20_STATE *state, - unsigned int counts, - uint8_t *out); + size_t counts, uint8_t *out); #ifdef __cplusplus diff --git a/include/gmssl/cms.h b/include/gmssl/cms.h index 8c1a9405..b8def7cf 100644 --- a/include/gmssl/cms.h +++ b/include/gmssl/cms.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,6 +46,12 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* +References: + 1. GM/T 0010-2012 SM2 Cryptography Message Syntax Specification + 2. RFC 2315 PKCS #7 Cryptographic Message Syntax Version 1.5 + 3. RFC 5652 Cryptographic Message Syntax (CMS) +*/ #ifndef GMSSL_CMS_H #define GMSSL_CMS_H @@ -62,379 +68,554 @@ extern "C" { #endif +/* +ContentType: + OID_cms_data + OID_cms_signed_data + OID_cms_enveloped_data + OID_cms_signed_and_enveloped_data + OID_cms_encrypted_data + OID_cms_key_agreement_info +*/ +const char *cms_content_type_name(int oid); +int cms_content_type_from_name(const char *name); +int cms_content_type_to_der(int oid, uint8_t **out, size_t *outlen); +int cms_content_type_from_der(int *oid, const uint8_t **in, size_t *inlen); -enum { - CMS_version = 1, -}; - -typedef enum { - CMS_data = 1, - CMS_signed_data = 2, - CMS_enveloped_data = 3, - CMS_signed_and_enveloped_data = 4, - CMS_encrypted_data = 5, - CMS_key_agreement_info = 6, -} CMS_CONTENT_TYPE; - - - - - - -int cms_data_print(FILE *fp, const uint8_t *a, size_t alen, int format, int indent); - -int cms_enced_content_info_to_der(int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len, - int content_type, const uint8_t *enced_content, size_t enced_content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, +/* +ContentInfo ::= SEQUENCE { + contentType OBJECT IDENTIFIER, + content [0] EXPLICIT ANY OPTIONAL } +*/ +int cms_content_info_to_der( + int content_type, + const uint8_t *content, size_t content_len, uint8_t **out, size_t *outlen); - -int cms_enced_content_info_from_der(int *content_type, - int *enc_algor, const uint8_t **enc_iv, size_t *enc_iv_len, - const uint8_t **enced_content, size_t *enced_content_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, +int cms_content_info_from_der( + int *content_type, + const uint8_t **content, size_t *content_len, // 这里获得的是完整的TLV const uint8_t **in, size_t *inlen); +int cms_content_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); -int cms_enced_content_info_print(FILE *fp, +/* +Data ::= OCTET STRING +*/ +#define cms_data_to_der(d,dlen,out,outlen) asn1_octet_string_to_der(d,dlen,out,outlen) +#define cms_data_from_der(d,dlen,in,inlen) asn1_octet_string_from_der(d,dlen,in,inlen) +#define cms_data_print(fp,fmt,ind,label,d,dlen) format_bytes(fp,fmt,ind,label,d,dlen) + +/* +EncryptedContentInfo ::= SEQUENCE { + contentType OBJECT IDENTIFIER, + contentEncryptionAlgorithm AlgorithmIdentifier, + encryptedContent [0] IMPLICIT OCTET STRING OPTIONAL, + sharedInfo1 [1] IMPLICIT OCTET STRING OPTIONAL, + sharedInfo2 [2] IMPLICIT OCTET STRING OPTIONAL } +*/ +int cms_enced_content_info_to_der( int content_type, int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len, const uint8_t *enced_content, size_t enced_content_len, const uint8_t *shared_info1, size_t shared_info1_len, const uint8_t *shared_info2, size_t shared_info2_len, - int format, int indent); - -int cms_enced_content_info_encrypt_to_der(const SM4_KEY *sm4_key, const uint8_t iv[16], - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, uint8_t **out, size_t *outlen); - -int cms_enced_content_info_decrypt_from_der(const SM4_KEY *key, - int *content_type, uint8_t *content, size_t *content_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **in, size_t *inlen); - -int cms_encrypted_data_to_der(int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len, - int content_type, const uint8_t *enced_content, size_t enced_content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen); - -int cms_encrypted_data_from_der(int *content_type, - int *enc_algor, const uint8_t **enc_iv, size_t *enc_iv_len, - const uint8_t **enced_content, size_t *enced_content_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **in, size_t *inlen); - -int cms_encrypted_data_print(FILE *fp, const uint8_t *a, size_t alen, int format, int indent); - -int cms_encrypted_data_encrypt_to_der(const SM4_KEY *sm4_key, const uint8_t iv[16], - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen); - -int cms_encrypted_data_decrypt_from_der(const SM4_KEY *key, - int *content_type, uint8_t *content, size_t *content_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **in, size_t *inlen); - - -int cms_key_agreement_info_to_der(const SM2_KEY *pub_key, const X509_CERTIFICATE *cert, - const uint8_t *user_id, size_t user_id_len, uint8_t **out, size_t *outlen); - -int cms_key_agreement_info_from_der(SM2_KEY *pub_key, X509_CERTIFICATE *cert, - const uint8_t **user_id, size_t *user_id_len, const uint8_t **in, size_t *inlen); - -int cms_key_agreement_info_print(FILE *fp, const uint8_t *a, size_t alen, int format, int indent); - - -int cms_issuer_and_serial_number_from_certificate(const X509_NAME **issuer, - const uint8_t **serial_number, size_t *serial_number_len, - const X509_CERTIFICATE *cert); - -int cms_public_key_from_certificate(const SM2_KEY **sm2_key, - const X509_CERTIFICATE *cert); - -int cms_issuer_and_serial_number_to_der(const X509_NAME *issuer, - const uint8_t *serial_number, size_t serial_number_len, - uint8_t **out, size_t *outlen); - -int cms_issuer_and_serial_number_from_der(X509_NAME *issuer, - const uint8_t **serial_number, size_t *serial_number_len, - const uint8_t **in, size_t *inlen); - -int cms_issuer_and_serial_number_print(FILE *fp, - const X509_NAME *issuer, - const uint8_t *serial_number, size_t serial_number_len, - int format, int indent); - - - -int cms_recipient_info_from_x509_certificate( - const SM2_KEY **key, - const X509_NAME **issuer, - const uint8_t **serial_number, size_t *serial_number_len, - const X509_CERTIFICATE *cert); - -int cms_recipient_info_to_der(const X509_NAME *issuer, - const uint8_t *serial_number, size_t serial_number_len, - const uint8_t *enced_key, size_t enced_key_len, - uint8_t **out, size_t *outlen); - -int cms_recipient_info_from_der( - int *version, - X509_NAME *issuer, - const uint8_t **serial_number, size_t *serial_number_len, - int *pke_algor, const uint8_t **params, size_t *paramslen, - const uint8_t **enced_key, size_t *enced_key_len, - const uint8_t **in, size_t *inlen); - -int cms_recipient_info_print(FILE *fp, - int version, - const X509_NAME *issuer, const uint8_t *serial_number, size_t serial_number_len, - int pke_algor, const uint8_t *params, size_t paramslen, - const uint8_t *enced_key, size_t enced_key_len, - int format, int indent); - -int cms_recipient_info_encrypt_to_der(const SM2_KEY *sm2_key, - const X509_NAME *issuer, const uint8_t *serial_number, size_t serial_number_len, - const uint8_t *key, size_t keylen, - uint8_t **out, size_t *outlen); - -int cms_recipient_info_decrypt_from_der(const SM2_KEY *sm2_key, - X509_NAME *issuer, const uint8_t **serial_number, size_t *serial_number_len, - uint8_t *key, size_t *keylen, - const uint8_t **in, size_t *inlen); - - -int cms_enveloped_data_to_der(const uint8_t *rcpt_infos, size_t rcpt_infos_len, - int content_type, - int enc_algor, - const uint8_t *enc_iv, size_t enc_iv_len, - const uint8_t *enced_content, size_t enced_content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - const uint8_t **out, size_t *outlen); - -int cms_enveloped_data_from_der(const uint8_t **rcpt_infos, size_t *rcpt_infos_len, +int cms_enced_content_info_from_der( int *content_type, int *enc_algor, const uint8_t **enc_iv, size_t *enc_iv_len, const uint8_t **enced_content, size_t *enced_content_len, const uint8_t **shared_info1, size_t *shared_info1_len, const uint8_t **shared_info2, size_t *shared_info2_len, const uint8_t **in, size_t *inlen); +int cms_enced_content_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); -int cms_enveloped_data_print(FILE *fp, const uint8_t *a, size_t alen, int format, int indent); +int cms_enced_content_info_encrypt_to_der( + int content_type, + int enc_algor, const uint8_t *iv, size_t ivlen, + const uint8_t *content, size_t content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + const uint8_t *key, size_t keylen, + uint8_t **out, size_t *outlen); +int cms_enced_content_info_decrypt_from_der( + int *content_type, + int *enc_algor, const uint8_t **iv, size_t *ivlen, + uint8_t *content, size_t *content_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, + const uint8_t *key, size_t keylen, + const uint8_t **in, size_t *inlen); -int cms_enveloped_data_encrypt_to_der(const X509_CERTIFICATE *rcpt_certs, size_t rcpt_count, +/* +EncryptedData ::= SEQUENCE { + version INTEGER (1), + encryptedContentInfo EncryptedContentInfo } +*/ +int cms_encrypted_data_to_der( + int version, + int content_type, + int enc_algor, const uint8_t *iv, size_t ivlen, + const uint8_t *enced_content, size_t enced_content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t **out, size_t *outlen); +int cms_encrypted_data_from_der( + int *version, + int *content_type, + int *enc_algor, const uint8_t **iv, size_t *ivlen, + const uint8_t **enced_content, size_t *enced_content_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, + const uint8_t **in, size_t *inlen); +int cms_encrypted_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int cms_encrypted_data_encrypt_to_der( + int content_type, + int enc_algor, const uint8_t *iv, size_t ivlen, + const uint8_t *content, size_t content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + const uint8_t *key, size_t keylen, + uint8_t **out, size_t *outlen); +int cms_encrypted_data_decrypt_from_der( + int *content_type, + int *enc_algor, const uint8_t **iv, size_t *ivlen, + uint8_t *content, size_t *content_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, + const uint8_t *key, size_t keylen, + const uint8_t **in, size_t *inlen); + +/* +IssuerAndSerialNumber ::= SEQUENCE { + isser Name, + serialNumber INTEGER } +*/ +int cms_issuer_and_serial_number_to_der( + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + uint8_t **out, size_t *outlen); +int cms_issuer_and_serial_number_from_der( + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial_number, size_t *serial_number_len, + const uint8_t **in, size_t *inlen); +int cms_issuer_and_serial_number_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +SignerInfo ::= SEQUENCE { + version INTEGER (1), + issuerAndSerialNumber IssuerAndSerialNumber, + digestAlgorithm AlgorithmIdentifier, + authenticatedAttributes [0] IMPLICIT SET OF Attribute OPTINOAL, + digestEncryptionAlgorithm AlgorithmIdentifier, + encryptedDigest OCTET STRING, + unauthenticatedAttributes [1] IMPLICIT SET OF Attribute OPTINOAL, } +*/ +int cms_signer_info_to_der( + int version, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + int digest_algor, + const uint8_t *authed_attrs, size_t authed_attrs_len, + int signature_algor, + const uint8_t *enced_digest, size_t enced_digest_len, + const uint8_t *unauthed_attrs, size_t unauthed_attrs_len, + uint8_t **out, size_t *outlen); +int cms_signer_info_from_der( + int *version, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial_number, size_t *serial_number_len, + int *digest_algor, + const uint8_t **authed_attrs, size_t *authed_attrs_len, + int *signature_algor, + const uint8_t **enced_digest, size_t *enced_digest_len, + const uint8_t **unauthed_attrs, size_t *unauthed_attrs_len, + const uint8_t **in, size_t *inlen); +int cms_signer_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int cms_signer_info_sign_to_der( + int version, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + const uint8_t *authed_attrs, size_t authed_attrs_len, + const uint8_t *unauthed_attrs, size_t unauthed_attrs_len, + const SM3_CTX *sm3_ctx, + const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len, + uint8_t **out, size_t *outlen); +int cms_signer_info_verify_from_der( + int *version, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial_number, size_t *serial_number_len, + int *digest_algor, + const uint8_t **authed_attrs, size_t *authed_attrs_len, + int *signature_algor, + const uint8_t **enced_digest, size_t *enced_digest_len, + const uint8_t **unauthed_attrs, size_t *unauthed_attrs_len, + const uint8_t *certs, size_t certslen, + const uint8_t **in, size_t *inlen); + +/* +SignerInfos ::= SET OF SignerInfo; +*/ +int cms_signer_infos_add_signer_info( + uint8_t *d, size_t *dlen, size_t maxlen, + int version, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + const uint8_t *authed_attrs, size_t authed_attrs_len, + const uint8_t *unauthed_attrs, size_t unauthed_attrs_len, + const SM3_CTX *sm3_ctx, + const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len); + +#define cms_signer_infos_to_der(d,dlen,out,outlen) asn1_set_to_der(d,dlen,out,outlen) +#define cms_signer_infos_from_der(d,dlen,in,inlen) asn1_set_from_der(d,dlen,in,inlen) +int cms_signer_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +CertificateRevocationLists ::= SET OF CertificateRevocationList +*/ +int cms_crls_add_crl(uint8_t *d, size_t *dlen, size_t maxlen, const uint8_t *crl, size_t crllen); +#define cms_crls_to_der(d,dlen,out,outlen) asn1_set_to_der(d,dlen,out,outlen) +#define cms_crls_from_der(d,dlen,in,inlen) asn1_set_from_der(d,dlen,in,inlen) +int cms_crls_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +ExtendedCertificateAndCertificate ::= CHOICE { + certificate Certificate, + extendedCertificate [0] IMPLICIT ExtendedCertificate } + +ExtendedCertificatesAndCertificates ::= SET OF + ExtendedCertificateOrCertificate + +ExtendedCertificate is supported in print, not in add/to/from +*/ +int cms_extened_certs_add_cert(uint8_t *d, size_t *dlen, size_t maxlen, const uint8_t *cert, size_t certlen); +#define cms_extened_certs_to_der(d,dlen,out,outlen) asn1_set_to_der(d,dlen,out,outlen) +#define cms_extened_certs_from_der(d,dlen,in,inlen) asn1_set_from_der(d,dlen,in,inlen) +int cms_extended_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +SignedData ::= SEQUENCE { + version INTEGER (1), + digestAlgorithms SET OF AlgorithmIdentifier, + contentInfo ContentInfo, + certificates [0] IMPLICIT SET OF Certificate OPTIONAL, + crls [1] IMPLICIT SET OF CertificateRevocationList OPTIONAL, + signerInfos SET OF SignerInfo } +*/ +int cms_signed_data_to_der( + int version, + const int *digest_algors, const size_t digest_algors_cnt, + const int content_type, const uint8_t *content, const size_t content_len, + const uint8_t *certs, size_t certs_len, + const uint8_t *crls, const size_t crls_lens, + const uint8_t *signer_infos, size_t signer_infos_lens, + uint8_t **out, size_t *outlen); +int cms_signed_data_from_der( + int *version, + const uint8_t *digest_algors, size_t *digest_algors_count, size_t max_digest_algors, + int *content_type, const uint8_t **content, size_t *content_len, + const uint8_t **certs, size_t *certs_len, + const uint8_t **crls, size_t *crls_len, +cms_set_key_agreement_info const uint8_t **signer_infos, size_t *signer_infos_len, + const uint8_t **in, size_t *inlen); +int cms_signed_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + +typedef struct { + uint8_t *certs; + size_t certs_len; + SM2_KEY *sm2_key; + char *signer_id; + size_t signer_id_len; +} CMS_CERT_AND_KEY; + +int cms_signed_data_sign_to_der( + int version, + int content_type, const uint8_t *content, size_t content_len, + const CMS_CERT_AND_KEY *signers, size_t signers_cnt, + const uint8_t *crls, size_t crls_len, + uint8_t **out, size_t *outlen); +int cms_signed_data_verify_from_der( + int *version, + const uint8_t *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors, + int *content_type, const uint8_t **content, size_t *content_len, + const uint8_t **certs, size_t *certs_len, + const uint8_t **crls, size_t *crls_len, + const uint8_t **signer_infos, size_t *signer_infos_len, + const uint8_t *extra_certs, size_t extra_certs_len, + const uint8_t *extra_crls, size_t extra_crls_len, + const uint8_t **in, size_t *inlen); + +/* +RecipientInfo ::= SEQUENCE { + version INTEGER (1), + issuerAndSerialNumber IssuerAndSerialNumber, + keyEncryptionAlgorithm AlgorithmIdentifier, + encryptedKey OCTET STRING -- DER-encoding of SM2Cipher +} +*/ +int cms_recipient_info_to_der( + int version, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + int public_key_enc_algor, + const uint8_t *enced_key, size_t enced_key_len, + uint8_t **out, size_t *outlen); +int cms_recipient_info_from_der( + int *version, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial_number, size_t *serial_number_len, + int *pke_algor, const uint8_t **params, size_t *paramslen,// SM2加密只使用SM3,没有默认参数,但是ECIES可能有 + const uint8_t **enced_key, size_t *enced_key_len, + const uint8_t **in, size_t *inlen); +int cms_recipient_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int cms_recipient_info_encrypt_to_der( + int version, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + int public_key_enc_algor, + const uint8_t *in, size_t inlen, + const SM2_KEY *public_key, + uint8_t **out, size_t *outlen); +int cms_recipient_info_decrypt_from_der( + int *version, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial_number, size_t *serial_number_len, + int *pke_algor, const uint8_t **params, size_t *paramslen, + const uint8_t **decrypted_key, size_t *decrypted_key_len, + const SM2_KEY *sm2_key, + const uint8_t **in, size_t *inlen); + +/* +EnvelopedData ::= SEQUENCE { + version Version, + recipientInfos SET OF RecipientInfo, + encryptedContentInfo EncryptedContentInfo } +*/ +int cms_enveloped_data_to_der( + int version, + const uint8_t *rcpt_infos, size_t rcpt_infos_len, + int content_type, + int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len, + const uint8_t *enced_content, size_t enced_content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + const uint8_t **out, size_t *outlen); +int cms_enveloped_data_from_der( + int *version, + const uint8_t **rcpt_infos, size_t *rcpt_infos_len, + int *content_type, + int *enc_algor, const uint8_t **enc_iv, size_t *enc_iv_len, + const uint8_t **enced_content, size_t *enced_content_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, + const uint8_t **in, size_t *inlen); +int cms_enveloped_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int cms_enveloped_data_encrypt_to_der( + int version, + const uint8_t *rcpt_certs, size_t rcpt_certs_len, // 当只有一个接收者的时候,这个参数类型非常方便 + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, int content_type, const uint8_t *content, size_t content_len, const uint8_t *shared_info1, size_t shared_info1_len, const uint8_t *shared_info2, size_t shared_info2_len, uint8_t **out, size_t *outlen); - int cms_enveloped_data_decrypt_from_der( - const SM2_KEY *sm2_key, const X509_CERTIFICATE *cert, // 应该用证书还是issuer_and_serial_number? + int *version, + const uint8_t **rcpt_infos, size_t *rcpt_infos_len, int *content_type, uint8_t *content, size_t *content_len, const uint8_t **shared_info1, size_t *shared_info1_len, const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **in, size_t *inlen); - - -const char *cms_content_type_name(int type); -int cms_content_type_to_der(int type, uint8_t **out, size_t *outlen); -int cms_content_type_from_der(int *type, const uint8_t **in, size_t *inlen); - -int cms_content_info_to_der(int content_type, const uint8_t *content, size_t content_len, - uint8_t **out, size_t *outlen); - -int cms_content_info_from_der(int *content_type, const uint8_t **content, size_t *content_len, - const uint8_t **in, size_t *inlen); - - - - -int cms_signer_info_to_der( - const X509_NAME *issuer, + const SM2_KEY *sm2_key, + const uint8_t *issuer, size_t issuer_len, const uint8_t *serial_number, size_t serial_number_len, - int digest_algor, - const uint8_t *authed_attrs, size_t authed_attrs_len, - const uint8_t *enced_digest, size_t enced_digest_len, - const uint8_t *unauthed_attrs, size_t unauthed_attrs_len, - uint8_t **out, size_t *outlen); - -int cms_signer_info_from_der(X509_NAME *issuer, - const uint8_t **serial_number, size_t *serial_number_len, - int *digest_algor, - const uint8_t **authed_attrs, size_t *authed_attrs_len, - int *sign_algor, - const uint8_t **enced_digest, size_t *enced_digest_len, - const uint8_t **unauthed_attrs, size_t *unauthed_attrs_len, const uint8_t **in, size_t *inlen); -int cms_signer_info_print(FILE *fp, - int version, - const X509_NAME *issuer, const uint8_t *serial_number, size_t serial_number_len, - int digest_algor, const uint8_t *digest_params, size_t digest_params_len, - const uint8_t *authed_attrs, size_t authed_attrs_len, - int sign_algor, const uint8_t *sign_params, size_t sign_params_len, - const uint8_t *sig, size_t siglen, - const uint8_t *unauthed_attrs, size_t unauthed_attrs_len, - int format, int indent); - -int cms_signer_info_sign_to_der(const SM2_KEY *sm2_key, const SM3_CTX *sm3_ctx, - const X509_NAME *issuer, const uint8_t *serial_number, size_t serial_number_len, - const uint8_t *authed_attrs, size_t authed_attrs_len, - const uint8_t *unauthed_attrs, size_t unauthed_attrs_len, - uint8_t **out, size_t *outlen); - -int cms_signer_info_verify( - const SM2_KEY *sm2_key, const SM3_CTX *sm3_ctx, - const uint8_t *authed_attrs, size_t authed_attrs_len, - const uint8_t *sig, size_t siglen); - - -int cms_signed_data_to_der( - const int *digest_algors, const size_t digest_algors_count, - const int content_type, const uint8_t *content, const size_t content_len, - const X509_CERTIFICATE *certs, size_t certs_count, - const uint8_t **crls, const size_t *crls_lens, const size_t crls_count, - const uint8_t **signer_infos, size_t *signer_infos_lens, size_t signer_infos_count, - uint8_t **out, size_t *outlen); - -int cms_signed_data_from_der( - const uint8_t **digest_algors, size_t *digest_algors_len, - int *content_type, const uint8_t **content, size_t *content_len, - const uint8_t **certs, size_t *certs_len, - const uint8_t **crls, size_t *crls_len, - const uint8_t **signer_infos, size_t *signer_infos_len, - const uint8_t **in, size_t *inlen); - -int cms_signed_data_print(FILE *fp, const uint8_t *a, size_t alen, int format, int indent); - -int cms_signed_data_sign_to_der(const SM2_KEY *sign_keys, - const X509_CERTIFICATE *sign_certs, size_t sign_count, - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *crls, size_t crls_len, - uint8_t **out, size_t *outlen); - -int cms_signed_data_verify_from_der( - const uint8_t **digest_algors, size_t *digest_algors_len, - int *content_type, const uint8_t **content, size_t *content_len, - const uint8_t **certs, size_t *certs_len, - const uint8_t **crls, size_t *crls_len, - const uint8_t **signer_infos, size_t *signer_infos_len, - const uint8_t **in, size_t *inlen); - -int cms_signed_data_verify( - int content_type, const uint8_t *content, size_t content_len, // 被签名的到底是什么数据? - const uint8_t *certs, size_t certs_len, - const uint8_t *signer_infos, size_t signer_infos_len); - - +/* +SignedAndEnvelopedData ::= SEQUENCE { + version INTEGER (1), + recipientInfos SET OF RecipientInfo, + digestAlgorithms SET OF AlgorithmIdentifier, + encryptedContentInfo EncryptedContentInfo, + certificates [0] IMPLICIT SET OF Certificate OPTIONAL, + crls [1] IMPLICIT SET OF CertificateRevocationList OPTIONAL, + signerInfos SET OF SignerInfo } +*/ int cms_signed_and_enveloped_data_to_der( int version, const uint8_t *rcpt_infos, size_t rcpt_infos_len, const int *digest_algors, size_t digest_algors_count, int content_type, - int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len, - const uint8_t *enced_content, size_t enced_content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - const X509_CERTIFICATE *certs, size_t certs_count, - const uint8_t *crls, size_t crls_count, - const uint8_t signer_infos, size_t signer_infos_len); - + int enc_algor, const uint8_t *iv, size_t ivlen, + const uint8_t *enced_content, size_t enced_content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + const uint8_t *certs, size_t certs_len, + const uint8_t *crls, size_t crls_len, + const uint8_t *signer_infos, size_t signer_infos_len); int cms_signed_and_enveloped_data_from_der( int *version, const uint8_t **rcpt_infos, size_t *rcpt_infos_len, - const uint8_t **dgst_algors, size_t *dgst_algors_len, + const uint8_t **digest_algors, size_t *digest_algors_len, int *content_type, - int *enc_algor, const uint8_t **enc_iv, size_t *enc_iv_len, - const uint8_t **enced_content, size_t *enced_content_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, + int *enc_algor, const uint8_t **enc_iv, size_t *enc_iv_len, + const uint8_t **enced_content, size_t *enced_content_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, const uint8_t **certs, size_t *certs_len, const uint8_t **crls, size_t *crls_len, const uint8_t **signer_infos, size_t *signer_infos_len, const uint8_t **in, size_t *inlen); +int cms_signed_and_enveloped_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); -int cms_signed_and_enveloped_data_print(FILE *fp, const uint8_t *a, size_t alen, - int format, int indent); - - - - -int cms_signed_and_enveloped_data_sign_encrypt_to_der( - const SM2_KEY *sign_keys, const X509_CERTIFICATE *sign_certs, size_t sign_count, - const uint8_t *sign_crls, const size_t sign_crls_len, - const X509_CERTIFICATE *rcpt_certs, size_t rcpt_count, +int cms_signed_and_enveloped_encipher_to_der( + const CMS_CERT_AND_KEY *signers, size_t signers_cnt, + const uint8_t *rcpt_certs, size_t rcpt_certs_len, int content_type, const uint8_t *content, size_t content_len, + const uint8_t *signer_crls, size_t signer_crls_len, const uint8_t *shared_info1, size_t shared_info1_len, const uint8_t *shared_info2, size_t shared_info2_len, uint8_t **out, size_t *outlen); - -int cms_signed_and_enveloped_data_decrypt_verify_from_der( - const SM2_KEY *dec_key, const X509_CERTIFICATE *dec_cert, +int cms_deenvelop_and_verify_decipher_from_der( + int *version, const uint8_t **rcpt_infos, size_t *rcpt_infos_len, - const uint8_t **dgst_algors, size_t *dgst_algors_len, - int *content_type, - int *enc_algor, const uint8_t **enc_iv, size_t *enc_iv_len, - const uint8_t **enced_content, size_t *enced_content_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **certs, size_t *certs_len, - const uint8_t **crls, size_t *crls_len, - const uint8_t **signer_infos, size_t *signer_infos_len); - - -/* -下面是预计export的函数 -*/ - -int cms_content_info_print(FILE *fp, const uint8_t *a, size_t alen, int format, int indent); - - -int cms_encrypt(const uint8_t key[16], const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen); - -int cms_decrypt(const uint8_t key[16], const uint8_t *in, size_t inlen, - int *content_type, uint8_t *out, size_t *outlen); - -int cms_seal(const X509_CERTIFICATE *rcpt_certs, size_t rcpt_count, - const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen); - -int cms_open(const SM2_KEY *sm2_key, const X509_CERTIFICATE *cert, - const uint8_t *in, size_t inlen, - int *content_type, uint8_t *out, size_t *outlen); - -int cms_sign(const SM2_KEY *sign_keys, const X509_CERTIFICATE *sign_certs, size_t sign_count, - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); - -int cms_verify(int *content_type, const uint8_t **content, size_t *content_len, + const uint8_t **digest_algors, size_t *digest_algors_len, + int *enc_algor, uint8_t *key, size_t *keylen, const uint8_t **iv, size_t *ivlen, + int *content_type, uint8_t *content, size_t *content_len, + const uint8_t **enced_content, size_t *enced_content_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, const uint8_t **certs, size_t *certs_len, const uint8_t **crls, size_t *crls_len, const uint8_t **signer_infos, size_t *signer_infos_len, - const uint8_t *cms, size_t cmslen); -int cms_sign_and_seal(const SM2_KEY *sign_keys, - const X509_CERTIFICATE *sign_certs, size_t sign_count, - const X509_CERTIFICATE *rcpt_certs, size_t rcpt_count, - const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen); + const SM2_KEY *rcpt_key, + const uint8_t *rcpt_issuer, size_t rcpt_issuer_len, + const uint8_t *rcpt_serial_number, size_t rcpt_serial_number_len, + const uint8_t *extra_verify_certs, size_t extra_verify_certs_len, + const uint8_t *extra_verify_crls, size_t extra_verify_crls_len, -int cms_open_and_verify( - const SM2_KEY *sm2_key, const X509_CERTIFICATE *cert, - const uint8_t *in, size_t inlen, - int *content_type, uint8_t *out, size_t *outlen); + const uint8_t **in, size_t *inlen); +/* +KeyAgreementInfo ::= SEQUENCE { + version INTEGER (1), + tempPublicKeyR SM2PublicKey, + userCertificate Certificate, + userID OCTET STRING } +*/ +int cms_key_agreement_info_to_der( + int version, + const SM2_KEY *temp_public_key_r, + const uint8_t *user_cert, size_t user_cert_len, + const uint8_t *user_id, size_t user_id_len, + uint8_t **out, size_t *outlen); +int cms_key_agreement_info_from_der( + int *version, + SM2_KEY *temp_public_key_r, + const uint8_t **user_cert, size_t *user_cert_len, + const uint8_t **user_id, size_t *user_id_len, + const uint8_t **in, size_t *inlen); +int cms_key_agreement_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + + +// 下面是公开API + + +// 生成ContentInfo, type == data +int cms_set_data(uint8_t *cms, size_t *cms_len, const uint8_t *d, size_t dlen); + +int cms_encrypt( + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, // 对称加密算法、密钥和IV + int content_type, const uint8_t *content, size_t content_len, // 待加密的输入数据 + const uint8_t *shared_info1, size_t shared_info1_len, // 附加信息 + const uint8_t *shared_info2, size_t shared_info2_len, // 附加信息 + uint8_t *cms, size_t *cms_len); // 输出的ContentInfo (type encryptedData) + +int cms_decrypt( + const uint8_t *key, size_t keylen, // 解密密钥(我们不知道解密算法) + const uint8_t *cms, size_t cms_len, // 输入的ContentInfo (type encryptedData) + const uint8_t *extra_enced_content, size_t extra_enced_content_len, // EncryptedContentInfo的密文数据为空时显示提供输入密文 + int *content_type, uint8_t *content, size_t *content_len, // 输出的解密数据类型及数据 + int *enc_algor, const uint8_t **iv, size_t *ivlen, // 解析EncryptedContentInfo得到的对称加密算法及参数 + const uint8_t **shared_info1, size_t *shared_info1_len, // 附加信息 + const uint8_t **shared_info2, size_t *shared_info2_len); + +int cms_sign( + const CMS_CERT_AND_KEY *signers, size_t signers_cnt, // 签名者的签名私钥和证书 + int content_type, const uint8_t *content, size_t content_len, // 待签名的输入数据 + const uint8_t *crls, size_t crls_len, // 签名者证书的CRL + uint8_t *cms, size_t *cms_len); // 输出的ContentInfo (type signedData) + +int cms_verify( + const uint8_t *cms, size_t cms_len, // 输入的ContentInfo (type signedData) + const uint8_t *extra_content, size_t extra_content_len, // ContentInfo的数据为空时显示提供输入 + const uint8_t *extra_certs, size_t extra_certs_len, // 当SignedData中未提供证书时显示输入 + const uint8_t *extra_crls, size_t extra_crls_len, // 当SignedData中未提供CRL时显示输入 + int *content_type, const uint8_t **content, size_t *content_len, // 从SignedData解析得到的被签名数据 + const uint8_t **certs, size_t *certs_len, // 从SignedData解析得到的签名证书 + const uint8_t **crls, size_t *crls_len, // 从SignedData解析得到的CRL + const uint8_t **signer_infos, size_t *signer_infos_len); // 从SignedData解析得到的SignerInfos,可用于显示验证结果 + +int cms_envelop( + const uint8_t *rcpt_certs, size_t rcpt_certs_len, // 接收方证书,注意这个参数的类型可以容纳多个证书,但是只有在一个接受者时对调用方最方便 + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, // 对称加密算法及参数 + int content_type, const uint8_t *content, size_t content_len, // 待加密的输入数据 + const uint8_t *shared_info1, size_t shared_info1_len, // 附加输入信息 + const uint8_t *shared_info2, size_t shared_info2_len, // 附加输入信息 + uint8_t *cms, size_t *cms_len); // 输出ContentInfo + +int cms_deenvelop( + const SM2_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len, // 接收方的解密私钥和对应的证书,注意只需要一个解密方 + const uint8_t *cms, size_t cms_len, + const uint8_t *extra_enced_content, size_t extra_enced_content_len, // 显式输入的密文 + int *content_type, uint8_t *content, size_t *content_len, + int *enc_algor, const uint8_t **iv, size_t *ivlen, // 注意,对称加密的密钥就不输出了 + const uint8_t **rcpt_infos, size_t *rcpt_infos_len, // 解析得到,用于显示 + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len); + +int cms_sign_and_envelop( // 参考cms_sign, cms_envelop + const CMS_CERT_AND_KEY *signers, size_t signers_cnt, + const uint8_t *rcpt_certs, size_t rcpt_certs_len, + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, + int content_type, const uint8_t *content, size_t content_len, + const uint8_t *signer_crls, size_t signer_crls_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t *cms, size_t *cms_len); + +int cms_deenvelop_and_verify( // 参考cms_deenvelop, cms_verify + const SM2_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len, + // 输入 + const uint8_t *cms, size_t cms_len, + const uint8_t *extra_enced_content, size_t extra_enced_content_len, + const uint8_t *extra_signer_certs, size_t extra_signer_certs_len, + const uint8_t *extra_signer_crls, size_t extra_signer_crls_len, + // 输出 + int *content_type, uint8_t *content, size_t *content_len, + // 格外的解析内容输出,均为可选 + int *enc_algor, const uint8_t **iv, size_t *ivlen, + const uint8_t **rcpt_infos, size_t rcpt_infos_len, + const uint8_t **signer_infos, size_t *signer_infos_len, + const uint8_t **signer_certs, size_t *signer_certs_len, + const uint8_t **signer_crls, size_t *signer_crls_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len); + +// 生成ContentInfo, type == keyAgreementInfo +int cms_set_key_agreement_info( + uint8_t *cms, size_t *cms_len, + const SM2_KEY *temp_public_key_r, + const uint8_t *user_cert, size_t user_cert_len, + const uint8_t *user_id, size_t user_id_len); + +int cms_print(FILE *fp, int fmt, int ind, const uint8_t *a, size_t alen); + #ifdef __cplusplus } diff --git a/include/gmssl/des.h b/include/gmssl/des.h index f879d64e..22b50a04 100644 --- a/include/gmssl/des.h +++ b/include/gmssl/des.h @@ -63,30 +63,31 @@ extern "C" { #define DES_KEY_BITS 56 #define DES_BLOCK_BITS 64 -#define DES_KEY_SIZE (DES_KEY_BITS/8) +#define DES_KEY_SIZE ((DES_KEY_BITS)/7) #define DES_BLOCK_SIZE (DES_BLOCK_BITS/8) #define DES_RK_BITS 48 #define DES_RK_SIZE (DES_RK_BITS/8) #define DES_ROUNDS 16 +#define DES_EDE_KEY_SIZE (DES_KEY_SIZE * 3) typedef struct { uint64_t rk[DES_ROUNDS]; } DES_KEY; -void des_set_encrypt_key(DES_KEY *key, const unsigned char user_key[8]); -void des_set_decrypt_key(DES_KEY *key, const unsigned char user_key[8]); -void des_encrypt(DES_KEY *key, const unsigned char in[8], unsigned char out[8]); +void des_set_encrypt_key(DES_KEY *key, const uint8_t raw_key[DES_KEY_SIZE]); +void des_set_decrypt_key(DES_KEY *key, const uint8_t raw_key[DES_KEY_SIZE]); +void des_encrypt(DES_KEY *key, const uint8_t in[DES_BLOCK_SIZE], uint8_t out[DES_BLOCK_SIZE]); typedef struct { DES_KEY K[3]; } DES_EDE_KEY; -void des_ede_set_encrypt_key(DES_EDE_KEY *key, const unsigned char user_key[24]); -void des_ede_set_decrypt_key(DES_EDE_KEY *key, const unsigned char user_key[24]); -void des_ede_encrypt(DES_EDE_KEY *key, const unsigned char in[8], unsigned char out[8]); +void des_ede_set_encrypt_key(DES_EDE_KEY *key, const uint8_t raw_key[DES_EDE_KEY_SIZE]); +void des_ede_set_decrypt_key(DES_EDE_KEY *key, const uint8_t raw_key[DES_EDE_KEY_SIZE]); +void des_ede_encrypt(DES_EDE_KEY *key, const uint8_t in[DES_BLOCK_SIZE], uint8_t out[DES_BLOCK_SIZE]); #ifdef __cplusplus diff --git a/include/gmssl/digest.h b/include/gmssl/digest.h index 9633dedf..92695fd6 100644 --- a/include/gmssl/digest.h +++ b/include/gmssl/digest.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -64,16 +64,15 @@ extern "C" { #endif -typedef struct digest_st DIGEST; -typedef struct digest_ctx_st DIGEST_CTX; +typedef struct DIGEST DIGEST; +typedef struct DIGEST_CTX DIGEST_CTX; #define DIGEST_MAX_SIZE 64 #define DIGEST_MAX_BLOCK_SIZE (1024/8) -struct digest_ctx_st { - const DIGEST *digest; +struct DIGEST_CTX { union { SM3_CTX sm3_ctx; MD5_CTX md5_ctx; @@ -83,23 +82,19 @@ struct digest_ctx_st { SHA384_CTX sha384_ctx; SHA512_CTX sha512_ctx; } u; + const DIGEST *digest; }; -struct digest_st { - int nid; +struct DIGEST { + int oid; size_t digest_size; size_t block_size; size_t ctx_size; int (*init)(DIGEST_CTX *ctx); - int (*update)(DIGEST_CTX *ctx, const unsigned char *data, size_t datalen); - int (*finish)(DIGEST_CTX *ctx, unsigned char *dgst); + int (*update)(DIGEST_CTX *ctx, const uint8_t *data, size_t datalen); + int (*finish)(DIGEST_CTX *ctx, uint8_t *dgst); }; -int digest_nid(const DIGEST *digest); -const char *digest_name(const DIGEST *digest); -size_t digest_size(const DIGEST *digest); -size_t digest_block_size(const DIGEST *digest); - const DIGEST *DIGEST_sm3(void); const DIGEST *DIGEST_md5(void); const DIGEST *DIGEST_sha1(void); @@ -111,26 +106,12 @@ const DIGEST *DIGEST_sha512_224(void); const DIGEST *DIGEST_sha512_256(void); const DIGEST *digest_from_name(const char *name); - -int digest_ctx_nid(const DIGEST_CTX *ctx); -const char *digest_ctx_name(const DIGEST_CTX *ctx); -size_t digest_ctx_size(const DIGEST_CTX *ctx); -size_t digest_ctx_block_size(const DIGEST_CTX *ctx); -const DIGEST *digest_ctx_digest(const DIGEST_CTX *ctx); - -int digest_ctx_init(DIGEST_CTX *ctx); +const char *digest_name(const DIGEST *digest); int digest_init(DIGEST_CTX *ctx, const DIGEST *algor); -int digest_update(DIGEST_CTX *ctx, const unsigned char *data, size_t datalen); -int digest_finish(DIGEST_CTX *ctx, unsigned char *dgst, size_t *dgstlen); -void digest_ctx_cleanup(DIGEST_CTX *ctx); +int digest_update(DIGEST_CTX *ctx, const uint8_t *data, size_t datalen); +int digest_finish(DIGEST_CTX *ctx, uint8_t *dgst, size_t *dgstlen); +int digest(const DIGEST *digest, const uint8_t *data, size_t datalen, uint8_t *dgst, size_t *dgstlen); -int digest(const DIGEST *digest, const unsigned char *data, size_t datalen, - unsigned char *dgst, size_t *dgstlen); - -const char *digest_algor_name(int oid); -int digest_algor_to_der(int oid, uint8_t **out, size_t *outlen); -int digest_algor_from_der(int *oid, uint32_t *nodes, size_t *nodes_count, - const uint8_t **in, size_t *inlen); #ifdef __cplusplus } diff --git a/include/gmssl/crl.h b/include/gmssl/ec.h similarity index 67% rename from include/gmssl/crl.h rename to include/gmssl/ec.h index 43044202..d45ea9c2 100644 --- a/include/gmssl/crl.h +++ b/include/gmssl/ec.h @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2020 - 2021 The GmSSL Project. All rights reserved. +/* + * 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 @@ -46,67 +46,40 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ - -#ifndef GMSSL_CRL_H -#define GMSSL_CRL_H +#ifndef GMSSL_EC_H +#define GMSSL_EC_H +#include +#include +#include +#include +#include +#include +#include #ifdef __cplusplus extern "C" { #endif +/* +curve: + OID_sm2 + OID_prime192v1 + OID_prime256v1 + OID_secp256k1 + OID_secp384r1 + OID_secp521r1 +*/ +const char *ec_curve_name(int curve); +int ec_curve_from_name(const char *name); -typedef enum X509_CRLReason { - X509_cr_unspecified = 0, - X509_cr_keyCompromise, - X509_cr_cACompromise, - X509_cr_affiliationChanged, - X509_cr_superseded, - X509_cr_cessationOfOperation, - X509_cr_certificateHold, - X509_cr_7_not_assigned = 7, - X509_cr_removeFromCRL, - X509_cr_privilegeWithdrawn, - X509_cr_aACompromise, -} CRL_REASON; - -typedef struct { - uint8_t serial_number[20]; - size_t serial_number_len; - time_t revoke_date; - CRL_EXTENSIONS crlEntryExtensions; -} CRL_REVOKED_CERT; - -typedef struct { - int version; // OPTIONAL, if present MUST be v2 - int signature_algor; - X509_NAME issuer; - time_t this_update; - time_t next_update; - uint8_t *revoked_certs; - size_t revoked_certs_count; - X509_EXTENSION crl_exts[32]; - size_t crl_exts_count; - - uint8_t buf[1024]; -} CRL_TBS_CERT_LIST; - -typedef struct { - X509_TBS_CERT_LIST tbs_cert_list; - int signature_algor; - uint8_t signature[128]; - size_t signature_len; -} CRL_CERT_LIST; +int ec_public_key_algor_to_der(int curve, uint8_t **out, size_t *outlen); +int ec_public_key_algor_from_der(int *curve, const uint8_t **in, size_t *inlen); +int ec_public_key_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - - - - - - -#ifdef __cplusplus +#ifdef __cplusplus } #endif #endif diff --git a/include/gmssl/error.h b/include/gmssl/error.h index c4ec5f09..81a56e61 100644 --- a/include/gmssl/error.h +++ b/include/gmssl/error.h @@ -79,6 +79,7 @@ void print_nodes(const uint32_t *in, size_t inlen); int format_print(FILE *fp, int format, int indent, const char *str, ...); int format_bytes(FILE *fp, int format, int indent, const char *str, const uint8_t *data, size_t datalen); +int format_string(FILE *fp, int format, int indent, const char *str, const uint8_t *data, size_t datalen); //int tls_trace(int format, int indent, const char *str, ...); diff --git a/include/gmssl/gcm.h b/include/gmssl/gcm.h index ce7035ad..bf9d6107 100644 --- a/include/gmssl/gcm.h +++ b/include/gmssl/gcm.h @@ -61,8 +61,6 @@ extern "C" { #endif - - #define GCM_IV_MIN_SIZE 1 #define GCM_IV_MAX_SIZE ((uint64_t)(1 << (64-3))) #define GCM_IV_DEFAULT_BITS 96 @@ -84,7 +82,6 @@ extern "C" { void ghash(const uint8_t h[16], const uint8_t *aad, size_t aadlen, const uint8_t *c, size_t clen, uint8_t out[16]); - int gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, uint8_t *out, size_t taglen, uint8_t *tag); @@ -94,8 +91,6 @@ int gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, const uint8_t *tag, size_t taglen, uint8_t *out); - - #ifdef __cplusplus } #endif diff --git a/include/gmssl/hex.h b/include/gmssl/hex.h index 466019a7..dfeb8f96 100644 --- a/include/gmssl/hex.h +++ b/include/gmssl/hex.h @@ -64,10 +64,6 @@ extern "C" { int hex_to_bytes(const char *in, size_t inlen, uint8_t *out, size_t *outlen); -int hex2bin(const char *in, size_t inlen, uint8_t *out); -//int OPENSSL_hexchar2int(unsigned char c); -//unsigned char *OPENSSL_hexstr2buf(const char *str, size_t *len); - #ifdef __cplusplus } #endif diff --git a/include/gmssl/hkdf.h b/include/gmssl/hkdf.h index 85c0dddf..45ce05c7 100644 --- a/include/gmssl/hkdf.h +++ b/include/gmssl/hkdf.h @@ -69,7 +69,6 @@ int hkdf_expand(const DIGEST *digest, const uint8_t *prk, size_t prklen, size_t L, uint8_t *okm); - #ifdef __cplusplus } #endif diff --git a/include/gmssl/hmac.h b/include/gmssl/hmac.h index 62511e85..af692f18 100644 --- a/include/gmssl/hmac.h +++ b/include/gmssl/hmac.h @@ -70,13 +70,13 @@ typedef struct hmac_ctx_st { size_t hmac_size(const HMAC_CTX *ctx); -int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const unsigned char *key, size_t keylen); -int hmac_update(HMAC_CTX *ctx, const unsigned char *data, size_t datalen); -int hmac_finish(HMAC_CTX *ctx, unsigned char *mac, size_t *maclen); +int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const uint8_t *key, size_t keylen); +int hmac_update(HMAC_CTX *ctx, const uint8_t *data, size_t datalen); +int hmac_finish(HMAC_CTX *ctx, uint8_t *mac, size_t *maclen); -int hmac(const DIGEST *md, const unsigned char *key, size_t keylen, - const unsigned char *data, size_t dlen, - unsigned char *mac, size_t *maclen); +int hmac(const DIGEST *md, const uint8_t *key, size_t keylen, + const uint8_t *data, size_t dlen, + uint8_t *mac, size_t *maclen); #ifdef __cplusplus diff --git a/include/gmssl/md5.h b/include/gmssl/md5.h index e388690c..d550c5ff 100644 --- a/include/gmssl/md5.h +++ b/include/gmssl/md5.h @@ -64,13 +64,13 @@ extern "C" { #define MD5_DIGEST_SIZE 16 #define MD5_BLOCK_SIZE 64 - +#define MD5_STATE_WORDS (MD5_BLOCK_SIZE/sizeof(uint32_t)) typedef struct { - uint32_t state[4]; - uint64_t nblocks; /* num of processed blocks */ - uint8_t block[64]; /* buffer */ - size_t num; /* buffered bytes in |block| */ + uint32_t state[MD5_STATE_WORDS]; + uint64_t nblocks; + uint8_t block[MD5_BLOCK_SIZE]; + size_t num; } MD5_CTX; diff --git a/include/gmssl/oid.h b/include/gmssl/oid.h index 36c290c9..e224288e 100644 --- a/include/gmssl/oid.h +++ b/include/gmssl/oid.h @@ -50,56 +50,14 @@ OCSPSigning * Redistribution and use in source and binary forms, with or without #ifndef GMSSL_OID_H #define GMSSL_OID_H - #include - #ifdef __cplusplus extern "C" { #endif - enum { OID_undef = 0, - //OID_aes, - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ShangMi schemes in GM/T 0006-2012 OID_sm1, @@ -119,129 +77,75 @@ enum { OID_hmac_sm3, OID_sm2sign_with_sm3, OID_rsasign_with_sm3, - OID_x9_62_ecPublicKey, // start of X9.62 curves + OID_ec_public_key, // X9.62 ecPublicKey OID_prime192v1, - OID_prime192v2, - OID_prime192v3, - OID_prime239v1, - OID_prime239v2, - OID_prime239v3, OID_prime256v1, - OID_secp256k1, // start of SECG curves (secure curves only!) + OID_secp256k1, OID_secp192k1, OID_secp224k1, OID_secp224r1, OID_secp384r1, OID_secp521r1, - OID_at_commonName, // start of X.509 Attributes - OID_at_surname, - OID_at_serialNumber, - OID_at_countryName, - OID_at_localityName, - OID_at_stateOrProvinceName, - OID_at_streetAddress, - OID_at_organizationName, - OID_at_organizationalUnitName, - OID_at_title, - OID_at_description, - OID_at_searchGuide, - OID_at_businessCategory, - OID_at_postalAddress, - OID_at_postalCode, - OID_at_postOfficeBox, - OID_at_physicalDeliveryOfficeName, - OID_at_telephoneNumber, - OID_at_telexNumber, - OID_at_teletexTerminalIdentifier, - OID_at_facsimileTelephoneNumber, - OID_at_x121Address, - OID_at_internationaliSDNNumber, - OID_at_registeredAddress, - OID_at_destinationIndicator, - OID_at_preferredDeliveryMethod, - OID_at_presentationAddress, - OID_at_supportedApplicationContext, - OID_at_member, - OID_at_owner, - OID_at_roleOccupant, - OID_at_seeAlso, - OID_at_userPassword, - OID_at_userCertificate, - OID_at_caCertificate, - OID_at_authorityRevocationList, - OID_at_certificateRevocationList, - OID_at_crossCertificatePair, + OID_at_name, - OID_at_givenName, + OID_at_surname, + OID_at_given_name, OID_at_initials, - OID_at_generationQualifier, - OID_at_x500UniqueIdentifier, - OID_at_dnQualifier, - OID_at_enhancedSearchGuide, - OID_at_protocolInformation, - OID_at_distinguishedName, - OID_at_uniqueMember, - OID_at_houseIdentifier, - OID_at_supportedAlgorithms, - OID_at_deltaRevocationList, - OID_at_dmdName, + OID_at_generation_qualifier, + OID_at_common_name, + OID_at_locality_name, + OID_at_state_or_province_name, + OID_at_organization_name, + OID_at_organizational_unit_name, + OID_at_title, + OID_at_dn_qualifier, + OID_at_country_name, + OID_at_serial_number, OID_at_pseudonym, - OID_at_role, + OID_domain_component, - /* ext 1 */ OID_ce_authorityKeyIdentifier, - /* ext 2 */ OID_ce_subjectKeyIdentifier, - /* ext 3 */ OID_ce_keyUsage, - /* ext 4 */ OID_ce_certificatePolicies, // start of X.500v3 Certificate Extensions - /* ext 5 */ OID_ce_policyMappings, // start of OID_ce_certificatePolicies, - /* ext 6 */ OID_ce_subjectAltName, - /* ext 7 */ OID_ce_issuerAltName, - /* ext 8 */ OID_ce_subjectDirectoryAttributes, - /* ext 9 */ OID_ce_basicConstraints, - /* ext 10 */ OID_ce_nameConstraints, - /* ext 11 */ OID_ce_policyConstraints, - /* ext 12 */ OID_ce_extKeyUsage, - /* ext 13 */ OID_ce_crlDistributionPoints, - /* ext 14 */ OID_ce_inhibitAnyPolicy, - /* ext 15 */ OID_ce_freshestCRL, + // Cert Extensions + OID_ce_authority_key_identifier, + OID_ce_subject_key_identifier, + OID_ce_key_usage, + OID_ce_certificate_policies, + OID_ce_policy_mappings, + OID_ce_subject_alt_name, + OID_ce_issuer_alt_name, + OID_ce_subject_directory_attributes, + OID_ce_basic_constraints, + OID_ce_name_constraints, + OID_ce_policy_constraints, + OID_ce_ext_key_usage, + OID_ce_crl_distribution_points, + OID_ce_inhibit_any_policy, + OID_ce_freshest_crl, - OID_ce_primaryKeyUsageRestriction, - - - - OID_ce_privateKeyUsagePeriod, - - - - OID_ce_crlNumber, - OID_ce_reasonCode, - OID_ce_instructionCode, - OID_ce_invalidityDate, - OID_ce_deltaCRLIndicator, - OID_ce_issuingDistributionPoint, - OID_ce_certificateIssuer, - - - - - - - - + // CRL Extensions + //OID_ce_authority_key_identifier, + //OID_ce_issuer_alt_name, + OID_ce_crl_number, + OID_ce_delta_crl_indicator, + OID_ce_issuing_distribution_point, + //OID_ce_freshest_crl, + OID_pe_authority_info_access, + // CRL Entry Extensions + OID_ce_crl_reasons, + OID_ce_invalidity_date, + OID_ce_certificate_issuer, - OID_kp_serverAuth, // start of X.509 KeyPropuseID - OID_kp_clientAuth, - OID_kp_codeSigning, - OID_kp_emailProtection, - OID_kp_timeStamping, - OID_kp_OCSPSigning, - + // X.509 KeyPropuseID + OID_kp_server_auth, + OID_kp_client_auth, + OID_kp_code_signing, + OID_kp_email_protection, + OID_kp_time_stamping, + OID_kp_ocsp_signing, OID_qt_cps, OID_qt_unotice, - OID_MAX, - OID_md5, OID_sha1, OID_sha224, @@ -251,7 +155,6 @@ enum { OID_sha512_224, OID_sha512_256, - OID_pbkdf2, // {pkcs-5 12} OID_pbes2, // {pkcs-5 13} OID_hmacWithSHA1, @@ -260,7 +163,6 @@ enum { OID_sm4_ecb, // 1 2 156 10197 1 104 1 OID_sm4_cbc, // 1 2 156 10197 1 104 2 - OID_aes, OID_aes128_cbc, OID_aes192_cbc, @@ -281,58 +183,33 @@ enum { OID_rsa_encryption, OID_rsaes_oaep, + OID_any_policy, + OID_cms_data, + OID_cms_signed_data, + OID_cms_enveloped_data, + OID_cms_signed_and_enveloped_data, + OID_cms_encrypted_data, + OID_cms_key_agreement_info, }; -typedef struct { - int oid; - uint32_t nodes[32]; - int nodes_count; -} ASN1_OBJECT_IDENTIFIER; +#define oid_pkix 1,3,6,1,5,5,7 + +#define oid_pe oid_pkix,1 +#define oid_qt oid_pkix,2 +#define oid_kp oid_pkix,3 +#define oid_ad oid_pkix,48 -const char *asn1_sm_oid_name(int oid); -const char *asn1_sm_oid_description(int oid); -void asn1_sm_oid_to_octets(int oid, uint8_t *out, size_t *outlen); -int asn1_sm_oid_from_octets(const uint8_t *in, size_t inlen); -int asn1_sm_oid_from_name(const char *name); - -const char *asn1_x9_62_curve_oid_name(int oid); -const char *asn1_x9_62_curve_oid_description(int oid); -void asn1_x9_62_curve_oid_to_octets(int oid, uint8_t *out, size_t *outlen); -int asn1_x9_62_curve_oid_from_octets(const uint8_t *in, size_t inlen); -int asn1_x9_62_curve_oid_from_name(const char *name); - -const char *asn1_secg_curve_oid_name(int oid); -const char *asn1_secg_curve_oid_description(int oid); -void asn1_secg_curve_oid_to_octets(int oid, uint8_t *out, size_t *outlen); -int asn1_secg_curve_oid_from_octets(const uint8_t *in, size_t inlen); -int asn1_secg_curve_oid_from_name(const char *name); - -const char *asn1_x509_oid_name(int oid); -const char *asn1_x509_oid_description(int oid); -void asn1_x509_oid_to_octets(int oid, uint8_t *out, size_t *outlen); -int asn1_x509_oid_from_octets(const uint8_t *in, size_t inlen); -int asn1_x509_oid_from_name(const char *name); +#define oid_at 2,5,4 +#define oid_ce 2,5,29 -const char *asn1_x509_kp_oid_name(int oid); -const char *asn1_x509_kp_oid_description(int oid); -void asn1_x509_kp_oid_to_octets(int oid, uint8_t *out, size_t *outlen); -int asn1_x509_kp_oid_from_octets(const uint8_t *in, size_t inlen); -int asn1_x509_kp_oid_from_name(const char *name); +#define oid_sm2_cms 1,2,156,10197,6,1,4,2 -void asn1_oid_to_octets(int oid, uint8_t *out, size_t *outlen); -int asn1_oid_from_octets(const uint8_t *in, size_t inlen); -int asn1_oid_nodes_to_octets(const uint32_t *nodes, size_t nodes_count, uint8_t *out, size_t *outlen); -int asn1_oid_nodes_from_octets(uint32_t *nodes, size_t *nodes_count, const uint8_t *in, size_t inlen); - -int test_asn1_oid(void); -int test_asn1_object_identifier(void); - #ifdef __cplusplus } #endif diff --git a/include/gmssl/pbkdf2.h b/include/gmssl/pbkdf2.h index 01a17443..e9afc085 100644 --- a/include/gmssl/pbkdf2.h +++ b/include/gmssl/pbkdf2.h @@ -66,9 +66,8 @@ extern "C" { int pbkdf2_genkey(const DIGEST *digest, - const char *pass, size_t passlen, - const uint8_t *salt, size_t saltlen, - size_t count, size_t outlen, uint8_t *out); + const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen, size_t count, + size_t outlen, uint8_t *out); #ifdef __cplusplus diff --git a/include/gmssl/pem.h b/include/gmssl/pem.h index 940f0f32..8bae71ff 100644 --- a/include/gmssl/pem.h +++ b/include/gmssl/pem.h @@ -61,9 +61,8 @@ extern "C" { #endif -int pem_read(FILE *fp, const char *name, uint8_t *data, size_t *datalen); -int pem_write(FILE *fp, const char *name, const uint8_t *data, size_t datalen); - +int pem_read(FILE *fp, const char *name, uint8_t *out, size_t *outlen, size_t maxlen); +int pem_write(FILE *fp, const char *name, const uint8_t *in, size_t inlen); #ifdef __cplusplus diff --git a/include/gmssl/pkcs8.h b/include/gmssl/pkcs8.h index 07b56a91..167bae3b 100644 --- a/include/gmssl/pkcs8.h +++ b/include/gmssl/pkcs8.h @@ -45,6 +45,8 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ +// RFC 5208: PKCS #8: Private-Key Information Syntax Specification version 1.2 + #ifndef GMSSL_PKCS8_H #define GMSSL_PKCS8_H @@ -62,8 +64,10 @@ extern "C" { // 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_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); @@ -71,19 +75,9 @@ 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 */ - -int pbkdf2_params_to_der( - const uint8_t *salt, size_t saltlen, - int iter, - int keylen, // optional, -1 - int prf, +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, // -1, optional - int *prf, +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_algor_to_der( @@ -92,7 +86,6 @@ int pbkdf2_algor_to_der( int keylen, int prf, uint8_t **out, size_t *outlen); - int pbkdf2_algor_from_der( const uint8_t **salt, size_t *saltlen, int *iter, @@ -104,7 +97,6 @@ int pbes2_enc_algor_to_der( int cipher, const uint8_t *iv, size_t ivlen, uint8_t **out, size_t *outlen); - int pbes2_enc_algor_from_der( int *cipher, const uint8_t **iv, size_t *ivlen, @@ -117,7 +109,6 @@ int pbes2_params_to_der( int cipher, const uint8_t *iv, size_t ivlen, uint8_t **out, size_t *outlen); - int pbes2_params_from_der( const uint8_t **salt, size_t *saltlen, int *iter, @@ -133,7 +124,6 @@ int pbes2_algor_to_der( int cipher, const uint8_t *iv, size_t ivlen, uint8_t **out, size_t *outlen); - int pbes2_algor_from_der( const uint8_t **salt, size_t *saltlen, int *iter, @@ -150,7 +140,6 @@ int pkcs8_enced_private_key_info_to_der( const uint8_t *iv, size_t ivlen, const uint8_t *enced, size_t encedlen, uint8_t **out, size_t *outlen); - int pkcs8_enced_private_key_info_from_der( const uint8_t **salt, size_t *saltlen, int *iter, diff --git a/include/gmssl/rand.h b/include/gmssl/rand.h index 8a27f3dd..5ef9c79a 100644 --- a/include/gmssl/rand.h +++ b/include/gmssl/rand.h @@ -49,12 +49,15 @@ #ifndef GMSSL_RAND_H #define GMSSL_RAND_H - #include #include -int rand_bytes(uint8_t *buf, size_t len); +#ifdef __cplusplus +extern "C" { +#endif + +int rand_bytes(uint8_t *buf, size_t buflen); #ifdef __cplusplus diff --git a/include/gmssl/rc4.h b/include/gmssl/rc4.h index 5bffb479..295e59b2 100644 --- a/include/gmssl/rc4.h +++ b/include/gmssl/rc4.h @@ -65,10 +65,10 @@ extern "C" { typedef struct { - unsigned char d[256]; + uint8_t d[RC4_STATE_NUM_WORDS]; } RC4_STATE; -void rc4_set_key(RC4_STATE *state, const uint8_t *key, size_t keylen); +void rc4_init(RC4_STATE *state, const uint8_t *key, size_t keylen); void rc4_generate_keystream(RC4_STATE *state, size_t outlen, uint8_t *out); diff --git a/include/gmssl/sha1.h b/include/gmssl/sha1.h index 9dab2470..5e7e3c30 100644 --- a/include/gmssl/sha1.h +++ b/include/gmssl/sha1.h @@ -51,7 +51,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { @@ -67,9 +66,9 @@ extern "C" { typedef struct { uint32_t state[SHA1_STATE_WORDS]; - uint64_t nblocks; /* num of processed blocks */ - uint8_t block[SHA1_BLOCK_SIZE]; /* buffer */ - size_t num; /* buffered bytes in |block| */ + uint64_t nblocks; + uint8_t block[SHA1_BLOCK_SIZE]; + size_t num; } SHA1_CTX; void sha1_init(SHA1_CTX *ctx); diff --git a/include/gmssl/sha2.h b/include/gmssl/sha2.h index eb2ecfb3..1a81fd05 100644 --- a/include/gmssl/sha2.h +++ b/include/gmssl/sha2.h @@ -69,15 +69,15 @@ extern "C" { typedef struct { uint32_t state[SHA224_STATE_WORDS]; uint64_t nblocks; - unsigned char block[SHA224_BLOCK_SIZE]; + uint8_t block[SHA224_BLOCK_SIZE]; int num; } SHA224_CTX; void sha224_init(SHA224_CTX *ctx); -void sha224_update(SHA224_CTX *ctx, const unsigned char* data, size_t datalen); -void sha224_finish(SHA224_CTX *ctx, unsigned char dgst[SHA224_DIGEST_SIZE]); -void sha224_digest(const unsigned char *data, size_t datalen, - unsigned char dgst[SHA224_DIGEST_SIZE]); +void sha224_update(SHA224_CTX *ctx, const uint8_t* data, size_t datalen); +void sha224_finish(SHA224_CTX *ctx, uint8_t dgst[SHA224_DIGEST_SIZE]); +void sha224_digest(const uint8_t *data, size_t datalen, + uint8_t dgst[SHA224_DIGEST_SIZE]); #define SHA256_DIGEST_SIZE 32 @@ -85,17 +85,17 @@ void sha224_digest(const unsigned char *data, size_t datalen, #define SHA256_STATE_WORDS 8 typedef struct { - uint32_t state[8]; + uint32_t state[SHA256_STATE_WORDS]; uint64_t nblocks; - unsigned char block[64]; + uint8_t block[SHA256_BLOCK_SIZE]; int num; } SHA256_CTX; void sha256_init(SHA256_CTX *ctx); -void sha256_update(SHA256_CTX *ctx, const unsigned char* data, size_t datalen); -void sha256_finish(SHA256_CTX *ctx, unsigned char dgst[SHA256_DIGEST_SIZE]); -void sha256_digest(const unsigned char *data, size_t datalen, - unsigned char dgst[SHA256_DIGEST_SIZE]); +void sha256_update(SHA256_CTX *ctx, const uint8_t* data, size_t datalen); +void sha256_finish(SHA256_CTX *ctx, uint8_t dgst[SHA256_DIGEST_SIZE]); +void sha256_digest(const uint8_t *data, size_t datalen, + uint8_t dgst[SHA256_DIGEST_SIZE]); #define SHA384_DIGEST_SIZE 48 @@ -103,17 +103,17 @@ void sha256_digest(const unsigned char *data, size_t datalen, #define SHA384_STATE_WORDS 8 typedef struct { - uint64_t state[8]; + uint64_t state[SHA384_STATE_WORDS]; uint64_t nblocks; - unsigned char block[128]; + uint8_t block[SHA384_BLOCK_SIZE]; int num; } SHA384_CTX; void sha384_init(SHA384_CTX *ctx); -void sha384_update(SHA384_CTX *ctx, const unsigned char* data, size_t datalen); -void sha384_finish(SHA384_CTX *ctx, unsigned char dgst[SHA384_DIGEST_SIZE]); -void sha384_digest(const unsigned char *data, size_t datalen, - unsigned char dgst[SHA384_DIGEST_SIZE]); +void sha384_update(SHA384_CTX *ctx, const uint8_t* data, size_t datalen); +void sha384_finish(SHA384_CTX *ctx, uint8_t dgst[SHA384_DIGEST_SIZE]); +void sha384_digest(const uint8_t *data, size_t datalen, + uint8_t dgst[SHA384_DIGEST_SIZE]); #define SHA512_DIGEST_SIZE 64 @@ -121,17 +121,17 @@ void sha384_digest(const unsigned char *data, size_t datalen, #define SHA512_STATE_WORDS 8 typedef struct { - uint64_t state[8]; + uint64_t state[SHA512_STATE_WORDS]; uint64_t nblocks; - unsigned char block[128]; + uint8_t block[SHA512_BLOCK_SIZE]; int num; } SHA512_CTX; void sha512_init(SHA512_CTX *ctx); -void sha512_update(SHA512_CTX *ctx, const unsigned char* data, size_t datalen); -void sha512_finish(SHA512_CTX *ctx, unsigned char dgst[SHA512_DIGEST_SIZE]); -void sha512_digest(const unsigned char *data, size_t datalen, - unsigned char dgst[SHA512_DIGEST_SIZE]); +void sha512_update(SHA512_CTX *ctx, const uint8_t* data, size_t datalen); +void sha512_finish(SHA512_CTX *ctx, uint8_t dgst[SHA512_DIGEST_SIZE]); +void sha512_digest(const uint8_t *data, size_t datalen, + uint8_t dgst[SHA512_DIGEST_SIZE]); #ifdef __cplusplus diff --git a/include/gmssl/sm2.h b/include/gmssl/sm2.h index 8d6bf1fd..e00b3447 100644 --- a/include/gmssl/sm2.h +++ b/include/gmssl/sm2.h @@ -60,7 +60,6 @@ extern "C" { #endif - typedef struct { uint8_t x[32]; uint8_t y[32]; @@ -69,18 +68,15 @@ typedef struct { void sm2_point_to_compressed_octets(const SM2_POINT *P, uint8_t out[33]); void sm2_point_to_uncompressed_octets(const SM2_POINT *P, uint8_t out[65]); int sm2_point_from_octets(SM2_POINT *P, const uint8_t *in, size_t inlen); -int sm2_point_to_der(const SM2_POINT *a, uint8_t **out, size_t *outlen); -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 sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen); int sm2_point_from_x(SM2_POINT *P, const uint8_t x[32], int y); int sm2_point_from_xy(SM2_POINT *P, const uint8_t x[32], const uint8_t y[32]); int sm2_point_is_on_curve(const SM2_POINT *P); int sm2_point_mul(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P); int sm2_point_mul_generator(SM2_POINT *R, const uint8_t k[32]); -int sm2_point_mul_sum(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P, const uint8_t s[32]); -int sm2_point_print(FILE *fp, const SM2_POINT *P, int format, int indent); - -int sm2_compute_z(uint8_t z[32], const SM2_POINT *pub, const char *id); - +int sm2_point_mul_sum(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P, const uint8_t s[32]); // R = k * P + s * G +int sm2_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_POINT *P); typedef struct { SM2_POINT public_key; @@ -88,30 +84,63 @@ typedef struct { uint8_t key_usage[4]; } SM2_KEY; -int sm2_keygen(SM2_KEY *key); -int sm2_set_private_key(SM2_KEY *key, const uint8_t private_key[32]); -int sm2_set_public_key(SM2_KEY *key, const uint8_t public_key[64]); // FIXME: 这里是否应该用octets呢?这算是椭圆曲线点的一个公开格式了 -int sm2_key_print(FILE *fp, const SM2_KEY *key, int format, int indent); +int sm2_key_generate(SM2_KEY *key); +int sm2_key_set_private_key(SM2_KEY *key, const uint8_t private_key[32]); +int sm2_key_set_public_key(SM2_KEY *key, const SM2_POINT *public_key); +int sm2_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *key); + +int sm2_public_key_copy(SM2_KEY *sm2_key, const SM2_KEY *pub_key); int sm2_public_key_digest(const SM2_KEY *key, uint8_t dgst[32]); -// ECPrivateKey +/* +from RFC 5915 + +ECPrivateKey ::= SEQUENCE { + version INTEGER, -- value MUST be (1) + privateKey OCTET STRING, -- big endian encoding of integer + parameters [0] EXPLICIT ECParameters OPTIONAL, + -- ONLY namedCurve OID is permitted, by RFC 5480 + -- MUST always include this field, by RFC 5915 + publicKey [1] EXPLICIT BIT STRING OPTIONAL + -- SHOULD always include this field, by RFC 5915 } + +ECParameters ::= CHOICE { namedCurve OBJECT IDENTIFIER } +*/ int sm2_private_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen); -int sm2_private_key_to_pem(const SM2_KEY *key, FILE *fp); int sm2_private_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen); +int sm2_private_key_to_pem(const SM2_KEY *key, FILE *fp); int sm2_private_key_from_pem(SM2_KEY *key, FILE *fp); - -// AlgorithmIdentifier +/* +AlgorithmIdentifier ::= { + algorithm OBJECT IDENTIFIER { id-ecPublicKey }, + parameters OBJECT IDENTIFIER { id-sm2 } } +*/ 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 + +/* +X.509 SubjectPublicKeyInfo from RFC 5280 + +SubjectPublicKeyInfo ::= SEQUENCE { + algorithm AlgorithmIdentifier, + subjectPublicKey BIT STRING -- uncompressed octets of ECPoint } +*/ int sm2_public_key_info_to_der(const SM2_KEY *a, uint8_t **out, size_t *outlen); -int sm2_public_key_info_to_pem(const SM2_KEY *a, FILE *fp); int sm2_public_key_info_from_der(SM2_KEY *a, const uint8_t **in, size_t *inlen); +int sm2_public_key_info_to_pem(const SM2_KEY *a, FILE *fp); int sm2_public_key_info_from_pem(SM2_KEY *a, FILE *fp); -// PKCS #8 PrivateKeyInfo +/* +PKCS #8 PrivateKeyInfo from RFC 5208 + +PrivateKeyInfo ::= SEQUENCE { + version Version { v1(0) }, + privateKeyAlgorithm AlgorithmIdentifier, + privateKey OCTET STRING, -- DER-encoding of ECPrivateKey + attributes [0] IMPLICIT SET OF Attribute OPTIONAL } +*/ int sm2_private_key_info_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen); int sm2_private_key_info_from_der(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, const uint8_t **in, size_t *inlen); int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp); @@ -125,25 +154,27 @@ typedef struct { int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen); int sm2_signature_from_der(SM2_SIGNATURE *sig, const uint8_t **in, size_t *inlen); +int sm2_signature_print(FILE *fp, int fmt, int ind, const SM2_SIGNATURE *sig); int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig); int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig); -int sm2_print_signature(FILE *fp, const uint8_t *sig, size_t siglen, int format, int indent); #define SM2_MAX_SIGNATURE_SIZE 72 int sm2_sign(const SM2_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen); int sm2_verify(const SM2_KEY *key, const uint8_t dgst[32], const uint8_t *sig, size_t siglen); -#define SM2_MAX_ID_BITS 65535 -#define SM2_MAX_ID_LENGTH (SM2_MAX_ID_BITS/8) -#define SM2_MAX_ID_SIZE (SM2_MAX_ID_BITS/8) -#define SM2_DEFAULT_ID_GMT09 "1234567812345678" -#define SM2_DEFAULT_ID_GMSSL "anonym@gmssl.org" -#define SM2_DEFAULT_ID SM2_DEFAULT_ID_GMT09 + +#define SM2_DEFAULT_ID "1234567812345678" #define SM2_DEFAULT_ID_LENGTH (sizeof(SM2_DEFAULT_ID) - 1) #define SM2_DEFAULT_ID_BITS (SM2_DEFAULT_ID_LENGTH * 8) #define SM2_DEFAULT_ID_DIGEST_LENGTH SM3_DIGEST_LENGTH +#define SM2_MAX_ID_BITS 65535 +#define SM2_MAX_ID_LENGTH (SM2_MAX_ID_BITS/8) +#define SM2_MAX_ID_SIZE (SM2_MAX_ID_BITS/8) + +int sm2_compute_z(uint8_t z[32], const SM2_POINT *pub, const char *id, size_t idlen); + typedef struct { SM2_KEY key; @@ -151,14 +182,21 @@ typedef struct { int flags; } SM2_SIGN_CTX; -int sm2_sign_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id); +int sm2_sign_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen); int sm2_sign_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); int sm2_sign_finish(SM2_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen); -int sm2_verify_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id); + +int sm2_verify_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen); int sm2_verify_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); int sm2_verify_finish(SM2_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen); - +/* +SM2Cipher ::= SEQUENCE { + XCoordinate INTEGER, + YCoordinate INTEGER, + HASH OCTET STRING SIZE(32), + CipherText OCTET STRING } +*/ typedef struct { SM2_POINT point; uint8_t hash[32]; @@ -166,18 +204,13 @@ typedef struct { uint8_t ciphertext[1]; } SM2_CIPHERTEXT; -#define SM2_MAX_PLAINTEXT 256 #define SM2_MAX_PLAINTEXT_SIZE 256 - -#define SM2_CIPHERTEXT_SIZE(inlen) (sizeof(SM2_CIPHERTEXT)-1+inlen) - #define SM2_MAX_CIPHERTEXT_SIZE 512 - - +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); int sm2_ciphertext_from_der(SM2_CIPHERTEXT *c, const uint8_t **in, size_t *inlen); -int sm2_ciphertext_print(FILE *fp, const SM2_CIPHERTEXT *c, int format, int indent); +int sm2_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const SM2_CIPHERTEXT *c); int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out); int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, size_t *outlen); @@ -188,9 +221,6 @@ int sm2_print_ciphertext(FILE *fp, const uint8_t *c, size_t clen, int format, in int sm2_ecdh(const SM2_KEY *key, const SM2_POINT *peer_public, SM2_POINT *out); -int sm2_algo_selftest(void); - - #ifdef __cplusplus extern "C" { #endif diff --git a/include/gmssl/sm4.h b/include/gmssl/sm4.h index 160f7394..c750d080 100644 --- a/include/gmssl/sm4.h +++ b/include/gmssl/sm4.h @@ -49,12 +49,9 @@ #ifndef GMSSL_SM4_H #define GMSSL_SM4_H - -#include #include #include - #ifdef __cplusplus extern "C" { #endif @@ -64,38 +61,45 @@ extern "C" { #define SM4_BLOCK_SIZE (16) #define SM4_NUM_ROUNDS (32) -// TODO: 增加一个flag标注用于加密还是解密,使用时用assert检查这个flag + typedef struct { uint32_t rk[SM4_NUM_ROUNDS]; } SM4_KEY; - -void sm4_set_encrypt_key(SM4_KEY *sm4_key, const uint8_t key[16]); -void sm4_set_decrypt_key(SM4_KEY *sm4_key, const uint8_t key[16]); -void sm4_encrypt(const SM4_KEY *sm4_key, const uint8_t in[16], uint8_t out[16]); +void sm4_set_encrypt_key(SM4_KEY *key, const uint8_t raw_key[SM4_KEY_SIZE]); +void sm4_set_decrypt_key(SM4_KEY *key, const uint8_t raw_key[SM4_KEY_SIZE]); +void sm4_encrypt(const SM4_KEY *key, const uint8_t in[SM4_BLOCK_SIZE], uint8_t out[SM4_BLOCK_SIZE]); +#define sm4_decrypt(key,in,out) sm4_encrypt(key,in,out) -void sm4_cbc_encrypt(const SM4_KEY *key, const uint8_t iv[16], +void sm4_cbc_encrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], const uint8_t *in, size_t nblocks, uint8_t *out); - -void sm4_cbc_decrypt(const SM4_KEY *key, const uint8_t iv[16], +void sm4_cbc_decrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], const uint8_t *in, size_t nblocks, uint8_t *out); +int sm4_cbc_padding_encrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); +int sm4_cbc_padding_decrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int sm4_cbc_padding_encrypt(const SM4_KEY *key, const uint8_t iv[16], - const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen); - -int sm4_cbc_padding_decrypt(const SM4_KEY *key, const uint8_t iv[16], - const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen); - -void sm4_ctr_encrypt(const SM4_KEY *key, uint8_t ctr[16], +void sm4_ctr_encrypt(const SM4_KEY *key, uint8_t ctr[SM4_BLOCK_SIZE], const uint8_t *in, size_t inlen, uint8_t *out); +#define sm4_ctr_decrypt(key,ctr,in,inlen,out) sm4_ctr_encrypt(key,ctr,in,inlen,out) + + +#define SM4_GCM_IV_MIN_SIZE 1 +#define SM4_GCM_IV_MAX_SIZE ((uint64_t)(1 << (64-3))) +#define SM4_GCM_IV_DEFAULT_BITS 96 +#define SM4_GCM_IV_DEFAULT_SIZE 12 + +#define SM4_GCM_MIN_AAD_SIZE 0 +#define SM4_GCM_MAX_AAD_SIZE ((uint64_t)(1 << (64-3))) + +#define SM4_GCM_MIN_PLAINTEXT_SIZE 0 +#define SM4_GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3) int sm4_gcm_encrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen, const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, - uint8_t *out, const size_t taglen, uint8_t *tag); - + uint8_t *out, size_t taglen, uint8_t *tag); int sm4_gcm_decrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen, const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, const uint8_t *tag, size_t taglen, uint8_t *out); diff --git a/include/gmssl/version.h b/include/gmssl/version.h index 34c04d71..9595b977 100644 --- a/include/gmssl/version.h +++ b/include/gmssl/version.h @@ -50,17 +50,15 @@ #ifndef GMSSL_VERSION_H #define GMSSL_VERSION_H - - - #ifdef __cplusplus extern "C" { #endif +#define GMSSL_VERSION_NUM 30000 +#define GMSSL_VERSION_STR "GmSSL 3.0.0 Alpha" -const char *gmssl_version(void); - - +int gmssl_version_num(void); +const char *gmssl_version_str(void); #ifdef __cplusplus } diff --git a/include/gmssl/x509.h b/include/gmssl/x509.h index ebabe181..ecaa1e98 100644 --- a/include/gmssl/x509.h +++ b/include/gmssl/x509.h @@ -63,994 +63,57 @@ extern "C" { #endif -/* - ASN.1 API 规则 - - * SEQUENCE OF/SET OF 类型是存储类型 - * 如果一个CHOICE类型可选项中有存储类型,那么这个CHOICE也设置为存储类型 - -*/ - - enum X509_Version { X509_version_v1 = 0, X509_version_v2 = 1, X509_version_v3 = 2, }; +const char *x509_version_name(int version); +int x509_explicit_version_to_der(int index, int version); +int x509_explicit_version_from_der(int index, int *version); + +/* +Time ::= CHOICE { + utcTime UTCTime, + generalTime GeneralizedTime } +*/ int x509_time_to_der(time_t a, uint8_t **out, size_t *outlen); int x509_time_from_der(time_t *a, const uint8_t **in, size_t *inlen); -typedef struct { - time_t not_before; - time_t not_after; -} X509_VALIDITY; - -int x509_validity_set_days(X509_VALIDITY *a, time_t not_before, int days); -int x509_validity_to_der(const X509_VALIDITY *a, uint8_t **out, size_t *outlen); -int x509_validity_from_der(X509_VALIDITY *a, const uint8_t **in, size_t *inlen); -int x509_validity_print(FILE *fp, const X509_VALIDITY *validity, int format, int indent); - /* -DirectoryString ::= CHOICE { - teletexString TeletexString (SIZE (1..MAX)), - printableString PrintableString (SIZE (1..MAX)), - universalString UniversalString (SIZE (1..MAX)), - utf8String UTF8String (SIZE (1..MAX)), - bmpString BMPString (SIZE (1..MAX)), -} -DirectoryString 实际上就是一个 Universal 类型,因此提供和 asn1.h 中基本类型一致的接口 +Validity ::= SEQUENCE { + notBefore Time, + notAfter Time } */ -int x509_directory_string_to_der(int tag, const char *a, size_t alen, uint8_t **out, size_t *outlen); -int x509_directory_string_from_der(int *tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen); - +int x509_validity_add_days(time_t *not_after, time_t not_before, int days); +int x509_validity_to_der(time_t not_before, time_t not_after, uint8_t **out, size_t *outlen); +int x509_validity_from_der(time_t *not_before, time_t *not_after, const uint8_t **in, size_t *inlen); +int x509_validity_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); /* -Name ::= SEQUENCE OF RelativeDistinguishedName - -RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue - -- 我们只支持 SIZE == 1 的情况 - AttributeTypeAndValue ::= SEQUENCE { type OBJECT IDENTIFIER, - value ANY -- DEFINED BY AttributeType - -- mostly DirectoryString or PrintableString -} - - type == domainComponent 可能出现多次,因此目前X509_NAME并不支持这种情况 - 这个在实际中出现的多吗? + value ANY -- DEFINED BY AttributeType } +id-at + name DirectoryName 1..ub-name + surname DirectoryName 1..ub-name + givenName DirectoryName 1..ub-name + initials DirectoryName 1..ub-name + generationQualifier DirectoryName 1..ub-name + commonName DirectoryName 1..ub-common-name + localityName DirectoryName 1..ub-locality-name + stateOrProvinceName DirectoryName 1..ub-state-name + organizationName DirectoryName 1..ub-organization-name + organizationalUnitName DirectoryName 1..ub-organizational-unit-name + title DirectoryName 1..ub-title + dnQualifier PrintableString N/A + countryName PrintableString 2..2 + serialNumber PrintableString 1..ub-serial-number + pseudonym DirectoryName 1..ub-pseudonym + domainComponent IA5String N/A */ - -typedef struct { - size_t datalen; - uint8_t data[256]; -} X509_RDN; - -int x509_rdn_to_der(int oid, int tag, const char *str, uint8_t **out, size_t *outlen); -int x509_rdn_from_der(int *oid, int *tag, const char **str, size_t *slen, const uint8_t **in, size_t *inlen); - -typedef struct { - int count; - int oids[8]; - int tags[8]; - - char country[3]; // printableString - char state_or_province[129]; - char locality[129]; - char org[65]; - char org_unit[65]; - char common_name[65]; - char serial_number[65]; // printableString - char dn_qualifier[65]; // printableString -} X509_NAME; - -int x509_name_add_rdn_ex(X509_NAME *a, int oid, int tag, const char *str, size_t len); -int x509_name_equ(const X509_NAME *a, const X509_NAME *b); -int x509_name_from_der(X509_NAME *a, const uint8_t **in, size_t *inlen); -int x509_name_to_der(const X509_NAME *a, uint8_t **out, size_t *outlen); -int x509_name_print(FILE *fp, const X509_NAME *a, int format, int indent); - - -#define x509_name_add_rdn(a,oid,tag,s) x509_name_add_rdn_ex((a),(oid),(tag),(s),strlen(s)) -#define x509_name_set_country(a,s) x509_name_add_rdn((a),OID_at_countryName,ASN1_TAG_PrintableString,(s)) -#define x509_name_set_state_or_province(a,s) x509_name_add_rdn((a),OID_at_stateOrProvinceName,ASN1_TAG_PrintableString,(s)) -#define x509_name_set_organization(a,s) x509_name_add_rdn((a),OID_at_organizationName,ASN1_TAG_PrintableString,(s)) -#define x509_name_set_organizational_unit(a,s) x509_name_add_rdn((a),OID_at_organizationalUnitName,ASN1_TAG_PrintableString,(s)) -#define x509_name_set_common_name(a,s) x509_name_add_rdn((a),OID_at_commonName,ASN1_TAG_PrintableString,(s)) - -/* -AlgorithmIdentifier ::= SEQUENCE { - algorithm OBJECT IDENTIFIER, - parameters ANY DEFINED BY algorithm OPTIONAL } - - SignatureAlgorithm 是特殊的 AlgorithmIdentifier - 当 algorithm 为 ECDSA/SM2 时,parameters 为空 - 当 algorithm 为 RSA 时,parameters 为 ASN1_NULL 对象 -*/ - -const char *x509_digest_algor_name(int algor); -int x509_digest_algor_from_name(const char *name); -int x509_digest_algor_to_der(int algor, uint8_t **out, size_t *outlen); -int x509_digest_algor_from_der(int *algor, uint32_t *nodes, size_t *nodes_count, - const uint8_t **in, size_t *inlen); - -const char *x509_encryption_algor_name(int algor); -int x509_encryption_algor_from_name(const char *name); -int x509_encryption_algor_to_der(int algor, const uint8_t *iv, size_t ivlen, - uint8_t **out, size_t *outlen); -int x509_encryption_algor_from_der(int *algor, uint32_t *nodes, size_t *nodes_count, - const uint8_t **iv, size_t *ivlen, - const uint8_t **in, size_t *inlen); - -const char *x509_signature_algor_name(int algor); -int x509_signature_algor_from_name(const char *name); -int x509_signature_algor_to_der(int algor, uint8_t **out, size_t *outlen); -int x509_signature_algor_from_der(int *algor, uint32_t *nodes, size_t *nodes_count, - const uint8_t **in, size_t *inlen); - -const char *x509_public_key_encryption_algor_name(int algor); -int x509_public_key_encryption_algor_from_name(const char *name); -int x509_public_key_encryption_algor_to_der(int algor, uint8_t **out, size_t *outlen); -int x509_public_key_encryption_algor_from_der(int *algor, uint32_t *nodes, size_t *nodes_count, - const uint8_t **params, size_t *params_len, - const uint8_t **in, size_t *inlen); - - - -/* -SubjectPublicKeyInfo ::= SEQUENCE { - algorithm AlgorithmIdentifier, - subjectPublicKey BIT STRING } - - algorithm.algorithm = OID_x9_62_ecPublicKey; - algorithm.parameters = OID_sm2p256v1; - subjectPublicKey = ECPoint -*/ -typedef struct { - int algor_oid; - int curve_oid; - SM2_KEY sm2_key; -} X509_PUBLIC_KEY_INFO; - -int x509_public_key_info_set_sm2(X509_PUBLIC_KEY_INFO *a, const SM2_KEY *sm2_key); -#define x509_public_key_info_set(a,pk) x509_public_key_info_set_sm2((a),(pk)) -int x509_public_key_info_to_der(const X509_PUBLIC_KEY_INFO *a, uint8_t **out, size_t *outlen); -int x509_public_key_info_from_der(X509_PUBLIC_KEY_INFO *a, const uint8_t **in, size_t *inlen); -int x509_public_key_info_print(FILE *fp, const X509_PUBLIC_KEY_INFO *a, int format, int indent); - -/* -Extension ::= SEQUENCE { - extnID OBJECT IDENTIFIER, - critical BOOLEAN DEFAULT FALSE, - extnValue OCTET STRING -- contains the DER encoding of an ASN.1 value -*/ -const char *x509_extension_oid_name(int oid); -int x509_extension_oid_to_der(int oid, uint8_t **out, size_t *outlen); -int x509_extension_oid_from_der(int *oid, uint32_t *nodes, size_t *nodes_count, const uint8_t **in, size_t *inlen); - -int x509_extension_to_der(int oid, - int is_critical, const uint8_t *data, size_t datalen, - uint8_t **out, size_t *outlen); -int x509_extension_from_der(int *oid, uint32_t *nodes, size_t *nodes_count, - int *is_critical, const uint8_t **data, size_t *datalen, - const uint8_t **in, size_t *inlen); -int x509_extension_print(FILE *fp, int oid, const uint32_t *nodes, size_t nodes_count, - int is_critical, const uint8_t *data, size_t datalen, - int format, int indent); - -typedef struct { - size_t datalen; - uint8_t data[2048]; -} X509_EXTENSIONS; - -int x509_extensions_add_item(X509_EXTENSIONS *a, - int oid, int is_critical, const uint8_t *data, size_t datalen); -int x509_extensions_get_next_item(const X509_EXTENSIONS *a, const uint8_t **next, - int *oid, uint32_t *nodes, size_t *nodes_count, - int *is_critical, const uint8_t **data, size_t *datalen); -int x509_extensions_print(FILE *fp, const X509_EXTENSIONS *a, int format, int indent); - - - - - - -typedef struct { - int version; // [0] EXPLICIT INTEGER DEFAULT v1 - uint8_t serial_number[20]; // INTEGER - size_t serial_number_len; - int signature_algor; // AlgorithmIdentifier - X509_NAME issuer; - X509_VALIDITY validity; - X509_NAME subject; - X509_PUBLIC_KEY_INFO subject_public_key_info; - uint8_t issuer_unique_id[64]; // [1] IMPLICIT BIT STRING OPTIONAL - size_t issuer_unique_id_len; - uint8_t subject_unique_id[64]; // [2] IMPLICIT BIT STRING OPTIONAL - size_t subject_unique_id_len; - X509_EXTENSIONS extensions; // [3] EXPLICIT, If present, version MUST be v3 -} X509_TBS_CERTIFICATE; - -int x509_tbs_certificate_to_der(const X509_TBS_CERTIFICATE *a, uint8_t **out, size_t *outlen); -int x509_tbs_certificate_from_der(X509_TBS_CERTIFICATE *a, const uint8_t **in, size_t *inlen); - - - -/* -Certificate ::= SEQUENCE { - tbsCertificate TBSCertificate, - signatureAlgorithm AlgorithmIdentifier, - signatureValue BIT STRING } -*/ -typedef struct { - X509_TBS_CERTIFICATE tbs_certificate; - int signature_algor; - uint8_t signature[256]; - size_t signature_len; -} X509_CERTIFICATE; - - -int x509_certificate_set_version(X509_CERTIFICATE *cert, int version); -int x509_certificate_set_serial_number(X509_CERTIFICATE *cert, const uint8_t *sn, size_t snlen); -int x509_certificate_set_signature_algor(X509_CERTIFICATE *cert, int oid); // 这个应该直接指定SM2吗? -int x509_certificate_set_issuer(X509_CERTIFICATE *cert, const X509_NAME *name); -int x509_certificate_set_subject(X509_CERTIFICATE *cert, const X509_NAME *name); -int x509_certificate_set_validity(X509_CERTIFICATE *cert, time_t not_before, int days); -int x509_certificate_set_subject_public_key_info_sm2(X509_CERTIFICATE *cert, const SM2_KEY *sm2_key); -int x509_certificate_set_issuer_unique_id(X509_CERTIFICATE *cert, const uint8_t *id, size_t idlen); -int x509_certificate_set_subject_unique_id(X509_CERTIFICATE *cert, const uint8_t *id, size_t idlen); -int x509_certificate_set_issuer_unique_id_from_public_key_sm2(X509_CERTIFICATE *cert, const SM2_KEY *sm2_key); -int x509_certificate_set_subject_unique_id_from_public_key_sm2(X509_CERTIFICATE *cert, const SM2_KEY *sm2_key); -#define x509_certificate_set_subject_public_key_info(c,pk) x509_certificate_set_subject_public_key_info_sm2((c),(pk)) -#define x509_certificate_set_issuer_unique_id_from_public_key(c,pk) x509_certificate_set_issuer_unique_id_from_public_key_sm2((c),(pk)) -#define x509_certificate_set_subject_unique_id_from_public_key(c,pk) x509_certificate_set_subject_unique_id_from_public_key_sm2((c),(pk)) - - -int x509_certificate_add_extension(X509_CERTIFICATE *a, int oid, int is_critical, - const uint8_t *data, size_t datalen); -int x509_certificate_get_extension_from_oid(const X509_CERTIFICATE *a, int oid, - int *is_critical, const uint8_t **data, size_t *datalen); - -int x509_certificate_sign_sm2(X509_CERTIFICATE *cert, const SM2_KEY *key); -int x509_certificate_verify_sm2(const X509_CERTIFICATE *cert, const SM2_KEY *sm2_key); -int x509_certificate_get_public_key_sm2(const X509_CERTIFICATE *cert, SM2_KEY *sm2_key); -#define x509_certificate_sign(c,sk) x509_certificate_sign_sm2((c),(sk)) -#define x509_certificate_verify(c,pk) x509_certificate_verify_sm2((c),(pk)) -#define x509_certificate_get_public_key(c,pk) x509_certificate_get_public_key_sm2((c),(pk)) - -int x509_certificate_to_der(const X509_CERTIFICATE *a, uint8_t **out, size_t *outlen); -int x509_certificate_to_pem(const X509_CERTIFICATE *a, FILE *fp); -int x509_certificate_from_der(X509_CERTIFICATE *a, const uint8_t **in, size_t *inlen); -int x509_certificate_from_pem(X509_CERTIFICATE *a, FILE *fp); -int x509_certificate_print(FILE *fp, const X509_CERTIFICATE *a, int format, int indent); - -int x509_certificate_from_pem_by_name(X509_CERTIFICATE *cert, FILE *certs_fp, const X509_NAME *issuer); - -int x509_certificate_verify_by_certificate(const X509_CERTIFICATE *cert, const X509_CERTIFICATE *cacert); - - - - - - - -// Extension 1 AuthorityKeyIdentifier - -/* -OtherName ::= SEQUENCE { - type-id OBJECT IDENTIFIER, - value [0] EXPLICIT ANY DEFINED BY type-id } -*/ -int x509_other_name_to_der_ex(int tag, - int oid, const uint32_t *nodes, size_t nodes_count, - const uint8_t *value, size_t valuelen, - uint8_t **out, size_t *outlen); - -int x509_other_name_from_der_ex(int tag, - int *oid, uint32_t *nodes, size_t *nodes_count, - const uint8_t **value, size_t *valuelen, - const uint8_t **in, size_t *inlen); - -/* -EDIPartyName ::= SEQUENCE { - nameAssigner [0] DirectoryString OPTIONAL, - partyName [1] DirectoryString } -*/ -int x509_edi_party_name_to_der_ex( - int tag, - int assigner_tag, const char *assigner, size_t assigner_len, - int party_name_tag, const char *party_name, size_t party_name_len, - uint8_t **out, size_t *outlen); - -int x509_edi_party_name_from_der_ex( - int tag, - int *assigner_tag, const char **assigner, size_t *assigner_len, - int *party_name_tag, const char **party_name, size_t *party_name_len, - const uint8_t **in, size_t *inlen); - -/* -GeneralName ::= CHOICE { - otherName [0] OtherName, - rfc822Name [1] IA5String, - dNSName [2] IA5String, - x400Address [3] ORAddress, - directoryName [4] Name, - ediPartyName [5] EDIPartyName, - uniformResourceIdentifier [6] IA5String, - iPAddress [7] OCTET STRING, - registeredID [8] OBJECT IDENTIFIER - } -*/ -enum { - X509_gn_otherName = 0, - X509_gn_rfc822Name, - X509_gn_dnsName, - X509_gn_x400Address, - X509_gn_directoryName, - X509_gn_ediPartyName, - X509_gn_uniformResourceIdentifier, - X509_gn_ipAddress, - X509_gn_registeredID, -}; - -int x509_general_name_to_der(int choice, const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen); -int x509_general_name_from_der(int *choice, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen); - - -typedef struct { - size_t datalen; - uint8_t data[256]; -} X509_GENERAL_NAMES; - -int x509_general_names_add_item(X509_GENERAL_NAMES *a, int choice, const uint8_t *data, size_t datalen); -int x509_general_names_get_next_item(const X509_GENERAL_NAMES *a, const uint8_t **next, - int *choice, const uint8_t **data, size_t *datalen); - -#define x509_general_names_to_der(a,d,dl) \ - asn1_sequence_to_der((a)->data,(a)->datalen,d,dl) - -#define x509_general_names_from_der(a,d,dl) \ - asn1_sequence_copy_from_der((a)->data,&((a)->datalen),d,dl) - -#define x509_implicit_general_names_to_der(i,a,d,dl) \ - asn1_type_to_der(ASN1_TAG_EXPLICIT(i),(a)->data,(a)->datalen,d,dl) - -#define x509_implicit_general_names_from_der(i,a,d,dl) \ - asn1_type_copy_from_der(ASN1_TAG_EXPLICIT(i),256,(a)->data,&((a)->datalen),d,dl) - - -/* -Extension 1 -AuthorityKeyIdentifier ::= SEQUENCE { - keyIdentifier [0] IMPLICIT OCTET STRING OPTIONAL, - authorityCertIssuer [1] IMPLICIT GeneralNames OPTIONAL, - authorityCertSerialNumber [2] IMPLICIT INTEGER OPTIONAL -} - 在验证证书时,签名方公钥是通过 issuer 在备选的CA证书列表中检索得到的 - 但是某些CA可能存在一个同一个名字对应了多个证书,因此需要一个格外的公钥ID - 也许我们可以对所有这种SEQUENCE OF类型的都支持一个IMPLICIT - -用于从多个subject同名的CA证书中挑选出需要的证书 - - * 如果这些同名CA证书中使用的公钥不同,那么这些公钥的key_id不同 - * 如果这些同名CA证书(不是根CA证书)是由不同的上级CA签发,那么可以由issuer来区分 - * 如果这些同名CA证书的序列号 - - -AuthorityKeyIdentifier 扩展中包含签发该证书的上级CA证书的部分信息 -*/ - -int x509_authority_key_identifier_to_der( - const uint8_t *keyid, size_t keyid_len, - const X509_GENERAL_NAMES *issuer, - const uint8_t *serial_number, size_t serial_number_len, - uint8_t **out, size_t *outlen); - -int x509_authority_key_identifier_from_der( - const uint8_t **keyid, size_t *keyid_len, - X509_GENERAL_NAMES *issuer, - const uint8_t **serial_number, size_t *serial_number_len, - const uint8_t **in, size_t *inlen); - -int x509_certificate_set_authority_key_identifier(X509_CERTIFICATE *cert, - int is_critical, - const uint8_t *keyid, size_t keyid_len, - const X509_GENERAL_NAMES *issuer, - const uint8_t *serial_number, size_t serial_number_len); - -int x509_certificate_get_authority_key_identifier(const X509_CERTIFICATE *cert, - int *is_critical, - const uint8_t **keyid, size_t *keyid_len, - X509_GENERAL_NAMES *issuer, - const uint8_t **serial_number, size_t *serial_number_len); - -/* -Extension 2 -SubjectKeyIdentifier ::= OCTET STRING -*/ -int x509_certificate_set_subject_key_identifier(X509_CERTIFICATE *cert, - int is_critical, - const uint8_t *keyid, size_t keyid_len); - -// keyid = sm3(uncompressed_sm2_public_key_point) -int x509_certificate_generate_subject_key_identifier(X509_CERTIFICATE *cert, - int is_critical); - -int x509_certificate_get_subject_key_identifier(const X509_CERTIFICATE *cert, - int *is_critical, - const uint8_t **keyid, size_t *keyid_len); - - -int x509_subject_key_identifier_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); - - -/* -Extension 3 KeyUsage - -KeyUsage ::= BIT STRING { - digitalSignature (0), - nonRepudiation (1), -- recent editions of X.509 have - -- renamed this bit to contentCommitment - keyEncipherment (2), - dataEncipherment (3), - keyAgreement (4), - keyCertSign (5), - cRLSign (6), - encipherOnly (7), - decipherOnly (8) } -*/ -enum X509_KeyUsage { - X509_ku_digital_signature = 0, - X509_ku_non_repudiation, // -- renamed this bit to contentCommitment - X509_ku_key_encipherment, - X509_ku_data_encipherment, - X509_ku_key_agreement, - X509_ku_key_cert_sign, - X509_ku_crl_sign, - X509_ku_encipher_only, - X509_ku_decipher_only, -}; - -int x509_certificate_set_key_usage(X509_CERTIFICATE *cert, - int is_critical, - int usage_bits); - -int x509_certificate_get_key_usage(const X509_CERTIFICATE *cert, - int *is_critical, - int *usage_bits); - - -// Extension 4 CertificatePolicies - -/* - DisplayText ::= CHOICE { - ia5String IA5String (SIZE (1..200)), - visibleString VisibleString (SIZE (1..200)), - bmpString BMPString (SIZE (1..200)), - utf8String UTF8String (SIZE (1..200)) } -*/ -int x509_display_text_to_der(int tag, const char *text, size_t textlen, uint8_t **out, size_t *outlen); -int x509_display_text_from_der(int *tag, const char **text, size_t *textlen, const uint8_t **in, size_t *inlen); - - -/* -NoticeReference ::= SEQUENCE { - organization DisplayText, - noticeNumbers SEQUENCE OF INTEGER } -*/ -int x509_notice_reference_to_der( - int organization_tag, const char *organization, size_t organization_len, - const int *notice_numbers, size_t notice_numbers_count, - uint8_t **out, size_t *outlen); - -int x509_notice_reference_from_der( - int *organization_tag, const char **organization, size_t *organization_len, - int *notice_numbers, size_t *notice_numbers_count, - const uint8_t **in, size_t *inlen); - -/* -UserNotice ::= SEQUENCE { - noticeRef NoticeReference OPTIONAL, - explicitText DisplayText OPTIONAL } -*/ -int x509_user_notice_to_der( - const uint8_t *notice_ref_der, size_t notice_ref_der_len, - int explicit_text_tag, const char *explicit_text, size_t explicit_text_len, - uint8_t **out, size_t *outlen); - -int x509_user_notice_from_der( - const uint8_t **notice_ref_der, size_t *notice_ref_der_len, - int *explicit_text_tag, const char **explicit_text, size_t *explicit_text_len, - const uint8_t **in, size_t *inlen); - -/* -PolicyQualifierInfo ::= SEQUENCE { - policyQualifierId PolicyQualifierId, - qualifier ANY DEFINED BY policyQualifierId } - - switch(policyQualifierId) - case id-qt-cps : qualifier ::= IA5String - case id-qt-unotice : qualifier ::= UserNotice -*/ -int x509_policy_qualifier_info_to_der(int oid, - const uint8_t *qualifier, size_t qualifier_len, - uint8_t **out, size_t *outlen); - -int x509_policy_qualifier_info_from_der(int *oid, - const uint8_t **qualifier, size_t *qualifier_len, - const uint8_t **in, size_t *inlen); - -/* -PolicyInformation ::= SEQUENCE { - policyIdentifier CertPolicyId, - policyQualifiers SEQUENCE SIZE (1..MAX) OF - PolicyQualifierInfo OPTIONAL } - -CertPolicyId ::= OBJECT IDENTIFIER -*/ -typedef struct { - size_t datalen; - uint8_t data[256]; -} X509_POLICY_QUALIFIER_INFOS; - -int x509_policy_qualifier_infos_add_item(X509_POLICY_QUALIFIER_INFOS *a, - int oid, const uint8_t *qualifier, size_t qualifier_len); - -int x509_policy_qualifier_infos_get_next_item(const X509_POLICY_QUALIFIER_INFOS *a, const uint8_t **next, - int *oid, const uint8_t **qualifier, size_t *qualifier_len); - -#define x509_policy_qualifier_infos_to_der(a,d,dl) \ - asn1_sequence_to_der((a)->data,(a)->datalen,d,dl) - -#define x509_policy_qualifier_infos_from_der(a,d,dl) \ - asn1_sequence_copy_from_der(256, (a)->data,&((a)->datalen),d,dl) - -int x509_policy_information_to_der( - int oid, const uint32_t *nodes, size_t nodes_count, - const X509_POLICY_QUALIFIER_INFOS *qualifiers, - uint8_t **out, size_t *outlen); - -int x509_policy_information_from_der( - int *oid, uint32_t *nodes, size_t *nodes_count, - X509_POLICY_QUALIFIER_INFOS *qualifiers, - const uint8_t **in, size_t *inlen); - -/* -Extension 4 Certificate Policies -CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation -*/ -typedef struct { - size_t datalen; - uint8_t data[1024]; -} X509_CERTIFICATE_POLICIES; - -int x509_certificate_policies_add_item(X509_CERTIFICATE_POLICIES *a, - int oid, const uint32_t *nodes, size_t nodes_count, - const X509_POLICY_QUALIFIER_INFOS *qualifiers); - -int x509_certificate_policies_get_next_item(const X509_CERTIFICATE_POLICIES *a, const uint8_t **next, - int *oid, const uint32_t *nodes, size_t *nodes_count, - X509_POLICY_QUALIFIER_INFOS *qualifiers); - -#define x509_certificate_policies_to_der(a,d,dl) \ - asn1_sequence_to_der((a)->data,(a)->datalen,d,dl) - -#define x509_certificate_policies_from_der(a,d,dl) \ - asn1_sequence_copy_from_der(1024, (a)->data,&((a)->datalen),d,dl) - - - -int x509_certificate_set_certificate_policies(X509_CERTIFICATE *cert, - int is_critical, - const X509_CERTIFICATE_POLICIES *policies); - -int x509_certificate_get_certificate_policies(const X509_CERTIFICATE *cert, - int *is_critical, - X509_CERTIFICATE_POLICIES *policies); - - - -// Extension 5. Policy Mappings - -/* - PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE { - issuerDomainPolicy CertPolicyId, - subjectDomainPolicy CertPolicyId } -*/ -int x509_policy_mapping_to_der( - int issuer_policy_oid, const uint32_t *issuer_policy_nodes, size_t issuer_policy_nodes_count, - int subject_policy_oid, const uint32_t *subject_policy_nodes, size_t subject_policy_nodes_count, - uint8_t **out, size_t *outlen); - -int x509_policy_mapping_from_der( - int *issuer_policy_oid, uint32_t *issuer_policy_nodes, size_t *issuer_policy_nodes_count, - int *subject_policy_oid, uint32_t *subject_policy_nodes, size_t *subject_policy_nodes_count, - const uint8_t **in, size_t *inlen); - -typedef struct { - size_t datalen; - uint8_t data[1024]; -} X509_POLICY_MAPPINGS; - -int x509_policy_mappings_add_item(X509_POLICY_MAPPINGS *a, - int issuer_policy_oid, const uint32_t *issuer_policy_nodes, size_t issuer_policy_nodes_count, - int subject_policy_oid, const uint32_t *subject_policy_nodes, size_t subject_policy_nodes_count); -int x509_policy_mappings_get_next_item(const X509_POLICY_MAPPINGS *a, const uint8_t **next, - uint32_t *issuer_policy_nodes, size_t *issuer_policy_nodes_count, - uint32_t *subject_policy_nodes, size_t *subject_policy_nodes_count); - -#define x509_policy_mappings_to_der(a,d,dl) \ - asn1_sequence_to_der((a)->data,(a)->datalen,d,dl) - -#define x509_policy_mappings_from_der(a,d,dl) \ - asn1_sequence_copy_from_der(1024,(a)->data,&((a)->datalen),d,dl) - - -int x509_certificate_set_policy_mappings(X509_CERTIFICATE *cert, - int is_critical, - const X509_POLICY_MAPPINGS *mappings); - -int x509_certificate_get_policy_mappings(const X509_CERTIFICATE *cert, - int *is_critical, - X509_POLICY_MAPPINGS *mappings); - - -// Extension 6 Subject Alternative Names -// SubjectAltName ::= GeneralNames - -int x509_certificate_set_subject_alt_name(X509_CERTIFICATE *a, - int is_critical, - const X509_GENERAL_NAMES *name); - -int x509_certificate_get_subject_alt_name(const X509_CERTIFICATE *a, - int *is_critical, - X509_GENERAL_NAMES *name); - - -// Extension 7 Issuer Alternative Name -// IssuerAltName ::= GeneralNames - -int x509_certificate_set_issuer_alt_name(X509_CERTIFICATE *a, - int is_critical, - const X509_GENERAL_NAMES *name); - -int x509_certificate_get_issuer_alt_name(X509_CERTIFICATE *a, - int *is_critical, - X509_GENERAL_NAMES *name); - -// Extension 8. Subject Directory Attributes -/* -SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute - -Attribute ::= SEQUENCE { - type OBJECT IDENTIFIER, - values SET OF AttributeValue } - -- at least one value is required - - AttributeValue ::= ANY - - Conforming CAs MUST mark this extension as non-critical. -*/ -int x509_attribute_to_der( - int oid, const uint32_t *nodes, size_t nodes_count, - const uint8_t *values, size_t valueslen, - uint8_t **out, size_t *outlen); -int x509_attribute_from_der( - int *oid, uint32_t *nodes, size_t *nodes_count, - const uint8_t **values, size_t *valueslen, - const uint8_t **in, size_t *inlen); - -typedef struct { - size_t datalen; - uint8_t data[128]; -} X509_ATTRIBUTES; - -int x509_attributes_add_item(X509_ATTRIBUTES *a, - int oid, const uint32_t *nodes, size_t nodes_count, - const uint8_t *values, size_t valueslen); - -int x509_attributes_get_next_item(const X509_ATTRIBUTES *a, const uint8_t **next, - int *oid, uint32_t *nodes, size_t *nodes_count, - const uint8_t **data, size_t *datalen); - -#define x509_attributes_to_der(a,d,dl) \ - asn1_sequence_to_der((a)->data,(a)->datalen,d,dl) - -#define x509_attributes_from_der(a,d,dl) \ - asn1_sequence_copy_from_der(128,(a)->data,&((a)->datalen),d,dl) - - -int x509_certificate_set_subject_directory_attributes(X509_CERTIFICATE *cert, - int is_critical, - const X509_ATTRIBUTES *attrs); - -int x509_certificate_get_subject_directory_attributes(const X509_CERTIFICATE *cert, - int *is_critical, - X509_ATTRIBUTES *attrs); - - - - -// Extension 9. Basic Constraints -/* -BasicConstraints ::= SEQUENCE { - cA BOOLEAN DEFAULT FALSE, - pathLenConstraint INTEGER (0..MAX) OPTIONAL } -*/ - -int x509_basic_constraints_to_der(int is_ca_cert, // 必须设置为 0 或 1,如果设为 0 那么不编码 - int cert_chain_maxlen, // -1 means omitted,FIXME: 应该设置一个最大值 - uint8_t **out, size_t *outlen); - -int x509_basic_constraints_from_der(int *is_ca_cert, int *cert_chain_maxlen, const uint8_t **in, size_t *inlen); - -int x509_certificate_set_basic_constraints(X509_CERTIFICATE *cert, - int is_critical, - int is_ca_cert, - int cert_chain_maxlen); - -int x509_certificate_get_basic_constraints(const X509_CERTIFICATE *cert, - int *is_critical, - int *is_ca_cert, - int *cert_chain_maxlen); - -int x509_basic_constraints_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); -int x509_key_usage_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); -int x509_ext_key_usage_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); -int x509_authority_key_identifier_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); -int x509_policy_constraints_print(FILE *fp, const uint8_t *p, size_t len, int format, int indent); - - -// Extension 10. Name Constraints -/* - NameConstraints ::= SEQUENCE { - permittedSubtrees [0] GeneralSubtrees OPTIONAL, - excludedSubtrees [1] GeneralSubtrees OPTIONAL } - - GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree - - GeneralSubtree ::= SEQUENCE { - base GeneralName, - minimum [0] BaseDistance DEFAULT 0, - maximum [1] BaseDistance OPTIONAL } - - BaseDistance ::= INTEGER (0..MAX) -*/ -int x509_general_subtree_to_der( - int base_choise, const uint8_t *base_data, size_t base_datalen, - int minimum, - int maximum, - uint8_t **out, size_t *outlen); -int x509_general_subtree_from_der( - int *base_choise, const uint8_t **base_data, size_t *base_datalen, - int *minimum, - int *maximum, - const uint8_t **in, size_t *inlen); - -typedef struct { - size_t datalen; - uint8_t data[128]; -} X509_GENERAL_SUBTREES; - -int x509_general_subtrees_add_item(X509_GENERAL_SUBTREES *a, - int base_choise, const uint8_t *base_data, size_t base_datalen, - int minimum, - int maximum); -int x509_general_subtrees_get_next_item(const X509_GENERAL_SUBTREES *a, const uint8_t **next, - int *base_choise, const uint8_t **base_data, size_t *base_datalen, - int *minimum, - int *maximum); - -int x509_general_subtrees_to_der_ex(int tag, const X509_GENERAL_SUBTREES *a, uint8_t **out, size_t *outlen); -int x509_general_subtrees_from_der_ex(int tag, X509_GENERAL_SUBTREES *a, const uint8_t **in, size_t *inlen); - -#define x509_general_subtrees_to_der(a,d,dl) \ - asn1_sequence_to_der((a)->data,(a)->datalen,d,dl) - -#define x509_general_subtrees_from_der(a,d,dl) \ - asn1_sequence_copy_from_der(128,(a)->data,&((a)->datalen),d,dl) - -int x509_name_constraints_to_der( - const X509_GENERAL_SUBTREES *permitted_subtrees, - const X509_GENERAL_SUBTREES *excluded_subtrees, - uint8_t **out, size_t *outlen); - -int x509_name_constraints_from_der( - X509_GENERAL_SUBTREES *permitted_subtrees, - X509_GENERAL_SUBTREES *excluded_subtrees, - const uint8_t **in, size_t *inlen); - -int x509_certificate_set_name_constraints(X509_CERTIFICATE *cert, - int is_critical, - const X509_GENERAL_SUBTREES *permitted_subtrees, - const X509_GENERAL_SUBTREES *excluded_subtrees); - -int x509_certificate_get_name_constraints(X509_CERTIFICATE *cert, - int *is_critical, - X509_GENERAL_SUBTREES *permitted_subtrees, - X509_GENERAL_SUBTREES *excluded_subtrees); - - - -// Extension 11. Policy Constraints -/* - PolicyConstraints ::= SEQUENCE { - requireExplicitPolicy [0] SkipCerts OPTIONAL, - inhibitPolicyMapping [1] SkipCerts OPTIONAL } - - SkipCerts ::= INTEGER (0..MAX) -*/ - -int x509_policy_constraints_to_der( - int require_explicit_policy, - int inhibit_policy_mapping, - uint8_t **out, size_t *outlen); - -int x509_policy_constraints_from_der( - int *require_explicit_policy, - int *inhibit_policy_mapping, - const uint8_t **in, size_t *inlen); - -int x509_certificate_set_policy_constraints(X509_CERTIFICATE *cert, - int is_critical, - int require_explicit_policy, - int inhibit_policy_mapping); - -int x509_certificate_get_policy_constraints(const X509_CERTIFICATE *cert, - int *is_critical, - int *requireExplicitPolicy, - int *inhibitPolicyMapping); - - -/* -12. Extended Key Usage - - ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId - KeyPurposeId ::= OBJECT IDENTIFIER - -*/ -int x509_key_purpose_from_name(int *oid, const char *name); -const char *x509_key_purpose_name(int oid); -const char *x509_key_purpose_text(int oid); -int x509_key_purpose_to_der(int oid, uint8_t **out, size_t *outlen); -int x509_key_purpose_from_der(int *oid, const uint8_t **in, size_t *inlen); -int x509_ext_key_usage_to_der(const int *oids, size_t oids_count, uint8_t **out, size_t *outlen); -int x509_ext_key_usage_from_der(int *oids, size_t *oids_count, const uint8_t **in, size_t *inlen); - -int x509_certificate_set_ext_key_usage(X509_CERTIFICATE *cert, - int is_critical, - const int *key_purpose_oids, size_t key_purpose_oids_count); - -int x509_certificate_get_ext_key_usage(const X509_CERTIFICATE *cert, - int *is_critical, - int *key_purpose_oids, size_t *key_purpose_oids_count); - -/* - -13. CRL Distribution Points - - CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint - - DistributionPoint ::= SEQUENCE { - distributionPoint [0] DistributionPointName OPTIONAL, - reasons [1] ReasonFlags OPTIONAL, - cRLIssuer [2] GeneralNames OPTIONAL } - - DistributionPointName ::= CHOICE { - fullName [0] GeneralNames, - nameRelativeToCRLIssuer [1] RelativeDistinguishedName } - - 由于 GeneralNames 是存储类型,因此 DistributionPointName 也是存储类型 - - ReasonFlags ::= BIT STRING { - unused (0), - keyCompromise (1), - cACompromise (2), - affiliationChanged (3), - superseded (4), - cessationOfOperation (5), - certificateHold (6), - privilegeWithdrawn (7), - aACompromise (8) } -*/ -enum { - X509_rf_unused = 0, - X509_rf_keyCompromise, - X509_rf_caCompromise, - X509_rf_affiliationChanged, - X509_rf_superseded, - X509_rf_cessationOfOperation, - X509_rf_certificateHold, - X509_rf_privilegeWithdrawn, - X509_rf_aaCompromise, -}; - -typedef struct { - int choice; - union { - X509_GENERAL_NAMES full_name; // [0] IMPLICIT - X509_RDN relative_name; // [1] IMPLICIT - } u; -} X509_DISTRIBUTION_POINT_NAME; - -int x509_distribution_point_name_to_der_ex( - int tag, - const X509_DISTRIBUTION_POINT_NAME *a, - uint8_t **out, size_t *outlen); - -int x509_distribution_point_name_from_der_ex( - int tag, - X509_DISTRIBUTION_POINT_NAME *a, - const uint8_t **in, size_t *inlen); - - -int x509_distribution_point_to_der( // DistributionPoint - const X509_DISTRIBUTION_POINT_NAME *dist_point_name, // [0] EXPLICIT OPTIONAL - int reason_bits, // [1] IMPLICIT OPTIONAL - const X509_GENERAL_NAMES *crl_issuer, // [2] IMPLICIT OPTIONAL - uint8_t **out, size_t *outlen); - -int x509_distribution_point_from_der( - X509_DISTRIBUTION_POINT_NAME *dist_point_name, - int *reason_bits, - X509_GENERAL_NAMES *crl_issuer, - const uint8_t **in, size_t *inlen); - -typedef struct { - size_t datalen; - uint8_t data[128]; -} X509_CRL_DISTRIBUTION_POINTS; - -int x509_crl_distribution_points_add_item(X509_CRL_DISTRIBUTION_POINTS *a, - const X509_DISTRIBUTION_POINT_NAME *dist_point_name, - int reason_bits, - const X509_GENERAL_NAMES *crl_issuer); -int x509_crl_distribution_points_get_next_item(const X509_CRL_DISTRIBUTION_POINTS *a, - const uint8_t **next, - X509_DISTRIBUTION_POINT_NAME *distribution_point, - int *reasons, - X509_GENERAL_NAMES *crl_issuer); -int x509_crl_distribution_points_to_der(const X509_CRL_DISTRIBUTION_POINTS *a, uint8_t **out, size_t *outlen); -int x509_crl_distribution_points_from_der(X509_CRL_DISTRIBUTION_POINTS *a, const uint8_t **in, size_t *inlen); - -int x509_certificate_set_crl_distribution_points(X509_CERTIFICATE *cert, - int is_critical, - const X509_CRL_DISTRIBUTION_POINTS *crl_dist_points); - -int x509_certificate_get_crl_distribution_points(const X509_CERTIFICATE *cert, - int *is_critical, - X509_CRL_DISTRIBUTION_POINTS *crl_dist_points); - - -/* -14. Inhibit anyPolicy - - id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } - - InhibitAnyPolicy ::= SkipCerts - - SkipCerts ::= INTEGER (0..MAX) -*/ -int x509_certificate_set_inhibit_any_policy(X509_CERTIFICATE *cert, - int is_critical, - int skip_certs); -int x509_certificate_get_inhibit_any_policy(const X509_CERTIFICATE *cert, - int *is_critical, - int *skip_certs); - -/* -15. Freshest CRL (a.k.a. Delta CRL Distribution Point) -FreshestCRL ::= CRLDistributionPoints -*/ -int x509_certificate_set_freshest_crl(X509_CERTIFICATE *cert, - int is_critical, - const X509_CRL_DISTRIBUTION_POINTS *crl_dist_points); -int x509_certificate_get_freshest_crl(const X509_CERTIFICATE *cert, - int *is_critical, - X509_CRL_DISTRIBUTION_POINTS *crl_dist_points); - - #define X509_ub_name 32768 #define X509_ub_common_name 64 #define X509_ub_locality_name 128 @@ -1059,66 +122,189 @@ int x509_certificate_get_freshest_crl(const X509_CERTIFICATE *cert, #define X509_ub_organizational_unit_name 64 #define X509_ub_title 64 #define X509_ub_serial_number 64 -#define X509_ub_match 128 -#define X509_ub_emailaddress_length 255 -#define X509_ub_common_name_length 64 -#define X509_ub_country_name_alpha_length 2 -#define X509_ub_country_name_numeric_length 3 -#define X509_ub_domain_defined_attributes 4 -#define X509_ub_domain_defined_attribute_type_length 8 -#define X509_ub_domain_defined_attribute_value_length 128 -#define X509_ub_domain_name_length 16 -#define X509_ub_extension_attributes 256 -#define X509_ub_e163_4_number_length 15 -#define X509_ub_e163_4_sub_address_length 40 -#define X509_ub_generation_qualifier_length 3 -#define X509_ub_given_name_length 16 -#define X509_ub_initials_length 5 -#define X509_ub_integer_options 256 -#define X509_ub_numeric_user_id_length 32 -#define X509_ub_organization_name_length 64 -#define X509_ub_organizational_unit_name_length 32 -#define X509_ub_organizational_units 4 -#define X509_ub_pds_name_length 16 -#define X509_ub_pds_parameter_length 30 -#define X509_ub_pds_physical_address_lines 6 -#define X509_ub_postal_code_length 16 #define X509_ub_pseudonym 128 -#define X509_ub_surname_length 40 -#define X509_ub_terminal_id_length 24 -#define X509_ub_unformatted_address_length 180 -#define X509_ub_x121_address_length 16 +int x509_attr_type_and_value_check(int oid, int tag, const uint8_t *val, size_t vlen); +int x509_attr_type_and_value_to_der(int oid, int tag, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen); +int x509_attr_type_and_value_from_der(int *oid, int *tag, const uint8_t **val, size_t *vlen, const uint8_t **in, size_t *inlen); +int x509_attr_type_and_value_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); -typedef struct { - int version; - X509_NAME subject; - X509_PUBLIC_KEY_INFO subject_public_key_info; -} X509_CERT_REQUEST_INFO; +/* +RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue +*/ +int x509_rdn_to_der(int oid, int tag, const uint8_t *val, size_t vlen, const uint8_t *more, size_t mlen, uint8_t **out, size_t *outlen); +int x509_rdn_from_der(int *oid, int *tag, const uint8_t **val, size_t *vlen, const uint8_t **more, size_t *mlen, const uint8_t **in, size_t *inlen); +int x509_rdn_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); -int x509_cert_request_info_to_der(const X509_CERT_REQUEST_INFO *a, uint8_t **out, size_t *outlen); -int x509_cert_request_info_from_der(X509_CERT_REQUEST_INFO *a, const uint8_t **in, size_t *inlen); -int x509_cert_request_info_print(FILE *fp, const X509_CERT_REQUEST_INFO *a, int format, int indent); +/* +Name ::= SEQUENCE OF RelativeDistinguishedName +*/ +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 mlen); +int x509_name_add_country_name(uint8_t *d, size_t *dlen, int maxlen, const char val[2] ); // val: PrintableString SIZE(2) +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); +int x509_name_add_locality_name(uint8_t *d, size_t *dlen, int maxlen, cint tag, onst uint8_t *val, size_t vlen); +int x509_name_add_organization_name(uint8_t *d, size_t *dlen, int maxlen, cint tag, onst uint8_t *val, size_t vlen); +int x509_name_add_organizational_unit_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen); +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 -typedef struct { - X509_CERT_REQUEST_INFO req_info; - int signature_algor; - uint8_t signature[SM2_MAX_SIGNATURE_SIZE]; - size_t signature_len; -} X509_CERT_REQUEST; +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); +int x509_name_get_common_name(const uint8_t *d, size_t dlen, int *tag, const uint8_t **val, size_t *vlen); -int x509_cert_request_set_sm2(X509_CERT_REQUEST *a, const X509_NAME *subject, const SM2_KEY *sm2_key); -int x509_cert_request_sign_sm2(X509_CERT_REQUEST *a, const SM2_KEY *sm2_key); -int x509_cert_request_verify(const X509_CERT_REQUEST *a); -#define x509_cert_request_set(a,subj,pk) x509_cert_request_set_sm2((a),(subj),(pk)) -#define x509_cert_request_sign(a,sk) x509_cert_request_sign_sm2((a),(sk)) +/* +SubjectPublicKeyInfo ::= SEQUENCE { + algorithm AlgorithmIdentifier, + subjectPublicKey BIT STRING } -int x509_cert_request_to_der(const X509_CERT_REQUEST *a, uint8_t **out, size_t *outlen); -int x509_cert_request_to_pem(const X509_CERT_REQUEST *a, FILE *fp); -int x509_cert_request_from_der(X509_CERT_REQUEST *a, const uint8_t **in, size_t *inlen); -int x509_cert_request_from_pem(X509_CERT_REQUEST *a, FILE *fp); -int x509_cert_request_print(FILE *fp, const X509_CERT_REQUEST *a, int format, int indent); +algorithm.algorithm = OID_ec_public_key; +algorithm.parameters = OID_sm2; +subjectPublicKey = ECPoint +*/ +#define x509_public_key_info_to_der(key,out,outlen) sm2_public_key_info_to_der(key,out,outlen) +#define x509_public_key_info_from_der(key,in,inlen) sm2_public_key_info_from_der(key,in,inlen) +int x509_public_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +/* +Extension ::= SEQUENCE { + extnID OBJECT IDENTIFIER, + critical BOOLEAN DEFAULT FALSE, + extnValue OCTET STRING -- contains the DER encoding of an ASN.1 value +*/ +int x509_ext_to_der(int oid, int critical, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen); +int x509_ext_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, int *critical, const uint8_t **val, size_t *vlen, const uint8_t **in, size_t *inlen); +int x509_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +[3] EXPLICIT SEQUENCE OF Extension + */ +int x509_explicit_exts_to_der(int index, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int x509_explicit_exts_from_der(int index, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +#define x509_exts_to_der(d,dlen,out,outlen) x509_explicit_exts_to_der(3,d,dlen,out,outlen) +#define x509_exts_from_der(d,dlen,in,inlen) x509_explicit_exts_from_der(3,d,dlen,in,inlen) + +int x509_exts_get_count(const uint8_t *d, size_t dlen, int *count); +int x509_exts_get_ext_by_index(const uint8_t *d, size_t dlen, int index, + int *oid, uint32_t *nodes, size_t *nodes_cnt, int *critical, + const uint8_t **val, size_t *vlen); +int x509_exts_get_ext_by_oid(const uint8_t *d, size_t dlen, int oid, + int *critical, const uint8_t **val, size_t *vlen); +int x509_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +TBSCertificate ::= SEQUENCE { + version [0] EXPLICIT INTEGER DEFAULT v1, + serialNumber INTEGER, + siganture AlgorithmIdentifier, + issuer Name, + validity Validity, + subject Name, + subjectPulbicKeyInfo SubjectPublicKeyInfo, + issuerUniqueID [1] IMPLICIT BIT STRING OPTIONAL, -- If present, must be v2,v3 + subjectUniqueID [2] IMPLICIT BIT STRING OPTIONAL, -- If present, must be v2,v3 + extensions [3] EXPLICIT Extensions OPTIONAL -- If present, must be v3 } +*/ +#define X509_SERIAL_NUMBER_MIN_LEN 1 +#define X509_SERIAL_NUMBER_MAX_LEN 20 +#define X509_UNIQUE_ID_MIN_LEN 32 +#define X509_UNIQUE_ID_MAX_LEN 32 + +int x509_tbs_cert_to_der( + int version, + const uint8_t *serial, size_t serial_len, + int signature_algor, + const uint8_t *issuer, size_t issuer_len, + time_t not_before, time_t not_after, + const uint8_t *subject, size_t subject_len, + const SM2_KEY *subject_public_key, + const 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, + uint8_t **out, size_t *outlen); +int x509_tbs_cert_from_der( + int *version, + const uint8_t **serial, size_t *serial_len, + int *signature_algor, + const uint8_t **issuer, size_t *issuer_len, + time_t *not_before, time_t *not_after, + const uint8_t **subject, size_t *subject_len, + SM2_KEY *subject_public_key, + 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 uint8_t **in, size_t *inlen); +int x509_tbs_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +Certificate ::= SEQUENCE { + tbsCertificate TBSCertificate, + signatureAlgorithm AlgorithmIdentifier, + signatureValue BIT STRING } +*/ +int x509_certificate_to_der( + const uint8_t *tbs, size_t tbslen, + int signature_algor, + const uint8_t *sig, size_t siglen, + uint8_t **out, size_t *outlen); +int x509_certificate_from_der( + const uint8_t **tbs, size_t *tbslen, + int *signature_algor, + const uint8_t **sig, size_t *siglen, + const uint8_t **in, size_t *inlen); +int x509_certificate_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +// x509_cert functions +int x509_cert_sign( + uint8_t *cert, size_t *certlen, size_t maxlen, + int version, + const uint8_t *serial, size_t serial_len, + int signature_algor, + const uint8_t *issuer, size_t issuer_len, + time_t not_before, time_t not_after, + const uint8_t *subject, size_t subject_len, + const SM2_KEY *subject_public_key, + const 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); +int x509_cert_verify(const uint8_t *a, size_t alen, const SM2_KEY *pub_key, const char *signer_id); +int x509_cert_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen); + +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, FILE *fp, int index); +int x509_cert_from_pem_by_subject(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp, const uint8_t *name, size_t namelen); +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, + const uint8_t **serial_number, size_t *serial_number_len, + int *inner_signature_algor, + const uint8_t **issuer, size_t *issuer_len, + time_t *not_before, time_t *not_after, + const uint8_t *subject, size_t *subject_len, + SM2_KEY *subject_public_key, + const uint8_t **issuer_unique_id, size_t *issuer_unique_id_len, + const uint8_t **subject_unique_id, size_t *subject_unique_id_len, + const uint8_t **extensions, size_t *extensions_len, + int *signature_algor, + const uint8_t **signature, size_t *signature_len); + +/* +IssuerAndSerialNumber ::= SEQUENCE { + isser Name, + serialNumber INTEGER } +*/ +int x509_cert_get_issuer_and_serial_number(const uint8_t *cert, size_t certlen, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial_number, size_t *serial_number_len); + +int x509_certs_to_pem(const uint8_t *d, size_t dlen, FILE *fp); +int x509_certs_from_pem(const uint8_t *d, size_t *dlen, size_t maxlen, FILE *fp); +int x509_certs_get_count(const uint8_t *d, size_t dlen, int count); +int x509_certs_get_cert_by_index(const uint8_t *d, size_t dlen, int index, const uint8_t **cert, size_t *certlen); +int x509_certs_get_cert_by_subject(const uint8_t *d, size_t dlen, const uint8_t *subject, size_t subject_len, const uint8_t **cert, size_t *certlen); #ifdef __cplusplus } diff --git a/include/gmssl/x509_alg.h b/include/gmssl/x509_alg.h new file mode 100644 index 00000000..d1fe4d89 --- /dev/null +++ b/include/gmssl/x509_alg.h @@ -0,0 +1,104 @@ +/* + * 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. + */ + +#ifndef GMSSL_X509_ALG_H +#define GMSSL_X509_ALG_H + + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +AlgorithmIdentifier ::= SEQUENCE { + algorithm OBJECT IDENTIFIER, + parameters ANY } +*/ + +const char *x509_digest_algor_name(int oid); +int x509_digest_algor_from_name(const char *name); +int x509_digest_algor_from_der(int *oid, const uint8_t **in, size_t *inlen); +int x509_digest_algor_to_der(int oid, uint8_t **out, size_t *outlen); +int x509_digest_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +const char *x509_encryption_algor_name(int oid); +int x509_encryption_algor_from_name(const char *name); +int x509_encryption_algor_from_der(int *oid, const uint8_t **iv, size_t *ivlen, const uint8_t **in, size_t *inlen); +int x509_encryption_algor_to_der(int oid, const uint8_t *iv, size_t ivlen, uint8_t **out, size_t *outlen); +int x509_encryption_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +const char *x509_signature_algor_name(int oid); +int x509_signature_algor_from_name(const char *name); +int x509_signature_algor_from_der(int *oid, const uint8_t **in, size_t *inlen); +int x509_signature_algor_to_der(int oid, uint8_t **out, size_t *outlen); +int x509_signature_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +const char *x509_public_key_encryption_algor_name(int oid); +int x509_public_key_encryption_algor_from_name(const char *name); +int x509_public_key_encryption_algor_from_der(int *oid, const uint8_t **params, size_t *params_len, const uint8_t **in, size_t *inlen); +int x509_public_key_encryption_algor_to_der(int oid, uint8_t **out, size_t *outlen); +int x509_public_key_encryption_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +const char *x509_public_key_algor_name(int oid); +int x509_public_key_algor_from_name(const char *name); +int x509_public_key_algor_from_der(int *oid, const uint8_t **params, size_t *paramslen, const uint8_t **in, size_t *inlen); +int x509_public_key_algor_to_der(int oid, const uint8_t *params, size_t paramslen, uint8_t **out, size_t *outlen); +int x509_public_key_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/x509_crl.h b/include/gmssl/x509_crl.h new file mode 100644 index 00000000..862b8165 --- /dev/null +++ b/include/gmssl/x509_crl.h @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2020 - 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. + */ + + +#ifndef GMSSL_X509_CRL_H +#define GMSSL_X509_CRL_H + + +#ifdef __cplusplus +extern "C" { +#endif + +/* +CRLReason ::= ENUMERATED +*/ +typedef enum { + X509_cr_unspecified = 0, + X509_cr_key_compromise = 1, + X509_cr_ca_compromise = 2 , + X509_cr_affiliation_changed = 3, + X509_cr_superseded = 4, + X509_cr_cessation_of_operation = 5, + X509_cr_certificate_hold = 6, + X509_cr_not_assigned = 7, + X509_cr_remove_from_crl = 8, + X509_cr_privilege_withdrawn = 9, + X509_cr_aa_compromise = 10, +} X509_CRL_REASON; + +const char *x509_crl_reason_name(int reason); +int x509_crl_reason_from_name(int *reason, const char *name); +int x509_crl_reason_to_der(int reason, uint8_t **out, size_t *outlen); +int x509_crl_reason_from_der(int *reason, const uint8_t **in, size_t *inlen); + +/* +CRL Entry Extensions: + OID_ce_crl_reasons ENUMERATED + OID_ce_invalidity_date GeneralizedTime + OID_ce_certificate_issuer SEQUENCE GeneralNames +*/ +const char *x509_crl_entry_ext_id_name(int oid); +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); +int x509_crl_entry_ext_id_from_der(int *oid, const uint8_t **in, size_t *inlen); + +int x509_crl_entry_exts_add_reason( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + int reason); +int x509_crl_entry_exts_add_invalidity_date( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + time_t tv); +int x509_crl_entry_exts_add_certificate_issuer( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + const uint8_t *d, size_t dlen); + +/* +RevokedCertificate ::= SEQUENCE { + userCertificate CertificateSerialNumber, + revocationDate Time, + crlEntryExtensions Extensions OPTIONAL } +*/ +int x509_revoked_cert_to_der( + const uint8_t *serial, size_t serial_len, + time_t revoke_date, + const uint8_t *entry_exts, size_t entry_exts_len, + uint8_t **out, size_t *outlen); +int x509_revoked_cert_from_der( + const uint8_t **serial, size_t *serial_len, + time_t *revoke_date, + const uint8_t **entry_exts, size_t *entry_exts_len, + const uint8_t **in, size_t *inlen); +int x509_revoked_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +RevokedCertificates ::= SEQUENCE OF RevokedCertificate +*/ +int x509_revoked_certs_add_revoked_cert(uint8_t *d, size_t *dlen, size_t maxlen, + const uint8_t *serial, size_t serial_len, + time_t revoke_date, + const uint8_t *entry_exts, size_t entry_exts_len); +int x509_revoked_certs_get_revoked_cert_by_serial_number(const uint8_t *d, size_t dlen, + const uint8_t *serial, size_t serial_len, + time_t *revoke_date, + const uint8_t **entry_exts, size_t *entry_exts_len); +#define x509_revoked_certs_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_revoked_certs_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) +int x509_revoked_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +CRL Extensions: + OID_ce_authority_key_identifier SEQUENCE AuthorityKeyIdentifier + OID_ce_issuer_alt_name SEQUENCE GeneralNames + OID_ce_crl_number INTEGER + OID_ce_delta_crl_indicator INTEGER + OID_ce_issuing_distribution_point SEQUENCE IssuingDistributionPoint +*/ +const char *x509_crl_ext_id_name(int oid); +int x509_crl_ext_id_from_name(const char *name); +int x509_crl_ext_id_to_der(int oid, uint8_t **out, size_t *outlen); +int x509_crl_ext_id_from_der(int *oid, const uint8_t **in, size_t *inlen); + +int x509_crl_exts_add_authority_key_identifier( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + const uint8_t *keyid, size_t keyid_len, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial, size_t serial_len); +int x509_crl_exts_add_issuer_alt_name( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + const uint8_t *d, size_t dlen); +int x509_crl_exts_add_crl_number( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + int num); +int x509_crl_exts_add_delta_crl_indicator( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + int num); +int x509_crl_exts_add_issuing_distribution_point( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + const uint8_t *dist_point, size_t dist_point_len, + int only_contains_user_certs, + int only_contains_ca_certs, + int only_some_reasons, + int indirect_crl, + int only_contains_attr_certs); + +#define x509_crl_exts_to_der(d,dlen,out,outlen) x509_explicit_exts_to_der(0,d,dlen,out,outlen) +#define x509_crl_exts_from_der(d,dlen,in,inlen) x509_explicit_exts_from_der(0,d,dlen,in,inlen) +int x509_crl_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + +/* +TBSCertList ::= SEQUENCE { + version INTEGER OPTIONAL, -- if present, MUST be v2 + signature AlgorithmIdentifier, + issuer Name, + thisUpdate Time, + nextUpdate Time OPTIONAL, + revokedCertificates RevokedCertificates OPTIONAL, + crlExtensions [0] EXPLICIT Extensions OPTIONAL, -- if present, MUST be v2 } +*/ +int x509_tbs_crl_to_der( + int version, + int signature_algor, + const uint8_t *issuer, size_t issuer_len, + time_t this_update, + time_t next_update, + const uint8_t *revoked_certs, size_t revoked_certs_len, + const uint8_t *exts, size_t exts_len, + uint8_t **out, size_t *outlen); +int x509_tbs_crl_from_der( + int *version, + int *signature_algor, + const uint8_t **issuer, size_t *issuer_len, + time_t *this_update, + time_t *next_update, + const uint8_t **revoked_certs, size_t *revoked_certs_len, + const uint8_t **exts, size_t *exts_len, + uint8_t **in, size_t *inlen); +int x509_tbs_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +CertificateList ::= SEQUENCE { + tbsCertList TBSCertList, + signatureAlgorithm AlgorithmIdentifier, + signatureValue BIT STRING } +*/ +int x509_cert_list_to_der(const uint8_t *tbs_crl, size_t tbs_crl_len, + int signature_algor, const uint8_t *sig, size_t siglen, + uint8_t **out, size_t *outlen); +int x509_cert_list_from_der(const uint8_t **tbs_crl, size_t *tbs_crl_len, + int *signature_algor, const uint8_t **sig, size_t *siglen, + const uint8_t **in, size_t *inlen); +int x509_cert_list_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +// x509_crl_ functions + +int x509_crl_to_pem(const uint8_t *a, size_t *alen, FILE *fp); +int x509_crl_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp); +int x509_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen); + +int x509_crl_sign(uint8_t *crl, size_t *crl_len, + int version, + int signature_algor, + const uint8_t *issuer, size_t issuer_len, + time_t this_update, + time_t next_update, + const uint8_t *revoked_certs, size_t revoked_certs_len, + const uint8_t *exts, size_t exts_len, + const SM2_KEY *sign_key, const char *signer_id); +int x509_crl_verify(const uint8_t *a, size_t alen, const SM2_KEY *pub_key, const char *key_id); + +int x509_crl_get_details(const uint8_t *crl, size_t crl_len, + int *version, + const uint8_t **issuer, size_t *issuer_len, + time_t *this_update, + time_t *next_update, + const uint8_t **revoked_certs, size_t *revoked_certs_len, + int *signature_algor, + const uint8_t *sig, size_t *siglen); +int x509_crl_get_revoked_cert_by_serial_number(const uint8_t *a, size_t alen, + const uint8_t *serial, size_t serial_len, time_t *revoke_date, + const uint8_t **entry_exts, size_t *entry_exts_len); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/x509_ext.h b/include/gmssl/x509_ext.h new file mode 100644 index 00000000..3a11c44f --- /dev/null +++ b/include/gmssl/x509_ext.h @@ -0,0 +1,498 @@ +/* + * 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. + */ + +#ifndef GMSSL_X509_EXT_H +#define GMSSL_X509_EXT_H + + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +Extensions: + + 1. AuthorityKeyIdentifier SEQUENCE AuthorityKeyIdentifier + 2. SubjectKeyIdentifier OCTET STRING + 3. KeyUsage BIT STRING + 4. CertificatePolicies SEQUENCE OF SEQUENCE CertificatePolicies + 5. PolicyMappings SEQUENCE OF SEQUENCE PolicyMappings + 6. SubjectAltName SEQUENCE OF SEQUENCE GeneralNames + 7. IssuerAltName SEQUENCE OF SEQUENCE GeneralNames + 8. SubjectDirectoryAttributes SEQUENCE OF SEQUENCE Attributes + 9. BasicConstraints SEQUENCE BasicConstraints + 10. NameConstraints SEQUENCE NameConstraints + 11. PolicyConstraints SEQUENCE PolicyConstraints + 12. ExtKeyUsageSyntax SEQUENCE OF OBJECT IDENTIFIER + 13. CRLDistributionPoints SEQUENCE OF SEQUENCE DistributionPoints + 14. InhibitAnyPolicy INTEGER + 15. FreshestCRL SEQUENCE OF SEQUENCE DistributionPoints +*/ + +int x509_exts_add_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, + const uint8_t *keyid, size_t keyid_len, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial, size_t serial_len); +int x509_exts_add_subject_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); +int x509_exts_add_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int bits); +int x509_exts_add_certificate_policies(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); +int x509_exts_add_policy_mappings(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); +int x509_exts_add_subject_alt_name(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); +int x509_exts_add_issuer_alt_name(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); +int x509_exts_add_subject_directory_attributes(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); +int x509_exts_add_name_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, + const uint8_t *permitted_subtrees, size_t permitted_subtrees_len, + const uint8_t *excluded_subtrees, size_t excluded_subtrees_len); +int x509_exts_add_policy_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, + int require_explicit_policy, int inhibit_policy_mapping); +int x509_exts_add_basic_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int ca, int path_len_constraint); +int x509_exts_add_ext_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const int *key_purposes, size_t key_purposes_cnt); +int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); +int x509_exts_add_inhibit_any_policy(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int skip_certs); +int x509_exts_add_freshest_crl(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); + + +/* +OtherName ::= SEQUENCE { + type-id OBJECT IDENTIFIER, -- known oid from x509_rdn_oid such as OID_at_common_name, or oid nodes + value [0] EXPLICIT ANY DEFINED BY type-id } +*/ +int x509_other_name_to_der( + const uint32_t *nodes, size_t nodes_count, + const uint8_t *value, size_t value_len, + uint8_t **out, size_t *outlen); +int x509_other_name_from_der( + uint32_t *nodes, size_t *nodes_count, + const uint8_t **value, size_t *valuelen, + const uint8_t **in, size_t *inlen); +int x509_other_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +EDIPartyName ::= SEQUENCE { + nameAssigner [0] EXPLICIT DirectoryString OPTIONAL, + partyName [1] EXPLICIT DirectoryString } +*/ +int x509_edi_party_name_to_der( + 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, + uint8_t **out, size_t *outlen); +int x509_edi_party_name_from_der( + 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, + const uint8_t **in, size_t *inlen); +int x509_edi_party_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +GeneralName ::= CHOICE { + otherName [0] IMPLICIT OtherName, -- 只在GeneralName中出现 + rfc822Name [1] IMPLICIT IA5String, + dNSName [2] IMPLICIT IA5String, + x400Address [3] IMPLICIT ORAddress, + directoryName [4] IMPLICIT Name, -- SEQENCE OF,因此是d,dlen + ediPartyName [5] IMPLICIT EDIPartyName, -- 只在GeneralName中出现 + uniformResourceIdentifier [6] IMPLICIT IA5String, + iPAddress [7] IMPLICIT OCTET STRING, -- 4 bytes or string? + registeredID [8] IMPLICIT OBJECT IDENTIFIER } +*/ +typedef enum { + X509_gn_other_name = 0, + X509_gn_rfc822_name = 1, + X509_gn_dns_name = 2, + X509_gn_x400_address = 3, + X509_gn_directory_name = 4, + X509_gn_edi_party_name = 5, + X509_gn_uniform_resource_identifier = 6, + X509_gn_ip_address = 7, + X509_gn_registered_id = 8, +} X509_GENERAL_NAME_CHOICE; + +int x509_general_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int x509_general_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +int x509_general_name_print(FILE *fp, int fmt, int ind, const char *label, int choice, const uint8_t *d, size_t dlen); + +/* +GeneralNames ::= SEQUENCE OF GeneralName +*/ +#define x509_general_names_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_general_names_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) +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); +int x509_general_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +AuthorityKeyIdentifier ::= SEQUENCE { + keyIdentifier [0] IMPLICIT OCTET STRING OPTIONAL, + authorityCertIssuer [1] IMPLICIT GeneralNames OPTIONAL, + authorityCertSerialNumber [2] IMPLICIT INTEGER OPTIONAL } +*/ +int x509_authority_key_identifier_to_der( + const uint8_t *keyid, size_t keyid_len, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial, size_t serial_len, + uint8_t **out, size_t *outlen); +int x509_authority_key_identifier_from_der( + const uint8_t **keyid, size_t *keyid_len, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial, size_t *serial_len, + const uint8_t **in, size_t *inlen); +int x509_authority_key_identifier_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +KeyUsage ::= BIT STRING { + digitalSignature (0), + nonRepudiation (1), -- recent renamed contentCommitment + keyEncipherment (2), + dataEncipherment (3), + keyAgreement (4), + keyCertSign (5), + cRLSign (6), + encipherOnly (7), + decipherOnly (8) } +*/ +#define X509_KU_DIGITAL_SIGNATURE (1 << 0) +#define X509_KU_NON_REPUDIATION (1 << 1) +#define X509_KU_KEY_ENCIPHERMENT (1 << 2) +#define X509_KU_DATA_ENCIPHERMENT (1 << 3) +#define X509_KU_KEY_AGREEMENT (1 << 4) +#define X509_KU_KEY_CERT_SIGN (1 << 5) +#define X509_KU_CRL_SIGN (1 << 6) +#define X509_KU_ENCIPHER_ONLY (1 << 7) +#define X509_KU_DECIPHER_ONLY (1 << 8) + +#define x509_key_usage_to_der(bits,out,outlen) asn1_bits_to_der(bits,out,outlen) +#define x509_key_usage_from_der(bits,in,inlen) asn1_bits_from_der(bits,in,inlen) +int x509_key_usage_print(FILE *fp, int fmt, int ind, const char *label, int bits); + +/* +NoticeReference ::= SEQUENCE { + organization DisplayText, + noticeNumbers SEQUENCE OF INTEGER } + +UserNotice ::= SEQUENCE { + noticeRef NoticeReference OPTIONAL, + explicitText DisplayText OPTIONAL } +*/ +#define X509_MAX_NOTICE_NUMBERS 32 + +int x509_notice_reference_to_der( + int org_tag, const uint8_t *org, size_t org_len, + const int *notice_numbers, size_t notice_numbers_cnt, + uint8_t **out, size_t *outlen); +int x509_notice_reference_from_der( + int *org_tag, const uint8_t **org, size_t *org_len, + int *notice_numbers, size_t *notice_numbers_cnt, size_t max_notice_numbers, + const uint8_t **in, size_t *inlen); +int x509_notice_reference_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int x509_user_notice_to_der( + int notice_ref_org_tag, const uint8_t *notice_ref_org, size_t notice_ref_org_len, + const int *notice_ref_notice_numbers, size_t notice_ref_notice_numbers_cnt, + int explicit_text_tag, const uint8_t *explicit_text, size_t explicit_text_len, + uint8_t **out, size_t *outlen); +int x509_user_notice_from_der( + int *notice_ref_org_tag, const uint8_t **notice_ref_org, size_t *notice_ref_org_len, + int *notice_ref_notice_numbers, size_t *notice_ref_notice_numbers_cnt, size_t max_notice_ref_notice_numbers, + int *explicit_text_tag, const uint8_t **explicit_text, size_t *explicit_text_len, + const uint8_t **in, size_t *inlen); +int x509_user_notice_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +PolicyQualifierInfo ::= SEQUENCE { + policyQualifierId PolicyQualifierId, + qualifier ANY DEFINED BY policyQualifierId } + + switch(policyQualifierId) + case id-qt-cps : qualifier ::= IA5String + case id-qt-unotice : qualifier ::= UserNotice +*/ +int x509_policy_qualifier_info_to_der(int oid, + const uint8_t *qualifier, size_t qualifier_len, + uint8_t **out, size_t *outlen); +int x509_policy_qualifier_info_from_der(int *oid, + const uint8_t **qualifier, size_t *qualifier_len, + const uint8_t **in, size_t *inlen); +int x509_policy_qualifier_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +int x509_policy_qualifier_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +PolicyInformation ::= SEQUENCE { + policyIdentifier CertPolicyId, + policyQualifiers SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo OPTIONAL } + +CertPolicyId ::= OBJECT IDENTIFIER -- undefined +*/ + +int x509_policy_information_to_der( + int policy_oid, const uint32_t *policy_nodes, size_t policy_nodes_cnt, + const uint8_t *qualifiers, size_t qualifiers_len, + uint8_t **out, size_t *outlen); +int x509_policy_information_from_der( + int *policy_oid, uint32_t *policy_nodes, size_t *policy_nodes_cnt, + const uint8_t **qualifiers, size_t *qualifiers_len, + const uint8_t **in, size_t *inlen); +int x509_policy_information_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation +*/ +int x509_certificate_policies_add_policy_information(uint8_t *d, size_t *dlen, size_t maxlen, + int policy_oid, const uint32_t *policy_nodes, size_t policy_nodes_cnt, + const uint8_t *qualifiers, size_t qualifiers_len); +int x509_certificate_policies_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +#define x509_certificate_policies_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_certificate_policies_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) + +/* +PolicyMapping ::= SEQUENCE { + issuerDomainPolicy CertPolicyId, + subjectDomainPolicy CertPolicyId } +*/ +int x509_policy_mapping_to_der( + int issuer_policy_oid, const uint32_t *issuer_policy_nodes, size_t issuer_policy_nodes_cnt, + int subject_policy_oid, const uint32_t *subject_policy_nodes, size_t subject_policy_nodes_cnt, + uint8_t **out, size_t *outlen); +int x509_policy_mapping_from_der( + int *issuer_policy_oid, uint32_t *issuer_policy_nodes, size_t *issuer_policy_nodes_cnt, + int *subject_policy_oid, uint32_t *subject_policy_nodes, size_t *subject_policy_nodes_cnt, + const uint8_t **in, size_t *inlen); +int x509_policy_mapping_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +PolicyMappings ::= SEQUENCE OF PolicyMapping +*/ +int x509_policy_mappings_add_policy_mapping(uint8_t *d, size_t *dlen, size_t maxlen, + int issuer_policy_oid, const uint32_t *issuer_policy_nodes, size_t issuer_policy_nodes_cnt, + int subject_policy_oid, const uint32_t *subject_policy_nodes, size_t subject_policy_nodes_cnt); +int x509_policy_mappings_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +#define x509_policy_mappings_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_policy_mappings_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) + +/* +SubjectAltName ::= GeneralNames +*/ +#define x509_subject_alt_name_print(fp,fmt,ind,label,d,dlen) x509_general_names_print(fp,fmt,ind,label,d,dlen) + +/* +IssuerAltName ::= GeneralNames +*/ +#define x509_issuer_alt_name_print(fp,fmt,ind,label,d,dlen) x509_general_names_print(fp,fmt,ind,label,d,dlen) + +/* +SubjectDirectoryAttributes ::= SEQUENCE OF Attribute + +Attribute ::= SEQUENCE { + type OBJECT IDENTIFIER, + values SET OF ANY } +*/ +int x509_attribute_to_der( + const uint32_t *nodes, size_t nodes_cnt, + const uint8_t *values, size_t values_len, + uint8_t **out, size_t *outlen); +int x509_attribute_from_der( + int *oid, uint32_t *nodes, size_t *nodes_cnt, + const uint8_t **values, size_t *values_len, + const uint8_t **in, size_t *inlen); +int x509_attribute_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int x509_attributes_add_attribute(uint8_t *d, size_t *dlen, size_t maxlen, + const uint32_t *nodes, size_t nodes_cnt, + const uint8_t *values, size_t values_len); +int x509_attributes_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +#define x509_attributes_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_attributes_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) + +/* +BasicConstraints ::= SEQUENCE { + cA BOOLEAN DEFAULT FALSE, + pathLenConstraint INTEGER (0..MAX) OPTIONAL } +*/ +int x509_basic_constraints_to_der(int ca, int path_len_cons, uint8_t **out, size_t *outlen); +int x509_basic_constraints_from_der(int *ca, int *path_len_cons, const uint8_t **in, size_t *inlen); +int x509_basic_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +GeneralSubtree ::= SEQUENCE { + base GeneralName, + minimum [0] IMPLICIT BaseDistance DEFAULT 0, + maximum [1] IMPLICIT BaseDistance OPTIONAL } + +BaseDistance ::= INTEGER (0..MAX) +*/ +int x509_general_subtree_to_der( + int base_choice, const uint8_t *base, size_t base_len, + int minimum, int maximum, + uint8_t **out, size_t *outlen); +int x509_general_subtree_from_der( + int *base_choice, const uint8_t **base, size_t *base_len, + int *minimum, int *maximum, + const uint8_t **in, size_t *inlen); +int x509_general_subtree_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree +*/ +int x509_general_subtrees_add_general_subtree(uint8_t *d, size_t *dlen, size_t maxlen, + int base_choice, const uint8_t *base, size_t base_len, + int minimum, int maximum); +int x509_general_subtrees_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +#define x509_general_subtrees_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_general_subtrees_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) + +/* +NameConstraints ::= SEQUENCE { + permittedSubtrees [0] GeneralSubtrees OPTIONAL, + excludedSubtrees [1] GeneralSubtrees OPTIONAL } +*/ +int x509_name_constraints_to_der( + const uint8_t *permitted_subtrees, size_t permitted_subtrees_len, + const uint8_t *excluded_subtrees, size_t excluded_subtrees_len, + uint8_t **out, size_t *outlen); +int x509_name_constraints_from_der( + const uint8_t **permitted_subtrees, size_t *permitted_subtrees_len, + const uint8_t **excluded_subtrees, size_t *excluded_subtrees_len, + const uint8_t **in, size_t *inlen); +int x509_name_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +PolicyConstraints ::= SEQUENCE { + requireExplicitPolicy [0] IMPLICIT SkipCerts OPTIONAL, + inhibitPolicyMapping [1] IMPLICIT SkipCerts OPTIONAL +} + +SkipCerts ::= INTEGER (0..MAX) +*/ +int x509_policy_constraints_to_der(int require_explicit_policy, int inhibit_policy_mapping, uint8_t **out, size_t *outlen); +int x509_policy_constraints_from_der(int *require_explicit_policy, int *inhibit_policy_mapping, const uint8_t **in, size_t *inlen); +int x509_policy_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId +*/ +#define X509_MAX_KEY_PURPOSES 6 +int x509_ext_key_usage_to_der(const int *oids, size_t oids_cnt, uint8_t **out, size_t *outlen); +int x509_ext_key_usage_from_der(int *oids, size_t *oids_cnt, size_t max_cnt, const uint8_t **in, size_t *inlen); +int x509_ext_key_usage_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +ReasonFlags ::= BIT STRING { + unused (0), + keyCompromise (1), + cACompromise (2), + affiliationChanged (3), + superseded (4), + cessationOfOperation (5), + certificateHold (6), + privilegeWithdrawn (7), + aACompromise (8) } +*/ +#define X509_RF_UNUSED (1 << 0) +#define X509_RF_KEY_COMPROMISE (1 << 1) +#define X509_RF_CA_COMPROMISE (1 << 2) +#define X509_RF_AFFILIATION_CHANGED (1 << 3) +#define X509_RF_SUPERSEDED (1 << 4) +#define X509_RF_CESSATION_OF_OPERATION (1 << 5) +#define X509_RF_CERTIFICATE_HOLD (1 << 6) +#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); +int x509_revoke_reasons_print(FILE *fp, int fmt, int ind, const char *label, int bits); + +/* +DistributionPointName ::= CHOICE { + fullName [0] IMPLICIT GeneralNames, -- SEQUENCE OF + nameRelativeToCRLIssuer [1] IMPLICIT RelativeDistinguishedName } -- SET OF +*/ +int x509_distribution_point_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int x509_distribution_point_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label, int choice, const uint8_t *d, size_t dlen); + +/* +DistributionPoint ::= SEQUENCE { + distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL, + reasons [1] IMPLICIT ReasonFlags OPTIONAL, + cRLIssuer [2] IMPLICIT GeneralNames OPTIONAL } +*/ +int x509_distribution_point_to_der( + int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len, + int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len, + uint8_t **out, size_t *outlen); +int x509_distribution_point_from_der( + int *dist_point_choice, const uint8_t **dist_point, size_t *dist_point_len, + int *reasons, const uint8_t **crl_issuer, size_t *crl_issuer_len, + const uint8_t **in, size_t *inlen); +int x509_distribution_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +DistributionPoints ::= SEQUENCE OF DistributionPoint +*/ +int x509_distribution_points_add_distribution_point(uint8_t *d, size_t *dlen, size_t maxlen, + int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len, + int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len); +int x509_distribution_points_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +#define x509_distribution_points_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_distribution_points_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) + +/* +CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint +FreshestCRL ::= CRLDistributionPoints +*/ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/x509_oid.h b/include/gmssl/x509_oid.h new file mode 100644 index 00000000..85d3f24c --- /dev/null +++ b/include/gmssl/x509_oid.h @@ -0,0 +1,148 @@ +/* + * 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. + */ + +#ifndef GMSSL_X509_OID_H +#define GMSSL_X509_OID_H + + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +id-at: + OID_at_name + OID_at_surname + OID_at_given_name + OID_at_initials + OID_at_generation_qualifier + OID_at_common_name + OID_at_locality_name + OID_at_state_or_province_name + OID_at_organization_name + OID_at_organizational_unit_name + OID_at_title + OID_at_dn_qualifier + OID_at_country_name + OID_at_serial_number + OID_at_pseudonym + OID_domain_component +*/ +const char *x509_name_type_name(int oid); +int x509_name_type_from_name(const char *name); +int x509_name_type_from_der(int *oid, const uint8_t **in, size_t *inlen); +int x509_name_type_to_der(int oid, uint8_t **out, size_t *outlen); + +/* +id-ce: + OID_ce_authority_key_identifier + OID_ce_subject_key_identifier + OID_ce_key_usage + OID_ce_certificate_policies + OID_ce_policy_mappings + OID_ce_subject_alt_name + OID_ce_issuer_alt_name + OID_ce_subject_directory_attributes + OID_ce_basic_constraints + OID_ce_name_constraints + OID_ce_policy_constraints + OID_ce_ext_key_usage + OID_ce_crl_distribution_points + OID_ce_inhibit_any_policy + OID_ce_freshest_crl +*/ +const char *x509_ext_type_name(int oid); +int x509_ext_type_from_name(const char *name); +int x509_ext_type_from_der(int *oid, uint32_t *nodes, size_t *nodes_count, const uint8_t **in, size_t *inlen); +int x509_ext_type_to_der(int oid, uint8_t **out, size_t *outlen); + +/* +id-qt + OID_qt_cps + OID_qt_unotice +*/ +const char *x509_qualifier_id_name(int oid); +int x509_qualifier_id_from_name(const char *name); +int x509_qualifier_id_from_der(int *oid, const uint8_t **in, size_t *inlen); +int x509_qualifier_id_to_der(int oid, uint8_t **out, size_t *outlen); + +/* + OID_any_policy +*/ +char *x509_cert_policy_id_name(int oid); +int x509_cert_policy_id_from_name(const char *name); +int x509_cert_policy_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen); +int x509_cert_policy_id_to_der(int oid, const uint32_t *nodes, size_t nodes_cnt, uint8_t **out, size_t *outlen); + +/* +id-kp + OID_kp_server_auth + OID_kp_client_auth + OID_kp_code_signing + OID_kp_email_protection + OID_kp_time_stamping + OID_kp_ocsp_signing +*/ +const char *x509_key_purpose_name(int oid); +const char *x509_key_purpose_text(int oid); +int x509_key_purpose_from_name(const char *name); +int x509_key_purpose_from_der(int *oid, const uint8_t **in, size_t *inlen); +int x509_key_purpose_to_der(int oid, uint8_t **out, size_t *outlen); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/x509_req.h b/include/gmssl/x509_req.h new file mode 100644 index 00000000..2864b658 --- /dev/null +++ b/include/gmssl/x509_req.h @@ -0,0 +1,132 @@ +/* + * 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. + */ + +#ifndef GMSSL_X509_REQ_H +#define GMSSL_X509_REQ_H + + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +from RFC 2986 + +CertificationRequestInfo ::= SEQUENCE { + version INTEGER { v1(0) }, + subject Name, + subjectPKInfo SubjectPublicKeyInfo, + attributes [0] IMPLICIT SET OF Attribute } +*/ +int x509_request_info_to_der(int version, const uint8_t *subject, size_t subject_len, + const SM2_KEY *subject_public_key, const uint8_t *attrs, size_t attrs_len, + uint8_t **out, size_t *outlen); +int x509_request_info_from_der(int *version, const uint8_t **subject, size_t *subject_len, + SM2_KEY *subject_public_key, const uint8_t **attrs, size_t *attrs_len, + const uint8_t **in, size_t *inlen); +int x509_request_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +CertificationRequest ::= SEQUENCE { + certificationRequestInfo CertificationRequestInfo, + signatureAlgorithm AlgorithmIdentifier, + signature BIT STRING } +*/ +int x509_request_to_der( + int version, + const uint8_t *subject, size_t subject_len, + const SM2_KEY *subject_public_key, + const uint8_t *attrs, size_t attrs_len, + int signature_algor, + const uint8_t *sig, size_t siglen, + uint8_t **out, size_t *outlen); +int x509_request_from_der( + int *version, + const uint8_t **subject, size_t *subject_len, + SM2_KEY *subject_public_key, + const uint8_t **attrs, size_t *attrs_len, + int *signature_algor, + const uint8_t **sig, size_t *siglen, + const uint8_t **in, size_t *inlen); +int x509_request_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int x509_req_sign(uint8_t *req, size_t *reqlen, size_t maxlen, + int version, + const uint8_t *subject, size_t subject_len, + const SM2_KEY *subject_public_key, + const uint8_t *attrs, size_t attrs_len, + int signature_algor, + const SM2_KEY *sign_key, const char *signer_id); +int x509_req_verify(const uint8_t *req, size_t reqlen, + const SM2_KEY *sign_pubkey, const char *signer_id) +int x509_req_get_details(const uint8_t *req, size_t reqlen, + int *verison, + const uint8_t **subject, size_t *subject_len, + SM2_KEY *subject_public_key, + 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_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); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/x509_str.h b/include/gmssl/x509_str.h new file mode 100644 index 00000000..82cd7edd --- /dev/null +++ b/include/gmssl/x509_str.h @@ -0,0 +1,105 @@ +/* + * 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. + */ + +#ifndef GMSSL_X509_STR_H +#define GMSSL_X509_STR_H + + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +DirectoryString or DirectoryName + +DirectoryName ::= CHOICE { + teletexString TeletexString (SIZE (1..MAX)), + printableString PrintableString (SIZE (1..MAX)), + universalString UniversalString (SIZE (1..MAX)), + utf8String UTF8String (SIZE (1..MAX)), + bmpString BMPString (SIZE (1..MAX)), +} +*/ +int x509_directory_name_check(int tag, const uint8_t *d, size_t dlen); +int x509_directory_name_check_ex(int tag, const uint8_t *d, size_t dlen, size_t minlen, size_t maxlen); +int x509_directory_name_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int x509_directory_name_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +int x509_explicit_directory_name_to_der(int index, int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int x509_explicit_directory_name_from_der(int index, int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +int x509_directory_name_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen); + + +/* +DisplayText ::= CHOICE { + ia5String IA5String (SIZE (1..200)), + visibleString VisibleString (SIZE (1..200)), + bmpString BMPString (SIZE (1..200)), + utf8String UTF8String (SIZE (1..200)) +} +*/ +#define X509_DISPLAY_TEXT_MIN_LEN 1 +#define X509_DISPLAY_TEXT_MAX_LEN 200 + +int x509_display_text_check(int tag, const uint8_t *d, size_t dlen); +int x509_display_text_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int x509_display_text_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +int x509_display_text_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/zuc.h b/include/gmssl/zuc.h index 49b325cd..630b5351 100644 --- a/include/gmssl/zuc.h +++ b/include/gmssl/zuc.h @@ -70,15 +70,15 @@ typedef uint32_t ZUC_UINT15; typedef uint32_t ZUC_UINT31; typedef uint32_t ZUC_UINT32; -typedef struct ZUC_KEY_st { +typedef struct { ZUC_UINT31 LFSR[16]; ZUC_UINT32 R1; ZUC_UINT32 R2; -} ZUC_KEY; +} ZUC_STATE; -void zuc_set_key(ZUC_KEY *key, const uint8_t user_key[16], const uint8_t iv[16]); -void zuc_generate_keystream(ZUC_KEY *key, size_t nwords, ZUC_UINT32 *words); -ZUC_UINT32 zuc_generate_keyword(ZUC_KEY *key); +void zuc_init(ZUC_STATE *state, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE]); +void zuc_generate_keystream(ZUC_STATE *state, size_t nwords, ZUC_UINT32 *words); +ZUC_UINT32 zuc_generate_keyword(ZUC_STATE *state); typedef struct ZUC_MAC_CTX_st { @@ -91,31 +91,31 @@ typedef struct ZUC_MAC_CTX_st { size_t buflen; } ZUC_MAC_CTX; -void zuc_mac_init(ZUC_MAC_CTX *ctx, const uint8_t key[16], const uint8_t iv[16]); +void zuc_mac_init(ZUC_MAC_CTX *ctx, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE]); void zuc_mac_update(ZUC_MAC_CTX *ctx, const uint8_t *data, size_t len); -void zuc_mac_finish(ZUC_MAC_CTX *ctx, const uint8_t *data, size_t nbits, uint8_t mac[4]); +void zuc_mac_finish(ZUC_MAC_CTX *ctx, const uint8_t *data, size_t nbits, uint8_t mac[ZUC_MAC_SIZE]); void zuc_eea_encrypt(const ZUC_UINT32 *in, ZUC_UINT32 *out, size_t nbits, - const uint8_t key[16], ZUC_UINT32 count, ZUC_UINT5 bearer, + const uint8_t key[ZUC_KEY_SIZE], ZUC_UINT32 count, ZUC_UINT5 bearer, ZUC_BIT direction); ZUC_UINT32 zuc_eia_generate_mac(const ZUC_UINT32 *data, size_t nbits, - const uint8_t user_key[16], ZUC_UINT32 count, ZUC_UINT5 bearer, + const uint8_t key[ZUC_KEY_SIZE], ZUC_UINT32 count, ZUC_UINT5 bearer, ZUC_BIT direction); # define ZUC256_KEY_SIZE 32 -# define ZUC256_IV_SIZE 23 +# define ZUC256_IV_SIZE 23 # define ZUC256_MAC32_SIZE 4 # define ZUC256_MAC64_SIZE 8 # define ZUC256_MAC128_SIZE 16 # define ZUC256_MIN_MAC_SIZE ZUC256_MAC32_SIZE # define ZUC256_MAX_MAC_SIZE ZUC256_MAC128_SIZE -typedef ZUC_KEY ZUC256_KEY; +typedef ZUC_STATE ZUC256_STATE; -void zuc256_set_key(ZUC256_KEY *key, const uint8_t user_key[32], const uint8_t iv[23]); -#define zuc256_generate_keystream(k,n,out) zuc_generate_keystream(k,n,out) -#define zuc256_generate_keyword(k) zuc_generate_keyword(k) +void zuc256_set_state(ZUC256_STATE *state, const uint8_t key[ZUC256_KEY_SIZE], const uint8_t iv[ZUC256_IV_SIZE]); +#define zuc256_generate_keystream(state,nwords,words) zuc_generate_keystream(state,nwords,words) +#define zuc256_generate_keyword(state) zuc_generate_keyword(state) typedef struct ZUC256_MAC_CTX_st { @@ -129,7 +129,8 @@ typedef struct ZUC256_MAC_CTX_st { int macbits; } ZUC256_MAC_CTX; -void zuc256_mac_init(ZUC256_MAC_CTX *ctx, const uint8_t key[32], const uint8_t iv[23], int macbits); +void zuc256_mac_init(ZUC256_MAC_CTX *ctx, const uint8_t key[ZUC256_KEY_SIZE], + const uint8_t iv[ZUC256_IV_SIZE], int macbits); void zuc256_mac_update(ZUC256_MAC_CTX *ctx, const uint8_t *data, size_t len); void zuc256_mac_finish(ZUC256_MAC_CTX *ctx, const uint8_t *data, size_t nbits, uint8_t *mac);