From 2a49a5de690b31bed35d4875a6f20bdfe3dfaf47 Mon Sep 17 00:00:00 2001 From: Damian Minkov Date: Wed, 31 Mar 2010 22:03:56 +0000 Subject: [PATCH] Implement use of Certificate Verification service in jabber. --- lib/installer-exclude/smack.jar | Bin 287855 -> 300461 bytes .../impl/protocol/jabber/JabberActivator.java | 26 ++ .../ProtocolProviderServiceJabberImpl.java | 336 +++++++++++++++++- .../jabber/jabber.provider.manifest.mf | 2 + 4 files changed, 361 insertions(+), 3 deletions(-) diff --git a/lib/installer-exclude/smack.jar b/lib/installer-exclude/smack.jar index 7acf9e10616a4d17742e7302a774595f02788454..e82c2f9c12632a65e974c715bf2fa0b49824edf9 100644 GIT binary patch delta 26072 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 WQAfLW(fx;^-x)0wlsaVqLjMQI*;ai3 delta 13295 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 diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/JabberActivator.java b/src/net/java/sip/communicator/impl/protocol/jabber/JabberActivator.java index 21f8bb1e5..4083aaa8f 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/JabberActivator.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/JabberActivator.java @@ -9,6 +9,7 @@ import java.util.*; import net.java.sip.communicator.service.configuration.*; +import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.service.gui.*; //import net.java.sip.communicator.service.media.*; import net.java.sip.communicator.service.protocol.*; @@ -42,6 +43,11 @@ public class JabberActivator */ private static ConfigurationService configurationService = null; + /** + * File access service. + */ + private static FileAccessService fileService = null; + /** * Media service. */ @@ -122,6 +128,26 @@ public static ConfigurationService getConfigurationService() return configurationService; } + /** + * Returns a reference to a FileAccessService implementation currently + * registered in the bundle context or null if no such implementation was + * found. + * + * @return a currently valid implementation of the FileAccessService. + */ + public static FileAccessService getFileAccessService() + { + if(fileService == null) + { + ServiceReference fileReference + = bundleContext.getServiceReference( + FileAccessService.class.getName()); + fileService + = (FileAccessService) bundleContext.getService(fileReference); + } + return fileService; + } + /** * Returns a reference to the bundle context that we were started with. * @return a reference to the BundleContext instance that we were started diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java index 5e00a8121..67a055f93 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java @@ -6,15 +6,20 @@ */ package net.java.sip.communicator.impl.protocol.jabber; +import java.io.*; import java.net.*; +import java.security.*; +import java.security.cert.*; import java.text.*; import java.util.*; +import javax.net.ssl.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.jabberconstants.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.impl.protocol.jabber.sasl.*; +import net.java.sip.communicator.service.gui.*; import org.jivesoftware.smack.*; import org.jivesoftware.smack.packet.*; @@ -22,6 +27,8 @@ import org.jivesoftware.smackx.*; import org.jivesoftware.smackx.packet.*; +import org.osgi.framework.*; + /** * An implementation of the protocol provider service over the Jabber protocol * @@ -113,6 +120,54 @@ public class ProtocolProviderServiceJabberImpl */ private JabberStatusEnum jabberStatusEnum; + /** + * The service we use to interact with user. + */ + private CertificateVerificationService guiVerification; + + /** + * + */ + private boolean additionalCertificateChecks = true; + + /** + * The key store holding stored certificate during previous sessions. + */ + private KeyStore keyStore; + + /** + * The property for the configuration value to store the + * KeyStore file location. + */ + private static final String KEYSTORE_FILE_PROP = + "net.java.sip.communicator.impl.protocol.sip.net.KEYSTORE"; + + /** + * The default password used for the keystore. + */ + private char[] defaultPassword = new char[0]; + + /** + * Used with tls connecting when certificates are not trusted + * and we ask the user to confirm connection. When some timeout expires + * connect method returns, and we use abortConnecting to abort further + * execution cause after user chooses we make further processing from there. + */ + private boolean abortConnecting = false; + + /** + * Used with tls. When certificate was confirmed we abort current + * connecting and try connecting again. + */ + private boolean abortConnectingAndReconnect = false; + + /** + * This are the certificates which are temporally allowed + * only for this session. + */ + private ArrayList temporalyAllowed = + new ArrayList(); + /** * Returns the state of the registration of this protocol provider * @return the RegistrationState that this provider is @@ -128,6 +183,27 @@ else if(connection.isConnected() && connection.isAuthenticated()) return RegistrationState.UNREGISTERED; } + /** + * Return the certificate verification service impl. + * @return the CertificateVerification service. + */ + private CertificateVerificationService getCertificateVerificationService() + { + if(guiVerification == null) + { + ServiceReference guiVerifyReference + = JabberActivator.getBundleContext().getServiceReference( + CertificateVerificationService.class.getName()); + if(guiVerifyReference != null) + guiVerification = (CertificateVerificationService) + JabberActivator.getBundleContext().getService( + guiVerifyReference); + } + + return guiVerification; + } + + /** * Starts the registration process. Connection details such as * registration server, user name/number are provided through the @@ -135,7 +211,7 @@ else if(connection.isConnected() && connection.isAuthenticated()) * * @param authority the security authority that will be used for resolving * any security challenges that may be returned during the - * registration or at any moment while wer're registered. + * registration or at any moment while we're registered. * @throws OperationFailedException with the corresponding code it the * registration fails for some reason (e.g. a networking error or an * implementation problem). @@ -423,9 +499,70 @@ else if(globalProxyType.equals( proxy ); confConn.setReconnectionAllowed(false); + confConn.setExpiredCertificatesCheckEnabled( + additionalCertificateChecks); + confConn.setNotMatchingDomainCheckEnabled( + additionalCertificateChecks); + + TrustManagerFactory tmFactory = null; + try + { + keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + keyStore.load(null, defaultPassword); + + String keyStoreFile = + JabberActivator.getConfigurationService() + .getString(KEYSTORE_FILE_PROP); + + if(keyStoreFile == null || keyStoreFile.length() == 0) + { + File f = JabberActivator.getFileAccessService() + .getPrivatePersistentFile("jssecacerts"); + keyStoreFile = f.getCanonicalPath(); + + JabberActivator.getConfigurationService() + .setProperty(KEYSTORE_FILE_PROP, keyStoreFile); + + keyStore.store( + new FileOutputStream(f), defaultPassword); + } + else + { + File f = new File(keyStoreFile); + if(!f.exists()) + { + // if for some reason file is missing, create it + // by saving the empty store + keyStore.store( + new FileOutputStream(f), defaultPassword); + } + + keyStore.load(new FileInputStream(keyStoreFile), null); + } + + String algorithm = KeyManagerFactory.getDefaultAlgorithm(); + tmFactory = TrustManagerFactory.getInstance(algorithm); + tmFactory.init(keyStore); + confConn.setKeystorePath(keyStoreFile); + } catch (Exception e) + { + logger.error("Cannot create key store", e); + } + connection = new XMPPConnection(confConn); + if(tmFactory != null) + { + connection.setCustomTrustManager( + new HostTrustManager( + (X509TrustManager)tmFactory.getTrustManagers()[0], + serverAddress, + Integer.parseInt(serverPort))); + } connection.connect(); + + connection.addConnectionListener( + new JabberConnectionListener()); } catch (XMPPException exc) { @@ -442,8 +579,20 @@ else if(globalProxyType.equals( , exc); } - connection.addConnectionListener( - new JabberConnectionListener()); + if(abortConnecting) + { + abortConnecting = false; + if(abortConnectingAndReconnect) + { + abortConnectingAndReconnect = false; + reregister(SecurityAuthority.CONNECTION_FAILED); + } + else + { + connection.disconnect(); + } + return; + } fireRegistrationStateChanged( getRegistrationState() @@ -487,6 +636,21 @@ else if(globalProxyType.equals( connection.addConnectionListener( new JabberConnectionListener()); + if(abortConnecting) + { + abortConnecting = false; + if(abortConnectingAndReconnect) + { + abortConnectingAndReconnect = false; + reregister(SecurityAuthority.CONNECTION_FAILED); + } + else + { + connection.disconnect(); + } + return; + } + fireRegistrationStateChanged( getRegistrationState() , RegistrationState.REGISTERING @@ -898,6 +1062,11 @@ public void connectionClosedOnError(Exception exception) "Connecting multiple times with the same resource"); return; } + } // Ignore certificate exceptions as we handle them elsewhere + else if(exception instanceof SSLHandshakeException && + exception.getCause() instanceof CertificateException) + { + return; } if(!reconnecting) @@ -1022,4 +1191,165 @@ String getFullJid(Contact contact) return presence.getFrom(); } + + /** + * The trust manager which asks the client whether to trust particular + * certificate which is not globally trusted. + */ + private class HostTrustManager + implements X509TrustManager + { + /** + * The address we connect to. + */ + String address; + + /** + * The port we connect to. + */ + int port; + + /** + * The default trust manager. + */ + private final X509TrustManager tm; + + /** + * Creates the custom trust manager. + * @param tm the default trust manager. + * @param address the address we are connecting to. + * @param port the port. + */ + HostTrustManager(X509TrustManager tm, String address, int port) + { + this.tm = tm; + this.port = port; + this.address = address; + } + + /** + * Not used. + * @return + */ + public X509Certificate[] getAcceptedIssuers() { + throw new UnsupportedOperationException(); + } + + /** + * Not used. + * @param chain the cert chain. + * @param authType authentication type like: RSA. + * @throws CertificateException + */ + public void checkClientTrusted(X509Certificate[] chain, String authType) + throws CertificateException + { + throw new UnsupportedOperationException(); + } + + /** + * Check whether a certificate is trusted, if not as user whether he + * trust it. + * @param chain the certificate chain. + * @param authType authentication type like: RSA. + * @throws CertificateException not trusted. + */ + public void checkServerTrusted(X509Certificate[] chain, String authType) + throws CertificateException + { + try + { + tm.checkServerTrusted(chain, authType); + } catch (Throwable certificateException) + { + try + { + for (int i = 0; i < chain.length; i++) + { + X509Certificate c = chain[i]; + + // check for temporaly allowed certs + if(temporalyAllowed.contains(c)) + { + return; + } + + // now check for permanent allow of certs + String alias = keyStore.getCertificateAlias(c); + if(alias != null) + return; + } + + CertificateVerificationService guiVerification = + getCertificateVerificationService(); + + if(guiVerification == null) + throw new CertificateException(certificateException.getMessage()); + + abortConnecting = true; + int result = guiVerification + .verificationNeeded(chain, address, port); + + if(result == CertificateVerificationService.DO_NOT_TRUST) + { + fireRegistrationStateChanged(getRegistrationState(), + RegistrationState.CONNECTION_FAILED, + RegistrationStateChangeEvent.REASON_USER_REQUEST, + "Not trusted certificate"); + return; + } + else if(result + == CertificateVerificationService.TRUST_THIS_SESSION_ONLY) + { + for (X509Certificate c : chain) + temporalyAllowed.add(c); + } + else if(result == CertificateVerificationService.TRUST_ALWAYS) + { + for (X509Certificate c : chain) + keyStore.setCertificateEntry( + String.valueOf(System.currentTimeMillis()), c); + } + + try + { + String keyStoreFile = JabberActivator.getConfigurationService() + .getString(KEYSTORE_FILE_PROP); + keyStore.store( + new FileOutputStream(keyStoreFile), defaultPassword); + } catch (Exception e) + { + logger.error("Error saving keystore.", e); + } + + if(abortConnecting) + { + abortConnectingAndReconnect = true; + return; + } + else + { + // register.connect in new thread so we can release the + // current connecting thread, otherwise this blocks + // jabber + new Thread(new Runnable() + { + public void run() + { + reregister(SecurityAuthority.CONNECTION_FAILED); + } + }).start(); + return; + } + } catch (KeyStoreException e) + { + // something happend + logger.error("Error trying to " + + "show certificate to user", e); + + throw new CertificateException(certificateException.getMessage()); + } + } + } + } } diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/jabber.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/jabber/jabber.provider.manifest.mf index 7e32c7a02..dfa3a86fd 100755 --- a/src/net/java/sip/communicator/impl/protocol/jabber/jabber.provider.manifest.mf +++ b/src/net/java/sip/communicator/impl/protocol/jabber/jabber.provider.manifest.mf @@ -24,6 +24,7 @@ Import-Package: org.osgi.framework, org.jivesoftware.smackx.filetransfer, org.jivesoftware.smackx.provider, net.java.sip.communicator.service.configuration, + net.java.sip.communicator.service.fileaccess, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.service.configuration.event, @@ -36,5 +37,6 @@ Import-Package: org.osgi.framework, org.xmlpull.v1, org.xmlpull.mxp1, javax.xml.parsers, + javax.net.ssl, javax.security.sasl, javax.security.auth.callback