public void savePublicKey(SessionID sessionID, PublicKey pubKey) { if (sessionID == null) return; X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(pubKey.getEncoded()); // if (!Address.hasResource(fullUserId)) // return; this.store.setProperty( sessionID.getRemoteUserId() + ".publicKey", x509EncodedKeySpec.getEncoded()); // Stash the associated fingerprint. This saves calculating it in the future // and is useful for transferring rosters to other apps. try { String fingerprintString = new OtrCryptoEngineImpl().getFingerprint(pubKey); String verifiedToken = buildPublicKeyVerifiedId(sessionID.getRemoteUserId(), fingerprintString.toLowerCase()); if (!this.store.hasProperty(verifiedToken)) this.store.setProperty(verifiedToken, false); this.store.setPropertyHex( sessionID.getRemoteUserId() + ".fingerprint", Hex.decode(fingerprintString)); store.save(); } catch (OtrCryptoException e) { e.printStackTrace(); } }
@Override public void injectMessage(SessionID session, String body) throws OtrException { MessagePacket packet = new MessagePacket(); packet.setFrom(account.getJid()); if (session.getUserID().isEmpty()) { packet.setAttribute("to", session.getAccountID()); } else { packet.setAttribute("to", session.getAccountID() + "/" + session.getUserID()); } packet.setBody(body); MessageGenerator.addMessageHints(packet); try { Jid jid = Jid.fromSessionID(session); Conversation conversation = mXmppConnectionService.find(account, jid); if (conversation != null && conversation.setOutgoingChatState(Config.DEFAULT_CHATSTATE)) { if (mXmppConnectionService.sendChatStates()) { packet.addChild(ChatState.toElement(conversation.getOutgoingChatState())); } } } catch (final InvalidJidException ignored) { } packet.setType(MessagePacket.TYPE_CHAT); account.getXmppConnection().sendMessagePacket(packet); }
public boolean isVerified(SessionID sessionID) { if (sessionID == null) return false; String remoteFingerprint = getRemoteFingerprint(sessionID.getRemoteUserId()); if (remoteFingerprint != null) { String username = Address.stripResource(sessionID.getRemoteUserId()); String pubKeyVerifiedToken = buildPublicKeyVerifiedId(username, remoteFingerprint); return this.store.getPropertyBoolean(pubKeyVerifiedToken, false); } else { return false; } }
public void verify(SessionID sessionID) { if (sessionID == null) return; if (this.isVerified(sessionID)) return; verifyUser(sessionID.getRemoteUserId()); }
@Override public void verify(SessionID id, String fingerprint, boolean approved) { Log.d( Config.LOGTAG, "OtrService.verify(" + id.toString() + "," + fingerprint + "," + String.valueOf(approved) + ")"); try { final Jid jid = Jid.fromSessionID(id); Conversation conversation = this.mXmppConnectionService.find(this.account, jid); if (conversation != null) { if (approved) { conversation.getContact().addOtrFingerprint(fingerprint); } conversation.smp().hint = null; conversation.smp().status = Conversation.Smp.STATUS_VERIFIED; mXmppConnectionService.updateConversationUi(); mXmppConnectionService.syncRosterToDisk(conversation.getAccount()); } } catch (final InvalidJidException ignored) { } }
/** * Returns the key pair (private and public key) for the local machine * * @param sessionID sessionID for currect machine */ public KeyPair loadLocalKeyPair(SessionID sessionID) { if (sessionID == null) return null; String accountID = sessionID.getAccountID(); // Load Private Key. byte[] b64PrivKey = this.store.getPropertyBytes(accountID + ".privateKey"); if (b64PrivKey == null) return null; PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(b64PrivKey); // Load Public Key. byte[] b64PubKey = this.store.getPropertyBytes(accountID + ".publicKey"); if (b64PubKey == null) return null; X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64PubKey); PublicKey publicKey; PrivateKey privateKey; // Generate KeyPair. KeyFactory keyFactory; try { keyFactory = KeyFactory.getInstance("DSA"); publicKey = keyFactory.generatePublic(publicKeySpec); privateKey = keyFactory.generatePrivate(privateKeySpec); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } catch (InvalidKeySpecException e) { e.printStackTrace(); return null; } return new KeyPair(publicKey, privateKey); }
/** Removes the verification for the specified sessionID */ public void unverify(SessionID sessionID) { if (sessionID == null) return; if (!isVerified(sessionID)) return; this.store.removeProperty(sessionID.getUserID() + ".publicKey.verified"); for (OtrKeyManagerListener l : listeners) l.verificationStatusChanged(sessionID); }
@Override public void sessionStatusChanged(SessionID sessionID) { if (sessionID .getRemoteUserId() .equals(mChatSession.getParticipant().getAddress().getAddress())) onStatusChanged(mChatSession, OtrChatManager.getInstance().getSessionStatus(sessionID)); }
public void unverify(SessionID sessionID) { if (sessionID == null) return; if (!isVerified(sessionID)) return; unverifyUser(sessionID.getRemoteUserId()); for (OtrKeyManagerListener l : listeners) l.verificationStatusChanged(sessionID); }
/** * Stores the public key for a specified user from sessionID * * @param sessionID sessionID to identifiy the owner of the key * @param pubKey the key which should be stored */ public void savePublicKey(SessionID sessionID, PublicKey pubKey) { if (sessionID == null) return; X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(pubKey.getEncoded()); String userID = sessionID.getUserID(); this.store.setProperty(userID + ".publicKey", x509EncodedKeySpec.getEncoded()); this.store.removeProperty(userID + ".publicKey.verified"); }
@Override public void askForSecret(SessionID id, InstanceTag instanceTag, String question) { try { final Jid jid = Jid.fromSessionID(id); Conversation conversation = this.mXmppConnectionService.find(this.account, jid); if (conversation != null) { conversation.smp().hint = question; conversation.smp().status = Conversation.Smp.STATUS_CONTACT_REQUESTED; mXmppConnectionService.updateConversationUi(); } } catch (InvalidJidException e) { Log.d( Config.LOGTAG, account.getJid().toBareJid() + ": smp in invalid session " + id.toString()); } }
/** * Loads the public key for the specified sessionID. If there is no key stored, you will get * 'null' */ public PublicKey loadRemotePublicKey(SessionID sessionID) { if (sessionID == null) return null; String userID = sessionID.getUserID(); byte[] b64PubKey = this.store.getPropertyBytes(userID + ".publicKey"); if (b64PubKey == null) return null; X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64PubKey); // Generate KeyPair. KeyFactory keyFactory; try { keyFactory = KeyFactory.getInstance("DSA"); return keyFactory.generatePublic(publicKeySpec); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } catch (InvalidKeySpecException e) { e.printStackTrace(); return null; } }
/** * Generate a local key pair. Be careful. If there is already an key pair, it will override it * * @param sessionID the sessionID that is identified with the local machine */ public void generateLocalKeyPair(SessionID sessionID) { if (sessionID == null) return; String accountID = sessionID.getAccountID(); KeyPair keyPair; try { keyPair = KeyPairGenerator.getInstance("DSA").genKeyPair(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return; } // Store Public Key. PublicKey pubKey = keyPair.getPublic(); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(pubKey.getEncoded()); this.store.setProperty(accountID + ".publicKey", x509EncodedKeySpec.getEncoded()); // Store Private Key. PrivateKey privKey = keyPair.getPrivate(); PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privKey.getEncoded()); this.store.setProperty(accountID + ".privateKey", pkcs8EncodedKeySpec.getEncoded()); }
public String getRemoteFingerprint(SessionID sessionID) { return getRemoteFingerprint(sessionID.getRemoteUserId()); }
/** check if the specified sessionID is verified for this machine */ public boolean isVerified(SessionID sessionID) { if (sessionID == null) return false; return this.store.getPropertyBoolean(sessionID.getUserID() + ".publicKey.verified", false); }
public KeyPair loadLocalKeyPair(SessionID sessionID) { if (sessionID == null) return null; return loadLocalKeyPair(sessionID.getLocalUserId()); }
public String getLocalFingerprint(SessionID sessionID) { return getLocalFingerprint(sessionID.getLocalUserId()); }
public PublicKey loadRemotePublicKey(SessionID sessionID) { return loadRemotePublicKeyFromStore(sessionID.getRemoteUserId()); }
public void selectPresence(final Conversation conversation, final OnPresenceSelected listener) { final Contact contact = conversation.getContact(); if (conversation.hasValidOtrSession()) { SessionID id = conversation.getOtrSession().getSessionID(); Jid jid; try { jid = Jid.fromString(id.getAccountID() + "/" + id.getUserID()); } catch (InvalidJidException e) { jid = null; } conversation.setNextCounterpart(jid); listener.onPresenceSelected(); } else if (!contact.showInRoster()) { showAddToRosterDialog(conversation); } else { Presences presences = contact.getPresences(); if (presences.size() == 0) { if (!contact.getOption(Contact.Options.TO) && !contact.getOption(Contact.Options.ASKING) && contact.getAccount().getStatus() == Account.State.ONLINE) { showAskForPresenceDialog(contact); } else if (!contact.getOption(Contact.Options.TO) || !contact.getOption(Contact.Options.FROM)) { warnMutalPresenceSubscription(conversation, listener); } else { conversation.setNextCounterpart(null); listener.onPresenceSelected(); } } else if (presences.size() == 1) { String presence = presences.asStringArray()[0]; try { conversation.setNextCounterpart( Jid.fromParts( contact.getJid().getLocalpart(), contact.getJid().getDomainpart(), presence)); } catch (InvalidJidException e) { conversation.setNextCounterpart(null); } listener.onPresenceSelected(); } else { final StringBuilder presence = new StringBuilder(); AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(getString(R.string.choose_presence)); final String[] presencesArray = presences.asStringArray(); int preselectedPresence = 0; for (int i = 0; i < presencesArray.length; ++i) { if (presencesArray[i].equals(contact.lastseen.presence)) { preselectedPresence = i; break; } } presence.append(presencesArray[preselectedPresence]); builder.setSingleChoiceItems( presencesArray, preselectedPresence, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { presence.delete(0, presence.length()); presence.append(presencesArray[which]); } }); builder.setNegativeButton(R.string.cancel, null); builder.setPositiveButton( R.string.ok, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { try { conversation.setNextCounterpart( Jid.fromParts( contact.getJid().getLocalpart(), contact.getJid().getDomainpart(), presence.toString())); } catch (InvalidJidException e) { conversation.setNextCounterpart(null); } listener.onPresenceSelected(); } }); builder.create().show(); } } }
public void generateLocalKeyPair(SessionID sessionID) { if (sessionID == null) return; generateLocalKeyPair(sessionID.getLocalUserId()); }