[Fedora-directory-commits] ldapserver/ldap/servers/plugins/pwdstorage pwd_init.c, 1.6, 1.7 pwdstorage.h, 1.6, 1.7 sha_pwd.c, 1.4, 1.5 ssha_pwd.c, 1.5, 1.6

Nathan Kinder (nkinder) fedora-directory-commits at redhat.com
Tue Sep 6 21:15:17 UTC 2005


Author: nkinder

Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/pwdstorage
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv23217/ldap/servers/plugins/pwdstorage

Modified Files:
	pwd_init.c pwdstorage.h sha_pwd.c ssha_pwd.c 
Log Message:
167441 - Added SHA2 hashed password storage support.


Index: pwd_init.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/pwdstorage/pwd_init.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- pwd_init.c	14 Jun 2005 15:44:19 -0000	1.6
+++ pwd_init.c	6 Sep 2005 21:15:15 -0000	1.7
@@ -47,6 +47,18 @@
 
 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 @@
 	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 )


Index: pwdstorage.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/pwdstorage/pwdstorage.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- pwdstorage.h	14 Jun 2005 15:44:19 -0000	1.6
+++ pwdstorage.h	6 Sep 2005 21:15:15 -0000	1.7
@@ -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 @@
  * Number of bytes each hash algorithm produces
  */
 #define SHA1_LENGTH     20
+#define SHA256_LENGTH   32
+#define SHA384_LENGTH   48
+#define SHA512_LENGTH   64
  
 /******************************************/
 /*


Index: sha_pwd.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/pwdstorage/sha_pwd.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- sha_pwd.c	19 Apr 2005 22:07:32 -0000	1.4
+++ sha_pwd.c	6 Sep 2005 21:15:15 -0000	1.5
@@ -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 @@
  * 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 @@
         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 );
+}


Index: ssha_pwd.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/pwdstorage/ssha_pwd.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ssha_pwd.c	19 Apr 2005 22:07:32 -0000	1.5
+++ ssha_pwd.c	6 Sep 2005 21:15:15 -0000	1.6
@@ -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 @@
     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 );
+}




More information about the Fedora-directory-commits mailing list