summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Kinder <nkinder@redhat.com>2005-09-06 21:15:15 +0000
committerNathan Kinder <nkinder@redhat.com>2005-09-06 21:15:15 +0000
commitfc5df4e689808710d3394ee65acbc403da24baef (patch)
tree56751630447470b6bba5b171487fee6b35c96594
parent2d816548bb0c0a6abe1adebe5f60c0a56cee21a2 (diff)
downloadds-fc5df4e689808710d3394ee65acbc403da24baef.tar.gz
ds-fc5df4e689808710d3394ee65acbc403da24baef.tar.xz
ds-fc5df4e689808710d3394ee65acbc403da24baef.zip
167441 - Added SHA2 hashed password storage support.
-rw-r--r--ldap/admin/src/create_instance.c60
-rw-r--r--ldap/servers/plugins/pwdstorage/pwd_init.c159
-rw-r--r--ldap/servers/plugins/pwdstorage/pwdstorage.h31
-rw-r--r--ldap/servers/plugins/pwdstorage/sha_pwd.c174
-rw-r--r--ldap/servers/plugins/pwdstorage/ssha_pwd.c157
-rw-r--r--ldap/servers/slapd/plugin.c7
6 files changed, 509 insertions, 79 deletions
diff --git a/ldap/admin/src/create_instance.c b/ldap/admin/src/create_instance.c
index aa0eedc3..11ff03e8 100644
--- a/ldap/admin/src/create_instance.c
+++ b/ldap/admin/src/create_instance.c
@@ -3194,6 +3194,36 @@ char *ds_gen_confs(char *sroot, server_config_s *cf,
fprintf(f, "nsslapd-pluginenabled: on\n");
fprintf(f, "\n");
+ fprintf(f, "dn: cn=SSHA256,cn=Password Storage Schemes,cn=plugins,cn=config\n");
+ fprintf(f, "objectclass: top\n");
+ fprintf(f, "objectclass: nsSlapdPlugin\n");
+ fprintf(f, "cn: SSHA256\n");
+ fprintf(f, "nsslapd-pluginpath: %s/lib/pwdstorage-plugin%s\n", sroot, shared_lib);
+ fprintf(f, "nsslapd-plugininitfunc: ssha256_pwd_storage_scheme_init\n");
+ fprintf(f, "nsslapd-plugintype: pwdstoragescheme\n");
+ fprintf(f, "nsslapd-pluginenabled: on\n");
+ fprintf(f, "\n");
+
+ fprintf(f, "dn: cn=SSHA384,cn=Password Storage Schemes,cn=plugins,cn=config\n");
+ fprintf(f, "objectclass: top\n");
+ fprintf(f, "objectclass: nsSlapdPlugin\n");
+ fprintf(f, "cn: SSHA384\n");
+ fprintf(f, "nsslapd-pluginpath: %s/lib/pwdstorage-plugin%s\n", sroot, shared_lib);
+ fprintf(f, "nsslapd-plugininitfunc: ssha384_pwd_storage_scheme_init\n");
+ fprintf(f, "nsslapd-plugintype: pwdstoragescheme\n");
+ fprintf(f, "nsslapd-pluginenabled: on\n");
+ fprintf(f, "\n");
+
+ fprintf(f, "dn: cn=SSHA512,cn=Password Storage Schemes,cn=plugins,cn=config\n");
+ fprintf(f, "objectclass: top\n");
+ fprintf(f, "objectclass: nsSlapdPlugin\n");
+ fprintf(f, "cn: SSHA512\n");
+ fprintf(f, "nsslapd-pluginpath: %s/lib/pwdstorage-plugin%s\n", sroot, shared_lib);
+ fprintf(f, "nsslapd-plugininitfunc: ssha512_pwd_storage_scheme_init\n");
+ fprintf(f, "nsslapd-plugintype: pwdstoragescheme\n");
+ fprintf(f, "nsslapd-pluginenabled: on\n");
+ fprintf(f, "\n");
+
fprintf(f, "dn: cn=SHA,cn=Password Storage Schemes,cn=plugins,cn=config\n");
fprintf(f, "objectclass: top\n");
fprintf(f, "objectclass: nsSlapdPlugin\n");
@@ -3204,6 +3234,36 @@ char *ds_gen_confs(char *sroot, server_config_s *cf,
fprintf(f, "nsslapd-pluginenabled: on\n");
fprintf(f, "\n");
+ fprintf(f, "dn: cn=SHA256,cn=Password Storage Schemes,cn=plugins,cn=config\n");
+ fprintf(f, "objectclass: top\n");
+ fprintf(f, "objectclass: nsSlapdPlugin\n");
+ fprintf(f, "cn: SHA256\n");
+ fprintf(f, "nsslapd-pluginpath: %s/lib/pwdstorage-plugin%s\n", sroot, shared_lib);
+ fprintf(f, "nsslapd-plugininitfunc: sha256_pwd_storage_scheme_init\n");
+ fprintf(f, "nsslapd-plugintype: pwdstoragescheme\n");
+ fprintf(f, "nsslapd-pluginenabled: on\n");
+ fprintf(f, "\n");
+
+ fprintf(f, "dn: cn=SHA384,cn=Password Storage Schemes,cn=plugins,cn=config\n");
+ fprintf(f, "objectclass: top\n");
+ fprintf(f, "objectclass: nsSlapdPlugin\n");
+ fprintf(f, "cn: SHA384\n");
+ fprintf(f, "nsslapd-pluginpath: %s/lib/pwdstorage-plugin%s\n", sroot, shared_lib);
+ fprintf(f, "nsslapd-plugininitfunc: sha384_pwd_storage_scheme_init\n");
+ fprintf(f, "nsslapd-plugintype: pwdstoragescheme\n");
+ fprintf(f, "nsslapd-pluginenabled: on\n");
+ fprintf(f, "\n");
+
+ fprintf(f, "dn: cn=SHA512,cn=Password Storage Schemes,cn=plugins,cn=config\n");
+ fprintf(f, "objectclass: top\n");
+ fprintf(f, "objectclass: nsSlapdPlugin\n");
+ fprintf(f, "cn: SHA512\n");
+ fprintf(f, "nsslapd-pluginpath: %s/lib/pwdstorage-plugin%s\n", sroot, shared_lib);
+ fprintf(f, "nsslapd-plugininitfunc: sha512_pwd_storage_scheme_init\n");
+ fprintf(f, "nsslapd-plugintype: pwdstoragescheme\n");
+ fprintf(f, "nsslapd-pluginenabled: on\n");
+ fprintf(f, "\n");
+
#if !defined(_WIN32)
fprintf(f, "dn: cn=CRYPT,cn=Password Storage Schemes,cn=plugins,cn=config\n");
fprintf(f, "objectclass: top\n");
diff --git a/ldap/servers/plugins/pwdstorage/pwd_init.c b/ldap/servers/plugins/pwdstorage/pwd_init.c
index fa3f5d8d..e55d3096 100644
--- a/ldap/servers/plugins/pwdstorage/pwd_init.c
+++ b/ldap/servers/plugins/pwdstorage/pwd_init.c
@@ -47,6 +47,18 @@ static Slapi_PluginDesc sha_pdesc = { "sha-password-storage-scheme", PLUGIN_MAGI
static Slapi_PluginDesc ssha_pdesc = { "ssha-password-storage-scheme", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT, "Salted Secure Hashing Algorithm (SSHA)" };
+static Slapi_PluginDesc sha256_pdesc = { "sha256-password-storage-scheme", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT, "Secure Hashing Algorithm (SHA256)" };
+
+static Slapi_PluginDesc ssha256_pdesc = { "ssha256-password-storage-scheme", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT, "Salted Secure Hashing Algorithm (SSHA256)" };
+
+static Slapi_PluginDesc sha384_pdesc = { "sha384-password-storage-scheme", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT, "Secure Hashing Algorithm (SHA384)" };
+
+static Slapi_PluginDesc ssha384_pdesc = { "ssha384-password-storage-scheme", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT, "Salted Secure Hashing Algorithm (SSHA384)" };
+
+static Slapi_PluginDesc sha512_pdesc = { "sha512-password-storage-scheme", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT, "Secure Hashing Algorithm (SHA512)" };
+
+static Slapi_PluginDesc ssha512_pdesc = { "ssha512-password-storage-scheme", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT, "Salted Secure Hashing Algorithm (SSHA512)" };
+
#ifndef _WIN32
static Slapi_PluginDesc crypt_pdesc = { "crypt-password-storage-scheme", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT, "Unix crypt algorithm (CRYPT)" };
#endif
@@ -108,6 +120,153 @@ ssha_pwd_storage_scheme_init( Slapi_PBlock *pb )
return( rc );
}
+int
+sha256_pwd_storage_scheme_init( Slapi_PBlock *pb )
+{
+ int rc;
+ char *name;
+
+ slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "=> sha256_pwd_storage_scheme_init\n" );
+
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
+ (void *) SLAPI_PLUGIN_VERSION_01 );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *)&sha256_pdesc );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN,
+ (void *) sha256_pw_enc);
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN,
+ (void *) sha256_pw_cmp );
+ name = slapi_ch_strdup("SHA256");
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_NAME,
+ name );
+
+ slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "<= sha256_pwd_storage_scheme_init %d\n\n", rc );
+
+ return( rc );
+}
+
+int
+ssha256_pwd_storage_scheme_init( Slapi_PBlock *pb )
+{
+ int rc;
+ char *name;
+
+ slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "=> ssha256_pwd_storage_scheme_init\n" );
+
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
+ (void *) SLAPI_PLUGIN_VERSION_01 );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *)&ssha256_pdesc );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN,
+ (void *) salted_sha256_pw_enc );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN,
+ (void *) sha256_pw_cmp );
+ name = slapi_ch_strdup("SSHA256");
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_NAME,
+ name );
+
+ slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "<= ssha256_pwd_storage_scheme_init %d\n\n", rc );
+ return( rc );
+}
+
+int
+sha384_pwd_storage_scheme_init( Slapi_PBlock *pb )
+{
+ int rc;
+ char *name;
+
+ slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "=> sha384_pwd_storage_scheme_init\n" );
+
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
+ (void *) SLAPI_PLUGIN_VERSION_01 );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *)&sha384_pdesc );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN,
+ (void *) sha384_pw_enc);
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN,
+ (void *) sha384_pw_cmp );
+ name = slapi_ch_strdup("SHA384");
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_NAME,
+ name );
+
+ slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "<= sha384_pwd_storage_scheme_init %d\n\n", rc );
+
+ return( rc );
+}
+
+int
+ssha384_pwd_storage_scheme_init( Slapi_PBlock *pb )
+{
+ int rc;
+ char *name;
+
+ slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "=> ssha384_pwd_storage_scheme_init\n" );
+
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
+ (void *) SLAPI_PLUGIN_VERSION_01 );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *)&ssha384_pdesc );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN,
+ (void *) salted_sha384_pw_enc );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN,
+ (void *) sha384_pw_cmp );
+ name = slapi_ch_strdup("SSHA384");
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_NAME,
+ name );
+
+ slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "<= ssha384_pwd_storage_scheme_init %d\n\n", rc );
+ return( rc );
+}
+
+int
+sha512_pwd_storage_scheme_init( Slapi_PBlock *pb )
+{
+ int rc;
+ char *name;
+
+ slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "=> sha512_pwd_storage_scheme_init\n" );
+
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
+ (void *) SLAPI_PLUGIN_VERSION_01 );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *)&sha512_pdesc );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN,
+ (void *) sha512_pw_enc);
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN,
+ (void *) sha512_pw_cmp );
+ name = slapi_ch_strdup("SHA512");
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_NAME,
+ name );
+
+ slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "<= sha512_pwd_storage_scheme_init %d\n\n", rc );
+
+ return( rc );
+}
+
+int
+ssha512_pwd_storage_scheme_init( Slapi_PBlock *pb )
+{
+ int rc;
+ char *name;
+
+ slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "=> ssha512_pwd_storage_scheme_init\n" );
+
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
+ (void *) SLAPI_PLUGIN_VERSION_01 );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *)&ssha512_pdesc );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN,
+ (void *) salted_sha512_pw_enc );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN,
+ (void *) sha512_pw_cmp );
+ name = slapi_ch_strdup("SSHA512");
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_NAME,
+ name );
+
+ slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "<= ssha512_pwd_storage_scheme_init %d\n\n", rc );
+ return( rc );
+}
+
#ifndef _WIN32
int
crypt_pwd_storage_scheme_init( Slapi_PBlock *pb )
diff --git a/ldap/servers/plugins/pwdstorage/pwdstorage.h b/ldap/servers/plugins/pwdstorage/pwdstorage.h
index 9e0932b3..70fe11ba 100644
--- a/ldap/servers/plugins/pwdstorage/pwdstorage.h
+++ b/ldap/servers/plugins/pwdstorage/pwdstorage.h
@@ -49,10 +49,24 @@
#define PWD_HASH_PREFIX_START '{'
#define PWD_HASH_PREFIX_END '}'
+#define MAX_SHA_HASH_SIZE 64
+
#define SHA1_SCHEME_NAME "SHA"
#define SHA1_NAME_LEN 3
#define SALTED_SHA1_SCHEME_NAME "SSHA"
#define SALTED_SHA1_NAME_LEN 4
+#define SHA256_SCHEME_NAME "SHA256"
+#define SHA256_NAME_LEN 6
+#define SALTED_SHA256_SCHEME_NAME "SSHA256"
+#define SALTED_SHA256_NAME_LEN 7
+#define SHA384_SCHEME_NAME "SHA384"
+#define SHA384_NAME_LEN 6
+#define SALTED_SHA384_SCHEME_NAME "SSHA384"
+#define SALTED_SHA384_NAME_LEN 7
+#define SHA512_SCHEME_NAME "SHA512"
+#define SHA512_NAME_LEN 6
+#define SALTED_SHA512_SCHEME_NAME "SSHA512"
+#define SALTED_SHA512_NAME_LEN 7
#define CRYPT_SCHEME_NAME "crypt"
#define CRYPT_NAME_LEN 5
#define NS_MTA_MD5_SCHEME_NAME "NS-MTA-MD5"
@@ -62,10 +76,22 @@
#define MD5_SCHEME_NAME "MD5"
#define MD5_NAME_LEN 3
-SECStatus sha1_salted_hash(unsigned char *hash_out, char *pwd, struct berval *salt);
+SECStatus sha_salted_hash(unsigned char *hash_out, char *pwd, struct berval *salt, unsigned int secOID);
+int sha_pw_cmp( char *userpwd, char *dbpwd, unsigned int shaLen );
+char * sha_pw_enc( char *pwd, unsigned int shaLen );
+char * salted_sha_pw_enc( char *pwd, unsigned int shaLen );
int sha1_pw_cmp( char *userpwd, char *dbpwd );
char * sha1_pw_enc( char *pwd );
char * salted_sha1_pw_enc( char *pwd );
+int sha256_pw_cmp( char *userpwd, char *dbpwd );
+char * sha256_pw_enc( char *pwd );
+char * salted_sha256_pw_enc( char *pwd );
+int sha384_pw_cmp( char *userpwd, char *dbpwd );
+char * sha384_pw_enc( char *pwd );
+char * salted_sha384_pw_enc( char *pwd );
+int sha512_pw_cmp( char *userpwd, char *dbpwd );
+char * sha512_pw_enc( char *pwd );
+char * salted_sha512_pw_enc( char *pwd );
int clear_pw_cmp( char *userpwd, char *dbpwd );
char *clear_pw_enc( char *pwd );
#ifndef _WIN32
@@ -121,6 +147,9 @@ typedef enum DSStatusEnum {
* Number of bytes each hash algorithm produces
*/
#define SHA1_LENGTH 20
+#define SHA256_LENGTH 32
+#define SHA384_LENGTH 48
+#define SHA512_LENGTH 64
/******************************************/
/*
diff --git a/ldap/servers/plugins/pwdstorage/sha_pwd.c b/ldap/servers/plugins/pwdstorage/sha_pwd.c
index a40f40f4..6a86f161 100644
--- a/ldap/servers/plugins/pwdstorage/sha_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/sha_pwd.c
@@ -50,7 +50,7 @@
#include <sechash.h>
#endif /* NET_SSL */
-#define SHA1_SALT_LENGTH 8 /* number of bytes of data in salt */
+#define SHA_SALT_LENGTH 8 /* number of bytes of data in salt */
#define NOT_FIRST_TIME (time_t)1 /* not the first logon */
static char *hasherrmsg = "pw_cmp: %s userPassword \"%s\" is the wrong length or is not properly encoded BASE64\n";
@@ -62,21 +62,46 @@ static char *plugin_name = "NSPwdStoragePlugin";
* 8 bytes of salt plus the first 10 bytes of the SHA-1 digest.
* It's obsolescent now, but we still handle such stored values.
*/
-
+
int
-sha1_pw_cmp (char *userpwd, char *dbpwd )
+sha_pw_cmp (char *userpwd, char *dbpwd, unsigned int shaLen )
{
/*
- * SHA1 passwords are stored in the database as SHA1_LENGTH bytes of
+ * SHA passwords are stored in the database as shaLen bytes of
* hash, followed by zero or more bytes of salt, all BASE64 encoded.
*/
int result = 1; /* failure */
- unsigned char userhash[SHA1_LENGTH];
- unsigned char quick_dbhash[SHA1_LENGTH + SHA1_SALT_LENGTH + 3];
+ unsigned char userhash[MAX_SHA_HASH_SIZE];
+ unsigned char quick_dbhash[MAX_SHA_HASH_SIZE + SHA_SALT_LENGTH + 3];
unsigned char *dbhash = quick_dbhash;
struct berval salt;
int hash_len; /* must be a signed valued -- see below */
-
+ unsigned int secOID;
+ char *schemeName;
+
+ /* Determine which algorithm we're using */
+ switch (shaLen) {
+ case SHA1_LENGTH:
+ schemeName = SHA1_SCHEME_NAME;
+ secOID = SEC_OID_SHA1;
+ break;
+ case SHA256_LENGTH:
+ schemeName = SHA256_SCHEME_NAME;
+ secOID = SEC_OID_SHA256;
+ break;
+ case SHA384_LENGTH:
+ schemeName = SHA384_SCHEME_NAME;
+ secOID = SEC_OID_SHA384;
+ break;
+ case SHA512_LENGTH:
+ schemeName = SHA512_SCHEME_NAME;
+ secOID = SEC_OID_SHA512;
+ break;
+ default:
+ /* An unknown shaLen was passed in. We shouldn't get here. */
+ goto loser;
+ }
+
/*
* Decode hash stored in database.
*
@@ -90,54 +115,137 @@ sha1_pw_cmp (char *userpwd, char *dbpwd )
if ( dbhash == NULL ) goto loser;
}
hash_len = ldif_base64_decode( dbpwd, dbhash );
- if ( hash_len >= SHA1_LENGTH ) {
- salt.bv_val = (void*)(dbhash + SHA1_LENGTH);
- salt.bv_len = hash_len - SHA1_LENGTH;
+ if ( hash_len >= shaLen ) {
+ salt.bv_val = (void*)(dbhash + shaLen);
+ salt.bv_len = hash_len - shaLen;
} else if ( hash_len == DS40B1_SALTED_SHA_LENGTH ) {
salt.bv_val = (void*)dbhash;
salt.bv_len = 8;
} else { /* unsupported, invalid BASE64 (hash_len < 0), or similar */
- slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, hasherrmsg, SHA1_SCHEME_NAME, dbpwd );
+ slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, hasherrmsg, schemeName, dbpwd );
goto loser;
}
-
- /* SHA1 hash the user's key */
- if ( sha1_salted_hash( userhash, userpwd, &salt ) != SECSuccess ) {
- slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "sha1_pw_cmp: SHA1_Hash() failed\n");
+
+ /* hash the user's key */
+ if ( sha_salted_hash( userhash, userpwd, &salt, secOID ) != SECSuccess ) {
+ slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "sha_pw_cmp: sha_salted_hash() failed\n");
goto loser;
}
-
+
/* the proof is in the comparison... */
result = ( hash_len == DS40B1_SALTED_SHA_LENGTH ) ?
( memcmp( userhash, dbhash + 8, hash_len - 8 )) :
- ( memcmp( userhash, dbhash, SHA1_LENGTH ));
-
+ ( memcmp( userhash, dbhash, shaLen ));
+
loser:
if ( dbhash && dbhash != quick_dbhash ) slapi_ch_free( (void**)&dbhash );
return result;
}
-
-
+
char *
-sha1_pw_enc( char *pwd )
+sha_pw_enc( char *pwd, unsigned int shaLen )
{
- unsigned char hash[ SHA1_LENGTH ];
+ unsigned char hash[MAX_SHA_HASH_SIZE];
char *enc;
-
- /* SHA1 hash the user's key */
- if ( sha1_salted_hash( hash, pwd, NULL ) != SECSuccess ) {
+ char *schemeName;
+ unsigned int schemeNameLen;
+ unsigned int secOID;
+
+ /* Determine which algorithm we're using */
+ switch (shaLen) {
+ case SHA1_LENGTH:
+ schemeName = SHA1_SCHEME_NAME;
+ schemeNameLen = SHA1_NAME_LEN;
+ secOID = SEC_OID_SHA1;
+ break;
+ case SHA256_LENGTH:
+ schemeName = SHA256_SCHEME_NAME;
+ schemeNameLen = SHA256_NAME_LEN;
+ secOID = SEC_OID_SHA256;
+ break;
+ case SHA384_LENGTH:
+ schemeName = SHA384_SCHEME_NAME;
+ schemeNameLen = SHA384_NAME_LEN;
+ secOID = SEC_OID_SHA384;
+ break;
+ case SHA512_LENGTH:
+ schemeName = SHA512_SCHEME_NAME;
+ schemeNameLen = SHA512_NAME_LEN;
+ secOID = SEC_OID_SHA512;
+ break;
+ default:
+ /* An unknown shaLen was passed in. We shouldn't get here. */
+ return( NULL );
+ }
+
+ /* hash the user's key */
+ if ( sha_salted_hash( hash, pwd, NULL, secOID ) != SECSuccess ) {
return( NULL );
}
-
- if (( enc = slapi_ch_malloc( 3 + SHA1_NAME_LEN +
- LDIF_BASE64_LEN( SHA1_LENGTH ))) == NULL ) {
+
+ if (( enc = slapi_ch_malloc( 3 + schemeNameLen +
+ LDIF_BASE64_LEN( shaLen ))) == NULL ) {
return( NULL );
}
-
- sprintf( enc, "%c%s%c", PWD_HASH_PREFIX_START, SHA1_SCHEME_NAME,
+
+ sprintf( enc, "%c%s%c", PWD_HASH_PREFIX_START, schemeName,
PWD_HASH_PREFIX_END );
- (void)ldif_base64_encode( hash, enc + 2 + SHA1_NAME_LEN,
- SHA1_LENGTH, -1 );
-
+ (void)ldif_base64_encode( hash, enc + 2 + schemeNameLen,
+ shaLen, -1 );
+
return( enc );
}
+
+/*
+ * Wrapper password comparison functions
+ */
+int
+sha1_pw_cmp (char *userpwd, char *dbpwd )
+{
+ return sha_pw_cmp( userpwd, dbpwd, SHA1_LENGTH );
+}
+
+int
+sha256_pw_cmp (char *userpwd, char *dbpwd )
+{
+ return sha_pw_cmp( userpwd, dbpwd, SHA256_LENGTH );
+}
+
+int
+sha384_pw_cmp (char *userpwd, char *dbpwd )
+{
+ return sha_pw_cmp( userpwd, dbpwd, SHA384_LENGTH );
+}
+
+int
+sha512_pw_cmp (char *userpwd, char *dbpwd )
+{
+ return sha_pw_cmp( userpwd, dbpwd, SHA512_LENGTH );
+}
+
+/*
+ * Wrapper password encryption functions
+ */
+char *
+sha1_pw_enc( char *pwd )
+{
+ return sha_pw_enc( pwd, SHA1_LENGTH );
+}
+
+char *
+sha256_pw_enc( char *pwd )
+{
+ return sha_pw_enc( pwd, SHA256_LENGTH );
+}
+
+char *
+sha384_pw_enc( char *pwd )
+{
+ return sha_pw_enc( pwd, SHA384_LENGTH );
+}
+
+char *
+sha512_pw_enc( char *pwd )
+{
+ return sha_pw_enc( pwd, SHA512_LENGTH );
+}
diff --git a/ldap/servers/plugins/pwdstorage/ssha_pwd.c b/ldap/servers/plugins/pwdstorage/ssha_pwd.c
index 0384c33f..b23c2adf 100644
--- a/ldap/servers/plugins/pwdstorage/ssha_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/ssha_pwd.c
@@ -53,7 +53,7 @@
#include <pk11pqg.h>
#endif /* NET_SSL */
-#define SHA1_SALT_LENGTH 8 /* number of bytes of data in salt */
+#define SHA_SALT_LENGTH 8 /* number of bytes of data in salt */
static void ssha_rand_array(void *randx, size_t len);
@@ -70,75 +70,146 @@ ssha_rand_array(void *randx, size_t len)
PK11_GenerateRandom((unsigned char *)randx, (int)len);
}
-/*
- * A salted SHA1 hash
- * if salt is null, no salt is used (this is for backward compatibility)
-*/
SECStatus
-sha1_salted_hash(unsigned char *hash_out, char *pwd, struct berval *salt)
+sha_salted_hash(unsigned char *hash_out, char *pwd, struct berval *salt, unsigned int secOID)
{
PK11Context *ctx;
unsigned int outLen;
+ unsigned int shaLen;
SECStatus rc;
+
+ switch (secOID) {
+ case SEC_OID_SHA1:
+ shaLen = SHA1_LENGTH;
+ break;
+ case SEC_OID_SHA256:
+ shaLen = SHA256_LENGTH;
+ break;
+ case SEC_OID_SHA384:
+ shaLen = SHA384_LENGTH;
+ break;
+ case SEC_OID_SHA512:
+ shaLen = SHA512_LENGTH;
+ break;
+ default:
+ /* An unknown secOID was passed in. We shouldn't get here. */
+ rc = SECFailure;
+ return rc;
+ }
if (salt && salt->bv_len) {
- ctx = PK11_CreateDigestContext(SEC_OID_SHA1);
- if (ctx == NULL) {
- rc = SECFailure;
- }
- else {
- PK11_DigestBegin(ctx);
- PK11_DigestOp(ctx, (unsigned char*)pwd, strlen(pwd));
- PK11_DigestOp(ctx, (unsigned char*)(salt->bv_val), salt->bv_len);
- PK11_DigestFinal(ctx, hash_out, &outLen, SHA1_LENGTH);
- PK11_DestroyContext(ctx, 1);
- if (outLen == SHA1_LENGTH)
- rc = SECSuccess;
- else
- rc = SECFailure;
- }
+ ctx = PK11_CreateDigestContext(secOID);
+ if (ctx == NULL) {
+ rc = SECFailure;
+ } else {
+ PK11_DigestBegin(ctx);
+ PK11_DigestOp(ctx, (unsigned char*)pwd, strlen(pwd));
+ PK11_DigestOp(ctx, (unsigned char*)(salt->bv_val), salt->bv_len);
+ PK11_DigestFinal(ctx, hash_out, &outLen, shaLen);
+ PK11_DestroyContext(ctx, 1);
+ if (outLen == shaLen)
+ rc = SECSuccess;
+ else
+ rc = SECFailure;
+ }
}
else {
/*backward compatibility*/
- rc = PK11_HashBuf(SEC_OID_SHA1, hash_out, (unsigned char *)pwd, strlen(pwd));
+ rc = PK11_HashBuf(secOID, hash_out, (unsigned char *)pwd, strlen(pwd));
}
-
+
return rc;
}
char *
-salted_sha1_pw_enc( char *pwd )
+salted_sha_pw_enc( char *pwd, unsigned int shaLen )
{
- unsigned char hash[ SHA1_LENGTH + SHA1_SALT_LENGTH ];
- unsigned char *salt = hash + SHA1_LENGTH;
+ unsigned char hash[ MAX_SHA_HASH_SIZE + SHA_SALT_LENGTH ];
+ unsigned char *salt = hash + shaLen;
struct berval saltval;
char *enc;
-
+ char *schemeName;
+ unsigned int schemeNameLen;
+ unsigned int secOID;
+
+ /* Determine which algorithm we're using */
+ switch (shaLen) {
+ case SHA1_LENGTH:
+ schemeName = SALTED_SHA1_SCHEME_NAME;
+ schemeNameLen = SALTED_SHA1_NAME_LEN;
+ secOID = SEC_OID_SHA1;
+ break;
+ case SHA256_LENGTH:
+ schemeName = SALTED_SHA256_SCHEME_NAME;
+ schemeNameLen = SALTED_SHA256_NAME_LEN;
+ secOID = SEC_OID_SHA256;
+ break;
+ case SHA384_LENGTH:
+ schemeName = SALTED_SHA384_SCHEME_NAME;
+ schemeNameLen = SALTED_SHA384_NAME_LEN;
+ secOID = SEC_OID_SHA384;
+ break;
+ case SHA512_LENGTH:
+ schemeName = SALTED_SHA512_SCHEME_NAME;
+ schemeNameLen = SALTED_SHA512_NAME_LEN;
+ secOID = SEC_OID_SHA512;
+ break;
+ default:
+ /* An unknown shaLen was passed in. We shouldn't get here. */
+ return( NULL );
+ }
+
saltval.bv_val = (void*)salt;
- saltval.bv_len = SHA1_SALT_LENGTH;
-
+ saltval.bv_len = SHA_SALT_LENGTH;
+
/* generate a new random salt */
- /* Note: the uninitialized salt array provides a little extra entropy
- * to the random array generation, but it is not really needed since
- * PK11_GenerateRandom takes care of seeding. In any case, it doesn't
- * hurt. */
- ssha_rand_array( salt, SHA1_SALT_LENGTH );
-
- /* SHA1 hash the user's key */
- if ( sha1_salted_hash( hash, pwd, &saltval ) != SECSuccess ) {
+ /* Note: the uninitialized salt array provides a little extra entropy
+ * to the random array generation, but it is not really needed since
+ * PK11_GenerateRandom takes care of seeding. In any case, it doesn't
+ * hurt. */
+ ssha_rand_array( salt, SHA_SALT_LENGTH );
+
+ /* hash the user's key */
+ if ( sha_salted_hash( hash, pwd, &saltval, secOID ) != SECSuccess ) {
return( NULL );
}
-
- if (( enc = slapi_ch_malloc( 3 + SALTED_SHA1_NAME_LEN +
+
+ if (( enc = slapi_ch_malloc( 3 + schemeNameLen +
LDIF_BASE64_LEN(sizeof(hash)))) == NULL ) {
return( NULL );
}
-
- sprintf( enc, "%c%s%c", PWD_HASH_PREFIX_START, SALTED_SHA1_SCHEME_NAME,
+
+ sprintf( enc, "%c%s%c", PWD_HASH_PREFIX_START, schemeName,
PWD_HASH_PREFIX_END );
- (void)ldif_base64_encode( hash, enc + 2 + SALTED_SHA1_NAME_LEN,
+ (void)ldif_base64_encode( hash, enc + 2 + schemeNameLen,
sizeof(hash), -1 );
-
+
return( enc );
}
+/*
+ * Wrapper functions for password encoding
+ */
+char *
+salted_sha1_pw_enc( char *pwd )
+{
+ return salted_sha_pw_enc( pwd, SHA1_LENGTH );
+}
+
+char *
+salted_sha256_pw_enc( char *pwd )
+{
+ return salted_sha_pw_enc( pwd, SHA256_LENGTH );
+}
+
+char *
+salted_sha384_pw_enc( char *pwd )
+{
+ return salted_sha_pw_enc( pwd, SHA384_LENGTH );
+}
+
+char *
+salted_sha512_pw_enc( char *pwd )
+{
+ return salted_sha_pw_enc( pwd, SHA512_LENGTH );
+}
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index cd28d188..a1b9ad7b 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -463,8 +463,11 @@ plugin_get_pwd_storage_scheme(char *name, int len, int index)
struct slapdplugin *p;
for ( p = global_plugin_list[index]; p != NULL; p = p->plg_next ) {
- if (strncasecmp(p->plg_pwdstorageschemename, name, len) == 0)
- return( p );
+ if (strlen(p->plg_pwdstorageschemename) == len) {
+ if (strncasecmp(p->plg_pwdstorageschemename, name, len) == 0) {
+ return( p );
+ }
+ }
}
return( NULL );
}