]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/server/SecureRequestCustomizer.java
Merge "Update notes about password security"
[gigi.git] / lib / jetty / org / eclipse / jetty / server / SecureRequestCustomizer.java
1 //
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.
8 //
9 //      The Eclipse Public License is available at
10 //      http://www.eclipse.org/legal/epl-v10.html
11 //
12 //      The Apache License v2.0 is available at
13 //      http://www.opensource.org/licenses/apache2.0.php
14 //
15 //  You may elect to redistribute this code under either of these licenses.
16 //  ========================================================================
17 //
18
19 package org.eclipse.jetty.server;
20
21 import java.security.cert.X509Certificate;
22
23 import javax.net.ssl.SSLContext;
24 import javax.net.ssl.SSLEngine;
25 import javax.net.ssl.SSLSession;
26 import javax.servlet.ServletRequest;
27
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;
35
36
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.
41  */
42 public class SecureRequestCustomizer implements HttpConfiguration.Customizer
43 {
44     private static final Logger LOG = Log.getLogger(SecureRequestCustomizer.class);
45     
46     /**
47      * The name of the SSLSession attribute that will contain any cached information.
48      */
49     public static final String CACHED_INFO_ATTR = CachedInfo.class.getName();
50
51     private String sslSessionAttribute = "org.eclipse.jetty.servlet.request.ssl_session";
52
53     @Override
54     public void customize(Connector connector, HttpConfiguration channelConfig, Request request)
55     {
56         if (request.getHttpChannel().getEndPoint() instanceof DecryptedEndPoint)
57         {
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);
64         }
65     }
66
67     /* ------------------------------------------------------------ */
68     /*
69      * Customise the request attributes to be set for SSL requests. <br>
70      * The requirements of the Servlet specs are:
71      * <ul>
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
75      * String.</li>
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.
82      * </li>
83      * </ul>
84      *
85      * @param request
86      *                HttpRequest to be customised.
87      */
88     public void customize(SSLEngine sslEngine, Request request)
89     {
90         request.setScheme(HttpScheme.HTTPS.asString());
91         SSLSession sslSession = sslEngine.getSession();
92
93         try
94         {
95             String cipherSuite=sslSession.getCipherSuite();
96             Integer keySize;
97             X509Certificate[] certs;
98             String idStr;
99
100             CachedInfo cachedInfo=(CachedInfo)sslSession.getValue(CACHED_INFO_ATTR);
101             if (cachedInfo!=null)
102             {
103                 keySize=cachedInfo.getKeySize();
104                 certs=cachedInfo.getCerts();
105                 idStr=cachedInfo.getIdStr();
106             }
107             else 
108             {
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);
115             }
116
117             if (certs!=null)
118                 request.setAttribute("javax.servlet.request.X509Certificate",certs);
119
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);
124         }
125         catch (Exception e)
126         {
127             LOG.warn(Log.EXCEPTION,e);
128         }
129     }
130     
131     public void setSslSessionAttribute(String attribute)
132     {
133         this.sslSessionAttribute = attribute;
134     }
135
136     public String getSslSessionAttribute()
137     {
138         return sslSessionAttribute;
139     }
140
141     @Override
142     public String toString()
143     {
144         return String.format("%s@%x",this.getClass().getSimpleName(),hashCode());
145     }
146     
147     /* ------------------------------------------------------------ */
148     /* ------------------------------------------------------------ */
149     /* ------------------------------------------------------------ */
150     /**
151      * Simple bundle of information that is cached in the SSLSession. Stores the
152      * effective keySize and the client certificate chain.
153      */
154     private static class CachedInfo
155     {
156         private final X509Certificate[] _certs;
157         private final Integer _keySize;
158         private final String _idStr;
159
160         CachedInfo(Integer keySize, X509Certificate[] certs,String idStr)
161         {
162             this._keySize=keySize;
163             this._certs=certs;
164             this._idStr=idStr;
165         }
166
167         X509Certificate[] getCerts()
168         {
169             return _certs;
170         }
171
172         Integer getKeySize()
173         {
174             return _keySize;
175         }
176
177         String getIdStr()
178         {
179             return _idStr;
180         }
181     }
182
183
184
185 }