]> git.sur5r.net Git - openldap/commitdiff
ITS#7977 Add PBKDF2 -SHA256 and -SHA512
authorHAMANO Tsukasa <hamano@osstech.co.jp>
Wed, 5 Nov 2014 09:26:35 +0000 (09:26 +0000)
committerHoward Chu <hyc@openldap.org>
Wed, 5 Nov 2014 09:29:31 +0000 (09:29 +0000)
contrib/slapd-modules/passwd/pbkdf2/README
contrib/slapd-modules/passwd/pbkdf2/pw-pbkdf2.c

index 348580be0fffb489f477abcc7188609783f3737d..b1cced1dc8fd4e23e960afadbc6e0dd51d94901d 100644 (file)
@@ -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
 
index 6070013a580bd2214e6b45e48b367ca46ef0bef3..7a962c1829db7a3e3d60445feab0e4fdd65456c5 100644 (file)
 
 #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;
+       rc = lutil_passwd_add((struct berval *)&pbkdf2_sha1_scheme,
                                                  pbkdf2_check, pbkdf2_encrypt);
-       if(!rc) return rc;
+       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;
 }