kaoh / globalplatform

C library + command-line for Open- / GlobalPlatform smart cards
https://kaoh.github.io/globalplatform/
Other
72 stars 30 forks source link

install_for_install_and_make_selectable() returns 0x80206E00 #14

Closed kaoh closed 4 years ago

kaoh commented 14 years ago

Sorry if this is in the wrong place but I'm all out of ideas for how to fix this.

I'm trying to install the helloWorld applet using helloInstalGP211.txt. The install and load commands work fine but the install_for_install command results in: install_for_install_and_make_selectable() returns 0x80206E00 (6E00: Wrong CLA byte.).

This error has been encourntered by others with no obvious solution as seen here: http://forums.sun.com/thread.jspa?threadID=5355071 and http://forums.sun.com/thread.jspa?threadID=5335555

Attached is a debug log. Any help would be appreciated

Reported by: *anonymous

kaoh commented 14 years ago

GPShell debug log

Original comment by: nobody

kaoh commented 14 years ago

This is the perfect place. This is the issue tracker of GPShell and GlobalPlatform.

80 e6 0c is the correct beginnign for this command. I have not glue what can be the problem. Maybe you can try to issuue the command without security (should be the switch -security 0).

What card are you using?

I have tried it with all of my cards here.

Original comment by: kaoh

kaoh commented 14 years ago

I've tried it with -security 0 and the same thing happens.

To be honest, I'm doing this for work and I'm not really sure what kind of card it is, it was just given to me and I was told to work with it. It has no identifying marks or anything, is there some command(s) I can issue to identify it?

Thanks for your help

Original comment by: nobody

kaoh commented 14 years ago

The ATR (Answer to Reset) received when the card is inserted can help. This is unique for a type of card. You can use the ATR and google around.

Or take a look in this list: http://svn.debian.org/wsvn/pcsclite/trunk/pcsc-tools/smartcard_list.txt?sc=1

If you are using Windows there should be some tool which can read the ATR. Usually with the reader something like this is delivered. Under Linux you can use the http://linux.die.net/man/1/pcsc_scan or stop pcscd and run pcscd -e -d -a -f to see all PC/SC traffic. (Also all APUs which are sent, so you can compare it with the GlobalPlatform log)

Original comment by: kaoh

kaoh commented 14 years ago

The ATR returned from the card did not appear in the list, it was: 3b7918004a434f503231563232 which is (in ASCII): ;y??JCOP21V22

Does this help identify the problem at all? I don't really understand how a standard install_for_install command could have the wrong CLA byte according to this card...

Original comment by: nobody

kaoh commented 14 years ago

It is a JCOP21

http://www.usasmartcard.com/component/page,shop.product_details/flypage,shop.flypage/product_id,52/category_id,26/manufacturer_id,0/option,com_virtuemart/Itemid,26/index.php?page=shop.product_details&flypage=shop.flypage&product_id=52&category_id=26&manufacturer_id=0&option=com_virtuemart&Itemid=26&vmcchk=1

I do not have such a card.

What script are you using?

Try the JCOP10 script, whre the install is not performed as one single command but step by step:

mode_211 gemXpressoPro enable_trace establish_context card_connect -readerNumber 3 select -AID a000000003000000 open_sc -security 1 -keyind 0 -keyver 0 -key 404142434445464748494a4b4c4d4e4f delete -AID a00000006203010c0101 delete -AID a00000006203010c01 delete -AID a00000006203010c0101 install_for_load -pkgAID a00000006203010c01 -nvCodeLimit 500 load -file HelloWorld.cap install_for_install -instParam 00 -priv 02 -AID a00000006203010c0101 -pkgAID a00000006203010c01 -instAID a00000006203010c0101 -nvDataLimit 500 card_disconnect release_context

(Adjust to your needs, I dont know if the gemXpresso switch is necessary.) Maybe some parameters for the install_for_install command are not correct and the card complains with the 6E error.

Original comment by: kaoh

kaoh commented 14 years ago

I tried using that script (and a few variations) and everything results in the 6E00 response. Interestingly when I try and invoke the applet after the failed install I get a RemoteException: Method not found (the applet I am trying to install uses RMI). If it wasn't installed properly I would've expected a 6A82.

