moved RDN OIDs to oid.txt, use asn1_get_known_oid() for lookup
This commit is contained in:
parent
56807f35b9
commit
c31687daa7
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue