mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-08-07 21:53:41 +08:00
Add checking to ASN.1 IA5, UTF8, Printable strings
This commit is contained in:
@@ -169,7 +169,6 @@ int asn1_object_identifier_print(FILE *fp, int fmt, int ind, const char *label,
|
|||||||
#define asn1_implicit_enumerated_to_der(i,val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen)
|
#define asn1_implicit_enumerated_to_der(i,val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen)
|
||||||
#define asn1_implicit_enumerated_from_der(i,val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_IMPLICIT(i),val,in,inlen)
|
#define asn1_implicit_enumerated_from_der(i,val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_IMPLICIT(i),val,in,inlen)
|
||||||
|
|
||||||
int asn1_utf8_string_check(const char *d, size_t dlen);
|
|
||||||
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_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);
|
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)
|
#define asn1_utf8_string_to_der(d,dlen,out,outlen) asn1_utf8_string_to_der_ex(ASN1_TAG_UTF8String,d,dlen,out,outlen)
|
||||||
@@ -177,7 +176,6 @@ int asn1_utf8_string_from_der_ex(int tag, const char **d, size_t *dlen, const ui
|
|||||||
#define asn1_implicit_utf8_string_to_der(i,d,dlen,out,outlen) asn1_utf8_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
|
#define asn1_implicit_utf8_string_to_der(i,d,dlen,out,outlen) asn1_utf8_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
|
||||||
#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)
|
#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_printable_string_check(const char *d, size_t dlen);
|
|
||||||
int asn1_printable_string_case_ignore_match(const char *a, size_t alen, const char *b, size_t blen);
|
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_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);
|
int asn1_printable_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen);
|
||||||
@@ -186,7 +184,6 @@ int asn1_printable_string_from_der_ex(int tag, const char **d, size_t *dlen, con
|
|||||||
#define asn1_implicit_printable_string_to_der(i,d,dlen,out,outlen) asn1_printable_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
|
#define asn1_implicit_printable_string_to_der(i,d,dlen,out,outlen) asn1_printable_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
|
||||||
#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)
|
#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_ia5_string_check(const char *d, size_t dlen);
|
|
||||||
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_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);
|
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)
|
#define asn1_ia5_string_to_der(d,dlen,out,outlen) asn1_ia5_string_to_der_ex(ASN1_TAG_IA5String,d,dlen,out,outlen)
|
||||||
@@ -194,6 +191,10 @@ 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_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)
|
#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_string_is_printable_string(const char *d, size_t dlen);
|
||||||
|
int asn1_string_is_ia5_string(const char *d, size_t dlen);
|
||||||
|
int asn1_string_is_utf8_string(const char *d, size_t dlen);
|
||||||
int asn1_string_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen);
|
int asn1_string_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen);
|
||||||
|
|
||||||
#define ASN1_UTC_TIME_LEN (sizeof("YYMMDDHHMMSSZ")-1)
|
#define ASN1_UTC_TIME_LEN (sizeof("YYMMDDHHMMSSZ")-1)
|
||||||
|
|||||||
131
src/asn1.c
131
src/asn1.c
@@ -113,12 +113,73 @@ int asn1_tag_is_cstring(int tag)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int asn1_utf8_string_check(const char *a, size_t alen)
|
/*
|
||||||
|
utf-8 character encoding
|
||||||
|
1-byte: 0xxxxxxx
|
||||||
|
2-byte: 110xxxxx 10xxxxxx
|
||||||
|
3-byte: 1110xxxx 10xxxxxx 10xxxxxx
|
||||||
|
4-byte: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||||
|
*/
|
||||||
|
int asn1_utf8char_from_bytes(uint32_t *c, const uint8_t **pin, size_t *pinlen)
|
||||||
{
|
{
|
||||||
|
uint32_t utf8char;
|
||||||
|
const uint8_t *in = *pin;
|
||||||
|
size_t inlen = *pinlen;
|
||||||
|
uint32_t utf8char_len, i;
|
||||||
|
|
||||||
|
if (!inlen) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((in[0] & 0x80) == 0x00) {
|
||||||
|
utf8char_len = 1;
|
||||||
|
} else if ((in[0] & 0xe0) == 0xc0) {
|
||||||
|
utf8char_len = 2;
|
||||||
|
} else if ((in[0] & 0xf0) == 0xe0) {
|
||||||
|
utf8char_len = 3;
|
||||||
|
} else if ((in[0] & 0xf8) == 0xf0) {
|
||||||
|
utf8char_len = 4;
|
||||||
|
} else {
|
||||||
|
//error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inlen < utf8char_len) {
|
||||||
|
//error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
utf8char = in[0];
|
||||||
|
for (i = 1; i < utf8char_len; i++) {
|
||||||
|
if ((in[i] & 0x60) != 0x80) {
|
||||||
|
//error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
utf8char = (utf8char << 8) | in[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
*c = utf8char;
|
||||||
|
(*pin) += utf8char_len;
|
||||||
|
(*pinlen) -= utf8char_len;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int asn1_char_is_printable(int a)
|
int asn1_string_is_utf8_string(const char *a, size_t alen)
|
||||||
|
{
|
||||||
|
uint32_t utf8char;
|
||||||
|
|
||||||
|
if (!a || !alen) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while (alen) {
|
||||||
|
if (asn1_utf8char_from_bytes(&utf8char, (const uint8_t **)&a, &alen) != 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int asn1_char_is_printable(int a)
|
||||||
{
|
{
|
||||||
if (isalpha(a) || isdigit(a)) {
|
if (isalpha(a) || isdigit(a)) {
|
||||||
return 1;
|
return 1;
|
||||||
@@ -132,6 +193,7 @@ static int asn1_char_is_printable(int a)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
int asn1_printable_string_check(const char *a, size_t alen)
|
int asn1_printable_string_check(const char *a, size_t alen)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
@@ -143,6 +205,18 @@ int asn1_printable_string_check(const char *a, size_t alen)
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
int asn1_string_is_printable_string(const char *a, size_t alen)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < alen; i++) {
|
||||||
|
if (asn1_char_is_printable(a[i]) != 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int asn1_printable_string_case_ignore_match(const char *a, size_t alen,
|
int asn1_printable_string_case_ignore_match(const char *a, size_t alen,
|
||||||
const char *b, size_t blen)
|
const char *b, size_t blen)
|
||||||
@@ -177,8 +251,14 @@ int asn1_printable_string_case_ignore_match(const char *a, size_t alen,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int asn1_ia5_string_check(const char *a, size_t alen)
|
int asn1_string_is_ia5_string(const char *a, size_t alen)
|
||||||
{
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < alen; i++) {
|
||||||
|
if (!isascii(a[i])) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1314,17 +1394,56 @@ int asn1_string_from_der(int tag, const char **a, size_t *alen, const uint8_t **
|
|||||||
|
|
||||||
int asn1_utf8_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen)
|
int asn1_utf8_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen)
|
||||||
{
|
{
|
||||||
return asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen);
|
int ret;
|
||||||
|
if ((ret = asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen)) != 1) {
|
||||||
|
if (ret < 0) error_print();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (!(*a) || !(*alen)) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (asn1_string_is_utf8_string(*a, *alen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int asn1_printable_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen)
|
int asn1_printable_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen)
|
||||||
{
|
{
|
||||||
return asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen);
|
int ret;
|
||||||
|
if ((ret = asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen)) != 1) {
|
||||||
|
if (ret < 0) error_print();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (!(*a) || !(*alen)) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (asn1_string_is_printable_string(*a, *alen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int asn1_ia5_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen)
|
int asn1_ia5_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen)
|
||||||
{
|
{
|
||||||
return asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen);
|
int ret;
|
||||||
|
if ((ret = asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen)) != 1) {
|
||||||
|
if (ret < 0) error_print();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (!(*a) || !(*alen)) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (asn1_string_is_ia5_string(*a, *alen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int asn1_utc_time_from_der_ex(int tag, time_t *t, const uint8_t **pin, size_t *pinlen)
|
int asn1_utc_time_from_der_ex(int tag, time_t *t, const uint8_t **pin, size_t *pinlen)
|
||||||
|
|||||||
@@ -528,7 +528,7 @@ static size_t _strlen(const char *s) { return s ? strlen(s) : 0; }
|
|||||||
static int x509_name_tag(const char *str)
|
static int x509_name_tag(const char *str)
|
||||||
{
|
{
|
||||||
if (str) {
|
if (str) {
|
||||||
if (asn1_printable_string_check(str, strlen(str)) == 1)
|
if (asn1_string_is_printable_string(str, strlen(str)) == 1)
|
||||||
return ASN1_TAG_PrintableString;
|
return ASN1_TAG_PrintableString;
|
||||||
else return ASN1_TAG_UTF8String;
|
else return ASN1_TAG_UTF8String;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
|
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
* not use this file except in compliance with the License.
|
* not use this file except in compliance with the License.
|
||||||
@@ -527,7 +527,7 @@ int x509_general_names_add_general_name(uint8_t *gns, size_t *gnslen, size_t max
|
|||||||
case X509_gn_rfc822_name:
|
case X509_gn_rfc822_name:
|
||||||
case X509_gn_dns_name:
|
case X509_gn_dns_name:
|
||||||
case X509_gn_uniform_resource_identifier:
|
case X509_gn_uniform_resource_identifier:
|
||||||
if (asn1_ia5_string_check((char *)d, dlen) != 1) {
|
if (asn1_string_is_ia5_string((char *)d, dlen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ static int test_asn1_printable_string(void)
|
|||||||
char *tests[] = {
|
char *tests[] = {
|
||||||
"hello",
|
"hello",
|
||||||
"world",
|
"world",
|
||||||
"Just do it!",
|
"Just do it", // string "Just do it!" include invalid '!'
|
||||||
};
|
};
|
||||||
uint8_t buf[256];
|
uint8_t buf[256];
|
||||||
uint8_t *p = buf;
|
uint8_t *p = buf;
|
||||||
@@ -408,12 +408,12 @@ static int test_asn1_printable_string(void)
|
|||||||
static int test_asn1_printable_string_check(void)
|
static int test_asn1_printable_string_check(void)
|
||||||
{
|
{
|
||||||
char *printable_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '()+,-./:=?";
|
char *printable_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '()+,-./:=?";
|
||||||
if (asn1_printable_string_check(printable_str, strlen(printable_str)) != 1) {
|
if (asn1_string_is_printable_string(printable_str, strlen(printable_str)) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (asn1_printable_string_check("a*b", 3) == 1) {
|
if (asn1_string_is_printable_string("a*b", 3) == 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user