592250e
MozNSS: better file name matching for hashed CA  certificate directory
592250e
592250e
CA certificate files in OpenSSL compatible CACERTDIR were loaded if the file extension was '.0'. However the file name
592250e
should be 8 letters long certificate hash of the certificate subject name, followed by a numeric suffix which is used
592250e
to differentiate between two certificates with the same subject name.
592250e
592250e
Wit this patch, certificate file names are matched correctly (using regular expressions).
592250e
592250e
Author: Jan Vcelak <jvcelak@redhat.com>
592250e
Upstream ITS: #7374
592250e
Resolves: #852786
592250e
592250e
diff --git a/libraries/libldap/tls_m.c b/libraries/libldap/tls_m.c
592250e
index 5e49fc5..61d71d4 100644
592250e
--- a/libraries/libldap/tls_m.c
592250e
+++ b/libraries/libldap/tls_m.c
592250e
@@ -38,6 +38,7 @@
592250e
 #include <ac/unistd.h>
592250e
 #include <ac/param.h>
592250e
 #include <ac/dirent.h>
592250e
+#include <ac/regex.h>
592250e
 
592250e
 #include "ldap-int.h"
592250e
 #include "ldap-tls.h"
592250e
@@ -118,9 +119,7 @@ static const PRIOMethods tlsm_PR_methods;
592250e
 
592250e
 #define PEM_LIBRARY	"nsspem"
592250e
 #define PEM_MODULE	"PEM"
592250e
-/* hash files for use with cacertdir have this file name suffix */
592250e
-#define PEM_CA_HASH_FILE_SUFFIX	".0"
592250e
-#define PEM_CA_HASH_FILE_SUFFIX_LEN 2
592250e
+#define PEM_CA_HASH_FILE_REGEX "^[0-9a-f]{8}\\.[0-9]+$"
592250e
 
592250e
 static SECMODModule *pem_module;
592250e
 
592250e
@@ -1541,6 +1540,7 @@ tlsm_init_ca_certs( tlsm_ctx *ctx, const char *cacertfile, const char *cacertdir
592250e
 		PRDir *dir;
592250e
 		PRDirEntry *entry;
592250e
 		PRStatus fistatus = PR_FAILURE;
592250e
+		regex_t hashfile_re;
592250e
 
592250e
 		memset( &fi, 0, sizeof(fi) );
592250e
 		fistatus = PR_GetFileInfo( cacertdir, &fi );
592250e
@@ -1570,20 +1570,30 @@ tlsm_init_ca_certs( tlsm_ctx *ctx, const char *cacertfile, const char *cacertdir
592250e
 			goto done;
592250e
 		}
592250e
 
592250e
+		if ( regcomp( &hashfile_re, PEM_CA_HASH_FILE_REGEX, REG_NOSUB|REG_EXTENDED ) != 0 ) {
592250e
+			Debug( LDAP_DEBUG_ANY, "TLS: cannot compile regex for CA hash files matching\n", 0, 0, 0 );
592250e
+			goto done;
592250e
+		}
592250e
+
592250e
 		do {
592250e
 			entry = PR_ReadDir( dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN );
592250e
 			if ( ( NULL != entry ) && ( NULL != entry->name ) ) {
592250e
 				char *fullpath = NULL;
592250e
-				char *ptr;
592250e
+				int match;
592250e
 
592250e
-				ptr = PL_strrstr( entry->name, PEM_CA_HASH_FILE_SUFFIX );
592250e
-				if ( ( ptr == NULL ) || ( *(ptr + PEM_CA_HASH_FILE_SUFFIX_LEN) != '\0' ) ) {
592250e
+				match = regexec( &hashfile_re, entry->name, 0, NULL, 0 );
592250e
+				if ( match == REG_NOMATCH ) {
592250e
 					Debug( LDAP_DEBUG_TRACE,
592250e
-						   "TLS: file %s does not end in [%s] - does not appear to be a CA certificate "
592250e
-						   "directory file with a properly hashed file name - skipping.\n",
592250e
-						   entry->name, PEM_CA_HASH_FILE_SUFFIX, 0 );
592250e
+						   "TLS: skipping '%s' - filename does not have expected format "
592250e
+						   "(certificate hash with numeric suffix)\n", entry->name, 0, 0 );
592250e
+					continue;
592250e
+				} else if ( match != 0 ) {
592250e
+					Debug( LDAP_DEBUG_ANY,
592250e
+						   "TLS: cannot execute regex for CA hash file matching (%d).\n",
592250e
+						   match, 0, 0 );
592250e
 					continue;
592250e
 				}
592250e
+
592250e
 				fullpath = PR_smprintf( "%s/%s", cacertdir, entry->name );
592250e
 				if ( !tlsm_add_cert_from_file( ctx, fullpath, isca ) ) {
592250e
 					Debug( LDAP_DEBUG_TRACE,
592250e
@@ -1599,6 +1609,7 @@ tlsm_init_ca_certs( tlsm_ctx *ctx, const char *cacertfile, const char *cacertdir
592250e
 				PR_smprintf_free( fullpath );
592250e
 			}
592250e
 		} while ( NULL != entry );
592250e
+		regfree ( &hashfile_re );
592250e
 		PR_CloseDir( dir );
592250e
 	}
592250e
 done:
592250e
-- 
592250e
1.7.11.4
592250e