aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/plugin/otr
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/java/sip/communicator/plugin/otr')
-rw-r--r--src/net/java/sip/communicator/plugin/otr/OtrConfigurator.java338
-rw-r--r--src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java82
-rw-r--r--src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerImpl.java618
-rw-r--r--src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerListener.java26
-rw-r--r--src/net/java/sip/communicator/plugin/otr/ScSessionID.java162
5 files changed, 613 insertions, 613 deletions
diff --git a/src/net/java/sip/communicator/plugin/otr/OtrConfigurator.java b/src/net/java/sip/communicator/plugin/otr/OtrConfigurator.java
index 42efc97..dd3940b 100644
--- a/src/net/java/sip/communicator/plugin/otr/OtrConfigurator.java
+++ b/src/net/java/sip/communicator/plugin/otr/OtrConfigurator.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,171 +15,171 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.otr;
-
-import java.util.*;
-
-import org.bouncycastle.util.encoders.Base64; // disambiguation
-import org.jitsi.service.configuration.*;
-
-/**
- * A class that gets/sets the OTR configuration values. Introduced to assure our
- * configuration is properly written when <tt>XMLConfigurationStore</tt> is
- * used. Can be seen as a proxy between the {@link ConfigurationService} and the
- * OTR Plugin.
- *
- * @author George Politis
- */
-public class OtrConfigurator
-{
- /**
- * Gets an XML tag friendly {@link String} from a {@link String}.
- *
- * @param s a {@link String}
- * @return an XML friendly {@link String}
- */
- private String getXmlFriendlyString(String s)
- {
- if (s == null || s.length() < 1)
- return s;
-
- // XML Tags are not allowed to start with digits,
- // insert a dummy "p" char.
- if (Character.isDigit(s.charAt(0)))
- s = "p" + s;
-
- char[] cId = new char[s.length()];
-
- for (int i = 0; i < cId.length; i++)
- {
- char c = s.charAt(i);
-
- cId[i] = Character.isLetterOrDigit(c) ? c : '_';
- }
-
- return new String(cId);
- }
-
- /**
- * Puts a given property ID under the OTR namespace and makes sure it is XML
- * tag friendly.
- *
- * @param id the property ID.
- * @return the namespaced ID.
- */
- private String getID(String id)
- {
- return
- "net.java.sip.communicator.plugin.otr." + getXmlFriendlyString(id);
- }
-
- /**
- * Returns the value of the property with the specified name or null if no
- * such property exists ({@link ConfigurationService#getProperty(String)}
- * proxy).
- *
- * @param id of the property that is being queried.
- * @return the <tt>byte[]</tt> value of the property with the specified
- * name.
- */
- public byte[] getPropertyBytes(String id)
- {
- String value = OtrActivator.configService.getString(getID(id));
-
- return (value == null) ? null : Base64.decode(value.getBytes());
- }
-
- /**
- * Gets the value of a specific property as a boolean (
- * {@link ConfigurationService#getBoolean(String, boolean)} proxy).
- *
- * @param id of the property that is being queried.
- * @param defaultValue the value to be returned if the specified property
- * name is not associated with a value.
- * @return the <tt>Boolean</tt> value of the property with the specified
- * name.
- */
- public boolean getPropertyBoolean(String id, boolean defaultValue)
- {
- return
- OtrActivator.configService.getBoolean(getID(id), defaultValue);
- }
-
- /**
- * Sets the property with the specified name to the specified value (
- * {@link ConfigurationService#setProperty(String, Object)} proxy). The
- * value is Base64 encoded.
- *
- * @param id the name of the property to change.
- * @param value the new value of the specified property.
- */
- public void setProperty(String id, byte[] value)
- {
- String valueToStore = new String(Base64.encode(value));
-
- OtrActivator.configService.setProperty(getID(id), valueToStore);
- }
-
- /**
- * Sets the property with the specified name to the specified value (
- * {@link ConfigurationService#setProperty(String, Object)} proxy).
- *
- * @param id the name of the property to change.
- * @param value the new value of the specified property.
- */
- public void setProperty(String id, Object value)
- {
- OtrActivator.configService.setProperty(getID(id), value);
- }
-
- /**
- * Removes the property with the specified name (
- * {@link ConfigurationService#removeProperty(String)} proxy).
- *
- * @param id the name of the property to change.
- */
- public void removeProperty(String id)
- {
- OtrActivator.configService.removeProperty(getID(id));
- }
-
- /**
- * Gets the value of a specific property as a signed decimal integer.
- *
- * @param id the name of the property to change.
- * @param defaultValue the value to be returned if the specified property
- * name is not associated with a value.
- * @return the <tt>int</tt> value of the property
- */
- public int getPropertyInt(String id, int defaultValue)
- {
- return OtrActivator.configService.getInt(getID(id), defaultValue);
- }
-
- /**
- * Appends <tt>value</tt> to the old value of the property with the
- * specified name. The two values will be comma separated.
- *
- * @param id the name of the property to append to
- * @param value the value to append
- */
- public void appendProperty(String id, Object value)
- {
- Object oldValue = OtrActivator.configService.getProperty(getID(id));
-
- String newValue =
- oldValue == null ? value.toString() : oldValue + "," + value;
-
- setProperty(id, newValue);
- }
-
- public List<String> getAppendedProperties(String id)
- {
- String listProperties =
- (String) OtrActivator.configService.getProperty(getID(id));
-
- if (listProperties == null) return new ArrayList<String>();
-
- return Arrays.asList(listProperties.split(","));
- }
-}
+package net.java.sip.communicator.plugin.otr;
+
+import java.util.*;
+
+import org.bouncycastle.util.encoders.Base64; // disambiguation
+import org.jitsi.service.configuration.*;
+
+/**
+ * A class that gets/sets the OTR configuration values. Introduced to assure our
+ * configuration is properly written when <tt>XMLConfigurationStore</tt> is
+ * used. Can be seen as a proxy between the {@link ConfigurationService} and the
+ * OTR Plugin.
+ *
+ * @author George Politis
+ */
+public class OtrConfigurator
+{
+ /**
+ * Gets an XML tag friendly {@link String} from a {@link String}.
+ *
+ * @param s a {@link String}
+ * @return an XML friendly {@link String}
+ */
+ private String getXmlFriendlyString(String s)
+ {
+ if (s == null || s.length() < 1)
+ return s;
+
+ // XML Tags are not allowed to start with digits,
+ // insert a dummy "p" char.
+ if (Character.isDigit(s.charAt(0)))
+ s = "p" + s;
+
+ char[] cId = new char[s.length()];
+
+ for (int i = 0; i < cId.length; i++)
+ {
+ char c = s.charAt(i);
+
+ cId[i] = Character.isLetterOrDigit(c) ? c : '_';
+ }
+
+ return new String(cId);
+ }
+
+ /**
+ * Puts a given property ID under the OTR namespace and makes sure it is XML
+ * tag friendly.
+ *
+ * @param id the property ID.
+ * @return the namespaced ID.
+ */
+ private String getID(String id)
+ {
+ return
+ "net.java.sip.communicator.plugin.otr." + getXmlFriendlyString(id);
+ }
+
+ /**
+ * Returns the value of the property with the specified name or null if no
+ * such property exists ({@link ConfigurationService#getProperty(String)}
+ * proxy).
+ *
+ * @param id of the property that is being queried.
+ * @return the <tt>byte[]</tt> value of the property with the specified
+ * name.
+ */
+ public byte[] getPropertyBytes(String id)
+ {
+ String value = OtrActivator.configService.getString(getID(id));
+
+ return (value == null) ? null : Base64.decode(value.getBytes());
+ }
+
+ /**
+ * Gets the value of a specific property as a boolean (
+ * {@link ConfigurationService#getBoolean(String, boolean)} proxy).
+ *
+ * @param id of the property that is being queried.
+ * @param defaultValue the value to be returned if the specified property
+ * name is not associated with a value.
+ * @return the <tt>Boolean</tt> value of the property with the specified
+ * name.
+ */
+ public boolean getPropertyBoolean(String id, boolean defaultValue)
+ {
+ return
+ OtrActivator.configService.getBoolean(getID(id), defaultValue);
+ }
+
+ /**
+ * Sets the property with the specified name to the specified value (
+ * {@link ConfigurationService#setProperty(String, Object)} proxy). The
+ * value is Base64 encoded.
+ *
+ * @param id the name of the property to change.
+ * @param value the new value of the specified property.
+ */
+ public void setProperty(String id, byte[] value)
+ {
+ String valueToStore = new String(Base64.encode(value));
+
+ OtrActivator.configService.setProperty(getID(id), valueToStore);
+ }
+
+ /**
+ * Sets the property with the specified name to the specified value (
+ * {@link ConfigurationService#setProperty(String, Object)} proxy).
+ *
+ * @param id the name of the property to change.
+ * @param value the new value of the specified property.
+ */
+ public void setProperty(String id, Object value)
+ {
+ OtrActivator.configService.setProperty(getID(id), value);
+ }
+
+ /**
+ * Removes the property with the specified name (
+ * {@link ConfigurationService#removeProperty(String)} proxy).
+ *
+ * @param id the name of the property to change.
+ */
+ public void removeProperty(String id)
+ {
+ OtrActivator.configService.removeProperty(getID(id));
+ }
+
+ /**
+ * Gets the value of a specific property as a signed decimal integer.
+ *
+ * @param id the name of the property to change.
+ * @param defaultValue the value to be returned if the specified property
+ * name is not associated with a value.
+ * @return the <tt>int</tt> value of the property
+ */
+ public int getPropertyInt(String id, int defaultValue)
+ {
+ return OtrActivator.configService.getInt(getID(id), defaultValue);
+ }
+
+ /**
+ * Appends <tt>value</tt> to the old value of the property with the
+ * specified name. The two values will be comma separated.
+ *
+ * @param id the name of the property to append to
+ * @param value the value to append
+ */
+ public void appendProperty(String id, Object value)
+ {
+ Object oldValue = OtrActivator.configService.getProperty(getID(id));
+
+ String newValue =
+ oldValue == null ? value.toString() : oldValue + "," + value;
+
+ setProperty(id, newValue);
+ }
+
+ public List<String> getAppendedProperties(String id)
+ {
+ String listProperties =
+ (String) OtrActivator.configService.getProperty(getID(id));
+
+ if (listProperties == null) return new ArrayList<String>();
+
+ return Arrays.asList(listProperties.split(","));
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java
index 183eed7..ae50390 100644
--- a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java
+++ b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,44 +15,44 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.otr;
-
-import java.security.*;
-import java.util.*;
-
-import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- *
- * @author George Politis
- *
- */
-public interface ScOtrKeyManager
-{
-
- public abstract void addListener(ScOtrKeyManagerListener l);
-
- public abstract void removeListener(ScOtrKeyManagerListener l);
-
- public abstract void verify(OtrContact contact, String fingerprint);
-
- public abstract void unverify(OtrContact contact, String fingerprint);
-
- public abstract boolean isVerified(Contact contact, String fingerprint);
-
- public abstract String getFingerprintFromPublicKey(PublicKey pubKey);
-
- public abstract List<String> getAllRemoteFingerprints(Contact contact);
-
- public abstract String getLocalFingerprint(AccountID account);
-
- public abstract byte[] getLocalFingerprintRaw(AccountID account);
-
- public abstract void saveFingerprint(Contact contact, String fingerprint);
-
- public abstract KeyPair loadKeyPair(AccountID accountID);
-
- public abstract void generateKeyPair(AccountID accountID);
-
+package net.java.sip.communicator.plugin.otr;
+
+import java.security.*;
+import java.util.*;
+
+import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *
+ * @author George Politis
+ *
+ */
+public interface ScOtrKeyManager
+{
+
+ public abstract void addListener(ScOtrKeyManagerListener l);
+
+ public abstract void removeListener(ScOtrKeyManagerListener l);
+
+ public abstract void verify(OtrContact contact, String fingerprint);
+
+ public abstract void unverify(OtrContact contact, String fingerprint);
+
+ public abstract boolean isVerified(Contact contact, String fingerprint);
+
+ public abstract String getFingerprintFromPublicKey(PublicKey pubKey);
+
+ public abstract List<String> getAllRemoteFingerprints(Contact contact);
+
+ public abstract String getLocalFingerprint(AccountID account);
+
+ public abstract byte[] getLocalFingerprintRaw(AccountID account);
+
+ public abstract void saveFingerprint(Contact contact, String fingerprint);
+
+ public abstract KeyPair loadKeyPair(AccountID accountID);
+
+ public abstract void generateKeyPair(AccountID accountID);
+
}
diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerImpl.java b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerImpl.java
index 890211e..cb57ba4 100644
--- a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerImpl.java
+++ b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerImpl.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,311 +15,311 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.otr;
-
-import java.security.*;
-import java.security.spec.*;
-import java.util.*;
-
-import net.java.otr4j.crypto.*;
-import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- *
- * @author George Politis
- * @author Lyubomir Marinov
- */
-public class ScOtrKeyManagerImpl
- implements ScOtrKeyManager
-{
- private final OtrConfigurator configurator = new OtrConfigurator();
-
- private final List<ScOtrKeyManagerListener> listeners =
- new Vector<ScOtrKeyManagerListener>();
-
- public void addListener(ScOtrKeyManagerListener l)
- {
- synchronized (listeners)
- {
- if (!listeners.contains(l))
- listeners.add(l);
- }
- }
-
- /**
- * Gets a copy of the list of <tt>ScOtrKeyManagerListener</tt>s registered
- * with this instance which may safely be iterated without the risk of a
- * <tt>ConcurrentModificationException</tt>.
- *
- * @return a copy of the list of <tt>ScOtrKeyManagerListener<tt>s registered
- * with this instance which may safely be iterated without the risk of a
- * <tt>ConcurrentModificationException</tt>
- */
- private ScOtrKeyManagerListener[] getListeners()
- {
- synchronized (listeners)
- {
- return
- listeners.toArray(
- new ScOtrKeyManagerListener[listeners.size()]);
- }
- }
-
- public void removeListener(ScOtrKeyManagerListener l)
- {
- synchronized (listeners)
- {
- listeners.remove(l);
- }
- }
-
- public void verify(OtrContact otrContact, String fingerprint)
- {
- if ((fingerprint == null) || otrContact == null)
- return;
-
- this.configurator.setProperty(otrContact.contact.getAddress() + fingerprint
- + ".fingerprint.verified", true);
-
- for (ScOtrKeyManagerListener l : getListeners())
- l.contactVerificationStatusChanged(otrContact);
- }
-
- public void unverify(OtrContact otrContact, String fingerprint)
- {
- if ((fingerprint == null) || otrContact == null)
- return;
-
- this.configurator.setProperty(otrContact.contact.getAddress() + fingerprint
- + ".fingerprint.verified", false);
-
- for (ScOtrKeyManagerListener l : getListeners())
- l.contactVerificationStatusChanged(otrContact);
- }
-
- public boolean isVerified(Contact contact, String fingerprint)
- {
- if (fingerprint == null || contact == null)
- return false;
-
- return this.configurator.getPropertyBoolean(
- contact.getAddress() + fingerprint
- + ".fingerprint.verified", false);
- }
-
- public List<String> getAllRemoteFingerprints(Contact contact)
- {
- if (contact == null)
- return null;
-
- /*
- * The following lines are needed for backward compatibility with old
- * versions of the otr plugin. Instead of lists of fingerprints the otr
- * plugin used to store one public key for every contact in the form of
- * "userID.publicKey=..." and one boolean property in the form of
- * "userID.publicKey.verified=...". In order not to loose these old
- * properties we have to convert them to match the new format.
- */
- String userID = contact.getAddress();
-
- byte[] b64PubKey =
- this.configurator.getPropertyBytes(userID + ".publicKey");
- if (b64PubKey != null)
- {
- // We delete the old format property because we are going to convert
- // it in the new format
- this.configurator.removeProperty(userID + ".publicKey");
-
- X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64PubKey);
-
- KeyFactory keyFactory;
- try
- {
- keyFactory = KeyFactory.getInstance("DSA");
- PublicKey pubKey = keyFactory.generatePublic(publicKeySpec);
-
- boolean isVerified =
- this.configurator.getPropertyBoolean(userID
- + ".publicKey.verified", false);
-
- // We also make sure to delete this old format property if it
- // exists.
- this.configurator.removeProperty(userID + ".publicKey.verified");
-
- String fingerprint = getFingerprintFromPublicKey(pubKey);
-
- // Now we can store the old properties in the new format.
- if (isVerified)
- verify(OtrContactManager.getOtrContact(contact, null), fingerprint);
- else
- unverify(OtrContactManager.getOtrContact(contact, null), fingerprint);
-
- // Finally we append the new fingerprint to out stored list of
- // fingerprints.
- this.configurator.appendProperty(
- userID + ".fingerprints", fingerprint);
- }
- catch (NoSuchAlgorithmException e)
- {
- e.printStackTrace();
- }
- catch (InvalidKeySpecException e)
- {
- e.printStackTrace();
- }
- }
-
- // Now we can safely return our list of fingerprints for this contact
- // without worrying that we missed an old format property.
- return this.configurator.getAppendedProperties(
- contact.getAddress() + ".fingerprints");
- }
-
- public String getFingerprintFromPublicKey(PublicKey pubKey)
- {
- try
- {
- return new OtrCryptoEngineImpl().getFingerprint(pubKey);
- }
- catch (OtrCryptoException e)
- {
- e.printStackTrace();
- return null;
- }
- }
-
- public String getLocalFingerprint(AccountID account)
- {
- KeyPair keyPair = loadKeyPair(account);
-
- if (keyPair == null)
- return null;
-
- PublicKey pubKey = keyPair.getPublic();
-
- try
- {
- return new OtrCryptoEngineImpl().getFingerprint(pubKey);
- }
- catch (OtrCryptoException e)
- {
- e.printStackTrace();
- return null;
- }
- }
-
- public byte[] getLocalFingerprintRaw(AccountID account)
- {
- KeyPair keyPair = loadKeyPair(account);
-
- if (keyPair == null)
- return null;
-
- PublicKey pubKey = keyPair.getPublic();
-
- try
- {
- return new OtrCryptoEngineImpl().getFingerprintRaw(pubKey);
- }
- catch (OtrCryptoException e)
- {
- e.printStackTrace();
- return null;
- }
- }
-
- public void saveFingerprint(Contact contact, String fingerprint)
- {
- if (contact == null)
- return;
-
- this.configurator.appendProperty(contact.getAddress() + ".fingerprints",
- fingerprint);
-
- this.configurator.setProperty(contact.getAddress() + fingerprint
- + ".fingerprint.verified", false);
- }
-
- public KeyPair loadKeyPair(AccountID account)
- {
- if (account == null)
- return null;
-
- String accountID = account.getAccountUniqueID();
- // Load Private Key.
- byte[] b64PrivKey =
- this.configurator.getPropertyBytes(accountID + ".privateKey");
- if (b64PrivKey == null)
- return null;
-
- PKCS8EncodedKeySpec privateKeySpec =
- new PKCS8EncodedKeySpec(b64PrivKey);
-
- // Load Public Key.
- byte[] b64PubKey =
- this.configurator.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 void generateKeyPair(AccountID account)
- {
- if (account == null)
- return;
-
- String accountID = account.getAccountUniqueID();
- 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.configurator.setProperty(accountID + ".publicKey",
- x509EncodedKeySpec.getEncoded());
-
- // Store Private Key.
- PrivateKey privKey = keyPair.getPrivate();
- PKCS8EncodedKeySpec pkcs8EncodedKeySpec =
- new PKCS8EncodedKeySpec(privKey.getEncoded());
-
- this.configurator.setProperty(accountID + ".privateKey",
- pkcs8EncodedKeySpec.getEncoded());
- }
-}
+package net.java.sip.communicator.plugin.otr;
+
+import java.security.*;
+import java.security.spec.*;
+import java.util.*;
+
+import net.java.otr4j.crypto.*;
+import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *
+ * @author George Politis
+ * @author Lyubomir Marinov
+ */
+public class ScOtrKeyManagerImpl
+ implements ScOtrKeyManager
+{
+ private final OtrConfigurator configurator = new OtrConfigurator();
+
+ private final List<ScOtrKeyManagerListener> listeners =
+ new Vector<ScOtrKeyManagerListener>();
+
+ public void addListener(ScOtrKeyManagerListener l)
+ {
+ synchronized (listeners)
+ {
+ if (!listeners.contains(l))
+ listeners.add(l);
+ }
+ }
+
+ /**
+ * Gets a copy of the list of <tt>ScOtrKeyManagerListener</tt>s registered
+ * with this instance which may safely be iterated without the risk of a
+ * <tt>ConcurrentModificationException</tt>.
+ *
+ * @return a copy of the list of <tt>ScOtrKeyManagerListener<tt>s registered
+ * with this instance which may safely be iterated without the risk of a
+ * <tt>ConcurrentModificationException</tt>
+ */
+ private ScOtrKeyManagerListener[] getListeners()
+ {
+ synchronized (listeners)
+ {
+ return
+ listeners.toArray(
+ new ScOtrKeyManagerListener[listeners.size()]);
+ }
+ }
+
+ public void removeListener(ScOtrKeyManagerListener l)
+ {
+ synchronized (listeners)
+ {
+ listeners.remove(l);
+ }
+ }
+
+ public void verify(OtrContact otrContact, String fingerprint)
+ {
+ if ((fingerprint == null) || otrContact == null)
+ return;
+
+ this.configurator.setProperty(otrContact.contact.getAddress() + fingerprint
+ + ".fingerprint.verified", true);
+
+ for (ScOtrKeyManagerListener l : getListeners())
+ l.contactVerificationStatusChanged(otrContact);
+ }
+
+ public void unverify(OtrContact otrContact, String fingerprint)
+ {
+ if ((fingerprint == null) || otrContact == null)
+ return;
+
+ this.configurator.setProperty(otrContact.contact.getAddress() + fingerprint
+ + ".fingerprint.verified", false);
+
+ for (ScOtrKeyManagerListener l : getListeners())
+ l.contactVerificationStatusChanged(otrContact);
+ }
+
+ public boolean isVerified(Contact contact, String fingerprint)
+ {
+ if (fingerprint == null || contact == null)
+ return false;
+
+ return this.configurator.getPropertyBoolean(
+ contact.getAddress() + fingerprint
+ + ".fingerprint.verified", false);
+ }
+
+ public List<String> getAllRemoteFingerprints(Contact contact)
+ {
+ if (contact == null)
+ return null;
+
+ /*
+ * The following lines are needed for backward compatibility with old
+ * versions of the otr plugin. Instead of lists of fingerprints the otr
+ * plugin used to store one public key for every contact in the form of
+ * "userID.publicKey=..." and one boolean property in the form of
+ * "userID.publicKey.verified=...". In order not to loose these old
+ * properties we have to convert them to match the new format.
+ */
+ String userID = contact.getAddress();
+
+ byte[] b64PubKey =
+ this.configurator.getPropertyBytes(userID + ".publicKey");
+ if (b64PubKey != null)
+ {
+ // We delete the old format property because we are going to convert
+ // it in the new format
+ this.configurator.removeProperty(userID + ".publicKey");
+
+ X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64PubKey);
+
+ KeyFactory keyFactory;
+ try
+ {
+ keyFactory = KeyFactory.getInstance("DSA");
+ PublicKey pubKey = keyFactory.generatePublic(publicKeySpec);
+
+ boolean isVerified =
+ this.configurator.getPropertyBoolean(userID
+ + ".publicKey.verified", false);
+
+ // We also make sure to delete this old format property if it
+ // exists.
+ this.configurator.removeProperty(userID + ".publicKey.verified");
+
+ String fingerprint = getFingerprintFromPublicKey(pubKey);
+
+ // Now we can store the old properties in the new format.
+ if (isVerified)
+ verify(OtrContactManager.getOtrContact(contact, null), fingerprint);
+ else
+ unverify(OtrContactManager.getOtrContact(contact, null), fingerprint);
+
+ // Finally we append the new fingerprint to out stored list of
+ // fingerprints.
+ this.configurator.appendProperty(
+ userID + ".fingerprints", fingerprint);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ e.printStackTrace();
+ }
+ catch (InvalidKeySpecException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ // Now we can safely return our list of fingerprints for this contact
+ // without worrying that we missed an old format property.
+ return this.configurator.getAppendedProperties(
+ contact.getAddress() + ".fingerprints");
+ }
+
+ public String getFingerprintFromPublicKey(PublicKey pubKey)
+ {
+ try
+ {
+ return new OtrCryptoEngineImpl().getFingerprint(pubKey);
+ }
+ catch (OtrCryptoException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public String getLocalFingerprint(AccountID account)
+ {
+ KeyPair keyPair = loadKeyPair(account);
+
+ if (keyPair == null)
+ return null;
+
+ PublicKey pubKey = keyPair.getPublic();
+
+ try
+ {
+ return new OtrCryptoEngineImpl().getFingerprint(pubKey);
+ }
+ catch (OtrCryptoException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public byte[] getLocalFingerprintRaw(AccountID account)
+ {
+ KeyPair keyPair = loadKeyPair(account);
+
+ if (keyPair == null)
+ return null;
+
+ PublicKey pubKey = keyPair.getPublic();
+
+ try
+ {
+ return new OtrCryptoEngineImpl().getFingerprintRaw(pubKey);
+ }
+ catch (OtrCryptoException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public void saveFingerprint(Contact contact, String fingerprint)
+ {
+ if (contact == null)
+ return;
+
+ this.configurator.appendProperty(contact.getAddress() + ".fingerprints",
+ fingerprint);
+
+ this.configurator.setProperty(contact.getAddress() + fingerprint
+ + ".fingerprint.verified", false);
+ }
+
+ public KeyPair loadKeyPair(AccountID account)
+ {
+ if (account == null)
+ return null;
+
+ String accountID = account.getAccountUniqueID();
+ // Load Private Key.
+ byte[] b64PrivKey =
+ this.configurator.getPropertyBytes(accountID + ".privateKey");
+ if (b64PrivKey == null)
+ return null;
+
+ PKCS8EncodedKeySpec privateKeySpec =
+ new PKCS8EncodedKeySpec(b64PrivKey);
+
+ // Load Public Key.
+ byte[] b64PubKey =
+ this.configurator.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 void generateKeyPair(AccountID account)
+ {
+ if (account == null)
+ return;
+
+ String accountID = account.getAccountUniqueID();
+ 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.configurator.setProperty(accountID + ".publicKey",
+ x509EncodedKeySpec.getEncoded());
+
+ // Store Private Key.
+ PrivateKey privKey = keyPair.getPrivate();
+ PKCS8EncodedKeySpec pkcs8EncodedKeySpec =
+ new PKCS8EncodedKeySpec(privKey.getEncoded());
+
+ this.configurator.setProperty(accountID + ".privateKey",
+ pkcs8EncodedKeySpec.getEncoded());
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerListener.java b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerListener.java
index aeabf75..95403d3 100644
--- a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerListener.java
+++ b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerListener.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,15 +15,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.otr;
-
-import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
-
-/**
- *
- * @author George Politis
- */
-public interface ScOtrKeyManagerListener
-{
- public void contactVerificationStatusChanged(OtrContact contact);
-}
+package net.java.sip.communicator.plugin.otr;
+
+import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
+
+/**
+ *
+ * @author George Politis
+ */
+public interface ScOtrKeyManagerListener
+{
+ public void contactVerificationStatusChanged(OtrContact contact);
+}
diff --git a/src/net/java/sip/communicator/plugin/otr/ScSessionID.java b/src/net/java/sip/communicator/plugin/otr/ScSessionID.java
index 4392045..1a55fcd 100644
--- a/src/net/java/sip/communicator/plugin/otr/ScSessionID.java
+++ b/src/net/java/sip/communicator/plugin/otr/ScSessionID.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,83 +15,83 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.otr;
-
-import java.util.*;
-
-import net.java.otr4j.session.*;
-
-/**
- * Class used to associate a random UUID to an OTR4J SessionID.
- *
- * @author Daniel Perren
- */
-public class ScSessionID
-{
- private final UUID guid = UUID.randomUUID();
-
- private final SessionID sessionID;
-
- /**
- * Creates a new instance of this class.
- *
- * @param sessionID the OTR4J SessionID that is being wrapped.
- */
- public ScSessionID(SessionID sessionID)
- {
- this.sessionID = sessionID;
- }
-
- /**
- * Overrides equals() for the ability to get the hashcode from sessionID.
- *
- * @param obj the object to compare
- * @return true if the objects are considered equal.
- */
- @Override
- public boolean equals(Object obj)
- {
- return (obj != null) && sessionID.toString().equals(obj.toString());
- }
-
- /**
- * Get the current GUID.
- *
- * @return The GUID generated for this SessionID.
- */
- public UUID getGUID()
- {
- return guid;
- }
-
- /**
- * Gets the wrapped session ID
- *
- * @return sessionID
- */
- public SessionID getSessionID()
- {
- return sessionID;
- }
-
- /**
- * Returns {@link SessionID#hashCode()} of the wrapped SessionID.
- *
- * @return HashCode of the wrapped SessionID.
- */
- @Override
- public int hashCode()
- {
- return sessionID.hashCode();
- }
-
- /**
- * Returns {@link SessionID#toString()} of the wrapped SessionID.
- * @return String representation of the wrapped SessionID.
- */
- @Override
- public String toString()
- {
- return sessionID.toString();
- }
-}
+package net.java.sip.communicator.plugin.otr;
+
+import java.util.*;
+
+import net.java.otr4j.session.*;
+
+/**
+ * Class used to associate a random UUID to an OTR4J SessionID.
+ *
+ * @author Daniel Perren
+ */
+public class ScSessionID
+{
+ private final UUID guid = UUID.randomUUID();
+
+ private final SessionID sessionID;
+
+ /**
+ * Creates a new instance of this class.
+ *
+ * @param sessionID the OTR4J SessionID that is being wrapped.
+ */
+ public ScSessionID(SessionID sessionID)
+ {
+ this.sessionID = sessionID;
+ }
+
+ /**
+ * Overrides equals() for the ability to get the hashcode from sessionID.
+ *
+ * @param obj the object to compare
+ * @return true if the objects are considered equal.
+ */
+ @Override
+ public boolean equals(Object obj)
+ {
+ return (obj != null) && sessionID.toString().equals(obj.toString());
+ }
+
+ /**
+ * Get the current GUID.
+ *
+ * @return The GUID generated for this SessionID.
+ */
+ public UUID getGUID()
+ {
+ return guid;
+ }
+
+ /**
+ * Gets the wrapped session ID
+ *
+ * @return sessionID
+ */
+ public SessionID getSessionID()
+ {
+ return sessionID;
+ }
+
+ /**
+ * Returns {@link SessionID#hashCode()} of the wrapped SessionID.
+ *
+ * @return HashCode of the wrapped SessionID.
+ */
+ @Override
+ public int hashCode()
+ {
+ return sessionID.hashCode();
+ }
+
+ /**
+ * Returns {@link SessionID#toString()} of the wrapped SessionID.
+ * @return String representation of the wrapped SessionID.
+ */
+ @Override
+ public String toString()
+ {
+ return sessionID.toString();
+ }
+}