]> git.sur5r.net Git - openldap/blob - contrib/slapd-modules/passwd/sha2/slapd-sha2.c
9b91ec01c807d7e5d3a8d7142315f02302e609f6
[openldap] / contrib / slapd-modules / passwd / sha2 / slapd-sha2.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 2009-2017 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted only as authorized by the OpenLDAP
9  * Public License.
10  *
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>.
14  */
15 /* ACKNOWLEDGEMENT:
16  * This work was initially developed by Jeff Turner for inclusion
17  * in OpenLDAP Software.
18  *
19  * Hash methods for passwords generation added by Cédric Delfosse.
20  *
21  * SSHA256 / SSHA384 / SSHA512 support added, and chk_sha*() replaced
22  * with libraries/liblutil/passwd.c:chk_sha1() implementation to
23  * fix a race by SATOH Fumiyasu @ OSS Technology, Inc.
24  */
25
26 #include "portable.h"
27
28 #include <ac/string.h>
29
30 #include "lber_pvt.h"
31 #include "lutil.h"
32 #include "sha2.h"
33
34 #ifdef SLAPD_SHA2_DEBUG
35 #include <stdio.h>
36 #endif
37
38 #define SHA2_SALT_SIZE 8
39
40 static int hash_ssha256(
41         const struct berval *scheme,
42         const struct berval *passwd,
43         struct berval *hash,
44         const char **text )
45 {
46         SHA256_CTX ct;
47         unsigned char hash256[SHA256_DIGEST_LENGTH];
48         char          saltdata[SHA2_SALT_SIZE];
49         struct berval digest;
50         struct berval salt;
51
52         digest.bv_val = (char *) hash256;
53         digest.bv_len = sizeof(hash256);
54         salt.bv_val = saltdata;
55         salt.bv_len = sizeof(saltdata);
56
57         if (lutil_entropy((unsigned char *)salt.bv_val, salt.bv_len) < 0) {
58                 return LUTIL_PASSWD_ERR;
59         }
60
61         SHA256_Init(&ct);
62         SHA256_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len);
63         SHA256_Update(&ct, (const uint8_t*)salt.bv_val, salt.bv_len);
64         SHA256_Final(hash256, &ct);
65
66         return lutil_passwd_string64(scheme, &digest, hash, &salt);
67 }
68
69 static int hash_sha256(
70         const struct berval *scheme,
71         const struct berval *passwd,
72         struct berval *hash,
73         const char **text )
74 {
75         SHA256_CTX ct;
76         unsigned char hash256[SHA256_DIGEST_LENGTH];
77         struct berval digest;
78         digest.bv_val = (char *) hash256;
79         digest.bv_len = sizeof(hash256);
80
81         SHA256_Init(&ct);
82         SHA256_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len);
83         SHA256_Final(hash256, &ct);
84
85         return lutil_passwd_string64(scheme, &digest, hash, NULL);
86 }
87
88 static int hash_ssha384(
89         const struct berval *scheme,
90         const struct berval *passwd,
91         struct berval *hash,
92         const char **text )
93 {
94         SHA384_CTX ct;
95         unsigned char hash384[SHA384_DIGEST_LENGTH];
96         char          saltdata[SHA2_SALT_SIZE];
97         struct berval digest;
98         struct berval salt;
99
100         digest.bv_val = (char *) hash384;
101         digest.bv_len = sizeof(hash384);
102         salt.bv_val = saltdata;
103         salt.bv_len = sizeof(saltdata);
104
105         if (lutil_entropy((unsigned char *)salt.bv_val, salt.bv_len) < 0) {
106                 return LUTIL_PASSWD_ERR;
107         }
108
109         SHA384_Init(&ct);
110         SHA384_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len);
111         SHA384_Update(&ct, (const uint8_t*)salt.bv_val, salt.bv_len);
112         SHA384_Final(hash384, &ct);
113
114         return lutil_passwd_string64(scheme, &digest, hash, &salt);
115 }
116
117 static int hash_sha384(
118         const struct berval *scheme,
119         const struct berval *passwd,
120         struct berval *hash,
121         const char **text )
122 {
123         SHA384_CTX ct;
124         unsigned char hash384[SHA384_DIGEST_LENGTH];
125         struct berval digest;
126         digest.bv_val = (char *) hash384;
127         digest.bv_len = sizeof(hash384);
128
129         SHA384_Init(&ct);
130         SHA384_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len);
131         SHA384_Final(hash384, &ct);
132
133         return lutil_passwd_string64(scheme, &digest, hash, NULL);
134 }
135
136 static int hash_ssha512(
137         const struct berval *scheme,
138         const struct berval *passwd,
139         struct berval *hash,
140         const char **text )
141 {
142         SHA512_CTX ct;
143         unsigned char hash512[SHA512_DIGEST_LENGTH];
144         char          saltdata[SHA2_SALT_SIZE];
145         struct berval digest;
146         struct berval salt;
147
148         digest.bv_val = (char *) hash512;
149         digest.bv_len = sizeof(hash512);
150         salt.bv_val = saltdata;
151         salt.bv_len = sizeof(saltdata);
152
153         if (lutil_entropy((unsigned char *)salt.bv_val, salt.bv_len) < 0) {
154                 return LUTIL_PASSWD_ERR;
155         }
156
157         SHA512_Init(&ct);
158         SHA512_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len);
159         SHA512_Update(&ct, (const uint8_t*)salt.bv_val, salt.bv_len);
160         SHA512_Final(hash512, &ct);
161
162         return lutil_passwd_string64(scheme, &digest, hash, &salt);
163 }
164
165 static int hash_sha512(
166         const struct berval *scheme,
167         const struct berval *passwd,
168         struct berval *hash,
169         const char **text )
170 {
171         SHA512_CTX ct;
172         unsigned char hash512[SHA512_DIGEST_LENGTH];
173         struct berval digest;
174         digest.bv_val = (char *) hash512;
175         digest.bv_len = sizeof(hash512);
176
177         SHA512_Init(&ct);
178         SHA512_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len);
179         SHA512_Final(hash512, &ct);
180
181         return lutil_passwd_string64(scheme, &digest, hash, NULL);
182 }
183
184 #ifdef SLAPD_SHA2_DEBUG
185 static void chk_sha_debug(
186         const struct berval *scheme,
187         const struct berval *passwd,
188         const struct berval *cred,
189         const char *cred_hash,
190         size_t cred_len,
191         int cmp_rc)
192 {
193         int rc;
194         struct berval cred_b64;
195
196         cred_b64.bv_len = LUTIL_BASE64_ENCODE_LEN(cred_len) + 1;
197         cred_b64.bv_val = ber_memalloc(cred_b64.bv_len + 1);
198
199         if( cred_b64.bv_val == NULL ) {
200                 return;
201         }
202
203         rc = lutil_b64_ntop(
204                 (unsigned char *) cred_hash, cred_len,
205                 cred_b64.bv_val, cred_b64.bv_len );
206
207         if( rc < 0 ) {
208                 ber_memfree(cred_b64.bv_val);
209                 return;
210         }
211
212         fprintf(stderr, "Validating password\n");
213         fprintf(stderr, "  Hash scheme:\t\t%s\n", scheme->bv_val);
214         fprintf(stderr, "  Password to validate: %s\n", cred->bv_val);
215         fprintf(stderr, "  Password hash:\t%s\n", cred_b64.bv_val);
216         fprintf(stderr, "  Stored password hash:\t%s\n", passwd->bv_val);
217         fprintf(stderr, "  Result:\t\t%s\n", cmp_rc ?  "do not match" : "match");
218
219         ber_memfree(cred_b64.bv_val);
220 }
221 #endif
222
223 static int chk_ssha256(
224         const struct berval *scheme, /* Scheme of hashed reference password */
225         const struct berval *passwd, /* Hashed reference password to check against */
226         const struct berval *cred, /* user-supplied password to check */
227         const char **text )
228 {
229         SHA256_CTX SHAcontext;
230         unsigned char SHAdigest[SHA256_DIGEST_LENGTH];
231         int rc;
232         unsigned char *orig_pass = NULL;
233         size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len);
234
235         /* safety check */
236         if (decode_len <= sizeof(SHAdigest)) {
237                 return LUTIL_PASSWD_ERR;
238         }
239
240         /* base64 un-encode password */
241         orig_pass = (unsigned char *) ber_memalloc(decode_len + 1);
242
243         if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
244
245         rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len);
246
247         if( rc <= (int)(sizeof(SHAdigest)) ) {
248                 ber_memfree(orig_pass);
249                 return LUTIL_PASSWD_ERR;
250         }
251
252         /* hash credentials with salt */
253         SHA256_Init(&SHAcontext);
254         SHA256_Update(&SHAcontext,
255                 (const unsigned char *) cred->bv_val, cred->bv_len);
256         SHA256_Update(&SHAcontext,
257                 (const unsigned char *) &orig_pass[sizeof(SHAdigest)],
258                 rc - sizeof(SHAdigest));
259         SHA256_Final(SHAdigest, &SHAcontext);
260
261         /* compare */
262         rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest));
263         ber_memfree(orig_pass);
264         return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
265 }
266
267 static int chk_sha256(
268         const struct berval *scheme, /* Scheme of hashed reference password */
269         const struct berval *passwd, /* Hashed reference password to check against */
270         const struct berval *cred, /* user-supplied password to check */
271         const char **text )
272 {
273         SHA256_CTX SHAcontext;
274         unsigned char SHAdigest[SHA256_DIGEST_LENGTH];
275         int rc;
276         unsigned char *orig_pass = NULL;
277         size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len);
278
279         /* safety check */
280         if (decode_len < sizeof(SHAdigest)) {
281                 return LUTIL_PASSWD_ERR;
282         }
283
284         /* base64 un-encode password */
285         orig_pass = (unsigned char *) ber_memalloc(decode_len + 1);
286
287         if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
288
289         rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len);
290
291         if( rc != sizeof(SHAdigest) ) {
292                 ber_memfree(orig_pass);
293                 return LUTIL_PASSWD_ERR;
294         }
295
296         /* hash credentials with salt */
297         SHA256_Init(&SHAcontext);
298         SHA256_Update(&SHAcontext,
299                 (const unsigned char *) cred->bv_val, cred->bv_len);
300         SHA256_Final(SHAdigest, &SHAcontext);
301
302         /* compare */
303         rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest));
304 #ifdef SLAPD_SHA2_DEBUG
305         chk_sha_debug(scheme, passwd, cred, (char *)SHAdigest, sizeof(SHAdigest), rc);
306 #endif
307         ber_memfree(orig_pass);
308         return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
309 }
310
311 static int chk_ssha384(
312         const struct berval *scheme, /* Scheme of hashed reference password */
313         const struct berval *passwd, /* Hashed reference password to check against */
314         const struct berval *cred, /* user-supplied password to check */
315         const char **text )
316 {
317         SHA384_CTX SHAcontext;
318         unsigned char SHAdigest[SHA384_DIGEST_LENGTH];
319         int rc;
320         unsigned char *orig_pass = NULL;
321         size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len);
322
323         /* safety check */
324         if (decode_len <= sizeof(SHAdigest)) {
325                 return LUTIL_PASSWD_ERR;
326         }
327
328         /* base64 un-encode password */
329         orig_pass = (unsigned char *) ber_memalloc(decode_len + 1);
330
331         if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
332
333         rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len);
334
335         if( rc <= (int)(sizeof(SHAdigest)) ) {
336                 ber_memfree(orig_pass);
337                 return LUTIL_PASSWD_ERR;
338         }
339
340         /* hash credentials with salt */
341         SHA384_Init(&SHAcontext);
342         SHA384_Update(&SHAcontext,
343                 (const unsigned char *) cred->bv_val, cred->bv_len);
344         SHA384_Update(&SHAcontext,
345                 (const unsigned char *) &orig_pass[sizeof(SHAdigest)],
346                 rc - sizeof(SHAdigest));
347         SHA384_Final(SHAdigest, &SHAcontext);
348
349         /* compare */
350         rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest));
351         ber_memfree(orig_pass);
352         return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
353 }
354
355 static int chk_sha384(
356         const struct berval *scheme, /* Scheme of hashed reference password */
357         const struct berval *passwd, /* Hashed reference password to check against */
358         const struct berval *cred, /* user-supplied password to check */
359         const char **text )
360 {
361         SHA384_CTX SHAcontext;
362         unsigned char SHAdigest[SHA384_DIGEST_LENGTH];
363         int rc;
364         unsigned char *orig_pass = NULL;
365         size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len);
366
367         /* safety check */
368         if (decode_len < sizeof(SHAdigest)) {
369                 return LUTIL_PASSWD_ERR;
370         }
371
372         /* base64 un-encode password */
373         orig_pass = (unsigned char *) ber_memalloc(decode_len + 1);
374
375         if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
376
377         rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len);
378
379         if( rc != sizeof(SHAdigest) ) {
380                 ber_memfree(orig_pass);
381                 return LUTIL_PASSWD_ERR;
382         }
383
384         /* hash credentials with salt */
385         SHA384_Init(&SHAcontext);
386         SHA384_Update(&SHAcontext,
387                 (const unsigned char *) cred->bv_val, cred->bv_len);
388         SHA384_Final(SHAdigest, &SHAcontext);
389
390         /* compare */
391         rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest));
392 #ifdef SLAPD_SHA2_DEBUG
393         chk_sha_debug(scheme, passwd, cred, (char *)SHAdigest, sizeof(SHAdigest), rc);
394 #endif
395         ber_memfree(orig_pass);
396         return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
397 }
398
399 static int chk_ssha512(
400         const struct berval *scheme, /* Scheme of hashed reference password */
401         const struct berval *passwd, /* Hashed reference password to check against */
402         const struct berval *cred, /* user-supplied password to check */
403         const char **text )
404 {
405         SHA512_CTX SHAcontext;
406         unsigned char SHAdigest[SHA512_DIGEST_LENGTH];
407         int rc;
408         unsigned char *orig_pass = NULL;
409         size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len);
410
411         /* safety check */
412         if (decode_len <= sizeof(SHAdigest)) {
413                 return LUTIL_PASSWD_ERR;
414         }
415
416         /* base64 un-encode password */
417         orig_pass = (unsigned char *) ber_memalloc(decode_len + 1);
418
419         if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
420
421         rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len);
422
423         if( rc <= (int)(sizeof(SHAdigest)) ) {
424                 ber_memfree(orig_pass);
425                 return LUTIL_PASSWD_ERR;
426         }
427
428         /* hash credentials with salt */
429         SHA512_Init(&SHAcontext);
430         SHA512_Update(&SHAcontext,
431                 (const unsigned char *) cred->bv_val, cred->bv_len);
432         SHA512_Update(&SHAcontext,
433                 (const unsigned char *) &orig_pass[sizeof(SHAdigest)],
434                 rc - sizeof(SHAdigest));
435         SHA512_Final(SHAdigest, &SHAcontext);
436
437         /* compare */
438         rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest));
439         ber_memfree(orig_pass);
440         return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
441 }
442
443 static int chk_sha512(
444         const struct berval *scheme, /* Scheme of hashed reference password */
445         const struct berval *passwd, /* Hashed reference password to check against */
446         const struct berval *cred, /* user-supplied password to check */
447         const char **text )
448 {
449         SHA512_CTX SHAcontext;
450         unsigned char SHAdigest[SHA512_DIGEST_LENGTH];
451         int rc;
452         unsigned char *orig_pass = NULL;
453         size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len);
454
455         /* safety check */
456         if (decode_len < sizeof(SHAdigest)) {
457                 return LUTIL_PASSWD_ERR;
458         }
459
460         /* base64 un-encode password */
461         orig_pass = (unsigned char *) ber_memalloc(decode_len + 1);
462
463         if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
464
465         rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len);
466
467         if( rc != sizeof(SHAdigest) ) {
468                 ber_memfree(orig_pass);
469                 return LUTIL_PASSWD_ERR;
470         }
471
472         /* hash credentials with salt */
473         SHA512_Init(&SHAcontext);
474         SHA512_Update(&SHAcontext,
475                 (const unsigned char *) cred->bv_val, cred->bv_len);
476         SHA512_Final(SHAdigest, &SHAcontext);
477
478         /* compare */
479         rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest));
480 #ifdef SLAPD_SHA2_DEBUG
481         chk_sha_debug(scheme, passwd, cred, (char *)SHAdigest, sizeof(SHAdigest), rc);
482 #endif
483         ber_memfree(orig_pass);
484         return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
485 }
486
487 const struct berval ssha256scheme = BER_BVC("{SSHA256}");
488 const struct berval sha256scheme = BER_BVC("{SHA256}");
489 const struct berval ssha384scheme = BER_BVC("{SSHA384}");
490 const struct berval sha384scheme = BER_BVC("{SHA384}");
491 const struct berval ssha512scheme = BER_BVC("{SSHA512}");
492 const struct berval sha512scheme = BER_BVC("{SHA512}");
493
494 int init_module(int argc, char *argv[]) {
495         int result = 0;
496         result = lutil_passwd_add( (struct berval *)&ssha256scheme, chk_ssha256, hash_ssha256 );
497         if (result != 0) return result;
498         result = lutil_passwd_add( (struct berval *)&sha256scheme, chk_sha256, hash_sha256 );
499         if (result != 0) return result;
500         result = lutil_passwd_add( (struct berval *)&ssha384scheme, chk_ssha384, hash_ssha384 );
501         if (result != 0) return result;
502         result = lutil_passwd_add( (struct berval *)&sha384scheme, chk_sha384, hash_sha384 );
503         if (result != 0) return result;
504         result = lutil_passwd_add( (struct berval *)&ssha512scheme, chk_ssha512, hash_ssha512 );
505         if (result != 0) return result;
506         result = lutil_passwd_add( (struct berval *)&sha512scheme, chk_sha512, hash_sha512 );
507         return result;
508 }