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

Add standalone fido services #2183

Closed
wants to merge 2 commits into from
Closed

Conversation

p1gp1g
Copy link
Contributor

@p1gp1g p1gp1g commented Feb 19, 2024

This PR gives user the ability to use FIDO services with applications using the microG FIDO library (org.microg.gms:play-services-fido), like the Fennec browser, even if they don't have signature spoofing on their system.

This PR allows users to use FIDO services with applications using the microG FIDO library (org.microg.gms:play-services-fido), such as the Fennec browser, even if there is no signature spoofing on their system. Specifically, it will (finally) allow everyone to use non-discoverable FIDO credentials and physical security keys on Android.

To achieve this:

  1. The base module has been edited to allow requests to an additional package. Currently, it tries the GMS (com.google.android.gms) package, or itself. With the patch, it tries the GMS package, the additionnal package if provided or itself.
  2. I've added org.microg.gms.fido.app as the additional allowed package for the FIDO requests.
  3. I've added a standalone application named microG FIDO Services (org.microg.gms.fido.app).

To test it, you can use this demo application : https://github.com/p1gp1g/androidfido2demo . You need to use a system without microG, PlayService, or signature spoofing.

  1. Register a username on https://webauthn.io (I've not set the registration on the demo app)
  2. Install the microG FIDO Serivces application
  3. Install the demo app, and try to login : it should work !

PS: This idea of obtaining user-installable services without signature spoofing, working with applications using microG libraries as a (drop-in) replacement for Google libraries, can perhaps be extended to other functions.

This allows users to use some microG services with non-system app
@p1gp1g p1gp1g mentioned this pull request Feb 19, 2024
@mar-v-in
Copy link
Member

Hi @p1gp1g. Thanks for the PR.

The idea is that apps that want to use org.microg.gms:play-services-fido on devices that have neither microG nor official Google Play Services can just also add org.microg.gms:play-services-fido-core to their package. This way there would be no requirement to ship an additional app. That's why it tries to also connect to itself.

We already used this model with wide success for the exposure notifications API in CCTG, see https://codeberg.org/corona-contact-tracing-germany/cwa-android

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 19, 2024

Thanks for the reply.

I've seen that you were recommended it, and I think that's a good solution. Nevertheless, some project just want to change com.google.android.gms:play-services-fido to org.microg.gms:play-services-fido without adding org.microg.gms:play-services-fido-core, such as Fennec does.

While adding org.microg.gms:play-services-fido-core is still the recommended way, this standalone service will allow us to use the FIDO services for these projects too.

I think some app just want to avoid google proprietary blobs, and they just change the group of the import part. Maybe other project want to avoid some side effects. For instance, there was a crash that blocked Fennec to use it back in the days and with an external service it would have crash that service and not the client app.


To resume:

  • Recommended way: using org.microg.gms:play-services-fido and org.microg.gms:play-services-fido-core
  • If a project only use org.microg.gms:play-services-fido, then user can install microG FIDO Services

@ale5000-git
Copy link
Member

ale5000-git commented Feb 19, 2024

@p1gp1g

  1. If a device doesn't have signature spoofing and doesn't have GApps it can still install microG as is now.
    Apps compiled with Google libraries will not work but apps compiled with microG libraries will still work regardless of signature spoofing.

  2. I'm not sure if the change must be done in the microG library or in the app itself but if the Fido service run in a different process (in the same app) then it will not crash the app when the service crash.
    See here: https://stackoverflow.com/a/50231499

@mar-v-in
Copy link
Member

Maybe other project want to avoid some side effects. For instance, there was a crash that blocked Fennec to use it back in the days and with an external service it would have crash that service and not the client app.

I'd rather see any issues arising with the embedding of -core modules being fixed rather than doing a workaround by requiring the user to install another package without any guidance on the process.

Given that the Fido service stores credentials (when using fingerprint unlock or soon-to-be-supported passkeys), it's important that users are aware of its existence and its purpose. An additional service app without any UI is not really helpful for this.

Also, as @ale5000-git already mentions: everyone that can make use of this service could also just install and use regular microG services (as a user app and without the need for signature spoofing) and will have the same results.

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 19, 2024

Also, as @ale5000-git already mentions: everyone that can make use of this service could also just install and use regular microG services (as a user app and without the need for signature spoofing) and will have the same results.

In many systems, the application with the identifier com.google.android.gms is handled in a special way. It is even not possible to install a regular application with this id on some systems. And installing a regular microG services with this id leads to many side effects for other applications that expect working PlayServices and therefore is something to avoid.

In a first time, I thought about adding the possibility to use microG Services as a regular user app with its proper id (see p1gp1g@895bae1).
Then I thought it would even makes more sense to have extremely light feature-package (like OpenCV does), for some reason:

  • ATM there would be a single feature supporting it, but it could be extended to other
  • A user may want to use a single service

@mar-v-in
Copy link
Member

mar-v-in commented Feb 19, 2024

In many systems, the application with the identifier com.google.android.gms is handled in a special way. It is even not possible to install a regular application with this id on some systems. And installing a regular microG services with this id leads to many side effects for other applications that expect working PlayServices and therefore is something to avoid.

I haven't encountered any system where it was not possible to install a package with the package name com.google.android.gms except for those where it is already installed. A special handling of the package name on the operating system itself when installed as a user app is at least not part of AOSP and I really wouldn't expect derivatives to add special handling for non-system apps - other than maybe to provide signature spoofing or another level of compatibility.

Applications that try to use com.google.android.gms that use original Google Play Services client library will check its signature, so if your system does not have signature spoofing or you don't enable it, applications should behave the same as if it was not installed. If apps use the microG variant of the client library, they will be able to connect and use microG, which I would generally consider desirable.

I think I would generally be fine with allowing the use of the org.microg.gms package as a fallback when com.google.android.gms is not present (doing so for all APIs, not just FIDO) and then add a build flavor of the microG Service app that build to a different package name. So at least there will be only a single service app to be installed and it already comes with all the UI. However I already fear the amount of users having problems because they picked the wrong variant. We had this with UnifiedNlp before.

Android's package system is really not build for "library" or "service" packages. It might be suitable for you and some other power users, but not for the majority of the users. We already have enough users complaining because of ReVanced microG (a weird fork of microG only intended for using a patched YouTube app).

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 19, 2024

In many systems, the application with the identifier com.google.android.gms is handled in a special way. It is even not possible to install a regular application with this id on some systems. And installing a regular microG services with this id leads to many side effects for other applications that expect working PlayServices and therefore is something to avoid.

I haven't encountered any system where it was not possible to install a package with the package name com.google.android.gms except for those where it is already installed. A special handling of the package name on the operating system itself when installed as a user app is at least not part of AOSP and I really wouldn't expect derivatives to add special handling for non-system apps - other than maybe to provide signature spoofing or another level of compatibility.

Applications that try to use com.google.android.gms that use original Google Play Services client library will check its signature, so if your system does not have signature spoofing or you don't enable it, applications should behave the same as if it was not installed. If apps use the microG variant of the client library, they will be able to connect and use microG, which I would generally consider desirable.

GrapheneOS doesn't allow it at least. And there are some applications not using the original client library that will have side effects, like the mastodon application. [EDIT: but a working regular-app microG services will probably allow FCM push notif for mastodon then (BTW, a FOSS firebase-messaging may be something interesting to do, we already have FOSS code for clients)]

I think I would generally be fine with allowing the use of the org.microg.gms package as a fallback when com.google.android.gms is not present (doing so for all APIs, not just FIDO) and then add a build flavor of the microG Service app that build to a different package name. So at least there will be only a single service app to be installed and it already comes with all the UI. However I already fear the amount of users having problems because they picked the wrong variant. We had this with UnifiedNlp before.

That was another reason I thought about in favor of a proper feature only service. I can edit that PR in this way if you want.

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 19, 2024

What is the best order to check for the service ?

  1. com.google.android.gms > self > org.microg.gms
  2. com.google.android.gms > org.microg.gms > self

@ale5000-git
Copy link
Member

@mar-v-in
It would be nice to add a build flavor for org.microg.gms, but to avoid confusion I suggest to do these:

  1. Don't create it by default when someone just use gradlew build but require a specific command to compile it;
  2. Call it "microG User Services" instead of "microG Services";
  3. Don't add the apk on github and don't add the apk on https://microg.org/download.html but add a link in the page https://microg.org/download.html to a separate page under https://microg.org/ with a detailed explanation of it.

What do you think?
I also think that it should be able to coexist with normal microG so it can be used by developers to do test on microG without mess up with the entire system.

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 19, 2024

This is a bit related to this. What do you think about providing a reimplementation of firebase-messaging ? Most of the proprietary blobs are already written and we already have foss client-side code. With microG version of firebase-messaging, org.microg.gms would be able to be used too.

@mar-v-in
Copy link
Member

mar-v-in commented Feb 19, 2024

@ale5000-git The problem with your approach is that it doesn't cover updates. If we want to provide updates, we should do it through f-droid, but if we do it through f-droid (default or microG repository doesn't matter) it will confuse users that don't need it in any way. "microG User Services" and "microG Services" sound very similar, especially for people that don't speak English.

@p1gp1g That's a very good question. The problem if we give org.microg.gms priority over self, is that apps that have -core built-in will stop use their local storage as soon as org.microg.gms is installed, which is something we seem to expect to happen at runtime. This would be very bad for the user as they may lose access to their on-device/software FIDO keys / Passkeys. However, if we prioritize self over org.microg.gms, if you have one browser that has -core and one that doesn't, they wouldn't share keys. I guess I prefer the second over the first though.

I didn't know GrapheneOS does not allow installing packages with the name com.google.android.gms that are not the official Play Services. I guess that is because they give certain special privileges to that package to make it work and they don't want "untrusted" apps to be able to use those (although I wouldn't call original Play Services "trusted" either).

Regarding firebase-messaging: Yes, adding support for it is also on my list (we already do have play-services-gcm, which previously was used for GCM/FCM). I also did some documentation on how to do push without it for FOSS app developers at https://gist.github.com/mar-v-in/2a054e3a4c0a508656549fc7d0aaeb74.
And I was also thinking to provide a general purpose, FOSS push notification library, that works on official Play Services, microG, UnifiedPush, Web and potentially others by making use of the WebPush server-side protocol (so that apps developers only have to support one push protocol on the server side, but that one is decentralized).

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 19, 2024

@ale5000-git The problem with your approach is that it doesn't cover updates. If we want to provide updates, we should do it through f-droid, but if we do it through f-droid (default or microG repository doesn't matter) it will confuse users that don't need it in any way. "microG User Services" and "microG Services" sound very similar, especially for people that don't speak English.

@p1gp1g That's a very good question. The problem if we give org.microg.gms priority over self, is that apps that have -core built-in will stop use their local storage as soon as org.microg.gms is installed, which is something we seem to expect to happen at runtime. This would be very bad for the user as they may lose access to their on-device/software FIDO keys / Passkeys. However, if we prioritize self over org.microg.gms, if you have one browser that has -core and one that doesn't, they wouldn't share keys.

I think we can do some tests for this, if moving from self to gms changes something. The keys are stored on the TPM with uniq ids, and it may be able to use them even if we change the app requesting it.

