]> git.sur5r.net Git - openldap/blob - contrib/slapd-modules/passwd/sha2/slapd-sha2.c
ITS#6433
[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-2010 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
22 #include <lber.h>
23 #include <lber_pvt.h>
24 #include <ac/string.h>
25 #include "lutil.h"
26 #include <stdint.h>
27 #include <string.h>
28 #include <assert.h>
29 #include "sha2.h"
30
31 #ifdef SLAPD_SHA2_DEBUG
32 #include <stdio.h>
33 #endif
34
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,
39         struct berval *b64,
40         const struct berval *salt )
41 {
42         int rc;
43         struct berval string;
44         size_t b64len;
45
46         if( 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 );
50
51                 if( string.bv_val == NULL ) {
52                         return LUTIL_PASSWD_ERR;
53                 }
54
55                 AC_MEMCPY( string.bv_val, hash->bv_val,
56                         hash->bv_len );
57                 AC_MEMCPY( &string.bv_val[hash->bv_len], salt->bv_val,
58                         salt->bv_len );
59                 string.bv_val[string.bv_len] = '\0';
60
61         } else {
62                 string = *hash;
63         }
64
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 );
68
69         if( b64->bv_val == NULL ) {
70                 if( salt ) ber_memfree( string.bv_val );
71                 return LUTIL_PASSWD_ERR;
72         }
73
74         AC_MEMCPY(b64->bv_val, sc->bv_val, sc->bv_len);
75
76         rc = lutil_b64_ntop(
77                 (unsigned char *) string.bv_val, string.bv_len,
78                 &b64->bv_val[sc->bv_len], b64len );
79
80         if( salt ) ber_memfree( string.bv_val );
81         
82         if( rc < 0 ) {
83                 return LUTIL_PASSWD_ERR;
84         }
85
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;
90 }
91
92 char * sha256_hex_hash(const char * passwd) {
93
94         SHA256_CTX ct;
95         unsigned char hash[SHA256_DIGEST_LENGTH];
96         static char real_hash[LUTIL_BASE64_ENCODE_LEN(SHA256_DIGEST_LENGTH)+1]; // extra char for \0
97
98         SHA256_Init(&ct);
99         SHA256_Update(&ct, (const uint8_t*)passwd, strlen(passwd));
100         SHA256_Final(hash, &ct);
101
102         /* base64 encode it */
103         lutil_b64_ntop(
104                         hash,
105                         SHA256_DIGEST_LENGTH,
106                         real_hash,
107                         LUTIL_BASE64_ENCODE_LEN(SHA256_DIGEST_LENGTH)+1
108                         );
109
110         return real_hash;
111 }
112
113
114 char * sha384_hex_hash(const char * passwd) {
115
116         SHA384_CTX ct;
117         unsigned char hash[SHA384_DIGEST_LENGTH];
118         static char real_hash[LUTIL_BASE64_ENCODE_LEN(SHA384_DIGEST_LENGTH)+1]; // extra char for \0
119
120         SHA384_Init(&ct);
121         SHA384_Update(&ct, (const uint8_t*)passwd, strlen(passwd));
122         SHA384_Final(hash, &ct);
123
124         /* base64 encode it */
125         lutil_b64_ntop(
126                         hash,
127                         SHA384_DIGEST_LENGTH,
128                         real_hash,
129                         LUTIL_BASE64_ENCODE_LEN(SHA384_DIGEST_LENGTH)+1
130                         );
131
132         return real_hash;
133 }
134
135 char * sha512_hex_hash(const char * passwd) {
136
137         SHA512_CTX ct;
138         unsigned char hash[SHA512_DIGEST_LENGTH];
139         static char real_hash[LUTIL_BASE64_ENCODE_LEN(SHA512_DIGEST_LENGTH)+1]; // extra char for \0
140
141         SHA512_Init(&ct);
142         SHA512_Update(&ct, (const uint8_t*)passwd, strlen(passwd));
143         SHA512_Final(hash, &ct);
144
145         /* base64 encode it */
146         lutil_b64_ntop(
147                         hash,
148                         SHA512_DIGEST_LENGTH,
149                         real_hash,
150                         LUTIL_BASE64_ENCODE_LEN(SHA512_DIGEST_LENGTH)+1
151                         );
152
153         return real_hash;
154 }
155
156 static int hash_sha256(
157         const struct berval *scheme,
158         const struct berval *passwd,
159         struct berval *hash,
160         const char **text )
161 {
162         SHA256_CTX ct;
163         unsigned char hash256[SHA256_DIGEST_LENGTH];
164
165         SHA256_Init(&ct);
166         SHA256_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len);
167         SHA256_Final(hash256, &ct);
168
169         struct berval digest;
170         digest.bv_val = (char *) hash256;
171         digest.bv_len = sizeof(hash256);
172
173         return pw_string64(scheme, &digest, hash, NULL);
174 }
175
176 static int hash_sha384(
177         const struct berval *scheme,
178         const struct berval *passwd,
179         struct berval *hash,
180         const char **text )
181 {
182         SHA384_CTX ct;
183         unsigned char hash384[SHA384_DIGEST_LENGTH];
184
185 #ifdef SLAPD_SHA2_DEBUG
186         fprintf(stderr, "hashing password\n");
187 #endif
188         SHA384_Init(&ct);
189         SHA384_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len);
190         SHA384_Final(hash384, &ct);
191
192         struct berval digest;
193         digest.bv_val = (char *) hash384;
194         digest.bv_len = sizeof(hash384);
195
196         return pw_string64(scheme, &digest, hash, NULL);
197 }
198
199 static int hash_sha512(
200         const struct berval *scheme,
201         const struct berval *passwd,
202         struct berval *hash,
203         const char **text )
204 {
205         SHA512_CTX ct;
206         unsigned char hash512[SHA512_DIGEST_LENGTH];
207
208         SHA512_Init(&ct);
209         SHA512_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len);
210         SHA512_Final(hash512, &ct);
211
212         struct berval digest;
213         digest.bv_val = (char *) hash512;
214         digest.bv_len = sizeof(hash512);
215
216         return pw_string64(scheme, &digest, hash, NULL);
217 }
218
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
223         const char **text )
224 {
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");
232 #endif
233         return (strcmp(sha256_hex_hash(cred->bv_val), passwd->bv_val));
234 }
235
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
240         const char **text )
241 {
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");
249 #endif
250         return (strcmp(sha384_hex_hash(cred->bv_val), passwd->bv_val));
251 }
252
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
257         const char **text )
258 {
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");
265 #endif
266         return (strcmp(sha512_hex_hash(cred->bv_val), passwd->bv_val));
267 }
268
269 const struct berval sha256scheme = BER_BVC("{SHA256}");
270 const struct berval sha384scheme = BER_BVC("{SHA384}");
271 const struct berval sha512scheme = BER_BVC("{SHA512}");
272
273 int init_module(int argc, char *argv[]) {
274         int result = 0;
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 );
280         return result;
281 }