int GenerateCrypt(char *szUser, char *szPassword, char *szChallenge64, long clientinfo, long embkey, char *szResult) { unsigned char szDecoded[256]; unsigned char szKey[256]; unsigned char szAscii[256]; unsigned int nDecodedLen; long challengetime = 0; int nMoveBits; long challengetime_new = 0; long a, b, c, d; unsigned int nKey; int nUser; unsigned int nEncoded; //Base64 解码 nDecodedLen = lutil_b64_pton(szChallenge64, szDecoded, 256); memcpy(&challengetime, szDecoded + 6, 4); //取反进行或运算 challengetime |= ~embkey; //得到循环移位位数 nMoveBits = challengetime % 30; //完成32位的循环位移 a = challengetime << ((32 - nMoveBits) % 32); b = challengetime >> (((unsigned int )nMoveBits) % 32); c = ~(0xffffffff << ((32 - nMoveBits) % 32)); d = b & c; challengetime_new = a | d; //KEY-MD5 nKey = KeyMD5Encode(szKey, (unsigned char*)szPassword, strlen((char*)szPassword), (unsigned char*)szDecoded, nDecodedLen); szKey[nKey] = 0; nUser = strlen((char *)szUser); memcpy(szAscii, szUser, nUser); szAscii[nUser] = ' '; memcpy(szAscii+nUser+1, &challengetime_new,4); memcpy(szAscii+nUser+1+4,&clientinfo,4); memcpy(szAscii+nUser+1+4+4, szKey, nKey); //base64 编码 nEncoded = lutil_b64_ntop((unsigned char *)szAscii, nUser + 1 + 4 + 4 + nKey, szResult, 256); return nEncoded; }
static int chk_sha512( const struct berval *scheme, /* Scheme of hashed reference password */ const struct berval *passwd, /* Hashed reference password to check against */ const struct berval *cred, /* user-supplied password to check */ const char **text ) { SHA512_CTX SHAcontext; unsigned char SHAdigest[SHA512_DIGEST_LENGTH]; int rc; unsigned char *orig_pass = NULL; size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len); /* safety check */ if (decode_len < sizeof(SHAdigest)) { return LUTIL_PASSWD_ERR; } /* base64 un-encode password */ orig_pass = (unsigned char *) ber_memalloc(decode_len + 1); if( orig_pass == NULL ) return LUTIL_PASSWD_ERR; rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len); if( rc != sizeof(SHAdigest) ) { ber_memfree(orig_pass); return LUTIL_PASSWD_ERR; } /* hash credentials with salt */ SHA512_Init(&SHAcontext); SHA512_Update(&SHAcontext, (const unsigned char *) cred->bv_val, cred->bv_len); SHA512_Final(SHAdigest, &SHAcontext); /* compare */ rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest)); #ifdef SLAPD_SHA2_DEBUG chk_sha_debug(scheme, passwd, cred, (char *)SHAdigest, sizeof(SHAdigest), rc); #endif ber_memfree(orig_pass); return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; }
static int chk_phk( const struct berval *magic, const struct berval *passwd, const struct berval *cred, const char **text) { unsigned char digest[LUTIL_MD5_BYTES]; unsigned char *orig_pass; int rc, n; struct berval salt; /* safety check */ n = LUTIL_BASE64_DECODE_LEN(passwd->bv_len); if (n <= sizeof(digest)) return LUTIL_PASSWD_ERR; /* base64 un-encode password hash */ orig_pass = (unsigned char *) ber_memalloc((size_t) (n + 1)); if (orig_pass == NULL) return LUTIL_PASSWD_ERR; rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len); if (rc <= (int) sizeof(digest)) { ber_memfree(orig_pass); return LUTIL_PASSWD_ERR; } salt.bv_val = (char *) &orig_pass[sizeof(digest)]; salt.bv_len = rc - sizeof(digest); do_phk_hash(cred, magic, &salt, digest); if (text) *text = NULL; /* compare */ rc = memcmp((char *) orig_pass, (char *) digest, sizeof(digest)); ber_memfree(orig_pass); return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; }
/*porting from oms project: parse_url */ BOOL RTSP_Parse_Url(const char *url, char *server, int *port, char *file_name, char *user, char *password) { /* expects format '[rtsp://[user:password@]server[:port]/]filename[?param=encoded_parameters]' */ /* parameters: username=xxx&password=yyyy&expire=nnnn */ BOOL ret = FALSE; /* copy url */ *port = RTSP_DEFAULT_SVR_PORT; if(user) *user = '******'; if(password) *password = '******'; if (strncmp(url, "rtsp://", 7) == 0) { char *param; char *p1 =(char*)(url+7); char *p2 = p1; int hasAccount = strchr(url, '@'); param = strchr(p1, '?'); if(param) *param = '\0'; //set to '\0' temporarily for convenionce of string operation while(*p2 && *p2 != '/') { if(*p2 == '@') { if(password) strncpyz(password, p1, p2-p1+1); p1 = p2 + 1; hasAccount = 0; } else if(*p2 == ':') { if(hasAccount) { if(user) strncpyz(user, p1, p2-p1+1); p1 = p2 + 1; } else break; } p2++; } strncpy(server, p1, p2-p1); server[p2-p1] = '\0'; if(*p2 == ':') { *port = atoi(p2+1); while(*p2 && *p2 != '/') p2++; } strcpy(file_name, p2+1); if(param) { *param++ = '?'; //restore if(strncmp("param=", param, 6) == 0) { char str[128], *usr, *pswd; KEYVAL kv[] = { { "username", KEYVALTYPE_POINTER, &usr }, { "password", KEYVALTYPE_POINTER, &pswd } }; memset(str, 0, sizeof(str)); lutil_b64_pton(param+6, str, sizeof(str)); ParseHttpBody(str, kv, sizeof(kv)/sizeof(KEYVAL), 0); if(usr && user) strcpy(user, usr); if(pswd && password) strcpy(password, pswd); } } dbg_msg("Parse rtsp usl: %s\nResult: user=%s,password=%s, host=%s, port=%d, path=%s\n", url, user?user:"", password?password:"", server, *port, file_name); return TRUE; } else { /* try just to extract a file name */ char *token = strtok((char*)url, " \t\n"); if (token) { strcpy(file_name, token); server[0] = '\0'; ret = 0; } } return ret; }
int main( int argc, char **argv ) { char *compdn = NULL, *attrs = NULL; char *sep; int rc; LDAP *ld = NULL; struct berval bvalue = { 0, NULL }; int i = 0; LDAPControl c[1]; tool_init( TOOL_COMPARE ); prog = lutil_progname( "ldapcompare", argc, argv ); tool_args( argc, argv ); if ( argc - optind != 2 ) { usage(); } compdn = argv[optind++]; attrs = argv[optind++]; /* user passed in only 2 args, the last one better be in * the form attr:value or attr::b64value */ sep = strchr(attrs, ':'); if (!sep) { usage(); } *sep++='\0'; if ( *sep != ':' ) { bvalue.bv_val = strdup( sep ); bvalue.bv_len = strlen( bvalue.bv_val ); } else { /* it's base64 encoded. */ bvalue.bv_val = malloc( strlen( &sep[1] )); bvalue.bv_len = lutil_b64_pton( &sep[1], (unsigned char *) bvalue.bv_val, strlen( &sep[1] )); if (bvalue.bv_len == (ber_len_t)-1) { fprintf(stderr, _("base64 decode error\n")); exit(-1); } } ld = tool_conn_setup( 0, 0 ); tool_bind( ld ); if ( 0 #ifdef LDAP_CONTROL_DONTUSECOPY || dontUseCopy #endif ) { #ifdef LDAP_CONTROL_DONTUSECOPY if ( dontUseCopy ) { c[i].ldctl_oid = LDAP_CONTROL_DONTUSECOPY; c[i].ldctl_value.bv_val = NULL; c[i].ldctl_value.bv_len = 0; c[i].ldctl_iscritical = dontUseCopy > 1; i++; } #endif } tool_server_controls( ld, c, i ); if ( verbose ) { fprintf( stderr, _("DN:%s, attr:%s, value:%s\n"), compdn, attrs, sep ); } rc = docompare( ld, compdn, attrs, &bvalue, quiet, NULL, NULL ); free( bvalue.bv_val ); tool_exit( ld, rc ); }
int ExecuteUpdate(PHGlobal *phglobal) { char buffer[1024]; char username[128] = ""; char key[128] = ""; char sendbuffer[256]; char domains[255][255]; char regicommand[255]; int i,len, totaldomains; long challengetime = 0; char *chatid = NULL; char *startid = NULL; char *xmldata = NULL; int buflen = 0; LOG(1) ("ExecuteUpdate Connecting %s.\n",phglobal->szHost); if (!phConnect(phglobal->m_tcpsocket, phglobal->szHost,phglobal->nPort,&phglobal->nAddressIndex,phglobal->szTcpConnectAddress)) { LOG(1) ("ExecuteUpdate errorConnectFailed.\n"); phglobal->nAddressIndex++; return errorConnectFailed; } ////////////////////////////////////////////////////////////////////////// //Recv server hello string memset(buffer, 0, 128); len = phReadOneLine(phglobal->m_tcpsocket, buffer,sizeof(buffer)); if (len <=0 ) { LOG(1) ("ExecuteUpdate Recv server hello string failed.\n"); phClose(&phglobal->m_tcpsocket); phglobal->nAddressIndex++; return errorConnectFailed; } LOG(1) (("SEND AUTH REQUEST COMMAND...")); phSend(phglobal->m_tcpsocket, (char*)COMMAND_AUTH,sizeof(COMMAND_AUTH),0); LOG(1) (("OK.\n")); ////////////////////////////////////////////////////////////////////////// //Recv server key string memset(buffer, 0, 128); len = phReadOneLine(phglobal->m_tcpsocket, buffer,sizeof(buffer)); if (len <=0 ) { LOG(1) (("ExecuteUpdate Recv server key string failed.\n")); phClose(&phglobal->m_tcpsocket); return errorConnectFailed; } LOG(1) (("SERVER SIDE KEY \"%s\" RECEIVED.\n"),buffer); phglobal->nChallengeLen = lutil_b64_pton(buffer+4, (unsigned char *)phglobal->szChallenge, 256); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// //Generate encoded auth string len = GenerateCrypt(phglobal->szUserID, phglobal->szUserPWD, buffer+4, phglobal->clientinfo, phglobal->challengekey, sendbuffer); strcat(sendbuffer, "\r\n"); //Generate ok. ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// //send auth data LOG(1) (("SEND AUTH DATA...")); phSend(phglobal->m_tcpsocket, sendbuffer,strlen(sendbuffer),0); LOG(1) (("OK\n")); memset(buffer, 0, 128); len = phReadOneLine(phglobal->m_tcpsocket, buffer,sizeof(buffer)); buffer[3] = 0; if (len <=0 ) { LOG(1) (("ExecuteUpdate Recv server auth response failed.\n")); phClose(&phglobal->m_tcpsocket); //modified skyvense 2005/10/08, for server db conn lost bug //return errorAuthFailed; return errorConnectFailed; } if (strcmp(buffer,"250")!=0 && strcmp(buffer,"536")!=0) { LOG(1) ("CTcpThread::ExecuteUpdate auth failed.\n"); phClose(&phglobal->m_tcpsocket); if (strstr(buffer + 4, "Busy.") != NULL) return errorAuthBusy; return errorAuthFailed; } if (strcmp(buffer,"536") == 0) //find redirected server address, and let us connect again to new server { char *pos0 = strchr(buffer + 4, '<'); if (pos0) { char *pos1 = strchr(pos0 + 1, '>'); if (pos1) { *pos1 = '\0'; strcpy(phglobal->szHost, pos0 + 1); phClose(&phglobal->m_tcpsocket); return okRedirecting; } } return errorAuthFailed; } if (strcmp(buffer,"250") == 0) //get user type level, 0(free),1(pro),2(biz) { char *pos0 = strchr(buffer + 4, '<'); if (pos0) { char *pos1 = strchr(pos0 + 1, '>'); if (pos1) { *pos1 = '\0'; phglobal->nUserType = atoi(pos0 + 1); } } } ////////////////////////////////////////////////////////////////////////// //list domains for (i=0,totaldomains=0; i<255; i++) { memset(domains[i], 0, 255); phReadOneLine(phglobal->m_tcpsocket, domains[i],255); LOG(1) (("ExecuteUpdate domain \"%s\"\n"),domains[i]); totaldomains++; strcpy(phglobal->szActiveDomains[i],domains[i]); if (domains[i][0] == '.') break; } if (totaldomains<=0) { LOG(1) (("ExecuteUpdate Domain List Failed.\n")); phClose(&phglobal->m_tcpsocket); return errorDomainListFailed; } phglobal->cLastResult = okDomainListed; if (phglobal->cbOnStatusChanged) phglobal->cbOnStatusChanged(phglobal->cLastResult, 0); //::SendMessage(theApp.m_hWndController,WM_DOMAIN_UPDATEMSG,okDomainListed,(long)domains); ////////////////////////////////////////////////////////////////////////// //send domain regi commands list for (i=0;; i++) { if (domains[i][0] == '.') break; memset(regicommand, 0, 128); strcpy(regicommand, COMMAND_REGI); strcat(regicommand, " "); strcat(regicommand, domains[i]); strcat(regicommand, "\r\n"); //printf("%s",regicommand); phSend(phglobal->m_tcpsocket,regicommand,strlen(regicommand),0); } ////////////////////////////////////////////////////////////////////////// //send confirm LOG(1) (("SEND CNFM DATA...")); phSend(phglobal->m_tcpsocket,(char*)COMMAND_CNFM,strlen(COMMAND_CNFM),0); LOG(1) (("OK\n")); for (i=0; i<totaldomains-1; i++) { memset(buffer, 0, 128); len = phReadOneLine(phglobal->m_tcpsocket, buffer,sizeof(buffer)); if (len <= 0) { LOG(1) (("ExecuteUpdate Recv server confirm response failed.\n")); phClose(&phglobal->m_tcpsocket); return errorDomainRegisterFailed; } LOG(1) (("ExecuteUpdate %s\n"),buffer); if (phglobal->cbOnDomainRegistered) phglobal->cbOnDomainRegistered(domains[i]); } memset(buffer, 0, 128); len = phReadOneLine(phglobal->m_tcpsocket, buffer,sizeof(buffer)); if (len <= 0) { LOG(1) (("ExecuteUpdate Recv server confirmed chatID response failed.\n")); phClose(&phglobal->m_tcpsocket); return errorDomainRegisterFailed; } LOG(1) (("%s\n"),buffer); ////////////////////////////////////////////////////////////////////////// //find chatid & startid chatid = buffer + 4; startid = NULL; for (i=4; i<strlen(buffer); i++) { if (buffer[i] == ' ') { buffer[i] = 0; startid = buffer + i + 1; break; } } phglobal->nChatID = atoi(chatid); if (startid) phglobal->nStartID = atoi(startid); LOG(1) (("ExecuteUpdate nChatID:%d, nStartID:%d\n"),phglobal->nChatID,phglobal->nStartID); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// //after confirm domain register, we begin to get user information phSend(phglobal->m_tcpsocket,(void *)COMMAND_STAT_USER,sizeof(COMMAND_STAT_USER),0); memset(buffer, 0, 1024); len = phReadOneLine(phglobal->m_tcpsocket, buffer,sizeof(buffer)); buffer[3] = 0; if (len <= 0 || strcmp(buffer,"250")!=0) { LOG(1) ("CTcpThread::ExecuteUpdate Recv server confirmed stat user response failed.\n"); phClose(&phglobal->m_tcpsocket); return errorStatDetailInfoFailed; } buflen = MAX_PATH; xmldata = (char *)malloc(buflen); memset(xmldata, 0, buflen); for (;;) { memset(buffer, 0, 1024); len = phReadOneLine(phglobal->m_tcpsocket, buffer,1024); if (buffer[0] == '.' || len <= 0) break; if (buflen < strlen(xmldata) + len) { buflen += MAX_PATH; xmldata = realloc(xmldata, buflen); memset((xmldata + buflen) - MAX_PATH, 0, MAX_PATH); } strncat(xmldata, buffer, len); } LOG(1) ("userinfo: \r\n%s\r\n", xmldata); if (phglobal->cbOnUserInfo) phglobal->cbOnUserInfo(xmldata, strlen(xmldata)); free(xmldata); buflen = 0; phSend(phglobal->m_tcpsocket,(void *)COMMAND_STAT_DOM,sizeof(COMMAND_STAT_DOM),0); memset(buffer, 0, 1024); len = phReadOneLine(phglobal->m_tcpsocket, buffer,sizeof(buffer)); buffer[3] = 0; if (len <= 0 || strcmp(buffer,"250")!=0) { LOG(1) ("CTcpThread::ExecuteUpdate Recv server confirmed stat user response failed.\n"); phClose(&phglobal->m_tcpsocket); return errorStatDetailInfoFailed; } buflen = MAX_PATH; xmldata = (char *)malloc(buflen); memset(xmldata, 0, buflen); for (;;) { memset(buffer, 0, 1024); len = phReadOneLine(phglobal->m_tcpsocket, buffer,1024); if (buffer[0] == '.' || len <= 0) break; if (buflen < strlen(xmldata) + len) { buflen += MAX_PATH; xmldata = realloc(xmldata, buflen); memset((xmldata + buflen) - MAX_PATH, 0, MAX_PATH); } strncat(xmldata, buffer, len); } LOG(1) ("domaininfo: \r\n%s\r\n", xmldata); if (phglobal->cbOnAccountDomainInfo) phglobal->cbOnAccountDomainInfo(xmldata, strlen(xmldata)); free(xmldata); buflen = 0; ////////////////////////////////////////////////////////////////////////// //good bye! LOG(1) (("SEND QUIT COMMAND...")); phSend(phglobal->m_tcpsocket,(char*)COMMAND_QUIT,sizeof(COMMAND_QUIT),0); LOG(1) (("OK.\n")); memset(buffer, 0, 128); len = phReadOneLine(phglobal->m_tcpsocket, buffer,sizeof(buffer)); if (len <= 0) { LOG(1) (("ExecuteUpdate Recv server goodbye response failed.\n")); phClose(&phglobal->m_tcpsocket); return okDomainsRegistered; } LOG(1) (("%s\n"),buffer); phClose(&phglobal->m_tcpsocket); return okDomainsRegistered; }
static int pbkdf2_check( const struct berval *scheme, const struct berval *passwd, const struct berval *cred, const char **text) { int rc; int iteration; /* salt_value require PBKDF2_SALT_SIZE + 1 in lutil_b64_pton. */ unsigned char salt_value[PBKDF2_SALT_SIZE + 1]; char salt_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_SALT_SIZE) + 1]; /* dk_value require PBKDF2_MAX_DK_SIZE + 1 in lutil_b64_pton. */ unsigned char dk_value[PBKDF2_MAX_DK_SIZE + 1]; char dk_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_MAX_DK_SIZE) + 1]; unsigned char input_dk_value[PBKDF2_MAX_DK_SIZE]; size_t dk_len; #ifdef HAVE_OPENSSL const EVP_MD *md; #elif HAVE_GNUTLS struct hmac_sha1_ctx sha1_ctx; struct hmac_sha256_ctx sha256_ctx; struct hmac_sha512_ctx sha512_ctx; void * current_ctx = NULL; pbkdf2_hmac_update current_hmac_update = NULL; pbkdf2_hmac_digest current_hmac_digest = NULL; #endif #ifdef SLAPD_PBKDF2_DEBUG printf("Checking for %s\n", scheme->bv_val); printf(" Stored Value:\t%s\n", passwd->bv_val); printf(" Input Cred:\t%s\n", cred->bv_val); #endif #ifdef HAVE_OPENSSL if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ dk_len = PBKDF2_SHA1_DK_SIZE; md = EVP_sha1(); }else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){ dk_len = PBKDF2_SHA1_DK_SIZE; md = EVP_sha1(); }else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){ dk_len = PBKDF2_SHA256_DK_SIZE; md = EVP_sha256(); }else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){ dk_len = PBKDF2_SHA512_DK_SIZE; md = EVP_sha512(); }else{ return LUTIL_PASSWD_ERR; } #elif HAVE_GNUTLS if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ dk_len = PBKDF2_SHA1_DK_SIZE; current_ctx = &sha1_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest; hmac_sha1_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); }else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){ dk_len = PBKDF2_SHA1_DK_SIZE; current_ctx = &sha1_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest; hmac_sha1_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); }else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){ dk_len = PBKDF2_SHA256_DK_SIZE; current_ctx = &sha256_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha256_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha256_digest; hmac_sha256_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); }else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){ dk_len = PBKDF2_SHA512_DK_SIZE; current_ctx = &sha512_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha512_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha512_digest; hmac_sha512_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); }else{ return LUTIL_PASSWD_ERR; } #endif iteration = atoi(passwd->bv_val); if(iteration < 1){ return LUTIL_PASSWD_ERR; } char *ptr; ptr = strchr(passwd->bv_val, '$'); if(!ptr){ return LUTIL_PASSWD_ERR; } ptr++; /* skip '$' */ rc = ab64_to_b64(ptr, salt_b64, sizeof(salt_b64)); if(rc < 0){ return LUTIL_PASSWD_ERR; } ptr = strchr(ptr, '$'); if(!ptr){ return LUTIL_PASSWD_ERR; } ptr++; /* skip '$' */ rc = ab64_to_b64(ptr, dk_b64, sizeof(dk_b64)); if(rc < 0){ return LUTIL_PASSWD_ERR; } /* The targetsize require PBKDF2_SALT_SIZE + 1 in lutil_b64_pton. */ rc = lutil_b64_pton(salt_b64, salt_value, PBKDF2_SALT_SIZE + 1); if(rc < 0){ return LUTIL_PASSWD_ERR; } /* consistency check */ if(rc != PBKDF2_SALT_SIZE){ return LUTIL_PASSWD_ERR; } /* The targetsize require PBKDF2_MAX_DK_SIZE + 1 in lutil_b64_pton. */ rc = lutil_b64_pton(dk_b64, dk_value, sizeof(dk_value)); if(rc < 0){ return LUTIL_PASSWD_ERR; } /* consistency check */ if(rc != dk_len){ return LUTIL_PASSWD_ERR; } #ifdef HAVE_OPENSSL if(!PKCS5_PBKDF2_HMAC(cred->bv_val, cred->bv_len, salt_value, PBKDF2_SALT_SIZE, iteration, md, dk_len, input_dk_value)){ return LUTIL_PASSWD_ERR; } #elif HAVE_GNUTLS PBKDF2(current_ctx, current_hmac_update, current_hmac_digest, dk_len, iteration, PBKDF2_SALT_SIZE, salt_value, dk_len, input_dk_value); #endif rc = memcmp(dk_value, input_dk_value, dk_len); #ifdef SLAPD_PBKDF2_DEBUG printf(" Iteration:\t%d\n", iteration); printf(" Base64 Salt:\t%s\n", salt_b64); printf(" Base64 DK:\t%s\n", dk_b64); int i; printf(" Stored Salt:\t"); for(i=0; i<PBKDF2_SALT_SIZE; i++){ printf("%02x", salt_value[i]); } printf("\n"); printf(" Stored DK:\t"); for(i=0; i<dk_len; i++){ printf("%02x", dk_value[i]); } printf("\n"); printf(" Input DK:\t"); for(i=0; i<dk_len; i++){ printf("%02x", input_dk_value[i]); } printf("\n"); printf(" Result:\t%d\n", rc); #endif return rc?LUTIL_PASSWD_ERR:LUTIL_PASSWD_OK; }
static int pbkdf2_check( const struct berval *scheme, const struct berval *passwd, const struct berval *cred, const char **text) { int rc; int iteration; /* salt_value require PBKDF2_SALT_SIZE + 1 in lutil_b64_pton. */ unsigned char salt_value[PBKDF2_SALT_SIZE + 1]; char salt_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_SALT_SIZE) + 1]; /* dk_value require PBKDF2_DK_SIZE + 1 in lutil_b64_pton. */ unsigned char dk_value[PBKDF2_DK_SIZE + 1]; char dk_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_DK_SIZE) + 1]; unsigned char input_dk_value[PBKDF2_DK_SIZE]; #ifdef SLAPD_PBKDF2_DEBUG printf("DEBUG pbkdf2_check()\n"); printf(" Stored Value:\t%s\n", passwd->bv_val); printf(" Input Cred:\t%s\n", cred->bv_val); #endif iteration = atoi(passwd->bv_val); if(iteration < 1){ return LUTIL_PASSWD_ERR; } char *ptr; ptr = strchr(passwd->bv_val, '$'); if(!ptr){ return LUTIL_PASSWD_ERR; } ptr++; /* skip '$' */ rc = ab64_to_b64(ptr, salt_b64, sizeof(salt_b64)); if(rc < 0){ return LUTIL_PASSWD_ERR; } ptr = strchr(ptr, '$'); if(!ptr){ return LUTIL_PASSWD_ERR; } ptr++; /* skip '$' */ rc = ab64_to_b64(ptr, dk_b64, sizeof(dk_b64)); if(rc < 0){ return LUTIL_PASSWD_ERR; } /* The targetsize require PBKDF2_SALT_SIZE + 1 in lutil_b64_pton. */ rc = lutil_b64_pton(salt_b64, salt_value, PBKDF2_SALT_SIZE + 1); if(rc < 0){ return LUTIL_PASSWD_ERR; } /* consistency check */ if(rc != PBKDF2_SALT_SIZE){ return LUTIL_PASSWD_ERR; } /* The targetsize require PBKDF2_DK_SIZE + 1 in lutil_b64_pton. */ rc = lutil_b64_pton(dk_b64, dk_value, PBKDF2_DK_SIZE + 1); if(rc < 0){ return LUTIL_PASSWD_ERR; } /* consistency check */ if(rc != PBKDF2_DK_SIZE){ return LUTIL_PASSWD_ERR; } if(!PKCS5_PBKDF2_HMAC_SHA1(cred->bv_val, cred->bv_len, salt_value, PBKDF2_SALT_SIZE, iteration, PBKDF2_DK_SIZE, input_dk_value)){ return LUTIL_PASSWD_ERR; } rc = memcmp(dk_value, input_dk_value, PBKDF2_DK_SIZE); #ifdef SLAPD_PBKDF2_DEBUG printf(" Iteration:\t%d\n", iteration); printf(" Base64 Salt:\t%s\n", salt_b64); printf(" Base64 DK:\t%s\n", dk_b64); int i; printf(" Stored Salt:\t"); for(i=0; i<PBKDF2_SALT_SIZE; i++){ printf("%02x", salt_value[i]); } printf("\n"); printf(" Stored DK:\t"); for(i=0; i<PBKDF2_DK_SIZE; i++){ printf("%02x", dk_value[i]); } printf("\n"); printf(" Input DK:\t"); for(i=0; i<PBKDF2_DK_SIZE; i++){ printf("%02x", input_dk_value[i]); } printf("\n"); printf(" Result:\t%d\n", rc); #endif return rc?LUTIL_PASSWD_ERR:LUTIL_PASSWD_OK; }