#include <ac/string.h>
#include "lber_pvt.h"
#include "lutil.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_OPENSSL
#include <openssl/evp.h>
+#elif HAVE_GNUTLS
+#include <nettle/pbkdf2.h>
+#include <nettle/hmac.h>
+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
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();
}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);
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);
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();
}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){
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