示例#1
0
        public static InitializationPacket ReadFrom(ArraySegment <byte> segment)
        {
            if (segment.Count < NoDataSize)
            {
                throw new InvalidPacketSizeException(segment,
                                                     $"Data is too small, expected {NoDataSize} bytes but provided only {segment.Count}");
            }

            var result = new InitializationPacket();

            using (var stream = new MemoryStream(segment.Array, segment.Offset, segment.Count))
            {
                var reader = new EndianReader(stream, Endianness.BigEndian);
                result.ChannelIdentifier = reader.ReadUInt32();
                result.CommandIdentifier = reader.ReadByte();

                CheckCommand(segment, result.CommandIdentifier);

                var payloadLengthHi = reader.ReadByte();
                var payloadLengthLo = reader.ReadByte();
                result.PayloadLength = (ushort)(payloadLengthHi << 8 | payloadLengthLo);
            }

            var remainingBytes = Math.Min(segment.Count - NoDataSize, result.PayloadLength);

            result.Data = new ArraySegment <byte>(segment.Array, segment.Offset + NoDataSize,
                                                  remainingBytes);

            return(result);
        }
        public static InitializationPacket ReadFrom(ArraySegment<byte> segment)
        {
            if (segment.Count < NoDataSize)
            {
                throw new InvalidPacketSizeException(segment,
                    $"Data is too small, expected {NoDataSize} bytes but provided only {segment.Count}");
            }

            var result = new InitializationPacket();

            using (var stream = new MemoryStream(segment.Array, segment.Offset, segment.Count))
            {
                var reader = new EndianReader(stream, Endianness.BigEndian);
                result.ChannelIdentifier = reader.ReadUInt32();
                result.CommandIdentifier = reader.ReadByte();

                CheckCommand(segment, result.CommandIdentifier);

                var payloadLengthHi = reader.ReadByte();
                var payloadLengthLo = reader.ReadByte();
                result.PayloadLength = (ushort)(payloadLengthHi << 8 | payloadLengthLo);
            }

            var remainingBytes = Math.Min(segment.Count - NoDataSize, result.PayloadLength);
            result.Data = new ArraySegment<byte>(segment.Array, segment.Offset + NoDataSize,
                remainingBytes);

            return result;
        }
        static FidoU2FHidMessage BuildMessage(InitializationPacket init, List<ContinuationPacket> continuations)
        {
            ArraySegment<byte> data;
            if (continuations.Count > 0)
            {
                // We must allocate memory to reconstruct the message
                var stream = new MemoryStream(init.PayloadLength);
                stream.Write(init.Data.Array, init.Data.Offset, init.Data.Count);
                foreach (var continuation in continuations)
                {
                    stream.Write(continuation.Data.Array, continuation.Data.Offset, continuation.Data.Count);
                }
                data = stream.ToArray().Segment();
            }
            else
            {
                // No need to reconstruct the message
                data = init.Data;
            }

            return new FidoU2FHidMessage(init.ChannelIdentifier, (U2FHidCommand)init.CommandIdentifier, data);
        }
        static Tuple<InitializationPacket, List<ContinuationPacket>> MakeOutputPackets(
            int paketLength, FidoU2FHidMessage message)
        {
            var availableInInit = paketLength - InitializationPacket.NoDataSize;
            var availableInContinuation = paketLength - ContinuationPacket.NoDataSize;
            var data = message.Data;

            var init = new InitializationPacket
            {
                ChannelIdentifier = message.Channel,
                CommandIdentifier = (byte)message.Command,
                PayloadLength = (ushort)data.Count,
                Data = new ArraySegment<byte>(data.Array, data.Offset,
                    Math.Min(data.Count, availableInInit))
            };

            var sizeHandled = init.Data.Count;
            var continuations = new List<ContinuationPacket>();
            byte sequence = 0;
            while (sizeHandled < data.Count)
            {
                var continuation = new ContinuationPacket
                {
                    ChannelIdentifier = message.Channel,
                    PaketSequence = sequence,
                    Data = new ArraySegment<byte>(data.Array, data.Offset + sizeHandled,
                        Math.Min(data.Count - sizeHandled, availableInContinuation))
                };

                continuations.Add(continuation);

                sizeHandled += continuation.Data.Count;
                sequence += 1;
            }

            return Tuple.Create(init, continuations);
        }
示例#5
0
        static unsafe void Test(Win32HidDevice device)
        {
            var init = new InitializationPacket();
            init.CommandIdentifier = (byte)U2FHidCommand.Init;
            init.ChannelIdentifier = U2FHID_BROADCAST_CID;
            init.PayloadLength = 8;
            var caps = device.Information.Capabilities;

            var buffer = new byte[caps.InputReportByteLength];

            fixed (byte* pBuffer = buffer)
            {
                Marshal.StructureToPtr(init, new IntPtr(pBuffer + 1), false);

                buffer[0] = 0x00;
                buffer[8] = 0xCA;
                buffer[9] = 0xFE;
                buffer[10] = 0xBA;
                buffer[11] = 0xBE;
                buffer[12] = 0xDE;
                buffer[13] = 0xAD;
                buffer[14] = 0xBA;
                buffer[15] = 0xBE;

                WriteBuffer(buffer);

                var task = Kernel32Dll.WriteFileAsync(device.Handle, new IntPtr(pBuffer), buffer.Length);
                var writen = task.Result;
                Console.WriteLine("Writen {0} bytes", writen);
            }

            var bufferOut = new byte[caps.OutputReportByteLength];
            fixed (byte* pBuffer = bufferOut)
            {
                var intPtr = new IntPtr(pBuffer);
                var task = Kernel32Dll.ReadFileAsync(device.Handle, intPtr, bufferOut.Length);
                var read = task.Result;
                Console.WriteLine("Read {0} bytes", read);
            }

            WriteBuffer(bufferOut);

            Wink(device, bufferOut[16], bufferOut[17], bufferOut[18], bufferOut[19]);
        }