Knox ISV SDK

Tutorials

This tutorial describes how you can use Samsung Knox Attestation to verify the integrity of a device. You can check if a device has been rooted or is running unauthorized firmware. You might do this, for example, to avoid handling private or confidential data on a device that might be compromised and be vulnerable to malware.

To perform a reliable attestation check, you must create both an Android app to initiate the attestation check on a device as well as a web script to communicate with Samsung's Attestation server.

Here is the end-to-end process:

Note that the Knox Attestation service is available to both ISVs, through the Knox ISV SDK, as well as MDM partners, through the Knox Premium SDK. This tutorial however describes the ISV SDK.

Before you start

Back to top
Set up your web server

Your web server communicates with Samsung’s Attestation Server, which provides you with nonces and translates blob data into attestation verdicts. Communication is through REST API calls over a secure HTTPS connection. You use JSON to build requests for and parse responses from the Attestation Server.

In the following examples, we use an Apache server with the Linux operating system, and the PHP scripting language. You can set up such a web server from scratch quite simply. If you don’t have a web server, you can enroll in a free or trial cloud service to get quick access to one.

If you are new to web server setup, here are some basic Linux commands to set up the server:

  1. install Ubuntu 14.0

  2. sudo apt-get update

  3. sudo apt-get install apache2

  4. sudo apt-get install php5 libapache2-mod-php5 php5-mcrypt php5-curl

  5. sudo /etc/init.d/apache2 restart

Alternatively, you can use a pre-built environment, such as that provided by Apache Friends.

Once you have a web server with PHP support, copy your scripts into the folder /var/www/html. In the sample Attestation app, there are two PHP scripts, called nonces.php and measurements.php, which you can copy into this folder.

For secure communication with the Attestation Server, you use an HTTPS connection. Use an SSL certificate to encrypt data sent over the connection. Make sure to purchase an SSL certificate from a trusted provider. Self-signed certificates are not trusted by the Attestation server. Also, make sure your certificate contains the complete certificate chain. For help, please consult with your web provider.

In the header of every REST API call to the Attestation server, you identify yourself by encoding your unique Attestation REST API key, which is described next.

Back to top
Activate your license keys

Before you can use the Knox Attestation in your app, you need to get an ISV (Independent Software Vendor) license and a REST API key.

Why do you need these? To identify yourself and prove that you have permission to use the Attestation feature. Use the ISV key in your Android app, and the REST API key in your web script, when you request services from the Attestation server. Should a key become compromised, Samsung can revoke it, and any app that uses the compromised key can’t use the attestation services.

Get your license keys

  1. Go to License Keys > Knox ISV SDK.

  2. Choose the type of ISV key to generate:
    • Development - Use this for testing; this key doesn’t get validated by our license server.
    • Production - Use this for the final release; this key does get validated by our license server. To be able to generate production keys, you must apply to become a partner.
  3. Enter a key alias to identify the key; this is useful if you generate multiple keys.
  4. Select the optional Attestation REST API key; then enter an alias for it too.
  5. Click GENERATE LICENSE KEY. The KNOX ISV SDK LICENSE AGREEMENT appears.
  6. Click Agree to accept the agreement and continue the key creation process. When the key is successfully created, the License Keys page appears with your ISV key listed in the Your New License Keys section.

Keep these keys secure.

Activate the ISV license

When the ISV license is validated, the intent edm.intent.action.license.status is emitted. You must identify the class that handles this intent. In our sample app com.samsung.business.sdk.attestation, we use the class SampleLicenseReceiver. Declare the class in the manifest file as follows:

<receiver android:name="com.samsung.business.sdk.attestation.SampleLicenseReceiver" android:enabled="true" >
    <intent-filter>
        <action android:name="edm.intent.action.license.status" />
    </intent-filter>
</receiver>

When your app receives an edm.intent.action.license.status intent, it passes the intent SampleLicenseReceiver.onReceive(). This method is where you can have your app respond to the ISV license being activated. For example, you might prompt the device user to start attestation.

To activate an ISV license, call the API method EnterpriseLicenseManager.activateLicense() and pass it your ISV key. For example:

String pkgName = "com.mycompany.mymobileapp";
 
// NOTE: Embedding the license in the code is unsafe and it is done here for demo purposes only
String isvLicense  = ""; // Enter ISV license key
 
// Activate the ISV license
EnterpriseLicenseManager elmManager = EnterpriseLicenseManager.getInstance(context);
elmManager.activateLicense(isvLicense, pkgName);
 
// Listen for intent result - EnterpriseLicenseManager.ACTION_LICENSE_STATUS

The ISV key is hard-coded into this code snippet for demonstration purposes only. In a production app, you should fetch the key from a web service over a secure connection. This decreases the possibility of your key being compromised. If your key is compromised and Samsung issues a replacement key, then your app retrieves and uses the new key, rather than attempting to use an invalid hard-coded key.

To test license activation in your app:

  1. Launch the app. Here is the sample Attestation app:

  2. Tap Activate Admin. This displays a list of the device admin permissions that will be granted to the app.

  3. Tap Activate to confirm that you want the app to have these permissions.
    If you later want to revoke these device admin permissions from the app (for example, to uninstall the app), go to the Android Settings > Lock screen and security > Device administrators. (This path might vary slightly on some devices.)

  4. Tap Activate ISV. The app sends your ISV license to the web-based Samsung License Manager to verify that your ISV license is valid and still active. Depending on the network, there might be a slight delay, but within a minute, your license should be authenticated.

If the license is not valid, the app displays an error message. If this happens, carefully check your ISV license again and re-enter it if needed.

If the license is valid, the app greys out the Activate ISV button to show that it has been activated successfully on the device.

Encode the REST API key

In the header of every REST API call to the Attestation server, you identify yourself by encoding your Attestation REST API key.

Here is some sample PHP code showing how to insert a REST API key into the header of a REST API request:

<?php
    // insert the REST API key you got from the SEAP portal
    $api_key = '';
 
    // initialize a new HTTP session
    $curl = curl_init();
    // specify the URL of the cloud service
    curl_setopt($curl, CURLOPT_URL,"https://attest-api.secb2b.com/v2/nonces");
    // select the HTTP POST method
    curl_setopt($curl, CURLOPT_POST, 1);
 
    // build the HTTP message header, which includes a field for the REST API key
    $headers = array(
        'x-knox-attest-api-key: '.$api_key,
    );
    // set the HTTP message header
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    // execute the HTTP session
    curl_exec($curl);
Back to top
Get a nonce

A nonce is a random value that uniquely identifies each attestation request. Each nonce is valid for a short time period. This is for security purposes, so that the Attestation Server can fail any request made using that nonce after the valid period. This avoids replay attacks that could allow an attacker to access a past attestation result.

In your Android app, request a nonce from your web server. On the web server, you need a script to take the request and forward it to Samsung’s Attestation server. In the sample Attestation app, there is a script called nonces.php that does this.

// identify the URL of your web server
private static final String URL_MDM_SERVER_NONCE = "http://attestation.example.com/nonces";
 
// through HTTP, send a nonce request to your web server
String response = HttpClient.getInstance().getNonce(URL_MDM_SERVER_NONCE, mEditApiKey.getText().toString());

In this example, we use a string variable called response to store the resulting nonce. Later, you will parse the response into a JSON object and pass it to the Attestation agent on the device.

In your web script, build the request to get a nonce from the Attestation Server. Our sample app does this using PHP, which you can find in the file nonces.php:

$curl = curl_init();
 
// build an HTTPS message with a POST method to get a nonce from Samsung's Attestation server
curl_setopt($curl, CURLOPT_URL,"https://attest-api.secb2b.com/v2/nonces";
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
 
// provide your Attestation key through the HTTPS message header
$headers = array(
    'x-knox-attest-api-key: '.$api_key,
    'Accept: '.$accept
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
 
// send your nonce request to Samsung's Attestation server
curl_exec($curl);

For details about the syntax of the REST API calls to the Attestation Server, see the Attestation REST API Reference.

Back to top
Start attestation

When your Android app gets a nonce from your web server, send it to Samsung’s Attestation agent on the device and set up an intent to handle the response.

When the Knox Attestation agent has a blob containing the attestation measurements, it emits the intent com.sec.enterprise.knox.intent.action.KNOX_ATTESTATION_RESULT.

Identify the class that handles this intent. In our sample app com.samsung.business.sdk.attestation, we use the class AttestationReceiver. Declare the class in the manifest file as follows:

<receiver
    android:name="com.samsung.business.sdk.attestation.AttestationReceiver"
    android:enabled="true">
    <intent-filter>
        <action android:name="com.sec.enterprise.knox.intent.action.KNOX_ATTESTATION_RESULT" />
    </intent-filter>
</receiver>

Your app communicates with the Knox Attestation agent using AIDL, as declared through the file IAttestation.aidl.

// import AIDL file that declares interface with Knox Attestation agent
import com.sec.enterprise.knox.IAttestation;
    :
// parse the response from your web server into a JSONObject
jsonObject = new JSONObject(response);
 
// extract the nonce from the JSONObject
mNonce = jsonObject.getString("nonce");
 
// create a new intent for the attestation request sent to the Knox Attestation Agent
Intent intent = new Intent(IAttestation.class.getName());
intent.setAction("com.sec.enterprise.knox.intent.action.BIND_KNOX_ATTESTATION_SERVICE");
getActivity().bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);

Set up a service connection with the Knox Attestation Agent to handle the response:

private IAttestation mIAttestation;
private String mNonce;
// create a new service connection
private ServiceConnection mServiceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        //set attestation object from service
        mIAttestation = IAttestation.Stub.asInterface(iBinder);
        //start attestation using the provided nonce
        mIAttestation.startAttestation_nonce(mNonce);

Your app handles the intent com.sec.enterprise.knox.intent.action.KNOX_ATTESTATION_RESULT by passing it to AttestationReceiver.onReceive(). This method is where you handle the blob sent by the Knox Attestation Agent.

// import JAR file that defines constants for values returned by Knox Attestation Agent
import com.sec.enterprise.knox.Attestation;
    :
 
public class AttestationReceiver extends BroadcastReceiver {
    private static final String TAG = "Attestation";
    static AttestationFragment attestationFragment;
    // Get the current fragment instance
    public AttestationReceiver(AttestationFragment attestationFragment) {
        AttestationReceiver.attestationFragment = attestationFragment;
    }
 
    @Override
    public void onReceive(Context context, Intent intent) {
        // Get the result of the intent
        final int result = intent.getIntExtra(Attestation.EXTRA_RESULT, Integer.MIN_VALUE);
 
        switch (result) {
            // check if communication with the Knox Attestation Agent was successful
            case Attestation.RESULT_ATTESTATION_SUCCESSFUL:
                // Get the blob from the intent
                byte[] blob = intent.getByteArrayExtra(Attestation.EXTRA_ATTESTATION_DATA);
                // Get the status from within the blob
                attestationFragment.getAttestationStatus(blob);
                break;
Back to top
Get the attestation verdict

Now that you have a blob containing the integrity measurements, send it to your web server, which in turn sends it to Samsung’s Attestation server to get a verdict on whether or not the device passed the integrity checks.

Send the blob to your web server using the HTTP protocol. On the web server, you need a script to take the blob and forward it to Samsung’s Attestation server. In the sample Attestation app, there is a script called measurements.php that does this.

String response = HttpClient.getInstance().getAttestationStatus(http://my.attestation.server.com/measurements + 
    "?nonce=" + mNonce, blob, mEditApiKey.getText().toString());

In this example, we use a string variable called response to store the resulting verdict. Later, you will parse the response into a JSON object and display the verdict details.

In the web script, build a request to get the attestation verdict from the Attestation Server. Our sample code does this using PHP, which you can find in the source code file measurements.php:

$curl = curl_init();
 
// build an HTTPS message with a POST method to send the blob to Samsung's Attestation server
curl_setopt($curl, CURLOPT_URL,"https://attest-api.secb2b.com/v2/blobs?nonce=".$nonce);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $entityBody);  //Post Fields
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
 
// provide your Attestation key through the HTTPS message header
$headers = array(
  'x-knox-attest-api-key: '.$api_key,
  'Accept: '.$accept,
  'Content-type: '.$content_type
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
 
// send your blob to Samsung's Attestation server
curl_exec($curl);

You can process the verdict in either the web script or the Android app.

Here, we use the Android app to parse the attestation response into a JSONObject to extract the results of the attestation:

JsonObject = new JSONObject(mAttestationStatus);
 
// get the overall verdict
String verdict = jsonObject.getString("verdict");
buff.append("verdict = " + verdict);
 
// get the detailed measurements
String measurements = jsonObject.getString("measurements");
buff.append("measurements = " + measurements);
String mac = jsonObject.getString("MAC");
buff.append("mac = " + mac);

Here is how the app displays the attestation results:

A verdict of:

  • Yes - indicates that the device passed the integrity checks
  • No - indicates that the device failed the integrity checks

The tamperBit indicates whether or not the Knox Warranty Bit has been set. A:

  • 0 - indicates that unauthorized firmware is not detected on the device
  • 1 - indicates that unauthorized firmware is detected on the device

The status indicates whether or not the blob is authentic, based on its digital signature and public key certificate.

For details about fields returned in the verdict, see the Attestation REST API Reference.

SDK version:
2.6
Rate this article: