Commit d73b64d8 authored by Jakub Jelen's avatar Jakub Jelen Committed by Marc-André Lureau

cac, cac-aca: Implement other undocumented encoding for extended properties

 * These modifiers nor format is not documented anywhere, but ActivClient
   expects them and cards happily answer them
 * This is a kind of more compressed form of other ACA buffers, but it is
   extended with some additional values of unknown meaning.
 * This is somehow consistent with the standard GET ACR parameters, but if
   P1 | 0x40 is set, the response should come in this new format.
 * This affects also GET PROPERTIES APDU, where we get also other bunch of
   TLVs in case of this bit is set.
Signed-off-by: default avatarJakub Jelen <jjelen@redhat.com>
Reviewed-by: default avatarRobert Relyea <rrelyea@redhat.com>
Message-Id: <20180802094407.4104-29-jjelen@redhat.com>
parent 08c347c1
This diff is collapsed.
......@@ -19,14 +19,15 @@
#include <string.h>
VCardResponse *
cac_aca_get_acr_response(VCard *card, int Le, unsigned char *acrid);
cac_aca_get_acr_response(VCard *card, int Le, unsigned char *acrid, int format);
VCardResponse *
cac_aca_get_applet_acr_response(VCard *card, int Le, unsigned int pki_applets,
unsigned char *aid, unsigned int aid_len,
unsigned char *coid);
unsigned char *coid, int format);
VCardResponse *
cac_aca_get_amp_response(VCard *card, int Le);
cac_aca_get_amp_response(VCard *card, int Le, int format);
VCardResponse *
cac_aca_get_service_response(VCard *card, int Le, unsigned int pki_applets);
cac_aca_get_service_response(VCard *card, int Le, unsigned int pki_applets,
int format);
This diff is collapsed.
/*
* defines the entry point for the cac card. Only used by cac.c anc
* defines the entry point for the cac card. Only used by cac.c and
* vcard_emul_type.c
*
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
......@@ -64,6 +64,10 @@
#define CAC_PROPERTIES_TV_OBJECT 0x50
#define CAC_PROPERTIES_PKI_OBJECT 0x51
/* Buffer formats */
#define CAC_FORMAT_SIMPLETLV 1
#define CAC_FORMAT_EXTENDED 2
/*
* Initialize the cac card. This is the only public function in this file. All
......
......@@ -102,11 +102,11 @@ void get_properties_coid(VReader *reader, const unsigned char coid[2],
VReaderStatus status;
uint8_t pbRecvBuffer[APDUBufSize], *p, *p_end, *p2, *p2_end;
uint8_t get_properties[] = {
/* Get properties */
/* Get properties [Le] */
0x80, 0x56, 0x01, 0x00, 0x00
};
uint8_t get_properties_tag[] = {
/* Get properties [tag list] */
/* Get properties [tag list] [Le] */
0x80, 0x56, 0x02, 0x00, 0x02, 0x01, 0x01, 0x00
};
int verified_pki_properties = 0;
......@@ -203,6 +203,11 @@ void get_properties_coid(VReader *reader, const unsigned char coid[2],
verified_pki_properties = 1;
break;
case 0x26:
g_assert_cmpint(vlen2, ==, 1);
g_assert_cmphex(p2[0], ==, 0x01);
break;
default:
g_debug("Unknown tag in object: 0x%02x", tag2);
g_assert_not_reached();
......@@ -212,6 +217,16 @@ void get_properties_coid(VReader *reader, const unsigned char coid[2],
/* one more object processed */
num_objects++;
break;
case 0x39:
g_assert_cmpint(vlen, ==, 1);
g_assert_cmphex(p[0], ==, 0x00);
break;
case 0x3A:
g_assert_cmpint(vlen, ==, 7);
break;
default:
g_debug("Unknown tag in properties buffer: 0x%02x", tag);
g_assert_not_reached();
......@@ -257,6 +272,32 @@ void get_properties_coid(VReader *reader, const unsigned char coid[2],
g_assert_cmpint(dwRecvLength, ==, 16); /* Two applet information buffers + status */
g_assert_cmpint(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
g_assert_cmpint(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
/* Test the undocumented P1 = 0x40 */
dwRecvLength = APDUBufSize;
get_properties[2] = 0x40;
get_properties[4] = 0x00;
status = vreader_xfr_bytes(reader,
get_properties, sizeof(get_properties),
pbRecvBuffer, &dwRecvLength);
g_assert_cmpint(status, ==, VREADER_OK);
/* for too long Le, the cards return LE_ERROR with correct length to ask */
g_assert_cmpint(dwRecvLength, ==, 2);
g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_LE_ERROR);
g_assert_cmpint(pbRecvBuffer[1], !=, 0x00);
/* Update the APDU to match Le field from response and resend */
get_properties[4] = pbRecvBuffer[1];
dwRecvLength = APDUBufSize;
status = vreader_xfr_bytes(reader,
get_properties, sizeof(get_properties),
pbRecvBuffer, &dwRecvLength);
g_assert_cmpint(status, ==, VREADER_OK);
g_assert_cmpint(dwRecvLength, >, 2);
g_assert_cmpint(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
g_assert_cmpint(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
}
void get_properties(VReader *reader, int object_type)
......
......@@ -388,6 +388,62 @@ static void get_acr(VReader *reader)
/* parse the response */
parse_acr(pbRecvBuffer, dwRecvLength);
/* Undocumented 0x40 returns ACR in different encoding */
get_acr[2] = 0x40;
dwRecvLength = APDUBufSize;
status = vreader_xfr_bytes(reader,
get_acr, sizeof(get_acr),
pbRecvBuffer, &dwRecvLength);
g_assert_cmpint(status, ==, VREADER_OK);
g_assert_cmpint(dwRecvLength, >, 2);
g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
/* parse the response */
//parse_acr(pbRecvBuffer, dwRecvLength);
/* Undocumented 0x50 returns Applet/Object ACR in different encoding */
get_acr[2] = 0x50;
dwRecvLength = APDUBufSize;
status = vreader_xfr_bytes(reader,
get_acr, sizeof(get_acr),
pbRecvBuffer, &dwRecvLength);
g_assert_cmpint(status, ==, VREADER_OK);
g_assert_cmpint(dwRecvLength, ==, 2);
g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_RESPONSE_BYTES);
g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
/* parse the response */
//parse_acr(pbRecvBuffer, dwRecvLength);
/* Undocumented 0x60 returns AMP in different encoding */
get_acr[2] = 0x60;
dwRecvLength = APDUBufSize;
status = vreader_xfr_bytes(reader,
get_acr, sizeof(get_acr),
pbRecvBuffer, &dwRecvLength);
g_assert_cmpint(status, ==, VREADER_OK);
g_assert_cmpint(dwRecvLength, >, 2);
g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
/* parse the response */
//parse_acr(pbRecvBuffer, dwRecvLength);
/* Undocumented 0x61 returns Service Applet in different encoding */
get_acr[2] = 0x61;
dwRecvLength = APDUBufSize;
status = vreader_xfr_bytes(reader,
get_acr, sizeof(get_acr),
pbRecvBuffer, &dwRecvLength);
g_assert_cmpint(status, ==, VREADER_OK);
g_assert_cmpint(dwRecvLength, >, 2);
g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
/* parse the response */
//parse_acr(pbRecvBuffer, dwRecvLength);
}
static void do_login(VReader *reader)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment