2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 2009-2011 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
11 * A copy of this license is available in the file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
16 * This work was initially developed by Jeff Turner for inclusion
17 * in OpenLDAP Software.
19 * Hash methods for passwords generation added by Cédric Delfosse.
24 #include <ac/string.h>
31 #ifdef SLAPD_SHA2_DEBUG
35 /* pw_string64 function taken from libraries/liblutil/passwd.c */
36 static int pw_string64(
37 const struct berval *sc,
38 const struct berval *hash,
40 const struct berval *salt )
47 /* need to base64 combined string */
48 string.bv_len = hash->bv_len + salt->bv_len;
49 string.bv_val = ber_memalloc( string.bv_len + 1 );
51 if( string.bv_val == NULL ) {
52 return LUTIL_PASSWD_ERR;
55 AC_MEMCPY( string.bv_val, hash->bv_val,
57 AC_MEMCPY( &string.bv_val[hash->bv_len], salt->bv_val,
59 string.bv_val[string.bv_len] = '\0';
65 b64len = LUTIL_BASE64_ENCODE_LEN( string.bv_len ) + 1;
66 b64->bv_len = b64len + sc->bv_len;
67 b64->bv_val = ber_memalloc( b64->bv_len + 1 );
69 if( b64->bv_val == NULL ) {
70 if( salt ) ber_memfree( string.bv_val );
71 return LUTIL_PASSWD_ERR;
74 AC_MEMCPY(b64->bv_val, sc->bv_val, sc->bv_len);
77 (unsigned char *) string.bv_val, string.bv_len,
78 &b64->bv_val[sc->bv_len], b64len );
80 if( salt ) ber_memfree( string.bv_val );
83 return LUTIL_PASSWD_ERR;
86 /* recompute length */
87 b64->bv_len = sc->bv_len + rc;
88 assert( strlen(b64->bv_val) == b64->bv_len );
89 return LUTIL_PASSWD_OK;
92 char * sha256_hex_hash(const char * passwd) {
95 unsigned char hash[SHA256_DIGEST_LENGTH];
96 static char real_hash[LUTIL_BASE64_ENCODE_LEN(SHA256_DIGEST_LENGTH)+1]; // extra char for \0
99 SHA256_Update(&ct, (const uint8_t*)passwd, strlen(passwd));
100 SHA256_Final(hash, &ct);
102 /* base64 encode it */
105 SHA256_DIGEST_LENGTH,
107 LUTIL_BASE64_ENCODE_LEN(SHA256_DIGEST_LENGTH)+1
114 char * sha384_hex_hash(const char * passwd) {
117 unsigned char hash[SHA384_DIGEST_LENGTH];
118 static char real_hash[LUTIL_BASE64_ENCODE_LEN(SHA384_DIGEST_LENGTH)+1]; // extra char for \0
121 SHA384_Update(&ct, (const uint8_t*)passwd, strlen(passwd));
122 SHA384_Final(hash, &ct);
124 /* base64 encode it */
127 SHA384_DIGEST_LENGTH,
129 LUTIL_BASE64_ENCODE_LEN(SHA384_DIGEST_LENGTH)+1
135 char * sha512_hex_hash(const char * passwd) {
138 unsigned char hash[SHA512_DIGEST_LENGTH];
139 static char real_hash[LUTIL_BASE64_ENCODE_LEN(SHA512_DIGEST_LENGTH)+1]; // extra char for \0
142 SHA512_Update(&ct, (const uint8_t*)passwd, strlen(passwd));
143 SHA512_Final(hash, &ct);
145 /* base64 encode it */
148 SHA512_DIGEST_LENGTH,
150 LUTIL_BASE64_ENCODE_LEN(SHA512_DIGEST_LENGTH)+1
156 static int hash_sha256(
157 const struct berval *scheme,
158 const struct berval *passwd,
163 unsigned char hash256[SHA256_DIGEST_LENGTH];
166 SHA256_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len);
167 SHA256_Final(hash256, &ct);
169 struct berval digest;
170 digest.bv_val = (char *) hash256;
171 digest.bv_len = sizeof(hash256);
173 return pw_string64(scheme, &digest, hash, NULL);
176 static int hash_sha384(
177 const struct berval *scheme,
178 const struct berval *passwd,
183 unsigned char hash384[SHA384_DIGEST_LENGTH];
185 #ifdef SLAPD_SHA2_DEBUG
186 fprintf(stderr, "hashing password\n");
189 SHA384_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len);
190 SHA384_Final(hash384, &ct);
192 struct berval digest;
193 digest.bv_val = (char *) hash384;
194 digest.bv_len = sizeof(hash384);
196 return pw_string64(scheme, &digest, hash, NULL);
199 static int hash_sha512(
200 const struct berval *scheme,
201 const struct berval *passwd,
206 unsigned char hash512[SHA512_DIGEST_LENGTH];
209 SHA512_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len);
210 SHA512_Final(hash512, &ct);
212 struct berval digest;
213 digest.bv_val = (char *) hash512;
214 digest.bv_len = sizeof(hash512);
216 return pw_string64(scheme, &digest, hash, NULL);
219 static int chk_sha256(
220 const struct berval *scheme, // Scheme of hashed reference password
221 const struct berval *passwd, // Hashed reference password to check against
222 const struct berval *cred, // user-supplied password to check
225 #ifdef SLAPD_SHA2_DEBUG
226 fprintf(stderr, "Validating password\n");
227 fprintf(stderr, " Password to validate: %s\n", cred->bv_val);
228 fprintf(stderr, " Hashes to: %s\n", sha256_hex_hash(cred->bv_val));
229 fprintf(stderr, " Stored password scheme: %s\n", scheme->bv_val);
230 fprintf(stderr, " Stored password value: %s\n", passwd->bv_val);
231 fprintf(stderr, " -> Passwords %s\n", strcmp(sha256_hex_hash(cred->bv_val), passwd->bv_val) == 0 ? "match" : "do not match");
233 return (strcmp(sha256_hex_hash(cred->bv_val), passwd->bv_val));
236 static int chk_sha384(
237 const struct berval *scheme, // Scheme of hashed reference password
238 const struct berval *passwd, // Hashed reference password to check against
239 const struct berval *cred, // user-supplied password to check
242 #ifdef SLAPD_SHA2_DEBUG
243 fprintf(stderr, "Validating password\n");
244 fprintf(stderr, " Password to validate: %s\n", cred->bv_val);
245 fprintf(stderr, " Hashes to: %s\n", sha384_hex_hash(cred->bv_val));
246 fprintf(stderr, " Stored password scheme: %s\n", scheme->bv_val);
247 fprintf(stderr, " Stored password value: %s\n", passwd->bv_val);
248 fprintf(stderr, " -> Passwords %s\n", strcmp(sha384_hex_hash(cred->bv_val), passwd->bv_val) == 0 ? "match" : "do not match");
250 return (strcmp(sha384_hex_hash(cred->bv_val), passwd->bv_val));
253 static int chk_sha512(
254 const struct berval *scheme, // Scheme of hashed reference password
255 const struct berval *passwd, // Hashed reference password to check against
256 const struct berval *cred, // user-supplied password to check
259 #ifdef SLAPD_SHA2_DEBUG
260 fprintf(stderr, " Password to validate: %s\n", cred->bv_val);
261 fprintf(stderr, " Hashes to: %s\n", sha512_hex_hash(cred->bv_val));
262 fprintf(stderr, " Stored password scheme: %s\n", scheme->bv_val);
263 fprintf(stderr, " Stored password value: %s\n", passwd->bv_val);
264 fprintf(stderr, " -> Passwords %s\n", strcmp(sha512_hex_hash(cred->bv_val), passwd->bv_val) == 0 ? "match" : "do not match");
266 return (strcmp(sha512_hex_hash(cred->bv_val), passwd->bv_val));
269 const struct berval sha256scheme = BER_BVC("{SHA256}");
270 const struct berval sha384scheme = BER_BVC("{SHA384}");
271 const struct berval sha512scheme = BER_BVC("{SHA512}");
273 int init_module(int argc, char *argv[]) {
275 result = lutil_passwd_add( (struct berval *)&sha256scheme, chk_sha256, hash_sha256 );
276 if (result != 0) return result;
277 result = lutil_passwd_add( (struct berval *)&sha384scheme, chk_sha384, hash_sha384 );
278 if (result != 0) return result;
279 result = lutil_passwd_add( (struct berval *)&sha512scheme, chk_sha512, hash_sha512 );