diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2006-07-18 12:36:19 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2006-07-18 12:36:19 +0000 |
commit | 450ea83495f8da9d9331da7a724514158d618a6f (patch) | |
tree | 2ea54540139764fb5347f7722aac81e2820f3951 /crypto/x509 | |
parent | af8c1d81a3366009fbf7b563ac629d6a33880012 (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.h | 2 | ||||
-rw-r--r-- | crypto/x509/x509_cmp.c | 159 |
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. */ |