Moved key management functionality from ScOtrEngineImpl to ScOtrKeyManager (new). Updated otr4j@112

cusax-fix
George Politis 17 years ago
parent 55b0e3520a
commit e2974c6817

Binary file not shown.

@ -19,16 +19,16 @@
* @author George Politis
*/
public class OtrActivator
implements BundleActivator,
ServiceListener
implements BundleActivator, ServiceListener
{
public static BundleContext bundleContext;
private OtrTransformLayer otrTransformLayer;
public static ScOtrEngine scOtrEngine;
public static ScOtrKeyManager scOtrKeyManager = new ScOtrKeyManagerImpl();
public static ResourceManagementService resourceService;
public static UIService uiService;
@ -45,8 +45,8 @@ public void start(BundleContext bc) throws Exception
scOtrEngine = new ScOtrEngineImpl();
otrTransformLayer = new OtrTransformLayer();
resourceService
= ResourceManagementServiceUtils
resourceService =
ResourceManagementServiceUtils
.getService(OtrActivator.bundleContext);
if (resourceService == null)
return;
@ -94,9 +94,9 @@ public void start(BundleContext bc) throws Exception
+ " already installed providers.");
for (ServiceReference protocolProviderRef : protocolProviderRefs)
{
ProtocolProviderService provider
= (ProtocolProviderService)
bundleContext.getService(protocolProviderRef);
ProtocolProviderService provider =
(ProtocolProviderService) bundleContext
.getService(protocolProviderRef);
this.handleProviderAdded(provider);
}
@ -189,9 +189,9 @@ public void stop(BundleContext bc) throws Exception
// in case we found any
for (ServiceReference protocolProviderRef : protocolProviderRefs)
{
ProtocolProviderService provider
= (ProtocolProviderService)
bundleContext.getService(protocolProviderRef);
ProtocolProviderService provider =
(ProtocolProviderService) bundleContext
.getService(protocolProviderRef);
this.handleProviderRemoved(provider);
}
@ -250,7 +250,52 @@ else if (serviceEvent.getType() == ServiceEvent.UNREGISTERING)
}
public static Map<Object, ProtocolProviderFactory> getProtocolProviderFactories()
public static List<AccountID> getAllAccountIDs()
{
Map<Object, ProtocolProviderFactory> providerFactoriesMap =
OtrActivator.getProtocolProviderFactories();
if (providerFactoriesMap == null)
return null;
List<AccountID> accountIDs = new Vector<AccountID>();
for (ProtocolProviderFactory providerFactory : providerFactoriesMap
.values())
{
for (AccountID accountID : providerFactory.getRegisteredAccounts())
{
accountIDs.add(accountID);
}
}
return accountIDs;
}
public static AccountID getAccountIDByUID(String uid)
{
if (uid == null || uid.length() < 1)
return null;
Map<Object, ProtocolProviderFactory> providerFactoriesMap =
OtrActivator.getProtocolProviderFactories();
if (providerFactoriesMap == null)
return null;
for (ProtocolProviderFactory providerFactory : providerFactoriesMap
.values())
{
for (AccountID accountID : providerFactory.getRegisteredAccounts())
{
if (accountID.getAccountUniqueID().equals(uid))
return accountID;
}
}
return null;
}
private static Map<Object, ProtocolProviderFactory> getProtocolProviderFactories()
{
ServiceReference[] serRefs = null;
try
@ -273,12 +318,11 @@ public static Map<Object, ProtocolProviderFactory> getProtocolProviderFactories(
{
for (ServiceReference serRef : serRefs)
{
ProtocolProviderFactory providerFactory
= (ProtocolProviderFactory)
bundleContext.getService(serRef);
ProtocolProviderFactory providerFactory =
(ProtocolProviderFactory) bundleContext.getService(serRef);
providerFactoriesMap.put(
serRef.getProperty(ProtocolProviderFactory.PROTOCOL),
providerFactoriesMap.put(serRef
.getProperty(ProtocolProviderFactory.PROTOCOL),
providerFactory);
}
}

@ -45,7 +45,7 @@ private void loadContact()
String account =
contact.getProtocolProvider().getAccountID().getDisplayName();
String localFingerprint =
OtrActivator.scOtrEngine.getLocalFingerprint(contact
OtrActivator.scOtrKeyManager.getLocalFingerprint(contact
.getProtocolProvider().getAccountID());
txtLocalFingerprint.setText(OtrActivator.resourceService.getI18NString(
"plugin.otr.authbuddydialog.LOCAL_FINGERPRINT", new String[]
@ -54,7 +54,7 @@ private void loadContact()
// Remote fingerprint.
String user = contact.getDisplayName();
String remoteFingerprint =
OtrActivator.scOtrEngine.getRemoteFingerprint(contact);
OtrActivator.scOtrKeyManager.getRemoteFingerprint(contact);
txtRemoteFingerprint.setText(OtrActivator.resourceService
.getI18NString("plugin.otr.authbuddydialog.REMOTE_FINGERPRINT",
new String[]
@ -153,8 +153,8 @@ private void initComponents()
new ActionComboBoxItem(ActionComboBoxItemIndex.I_HAVE_NOT);
cbAction.addItem(iHave);
cbAction.addItem(iHaveNot);
cbAction.setSelectedItem(OtrActivator.scOtrEngine
.isContactVerified(contact) ? iHave : iHaveNot);
cbAction.setSelectedItem(OtrActivator.scOtrKeyManager
.isVerified(contact) ? iHave : iHaveNot);
pnlAction.add(cbAction, c);
@ -209,10 +209,10 @@ public void actionPerformed(ActionEvent e)
switch (actionItem.action)
{
case I_HAVE:
OtrActivator.scOtrEngine.verifyContactFingerprint(contact);
OtrActivator.scOtrKeyManager.verify(contact);
break;
case I_HAVE_NOT:
OtrActivator.scOtrEngine.forgetContactFingerprint(contact);
OtrActivator.scOtrKeyManager.unverify(contact);
break;
}

@ -8,6 +8,7 @@
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
import javax.swing.*;
import javax.swing.border.*;
@ -55,21 +56,13 @@ public String toString()
public AccountsComboBox()
{
Map<Object, ProtocolProviderFactory> providerFactoriesMap =
OtrActivator.getProtocolProviderFactories();
List<AccountID> accountIDs = OtrActivator.getAllAccountIDs();
if (providerFactoriesMap == null)
if (accountIDs == null)
return;
for (ProtocolProviderFactory providerFactory : providerFactoriesMap
.values())
{
for (AccountID accountID : providerFactory
.getRegisteredAccounts())
{
this.addItem(new AccountsComboBoxItem(accountID));
}
}
for (AccountID accountID : accountIDs)
this.addItem(new AccountsComboBoxItem(accountID));
}
public AccountID getSelectedAccountID()
@ -111,7 +104,7 @@ private void openAccount(AccountID account)
btnGenerate.setEnabled(true);
String fingerprint =
OtrActivator.scOtrEngine.getLocalFingerprint(account);
OtrActivator.scOtrKeyManager.getLocalFingerprint(account);
if (fingerprint == null || fingerprint.length() < 1)
{
@ -166,8 +159,7 @@ public void actionPerformed(ActionEvent e)
AccountID account = cbAccounts.getSelectedAccountID();
if (account == null)
return;
OtrActivator.scOtrEngine.generateKeyPair(account
.getAccountUniqueID());
OtrActivator.scOtrKeyManager.generateKeyPair(account);
openAccount(account);
}
});
@ -267,10 +259,10 @@ public Object getValueAt(int row, int column)
case CONTACTNAME_INDEX:
return contact.getDisplayName();
case VERIFIED_INDEX:
return (OtrActivator.scOtrEngine.isContactVerified(contact)) ? "Yes"
return (OtrActivator.scOtrKeyManager.isVerified(contact)) ? "Yes"
: "No";
case FINGERPRINT_INDEX:
return OtrActivator.scOtrEngine
return OtrActivator.scOtrKeyManager
.getRemoteFingerprint(contact);
default:
return null;
@ -316,7 +308,7 @@ private void openContact(Contact contact)
else
{
boolean verified =
OtrActivator.scOtrEngine.isContactVerified(contact);
OtrActivator.scOtrKeyManager.isVerified(contact);
btnForgetFingerprint.setEnabled(verified);
btnVerifyFingerprint.setEnabled(!verified);
@ -371,8 +363,7 @@ public void valueChanged(ListSelectionEvent e)
{
public void actionPerformed(ActionEvent arg0)
{
OtrActivator.scOtrEngine
.verifyContactFingerprint(getSelectedContact());
OtrActivator.scOtrKeyManager.verify(getSelectedContact());
}
});
@ -384,8 +375,7 @@ public void actionPerformed(ActionEvent arg0)
{
public void actionPerformed(ActionEvent arg0)
{
OtrActivator.scOtrEngine
.forgetContactFingerprint(getSelectedContact());
OtrActivator.scOtrKeyManager.unverify(getSelectedContact());
}
});
pnlButtons.add(btnForgetFingerprint);

@ -0,0 +1,86 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license. See terms of license at gnu.org.
*/
package net.java.sip.communicator.plugin.otr;
import org.bouncycastle.util.encoders.*;
/**
*
* @author George Politis
*
*/
class Configurator
{
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);
}
private String getID(String id)
{
return "net.java.sip.communicator.plugin.otr."
+ getXmlFriendlyString(id);
}
public byte[] getPropertyBytes(String id)
{
String value =
(String) OtrActivator.configService.getProperty(this.getID(id));
if (value == null)
return null;
return Base64.decode(value.getBytes());
}
public Boolean getPropertyBoolean(String id, boolean defaultValue)
{
return OtrActivator.configService.getBoolean(this.getID(id),
defaultValue);
}
public void setProperty(String id, byte[] value)
{
String valueToStore = new String(Base64.encode(value));
OtrActivator.configService
.setProperty(this.getID(id), valueToStore);
}
public void setProperty(String id, boolean value)
{
OtrActivator.configService.setProperty(this.getID(id), value);
}
public void setProperty(String id, Integer value)
{
OtrActivator.configService.setProperty(this.getID(id), value);
}
public void removeProperty(String id)
{
OtrActivator.configService.removeProperty(this.getID(id));
}
public int getPropertyInt(String id, int defaultValue)
{
return OtrActivator.configService.getInt(getID(id), defaultValue);
}
}

@ -27,7 +27,7 @@ public OtrContactMenu(Contact contact)
{
this.contact = contact;
this.setText(contact.getDisplayName());
OtrActivator.scOtrEngine.addListener(new ScOtrEngineListener()
{
public void sessionStatusChanged(Contact contact)
@ -57,7 +57,10 @@ public void globalPolicyChanged()
setOtrPolicy(policy);
}
});
OtrActivator.scOtrKeyManager.addListener(new ScOtrKeyManagerListener()
{
public void contactVerificationStatusChanged(Contact contact)
{
SessionStatus status =
@ -67,7 +70,7 @@ public void contactVerificationStatusChanged(Contact contact)
setSessionStatus(status);
}
});
setSessionStatus(OtrActivator.scOtrEngine.getSessionStatus(contact));
setOtrPolicy(OtrActivator.scOtrEngine.getContactPolicy(contact));
}
@ -112,8 +115,8 @@ public void actionPerformed(ActionEvent e)
case ENCRYPTED:
this
.setIcon(OtrActivator.resourceService
.getImage((OtrActivator.scOtrEngine
.isContactVerified(contact))
.getImage((OtrActivator.scOtrKeyManager
.isVerified(contact))
? "plugin.otr.ENCRYPTED_ICON_16x16"
: "plugin.otr.ENCRYPTED_UNVERIFIED_ICON_16x16"));

@ -66,8 +66,11 @@ public void globalPolicyChanged()
if (OtrMetaContactButton.this.contact != null)
setPolicy(OtrActivator.scOtrEngine
.getContactPolicy(contact));
}
}
});
OtrActivator.scOtrKeyManager.addListener(new ScOtrKeyManagerListener()
{
public void contactVerificationStatusChanged(Contact contact)
{
// OtrMetaContactButton.this.contact can be null.
@ -79,7 +82,7 @@ public void contactVerificationStatusChanged(Contact contact)
}
});
this.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
@ -161,8 +164,8 @@ private void setStatus(SessionStatus status)
this
.setImage(ImageIO
.read(OtrActivator.resourceService
.getImageURL((OtrActivator.scOtrEngine
.isContactVerified(contact))
.getImageURL((OtrActivator.scOtrKeyManager
.isVerified(contact))
? "plugin.otr.ENCRYPTED_ICON_22x22"
: "plugin.otr.ENCRYPTED_UNVERIFIED_ICON_22x22")));
}

