make printablestring and ia5string octetstrings
This commit is contained in:
@@ -20,8 +20,8 @@ typedef struct heim_octet_string {
|
|||||||
|
|
||||||
typedef char *heim_general_string;
|
typedef char *heim_general_string;
|
||||||
typedef char *heim_utf8_string;
|
typedef char *heim_utf8_string;
|
||||||
typedef char *heim_printable_string;
|
typedef struct heim_octet_string heim_printable_string;
|
||||||
typedef char *heim_ia5_string;
|
typedef struct heim_octet_string heim_ia5_string;
|
||||||
|
|
||||||
typedef struct heim_bmp_string {
|
typedef struct heim_bmp_string {
|
||||||
size_t length;
|
size_t length;
|
||||||
|
@@ -181,11 +181,33 @@ loop (unsigned char *buf, size_t len, int indent)
|
|||||||
free (str.data);
|
free (str.data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case UT_IA5String :
|
||||||
|
case UT_PrintableString : {
|
||||||
|
heim_printable_string str;
|
||||||
|
unsigned char *s;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
memset(&str, 0, sizeof(str));
|
||||||
|
|
||||||
|
ret = der_get_printable_string (buf, length, &str, NULL);
|
||||||
|
if (ret)
|
||||||
|
errx (1, "der_get_general_string: %s",
|
||||||
|
error_message (ret));
|
||||||
|
s = str.data;
|
||||||
|
printf("\"");
|
||||||
|
for (n = 0; n < str.length; n++) {
|
||||||
|
if (isprint((int)s[n]))
|
||||||
|
printf ("%c", s[n]);
|
||||||
|
else
|
||||||
|
printf ("#%02x", s[n]);
|
||||||
|
}
|
||||||
|
printf("\"\n");
|
||||||
|
der_free_printable_string(&str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case UT_GeneralizedTime :
|
case UT_GeneralizedTime :
|
||||||
case UT_GeneralString :
|
case UT_GeneralString :
|
||||||
case UT_PrintableString :
|
|
||||||
case UT_VisibleString :
|
case UT_VisibleString :
|
||||||
case UT_IA5String :
|
|
||||||
case UT_UTF8String : {
|
case UT_UTF8String : {
|
||||||
heim_general_string str;
|
heim_general_string str;
|
||||||
|
|
||||||
|
@@ -352,12 +352,14 @@ test_Name (void)
|
|||||||
atv1[0].type.length = sizeof(cmp_CN)/sizeof(cmp_CN[0]);
|
atv1[0].type.length = sizeof(cmp_CN)/sizeof(cmp_CN[0]);
|
||||||
atv1[0].type.components = cmp_CN;
|
atv1[0].type.components = cmp_CN;
|
||||||
atv1[0].value.element = choice_DirectoryString_printableString;
|
atv1[0].value.element = choice_DirectoryString_printableString;
|
||||||
atv1[0].value.u.printableString = "Love";
|
atv1[0].value.u.printableString.data = "Love";
|
||||||
|
atv1[0].value.u.printableString.length = 4;
|
||||||
|
|
||||||
atv1[1].type.length = sizeof(cmp_L)/sizeof(cmp_L[0]);
|
atv1[1].type.length = sizeof(cmp_L)/sizeof(cmp_L[0]);
|
||||||
atv1[1].type.components = cmp_L;
|
atv1[1].type.components = cmp_L;
|
||||||
atv1[1].value.element = choice_DirectoryString_printableString;
|
atv1[1].value.element = choice_DirectoryString_printableString;
|
||||||
atv1[1].value.u.printableString = "STOCKHOLM";
|
atv1[1].value.u.printableString.data = "STOCKHOLM";
|
||||||
|
atv1[1].value.u.printableString.length = 9;
|
||||||
|
|
||||||
/* n2 */
|
/* n2 */
|
||||||
n2.element = choice_Name_rdnSequence;
|
n2.element = choice_Name_rdnSequence;
|
||||||
@@ -369,12 +371,14 @@ test_Name (void)
|
|||||||
atv2[0].type.length = sizeof(cmp_L)/sizeof(cmp_L[0]);
|
atv2[0].type.length = sizeof(cmp_L)/sizeof(cmp_L[0]);
|
||||||
atv2[0].type.components = cmp_L;
|
atv2[0].type.components = cmp_L;
|
||||||
atv2[0].value.element = choice_DirectoryString_printableString;
|
atv2[0].value.element = choice_DirectoryString_printableString;
|
||||||
atv2[0].value.u.printableString = "STOCKHOLM";
|
atv2[0].value.u.printableString.data = "STOCKHOLM";
|
||||||
|
atv2[0].value.u.printableString.length = 9;
|
||||||
|
|
||||||
atv2[1].type.length = sizeof(cmp_CN)/sizeof(cmp_CN[0]);
|
atv2[1].type.length = sizeof(cmp_CN)/sizeof(cmp_CN[0]);
|
||||||
atv2[1].type.components = cmp_CN;
|
atv2[1].type.components = cmp_CN;
|
||||||
atv2[1].value.element = choice_DirectoryString_printableString;
|
atv2[1].value.element = choice_DirectoryString_printableString;
|
||||||
atv2[1].value.u.printableString = "Love";
|
atv2[1].value.u.printableString.data = "Love";
|
||||||
|
atv2[1].value.u.printableString.length = 4;
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
tests[0].val = &n1;
|
tests[0].val = &n1;
|
||||||
|
@@ -52,6 +52,20 @@ der_heim_octet_string_cmp(const heim_octet_string *p,
|
|||||||
return memcmp(p->data, q->data, p->length);
|
return memcmp(p->data, q->data, p->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
der_printable_string_cmp(const heim_printable_string *p,
|
||||||
|
const heim_printable_string *q)
|
||||||
|
{
|
||||||
|
return der_heim_octet_string_cmp(q, q);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
der_ia5_string_cmp(const heim_ia5_string *p,
|
||||||
|
const heim_ia5_string *q)
|
||||||
|
{
|
||||||
|
return der_heim_octet_string_cmp(q, q);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
der_heim_bit_string_cmp(const heim_bit_string *p,
|
der_heim_bit_string_cmp(const heim_bit_string *p,
|
||||||
const heim_bit_string *q)
|
const heim_bit_string *q)
|
||||||
|
@@ -85,14 +85,20 @@ int
|
|||||||
der_copy_printable_string (const heim_printable_string *from,
|
der_copy_printable_string (const heim_printable_string *from,
|
||||||
heim_printable_string *to)
|
heim_printable_string *to)
|
||||||
{
|
{
|
||||||
return der_copy_general_string(from, to);
|
to->length = from->length;
|
||||||
|
to->data = malloc(to->length + 1);
|
||||||
|
if(to->data == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
memcpy(to->data, from->data, to->length);
|
||||||
|
((char *)to->data)[to->length] = '\0';
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
der_copy_ia5_string (const heim_printable_string *from,
|
der_copy_ia5_string (const heim_ia5_string *from,
|
||||||
heim_printable_string *to)
|
heim_ia5_string *to)
|
||||||
{
|
{
|
||||||
return der_copy_general_string(from, to);
|
return der_copy_printable_string(from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@@ -79,15 +79,13 @@ der_free_utf8string (heim_utf8_string *str)
|
|||||||
void
|
void
|
||||||
der_free_printable_string (heim_printable_string *str)
|
der_free_printable_string (heim_printable_string *str)
|
||||||
{
|
{
|
||||||
free(*str);
|
der_free_octet_string(str);
|
||||||
*str = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
der_free_ia5_string (heim_ia5_string *str)
|
der_free_ia5_string (heim_ia5_string *str)
|
||||||
{
|
{
|
||||||
free(*str);
|
der_free_octet_string(str);
|
||||||
*str = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -170,14 +170,21 @@ int
|
|||||||
der_get_printable_string(const unsigned char *p, size_t len,
|
der_get_printable_string(const unsigned char *p, size_t len,
|
||||||
heim_printable_string *str, size_t *size)
|
heim_printable_string *str, size_t *size)
|
||||||
{
|
{
|
||||||
return der_get_general_string(p, len, str, size);
|
str->length = len;
|
||||||
|
str->data = malloc(len + 1);
|
||||||
|
if (str->data == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
memcpy(str->data, p, len);
|
||||||
|
((char *)str->data)[len] = '\0';
|
||||||
|
if(size) *size = len;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
der_get_ia5_string(const unsigned char *p, size_t len,
|
der_get_ia5_string(const unsigned char *p, size_t len,
|
||||||
heim_ia5_string *str, size_t *size)
|
heim_ia5_string *str, size_t *size)
|
||||||
{
|
{
|
||||||
return der_get_general_string(p, len, str, size);
|
return der_get_printable_string(p, len, str, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@@ -161,13 +161,13 @@ der_length_utf8string (const heim_utf8_string *data)
|
|||||||
size_t
|
size_t
|
||||||
der_length_printable_string (const heim_printable_string *data)
|
der_length_printable_string (const heim_printable_string *data)
|
||||||
{
|
{
|
||||||
return strlen(*data);
|
return data->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
der_length_ia5_string (const heim_ia5_string *data)
|
der_length_ia5_string (const heim_ia5_string *data)
|
||||||
{
|
{
|
||||||
return strlen(*data);
|
return data->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
|
@@ -181,14 +181,14 @@ int
|
|||||||
der_put_printable_string (unsigned char *p, size_t len,
|
der_put_printable_string (unsigned char *p, size_t len,
|
||||||
const heim_printable_string *str, size_t *size)
|
const heim_printable_string *str, size_t *size)
|
||||||
{
|
{
|
||||||
return der_put_general_string(p, len, str, size);
|
return der_put_octet_string(p, len, str, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
der_put_ia5_string (unsigned char *p, size_t len,
|
der_put_ia5_string (unsigned char *p, size_t len,
|
||||||
const heim_ia5_string *str, size_t *size)
|
const heim_ia5_string *str, size_t *size)
|
||||||
{
|
{
|
||||||
return der_put_general_string(p, len, str, size);
|
return der_put_octet_string(p, len, str, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@@ -181,10 +181,10 @@ init_generate (const char *filename, const char *base)
|
|||||||
"typedef char *heim_utf8_string;\n\n"
|
"typedef char *heim_utf8_string;\n\n"
|
||||||
);
|
);
|
||||||
fprintf (headerfile,
|
fprintf (headerfile,
|
||||||
"typedef char *heim_printable_string;\n\n"
|
"typedef struct heim_octet_string heim_printable_string;\n\n"
|
||||||
);
|
);
|
||||||
fprintf (headerfile,
|
fprintf (headerfile,
|
||||||
"typedef char *heim_ia5_string;\n\n"
|
"typedef struct heim_octet_string heim_ia5_string;\n\n"
|
||||||
);
|
);
|
||||||
fprintf (headerfile,
|
fprintf (headerfile,
|
||||||
"typedef struct heim_bmp_string {\n"
|
"typedef struct heim_bmp_string {\n"
|
||||||
|
@@ -485,7 +485,8 @@ hx509_ca_tbs_add_crl_dp_uri(hx509_context context,
|
|||||||
name.u.fullName.val = &gn;
|
name.u.fullName.val = &gn;
|
||||||
|
|
||||||
gn.element = choice_GeneralName_uniformResourceIdentifier;
|
gn.element = choice_GeneralName_uniformResourceIdentifier;
|
||||||
gn.u.uniformResourceIdentifier = rk_UNCONST(uri);
|
gn.u.uniformResourceIdentifier.data = rk_UNCONST(uri);
|
||||||
|
gn.u.uniformResourceIdentifier.length = strlen(uri);
|
||||||
|
|
||||||
ASN1_MALLOC_ENCODE(DistributionPointName,
|
ASN1_MALLOC_ENCODE(DistributionPointName,
|
||||||
dp.distributionPoint->data,
|
dp.distributionPoint->data,
|
||||||
@@ -785,7 +786,8 @@ hx509_ca_tbs_add_san_hostname(hx509_context context,
|
|||||||
|
|
||||||
memset(&gn, 0, sizeof(gn));
|
memset(&gn, 0, sizeof(gn));
|
||||||
gn.element = choice_GeneralName_dNSName;
|
gn.element = choice_GeneralName_dNSName;
|
||||||
gn.u.dNSName = rk_UNCONST(dnsname);
|
gn.u.dNSName.data = rk_UNCONST(dnsname);
|
||||||
|
gn.u.dNSName.length = strlen(dnsname);
|
||||||
|
|
||||||
return add_GeneralNames(&tbs->san, &gn);
|
return add_GeneralNames(&tbs->san, &gn);
|
||||||
}
|
}
|
||||||
@@ -812,7 +814,8 @@ hx509_ca_tbs_add_san_rfc822name(hx509_context context,
|
|||||||
|
|
||||||
memset(&gn, 0, sizeof(gn));
|
memset(&gn, 0, sizeof(gn));
|
||||||
gn.element = choice_GeneralName_rfc822Name;
|
gn.element = choice_GeneralName_rfc822Name;
|
||||||
gn.u.rfc822Name = rk_UNCONST(rfc822Name);
|
gn.u.rfc822Name.data = rk_UNCONST(rfc822Name);
|
||||||
|
gn.u.rfc822Name.length = strlen(rfc822Name);
|
||||||
|
|
||||||
return add_GeneralNames(&tbs->san, &gn);
|
return add_GeneralNames(&tbs->san, &gn);
|
||||||
}
|
}
|
||||||
|
@@ -1696,19 +1696,20 @@ match_general_name(const GeneralName *c, const GeneralName *n, int *match)
|
|||||||
case choice_GeneralName_rfc822Name: {
|
case choice_GeneralName_rfc822Name: {
|
||||||
const char *s;
|
const char *s;
|
||||||
size_t len1, len2;
|
size_t len1, len2;
|
||||||
s = strchr(c->u.rfc822Name, '@');
|
s = memchr(c->u.rfc822Name.data, '@', c->u.rfc822Name.length);
|
||||||
if (s) {
|
if (s) {
|
||||||
if (strcasecmp(c->u.rfc822Name, n->u.rfc822Name) != 0)
|
if (der_printable_string_cmp(&c->u.rfc822Name, &n->u.rfc822Name) != 0)
|
||||||
return HX509_NAME_CONSTRAINT_ERROR;
|
return HX509_NAME_CONSTRAINT_ERROR;
|
||||||
} else {
|
} else {
|
||||||
s = strchr(n->u.rfc822Name, '@');
|
s = memchr(n->u.rfc822Name.data, '@', n->u.rfc822Name.length);
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
return HX509_NAME_CONSTRAINT_ERROR;
|
return HX509_NAME_CONSTRAINT_ERROR;
|
||||||
len1 = strlen(c->u.rfc822Name);
|
len1 = c->u.rfc822Name.length;
|
||||||
len2 = strlen(s + 1);
|
len2 = n->u.rfc822Name.length -
|
||||||
|
(s - ((char *)n->u.rfc822Name.data));
|
||||||
if (len1 > len2)
|
if (len1 > len2)
|
||||||
return HX509_NAME_CONSTRAINT_ERROR;
|
return HX509_NAME_CONSTRAINT_ERROR;
|
||||||
if (strcasecmp(s + 1 + len2 - len1, c->u.rfc822Name) != 0)
|
if (memcmp(s + 1 + len2 - len1, c->u.rfc822Name.data, len1) != 0)
|
||||||
return HX509_NAME_CONSTRAINT_ERROR;
|
return HX509_NAME_CONSTRAINT_ERROR;
|
||||||
if (len1 < len2 && s[len2 - len1 + 1] != '.')
|
if (len1 < len2 && s[len2 - len1 + 1] != '.')
|
||||||
return HX509_NAME_CONSTRAINT_ERROR;
|
return HX509_NAME_CONSTRAINT_ERROR;
|
||||||
@@ -1718,14 +1719,16 @@ match_general_name(const GeneralName *c, const GeneralName *n, int *match)
|
|||||||
}
|
}
|
||||||
case choice_GeneralName_dNSName: {
|
case choice_GeneralName_dNSName: {
|
||||||
size_t lenc, lenn;
|
size_t lenc, lenn;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
lenc = strlen(c->u.dNSName);
|
lenc = c->u.dNSName.length;
|
||||||
lenn = strlen(n->u.dNSName);
|
lenn = n->u.dNSName.length;
|
||||||
if (lenc > lenn)
|
if (lenc > lenn)
|
||||||
return HX509_NAME_CONSTRAINT_ERROR;
|
return HX509_NAME_CONSTRAINT_ERROR;
|
||||||
if (strcasecmp(&n->u.dNSName[lenn - lenc], c->u.dNSName) != 0)
|
ptr = n->u.dNSName.data;
|
||||||
|
if (memcmp(&ptr[lenn - lenc], c->u.dNSName.data, c->u.dNSName.length) != 0)
|
||||||
return HX509_NAME_CONSTRAINT_ERROR;
|
return HX509_NAME_CONSTRAINT_ERROR;
|
||||||
if (lenc != lenn && n->u.dNSName[lenn - lenc - 1] != '.')
|
if (lenc != lenn && ptr[lenn - lenc - 1] != '.')
|
||||||
return HX509_NAME_CONSTRAINT_ERROR;
|
return HX509_NAME_CONSTRAINT_ERROR;
|
||||||
*match = 1;
|
*match = 1;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2405,12 +2408,17 @@ hx509_verify_hostname(hx509_context context,
|
|||||||
|
|
||||||
for (j = 0; j < san.len; j++) {
|
for (j = 0; j < san.len; j++) {
|
||||||
switch (san.val[j].element) {
|
switch (san.val[j].element) {
|
||||||
case choice_GeneralName_dNSName:
|
case choice_GeneralName_dNSName: {
|
||||||
if (strcasecmp(san.val[j].u.dNSName, hostname) == 0) {
|
heim_printable_string hn;
|
||||||
|
hn.data = rk_UNCONST(hostname);
|
||||||
|
hn.length = strlen(hostname);
|
||||||
|
|
||||||
|
if (der_printable_string_cmp(&san.val[j].u.dNSName, &hn) == 0) {
|
||||||
free_GeneralNames(&san);
|
free_GeneralNames(&san);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2428,14 +2436,24 @@ hx509_verify_hostname(hx509_context context,
|
|||||||
if (der_heim_oid_cmp(&n->type, &asn1_oid_id_at_commonName) == 0) {
|
if (der_heim_oid_cmp(&n->type, &asn1_oid_id_at_commonName) == 0) {
|
||||||
DirectoryString *ds = &n->value;
|
DirectoryString *ds = &n->value;
|
||||||
switch (ds->element) {
|
switch (ds->element) {
|
||||||
case choice_DirectoryString_printableString:
|
case choice_DirectoryString_printableString: {
|
||||||
if (strcasecmp(ds->u.printableString, hostname) == 0)
|
heim_printable_string hn;
|
||||||
|
hn.data = rk_UNCONST(hostname);
|
||||||
|
hn.length = strlen(hostname);
|
||||||
|
|
||||||
|
if (der_printable_string_cmp(&ds->u.printableString, &hn) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case choice_DirectoryString_ia5String:
|
}
|
||||||
if (strcasecmp(ds->u.ia5String, hostname) == 0)
|
case choice_DirectoryString_ia5String: {
|
||||||
|
heim_ia5_string hn;
|
||||||
|
hn.data = rk_UNCONST(hostname);
|
||||||
|
hn.length = strlen(hostname);
|
||||||
|
|
||||||
|
if (der_ia5_string_cmp(&ds->u.ia5String, &hn) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case choice_DirectoryString_utf8String:
|
case choice_DirectoryString_utf8String:
|
||||||
if (strcasecmp(ds->u.utf8String, hostname) == 0)
|
if (strcasecmp(ds->u.utf8String, hostname) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
45
lib/hx509/char_map.h
Normal file
45
lib/hx509/char_map.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#define Q_CONTROL_CHAR 1
|
||||||
|
#define Q_PRINTABLE 2
|
||||||
|
#define Q_RFC2253_QUOTE_FIRST 4
|
||||||
|
#define Q_RFC2253_QUOTE_LAST 8
|
||||||
|
#define Q_RFC2253_QUOTE 16
|
||||||
|
#define Q_RFC2253_HEX 32
|
||||||
|
|
||||||
|
#define Q_RFC2253 (Q_RFC2253_QUOTE_FIRST|Q_RFC2253_QUOTE_LAST|Q_RFC2253_QUOTE|Q_RFC2253_HEX)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char char_map[] = {
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x06 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 , 0x00 ,
|
||||||
|
0x00 , 0x00 , 0x00 , 0x12 , 0x12 , 0x02 , 0x02 , 0x02 ,
|
||||||
|
0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 ,
|
||||||
|
0x02 , 0x02 , 0x02 , 0x10 , 0x10 , 0x12 , 0x10 , 0x02 ,
|
||||||
|
0x00 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 ,
|
||||||
|
0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 ,
|
||||||
|
0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 ,
|
||||||
|
0x02 , 0x02 , 0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
|
||||||
|
0x00 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 ,
|
||||||
|
0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 ,
|
||||||
|
0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 ,
|
||||||
|
0x02 , 0x02 , 0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
|
||||||
|
0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21
|
||||||
|
};
|
BIN
lib/hx509/data/win-u16-in-printablestring.der
Normal file
BIN
lib/hx509/data/win-u16-in-printablestring.der
Normal file
Binary file not shown.
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "hx_locl.h"
|
#include "hx_locl.h"
|
||||||
#include <wind.h>
|
#include <wind.h>
|
||||||
|
#include "char_map.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @page page_name PKIX/X.509 Names
|
* @page page_name PKIX/X.509 Names
|
||||||
@@ -79,11 +80,11 @@ static const struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
quote_string(const char *f, size_t len, size_t *rlen)
|
quote_string(const char *f, size_t len, int flags, size_t *rlen)
|
||||||
{
|
{
|
||||||
size_t i, j, tolen;
|
size_t i, j, tolen;
|
||||||
const char *from = f;
|
const unsigned char *from = (const unsigned char *)f;
|
||||||
char *to;
|
unsigned char *to;
|
||||||
|
|
||||||
tolen = len * 3 + 1;
|
tolen = len * 3 + 1;
|
||||||
to = malloc(tolen);
|
to = malloc(tolen);
|
||||||
@@ -91,26 +92,29 @@ quote_string(const char *f, size_t len, size_t *rlen)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (i = 0, j = 0; i < len; i++) {
|
for (i = 0, j = 0; i < len; i++) {
|
||||||
if (from[i] == ' ' && i + 1 < len)
|
unsigned char map = char_map[from[i]] & flags;
|
||||||
to[j++] = from[i];
|
if (i == 0 && (map & Q_RFC2253_QUOTE_FIRST)) {
|
||||||
else if (from[i] == ',' || from[i] == '=' || from[i] == '+' ||
|
|
||||||
from[i] == '<' || from[i] == '>' || from[i] == '#' ||
|
|
||||||
from[i] == ';' || from[i] == ' ')
|
|
||||||
{
|
|
||||||
to[j++] = '\\';
|
to[j++] = '\\';
|
||||||
to[j++] = from[i];
|
to[j++] = from[i];
|
||||||
} else if (((unsigned char)from[i]) >= 32 && ((unsigned char)from[i]) <= 127) {
|
} else if ((i + 1) == len && (map & Q_RFC2253_QUOTE_LAST)) {
|
||||||
|
|
||||||
|
to[j++] = '\\';
|
||||||
to[j++] = from[i];
|
to[j++] = from[i];
|
||||||
} else {
|
} else if (map & Q_RFC2253_QUOTE) {
|
||||||
int l = snprintf(&to[j], tolen - j - 1,
|
to[j++] = '\\';
|
||||||
|
to[j++] = from[i];
|
||||||
|
} else if (map & Q_RFC2253_HEX) {
|
||||||
|
int l = snprintf((char *)&to[j], tolen - j - 1,
|
||||||
"#%02x", (unsigned char)from[i]);
|
"#%02x", (unsigned char)from[i]);
|
||||||
j += l;
|
j += l;
|
||||||
|
} else {
|
||||||
|
to[j++] = from[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
to[j] = '\0';
|
to[j] = '\0';
|
||||||
assert(j < tolen);
|
assert(j < tolen);
|
||||||
*rlen = j;
|
*rlen = j;
|
||||||
return to;
|
return (char *)to;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -121,7 +125,7 @@ append_string(char **str, size_t *total_len, const char *ss,
|
|||||||
char *s, *qs;
|
char *s, *qs;
|
||||||
|
|
||||||
if (quote)
|
if (quote)
|
||||||
qs = quote_string(ss, len, &len);
|
qs = quote_string(ss, len, Q_RFC2253, &len);
|
||||||
else
|
else
|
||||||
qs = rk_UNCONST(ss);
|
qs = rk_UNCONST(ss);
|
||||||
|
|
||||||
@@ -203,7 +207,7 @@ _hx509_Name_to_string(const Name *n, char **str)
|
|||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
for (i = n->u.rdnSequence.len - 1 ; i >= 0 ; i--) {
|
for (i = n->u.rdnSequence.len - 1 ; i >= 0 ; i--) {
|
||||||
int len;
|
size_t len;
|
||||||
|
|
||||||
for (j = 0; j < n->u.rdnSequence.val[i].len; j++) {
|
for (j = 0; j < n->u.rdnSequence.val[i].len; j++) {
|
||||||
DirectoryString *ds = &n->u.rdnSequence.val[i].val[j].value;
|
DirectoryString *ds = &n->u.rdnSequence.val[i].val[j].value;
|
||||||
@@ -214,13 +218,16 @@ _hx509_Name_to_string(const Name *n, char **str)
|
|||||||
|
|
||||||
switch(ds->element) {
|
switch(ds->element) {
|
||||||
case choice_DirectoryString_ia5String:
|
case choice_DirectoryString_ia5String:
|
||||||
ss = ds->u.ia5String;
|
ss = ds->u.ia5String.data;
|
||||||
|
len = ds->u.ia5String.length;
|
||||||
break;
|
break;
|
||||||
case choice_DirectoryString_printableString:
|
case choice_DirectoryString_printableString:
|
||||||
ss = ds->u.printableString;
|
ss = ds->u.printableString.data;
|
||||||
|
len = ds->u.printableString.length;
|
||||||
break;
|
break;
|
||||||
case choice_DirectoryString_utf8String:
|
case choice_DirectoryString_utf8String:
|
||||||
ss = ds->u.utf8String;
|
ss = ds->u.utf8String;
|
||||||
|
len = strlen(ss);
|
||||||
break;
|
break;
|
||||||
case choice_DirectoryString_bmpString: {
|
case choice_DirectoryString_bmpString: {
|
||||||
const uint16_t *bmp = ds->u.bmpString.data;
|
const uint16_t *bmp = ds->u.bmpString.data;
|
||||||
@@ -240,10 +247,12 @@ _hx509_Name_to_string(const Name *n, char **str)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ss[k] = '\0';
|
ss[k] = '\0';
|
||||||
|
len = k;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case choice_DirectoryString_teletexString:
|
case choice_DirectoryString_teletexString:
|
||||||
ss = ds->u.teletexString;
|
ss = ds->u.teletexString;
|
||||||
|
len = strlen(ss);
|
||||||
break;
|
break;
|
||||||
case choice_DirectoryString_universalString: {
|
case choice_DirectoryString_universalString: {
|
||||||
const uint32_t *uni = ds->u.universalString.data;
|
const uint32_t *uni = ds->u.universalString.data;
|
||||||
@@ -263,6 +272,7 @@ _hx509_Name_to_string(const Name *n, char **str)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ss[k] = '\0';
|
ss[k] = '\0';
|
||||||
|
len = k;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -272,10 +282,9 @@ _hx509_Name_to_string(const Name *n, char **str)
|
|||||||
append_string(str, &total_len, oidname, strlen(oidname), 0);
|
append_string(str, &total_len, oidname, strlen(oidname), 0);
|
||||||
free(oidname);
|
free(oidname);
|
||||||
append_string(str, &total_len, "=", 1, 0);
|
append_string(str, &total_len, "=", 1, 0);
|
||||||
len = strlen(ss);
|
|
||||||
append_string(str, &total_len, ss, len, 1);
|
append_string(str, &total_len, ss, len, 1);
|
||||||
if (ds->element == choice_DirectoryString_universalString ||
|
if (ds->element == choice_DirectoryString_bmpString ||
|
||||||
ds->element == choice_DirectoryString_bmpString)
|
ds->element == choice_DirectoryString_universalString)
|
||||||
{
|
{
|
||||||
free(ss);
|
free(ss);
|
||||||
}
|
}
|
||||||
@@ -330,12 +339,12 @@ dsstringprep(const DirectoryString *ds, uint32_t **rname, size_t *rlen)
|
|||||||
switch(ds->element) {
|
switch(ds->element) {
|
||||||
case choice_DirectoryString_ia5String:
|
case choice_DirectoryString_ia5String:
|
||||||
flags = WIND_PROFILE_LDAP;
|
flags = WIND_PROFILE_LDAP;
|
||||||
COPYCHARARRAY(ds, ia5String, len, name);
|
COPYVOIDARRAY(ds, ia5String, len, name);
|
||||||
break;
|
break;
|
||||||
case choice_DirectoryString_printableString:
|
case choice_DirectoryString_printableString:
|
||||||
flags = WIND_PROFILE_LDAP;
|
flags = WIND_PROFILE_LDAP;
|
||||||
flags |= WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE;
|
flags |= WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE;
|
||||||
COPYCHARARRAY(ds, printableString, len, name);
|
COPYVOIDARRAY(ds, printableString, len, name);
|
||||||
break;
|
break;
|
||||||
case choice_DirectoryString_teletexString:
|
case choice_DirectoryString_teletexString:
|
||||||
flags = WIND_PROFILE_LDAP_CASE;
|
flags = WIND_PROFILE_LDAP_CASE;
|
||||||
@@ -939,12 +948,14 @@ hx509_general_name_unparse(GeneralName *name, char **str)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case choice_GeneralName_rfc822Name:
|
case choice_GeneralName_rfc822Name:
|
||||||
strpool = rk_strpoolprintf(strpool, "rfc822Name: %s\n",
|
strpool = rk_strpoolprintf(strpool, "rfc822Name: %.*s\n",
|
||||||
name->u.rfc822Name);
|
(int)name->u.rfc822Name.length,
|
||||||
|
(char *)name->u.rfc822Name.data);
|
||||||
break;
|
break;
|
||||||
case choice_GeneralName_dNSName:
|
case choice_GeneralName_dNSName:
|
||||||
strpool = rk_strpoolprintf(strpool, "dNSName: %s\n",
|
strpool = rk_strpoolprintf(strpool, "dNSName: %.*s\n",
|
||||||
name->u.dNSName);
|
(int)name->u.dNSName.length,
|
||||||
|
(char *)name->u.dNSName.data);
|
||||||
break;
|
break;
|
||||||
case choice_GeneralName_directoryName: {
|
case choice_GeneralName_directoryName: {
|
||||||
Name dir;
|
Name dir;
|
||||||
@@ -961,8 +972,9 @@ hx509_general_name_unparse(GeneralName *name, char **str)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case choice_GeneralName_uniformResourceIdentifier:
|
case choice_GeneralName_uniformResourceIdentifier:
|
||||||
strpool = rk_strpoolprintf(strpool, "URI: %s",
|
strpool = rk_strpoolprintf(strpool, "URI: %.*s",
|
||||||
name->u.uniformResourceIdentifier);
|
(int)name->u.uniformResourceIdentifier.length,
|
||||||
|
(char *)name->u.uniformResourceIdentifier.data);
|
||||||
break;
|
break;
|
||||||
case choice_GeneralName_iPAddress: {
|
case choice_GeneralName_iPAddress: {
|
||||||
unsigned char *a = name->u.iPAddress.data;
|
unsigned char *a = name->u.iPAddress.data;
|
||||||
|
101
lib/hx509/quote.py
Normal file
101
lib/hx509/quote.py
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright (c) 2010 Kungliga Tekniska Högskolan
|
||||||
|
# (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
|
# 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. Neither the name of the Institute nor the names of its contributors
|
||||||
|
# may be used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
# ANY EXPRESS 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 INSTITUTE OR 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
CONTROL_CHAR = 1
|
||||||
|
PRINTABLE = 2
|
||||||
|
RFC2253_QUOTE_FIRST = 4
|
||||||
|
RFC2253_QUOTE_LAST = 8
|
||||||
|
RFC2253_QUOTE = 16
|
||||||
|
RFC2253_HEX = 32
|
||||||
|
|
||||||
|
chars = []
|
||||||
|
|
||||||
|
for i in range(0, 256):
|
||||||
|
chars.append(0);
|
||||||
|
|
||||||
|
for i in range(0, 256):
|
||||||
|
if (i < 32 or i > 126):
|
||||||
|
chars[i] |= CONTROL_CHAR | RFC2253_HEX;
|
||||||
|
|
||||||
|
for i in range(ord("A"), ord("Z") + 1):
|
||||||
|
chars[i] |= PRINTABLE
|
||||||
|
for i in range(ord("a"), ord("z") + 1):
|
||||||
|
chars[i] |= PRINTABLE
|
||||||
|
for i in range(ord("0"), ord("9") + 1):
|
||||||
|
chars[i] |= PRINTABLE
|
||||||
|
|
||||||
|
chars[ord(' ')] |= PRINTABLE
|
||||||
|
chars[ord('+')] |= PRINTABLE
|
||||||
|
chars[ord(',')] |= PRINTABLE
|
||||||
|
chars[ord('-')] |= PRINTABLE
|
||||||
|
chars[ord('.')] |= PRINTABLE
|
||||||
|
chars[ord('/')] |= PRINTABLE
|
||||||
|
chars[ord(':')] |= PRINTABLE
|
||||||
|
chars[ord('=')] |= PRINTABLE
|
||||||
|
chars[ord('?')] |= PRINTABLE
|
||||||
|
|
||||||
|
chars[ord(' ')] |= RFC2253_QUOTE_FIRST | RFC2253_QUOTE_FIRST
|
||||||
|
|
||||||
|
chars[ord(',')] |= RFC2253_QUOTE
|
||||||
|
chars[ord('=')] |= RFC2253_QUOTE
|
||||||
|
chars[ord('+')] |= RFC2253_QUOTE
|
||||||
|
chars[ord('<')] |= RFC2253_QUOTE
|
||||||
|
chars[ord('>')] |= RFC2253_QUOTE
|
||||||
|
chars[ord('#')] |= RFC2253_QUOTE
|
||||||
|
chars[ord(';')] |= RFC2253_QUOTE
|
||||||
|
|
||||||
|
print "#define Q_CONTROL_CHAR 1"
|
||||||
|
print "#define Q_PRINTABLE 2"
|
||||||
|
print "#define Q_RFC2253_QUOTE_FIRST 4"
|
||||||
|
print "#define Q_RFC2253_QUOTE_LAST 8"
|
||||||
|
print "#define Q_RFC2253_QUOTE 16"
|
||||||
|
print "#define Q_RFC2253_HEX 32"
|
||||||
|
print ""
|
||||||
|
print "#define Q_RFC2253 (Q_RFC2253_QUOTE_FIRST|Q_RFC2253_QUOTE_LAST|Q_RFC2253_QUOTE|Q_RFC2253_HEX)"
|
||||||
|
print "\n" * 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print "unsigned char char_map[] = {\n\t",
|
||||||
|
for x in range(0, 256):
|
||||||
|
if (x % 8) == 0 and x != 0:
|
||||||
|
print "\n\t",
|
||||||
|
print "0x%(char)02x" % { 'char' : chars[x] },
|
||||||
|
if x < 255:
|
||||||
|
print ", ",
|
||||||
|
else:
|
||||||
|
print ""
|
||||||
|
print "};"
|
@@ -143,7 +143,8 @@ _hx509_request_add_dns_name(hx509_context context,
|
|||||||
|
|
||||||
memset(&name, 0, sizeof(name));
|
memset(&name, 0, sizeof(name));
|
||||||
name.element = choice_GeneralName_dNSName;
|
name.element = choice_GeneralName_dNSName;
|
||||||
name.u.dNSName = rk_UNCONST(hostname);
|
name.u.dNSName.data = rk_UNCONST(hostname);
|
||||||
|
name.u.dNSName.length = strlen(hostname);
|
||||||
|
|
||||||
return add_GeneralNames(&req->san, &name);
|
return add_GeneralNames(&req->san, &name);
|
||||||
}
|
}
|
||||||
@@ -157,7 +158,8 @@ _hx509_request_add_email(hx509_context context,
|
|||||||
|
|
||||||
memset(&name, 0, sizeof(name));
|
memset(&name, 0, sizeof(name));
|
||||||
name.element = choice_GeneralName_rfc822Name;
|
name.element = choice_GeneralName_rfc822Name;
|
||||||
name.u.dNSName = rk_UNCONST(email);
|
name.u.dNSName.data = rk_UNCONST(email);
|
||||||
|
name.u.dNSName.length = strlen(email);
|
||||||
|
|
||||||
return add_GeneralNames(&req->san, &name);
|
return add_GeneralNames(&req->san, &name);
|
||||||
}
|
}
|
||||||
|
@@ -76,4 +76,9 @@ ${hxtool} verify --missing-revoke \
|
|||||||
cert:FILE:$srcdir/data/n0ll.pem \
|
cert:FILE:$srcdir/data/n0ll.pem \
|
||||||
anchor:FILE:$srcdir/data/n0ll.pem && exit 1
|
anchor:FILE:$srcdir/data/n0ll.pem && exit 1
|
||||||
|
|
||||||
|
echo "check that windows cert with utf16 in printable string works"
|
||||||
|
${hxtool} verify --missing-revoke \
|
||||||
|
cert:FILE:$srcdir/data/win-u16-in-printablestring.der \
|
||||||
|
anchor:FILE:$srcdir/data/win-u16-in-printablestring.der || exit 1
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
Reference in New Issue
Block a user