Update vdstools to latest version
And migrate the code to use the public API only. This version doesn't include the Kermit logging library which would have required a minSdk raise.
This commit is contained in:
+1
-1
@@ -83,7 +83,7 @@ dependencies {
|
||||
implementation 'androidx.camera:camera-view:1.4.2'
|
||||
implementation 'com.github.markusfisch:ScalingImageView:1.4.3'
|
||||
implementation 'com.github.markusfisch:zxing-cpp:v3.0.2.3'
|
||||
implementation 'de.tsenger:vdstools:0.14.0'
|
||||
implementation 'de.tsenger:vdstools:0.16.0-SNAPSHOT'
|
||||
implementation 'org.bouncycastle:bcpkix-jdk15to18:1.83'
|
||||
|
||||
// Testing
|
||||
|
||||
@@ -17,10 +17,7 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
import java.security.Provider
|
||||
import java.security.Security
|
||||
import java.security.cert.X509Certificate
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
import java.util.TimeZone
|
||||
|
||||
object IdbVerifier {
|
||||
private const val MASTER_LIST_ASSET = "DE_ML_2026-01-08-12-20-54.ml"
|
||||
@@ -44,32 +41,25 @@ object IdbVerifier {
|
||||
context.getString(R.string.idb_verification_unsigned)
|
||||
)
|
||||
)
|
||||
val headerCertificateReference = seal.payLoad.idbHeader.certificateReference
|
||||
val embeddedSignerCertificate = seal.payLoad.idbSignerCertificate
|
||||
?.certBytes
|
||||
?.let {
|
||||
parseCertificate(it)
|
||||
}
|
||||
if (seal.payLoad.idbSignerCertificate != null && embeddedSignerCertificate == null) {
|
||||
return listOf(
|
||||
SealField(
|
||||
R.string.idb_verification,
|
||||
context.getString(
|
||||
R.string.idb_verification_invalid_signer_certificate
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
val signerCertificate = embeddedSignerCertificate
|
||||
?: context.findCertificateByReference(headerCertificateReference)
|
||||
val headerCertificateReference = seal.signerCertReference
|
||||
?.hexToByteArrayOrNull()
|
||||
val signerCertificate = context.findCertificateByReference(
|
||||
headerCertificateReference
|
||||
)
|
||||
val curveName = signerCertificate?.let {
|
||||
curveNameFrom(it)
|
||||
}
|
||||
val signatureResult = if (signerCertificate == null || curveName.isNullOrBlank()) {
|
||||
val signedBytes = seal.signedBytes
|
||||
val signatureResult = if (
|
||||
signerCertificate == null ||
|
||||
curveName.isNullOrBlank() ||
|
||||
signedBytes == null
|
||||
) {
|
||||
Verifier.Result.VerifyError
|
||||
} else {
|
||||
Verifier(
|
||||
seal,
|
||||
signedBytes,
|
||||
signatureInfo.plainSignatureBytes,
|
||||
signerCertificate.publicKey.encoded,
|
||||
curveName
|
||||
).verify()
|
||||
@@ -113,9 +103,7 @@ object IdbVerifier {
|
||||
),
|
||||
SealField(
|
||||
R.string.vds_signing_date,
|
||||
parseSigningDate(
|
||||
signatureInfo.signingDate.toString()
|
||||
).toString()
|
||||
signatureInfo.signingDate.toString()
|
||||
),
|
||||
SealField(
|
||||
R.string.idb_signature_verification,
|
||||
@@ -139,12 +127,14 @@ object IdbVerifier {
|
||||
return fields
|
||||
}
|
||||
|
||||
private fun parseSigningDate(value: String): Date? {
|
||||
private fun String.hexToByteArrayOrNull(): ByteArray? {
|
||||
if (length % 2 != 0) {
|
||||
return null
|
||||
}
|
||||
return runCatching {
|
||||
SimpleDateFormat("yyyy-MM-dd", Locale.US).apply {
|
||||
isLenient = false
|
||||
timeZone = TimeZone.getTimeZone("UTC")
|
||||
}.parse(value)
|
||||
ByteArray(length / 2) { index ->
|
||||
substring(index * 2, index * 2 + 2).toInt(16).toByte()
|
||||
}
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
@@ -172,14 +162,6 @@ object IdbVerifier {
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseCertificate(certificateBytes: ByteArray): X509Certificate? {
|
||||
return runCatching {
|
||||
JcaX509CertificateConverter()
|
||||
.setProvider(provider)
|
||||
.getCertificate(X509CertificateHolder(certificateBytes))
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
private fun Context.findCertificateByReference(
|
||||
certificateReference: ByteArray?
|
||||
): X509Certificate? {
|
||||
|
||||
@@ -109,8 +109,9 @@ object IdlParser {
|
||||
// Detect this by checking that the marker matches the key prefix
|
||||
// (jurisdiction fields always share their 2-char subfile prefix).
|
||||
val seg = if (skipSubtype && p - start >= 4 &&
|
||||
data[start] == data[start + 2] &&
|
||||
data[start + 1] == data[start + 3]) {
|
||||
data[start] == data[start + 2] &&
|
||||
data[start + 1] == data[start + 3]
|
||||
) {
|
||||
start + 2
|
||||
} else {
|
||||
start
|
||||
|
||||
@@ -2,7 +2,7 @@ package de.markusfisch.android.binaryeye.content
|
||||
|
||||
import android.content.Context
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import de.tsenger.vdstools.DataEncoder
|
||||
import de.tsenger.vdstools.asn1.DerTlv
|
||||
import de.tsenger.vdstools.generic.Message
|
||||
import de.tsenger.vdstools.generic.MessageCoding
|
||||
import de.tsenger.vdstools.generic.MessageValue
|
||||
@@ -10,6 +10,7 @@ import de.tsenger.vdstools.generic.Seal
|
||||
import de.tsenger.vdstools.idb.IdbSeal
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import de.tsenger.vdstools.generic.SealParser as VdsSealParser
|
||||
|
||||
data class SealField(val name: Any, val value: String)
|
||||
private data class IdbChildMessageDefinition(
|
||||
@@ -27,7 +28,7 @@ object SealParser {
|
||||
bytes: ByteArray
|
||||
): List<SealField>? = try {
|
||||
context.buildFields(
|
||||
Seal.fromString(bytes.toString(Charsets.ISO_8859_1))
|
||||
VdsSealParser().parse(bytes.toString(Charsets.ISO_8859_1))
|
||||
)
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
@@ -66,7 +67,7 @@ object SealParser {
|
||||
private fun Message.childMessages(): List<Message> {
|
||||
val childDefinitionsByTag = idbChildMessagesByName[name] ?: return emptyList()
|
||||
return runCatching {
|
||||
DataEncoder.parseDerTLvs(value.rawBytes).mapNotNull { derTlv ->
|
||||
DerTlv.parseAll(value.rawBytes).mapNotNull { derTlv ->
|
||||
val childTag = derTlv.tag.toInt() and 0xff
|
||||
val childDefinition = childDefinitionsByTag[childTag]
|
||||
?: return@mapNotNull null
|
||||
|
||||
@@ -10,6 +10,10 @@ dependencyResolutionManagement {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = 'Central Portal Snapshots'
|
||||
url = uri('https://central.sonatype.com/repository/maven-snapshots/')
|
||||
}
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user