From fc5df4e689808710d3394ee65acbc403da24baef Mon Sep 17 00:00:00 2001 From: Nathan Kinder Date: Tue, 6 Sep 2005 21:15:15 +0000 Subject: 167441 - Added SHA2 hashed password storage support. --- ldap/admin/src/create_instance.c | 60 +++++++++ ldap/servers/plugins/pwdstorage/pwd_init.c | 159 ++++++++++++++++++++++++ ldap/servers/plugins/pwdstorage/pwdstorage.h | 31 ++++- ldap/servers/plugins/pwdstorage/sha_pwd.c | 174 ++++++++++++++++++++++----- ldap/servers/plugins/pwdstorage/ssha_pwd.c | 157 +++++++++++++++++------- ldap/servers/slapd/plugin.c | 7 +- 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 #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 #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 ); } -- cgit