-
Notifications
You must be signed in to change notification settings - Fork 712
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for Polish e-dowód #1831
Comments
If you have their application, I would try to run pcscd in debug mode to list what APDUs are exchanged with the cards. This should give you some idea what they are sending when and hopefully some meaning and context to that (with the help of ISO 7816-4). |
@Jakuje I beet that instead of thins pkcs11 lib extensions |
Your card seems to have some proprietary extension in the front of the general authenticate response. The CAN protects the card's privacy via NFC. For the German ID card, the process would be
However, most PKCS#11 applications aren't prepared to perform the first step. (Theoretically, you could do this via PKCS#11, but, again, no real world application is actually that flexible.) That's why I've decided to let the user hardcode her CAN in |
Here is transmission dump from official initialization. --- can1.log 2019-10-19 13:25:47.319940334 +0300
+++ can2.log 2019-10-19 13:23:09.220255419 +0300
@@ -105,10 +105,10 @@
APDU: 00 22 C1 A4 12 80 0A 04 00 7F 00 07 02 02 04 02 04 83 01 02 84 01 10
SW: 90 00
APDU: 10 86 00 00 02 7C 00 00
-SW: 7C 12 80 10 CC 59 1B 38 DB 55 AB 27 1F 60 AE 72 E4 02 FB E4 90 00
-APDU: 10 86 00 00 65 7C 63 81 61 04 76 7F F8 45 37 BF 72 8C 24 96 EF 2A 5D 3C 2D 38 BD B3 4A A5 28 01 D7 45 77 44 CC 62 A8 6F AC 1F 5E C7 F6 D7 DC 88 86 5F 29 68 6C 65 CC 0A 57 63 3C 3B AB 9F C8 EF 48 71 1B 24 E1 E7 19 E6 5B F9 CE 11 68 10 A5 90 63 B1 88 40 32 9C F7 9A 85 52 8D E0 03 49 5B 48 D4 0E 0E FF 6E 30 15 06 D7 11 65
-SW: 7C 63 82 61 04 7B B8 A0 36 79 BC 1C AC 7D 50 14 A1 02 63 AF F9 D6 70 DA 8A 2E 10 89 40 7D 2B 47 C3 9E AC 96 54 A0 61 DB D1 25 02 93 10 D4 93 B6 B5 42 61 F8 40 4A C8 37 8B 45 03 23 B1 72 58 7A 3C B8 40 68 83 5E 57 E2 9B 01 BC 9A 31 38 FD 87 F1 84 F9 04 E6 04 11 80 7E A7 90 3E 1A 88 54 02 9E 67 B9 53 8E 90 00
-APDU: 10 86 00 00 65 7C 63 83 61 04 65 43 9B 2A 9D F5 73 B4 00 0A 57 D5 BA 83 91 A3 75 3B 49 96 D5 9D E8 2E BB 8B C5 98 C9 CE 7A 01 07 42 9C 67 E5 A5 0C BB D9 9B 10 E1 96 20 78 FD 1E C4 05 62 9B 32 9F E3 26 A8 69 4C 8D 05 04 D4 2D F9 7C 93 24 1F 74 A6 05 71 B1 46 00 4C B7 2B E5 A6 3E 23 4C 2C 3E 98 7D 04 20 CB E0 71 8D 70 65
-SW: 7C 63 84 61 04 23 BA EA 01 84 F2 A3 5F B0 A8 3E 30 95 12 52 8B 53 19 A8 6E 92 D5 04 53 27 4C D8 35 7D D4 0C AF 97 A7 B4 FC 17 DA 22 EE B9 42 BD 5B 61 C9 6F 2A 25 7D 53 E3 9B 2A 41 7B 5B 17 22 10 BB EF 31 DD 08 16 F1 0D C8 43 C2 C0 2E ED AC 44 17 DC 17 87 9E 1E 52 01 F2 94 07 AE 0B 9B 5C C6 6A 6B 2E 81 90 00
-APDU: 00 86 00 00 0C 7C 0A 85 08 26 46 F3 5E 67 D2 CC 6B 0C
-SW: 7C 0A 86 08 25 0A 72 A6 23 9B A4 11 90 00
+SW: 7C 12 80 10 E8 6B 0B CA 7C F5 8B ED 7E 08 68 AC 5D 0E D6 79 90 00
+APDU: 10 86 00 00 65 7C 63 81 61 04 07 05 34 76 8B AC 9B BA A8 ED 04 14 64 2C FB FE 1F 4F 7B E1 4D 4D A2 F7 E3 22 B0 3E 65 A0 66 DE 55 1E 36 58 4C 15 35 24 AF 3C CE F2 C7 05 C7 A3 03 1B B6 5D 6E C5 A3 E5 B0 BA 87 9D 36 EE 75 79 6A AC 70 B6 D8 D4 B3 6E 6E 80 2C A6 E0 75 E7 FD 9B B1 EB 1B A9 8F 3F C0 43 77 ED 36 B2 50 B2 9F 65
+SW: 7C 63 82 61 04 57 7D A3 9D 23 A2 36 1B CA 19 DA F5 6F 97 E7 9F C9 75 3A 20 3F F1 36 65 9E 4E DE 1E 65 79 A7 0C 66 17 85 62 1C B2 FA 70 0D FD 32 DC 56 48 22 A2 1D 7B AD 7F B9 C6 E8 71 48 FB 7D A5 13 96 9E 1A F7 81 2E 37 3B 07 A3 B6 88 43 05 2E 84 16 0C FA DA 47 3C 50 A3 E8 80 B3 92 1F FF 94 74 8E 26 8E 90 00
+APDU: 10 86 00 00 65 7C 63 83 61 04 1D FD C6 3D D1 FC 02 03 F2 16 6A 8E C2 C6 A0 4F F4 74 AC 01 D1 F5 76 08 56 3D A4 A3 5B B1 4B 9E 64 DC 6E 46 2F BE 91 C8 BF 40 77 B2 B4 B4 75 30 7F A4 FA 09 48 90 BA F3 5F CC 51 89 71 2C 5B E9 20 DF 71 41 A0 99 8D 7B F2 68 22 01 A4 C7 40 54 F8 68 ED 87 B7 7B 8E 2B 11 65 69 72 5C 8A BD FF 65
+SW: 7C 63 84 61 04 45 C4 58 30 47 E2 DB 86 70 01 A3 96 EB 22 26 69 69 F7 E8 CF 39 6B 2E F2 08 53 06 91 BB E9 33 15 28 3A 3C EF DE B2 81 83 10 DA FA E4 57 7F BC 5A 2A C0 44 53 F2 8D 93 78 61 61 99 29 38 B0 5A 0F 2C D6 49 BA 4B 57 ED E5 C3 89 5A 47 94 71 89 60 7B 61 3D E3 0C 4E CC 8E 0A 36 C8 09 E9 81 58 C9 90 00
+APDU: 00 86 00 00 0C 7C 0A 85 08 37 AD 23 D5 EA 89 71 E1 0C
+SW: 7C 0A 86 08 7A 47 9E 8F 47 03 AB E5 90 00 I'm afraid that
|
I've authorized successfully with following code, but #include <stdio.h>
#include <stdlib.h>
#include <winscard.h>
#include <eac/eac.h>
#include <eac/pace.h>
#include <openssl/bio.h>
#include <string.h>
#include <time.h>
#define CHECK(f, rv) \
if (SCARD_S_SUCCESS != rv) \
{ \
printf(f ": %s\n", pcsc_stringify_error(rv)); \
return -1; \
}
SCARDHANDLE hCard;
SCARDCONTEXT hContext;
BYTE pbRecvBuffer[258];
DWORD dwRecvLength;
BIO* bio;
EAC_CTX* pcd_ctx;
PACE_SEC* secret = NULL;
BUF_MEM* pcd_ephemeral_pubkey;
BUF_MEM* picc_ephemeral_pubkey;
int main(int argc, char** argv) {
LONG rv;
{
bio = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT);
}
{
EAC_init();
pcd_ctx = EAC_CTX_new();
EAC_CTX_init_pace(pcd_ctx, NID_id_PACE_ECDH_GM_AES_CBC_CMAC_256, 16);
}
{
secret = PACE_SEC_new(argv[1], 6, PACE_CAN);
}
{
DWORD dwActiveProtocol;
unsigned int i;
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
CHECK("SCardEstablishContext", rv)
rv = SCardConnect(hContext, "Identiv Identiv uTrust 4701 F Dual Interface Reader [uTrust 4701 F CL Reader] (55041747202849) 01 00", SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
CHECK("SCardConnect", rv)
}
// STEP 1 – MSE:Set AT
{
unsigned char msg[] = {0x00, 0x22, 0xC1, 0xA4, 0x12, 0x80, 0x0A, 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x04, 0x02, 0x04, 0x83, 0x01, 0x02, 0x84, 0x01, 0x10};
dwRecvLength = sizeof(pbRecvBuffer);
rv = SCardTransmit(hCard, SCARD_PCI_T1, msg, sizeof msg, NULL, pbRecvBuffer, &dwRecvLength);
CHECK("SCardTransmit", rv)
}
// STEP 2.1 – General Authenticate (Encrypted Nonce)
{
unsigned char msg[] = {0x10, 0x86, 0x00, 0x00, 0x02, 0x7C, 0x00, 0x00};
dwRecvLength = sizeof(pbRecvBuffer);
rv = SCardTransmit(hCard, SCARD_PCI_T1, msg, sizeof msg, NULL, pbRecvBuffer, &dwRecvLength);
CHECK("SCardTransmit", rv)
BUF_MEM* enc_nonce = BUF_MEM_new();
BUF_MEM_grow(enc_nonce, 16);
enc_nonce->length = 16, memcpy(enc_nonce->data, pbRecvBuffer + 4, 16);
PACE_STEP2_dec_nonce(pcd_ctx, secret, enc_nonce);
}
// STEP 2.2 – General Authenticate (Map Nonce)
{
unsigned char msg[9 + 0x61 + 1] = {0x10, 0x86, 0x00, 0x00, 0x65, 0x7C, 0x63, 0x81, 0x61, [9 + 0x61] = 0x65};
BUF_MEM* pcd_mapping_data = PACE_STEP3A_generate_mapping_data(pcd_ctx);
memcpy(msg + 9, pcd_mapping_data->data, 0x61);
dwRecvLength = sizeof(pbRecvBuffer);
rv = SCardTransmit(hCard, SCARD_PCI_T1, msg, sizeof msg, NULL, pbRecvBuffer, &dwRecvLength);
CHECK("SCardTransmit", rv)
BUF_MEM* picc_mapping_data = BUF_MEM_new();
BUF_MEM_grow(picc_mapping_data, 0x61);
picc_mapping_data->length = 0x61, memcpy(picc_mapping_data->data, pbRecvBuffer + 4, 0x61);
PACE_STEP3A_map_generator(pcd_ctx, picc_mapping_data);
}
// STEP 2.3 – General Authenticate (Perform Key Agreement)
{
unsigned char msg[9 + 0x61 + 1] = {0x10, 0x86, 0x00, 0x00, 0x65, 0x7C, 0x63, 0x83, 0x61, [9 + 0x61] = 0x65};
pcd_ephemeral_pubkey = PACE_STEP3B_generate_ephemeral_key(pcd_ctx);
memcpy(msg + 9, pcd_ephemeral_pubkey->data, 0x61);
dwRecvLength = sizeof(pbRecvBuffer);
rv = SCardTransmit(hCard, SCARD_PCI_T1, msg, sizeof msg, NULL, pbRecvBuffer, &dwRecvLength);
CHECK("SCardTransmit", rv)
picc_ephemeral_pubkey = BUF_MEM_new();
BUF_MEM_grow(picc_ephemeral_pubkey, 0x61);
picc_ephemeral_pubkey->length = 0x61, memcpy(picc_ephemeral_pubkey->data, pbRecvBuffer + 4, 0x61);
PACE_STEP3B_compute_shared_secret(pcd_ctx, picc_ephemeral_pubkey);
}
PACE_STEP3C_derive_keys(pcd_ctx);
// STEP 2.4 – General Authenticate (Mutual Authentication)
{
unsigned char msg[9 + 8 + 1] = {0x00, 0x86, 0x00, 0x00, 0x0C, 0x7C, 0x0A, 0x85, 0x08, [9 + 8] = 0x0C};
BUF_MEM* pcd_token = PACE_STEP3D_compute_authentication_token(pcd_ctx, picc_ephemeral_pubkey);
BIO_dump_indent(bio, pcd_token->data, pcd_token->length, 4);
memcpy(msg + 9, pcd_token->data, 8);
dwRecvLength = sizeof(pbRecvBuffer);
rv = SCardTransmit(hCard, SCARD_PCI_T1, msg, sizeof msg, NULL, pbRecvBuffer, &dwRecvLength);
CHECK("SCardTransmit", rv)
BUF_MEM* picc_token = BUF_MEM_new();
BUF_MEM_grow(picc_token, 8);
picc_token->length = 8, memcpy(picc_token->data, pbRecvBuffer + 4, 8);
if (PACE_STEP3D_verify_authentication_token(pcd_ctx, picc_token) != 1) {
return 1;
}
printf("success\n");
}
return 0;
} |
OK, after some debugging I think that there might be some global state in the pkcs11 library, which is initialized by some nonstandard extensions. The function which orchestrate initialization process is outside the pkcs11 library and looks like it is anonymous Qt event handler. P.S. Am I right that sources of pkcs11 libraries should be opened. Original OpenSC are on LGPL |
@majkrzak You mean the supposedly modified libraries provided with the custom handling app? I would think so. Some OSS license notification should be provided with it as well. |
I've requested access to the LGPL licensed sourcecode, but in the response I've got follwoing information (my translation):
According to the https://www.gnu.org/licenses/gpl-violation.html copyright owners are the one who can take further actions. @alonbl @CardContact @dengert @frankmorgner @LudovicRousseau @martinpaljak @mtrojnar @szikora @viktorTarasov ? |
@majkrzak Do you mean a progress dealing with copyright infringement? This issue is "Add support for Polish e-dowód", which is clearly a separate topic. Please open a new issue for copyright infringement. Please include the full vendor's response, and not just your partial translation. Which LGPL-licensed files are affected? Who are the copyright holders for those files? I presume you listed the current OpenSC team members, which are not necessarily the same people who contributed to some specific LGPL-licensed files throughout the long history of the OpenSC project. |
@mtrojnar I had in my mind rearranging this ticket at the beginning of the year. I'll extract copyright issue separately. |
above, you've said that npa-tool doesn't work.
but your output doesn't indicate any error. Could you get a more verbose output ( |
do you have some documentation describing the detailed functionality of the card? |
Output of
|
@mtrojnar I'm a bit occupied nowadays, can you handle the ticket you mentioned? It seems that you might have more experience with topic like this. |
This comment has been minimized.
This comment has been minimized.
I just realized that the ASN.1 formatted response of the card is two bytes beyond the response buffer! In your example code above, you take 16 bytes from offset 4. So if you take
then you are actually taking Since you say that your code above worked successfully (taking However, this patch should make the card work until the above problem is resolved: diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c
index b1d660cc..83369304 100644
--- a/src/sm/sm-eac.c
+++ b/src/sm/sm-eac.c
@@ -642,8 +642,12 @@ static int eac_gen_auth_1_encrypted_nonce(sc_card_t *card,
sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Encrypted Nonce) response data", apdu.resp, apdu.resplen);
+ /* card seems to take SW as part of the mapping data. Need to contact the
+ * vendor, because this IS A PROBLEM */
+ apdu.resp[apdu.resplen] = apdu.sw1;
+ apdu.resp[apdu.resplen+1] = apdu.sw2;
if (!d2i_EAC_GEN_AUTH_PACE_R(&r_data,
- (const unsigned char **) &apdu.resp, apdu.resplen)) {
+ (const unsigned char **) &apdu.resp+2, apdu.resplen)) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse general authenticate response data.");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
`` |
@frankmorgner I went through your post and one of my pervious one: #1831 (comment) If you take a look you will see that my code and official app makes a request:
while your code is sending:
I would call it interesting, cause Is there everything fine? Generally Polish e-id seem to not be able to handle data length in long form ( Is this TODO releated? Line 69 in 75847f4
|
Uff, I've managed to identify why it is happening like that. Polish eID do not work with Extended APDU-s, at least in this step. Max response length is set to 65 536 which causes the request length is also send in extended format. Line 615 in b6be87a
Can it be safely changed to the classic limit? Or maybe made dependent on the card attributes? |
P.S. |
I've make some test with SC_MAX_EXT_APDU_RESP_SIZE changed to SC_MAX_APDU_RESP_SIZE.
|
I wasn't aware of a ban. That's fixed now. Fine to hear that your card technically works now. The changes to your
|
Result is similar. Probably I have to start setting up new card driver for it.
|
I've made some investigation on a dump from PCSC while running the app (fetching personal data from the card and all the certs): I don't know exactly what is going there, but what is interesting for me is that PACE is established two times and that between that Do you think that there is some useful data that might help to recreate the driver? |
Googled for: ISO 7816 AID A0 00 00 01 67 45 53 49 47 4E |
I'm slowly implementing the driver, but now got stuck on generating first MSE command, which form some reason is missing Cryptographic mechanism reference part. @frankmorgner do you know what might be wrong? (I'll try to publish some sane WIP code still today)
Similar part in npa_tool results in:
SOLVED
|
I've made some basic driver based on @frankmorgner pkcs15-tool.log |
I'll try to attach somewhere in here:
|
I've also noticed that with: LOG_TEST_RET(card->ctx, _sc_card_add_ec_alg(
card, 384,
SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDSA_HASH_NONE,
SC_ALGORITHM_EXT_EC_NAMEDCURVE,
&(struct sc_object_id) {{1, 3, 132, 0, 34, -1}}
), "Add ec alg failed");
(0x1041) is tried When SHA1 is used, the request uses correct alg, but it allso fails
The issue I see is that |
I need explanation what is going on here in the log of
|
Try adding
|
Result looks very similar 😞 |
I've omitted the |
Not the prettiest , but unPACEed dump of
oryginal sec env data: |
Yupi 😊 another small step forward. It looks like I managed to make a signature. At least response from he card is positive, but OpenSC died on iso_sm due to the wrong length. Security environment had to be established in slightly different way, and key DF had to be selected. I've changed a logic a bit, because even if, the last two bytes were not referring the EF but DF in that case. I'm not sure how they should be distinguished, but About SM, @frankmorgner might it be similar issue to the one you had fixed couple days ago?
|
If I will get some clues how to resolve above sm issue, I might be able to push it forward during the weekend. |
@majkrzak |
@wiedzmin26 It seems that the my implementation is able to trigger the signature on the card. Issue is with receiving it from the card. Probably due to the some error or incompatibility in the iso-sm. Figuring this out is beyond my capabilities, I hope @frankmorgner or someone familiar with the topic will take a look into it or give me some clues. |
The SM stuff looks all fine. However, it appears that the card sends more data than you've requested. You requested Try using a bigger response buffer when requesting the signature. libedowod.so uses |
Looks that case CKK_EC:
/* TODO: -DEE we should use something other then CKA_MODULUS_BITS... */
rv = key->ops->get_attribute(operation->session, key, &attr);
*pLength = ((*pLength + 7)/8) * 2 ; /* 2*nLen in bytes */
break; After hardcoding Received signature looks correct
I'm not sure, but it might be that ASN1 wrapper around signature was not expected 🤔 Looks like i found answer in ISO applet implementation |
Yep, it works. 💪
I'll deliver initial PR by the end of the weekend. |
You could add the fix as general improvement. |
@majkrzak Good Job :) |
@majkrzak Hi, while trying to use your solution i stumbled into a problem, when i run pkcs15-tool -D or pkcs11-tool --test --login I'm getting:
Can you give me a hint what should i do with that? Part of the log:
|
The ASN1 says "preferred Language" is "706C2D504C" in ASCII: pl-PL pkcs15.c has:
Why it sets the limit to 3 is not clear. Or do something like this untested diff: Note the same could be done for options that also end up using strdup. |
Resurrecting topic. Hi @majkrzak; currently working in this context. Wanted to ask - what is the status of the technical specification of polish edo card. Is it publicly available? |
@polishcode I'm not aware about that. Personally I doubt if it even exists. As far as I remember edo is more or less compliant with some international standards, so for example german resources may be treated as some kind of documentation. |
Thanks for response. Yeah, have the same impression. Taxpayers' money well spent :/ Additional facts I found surprising in the current eDO implementation:
|
Hi @majkrzak I just got a fresh new e-dowód and thought I could perhaps use your driver. Unfortunately it does not seem to work.
opensc.conf
I'm happy to provide any other logs/information/etc. Environment: Thanks |
Based on the result from |
I guess
I may be able to figure out something about 2.0, we'll see. |
initial support was integrated long ago. for bug reports (or support for new versions of the card please open a new issue) |
Background
Since March 2019 new Polish ID card with electronic layer is available.
It contains some general information about ID holder like name, personal evidence number, photo etc. Also three default keys and certificates together with place for cusom ones.
With offical pkcs11 lib (which is opensc based see #1992 ) they are displayed as separate tokens:
Card does not have contact interface and is protected with PACEv2 in probably similar way as German one.
Will be glad to get your assistance and guidance, so I can handle this issue and add new supported card.
Subtasks
src/libopensc/card-npa.c
)Attachments
Polish
Engilsh
The text was updated successfully, but these errors were encountered: