From 61129f8d7a2eae4229a32b2a8ca0ce1a31e80ea9 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 3 Mar 2010 23:56:30 +0000 Subject: [PATCH] ITS#6433 add mechs for generating SHA2 hashes --- contrib/slapd-modules/passwd/sha2/README | 13 +- .../slapd-modules/passwd/sha2/slapd-sha2.c | 128 +++++++++++++++++- 2 files changed, 137 insertions(+), 4 deletions(-) diff --git a/contrib/slapd-modules/passwd/sha2/README b/contrib/slapd-modules/passwd/sha2/README index b1bf5ed9b3..33fc773c72 100644 --- a/contrib/slapd-modules/passwd/sha2/README +++ b/contrib/slapd-modules/passwd/sha2/README @@ -37,7 +37,18 @@ moduleload ...path/to/slapd-sha2.so 5) Restart slapd. -The {SHA512} scheme should now be recognised. + +Configuring +----------- + +The {SHA256}, {SHA384} and {SHA512} password schemes should now be recognised. + +You can also tell OpenLDAP to use one of these new schemes when processing LDAP +Password Modify Extended Operations, thanks to the password-hash option in +slapd.conf. For example: + +password-hash {SHA256} + Testing ------- diff --git a/contrib/slapd-modules/passwd/sha2/slapd-sha2.c b/contrib/slapd-modules/passwd/sha2/slapd-sha2.c index 962aa39657..20895484c2 100644 --- a/contrib/slapd-modules/passwd/sha2/slapd-sha2.c +++ b/contrib/slapd-modules/passwd/sha2/slapd-sha2.c @@ -15,6 +15,8 @@ /* ACKNOWLEDGEMENT: * This work was initially developed by Jeff Turner for inclusion * in OpenLDAP Software. + * + * Hash methods for passwords generation added by Cédric Delfosse. */ #include @@ -30,6 +32,63 @@ #include #endif +/* pw_string64 function taken from libraries/liblutil/passwd.c */ +static int pw_string64( + const struct berval *sc, + const struct berval *hash, + struct berval *b64, + const struct berval *salt ) +{ + int rc; + struct berval string; + size_t b64len; + + if( salt ) { + /* need to base64 combined string */ + string.bv_len = hash->bv_len + salt->bv_len; + string.bv_val = ber_memalloc( string.bv_len + 1 ); + + if( string.bv_val == NULL ) { + return LUTIL_PASSWD_ERR; + } + + AC_MEMCPY( string.bv_val, hash->bv_val, + hash->bv_len ); + AC_MEMCPY( &string.bv_val[hash->bv_len], salt->bv_val, + salt->bv_len ); + string.bv_val[string.bv_len] = '\0'; + + } else { + string = *hash; + } + + b64len = LUTIL_BASE64_ENCODE_LEN( string.bv_len ) + 1; + b64->bv_len = b64len + sc->bv_len; + b64->bv_val = ber_memalloc( b64->bv_len + 1 ); + + if( b64->bv_val == NULL ) { + if( salt ) ber_memfree( string.bv_val ); + return LUTIL_PASSWD_ERR; + } + + AC_MEMCPY(b64->bv_val, sc->bv_val, sc->bv_len); + + rc = lutil_b64_ntop( + (unsigned char *) string.bv_val, string.bv_len, + &b64->bv_val[sc->bv_len], b64len ); + + if( salt ) ber_memfree( string.bv_val ); + + if( rc < 0 ) { + return LUTIL_PASSWD_ERR; + } + + /* recompute length */ + b64->bv_len = sc->bv_len + rc; + assert( strlen(b64->bv_val) == b64->bv_len ); + return LUTIL_PASSWD_OK; +} + char * sha256_hex_hash(const char * passwd) { SHA256_CTX ct; @@ -94,6 +153,69 @@ char * sha512_hex_hash(const char * passwd) { return real_hash; } +static int hash_sha256( + const struct berval *scheme, + const struct berval *passwd, + struct berval *hash, + const char **text ) +{ + SHA256_CTX ct; + unsigned char hash256[SHA256_DIGEST_LENGTH]; + + SHA256_Init(&ct); + SHA256_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); + SHA256_Final(hash256, &ct); + + struct berval digest; + digest.bv_val = (char *) hash256; + digest.bv_len = sizeof(hash256); + + return pw_string64(scheme, &digest, hash, NULL); +} + +static int hash_sha384( + const struct berval *scheme, + const struct berval *passwd, + struct berval *hash, + const char **text ) +{ + SHA384_CTX ct; + unsigned char hash384[SHA384_DIGEST_LENGTH]; + +#ifdef SLAPD_SHA2_DEBUG + fprintf(stderr, "hashing password\n"); +#endif + SHA384_Init(&ct); + SHA384_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); + SHA384_Final(hash384, &ct); + + struct berval digest; + digest.bv_val = (char *) hash384; + digest.bv_len = sizeof(hash384); + + return pw_string64(scheme, &digest, hash, NULL); +} + +static int hash_sha512( + const struct berval *scheme, + const struct berval *passwd, + struct berval *hash, + const char **text ) +{ + SHA512_CTX ct; + unsigned char hash512[SHA512_DIGEST_LENGTH]; + + SHA512_Init(&ct); + SHA512_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); + SHA512_Final(hash512, &ct); + + struct berval digest; + digest.bv_val = (char *) hash512; + digest.bv_len = sizeof(hash512); + + return pw_string64(scheme, &digest, hash, NULL); +} + static int chk_sha256( const struct berval *scheme, // Scheme of hashed reference password const struct berval *passwd, // Hashed reference password to check against @@ -150,10 +272,10 @@ const struct berval sha512scheme = BER_BVC("{SHA512}"); int init_module(int argc, char *argv[]) { int result = 0; - result = lutil_passwd_add( (struct berval *)&sha256scheme, chk_sha256, NULL ); + result = lutil_passwd_add( (struct berval *)&sha256scheme, chk_sha256, hash_sha256 ); if (result != 0) return result; - result = lutil_passwd_add( (struct berval *)&sha384scheme, chk_sha384, NULL ); + result = lutil_passwd_add( (struct berval *)&sha384scheme, chk_sha384, hash_sha384 ); if (result != 0) return result; - result = lutil_passwd_add( (struct berval *)&sha512scheme, chk_sha512, NULL ); + result = lutil_passwd_add( (struct berval *)&sha512scheme, chk_sha512, hash_sha512 ); return result; } -- 2.39.5