Hi, Steve
There is a bug in my previous patch as well, the X509_NAME_bytescmp() should be
static int X509_NAME_bytescmp(const X509_NAME *a, const X509_NAME *b)
{
#ifndef OPENSSL_NO_BUFFER
int j;
j = a->bytes->length - b->bytes->length;
int ret = memcmp(a->bytes->data, b->bytes->data,
j>0?b->bytes->length:a->bytes->length);
/* XXX this is to make sure memcmp() behalf the same as strcmp() */
if (!ret) return j;
return ret;
#else
return strcmp(a->bytes, b->bytes);
#endif
}
I attached the updated patch for your information. Since I'm not quite
sure the logic in x509_cmp.c
Thanks
Jeff
On Mon, Mar 2, 2009 at 11:17 AM, Jeff Wu <[email protected]> wrote:
> Hi, Steve
>
> Thanks for quick response. Since the function (X509_NAME_cmp) is used
> for sort and bsearh, we'd better make sure the return value is
> consistent. say a>b and b>c, then a>c is always expected. My previous
> patch has a clear logic to guarantee this but I am not sure if the fix
> in current snapshot also has the same consistence. It works with the
> test CA files though.
>
> Regards,
>
> Jeff
>
>
> On Fri, Feb 27, 2009 at 3:26 PM, Stephen Henson via RT <[email protected]>
> wrote:
>>
>> Please try this against a recent snapshot of 0.9.8-stable. An update to
>> X509_NAME_cmp which was applied recently should address this.
>>
>> Steve.
>>
>>
>>
>
diff -b -U 10 --show-c-function -ur openssl-0.9.8j-orig/crypto/x509/x509_cmp.c openssl-0.9.8j-work/crypto/x509/x509_cmp.c
--- openssl-0.9.8j-orig/crypto/x509/x509_cmp.c 2008-09-15 12:56:12.000000000 -0700
+++ openssl-0.9.8j-work/crypto/x509/x509_cmp.c 2009-03-02 16:06:36.000000000 -0800
@@ -256,68 +256,83 @@ static int nocase_spacenorm_cmp(const AS
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);
}
+static int X509_NAME_bytescmp(const X509_NAME *a, const X509_NAME *b)
+ {
+#ifndef OPENSSL_NO_BUFFER
+ int j;
+ j = a->bytes->length - b->bytes->length;
+ int ret = memcmp(a->bytes->data, b->bytes->data, j>0?b->bytes->length:a->bytes->length);
+ if (!ret) return j;
+ return ret;
+#else
+ return strcmp(a->bytes, b->bytes);
+#endif
+ }
+
#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;
unsigned long nabit, nbbit;
+ int bytes_cmp = X509_NAME_bytescmp(a, b);
+ if (!bytes_cmp) return 0;
+
j = sk_X509_NAME_ENTRY_num(a->entries)
- sk_X509_NAME_ENTRY_num(b->entries);
- if (j)
- return j;
+ if (j) return bytes_cmp;
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)
{
nabit = ASN1_tag2bit(na->value->type);
nbbit = ASN1_tag2bit(nb->value->type);
if (!(nabit & STR_TYPE_CMP) ||
!(nbbit & STR_TYPE_CMP))
- return j;
+ return bytes_cmp;
j = asn1_string_memcmp(na->value, nb->value);
}
else 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 = asn1_string_memcmp(na->value, nb->value);
- if (j) return(j);
+ if (j) return bytes_cmp;
j=na->set-nb->set;
- if (j) return(j);
+ if (j) return bytes_cmp;
}
/* We will check the object types after checking the values
* since the values will more often be different than the object
* types. */
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=OBJ_cmp(na->object,nb->object);
- if (j) return(j);
+ if (j) return bytes_cmp;
}
return(0);
}
#ifndef OPENSSL_NO_MD5
/* I now DER encode the name and hash it. Since I cache the DER encoding,
* this is reasonably efficient. */
unsigned long X509_NAME_hash(X509_NAME *x)
{
unsigned long ret=0;
Only in openssl-0.9.8j-work/crypto/x509: .x509_cmp.c.swp