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.io.InputStream; 021import java.security.GeneralSecurityException; 022import java.security.KeyStore; 023import java.security.Security; 024import java.util.Enumeration; 025import java.util.LinkedList; 026import java.util.List; 027 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030 031/** 032 * A representation of configuration options for creating and loading a 033 * {@link KeyStore} instance. 034 */ 035public class KeyStoreParameters extends JsseParameters { 036 037 private static final Logger LOG = LoggerFactory.getLogger(KeyStoreParameters.class); 038 039 /** 040 * The optional type of the key store to load. See Appendix A in the 041 * <a href="http://download.oracle.com/javase/6/docs/technotes/guides/security/StandardNames.html#KeyStore"> 042 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> for more information on standard names. 043 */ 044 protected String type; 045 046 /** 047 * The optional password for reading/opening/verifying the key store. 048 */ 049 protected String password; 050 051 /** 052 * The optional provider identifier for instantiating the key store. 053 */ 054 protected String provider; 055 056 /** 057 * The optional file path, class path resource, or URL of the resource 058 * used to load the key store. 059 */ 060 protected String resource; 061 062 /** 063 * @see #setType(String) 064 */ 065 public String getType() { 066 return type; 067 } 068 069 /** 070 * Sets the type of the key store to create and load. See Appendix A in the 071 * <a href="http://download.oracle.com/javase/6/docs/technotes/guides/security/StandardNames.html#KeyStore" 072 * >Java Cryptography Architecture Standard Algorithm Name 073 * Documentation</a> for more information on standard names. 074 * 075 * @param value the key store type identifier (may be {@code null}) 076 */ 077 public void setType(String value) { 078 this.type = value; 079 } 080 081 /** 082 * @see #getPassword() 083 */ 084 public String getPassword() { 085 return password; 086 } 087 088 /** 089 * Set the optional password for reading/opening/verifying the key store. 090 * 091 * @param value the password value (may be {@code null}) 092 */ 093 public void setPassword(String value) { 094 this.password = value; 095 } 096 097 /** 098 * @see #setProvider(String) 099 */ 100 public String getProvider() { 101 return provider; 102 } 103 104 /** 105 * Sets the optional provider identifier for instantiating the key store. 106 * 107 * @param value the provider identifier (may be {@code null}) 108 * 109 * @see Security#getProviders() 110 */ 111 public void setProvider(String value) { 112 this.provider = value; 113 } 114 115 /** 116 * @see #getResource() 117 */ 118 public String getResource() { 119 return resource; 120 } 121 122 /** 123 * Sets the optional file path, class path resource, or URL of the resource 124 * used to load the key store. 125 * 126 * @param value the resource (may be {@code null}) 127 */ 128 public void setResource(String value) { 129 this.resource = value; 130 } 131 132 /** 133 * Creates a {@link KeyStoreParameters} instance based off of the configuration state 134 * of this instance. If {@link #getType()} returns {@code null}, the default 135 * key store type is loaded, otherwise the type will be of that specified. 136 * <p/> 137 * The created instance will always be loaded, but if the type requires an 138 * input stream and {@link #getResource()} returns {@code null}, the 139 * instance will be empty. The loading of the resource, if not {@code null}, 140 * is attempted by treating the resource as a file path, a class path 141 * resource, and a URL in that order. An exception is thrown if the resource 142 * cannot be resolved to readable input stream using any of the above 143 * methods. 144 * 145 * @return a configured and loaded key store 146 * @throws GeneralSecurityException if there is an error creating an instance 147 * with the given configuration 148 * @throws IOException if there is an error resolving the configured 149 * resource to an input stream 150 */ 151 public KeyStore createKeyStore() throws GeneralSecurityException, IOException { 152 LOG.trace("Creating KeyStore instance from KeyStoreParameters [{}].", this); 153 154 String ksType = this.parsePropertyValue(this.type); 155 if (ksType == null) { 156 ksType = KeyStore.getDefaultType(); 157 } 158 159 char[] ksPassword = null; 160 if (this.password != null) { 161 ksPassword = this.parsePropertyValue(this.password).toCharArray(); 162 } 163 164 KeyStore ks; 165 if (this.provider == null) { 166 ks = KeyStore.getInstance(ksType); 167 } else { 168 ks = KeyStore.getInstance(ksType, this.parsePropertyValue(this.provider)); 169 } 170 171 if (this.resource == null) { 172 ks.load(null, ksPassword); 173 } else { 174 InputStream is = this.resolveResource(this.parsePropertyValue(this.resource)); 175 ks.load(is, ksPassword); 176 } 177 178 if (LOG.isDebugEnabled()) { 179 List<String> aliases = new LinkedList<String>(); 180 181 Enumeration<String> aliasEnum = ks.aliases(); 182 while (aliasEnum.hasMoreElements()) { 183 aliases.add(aliasEnum.nextElement()); 184 } 185 186 LOG.debug("KeyStore [{}], initialized from [{}], is using provider [{}], has type [{}], and contains aliases {}.", 187 new Object[] {ks, this, ks.getProvider(), ks.getType(), aliases}); 188 } 189 190 return ks; 191 } 192 193 @Override 194 public String toString() { 195 StringBuilder builder = new StringBuilder(); 196 builder.append("KeyStoreParameters [type="); 197 builder.append(type); 198 builder.append(", password="); 199 builder.append("********"); 200 builder.append(", provider="); 201 builder.append(provider); 202 builder.append(", resource="); 203 builder.append(resource); 204 builder.append(", getContext()="); 205 builder.append(getCamelContext()); 206 builder.append("]"); 207 return builder.toString(); 208 } 209}