public byte[] SelectFile(byte[] id, SelectMode mode, SelectOccurrence occurrence, SelectFileControlInfo info) { if (id == null) { throw new ArgumentException("id"); } // Setup the command CApdu command = new CApdu(); command.Cla = 0x00; command.Ins = (byte)Part4Instruction.Select; command.P1 = (byte)mode; command.P2 = (byte)((byte)occurrence | (byte)info); command.Data = id; command.LE = 0x00; // Transceive RApdu response = Transcieve(command); // Parse and test response if (response.IsError) { throw response.ThrowBySW("SelectFile"); } return(response.Data); }
public byte[] GetData(byte[] id) { // Argument validation if (id == null) { throw new ArgumentException("id"); } // Setup the command and transcieve CApdu command = new CApdu(); command.Cla = 0x00; command.Ins = (byte)Part4Instruction.GetDataA; command.P1 = id[0]; command.P2 = id[1]; RApdu response = Transcieve(command); // Validate the response if (response.IsError) { throw response.ThrowBySW("GetData"); } return(response.Data); }
public void SwitchProtocol(SwitchProtocolStandard standard, SwitchProtocolLayer layer) { const byte DataLength = 4; // Construct the data object byte[] data = new byte[DataLength]; data[0] = TagSwitchProtocol; data[1] = 0x02; // Static length for data object data[2] = (byte)standard; data[3] = (byte)layer; CApdu command = new CApdu(); command.Cla = CApdu.ClaProprietary; command.Ins = InsSupplementalCommand; command.P1 = 0x00; // Always null command.P2 = P2SwitchProtocol; command.Data = data; Iso7816Protocol protocol = GetProtocol <Iso7816Protocol>(); RApdu response = protocol.Transceive(command); // Validate the response, if (response.IsError) { throw response.ThrowBySW("SwitchProtocol"); } }
/* * PLAID Commands */ public byte[] PlaidInitialAuthenticate(short keyIndex, byte[] estr1, short opMode) { // Setup the command CApdu command = new CApdu(); command.Cla = CLA; command.Ins = (byte)PACSAMCommand.PlaidInitialAuth; command.P1 = (byte)((keyIndex >> 8) & 0xFF); // Key index MSB command.P2 = (byte)(keyIndex & 0xFF); // Key index LSB // Generate the full APDU data MemoryStream data = new MemoryStream(); data.WriteByte((byte)((opMode >> 8) & 0xFF)); // Key index MSB data.WriteByte((byte)(opMode & 0xFF)); // Key index LSB data.Write(estr1, 0, estr1.Length); command.Data = data.ToArray(); //command.LE = 0x00; // Transceive RApdu response = Transcieve(command); // Parse and test DESFire status code if (response.IsError) { throw new Iso7816Exception(response.SW12, "PlaidInitialAuthenticate"); } return(response.Data); }
public bool EV1VerifyMAC(byte[] data) { // Setup the command CApdu command = new CApdu(); command.Cla = CLA; command.Ins = (byte)PACSAMCommand.EV1verifyMac; command.P1 = 0; command.P2 = 0; command.Data = data; command.LE = 0x00; // Transceive RApdu response = Transcieve(command); // Parse and test DESFire status code if (response.IsError) { //throw new Iso7816Exception(response.SW12, "EV1VerifyMAC"); return(false); } // Done return(true); }
/* * DESFireEV1 Commands */ public byte[] EV1Authenticate0(short keyIndex, byte[] ekRndB) { // This command will reset our authentication status //ResetAuthentication(); // Setup the command CApdu command = new CApdu(); command.Cla = CLA; command.Ins = (byte)PACSAMCommand.EV1Auth0; command.P1 = (byte)((keyIndex >> 8) & 0xFF); // Key index MSB command.P2 = (byte)(keyIndex & 0xFF); // Key index LSB MemoryStream data = new MemoryStream(); // ekRndB (from PICC) data.Write(ekRndB, 0, ekRndB.Length); command.Data = data.ToArray(); command.LE = 0x00; // Transceive RApdu response = Transcieve(command); // Parse and test DESFire status code if (response.IsError) { throw new Iso7816Exception(response.SW12, "EV1Authenticate0"); } return(response.Data); }
public void EV1Authenticate1(byte[] ekRndA) { // Setup the command CApdu command = new CApdu(); command.Cla = CLA; command.Ins = (byte)PACSAMCommand.EV1Auth1; command.P1 = 0; command.P2 = 0; command.Data = ekRndA; command.LE = 0x00; // Transceive RApdu response = Transcieve(command); // Parse and test DESFire status code if (response.IsError) { throw new Iso7816Exception(response.SW12, "EV1Authenticate1"); } // If we get a valid response then everything went OK and the PACSAM instance now has a session key established. // Confirm this by interrogating the PACSAM var status = GetStatus(); if ((status.DESFireStatus != DESFireAuthStatus.AUTH_STATE_OK_DES) && (status.DESFireStatus != DESFireAuthStatus.AUTH_STATE_OK_ISO) && (status.DESFireStatus != DESFireAuthStatus.AUTH_STATE_OK_AES)) { throw new InvalidOperationException(@"PACSAM authentication state not changed. Authentication failed."); } }
public void GeneralAuthenticate(ushort address, GeneralAuthenticateKeyType keyType, byte keyIndex) { const int AuthenticateDataLen = 5; CApdu command = new CApdu(); command.Cla = CLA; command.Ins = INSGeneralAuthenticate; command.P1 = 0x00; // Always null command.P2 = 0x00; // Always null byte[] data = new byte[AuthenticateDataLen]; data[0] = 0x01; // Static version data[1] = (byte)(address >> 8); data[2] = (byte)(address & 0xFF); data[3] = (byte)keyType; data[4] = 0; command.Data = data; RApdu response = myProtocol.Transceive(command); // Validate the response, if (response.IsError) { throw response.ThrowBySW("GeneralAuthenticate"); } }
public void LoadKey(PACSAMKeyType keyType, byte element, byte[] record) { // Setup the command CApdu command = new CApdu(); command.Cla = CLA; command.Ins = (byte)PACSAMCommand.LoadKey; command.P1 = (byte)keyType; command.P2 = element; command.Data = record; // NOTE: For some reason I get poor handling of Extended APDU's when supplying the LE byte. This may only be relevant to the Javacos virtual reader // but for now we just omit it. if (record.Length <= 255) { command.LE = 0x00; } // Transceive RApdu response = Transcieve(command); // Parse and test DESFire status code if (response.IsError) { throw new Iso7816Exception(response.SW12, "LoadKey"); } }
public byte[] GetDataExtended(byte[] id, byte p1, byte p2) { // Argument validation if (id == null) { throw new ArgumentException("id"); } // Setup the command and transcieve CApdu command = new CApdu(); command.Cla = 0x00; command.Ins = (byte)Part4Instruction.GetDataB; command.P1 = p1; command.P2 = p2; command.Data = id; command.LE = 0x00; RApdu response = Transcieve(command); // Validate the response, if (response.IsError) { throw response.ThrowBySW("GetDataExtended"); } return(response.Data); }
public override RApdu Transceive(CApdu command) { IntPtr requestPci; switch (myCard.CommsProtocol) { case SCardProtocol.T0: requestPci = PCSCApi.SCardPciT0; break; case SCardProtocol.T1: requestPci = PCSCApi.SCardPciT1; break; default: throw PCSCException.ThrowUnsupportedProtocol(); } int responseLength = 1024; byte[] responseBuffer = new byte[responseLength]; byte[] cmdBuffer = command.ToArray(); PCSCResult result = NativeMethods.SCardTransmit(myCard.Handle, requestPci, cmdBuffer, cmdBuffer.Length, IntPtr.Zero, responseBuffer, ref responseLength); if (PCSCResult.None == result) { byte[] response = new byte[responseLength]; Array.Copy(responseBuffer, response, responseLength); #if DEBUG RaiseOnTranscieve("CAPDU> " + Converters.ByteArrayToString(cmdBuffer)); RaiseOnTranscieve("RAPDU> " + Converters.ByteArrayToString(response)); #endif return(RApdu.Parse(response)); } else { #if DEBUG RaiseOnTranscieve("CAPDU> " + Converters.ByteArrayToString(cmdBuffer)); RaiseOnTranscieve("RAPDU> Error condition (HRESULT = " + EnumHelper.GetDescription(result) + ")"); #endif throw new PCSCException("Communications error."); } }
public void LoadKeys(OptionalLoadKeyStructure structure, byte secureKeyIndex, byte keyIndex, byte[] key) { CApdu command = new CApdu(); command.Cla = CLA; command.Ins = INSLoadKeys; command.P1 = (byte)((byte)structure | secureKeyIndex); command.P2 = keyIndex; command.Data = key; RApdu response = myProtocol.Transceive(command); // Validate the response, if (response.IsError) { throw response.ThrowBySW("LoadKeys"); } }
public void UpdateBinary(ushort address, byte[] data) { CApdu command = new CApdu(); command.Cla = CLA; command.Ins = INSUpdateBinary; command.P1 = (byte)(address >> 8); command.P2 = (byte)(address & 0xFF); command.Data = data; RApdu response = myProtocol.Transceive(command); // Validate the response, if (response.IsError) { throw response.ThrowBySW("UpdateBinary"); } }
public byte[] GetATS() { CApdu command = new CApdu(); command.Cla = CLA; command.Ins = INSGetATS; command.P1 = P1GetATS; command.P2 = 0x00; // Always null RApdu response = myProtocol.Transceive(command); // Validate the response, if (response.IsError) { throw response.ThrowBySW("GetATS"); } return(response.Data); }
internal PCSCIso14443AProtocol(byte[] atr, PCSCCard card) : base(atr, card) { try { // Retrieve our UID CApdu command = new CApdu(0xFF, 0xCA, 0, le: 00); RApdu response = Transceive(command); if (response.IsError) { throw new InvalidOperationException("Error retrieving the Card UID"); } UID = response.Data; } catch (Exception) { // Some IFD's don't support UID retrieval } }
public byte[] ReadBinary(ushort address, byte length) { CApdu command = new CApdu(); command.Cla = CLA; command.Ins = INSReadBinary; command.P1 = (byte)(address >> 8); command.P2 = (byte)(address & 0xFF); command.LE = length; // 16 byte read RApdu response = myProtocol.Transceive(command); // Validate the response, if (response.IsError) { throw response.ThrowBySW("ReadBinary"); } return(response.Data); }
public void PlaidLoadFAKey(short keyIndex, byte[] cryptogram) { // Setup the command CApdu command = new CApdu(); command.Cla = CLA; command.Ins = (byte)PACSAMCommand.PlaidLoadFAKey; command.P1 = (byte)((keyIndex >> 8) & 0xFF); // Key index MSB command.P2 = (byte)(keyIndex & 0xFF); // Key index LSB command.Data = cryptogram; // Transceive RApdu response = Transcieve(command); // Parse and test status code if (response.IsError) { throw new Iso7816Exception(response.SW12, "PlaidLoadFAKey"); } }
protected void ManageSession(byte[] dataObject) { CApdu command = new CApdu(); command.Cla = CApdu.ClaProprietary; command.Ins = InsSupplementalCommand; command.P1 = 0x00; // Always null command.P2 = P2ManageSession; command.Data = dataObject; command.LE = 0x00; Iso7816Protocol protocol = GetProtocol <Iso7816Protocol>(); RApdu response = protocol.Transceive(command); // Validate the response, if (response.IsError) { throw response.ThrowBySW("ManageSession"); } }
public byte[] GetData(byte element) { Iso7816Protocol protocol = Card.GetProtocol <Iso7816Protocol>(); // Construct the APDU CApdu command = new CApdu(); command.Cla = CLA; command.Ins = INS_GET_DATA; command.P1 = element; command.P2 = 0x00; RApdu response = protocol.Transceive(command); // Validate the response, if (response.IsError) { throw response.ThrowBySW("GetData"); } return(response.Data); }
public void ResetAuthentication() { Iso7816Protocol protocol = Card.GetProtocol <Iso7816Protocol>(); // Construct the APDU CApdu command = new CApdu(); command.Cla = CLA; command.Ins = INS_RESET_AUTH; command.P1 = 0x00; command.P2 = 0x00; RApdu response = protocol.Transceive(command); // Validate the response, if (response.IsError) { throw response.ThrowBySW("SetData"); } return; }
public void EV1UpdateIV(byte[] data) { // Setup the command CApdu command = new CApdu(); command.Cla = CLA; command.Ins = (byte)PACSAMCommand.EV1UpdateIV; command.P1 = 0; command.P2 = 0; command.Data = data; command.LE = 0x00; // Transceive RApdu response = Transcieve(command); // Parse and test DESFire status code if (response.IsError) { throw new Iso7816Exception(response.SW12, "EV1UpdateIV"); } }
public void SetData(byte[] cryptogram) { Iso7816Protocol protocol = Card.GetProtocol <Iso7816Protocol>(); // Construct the APDU CApdu command = new CApdu(); command.Cla = CLA; command.Ins = INS_SET_DATA; command.P1 = 0x00; command.P2 = 0x00; command.Data = cryptogram; RApdu response = protocol.Transceive(command); // Validate the response, if (response.IsError) { throw response.ThrowBySW("SetData"); } return; }
public byte[] FinalAuthenticate(byte[] estr2) { Iso7816Protocol protocol = Card.GetProtocol <Iso7816Protocol>(); CApdu command = new CApdu(); command.Cla = CLA; command.Ins = INS_PLAID_FINAL_AUTH; command.P1 = 0x00; command.P2 = 0x00; command.Data = estr2; RApdu response = protocol.Transceive(command); // Validate the response, if (response.IsError) { throw response.ThrowBySW("FinalAuthenticate"); } return(response.Data); }
public byte[] InitialAuthenticate(KeysetList keysets) { Iso7816Protocol protocol = Card.GetProtocol <Iso7816Protocol>(); CApdu command = new CApdu(); command.Cla = CLA; command.Ins = INS_PLAID_INITIAL_AUTH; command.P1 = 0x00; command.P2 = 0x00; command.Data = keysets.Encode(); RApdu response = protocol.Transceive(command); // Validate the response, if (response.IsError) { throw response.ThrowBySW("InitialAuthenticate"); } return(response.Data); }
protected RApdu Transcieve(CApdu command) { Iso7816Protocol protocol = Card.GetProtocol <Iso7816Protocol>(); MemoryStream data = new MemoryStream(); // Send the first (and possibly only) tranceive command RApdu response = protocol.Transceive(command); // Check for more data while (response.SW1 == RApdu.SW1MoreData) { // Dump what we have so far to the memory stream data.Write(response.Data, 0, response.Data.Length); // Issue a 'GET RESPONSE' request command.Ins = (byte)Part4Instruction.GetResponse; command.P1 = 0x00; command.P2 = 0x00; command.Data = new byte[0]; command.LE = response.SW2; // Request the next block response = protocol.Transceive(command); } // Check for other error, just return if it is if (response.IsError) { return(response); } // Get the final block of response data data.Write(response.Data, 0, response.Data.Length); // Done, return the last RApdu with the full data response.Data = data.ToArray(); return(response); }
public PlaidStatus GetStatus() { Iso7816Protocol protocol = Card.GetProtocol <Iso7816Protocol>(); // Construct the APDU CApdu command = new CApdu(); command.Cla = CLA; command.Ins = INS_GET_STATUS; command.P1 = 0x00; command.P2 = 0x00; RApdu response = protocol.Transceive(command); // Validate the response, if (response.IsError) { throw response.ThrowBySW("GetStatus"); } PlaidStatus status = new PlaidStatus(response.Data); return(status); }
public void EV1SetDivData(byte[] divData) { // Setup the command CApdu command = new CApdu(); command.Cla = CLA; command.Ins = (byte)PACSAMCommand.EV1SetDivData; command.P1 = 0; command.P2 = 0; command.Data = divData; command.LE = 0x00; // Transceive RApdu response = Transcieve(command); // Parse and test DESFire status code if (response.IsError) { throw new Iso7816Exception(response.SW12, "EV1SetDivData"); } // If we get a valid response then everything went OK and the PACSAM instance now has a session key established. }
protected RApdu Transcieve(byte cla, byte ins, byte p1 = 0, byte p2 = 0, byte[] data = null, byte?le = 0) { // Setup the command CApdu command = new CApdu(); command.Cla = cla; command.Ins = ins; command.P1 = p1; command.P2 = p2; if (data != null) { command.Data = data; } if (le != null) { command.LE = le; } // Transceive RApdu response = Transcieve(command); return(response); }
public byte[] PlaidFinalAuthenticate(byte[] estr3) { // Setup the command CApdu command = new CApdu(); command.Cla = CLA; command.Ins = (byte)PACSAMCommand.PlaidFinalAuth; command.P1 = 0x00; command.P2 = 0x00; command.Data = estr3; command.LE = 0x00; // Transceive RApdu response = Transcieve(command); // Parse and test status code if (response.IsError) { throw new Iso7816Exception(response.SW12, "PlaidFinalAuthenticate"); } return(response.Data); }
public byte[] PlaidSetData(byte[] commandObject) { // Setup the command CApdu command = new CApdu(); command.Cla = CLA; command.Ins = (byte)PACSAMCommand.PlaidSetData; command.P1 = 0x00; command.P2 = 0x00; command.Data = commandObject; //command.LE = 0x00; // Transceive RApdu response = Transcieve(command); // Parse and test status code if (response.IsError) { throw new Iso7816Exception(response.SW12, "PlaidSetData"); } return(response.Data); }