From 709a0f4a97b6ab40fd2a267be4bf80d303d657a4 Mon Sep 17 00:00:00 2001 From: Luca Bruno Date: Wed, 5 Nov 2014 15:32:33 +0100 Subject: [PATCH] ITS#8198 Optionally use libnettle instead of OpenSSL for crypto OpenLDAP can be configured to be either built with OpenSSL or GnuTLS. This commit adds support for building pw-pbkbdf2 module without OpenSSL, by using PBKDF2 crypto primitives provided by libnettle. Closes hamano/openldap-pbkdf2#2 Signed-off-by: Luca Bruno --- .../slapd-modules/passwd/pbkdf2/pw-pbkdf2.c | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/contrib/slapd-modules/passwd/pbkdf2/pw-pbkdf2.c b/contrib/slapd-modules/passwd/pbkdf2/pw-pbkdf2.c index e0f5dfd74c..83559086a7 100644 --- a/contrib/slapd-modules/passwd/pbkdf2/pw-pbkdf2.c +++ b/contrib/slapd-modules/passwd/pbkdf2/pw-pbkdf2.c @@ -22,8 +22,19 @@ #include #include "lber_pvt.h" #include "lutil.h" +#include +#include +#ifdef HAVE_OPENSSL #include +#elif HAVE_GNUTLS +#include +#include +typedef void (*pbkdf2_hmac_update)(void *, unsigned, const uint8_t *); +typedef void (*pbkdf2_hmac_digest)(void *, unsigned, uint8_t *); +#else +#error Unsupported crypto backend. +#endif #define PBKDF2_ITERATION 10000 #define PBKDF2_SALT_SIZE 16 @@ -139,11 +150,22 @@ static int pbkdf2_encrypt( struct berval dk; int iteration = PBKDF2_ITERATION; int rc; +#ifdef HAVE_OPENSSL const EVP_MD *md; +#else + struct hmac_sha1_ctx sha1_ctx; + struct hmac_sha256_ctx sha256_ctx; + struct hmac_sha512_ctx sha512_ctx; + void * current_ctx = NULL; + pbkdf2_hmac_update current_hmac_update = NULL; + pbkdf2_hmac_digest current_hmac_digest = NULL; +#endif salt.bv_val = (char *)salt_value; salt.bv_len = sizeof(salt_value); dk.bv_val = (char *)dk_value; + +#ifdef HAVE_OPENSSL if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ dk.bv_len = PBKDF2_SHA1_DK_SIZE; md = EVP_sha1(); @@ -159,16 +181,52 @@ static int pbkdf2_encrypt( }else{ return LUTIL_PASSWD_ERR; } +#else + if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ + dk.bv_len = PBKDF2_SHA1_DK_SIZE; + current_ctx = &sha1_ctx; + current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update; + current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest; + hmac_sha1_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val); + }else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){ + dk.bv_len = PBKDF2_SHA1_DK_SIZE; + current_ctx = &sha1_ctx; + current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update; + current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest; + hmac_sha1_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val); + }else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){ + dk.bv_len = PBKDF2_SHA256_DK_SIZE; + current_ctx = &sha256_ctx; + current_hmac_update = (pbkdf2_hmac_update) &hmac_sha256_update; + current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha256_digest; + hmac_sha256_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val); + }else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){ + dk.bv_len = PBKDF2_SHA512_DK_SIZE; + current_ctx = &sha512_ctx; + current_hmac_update = (pbkdf2_hmac_update) &hmac_sha512_update; + current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha512_digest; + hmac_sha512_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val); + }else{ + return LUTIL_PASSWD_ERR; + } +#endif if(lutil_entropy((unsigned char *)salt.bv_val, salt.bv_len) < 0){ return LUTIL_PASSWD_ERR; } +#ifdef HAVE_OPENSSL if(!PKCS5_PBKDF2_HMAC(passwd->bv_val, passwd->bv_len, (unsigned char *)salt.bv_val, salt.bv_len, iteration, md, dk.bv_len, dk_value)){ return LUTIL_PASSWD_ERR; } +#else + PBKDF2(current_ctx, current_hmac_update, current_hmac_digest, + dk.bv_len, iteration, + salt.bv_len, (const uint8_t *) salt.bv_val, + dk.bv_len, dk_value); +#endif #ifdef SLAPD_PBKDF2_DEBUG printf("Encrypt for %s\n", scheme->bv_val); @@ -215,7 +273,16 @@ static int pbkdf2_check( char dk_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_MAX_DK_SIZE) + 1]; unsigned char input_dk_value[PBKDF2_MAX_DK_SIZE]; size_t dk_len; +#ifdef HAVE_OPENSSL const EVP_MD *md; +#else + struct hmac_sha1_ctx sha1_ctx; + struct hmac_sha256_ctx sha256_ctx; + struct hmac_sha512_ctx sha512_ctx; + void * current_ctx = NULL; + pbkdf2_hmac_update current_hmac_update = NULL; + pbkdf2_hmac_digest current_hmac_digest = NULL; +#endif #ifdef SLAPD_PBKDF2_DEBUG printf("Checking for %s\n", scheme->bv_val); @@ -223,6 +290,7 @@ static int pbkdf2_check( printf(" Input Cred:\t%s\n", cred->bv_val); #endif +#ifdef HAVE_OPENSSL if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ dk_len = PBKDF2_SHA1_DK_SIZE; md = EVP_sha1(); @@ -238,6 +306,35 @@ static int pbkdf2_check( }else{ return LUTIL_PASSWD_ERR; } +#else + if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ + dk_len = PBKDF2_SHA1_DK_SIZE; + current_ctx = &sha1_ctx; + current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update; + current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest; + hmac_sha1_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); + }else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){ + dk_len = PBKDF2_SHA1_DK_SIZE; + current_ctx = &sha1_ctx; + current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update; + current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest; + hmac_sha1_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); + }else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){ + dk_len = PBKDF2_SHA256_DK_SIZE; + current_ctx = &sha256_ctx; + current_hmac_update = (pbkdf2_hmac_update) &hmac_sha256_update; + current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha256_digest; + hmac_sha256_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); + }else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){ + dk_len = PBKDF2_SHA512_DK_SIZE; + current_ctx = &sha512_ctx; + current_hmac_update = (pbkdf2_hmac_update) &hmac_sha512_update; + current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha512_digest; + hmac_sha512_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); + }else{ + return LUTIL_PASSWD_ERR; + } +#endif iteration = atoi(passwd->bv_val); if(iteration < 1){ @@ -287,11 +384,18 @@ static int pbkdf2_check( return LUTIL_PASSWD_ERR; } +#ifdef HAVE_OPENSSL if(!PKCS5_PBKDF2_HMAC(cred->bv_val, cred->bv_len, salt_value, PBKDF2_SALT_SIZE, iteration, md, dk_len, input_dk_value)){ return LUTIL_PASSWD_ERR; } +#else + PBKDF2(current_ctx, current_hmac_update, current_hmac_digest, + dk_len, iteration, + PBKDF2_SALT_SIZE, salt_value, + dk_len, input_dk_value); +#endif rc = memcmp(dk_value, input_dk_value, dk_len); #ifdef SLAPD_PBKDF2_DEBUG -- 2.39.5