586 lines
20 KiB
Dart
586 lines
20 KiB
Dart
import 'dart:typed_data';
|
|
|
|
import 'package:dmrtd/dmrtd.dart';
|
|
import 'package:dmrtd/src/proto/can_key.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:gascom/widgets/custom_app_bar.dart';
|
|
|
|
class NfcScreen extends StatefulWidget {
|
|
const NfcScreen({super.key});
|
|
|
|
@override
|
|
State<NfcScreen> createState() => _NfcScreenState();
|
|
}
|
|
|
|
class _NfcScreenState extends State<NfcScreen> {
|
|
final NfcProvider _nfc = NfcProvider();
|
|
MrtdData? _mrtdData = MrtdData();
|
|
String _alertMessage = "";
|
|
bool _isReading = false;
|
|
|
|
String id = ''; // should change based on user id card (it's the string below the image)
|
|
DateTime dateOfBirth = DateTime(2000, 1, 1); // should change based on user id card
|
|
DateTime dateOfExpiry = DateTime(2029, 1, 1); // should change based on user id card
|
|
|
|
@override
|
|
void initState() {
|
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
|
try {
|
|
_buttonPressed();
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
});
|
|
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return const Scaffold(
|
|
appBar: CustomAppBar(),
|
|
body: SafeArea(
|
|
child: Center(
|
|
child: Text("NFC Screen, Nfc has ti be turned on."),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
String formatProgressMsg(String message, int percentProgress) {
|
|
final p = (percentProgress / 20).round();
|
|
final full = "🟢 " * p;
|
|
final empty = "⚪️ " * (5 - p);
|
|
return "$message\n\n$full$empty";
|
|
}
|
|
|
|
void _readMRTD({required AccessKey accessKey, bool isPace = false}) async {
|
|
try {
|
|
setState(() {
|
|
_mrtdData = null;
|
|
_alertMessage = "Waiting for Passport tag ...";
|
|
_isReading = true;
|
|
});
|
|
try {
|
|
bool demo = false;
|
|
print("-------------- FIRST -------------");
|
|
if (!demo)
|
|
await _nfc.connect(
|
|
iosAlertMessage: "Hold your phone near Biometric Passport");
|
|
|
|
print("-------------- SECOND -------------");
|
|
final passport = Passport(_nfc);
|
|
|
|
print("-------------- THIRD -------------");
|
|
setState(() {
|
|
_alertMessage = "Reading Passport ...";
|
|
});
|
|
|
|
print("-------------- 4 -------------");
|
|
_nfc.setIosAlertMessage("Trying to read EF.CardAccess ...");
|
|
final mrtdData = MrtdData();
|
|
|
|
print("-------------- 5 -------------");
|
|
try {
|
|
mrtdData.cardAccess = await passport.readEfCardAccess();
|
|
} on PassportError {
|
|
print("-------------- 6 -------------");
|
|
//if (e.code != StatusWord.fileNotFound) rethrow;
|
|
}
|
|
|
|
_nfc.setIosAlertMessage("Trying to read EF.CardSecurity ...");
|
|
|
|
try {
|
|
//mrtdData.cardSecurity = await passport.readEfCardSecurity();
|
|
} on PassportError {
|
|
//if (e.code != StatusWord.fileNotFound) rethrow;
|
|
}
|
|
|
|
_nfc.setIosAlertMessage("Initiating session with PACE...");
|
|
//set MrtdData
|
|
mrtdData.isPACE = isPace;
|
|
mrtdData.isDBA = accessKey.PACE_REF_KEY_TAG == 0x01 ? true : false;
|
|
|
|
if (isPace) {
|
|
//PACE session
|
|
print("-------------- 7 -------------");
|
|
await passport.startSessionPACE(accessKey, mrtdData.cardAccess!);
|
|
} else {
|
|
print("-------------- 8 -------------");
|
|
//BAC session
|
|
await passport.startSession(accessKey as DBAKey);
|
|
}
|
|
|
|
print("-------------- 9 -------------");
|
|
_nfc.setIosAlertMessage(formatProgressMsg("Reading EF.COM ...", 0));
|
|
mrtdData.com = await passport.readEfCOM();
|
|
|
|
_nfc.setIosAlertMessage(
|
|
formatProgressMsg("Reading Data Groups ...", 20));
|
|
|
|
print("-------------- 10 -------------");
|
|
if (mrtdData.com!.dgTags.contains(EfDG1.TAG)) {
|
|
mrtdData.dg1 = await passport.readEfDG1();
|
|
print("DG1 mrz country: ${mrtdData.dg1?.mrz.country}");
|
|
print("DG1 mrz dateOfBirth: ${mrtdData.dg1?.mrz.dateOfBirth}");
|
|
print("DG1 mrz dateOfExpiry: ${mrtdData.dg1?.mrz.dateOfExpiry}");
|
|
print("DG1 mrz documentCode: ${mrtdData.dg1?.mrz.documentCode}");
|
|
print("DG1 mrz documentNumber: ${mrtdData.dg1?.mrz.documentNumber}");
|
|
print("DG1 mrz firstName: ${mrtdData.dg1?.mrz.firstName}");
|
|
print("DG1 mrz gender: ${mrtdData.dg1?.mrz.gender}");
|
|
print("DG1 mrz lastName: ${mrtdData.dg1?.mrz.lastName}");
|
|
print("DG1 mrz nationality: ${mrtdData.dg1?.mrz.nationality}");
|
|
print("DG1 mrz optionalData: ${mrtdData.dg1?.mrz.optionalData}");
|
|
print("DG1 mrz optionalData2: ${mrtdData.dg1?.mrz.optionalData2}");
|
|
print("DG1 mrz version: ${mrtdData.dg1?.mrz.version}");
|
|
}
|
|
|
|
print("-------------- 11 -------------");
|
|
if (mrtdData.com!.dgTags.contains(EfDG2.TAG)) {
|
|
mrtdData.dg2 = await passport.readEfDG2();
|
|
print("DG2 deviceType: ${mrtdData.dg2?.deviceType}");
|
|
print("DG2 expression: ${mrtdData.dg2?.expression}");
|
|
print("DG2 eyeColor: ${mrtdData.dg2?.eyeColor}");
|
|
print("DG2 faceImageType: ${mrtdData.dg2?.faceImageType}");
|
|
print("DG2 facialRecordDataLength: ${mrtdData.dg2?.facialRecordDataLength}");
|
|
print("DG2 featureMask: ${mrtdData.dg2?.featureMask}");
|
|
print("DG2 gender: ${mrtdData.dg2?.gender}");
|
|
print("DG2 hairColor: ${mrtdData.dg2?.hairColor}");
|
|
print("DG2 imageColorSpace: ${mrtdData.dg2?.imageColorSpace}");
|
|
print("DG2 imageData: ${mrtdData.dg2?.imageData}");
|
|
print("DG2 imageHeight: ${mrtdData.dg2?.imageHeight}");
|
|
print("DG2 imageType: ${mrtdData.dg2?.imageType}");
|
|
print("DG2 imageWidth: ${mrtdData.dg2?.imageWidth}");
|
|
print("DG2 lengthOfRecord: ${mrtdData.dg2?.lengthOfRecord}");
|
|
print("DG2 nrFeaturePoints: ${mrtdData.dg2?.nrFeaturePoints}");
|
|
print("DG2 numberOfFacialImages: ${mrtdData.dg2?.numberOfFacialImages}");
|
|
print("DG2 poseAngle: ${mrtdData.dg2?.poseAngle}");
|
|
print("DG2 poseAngleUncertainty: ${mrtdData.dg2?.poseAngleUncertainty}");
|
|
print("DG2 quality: ${mrtdData.dg2?.quality}");
|
|
print("DG2 sourceType: ${mrtdData.dg2?.sourceType}");
|
|
print("DG2 versionNumber: ${mrtdData.dg2?.versionNumber}");
|
|
}
|
|
|
|
// To read DG3 and DG4 session has to be established with CVCA certificate (not supported).
|
|
// if(mrtdData.com!.dgTags.contains(EfDG3.TAG)) {
|
|
// mrtdData.dg3 = await passport.readEfDG3();
|
|
// }
|
|
|
|
// if(mrtdData.com!.dgTags.contains(EfDG4.TAG)) {
|
|
// mrtdData.dg4 = await passport.readEfDG4();
|
|
// }
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG5.TAG)) {
|
|
mrtdData.dg5 = await passport.readEfDG5();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG6.TAG)) {
|
|
mrtdData.dg6 = await passport.readEfDG6();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG7.TAG)) {
|
|
mrtdData.dg7 = await passport.readEfDG7();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG8.TAG)) {
|
|
mrtdData.dg8 = await passport.readEfDG8();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG9.TAG)) {
|
|
mrtdData.dg9 = await passport.readEfDG9();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG10.TAG)) {
|
|
mrtdData.dg10 = await passport.readEfDG10();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG11.TAG)) {
|
|
mrtdData.dg11 = await passport.readEfDG11();
|
|
print("DG11 custodyInformation: ${mrtdData.dg11?.custodyInformation}");
|
|
print("DG11 ersonalSummary: ${mrtdData.dg11?.ersonalSummary}");
|
|
print("DG11 fullDateOfBirth: ${mrtdData.dg11?.fullDateOfBirth}");
|
|
print("DG11 nameOfHolder: ${mrtdData.dg11?.nameOfHolder}");
|
|
print("DG11 otherNames: ${mrtdData.dg11?.otherNames}");
|
|
print("DG11 otherValidTDNumbers: ${mrtdData.dg11?.otherValidTDNumbers}");
|
|
print("DG11 permanentAddress: ${mrtdData.dg11?.permanentAddress}");
|
|
print("DG11 personalNumber: ${mrtdData.dg11?.personalNumber}");
|
|
print("DG11 placeOfBirth: ${mrtdData.dg11?.placeOfBirth}");
|
|
print("DG11 profession: ${mrtdData.dg11?.profession}");
|
|
print("DG11 proofOfCitizenship: ${mrtdData.dg11?.proofOfCitizenship}");
|
|
print("DG11 telephone: ${mrtdData.dg11?.telephone}");
|
|
print("DG11 title: ${mrtdData.dg11?.title}");
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG12.TAG)) {
|
|
mrtdData.dg12 = await passport.readEfDG12();
|
|
print("DG12 dateOfIssue: ${mrtdData.dg12?.dateOfIssue}");
|
|
print("DG12 dateOfIssue: ${mrtdData.dg12?.issuingAuthority}");
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG13.TAG)) {
|
|
mrtdData.dg13 = await passport.readEfDG13();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG14.TAG)) {
|
|
mrtdData.dg14 = await passport.readEfDG14();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG15.TAG)) {
|
|
mrtdData.dg15 = await passport.readEfDG15();
|
|
_nfc.setIosAlertMessage(formatProgressMsg("Doing AA ...", 60));
|
|
|
|
print("DG15 aaPublicKey: ${mrtdData.dg15?.aaPublicKey}");
|
|
|
|
mrtdData.aaSig = await passport.activeAuthenticate(Uint8List(8));
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG16.TAG)) {
|
|
mrtdData.dg16 = await passport.readEfDG16();
|
|
}
|
|
|
|
print("-------------- 12 -------------");
|
|
_nfc.setIosAlertMessage(formatProgressMsg("Reading EF.SOD ...", 80));
|
|
mrtdData.sod = await passport.readEfSOD();
|
|
|
|
setState(() {
|
|
_mrtdData = mrtdData;
|
|
});
|
|
|
|
setState(() {
|
|
_alertMessage = "";
|
|
});
|
|
} on Exception catch (e) {
|
|
final se = e.toString().toLowerCase();
|
|
String alertMsg = "An error has occurred while reading Passport!";
|
|
if (e is PassportError) {
|
|
if (se.contains("security status not satisfied")) {
|
|
alertMsg =
|
|
"Failed to initiate session with passport.\nCheck input data!";
|
|
}
|
|
print("PassportError: ${e.message}");
|
|
} else {
|
|
print(
|
|
"An exception was encountered while trying to read Passport: $e");
|
|
}
|
|
|
|
if (se.contains('timeout')) {
|
|
alertMsg = "Timeout while waiting for Passport tag";
|
|
} else if (se.contains("tag was lost")) {
|
|
alertMsg = "Tag was lost. Please try again!";
|
|
} else if (se.contains("invalidated by user")) {
|
|
alertMsg = "";
|
|
}
|
|
|
|
setState(() {
|
|
_alertMessage = alertMsg;
|
|
});
|
|
} finally {
|
|
if (_alertMessage.isNotEmpty) {
|
|
await _nfc.disconnect(iosErrorMessage: _alertMessage);
|
|
} else {
|
|
await _nfc.disconnect(
|
|
iosAlertMessage: formatProgressMsg("Finished", 100));
|
|
}
|
|
setState(() {
|
|
_isReading = false;
|
|
});
|
|
}
|
|
} on Exception catch (e) {
|
|
print("Read MRTD error: $e");
|
|
}
|
|
}
|
|
|
|
void _readMRTDOld() async {
|
|
try {
|
|
setState(() {
|
|
_mrtdData = null;
|
|
_alertMessage = "Waiting for Passport tag ...";
|
|
_isReading = true;
|
|
});
|
|
|
|
await _nfc.connect(
|
|
iosAlertMessage: "Hold your phone near Biometric Passport");
|
|
final passport = Passport(_nfc);
|
|
|
|
setState(() {
|
|
_alertMessage = "Reading Passport ...";
|
|
});
|
|
|
|
_nfc.setIosAlertMessage("Trying to read EF.CardAccess ...");
|
|
final mrtdData = MrtdData();
|
|
|
|
try {
|
|
mrtdData.cardAccess = await passport.readEfCardAccess();
|
|
} on PassportError {
|
|
//if (e.code != StatusWord.fileNotFound) rethrow;
|
|
}
|
|
|
|
_nfc.setIosAlertMessage("Trying to read EF.CardSecurity ...");
|
|
|
|
try {
|
|
mrtdData.cardSecurity = await passport.readEfCardSecurity();
|
|
} on PassportError {
|
|
//if (e.code != StatusWord.fileNotFound) rethrow;
|
|
}
|
|
|
|
_nfc.setIosAlertMessage("Initiating session ...");
|
|
final bacKeySeed = DBAKey(id, dateOfBirth, dateOfExpiry);
|
|
await passport.startSession(bacKeySeed);
|
|
|
|
_nfc.setIosAlertMessage(formatProgressMsg("Reading EF.COM ...", 0));
|
|
mrtdData.com = await passport.readEfCOM();
|
|
|
|
_nfc.setIosAlertMessage(formatProgressMsg("Reading Data Groups ...", 20));
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG1.TAG)) {
|
|
mrtdData.dg1 = await passport.readEfDG1();
|
|
print(mrtdData.dg1?.mrz);
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG2.TAG)) {
|
|
mrtdData.dg2 = await passport.readEfDG2();
|
|
print("DG2 deviceType: ${mrtdData.dg2?.deviceType}");
|
|
print("DG2 expression: ${mrtdData.dg2?.expression}");
|
|
print("DG2 eyeColor: ${mrtdData.dg2?.eyeColor}");
|
|
print("DG2 faceImageType: ${mrtdData.dg2?.faceImageType}");
|
|
print("DG2 facialRecordDataLength: ${mrtdData.dg2?.facialRecordDataLength}");
|
|
print("DG2 featureMask: ${mrtdData.dg2?.featureMask}");
|
|
print("DG2 fid: ${mrtdData.dg2?.fid}");
|
|
print("DG2 gender: ${mrtdData.dg2?.gender}");
|
|
print("DG2 hairColor: ${mrtdData.dg2?.hairColor}");
|
|
print("DG2 imageColorSpace: ${mrtdData.dg2?.imageColorSpace}");
|
|
print("DG2 imageData: ${mrtdData.dg2?.imageData}");
|
|
print("DG2 imageHeight: ${mrtdData.dg2?.imageHeight}");
|
|
print("DG2 imageType: ${mrtdData.dg2?.imageType}");
|
|
print("DG2 imageWidth: ${mrtdData.dg2?.imageWidth}");
|
|
print("DG2 nrFeaturePoints: ${mrtdData.dg2?.nrFeaturePoints}");
|
|
print("DG2 numberOfFacialImages: ${mrtdData.dg2?.numberOfFacialImages}");
|
|
print("DG2 lengthOfRecord: ${mrtdData.dg2?.lengthOfRecord}");
|
|
print("DG2 poseAngle: ${mrtdData.dg2?.poseAngle}");
|
|
print("DG2 poseAngleUncertainty: ${mrtdData.dg2?.poseAngleUncertainty}");
|
|
print("DG2 quality: ${mrtdData.dg2?.quality}");
|
|
print("DG2 sourceType: ${mrtdData.dg2?.sourceType}");
|
|
print("DG2 versionNumber: ${mrtdData.dg2?.versionNumber}");
|
|
print("DG2 tag: ${mrtdData.dg2?.tag}");
|
|
print("DG2 sfi: ${mrtdData.dg2?.sfi}");
|
|
}
|
|
|
|
// To read DG3 and DG4 session has to be established with CVCA certificate (not supported).
|
|
// if(mrtdData.com!.dgTags.contains(EfDG3.TAG)) {
|
|
// mrtdData.dg3 = await passport.readEfDG3();
|
|
// }
|
|
|
|
// if(mrtdData.com!.dgTags.contains(EfDG4.TAG)) {
|
|
// mrtdData.dg4 = await passport.readEfDG4();
|
|
// }
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG5.TAG)) {
|
|
mrtdData.dg5 = await passport.readEfDG5();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG6.TAG)) {
|
|
mrtdData.dg6 = await passport.readEfDG6();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG7.TAG)) {
|
|
mrtdData.dg7 = await passport.readEfDG7();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG8.TAG)) {
|
|
mrtdData.dg8 = await passport.readEfDG8();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG9.TAG)) {
|
|
mrtdData.dg9 = await passport.readEfDG9();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG10.TAG)) {
|
|
mrtdData.dg10 = await passport.readEfDG10();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG11.TAG)) {
|
|
mrtdData.dg11 = await passport.readEfDG11();
|
|
print("DG11 custodyInformation: ${mrtdData.dg11?.custodyInformation}");
|
|
print("DG11 ersonalSummary: ${mrtdData.dg11?.ersonalSummary}");
|
|
print("DG11 fullDateOfBirth: ${mrtdData.dg11?.fullDateOfBirth}");
|
|
print("DG11 nameOfHolder: ${mrtdData.dg11?.nameOfHolder}");
|
|
print("DG11 otherNames: ${mrtdData.dg11?.otherNames}");
|
|
print("DG11 otherValidTDNumbers: ${mrtdData.dg11?.otherValidTDNumbers}");
|
|
print("DG11 permanentAddress: ${mrtdData.dg11?.permanentAddress}");
|
|
print("DG11 personalNumber: ${mrtdData.dg11?.personalNumber}");
|
|
print("DG11 placeOfBirth: ${mrtdData.dg11?.placeOfBirth}");
|
|
print("DG11 profession: ${mrtdData.dg11?.profession}");
|
|
print("DG11 proofOfCitizenship: ${mrtdData.dg11?.proofOfCitizenship}");
|
|
print("DG11 telephone: ${mrtdData.dg11?.telephone}");
|
|
print("DG11 title: ${mrtdData.dg11?.title}");
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG12.TAG)) {
|
|
mrtdData.dg12 = await passport.readEfDG12();
|
|
print("DG12 dateOfIssue: ${mrtdData.dg12?.dateOfIssue}");
|
|
print("DG12 issuingAuthority: ${mrtdData.dg12?.issuingAuthority}");
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG13.TAG)) {
|
|
mrtdData.dg13 = await passport.readEfDG13();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG14.TAG)) {
|
|
mrtdData.dg14 = await passport.readEfDG14();
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG15.TAG)) {
|
|
mrtdData.dg15 = await passport.readEfDG15();
|
|
print("DG12 issuingAuthority: ${mrtdData.dg15?.aaPublicKey}");
|
|
_nfc.setIosAlertMessage(formatProgressMsg("Doing AA ...", 60));
|
|
mrtdData.aaSig = await passport.activeAuthenticate(Uint8List(8));
|
|
}
|
|
|
|
if (mrtdData.com!.dgTags.contains(EfDG16.TAG)) {
|
|
mrtdData.dg16 = await passport.readEfDG16();
|
|
}
|
|
|
|
_nfc.setIosAlertMessage(formatProgressMsg("Reading EF.SOD ...", 80));
|
|
mrtdData.sod = await passport.readEfSOD();
|
|
|
|
setState(() {
|
|
_mrtdData = mrtdData;
|
|
});
|
|
|
|
setState(() {
|
|
_alertMessage = "";
|
|
});
|
|
} on Exception catch (e) {
|
|
final se = e.toString().toLowerCase();
|
|
String alertMsg = "An error has occurred while reading Passport!";
|
|
if (e is PassportError) {
|
|
if (se.contains("security status not satisfied")) {
|
|
alertMsg =
|
|
"Failed to initiate session with passport.\nCheck input data!";
|
|
}
|
|
print("PassportError: ${e.message}");
|
|
} else {
|
|
print("An exception was encountered while trying to read Passport: $e");
|
|
}
|
|
|
|
if (se.contains('timeout')) {
|
|
alertMsg = "Timeout while waiting for Passport tag";
|
|
} else if (se.contains("tag was lost")) {
|
|
alertMsg = "Tag was lost. Please try again!";
|
|
} else if (se.contains("invalidated by user")) {
|
|
alertMsg = "";
|
|
}
|
|
|
|
setState(() {
|
|
_alertMessage = alertMsg;
|
|
});
|
|
} finally {
|
|
if (_alertMessage.isNotEmpty) {
|
|
await _nfc.disconnect(iosErrorMessage: _alertMessage);
|
|
} else {
|
|
await _nfc.disconnect(
|
|
iosAlertMessage: formatProgressMsg("Finished", 100));
|
|
}
|
|
setState(() {
|
|
_isReading = false;
|
|
});
|
|
}
|
|
}
|
|
|
|
void _buttonPressed() async {
|
|
String _can = "";
|
|
print("Button pressed");
|
|
//Check on what tab we are
|
|
if (true) {
|
|
//DBA tab
|
|
// String errorText = "";
|
|
// if (_doe.text.isEmpty) {
|
|
// errorText += "Please enter date of expiry!\n";
|
|
// }
|
|
// if (_dob.text.isEmpty) {
|
|
// errorText += "Please enter date of birth!\n";
|
|
// }
|
|
// if (_docNumber.text.isEmpty) {
|
|
// errorText += "Please enter passport number!";
|
|
// }
|
|
|
|
// setState(() {
|
|
// _alertMessage = errorText;
|
|
// });
|
|
// //If there is an error, just jump out of the function
|
|
// if (errorText.isNotEmpty) return;
|
|
|
|
final bacKeySeed = DBAKey(id, dateOfBirth, dateOfExpiry, paceMode: true);
|
|
_readMRTD(accessKey: bacKeySeed, isPace: true);
|
|
} else {
|
|
// PACE tab
|
|
// String errorText = "";
|
|
// if (_can.isEmpty) {
|
|
// errorText = "Please enter CAN number!";
|
|
// } else if (_can.text.length != 6) {
|
|
// errorText = "CAN number must be exactly 6 digits long!";
|
|
// }
|
|
|
|
// setState(() {
|
|
// _alertMessage = errorText;
|
|
// });
|
|
// //If there is an error, just jump out of the function
|
|
// if (errorText.isNotEmpty) return;
|
|
|
|
// final canKeySeed = CanKey(_can.text);
|
|
final canKeySeed = CanKey(id);
|
|
_readMRTD(accessKey: canKeySeed, isPace: true);
|
|
}
|
|
}
|
|
}
|
|
|
|
class MrtdData {
|
|
EfCardAccess? cardAccess;
|
|
EfCardSecurity? cardSecurity;
|
|
EfCOM? com;
|
|
EfSOD? sod;
|
|
EfDG1? dg1;
|
|
EfDG2? dg2;
|
|
EfDG3? dg3;
|
|
EfDG4? dg4;
|
|
EfDG5? dg5;
|
|
EfDG6? dg6;
|
|
EfDG7? dg7;
|
|
EfDG8? dg8;
|
|
EfDG9? dg9;
|
|
EfDG10? dg10;
|
|
EfDG11? dg11;
|
|
EfDG12? dg12;
|
|
EfDG13? dg13;
|
|
EfDG14? dg14;
|
|
EfDG15? dg15;
|
|
EfDG16? dg16;
|
|
Uint8List? aaSig;
|
|
bool? isPACE;
|
|
bool? isDBA;
|
|
}
|
|
|
|
final Map<DgTag, String> dgTagToString = {
|
|
EfDG1.TAG: 'EF.DG1',
|
|
EfDG2.TAG: 'EF.DG2',
|
|
EfDG3.TAG: 'EF.DG3',
|
|
EfDG4.TAG: 'EF.DG4',
|
|
EfDG5.TAG: 'EF.DG5',
|
|
EfDG6.TAG: 'EF.DG6',
|
|
EfDG7.TAG: 'EF.DG7',
|
|
EfDG8.TAG: 'EF.DG8',
|
|
EfDG9.TAG: 'EF.DG9',
|
|
EfDG10.TAG: 'EF.DG10',
|
|
EfDG11.TAG: 'EF.DG11',
|
|
EfDG12.TAG: 'EF.DG12',
|
|
EfDG13.TAG: 'EF.DG13',
|
|
EfDG14.TAG: 'EF.DG14',
|
|
EfDG15.TAG: 'EF.DG15',
|
|
EfDG16.TAG: 'EF.DG16'
|
|
};
|