001 package org.apache.fulcrum.yaafi.framework.crypto; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 import org.apache.fulcrum.yaafi.framework.reflection.Clazz; 023 024 import java.io.InputStream; 025 026 /** 027 * Factory class to get a decrypting input stream for reading configuration 028 * files. The implementation uses dynamic class loading to make decryption 029 * an optional feature which is highly desirable when avoiding the ECCN 030 * export code problems. 031 * 032 * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl </a> 033 */ 034 035 public class CryptoStreamFactory 036 { 037 /** is the instance already initialized */ 038 private static boolean isInitialized; 039 040 /** the factory to create encrypting input streams */ 041 private static Object cryptoStreamFactory; 042 043 /** the name of the class to be loaded */ 044 private static String className = "org.apache.fulcrum.jce.crypto.CryptoStreamFactoryImpl"; 045 046 /** 047 * Create a (potentially) decrypting input stream using the default 048 * password. 049 * 050 * @param is the input stream to be decrypted 051 * @param isEncrypted the encryption mode (true|false|auto) 052 * @return a decrypting input stream 053 * @throws Exception reading the input stream failed 054 */ 055 public static InputStream getDecryptingInputStream( InputStream is, String isEncrypted ) 056 throws Exception 057 { 058 InputStream result; 059 060 if( isEncrypted.equalsIgnoreCase("true") ) 061 { 062 // a decrypting input stream was requested 063 result = createDecryptingInputStream(is, "getInputStream"); 064 } 065 else if( isEncrypted.equalsIgnoreCase("auto") && hasCryptoStreamFactory()) 066 { 067 // no user-supplied preferences but crypto stream is available 068 result = createDecryptingInputStream(is, "getSmartInputStream"); 069 } 070 else if( isEncrypted.equalsIgnoreCase("auto") && !hasCryptoStreamFactory()) 071 { 072 // no user-supplied perferences so we fall back to normal input stream 073 result = is; 074 } 075 else if( isEncrypted.equalsIgnoreCase("false") ) 076 { 077 // just use normal input stream 078 result = is; 079 } 080 else 081 { 082 throw new IllegalArgumentException("Unknown decryption mode : " + isEncrypted); 083 } 084 085 return result; 086 } 087 088 /** 089 * Factory method to create a decrypting input stream. 090 * 091 * @param is the input stream to be decrypted 092 * @param factoryMethodName the name of the factory method 093 * @return a decrypting input stream 094 * @throws Exception creating the decrypting input stream failed 095 */ 096 private static InputStream createDecryptingInputStream( InputStream is, String factoryMethodName ) 097 throws Exception 098 { 099 Class[] signature = {InputStream.class}; 100 Object[] args = {is}; 101 Object cryptoStreamFactory = getCryptoStreamFactory(); 102 103 if(cryptoStreamFactory == null) 104 { 105 throw new IllegalStateException("No CryptoStreamFactory available - unable to create a decrypting input stream"); 106 } 107 else 108 { 109 return (InputStream) Clazz.invoke(cryptoStreamFactory, factoryMethodName, signature, args); 110 } 111 } 112 113 /** 114 * Factory method to create a CryptoStreamFactory. 115 */ 116 private synchronized static Object getCryptoStreamFactory() 117 throws Exception 118 { 119 if(!isInitialized) 120 { 121 isInitialized = true; 122 ClassLoader clazzLoader = CryptoStreamFactory.class.getClassLoader(); 123 124 if(Clazz.hasClazz(clazzLoader, className)) 125 { 126 Class[] signature = {}; 127 Object[] args = {}; 128 Class clazz = Clazz.getClazz(clazzLoader, className); 129 cryptoStreamFactory = Clazz.newInstance(clazz, signature, args); 130 } 131 } 132 133 return cryptoStreamFactory; 134 } 135 136 /** 137 * @return true if a CryptoStreamFactory is available 138 */ 139 private static boolean hasCryptoStreamFactory() 140 throws Exception 141 { 142 return ( getCryptoStreamFactory() != null ); 143 } 144 }