Perform partial comparison of different character types in X509_NAME_cmp().
authorDr. Stephen Henson <steve@openssl.org>
Wed, 1 Dec 2004 01:45:57 +0000 (01:45 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 1 Dec 2004 01:45:57 +0000 (01:45 +0000)
CHANGES
crypto/x509/x509_cmp.c

diff --git a/CHANGES b/CHANGES
index a82dd796c46e326d84e6bdc86d281534ae534c90..cc94765388037a43dddf0d29cf524c111269d69e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,12 @@
 
  Changes between 0.9.7e and 0.9.7f  [XX xxx XXXX]
 
+  *) 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]
+
   *) Make an explicit check during certificate validation to see that
      the CA setting in each certificate on the chain is correct.  As a
      side effect always do the following basic checks on extensions,
index f460102f49785c8f8eb35d3f9111f437b53bd4bf..4e71ade1abdfdcedae0a9c5b4ae91ea8121e3934 100644 (file)
@@ -254,33 +254,49 @@ static int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
        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)
                        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);
-                       }
+                       j = asn1_string_memcmp(na->value, nb->value);
                if (j) return(j);
                j=na->set-nb->set;
                if (j) return(j);