Any other ideas to try? Thanks again for your help.

Also I found a better tool for getting the ATR so here is a more complete version:

0000 3B 79 18 00 00 4A 43 4F 50 32 31 56 32 32 ;y...JCOP21V22

TS : 3B Direct logic TO : 79 K = 9 byte [historical characters] TA1 : 18 Fi/f = 372/ 5 [clock rate conversion factor / max. frequency (MHz)] Di = 12 [bit rate conversion factor] TB1 : 00 pa = 4 % [programming voltage accurancy] I = 25 mA [maximum current] P = 0 V [programming voltage] TC1 : 00 N = 0 etu [extra guardtime] 4A434F503231563232 JCOP21V22

Original comment by: nobody

kaoh commented 14 years ago

Mmh, maybe the command is successful and only GPShell makes an error? Can you log the PC/SC traffic?

Run pcscd -f -d -a on linux to see all and see if the last command is 9000.

Original comment by: kaoh

kaoh commented 14 years ago

I'm trying to get gpshell working on a mac so that I can capture the APDU's using pcscd but I'm not having much luck.

I've managed to build gpshell and get it running but when I use the establish_context command i get: establish_context failed with error 0x8010001D (Service not available.)

I've made sure pcscd is definitely running before issuing this command, any ideas?

Thanks

Original comment by: nobody

kaoh commented 14 years ago

Sorry for the long delay. I was busy with the new GlobalPlatform version.

Well, just try out if other tools are working. E.g. pcsc_scan. Can it connect to the service? What version of pcsc is installed in MacOSX? I remember that a very old version 1.2 is shipped with it.

Original comment by: kaoh

kaoh commented 14 years ago

I've finally got everything working in an Ubuntu VM and so can provide logs from GPShell and pcscd. I'll paste the interesting parts below for you to have a look at.

GPShell: install_for_install -instParam 00 -priv 02 -AID a00000006203010c0101 -pkgAID a00000006203010c01 -instAID a00000006203010c0101 Command --> 80E60C002709A00000006203010C010AA00000006203010C01010AA00000006203010C0101010203C901000000 Wrapped command --> 84E60C002F09A00000006203010C010AA00000006203010C01010AA00000006203010C0101010203C901000005A423DD1E48B55A00 Response <-- 6E00 install_for_install_and_make_selectable() returns 0x80206E00 (6E00: Wrong CLA byte.)

pcscd: 00000015 APDU: 84 E6 0C 00 2F 09 A0 00 00 00 62 03 01 0C 01 0A A0 00 00 00 62 03 01 0C 01 01 0A A0 00 00 00 62 03 01 0C 01 01 01 02 03 C9 01 00 00 05 A4 23 DD 1E 48 B5 5A 00000007 ifdhandler.c:1129:IFDHTransmitToICC() usb:0e0f/0004:libhal:/org/freedesktop/Hal/devices/usb_device_e0f_4_noserial_if0 (lun: 0) 00098549 SW: 90 00 00000135 winscard_msg_srv.c:317:SHMProcessEventsContext() command TRANSMIT received by client 8 00000009 winscard.c:1647:SCardTransmit() Send Protocol: T=0 00000006 APDU: 00 C0 00 00 00 00000006 ifdhandler.c:1129:IFDHTransmitToICC() usb:0e0f/0004:libhal:/org/freedesktop/Hal/devices/usb_device_e0f_4_noserial_if0 (lun: 0) 00012396 SW: 6E 00 00000696 winscard_msg_srv.c:306:SHMProcessEventsContext() Client has disappeared: 8 00000013 winscard_svc.c:146:ContextThread() Client die: 8 00000005 winscard.c:253:SCardReleaseContext() Releasing Context: 16982050 00000006 winscard.c:880:SCardDisconnect() Active Contexts: 1

It seems to send an APDU (APDU: 00 C0 00 00 00) that does not appear in GPShell? If you need more of the logs I can upload them somewhere.

Thanks

Original comment by: revile

kaoh commented 14 years ago

These additional APDUs are really strange. I will examine this. By the way I have working versions of the next release in SVN. I can also send you Ubuntu packages if this is easier. Build globalplatform, then gppcscconnectionplugin and then gpshell with ./configure --prefix=/usr --enable-debug && make && sudo make install

