Java Code Examples for javax.smartcardio.ResponseAPDU#getData()

The following examples show how to use javax.smartcardio.ResponseAPDU#getData() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: GPSecureChannel.java    From openjavacard-tools with GNU Lesser General Public License v3.0 7 votes vote down vote up
/**
 * Assemble and transact an INITIALIZE UPDATE command
 * <p/>
 * The command will be sent on the underlying unencrypted channel.
 * <p/>
 * @param keyVersion    to indicate
 * @param keyId         to indicate
 * @param hostChallenge to send
 * @return a decoded response to the command
 * @throws CardException on error
 */
private GPInitUpdateResponse performInitializeUpdate(byte keyVersion, byte keyId, byte[] hostChallenge) throws CardException {
    LOG.trace("performInitializeUpdate()");
    // build the command
    CommandAPDU initCommand = APDUUtil.buildCommand(
            GP.CLA_GP,
            GP.INS_INITIALIZE_UPDATE,
            keyVersion,
            keyId,
            hostChallenge
    );
    // and transmit it on the underlying channel
    ResponseAPDU initResponse = mBasicWrapper.transmitRaw(initCommand);
    // check the response
    checkResponse(initResponse);
    // parse the response
    byte[] responseData = initResponse.getData();
    GPInitUpdateResponse response = new GPInitUpdateResponse(responseData);
    // return the parsed response
    return response;
}
 
Example 2
Source File: APDUUtil.java    From openjavacard-tools with GNU Lesser General Public License v3.0 6 votes vote down vote up
/**
 * Stringify a response APDU verbosely
 *
 * @param apdu to stringify
 * @return string representing the APDU
 */
public static String toString(ResponseAPDU apdu) {
    StringBuffer sb = new StringBuffer();
    int sw = apdu.getSW();
    sb.append("SW=" + HexUtil.hex16(sw));
    SWInfo swData = SWInfo.get(sw);
    if (swData != null) {
        sb.append(" [");
        sb.append(swData.name);
        sb.append("]");
    } else {
        sb.append(" [unknown]");
    }
    byte[] data = apdu.getData();
    if (data == null || data.length == 0) {
        sb.append(" (no data)");
    } else {
        sb.append(" LE=" + data.length);
        sb.append(" DATA=" + HexUtil.bytesToHex(data));
    }
    return sb.toString();
}
 
Example 3
Source File: JCMathLibTests.java    From JCMathLib with MIT License 6 votes vote down vote up
void testAPDU(CardManager cardMngr, String input, String expectedOutput) {
    try {
        ResponseAPDU response = cardMngr.transmit(new CommandAPDU(hexStringToByteArray(input)));
        if (response.getSW() == (ISO7816.SW_NO_ERROR & 0xffff)) {
            if (!expectedOutput.isEmpty()) {
                byte[] data = response.getData();
                String output = Util.bytesToHex(data);
                assertTrue(expectedOutput.equalsIgnoreCase(output), "Result provided by card mismatch expected");
            }
        }
        else {
            assertTrue(false, String.format("Card failed with 0x%x", response.getSW()));
        }                
    }
    catch (Exception e) {
        e.printStackTrace();
        assertTrue(false, "Card transmit failed with execption");
    }
}
 
Example 4
Source File: ScanFID.java    From openjavacard-tools with GNU Lesser General Public License v3.0 5 votes vote down vote up
private void scanNames(GenericCard card, int base, int count) throws CardException {
    PrintStream os = System.out;

    int last = base + count - 1;

    os.println("SCANNING FILE ID FROM " + HexUtil.hex16(base) + " THROUGH " + HexUtil.hex16(last));

    ArrayList<Integer> found = new ArrayList<>();
    for(int current = base; current <= last; current++) {
        if(verbose) {
            os.println(" PROGRESS " + HexUtil.hex16(current));
        }
        ResponseAPDU rapdu = performSelect(card, current, true);
        int sw = rapdu.getSW();
        if(sw == 0x9000) {
            String foundLog = "  FOUND " + HexUtil.hex16(current);
            found.add(current);
            byte[] data = rapdu.getData();
            if(data.length > 0) {
                foundLog += " DATA " + HexUtil.bytesToHex(data);
            }
            os.println(foundLog);
        } else if(sw == ISO7816.SW_FILE_NOT_FOUND) {
            continue;
        } else {
            os.println("  ERROR FID=" + HexUtil.hex16(current) + " " + SW.toString(sw));
        }
    }

    if(found.isEmpty()) {
        os.println("  FOUND NOTHING");
    }
}
 
