001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.util.jsse;
018
019import java.io.IOException;
020import java.security.GeneralSecurityException;
021import java.security.KeyStore;
022import java.security.Security;
023
024import javax.net.ssl.TrustManager;
025import javax.net.ssl.TrustManagerFactory;
026
027import org.slf4j.Logger;
028import org.slf4j.LoggerFactory;
029
030public class TrustManagersParameters extends JsseParameters {
031
032    private static final Logger LOG = LoggerFactory.getLogger(TrustManagersParameters.class);
033    
034    /**
035     * The key store configuration used to create the {@link KeyStoreParameters} that the
036     * {@link TrustManager}s produced by this object's configuration expose.
037     */
038    protected KeyStoreParameters keyStore;
039
040    /**
041     * The optional provider identifier for the {@link TrustManagerFactory} used to create
042     * the {@link TrustManager}s represented by this object's configuration.
043     */
044    protected String provider;
045
046    /**
047     * The optional algorithm name for the {@link TrustManagerFactory} used to
048     * create the {@link TrustManager}s represented by this object's
049     * configuration. See the <a href=
050     * "http://download.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html"
051     * >Java Secure Socket Extension Reference Guide</a> for information about
052     * standard algorithm names.
053     */
054    protected String algorithm;
055
056    /**
057     * To use a existing configured trust manager instead of using {@link TrustManagerFactory} to
058     * get the {@link TrustManager}.
059     */
060    protected TrustManager trustManager;
061    
062    /**
063     * Creates {@link TrustManager}s based on this instance's configuration and the
064     * {@code KeyStore} produced by the configuration returned from
065     * {@link #getKeyStore()}. The {@code KeyManager}s are produced from a
066     * factory created by using the provider and algorithm identifiers returned
067     * by {@link #getProvider()} and {@link #getAlgorithm()}, respectively. If
068     * either of these methods returns null, the default JSSE value is used
069     * instead.
070     * 
071     * @return the initialized {@code TrustManager}s
072     * @throws GeneralSecurityException if there is an error creating the
073     *             {@code TrustManagers}s or in creating the {@code KeyStore}
074     * @throws IOException if there is an error loading the {@code KeyStore}
075     *
076     * @see KeyStoreParameters#createKeyStore()
077     */
078    public TrustManager[] createTrustManagers() throws GeneralSecurityException, IOException {
079        if (trustManager != null) {
080            // use existing trust manager
081            return new TrustManager[]{trustManager};
082        }
083        
084        LOG.trace("Creating TrustManager[] from TrustManagersParameters [{}]", this);
085
086        TrustManager[] trustManagers = null;
087
088        if (this.getKeyStore() != null) {
089            String tmfAlgorithm = this.parsePropertyValue(this.getAlgorithm());
090            if (tmfAlgorithm == null) {
091                tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
092            }
093            
094            TrustManagerFactory tmf;
095            if (this.getProvider() == null) {
096                tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
097            } else {
098                tmf = TrustManagerFactory.getInstance(tmfAlgorithm, this.parsePropertyValue(this.getProvider()));
099            }
100            
101            LOG.debug("TrustManagerFactory [{}] is using provider [{}] and algorithm [{}].",
102                      new Object[] {tmf, tmf.getProvider(), tmf.getAlgorithm()});
103            
104            KeyStore ks = this.getKeyStore() == null ? null : this.getKeyStore().createKeyStore();
105            tmf.init(ks);
106            trustManagers = tmf.getTrustManagers();
107            
108            LOG.debug("TrustManager[] [{}], initialized from TrustManagerFactory [{}].", trustManagers, tmf);
109        }
110        
111        return trustManagers;
112    }
113
114    public KeyStoreParameters getKeyStore() {
115        return keyStore;
116    }
117
118    /**
119     * Sets the key store configuration used to create the {@link KeyStoreParameters} that the
120     * {@link TrustManager}s produced by this object's configuration expose.
121     * 
122     * @param value the configuration to use
123     */
124    public void setKeyStore(KeyStoreParameters value) {
125        this.keyStore = value;
126    }
127
128    public String getProvider() {
129        return provider;
130    }
131
132    /**
133     * Sets the optional provider identifier for the {@link TrustManagerFactory}
134     * used to create the {@link TrustManager}s represented by this object's
135     * configuration.
136     * 
137     * @param value the desired provider identifier or {@code null} to use the
138     *            highest priority provider implementing the algorithm
139     *            
140     * @see Security#getProviders()
141     */
142    public void setProvider(String value) {
143        this.provider = value;
144    }
145
146    public String getAlgorithm() {
147        return algorithm;
148    }
149
150    /**
151     * Sets optional algorithm name for the {@link TrustManagerFactory} used to create
152     * the {@link TrustManager}s represented by this object's configuration.  See the <a href=
153     * "http://download.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html"
154     * >Java Secure Socket Extension Reference Guide</a> for information about
155     * standard algorithm names.
156     * 
157     * @param value the desired algorithm or {@code null} to use default
158     * 
159     * @see TrustManagerFactory#getDefaultAlgorithm()
160     */
161    public void setAlgorithm(String value) {
162        this.algorithm = value;
163    }
164
165    public TrustManager getTrustManager() {
166        return trustManager;
167    }
168
169    /**
170     * To use a existing configured trust manager instead of using {@link TrustManagerFactory} to
171     * get the {@link TrustManager}.
172     */
173    public void setTrustManager(TrustManager trustManager) {
174        this.trustManager = trustManager;
175    }
176
177    @Override
178    public String toString() {
179        StringBuilder builder = new StringBuilder();
180        if (trustManager != null) {
181            builder.append("TrustManagerType[trustManager=");
182            builder.append(trustManager);
183            builder.append("]");
184        } else {
185            builder.append("TrustManagerType[keyStore=");
186            builder.append(keyStore);
187            builder.append(", provider=");
188            builder.append(provider);
189            builder.append(", algorithm=");
190            builder.append(algorithm);
191            builder.append("]");
192        }
193        return builder.toString();
194    }
195}