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

View File

@ -4,7 +4,7 @@
0x01 "Deutsche Telekom AG" 0x01 "Deutsche Telekom AG"
0x0A "" 0x0A ""
0x07 "" 0x07 ""
0x14 "ND" 0x14 "ND" OID_NAME_DISTINGUISHER
0x09 "data" 0x09 "data"
0x92 "" 0x92 ""
0x26 "" 0x26 ""
@ -14,25 +14,25 @@
0x2C "" 0x2C ""
0x64 "pilot" 0x64 "pilot"
0x01 "pilotAttributeType" 0x01 "pilotAttributeType"
0x01 "UID" 0x01 "UID" OID_PILOT_USERID
0x19 "DC" 0x19 "DC" OID_PILOT_DOMAIN_COMPONENT
0x55 "X.500" 0x55 "X.500"
0x04 "X.509" 0x04 "X.509"
0x03 "CN" 0x03 "CN" OID_COMMON_NAME
0x04 "S" 0x04 "S" OID_SURNAME
0x05 "SN" 0x05 "SN" OID_SERIAL_NUMBER
0x06 "C" 0x06 "C" OID_COUNTRY
0x07 "L" 0x07 "L" OID_LOCALITY
0x08 "ST" 0x08 "ST" OID_STATE_OR_PROVINCE
0x0A "O" 0x0A "O" OID_ORGANIZATION
0x0B "OU" 0x0B "OU" OID_ORGANIZATION_UNIT
0x0C "T" 0x0C "T" OID_TITLE
0x0D "D" 0x0D "D" OID_DESCRIPTION
0x24 "userCertificate" 0x24 "userCertificate" OID_USER_CERTIFICATE
0x29 "N" 0x29 "N" OID_NAME
0x2A "G" 0x2A "G" OID_GIVEN_NAME
0x2B "I" 0x2B "I" OID_INITIALS
0x2D "ID" 0x2D "ID" OID_UNIQUE_IDENTIFIER
0x48 "role" OID_ROLE 0x48 "role" OID_ROLE
0x1D "id-ce" 0x1D "id-ce"
0x09 "subjectDirectoryAttrs" 0x09 "subjectDirectoryAttrs"
@ -149,7 +149,7 @@
0x01 "" 0x01 ""
0x02 "" 0x02 ""
0x02 "" 0x02 ""
0x4B "TCGID" 0x4B "TCGID" OID_TCGID
0x05 "security" 0x05 "security"
0x05 "mechanisms" 0x05 "mechanisms"
0x07 "id-pkix" 0x07 "id-pkix"
@ -251,7 +251,7 @@
0x0d "nsComment" OID_NS_COMMENT 0x0d "nsComment" OID_NS_COMMENT
0x03 "directory" 0x03 "directory"
0x01 "" 0x01 ""
0x03 "employeeNumber" 0x03 "employeeNumber" OID_EMPLOYEE_NUMBER
0x04 "policy" 0x04 "policy"
0x01 "nsSGC" 0x01 "nsSGC"
0x45 "verisign" 0x45 "verisign"
@ -264,3 +264,10 @@
0x06 "recipientNonce" OID_PKI_RECIPIENT_NONCE 0x06 "recipientNonce" OID_PKI_RECIPIENT_NONCE
0x07 "transID" OID_PKI_TRANS_ID 0x07 "transID" OID_PKI_TRANS_ID
0x08 "extensionReq" 0x08 "extensionReq"
0x86 "old-netscape"
0xF7 ""
0x0D ""
0x01 ""
0x09 ""
0x01 "emailAddress" OID_EMAIL_ADDRESS
0x02 "unstructuredName" OID_UNSTRUCTURED_NAME

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"); "ID_CERT_DER_SHA1");
ENUM_END(id_type_names, 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 * coding of X.501 distinguished name
*/ */
typedef struct { typedef struct {
const u_char *name; const u_char *name;
chunk_t oid; int oid;
u_char type; u_char type;
} x501rdn_t; } x501rdn_t;
static const x501rdn_t x501rdns[] = { static const x501rdn_t x501rdns[] = {
{"ND", {oid_ND, 7}, ASN1_PRINTABLESTRING}, {"ND", OID_NAME_DISTINGUISHER, ASN1_PRINTABLESTRING},
{"UID", {oid_UID, 10}, ASN1_PRINTABLESTRING}, {"UID", OID_PILOT_USERID, ASN1_PRINTABLESTRING},
{"DC", {oid_DC, 10}, ASN1_PRINTABLESTRING}, {"DC", OID_PILOT_DOMAIN_COMPONENT, ASN1_PRINTABLESTRING},
{"CN", {oid_CN, 3}, ASN1_PRINTABLESTRING}, {"CN", OID_COMMON_NAME, ASN1_PRINTABLESTRING},
{"S", {oid_S, 3}, ASN1_PRINTABLESTRING}, {"S", OID_SURNAME, ASN1_PRINTABLESTRING},
{"SN", {oid_SN, 3}, ASN1_PRINTABLESTRING}, {"SN", OID_SERIAL_NUMBER, ASN1_PRINTABLESTRING},
{"serialNumber", {oid_SN, 3}, ASN1_PRINTABLESTRING}, {"serialNumber", OID_SERIAL_NUMBER, ASN1_PRINTABLESTRING},
{"C", {oid_C, 3}, ASN1_PRINTABLESTRING}, {"C", OID_COUNTRY, ASN1_PRINTABLESTRING},
{"L", {oid_L, 3}, ASN1_PRINTABLESTRING}, {"L", OID_LOCALITY, ASN1_PRINTABLESTRING},
{"ST", {oid_ST, 3}, ASN1_PRINTABLESTRING}, {"ST", OID_STATE_OR_PROVINCE, ASN1_PRINTABLESTRING},
{"O", {oid_O, 3}, ASN1_PRINTABLESTRING}, {"O", OID_ORGANIZATION, ASN1_PRINTABLESTRING},
{"OU", {oid_OU, 3}, ASN1_PRINTABLESTRING}, {"OU", OID_ORGANIZATION_UNIT, ASN1_PRINTABLESTRING},
{"T", {oid_T, 3}, ASN1_PRINTABLESTRING}, {"T", OID_TITLE, ASN1_PRINTABLESTRING},
{"D", {oid_D, 3}, ASN1_PRINTABLESTRING}, {"D", OID_DESCRIPTION, ASN1_PRINTABLESTRING},
{"N", {oid_N, 3}, ASN1_PRINTABLESTRING}, {"N", OID_NAME, ASN1_PRINTABLESTRING},
{"G", {oid_G, 3}, ASN1_PRINTABLESTRING}, {"G", OID_GIVEN_NAME, ASN1_PRINTABLESTRING},
{"I", {oid_I, 3}, ASN1_PRINTABLESTRING}, {"I", OID_INITIALS, ASN1_PRINTABLESTRING},
{"ID", {oid_ID, 3}, ASN1_PRINTABLESTRING}, {"ID", OID_UNIQUE_IDENTIFIER, ASN1_PRINTABLESTRING},
{"EN", {oid_EN, 10}, ASN1_PRINTABLESTRING}, {"EN", OID_EMPLOYEE_NUMBER, ASN1_PRINTABLESTRING},
{"employeeNumber", {oid_EN, 10}, ASN1_PRINTABLESTRING}, {"employeeNumber", OID_EMPLOYEE_NUMBER, ASN1_PRINTABLESTRING},
{"E", {oid_E, 9}, ASN1_IA5STRING}, {"E", OID_EMAIL_ADDRESS, ASN1_IA5STRING},
{"Email", {oid_E, 9}, ASN1_IA5STRING}, {"Email", OID_EMAIL_ADDRESS, ASN1_IA5STRING},
{"emailAddress", {oid_E, 9}, ASN1_IA5STRING}, {"emailAddress", OID_EMAIL_ADDRESS, ASN1_IA5STRING},
{"UN", {oid_UN, 9}, ASN1_IA5STRING}, {"UN", OID_UNSTRUCTURED_NAME, ASN1_IA5STRING},
{"unstructuredName",{oid_UN, 9}, ASN1_IA5STRING}, {"unstructuredName",OID_UNSTRUCTURED_NAME, ASN1_IA5STRING},
{"TCGID", {oid_TCGID, 12}, ASN1_PRINTABLESTRING} {"TCGID", OID_TCGID, ASN1_PRINTABLESTRING}
}; };
#define X501_RDN_ROOF 26
/** /**
* maximum number of RDNs in atodn() * 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 * 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; chunk_t body;
/* initialize return values */ /* initialize return values */
*oid = chunk_empty; *oid = chunk_empty;
*value = chunk_empty; *value = chunk_empty;
/* if all attributes have been parsed, get next rdn */ /* if all attributes have been parsed, get next rdn */
if (attribute->len <= 0) if (attribute->len <= 0)
{ {
@ -359,19 +292,19 @@ static bool dntoa(chunk_t dn, chunk_t *str)
int oid_code; int oid_code;
bool next; bool next;
bool first = TRUE; bool first = TRUE;
if (!init_rdn(dn, &rdn, &attribute, &next)) if (!init_rdn(dn, &rdn, &attribute, &next))
{ {
return FALSE; return FALSE;
} }
while (next) while (next)
{ {
if (!get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next)) if (!get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next))
{ {
return FALSE; return FALSE;
} }
if (first) if (first)
{ /* first OID/value pair */ { /* first OID/value pair */
first = FALSE; first = FALSE;
@ -380,7 +313,7 @@ static bool dntoa(chunk_t dn, chunk_t *str)
{ /* separate OID/value pair by a comma */ { /* separate OID/value pair by a comma */
update_chunk(str, snprintf(str->ptr,str->len,", ")); update_chunk(str, snprintf(str->ptr,str->len,", "));
} }
/* print OID */ /* print OID */
oid_code = asn1_known_oid(oid); oid_code = asn1_known_oid(oid);
if (oid_code == OID_UNKNOWN) 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; chunk_t oid_a, oid_b, value_a, value_b;
asn1_t type_a, type_b; asn1_t type_a, type_b;
bool next_a, next_b; bool next_a, next_b;
/* same lengths for the DNs */ /* same lengths for the DNs */
if (a.len != b.len) if (a.len != b.len)
{ {
@ -426,7 +359,7 @@ static bool same_dn(chunk_t a, chunk_t b)
{ {
return FALSE; return FALSE;
} }
/* fetch next RDN pair */ /* fetch next RDN pair */
while (next_a && next_b) while (next_a && next_b)
{ {
@ -436,19 +369,19 @@ static bool same_dn(chunk_t a, chunk_t b)
{ {
return FALSE; return FALSE;
} }
/* OIDs must agree */ /* OIDs must agree */
if (oid_a.len != oid_b.len || !memeq(oid_a.ptr, oid_b.ptr, oid_b.len)) if (oid_a.len != oid_b.len || !memeq(oid_a.ptr, oid_b.ptr, oid_b.len))
{ {
return FALSE; return FALSE;
} }
/* same lengths for values */ /* same lengths for values */
if (value_a.len != value_b.len) if (value_a.len != value_b.len)
{ {
return FALSE; return FALSE;
} }
/* printableStrings and email RDNs require uppercase comparison */ /* printableStrings and email RDNs require uppercase comparison */
if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING || if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
(type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_PKCS9_EMAIL))) (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; chunk_t oid_a, oid_b, value_a, value_b;
asn1_t type_a, type_b; asn1_t type_a, type_b;
bool next_a, next_b; bool next_a, next_b;
/* initialize wildcard counter */ /* initialize wildcard counter */
*wildcards = 0; *wildcards = 0;
/* initialize DN parsing */ /* initialize DN parsing */
if (!init_rdn(a, &rdn_a, &attribute_a, &next_a) || if (!init_rdn(a, &rdn_a, &attribute_a, &next_a) ||
!init_rdn(b, &rdn_b, &attribute_b, &next_b)) !init_rdn(b, &rdn_b, &attribute_b, &next_b))
{ {
return FALSE; return FALSE;
} }
/* fetch next RDN pair */ /* fetch next RDN pair */
while (next_a && next_b) while (next_a && next_b)
{ {
@ -512,7 +445,7 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
{ {
return FALSE; return FALSE;
} }
/* does rdn_b contain a wildcard? */ /* does rdn_b contain a wildcard? */
if (value_b.len == 1 && *value_b.ptr == '*') 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; return FALSE;
} }
/* printableStrings and email RDNs require uppercase comparison */ /* printableStrings and email RDNs require uppercase comparison */
if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING || if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
(type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_PKCS9_EMAIL))) (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 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 if (strlen(x501rdns[i].name) == oid.len &&
&& strncasecmp(x501rdns[i].name, oid.ptr, oid.len) == 0) 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; status = NOT_SUPPORTED;
state = UNKNOWN_OID; state = UNKNOWN_OID;
@ -643,14 +579,24 @@ static status_t atodn(char *src, chunk_t *dn)
if (rdn_count < RDN_MAX) if (rdn_count < RDN_MAX)
{ {
rdns[rdn_count] = chunk_t rdn_oid;
asn1_wrap(ASN1_SET, "m",
asn1_wrap(ASN1_SEQUENCE, "mm", rdn_oid = asn1_get_known_oid(x501rdns[i].oid);
asn1_wrap(ASN1_OID, "c", x501rdns[i].oid), if (rdn_oid.len)
asn1_wrap(rdn_type, "c", name) {
) rdns[rdn_count] =
); asn1_wrap(ASN1_SET, "m",
dn_len += rdns[rdn_count++].len; 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 else
{ {
@ -665,12 +611,12 @@ static status_t atodn(char *src, chunk_t *dn)
break; break;
} }
} while (*src++ != '\0'); } while (*src++ != '\0');
/* build the distinguished name sequence */ /* build the distinguished name sequence */
{ {
int i; int i;
u_char *pos = asn1_build_object(dn, ASN1_SEQUENCE, dn_len); u_char *pos = asn1_build_object(dn, ASN1_SEQUENCE, dn_len);
for (i = 0; i < rdn_count; i++) for (i = 0; i < rdn_count; i++)
{ {
memcpy(pos, rdns[i].ptr, rdns[i].len); 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); free(rdns[i].ptr);
} }
} }
if (status != SUCCESS) if (status != SUCCESS)
{ {
free(dn->ptr); free(dn->ptr);