/** * Delete the private key for a account. */ void OtrConnection::deletePrivateKey(QString account) { OtrlPrivKey* key = otrl_privkey_find(userstate, account.toStdString().c_str(), protocolString); if (key != NULL) { otrl_privkey_forget(key); } //TODO: write changed otr.keys }
void OtrInternal::deleteKey(const QString& account) { OtrlPrivKey* privKey = otrl_privkey_find(m_userstate, account.toUtf8().constData(), OTR_PROTOCOL_STRING); otrl_privkey_forget(privKey); otrl_privkey_write(m_userstate, QFile::encodeName(m_keysFile).constData()); }
gcry_error_t jsapi_privkey_delete(OtrlUserState us, const char *filename, const char *accountname, const char *protocol) { gcry_error_t err = GPG_ERR_NO_ERROR; /* remove key from userstate */ OtrlPrivKey* existing_key = otrl_privkey_find(us,accountname,protocol); if( existing_key ){ otrl_privkey_forget(existing_key); err = jsapi_userstate_write_to_file(us, filename);//write out the changes } return err; }
/* Calculate a raw hash of our DSA public key. Return it in the passed * fingerprint buffer. Return NULL on error, or a pointer to the given * buffer on success. */ unsigned char *otrl_privkey_fingerprint_raw(OtrlUserState us, unsigned char hash[20], const char *accountname, const char *protocol) { OtrlPrivKey *p = otrl_privkey_find(us, accountname, protocol); if (p) { /* Calculate the hash */ gcry_md_hash_buffer(GCRY_MD_SHA1, hash, p->pubkey_data, p->pubkey_datalen); } else { return NULL; } return hash; }
void OtrInternal::startSession(const QString& account, const QString& contact) { m_callback->stateChange(account, contact, psiotr::OTR_STATECHANGE_GOINGSECURE); if (!otrl_privkey_find(m_userstate, account.toUtf8().constData(), OTR_PROTOCOL_STRING)) { create_privkey(account.toUtf8().constData(), OTR_PROTOCOL_STRING); } //TODO: make allowed otr versions configureable char* msg = otrl_proto_default_query_msg(m_callback->humanAccountPublic(account).toUtf8().constData(), OTRL_POLICY_DEFAULT); m_callback->sendMessage(account, contact, QString::fromUtf8(msg)); free(msg); }
/* Calculate a human-readable hash of our DSA public key. Return it in * the passed fingerprint buffer. Return NULL on error, or a pointer to * the given buffer on success. */ char *otrl_privkey_fingerprint(OtrlUserState us, char fingerprint[45], const char *accountname, const char *protocol) { unsigned char hash[20]; OtrlPrivKey *p = otrl_privkey_find(us, accountname, protocol); if (p) { /* Calculate the hash */ gcry_md_hash_buffer(GCRY_MD_SHA1, hash, p->pubkey_data, p->pubkey_datalen); /* Now convert it to a human-readable format */ otrl_privkey_hash_to_human(fingerprint, hash); } else { return NULL; } return fingerprint; }
static INT_PTR CALLBACK DlgProcMirOTROptsProto(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { HWND lv = GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS); int sel; switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); { HWND cmb = GetDlgItem(hwndDlg, IDC_CMB_PROTO_POLICY); SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateT(LANG_POLICY_DEFAULT)); SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateT(LANG_POLICY_ALWAYS)); SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateT(LANG_POLICY_OPP)); SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateT(LANG_POLICY_MANUAL)); SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateT(LANG_POLICY_NEVER)); SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_SETCURSEL, (LPARAM)-1, 0); EnableWindow(GetDlgItem(hwndDlg, IDC_CMB_PROTO_POLICY), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_NEWKEY), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_FORGET), FALSE); } SendMessage(lv, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);// | LVS_EX_CHECKBOXES); { // add list columns LVCOLUMN lvc; // Initialize the LVCOLUMN structure. // The mask specifies that the format, width, text, and // subitem members of the structure are valid. lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.fmt = LVCFMT_LEFT; lvc.iSubItem = 0; lvc.pszText = TranslateT(LANG_PROTO); lvc.cx = 85; // width of column in pixels ListView_InsertColumn(lv, 0, &lvc); lvc.iSubItem = 1; lvc.pszText = TranslateT(LANG_POLICY); lvc.cx = 80; // width of column in pixels ListView_InsertColumn(lv, 1, &lvc); lvc.iSubItem = 2; lvc.pszText = TranslateT(LANG_FINGERPRINT); lvc.cx = 275; // width of column in pixels ListView_InsertColumn(lv, 2, &lvc); } PostMessage(hwndDlg, WMU_REFRESHPROTOLIST, 0, 0); return TRUE; case WMU_REFRESHPROTOLIST: ListView_DeleteAllItems(lv); { LV_ITEM item = { 0 }; int num_protocols; PROTOACCOUNT **pppDesc; Proto_EnumAccounts(&num_protocols, &pppDesc); for (int i = 0; i < num_protocols; i++) { if (!mir_strcmp(pppDesc[i]->szModuleName, META_PROTO)) continue; if ((CallProtoService(pppDesc[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IM) == 0) continue; item.mask = LVIF_TEXT | LVIF_PARAM; item.pszText = pppDesc[i]->tszAccountName; item.lParam = (LPARAM)pppDesc[i]->szModuleName; int ilvItem = ListView_InsertItem(lv, &item); ListView_SetItemText(lv, ilvItem, 1, (TCHAR*)policy_to_string(db_get_dw(0, MODULENAME"_ProtoPol", pppDesc[i]->szModuleName, CONTACT_DEFAULT_POLICY))); char fprint[45]; if (otrl_privkey_fingerprint(otr_user_state, fprint, pppDesc[i]->szModuleName, pppDesc[i]->szModuleName)) { TCHAR *temp = mir_a2t(fprint); ListView_SetItemText(lv, ilvItem, 2, temp); mir_free(temp); } } } return TRUE; case WM_COMMAND: switch (HIWORD(wParam)) { case BN_CLICKED: switch (LOWORD(wParam)) { case IDC_BTN_PROTO_NEWKEY: sel = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS)); if (sel != -1) { PROTOREGENKEYOPTIONS *opts = new PROTOREGENKEYOPTIONS(); opts->refresh = hwndDlg; ListView_GetItemText(GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS), sel, 0, opts->proto, _countof(opts->proto)); CloseHandle((HANDLE)_beginthreadex(0, 0, regen_key_thread, opts, 0, 0)); } break; case IDC_BTN_PROTO_FORGET: sel = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS)); if (sel != -1) { TCHAR buff_proto[128]; ListView_GetItemText(GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS), sel, 0, buff_proto, _countof(buff_proto)); TCHAR buff[512]; mir_sntprintf(buff, TranslateT(LANG_OTR_ASK_REMOVEKEY), buff_proto); if (IDYES == MessageBox(hwndDlg, buff, TranslateT(LANG_OTR_INFO), MB_ICONQUESTION | MB_YESNO)) { char *proto = GetProtoName(lv, sel); if (proto == NULL) break; OtrlPrivKey *key = otrl_privkey_find(otr_user_state, proto, proto); if (key) { otrl_privkey_forget(key); otrl_privkey_write(otr_user_state, _T2A(g_private_key_filename)); ListView_SetItemText(GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS), sel, 2, _T("")); } } } } break; case CBN_SELCHANGE: switch (LOWORD(wParam)) { case IDC_CMB_PROTO_POLICY: int proto = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS)); if (proto == -1) break; int sel = SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_GETCURSEL, 0, 0); if (sel == CB_ERR) break; int len = SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_GETLBTEXTLEN, sel, 0); if (len < 0) break; TCHAR *text = new TCHAR[len + 1]; SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_GETLBTEXT, sel, (LPARAM)text); ListView_SetItemText(GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS), proto, 1, text); delete[] text; SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); } break; } break; case WM_NOTIFY: if (((LPNMHDR)lParam)->code == LVN_ITEMCHANGED && ((LPNMHDR)lParam)->hwndFrom == lv) { LPNMLISTVIEW notif = (LPNMLISTVIEW)lParam; if ((notif->uNewState & LVIS_SELECTED) == 0) break; if (notif->iItem == -1) { SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_SETCURSEL, (LPARAM)-1, 0); EnableWindow(GetDlgItem(hwndDlg, IDC_CMB_PROTO_POLICY), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_NEWKEY), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_FORGET), FALSE); } else { EnableWindow(GetDlgItem(hwndDlg, IDC_CMB_PROTO_POLICY), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_NEWKEY), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_FORGET), TRUE); TCHAR buff[50]; ListView_GetItemText(((LPNMHDR)lParam)->hwndFrom, notif->iItem, 1, buff, _countof(buff)); SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_SELECTSTRING, (LPARAM)-1, (WPARAM)buff); } } else if (((LPNMHDR)lParam)->code == PSN_APPLY) { int cnt = ListView_GetItemCount(lv); TCHAR policy[64]; for (int i = 0; i < cnt; ++i) { char *proto = GetProtoName(lv, i); if (proto == NULL) continue; ListView_GetItemText(lv, i, 1, policy, _countof(policy)); db_set_dw(0, MODULENAME"_ProtoPol", proto, policy_from_string(policy)); } // handle apply return TRUE; } break; } return FALSE; }
void otr_on_connect(ProfAccount *account) { if (jid) { free(jid); } jid = strdup(account->jid); log_info("Loading OTR key for %s", jid); gchar *data_home = xdg_get_data_home(); GString *basedir = g_string_new(data_home); free(data_home); gchar *account_dir = str_replace(jid, "@", "_at_"); g_string_append(basedir, "/profanity/otr/"); g_string_append(basedir, account_dir); g_string_append(basedir, "/"); free(account_dir); if (!mkdir_recursive(basedir->str)) { log_error("Could not create %s for account %s.", basedir->str, jid); cons_show_error("Could not create %s for account %s.", basedir->str, jid); g_string_free(basedir, TRUE); return; } user_state = otrl_userstate_create(); gcry_error_t err = 0; GString *keysfilename = g_string_new(basedir->str); g_string_append(keysfilename, "keys.txt"); if (!g_file_test(keysfilename->str, G_FILE_TEST_IS_REGULAR)) { log_info("No OTR private key file found %s", keysfilename->str); data_loaded = FALSE; } else { log_info("Loading OTR private key %s", keysfilename->str); err = otrl_privkey_read(user_state, keysfilename->str); if (!err == GPG_ERR_NO_ERROR) { log_warning("Failed to read OTR private key file: %s", keysfilename->str); cons_show_error("Failed to read OTR private key file: %s", keysfilename->str); g_string_free(basedir, TRUE); g_string_free(keysfilename, TRUE); return; } OtrlPrivKey* privkey = otrl_privkey_find(user_state, jid, "xmpp"); if (!privkey) { log_warning("No OTR private key found for account \"%s\", protocol \"xmpp\" in file: %s", jid, keysfilename->str); cons_show_error("No OTR private key found for account \"%s\", protocol \"xmpp\" in file: %s", jid, keysfilename->str); g_string_free(basedir, TRUE); g_string_free(keysfilename, TRUE); return; } log_info("Loaded OTR private key"); data_loaded = TRUE; } GString *fpsfilename = g_string_new(basedir->str); g_string_append(fpsfilename, "fingerprints.txt"); if (!g_file_test(fpsfilename->str, G_FILE_TEST_IS_REGULAR)) { log_info("No OTR fingerprints file found %s", fpsfilename->str); data_loaded = FALSE; } else { log_info("Loading OTR fingerprints %s", fpsfilename->str); err = otrl_privkey_read_fingerprints(user_state, fpsfilename->str, NULL, NULL); if (!err == GPG_ERR_NO_ERROR) { log_error("Failed to load OTR fingerprints file: %s", fpsfilename->str); g_string_free(basedir, TRUE); g_string_free(keysfilename, TRUE); g_string_free(fpsfilename, TRUE); return; } else { log_info("Loaded OTR fingerprints"); data_loaded = TRUE; } } if (data_loaded) { cons_show("Loaded OTR private key for %s", jid); } g_string_free(basedir, TRUE); g_string_free(keysfilename, TRUE); g_string_free(fpsfilename, TRUE); return; }
void OtrInternal::deleteKey(QString account, QString protocol) { otrl_privkey_forget(otrl_privkey_find(m_userstate,account.toLocal8Bit().data(),protocol.toLocal8Bit().data())); }
gcry_error_t jsapi_userstate_import_privkey(OtrlUserState us, char *accountname, char * protocol, gcry_mpi_t p, gcry_mpi_t q, gcry_mpi_t g, gcry_mpi_t y, gcry_mpi_t x){ size_t *erroff; const char *token; size_t tokenlen; gcry_error_t err; gcry_sexp_t allkeys; size_t i; //puts("jsapi_userstate_import_privkey: building sexp"); err = gcry_sexp_build(&allkeys,erroff,"(privkeys (account (name %s) (protocol %s) (private-key (dsa \ (p %M) (q %M) (g %M) (y %M) (x %M) ))))",accountname,protocol,p,q,g,y,x); if(err) return err; /* forget existing account/key */ OtrlPrivKey* existing_key = otrl_privkey_find(us,accountname,protocol); if( existing_key) otrl_privkey_forget(existing_key); //puts("getting allkeys from sexp"); token = gcry_sexp_nth_data(allkeys, 0, &tokenlen); if (tokenlen != 8 || strncmp(token, "privkeys", 8)) { gcry_sexp_release(allkeys); return gcry_error(GPG_ERR_UNUSABLE_SECKEY); } /* Get each account */ for(i=1; i<gcry_sexp_length(allkeys); ++i) { gcry_sexp_t names, protos, privs; char *name, *proto; gcry_sexp_t accounts; OtrlPrivKey *p; //printf("reading account #:%d\n",i); /* Get the ith "account" S-exp */ accounts = gcry_sexp_nth(allkeys, i); /* It's really an "account" S-exp? */ token = gcry_sexp_nth_data(accounts, 0, &tokenlen); if (tokenlen != 7 || strncmp(token, "account", 7)) { gcry_sexp_release(accounts); gcry_sexp_release(allkeys); return gcry_error(GPG_ERR_UNUSABLE_SECKEY); } /* Extract the name, protocol, and privkey S-exps */ names = gcry_sexp_find_token(accounts, "name", 0); protos = gcry_sexp_find_token(accounts, "protocol", 0); privs = gcry_sexp_find_token(accounts, "private-key", 0); gcry_sexp_release(accounts); if (!names || !protos || !privs) { gcry_sexp_release(names); gcry_sexp_release(protos); gcry_sexp_release(privs); gcry_sexp_release(allkeys); return gcry_error(GPG_ERR_UNUSABLE_SECKEY); } /* Extract the actual name and protocol */ token = gcry_sexp_nth_data(names, 1, &tokenlen); if (!token) { gcry_sexp_release(names); gcry_sexp_release(protos); gcry_sexp_release(privs); gcry_sexp_release(allkeys); return gcry_error(GPG_ERR_UNUSABLE_SECKEY); } name = malloc(tokenlen + 1); if (!name) { gcry_sexp_release(names); gcry_sexp_release(protos); gcry_sexp_release(privs); gcry_sexp_release(allkeys); return gcry_error(GPG_ERR_ENOMEM); } memmove(name, token, tokenlen); name[tokenlen] = '\0'; gcry_sexp_release(names); token = gcry_sexp_nth_data(protos, 1, &tokenlen); if (!token) { free(name); gcry_sexp_release(protos); gcry_sexp_release(privs); gcry_sexp_release(allkeys); return gcry_error(GPG_ERR_UNUSABLE_SECKEY); } proto = malloc(tokenlen + 1); if (!proto) { free(name); gcry_sexp_release(protos); gcry_sexp_release(privs); gcry_sexp_release(allkeys); return gcry_error(GPG_ERR_ENOMEM); } memmove(proto, token, tokenlen); proto[tokenlen] = '\0'; gcry_sexp_release(protos); /* Make a new OtrlPrivKey entry */ p = malloc(sizeof(*p)); if (!p) { free(name); free(proto); gcry_sexp_release(privs); gcry_sexp_release(allkeys); return gcry_error(GPG_ERR_ENOMEM); } /* Fill it in and link it up */ p->accountname = name; p->protocol = proto; p->pubkey_type = OTRL_PUBKEY_TYPE_DSA; p->privkey = privs; p->next = us->privkey_root; if (p->next) { p->next->tous = &(p->next); } p->tous = &(us->privkey_root); us->privkey_root = p; err = jsapi_make_pubkey(&(p->pubkey_data), &(p->pubkey_datalen), p->privkey); if (err) { gcry_sexp_release(allkeys); otrl_privkey_forget(p); return gcry_error(GPG_ERR_UNUSABLE_SECKEY); } } gcry_sexp_release(allkeys); /* application should write out userstate to disk */ return gcry_error(GPG_ERR_NO_ERROR); }