@ -29,19 +29,6 @@ public interface ScOtrEngine
public abstract SessionStatus getSessionStatus(Contact contact);
// New Methods (Key Management)
public abstract void generateKeyPair(String accountID);
public abstract String getRemoteFingerprint(Contact contact);
public abstract void verifyContactFingerprint(Contact contact);
public abstract void forgetContactFingerprint(Contact contact);
public abstract String getLocalFingerprint(AccountID account);
public abstract boolean isContactVerified(Contact contact);
// New Methods (Misc)
public abstract boolean isMessageUIDInjected(String messageUID);

@ -6,14 +6,11 @@
package net.java.sip.communicator.plugin.otr;
import java.security.*;
import java.security.spec.*;
import java.util.*;
import org.bouncycastle.util.encoders.*;
import org.osgi.framework.*;
import net.java.otr4j.*;
import net.java.otr4j.crypto.*;
import net.java.otr4j.session.*;
import net.java.sip.communicator.service.browserlauncher.*;
import net.java.sip.communicator.service.gui.*;
@ -33,12 +30,19 @@ public class ScOtrEngineImpl
public void addListener(ScOtrEngineListener l)
{
listeners.add(l);
synchronized (listeners)
{
if (!listeners.contains(l))
listeners.add(l);
}
}
public void removeListener(ScOtrEngineListener l)
{
listeners.remove(l);
synchronized (listeners)
{
listeners.remove(l);
}
}
private List<String> injectedMessageUIDs = new Vector<String>();
@ -48,26 +52,24 @@ public boolean isMessageUIDInjected(String mUID)
return injectedMessageUIDs.contains(mUID);
}
class ScOtrKeyManager
implements OtrKeyManager
class ScOtrEngineHost
implements OtrEngineHost
{
public KeyPair getKeyPair(SessionID sessionID)
{
String accountID = sessionID.getAccountID();
KeyPair keyPair = loadKeyPair(accountID);
AccountID accountID =
OtrActivator.getAccountIDByUID(sessionID.getAccountID());
KeyPair keyPair =
OtrActivator.scOtrKeyManager.loadKeyPair(accountID);
if (keyPair == null)
generateKeyPair(accountID);
OtrActivator.scOtrKeyManager.generateKeyPair(accountID);
return loadKeyPair(accountID);
return OtrActivator.scOtrKeyManager.loadKeyPair(accountID);
}
}
class ScOtrEngineHost
implements OtrEngineHost
{
public void showWarning(SessionID sessionID, String warn)
{
Contact contact = contactsMap.get(sessionID);
Contact contact = getContact(sessionID);
if (contact == null)
return;
@ -79,7 +81,7 @@ public void showWarning(SessionID sessionID, String warn)
public void showError(SessionID sessionID, String err)
{
Contact contact = contactsMap.get(sessionID);
Contact contact = getContact(sessionID);
if (contact == null)
return;
@ -91,7 +93,7 @@ public void showError(SessionID sessionID, String err)
public void injectMessage(SessionID sessionID, String messageText)
{
Contact contact = contactsMap.get(sessionID);
Contact contact = getContact(sessionID);
OperationSetBasicInstantMessaging imOpSet =
(OperationSetBasicInstantMessaging) contact
.getProtocolProvider().getOperationSet(
@ -104,87 +106,113 @@ public void injectMessage(SessionID sessionID, String messageText)
public OtrPolicy getSessionPolicy(SessionID sessionID)
{
return getContactPolicy(contactsMap.get(sessionID));
return getContactPolicy(getContact(sessionID));
}
}
public void sessionStatusChanged(SessionID sessionID)
public ScOtrEngineImpl()
{
this.otrEngine.addOtrEngineListener(new OtrEngineListener()
{
Contact contact = contactsMap.get(sessionID);
if (contact == null)
return;
String message = "";
switch (otrEngine.getSessionStatus(sessionID))
public void sessionStatusChanged(SessionID sessionID)
{
case ENCRYPTED:
PublicKey remotePubKey =
otrEngine.getRemotePublicKey(sessionID);
PublicKey storedPubKey = loadPublicKey(sessionID.getUserID());
Contact contact = getContact(sessionID);
if (contact == null)
return;
if (!remotePubKey.equals(storedPubKey))
savePublicKey(sessionID.getUserID(), remotePubKey);
if (!isContactVerified(contact))
String message = "";
switch (otrEngine.getSessionStatus(sessionID))
{
String unverifiedSessionWarning =
case ENCRYPTED:
PublicKey remotePubKey =
otrEngine.getRemotePublicKey(sessionID);
PublicKey storedPubKey =
OtrActivator.scOtrKeyManager.loadPublicKey(contact);
if (!remotePubKey.equals(storedPubKey))
OtrActivator.scOtrKeyManager.savePublicKey(contact,
remotePubKey);
if (!OtrActivator.scOtrKeyManager.isVerified(contact))
{
String unverifiedSessionWarning =
OtrActivator.resourceService
.getI18NString(
"plugin.otr.activator.unverifiedsessionwarning",
new String[]
{ contact.getDisplayName() });
OtrActivator.uiService.getChat(contact).addMessage(
contact.getDisplayName(),
System.currentTimeMillis(), Chat.SYSTEM_MESSAGE,
unverifiedSessionWarning,
OperationSetBasicInstantMessaging.HTML_MIME_TYPE);
}
message =
OtrActivator.resourceService
.getI18NString(
(OtrActivator.scOtrKeyManager
.isVerified(contact)) ? "plugin.otr.activator.sessionstared"
: "plugin.otr.activator.unverifiedsessionstared",
new String[]
{ contact.getDisplayName() });
break;
case FINISHED:
message =
OtrActivator.resourceService.getI18NString(
"plugin.otr.activator.unverifiedsessionwarning",
"plugin.otr.activator.sessionfinished",
new String[]
{ contact.getDisplayName() });
break;
case PLAINTEXT:
message =
OtrActivator.resourceService.getI18NString(
"plugin.otr.activator.sessionlost", new String[]
{ contact.getDisplayName() });
break;
}
OtrActivator.uiService.getChat(contact).addMessage(
contact.getDisplayName(), System.currentTimeMillis(),
Chat.SYSTEM_MESSAGE, unverifiedSessionWarning,
OperationSetBasicInstantMessaging.HTML_MIME_TYPE);
OtrActivator.uiService.getChat(contact).addMessage(
contact.getDisplayName(), System.currentTimeMillis(),
Chat.SYSTEM_MESSAGE, message,
OperationSetBasicInstantMessaging.HTML_MIME_TYPE);
for (ScOtrEngineListener l : listeners)
{
l.sessionStatusChanged(contact);
}
message =
OtrActivator.resourceService
.getI18NString(
(isContactVerified(contact)) ? "plugin.otr.activator.sessionstared"
: "plugin.otr.activator.unverifiedsessionstared",
new String[]
{ contact.getDisplayName() });
break;
case FINISHED:
message =
OtrActivator.resourceService.getI18NString(
"plugin.otr.activator.sessionfinished", new String[]
{ contact.getDisplayName() });
break;
case PLAINTEXT:
message =
OtrActivator.resourceService.getI18NString(
"plugin.otr.activator.sessionlost", new String[]
{ contact.getDisplayName() });
break;
}
});
}
OtrActivator.uiService.getChat(contact).addMessage(
contact.getDisplayName(), System.currentTimeMillis(),
Chat.SYSTEM_MESSAGE, message,
OperationSetBasicInstantMessaging.HTML_MIME_TYPE);
private OtrEngine otrEngine = new OtrEngineImpl(new ScOtrEngineHost());
for (ScOtrEngineListener l : listeners)
{
l.sessionStatusChanged(contact);
}
private static Map<SessionID, Contact> contactsMap =
new Hashtable<SessionID, Contact>();
public static SessionID getSessionID(Contact contact)
{
SessionID sessionID =
new SessionID(contact.getProtocolProvider().getAccountID()
.getAccountUniqueID(), contact.getAddress(), contact
.getProtocolProvider().getProtocolName());
synchronized (contactsMap)
{
contactsMap.put(sessionID, contact);
}
}
private OtrEngine otrEngine =
new OtrEngineImpl(new ScOtrEngineHost(), new ScOtrKeyManager());
return sessionID;
}
public boolean isContactVerified(Contact contact)
public static Contact getContact(SessionID sessionID)
{
return this.configurator.getPropertyBoolean(getSessionID(contact)
+ "publicKey.verified", false);
return contactsMap.get(sessionID);
}
Map<SessionID, Contact> contactsMap = new Hashtable<SessionID, Contact>();
public void endSession(Contact contact)
{
otrEngine.endSession(getSessionID(contact));
@ -215,159 +243,8 @@ public void startSession(Contact contact)
otrEngine.startSession(getSessionID(contact));
}
private SessionID getSessionID(Contact contact)
{
SessionID sessionID =
new SessionID(contact.getProtocolProvider().getAccountID()
.getAccountUniqueID(), contact.getAddress(), contact
.getProtocolProvider().getProtocolName());
contactsMap.put(sessionID, contact);
return sessionID;
}
public String getRemoteFingerprint(Contact contact)
{
PublicKey remotePublicKey = loadPublicKey(contact.getAddress());
if (remotePublicKey == null)
return null;
try
{
return new OtrCryptoEngineImpl().getFingerprint(remotePublicKey);
}
catch (OtrCryptoException e)
{
e.printStackTrace();
return null;
}
}
public String getLocalFingerprint(AccountID account)
{
KeyPair keyPair = loadKeyPair(account.getAccountUniqueID());
if (keyPair == null)
return null;
PublicKey pubKey = keyPair.getPublic();
try
{
return new OtrCryptoEngineImpl().getFingerprint(pubKey);
}
catch (OtrCryptoException e)
{
e.printStackTrace();
return null;
}
}
private Configurator configurator = new Configurator();
class Configurator
{
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);
}
private String getID(String id)
{
return "net.java.sip.communicator.plugin.otr."
+ getXmlFriendlyString(id);
}
public byte[] getPropertyBytes(String id)
{
String value =
(String) OtrActivator.configService.getProperty(this.getID(id));
if (value == null)
return null;
return Base64.decode(value.getBytes());
}
public Boolean getPropertyBoolean(String id, boolean defaultValue)
{
return OtrActivator.configService.getBoolean(this.getID(id),
defaultValue);
}
public void setProperty(String id, byte[] value)
{
String valueToStore = new String(Base64.encode(value));
OtrActivator.configService
.setProperty(this.getID(id), valueToStore);
}
public void setProperty(String id, boolean value)
{
OtrActivator.configService.setProperty(this.getID(id), value);
}
public void setProperty(String id, Integer value)
{
OtrActivator.configService.setProperty(this.getID(id), value);
}
public void removeProperty(String id)
{
OtrActivator.configService.removeProperty(this.getID(id));
}
public int getPropertyInt(String id, int defaultValue)
{
return OtrActivator.configService.getInt(getID(id), defaultValue);
}
}
public void verifyContactFingerprint(Contact contact)
{
if (contact == null)
return;
if (isContactVerified(contact))
return;
this.configurator.setProperty(getSessionID(contact)
+ "publicKey.verified", true);
for (ScOtrEngineListener l : listeners)
l.contactVerificationStatusChanged(contact);
}
public void forgetContactFingerprint(Contact contact)
{
if (contact == null)
return;
if (!isContactVerified(contact))
return;
this.configurator.removeProperty(getSessionID(contact)
+ "publicKey.verified");
for (ScOtrEngineListener l : listeners)
l.contactVerificationStatusChanged(contact);
}
public OtrPolicy getGlobalPolicy()
{
return new OtrPolicyImpl(this.configurator.getPropertyInt("POLICY",
@ -424,117 +301,4 @@ public void setContactPolicy(Contact contact, OtrPolicy policy)
l.contactPolicyChanged(contact);
}
private KeyPair loadKeyPair(String accountID)
{
// 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(String accountID)
{
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());
}
private void savePublicKey(String userID, PublicKey pubKey)
{
X509EncodedKeySpec x509EncodedKeySpec =
new X509EncodedKeySpec(pubKey.getEncoded());
this.configurator.setProperty(userID + ".publicKey", x509EncodedKeySpec
.getEncoded());
this.configurator.removeProperty(userID + ".publicKey.verified");
}
private PublicKey loadPublicKey(String userID)
{
byte[] b64PubKey =
this.configurator.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;
}
}
}

@ -14,8 +14,6 @@
*/
public interface ScOtrEngineListener
{
public abstract void contactVerificationStatusChanged(Contact contact);
public abstract void sessionStatusChanged(Contact contact);
public abstract void contactPolicyChanged(Contact contact);

@ -0,0 +1,42 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license. See terms of license at gnu.org.
*/
package net.java.sip.communicator.plugin.otr;
import java.security.*;
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(Contact contact);
public abstract void unverify(Contact contact);
public abstract boolean isVerified(Contact contact);
public abstract String getRemoteFingerprint(Contact contact);
public abstract String getLocalFingerprint(AccountID account);
public abstract void savePublicKey(Contact contact, PublicKey pubKey);
public abstract PublicKey loadPublicKey(Contact contact);
public abstract KeyPair loadKeyPair(AccountID accountID);
public abstract void generateKeyPair(AccountID accountID);
}

@ -0,0 +1,243 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license. See terms of license at gnu.org.
*/
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.service.protocol.*;
/**
*
* @author George Politis
*
*/
public class ScOtrKeyManagerImpl
implements ScOtrKeyManager
{
private List<ScOtrKeyManagerListener> listeners =
new Vector<ScOtrKeyManagerListener>();
public void addListener(ScOtrKeyManagerListener l)
{
synchronized (listeners)
{
if (!listeners.contains(l))
listeners.add(l);
}
}
public void removeListener(ScOtrKeyManagerListener l)
{
synchronized (listeners)
{
listeners.remove(l);
}
}
private Configurator configurator = new Configurator();
public void verify(Contact contact)
{
if (contact == null)
return;
if (this.isVerified(contact))
return;
this.configurator.setProperty(contact.getAddress()
+ ".publicKey.verified", true);
for (ScOtrKeyManagerListener l : listeners)
l.contactVerificationStatusChanged(contact);
}
public void unverify(Contact contact)
{
if (contact == null)
return;
if (!isVerified(contact))
return;
this.configurator.removeProperty(contact.getAddress()
+ ".publicKey.verified");
for (ScOtrKeyManagerListener l : listeners)
l.contactVerificationStatusChanged(contact);
}
public boolean isVerified(Contact contact)
{
if (contact == null)
return false;
return this.configurator.getPropertyBoolean(contact.getAddress()
+ ".publicKey.verified", false);
}
public String getRemoteFingerprint(Contact contact)
{
PublicKey remotePublicKey = loadPublicKey(contact);
if (remotePublicKey == null)
return null;
try
{
return new OtrCryptoEngineImpl().getFingerprint(remotePublicKey);
}
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 void savePublicKey(Contact contact, PublicKey pubKey)
{
if (contact == null)
return;
X509EncodedKeySpec x509EncodedKeySpec =
new X509EncodedKeySpec(pubKey.getEncoded());
this.configurator.setProperty(contact.getAddress() + ".publicKey",
x509EncodedKeySpec.getEncoded());
this.configurator.removeProperty(contact.getAddress()
+ ".publicKey.verified");
}
public PublicKey loadPublicKey(Contact contact)
{
if (contact == null)
return null;
String userID = contact.getAddress();
byte[] b64PubKey =
this.configurator.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 KeyPair loadKeyPair(AccountID account)
{
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)
{
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());
}
}

@ -0,0 +1,18 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license. See terms of license at gnu.org.
*/
package net.java.sip.communicator.plugin.otr;
import net.java.sip.communicator.service.protocol.*;
/**
*
* @author George Politis
*
*/
public interface ScOtrKeyManagerListener
{
public abstract void contactVerificationStatusChanged(Contact contact);
}
Loading…
Cancel
Save