All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xipki.http.servlet.TlsHelper Maven / Gradle / Ivy

/*
 *
 * Copyright (c) 2013 - 2018 Lijun Liao
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.xipki.http.servlet;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Base64;

import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;

import io.netty.handler.codec.http.HttpRequest;
import io.netty.util.CharsetUtil;

/**
 * For more details please refer to
 * http://httpd.apache.org/docs/2.2/mod/mod_ssl.html
 * http://www.zeitoun.net/articles/client-certificate-x509-authentication-behind-reverse-proxy/start
 * 

* Please forward at least the following headers: *

    *
  • SSL_CLIENT_VERIFY
  • *
  • SSL_CLIENT_CERT
  • *
* @author Lijun Liao * @since 2.1.0 */ public class TlsHelper { private static CertificateFactory cf; static { try { cf = CertificateFactory.getInstance("X509"); } catch (Exception ex) { throw new RuntimeException(ex); } } private static final SimpleLruCache clientCerts = new SimpleLruCache<>(100); public static X509Certificate getTlsClientCert(HttpRequest request, SSLSession session, SslReverseProxyMode mode) throws IOException { if (mode == SslReverseProxyMode.NONE || mode == null) { if (session == null) { return null; } Certificate[] certs; try { certs = session.getPeerCertificates(); } catch (SSLPeerUnverifiedException ex) { certs = null; } Certificate cert = (certs == null || certs.length < 1) ? null : certs[0]; if (cert != null) { return (X509Certificate) cert; } } else if (mode != SslReverseProxyMode.APACHE) { throw new RuntimeException("Should not reach here, unknown SslReverseProxyMode " + mode); } // check whether this application is behind a reverse proxy and the TLS client certificate // is forwarded. Following headers should be configured to be forwarded: String clientVerify = request.headers().get("SSL_CLIENT_VERIFY"); if (clientVerify == null || clientVerify.isEmpty()) { return null; } if (!"SUCCESS".equalsIgnoreCase(clientVerify.trim())) { return null; } String pemClientCert = request.headers().get("SSL_CLIENT_CERT"); if (pemClientCert == null || pemClientCert.isEmpty()) { return null; } X509Certificate clientCert = clientCerts.get(pemClientCert); if (clientCert != null) { return clientCert; } try { String b64 = pemClientCert.replace("-----BEGIN CERTIFICATE-----", "") .replace("-----END CERTIFICATE-----", ""); byte[] encoded = Base64.getDecoder().decode(b64.getBytes(CharsetUtil.US_ASCII)); clientCert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(encoded)); } catch (CertificateException ex) { throw new IOException("could not parse Certificate", ex); } clientCerts.put(pemClientCert, clientCert); return clientCert; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy