Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Joe Martin
OpenLDAP
Commits
a078dc3d
Commit
a078dc3d
authored
Nov 08, 2013
by
HAMANO Tsukasa
Committed by
Quanah Gibson-Mount
May 29, 2014
Browse files
ITS#7742 New: PBKDF2 module
Signed-off-by:
HAMANO Tsukasa
<
hamano@osstech.co.jp
>
parent
d9616507
Changes
3
Hide whitespace changes
Inline
Side-by-side
contrib/slapd-modules/passwd/pbkdf2/Makefile
0 → 100644
View file @
a078dc3d
# $OpenLDAP$
LDAP_SRC
=
../../../..
LDAP_BUILD
=
../../../..
LDAP_INC
=
-I
$(LDAP_BUILD)
/include
-I
$(LDAP_SRC)
/include
-I
$(LDAP_SRC)
/servers/slapd
LDAP_LIB
=
$(LDAP_BUILD)
/libraries/libldap_r/libldap_r.la
\
$(LDAP_BUILD)
/libraries/liblber/liblber.la
LIBTOOL
=
$(LDAP_BUILD)
/libtool
CC
=
gcc
OPT
=
-g
-O2
-Wall
#DEFS = -DSLAPD_PBKDF2_DEBUG
INCS
=
$(LDAP_INC)
LIBS
=
$(LDAP_LIB)
-lcrypto
PROGRAMS
=
pw-pbkdf2.la
LTVER
=
0:0:0
#prefix=/usr/local
prefix
=
`
grep
-e
"^prefix ="
$(LDAP_BUILD)
/Makefile |
cut
-d
=
-f2
`
exec_prefix
=
$(prefix)
ldap_subdir
=
/openldap
libdir
=
$(exec_prefix)
/lib
libexecdir
=
$(exec_prefix)
/libexec
moduledir
=
$(libexecdir)$(ldap_subdir)
.SUFFIXES
:
.c .o .lo
.c.lo
:
$(LIBTOOL)
--mode
=
compile
$(CC)
$(OPT)
$(DEFS)
$(INCS)
-c
$<
all
:
$(PROGRAMS)
pw-pbkdf2.la
:
pw-pbkdf2.lo
$(LIBTOOL)
--mode
=
link
$(CC)
$(OPT)
-version-info
$(LTVER)
\
-rpath
$(moduledir)
-module
-o
$@
$?
$(LIBS)
clean
:
rm
-rf
*
.o
*
.lo
*
.la .libs
install
:
$(PROGRAMS)
mkdir
-p
$(DESTDIR)$(moduledir)
for
p
in
$(PROGRAMS)
;
do
\
$(LIBTOOL)
--mode
=
install cp
$$
p
$(DESTDIR)$(moduledir)
;
\
done
contrib/slapd-modules/passwd/pbkdf2/README
0 → 100644
View file @
a078dc3d
PBKDF2 for OpenLDAP
=======================
pw-pbkdf2.c provides support for PBKDF2 key derivation functions in
OpenLDAP.
# Requirements
* OpenSSL 1.0.0 or later
# Installations
$ cd <OPENLDAP_BUILD_DIR>/contrib/slapd-modules/passwd/
$ git clone https://github.com/hamano/openldap-pbkdf2.git
$ cd openldap-pbkdf2/
$ make
# make install
# Configuration
In slapd.conf:
moduleload pw-pbkdf2.so
You can also tell OpenLDAP to use the schemes when processing LDAP
Password Modify Extended Operations, thanks to the password-hash
option in slapd.conf. For example:
password-hash {PBKDF2}
# Testing
You can get hash to use slappasswd.
$ slappasswd -o module-load=pw-pbkdf2.la -h {PBKDF2} -s secret
{PBKDF2}60000$Y6ZHtTTbeUgpIbIW0QDmDA$j/aU7jFKUSbH4UobNQDm9OEIwuw
A quick way to test whether it's working is to customize the rootdn and
rootpw in slapd.conf, eg:
rootdn "cn=Manager,dc=example,dc=com"
rootpw {PBKDF2}60000$Y6ZHtTTbeUgpIbIW0QDmDA$j/aU7jFKUSbH4UobNQDm9OEIwuw
Then to test, run something like:
$ ldapsearch -x -b "dc=example,dc=com" -D "cn=Manager,dc=example,dc=com" -w secret
# Debugging
You can specify -DSLAPD_PBKDF2_DEBUG flag for debugging.
# Message Format
{PBKDF2}<Iteration>$<Adapted Base64 Salt>$<Adapted Base64 DK>
# References
* [RFC 2898 Password-Based Cryptography][^1]
[^1]: http://tools.ietf.org/html/rfc2898
* [PKCS #5 PBKDF2 Test Vectors][^2]
[^2]: http://tools.ietf.org/html/draft-josefsson-pbkdf2-test-vectors-06
* [RFC 2307 Using LDAP as a Network Information Service][^3]
[^3]: http://tools.ietf.org/html/rfc2307
* [Python Passlib][^4]
[^4]: http://pythonhosted.org/passlib/
* [Adapted Base64 Encoding][^5]
[^5]: http://pythonhosted.org/passlib/lib/passlib.utils.html#passlib.utils.ab64_encode
# License
This work is part of OpenLDAP Software <http://www.openldap.org/>.
Copyright 2009-2013 The OpenLDAP Foundation.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted only as authorized by the OpenLDAP
Public License.
A copy of this license is available in the file LICENSE in the
top-level directory of the distribution or, alternatively, at
<http://www.OpenLDAP.org/license.html>.
# ACKNOWLEDGEMENT
This work was initially developed by HAMANO Tsukasa <hamano@osstech.co.jp>
contrib/slapd-modules/passwd/pbkdf2/pw-pbkdf2.c
0 → 100644
View file @
a078dc3d
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Copyright 2009-2013 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
/* ACKNOWLEDGEMENT:
* This work was initially developed by HAMANO Tsukasa <hamano@osstech.co.jp>
*/
#define _GNU_SOURCE
#include
"portable.h"
#include
<ac/string.h>
#include
"lber_pvt.h"
#include
"lutil.h"
#include
<openssl/evp.h>
#define PBKDF2_SALT_SIZE 16
#define PBKDF2_DK_SIZE 20
#define PBKDF2_ITERATION 60000
const
struct
berval
pbkdf2scheme
=
BER_BVC
(
"{PBKDF2}"
);
/*
* Converting base64 string to adapted base64 string.
* Adapted base64 encode is identical to general base64 encode except
* that it uses '.' instead of '+', and omits trailing padding '=' and
* whitepsace.
* see http://pythonhosted.org/passlib/lib/passlib.utils.html
* This is destructive function.
*/
static
int
b64_to_ab64
(
char
*
str
)
{
char
*
p
=
str
;
while
(
*
p
++
){
if
(
*
p
==
'+'
){
*
p
=
'.'
;
}
if
(
*
p
==
'='
){
*
p
=
'\0'
;
break
;
}
}
return
0
;
}
/*
* Converting adapted base64 string to base64 string.
* dstsize will require src length + 2, due to output string have
* potential to append "=" or "==".
* return -1 if few output buffer.
*/
static
int
ab64_to_b64
(
char
*
src
,
char
*
dst
,
size_t
dstsize
){
int
i
;
char
*
p
=
src
;
for
(
i
=
0
;
p
[
i
]
&&
p
[
i
]
!=
'$'
;
i
++
){
if
(
i
>=
dstsize
){
dst
[
0
]
=
'\0'
;
return
-
1
;
}
if
(
p
[
i
]
==
'.'
){
dst
[
i
]
=
'+'
;
}
else
{
dst
[
i
]
=
p
[
i
];
}
}
for
(;
i
%
4
;
i
++
){
if
(
i
>=
dstsize
){
dst
[
0
]
=
'\0'
;
return
-
1
;
}
dst
[
i
]
=
'='
;
}
dst
[
i
]
=
'\0'
;
return
0
;
}
static
int
pbkdf2_format
(
const
struct
berval
*
sc
,
int
iteration
,
const
struct
berval
*
salt
,
const
struct
berval
*
dk
,
struct
berval
*
msg
)
{
int
rc
;
char
salt_b64
[
LUTIL_BASE64_ENCODE_LEN
(
PBKDF2_SALT_SIZE
)
+
1
];
char
dk_b64
[
LUTIL_BASE64_ENCODE_LEN
(
PBKDF2_DK_SIZE
)
+
1
];
rc
=
lutil_b64_ntop
((
unsigned
char
*
)
salt
->
bv_val
,
salt
->
bv_len
,
salt_b64
,
sizeof
(
salt_b64
));
if
(
rc
<
0
){
return
LUTIL_PASSWD_ERR
;
}
b64_to_ab64
(
salt_b64
);
rc
=
lutil_b64_ntop
((
unsigned
char
*
)
dk
->
bv_val
,
dk
->
bv_len
,
dk_b64
,
sizeof
(
dk_b64
));
if
(
rc
<
0
){
return
LUTIL_PASSWD_ERR
;
}
b64_to_ab64
(
dk_b64
);
msg
->
bv_len
=
asprintf
(
&
msg
->
bv_val
,
"%s%d$%s$%s"
,
sc
->
bv_val
,
iteration
,
salt_b64
,
dk_b64
);
if
(
msg
->
bv_len
<
0
){
return
LUTIL_PASSWD_ERR
;
}
#ifdef SLAPD_PBKDF2_DEBUG
printf
(
" Output:
\t
%s
\n
"
,
msg
->
bv_val
);
#endif
return
LUTIL_PASSWD_OK
;
}
static
int
pbkdf2_encrypt
(
const
struct
berval
*
scheme
,
const
struct
berval
*
passwd
,
struct
berval
*
msg
,
const
char
**
text
)
{
unsigned
char
salt_value
[
PBKDF2_SALT_SIZE
];
struct
berval
salt
;
unsigned
char
dk_value
[
PBKDF2_DK_SIZE
];
struct
berval
dk
;
int
iteration
=
PBKDF2_ITERATION
;
dk
.
bv_val
=
(
char
*
)
dk_value
;
dk
.
bv_len
=
PBKDF2_DK_SIZE
;
salt
.
bv_val
=
(
char
*
)
salt_value
;
salt
.
bv_len
=
sizeof
(
salt_value
);
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
)){
return
LUTIL_PASSWD_ERR
;
}
#ifdef SLAPD_PBKDF2_DEBUG
printf
(
"DEBUG pbkdf2_encrypt()
\n
"
);
printf
(
" Password:
\t
%s
\n
"
,
passwd
->
bv_val
);
printf
(
" Salt:
\t\t
"
);
int
i
;
for
(
i
=
0
;
i
<
salt
.
bv_len
;
i
++
){
printf
(
"%02x"
,
salt_value
[
i
]);
}
printf
(
"
\n
"
);
printf
(
" Iteration:
\t
%d
\n
"
,
iteration
);
printf
(
" DK:
\t\t
"
);
for
(
i
=
0
;
i
<
PBKDF2_DK_SIZE
;
i
++
){
printf
(
"%02x"
,
dk_value
[
i
]);
}
printf
(
"
\n
"
);
#endif
return
pbkdf2_format
(
scheme
,
iteration
,
&
salt
,
&
dk
,
msg
);
}
static
int
pbkdf2_check
(
const
struct
berval
*
scheme
,
const
struct
berval
*
passwd
,
const
struct
berval
*
cred
,
const
char
**
text
)
{
int
rc
;
int
iteration
;
/* 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
];
#ifdef SLAPD_PBKDF2_DEBUG
printf
(
"DEBUG pbkdf2_check()
\n
"
);
printf
(
" Stored Value:
\t
%s
\n
"
,
passwd
->
bv_val
);
printf
(
" Input Cred:
\t
%s
\n
"
,
cred
->
bv_val
);
#endif
iteration
=
atoi
(
passwd
->
bv_val
);
if
(
iteration
<
1
){
return
LUTIL_PASSWD_ERR
;
}
char
*
ptr
;
ptr
=
strchr
(
passwd
->
bv_val
,
'$'
);
if
(
!
ptr
){
return
LUTIL_PASSWD_ERR
;
}
ptr
++
;
/* skip '$' */
rc
=
ab64_to_b64
(
ptr
,
salt_b64
,
sizeof
(
salt_b64
));
if
(
rc
<
0
){
return
LUTIL_PASSWD_ERR
;
}
ptr
=
strchr
(
ptr
,
'$'
);
if
(
!
ptr
){
return
LUTIL_PASSWD_ERR
;
}
ptr
++
;
/* skip '$' */
rc
=
ab64_to_b64
(
ptr
,
dk_b64
,
sizeof
(
dk_b64
));
if
(
rc
<
0
){
return
LUTIL_PASSWD_ERR
;
}
/* The targetsize require PBKDF2_SALT_SIZE + 1 in lutil_b64_pton. */
rc
=
lutil_b64_pton
(
salt_b64
,
salt_value
,
PBKDF2_SALT_SIZE
+
1
);
if
(
rc
<
0
){
return
LUTIL_PASSWD_ERR
;
}
/* consistency check */
if
(
rc
!=
PBKDF2_SALT_SIZE
){
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
);
if
(
rc
<
0
){
return
LUTIL_PASSWD_ERR
;
}
/* consistency check */
if
(
rc
!=
PBKDF2_DK_SIZE
){
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
)){
return
LUTIL_PASSWD_ERR
;
}
rc
=
memcmp
(
dk_value
,
input_dk_value
,
PBKDF2_DK_SIZE
);
#ifdef SLAPD_PBKDF2_DEBUG
printf
(
" Iteration:
\t
%d
\n
"
,
iteration
);
printf
(
" Base64 Salt:
\t
%s
\n
"
,
salt_b64
);
printf
(
" Base64 DK:
\t
%s
\n
"
,
dk_b64
);
int
i
;
printf
(
" Stored Salt:
\t
"
);
for
(
i
=
0
;
i
<
PBKDF2_SALT_SIZE
;
i
++
){
printf
(
"%02x"
,
salt_value
[
i
]);
}
printf
(
"
\n
"
);
printf
(
" Stored DK:
\t
"
);
for
(
i
=
0
;
i
<
PBKDF2_DK_SIZE
;
i
++
){
printf
(
"%02x"
,
dk_value
[
i
]);
}
printf
(
"
\n
"
);
printf
(
" Input DK:
\t
"
);
for
(
i
=
0
;
i
<
PBKDF2_DK_SIZE
;
i
++
){
printf
(
"%02x"
,
input_dk_value
[
i
]);
}
printf
(
"
\n
"
);
printf
(
" Result:
\t
%d
\n
"
,
rc
);
#endif
return
rc
?
LUTIL_PASSWD_ERR
:
LUTIL_PASSWD_OK
;
}
int
init_module
(
int
argc
,
char
*
argv
[])
{
int
rc
;
rc
=
lutil_passwd_add
((
struct
berval
*
)
&
pbkdf2scheme
,
pbkdf2_check
,
pbkdf2_encrypt
);
if
(
!
rc
)
return
rc
;
/* TODO: add {PBKDF2-SHA256} and {PBKDF2-SHA512} schemes. */
return
rc
;
}
/*
* Local variables:
* indent-tabs-mode: t
* tab-width: 4
* c-basic-offset: 4
* End:
*/
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment