Simon Josefsson wrote:
Edgar Fuß<ef(a)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-c...
Yes, callgrind is pretty cool, much more useful than old gprof-style
profilers. Though as you note, the runtimes of any valgrind tool can be pretty
extreme. My tweaked version of FunctionCheck is also useful when you can
afford to compile an instrumented version of your code. Faster runtimes in
exchange for extra compile time - frequently it's a worthwhile tradeoff.
http://highlandsun.com/hyc/#fncchk
> 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.
You're already approaching GnuTLS version 2.4. If optimizing now is premature,
when will it actually be time to optimize?
--
-- Howard Chu
Chief Architect, Symas Corp.
http://www.symas.com
Director, Highland Sun
http://highlandsun.com/hyc/
Chief Architect, OpenLDAP
http://www.openldap.org/project/