/* * CDDL HEADER START * * The contents of this file are subject to the terms of the Common Development * and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at * src/com/vodafone360/people/VODAFONE.LICENSE.txt or * http://github.com/360/360-Engine-for-Android * See the License for the specific language governing permissions and * limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each file and * include the License file at src/com/vodafone360/people/VODAFONE.LICENSE.txt. * If applicable, add the following below this CDDL HEADER, with the fields * enclosed by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * Copyright 2010 Vodafone Sales & Services Ltd. All rights reserved. * Use is subject to license terms. */ package com.vodafone360.people.service.utils; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collections; import java.util.Hashtable; import java.util.List; import java.util.Vector; import com.vodafone360.people.Settings; import com.vodafone360.people.SettingsManager; import com.vodafone360.people.datatypes.AuthSessionHolder; import com.vodafone360.people.utils.LogUtils; /** * Set of functions that are used for generating 'auth' parameter required for * cresting requests and is usually based on a valid session created on * sign-up/login. */ public class AuthUtils { /** * Generates a MD5 hash of the input. * * @param input - String from which MD5 will be created * @return String containing MD5 hash created from input parameter * @throws NullPointerException when input is NULL * @throws NullPointerException MD5 algorithm could not be found */ public static String getMd5Hash(String input) { if (input == null) { throw new NullPointerException("AuthUtils.getMd5Hash() input cannot be NULL"); } try { String md5 = new BigInteger(1, MessageDigest.getInstance("MD5") .digest(input.getBytes())).toString(16); while (md5.length() < 32) { md5 = "0" + md5; } return md5; } catch (NoSuchAlgorithmException e) { LogUtils .logE("AuthUtils.getMd5Hash() NoSuchAlgorithmException, indicates that MD5 algorithm could not be found."); throw new NullPointerException("AuthUtils.getMd5Hash() NoSuchAlgorithmException"); } } /** * Calculates the AUTH parameter using a list of NameValues. TODO: Why is * this called differently for every API? * * @param functionName - String representation of function, using the * "class/funcName" convention e.g. * "auth/getsessionbycredentials". Typically empty. * @param parameters - List of name/value pairs * @param timeStamp - String containing absolute time stamps, generated by * calls to getCurrentTimeInSeconds() * @param session - Valid session object or NULL * @return AUTH parameter String * @throws NullPointerException when functionName is NULL * @throws NullPointerException when parameters is NULL * @throws NullPointerException when timeStamp is NULL */ public static String calculateAuth(String functionName, Hashtable<String, Object> parameters, String timeStamp, AuthSessionHolder session) { LogUtils.logI("AuthUtils.calculateAuth() Call to function [" + functionName + "]"); if (functionName == null) { throw new NullPointerException("AuthUtils.calculateAuth() functionName cannot be NULL"); } if (parameters == null) { throw new NullPointerException("AuthUtils.calculateAuth() parameters cannot be NULL"); } if (timeStamp == null) { throw new NullPointerException("AuthUtils.calculateAuth() timeStamp cannot be NULL"); } StringBuffer toMd5 = new StringBuffer(); toMd5.append(SettingsManager.getProperty(Settings.APP_SECRET_KEY)); if (session != null) { toMd5.append("&" + session.sessionSecret); } toMd5.append( "&" + functionName); List<String> sortedList = AuthUtils.getSortedListOfKeys(parameters); for (int i = 0; i < sortedList.size(); i++) { String key = sortedList.get(i); toMd5.append("&" + createSigningString(key, parameters.get(key))); } LogUtils.logI("AuthUtils.calculateAuth() Before auth[" + toMd5 + "]"); if (session == null) { return SettingsManager.getProperty(Settings.APP_KEY_ID) + "::" + timeStamp + "::" + getMd5Hash(toMd5.toString()); } else { return SettingsManager.getProperty(Settings.APP_KEY_ID) + "::" + session.sessionID + "::" + timeStamp + "::" + getMd5Hash(toMd5.toString()); } } /** * Calculates a signing string from a name/value pair * * @param inputString - String name. * @param inputObject - Object value can be Hashtable, Vector, byte[] or * String. * @return Signing String * @throws NullPointerException when inputString is NULL * @throws NullPointerException when inputObject is NULL */ @SuppressWarnings("unchecked") private static String createSigningString(String inputString, Object inputObject) { if (inputString == null) { throw new NullPointerException("AuthUtils.createSigning() inputString cannot be NULL"); } if (inputObject == null) { throw new NullPointerException("AuthUtils.createSigning() inputObject cannot be NULL"); } if (inputObject instanceof Hashtable<?, ?>) { return inputString + "=" + createSignOfHastable((Hashtable<String, Object>)inputObject); } else if (inputObject instanceof Vector<?>) { return inputString + "=" + createSignOfVector((Vector<Object>)inputObject); } else if (inputObject instanceof byte[]) { return inputString + "=" + getMd5Hash(createSignOfByteAray((byte[])inputObject)); } else { return inputString + "=" + inputObject.toString(); } } /** * Calculates the sign value from a Hash table * * @param hashTable - Given Hash table * @return Sign value String * @throws NullPointerException when hashTable is NULL */ private static String createSignOfHastable(Hashtable<String, Object> hashTable) { if (hashTable == null) { throw new NullPointerException( "AuthUtils.createSignOfHastable() hashTable cannot be NULL"); } StringBuffer returnString = new StringBuffer(); List<String> list = AuthUtils.getSortedListOfKeys(hashTable); for (int i = 0; i < list.size(); i++) { String key = list.get(i); Object obj = hashTable.get(key); returnString.append(createSigningString(key, obj)); if (i < list.size() - 1) { returnString.append("&"); } } return returnString.toString(); } /** * Calculates the sign value from a Vector * * @param hashTable - Given Vector * @return Sign value String * @throws NullPointerException when vector is NULL */ @SuppressWarnings("unchecked") private static String createSignOfVector(Vector<Object> vector) { if (vector == null) { throw new NullPointerException("AuthUtils.createSignOfByteAray() vector cannot be NULL"); } StringBuffer ret = new StringBuffer(); for (int i = 0; i < vector.size(); i++) { Object tempObject = vector.get(i); if (tempObject instanceof Hashtable<?, ?>) { ret.append(createSignOfHastable((Hashtable<String, Object>) tempObject)); } else if (tempObject instanceof Vector<?>) { ret.append(createSignOfVector((Vector<Object>) tempObject)); } else { ret.append(tempObject.toString()); } if (i < vector.size() - 1) { ret.append("&"); } } return ret.toString(); } /** * Calculates the sign value from a byte array * * @param bytes - Given byte array * @return Sign value String * @throws NullPointerException when bytes is NULL */ private static String createSignOfByteAray(byte[] bytes) { if (bytes == null) { throw new NullPointerException("AuthUtils.createSignOfByteAray() bytes cannot be NULL"); } return String.valueOf(bytes.length); } /** * Returns a list of keys from the map in alphabetical order * * @param map The map to sort * @return The ordered list of keys */ private static List<String> getSortedListOfKeys(Hashtable<String, Object> map) { List<String> mList = new ArrayList<String>(map.keySet()); Collections.sort(mList); return mList; } }