mirror of
https://gitlab.com/fabinfra/fabaccess/borepin.git
synced 2025-03-12 23:01:52 +01:00
Added: PCSC Implementation
This commit is contained in:
parent
2034c08d33
commit
187dfc4f4a
28
Borepin.sln
28
Borepin.sln
@ -15,7 +15,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Borepin.GTK", "Borepin\Bore
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Borepin.macOS", "Borepin\Borepin.macOS\Borepin.macOS.csproj", "{3EC23FE7-395E-4BBC-B56B-9455354BDA34}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFC", "NFC\NFC.csproj", "{72DAC306-D4B2-4DBF-9C32-317203FD5D61}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NFC", "NFC\NFC.csproj", "{72DAC306-D4B2-4DBF-9C32-317203FD5D61}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFC_Test", "NFC_Test\NFC_Test.csproj", "{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -249,6 +251,30 @@ Global
|
||||
{72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|x64.Build.0 = Release|Any CPU
|
||||
{72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|x86.Build.0 = Release|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|x64.Build.0 = Release|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
61
NFC/APDUCommand.cs
Normal file
61
NFC/APDUCommand.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NFC
|
||||
{
|
||||
public class APDUCommand
|
||||
{
|
||||
/// <summary>
|
||||
/// ISO 7816 - CLA - Class
|
||||
/// </summary>
|
||||
public byte Class { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ISO 7816 - INS - Instruction
|
||||
/// </summary>
|
||||
public byte Instruction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ISO 7816 - P1 - Parameter 1
|
||||
/// </summary>
|
||||
public byte Parameter1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ISO 7816 - P2 - Parameter 2
|
||||
/// </summary>
|
||||
public byte Parameter2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ISO 7816 - Lc - Length Command
|
||||
/// </summary>
|
||||
public byte LengthCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ISO 7816 - Data - Data
|
||||
/// </summary>
|
||||
public byte[] Data { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ISO 7816 - Le - Length expected
|
||||
/// </summary>
|
||||
public byte LengthExpected
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] APDUCommandMessage()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
108
NFC/APDUResponse.cs
Normal file
108
NFC/APDUResponse.cs
Normal file
@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using NFC.Mifare_DESFire;
|
||||
|
||||
namespace NFC
|
||||
{
|
||||
public class APDUResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// ISO 7816 - Body - Body
|
||||
/// </summary>
|
||||
public byte[] Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ISO 7816 - SW1 - Status Word 1
|
||||
/// </summary>
|
||||
public byte SW1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ISO 7816 - SW2 - Status Word 2
|
||||
/// </summary>
|
||||
public byte SW2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new APDUResponse from the raw received data.
|
||||
/// </summary>
|
||||
public APDUResponse(byte[] raw) {
|
||||
Body = raw.Take(raw.Length-1).ToArray();
|
||||
SW1 = raw[raw.Length - 2];
|
||||
SW2 = raw[raw.Length - 3];
|
||||
}
|
||||
|
||||
public APDUResponse()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public APDUStatusWords StatusWord
|
||||
{
|
||||
get
|
||||
{
|
||||
// Some status words only require a specific first byte
|
||||
// and in some cases SW2 contains additional information.
|
||||
// This will filter out those errors. When there is more information separate methods for getting those are available.
|
||||
switch(SW1) {
|
||||
case 0x61:
|
||||
// Kommando erfolgreich ausgeführt. xx Datenbytes können mit dem ‚GET RESPONSE‘-Kommando abgeholt werden. Statuswort zur Steuerung des T=0-Protokolls
|
||||
return APDUStatusWords.DATA_READY;
|
||||
case 0x62:
|
||||
// Warnung; Zustand des nichtflüchtigen Speichers nicht verändert
|
||||
return APDUStatusWords.STORAGE_NOT_CHANGED;
|
||||
case 0x63:
|
||||
if((SW2 & 0xF0) == 0xC0) {
|
||||
// Zähler hat den Wert x erreicht (die genaue Bedeutung ist vom Kommando abhängig)
|
||||
return APDUStatusWords.COUNTER_REACHED;
|
||||
}
|
||||
// Warnung; Zustand des nichtflüchtigen Speichers verändert
|
||||
return APDUStatusWords.STORAGE_CHANGED;
|
||||
case 0x64:
|
||||
// Ausführungsfehler; Zustand des nichtflüchtigen Speichers nicht verändert
|
||||
return APDUStatusWords.EXECUTION_ERROR_WITHOUT_CHANGE;
|
||||
case 0x65:
|
||||
// Ausführungsfehler; Zustand des nichtflüchtigen Speichers verändert
|
||||
return APDUStatusWords.EXECUTION_ERROR_WITH_CHANGE;
|
||||
case 0x6C:
|
||||
// Falsche Länge Le; xx gibt die korrekte Länge an Statuswort zur Steuerung des T=0-Protokolls
|
||||
return APDUStatusWords.INVALID_LE;
|
||||
}
|
||||
return (APDUStatusWords) (((UInt16) SW1) << 8 | ((UInt16) SW2));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the reponse status is DATA_READY this method can be used to get the amount of data that can be read from the card.
|
||||
/// </summary>
|
||||
public byte DataLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return SW2;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the reponse status is COUNTER_REACHED this method can be used to get the value that the counter reached.
|
||||
/// </summary>
|
||||
public byte Counter
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)(SW2 & 0x0F);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the reponse status is INVALID_LE this method can be used to get the correct LE.
|
||||
/// </summary>
|
||||
public byte CorrectLE
|
||||
{
|
||||
get
|
||||
{
|
||||
return SW2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
209
NFC/APDUStatusWords.cs
Normal file
209
NFC/APDUStatusWords.cs
Normal file
@ -0,0 +1,209 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NFC.Mifare_DESFire
|
||||
{
|
||||
public enum APDUStatusWords : UInt16
|
||||
{
|
||||
/// <summary>
|
||||
/// Kommando erfolgreich ausgeführt. xx Datenbytes können mit dem ‚GET RESPONSE‘-Kommando abgeholt werden. Statuswort zur Steuerung des T=0-Protokolls
|
||||
/// </summary>
|
||||
DATA_READY = 0x6100,
|
||||
|
||||
/// <summary>
|
||||
/// Die zurückgegebenen Daten können fehlerhaft sein.
|
||||
/// </summary>
|
||||
FAULTY_DATA = 0x6281,
|
||||
|
||||
/// <summary>
|
||||
/// Da das Dateiende vorher erreicht wurde, konnten nur weniger als Le Bytes gelesen werden.
|
||||
/// </summary>
|
||||
UNEXPECTED_END_OF_FILE = 0x6282,
|
||||
|
||||
/// <summary>
|
||||
/// Die ausgewählte Datei ist gesperrt (englisch invalidated, wörtlich „ungültig“).
|
||||
/// </summary>
|
||||
INVALIDATED_FILE = 0x6283,
|
||||
|
||||
/// <summary>
|
||||
/// Die File Control Information (FCI) ist inkonform zu ISO 7816-4.
|
||||
/// </summary>
|
||||
FCI_NOT_CONFORM = 0x6284,
|
||||
|
||||
/// <summary>
|
||||
/// Warnung; Zustand des nichtflüchtigen Speichers nicht verändert
|
||||
/// </summary>
|
||||
STORAGE_NOT_CHANGED = 0x6200,
|
||||
|
||||
/// <summary>
|
||||
/// Zähler hat den Wert x erreicht (die genaue Bedeutung ist vom Kommando abhängig)
|
||||
/// </summary>
|
||||
COUNTER_REACHED = 0x63C0,
|
||||
|
||||
/// <summary>
|
||||
/// Warnung; Zustand des nichtflüchtigen Speichers verändert
|
||||
/// </summary>
|
||||
STORAGE_CHANGED = 0x6300,
|
||||
|
||||
/// <summary>
|
||||
/// Ausführungsfehler; Zustand des nichtflüchtigen Speichers nicht verändert
|
||||
/// </summary>
|
||||
EXECUTION_ERROR_WITHOUT_CHANGE = 0x6400,
|
||||
|
||||
/// <summary>
|
||||
/// Speicherfehler
|
||||
/// </summary>
|
||||
MEMORY_ERROR = 0x6581,
|
||||
|
||||
/// <summary>
|
||||
/// Ausführungsfehler; Zustand des nichtflüchtigen Speichers verändert
|
||||
/// </summary>
|
||||
EXECUTION_ERROR_WITH_CHANGE = 0x6500,
|
||||
|
||||
/// <summary>
|
||||
/// Befehlslänge (Lc) oder erwartete Antwortlänge (Le) falsch
|
||||
/// </summary>
|
||||
INVALID_LC_LE = 0x6700,
|
||||
|
||||
/// <summary>
|
||||
/// Funktionen im Class-Byte werden nicht unterstützt
|
||||
/// </summary>
|
||||
CLASS_FEATURE_NOT_SUPPORTED = 0x6800,
|
||||
|
||||
/// <summary>
|
||||
/// Logische Kanäle werden nicht unterstützt
|
||||
/// </summary>
|
||||
LOGIC_CHANNEL_NOT_SUPPORTED = 0x6881,
|
||||
|
||||
/// <summary>
|
||||
/// Secure Messaging wird nicht unterstützt
|
||||
/// </summary>
|
||||
SECURE_MESSAGING_NOT_SUPPORTED = 0x6882,
|
||||
|
||||
/// <summary>
|
||||
/// Kommando nicht erlaubt
|
||||
/// </summary>
|
||||
COMMAND_NOT_ALLOWED = 0x6900,
|
||||
|
||||
/// <summary>
|
||||
/// Kommando inkompatibel zur Dateistruktur
|
||||
/// </summary>
|
||||
COMMAND_INCOMPATIBLE = 0x6981,
|
||||
|
||||
/// <summary>
|
||||
/// Sicherheitszustand nicht erfüllt
|
||||
/// </summary>
|
||||
SAFETY_STATUS_NOT_FULFILLED = 0x6982,
|
||||
|
||||
/// <summary>
|
||||
/// Authentisierungsmethode ist gesperrt
|
||||
/// </summary>
|
||||
AUTHENTICATION_METHOD_LOCKED = 0x6983,
|
||||
|
||||
/// <summary>
|
||||
/// Referenzierte Daten sind gesperrt
|
||||
/// </summary>
|
||||
REFERENCED_FILE_LOCKED = 0x6984,
|
||||
|
||||
/// <summary>
|
||||
/// Nutzungsbedingungen sind nicht erfüllt
|
||||
/// </summary>
|
||||
TERMS_OF_SERVICE_NOT_FULFILLED = 0x6985,
|
||||
|
||||
/// <summary>
|
||||
/// Kommando nicht erlaubt (kein EF selektiert)
|
||||
/// </summary>
|
||||
COMMAND_NOT_ALLOWED_NO_EF_SELECTED = 0x6986,
|
||||
|
||||
/// <summary>
|
||||
/// Erwartete Secure-Messaging-Objekte nicht gefunden
|
||||
/// </summary>
|
||||
EXPECTED_SECURE_MESSAGING_OBJECTS_NOT_FOUND = 0x6987,
|
||||
|
||||
/// <summary>
|
||||
/// Secure-Messaging-Datenobjekte sind inkorrekt
|
||||
/// </summary>
|
||||
INVALID_SECURE_MESSAGING_OBJECTS = 0x6988,
|
||||
|
||||
/// <summary>
|
||||
/// Falsche Parameter P1/P2
|
||||
/// </summary>
|
||||
WRONG_PARAMETERS = 0x6A00,
|
||||
|
||||
/// <summary>
|
||||
/// Falsche Daten
|
||||
/// </summary>
|
||||
WRONG_DATA = 0x6A80,
|
||||
|
||||
/// <summary>
|
||||
/// Funktion wird nicht unterstützt
|
||||
/// </summary>
|
||||
FEATURE_NOT_SUPPORTED = 0x6A81,
|
||||
|
||||
/// <summary>
|
||||
/// Datei wurde nicht gefunden
|
||||
/// </summary>
|
||||
FILE_NOT_FOUND = 0x6A82,
|
||||
|
||||
/// <summary>
|
||||
/// Datensatz (engl. record) der Datei nicht gefunden
|
||||
/// </summary>
|
||||
RECORD_NOT_FOUND = 0x6A83,
|
||||
|
||||
/// <summary>
|
||||
/// Nicht genügend Speicherplatz in der Datei
|
||||
/// </summary>
|
||||
INSUFFICIENT_SPACE = 0x6A84,
|
||||
|
||||
/// <summary>
|
||||
/// Lc nicht konsistent mit der TLV-Struktur
|
||||
/// </summary>
|
||||
LC_TLV_INCONSISTENT = 0x6A85,
|
||||
|
||||
/// <summary>
|
||||
/// Inkorrekte Parameter P1/P2
|
||||
/// </summary>
|
||||
INCORRECT_PARAMETERs = 0x6A86,
|
||||
|
||||
/// <summary>
|
||||
/// Lc inkonsistent mit P1/P2
|
||||
/// </summary>
|
||||
LC_PARAMETERS_INCONSISTENT = 0x6A87,
|
||||
|
||||
/// <summary>
|
||||
/// Referenzierte Daten nicht gefunden
|
||||
/// </summary>
|
||||
REFERENCED_FILE_NOT_FOUND = 0x6A88,
|
||||
|
||||
/// <summary>
|
||||
/// Parameter P1/P2 falsch
|
||||
/// </summary>
|
||||
WRONG_PARAMETERS_2 = 0x6B00,
|
||||
|
||||
/// <summary>
|
||||
/// Falsche Länge Le; xx gibt die korrekte Länge an Statuswort zur Steuerung des T=0-Protokolls
|
||||
/// </summary>
|
||||
INVALID_LE = 0x6C00,
|
||||
|
||||
/// <summary>
|
||||
/// Das Kommando (INS) wird nicht unterstützt
|
||||
/// </summary>
|
||||
INSTRUCTION_NOT_SUPPORTED = 0x6D00,
|
||||
|
||||
/// <summary>
|
||||
/// Die Kommandoklasse (CLA) wird nicht unterstützt
|
||||
/// </summary>
|
||||
CLASS_NOT_SUPPORTED = 0x6E00,
|
||||
|
||||
/// <summary>
|
||||
/// Kommando wurde mit unbekanntem Fehler abgebrochen
|
||||
/// </summary>
|
||||
UNKNOWN_ERROR = 0x6F00,
|
||||
|
||||
/// <summary>
|
||||
/// Kommando erfolgreich ausgeführt
|
||||
/// </summary>
|
||||
SUCCESS = 0x9000,
|
||||
}
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NFC
|
||||
{
|
||||
@ -16,16 +14,18 @@ namespace NFC
|
||||
bool IsAvailable();
|
||||
|
||||
/// <returns>Returns all available readers.</returns>
|
||||
String[] GetReader();
|
||||
string[] GetReaders();
|
||||
|
||||
/// <summary>
|
||||
/// Create a new reader instance from the specified id.
|
||||
/// </summary>
|
||||
/// <returns>Returns the spatform specific reader that corresponds to the id.</returns>
|
||||
/// <exception cref="ArgumentException">Invalid reader id.</exception>
|
||||
IReader OpenReader(String readerID);
|
||||
IReader OpenReader(string readerID);
|
||||
}
|
||||
|
||||
public delegate void ReaderEventHandler(object sender, ICard card);
|
||||
|
||||
/// <summary>
|
||||
/// Abstraction of a platform-specifc reader that can communicate with NFC cards.
|
||||
/// </summary>
|
||||
@ -34,12 +34,12 @@ namespace NFC
|
||||
/// <summary>
|
||||
/// Event that will be called when a new tag was discovered.
|
||||
/// </summary>
|
||||
event EventHandler CardDiscovered;
|
||||
event ReaderEventHandler CardDiscovered;
|
||||
|
||||
/// <summary>
|
||||
/// Event that will be called when a tag that is in use gets disconnected.
|
||||
/// </summary>
|
||||
event EventHandler CardLost;
|
||||
event ReaderEventHandler CardLost;
|
||||
|
||||
void start();
|
||||
|
||||
@ -63,7 +63,7 @@ namespace NFC
|
||||
/// </summary>
|
||||
/// <param name="apdu_cmd">Application Protocol Data Unit Command - ISO 7816</param>
|
||||
/// <returns>Application Protocol Data Unit Response - ISO 7816</returns>
|
||||
byte[] Transmit(byte[] apdu_cmd);
|
||||
APDUResponse Transmit(APDUCommand apdu_cmd);
|
||||
}
|
||||
|
||||
public class ReaderUnavailableException : Exception { }
|
||||
|
44
NFC/Mifare DESFire/APDUInstructions.cs
Normal file
44
NFC/Mifare DESFire/APDUInstructions.cs
Normal file
@ -0,0 +1,44 @@
|
||||
namespace NFC.Mifare_DESFire
|
||||
{
|
||||
enum APDUInstructions : byte
|
||||
{
|
||||
AUTHENTICATE_ISO = 0x1A,
|
||||
AUTHENTICATE_AES = 0xAA,
|
||||
CHANGE_KEY_SETTINGS = 0x54,
|
||||
SET_CONFIGURATION = 0x5C,
|
||||
CHANGE_KEY = 0xC4,
|
||||
GET_KEY_VERSION = 0x64,
|
||||
CREATE_APPLICATION = 0xCA,
|
||||
DELETE_APPLICATION = 0xDA,
|
||||
GET_APPLICATION_IDS = 0x6A,
|
||||
FREE_MEMORY = 0x6E,
|
||||
GET_DF_NAMES = 0x6D,
|
||||
GET_KEY_SETTINGS = 0x45,
|
||||
SELECT_APPLICATION = 0x5A,
|
||||
FORMAT_PICC = 0xFC,
|
||||
GET_VERSION = 0x60,
|
||||
GET_CARD_UID = 0x51,
|
||||
GET_FILE_IDS = 0x6F,
|
||||
GET_FILE_SETTINGS = 0xF5,
|
||||
CHANGE_FILE_SETTINGS = 0x5F,
|
||||
CREATE_STDDATAFILE = 0xCD,
|
||||
CREATE_BACKUPDATAFILE = 0xCB,
|
||||
CREATE_VALUE_FILE = 0xCC,
|
||||
CREATE_LINEAR_RECORD_FILE = 0xC1,
|
||||
CREATE_CYCLIC_RECORD_FILE = 0xC0,
|
||||
DELETE_FILE = 0xDF,
|
||||
GET_ISO_FILE_IDS = 0x61,
|
||||
READ_DATA = 0x8D,
|
||||
WRITE_DATA = 0x3D,
|
||||
GET_VALUE = 0x6C,
|
||||
CREDIT = 0x0C,
|
||||
DEBIT = 0xDC,
|
||||
LIMITED_CREDIT = 0x1C,
|
||||
WRITE_RECORD = 0x3B,
|
||||
READ_RECORDS = 0xBB,
|
||||
CLEAR_RECORD_FILE = 0xEB,
|
||||
COMMIT_TRANSACTION = 0xC7,
|
||||
ABORT_TRANSACTION = 0xA7,
|
||||
CONTINUE = 0xAF,
|
||||
}
|
||||
}
|
32
NFC/Mifare DESFire/APDUStatusCodes.cs
Normal file
32
NFC/Mifare DESFire/APDUStatusCodes.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NFC.Mifare_DESFire
|
||||
{
|
||||
public enum APDUStatusCodes : UInt16
|
||||
{
|
||||
OPERATION_OK = 0x9000, // = Successful operation
|
||||
NO_CHANGES = 0x900C, // = No changes done to backup files, CommitTransaction / AbortTransaction not necessary
|
||||
OUT_OF_EEPROM_ERROR = 0x900E, // = Insufficient NV-Memory to complete command
|
||||
ILLEGAL_COMMAND_CODE = 0x901C, // = Command code not supported
|
||||
INTEGRITY_ERROR = 0x901E, // = CRC or MAC does not match data Padding bytes not valid
|
||||
NO_SUCH_KEY = 0x9040, // = Invalid key number specified
|
||||
LENGTH_ERROR = 0x907E, // = Length of command string invalid
|
||||
PERMISSION_DENIED = 0x909D, // = Current configuration / status does not allow the requested command
|
||||
PARAMETER_ERROR = 0x909E, // = Value of the parameter(s) invalid
|
||||
APPLICATION_NOT_FOUND = 0x90A0, // = Requested AID not present on PICC
|
||||
APPL_INTEGRITY_ERROR = 0x90A1, // = Unrecoverable error within application, application will be disabled
|
||||
AUTHENTICATION_ERROR = 0x90AE, // = Current authentication status does not allow the requested command
|
||||
ADDITIONAL_FRAME = 0x90AF, // = Additional data frame is expected to be sent
|
||||
BOUNDARY_ERROR = 0x90BE, // = Attempt to read/write data from/to beyond the file\'s/record\'s limits. Attempt to exceed the limits of a value file.
|
||||
PICC_INTEGRITY_ERROR = 0x90C1, // = Unrecoverable error within PICC, PICC will be disabled
|
||||
COMMAND_ABORTED = 0x90CA, // = Previous Command was not fully completed Not all Frames were requested or provided by the PCD
|
||||
PICC_DISABLED_ERROR = 0x90CD, // = PICC was disabled by an unrecoverable error
|
||||
COUNT_ERROR = 0x90CE, // = Number of Applications limited to 28, no additional CreateApplication possible
|
||||
DUPLICATE_ERROR = 0x90DE, // = Creation of file/application failed because file/application with same number already exists
|
||||
EEPROM_ERROR = 0x90EE, // = Could not complete NV-write operation due to loss of power, internal backup/rollback mechanism activated
|
||||
FILE_NOT_FOUND = 0x90F0, // = Specified file number does not exist
|
||||
FILE_INTEGRITY_ERROR = 0x90F1, // = Unrecoverable error within file, file will be disabled
|
||||
}
|
||||
}
|
13
NFC/Mifare DESFire/CryptoOperations.cs
Normal file
13
NFC/Mifare DESFire/CryptoOperations.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NFC.Mifare_DESFire
|
||||
{
|
||||
enum CryptoOperations : byte
|
||||
{
|
||||
TDES = 0x00,
|
||||
TKTDES = 0x40,
|
||||
AES = 0x80,
|
||||
}
|
||||
}
|
20
NFC/Mifare DESFire/FileCommunication.cs
Normal file
20
NFC/Mifare DESFire/FileCommunication.cs
Normal file
@ -0,0 +1,20 @@
|
||||
namespace NFC.Mifare_DESFire
|
||||
{
|
||||
enum FileCommunication : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// "Plain communication"
|
||||
/// </summary>
|
||||
PLAIN = 0x00,
|
||||
|
||||
/// <summary>
|
||||
/// Plain communication secured by DES/3DES MACing
|
||||
/// </summary>
|
||||
MAC = 0x01,
|
||||
|
||||
/// <summary>
|
||||
/// Fully DES/3DES enciphered communication
|
||||
/// </summary>
|
||||
ENCRYPT = 0x03
|
||||
}
|
||||
}
|
30
NFC/Mifare DESFire/FileTypes.cs
Normal file
30
NFC/Mifare DESFire/FileTypes.cs
Normal file
@ -0,0 +1,30 @@
|
||||
namespace NFC.Mifare_DESFire
|
||||
{
|
||||
enum FileTypes : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Standard Data File
|
||||
/// </summary>
|
||||
STANDARD = 0x00,
|
||||
|
||||
/// <summary>
|
||||
/// Backup Data Files
|
||||
/// </summary>
|
||||
BACKUP = 0x01,
|
||||
|
||||
/// <summary>
|
||||
/// Value Files with Backup
|
||||
/// </summary>
|
||||
VALUE = 0x02,
|
||||
|
||||
/// <summary>
|
||||
/// Linear Record Files with Backup
|
||||
/// </summary>
|
||||
LINEARRECORD = 0x03,
|
||||
|
||||
/// <summary>
|
||||
/// Cyclic Record Files with Backup
|
||||
/// </summary>
|
||||
CYCLICRECORD = 0x04
|
||||
}
|
||||
}
|
@ -4,4 +4,9 @@
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="PCSC" Version="5.0.0" />
|
||||
<PackageReference Include="PCSC.Iso7816" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
63
NFC/Readers/PCSC/Card.cs
Normal file
63
NFC/Readers/PCSC/Card.cs
Normal file
@ -0,0 +1,63 @@
|
||||
using PCSC;
|
||||
using PCSC.Iso7816;
|
||||
|
||||
namespace NFC.Readers.PCSC
|
||||
{
|
||||
public class Card : ICard
|
||||
{
|
||||
private IsoReader _ISOReader;
|
||||
private string _ReaderID;
|
||||
|
||||
public Card(IsoReader isoreader, string readerID)
|
||||
{
|
||||
_ISOReader = isoreader;
|
||||
_ReaderID = readerID;
|
||||
}
|
||||
public void Connect()
|
||||
{
|
||||
_ISOReader.Connect(_ReaderID, SCardShareMode.Shared, SCardProtocol.Any);
|
||||
}
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
_ISOReader.Disconnect(SCardReaderDisposition.Eject);
|
||||
}
|
||||
|
||||
public APDUResponse Transmit(APDUCommand apdu_cmd)
|
||||
{
|
||||
Response response = _ISOReader.Transmit(Convert(apdu_cmd));
|
||||
return Convert(response);
|
||||
}
|
||||
|
||||
public CommandApdu Convert(APDUCommand apdu_cmd)
|
||||
{
|
||||
CommandApdu apdu = new CommandApdu(IsoCase.Case2Short, _ISOReader.ActiveProtocol)
|
||||
{
|
||||
CLA = apdu_cmd.Class,
|
||||
INS = apdu_cmd.Instruction,
|
||||
P1 = apdu_cmd.Parameter1,
|
||||
P2 = apdu_cmd.Parameter2,
|
||||
|
||||
Data = apdu_cmd.Data,
|
||||
|
||||
Le = apdu_cmd.LengthExpected
|
||||
};
|
||||
|
||||
return apdu;
|
||||
}
|
||||
|
||||
public APDUResponse Convert(Response response)
|
||||
{
|
||||
ResponseApdu responseApdu = response.Get(0);
|
||||
|
||||
APDUResponse apduResponse = new APDUResponse()
|
||||
{
|
||||
SW1 = responseApdu.SW1,
|
||||
SW2 = responseApdu.SW2,
|
||||
Body = responseApdu.GetData()
|
||||
};
|
||||
|
||||
return apduResponse;
|
||||
}
|
||||
}
|
||||
}
|
33
NFC/Readers/PCSC/Hardware.cs
Normal file
33
NFC/Readers/PCSC/Hardware.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using PCSC;
|
||||
|
||||
namespace NFC.Readers.PCSC
|
||||
{
|
||||
public class Hardware : IHardware
|
||||
{
|
||||
public string[] GetReaders()
|
||||
{
|
||||
var contextFactory = ContextFactory.Instance;
|
||||
using (var context = contextFactory.Establish(SCardScope.System))
|
||||
{
|
||||
return context.GetReaders();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAvailable()
|
||||
{
|
||||
if(GetReaders().Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public IReader OpenReader(string readerID)
|
||||
{
|
||||
return new Reader(readerID);
|
||||
}
|
||||
}
|
||||
}
|
51
NFC/Readers/PCSC/Reader.cs
Normal file
51
NFC/Readers/PCSC/Reader.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using PCSC;
|
||||
using PCSC.Iso7816;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NFC.Readers.PCSC
|
||||
{
|
||||
|
||||
public class Reader : IReader, IDisposable
|
||||
{
|
||||
private string _ReaderID;
|
||||
private IContextFactory _ContextFactory;
|
||||
private ISCardContext _SCardContext;
|
||||
private IsoReader _ISOReader;
|
||||
private ICard _Card;
|
||||
|
||||
public Reader(string readerID)
|
||||
{
|
||||
_ReaderID = readerID;
|
||||
}
|
||||
|
||||
public event ReaderEventHandler CardDiscovered;
|
||||
public event ReaderEventHandler CardLost;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
public void start()
|
||||
{
|
||||
_ContextFactory = ContextFactory.Instance;
|
||||
_SCardContext = _ContextFactory.Establish(SCardScope.System);
|
||||
|
||||
_ISOReader = new IsoReader(_SCardContext);
|
||||
|
||||
_Card = new Card(_ISOReader, _ReaderID);
|
||||
|
||||
CardDiscovered?.Invoke(this, _Card);
|
||||
}
|
||||
|
||||
public void stop()
|
||||
{
|
||||
CardLost?.Invoke(this, _Card);
|
||||
|
||||
_ISOReader.Dispose();
|
||||
_SCardContext.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
17
NFC_Test/NFC_Test.csproj
Normal file
17
NFC_Test/NFC_Test.csproj
Normal file
@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NFC\NFC.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
37
NFC_Test/REAL_Windows.cs
Normal file
37
NFC_Test/REAL_Windows.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NFC;
|
||||
using NFC.Readers.PCSC;
|
||||
|
||||
namespace NFC_Test
|
||||
{
|
||||
[TestFixture, Explicit]
|
||||
public class REAL_Windows
|
||||
{
|
||||
[Test]
|
||||
public void GetReaders()
|
||||
{
|
||||
Hardware hardware = new Hardware();
|
||||
string[] readers = hardware.GetReaders();
|
||||
|
||||
Console.WriteLine("Readers detected: {0}", readers.Length);
|
||||
|
||||
if(readers.Length > 0)
|
||||
{
|
||||
Console.WriteLine("List of ReaderIDs:");
|
||||
foreach (string readerID in readers)
|
||||
{
|
||||
Console.WriteLine("{0}", readerID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase("")]
|
||||
public void Connect(string readerID)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user