This shouldn't fix the problem but who knows?

Original comment by: kaoh

kaoh commented 14 years ago

The 00 C0 00 00 00 is a GET RESPONSE command. If the card wants to return some data, this must be issued. Usually this works. Hava you already tried a different reader? Maybe the reader is the problem. Please test it.

Also try to pass -protocol 1 to the card_connect command. Maybe the T=1 send protocol works.

Original comment by: kaoh

kaoh commented 14 years ago

This reader works with a different card but I will try it with a different reader now. I tried -protocol 1 and got the following response: card_connect -protocol 1 card_connect() returns 0x8010000F (Card protocol mismatch.)

I can't build the new gpshell either, I built the previous 2 packages ok but during configure for gpshell I get: configure: creating ./config.status config.status: error: cannot find input file: Makefile.in

Original comment by: revile

kaoh commented 14 years ago

I've tried a different reader (on Windows, it doesn't work in Ubuntu) and get the same error.

Original comment by: revile

kaoh commented 14 years ago

I just added the missing file for gpshell.

Well, I googled around and this seems to be a problem of the card. Maybe the error is on my side, but what makes me wonder is that so many cards are working but not this card. Actually it works like this:

A program wants to send and receive something, this is called a Case 4 APDU. A Case 4 APDU has a body with data and an "Le" byte as last byte specifying the expected length = (Le) which is returned from the card. 00 means indefinite At first the APDU is send without the Le byte The card should return a 9000 Now a GET RESPONSE must follow = 00 C0 00 00 00 The card returns the response data.

For some reason this fails.

Can you take a look in the select command before? This is also a Case 4 command. A GET RESPONSE should also be done. And here it seems to work, right?

Original comment by: kaoh

kaoh commented 14 years ago

I've uploaded the complete log from both GPShell and pcscd so you can take a look what happened elsewhere.

http://zubon.net/pcscd.log http://zubon.net/gpshell.log

Thanks

Original comment by: revile

kaoh commented 14 years ago

Also still can't get GPShell working: vadmin@ubuntu:~/globalplatform-6.0.0/gpshell$ make Makefile:6: *** target pattern contains no `%'. Stop.

Original comment by: revile

kaoh commented 14 years ago

Strange. Are you using a colon somewhere in the compile command?

Try to regenerate the Makefiles: Eexcfute ./reconf in the directory of gpshell

Original comment by: kaoh

kaoh commented 14 years ago

I fixed that problem and have now built the new GPShell but I get the following error when I try and run it: vadmin@ubuntu:~/globalplatform-6.0.0/gpshell$ ./gpshell ./gpshell: error while loading shared libraries: libglobalplatform.so.6: cannot open shared object file: No such file or directory

Original comment by: revile

kaoh commented 14 years ago

I just tested this with a card that works, here is the pcscd output: 00000018 APDU: 84 E6 0C 00 2F 09 A0 00 00 00 62 03 01 0C 01 0A A0 00 00 00 62 03 01 0C 01 01 0A A0 00 00 00 62 03 01 0C 01 01 01 02 03 C9 01 00 00 31 24 C4 6F 28 2A 76 8F 00000008 ifdhandler.c:1129:IFDHTransmitToICC() usb:08e6/3478:libhal:/org/freedesktop/Hal/devices/usb_device_8e6_3478_noserial_if0 (lun: 0) 00089817 SW: 61 01 00000133 winscard_msg_srv.c:317:SHMProcessEventsContext() command TRANSMIT received by client 8 00000011 winscard.c:1647:SCardTransmit() Send Protocol: T=0 00000006 APDU: 00 C0 00 00 01 00000007 ifdhandler.c:1129:IFDHTransmitToICC() usb:08e6/3478:libhal:/org/freedesktop/Hal/devices/usb_device_8e6_3478_noserial_if0 (lun: 0) 00005807 SW: 00 90 00

As you can see, the APDU that causes a problem on the other card is different here (00 C0 00 00 01 vs 00 C0 00 00 00). Seems like for some reason GPShell is sending an Le byte of 0 for the "broken" card and 01 for the one that works...

Just throwing ideas out there, not sure if this is helpful or not

Original comment by: revile

kaoh commented 14 years ago

Hmm, upon reading the pcscd logs of the 2 (the card that works and the card that doesn't) closer it seems they are quite different.

The card that works responds with a 61 01 SW after the install_for_install command, GPShell then asks for the data with the 00 C0 00 00 01 APDU and the card response with 00 90 00.

With the "broken" card it responds to the install_for_install command directly with a 90 00, but GPShell still asks for (indefinite length) data to be returned... could this be the problem?

Original comment by: revile

kaoh commented 14 years ago

I've managed to fix this by hacking GlobalPlatform.c slightly, obviously its not a permenant fix but it confirms what I thought the problem was. It is related to the comment starting from line 1288 in GlobalPlatform.c from globalplatform-5.0.0: / Note: Some smartcard are not fully compatible with ISO normatives in case short 4. So when a card returns a 0x9000 to inform a good transfer of the APDU command then the terminal have to terminate the transaction and it shall return the sw1 sw2 to the user. In the case of fully ISO, the terminal sends a get response to extract the "le" bytes requested inside the APDU command. /

I commented out line 1301 (//|| responseData[offset] == 0x90) and now it installs successfully.

Original comment by: nobody

kaoh commented 14 years ago

Great work!

You finally found the libglobalplatform.so.6 library? This should be produced by the globalplatform library installation, isn't it?

This is a good point, I also have looked into this problem, but how to solve this globally? I could introduce a new flag "broken_response" or something like that which informs the library not to behave standard complinat and omit the GET RESPONSE command. Actually this command must return a single byte, but the your JCOP does not return a byte. I could leave away the 9000 check and test if it works for all cards.

Original comment by: kaoh

kaoh commented 14 years ago

I guess the flag would work but is there a situation where a card responds directly with 90 00 but still requires the GET RESPONSE command to be sent?

Original comment by: nobody

kaoh commented 14 years ago

Yes, all cards must do this:

http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_annex-a.aspx

See Case 4 short.

Original comment by: kaoh

kaoh commented 14 years ago

Ah right, so this card I have just ignores the standard. Great...

I guess it has to be a flag then, perhaps some kind of mode flag like gemXpressoPro?

Original comment by: nobody

kaoh commented 14 years ago

I would think so.

Also the GP spec says for the install commands:

9.5.3 Response Message A data field shall always be returned in the response message. The content of the data field is only relevant in the case of Delegated Management i.e. if an INSTALL [for install], INSTALL [for install and make selectable] or INSTALL [for extradition] command is being issued to a Security Domain with the Delegated Management privilege, a Receipt may be present in the data field depending on the security policy of the Card Issuer. 9.5.3.1 Data Field Returned in the Response Message If the Issuer Security Domain processes the INSTALL command, a single byte of '00' shall be returned indicating that no additional data is present. If an INSTALL [for load] command, an INSTALL [for make selectable] command alone or an INSTALL [for personalization] command is being issued to a Security Domain with the Delegated Management privilege, a single byte of '00' shall also be returned indicating that no additional data is present. For INSTALL [for install], INSTALL [for install and make selectable] and INSTALL [for extradition] commands being issued to a Security Domain with the Delegated Management privilege, the data field may contain the confirmation of the install procedure. The overall length of the response message shall not exceed 256 bytes. The following table describes the structure of the INSTALL response data field. Presence Length in Bytes Name Mandatory 1 Length of install confirmation Conditional 0-n Install confirmation (see Section 9.1.7)

So at least one byte must be returned, so if 9000 is the status, it should return at least 009000, so I can see, this is actually wrong, but I can recogbnize it because something is returned.

Yes, this will be a specifier like gemXpresso, but gemXpresso is now renamed to visa_key_derivation. It was introduced to support a key derivation scheme. Some other cards are also using this scheme, so the name fits better. The old name is depracted but still accepted.

Original comment by: kaoh

kaoh commented 14 years ago

I've fixed this in a more permanent way locally. It's probably better to wait for your fix as its your project and I wasn't really sure how to go about it but this will work in the mean time.

The way I did it was to modify the OPGP_CARD_INFO struct to hold a flag specifying whether the response to case 4 APDU's is broken or not. Then I added a flag to GPShell and set the flag on the cardInfo after card_connect is called. Following that, a simple change to send_APDU in GlobalPlatform to check the flag on the cardInfo and it seems to work. Although I don't have a card that responds with 90 00 and still requires a GET DATA command so I can't test that side of things. All the cards I do have work (the broken one that responds with 90 00 and requires no GET DATA, and the correct one that replies with 61 01 and responds with 00 90 00 to the subsequent GET DATA command).

If my changes make sense and they can save you some time I'm happy to add them in, they may well be a hack and not the way you would have gone about fixing it though so up to you.

Thanks for all your help getting this sorted, much appreciated.

Original comment by: revile

kaoh commented 14 years ago

No, I have no better idea. If you can provide a patch this would be nice.

Original comment by: kaoh

kaoh commented 14 years ago

How do you want me to provide the changes? Also I have made my changes against globalplatform-5.0.0, do you want me to do them against 6.0.0?

Original comment by: revile

kaoh commented 14 years ago

6.0.0 would be better. I have given you commit privileges in SVN. At least I do it right now.

Original comment by: kaoh

kaoh commented 14 years ago

I'm trying to build GlobalPlatform and GPShell on Windows and am a bit lost, both seem to be missing makefile.in and makefile.targ.inc. Am I doing something wrong?

I'm running nmake -f Makefile.mak in a VS command prompt

Original comment by: nobody

kaoh commented 14 years ago

Hmm, further testing of my fix has led me to think it might not be quite right. The application nos installs ok but when deleting it again I get this: mode_211 establish_context card_connect select -AID a000000003000000 open_sc -security 3 -keyver 0 -mac_key 404142434445464748494a4b4c4d4e4f -enc_key 404142434445464748494a4b4c4d4e4f delete -AID a00000006203010c0801 delete_applet() returns 0x80206A88 (6A88: Referenced data not found.) delete -AID a00000006203010c08 card_disconnect release_context

On the other card this works fine, and the applet itself works fine. Is there some step missing or is this just more strange behaviour of the card?

Original comment by: revile

kaoh commented 14 years ago

It is not that obvious when looking at all the specs

Application layer -GP 2.1.1: now the INSTALL command is a case 4 and a 1 byte response is requested

Original comment by: lexdabear

kaoh commented 14 years ago

But then EMV violates ISO 7816-4. There after a 9000 a GET RESPONSE must follow. I cannot conclude from 9000 that there is no more data. http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_annex-a.aspx

So a specifier must be introduced to specify if this card is an EMV card or an ISO conforming card? So the spec is broken.

Original comment by: kaoh

kaoh commented 14 years ago

Do you still want me to add my changes in or does this require more thought now? Also did you get a chance to have a look at my previous comment about the strangeness deleting the applet?

Original comment by: nobody

kaoh commented 14 years ago

The deletion problem is also strange. I sounds like nothing was installed. But why? Everything seems to be successful? Another problem?

Well, the patch woul be something like this:

You can introduce for npw a flag for the JCOP 2.2 card and pass it in some way down. In the install_for_install if the flag is set a case 3 command instead of a case 4 command must be executed, because the PC/SC layer cannot be patched easily (in 6.0.0).

A more flexible general approach would be (which I would implement later if you don't go for it): Internal in GP a list with ATRs of "special" cards is stored and if the card ATR is known some specific action must be done to fix the behavior.

Because you have such a card, it would be the best you integrate it and test it.

Thanks

Original comment by: kaoh

kaoh commented 14 years ago

I have submitted a patch for the problem. At least the install_for_X.

Look for occurences of JCOP21V22_ATR in globalplatform.c. Does it work? What happens during the deletion?

Original comment by: kaoh

kaoh commented 14 years ago

Any news about this problem?

Original comment by: kaoh

kaoh commented 14 years ago

Sorry got sidetracked with other things, I'll test your solution this week and let you know

Original comment by: nobody

kaoh commented 14 years ago

This works now! Somebody had a similar problem and the problem with the JCOP 2x card was that an INSTALLL [for install and make selectable] command did not return a single byte as response. This was the reason the GET RESPONSE failed. Now I intercept this error and return the previous response.

Original comment by: kaoh