diff options
| author | tkellner <tkellner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2013-09-03 15:38:58 +0000 | 
|---|---|---|
| committer | tkellner <tkellner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2013-09-03 15:38:58 +0000 | 
| commit | b95a023faa4b6248c9526d1a76ed4e26b1dfc997 (patch) | |
| tree | 817fc59d324dfdae7683f684d651c5d7f2975921 /smcc | |
| parent | 2f19e8e81a42b495108b31133e37917ffd0620a8 (diff) | |
| download | mocca-b95a023faa4b6248c9526d1a76ed4e26b1dfc997.tar.gz mocca-b95a023faa4b6248c9526d1a76ed4e26b1dfc997.tar.bz2 mocca-b95a023faa4b6248c9526d1a76ed4e26b1dfc997.zip | |
Gemalto .NET V2 Card integration
git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@1201 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
Diffstat (limited to 'smcc')
8 files changed, 1448 insertions, 2 deletions
| diff --git a/smcc/src/main/java/at/gv/egiz/smcc/GemaltoNetV2_0Card.java b/smcc/src/main/java/at/gv/egiz/smcc/GemaltoNetV2_0Card.java new file mode 100644 index 00000000..3bea0753 --- /dev/null +++ b/smcc/src/main/java/at/gv/egiz/smcc/GemaltoNetV2_0Card.java @@ -0,0 +1,513 @@ +package at.gv.egiz.smcc; + +import iaik.me.security.CryptoBag; +import iaik.me.security.CryptoException; +import iaik.me.security.MessageDigest; +import iaik.me.security.cipher.TripleDES; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.util.zip.DataFormatException; +import java.util.zip.Inflater; + +import javax.print.attribute.standard.Severity; +import javax.smartcardio.Card; +import javax.smartcardio.CardChannel; +import javax.smartcardio.CardException; +import javax.smartcardio.CardTerminal; +import javax.smartcardio.CommandAPDU; +import javax.smartcardio.ResponseAPDU; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sun.security.rsa.RSAPadding; +import at.gv.egiz.smcc.pin.gui.ModifyPINGUI; +import at.gv.egiz.smcc.pin.gui.PINGUI; +import at.gv.egiz.smcc.util.MSCMException; +import at.gv.egiz.smcc.util.MSCMService; + +public class GemaltoNetV2_0Card extends AbstractSignatureCard implements +		PINMgmtSignatureCard { + +	private final Logger log = LoggerFactory +			.getLogger(GemaltoNetV2_0Card.class); + +	PinInfo pinPinInfo; +	PinInfo pukPinInfo; + +	public void init(Card card, CardTerminal cardTerminal) { +		super.init(card, cardTerminal); + +		log.info("GemaltoNetV2 card found"); + +		pinPinInfo = new PinInfo(4, 64, "[0-9]", +				"at/gv/egiz/smcc/GemaltoNetV2_0Card", "sig.pin", (byte) 1, +				new byte[] {}, 5); + +		pukPinInfo = new PinInfo(48, 48, "[0-9A-F]", +				"at/gv/egiz/smcc/GemaltoNetV2_0Card", "sig.puk", (byte) 2, +				new byte[] {}, 3); +	} +	 +	public static byte[] hexStringToByteArray(String s) { +	    int len = s.length(); +	    byte[] data = new byte[len / 2]; +	    for (int i = 0; i < len; i += 2) { +	        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) +	                             + Character.digit(s.charAt(i+1), 16)); +	    } +	    return data; +	} + +	@Override +	public byte[] getCertificate(KeyboxName keyboxName, PINGUI pinGUI) +			throws SignatureCardException, InterruptedException { +		try { +			CardChannel channel = this.getCardChannel();// this.getCard().getBasicChannel(); +			MSCMService service = new MSCMService(channel); +			byte[] filecnt = service.readFile("mscp\\ksc00"); + +			Inflater inflater = new Inflater(); +			inflater.setInput(filecnt, 4, filecnt.length - 4); +			ByteArrayOutputStream out = new ByteArrayOutputStream(); +			while (!inflater.finished()) { +				byte[] uncompressedData = new byte[1024]; +				int compressLength = inflater.inflate(uncompressedData, 0, +						uncompressedData.length); +				// System.out.println(compressedData); +				out.write(uncompressedData, 0, compressLength); +			} +			byte[] uncompressed = out.toByteArray(); +			return uncompressed; +		} catch (CardException e) { +			log.info("Failed to get certificate.", e); +			throw new SignatureCardException(e); +		} catch (DataFormatException e) { +			log.info("Failed to get certificate.", e); +			throw new SignatureCardException(e); +		} catch (IOException e) { +			log.info("Failed to get certificate.", e); +			throw new SignatureCardException(e); +		} catch (MSCMException e) { +			log.info("Failed to get certificate.", e); +			throw new SignatureCardException(e); +		} +	} + +	@Override +	public byte[] getInfobox(String infobox, PINGUI pinGUI, String domainId) +			throws SignatureCardException, InterruptedException { +		throw new IllegalArgumentException("Infobox '" + infobox +				+ "' not supported."); +	} + +	@Override +	public byte[] createSignature(InputStream input, KeyboxName keyboxName, +			PINGUI pinGUI, String alg) throws SignatureCardException, +			InterruptedException, IOException { + +		MessageDigest md; +		try { +			if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName) +					&& (alg == null || "http://www.w3.org/2000/09/xmldsig#rsa-sha1" +							.equals(alg))) { +				md = MessageDigest.getInstance("SHA-1"); +			} else if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName) +					&& ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" +							.equals(alg))) { +				md = MessageDigest.getInstance("SHA-256"); +			} else { +				throw new SignatureCardException( +						"Card does not support signature algorithm " + alg +								+ "."); +			} +		} catch (CryptoException e) { +			log.error("Failed to get MessageDigest.", e); +			throw new SignatureCardException(e); +		} + +		byte[] digest = new byte[md.getDigestLength()]; +		for (int l; (l = input.read(digest)) != -1;) { +			md.update(digest, 0, l); +		} +		digest = md.digest(); + +		try { +			RSAPadding padding = RSAPadding.getInstance( +					RSAPadding.PAD_BLOCKTYPE_1, 256); + +			CardChannel channel = this.getCardChannel(); +			MSCMService service = new MSCMService(channel); + +			verifyPINLoop(channel, pinPinInfo, pinGUI); + +			byte[] paded = padding.pad(digest); +			byte[] sign = service.privateKeyDecrypt((byte) 0, (byte) 2, paded); +			return sign; +		} catch (Throwable e) { +			log.warn("Failed to execute command.", e); +			throw new SignatureCardException("Failed to access card.", e); +		} +	} + +	protected void unblockPINLoop(CardChannel channel, +			ModifyPINGUI provider, PinInfo pin) throws InterruptedException, CardException, SignatureCardException{ + +		int retries = -1; +		do { +			retries = exec_unblockPIN(channel, provider, pin); +		} while (retries > 0); +	} +	 +	/* +	 * Unblock PIN with PUK code +	 */ +	protected int exec_unblockPIN(CardChannel channel, ModifyPINGUI changePINGUI, PinInfo pin) +			throws InterruptedException, CardException, SignatureCardException { +		 +		 +		char[] oldPIN = changePINGUI.providePUK(pin, pukPinInfo, +				pukPinInfo.retries); + +		char[] newPIN = changePINGUI.provideNewPIN(pin); +		 +		byte[] ascii_pin = encodePIN(newPIN); + +		MSCMService service = new MSCMService(channel); +		 +		try { +			byte[] key = hexStringToByteArray(new String(oldPIN)); +			if(key.length != 24) { +				throw new SignatureCardException("Invalid ADMIN PIN (not 24 bytes long)!"); +			} +			byte[] challenge = service.getChallenge(); +			byte[] response = service.cryptoResponse(challenge, key); +			service.unblockPIN((byte) 1, response, ascii_pin, pin.maxRetries); +			pin.setActive(pin.maxRetries); +			return -1; +		} catch (IOException e) { +			String msg = "SET PIN failed."; +			log.info(msg); +			pin.setUnknown(); +			throw new SignatureCardException(msg, e); +		} catch (MSCMException e) { +			log.info(e.getMessage()); +			try { +				return service.getTriesRemaining((byte) 2); +			} catch (IOException ec) { +				String msg = "getTriesRemaining failed."; +				log.info(msg); +				pin.setUnknown(); +				throw new SignatureCardException(msg, ec); +			} catch (MSCMException e1) { +				String msg = "getTriesRemaining failed."; +				log.info(msg); +				pin.setUnknown(); +				throw new SignatureCardException(msg, e1); +			} +		} + +	} +	 +	protected void verifyPINLoop(CardChannel channel, PinInfo spec, +			PINGUI provider) throws InterruptedException, CardException, +			SignatureCardException { + +		int retries = -1; +		do { +			retries = verifyPIN(channel, spec, provider, retries); +		} while (retries > 0); +	} + +	/* +	 * Verify PIN/PUK entry +	 */ +	protected int verifyPUK(CardChannel channel, PinInfo pinInfo, +			PINGUI provider, int retries) throws InterruptedException, +			CardException, SignatureCardException { + +		char[] pin = provider.providePIN(pinInfo, pinInfo.retries); + +		byte[] ascii_pin = hexStringToByteArray(new String(pin)); +		 +		if(ascii_pin.length != 24) { +			throw new SignatureCardException("Invalid ADMIN PIN (not 24 bytes long)!"); +		} +		 +		MSCMService service = new MSCMService(channel); + +		try { +			byte[] challenge = service.getChallenge(); +			byte[] response = service.cryptoResponse(challenge, ascii_pin); +			service.doExternalAuthentication(response); +			pinInfo.setActive(pinInfo.maxRetries); +			return -1; +		} catch (MSCMException e) { +			try { +				int tries = service.getTriesRemaining(pinInfo.getKID()); +				pinInfo.setActive(tries); +				return tries; +			} catch (Exception ex) { +				log.error("Failed to get remaining tries"); +				throw new SignatureCardException(ex); +			} +		} catch (IOException e) { +			log.error("Failed to verify PIN"); +			throw new SignatureCardException(e); +		} +	} +	 +	/* +	 * Verify PIN/PUK entry +	 */ +	protected int verifyPIN(CardChannel channel, PinInfo pinInfo, +			PINGUI provider, int retries) throws InterruptedException, +			CardException, SignatureCardException { + +		char[] pin = provider.providePIN(pinInfo, pinInfo.retries); + +		byte[] ascii_pin = encodePIN(pin); +		MSCMService service = new MSCMService(channel); + +		try { +			service.verifyPin(pinInfo.getKID(), ascii_pin); +			pinInfo.setActive(pinInfo.maxRetries); +			return -1; +		} catch (MSCMException e) { +			try { +				int tries = service.getTriesRemaining(pinInfo.getKID()); +				if(tries == 0) { +					pinInfo.setBlocked(); +					throw new LockedException(); +				} +				pinInfo.setActive(tries); +				return tries; +			} catch (IOException ex) { +				log.error("Failed to get remaining tries"); +				throw new SignatureCardException(ex); +			} catch (MSCMException e1) { +				log.error("Failed to get remaining tries"); +				throw new SignatureCardException(e1); +			} +		} catch (IOException e) { +			log.error("Failed to verify PIN"); +			throw new SignatureCardException(e); +		} +	} + +	protected void changePINLoop(CardChannel channel, ModifyPINGUI provider, +			PinInfo pin) throws InterruptedException, CardException, +			SignatureCardException { + +		int retries = -1; +		do { +			if(pin.getKID() == 2) { +				retries = exec_changePUK(channel, provider, pin); +			} else { +				retries = exec_changePIN(channel, provider, pin); +			} +		} while (retries > 0); +	} + +	protected byte[] cryptoChallenge(byte[] challenge, byte[] pass) { +		try { +			byte[] iv = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, +					(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, +					(byte) 0x00 }; +			TripleDES cip = new TripleDES(); +			cip.init(TripleDES.ENCRYPT_MODE, CryptoBag.makeSecretKey(pass), +					CryptoBag.makeIV(iv), null); +			log.info("Crypto IV: " +					+ MSCMService.bytArrayToHex(cip.getIV().getEncoded())); +			byte[] result = cip.doFinal(challenge); +			log.info("Crypto result: " + MSCMService.bytArrayToHex(result)); +			return result; +		} catch (CryptoException e) { +			log.error("Failed to get crypto stuff", e); +			return null; +		} +	} + +	/* +	 * Unblock PIN with PUK code +	 */ +	protected int exec_changePUK(CardChannel channel, +			ModifyPINGUI changePINGUI, PinInfo pin) +			throws InterruptedException, CardException, SignatureCardException { + +		char[] oldPIN = changePINGUI.providePUK(pin, pukPinInfo, +				pukPinInfo.retries); + +		char[] newPIN = changePINGUI.provideNewPIN(pin); + +		MSCMService service = new MSCMService(channel); + +		try { +			byte[] key = hexStringToByteArray(new String(oldPIN)); +			byte[] keynew = hexStringToByteArray(new String(newPIN)); +			if(key.length != 24) { +				throw new SignatureCardException("Invalid ADMIN PIN (not 24 bytes long)!"); +			} +			if(keynew.length != 24) { +				throw new SignatureCardException("Invalid ADMIN PIN (not 24 bytes long)!"); +			} +			byte[] challenge = service.getChallenge(); +			byte[] response = service.cryptoResponse(challenge, key); +			service.changePIN((byte) 2, response, keynew, pin.maxRetries); +			pin.setActive(pin.maxRetries); +			return -1; +		} catch (IOException e) { +			String msg = "SET PIN failed."; +			log.info(msg); +			pin.setUnknown(); +			throw new SignatureCardException(msg, e); +		} catch (MSCMException e) { +			log.info(e.getMessage()); +			try { +				int tries = service.getTriesRemaining(pin.getKID()); +				if(tries == 0) { +					pin.setBlocked(); +					throw new LockedException(); +				} +				pin.setActive(tries); +				return tries; +			} catch (IOException ec) { +				String msg = "getTriesRemaining failed."; +				log.info(msg); +				pin.setUnknown(); +				throw new SignatureCardException(msg, ec); +			} catch (MSCMException e1) { +				String msg = "getTriesRemaining failed."; +				log.info(msg); +				pin.setUnknown(); +				throw new SignatureCardException(msg, e1); +			} +		} + +	} +	 +	/* +	 * Unblock PIN with PUK code +	 */ +	protected int exec_changePIN(CardChannel channel, +			ModifyPINGUI changePINGUI, PinInfo pin) +			throws InterruptedException, CardException, SignatureCardException { + +		char[] oldPIN = changePINGUI.providePUK(pin, pinPinInfo, +				pinPinInfo.retries); + +		char[] newPIN = changePINGUI.provideNewPIN(pin); + +		byte[] ascii_puk = encodePIN(oldPIN); + +		byte[] ascii_pin = encodePIN(newPIN); + +		MSCMService service = new MSCMService(channel); + +		try { +			// service -> change pin +			service.changePIN((byte) 1, ascii_puk, ascii_pin, +					pin.maxRetries); +			pin.setActive(pin.maxRetries); +			return -1; +		} catch (IOException e) { +			String msg = "SET PIN failed."; +			log.info(msg); +			pin.setUnknown(); +			throw new SignatureCardException(msg, e); +		} catch (MSCMException e) { +			log.info(e.getMessage()); +			try { +				int tries = service.getTriesRemaining(pin.getKID()); +				if(tries == 0) { +					pin.setBlocked(); +					throw new LockedException(); +				} +				pin.setActive(tries); +				return tries; +			} catch (IOException ec) { +				String msg = "getTriesRemaining failed."; +				log.info(msg); +				pin.setUnknown(); +				throw new SignatureCardException(msg, ec); +			} catch (MSCMException e1) { +				String msg = "getTriesRemaining failed."; +				log.info(msg); +				pin.setUnknown(); +				throw new SignatureCardException(msg, e1); +			} +		} + +	} + +	private byte[] encodePIN(char[] pin) { +		return Charset.forName("ASCII").encode(CharBuffer.wrap(pin)).array(); +	} + +	// @Override +	public PinInfo[] getPinInfos() throws SignatureCardException { +		return new PinInfo[] { pinPinInfo, pukPinInfo }; +	} + +	// @Override +	public void verifyPIN(PinInfo pinInfo, PINGUI pinGUI) +			throws LockedException, NotActivatedException, CancelledException, +			SignatureCardException, InterruptedException { +		 +		try { +			CardChannel channel = this.getCardChannel(); +			if(pinInfo.getKID() == 2) { +				verifyPUK(channel, pinInfo, pinGUI, pinInfo.retries); +			} else { +				verifyPIN(channel, pinInfo, pinGUI, pinInfo.retries); +			} +		} catch (CardException e) { +			log.error("Failed to verify PIN"); +			throw new SignatureCardException(e); +		} +	} + +	// @Override +	public void changePIN(PinInfo pinInfo, ModifyPINGUI changePINGUI) +			throws LockedException, NotActivatedException, CancelledException, +			PINFormatException, SignatureCardException, InterruptedException { +		try { +			changePINLoop(getCardChannel(), changePINGUI, pinInfo); +		} catch (CardException e) { +			log.error("Failed to change PIN"); +			throw new SignatureCardException(e); +		} +	} + +	// @Override +	public void activatePIN(PinInfo pinInfo, ModifyPINGUI activatePINGUI) +			throws CancelledException, SignatureCardException, +			InterruptedException { +		log.error("ACTIVATE PIN not supported by Cypriotic EID"); +		throw new SignatureCardException( +				"PIN activation not supported by this card."); +	} + +	// @Override +	public void unblockPIN(PinInfo pinInfo, ModifyPINGUI pukGUI) +			throws CancelledException, SignatureCardException, +			InterruptedException { +		if(pinInfo.getKID() == 2) { +			throw new SignatureCardException("Unable to unblock PUK"); +		} else { +			CardChannel channel = getCardChannel(); + +			try { +				unblockPINLoop(channel, pukGUI, pinInfo); +			} catch (CardException e) { +				log.info("Failed to unblock PIN.", e); +				throw new SignatureCardException("Failed to unblock PIN.", e); +			} +		} +	} +} diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java index 2d43e375..7c1e56a2 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java @@ -405,6 +405,18 @@ public class SignatureCardFactory {  						(byte) 0xff, (byte) 0xff, (byte) 0xff},  				"at.gv.egiz.smcc.CypriotEID"));	 +		// Gemalto .NET V2.0 +		supportedCards.add(new SupportedCard( +				// ATR [3B:16:96:41:73:74:72:69:64] +				new byte[] { (byte) 0x3b, (byte) 0x16, (byte) 0x96,  +						(byte) 0x41, (byte) 0x73, (byte) 0x74, (byte) 0x72,  +						(byte) 0x69, (byte) 0x64}, +				// mas (ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff) +				new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff,  +						(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,  +						(byte) 0xff, (byte) 0xff}, +				"at.gv.egiz.smcc.GemaltoNetV2_0Card"));	 +		  		// ES DNIe  		supportedCards.add(new SupportedCard(  		// ATR [3b:7f:38:00:00:00:6a:44:4e:49:65:20:02:4c:34:01:13:03:90:00] diff --git a/smcc/src/main/java/at/gv/egiz/smcc/T0CardChannel.java b/smcc/src/main/java/at/gv/egiz/smcc/T0CardChannel.java index 9ae85d04..001f6ec9 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/T0CardChannel.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/T0CardChannel.java @@ -26,6 +26,7 @@ package at.gv.egiz.smcc;  import java.io.ByteArrayOutputStream;  import java.io.IOException; +import java.nio.ByteBuffer;  import javax.smartcardio.CardChannel;  import javax.smartcardio.CardException; @@ -35,10 +36,9 @@ import javax.smartcardio.ResponseAPDU;  public class T0CardChannel extends LogCardChannel {  	public T0CardChannel(CardChannel channel) { -  		super(channel);  	} - +	  	@Override  	public ResponseAPDU transmit(CommandAPDU command) throws CardException { diff --git a/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMConstants.java b/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMConstants.java new file mode 100644 index 00000000..fdaff61e --- /dev/null +++ b/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMConstants.java @@ -0,0 +1,220 @@ +package at.gv.egiz.smcc.util; + +public interface MSCMConstants { +	public static final int HIVECODE_METHOD_GET_PROPERTIES = 0x8187; +	 +	 +	public static final short DEFAULT_SERVICE_PORT = 5; +	 +	public static final String URI = "MSCM"; +	 +	public static final short HIVECODE_TYPE_DEFAULT									= (short)0x7FBD; +	 +	// Methods +	public static final short HIVECODE_METHOD_GETCARDPROPERTY 						= (short)0x8187; +	public static final short HIVECODE_METHOD_GETCONTAINERPROPERTY 					= (short)0x279C; +	public static final short HIVECODE_METHOD_GETVERSION 							= (short)0xDEEC; +	public static final short HIVECODE_METHOD_GETFILES 								= (short)0xE72B; +	public static final short HIVECODE_METHOD_GETTRIESREMAINING						= (short)0x6D08; +	public static final short HIVECODE_METHOD_PRIVATEKEYDECRYPT						= (short)0x6144; +	public static final short HIVECODE_METHOD_GETFILEPROPERTIES						= (short)0xA01B; +	public static final short HIVECODE_METHOD_QUERYFREESPACE						= (short)0x00E5; +	public static final short HIVECODE_METHOD_FORCEGC								= (short)0x3D38; +	public static final short HIVECODE_METHOD_READFILE								= (short)0x744C; +	public static final short HIVECODE_METHOD_VERIFYPIN								= (short)0x506B; +	public static final short HIVECODE_METHOD_CHANGEREFDATA							= (short)0xE08A; +	public static final short HIVECODE_METHOD_GETCHALLENGE							= (short)0xFA3B; +	public static final short HIVECODE_METHOD_EXTAUTH								= (short)0x24FE; +	 +	 +	// Property Fields +	public static final byte PROPERTY_CARD_FREE_SPACE								= (byte)0x00; +	public static final byte PROPERTY_CARD_KEY_SIZES								= (byte)0x02; +	public static final byte PROPERTY_CARD_READ_ONLY								= (byte)0x03; +	public static final byte PROPERTY_CARD_CACHE_MODE								= (byte)0x04; +	public static final byte PROPERTY_CARD_GUID										= (byte)0x05; +	public static final byte PROPERTY_CARD_SERIAL_NUMBER							= (byte)0x06; +	public static final byte PROPERTY_CARD_PIN_INFO									= (byte)0x07; +	public static final byte PROPERTY_CARD_ROLES_LIST								= (byte)0x08; +	public static final byte PROPERTY_CARD_AUTHENTICATED_ROLES						= (byte)0x09; +	public static final byte PROPERTY_CARD_PIN_STRENGTH								= (byte)0x0A; +	public static final byte PROPERTY_CARD_UNBLOCK_FP_SYNC							= (byte)0xF9; +	public static final byte PROPERTY_CARD_PIN_POLICY								= (byte)0x80; +	public static final byte PROPERTY_CARD_X509_ENROLL								= (byte)0x0D; +	public static final byte PROPERTY_CARD_CHANGE_PIN_FIRST							= (byte)0xFA; +	public static final byte PROPERTY_CARD_IMPORT_ALLOWED							= (byte)0x90; +	public static final byte PROPERTY_CARD_IMPORT_CHANGE_ALLOWED					= (byte)0x91; +	public static final byte PROPERTY_CARD_PKI_OFF									= (byte)0xF7; +	public static final byte PROPERTY_CARD_VERSION_INFO								= (byte)0xFF; +	 +	public static final byte PROPERTY_CONTAINER_INFO								= (byte)0x00; +	public static final byte PROPERTY_CONTAINER_PIN_IDENTIFIER						= (byte)0x01; +	public static final byte PROPERTY_CONTAINER_TYPE								= (byte)0x80; +	 +	// Types +	// ============================================================================================= +	public static final short HIVECODE_TYPE_SMARTCARD_CONTENTMANAGER                = (short)0xB18C; +	public static final short HIVECODE_TYPE_SYSTEM_VOID								= (short)0xCE81; +	public static final short HIVECODE_TYPE_SYSTEM_INT32							= (short)0x61C0; +	public static final short HIVECODE_TYPE_SYSTEM_INT32_ARRAY						= (short)0x61C1; +	public static final short HIVECODE_TYPE_SYSTEM_BOOLEAN							= (short)0x2227; +	public static final short HIVECODE_TYPE_SYSTEM_BOOLEAN_ARRAY					= (short)0x2228; +	public static final short HIVECODE_TYPE_SYSTEM_SBYTE							= (short)0x767E; +	public static final short HIVECODE_TYPE_SYSTEM_SBYTE_ARRAY						= (short)0x767F; +	public static final short HIVECODE_TYPE_SYSTEM_UINT16 							= (short)0xD98B; +	public static final short HIVECODE_TYPE_SYSTEM_UINT16_ARRAY						= (short)0xD98C; +	public static final short HIVECODE_TYPE_SYSTEM_UINT32 							= (short)0x95E7; +	public static final short HIVECODE_TYPE_SYSTEM_UINT32_ARRAY						= (short)0x95E8; +	public static final short HIVECODE_TYPE_SYSTEM_BYTE 							= (short)0x45A2; +	public static final short HIVECODE_TYPE_SYSTEM_BYTE_ARRAY						= (short)0x45A3; +	public static final short HIVECODE_TYPE_SYSTEM_CHAR 							= (short)0x958E; +	public static final short HIVECODE_TYPE_SYSTEM_CHAR_ARRAY						= (short)0x958F; +	public static final short HIVECODE_TYPE_SYSTEM_INT16 							= (short)0xBC39; +	public static final short HIVECODE_TYPE_SYSTEM_INT16_ARRAY						= (short)0xBC3A; +	public static final short HIVECODE_TYPE_SYSTEM_STRING 							= (short)0x1127; +	public static final short HIVECODE_TYPE_SYSTEM_STRING_ARRAY						= (short)0x1128; +	public static final short HIVECODE_TYPE_SYSTEM_INT64 							= (short)0xDEFB; +	public static final short HIVECODE_TYPE_SYSTEM_INT64_ARRAY						= (short)0xDEFC; +	public static final short HIVECODE_TYPE_SYSTEM_UINT64 							= (short)0x71AF; +	public static final short HIVECODE_TYPE_SYSTEM_UINT64_ARRAY						= (short)0x71B0; +	public static final short HIVECODE_TYPE_SYSTEM_IO_MEMORYSTREAM					= (short)0xFED7; +	 +	 +	 +	public static final String HIVECODE_TYPE_SYSTEM_VOID_STRING								= "System.Void"; +	public static final String HIVECODE_TYPE_SYSTEM_INT32_STRING							= "System.Int32"; +	public static final String HIVECODE_TYPE_SYSTEM_INT32_ARRAY_STRING						= "System.Int32[]"; +	public static final String HIVECODE_TYPE_SYSTEM_BOOLEAN_STRING							= "System.Boolean"; +	public static final String HIVECODE_TYPE_SYSTEM_BOOLEAN_ARRAY_STRING					= "System.Boolean[]"; +	public static final String HIVECODE_TYPE_SYSTEM_SBYTE_STRING							= "System.SByte"; +	public static final String HIVECODE_TYPE_SYSTEM_SBYTE_ARRAY_STRING						= "System.SByte[]"; +	public static final String HIVECODE_TYPE_SYSTEM_UINT16_STRING 							= "System.UInt16"; +	public static final String HIVECODE_TYPE_SYSTEM_UINT16_ARRAY_STRING						= "System.UInt16[]"; +	public static final String HIVECODE_TYPE_SYSTEM_UINT32_STRING 							= "System.UInt32"; +	public static final String HIVECODE_TYPE_SYSTEM_UINT32_ARRAY_STRING						= "System.UInt32[]"; +	public static final String HIVECODE_TYPE_SYSTEM_BYTE_STRING 							= "System.Byte"; +	public static final String HIVECODE_TYPE_SYSTEM_BYTE_ARRAY_STRING						= "System.Byte[]"; +	public static final String HIVECODE_TYPE_SYSTEM_CHAR_STRING 							= "System.Char"; +	public static final String HIVECODE_TYPE_SYSTEM_CHAR_ARRAY_STRING						= "System.Char[]"; +	public static final String HIVECODE_TYPE_SYSTEM_INT16_STRING 							= "System.Int16"; +	public static final String HIVECODE_TYPE_SYSTEM_INT16_ARRAY_STRING						= "System.Int16[]"; +	public static final String HIVECODE_TYPE_SYSTEM_STRING_STRING 							= "System.String"; +	public static final String HIVECODE_TYPE_SYSTEM_STRING_ARRAY_STRING						= "System.String[]"; +	public static final String HIVECODE_TYPE_SYSTEM_INT64_STRING 							= "System.Int64"; +	public static final String HIVECODE_TYPE_SYSTEM_INT64_ARRAY_STRING						= "System.Int64[]"; +	public static final String HIVECODE_TYPE_SYSTEM_UINT64_STRING 							= "System.UInt64"; +	public static final String HIVECODE_TYPE_SYSTEM_UINT64_ARRAY_STRING						= "System.UInt64[]"; +	public static final String HIVECODE_TYPE_SYSTEM_IO_MEMORYSTREAM_STRING					= "System.IO.MemoryStream"; +	 +	 +	// Namespaces +	// ========================================================================================== +	public static final int HIVECODE_NAMESPACE_SYSTEM                               = 0x00D25D1C; +	public static final int HIVECODE_NAMESPACE_SYSTEM_IO                            = 0x00D5E6DB; +	public static final int HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_CHANNELS     = 0x0000886E; +	public static final int HIVECODE_NAMESPACE_NETCARD_FILESYSTEM                   = 0x00A1AC39; +	public static final int HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING              = 0x00EB3DD9; +	public static final int HIVECODE_NAMESPACE_SYSTEM_SECURITY_CRYPTOGRAPHY         = 0x00ACF53B; +	public static final int HIVECODE_NAMESPACE_SYSTEM_COLLECTIONS                   = 0x00C5A010; +	public static final int HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_CONTEXTS     = 0x001F4994; +	public static final int HIVECODE_NAMESPACE_SYSTEM_SECURITY                      = 0x00964145; +	public static final int HIVECODE_NAMESPACE_SYSTEM_REFLECTION                    = 0x0008750F; +	public static final int HIVECODE_NAMESPACE_SYSTEM_RUNTIME_SERIALIZATION         = 0x008D3B3D; +	public static final int HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_MESSAGING    = 0x00DEB940; +	public static final int HIVECODE_NAMESPACE_SYSTEM_DIAGNOSTICS                   = 0x0097995F; +	public static final int HIVECODE_NAMESPACE_SYSTEM_RUNTIME_COMPILERSERVICES      = 0x00F63E11; +	public static final int HIVECODE_NAMESPACE_SYSTEM_TEXT                          = 0x00702756; +	public static final int HIVECODE_NAMESPACE_SMARTCARD                            = 0x00F5EFBF; +	 +	public static final String HIVECODE_NAMESPACE_SYSTEM_STRING								= "System"; +	public static final String HIVECODE_NAMESPACE_SYSTEM_IO_STRING							= "System.IO"; +	public static final String HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_CHANNELS_STRING	= "System.Runtime.Remoting.Channels"; +	public static final String HIVECODE_NAMESPACE_NETCARD_FILESYSTEM_STRING					= "Netcard.Filesystem"; +	public static final String HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_STRING			= "System.Runtime.Remoting"; +	public static final String HIVECODE_NAMESPACE_SYSTEM_SECURITY_CRYPTOGRAPHY_STRING		= "System.Security.Cryptography"; +	public static final String HIVECODE_NAMESPACE_SYSTEM_COLLECTIONS_STRING					= "System.Collections"; +	public static final String HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_CONTEXTS_STRING	= "System.Runtime.Remoting.Contexts"; +	public static final String HIVECODE_NAMESPACE_SYSTEM_SECURITY_STRING					= "System.Security"; +	public static final String HIVECODE_NAMESPACE_SYSTEM_REFLECTION_STRING					= "System.Reflection"; +	public static final String HIVECODE_NAMESPACE_SYSTEM_RUNTIME_SERIALIZATION_STRING		= "System.Runtime.Serialization"; +	public static final String HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_MESSAGING_STRING	= "System.Runtime.Remoting.Messaging"; +	public static final String HIVECODE_NAMESPACE_SYSTEM_DIAGNOSTICS_STRING					= "System.Diagnostics"; +	public static final String HIVECODE_NAMESPACE_SYSTEM_RUNTIME_COMPILERSERVICES_STRING	= "System.Runtime.Compilerservices"; +	public static final String HIVECODE_NAMESPACE_SYSTEM_TEXT_STRING						= "System.Text"; +	public static final String HIVECODE_NAMESPACE_SMARTCARD_STRING							= "Smartcard"; +	 +	public static final int HIVECODE_NAMESPACE_GEMALTO								= 0x00C04B4E; +	 +	// Exceptions +	// ============================================================================================ +	public static final short HIVECODE_EXCEPTION_SYSTEM_EXCEPTION										= (short) 0xD4B0; +	public static final short HIVECODE_EXCEPTION_SYSTEM_SYSTEMEXCEPTION									= (short) 0x28AC; +	public static final short HIVECODE_EXCEPTION_SYSTEM_OUTOFMEMORYEXCEPTION							= (short) 0xE14E; +	public static final short HIVECODE_EXCEPTION_SYSTEM_ARGUMENTEXCEPTION								= (short) 0xAB8C; +	public static final short HIVECODE_EXCEPTION_SYSTEM_ARGUMENTNULLEXCEPTION							= (short) 0x2138; +	public static final short HIVECODE_EXCEPTION_SYSTEM_NULLREFERENCEEXCEPTION							= (short) 0xC5B8; +	public static final short HIVECODE_EXCEPTION_SYSTEM_ARGUMENTOUTOFRANGEEXCEPTION						= (short) 0x6B11; +	public static final short HIVECODE_EXCEPTION_SYSTEM_NOTSUPPORTEDEXCEPTION							= (short) 0xAA74; +	public static final short HIVECODE_EXCEPTION_SYSTEM_INVALIDCASTEXCEPTION							= (short) 0xD24F; +	public static final short HIVECODE_EXCEPTION_SYSTEM_INVALIDOPERATIONEXCEPTION						= (short) 0xFAB4; +	public static final short HIVECODE_EXCEPTION_SYSTEM_NOTIMPLEMENTEDEXCEPTION							= (short) 0x3CE5; +	public static final short HIVECODE_EXCEPTION_SYSTEM_OBJECTDISPOSEDEXCEPTION							= (short) 0x0FAC; +	public static final short HIVECODE_EXCEPTION_SYSTEM_UNAUTHORIZEDACCESSEXCEPTION						= (short) 0x4697; +	public static final short HIVECODE_EXCEPTION_SYSTEM_INDEXOUTOFRANGEEXCEPTION						= (short) 0xBF1D; +	public static final short HIVECODE_EXCEPTION_SYSTEM_FORMATEXCEPTION									= (short) 0xF3BF; +	public static final short HIVECODE_EXCEPTION_SYSTEM_ARITHMETICEXCEPTION								= (short) 0x6683; +	public static final short HIVECODE_EXCEPTION_SYSTEM_OVERFLOWEXCEPTION								= (short) 0x20A0; +	public static final short HIVECODE_EXCEPTION_SYSTEM_BADIMAGEFORMATEXCEPTION							= (short) 0x530A; +	public static final short HIVECODE_EXCEPTION_SYSTEM_APPLICATIONEXCEPTION							= (short) 0xB1EA; +	public static final short HIVECODE_EXCEPTION_SYSTEM_ARRAYTYPEMISMATCHEXCEPTION						= (short) 0x3F88; +	public static final short HIVECODE_EXCEPTION_SYSTEM_DIVIDEBYZEROEXCEPTION							= (short) 0xDFCF; +	public static final short HIVECODE_EXCEPTION_SYSTEM_MEMBERACCESSEXCEPTION							= (short) 0xF5F3; +	public static final short HIVECODE_EXCEPTION_SYSTEM_MISSINGMEMBEREXCEPTION							= (short) 0x20BB; +	public static final short HIVECODE_EXCEPTION_SYSTEM_MISSINGFIELDEXCEPTION							= (short) 0x7366; +	public static final short HIVECODE_EXCEPTION_SYSTEM_MISSINGMEHTODEXCEPTION							= (short) 0x905B; +	public static final short HIVECODE_EXCEPTION_SYSTEM_RANKEXCEPTION									= (short) 0xB2AE; +	public static final short HIVECODE_EXCEPTION_SYSTEM_STACKOVERFLOWEXCEPTION							= (short) 0x0844; +	public static final short HIVECODE_EXCEPTION_SYSTEM_TYPELOADEXCEPTION								= (short) 0x048E; +	public static final short HIVECODE_EXCEPTION_SYSTEM_IO_IOEXCEPTION									= (short) 0x3BBE; +	public static final short HIVECODE_EXCEPTION_SYSTEM_IO_DIRECTORYNOTFOUNDEXCEPTION					= (short) 0x975A; +	public static final short HIVECODE_EXCEPTION_SYSTEM_IO_FILENOTFOUNDEXCEPTION						= (short) 0x07EB; +	public static final short HIVECODE_EXCEPTION_SYSTEM_RUNTIME_REMOTING_REMOTINGEXCEPTION				= (short) 0xD52A; +	public static final short HIVECODE_EXCEPTION_SYSTEM_SECURITY_CRYPTOGRAPHY_CRYPTOGRAPHICEXCEPTION	= (short) 0x8FEB; + +	 +	public static final String HIVECODE_EXCEPTION_SYSTEM_EXCEPTION_STRING										= "System.Exception"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_SYSTEMEXCEPTION_STRING									= "System.SystemException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_OUTOFMEMORYEXCEPTION_STRING							= "System.OutOfMemoryException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_ARGUMENTEXCEPTION_STRING								= "System.ArgumentException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_ARGUMENTNULLEXCEPTION_STRING							= "System.ArgumentNullException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_NULLREFERENCEEXCEPTION_STRING							= "System.NullReferenceException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_ARGUMENTOUTOFRANGEEXCEPTION_STRING						= "System.ArgumentOutOfRangeException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_NOTSUPPORTEDEXCEPTION_STRING							= "System.NotSupportedException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_INVALIDCASTEXCEPTION_STRING							= "System.InvalidCastException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_INVALIDOPERATIONEXCEPTION_STRING						= "System.InvalidOperationException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_NOTIMPLEMENTEDEXCEPTION_STRING							= "System.NotImplementedException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_OBJECTDISPOSEDEXCEPTION_STRING							= "System.ObjectDisposed Exception"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_UNAUTHORIZEDACCESSEXCEPTION_STRING						= "System.UnauthorizedAccessException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_INDEXOUTOFRANGEEXCEPTION_STRING						= "System.IndexOutOfRangeException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_FORMATEXCEPTION_STRING									= "System.FormatException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_ARITHMETICEXCEPTION_STRING								= "System.ArithmeticException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_OVERFLOWEXCEPTION_STRING								= "System.OverflowException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_BADIMAGEFORMATEXCEPTION_STRING							= "System.BadImageFormatException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_APPLICATIONEXCEPTION_STRING							= "System.ApplicationException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_ARRAYTYPEMISMATCHEXCEPTION_STRING						= "System.ArrayTypeMismatchException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_DIVIDEBYZEROEXCEPTION_STRING							= "System.DivideByZeroException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_MEMBERACCESSEXCEPTION_STRING							= "System.MemberAccessException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_MISSINGMEMBEREXCEPTION_STRING							= "System.MissingMemberException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_MISSINGFIELDEXCEPTION_STRING							= "System.MissingFieldException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_MISSINGMEHTODEXCEPTION_STRING							= "System.MissingMethodException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_RANKEXCEPTION_STRING									= "System.RankException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_STACKOVERFLOWEXCEPTION_STRING							= "System.StackOverflowException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_TYPELOADEXCEPTION_STRING								= "System.TypeLoadException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_IO_IOEXCEPTION_STRING									= "System.IO.IOException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_IO_DIRECTORYNOTFOUNDEXCEPTION_STRING					= "System.IO.DirectoryNotFoundException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_IO_FILENOTFOUNDEXCEPTION_STRING						= "System.IO.FileNotFoundException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_RUNTIME_REMOTING_REMOTINGEXCEPTION_STRING				= "System.Runtime.Remoting.RemotingException"; +	public static final String HIVECODE_EXCEPTION_SYSTEM_SECURITY_CRYPTOGRAPHY_CRYPTOGRAPHICEXCEPTION_STRING	= "System.Security.Cryptography.CryptographicException"; + +	 +} diff --git a/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMDecoder.java b/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMDecoder.java new file mode 100644 index 00000000..5eddbe25 --- /dev/null +++ b/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMDecoder.java @@ -0,0 +1,259 @@ +package at.gv.egiz.smcc.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; + +public class MSCMDecoder implements MSCMConstants { +	 +	private static Map<Integer, String> namespaces; +	 +	private static Map<Short, String> types; +	 +	private static Map<Short, String> exceptions; +	 +	static { +		namespaces = new HashMap<Integer, String>(); +		namespaces.put(HIVECODE_NAMESPACE_SYSTEM, HIVECODE_NAMESPACE_SYSTEM_STRING); +		namespaces.put(HIVECODE_NAMESPACE_SYSTEM_IO, HIVECODE_NAMESPACE_SYSTEM_IO_STRING); +		namespaces.put(HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_CHANNELS, HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_CHANNELS_STRING); +		namespaces.put(HIVECODE_NAMESPACE_NETCARD_FILESYSTEM, HIVECODE_NAMESPACE_NETCARD_FILESYSTEM_STRING); +		namespaces.put(HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING, HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_STRING); +		namespaces.put(HIVECODE_NAMESPACE_SYSTEM_SECURITY_CRYPTOGRAPHY, HIVECODE_NAMESPACE_SYSTEM_SECURITY_CRYPTOGRAPHY_STRING); +		namespaces.put(HIVECODE_NAMESPACE_SYSTEM_COLLECTIONS, HIVECODE_NAMESPACE_SYSTEM_COLLECTIONS_STRING); +		namespaces.put(HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_CONTEXTS, HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_CONTEXTS_STRING); +		namespaces.put(HIVECODE_NAMESPACE_SYSTEM_SECURITY, HIVECODE_NAMESPACE_SYSTEM_SECURITY_STRING); +		namespaces.put(HIVECODE_NAMESPACE_SYSTEM_REFLECTION, HIVECODE_NAMESPACE_SYSTEM_REFLECTION_STRING); +		namespaces.put(HIVECODE_NAMESPACE_SYSTEM_RUNTIME_SERIALIZATION, HIVECODE_NAMESPACE_SYSTEM_RUNTIME_SERIALIZATION_STRING); +		namespaces.put(HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_MESSAGING, HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_MESSAGING_STRING); +		namespaces.put(HIVECODE_NAMESPACE_SYSTEM_DIAGNOSTICS, HIVECODE_NAMESPACE_SYSTEM_DIAGNOSTICS_STRING); +		namespaces.put(HIVECODE_NAMESPACE_SYSTEM_RUNTIME_COMPILERSERVICES, HIVECODE_NAMESPACE_SYSTEM_RUNTIME_COMPILERSERVICES_STRING); +		namespaces.put(HIVECODE_NAMESPACE_SYSTEM_TEXT, HIVECODE_NAMESPACE_SYSTEM_TEXT_STRING); +		namespaces.put(HIVECODE_NAMESPACE_SMARTCARD, HIVECODE_NAMESPACE_SMARTCARD_STRING); +		 +		 +		types = new HashMap<Short, String>(); +		 +		types.put(HIVECODE_TYPE_SYSTEM_VOID, HIVECODE_TYPE_SYSTEM_VOID_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_INT32, HIVECODE_TYPE_SYSTEM_INT32_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_INT32_ARRAY, HIVECODE_TYPE_SYSTEM_INT32_ARRAY_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_BOOLEAN, HIVECODE_TYPE_SYSTEM_BOOLEAN_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_BOOLEAN_ARRAY, HIVECODE_TYPE_SYSTEM_BOOLEAN_ARRAY_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_SBYTE, HIVECODE_TYPE_SYSTEM_SBYTE_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_SBYTE_ARRAY, HIVECODE_TYPE_SYSTEM_SBYTE_ARRAY_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_UINT16, HIVECODE_TYPE_SYSTEM_UINT16_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_UINT16_ARRAY, HIVECODE_TYPE_SYSTEM_UINT16_ARRAY_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_UINT32, HIVECODE_TYPE_SYSTEM_UINT32_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_UINT32_ARRAY, HIVECODE_TYPE_SYSTEM_UINT32_ARRAY_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_BYTE, HIVECODE_TYPE_SYSTEM_BYTE_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_BYTE_ARRAY, HIVECODE_TYPE_SYSTEM_BYTE_ARRAY_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_CHAR, HIVECODE_TYPE_SYSTEM_CHAR_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_CHAR_ARRAY, HIVECODE_TYPE_SYSTEM_CHAR_ARRAY_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_INT16, HIVECODE_TYPE_SYSTEM_INT16_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_INT16_ARRAY, HIVECODE_TYPE_SYSTEM_INT16_ARRAY_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_STRING, HIVECODE_TYPE_SYSTEM_STRING_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_STRING_ARRAY, HIVECODE_TYPE_SYSTEM_STRING_ARRAY_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_INT64, HIVECODE_TYPE_SYSTEM_INT64_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_INT64_ARRAY, HIVECODE_TYPE_SYSTEM_INT64_ARRAY_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_UINT64, HIVECODE_TYPE_SYSTEM_UINT64_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_UINT64_ARRAY, HIVECODE_TYPE_SYSTEM_UINT64_ARRAY_STRING); +		types.put(HIVECODE_TYPE_SYSTEM_IO_MEMORYSTREAM, HIVECODE_TYPE_SYSTEM_IO_MEMORYSTREAM_STRING); +		 +		exceptions = new HashMap<Short, String>(); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_EXCEPTION, HIVECODE_EXCEPTION_SYSTEM_EXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_SYSTEMEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_SYSTEMEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_OUTOFMEMORYEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_OUTOFMEMORYEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_ARGUMENTEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_ARGUMENTEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_ARGUMENTNULLEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_ARGUMENTNULLEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_NULLREFERENCEEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_NULLREFERENCEEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_ARGUMENTOUTOFRANGEEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_ARGUMENTOUTOFRANGEEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_NOTSUPPORTEDEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_NOTSUPPORTEDEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_INVALIDCASTEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_INVALIDCASTEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_INVALIDOPERATIONEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_INVALIDOPERATIONEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_NOTIMPLEMENTEDEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_NOTIMPLEMENTEDEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_OBJECTDISPOSEDEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_OBJECTDISPOSEDEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_UNAUTHORIZEDACCESSEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_UNAUTHORIZEDACCESSEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_INDEXOUTOFRANGEEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_INDEXOUTOFRANGEEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_FORMATEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_FORMATEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_ARITHMETICEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_ARITHMETICEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_OVERFLOWEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_OVERFLOWEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_BADIMAGEFORMATEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_BADIMAGEFORMATEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_APPLICATIONEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_APPLICATIONEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_ARRAYTYPEMISMATCHEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_ARRAYTYPEMISMATCHEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_DIVIDEBYZEROEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_DIVIDEBYZEROEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_MEMBERACCESSEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_MEMBERACCESSEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_MISSINGMEMBEREXCEPTION, HIVECODE_EXCEPTION_SYSTEM_MISSINGMEMBEREXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_MISSINGFIELDEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_MISSINGFIELDEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_MISSINGMEHTODEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_MISSINGMEHTODEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_RANKEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_RANKEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_STACKOVERFLOWEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_STACKOVERFLOWEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_TYPELOADEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_TYPELOADEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_IO_IOEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_IO_IOEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_IO_DIRECTORYNOTFOUNDEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_IO_DIRECTORYNOTFOUNDEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_IO_FILENOTFOUNDEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_IO_FILENOTFOUNDEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_RUNTIME_REMOTING_REMOTINGEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_RUNTIME_REMOTING_REMOTINGEXCEPTION_STRING); +		exceptions.put(HIVECODE_EXCEPTION_SYSTEM_SECURITY_CRYPTOGRAPHY_CRYPTOGRAPHICEXCEPTION, HIVECODE_EXCEPTION_SYSTEM_SECURITY_CRYPTOGRAPHY_CRYPTOGRAPHICEXCEPTION_STRING); + +	} +	 +	public static void checkExceptionInResponse(byte[] data, int offset) throws MSCMException { +		short value; +		String optional = null; +		if(data[offset] == (byte)0xFF) { +			value = MSCMService.bytesToShort(data, offset+5); +			if(data.length > offset + 7) { +				try { +					optional = decodeString(data, offset + 7); +				} catch (UnsupportedEncodingException e) { +					e.printStackTrace(); +				} +			} +		} else { +			value = MSCMService.bytesToShort(data, offset+4); +			if(data.length > offset + 6) { +				try { +					optional = decodeString(data, offset + 6); +				} catch (UnsupportedEncodingException e) { +					e.printStackTrace(); +				} +			} +		} +		String message = exceptions.get(value); +		if(message != null) { +			 +			if(optional == null) { +				throw new MSCMException(value, message); +			} else { +				throw new MSCMException(value, message, optional); +			} +		} +		 +	} +	 +	public static String namespaceHiveToString(byte[] hive, int offset) { +		int value = MSCMService.bytesToInt(hive, offset); +		String str = namespaces.get(value); +		if(str == null) { +			str =  MSCMService.bytArrayToHex(hive); +		} +		return str; +	} +	 +	public static String typeHiveToString(byte[] hive, int offset) { +		short value = MSCMService.bytesToShort(hive, offset); +		String str = types.get(value); +		if(str == null) { +			str =  MSCMService.bytArrayToHex(hive); +		} +		return str; +	} +	 +	public static boolean decodeBoolean(byte data) { +		return (data == (byte) 0x01); +	} +	 +	public static byte[] decodeByteArray(byte[] data, int offset) { +		int length = MSCMService.bytesToInt(data, offset); +		if(length > data.length - offset - 4) { +			// encoding error +			return null; +		} +		byte[] result = new byte[length]; +		for(int i = 0; i < length; i++) { +			result[i] = data[offset + 4 + i]; +		} +		return result; +	} +	 +	public static short[] decodeShortArray(byte[] data, int offset) { +		int length = MSCMService.bytesToInt(data, offset); +		if(length  * 2 > data.length - offset - 4) { +			// encoding error +			return null; +		} +		short[] result = new short[length]; +		for(int i = 0; i < length; i++) { +			result[i] = MSCMService.bytesToShort(data, offset + 4 + i * 2); +		} +		return result; +	} +	 +	public static int[] decodeIntArray(byte[] data, int offset) { +		int length = MSCMService.bytesToInt(data, offset); +		if(length  * 4 > data.length - offset - 4) { +			// encoding error +			return null; +		} +		int[] result = new int[length]; +		for(int i = 0; i < length; i++) { +			result[i] = MSCMService.bytesToInt(data, offset + 4 + i * 4); +		} +		return result; +	} +	 +	public static String[] decodeStringArray(byte[] data, int offset) throws UnsupportedEncodingException { +		int length = MSCMService.bytesToInt(data, offset); +		String[] result = new String[length]; +		int curoffset = 4; +		for(int i = 0; i < length; i++) { +			short strlength = MSCMService.bytesToShort(data, offset + curoffset); +			result[i] = decodeString(data, offset + curoffset); +			curoffset += strlength + 2; +		} +		return result; +	} +	 +	 +	public static String decodeString(byte[] data, int offset) throws UnsupportedEncodingException { +		short length = MSCMService.bytesToShort(data, offset); +		if(length == 0xFFFF) { +			return ""; +		} +		 +		byte[] utf8Data = new byte[length*2]; +		for(int i = 0; i < length; i++) { +			utf8Data[i] = data[offset + 2 + i]; +		} +		 +		String str = new String(utf8Data, "UTF-8"); +		return str; +	} +	 +	 +	public static byte[] encodeString(String str) throws IOException { +		if(str == null) { +			return new byte[] { (byte) 0xFF, (byte) 0xFF }; +		} +		byte[] utf8data = str.getBytes("UTF-8"); +		short strinlen = (short)utf8data.length; +		byte[] lendata = MSCMService.shortToBytes(strinlen); +		 +		ByteArrayOutputStream out = new ByteArrayOutputStream(strinlen + 2); +		out.write(lendata); +		out.write(utf8data); +		out.close(); +		return out.toByteArray(); +	} +	 +	public static byte[] encodeByteArray(byte[] data) throws IOException { +		int strinlen = (int)data.length; +		byte[] lendata = MSCMService.intToBytes(strinlen); +		 +		ByteArrayOutputStream out = new ByteArrayOutputStream(strinlen + 4); +		out.write(lendata); +		out.write(data); +		out.close(); +		return out.toByteArray(); +	} +	 +	public static byte[] concatByteArrays(byte[] a, byte[] b) throws IOException { +		ByteArrayOutputStream out = new ByteArrayOutputStream(a.length + b.length); +		out.write(a); +		out.write(b); +		out.close(); +		return out.toByteArray(); +	} +} + 
\ No newline at end of file diff --git a/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMException.java b/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMException.java new file mode 100644 index 00000000..0466d30c --- /dev/null +++ b/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMException.java @@ -0,0 +1,23 @@ +package at.gv.egiz.smcc.util; + +public class MSCMException extends Exception { +	private short hive; +	 +	public MSCMException(short hive, String netException, String optional) { +		super(netException + " [ " + optional + " ]"); +		this.setHive(hive); +	} +	 +	public MSCMException(short hive, String netException) { +		super(netException); +		this.setHive(hive); +	} + +	public short getHive() { +		return hive; +	} + +	public void setHive(short hive) { +		this.hive = hive; +	} +} diff --git a/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMService.java b/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMService.java new file mode 100644 index 00000000..0c705447 --- /dev/null +++ b/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMService.java @@ -0,0 +1,273 @@ +package at.gv.egiz.smcc.util; + +import iaik.me.security.Cipher; +import iaik.me.security.CryptoBag; +import iaik.me.security.CryptoException; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import javax.smartcardio.CardChannel; +import javax.smartcardio.CardException; + +public class MSCMService implements MSCMConstants { + +	MSCMTransfer transfer; + +	public MSCMService(CardChannel channel) { +		transfer = new MSCMTransfer(channel); +	} + +	public String[] getFiles(String path) throws IOException, CardException, MSCMException { + +		byte[] cmd = buildAPDU(DEFAULT_SERVICE_PORT, +				HIVECODE_NAMESPACE_GEMALTO, HIVECODE_TYPE_DEFAULT, +				HIVECODE_METHOD_GETFILES, URI, MSCMDecoder.encodeString(path)); + +		return MSCMDecoder.decodeStringArray( +				transfer.transfer(cmd, HIVECODE_TYPE_SYSTEM_STRING_ARRAY), 0); + +	} +	 +	public byte[] getFileProperties(String path) throws IOException, CardException, MSCMException { +		byte[] cmd = buildAPDU(DEFAULT_SERVICE_PORT, +				HIVECODE_NAMESPACE_GEMALTO, HIVECODE_TYPE_DEFAULT, +				HIVECODE_METHOD_GETFILEPROPERTIES, URI,  +				 MSCMDecoder.encodeString(path)); +		 +		return MSCMDecoder.decodeByteArray( +				transfer.transfer(cmd, HIVECODE_TYPE_SYSTEM_BYTE_ARRAY), 0); +	} +	 +	public void verifyPin(byte role, byte[] pin) throws IOException, CardException, MSCMException { +		byte[] cmd = buildAPDU(DEFAULT_SERVICE_PORT, +				HIVECODE_NAMESPACE_GEMALTO, HIVECODE_TYPE_DEFAULT, +				HIVECODE_METHOD_VERIFYPIN, URI,  +				MSCMDecoder.concatByteArrays(new byte[] { role },  +						MSCMDecoder.encodeByteArray(pin))); +		 +		transfer.transfer(cmd, HIVECODE_TYPE_SYSTEM_VOID); +	} +	 +	public void changePIN(byte role, byte[] oldpin , byte[] newpin, int maxtries) throws IOException, CardException, MSCMException { +		byte[] p = MSCMDecoder.concatByteArrays(new byte[] { (byte)0, role },  +				MSCMDecoder.encodeByteArray(oldpin)); +		byte[] pr = MSCMDecoder.concatByteArrays(p, MSCMDecoder.encodeByteArray(newpin)); +		byte[] pre = MSCMDecoder.concatByteArrays(pr, intToBytes(maxtries)); +		 +		byte[] cmd = buildAPDU(DEFAULT_SERVICE_PORT, +				HIVECODE_NAMESPACE_GEMALTO, HIVECODE_TYPE_DEFAULT, +				HIVECODE_METHOD_CHANGEREFDATA, URI,  +				pre); +		 +		transfer.transfer(cmd, HIVECODE_TYPE_SYSTEM_VOID); +	} +	 +	public void unblockPIN(byte role, byte[] oldpin , byte[] newpin, int maxtries) throws IOException, CardException, MSCMException { +		byte[] p = MSCMDecoder.concatByteArrays(new byte[] { (byte)1, role },  +				MSCMDecoder.encodeByteArray(oldpin)); +		byte[] pr = MSCMDecoder.concatByteArrays(p, MSCMDecoder.encodeByteArray(newpin)); +		byte[] pre = MSCMDecoder.concatByteArrays(pr, intToBytes(maxtries)); +		 +		byte[] cmd = buildAPDU(DEFAULT_SERVICE_PORT, +				HIVECODE_NAMESPACE_GEMALTO, HIVECODE_TYPE_DEFAULT, +				HIVECODE_METHOD_CHANGEREFDATA, URI,  +				pre); +		 +		transfer.transfer(cmd, HIVECODE_TYPE_SYSTEM_VOID); +	} +	 +	public int[] queryFreeSpace() throws IOException, CardException, MSCMException { +		byte[] cmd = buildAPDU(DEFAULT_SERVICE_PORT, +				HIVECODE_NAMESPACE_GEMALTO, HIVECODE_TYPE_DEFAULT, +				HIVECODE_METHOD_QUERYFREESPACE, URI,  +				 null); +		 +		return MSCMDecoder.decodeIntArray( +				transfer.transfer(cmd, HIVECODE_TYPE_SYSTEM_INT32_ARRAY), 0); +	} +	 +	public void forceGC() throws IOException, CardException, MSCMException { +		byte[] cmd = buildAPDU(DEFAULT_SERVICE_PORT, +				HIVECODE_NAMESPACE_GEMALTO, HIVECODE_TYPE_DEFAULT, +				HIVECODE_METHOD_FORCEGC, URI,  +				 null); +		transfer.transfer(cmd, HIVECODE_TYPE_SYSTEM_VOID); +	} +	 +	public byte[] readFile(String path) throws IOException, CardException, MSCMException { +		byte[] cmd = buildAPDU(DEFAULT_SERVICE_PORT, +				HIVECODE_NAMESPACE_GEMALTO, HIVECODE_TYPE_DEFAULT, +				HIVECODE_METHOD_READFILE, URI,  +				 MSCMDecoder.concatByteArrays(MSCMDecoder.encodeString(path),  +						 intToBytes(0) )); +		 +		return MSCMDecoder.decodeByteArray( +				transfer.transfer(cmd, HIVECODE_TYPE_SYSTEM_BYTE_ARRAY), 0); +	} + +	public byte[] privateKeyDecrypt(byte ctrIdx, byte keyType, byte[] data)  +			throws IOException, CardException, MSCMException { +		byte[] cmd = buildAPDU(DEFAULT_SERVICE_PORT, +				HIVECODE_NAMESPACE_GEMALTO, HIVECODE_TYPE_DEFAULT, +				HIVECODE_METHOD_PRIVATEKEYDECRYPT, URI,  +				 MSCMDecoder.concatByteArrays(new byte[] { ctrIdx, +				keyType }, MSCMDecoder.encodeByteArray(data))); +		 +		return MSCMDecoder.decodeByteArray( +				transfer.transfer(cmd, HIVECODE_TYPE_SYSTEM_BYTE_ARRAY), 0); +	} +	 +	public int getTriesRemaining(byte role) throws IOException, CardException, MSCMException { +		byte[] cmd = buildAPDU(DEFAULT_SERVICE_PORT, +				HIVECODE_NAMESPACE_GEMALTO, HIVECODE_TYPE_DEFAULT, +				HIVECODE_METHOD_GETTRIESREMAINING, URI, new byte[] { role }); + +		return bytesToInt(transfer.transfer(cmd, HIVECODE_TYPE_SYSTEM_INT32), 0); +	} + +	public String getVersion() throws IOException, CardException, MSCMException { + +		byte[] cmd = buildAPDU(DEFAULT_SERVICE_PORT, +				HIVECODE_NAMESPACE_GEMALTO, HIVECODE_TYPE_DEFAULT, +				HIVECODE_METHOD_GETVERSION, URI, null); + +		return MSCMDecoder.decodeString( +				transfer.transfer(cmd, HIVECODE_TYPE_SYSTEM_STRING), 0); + +	} + +	public byte[] getContainerProperty(byte ctrIndex, byte property, byte flags) +			throws IOException, CardException, MSCMException { +		byte[] cmd = buildAPDU(DEFAULT_SERVICE_PORT, +				HIVECODE_NAMESPACE_GEMALTO, HIVECODE_TYPE_DEFAULT, +				HIVECODE_METHOD_GETCONTAINERPROPERTY, URI, new byte[] { +						ctrIndex, property, flags }); + +		return transfer.transfer(cmd, HIVECODE_TYPE_SYSTEM_BYTE_ARRAY); +	} + +	public byte[] getCardProperty(byte property, byte flags) +			throws IOException, CardException, MSCMException { + +		byte[] cmd = buildAPDU(DEFAULT_SERVICE_PORT, +				HIVECODE_NAMESPACE_GEMALTO, HIVECODE_TYPE_DEFAULT, +				HIVECODE_METHOD_GETCARDPROPERTY, URI, new byte[] { property, +						flags }); + +		return transfer.transfer(cmd, HIVECODE_TYPE_SYSTEM_BYTE_ARRAY); +	} + +	public static String bytArrayToHex(byte[] a) { +		StringBuilder sb = new StringBuilder(); +		for (byte b : a) +			sb.append(String.format("%02X ", b & 0xff)); +		return sb.toString(); +	} + +	public static String bytArrayToHex(byte[] a, int offset) { +		StringBuilder sb = new StringBuilder(); +		for (int i = offset; i < a.length; i++) { +			byte b = a[i]; +			sb.append(String.format("%02X ", b & 0xff)); +		} +		return sb.toString(); +	} + +	public static byte[] shortToBytes(short x) { +		byte[] ret = new byte[2]; +		ret[1] = (byte) (x & 0xff); +		ret[0] = (byte) ((x >> 8) & 0xff); +		return ret; +	} + +	public static byte[] intToBytes(int x) { +		byte[] ret = new byte[4]; +		ret[3] = (byte) (x & 0xff); +		ret[2] = (byte) ((x >> 8) & 0xff); +		ret[1] = (byte) ((x >> 16) & 0xff); +		ret[0] = (byte) ((x >> 24) & 0xff); +		return ret; +	} + +	public static int bytesToInt(byte[] by, int offset) { +		int value = 0; +		for (int i = 0; i < 4 && i + offset < by.length; i++) { +			value <<= 8; +			value |= (int) by[offset + i] & 0xFF; +		} +		return value; +	} + +	public static short bytesToShort(byte[] by, int offset) { +		short value = 0; +		for (int i = 0; i < 2 && i + offset < by.length; i++) { +			value <<= 8; +			value |= (short) by[i + offset] & 0xFF; +		} +		return value; +	} + +	public byte[] buildAPDU(short servicePort, int hiveServiceNamespace, +			short hiveServiceType, short hiveMethod, String serviceName, +			byte[] arguments) throws IOException { +		byte[] c1 = new byte[1]; +		byte[] c2 = new byte[1]; +		byte[] encodedServiceName = serviceName.getBytes("UTF-8"); +		c1[0] = (byte) 0xD8; +		c2[0] = (byte) 0x6F; + +		ByteArrayOutputStream payloadbuffer = new ByteArrayOutputStream(); + +		payloadbuffer.write(c1); +		payloadbuffer.write(shortToBytes(servicePort)); +		payloadbuffer.write(c2); +		payloadbuffer.write(intToBytes(hiveServiceNamespace)); +		payloadbuffer.write(shortToBytes(hiveServiceType)); +		payloadbuffer.write(shortToBytes(hiveMethod)); +		payloadbuffer.write(shortToBytes((short) encodedServiceName.length)); +		payloadbuffer.write(encodedServiceName); +		if (arguments != null) { +			payloadbuffer.write(arguments); +		} + +		return payloadbuffer.toByteArray(); +	} +	 + +	public byte[] cryptoResponse(byte[] challenge, byte[] key) { +		try { +			Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding"); +	        cipher.init(Cipher.ENCRYPT_MODE, CryptoBag.makeSecretKey(key)); +			 +			/*System.out.println("Crypto IV: " +					+ MSCMService.bytArrayToHex(cipher.getIV().getEncoded()));*/ +			byte[] result = cipher.doFinal(challenge); +			System.out.println("Crypto result: " + MSCMService.bytArrayToHex(result)); +			return result; +		} catch (CryptoException e) { +			System.out.println("Failed to get crypto stuff" + e.getMessage()); +			return null; +		} +	} +	 +	public void doExternalAuthentication(byte[] response) +			throws IOException, CardException, MSCMException { +		byte[] cmd = buildAPDU(DEFAULT_SERVICE_PORT, +				HIVECODE_NAMESPACE_GEMALTO, HIVECODE_TYPE_DEFAULT, +				HIVECODE_METHOD_EXTAUTH, URI,  +				MSCMDecoder.encodeByteArray(response)); +		 +		transfer.transfer(cmd, HIVECODE_TYPE_SYSTEM_VOID); +	} +	 +	public byte[] getChallenge() throws IOException, CardException, MSCMException { +		byte[] cmd = buildAPDU(DEFAULT_SERVICE_PORT, +				HIVECODE_NAMESPACE_GEMALTO, HIVECODE_TYPE_DEFAULT, +				HIVECODE_METHOD_GETCHALLENGE, URI,  +				 null); +		 +		return MSCMDecoder.decodeByteArray( +				transfer.transfer(cmd, HIVECODE_TYPE_SYSTEM_BYTE_ARRAY), 0); +	} +} diff --git a/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMTransfer.java b/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMTransfer.java new file mode 100644 index 00000000..ea4121a5 --- /dev/null +++ b/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMTransfer.java @@ -0,0 +1,146 @@ +package at.gv.egiz.smcc.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import javax.smartcardio.CardChannel; +import javax.smartcardio.CardException; +import javax.smartcardio.CommandAPDU; +import javax.smartcardio.ResponseAPDU; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.smcc.GemaltoNetV2_0Card; + +import java.nio.ByteBuffer; + +public class MSCMTransfer implements MSCMConstants { + +	private final Logger log = LoggerFactory +			.getLogger(MSCMTransfer.class); +	 +	private CardChannel channel; +	 +	public MSCMTransfer(CardChannel channel) { +		this.channel = channel; +	} +	 +	public byte[] transfer(byte[] payload, short expectedType) throws IOException, CardException, MSCMException { +		byte[] header = new byte[] { (byte) 0x80, (byte) 0xC2, (byte) 0x00, +				(byte) 0x00 }; +		byte[] cmd = null; +		byte[] len = new byte[1]; +		byte[] con = new byte[] { (byte) 0xD8, (byte) 0xFF, (byte) 0xFF }; +		ByteArrayOutputStream cmdbuffer = new ByteArrayOutputStream(); +		ResponseAPDU response = null; +		if(payload.length <= 0xFF) { +			cmdbuffer.write(header); +			len[0] = (byte) payload.length; +			cmdbuffer.write(len); +			cmdbuffer.write(payload); +			// Transfer cmdbuffer +			cmd = cmdbuffer.toByteArray(); +			String str = MSCMService.bytArrayToHex(cmd); +			log.info("Sending: >>> " + str); +			//ByteBuffer bb = ByteBuffer.wrap(cmd); +			//ByteBuffer resp = ByteBuffer.allocate(18000); +			//response = channel.transmit(bb, resp); +			//int resps = channel.transmit(bb, resp); +			//ByteArrayOutputStream out = new ByteArrayOutputStream(); +			//out.write(resp.array(), 0, resps); +			//out.close(); +			//response = new ResponseAPDU(out.toByteArray()); +			response = channel.transmit(new CommandAPDU(cmd)); +		} else { // (> 0xFF) +			// divide payload +			int length = payload.length; +			int offset = 0; +			int curlen = 0; +			boolean first = true; +			while(length > 0) { +				curlen = (length > 0xF4) ? 0xF4 : length; +				ByteArrayOutputStream dpay = new ByteArrayOutputStream(); +				dpay.write(con); +				if(first) { +					dpay.write(MSCMService.intToBytes(payload.length-18)); +					dpay.write(MSCMService.intToBytes(curlen-18)); +				} else { +					dpay.write(MSCMService.intToBytes(offset-18)); +					dpay.write(MSCMService.intToBytes(curlen)); +				} +				first = false; +				 +				dpay.write(payload, offset, curlen); +				dpay.close(); +				byte[] ppay = dpay.toByteArray(); +				 +				cmdbuffer.write(header); +				len[0] = (byte)ppay.length; +				cmdbuffer.write(len); +				cmdbuffer.write(ppay); +				 +				length -= curlen; +				offset += curlen; +				 +				cmd = cmdbuffer.toByteArray(); +				String str = MSCMService.bytArrayToHex(cmd); +				log.info("Sending: >>> " + str); +				response = channel.transmit(new CommandAPDU(cmd)); +				 +				 +				//ByteBuffer bb = ByteBuffer.wrap(cmd); +				//ByteBuffer resp = ByteBuffer.allocate(18000); +				//response = channel.transmit(bb, resp); +				//int resps = channel.transmit(bb, resp); +				//ByteArrayOutputStream out = new ByteArrayOutputStream(); +				//out.write(resp.array(), 0, resps); +				//out.close(); +				//response = new ResponseAPDU(out.toByteArray()); +				log.info("Resp: <<< " + MSCMService.bytArrayToHex(MSCMService.intToBytes(response.getSW()))); +				cmdbuffer.reset(); +			} +		} +		 +		log.info(" SW : <<< " + MSCMService.bytArrayToHex( +				MSCMService.intToBytes(response.getSW()))); +		byte[] data = response.getData(); +		log.info("DATA: <<< " + MSCMService.bytArrayToHex(data)); +		 +		if(data.length == 0) { +			return null; +		} +		 +		MSCMDecoder.checkExceptionInResponse(data, 0); +		 +		if(expectedType == HIVECODE_TYPE_SYSTEM_VOID)  { +			return data; +		} +		 +		String namespaceString = MSCMDecoder.namespaceHiveToString(data, 0); +		String typeString = MSCMDecoder.typeHiveToString(data, 4); +		short resultType = MSCMService.bytesToShort(data, 4); +		if(expectedType == resultType) { +			ByteArrayOutputStream str = new ByteArrayOutputStream(); +			str.write(data, 6, data.length-6); +			return str.toByteArray(); +		} else { +			throw new CardException("Wrong result type"); +		}/* +		if(typeString.equals(HIVECODE_TYPE_SYSTEM_STRING_STRING)) { +			System.out.println(namespaceString + "." + typeString + ": " +  +					MSCMDecoder.decodeString(data, 6)); +		} else if(typeString.equals(HIVECODE_TYPE_SYSTEM_STRING_ARRAY_STRING)) { +			String[] results = MSCMDecoder.decodeStringArray(data, 6); +			System.out.println(typeString + ": "); +			for(String str : results) { +				System.out.println(str); +			} +		} else { +			System.out.println(namespaceString + "." + typeString + ": " +  +				MSCMService.bytArrayToHex(MSCMDecoder.decodeByteArray(data, 6))); +		} +		return data;*/ +	} +	 +} | 
