Update X509 name

This commit is contained in:
Zhi Guan
2026-06-19 08:17:04 +08:00
parent 7b18070318
commit 545ea46fdb
5 changed files with 283 additions and 342 deletions

View File

@@ -820,7 +820,7 @@ endif()
#
set(CPACK_PACKAGE_NAME "GmSSL")
set(CPACK_PACKAGE_VENDOR "GmSSL develop team")
set(CPACK_PACKAGE_VERSION "3.2.0-dev.1094")
set(CPACK_PACKAGE_VERSION "3.2.0-dev.1095")
set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md)
set(CPACK_NSIS_MODIFY_PATH ON)
include(CPack)

View File

@@ -214,7 +214,7 @@ int asn1_oid_info_from_der(const ASN1_OID_INFO **info,
#define asn1_implicit_enumerated_from_der(i,val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_IMPLICIT(i),val,in,inlen)
int asn1_string_is_utf8_string(const char *d, size_t dlen);
int asn1_utf8_string_next_code_point(const uint8_t *str, size_t len, const uint8_t **ptr, uint32_t *code_point);
int asn1_utf8_string_code_point_from_bytes(uint32_t *code_point, const uint8_t **in, size_t *inlen);
int asn1_utf8_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen);
int asn1_utf8_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen);
#define asn1_utf8_string_to_der(d,dlen,out,outlen) asn1_utf8_string_to_der_ex(ASN1_TAG_UTF8String,d,dlen,out,outlen)
@@ -223,7 +223,7 @@ int asn1_utf8_string_from_der_ex(int tag, const char **d, size_t *dlen, const ui
#define asn1_implicit_utf8_string_from_der(i,d,dlen,in,inlen) asn1_utf8_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
int asn1_string_is_printable_string(const char *d, size_t dlen);
int asn1_printable_string_next_code_point(const uint8_t *str, size_t len, const uint8_t **ptr, uint32_t *code_point);
int asn1_printable_string_code_point_from_bytes(uint32_t *code_point, const uint8_t **in, size_t *inlen);
int asn1_printable_string_case_ignore_match(const char *a, size_t alen, const char *b, size_t blen);
int asn1_printable_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen);
int asn1_printable_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen);
@@ -233,7 +233,7 @@ int asn1_printable_string_from_der_ex(int tag, const char **d, size_t *dlen, con
#define asn1_implicit_printable_string_from_der(i,d,dlen,in,inlen) asn1_printable_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
int asn1_string_is_ia5_string(const char *d, size_t dlen);
int asn1_ia5_string_next_code_point(const uint8_t *str, size_t len, const uint8_t **ptr, uint32_t *code_point);
int asn1_ia5_string_code_point_from_bytes(uint32_t *code_point, const uint8_t **in, size_t *inlen);
int asn1_ia5_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen);
int asn1_ia5_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen);
#define asn1_ia5_string_to_der(d,dlen,out,outlen) asn1_ia5_string_to_der_ex(ASN1_TAG_IA5String,d,dlen,out,outlen)
@@ -241,8 +241,8 @@ int asn1_ia5_string_from_der_ex(int tag, const char **d, size_t *dlen, const uin
#define asn1_implicit_ia5_string_to_der(i,d,dlen,out,outlen) asn1_ia5_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
#define asn1_implicit_ia5_string_from_der(i,d,dlen,in,inlen) asn1_ia5_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
int asn1_bmp_string_next_code_point(const uint8_t *str, size_t len, const uint8_t **ptr, uint32_t *code_point);
int asn1_universal_string_next_code_point(const uint8_t *str, size_t len, const uint8_t **ptr, uint32_t *code_point);
int asn1_bmp_string_code_point_from_bytes(uint32_t *code_point, const uint8_t **in, size_t *inlen);
int asn1_universal_string_code_point_from_bytes(uint32_t *code_point, const uint8_t **in, size_t *inlen);
int asn1_string_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen);

View File

