6

I'm trying to pass though APDUs command via HID OMNIKEY 5427 CK to operate MIFARE Card ie. Ultralight C card, on the Windows 10 x64 OS environment using WinSCard.dll. (I'm under NXP NDA and have full access t their documents)

I tried to find information online for days now. Seem like no published document for this model except the 2pages brochure.

The simple command like GetUID (FFCA000000) is OK, I can get back the actual card UID.

But for 'Authentication with Card', reference document from HID 5421 model said I should start with OpenGenericSession (FFA0000703010001), I tried that and reader always replied with 6D00h (error)

I tried send Authentication command directly '1Ah+00h' (FFA00005080100F30000641A0000) the reader also always replied with error code.

I've experience with HID 5421 model and it quite straight forward, not sure why this 5427 is unlike its sibling.

And yes, I contacted HID support. No luck. No useful information I could get from them.

If any one have idea or have 5427 software development guide please help. I'm pulling my hair for almost a week by now.

vlp
  • 6,063
  • 2
  • 18
  • 44
Eric F.
  • 279
  • 3
  • 11
  • 1
    I can share a working code to access Ultralight-C with HID 5321/6321 readers (using generic session) -- but it seems your problem is with HID 5427 card reader (which I do not have access to). What is interesting with generic session is that it works from windows, but not from linux (even with official omnikey drivers). It might be worth trying to check if 5427 uses the same drivers as 5421...Good luck! – vlp Jun 19 '17 at 22:01
  • My target platform is Windows so I hope I can use generic session method. Please share the code, I suppose the generic session protocol among all HID devices is the same but I can't find HID's sample online that demonstrate that feature. What strange for me is this particular model 5427 is not having any published development guide online. .. Thank you very much for your edit & generousity. @vlp – Eric F. Jun 20 '17 at 07:01
  • 1
    Did you know you can configure the OK5427CK via web-interface? Maybe you will find a missing setting there. – arminb Jun 20 '17 at 12:29
  • Web-interface? I think I miss that feature. Do you know how to get access to it? – Eric F. Jun 20 '17 at 13:59
  • 1
    Yes, the OK5427CK is a composite USB device (smartcard reader + ethernet interface). You need to install the OMNIKEY driver for OK5427CK, default windows driver won't work. Then you will see an additional "network interface" in the device manager, as well as in your network connections. You should be able to call its interface via http://192.168.63.99 (see chapter 2, Link: goo.gl/hjj7Ut) Sadly the web-interface driver is available only for Windows 7 and prior. – arminb Jun 20 '17 at 14:39
  • Thanks @arminb , I now able to goes to web interface using Chrome on Win10x64, unfortunately I think there is not much configuration related to APDU interfacing. I've check that it didn't enable KeyBoard Wedge mode by default so APDU mode is on. And using built-in webtools to send APDU command to 5427 also return same error :( – Eric F. Jun 21 '17 at 04:20
  • Anyway, @arminb do you know what is the OpenGenericSession APDU command for this OK5427CK ? I think this is the magic word to access all APDU features that I really need. – Eric F. Jun 21 '17 at 04:39
  • @EricF. : did you get any solution to read 5427? if yes, could you please share your solution. – SK. Feb 01 '18 at 15:33
  • Sorry @SKumar, I gave up. Spent days on http://pcscworkgroup.com/Download/Specifications/pcsc3_v2.02.00_sup2.pdf that [at]vlp suggested but can't find the correct way to use it with 5427. Now all HID devices we throw away for good.Guess you will have to buy their SDK and hope it worth enough. – Eric F. Feb 05 '18 at 04:59

1 Answers1

2

Below is a proof-of-concept java code to communicate with Ultralight-C over Generic Session using Omnikey 5321/6321:

private static final byte AF = (byte)0xAF;

protected static final byte[] PREFIX = new byte[] { 0x01, 0x00, (byte) 0xF3, 0x00, 0x00, 0x64 };

protected final CardChannel channel;

protected void openGenericSession() throws CardException {
    System.out.println("OPEN GENERIC SESSION");
    transmitAssert9000(new CommandAPDU(0xFF, 0xA0, 0x00, 0x07, new byte[] { 0x01, 0x00, 0x01}));
}

protected byte[] transmitRaw(byte[] data) throws CardException {
    System.out.println(" => " + toHex(data));
    byte[] ret = transmitAssert9000(new CommandAPDU(0xFF, 0xA0, 0x00, 0x05, ArrayUtils.addAll(PREFIX, data), 256));
    if(ret.length<2) {
        throw new RuntimeException();
    }
    if((ret[0]==0x00)&&(ret[1]==0x00)) {
        // Success
        ret = Arrays.copyOfRange(ret, 2, ret.length);
        System.out.println(" <= " + toHex(ret));
        return ret;
    }
    if((ret[0]==0x08)&&(ret[1]==0x04)&&(ret.length==3)) {
        // ACK/NAK
        switch(ret[2]) {
            case 0x0A:
                System.out.println(" <= ACK");
                return ArrayUtils.EMPTY_BYTE_ARRAY;
            default:
                // Buyer beware: very simplified
                System.out.println(" <= NAK");
                throw new RuntimeException("NAK");
        }
    }
    ret = Arrays.copyOfRange(ret, 2, ret.length);
    System.out.println(" <= " + toHex(ret));
    return ret;
}

protected static byte[] assert9000(ResponseAPDU transmit) {
    if(transmit.getSW()!=0x9000) {
        throw new RuntimeException("Unexpected response code");
    }
    return transmit.getData();
}

protected byte[] transmitAssert9000(CommandAPDU commandAPDU) throws CardException {
    return assert9000(transmit(commandAPDU));
}

protected ResponseAPDU transmit(CommandAPDU commandAPDU) throws CardException {
    System.out.println(" -> " + toHex(commandAPDU.getBytes()));
    ResponseAPDU responseAPDU = channel.transmit(commandAPDU);
    System.out.println(" <- " + toHex(responseAPDU.getBytes()));
    return responseAPDU;
}

public byte[] read(int offset) throws CardException {
    System.out.println("READ");
    return transmitRaw(new byte[] {0x30, (byte)offset});
}

Note 1: this code uses javax.smartcardio and Apache Commons Lang.

Note 2: It has been some time I wrote this code, please validate my thoughts...

Note 3: For Ultralight-C authentication code see this companion answer.


Generic session example trace for Omnikey 6321 with Ultralight-C (single line arrows denote Generic Session APDUs and double line arrows denote Ultralight-C commands):

OPEN GENERIC SESSION
 -> FFA0000703010001
 <- 9000
AUTHENTICATE
 => 1A00
 -> FFA00005080100F30000641A0000
 <- 0000AF4BDA4E34B5D04A019000
 <= AF4BDA4E34B5D04A01
 => AF6F18402E0F0E5357D854833B149FBB56
 -> FFA00005170100F3000064AF6F18402E0F0E5357D854833B149FBB5600
 <- 000000F0F667CCF0E140419000
 <= 00F0F667CCF0E14041
READ
 => 3003
 -> FFA00005080100F3000064300300
 <- 0000000000000000000000000000000000009000
 <= 00000000000000000000000000000000
CLOSE GENERIC SESSION
 -> FFA0000703010002
 <- 9000

Some additional notes:

  • (AFAIK) This approach works under Windows (with Omnikey drivers). It does not work under linux (even with Omnikey drivers).

  • Note that PC/SC version 2.02 Part 3 defines MANAGE SESSION, TRANSAPARENT EXCHANGE and SWITCH PROTOCOL commands which provide the same in a standardized way (your reader might support it instead of proprietary generic session mechanism -- HID even participated on this document).

Good luck!

vlp
  • 6,063
  • 2
  • 18
  • 44
  • Thank a lot. The code is enlighten me a lot. Unfortunately the OpenGeneric session APDU is still no go for 5427. Always return 6D00 to me. And I will continue study the PC/SC version 2.02 Part 3 spec you provide, looks promising. – Eric F. Jun 21 '17 at 04:25
  • 1
    @EricF. : Did you get any solution for 5427. Could you please share – SK. Feb 01 '18 at 14:35