]> git.sur5r.net Git - openldap/commitdiff
ITS#7374 - MozNSS: better file name matching for hashed CA certificate directory
authorJan Vcelak <jvcelak@redhat.com>
Wed, 29 Aug 2012 14:23:52 +0000 (16:23 +0200)
committerQuanah Gibson-Mount <quanah@ub16.quanah.org>
Fri, 6 Oct 2017 17:44:13 +0000 (10:44 -0700)
CA certificate files in OpenSSL compatible CACERTDIR were loaded if the
file extension was '.0'. However the file name should be 8 letters long
certificate hash of the certificate subject name, followed by a numeric
suffix which is used to differentiate between two certificates with the
same subject name.

Wit this patch, certificate file names are matched correctly (using
regular expressions).

libraries/libldap/tls_m.c

index a8691c59776cbe51658ab23bff17eb579549d80c..e5e950cad08876f83c76ae46aaa229ce03e4263b 100644 (file)
@@ -38,6 +38,7 @@
 #include <ac/unistd.h>
 #include <ac/param.h>
 #include <ac/dirent.h>
+#include <ac/regex.h>
 
 #include "ldap-int.h"
 #include "ldap-tls.h"
@@ -118,9 +119,7 @@ static const PRIOMethods tlsm_PR_methods;
 
 #define PEM_LIBRARY    "nsspem"
 #define PEM_MODULE     "PEM"
-/* hash files for use with cacertdir have this file name suffix */
-#define PEM_CA_HASH_FILE_SUFFIX        ".0"
-#define PEM_CA_HASH_FILE_SUFFIX_LEN 2
+#define PEM_CA_HASH_FILE_REGEX "^[0-9a-f]{8}\\.[0-9]+$"
 
 static SECMODModule *pem_module;
 
@@ -1473,6 +1472,7 @@ tlsm_init_ca_certs( tlsm_ctx *ctx, const char *cacertfile, const char *cacertdir
                PRDir *dir;
                PRDirEntry *entry;
                PRStatus fistatus = PR_FAILURE;
+               regex_t hashfile_re;
 
                memset( &fi, 0, sizeof(fi) );
                fistatus = PR_GetFileInfo( cacertdir, &fi );
@@ -1502,20 +1502,30 @@ tlsm_init_ca_certs( tlsm_ctx *ctx, const char *cacertfile, const char *cacertdir
                        goto done;
                }
 
+               if ( regcomp( &hashfile_re, PEM_CA_HASH_FILE_REGEX, REG_NOSUB|REG_EXTENDED ) != 0 ) {
+                       Debug( LDAP_DEBUG_ANY, "TLS: cannot compile regex for CA hash files matching\n", 0, 0, 0 );
+                       goto done;
+               }
+
                do {
                        entry = PR_ReadDir( dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN );
                        if ( ( NULL != entry ) && ( NULL != entry->name ) ) {
                                char *fullpath = NULL;
-                               char *ptr;
+                               int match;
 
-                               ptr = PL_strrstr( entry->name, PEM_CA_HASH_FILE_SUFFIX );
-                               if ( ( ptr == NULL ) || ( *(ptr + PEM_CA_HASH_FILE_SUFFIX_LEN) != '\0' ) ) {
+                               match = regexec( &hashfile_re, entry->name, 0, NULL, 0 );
+                               if ( match == REG_NOMATCH ) {
                                        Debug( LDAP_DEBUG_TRACE,
-                                                  "TLS: file %s does not end in [%s] - does not appear to be a CA certificate "
-                                                  "directory file with a properly hashed file name - skipping.\n",
-                                                  entry->name, PEM_CA_HASH_FILE_SUFFIX, 0 );
+                                                  "TLS: skipping '%s' - filename does not have expected format "
+                                                  "(certificate hash with numeric suffix)\n", entry->name, 0, 0 );
+                                       continue;
+                               } else if ( match != 0 ) {
+                                       Debug( LDAP_DEBUG_ANY,
+                                                  "TLS: cannot execute regex for CA hash file matching (%d).\n",
+                                                  match, 0, 0 );
                                        continue;
                                }
+
                                fullpath = PR_smprintf( "%s/%s", cacertdir, entry->name );
                                if ( !tlsm_add_cert_from_file( ctx, fullpath, isca ) ) {
                                        Debug( LDAP_DEBUG_TRACE,
@@ -1531,6 +1541,7 @@ tlsm_init_ca_certs( tlsm_ctx *ctx, const char *cacertfile, const char *cacertdir
                                PR_smprintf_free( fullpath );
                        }
                } while ( NULL != entry );
+               regfree ( &hashfile_re );
                PR_CloseDir( dir );
        }
 done: