mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-17 20:34:08 -05:00
ITS#7977 Add PBKDF2 -SHA256 and -SHA512
This commit is contained in:
parent
b0225e8e60
commit
2a43a7d16f
2 changed files with 99 additions and 36 deletions
|
|
@ -1,8 +1,14 @@
|
|||
PBKDF2 for OpenLDAP
|
||||
=======================
|
||||
|
||||
pw-pbkdf2.c provides support for PBKDF2 key derivation functions in
|
||||
OpenLDAP.
|
||||
pw-pbkdf2.c provides PBKDF2 key derivation functions in OpenLDAP.
|
||||
|
||||
Schemes:
|
||||
|
||||
* {PBKDF2} - alias to {PBKDF2-SHA1}
|
||||
* {PBKDF2-SHA1}
|
||||
* {PBKDF2-SHA256}
|
||||
* {PBKDF2-SHA512}
|
||||
|
||||
# Requirements
|
||||
|
||||
|
|
@ -10,13 +16,15 @@ OpenLDAP.
|
|||
|
||||
# Installations
|
||||
|
||||
First, You need to configure and build OpenLDAP.
|
||||
|
||||
$ cd <OPENLDAP_BUILD_DIR>/contrib/slapd-modules/passwd/
|
||||
$ git clone https://github.com/hamano/openldap-pbkdf2.git
|
||||
$ cd openldap-pbkdf2/
|
||||
$ make
|
||||
# make install
|
||||
|
||||
# Configuration
|
||||
# Configration
|
||||
|
||||
In slapd.conf:
|
||||
|
||||
|
|
@ -27,6 +35,10 @@ Password Modify Extended Operations, thanks to the password-hash
|
|||
option in slapd.conf. For example:
|
||||
|
||||
password-hash {PBKDF2}
|
||||
or
|
||||
password-hash {PBKDF2-SHA256}
|
||||
or
|
||||
password-hash {PBKDF2-SHA512}
|
||||
|
||||
# Testing
|
||||
|
||||
|
|
|
|||
|
|
@ -25,11 +25,17 @@
|
|||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#define PBKDF2_ITERATION 10000
|
||||
#define PBKDF2_SALT_SIZE 16
|
||||
#define PBKDF2_DK_SIZE 20
|
||||
#define PBKDF2_ITERATION 60000
|
||||
#define PBKDF2_SHA1_DK_SIZE 20
|
||||
#define PBKDF2_SHA256_DK_SIZE 32
|
||||
#define PBKDF2_SHA512_DK_SIZE 64
|
||||
#define PBKDF2_MAX_DK_SIZE 64
|
||||
|
||||
const struct berval pbkdf2scheme = BER_BVC("{PBKDF2}");
|
||||
const struct berval pbkdf2_scheme = BER_BVC("{PBKDF2}");
|
||||
const struct berval pbkdf2_sha1_scheme = BER_BVC("{PBKDF2-SHA1}");
|
||||
const struct berval pbkdf2_sha256_scheme = BER_BVC("{PBKDF2-SHA256}");
|
||||
const struct berval pbkdf2_sha512_scheme = BER_BVC("{PBKDF2-SHA512}");
|
||||
|
||||
/*
|
||||
* Converting base64 string to adapted base64 string.
|
||||
|
|
@ -95,7 +101,7 @@ static int pbkdf2_format(
|
|||
|
||||
int rc;
|
||||
char salt_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_SALT_SIZE) + 1];
|
||||
char dk_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_DK_SIZE) + 1];
|
||||
char dk_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_MAX_DK_SIZE) + 1];
|
||||
|
||||
rc = lutil_b64_ntop((unsigned char *)salt->bv_val, salt->bv_len,
|
||||
salt_b64, sizeof(salt_b64));
|
||||
|
|
@ -116,9 +122,6 @@ static int pbkdf2_format(
|
|||
return LUTIL_PASSWD_ERR;
|
||||
}
|
||||
|
||||
#ifdef SLAPD_PBKDF2_DEBUG
|
||||
printf(" Output:\t%s\n", msg->bv_val);
|
||||
#endif
|
||||
return LUTIL_PASSWD_OK;
|
||||
}
|
||||
|
||||
|
|
@ -130,27 +133,43 @@ static int pbkdf2_encrypt(
|
|||
{
|
||||
unsigned char salt_value[PBKDF2_SALT_SIZE];
|
||||
struct berval salt;
|
||||
unsigned char dk_value[PBKDF2_DK_SIZE];
|
||||
unsigned char dk_value[PBKDF2_MAX_DK_SIZE];
|
||||
struct berval dk;
|
||||
int iteration = PBKDF2_ITERATION;
|
||||
int rc;
|
||||
const EVP_MD *md;
|
||||
|
||||
dk.bv_val = (char *)dk_value;
|
||||
dk.bv_len = PBKDF2_DK_SIZE;
|
||||
salt.bv_val = (char *)salt_value;
|
||||
salt.bv_len = sizeof(salt_value);
|
||||
dk.bv_val = (char *)dk_value;
|
||||
if(!ber_bvcmp(scheme, &pbkdf2_scheme)){
|
||||
dk.bv_len = PBKDF2_SHA1_DK_SIZE;
|
||||
md = EVP_sha1();
|
||||
}else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){
|
||||
dk.bv_len = PBKDF2_SHA1_DK_SIZE;
|
||||
md = EVP_sha1();
|
||||
}else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){
|
||||
dk.bv_len = PBKDF2_SHA256_DK_SIZE;
|
||||
md = EVP_sha256();
|
||||
}else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){
|
||||
dk.bv_len = PBKDF2_SHA512_DK_SIZE;
|
||||
md = EVP_sha512();
|
||||
}else{
|
||||
return LUTIL_PASSWD_ERR;
|
||||
}
|
||||
|
||||
if(lutil_entropy((unsigned char *)salt.bv_val, salt.bv_len) < 0){
|
||||
return LUTIL_PASSWD_ERR;
|
||||
}
|
||||
|
||||
if(!PKCS5_PBKDF2_HMAC_SHA1(passwd->bv_val, passwd->bv_len,
|
||||
(unsigned char *)salt.bv_val, salt.bv_len,
|
||||
iteration, PBKDF2_DK_SIZE, dk_value)){
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef SLAPD_PBKDF2_DEBUG
|
||||
printf("DEBUG pbkdf2_encrypt()\n");
|
||||
printf("Encrypt for %s\n", scheme->bv_val);
|
||||
printf(" Password:\t%s\n", passwd->bv_val);
|
||||
|
||||
printf(" Salt:\t\t");
|
||||
|
|
@ -162,13 +181,19 @@ static int pbkdf2_encrypt(
|
|||
printf(" Iteration:\t%d\n", iteration);
|
||||
|
||||
printf(" DK:\t\t");
|
||||
for(i=0; i<PBKDF2_DK_SIZE; i++){
|
||||
for(i=0; i<dk.bv_len; i++){
|
||||
printf("%02x", dk_value[i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
return pbkdf2_format(scheme, iteration, &salt, &dk, msg);
|
||||
rc = pbkdf2_format(scheme, iteration, &salt, &dk, msg);
|
||||
|
||||
#ifdef SLAPD_PBKDF2_DEBUG
|
||||
printf(" Output:\t%s\n", msg->bv_val);
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int pbkdf2_check(
|
||||
|
|
@ -183,17 +208,35 @@ static int pbkdf2_check(
|
|||
/* salt_value require PBKDF2_SALT_SIZE + 1 in lutil_b64_pton. */
|
||||
unsigned char salt_value[PBKDF2_SALT_SIZE + 1];
|
||||
char salt_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_SALT_SIZE) + 1];
|
||||
/* dk_value require PBKDF2_DK_SIZE + 1 in lutil_b64_pton. */
|
||||
unsigned char dk_value[PBKDF2_DK_SIZE + 1];
|
||||
char dk_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_DK_SIZE) + 1];
|
||||
unsigned char input_dk_value[PBKDF2_DK_SIZE];
|
||||
/* dk_value require PBKDF2_MAX_DK_SIZE + 1 in lutil_b64_pton. */
|
||||
unsigned char dk_value[PBKDF2_MAX_DK_SIZE + 1];
|
||||
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;
|
||||
const EVP_MD *md;
|
||||
|
||||
#ifdef SLAPD_PBKDF2_DEBUG
|
||||
printf("DEBUG pbkdf2_check()\n");
|
||||
printf("Checking for %s\n", scheme->bv_val);
|
||||
printf(" Stored Value:\t%s\n", passwd->bv_val);
|
||||
printf(" Input Cred:\t%s\n", cred->bv_val);
|
||||
#endif
|
||||
|
||||
if(!ber_bvcmp(scheme, &pbkdf2_scheme)){
|
||||
dk_len = PBKDF2_SHA1_DK_SIZE;
|
||||
md = EVP_sha1();
|
||||
}else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){
|
||||
dk_len = PBKDF2_SHA1_DK_SIZE;
|
||||
md = EVP_sha1();
|
||||
}else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){
|
||||
dk_len = PBKDF2_SHA256_DK_SIZE;
|
||||
md = EVP_sha256();
|
||||
}else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){
|
||||
dk_len = PBKDF2_SHA512_DK_SIZE;
|
||||
md = EVP_sha512();
|
||||
}else{
|
||||
return LUTIL_PASSWD_ERR;
|
||||
}
|
||||
|
||||
iteration = atoi(passwd->bv_val);
|
||||
if(iteration < 1){
|
||||
return LUTIL_PASSWD_ERR;
|
||||
|
|
@ -231,24 +274,24 @@ static int pbkdf2_check(
|
|||
return LUTIL_PASSWD_ERR;
|
||||
}
|
||||
|
||||
/* The targetsize require PBKDF2_DK_SIZE + 1 in lutil_b64_pton. */
|
||||
rc = lutil_b64_pton(dk_b64, dk_value, PBKDF2_DK_SIZE + 1);
|
||||
/* The targetsize require PBKDF2_MAX_DK_SIZE + 1 in lutil_b64_pton. */
|
||||
rc = lutil_b64_pton(dk_b64, dk_value, sizeof(dk_value));
|
||||
if(rc < 0){
|
||||
return LUTIL_PASSWD_ERR;
|
||||
}
|
||||
|
||||
/* consistency check */
|
||||
if(rc != PBKDF2_DK_SIZE){
|
||||
if(rc != dk_len){
|
||||
return LUTIL_PASSWD_ERR;
|
||||
}
|
||||
|
||||
if(!PKCS5_PBKDF2_HMAC_SHA1(cred->bv_val, cred->bv_len,
|
||||
salt_value, PBKDF2_SALT_SIZE,
|
||||
iteration, PBKDF2_DK_SIZE, input_dk_value)){
|
||||
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;
|
||||
}
|
||||
|
||||
rc = memcmp(dk_value, input_dk_value, PBKDF2_DK_SIZE);
|
||||
rc = memcmp(dk_value, input_dk_value, dk_len);
|
||||
#ifdef SLAPD_PBKDF2_DEBUG
|
||||
printf(" Iteration:\t%d\n", iteration);
|
||||
printf(" Base64 Salt:\t%s\n", salt_b64);
|
||||
|
|
@ -261,13 +304,13 @@ static int pbkdf2_check(
|
|||
printf("\n");
|
||||
|
||||
printf(" Stored DK:\t");
|
||||
for(i=0; i<PBKDF2_DK_SIZE; i++){
|
||||
for(i=0; i<dk_len; i++){
|
||||
printf("%02x", dk_value[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf(" Input DK:\t");
|
||||
for(i=0; i<PBKDF2_DK_SIZE; i++){
|
||||
for(i=0; i<dk_len; i++){
|
||||
printf("%02x", input_dk_value[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
|
@ -278,11 +321,19 @@ static int pbkdf2_check(
|
|||
|
||||
int init_module(int argc, char *argv[]) {
|
||||
int rc;
|
||||
rc = lutil_passwd_add((struct berval *)&pbkdf2scheme,
|
||||
rc = lutil_passwd_add((struct berval *)&pbkdf2_scheme,
|
||||
pbkdf2_check, pbkdf2_encrypt);
|
||||
if(!rc) return rc;
|
||||
if(rc) return rc;
|
||||
rc = lutil_passwd_add((struct berval *)&pbkdf2_sha1_scheme,
|
||||
pbkdf2_check, pbkdf2_encrypt);
|
||||
if(rc) return rc;
|
||||
|
||||
/* TODO: add {PBKDF2-SHA256} and {PBKDF2-SHA512} schemes. */
|
||||
rc = lutil_passwd_add((struct berval *)&pbkdf2_sha256_scheme,
|
||||
pbkdf2_check, pbkdf2_encrypt);
|
||||
if(rc) return rc;
|
||||
|
||||
rc = lutil_passwd_add((struct berval *)&pbkdf2_sha512_scheme,
|
||||
pbkdf2_check, pbkdf2_encrypt);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue