X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Fliblutil%2Fpasswd.c;h=d5ab32617261f06e9f4a11ab9df444d3aae4b4f0;hb=8452b4ccde09a41c7e21cff66ec4f566b1a34e28;hp=269df67ed188c2bf58f3ab45ec29ceb1ccac80bd;hpb=9449c5709e19753fd5ea2cbaeca923d1f2d2a9c7;p=openldap diff --git a/libraries/liblutil/passwd.c b/libraries/liblutil/passwd.c index 269df67ed1..d5ab326172 100644 --- a/libraries/liblutil/passwd.c +++ b/libraries/liblutil/passwd.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2005 The OpenLDAP Foundation. + * Copyright 1998-2012 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,32 @@ #include #if defined(SLAPD_LMHASH) +#if defined(HAVE_OPENSSL) # include + + +typedef des_cblock des_key; +typedef des_cblock des_data_block; +typedef des_key_schedule des_context; +#define des_failed(encrypted) 0 +#define des_finish(key, schedule) + +#elif defined(HAVE_MOZNSS) +/* + hack hack hack + We need to define this here so that nspr/obsolete/protypes.h will not be included + if that file is included, it will create a uint32 typedef that will cause the + one in lutil_sha1.h to blow up +*/ +#define PROTYPES_H 1 +# include +typedef PK11SymKey *des_key; +typedef unsigned char des_data_block[8]; +typedef PK11Context *des_context[1]; +#define DES_ENCRYPT CKA_ENCRYPT + +#endif + #endif /* SLAPD_LMHASH */ #include @@ -309,7 +334,7 @@ lutil_passwd( * didn't recognize? Assume a scheme name is at least 1 character. */ if (( passwd->bv_val[0] == '{' ) && - ( strchr( passwd->bv_val, '}' ) > passwd->bv_val+1 )) + ( ber_bvchr( passwd, '}' ) > passwd->bv_val+1 )) { return 1; } @@ -399,7 +424,7 @@ static int pw_string( } #endif /* SLAPD_LMHASH || SLAPD_CRYPT */ -static int pw_string64( +int lutil_passwd_string64( const struct berval *sc, const struct berval *hash, struct berval *b64, @@ -632,6 +657,106 @@ static int chk_md5( } #ifdef SLAPD_LMHASH + +#if defined(HAVE_OPENSSL) + +/* + * abstract away setting the parity. + */ +static void +des_set_key_and_parity( des_key *key, unsigned char *keyData) +{ + memcpy(key, keyData, 8); + des_set_odd_parity( key ); +} + + +#elif defined(HAVE_MOZNSS) + +/* + * implement MozNSS wrappers for the openSSL calls + */ +static void +des_set_key_and_parity( des_key *key, unsigned char *keyData) +{ + SECItem keyDataItem; + PK11SlotInfo *slot; + *key = NULL; + + keyDataItem.data = keyData; + keyDataItem.len = 8; + + slot = PK11_GetBestSlot(CKM_DES_ECB, NULL); + if (slot == NULL) { + return; + } + + /* NOTE: this will not work in FIPS mode. In order to make lmhash + * work in fips mode we need to define a LMHASH pbe mechanism and + * do the fulll key derivation inside the token */ + *key = PK11_ImportSymKey(slot, CKM_DES_ECB, PK11_OriginGenerated, + CKA_ENCRYPT, &keyDataItem, NULL); +} + +static void +des_set_key_unchecked( des_key *key, des_context ctxt ) +{ + ctxt[0] = NULL; + + /* handle error conditions from previous call */ + if (!*key) { + return; + } + + ctxt[0] = PK11_CreateContextBySymKey(CKM_DES_ECB, CKA_ENCRYPT, *key, NULL); +} + +static void +des_ecb_encrypt( des_data_block *plain, des_data_block *encrypted, + des_context ctxt, int op) +{ + SECStatus rv; + int size; + + if (ctxt[0] == NULL) { + /* need to fail here... */ + memset(encrypted, 0, sizeof(des_data_block)); + return; + } + rv = PK11_CipherOp(ctxt[0], (unsigned char *)&encrypted[0], + &size, sizeof(des_data_block), + (unsigned char *)&plain[0], sizeof(des_data_block)); + if (rv != SECSuccess) { + /* signal failure */ + memset(encrypted, 0, sizeof(des_data_block)); + return; + } + return; +} + +static int +des_failed(des_data_block *encrypted) +{ + static const des_data_block zero = { 0 }; + return memcmp(encrypted, zero, sizeof(zero)) == 0; +} + +static void +des_finish(des_key *key, des_context ctxt) +{ + if (*key) { + PK11_FreeSymKey(*key); + *key = NULL; + } + if (ctxt[0]) { + PK11_Finalize(ctxt[0]); + PK11_DestroyContext(ctxt[0], PR_TRUE); + ctxt[0] = NULL; + } +} + +#endif + /* pseudocode from RFC2433 * A.2 LmPasswordHash() * @@ -692,10 +817,10 @@ static int chk_md5( static void lmPasswd_to_key( const char *lmPasswd, - des_cblock *key) + des_key *key) { const unsigned char *lpw = (const unsigned char *) lmPasswd; - unsigned char *k = (unsigned char *) key; + unsigned char k[8]; /* make room for parity bits */ k[0] = lpw[0]; @@ -707,7 +832,7 @@ static void lmPasswd_to_key( k[6] = ((lpw[5] & 0x3F) << 2) | (lpw[6] >> 6); k[7] = ((lpw[6] & 0x7F) << 1); - des_set_odd_parity( key ); + des_set_key_and_parity( key, k ); } static int chk_lanman( @@ -716,12 +841,12 @@ static int chk_lanman( const struct berval *cred, const char **text ) { - int i; + ber_len_t i; char UcasePassword[15]; - des_cblock key; - des_key_schedule schedule; - des_cblock StdText = "KGS!@#$%"; - des_cblock PasswordHash1, PasswordHash2; + des_key key; + des_context schedule; + des_data_block StdText = "KGS!@#$%"; + des_data_block PasswordHash1, PasswordHash2; char PasswordHash[33], storedPasswordHash[33]; for( i=0; ibv_len; i++) { @@ -741,10 +866,19 @@ static int chk_lanman( lmPasswd_to_key( UcasePassword, &key ); des_set_key_unchecked( &key, schedule ); des_ecb_encrypt( &StdText, &PasswordHash1, schedule , DES_ENCRYPT ); + + if (des_failed(&PasswordHash1)) { + return LUTIL_PASSWD_ERR; + } lmPasswd_to_key( &UcasePassword[7], &key ); des_set_key_unchecked( &key, schedule ); des_ecb_encrypt( &StdText, &PasswordHash2, schedule , DES_ENCRYPT ); + if (des_failed(&PasswordHash2)) { + return LUTIL_PASSWD_ERR; + } + + des_finish( &key, schedule ); sprintf( PasswordHash, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", PasswordHash1[0],PasswordHash1[1],PasswordHash1[2],PasswordHash1[3], @@ -917,7 +1051,7 @@ static int hash_ssha1( (const unsigned char *)salt.bv_val, salt.bv_len ); lutil_SHA1Final( SHA1digest, &SHA1context ); - return pw_string64( scheme, &digest, hash, &salt); + return lutil_passwd_string64( scheme, &digest, hash, &salt); } static int hash_sha1( @@ -937,7 +1071,7 @@ static int hash_sha1( (const unsigned char *)passwd->bv_val, passwd->bv_len ); lutil_SHA1Final( SHA1digest, &SHA1context ); - return pw_string64( scheme, &digest, hash, NULL); + return lutil_passwd_string64( scheme, &digest, hash, NULL); } #endif @@ -969,7 +1103,7 @@ static int hash_smd5( (const unsigned char *) salt.bv_val, salt.bv_len ); lutil_MD5Final( MD5digest, &MD5context ); - return pw_string64( scheme, &digest, hash, &salt ); + return lutil_passwd_string64( scheme, &digest, hash, &salt ); } static int hash_md5( @@ -991,7 +1125,7 @@ static int hash_md5( (const unsigned char *) passwd->bv_val, passwd->bv_len ); lutil_MD5Final( MD5digest, &MD5context ); - return pw_string64( scheme, &digest, hash, NULL ); + return lutil_passwd_string64( scheme, &digest, hash, NULL ); ; } @@ -1003,12 +1137,12 @@ static int hash_lanman( const char **text ) { - int i; + ber_len_t i; char UcasePassword[15]; - des_cblock key; - des_key_schedule schedule; - des_cblock StdText = "KGS!@#$%"; - des_cblock PasswordHash1, PasswordHash2; + des_key key; + des_context schedule; + des_data_block StdText = "KGS!@#$%"; + des_data_block PasswordHash1, PasswordHash2; char PasswordHash[33]; for( i=0; ibv_len; i++) { @@ -1107,7 +1241,7 @@ static int hash_crypt( int lutil_salt_format(const char *format) { #ifdef SLAPD_CRYPT - free( salt_format ); + ber_memfree( salt_format ); salt_format = format != NULL ? ber_strdup( format ) : NULL; #endif