2 // ========================================================================
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
19 package org.eclipse.jetty.server;
21 import java.security.cert.X509Certificate;
23 import javax.net.ssl.SSLEngine;
24 import javax.net.ssl.SSLSession;
26 import org.eclipse.jetty.http.HttpScheme;
27 import org.eclipse.jetty.io.ssl.SslConnection;
28 import org.eclipse.jetty.io.ssl.SslConnection.DecryptedEndPoint;
29 import org.eclipse.jetty.util.TypeUtil;
30 import org.eclipse.jetty.util.log.Log;
31 import org.eclipse.jetty.util.log.Logger;
32 import org.eclipse.jetty.util.ssl.SslContextFactory;
34 public class SecureRequestCustomizer implements HttpConfiguration.Customizer
36 private static final Logger LOG = Log.getLogger(SecureRequestCustomizer.class);
39 * The name of the SSLSession attribute that will contain any cached information.
41 public static final String CACHED_INFO_ATTR = CachedInfo.class.getName();
45 public void customize(Connector connector, HttpConfiguration channelConfig, Request request)
47 if (request.getHttpChannel().getEndPoint() instanceof DecryptedEndPoint)
49 request.setScheme(HttpScheme.HTTPS.asString());
50 request.setSecure(true);
51 SslConnection.DecryptedEndPoint ssl_endp = (DecryptedEndPoint)request.getHttpChannel().getEndPoint();
52 SslConnection sslConnection = ssl_endp.getSslConnection();
53 SSLEngine sslEngine=sslConnection.getSSLEngine();
54 customize(sslEngine,request);
59 /* ------------------------------------------------------------ */
61 * Allow the Listener a chance to customise the request. before the server
62 * does its stuff. <br>
63 * This allows the required attributes to be set for SSL requests. <br>
64 * The requirements of the Servlet specs are:
66 * <li> an attribute named "javax.servlet.request.ssl_session_id" of type
67 * String (since Servlet Spec 3.0).</li>
68 * <li> an attribute named "javax.servlet.request.cipher_suite" of type
70 * <li> an attribute named "javax.servlet.request.key_size" of type Integer.</li>
71 * <li> an attribute named "javax.servlet.request.X509Certificate" of type
72 * java.security.cert.X509Certificate[]. This is an array of objects of type
73 * X509Certificate, the order of this array is defined as being in ascending
74 * order of trust. The first certificate in the chain is the one set by the
75 * client, the next is the one used to authenticate the first, and so on.
80 * HttpRequest to be customised.
82 public void customize(SSLEngine sslEngine, Request request)
84 request.setScheme(HttpScheme.HTTPS.asString());
85 SSLSession sslSession = sslEngine.getSession();
89 String cipherSuite=sslSession.getCipherSuite();
91 X509Certificate[] certs;
94 CachedInfo cachedInfo=(CachedInfo)sslSession.getValue(CACHED_INFO_ATTR);
97 keySize=cachedInfo.getKeySize();
98 certs=cachedInfo.getCerts();
99 idStr=cachedInfo.getIdStr();
103 keySize=new Integer(SslContextFactory.deduceKeyLength(cipherSuite));
104 certs=SslContextFactory.getCertChain(sslSession);
105 byte[] bytes = sslSession.getId();
106 idStr = TypeUtil.toHexString(bytes);
107 cachedInfo=new CachedInfo(keySize,certs,idStr);
108 sslSession.putValue(CACHED_INFO_ATTR,cachedInfo);
112 request.setAttribute("javax.servlet.request.X509Certificate",certs);
114 request.setAttribute("javax.servlet.request.cipher_suite",cipherSuite);
115 request.setAttribute("javax.servlet.request.key_size",keySize);
116 request.setAttribute("javax.servlet.request.ssl_session_id", idStr);
120 LOG.warn(Log.EXCEPTION,e);
125 public String toString()
127 return String.format("%s@%x",this.getClass().getSimpleName(),hashCode());
130 /* ------------------------------------------------------------ */
131 /* ------------------------------------------------------------ */
132 /* ------------------------------------------------------------ */
134 * Simple bundle of information that is cached in the SSLSession. Stores the
135 * effective keySize and the client certificate chain.
137 private static class CachedInfo
139 private final X509Certificate[] _certs;
140 private final Integer _keySize;
141 private final String _idStr;
143 CachedInfo(Integer keySize, X509Certificate[] certs,String idStr)
145 this._keySize=keySize;
150 X509Certificate[] getCerts()