/* This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, see http://www.gnu.org/licenses or write to the Free Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ package com.servoy.j2db.util; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.security.Key; import java.security.KeyStore; import java.util.Enumeration; import java.util.Properties; import javax.crypto.Cipher; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.SecretKeySpec; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocketFactory; import org.apache.commons.codec.binary.Base64; import com.servoy.j2db.server.shared.ApplicationServerRegistry; import com.servoy.j2db.server.shared.IApplicationServerSingleton; public class SecuritySupport { private static KeyStore passwordKeyStore; private static KeyStore sslKeyStore; private static char[] passphrase; // public static void main(String[] args) throws Exception // { // Settings settings = Settings.getDefaultSettings(false, null); // // //KeyStore ks = getKeyStore(settings); // initKeyStoreAndPassphrase(settings); // // Enumeration e = keyStore.aliases(); // if (e.hasMoreElements()) // { // String alias = (String) e.nextElement(); // Key desKey = new SecretKeySpec(new DESedeKeySpec(keyStore.getKey(alias, passphrase).getEncoded()).getKey(),"DESede"); // Cipher desCipher = Cipher.getInstance("DESede"); // desCipher.init(Cipher.ENCRYPT_MODE, desKey); // // // Our cleartext // byte[] cleartext = "This is just an example".getBytes(); // // // Encrypt the cleartext // byte[] ciphertext = desCipher.doFinal(cleartext); // // System.out.println(new String(ciphertext) + " lenght "+ciphertext.length); // // // Initialize the same cipher for decryption // desCipher.init(Cipher.DECRYPT_MODE, desKey); // // // Decrypt the ciphertext // byte[] cleartext1 = desCipher.doFinal(ciphertext); // // System.out.println(new String(cleartext1) + " lenght "+cleartext1.length); // System.out.println(Utils.encodeBASE64(ciphertext)); // } // } public static SSLContext getSSLContext(Properties settings) throws Exception { // set up key manager to do server authentication SSLContext ctx = SSLContext.getInstance("TLS"); //$NON-NLS-1$ KeyManagerFactory kmf = null; try { kmf = KeyManagerFactory.getInstance("SunX509"); //$NON-NLS-1$ } catch (Exception e) { Debug.log("couldn't get SunX509, now trying ibm"); kmf = KeyManagerFactory.getInstance("IbmX509"); //$NON-NLS-1$ } initSSLKeyStoreAndPassphrase(settings); kmf.init(sslKeyStore, passphrase); ctx.init(kmf.getKeyManagers(), null, null); return ctx; } public static SSLServerSocketFactory getSSLServerSocketFactory(Settings settings) throws Exception { return getSSLContext(settings).getServerSocketFactory(); } public static Key getCryptKey(Settings settings) throws Exception { if (passwordKeyStore == null) { InputStream is = null; try { is = SecuritySupport.class.getResourceAsStream("background.gif"); passwordKeyStore = KeyStore.getInstance("JKS"); passwordKeyStore.load(is, "passphrase".toCharArray()); } finally { Utils.closeInputStream(is); } } Enumeration e = passwordKeyStore.aliases(); while (e.hasMoreElements()) { String alias = (String)e.nextElement(); if (passwordKeyStore.isKeyEntry(alias)) { return new SecretKeySpec(new DESedeKeySpec(passwordKeyStore.getKey(alias, "passphrase".toCharArray()).getEncoded()).getKey(), "DESede"); } } return null; } @SuppressWarnings("nls") public static String encrypt(Settings settings, String value) throws Exception { if (value == null) return value; Cipher cipher = Cipher.getInstance("DESede"); cipher.init(Cipher.ENCRYPT_MODE, SecuritySupport.getCryptKey(settings)); return Utils.encodeBASE64(cipher.doFinal(value.getBytes())); } @SuppressWarnings("nls") public static String decrypt(Settings settings, String value) throws Exception { if (value == null) return value; Cipher cipher = Cipher.getInstance("DESede"); cipher.init(Cipher.DECRYPT_MODE, SecuritySupport.getCryptKey(settings)); return new String(cipher.doFinal(Utils.decodeBASE64(value))); } @SuppressWarnings("nls") public static String encryptUrlSafe(Settings settings, String value) throws Exception { if (value == null) return value; Cipher cipher = Cipher.getInstance("DESede"); cipher.init(Cipher.ENCRYPT_MODE, SecuritySupport.getCryptKey(settings)); return Base64.encodeBase64URLSafeString(cipher.doFinal(value.getBytes())); } @SuppressWarnings("nls") private static void initSSLKeyStoreAndPassphrase(Properties settings) throws Exception { if (sslKeyStore == null) { InputStream is = null; try { passphrase = "passphrase".toCharArray(); String filename = settings.getProperty("SocketFactory.SSLKeystorePath", ""); if (!"".equals(filename)) //$NON-NLS-1$ { try { File file = new File(filename); if (!file.exists()) { IApplicationServerSingleton appServer = ApplicationServerRegistry.get(); if (appServer != null && appServer.getServoyApplicationServerDirectory() != null) { String applicationServerDirectory = appServer.getServoyApplicationServerDirectory(); file = new File(applicationServerDirectory, filename); } if (!file.exists()) { Debug.error("couldn't resolve the ssl keystore file " + file.getAbsolutePath() + ", maybe the user dir (" + System.getProperty("user.dir") + ") of the application server is incorrect, please specify the system property: servoy.application_server.dir to point to the right directory [servoy_install]/application_server"); } } is = new FileInputStream(file); passphrase = settings.getProperty("SocketFactory.SSLKeystorePassphrase", "").toCharArray(); } catch (Exception e) { Debug.error("SSLKeystorePath not found: " + filename + " fallback to default one", e); } } if (is == null) { is = SecuritySupport.class.getResourceAsStream("background2.gif"); } sslKeyStore = KeyStore.getInstance("JKS"); sslKeyStore.load(is, passphrase); } finally { Utils.closeInputStream(is); } } } /** * */ public static void clearCryptKey() { sslKeyStore = null; passwordKeyStore = null; } }