Пример #1
0
        public void StartIoLoop(CancellationToken token)
        {
            IRawConvertible     response = null;
            IO_CTL_XFER_MESSAGE replyTo  = default;

            while (!token.IsCancellationRequested)
            {
                replyTo  = SendInitRequest(out var nTransferred, out var data, response, replyTo);
                response = HandleRequest(data, replyTo);
            }
        }
Пример #2
0
        private IRawConvertible HandleRegisterRequest(byte[] rawData, IO_CTL_XFER_MESSAGE request)
        {
            var req   = new RegisterRequest(rawData);
            var facet = KnownFacets.GetKnownFacet(req.ApplicationParameter);
            var ss    = Encoding.UTF8.GetString(req.ApplicationParameter);

            if (facet == "bogus")
            {
                return(CreateError(ProtocolErrorCode.OtherError));
            }

            if (!UserPresence.Present)
            {
                UserPresence.AskAsync(UserPresence.PresenceType.Registration, facet);
                return(CreateError(ProtocolErrorCode.ConditionNoSatisfied));
            }

            UserPresence.Take();
            U2FRegistration reg;

            try
            {
                reg = new U2FRegistration(req.ApplicationParameter);
            }
            catch
            {
                return(CreateError(ProtocolErrorCode.OtherError));
            }

            var publicKey = reg.KeyPair.PublicKey;

            if (publicKey == null)
            {
                return(CreateError(ProtocolErrorCode.OtherError));
            }

            var payloadSize = 1 + req.ApplicationParameter.Length + req.ChallengeParameter.Length +
                              reg.KeyHandle.Length + publicKey.Length;

            var sigPayload = new List <byte>(payloadSize);

            sigPayload.Add(0);
            sigPayload.AddRange(req.ApplicationParameter);
            sigPayload.AddRange(req.ChallengeParameter);
            sigPayload.AddRange(reg.KeyHandle);
            sigPayload.AddRange(publicKey);

            var sig  = Signature.SignData(sigPayload.ToArray());
            var resp = new RegisterResponse(publicKey, keyHandle: reg.KeyHandle,
                                            certificate: Signature.GetCertificatePublicKeyInDer(), signature: sig);

            return(resp);
        }
        private IO_CTL_XFER_MESSAGE SendInitRequest(out uint nTransferred, out byte[] data,
                                                    IRawConvertible response = null, IO_CTL_XFER_MESSAGE replyTo = default)
        {
            nTransferred = 0;
            data         = default;
            var      outputBuffer       = new byte[MAX_BCNT + IO_CTL_XFER_MESSAGE_LEN];
            var      outputBufferHandle = GCHandle.Alloc(outputBuffer, GCHandleType.Pinned);
            var      outputBufferPtr    = outputBufferHandle.AddrOfPinnedObject();
            var      outputBufferLen    = (uint)outputBuffer.Length;
            GCHandle inputBufferHandle  = default;

            var  inputBufferPtr = IntPtr.Zero;
            uint inputBufferLen = 0;

            if (response != null)
            {
                var reply = new IO_CTL_XFER_MESSAGE();
                reply.cid  = replyTo.cid;
                reply.cmd  = replyTo.cmd;
                reply.bcnt = (short)response.Raw.Length;

                var messageHeader = StructToBytes(reply);

                var inputBuffer = messageHeader.Concat(response.Raw).ToArray();
                inputBufferHandle = GCHandle.Alloc(inputBuffer, GCHandleType.Pinned);
                inputBufferPtr    = inputBufferHandle.AddrOfPinnedObject();
                inputBufferLen    = (uint)inputBuffer.Length;
            }

            var result = DeviceIoControl(
                _device,
                IOCTL_SOFTU2F_FILTER_INIT,
                inputBufferPtr, inputBufferLen,
                outputBufferPtr, outputBufferLen,
                ref nTransferred, IntPtr.Zero);

            if (result == 0)
            {
                return(default);
Пример #4
0
        private IRawConvertible HandleRequest(byte[] data, IO_CTL_XFER_MESSAGE request)
        {
            try
            {
                var ins = Command.CommandType(data);

                IRawConvertible response;
                switch (ins)
                {
                case CommandCode.Register:
                    response = HandleRegisterRequest(data, request);
                    break;

                case CommandCode.Version:
                    response = HandleVersionRequest(data, request);
                    break;

                case CommandCode.Authenticate:
                    response = HandleAuthenticationRequest(data, request);
                    break;

                default:
                    response = CreateError(ProtocolErrorCode.InsNotSupported);
                    break;
                }

                return(response);
            }
            catch (ProtocolError e)
            {
                return(CreateError(e.ErrorCode));
            }
            catch
            {
                return(CreateError(ProtocolErrorCode.OtherError));
            }
        }
Пример #5
0
        private IRawConvertible HandleVersionRequest(byte[] rawData, IO_CTL_XFER_MESSAGE request)
        {
            var _ = new VersionRequest(rawData); // validate request data;

            return(new VersionResponse("U2F_V2"));
        }