-
Notifications
You must be signed in to change notification settings - Fork 13
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
Implement HMAC-Secret extension #5
base: master
Are you sure you want to change the base?
Implement HMAC-Secret extension #5
Conversation
This adds the ability for Android apps (not web pages) to use the hwsecurity library to: - register credentials with the FIDO2 hmac-secret extension enabled - pass salts in to authenticators with getAssertion calls - retrieve decrypted results back from the authenticator It also lays the basic groundwork for supporting PIN Protocol 2, defined as a mandatory part of FIDO2 CTAP2.1.
@@ -27,5 +27,5 @@ allprojects { | |||
|
|||
ext { | |||
compileSdkVersion = 29 | |||
hwSdkVersionName = '4.4.0' | |||
hwSdkVersionName = '4.5.0' |
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 change doesn't break any non-"internal" classes, per se, but it does add fields and features.
import com.google.auto.value.AutoValue; | ||
|
||
@AutoValue | ||
public abstract class ExtensionParameter implements Parcelable { |
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 class (and change) lays the groundwork for supporting other extensions such as CredProtect, mandatory in CTAP2.1 and quite desirable for an application using resident keys.
@SuppressWarnings("mutable") | ||
public abstract byte[] salt2(); | ||
|
||
public static HmacSecretExtensionParameterValue create(byte[] salt1, @Nullable byte[] salt2) { |
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.
These are the unencrypted values so they must always be 32 bytes long - even when PIN Protocol 2 will add a 16-byte IV to the front, that happens around these values and not within them.
@@ -69,7 +70,7 @@ public abstract class AuthenticatorData { | |||
// extensions variable (if present) Extension-defined authenticator data. This is a CBOR [RFC7049] map with extension identifiers as keys, and authenticator extension outputs as values. See §9 WebAuthn Extensions for details. | |||
@Nullable | |||
@SuppressWarnings("mutable") | |||
public abstract byte[] extensions(); | |||
public abstract Map extensions(); |
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.
It's not useful to have the extensions type (never actually exposed in app-visible objects) be a byte array because some of its contents depend on authenticator state objects like the shared secret :-(.
// Handle parameters which require assertion-specific data here | ||
Object value = extensionParameters.value(); | ||
if (value instanceof HmacSecretExtensionParameterValue) { | ||
HmacSecretExtensionParameterValue param = (HmacSecretExtensionParameterValue) value; |
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.
Significant change here: serialize hmac-secret extension parameters to the CTAP2 CBOR request.
throw new IOException("hmac-secret response is not a byte string"); | ||
} | ||
byte[] hmacSecretBytes = ((ByteString) hmacSecretValue).getBytes(); | ||
decryptedHmacSecretValue = authenticatorGetAssertion.pinToken().decrypt(hmacSecretBytes); |
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.
Return side of the hmac-secret getAssertion flow, and the reason why I did all this wiring of the PinToken: the hmac-secret response value must be decrypted using the platform<->authenticator shared secret in order to be useful.
That's done here in the response factory.
|
||
import de.cotech.hw.fido2.internal.Fido2AppletConnection; | ||
|
||
public interface PinProtocol { |
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.
The changes here aren't, strictly speaking, necessary for hmac-secret support. But if you ever want to implement the vastly superior CTAP2.1 PIN Protocol 2, you're going to need changes like these to do so.
I've used the CTAP2.1 terminology for the PIN operations - authenticate, encrypt, decrypt - instead of the implementation-specific ones that were here before.
This adds the ability for Android apps (not web pages) to use the
hwsecurity library to:
It also lays the basic groundwork for supporting PIN Protocol 2,
defined as a mandatory part of FIDO2 CTAP2.1.
Example usage for create:
Example usage for getAssertion: