示例#1
0
        /// <summary>
        /// Read record comand
        /// </summary>
        /// <param name="fileNumber"></param>
        /// <param name="offset"></param>
        /// <param name="numberOfRecords"></param>
        /// <returns>
        /// byte array of read data
        /// </returns>
        public async Task <byte[]> ReadRecordAsync(byte fileNumber, ulong offset, ulong numberOfRecords)
        {
            var args = new byte[7];

            args[0] = fileNumber;
            args[1] = (byte)(offset & 0xFF);
            args[2] = (byte)((offset >> 8) & 0xFF);
            args[3] = (byte)((offset >> 16) & 0xFF);
            args[4] = (byte)(numberOfRecords & 0xFF);
            args[5] = (byte)((numberOfRecords >> 8) & 0xFF);
            args[6] = (byte)((numberOfRecords >> 16) & 0xFF);

            desfireCommand.Command = (byte)DesfireCommand.CommandType.ReadRecord;
            desfireCommand.Data    = args;

            DesfireResponse desfireRes = await connectionObject.TransceiveAsync(desfireCommand) as DesfireResponse;

            if (desfireRes.BoundaryError)
            {
                // Boundary error, the record doesn't exist
                return(null);
            }
            if (!desfireRes.SucceededDesfire)
            {
                throw new Exception("Failure selecting application, SW=" + desfireResponse.SW + " (" + desfireResponse.SWTranslationDesfire + ")");
            }

            return(desfireRes.ResponseData);
        }
示例#2
0
        public async Task <byte[]> ReadDataAsync(byte filenumber)
        {
            desfireCommand.Command     = 0xBD;
            desfireCommand.CommandData = new byte[] { filenumber, 0, 0, 0, 0, 0, 0 };
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            while (true)
            {
                DesfireResponse response = await connectionObject.TransceiveAsync(desfireCommand) as DesfireResponse;

                if (response.Succeeded || response.SubsequentFrame)
                {
                    ms.Write(response.ResponseData, 0, response.ResponseData.Length);
                }
                if (response.SubsequentFrame)
                {
                    desfireCommand.Command     = 0xAF;
                    desfireCommand.CommandData = null;
                    continue;
                }
                else if (response.AccessDenied)
                {
                    return(null);
                }
                else if (response.Succeeded)
                {
                    return(ms.ToArray());
                }
                else
                {
                    throw new Exception("Failed to get file; SW=" + response.SW);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Read data command
        /// </summary>
        /// <param name="fileNumber">
        /// </param>
        /// <param name="offset">
        /// </param>
        /// <param name="length">
        /// </param>
        /// <returns>
        /// byte array of read data
        /// </returns>
        public async Task <byte[]> ReadDataAsync(byte fileNumber, ulong offset, ulong length)
        {
            var args = new byte[7];

            args[0] = fileNumber;
            args[1] = (byte)(offset & 0xFF);
            args[2] = (byte)((offset >> 8) & 0xFF);
            args[3] = (byte)((offset >> 16) & 0xFF);
            args[4] = (byte)(length & 0xFF);
            args[5] = (byte)((length >> 8) & 0xFF);
            args[6] = (byte)((length >> 16) & 0xFF);

            desfireCommand.Command = (byte)DesfireCommand.CommandType.ReadData;
            desfireCommand.Data    = args;

            DesfireResponse desfireRes = await connectionObject.TransceiveAsync(desfireCommand) as DesfireResponse;



            if (!desfireRes.Succeeded)
            {
                throw new Exception("Failure reading data, SW=" + desfireRes.SW + " (" + desfireRes.SWTranslation + ")");
            }

            return(desfireRes.ResponseData);
        }
示例#4
0
        /// <summary>
        /// Select ICC application by AID
        /// </summary>
        /// <param name="aid">
        /// application id
        /// </param>
        public async Task SelectApplicationAsync(byte[] aid)
        {
            // AIDs must be 3 bytes.
            if (aid.Length != 3)
            {
                throw new NotSupportedException();
            }

            desfireCommand.Command = (byte)DesfireCommand.CommandType.SelectApplication;
            desfireCommand.Data    = aid;
            DesfireResponse desfireRes = null;

            if (connectionObject == null)
            {
                throw new Exception("??? no connection object ???");
            }
            try
            {
                desfireRes = await connectionObject.TransceiveAsync(desfireCommand) as DesfireResponse;
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine("F**K:" + e.ToString());
            }
            if (desfireRes == null)
            {
                throw new Exception("??? DesFire response Isn't a thing???");
            }

            // There is no real data to return, but if it didn't succeed, then there's something wrong.
            if (!desfireRes.Succeeded)
            {
                throw new Exception("Failure selecting application, SW=" + desfireRes.SW + " (" + desfireRes.SWTranslation + ")");
            }
        }
示例#5
0
        /// <summary>
        /// Read card details commands
        /// </summary>
        /// <returns>
        /// returns Desfire CardDetails object
        /// </returns>
        public async Task <CardDetails> ReadCardDetailsAsync()
        {
            desfireCommand.Command = (byte)DesfireCommand.CommandType.GetVersion;
            desfireCommand.Data    = null;

            DesfireResponse desfireRes = await connectionObject.TransceiveAsync(desfireCommand) as DesfireResponse;

            if (!desfireRes.SubsequentFrame || desfireRes.ResponseData.Length != 7)
            {
                return(null);
            }

            CardDetails card = new CardDetails();

            card.HardwareVendorID     = desfireRes.ResponseData[0];
            card.HardwareType         = desfireRes.ResponseData[1];
            card.HardwareSubType      = desfireRes.ResponseData[2];
            card.HardwareMajorVersion = desfireRes.ResponseData[3];
            card.HardwareMinorVersion = desfireRes.ResponseData[4];
            card.HardwareStorageSize  = desfireRes.ResponseData[5];
            card.HardwareProtocolType = desfireRes.ResponseData[6];

            desfireCommand.Command = (byte)DesfireCommand.CommandType.GetAdditionalFrame;
            desfireRes             = await connectionObject.TransceiveAsync(desfireCommand) as DesfireResponse;

            if (!desfireRes.SubsequentFrame || desfireRes.ResponseData.Length != 7)
            {
                // Not expected
                return(null);
            }
            card.SoftwareVendorID     = desfireRes.ResponseData[0];
            card.SoftwareType         = desfireRes.ResponseData[1];
            card.SoftwareSubType      = desfireRes.ResponseData[2];
            card.SoftwareMajorVersion = desfireRes.ResponseData[3];
            card.SoftwareMinorVersion = desfireRes.ResponseData[4];
            card.SoftwareStorageSize  = desfireRes.ResponseData[5];
            card.SoftwareProtocolType = desfireRes.ResponseData[6];

            desfireRes = await connectionObject.TransceiveAsync(desfireCommand) as DesfireResponse;

            if (!desfireRes.SucceededDesfire || desfireRes.ResponseData.Length != 14)
            {
                // Not expected
                return(null);
            }

            card.UID = new byte[7];
            System.Buffer.BlockCopy(desfireRes.ResponseData, 0, card.UID, 0, 7);

            card.ProductionBatchNumber = new byte[5];
            System.Buffer.BlockCopy(desfireRes.ResponseData, 7, card.ProductionBatchNumber, 0, 5);

            card.WeekOfProduction = desfireRes.ResponseData[12];
            card.YearOfProduction = desfireRes.ResponseData[13];

            return(card);
        }
示例#6
0
        public async Task <byte[]> GetFileSettingsAsync(byte fileNumber)
        {
            desfireCommand.Command     = (byte)DesfireCommand.CommandType.GetFileSettings;
            desfireCommand.CommandData = new byte[] { fileNumber };

            DesfireResponse desfireRes = await connectionObject.TransceiveAsync(desfireCommand) as DesfireResponse;

            if (!desfireRes.Succeeded)
            {
                throw new Exception("Failure getting file settings SW=" + desfireRes.SW);
            }
            return(desfireRes.ResponseData);
        }
示例#7
0
        /// <summary>
        /// Select ICC application by AID
        /// </summary>
        /// <param name="aid">
        /// application id
        /// </param>
        public async Task SelectApplicationAsync(byte[] aid)
        {
            if (aid.Length != 3)
            {
                throw new NotSupportedException();
            }

            desfireCommand.Command = (byte)DesfireCommand.CommandType.SelectApplication;
            desfireCommand.Data    = aid;

            DesfireResponse desfireRes = await connectionObject.TransceiveAsync(desfireCommand) as DesfireResponse;

            if (!desfireResponse.SucceededDesfire)
            {
                throw new Exception("Failure selecting application, SW=" + desfireResponse.SW + " (" + desfireResponse.SWTranslationDesfire + ")");
            }
        }
示例#8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="aid"></param>
        /// <returns></returns>
        public async Task <byte[]> getFiles(byte[] aid)
        {
            System.Diagnostics.Debug.WriteLine("PCSCSDK: Get files for AID " + BitConverter.ToString(aid));
            await SelectApplicationAsync(aid);

            desfireCommand.Command     = (byte)(DesfireCommand.CommandType.GetFiles);
            desfireCommand.CommandData = null;
            System.Diagnostics.Debug.WriteLine("PCSCSDK: Fetch file index!");
            DesfireResponse desfireRes = await connectionObject.TransceiveAsync(desfireCommand) as DesfireResponse;

            if (!desfireRes.Succeeded)
            {
                System.Diagnostics.Debug.WriteLine("PCSCSDK: !!! FAILED TO GET FILE INDEX SW=" + desfireRes.SW + " ( " + desfireRes.SWTranslation + " ) ");
                throw new Exception("Failure listing files SW=" + desfireRes.SW);
            }

            return(desfireRes.ResponseData);
        }
示例#9
0
        /// <summary>
        /// Request the list of ICC application IDs from the card.
        ///
        /// nb: this selects ICC application ID <code>0x00 0x00 0x00</code>
        /// </summary>
        /// <returns>Array of application IDs as unparsed byte IDs</returns>
        public async Task <byte[][]> GetApplicationIds()
        {
            // The first thing we must do is select application id 0x00000

            System.Diagnostics.Debug.WriteLine("PCSCSDK: Attempt to swap to AID 0x000000");
            await SelectApplicationAsync(new byte[] { 0x00, 0x00, 0x00 });

            System.Diagnostics.Debug.WriteLine("PCSCSDK: Swap to AID 0x000000 OK");


            // then, we can request the index of application IDs
            desfireCommand.Command = (byte)DesfireCommand.CommandType.GetApplicationDirectory;
            desfireCommand.Data    = null;

            // Transceive and get the response

            System.Diagnostics.Debug.WriteLine("PCSCSDK: Attempt to fetch application directory");

            DesfireResponse desfireRes = await connectionObject.TransceiveAsync(desfireCommand) as DesfireResponse;

            if (desfireRes.BoundaryError)
            {
                throw new Exception("Couldn't get application IDs from desfire card");
            }
            System.Diagnostics.Debug.WriteLine("PCSCSDK: Got application directory.");
            // buffer that holds our application IDs.
            byte[] buffer = new byte[desfireRes.ResponseData.Length];
            // copy the recieved information into our buffer. We won't work on them *quite* yet.
            Array.Copy(desfireRes.ResponseData, buffer, buffer.Length);

            // If there are more than 19 AIDs, there's going to be another frame.
            // Theoretically, there's a maximum of 28 AIDs that can be registered to a card, however
            // it's not entirely clear.
            if (desfireRes.SubsequentFrame)
            {
                System.Diagnostics.Debug.WriteLine("PCSCSDK: Need additional frame for AID list");
                desfireCommand.Command = (byte)DesfireCommand.CommandType.GetAdditionalFrame;
                desfireCommand.Data    = null;
                desfireRes             = await connectionObject.TransceiveAsync(desfireCommand) as DesfireResponse;

                if (desfireRes.SubsequentFrame)
                {
                    System.Diagnostics.Debug.WriteLine("PCSCSDK: Too many frames for AID list.");
                    // Unexpected: There should be no more than 3 frames.
                    return(null);
                }
                // resize the array to be the current size of the array + the size of the responded data.
                Array.Resize(ref buffer, buffer.Length + desfireRes.ResponseData.Length);
                // Now, copy the data from the latest response, offset forward against the current buffer length
                int offset = buffer.Length;
                Array.Copy(desfireRes.ResponseData, 0, buffer, offset, desfireRes.ResponseData.Length);
            }

            // Each AID is 3 bytes
            int count = buffer.Length / 3;

            // There should not be > 28 application IDs.
            if (count > 28)
            {
                return(null);
            }
            // a token holder.
            int aIdx = 0;

            // A horrible type, forged in the bowels of hell.
            byte[][] ids = new byte[count][];

            // Walk the wrapper.
            while (aIdx < count)
            {
                int    idx  = aIdx * 3;
                byte[] atmp = new byte[3];
                Array.Copy(buffer, idx, atmp, 0, 3);
                System.Diagnostics.Debug.WriteLine("Got AID " + BitConverter.ToString(atmp));
                ids[aIdx] = atmp;
                aIdx++;
            }
            System.Diagnostics.Debug.WriteLine("Got " + count + " AIDs");
            return(ids);
        }