Bug 329067, r=nelson,alexei "NSS encodes DN attributes with wrong type

git-svn-id: svn://10.0.0.236/trunk@225305 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
neil.williams%sun.com
2007-04-30 23:31:25 +00:00
parent 896023e188
commit 5988367130

View File

@@ -43,52 +43,59 @@
#include "secitem.h"
#include "secerr.h"
/* for better RFC 2253 compliance. */
#define NSS_STRICT_RFC_2253_VALUES_ONLY 1
struct NameToKind {
const char * name;
unsigned int maxLen; /* max bytes in UTF8 encoded string value */
SECOidTag kind;
int valueType;
};
/* local type for directory string--could be printable_string or utf8 */
#define SEC_ASN1_DS SEC_ASN1_HIGH_TAG_NUMBER
/* Add new entries to this table, and maybe to function CERT_ParseRFC1485AVA */
static const struct NameToKind name2kinds[] = {
/* keywords given in RFC 2253 */
{ "CN", 64, SEC_OID_AVA_COMMON_NAME },
{ "L", 128, SEC_OID_AVA_LOCALITY },
{ "ST", 128, SEC_OID_AVA_STATE_OR_PROVINCE },
{ "O", 64, SEC_OID_AVA_ORGANIZATION_NAME },
{ "OU", 64, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME },
{ "C", 2, SEC_OID_AVA_COUNTRY_NAME },
{ "STREET", 128, SEC_OID_AVA_STREET_ADDRESS },
{ "DC", 128, SEC_OID_AVA_DC },
{ "UID", 256, SEC_OID_RFC1274_UID },
/* IANA registered type names
(See: http://www.iana.org/assignments/ldap-parameters) */
/* RFC 3280,4630 MUST SUPPORT */
{ "CN", 64, SEC_OID_AVA_COMMON_NAME, SEC_ASN1_DS},
{ "ST", 128, SEC_OID_AVA_STATE_OR_PROVINCE,
SEC_ASN1_DS},
{ "O", 64, SEC_OID_AVA_ORGANIZATION_NAME,
SEC_ASN1_DS},
{ "OU", 64, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
SEC_ASN1_DS},
{ "dnQualifier", 32767, SEC_OID_AVA_DN_QUALIFIER, SEC_ASN1_PRINTABLE_STRING},
{ "C", 2, SEC_OID_AVA_COUNTRY_NAME, SEC_ASN1_PRINTABLE_STRING},
{ "serialNumber", 64, SEC_OID_AVA_SERIAL_NUMBER,SEC_ASN1_PRINTABLE_STRING},
/* RFC 3280,4630 SHOULD SUPPORT */
{ "L", 128, SEC_OID_AVA_LOCALITY, SEC_ASN1_DS},
{ "title", 64, SEC_OID_AVA_TITLE, SEC_ASN1_DS},
{ "SN", 64, SEC_OID_AVA_SURNAME, SEC_ASN1_DS},
{ "givenName", 64, SEC_OID_AVA_GIVEN_NAME, SEC_ASN1_DS},
{ "initials", 64, SEC_OID_AVA_INITIALS, SEC_ASN1_DS},
{ "generationQualifier",
64, SEC_OID_AVA_GENERATION_QUALIFIER,
SEC_ASN1_DS},
/* RFC 3280,4630 MAY SUPPORT */
{ "DC", 128, SEC_OID_AVA_DC, SEC_ASN1_IA5_STRING},
/* values from draft-ietf-ldapbis-user-schema-05 (not in RFC 3280) */
{ "postalAddress", 128, SEC_OID_AVA_POSTAL_ADDRESS, SEC_ASN1_DS},
{ "postalCode", 40, SEC_OID_AVA_POSTAL_CODE, SEC_ASN1_DS},
{ "postOfficeBox", 40, SEC_OID_AVA_POST_OFFICE_BOX,SEC_ASN1_DS},
{ "houseIdentifier",64, SEC_OID_AVA_HOUSE_IDENTIFIER,SEC_ASN1_DS},
/* legacy keywords */
{ "MAIL", 256, SEC_OID_RFC1274_MAIL, SEC_ASN1_IA5_STRING},
{ "UID", 256, SEC_OID_RFC1274_UID, SEC_ASN1_DS},
/* end of IANA registered type names */
{ "E", 128, SEC_OID_PKCS9_EMAIL_ADDRESS,SEC_ASN1_DS},
#ifndef NSS_STRICT_RFC_2253_KEYWORDS_ONLY
/* NSS legacy keywords */
{ "dnQualifier", 32767, SEC_OID_AVA_DN_QUALIFIER },
{ "E", 128, SEC_OID_PKCS9_EMAIL_ADDRESS },
{ "MAIL", 256, SEC_OID_RFC1274_MAIL },
#ifndef NSS_LEGACY_KEYWORDS_ONLY
/* values from draft-ietf-ldapbis-user-schema-05 */
{ "SN", 64, SEC_OID_AVA_SURNAME },
{ "serialNumber", 64, SEC_OID_AVA_SERIAL_NUMBER },
{ "title", 64, SEC_OID_AVA_TITLE },
{ "postalAddress", 128, SEC_OID_AVA_POSTAL_ADDRESS },
{ "postalCode", 40, SEC_OID_AVA_POSTAL_CODE },
{ "postOfficeBox", 40, SEC_OID_AVA_POST_OFFICE_BOX },
{ "givenName", 64, SEC_OID_AVA_GIVEN_NAME },
{ "initials", 64, SEC_OID_AVA_INITIALS },
{ "generationQualifier", 64, SEC_OID_AVA_GENERATION_QUALIFIER },
{ "houseIdentifier", 64, SEC_OID_AVA_HOUSE_IDENTIFIER },
#if 0 /* removed. Not yet in any IETF draft or RFC. */
{ "pseudonym", 64, SEC_OID_AVA_PSEUDONYM },
{ "pseudonym", 64, SEC_OID_AVA_PSEUDONYM, SEC_ASN1_DS},
#endif
#endif
#endif
{ 0, 256, SEC_OID_UNKNOWN }
{ 0, 256, SEC_OID_UNKNOWN , 0},
};
#define C_DOUBLE_QUOTE '\042'
@@ -146,21 +153,6 @@ IsPrintable(unsigned char *data, unsigned len)
return PR_TRUE;
}
static PRBool
Is7Bit(unsigned char *data, unsigned len)
{
unsigned char ch, *end;
end = data + len;
while (data < end) {
ch = *data++;
if ((ch & 0x80)) {
return PR_FALSE;
}
}
return PR_TRUE;
}
static void
skipSpace(char **pbp, char *endptr)
{
@@ -313,8 +305,6 @@ CERT_ParseRFC1485AVA(PRArenaPool *arena, char **pbp, char *endptr,
{
CERTAVA *a;
const struct NameToKind *n2k;
int vt;
int valLen;
char *bp;
char tagBuf[32];
@@ -340,31 +330,26 @@ CERT_ParseRFC1485AVA(PRArenaPool *arena, char **pbp, char *endptr,
*pbp = bp;
for (n2k = name2kinds; n2k->name; n2k++) {
int vt,
valLen;
if (PORT_Strcasecmp(n2k->name, tagBuf) == 0) {
valLen = PORT_Strlen(valBuf);
if (n2k->kind == SEC_OID_AVA_COUNTRY_NAME) {
vt = SEC_ASN1_PRINTABLE_STRING;
if (valLen != 2) {
PORT_SetError(SEC_ERROR_INVALID_AVA);
return 0;
}
if (!IsPrintable((unsigned char*) valBuf, 2)) {
PORT_SetError(SEC_ERROR_INVALID_AVA);
return 0;
}
} else if ((n2k->kind == SEC_OID_PKCS9_EMAIL_ADDRESS) ||
(n2k->kind == SEC_OID_RFC1274_MAIL)) {
vt = SEC_ASN1_IA5_STRING;
} else {
/* Hack -- for rationale see X.520 DirectoryString defn */
if (IsPrintable((unsigned char*)valBuf, valLen)) {
if (n2k->kind == SEC_OID_AVA_COUNTRY_NAME && valLen != 2) {
PORT_SetError(SEC_ERROR_INVALID_AVA);
return 0;
}
vt = n2k->valueType;
if (vt == SEC_ASN1_PRINTABLE_STRING &&
!IsPrintable((unsigned char*) valBuf, valLen)) {
PORT_SetError(SEC_ERROR_INVALID_AVA);
return 0;
}
if (vt == SEC_ASN1_DS) {
/* RFC 4630: choose PrintableString or UTF8String */
if (IsPrintable((unsigned char*) valBuf, valLen))
vt = SEC_ASN1_PRINTABLE_STRING;
} else if (Is7Bit((unsigned char *)valBuf, valLen)) {
vt = SEC_ASN1_T61_STRING;
} else {
/* according to RFC3280, UTF8String is preferred encoding */
else
vt = SEC_ASN1_UTF8_STRING;
}
}
a = CERT_CreateAVA(arena, n2k->kind, vt, (char *) valBuf);
return a;