moved RDN OIDs to oid.txt, use asn1_get_known_oid() for lookup

This commit is contained in:
Martin Willi
2009-04-14 13:53:06 +00:00
parent 56807f35b9
commit c31687daa7
2 changed files with 102 additions and 149 deletions
+75 -129
View File
@@ -58,111 +58,43 @@ ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_CERT_DER_SHA1, ID_KEY_ID,
"ID_CERT_DER_SHA1");
ENUM_END(id_type_names, ID_CERT_DER_SHA1);
/**
* X.501 acronyms for well known object identifiers (OIDs)
*/
static u_char oid_ND[] = {
0x02, 0x82, 0x06, 0x01, 0x0A, 0x07, 0x14
};
static u_char oid_UID[] = {
0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x01
};
static u_char oid_DC[] = {
0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19
};
static u_char oid_CN[] = {
0x55, 0x04, 0x03
};
static u_char oid_S[] = {
0x55, 0x04, 0x04
};
static u_char oid_SN[] = {
0x55, 0x04, 0x05
};
static u_char oid_C[] = {
0x55, 0x04, 0x06
};
static u_char oid_L[] = {
0x55, 0x04, 0x07
};
static u_char oid_ST[] = {
0x55, 0x04, 0x08
};
static u_char oid_O[] = {
0x55, 0x04, 0x0A
};
static u_char oid_OU[] = {
0x55, 0x04, 0x0B
};
static u_char oid_T[] = {
0x55, 0x04, 0x0C
};
static u_char oid_D[] = {
0x55, 0x04, 0x0D
};
static u_char oid_N[] = {
0x55, 0x04, 0x29
};
static u_char oid_G[] = {
0x55, 0x04, 0x2A
};
static u_char oid_I[] = {
0x55, 0x04, 0x2B
};
static u_char oid_ID[] = {
0x55, 0x04, 0x2D
};
static u_char oid_EN[] = {
0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x42, 0x03, 0x01, 0x03
};
static u_char oid_E[] = {
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01
};
static u_char oid_UN[] = {
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x02
};
static u_char oid_TCGID[] = {
0x2B, 0x06, 0x01, 0x04, 0x01, 0x89, 0x31, 0x01, 0x01, 0x02, 0x02, 0x4B
};
/**
* coding of X.501 distinguished name
*/
typedef struct {
const u_char *name;
chunk_t oid;
int oid;
u_char type;
} x501rdn_t;
static const x501rdn_t x501rdns[] = {
{"ND", {oid_ND, 7}, ASN1_PRINTABLESTRING},
{"UID", {oid_UID, 10}, ASN1_PRINTABLESTRING},
{"DC", {oid_DC, 10}, ASN1_PRINTABLESTRING},
{"CN", {oid_CN, 3}, ASN1_PRINTABLESTRING},
{"S", {oid_S, 3}, ASN1_PRINTABLESTRING},
{"SN", {oid_SN, 3}, ASN1_PRINTABLESTRING},
{"serialNumber", {oid_SN, 3}, ASN1_PRINTABLESTRING},
{"C", {oid_C, 3}, ASN1_PRINTABLESTRING},
{"L", {oid_L, 3}, ASN1_PRINTABLESTRING},
{"ST", {oid_ST, 3}, ASN1_PRINTABLESTRING},
{"O", {oid_O, 3}, ASN1_PRINTABLESTRING},
{"OU", {oid_OU, 3}, ASN1_PRINTABLESTRING},
{"T", {oid_T, 3}, ASN1_PRINTABLESTRING},
{"D", {oid_D, 3}, ASN1_PRINTABLESTRING},
{"N", {oid_N, 3}, ASN1_PRINTABLESTRING},
{"G", {oid_G, 3}, ASN1_PRINTABLESTRING},
{"I", {oid_I, 3}, ASN1_PRINTABLESTRING},
{"ID", {oid_ID, 3}, ASN1_PRINTABLESTRING},
{"EN", {oid_EN, 10}, ASN1_PRINTABLESTRING},
{"employeeNumber", {oid_EN, 10}, ASN1_PRINTABLESTRING},
{"E", {oid_E, 9}, ASN1_IA5STRING},
{"Email", {oid_E, 9}, ASN1_IA5STRING},
{"emailAddress", {oid_E, 9}, ASN1_IA5STRING},
{"UN", {oid_UN, 9}, ASN1_IA5STRING},
{"unstructuredName",{oid_UN, 9}, ASN1_IA5STRING},
{"TCGID", {oid_TCGID, 12}, ASN1_PRINTABLESTRING}
{"ND", OID_NAME_DISTINGUISHER, ASN1_PRINTABLESTRING},
{"UID", OID_PILOT_USERID, ASN1_PRINTABLESTRING},
{"DC", OID_PILOT_DOMAIN_COMPONENT, ASN1_PRINTABLESTRING},
{"CN", OID_COMMON_NAME, ASN1_PRINTABLESTRING},
{"S", OID_SURNAME, ASN1_PRINTABLESTRING},
{"SN", OID_SERIAL_NUMBER, ASN1_PRINTABLESTRING},
{"serialNumber", OID_SERIAL_NUMBER, ASN1_PRINTABLESTRING},
{"C", OID_COUNTRY, ASN1_PRINTABLESTRING},
{"L", OID_LOCALITY, ASN1_PRINTABLESTRING},
{"ST", OID_STATE_OR_PROVINCE, ASN1_PRINTABLESTRING},
{"O", OID_ORGANIZATION, ASN1_PRINTABLESTRING},
{"OU", OID_ORGANIZATION_UNIT, ASN1_PRINTABLESTRING},
{"T", OID_TITLE, ASN1_PRINTABLESTRING},
{"D", OID_DESCRIPTION, ASN1_PRINTABLESTRING},
{"N", OID_NAME, ASN1_PRINTABLESTRING},
{"G", OID_GIVEN_NAME, ASN1_PRINTABLESTRING},
{"I", OID_INITIALS, ASN1_PRINTABLESTRING},
{"ID", OID_UNIQUE_IDENTIFIER, ASN1_PRINTABLESTRING},
{"EN", OID_EMPLOYEE_NUMBER, ASN1_PRINTABLESTRING},
{"employeeNumber", OID_EMPLOYEE_NUMBER, ASN1_PRINTABLESTRING},
{"E", OID_EMAIL_ADDRESS, ASN1_IA5STRING},
{"Email", OID_EMAIL_ADDRESS, ASN1_IA5STRING},
{"emailAddress", OID_EMAIL_ADDRESS, ASN1_IA5STRING},
{"UN", OID_UNSTRUCTURED_NAME, ASN1_IA5STRING},
{"unstructuredName",OID_UNSTRUCTURED_NAME, ASN1_IA5STRING},
{"TCGID", OID_TCGID, ASN1_PRINTABLESTRING}
};
#define X501_RDN_ROOF 26
/**
* maximum number of RDNs in atodn()
@@ -260,14 +192,15 @@ static bool init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
/**
* Fetches the next RDN in a DN
*/
static bool get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value, asn1_t *type, bool *next)
static bool get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid,
chunk_t *value, asn1_t *type, bool *next)
{
chunk_t body;
/* initialize return values */
*oid = chunk_empty;
*value = chunk_empty;
/* if all attributes have been parsed, get next rdn */
if (attribute->len <= 0)
{
@@ -359,19 +292,19 @@ static bool dntoa(chunk_t dn, chunk_t *str)
int oid_code;
bool next;
bool first = TRUE;
if (!init_rdn(dn, &rdn, &attribute, &next))
{
return FALSE;
}
while (next)
{
if (!get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next))
{
return FALSE;
}
if (first)
{ /* first OID/value pair */
first = FALSE;
@@ -380,7 +313,7 @@ static bool dntoa(chunk_t dn, chunk_t *str)
{ /* separate OID/value pair by a comma */
update_chunk(str, snprintf(str->ptr,str->len,", "));
}
/* print OID */
oid_code = asn1_known_oid(oid);
if (oid_code == OID_UNKNOWN)
@@ -409,7 +342,7 @@ static bool same_dn(chunk_t a, chunk_t b)
chunk_t oid_a, oid_b, value_a, value_b;
asn1_t type_a, type_b;
bool next_a, next_b;
/* same lengths for the DNs */
if (a.len != b.len)
{
@@ -426,7 +359,7 @@ static bool same_dn(chunk_t a, chunk_t b)
{
return FALSE;
}
/* fetch next RDN pair */
while (next_a && next_b)
{
@@ -436,19 +369,19 @@ static bool same_dn(chunk_t a, chunk_t b)
{
return FALSE;
}
/* OIDs must agree */
if (oid_a.len != oid_b.len || !memeq(oid_a.ptr, oid_b.ptr, oid_b.len))
{
return FALSE;
}
/* same lengths for values */
if (value_a.len != value_b.len)
{
return FALSE;
}
/* printableStrings and email RDNs require uppercase comparison */
if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
(type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_PKCS9_EMAIL)))
@@ -487,17 +420,17 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
chunk_t oid_a, oid_b, value_a, value_b;
asn1_t type_a, type_b;
bool next_a, next_b;
/* initialize wildcard counter */
*wildcards = 0;
/* initialize DN parsing */
if (!init_rdn(a, &rdn_a, &attribute_a, &next_a) ||
!init_rdn(b, &rdn_b, &attribute_b, &next_b))
{
return FALSE;
}
/* fetch next RDN pair */
while (next_a && next_b)
{
@@ -512,7 +445,7 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
{
return FALSE;
}
/* does rdn_b contain a wildcard? */
if (value_b.len == 1 && *value_b.ptr == '*')
{
@@ -524,7 +457,7 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
{
return FALSE;
}
/* printableStrings and email RDNs require uppercase comparison */
if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
(type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_PKCS9_EMAIL)))
@@ -597,15 +530,18 @@ static status_t atodn(char *src, chunk_t *dn)
}
else
{
for (i = 0; i < X501_RDN_ROOF; i++)
bool found = FALSE;
for (i = 0; i < countof(x501rdns); i++)
{
if (strlen(x501rdns[i].name) == oid.len
&& strncasecmp(x501rdns[i].name, oid.ptr, oid.len) == 0)
if (strlen(x501rdns[i].name) == oid.len &&
strncasecmp(x501rdns[i].name, oid.ptr, oid.len) == 0)
{
break; /* found a valid OID */
found = TRUE;
break;
}
}
if (i == X501_RDN_ROOF)
if (!found)
{
status = NOT_SUPPORTED;
state = UNKNOWN_OID;
@@ -643,14 +579,24 @@ static status_t atodn(char *src, chunk_t *dn)
if (rdn_count < RDN_MAX)
{
rdns[rdn_count] =
asn1_wrap(ASN1_SET, "m",
asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_wrap(ASN1_OID, "c", x501rdns[i].oid),
asn1_wrap(rdn_type, "c", name)
)
);
dn_len += rdns[rdn_count++].len;
chunk_t rdn_oid;
rdn_oid = asn1_get_known_oid(x501rdns[i].oid);
if (rdn_oid.len)
{
rdns[rdn_count] =
asn1_wrap(ASN1_SET, "m",
asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_wrap(ASN1_OID, "m", rdn_oid),
asn1_wrap(rdn_type, "c", name)
)
);
dn_len += rdns[rdn_count++].len;
}
else
{
status = INVALID_ARG;
}
}
else
{
@@ -665,12 +611,12 @@ static status_t atodn(char *src, chunk_t *dn)
break;
}
} while (*src++ != '\0');
/* build the distinguished name sequence */
{
{
int i;
u_char *pos = asn1_build_object(dn, ASN1_SEQUENCE, dn_len);
for (i = 0; i < rdn_count; i++)
{
memcpy(pos, rdns[i].ptr, rdns[i].len);
@@ -678,7 +624,7 @@ static status_t atodn(char *src, chunk_t *dn)
free(rdns[i].ptr);
}
}
if (status != SUCCESS)
{
free(dn->ptr);