aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoriNPUTmice <daniel@gultsch.de>2014-11-16 00:20:20 +0100
committeriNPUTmice <daniel@gultsch.de>2014-11-16 00:20:20 +0100
commit88c3537b6869996098da25954985fcb0c6971635 (patch)
tree07e407896b951de710ec9027468d98022ae40241
parent0fb1772f18e71755ce72a97f18ea2c28cc771aba (diff)
parse otr-fingerprint in qr codes and nfc. include otr fingerprint in shareable uri where ever possible
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Account.java45
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Contact.java35
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Conversation.java6
-rw-r--r--src/main/java/eu/siacs/conversations/parser/MessageParser.java6
-rw-r--r--src/main/java/eu/siacs/conversations/services/XmppConnectionService.java15
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java6
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationActivity.java2
-rw-r--r--src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java8
-rw-r--r--src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java51
-rw-r--r--src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java5
-rw-r--r--src/main/java/eu/siacs/conversations/utils/CryptoHelper.java9
11 files changed, 119 insertions, 69 deletions
diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java
index 10f2940c..1d0a025f 100644
--- a/src/main/java/eu/siacs/conversations/entities/Account.java
+++ b/src/main/java/eu/siacs/conversations/entities/Account.java
@@ -280,10 +280,11 @@ public class Account extends AbstractEntity {
return values;
}
- public OtrEngine getOtrEngine(XmppConnectionService context) {
- if (otrEngine == null) {
- otrEngine = new OtrEngine(context, this);
- }
+ public void initOtrEngine(XmppConnectionService context) {
+ this.otrEngine = new OtrEngine(context, this);
+ }
+
+ public OtrEngine getOtrEngine() {
return this.otrEngine;
}
@@ -298,23 +299,21 @@ public class Account extends AbstractEntity {
public String getOtrFingerprint() {
if (this.otrFingerprint == null) {
try {
- DSAPublicKey pubkey = (DSAPublicKey) this.otrEngine
- .getPublicKey();
- if (pubkey == null) {
+ if (this.otrEngine == null) {
return null;
}
- StringBuilder builder = new StringBuilder(
- new OtrCryptoEngineImpl().getFingerprint(pubkey));
- builder.insert(8, " ");
- builder.insert(17, " ");
- builder.insert(26, " ");
- builder.insert(35, " ");
- this.otrFingerprint = builder.toString();
+ DSAPublicKey publicKey = (DSAPublicKey) this.otrEngine.getPublicKey();
+ if (publicKey == null) {
+ return null;
+ }
+ this.otrFingerprint = new OtrCryptoEngineImpl().getFingerprint(publicKey);
+ return this.otrFingerprint;
} catch (final OtrCryptoException ignored) {
-
+ return null;
}
+ } else {
+ return this.otrFingerprint;
}
- return this.otrFingerprint;
}
public String getRosterVersion() {
@@ -329,11 +328,6 @@ public class Account extends AbstractEntity {
this.rosterVersion = version;
}
- public String getOtrFingerprint(XmppConnectionService service) {
- this.getOtrEngine(service);
- return this.getOtrFingerprint();
- }
-
public void updatePresence(String resource, int status) {
this.presences.updatePresence(resource, status);
}
@@ -411,4 +405,13 @@ public class Account extends AbstractEntity {
public boolean inGracePeriod() {
return SystemClock.elapsedRealtime() < this.mEndGracePeriod;
}
+
+ public String getShareableUri() {
+ String fingerprint = this.getOtrFingerprint();
+ if (fingerprint != null) {
+ return "xmpp:" + this.getJid().toBareJid().toString() + "?otr-fingerprint="+fingerprint;
+ } else {
+ return "xmpp:" + this.getJid().toBareJid().toString();
+ }
+ }
}
diff --git a/src/main/java/eu/siacs/conversations/entities/Contact.java b/src/main/java/eu/siacs/conversations/entities/Contact.java
index 9a827f85..32e4601d 100644
--- a/src/main/java/eu/siacs/conversations/entities/Contact.java
+++ b/src/main/java/eu/siacs/conversations/entities/Contact.java
@@ -7,6 +7,7 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
@@ -206,24 +207,26 @@ public class Contact implements ListItem {
return systemAccount;
}
- public Set<String> getOtrFingerprints() {
- Set<String> set = new HashSet<>();
+ public ArrayList<String> getOtrFingerprints() {
+ ArrayList<String> fingerprints = new ArrayList<String>();
try {
if (this.keys.has("otr_fingerprints")) {
- JSONArray fingerprints = this.keys
+ JSONArray prints = this.keys
.getJSONArray("otr_fingerprints");
- for (int i = 0; i < fingerprints.length(); ++i) {
- set.add(fingerprints.getString(i));
+ for (int i = 0; i < prints.length(); ++i) {
+ fingerprints.add(prints.getString(i));
}
}
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ } catch (final JSONException ignored) {
+
}
- return set;
+ return fingerprints;
}
- public void addOtrFingerprint(String print) {
+ public boolean addOtrFingerprint(String print) {
+ if (getOtrFingerprints().contains(print)) {
+ return false;
+ }
try {
JSONArray fingerprints;
if (!this.keys.has("otr_fingerprints")) {
@@ -234,8 +237,9 @@ public class Contact implements ListItem {
}
fingerprints.put(print);
this.keys.put("otr_fingerprints", fingerprints);
+ return true;
} catch (final JSONException ignored) {
-
+ return false;
}
}
@@ -396,4 +400,13 @@ public class Contact implements ListItem {
public boolean trusted() {
return getOption(Options.FROM) && getOption(Options.TO);
}
+
+ public String getShareableUri() {
+ if (getOtrFingerprints().size() >= 1) {
+ String otr = getOtrFingerprints().get(0);
+ return "xmpp:"+getJid().toBareJid().toString()+"?otr-fingerprint="+otr.replace(" ","");
+ } else {
+ return "xmpp:"+getJid().toBareJid().toString();
+ }
+ }
}
diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java
index a9f4c0f1..b1df7ec7 100644
--- a/src/main/java/eu/siacs/conversations/entities/Conversation.java
+++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java
@@ -240,16 +240,14 @@ public class Conversation extends AbstractEntity {
this.mode = mode;
}
- public SessionImpl startOtrSession(XmppConnectionService service,
- String presence, boolean sendStart) {
+ public SessionImpl startOtrSession(String presence, boolean sendStart) {
if (this.otrSession != null) {
return this.otrSession;
} else {
final SessionID sessionId = new SessionID(this.getContactJid().toBareJid().toString(),
presence,
"xmpp");
- this.otrSession = new SessionImpl(sessionId, getAccount()
- .getOtrEngine(service));
+ this.otrSession = new SessionImpl(sessionId, getAccount().getOtrEngine());
try {
if (sendStart) {
this.otrSession.startSession();
diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
index bc2db87f..b7aef931 100644
--- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java
+++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
@@ -76,8 +76,7 @@ public class MessageParser extends AbstractParser implements
}
if (!conversation.hasValidOtrSession()) {
if (properlyAddressed) {
- conversation.startOtrSession(mXmppConnectionService, presence,
- false);
+ conversation.startOtrSession(presence,false);
} else {
return null;
}
@@ -87,8 +86,7 @@ public class MessageParser extends AbstractParser implements
if (!foreignPresence.equals(presence)) {
conversation.endOtrIfNeeded();
if (properlyAddressed) {
- conversation.startOtrSession(mXmppConnectionService,
- presence, false);
+ conversation.startOtrSession(presence, false);
} else {
return null;
}
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index 0c5dfd96..509030c6 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -491,6 +491,7 @@ public class XmppConnectionService extends Service {
this.accounts = databaseBackend.getAccounts();
for (Account account : this.accounts) {
+ account.initOtrEngine(this);
this.databaseBackend.readRoster(account.getRoster());
}
this.mergePhoneContactsWithRoster();
@@ -608,8 +609,7 @@ public class XmppConnectionService extends Service {
if (message.getCounterpart() != null) {
if (message.getEncryption() == Message.ENCRYPTION_OTR) {
if (!conv.hasValidOtrSession()) {
- conv.startOtrSession(this, message.getCounterpart().getResourcepart(),
- true);
+ conv.startOtrSession(message.getCounterpart().getResourcepart(),true);
message.setStatus(Message.STATUS_WAITING);
} else if (conv.hasValidOtrSession()
&& conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) {
@@ -628,7 +628,7 @@ public class XmppConnectionService extends Service {
} else {
if (message.getEncryption() == Message.ENCRYPTION_OTR) {
if (!conv.hasValidOtrSession() && (message.getCounterpart() != null)) {
- conv.startOtrSession(this, message.getCounterpart().getResourcepart(), true);
+ conv.startOtrSession(message.getCounterpart().getResourcepart(), true);
message.setStatus(Message.STATUS_WAITING);
} else if (conv.hasValidOtrSession()) {
if (conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) {
@@ -672,7 +672,7 @@ public class XmppConnectionService extends Service {
} else if (message.getEncryption() == Message.ENCRYPTION_OTR) {
if (!conv.hasValidOtrSession()
&& message.getCounterpart() != null) {
- conv.startOtrSession(this, message.getCounterpart().getResourcepart(), false);
+ conv.startOtrSession(message.getCounterpart().getResourcepart(), false);
}
}
}
@@ -709,13 +709,11 @@ public class XmppConnectionService extends Service {
if (!message.getConversation().hasValidOtrSession()) {
if ((message.getCounterpart() != null)
&& (presences.has(message.getCounterpart().getResourcepart()))) {
- message.getConversation().startOtrSession(this,
- message.getCounterpart().getResourcepart(), true);
+ message.getConversation().startOtrSession(message.getCounterpart().getResourcepart(), true);
} else {
if (presences.size() == 1) {
String presence = presences.asStringArray()[0];
- message.getConversation().startOtrSession(this,
- presence, true);
+ message.getConversation().startOtrSession(presence, true);
}
}
} else {
@@ -1061,6 +1059,7 @@ public class XmppConnectionService extends Service {
}
public void createAccount(Account account) {
+ account.initOtrEngine(this);
databaseBackend.createAccount(account);
this.accounts.add(account);
this.reconnectAccount(account, false);
diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java
index 96fb7b61..788244e3 100644
--- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java
@@ -154,7 +154,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
@Override
protected String getShareableUri() {
if (contact != null) {
- return "xmpp:" + contact.getJid();
+ return contact.getShareableUri();
} else {
return "";
}
@@ -326,10 +326,8 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
keys.removeAllViews();
boolean hasKeys = false;
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- for (Iterator<String> iterator = contact.getOtrFingerprints()
- .iterator(); iterator.hasNext(); ) {
+ for(final String otrFingerprint : contact.getOtrFingerprints()) {
hasKeys = true;
- final String otrFingerprint = iterator.next();
View view = inflater.inflate(R.layout.contact_key, keys, false);
TextView key = (TextView) view.findViewById(R.id.key);
TextView keyType = (TextView) view.findViewById(R.id.key_type);
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
index 7e28cc6c..5dccde18 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
@@ -108,7 +108,7 @@ public class ConversationActivity extends XmppActivity implements
protected String getShareableUri() {
Conversation conversation = getSelectedConversation();
if (conversation != null) {
- return "xmpp:" + conversation.getAccount().getJid().toBareJid();
+ return conversation.getAccount().getShareableUri();
} else {
return "";
}
diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java
index dc818599..b9772bd7 100644
--- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java
@@ -26,6 +26,7 @@ import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
+import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.utils.Validator;
import eu.siacs.conversations.xmpp.XmppConnection.Features;
@@ -270,7 +271,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
@Override
protected String getShareableUri() {
if (mAccount!=null) {
- return "xmpp:"+mAccount.getJid().toBareJid();
+ return mAccount.getShareableUri();
} else {
return "";
}
@@ -402,11 +403,10 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
} else {
this.mServerInfoPep.setText(R.string.server_info_unavailable);
}
- final String fingerprint = this.mAccount
- .getOtrFingerprint(xmppConnectionService);
+ final String fingerprint = this.mAccount.getOtrFingerprint();
if (fingerprint != null) {
this.mOtrFingerprintBox.setVisibility(View.VISIBLE);
- this.mOtrFingerprint.setText(fingerprint);
+ this.mOtrFingerprint.setText(CryptoHelper.prettifyFingerprint(fingerprint));
this.mOtrFingerprintToClipboardButton
.setVisibility(View.VISIBLE);
this.mOtrFingerprintToClipboardButton
diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java
index 766b3961..fe188737 100644
--- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java
@@ -62,6 +62,7 @@ import eu.siacs.conversations.entities.ListItem;
import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
import eu.siacs.conversations.ui.adapter.ListItemAdapter;
+import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.Validator;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
@@ -316,7 +317,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
}
@SuppressLint("InflateParams")
- protected void showCreateContactDialog(String prefilledJid) {
+ protected void showCreateContactDialog(final String prefilledJid, final String fingerprint) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.create_contact);
View dialogView = getLayoutInflater().inflate(
@@ -328,6 +329,12 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
android.R.layout.simple_list_item_1, mKnownHosts));
if (prefilledJid != null) {
jid.append(prefilledJid);
+ if (fingerprint!=null) {
+ jid.setFocusable(false);
+ jid.setFocusableInTouchMode(false);
+ jid.setClickable(false);
+ jid.setCursorVisible(false);
+ }
}
populateAccountSpinner(spinner);
builder.setView(dialogView);
@@ -367,6 +374,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
if (contact.showInRoster()) {
jid.setError(getString(R.string.contact_already_exists));
} else {
+ contact.addOtrFingerprint(fingerprint);
xmppConnectionService.createContact(contact);
dialog.dismiss();
switchToConversation(contact);
@@ -511,7 +519,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_create_contact:
- showCreateContactDialog(null);
+ showCreateContactDialog(null,null);
return true;
case R.id.action_join_conference:
showJoinConferenceDialog(null);
@@ -615,22 +623,29 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
return false;
}
- private boolean handleJid(String jid) {
- List<Contact> contacts = xmppConnectionService.findContacts(jid);
+ private boolean handleJid(Invite invite) {
+ List<Contact> contacts = xmppConnectionService.findContacts(invite.jid);
if (contacts.size() == 0) {
- showCreateContactDialog(jid);
+ showCreateContactDialog(invite.jid,invite.fingerprint);
return false;
} else if (contacts.size() == 1) {
- switchToConversation(contacts.get(0));
+ Contact contact = contacts.get(0);
+ if (invite.fingerprint != null) {
+ if (contact.addOtrFingerprint(invite.fingerprint)) {
+ Log.d(Config.LOGTAG,"added new fingerprint");
+ xmppConnectionService.syncRosterToDisk(contact.getAccount());
+ }
+ }
+ switchToConversation(contact);
return true;
} else {
if (mMenuSearchView != null) {
mMenuSearchView.expandActionView();
mSearchEditText.setText("");
- mSearchEditText.append(jid);
- filter(jid);
+ mSearchEditText.append(invite.jid);
+ filter(invite.jid);
} else {
- mInitialJid = jid;
+ mInitialJid = invite.jid;
}
return true;
}
@@ -743,6 +758,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
private class Invite {
private String jid;
private boolean muc;
+ private String fingerprint;
Invite(Uri uri) {
parse(uri);
@@ -761,7 +777,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
if (muc) {
showJoinConferenceDialog(jid);
} else {
- return handleJid(jid);
+ return handleJid(this);
}
}
return false;
@@ -777,6 +793,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
} else {
jid = uri.getSchemeSpecificPart().split("\\?")[0];
}
+ fingerprint = parseFingerprint(uri.getQuery());
} else if ("imto".equals(scheme)) {
// sample: imto://xmpp/jid@foo.com
try {
@@ -785,5 +802,19 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
}
}
}
+
+ String parseFingerprint(String query) {
+ if (query == null) {
+ return null;
+ } else {
+ final String NEEDLE = "otr-fingerprint=";
+ int index = query.indexOf(NEEDLE);
+ if (index >= 0 && query.length() >= (NEEDLE.length() + index + 40)) {
+ return CryptoHelper.prettifyFingerprint(query.substring(index + NEEDLE.length(), index + NEEDLE.length() + 40));
+ } else {
+ return null;
+ }
+ }
+ }
}
}
diff --git a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java
index af3194e9..bffc9743 100644
--- a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java
@@ -16,6 +16,7 @@ import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
@@ -184,7 +185,7 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer
this.mVerificationAreaOne.setVisibility(View.VISIBLE);
this.mVerificationAreaTwo.setVisibility(View.VISIBLE);
this.mErrorNoSession.setVisibility(View.GONE);
- this.mYourFingerprint.setText(this.mAccount.getOtrFingerprint(xmppConnectionService));
+ this.mYourFingerprint.setText(CryptoHelper.prettifyFingerprint(this.mAccount.getOtrFingerprint()));
this.mRemoteFingerprint.setText(this.mConversation.getOtrFingerprint());
this.mRemoteJid.setText(this.mConversation.getContact().getJid().toBareJid().toString());
Conversation.Smp smp = mConversation.smp();
@@ -279,7 +280,7 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer
@Override
protected String getShareableUri() {
if (mAccount!=null) {
- return "xmpp:"+mAccount.getJid().toBareJid();
+ return mAccount.getShareableUri();
} else {
return "";
}
diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java
index f7126a2f..b4a6e65c 100644
--- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java
+++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java
@@ -82,4 +82,13 @@ public class CryptoHelper {
public static String saslPrep(final String s) {
return saslEscape(Normalizer.normalize(s, Normalizer.Form.NFKC));
}
+
+ public static String prettifyFingerprint(String fingerprint) {
+ StringBuilder builder = new StringBuilder(fingerprint);
+ builder.insert(8, " ");
+ builder.insert(17, " ");
+ builder.insert(26, " ");
+ builder.insert(35, " ");
+ return builder.toString();
+ }
}