ITS#7374 - MozNSS: better file name matching for hashed CA certificate directory

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).
This commit is contained in:
Jan Vcelak 2012-08-29 16:23:52 +02:00 committed by Quanah Gibson-Mount
parent acc5b88661
commit 19fd969d21

View 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: