8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Copyright (c) 2009 Sun Microsystems Inc. All Rights Reserved
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The contents of this file are subject to the terms
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * of the Common Development and Distribution License
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (the License). You may not use this file except in
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * compliance with the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * You can obtain a copy of the License at
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * opensso/legal/CDDLv1.0.txt
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * See the License for the specific language governing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * permission and limitations under the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * When distributing Covered Code, include this CDDL
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Header Notice in each file and include the License file
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * at opensso/legal/CDDLv1.0.txt.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If applicable, add the following below the CDDL Header,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * with the fields enclosed by brackets [] replaced by
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * your own identifying information:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * $Id: JCECrypt.java,v 1.1 2009/05/05 21:24:47 veiming Exp $
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
7cc1037f41ae81479fcd529c51fe3507916b0512Peter Major * Portions Copyrighted 2011-2014 ForgeRock AS
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterpackage com.sun.identity.setup;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.services.util.AMEncryption;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.services.util.ConfigurableKey;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.services.util.JCEEncryption;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.io.BufferedReader;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.io.IOException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.io.StringReader;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.io.UnsupportedEncodingException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.shared.debug.Debug;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.shared.encode.Base64;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The class <code>Crypt</code> provides generic methods to encryt and decrypt
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * data. This class provides a pluggable architecture to encrypt and decrypt
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * data, using the <code>AMEncryption</code> interface class. A class that
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * implements <code>AMEncryption</code> must be specified via the system
f0cb5ab1344f9596bef788d2312629a152869f4eNeil Madden * property: <code>com.iplanet.security.encryptor</code>. If none is
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * provided, the default provided by iDSAME
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * <code>com.iplanet.services.util.JCEEncryption</code> will be used.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * <p>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Additionally, it provides a method to check if the calling class has
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * permission to call these methods. To enable the additional security, the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * property com.sun.identity.security.checkcaller must be set to true.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterpublic class JCECrypt {
7cc1037f41ae81479fcd529c51fe3507916b0512Peter Major
7cc1037f41ae81479fcd529c51fe3507916b0512Peter Major private static final String ENCRYPTOR_CLASS_PROPERTY = "com.iplanet.security.encryptor";
7cc1037f41ae81479fcd529c51fe3507916b0512Peter Major private static final String DEFAULT_ENCRYPTOR_CLASS = "com.iplanet.services.util.JCEEncryption";
7cc1037f41ae81479fcd529c51fe3507916b0512Peter Major private static final String DEFAULT_PWD = "KmhUnWR1MYWDYW4xuqdF5nbm+CXIyOVt";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static AMEncryption encryptor;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster encryptor = createInstance(DEFAULT_PWD);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static AMEncryption createInstance(String password) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster AMEncryption instance;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Construct the encryptor class
7cc1037f41ae81479fcd529c51fe3507916b0512Peter Major String encClass = System.getProperty(ENCRYPTOR_CLASS_PROPERTY, DEFAULT_ENCRYPTOR_CLASS);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
7cc1037f41ae81479fcd529c51fe3507916b0512Peter Major instance = Class.forName(encClass).asSubclass(AMEncryption.class).newInstance();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (Exception e) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Debug debug = Debug.getInstance("amSDK");
7cc1037f41ae81479fcd529c51fe3507916b0512Peter Major debug.error("JCECrypt.createInstance Unable to get class instance: " + encClass + ", falling back to the"
7cc1037f41ae81479fcd529c51fe3507916b0512Peter Major + " default implementation: " + DEFAULT_ENCRYPTOR_CLASS, e);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster instance = new JCEEncryption();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ((ConfigurableKey) instance).setPassword(password);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (Exception e) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Debug debug = Debug.getInstance("amSDK");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug != null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.error(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "JCECrypt.createInstance: failed to set password-based key",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster e);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return instance;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static String encode(String clearText, AMEncryption encr) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (clearText == null || clearText.length() == 0) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Encrypt the data
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster byte[] encData = null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster encData = encr.encrypt(clearText.getBytes("utf-8"));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (UnsupportedEncodingException uee) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Debug debug = Debug.getInstance("amSDK");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.error("Crypt:: utf-8 encoding is not supported");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster encData = encryptor.encrypt(clearText.getBytes());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // BASE64 encode the data
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String str = null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Perf Improvement : Removed the sync block and newed up the Encoder
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // object for every call. Its a trade off b/w CPU and mem usage.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster str = Base64.encode(encData).trim();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Serialize the data, i.e., remove \n and \r
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster BufferedReader bufReader = new BufferedReader(new StringReader(str));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster StringBuilder strClean = new StringBuilder(str.length());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String strTemp = null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster while ((strTemp = bufReader.readLine()) != null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster strClean.append(strTemp);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (IOException ioe) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Debug debug = Debug.getInstance("amSDK");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.error("Crypt:: Error while base64 encoding", ioe);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (strClean.toString());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static String encode(String clearText) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return encode(clearText, encryptor);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static String decode(String encoded, AMEncryption encr) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (encoded == null || encoded.length() == 0) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (null);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // BASE64 decode the data
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster byte[] encData = null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Perf Improvement : Removed the sync block and newed up the Decoder
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // object for every call. Its a trade off b/w CPU and mem usage.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster encData = Base64.decode(encoded.trim());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Decrypt the data
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster byte[] rawData = encr.decrypt(encData);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (rawData == null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (null);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Convert to String and return
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String answer = null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster answer = new String(rawData, "utf-8");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (UnsupportedEncodingException uue) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Debug debug = Debug.getInstance("amSDK");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.error("Crypt:: Unsupported encoding UTF-8", uue);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster answer = new String(rawData);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (answer);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Decode an encoded string
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param encoded
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The encoded string.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @return The decoded string.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static String decode(String encoded) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return decode(encoded, encryptor);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}