]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/server/SecureRequestCustomizer.java
Importing upstream Jetty jetty-9.2.1.v20140609
[gigi.git] / lib / jetty / org / eclipse / jetty / server / SecureRequestCustomizer.java
1 //
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.
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.SSLEngine;
24 import javax.net.ssl.SSLSession;
25
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;
33
34 public class SecureRequestCustomizer implements HttpConfiguration.Customizer
35 {
36     private static final Logger LOG = Log.getLogger(SecureRequestCustomizer.class);
37     
38     /**
39      * The name of the SSLSession attribute that will contain any cached information.
40      */
41     public static final String CACHED_INFO_ATTR = CachedInfo.class.getName();
42
43
44     @Override
45     public void customize(Connector connector, HttpConfiguration channelConfig, Request request)
46     {
47         if (request.getHttpChannel().getEndPoint() instanceof DecryptedEndPoint)
48         {
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);
55         }
56
57     }
58
59     /* ------------------------------------------------------------ */
60     /*
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:
65      * <ul>
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
69      * String.</li>
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.
76      * </li>
77      * </ul>
78      *
79      * @param request
80      *                HttpRequest to be customised.
81      */
82     public void customize(SSLEngine sslEngine, Request request)
83     {
84         request.setScheme(HttpScheme.HTTPS.asString());
85         SSLSession sslSession = sslEngine.getSession();
86
87         try
88         {
89             String cipherSuite=sslSession.getCipherSuite();
90             Integer keySize;
91             X509Certificate[] certs;
92             String idStr;
93
94             CachedInfo cachedInfo=(CachedInfo)sslSession.getValue(CACHED_INFO_ATTR);
95             if (cachedInfo!=null)
96             {
97                 keySize=cachedInfo.getKeySize();
98                 certs=cachedInfo.getCerts();
99                 idStr=cachedInfo.getIdStr();
100             }
101             else 
102             {
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);
109             }
110
111             if (certs!=null)
112                 request.setAttribute("javax.servlet.request.X509Certificate",certs);
113
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);
117         }
118         catch (Exception e)
119         {
120             LOG.warn(Log.EXCEPTION,e);
121         }
122     }
123
124     @Override
125     public String toString()
126     {
127         return String.format("%s@%x",this.getClass().getSimpleName(),hashCode());
128     }
129     
130     /* ------------------------------------------------------------ */
131     /* ------------------------------------------------------------ */
132     /* ------------------------------------------------------------ */
133     /**
134      * Simple bundle of information that is cached in the SSLSession. Stores the
135      * effective keySize and the client certificate chain.
136      */
137     private static class CachedInfo
138     {
139         private final X509Certificate[] _certs;
140         private final Integer _keySize;
141         private final String _idStr;
142
143         CachedInfo(Integer keySize, X509Certificate[] certs,String idStr)
144         {
145             this._keySize=keySize;
146             this._certs=certs;
147             this._idStr=idStr;
148         }
149
150         X509Certificate[] getCerts()
151         {
152             return _certs;
153         }
154
155         Integer getKeySize()
156         {
157             return _keySize;
158         }
159
160         String getIdStr()
161         {
162             return _idStr;
163         }
164     }
165
166
167
168 }