]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java
updating jetty to jetty-9.2.16.v2016040
[gigi.git] / lib / jetty / org / eclipse / jetty / security / authentication / ClientCertAuthenticator.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.security.authentication;
20
21 import java.io.InputStream;
22 import java.security.KeyStore;
23 import java.security.Principal;
24 import java.security.cert.CRL;
25 import java.security.cert.X509Certificate;
26 import java.util.Collection;
27
28 import javax.servlet.ServletRequest;
29 import javax.servlet.ServletResponse;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32
33 import org.eclipse.jetty.security.ServerAuthException;
34 import org.eclipse.jetty.security.UserAuthentication;
35 import org.eclipse.jetty.server.Authentication;
36 import org.eclipse.jetty.server.Authentication.User;
37 import org.eclipse.jetty.server.UserIdentity;
38 import org.eclipse.jetty.util.B64Code;
39 import org.eclipse.jetty.util.security.CertificateUtils;
40 import org.eclipse.jetty.util.security.CertificateValidator;
41 import org.eclipse.jetty.util.security.Constraint;
42 import org.eclipse.jetty.util.security.Password;
43
44 /**
45  * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
46  */
47 public class ClientCertAuthenticator extends LoginAuthenticator
48 {
49     /** String name of keystore password property. */
50     private static final String PASSWORD_PROPERTY = "org.eclipse.jetty.ssl.password";
51
52     /** Truststore path */
53     private String _trustStorePath;
54     /** Truststore provider name */
55     private String _trustStoreProvider;
56     /** Truststore type */
57     private String _trustStoreType = "JKS";
58     /** Truststore password */
59     private transient Password _trustStorePassword;
60
61     /** Set to true if SSL certificate validation is required */
62     private boolean _validateCerts;
63     /** Path to file that contains Certificate Revocation List */
64     private String _crlPath;
65     /** Maximum certification path length (n - number of intermediate certs, -1 for unlimited) */
66     private int _maxCertPathLength = -1;
67     /** CRL Distribution Points (CRLDP) support */
68     private boolean _enableCRLDP = false;
69     /** On-Line Certificate Status Protocol (OCSP) support */
70     private boolean _enableOCSP = false;
71     /** Location of OCSP Responder */
72     private String _ocspResponderURL;
73
74     public ClientCertAuthenticator()
75     {
76         super();
77     }
78
79     @Override
80     public String getAuthMethod()
81     {
82         return Constraint.__CERT_AUTH;
83     }
84
85     
86
87     /**
88      * @return Authentication for request
89      * @throws ServerAuthException
90      */
91     @Override
92     public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException
93     {
94         if (!mandatory)
95             return new DeferredAuthentication(this);
96
97         HttpServletRequest request = (HttpServletRequest)req;
98         HttpServletResponse response = (HttpServletResponse)res;
99         X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
100
101         try
102         {
103             // Need certificates.
104             if (certs != null && certs.length > 0)
105             {
106
107                 if (_validateCerts)
108                 {
109                     KeyStore trustStore = getKeyStore(null,
110                             _trustStorePath, _trustStoreType, _trustStoreProvider,
111                             _trustStorePassword == null ? null :_trustStorePassword.toString());
112                     Collection<? extends CRL> crls = loadCRL(_crlPath);
113                     CertificateValidator validator = new CertificateValidator(trustStore, crls);
114                     validator.validate(certs);
115                 }
116
117                 for (X509Certificate cert: certs)
118                 {
119                     if (cert==null)
120                         continue;
121
122                     Principal principal = cert.getSubjectDN();
123                     if (principal == null) principal = cert.getIssuerDN();
124                     final String username = principal == null ? "clientcert" : principal.getName();
125
126                     final char[] credential = B64Code.encode(cert.getSignature());
127
128                     UserIdentity user = login(username, credential, req);
129                     if (user!=null)
130                     {
131                         return new UserAuthentication(getAuthMethod(),user);
132                     }
133                 }
134             }
135
136             if (!DeferredAuthentication.isDeferred(response))
137             {
138                 response.sendError(HttpServletResponse.SC_FORBIDDEN);
139                 return Authentication.SEND_FAILURE;
140             }
141
142             return Authentication.UNAUTHENTICATED;
143         }
144         catch (Exception e)
145         {
146             throw new ServerAuthException(e.getMessage());
147         }
148     }
149
150     /* ------------------------------------------------------------ */
151     /**
152      * Loads keystore using an input stream or a file path in the same
153      * order of precedence.
154      *
155      * Required for integrations to be able to override the mechanism
156      * used to load a keystore in order to provide their own implementation.
157      *
158      * @param storeStream keystore input stream
159      * @param storePath path of keystore file
160      * @param storeType keystore type
161      * @param storeProvider keystore provider
162      * @param storePassword keystore password
163      * @return created keystore
164      * @throws Exception
165      */
166     protected KeyStore getKeyStore(InputStream storeStream, String storePath, String storeType, String storeProvider, String storePassword) throws Exception
167     {
168         return CertificateUtils.getKeyStore(storeStream, storePath, storeType, storeProvider, storePassword);
169     }
170
171     /* ------------------------------------------------------------ */
172     /**
173      * Loads certificate revocation list (CRL) from a file.
174      *
175      * Required for integrations to be able to override the mechanism used to
176      * load CRL in order to provide their own implementation.
177      *
178      * @param crlPath path of certificate revocation list file
179      * @return a (possibly empty) collection view of java.security.cert.CRL objects initialized with the data from the
180      *         input stream.
181      * @throws Exception
182      */
183     protected Collection<? extends CRL> loadCRL(String crlPath) throws Exception
184     {
185         return CertificateUtils.loadCRL(crlPath);
186     }
187
188     @Override
189     public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, User validatedUser) throws ServerAuthException
190     {
191         return true;
192     }
193
194     /* ------------------------------------------------------------ */
195     /**
196      * @return true if SSL certificate has to be validated
197      */
198     public boolean isValidateCerts()
199     {
200         return _validateCerts;
201     }
202
203     /* ------------------------------------------------------------ */
204     /**
205      * @param validateCerts
206      *            true if SSL certificates have to be validated
207      */
208     public void setValidateCerts(boolean validateCerts)
209     {
210         _validateCerts = validateCerts;
211     }
212
213     /* ------------------------------------------------------------ */
214     /**
215      * @return The file name or URL of the trust store location
216      */
217     public String getTrustStore()
218     {
219         return _trustStorePath;
220     }
221
222     /* ------------------------------------------------------------ */
223     /**
224      * @param trustStorePath
225      *            The file name or URL of the trust store location
226      */
227     public void setTrustStore(String trustStorePath)
228     {
229         _trustStorePath = trustStorePath;
230     }
231
232     /* ------------------------------------------------------------ */
233     /**
234      * @return The provider of the trust store
235      */
236     public String getTrustStoreProvider()
237     {
238         return _trustStoreProvider;
239     }
240
241     /* ------------------------------------------------------------ */
242     /**
243      * @param trustStoreProvider
244      *            The provider of the trust store
245      */
246     public void setTrustStoreProvider(String trustStoreProvider)
247     {
248         _trustStoreProvider = trustStoreProvider;
249     }
250
251     /* ------------------------------------------------------------ */
252     /**
253      * @return The type of the trust store (default "JKS")
254      */
255     public String getTrustStoreType()
256     {
257         return _trustStoreType;
258     }
259
260     /* ------------------------------------------------------------ */
261     /**
262      * @param trustStoreType
263      *            The type of the trust store (default "JKS")
264      */
265     public void setTrustStoreType(String trustStoreType)
266     {
267         _trustStoreType = trustStoreType;
268     }
269
270     /* ------------------------------------------------------------ */
271     /**
272      * @param password
273      *            The password for the trust store
274      */
275     public void setTrustStorePassword(String password)
276     {
277         _trustStorePassword = Password.getPassword(PASSWORD_PROPERTY,password,null);
278     }
279
280     /* ------------------------------------------------------------ */
281     /** Get the crlPath.
282      * @return the crlPath
283      */
284     public String getCrlPath()
285     {
286         return _crlPath;
287     }
288
289     /* ------------------------------------------------------------ */
290     /** Set the crlPath.
291      * @param crlPath the crlPath to set
292      */
293     public void setCrlPath(String crlPath)
294     {
295         _crlPath = crlPath;
296     }
297
298     /**
299      * @return Maximum number of intermediate certificates in
300      * the certification path (-1 for unlimited)
301      */
302     public int getMaxCertPathLength()
303     {
304         return _maxCertPathLength;
305     }
306
307     /* ------------------------------------------------------------ */
308     /**
309      * @param maxCertPathLength
310      *            maximum number of intermediate certificates in
311      *            the certification path (-1 for unlimited)
312      */
313     public void setMaxCertPathLength(int maxCertPathLength)
314     {
315         _maxCertPathLength = maxCertPathLength;
316     }
317
318     /* ------------------------------------------------------------ */
319     /**
320      * @return true if CRL Distribution Points support is enabled
321      */
322     public boolean isEnableCRLDP()
323     {
324         return _enableCRLDP;
325     }
326
327     /* ------------------------------------------------------------ */
328     /** Enables CRL Distribution Points Support
329      * @param enableCRLDP true - turn on, false - turns off
330      */
331     public void setEnableCRLDP(boolean enableCRLDP)
332     {
333         _enableCRLDP = enableCRLDP;
334     }
335
336     /* ------------------------------------------------------------ */
337     /**
338      * @return true if On-Line Certificate Status Protocol support is enabled
339      */
340     public boolean isEnableOCSP()
341     {
342         return _enableOCSP;
343     }
344
345     /* ------------------------------------------------------------ */
346     /** Enables On-Line Certificate Status Protocol support
347      * @param enableOCSP true - turn on, false - turn off
348      */
349     public void setEnableOCSP(boolean enableOCSP)
350     {
351         _enableOCSP = enableOCSP;
352     }
353
354     /* ------------------------------------------------------------ */
355     /**
356      * @return Location of the OCSP Responder
357      */
358     public String getOcspResponderURL()
359     {
360         return _ocspResponderURL;
361     }
362
363     /* ------------------------------------------------------------ */
364     /** Set the location of the OCSP Responder.
365      * @param ocspResponderURL location of the OCSP Responder
366      */
367     public void setOcspResponderURL(String ocspResponderURL)
368     {
369         _ocspResponderURL = ocspResponderURL;
370     }
371 }