-
Notifications
You must be signed in to change notification settings - Fork 34
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
Merging Smartcard CBA Feature into Dev #1814
Conversation
Implementing Cert Picker and PIN Dialogs for Smartcard CBA
Bump YubiKit version to public 2.1.0 release
…zureAD/microsoft-authentication-library-common-for-android into melissaahn/SmartcardCBAFeature
Codecov Report
@@ Coverage Diff @@
## dev #1814 +/- ##
============================================
- Coverage 14.79% 14.15% -0.64%
- Complexity 306 307 +1
============================================
Files 163 168 +5
Lines 6934 7317 +383
Branches 685 707 +22
============================================
+ Hits 1026 1036 +10
- Misses 5754 6127 +373
Partials 154 154
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left some suggestion - most can be done in a separate (smaller) PR.
package="com.microsoft.identity.common"> | ||
|
||
<uses-permission android:name="android.permission.INTERNET" /> | ||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> | ||
<!-- Min Sdk version for YubiKit is 19, so override is needed to avoid build errors with Common's min sdk version --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're already introducing a breaking change... maybe we should just consider bumping minSDK of our projects to 19.
Let's bring this up during standup.
...va/com/microsoft/identity/common/internal/providers/oauth2/WebViewAuthorizationFragment.java
Outdated
Show resolved
Hide resolved
...ft/identity/common/internal/ui/webview/challengehandlers/ClientCertAuthChallengeHandler.java
Outdated
Show resolved
Hide resolved
...ft/identity/common/internal/ui/webview/challengehandlers/ClientCertAuthChallengeHandler.java
Show resolved
Hide resolved
//Create and start YubiKitManager for UsbDiscovery mode. | ||
//When in Usb Discovery mode, Yubikeys that plug into the device will be accessible | ||
// once the user provides permission via the Android permission dialog. | ||
mYubiKitManager = new YubiKitManager(mActivity.getApplicationContext()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: let's try to figure out how you would extract ALL the yubikey logic from this class into one of its own. (and the regular CBA into another one).
what kind of interface would you need, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do that in a separate PR, as this one is meant to be "merge back to dev as-is" only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(This will allow us to do an easy-rollback if anything goes wrong as well).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had a chat with Brian regarding this as well. Creating an abstract class to handle the YubiKit logic for ClientCertAuthChallengeHandler will be the next PR I'll work on.
...ft/identity/common/internal/ui/webview/challengehandlers/ClientCertAuthChallengeHandler.java
Outdated
Show resolved
Hide resolved
...ft/identity/common/internal/ui/webview/challengehandlers/ClientCertAuthChallengeHandler.java
Outdated
Show resolved
Hide resolved
//Creating a PivProviderStatusEvent for Telemetry. | ||
final PivProviderStatusEvent pivProviderStatusEvent = new PivProviderStatusEvent(); | ||
//First check if a PivProvider instance is already present in the static list. | ||
if (Security.getProvider(YUBIKEY_PROVIDER) != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: could potentially extract 488-508 into a separate function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the lines have changed a bit since merging the PIN PR. Were you referring to all the PivProvider/Static List logic? (or were the lines 498-508)
...n/java/com/microsoft/identity/common/internal/ui/webview/challengehandlers/DialogHolder.java
Outdated
Show resolved
Hide resolved
...crosoft/identity/common/internal/ui/webview/challengehandlers/SmartcardCertPickerDialog.java
Outdated
Show resolved
Hide resolved
Thanks @rpdome for the review and approval. I've made changes in the latest commit that address some of the smaller comments (final, NonNull, removing some unnecessary comments).
|
Smartcard CBA
This branch contains a feature that allows AAD account users to authenticate via USB using their YubiKey. This work is being done in order to help satisfy Executive Order 14028, "Improving the Nation's Cybersecurity" .
Summary
Steps
Note: This private preview testing document has detailed steps and screenshots for testing with Authenticator and Outlook.
AuthorizationFragment
is hosting, which will prompt an Android dialog for permission to connect to the YubiKey.Some error handling has been implemented to address situations such as:
ErrorEvent
.Sub-Branches
keyboard
andkeyboardHidden
added toconfigChanges
of applicable activities within manifest.- Override for yubico.yubikit.android in order to clear error messages regarding the min sdk of Yubikit (19) being higher than ours (16).
- Basic use of YubiKit that shows detection of a YubiKey being plugged in.
- Method added to
WebviewAuthorizationFragment
that stops the detection of YubiKey devices when the fragment is about to be destroyed.- smartcard cert picker now pops up when "sign in with certificate" is clicked and YubiKey is already plugged in.
- smartcard cert picker shows PIV certs on YubiKey and prompts user to choose.
- PIN dialog prompts user to enter PIN. If incorrect, an error message tells the user to try again.
- If the user has three incorrect PIN attempts, a max attempts error dialog will show and the user won't be able to authenticate until they get their YubiKey unlocked.
- If YubiKey is unplugged in the middle of the smartcard CBA dialog flow, the request is cancelled and an error dialog is shown.
- The complete smartcard CBA flow now works. This involves adding a PivProvider instance in the Java Security static list of security providers.
- max attempts error dialog is altered to become a generic error dialog that takes in strings as parameters.
- DialogHolder class is created to manage the current dialog showing.
- Some more string resources added for error messages.
- Very simple telemetry started.
- Telemetry is set up for when CBA in general either succeeds or fails after we call
proceed
on the cert request from our side.- ErrorEvents are emitted when an unexpected exception is thrown.
- Small change made to PIN dialog layout to ensure EditText types from right to left for right-to-left languages.
- A good amount of the files added in this PR are a result of localization.
- The PIN char array is cleared as soon as it is no longer needed on the client side.
Breaking Changes
Since YubiKeys are recognized as external keyboards on Android, a configuration change is detected when they are plugged in and unplugged from the device. The default response to this change is to restart the activity, which is unnecessary, and even harmful, in many cases. A simple fix is to add the flags
keyboard
andkeyboardHidden
to the configChanges attribute for every relevant (could be hosting when YubiKey is active) activity within the manifest. This fix was done for our libraries, but other apps may need to implement this change as well.I created PRs for Authenticator and Company Portal that address the breaking change. I'm engaging with engineers on both teams to help explain why these changes need to be made.
The broker release engineer for next month must take a commit after these PRs get merged for the RC builds.
For other apps that use MSAL, this breaking change and fix should be noted in the monthly announcement and wherever else it may be relevant.
Known Issues
Testing
Manual tests for a success scenario and two common failure scenarios (incorrect PIN and unplugging mid-dialog) were added under the Cert Based Auth folder in the master monthly test plan. I'm curious if I should create tests for 1p apps as well (for example, installing Authenticator and testing with production Outlook).
There could be some opportunities for automation that I still need to investigate. While I do think it would be valuable to at least manually plug in a YubiKey as a part of testing, the dialog steps that come afterwards could potentially be automated with the help of Robolectric Shadows. This ShadowUsbManager class could be interesting.
Private preview is currently in progress (with an apk that consumes a non-production version of YubiKit), but other than some internal testing, it doesn't seem that we will get too much feedback before GA. Yubico also has a copy of this apk and had some smaller followup questions regarding if NFC was implemented (it wasn't), if the apk contained the production version of YubiKit (it contains 2.1.0-alpha, as the apk was generated before 2.1.0 was released), and why they were seeing a server error if they clicked on "Sign in with a certificate" without a plugged in YubiKey (defaults to on-device, so device probably didn't have any applicable user certs).
I've created a successful apk of Authenticator with the feature. I'm investigating a small issue with Company Portal (it can't find new classes written in common4j..... but I have been given a potential commandline statement that could fix this issue).
Future Work