Skip to content

Commit

Permalink
v4.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
dschuermann committed Dec 18, 2020
1 parent 6d1261f commit bd93a33
Show file tree
Hide file tree
Showing 34 changed files with 640 additions and 217 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
import de.cotech.hw.SecurityKeyCallback;
import de.cotech.hw.SecurityKeyException;
import de.cotech.hw.SecurityKeyManager;
import de.cotech.hw.exceptions.InsNotSupportedException;
import de.cotech.hw.exceptions.SecurityKeyDisconnectedException;
import de.cotech.hw.fido.FidoAuthenticateCallback;
import de.cotech.hw.fido.FidoAuthenticateRequest;
Expand All @@ -79,16 +78,18 @@
import de.cotech.hw.ui.internal.NfcFullscreenView;
import de.cotech.hw.ui.internal.SecurityKeyFormFactor;
import de.cotech.hw.ui.internal.SmartcardFormFactor;
import de.cotech.hw.ui.internal.SuccessView;
import de.cotech.hw.util.HwTimber;


public class FidoDialogFragment extends BottomSheetDialogFragment implements SecurityKeyCallback<FidoSecurityKey>, SecurityKeyFormFactor.SelectTransportCallback {
private static final String FRAGMENT_TAG = "hwsecurity-fido-fragment";
private static final String ARG_FIDO_REGISTER_REQUEST = "ARG_FIDO_REGISTER_REQUEST";
private static final String ARG_FIDO_AUTHENTICATE_REQUEST = "ARG_FIDO_AUTHENTICATE_REQUEST";
private static final String ARG_FIDO_OPTIONS = "de.cotech.hw.fido.ARG_FIDO_OPTIONS";
private static final String ARG_FIDO_OPTIONS = "de.cotech.hw.fido.ui.ARG_FIDO_OPTIONS";

private static final long TIME_DELAYED_SCREEN_CHANGE = 3000;
private static final long TIME_DELAYED_SUCCESS_DISMISS = 1600;

static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
Expand All @@ -112,6 +113,7 @@ public class FidoDialogFragment extends BottomSheetDialogFragment implements Sec
private SmartcardFormFactor smartcardFormFactor;

private ErrorView errorView;
private SuccessView successView;

private FidoDialogOptions options;
private FidoRegisterRequest fidoRegisterRequest;
Expand All @@ -126,6 +128,7 @@ private enum Screen {
USB_PRESS_BUTTON,
USB_SELECT_AND_PRESS_BUTTON,
ERROR,
SUCCESS,
}

private Screen currentScreen;
Expand Down Expand Up @@ -348,6 +351,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
securityKeyFormFactor = new SecurityKeyFormFactor(view.findViewById(R.id.includeSecurityKeyFormFactor), this, this, innerBottomSheet, options.getShowSdkLogo());

errorView = new ErrorView(view.findViewById(de.cotech.hw.ui.R.id.includeError));
successView = new SuccessView(view.findViewById(de.cotech.hw.ui.R.id.includeSuccess));

nfcFullscreenView = new NfcFullscreenView(view.findViewById(de.cotech.hw.ui.R.id.includeNfcFullscreen), innerBottomSheet);

Expand Down Expand Up @@ -402,7 +406,11 @@ private void gotoScreen(Screen newScreen) {
break;
}
case ERROR: {
animateError();
showError();
break;
}
case SUCCESS: {
showSuccess();
break;
}
}
Expand All @@ -413,6 +421,7 @@ public void screeFullscreenNfc() {
textTitle.setVisibility(View.GONE);
textDescription.setVisibility(View.GONE);
errorView.setVisibility(View.GONE);
successView.setVisibility(View.GONE);
smartcardFormFactor.setVisibility(View.GONE);
securityKeyFormFactor.setVisibility(View.GONE);

Expand All @@ -433,19 +442,32 @@ private void animateStart() {
textTitle.setVisibility(View.VISIBLE);
textDescription.setVisibility(View.VISIBLE);
errorView.setVisibility(View.GONE);
successView.setVisibility(View.GONE);
securityKeyFormFactor.setVisibility(View.VISIBLE);

securityKeyFormFactor.resetAnimation();
}

private void animateError() {
private void showError() {
TransitionManager.beginDelayedTransition(innerBottomSheet);
textTitle.setVisibility(View.GONE);
textDescription.setVisibility(View.GONE);
securityKeyFormFactor.setVisibility(View.GONE);
smartcardFormFactor.setVisibility(View.GONE);
nfcFullscreenView.setVisibility(View.GONE);
errorView.setVisibility(View.VISIBLE);
successView.setVisibility(View.GONE);
}

private void showSuccess() {
TransitionManager.beginDelayedTransition(innerBottomSheet);
textTitle.setVisibility(View.GONE);
textDescription.setVisibility(View.GONE);
securityKeyFormFactor.setVisibility(View.GONE);
smartcardFormFactor.setVisibility(View.GONE);
nfcFullscreenView.setVisibility(View.GONE);
errorView.setVisibility(View.GONE);
successView.setVisibility(View.VISIBLE);
}

@UiThread
Expand Down Expand Up @@ -483,7 +505,13 @@ public void onRegisterResponse(FidoRegisterResponse response) {
if (securityKey.isTransportNfc()) {
securityKey.release();
}
dismiss();
gotoScreen(Screen.SUCCESS);
bottomSheet.postDelayed(() -> {
if (!isAdded()) {
return;
}
dismiss();
}, TIME_DELAYED_SUCCESS_DISMISS);
}

@Override
Expand All @@ -502,7 +530,13 @@ public void onAuthenticateResponse(FidoAuthenticateResponse response) {
if (securityKey.isTransportNfc()) {
securityKey.release();
}
dismiss();
gotoScreen(Screen.SUCCESS);
bottomSheet.postDelayed(() -> {
if (!isAdded()) {
return;
}
dismiss();
}, TIME_DELAYED_SUCCESS_DISMISS);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public abstract static class Builder {
* &#60;item name="hwSecurityButtonColor"&#62;@color/hwSecurityDarkBlue&#60;/item&#62;
* &#60;item name="hwSecuritySurfaceColor"&#62;@color/hwSecurityBlue&#60;/item&#62;
* &#60;item name="hwSecurityErrorColor"&#62;@color/hwSecurityRed&#60;/item&#62;
* &#60;item name="hwSecuritySuccessColor"&#62;@color/hwSecurityGreen&#60;/item&#62;
* &#60;/style&#62;
* </pre>
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ private PublicKeyCredential ctap1ResponseApduToWebauthnResponse(
U2fAuthenticateResponse u2fResponse = U2fAuthenticateResponse.fromBytes(responseData);

AuthenticatorData authenticatorData =
AuthenticatorData.create(rpIdHash, (byte) 1, u2fResponse.counter(), null, null);
AuthenticatorData.create(rpIdHash, u2fResponse.presence(), u2fResponse.counter(), null, null);
byte[] authenticatorDataBytes = new AuthenticatorDataParser().toBytes(authenticatorData);
AuthenticatorAssertionResponse authenticatorResponse =
AuthenticatorAssertionResponse.create(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public static U2fAuthenticateResponse fromBytes(byte[] data) throws IOException
int counter = buf.getInt();

int signatureLength = buf.remaining();
if (signatureLength < 70 || signatureLength > 73) {
if (signatureLength < 71 || signatureLength > 73) {
throw new IOException("Signature length must be 71-73 bytes!");
}
byte[] signature = new byte[signatureLength];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@


class PublicSuffixDatabase {
private static final String PUBLIC_SUFFIX_RESOURCE = "publicsuffixes.gz";
// Must be an absolute path to work after Proguard optimizations!
private static final String PUBLIC_SUFFIX_RESOURCE = "/de/cotech/hw/fido2/internal/utils/publicsuffixes.gz";
private static final byte[] WILDCARD_LABEL = new byte[] { '*' };
private static final char EXCEPTION_MARKER = '!';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import de.cotech.hw.ui.internal.SecurityKeyDialogPresenter;

public class GenericFido2SecurityKeyDialogFragment extends SecurityKeyDialogFragment<Fido2SecurityKey> {
public static final String ARG_FIDO2_CONFIG = "de.cotech.hw.fido2.ARG_FIDO2_CONFIG";
public static final String ARG_FIDO2_CONFIG = "de.cotech.hw.fido2.ui.ARG_FIDO2_CONFIG";

public static SecurityKeyDialogFragment<Fido2SecurityKey> newInstance() {
return newInstance(SecurityKeyDialogOptions.builder().build(), Fido2SecurityKeyConnectionModeConfig.getDefaultConfig());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,18 @@
import de.cotech.hw.ui.internal.PinInput;
import de.cotech.hw.ui.internal.SecurityKeyFormFactor;
import de.cotech.hw.ui.internal.SmartcardFormFactor;
import de.cotech.hw.ui.internal.SuccessView;
import de.cotech.hw.util.HwTimber;


public class WebauthnDialogFragment extends BottomSheetDialogFragment
implements SecurityKeyCallback<Fido2SecurityKey>, SecurityKeyFormFactor.SelectTransportCallback, PinInput.PinInputCallback {
private static final String FRAGMENT_TAG = "hwsecurity-webauthn-fragment";
private static final String ARG_WEBAUTHN_COMMAND = "ARG_WEBAUTHN_COMMAND";
private static final String ARG_WEBAUTHN_OPTIONS = "de.cotech.hw.fido.ARG_WEBAUTHN_OPTIONS";
private static final String ARG_WEBAUTHN_OPTIONS = "de.cotech.hw.fido2.ui.ARG_WEBAUTHN_OPTIONS";

private static final long TIME_DELAYED_SCREEN_CHANGE = 3000;
private static final long TIME_DELAYED_SUCCESS_DISMISS = 1600;

static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
Expand Down Expand Up @@ -130,6 +132,7 @@ public class WebauthnDialogFragment extends BottomSheetDialogFragment
private TextView textDescription;

private ErrorView errorView;
private SuccessView successView;

private WebauthnDialogOptions options;
private WebauthnCommand webauthnCommand;
Expand All @@ -147,6 +150,7 @@ private enum Screen {
USB_PRESS_BUTTON,
USB_SELECT_AND_PRESS_BUTTON,
ERROR,
SUCCESS,
}

private Screen currentScreen;
Expand Down Expand Up @@ -362,6 +366,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
securityKeyFormFactor = new SecurityKeyFormFactor(view.findViewById(R.id.includeSecurityKeyFormFactor), this, this, innerBottomSheet, options.getShowSdkLogo());

errorView = new ErrorView(view.findViewById(de.cotech.hw.ui.R.id.includeError));
successView = new SuccessView(view.findViewById(de.cotech.hw.ui.R.id.includeSuccess));

nfcFullscreenView = new NfcFullscreenView(view.findViewById(de.cotech.hw.ui.R.id.includeNfcFullscreen), innerBottomSheet);

Expand Down Expand Up @@ -508,6 +513,10 @@ private void gotoScreen(Screen newScreen) {
showError();
break;
}
case SUCCESS: {
showSuccess();
break;
}
}
}

Expand All @@ -516,6 +525,7 @@ public void screeFullscreenNfc() {
textTitle.setVisibility(View.GONE);
textDescription.setVisibility(View.GONE);
errorView.setVisibility(View.GONE);
successView.setVisibility(View.GONE);
securityKeyFormFactor.setVisibility(View.GONE);
smartcardFormFactor.setVisibility(View.GONE);
buttonRight.setVisibility(View.GONE);
Expand Down Expand Up @@ -550,6 +560,7 @@ private void animateStart() {
textTitle.setVisibility(View.VISIBLE);
textDescription.setVisibility(View.VISIBLE);
errorView.setVisibility(View.GONE);
successView.setVisibility(View.GONE);
keyboardPinInput.setVisibility(View.GONE);
keypadPinInput.setVisibility(View.GONE);
switch (options.getFormFactor()) {
Expand All @@ -574,6 +585,7 @@ public void showPinInput(boolean allowSkip) {
textTitle.setVisibility(View.VISIBLE);
textDescription.setVisibility(View.VISIBLE);
errorView.setVisibility(View.GONE);
successView.setVisibility(View.GONE);
securityKeyFormFactor.setVisibility(View.GONE);
smartcardFormFactor.setVisibility(View.GONE);
buttonPinInputSwitch.setVisibility(options.getAllowKeyboard() ? View.VISIBLE : View.INVISIBLE);
Expand Down Expand Up @@ -604,6 +616,22 @@ private void showError() {
smartcardFormFactor.setVisibility(View.GONE);
nfcFullscreenView.setVisibility(View.GONE);
errorView.setVisibility(View.VISIBLE);
successView.setVisibility(View.GONE);
buttonRight.setVisibility(View.GONE);
keyboardPinInput.setVisibility(View.GONE);
keypadPinInput.setVisibility(View.GONE);
buttonPinInputSwitch.setVisibility(View.GONE);
}

private void showSuccess() {
TransitionManager.beginDelayedTransition(innerBottomSheet);
textTitle.setVisibility(View.GONE);
textDescription.setVisibility(View.GONE);
securityKeyFormFactor.setVisibility(View.GONE);
smartcardFormFactor.setVisibility(View.GONE);
nfcFullscreenView.setVisibility(View.GONE);
errorView.setVisibility(View.GONE);
successView.setVisibility(View.VISIBLE);
buttonRight.setVisibility(View.GONE);
keyboardPinInput.setVisibility(View.GONE);
keypadPinInput.setVisibility(View.GONE);
Expand Down Expand Up @@ -663,7 +691,13 @@ public void onResponse(PublicKeyCredential publicKeyCredential) {
if (securityKey.isTransportNfc()) {
securityKey.release();
}
dismiss();
gotoScreen(Screen.SUCCESS);
bottomSheet.postDelayed(() -> {
if (!isAdded()) {
return;
}
dismiss();
}, TIME_DELAYED_SUCCESS_DISMISS);
}

@Override
Expand All @@ -682,7 +716,13 @@ public void onResponse(PublicKeyCredential response) {
if (securityKey.isTransportNfc()) {
securityKey.release();
}
dismiss();
gotoScreen(Screen.SUCCESS);
bottomSheet.postDelayed(() -> {
if (!isAdded()) {
return;
}
dismiss();
}, TIME_DELAYED_SUCCESS_DISMISS);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ public abstract static class Builder {
* &#60;item name="hwSecurityButtonColor"&#62;@color/hwSecurityDarkBlue&#60;/item&#62;
* &#60;item name="hwSecuritySurfaceColor"&#62;@color/hwSecurityBlue&#60;/item&#62;
* &#60;item name="hwSecurityErrorColor"&#62;@color/hwSecurityRed&#60;/item&#62;
* &#60;item name="hwSecuritySuccessColor"&#62;@color/hwSecurityGreen&#60;/item&#62;
* &#60;/style&#62;
* </pre>
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ public class PinProtocolV1Test {
static final byte[] PIN_TOKEN_ENC = Hex.decodeHexOrFail("554df3802226935b2bf49f30aae3096f");
static final String CLIENT_PIN_GET_TOKEN = "801000006606a40101020503a501020326200121582099401f6ffa9446585074d1058578f4c68ab46953ccf8cb7910d8b3c9350e1040225820a3c962cddad166b1fdea8a95a377dbf8efbedd82778a8004b884f0009bd6df9506502eb756ae474f7ca032b5111b2eef6959";
static final String CLIENT_PIN_GET_TOKEN_RESPONSE = "00a10250554df3802226935b2bf49f30aae3096f9000";
static final String CLIENT_PIN_GET_TOKEN_RESPONSE_INVALID = "329000";
static final String CLIENT_PIN_GET_TOKEN_RESPONSE_BLOCKED = "319000";
static final String CLIENT_PIN_GET_TOKEN_RESPONSE_INVALID = "319000";
static final String CLIENT_PIN_GET_TOKEN_RESPONSE_BLOCKED = "329000";

static final byte[] SHARED_SECRET = new byte[1];
static final byte[] PIN_TOKEN = new byte[1];
Expand Down Expand Up @@ -75,7 +75,7 @@ public void pinAuth_invalid() throws Exception {
pinProtocolV1.clientPinAuthenticate(fakeFidoConnection.connection, "1234", false);
}

@Test(expected = FidoClientPinInvalidException.class)
@Test(expected = FidoClientPinBlockedException.class)
public void pinAuth_invalid_blocked() throws Exception {
PinProtocolV1 pinProtocolV1 = setupPinProtocol();

Expand Down
2 changes: 1 addition & 1 deletion hwsecurity/openpgp/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ dependencies {
compileOnly project(':hwsecurity:ui')
compileOnly 'com.google.android.material:material:1.1.0'

implementation 'org.bouncycastle:bcprov-jdk15on:1.65'
implementation 'org.bouncycastle:bcprov-jdk15on:1.67'

compileOnly 'androidx.annotation:annotation:1.1.0'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,6 @@

@RestrictTo(Scope.LIBRARY_GROUP)
public class OpenPgpCardUtils {
public static byte[] attributesForEccKey(KeyType slot, ASN1ObjectIdentifier curveOid) throws IOException {
byte[] oid = curveOid.getEncoded();
byte[] attrs = new byte[1 + (oid.length - 2) + 1];

if (slot.equals(KeyType.SIGN))
attrs[0] = ECKeyFormat.ECAlgorithmFormat.ECDSA_WITH_PUBKEY.getValue();
else {
attrs[0] = ECKeyFormat.ECAlgorithmFormat.ECDH_WITH_PUBKEY.getValue();
}

System.arraycopy(oid, 2, attrs, 1, (oid.length - 2));
attrs[attrs.length - 1] = (byte) 0xff;
return attrs;
}

public static byte[] createRSAPrivKeyTemplate(RSAPrivateCrtKey secretKey, KeyType slot,
RSAKeyFormat format) throws IOException {
Expand Down Expand Up @@ -141,7 +127,7 @@ public static byte[] createECPrivKeyTemplate(ECPrivateKey secretKey, ECPublicKey
template.write(Hex.decode("92"));
template.write(encodeLength(data.size()));

if (format.getAlgorithmFormat().isWithPubkey()) {
if (format.ecAlgorithmFormat().isWithPubkey()) {
data.write(Hex.decode("04"));
writeBits(data, publicKey.getW().getAffineX(), csize);
writeBits(data, publicKey.getW().getAffineY(), csize);
Expand Down
Loading

0 comments on commit bd93a33

Please sign in to comment.