BOOL ReaderLeds(const char *szReaderName, BYTE red, BYTE green, BYTE blue) { BYTE c_apdu[256]; DWORD c_apdu_len; BYTE r_apdu[256]; DWORD r_apdu_len; CARD_CHANNEL_T Channel = { 0 }; BOOL rc = FALSE; Channel.bSilent = TRUE; /* Try to connect to the card in the reader (if there's one) */ if (CardConnect(szReaderName, &Channel)) { /* Card connected, use the APDU method */ c_apdu_len = 0; c_apdu[c_apdu_len++] = 0xFF; c_apdu[c_apdu_len++] = 0xF0; c_apdu[c_apdu_len++] = 0x00; c_apdu[c_apdu_len++] = 0x00; c_apdu[c_apdu_len++] = 4; c_apdu[c_apdu_len++] = 0x1E; c_apdu[c_apdu_len++] = red; c_apdu[c_apdu_len++] = green; c_apdu[c_apdu_len++] = blue; r_apdu_len = sizeof(r_apdu); rc = CardTransmit(&Channel, c_apdu, c_apdu_len, r_apdu, &r_apdu_len); CardDisconnect(&Channel, SCARD_LEAVE_CARD); } if (!rc) { /* No card in the reader (or any other error...) try a direct connection to the reader itself */ if (ReaderConnect(szReaderName, &Channel)) { c_apdu_len = 0; c_apdu[c_apdu_len++] = 0x58; c_apdu[c_apdu_len++] = 0x1E; c_apdu[c_apdu_len++] = red; c_apdu[c_apdu_len++] = green; c_apdu[c_apdu_len++] = blue; r_apdu_len = sizeof(r_apdu); rc = ReaderControl(&Channel, c_apdu, c_apdu_len, r_apdu, &r_apdu_len); CardDisconnect(&Channel, SCARD_LEAVE_CARD); } } return rc; }
int main(int argc, const char *argv[]) { nfc_device *pnd; nfc_target nt; nfc_context *context; nfc_init(&context); printf("\nRunning checks...\n"); if (context == NULL) { printf("Unable to init libnfc (malloc)\n"); exit(EXIT_FAILURE); } const char *acLibnfcVersion = nfc_version(); (void)argc; printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion); pnd = nfc_open(context, NULL); if (pnd == NULL) { printf("ERROR: %s", "Unable to open NFC device."); exit(EXIT_FAILURE); } if (nfc_initiator_init(pnd) < 0) { nfc_perror(pnd, "nfc_initiator_init"); exit(EXIT_FAILURE); } printf("NFC reader: %s opened\n", nfc_device_get_name(pnd)); const nfc_modulation nmMifare = { .nmt = NMT_ISO14443A, .nbr = NBR_106, }; // nfc_set_property_bool(pnd, NP_AUTO_ISO14443_4, true); printf("Polling for target...\n"); while (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0); printf("Target detected! Running command set...\n\n"); uint8_t capdu[264]; size_t capdulen; uint8_t rapdu[264]; size_t rapdulen; // Select application memcpy(capdu, "\x00\xA4\x04\x00\x07\xF0\x39\x41\x48\x14\x81\x00\x00", 13); capdulen=13; rapdulen=sizeof(rapdu); printf("Sending ADPU SELECT...\n"); if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) { exit(EXIT_FAILURE); } if (rapdulen < 2 || rapdu[rapdulen-2] != 0x90 || rapdu[rapdulen-1] != 0x00) { exit(EXIT_FAILURE); } printf("Application selected!\n\n"); // Select Capability Container memcpy(capdu, "\x00\xa4\x00\x0c\x02\xe1\x03", 7); capdulen=7; rapdulen=sizeof(rapdu); printf("Sending CC SELECT...\n"); if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) exit(EXIT_FAILURE); if (rapdulen < 2 || rapdu[rapdulen-2] != 0x90 || rapdu[rapdulen-1] != 0x00) { capdu[3]='\x00'; // Maybe an older Tag4 ? if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) exit(EXIT_FAILURE); } printf("Capability Container selected!\n\n"); // Read Capability Container memcpy(capdu, "\x00\xb0\x00\x00\x0f", 5); capdulen=5; rapdulen=sizeof(rapdu); printf("Sending ReadBinary from CC...\n"); if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) exit(EXIT_FAILURE); if (rapdulen < 2 || rapdu[rapdulen-2] != 0x90 || rapdu[rapdulen-1] != 0x00) exit(EXIT_FAILURE); printf("\nCapability Container header:\n"); size_t szPos; for (szPos = 0; szPos < rapdulen-2; szPos++) { printf("%02x ", rapdu[szPos]); } printf("\n\n"); // NDEF Select memcpy(capdu, "\x00\xa4\x00\x0C\x02\xE1\x04", 7); capdulen=7; rapdulen=sizeof(rapdu); printf("Sending NDEF Select...\n"); if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) exit(EXIT_FAILURE); if (rapdulen < 2 || rapdu[rapdulen-2] != 0x90 || rapdu[rapdulen-1] != 0x00) exit(EXIT_FAILURE); printf("\n"); // ReadBinary memcpy(capdu, "\x00\xb0\x00\x00\x02", 5); capdulen=5; rapdulen=sizeof(rapdu); printf("Sending ReadBinary NLEN...\n"); if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) exit(EXIT_FAILURE); if (rapdulen < 2 || rapdu[rapdulen-2] != 0x90 || rapdu[rapdulen-1] != 0x00) exit(EXIT_FAILURE); printf("\n"); // ReadBinary - Get NDEF data memcpy(capdu, "\x00\xb0\x00\x00\x0f", 5); capdulen=5; rapdulen=sizeof(rapdu); printf("Sending ReadBinary, get NDEF data...\n"); if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) exit(EXIT_FAILURE); if (rapdulen < 2 || rapdu[rapdulen-2] != 0x90 || rapdu[rapdulen-1] != 0x00) exit(EXIT_FAILURE); printf("\n"); printf("Wrapping up, closing session.\n\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_SUCCESS); }
void nfcProtocol() { char message[1024]; char UAFMessage[2048]; memoryStruct chunk; uint8_t capdu[264]; size_t capdulen; uint8_t rapdu[264]; size_t rapdulen; char *response = 0; const nfc_modulation nmMifare = { .nmt = NMT_ISO14443A, .nbr = NBR_106, }; printf("Polling for target...\n"); while (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0); printf("Target detected!\n"); // Select application memcpy(capdu, APDU, sizeof (APDU)); capdulen = sizeof (APDU); // 13 rapdulen = sizeof (rapdu); if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) exit(EXIT_FAILURE); printf("Application selected!\n"); if (strncmp(rapdu, DOOR_HELLO, (int) rapdulen)) { printf("** Opss ** I'm expecting HELLO msg, but card sent to me: %s. len: %d\n", response, (int) rapdulen); return; } // FIDO Auth Request Message printf("Doing AuthRequest to FIDO UAF Server\n"); sprintf(UAFMessage, AUTH_REQUEST_MSG, SCHEME, HOSTNAME, PORT, AUTH_REQUEST_ENDPOINT); chunk = getHttpRequest(UAFMessage); if (chunk.size <= 0) { printf("** Opss ** Error to connect to FIDO Server\n"); memcpy(capdu, "ERROR", 5); capdulen = 5; rapdulen = sizeof (rapdu); if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) { printf("Error to sent error message to card...\n"); } return; } size_t blocks = (chunk.size / BLOCK_SIZE) + 1; char *buffer[blocks]; blockSplit(chunk.memory, buffer, blocks); sprintf(message, "BLOCK:%ld", blocks); printf("Sending number of blocks: %s\n", message); free(chunk.memory); memcpy(capdu, message, strlen(message)); capdulen = strlen(message); rapdulen = sizeof (rapdu); if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) { printf("Error to send number of blocks\n"); return; } int totalSent = 0; if (strncmp(rapdu, DOOR_NEXT, (int) rapdulen)) { printf("** Opss ** I'm expecting NEXT msg, but card sent to me: %s. len: %d", response, (int) rapdulen); return; } response = NULL; do { // Sending UAFRequestMessage to card memcpy(capdu, buffer[totalSent], strlen(buffer[totalSent])); capdulen = strlen(buffer[totalSent]); rapdulen = sizeof (rapdu); if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) { int i = strlen(buffer[totalSent]); printf("error to send UAFRequestMessage to card. Message size: %d, message: %s\n", i, buffer[totalSent]); return; } if (strncmp(rapdu, DOOR_OK, (int) rapdulen)) { printf("** Opss ** I'm expecting OK msg, but card sent to me: %s. len: %d", response, (int) rapdulen); return; } response = NULL; free(buffer[totalSent]); totalSent++; } while (totalSent < blocks); printf("Sending READY!\n"); memcpy(capdu, DOOR_READY, sizeof (DOOR_READY)); capdulen = strlen(DOOR_READY); rapdulen = sizeof (rapdu); unsigned long timeout = LONG_MAX; do { if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) { printf("Error to received WAIT\n"); return; } if (strncmp(rapdu, DOOR_WAIT, (int) rapdulen) == 0) { continue; } if (strncmp(rapdu, DOOR_DONE, (int) rapdulen) == 0) { printf("Sending RESPONSE!\n"); memcpy(capdu, DOOR_RESPONSE, sizeof (DOOR_RESPONSE)); capdulen = strlen(DOOR_RESPONSE); rapdulen = sizeof (rapdu); if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) { printf("Error RESPONSE...\n"); return; } break; } timeout--; } while (timeout > 0); if (timeout == 0) { printf("Error. Client is not responding...\n"); return; } strncpy(message, rapdu, (int) rapdulen); char *p = strtok(message, ":"); char *endptr; long val; if (strcmp(p, "BLOCK") == 0) { p = strtok(NULL, ":"); val = strtol(p, &endptr, 10); char *UAFmsg = malloc(sizeof (char) * BLOCK_SIZE * val + 1); UAFmsg[0] = '\0'; do { printf("Sending NEXT!\n"); memcpy(capdu, DOOR_NEXT, sizeof (DOOR_NEXT)); capdulen = strlen(DOOR_NEXT); rapdulen = sizeof (rapdu); if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) { printf("Error NEXT\n"); return; } strncat(UAFmsg, rapdu, (int) rapdulen); val--; } while (val > 0); // FIDO Auth Request Message printf("Forwarding card response to FIDO UAF Server: \n"); sprintf(UAFMessage, AUTH_REQUEST_MSG, SCHEME, HOSTNAME, PORT, AUTH_RESPONSE_ENDPOINT); //curlFetchStruct *result = postHttpRequest(UAFMessage, UAFmsg); json_object *result = postHttpRequest(UAFMessage, UAFmsg); free(UAFmsg); // if (result->size <= 0) { if (result == NULL) { printf("Error to connect to FIDO Server\n"); memcpy(capdu, "ERROR", 5); capdulen = 5; rapdulen = sizeof (rapdu); if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) { printf("Error to send response to card\n"); } return; } printf("Resul payload: %s \n", json_object_to_json_string(result)); const char *resultStr = json_object_to_json_string(result); if (strstr(resultStr, "SUCCESS") == NULL) { printf("Access denied!\n"); memcpy(capdu, DOOR_DENY, sizeof (DOOR_DENY)); capdulen = strlen(DOOR_DENY); rapdulen = sizeof (rapdu); if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) { return; } } else { printf("Access granted!\n"); memcpy(capdu, DOOR_GRANTED, sizeof (DOOR_GRANTED)); capdulen = strlen(DOOR_GRANTED); rapdulen = sizeof (rapdu); if (CardTransmit(pnd, capdu, capdulen, rapdu, &rapdulen) < 0) { return; } doorlock(1); doorlock(0); } /* free json object */ json_object_put(result); strncpy(message, rapdu, (int) rapdulen); if (strstr(message, "BYE") != NULL) { printf("bye!\n"); } else { printf(":-(\n"); } } }