Skip to content

Commit a58014c

Browse files
committed
Added KeyRevokedException that is thrown by getPassword if the key has been revoked. This provides some added information for the app to provide better feedback to the user if their fingerprint auth fails. So far this exception is only available on Android. Looking into iOS now. codenameone/CodenameOne#3045
1 parent 0a5c01a commit a58014c

File tree

5 files changed

+162
-7
lines changed

5 files changed

+162
-7
lines changed

native/android/com/codename1/fingerprint/impl/InternalFingerprintImpl.java

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
/*
2+
* Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
* This code is free software; you can redistribute it and/or modify it
5+
* under the terms of the GNU General Public License version 2 only, as
6+
* published by the Free Software Foundation. Codename One designates this
7+
* particular file as subject to the "Classpath" exception as provided
8+
* by Oracle in the LICENSE file that accompanied this code.
9+
*
10+
* This code is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* version 2 for more details (a copy is included in the LICENSE file that
14+
* accompanied this code).
15+
*
16+
* You should have received a copy of the GNU General Public License version
17+
* 2 along with this work; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*
20+
* Please contact Codename One through http://www.codenameone.com/ if you
21+
* need additional information or have any questions.
22+
*/
123
package com.codename1.fingerprint.impl;
224

325
import android.hardware.fingerprint.FingerprintManager;
@@ -317,6 +339,7 @@ private boolean addPassword29(final int requestId, final String reason, final St
317339
secretKey = getSecretKey();
318340
} else {
319341
InternalCallback.requestError(requestId, String.valueOf("Failed to create key"));
342+
return false;
320343
}
321344
}
322345

@@ -451,6 +474,7 @@ private boolean addPassword(final int requestId, final String reason, final Stri
451474
secretKey = getSecretKey();
452475
} else {
453476
InternalCallback.requestError(requestId, String.valueOf("Failed to create key"));
477+
return false;
454478
}
455479
}
456480

@@ -576,11 +600,20 @@ private boolean getPassword29(final int requestId, final String reason, final St
576600
SecretKey secretKey = getSecretKey();
577601

578602
if (secretKey == null) {
603+
/*
579604
if (createKey()) {
580605
secretKey = getSecretKey();
581606
} else {
582607
InternalCallback.requestError(requestId, String.valueOf("Failed to create key"));
608+
return false;
583609
}
610+
*/
611+
if (keyRevoked) {
612+
InternalCallback.requestKeyRevokedError(requestId, String.valueOf("Key has been invalidated"));
613+
} else {
614+
InternalCallback.requestError(requestId, String.valueOf("No key found"));
615+
}
616+
return false;
584617
}
585618

586619

@@ -641,6 +674,9 @@ public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult resul
641674
};
642675
if(!initCipher(Cipher.DECRYPT_MODE, key)) {
643676
// Could not initialize cipher, key must have been invalidated
677+
InternalCallback.requestKeyRevokedError(requestId, "Failed to initialize cipher. Secret key must have been revoked");
678+
return;
679+
/*
644680
if (!createKey()) {
645681
InternalCallback.requestError(requestId, "Failed to create a new key after old key failed to initialize the cipher. Something must be wrong.");
646682
return;
@@ -649,6 +685,7 @@ public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult resul
649685
InternalCallback.requestError(requestId, "Failed to initialize the cipher even after generating new key. Something must be wrong");
650686
return;
651687
}
688+
*/
652689

653690

654691
}
@@ -695,11 +732,20 @@ private boolean getPassword(final int requestId, final String reason, final Stri
695732
SecretKey secretKey = getSecretKey();
696733

697734
if (secretKey == null) {
735+
/*
698736
if (createKey()) {
699737
secretKey = getSecretKey();
700738
} else {
701739
InternalCallback.requestError(requestId, String.valueOf("Failed to create key"));
740+
return false;
741+
}
742+
*/
743+
if (keyRevoked) {
744+
InternalCallback.requestKeyRevokedError(requestId, String.valueOf("Key has been invalidated"));
745+
} else {
746+
InternalCallback.requestError(requestId, String.valueOf("No key found"));
702747
}
748+
return false;
703749
}
704750

705751

@@ -760,6 +806,9 @@ public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult re
760806
};
761807
if(!initCipher(Cipher.DECRYPT_MODE, key)) {
762808
// Could not initialize cipher, key must have been invalidated
809+
InternalCallback.requestKeyRevokedError(requestId, "Failed to initialize cipher. Secret key must have been revoked");
810+
return;
811+
/*
763812
if (!createKey()) {
764813
InternalCallback.requestError(requestId, "Failed to create a new key after old key failed to initialize the cipher. Something must be wrong.");
765814
return;
@@ -768,6 +817,7 @@ public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult re
768817
InternalCallback.requestError(requestId, "Failed to initialize the cipher even after generating new key. Something must be wrong");
769818
return;
770819
}
820+
*/
771821

772822

773823
}
@@ -842,8 +892,9 @@ private boolean createKey() {
842892
}
843893
return isKeyCreated;
844894
}
845-
895+
private boolean keyRevoked = false;
846896
private SecretKey getSecretKey() {
897+
keyRevoked = false;
847898
String errorMessage = "";
848899
String getSecretKeyExceptionErrorPrefix = "Failed to get SecretKey from KeyStore: ";
849900
SecretKey key = null;
@@ -855,12 +906,14 @@ private SecretKey getSecretKey() {
855906
} catch (CertificateException e) {
856907
errorMessage = getSecretKeyExceptionErrorPrefix + "CertificateException";
857908
} catch (UnrecoverableKeyException e) {
909+
keyRevoked = true;
858910
errorMessage = getSecretKeyExceptionErrorPrefix + "UnrecoverableKeyException";
859911
} catch (IOException e) {
860912
errorMessage = getSecretKeyExceptionErrorPrefix + "IOException";
861913
} catch (NoSuchAlgorithmException e) {
862914
errorMessage = getSecretKeyExceptionErrorPrefix + "NoSuchAlgorithmException";
863915
} catch (UnrecoverableEntryException e) {
916+
keyRevoked = true;
864917
errorMessage = getSecretKeyExceptionErrorPrefix + "UnrecoverableEntryException";
865918
}
866919
if (key == null) {
@@ -893,6 +946,7 @@ private static class CipherInitializerM {
893946

894947
@RequiresApi(api = Build.VERSION_CODES.M)
895948
private static boolean initCipher(InternalFingerprintImpl impl, int mode, String account) {
949+
896950
boolean initCipher = false;
897951
String errorMessage = "";
898952
String initCipherExceptionErrorPrefix = "Failed to init Cipher: ";

src/com/codename1/fingerprint/Fingerprint.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
11
/*
2-
* To change this license header, choose License Headers in Project Properties.
3-
* To change this template file, choose Tools | Templates
4-
* and open the template in the editor.
2+
* Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
* This code is free software; you can redistribute it and/or modify it
5+
* under the terms of the GNU General Public License version 2 only, as
6+
* published by the Free Software Foundation. Codename One designates this
7+
* particular file as subject to the "Classpath" exception as provided
8+
* by Oracle in the LICENSE file that accompanied this code.
9+
*
10+
* This code is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* version 2 for more details (a copy is included in the LICENSE file that
14+
* accompanied this code).
15+
*
16+
* You should have received a copy of the GNU General Public License version
17+
* 2 along with this work; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*
20+
* Please contact Codename One through http://www.codenameone.com/ if you
21+
* need additional information or have any questions.
522
*/
623
package com.codename1.fingerprint;
724

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
* This code is free software; you can redistribute it and/or modify it
5+
* under the terms of the GNU General Public License version 2 only, as
6+
* published by the Free Software Foundation. Codename One designates this
7+
* particular file as subject to the "Classpath" exception as provided
8+
* by Oracle in the LICENSE file that accompanied this code.
9+
*
10+
* This code is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* version 2 for more details (a copy is included in the LICENSE file that
14+
* accompanied this code).
15+
*
16+
* You should have received a copy of the GNU General Public License version
17+
* 2 along with this work; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*
20+
* Please contact Codename One through http://www.codenameone.com/ if you
21+
* need additional information or have any questions.
22+
*/
23+
package com.codename1.fingerprint;
24+
25+
/**
26+
* Exception thrown by {@link Fingerprint#addPassword(java.lang.String, java.lang.String, java.lang.String) } and
27+
* {@link Fingerprint#getPassword(java.lang.String, java.lang.String) } if the key has been revoked. A key is revoked
28+
* if the user has added fingerprints, or other forms of biometric authentication since the key was generated.
29+
* @author Steve Hannah
30+
*/
31+
public class KeyRevokedException extends RuntimeException {
32+
public KeyRevokedException(String msg) {
33+
super(msg);
34+
}
35+
}

src/com/codename1/fingerprint/impl/InternalCallback.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,30 @@
1+
/*
2+
* Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
* This code is free software; you can redistribute it and/or modify it
5+
* under the terms of the GNU General Public License version 2 only, as
6+
* published by the Free Software Foundation. Codename One designates this
7+
* particular file as subject to the "Classpath" exception as provided
8+
* by Oracle in the LICENSE file that accompanied this code.
9+
*
10+
* This code is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* version 2 for more details (a copy is included in the LICENSE file that
14+
* accompanied this code).
15+
*
16+
* You should have received a copy of the GNU General Public License version
17+
* 2 along with this work; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*
20+
* Please contact Codename One through http://www.codenameone.com/ if you
21+
* need additional information or have any questions.
22+
*/
123
package com.codename1.fingerprint.impl;
224

325
import com.codename1.components.SpanLabel;
426
import com.codename1.fingerprint.Fingerprint;
27+
import com.codename1.fingerprint.KeyRevokedException;
528
import com.codename1.ui.Dialog;
629
import com.codename1.ui.Display;
730
import com.codename1.ui.FontImage;
@@ -109,6 +132,15 @@ public static void requestError(int requestId, String message) {
109132
req.error(new RuntimeException(message));
110133
}
111134

135+
public static void requestKeyRevokedError(int requestId, String message) {
136+
AsyncResource<?> req = requests.get(requestId);
137+
if (req == null) {
138+
return;
139+
}
140+
requests.remove(requestId);
141+
req.error(new KeyRevokedException(message));
142+
}
143+
112144
public static void requestComplete(int requestId, boolean success) {
113145
AsyncResource<Boolean> req = (AsyncResource<Boolean>)requests.get(requestId);
114146
if (req == null) {

src/com/codename1/fingerprint/impl/InternalFingerprint.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
11
/*
2-
* To change this license header, choose License Headers in Project Properties.
3-
* To change this template file, choose Tools | Templates
4-
* and open the template in the editor.
2+
* Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
* This code is free software; you can redistribute it and/or modify it
5+
* under the terms of the GNU General Public License version 2 only, as
6+
* published by the Free Software Foundation. Codename One designates this
7+
* particular file as subject to the "Classpath" exception as provided
8+
* by Oracle in the LICENSE file that accompanied this code.
9+
*
10+
* This code is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* version 2 for more details (a copy is included in the LICENSE file that
14+
* accompanied this code).
15+
*
16+
* You should have received a copy of the GNU General Public License version
17+
* 2 along with this work; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*
20+
* Please contact Codename One through http://www.codenameone.com/ if you
21+
* need additional information or have any questions.
522
*/
623
package com.codename1.fingerprint.impl;
724

0 commit comments

Comments
 (0)