summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoshiaki Naka <yoshiaki.naka@sony.com>2018-02-20 18:32:50 +0900
committerRuchi Kandoi <kandoiruchi@google.com>2018-03-06 13:35:21 -0800
commit3878ce67ae4810258882c749f4dcbf508e6ad9ed (patch)
tree75745e09114719d52ce593abd7c6ef6d490d84f6
parent3e785e28c90aefc1a5c09f089684fdd48633fa32 (diff)
downloadSecureElement-3878ce67ae4810258882c749f4dcbf508e6ad9ed.tar.gz
IOError happened while sending command for retrieving access rules
IOException shall be thrown to client application if communication problem happens between the terminal and the secure element while the terminal retrieves the access rules. That is the expected behavior described in the clause 6.2.7 (h) of Open Mobile API Specification. Bug: 74094356 Test: OMAPI TC 6.4.7 ID8 and TC 6.4.10 ID8 pass with this change. Change-Id: If444384541d3425e9a0dc052e933c9739a9f1025 (cherry picked from commit 54f116c755f9cfc2495e3c233357ec5d32a94121)
-rw-r--r--src/com/android/se/Channel.java20
-rw-r--r--src/com/android/se/Terminal.java20
-rw-r--r--[-rwxr-xr-x]src/com/android/se/security/ara/AccessRuleApplet.java16
-rw-r--r--src/com/android/se/security/ara/AraController.java6
-rw-r--r--[-rwxr-xr-x]src/com/android/se/security/arf/PKCS15/EF.java7
-rw-r--r--[-rwxr-xr-x]src/com/android/se/security/arf/PKCS15/EFACConditions.java3
-rw-r--r--[-rwxr-xr-x]src/com/android/se/security/arf/PKCS15/EFACMain.java3
-rw-r--r--[-rwxr-xr-x]src/com/android/se/security/arf/PKCS15/EFACRules.java7
-rw-r--r--[-rwxr-xr-x]src/com/android/se/security/arf/PKCS15/EFDIR.java4
-rw-r--r--[-rwxr-xr-x]src/com/android/se/security/arf/PKCS15/EFDODF.java5
-rw-r--r--[-rwxr-xr-x]src/com/android/se/security/arf/PKCS15/EFODF.java5
-rw-r--r--src/com/android/se/security/arf/PKCS15/PKCS15Handler.java6
-rw-r--r--src/com/android/se/security/arf/SecureElement.java5
13 files changed, 71 insertions, 36 deletions
diff --git a/src/com/android/se/Channel.java b/src/com/android/se/Channel.java
index 9dff38a..582d4c4 100644
--- a/src/com/android/se/Channel.java
+++ b/src/com/android/se/Channel.java
@@ -25,13 +25,17 @@ package com.android.se;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.se.omapi.ISecureElementChannel;
import android.se.omapi.ISecureElementListener;
+import android.se.omapi.SEService;
import android.util.Log;
import com.android.se.SecureElementService.SecureElementSession;
import com.android.se.security.ChannelAccess;
+import java.io.IOException;
+
/**
* Represents a Channel opened with the Secure Element
*/
@@ -106,7 +110,7 @@ public class Channel implements IBinder.DeathRecipient {
/**
* Transmits the given byte and returns the response.
*/
- public byte[] transmit(byte[] command) throws RemoteException {
+ public byte[] transmit(byte[] command) throws IOException {
if (isClosed()) {
throw new IllegalStateException("Channel is closed");
}
@@ -142,7 +146,7 @@ public class Channel implements IBinder.DeathRecipient {
}
}
- private boolean selectNext() throws RemoteException {
+ private boolean selectNext() throws IOException {
if (isClosed()) {
throw new IllegalStateException("Channel is closed");
} else if (mChannelAccess == null) {
@@ -306,13 +310,21 @@ public class Channel implements IBinder.DeathRecipient {
@Override
public byte[] transmit(byte[] command) throws RemoteException {
Channel.this.setCallingPid(Binder.getCallingPid());
- return Channel.this.transmit(command);
+ try {
+ return Channel.this.transmit(command);
+ } catch (IOException e) {
+ throw new ServiceSpecificException(SEService.IO_ERROR, e.getMessage());
+ }
}
@Override
public boolean selectNext() throws RemoteException {
Channel.this.setCallingPid(Binder.getCallingPid());
- return Channel.this.selectNext();
+ try {
+ return Channel.this.selectNext();
+ } catch (IOException e) {
+ throw new ServiceSpecificException(SEService.IO_ERROR, e.getMessage());
+ }
}
}
}
diff --git a/src/com/android/se/Terminal.java b/src/com/android/se/Terminal.java
index dd28917..28f02bd 100644
--- a/src/com/android/se/Terminal.java
+++ b/src/com/android/se/Terminal.java
@@ -204,11 +204,11 @@ public class Terminal {
} catch (Exception ignore) {
}
}
- } catch (RemoteException ignore) {
+ } catch (Exception ignore) {
}
}
- private void select(byte[] aid) throws RemoteException {
+ private void select(byte[] aid) throws IOException {
int commandSize = (aid == null ? 0 : aid.length) + 5;
byte[] selectCommand = new byte[commandSize];
selectCommand[0] = 0x00;
@@ -425,11 +425,10 @@ public class Terminal {
* @param cmd the command APDU to be transmitted.
* @return the response received.
*/
- public byte[] transmit(byte[] cmd) throws RemoteException {
+ public byte[] transmit(byte[] cmd) throws IOException {
if (!mIsConnected) {
Log.e(mTag, "Secure Element is not connected");
- throw new ServiceSpecificException(SEService.IO_ERROR,
- "Secure Element is not connected");
+ throw new IOException("Secure Element is not connected");
}
byte[] rsp = transmitInternal(cmd);
@@ -456,10 +455,15 @@ public class Terminal {
return rsp;
}
- private byte[] transmitInternal(byte[] cmd) throws RemoteException {
- ArrayList<Byte> response = mSEHal.transmit(byteArrayToArrayList(cmd));
+ private byte[] transmitInternal(byte[] cmd) throws IOException {
+ ArrayList<Byte> response;
+ try {
+ response = mSEHal.transmit(byteArrayToArrayList(cmd));
+ } catch (RemoteException e) {
+ throw new IOException(e.getMessage());
+ }
if (response.isEmpty()) {
- throw new ServiceSpecificException(SEService.IO_ERROR, "Error in transmit()");
+ throw new IOException("Error in transmit()");
}
byte[] rsp = arrayListToByteArray(response);
if (mDebug) {
diff --git a/src/com/android/se/security/ara/AccessRuleApplet.java b/src/com/android/se/security/ara/AccessRuleApplet.java
index c5bc560..d23c68d 100755..100644
--- a/src/com/android/se/security/ara/AccessRuleApplet.java
+++ b/src/com/android/se/security/ara/AccessRuleApplet.java
@@ -35,8 +35,6 @@
package com.android.se.security.ara;
-import android.os.RemoteException;
-
import com.android.se.Channel;
import com.android.se.security.CommandApdu;
import com.android.se.security.ResponseApdu;
@@ -67,7 +65,7 @@ public class AccessRuleApplet {
}
/** Reads all the access rules from the secure element */
- public byte[] readAllAccessRules() throws AccessControlException {
+ public byte[] readAllAccessRules() throws AccessControlException, IOException {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
int overallLen = 0;
@@ -132,7 +130,7 @@ public class AccessRuleApplet {
}
/** Fetches the Refresh Tag from the Secure Element */
- public byte[] readRefreshTag() throws AccessControlException {
+ public byte[] readRefreshTag() throws AccessControlException, IOException {
CommandApdu apdu = (CommandApdu) GET_REFRESH_TAG.clone();
ResponseApdu response = send(apdu);
// OK
@@ -156,12 +154,8 @@ public class AccessRuleApplet {
throw new AccessControlException("GET REFRESH TAG not successfull.");
}
- private ResponseApdu send(CommandApdu cmdApdu) {
- try {
- byte[] response = mChannel.transmit(cmdApdu.toBytes());
- return new ResponseApdu(response);
- } catch (RemoteException e) {
- return null;
- }
+ private ResponseApdu send(CommandApdu cmdApdu) throws IOException {
+ byte[] response = mChannel.transmit(cmdApdu.toBytes());
+ return new ResponseApdu(response);
}
}
diff --git a/src/com/android/se/security/ara/AraController.java b/src/com/android/se/security/ara/AraController.java
index 99b1942..543337a 100644
--- a/src/com/android/se/security/ara/AraController.java
+++ b/src/com/android/se/security/ara/AraController.java
@@ -114,6 +114,10 @@ public class AraController {
Log.i(mTag, "Read ARs from ARA");
readAllAccessRules();
+ } catch (IOException e) {
+ // Some kind of communication problem happened while transmit() was executed.
+ // IOError shall be notified to the client application in this case.
+ throw e;
} catch (Exception e) {
Log.i(mTag, "ARA error: " + e.getLocalizedMessage());
throw new AccessControlException(e.getLocalizedMessage());
@@ -124,7 +128,7 @@ public class AraController {
}
}
- private void readAllAccessRules() throws AccessControlException {
+ private void readAllAccessRules() throws AccessControlException, IOException {
try {
byte[] data = mApplet.readAllAccessRules();
// no data returned, but no exception
diff --git a/src/com/android/se/security/arf/PKCS15/EF.java b/src/com/android/se/security/arf/PKCS15/EF.java
index bd929ea..a523dde 100755..100644
--- a/src/com/android/se/security/arf/PKCS15/EF.java
+++ b/src/com/android/se/security/arf/PKCS15/EF.java
@@ -30,6 +30,7 @@ import com.android.se.security.arf.DERParser;
import com.android.se.security.arf.SecureElement;
import com.android.se.security.arf.SecureElementException;
+import java.io.IOException;
import java.util.Arrays;
/** Base class for ARF Data Objects */
@@ -166,7 +167,7 @@ public class EF {
* @param path Path of the file
* @return Command status code [sw1 sw2]
*/
- public int selectFile(byte[] path) throws SecureElementException {
+ public int selectFile(byte[] path) throws IOException, SecureElementException {
if ((path == null) || (path.length == 0) || ((path.length % 2) != 0)) {
throw new SecureElementException("Incorrect path");
}
@@ -209,7 +210,7 @@ public class EF {
* @param nbBytes Number of bytes to read
* @return Data retreived from the file
*/
- public byte[] readBinary(int offset, int nbBytes) throws SecureElementException {
+ public byte[] readBinary(int offset, int nbBytes) throws IOException, SecureElementException {
if (mFileSize == 0) return null;
if (nbBytes == -1) nbBytes = mFileSize;
if (mFileType != EF) throw new SecureElementException("Incorrect file type");
@@ -246,7 +247,7 @@ public class EF {
* @param record Record ID [0..n]
* @return Data from requested record
*/
- public byte[] readRecord(short record) throws SecureElementException {
+ public byte[] readRecord(short record) throws IOException, SecureElementException {
// Check the type of current selected file
if (mFileType != EF) throw new SecureElementException("Incorrect file type");
if (mFileStructure != LINEAR_FIXED) {
diff --git a/src/com/android/se/security/arf/PKCS15/EFACConditions.java b/src/com/android/se/security/arf/PKCS15/EFACConditions.java
index 8cb09e5..1068969 100755..100644
--- a/src/com/android/se/security/arf/PKCS15/EFACConditions.java
+++ b/src/com/android/se/security/arf/PKCS15/EFACConditions.java
@@ -50,6 +50,7 @@ import com.android.se.security.arf.SecureElement;
import com.android.se.security.gpac.AID_REF_DO;
import com.android.se.security.gpac.Hash_REF_DO;
+import java.io.IOException;
import java.util.Vector;
/** EF_ACConditions related features ************************************************* */
@@ -260,7 +261,7 @@ public class EFACConditions extends EF {
*
* @param path Path of the "EF_ACConditions" file
*/
- public void addRestrictedHashes(byte[] path) throws PKCS15Exception {
+ public void addRestrictedHashes(byte[] path) throws IOException, PKCS15Exception {
try {
Log.i(TAG, "Reading and analysing EF_ACConditions...");
if (selectFile(path) == APDU_SUCCESS) {
diff --git a/src/com/android/se/security/arf/PKCS15/EFACMain.java b/src/com/android/se/security/arf/PKCS15/EFACMain.java
index 2124333..9596003 100755..100644
--- a/src/com/android/se/security/arf/PKCS15/EFACMain.java
+++ b/src/com/android/se/security/arf/PKCS15/EFACMain.java
@@ -47,6 +47,7 @@ import com.android.se.security.arf.DERParser;
import com.android.se.security.arf.SecureElement;
import com.android.se.security.arf.SecureElementException;
+import java.io.IOException;
import java.util.Arrays;
/** EF_ACMain related features */
@@ -95,7 +96,7 @@ public class EFACMain extends EF {
*
* @return Path to "EF_ACRules" if "RefreshTag" has been updated; <code>null</code> otherwise
*/
- public byte[] analyseFile() throws PKCS15Exception, SecureElementException {
+ public byte[] analyseFile() throws IOException, PKCS15Exception, SecureElementException {
Log.i(TAG, "Analysing EF_ACMain...");
byte[] path = mACMainPath;
diff --git a/src/com/android/se/security/arf/PKCS15/EFACRules.java b/src/com/android/se/security/arf/PKCS15/EFACRules.java
index 15ed4e0..62dfde8 100755..100644
--- a/src/com/android/se/security/arf/PKCS15/EFACRules.java
+++ b/src/com/android/se/security/arf/PKCS15/EFACRules.java
@@ -49,6 +49,7 @@ import com.android.se.security.arf.SecureElement;
import com.android.se.security.arf.SecureElementException;
import com.android.se.security.gpac.AID_REF_DO;
+import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@@ -75,7 +76,7 @@ public class EFACRules extends EF {
*
* @param buffer ASN.1 data
*/
- private void decodeDER(byte[] buffer) throws PKCS15Exception {
+ private void decodeDER(byte[] buffer) throws IOException, PKCS15Exception {
byte[] aid = null;
DERParser der = new DERParser(buffer);
@@ -129,8 +130,8 @@ public class EFACRules extends EF {
*
* @param path Path of the "EF_ACRules" file
*/
- public void analyseFile(byte[] path) throws PKCS15Exception, SecureElementException {
-
+ public void analyseFile(byte[] path) throws IOException, PKCS15Exception,
+ SecureElementException {
Log.i(TAG, "Analysing EF_ACRules...");
// clear EF AC Condition data cache.
diff --git a/src/com/android/se/security/arf/PKCS15/EFDIR.java b/src/com/android/se/security/arf/PKCS15/EFDIR.java
index 1e2fb18..6a6f2f3 100755..100644
--- a/src/com/android/se/security/arf/PKCS15/EFDIR.java
+++ b/src/com/android/se/security/arf/PKCS15/EFDIR.java
@@ -42,6 +42,7 @@ import com.android.se.security.arf.DERParser;
import com.android.se.security.arf.SecureElement;
import com.android.se.security.arf.SecureElementException;
+import java.io.IOException;
import java.util.Arrays;
/** EF_DIR related features */
@@ -93,7 +94,8 @@ public class EFDIR extends EF {
* @param aid Record key to search for
* @return Path to "EF_ODF" when an expected record is found; <code>null</code> otherwise
*/
- public byte[] lookupAID(byte[] aid) throws PKCS15Exception, SecureElementException {
+ public byte[] lookupAID(byte[] aid) throws IOException, PKCS15Exception,
+ SecureElementException {
Log.i(TAG, "Analysing EF_DIR...");
if (selectFile(EFDIR_PATH) != APDU_SUCCESS) throw new PKCS15Exception("EF_DIR not found!!");
diff --git a/src/com/android/se/security/arf/PKCS15/EFDODF.java b/src/com/android/se/security/arf/PKCS15/EFDODF.java
index a8eb228..a9e7b26 100755..100644
--- a/src/com/android/se/security/arf/PKCS15/EFDODF.java
+++ b/src/com/android/se/security/arf/PKCS15/EFDODF.java
@@ -43,6 +43,8 @@ import com.android.se.security.arf.DERParser;
import com.android.se.security.arf.SecureElement;
import com.android.se.security.arf.SecureElementException;
+import java.io.IOException;
+
/** EF_DODF related features */
public class EFDODF extends EF {
@@ -109,7 +111,8 @@ public class EFDODF extends EF {
* @param path Path of the "EF_DODF" file
* @return Path to "EF_ACMain" from "Access Control" OID; <code>null</code> otherwise
*/
- public byte[] analyseFile(byte[] path) throws PKCS15Exception, SecureElementException {
+ public byte[] analyseFile(byte[] path) throws IOException, PKCS15Exception,
+ SecureElementException {
Log.i(TAG, "Analysing EF_DODF...");
if (selectFile(path) != APDU_SUCCESS) throw new PKCS15Exception("EF_DODF not found!");
diff --git a/src/com/android/se/security/arf/PKCS15/EFODF.java b/src/com/android/se/security/arf/PKCS15/EFODF.java
index e751908..67508d1 100755..100644
--- a/src/com/android/se/security/arf/PKCS15/EFODF.java
+++ b/src/com/android/se/security/arf/PKCS15/EFODF.java
@@ -47,6 +47,8 @@ import com.android.se.security.arf.DERParser;
import com.android.se.security.arf.SecureElement;
import com.android.se.security.arf.SecureElementException;
+import java.io.IOException;
+
/** EF_ODF related features */
public class EFODF extends EF {
@@ -104,7 +106,8 @@ public class EFODF extends EF {
*
* @return Path to "EF_DODF" from "DODF Tag" entry; <code>null</code> otherwise
*/
- public byte[] analyseFile(byte[] pkcs15Path) throws PKCS15Exception, SecureElementException {
+ public byte[] analyseFile(byte[] pkcs15Path) throws IOException, PKCS15Exception,
+ SecureElementException {
Log.i(mTag, "Analysing EF_ODF...");
// 2012-04-12
diff --git a/src/com/android/se/security/arf/PKCS15/PKCS15Handler.java b/src/com/android/se/security/arf/PKCS15/PKCS15Handler.java
index 59e0ba0..f6e1b42 100644
--- a/src/com/android/se/security/arf/PKCS15/PKCS15Handler.java
+++ b/src/com/android/se/security/arf/PKCS15/PKCS15Handler.java
@@ -100,6 +100,9 @@ public class PKCS15Handler {
try {
ACRulesPath = mACMainObject.analyseFile();
mACMFfound = true;
+ } catch (IOException e) {
+ // IOException must be propagated to the access control enforcer.
+ throw e;
} catch (Exception e) {
Log.i(mTag, "ACMF Not found !");
mACMainObject = null;
@@ -121,6 +124,9 @@ public class PKCS15Handler {
try {
mACRulesObject.analyseFile(ACRulesPath);
+ } catch (IOException e) {
+ // IOException must be propagated to the access control enforcer.
+ throw e;
} catch (Exception e) {
Log.i(mTag, "Exception: clear access rule cache and refresh tag");
mSEHandle.resetAccessRules();
diff --git a/src/com/android/se/security/arf/SecureElement.java b/src/com/android/se/security/arf/SecureElement.java
index 134881a..6323815 100644
--- a/src/com/android/se/security/arf/SecureElement.java
+++ b/src/com/android/se/security/arf/SecureElement.java
@@ -81,9 +81,12 @@ public class SecureElement {
* @param cmd APDU command
* @return Data returned by the APDU command
*/
- public byte[] exchangeAPDU(EF ef, byte[] cmd) throws SecureElementException {
+ public byte[] exchangeAPDU(EF ef, byte[] cmd) throws IOException, SecureElementException {
try {
return mArfChannel.transmit(cmd);
+ } catch (IOException e) {
+ // Communication error happened while the terminal sending a command.
+ throw e;
} catch (Exception e) {
throw new SecureElementException(
"Secure Element access error " + e.getLocalizedMessage());