📄 sslselectchannelconnector.java
字号:
//========================================================================//Copyright 2004-2008 Mort Bay Consulting Pty. Ltd.//------------------------------------------------------------------------//Licensed under the Apache License, Version 2.0 (the "License");//you may not use this file except in compliance with the License.//You may obtain a copy of the License at //http://www.apache.org/licenses/LICENSE-2.0//Unless required by applicable law or agreed to in writing, software//distributed under the License is distributed on an "AS IS" BASIS,//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.//See the License for the specific language governing permissions and//limitations under the License.//========================================================================package org.mortbay.jetty.security;import java.io.ByteArrayInputStream;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.SocketChannel;import java.security.KeyStore;import java.security.SecureRandom;import java.security.Security;import java.security.cert.X509Certificate;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.concurrent.ConcurrentLinkedQueue;import javax.net.ssl.KeyManager;import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLEngine;import javax.net.ssl.SSLPeerUnverifiedException;import javax.net.ssl.SSLSession;import javax.net.ssl.SSLSocket;import javax.net.ssl.TrustManager;import javax.net.ssl.TrustManagerFactory;import org.mortbay.io.Buffer;import org.mortbay.io.Connection;import org.mortbay.io.EndPoint;import org.mortbay.io.bio.SocketEndPoint;import org.mortbay.io.nio.DirectNIOBuffer;import org.mortbay.io.nio.IndirectNIOBuffer;import org.mortbay.io.nio.NIOBuffer;import org.mortbay.io.nio.SelectChannelEndPoint;import org.mortbay.io.nio.SelectorManager.SelectSet;import org.mortbay.jetty.HttpConnection;import org.mortbay.jetty.HttpParser;import org.mortbay.jetty.HttpSchemes;import org.mortbay.jetty.Request;import org.mortbay.jetty.nio.SelectChannelConnector;import org.mortbay.log.Log;import org.mortbay.resource.Resource;/* ------------------------------------------------------------ *//** * SslSelectChannelConnector. * * @author Nik Gonzalez <ngonzalez@exist.com> * @author Greg Wilkins <gregw@mortbay.com> */public class SslSelectChannelConnector extends SelectChannelConnector{ /** * The name of the SSLSession attribute that will contain any cached * information. */ static final String CACHED_INFO_ATTR=CachedInfo.class.getName(); /** Default value for the keystore location path. */ public static final String DEFAULT_KEYSTORE=System.getProperty("user.home")+File.separator+".keystore"; /** String name of key password property. */ public static final String KEYPASSWORD_PROPERTY="jetty.ssl.keypassword"; /** String name of keystore password property. */ public static final String PASSWORD_PROPERTY="jetty.ssl.password"; /** Default value for the cipher Suites. */ private String _excludeCipherSuites[]=null; /** Default value for the keystore location path. */ private String _keystore=DEFAULT_KEYSTORE; private String _keystoreType="JKS"; // type of the key store /** Set to true if we require client certificate authentication. */ private boolean _needClientAuth=false; private boolean _wantClientAuth=false; private transient Password _password; private transient Password _keyPassword; private transient Password _trustPassword; private String _protocol="TLS"; private String _algorithm="SunX509"; // cert algorithm private String _provider; private String _secureRandomAlgorithm; // cert algorithm private String _sslKeyManagerFactoryAlgorithm=(Security.getProperty("ssl.KeyManagerFactory.algorithm")==null?"SunX509":Security .getProperty("ssl.KeyManagerFactory.algorithm")); // cert // algorithm private String _sslTrustManagerFactoryAlgorithm=(Security.getProperty("ssl.TrustManagerFactory.algorithm")==null?"SunX509":Security .getProperty("ssl.TrustManagerFactory.algorithm")); // cert // algorithm private String _truststore; private String _truststoreType="JKS"; // type of the key store private SSLContext _context; private int _packetBufferSize; private int _applicationBufferSize; private ConcurrentLinkedQueue<Buffer> _packetBuffers = new ConcurrentLinkedQueue<Buffer>(); private ConcurrentLinkedQueue<Buffer> _applicationBuffers = new ConcurrentLinkedQueue<Buffer>(); /* ------------------------------------------------------------ */ /* (non-Javadoc) * @see org.mortbay.jetty.AbstractBuffers#getBuffer(int) */ public Buffer getBuffer(int size) { Buffer buffer; if (size==_applicationBufferSize) { buffer = _applicationBuffers.poll(); if (buffer==null) buffer=new IndirectNIOBuffer(size); } else if (size==_packetBufferSize) { buffer = _packetBuffers.poll(); if (buffer==null) buffer=getUseDirectBuffers() ?(NIOBuffer)new DirectNIOBuffer(size) :(NIOBuffer)new IndirectNIOBuffer(size); } else buffer=super.getBuffer(size); return buffer; } /* ------------------------------------------------------------ */ /* (non-Javadoc) * @see org.mortbay.jetty.AbstractBuffers#returnBuffer(org.mortbay.io.Buffer) */ public void returnBuffer(Buffer buffer) { buffer.clear(); int size=buffer.capacity(); ByteBuffer bbuf = ((NIOBuffer)buffer).getByteBuffer(); bbuf.position(0); bbuf.limit(size); if (size==_applicationBufferSize) _applicationBuffers.add(buffer); else if (size==_packetBufferSize) _packetBuffers.add(buffer); else super.returnBuffer(buffer); } /** * Return the chain of X509 certificates used to negotiate the SSL Session. * <p> * Note: in order to do this we must convert a * javax.security.cert.X509Certificate[], as used by JSSE to a * java.security.cert.X509Certificate[],as required by the Servlet specs. * * @param sslSession * the javax.net.ssl.SSLSession to use as the source of the * cert chain. * @return the chain of java.security.cert.X509Certificates used to * negotiate the SSL connection. <br> * Will be null if the chain is missing or empty. */ private static X509Certificate[] getCertChain(SSLSession sslSession) { try { javax.security.cert.X509Certificate javaxCerts[]=sslSession.getPeerCertificateChain(); if (javaxCerts==null||javaxCerts.length==0) return null; int length=javaxCerts.length; X509Certificate[] javaCerts=new X509Certificate[length]; java.security.cert.CertificateFactory cf=java.security.cert.CertificateFactory.getInstance("X.509"); for (int i=0; i<length; i++) { byte bytes[]=javaxCerts[i].getEncoded(); ByteArrayInputStream stream=new ByteArrayInputStream(bytes); javaCerts[i]=(X509Certificate)cf.generateCertificate(stream); } return javaCerts; } catch (SSLPeerUnverifiedException e) { Log.ignore(e); return null; } catch (Exception e) { Log.warn(Log.EXCEPTION,e); return null; } } /* ------------------------------------------------------------ */ /** * Allow the Listener a chance to customise the request. before the server * does its stuff. <br> * This allows the required attributes to be set for SSL requests. <br> * The requirements of the Servlet specs are: * <ul> * <li> an attribute named "javax.servlet.request.cipher_suite" of type * String.</li> * <li> an attribute named "javax.servlet.request.key_size" of type Integer.</li> * <li> an attribute named "javax.servlet.request.X509Certificate" of type * java.security.cert.X509Certificate[]. This is an array of objects of type * X509Certificate, the order of this array is defined as being in ascending * order of trust. The first certificate in the chain is the one set by the * client, the next is the one used to authenticate the first, and so on. * </li> * </ul> * * @param endpoint * The Socket the request arrived on. This should be a * {@link SocketEndPoint} wrapping a {@link SSLSocket}. * @param request * HttpRequest to be customised. */ public void customize(EndPoint endpoint, Request request) throws IOException { super.customize(endpoint,request); request.setScheme(HttpSchemes.HTTPS); SslHttpChannelEndPoint sslHttpChannelEndpoint=(SslHttpChannelEndPoint)endpoint; SSLEngine sslEngine=sslHttpChannelEndpoint.getSSLEngine(); try { SSLSession sslSession=sslEngine.getSession(); String cipherSuite=sslSession.getCipherSuite(); Integer keySize; X509Certificate[] certs; CachedInfo cachedInfo=(CachedInfo)sslSession.getValue(CACHED_INFO_ATTR); if (cachedInfo!=null) { keySize=cachedInfo.getKeySize(); certs=cachedInfo.getCerts(); } else { keySize=new Integer(ServletSSL.deduceKeyLength(cipherSuite)); certs=getCertChain(sslSession); cachedInfo=new CachedInfo(keySize,certs); sslSession.putValue(CACHED_INFO_ATTR,cachedInfo); } if (certs!=null) request.setAttribute("javax.servlet.request.X509Certificate",certs); request.setAttribute("javax.servlet.request.cipher_suite",cipherSuite); request.setAttribute("javax.servlet.request.key_size",keySize); } catch (Exception e) { Log.warn(Log.EXCEPTION,e); } } /* ------------------------------------------------------------ */ public SslSelectChannelConnector() { // Buffer sizes should be from SSL session, but not known at this stage. // size should be 16k, but appears to need 16k+1 byte? Giving it 16k+2k // just // to be safe. TODO investigate } /** * * @deprecated As of Java Servlet API 2.0, with no replacement. * */ public String[] getCipherSuites() { return getExcludeCipherSuites(); } public String[] getExcludeCipherSuites() { return _excludeCipherSuites; } /** * * @deprecated As of Java Servlet API 2.0, with no replacement. * * @author Tony Jiang */ public void setCipherSuites(String[] cipherSuites) { setExcludeCipherSuites(cipherSuites); } public void setExcludeCipherSuites(String[] cipherSuites) { this._excludeCipherSuites=cipherSuites; } /* ------------------------------------------------------------ */ public void setPassword(String password) { _password=Password.getPassword(PASSWORD_PROPERTY,password,null); } /* ------------------------------------------------------------ */ public void setTrustPassword(String password) { _trustPassword=Password.getPassword(PASSWORD_PROPERTY,password,null); } /* ------------------------------------------------------------ */ public void setKeyPassword(String password) { _keyPassword=Password.getPassword(KEYPASSWORD_PROPERTY,password,null); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -