mirror of
https://github.com/igniterealtime/Spark.git
synced 2025-12-01 12:27:58 +00:00
moving on, OTR Plugin, the next step
git-svn-id: http://svn.igniterealtime.org/svn/repos/spark/branches/otrplugin@12451 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
committed by
holger.bergunde
parent
25ee667d15
commit
e895d58af7
@ -7,6 +7,7 @@
|
|||||||
<email>holger@bergunde.de</email>
|
<email>holger@bergunde.de</email>
|
||||||
<description>Adds OTR support to Spark</description>
|
<description>Adds OTR support to Spark</description>
|
||||||
<minSparkVersion>2.6.0</minSparkVersion>
|
<minSparkVersion>2.6.0</minSparkVersion>
|
||||||
|
<java>1.6.0_1</java>
|
||||||
<class>org.jivesoftware.spark.otrplug.OTRPlugin</class>
|
<class>org.jivesoftware.spark.otrplug.OTRPlugin</class>
|
||||||
<os>Windows,Linux,Mac</os>
|
<os>Windows,Linux,Mac</os>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
@ -33,7 +33,8 @@ public class OTRManager extends ChatRoomListenerAdapter {
|
|||||||
private MessageListenerHandler _msgListener;
|
private MessageListenerHandler _msgListener;
|
||||||
private Map<String, OTRSession> _activeSessions = new HashMap<String,OTRSession>();
|
private Map<String, OTRSession> _activeSessions = new HashMap<String,OTRSession>();
|
||||||
final ChatManager chatManager = SparkManager.getChatManager();
|
final ChatManager chatManager = SparkManager.getChatManager();
|
||||||
private static OtrKeyManager _keyManager;
|
private static MyOtrKeyManager _keyManager;
|
||||||
|
|
||||||
|
|
||||||
private OTRManager()
|
private OTRManager()
|
||||||
{
|
{
|
||||||
@ -81,7 +82,7 @@ public class OTRManager extends ChatRoomListenerAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public OtrKeyManager getKeyManager()
|
public MyOtrKeyManager getKeyManager()
|
||||||
{
|
{
|
||||||
return _keyManager;
|
return _keyManager;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,139 @@
|
|||||||
|
|
||||||
|
package org.jivesoftware.spark.otrplug;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Properties;
|
||||||
|
import org.jivesoftware.spark.SparkManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RoarProperties file stuff
|
||||||
|
*
|
||||||
|
* @author wolf.posdorfer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class OTRProperties {
|
||||||
|
private Properties props;
|
||||||
|
private File configFile;
|
||||||
|
|
||||||
|
private static final Object LOCK = new Object();
|
||||||
|
private static OTRProperties instance = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the Instance of this Properties file
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static OTRProperties getInstance() {
|
||||||
|
synchronized (LOCK) {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new OTRProperties();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private OTRProperties() {
|
||||||
|
this.props = new Properties();
|
||||||
|
|
||||||
|
try {
|
||||||
|
props.load(new FileInputStream(getConfigFile()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Can't load ConfigFile
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private File getConfigFile() {
|
||||||
|
if (configFile == null)
|
||||||
|
configFile = new File(SparkManager.getUserDirectory(), "otr.properties");
|
||||||
|
|
||||||
|
return configFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() {
|
||||||
|
try {
|
||||||
|
props.store(new FileOutputStream(getConfigFile()),
|
||||||
|
"Storing OTRPlugin properties");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getIsOTREnabled()
|
||||||
|
{
|
||||||
|
return getBoolean("isOTREnabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsOTREnabled(boolean enabled)
|
||||||
|
{
|
||||||
|
setBoolean("isOTREnabeld", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ===============================================================================
|
||||||
|
// ===============================================================================
|
||||||
|
// ===============================================================================
|
||||||
|
private boolean getBoolean(String property, boolean defaultValue) {
|
||||||
|
return Boolean.parseBoolean(props.getProperty(property,
|
||||||
|
Boolean.toString(defaultValue)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setBoolean(String property, boolean value) {
|
||||||
|
props.setProperty(property, Boolean.toString(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getInt(String property) {
|
||||||
|
return Integer.parseInt(props.getProperty(property, "0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setInt(String property, int integer) {
|
||||||
|
props.setProperty(property, "" + integer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setColor(String property, Color color) {
|
||||||
|
props.setProperty(property, convertColor(color));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color getColor(String property, Color defaultcolor) {
|
||||||
|
try {
|
||||||
|
return convertString(props.getProperty(property));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return defaultcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProperty(String property) {
|
||||||
|
return props.getProperty(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a {@link String} matching xxx,xxx,xxx to a {@link Color}<br>
|
||||||
|
* where xxx is a number from 0 to 255
|
||||||
|
*
|
||||||
|
* @param s
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Color convertString(String s) throws Exception {
|
||||||
|
String[] arr = s.split(",");
|
||||||
|
return new Color(Integer.parseInt(arr[0]), Integer.parseInt(arr[1]),
|
||||||
|
Integer.parseInt(arr[2]));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a {@link Color} to a {@link String} in this format:<br>
|
||||||
|
* <b>xxx,xxx,xxx</b> <br>
|
||||||
|
* where xxx is a number from 0 to 255
|
||||||
|
*
|
||||||
|
* @param color
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String convertColor(Color color) {
|
||||||
|
return color.getRed() + "," + color.getGreen() + "," + color.getBlue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package org.jivesoftware.spark.otrplug;
|
||||||
|
|
||||||
|
import java.util.PropertyResourceBundle;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
import org.jivesoftware.spark.util.log.Log;
|
||||||
|
|
||||||
|
public class OTRResources {
|
||||||
|
|
||||||
|
private static PropertyResourceBundle prb;
|
||||||
|
|
||||||
|
static ClassLoader cl = OTRResources.class.getClassLoader();
|
||||||
|
|
||||||
|
static {
|
||||||
|
prb = (PropertyResourceBundle) ResourceBundle.getBundle("i18n/otrplugin_i18n");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String getString(String propertyName) {
|
||||||
|
try {
|
||||||
|
return prb.getString(propertyName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.error(e);
|
||||||
|
return propertyName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -32,276 +32,264 @@ import net.java.otr4j.session.SessionID;
|
|||||||
|
|
||||||
public class MyOtrKeyManager implements OtrKeyManager {
|
public class MyOtrKeyManager implements OtrKeyManager {
|
||||||
|
|
||||||
private OtrKeyManagerStore store;
|
private OtrKeyManagerStore store;
|
||||||
|
|
||||||
public MyOtrKeyManager(OtrKeyManagerStore store) {
|
public MyOtrKeyManager(OtrKeyManagerStore store) {
|
||||||
this.store = store;
|
this.store = store;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DefaultPropertiesStore implements OtrKeyManagerStore {
|
||||||
|
private final Properties properties = new Properties();
|
||||||
|
private String filepath;
|
||||||
|
|
||||||
|
public DefaultPropertiesStore(String filepath) throws IOException {
|
||||||
|
if (filepath == null || filepath.length() < 1)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
this.filepath = filepath;
|
||||||
|
properties.clear();
|
||||||
|
|
||||||
|
InputStream in = new BufferedInputStream(new FileInputStream(getConfigurationFile()));
|
||||||
|
try {
|
||||||
|
properties.load(in);
|
||||||
|
} finally {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultPropertiesStore implements OtrKeyManagerStore {
|
private File getConfigurationFile() throws IOException {
|
||||||
private final Properties properties = new Properties();
|
File configFile = new File(filepath);
|
||||||
private String filepath;
|
if (!configFile.exists())
|
||||||
|
configFile.createNewFile();
|
||||||
public DefaultPropertiesStore(String filepath) throws IOException {
|
return configFile;
|
||||||
if (filepath == null || filepath.length() < 1)
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
this.filepath = filepath;
|
|
||||||
properties.clear();
|
|
||||||
|
|
||||||
InputStream in = new BufferedInputStream(new FileInputStream(
|
|
||||||
getConfigurationFile()));
|
|
||||||
try {
|
|
||||||
properties.load(in);
|
|
||||||
} finally {
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private File getConfigurationFile() throws IOException {
|
|
||||||
File configFile = new File(filepath);
|
|
||||||
if (!configFile.exists())
|
|
||||||
configFile.createNewFile();
|
|
||||||
return configFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProperty(String id, boolean value) {
|
|
||||||
properties.setProperty(id, "true");
|
|
||||||
try {
|
|
||||||
this.store();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void store() throws FileNotFoundException, IOException {
|
|
||||||
OutputStream out = new FileOutputStream(getConfigurationFile());
|
|
||||||
properties.store(out, null);
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProperty(String id, byte[] value) {
|
|
||||||
properties.setProperty(id, new String(Base64.encode(value)));
|
|
||||||
try {
|
|
||||||
this.store();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeProperty(String id) {
|
|
||||||
properties.remove(id);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getPropertyBytes(String id) {
|
|
||||||
String value = properties.getProperty(id);
|
|
||||||
if (value == null)
|
|
||||||
return null;
|
|
||||||
return Base64.decode(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getPropertyBoolean(String id, boolean defaultValue) {
|
|
||||||
try {
|
|
||||||
return Boolean.valueOf(properties.get(id).toString());
|
|
||||||
} catch (Exception e) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MyOtrKeyManager(String filepath) throws IOException {
|
public void setProperty(String id, boolean value) {
|
||||||
this.store = new DefaultPropertiesStore(filepath);
|
properties.setProperty(id, "true");
|
||||||
|
try {
|
||||||
|
this.store();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<OtrKeyManagerListener> listeners = new Vector<OtrKeyManagerListener>();
|
private void store() throws FileNotFoundException, IOException {
|
||||||
|
OutputStream out = new FileOutputStream(getConfigurationFile());
|
||||||
public void addListener(OtrKeyManagerListener l) {
|
properties.store(out, null);
|
||||||
synchronized (listeners) {
|
out.close();
|
||||||
if (!listeners.contains(l))
|
|
||||||
listeners.add(l);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeListener(OtrKeyManagerListener l) {
|
public void setProperty(String id, byte[] value) {
|
||||||
synchronized (listeners) {
|
properties.setProperty(id, new String(Base64.encode(value)));
|
||||||
listeners.remove(l);
|
try {
|
||||||
}
|
this.store();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateLocalKeyPair(SessionID sessionID) {
|
public void removeProperty(String id) {
|
||||||
if (sessionID == null)
|
properties.remove(id);
|
||||||
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 getLocalFingerprint(SessionID sessionID) {
|
|
||||||
KeyPair keyPair = loadLocalKeyPair(sessionID);
|
|
||||||
|
|
||||||
if (keyPair == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
PublicKey pubKey = keyPair.getPublic();
|
|
||||||
|
|
||||||
try {
|
|
||||||
return new OtrCryptoEngineImpl().getFingerprint(pubKey);
|
|
||||||
} catch (OtrCryptoException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRemoteFingerprint(SessionID sessionID) {
|
|
||||||
PublicKey remotePublicKey = loadRemotePublicKey(sessionID);
|
|
||||||
if (remotePublicKey == null)
|
|
||||||
return null;
|
|
||||||
try {
|
|
||||||
return new OtrCryptoEngineImpl().getFingerprint(remotePublicKey);
|
|
||||||
} catch (OtrCryptoException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void verify(SessionID sessionID) {
|
public byte[] getPropertyBytes(String id) {
|
||||||
if (sessionID == null)
|
String value = properties.getProperty(id);
|
||||||
return;
|
if (value == null)
|
||||||
|
return null;
|
||||||
if (this.isVerified(sessionID))
|
return Base64.decode(value);
|
||||||
return;
|
|
||||||
|
|
||||||
this.store.setProperty(sessionID.getUserID() + ".publicKey.verified",
|
|
||||||
true);
|
|
||||||
|
|
||||||
for (OtrKeyManagerListener l : listeners)
|
|
||||||
l.verificationStatusChanged(sessionID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getPropertyBoolean(String id, boolean defaultValue) {
|
||||||
|
try {
|
||||||
|
return Boolean.valueOf(properties.get(id).toString());
|
||||||
|
} catch (Exception e) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MyOtrKeyManager(String filepath) throws IOException {
|
||||||
|
this.store = new DefaultPropertiesStore(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<OtrKeyManagerListener> listeners = new Vector<OtrKeyManagerListener>();
|
||||||
|
|
||||||
|
public void addListener(OtrKeyManagerListener l) {
|
||||||
|
synchronized (listeners) {
|
||||||
|
if (!listeners.contains(l))
|
||||||
|
listeners.add(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeListener(OtrKeyManagerListener l) {
|
||||||
|
synchronized (listeners) {
|
||||||
|
listeners.remove(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 getLocalFingerprint(SessionID sessionID) {
|
||||||
|
KeyPair keyPair = loadLocalKeyPair(sessionID);
|
||||||
|
|
||||||
|
if (keyPair == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
PublicKey pubKey = keyPair.getPublic();
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new OtrCryptoEngineImpl().getFingerprint(pubKey);
|
||||||
|
} catch (OtrCryptoException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRemoteFingerprint(SessionID sessionID) {
|
||||||
|
PublicKey remotePublicKey = loadRemotePublicKey(sessionID);
|
||||||
|
if (remotePublicKey == null)
|
||||||
|
return null;
|
||||||
|
try {
|
||||||
|
return new OtrCryptoEngineImpl().getFingerprint(remotePublicKey);
|
||||||
|
} catch (OtrCryptoException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void verify(SessionID sessionID) {
|
||||||
|
if (sessionID == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this.isVerified(sessionID))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.store.setProperty(sessionID.getUserID() + ".publicKey.verified", true);
|
||||||
|
|
||||||
|
for (OtrKeyManagerListener l : listeners)
|
||||||
|
l.verificationStatusChanged(sessionID);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,85 @@
|
|||||||
|
package org.jivesoftware.spark.ui;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTable;
|
||||||
|
|
||||||
|
import javax.swing.event.TableModelListener;
|
||||||
|
import javax.swing.table.DefaultTableModel;
|
||||||
|
|
||||||
|
import org.jivesoftware.spark.otrplug.OTRResources;
|
||||||
|
|
||||||
|
public class OTRKeyTable extends JComponent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -2922785387942547350L;
|
||||||
|
private JTable _table;
|
||||||
|
private DefaultTableModel _tableModel;
|
||||||
|
|
||||||
|
public OTRKeyTable() {
|
||||||
|
|
||||||
|
final String[] header = { OTRResources.getString("otr.table.jid"), OTRResources.getString("otr.table.public.key"), OTRResources.getString("otr.key.verified") };
|
||||||
|
|
||||||
|
_tableModel = new MyTableModel(header);
|
||||||
|
_table = new JTable(_tableModel);
|
||||||
|
|
||||||
|
this.setLayout(new BorderLayout());
|
||||||
|
this.add(new JScrollPane(_table), BorderLayout.CENTER);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyTableModel extends DefaultTableModel {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -2930577433474767242L;
|
||||||
|
|
||||||
|
public MyTableModel(String[] headers) {
|
||||||
|
super(headers, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCellEditable(int row, int column) {
|
||||||
|
if (column == 2)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getColumnClass(int columnIndex) {
|
||||||
|
if (columnIndex == 2) {
|
||||||
|
return Boolean.class;
|
||||||
|
} else
|
||||||
|
return String.class;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTableChangeListener(TableModelListener listener) {
|
||||||
|
_tableModel.addTableModelListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEntry(String jid, String hash, boolean verified) {
|
||||||
|
Vector<Object> data = new Vector<Object>(3);
|
||||||
|
|
||||||
|
data.add(jid);
|
||||||
|
data.add(hash);
|
||||||
|
data.add(verified);
|
||||||
|
|
||||||
|
_tableModel.addRow(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getValueAt(int row, int col) {
|
||||||
|
return _tableModel.getValueAt(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -3,46 +3,157 @@ package org.jivesoftware.spark.ui;
|
|||||||
import java.awt.GridBagConstraints;
|
import java.awt.GridBagConstraints;
|
||||||
import java.awt.GridBagLayout;
|
import java.awt.GridBagLayout;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
import java.security.KeyPair;
|
import java.awt.event.ActionEvent;
|
||||||
import java.security.KeyPairGenerator;
|
import java.awt.event.ActionListener;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
|
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JCheckBox;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
import javax.swing.JTextField;
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.event.TableModelEvent;
|
||||||
|
import javax.swing.event.TableModelListener;
|
||||||
|
|
||||||
import net.java.otr4j.session.SessionID;
|
import net.java.otr4j.session.SessionID;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.RosterEntry;
|
||||||
import org.jivesoftware.spark.SparkManager;
|
import org.jivesoftware.spark.SparkManager;
|
||||||
|
import org.jivesoftware.spark.component.VerticalFlowLayout;
|
||||||
import org.jivesoftware.spark.otrplug.OTRManager;
|
import org.jivesoftware.spark.otrplug.OTRManager;
|
||||||
|
import org.jivesoftware.spark.otrplug.OTRProperties;
|
||||||
|
import org.jivesoftware.spark.otrplug.OTRResources;
|
||||||
|
|
||||||
public class OTRPrefPanel extends JPanel{
|
public class OTRPrefPanel extends JPanel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -7125162190413040003L;
|
||||||
private OTRManager _manager;
|
private OTRManager _manager;
|
||||||
private SessionID _mySession = new SessionID(SparkManager.getConnection().getUser(), SparkManager.getConnection().getUser(), "Scytale");
|
private JCheckBox _enableOTR;
|
||||||
public OTRPrefPanel()
|
private JCheckBox _closeSessionOff;
|
||||||
{
|
private JCheckBox _closeSessionOnWindowClose;
|
||||||
|
private JLabel _currentKeyLabel;
|
||||||
|
private JButton _renewPrivateKey;
|
||||||
|
private OTRKeyTable _keytable;
|
||||||
|
private JTextField _privateKey;
|
||||||
|
private JPanel _gridPanel;
|
||||||
|
private MyOtrKeyManager _keyManager;
|
||||||
|
private OTRProperties _properties;
|
||||||
|
|
||||||
|
public OTRPrefPanel() {
|
||||||
|
|
||||||
_manager = OTRManager.getInstance();
|
_manager = OTRManager.getInstance();
|
||||||
setLayout(new GridBagLayout());
|
_keyManager = _manager.getKeyManager();
|
||||||
|
_properties = OTRProperties.getInstance();
|
||||||
|
setLayout(new VerticalFlowLayout());
|
||||||
|
init();
|
||||||
buildGUI();
|
buildGUI();
|
||||||
}
|
OtrEnableSwitch();
|
||||||
|
this.add(_gridPanel);
|
||||||
|
|
||||||
private void buildGUI()
|
|
||||||
{
|
|
||||||
//_manager.getKeyManager().generateLocalKeyPair(_mySession);
|
|
||||||
KeyPair key = _manager.getKeyManager().loadLocalKeyPair(_mySession);
|
|
||||||
|
|
||||||
String privkey = _manager.getKeyManager().getLocalFingerprint(_mySession);
|
|
||||||
|
|
||||||
System.out.println( privkey);
|
|
||||||
this.add(new JLabel("key: "), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
|
|
||||||
this.add(new JTextField(privkey), new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OtrEnableSwitch() {
|
||||||
|
|
||||||
|
_enableOTR.setSelected(_properties.getIsOTREnabled());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOTREnabled()
|
||||||
|
{
|
||||||
|
return _enableOTR.isSelected();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
_gridPanel = new JPanel(new GridBagLayout());
|
||||||
|
|
||||||
|
_enableOTR = new JCheckBox();
|
||||||
|
_enableOTR.setText(OTRResources.getString("otr.enable"));
|
||||||
|
|
||||||
|
_closeSessionOff = new JCheckBox();
|
||||||
|
_closeSessionOff.setText(OTRResources.getString("otr.close.session.on.contact.off"));
|
||||||
|
|
||||||
|
_closeSessionOnWindowClose = new JCheckBox();
|
||||||
|
_closeSessionOnWindowClose.setText(OTRResources.getString("otr.close.session.on.window.close"));
|
||||||
|
|
||||||
|
_currentKeyLabel = new JLabel();
|
||||||
|
_currentKeyLabel.setText(OTRResources.getString("current.priv.key"));
|
||||||
|
|
||||||
|
_renewPrivateKey = new JButton();
|
||||||
|
_renewPrivateKey.setText(OTRResources.getString("renew.current.key"));
|
||||||
|
_renewPrivateKey.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
SessionID mySession = new SessionID(SparkManager.getConnection().getUser(), "no one", "Scytale");
|
||||||
|
_manager.getKeyManager().generateLocalKeyPair(mySession);
|
||||||
|
_privateKey.setText(getCurrentLocalKey());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_privateKey = new JTextField();
|
||||||
|
_privateKey.setEditable(false);
|
||||||
|
_privateKey.setSize(300, 20);
|
||||||
|
_privateKey.setText(getCurrentLocalKey());
|
||||||
|
|
||||||
|
_keytable = new OTRKeyTable();
|
||||||
|
|
||||||
|
loadRemoteKeys();
|
||||||
|
|
||||||
|
_keytable.addTableChangeListener(new TableModelListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tableChanged(TableModelEvent e) {
|
||||||
|
int col = e.getColumn();
|
||||||
|
int row = e.getFirstRow();
|
||||||
|
|
||||||
|
if (col == 2) {
|
||||||
|
boolean selection = (Boolean) _keytable.getValueAt(row, col);
|
||||||
|
String JID = (String)_keytable.getValueAt(row, 0);
|
||||||
|
SessionID curSelectedSession = new SessionID(SparkManager.getConnection().getUser(), JID, "Scytale");
|
||||||
|
if (selection) {
|
||||||
|
_keyManager.verify(curSelectedSession);
|
||||||
|
} else
|
||||||
|
|
||||||
|
{
|
||||||
|
_keyManager.unverify(curSelectedSession);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getCurrentLocalKey() {
|
||||||
|
SessionID mySession = new SessionID(SparkManager.getConnection().getUser(), "no one", "Scytale");
|
||||||
|
String myKey = _keyManager.getLocalFingerprint(mySession);
|
||||||
|
return myKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadRemoteKeys() {
|
||||||
|
|
||||||
|
for (RosterEntry entry : SparkManager.getConnection().getRoster().getEntries()) {
|
||||||
|
SessionID curSession = new SessionID(SparkManager.getConnection().getUser(), entry.getUser(), "Scytale");
|
||||||
|
String remoteKey = _keyManager.getRemoteFingerprint(curSession);
|
||||||
|
if (remoteKey != null) {
|
||||||
|
boolean isVerified = _keyManager.isVerified(curSession);
|
||||||
|
_keytable.addEntry(entry.getUser(), remoteKey, isVerified);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildGUI() {
|
||||||
|
_gridPanel.setBorder(BorderFactory.createTitledBorder(OTRResources.getString("otr.settings")));
|
||||||
|
|
||||||
|
_gridPanel.add(_enableOTR, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
|
||||||
|
_gridPanel.add(_closeSessionOff, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
|
||||||
|
_gridPanel.add(_closeSessionOnWindowClose, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
|
||||||
|
_gridPanel.add(_currentKeyLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(10, 0, 0, 0), 0, 0));
|
||||||
|
_gridPanel.add(_privateKey, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(10, 0, 0, 0), 0, 0));
|
||||||
|
_gridPanel.add(_renewPrivateKey, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||||
|
_gridPanel.add(_keytable, new GridBagConstraints(0, 5, 2, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(20, 0, 0, 0), 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,13 +4,17 @@ import javax.swing.Icon;
|
|||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
import org.jivesoftware.spark.otrplug.OTRManager;
|
import org.jivesoftware.spark.otrplug.OTRManager;
|
||||||
|
import org.jivesoftware.spark.otrplug.OTRProperties;
|
||||||
|
import org.jivesoftware.spark.otrplug.OTRResources;
|
||||||
import org.jivesoftware.spark.preference.Preference;
|
import org.jivesoftware.spark.preference.Preference;
|
||||||
|
|
||||||
public class OTRPreferences implements Preference {
|
public class OTRPreferences implements Preference {
|
||||||
|
|
||||||
|
private OTRPrefPanel pref = new OTRPrefPanel();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return "Off-The-Record Plugin";
|
return OTRResources.getString("otr.title");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -27,7 +31,7 @@ public class OTRPreferences implements Preference {
|
|||||||
@Override
|
@Override
|
||||||
public String getListName() {
|
public String getListName() {
|
||||||
|
|
||||||
return "OTR";
|
return OTRResources.getString("otr.list.entry");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -38,7 +42,7 @@ public class OTRPreferences implements Preference {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JComponent getGUI() {
|
public JComponent getGUI() {
|
||||||
return new OTRPrefPanel();
|
return pref;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -49,7 +53,8 @@ public class OTRPreferences implements Preference {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void commit() {
|
public void commit() {
|
||||||
// TODO Auto-generated method stub
|
OTRProperties.getInstance().setIsOTREnabled(pref.isOTREnabled());
|
||||||
|
OTRProperties.getInstance().save();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -162,8 +162,20 @@ public class OTRSession {
|
|||||||
{
|
{
|
||||||
PublicKey rempubkey = _engine.getRemotePublicKey(_mySession);
|
PublicKey rempubkey = _engine.getRemotePublicKey(_mySession);
|
||||||
OTRManager.getInstance().getKeyManager().savePublicKey(_mySession, rempubkey);
|
OTRManager.getInstance().getKeyManager().savePublicKey(_mySession, rempubkey);
|
||||||
remkey = OTRManager.getInstance().getKeyManager().getRemoteFingerprint(_mySession);
|
remkey = OTRManager.getInstance().getKeyManager().getRemoteFingerprint(_mySession);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
System.out.println(remkey);
|
||||||
|
|
||||||
|
if (OTRManager.getInstance().getKeyManager().isVerified(_mySession))
|
||||||
|
{
|
||||||
|
System.out.println("verified");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(_mySession.getUserID());
|
||||||
|
System.out.println( OTRManager.getInstance().getKeyManager().getLocalFingerprint(_mySession));;
|
||||||
|
|
||||||
//String remkey = OTRManager.getInstance().getKeyManager().getRemoteFingerprint(_mySession);
|
//String remkey = OTRManager.getInstance().getKeyManager().getRemoteFingerprint(_mySession);
|
||||||
_chatRoom.getTranscriptWindow().insertNotificationMessage("From now on, your conversation is encrypted Remotekey: "+remkey, Color.gray);
|
_chatRoom.getTranscriptWindow().insertNotificationMessage("From now on, your conversation is encrypted Remotekey: "+remkey, Color.gray);
|
||||||
_otrButton.setIcon(new ImageIcon(cl.getResource("otr_on.png")));
|
_otrButton.setIcon(new ImageIcon(cl.getResource("otr_on.png")));
|
||||||
|
|||||||
19
src/plugins/otr/src/resources/i18n/otrplugin_i18n.properties
Normal file
19
src/plugins/otr/src/resources/i18n/otrplugin_i18n.properties
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
# OTR language file
|
||||||
|
|
||||||
|
otr.title = Off-the-Record Messaging
|
||||||
|
otr.list.entry = OTR Messaging
|
||||||
|
otr.settings = OTR Settings
|
||||||
|
otr.enable = OTR Enabled
|
||||||
|
current.priv.key = Current private key:
|
||||||
|
renew.current.key = Generate a new key
|
||||||
|
otr.close.session.on.window.close = Close OTR session when chat window is closed
|
||||||
|
otr.close.session.on.contact.off = Close OTR session when contact went offline
|
||||||
|
|
||||||
|
|
||||||
|
#Table Columns
|
||||||
|
otr.table.jid = User's JID
|
||||||
|
otr.table.public.key = Public key
|
||||||
|
otr.key.verified = Verified
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
# OTR language file
|
||||||
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.3 KiB |
Reference in New Issue
Block a user