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

Reply via email to