Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing OpenSK-based FIDO2 emulator for QEMU #485

Closed
egor-duda opened this issue May 29, 2022 · 11 comments
Closed

Implementing OpenSK-based FIDO2 emulator for QEMU #485

egor-duda opened this issue May 29, 2022 · 11 comments
Assignees
Labels
duplicate This issue or pull request already exists enhancement New feature or request

Comments

@egor-duda
Copy link
Contributor

I've made a quick-and-dirty prototype of virtual FIDO2 authenticator for QEMU using OpenSK application. The purpose is similar to #288, but instead of creating a CTAP library and linking it into QEMU, I've patched QEMU to add a fido2 device, which uses socket-connected chardev. Then I've modified main OpenSK application to listen on a unix socket and, after connection from QEMU, to process all CTAP requests/responses via that socket connection.

To go beyond prototype, I suppose I have to:

  1. Create separate NonEmbeddedEnv (naming suggestions are welcome) for running on non-embedded OS
  2. Implement file-based storage for persistent authenticator data. Currently I've used TestEnv with its BufferStorage, which means that master key is being lost after OpenSK application restart, making all previously created credentials invalid
  3. Move main protocol I/O function from loop in src/main.rs to Env, and implement socket- or stdio- based I/O in NonEmbeddedEnv
  4. Implement user-presence checking in new NonEmbeddedEnv

Obviously, all this new NonEmbeddedEnv stuff should not be compiled in when building token-targeted version of an application.

Is this a viable plan?

@kaczmarczyck kaczmarczyck self-assigned this May 31, 2022
@kaczmarczyck kaczmarczyck added the enhancement New feature or request label May 31, 2022
@kaczmarczyck
Copy link
Collaborator

May I ask if you have a specific goal in mind? Is QEMU the purpose like in #288, or do you want a desktop OpenSK?

Let me elaborate a bit on our current work in progress. We noticed that OpenSK is more testable and more broadly usable if its logic was separate from the platform it runs on. With that in mind, we started splitting everything TockOS-related into TockEnv. (It looks like you found that, and noticed that it's infinished.) Some functions in TockEnv still contain CTAP logic, that needs a cleaner sparation. Generally, we haven't converged on the best API and Env trait yet.
All of this is tracked under a project.

Once that is finished, you will be able to support a new platform by adding a new Env, i.e. what you call NonEmbeddedEnv (I agree we'd need a different name ^^). That would hopefully be easier than it is right now. So your plan is pretty viable!

Since you were asking for "beyond prototype", I assume you mean that you want to create a PR that we would eventually merge. Cleanest and easiest would be for us to first finish the CTAP library, and then merging your new NonEmbeddedEnv. Else we'd have to port yet another platform to the new API. Afterwards, you could use that desktop version of OpenSK for whatever you want, for example QEMU. Is this a helpful answer for what you have in mind?

@egor-duda
Copy link
Contributor Author

May I ask if you have a specific goal in mind? Is QEMU the purpose like in #288, or do you want a desktop OpenSK?

QEMU, mostly.

I've experimented with running desktop version of OpenSK (on Linux, using /dev/uhid), but I don't see the point, security-wise, of running authenticator on the same host system with user agent. Maybe only for testing/development?

[...]

All of this is tracked under a project.

Great!

I've implemented storage which stores its contents in host-OS-based file: https://github.com/egor-duda/OpenSK/tree/hostenv-file-storage
This change is independent of Env-related changes -- shall I make a PR from it?

[...]

Since you were asking for "beyond prototype", I assume you mean that you want to create a PR that we would eventually merge. Cleanest and easiest would be for us to first finish the CTAP library, and then merging your new NonEmbeddedEnv. Else we'd have to port yet another platform to the new API. Afterwards, you could use that desktop version of OpenSK for whatever you want, for example QEMU. Is this a helpful answer for what you have in mind?

Absolutely, thanks for detailed response!

@kaczmarczyck
Copy link
Collaborator

I've experimented with running desktop version of OpenSK (on Linux, using /dev/uhid), but I don't see the point, security-wise, of running authenticator on the same host system with user agent. Maybe only for testing/development?

Testing is definitely a plus. One real world example (that doesn't necessairly require file storage) of desktop security key implementations might be Chrome's WebAuthn debugger.
Outside of testing, I'll leave it to the community to decide what use cases they have in mind. Security keys as a file at least make backups a lot easier :) It's a bit like a password manager - with different cryptographic properties.

This change is independent of Env-related changes -- shall I make a PR from it?

The maintenance question still applies. Changing the storage API would be a bit harder. But I agree this is something we will find useful eventually. Maybe @ia0 wants to jump in here wrt storage?

@ia0
Copy link
Member

ia0 commented Jun 1, 2022

Regarding storage, the proposed implementation is a valid idea (adding a file-based Storage implementation). I'm not sure why the BufferStorage is used though, since the file is probably going to be in RAM anyway, so it's not even more performant. Then there are a few technical aspects too. But overall it's a PR that could be merged.

@egor-duda
Copy link
Contributor Author

I'm not sure if it's possible to make pure file-based storage without memory buffer using current API?

read_slice returns a reference, which means, as far as I understand, than underlying storage object must own all those slices' data, and keep it while application is running.

@ia0
Copy link
Member

ia0 commented Jun 1, 2022

I see. That's actually a good reason to change the API then. I was considering it for other reasons (in particular make it compatible with embedded-storage), but this one adds to it. Might be worth checking whether it's easy to do and if it changing the binary size in any way.

@jmichelp
Copy link
Collaborator

jmichelp commented Jun 1, 2022

Although for test/debug purposes I don't see objections to a storage serialized on drive, for a "normal" usage, I'd prefer to see the file at least encrypted and if possible using a key derived from hardware unique IDs for security reasons. Otherwise the storage end up being nothing more than a cookie jar that could be stolen by a malware while the promise of FIDO is to resist a remote attacker.

@egor-duda
Copy link
Contributor Author

Otherwise the storage end up being nothing more than a cookie jar that could be stolen by a malware while the promise of FIDO is to resist a remote attacker.

The idea is to have file-backed storage residing on the host OS, on which QEMU is running, whereas user agent runs on the guest, accessing authenticator via virtual QEMU device. Presumably, malware shouldn't be able to escape from guest VM and access any data on host OS.

If malware somehow succeeds in reaching host OS, then I don't think file encryption would be of much help. If malware gets non-root access to host OS, then normal OS permission protection should be enough. If malware escapes from guest and gets root-level access to host OS, then it would be able to get decrypted storage from memory of running authenticator application.

@kaczmarczyck
Copy link
Collaborator

@ia0 is looking into solutions to enable file storage (#486, #487). Outside of that, any other plans regarding implementation for this issue? Feel free to reach out to discuss if you are interested!

@kaczmarczyck
Copy link
Collaborator

Some thoughts on transports in FIDO. Generally, the WebAuthn transport we would use is this internal. However, CTAP only mentions HID, NFC and BLE. Since WebAuthn allows it, I believe we should be okay to use it regardless. The intention I read into the specification is: If you don't use special hardware, implement it any way you like.

If you want the security key to look like a HID (or other) device, we might have to approach that differently. The question is at what level you want to exchange data.

@kaczmarczyck
Copy link
Collaborator

Closing this as a duplicate of #288 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists enhancement New feature or request
Projects
Status: Dependencies
Development

No branches or pull requests

4 participants