]> WPIA git - gigi.git/blobdiff - lib/jetty/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java
Importing upstream Jetty jetty-9.2.1.v20140609
[gigi.git] / lib / jetty / org / eclipse / jetty / security / authentication / ClientCertAuthenticator.java
diff --git a/lib/jetty/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java b/lib/jetty/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java
new file mode 100644 (file)
index 0000000..9694cf1
--- /dev/null
@@ -0,0 +1,371 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.security.authentication;
+
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.Principal;
+import java.security.cert.CRL;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.security.ServerAuthException;
+import org.eclipse.jetty.security.UserAuthentication;
+import org.eclipse.jetty.server.Authentication;
+import org.eclipse.jetty.server.Authentication.User;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.util.B64Code;
+import org.eclipse.jetty.util.security.CertificateUtils;
+import org.eclipse.jetty.util.security.CertificateValidator;
+import org.eclipse.jetty.util.security.Constraint;
+import org.eclipse.jetty.util.security.Password;
+
+/**
+ * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
+ */
+public class ClientCertAuthenticator extends LoginAuthenticator
+{
+    /** String name of keystore password property. */
+    private static final String PASSWORD_PROPERTY = "org.eclipse.jetty.ssl.password";
+
+    /** Truststore path */
+    private String _trustStorePath;
+    /** Truststore provider name */
+    private String _trustStoreProvider;
+    /** Truststore type */
+    private String _trustStoreType = "JKS";
+    /** Truststore password */
+    private transient Password _trustStorePassword;
+
+    /** Set to true if SSL certificate validation is required */
+    private boolean _validateCerts;
+    /** Path to file that contains Certificate Revocation List */
+    private String _crlPath;
+    /** Maximum certification path length (n - number of intermediate certs, -1 for unlimited) */
+    private int _maxCertPathLength = -1;
+    /** CRL Distribution Points (CRLDP) support */
+    private boolean _enableCRLDP = false;
+    /** On-Line Certificate Status Protocol (OCSP) support */
+    private boolean _enableOCSP = false;
+    /** Location of OCSP Responder */
+    private String _ocspResponderURL;
+
+    public ClientCertAuthenticator()
+    {
+        super();
+    }
+
+    @Override
+    public String getAuthMethod()
+    {
+        return Constraint.__CERT_AUTH;
+    }
+
+    
+
+    /**
+     * @return Authentication for request
+     * @throws ServerAuthException
+     */
+    @Override
+    public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException
+    {
+        if (!mandatory)
+            return new DeferredAuthentication(this);
+
+        HttpServletRequest request = (HttpServletRequest)req;
+        HttpServletResponse response = (HttpServletResponse)res;
+        X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
+
+        try
+        {
+            // Need certificates.
+            if (certs != null && certs.length > 0)
+            {
+
+                if (_validateCerts)
+                {
+                    KeyStore trustStore = getKeyStore(null,
+                            _trustStorePath, _trustStoreType, _trustStoreProvider,
+                            _trustStorePassword == null ? null :_trustStorePassword.toString());
+                    Collection<? extends CRL> crls = loadCRL(_crlPath);
+                    CertificateValidator validator = new CertificateValidator(trustStore, crls);
+                    validator.validate(certs);
+                }
+
+                for (X509Certificate cert: certs)
+                {
+                    if (cert==null)
+                        continue;
+
+                    Principal principal = cert.getSubjectDN();
+                    if (principal == null) principal = cert.getIssuerDN();
+                    final String username = principal == null ? "clientcert" : principal.getName();
+
+                    final char[] credential = B64Code.encode(cert.getSignature());
+
+                    UserIdentity user = login(username, credential, req);
+                    if (user!=null)
+                    {
+                        return new UserAuthentication(getAuthMethod(),user);
+                    }
+                }
+            }
+
+            if (!DeferredAuthentication.isDeferred(response))
+            {
+                response.sendError(HttpServletResponse.SC_FORBIDDEN);
+                return Authentication.SEND_FAILURE;
+            }
+
+            return Authentication.UNAUTHENTICATED;
+        }
+        catch (Exception e)
+        {
+            throw new ServerAuthException(e.getMessage());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Loads keystore using an input stream or a file path in the same
+     * order of precedence.
+     *
+     * Required for integrations to be able to override the mechanism
+     * used to load a keystore in order to provide their own implementation.
+     *
+     * @param storeStream keystore input stream
+     * @param storePath path of keystore file
+     * @param storeType keystore type
+     * @param storeProvider keystore provider
+     * @param storePassword keystore password
+     * @return created keystore
+     * @throws Exception
+     */
+    protected KeyStore getKeyStore(InputStream storeStream, String storePath, String storeType, String storeProvider, String storePassword) throws Exception
+    {
+        return CertificateUtils.getKeyStore(storeStream, storePath, storeType, storeProvider, storePassword);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Loads certificate revocation list (CRL) from a file.
+     *
+     * Required for integrations to be able to override the mechanism used to
+     * load CRL in order to provide their own implementation.
+     *
+     * @param crlPath path of certificate revocation list file
+     * @return a (possibly empty) collection view of java.security.cert.CRL objects initialized with the data from the
+     *         input stream.
+     * @throws Exception
+     */
+    protected Collection<? extends CRL> loadCRL(String crlPath) throws Exception
+    {
+        return CertificateUtils.loadCRL(crlPath);
+    }
+
+    @Override
+    public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, User validatedUser) throws ServerAuthException
+    {
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if SSL certificate has to be validated
+     */
+    public boolean isValidateCerts()
+    {
+        return _validateCerts;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param validateCerts
+     *            true if SSL certificates have to be validated
+     */
+    public void setValidateCerts(boolean validateCerts)
+    {
+        _validateCerts = validateCerts;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The file name or URL of the trust store location
+     */
+    public String getTrustStore()
+    {
+        return _trustStorePath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param trustStorePath
+     *            The file name or URL of the trust store location
+     */
+    public void setTrustStore(String trustStorePath)
+    {
+        _trustStorePath = trustStorePath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The provider of the trust store
+     */
+    public String getTrustStoreProvider()
+    {
+        return _trustStoreProvider;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param trustStoreProvider
+     *            The provider of the trust store
+     */
+    public void setTrustStoreProvider(String trustStoreProvider)
+    {
+        _trustStoreProvider = trustStoreProvider;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The type of the trust store (default "JKS")
+     */
+    public String getTrustStoreType()
+    {
+        return _trustStoreType;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param trustStoreType
+     *            The type of the trust store (default "JKS")
+     */
+    public void setTrustStoreType(String trustStoreType)
+    {
+        _trustStoreType = trustStoreType;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param password
+     *            The password for the trust store
+     */
+    public void setTrustStorePassword(String password)
+    {
+        _trustStorePassword = Password.getPassword(PASSWORD_PROPERTY,password,null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get the crlPath.
+     * @return the crlPath
+     */
+    public String getCrlPath()
+    {
+        return _crlPath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the crlPath.
+     * @param crlPath the crlPath to set
+     */
+    public void setCrlPath(String crlPath)
+    {
+        _crlPath = crlPath;
+    }
+
+    /**
+     * @return Maximum number of intermediate certificates in
+     * the certification path (-1 for unlimited)
+     */
+    public int getMaxCertPathLength()
+    {
+        return _maxCertPathLength;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param maxCertPathLength
+     *            maximum number of intermediate certificates in
+     *            the certification path (-1 for unlimited)
+     */
+    public void setMaxCertPathLength(int maxCertPathLength)
+    {
+        _maxCertPathLength = maxCertPathLength;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if CRL Distribution Points support is enabled
+     */
+    public boolean isEnableCRLDP()
+    {
+        return _enableCRLDP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Enables CRL Distribution Points Support
+     * @param enableCRLDP true - turn on, false - turns off
+     */
+    public void setEnableCRLDP(boolean enableCRLDP)
+    {
+        _enableCRLDP = enableCRLDP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if On-Line Certificate Status Protocol support is enabled
+     */
+    public boolean isEnableOCSP()
+    {
+        return _enableOCSP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Enables On-Line Certificate Status Protocol support
+     * @param enableOCSP true - turn on, false - turn off
+     */
+    public void setEnableOCSP(boolean enableOCSP)
+    {
+        _enableOCSP = enableOCSP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Location of the OCSP Responder
+     */
+    public String getOcspResponderURL()
+    {
+        return _ocspResponderURL;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the location of the OCSP Responder.
+     * @param ocspResponderURL location of the OCSP Responder
+     */
+    public void setOcspResponderURL(String ocspResponderURL)
+    {
+        _ocspResponderURL = ocspResponderURL;
+    }
+}