1 /* $NetBSD: slapd-sha2.c,v 1.1.1.2 2010/12/12 15:19:14 adam Exp $ */ 2 3 /* OpenLDAP: pkg/ldap/contrib/slapd-modules/passwd/sha2/slapd-sha2.c,v 1.1.2.5 2010/04/15 18:40:14 quanah Exp */ 4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 2009-2010 The OpenLDAP Foundation. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted only as authorized by the OpenLDAP 11 * Public License. 12 * 13 * A copy of this license is available in the file LICENSE in the 14 * top-level directory of the distribution or, alternatively, at 15 * <http://www.OpenLDAP.org/license.html>. 16 */ 17 /* ACKNOWLEDGEMENT: 18 * This work was initially developed by Jeff Turner for inclusion 19 * in OpenLDAP Software. 20 * 21 * Hash methods for passwords generation added by Cédric Delfosse. 22 */ 23 24 #include <lber.h> 25 #include <lber_pvt.h> 26 #include <ac/string.h> 27 #include "lutil.h" 28 #include <stdint.h> 29 #include <string.h> 30 #include <assert.h> 31 #include "sha2.h" 32 33 #ifdef SLAPD_SHA2_DEBUG 34 #include <stdio.h> 35 #endif 36 37 /* pw_string64 function taken from libraries/liblutil/passwd.c */ 38 static int pw_string64( 39 const struct berval *sc, 40 const struct berval *hash, 41 struct berval *b64, 42 const struct berval *salt ) 43 { 44 int rc; 45 struct berval string; 46 size_t b64len; 47 48 if( salt ) { 49 /* need to base64 combined string */ 50 string.bv_len = hash->bv_len + salt->bv_len; 51 string.bv_val = ber_memalloc( string.bv_len + 1 ); 52 53 if( string.bv_val == NULL ) { 54 return LUTIL_PASSWD_ERR; 55 } 56 57 AC_MEMCPY( string.bv_val, hash->bv_val, 58 hash->bv_len ); 59 AC_MEMCPY( &string.bv_val[hash->bv_len], salt->bv_val, 60 salt->bv_len ); 61 string.bv_val[string.bv_len] = '\0'; 62 63 } else { 64 string = *hash; 65 } 66 67 b64len = LUTIL_BASE64_ENCODE_LEN( string.bv_len ) + 1; 68 b64->bv_len = b64len + sc->bv_len; 69 b64->bv_val = ber_memalloc( b64->bv_len + 1 ); 70 71 if( b64->bv_val == NULL ) { 72 if( salt ) ber_memfree( string.bv_val ); 73 return LUTIL_PASSWD_ERR; 74 } 75 76 AC_MEMCPY(b64->bv_val, sc->bv_val, sc->bv_len); 77 78 rc = lutil_b64_ntop( 79 (unsigned char *) string.bv_val, string.bv_len, 80 &b64->bv_val[sc->bv_len], b64len ); 81 82 if( salt ) ber_memfree( string.bv_val ); 83 84 if( rc < 0 ) { 85 return LUTIL_PASSWD_ERR; 86 } 87 88 /* recompute length */ 89 b64->bv_len = sc->bv_len + rc; 90 assert( strlen(b64->bv_val) == b64->bv_len ); 91 return LUTIL_PASSWD_OK; 92 } 93 94 char * sha256_hex_hash(const char * passwd) { 95 96 SHA256_CTX ct; 97 unsigned char hash[SHA256_DIGEST_LENGTH]; 98 static char real_hash[LUTIL_BASE64_ENCODE_LEN(SHA256_DIGEST_LENGTH)+1]; // extra char for \0 99 100 SHA256_Init(&ct); 101 SHA256_Update(&ct, (const uint8_t*)passwd, strlen(passwd)); 102 SHA256_Final(hash, &ct); 103 104 /* base64 encode it */ 105 lutil_b64_ntop( 106 hash, 107 SHA256_DIGEST_LENGTH, 108 real_hash, 109 LUTIL_BASE64_ENCODE_LEN(SHA256_DIGEST_LENGTH)+1 110 ); 111 112 return real_hash; 113 } 114 115 116 char * sha384_hex_hash(const char * passwd) { 117 118 SHA384_CTX ct; 119 unsigned char hash[SHA384_DIGEST_LENGTH]; 120 static char real_hash[LUTIL_BASE64_ENCODE_LEN(SHA384_DIGEST_LENGTH)+1]; // extra char for \0 121 122 SHA384_Init(&ct); 123 SHA384_Update(&ct, (const uint8_t*)passwd, strlen(passwd)); 124 SHA384_Final(hash, &ct); 125 126 /* base64 encode it */ 127 lutil_b64_ntop( 128 hash, 129 SHA384_DIGEST_LENGTH, 130 real_hash, 131 LUTIL_BASE64_ENCODE_LEN(SHA384_DIGEST_LENGTH)+1 132 ); 133 134 return real_hash; 135 } 136 137 char * sha512_hex_hash(const char * passwd) { 138 139 SHA512_CTX ct; 140 unsigned char hash[SHA512_DIGEST_LENGTH]; 141 static char real_hash[LUTIL_BASE64_ENCODE_LEN(SHA512_DIGEST_LENGTH)+1]; // extra char for \0 142 143 SHA512_Init(&ct); 144 SHA512_Update(&ct, (const uint8_t*)passwd, strlen(passwd)); 145 SHA512_Final(hash, &ct); 146 147 /* base64 encode it */ 148 lutil_b64_ntop( 149 hash, 150 SHA512_DIGEST_LENGTH, 151 real_hash, 152 LUTIL_BASE64_ENCODE_LEN(SHA512_DIGEST_LENGTH)+1 153 ); 154 155 return real_hash; 156 } 157 158 static int hash_sha256( 159 const struct berval *scheme, 160 const struct berval *passwd, 161 struct berval *hash, 162 const char **text ) 163 { 164 SHA256_CTX ct; 165 unsigned char hash256[SHA256_DIGEST_LENGTH]; 166 167 SHA256_Init(&ct); 168 SHA256_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); 169 SHA256_Final(hash256, &ct); 170 171 struct berval digest; 172 digest.bv_val = (char *) hash256; 173 digest.bv_len = sizeof(hash256); 174 175 return pw_string64(scheme, &digest, hash, NULL); 176 } 177 178 static int hash_sha384( 179 const struct berval *scheme, 180 const struct berval *passwd, 181 struct berval *hash, 182 const char **text ) 183 { 184 SHA384_CTX ct; 185 unsigned char hash384[SHA384_DIGEST_LENGTH]; 186 187 #ifdef SLAPD_SHA2_DEBUG 188 fprintf(stderr, "hashing password\n"); 189 #endif 190 SHA384_Init(&ct); 191 SHA384_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); 192 SHA384_Final(hash384, &ct); 193 194 struct berval digest; 195 digest.bv_val = (char *) hash384; 196 digest.bv_len = sizeof(hash384); 197 198 return pw_string64(scheme, &digest, hash, NULL); 199 } 200 201 static int hash_sha512( 202 const struct berval *scheme, 203 const struct berval *passwd, 204 struct berval *hash, 205 const char **text ) 206 { 207 SHA512_CTX ct; 208 unsigned char hash512[SHA512_DIGEST_LENGTH]; 209 210 SHA512_Init(&ct); 211 SHA512_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); 212 SHA512_Final(hash512, &ct); 213 214 struct berval digest; 215 digest.bv_val = (char *) hash512; 216 digest.bv_len = sizeof(hash512); 217 218 return pw_string64(scheme, &digest, hash, NULL); 219 } 220 221 static int chk_sha256( 222 const struct berval *scheme, // Scheme of hashed reference password 223 const struct berval *passwd, // Hashed reference password to check against 224 const struct berval *cred, // user-supplied password to check 225 const char **text ) 226 { 227 #ifdef SLAPD_SHA2_DEBUG 228 fprintf(stderr, "Validating password\n"); 229 fprintf(stderr, " Password to validate: %s\n", cred->bv_val); 230 fprintf(stderr, " Hashes to: %s\n", sha256_hex_hash(cred->bv_val)); 231 fprintf(stderr, " Stored password scheme: %s\n", scheme->bv_val); 232 fprintf(stderr, " Stored password value: %s\n", passwd->bv_val); 233 fprintf(stderr, " -> Passwords %s\n", strcmp(sha256_hex_hash(cred->bv_val), passwd->bv_val) == 0 ? "match" : "do not match"); 234 #endif 235 return (strcmp(sha256_hex_hash(cred->bv_val), passwd->bv_val)); 236 } 237 238 static int chk_sha384( 239 const struct berval *scheme, // Scheme of hashed reference password 240 const struct berval *passwd, // Hashed reference password to check against 241 const struct berval *cred, // user-supplied password to check 242 const char **text ) 243 { 244 #ifdef SLAPD_SHA2_DEBUG 245 fprintf(stderr, "Validating password\n"); 246 fprintf(stderr, " Password to validate: %s\n", cred->bv_val); 247 fprintf(stderr, " Hashes to: %s\n", sha384_hex_hash(cred->bv_val)); 248 fprintf(stderr, " Stored password scheme: %s\n", scheme->bv_val); 249 fprintf(stderr, " Stored password value: %s\n", passwd->bv_val); 250 fprintf(stderr, " -> Passwords %s\n", strcmp(sha384_hex_hash(cred->bv_val), passwd->bv_val) == 0 ? "match" : "do not match"); 251 #endif 252 return (strcmp(sha384_hex_hash(cred->bv_val), passwd->bv_val)); 253 } 254 255 static int chk_sha512( 256 const struct berval *scheme, // Scheme of hashed reference password 257 const struct berval *passwd, // Hashed reference password to check against 258 const struct berval *cred, // user-supplied password to check 259 const char **text ) 260 { 261 #ifdef SLAPD_SHA2_DEBUG 262 fprintf(stderr, " Password to validate: %s\n", cred->bv_val); 263 fprintf(stderr, " Hashes to: %s\n", sha512_hex_hash(cred->bv_val)); 264 fprintf(stderr, " Stored password scheme: %s\n", scheme->bv_val); 265 fprintf(stderr, " Stored password value: %s\n", passwd->bv_val); 266 fprintf(stderr, " -> Passwords %s\n", strcmp(sha512_hex_hash(cred->bv_val), passwd->bv_val) == 0 ? "match" : "do not match"); 267 #endif 268 return (strcmp(sha512_hex_hash(cred->bv_val), passwd->bv_val)); 269 } 270 271 const struct berval sha256scheme = BER_BVC("{SHA256}"); 272 const struct berval sha384scheme = BER_BVC("{SHA384}"); 273 const struct berval sha512scheme = BER_BVC("{SHA512}"); 274 275 int init_module(int argc, char *argv[]) { 276 int result = 0; 277 result = lutil_passwd_add( (struct berval *)&sha256scheme, chk_sha256, hash_sha256 ); 278 if (result != 0) return result; 279 result = lutil_passwd_add( (struct berval *)&sha384scheme, chk_sha384, hash_sha384 ); 280 if (result != 0) return result; 281 result = lutil_passwd_add( (struct berval *)&sha512scheme, chk_sha512, hash_sha512 ); 282 return result; 283 } 284