Update src

This commit is contained in:
Zhi Guan
2022-02-27 19:09:39 +08:00
parent 7af9f951a2
commit 381bfb5b99
36 changed files with 5884 additions and 7808 deletions

View File

@@ -59,6 +59,9 @@
#include "endian.h"
//FIXME: ENUMERATED 没有支持在CRLReason中用到
/*
## 返回值
@@ -131,7 +134,7 @@ const char *asn1_tag_name(int tag)
return NULL;
}
static int asn1_tag_is_cstring(int tag)
int asn1_tag_is_cstring(int tag)
{
switch (tag) {
case ASN1_TAG_UTF8String:
@@ -167,15 +170,16 @@ int asn1_ia5_string_check(const char *a, size_t alen)
// 还是检查报错比较方便,这样调用的函数更容易实现
// asn.1编解码不考虑效率的问题
void asn1_tag_to_der(int tag, uint8_t **out, size_t *outlen)
int asn1_tag_to_der(int tag, uint8_t **out, size_t *outlen)
{
if (out) {
*(*out)++ = (uint8_t)tag;
}
(*outlen)++;
return 1;
}
void asn1_length_to_der(size_t len, uint8_t **out, size_t *outlen)
int asn1_length_to_der(size_t len, uint8_t **out, size_t *outlen)
{
if (len < 128) {
if (out) {
@@ -200,15 +204,18 @@ void asn1_length_to_der(size_t len, uint8_t **out, size_t *outlen)
}
(*outlen) += 1 + i;
}
return 1;
}
void asn1_data_to_der(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen)
// 提供返回值是为了和其他to_der函数一致
int asn1_data_to_der(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen)
{
if (out) {
memcpy(*out, data, datalen);
*out += datalen;
}
*outlen += datalen;
return 1;
}
int asn1_tag_from_der(int tag, const uint8_t **in, size_t *inlen)
@@ -226,6 +233,15 @@ int asn1_tag_from_der(int tag, const uint8_t **in, size_t *inlen)
return 1;
}
int asn1_tag_get(int *tag, const uint8_t **in, size_t *inlen)
{
if (*inlen == 0) {
return 0;
}
*tag = **in;
return 1;
}
int asn1_length_from_der(size_t *plen, const uint8_t **pin, size_t *pinlen)
{
const uint8_t *in = *pin;
@@ -332,27 +348,6 @@ int asn1_type_from_der(int tag, const uint8_t **data, size_t *datalen, const uin
return 1;
}
int asn1_type_copy_from_der(int tag, size_t maxlen, uint8_t *data, size_t *datalen, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *p;
if ((ret = asn1_tag_from_der(tag, in, inlen)) != 1) {
return ret;
}
if (asn1_length_from_der(datalen, in, inlen) != 1
|| asn1_data_from_der(&p, *datalen, in, inlen) != 1) {
error_print();
return -1;
}
if (*datalen > maxlen) {
error_print();
return -1;
}
memcpy(data, p, *datalen);
return 1;
}
int asn1_any_tag_from_der(int *tag, const uint8_t **in, size_t *inlen)
{
if (*inlen == 0) {
@@ -381,6 +376,11 @@ int asn1_any_type_from_der(int *tag, const uint8_t **data, size_t *datalen, cons
return 1;
}
int asn1_any_to_der(const uint8_t *tlv, size_t tlvlen, uint8_t **out, size_t *outlen)
{
return asn1_data_to_der(tlv, tlvlen, out, outlen);
}
int asn1_any_from_der(const uint8_t **tlv, size_t *tlvlen, const uint8_t **in, size_t *inlen)
{
int ret;
@@ -400,6 +400,9 @@ int asn1_any_from_der(const uint8_t **tlv, size_t *tlvlen, const uint8_t **in, s
//////////////////////////////////////////////////////////////////////////////////////////////////////////
#define ASN1_TRUE 0xff
#define ASN1_FALSE 0x00
int asn1_boolean_to_der_ex(int tag, int val, uint8_t **out, size_t *outlen)
{
if ((out && !(*out)) || !outlen) {
@@ -497,6 +500,12 @@ int asn1_bit_string_to_der_ex(int tag, const uint8_t *bits, size_t nbits, uint8_
return 1;
}
int asn1_bit_octets_to_der_ex(int tag, const uint8_t *octs, size_t nocts, uint8_t **out, size_t *outlen)
{
return asn1_bit_string_to_der_ex(tag, octs, nocts << 3, out, outlen);
}
int asn1_bits_to_der_ex(int tag, int bits, uint8_t **out, size_t *outlen)
{
size_t nbits = 0;
@@ -534,7 +543,122 @@ int asn1_null_to_der(uint8_t **out, size_t *outlen)
return 1;
}
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)
static void asn1_oid_node_to_base128(uint32_t a, uint8_t **out, size_t *outlen)
{
uint8_t buf[5];
int n = 0;
buf[n++] = a & 0x7f;
a >>= 7;
while (a) {
buf[n++] = 0x80 | (a & 0x7f);
a >>= 7;
}
while (n--) {
if (out)
*(*out)++ = buf[n];
(*outlen)++;
}
}
// 实际上我们在解析的时候是不知道具体在哪里结束的
// 解析是有可能出错的如果没有发现最后一个0开头的字节就出错了
// 还有值太大也会出错我们最多读取5个字节
// { 0x81, 0x82 }
// { 0x81, 0x82, 0x83, 0x84, 0x85, 0x06 }
static int asn1_oid_node_from_base128(uint32_t *a, const uint8_t **in, size_t *inlen)
{
uint8_t buf[5];
int n = 0;
int i;
for (;;) {
if ((*inlen)-- < 1 || n >= 5) {
return -1;
}
buf[n] = *(*in)++;
if ((buf[n++] & 0x80) == 0) {
break;
}
}
// 32 - 7*4 = 4, so the first byte should be like 1000bbbb
if (n == 5 && (buf[0] & 0x70)) {
return -1;
}
*a = 0;
for (i = 0; i < n; i++) {
*a = ((*a) << 7) | (buf[i] & 0x7f);
}
return 1;
}
int asn1_oid_nodes_to_octets(const uint32_t *nodes, size_t nodes_cnt, uint8_t *out, size_t *outlen)
{
if (nodes_cnt < 2 || nodes_cnt > 32) {
return -1;
}
if (out)
*out++ = (uint8_t)(nodes[0] * 40 + nodes[1]);
(*outlen) = 1;
nodes += 2;
nodes_cnt -= 2;
while (nodes_cnt--) {
asn1_oid_node_to_base128(*nodes++, &out, outlen);
}
return 1;
}
// 因为这个函数总是被asn1函数调用的因此给的输入数据长度是已知的
int asn1_object_identifier_from_octets(uint32_t *nodes, size_t *nodes_cnt, const uint8_t *in, size_t inlen)
{
size_t count = 0;
const uint8_t *p = in;
size_t len = inlen;
if (!nodes || !nodes_cnt || !in || inlen <= 0) {
error_print();
return -1;
}
if (inlen < 1) {
error_print();
return -1;
}
// FIXME: 需要支持 nodes = NULL 吗?
if (nodes) {
*nodes++ = (*in) / 40;
*nodes++ = (*in) % 40;
}
in++;
inlen--;
count += 2;
while (inlen) {
uint32_t val;
if (count > 32) {
return -1;
}
if (asn1_oid_node_from_base128(&val, &in, &inlen) < 0) {
return -1;
}
if (nodes) {
*nodes++ = val;
}
count++;
}
*nodes_cnt = count;
return 1;
}
int asn1_object_identifier_to_der_ex(int tag, const uint32_t *nodes, size_t nodes_cnt, uint8_t **out, size_t *outlen)
{
uint8_t octets[32];
size_t octetslen = 0;
@@ -547,9 +671,7 @@ int asn1_object_identifier_to_der_ex(int tag, int oid, const uint32_t *nodes, si
*(*out)++ = tag;
(*outlen)++;
if (oid != OID_undef)
asn1_oid_to_octets(oid, octets, &octetslen);
else asn1_oid_nodes_to_octets(nodes, nodes_count, octets, &octetslen);
asn1_oid_nodes_to_octets(nodes, nodes_cnt, octets, &octetslen);
asn1_length_to_der(octetslen, out, outlen);
@@ -562,19 +684,94 @@ int asn1_object_identifier_to_der_ex(int tag, int oid, const uint32_t *nodes, si
return 1;
}
int asn1_utf8_string_to_der_ex(int tag, const char *a, uint8_t **out, size_t *outlen)
const ASN1_OID_INFO *asn1_oid_info_from_name(const ASN1_OID_INFO *infos, size_t count, const char *name)
{
return asn1_type_to_der(tag, (const uint8_t *)a, strlen(a), out, outlen);
size_t i;
for (i = 0; i < count; i++) {
if (strcmp(infos[i].name, name) == 0) {
return &infos[i];
}
}
return NULL;
}
int asn1_printable_string_to_der_ex(int tag, const char *a, uint8_t **out, size_t *outlen)
const ASN1_OID_INFO *asn1_oid_info_from_oid(const ASN1_OID_INFO *infos, size_t count, int oid)
{
return asn1_type_to_der(tag, (const uint8_t *)a, strlen(a), out, outlen);
size_t i;
for (i = 0; i < count; i++) {
if (infos[i].oid == oid) {
return &infos[i];
}
}
return NULL;
}
int asn1_ia5_string_to_der_ex(int tag, const char *a, uint8_t **out, size_t *outlen)
// 这个函数可以支持未知的OID通常只有在print或者解析Extensions时需要调用该函数
// 注意:函数有特殊返回值
int asn1_oid_info_from_der_ex(const ASN1_OID_INFO **info, uint32_t *nodes, size_t *nodes_cnt,
const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen)
{
return asn1_type_to_der(tag, (const uint8_t *)a, strlen(a), out, outlen);
int ret;
size_t i;
if ((ret = asn1_object_identifier_from_der(nodes, nodes_cnt, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
*info = NULL;
for (i = 0; i < count; i++) {
if (*nodes_cnt == infos[i].nodes_cnt
&& memcmp(nodes, infos[i].nodes, (*nodes_cnt) * sizeof(int)) == 0) {
*info = &infos[i];
return 1;
}
}
return 2; // 返回非1的正整数表示OID格式正确但是不在给定列表中
}
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 ret;
uint32_t nodes[32];
size_t nodes_cnt;
if ((ret = asn1_oid_info_from_der_ex(info, nodes, &nodes_cnt, infos, count, in, inlen)) < 0) {
error_print();
return -1;
} else if (ret > 1) {
error_print();
return -1;
}
return ret;
}
// asn1_oid_from_octets 不返回错误值,只返回 OID_undef
// 但是数据编码仍可能是非法的
// 如果返回 OID_undef需要通过 asn1_object_identifier_from_octets 判断格式是否正确
// 显然这个函数并不合适因为在整个gmssl中我们不提供完整的ASN.1数据库无法从一个OID中给出解析
int asn1_utf8_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen)
{
return asn1_type_to_der(tag, (const uint8_t *)d, dlen, out, outlen);
}
int asn1_printable_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen)
{
return asn1_type_to_der(tag, (const uint8_t *)d, dlen, out, outlen);
}
int asn1_ia5_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen)
{
return asn1_type_to_der(tag, (const uint8_t *)d, dlen, out, outlen);
}
int asn1_utc_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen)
@@ -792,6 +989,23 @@ int asn1_bit_string_from_der_ex(int tag, const uint8_t **bits, size_t *nbits, co
return 1;
}
int asn1_bit_octets_from_der_ex(int tag, const uint8_t **octs, size_t *nocts, const uint8_t **in, size_t *inlen)
{
int ret;
size_t nbits;
if ((ret = asn1_bit_string_from_der_ex(tag, octs, &nbits, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (nbits % 8) {
error_print();
return -1;
}
*nocts = nbits >> 3;
return 1;
}
int asn1_bits_from_der_ex(int tag, int *bits, const uint8_t **in, size_t *inlen)
{
int ret;
@@ -836,15 +1050,14 @@ int asn1_null_from_der(const uint8_t **in, size_t *inlen)
return 1;
}
// FIXME这个函数应该最终取消返回oid
int asn1_object_identifier_from_der_ex(int tag, int *oid, uint32_t nodes[32], size_t *nodes_count,
int asn1_object_identifier_from_der_ex(int tag, uint32_t *nodes, size_t *nodes_cnt,
const uint8_t **pin, size_t *pinlen)
{
const uint8_t *in = *pin;
size_t inlen = *pinlen;
size_t len;
if (!nodes || !nodes_count || !pin || !(*pin) || !pinlen) {
if (!nodes || !nodes_cnt || !pin || !(*pin) || !pinlen) {
error_print();
return -1;
}
@@ -858,14 +1071,10 @@ int asn1_object_identifier_from_der_ex(int tag, int *oid, uint32_t nodes[32], si
error_print();
return -1;
}
// 由于 asn1_oid_from_der 无法判断不识别的 OID 数据编码是否正确,因此必须先解码
if (asn1_oid_nodes_from_octets(nodes, nodes_count, in, len) < 0) {
if (asn1_object_identifier_from_octets(nodes, nodes_cnt, in, len) != 1) {
error_print();
return -1;
}
if (oid) {
*oid = asn1_oid_from_octets(in, len);
}
*pin = in + len;
*pinlen = inlen - len;
return 1;
@@ -1015,47 +1224,6 @@ int asn1_generalized_time_from_der_ex(int tag, time_t *t, const uint8_t **pin, s
return 1;
}
// 其中的每一个data/datalen都是一个ASN1的TLV因此我们可以去解析
int asn1_sequence_of_get_next_item(const ASN1_SEQUENCE_OF *a, const uint8_t **next, const uint8_t **data, size_t *datalen)
{
int ret;
size_t len;
int tag;
const uint8_t *value;
size_t valuelen;
if (*next == NULL) {
*next = a->data;
}
if (*next < a->data || *next > a->data + a->datalen) {
error_print();
return -1;
}
*data = *next;
len = a->data + a->datalen - *next;
ret = asn1_any_type_from_der(&tag, &value, &valuelen, next, &len);
if (ret < 0) error_print();
*datalen = *next - *data;
return ret;
}
int asn1_sequence_of_get_count(const ASN1_SEQUENCE_OF *a, size_t *count)
{
int ret;
const uint8_t *next = NULL;
const uint8_t *data;
size_t datalen;
*count = 0;
while ((ret = asn1_sequence_of_get_next_item(a, &next, &data, &datalen)) == 1) {
(*count)++;
}
if (ret < 0) {
error_print();
return -1;
}
return 1;
}
int asn1_check(int expr)
{
@@ -1068,8 +1236,146 @@ int asn1_check(int expr)
int asn1_length_is_zero(size_t len)
{
if (len) {
error_print();
return -1;
}
return 1;
}
int asn1_length_le(size_t len1, size_t len2)
{
if (len1 > len2) {
error_print();
return -1;
}
return 1;
}
int asn1_object_identifier_equ(const uint32_t *a, size_t a_cnt, const uint32_t *b, size_t b_cnt)
{
if (a_cnt != b_cnt
|| memcmp(a, b, b_cnt * sizeof(uint32_t)) != 0) {
error_print();
return 0;
}
return 1;
}
int asn1_sequence_of_int_to_der(const int *nums, size_t nums_cnt, uint8_t **out, size_t *outlen)
{
size_t len = 0;
size_t i;
for (i = 0; i < nums_cnt; i++) {
if (asn1_int_to_der(nums[i], NULL, &len) != 1) {
error_print();
return -1;
}
}
if (asn1_sequence_header_to_der(len, out, outlen) != 1) {
error_print();
return -1;
}
for (i = 0; i < nums_cnt; i++) {
if (asn1_int_to_der(nums[i], out, outlen) != 1) {
error_print();
return -1;
}
}
return 1;
}
int asn1_sequence_of_int_from_der(int *nums, size_t *nums_cnt, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *d;
size_t dlen;
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
*nums_cnt = 0;
while (dlen) {
int num;
if (asn1_int_from_der(&num, &d, &dlen) != 1) {
error_print();
return -1;
}
if (nums) {
*nums++ = num;
}
(*nums_cnt)++;
}
return 1;
}
int asn1_sequence_of_int_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
return -1;
}
int asn1_object_identifier_print(FILE *fp, int format, int indent, const char *label, const char *name,
const uint32_t *nodes, size_t nodes_cnt)
{
size_t i;
format_print(fp, format, indent, "%s: %s (", label, name);
for (i = 0; i < nodes_cnt - 1; i++) {
fprintf(fp, "%d.", (int)nodes[i]);
}
fprintf(fp, "%d)\n", nodes[i]);
return 1;
}
int asn1_string_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen)
{
format_print(fp, fmt, ind, "%s: ", label);
while (dlen--) {
fprintf(fp, "%c", *d++);
}
fprintf(fp, "\n");
return 1;
}
int asn1_bits_print(FILE *fp, int fmt, int ind, const char *label, const char **names, size_t names_cnt, int bits)
{
size_t i;
format_print(fp, fmt, ind, "%s: ", label);
for (i = 0; i < names_cnt; i++) {
if (bits & 0x01)
fprintf(fp, "%s", names[i]);
bits >>= 1;
if (bits)
fprintf(fp, ", ");
}
fprintf(fp, "\n");
if (bits) {
error_print();
return -1;
}
return 1;
}
int asn1_types_get_count(const uint8_t *d, size_t dlen, int tag, size_t *cnt)
{
error_print();
return -1;
}
int asn1_types_get_item_by_index(const uint8_t *d, size_t *dlen, int tag,
int index, const uint8_t **item_d, size_t *item_dlen)
{
error_print();
return -1;
}