@@ -18,7 +18,7 @@ extern "C" {
#define GMSSL_VERSION_NUM 30200
#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1094"
#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1095"
int gmssl_version_num(void);
const char *gmssl_version_str(void);

View File

@@ -20,7 +20,7 @@
static int x509_cert_get_authority_key_identifier_keyid(const uint8_t *cert, size_t certlen,
static int x509_cert_get_authority_key_identifier(const uint8_t *cert, size_t certlen,
const uint8_t **keyid, size_t *keyid_len,
const uint8_t **issuer, size_t *issuer_len,
const uint8_t **serial, size_t *serial_len)
@@ -115,12 +115,14 @@ static int x509_signed_is_verified_by_key(const uint8_t *a, size_t alen,
error_print();
return -1;
}
if (x509_key_get_sign_algor(key, &key_sig_alg) != 1) {
if (x509_signed_from_der(&tbs, &tbslen, &sig_alg, &sig, &siglen, &a, &alen) != 1
|| asn1_length_is_zero(alen) != 1) {
error_print();
return -1;
}
if (x509_signed_from_der(&tbs, &tbslen, &sig_alg, &sig, &siglen, &a, &alen) != 1
|| asn1_length_is_zero(alen) != 1) {
// FIXME: 改为 x509_key_support_algor
if (x509_key_get_sign_algor(key, &key_sig_alg) != 1) {
error_print();
return -1;
}
@@ -128,6 +130,8 @@ static int x509_signed_is_verified_by_key(const uint8_t *a, size_t alen,
return 0;
}
// X509_sign/verify 还是默认就使用SM2的默认ID吧
if (key->algor == OID_ec_public_key && key->algor_param == OID_sm2) {
sign_args = (uint8_t *)signer_id;
sign_argslen = signer_id_len;
@@ -140,6 +144,7 @@ static int x509_signed_is_verified_by_key(const uint8_t *a, size_t alen,
return 1;
}
// 其实只要把验证签名的步骤拿出来,就可以重用已有的函数
int x509_cert_is_signed_by_root_ca_cert(const uint8_t *cert, size_t certlen,
const uint8_t *rootcacert, size_t rootcacertlen,
const char *signer_id, size_t signer_id_len)
@@ -182,7 +187,7 @@ int x509_cert_is_signed_by_root_ca_cert(const uint8_t *cert, size_t certlen,
}
// if AKI not exist
if ((ret = x509_cert_get_authority_key_identifier_keyid(cert, certlen,
if ((ret = x509_cert_get_authority_key_identifier(cert, certlen,
&aki, &aki_len, &aki_issuer, &aki_issuer_len, &aki_serial, &aki_serial_len)) < 0) {
error_print();
return -1;
@@ -241,6 +246,9 @@ int x509_cert_is_signed_by_root_ca_cert(const uint8_t *cert, size_t certlen,
error_print();
return -1;
}
// 最后才是verify
// 可以修改一下 x509_signed_verify_ex ,验证失败不都显式打印错误。
return x509_signed_is_verified_by_key(cert, certlen, &public_key, signer_id, signer_id_len);
}
@@ -371,23 +379,34 @@ static int x509_general_names_check(const uint8_t *d, size_t dlen)
int x509_cert_check_subject(const uint8_t *cert, size_t certlen, int cert_type)
{
int ret;
int is_cacert;
int has_subject;
const uint8_t *subject;
size_t subject_len;
const uint8_t *exts;
size_t extslen;
const uint8_t *val;
size_t vlen;
const uint8_t *gns;
size_t gnslen;
int critical;
if (!cert || !certlen) {
error_print();
return -1;
}
if (x509_cert_get_subject(cert, certlen, &subject, &subject_len) != 1) {
error_print();
return -1;
}
if ((has_subject = x509_name_check(subject, subject_len)) < 0) {
error_print();
return -1;
}
if (!has_subject) {
int is_cacert;
const uint8_t *exts;
size_t extslen;
int critical;
const uint8_t *val;
size_t vlen;
const uint8_t *gns;
size_t gnslen;
switch (cert_type) {
case X509_cert_server_auth:
case X509_cert_client_auth:
@@ -405,26 +424,12 @@ int x509_cert_check_subject(const uint8_t *cert, size_t certlen, int cert_type)
return -1;
}
if (x509_cert_get_subject(cert, certlen, &subject, &subject_len) != 1) {
error_print();
return -1;
}
if ((ret = x509_name_check(subject, subject_len)) < 0) {
error_print();
return -1;
}
if (ret == 0) {
if (is_cacert) {
error_print();
return -1;
}
if (x509_cert_get_exts(cert, certlen, &exts, &extslen) != 1) {
error_print();
return -1;
}
if (x509_exts_get_ext_by_oid(exts, extslen, OID_ce_subject_alt_name, &critical, &val, &vlen) != 1) {
if (x509_cert_get_exts(cert, certlen, &exts, &extslen) != 1
|| x509_exts_get_ext_by_oid(exts, extslen, OID_ce_subject_alt_name, &critical, &val, &vlen) != 1) {
error_print();
return -1;
}
@@ -443,153 +448,122 @@ int x509_cert_check_subject(const uint8_t *cert, size_t certlen, int cert_type)
return 1;
}
static int x509_name_string_char_from_bytes(int tag, const uint8_t **in, size_t *inlen, uint32_t *ch)
static int x509_name_string_char_from_bytes(int tag, uint32_t *ch, const uint8_t **in, size_t *inlen)
{
int ret = 1;
const uint8_t *p;
size_t len;
int ret;
if (!in || !*in || !inlen || !ch) {
error_print();
return -1;
}
p = *in;
len = *inlen;
if (*inlen == 0) {
return 0;
}
if (len == 0) {
ret = 0;
} else {
switch (tag) {
case ASN1_TAG_TeletexString:
*ch = p[0];
p++;
len--;
*ch = *(*in)++;
(*inlen)--;
ret = 1;
break;
case ASN1_TAG_PrintableString:
if (asn1_printable_string_next_code_point(*in, *inlen, &p, ch) != 1) {
if ((ret = asn1_printable_string_code_point_from_bytes(ch, in, inlen)) < 0) {
error_print();
return -1;
}
len = *inlen - (size_t)(p - *in);
break;
case ASN1_TAG_IA5String:
if (asn1_ia5_string_next_code_point(*in, *inlen, &p, ch) != 1) {
if ((ret = asn1_ia5_string_code_point_from_bytes(ch, in, inlen)) < 0) {
error_print();
return -1;
}
len = *inlen - (size_t)(p - *in);
break;
case ASN1_TAG_UTF8String:
if (asn1_utf8_string_next_code_point(*in, *inlen, &p, ch) != 1) {
if ((ret = asn1_utf8_string_code_point_from_bytes(ch, in, inlen)) < 0) {
error_print();
return -1;
}
len = *inlen - (size_t)(p - *in);
break;
case ASN1_TAG_BMPString:
if (asn1_bmp_string_next_code_point(*in, *inlen, &p, ch) != 1) {
if ((ret = asn1_bmp_string_code_point_from_bytes(ch, in, inlen)) < 0) {
error_print();
return -1;
}
len = *inlen - (size_t)(p - *in);
break;
case ASN1_TAG_UniversalString:
if (asn1_universal_string_next_code_point(*in, *inlen, &p, ch) != 1) {
if ((ret = asn1_universal_string_code_point_from_bytes(ch, in, inlen)) < 0) {
error_print();
return -1;
}
len = *inlen - (size_t)(p - *in);
break;
default:
ret = 0;
break;
}
error_print();
return -1;
}
if (ret == 1) {
*in = p;
*inlen = len;
}
return ret;
}
static int x509_name_string_next_normalized_code_point(int tag,
const uint8_t *str, size_t len, const uint8_t **ptr, uint32_t *code_point)
static int x509_name_string_skip_spaces(int tag, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *p;
const uint8_t *q;
const uint8_t *end;
size_t qlen;
size_t len;
uint32_t ch;
if (!ptr || !code_point || (!str && len)) {
if (!in || !*in || !inlen) {
error_print();
return -1;
}
if (!str) {
if (*ptr) {
while (*inlen) {
p = *in;
len = *inlen;
if ((ret = x509_name_string_char_from_bytes(tag, &ch, &p, &len)) != 1) {
error_print();
return -1;
}
if (ch != ' ') {
return 1;
}
*in = p;
*inlen = len;
}
return 1;
}
static int x509_name_string_code_point_from_bytes(int tag, uint32_t *code_point,
const uint8_t **in, size_t *inlen)
{
int ret;
uint32_t ch;
if (!code_point || !in || !*in || !inlen) {
error_print();
return -1;
}
if ((ret = x509_name_string_char_from_bytes(tag, &ch, in, inlen)) != 1) {
if (ret == 0) {
return 0;
}
end = str + len;
p = *ptr ? *ptr : str;
if (p < str || p > end) {
error_print();
return -1;
}
while (p < end) {
q = p;
qlen = (size_t)(end - q);
if ((ret = x509_name_string_char_from_bytes(tag, &q, &qlen, &ch)) != 1) {
if (ret == 0) error_print();
return -1;
}
if ('A' <= ch && ch <= 'Z') {
ch += 'a' - 'A';
}
if (ch != ' ') {
if (ch == ' ') {
if (x509_name_string_skip_spaces(tag, in, inlen) != 1) {
error_print();
return -1;
}
if (*inlen == 0) {
return 0;
}
ch = ' ';
}
*code_point = ch;
*ptr = q;
return 1;
}
/* Skip leading spaces and collapse repeated spaces. */
while (q < end) {
const uint8_t *r = q;
size_t rlen = (size_t)(end - r);
if ((ret = x509_name_string_char_from_bytes(tag, &r, &rlen, &ch)) != 1) {
if (ret == 0) error_print();
return -1;
}
if ('A' <= ch && ch <= 'Z') {
ch += 'a' - 'A';
}
if (ch != ' ') {
break;
}
q = r;
}
if (q == end) {
*ptr = end;
return 0;
}
if (p == str) {
p = q;
continue;
}
*code_point = ' ';
*ptr = q;
return 1;
}
*ptr = end;
return 0;
}
static int x509_name_string_normalized_equ(int a_tag, const uint8_t *a, size_t alen,
@@ -597,15 +571,30 @@ static int x509_name_string_normalized_equ(int a_tag, const uint8_t *a, size_t a
{
int a_ret;
int b_ret;
const uint8_t *a_ptr = NULL;
const uint8_t *b_ptr = NULL;
uint32_t a_ch;
uint32_t b_ch;
if ((!a && alen) || (!b && blen)) {
error_print();
return -1;
}
if (alen && x509_name_string_skip_spaces(a_tag, &a, &alen) != 1) {
error_print();
return -1;
}
if (blen && x509_name_string_skip_spaces(b_tag, &b, &blen) != 1) {
error_print();
return -1;
}
for (;;) {
a_ret = x509_name_string_next_normalized_code_point(a_tag, a, alen, &a_ptr, &a_ch);
b_ret = x509_name_string_next_normalized_code_point(b_tag, b, blen, &b_ptr, &b_ch);
if (a_ret < 0 || b_ret < 0) {
a_ret = x509_name_string_code_point_from_bytes(a_tag, &a_ch, &a, &alen);
if (a_ret < 0) {
error_print();
return -1;
}
b_ret = x509_name_string_code_point_from_bytes(b_tag, &b_ch, &b, &blen);
if (b_ret < 0) {
error_print();
return -1;
}
@@ -618,24 +607,6 @@ static int x509_name_string_normalized_equ(int a_tag, const uint8_t *a, size_t a
}
}
static int x509_name_string_tag(int tag)
{
int ret = 0;
switch (tag) {
case ASN1_TAG_TeletexString:
case ASN1_TAG_PrintableString:
case ASN1_TAG_UniversalString:
case ASN1_TAG_UTF8String:
case ASN1_TAG_BMPString:
case ASN1_TAG_IA5String:
ret = 1;
break;
default:
break;
}
return ret;
}
/*
* 这个 _ex 版本和 x509_attr_type_and_value_from_der() 的区别是:
@@ -729,9 +700,12 @@ static int x509_attr_type_and_value_normalized_equ(const uint8_t *a, size_t alen
} else if (a_val_der_len == b_val_der_len
&& memcmp(a_val_der, b_val_der, a_val_der_len) == 0) {
ret = 1;
} else if (x509_name_string_tag(a_tag) && x509_name_string_tag(b_tag)) {
} else if (asn1_tag_is_cstring(a_tag) && asn1_tag_is_cstring(b_tag)) {
ret = x509_name_string_normalized_equ(a_tag, a_val, a_val_len, b_tag, b_val, b_val_len);
if (ret < 0) error_print();
if (ret < 0) {
error_print();
return -1;
}
}
return ret;
}
@@ -760,6 +734,16 @@ end:
return ret;
}
/*
* 统计一个 RDN SET 中和给定 AttributeTypeAndValue 规范化相等的项数。
*
* 例如同一个 RDN 允许包含多个 AVA
* SET {
* commonName = "Alice",
* commonName = " ALICE "
* }
* 如果待匹配的 AVA 是 commonName = "alice",规范化比较会使 count == 2。
*/
static int x509_rdn_count_attr_type_and_value(const uint8_t *rdn, size_t rdnlen,
const uint8_t *ava, size_t avalen, size_t *count)
{
@@ -846,7 +830,7 @@ end:
int x509_name_normalized_equ(const uint8_t *a, size_t alen, const uint8_t *b, size_t blen)
{
int ret = 0;
int ret;
const uint8_t *a_rdn;
const uint8_t *b_rdn;
size_t a_rdn_len;
@@ -860,54 +844,39 @@ int x509_name_normalized_equ(const uint8_t *a, size_t alen, const uint8_t *b, si
if (asn1_set_from_der(&a_rdn, &a_rdn_len, &a, &alen) != 1
|| asn1_set_from_der(&b_rdn, &b_rdn_len, &b, &blen) != 1) {
error_print();
ret = -1;
goto end;
return -1;
}
ret = x509_rdn_normalized_equ(a_rdn, a_rdn_len, b_rdn, b_rdn_len);
if (ret != 1) {
goto end;
if (ret < 0) {
error_print();
return -1;
}
if (ret == 0) {
return 0;
}
}
if (alen || blen) {
ret = 0;
} else {
ret = 1;
return 0;
}
end:
return ret;
return 1;
}
int asn1_utf8_string_next_code_point(const uint8_t *str, size_t len,
const uint8_t **ptr, uint32_t *code_point)
int asn1_utf8_string_code_point_from_bytes(uint32_t *code_point, const uint8_t **in, size_t *inlen)
{
const uint8_t *p;
const uint8_t *end;
size_t rem;
uint32_t cp;
if (!ptr || !code_point || (!str && len)) {
error_print();
return -1;
}
if (!str) {
if (*ptr) {
if (!code_point || !in || !*in || !inlen) {
error_print();
return -1;
}
if (*inlen == 0) {
return 0;
}
end = str + len;
p = *ptr ? *ptr : str;
if (p < str || p > end) {
error_print();
return -1;
}
if (p == end) {
return 0;
}
rem = (size_t)(end - p);
p = *in;
rem = *inlen;
if (p[0] < 0x80) {
cp = p[0];
p++;
@@ -953,123 +922,83 @@ int asn1_utf8_string_next_code_point(const uint8_t *str, size_t len,
}
*code_point = cp;
*ptr = p;
*inlen -= (size_t)(p - *in);
*in = p;
return 1;
}
static int asn1_string_next_code_point_ptr(const uint8_t *str, size_t len,
const uint8_t **ptr, const uint8_t **p, size_t code_point_len)
int asn1_printable_string_code_point_from_bytes(uint32_t *code_point, const uint8_t **in, size_t *inlen)
{
const uint8_t *end;
if (!ptr || !p || !code_point_len || (!str && len)) {
error_print();
return -1;
}
if (!str) {
if (*ptr) {
if (!code_point || !in || !*in || !inlen) {
error_print();
return -1;
}
if (*inlen == 0) {
return 0;
}
end = str + len;
*p = *ptr ? *ptr : str;
if (*p < str || *p > end) {
if (asn1_string_is_printable_string((const char *)*in, 1) != 1) {
error_print();
return -1;
}
if (*p == end) {
*code_point = **in;
(*in)++;
(*inlen)--;
return 1;
}
int asn1_ia5_string_code_point_from_bytes(uint32_t *code_point, const uint8_t **in, size_t *inlen)
{
if (!code_point || !in || !*in || !inlen) {
error_print();
return -1;
}
if (*inlen == 0) {
return 0;
}
if ((size_t)(end - *p) < code_point_len) {
if (asn1_string_is_ia5_string((const char *)*in, 1) != 1) {
error_print();
return -1;
}
*code_point = **in;
(*in)++;
(*inlen)--;
return 1;
}
int asn1_printable_string_next_code_point(const uint8_t *str, size_t len,
const uint8_t **ptr, uint32_t *code_point)
int asn1_bmp_string_code_point_from_bytes(uint32_t *code_point, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *p;
if (!code_point) {
if (!code_point || !in || !*in || !inlen) {
error_print();
return -1;
}
if ((ret = asn1_string_next_code_point_ptr(str, len, ptr, &p, 1)) != 1) {
if (ret < 0) error_print();
return ret;
if (*inlen == 0) {
return 0;
}
if (asn1_string_is_printable_string((const char *)p, 1) != 1) {
if (*inlen < 2 || *inlen % 2) {
error_print();
return -1;
}
*code_point = p[0];
*ptr = p + 1;
*code_point = GETU16(*in);
*in += 2;
*inlen -= 2;
return 1;
}
int asn1_ia5_string_next_code_point(const uint8_t *str, size_t len,
const uint8_t **ptr, uint32_t *code_point)
int asn1_universal_string_code_point_from_bytes(uint32_t *code_point, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *p;
if (!code_point) {
if (!code_point || !in || !*in || !inlen) {
error_print();
return -1;
}
if ((ret = asn1_string_next_code_point_ptr(str, len, ptr, &p, 1)) != 1) {
if (ret < 0) error_print();
return ret;
if (*inlen == 0) {
return 0;
}
if (asn1_string_is_ia5_string((const char *)p, 1) != 1) {
if (*inlen < 4 || *inlen % 4) {
error_print();
return -1;
}
*code_point = p[0];
*ptr = p + 1;
return 1;
}
int asn1_bmp_string_next_code_point(const uint8_t *str, size_t len,
const uint8_t **ptr, uint32_t *code_point)
{
int ret;
const uint8_t *p;
if (!code_point || len % 2) {
error_print();
return -1;
}
if ((ret = asn1_string_next_code_point_ptr(str, len, ptr, &p, 2)) != 1) {
if (ret < 0) error_print();
return ret;
}
*code_point = GETU16(p);
*ptr = p + 2;
return 1;
}
int asn1_universal_string_next_code_point(const uint8_t *str, size_t len,
const uint8_t **ptr, uint32_t *code_point)
{
int ret;
const uint8_t *p;
if (!code_point || len % 4) {
error_print();
return -1;
}
if ((ret = asn1_string_next_code_point_ptr(str, len, ptr, &p, 4)) != 1) {
if (ret < 0) error_print();
return ret;
}
*code_point = GETU32(p);
*ptr = p + 4;
*code_point = GETU32(*in);
*in += 4;
*inlen -= 4;
return 1;
}

View File

@@ -541,7 +541,7 @@ static int test_asn1_utf8_string(void)
return 1;
}
static int test_asn1_string_next_code_point(void)
static int test_asn1_string_code_point_from_bytes(void)
{
const uint8_t utf8[] = {
0x41, 0xe4, 0xb8, 0xad, 0xf0, 0x9f, 0x98, 0x80
@@ -558,67 +558,79 @@ static int test_asn1_string_next_code_point(void)
0x00, 0x00, 0x4e, 0x2d,
};
const uint8_t invalid_universal[] = { 0x00, 0x00, 0x00 };
const uint8_t *p = NULL;
const uint8_t *p;
size_t len;
uint32_t cp;
if (asn1_utf8_string_next_code_point(utf8, sizeof(utf8), &p, &cp) != 1 || cp != 0x41
|| asn1_utf8_string_next_code_point(utf8, sizeof(utf8), &p, &cp) != 1 || cp != 0x4e2d
|| asn1_utf8_string_next_code_point(utf8, sizeof(utf8), &p, &cp) != 1 || cp != 0x1f600
|| asn1_utf8_string_next_code_point(utf8, sizeof(utf8), &p, &cp) != 0) {
p = utf8;
len = sizeof(utf8);
if (asn1_utf8_string_code_point_from_bytes(&cp, &p, &len) != 1 || cp != 0x41
|| asn1_utf8_string_code_point_from_bytes(&cp, &p, &len) != 1 || cp != 0x4e2d
|| asn1_utf8_string_code_point_from_bytes(&cp, &p, &len) != 1 || cp != 0x1f600
|| asn1_utf8_string_code_point_from_bytes(&cp, &p, &len) != 0) {
error_print();
return -1;
}
p = NULL;
if (asn1_utf8_string_next_code_point(invalid_utf8, sizeof(invalid_utf8), &p, &cp) != -1) {
p = invalid_utf8;
len = sizeof(invalid_utf8);
if (asn1_utf8_string_code_point_from_bytes(&cp, &p, &len) != -1) {
error_print();
return -1;
}
p = NULL;
if (asn1_printable_string_next_code_point(printable, sizeof(printable) - 1, &p, &cp) != 1 || cp != 'A'
|| asn1_printable_string_next_code_point(printable, sizeof(printable) - 1, &p, &cp) != 1 || cp != 'z') {
p = printable;
len = sizeof(printable) - 1;
if (asn1_printable_string_code_point_from_bytes(&cp, &p, &len) != 1 || cp != 'A'
|| asn1_printable_string_code_point_from_bytes(&cp, &p, &len) != 1 || cp != 'z') {
error_print();
return -1;
}
p = NULL;
if (asn1_printable_string_next_code_point(invalid_printable, sizeof(invalid_printable) - 1, &p, &cp) != -1) {
p = invalid_printable;
len = sizeof(invalid_printable) - 1;
if (asn1_printable_string_code_point_from_bytes(&cp, &p, &len) != -1) {
error_print();
return -1;
}
p = NULL;
if (asn1_ia5_string_next_code_point(ia5, sizeof(ia5) - 1, &p, &cp) != 1 || cp != 'a') {
p = ia5;
len = sizeof(ia5) - 1;
if (asn1_ia5_string_code_point_from_bytes(&cp, &p, &len) != 1 || cp != 'a') {
error_print();
return -1;
}
p = NULL;
if (asn1_ia5_string_next_code_point(invalid_ia5, sizeof(invalid_ia5), &p, &cp) != -1) {
p = invalid_ia5;
len = sizeof(invalid_ia5);
if (asn1_ia5_string_code_point_from_bytes(&cp, &p, &len) != -1) {
error_print();
return -1;
}
p = NULL;
if (asn1_bmp_string_next_code_point(bmp, sizeof(bmp), &p, &cp) != 1 || cp != 0x41
|| asn1_bmp_string_next_code_point(bmp, sizeof(bmp), &p, &cp) != 1 || cp != 0x4e2d
|| asn1_bmp_string_next_code_point(bmp, sizeof(bmp), &p, &cp) != 0) {
p = bmp;
len = sizeof(bmp);
if (asn1_bmp_string_code_point_from_bytes(&cp, &p, &len) != 1 || cp != 0x41
|| asn1_bmp_string_code_point_from_bytes(&cp, &p, &len) != 1 || cp != 0x4e2d
|| asn1_bmp_string_code_point_from_bytes(&cp, &p, &len) != 0) {
error_print();
return -1;
}
p = NULL;
if (asn1_bmp_string_next_code_point(invalid_bmp, sizeof(invalid_bmp), &p, &cp) != -1) {
p = invalid_bmp;
len = sizeof(invalid_bmp);
if (asn1_bmp_string_code_point_from_bytes(&cp, &p, &len) != -1) {
error_print();
return -1;
}
p = NULL;
if (asn1_universal_string_next_code_point(universal, sizeof(universal), &p, &cp) != 1 || cp != 0x41
|| asn1_universal_string_next_code_point(universal, sizeof(universal), &p, &cp) != 1 || cp != 0x4e2d
|| asn1_universal_string_next_code_point(universal, sizeof(universal), &p, &cp) != 0) {
p = universal;
len = sizeof(universal);
if (asn1_universal_string_code_point_from_bytes(&cp, &p, &len) != 1 || cp != 0x41
|| asn1_universal_string_code_point_from_bytes(&cp, &p, &len) != 1 || cp != 0x4e2d
|| asn1_universal_string_code_point_from_bytes(&cp, &p, &len) != 0) {
error_print();
return -1;
}
p = NULL;
if (asn1_universal_string_next_code_point(invalid_universal, sizeof(invalid_universal), &p, &cp) != -1) {
p = invalid_universal;
len = sizeof(invalid_universal);
if (asn1_universal_string_code_point_from_bytes(&cp, &p, &len) != -1) {
error_print();
return -1;
}
@@ -935,7 +947,7 @@ int main(void)
{
if (test_asn1_tag() != 1) goto err;
if (test_asn1_utf8_string() != 1) goto err;
if (test_asn1_string_next_code_point() != 1) goto err;
if (test_asn1_string_code_point_from_bytes() != 1) goto err;
/*
if (test_asn1_length() != 1) goto err;
if (test_asn1_length_from_ber() != 1) goto err;