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); } }
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);
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)); } }
private IRawConvertible HandleVersionRequest(byte[] rawData, IO_CTL_XFER_MESSAGE request) { var _ = new VersionRequest(rawData); // validate request data; return(new VersionResponse("U2F_V2")); }