Sample Code: One Time Password (OTP) Demo

Download as PDF

Download source code

Peng Wang, Software Applications Engineer

Application Origination:
Intel SSG

Introduction

Traditionally, two-factor authentication uses a one-time password (OTP), which combines something the user knows (a username and password) and something the user has (typically, a token or key fob that produces a six-digit number, valid only for a short period of time and available on demand).

If your business is already using two-factor authentication, then you are also familiar with the various issues around token usability and logistics. Replacing lost or broken tokens and users mistyping their one-time passwords are just two of the headaches currently affecting help desks and IT departments. Intel® Identity Protection Technology (Intel® IPT) with OTP is a built-in hardware token (of your security vendor choice) that negates the need for a separate physical token, thus simplifying the two-factor VPN log-in process for a seamless experience with virtually no delays.

The purpose of this paper is to provide a high level overview of the one-time password (OTP) functionalities and show how to use the OTP APIs in Android*.

Code and Explanations

OTP has three major functionalities: OTP provisioning, OTP generation, and OTP verification.  There are also APIs for querying OTP capability and the OTP version on the system.

OTP Provisioning

InvokeIPTProv extends the AsyncTask to execute the provisioning in the background. It first creates the security service (Provision Service) and then starts the provisioning process.

@Override
protected Void doInBackground(Void... params) {
	ChaabiProvision prov = new ChaabiProvision();
	try {
		prov.execute().get(PROV_MAX_TIMEOUT, TimeUnit.MILLISECONDS);
	} catch (InterruptedException e) {
		error = "Provisioning failed: " + e.getClass().getName() + ": "
				+ e.getLocalizedMessage();
		e.printStackTrace();
	} catch (ExecutionException e) {
		error = "Provisioning failed: " + e.getClass().getName() + ": "
				+ e.getLocalizedMessage();
		e.printStackTrace();
	} catch (TimeoutException e) {
		error = "Provisioning failed: " + e.getClass().getName() + ": "
				+ e.getLocalizedMessage();
		e.printStackTrace();
	}
	return null;
}

OTP Generation  

Before we start generating the OTP, we need to check if the device has already successfully completed the provisioning process.

// Read token if exists
if (!readData()) {
	tvOTPGenerate
			.setText("OTP generation failed: No token exists. Please do provisioning.");
	return;
}

Then we can invoke the Async call to generate the OTP.

boolean invokeResyncGenerateOTP(IPTWrapper obj) {
	try {
		// Send request to the server for resync message and process
		// the received resync message
		InvokeIPTResync ipt_obj = new InvokeIPTResync();
		boolean status = ipt_obj.execute().get();
		if (status) {

			// Processes the server resync message
			obj.ProcessResyncMessage(encrToken_b64, serverResyncMessage);

			// Invoke OTP generation again
			// Check if token is of type OCRA
			if (tokenInfo
					.equalsIgnoreCase(OTPDemoActivity.OCRA_TOKEN_INFO)) {
				invokeGenerateOTP(obj, true);
			} else {
				invokeGenerateOTP(obj, false);
			}
			displayOTP();
			progressDialog.dismiss();
		} else {
			String error = "Receive server resync message failed.";
			tvOTPGenerate.setText(error);
			progressDialog.dismiss();
			OTPDemoActivity.OTP = null;
			return false;
		}
	} catch (IhaException e) {
		String error = "OTP generation failed. Message: "
				+ e.getLocalizedMessage() + " Error code: " + e.GetError();
		tvOTPGenerate.setText(error);
		progressDialog.dismiss();
		OTPDemoActivity.OTP = null;
		return false;
	} catch (Exception e) {
		String error = "OTP generation failed: " + e.getClass().getName()
				+ ": " + e.getLocalizedMessage();
		tvOTPGenerate.setText(error);
		progressDialog.dismiss();
		OTPDemoActivity.OTP = null;
		return false;
	}
	return true;
}

OTP Verification

Once the OTP is generated, we can then check if it is valid.

	ChaabiOTPVerify otp_ver = new ChaabiOTPVerify();
	try {
		otp_ver.execute()
				.get(OTP_VERIFY_TIMEOUT, TimeUnit.MILLISECONDS);
	} catch (InterruptedException e) {
		error = "OTP verification failed: " + e.getClass().getName()
				+ ": " + e.getLocalizedMessage();
		e.printStackTrace();
	} catch (ExecutionException e) {
		error = "OTP verification failed: " + e.getClass().getName()
				+ ": " + e.getLocalizedMessage();
		e.printStackTrace();
	} catch (TimeoutException e) {
		error = "OTP verification failed: " + e.getClass().getName()
				+ ": " + e.getLocalizedMessage();
		e.printStackTrace();
	}
	return null;	} catch (JSONException e) {
		error = e.getClass().getName() + ": " + e.getLocalizedMessage();
		status = false;
		e.printStackTrace();
	} catch (UnsupportedEncodingException e) {
		error = e.getClass().getName() + ": " + e.getLocalizedMessage();
		status = false;
		e.printStackTrace();
	} catch (ClientProtocolException e) {
		error = e.getClass().getName() + ": " + e.getLocalizedMessage();
		status = false;
		e.printStackTrace();
	} catch (IOException e) {
		error = e.getClass().getName() + ": " + e.getLocalizedMessage();
		status = false;
		e.printStackTrace();
	}
	Log.v(LOG_TAG, "Return results: " + status);
	return status;
}

Query OTP Capability

Built-in, hardware-based OTP is not available on all mobile devices, so it would be helpful to first query the system if the OTP capability is available.

private boolean isOTPCapable(){
	try {
		IPTWrapper caps = new IPTWrapper();
		String cap = caps.GetCapabilities();
		displayMessage("Capabilities: " + cap);
		return true; 
	} catch (IhaException e) {
		String error = "GetCapabilities() failed. Message: "
				+ e.getLocalizedMessage() + " Error code: "
				+ e.GetError();
		notifyUser("Failed: " + error);
		return false;
	} catch (Exception e) {
		String error = "GetCapabilities() failed: "
				+ e.getClass().getName() + ": "
				+ e.getLocalizedMessage();
		notifyUser("Failed: " + error);
		return false;
	}
}

Conclusion

By implementing code like the samples described in this paper, you can quickly learn how to use Intel® IPT with one-time password APIs to utilize hardware-based OTP on Intel® processor-based platforms running Android.

About the author

Peng Wang is a member of the Intel® Software and Solutions Group (SSG), Developer Relations Division, Intel® Atom™ Processor High Touch Software Enabling team. Before joining SSG, Peng was leading the integration and validation team for the Ultra Mobile Group. 

 

Notices

INFORMATION IN THIS DOCUMENT IS PROVIDED IN CONNECTION WITH INTEL PRODUCTS. NO LICENSE, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, TO ANY INTELLECTUAL PROPERTY RIGHTS IS GRANTED BY THIS DOCUMENT. EXCEPT AS PROVIDED IN INTEL'S TERMS AND CONDITIONS OF SALE FOR SUCH PRODUCTS, INTEL ASSUMES NO LIABILITY WHATSOEVER AND INTEL DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY, RELATING TO SALE AND/OR USE OF INTEL PRODUCTS INCLUDING LIABILITY OR WARRANTIES RELATING TO FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR INFRINGEMENT OF ANY PATENT, COPYRIGHT OR OTHER INTELLECTUAL PROPERTY RIGHT.

UNLESS OTHERWISE AGREED IN WRITING BY INTEL, THE INTEL PRODUCTS ARE NOT DESIGNED NOR INTENDED FOR ANY APPLICATION IN WHICH THE FAILURE OF THE INTEL PRODUCT COULD CREATE A SITUATION WHERE PERSONAL INJURY OR DEATH MAY OCCUR.

Intel may make changes to specifications and product descriptions at any time, without notice. Designers must not rely on the absence or characteristics of any features or instructions marked "reserved" or "undefined." Intel reserves these for future definition and shall have no responsibility whatsoever for conflicts or incompatibilities arising from future changes to them. The information here is subject to change without notice. Do not finalize a design with this information.

The products described in this document may contain design defects or errors known as errata which may cause the product to deviate from published specifications. Current characterized errata are available on request.

Contact your local Intel sales office or your distributor to obtain the latest specifications and before placing your product order.

Copies of documents which have an order number and are referenced in this document, or other Intel literature, may be obtained by calling 1-800-548-4725, or go to: http://www.intel.com/design/literature.htm

Software and workloads used in performance tests may have been optimized for performance only on Intel microprocessors. Performance tests, such as SYSmark* and MobileMark*, are measured using specific computer systems, components, software, operations, and functions. Any change to any of those factors may cause the results to vary. You should consult other information and performance tests to assist you in fully evaluating your contemplated purchases, including the performance of that product when combined with other products.

Any software source code reprinted in this document is furnished under a software license and may only be used or copied in accordance with the terms of that license.

Intel, the Intel logo, and Atom are trademarks of Intel Corporation in the US and/or other countries.

Copyright © 2014 Intel Corporation. All rights reserved.

*Other names and brands may be claimed as the property of others.