Manage device applications
Now, you can use the Knox APIs to manage certificates in TIMA CCM.
Create CCM Profile
This method initializes a CCMProfile object, sets its accessControlMethod to default and asks the user if they want to whitelist all the packages in the container.
private void createCCMProfile() { // Initialize a CCMProfile object mCCMProfileObj = new CCMProfile(); // Set its accessControlMethod to the default method mCCMProfileObj.accessControlMethod = CCMProfile.AccessControlMethod.LOCK_STATE; // Proceed to ask the user if they want to whitelist all packages whitelistAllPackages(); }
Whitelist all packages
This method asks the user if they want to whitelist all the packages in the container. Whitelisting allows them access to the token. If they do, the app skips asking the user to whitelist specific package names and set the CCM profile. If they don't, it asks the user to whitelist specific package names before setting the CCM profile.
private void whitelistAllPackages() { // Create a dialog box to show to the user new AlertDialog.Builder(this) // Set the dialog box's title .setTitle(getString(R.string.whitelist_all_packages)) // Set the dialog box's message .setMessage(getString(R.string.whitelist_all_packages_message)) // Set the action buttons .setPositiveButton(getString(R.string.opt_yes), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // Whitelist all the packages, then set the CCM profile mCCMProfileObj.whiteListAllPackages = true; setCCMProfile(); } }).setNegativeButton(getString(R.string.opt_no), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // Ask the user for specific package names to be whitelisted mCCMProfileObj.whiteListAllPackages = false; whitelistPackagesToAccessToken(); } }).show(); }
Whitelist specific packages
This method prompts the user to select certain packages in the container to be whitelisted, allowing them to access the token.
private void whitelistPackagesToAccessToken() { // List to contain the user's selected packages final List<String> selectedPackages = new ArrayList<>(); // List of installed packages on the device final List<String> installedPackages = getInstalledPackages(); // Create a dialog box to show to the user AlertDialog.Builder builder = new AlertDialog.Builder(this); // Set the dialog box's title builder.setTitle(getString(R.string.whitelist_packages_list_title)); // Convert the list of installed packages to an array final String[] installedPackagesArr = installedPackages.toArray( new String[installedPackages.size()]); builder.setMultiChoiceItems(installedPackagesArr, null, new DialogInterface.OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int indexSelected, boolean isChecked) { // If user selects a package in the list String selectedPackage = installedPackagesArr[indexSelected]; // If the package is checked, then add it to the selected items if (isChecked) { selectedPackages.add(selectedPackage); } else if (selectedPackages.contains(selectedPackage)) { selectedPackages.remove(selectedPackage); } } }) // Set the action buttons .setPositiveButton(getString(R.string.option_confirm), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { // Set the CCM Profile's packageList to that of whitelisted packages by user mCCMProfileObj.packageList = selectedPackages; // Proceed to apply the CCM profile setCCMProfile(); dialog.dismiss(); } }) .setNegativeButton(getString(R.string.option_cancel), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { // Cancel CCM Profile creation mCCMProfileObj = null; mUtils.log(getString(R.string.cancel_ccm_profile)); dialog.dismiss(); } }); AlertDialog dialog = builder.create(); // Show the dialog box to the user dialog.show(); }
Set CCM Profile
This method applies the CCM profile created by the user through the dialog boxes.
private void setCCMProfile () { // Instantiate the EnterpriseKnoxManager class EnterpriseKnoxManager enterpriseKnoxManager = EnterpriseKnoxManager.getInstance(this); // Get the ClientCertificateManager where the setCCMProfile method lives ClientCertificateManager clientCertificateManager = enterpriseKnoxManager. getClientCertificateManagerPolicy(); mUtils.log(getString(R.string.about_to_apply_profile)); // display the current CCM Profile Object's access method mUtils.log(getString(R.string.display_ccm_access, mCCMProfileObj.accessControlMethod)); // display whether the CCM profile whitelisted all packages mUtils.log(getString(R.string.display_ccm_whitelist_all_packages, mCCMProfileObj.whiteListAllPackages)); // if not whitelisting all packages, display each whitelisted package if (!mCCMProfileObj.whiteListAllPackages) { mUtils.log(getString(R.string.display_ccm_packagelist)); // display the CCM profile's package list for (String packageName : mCCMProfileObj.packageList) { mUtils.log(getString(R.string.input_package_name, packageName)); } } try { // Apply the CCM Profile boolean result = clientCertificateManager.setCCMProfile(mCCMProfileObj); // Display CCM profile set result if (result) { mUtils.log(getString(R.string.ccm_profile_set_successfully)); } else { mUtils.log(getString(R.string.ccm_profile_failed)); } } catch (SecurityException e) { mUtils.processException(e, TAG); } }
Get CCM Profile
This method gets the current CCM profile set through setCCMProfile, and displays its details to the user.
private void getCCMProfile () { // Instantiate the EnterpriseKnoxManager class EnterpriseKnoxManager enterpriseKnoxManager = EnterpriseKnoxManager.getInstance(this); // Get the ClientCertificateManager where the setCCMProfile method lives ClientCertificateManager clientCertificateManager = enterpriseKnoxManager. getClientCertificateManagerPolicy(); try { CCMProfile currentProfile = clientCertificateManager.getCCMProfile(); if (currentProfile != null) { mUtils.log(getString(R.string.display_current_profile)); // display the current CCM Profile Object's access method mUtils.log(getString(R.string.display_ccm_access, currentProfile.accessControlMethod)); // display whether the CCM profile whitelisted all packages mUtils.log(getString(R.string.display_ccm_whitelist_all_packages, currentProfile.whiteListAllPackages)); // if not whitelisting all packages, display each whitelisted package if (!currentProfile.whiteListAllPackages) { mUtils.log(getString(R.string.display_ccm_packagelist)); // display the CCM profile's package list for (String packageName : currentProfile.packageList) { mUtils.log(getString(R.string.input_package_name, packageName)); } } } else { mUtils.log(getString(R.string.no_profile_set)); } } catch (Exception e) { mUtils.processException(e, TAG); } }
Delete CCM Profile
This method deletes the current CCM Profile.
private void deleteCCMProfile () { // Instantiate the EnterpriseKnoxManager class EnterpriseKnoxManager enterpriseKnoxManager = EnterpriseKnoxManager.getInstance(this); // Get the ClientCertificateManager where the setCCMProfile method lives ClientCertificateManager clientCertificateManager = enterpriseKnoxManager .getClientCertificateManagerPolicy(); try { boolean result = clientCertificateManager.deleteCCMProfile(); if (result) { // Delete CCM Profile result mUtils.log(getString(R.string.ccm_profile_delete_successfully)); } else { mUtils.log(getString(R.string.ccm_profile_delete_failed)); } } catch (SecurityException e) { mUtils.processException(e, TAG); } }
Get default Certificate Alias
This method returns the default certificate alias, if one exists for the device. The default certificate is a device-unique certificate rooted at the Samsung root certificate, and can be used to uniquely identify a Samsung device.
private void getDefaultCertificateAlias() { // Instantiate the EnterpriseKnoxManager class EnterpriseKnoxManager enterpriseKnoxManager = EnterpriseKnoxManager.getInstance(this); // Get the ClientCertificateManager where the setCCMProfile method lives ClientCertificateManager clientCertificateManager = enterpriseKnoxManager. getClientCertificateManagerPolicy(); try { String defaultAlias = clientCertificateManager.getDefaultCertificateAlias(); if (defaultAlias != null) { // Display the default certificate alias mUtils.log(getString(R.string.get_default_certificate, defaultAlias)); } else { // No default certificate alias is available mUtils.log(getString(R.string.no_default_certificate)); } } catch (Exception e) { mUtils.processException(e, TAG); } }
Create Certificate
This method initializes a CertificateProfile object, and asks the user to set an alias for it.
private void createCertificate() { mCertificateProfile = new CertificateProfile(); mUtils.log(getString(R.string.creating_new_certificate_profile)); configureCertificate(); }
Configure Certificate
This method asks the user to provide a certificate alias, as well as choose to allow or disallow Wi-Fi, allow or disallow all packages, and enable or disable CSRResponse.
private void configureCertificate() { // Build a dialog to show the user AlertDialog.Builder builder = new AlertDialog.Builder(this); // WIth the title "Configure Certificate" builder.setTitle(getString(R.string.configure_certificate)); View viewInflated = LayoutInflater.from(this). inflate(R.layout.prompt_certificate_alias_wifi_packages_csrresponse, (ViewGroup) findViewById(R.id.configureCertificateGroup), false); final EditText edTxtCertAlias = viewInflated.findViewById(R.id.edtxtCertificateAlias); final CheckBox chkAllowAllPackages = viewInflated.findViewById(R.id.chkAllowAllPackages); final CheckBox chkAllowWifi = viewInflated.findViewById(R.id.chkAllowWifi); final CheckBox chkIsCSRResponse = viewInflated.findViewById(R.id.chkIsCSRResponse); builder.setView(viewInflated); builder.setPositiveButton(getString(R.string.option_confirm), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mCertificateProfile.alias = edTxtCertAlias.getText().toString(); mCertificateProfile.allowAllPackages = chkAllowAllPackages.isChecked(); mCertificateProfile.allowWiFi = chkAllowWifi.isChecked(); mCertificateProfile.isCSRResponse = chkIsCSRResponse.isChecked(); mUtils.log(getString(R.string.configuring_certificate_with)); mUtils.log(getString(R.string.certificate_alias_is, mCertificateProfile.alias)); mUtils.log(getString(R.string.certificate_allow_all_packages_is, mCertificateProfile.allowAllPackages)); mUtils.log(getString(R.string.certificate_allow_wifi_is, mCertificateProfile.allowWiFi)); mUtils.log(getString(R.string.certificate_iscsrresponse_is, mCertificateProfile.isCSRResponse)); // If provided alias is not empty string if (!(mCertificateProfile.alias).equals("")) { // Check if allow all packages checked if (mCertificateProfile.allowAllPackages) { // If it is, skip choosing specific packages to choose setCertificatePathAndPassword(); } else { // If it isn't, prompt user for specific packages to choose allowPackagesToAccessCertificate(); } } else { // If provided alias is empty, prompt user for valid alias mUtils.log(getString(R.string.provide_valid_alias)); } } }); builder.setNegativeButton(getString(R.string.option_cancel), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // Certificate creation cancelled. Reset the certificate profile. mCertificateProfile = null; mUtils.log(getString(R.string.certificate_profile_cancelled)); dialog.cancel(); } }); builder.show(); }
Allow packages to access current Certificate
private void allowPackagesToAccessCertificate () { // List to contain the user's selected packages final List<String> selectedPackages = new ArrayList<>(); // List of installed packages on the device final List<String> installedPackages = getInstalledPackages(); // Create a dialog box to show to the user AlertDialog.Builder builder = new AlertDialog.Builder(this); // Set the dialog box's title builder.setTitle(getString(R.string.whitelist_packages_list_title)); // Convert the list of installed packages to an array final String[] installedPackagesArr = installedPackages.toArray( new String[installedPackages.size()]); builder.setMultiChoiceItems(installedPackagesArr, null, new DialogInterface.OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int indexSelected, boolean isChecked) { // If user selects a package in the list String selectedPackage = installedPackagesArr[indexSelected]; // If package is checked, then add it to the selected items if (isChecked) { selectedPackages.add(selectedPackage); } else if (selectedPackages.contains(selectedPackage)) { selectedPackages.remove(selectedPackage); } } }) // Set the action buttons .setPositiveButton(getString(R.string.option_confirm), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { // Set the CertificateProfile's packageList to that of whitelisted packages mCertificateProfile.packageList = selectedPackages; // Proceed to set CertificateProfile's path and password setCertificatePathAndPassword(); dialog.dismiss(); } }) .setNegativeButton(getString(R.string.option_cancel), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { // Certificate creation cancelled. Reset the certificate profile. mCertificateProfile = null; mUtils.log(getString(R.string.certificate_profile_cancelled)); dialog.dismiss(); } }); AlertDialog dialog = builder.create(); // Show the dialog box to the user dialog.show(); }
Set Certificate path and password
This method sets the current certificate's path and password.
private void setCertificatePathAndPassword() { // Build a dialog for the user AlertDialog.Builder builder = new AlertDialog.Builder(this); // with the title "Set Certificate Path and Password" builder.setTitle(getString(R.string.set_cert_path_and_pass)); View viewInflated = LayoutInflater.from(this). inflate(R.layout.prompt_certificate_path_and_password, (ViewGroup) findViewById(R.id.certificatePassAndPathGroup), false); final EditText edTxtCertPath = viewInflated.findViewById(R.id.edTxtCertificatePath); final EditText edTxtCertPassword = viewInflated.findViewById(R.id.edTxtCertificatePassword); builder.setView(viewInflated); builder.setPositiveButton(getString(R.string.option_confirm), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String path = Environment.getExternalStorageDirectory() + "/"; String password = edTxtCertPassword.getText().toString(); mUtils.log(getString(R.string.provided_cert_path_and_pass)); // Install the path and password installCertificate(path, password); } }); builder.setNegativeButton(getString(R.string.option_cancel), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // Certificate creation cancelled. Reset the certificate profile. mCertificateProfile = null; mUtils.log(getString(R.string.certificate_profile_cancelled)); dialog.cancel(); } }); builder.show(); }
Install Certificate
This method installs the current certificate with user-provided details.
private void installCertificate(String path, String password) { mUtils.log(getString(R.string.installing_certificate)); // Initialize the EnterpriseKnoxManager class EnterpriseKnoxManager enterpriseKnoxManager = EnterpriseKnoxManager.getInstance(this); // Get the ClientCertificateManager where the installCertificate method lives ClientCertificateManager clientCertificateManager = enterpriseKnoxManager.getClientCertificateManagerPolicy(); try { grantReadExternalStorageRuntimePermission(); // Get the byte array from the provided path byte[] certificateBuffer = Utils.getByteArrayFromPath(path); // Install the certificate with the profile config, byte array and password provided boolean result = clientCertificateManager. installCertificate(mCertificateProfile, certificateBuffer, password); if (result) { mUtils.log(getString(R.string.certificate_profile_installed_successfully)); } else { mUtils.log(getString(R.string.certificate_profile_installation_failed)); } } catch (Exception e) { mUtils.processException(e, TAG); } }
Get installed packages
This method returns a list of installed package names on the device.
private List<String> getInstalledPackages () { // Get list of installed packages List<PackageInfo> packages = getPackageManager().getInstalledPackages(0); // Initialize a list of package names ArrayList<String> packageList = new ArrayList<>(); // For each installed package for (PackageInfo pInfo : packages) { // Add its package name to the return list packageList.add(pInfo.packageName); } return packageList; }
Prompt user to delete Certificate
This method prompts the user for a certificate alias to delete.
private void promptUserToDeleteCertificate () { // Create a dialog box AlertDialog.Builder builder = new AlertDialog.Builder(this); // with the title "Delete Certificate." builder.setTitle(getString(R.string.delete_certificate)); View viewInflated = LayoutInflater.from(this). inflate(R.layout.prompt_certificate_alias_to_delete, (ViewGroup) findViewById(R.id.deleteCertGroup), false); final EditText edTxtCertAlias = viewInflated.findViewById(R.id.edtxtCertificateAlias); builder.setView(viewInflated); builder.setPositiveButton(getString(R.string.option_confirm), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // Get the user provided alias String alias = edTxtCertAlias.getText().toString(); // If alias is valid if (!alias.equals("")) { // Delete the certificate with an alias that matches provided alias. deleteCertificate(alias); } else { mUtils.log(getString(R.string.no_alias_entered)); } } }); builder.setNegativeButton(getString(R.string.option_cancel), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mCertificateProfile = null; mUtils.log(getString(R.string.certificate_profile_deletion_cancelled)); dialog.cancel(); } }); builder.show(); }
Delete certificate
This method deletes a certificate with an alias that matches the user-provided alias.
private void deleteCertificate (String alias) { // Instantiate the EnterpriseKnoxManager class EnterpriseKnoxManager enterpriseKnoxManager = EnterpriseKnoxManager.getInstance(this); // Get the ClientCertificateManager where the setCCMProfile method lives ClientCertificateManager clientCertificateManager = enterpriseKnoxManager. getClientCertificateManagerPolicy(); try { // attempt to delete the certificate boolean result = clientCertificateManager.deleteCertificate(alias); if (result) { mUtils.log(getString(R.string.certificate_profile_deleted_successfully)); } else { mUtils.log(getString(R.string.certificate_profile_deletion_failed)); } } catch (SecurityException e) { mUtils.processException(e, TAG); } }
Prompt user for a package name
This method prompts the user for a package name to either add or remove from the exempt list, or check if it is affected by CCM policy.
private void promptUserForPackage (final int type) { // Create a dialog box AlertDialog.Builder builder = new AlertDialog.Builder(this); // With a title depending on what button the user pressed switch (type) { // Title to add package to exempt list case ADD_PACKAGE: builder.setTitle(getString(R.string.add_package_to_exempt_list)); break; // Title to remove package from exempt list case REMOVE_PACKAGE: builder.setTitle(getString(R.string.remove_package_from_exempt_list)); break; // Title to check if CCM policy is enabled for a package case CHECK_PACKAGE: builder.setTitle(getString(R.string.check_ccm_policy_enabled_for_package)); break; default: return; } View viewInflated = LayoutInflater.from(this). inflate(R.layout.prompt_package_name, (ViewGroup) findViewById(R.id.packageNameInputGroup), false); final EditText edTxtPackageName = viewInflated.findViewById(R.id.edTxtPackageName); builder.setView(viewInflated); builder.setPositiveButton(getString(R.string.option_confirm), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // Get the user provided package name String packageName = edTxtPackageName.getText().toString(); switch (type) { case ADD_PACKAGE: addPackageToExemptList(packageName); break; case REMOVE_PACKAGE: removePackageFromExemptList(packageName); break; case CHECK_PACKAGE: checkCCMEnabledForPackage(packageName); break; default: break; } } }); builder.setNegativeButton(getString(R.string.option_cancel), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); builder.show(); }
Add package to the exempt list
This method adds the given package name to the exempt list. This is required in case an app (running in background) needs access to certificates when the device or container is locked, or the user is not expected to enter a password. An example of a package that requires exemption is a third-party VPN application that needs to access certificates without user interaction.
private void addPackageToExemptList (String packageName) { // Instantiate the EnterpriseKnoxManager class EnterpriseKnoxManager enterpriseKnoxManager = EnterpriseKnoxManager.getInstance(this); // Get the ClientCertificateManager where the addPackageToExemptList method lives ClientCertificateManager clientCertificateManager = enterpriseKnoxManager. getClientCertificateManagerPolicy(); try { // attempt to add package name to exempt list boolean result = clientCertificateManager.addPackageToExemptList(packageName); if (result) { mUtils.log(getString(R.string.package_name_added_exempt_list_success)); } else { mUtils.log(getString(R.string.package_name_added_exempt_list_failed)); } } catch (SecurityException e) { mUtils.processException(e, TAG); } }
Remove package from the exempt list
This method removes the given package name from the exempt list.
private void removePackageFromExemptList (String packageName) { // Instantiate the EnterpriseKnoxManager class EnterpriseKnoxManager enterpriseKnoxManager = EnterpriseKnoxManager.getInstance(this); // Get the ClientCertificateManager where the removePackageFromExemptList method lives ClientCertificateManager clientCertificateManager = enterpriseKnoxManager. getClientCertificateManagerPolicy(); try { // attempt to add package name to exempt list boolean result = clientCertificateManager.removePackageFromExemptList(packageName); if (result) { mUtils.log(getString(R.string.package_name_remove_exempt_list_success)); } else { mUtils.log(getString(R.string.package_name_remove_exempt_list_failed)); } } catch (SecurityException e) { mUtils.processException(e, TAG); } }
Check CCM Policy for a package
This method checks if a CCM policy is enabled for a package.
private void checkCCMEnabledForPackage (String packageName) { // Instantiate the EnterpriseKnoxManager class EnterpriseKnoxManager enterpriseKnoxManager = EnterpriseKnoxManager.getInstance(this); // Get the ClientCertificateManager where the isCCMPolicyEnabledForPackage method lives ClientCertificateManager clientCertificateManager = enterpriseKnoxManager. getClientCertificateManagerPolicy(); try { // attempt to add package name to exempt list boolean result = clientCertificateManager.isCCMPolicyEnabledForPackage(packageName); if (result) { mUtils.log(getString(R.string.ccm_policy_enabled_for_package, packageName)); } else { mUtils.log(getString(R.string.ccm_policy_not_enabled_for_package, packageName)); } } catch (SecurityException e) { mUtils.processException(e, TAG); } }
Toggle TIMA Keystore state
This method enables/disables the TIMA Keystore state.
private void toggleTimaKeystoreState () { // Instantiate the EnterpriseKnoxManager class EnterpriseKnoxManager enterpriseKnoxManager = EnterpriseKnoxManager.getInstance(this); // Get the TimaKeystore object where the enableTimaKeystore method lives TimaKeystore timaKeystore = enterpriseKnoxManager.getTimaKeystorePolicy(); try { // Check current status of the TimaKeystore boolean isTimaKeystoreEnabled = timaKeystore.isTimaKeystoreEnabled(); mUtils.log("Attempting to toggle. Is enabled? " + isTimaKeystoreEnabled); // Enable/disable the Tima Keystore boolean result = timaKeystore.enableTimaKeystore(!isTimaKeystoreEnabled); if (result) { mUtils.log(getString(R.string.toggled_tima_keystore, !isTimaKeystoreEnabled)); } else { mUtils.log(getString(R.string.failed_to_toggle_tima_keystore)); } } catch (SecurityException e) { mUtils.processException(e, TAG); } }
Display TIMA Keystore status
This method displays the TIMA Keystore status as "enabled" or "disabled".
private void isTimaKeystoreEnabled () { // Instantiate the EnterpriseKnoxManager class EnterpriseKnoxManager enterpriseKnoxManager = EnterpriseKnoxManager.getInstance(this); // Get the TimaKeystore object where the enableTimaKeystore method lives TimaKeystore timaKeystore = enterpriseKnoxManager.getTimaKeystorePolicy(); try { // Check current status of the TimaKeystore boolean isTimaKeystoreEnabled = timaKeystore.isTimaKeystoreEnabled(); mUtils.log(getString(R.string.tima_keystore_status, isTimaKeystoreEnabled)); } catch (SecurityException e) { mUtils.processException(e, TAG); } }
Tutorial Progress
You are 6/7 done! Go to the next step.