RT3495: Add a hash for faster dup detection.
authorToshikuni Fukaya <toshikuni-fukaya@cybozu.co.jp>
Wed, 3 Feb 2016 18:08:45 +0000 (13:08 -0500)
committerRich Salz <rsalz@openssl.org>
Thu, 11 Feb 2016 17:19:34 +0000 (12:19 -0500)
Updated for 1.1 by Rich Salz

Reviewed-by: Richard Levitte <levitte@openssl.org>
ssl/ssl_cert.c

index 68c892442519e22211c2654da08d2cd2ed4512b0..dc58e25752eab702c8e6640d0f159f34d6b87cd4 100644 (file)
@@ -1,6 +1,3 @@
-/*
- * ! \file ssl/ssl_cert.c
- */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #endif
 
 #include "internal/o_dir.h"
-#include <openssl/objects.h>
+#include <openssl/lhash.h>
 #include <openssl/bio.h>
 #include <openssl/pem.h>
 #include <openssl/x509v3.h>
@@ -642,11 +639,23 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
     return (add_client_CA(&(ctx->client_CA), x));
 }
 
-static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
+static int xname_sk_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
 {
     return (X509_NAME_cmp(*a, *b));
 }
 
+static int xname_cmp(const X509_NAME *a, const X509_NAME *b)
+{
+    return X509_NAME_cmp(a, b);
+}
+
+static unsigned long xname_hash(const X509_NAME *a)
+{
+    return X509_NAME_hash((X509_NAME *)a);
+}
+
+DEFINE_LHASH_OF(X509_NAME);
+
 /**
  * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
  * it doesn't really have anything to do with clients (except that a common use
@@ -657,16 +666,14 @@ static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
  */
 STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
 {
-    BIO *in;
+    BIO *in = BIO_new(BIO_s_file());
     X509 *x = NULL;
     X509_NAME *xn = NULL;
-    STACK_OF(X509_NAME) *ret = NULL, *sk;
-
-    sk = sk_X509_NAME_new(xname_cmp);
+    STACK_OF(X509_NAME) *ret = NULL;
+    LHASH_OF(X509_NAME) *name_hash =
+        lh_X509_NAME_new(xname_hash, xname_cmp);
 
-    in = BIO_new(BIO_s_file());
-
-    if ((sk == NULL) || (in == NULL)) {
+    if ((name_hash == NULL) || (in == NULL)) {
         SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE);
         goto err;
     }
@@ -690,10 +697,11 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
         xn = X509_NAME_dup(xn);
         if (xn == NULL)
             goto err;
-        if (sk_X509_NAME_find(sk, xn) >= 0)
+        if (lh_X509_NAME_retrieve(name_hash, xn) != NULL) {
+            /* Duplicate. */
             X509_NAME_free(xn);
-        else {
-            sk_X509_NAME_push(sk, xn);
+        else {
+            lh_X509_NAME_insert(name_hash, xn);
             sk_X509_NAME_push(ret, xn);
         }
     }
@@ -703,9 +711,9 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
     sk_X509_NAME_pop_free(ret, X509_NAME_free);
     ret = NULL;
  done:
-    sk_X509_NAME_free(sk);
     BIO_free(in);
     X509_free(x);
+    lh_X509_NAME_free(name_hash);
     if (ret != NULL)
         ERR_clear_error();
     return (ret);
@@ -729,7 +737,7 @@ int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
     int ret = 1;
     int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b);
 
-    oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp);
+    oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_sk_cmp);
 
     in = BIO_new(BIO_s_file());