In openssl-0.9.7e and before, X509_NAME_cmp() returned the value 'j' at
this section:
na=sk_X509_NAME_ENTRY_value(a->entries,i);
nb=sk_X509_NAME_ENTRY_value(b->entries,i);
j=na->value->type-nb->value->type;
if (j) return(j);
Starting with openssl-0.9.7f, X509_NAME_cmp() now calls the new
asn1_string_memcmp() function even when 'j' is non-zero and it will
return the return-value of asn1_string_memcmp() as opposed to 'j'.
X509_NAME_cmp() is used by functions such as qsort() and bsearch()
and so it's important that it returns a negative value when the
first argument is smaller and a positive one when the second argument
is greater. The problem now is that X509_NAME_cmp() may return the
return value of asn1_string_memcmp() which does a
int j;
j = a->length - b->length;
if (j)
return j;
before calling memcmp(). The comparison on the length of the strings
may result in a different return value sign than what memcmp() would
return. This may in turn mess up qsort() and bsearch() later.
My fix is to return the original value of 'j' without allowing
asn1_string_memcmp() to override it. This essentially restores the
original return value of X509_NAME_cmp() without modifying the new
additions.
Details of the bug:
>From the openssl-0.9.7f CHANGES file:
+ *) Perform some character comparisons of different types in X509_NAME_cmp:
+ this is needed for some certificates that reencode DNs into UTF8Strings
+ (in violation of RFC3280) and can't or wont issue name rollover
+ certificates.
+ [Steve Henson]
diff -rbB -U 6 openssl-0.9.7e/crypto/x509/x509_cmp.c
openssl-0.9.7f/crypto/x509/x509_cmp.c
--- openssl-0.9.7e/crypto/x509/x509_cmp.c Tue Nov 12 05:23:01 2002
+++ openssl-0.9.7f/crypto/x509/x509_cmp.c Wed Jan 26 12:00:38 2005
@@ -251,39 +251,55 @@
if (la > 0 || lb > 0)
return la - lb;
return 0;
}
+static int asn1_string_memcmp(ASN1_STRING *a, ASN1_STRING *b)
+ {
+ int j;
+ j = a->length - b->length;
+ if (j)
+ return j;
+ return memcmp(a->data, b->data, a->length);
+ }
+
+#define STR_TYPE_CMP
(B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_UTF8STRING)
+
int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
{
int i,j;
X509_NAME_ENTRY *na,*nb;
- if (sk_X509_NAME_ENTRY_num(a->entries)
- != sk_X509_NAME_ENTRY_num(b->entries))
- return sk_X509_NAME_ENTRY_num(a->entries)
- -sk_X509_NAME_ENTRY_num(b->entries);
+ unsigned long nabit, nbbit;
+
+ j = sk_X509_NAME_ENTRY_num(a->entries)
+ - sk_X509_NAME_ENTRY_num(b->entries);
+ if (j)
+ return j;
for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
{
na=sk_X509_NAME_ENTRY_value(a->entries,i);
nb=sk_X509_NAME_ENTRY_value(b->entries,i);
j=na->value->type-nb->value->type;
- if (j) return(j);
- if (na->value->type == V_ASN1_PRINTABLESTRING)
+ if (j)
+ {
+ nabit = ASN1_tag2bit(na->value->type);
+ nbbit = ASN1_tag2bit(nb->value->type);
+ if (!(nabit & STR_TYPE_CMP) ||
+ !(nbbit & STR_TYPE_CMP))
+ return j;
+ j = asn1_string_memcmp(na->value, nb->value);
+ }
+ else if (na->value->type == V_ASN1_PRINTABLESTRING)
and my patch to fix it is by returning the value of 'j' this function returned
before:
--- openssl-0.9.8d/crypto/x509/x509_cmp.c Tue Nov 30 17:45:30 2004
+++ openssl-0.9.8d.new/crypto/x509/x509_cmp.c Thu Nov 2 14:42:11 2006
@@ -283,12 +283,17 @@
j=na->value->type-nb->value->type;
if (j)
{
+ int j2;
nabit = ASN1_tag2bit(na->value->type);
nbbit = ASN1_tag2bit(nb->value->type);
if (!(nabit & STR_TYPE_CMP) ||
!(nbbit & STR_TYPE_CMP))
return j;
- j = asn1_string_memcmp(na->value, nb->value);
+ j2 = asn1_string_memcmp(na->value, nb->value);
+ if (j2)
+ return j;
+ else
+ j = 0;
}
else if (na->value->type == V_ASN1_PRINTABLESTRING)
j=nocase_spacenorm_cmp(na->value, nb->value);
____________________________________________________________________________________
Everyone is raving about the all-new Yahoo! Mail
(http://advision.webevents.yahoo.com/mailbeta/)
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [email protected]
Automated List Manager [EMAIL PROTECTED]