001    /*
002     * ====================================================================
003     *
004     *  Licensed to the Apache Software Foundation (ASF) under one or more
005     *  contributor license agreements.  See the NOTICE file distributed with
006     *  this work for additional information regarding copyright ownership.
007     *  The ASF licenses this file to You under the Apache License, Version 2.0
008     *  (the "License"); you may not use this file except in compliance with
009     *  the License.  You may obtain a copy of the License at
010     *
011     *      http://www.apache.org/licenses/LICENSE-2.0
012     *
013     *  Unless required by applicable law or agreed to in writing, software
014     *  distributed under the License is distributed on an "AS IS" BASIS,
015     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016     *  See the License for the specific language governing permissions and
017     *  limitations under the License.
018     * ====================================================================
019     *
020     * This software consists of voluntary contributions made by many
021     * individuals on behalf of the Apache Software Foundation.  For more
022     * information on the Apache Software Foundation, please see
023     * <http://www.apache.org/>.
024     *
025     */
026    
027    package org.apache.commons.httpclient.contrib.ssl;
028    
029    import java.security.KeyStore;
030    import java.security.KeyStoreException;
031    import java.security.NoSuchAlgorithmException;
032    import java.security.cert.CertificateException;
033    import java.security.cert.X509Certificate;
034    
035    import javax.net.ssl.TrustManagerFactory;
036    import javax.net.ssl.TrustManager;
037    import javax.net.ssl.X509TrustManager;
038    import org.apache.commons.logging.Log; 
039    import org.apache.commons.logging.LogFactory;
040    
041    /**
042     * <p>
043     * EasyX509TrustManager unlike default {@link X509TrustManager} accepts 
044     * self-signed certificates. 
045     * </p>
046     * <p>
047     * This trust manager SHOULD NOT be used for productive systems 
048     * due to security reasons, unless it is a concious decision and 
049     * you are perfectly aware of security implications of accepting 
050     * self-signed certificates
051     * </p>
052     * 
053     * @author <a href="mailto:adrian.sutton@ephox.com">Adrian Sutton</a>
054     * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
055     * 
056     * <p>
057     * DISCLAIMER: HttpClient developers DO NOT actively support this component.
058     * The component is provided as a reference material, which may be inappropriate
059     * for use without additional customization.
060     * </p>
061     */
062    
063    public class EasyX509TrustManager implements X509TrustManager
064    {
065        private X509TrustManager standardTrustManager = null;
066    
067        /** Log object for this class. */
068        private static final Log LOG = LogFactory.getLog(EasyX509TrustManager.class);
069    
070        /**
071         * Constructor for EasyX509TrustManager.
072         */
073        public EasyX509TrustManager(KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException {
074            super();
075            TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
076            factory.init(keystore);
077            TrustManager[] trustmanagers = factory.getTrustManagers();
078            if (trustmanagers.length == 0) {
079                throw new NoSuchAlgorithmException("no trust manager found");
080            }
081            this.standardTrustManager = (X509TrustManager)trustmanagers[0];
082        }
083    
084        /**
085         * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],String authType)
086         */
087        public void checkClientTrusted(X509Certificate[] certificates,String authType) throws CertificateException {
088            standardTrustManager.checkClientTrusted(certificates,authType);
089        }
090    
091        /**
092         * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],String authType)
093         */
094        public void checkServerTrusted(X509Certificate[] certificates,String authType) throws CertificateException {
095            if ((certificates != null) && LOG.isDebugEnabled()) {
096                LOG.debug("Server certificate chain:");
097                for (int i = 0; i < certificates.length; i++) {
098                    LOG.debug("X509Certificate[" + i + "]=" + certificates[i]);
099                }
100            }
101            if ((certificates != null) && (certificates.length == 1)) {
102                certificates[0].checkValidity();
103            } else {
104                standardTrustManager.checkServerTrusted(certificates,authType);
105            }
106        }
107    
108        /**
109         * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
110         */
111        public X509Certificate[] getAcceptedIssuers() {
112            return this.standardTrustManager.getAcceptedIssuers();
113        }
114    }