void calculate_password_key_and_hash(const char *a_password, char *a_key, char *a_hash) { char key[256 / 8]; char hash[256 / 8]; key_from_password(a_password, key); htob64(key, a_key, 32); key_hash(key, hash); htob64(hash, a_hash, 32); }
// Input: priv_key = buffer of 200 bytes // pub_key = buffer of 200 bytes // Output: priv_key = Your private key // pub_key = Your public key int DH1080_gen(char *priv_key, char *pub_key) { unsigned char raw_buf[256]; //, iniHash[33]; //unsigned long seed; int iRet, i; size_t len; mpz_t b_privkey, b_pubkey, b_base; unsigned char temp[DH1080_PRIME_BYTES]; //FILE *hRnd; priv_key[0]='0'; priv_key[1]='\0'; pub_key[0]='0'; pub_key[1]='\0'; mpz_init(b_privkey); mpz_init(b_pubkey); mpz_init_set_ui(b_base, 2); do { for(i=0; i < DH1080_PRIME_BYTES; i++) temp[i] = (unsigned char)rand(&csprng); mpz_import(b_privkey, DH1080_PRIME_BYTES, 1, 1, 0, 0, temp); mpz_mod(b_privkey, b_privkey, b_prime1080); /* [2, prime1080-1] */ } while( mpz_cmp_ui(b_privkey, 1) != 1); /* while smaller than 2 */ mpz_powm(b_pubkey, b_base, b_privkey, b_prime1080); if(DH_verifyPubKey(b_pubkey)) { mpz_export(raw_buf, &len, 1, 1, 0, 0, b_privkey); mpz_clear(b_privkey); htob64((char *)raw_buf, priv_key, len); mpz_export(raw_buf, &len, 1, 1, 0, 0, b_pubkey); htob64((char *)raw_buf, pub_key, len); iRet=1; } else iRet=0; ZeroMemory(raw_buf, sizeof(raw_buf)); mpz_clear(b_pubkey); mpz_clear(b_base); return iRet; }
// Input: MyPrivKey = Your private key // HisPubKey = Someones public key // Output: MyPrivKey has been destroyed for security reasons // HisPubKey = the secret key int DH1080_comp(char *MyPrivKey, char *HisPubKey) { //int i=0; int iRet; unsigned char SHA256digest[35], base64_tmp[160]; mpz_t b_myPrivkey, b_HisPubkey, b_theKey; size_t len; // Verify base64 strings if((strspn(MyPrivKey, B64ABC) != strlen(MyPrivKey)) || (strspn(HisPubKey, B64ABC) != strlen(HisPubKey))) { memset(MyPrivKey, 0x20, strlen(MyPrivKey)); memset(HisPubKey, 0x20, strlen(HisPubKey)); return 0; } mpz_init(b_HisPubkey); mpz_init(b_theKey); len=b64toh(HisPubKey, (char *)base64_tmp); mpz_import(b_HisPubkey, len, 1, 1, 0, 0, base64_tmp); if(DH_verifyPubKey(b_HisPubkey)) { mpz_init(b_myPrivkey); len=b64toh(MyPrivKey, (char *)base64_tmp); mpz_import(b_myPrivkey, len, 1, 1, 0, 0, base64_tmp); memset(MyPrivKey, 0x20, strlen(MyPrivKey)); mpz_powm(b_theKey, b_HisPubkey, b_myPrivkey, b_prime1080); mpz_clear(b_myPrivkey); mpz_export(base64_tmp, &len, 1, 1, 0, 0, b_theKey); SHA256_memory((char *)base64_tmp, len, (char *)SHA256digest); htob64((char *)SHA256digest, HisPubKey, 32); iRet=1; } else iRet=0; ZeroMemory(base64_tmp, sizeof(base64_tmp)); ZeroMemory(SHA256digest, sizeof(SHA256digest)); mpz_clear(b_theKey); mpz_clear(b_HisPubkey); return iRet; }
// Input: MyPrivKey = Your private key // HisPubKey = Someones public key // Output: MyPrivKey has been destroyed for security reasons // HisPubKey = the secret key int DH1080_comp(char *MyPrivKey, char *HisPubKey) { int i=0, len, iRet; unsigned char SHA256digest[35], base64_tmp[160]; big b_myPrivkey, b_HisPubkey, b_theKey; // Verify base64 strings if((strspn(MyPrivKey, B64ABC) != strlen(MyPrivKey)) || (strspn(HisPubKey, B64ABC) != strlen(HisPubKey))) { memset(MyPrivKey, 0x20, strlen(MyPrivKey)); memset(HisPubKey, 0x20, strlen(HisPubKey)); return 0; } b_HisPubkey=mirvar(0); b_theKey=mirvar(0); len=b64toh(HisPubKey, base64_tmp); bytes_to_big(len, base64_tmp, b_HisPubkey); if(DH_verifyPubKey(b_HisPubkey)) { b_myPrivkey=mirvar(0); len=b64toh(MyPrivKey, base64_tmp); bytes_to_big(len, base64_tmp, b_myPrivkey); memset(MyPrivKey, 0x20, strlen(MyPrivKey)); powmod(b_HisPubkey, b_myPrivkey, b_prime1080, b_theKey); mirkill(b_myPrivkey); len=big_to_bytes(sizeof(base64_tmp), b_theKey, base64_tmp, FALSE); SHA256_memory(base64_tmp, len, SHA256digest); htob64(SHA256digest, HisPubKey, 32); iRet=1; } else iRet=0; ZeroMemory(base64_tmp, sizeof(base64_tmp)); ZeroMemory(SHA256digest, sizeof(SHA256digest)); mirkill(b_theKey); mirkill(b_HisPubkey); return iRet; }
void cmd_setinipw(const char *iniPW, SERVER_REC * server, WI_ITEM_REC * item) { int pw_len, re_enc = 0; char B64digest[50] = { '\0' }; char key[32] = { '\0' }; char hash[32] = { '\0' }; char new_iniKey[KEYBUF_SIZE], old_iniKey[KEYBUF_SIZE], iniPath_new[300]; strcpy(old_iniKey, iniKey); if (iniPW != NULL) { pw_len = strlen(iniPW); if (pw_len < 1 || (size_t) pw_len > sizeof(new_iniKey)) { printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH:\002 No parameters. Usage: /setinipw <sekure_blow.ini_password>"); return; } if (strfcpy(new_iniKey, (char *)iniPW, sizeof(new_iniKey)) == NULL) return; ZeroMemory(iniPW, pw_len); pw_len = strlen(new_iniKey); if (pw_len < 8) { printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH:\002 Password too short, at least 8 characters needed! Usage: /setinipw <sekure_blow.ini_password>"); return; } key_from_password(new_iniKey, key); htob64(key, B64digest, 32); ZeroMemory(new_iniKey, sizeof(new_iniKey)); strcpy(iniKey, B64digest); // this is used for encrypting blow.ini } else { strcpy(iniKey, default_iniKey); // use default blow.ini key } key_hash(key, hash); htob64(hash, B64digest, 32); // this is used to verify the entered password ZeroMemory(hash, sizeof(hash)); ZeroMemory(key, sizeof(key)); // re-encrypt blow.ini with new password strcpy(iniPath_new, iniPath); strcat(iniPath_new, "_new"); re_enc = recrypt_ini_file(iniPath, iniPath_new, old_iniKey); if (re_enc < 0) { ZeroMemory(B64digest, sizeof(B64digest)); ZeroMemory(old_iniKey, sizeof(old_iniKey)); printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH ERROR:\002 Unable to write new blow.ini, probably out of disc space."); return; } else { ZeroMemory(old_iniKey, sizeof(old_iniKey)); } if (setIniValue("FiSH", "ini_password_Hash", B64digest, iniPath) == -1) { ZeroMemory(B64digest, sizeof(B64digest)); printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH ERROR:\002 Unable to write to blow.ini, probably out of space or permission denied."); return; } ZeroMemory(B64digest, sizeof(B64digest)); if (re_enc) { printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH: Re-encrypted blow.ini\002 with new password."); } if (iniPW != NULL) { printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH:\002 blow.ini password hash saved."); } }
void fish_init(void) { char iniPasswordHash[50], SHA256digest[35], B64digest[50], *iniPass_ptr; int i; strcpy(iniPath, get_irssi_config()); // path to irssi config file strcpy(tempPath, iniPath); strcpy(strrchr(iniPath, '/'), blow_ini); strcpy(strrchr(tempPath, '/'), "/temp_FiSH.$$$"); if (DH1080_Init()==FALSE) return; GetPrivateProfileString("FiSH", "ini_password_Hash", "0", iniPasswordHash, sizeof(iniPasswordHash), iniPath); if (strlen(iniPasswordHash) == 43) { iniPass_ptr = getpass(" --> Please enter your blow.ini password: "******"\002FiSH:\002 Wrong blow.ini password entered, try again..."); printtext(NULL, NULL, MSGLEVEL_CRAP, "\002FiSH module NOT loaded.\002"); return; } printtext(NULL, NULL, MSGLEVEL_CRAP, "\002FiSH:\002 Correct blow.ini password entered, lets go!"); } else { strcpy(iniKey, default_iniKey); printtext(NULL, NULL, MSGLEVEL_CRAP, "\002FiSH:\002 Using default password to decrypt blow.ini... Try /setinipw to set a custom password."); } signal_add_first("server sendmsg", (SIGNAL_FUNC) encrypt_msg); signal_add_first("message private", (SIGNAL_FUNC) decrypt_msg); signal_add_first("message public", (SIGNAL_FUNC) decrypt_msg); signal_add_first("message irc notice", (SIGNAL_FUNC) decrypt_notice); signal_add_first("message irc action", (SIGNAL_FUNC) decrypt_action); signal_add_first("message own_private", (SIGNAL_FUNC) format_msg); signal_add_first("message own_public", (SIGNAL_FUNC) format_msg); signal_add_first("channel topic changed", (SIGNAL_FUNC) decrypt_changed_topic); signal_add_first("message topic", (SIGNAL_FUNC) decrypt_topic); signal_add_first("server incoming", (SIGNAL_FUNC) raw_handler); signal_add("query created", (SIGNAL_FUNC) do_auto_keyx); signal_add("query nick changed", (SIGNAL_FUNC) query_nick_changed); command_bind("topic+", NULL, (SIGNAL_FUNC) cmd_crypt_TOPIC); command_bind("notice+", NULL, (SIGNAL_FUNC) cmd_crypt_notice); command_bind("notfish", NULL, (SIGNAL_FUNC) cmd_crypt_notice); command_bind("me+", NULL, (SIGNAL_FUNC) cmd_crypt_action); command_bind("setkey", NULL, (SIGNAL_FUNC) cmd_setkey); command_bind("delkey", NULL, (SIGNAL_FUNC) cmd_delkey); command_bind("key", NULL, (SIGNAL_FUNC) cmd_key); command_bind("showkey", NULL, (SIGNAL_FUNC) cmd_key); command_bind("keyx", NULL, (SIGNAL_FUNC) cmd_keyx); command_bind("setinipw", NULL, (SIGNAL_FUNC) cmd_setinipw); command_bind("unsetinipw", NULL, (SIGNAL_FUNC) cmd_unsetinipw); command_bind("fishhelp", NULL, (SIGNAL_FUNC) cmd_helpfish); command_bind("helpfish", NULL, (SIGNAL_FUNC) cmd_helpfish); printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, "FiSH v1.00 - encryption module for irssi loaded! URL: https://github.com/falsovsky/FiSH-irssi\n" "Try /helpfish or /fishhelp for a short command overview"); module_register("fish", "core"); }
void cmd_setinipw(const char *iniPW, SERVER_REC *server, WI_ITEM_REC *item) { int i=0, pw_len, re_enc=0; char B64digest[50], SHA256digest[35]; char bfKey[512], new_iniKey[KEYBUF_SIZE], old_iniKey[KEYBUF_SIZE], *fptr, *ok_ptr, line_buf[1000], iniPath_new[300]; FILE *h_ini, *h_ini_new; if (!unsetiniFlag) { pw_len=strlen(iniPW); if (pw_len < 1 || (size_t)pw_len > sizeof(new_iniKey)) { printtext(server, item!=NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH:\002 No parameters. Usage: /setinipw <sekure_blow.ini_password>"); return; } if (strfcpy(new_iniKey, (char *)iniPW, sizeof(new_iniKey))==NULL) return; ZeroMemory(iniPW, pw_len); pw_len=strlen(new_iniKey); if (pw_len < 8) { printtext(server, item!=NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH:\002 Password too short, at least 8 characters needed! Usage: /setinipw <sekure_blow.ini_password>"); return; } SHA256_memory(new_iniKey, pw_len, SHA256digest); ZeroMemory(new_iniKey, sizeof(new_iniKey)); for (i=0; i<40872; i++) SHA256_memory(SHA256digest, 32, SHA256digest); htob64(SHA256digest, B64digest, 32); } strcpy(old_iniKey, iniKey); if (unsetiniFlag) strcpy(iniKey, default_iniKey); // unsetinipw -> use default blow.ini key else strcpy(iniKey, B64digest); // this is used for encrypting blow.ini for (i=0; i<30752; i++) SHA256_memory(SHA256digest, 32, SHA256digest); htob64(SHA256digest, B64digest, 32); // this is used to verify the entered password ZeroMemory(SHA256digest, sizeof(SHA256digest)); // re-encrypt blow.ini with new password strcpy(iniPath_new, iniPath); strcat(iniPath_new, "_new"); h_ini_new=fopen(iniPath_new, "w"); h_ini=fopen(iniPath,"r"); if (h_ini && h_ini_new) { while (!feof(h_ini)) { fptr=fgets(line_buf, sizeof(line_buf)-2, h_ini); if (fptr) { ok_ptr=strstr(line_buf, "+OK "); if (ok_ptr) { re_enc=1; strtok(ok_ptr+4, " \n\r"); decrypt_string(old_iniKey, ok_ptr+4, bfKey, strlen(ok_ptr+4)); ZeroMemory(ok_ptr+4, strlen(ok_ptr+4)+1); encrypt_string(iniKey, bfKey, ok_ptr+4, strlen(bfKey)); strcat(line_buf, "\n"); } if (fprintf(h_ini_new, "%s", line_buf) < 0) { ZeroMemory(B64digest, sizeof(B64digest)); ZeroMemory(bfKey, sizeof(bfKey)); ZeroMemory(line_buf, sizeof(line_buf)); ZeroMemory(old_iniKey, sizeof(old_iniKey)); fclose(h_ini); fclose(h_ini_new); remove(iniPath_new); printtext(server, item!=NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH ERROR:\002 Unable to write new blow.ini, probably out of disc space."); return; } } } ZeroMemory(bfKey, sizeof(bfKey)); ZeroMemory(line_buf, sizeof(line_buf)); ZeroMemory(old_iniKey, sizeof(old_iniKey)); fclose(h_ini); fclose(h_ini_new); remove(iniPath); rename(iniPath_new, iniPath); } else return; if (WritePrivateProfileString("FiSH", "ini_password_Hash", B64digest, iniPath) == -1) { ZeroMemory(B64digest, sizeof(B64digest)); printtext(server, item!=NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH ERROR:\002 Unable to write to blow.ini, probably out of space or permission denied."); return; } ZeroMemory(B64digest, sizeof(B64digest)); if (re_enc) printtext(server, item!=NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH: Re-encrypted blow.ini\002 with new password."); if (!unsetiniFlag) printtext(server, item!=NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH:\002 blow.ini password hash saved."); }
// Input: priv_key = buffer of 200 bytes // pub_key = buffer of 200 bytes // Output: priv_key = Your private key // pub_key = Your public key int DH1080_gen(char *priv_key, char *pub_key) { unsigned char raw_buf[160], iniHash[33]; unsigned long seed; int len, iRet; big b_privkey, b_pubkey; csprng myRNG; FILE *hRnd; priv_key[0]='0'; priv_key[1]='\0'; pub_key[0]='0'; pub_key[1]='\0'; hRnd = fopen("/dev/urandom", "r"); // don't use /dev/random, it's a blocking device if(!hRnd) return 0; b_privkey=mirvar(0); b_pubkey=mirvar(0); // #*#*#*#*#* RNG START #*#*#*#*#* time((time_t *)&seed); seed ^= (long)hRnd << 16; if(fread(raw_buf, 1, sizeof(raw_buf), hRnd) < 32) { ZeroMemory(raw_buf, sizeof(raw_buf)); fclose(hRnd); mirkill(b_privkey); mirkill(b_pubkey); return 0; } fclose(hRnd); sha_file(iniPath, iniHash); memXOR(raw_buf+128, iniHash, 32); sha_file((unsigned char *)get_irssi_config(), iniHash); memXOR(raw_buf+128, iniHash, 32); ZeroMemory(iniHash, sizeof(iniHash)); // first 128 byte in raw_buf: output from /dev/urandom // last 32 byte in raw_buf: SHA-256 digest from blow.ini and irssi.conf seed *= (unsigned long)mip; strong_init(&myRNG, sizeof(raw_buf), raw_buf, (unsigned int)seed); strong_rng(&myRNG); strong_bigdig(&myRNG, 1080, 2, b_privkey); strong_kill(&myRNG); seed=0; // #*#*#*#*#* RNG END #*#*#*#*#* powltr(2, b_privkey, b_prime1080, b_pubkey); if(DH_verifyPubKey(b_pubkey)) { len=big_to_bytes(sizeof(raw_buf), b_privkey, raw_buf, FALSE); htob64(raw_buf, priv_key, len); len=big_to_bytes(sizeof(raw_buf), b_pubkey, raw_buf, FALSE); htob64(raw_buf, pub_key, len); iRet=1; } else iRet=0; ZeroMemory(raw_buf, sizeof(raw_buf)); mirkill(b_privkey); mirkill(b_pubkey); return iRet; }