summaryrefslogtreecommitdiff
path: root/java/src/IceSSL/Instance.java
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2014-05-29 11:06:44 -0700
committerMark Spruiell <mes@zeroc.com>2014-05-29 11:06:44 -0700
commit3cfd324cdcc65d2acbc7536f1652d44f66a0e896 (patch)
tree44613394c5b9c6c6eb0ec8b41e110002a58d60ea /java/src/IceSSL/Instance.java
parentFixed Python throughput demo config (diff)
downloadice-3cfd324cdcc65d2acbc7536f1652d44f66a0e896.tar.bz2
ice-3cfd324cdcc65d2acbc7536f1652d44f66a0e896.tar.xz
ice-3cfd324cdcc65d2acbc7536f1652d44f66a0e896.zip
porting C++ transport changes to Java
Diffstat (limited to 'java/src/IceSSL/Instance.java')
-rw-r--r--java/src/IceSSL/Instance.java1184
1 files changed, 21 insertions, 1163 deletions
diff --git a/java/src/IceSSL/Instance.java b/java/src/IceSSL/Instance.java
index 741199480b5..944d6d95074 100644
--- a/java/src/IceSSL/Instance.java
+++ b/java/src/IceSSL/Instance.java
@@ -13,1196 +13,54 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
-class Instance
+class Instance extends IceInternal.ProtocolInstance
{
- Instance(Ice.Communicator communicator)
+ Instance(SharedInstance sharedInstance, short type, String protocol)
{
- _logger = communicator.getLogger();
- _facade = IceInternal.Util.getProtocolPluginFacade(communicator);
- _securityTraceLevel = communicator.getProperties().getPropertyAsIntWithDefault("IceSSL.Trace.Security", 0);
- _securityTraceCategory = "Security";
- _trustManager = new TrustManager(communicator);
-
- //
- // Register the endpoint factory. We have to do this now, rather than
- // in initialize, because the communicator may need to interpret
- // proxies before the plug-in is fully initialized.
- //
- _facade.addEndpointFactory(new EndpointFactoryI(this));
- }
-
- void
- initialize()
- {
- if(_initialized)
- {
- return;
- }
-
- final String prefix = "IceSSL.";
- Ice.Properties properties = communicator().getProperties();
-
- //
- // Parse the cipher list.
- //
- String ciphers = properties.getProperty(prefix + "Ciphers");
- if(ciphers.length() > 0)
- {
- parseCiphers(ciphers);
- }
-
- //
- // Select protocols.
- //
- String[] protocols = properties.getPropertyAsList(prefix + "Protocols");
- if(protocols.length != 0)
- {
- java.util.ArrayList<String> l = new java.util.ArrayList<String>();
- for(String prot : protocols)
- {
- String s = prot.toLowerCase();
- if(s.equals("ssl3") || s.equals("sslv3"))
- {
- l.add("SSLv3");
- }
- else if(s.equals("tls") || s.equals("tls1") || s.equals("tlsv1") || s.equals("tls1_0") ||
- s.equals("tlsv1_0"))
- {
- l.add("TLSv1");
- }
- else if(s.equals("tls1_1") || s.equals("tlsv1_1"))
- {
- l.add("TLSv1.1");
- }
- else if(s.equals("tls1_2") || s.equals("tlsv1_2"))
- {
- l.add("TLSv1.2");
- }
- else
- {
- Ice.PluginInitializationException e = new Ice.PluginInitializationException();
- e.reason = "IceSSL: unrecognized protocol `" + prot + "'";
- throw e;
- }
- }
- _protocols = new String[l.size()];
- l.toArray(_protocols);
- }
-
- //
- // CheckCertName determines whether we compare the name in a peer's
- // certificate against its hostname.
- //
- _checkCertName = properties.getPropertyAsIntWithDefault(prefix + "CheckCertName", 0) > 0;
-
- //
- // VerifyDepthMax establishes the maximum length of a peer's certificate
- // chain, including the peer's certificate. A value of 0 means there is
- // no maximum.
- //
- _verifyDepthMax = properties.getPropertyAsIntWithDefault(prefix + "VerifyDepthMax", 2);
-
- //
- // VerifyPeer determines whether certificate validation failures abort a connection.
- //
- _verifyPeer = communicator().getProperties().getPropertyAsIntWithDefault("IceSSL.VerifyPeer", 2);
-
- //
- // Check for a certificate verifier.
- //
- final String certVerifierClass = properties.getProperty(prefix + "CertVerifier");
- if(certVerifierClass.length() > 0)
- {
- if(_verifier != null)
- {
- Ice.PluginInitializationException e = new Ice.PluginInitializationException();
- e.reason = "IceSSL: certificate verifier already installed";
- throw e;
- }
-
- Class<?> cls = null;
- try
- {
- cls = _facade.findClass(certVerifierClass);
- }
- catch(Throwable ex)
- {
- throw new Ice.PluginInitializationException(
- "IceSSL: unable to load certificate verifier class " + certVerifierClass, ex);
- }
-
- try
- {
- _verifier = (CertificateVerifier)cls.newInstance();
- }
- catch(Throwable ex)
- {
- throw new Ice.PluginInitializationException(
- "IceSSL: unable to instantiate certificate verifier class " + certVerifierClass, ex);
- }
- }
-
- //
- // Check for a password callback.
- //
- final String passwordCallbackClass = properties.getProperty(prefix + "PasswordCallback");
- if(passwordCallbackClass.length() > 0)
- {
- if(_passwordCallback != null)
- {
- Ice.PluginInitializationException e = new Ice.PluginInitializationException();
- e.reason = "IceSSL: password callback already installed";
- throw e;
- }
-
- Class<?> cls = null;
- try
- {
- cls = _facade.findClass(passwordCallbackClass);
- }
- catch(Throwable ex)
- {
- throw new Ice.PluginInitializationException(
- "IceSSL: unable to load password callback class " + passwordCallbackClass, ex);
- }
-
- try
- {
- _passwordCallback = (PasswordCallback)cls.newInstance();
- }
- catch(Throwable ex)
- {
- throw new Ice.PluginInitializationException(
- "IceSSL: unable to instantiate password callback class " + passwordCallbackClass, ex);
- }
- }
-
- //
- // If the user doesn't supply an SSLContext, we need to create one based
- // on property settings.
- //
- if(_context == null)
- {
- try
- {
- //
- // Check for a default directory. We look in this directory for
- // files mentioned in the configuration.
- //
- _defaultDir = properties.getProperty(prefix + "DefaultDir");
-
- //
- // We need a SecureRandom object.
- //
- // NOTE: The JDK recommends obtaining a SecureRandom object like this:
- //
- // java.security.SecureRandom rand = java.security.SecureRandom.getInstance("SHA1PRNG");
- //
- // However, there is a bug (6202721) which causes it to always use /dev/random,
- // which can lead to long delays at program startup. The workaround is to use
- // the default constructor.
- //
- java.security.SecureRandom rand = new java.security.SecureRandom();
-
- //
- // Check for seed data for the random number generator.
- //
- final String seedFiles = properties.getProperty(prefix + "Random");
- if(seedFiles.length() > 0)
- {
- final String[] arr = seedFiles.split(java.io.File.pathSeparator);
- for(String file : arr)
- {
- try
- {
- java.io.InputStream seedStream = openResource(file);
- if(seedStream == null)
- {
- Ice.PluginInitializationException e = new Ice.PluginInitializationException();
- e.reason = "IceSSL: random seed file not found:\n" + file;
- throw e;
- }
-
- _seeds.add(seedStream);
- }
- catch(java.io.IOException ex)
- {
- throw new Ice.PluginInitializationException(
- "IceSSL: unable to access random seed file:\n" + file, ex);
- }
- }
- }
-
- if(!_seeds.isEmpty())
- {
- byte[] seed = null;
- int start = 0;
- for(InputStream in : _seeds)
- {
- try
- {
- int num = in.available();
- if(seed == null)
- {
- seed = new byte[num];
- }
- else
- {
- byte[] tmp = new byte[seed.length + num];
- System.arraycopy(seed, 0, tmp, 0, seed.length);
- start = seed.length;
- seed = tmp;
- }
- in.read(seed, start, num);
- }
- catch(java.io.IOException ex)
- {
- throw new Ice.PluginInitializationException("IceSSL: error while reading random seed", ex);
- }
- finally
- {
- try
- {
- in.close();
- }
- catch(java.io.IOException e)
- {
- // Ignore.
- }
- }
- }
- rand.setSeed(seed);
- }
- _seeds.clear();
-
- //
- // We call nextInt() in order to force the object to perform any time-consuming
- // initialization tasks now.
- //
- rand.nextInt();
-
- //
- // The keystore holds private keys and associated certificates.
- //
- String keystorePath = properties.getProperty(prefix + "Keystore");
-
- //
- // The password for the keys.
- //
- String password = properties.getProperty(prefix + "Password");
-
- //
- // The password for the keystore.
- //
- String keystorePassword = properties.getProperty(prefix + "KeystorePassword");
-
- //
- // The default keystore type is usually "JKS", but the legal values are determined
- // by the JVM implementation. Other possibilities include "PKCS12" and "BKS".
- //
- final String defaultType = java.security.KeyStore.getDefaultType();
- final String keystoreType = properties.getPropertyWithDefault(prefix + "KeystoreType", defaultType);
-
- //
- // The alias of the key to use in authentication.
- //
- final String alias = properties.getProperty(prefix + "Alias");
-
- //
- // The truststore holds the certificates of trusted CAs.
- //
- String truststorePath = properties.getProperty(prefix + "Truststore");
-
- //
- // The password for the truststore.
- //
- String truststorePassword = properties.getProperty(prefix + "TruststorePassword");
-
- //
- // The default truststore type is usually "JKS", but the legal values are determined
- // by the JVM implementation. Other possibilities include "PKCS12" and "BKS".
- //
- final String truststoreType =
- properties.getPropertyWithDefault(prefix + "TruststoreType",
- java.security.KeyStore.getDefaultType());
-
- //
- // Collect the key managers.
- //
- javax.net.ssl.KeyManager[] keyManagers = null;
- java.security.KeyStore keys = null;
- if(_keystoreStream != null || keystorePath.length() > 0)
- {
- java.io.InputStream keystoreStream = null;
- try
- {
- if(_keystoreStream != null)
- {
- keystoreStream = _keystoreStream;
- }
- else
- {
- keystoreStream = openResource(keystorePath);
- if(keystoreStream == null)
- {
- Ice.PluginInitializationException e = new Ice.PluginInitializationException();
- e.reason = "IceSSL: keystore not found:\n" + keystorePath;
- throw e;
- }
- }
-
- keys = java.security.KeyStore.getInstance(keystoreType);
- char[] passwordChars = null;
- if(keystorePassword.length() > 0)
- {
- passwordChars = keystorePassword.toCharArray();
- }
- else if(_passwordCallback != null)
- {
- passwordChars = _passwordCallback.getKeystorePassword();
- }
- else if(keystoreType.equals("BKS"))
- {
- // Bouncy Castle does not permit null passwords.
- passwordChars = new char[0];
- }
-
- keys.load(keystoreStream, passwordChars);
-
- if(passwordChars != null)
- {
- java.util.Arrays.fill(passwordChars, '\0');
- }
- keystorePassword = null;
- }
- catch(java.io.IOException ex)
- {
- throw new Ice.PluginInitializationException(
- "IceSSL: unable to load keystore:\n" + keystorePath, ex);
- }
- finally
- {
- if(keystoreStream != null)
- {
- try
- {
- keystoreStream.close();
- }
- catch(java.io.IOException e)
- {
- // Ignore.
- }
- }
- }
-
- String algorithm = javax.net.ssl.KeyManagerFactory.getDefaultAlgorithm();
- javax.net.ssl.KeyManagerFactory kmf = javax.net.ssl.KeyManagerFactory.getInstance(algorithm);
- char[] passwordChars = new char[0]; // This password cannot be null.
- if(password.length() > 0)
- {
- passwordChars = password.toCharArray();
- }
- else if(_passwordCallback != null)
- {
- passwordChars = _passwordCallback.getPassword(alias);
- }
- kmf.init(keys, passwordChars);
- if(passwordChars.length > 0)
- {
- java.util.Arrays.fill(passwordChars, '\0');
- }
- password = null;
- keyManagers = kmf.getKeyManagers();
-
- //
- // If the user selected a specific alias, we need to wrap the key managers
- // in order to return the desired alias.
- //
- if(alias.length() > 0)
- {
- if(!keys.isKeyEntry(alias))
- {
- Ice.PluginInitializationException e = new Ice.PluginInitializationException();
- e.reason = "IceSSL: keystore does not contain an entry with alias `" + alias + "'";
- throw e;
- }
-
- for(int i = 0; i < keyManagers.length; ++i)
- {
- keyManagers[i] = new X509KeyManagerI((javax.net.ssl.X509KeyManager)keyManagers[i], alias);
- }
- }
- }
-
- //
- // Load the truststore.
- //
- java.security.KeyStore ts = null;
- if(_truststoreStream != null || truststorePath.length() > 0)
- {
- //
- // If the trust store and the key store are the same input
- // stream or file, don't create another key store.
- //
- if((_truststoreStream != null && _truststoreStream == _keystoreStream) ||
- (truststorePath.length() > 0 && truststorePath.equals(keystorePath)))
- {
- assert keys != null;
- ts = keys;
- }
- else
- {
- java.io.InputStream truststoreStream = null;
- try
- {
- if(_truststoreStream != null)
- {
- truststoreStream = _truststoreStream;
- }
- else
- {
- truststoreStream = openResource(truststorePath);
- if(truststoreStream == null)
- {
- Ice.PluginInitializationException e = new Ice.PluginInitializationException();
- e.reason = "IceSSL: truststore not found:\n" + truststorePath;
- throw e;
- }
- }
-
- ts = java.security.KeyStore.getInstance(truststoreType);
-
- char[] passwordChars = null;
- if(truststorePassword.length() > 0)
- {
- passwordChars = truststorePassword.toCharArray();
- }
- else if(_passwordCallback != null)
- {
- passwordChars = _passwordCallback.getTruststorePassword();
- }
- else if(truststoreType.equals("BKS"))
- {
- // Bouncy Castle does not permit null passwords.
- passwordChars = new char[0];
- }
-
- ts.load(truststoreStream, passwordChars);
-
- if(passwordChars != null)
- {
- java.util.Arrays.fill(passwordChars, '\0');
- }
- truststorePassword = null;
- }
- catch(java.io.IOException ex)
- {
- throw new Ice.PluginInitializationException(
- "IceSSL: unable to load truststore:\n" + truststorePath, ex);
- }
- finally
- {
- if(truststoreStream != null)
- {
- try
- {
- truststoreStream.close();
- }
- catch(java.io.IOException e)
- {
- // Ignore.
- }
- }
- }
- }
- }
- else
- {
- ts = keys;
- }
-
- //
- // Collect the trust managers.
- //
- javax.net.ssl.TrustManager[] trustManagers = null;
- {
- String algorithm = javax.net.ssl.TrustManagerFactory.getDefaultAlgorithm();
- javax.net.ssl.TrustManagerFactory tmf = javax.net.ssl.TrustManagerFactory.getInstance(algorithm);
- tmf.init(ts);
- trustManagers = tmf.getTrustManagers();
- assert(trustManagers != null);
- }
-
- //
- // Wrap each trust manager.
- //
- for(int i = 0; i < trustManagers.length; ++i)
- {
- trustManagers[i] = new X509TrustManagerI(this, (javax.net.ssl.X509TrustManager)trustManagers[i]);
- }
-
- //
- // Initialize the SSL context.
- //
- _context = javax.net.ssl.SSLContext.getInstance("TLS");
- _context.init(keyManagers, trustManagers, rand);
- }
- catch(java.security.GeneralSecurityException ex)
- {
- throw new Ice.PluginInitializationException("IceSSL: unable to initialize context", ex);
- }
- }
-
- //
- // Clear cached input streams.
- //
- _seeds.clear();
- _keystoreStream = null;
- _truststoreStream = null;
-
- _initialized = true;
- }
-
- void
- context(javax.net.ssl.SSLContext context)
- {
- if(_initialized)
- {
- Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
- ex.reason = "IceSSL: plug-in is already initialized";
- throw ex;
- }
-
- _context = context;
- }
-
- javax.net.ssl.SSLContext
- context()
- {
- return _context;
- }
-
- void
- setCertificateVerifier(CertificateVerifier verifier)
- {
- _verifier = verifier;
- }
-
- CertificateVerifier
- getCertificateVerifier()
- {
- return _verifier;
- }
-
- void
- setPasswordCallback(PasswordCallback callback)
- {
- _passwordCallback = callback;
- }
-
- PasswordCallback
- getPasswordCallback()
- {
- return _passwordCallback;
- }
-
- void
- setKeystoreStream(java.io.InputStream stream)
- {
- if(_initialized)
- {
- Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
- ex.reason = "IceSSL: plugin is already initialized";
- throw ex;
- }
-
- _keystoreStream = stream;
- }
-
- void
- setTruststoreStream(java.io.InputStream stream)
- {
- if(_initialized)
- {
- Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
- ex.reason = "IceSSL: plugin is already initialized";
- throw ex;
- }
-
- _truststoreStream = stream;
- }
-
- void
- addSeedStream(java.io.InputStream stream)
- {
- _seeds.add(stream);
- }
-
- Ice.Communicator
- communicator()
- {
- return _facade.getCommunicator();
- }
-
- IceInternal.EndpointHostResolver
- endpointHostResolver()
- {
- return _facade.getEndpointHostResolver();
- }
-
- int
- protocolSupport()
- {
- return _facade.getProtocolSupport();
- }
-
- boolean
- preferIPv6()
- {
- return _facade.getPreferIPv6();
+ super(sharedInstance.communicator(), type, protocol);
+ _sharedInstance = sharedInstance;
}
- Ice.EncodingVersion
- defaultEncoding()
+ SharedInstance sharedInstance()
{
- return _facade.getDefaultEncoding();
+ return _sharedInstance;
}
- String
- defaultHost()
+ int securityTraceLevel()
{
- return _facade.getDefaultHost();
+ return _sharedInstance.securityTraceLevel();
}
- int
- networkTraceLevel()
+ String securityTraceCategory()
{
- return _facade.getNetworkTraceLevel();
+ return _sharedInstance.securityTraceCategory();
}
- String
- networkTraceCategory()
+ boolean initialized()
{
- return _facade.getNetworkTraceCategory();
+ return _sharedInstance.initialized();
}
- int
- securityTraceLevel()
+ javax.net.ssl.SSLEngine createSSLEngine(boolean incoming, java.net.InetSocketAddress peerAddr)
{
- return _securityTraceLevel;
+ return _sharedInstance.createSSLEngine(incoming, peerAddr);
}
- String
- securityTraceCategory()
+ void traceConnection(java.nio.channels.SocketChannel fd, javax.net.ssl.SSLEngine engine, boolean incoming)
{
- return _securityTraceCategory;
+ _sharedInstance.traceConnection(fd, engine, incoming);
}
- boolean
- initialized()
+ void verifyPeer(NativeConnectionInfo info, java.nio.channels.SelectableChannel fd, String address)
{
- return _initialized;
+ _sharedInstance.verifyPeer(info, fd, address);
}
- javax.net.ssl.SSLEngine
- createSSLEngine(boolean incoming, java.net.InetSocketAddress peerAddr)
- {
- javax.net.ssl.SSLEngine engine;
- if(peerAddr != null)
- {
- engine = _context.createSSLEngine(peerAddr.getAddress().getHostAddress(), peerAddr.getPort());
- }
- else
- {
- engine = _context.createSSLEngine();
- }
- engine.setUseClientMode(!incoming);
-
- String[] cipherSuites = filterCiphers(engine.getSupportedCipherSuites(), engine.getEnabledCipherSuites());
- try
- {
- engine.setEnabledCipherSuites(cipherSuites);
- }
- catch(IllegalArgumentException ex)
- {
- throw new Ice.SecurityException("IceSSL: invalid ciphersuite", ex);
- }
-
- if(_securityTraceLevel >= 1)
- {
- StringBuilder s = new StringBuilder(128);
- s.append("enabling SSL ciphersuites:");
- for(String suite : cipherSuites)
- {
- s.append("\n ");
- s.append(suite);
- }
- _logger.trace(_securityTraceCategory, s.toString());
- }
-
- if(_protocols != null)
- {
- try
- {
- engine.setEnabledProtocols(_protocols);
- }
- catch(IllegalArgumentException ex)
- {
- throw new Ice.SecurityException("IceSSL: invalid protocol", ex);
- }
- }
-
- if(incoming)
- {
- if(_verifyPeer == 0)
- {
- engine.setWantClientAuth(false);
- engine.setNeedClientAuth(false);
- }
- else if(_verifyPeer == 1)
- {
- engine.setWantClientAuth(true);
- }
- else
- {
- engine.setNeedClientAuth(true);
- }
- }
-
- try
- {
- engine.beginHandshake();
- }
- catch(javax.net.ssl.SSLException ex)
- {
- throw new Ice.SecurityException("IceSSL: handshake error", ex);
- }
-
- return engine;
- }
-
- String[]
- filterCiphers(String[] supportedCiphers, String[] defaultCiphers)
- {
- java.util.LinkedList<String> result = new java.util.LinkedList<String>();
- if(_allCiphers)
- {
- for(String cipher : supportedCiphers)
- {
- result.add(cipher);
- }
- }
- else if(!_noCiphers)
- {
- for(String cipher : defaultCiphers)
- {
- result.add(cipher);
- }
- }
-
- if(_ciphers != null)
- {
- for(CipherExpression ce : _ciphers)
- {
- if(ce.not)
- {
- java.util.Iterator<String> e = result.iterator();
- while(e.hasNext())
- {
- String cipher = e.next();
- if(ce.cipher != null)
- {
- if(ce.cipher.equals(cipher))
- {
- e.remove();
- }
- }
- else
- {
- assert(ce.re != null);
- java.util.regex.Matcher m = ce.re.matcher(cipher);
- if(m.find())
- {
- e.remove();
- }
- }
- }
- }
- else
- {
- if(ce.cipher != null)
- {
- result.add(0, ce.cipher);
- }
- else
- {
- assert(ce.re != null);
- for(String cipher : supportedCiphers)
- {
- java.util.regex.Matcher m = ce.re.matcher(cipher);
- if(m.find())
- {
- result.add(0, cipher);
- }
- }
- }
- }
- }
- }
-
- String[] arr = new String[result.size()];
- result.toArray(arr);
- return arr;
- }
-
- String[]
- protocols()
- {
- return _protocols;
- }
-
- void
- traceConnection(java.nio.channels.SocketChannel fd, javax.net.ssl.SSLEngine engine, boolean incoming)
- {
- javax.net.ssl.SSLSession session = engine.getSession();
- String msg = "SSL summary for " + (incoming ? "incoming" : "outgoing") + " connection\n" +
- "cipher = " + session.getCipherSuite() + "\n" +
- "protocol = " + session.getProtocol() + "\n" +
- IceInternal.Network.fdToString(fd);
- _logger.trace(_securityTraceCategory, msg);
- }
-
- void
- verifyPeer(NativeConnectionInfo info, java.nio.channels.SelectableChannel fd, String address)
- {
- //
- // For an outgoing connection, we compare the proxy address (if any) against
- // fields in the server's certificate (if any).
- //
- if(info.nativeCerts != null && info.nativeCerts.length > 0 && address.length() > 0)
- {
- java.security.cert.X509Certificate cert = (java.security.cert.X509Certificate)info.nativeCerts[0];
-
- //
- // Extract the IP addresses and the DNS names from the subject
- // alternative names.
- //
- java.util.ArrayList<String> ipAddresses = new java.util.ArrayList<String>();
- java.util.ArrayList<String> dnsNames = new java.util.ArrayList<String>();
- try
- {
- java.util.Collection<java.util.List<?> > subjectAltNames = cert.getSubjectAlternativeNames();
- if(subjectAltNames != null)
- {
- for(java.util.List<?> l : subjectAltNames)
- {
- assert(!l.isEmpty());
- Integer n = (Integer)l.get(0);
- if(n.intValue() == 7)
- {
- ipAddresses.add((String)l.get(1));
- }
- else if(n.intValue() == 2)
- {
- dnsNames.add(((String)l.get(1)).toLowerCase());
- }
- }
- }
- }
- catch(java.security.cert.CertificateParsingException ex)
- {
- assert(false);
- }
-
- //
- // Compare the peer's address against the common name as well as
- // the dnsName and ipAddress values in the subject alternative name.
- //
- boolean certNameOK = false;
- String dn = "";
- String addrLower = address.toLowerCase();
- {
- javax.security.auth.x500.X500Principal principal = cert.getSubjectX500Principal();
- dn = principal.getName(javax.security.auth.x500.X500Principal.CANONICAL);
- //
- // Canonical format is already in lower case.
- //
- String cn = "cn=" + addrLower;
- int pos = dn.indexOf(cn);
- if(pos >= 0)
- {
- //
- // Ensure we match the entire common name.
- //
- certNameOK = (pos + cn.length() == dn.length()) || (dn.charAt(pos + cn.length()) == ',');
- }
- }
-
- //
- // Compare the peer's address against the dnsName and ipAddress
- // values in the subject alternative name.
- //
- if(!certNameOK)
- {
- certNameOK = ipAddresses.contains(addrLower);
- }
- if(!certNameOK)
- {
- certNameOK = dnsNames.contains(addrLower);
- }
-
- //
- // Log a message if the name comparison fails. If CheckCertName is defined,
- // we also raise an exception to abort the connection. Don't log a message if
- // CheckCertName is not defined and a verifier is present.
- //
- if(!certNameOK && (_checkCertName || (_securityTraceLevel >= 1 && _verifier == null)))
- {
- StringBuilder sb = new StringBuilder(128);
- sb.append("IceSSL: ");
- if(!_checkCertName)
- {
- sb.append("ignoring ");
- }
- sb.append("certificate validation failure:\npeer certificate does not have `");
- sb.append(address);
- sb.append("' as its commonName or in its subjectAltName extension");
- if(dn.length() > 0)
- {
- sb.append("\nSubject DN: ");
- sb.append(dn);
- }
- if(!dnsNames.isEmpty())
- {
- sb.append("\nDNS names found in certificate: ");
- for(int j = 0; j < dnsNames.size(); ++j)
- {
- if(j > 0)
- {
- sb.append(", ");
- }
- sb.append(dnsNames.get(j));
- }
- }
- if(!ipAddresses.isEmpty())
- {
- sb.append("\nIP addresses found in certificate: ");
- for(int j = 0; j < ipAddresses.size(); ++j)
- {
- if(j > 0)
- {
- sb.append(", ");
- }
- sb.append(ipAddresses.get(j));
- }
- }
- if(_securityTraceLevel >= 1)
- {
- _logger.trace(_securityTraceCategory, sb.toString());
- }
- if(_checkCertName)
- {
- Ice.SecurityException ex = new Ice.SecurityException();
- ex.reason = sb.toString();
- throw ex;
- }
- }
- }
-
- if(_verifyDepthMax > 0 && info.nativeCerts != null && info.nativeCerts.length > _verifyDepthMax)
- {
- String msg = (info.incoming ? "incoming" : "outgoing") + " connection rejected:\n" +
- "length of peer's certificate chain (" + info.nativeCerts.length + ") exceeds maximum of " +
- _verifyDepthMax + "\n" +
- IceInternal.Network.fdToString(fd);
- if(_securityTraceLevel >= 1)
- {
- _logger.trace(_securityTraceCategory, msg);
- }
- Ice.SecurityException ex = new Ice.SecurityException();
- ex.reason = msg;
- throw ex;
- }
-
- if(!_trustManager.verify(info))
- {
- String msg = (info.incoming ? "incoming" : "outgoing") + " connection rejected by trust manager\n" +
- IceInternal.Network.fdToString(fd);
- if(_securityTraceLevel >= 1)
- {
- _logger.trace(_securityTraceCategory, msg);
- }
- Ice.SecurityException ex = new Ice.SecurityException();
- ex.reason = msg;
- throw ex;
- }
-
- if(_verifier != null && !_verifier.verify(info))
- {
- String msg = (info.incoming ? "incoming" : "outgoing") + " connection rejected by certificate verifier\n" +
- IceInternal.Network.fdToString(fd);
- if(_securityTraceLevel >= 1)
- {
- _logger.trace(_securityTraceCategory, msg);
- }
- Ice.SecurityException ex = new Ice.SecurityException();
- ex.reason = msg;
- throw ex;
- }
- }
-
- void
- trustManagerFailure(boolean incoming, java.security.cert.CertificateException ex)
+ void trustManagerFailure(boolean incoming, java.security.cert.CertificateException ex)
throws java.security.cert.CertificateException
{
- if(_verifyPeer == 0)
- {
- if(_securityTraceLevel >= 1)
- {
- String msg = "ignoring peer verification failure";
- if(_securityTraceLevel > 1)
- {
- java.io.StringWriter sw = new java.io.StringWriter();
- java.io.PrintWriter pw = new java.io.PrintWriter(sw);
- ex.printStackTrace(pw);
- pw.flush();
- msg += ":\n" + sw.toString();
- }
- _logger.trace(_securityTraceCategory, msg);
- }
- }
- else
- {
- throw ex;
- }
- }
-
- private void
- parseCiphers(String ciphers)
- {
- java.util.ArrayList<CipherExpression> cipherList = new java.util.ArrayList<CipherExpression>();
- String[] expr = ciphers.split("[ \t]+");
- for(int i = 0; i < expr.length; ++i)
- {
- if(expr[i].equals("ALL"))
- {
- if(i != 0)
- {
- Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
- ex.reason = "IceSSL: `ALL' must be first in cipher list `" + ciphers + "'";
- throw ex;
- }
- _allCiphers = true;
- }
- else if(expr[i].equals("NONE"))
- {
- if(i != 0)
- {
- Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
- ex.reason = "IceSSL: `NONE' must be first in cipher list `" + ciphers + "'";
- throw ex;
- }
- _noCiphers = true;
- }
- else
- {
- CipherExpression ce = new CipherExpression();
- String exp = expr[i];
- if(exp.charAt(0) == '!')
- {
- ce.not = true;
- if(exp.length() > 1)
- {
- exp = exp.substring(1);
- }
- else
- {
- Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
- ex.reason = "IceSSL: invalid cipher expression `" + exp + "'";
- throw ex;
- }
- }
-
- if(exp.charAt(0) == '(')
- {
- if(!exp.endsWith(")"))
- {
- Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
- ex.reason = "IceSSL: invalid cipher expression `" + exp + "'";
- throw ex;
- }
-
- try
- {
- ce.re = java.util.regex.Pattern.compile(exp.substring(1, exp.length() - 2));
- }
- catch(java.util.regex.PatternSyntaxException ex)
- {
- throw new Ice.PluginInitializationException(
- "IceSSL: invalid cipher expression `" + exp + "'", ex);
- }
- }
- else
- {
- ce.cipher = exp;
- }
-
- cipherList.add(ce);
- }
- }
- _ciphers = new CipherExpression[cipherList.size()];
- cipherList.toArray(_ciphers);
- }
-
- private java.io.InputStream
- openResource(String path)
- throws java.io.IOException
- {
- //
- // This method wraps a call to IceInternal.Util.openResource. If the first call fails and
- // IceSSL.DefaultDir is defined, prepend the default directory and try again.
- //
- java.io.InputStream stream = IceInternal.Util.openResource(getClass().getClassLoader(), path);
- if(stream == null && _defaultDir.length() > 0)
- {
- stream = IceInternal.Util.openResource(getClass().getClassLoader(),
- _defaultDir + java.io.File.separator + path);
- }
-
- if(stream != null)
- {
- stream = new java.io.BufferedInputStream(stream);
- }
-
- return stream;
- }
-
- private static class CipherExpression
- {
- boolean not;
- String cipher;
- java.util.regex.Pattern re;
+ _sharedInstance.trustManagerFailure(incoming, ex);
}
- private Ice.Logger _logger;
- private IceInternal.ProtocolPluginFacade _facade;
- private int _securityTraceLevel;
- private String _securityTraceCategory;
- private boolean _initialized;
- private javax.net.ssl.SSLContext _context;
- private String _defaultDir;
- private CipherExpression[] _ciphers;
- private boolean _allCiphers;
- private boolean _noCiphers;
- private String[] _protocols;
- private boolean _checkCertName;
- private int _verifyDepthMax;
- private int _verifyPeer;
- private CertificateVerifier _verifier;
- private PasswordCallback _passwordCallback;
- private TrustManager _trustManager;
-
- private InputStream _keystoreStream;
- private InputStream _truststoreStream;
- private List<InputStream> _seeds = new ArrayList<InputStream>();
+ private SharedInstance _sharedInstance;
}