diff --git a/openpgp.c b/openpgp.c index f4f89f1..910abc1 100644 --- a/openpgp.c +++ b/openpgp.c @@ -169,16 +169,21 @@ void process_fci(const pkcs15_entry_t *pe) { res_APDU[1] = res_APDU_size-2; } -uint8_t t[] = { +const uint8_t t[] = { 0x01,0xbb, 0x7F,0x21,0x82,0x01,0xB6,0x7F,0x4E,0x82,0x01,0x6E,0x5F,0x29,0x01,0x00,0x42,0x0E,0x44,0x45,0x43,0x56,0x43,0x41,0x65,0x49,0x44,0x30,0x30,0x31,0x30,0x32,0x7F,0x49,0x82,0x01,0x1D,0x06,0x0A,0x04,0x00,0x7F,0x00,0x07,0x02,0x02,0x02,0x02,0x03,0x81,0x20,0xA9,0xFB,0x57,0xDB,0xA1,0xEE,0xA9,0xBC,0x3E,0x66,0x0A,0x90,0x9D,0x83,0x8D,0x72,0x6E,0x3B,0xF6,0x23,0xD5,0x26,0x20,0x28,0x20,0x13,0x48,0x1D,0x1F,0x6E,0x53,0x77,0x82,0x20,0x7D,0x5A,0x09,0x75,0xFC,0x2C,0x30,0x57,0xEE,0xF6,0x75,0x30,0x41,0x7A,0xFF,0xE7,0xFB,0x80,0x55,0xC1,0x26,0xDC,0x5C,0x6C,0xE9,0x4A,0x4B,0x44,0xF3,0x30,0xB5,0xD9,0x83,0x20,0x26,0xDC,0x5C,0x6C,0xE9,0x4A,0x4B,0x44,0xF3,0x30,0xB5,0xD9,0xBB,0xD7,0x7C,0xBF,0x95,0x84,0x16,0x29,0x5C,0xF7,0xE1,0xCE,0x6B,0xCC,0xDC,0x18,0xFF,0x8C,0x07,0xB6,0x84,0x41,0x04,0x8B,0xD2,0xAE,0xB9,0xCB,0x7E,0x57,0xCB,0x2C,0x4B,0x48,0x2F,0xFC,0x81,0xB7,0xAF,0xB9,0xDE,0x27,0xE1,0xE3,0xBD,0x23,0xC2,0x3A,0x44,0x53,0xBD,0x9A,0xCE,0x32,0x62,0x54,0x7E,0xF8,0x35,0xC3,0xDA,0xC4,0xFD,0x97,0xF8,0x46,0x1A,0x14,0x61,0x1D,0xC9,0xC2,0x77,0x45,0x13,0x2D,0xED,0x8E,0x54,0x5C,0x1D,0x54,0xC7,0x2F,0x04,0x69,0x97,0x85,0x20,0xA9,0xFB,0x57,0xDB,0xA1,0xEE,0xA9,0xBC,0x3E,0x66,0x0A,0x90,0x9D,0x83,0x8D,0x71,0x8C,0x39,0x7A,0xA3,0xB5,0x61,0xA6,0xF7,0x90,0x1E,0x0E,0x82,0x97,0x48,0x56,0xA7,0x86,0x41,0x04,0x33,0x47,0xEC,0xF9,0x6F,0xFB,0x4B,0xD9,0xB8,0x55,0x4E,0xFB,0xCC,0xFC,0x7D,0x0B,0x24,0x2F,0x10,0x71,0xE2,0x9B,0x4C,0x9C,0x62,0x2C,0x79,0xE3,0x39,0xD8,0x40,0xAF,0x67,0xBE,0xB9,0xB9,0x12,0x69,0x22,0x65,0xD9,0xC1,0x6C,0x62,0x57,0x3F,0x45,0x79,0xFF,0xD4,0xDE,0x2D,0xE9,0x2B,0xAB,0x40,0x9D,0xD5,0xC5,0xD4,0x82,0x44,0xA9,0xF7,0x87,0x01,0x01,0x5F,0x20,0x0E,0x44,0x45,0x43,0x56,0x43,0x41,0x65,0x49,0x44,0x30,0x30,0x31,0x30,0x32,0x7F,0x4C,0x12,0x06,0x09,0x04,0x00,0x7F,0x00,0x07,0x03,0x01,0x02,0x02,0x53,0x05,0xFE,0x0F,0x01,0xFF,0xFF,0x5F,0x25,0x06,0x01,0x00,0x01,0x00,0x01,0x08,0x5F,0x24,0x06,0x01,0x03,0x01,0x00,0x01,0x08,0x5F,0x37,0x40,0x50,0x67,0x14,0x5C,0x68,0xCA,0xE9,0x52,0x0F,0x5B,0xB3,0x48,0x17,0xF1,0xCA,0x9C,0x43,0x59,0x3D,0xB5,0x64,0x06,0xC6,0xA3,0xB0,0x06,0xCB,0xF3,0xF3,0x14,0xE7,0x34,0x9A,0xCF,0x0C,0xC6,0xBF,0xEB,0xCB,0xDE,0xFD,0x10,0xB4,0xDC,0xF0,0xF2,0x31,0xDA,0x56,0x97,0x7D,0x88,0xF9,0xF9,0x01,0x82,0xD1,0x99,0x07,0x6A,0x56,0x50,0x64,0x51 }; +const uint8_t token_info[] = { + 0x0, 0x1f, + 0x30, 0x1d, 0x2, 0x1, 0x2, 0x4, 0x4, 0x6, 0x0, 0x0, 0x0, 0xc, 0x6, 0x4d, 0x61, 0x6e, 0x75, 0x49, 0x44, 0x80, 0x6, 0x50, 0x61, 0x74, 0x61, 0x74, 0x61, 0x3, 0x2, 0x7, 0x80 +}; const pkcs15_entry_t pkcs15_entries[] = { { .fid = 0x3f00, .parent = 0xff, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, .ef_structure = 0, .acl = {0} }, // MF { .fid = 0x2f00, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.DIR { .fid = 0x2f01, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.ATR { .fid = 0x2f02, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF,.data = t, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.GDO + { .fid = 0x2f03, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF,.data = token_info, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.TokenInfo { .fid = 0x5015, .parent = 0, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, .ef_structure = 0, .acl = {0} }, //DF.PKCS15 { .fid = 0x5031, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.ODF { .fid = 0x5032, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.TokenInfo @@ -189,7 +194,9 @@ const pkcs15_entry_t pkcs15_entries[] = { }; const pkcs15_entry_t *MF = &pkcs15_entries[0]; -const pkcs15_entry_t *pkcs15_last = &pkcs15_entries[sizeof(pkcs15_entries)/sizeof(pkcs15_entry_t)]; +const pkcs15_entry_t *pkcs15_last = &pkcs15_entries[sizeof(pkcs15_entries)/sizeof(pkcs15_entry_t)-1]; +const pkcs15_entry_t *pkcs15_openpgp = &pkcs15_entries[sizeof(pkcs15_entries)/sizeof(pkcs15_entry_t)-3]; +const pkcs15_entry_t *pkcs15_sc_hsm = &pkcs15_entries[sizeof(pkcs15_entries)/sizeof(pkcs15_entry_t)-2]; extern const pkcs15_entry_t *search_by_fid(const uint16_t, const pkcs15_entry_t *, const uint8_t); @@ -267,6 +274,7 @@ const pkcs15_entry_t *search_by_path(const uint8_t *pe_path, uint8_t pathlen, co uint8_t file_selection; const pkcs15_entry_t *currentEF = NULL; const pkcs15_entry_t *currentDF = NULL; +const pkcs15_entry_t *selected_applet = NULL; bool isUserAuthenticated = false; bool authenticate_action(const pkcs15_entry_t *ef, uint8_t op) { @@ -325,86 +333,90 @@ get_pinpad_input (int msg_code) } #endif -static void -cmd_verify (queue_t *ccid_comm) +static int cmd_verify (queue_t *ccid_comm) { - int len; - uint8_t p1 = P1 (apdu); - uint8_t p2 = P2 (apdu); - int r; - const uint8_t *pw; - - (void)ccid_comm; - DEBUG_INFO (" - VERIFY\r\n"); - DEBUG_BYTE (p2); - - len = apdu.cmd_apdu_data_len; - pw = apdu.cmd_apdu_data; - - if (len == 0) - { - if (p1 == 0) - { /* This is to examine status. */ - if (p2 == 0x81) - r = ac_check_status (AC_PSO_CDS_AUTHORIZED); - else if (p2 == 0x82) - r = ac_check_status (AC_OTHER_AUTHORIZED); - else - r = ac_check_status (AC_ADMIN_AUTHORIZED); - - if (r) - /* If authentication done already, return success. */ - GPG_SUCCESS (); - else - { /* If not, return retry counter, encoded. */ - r = gpg_pw_get_retry_counter (p2); - set_res_sw (0x63, 0xc0 | (r&0x0f)); - } - } - else if (p1 == 0xff) - { /* Reset the status. */ - if (p2 == 0x81) - ac_reset_pso_cds (); - else if (p2 == 0x82) - ac_reset_other (); - else - ac_reset_admin (); - GPG_SUCCESS (); - } - else - GPG_BAD_P1_P2 (); - return; + int len; + uint8_t p1 = P1 (apdu); + uint8_t p2 = P2 (apdu); + int r; + const uint8_t *pw; + + (void)ccid_comm; + DEBUG_INFO (" - VERIFY\r\n"); + DEBUG_BYTE (p2); + + len = apdu.cmd_apdu_data_len; + pw = apdu.cmd_apdu_data; + printf("%X %X %X\r\n",selected_applet,pkcs15_openpgp,pkcs15_sc_hsm); + + if (selected_applet == pkcs15_openpgp) { + if (len == 0) + { + if (p1 == 0) + { /* This is to examine status. */ + if (p2 == 0x81) + r = ac_check_status (AC_PSO_CDS_AUTHORIZED); + else if (p2 == 0x82) + r = ac_check_status (AC_OTHER_AUTHORIZED); + else + r = ac_check_status (AC_ADMIN_AUTHORIZED); + + if (r) + /* If authentication done already, return success. */ + return GPG_SUCCESS (); + else + { /* If not, return retry counter, encoded. */ + r = gpg_pw_get_retry_counter (p2); + set_res_sw (0x63, 0xc0 | (r&0x0f)); + } + } + else if (p1 == 0xff) + { /* Reset the status. */ + if (p2 == 0x81) + ac_reset_pso_cds (); + else if (p2 == 0x82) + ac_reset_other (); + else + ac_reset_admin (); + return GPG_SUCCESS (); + } + else + return GPG_BAD_P1_P2 (); + } + + if (gpg_do_kdf_check (len, 1) == 0) + { + return GPG_CONDITION_NOT_SATISFIED (); + } + + /* This is real authentication. */ + if (p2 == 0x81) + r = verify_pso_cds (pw, len); + else if (p2 == 0x82) + r = verify_other (pw, len); + else + r = verify_admin (pw, len); + + if (r < 0) + { + DEBUG_INFO ("failed\r\n"); + return GPG_SECURITY_FAILURE (); + } + else if (r == 0) + { + DEBUG_INFO ("blocked\r\n"); + return GPG_SECURITY_AUTH_BLOCKED (); + } + else + { + DEBUG_INFO ("good\r\n"); + return GPG_SUCCESS (); + } } - - if (gpg_do_kdf_check (len, 1) == 0) - { - GPG_CONDITION_NOT_SATISFIED (); - return; - } - - /* This is real authentication. */ - if (p2 == 0x81) - r = verify_pso_cds (pw, len); - else if (p2 == 0x82) - r = verify_other (pw, len); - else - r = verify_admin (pw, len); - - if (r < 0) - { - DEBUG_INFO ("failed\r\n"); - GPG_SECURITY_FAILURE (); - } - else if (r == 0) - { - DEBUG_INFO ("blocked\r\n"); - GPG_SECURITY_AUTH_BLOCKED (); - } - else - { - DEBUG_INFO ("good\r\n"); - GPG_SUCCESS (); + else if (selected_applet == pkcs15_sc_hsm) { + return GPG_BAD_P1_P2(); } + return 0; } int @@ -1021,6 +1033,8 @@ void select_file(const pkcs15_entry_t *pe) { else { currentDF = pe; } + if (currentEF == pkcs15_openpgp || currentEF == pkcs15_sc_hsm) + selected_applet = currentEF; } static uint16_t cmd_select_file (queue_t *ccid_comm) { @@ -1752,7 +1766,7 @@ process_command_apdu (queue_t *ccid_comm) && cmd != INS_SELECT_FILE && cmd != INS_ACTIVATE_FILE && cmd != INS_GET_CHALLENGE && cmd != INS_EXTERNAL_AUTHENTICATE) GPG_APPLICATION_TERMINATED (); - else if (file_selection != FILE_DF_SC_HSM + else if (selected_applet == NULL && cmd != INS_SELECT_FILE && cmd != INS_ACTIVATE_FILE && cmd != INS_GET_CHALLENGE && cmd != INS_EXTERNAL_AUTHENTICATE && cmd != INS_WRITE_BINARY && cmd != INS_UPDATE_BINARY