2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 2009-2012 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 char * sha256_hex_hash(const char * passwd) {
38 unsigned char hash[SHA256_DIGEST_LENGTH];
39 static char real_hash[LUTIL_BASE64_ENCODE_LEN(SHA256_DIGEST_LENGTH)+1]; // extra char for \0
42 SHA256_Update(&ct, (const uint8_t*)passwd, strlen(passwd));
43 SHA256_Final(hash, &ct);
45 /* base64 encode it */
50 LUTIL_BASE64_ENCODE_LEN(SHA256_DIGEST_LENGTH)+1
57 char * sha384_hex_hash(const char * passwd) {
60 unsigned char hash[SHA384_DIGEST_LENGTH];
61 static char real_hash[LUTIL_BASE64_ENCODE_LEN(SHA384_DIGEST_LENGTH)+1]; // extra char for \0
64 SHA384_Update(&ct, (const uint8_t*)passwd, strlen(passwd));
65 SHA384_Final(hash, &ct);
67 /* base64 encode it */
72 LUTIL_BASE64_ENCODE_LEN(SHA384_DIGEST_LENGTH)+1
78 char * sha512_hex_hash(const char * passwd) {
81 unsigned char hash[SHA512_DIGEST_LENGTH];
82 static char real_hash[LUTIL_BASE64_ENCODE_LEN(SHA512_DIGEST_LENGTH)+1]; // extra char for \0
85 SHA512_Update(&ct, (const uint8_t*)passwd, strlen(passwd));
86 SHA512_Final(hash, &ct);
88 /* base64 encode it */
93 LUTIL_BASE64_ENCODE_LEN(SHA512_DIGEST_LENGTH)+1
99 static int hash_sha256(
100 const struct berval *scheme,
101 const struct berval *passwd,
106 unsigned char hash256[SHA256_DIGEST_LENGTH];
109 SHA256_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len);
110 SHA256_Final(hash256, &ct);
112 struct berval digest;
113 digest.bv_val = (char *) hash256;
114 digest.bv_len = sizeof(hash256);
116 return lutil_passwd_string64(scheme, &digest, hash, NULL);
119 static int hash_sha384(
120 const struct berval *scheme,
121 const struct berval *passwd,
126 unsigned char hash384[SHA384_DIGEST_LENGTH];
128 #ifdef SLAPD_SHA2_DEBUG
129 fprintf(stderr, "hashing password\n");
132 SHA384_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len);
133 SHA384_Final(hash384, &ct);
135 struct berval digest;
136 digest.bv_val = (char *) hash384;
137 digest.bv_len = sizeof(hash384);
139 return lutil_passwd_string64(scheme, &digest, hash, NULL);
142 static int hash_sha512(
143 const struct berval *scheme,
144 const struct berval *passwd,
149 unsigned char hash512[SHA512_DIGEST_LENGTH];
152 SHA512_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len);
153 SHA512_Final(hash512, &ct);
155 struct berval digest;
156 digest.bv_val = (char *) hash512;
157 digest.bv_len = sizeof(hash512);
159 return lutil_passwd_string64(scheme, &digest, hash, NULL);
162 static int chk_sha256(
163 const struct berval *scheme, // Scheme of hashed reference password
164 const struct berval *passwd, // Hashed reference password to check against
165 const struct berval *cred, // user-supplied password to check
168 #ifdef SLAPD_SHA2_DEBUG
169 fprintf(stderr, "Validating password\n");
170 fprintf(stderr, " Password to validate: %s\n", cred->bv_val);
171 fprintf(stderr, " Hashes to: %s\n", sha256_hex_hash(cred->bv_val));
172 fprintf(stderr, " Stored password scheme: %s\n", scheme->bv_val);
173 fprintf(stderr, " Stored password value: %s\n", passwd->bv_val);
174 fprintf(stderr, " -> Passwords %s\n", strcmp(sha256_hex_hash(cred->bv_val), passwd->bv_val) == 0 ? "match" : "do not match");
176 return (strcmp(sha256_hex_hash(cred->bv_val), passwd->bv_val));
179 static int chk_sha384(
180 const struct berval *scheme, // Scheme of hashed reference password
181 const struct berval *passwd, // Hashed reference password to check against
182 const struct berval *cred, // user-supplied password to check
185 #ifdef SLAPD_SHA2_DEBUG
186 fprintf(stderr, "Validating password\n");
187 fprintf(stderr, " Password to validate: %s\n", cred->bv_val);
188 fprintf(stderr, " Hashes to: %s\n", sha384_hex_hash(cred->bv_val));
189 fprintf(stderr, " Stored password scheme: %s\n", scheme->bv_val);
190 fprintf(stderr, " Stored password value: %s\n", passwd->bv_val);
191 fprintf(stderr, " -> Passwords %s\n", strcmp(sha384_hex_hash(cred->bv_val), passwd->bv_val) == 0 ? "match" : "do not match");
193 return (strcmp(sha384_hex_hash(cred->bv_val), passwd->bv_val));
196 static int chk_sha512(
197 const struct berval *scheme, // Scheme of hashed reference password
198 const struct berval *passwd, // Hashed reference password to check against
199 const struct berval *cred, // user-supplied password to check
202 #ifdef SLAPD_SHA2_DEBUG
203 fprintf(stderr, " Password to validate: %s\n", cred->bv_val);
204 fprintf(stderr, " Hashes to: %s\n", sha512_hex_hash(cred->bv_val));
205 fprintf(stderr, " Stored password scheme: %s\n", scheme->bv_val);
206 fprintf(stderr, " Stored password value: %s\n", passwd->bv_val);
207 fprintf(stderr, " -> Passwords %s\n", strcmp(sha512_hex_hash(cred->bv_val), passwd->bv_val) == 0 ? "match" : "do not match");
209 return (strcmp(sha512_hex_hash(cred->bv_val), passwd->bv_val));
212 const struct berval sha256scheme = BER_BVC("{SHA256}");
213 const struct berval sha384scheme = BER_BVC("{SHA384}");
214 const struct berval sha512scheme = BER_BVC("{SHA512}");
216 int init_module(int argc, char *argv[]) {
218 result = lutil_passwd_add( (struct berval *)&sha256scheme, chk_sha256, hash_sha256 );
219 if (result != 0) return result;
220 result = lutil_passwd_add( (struct berval *)&sha384scheme, chk_sha384, hash_sha384 );
221 if (result != 0) return result;
222 result = lutil_passwd_add( (struct berval *)&sha512scheme, chk_sha512, hash_sha512 );