Example 5
Source File: GPBasicWrapper.java    From openjavacard-tools with GNU Lesser General Public License v3.0 5 votes vote down vote up
/**
 * Perform a GlobalPlatform GET DATA operation
 *
 * @param p1p2 selecting the data
 * @return data retrieved
 * @throws CardException on error
 */
public byte[] readData(short p1p2) throws CardException {
    LOG.trace("readData(" + HexUtil.hex16(p1p2) + ")");
    CommandAPDU command = APDUUtil.buildCommand(
            GP.CLA_GP,
            GP.INS_GET_DATA,
            p1p2
    );
    byte[] response = null;
    try {
        // execute the command
        ResponseAPDU rapdu = transactAndCheck(command);
        // allow for empty response (return null)
        if(rapdu.getNr() > 0) {
            response = rapdu.getData();
        }
    } catch (SWException e) {
        switch (e.getCode()) {
            case ISO7816.SW_FILE_NOT_FOUND:
            case ISO7816.SW_REFERENCED_DATA_NOT_FOUND:
                break;
            default:
                throw e;
        }
    }
    return response;
}
 
Example 6
Source File: CardManager.java    From JCMathLib with MIT License 5 votes vote down vote up
private void log(ResponseAPDU response, long time) {
    String swStr = String.format("%02X", response.getSW());
    byte[] data = response.getData();
    if (data.length > 0) {
        System.out.printf("<-- %s %s (%d) [%d ms]\n", Util.toHex(data), swStr,
                data.length, time);
    } else {
        System.out.printf("<-- %s [%d ms]\n", swStr, time);
    }
}
 
Example 7
Source File: CardManager.java    From JCMathLib with MIT License 5 votes vote down vote up
private void log(ResponseAPDU response, long time) {
    String swStr = String.format("%02X", response.getSW());
    byte[] data = response.getData();
    if (data.length > 0) {
        System.out.printf("<-- %s %s (%d) [%d ms]\n", toHex(data), swStr,
                data.length, time);
    } else {
        System.out.printf("<-- %s [%d ms]\n", swStr, time);
    }
}
 
Example 8
Source File: SmartcardTestService.java    From statelearner with Apache License 2.0 5 votes vote down vote up
public String processCommand(String command) throws Exception {
	ResponseAPDU[] responses = sendCommand(command);
	List<String> outputs = new ArrayList<String>();
	
	for(ResponseAPDU response: responses) {
		// Return abstract response from card
		String returnValue = "SW:" + Integer.toHexString(response.getSW());
	
		if(response.getData().length > 0) {
			String strData = Utils.bytesToHex(response.getData());

			if(strData.contains("9F27")) {
				returnValue += ",AC:" + strData.substring(strData.indexOf("9F27")+6, strData.indexOf("9F27")+8);
			}
			else if(command.contains("GENERATE_AC")) {
				// Visa card?
				returnValue += ",AC:" + strData.substring(4, 6);
			}

			returnValue += ",Len:" + response.getData().length;
		}
		
		outputs.add(returnValue);
	}
	
	//TODO Add support to select part of data to be included in output
	return String.join("/", outputs);
}
 
Example 9
Source File: SmartcardTestService.java    From statelearner with Apache License 2.0 5 votes vote down vote up
public static void main(String[] args) throws Exception {
	if(args.length < 2) {
		System.out.println("Usage: " + args[0] + " <APDU file> <APDU list>");
		System.exit(0);
	}
	
	SmartcardTestService sc = new SmartcardTestService();
	sc.loadAPDUDictionary(args[0]);
	
	String[] commands = args[1].split(";");
	List<String> outputs = new ArrayList<String>();
	
	for(String command: commands) {
		ResponseAPDU[] responses = sc.sendCommand(command.trim());
		List<String> output = new ArrayList<String>();

		for(ResponseAPDU response: responses) {
			String resp = "SW:" + Integer.toHexString(response.getSW());

			if(response.getData().length > 0) {
				resp += ",Data:" + Utils.bytesToHex(response.getData());
			}
			
			output.add(resp);
		}
		
		outputs.add(String.join("/", output));
	}
	
	System.out.println(String.join(";", outputs));
}
 
Example 10
Source File: CardUtils.java    From OpenPGP-Card with GNU General Public License v3.0 5 votes vote down vote up
public static String formatResponseAPDU(ResponseAPDU response) {
  if (response.getData().length > 0) {
    return format("[Received] SW: %04X Data: ", response.getSW()) + HexString.bytesToHex(
        response.getData());
  } else {
    return format("[Received] SW: %04X", response.getSW());
  }
}
 
Example 11
Source File: ScanName.java    From openjavacard-tools with GNU Lesser General Public License v3.0 4 votes vote down vote up
private void scanNames(GenericCard card, byte[] base, int depth, int recurse) throws CardException {
    PrintStream os = System.out;

    BigInteger bStart = new BigInteger(Arrays.copyOf(base, base.length + depth));
    BigInteger bLimit;
    if(aidDepth != 0) {
        BigInteger bDepth = BigInteger.valueOf(1 << (depth * 8));
        bLimit = bStart.add(bDepth);
    } else {
        BigInteger bCount = BigInteger.valueOf(aidCount);
        bLimit = bStart.add(bCount);
    }

    os.println("SCANNING NAMES FROM " + HexUtil.bytesToHex(bStart.toByteArray())
            + " BELOW " + HexUtil.bytesToHex(bLimit.toByteArray()));

    ArrayList<byte[]> found = new ArrayList<>();
    for(BigInteger index = bStart;
        index.compareTo(bLimit) < 0;
        index = index.add(BigInteger.ONE)) {
        byte[] name = index.toByteArray();
        if(verbose || (name[name.length - 1] == (byte)0xFF)) {
            os.println(" PROGRESS " + HexUtil.bytesToHex(name));
        }
        ResponseAPDU rapdu = performSelect(card, name, true);
        int sw = rapdu.getSW();
        if(sw == 0x9000) {
            String foundLog = "  FOUND " + HexUtil.bytesToHex(name);
            found.add(name);
            byte[] data = rapdu.getData();
            if(data.length > 0) {
                foundLog += " DATA " + HexUtil.bytesToHex(data);
            }
            os.println(foundLog);
            card.reconnect(true);
        } else if(sw == ISO7816.SW_FILE_NOT_FOUND) {
            continue;
        } else {
            os.println("  ERROR " + HexUtil.bytesToHex(name) + " " + SW.toString(sw));
            card.reconnect(true);
        }
    }

    if(found.isEmpty()) {
        os.println("  FOUND NOTHING");
    }

    if(recurse > 0) {
        for(byte[] aid: found) {
            scanNames(card, aid, 1, recurse - 1);
        }
    }
}
 
Example 12
Source File: SCP03Wrapper.java    From openjavacard-tools with GNU Lesser General Public License v3.0 4 votes vote down vote up
@Override
public ResponseAPDU unwrap(ResponseAPDU response) throws CardException {
    // get fields
    byte[] data = response.getData();
    int sw1 = response.getSW1();
    int sw2 = response.getSW2();

    // perform RMAC
    if (mRMAC) {
        // get the right key
        GPKey rmacKey = mKeys.getKeyByUsage(GPKeyUsage.RMAC);

        // check for sufficient length
        if (data.length < 16) {
            throw new CardException("Can not unwrap: response too short");
        }

        // extract the MAC value
        byte[] mac = Arrays.copyOfRange(data, data.length - 8, data.length);

        // complete MAC context with response
        ByteArrayOutputStream rmac = new ByteArrayOutputStream();
        rmac.write(mICV, 0, mICV.length);
        rmac.write(data, 0, data.length - 8);
        rmac.write(sw1);
        rmac.write(sw2);

        // perform MAC computation
        byte[] macResult = GPBouncy.scp03_mac(rmacKey, rmac.toByteArray(), 128);
        byte[] myMAC = Arrays.copyOfRange(macResult, 0, 8);

        // compare MAC values
        if (!Arrays.equals(mac, myMAC)) {
            throw new CardException("Can not unwrap: bad response MAC");
        }

        data = Arrays.copyOfRange(data, 0, data.length - 8);
    }

    // perform RENC
    if(mRENC && data.length > 0) {
        // RENC uses the ENC key
        GPKey encKey = mKeys.getKeyByUsage(GPKeyUsage.ENC);
        // get counter and modify it for RENC
        byte[] ctr = getEncryptionCounter();
        ctr[0] = (byte)0x80;
        // derive the ICV
        byte[] icv = GPCrypto.enc_aes_ecb(encKey, ctr);
        // perform decryption
        byte[] decrypted = GPCrypto.dec_aes_cbc(encKey, data, icv);
        // remove padding
        data = GPCrypto.unpad80(decrypted);
    }

    // assemble response APDU
    ByteArrayOutputStream myData = new ByteArrayOutputStream();
    myData.write(data, 0, data.length);
    myData.write(sw1);
    myData.write(sw2);

    // return response object
    return new ResponseAPDU(myData.toByteArray());
}
 
Example 13
Source File: GPSecureWrapper.java    From openjavacard-tools with GNU Lesser General Public License v3.0 4 votes vote down vote up
/**
 * Perform a GlobalPlatform SET STATUS operation
 *
 * @param p1Subset
 * @param p2Format
 * @param criteria
 * @return data retrieved
 * @throws CardException on error
 */
private ArrayList<byte[]> performReadStatus(byte p1Subset, byte p2Format, byte[] criteria) throws CardException {
    LOG.trace("performReadStatus()");
    ArrayList<byte[]> res = new ArrayList<>();
    boolean first = true;
    do {
        // determine first/next parameter
        byte getParam = GP.GET_STATUS_P2_GET_NEXT;
        if (first) {
            getParam = GP.GET_STATUS_P2_GET_FIRST_OR_ALL;
        }
        first = false;
        // build the command
        CommandAPDU command = APDUUtil.buildCommand(
                GP.CLA_GP,
                GP.INS_GET_STATUS,
                p1Subset, (byte) (getParam | p2Format), criteria);
        // run the command
        ResponseAPDU response = transactSecure(command);
        // get SW and data
        int sw = response.getSW();
        byte[] data = response.getData();
        // append data, no matter the SW
        if (data != null && data.length > 0) {
            res.add(data);
        }
        // continue if SW says that we should
        //   XXX extract this constant
        if (sw == 0x6310) {
            continue;
        }
        // check for various cases of "empty"
        //   XXX rethink this loop
        if (sw == ISO7816.SW_NO_ERROR
                || sw == ISO7816.SW_FILE_NOT_FOUND
                || sw == ISO7816.SW_REFERENCED_DATA_NOT_FOUND) {
            break;
        } else {
            throw new SWException("Error in GET STATUS", sw);
        }
    } while (true);
    return res;
}
 
Example 14
Source File: GpgCryptoTest.java    From OpenPGP-Card with GNU General Public License v3.0 4 votes vote down vote up
@Test
public void internalAuthenticate()
    throws CardException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
  KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
  keyGen.initialize(2048);
  KeyPair key = keyGen.generateKeyPair();
  RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) key.getPrivate();
  byte[] data = encodeCRTKey(0xA4, bytesToHex(trimmedBigInteger(privateKey.getPrimeP())),
                             bytesToHex(trimmedBigInteger(privateKey.getPrimeQ())),
                             bytesToHex(trimmedBigInteger(privateKey.getPrimeExponentP())),
                             bytesToHex(trimmedBigInteger(privateKey.getPrimeExponentQ())),
                             bytesToHex(trimmedBigInteger(privateKey.getCrtCoefficient())));

  // Submit PW3
  assertSWOnly(0x9000, card.sendAPDU(0, Gpg.CMD_VERIFY, 0, 0x83, "31 32 33 34 35 36 37 38"));
  // Load the encrytion key.
  sendKey(data);
  assertSWOnly(0x9000, card.sendAPDU(0, Gpg.CMD_VERIFY, 0, 0x82, "31 32 33 34 35 36"));
  String testData = "33 A8 43 1F E0 44 B8 55";
  ResponseAPDU r = assertSW(0x9000, card.sendAPDU(0, Gpg.CMD_INTERNAL_AUTHENTICATE, 0, 0,
                                                  testData));

  // Compute signature as described in 7.2.10
  byte[] byteData = toByteArray(testData);
  byte[] pad = new byte[256 - 3 - byteData.length];
  Arrays.fill(pad, (byte) 0xFF);
  byte[] expected = mergeByteArrays(toByteArray("00 01"), pad, new byte[1], byteData);
  BigInteger s = new BigInteger(1, r.getData());
  RSAPublicKey pkey = (RSAPublicKey) key.getPublic();
  BigInteger se = s.modPow(pkey.getPublicExponent(), pkey.getModulus());
  byte[] computedAuth = se.toByteArray();
  if (computedAuth.length < 256) {
    computedAuth = mergeByteArrays(new byte[256 - computedAuth.length], computedAuth);
  }
  assertArrayEquals(bytesToHex(computedAuth), computedAuth, expected);
  // Make sure that the authentication key is cleared.
  clearCard();
  assertSWOnly(0x9000, card.sendAPDU(0, Gpg.CMD_VERIFY, 0, 0x83, "31 32 33 34 35 36 37 38"));
  assertSWOnly(0x9000, card.sendAPDU(0, Gpg.CMD_VERIFY, 0, 0x82, "31 32 33 34 35 36"));
  assertSWOnly(0x9000, card.sendAPDU(0, Gpg.CMD_VERIFY, 0, 0x81, "31 32 33 34 35 36"));
  // Check that the decryption key is not operable.
  assertSWOnly(0x6A82, card.sendAPDU(0, Gpg.CMD_INTERNAL_AUTHENTICATE, 0, 0, testData));
}