Back to project page cryptfs-password-manager.
The source code is released under:
Apache License
If you think the Android project cryptfs-password-manager listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package org.nick.cryptfs.passwdmanager; /*w w w .j av a2s . c o m*/ import android.os.Build; import android.util.Log; import java.io.UnsupportedEncodingException; import java.util.List; import java.util.regex.Pattern; public class CryptfsCommands { private static final String TAG = CryptfsCommands.class.getSimpleName(); private static final boolean IS_JB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN; private static final String GET_PROP_CMD_PATH = "/system/bin/getprop"; private static final String CRYPTO_STATE_PROP = "ro.crypto.state"; private static final String CRYPTO_STATE_ENCRYPTED = "encrypted"; private static final String VDC_CMD_PATH = "/system/bin/vdc"; private static final String CRYPTFS_VERIFYPW_CMD = VDC_CMD_PATH + " cryptfs verifypw '%s'"; private static final String CRYPTFS_VERIFYPW_LOLLIPOP_CMD = VDC_CMD_PATH + " cryptfs verifypw %s"; private static final String CRYPTFS_CHANGEPW_CMD = VDC_CMD_PATH + " cryptfs changepw '%s'"; private static final String CRYPTFS_CHANGEPW_PIN_CMD = VDC_CMD_PATH + " cryptfs changepw pin %s"; private static final String CRYPTFS_CHANGEPW_PASSWORD_CMD = VDC_CMD_PATH + " cryptfs changepw password %s"; private static final String CRYPTFS_GETPWTYPE_CMD = VDC_CMD_PATH + " cryptfs getpwtype"; private static final int VDC_STATUS_OK = 200; private static final int VDC_STATUS_PWTYPE_RESULT = 213; private static final String VDC_OK_RC = "0"; private static final Pattern PIN_PATTERN = Pattern.compile("\\d+"); public static final String PWTYPE_DEFAULT = "default"; public CryptfsCommands() { } public static boolean checkCryptfsPassword(String password) { List<String> response = SuShell.runWithSu(String.format( CRYPTFS_VERIFYPW_CMD, escape(password))); return checkVdcResponse(response); } public static boolean checkCryptfsPasswordLollipop(String password) { List<String> response = SuShell.runWithSu(String.format( CRYPTFS_VERIFYPW_LOLLIPOP_CMD, toHexAscii(password))); return checkVdcResponse(response); } public static String getPasswordType() { List<String> response = SuShell.runWithSu(CRYPTFS_GETPWTYPE_CMD); boolean responseOk = checkVdcResponse(response); // command not supported on older versions if (!responseOk) { return null; } return response.get(0).split(" ")[2]; } private static String toHexAscii(String password) { if (password == null) { return ""; } try { return toHex(password.getBytes("ASCII")); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } public static String toHex(byte[] bytes) { StringBuffer buff = new StringBuffer(); for (byte b : bytes) { buff.append(String.format("%02X", b)); } return buff.toString(); } private static String escape(String str) { // escape double quotes and backslashes // FrameworkListener::dispatchCommand checks for this String result = str.replaceAll("\\\"", "\\\\\""); // only do this if the original string had a backslash if (str.contains("\\")) { result = result.replaceAll("\\\\", "\\\\\\\\"); } // escape single quotes for the shell result = result.replaceAll("'", "'\\\\''"); return result; } private static boolean checkVdcResponse(List<String> result) { if (result.isEmpty()) { Log.wtf(TAG, "No result from vdc command?"); return false; } String status = result.get(0); String[] fields = status.split(" "); if (IS_JB && fields.length != 3) { Log.wtf(TAG, "Unrecognized vdc output format: " + status); return false; } if (!IS_JB && fields.length != 2) { Log.wtf(TAG, "Unrecognized vdc output format: " + status); return false; } int responseCode = Integer.parseInt(fields[0]); if (responseCode != VDC_STATUS_OK && responseCode != VDC_STATUS_PWTYPE_RESULT) { Log.e(TAG, "vdc returned error: " + status); return false; } if (responseCode == VDC_STATUS_PWTYPE_RESULT) { return true; } return IS_JB ? fields[2].equals(VDC_OK_RC) : fields[1] .equals(VDC_OK_RC); } public static boolean changeCryptfsPassword(String newPassword, String oldPassword) { List<String> response = SuShell.run("su", String.format(CRYPTFS_CHANGEPW_CMD, escape(newPassword))); boolean changeResult = checkVdcResponse(response); boolean verifyResult = checkCryptfsPassword(newPassword); if (!verifyResult) { // rollback boolean rollbackResult = changePasswordNoVerify(oldPassword); Log.d(TAG, "Password rollback succeeded: " + rollbackResult); return false; } return changeResult && verifyResult; } public static boolean changeCryptfsPasswordLollipop(String newPassword, String oldPassword) { String command = CRYPTFS_CHANGEPW_PASSWORD_CMD; if (PIN_PATTERN.matcher(newPassword).matches()) { command = CRYPTFS_CHANGEPW_PIN_CMD; } List<String> response = SuShell.run("su", String.format(command, toHexAscii(newPassword))); boolean changeResult = checkVdcResponse(response); boolean verifyResult = checkCryptfsPasswordLollipop(newPassword); if (!verifyResult) { // rollback boolean rollbackResult = changePasswordNoVerifyLollipop(oldPassword); Log.d(TAG, "Password rollback succeeded: " + rollbackResult); return false; } return changeResult && verifyResult; } private static boolean changePasswordNoVerify(String newPassword) { List<String> response = SuShell.run("su", String.format(CRYPTFS_CHANGEPW_CMD, escape(newPassword))); return checkVdcResponse(response); } private static boolean changePasswordNoVerifyLollipop(String newPassword) { String command = CRYPTFS_CHANGEPW_PASSWORD_CMD; if (PIN_PATTERN.matcher(newPassword).matches()) { command = CRYPTFS_CHANGEPW_PIN_CMD; } List<String> response = SuShell.run("su", String.format(command, toHexAscii(newPassword))); return checkVdcResponse(response); } public static boolean isDeviceEncrypted() { try { String value = getProp(CRYPTO_STATE_PROP); Log.d(TAG, CRYPTO_STATE_PROP + "= " + value); return value.equals(CRYPTO_STATE_ENCRYPTED); } catch (Exception e) { return false; } } private static String getProp(String propertyName) { return SuShell .runWithShell(GET_PROP_CMD_PATH + " " + CRYPTO_STATE_PROP).get( 0); } }