summaryrefslogtreecommitdiffstats
path: root/crypto/x509
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2006-07-18 12:36:19 +0000
committerDr. Stephen Henson <steve@openssl.org>2006-07-18 12:36:19 +0000
commit450ea83495f8da9d9331da7a724514158d618a6f (patch)
tree2ea54540139764fb5347f7722aac81e2820f3951 /crypto/x509
parentaf8c1d81a3366009fbf7b563ac629d6a33880012 (diff)
Store canonical encodings of Name structures. Update X509_NAME_cmp() to use
them.
Diffstat (limited to 'crypto/x509')
-rw-r--r--crypto/x509/x509.h2
-rw-r--r--crypto/x509/x509_cmp.c159
2 files changed, 20 insertions, 141 deletions
diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
index f9d7e56219..b068632910 100644
--- a/crypto/x509/x509.h
+++ b/crypto/x509/x509.h
@@ -190,6 +190,8 @@ struct X509_name_st
char *bytes;
#endif
unsigned long hash; /* Keep the hash around for lookups */
+ unsigned char *canon_enc;
+ int canon_enclen;
} /* X509_NAME */;
DECLARE_STACK_OF(X509_NAME)
diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c
index d04225a932..4f157ba807 100644
--- a/crypto/x509/x509_cmp.c
+++ b/crypto/x509/x509_cmp.c
@@ -162,159 +162,36 @@ 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; i<a->length; 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 X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
{
- int ca, cb;
-
- /* compare character */
- ca = tolower(*pa);
- cb = tolower(*pb);
- if (ca != cb)
- return (ca - cb);
-
- pa++; pb++;
- la--; lb--;
+ int ret;
- if (la <= 0 || lb <= 0)
- break;
+ /* Ensure canonical encoding is present */
- /* is white space next character ? */
- if (isspace(*pa) && isspace(*pb))
+ if (!a->canon_enc)
{
- /* skip remaining white spaces */
- while (la > 0 && isspace(*pa))
- {
- la--;
- pa++;
- }
- while (lb > 0 && isspace(*pb))
- {
- lb--;
- pb++;
- }
+ ret = i2d_X509_NAME((X509_NAME *)a, NULL);
+ if (ret < 0)
+ return -2;
}
- }
- 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)
+ if (!b->canon_enc)
+ {
+ ret = i2d_X509_NAME((X509_NAME *)b, NULL);
+ if (ret < 0)
+ return -2;
+ }
-int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
- {
- int i,j;
- X509_NAME_ENTRY *na,*nb;
+ ret = a->canon_enclen - b->canon_enclen;
- unsigned long nabit, nbbit;
+ if (ret)
+ return ret;
- 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)
- {
- 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 = asn1_string_memcmp(na->value, nb->value);
- if (j) return(j);
- j=na->set-nb->set;
- if (j) return(j);
- }
+ return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
- /* 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);
- }
- 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. */