001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.core.net.ssl; 015 016import java.io.FileNotFoundException; 017import java.io.IOException; 018import java.io.InputStream; 019import java.net.URL; 020import java.security.KeyStore; 021import java.security.KeyStoreException; 022import java.security.NoSuchAlgorithmException; 023import java.security.NoSuchProviderException; 024 025import ch.qos.logback.core.util.LocationUtil; 026 027/** 028 * A factory bean for a JCA {@link KeyStore}. 029 * <p> 030 * This object holds the configurable properties of a key store and uses them to 031 * create and load a {@link KeyStore} instance. 032 * 033 * @author Carl Harris 034 */ 035public class KeyStoreFactoryBean { 036 037 private String location; 038 private String provider; 039 private String type; 040 private String password; 041 042 /** 043 * Creates a new {@link KeyStore} using the receiver's configuration. 044 * 045 * @return key store 046 * @throws NoSuchProviderException if the provider specified by 047 * {@link #setProvider(String)} is not known to 048 * the platform 049 * @throws NoSuchAlgorithmException if the key store type specified by 050 * {@link #setType(String)} is not known to the 051 * specified provider (or the platform's 052 * default provider if the provider isn't 053 * specified) 054 * @throws KeyStoreException if some other error occurs in loading the 055 * key store from the resource specified by 056 * {@link #setLocation(String)} 057 */ 058 public KeyStore createKeyStore() throws NoSuchProviderException, NoSuchAlgorithmException, KeyStoreException { 059 060 if (getLocation() == null) { 061 throw new IllegalArgumentException("location is required"); 062 } 063 064 InputStream inputStream = null; 065 try { 066 URL url = LocationUtil.urlForResource(getLocation()); 067 inputStream = url.openStream(); 068 KeyStore keyStore = newKeyStore(); 069 keyStore.load(inputStream, getPassword().toCharArray()); 070 return keyStore; 071 } catch (NoSuchProviderException ex) { 072 throw new NoSuchProviderException("no such keystore provider: " + getProvider()); 073 } catch (NoSuchAlgorithmException ex) { 074 throw new NoSuchAlgorithmException("no such keystore type: " + getType()); 075 } catch (FileNotFoundException ex) { 076 throw new KeyStoreException(getLocation() + ": file not found"); 077 } catch (Exception ex) { 078 throw new KeyStoreException(getLocation() + ": " + ex.getMessage(), ex); 079 } finally { 080 try { 081 if (inputStream != null) { 082 inputStream.close(); 083 } 084 } catch (IOException ex) { 085 ex.printStackTrace(System.err); 086 } 087 } 088 } 089 090 /** 091 * Invokes the appropriate JCE factory method to obtain a new {@link KeyStore} 092 * object. 093 */ 094 private KeyStore newKeyStore() throws NoSuchAlgorithmException, NoSuchProviderException, KeyStoreException { 095 096 return getProvider() != null ? KeyStore.getInstance(getType(), getProvider()) : KeyStore.getInstance(getType()); 097 } 098 099 /** 100 * Gets the location of the key store resource. 101 * 102 * @return a String containing a URL for the resource 103 */ 104 public String getLocation() { 105 return location; 106 } 107 108 /** 109 * Sets the location of the key store resource. 110 * 111 * @param location a String containing a URL for the resource; if the URL string 112 * isn't prefixed by a scheme, the path is assumed to be 113 * relative to the root of the classpath. 114 */ 115 public void setLocation(String location) { 116 this.location = location; 117 } 118 119 /** 120 * Gets the type of key store to load. 121 * 122 * @return a key store type name (e.g. {@code JKS}); the 123 * {@link SSL#DEFAULT_KEYSTORE_TYPE} is returned if no type has been 124 * configured 125 */ 126 public String getType() { 127 if (type == null) { 128 return SSL.DEFAULT_KEYSTORE_TYPE; 129 } 130 return type; 131 } 132 133 /** 134 * Sets the type of key store to load. 135 * 136 * @param type a key store type name (e.g. {@code JKS}, {@code PKCS12}); the 137 * type specified must be supported by the provider specified by 138 * {@link #setProvider(String)} or by the platform's default 139 * provider if no provider is specified 140 */ 141 public void setType(String type) { 142 this.type = type; 143 } 144 145 /** 146 * Gets the JCA key store provider name. 147 * 148 * @return provider name or {@code null} if no provider has been configured 149 */ 150 public String getProvider() { 151 return provider; 152 } 153 154 /** 155 * Sets the JCA key store provider name. 156 * 157 * @param provider name of the JCA provider to utilize in creating the key store 158 */ 159 public void setProvider(String provider) { 160 this.provider = provider; 161 } 162 163 /** 164 * Gets the password to use to access the key store. 165 * 166 * @return password string; the {@link SSL#DEFAULT_KEYSTORE_PASSWORD} is 167 * returned if no password has been configured 168 */ 169 public String getPassword() { 170 if (password == null) { 171 return SSL.DEFAULT_KEYSTORE_PASSWORD; 172 } 173 return password; 174 } 175 176 /** 177 * Sets the password to use to access the keystore. 178 * 179 * @param password the password to set 180 */ 181 public void setPassword(String password) { 182 this.password = password; 183 } 184 185}