2 // ========================================================================
3 // Copyright (c) 1995-2016 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.SSLContext;
24 import javax.net.ssl.SSLEngine;
25 import javax.net.ssl.SSLSession;
26 import javax.servlet.ServletRequest;
28 import org.eclipse.jetty.http.HttpScheme;
29 import org.eclipse.jetty.io.ssl.SslConnection;
30 import org.eclipse.jetty.io.ssl.SslConnection.DecryptedEndPoint;
31 import org.eclipse.jetty.util.TypeUtil;
32 import org.eclipse.jetty.util.log.Log;
33 import org.eclipse.jetty.util.log.Logger;
34 import org.eclipse.jetty.util.ssl.SslContextFactory;
37 /* ------------------------------------------------------------ */
38 /** Customizer that extracts the attribute from an {@link SSLContext}
39 * and sets them on the request with {@link ServletRequest#setAttribute(String, Object)}
40 * according to Servlet Specification Requirements.
42 public class SecureRequestCustomizer implements HttpConfiguration.Customizer
44 private static final Logger LOG = Log.getLogger(SecureRequestCustomizer.class);
47 * The name of the SSLSession attribute that will contain any cached information.
49 public static final String CACHED_INFO_ATTR = CachedInfo.class.getName();
51 private String sslSessionAttribute = "org.eclipse.jetty.servlet.request.ssl_session";
54 public void customize(Connector connector, HttpConfiguration channelConfig, Request request)
56 if (request.getHttpChannel().getEndPoint() instanceof DecryptedEndPoint)
58 request.setScheme(HttpScheme.HTTPS.asString());
59 request.setSecure(true);
60 SslConnection.DecryptedEndPoint ssl_endp = (DecryptedEndPoint)request.getHttpChannel().getEndPoint();
61 SslConnection sslConnection = ssl_endp.getSslConnection();
62 SSLEngine sslEngine=sslConnection.getSSLEngine();
63 customize(sslEngine,request);
67 /* ------------------------------------------------------------ */
69 * Customise the request attributes to be set for SSL requests. <br>
70 * The requirements of the Servlet specs are:
72 * <li> an attribute named "javax.servlet.request.ssl_session_id" of type
73 * String (since Servlet Spec 3.0).</li>
74 * <li> an attribute named "javax.servlet.request.cipher_suite" of type
76 * <li> an attribute named "javax.servlet.request.key_size" of type Integer.</li>
77 * <li> an attribute named "javax.servlet.request.X509Certificate" of type
78 * java.security.cert.X509Certificate[]. This is an array of objects of type
79 * X509Certificate, the order of this array is defined as being in ascending
80 * order of trust. The first certificate in the chain is the one set by the
81 * client, the next is the one used to authenticate the first, and so on.
86 * HttpRequest to be customised.
88 public void customize(SSLEngine sslEngine, Request request)
90 request.setScheme(HttpScheme.HTTPS.asString());
91 SSLSession sslSession = sslEngine.getSession();
95 String cipherSuite=sslSession.getCipherSuite();
97 X509Certificate[] certs;
100 CachedInfo cachedInfo=(CachedInfo)sslSession.getValue(CACHED_INFO_ATTR);
101 if (cachedInfo!=null)
103 keySize=cachedInfo.getKeySize();
104 certs=cachedInfo.getCerts();
105 idStr=cachedInfo.getIdStr();
109 keySize=new Integer(SslContextFactory.deduceKeyLength(cipherSuite));
110 certs=SslContextFactory.getCertChain(sslSession);
111 byte[] bytes = sslSession.getId();
112 idStr = TypeUtil.toHexString(bytes);
113 cachedInfo=new CachedInfo(keySize,certs,idStr);
114 sslSession.putValue(CACHED_INFO_ATTR,cachedInfo);
118 request.setAttribute("javax.servlet.request.X509Certificate",certs);
120 request.setAttribute("javax.servlet.request.cipher_suite",cipherSuite);
121 request.setAttribute("javax.servlet.request.key_size",keySize);
122 request.setAttribute("javax.servlet.request.ssl_session_id", idStr);
123 request.setAttribute(getSslSessionAttribute(), sslSession);
127 LOG.warn(Log.EXCEPTION,e);
131 public void setSslSessionAttribute(String attribute)
133 this.sslSessionAttribute = attribute;
136 public String getSslSessionAttribute()
138 return sslSessionAttribute;
142 public String toString()
144 return String.format("%s@%x",this.getClass().getSimpleName(),hashCode());
147 /* ------------------------------------------------------------ */
148 /* ------------------------------------------------------------ */
149 /* ------------------------------------------------------------ */
151 * Simple bundle of information that is cached in the SSLSession. Stores the
152 * effective keySize and the client certificate chain.
154 private static class CachedInfo
156 private final X509Certificate[] _certs;
157 private final Integer _keySize;
158 private final String _idStr;
160 CachedInfo(Integer keySize, X509Certificate[] certs,String idStr)
162 this._keySize=keySize;
167 X509Certificate[] getCerts()