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