[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: Strange TLS behaviour with slapd 2.3.30 on Debian Etch



Edgar Fuß <ef@math.uni-bonn.de> writes:

>> I already have problems with /etc/ssl/certs directory, when I use CACertDirs
>> with a lot of certificates in the directory, it was awfully long to get
>> the result, so I switch to CaCertFile instead ... And the problem is only
>> with pam_ldap and not with ldapsearch (or the contrary, I don't remember),
>> and the pam_ldap was linked against gnutls and ldapsearch linked against
>> openssl ...
> We experienced the same problem. The culprit turned out to be libldap2 (opposed to libldap-2.3-0), which has GNUTLS support patched in by Debian. To the contrary, ldapsearch is linked against libldap-2.3-0, which uses OpenSSL.
>
> More precisely, the problem is get_ca_list() in libraries/libldap/tls.c. If you profile a test program like
>
> #include <stdlib.h>
> #include <dirent.h>
> #include <stdio.h>
> #include <sys/param.h>
> #include <sys/stat.h>
> #include <gnutls/gnutls.h>
> gnutls_certificate_credentials_t ca_list;
>
> int main(int argc, char *argv[]) {
> 	DIR *d;
> 	struct dirent *dent;
> 	char ca_file[MAXPATHLEN];
> 	struct stat s;
> 	char *dir;
>
> 	if (argc != 2) exit(1);
> 	dir = argv[1];
> 	d = opendir(dir);
> 	if (d == NULL) exit(1);
> 	gnutls_global_init();
> 	gnutls_certificate_allocate_credentials(&ca_list);
> 	while ((dent = readdir(d)) != NULL) {
> 		snprintf(ca_file, sizeof ca_file, "%s/%s", dir, dent->d_name);
> 		stat(ca_file, &s);
> 		if (!S_ISREG(s.st_mode)) continue;
> 		gnutls_certificate_set_x509_trust_file(ca_list, ca_file, GNUTLS_X509_FMT_PEM);
> 	}
> 	closedir(d);
> }
>
> you see unreasonable amounts of time being spent in memory and string manipulation routines.

Edgar, thanks for providing test code.  I profiled and improved GnuTLS
to execute your code faster, on my system the time was reduced from 40
seconds to 0.3 seconds.  I found debugging and fixing this problem
interesting so I blogged about it:

http://blog.josefsson.org/2008/02/27/real-world-performance-tuning-with-callgrind/

> Not being an TLS/SSL expert, I'm wondering why you need to add all
> those certificates in the first place. I thought the whole point of
> all those <subject hash>.<serial> links in /etc/openssl/certs (or
> whatever) was that a client could find a CA certificate simply by
> hashing the subject.

GnuTLS doesn't support hashed certificate directories.  Further, TLS
servers need to send a list of names of trusted certificates to clients,
so the server has to open and parse all local trust roots anyway.  Right
now, this is done for clients too, since the relevant code in GnuTLS
doesn't know whether it will be used as a client or server.  I hope the
new code will be fast enough so that it isn't a bottle-neck.  I suppose
that it could be optimized further, so that it isn't done for clients at
all, but let's not optimize prematurely.

Thanks,
/Simon