I didn't know GrapheneOS does not allow installing packages with the name com.google.android.gms that are not the official Play Services. I guess that is because they give certain special privileges to that package to make it work and they don't want "untrusted" apps to be able to use those (although I wouldn't call original Play Services "trusted" either).

I think too

Regarding firebase-messaging: Yes, adding support for it is also on my list (we already do have play-services-gcm, which previously was used for GCM/FCM). I also did some documentation on how to do push without it for FOSS app developers at https://gist.github.com/mar-v-in/2a054e3a4c0a508656549fc7d0aaeb74. And I was also thinking to provide a general purpose, FOSS push notification library, that works on official Play Services, microG, UnifiedPush, Web and potentially others by making use of the WebPush server-side protocol (so that apps developers only have to support one push protocol on the server side, but that one is decentralized).

That's on my todo list too, I'd be happy to work on this with you. For the FOSS library, I've done this already, and some projects already use it (nextcloud neon and schildichat) : https://github.com/UnifiedPush/android-foss_embedded_fcm_distributor/

@mar-v-in
Copy link
Member

mar-v-in commented Feb 19, 2024

The keys are stored on the TPM with uniq ids, and it may be able to use them even if we change the app requesting it.

With Passkeys, there is the need of auxiliary discovery data to be stored that can't go into the TPM, so this wouldn't be an option anymore soon.

For the FOSS library, I've done this already, and some projects already use it

The advantage of my idea is to actually use WebPush. FCM allows receiving push events via WebPush with VAPID natively, as does UnifiedPush and Web browsers, so as long as the pushing server supports WebPush with VAPID, it could send to all of them if there were client library supporting this usecase. WebPush by design does not require the server to be registered apriori to the push provider, instead registration happens through the client at push registration time (the app still needs to be registered for FCM though). This means that in decentralized environments (like Matrix, JMAP, XMPP) we don't need a centralized (per-app) proxy server to handle push notifications anymore, even if FCM compatibility is desired. And, if popular apps were to use this, people that don't use FCM can still have their push notifications delivered through other means via UnifiedPush.

@ale5000-git
Copy link
Member

ale5000-git commented Feb 19, 2024

@mar-v-in
What about a separate F-Droid repository for the user microG (I mean separate from the repository of the standard microG)?

For the name I'm not sure what name can be good but we may ask others to suggest.


The problem if we give org.microg.gms priority over self, is that apps that have -core built-in will stop use their local storage as soon as org.microg.gms is installed, which is something we seem to expect to happen at runtime.

I think that the first time the app is executed should detect what to use and store the value in their data so that even if another app with higher priority became available it keep using the one stored in settings (if it is still avaiable).

@mar-v-in
Copy link
Member

mar-v-in commented Feb 19, 2024

I think that the first time the app is executed should detect what to use and store the value in their data so that even if another app with higher priority became available it keep using the one stored in settings (if it is still avaiable).

Yes, that's probably a good option (not on first app execution, but on app first use of a certain API). And then we go with com.google.android.gms > org.microg.gms > self, because you would never lose access to already stored keys. It might be a little bit confusing in some rare cases, but for the majority of users will be the best way to handle this.

@ale5000-git
Copy link
Member

ale5000-git commented Feb 19, 2024

Yes, that's probably a good option (not on first app execution, but on app first use of a certain API).

But in this case you may end up with having have the same app that use an API from base microG, a second API from user microG and a third API from self, it would be confusing.

@mar-v-in
Copy link
Member

mar-v-in commented Feb 19, 2024

Yes, but some APIs might be not a good idea to ship with the app and should rather fail when used. e.g. if FIDO API is used with internal storage, you might want to still not use some other API with internal storage.

I would hope and expect that users don't have microG Service and microG User Service installed at the same time (in fact we should display warning if they do), so it's only between self and shared service, and it's up to the app that embeds -core how and if they want to handle and communicate that to users. In most cases it's probably going to be fine, because if user's are changing anything on their system, it wouldn't affect the status quo.

CCTG, for example, was showing a message in some details screen to let the user know if bundled -core is used or if microG Service app is used.

@ale5000-git
Copy link
Member

We should also expect users that have a ROM with bundled microG (with custom signature); in case the ROM author no longer update the ROM (and doesn't give a way to update microG) then the user may want to use User microG instead.

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 19, 2024

For the FOSS library, I've done this already, and some projects already use it

The advantage of my idea is to actually use WebPush. FCM allows receiving push events via WebPush with VAPID natively, as does UnifiedPush and Web browsers, so as long as the pushing server supports WebPush with VAPID, it could send to all of them if there were client library supporting this usecase. WebPush by design does not require the server to be registered apriori to the push provider, instead registration happens through the client at push registration time (the app still needs to be registered for FCM though). This means that in decentralized environments (like Matrix, JMAP, XMPP) we don't need a centralized (per-app) proxy server to handle push notifications anymore, even if FCM compatibility is desired. And, if popular apps were to use this, people that don't use FCM can still have their push notifications delivered through other means via UnifiedPush.

That's what I've in mind too. We may find another place for this discussion, what do you think ? :)

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 19, 2024

@ale5000-git I think a different repository used only to hosts the user-microG builds is a good idea.

We can also show a dialog to the user if the service is installed with id org.microg.gms and com.google.android.gms is installed on the system.

@ale5000-git
Copy link
Member

Just to be more clear since my initial message was confusing before I edited it:
I mean separate F-Droid repository, the GitHub repository should be the same.

@ale5000-git
Copy link
Member

An additional thing useful for debugging would be to provide a way to query the used service via adb (in every app using microG libraries), for example:
adb shell "some_command app_internal_name"

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 19, 2024

What other feature may use self as fido/fido-core ?
Regarding FIDO services, the migration (from self to services) is only an issue for credential requests, not for credentials registration. Therefore, for the credential requests, we can request the installed services first (com.google.android.gms if installed, org.microg.gms else) and fallback to self if the credentials are not found in the services. It would avoid sticking with self if the user install the services. What do you think ?

And how do you want to do your shell command ? Like a broadcast + logcat ?

@mar-v-in
Copy link
Member

mar-v-in commented Feb 19, 2024

What other feature may use self as fido/fido-core ?

Most features that are actually useful could also be bundled as -core. Location, Maps, Nearby, ReCaptcha, Vision, Firebase, ... We don't have the code for most of them yet (and/or haven't tested it yet).

