Skip to content

Commit d27cd1a

Browse files
Merge pull request #14 from regulaforensics/release-6.1
Release 6.1
2 parents 740bb09 + 563c7f5 commit d27cd1a

118 files changed

Lines changed: 2297 additions & 408 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CertificatePinningSample/app/build.gradle

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ plugins {
44
}
55

66
android {
7-
compileSdkVersion 32
7+
compileSdk 32
88

99
defaultConfig {
1010
applicationId "com.regula.facesamplekotlin"
11-
minSdkVersion 24
12-
targetSdkVersion 32
11+
minSdk 24
12+
targetSdk 32
1313
versionCode 1
1414
versionName "1.0"
1515
}
@@ -24,6 +24,11 @@ android {
2424
buildFeatures {
2525
viewBinding true
2626
}
27+
28+
//Required to add
29+
aaptOptions {
30+
noCompress "Regula/faceSdkResource.dat"
31+
}
2732
}
2833

2934
dependencies {
@@ -34,9 +39,9 @@ dependencies {
3439
implementation "androidx.core:core-ktx:1.7.0"
3540
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
3641

37-
implementation ('com.regula.face:api:5.2.+@aar'){
42+
implementation ('com.regula.face:api:6.1.+@aar'){
3843
transitive = true
3944
}
4045

41-
implementation ('com.regula.face:core:5.2.+@aar')
46+
implementation ('com.regula.face.core:basic:6.1.+@aar')
4247
}

CertificatePinningSample/app/src/main/java/com/regula/facesamplekotlin/MainActivity.kt

Lines changed: 104 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,35 @@
11
package com.regula.facesamplekotlin
22

3+
import android.net.http.X509TrustManagerExtensions
34
import android.os.Bundle
45
import android.os.Handler
56
import android.os.Looper
7+
import android.util.Base64
68
import android.util.Log
79
import android.widget.Toast
810
import androidx.appcompat.app.AppCompatActivity
11+
import com.regula.common.http.HttpRequestBuilder
912
import com.regula.facesamplekotlin.databinding.ActivityMainBinding
1013
import com.regula.facesdk.FaceSDK
1114
import com.regula.facesdk.exception.InitException
15+
import com.regula.facesdk.listener.NetworkInterceptorListener
16+
import java.security.KeyStore
17+
import java.security.MessageDigest
18+
import java.security.NoSuchAlgorithmException
19+
import java.security.cert.Certificate
20+
import java.security.cert.CertificateException
21+
import java.security.cert.X509Certificate
22+
import java.util.Arrays
23+
import javax.net.ssl.HttpsURLConnection
24+
import javax.net.ssl.SSLException
25+
import javax.net.ssl.SSLPeerUnverifiedException
26+
import javax.net.ssl.TrustManagerFactory
27+
import javax.net.ssl.X509TrustManager
1228

13-
class MainActivity : AppCompatActivity() {
29+
30+
class MainActivity : AppCompatActivity(), NetworkInterceptorListener {
31+
32+
val VALID_PINS = setOf("/5RKFaPkCjAzvsEZHOlYqncYADaLIG5VfTmhsBbkaBk=")
1433

1534
@Transient
1635
private lateinit var binding: ActivityMainBinding
@@ -21,15 +40,17 @@ class MainActivity : AppCompatActivity() {
2140
binding = ActivityMainBinding.inflate(layoutInflater)
2241
setContentView(binding.root)
2342

24-
FaceSDK.Instance().init(this) { status: Boolean, e: InitException? ->
43+
FaceSDK.Instance().initialize(this) { status: Boolean, e: InitException? ->
2544
if (!status) {
2645
Toast.makeText(
2746
this@MainActivity,
2847
"Init finished with error: " + if (e != null) e.message else "",
2948
Toast.LENGTH_LONG
3049
).show()
31-
return@init
50+
return@initialize
3251
}
52+
FaceSDK.Instance().setLogs(true)
53+
FaceSDK.Instance().setNetworkInterceptorListener(this@MainActivity)
3354
(Handler(Looper.getMainLooper())).post {
3455
binding.startBtn.isEnabled = true
3556
}
@@ -45,4 +66,84 @@ class MainActivity : AppCompatActivity() {
4566
}
4667
}
4768
}
69+
70+
override fun onPrepareRequest(connection: HttpRequestBuilder?) {
71+
val trustManagerFactory = TrustManagerFactory.getInstance(
72+
TrustManagerFactory.getDefaultAlgorithm()
73+
)
74+
trustManagerFactory.init(null as KeyStore?)
75+
// Find first X509TrustManager in the TrustManagerFactory
76+
// Find first X509TrustManager in the TrustManagerFactory
77+
var x509TrustManager: X509TrustManager? = null
78+
for (trustManager in trustManagerFactory.trustManagers) {
79+
if (trustManager is X509TrustManager) {
80+
x509TrustManager = trustManager
81+
break
82+
}
83+
}
84+
val trustManagerExt = X509TrustManagerExtensions(x509TrustManager)
85+
connection?.connection?.let {
86+
println("validatePinning")
87+
try {
88+
connection.connection.connect()
89+
} catch (e: Exception) {
90+
println("Error connect: " + e)
91+
}
92+
validatePinning(trustManagerExt, connection.connection as HttpsURLConnection, VALID_PINS)
93+
}
94+
95+
}
96+
97+
@Throws(SSLException::class)
98+
private fun validatePinning(
99+
trustManagerExt: X509TrustManagerExtensions,
100+
conn: HttpsURLConnection, validPins: Set<String>
101+
) {
102+
var certChainMsg = ""
103+
try {
104+
val md = MessageDigest.getInstance("SHA-256")
105+
val trustedChain: List<X509Certificate> = trustedChain(trustManagerExt, conn)
106+
println("trustedChain count: " + trustedChain.size)
107+
for (cert: X509Certificate in trustedChain) {
108+
val publicKey: ByteArray = cert.publicKey.encoded
109+
md.update(publicKey, 0, publicKey.size)
110+
val pin: String = Base64.encodeToString(
111+
md.digest(),
112+
Base64.NO_WRAP
113+
)
114+
certChainMsg += (" sha256/" + pin + " : " +
115+
cert.subjectDN.toString()) + "\n"
116+
if (validPins.contains(pin)) {
117+
return
118+
}
119+
}
120+
} catch (e: NoSuchAlgorithmException) {
121+
throw SSLException(e)
122+
}
123+
throw SSLPeerUnverifiedException(
124+
"Certificate pinning " +
125+
"failure\n Peer certificate chain:\n" + certChainMsg
126+
)
127+
}
128+
129+
@Throws(SSLException::class)
130+
private fun trustedChain(
131+
trustManagerExt: X509TrustManagerExtensions,
132+
conn: HttpsURLConnection
133+
): List<X509Certificate> {
134+
val serverCerts: Array<Certificate> = conn.serverCertificates
135+
val untrustedCerts: Array<X509Certificate> = Arrays.copyOf(
136+
serverCerts,
137+
serverCerts.size, Array<X509Certificate>::class.java
138+
)
139+
val host = conn.url.host
140+
try {
141+
return trustManagerExt.checkServerTrusted(
142+
untrustedCerts,
143+
"RSA", host
144+
)
145+
} catch (e: CertificateException) {
146+
throw SSLException(e)
147+
}
148+
}
48149
}

FaceSample/app/build.gradle

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ plugins {
33
}
44

55
android {
6-
compileSdkVersion 32
6+
compileSdk 32
77

88
defaultConfig {
99
applicationId "com.regula.facesample"
10-
minSdkVersion 21
11-
targetSdkVersion 32
10+
minSdk 21
11+
targetSdk 32
1212
versionCode 1
1313
versionName "1.0"
1414

@@ -21,6 +21,11 @@ android {
2121
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
2222
}
2323
}
24+
25+
//Required to add
26+
aaptOptions {
27+
noCompress "Regula/faceSdkResource.dat"
28+
}
2429
}
2530

2631
dependencies {
@@ -34,9 +39,9 @@ dependencies {
3439

3540
implementation "androidx.recyclerview:recyclerview:1.2.1"
3641

37-
implementation ('com.regula.face:api:5.2.+@aar'){
42+
implementation ('com.regula.face:api:6.1.+@aar'){
3843
transitive = true
3944
}
4045

41-
implementation ('com.regula.face:core:5.2.+@aar')
46+
implementation ('com.regula.face.core:basic:6.1.+@aar')
4247
}

FaceSample/app/src/main/java/com/regula/facesample/MainActivity.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@
55
import android.util.Log;
66
import android.widget.Toast;
77

8-
import androidx.annotation.Nullable;
98
import androidx.recyclerview.widget.LinearLayoutManager;
109
import androidx.recyclerview.widget.RecyclerView;
1110

1211
import com.regula.facesample.adapter.CategoryAdapter;
1312
import com.regula.facesample.data.CategoryDataProvider;
1413
import com.regula.facesdk.FaceSDK;
15-
import com.regula.facesdk.callback.InitCallback;
16-
import com.regula.facesdk.exception.InitException;
1714

1815
public class MainActivity extends Activity {
1916

@@ -31,7 +28,7 @@ public void onCreate(Bundle savedInstanceState) {
3128

3229
recyclerView.setAdapter(new CategoryAdapter(this, dataProvider));
3330

34-
FaceSDK.Instance().init(this, (status, e) -> {
31+
FaceSDK.Instance().initialize(this, (status, e) -> {
3532
if (!status) {
3633
Toast.makeText(MainActivity.this, "Init finished with error: " + (e != null ? e.getMessage() : ""), Toast.LENGTH_LONG).show();
3734
return;

FaceSample/app/src/main/java/com/regula/facesample/MatchFacesActivity.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import android.graphics.Bitmap;
77
import android.graphics.drawable.BitmapDrawable;
88
import android.net.Uri;
9-
import android.os.Build;
109
import android.os.Bundle;
1110
import android.provider.MediaStore;
1211
import android.widget.Button;
@@ -236,12 +235,17 @@ private void matchFaces(Bitmap first, Bitmap second) {
236235
FaceSDK.Instance().matchFaces(matchRequest, matchFacesResponse -> {
237236
MatchFacesSimilarityThresholdSplit split =
238237
new MatchFacesSimilarityThresholdSplit(matchFacesResponse.getResults(), 0.75d);
238+
Double similarity = null;
239239
if (split.getMatchedFaces().size() > 0) {
240-
double similarity = split.getMatchedFaces().get(0).getSimilarity();
240+
similarity = split.getMatchedFaces().get(0).getSimilarity();
241+
} else if (split.getUnmatchedFaces().size() > 0) {
242+
similarity = split.getUnmatchedFaces().get(0).getSimilarity();
243+
}
244+
245+
if (similarity != null)
241246
textViewSimilarity.setText("Similarity: " + String.format("%.2f", similarity * 100) + "%");
242-
} else {
247+
else
243248
textViewSimilarity.setText("Similarity: null");
244-
}
245249

246250
buttonMatch.setEnabled(true);
247251
buttonLiveness.setEnabled(true);

FaceSample/app/src/main/java/com/regula/facesample/items/basic/FaceCaptureDefaultItem.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package com.regula.facesample.items.basic;
22

33
import android.content.Context;
4+
import android.widget.Toast;
45

56
import com.regula.facesample.items.CategoryItem;
7+
import com.regula.facesample.util.FaceCaptureResponseUtil;
68
import com.regula.facesdk.FaceSDK;
79

810
/**
@@ -14,7 +16,7 @@ public class FaceCaptureDefaultItem extends CategoryItem {
1416

1517
@Override
1618
public void onItemSelected(Context context) {
17-
FaceSDK.Instance().presentFaceCaptureActivity(context, faceCaptureResponse -> { });
19+
FaceSDK.Instance().presentFaceCaptureActivity(context, faceCaptureResponse -> FaceCaptureResponseUtil.response(context, faceCaptureResponse));
1820
}
1921

2022
@Override

FaceSample/app/src/main/java/com/regula/facesample/items/basic/LivenessDefaultItem.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package com.regula.facesample.items.basic;
22

33
import android.content.Context;
4+
import android.widget.Toast;
45

56
import com.regula.facesample.items.CategoryItem;
7+
import com.regula.facesample.util.LivenessResponseUtil;
68
import com.regula.facesdk.FaceSDK;
79

810
/**
@@ -14,7 +16,7 @@ public class LivenessDefaultItem extends CategoryItem {
1416

1517
@Override
1618
public void onItemSelected(Context context) {
17-
FaceSDK.Instance().startLiveness(context, livenessResponse -> { });
19+
FaceSDK.Instance().startLiveness(context, livenessResponse -> LivenessResponseUtil.response(context, livenessResponse));
1820
}
1921

2022
@Override

FaceSample/app/src/main/java/com/regula/facesample/items/customization/AdvancedCustomItem.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import com.regula.facesample.items.CategoryItem;
66
import com.regula.facesample.items.customization.fragment.AdvancedCustomUiFragment;
7+
import com.regula.facesample.util.LivenessResponseUtil;
78
import com.regula.facesdk.FaceSDK;
89
import com.regula.facesdk.configuration.LivenessConfiguration;
910

@@ -19,7 +20,7 @@ public void onItemSelected(Context context) {
1920
LivenessConfiguration configuration = new LivenessConfiguration.Builder()
2021
.registerUiFragmentClass(AdvancedCustomUiFragment.class)
2122
.build();
22-
FaceSDK.Instance().startLiveness(context, configuration, livenessResponse -> {});
23+
FaceSDK.Instance().startLiveness(context, configuration, livenessResponse -> LivenessResponseUtil.response(context, livenessResponse));
2324
}
2425

2526
@Override

FaceSample/app/src/main/java/com/regula/facesample/items/customization/BasicCustomItem.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import com.regula.facesample.items.CategoryItem;
66
import com.regula.facesample.items.customization.fragment.BasicCustomUiFragment;
7+
import com.regula.facesample.util.LivenessResponseUtil;
78
import com.regula.facesdk.FaceSDK;
89
import com.regula.facesdk.configuration.LivenessConfiguration;
910

@@ -19,7 +20,7 @@ public void onItemSelected(Context context) {
1920
LivenessConfiguration configuration = new LivenessConfiguration.Builder()
2021
.registerUiFragmentClass(BasicCustomUiFragment.class)
2122
.build();
22-
FaceSDK.Instance().startLiveness(context, configuration, livenessResponse -> {});
23+
FaceSDK.Instance().startLiveness(context, configuration, livenessResponse -> LivenessResponseUtil.response(context, livenessResponse));
2324
}
2425

2526
@Override

FaceSample/app/src/main/java/com/regula/facesample/items/customization/ButtonsColorItem.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import com.regula.facesample.items.CategoryItem;
66
import com.regula.facesample.items.customization.fragment.ButtonsColorFragment;
7+
import com.regula.facesample.util.FaceCaptureResponseUtil;
78
import com.regula.facesdk.FaceSDK;
89
import com.regula.facesdk.configuration.FaceCaptureConfiguration;
910
import com.regula.facesdk.configuration.LivenessConfiguration;
@@ -20,7 +21,7 @@ public void onItemSelected(Context context) {
2021
.setCameraSwitchEnabled(true)
2122
.registerUiFragmentClass(ButtonsColorFragment.class)
2223
.build();
23-
FaceSDK.Instance().presentFaceCaptureActivity(context, configuration, faceCaptureResponse -> { });
24+
FaceSDK.Instance().presentFaceCaptureActivity(context, configuration, faceCaptureResponse -> FaceCaptureResponseUtil.response(context, faceCaptureResponse));
2425
}
2526

2627
@Override

0 commit comments

Comments
 (0)