From c81a15099a7b6a8c4ace55a2554005656aa8a307 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Sat, 9 Nov 2002 21:52:20 +0000 Subject: [PATCH] X509_NAME_cmp() now compares PrintableString and emailAddress with a value of type ia5String correctly. PR: 244 --- CHANGES | 5 ++ crypto/x509/x509_cmp.c | 109 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 111 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index a16d78daea..43565ec0e3 100644 --- a/CHANGES +++ b/CHANGES @@ -1997,6 +1997,11 @@ des-cbc 3624.96k 5258.21k 5530.91k 5624.30k 5628.26k Changes between 0.9.6g and 0.9.6h [xx XXX xxxx] + *) Change X509_NAME_cmp() so it applies the special rules on handling + DN values that are of type PrintableString, as well as RDNs of type + emailAddress where the value has the type ia5String. + [stefank@valicert.com via Richard Levitte] + *) Add a SSL_SESS_CACHE_NO_INTERNAL_STORE flag to take over half the job SSL_SESS_CACHE_NO_INTERNAL_LOOKUP was inconsistently doing, define a new flag (SSL_SESS_CACHE_NO_INTERNAL) to be diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c index 415e5f3863..474f6de50d 100644 --- a/crypto/x509/x509_cmp.c +++ b/crypto/x509/x509_cmp.c @@ -159,6 +159,99 @@ int X509_cmp(const X509 *a, const X509 *b) } #endif + +/* Case insensitive string comparision */ +static int nocase_cmp(const ASN1_STRING *a, const ASN1_STRING *b) +{ + int i; + + if (a->length != b->length) + return (a->length - b->length); + + for (i=0; ilength; i++) + { + int ca, cb; + + ca = tolower(a->data[i]); + cb = tolower(b->data[i]); + + if (ca != cb) + return(ca-cb); + } + return 0; +} + +/* Case insensitive string comparision with space normalization + * Space normalization - ignore leading, trailing spaces, + * multiple spaces between characters are replaced by single space + */ +static int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b) +{ + unsigned char *pa = NULL, *pb = NULL; + int la, lb; + + la = a->length; + lb = b->length; + pa = a->data; + pb = b->data; + + /* skip leading spaces */ + while (la > 0 && isspace(*pa)) + { + la--; + pa++; + } + while (lb > 0 && isspace(*pb)) + { + lb--; + pb++; + } + + /* skip trailing spaces */ + while (la > 0 && isspace(pa[la-1])) + la--; + while (lb > 0 && isspace(pb[lb-1])) + lb--; + + /* compare strings with space normalization */ + while (la > 0 && lb > 0) + { + int ca, cb; + + /* compare character */ + ca = tolower(*pa); + cb = tolower(*pb); + if (ca != cb) + return (ca - cb); + + pa++; pb++; + la--; lb--; + + if (la <= 0 || lb <= 0) + break; + + /* is white space next character ? */ + if (isspace(*pa) && isspace(*pb)) + { + /* skip remaining white spaces */ + while (la > 0 && isspace(*pa)) + { + la--; + pa++; + } + while (lb > 0 && isspace(*pb)) + { + lb--; + pb++; + } + } + } + if (la > 0 || lb > 0) + return la - lb; + + return 0; +} + int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) { int i,j; @@ -172,10 +265,20 @@ int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) { na=sk_X509_NAME_ENTRY_value(a->entries,i); nb=sk_X509_NAME_ENTRY_value(b->entries,i); - j=na->value->length-nb->value->length; + j=na->value->type-nb->value->type; if (j) return(j); - j=memcmp(na->value->data,nb->value->data, - na->value->length); + if (na->value->type == V_ASN1_PRINTABLESTRING) + j=nocase_spacenorm_cmp(na->value, nb->value); + else if (na->value->type == V_ASN1_IA5STRING + && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress) + j=nocase_cmp(na->value, nb->value); + else + { + j=na->value->length-nb->value->length; + if (j) return(j); + j=memcmp(na->value->data,nb->value->data, + na->value->length); + } if (j) return(j); j=na->set-nb->set; if (j) return(j); -- 2.25.1