Regarding FIDO services, the migration (from self to services) is only an issue for credential requests, not for credentials registration. Therefore, for the credential requests, we can request the installed services first (com.google.android.gms if installed, org.microg.gms else) and fallback to self if the credentials are not found in the services. It would avoid sticking with self if the user install the services. What do you think ?

I once built a more complex solution for location. I'd like to not do that again. It means a lot of complexity that needs to be maintained (e.g. Google might change the APIs) and is always on a case-by-case basis. A generic solution based on the API connection doesn't have that issue, that's why I prefer if everythings works generic, even if this meant some minimal downside for users that change how they use microG APIs.

Regarding shell command: I think that's a nice to have that we don't need to think about just yet.

@ale5000-git
Copy link
Member

And how do you want to do your shell command ? Like a broadcast + logcat ?

It is a low priority thing but I think broadcast could be easily parsed by a shell script on the PC compared to logcat.
In the future I will write a script to get info via adb about various microG things so if everything can be automatized it will be better.

@LuccoJ
Copy link

LuccoJ commented Feb 19, 2024

However I already fear the amount of users having problems because they picked the wrong variant. We had this with UnifiedNlp before.

FWIW, I am convinced most of the confusion there stemmed from the way F-Droid (mis)handled packages with the same package name and would show UnifiedNLP (no GAPPS) instead of microG even when people had the microG repository enabled... It was an issue for years, and actual issues were filed about it, but somehow it kept being an issue for a long time anyway.

I say this as an op in #microG (Libera and Matrix) too, where I've witnessed this confusion a number of times, and I really don't think it would have happened with a package that had another name, or with F-Droid handling the overlap better.

@chirayudesai
Copy link
Contributor

F-Droid (mis)handled packages with the same package name

https://f-droid.org/en/packages/com.google.android.gms it's solved now at least.

There's still https://f-droid.org/en/packages/com.google.android.location/ and https://f-droid.org/en/packages/org.microg.nlp/ but that's unrelated.

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 25, 2024

Closing, superseded by #2188

@p1gp1g p1gp1g closed this Feb 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants