aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libstrongswan/asn1/oid.txt47
-rw-r--r--src/libstrongswan/utils/identification.c204
2 files changed, 102 insertions, 149 deletions
diff --git a/src/libstrongswan/asn1/oid.txt b/src/libstrongswan/asn1/oid.txt
index 6bb765787..1efdebb57 100644
--- a/src/libstrongswan/asn1/oid.txt
+++ b/src/libstrongswan/asn1/oid.txt
@@ -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
diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c
index 213642e9a..a274757df 100644
--- a/src/libstrongswan/utils/identification.c
+++ b/src/libstrongswan/utils/identification.c
@@ -59,110 +59,42 @@ ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_CERT_DER_SHA1, ID_KEY_ID,
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);