From d17c5fe9072df8ee04c3f9c31e78141c17db890c Mon Sep 17 00:00:00 2001 From: Henri Manson Date: Mon, 6 Aug 2018 13:04:48 +0200 Subject: [PATCH] Platform independency by replacing CardException with Throwable and PKCS15CardException --- .../opensc/pkcs15/PKCS15CardException.java | 18 + .../org/opensc/pkcs15/PKCS15Exception.java | 30 +- .../opensc/pkcs15/token/impl/CardOSToken.java | 309 +++++++++--------- 3 files changed, 187 insertions(+), 170 deletions(-) create mode 100644 pkcs15/src/main/java/org/opensc/pkcs15/PKCS15CardException.java diff --git a/pkcs15/src/main/java/org/opensc/pkcs15/PKCS15CardException.java b/pkcs15/src/main/java/org/opensc/pkcs15/PKCS15CardException.java new file mode 100644 index 0000000..22b478b --- /dev/null +++ b/pkcs15/src/main/java/org/opensc/pkcs15/PKCS15CardException.java @@ -0,0 +1,18 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.opensc.pkcs15; + +import javax.smartcardio.CardException; + +/** + * + * @author hfman + */ +public class PKCS15CardException extends PKCS15Exception{ + public PKCS15CardException(String msg, CardException cause) { + super(msg, cause); + } +} diff --git a/pkcs15/src/main/java/org/opensc/pkcs15/PKCS15Exception.java b/pkcs15/src/main/java/org/opensc/pkcs15/PKCS15Exception.java index 863c6c6..d1caaf5 100644 --- a/pkcs15/src/main/java/org/opensc/pkcs15/PKCS15Exception.java +++ b/pkcs15/src/main/java/org/opensc/pkcs15/PKCS15Exception.java @@ -1,6 +1,6 @@ /*********************************************************** * $Id$ - * + * * PKCS#15 cryptographic provider of the opensc project. * http://www.opensc-project.org * @@ -17,15 +17,13 @@ * limitations under the License. * * Created: 26.12.2007 - * + * ***********************************************************/ package org.opensc.pkcs15; import java.io.IOException; -import javax.smartcardio.CardException; - /** * @author wglas * @@ -33,7 +31,7 @@ public class PKCS15Exception extends IOException { private static final long serialVersionUID = 7500833559613739356L; - + /** * This error code is for errors, which do originate from a * smart card operation. @@ -44,17 +42,17 @@ public class PKCS15Exception extends IOException { public static final int ERROR_FILE_DEACTIVATED = 0x6283; public static final int ERROR_FILE_TERMINATED = 0x6285; - + public static final int ERROR_AUTHENTICATION_FAILED = 0x6300; - + public static final int ERROR_EEPROM_ERROR = 0x6581; - + public static final int ERROR_LC_INVALID = 0x6700; - + public static final int ERROR_LOGICAL_CHANNEL_NOT_SUPPORTED = 0x6881; public static final int ERROR_SM_MODE_NOT_SUPPORTED = 0x6882; public static final int ERROR_CHAINING_ERROR = 0x6884; - + public static final int ERROR_INVALID_COMMAND = 0x6981; public static final int ERROR_ACCES_DENIED = 0x6982; public static final int ERROR_BS_OBJECT_BLOCKED = 0x6983; @@ -75,11 +73,11 @@ public class PKCS15Exception extends IOException { public static final int ERROR_DATA_OBJECT_NOT_FOUND = 0x6A88; public static final int ERROR_FILE_EXISTS = 0x6A89; public static final int ERROR_DF_EXISTS = 0x6A8A; - + public static final int ERROR_LE_INVALID = 0x6C00; public static final int ERROR_INS_INVALID = 0x6D00; public static final int ERROR_CLA_INVALID = 0x6E00; - + public static final int ERROR_TECHNICAL_ERROR = 0x6F00; public static final int ERROR_CHECKSUM = 0x6F81; public static final int ERROR_XRAM_OVERFLOW = 0x6F82; @@ -90,11 +88,11 @@ public class PKCS15Exception extends IOException { public static final int ERROR_HARDWARE_MANIPULATION_DETECTED= 0x6F87; public static final int ERROR_TRANSACTION_BUFFER_OVERFLOW = 0x6F88; public static final int ERROR_ASSERTION_FAILED = 0x6FFF; - + public static final int ERROR_INCREASE_DECREASE_EXCEEDED = 0x9850; public static final int ERROR_TRANSPORT_ERROR = 0xFFFF; - + private final int errorCode; /** @@ -136,11 +134,11 @@ public PKCS15Exception(Throwable cause, int errorCode) { /** * Translate a CardException in to a PKCS15Excetion by setting the * error code to {@link #ERROR_TRANSPORT_ERROR}. - * + * * @param msg The error message. * @param cause The card exception raised by the JAVA smartcard API. */ - public PKCS15Exception(String msg, CardException cause) { + protected PKCS15Exception(String msg, Throwable cause) { super(msg,cause); this.errorCode = ERROR_TRANSPORT_ERROR; } diff --git a/pkcs15/src/main/java/org/opensc/pkcs15/token/impl/CardOSToken.java b/pkcs15/src/main/java/org/opensc/pkcs15/token/impl/CardOSToken.java index e74aa0f..36c9540 100644 --- a/pkcs15/src/main/java/org/opensc/pkcs15/token/impl/CardOSToken.java +++ b/pkcs15/src/main/java/org/opensc/pkcs15/token/impl/CardOSToken.java @@ -1,6 +1,6 @@ /*********************************************************** * $Id$ - * + * * PKCS#15 cryptographic provider of the opensc project. * http://www.opensc-project.org * @@ -17,7 +17,7 @@ * limitations under the License. * * Created: 29.12.2007 - * + * ***********************************************************/ package org.opensc.pkcs15.token.impl; @@ -38,6 +38,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.opensc.pkcs15.PKCS15CardException; import org.opensc.pkcs15.PKCS15Exception; import org.opensc.pkcs15.script.Command; import org.opensc.pkcs15.script.ScriptParser; @@ -58,29 +59,29 @@ /** * A token implementation for Siemens CardOS 4.3b tokens. - * + * * @author wglas */ public class CardOSToken implements Token { private static final Log log = LogFactory.getLog(CardOSToken.class); - + public static final ATR CARDOS_4_3_b_ATR = new ATR(new byte[] { 0x3B, (byte) 0xF2, 0x18, 0x00, 0x02, (byte) 0xC1, 0x0A, 0x31, (byte) 0xFE, 0x58, (byte) 0xC8, 0x08, 0x74 }); - + private static final int DEFAULT_LE = 252; private static final int DEFAULT_EXTENDED_LE = 65532; - + private static final String DEFAULT_RESET_RESOURCE = "classpath:org/opensc/pkcs15/scripts/cardos/v43b_reset.ser"; - private static final String RESET_SCRIPT_PROPERTY = "org.opensc.pkcs15.scripts.cardos.v43b_reset"; - + private static final String RESET_SCRIPT_PROPERTY = "org.opensc.pkcs15.scripts.cardos.v43b_reset"; + private CardChannel channel; private TokenFile currentFile; - + /** * @param channel The card channel to use. */ @@ -94,26 +95,26 @@ public CardOSToken(CardChannel channel) { */ @Override public void reset() throws IOException { - + String res = System.getProperty(RESET_SCRIPT_PROPERTY); - + if (res == null) res = DEFAULT_RESET_RESOURCE; - + ScriptResourceFactory scriptResourceFactory = ScriptResourceFactory.getInstance(); ScriptResource r = scriptResourceFactory.getScriptResource(res); - + ScriptParserFactory scriptParserFactory = ScriptParserFactory.getInstance(); ScriptParser parser = scriptParserFactory.getScriptParser(res.substring(res.lastIndexOf('.')+1)); - + Command cmd = parser.parseScript(r); - + try { while (cmd != null) { cmd = cmd.execute(this.channel); } } catch (CardException e) { - throw new PKCS15Exception("Error executing reset script ["+res+"].",e); + throw new PKCS15CardException("Error executing reset script ["+res+"].",e); } } @@ -125,7 +126,7 @@ public void close() throws IOException { try { this.channel.close(); } catch (CardException e) { - throw new PKCS15Exception("Error closing card",e); + throw new PKCS15CardException("Error closing card",e); } } @@ -134,38 +135,38 @@ public void close() throws IOException { */ @Override public DF createDF(int path, long size, DFAcl acl) throws IOException { - + if (size < 0 || size > 65535L) throw new PKCS15Exception("Illegal size ["+size+"] for DF ["+PathHelper.formatPathAppend(this.currentFile.getPath(),path)+"].",PKCS15Exception.ERROR_INVALID_PARAMETER); ByteArrayOutputStream bos = new ByteArrayOutputStream(256); DataOutputStream dos = new DataOutputStream(bos); - + dos.write(0x62); // length of subsequent FCP data field, to be filled at end. dos.write(0x00); - + // fill in FCP data // DF body size dos.write(0x81); dos.write(0x02); dos.writeShort((int)size); - + // File descriptor: 38h DF dos.write(0x82); dos.write(0x01); dos.write(0x38); - + // File ID dos.write(0x83); dos.write(0x02); dos.writeShort(path); - + // Default file status. dos.write(0x85); dos.write(0x01); dos.write(0x00); - + // ACL definitions dos.write(0x86); dos.write(0x08); @@ -177,25 +178,25 @@ public DF createDF(int path, long size, DFAcl acl) throws IOException { dos.write(acl.getAcDelete()); dos.write(acl.getAcAdmin()); dos.write(acl.getAcCreate()); - + // get command data. dos.flush(); byte [] data = bos.toByteArray(); - + // fill in length of subsequent FCP data field, to be filled at end. data[1] = (byte)(data.length - 2); - + // CREATE FILE, P1=0x00, P2=0x00, ID -> read current EF from position 0. CommandAPDU cmd = new CommandAPDU(0x00,0xE0,0x00,0x00,data,DEFAULT_LE); - + try { ResponseAPDU resp = this.channel.transmit(cmd); - + if (resp.getSW() != PKCS15Exception.ERROR_OK) throw new PKCS15Exception("CREATE FILE for DF ["+PathHelper.formatPathAppend(this.currentFile.getPath(),path)+"] returned error",resp.getSW()); - + } catch (CardException e) { - throw new PKCS15Exception("Error sending CREATE FILE for DF ["+PathHelper.formatPathAppend(this.currentFile.getPath(),path)+"]",e); + throw new PKCS15CardException("Error sending CREATE FILE for DF ["+PathHelper.formatPathAppend(this.currentFile.getPath(),path)+"]",e); } return new DF(new TokenPath(this.currentFile.getPath(),path),size,acl); @@ -206,38 +207,38 @@ public DF createDF(int path, long size, DFAcl acl) throws IOException { */ @Override public EF createEF(int path, long size, EFAcl acl) throws IOException { - + if (size < 0 || size > 65535L) throw new PKCS15Exception("Illegal size ["+size+"] for EF ["+PathHelper.formatPathAppend(this.currentFile.getPath(),path)+"].",PKCS15Exception.ERROR_INVALID_PARAMETER); - + ByteArrayOutputStream bos = new ByteArrayOutputStream(256); DataOutputStream dos = new DataOutputStream(bos); - + dos.write(0x62); // length of subsequent FCP data field, to be filled at end. dos.write(0x00); - + // *** fill in FCP data // Only EF: Net size in bytes dos.write(0x80); dos.write(0x02); dos.writeShort((int)size); - + // File descriptor: 01h BINARY dos.write(0x82); dos.write(0x01); dos.write(0x01); - + // File ID dos.write(0x83); dos.write(0x02); dos.writeShort(path); - + // Default file status. dos.write(0x85); dos.write(0x01); dos.write(0x00); - + // ACL definitions dos.write(0x86); dos.write(0x09); @@ -250,25 +251,25 @@ public EF createEF(int path, long size, EFAcl acl) throws IOException { dos.write(acl.getAcAdmin()); dos.write(acl.getAcIncrease()); dos.write(acl.getAcDecrease()); - + // *** get command data. dos.flush(); byte [] data = bos.toByteArray(); - + // fill in length of subsequent FCP data field, to be filled at end. data[1] = (byte)(data.length - 2); - + // CREATE FILE, P1=0x00, P2=0x00, ID -> read current EF from position 0. CommandAPDU cmd = new CommandAPDU(0x00,0xE0,0x00,0x00,data,DEFAULT_LE); - + try { ResponseAPDU resp = this.channel.transmit(cmd); - + if (resp.getSW() != PKCS15Exception.ERROR_OK) throw new PKCS15Exception("CREATE FILE for EF ["+PathHelper.formatPathAppend(this.currentFile.getPath(),path)+"] returned error",resp.getSW()); - + } catch (CardException e) { - throw new PKCS15Exception("Error sending CREATE FILE for EF ["+PathHelper.formatPathAppend(this.currentFile.getPath(),path)+"]",e); + throw new PKCS15CardException("Error sending CREATE FILE for EF ["+PathHelper.formatPathAppend(this.currentFile.getPath(),path)+"]",e); } return new EF(new TokenPath(this.currentFile.getPath(),path),size,acl); @@ -279,18 +280,18 @@ public EF createEF(int path, long size, EFAcl acl) throws IOException { */ @Override public void deleteDF(int path) throws IOException { - + // DELETE FILE, P1=0x00, P2=0x00, ID -> read current EF from position 0. CommandAPDU cmd = new CommandAPDU(0x00,0xE4,0x00,0x00,PathHelper.idToPath(path),DEFAULT_LE); - + try { ResponseAPDU resp = this.channel.transmit(cmd); - + if (resp.getSW() != PKCS15Exception.ERROR_OK) throw new PKCS15Exception("DELETE FILE for DF ["+PathHelper.formatPathAppend(this.currentFile.getPath(),path)+"] returned error",resp.getSW()); - + } catch (CardException e) { - throw new PKCS15Exception("Error sending DELETE FILE for DF ["+PathHelper.formatPathAppend(this.currentFile.getPath(),path)+"]",e); + throw new PKCS15CardException("Error sending DELETE FILE for DF ["+PathHelper.formatPathAppend(this.currentFile.getPath(),path)+"]",e); } } @@ -299,18 +300,18 @@ public void deleteDF(int path) throws IOException { */ @Override public void deleteEF(int path) throws IOException { - + // DELETE FILE, P1=0x00, P2=0x00, ID -> read current EF from position 0. CommandAPDU cmd = new CommandAPDU(0x00,0xE4,0x00,0x00,PathHelper.idToPath(path),DEFAULT_LE); - + try { ResponseAPDU resp = this.channel.transmit(cmd); - + if (resp.getSW() != PKCS15Exception.ERROR_OK) throw new PKCS15Exception("DELETE FILE for EF ["+PathHelper.formatPathAppend(this.currentFile.getPath(),path)+"] returned error",resp.getSW()); - + } catch (CardException e) { - throw new PKCS15Exception("Error sending DELETE FILE for EF ["+PathHelper.formatPathAppend(this.currentFile.getPath(),path)+"]",e); + throw new PKCS15CardException("Error sending DELETE FILE for EF ["+PathHelper.formatPathAppend(this.currentFile.getPath(),path)+"]",e); } } @@ -319,7 +320,7 @@ public void deleteEF(int path) throws IOException { */ @Override public TokenFile getCurrentFile() throws IOException { - + return this.currentFile; } @@ -328,10 +329,10 @@ public TokenFile getCurrentFile() throws IOException { */ @Override public InputStream readEFData() throws IOException { - + if (this.currentFile == null) - throw new IOException("No current EF selected."); - + throw new IOException("No current EF selected."); + // READ BINARY, P1=0x00, P2=0x00, ID -> read current EF from position 0. CommandAPDU cmd = new CommandAPDU(0x00,0xB0,0x00,0x00,DEFAULT_EXTENDED_LE); @@ -339,9 +340,9 @@ public InputStream readEFData() throws IOException { ResponseAPDU resp = this.channel.transmit(cmd); return new ByteArrayInputStream(resp.getData()); - + } catch (CardException e) { - throw new PKCS15Exception("Error sending READ BINARY",e); + throw new PKCS15CardException("Error sending READ BINARY",e); } } @@ -349,24 +350,24 @@ private DataInputStream getSelectFileData(ResponseAPDU resp) throws IOException { if (resp.getSW() != PKCS15Exception.ERROR_OK) throw new PKCS15Exception("Card error in response to SELECT FILE",resp.getSW()); - + if (resp.getNr() < 2) - throw new IOException("response to SELECT FILE contains less than 2 bytes."); - + throw new IOException("response to SELECT FILE contains less than 2 bytes."); + int b = resp.getData()[0]; - + if (b != 0x6f) throw new IOException("response to SELECT FILE contains no FCI data."); - + int n = ((int)resp.getData()[1]) & 0xff; - + if (n != resp.getNr()-2) throw new IOException("FCI dat in response to SELECT FILE contains invalid length."); - + return new DataInputStream(new ByteArrayInputStream(resp.getData(),2,n)); - + } - + /* (non-Javadoc) * @see org.opensc.pkcs15.token.Token#select(int) */ @@ -374,16 +375,16 @@ private DataInputStream getSelectFileData(ResponseAPDU resp) throws IOException public TokenFile select(int path) throws IOException { if (this.currentFile == null) - throw new IOException("No current DF selected."); + throw new IOException("No current DF selected."); // SELECT FILE, P1=0x00, P2=0x00, ID -> select EF or DF CommandAPDU cmd = new CommandAPDU(0x00,0xA4,0x00,0x00,PathHelper.idToPath(path),DEFAULT_LE); - + try { ResponseAPDU resp = this.channel.transmit(cmd); - + DataInputStream dis = getSelectFileData(resp); - + long bodySize = -1; long fileSize = -1; int acRead = TokenFileAcl.AC_ALWAYS; @@ -395,14 +396,14 @@ public TokenFile select(int path) throws IOException { int acAdmin = TokenFileAcl.AC_ALWAYS; int acIncrease = TokenFileAcl.AC_ALWAYS; int acDecrease = TokenFileAcl.AC_ALWAYS; - + int tag; - + while ((tag=dis.read()) >= 0) { int n = dis.read(); if (n<0) break; - + switch (tag) { case 0x80: @@ -410,7 +411,7 @@ public TokenFile select(int path) throws IOException { throw new IOException("Invalid length ["+n+"] of FCI tag 0x80."); fileSize = dis.readUnsignedShort(); break; - + case 0x83: if (n!=2) throw new IOException("Invalid length ["+n+"] of FCI tag 0x83."); @@ -418,14 +419,14 @@ public TokenFile select(int path) throws IOException { if (tpath != path) throw new IOException("File ID ["+PathHelper.formatID(tpath)+"] reported by SELECT FILE differs from requested ID ["+PathHelper.formatID(path)+"]."); break; - + case 0x81: if (n!=2) throw new IOException("Invalid length ["+n+"] of FCI tag 0x81."); bodySize = dis.readUnsignedShort(); break; - - case 0x86: + + case 0x86: if (n>=1) acRead = dis.read(); if (n>=2) acUpdate = dis.read(); if (n>=3) acAppend = dis.read(); @@ -435,21 +436,21 @@ public TokenFile select(int path) throws IOException { if (n>=7) acAdmin = dis.read(); if (n>=8) acIncrease = dis.read(); if (n>=9) acDecrease = dis.read(); - + if (n!=9 && n!=8) log.warn("Invalid length ["+n+"] of FCI tag 0x86 for EF."); - + if (n>9) dis.skipBytes(n-9); break; - + default: byte [] tmp = new byte[n]; dis.readFully(tmp); log.warn("skipping FCI tag [0x"+Integer.toHexString(tag)+"], data ["+Util.asHex(tmp)+"]."); } } - + if (fileSize >= 0) this.currentFile = new EF(new TokenPath(this.currentFile.getPath(),path),fileSize, acRead,acUpdate,acAppend,acDeactivate,acActivate, @@ -462,19 +463,19 @@ else if (bodySize >= 0) throw new IOException("No 0x80 or 0x81 tag specified in order to distinguish between DF an EF."); return this.currentFile; - + } catch (CardException e) { - throw new PKCS15Exception("Error sending SELECT FILE",e); + throw new PKCS15CardException("Error sending SELECT FILE",e); } } private DF selectDFInternal(CommandAPDU cmd, TokenPath targetPath) throws IOException { - + try { ResponseAPDU resp = this.channel.transmit(cmd); - + DataInputStream dis = getSelectFileData(resp); - + long bodySize = 0; int acLifeCycle = TokenFileAcl.AC_ALWAYS; int acUpdate = TokenFileAcl.AC_ALWAYS; @@ -484,14 +485,14 @@ private DF selectDFInternal(CommandAPDU cmd, TokenPath targetPath) throws IOExce int acDelete = TokenFileAcl.AC_ALWAYS; int acAdmin = TokenFileAcl.AC_ALWAYS; int acCreate = TokenFileAcl.AC_ALWAYS; - + int tag; - + while ((tag=dis.read()) >= 0) { int n = dis.read(); if (n<0) break; - + switch (tag) { case 0x81: @@ -499,7 +500,7 @@ private DF selectDFInternal(CommandAPDU cmd, TokenPath targetPath) throws IOExce throw new IOException("Invalid length ["+n+"] of FCI tag 0x81."); bodySize = dis.readUnsignedShort(); break; - + case 0x83: if (n!=2) throw new IOException("Invalid length ["+n+"] of FCI tag 0x83."); @@ -508,7 +509,7 @@ private DF selectDFInternal(CommandAPDU cmd, TokenPath targetPath) throws IOExce throw new IOException("File ID ["+PathHelper.formatID(tpath)+"] reported by SELECT FILE differs from requested ID ["+PathHelper.formatID(targetPath.getTailID())+"]."); break; - case 0x86: + case 0x86: if (n>=1) acLifeCycle = dis.read(); if (n>=2) acUpdate = dis.read(); if (n>=3) acAppend = dis.read(); @@ -517,30 +518,30 @@ private DF selectDFInternal(CommandAPDU cmd, TokenPath targetPath) throws IOExce if (n>=6) acDelete = dis.read(); if (n>=7) acAdmin = dis.read(); if (n>=8) acCreate = dis.read(); - + if (n!=8) log.warn("Invalid length ["+n+"] of FCI tag 0x86 for DF."); - + if (n>8) dis.skipBytes(n-8); break; - + default: byte [] tmp = new byte[n]; dis.readFully(tmp); log.warn("skipping FCI tag [0x"+Integer.toHexString(tag)+"], data ["+Util.asHex(tmp)+"]."); } } - + DF df = new DF(targetPath,bodySize, acLifeCycle,acUpdate,acAppend,acDeactivate,acActivate, acDelete,acAdmin,acCreate); this.currentFile = df; return df; - + } catch (CardException e) { - throw new PKCS15Exception("Error sending select MF",e); + throw new PKCS15CardException("Error sending select MF",e); } } @@ -549,16 +550,16 @@ private DF selectDFInternal(CommandAPDU cmd, TokenPath targetPath) throws IOExce */ @Override public DF selectDF(int path) throws IOException { - + if (this.currentFile == null) - throw new IOException("No current DF selected."); + throw new IOException("No current DF selected."); // SELECT FILE, P1=0x01, P2=0x00, no data -> select DF CommandAPDU cmd = new CommandAPDU(0x00,0xA4,0x01,0x00,PathHelper.idToPath(path),DEFAULT_LE); - + return this.selectDFInternal(cmd,new TokenPath(this.currentFile.getPath(),path)); } - + /* (non-Javadoc) * @see org.opensc.pkcs15.token.Token#selectEF(int) */ @@ -566,16 +567,16 @@ public DF selectDF(int path) throws IOException { public EF selectEF(int path) throws IOException { if (this.currentFile == null) - throw new IOException("No current DF selected."); + throw new IOException("No current DF selected."); // SELECT FILE, P1=0x02, P2=0x00, no data -> select EF CommandAPDU cmd = new CommandAPDU(0x00,0xA4,0x02,0x00,PathHelper.idToPath(path),DEFAULT_LE); - + try { ResponseAPDU resp = this.channel.transmit(cmd); - + DataInputStream dis = getSelectFileData(resp); - + long fileSize = 0; int acRead = TokenFileAcl.AC_ALWAYS; int acUpdate = TokenFileAcl.AC_ALWAYS; @@ -586,14 +587,14 @@ public EF selectEF(int path) throws IOException { int acAdmin = TokenFileAcl.AC_ALWAYS; int acIncrease = TokenFileAcl.AC_ALWAYS; int acDecrease = TokenFileAcl.AC_ALWAYS; - + int tag; - + while ((tag=dis.read()) >= 0) { int n = dis.read(); if (n<0) break; - + switch (tag) { case 0x80: @@ -601,7 +602,7 @@ public EF selectEF(int path) throws IOException { throw new IOException("Invalid length ["+n+"] of FCI tag 0x80."); fileSize = dis.readUnsignedShort(); break; - + case 0x83: if (n!=2) throw new IOException("Invalid length ["+n+"] of FCI tag 0x83."); @@ -610,7 +611,7 @@ public EF selectEF(int path) throws IOException { throw new IOException("File ID ["+PathHelper.formatID(tpath)+"] reported by SELECT FILE differs from requested ID ["+PathHelper.formatID(path)+"]."); break; - case 0x86: + case 0x86: if (n>=1) acRead = dis.read(); if (n>=2) acUpdate = dis.read(); if (n>=3) acAppend = dis.read(); @@ -620,30 +621,30 @@ public EF selectEF(int path) throws IOException { if (n>=7) acAdmin = dis.read(); if (n>=8) acIncrease = dis.read(); if (n>=9) acDecrease = dis.read(); - + if (n!=9) log.warn("Invalid length ["+n+"] of FCI tag 0x86 for EF."); - + if (n>9) dis.skipBytes(n-9); break; - + default: byte [] tmp = new byte[n]; dis.readFully(tmp); log.warn("skipping FCI tag [0x"+Integer.toHexString(tag)+"], data ["+Util.asHex(tmp)+"]."); } } - + EF ef = new EF(new TokenPath(this.currentFile.getPath(),path),fileSize, acRead,acUpdate,acAppend,acDeactivate,acActivate, acDelete,acAdmin,acIncrease,acDecrease); this.currentFile = ef; return ef; - + } catch (CardException e) { - throw new PKCS15Exception("Error sending select MF",e); + throw new PKCS15CardException("Error sending select MF",e); } } @@ -652,15 +653,15 @@ public EF selectEF(int path) throws IOException { */ @Override public MF selectMF() throws IOException { - + // SELECT FILE, P1=0x00, P2=0x00, no data -> select MF CommandAPDU cmd = new CommandAPDU(0x00,0xA4,0x00,0x00,DEFAULT_LE); - + try { ResponseAPDU resp = this.channel.transmit(cmd); - + DataInputStream dis = getSelectFileData(resp); - + long bodySize = 0; int acLifeCycle = TokenFileAcl.AC_ALWAYS; int acUpdate = TokenFileAcl.AC_ALWAYS; @@ -672,14 +673,14 @@ public MF selectMF() throws IOException { int acCreate = TokenFileAcl.AC_ALWAYS; int acExecute = TokenFileAcl.AC_ALWAYS; int acAllocate = TokenFileAcl.AC_ALWAYS; - + int tag; - + while ((tag=dis.read()) >= 0) { int n = dis.read(); if (n<0) break; - + switch (tag) { case 0x81: @@ -687,7 +688,7 @@ public MF selectMF() throws IOException { throw new IOException("Invalid length ["+n+"] of FCI tag 0x81."); bodySize = dis.readUnsignedShort(); break; - + case 0x83: if (n!=2) throw new IOException("Invalid length ["+n+"] of FCI tag 0x83."); @@ -696,7 +697,7 @@ public MF selectMF() throws IOException { throw new IOException("File ID ["+PathHelper.formatID(tpath)+"] reported by SELECT FILE differs from requested ID ["+PathHelper.formatID(PathHelper.MF_ID)+"]."); break; - case 0x86: + case 0x86: if (n>=1) acLifeCycle = dis.read(); if (n>=2) acUpdate = dis.read(); if (n>=3) acAppend = dis.read(); @@ -707,30 +708,30 @@ public MF selectMF() throws IOException { if (n>=8) acCreate = dis.read(); if (n>=9) acExecute = dis.read(); if (n>=10) acAllocate = dis.read(); - + if (n!=10) log.warn("Invalid length ["+n+"] of FCI tag 0x86 for MF."); - + if (n>10) dis.skipBytes(n-10); break; - + default: byte [] tmp = new byte[n]; dis.readFully(tmp); log.warn("skipping FCI tag [0x"+Integer.toHexString(tag)+"], data ["+Util.asHex(tmp)+"]."); } } - + MF mf = new MF(PathHelper.MF_PATH,bodySize, acLifeCycle,acUpdate,acAppend,acDeactivate,acActivate, acDelete,acAdmin,acCreate,acExecute,acAllocate); this.currentFile = mf; return mf; - + } catch (CardException e) { - throw new PKCS15Exception("Error sending select MF",e); + throw new PKCS15CardException("Error sending select MF",e); } } @@ -739,10 +740,10 @@ public MF selectMF() throws IOException { */ @Override public DF selectParentDF() throws IOException { - + // SELECT FILE, P1=0x03, P2=0x00, no data -> select parent DF CommandAPDU cmd = new CommandAPDU(0x00,0xA4,0x03,0x00,DEFAULT_LE); - + return this.selectDFInternal(cmd,this.currentFile.getPath().getParent()); } @@ -750,37 +751,37 @@ private class EFOutputStream extends ByteArrayOutputStream { private final TokenPath pathToWrite; private int lastFlushPos; - + EFOutputStream(final TokenPath pathToWrite) { this.pathToWrite = pathToWrite; } - + /* (non-Javadoc) * @see java.io.ByteArrayOutputStream#close() */ @Override public void flush() throws IOException { - + if (this.size() == this.lastFlushPos) return; - + if (!this.pathToWrite.equals(CardOSToken.this.currentFile.getPath())) throw new PKCS15Exception("Path changed before writing content to EF ["+this.pathToWrite+"].",PKCS15Exception.ERROR_TECHNICAL_ERROR); - + super.close(); - + // UPDATE BINARY, P1=0x00, P2=0x00, ID -> read current EF from position 0. CommandAPDU cmd = new CommandAPDU(0x00,0xD6,0x00,0x00,this.toByteArray(),DEFAULT_LE); - + try { ResponseAPDU resp = CardOSToken.this.channel.transmit(cmd); - + if (resp.getSW() != PKCS15Exception.ERROR_OK) throw new PKCS15Exception("UPDATE BINARY for EF ["+this.pathToWrite+"] returned error",resp.getSW()); - + this.lastFlushPos = this.size(); - + } catch (CardException e) { - throw new PKCS15Exception("Error sending UPDATE BINARY for EF ["+this.pathToWrite+"]",e); + throw new PKCS15CardException("Error sending UPDATE BINARY for EF ["+this.pathToWrite+"]",e); } } @@ -789,21 +790,21 @@ public void flush() throws IOException { */ @Override public void close() throws IOException { - + this.flush(); super.close(); } }; - + /* (non-Javadoc) * @see org.opensc.pkcs15.token.Token#writeEFData() */ @Override public OutputStream writeEFData() throws IOException { - + if (this.currentFile == null) - throw new IOException("No current EF selected."); - + throw new IOException("No current EF selected."); + return new EFOutputStream(this.currentFile.getPath()); }